{
"name": "root",
"private": true,
"workspaces": {
"packages": [
"packages/medusa",
"packages/medusa-test-utils",
"packages/modules/*",
"packages/modules/providers/*",
"packages/plugins/*",
"packages/core/*",
"packages/framework/*",
"packages/cli/*",
"packages/cli/oas/*",
"packages/*",
"packages/admin/*",
"packages/design-system/*",
"packages/generated/*",
"integration-tests/**/*"
]
},
"devDependencies": {
"@atomico/rollup-plugin-sizes": "^1.1.4",
"@faker-js/faker": "^9.2.0",
"@medusajs/eslint-plugin": "workspace:^",
"@rollup/plugin-node-resolve": "^15.1.0",
"@rollup/plugin-replace": "^5.0.2",
"@storybook/addon-essentials": "^8.3.5",
"@storybook/addon-interactions": "^8.3.5",
"@storybook/addon-links": "^8.3.5",
"@storybook/addon-styling": "^1.3.7",
"@storybook/blocks": "^8.3.5",
"@storybook/react": "^8.3.5",
"@storybook/react-vite": "^8.3.5",
"@storybook/testing-library": "^0.2.2",
"@swc/core": "^1.7.28",
"@swc/helpers": "^0.5.11",
"@swc/jest": "^0.2.36",
"@testing-library/dom": "^9.3.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.4.3",
"@types/autocannon": "^7.12.5",
"@types/chalk": "^2.2.0",
"@types/commander": "^2.12.2",
"@types/compression": "^1.7.5",
"@types/configstore": "^6.0.0",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/fs-extra": "11.0.1",
"@types/inquirer": "^9.0.3",
"@types/js-yaml": "^4.0.9",
"@types/jsdom": "^27.0.0",
"@types/jsonwebtoken": "^8.5.9",
"@types/lodash": "^4.17.15",
"@types/lodash.debounce": "^4.0.9",
"@types/lodash.isequal": "^4.5.8",
"@types/lodash.mergewith": "^4.6.9",
"@types/multer": "^2.0.0",
"@types/node": "^20.12.11",
"@types/node-emoji": "^1.8.2",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.2.25",
"@types/validator": "^13.7.17",
"@types/wait-on": "^5.3.1",
"@types/yargs": "^15.0.15",
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"@typescript-eslint/rule-tester": "^8.0.0",
"@vitejs/plugin-react": "^4.2.1",
"@vitest/coverage-v8": "^0.32.2",
"ajv": "^8.18.0",
"autocannon": "^8.0.0",
"autoprefixer": "^10.4.19",
"awilix": "^8.0.1",
"axios": "^1.13.1",
"axios-mock-adapter": "^1.19.0",
"chromatic": "^6.20.0",
"configstore": "^5.0.1",
"cross-env": "^5.2.1",
"esbuild": "^0.25.0",
"eslint": "^8.40.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.31.11",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"eslint-plugin-storybook": "^10.0.1",
"eslint-plugin-unused-imports": "^2.0.0",
"expect-type": "^0.20.0",
"express": "^4.21.0",
"faker": "^5.5.3",
"get-port": "^5.1.1",
"glob": "13.0.6",
"import-from": "^3.0.0",
"ioredis": "^5.4.1",
"jest": "^29.7.0",
"js-yaml": "^4.2.0",
"jsdom": "^27.1.0",
"lint-staged": "^11.2.6",
"msw": "^2.3.0",
"node-notifier": "^10.0.1",
"nodemon": "^2.0.20",
"pg-god": "^1.0.12",
"postcss": "^8.5.10",
"posthog-node": "^5.11.0",
"prettier": "^2.8.8",
"prettier-plugin-tailwindcss": "^0.2.3",
"prop-types": "^15.8.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "6.30.3",
"resize-observer-polyfill": "^1.5.1",
"resolve-cwd": "^3.0.0",
"rimraf": "^5.0.1",
"rollup": "^4.28.1",
"rollup-plugin-esbuild": "^5.0.0",
"rollup-plugin-ts": "^3.2.0",
"rollup-plugin-visualizer": "^5.9.2",
"storybook": "^8.3.5",
"supertest": "^7.1.4",
"tailwindcss": "^3.4.3",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.2",
"tsc-alias": "^1.8.7",
"tsup": "^8.4.0",
"turbo": "^1.6.3",
"typescript": "^5.6.2",
"uuid": "^9.0.0",
"vite": "^5.4.21",
"vite-plugin-inspect": "^0.8.7",
"vite-plugin-turbosnap": "^1.0.2",
"vitest": "^3.0.5",
"yalc": "^1.0.0-pre.53",
"zod": "4.2.0",
"zod-validation-error": "5.0.0"
},
"scripts": {
"build": "turbo run build build:plugin --concurrency=100% --no-daemon",
"lint": "eslint --ignore-path .eslintignore --ext .js,.ts,.tsx .",
"lint:medusa": "eslint --no-eslintrc --config eslint.medusa.cjs --ignore-path .eslintignore --ext .js,.ts,.tsx .",
"lint:path": "eslint --ignore-path .eslintignore --ext .js,.ts,.tsx",
"prettier": "prettier",
"jest": "jest",
"test": "turbo run test --no-daemon --no-cache --force",
"test:chunk": "./scripts/run-workspace-unit-tests-in-chunks.sh",
"test:integration:packages:fast": "turbo run test:integration --concurrency=1 --no-daemon --no-cache --force --filter='./packages/core/*' --filter='./packages/medusa' --filter='./packages/modules/*' --filter='./packages/modules/providers/*' --filter='!./packages/modules/{workflow-engine-redis,index,product,order,cart}'",
"test:integration:packages:slow": "turbo run test:integration --concurrency=1 --no-daemon --no-cache --force --filter='./packages/modules/{workflow-engine-redis,index,product,order,cart}'",
"test:integration:packages": "turbo run test:integration --concurrency=1 --no-daemon --no-cache --force --filter='./packages/core/*' --filter='./packages/medusa' --filter='./packages/modules/*' --filter='./packages/modules/providers/*'",
"test:integration:http": "turbo run test:integration:chunk --no-daemon --no-cache --force --filter=integration-tests-http",
"test:integration:modules": "turbo run test:integration:chunk --no-daemon --no-cache --force --filter=integration-tests-modules",
"generate:http-types": "yarn workspace @medusajs/http-types-generator generate:http-types",
"validate:http-types": "yarn workspace @medusajs/http-types-generator validate:http-types",
"openapi:generate": "yarn ./packages/cli/oas/oas-github-ci run ci --with-full-file",
"medusa-oas": "yarn ./packages/cli/oas/medusa-oas-cli run medusa-oas",
"release:snapshot": "changeset publish --no-git-tags --snapshot --tag snapshot",
"release:next": "chgstangeset publish --no-git-tags --snapshot --tag next",
"version:next": "changeset version --snapshot next",
"release": "changeset publish",
"version": "changeset version && yarn install --no-immutable"
},
"dependencies": {
"@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.26.0",
"import-from": "^3.0.0"
},
"resolutions": {
"@redocly/cli/react": "^17.0.1",
"@redocly/cli/react-dom": "^17.0.1",
"lodash": "^4.18.1",
"pg": "8.16.3",
"@changesets/get-github-info@^0.5.2": "patch:@changesets/get-github-info@npm:^0.5.2#.yarn/patches/changesets-github-info.patch",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.2.25",
"semver": "^7.5.2",
"axios": "^1.13.1",
"esbuild": "^0.25.0",
"on-headers": "^1.1.0",
"postcss": "^8.5.10",
"validator": "^13.15.20",
"@opentelemetry/core": "^2.7.0",
"@rushstack/node-core-library/ajv": "^8.18.0",
"@changesets/assemble-release-plan@^6.0.9": "patch:@changesets/assemble-release-plan@npm:^6.0.9#.yarn/patches/@changesets-assemble-release-plan-npm-6.0.9-e01af97ef4.patch"
},
"packageManager": "yarn@3.2.1"
}
Not applicable.
The supported product update contract has no atomic option-value delta. A
variant cannot reference a newly added value until a separate value-link
operation commits.
Product updates cannot atomically add option values used by replacement variants
Package.json file
{ "name": "root", "private": true, "workspaces": { "packages": [ "packages/medusa", "packages/medusa-test-utils", "packages/modules/*", "packages/modules/providers/*", "packages/plugins/*", "packages/core/*", "packages/framework/*", "packages/cli/*", "packages/cli/oas/*", "packages/*", "packages/admin/*", "packages/design-system/*", "packages/generated/*", "integration-tests/**/*" ] }, "devDependencies": { "@atomico/rollup-plugin-sizes": "^1.1.4", "@faker-js/faker": "^9.2.0", "@medusajs/eslint-plugin": "workspace:^", "@rollup/plugin-node-resolve": "^15.1.0", "@rollup/plugin-replace": "^5.0.2", "@storybook/addon-essentials": "^8.3.5", "@storybook/addon-interactions": "^8.3.5", "@storybook/addon-links": "^8.3.5", "@storybook/addon-styling": "^1.3.7", "@storybook/blocks": "^8.3.5", "@storybook/react": "^8.3.5", "@storybook/react-vite": "^8.3.5", "@storybook/testing-library": "^0.2.2", "@swc/core": "^1.7.28", "@swc/helpers": "^0.5.11", "@swc/jest": "^0.2.36", "@testing-library/dom": "^9.3.1", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.4.3", "@types/autocannon": "^7.12.5", "@types/chalk": "^2.2.0", "@types/commander": "^2.12.2", "@types/compression": "^1.7.5", "@types/configstore": "^6.0.0", "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/fs-extra": "11.0.1", "@types/inquirer": "^9.0.3", "@types/js-yaml": "^4.0.9", "@types/jsdom": "^27.0.0", "@types/jsonwebtoken": "^8.5.9", "@types/lodash": "^4.17.15", "@types/lodash.debounce": "^4.0.9", "@types/lodash.isequal": "^4.5.8", "@types/lodash.mergewith": "^4.6.9", "@types/multer": "^2.0.0", "@types/node": "^20.12.11", "@types/node-emoji": "^1.8.2", "@types/react": "^18.3.2", "@types/react-dom": "^18.2.25", "@types/validator": "^13.7.17", "@types/wait-on": "^5.3.1", "@types/yargs": "^15.0.15", "@typescript-eslint/eslint-plugin": "^6.19.0", "@typescript-eslint/parser": "^6.19.0", "@typescript-eslint/rule-tester": "^8.0.0", "@vitejs/plugin-react": "^4.2.1", "@vitest/coverage-v8": "^0.32.2", "ajv": "^8.18.0", "autocannon": "^8.0.0", "autoprefixer": "^10.4.19", "awilix": "^8.0.1", "axios": "^1.13.1", "axios-mock-adapter": "^1.19.0", "chromatic": "^6.20.0", "configstore": "^5.0.1", "cross-env": "^5.2.1", "esbuild": "^0.25.0", "eslint": "^8.40.0", "eslint-config-google": "^0.14.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.5", "eslint-plugin-storybook": "^10.0.1", "eslint-plugin-unused-imports": "^2.0.0", "expect-type": "^0.20.0", "express": "^4.21.0", "faker": "^5.5.3", "get-port": "^5.1.1", "glob": "13.0.6", "import-from": "^3.0.0", "ioredis": "^5.4.1", "jest": "^29.7.0", "js-yaml": "^4.2.0", "jsdom": "^27.1.0", "lint-staged": "^11.2.6", "msw": "^2.3.0", "node-notifier": "^10.0.1", "nodemon": "^2.0.20", "pg-god": "^1.0.12", "postcss": "^8.5.10", "posthog-node": "^5.11.0", "prettier": "^2.8.8", "prettier-plugin-tailwindcss": "^0.2.3", "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "6.30.3", "resize-observer-polyfill": "^1.5.1", "resolve-cwd": "^3.0.0", "rimraf": "^5.0.1", "rollup": "^4.28.1", "rollup-plugin-esbuild": "^5.0.0", "rollup-plugin-ts": "^3.2.0", "rollup-plugin-visualizer": "^5.9.2", "storybook": "^8.3.5", "supertest": "^7.1.4", "tailwindcss": "^3.4.3", "ts-jest": "^29.1.0", "ts-node": "^10.9.2", "tsc-alias": "^1.8.7", "tsup": "^8.4.0", "turbo": "^1.6.3", "typescript": "^5.6.2", "uuid": "^9.0.0", "vite": "^5.4.21", "vite-plugin-inspect": "^0.8.7", "vite-plugin-turbosnap": "^1.0.2", "vitest": "^3.0.5", "yalc": "^1.0.0-pre.53", "zod": "4.2.0", "zod-validation-error": "5.0.0" }, "scripts": { "build": "turbo run build build:plugin --concurrency=100% --no-daemon", "lint": "eslint --ignore-path .eslintignore --ext .js,.ts,.tsx .", "lint:medusa": "eslint --no-eslintrc --config eslint.medusa.cjs --ignore-path .eslintignore --ext .js,.ts,.tsx .", "lint:path": "eslint --ignore-path .eslintignore --ext .js,.ts,.tsx", "prettier": "prettier", "jest": "jest", "test": "turbo run test --no-daemon --no-cache --force", "test:chunk": "./scripts/run-workspace-unit-tests-in-chunks.sh", "test:integration:packages:fast": "turbo run test:integration --concurrency=1 --no-daemon --no-cache --force --filter='./packages/core/*' --filter='./packages/medusa' --filter='./packages/modules/*' --filter='./packages/modules/providers/*' --filter='!./packages/modules/{workflow-engine-redis,index,product,order,cart}'", "test:integration:packages:slow": "turbo run test:integration --concurrency=1 --no-daemon --no-cache --force --filter='./packages/modules/{workflow-engine-redis,index,product,order,cart}'", "test:integration:packages": "turbo run test:integration --concurrency=1 --no-daemon --no-cache --force --filter='./packages/core/*' --filter='./packages/medusa' --filter='./packages/modules/*' --filter='./packages/modules/providers/*'", "test:integration:http": "turbo run test:integration:chunk --no-daemon --no-cache --force --filter=integration-tests-http", "test:integration:modules": "turbo run test:integration:chunk --no-daemon --no-cache --force --filter=integration-tests-modules", "generate:http-types": "yarn workspace @medusajs/http-types-generator generate:http-types", "validate:http-types": "yarn workspace @medusajs/http-types-generator validate:http-types", "openapi:generate": "yarn ./packages/cli/oas/oas-github-ci run ci --with-full-file", "medusa-oas": "yarn ./packages/cli/oas/medusa-oas-cli run medusa-oas", "release:snapshot": "changeset publish --no-git-tags --snapshot --tag snapshot", "release:next": "chgstangeset publish --no-git-tags --snapshot --tag next", "version:next": "changeset version --snapshot next", "release": "changeset publish", "version": "changeset version && yarn install --no-immutable" }, "dependencies": { "@changesets/changelog-github": "^0.4.8", "@changesets/cli": "^2.26.0", "import-from": "^3.0.0" }, "resolutions": { "@redocly/cli/react": "^17.0.1", "@redocly/cli/react-dom": "^17.0.1", "lodash": "^4.18.1", "pg": "8.16.3", "@changesets/get-github-info@^0.5.2": "patch:@changesets/get-github-info@npm:^0.5.2#.yarn/patches/changesets-github-info.patch", "@types/react": "^18.3.2", "@types/react-dom": "^18.2.25", "semver": "^7.5.2", "axios": "^1.13.1", "esbuild": "^0.25.0", "on-headers": "^1.1.0", "postcss": "^8.5.10", "validator": "^13.15.20", "@opentelemetry/core": "^2.7.0", "@rushstack/node-core-library/ajv": "^8.18.0", "@changesets/assemble-release-plan@^6.0.9": "patch:@changesets/assemble-release-plan@npm:^6.0.9#.yarn/patches/@changesets-assemble-release-plan-npm-6.0.9-e01af97ef4.patch" }, "packageManager": "yarn@3.2.1" }Node.js version
v22.23.1Database and its version
PostgreSQL 15.4
Operating system name and version
Windows 10.0.19045
Browser name
Not applicable.
What happened?
A product variant update can only resolve option values already linked to the
product. Adding a new option value and replacing a variant with one that uses
that value therefore requires two Product Module calls.
When those calls run without a shared outer transaction, the option-value
update commits before the variant update begins. If the variant update fails,
the new value link remains. Another writer can also observe or change the
partial state between calls.
Expected behavior
One product update should be able to add or remove product option values and
replace variants in the same transaction. A failure should roll back both the
value-link changes and variant changes.
Actual behavior
The supported product update contract has no atomic option-value delta. A
variant cannot reference a newly added value until a separate value-link
operation commits.
Reproduction
Source: https://github.com/medusajs/medusa/tree/e037c71ff11add91583124a600840ce793421fe7
Inside the existing
updateProductsintegration block inpackages/modules/product/integration-tests/__tests__/product-module-service/products.spec.ts,add:
Run:
On the linked
developcommit, the update rejects withOption value val-3 does not exist for option opt-title; the value cannot beadded in the same call that replaces the variant.
Proposed contract
Accept an ID-scoped
option_value_updatesdelta alongsidevariants, applyadditions before variant resolution and removals afterward, and execute all
changes in one Product Module transaction with guarded workflow compensation.