Releases: vendurehq/vendure
v3.6.4
Highlights
This patch release is mostly about hardening — both the runtime and the release pipeline itself — together with a big batch of dashboard fixes and a couple of performance wins. It also reverts a graphql dependency change from v3.6.3 that caused trouble in some setups. Thanks to everyone who reported issues and sent in PRs.
Reverting the graphql dependency change
v3.6.3 narrowed the graphql version range used by the core packages, and that turned out to break a number of repos with otherwise perfectly valid setups. We've widened it back to ^16.11.0 (#4716). If you pinned or added an override to graphql to get v3.6.3 working, you can take that workaround out now.
Security
- SSRF blocked in asset import (#4721) --
DefaultAssetImportStrategywould fetch whatever URL it was handed, which left room for server-side request forgery when importing assets from untrusted input. It now refuses requests aimed at internal and private network addresses.
In light of a recent increase in supply chain attacks on the npm ecosystem, a good chunk of the work this cycle went into the release pipeline rather than the code you run. We've moved to staged npm publishing, pinned all GitHub Actions to specific commit SHAs, dropped off the deprecated Node 20 runtime, scoped the GitHub App tokens down to least privilege, and gated the publish trigger to maintainers (#4784, #4785, #4786, #4787, #4788, #4789). None of this changes how Vendure behaves, but it tightens up the supply chain around how releases are built and shipped.
Core fixes
Notable fixes to the core:
- Inherited QueryRunner no longer released early (#4717) -- When a
TransactionWrapperinherited aQueryRunnerfrom an enclosing transaction, it would release that runner when it finished, affecting the outer transaction. It now only releases runners it created itself. - Order variant names respect translations (#4738) --
OrderService.findOnewasn't loadingProductVarianttranslations, so variant names could come back in the wrong language. The translations are now loaded as expected. - Asset translation migration skips empty databases (#4733) -- The v3.6 asset-translation migration helper threw when run against a fresh, empty database. It now detects that case and skips cleanly.
Performance
findByCustomerIdn+1 fixed (#4653) -- Filtering onproductVariantrelations infindByCustomerIdwas triggering an n+1 query. The relations are now fetched in a single query.- Lighter dashboard relation query (#4743) -- A heavy relation query behind one of the dashboard list views has been trimmed down, reducing load on larger datasets.
Dashboard improvements
- Custom fields (#4407, #4734, #4431, #4781) -- A round of custom-field fixes: relational custom fields now persist when saving a draft order; custom fields show up on the profile page now that
addCustomFieldsis applied to its route loader; fields the current user isn't allowed to write are stripped from the mutation before submit instead of triggering a permission error; and struct custom fields render properly in narrow containers rather than overflowing. - Form inputs (#4801, #4794, #4759, #4750) -- Select inputs backed by a nullable field can be set back to the empty option; boolean configurable args now initialise with the correct value instead of being left undefined;
AffixedInputforwardsonFocusandonKeyDownso consumers can hook into those events; and the bulk facet value modal no longer loses focus to its dropdown menu on keydown. - List pages (#4746, #4739) -- Multiple values within a single column filter now combine with OR, so filtering on several values returns the union as expected. Column visibility settings also persist properly, alongside a Dialog title context fix.
- AlertsProvider reacts to late-registered extensions (#4747) -- Alerts registered by extensions after the provider mounts are now picked up.
- Tiptap toolbar tracks editor state (#4705) -- The rich-text toolbar now reflects the current selection's formatting state instead of going stale.
- Less layout shift from remote data (#4707) -- Reduced the flicker and layout shift that showed while remote data was loading.
- Static assets skip rate limiting (#4709) -- Static dashboard assets bypass the rate limiter and get a long-lived cache header.
- Quieter logs (#4745) -- The dashboard no longer floods logs with "Uncompiled message detected" warnings.
- Windows
.poglob patterns normalised (#4751) -- Translation file globs now use forward slashes on Windows so they resolve correctly. - Administrator search and seller subtitle (#4778) -- Administrator search now spans multiple fields, and the empty seller subtitle has been tidied up.
- Filter and master toggle on variant generation (#4752) -- The variant generation table now has a filter and a master toggle for selecting rows in bulk.-
What's Changed
- fix(dashboard): fix tiptap toolbar not reacting to state changes by @Knitesik in #4705
- fix(dashboard): Reduce layout shift and flicker from remote data by @dlhck in #4707
- fix(create): Add vite as direct dev dependency in scaffolded projects by @grolmus in #4710
- fix(dashboard): Skip rate limit for static assets and add long-lived cache by @grolmus in #4709
- docs: Revise README by @dlhck in #4737
- fix(core): Load ProductVariant translations in OrderService.findOne by @grolmus in #4738
- fix(dashboard): Apply addCustomFields to profile page route loader by @grolmus in #4734
- Fix relational custom field not saving on draft order by @Ryrahul in #4407
- perf(dashboard): reduce heavy relation query by @dublin74 in #4743
- fix(dashboard): Preserve column visibility and fix Dialog title context by @grolmus in #4739
- fix(core): Block SSRF in DefaultAssetImportStrategy by @grolmus in #4721
- fix(core): prevent double-decoding of ID args in updatePromotion by @Ryrahul in #4740
- fix(core): Skip v3.6 asset translation migration on empty DB by @grolmus in #4733
- fix(dashboard): normalize glob patterns to forward slashes on Windows by @Yanis02015 in #4751
- fix(dashboard): Make AlertsProvider react to extensions registered after mount by @grolmus in #4747
- fix(dashboard): Stop logging "Uncompiled message detected" warnings by @grolmus in #4745
- fix(core): Do not release inherited QueryRunner in TransactionWrapper by @grolmus in #4717
- fix(dashboard): stop keydown propagation in facet values dialog to prevent DropdownMenu focus steal by @Ryrahul in #4750
- fix(dashboard): Apply column filters on list pages using OR filter operator by @grolmus in #4746
- docs: Add deployment overview and fix deployment guides by @dlhck in #4782
- chore: Enable npm staged publishing for releases by @michaelbromley in #4784
- ci: Restrict npm publish dispatch to maintainers (Tier 2) by @michaelbromley in #4785
- ci: Pin all GitHub Actions to SHA and bump off deprecated Node 20 runtime by @michaelbromley in #4786
- ci: Scope GitHub App tokens to least privilege by @michaelbromley in #4787
- fix(ci): Drop actions:write from CLA app token (regression from #4787) by @michaelbromley in #4789
- ci: Gate the npm publish release trigger to maintainers by @michaelbromley in #4788
- fix(dashboard): prevent struct custom field overflow in narrow contai… by @Ryrahul in #4781
- ci: Fix intermittent dashboard port race in Publish & Install by @michaelbromley in #4790
- fix(core, dashboard): Widen graphql version range to ^16.11.0 by @grolmus in #4716
- fix: Remove non permitted customfield from mutation before submit by @Ryrahul in #4431
- fix(dashboard): initialize boolean configurable args by @genm in #4794
- fix(dashboard): forward onFocus and onKeyDown in AffixedInput by @Ryrahul in #4759
- fix(services): findByCustomerId productVariant relation filter breaks by @harshit078 in #4653
- fix(dashboard): Resolve logout stuck in verifying state on failure by @calebcgates in #4757
- fix(admin-ui): remove puppeteer dependency and rely on system Chrome for Karma tests by @michaelbromley in #4798
- fix(ci): Install chromium-headless-shell for dashboard e2e by @michaelbromley in #4800
- feat(dashboard): Filter + master toggle on variant generation table by @grolmus in #4752
- fix: add administrator and seller to createEntityConfigs by @Ryrahul in https://github.com/vendurehq/vendure/...
v3.6.3
Highlights
This patch release lands a substantial round of stability, concurrency and dashboard fixes. The headline items address race conditions in promotion and coupon handling, prevent out-of-memory issues on large channel assignments, and harden the scheduled-task and state-machine subsystems against duplicated or partially-applied work. Thanks as ever to everyone who reported issues and contributed PRs.
Concurrency and integrity fixes
This release closes several long-standing edge cases that could cause data integrity issues under load or concurrent traffic:
- Coupon usage limits enforced under concurrent checkout (#4660) -- A race condition allowed customers to bypass the per-coupon usage limit when multiple checkouts completed concurrently. The check is now serialised correctly so the configured limit is always respected.
- Auto-applied promotion usage limits enforced (#4405) -- Promotions that auto-apply (no coupon code required) were not honouring their configured usage limits. They now respect the same limits as code-applied promotions.
- Atomic state-machine transitions on hook failure (#4689) -- If a state-transition hook threw after the entity state had been written, the entity could be left in an inconsistent state with hooks partially applied. Transitions are now atomic — a failing hook reverts the state change cleanly.
- No duplicate execution of fast scheduled tasks (#4681) -- Scheduled tasks running on a short interval could be picked up and executed by multiple workers in the same window. The scheduler now correctly deduplicates these executions.
Performance and scalability
- Avoid OOM on large product-to-channel operations (#4669) --
assignProductsToChannelandremoveProductsFromChannelnow use a query relation strategy that no longer hydrates the full product graph into memory. This unblocks customers who hit out-of-memory crashes when assigning thousands of products to a channel. - Job queues now created in
onModuleInit(#4680) -- Moving job-queue creation fromonApplicationBootstraptoonModuleInitmeans queues exist before any other module's bootstrap code runs, eliminating a class of "queue not found" startup races.
Core fixes
- Asset update with custom field relations (#4696) -- Updating an Asset that had a custom-field relation defined no longer fails. This pairs with the corresponding dashboard fix (#4695).
- Entity hydrator handles undefined relations (#4672) -- Hydrating an entity where a requested relation was undefined no longer throws.
- Customer user resolution via relation (#4468) -- The
Customer.userresolver now uses the configured relation instead of doing a separate email-based lookup, fixing edge cases where the email had been changed on the user record. - Admin UI handles
tokenMethodarray form (#4663, fixes #4656) -- WhentokenMethodis configured as an array (['cookie', 'bearer']), the generatedui-confignow serialises it correctly instead of producing an invalid value.
Dashboard fixes and improvements
- Asset save with custom fields (#4695) -- Saving an Asset with custom fields defined now works correctly from the dashboard.
- Action bar positioning relative to extensions (#4676) -- Extensions can now position action bar items relative to other extensions rather than only to built-in items, giving extension authors more control over toolbar layout.
- Graceful fallback on denied replace-extension (#4694) -- When a permission check denies a
replace-style extension, the dashboard now falls back to the original block instead of rendering nothing. - Custom-page permission checks (#4679) -- Custom pages now respect their declared
requiredPermissionsand won't render for users who lack them. isFullWidthmetadata prop implemented (#4638) -- PageBlocks can now opt into a full-width layout via metadata, useful for components like rich text editors.- Direct
@base-ui/reactimports dropped (#4697) -- Dashboard internals no longer import directly from@base-ui/react, going through the wrapped component layer instead. This keeps the public surface area consistent for extension authors. - Order modification preview includes nested fragments (#4640) -- Modification previews now include all required nested fields, so the preview matches what the modification will actually produce.
- Draft order mutation error messages (#4381) --
updateOrder*mutations on draft orders now surface their error messages to the UI rather than failing silently. - Promotions list default sort (#4688) -- The promotions list now opens with a sensible default sort instead of arbitrary order.
- Chart widget dynamic Y-axis width (#4516) -- The dashboard chart widget now sizes its Y-axis dynamically so long labels are no longer clipped.
- Empty
customFieldsselection handled (#4652) -- Custom-field components with no selection no longer throw. - Fulfillment arg defaults are strings (#4658) -- Fulfillment handler argument default values are now correctly stringified.
- Tanstack router generator stability (#4666) -- Inlining the route literal sidesteps a tanstack router-generator quirk that could produce broken route trees in certain layouts.
New dashboard features
- Bulk cancel action with human-readable durations (#4361) -- Order lists now expose a bulk-cancel action, and durations are rendered as human-readable strings (e.g. "3 days ago") rather than raw timestamps.
- Romanian translations (#4598) -- Romanian (
ro) is now supported in the dashboard.
i18n improvements
- Italian translations updated (#4645) -- A round of missing Italian (
it) strings has been added. - Swedish corrections (#4684) -- Several mistranslated Swedish (
sv.po) strings have been corrected. - Wrong-language msgstrs repaired (#4685) -- A bulk fix across
hr,nb,tr,it,ja,ko,heandroremoves msgstr entries that had drifted into the wrong language. Thei18n:applyscript has been hardened to prevent recurrences.
Plugins
BullMQJobQueuePluginfiltering (#4523) -- Job filtering in the BullMQ plugin now produces correct results when combining multiple filter fields.
What's Changed
- fix(ci): Remove [skip ci] from generate_docs workflow by @oliverstreissi in #4646
- fix(ci): Add gate job to unblock non-package PRs by @michaelbromley in #4649
- fix(docs): Fix broken links and outdated type names in custom form components docs by @gabriellbui in #4648
- docs: Fix typo in navigation-menu arrayToTree code snippet by @gabriellbui in #4593
- fix(core): Enforce usage limits for auto-applied promotions by @HouseinIsProgramming in #4405
- fix: Add missing include nested fragments in order modification preview by @Ryrahul in #4640
- fix: Add dynamic y axis width by @Ryrahul in #4516
- feat(dashboard): Add Romanian translations by @alingabrieldm in #4598
- fix: Add recursive flatten job filter for bull mq when filter is sent… by @Ryrahul in #4523
- fix: Make tab view scrollable by @Ryrahul in #4644
- feat(dashboard): Add bulk cancel action and human-readable duration t… by @Ryrahul in #4361
- chore: Bump @vendure-io/docs-generator to 0.1.1 by @michaelbromley in #4664
- fix(admin-ui): Handle tokenMethod array form when generating ui-config (#4656) by @Draykee in #4663
- fix(dashboard): Inline route literal for tanstack router-generator by @michaelbromley in #4666
- fix(core): Avoid OOM in product-to-channel assign/remove via query relation strategy by @arthur-nesterenko in #4669
- chore: Migrate package management from npm to Bun by @michaelbromley in #4675
- fix(core): Create job queues in onModuleInit instead of onApplicationBootstrap by @michaelbromley in #4680
- fix(core): Prevent coupon usage limit bypass via concurrent checkout race condition by @grolmus in #4660
- fix(core): Resolve customer user via relation instead of email lookup by @grolmus in #4468
- fix(dashboard): Support action bar positioning relative to extensions by @izumi0uu in #4676
- chore: Add local asset storage strategy and its factory to exports by @DanielBiegler in #4671
- fix(core): Handle undefined relation in entity hydrator by @izumi0uu in #4672
- fix(dashboard): Handle empty customFields selection when all fields h… by @Ryrahul in #4652
- fix(dashboard): Add missing Italian translations by @claudiolor in #4645
- feat(dashboard): implement
isFullWidthmetadata prop by @casperiv0 in #4638 - fix(dashboard): Repair wrong-language msgstrs across hr/nb/tr/it/ja/ko/he/ro and harden i18n:apply by @michaelbromley in #4685
- fix(dashboard): correct mistranslated Swedish strings in sv.po by @comega-johan in #4684
- fix(dashboard): Ensure fulfillment arg default value is a string by @kyuna...
v3.6.2
This is a high-priority security patch that addresses a vulnerability that was reported a few days ago, described in GHSA-9pp3-53p2-ww9v
You should update your Vendure version as soon as possible. Due to the severity of this vulnerability, we have also published patches for older versions for those who cannot yet update to the latest v3.6.x version:
- v3.6.x -> v3.6.2
- v3.5.x -> v3.5.7
- v2.3.x -> v2.3.4
Thank you to @jacobfrantz1 for responsibly disclosing this issue.
What's Changed
- core Fix SQL injection via languageCode query parameter (3ff0bc1)
- core Sanitize search term for Postgres tsquery syntax (32c947d)
- fix: Use shipping line tax instead of channel tax by @Ryrahul in #4624
Full Changelog: v3.6.1...v3.6.2
v3.6.1
Highlights
This patch release addresses some important issues that were flagged by our community after the recent v3.6.0 release. Thank you to everyone who contributed issue reports and PRs with fixes!
Product creation flow improvements
This release includes several fixes and improvements to the product creation experience in the dashboard:
- Single-variant products no longer require option groups (#4616) -- You can now create a product with a single variant directly, without needing to set up option groups first. This simplifies the workflow for products that don't have multiple options (e.g. sizes, colors).
- Validation no longer blocks unchecked variant rows (#4610) -- Previously, unchecked (excluded) variant rows in the creation form could still trigger validation errors, preventing you from saving. These rows are now correctly skipped during validation.
- Fixed option group edit link on variant detail page (#4620) -- The link to edit an option group from the variant detail page was broken; this is now corrected.
CLI codemod fix
- tsconfig resolution in the migration codemod (#4599) -- The
@vendure/clicodemod for migrating dashboard extensions now correctly resolvestsconfig.jsonby walking up from the target directory rather than only looking in the current working directory. This fixes failures when running the codemod from a different directory than where the tsconfig lives.
Core fixes
- Product channel assignment (#4618) --
assignProductsToChannelwas not correctly assigning the Product entity itself to the target channel, only its variants. This is now fixed. - Order splitting channel deduplication (#4632) -- When an order's channel matched the default channel, the
OrderSplittercould produce duplicate channel entries, causing issues downstream. Channels are now correctly deduplicated.
Dashboard fixes and improvements
- Toaster z-index stacking (#4634) -- Toast notifications are now portalled to
document.body, fixing an issue where they were hidden behind dialogs due to CSS stacking context isolation. - Address dialog scrollability (#4622) -- The address dialog is now scrollable with a max height, fixing overflow issues on smaller screens.
- Query key invalidation (#4630) -- Fixed a cache invalidation mismatch that could cause stale data after mutations.
- Zod v4 support (#4607) -- The dashboard now supports Zod v4 and re-exports Zod from
@vendure/dashboard, so extensions don't need to manage their own Zod dependency. - Dashboard widget permissions (#4627) -- Dashboard widgets can now specify
requiresPermissions, restoring a capability from the legacy Angular admin UI. The built-in order widgets are now gated behindReadOrder.
What's Changed
- ci: Fix Playwright install in publish_and_install workflow by @michaelbromley in #4603
- ci: Use cd instead of working-directory for Playwright install by @michaelbromley in #4605
- feat(dashboard): Support Zod v4 and re-export Zod from @vendure/dashboard by @dlhck in #4607
- fix(ci): Remove [skip ci] from docs manifest commit to unblock PR checks by @dlhck in #4611
- fix(dashboard): Use index-based identification for collection filters by @grolmus in #4428
- fix(dashboard): Skip validation for unchecked variant rows by @michaelbromley in #4610
- chore(dashboard): Sync i18n catalogs by @michaelbromley in #4613
- fix(cli): Resolve tsconfig by walking up from target directory by @michaelbromley in #4599
- fix(dashboard): Fix collection filter e2e test selector by @michaelbromley in #4615
- feat(dashboard): Allow creating single variant without option groups by @michaelbromley in #4616
- fix(ci): Tolerate i18n line reference changes in sync check by @michaelbromley in #4617
- fix(core): Assign Product entity to channel in assignProductsToChannel by @michaelbromley in #4618
- fix(dashboard): Fix option group edit link on variant detail page by @michaelbromley in #4620
- refactor: Replace local docs generation code with @vendure-io/docs-generator by @oliverstreissi in #4626
- fix: Make address dialog scrollabe with max h by @Ryrahul in #4622
- fix: Match query key invalidation by @Ryrahul in #4630
- fix(core): Deduplicate channels in OrderSplitter when channelId matches default (#4631) by @Draykee in #4632
- fix: Add creator portal in toaster to avoid isolation:isolate stacking by @Ryrahul in #4634
- feat(dashboard): Add requiresPermissions support to dashboard widgets by @niko91i in #4627
Full Changelog: v3.6.0...v3.6.1
v3.6.0
Highlights
Shared Product Option Groups
Option groups are now shared resources — a single "Size" group can be linked to as many products as you need. They're also channel-aware, so multi-tenant setups can scope them per channel. There's a new dedicated management page in the dashboard, and CSV imports handle shared groups out of the box. A migration helper is provided for the data transition.
API Key Authentication
First-class API key support for machine-to-machine authentication. Create a key, scope it to specific permissions, use it in a header. Keys can be rotated and revoked at any time, with a full management UI in the dashboard. Community contribution from Daniel Biegler.
Translatable Assets
Asset now implements the Translatable interface — asset names and custom fields can vary per language. A migration helper copies existing names into translations automatically.
Configurable Order Tax Calculation
Order-level tax calculation is now pluggable via OrderTaxCalculationStrategy. Ships with DefaultOrderTaxCalculationStrategy (same as v3.5) and OrderLevelTaxCalculationStrategy.
Refreshed Dashboard
The dashboard is now built on @vendure-io/ui, our own open-source design system. Same tech stack, refined visual identity. Under the hood, headless primitives migrated from Radix UI to Base UI — all components now live in a single package. New extension points: toolbar items, function-based nav sections, component-based alert actions, improved ActionBar. Translation fallback placeholders for non-default languages. New Hungarian and Dutch translations.
Community Plugins
Several plugins have moved to the @vendure-community npm org with independent versioning. See the migration guide below for the full mapping.
Per-Queue Job Concurrency
Job queue concurrency now accepts a function (queueName: string) => number for per-queue control.
Other Notable Features
BootstrappedEvent— fires when the server is fully ready afterapp.listen()onBeforeAppListenhook — operate on the NestJS app before it starts listening- Async email generators
setOrderCurrencyCodeShop API mutation- Collection search filters (
collectionIds,collectionSlugs) - Braintree multi-currency support
- Custom field
dashboard: { visible: false }option - Settings Store management page
- Force update payment status
EntityAccessControlStrategy(developer preview) — row-level access control
Notable Fixes
- Dashboard compilation: 2x faster builds, 4x lower memory usage (replaced
ts.createProgramwith per-file transpilation) - Atomic, concurrency-safe
mergeOrders - Schema-qualified table paths in
EXISTSsubqueries (multi-schema Postgres fix) - Stale shipping line cleanup for deleted shipping methods
Migration Guide
This guide covers all breaking changes and required migration steps when upgrading from v3.5.x to v3.6.0.
1. Database Migration
Back up your database before proceeding. The migration involves moving data between tables, and while the helpers are idempotent and well-tested, a backup is always good practice before a schema change of this scale.
After updating your Vendure packages to v3.6, generate your migration:
npx vendure migrate --generate v36This generates a migration file in your configured migrations directory. Before starting your application, you need to edit the generated migration file to insert two data migration helpers. If you skip these steps, the auto-generated DDL will drop columns and data will be permanently lost.
1a. Asset Translation Data
The Asset entity is now translatable (#4171). The name column moves from the asset table to a new asset_translation table.
Open your generated migration file and look for the SQL that creates the asset_translation table. Further down in the same file, you'll find a statement that drops the name column from asset. Insert the migrateAssetTranslationData helper call between these two operations.
1b. Shared ProductOptionGroup Data
ProductOptionGroup and ProductOption are now shared resources that can belong to multiple products, and are channel-aware (#4469). The productId FK column on product_option_group is replaced by join tables.
Look for the SQL that creates the new join tables (e.g. CREATE TABLE "product_option_groups_product_option_group"). Further down, you'll find a statement that drops the productId column. Insert the migrateProductOptionGroupData helper call between these two operations.
Putting it together
Here is a real example of a generated Postgres migration with the helpers inserted. Your migration will look similar — the exact SQL and constraint names will vary, but the structure is the same.
import { MigrationInterface, QueryRunner } from 'typeorm';
import {
migrateAssetTranslationData,
migrateProductOptionGroupData,
} from '@vendure/core';
export class V361774950673940 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
// ... auto-generated DDL ...
await queryRunner.query(`CREATE TABLE "asset_translation" ("createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), "languageCode" character varying NOT NULL, "name" character varying NOT NULL, "id" SERIAL NOT NULL, "baseId" integer, CONSTRAINT "PK_2f22e63eefeef14d245bdb956b6" PRIMARY KEY ("id"))`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_4eed4464adef51f53e1c7d8021" ON "asset_translation" ("baseId") `, undefined);
// ... api_key tables, product_option join tables, etc. ...
await queryRunner.query(`CREATE TABLE "product_option_groups_product_option_group" ("productId" integer NOT NULL, "productOptionGroupId" integer NOT NULL, CONSTRAINT "PK_6a7a0291e226fbb0d4df828a483" PRIMARY KEY ("productId", "productOptionGroupId"))`, undefined);
// ... indexes ...
// *** INSERTED: migrate option group data before productId is dropped ***
await migrateProductOptionGroupData(queryRunner);
await queryRunner.query(`ALTER TABLE "product_option_group" DROP COLUMN "productId"`, undefined);
// *** INSERTED: migrate asset names before name column is dropped ***
await migrateAssetTranslationData(queryRunner);
await queryRunner.query(`ALTER TABLE "asset" DROP COLUMN "name"`, undefined);
// ... remaining DDL (foreign key constraints, etc.) ...
}
public async down(queryRunner: QueryRunner): Promise<any> {
// Auto-generated reverse DDL (no changes needed here)
}
}Tip: In a Postgres migration, look for the two DROP COLUMN lines — they'll be close together:
ALTER TABLE "product_option_group" DROP COLUMN "productId"
ALTER TABLE "asset" DROP COLUMN "name"
Insert each helper call immediately before its corresponding DROP COLUMN.
Note for SQLite users: SQLite doesn't support DROP COLUMN directly. TypeORM uses a temporary table pattern instead (create temp table without the column, copy data, drop original, rename). The same principle applies — insert the helpers before the data copy that omits the column — but the SQL will look different.
Both helpers are idempotent — safe to run multiple times without creating duplicate data. If the migration is interrupted partway through, you can re-run it safely.
Run the Migration
Start your application. The default index.ts scaffold calls runMigrations(config) before bootstrap(config), so the migration will be applied automatically on startup.
Alternatively, you can run it explicitly:
npx vendure migrate --run2. Community Plugins: New Package Names
Several plugins have been moved out of the Vendure monorepo into a dedicated community repo: vendurehq/vendure-community-plugins. They are now published under the @vendure-community npm org with independent versioning, decoupled from Vendure Core releases.
The plugin APIs are unchanged — same classes, same configuration, same behaviour. This is a package rename, not a rewrite.
If you use any of these plugins, uninstall the old package and install the new one:
| Old package (final version) | New package |
|---|---|
@vendure/elasticsearch-plugin@3.5.6 |
@vendure-community/elasticsearch-plugin@1.1.0 |
@vendure/payments-plugin@3.5.6 (Stripe) |
@vendure-community/stripe-plugin@1.0.0 |
@vendure/payments-plugin@3.5.6 (Braintree) |
@vendure-community/braintree-plugin@1.0.0 |
@vendure/payments-plugin@3.5.6 (Mollie) |
@vendure-community/mollie-plugin@1.0.0 |
@vendure/sentry-plugin@3.5.6 |
@vendure-community/sentry-plugin@1.0.0 |
@vendure/stellate-plugin@3.5.6 |
@vendure-community/stellate-plugin@1.0.0 |
@vendure/job-queue-plugin@3.5.6 (pub-sub) |
@vendure-community/pub-sub-plugin@1.0.0 |
For example, to migrate the Stripe plugin:
npm uninstall @vendure/payments-plugin
npm install @vendure-community/stripe-plugin@1.0.0Then update all imports in your TypeScript code:
// Before
import { ElasticsearchPlugin } from '@vendure/elasticsearch-plugin';
import { StripePlugin } from '@vendure/payments-plugin/package/stripe';
// After
import { ElasticsearchPlugin } from '@vendure-community/elasticsearch-plugin';
import { StripePlugin } from '@vendure-community/stripe-plugin';Search your codebase for any remaining references to the old package names — this includes imports, dynamic require() calls, and any configuration files that ref...
v3.5.6
Highlights
This is the final release of the v3.5.x line, before the imminent release of Vendure v3.6!
This release includes a whole host of improvements to the core and dashboard packages.
Note: this is also the final release for the following packages before they are moved to their new homes:
- @vendure/elasticsearch-plugin
- @vendure/payments-plugin
- @vendure/sentry-plugin
- @vendure/stellate-plugin
- @vendure/job-queue-plugin/package/pub-sub
Instructions on updating these packages will be included with the v3.6 release notes & migration guide.
Core fixes
- Atomic order merging —
OrderService.mergeOrdersis now concurrency-safe, preventing race conditions when multiple requests hit simultaneously - Stale shipping lines cleaned up — orders no longer carry phantom shipping lines from deleted shipping methods
- Schema-qualified EXISTS subqueries — fixes correctness issues in multi-schema PostgreSQL setups
- Channel cache invalidation — channel token is now set before query invalidation, fixing stale data issues after channel updates
- Wider
TranslationInputtype —languageCodenow accepts string literal unions, improving TypeScript ergonomics for custom language handling
Dashboard improvements
- Product options on variant detail — product options are now visible directly on the variant detail page
- Collection tree state persisted in URL — expanded/collapsed state survives navigation and page refreshes
- Custom fields hideable from UI — new
dashboardoption lets you hide custom fields from the Dashboard without removing them from the API - Nested address custom fields — custom fields on customer addresses now render correctly in the customer detail view
- Breadcrumbs update reactively — breadcrumbs now reflect entity name changes after a save without requiring a page reload
- Sidebar hover cards for collapsed nav — navigation sections now show a hover card when the sidebar is collapsed
- Faceted filter wrapping — filters no longer overflow horizontally on narrow screens
ConfigurableOperationInputvalidation fix — args with adefaultValueare now treated as valid even when empty- MoneyInput focus & onChange handling — fixes edge cases in the money input component
- Currency display in order table — correct currency now passed to the
Moneycomponent in order line items - OOM fix in plugin compilation — replaces
ts.createProgram()with per-filets.transpileModule()in the config loader, eliminating heap exhaustion whenvendure-config.tsimports plugins with heavy transitive dependencies (e.g.openai,ai,@ai-sdk/*). Compile time drops by up to 98% and memory use by up to 78%. PathAdaptergets newsourceRootoption⚠️ BREAKING CHANGE IN EDGE CASES — where monorepos using a custompathAdapter.getCompiledConfigPathcannot build the dashboard because the output directory structure is flattened: If you use a custompathAdapter, setsourceRootto your workspace root to restore correct nesting:
vendureDashboardPlugin({
pathAdapter: {
sourceRoot: path.resolve(__dirname, '../..'), // workspace root
getCompiledConfigPath: ({ outputPath, configFileName }) => {
return join(outputPath, 'apps', 'vendure-server', 'src', configFileName);
},
},
})Non-monorepo setups are unaffected — the default behaviour is unchanged.
New translations
- 🇳🇱 Dutch (
nl) — thanks @LazyClicks! - 🇭🇺 Hungarian (
hu) — thanks @atistrcsn!
What's Changed
- Feat(dashboard) : nl translations by @LazyClicks in #4188
- fix(dashboard): Treat args with defaultValue as valid in ConfigurableOperationInput by @michaelbromley in #4462
- fix(dashboard): Display variant creation errors and list query errors by @grolmus in #4460
- fix(dashboard): Fix validation & UX issues in product variant option groups by @biggamesmallworld in #4458
- fix(ci): Pin third-party GitHub Actions to full commit SHAs by @michaelbromley in #4475
- chore(repo): Address SonarQube low-hanging fruit issues by @michaelbromley in #4477
- fix(core): Remove stale shipping lines when shipping method no longer exists by @colinpieper in #4487
- feat(dashboard): Add Hungarian translations by @atistrcsn in #4423
- fix(testing): Prevent e2e port collisions across packages by @michaelbromley in #4484
- fix(core): Make OrderService.mergeOrders atomic and concurrency-safe by @michaelbromley in #4488
- fix(dashboard): Use null instead of undefined when clearing relation custom fields by @grolmus in #4495
- fix(core): use schema-qualified table paths in EXISTS subqueries by @yasserlens in #4501
- fix: set channel token before query invalidation by @Ryrahul in #4472
- fix(dashboard): Show hover card for collapsed sidebar nav sections by @oliverstreissi in #4440
- fix: Channel cache invalidation after update by @Ryrahul in #4461
- fix(dashboard): Wrap faceted filters to prevent horizontal overflow by @grolmus in #4467
- fix(dashboard): Detect plugins compiled with tslib importHelpers by @michaelbromley in #4518
- fix(dashboard): Forward all ControllerProps in FormFieldWrapper by @gabriellbui in #4513
- fix(dashboard): Update breadcrumb reactively after entity mutation by @HouseinIsProgramming in #4512
- chore: Trim CLAUDE.md to implicit knowledge only by @BibiSebi in #4522
- fix(core): Widen TranslationInput languageCode to accept string literal unions by @HouseinIsProgramming in #4534
- fix(dashboard): Pass correct currency prop to Money component in order table by @isxwor in #4541
- feat(core): Add
dashboardoption to hide custom fields from Dashboard UI by @HouseinIsProgramming in #4544 - fix(docs): Correct typo in EventBus JSDoc by @latifniz in #4533
- fix(docs): Correct typo in ProductEvent JSDoc by @latifniz in #4539
- fix: Add nested address custom field in customer detail by @Ryrahul in #4546
- fix(ci): Update deploy dashboard workflow to match minor branch by @michaelbromley in #4556
- fix(dashboard): Replace ts.createProgram with per-file transpilation to prevent OOM by @michaelbromley in #4561
- fix(dashboard): Use tsconfig baseUrl as source root for monorepo pathAdapters by @michaelbromley in #4570
- docs: Add manifest.json and compile script by @dlhck in #4572
- feat(dashboard): Display product options on variant detail page by @grolmus in #4187
- fix(dashboard): Add missing i18n translations and CI sync check by @michaelbromley in #4578
- fix(dashboard): Persist collection tree expanded state in URL search params by @biggamesmallworld in #4509
- fix(dashboard): MoneyInput component to handle focus state and onChange by @harshit078 in #4586
New Contributors
- @LazyClicks made their first contribution in #4188
- @atistrcsn made their first contribution in #4423
- @latifniz made their first contribution in #4533
- @harshit078 made their first contribution in #4586
Full Changelog: v3.5.5...v3.5.6
v3.5.5
Release Highlights
This release is mostly focused on continued polish for the React dashboard, with a large batch of fixes including: order line discounts no longer showing [object Object] (#4378), proper disabled state propagation for form inputs (#4425), custom fields support on fulfillments (#4386) and on OrderLines in the modify order page (#4432), dark mode tooltip readability (#4393), and a number of UX improvements like a "Now" button on the date-time picker, better default sort orders, and scrollable configurable operation dropdowns.
On the feature side, product and variant lists now support filtering by facet value (#4415), making it much easier to locate products with specific attributes.
Core fixes include channel-aware productInStock cache keys (#4214), proper persistence of custom fields in updateGlobalSettings (#4343), and correct language fallbacks in FacetService and FacetValueService (#4434).
What's Changed
- fix(cli): Fix crash when cancelling follow-up feature selection during plugin creation by @michaelbromley in #4371
- fix(dashboard): Add missing dashboard dependency by @fcFn in #4384
- fix(dashboard): Return null for nullable non-string field defaults by @HouseinIsProgramming in #4339
- fix(dashboard): Fix order line discounts showing
[object Object]by @gabriellbui in #4378 - fix(core,elasticsearch-plugin): Include channelId in productInStock cache key by @BibiSebi in #4214
- fix(core): Persist customFields in updateGlobalSettings mutation by @Ryrahul in #4343
- fix(dashboard): Multiple small UI fixes by @michaelbromley in #4394
- fix(dashboard): Keep address visible when editing during order modification by @michaelbromley in #4413
- feat(dashboard): Add facet value filter to product & variant lists by @michaelbromley in #4415
- fix: Refresh language selector after saving language by @Ryrahul in #4417
- fix(create): Use promise-based mysql2 API for database check by @michaelbromley in #4418
- fix: Add custom fields of fulfillment in dashboard by @Ryrahul in #4386
- fix(dashboard): Propagate disabled state via React props for all form inputs by @michaelbromley in #4425
- fix(core): Handle empty sortedAssets in updateEntityAssets by @colinpieper in #4397
- fix(dashboard): Show custom fields edit button on OrderLine in modify order page by @DeltaSAMP in #4432
- fix(dashboard): Fix localization issues in Insights Dashboard by @HouseinIsProgramming in #4189
- fix(dashboard): add scroll to configurable operation dropdown by @Jeffrey-manzl in #4435
- fix(core): use channel defaultLanguageCode as translation fallback in FacetService and FacetValueService by @mr-mpage in #4434
New Contributors
- @fcFn made their first contribution in #4384
- @Jeffrey-manzl made their first contribution in #4435
- @mr-mpage made their first contribution in #4434
Full Changelog: v3.5.4...v3.5.5
v3.5.4
Release Highlights
Dashboard Fixes
A solid batch of fixes for the new React dashboard this release:
- List relation custom fields now save correctly — Previously, list-type relation custom fields weren't being persisted properly. (#4206)
- FacetValueInput passes native arrays — The
onChangehandler now correctly passes native arrays rather than wrapped values. (#4209) - ESM path alias resolution — Extension path aliases are now resolved relative to the source file location, fixing issues with dashboard extensions that use custom path mappings. (#4323)
- Required args validation in ConfigurableOperationInput — Configurable operations (e.g. promotions, shipping calculators) now correctly validate required arguments before submission. (#4202)
- Order detail refreshes after mutations — The order entity and history timeline now refresh correctly after all mutations, preventing stale data display. (#4338)
- Missing translations & CI check — Added missing translation keys and a CI script to catch gaps going forward. (#4207)
Core Fixes
- Promotion side effects now run before OrderLine save — Fixes an issue where in-memory changes made by promotion side effects (e.g.
onActivate/onDeactivatemodifying custom fields) were not being persisted. The side effects are now executed before the OrderLine save in both theapplyPriceAdjustmentsandmodifyOrdercode paths. (#4350) - Entity events now emit the post-update entity —
VendureEntityEventfor "updated" events now correctly includes the entity state after the update, rather than the pre-update state. (#4352) - Channel-aware tax zone cache keys — Active tax zone lookups are now cached per-channel, fixing incorrect tax calculations when operating across multiple channels with different tax configurations. (#4329)
Create (Scaffolding)
- Added
ts-nodeto devDependencies — New projects scaffolded with@vendure/createnow includets-node, which was previously missing and caused errors when running migration scripts. (#4212) - Explicit localhost API host in Vite config — The storefront Vite template now uses an explicit
localhosthost for the API proxy, fixing connectivity issues on some systems. (#4349)
Other Improvements
- Dashboard Playwright e2e test suite — A new end-to-end test suite using Playwright has been added for the dashboard, laying the groundwork for automated UI regression testing. (#4355)
- GraphiQL transparent background — The embedded GraphiQL plugin now uses a transparent background, making it blend properly with the dashboard theme. (#4205)
- Swahili translation — Added Swahili (sw) as a new admin UI language. (#4217)
- Documentation overhaul — Major rework of the core-concepts docs with new pages, sidebar reorganisation, SEO metadata, and restored code examples. (#4347)
What's Changed
- fix(ci): Correct CI Bot secret names in CLA workflow by @dlhck in #4211
- fix(dashboard): Pass native arrays from FacetValueInput onChange by @jantokic in #4209
- fix(graphiql-plugin): Make embedded mode background transparent by @dlhck in #4205
- chore: Deprecate community plugins by @michaelbromley in #4215
- ci: Add workflow to auto-generate docs on PR changes by @michaelbromley in #4216
- ci: Add AI-generated commit messages to docs workflow by @michaelbromley in #4219
- fix(dashboard): Fix list relation custom fields not saving correctly by @gabriellbui in #4206
- fix(create): Add ts-node to scaffolded project devDependencies by @HouseinIsProgramming in #4212
- chore(admin-ui): Add Swahili translation by @barakamwakisha in #4217
- fix(dashboard): Resolve ESM path aliases relative to source file location by @biggamesmallworld in #4323
- fix(dashboard): Add missing translations and CI check script by @grolmus in #4207
- fix(dashboard): Validate required args in ConfigurableOperationInput by @grolmus in #4202
- docs: Overhaul core-concepts, new pages, sidebar reorg, SEO metadata, restored code examples by @dlhck in #4347
- fix(create): Use explicit localhost API host in vite config template by @dlhck in #4349
- fix(core): Emit post-update entity in VendureEntityEvent for updated events by @michaelbromley in #4352
- feat(dashboard): Add Playwright e2e test suite by @michaelbromley in #4355
- ci: Optimize Build & Test workflow by @michaelbromley in #4357
- fix(core): Use channel-aware cache keys for active tax zone by @oliverstreissi in #4329
- fix(dashboard): Refresh order entity and history after all mutations by @HouseinIsProgramming in #4338
- fix(core): Run promotion side effects before OrderLine save by @DeltaSAMP in #4350
- fix(create): Fix welcome message on create by @michaelbromley in #4363
Full Changelog: v3.5.3...v3.5.4
v3.5.3
Highlights
Security Fix
- Timing attack vulnerability patched - The
NativeAuthenticationStrategyhad a timing discrepancy that could allow attackers to enumerate valid email addresses by measuring login response times. All authentication attempts now take consistent time, preventing account enumeration attacks. Thanks to Christbowel for the responsible disclosure.- CVE-2026-25050
- This is considered low severity
Performance
- Collections query N+1 fix - Added a new
productVariantCountfield that uses a simple count query instead of loading all variants just to get totals. Massively reduces database load when listing collections via the Dashboard
Dashboard Compilation
- Issues with compilation of the Dashboard were traced back to the use of the SWC compiler, which often conflicted with other dependencies in real projects. We moved to a different compiler now which should handle the issues people have been running into.
Dashboard New Features
- Refund & Cancel Order Dialog - The Dashboard now has a proper refund workflow with line item selection, quantity inputs, payment allocation across multiple payments, and configurable refund reasons.
- Sub-collection pagination - Large collection trees are now paginated for better performance and UX.
- Auth methods on profile page - Users can now see their linked authentication methods (native, external providers, etc.) on their profile.
- Customer search by phone - Customer list now filters by phone number as well as name/email.
- Dynamic schema-driven languages/currencies - Dashboard language and currency selectors are now driven by your server schema.
Notable Fixes
- Promotion usage counting - Seller orders are now excluded when counting promotion usage, fixing incorrect limits in multi-vendor setups.
- SubscribableJob.updates() - Fixed a bug where
job.updates()would complete after a single emission instead of streaming updates until the job finished. This affected anyone usinglastValueFrom(job.updates())patterns. - Custom fields on ProductVariantPrice - Both persistence and display in the Dashboard are now working correctly.
- Localized custom fields -
localeStringandlocaleTextcustom fields on translatable entities now persist properly. - ChangeChannelEvent - Now correctly publishes with the new channel IDs instead of the old ones.
- pnpm and Bun support - Dashboard plugin detection now works properly with pnpm and Bun package managers.
What's Changed
- feat(dashboard): Provide entity object to draft-order-detail Page component by @lucatk in #4073
- fix(dashboard): Prevent NaN or empty values in Latest Orders table w… by @raidsobhi in #4092
- fix(dashboard): Re-sync channel token when activeChannelId persists but token is cleared by @niko91i in #4094
- fix(dashboard): Fix incorrect currency being displayed in dashboard u… by @raidsobhi in #4090
- fix(dashboard): Channel switcher not scrollable if list exceeds screen height by @lucatk in #4075
- fix(dashboard): hide "Add channel" button for users without CreateChannel permission by @niko91i in #4097
- fix(dashboard): Fix compilation issues caused by SWC version issues by @michaelbromley in #4105
- feat(core): Expand userHasPermissions docstring; Add new userHasAllPermissions method by @HouseinIsProgramming in #4107
- fix(dashboard): Fix struct custom fields not rendering options or custom components by @michaelbromley in #4115
- fix(core): Use previously unused relations filter in findByCustomerId by @DeltaSAMP in #4118
- feat(dashboard): Use dynamic schema-driven languages and currencies by @TheHypnoo in #4111
- fix(core): Fix SubscribableJob.updates() completing after single emission by @michaelbromley in #4120
- feat(create): Set api url to
autofor newly created projects by @martijnvdbrug in #4102 - chore: Improve dashboard test reliability in publish workflow by @michaelbromley in #4122
- docs: add warning to distinguish custom field extension vs detail input field extension by @BibiSebi in #4123
- fix(create,docs): add useDefineForClassFields to fix ES2022 by @HouseinIsProgramming in #4116
- chore: Speed up publish_and_install workflow by @michaelbromley in #4127
- fix(dashboard): Dashboard plugin detection with pnpm by @oliverstreissi in #4126
- fix(core): Respect publishConfig.directory in npm publish workflow by @michaelbromley in #4131
- fix(dashboard): Bump @tanstack/react-router to fix ID param error by @jantokic in #4153
- fix(dashboard): Hide bulk action bar when no selected items are visible by @jantokic in #4151
- Fix(Mollie): allow overriding
immediateCapturefrom the plugin level by @martijnvdbrug in #4142 - fix(dashboard): Resolve tsconfig path aliases in ESM mode by @michaelbromley in #4134
- feat: Implement productVariantCount in collections query by @biggamesmallworld in #4132
- docs: Fix typo in plugins documentation by @aidenBarrett96 in #4145
- fix(dashboard): Register text-form-input component by @BibiSebi in #4149
- fix(dashboard): Preserve string arg values without JSON parsing in form inputs by @gabriellbui in #4156
- fix(dashboard): Fix entity creation when using a non default language by @tbouliere-datasolution in #4157
- chore: Add Claude Code rules for dashboard i18n by @HouseinIsProgramming in #4166
- fix(dashboard): Fix gross price display under price includes tax by @Qingbao in #4138
- fix(dashboard): Fix usePaginatedList context duplication in extensions by @michaelbromley in #4164
- feat(dashboard): Add pagination for sub-collections in collection list by @biggamesmallworld in #4154
- fix(dashboard): Fix displaying HistoryEntry for CustomerEmailUpdateComponent by @SiebelsTim in #4167
- fix(dashboard): Fallback to default input when custom form component not found by @DeltaSAMP in #4168
- feat(docs): Migrate documentation to @vendure/docs package by @dlhck in #4124
- fix(core): Correctly publish ChangeChannelEvent with new channel IDs. by @Draykee in #4176
- feat(dashboard): Add disabled option to exclude columns in ListPage by @BibiSebi in #4170
- fix(dashboard): Show all items in the order details page, clean up fu… by @oidt in #4160
- feat(dashboard): Add refundOrder and cancelOrder GraphQL mutations by @HouseinIsProgramming in #4130
- fix: Sync package-lock.json with package.json by @HouseinIsProgramming in #4178
- feat(dashboard): Display authentication methods on profile page by @dlhck in #4179
- fix(dashboard): Clarify draft order completion UX and add ar translations by @mohamed7-dev in #4163
- fix(dashboard): Collection contents not showing after saving filters by @gabriellbui in #4128
- feat(dashboard): Add phone number field to customer list query and search functionality by @TheHypnoo in #4100
- fix(dashboard): Transform Lingui macros in third-party npm packages by @michaelbromley in #4182
- fix(dashboard): Support Bun package manager in plugin discovery by @oliverstreissi in #4183
- fix(core): Persist custom fields when creating new ProductVariantPrice by @michaelbromley in #4184
- fix(dashboard): Persist localeString/localeText custom fields on translatable entities by @michaelbromley in #4185
- fix(core): Exclude seller orders when counting promotion usage by @twlite in #4070
- fix(dashboard): Boolean fields in DetailPage now show correct value by @oliverstreissi in #4186
- fix(dashboard): Display custom fields on product variant prices by @mehringer68 in #4180
New Contributors
- @lucatk made their first contribution in #4073
- @raidsobhi made their first contribution in #4092
- @niko91i made their first contr...
v3.5.2
Here are the notable improvements in Vendure v3.5.2:
Next.js Storefront
When you start a new project using @vendure/create, you now have the option to include our brand-new Next.js Storefront! This gives you a true full-stack headless commerce project in a modern monorepo configuration.
For existing projects, you can also try out the storefront:
Dashboard fixes
We have continued to refine and polish the new Dashboard with over 20 fixes and features in this release, including:
- Drag-drop reordering of collections
- Ability to add surcharges when modifying orders
- Improved right-to-left layout
Core fixes
There are a number of significant fixes in Vendure core too, including:
- Huge performance improvement when dealing with self-referencing entity lists (e.g. if you define a Product relation custom field on the Product entity)
- A very important fix for scheduled tasks on postgres, to ensure that tasks get executed by only a single worker in horizontally-scaled environments
- Fixes and optimizations to advanced filtering of paginated list queries
📚v3.5.2 Changelog
What's Changed
- refactor(dashboard): Sort languages by their label instead of language label by @BibiSebi in #3981
- Fix Docs icon location in GraphiQL explanation by @nezerk in #3982
- Fix(admin UI): apply useGlobalOutOfStockThreshold correctly by @PavanendraBaahubali in #3993
- fix(dashboard): Fix for custom nav section placement by @dev-ish in #3995
- docs: fix typo in @Args documentation by @MuhammadAnas8 in #4000
- fix(dashboard): Fix port:auto for api requests by @SiebelsTim in #3980
- fix(dashboard): Move shared config for global-languages to reuse by @DeltaSAMP in #4024
- perf: Fix slow queries when entities have self-referencing relations by @gabriellbui in #4020
- fix(job-queue-plugin): Upgrade @google-cloud/pubsub to fix protobufjs vulnerability by @dlhck in #4042
- Fix/dashboard typescript errors by @grolmus in #3996
- Add Bulgarian (bg) translation for the new Vendure DashboardFeat/bg translation by @k2cult in #4001
- feat(dashboard): Custom icons in data table faceted filters by @alingabrieldm in #3998
- feat(dashboard): Add surcharge functionality to order modification page by @BibiSebi in #4044
- fix: Decimal values in tax rate input by @gabriellbui in #4052
- feat(dashboard): Implement dragging to reorder collections by @biggamesmallworld in #4035
- feat(create): Add Next.js storefront option to create command by @dlhck in #4015
- fix(dashboard): Display shipping method in order summary by @michaelbromley in #4054
- fix(dashboard): keep job queue dropdown open during auto refresh by @starry-osean in #4059
- Fix/facet values opening by @grolmus in #4064
- Polish RTL layout and Arabic translation in dashboard by @mohamed7-dev in #4008
- fix(dashboard): Persist user-defined column order in saved views by @PavanendraBaahubali in #3988
- feat(dashboard): Product channel assigner by @biggamesmallworld in #4063
- fix(job-queue-plugin): Respect configured prefix in RedisJobBufferStorageStrategy by @colinpieper in #4066
- fix(core): Update validation for session if we work with relationLoadStrategy query by @monrostar in #3691
- fix(core): Correct behaviour of complex list filtering by @michaelbromley in #4068
- fix(core): Fix scheduled task concurrent execution on Postgres by @michaelbromley in #4069
- docs: Update docs to include new Next.js starter by @michaelbromley in #4060
New Contributors
- @nezerk made their first contribution in #3982
- @PavanendraBaahubali made their first contribution in #3993
- @MuhammadAnas8 made their first contribution in #4000
- @k2cult made their first contribution in #4001
- @alingabrieldm made their first contribution in #3998
- @starry-osean made their first contribution in #4059
- @mohamed7-dev made their first contribution in #4008
Full Changelog: v3.5.1...v3.5.2