Merge branch 'develop' into docs/quote-management-guide

This commit is contained in:
Shahed Nasser committed 2025-03-05 17:15:13 +02:00
commit 5bda9f6037
877 files changed
+491160 -480034

No files matched your search

-6
View File
@@ -1,6 +0,0 @@
---
"@medusajs/types": patch
"@medusajs/medusa": patch
---
fix(types, medusa): remove fulfillment and payment status filters from validator + http types
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/dashboard": patch
---
fix(dashboard): Use derrived state in DataTable
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/types": patch
---
chore(types): change payment provider types to interfaces
-6
View File
@@ -1,6 +0,0 @@
---
"@medusajs/types": patch
"@medusajs/medusa": patch
---
fix(types,medusa): calculate taxes for original price
-6
View File
@@ -1,6 +0,0 @@
---
"@medusajs/product": patch
"@medusajs/utils": patch
---
chore(product): Remove upsertWithReplace where needed
-7
View File
@@ -1,7 +0,0 @@
---
"@medusajs/medusa": patch
"@medusajs/core-flows": patch
"@medusajs/types": patch
---
fix: add additionl data to product categories hook
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/core-flows": patch
---
chore(core-flows): pass cart as reference to subflows
-7
View File
@@ -1,7 +0,0 @@
---
"@medusajs/cart": patch
"@medusajs/core-flows": patch
"@medusajs/types": patch
---
chore(): Improve cart update line items
-6
View File
@@ -1,6 +0,0 @@
---
"@medusajs/core-flows": patch
"@medusajs/cart": patch
---
chore(): Prevent workflow steps to even call modules when not necessary
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/framework": patch
---
feat: add middleware-file-loader
-6
View File
@@ -1,6 +0,0 @@
---
"@medusajs/framework": patch
"@medusajs/utils": patch
---
chore(): Add support for extra pool configuration
+7
View File
@@ -0,0 +1,7 @@
---
"@medusajs/product": patch
"@medusajs/framework": patch
"@medusajs/medusa": patch
---
chore(product): Improve product normalization
-9
View File
@@ -1,9 +0,0 @@
---
"@medusajs/cache-redis": patch
"@medusajs/event-bus-redis": patch
"@medusajs/workflow-engine-redis": patch
"@medusajs/locking-redis": patch
"@medusajs/workflows-sdk": patch
---
chore(): Prevent sub workflow events release early + redis unlink
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/types": patch
---
fix(types): Allow providing either vite@5 or vite@6 for the peer dependency
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/utils": patch
---
chore(): Improve cascade soft deletetion and update
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/link-modules": patch
---
Chore/link module serialization
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/core-flows": patch
---
fix(core-flows): support 0 as a valid unit price for custom line items
-9
View File
@@ -1,9 +0,0 @@
---
"@medusajs/inventory": patch
"@medusajs/link-modules": patch
"@medusajs/product": patch
"@medusajs/types": patch
"@medusajs/utils": patch
---
chore(): Improve internal repository delete algo
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/dashboard": patch
---
fix(dashboard): bust variant inventory cache on inventory update
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/core-flows": patch
---
chore(core-flows): reserve inventory from locations with availability
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/utils": patch
---
feat(utils): add error message when manager is not found
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/framework": patch
---
feat: add routes loader
-5
View File
@@ -1,5 +0,0 @@
---
"@medusajs/core-flows": patch
---
chore(core-flows): avoid overfetching to refresh cart
-7
View File
@@ -1,7 +0,0 @@
---
"@medusajs/dashboard": patch
"@medusajs/core-flows": patch
"@medusajs/medusa": patch
---
fix(core-flows, dashboard, medusa): prevent creatiion of a fulfilment without items
+28
View File
@@ -1,5 +1,33 @@
# integration-tests-http # integration-tests-http
## 1.0.9
### Patch Changes
- Updated dependencies [[`8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125`](https://github.com/medusajs/medusa/commit/8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125), [`51b0af193c7dde4899a696a515b59373b465d907`](https://github.com/medusajs/medusa/commit/51b0af193c7dde4899a696a515b59373b465d907), [`eeebb35758ea443468dd2355a7ea761dfe24babc`](https://github.com/medusajs/medusa/commit/eeebb35758ea443468dd2355a7ea761dfe24babc), [`d172ad8ebc4677bba73c36465c973f4784dc50ae`](https://github.com/medusajs/medusa/commit/d172ad8ebc4677bba73c36465c973f4784dc50ae), [`93cbc6b6695f236fa39b66169de971228888f1b9`](https://github.com/medusajs/medusa/commit/93cbc6b6695f236fa39b66169de971228888f1b9), [`322d108c0395757b4655a1e0055d722acf127b36`](https://github.com/medusajs/medusa/commit/322d108c0395757b4655a1e0055d722acf127b36), [`d1efad9bf05ca80959e8b50d74b74167fc1b0064`](https://github.com/medusajs/medusa/commit/d1efad9bf05ca80959e8b50d74b74167fc1b0064), [`caf83cf78cb6d2dbd1837f6814062dafecbd04fa`](https://github.com/medusajs/medusa/commit/caf83cf78cb6d2dbd1837f6814062dafecbd04fa), [`ca6a15717d05de112ca00ca56d65beb2ab0f2598`](https://github.com/medusajs/medusa/commit/ca6a15717d05de112ca00ca56d65beb2ab0f2598), [`d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30`](https://github.com/medusajs/medusa/commit/d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30), [`38beeb157eadcd7dabe814119c48b5ddbc17fe20`](https://github.com/medusajs/medusa/commit/38beeb157eadcd7dabe814119c48b5ddbc17fe20), [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76), [`03731c7660fe5dca3c6d3c38a2a71eb2ea89e192`](https://github.com/medusajs/medusa/commit/03731c7660fe5dca3c6d3c38a2a71eb2ea89e192), [`ab96ad3b8213b117b067ae0ab66b94f74b8bd031`](https://github.com/medusajs/medusa/commit/ab96ad3b8213b117b067ae0ab66b94f74b8bd031), [`cad8b40c130e371d615d3bd953bb466fb4ac54a8`](https://github.com/medusajs/medusa/commit/cad8b40c130e371d615d3bd953bb466fb4ac54a8), [`7dbec10b3bdde8a9f869080d5ef2c3c97fca1077`](https://github.com/medusajs/medusa/commit/7dbec10b3bdde8a9f869080d5ef2c3c97fca1077), [`fa1793e8e92164251c776859dea7a5e312ef9432`](https://github.com/medusajs/medusa/commit/fa1793e8e92164251c776859dea7a5e312ef9432), [`e23f204b7ca0f195e36fef2ba0bae7a686b8da4f`](https://github.com/medusajs/medusa/commit/e23f204b7ca0f195e36fef2ba0bae7a686b8da4f), [`aabbbb7292a59ec029a6165451aa6d949844b2ea`](https://github.com/medusajs/medusa/commit/aabbbb7292a59ec029a6165451aa6d949844b2ea)]:
- @medusajs/medusa@2.6.0
- @medusajs/product@2.6.0
- @medusajs/utils@2.6.0
- @medusajs/core-flows@2.6.0
- @medusajs/inventory@2.6.0
- @medusajs/modules-sdk@2.6.0
- @medusajs/test-utils@2.6.0
- @medusajs/api-key@2.6.0
- @medusajs/auth@2.6.0
- @medusajs/cache-inmemory@2.6.0
- @medusajs/customer@2.6.0
- @medusajs/event-bus-local@2.6.0
- @medusajs/fulfillment@2.6.0
- @medusajs/pricing@2.6.0
- @medusajs/promotion@2.6.0
- @medusajs/fulfillment-manual@2.6.0
- @medusajs/region@2.6.0
- @medusajs/stock-location@2.6.0
- @medusajs/store@2.6.0
- @medusajs/tax@2.6.0
- @medusajs/user@2.6.0
- @medusajs/workflow-engine-inmemory@2.6.0
## 1.0.8 ## 1.0.8
### Patch Changes ### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "integration-tests-http", "name": "integration-tests-http",
"version": "1.0.8", "version": "1.0.9",
"main": "index.js", "main": "index.js",
"license": "MIT", "license": "MIT",
"private": true, "private": true,
@@ -1,5 +1,14 @@
# @medusajs/admin-bundler # @medusajs/admin-bundler
## 2.6.0
### Patch Changes
- Updated dependencies [[`c28ae573e50b51bd3ef18de7c0e37b37963c423e`](https://github.com/medusajs/medusa/commit/c28ae573e50b51bd3ef18de7c0e37b37963c423e), [`954136f13a4ff00c0fa66d8159f43b2bce90355a`](https://github.com/medusajs/medusa/commit/954136f13a4ff00c0fa66d8159f43b2bce90355a), [`e23f204b7ca0f195e36fef2ba0bae7a686b8da4f`](https://github.com/medusajs/medusa/commit/e23f204b7ca0f195e36fef2ba0bae7a686b8da4f)]:
- @medusajs/dashboard@2.6.0
- @medusajs/admin-shared@2.6.0
- @medusajs/admin-vite-plugin@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/admin-bundler", "name": "@medusajs/admin-bundler",
"version": "2.5.1", "version": "2.6.0",
"description": "Bundler for the Medusa admin dashboard.", "description": "Bundler for the Medusa admin dashboard.",
"author": "Kasper Kristensen <kasper@medusajs.com>", "author": "Kasper Kristensen <kasper@medusajs.com>",
"scripts": { "scripts": {
@@ -18,7 +18,7 @@
"package.json" "package.json"
], ],
"devDependencies": { "devDependencies": {
"@medusajs/types": "^2.5.1", "@medusajs/types": "^2.6.0",
"@types/compression": "^1.7.5", "@types/compression": "^1.7.5",
"copyfiles": "^2.4.1", "copyfiles": "^2.4.1",
"express": "^4.21.0", "express": "^4.21.0",
@@ -26,9 +26,9 @@
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"dependencies": { "dependencies": {
"@medusajs/admin-shared": "2.5.1", "@medusajs/admin-shared": "2.6.0",
"@medusajs/admin-vite-plugin": "2.5.1", "@medusajs/admin-vite-plugin": "2.6.0",
"@medusajs/dashboard": "2.5.1", "@medusajs/dashboard": "2.6.0",
"@rollup/plugin-node-resolve": "^16.0.0", "@rollup/plugin-node-resolve": "^16.0.0",
"@vitejs/plugin-react": "^4.2.1", "@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.16", "autoprefixer": "^10.4.16",
+7
View File
@@ -1,5 +1,12 @@
# @medusajs/admin-sdk # @medusajs/admin-sdk
## 2.6.0
### Patch Changes
- Updated dependencies []:
- @medusajs/admin-shared@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "@medusajs/admin-sdk", "name": "@medusajs/admin-sdk",
"description": "SDK for building extension for the Medusa admin dashboard.", "description": "SDK for building extension for the Medusa admin dashboard.",
"version": "2.5.1", "version": "2.6.0",
"author": "Kasper Kristensen <kasper@medusajs.com>", "author": "Kasper Kristensen <kasper@medusajs.com>",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"main": "dist/index.js", "main": "dist/index.js",
@@ -24,7 +24,7 @@
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"dependencies": { "dependencies": {
"@medusajs/admin-shared": "^2.5.1", "@medusajs/admin-shared": "^2.6.0",
"zod": "3.22.4" "zod": "3.22.4"
}, },
"packageManager": "yarn@3.2.1" "packageManager": "yarn@3.2.1"
+2
View File
@@ -1,5 +1,7 @@
# @medusajs/admin-shared # @medusajs/admin-shared
## 2.6.0
## 2.5.1 ## 2.5.1
## 2.5.0 ## 2.5.0
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@medusajs/admin-shared", "name": "@medusajs/admin-shared",
"description": "Shared code for Medusa admin packages.", "description": "Shared code for Medusa admin packages.",
"version": "2.5.1", "version": "2.6.0",
"author": "Kasper Kristensen <kasper@medusajs.com>", "author": "Kasper Kristensen <kasper@medusajs.com>",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"main": "dist/index.js", "main": "dist/index.js",
@@ -1,5 +1,12 @@
# @medusajs/admin-vite-plugin # @medusajs/admin-vite-plugin
## 2.6.0
### Patch Changes
- Updated dependencies []:
- @medusajs/admin-shared@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/admin-vite-plugin", "name": "@medusajs/admin-vite-plugin",
"version": "2.5.1", "version": "2.6.0",
"main": "dist/index.js", "main": "dist/index.js",
"module": "dist/index.mjs", "module": "dist/index.mjs",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
@@ -40,7 +40,7 @@
"@babel/parser": "7.25.6", "@babel/parser": "7.25.6",
"@babel/traverse": "7.25.6", "@babel/traverse": "7.25.6",
"@babel/types": "7.25.6", "@babel/types": "7.25.6",
"@medusajs/admin-shared": "2.5.1", "@medusajs/admin-shared": "2.6.0",
"chokidar": "3.5.3", "chokidar": "3.5.3",
"fdir": "6.1.1", "fdir": "6.1.1",
"magic-string": "0.30.5", "magic-string": "0.30.5",
+15
View File
@@ -1,5 +1,20 @@
# @medusajs/dashboard # @medusajs/dashboard
## 2.6.0
### Patch Changes
- [#11487](https://github.com/medusajs/medusa/pull/11487) [`c28ae573e50b51bd3ef18de7c0e37b37963c423e`](https://github.com/medusajs/medusa/commit/c28ae573e50b51bd3ef18de7c0e37b37963c423e) Thanks [@kasperkristensen](https://github.com/kasperkristensen)! - fix(dashboard): Use derrived state in DataTable
- [#11690](https://github.com/medusajs/medusa/pull/11690) [`954136f13a4ff00c0fa66d8159f43b2bce90355a`](https://github.com/medusajs/medusa/commit/954136f13a4ff00c0fa66d8159f43b2bce90355a) Thanks [@riqwan](https://github.com/riqwan)! - fix(dashboard): bust variant inventory cache on inventory update
- [#11664](https://github.com/medusajs/medusa/pull/11664) [`e23f204b7ca0f195e36fef2ba0bae7a686b8da4f`](https://github.com/medusajs/medusa/commit/e23f204b7ca0f195e36fef2ba0bae7a686b8da4f) Thanks [@fPolic](https://github.com/fPolic)! - fix(core-flows, dashboard, medusa): prevent creatiion of a fulfilment without items
- Updated dependencies []:
- @medusajs/admin-shared@2.6.0
- @medusajs/js-sdk@2.6.0
- @medusajs/icons@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+8 -8
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/dashboard", "name": "@medusajs/dashboard",
"version": "2.5.1", "version": "2.6.0",
"scripts": { "scripts": {
"generate:static": "node ./scripts/generate-currencies.js && prettier --write ./src/lib/currencies.ts", "generate:static": "node ./scripts/generate-currencies.js && prettier --write ./src/lib/currencies.ts",
"dev": "vite", "dev": "vite",
@@ -45,9 +45,9 @@
"@dnd-kit/sortable": "^8.0.0", "@dnd-kit/sortable": "^8.0.0",
"@hookform/error-message": "^2.0.1", "@hookform/error-message": "^2.0.1",
"@hookform/resolvers": "3.4.2", "@hookform/resolvers": "3.4.2",
"@medusajs/admin-shared": "^2.5.1", "@medusajs/admin-shared": "^2.6.0",
"@medusajs/icons": "^2.5.1", "@medusajs/icons": "^2.6.0",
"@medusajs/js-sdk": "^2.5.1", "@medusajs/js-sdk": "^2.6.0",
"@medusajs/ui": "~4.0.6", "@medusajs/ui": "~4.0.6",
"@tanstack/react-query": "5.64.2", "@tanstack/react-query": "5.64.2",
"@tanstack/react-table": "8.20.5", "@tanstack/react-table": "8.20.5",
@@ -75,10 +75,10 @@
"zod": "3.22.4" "zod": "3.22.4"
}, },
"devDependencies": { "devDependencies": {
"@medusajs/admin-shared": "^2.5.1", "@medusajs/admin-shared": "^2.6.0",
"@medusajs/admin-vite-plugin": "^2.5.1", "@medusajs/admin-vite-plugin": "^2.6.0",
"@medusajs/types": "^2.5.1", "@medusajs/types": "^2.6.0",
"@medusajs/ui-preset": "^2.5.1", "@medusajs/ui-preset": "^2.6.0",
"@types/node": "^20.11.15", "@types/node": "^20.11.15",
"@types/react": "^18.2.79", "@types/react": "^18.2.79",
"@types/react-dom": "^18.2.25", "@types/react-dom": "^18.2.25",
@@ -1,5 +1,12 @@
# Change Log # Change Log
## 2.6.0
### Patch Changes
- Updated dependencies []:
- @medusajs/telemetry@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "create-medusa-app", "name": "create-medusa-app",
"version": "2.5.1", "version": "2.6.0",
"description": "Create a Medusa project using a single command.", "description": "Create a Medusa project using a single command.",
"type": "module", "type": "module",
"exports": "./dist/index.js", "exports": "./dist/index.js",
@@ -13,7 +13,7 @@
"watch": "tsc --watch" "watch": "tsc --watch"
}, },
"dependencies": { "dependencies": {
"@medusajs/telemetry": "^2.5.1", "@medusajs/telemetry": "^2.6.0",
"boxen": "^5", "boxen": "^5",
"chalk": "^5.2.0", "chalk": "^5.2.0",
"commander": "^10.0.1", "commander": "^10.0.1",
+8
View File
@@ -1,5 +1,13 @@
# Change Log # Change Log
## 2.6.0
### Patch Changes
- Updated dependencies [[`eeebb35758ea443468dd2355a7ea761dfe24babc`](https://github.com/medusajs/medusa/commit/eeebb35758ea443468dd2355a7ea761dfe24babc), [`ca6a15717d05de112ca00ca56d65beb2ab0f2598`](https://github.com/medusajs/medusa/commit/ca6a15717d05de112ca00ca56d65beb2ab0f2598), [`d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30`](https://github.com/medusajs/medusa/commit/d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30), [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76), [`ab96ad3b8213b117b067ae0ab66b94f74b8bd031`](https://github.com/medusajs/medusa/commit/ab96ad3b8213b117b067ae0ab66b94f74b8bd031)]:
- @medusajs/utils@2.6.0
- @medusajs/telemetry@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/cli", "name": "@medusajs/cli",
"version": "2.5.1", "version": "2.6.0",
"description": "Command Line interface for Medusa Commerce", "description": "Command Line interface for Medusa Commerce",
"main": "dist/index.js", "main": "dist/index.js",
"bin": { "bin": {
@@ -46,8 +46,8 @@
"typescript": "^5.6.2" "typescript": "^5.6.2"
}, },
"dependencies": { "dependencies": {
"@medusajs/telemetry": "^2.5.1", "@medusajs/telemetry": "^2.6.0",
"@medusajs/utils": "2.5.1", "@medusajs/utils": "2.6.0",
"@types/express": "^4.17.17", "@types/express": "^4.17.17",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"configstore": "5.0.1", "configstore": "5.0.1",
+2
View File
@@ -1,5 +1,7 @@
# Change Log # Change Log
## 2.6.0
## 2.5.1 ## 2.5.1
## 2.5.0 ## 2.5.0
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "medusa-dev-cli", "name": "medusa-dev-cli",
"description": "CLI helpers for contributors working on Medusa", "description": "CLI helpers for contributors working on Medusa",
"version": "2.5.1", "version": "2.6.0",
"author": "Sebastian Rindom <skrindom@gmail.com>", "author": "Sebastian Rindom <skrindom@gmail.com>",
"bin": { "bin": {
"medusa-dev": "./dist/index.js" "medusa-dev": "./dist/index.js"
@@ -1,5 +1,13 @@
# @medusajs/oas-cli # @medusajs/oas-cli
## 2.6.0
### Patch Changes
- Updated dependencies [[`8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125`](https://github.com/medusajs/medusa/commit/8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125), [`51b0af193c7dde4899a696a515b59373b465d907`](https://github.com/medusajs/medusa/commit/51b0af193c7dde4899a696a515b59373b465d907), [`eeebb35758ea443468dd2355a7ea761dfe24babc`](https://github.com/medusajs/medusa/commit/eeebb35758ea443468dd2355a7ea761dfe24babc), [`d172ad8ebc4677bba73c36465c973f4784dc50ae`](https://github.com/medusajs/medusa/commit/d172ad8ebc4677bba73c36465c973f4784dc50ae), [`93cbc6b6695f236fa39b66169de971228888f1b9`](https://github.com/medusajs/medusa/commit/93cbc6b6695f236fa39b66169de971228888f1b9), [`ca6a15717d05de112ca00ca56d65beb2ab0f2598`](https://github.com/medusajs/medusa/commit/ca6a15717d05de112ca00ca56d65beb2ab0f2598), [`d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30`](https://github.com/medusajs/medusa/commit/d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30), [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76), [`ab96ad3b8213b117b067ae0ab66b94f74b8bd031`](https://github.com/medusajs/medusa/commit/ab96ad3b8213b117b067ae0ab66b94f74b8bd031), [`e23f204b7ca0f195e36fef2ba0bae7a686b8da4f`](https://github.com/medusajs/medusa/commit/e23f204b7ca0f195e36fef2ba0bae7a686b8da4f), [`aabbbb7292a59ec029a6165451aa6d949844b2ea`](https://github.com/medusajs/medusa/commit/aabbbb7292a59ec029a6165451aa6d949844b2ea)]:
- @medusajs/medusa@2.6.0
- @medusajs/utils@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/medusa-oas-cli", "name": "@medusajs/medusa-oas-cli",
"version": "2.5.1", "version": "2.6.0",
"description": "OAS CLI", "description": "OAS CLI",
"main": "dist/index.js", "main": "dist/index.js",
"bin": { "bin": {
@@ -21,7 +21,7 @@
"author": "Medusa", "author": "Medusa",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@medusajs/types": "^2.5.1", "@medusajs/types": "^2.6.0",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"jest": "^29.1.0", "jest": "^29.1.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
@@ -35,8 +35,8 @@
"medusa-oas": "ts-node src/index.ts" "medusa-oas": "ts-node src/index.ts"
}, },
"dependencies": { "dependencies": {
"@medusajs/medusa": "^2.5.1", "@medusajs/medusa": "^2.6.0",
"@medusajs/utils": "^2.5.1", "@medusajs/utils": "^2.6.0",
"@readme/json-schema-ref-parser": "^1.2.0", "@readme/json-schema-ref-parser": "^1.2.0",
"@readme/openapi-parser": "^2.4.0", "@readme/openapi-parser": "^2.4.0",
"@redocly/cli": "^1.7.0", "@redocly/cli": "^1.7.0",
@@ -1,5 +1,12 @@
# @medusajs/oas-github-ci # @medusajs/oas-github-ci
## 2.6.0
### Patch Changes
- Updated dependencies []:
- @medusajs/medusa-oas-cli@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/oas-github-ci", "name": "@medusajs/oas-github-ci",
"version": "2.5.1", "version": "2.6.0",
"description": "OAS Github CI", "description": "OAS Github CI",
"main": "scripts/build-openapi.js", "main": "scripts/build-openapi.js",
"files": [ "files": [
@@ -21,7 +21,7 @@
"test": "jest --passWithNoTests" "test": "jest --passWithNoTests"
}, },
"dependencies": { "dependencies": {
"@medusajs/medusa-oas-cli": "2.5.1", "@medusajs/medusa-oas-cli": "2.6.0",
"execa": "^5.1.1" "execa": "^5.1.1"
} }
} }
+22
View File
@@ -1,5 +1,27 @@
# @medusajs/core-flows # @medusajs/core-flows
## 2.6.0
### Patch Changes
- [#11226](https://github.com/medusajs/medusa/pull/11226) [`93cbc6b6695f236fa39b66169de971228888f1b9`](https://github.com/medusajs/medusa/commit/93cbc6b6695f236fa39b66169de971228888f1b9) Thanks [@bouazzaayyoub](https://github.com/bouazzaayyoub)! - fix: add additionl data to product categories hook
- [#11617](https://github.com/medusajs/medusa/pull/11617) [`322d108c0395757b4655a1e0055d722acf127b36`](https://github.com/medusajs/medusa/commit/322d108c0395757b4655a1e0055d722acf127b36) Thanks [@carlos-r-l-rodrigues](https://github.com/carlos-r-l-rodrigues)! - chore(core-flows): pass cart as reference to subflows
- [#11666](https://github.com/medusajs/medusa/pull/11666) [`d1efad9bf05ca80959e8b50d74b74167fc1b0064`](https://github.com/medusajs/medusa/commit/d1efad9bf05ca80959e8b50d74b74167fc1b0064) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(): Improve cart update line items
- [#11632](https://github.com/medusajs/medusa/pull/11632) [`caf83cf78cb6d2dbd1837f6814062dafecbd04fa`](https://github.com/medusajs/medusa/commit/caf83cf78cb6d2dbd1837f6814062dafecbd04fa) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(): Prevent workflow steps to even call modules when not necessary
- [#11631](https://github.com/medusajs/medusa/pull/11631) [`38beeb157eadcd7dabe814119c48b5ddbc17fe20`](https://github.com/medusajs/medusa/commit/38beeb157eadcd7dabe814119c48b5ddbc17fe20) Thanks [@riqwan](https://github.com/riqwan)! - fix(core-flows): support 0 as a valid unit price for custom line items
- [#11538](https://github.com/medusajs/medusa/pull/11538) [`03731c7660fe5dca3c6d3c38a2a71eb2ea89e192`](https://github.com/medusajs/medusa/commit/03731c7660fe5dca3c6d3c38a2a71eb2ea89e192) Thanks [@carlos-r-l-rodrigues](https://github.com/carlos-r-l-rodrigues)! - chore(core-flows): reserve inventory from locations with availability
- [#11712](https://github.com/medusajs/medusa/pull/11712) [`7dbec10b3bdde8a9f869080d5ef2c3c97fca1077`](https://github.com/medusajs/medusa/commit/7dbec10b3bdde8a9f869080d5ef2c3c97fca1077) Thanks [@carlos-r-l-rodrigues](https://github.com/carlos-r-l-rodrigues)! - fix(order): summary raw totals
- [#11602](https://github.com/medusajs/medusa/pull/11602) [`fa1793e8e92164251c776859dea7a5e312ef9432`](https://github.com/medusajs/medusa/commit/fa1793e8e92164251c776859dea7a5e312ef9432) Thanks [@carlos-r-l-rodrigues](https://github.com/carlos-r-l-rodrigues)! - chore(core-flows): avoid overfetching to refresh cart
- [#11664](https://github.com/medusajs/medusa/pull/11664) [`e23f204b7ca0f195e36fef2ba0bae7a686b8da4f`](https://github.com/medusajs/medusa/commit/e23f204b7ca0f195e36fef2ba0bae7a686b8da4f) Thanks [@fPolic](https://github.com/fPolic)! - fix(core-flows, dashboard, medusa): prevent creatiion of a fulfilment without items
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/core-flows", "name": "@medusajs/core-flows",
"version": "2.5.1", "version": "2.6.0",
"description": "Set of workflow definitions for Medusa", "description": "Set of workflow definitions for Medusa",
"main": "dist/index.js", "main": "dist/index.js",
"exports": { "exports": {
@@ -26,7 +26,7 @@
"author": "Medusa", "author": "Medusa",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@medusajs/framework": "^2.5.1", "@medusajs/framework": "^2.6.0",
"@mikro-orm/core": "6.4.3", "@mikro-orm/core": "6.4.3",
"@mikro-orm/knex": "6.4.3", "@mikro-orm/knex": "6.4.3",
"@mikro-orm/migrations": "6.4.3", "@mikro-orm/migrations": "6.4.3",
@@ -56,12 +56,11 @@ export type ValidateRefundStepInput = {
*/ */
export const validateRefundStep = createStep( export const validateRefundStep = createStep(
"validate-refund-step", "validate-refund-step",
async function ({ async function ({ order, payment, amount }: ValidateRefundStepInput) {
order, const pendingDifference =
payment, order.summary?.raw_pending_difference! ??
amount, order.summary?.pending_difference! ??
}: ValidateRefundStepInput) { 0
const pendingDifference = order.summary?.raw_pending_difference!
if (MathBN.gte(pendingDifference, 0)) { if (MathBN.gte(pendingDifference, 0)) {
throw new MedusaError( throw new MedusaError(
@@ -122,9 +121,7 @@ export const refundPaymentWorkflowId = "refund-payment-workflow"
*/ */
export const refundPaymentWorkflow = createWorkflow( export const refundPaymentWorkflow = createWorkflow(
refundPaymentWorkflowId, refundPaymentWorkflowId,
( (input: WorkflowData<RefundPaymentWorkflowInput>) => {
input: WorkflowData<RefundPaymentWorkflowInput>
) => {
const payment = useRemoteQueryStep({ const payment = useRemoteQueryStep({
entry_point: "payment", entry_point: "payment",
fields: [ fields: [
@@ -1,6 +1,7 @@
import { import {
WorkflowData, WorkflowData,
WorkflowResponse, WorkflowResponse,
createHook,
createWorkflow, createWorkflow,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
@@ -44,6 +45,14 @@ export const createStockLocationsWorkflowId = "create-stock-locations-workflow"
export const createStockLocationsWorkflow = createWorkflow( export const createStockLocationsWorkflow = createWorkflow(
createStockLocationsWorkflowId, createStockLocationsWorkflowId,
(input: WorkflowData<CreateStockLocationsWorkflowInput>) => { (input: WorkflowData<CreateStockLocationsWorkflowInput>) => {
return new WorkflowResponse(createStockLocations(input.locations)) const stockLocations = createStockLocations(input.locations)
const stockLocationsCreated = createHook("stockLocationsCreated", {
stockLocations,
})
return new WorkflowResponse(stockLocations, {
hooks: [stockLocationsCreated],
})
} }
) )
+22
View File
@@ -1,5 +1,27 @@
# @medusajs/framework # @medusajs/framework
## 2.6.0
### Patch Changes
- [#11638](https://github.com/medusajs/medusa/pull/11638) [`b0a16488e01632bc2bfee4d4bf2a3e1d3e11b104`](https://github.com/medusajs/medusa/commit/b0a16488e01632bc2bfee4d4bf2a3e1d3e11b104) Thanks [@thetutlage](https://github.com/thetutlage)! - feat: add middleware-file-loader
- [#11636](https://github.com/medusajs/medusa/pull/11636) [`ca6a15717d05de112ca00ca56d65beb2ab0f2598`](https://github.com/medusajs/medusa/commit/ca6a15717d05de112ca00ca56d65beb2ab0f2598) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(): Add support for extra pool configuration
- [#11707](https://github.com/medusajs/medusa/pull/11707) [`5d184ba0c8ff0438b422af5602bf275333eb2019`](https://github.com/medusajs/medusa/commit/5d184ba0c8ff0438b422af5602bf275333eb2019) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(framework): Unified resource loading and exclude non js/ts files
- [#11592](https://github.com/medusajs/medusa/pull/11592) [`9e2af4801daeb72d0e5a4d5ae674bdf6d415cf58`](https://github.com/medusajs/medusa/commit/9e2af4801daeb72d0e5a4d5ae674bdf6d415cf58) Thanks [@thetutlage](https://github.com/thetutlage)! - feat: add routes loader
- [#11646](https://github.com/medusajs/medusa/pull/11646) [`aabbbb7292a59ec029a6165451aa6d949844b2ea`](https://github.com/medusajs/medusa/commit/aabbbb7292a59ec029a6165451aa6d949844b2ea) Thanks [@thetutlage](https://github.com/thetutlage)! - feat: Replace existing router with the new implementation
- Updated dependencies [[`8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125`](https://github.com/medusajs/medusa/commit/8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125), [`698a520729a3045cd13eed5ee0e5120a563e9261`](https://github.com/medusajs/medusa/commit/698a520729a3045cd13eed5ee0e5120a563e9261), [`51b0af193c7dde4899a696a515b59373b465d907`](https://github.com/medusajs/medusa/commit/51b0af193c7dde4899a696a515b59373b465d907), [`eeebb35758ea443468dd2355a7ea761dfe24babc`](https://github.com/medusajs/medusa/commit/eeebb35758ea443468dd2355a7ea761dfe24babc), [`93cbc6b6695f236fa39b66169de971228888f1b9`](https://github.com/medusajs/medusa/commit/93cbc6b6695f236fa39b66169de971228888f1b9), [`d1efad9bf05ca80959e8b50d74b74167fc1b0064`](https://github.com/medusajs/medusa/commit/d1efad9bf05ca80959e8b50d74b74167fc1b0064), [`ca6a15717d05de112ca00ca56d65beb2ab0f2598`](https://github.com/medusajs/medusa/commit/ca6a15717d05de112ca00ca56d65beb2ab0f2598), [`c250de79192bda1b1cd217bcca37f458c693de1d`](https://github.com/medusajs/medusa/commit/c250de79192bda1b1cd217bcca37f458c693de1d), [`d814d9540e76256be23d733b73cf5a63aa380c8b`](https://github.com/medusajs/medusa/commit/d814d9540e76256be23d733b73cf5a63aa380c8b), [`d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30`](https://github.com/medusajs/medusa/commit/d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30), [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76), [`ab96ad3b8213b117b067ae0ab66b94f74b8bd031`](https://github.com/medusajs/medusa/commit/ab96ad3b8213b117b067ae0ab66b94f74b8bd031)]:
- @medusajs/types@2.6.0
- @medusajs/utils@2.6.0
- @medusajs/workflows-sdk@2.6.0
- @medusajs/modules-sdk@2.6.0
- @medusajs/orchestration@2.6.0
- @medusajs/telemetry@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+9 -8
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/framework", "name": "@medusajs/framework",
"version": "2.5.1", "version": "2.6.0",
"description": "Framework", "description": "Framework",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
@@ -54,7 +54,7 @@
"test": "jest --runInBand --bail --forceExit -- src/**/__tests__/**/*.ts" "test": "jest --runInBand --bail --forceExit -- src/**/__tests__/**/*.ts"
}, },
"devDependencies": { "devDependencies": {
"@medusajs/cli": "^2.5.1", "@medusajs/cli": "^2.6.0",
"@mikro-orm/core": "6.4.3", "@mikro-orm/core": "6.4.3",
"@mikro-orm/knex": "6.4.3", "@mikro-orm/knex": "6.4.3",
"@mikro-orm/migrations": "6.4.3", "@mikro-orm/migrations": "6.4.3",
@@ -74,12 +74,12 @@
}, },
"dependencies": { "dependencies": {
"@jercle/yargonaut": "^1.1.5", "@jercle/yargonaut": "^1.1.5",
"@medusajs/modules-sdk": "^2.5.1", "@medusajs/modules-sdk": "^2.6.0",
"@medusajs/orchestration": "^2.5.1", "@medusajs/orchestration": "^2.6.0",
"@medusajs/telemetry": "^2.5.1", "@medusajs/telemetry": "^2.6.0",
"@medusajs/types": "^2.5.1", "@medusajs/types": "^2.6.0",
"@medusajs/utils": "^2.5.1", "@medusajs/utils": "^2.6.0",
"@medusajs/workflows-sdk": "^2.5.1", "@medusajs/workflows-sdk": "^2.6.0",
"@opentelemetry/api": "^1.9.0", "@opentelemetry/api": "^1.9.0",
"@types/express": "^4.17.17", "@types/express": "^4.17.17",
"chokidar": "^3.4.2", "chokidar": "^3.4.2",
@@ -93,6 +93,7 @@
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"lodash": "4.17.21", "lodash": "4.17.21",
"morgan": "^1.9.1", "morgan": "^1.9.1",
"path-to-regexp": "^0.1.10",
"tsconfig-paths": "^4.2.0", "tsconfig-paths": "^4.2.0",
"zod": "3.22.4" "zod": "3.22.4"
}, },
@@ -0,0 +1,5 @@
import { Request, Response } from "express"
export function GET(req: Request, res: Response) {
throw new Error("Failed")
}
@@ -16,7 +16,7 @@ import { container } from "../../../container"
import { featureFlagsLoader } from "../../../feature-flags" import { featureFlagsLoader } from "../../../feature-flags"
import { logger } from "../../../logger" import { logger } from "../../../logger"
import { MedusaRequest } from "../../types" import { MedusaRequest } from "../../types"
import { RoutesLoader } from "../../router" import { ApiLoader } from "../../router"
function asArray(resolvers) { function asArray(resolvers) {
return { return {
@@ -94,7 +94,7 @@ export const createServer = async (rootDir) => {
next() next()
}) })
await new RoutesLoader({ await new ApiLoader({
app, app,
sourceDir: rootDir, sourceDir: rootDir,
}).load() }).load()
@@ -6,7 +6,7 @@ import {
storeGlobalMiddlewareMock, storeGlobalMiddlewareMock,
} from "../__fixtures__/mocks" } from "../__fixtures__/mocks"
import { createServer } from "../__fixtures__/server" import { createServer } from "../__fixtures__/server"
import { MedusaNextFunction, RoutesLoader } from "../index" import { MedusaNextFunction, ApiLoader } from "../index"
jest.setTimeout(30000) jest.setTimeout(30000)
@@ -36,6 +36,22 @@ describe("RoutesLoader", function () {
request = request_ request = request_
}) })
it("should be handled by the error handler when a route handler fails", async function () {
const res = await request("GET", "/admin/fail", {
adminSession: {
jwt: {
userId: "admin_user",
},
},
})
expect(res.status).toBe(500)
console.log(res)
expect(res.text).toBe(
'{"code":"unknown_error","type":"unknown_error","message":"An unknown error occurred."}'
)
})
it("should return a status 200 on GET admin/order/:id", async function () { it("should return a status 200 on GET admin/order/:id", async function () {
const res = await request("GET", "/admin/orders/1000", { const res = await request("GET", "/admin/orders/1000", {
adminSession: { adminSession: {
@@ -237,7 +253,7 @@ describe("RoutesLoader", function () {
__dirname, __dirname,
"../__fixtures__/routers-duplicate-parameter" "../__fixtures__/routers-duplicate-parameter"
) )
const err = await new RoutesLoader({ const err = await new ApiLoader({
app, app,
sourceDir: rootDir, sourceDir: rootDir,
}) })
@@ -246,7 +262,7 @@ describe("RoutesLoader", function () {
expect(err).toBeDefined() expect(err).toBeDefined()
expect(err.message).toBe( expect(err.message).toBe(
"Duplicate parameters found in route /admin/customers/[id]/orders/[id] (id). Make sure that all parameters are unique." "Duplicate parameters found in route /admin/customers/[id]/orders/[id]/route.ts (id). Make sure that all parameters are unique."
) )
}) })
}) })
@@ -4,7 +4,7 @@ import { MiddlewareFileLoader } from "../middleware-file-loader"
describe("Middleware file loader", () => { describe("Middleware file loader", () => {
it("should load routes from the filesystem", async () => { it("should load routes from the filesystem", async () => {
const BASE_DIR = resolve(__dirname, "../__fixtures__/routers-middleware") const BASE_DIR = resolve(__dirname, "../__fixtures__/routers-middleware")
const loader = new MiddlewareFileLoader({}) const loader = new MiddlewareFileLoader()
await loader.scanDir(BASE_DIR) await loader.scanDir(BASE_DIR)
expect(loader.getBodyParserConfigRoutes()).toMatchInlineSnapshot(` expect(loader.getBodyParserConfigRoutes()).toMatchInlineSnapshot(`
@@ -14,12 +14,22 @@ describe("Middleware file loader", () => {
"preserveRawBody": true, "preserveRawBody": true,
}, },
"matcher": "/webhooks", "matcher": "/webhooks",
"method": undefined, "methods": [
"GET",
"POST",
"PUT",
"PATCH",
"DELETE",
"OPTIONS",
"HEAD",
],
}, },
{ {
"config": false, "config": false,
"matcher": "/webhooks/*", "matcher": "/webhooks/*",
"method": "POST", "methods": [
"POST",
],
}, },
] ]
`) `)
@@ -28,22 +38,26 @@ describe("Middleware file loader", () => {
{ {
"handler": [Function], "handler": [Function],
"matcher": "/customers", "matcher": "/customers",
"method": undefined, "methods": undefined,
}, },
{ {
"handler": [Function], "handler": [Function],
"matcher": "/customers", "matcher": "/customers",
"method": "POST", "methods": [
"POST",
],
}, },
{ {
"handler": [Function], "handler": [Function],
"matcher": "/store/*", "matcher": "/store/*",
"method": undefined, "methods": undefined,
}, },
{ {
"handler": [Function], "handler": [Function],
"matcher": "/webhooks/*", "matcher": "/webhooks/*",
"method": "POST", "methods": [
"POST",
],
}, },
] ]
`) `)
@@ -4,18 +4,19 @@ import { RoutesLoader } from "../routes-loader"
describe("Routes loader", () => { describe("Routes loader", () => {
it("should load routes from the filesystem", async () => { it("should load routes from the filesystem", async () => {
const BASE_DIR = resolve(__dirname, "../__fixtures__/routers") const BASE_DIR = resolve(__dirname, "../__fixtures__/routers")
const loader = new RoutesLoader({}) const loader = new RoutesLoader()
await loader.scanDir(BASE_DIR) await loader.scanDir(BASE_DIR)
expect(loader.getRoutes()).toMatchInlineSnapshot(` expect(loader.getRoutes()).toMatchInlineSnapshot(`
[ [
{ {
"absolutePath": "${BASE_DIR}/admin/orders/[id]/route.ts", "absolutePath": "${BASE_DIR}/admin/fail/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/fail",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/orders/[id]/route.ts", "relativePath": "/admin/fail/route.ts",
"route": "/admin/orders/:id",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -23,10 +24,23 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/orders/[id]/route.ts", "absolutePath": "${BASE_DIR}/admin/orders/[id]/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/orders/:id",
"method": "GET",
"optedOutOfAuth": false,
"relativePath": "/admin/orders/[id]/route.ts",
"shouldAppendAdminCors": true,
"shouldAppendAuthCors": false,
"shouldAppendStoreCors": false,
},
{
"absolutePath": "${BASE_DIR}/admin/orders/[id]/route.ts",
"handler": [Function],
"isRoute": true,
"matcher": "/admin/orders/:id",
"method": "POST", "method": "POST",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/orders/[id]/route.ts", "relativePath": "/admin/orders/[id]/route.ts",
"route": "/admin/orders/:id",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -34,10 +48,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/orders/route.ts", "absolutePath": "${BASE_DIR}/admin/orders/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/orders",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/orders/route.ts", "relativePath": "/admin/orders/route.ts",
"route": "/admin/orders",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -45,10 +60,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/[id]/route.ts", "absolutePath": "${BASE_DIR}/admin/products/[id]/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products/:id",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/[id]/route.ts", "relativePath": "/admin/products/[id]/route.ts",
"route": "/admin/products/:id",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -56,10 +72,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "DELETE", "method": "DELETE",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -67,10 +84,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -78,10 +96,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "HEAD", "method": "HEAD",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -89,10 +108,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "OPTIONS", "method": "OPTIONS",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -100,10 +120,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "PATCH", "method": "PATCH",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -111,10 +132,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "POST", "method": "POST",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -122,10 +144,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "PUT", "method": "PUT",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -133,10 +156,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/route.ts", "absolutePath": "${BASE_DIR}/admin/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/route.ts", "relativePath": "/admin/route.ts",
"route": "/admin",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -144,10 +168,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/route.ts", "absolutePath": "${BASE_DIR}/admin/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin",
"method": "POST", "method": "POST",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/route.ts", "relativePath": "/admin/route.ts",
"route": "/admin",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -155,10 +180,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/customers/[customer_id]/orders/[order_id]/route.ts", "absolutePath": "${BASE_DIR}/customers/[customer_id]/orders/[order_id]/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/customers/:customer_id/orders/:order_id",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/customers/[customer_id]/orders/[order_id]/route.ts", "relativePath": "/customers/[customer_id]/orders/[order_id]/route.ts",
"route": "/customers/:customer_id/orders/:order_id",
"shouldAppendAdminCors": false, "shouldAppendAdminCors": false,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -166,10 +192,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/customers/route.ts", "absolutePath": "${BASE_DIR}/customers/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/customers",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/customers/route.ts", "relativePath": "/customers/route.ts",
"route": "/customers",
"shouldAppendAdminCors": false, "shouldAppendAdminCors": false,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -184,19 +211,20 @@ describe("Routes loader", () => {
__dirname, __dirname,
"../__fixtures__/routers-with-duplicates" "../__fixtures__/routers-with-duplicates"
) )
const loader = new RoutesLoader({}) const loader = new RoutesLoader()
await loader.scanDir(BASE_DIR) await loader.scanDir(BASE_DIR)
await loader.scanDir(BASE_DIR_2) await loader.scanDir(BASE_DIR_2)
expect(loader.getRoutes()).toMatchInlineSnapshot(` expect(loader.getRoutes()).toMatchInlineSnapshot(`
[ [
{ {
"absolutePath": "${BASE_DIR}/admin/orders/[id]/route.ts", "absolutePath": "${BASE_DIR}/admin/fail/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/fail",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/orders/[id]/route.ts", "relativePath": "/admin/fail/route.ts",
"route": "/admin/orders/:id",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -204,10 +232,23 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/orders/[id]/route.ts", "absolutePath": "${BASE_DIR}/admin/orders/[id]/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/orders/:id",
"method": "GET",
"optedOutOfAuth": false,
"relativePath": "/admin/orders/[id]/route.ts",
"shouldAppendAdminCors": true,
"shouldAppendAuthCors": false,
"shouldAppendStoreCors": false,
},
{
"absolutePath": "${BASE_DIR}/admin/orders/[id]/route.ts",
"handler": [Function],
"isRoute": true,
"matcher": "/admin/orders/:id",
"method": "POST", "method": "POST",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/orders/[id]/route.ts", "relativePath": "/admin/orders/[id]/route.ts",
"route": "/admin/orders/:id",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -215,10 +256,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/orders/route.ts", "absolutePath": "${BASE_DIR}/admin/orders/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/orders",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/orders/route.ts", "relativePath": "/admin/orders/route.ts",
"route": "/admin/orders",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -226,10 +268,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR_2}/admin/products/[id]/route.ts", "absolutePath": "${BASE_DIR_2}/admin/products/[id]/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products/:id",
"method": "GET", "method": "GET",
"optedOutOfAuth": true, "optedOutOfAuth": true,
"relativePath": "/admin/products/[id]/route.ts", "relativePath": "/admin/products/[id]/route.ts",
"route": "/admin/products/:id",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -237,10 +280,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "DELETE", "method": "DELETE",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -248,10 +292,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR_2}/admin/products/route.ts", "absolutePath": "${BASE_DIR_2}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "GET", "method": "GET",
"optedOutOfAuth": true, "optedOutOfAuth": true,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -259,10 +304,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "HEAD", "method": "HEAD",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -270,10 +316,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "OPTIONS", "method": "OPTIONS",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -281,10 +328,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "PATCH", "method": "PATCH",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -292,10 +340,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR_2}/admin/products/route.ts", "absolutePath": "${BASE_DIR_2}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "POST", "method": "POST",
"optedOutOfAuth": true, "optedOutOfAuth": true,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -303,10 +352,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/products/route.ts", "absolutePath": "${BASE_DIR}/admin/products/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin/products",
"method": "PUT", "method": "PUT",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/products/route.ts", "relativePath": "/admin/products/route.ts",
"route": "/admin/products",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -314,10 +364,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/route.ts", "absolutePath": "${BASE_DIR}/admin/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/route.ts", "relativePath": "/admin/route.ts",
"route": "/admin",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -325,10 +376,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/admin/route.ts", "absolutePath": "${BASE_DIR}/admin/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/admin",
"method": "POST", "method": "POST",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/admin/route.ts", "relativePath": "/admin/route.ts",
"route": "/admin",
"shouldAppendAdminCors": true, "shouldAppendAdminCors": true,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -336,10 +388,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/customers/[customer_id]/orders/[order_id]/route.ts", "absolutePath": "${BASE_DIR}/customers/[customer_id]/orders/[order_id]/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/customers/:customer_id/orders/:order_id",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/customers/[customer_id]/orders/[order_id]/route.ts", "relativePath": "/customers/[customer_id]/orders/[order_id]/route.ts",
"route": "/customers/:customer_id/orders/:order_id",
"shouldAppendAdminCors": false, "shouldAppendAdminCors": false,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -347,10 +400,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR}/customers/route.ts", "absolutePath": "${BASE_DIR}/customers/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/customers",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/customers/route.ts", "relativePath": "/customers/route.ts",
"route": "/customers",
"shouldAppendAdminCors": false, "shouldAppendAdminCors": false,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": false, "shouldAppendStoreCors": false,
@@ -358,10 +412,11 @@ describe("Routes loader", () => {
{ {
"absolutePath": "${BASE_DIR_2}/store/[customer_id]/orders/[order_id]/route.ts", "absolutePath": "${BASE_DIR_2}/store/[customer_id]/orders/[order_id]/route.ts",
"handler": [Function], "handler": [Function],
"isRoute": true,
"matcher": "/store/:customer_id/orders/:order_id",
"method": "GET", "method": "GET",
"optedOutOfAuth": false, "optedOutOfAuth": false,
"relativePath": "/store/[customer_id]/orders/[order_id]/route.ts", "relativePath": "/store/[customer_id]/orders/[order_id]/route.ts",
"route": "/store/:customer_id/orders/:order_id",
"shouldAppendAdminCors": false, "shouldAppendAdminCors": false,
"shouldAppendAuthCors": false, "shouldAppendAuthCors": false,
"shouldAppendStoreCors": true, "shouldAppendStoreCors": true,
@@ -376,7 +431,7 @@ describe("Routes loader", () => {
"../__fixtures__/routers-duplicate-parameter" "../__fixtures__/routers-duplicate-parameter"
) )
const loader = new RoutesLoader({}) const loader = new RoutesLoader()
await expect(() => loader.scanDir(BASE_DIR)).rejects.toThrow( await expect(() => loader.scanDir(BASE_DIR)).rejects.toThrow(
"Duplicate parameters found in route /admin/customers/[id]/orders/[id]/route.ts (id). Make sure that all parameters are unique." "Duplicate parameters found in route /admin/customers/[id]/orders/[id]/route.ts (id). Make sure that all parameters are unique."
) )
@@ -19,6 +19,14 @@ describe("Routes sorter", () => {
isAppRoute: true, isAppRoute: true,
handler: () => {}, handler: () => {},
}, },
{
matcher: "/admin",
handler: () => {},
},
{
matcher: "/store",
handler: () => {},
},
{ {
matcher: "/admin/products/export", matcher: "/admin/products/export",
methods: ["GET"], methods: ["GET"],
@@ -32,12 +40,20 @@ describe("Routes sorter", () => {
}, },
{ {
matcher: "/admin/products/:id", matcher: "/admin/products/:id",
isAppRoute: true,
methods: ["GET"], methods: ["GET"],
handler: () => {}, handler: () => {},
}, },
{
matcher: "/admin/products/:id",
isAppRoute: true,
methods: ["POST"],
handler: () => {},
},
{ {
matcher: "/admin/products/batch", matcher: "/admin/products/batch",
methods: ["GET"], isAppRoute: true,
methods: ["POST"],
handler: () => {}, handler: () => {},
}, },
{ {
@@ -57,6 +73,7 @@ describe("Routes sorter", () => {
}, },
{ {
matcher: "/admin/:id/export", matcher: "/admin/:id/export",
isAppRoute: true,
methods: ["GET"], methods: ["GET"],
handler: () => {}, handler: () => {},
}, },
@@ -69,6 +86,14 @@ describe("Routes sorter", () => {
expect(sorter.sort()).toMatchInlineSnapshot(` expect(sorter.sort()).toMatchInlineSnapshot(`
[ [
{
"handler": [Function],
"matcher": "/admin",
},
{
"handler": [Function],
"matcher": "/store",
},
{ {
"handler": [Function], "handler": [Function],
"matcher": "/v1", "matcher": "/v1",
@@ -136,13 +161,15 @@ describe("Routes sorter", () => {
}, },
{ {
"handler": [Function], "handler": [Function],
"isAppRoute": true,
"matcher": "/admin/products/batch", "matcher": "/admin/products/batch",
"methods": [ "methods": [
"GET", "POST",
], ],
}, },
{ {
"handler": [Function], "handler": [Function],
"isAppRoute": true,
"matcher": "/admin/products/:id", "matcher": "/admin/products/:id",
"methods": [ "methods": [
"GET", "GET",
@@ -150,6 +177,15 @@ describe("Routes sorter", () => {
}, },
{ {
"handler": [Function], "handler": [Function],
"isAppRoute": true,
"matcher": "/admin/products/:id",
"methods": [
"POST",
],
},
{
"handler": [Function],
"isAppRoute": true,
"matcher": "/admin/:id/export", "matcher": "/admin/:id/export",
"methods": [ "methods": [
"GET", "GET",
@@ -286,4 +322,77 @@ describe("Routes sorter", () => {
] ]
`) `)
}) })
it("should sort routes with multiple params and static values", () => {
const sorter = new RoutesSorter([
{
matcher: "/admin/promotions/:id/:rule_type",
methods: ["GET"],
handler: () => {},
},
{
matcher:
"/admin/promotions/rule-value-options/:rule_type/:rule_attribute_id",
methods: ["GET"],
handler: () => {},
},
{
matcher: "/admin/promotions/rule-attribute-options/:rule_type",
methods: ["GET"],
handler: () => {},
},
{
matcher: "/admin/promotions/:id/:rule_type",
methods: ["GET"],
handler: () => {},
},
{
matcher: "/admin/promotions/rule-attribute-options/:rule_type",
methods: ["GET"],
isAppRoute: true,
handler: () => {},
},
])
expect(sorter.sort()).toMatchInlineSnapshot(`
[
{
"handler": [Function],
"matcher": "/admin/promotions/rule-value-options/:rule_type/:rule_attribute_id",
"methods": [
"GET",
],
},
{
"handler": [Function],
"matcher": "/admin/promotions/rule-attribute-options/:rule_type",
"methods": [
"GET",
],
},
{
"handler": [Function],
"isAppRoute": true,
"matcher": "/admin/promotions/rule-attribute-options/:rule_type",
"methods": [
"GET",
],
},
{
"handler": [Function],
"matcher": "/admin/promotions/:id/:rule_type",
"methods": [
"GET",
],
},
{
"handler": [Function],
"matcher": "/admin/promotions/:id/:rule_type",
"methods": [
"GET",
],
},
]
`)
})
}) })
@@ -2,10 +2,12 @@ import { join } from "path"
import { dynamicImport, FileSystem } from "@medusajs/utils" import { dynamicImport, FileSystem } from "@medusajs/utils"
import { logger } from "../logger" import { logger } from "../logger"
import type { import {
MiddlewaresConfig, type MiddlewaresConfig,
BodyParserConfigRoute, type BodyParserConfigRoute,
ScannedMiddlewareDescriptor, type MiddlewareDescriptor,
type MedusaErrorHandlerFunction,
HTTP_METHODS,
} from "./types" } from "./types"
/** /**
@@ -13,21 +15,6 @@ import type {
*/ */
const MIDDLEWARE_FILE_NAME = "middlewares" const MIDDLEWARE_FILE_NAME = "middlewares"
const log = ({
activityId,
message,
}: {
activityId?: string
message: string
}) => {
if (activityId) {
logger.progress(activityId, message)
return
}
logger.debug(message)
}
/** /**
* Exposes the API to scan a directory and load the `middleware.ts` file. This file contains * Exposes the API to scan a directory and load the `middleware.ts` file. This file contains
* the configuration for certain global middlewares and core routes validators. Also, it may * the configuration for certain global middlewares and core routes validators. Also, it may
@@ -35,19 +22,19 @@ const log = ({
*/ */
export class MiddlewareFileLoader { export class MiddlewareFileLoader {
/** /**
* Middleware collected manually or by scanning directories * Global error handler exported from the middleware file loader
*/ */
#middleware: ScannedMiddlewareDescriptor[] = [] #errorHandler?: MedusaErrorHandlerFunction
#bodyParserConfigRoutes: BodyParserConfigRoute[] = []
/** /**
* An eventual activity id for information tracking * Middleware collected manually or by scanning directories
*/ */
readonly #activityId?: string #middleware: MiddlewareDescriptor[] = []
constructor({ activityId }: { activityId?: string }) { /**
this.#activityId = activityId * Route matchers on which a custom body parser config is used
} */
#bodyParserConfigRoutes: BodyParserConfigRoute[] = []
/** /**
* Processes the middleware file and returns the middleware and the * Processes the middleware file and returns the middleware and the
@@ -58,25 +45,23 @@ export class MiddlewareFileLoader {
const middlewareConfig = middlewareExports.default const middlewareConfig = middlewareExports.default
if (!middlewareConfig) { if (!middlewareConfig) {
log({ logger.warn(
activityId: this.#activityId, `No middleware configuration found in ${absolutePath}. Skipping middleware configuration.`
message: `No middleware configuration found in ${absolutePath}. Skipping middleware configuration.`, )
})
return return
} }
const routes = middlewareConfig.routes as MiddlewaresConfig["routes"] const routes = middlewareConfig.routes as MiddlewaresConfig["routes"]
if (!routes || !Array.isArray(routes)) { if (!routes || !Array.isArray(routes)) {
log({ logger.warn(
activityId: this.#activityId, `Invalid default export found in ${absolutePath}. Make sure to use "defineMiddlewares" function and export its output.`
message: `Invalid default export found in ${absolutePath}. Make sure to use "defineMiddlewares" function and export its output.`, )
})
return return
} }
const result = routes.reduce<{ const result = routes.reduce<{
bodyParserConfigRoutes: BodyParserConfigRoute[] bodyParserConfigRoutes: BodyParserConfigRoute[]
middleware: ScannedMiddlewareDescriptor[] middleware: MiddlewareDescriptor[]
}>( }>(
(result, route) => { (result, route) => {
if (!route.matcher) { if (!route.matcher) {
@@ -92,9 +77,15 @@ export class MiddlewareFileLoader {
const matcher = String(route.matcher) const matcher = String(route.matcher)
if ("bodyParser" in route && route.bodyParser !== undefined) { if ("bodyParser" in route && route.bodyParser !== undefined) {
const methods = route.methods || [...HTTP_METHODS]
logger.debug(
`using custom bodyparser config on matcher ${methods}:${route.matcher}`
)
result.bodyParserConfigRoutes.push({ result.bodyParserConfigRoutes.push({
matcher: matcher, matcher: matcher,
method: route.method, methods,
config: route.bodyParser, config: route.bodyParser,
}) })
} }
@@ -104,7 +95,7 @@ export class MiddlewareFileLoader {
result.middleware.push({ result.middleware.push({
handler: middleware, handler: middleware,
matcher: matcher, matcher: matcher,
method: route.method, methods: route.methods,
}) })
}) })
} }
@@ -116,8 +107,16 @@ export class MiddlewareFileLoader {
} }
) )
this.#middleware = result.middleware const errorHandler =
this.#bodyParserConfigRoutes = result.bodyParserConfigRoutes middlewareConfig.errorHandler as MiddlewaresConfig["errorHandler"]
if (errorHandler) {
this.#errorHandler = errorHandler
}
this.#middleware = this.#middleware.concat(result.middleware)
this.#bodyParserConfigRoutes = this.#bodyParserConfigRoutes.concat(
result.bodyParserConfigRoutes
)
} }
/** /**
@@ -133,11 +132,18 @@ export class MiddlewareFileLoader {
) )
} else if (await fs.exists(`${MIDDLEWARE_FILE_NAME}.js`)) { } else if (await fs.exists(`${MIDDLEWARE_FILE_NAME}.js`)) {
await this.#processMiddlewareFile( await this.#processMiddlewareFile(
join(sourceDir, `${MIDDLEWARE_FILE_NAME}.ts`) join(sourceDir, `${MIDDLEWARE_FILE_NAME}.js`)
) )
} }
} }
/**
* Returns the globally registered error handler (if any)
*/
getErrorHandler() {
return this.#errorHandler
}
/** /**
* Returns a collection of registered middleware * Returns a collection of registered middleware
*/ */
@@ -1,10 +1,18 @@
import { isObject, isPresent } from "@medusajs/utils" import { isObject, isPresent } from "@medusajs/utils"
import { MedusaNextFunction, MedusaRequest } from "../types" import type {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
} from "../types"
export function applyDefaultFilters<TFilter extends object>( export function applyDefaultFilters<TFilter extends object>(
filtersToApply: TFilter filtersToApply: TFilter
) { ) {
return async (req: MedusaRequest, _, next: MedusaNextFunction) => { return async function defaultFiltersMiddleware(
req: MedusaRequest,
_: MedusaResponse,
next: MedusaNextFunction
) {
for (const [filter, filterValue] of Object.entries(filtersToApply)) { for (const [filter, filterValue] of Object.entries(filtersToApply)) {
let valueToApply = filterValue let valueToApply = filterValue
@@ -1,7 +1,15 @@
import { MedusaNextFunction, MedusaRequest } from "../types" import type {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
} from "../types"
export function applyParamsAsFilters(mappings: { [param: string]: string }) { export function applyParamsAsFilters(mappings: { [param: string]: string }) {
return async (req: MedusaRequest, _, next: MedusaNextFunction) => { return async function paramsAsFiltersMiddleware(
req: MedusaRequest,
_: MedusaResponse,
next: MedusaNextFunction
) {
for (const [param, paramValue] of Object.entries(req.params)) { for (const [param, paramValue] of Object.entries(req.params)) {
if (mappings[param]) { if (mappings[param]) {
req.filterableFields[mappings[param]] = paramValue req.filterableFields[mappings[param]] = paramValue
@@ -0,0 +1,96 @@
import { memoize } from "lodash"
import logger from "@medusajs/cli/dist/reporter"
import { json, NextFunction, RequestHandler, text, urlencoded } from "express"
import type {
MedusaRequest,
MedusaResponse,
MiddlewareVerb,
ParserConfigArgs,
MiddlewareFunction,
BodyParserConfigRoute,
} from "../types"
import type { RoutesFinder } from "../routes-finder"
/**
* Parsers to use for parsing the HTTP request body
*/
const parsers = {
json: memoize(function jsonParserMiddleware(options?: ParserConfigArgs) {
return json({
limit: options?.sizeLimit,
verify: options?.preserveRawBody
? (req: MedusaRequest, res: MedusaResponse, buf: Buffer) => {
req.rawBody = buf
}
: undefined,
})
}),
text: memoize(function textParser(options?: ParserConfigArgs) {
return text({
limit: options?.sizeLimit,
})
}),
urlencoded: memoize(function urlencodedParserMiddleware(
options?: ParserConfigArgs
) {
return urlencoded({
limit: options?.sizeLimit,
extended: true,
})
}),
}
/**
* Creates the bodyparser middlewares stack that creates custom bodyparsers
* during an HTTP request based upon the defined config. The bodyparser
* instances are cached for re-use.
*/
export function createBodyParserMiddlewaresStack(
route: string,
routesFinder: RoutesFinder<BodyParserConfigRoute>,
tracer?: (
handler: RequestHandler | MiddlewareFunction,
route: { route: string; method?: string }
) => RequestHandler | MiddlewareFunction
) {
return (["json", "text", "urlencoded"] as (keyof typeof parsers)[]).map(
(parser) => {
function bodyParser(
req: MedusaRequest,
res: MedusaResponse,
next: NextFunction
) {
const matchingRoute = routesFinder.find(
req.path,
req.method as MiddlewareVerb
)
const parserMiddleware = parsers[parser]
if (!matchingRoute) {
return parserMiddleware()(req, res, next)
}
if (matchingRoute.config === false) {
logger.debug(
`skipping ${parser} bodyparser middleware ${req.method} ${req.path}`
)
return next()
}
logger.debug(
`using custom ${parser} bodyparser config ${req.method} ${req.path}`
)
return parserMiddleware(matchingRoute.config)(req, res, next)
}
Object.defineProperty(bodyParser, "name", {
value: `${parser}BodyParser`,
})
return (
tracer ? tracer(bodyParser, { route }) : bodyParser
) as RequestHandler
}
)
}
@@ -1,7 +1,15 @@
import { MedusaNextFunction, MedusaRequest } from "../types" import type {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
} from "../types"
export function clearFiltersByKey(keys: string[]) { export function clearFiltersByKey(keys: string[]) {
return async (req: MedusaRequest, _, next: MedusaNextFunction) => { return async function clearFiltersByKeyMiddleware(
req: MedusaRequest,
_: MedusaResponse,
next: MedusaNextFunction
) {
keys.forEach((key) => { keys.forEach((key) => {
delete req.filterableFields[key] delete req.filterableFields[key]
}) })
@@ -5,7 +5,7 @@ import {
MedusaError, MedusaError,
PUBLISHABLE_KEY_HEADER, PUBLISHABLE_KEY_HEADER,
} from "@medusajs/utils" } from "@medusajs/utils"
import { import type {
MedusaNextFunction, MedusaNextFunction,
MedusaResponse, MedusaResponse,
MedusaStoreRequest, MedusaStoreRequest,
@@ -13,7 +13,7 @@ import {
export async function ensurePublishableApiKeyMiddleware( export async function ensurePublishableApiKeyMiddleware(
req: MedusaStoreRequest, req: MedusaStoreRequest,
_res: MedusaResponse, _: MedusaResponse,
next: MedusaNextFunction next: MedusaNextFunction
) { ) {
const publishableApiKey = req.get(PUBLISHABLE_KEY_HEADER) const publishableApiKey = req.get(PUBLISHABLE_KEY_HEADER)
@@ -1,4 +1,4 @@
import { NextFunction, Response } from "express" import { NextFunction, ErrorRequestHandler, Response } from "express"
import { ContainerRegistrationKeys, MedusaError } from "@medusajs/utils" import { ContainerRegistrationKeys, MedusaError } from "@medusajs/utils"
import { formatException } from "./exception-formatter" import { formatException } from "./exception-formatter"
@@ -13,12 +13,12 @@ const INVALID_REQUEST_ERROR = "invalid_request_error"
const INVALID_STATE_ERROR = "invalid_state_error" const INVALID_STATE_ERROR = "invalid_state_error"
export function errorHandler() { export function errorHandler() {
return ( return function coreErrorHandler(
err: MedusaError, err: MedusaError,
req: MedusaRequest, req: MedusaRequest,
res: Response, res: Response,
next: NextFunction _: NextFunction
) => { ) {
const logger = req.scope.resolve(ContainerRegistrationKeys.LOGGER) const logger = req.scope.resolve(ContainerRegistrationKeys.LOGGER)
err = formatException(err) err = formatException(err)
@@ -76,7 +76,7 @@ export function errorHandler() {
} }
res.status(statusCode).json(errObj) res.status(statusCode).json(errObj)
} } as unknown as ErrorRequestHandler
} }
/** /**
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,64 @@
import pathToRegexp from "path-to-regexp"
import type { MiddlewareVerb, RouteVerb } from "./types"
export class RoutesFinder<
T extends
| { matcher: string; methods: MiddlewareVerb | MiddlewareVerb[] }
| { matcher: string; method: RouteVerb }
> {
/**
* Cache of existing matches to avoid regex tests on every
* single HTTP request
*/
#existingMatches: Map<
string,
| (T & {
matchRegex: RegExp
})
| null
> = new Map()
/**
* Collection of registered routes
*/
#routes: (T & {
matchRegex: RegExp
})[] = []
constructor(routes?: T[]) {
if (routes) {
routes.forEach((route) => this.add(route))
}
}
/**
* Register route for lookup
*/
add(route: T) {
this.#routes.push({
...route,
matchRegex: pathToRegexp(route.matcher),
})
}
/**
* Get the matching route for a given HTTP method and URL
*/
find(url: string, method: MiddlewareVerb) {
const key = `${method}:${url}`
if (this.#existingMatches.has(key)) {
return this.#existingMatches.get(key)
}
const result =
this.#routes.find((route) => {
if ("methods" in route) {
return route.methods.includes(method) && route.matchRegex.test(url)
}
return route.method === method && route.matchRegex.test(url)
}) ?? null
this.#existingMatches.set(key, result)
return result
}
}
@@ -1,12 +1,7 @@
import { join, parse, sep } from "path" import { join, parse, sep } from "path"
import { dynamicImport, readDirRecursive } from "@medusajs/utils" import { dynamicImport, readDirRecursive } from "@medusajs/utils"
import { logger } from "../logger" import { logger } from "../logger"
import { import { type RouteVerb, HTTP_METHODS, type RouteDescriptor } from "./types"
type RouteVerb,
HTTP_METHODS,
type ScannedRouteDescriptor,
type FileSystemRouteDescriptor,
} from "./types"
/** /**
* File name that is used to indicate that the file is a route file * File name that is used to indicate that the file is a route file
@@ -43,21 +38,6 @@ const ADMIN_ROUTE_MATCH = /(\/admin$|\/admin\/)/
const STORE_ROUTE_MATCH = /(\/store$|\/store\/)/ const STORE_ROUTE_MATCH = /(\/store$|\/store\/)/
const AUTH_ROUTE_MATCH = /(\/auth$|\/auth\/)/ const AUTH_ROUTE_MATCH = /(\/auth$|\/auth\/)/
const log = ({
activityId,
message,
}: {
activityId?: string
message: string
}) => {
if (activityId) {
logger.progress(activityId, message)
return
}
logger.debug(message)
}
/** /**
* Exposes to API to register routes manually or by scanning the filesystem from a * Exposes to API to register routes manually or by scanning the filesystem from a
* source directory. * source directory.
@@ -69,19 +49,7 @@ export class RoutesLoader {
/** /**
* Routes collected manually or by scanning directories * Routes collected manually or by scanning directories
*/ */
#routes: Record< #routes: Record<string, Record<string, RouteDescriptor>> = {}
string,
Record<string, ScannedRouteDescriptor | FileSystemRouteDescriptor>
> = {}
/**
* An eventual activity id for information tracking
*/
readonly #activityId?: string
constructor({ activityId }: { activityId?: string }) {
this.#activityId = activityId
}
/** /**
* Creates the route path from its relative file path. * Creates the route path from its relative file path.
@@ -96,10 +64,9 @@ export class RoutesLoader {
if (segment.startsWith("[")) { if (segment.startsWith("[")) {
segment = segment.replace(PARAM_SEGMENT_MATCHER, (_, group) => { segment = segment.replace(PARAM_SEGMENT_MATCHER, (_, group) => {
if (params[group]) { if (params[group]) {
log({ logger.debug(
activityId: this.#activityId, `Duplicate parameters found in route ${relativePath} (${group})`
message: `Duplicate parameters found in route ${relativePath} (${group})`, )
})
throw new Error( throw new Error(
`Duplicate parameters found in route ${relativePath} (${group}). Make sure that all parameters are unique.` `Duplicate parameters found in route ${relativePath} (${group}). Make sure that all parameters are unique.`
@@ -122,7 +89,7 @@ export class RoutesLoader {
async #getRoutesForFile( async #getRoutesForFile(
routePath: string, routePath: string,
absolutePath: string absolutePath: string
): Promise<ScannedRouteDescriptor[]> { ): Promise<RouteDescriptor[]> {
const routeExports = await dynamicImport(absolutePath) const routeExports = await dynamicImport(absolutePath)
/** /**
@@ -161,10 +128,9 @@ export class RoutesLoader {
} }
if (!HTTP_METHODS.includes(key as RouteVerb)) { if (!HTTP_METHODS.includes(key as RouteVerb)) {
log({ logger.debug(
activityId: this.#activityId, `Skipping handler ${key} in ${absolutePath}. Invalid HTTP method: ${key}.`
message: `Skipping handler ${key} in ${absolutePath}. Invalid HTTP method: ${key}.`, )
})
return false return false
} }
@@ -172,14 +138,15 @@ export class RoutesLoader {
}) })
.map((key) => { .map((key) => {
return { return {
route: routePath, isRoute: true,
matcher: routePath,
method: key as RouteVerb, method: key as RouteVerb,
handler: routeExports[key], handler: routeExports[key],
optedOutOfAuth: !shouldAuthenticate, optedOutOfAuth: !shouldAuthenticate,
shouldAppendAdminCors: shouldApplyCors && routeType === "admin", shouldAppendAdminCors: shouldApplyCors && routeType === "admin",
shouldAppendAuthCors: shouldApplyCors && routeType === "auth", shouldAppendAuthCors: shouldApplyCors && routeType === "auth",
shouldAppendStoreCors: shouldApplyCors && routeType === "store", shouldAppendStoreCors: shouldApplyCors && routeType === "store",
} satisfies ScannedRouteDescriptor } satisfies RouteDescriptor
}) })
} }
@@ -232,18 +199,16 @@ export class RoutesLoader {
/** /**
* Register a route * Register a route
*/ */
registerRoute(route: ScannedRouteDescriptor | FileSystemRouteDescriptor) { registerRoute(route: RouteDescriptor) {
this.#routes[route.route] = this.#routes[route.route] ?? {} this.#routes[route.matcher] = this.#routes[route.matcher] ?? {}
const trackedRoute = this.#routes[route.route] const trackedRoute = this.#routes[route.matcher]
trackedRoute[route.method] = route trackedRoute[route.method] = route
} }
/** /**
* Register one or more routes * Register one or more routes
*/ */
registerRoutes( registerRoutes(routes: RouteDescriptor[]) {
routes: (ScannedRouteDescriptor | FileSystemRouteDescriptor)[]
) {
routes.forEach((route) => this.registerRoute(route)) routes.forEach((route) => this.registerRoute(route))
} }
@@ -252,14 +217,16 @@ export class RoutesLoader {
* manually. * manually.
*/ */
getRoutes() { getRoutes() {
return Object.keys(this.#routes).reduce< return Object.keys(this.#routes).reduce<RouteDescriptor[]>(
(ScannedRouteDescriptor | FileSystemRouteDescriptor)[] (result, routePattern) => {
>((result, routePattern) => { const methodsRoutes = this.#routes[routePattern]
const methodsRoutes = this.#routes[routePattern] Object.keys(methodsRoutes).forEach((method) => {
Object.keys(methodsRoutes).forEach((method) => { const route = methodsRoutes[method]
result.push(methodsRoutes[method]) result.push(route)
}) })
return result return result
}, []) },
[]
)
} }
} }
@@ -1,9 +1,9 @@
import { MiddlewareVerb } from "./types" import { MiddlewareVerb, RouteVerb } from "./types"
/** /**
* Route represents both the middleware/routes defined via the * Route represents both the middleware/routes defined via the
* "defineMiddlewares" method and the routes scanned from * "defineMiddlewares" method and the routes scanned from
* the filesystem. The later one's must be marked with "isAppRoute = true". * the filesystem.
*/ */
type Route = { type Route = {
/** /**
@@ -17,10 +17,9 @@ type Route = {
handler?: any handler?: any
/** /**
* Must be true when the route is discovered via the fileystem * The HTTP method specified as a single value
* scanning.
*/ */
isAppRoute?: boolean method?: RouteVerb
/** /**
* The HTTP methods this route is supposed to handle. * The HTTP methods this route is supposed to handle.
@@ -48,39 +47,39 @@ type Route = {
* - static * - static
* - params * - params
*/ */
type RoutesBranch = { type RoutesBranch<T extends Route> = {
global: { global: {
routes: Route[] routes: T[]
children?: { children?: {
[segment: string]: RoutesBranch [segment: string]: RoutesBranch<T>
} }
} }
regex: { regex: {
routes: Route[] routes: T[]
children?: { children?: {
[segment: string]: RoutesBranch [segment: string]: RoutesBranch<T>
} }
} }
wildcard: { wildcard: {
routes: Route[] routes: T[]
children?: { children?: {
[segment: string]: RoutesBranch [segment: string]: RoutesBranch<T>
} }
} }
params: { params: {
routes: Route[] routes: T[]
children?: { children?: {
[segment: string]: RoutesBranch [segment: string]: RoutesBranch<T>
} }
} }
static: { static: {
routes: Route[] routes: T[]
children?: { children?: {
[segment: string]: RoutesBranch [segment: string]: RoutesBranch<T>
} }
} }
} }
@@ -91,29 +90,42 @@ type RoutesBranch = {
* like structure and then sort them back to a flat array based upon the * like structure and then sort them back to a flat array based upon the
* priorities of different types of nodes. * priorities of different types of nodes.
*/ */
export class RoutesSorter { export class RoutesSorter<T extends Route> {
/**
* The order in which the routes will be sorted. This
* can be overridden at the time of call the sort
* method.
*/
#orderBy: [
keyof RoutesBranch<T>,
keyof RoutesBranch<T>,
keyof RoutesBranch<T>,
keyof RoutesBranch<T>,
keyof RoutesBranch<T>
] = ["global", "wildcard", "regex", "static", "params"]
/** /**
* Input routes * Input routes
*/ */
#routesToProcess: Route[] #routesToProcess: T[]
/** /**
* Intermediate tree representation for sorting routes * Intermediate tree representation for sorting routes
*/ */
#routesTree: { #routesTree: {
[segment: string]: RoutesBranch [segment: string]: RoutesBranch<T>
} = { } = {
root: this.#createBranch(), root: this.#createBranch(),
} }
constructor(routes: Route[]) { constructor(routes: T[]) {
this.#routesToProcess = routes this.#routesToProcess = routes
} }
/** /**
* Creates an empty branch with known nodes * Creates an empty branch with known nodes
*/ */
#createBranch(): RoutesBranch { #createBranch(): RoutesBranch<T> {
return { return {
global: { global: {
routes: [], routes: [],
@@ -162,14 +174,14 @@ export class RoutesSorter {
* } * }
* ``` * ```
*/ */
#processRoute(route: Route) { #processRoute(route: T) {
const segments = route.matcher.split("/").filter((s) => s.length) const segments = route.matcher.split("/").filter((s) => s.length)
let parent = this.#routesTree["root"] let parent = this.#routesTree["root"]
segments.forEach((segment, index) => { segments.forEach((segment, index) => {
let bucket: keyof RoutesBranch = "static" let bucket: keyof RoutesBranch<T> = "static"
if (!route.methods) { if (!route.methods && !route.method) {
bucket = "global" bucket = "global"
} else if (segment.startsWith("*")) { } else if (segment.startsWith("*")) {
bucket = "wildcard" bucket = "wildcard"
@@ -194,40 +206,51 @@ export class RoutesSorter {
/** /**
* Returns an array of sorted routes for a given branch. * Returns an array of sorted routes for a given branch.
*/ */
#sortBranch(routeBranch: { [segment: string]: RoutesBranch }) { #sortBranch(
routeBranch: { [segment: string]: RoutesBranch<T> },
orderBy: [
keyof RoutesBranch<T>,
keyof RoutesBranch<T>,
keyof RoutesBranch<T>,
keyof RoutesBranch<T>,
keyof RoutesBranch<T>
]
) {
const branchRoutes = Object.keys(routeBranch).reduce<{ const branchRoutes = Object.keys(routeBranch).reduce<{
global: Route[] global: T[]
wildcard: Route[] wildcard: T[]
regex: Route[] regex: T[]
params: Route[] params: T[]
static: Route[] static: T[]
}>( }>(
(result, branchKey) => { (result, branchKey) => {
const node = routeBranch[branchKey] const node = routeBranch[branchKey]
result.global.push(...node.global.routes) result.global.push(...node.global.routes)
if (node.global.children) { if (node.global.children) {
result.global.push(...this.#sortBranch(node.global.children)) result.global.push(...this.#sortBranch(node.global.children, orderBy))
} }
result.wildcard.push(...node.wildcard.routes) result.wildcard.push(...node.wildcard.routes)
if (node.wildcard.children) { if (node.wildcard.children) {
result.wildcard.push(...this.#sortBranch(node.wildcard.children)) result.wildcard.push(
...this.#sortBranch(node.wildcard.children, orderBy)
)
} }
result.regex.push(...node.regex.routes) result.regex.push(...node.regex.routes)
if (node.regex.children) { if (node.regex.children) {
result.regex.push(...this.#sortBranch(node.regex.children)) result.regex.push(...this.#sortBranch(node.regex.children, orderBy))
} }
result.static.push(...node.static.routes) result.static.push(...node.static.routes)
if (node.static.children) { if (node.static.children) {
result.static.push(...this.#sortBranch(node.static.children)) result.static.push(...this.#sortBranch(node.static.children, orderBy))
} }
result.params.push(...node.params.routes) result.params.push(...node.params.routes)
if (node.params.children) { if (node.params.children) {
result.params.push(...this.#sortBranch(node.params.children)) result.params.push(...this.#sortBranch(node.params.children, orderBy))
} }
return result return result
@@ -244,19 +267,33 @@ export class RoutesSorter {
/** /**
* Concatenating routes as per their priority. * Concatenating routes as per their priority.
*/ */
const routes: Route[] = branchRoutes.global return orderBy.reduce<T[]>((result, branch) => {
.concat(branchRoutes.wildcard) result = result.concat(branchRoutes[branch])
.concat(branchRoutes.regex) return result
.concat(branchRoutes.static) }, [])
.concat(branchRoutes.params)
return routes
} }
/** /**
* Sort the input routes * Returns the intermediate representation of routes as a tree.
*/ */
sort() { getTree() {
return this.#routesTree
}
/**
* Sort the input routes. You can optionally specify a custom
* orderBy array. Defaults to: ["global", "wildcard", "regex", "static", "params"]
*/
sort(
orderBy?: [
keyof RoutesBranch<T>,
keyof RoutesBranch<T>,
keyof RoutesBranch<T>,
keyof RoutesBranch<T>,
keyof RoutesBranch<T>
]
) {
this.#routesToProcess.map((route) => this.#processRoute(route)) this.#routesToProcess.map((route) => this.#processRoute(route))
return this.#sortBranch(this.#routesTree) return this.#sortBranch(this.#routesTree, orderBy ?? this.#orderBy)
} }
} }
+14 -35
View File
@@ -34,20 +34,6 @@ export type AsyncRouteHandler = (
export type RouteHandler = SyncRouteHandler | AsyncRouteHandler export type RouteHandler = SyncRouteHandler | AsyncRouteHandler
export type RouteImplementation = {
method?: RouteVerb
handler: RouteHandler
}
export type RouteConfig = {
optedOutOfAuth?: boolean
routeType?: "admin" | "store" | "auth"
shouldAppendAdminCors?: boolean
shouldAppendStoreCors?: boolean
shouldAppendAuthCors?: boolean
routes?: RouteImplementation[]
}
export type MiddlewareFunction = export type MiddlewareFunction =
| MedusaRequestHandler | MedusaRequestHandler
| ((...args: any[]) => any) | ((...args: any[]) => any)
@@ -67,7 +53,11 @@ export type ParserConfigArgs = {
export type ParserConfig = false | ParserConfigArgs export type ParserConfig = false | ParserConfigArgs
export type MiddlewareRoute = { export type MiddlewareRoute = {
/**
* @deprecated. Instead use {@link MiddlewareRoute.methods}
*/
method?: MiddlewareVerb | MiddlewareVerb[] method?: MiddlewareVerb | MiddlewareVerb[]
methods?: MiddlewareVerb[]
matcher: string | RegExp matcher: string | RegExp
bodyParser?: ParserConfig bodyParser?: ParserConfig
middlewares?: MiddlewareFunction[] middlewares?: MiddlewareFunction[]
@@ -78,49 +68,38 @@ export type MiddlewaresConfig = {
routes?: MiddlewareRoute[] routes?: MiddlewareRoute[]
} }
export type RouteDescriptor = {
absolutePath: string
relativePath: string
route: string
priority: number
config?: RouteConfig
}
/** /**
* Route descriptor refers represents a route either scanned * Route descriptor refers represents a route either scanned
* from the filesystem or registered manually. It does not * from the filesystem or registered manually. It does not
* represent a middleware * represent a middleware
*/ */
export type ScannedRouteDescriptor = { export type RouteDescriptor = {
route: string matcher: string
method: RouteVerb method: RouteVerb
handler: RouteHandler handler: RouteHandler
optedOutOfAuth: boolean optedOutOfAuth: boolean
isRoute: true
routeType?: "admin" | "store" | "auth" routeType?: "admin" | "store" | "auth"
absolutePath?: string
relativePath?: string
shouldAppendAdminCors: boolean shouldAppendAdminCors: boolean
shouldAppendStoreCors: boolean shouldAppendStoreCors: boolean
shouldAppendAuthCors: boolean shouldAppendAuthCors: boolean
} }
/** /**
* FileSystem route description represents a route scanned from * Represents a middleware
* the filesystem
*/ */
export type FileSystemRouteDescriptor = ScannedRouteDescriptor & { export type MiddlewareDescriptor = {
absolutePath: string
relativePath: string
}
export type ScannedMiddlewareDescriptor = {
matcher: string matcher: string
method?: MiddlewareVerb | MiddlewareVerb[] methods?: MiddlewareVerb | MiddlewareVerb[]
handler: MiddlewareFunction handler: MiddlewareFunction
} }
export type BodyParserConfigRoute = { export type BodyParserConfigRoute = {
matcher: string matcher: string
method?: MiddlewareVerb | MiddlewareVerb[] methods: MiddlewareVerb | MiddlewareVerb[]
config?: ParserConfig config: ParserConfig
} }
export type GlobalMiddlewareDescriptor = { export type GlobalMiddlewareDescriptor = {
@@ -16,7 +16,11 @@ import zod, { ZodRawShape } from "zod"
*/ */
export function defineMiddlewares< export function defineMiddlewares<
Route extends { Route extends {
/**
* @deprecated. Instead use {@link MiddlewareRoute.methods}
*/
method?: MiddlewareVerb | MiddlewareVerb[] method?: MiddlewareVerb | MiddlewareVerb[]
methods?: MiddlewareVerb[]
matcher: string | RegExp matcher: string | RegExp
bodyParser?: ParserConfig bodyParser?: ParserConfig
additionalDataValidator?: ZodRawShape additionalDataValidator?: ZodRawShape
@@ -38,7 +42,8 @@ export function defineMiddlewares<
return { return {
errorHandler, errorHandler,
routes: routes.map((route) => { routes: routes.map((route) => {
const { middlewares, additionalDataValidator, ...rest } = route let { middlewares, method, methods, additionalDataValidator, ...rest } =
route
const customMiddleware: MedusaRequestHandler[] = [] const customMiddleware: MedusaRequestHandler[] = []
/** /**
@@ -54,8 +59,13 @@ export function defineMiddlewares<
}) })
} }
if (!methods) {
methods = Array.isArray(method) ? method : method ? [method] : method
}
return { return {
...rest, ...rest,
methods,
middlewares: customMiddleware.concat(middlewares || []), middlewares: customMiddleware.concat(middlewares || []),
} }
}), }),
@@ -3,7 +3,11 @@ import {
ContainerRegistrationKeys, ContainerRegistrationKeys,
remoteQueryObjectFromString, remoteQueryObjectFromString,
} from "@medusajs/utils" } from "@medusajs/utils"
import { MedusaNextFunction, MedusaRequest } from "../types" import type {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
} from "../types"
export function maybeApplyLinkFilter({ export function maybeApplyLinkFilter({
entryPoint, entryPoint,
@@ -13,7 +17,7 @@ export function maybeApplyLinkFilter({
}) { }) {
return async function linkFilter( return async function linkFilter(
req: MedusaRequest, req: MedusaRequest,
_, _: MedusaResponse,
next: MedusaNextFunction next: MedusaNextFunction
) { ) {
const filterableFields = req.filterableFields const filterableFields = req.filterableFields
@@ -0,0 +1,38 @@
import type {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
MiddlewareFunction,
RouteHandler,
} from "../types"
export const wrapHandler = <T extends RouteHandler | MiddlewareFunction>(
fn: T
) => {
async function wrappedHandler(
req: MedusaRequest,
res: MedusaResponse,
next: MedusaNextFunction
) {
const req_ = req as MedusaRequest & { errors?: Error[] }
if (req_?.errors?.length) {
return res.status(400).json({
errors: req_.errors,
message:
"Provided request body contains errors. Please check the data and retry the request",
})
}
try {
return await fn(req, res, next)
} catch (err) {
console.log(err)
next(err)
}
}
if (fn.name) {
Object.defineProperty(wrappedHandler, "name", { value: fn.name })
}
return wrappedHandler as T
}
@@ -0,0 +1,11 @@
import { MedusaContainer } from "@medusajs/types"
export default async function handler(container: MedusaContainer) {
console.log(`You have received 5 orders today`)
}
export const config = {
name: "summarize-orders",
schedule: "* * * * * *",
numberOfExecutions: 2,
}
@@ -0,0 +1,11 @@
import { MedusaContainer } from "@medusajs/types"
export default async function handler(container: MedusaContainer) {
console.log(`You have received 5 orders today`)
}
export const config = {
name: "summarize-orders",
schedule: "* * * * * *",
numberOfExecutions: 2,
}
@@ -6,13 +6,14 @@ import { JobLoader } from "../job-loader"
describe("register jobs", () => { describe("register jobs", () => {
WorkflowScheduler.setStorage(new MockSchedulerStorage()) WorkflowScheduler.setStorage(new MockSchedulerStorage())
let jobLoader!: JobLoader afterEach(() => {
WorkflowManager.unregisterAll()
beforeAll(() => {
jobLoader = new JobLoader(join(__dirname, "../__fixtures__/plugin/jobs"))
}) })
it("registers jobs from plugins", async () => { it("should registers jobs from plugins", async () => {
const jobLoader: JobLoader = new JobLoader(
join(__dirname, "../__fixtures__/plugin/jobs")
)
await jobLoader.load() await jobLoader.load()
const workflow = WorkflowManager.getWorkflow("job-summarize-orders") const workflow = WorkflowManager.getWorkflow("job-summarize-orders")
expect(workflow).toBeDefined() expect(workflow).toBeDefined()
@@ -21,4 +22,13 @@ describe("register jobs", () => {
numberOfExecutions: 2, numberOfExecutions: 2,
}) })
}) })
it("should not load non js/ts files", async () => {
const jobLoader: JobLoader = new JobLoader(
join(__dirname, "../__fixtures__/plugin/jobs-with-other-files")
)
await jobLoader.load()
const workflow = WorkflowManager.getWorkflow("job-summarize-orders")
expect(workflow).toBeUndefined()
})
}) })
+23 -82
View File
@@ -1,21 +1,13 @@
import type { SchedulerOptions } from "@medusajs/orchestration" import type { SchedulerOptions } from "@medusajs/orchestration"
import { MedusaContainer } from "@medusajs/types" import { MedusaContainer } from "@medusajs/types"
import { import { isObject, MedusaError } from "@medusajs/utils"
dynamicImport,
isObject,
MedusaError,
promiseAll,
readDirRecursive,
} from "@medusajs/utils"
import { import {
createStep, createStep,
createWorkflow, createWorkflow,
StepResponse, StepResponse,
} from "@medusajs/workflows-sdk" } from "@medusajs/workflows-sdk"
import { Dirent } from "fs"
import { access } from "fs/promises"
import { join } from "path"
import { logger } from "../logger" import { logger } from "../logger"
import { ResourceLoader } from "../utils/resource-loader"
type CronJobConfig = { type CronJobConfig = {
name: string name: string
@@ -25,27 +17,26 @@ type CronJobConfig = {
type CronJobHandler = (container: MedusaContainer) => Promise<any> type CronJobHandler = (container: MedusaContainer) => Promise<any>
export class JobLoader { export class JobLoader extends ResourceLoader {
/** protected resourceName = "job"
* The directory from which to load the jobs
* @private
*/
#sourceDir: string | string[]
/**
* The list of file names to exclude from the subscriber scan
* @private
*/
#excludes: RegExp[] = [
/index\.js/,
/index\.ts/,
/\.DS_Store/,
/(\.ts\.map|\.js\.map|\.d\.ts|\.md)/,
/^_[^/\\]*(\.[^/\\]+)?$/,
]
constructor(sourceDir: string | string[]) { constructor(sourceDir: string | string[]) {
this.#sourceDir = sourceDir super(sourceDir)
}
protected async onFileLoaded(
path: string,
fileExports: {
default: CronJobHandler
config: CronJobConfig
}
) {
this.validateConfig(fileExports.config)
logger.debug(`Registering job from ${path}.`)
this.register({
config: fileExports.config,
handler: fileExports.default,
})
} }
/** /**
@@ -85,7 +76,7 @@ export class JobLoader {
* @param handler * @param handler
* @protected * @protected
*/ */
protected registerJob({ protected register({
config, config,
handler, handler,
}: { }: {
@@ -128,58 +119,8 @@ export class JobLoader {
* Load cron jobs from one or multiple source paths * Load cron jobs from one or multiple source paths
*/ */
async load() { async load() {
const normalizedSourcePath = Array.isArray(this.#sourceDir) await super.discoverResources()
? this.#sourceDir
: [this.#sourceDir]
const promises = normalizedSourcePath.map(async (sourcePath) => { logger.debug(`Jobs registered.`)
try {
await access(sourcePath)
} catch {
logger.info(`No job to load from ${sourcePath}. skipped.`)
return
}
return await readDirRecursive(sourcePath).then(async (entries) => {
const fileEntries = entries.filter((entry: Dirent) => {
return (
!entry.isDirectory() &&
!this.#excludes.some((exclude) => exclude.test(entry.name))
)
})
logger.debug(`Registering jobs from ${sourcePath}.`)
return await promiseAll(
fileEntries.map(async (entry: Dirent) => {
const fullPath = join(entry.path, entry.name)
const module_ = await dynamicImport(fullPath)
const input = {
config: module_.config,
handler: module_.default,
}
this.validateConfig(input.config)
return input
})
)
})
})
const jobsInputs = await promiseAll(promises)
const flatJobsInput = jobsInputs.flat(1).filter(
(
job
): job is {
config: CronJobConfig
handler: CronJobHandler
} => !!job
)
flatJobsInput.map(this.registerJob)
logger.debug(`Job registered.`)
} }
} }
@@ -0,0 +1,10 @@
import { SubscriberArgs, SubscriberConfig } from "../../types"
export default async function orderNotifier(\_: SubscriberArgs) {
return await Promise.resolve()
}
export const config: SubscriberConfig = {
event: ["order.placed", "order.canceled", "order.completed"],
context: { subscriberId: "order-notifier-md" },
}
@@ -0,0 +1,10 @@
import { SubscriberArgs, SubscriberConfig } from "../../types"
export default async function orderNotifier(_: SubscriberArgs) {
return await Promise.resolve()
}
export const config: SubscriberConfig = {
event: ["order.placed", "order.canceled", "order.completed"],
context: { subscriberId: "order-notifier-txt" },
}
@@ -1,20 +1,12 @@
import { Event, IEventBusModuleService, Subscriber } from "@medusajs/types" import { Event, IEventBusModuleService, Subscriber } from "@medusajs/types"
import { import { kebabCase, Modules } from "@medusajs/utils"
dynamicImport, import { parse } from "path"
kebabCase,
Modules,
promiseAll,
readDirRecursive,
resolveExports,
} from "@medusajs/utils"
import { access } from "fs/promises"
import { join, parse } from "path"
import { Dirent } from "fs"
import { configManager } from "../config" import { configManager } from "../config"
import { container } from "../container" import { container } from "../container"
import { logger } from "../logger" import { logger } from "../logger"
import { SubscriberArgs, SubscriberConfig } from "./types" import { SubscriberArgs, SubscriberConfig } from "./types"
import { ResourceLoader } from "../utils/resource-loader"
type SubscriberHandler<T> = (args: SubscriberArgs<T>) => Promise<void> type SubscriberHandler<T> = (args: SubscriberArgs<T>) => Promise<void>
@@ -23,31 +15,15 @@ type SubscriberModule<T> = {
handler: SubscriberHandler<T> handler: SubscriberHandler<T>
} }
export class SubscriberLoader { export class SubscriberLoader extends ResourceLoader {
protected resourceName = "subscriber"
/** /**
* The options of the plugin from which the subscribers are being loaded * The options of the plugin from which the subscribers are being loaded
* @private * @private
*/ */
#pluginOptions: Record<string, unknown> #pluginOptions: Record<string, unknown>
/**
* The base directory from which to scan for the subscribers
* @private
*/
#sourceDir: string | string[]
/**
* The list of file names to exclude from the subscriber scan
* @private
*/
#excludes: RegExp[] = [
/index\.js/,
/index\.ts/,
/\.DS_Store/,
/(\.ts\.map|\.js\.map|\.d\.ts|\.md)/,
/^_[^/\\]*(\.[^/\\]+)?$/,
]
/** /**
* Map of subscribers descriptors to consume in the loader * Map of subscribers descriptors to consume in the loader
* @private * @private
@@ -58,10 +34,28 @@ export class SubscriberLoader {
sourceDir: string | string[], sourceDir: string | string[],
options: Record<string, unknown> = {} options: Record<string, unknown> = {}
) { ) {
this.#sourceDir = sourceDir super(sourceDir)
this.#pluginOptions = options this.#pluginOptions = options
} }
protected async onFileLoaded(
path: string,
fileExports: Record<string, unknown>
) {
const isValid = this.validateSubscriber(fileExports, path)
logger.debug(`Registering subscribers from ${path}.`)
if (!isValid) {
return
}
this.#subscriberDescriptors.set(path, {
config: fileExports.config,
handler: fileExports.default,
})
}
private validateSubscriber( private validateSubscriber(
subscriber: any, subscriber: any,
path: string path: string
@@ -122,42 +116,6 @@ export class SubscriberLoader {
return true return true
} }
private async createDescriptor(absolutePath: string) {
return await dynamicImport(absolutePath).then((module_) => {
module_ = resolveExports(module_)
const isValid = this.validateSubscriber(module_, absolutePath)
if (!isValid) {
return
}
this.#subscriberDescriptors.set(absolutePath, {
config: module_.config,
handler: module_.default,
})
})
}
private async createMap(dirPath: string) {
const promises = await readDirRecursive(dirPath).then(async (entries) => {
const fileEntries = entries.filter((entry) => {
return (
!entry.isDirectory() &&
!this.#excludes.some((exclude) => exclude.test(entry.name))
)
})
logger.debug(`Registering subscribers from ${dirPath}.`)
return fileEntries.flatMap(async (entry: Dirent) => {
const fullPath = join(entry.path, entry.name)
return await this.createDescriptor(fullPath)
})
})
await promiseAll(promises)
}
private inferIdentifier<T>( private inferIdentifier<T>(
fileName: string, fileName: string,
{ context }: SubscriberConfig, { context }: SubscriberConfig,
@@ -222,21 +180,7 @@ export class SubscriberLoader {
} }
async load() { async load() {
const normalizeSourcePaths = Array.isArray(this.#sourceDir) await super.discoverResources()
? this.#sourceDir
: [this.#sourceDir]
const promises = normalizeSourcePaths.map(async (sourcePath) => {
try {
await access(sourcePath)
} catch {
logger.info(`No subscribers to load from ${sourcePath}. skipped.`)
return
}
return await this.createMap(sourcePath)
})
await promiseAll(promises)
for (const [ for (const [
fileName, fileName,
@@ -0,0 +1,101 @@
import { dynamicImport, promiseAll, readDirRecursive } from "@medusajs/utils"
import { Dirent } from "fs"
import { access } from "fs/promises"
import { join, parse } from "path"
import { logger } from "../logger"
export abstract class ResourceLoader {
/**
* The name of the resource (e.g job, subscriber, workflow)
*/
protected abstract resourceName: string
/**
* The directory from which to load the jobs
* @private
*/
#sourceDir: string | string[]
/**
* The list of file names to exclude from the subscriber scan
* @private
*/
#excludes: RegExp[] = [/^_[^/\\]*(\.[^/\\]+)?$/]
constructor(sourceDir: string | string[]) {
this.#sourceDir = sourceDir
}
/**
* Discover resources from the source directory
* @param exclude - custom exclusion regexes
* @param customFiltering - custom filtering function
* @returns The resources discovered
*/
protected async discoverResources({
exclude,
customFiltering,
}: {
exclude?: RegExp[]
customFiltering?: (entry: Dirent) => boolean
} = {}): Promise<Record<string, unknown>[]> {
exclude ??= []
customFiltering ??= (entry: Dirent) => {
const parsedName = parse(entry.name)
return (
!entry.isDirectory() &&
parsedName.name !== "index" &&
!parsedName.base.endsWith(".d.ts") &&
[".js", ".ts"].includes(parsedName.ext) &&
!this.#excludes.some((exclude) => exclude.test(parsedName.base)) &&
!exclude.some((exclude) => exclude.test(parsedName.base))
)
}
const normalizedSourcePath = Array.isArray(this.#sourceDir)
? this.#sourceDir
: [this.#sourceDir]
const promises = normalizedSourcePath.map(async (sourcePath) => {
try {
await access(sourcePath)
} catch {
logger.info(
`No ${this.resourceName} to load from ${sourcePath}. skipped.`
)
return
}
return await readDirRecursive(sourcePath).then(async (entries) => {
const fileEntries = entries.filter((entry: Dirent) =>
customFiltering(entry)
)
return await promiseAll(
fileEntries.map(async (entry: Dirent) => {
const fullPath = join(entry.path, entry.name)
const module_ = await dynamicImport(fullPath)
await this.onFileLoaded(fullPath, module_)
return module_
})
)
})
})
const resources = await promiseAll(promises)
return resources.flat()
}
/**
* Called when a file is imported
* @param path - The path of the file
* @param fileExports - The exports of the file
*/
protected abstract onFileLoaded(
path: string,
fileExports: Record<string, unknown>
): Promise<void> | never
}
@@ -1,30 +1,18 @@
import { dynamicImport, promiseAll, readDirRecursive } from "@medusajs/utils"
import { Dirent } from "fs"
import { access } from "fs/promises"
import { join } from "path"
import { logger } from "../logger" import { logger } from "../logger"
import { ResourceLoader } from "../utils/resource-loader"
export class WorkflowLoader { export class WorkflowLoader extends ResourceLoader {
/** protected resourceName = "workflow"
* The directory from which to load the workflows
* @private
*/
#sourceDir: string | string[]
/**
* The list of file names to exclude from the subscriber scan
* @private
*/
#excludes: RegExp[] = [
/index\.js/,
/index\.ts/,
/\.DS_Store/,
/(\.ts\.map|\.js\.map|\.d\.ts|\.md)/,
/^_[^/\\]*(\.[^/\\]+)?$/,
]
constructor(sourceDir: string | string[]) { constructor(sourceDir: string | string[]) {
this.#sourceDir = sourceDir super(sourceDir)
}
protected async onFileLoaded(
path: string,
fileExports: Record<string, unknown>
) {
logger.debug(`Registering workflows from ${path}.`)
} }
/** /**
@@ -32,38 +20,7 @@ export class WorkflowLoader {
* therefore we only need to import them * therefore we only need to import them
*/ */
async load() { async load() {
const normalizedSourcePath = Array.isArray(this.#sourceDir) await super.discoverResources()
? this.#sourceDir
: [this.#sourceDir]
const promises = normalizedSourcePath.map(async (sourcePath) => {
try {
await access(sourcePath)
} catch {
logger.info(`No workflow to load from ${sourcePath}. skipped.`)
return
}
return await readDirRecursive(sourcePath).then(async (entries) => {
const fileEntries = entries.filter((entry: Dirent) => {
return (
!entry.isDirectory() &&
!this.#excludes.some((exclude) => exclude.test(entry.name))
)
})
logger.debug(`Registering workflows from ${sourcePath}.`)
return await promiseAll(
fileEntries.map(async (entry: Dirent) => {
const fullPath = join(entry.path, entry.name)
return await dynamicImport(fullPath)
})
)
})
})
await promiseAll(promises)
logger.debug(`Workflows registered.`) logger.debug(`Workflows registered.`)
} }
+7
View File
@@ -1,5 +1,12 @@
# @medusajs/js-sdk # @medusajs/js-sdk
## 2.6.0
### Patch Changes
- Updated dependencies [[`8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125`](https://github.com/medusajs/medusa/commit/8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125), [`698a520729a3045cd13eed5ee0e5120a563e9261`](https://github.com/medusajs/medusa/commit/698a520729a3045cd13eed5ee0e5120a563e9261), [`51b0af193c7dde4899a696a515b59373b465d907`](https://github.com/medusajs/medusa/commit/51b0af193c7dde4899a696a515b59373b465d907), [`93cbc6b6695f236fa39b66169de971228888f1b9`](https://github.com/medusajs/medusa/commit/93cbc6b6695f236fa39b66169de971228888f1b9), [`d1efad9bf05ca80959e8b50d74b74167fc1b0064`](https://github.com/medusajs/medusa/commit/d1efad9bf05ca80959e8b50d74b74167fc1b0064), [`d814d9540e76256be23d733b73cf5a63aa380c8b`](https://github.com/medusajs/medusa/commit/d814d9540e76256be23d733b73cf5a63aa380c8b), [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76)]:
- @medusajs/types@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/js-sdk", "name": "@medusajs/js-sdk",
"version": "2.5.1", "version": "2.6.0",
"description": "SDK for the Medusa API", "description": "SDK for the Medusa API",
"main": "dist/index.js", "main": "dist/index.js",
"module": "dist/esm/index.js", "module": "dist/esm/index.js",
@@ -35,7 +35,7 @@
"typescript": "^5.6.2" "typescript": "^5.6.2"
}, },
"dependencies": { "dependencies": {
"@medusajs/types": "^2.5.1", "@medusajs/types": "^2.6.0",
"fetch-event-stream": "^0.1.5", "fetch-event-stream": "^0.1.5",
"qs": "^6.12.1" "qs": "^6.12.1"
}, },
+9
View File
@@ -1,5 +1,14 @@
# @medusajs/modules-sdk # @medusajs/modules-sdk
## 2.6.0
### Patch Changes
- Updated dependencies [[`8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125`](https://github.com/medusajs/medusa/commit/8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125), [`698a520729a3045cd13eed5ee0e5120a563e9261`](https://github.com/medusajs/medusa/commit/698a520729a3045cd13eed5ee0e5120a563e9261), [`51b0af193c7dde4899a696a515b59373b465d907`](https://github.com/medusajs/medusa/commit/51b0af193c7dde4899a696a515b59373b465d907), [`eeebb35758ea443468dd2355a7ea761dfe24babc`](https://github.com/medusajs/medusa/commit/eeebb35758ea443468dd2355a7ea761dfe24babc), [`93cbc6b6695f236fa39b66169de971228888f1b9`](https://github.com/medusajs/medusa/commit/93cbc6b6695f236fa39b66169de971228888f1b9), [`d1efad9bf05ca80959e8b50d74b74167fc1b0064`](https://github.com/medusajs/medusa/commit/d1efad9bf05ca80959e8b50d74b74167fc1b0064), [`ca6a15717d05de112ca00ca56d65beb2ab0f2598`](https://github.com/medusajs/medusa/commit/ca6a15717d05de112ca00ca56d65beb2ab0f2598), [`d814d9540e76256be23d733b73cf5a63aa380c8b`](https://github.com/medusajs/medusa/commit/d814d9540e76256be23d733b73cf5a63aa380c8b), [`d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30`](https://github.com/medusajs/medusa/commit/d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30), [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76), [`ab96ad3b8213b117b067ae0ab66b94f74b8bd031`](https://github.com/medusajs/medusa/commit/ab96ad3b8213b117b067ae0ab66b94f74b8bd031)]:
- @medusajs/types@2.6.0
- @medusajs/utils@2.6.0
- @medusajs/orchestration@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/modules-sdk", "name": "@medusajs/modules-sdk",
"version": "2.5.1", "version": "2.6.0",
"description": "SDK for medusa modules", "description": "SDK for medusa modules",
"main": "dist/index.js", "main": "dist/index.js",
"export": { "export": {
@@ -45,9 +45,9 @@
"typescript": "^5.6.2" "typescript": "^5.6.2"
}, },
"dependencies": { "dependencies": {
"@medusajs/orchestration": "^2.5.1", "@medusajs/orchestration": "^2.6.0",
"@medusajs/types": "^2.5.1", "@medusajs/types": "^2.6.0",
"@medusajs/utils": "^2.5.1" "@medusajs/utils": "^2.6.0"
}, },
"peerDependencies": { "peerDependencies": {
"@mikro-orm/core": "6.4.3", "@mikro-orm/core": "6.4.3",
+8
View File
@@ -1,5 +1,13 @@
# @medusajs/orchestration # @medusajs/orchestration
## 2.6.0
### Patch Changes
- Updated dependencies [[`8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125`](https://github.com/medusajs/medusa/commit/8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125), [`698a520729a3045cd13eed5ee0e5120a563e9261`](https://github.com/medusajs/medusa/commit/698a520729a3045cd13eed5ee0e5120a563e9261), [`51b0af193c7dde4899a696a515b59373b465d907`](https://github.com/medusajs/medusa/commit/51b0af193c7dde4899a696a515b59373b465d907), [`eeebb35758ea443468dd2355a7ea761dfe24babc`](https://github.com/medusajs/medusa/commit/eeebb35758ea443468dd2355a7ea761dfe24babc), [`93cbc6b6695f236fa39b66169de971228888f1b9`](https://github.com/medusajs/medusa/commit/93cbc6b6695f236fa39b66169de971228888f1b9), [`d1efad9bf05ca80959e8b50d74b74167fc1b0064`](https://github.com/medusajs/medusa/commit/d1efad9bf05ca80959e8b50d74b74167fc1b0064), [`ca6a15717d05de112ca00ca56d65beb2ab0f2598`](https://github.com/medusajs/medusa/commit/ca6a15717d05de112ca00ca56d65beb2ab0f2598), [`d814d9540e76256be23d733b73cf5a63aa380c8b`](https://github.com/medusajs/medusa/commit/d814d9540e76256be23d733b73cf5a63aa380c8b), [`d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30`](https://github.com/medusajs/medusa/commit/d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30), [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76), [`ab96ad3b8213b117b067ae0ab66b94f74b8bd031`](https://github.com/medusajs/medusa/commit/ab96ad3b8213b117b067ae0ab66b94f74b8bd031)]:
- @medusajs/types@2.6.0
- @medusajs/utils@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/orchestration", "name": "@medusajs/orchestration",
"version": "2.5.1", "version": "2.6.0",
"description": "Medusa utilities to orchestrate modules", "description": "Medusa utilities to orchestrate modules",
"main": "dist/index.js", "main": "dist/index.js",
"exports": { "exports": {
@@ -39,8 +39,8 @@
"typescript": "^5.6.2" "typescript": "^5.6.2"
}, },
"dependencies": { "dependencies": {
"@medusajs/types": "^2.5.1", "@medusajs/types": "^2.6.0",
"@medusajs/utils": "^2.5.1" "@medusajs/utils": "^2.6.0"
}, },
"peerDependencies": { "peerDependencies": {
"@mikro-orm/core": "6.4.3", "@mikro-orm/core": "6.4.3",
+18
View File
@@ -1,5 +1,23 @@
# @medusajs/types # @medusajs/types
## 2.6.0
### Patch Changes
- [#11604](https://github.com/medusajs/medusa/pull/11604) [`8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125`](https://github.com/medusajs/medusa/commit/8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125) Thanks [@shahednasser](https://github.com/shahednasser)! - fix(types, medusa): remove fulfillment and payment status filters from validator + http types
- [#11597](https://github.com/medusajs/medusa/pull/11597) [`698a520729a3045cd13eed5ee0e5120a563e9261`](https://github.com/medusajs/medusa/commit/698a520729a3045cd13eed5ee0e5120a563e9261) Thanks [@shahednasser](https://github.com/shahednasser)! - chore(types): change payment provider types to interfaces
- [#11692](https://github.com/medusajs/medusa/pull/11692) [`51b0af193c7dde4899a696a515b59373b465d907`](https://github.com/medusajs/medusa/commit/51b0af193c7dde4899a696a515b59373b465d907) Thanks [@riqwan](https://github.com/riqwan)! - fix(types,medusa): calculate taxes for original price
- [#11226](https://github.com/medusajs/medusa/pull/11226) [`93cbc6b6695f236fa39b66169de971228888f1b9`](https://github.com/medusajs/medusa/commit/93cbc6b6695f236fa39b66169de971228888f1b9) Thanks [@bouazzaayyoub](https://github.com/bouazzaayyoub)! - fix: add additionl data to product categories hook
- [#11666](https://github.com/medusajs/medusa/pull/11666) [`d1efad9bf05ca80959e8b50d74b74167fc1b0064`](https://github.com/medusajs/medusa/commit/d1efad9bf05ca80959e8b50d74b74167fc1b0064) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(): Improve cart update line items
- [#11581](https://github.com/medusajs/medusa/pull/11581) [`d814d9540e76256be23d733b73cf5a63aa380c8b`](https://github.com/medusajs/medusa/commit/d814d9540e76256be23d733b73cf5a63aa380c8b) Thanks [@kasperkristensen](https://github.com/kasperkristensen)! - fix(types): Allow providing either vite@5 or vite@6 for the peer dependency
- [#11601](https://github.com/medusajs/medusa/pull/11601) [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(): Improve internal repository delete algo
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/types", "name": "@medusajs/types",
"version": "2.5.1", "version": "2.6.0",
"description": "Medusa Types definition", "description": "Medusa Types definition",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
+17
View File
@@ -1,5 +1,22 @@
# @medusajs/utils # @medusajs/utils
## 2.6.0
### Patch Changes
- [#11585](https://github.com/medusajs/medusa/pull/11585) [`eeebb35758ea443468dd2355a7ea761dfe24babc`](https://github.com/medusajs/medusa/commit/eeebb35758ea443468dd2355a7ea761dfe24babc) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(product): Remove upsertWithReplace where needed
- [#11636](https://github.com/medusajs/medusa/pull/11636) [`ca6a15717d05de112ca00ca56d65beb2ab0f2598`](https://github.com/medusajs/medusa/commit/ca6a15717d05de112ca00ca56d65beb2ab0f2598) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(): Add support for extra pool configuration
- [#11618](https://github.com/medusajs/medusa/pull/11618) [`d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30`](https://github.com/medusajs/medusa/commit/d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(): Improve cascade soft deletetion and update
- [#11601](https://github.com/medusajs/medusa/pull/11601) [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(): Improve internal repository delete algo
- [#11693](https://github.com/medusajs/medusa/pull/11693) [`ab96ad3b8213b117b067ae0ab66b94f74b8bd031`](https://github.com/medusajs/medusa/commit/ab96ad3b8213b117b067ae0ab66b94f74b8bd031) Thanks [@riqwan](https://github.com/riqwan)! - feat(utils): add error message when manager is not found
- Updated dependencies [[`8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125`](https://github.com/medusajs/medusa/commit/8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125), [`698a520729a3045cd13eed5ee0e5120a563e9261`](https://github.com/medusajs/medusa/commit/698a520729a3045cd13eed5ee0e5120a563e9261), [`51b0af193c7dde4899a696a515b59373b465d907`](https://github.com/medusajs/medusa/commit/51b0af193c7dde4899a696a515b59373b465d907), [`93cbc6b6695f236fa39b66169de971228888f1b9`](https://github.com/medusajs/medusa/commit/93cbc6b6695f236fa39b66169de971228888f1b9), [`d1efad9bf05ca80959e8b50d74b74167fc1b0064`](https://github.com/medusajs/medusa/commit/d1efad9bf05ca80959e8b50d74b74167fc1b0064), [`d814d9540e76256be23d733b73cf5a63aa380c8b`](https://github.com/medusajs/medusa/commit/d814d9540e76256be23d733b73cf5a63aa380c8b), [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76)]:
- @medusajs/types@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/utils", "name": "@medusajs/utils",
"version": "2.5.1", "version": "2.6.0",
"description": "Medusa utilities functions shared by Medusa core and Modules", "description": "Medusa utilities functions shared by Medusa core and Modules",
"main": "dist/index.js", "main": "dist/index.js",
"exports": { "exports": {
@@ -47,7 +47,7 @@
"@graphql-codegen/typescript": "^4.0.9", "@graphql-codegen/typescript": "^4.0.9",
"@graphql-tools/merge": "^9.0.7", "@graphql-tools/merge": "^9.0.7",
"@graphql-tools/schema": "^10.0.6", "@graphql-tools/schema": "^10.0.6",
"@medusajs/types": "^2.5.1", "@medusajs/types": "^2.6.0",
"@types/pluralize": "^0.0.33", "@types/pluralize": "^0.0.33",
"bignumber.js": "^9.1.2", "bignumber.js": "^9.1.2",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
+12
View File
@@ -1,5 +1,17 @@
# @medusajs/workflows-sdk # @medusajs/workflows-sdk
## 2.6.0
### Patch Changes
- [#11641](https://github.com/medusajs/medusa/pull/11641) [`c250de79192bda1b1cd217bcca37f458c693de1d`](https://github.com/medusajs/medusa/commit/c250de79192bda1b1cd217bcca37f458c693de1d) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(): Prevent sub workflow events release early + redis unlink
- Updated dependencies [[`8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125`](https://github.com/medusajs/medusa/commit/8bb0a25f573c62ca1d1bcd7af184b0d0cf98e125), [`698a520729a3045cd13eed5ee0e5120a563e9261`](https://github.com/medusajs/medusa/commit/698a520729a3045cd13eed5ee0e5120a563e9261), [`51b0af193c7dde4899a696a515b59373b465d907`](https://github.com/medusajs/medusa/commit/51b0af193c7dde4899a696a515b59373b465d907), [`eeebb35758ea443468dd2355a7ea761dfe24babc`](https://github.com/medusajs/medusa/commit/eeebb35758ea443468dd2355a7ea761dfe24babc), [`93cbc6b6695f236fa39b66169de971228888f1b9`](https://github.com/medusajs/medusa/commit/93cbc6b6695f236fa39b66169de971228888f1b9), [`d1efad9bf05ca80959e8b50d74b74167fc1b0064`](https://github.com/medusajs/medusa/commit/d1efad9bf05ca80959e8b50d74b74167fc1b0064), [`ca6a15717d05de112ca00ca56d65beb2ab0f2598`](https://github.com/medusajs/medusa/commit/ca6a15717d05de112ca00ca56d65beb2ab0f2598), [`d814d9540e76256be23d733b73cf5a63aa380c8b`](https://github.com/medusajs/medusa/commit/d814d9540e76256be23d733b73cf5a63aa380c8b), [`d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30`](https://github.com/medusajs/medusa/commit/d254b2ddba3fba4fb60e1076a6bc4e7d425bbd30), [`b42f151be31161a5d7a73132ee6794b990403d76`](https://github.com/medusajs/medusa/commit/b42f151be31161a5d7a73132ee6794b990403d76), [`ab96ad3b8213b117b067ae0ab66b94f74b8bd031`](https://github.com/medusajs/medusa/commit/ab96ad3b8213b117b067ae0ab66b94f74b8bd031)]:
- @medusajs/types@2.6.0
- @medusajs/utils@2.6.0
- @medusajs/modules-sdk@2.6.0
- @medusajs/orchestration@2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/workflows-sdk", "name": "@medusajs/workflows-sdk",
"version": "2.5.1", "version": "2.6.0",
"description": "Set of workflows tooling for Medusa", "description": "Set of workflows tooling for Medusa",
"main": "dist/index.js", "main": "dist/index.js",
"exports": { "exports": {
@@ -40,10 +40,10 @@
"typescript": "^5.6.2" "typescript": "^5.6.2"
}, },
"dependencies": { "dependencies": {
"@medusajs/modules-sdk": "^2.5.1", "@medusajs/modules-sdk": "^2.6.0",
"@medusajs/orchestration": "^2.5.1", "@medusajs/orchestration": "^2.6.0",
"@medusajs/types": "^2.5.1", "@medusajs/types": "^2.6.0",
"@medusajs/utils": "^2.5.1", "@medusajs/utils": "^2.6.0",
"ulid": "^2.3.0" "ulid": "^2.3.0"
}, },
"peerDependencies": { "peerDependencies": {
@@ -1,5 +1,7 @@
# @medusajs/icons # @medusajs/icons
## 2.6.0
## 2.5.1 ## 2.5.1
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/icons", "name": "@medusajs/icons",
"version": "2.5.1", "version": "2.6.0",
"description": "Medusa UI React icon library", "description": "Medusa UI React icon library",
"author": "Kasper Kristensen <kasper@medusajs.com>", "author": "Kasper Kristensen <kasper@medusajs.com>",
"license": "MIT", "license": "MIT",
@@ -29,7 +29,7 @@
}, },
"devDependencies": { "devDependencies": {
"@atomico/rollup-plugin-sizes": "^1.1.4", "@atomico/rollup-plugin-sizes": "^1.1.4",
"@medusajs/toolbox": "^2.5.1", "@medusajs/toolbox": "^2.6.0",
"@rollup/plugin-node-resolve": "^15.1.0", "@rollup/plugin-node-resolve": "^15.1.0",
"@rollup/plugin-replace": "^5.0.2", "@rollup/plugin-replace": "^5.0.2",
"@testing-library/dom": "^9.3.1", "@testing-library/dom": "^9.3.1",
@@ -1,5 +1,7 @@
# @medusajs/toolbox # @medusajs/toolbox
## 2.6.0
## 2.5.1 ## 2.5.1
## 2.5.0 ## 2.5.0
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@medusajs/toolbox", "name": "@medusajs/toolbox",
"private": true, "private": true,
"version": "2.5.1", "version": "2.6.0",
"description": "CLI tool for importing Figma designs for Medusa UI", "description": "CLI tool for importing Figma designs for Medusa UI",
"license": "MIT", "license": "MIT",
"author": "Kasper Kristensen <kasper@medusajs.com>", "author": "Kasper Kristensen <kasper@medusajs.com>",
@@ -1,5 +1,7 @@
# @medusajs/ui-preset # @medusajs/ui-preset
## 2.6.0
## 2.5.1 ## 2.5.1
## 2.5.0 ## 2.5.0
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/ui-preset", "name": "@medusajs/ui-preset",
"version": "2.5.1", "version": "2.6.0",
"description": "Medusa UI preset", "description": "Medusa UI preset",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
@@ -30,7 +30,7 @@
"tailwindcss": ">=3.0.0" "tailwindcss": ">=3.0.0"
}, },
"devDependencies": { "devDependencies": {
"@medusajs/toolbox": "^2.5.1", "@medusajs/toolbox": "^2.6.0",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",
"tsup": "^7.1.0", "tsup": "^7.1.0",
"typescript": "^5.1.6" "typescript": "^5.1.6"
Loaded 100 of 877 files, more files were not shown because too many files have changed in this diff. Show more