chore(): start moving some packages to the core directory (#7215)
This commit is contained in:
1 parent
fdee748eed
commit
bbccd6481d
1436 files changed
+275
-756
No files matched your search
@@ -0,0 +1,188 @@
|
||||
# @medusajs/core-flows
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#7077](https://github.com/medusajs/medusa/pull/7077) [`8d356217bd`](https://github.com/medusajs/medusa/commit/8d356217bd31c97a196e861ee243822a4d924df7) Thanks [@riqwan](https://github.com/riqwan)! - feat(medusa,core-flows,types): add batch updates to price list prices
|
||||
|
||||
- [#6864](https://github.com/medusajs/medusa/pull/6864) [`e944a627f0`](https://github.com/medusajs/medusa/commit/e944a627f074fb39a56f4bc7b3d6d315736ebf7c) Thanks [@adrien2p](https://github.com/adrien2p)! - feat: region payment providers management workflows/api
|
||||
|
||||
- [#6880](https://github.com/medusajs/medusa/pull/6880) [`1a48fe0282`](https://github.com/medusajs/medusa/commit/1a48fe0282a8bc1f8548a4736255e457d173da09) Thanks [@sradevski](https://github.com/sradevski)! - Add v2 product type endpoints and adjust the product module
|
||||
|
||||
- [#6872](https://github.com/medusajs/medusa/pull/6872) [`86f499de2f`](https://github.com/medusajs/medusa/commit/86f499de2f31356ab36ad5e93f27345443b3e5f6) Thanks [@sradevski](https://github.com/sradevski)! - Aligned pricing module price set API with convention
|
||||
|
||||
- [#6876](https://github.com/medusajs/medusa/pull/6876) [`1bcb13f892`](https://github.com/medusajs/medusa/commit/1bcb13f892bc61db21b3fc6bdbce85f747aeec4c) Thanks [@olivermrbl](https://github.com/olivermrbl)! - feat: Remove sales channels from pub keys
|
||||
|
||||
- [#7095](https://github.com/medusajs/medusa/pull/7095) [`62b9dcc6c1`](https://github.com/medusajs/medusa/commit/62b9dcc6c1ce46aadb7944215006c12da3c9f619) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,types): cancel fulfillments API
|
||||
|
||||
- [#6851](https://github.com/medusajs/medusa/pull/6851) [`ea8d9d4d42`](https://github.com/medusajs/medusa/commit/ea8d9d4d42210a5598b308656922c0e93c90b7c8) Thanks [@olivermrbl](https://github.com/olivermrbl)! - feat: API key sales channel link
|
||||
|
||||
- [#7175](https://github.com/medusajs/medusa/pull/7175) [`e26cda4b6a`](https://github.com/medusajs/medusa/commit/e26cda4b6afb7fb25f0b0a7a7ce20b7f914d35db) Thanks [@adrien2p](https://github.com/adrien2p)! - feat(medusa, core-flows, types): Allow to update the rules from a shipping options
|
||||
|
||||
- [#7101](https://github.com/medusajs/medusa/pull/7101) [`18f3aacee6`](https://github.com/medusajs/medusa/commit/18f3aacee6752854d377faa806f4cc67bc71456b) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,types): add create shipment api for fulfillments
|
||||
|
||||
- [#6962](https://github.com/medusajs/medusa/pull/6962) [`65794f4bb5`](https://github.com/medusajs/medusa/commit/65794f4bb56e4fd3f0ccb7656a948f856f05324e) Thanks [@adrien2p](https://github.com/adrien2p)! - feat: Create shipping options API
|
||||
|
||||
- [#6905](https://github.com/medusajs/medusa/pull/6905) [`edafe7db47`](https://github.com/medusajs/medusa/commit/edafe7db4780631601d07e43b18f80c3406166f0) Thanks [@pKorsholm](https://github.com/pKorsholm)! - feat(link-modules, core-flows, medusa): add sales channel location management endpoint
|
||||
|
||||
- [#6800](https://github.com/medusajs/medusa/pull/6800) [`4cf71af07d`](https://github.com/medusajs/medusa/commit/4cf71af07d1807c83df3889c1774f82cbd1b9a6f) Thanks [@pKorsholm](https://github.com/pKorsholm)! - feat(core-flows, medusa): add update stock location endpoint to api-v2
|
||||
|
||||
- [#7153](https://github.com/medusajs/medusa/pull/7153) [`4b57c5d286`](https://github.com/medusajs/medusa/commit/4b57c5d286f9dc6e2098c67e9fecb0d93175b5a1) Thanks [@carlos-r-l-rodrigues](https://github.com/carlos-r-l-rodrigues)! - Remote query supporting context
|
||||
|
||||
- [#7028](https://github.com/medusajs/medusa/pull/7028) [`c78915c7c5`](https://github.com/medusajs/medusa/commit/c78915c7c5e91a99c1b1bae932656c8d86b17daf) Thanks [@adrien2p](https://github.com/adrien2p)! - feat(): Add support for shipping options prices update
|
||||
|
||||
- [#7101](https://github.com/medusajs/medusa/pull/7101) [`18f3aacee6`](https://github.com/medusajs/medusa/commit/18f3aacee6752854d377faa806f4cc67bc71456b) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,types): fulfillment API: create
|
||||
|
||||
- [#7150](https://github.com/medusajs/medusa/pull/7150) [`d2393f004e`](https://github.com/medusajs/medusa/commit/d2393f004e0d02450300ad34dbbf98e859dae844) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows, medusa): add shipping methods to cart API
|
||||
|
||||
- [#7018](https://github.com/medusajs/medusa/pull/7018) [`f175cac4af`](https://github.com/medusajs/medusa/commit/f175cac4af63b71066a8398ecf9beaa6f28b20cc) Thanks [@pKorsholm](https://github.com/pKorsholm)! - feat(core-flows, medusa, types): add reservation item endpoints
|
||||
|
||||
- [#6995](https://github.com/medusajs/medusa/pull/6995) [`0a9b9b073d`](https://github.com/medusajs/medusa/commit/0a9b9b073dd2d3f4aa5e5cb1c16e2221a7200e0d) Thanks [@fPolic](https://github.com/fPolic)! - feat(medusa, core-flows,types): delete fulfillment set, delete shipping profile
|
||||
|
||||
- Updated dependencies [[`e603726985`](https://github.com/medusajs/medusa/commit/e60372698565315145037eb40fbe86c43f91cc16), [`d333db0842`](https://github.com/medusajs/medusa/commit/d333db08429611c0571a0b173adf37103b8a8aa6), [`1eeb1e9de3`](https://github.com/medusajs/medusa/commit/1eeb1e9de3e0b571735437b00968ee96e4aabad5), [`20e8df914e`](https://github.com/medusajs/medusa/commit/20e8df914ec5fdf8d562d4fa84f72c58c7056195), [`a164c0d512`](https://github.com/medusajs/medusa/commit/a164c0d5126a40e2bc669f9fc2883be502a15036), [`e0b02a1012`](https://github.com/medusajs/medusa/commit/e0b02a1012981c29830d7779f59ebe805bbfd137), [`e944a627f0`](https://github.com/medusajs/medusa/commit/e944a627f074fb39a56f4bc7b3d6d315736ebf7c), [`cc557c8752`](https://github.com/medusajs/medusa/commit/cc557c8752fd0554f5a1b58522d9a88dc43a8509), [`dd35a4dbff`](https://github.com/medusajs/medusa/commit/dd35a4dbff10c86ea3c5f7f817c18b6e60d599e3), [`1bcb13f892`](https://github.com/medusajs/medusa/commit/1bcb13f892bc61db21b3fc6bdbce85f747aeec4c), [`82a176e30e`](https://github.com/medusajs/medusa/commit/82a176e30e47a7d11caaf31c3023bd8db588b465), [`5d9aea053c`](https://github.com/medusajs/medusa/commit/5d9aea053ce6e04f242f86fb9053c13dec515d5b), [`232322d035`](https://github.com/medusajs/medusa/commit/232322d03515f81e56867ff8c765b8409399ee68), [`45c49e89f2`](https://github.com/medusajs/medusa/commit/45c49e89f28123ef622fc1c07253bae94fd74875), [`71aeda7347`](https://github.com/medusajs/medusa/commit/71aeda7347a1dc7039be05071ce90a6dca5f9154), [`528ef4ca90`](https://github.com/medusajs/medusa/commit/528ef4ca90bb2cf6173dccc9fd6a9f9932ff9b76), [`65794f4bb5`](https://github.com/medusajs/medusa/commit/65794f4bb56e4fd3f0ccb7656a948f856f05324e), [`4b57c5d286`](https://github.com/medusajs/medusa/commit/4b57c5d286f9dc6e2098c67e9fecb0d93175b5a1), [`3affcc2525`](https://github.com/medusajs/medusa/commit/3affcc252599c93cf52fef24ec4f3695d65db79a), [`667c8609cc`](https://github.com/medusajs/medusa/commit/667c8609ccf3850f5df8cf784723a95bd0d6d2a6), [`edcafa140c`](https://github.com/medusajs/medusa/commit/edcafa140c1869df3c420c2becfbf23b6af75ddc), [`a6562d2a41`](https://github.com/medusajs/medusa/commit/a6562d2a41453cbe7aa43be352c4924e3e4c79d5), [`8fd1488938`](https://github.com/medusajs/medusa/commit/8fd148893850eb66c5eae00c4ca9391a80ea2eb9), [`1c6ba4468e`](https://github.com/medusajs/medusa/commit/1c6ba4468eab1440931c88929affd5b4c593f377)]:
|
||||
- @medusajs/workflows-sdk@0.1.6
|
||||
- @medusajs/orchestration@0.5.7
|
||||
- @medusajs/modules-sdk@1.12.11
|
||||
- @medusajs/utils@1.11.9
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#6759](https://github.com/medusajs/medusa/pull/6759) [`70859397c0`](https://github.com/medusajs/medusa/commit/70859397c00ad0b45a517547e2792ed4f6882d73) Thanks [@sradevski](https://github.com/sradevski)! - Align the v2 product HTTP endpoints to follow conventions
|
||||
|
||||
- [#6801](https://github.com/medusajs/medusa/pull/6801) [`deab12e27e`](https://github.com/medusajs/medusa/commit/deab12e27e8249e26d24d7bc904c18195679ff24) Thanks [@pKorsholm](https://github.com/pKorsholm)! - feat(types, medusa, core-flows): add delete-stock-location endpoint to api-v2
|
||||
|
||||
- [#6778](https://github.com/medusajs/medusa/pull/6778) [`7e93eda1a4`](https://github.com/medusajs/medusa/commit/7e93eda1a44310311d2f3f8a1d634f60e7c48cb5) Thanks [@carlos-r-l-rodrigues](https://github.com/carlos-r-l-rodrigues)! - Feat: workflow cancel
|
||||
|
||||
- [#6796](https://github.com/medusajs/medusa/pull/6796) [`9073d7aba3`](https://github.com/medusajs/medusa/commit/9073d7aba3419e4dc0a206473291a46ebd79b8c1) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,types,utils): rename psma to prices
|
||||
|
||||
- [#6819](https://github.com/medusajs/medusa/pull/6819) [`7bc7adeeb4`](https://github.com/medusajs/medusa/commit/7bc7adeeb4568ad85a81df08e3d6d3b5023cee13) Thanks [@olivermrbl](https://github.com/olivermrbl)! - feat: Create user account
|
||||
|
||||
- [#6787](https://github.com/medusajs/medusa/pull/6787) [`68b9812aa1`](https://github.com/medusajs/medusa/commit/68b9812aa1fe8a9e368112e721cd868919369980) Thanks [@pKorsholm](https://github.com/pKorsholm)! - feat(core-flows, medusa): add create stock location endpoint for api-v2
|
||||
|
||||
- [#6748](https://github.com/medusajs/medusa/pull/6748) [`05e857d256`](https://github.com/medusajs/medusa/commit/05e857d25657b5576a891c9b48c19c1759c70701) Thanks [@sradevski](https://github.com/sradevski)! - Updated the signature of the product module variant and options endpoints to follow our conventions
|
||||
|
||||
- [#6791](https://github.com/medusajs/medusa/pull/6791) [`20132d7cea`](https://github.com/medusajs/medusa/commit/20132d7cea13b7c7ae77b33684d01a9ab40f7ed3) Thanks [@pKorsholm](https://github.com/pKorsholm)! - feat(medusa, core-flows): add retrieve stock location endpoint to api-v2
|
||||
|
||||
- Updated dependencies [[`06f22bb48a`](https://github.com/medusajs/medusa/commit/06f22bb48ad1fe73577657b8c5db055312f16a0d), [`7e93eda1a4`](https://github.com/medusajs/medusa/commit/7e93eda1a44310311d2f3f8a1d634f60e7c48cb5), [`56481e683d`](https://github.com/medusajs/medusa/commit/56481e683d33ff98f0d4c4e144873bb23f993c9c), [`9073d7aba3`](https://github.com/medusajs/medusa/commit/9073d7aba3419e4dc0a206473291a46ebd79b8c1), [`4974f5e455`](https://github.com/medusajs/medusa/commit/4974f5e4557bd64a328a881ec02b91e15485bd23), [`3ca957ec0f`](https://github.com/medusajs/medusa/commit/3ca957ec0fdcdc966a3d2ca94b8222d68767cf9a), [`1ef9c78cea`](https://github.com/medusajs/medusa/commit/1ef9c78cea080c3b7c136f909c6cddec9d8f0c62)]:
|
||||
- @medusajs/modules-sdk@1.12.10
|
||||
- @medusajs/orchestration@0.5.6
|
||||
- @medusajs/workflows-sdk@0.1.5
|
||||
- @medusajs/utils@1.11.8
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#6648](https://github.com/medusajs/medusa/pull/6648) [`9288f53327`](https://github.com/medusajs/medusa/commit/9288f53327b8ce617af92ed8d14d9459cbfeb13c) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,utils): added price list prices upsert and delete workflows + endpoints
|
||||
|
||||
- [#6539](https://github.com/medusajs/medusa/pull/6539) [`557d86afbf`](https://github.com/medusajs/medusa/commit/557d86afbfef707d2998e4e5d1ce3559ec22f9f8) Thanks [@riqwan](https://github.com/riqwan)! - feat(medusa,core-flows): update cart adjustments on item updates
|
||||
|
||||
- [#6474](https://github.com/medusajs/medusa/pull/6474) [`ac86362e81`](https://github.com/medusajs/medusa/commit/ac86362e81d8523cb8e3dfad026fc94658513018) Thanks [@riqwan](https://github.com/riqwan)! - feat(workflows-sdk,core-flows,medusa,types): add workflow to add promotions to cart
|
||||
|
||||
- [#6580](https://github.com/medusajs/medusa/pull/6580) [`e4acde1aa2`](https://github.com/medusajs/medusa/commit/e4acde1aa2eb57f07e6692fe8b61f728948b9a96) Thanks [@riqwan](https://github.com/riqwan)! - feat(medusa,core-flows,types): add cart <> tax integration workflows + steps
|
||||
|
||||
- [#6696](https://github.com/medusajs/medusa/pull/6696) [`04a532e5ef`](https://github.com/medusajs/medusa/commit/04a532e5efabbf75b1e4155520b1da175b686ffc) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,types): remove rules from promotion endpoints + workflows
|
||||
|
||||
- [#6418](https://github.com/medusajs/medusa/pull/6418) [`1ba35b02dd`](https://github.com/medusajs/medusa/commit/1ba35b02dd52eeca9f3e1bee073c5e7a17edbc33) Thanks [@olivermrbl](https://github.com/olivermrbl)! - feat: Cart SalesChannel link
|
||||
|
||||
- [#6692](https://github.com/medusajs/medusa/pull/6692) [`640eccd5dd`](https://github.com/medusajs/medusa/commit/640eccd5ddbb163e0f987ce6c772f1129c2e2632) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,types,utils): add rules to promotion endpoints + workflow
|
||||
|
||||
- [#6667](https://github.com/medusajs/medusa/pull/6667) [`c3c4f49fc2`](https://github.com/medusajs/medusa/commit/c3c4f49fc2126f950e69e291ca939ca88a15afd3) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,types): add automatic-taxes to region + generate tax lines endpoint
|
||||
|
||||
- [#6648](https://github.com/medusajs/medusa/pull/6648) [`9288f53327`](https://github.com/medusajs/medusa/commit/9288f53327b8ce617af92ed8d14d9459cbfeb13c) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,pricing,types,utils): added price list workflows + endpoints
|
||||
|
||||
- [#6684](https://github.com/medusajs/medusa/pull/6684) [`b78f863d80`](https://github.com/medusajs/medusa/commit/b78f863d80cad0e7075585cd400dc47ac05f4bf1) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa): added api + workflows for rule types CRUD
|
||||
|
||||
- [#6711](https://github.com/medusajs/medusa/pull/6711) [`0c705d7bd4`](https://github.com/medusajs/medusa/commit/0c705d7bd41a768c48017ae95b3c8414d96c6acb) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,types): split upsert workflow to create and update
|
||||
|
||||
- [#6727](https://github.com/medusajs/medusa/pull/6727) [`c20eb15cd9`](https://github.com/medusajs/medusa/commit/c20eb15cd9b1bd90c8d01f68eca6f0f181cd902d) Thanks [@pKorsholm](https://github.com/pKorsholm)! - feat(medusa, core-flows, types): Add delete-location-level api-v2 endpoints
|
||||
|
||||
- [#6702](https://github.com/medusajs/medusa/pull/6702) [`e5945479e0`](https://github.com/medusajs/medusa/commit/e5945479e091d9560ae3e7240306a31031ef4584) Thanks [@riqwan](https://github.com/riqwan)! - feat(medusa,core-flows,types): adds update promotion rule endpoint + workflow
|
||||
|
||||
- [#6514](https://github.com/medusajs/medusa/pull/6514) [`f5c2256286`](https://github.com/medusajs/medusa/commit/f5c22562867f412040f8bc6c55ab5de3a3735e62) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,types,utils): adds update cart API with promotions
|
||||
|
||||
- [#6561](https://github.com/medusajs/medusa/pull/6561) [`d550be3685`](https://github.com/medusajs/medusa/commit/d550be3685423218d47a20c57a5e06758f4a961a) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,link-modules,modules-sdk): add cart <> promotion link as source of truth
|
||||
|
||||
- [#6708](https://github.com/medusajs/medusa/pull/6708) [`62d5803b20`](https://github.com/medusajs/medusa/commit/62d5803b2085daa682ea9bfbe7a3593057c7da4e) Thanks [@pKorsholm](https://github.com/pKorsholm)! - feat(medusa, core-flows, inventory-next): add delete-inventory-item endpoint
|
||||
|
||||
- [#6327](https://github.com/medusajs/medusa/pull/6327) [`4d51f095b3`](https://github.com/medusajs/medusa/commit/4d51f095b3f98f468cefb760512563f7b77bb9cf) Thanks [@pKorsholm](https://github.com/pKorsholm)! - feat(core-flows, types, utils, medusa): add user endpoints to api-v2
|
||||
|
||||
- [#6698](https://github.com/medusajs/medusa/pull/6698) [`cc1b66842c`](https://github.com/medusajs/medusa/commit/cc1b66842cbb37c6eab84e2d8b74844c214f38d7) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,types,utils): add/remove fulfillment shipping option rules
|
||||
|
||||
- [#6392](https://github.com/medusajs/medusa/pull/6392) [`24fb102a56`](https://github.com/medusajs/medusa/commit/24fb102a564b1253d1f8b039bb1e435cc5312fbb) Thanks [@olivermrbl](https://github.com/olivermrbl)! - feat: CartRegion link, definition + workflow
|
||||
|
||||
- Updated dependencies [[`9288f53327`](https://github.com/medusajs/medusa/commit/9288f53327b8ce617af92ed8d14d9459cbfeb13c), [`ac86362e81`](https://github.com/medusajs/medusa/commit/ac86362e81d8523cb8e3dfad026fc94658513018), [`56cbf88115`](https://github.com/medusajs/medusa/commit/56cbf88115994adea7037c3f2814f0c96af3cfc0), [`36a61658f9`](https://github.com/medusajs/medusa/commit/36a61658f969a7b19c84a1e621ad1464927cafb1), [`0c2a460751`](https://github.com/medusajs/medusa/commit/0c2a460751644021056d0f99d9b1fffe509fb7ab), [`25d176b851`](https://github.com/medusajs/medusa/commit/25d176b851c041ecc7901163b704b36b7e585076), [`c319edb8e0`](https://github.com/medusajs/medusa/commit/c319edb8e0ecd13d086652147667916e5abab2d8), [`0b9fcb6324`](https://github.com/medusajs/medusa/commit/0b9fcb6324eee9f2556c7e6317775fae93b12a47), [`586df9da25`](https://github.com/medusajs/medusa/commit/586df9da250e492442769f5bac2f8b3de1d46f05), [`b3d826497b`](https://github.com/medusajs/medusa/commit/b3d826497b3dae5e1b26b7924706c24fd5e87ca5), [`a86c87fe14`](https://github.com/medusajs/medusa/commit/a86c87fe1442afce9285e39255914e01012b4449), [`640eccd5dd`](https://github.com/medusajs/medusa/commit/640eccd5ddbb163e0f987ce6c772f1129c2e2632), [`8ea37d03c9`](https://github.com/medusajs/medusa/commit/8ea37d03c914a5004a3e42770668b2d1f7f8f564), [`339a946f38`](https://github.com/medusajs/medusa/commit/339a946f389033c21e05338f9dbf07d88e140533), [`9288f53327`](https://github.com/medusajs/medusa/commit/9288f53327b8ce617af92ed8d14d9459cbfeb13c), [`8dad2b51a2`](https://github.com/medusajs/medusa/commit/8dad2b51a26c4c3c14a6c95f70424c8bef2ad63e), [`8a946beb75`](https://github.com/medusajs/medusa/commit/8a946beb75dd2560baffb5adc508969bf1fe8ef5), [`a6d7070dd6`](https://github.com/medusajs/medusa/commit/a6d7070dd669c21ea19d70434d42c2f8167dc309), [`168f02f138`](https://github.com/medusajs/medusa/commit/168f02f138ad101e1013f2c8c3f8dc19de12accf), [`f5c2256286`](https://github.com/medusajs/medusa/commit/f5c22562867f412040f8bc6c55ab5de3a3735e62), [`000eb61e33`](https://github.com/medusajs/medusa/commit/000eb61e33e0302db95ee6ad1656ea9b430ed471), [`d550be3685`](https://github.com/medusajs/medusa/commit/d550be3685423218d47a20c57a5e06758f4a961a), [`4b06c17dc0`](https://github.com/medusajs/medusa/commit/4b06c17dc00dc9ed50898573aee704b84dd181b3), [`62a7bcc30c`](https://github.com/medusajs/medusa/commit/62a7bcc30cbc7b234b2b51d7858439951a84edeb), [`f611865553`](https://github.com/medusajs/medusa/commit/f611865553b1f6914bed58ef2eacdf5e929d60dc), [`a8794d48de`](https://github.com/medusajs/medusa/commit/a8794d48de11c4b31f7d8f0dd254caf17daf052e), [`8f8a4f9b13`](https://github.com/medusajs/medusa/commit/8f8a4f9b1353087d98f6cc75346d43a7f49901a8), [`6500f18b9b`](https://github.com/medusajs/medusa/commit/6500f18b9b80c5c9c473489e7e740d55dca74303), [`ce39b9b66e`](https://github.com/medusajs/medusa/commit/ce39b9b66e8c277ec0691ea6d0a950003be09cc1), [`a6a4b3f01a`](https://github.com/medusajs/medusa/commit/a6a4b3f01a6d2bd97b1580c59134279a1b033a5d), [`4625bd1241`](https://github.com/medusajs/medusa/commit/4625bd12416275b09c22cde4a09cb0f68df5d7c1), [`56b0b45304`](https://github.com/medusajs/medusa/commit/56b0b4530401a6ec5aa155874d371e45bb388fe2), [`cc1b66842c`](https://github.com/medusajs/medusa/commit/cc1b66842cbb37c6eab84e2d8b74844c214f38d7), [`24fb102a56`](https://github.com/medusajs/medusa/commit/24fb102a564b1253d1f8b039bb1e435cc5312fbb), [`e85463b2a7`](https://github.com/medusajs/medusa/commit/e85463b2a717751de2e21c39a4c745449b31affe)]:
|
||||
- @medusajs/utils@1.11.7
|
||||
- @medusajs/workflows-sdk@0.1.4
|
||||
- @medusajs/orchestration@0.5.5
|
||||
- @medusajs/modules-sdk@1.12.9
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#5923](https://github.com/medusajs/medusa/pull/5923) [`3db2f95e65`](https://github.com/medusajs/medusa/commit/3db2f95e65909f4fff432990b48be74509052e83) Thanks [@fPolic](https://github.com/fPolic)! - feat: Sales Channel module
|
||||
|
||||
- Updated dependencies [[`12054f5c0`](https://github.com/medusajs/medusa/commit/12054f5c01915899223ddc6da734151b31fbb23b), [`3db2f95e65`](https://github.com/medusajs/medusa/commit/3db2f95e65909f4fff432990b48be74509052e83), [`96ba49329`](https://github.com/medusajs/medusa/commit/96ba49329b6b05922c90f0c55f16455cb40aa5ca), [`45134e4d1`](https://github.com/medusajs/medusa/commit/45134e4d11cfcdc08dbd10aae687bfbe9e848ab9), [`884428a1b`](https://github.com/medusajs/medusa/commit/884428a1b573e499d7659aefed639bf797147428), [`882aa549b`](https://github.com/medusajs/medusa/commit/882aa549bdcc6f378934eab2a7c485df354f46aa)]:
|
||||
- @medusajs/utils@1.11.5
|
||||
- @medusajs/modules-sdk@1.12.8
|
||||
- @medusajs/orchestration@0.5.4
|
||||
- @medusajs/workflows-sdk@0.1.3
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#6152](https://github.com/medusajs/medusa/pull/6152) [`99045848f`](https://github.com/medusajs/medusa/commit/99045848fd3e863359c7878d9bc05271ed083a0e) Thanks [@riqwan](https://github.com/riqwan)! - feat(medusa,types,core-flows,utils): added delete endpoints for campaigns and promotions
|
||||
|
||||
- [#6130](https://github.com/medusajs/medusa/pull/6130) [`da5cc4cf7`](https://github.com/medusajs/medusa/commit/da5cc4cf7f7f0ef40d409704a95b025ce95477f4) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,medusa,utils): promotion and campaign create/update endpoint
|
||||
|
||||
- Updated dependencies [[`68ddd866a5`](https://github.com/medusajs/medusa/commit/68ddd866a5ff9414e2db5b80d75acc5e81948540), [`72bc52231c`](https://github.com/medusajs/medusa/commit/72bc52231ca3a72fa6d197a248fe07a938ed0d85), [`99045848f`](https://github.com/medusajs/medusa/commit/99045848fd3e863359c7878d9bc05271ed083a0e), [`a9b4214503`](https://github.com/medusajs/medusa/commit/a9b42145032ee88aa922a11fe03e777b140c68f4), [`d85fee42e`](https://github.com/medusajs/medusa/commit/d85fee42ee7f661310584dfee5741d6c53b989bb), [`5e655dd59`](https://github.com/medusajs/medusa/commit/5e655dd59bda4ffface28db38021ba71cae6de10), [`b782d3bcb7`](https://github.com/medusajs/medusa/commit/b782d3bcb7e8088a962584b9a55200dd29c2161c), [`2b9f98895e`](https://github.com/medusajs/medusa/commit/2b9f98895eaca255e01278674b11cd7cb69b388f), [`302323916`](https://github.com/medusajs/medusa/commit/302323916b6d8eaf571cd59b5fc92a913af207de), [`da5cc4cf7`](https://github.com/medusajs/medusa/commit/da5cc4cf7f7f0ef40d409704a95b025ce95477f4), [`daecd82a7`](https://github.com/medusajs/medusa/commit/daecd82a7cdf7315599f464999690414c20d6748), [`738e9115e`](https://github.com/medusajs/medusa/commit/738e9115ec920d48bc52b8a690847e58c87ca28e), [`06b33a9b4`](https://github.com/medusajs/medusa/commit/06b33a9b4525b77b1b14b35b973209700945654e), [`b6ac768698`](https://github.com/medusajs/medusa/commit/b6ac768698a3b49d0162cb49e628386f3352d034), [`19bbae61f8`](https://github.com/medusajs/medusa/commit/19bbae61f8de1ac0ed574caff17b33e17705005a), [`130c641e5c`](https://github.com/medusajs/medusa/commit/130c641e5c91cf831de64fb87aebbfdc4d23530d), [`fade8ea7bf`](https://github.com/medusajs/medusa/commit/fade8ea7bf560343ecbde116d226ac44053cdb8e), [`8472460f53`](https://github.com/medusajs/medusa/commit/8472460f533322cc4535199aa768ac163021bc79)]:
|
||||
- @medusajs/utils@1.11.4
|
||||
- @medusajs/modules-sdk@1.12.7
|
||||
- @medusajs/orchestration@0.5.3
|
||||
- @medusajs/workflows-sdk@0.1.2
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#5810](https://github.com/medusajs/medusa/pull/5810) [`fe007d01b`](https://github.com/medusajs/medusa/commit/fe007d01bd827f0e09ee545e48cef18913540c68) Thanks [@fPolic](https://github.com/fPolic)! - feat: sales channel <> order link
|
||||
|
||||
- [#5459](https://github.com/medusajs/medusa/pull/5459) [`76332ca6c`](https://github.com/medusajs/medusa/commit/76332ca6c153a786acc07d3f06ff45c3b9346fd3) Thanks [@fPolic](https://github.com/fPolic)! - feat: SalesChannel <> Cart joiner config
|
||||
|
||||
- Updated dependencies [[`6d1e3cc02`](https://github.com/medusajs/medusa/commit/6d1e3cc0285ef157fd6486060e8b32c00c01aa80), [`42cc8ae3f`](https://github.com/medusajs/medusa/commit/42cc8ae3f89ed7d642e51654d1a3cca011f13155), [`45996d58a2`](https://github.com/medusajs/medusa/commit/45996d58a2665d72335faad11bea958f8da74195), [`9cc787cac4`](https://github.com/medusajs/medusa/commit/9cc787cac4bf1c5d8edf1c4b548bb3205100e822), [`bf63c4e6a`](https://github.com/medusajs/medusa/commit/bf63c4e6a32258565e1d361b8919afbf93cc2c72), [`355075097`](https://github.com/medusajs/medusa/commit/3550750975a0c9359fd887929377733606ef03af), [`8402f4697`](https://github.com/medusajs/medusa/commit/8402f46970c007bab9e0f1f6ae653d955650d503), [`925feea04`](https://github.com/medusajs/medusa/commit/925feea04a8222285175c33577548e50516069a7), [`3f6d79961`](https://github.com/medusajs/medusa/commit/3f6d79961dec1c5eb8950f8eacd94a5d87a4acde), [`fbee006e5`](https://github.com/medusajs/medusa/commit/fbee006e512ef2d56ffb23eeabad8b51b56be285), [`c41f3002f`](https://github.com/medusajs/medusa/commit/c41f3002f3118b1f195c5c822fe0f400091d115b), [`a0dd18c12`](https://github.com/medusajs/medusa/commit/a0dd18c12ac5ab6280366d93d7b47cdb3036914b), [`d16d10619`](https://github.com/medusajs/medusa/commit/d16d10619dfbd3966a4709753de3d8cc37c6f2eb), [`890e76a5c`](https://github.com/medusajs/medusa/commit/890e76a5c53039576c42ca4d46af6f6977cdebd1), [`fe007d01b`](https://github.com/medusajs/medusa/commit/fe007d01bd827f0e09ee545e48cef18913540c68), [`76332ca6c`](https://github.com/medusajs/medusa/commit/76332ca6c153a786acc07d3f06ff45c3b9346fd3)]:
|
||||
- @medusajs/modules-sdk@1.12.6
|
||||
- @medusajs/utils@1.11.3
|
||||
- @medusajs/orchestration@0.5.2
|
||||
- @medusajs/workflows-sdk@0.1.1
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#5752](https://github.com/medusajs/medusa/pull/5752) [`079f0da83`](https://github.com/medusajs/medusa/commit/079f0da83f482562bbb525807ee1a7e32993b4da) Thanks [@riqwan](https://github.com/riqwan)! - feat(core-flows,pricing,medusa,pricing,types,utils): Price List Prices can have their own rules
|
||||
|
||||
- [#5811](https://github.com/medusajs/medusa/pull/5811) [`07107f356`](https://github.com/medusajs/medusa/commit/07107f3565bc2c97e9b89818b390210454f0566d) Thanks [@riqwan](https://github.com/riqwan)! - feat(orchestration,core-flows,medusa): product import uses workflows
|
||||
|
||||
- [#5725](https://github.com/medusajs/medusa/pull/5725) [`85cda7ce3`](https://github.com/medusajs/medusa/commit/85cda7ce3754e2a8ecb207f29d462a9bcd442ade) Thanks [@adrien2p](https://github.com/adrien2p)! - slightly improve create cart workflow
|
||||
|
||||
- Updated dependencies [[`079f0da83`](https://github.com/medusajs/medusa/commit/079f0da83f482562bbb525807ee1a7e32993b4da), [`c4deeee48`](https://github.com/medusajs/medusa/commit/c4deeee481399f5371d773173e20dc149d502e20), [`07107f356`](https://github.com/medusajs/medusa/commit/07107f3565bc2c97e9b89818b390210454f0566d), [`8f25ed8a1`](https://github.com/medusajs/medusa/commit/8f25ed8a10fe23e9342dc3d03545546b4ad4d6da)]:
|
||||
- @medusajs/utils@1.11.2
|
||||
- @medusajs/modules-sdk@1.12.5
|
||||
- @medusajs/orchestration@0.5.1
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#5705](https://github.com/medusajs/medusa/pull/5705) [`ddbeed4ea`](https://github.com/medusajs/medusa/commit/ddbeed4ea67d67a7aef04eb3135087551a7e9b37) Thanks [@adrien2p](https://github.com/adrien2p)! - chore(workflows, core-flows, ...): Split workflows tooling and definitions
|
||||
|
||||
- Updated dependencies [[`1e39a95f8`](https://github.com/medusajs/medusa/commit/1e39a95f8a136427d04ea20cd320337af0923e31), [`a39ce125c`](https://github.com/medusajs/medusa/commit/a39ce125cc96f14732d5a6301313d2376484fa23), [`ddbeed4ea`](https://github.com/medusajs/medusa/commit/ddbeed4ea67d67a7aef04eb3135087551a7e9b37), [`18afe0b9a`](https://github.com/medusajs/medusa/commit/18afe0b9addb33ec2e3b285651b4eb1ef8065845), [`de8f74867`](https://github.com/medusajs/medusa/commit/de8f748674bfd19b3dbadb9695d9080aa91940de), [`ffb0c7b4c`](https://github.com/medusajs/medusa/commit/ffb0c7b4cdbc83b61f70c881001a69de6ec8ae99), [`010560fd2`](https://github.com/medusajs/medusa/commit/010560fd2a4c12eb7a551919df33e58e7cbe920f), [`9f9db3969`](https://github.com/medusajs/medusa/commit/9f9db396987776039ad0c2b8d5792d0ebdbf8792), [`dc5750dd6`](https://github.com/medusajs/medusa/commit/dc5750dd665a91d35c0246ba83c7f90ec74907f4)]:
|
||||
- @medusajs/workflows-sdk@0.1.0
|
||||
- @medusajs/orchestration@0.5.0
|
||||
- @medusajs/utils@1.11.1
|
||||
- @medusajs/modules-sdk@1.12.4
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
transform: {
|
||||
"^.+\\.[jt]s?$": [
|
||||
"ts-jest",
|
||||
{
|
||||
tsconfig: "tsconfig.json",
|
||||
isolatedModules: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
testEnvironment: `node`,
|
||||
moduleFileExtensions: [`js`, `ts`],
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@medusajs/core-flows",
|
||||
"version": "0.0.9",
|
||||
"description": "Set of workflow definitions for Medusa",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/medusajs/medusa",
|
||||
"directory": "packages/core-flows"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"author": "Medusa",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@medusajs/types": "^1.11.16",
|
||||
"cross-env": "^5.2.1",
|
||||
"jest": "^29.6.3",
|
||||
"rimraf": "^5.0.1",
|
||||
"ts-jest": "^29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@medusajs/modules-sdk": "^1.12.11",
|
||||
"@medusajs/orchestration": "^0.5.7",
|
||||
"@medusajs/utils": "^1.11.9",
|
||||
"@medusajs/workflows-sdk": "^0.1.6",
|
||||
"awilix": "^8.0.1",
|
||||
"ulid": "^2.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublishOnly": "cross-env NODE_ENV=production tsc --build",
|
||||
"build": "rimraf dist && tsc --build",
|
||||
"watch": "tsc --build --watch",
|
||||
"test": "jest --runInBand --bail --forceExit --passWithNoTests"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./steps"
|
||||
export * from "./workflows"
|
||||
@@ -0,0 +1,33 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { CreateApiKeyDTO, IApiKeyModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type CreateApiKeysStepInput = {
|
||||
api_keys: CreateApiKeyDTO[]
|
||||
}
|
||||
|
||||
export const createApiKeysStepId = "create-api-keys"
|
||||
export const createApiKeysStep = createStep(
|
||||
createApiKeysStepId,
|
||||
async (data: CreateApiKeysStepInput, { container }) => {
|
||||
const service = container.resolve<IApiKeyModuleService>(
|
||||
ModuleRegistrationName.API_KEY
|
||||
)
|
||||
const created = await service.create(data.api_keys)
|
||||
return new StepResponse(
|
||||
created,
|
||||
created.map((apiKey) => apiKey.id)
|
||||
)
|
||||
},
|
||||
async (createdIds, { container }) => {
|
||||
if (!createdIds?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<IApiKeyModuleService>(
|
||||
ModuleRegistrationName.API_KEY
|
||||
)
|
||||
|
||||
await service.delete(createdIds)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { IApiKeyModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const deleteApiKeysStepId = "delete-api-keys"
|
||||
export const deleteApiKeysStep = createStep(
|
||||
{ name: deleteApiKeysStepId, noCompensation: true },
|
||||
async (ids: string[], { container }) => {
|
||||
const service = container.resolve<IApiKeyModuleService>(
|
||||
ModuleRegistrationName.API_KEY
|
||||
)
|
||||
|
||||
await service.delete(ids)
|
||||
return new StepResponse(void 0)
|
||||
},
|
||||
async () => {}
|
||||
)
|
||||
@@ -0,0 +1,6 @@
|
||||
export * from "./link-sales-channels-to-publishable-key"
|
||||
export * from "./create-api-keys"
|
||||
export * from "./delete-api-keys"
|
||||
export * from "./revoke-api-keys"
|
||||
export * from "./update-api-keys"
|
||||
export * from "./validate-sales-channel-exists"
|
||||
@@ -0,0 +1,62 @@
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
import { LinkWorkflowInput } from "@medusajs/types/src"
|
||||
import { ContainerRegistrationKeys, promiseAll } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const linkSalesChannelsToApiKeyStepId = "link-sales-channels-to-api-key"
|
||||
export const linkSalesChannelsToApiKeyStep = createStep(
|
||||
linkSalesChannelsToApiKeyStepId,
|
||||
async (input: LinkWorkflowInput, { container }) => {
|
||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||
if (!input || (!input.add?.length && !input.remove?.length)) {
|
||||
return
|
||||
}
|
||||
|
||||
const linksToCreate = (input.add ?? []).map((salesChannelId) => {
|
||||
return {
|
||||
[Modules.API_KEY]: {
|
||||
publishable_key_id: input.id,
|
||||
},
|
||||
[Modules.SALES_CHANNEL]: {
|
||||
sales_channel_id: salesChannelId,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
const linksToDismiss = (input.remove ?? []).map((salesChannelId) => {
|
||||
return {
|
||||
[Modules.API_KEY]: {
|
||||
publishable_key_id: input.id,
|
||||
},
|
||||
[Modules.SALES_CHANNEL]: {
|
||||
sales_channel_id: salesChannelId,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
const promises: Promise<any>[] = []
|
||||
if (linksToCreate.length) {
|
||||
promises.push(remoteLink.create(linksToCreate))
|
||||
}
|
||||
if (linksToDismiss.length) {
|
||||
promises.push(remoteLink.dismiss(linksToDismiss))
|
||||
}
|
||||
await promiseAll(promises)
|
||||
|
||||
return new StepResponse(void 0, { linksToCreate, linksToDismiss })
|
||||
},
|
||||
async (prevData, { container }) => {
|
||||
if (!prevData) {
|
||||
return
|
||||
}
|
||||
|
||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||
if (prevData.linksToCreate.length) {
|
||||
await remoteLink.dismiss(prevData.linksToCreate)
|
||||
}
|
||||
|
||||
if (prevData.linksToDismiss.length) {
|
||||
await remoteLink.create(prevData.linksToDismiss)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,26 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
FilterableApiKeyProps,
|
||||
IApiKeyModuleService,
|
||||
RevokeApiKeyDTO,
|
||||
} from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type RevokeApiKeysStepInput = {
|
||||
selector: FilterableApiKeyProps
|
||||
revoke: RevokeApiKeyDTO
|
||||
}
|
||||
|
||||
export const revokeApiKeysStepId = "revoke-api-keys"
|
||||
export const revokeApiKeysStep = createStep(
|
||||
{ name: revokeApiKeysStepId, noCompensation: true },
|
||||
async (data: RevokeApiKeysStepInput, { container }) => {
|
||||
const service = container.resolve<IApiKeyModuleService>(
|
||||
ModuleRegistrationName.API_KEY
|
||||
)
|
||||
|
||||
const apiKeys = await service.revoke(data.selector, data.revoke)
|
||||
return new StepResponse(apiKeys)
|
||||
},
|
||||
async () => {}
|
||||
)
|
||||
@@ -0,0 +1,51 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
FilterableApiKeyProps,
|
||||
IApiKeyModuleService,
|
||||
UpdateApiKeyDTO,
|
||||
} from "@medusajs/types"
|
||||
import { getSelectsAndRelationsFromObjectArray } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type UpdateApiKeysStepInput = {
|
||||
selector: FilterableApiKeyProps
|
||||
update: UpdateApiKeyDTO
|
||||
}
|
||||
|
||||
export const updateApiKeysStepId = "update-api-keys"
|
||||
export const updateApiKeysStep = createStep(
|
||||
updateApiKeysStepId,
|
||||
async (data: UpdateApiKeysStepInput, { container }) => {
|
||||
const service = container.resolve<IApiKeyModuleService>(
|
||||
ModuleRegistrationName.API_KEY
|
||||
)
|
||||
|
||||
const { selects, relations } = getSelectsAndRelationsFromObjectArray([
|
||||
data.update,
|
||||
])
|
||||
|
||||
const prevData = await service.list(data.selector, {
|
||||
select: selects,
|
||||
relations,
|
||||
})
|
||||
|
||||
const apiKeys = await service.update(data.selector, data.update)
|
||||
return new StepResponse(apiKeys, prevData)
|
||||
},
|
||||
async (prevData, { container }) => {
|
||||
if (!prevData?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<IApiKeyModuleService>(
|
||||
ModuleRegistrationName.API_KEY
|
||||
)
|
||||
|
||||
await service.upsert(
|
||||
prevData.map((r) => ({
|
||||
id: r.id,
|
||||
title: r.title,
|
||||
}))
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,37 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { ISalesChannelModuleService } from "@medusajs/types"
|
||||
import { MedusaError, arrayDifference } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
sales_channel_ids: string[]
|
||||
}
|
||||
|
||||
export const validateSalesChannelsExistStepId = "validate-sales-channels-exist"
|
||||
export const validateSalesChannelsExistStep = createStep(
|
||||
validateSalesChannelsExistStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const salesChannelModuleService =
|
||||
container.resolve<ISalesChannelModuleService>(
|
||||
ModuleRegistrationName.SALES_CHANNEL
|
||||
)
|
||||
|
||||
const salesChannels = await salesChannelModuleService.list(
|
||||
{ id: data.sales_channel_ids },
|
||||
{ select: ["id"] }
|
||||
)
|
||||
|
||||
const salesChannelIds = salesChannels.map((v) => v.id)
|
||||
|
||||
const notFound = arrayDifference(data.sales_channel_ids, salesChannelIds)
|
||||
|
||||
if (notFound.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Sales channels with IDs ${notFound.join(", ")} do not exist`
|
||||
)
|
||||
}
|
||||
|
||||
return new StepResponse(salesChannelIds)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
import { ApiKeyDTO, CreateApiKeyDTO } from "@medusajs/types"
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { createApiKeysStep } from "../steps"
|
||||
|
||||
type WorkflowInput = { api_keys: CreateApiKeyDTO[] }
|
||||
|
||||
export const createApiKeysWorkflowId = "create-api-keys"
|
||||
export const createApiKeysWorkflow = createWorkflow(
|
||||
createApiKeysWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<ApiKeyDTO[]> => {
|
||||
return createApiKeysStep(input)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { removeRemoteLinkStep } from "../../common/steps/remove-remote-links"
|
||||
import { deleteApiKeysStep } from "../steps"
|
||||
|
||||
type WorkflowInput = { ids: string[] }
|
||||
|
||||
export const deleteApiKeysWorkflowId = "delete-api-keys"
|
||||
export const deleteApiKeysWorkflow = createWorkflow(
|
||||
deleteApiKeysWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
|
||||
deleteApiKeysStep(input.ids)
|
||||
|
||||
// Please note, the ids here should be publishable key IDs
|
||||
removeRemoteLinkStep({
|
||||
[Modules.API_KEY]: { publishable_key_id: input.ids },
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
export * from "./create-api-keys"
|
||||
export * from "./delete-api-keys"
|
||||
export * from "./update-api-keys"
|
||||
export * from "./revoke-api-keys"
|
||||
export * from "./link-sales-channels-to-publishable-key"
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import {
|
||||
linkSalesChannelsToApiKeyStep,
|
||||
validateSalesChannelsExistStep,
|
||||
} from "../steps"
|
||||
import { LinkWorkflowInput } from "@medusajs/types/src"
|
||||
|
||||
export const linkSalesChannelsToApiKeyWorkflowId =
|
||||
"link-sales-channels-to-api-key"
|
||||
export const linkSalesChannelsToApiKeyWorkflow = createWorkflow(
|
||||
linkSalesChannelsToApiKeyWorkflowId,
|
||||
(input: WorkflowData<LinkWorkflowInput>) => {
|
||||
validateSalesChannelsExistStep({
|
||||
sales_channel_ids: input.add ?? [],
|
||||
})
|
||||
|
||||
linkSalesChannelsToApiKeyStep(input)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
import {
|
||||
ApiKeyDTO,
|
||||
FilterableApiKeyProps,
|
||||
RevokeApiKeyDTO,
|
||||
} from "@medusajs/types"
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { revokeApiKeysStep } from "../steps"
|
||||
|
||||
type RevokeApiKeysStepInput = {
|
||||
selector: FilterableApiKeyProps
|
||||
revoke: RevokeApiKeyDTO
|
||||
}
|
||||
|
||||
type WorkflowInput = RevokeApiKeysStepInput
|
||||
|
||||
export const revokeApiKeysWorkflowId = "revoke-api-keys"
|
||||
export const revokeApiKeysWorkflow = createWorkflow(
|
||||
revokeApiKeysWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<ApiKeyDTO[]> => {
|
||||
return revokeApiKeysStep(input)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
import {
|
||||
ApiKeyDTO,
|
||||
FilterableApiKeyProps,
|
||||
UpdateApiKeyDTO,
|
||||
} from "@medusajs/types"
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { updateApiKeysStep } from "../steps"
|
||||
|
||||
type UpdateApiKeysStepInput = {
|
||||
selector: FilterableApiKeyProps
|
||||
update: UpdateApiKeyDTO
|
||||
}
|
||||
|
||||
type WorkflowInput = UpdateApiKeysStepInput
|
||||
|
||||
export const updateApiKeysWorkflowId = "update-api-keys"
|
||||
export const updateApiKeysWorkflow = createWorkflow(
|
||||
updateApiKeysWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<ApiKeyDTO[]> => {
|
||||
return updateApiKeysStep(input)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./steps"
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./set-auth-app-metadata"
|
||||
@@ -0,0 +1,60 @@
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { IAuthModuleService } from "@medusajs/types"
|
||||
import { isDefined } from "@medusajs/utils"
|
||||
|
||||
type StepInput = {
|
||||
authUserId: string
|
||||
key: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export const setAuthAppMetadataStepId = "set-auth-app-metadata"
|
||||
export const setAuthAppMetadataStep = createStep(
|
||||
setAuthAppMetadataStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const service = container.resolve<IAuthModuleService>(
|
||||
ModuleRegistrationName.AUTH
|
||||
)
|
||||
|
||||
const authUser = await service.retrieve(data.authUserId)
|
||||
|
||||
const appMetadata = authUser.app_metadata || {}
|
||||
if (isDefined(appMetadata[data.key])) {
|
||||
throw new Error(`Key ${data.key} already exists in app metadata`)
|
||||
}
|
||||
|
||||
appMetadata[data.key] = data.value
|
||||
|
||||
await service.update({
|
||||
id: authUser.id,
|
||||
app_metadata: appMetadata,
|
||||
})
|
||||
|
||||
return new StepResponse(authUser, { id: authUser.id, key: data.key })
|
||||
},
|
||||
async (idAndKey, { container }) => {
|
||||
if (!idAndKey) {
|
||||
return
|
||||
}
|
||||
|
||||
const { id, key } = idAndKey
|
||||
|
||||
const service = container.resolve<IAuthModuleService>(
|
||||
ModuleRegistrationName.AUTH
|
||||
)
|
||||
|
||||
const authUser = await service.retrieve(id)
|
||||
|
||||
const appMetadata = authUser.app_metadata || {}
|
||||
if (isDefined(appMetadata[key])) {
|
||||
delete appMetadata[key]
|
||||
}
|
||||
|
||||
await service.update({
|
||||
id: authUser.id,
|
||||
app_metadata: appMetadata,
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./steps/remove-remote-links"
|
||||
export * from "./steps/use-remote-query"
|
||||
@@ -0,0 +1,50 @@
|
||||
import { DeleteEntityInput, RemoteLink } from "@medusajs/modules-sdk"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
||||
|
||||
type RemoveRemoteLinksStepInput = DeleteEntityInput | DeleteEntityInput[]
|
||||
|
||||
export const removeRemoteLinkStepId = "remove-remote-links"
|
||||
export const removeRemoteLinkStep = createStep(
|
||||
removeRemoteLinkStepId,
|
||||
async (data: RemoveRemoteLinksStepInput, { container }) => {
|
||||
const entries = Array.isArray(data) ? data : [data]
|
||||
const grouped: DeleteEntityInput = {}
|
||||
|
||||
for (const entry of entries) {
|
||||
for (const moduleName of Object.keys(entry)) {
|
||||
grouped[moduleName] ??= {}
|
||||
|
||||
for (const linkableKey of Object.keys(entry[moduleName])) {
|
||||
grouped[moduleName][linkableKey] ??= []
|
||||
|
||||
const keys = Array.isArray(entry[moduleName][linkableKey])
|
||||
? entry[moduleName][linkableKey]
|
||||
: [entry[moduleName][linkableKey]]
|
||||
|
||||
grouped[moduleName][linkableKey] = (
|
||||
grouped[moduleName][linkableKey] as string[]
|
||||
).concat(keys as string[])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const link = container.resolve<RemoteLink>(
|
||||
ContainerRegistrationKeys.REMOTE_LINK
|
||||
)
|
||||
await link.delete(grouped)
|
||||
|
||||
return new StepResponse(grouped, grouped)
|
||||
},
|
||||
async (removedLinks, { container }) => {
|
||||
if (!removedLinks) {
|
||||
return
|
||||
}
|
||||
|
||||
const link = container.resolve<RemoteLink>(
|
||||
ContainerRegistrationKeys.REMOTE_LINK
|
||||
)
|
||||
await link.restore(removedLinks)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
entry_point: string
|
||||
fields: string[]
|
||||
variables?: Record<string, any>
|
||||
throw_if_key_not_found?: boolean
|
||||
throw_if_relation_not_found?: boolean | string[]
|
||||
list?: boolean
|
||||
}
|
||||
|
||||
export const useRemoteQueryStepId = "use-remote-query"
|
||||
export const useRemoteQueryStep = createStep(
|
||||
useRemoteQueryStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { list = true, fields, variables, entry_point: entryPoint } = data
|
||||
const query = container.resolve("remoteQuery")
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint,
|
||||
fields,
|
||||
variables,
|
||||
})
|
||||
|
||||
const config = {
|
||||
throwIfKeyNotFound: !!data.throw_if_key_not_found,
|
||||
throwIfRelationNotFound: data.throw_if_key_not_found
|
||||
? data.throw_if_relation_not_found
|
||||
: undefined,
|
||||
}
|
||||
|
||||
const entities = await query(queryObject, undefined, config)
|
||||
const result = list ? entities : entities[0]
|
||||
|
||||
return new StepResponse(result)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./workflows"
|
||||
export * from "./steps"
|
||||
@@ -0,0 +1,33 @@
|
||||
import { CreateCustomerGroupDTO, ICustomerModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
|
||||
export const createCustomerGroupsStepId = "create-customer-groups"
|
||||
export const createCustomerGroupsStep = createStep(
|
||||
createCustomerGroupsStepId,
|
||||
async (data: CreateCustomerGroupDTO[], { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
const createdCustomerGroups = await service.createCustomerGroup(data)
|
||||
|
||||
return new StepResponse(
|
||||
createdCustomerGroups,
|
||||
createdCustomerGroups.map(
|
||||
(createdCustomerGroups) => createdCustomerGroups.id
|
||||
)
|
||||
)
|
||||
},
|
||||
async (createdCustomerGroupIds, { container }) => {
|
||||
if (!createdCustomerGroupIds?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.delete(createdCustomerGroupIds)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
import { GroupCustomerPair, ICustomerModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
|
||||
export const deleteCustomerGroupCustomersStepId =
|
||||
"delete-customer-group-customers"
|
||||
export const deleteCustomerGroupCustomersStep = createStep(
|
||||
deleteCustomerGroupCustomersStepId,
|
||||
async (data: GroupCustomerPair[], { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.removeCustomerFromGroup(data)
|
||||
|
||||
return new StepResponse(void 0, data)
|
||||
},
|
||||
async (groupPairs, { container }) => {
|
||||
if (!groupPairs?.length) {
|
||||
return
|
||||
}
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.addCustomerToGroup(groupPairs)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
import { ICustomerModuleService } from "@medusajs/types"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
|
||||
type DeleteCustomerGroupStepInput = string[]
|
||||
|
||||
export const deleteCustomerGroupStepId = "delete-customer-groups"
|
||||
export const deleteCustomerGroupStep = createStep(
|
||||
deleteCustomerGroupStepId,
|
||||
async (ids: DeleteCustomerGroupStepInput, { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.softDeleteCustomerGroups(ids)
|
||||
|
||||
return new StepResponse(void 0, ids)
|
||||
},
|
||||
async (prevCustomerGroups, { container }) => {
|
||||
if (!prevCustomerGroups) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.restoreCustomerGroups(prevCustomerGroups)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from "./update-customer-groups"
|
||||
export * from "./delete-customer-groups"
|
||||
export * from "./create-customer-groups"
|
||||
export * from "./link-customers-customer-group"
|
||||
@@ -0,0 +1,56 @@
|
||||
import { ICustomerModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { LinkWorkflowInput } from "@medusajs/types/src"
|
||||
import { promiseAll } from "@medusajs/utils"
|
||||
|
||||
export const linkCustomersToCustomerGroupStepId =
|
||||
"link-customers-to-customer-group"
|
||||
export const linkCustomersToCustomerGroupStep = createStep(
|
||||
linkCustomersToCustomerGroupStepId,
|
||||
async (data: LinkWorkflowInput, { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
const toAdd = (data.add ?? []).map((customerId) => {
|
||||
return {
|
||||
customer_id: customerId,
|
||||
customer_group_id: data.id,
|
||||
}
|
||||
})
|
||||
|
||||
const toRemove = (data.remove ?? []).map((customerId) => {
|
||||
return {
|
||||
customer_id: customerId,
|
||||
customer_group_id: data.id,
|
||||
}
|
||||
})
|
||||
|
||||
const promises: Promise<any>[] = []
|
||||
if (toAdd.length) {
|
||||
promises.push(service.addCustomerToGroup(toAdd))
|
||||
}
|
||||
if (toRemove.length) {
|
||||
promises.push(service.removeCustomerFromGroup(toRemove))
|
||||
}
|
||||
await promiseAll(promises)
|
||||
|
||||
return new StepResponse(void 0, { toAdd, toRemove })
|
||||
},
|
||||
async (prevData, { container }) => {
|
||||
if (!prevData) {
|
||||
return
|
||||
}
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
if (prevData.toAdd.length) {
|
||||
await service.removeCustomerFromGroup(prevData.toAdd)
|
||||
}
|
||||
if (prevData.toRemove.length) {
|
||||
await service.addCustomerToGroup(prevData.toRemove)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,58 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
CustomerGroupUpdatableFields,
|
||||
FilterableCustomerGroupProps,
|
||||
ICustomerModuleService,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
getSelectsAndRelationsFromObjectArray,
|
||||
promiseAll,
|
||||
} from "@medusajs/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
type UpdateCustomerGroupStepInput = {
|
||||
selector: FilterableCustomerGroupProps
|
||||
update: CustomerGroupUpdatableFields
|
||||
}
|
||||
|
||||
export const updateCustomerGroupStepId = "update-customer-groups"
|
||||
export const updateCustomerGroupsStep = createStep(
|
||||
updateCustomerGroupStepId,
|
||||
async (data: UpdateCustomerGroupStepInput, { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
const { selects, relations } = getSelectsAndRelationsFromObjectArray([
|
||||
data.update,
|
||||
])
|
||||
const prevCustomerGroups = await service.listCustomerGroups(data.selector, {
|
||||
select: selects,
|
||||
relations,
|
||||
})
|
||||
|
||||
const customers = await service.updateCustomerGroups(
|
||||
data.selector,
|
||||
data.update
|
||||
)
|
||||
|
||||
return new StepResponse(customers, prevCustomerGroups)
|
||||
},
|
||||
async (prevCustomerGroups, { container }) => {
|
||||
if (!prevCustomerGroups) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await promiseAll(
|
||||
prevCustomerGroups.map((c) =>
|
||||
service.updateCustomerGroups(c.id, {
|
||||
name: c.name,
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
import { CustomerGroupDTO, CreateCustomerGroupDTO } from "@medusajs/types"
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { createCustomerGroupsStep } from "../steps"
|
||||
|
||||
type WorkflowInput = { customersData: CreateCustomerGroupDTO[] }
|
||||
|
||||
export const createCustomerGroupsWorkflowId = "create-customer-groups"
|
||||
export const createCustomerGroupsWorkflow = createWorkflow(
|
||||
createCustomerGroupsWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<CustomerGroupDTO[]> => {
|
||||
return createCustomerGroupsStep(input.customersData)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { deleteCustomerGroupStep } from "../steps"
|
||||
|
||||
type WorkflowInput = { ids: string[] }
|
||||
|
||||
export const deleteCustomerGroupsWorkflowId = "delete-customer-groups"
|
||||
export const deleteCustomerGroupsWorkflow = createWorkflow(
|
||||
deleteCustomerGroupsWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
|
||||
return deleteCustomerGroupStep(input.ids)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from "./update-customer-groups"
|
||||
export * from "./delete-customer-groups"
|
||||
export * from "./create-customer-groups"
|
||||
export * from "./link-customers-customer-group"
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { linkCustomersToCustomerGroupStep } from "../steps"
|
||||
import { LinkWorkflowInput } from "@medusajs/types/src"
|
||||
|
||||
export const linkCustomersToCustomerGroupWorkflowId =
|
||||
"link-customers-to-customer-group"
|
||||
export const linkCustomersToCustomerGroupWorkflow = createWorkflow(
|
||||
linkCustomersToCustomerGroupWorkflowId,
|
||||
(input: WorkflowData<LinkWorkflowInput>): WorkflowData<void> => {
|
||||
return linkCustomersToCustomerGroupStep(input)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
import {
|
||||
CustomerGroupDTO,
|
||||
FilterableCustomerGroupProps,
|
||||
CustomerGroupUpdatableFields,
|
||||
} from "@medusajs/types"
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { updateCustomerGroupsStep } from "../steps"
|
||||
|
||||
type WorkflowInput = {
|
||||
selector: FilterableCustomerGroupProps
|
||||
update: CustomerGroupUpdatableFields
|
||||
}
|
||||
|
||||
export const updateCustomerGroupsWorkflowId = "update-customer-groups"
|
||||
export const updateCustomerGroupsWorkflow = createWorkflow(
|
||||
updateCustomerGroupsWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<CustomerGroupDTO[]> => {
|
||||
return updateCustomerGroupsStep(input)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./steps"
|
||||
export * from "./workflows"
|
||||
@@ -0,0 +1,34 @@
|
||||
import {
|
||||
CreateCustomerAddressDTO,
|
||||
ICustomerModuleService,
|
||||
} from "@medusajs/types"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
|
||||
export const createCustomerAddressesStepId = "create-customer-addresses"
|
||||
export const createCustomerAddressesStep = createStep(
|
||||
createCustomerAddressesStepId,
|
||||
async (data: CreateCustomerAddressDTO[], { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
const addresses = await service.addAddresses(data)
|
||||
|
||||
return new StepResponse(
|
||||
addresses,
|
||||
addresses.map((address) => address.id)
|
||||
)
|
||||
},
|
||||
async (ids, { container }) => {
|
||||
if (!ids?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.deleteAddresses(ids)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { CreateCustomerDTO, ICustomerModuleService } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
|
||||
export const createCustomersStepId = "create-customers"
|
||||
export const createCustomersStep = createStep(
|
||||
createCustomersStepId,
|
||||
async (data: CreateCustomerDTO[], { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
const createdCustomers = await service.create(data)
|
||||
|
||||
return new StepResponse(
|
||||
createdCustomers,
|
||||
createdCustomers.map((createdCustomers) => createdCustomers.id)
|
||||
)
|
||||
},
|
||||
async (createdCustomerIds, { container }) => {
|
||||
if (!createdCustomerIds?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.delete(createdCustomerIds)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,32 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { ICustomerModuleService } from "@medusajs/types"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
type DeleteCustomerAddressStepInput = string[]
|
||||
export const deleteCustomerAddressesStepId = "delete-customer-addresses"
|
||||
export const deleteCustomerAddressesStep = createStep(
|
||||
deleteCustomerAddressesStepId,
|
||||
async (ids: DeleteCustomerAddressStepInput, { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
const existing = await service.listAddresses({
|
||||
id: ids,
|
||||
})
|
||||
await service.deleteAddresses(ids)
|
||||
|
||||
return new StepResponse(void 0, existing)
|
||||
},
|
||||
async (prevAddresses, { container }) => {
|
||||
if (!prevAddresses?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.addAddresses(prevAddresses)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { ICustomerModuleService } from "@medusajs/types"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
type DeleteCustomerStepInput = string[]
|
||||
|
||||
export const deleteCustomersStepId = "delete-customers"
|
||||
export const deleteCustomersStep = createStep(
|
||||
deleteCustomersStepId,
|
||||
async (ids: DeleteCustomerStepInput, { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.softDelete(ids)
|
||||
|
||||
return new StepResponse(void 0, ids)
|
||||
},
|
||||
async (prevCustomerIds, { container }) => {
|
||||
if (!prevCustomerIds?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.restore(prevCustomerIds)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
export * from "./create-customers"
|
||||
export * from "./update-customers"
|
||||
export * from "./delete-customers"
|
||||
export * from "./create-addresses"
|
||||
export * from "./update-addresses"
|
||||
export * from "./delete-addresses"
|
||||
export * from "./maybe-unset-default-billing-addresses"
|
||||
export * from "./maybe-unset-default-shipping-addresses"
|
||||
@@ -0,0 +1,61 @@
|
||||
import {
|
||||
CreateCustomerAddressDTO,
|
||||
UpdateCustomerAddressDTO,
|
||||
FilterableCustomerAddressProps,
|
||||
ICustomerModuleService,
|
||||
} from "@medusajs/types"
|
||||
import { createStep } from "@medusajs/workflows-sdk"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { unsetForCreate, unsetForUpdate } from "./utils"
|
||||
import { isDefined } from "@medusajs/utils"
|
||||
|
||||
type StepInput = {
|
||||
create?: CreateCustomerAddressDTO[]
|
||||
update?: {
|
||||
selector: FilterableCustomerAddressProps
|
||||
update: UpdateCustomerAddressDTO
|
||||
}
|
||||
}
|
||||
|
||||
export const maybeUnsetDefaultBillingAddressesStepId =
|
||||
"maybe-unset-default-billing-customer-addresses"
|
||||
export const maybeUnsetDefaultBillingAddressesStep = createStep(
|
||||
maybeUnsetDefaultBillingAddressesStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const customerModuleService = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
if (isDefined(data.create)) {
|
||||
return unsetForCreate(
|
||||
data.create,
|
||||
customerModuleService,
|
||||
"is_default_billing"
|
||||
)
|
||||
}
|
||||
|
||||
if (isDefined(data.update)) {
|
||||
return unsetForUpdate(
|
||||
data.update,
|
||||
customerModuleService,
|
||||
"is_default_billing"
|
||||
)
|
||||
}
|
||||
|
||||
throw new Error("Invalid step input")
|
||||
},
|
||||
async (addressesToSet, { container }) => {
|
||||
if (!addressesToSet?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const customerModuleService = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await customerModuleService.updateAddresses(
|
||||
{ id: addressesToSet },
|
||||
{ is_default_billing: true }
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,60 @@
|
||||
import {
|
||||
CreateCustomerAddressDTO,
|
||||
UpdateCustomerAddressDTO,
|
||||
FilterableCustomerAddressProps,
|
||||
ICustomerModuleService,
|
||||
} from "@medusajs/types"
|
||||
import { createStep } from "@medusajs/workflows-sdk"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { unsetForCreate, unsetForUpdate } from "./utils"
|
||||
import { isDefined } from "@medusajs/utils"
|
||||
|
||||
type StepInput = {
|
||||
create?: CreateCustomerAddressDTO[]
|
||||
update?: {
|
||||
selector: FilterableCustomerAddressProps
|
||||
update: UpdateCustomerAddressDTO
|
||||
}
|
||||
}
|
||||
|
||||
export const maybeUnsetDefaultShippingAddressesStepId =
|
||||
"maybe-unset-default-shipping-customer-addresses"
|
||||
export const maybeUnsetDefaultShippingAddressesStep = createStep(
|
||||
maybeUnsetDefaultShippingAddressesStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const customerModuleService = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
if (isDefined(data.create)) {
|
||||
return unsetForCreate(
|
||||
data.create,
|
||||
customerModuleService,
|
||||
"is_default_shipping"
|
||||
)
|
||||
}
|
||||
|
||||
if (isDefined(data.update)) {
|
||||
return unsetForUpdate(
|
||||
data.update,
|
||||
customerModuleService,
|
||||
"is_default_shipping"
|
||||
)
|
||||
}
|
||||
|
||||
throw new Error("Invalid step input")
|
||||
},
|
||||
async (addressesToSet, { container }) => {
|
||||
if (!addressesToSet?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const customerModuleService = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await customerModuleService.updateAddresses(
|
||||
{ id: addressesToSet },
|
||||
{ is_default_shipping: true }
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,54 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
UpdateCustomerAddressDTO,
|
||||
FilterableCustomerAddressProps,
|
||||
ICustomerModuleService,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
getSelectsAndRelationsFromObjectArray,
|
||||
promiseAll,
|
||||
} from "@medusajs/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
type UpdateCustomerAddresseStepInput = {
|
||||
selector: FilterableCustomerAddressProps
|
||||
update: UpdateCustomerAddressDTO
|
||||
}
|
||||
|
||||
export const updateCustomerAddresseStepId = "update-customer-addresses"
|
||||
export const updateCustomerAddressesStep = createStep(
|
||||
updateCustomerAddresseStepId,
|
||||
async (data: UpdateCustomerAddresseStepInput, { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
const { selects, relations } = getSelectsAndRelationsFromObjectArray([
|
||||
data.update,
|
||||
])
|
||||
const prevCustomers = await service.listAddresses(data.selector, {
|
||||
select: selects,
|
||||
relations,
|
||||
})
|
||||
|
||||
const customerAddresses = await service.updateAddresses(
|
||||
data.selector,
|
||||
data.update
|
||||
)
|
||||
|
||||
return new StepResponse(customerAddresses, prevCustomers)
|
||||
},
|
||||
async (prevCustomerAddresses, { container }) => {
|
||||
if (!prevCustomerAddresses) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await promiseAll(
|
||||
prevCustomerAddresses.map((c) => service.updateAddresses(c.id, { ...c }))
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,59 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
FilterableCustomerProps,
|
||||
ICustomerModuleService,
|
||||
CustomerUpdatableFields,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
getSelectsAndRelationsFromObjectArray,
|
||||
promiseAll,
|
||||
} from "@medusajs/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
type UpdateCustomersStepInput = {
|
||||
selector: FilterableCustomerProps
|
||||
update: CustomerUpdatableFields
|
||||
}
|
||||
|
||||
export const updateCustomersStepId = "update-customer"
|
||||
export const updateCustomersStep = createStep(
|
||||
updateCustomersStepId,
|
||||
async (data: UpdateCustomersStepInput, { container }) => {
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
const { selects, relations } = getSelectsAndRelationsFromObjectArray([
|
||||
data.update,
|
||||
])
|
||||
const prevCustomers = await service.list(data.selector, {
|
||||
select: selects,
|
||||
relations,
|
||||
})
|
||||
|
||||
const customers = await service.update(data.selector, data.update)
|
||||
|
||||
return new StepResponse(customers, prevCustomers)
|
||||
},
|
||||
async (prevCustomers, { container }) => {
|
||||
if (!prevCustomers?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await promiseAll(
|
||||
prevCustomers.map((c) =>
|
||||
service.update(c.id, {
|
||||
first_name: c.first_name,
|
||||
last_name: c.last_name,
|
||||
email: c.email,
|
||||
phone: c.phone,
|
||||
metadata: c.metadata,
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./unset-address-for-create"
|
||||
export * from "./unset-address-for-update"
|
||||
@@ -0,0 +1,33 @@
|
||||
import {
|
||||
CreateCustomerAddressDTO,
|
||||
ICustomerModuleService,
|
||||
} from "@medusajs/types"
|
||||
import { StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const unsetForCreate = async (
|
||||
data: CreateCustomerAddressDTO[],
|
||||
customerService: ICustomerModuleService,
|
||||
field: "is_default_billing" | "is_default_shipping"
|
||||
) => {
|
||||
const customerIds = data.reduce<string[]>((acc, curr) => {
|
||||
if (curr[field]) {
|
||||
acc.push(curr.customer_id)
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
|
||||
const customerDefaultAddresses = await customerService.listAddresses({
|
||||
customer_id: customerIds,
|
||||
[field]: true,
|
||||
})
|
||||
|
||||
await customerService.updateAddresses(
|
||||
{ customer_id: customerIds, [field]: true },
|
||||
{ [field]: false }
|
||||
)
|
||||
|
||||
return new StepResponse(
|
||||
void 0,
|
||||
customerDefaultAddresses.map((address) => address.id)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
UpdateCustomerAddressDTO,
|
||||
FilterableCustomerAddressProps,
|
||||
ICustomerModuleService,
|
||||
} from "@medusajs/types"
|
||||
import { StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const unsetForUpdate = async (
|
||||
data: {
|
||||
selector: FilterableCustomerAddressProps
|
||||
update: UpdateCustomerAddressDTO
|
||||
},
|
||||
customerService: ICustomerModuleService,
|
||||
field: "is_default_billing" | "is_default_shipping"
|
||||
) => {
|
||||
if (!data.update[field]) {
|
||||
return new StepResponse(void 0)
|
||||
}
|
||||
|
||||
const affectedCustomers = await customerService.listAddresses(data.selector, {
|
||||
select: ["id", "customer_id"],
|
||||
})
|
||||
|
||||
const customerIds = affectedCustomers.map((address) => address.customer_id)
|
||||
|
||||
const customerDefaultAddresses = await customerService.listAddresses({
|
||||
customer_id: customerIds,
|
||||
[field]: true,
|
||||
})
|
||||
|
||||
await customerService.updateAddresses(
|
||||
{ customer_id: customerIds, [field]: true },
|
||||
{ [field]: false }
|
||||
)
|
||||
|
||||
return new StepResponse(
|
||||
void 0,
|
||||
customerDefaultAddresses.map((address) => address.id)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { CreateCustomerAddressDTO, CustomerAddressDTO } from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
parallelize,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import {
|
||||
createCustomerAddressesStep,
|
||||
maybeUnsetDefaultBillingAddressesStep,
|
||||
maybeUnsetDefaultShippingAddressesStep,
|
||||
} from "../steps"
|
||||
|
||||
type WorkflowInput = { addresses: CreateCustomerAddressDTO[] }
|
||||
|
||||
export const createCustomerAddressesWorkflowId = "create-customer-addresses"
|
||||
export const createCustomerAddressesWorkflow = createWorkflow(
|
||||
createCustomerAddressesWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<CustomerAddressDTO[]> => {
|
||||
const unsetInput = transform(input, (data) => ({
|
||||
create: data.addresses,
|
||||
}))
|
||||
|
||||
parallelize(
|
||||
maybeUnsetDefaultShippingAddressesStep(unsetInput),
|
||||
maybeUnsetDefaultBillingAddressesStep(unsetInput)
|
||||
)
|
||||
|
||||
return createCustomerAddressesStep(input.addresses)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
import { CreateCustomerDTO, CustomerDTO } from "@medusajs/types"
|
||||
import { createWorkflow, WorkflowData } from "@medusajs/workflows-sdk"
|
||||
import { createCustomersStep } from "../steps"
|
||||
import { setAuthAppMetadataStep } from "../../auth/steps"
|
||||
import { transform } from "@medusajs/workflows-sdk"
|
||||
|
||||
type WorkflowInput = {
|
||||
authUserId: string
|
||||
customersData: CreateCustomerDTO
|
||||
}
|
||||
|
||||
export const createCustomerAccountWorkflowId = "create-customer-account"
|
||||
export const createCustomerAccountWorkflow = createWorkflow(
|
||||
createCustomerAccountWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<CustomerDTO> => {
|
||||
const customers = createCustomersStep([input.customersData])
|
||||
|
||||
const customer = transform(
|
||||
customers,
|
||||
(customers: CustomerDTO[]) => customers[0]
|
||||
)
|
||||
|
||||
setAuthAppMetadataStep({
|
||||
authUserId: input.authUserId,
|
||||
key: "customer_id",
|
||||
value: customer.id,
|
||||
})
|
||||
|
||||
return customer
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
import { CustomerDTO, CreateCustomerDTO } from "@medusajs/types"
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { createCustomersStep } from "../steps"
|
||||
|
||||
type WorkflowInput = { customersData: CreateCustomerDTO[] }
|
||||
|
||||
export const createCustomersWorkflowId = "create-customers"
|
||||
export const createCustomersWorkflow = createWorkflow(
|
||||
createCustomersWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<CustomerDTO[]> => {
|
||||
return createCustomersStep(input.customersData)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { deleteCustomerAddressesStep } from "../steps"
|
||||
|
||||
type WorkflowInput = { ids: string[] }
|
||||
|
||||
export const deleteCustomerAddressesWorkflowId = "delete-customer-addresses"
|
||||
export const deleteCustomerAddressesWorkflow = createWorkflow(
|
||||
deleteCustomerAddressesWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
|
||||
return deleteCustomerAddressesStep(input.ids)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { deleteCustomersStep } from "../steps"
|
||||
|
||||
type WorkflowInput = { ids: string[] }
|
||||
|
||||
export const deleteCustomersWorkflowId = "delete-customers"
|
||||
export const deleteCustomersWorkflow = createWorkflow(
|
||||
deleteCustomersWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
|
||||
return deleteCustomersStep(input.ids)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,7 @@
|
||||
export * from "./create-customers"
|
||||
export * from "./update-customers"
|
||||
export * from "./delete-customers"
|
||||
export * from "./create-customer-account"
|
||||
export * from "./create-addresses"
|
||||
export * from "./update-addresses"
|
||||
export * from "./delete-addresses"
|
||||
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
FilterableCustomerAddressProps,
|
||||
CustomerAddressDTO,
|
||||
UpdateCustomerAddressDTO,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
parallelize,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import {
|
||||
maybeUnsetDefaultBillingAddressesStep,
|
||||
maybeUnsetDefaultShippingAddressesStep,
|
||||
updateCustomerAddressesStep,
|
||||
} from "../steps"
|
||||
|
||||
type WorkflowInput = {
|
||||
selector: FilterableCustomerAddressProps
|
||||
update: UpdateCustomerAddressDTO
|
||||
}
|
||||
|
||||
export const updateCustomerAddressesWorkflowId = "update-customer-addresses"
|
||||
export const updateCustomerAddressesWorkflow = createWorkflow(
|
||||
updateCustomerAddressesWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<CustomerAddressDTO[]> => {
|
||||
const unsetInput = transform(input, (data) => ({
|
||||
update: data,
|
||||
}))
|
||||
|
||||
parallelize(
|
||||
maybeUnsetDefaultShippingAddressesStep(unsetInput),
|
||||
maybeUnsetDefaultBillingAddressesStep(unsetInput)
|
||||
)
|
||||
|
||||
return updateCustomerAddressesStep(input)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
import {
|
||||
CustomerDTO,
|
||||
CustomerUpdatableFields,
|
||||
FilterableCustomerProps,
|
||||
} from "@medusajs/types"
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { updateCustomersStep } from "../steps"
|
||||
|
||||
type UpdateCustomersStepInput = {
|
||||
selector: FilterableCustomerProps
|
||||
update: CustomerUpdatableFields
|
||||
}
|
||||
|
||||
type WorkflowInput = UpdateCustomersStepInput
|
||||
|
||||
export const updateCustomersWorkflowId = "update-customers"
|
||||
export const updateCustomersWorkflow = createWorkflow(
|
||||
updateCustomersWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<CustomerDTO[]> => {
|
||||
return updateCustomersStep(input)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./steps"
|
||||
export * from "./workflows"
|
||||
@@ -0,0 +1,49 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { CreateStoreDTO, IStoreModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { createStoresWorkflow } from "../../store"
|
||||
|
||||
type CreateDefaultStoreStepInput = {
|
||||
store: CreateStoreDTO
|
||||
}
|
||||
|
||||
export const createDefaultStoreStepId = "create-default-store"
|
||||
export const createDefaultStoreStep = createStep(
|
||||
createDefaultStoreStepId,
|
||||
async (data: CreateDefaultStoreStepInput, { container }) => {
|
||||
const storeService = container.resolve(ModuleRegistrationName.STORE)
|
||||
|
||||
let shouldDelete = false
|
||||
let [store] = await storeService.list({}, { take: 1 })
|
||||
|
||||
if (!store) {
|
||||
store = await createStoresWorkflow(container).run({
|
||||
input: {
|
||||
stores: [
|
||||
{
|
||||
// TODO: Revisit for a more sophisticated approach
|
||||
...data.store,
|
||||
supported_currency_codes: ["usd"],
|
||||
default_currency_code: "usd",
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
shouldDelete = true
|
||||
}
|
||||
|
||||
return new StepResponse(store, { storeId: store.id, shouldDelete })
|
||||
},
|
||||
async (data, { container }) => {
|
||||
if (!data || !data.shouldDelete) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<IStoreModuleService>(
|
||||
ModuleRegistrationName.STORE
|
||||
)
|
||||
|
||||
await service.delete(data.storeId)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./create-default-store"
|
||||
@@ -0,0 +1,23 @@
|
||||
import { createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { createDefaultSalesChannelStep } from "../../sales-channel"
|
||||
import { createDefaultStoreStep } from "../steps/create-default-store"
|
||||
|
||||
export const createDefaultsWorkflowID = "create-defaults"
|
||||
export const createDefaultsWorkflow = createWorkflow(
|
||||
createDefaultsWorkflowID,
|
||||
(input) => {
|
||||
const salesChannel = createDefaultSalesChannelStep({
|
||||
data: {
|
||||
name: "Default Sales Channel",
|
||||
description: "Created by Medusa",
|
||||
},
|
||||
})
|
||||
const store = createDefaultStoreStep({
|
||||
store: {
|
||||
default_sales_channel_id: salesChannel.id,
|
||||
},
|
||||
})
|
||||
|
||||
return store
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./create-defaults"
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./steps"
|
||||
export * from "./workflows"
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { CreateShippingMethodDTO, ICartModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
shipping_methods: CreateShippingMethodDTO[]
|
||||
}
|
||||
|
||||
export const addShippingMethodToCartStepId = "add-shipping-method-to-cart-step"
|
||||
export const addShippingMethodToCartStep = createStep(
|
||||
addShippingMethodToCartStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const cartService = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const methods = await cartService.addShippingMethods(data.shipping_methods)
|
||||
|
||||
return new StepResponse(methods, methods)
|
||||
},
|
||||
async (methods, { container }) => {
|
||||
const cartService: ICartModuleService = container.resolve(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
if (!methods?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
await cartService.deleteShippingMethods(methods.map((m) => m.id))
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { CreateLineItemForCartDTO, ICartModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
items: CreateLineItemForCartDTO[]
|
||||
}
|
||||
|
||||
export const addToCartStepId = "add-to-cart-step"
|
||||
export const addToCartStep = createStep(
|
||||
addToCartStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const cartService = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const items = await cartService.addLineItems(data.items)
|
||||
|
||||
return new StepResponse(items, items)
|
||||
},
|
||||
async (createdLineItems, { container }) => {
|
||||
const cartService: ICartModuleService = container.resolve(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
if (!createdLineItems?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
await cartService.deleteLineItems(createdLineItems.map((c) => c.id))
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,47 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { IInventoryService } from "@medusajs/types"
|
||||
import { promiseAll } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
|
||||
interface StepInput {
|
||||
items: {
|
||||
inventory_item_id: string
|
||||
required_quantity: number
|
||||
quantity: number
|
||||
location_ids: string[]
|
||||
}[]
|
||||
}
|
||||
|
||||
export const confirmInventoryStepId = "confirm-inventory-step"
|
||||
export const confirmInventoryStep = createStep(
|
||||
confirmInventoryStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const inventoryService = container.resolve<IInventoryService>(
|
||||
ModuleRegistrationName.INVENTORY
|
||||
)
|
||||
|
||||
// TODO: Should be bulk
|
||||
const promises = data.items.map(async (item) => {
|
||||
const itemQuantity = item.required_quantity * item.quantity
|
||||
|
||||
return await inventoryService.confirmInventory(
|
||||
item.inventory_item_id,
|
||||
item.location_ids,
|
||||
itemQuantity
|
||||
)
|
||||
})
|
||||
|
||||
const inventoryCoverage = await promiseAll(promises)
|
||||
|
||||
if (inventoryCoverage.some((hasCoverage) => !hasCoverage)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
`Some variant does not have the required inventory`,
|
||||
MedusaError.Codes.INSUFFICIENT_INVENTORY
|
||||
)
|
||||
}
|
||||
|
||||
return new StepResponse(null)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { CreateCartDTO, ICartModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const createCartsStepId = "create-carts"
|
||||
export const createCartsStep = createStep(
|
||||
createCartsStepId,
|
||||
async (data: CreateCartDTO[], { container }) => {
|
||||
const service = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const createdCarts = await service.create(data)
|
||||
|
||||
return new StepResponse(
|
||||
createdCarts,
|
||||
createdCarts.map((cart) => cart.id)
|
||||
)
|
||||
},
|
||||
async (createdCartsIds, { container }) => {
|
||||
if (!createdCartsIds?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
await service.delete(createdCartsIds)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,41 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
CreateLineItemAdjustmentDTO,
|
||||
ICartModuleService,
|
||||
} from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
lineItemAdjustmentsToCreate: CreateLineItemAdjustmentDTO[]
|
||||
}
|
||||
|
||||
export const createLineItemAdjustmentsStepId = "create-line-item-adjustments"
|
||||
export const createLineItemAdjustmentsStep = createStep(
|
||||
createLineItemAdjustmentsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { lineItemAdjustmentsToCreate = [] } = data
|
||||
const cartModuleService: ICartModuleService = container.resolve(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const createdLineItemAdjustments =
|
||||
await cartModuleService.addLineItemAdjustments(
|
||||
lineItemAdjustmentsToCreate
|
||||
)
|
||||
|
||||
return new StepResponse(void 0, createdLineItemAdjustments)
|
||||
},
|
||||
async (createdLineItemAdjustments, { container }) => {
|
||||
const cartModuleService: ICartModuleService = container.resolve(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
if (!createdLineItemAdjustments?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
await cartModuleService.softDeleteLineItemAdjustments(
|
||||
createdLineItemAdjustments.map((c) => c.id)
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,57 @@
|
||||
import { CartWorkflowDTO } from "@medusajs/types"
|
||||
import { OrderStatus } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { createOrdersWorkflow } from "../../../order/workflows/create-orders"
|
||||
|
||||
interface StepInput {
|
||||
cart: CartWorkflowDTO
|
||||
}
|
||||
|
||||
export const createOrderFromCartStepId = "create-order-from-cart"
|
||||
export const createOrderFromCartStep = createStep(
|
||||
createOrderFromCartStepId,
|
||||
async (input: StepInput, { container }) => {
|
||||
const { cart } = input
|
||||
|
||||
const itemAdjustments = (cart.items || [])
|
||||
?.map((item) => item.adjustments || [])
|
||||
.flat(1)
|
||||
const shippingAdjustments = (cart.shipping_methods || [])
|
||||
?.map((sm) => sm.adjustments || [])
|
||||
.flat(1)
|
||||
|
||||
const promoCodes = [...itemAdjustments, ...shippingAdjustments]
|
||||
.map((adjustment) => adjustment.code)
|
||||
.filter((code) => Boolean) as string[]
|
||||
|
||||
const { transaction, result } = await createOrdersWorkflow(container).run({
|
||||
input: {
|
||||
region_id: cart.region?.id,
|
||||
customer_id: cart.customer?.id,
|
||||
sales_channel_id: cart.sales_channel_id,
|
||||
status: OrderStatus.PENDING,
|
||||
email: cart.email,
|
||||
currency_code: cart.currency_code,
|
||||
shipping_address: cart.shipping_address,
|
||||
billing_address: cart.billing_address,
|
||||
// TODO: This should be handle correctly
|
||||
no_notification: false,
|
||||
items: cart.items,
|
||||
shipping_methods: cart.shipping_methods,
|
||||
metadata: cart.metadata,
|
||||
promo_codes: promoCodes,
|
||||
},
|
||||
})
|
||||
|
||||
return new StepResponse(result, { transaction })
|
||||
},
|
||||
async (flow, { container }) => {
|
||||
if (!flow) {
|
||||
return
|
||||
}
|
||||
|
||||
await createOrdersWorkflow(container).cancel({
|
||||
transaction: flow.transaction,
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { BigNumberInput, IPaymentModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type StepInput = {
|
||||
region_id: string
|
||||
currency_code: string
|
||||
amount: BigNumberInput
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export const createPaymentCollectionsStepId = "create-payment-collections"
|
||||
export const createPaymentCollectionsStep = createStep(
|
||||
createPaymentCollectionsStepId,
|
||||
async (data: StepInput[], { container }) => {
|
||||
const service = container.resolve<IPaymentModuleService>(
|
||||
ModuleRegistrationName.PAYMENT
|
||||
)
|
||||
|
||||
const created = await service.createPaymentCollections(data)
|
||||
|
||||
return new StepResponse(
|
||||
created,
|
||||
created.map((collection) => collection.id)
|
||||
)
|
||||
},
|
||||
async (createdIds, { container }) => {
|
||||
if (!createdIds?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<IPaymentModuleService>(
|
||||
ModuleRegistrationName.PAYMENT
|
||||
)
|
||||
|
||||
await service.deletePaymentCollections(createdIds)
|
||||
}
|
||||
)
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
CreateShippingMethodAdjustmentDTO,
|
||||
ICartModuleService,
|
||||
} from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
shippingMethodAdjustmentsToCreate: CreateShippingMethodAdjustmentDTO[]
|
||||
}
|
||||
|
||||
export const createShippingMethodAdjustmentsStepId =
|
||||
"create-shipping-method-adjustments"
|
||||
export const createShippingMethodAdjustmentsStep = createStep(
|
||||
createShippingMethodAdjustmentsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { shippingMethodAdjustmentsToCreate = [] } = data
|
||||
const cartModuleService: ICartModuleService = container.resolve(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const createdShippingMethodAdjustments =
|
||||
await cartModuleService.addShippingMethodAdjustments(
|
||||
shippingMethodAdjustmentsToCreate
|
||||
)
|
||||
|
||||
return new StepResponse(void 0, createdShippingMethodAdjustments)
|
||||
},
|
||||
async (createdShippingMethodAdjustments, { container }) => {
|
||||
const cartModuleService: ICartModuleService = container.resolve(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
if (!createdShippingMethodAdjustments?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
await cartModuleService.softDeleteShippingMethodAdjustments(
|
||||
createdShippingMethodAdjustments.map((c) => c.id)
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { IRegionModuleService } from "@medusajs/types"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const findOneOrAnyRegionStepId = "find-one-or-any-region"
|
||||
export const findOneOrAnyRegionStep = createStep(
|
||||
findOneOrAnyRegionStepId,
|
||||
async (data: { regionId?: string }, { container }) => {
|
||||
const service = container.resolve<IRegionModuleService>(
|
||||
ModuleRegistrationName.REGION
|
||||
)
|
||||
|
||||
if (!data.regionId) {
|
||||
const regions = await service.list({})
|
||||
|
||||
if (!regions?.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"No regions found"
|
||||
)
|
||||
}
|
||||
|
||||
return new StepResponse(regions[0])
|
||||
}
|
||||
|
||||
const region = await service.retrieve(data.regionId)
|
||||
|
||||
return new StepResponse(region)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,93 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { CustomerDTO, ICustomerModuleService } from "@medusajs/types"
|
||||
import { validateEmail } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
customerId?: string | null
|
||||
email?: string | null
|
||||
}
|
||||
|
||||
interface StepOutput {
|
||||
customer?: CustomerDTO | null
|
||||
email?: string | null
|
||||
}
|
||||
|
||||
interface StepCompensateInput {
|
||||
customer?: CustomerDTO
|
||||
customerWasCreated: boolean
|
||||
}
|
||||
|
||||
export const findOrCreateCustomerStepId = "find-or-create-customer"
|
||||
export const findOrCreateCustomerStep = createStep(
|
||||
findOrCreateCustomerStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
if (
|
||||
typeof data.customerId === undefined &&
|
||||
typeof data.email === undefined
|
||||
) {
|
||||
return new StepResponse(
|
||||
{
|
||||
customer: undefined,
|
||||
email: undefined,
|
||||
},
|
||||
{ customerWasCreated: false }
|
||||
)
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
const customerData: StepOutput = {
|
||||
customer: null,
|
||||
email: null,
|
||||
}
|
||||
let customerWasCreated = false
|
||||
|
||||
if (data.customerId) {
|
||||
const customer = await service.retrieve(data.customerId)
|
||||
customerData.customer = customer
|
||||
customerData.email = customer.email
|
||||
|
||||
return new StepResponse(customerData, {
|
||||
customerWasCreated,
|
||||
})
|
||||
}
|
||||
|
||||
if (data.email) {
|
||||
const validatedEmail = validateEmail(data.email)
|
||||
|
||||
let [customer] = await service.list({
|
||||
email: validatedEmail,
|
||||
has_account: false,
|
||||
})
|
||||
|
||||
if (!customer) {
|
||||
customer = await service.create({ email: validatedEmail })
|
||||
customerWasCreated = true
|
||||
}
|
||||
|
||||
customerData.customer = customer
|
||||
customerData.email = customer.email
|
||||
}
|
||||
|
||||
return new StepResponse(customerData, {
|
||||
customer: customerData.customer,
|
||||
customerWasCreated,
|
||||
})
|
||||
},
|
||||
async (compData, { container }) => {
|
||||
const { customer, customerWasCreated } = compData as StepCompensateInput
|
||||
|
||||
if (!customerWasCreated || !customer?.id) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICustomerModuleService>(
|
||||
ModuleRegistrationName.CUSTOMER
|
||||
)
|
||||
|
||||
await service.delete(customer.id)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { ISalesChannelModuleService, SalesChannelDTO } from "@medusajs/types"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
salesChannelId?: string | null
|
||||
}
|
||||
|
||||
export const findSalesChannelStepId = "find-sales-channel"
|
||||
export const findSalesChannelStep = createStep(
|
||||
findSalesChannelStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const salesChannelService = container.resolve<ISalesChannelModuleService>(
|
||||
ModuleRegistrationName.SALES_CHANNEL
|
||||
)
|
||||
|
||||
if (data.salesChannelId === null) {
|
||||
return new StepResponse(null)
|
||||
}
|
||||
|
||||
let salesChannel: SalesChannelDTO | undefined
|
||||
if (data.salesChannelId) {
|
||||
salesChannel = await salesChannelService.retrieve(data.salesChannelId)
|
||||
} else {
|
||||
// TODO: Find default sales channel from store
|
||||
}
|
||||
|
||||
if (salesChannel?.is_disabled) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Unable to assign cart to disabled Sales Channel: ${salesChannel.name}`
|
||||
)
|
||||
}
|
||||
|
||||
return new StepResponse(salesChannel)
|
||||
}
|
||||
)
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import { LinkModuleUtils, ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { CartDTO, IPromotionModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
cart: CartDTO
|
||||
}
|
||||
|
||||
export const getActionsToComputeFromPromotionsStepId =
|
||||
"get-actions-to-compute-from-promotions"
|
||||
export const getActionsToComputeFromPromotionsStep = createStep(
|
||||
getActionsToComputeFromPromotionsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { cart } = data
|
||||
const remoteQuery = container.resolve(LinkModuleUtils.REMOTE_QUERY)
|
||||
const promotionService = container.resolve<IPromotionModuleService>(
|
||||
ModuleRegistrationName.PROMOTION
|
||||
)
|
||||
|
||||
const existingCartPromotionLinks = await remoteQuery({
|
||||
cart_promotion: {
|
||||
__args: { cart_id: [cart.id] },
|
||||
fields: ["id", "cart_id", "promotion_id", "deleted_at"],
|
||||
},
|
||||
})
|
||||
|
||||
const existingPromotions = await promotionService.list(
|
||||
{ id: existingCartPromotionLinks.map((l) => l.promotion_id) },
|
||||
{ take: null, select: ["code"] }
|
||||
)
|
||||
|
||||
const actionsToCompute = await promotionService.computeActions(
|
||||
existingPromotions.map((p) => p.code!),
|
||||
cart as any
|
||||
)
|
||||
|
||||
return new StepResponse(actionsToCompute)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,136 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
CartLineItemDTO,
|
||||
CartShippingMethodDTO,
|
||||
CartWorkflowDTO,
|
||||
ITaxModuleService,
|
||||
ItemTaxLineDTO,
|
||||
ShippingTaxLineDTO,
|
||||
TaxCalculationContext,
|
||||
TaxableItemDTO,
|
||||
TaxableShippingDTO,
|
||||
} from "@medusajs/types"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
cart: CartWorkflowDTO
|
||||
items: CartLineItemDTO[]
|
||||
shipping_methods: CartShippingMethodDTO[]
|
||||
force_tax_calculation?: boolean
|
||||
}
|
||||
|
||||
function normalizeTaxModuleContext(
|
||||
cart: CartWorkflowDTO,
|
||||
forceTaxCalculation: boolean
|
||||
): TaxCalculationContext | null {
|
||||
const address = cart.shipping_address
|
||||
const shouldCalculateTax = forceTaxCalculation || cart.region?.automatic_taxes
|
||||
|
||||
if (!shouldCalculateTax) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (forceTaxCalculation && !address?.country_code) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`country code is required to calculate taxes`
|
||||
)
|
||||
}
|
||||
|
||||
if (!address?.country_code) {
|
||||
return null
|
||||
}
|
||||
|
||||
const customer = cart.customer
|
||||
? {
|
||||
id: cart.customer.id,
|
||||
email: cart.customer.email,
|
||||
customer_groups: cart.customer.groups?.map((g) => g.id) || [],
|
||||
}
|
||||
: undefined
|
||||
|
||||
return {
|
||||
address: {
|
||||
country_code: address.country_code,
|
||||
province_code: address.province,
|
||||
address_1: address.address_1,
|
||||
address_2: address.address_2,
|
||||
city: address.city,
|
||||
postal_code: address.postal_code,
|
||||
},
|
||||
customer,
|
||||
// TODO: Should probably come in from order module, defaulting to false
|
||||
is_return: false,
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeLineItemsForTax(
|
||||
cart: CartWorkflowDTO,
|
||||
items: CartLineItemDTO[]
|
||||
): TaxableItemDTO[] {
|
||||
return items.map((item) => ({
|
||||
id: item.id,
|
||||
product_id: item.product_id!,
|
||||
product_name: item.variant_title,
|
||||
product_sku: item.variant_sku,
|
||||
product_type: item.product_type,
|
||||
product_type_id: item.product_type,
|
||||
quantity: item.quantity,
|
||||
unit_price: item.unit_price,
|
||||
currency_code: cart.currency_code,
|
||||
}))
|
||||
}
|
||||
|
||||
function normalizeLineItemsForShipping(
|
||||
cart: CartWorkflowDTO,
|
||||
shippingMethods: CartShippingMethodDTO[]
|
||||
): TaxableShippingDTO[] {
|
||||
return shippingMethods.map((shippingMethod) => ({
|
||||
id: shippingMethod.id,
|
||||
shipping_option_id: shippingMethod.shipping_option_id!,
|
||||
unit_price: shippingMethod.amount,
|
||||
currency_code: cart.currency_code,
|
||||
}))
|
||||
}
|
||||
|
||||
export const getItemTaxLinesStepId = "get-item-tax-lines"
|
||||
export const getItemTaxLinesStep = createStep(
|
||||
getItemTaxLinesStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const {
|
||||
cart,
|
||||
items,
|
||||
shipping_methods: shippingMethods,
|
||||
force_tax_calculation: forceTaxCalculation = false,
|
||||
} = data
|
||||
|
||||
const taxService = container.resolve<ITaxModuleService>(
|
||||
ModuleRegistrationName.TAX
|
||||
)
|
||||
|
||||
const taxContext = normalizeTaxModuleContext(cart, forceTaxCalculation)
|
||||
|
||||
if (!taxContext) {
|
||||
return new StepResponse({
|
||||
lineItemTaxLines: [],
|
||||
shippingMethodsTaxLines: [],
|
||||
})
|
||||
}
|
||||
|
||||
const lineItemTaxLines = (await taxService.getTaxLines(
|
||||
normalizeLineItemsForTax(cart, items),
|
||||
taxContext
|
||||
)) as ItemTaxLineDTO[]
|
||||
|
||||
const shippingMethodsTaxLines = (await taxService.getTaxLines(
|
||||
normalizeLineItemsForShipping(cart, shippingMethods),
|
||||
taxContext
|
||||
)) as ShippingTaxLineDTO[]
|
||||
|
||||
return new StepResponse({
|
||||
lineItemTaxLines,
|
||||
shippingMethodsTaxLines,
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,82 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { IPricingModuleService } from "@medusajs/types"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
variantIds: string[]
|
||||
context?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export const getVariantPriceSetsStepId = "get-variant-price-sets"
|
||||
export const getVariantPriceSetsStep = createStep(
|
||||
getVariantPriceSetsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
if (!data.variantIds.length) {
|
||||
return new StepResponse({})
|
||||
}
|
||||
|
||||
const pricingModuleService = container.resolve<IPricingModuleService>(
|
||||
ModuleRegistrationName.PRICING
|
||||
)
|
||||
|
||||
const remoteQuery = container.resolve("remoteQuery")
|
||||
|
||||
const variantPriceSets = await remoteQuery(
|
||||
{
|
||||
variant: {
|
||||
fields: ["id"],
|
||||
price_set: {
|
||||
fields: ["id"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: {
|
||||
id: data.variantIds,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const notFound: string[] = []
|
||||
const priceSetIds: string[] = []
|
||||
|
||||
variantPriceSets.forEach((v) => {
|
||||
if (v.price_set?.id) {
|
||||
priceSetIds.push(v.price_set.id)
|
||||
} else {
|
||||
notFound.push(v.id)
|
||||
}
|
||||
})
|
||||
|
||||
if (notFound.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Variants with IDs ${notFound.join(", ")} do not have a price`
|
||||
)
|
||||
}
|
||||
|
||||
const calculatedPriceSets = await pricingModuleService.calculatePrices(
|
||||
{ id: priceSetIds },
|
||||
{ context: data.context as Record<string, string | number> }
|
||||
)
|
||||
|
||||
const idToPriceSet = new Map<string, Record<string, any>>(
|
||||
calculatedPriceSets.map((p) => [p.id, p])
|
||||
)
|
||||
|
||||
const variantToCalculatedPriceSets = variantPriceSets.reduce(
|
||||
(acc, { id, price_set }) => {
|
||||
const calculatedPriceSet = idToPriceSet.get(price_set?.id)
|
||||
if (calculatedPriceSet) {
|
||||
acc[id] = calculatedPriceSet
|
||||
}
|
||||
|
||||
return acc
|
||||
},
|
||||
{}
|
||||
)
|
||||
|
||||
return new StepResponse(variantToCalculatedPriceSets)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
FilterableProductVariantProps,
|
||||
FindConfig,
|
||||
IProductModuleService,
|
||||
ProductVariantDTO,
|
||||
} from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
filter?: FilterableProductVariantProps
|
||||
config?: FindConfig<ProductVariantDTO>
|
||||
}
|
||||
|
||||
export const getVariantsStepId = "get-variants"
|
||||
export const getVariantsStep = createStep(
|
||||
getVariantsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const productModuleService = container.resolve<IProductModuleService>(
|
||||
ModuleRegistrationName.PRODUCT
|
||||
)
|
||||
|
||||
const variants = await productModuleService.listVariants(
|
||||
data.filter,
|
||||
data.config
|
||||
)
|
||||
|
||||
return new StepResponse(variants)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,25 @@
|
||||
export * from "./add-shipping-method-to-cart"
|
||||
export * from "./add-to-cart"
|
||||
export * from "./confirm-inventory"
|
||||
export * from "./create-carts"
|
||||
export * from "./create-line-item-adjustments"
|
||||
export * from "./create-order-from-cart"
|
||||
export * from "./create-shipping-method-adjustments"
|
||||
export * from "./find-one-or-any-region"
|
||||
export * from "./find-or-create-customer"
|
||||
export * from "./find-sales-channel"
|
||||
export * from "./get-actions-to-compute-from-promotions"
|
||||
export * from "./get-item-tax-lines"
|
||||
export * from "./get-variant-price-sets"
|
||||
export * from "./get-variants"
|
||||
export * from "./prepare-adjustments-from-promotion-actions"
|
||||
export * from "./refresh-cart-shipping-methods"
|
||||
export * from "./remove-line-item-adjustments"
|
||||
export * from "./remove-shipping-method-adjustments"
|
||||
export * from "./retrieve-cart"
|
||||
export * from "./retrieve-cart-with-links"
|
||||
export * from "./set-tax-lines-for-items"
|
||||
export * from "./update-cart-promotions"
|
||||
export * from "./update-carts"
|
||||
export * from "./validate-cart-shipping-options"
|
||||
export * from "./validate-variants-existence"
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type StepInput = {
|
||||
links: {
|
||||
cart_id: string
|
||||
payment_collection_id: string
|
||||
}[]
|
||||
}
|
||||
|
||||
export const linkCartAndPaymentCollectionsStepId =
|
||||
"link-cart-payment-collection"
|
||||
export const linkCartAndPaymentCollectionsStep = createStep(
|
||||
linkCartAndPaymentCollectionsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||
|
||||
const links = data.links.map((d) => ({
|
||||
[Modules.CART]: { cart_id: d.cart_id },
|
||||
[Modules.PAYMENT]: { payment_collection_id: d.payment_collection_id },
|
||||
}))
|
||||
|
||||
await remoteLink.create(links)
|
||||
|
||||
return new StepResponse(void 0, data)
|
||||
},
|
||||
async (data, { container }) => {
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
|
||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||
|
||||
const links = data.links.map((d) => ({
|
||||
[Modules.CART]: { cart_id: d.cart_id },
|
||||
[Modules.PAYMENT]: { payment_collection_id: d.payment_collection_id },
|
||||
}))
|
||||
|
||||
await remoteLink.dismiss(links)
|
||||
}
|
||||
)
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
AddItemAdjustmentAction,
|
||||
AddShippingMethodAdjustment,
|
||||
ComputeActions,
|
||||
IPromotionModuleService,
|
||||
PromotionDTO,
|
||||
RemoveItemAdjustmentAction,
|
||||
RemoveShippingMethodAdjustment,
|
||||
} from "@medusajs/types"
|
||||
import { ComputedActions } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
actions: ComputeActions[]
|
||||
}
|
||||
|
||||
export const prepareAdjustmentsFromPromotionActionsStepId =
|
||||
"prepare-adjustments-from-promotion-actions"
|
||||
export const prepareAdjustmentsFromPromotionActionsStep = createStep(
|
||||
prepareAdjustmentsFromPromotionActionsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const promotionModuleService: IPromotionModuleService = container.resolve(
|
||||
ModuleRegistrationName.PROMOTION
|
||||
)
|
||||
|
||||
const { actions = [] } = data
|
||||
const promotions = await promotionModuleService.list(
|
||||
{ code: actions.map((a) => a.code) },
|
||||
{ select: ["id", "code"] }
|
||||
)
|
||||
|
||||
const promotionsMap = new Map<string, PromotionDTO>(
|
||||
promotions.map((promotion) => [promotion.code!, promotion])
|
||||
)
|
||||
|
||||
const lineItemAdjustmentsToCreate = actions
|
||||
.filter((a) => a.action === ComputedActions.ADD_ITEM_ADJUSTMENT)
|
||||
.map((action) => ({
|
||||
code: action.code,
|
||||
amount: (action as AddItemAdjustmentAction).amount,
|
||||
item_id: (action as AddItemAdjustmentAction).item_id,
|
||||
promotion_id: promotionsMap.get(action.code)?.id,
|
||||
}))
|
||||
|
||||
const lineItemAdjustmentIdsToRemove = actions
|
||||
.filter((a) => a.action === ComputedActions.REMOVE_ITEM_ADJUSTMENT)
|
||||
.map((a) => (a as RemoveItemAdjustmentAction).adjustment_id)
|
||||
|
||||
const shippingMethodAdjustmentsToCreate = actions
|
||||
.filter(
|
||||
(a) => a.action === ComputedActions.ADD_SHIPPING_METHOD_ADJUSTMENT
|
||||
)
|
||||
.map((action) => ({
|
||||
code: action.code,
|
||||
amount: (action as AddShippingMethodAdjustment).amount,
|
||||
shipping_method_id: (action as AddShippingMethodAdjustment)
|
||||
.shipping_method_id,
|
||||
promotion_id: promotionsMap.get(action.code)?.id,
|
||||
}))
|
||||
|
||||
const shippingMethodAdjustmentIdsToRemove = actions
|
||||
.filter(
|
||||
(a) => a.action === ComputedActions.REMOVE_SHIPPING_METHOD_ADJUSTMENT
|
||||
)
|
||||
.map((a) => (a as RemoveShippingMethodAdjustment).adjustment_id)
|
||||
|
||||
return new StepResponse({
|
||||
lineItemAdjustmentsToCreate,
|
||||
lineItemAdjustmentIdsToRemove,
|
||||
shippingMethodAdjustmentsToCreate,
|
||||
shippingMethodAdjustmentIdsToRemove,
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
import { PromotionActions } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { updateCartPromotionsWorkflow } from "../workflows"
|
||||
|
||||
interface StepInput {
|
||||
id: string
|
||||
promo_codes?: string[]
|
||||
action?:
|
||||
| PromotionActions.ADD
|
||||
| PromotionActions.REMOVE
|
||||
| PromotionActions.REPLACE
|
||||
}
|
||||
|
||||
export const refreshCartPromotionsStepId = "refresh-cart-promotions"
|
||||
export const refreshCartPromotionsStep = createStep(
|
||||
refreshCartPromotionsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { promo_codes = [], id, action = PromotionActions.ADD } = data
|
||||
|
||||
await updateCartPromotionsWorkflow(container).run({
|
||||
input: {
|
||||
action,
|
||||
promoCodes: promo_codes,
|
||||
cartId: id,
|
||||
},
|
||||
})
|
||||
|
||||
return new StepResponse(null)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,75 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
CartDTO,
|
||||
ICartModuleService,
|
||||
IFulfillmentModuleService,
|
||||
} from "@medusajs/types"
|
||||
import { arrayDifference } from "@medusajs/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
cart: CartDTO
|
||||
}
|
||||
|
||||
export const refreshCartShippingMethodsStepId = "refresh-cart-shipping-methods"
|
||||
export const refreshCartShippingMethodsStep = createStep(
|
||||
refreshCartShippingMethodsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { cart } = data
|
||||
const { shipping_methods: shippingMethods = [] } = cart
|
||||
|
||||
if (!shippingMethods?.length) {
|
||||
return new StepResponse(void 0, [])
|
||||
}
|
||||
|
||||
const fulfillmentModule = container.resolve<IFulfillmentModuleService>(
|
||||
ModuleRegistrationName.FULFILLMENT
|
||||
)
|
||||
|
||||
const cartModule = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const shippingOptionIds: string[] = shippingMethods.map(
|
||||
(sm) => sm.shipping_option_id!
|
||||
)
|
||||
|
||||
const validShippingOptions =
|
||||
await fulfillmentModule.listShippingOptionsForContext(
|
||||
{
|
||||
id: shippingOptionIds,
|
||||
context: { ...cart },
|
||||
address: {
|
||||
country_code: cart.shipping_address?.country_code,
|
||||
province_code: cart.shipping_address?.province,
|
||||
city: cart.shipping_address?.city,
|
||||
postal_expression: cart.shipping_address?.postal_code,
|
||||
},
|
||||
},
|
||||
{ relations: ["rules"] }
|
||||
)
|
||||
|
||||
const validShippingOptionIds = validShippingOptions.map((o) => o.id)
|
||||
const invalidShippingOptionIds = arrayDifference(
|
||||
shippingOptionIds,
|
||||
validShippingOptionIds
|
||||
)
|
||||
|
||||
const shippingMethodsToDelete = shippingMethods
|
||||
.filter((sm) => invalidShippingOptionIds.includes(sm.shipping_option_id!))
|
||||
.map((sm) => sm.id)
|
||||
|
||||
await cartModule.softDeleteShippingMethods(shippingMethodsToDelete)
|
||||
|
||||
return new StepResponse(void 0, shippingMethodsToDelete)
|
||||
},
|
||||
async (shippingMethodsToRestore, { container }) => {
|
||||
if (shippingMethodsToRestore?.length) {
|
||||
const cartModule = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
await cartModule.restoreShippingMethods(shippingMethodsToRestore)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,37 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { ICartModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
lineItemAdjustmentIdsToRemove: string[]
|
||||
}
|
||||
|
||||
export const removeLineItemAdjustmentsStepId = "remove-line-item-adjustments"
|
||||
export const removeLineItemAdjustmentsStep = createStep(
|
||||
removeLineItemAdjustmentsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { lineItemAdjustmentIdsToRemove = [] } = data
|
||||
const cartModuleService: ICartModuleService = container.resolve(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
await cartModuleService.softDeleteLineItemAdjustments(
|
||||
lineItemAdjustmentIdsToRemove
|
||||
)
|
||||
|
||||
return new StepResponse(void 0, lineItemAdjustmentIdsToRemove)
|
||||
},
|
||||
async (lineItemAdjustmentIdsToRemove, { container }) => {
|
||||
const cartModuleService: ICartModuleService = container.resolve(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
if (!lineItemAdjustmentIdsToRemove?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
await cartModuleService.restoreLineItemAdjustments(
|
||||
lineItemAdjustmentIdsToRemove
|
||||
)
|
||||
}
|
||||
)
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { ICartModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
shippingMethodAdjustmentIdsToRemove: string[]
|
||||
}
|
||||
|
||||
export const removeShippingMethodAdjustmentsStepId =
|
||||
"remove-shipping-method-adjustments"
|
||||
export const removeShippingMethodAdjustmentsStep = createStep(
|
||||
removeShippingMethodAdjustmentsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { shippingMethodAdjustmentIdsToRemove = [] } = data
|
||||
const cartModuleService: ICartModuleService = container.resolve(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
await cartModuleService.softDeleteShippingMethodAdjustments(
|
||||
shippingMethodAdjustmentIdsToRemove
|
||||
)
|
||||
|
||||
return new StepResponse(void 0, shippingMethodAdjustmentIdsToRemove)
|
||||
},
|
||||
async (shippingMethodAdjustmentIdsToRemove, { container }) => {
|
||||
const cartModuleService: ICartModuleService = container.resolve(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
if (!shippingMethodAdjustmentIdsToRemove?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
await cartModuleService.restoreShippingMethodAdjustments(
|
||||
shippingMethodAdjustmentIdsToRemove
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,32 @@
|
||||
import { LinkModuleUtils, Modules } from "@medusajs/modules-sdk"
|
||||
import { CartWorkflowDTO } from "@medusajs/types"
|
||||
import { isObject, remoteQueryObjectFromString } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
cart_or_cart_id: string | CartWorkflowDTO
|
||||
fields: string[]
|
||||
}
|
||||
|
||||
export const retrieveCartWithLinksStepId = "retrieve-cart-with-links"
|
||||
export const retrieveCartWithLinksStep = createStep(
|
||||
retrieveCartWithLinksStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { cart_or_cart_id: cartOrCartId, fields } = data
|
||||
|
||||
if (isObject(cartOrCartId)) {
|
||||
return new StepResponse(cartOrCartId)
|
||||
}
|
||||
|
||||
const id = cartOrCartId
|
||||
const remoteQuery = container.resolve(LinkModuleUtils.REMOTE_QUERY)
|
||||
const query = remoteQueryObjectFromString({
|
||||
entryPoint: Modules.CART,
|
||||
fields,
|
||||
})
|
||||
|
||||
const [cart] = await remoteQuery(query, { cart: { id } })
|
||||
|
||||
return new StepResponse(cart)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,37 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { CartDTO, FindConfig, ICartModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
id: string
|
||||
config?: FindConfig<CartDTO>
|
||||
}
|
||||
|
||||
export const retrieveCartStepId = "retrieve-cart"
|
||||
export const retrieveCartStep = createStep(
|
||||
retrieveCartStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const cartModuleService = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const cart = await cartModuleService.retrieve(data.id, data.config)
|
||||
|
||||
// TODO: remove this when cart handles totals calculation
|
||||
cart.items = cart.items?.map((item) => {
|
||||
item.subtotal = item.unit_price
|
||||
|
||||
return item
|
||||
})
|
||||
|
||||
// TODO: remove this when cart handles totals calculation
|
||||
cart.shipping_methods = cart.shipping_methods?.map((shipping_method) => {
|
||||
// TODO: should we align all amounts/prices fields to be unit_price?
|
||||
shipping_method.subtotal = shipping_method.amount
|
||||
|
||||
return shipping_method
|
||||
})
|
||||
|
||||
return new StepResponse(cart)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,128 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
CartWorkflowDTO,
|
||||
CreateLineItemTaxLineDTO,
|
||||
CreateShippingMethodTaxLineDTO,
|
||||
ICartModuleService,
|
||||
ItemTaxLineDTO,
|
||||
ShippingTaxLineDTO,
|
||||
} from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
cart: CartWorkflowDTO
|
||||
item_tax_lines: ItemTaxLineDTO[]
|
||||
shipping_tax_lines: ShippingTaxLineDTO[]
|
||||
}
|
||||
|
||||
export const setTaxLinesForItemsStepId = "set-tax-lines-for-items"
|
||||
export const setTaxLinesForItemsStep = createStep(
|
||||
setTaxLinesForItemsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { cart, item_tax_lines, shipping_tax_lines } = data
|
||||
const cartService = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const getShippingTaxLinesPromise =
|
||||
await cartService.listShippingMethodTaxLines({
|
||||
shipping_method_id: shipping_tax_lines.map((t) => t.shipping_line_id),
|
||||
})
|
||||
|
||||
const getItemTaxLinesPromise = await cartService.listLineItemTaxLines({
|
||||
item_id: item_tax_lines.map((t) => t.line_item_id),
|
||||
})
|
||||
|
||||
const itemsTaxLinesData = normalizeItemTaxLinesForCart(item_tax_lines)
|
||||
const setItemTaxLinesPromise = itemsTaxLinesData.length
|
||||
? cartService.setLineItemTaxLines(cart.id, itemsTaxLinesData)
|
||||
: 0
|
||||
|
||||
const shippingTaxLinesData =
|
||||
normalizeShippingTaxLinesForCart(shipping_tax_lines)
|
||||
const setShippingTaxLinesPromise = shippingTaxLinesData.length
|
||||
? await cartService.setShippingMethodTaxLines(
|
||||
cart.id,
|
||||
shippingTaxLinesData
|
||||
)
|
||||
: 0
|
||||
|
||||
const [existingShippingMethodTaxLines, existingLineItemTaxLines] =
|
||||
await Promise.all([
|
||||
getShippingTaxLinesPromise,
|
||||
getItemTaxLinesPromise,
|
||||
setItemTaxLinesPromise,
|
||||
setShippingTaxLinesPromise,
|
||||
])
|
||||
|
||||
return new StepResponse(null, {
|
||||
cart,
|
||||
existingLineItemTaxLines,
|
||||
existingShippingMethodTaxLines,
|
||||
})
|
||||
},
|
||||
async (revertData, { container }) => {
|
||||
if (!revertData) {
|
||||
return
|
||||
}
|
||||
|
||||
const { cart, existingLineItemTaxLines, existingShippingMethodTaxLines } =
|
||||
revertData
|
||||
|
||||
const cartService = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
if (existingLineItemTaxLines) {
|
||||
await cartService.setLineItemTaxLines(
|
||||
cart.id,
|
||||
existingLineItemTaxLines.map((taxLine) => ({
|
||||
description: taxLine.description,
|
||||
tax_rate_id: taxLine.tax_rate_id,
|
||||
code: taxLine.code,
|
||||
rate: taxLine.rate,
|
||||
provider_id: taxLine.provider_id,
|
||||
item_id: taxLine.item_id,
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
await cartService.setShippingMethodTaxLines(
|
||||
cart.id,
|
||||
existingShippingMethodTaxLines.map((taxLine) => ({
|
||||
description: taxLine.description,
|
||||
tax_rate_id: taxLine.tax_rate_id,
|
||||
code: taxLine.code,
|
||||
rate: taxLine.rate,
|
||||
provider_id: taxLine.provider_id,
|
||||
shipping_method_id: taxLine.shipping_method_id,
|
||||
}))
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
function normalizeItemTaxLinesForCart(
|
||||
taxLines: ItemTaxLineDTO[]
|
||||
): CreateLineItemTaxLineDTO[] {
|
||||
return taxLines.map((taxLine) => ({
|
||||
description: taxLine.name,
|
||||
tax_rate_id: taxLine.rate_id,
|
||||
code: taxLine.code!,
|
||||
rate: taxLine.rate!,
|
||||
provider_id: taxLine.provider_id,
|
||||
item_id: taxLine.line_item_id,
|
||||
}))
|
||||
}
|
||||
|
||||
function normalizeShippingTaxLinesForCart(
|
||||
taxLines: ShippingTaxLineDTO[]
|
||||
): CreateShippingMethodTaxLineDTO[] {
|
||||
return taxLines.map((taxLine) => ({
|
||||
description: taxLine.name,
|
||||
tax_rate_id: taxLine.rate_id,
|
||||
code: taxLine.code!,
|
||||
rate: taxLine.rate!,
|
||||
provider_id: taxLine.provider_id,
|
||||
shipping_method_id: taxLine.shipping_line_id,
|
||||
}))
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import {
|
||||
LinkModuleUtils,
|
||||
ModuleRegistrationName,
|
||||
Modules,
|
||||
} from "@medusajs/modules-sdk"
|
||||
import { IPromotionModuleService } from "@medusajs/types"
|
||||
import { PromotionActions } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
id: string
|
||||
promo_codes?: string[]
|
||||
action?:
|
||||
| PromotionActions.ADD
|
||||
| PromotionActions.REMOVE
|
||||
| PromotionActions.REPLACE
|
||||
}
|
||||
|
||||
export const updateCartPromotionsStepId = "update-cart-promotions"
|
||||
export const updateCartPromotionsStep = createStep(
|
||||
updateCartPromotionsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { promo_codes = [], id, action = PromotionActions.ADD } = data
|
||||
|
||||
const remoteLink = container.resolve(LinkModuleUtils.REMOTE_LINK)
|
||||
const remoteQuery = container.resolve(LinkModuleUtils.REMOTE_QUERY)
|
||||
const promotionService = container.resolve<IPromotionModuleService>(
|
||||
ModuleRegistrationName.PROMOTION
|
||||
)
|
||||
|
||||
const existingCartPromotionLinks = await remoteQuery({
|
||||
cart_promotion: {
|
||||
__args: { cart_id: [id] },
|
||||
fields: ["cart_id", "promotion_id"],
|
||||
},
|
||||
})
|
||||
|
||||
const promotionLinkMap = new Map<string, any>(
|
||||
existingCartPromotionLinks.map((link) => [link.promotion_id, link])
|
||||
)
|
||||
|
||||
const promotions = await promotionService.list(
|
||||
{ code: promo_codes },
|
||||
{ select: ["id"] }
|
||||
)
|
||||
|
||||
const linksToCreate: any[] = []
|
||||
const linksToDismiss: any[] = []
|
||||
|
||||
for (const promotion of promotions) {
|
||||
const linkObject = {
|
||||
[Modules.CART]: { cart_id: id },
|
||||
[Modules.PROMOTION]: { promotion_id: promotion.id },
|
||||
}
|
||||
|
||||
if ([PromotionActions.ADD, PromotionActions.REPLACE].includes(action)) {
|
||||
linksToCreate.push(linkObject)
|
||||
}
|
||||
|
||||
if (action === PromotionActions.REMOVE) {
|
||||
const link = promotionLinkMap.get(promotion.id)
|
||||
|
||||
if (link) {
|
||||
linksToDismiss.push(linkObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (action === PromotionActions.REPLACE) {
|
||||
for (const link of existingCartPromotionLinks) {
|
||||
linksToDismiss.push({
|
||||
[Modules.CART]: { cart_id: link.cart_id },
|
||||
[Modules.PROMOTION]: { promotion_id: link.promotion_id },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const linksToDismissPromise = linksToDismiss.length
|
||||
? remoteLink.dismiss(linksToDismiss)
|
||||
: []
|
||||
|
||||
const linksToCreatePromise = linksToCreate.length
|
||||
? remoteLink.create(linksToCreate)
|
||||
: []
|
||||
|
||||
const [_, createdLinks] = await Promise.all([
|
||||
linksToDismissPromise,
|
||||
linksToCreatePromise,
|
||||
])
|
||||
|
||||
return new StepResponse(null, {
|
||||
createdLinkIds: createdLinks.map((link) => link.id),
|
||||
dismissedLinks: linksToDismiss,
|
||||
})
|
||||
},
|
||||
async (revertData, { container }) => {
|
||||
const remoteLink = container.resolve(LinkModuleUtils.REMOTE_LINK)
|
||||
|
||||
if (revertData?.dismissedLinks?.length) {
|
||||
await remoteLink.create(revertData.dismissedLinks)
|
||||
}
|
||||
|
||||
if (revertData?.createdLinkIds?.length) {
|
||||
await remoteLink.delete(revertData.createdLinkIds)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,53 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
ICartModuleService,
|
||||
UpdateCartDTO,
|
||||
UpdateCartWorkflowInputDTO,
|
||||
} from "@medusajs/types"
|
||||
import { getSelectsAndRelationsFromObjectArray } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const updateCartsStepId = "update-carts"
|
||||
export const updateCartsStep = createStep(
|
||||
updateCartsStepId,
|
||||
async (data: UpdateCartWorkflowInputDTO[], { container }) => {
|
||||
const cartModule = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const { selects, relations } = getSelectsAndRelationsFromObjectArray(data)
|
||||
const cartsBeforeUpdate = await cartModule.list(
|
||||
{ id: data.map((d) => d.id) },
|
||||
{ select: selects, relations }
|
||||
)
|
||||
|
||||
const updatedCart = await cartModule.update(data)
|
||||
|
||||
return new StepResponse(updatedCart, cartsBeforeUpdate)
|
||||
},
|
||||
async (cartsBeforeUpdate, { container }) => {
|
||||
if (!cartsBeforeUpdate) {
|
||||
return
|
||||
}
|
||||
|
||||
const cartModule = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const dataToUpdate: UpdateCartDTO[] = []
|
||||
|
||||
for (const cart of cartsBeforeUpdate) {
|
||||
dataToUpdate.push({
|
||||
id: cart.id,
|
||||
region_id: cart.region_id,
|
||||
customer_id: cart.customer_id,
|
||||
sales_channel_id: cart.sales_channel_id,
|
||||
email: cart.email,
|
||||
currency_code: cart.currency_code,
|
||||
metadata: cart.metadata,
|
||||
})
|
||||
}
|
||||
|
||||
return await cartModule.update(dataToUpdate)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,35 @@
|
||||
import {
|
||||
CartLineItemDTO,
|
||||
CartShippingMethodDTO,
|
||||
CartWorkflowDTO,
|
||||
} from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { updateTaxLinesWorkflow } from "../workflows"
|
||||
|
||||
interface StepInput {
|
||||
cart_or_cart_id: CartWorkflowDTO | string
|
||||
items?: CartLineItemDTO[]
|
||||
shipping_methods?: CartShippingMethodDTO[]
|
||||
force_tax_calculation?: boolean
|
||||
}
|
||||
|
||||
export const updateTaxLinesStepId = "update-tax-lines-step"
|
||||
export const updateTaxLinesStep = createStep(
|
||||
updateTaxLinesStepId,
|
||||
async (input: StepInput, { container }) => {
|
||||
const { transaction } = await updateTaxLinesWorkflow(container).run({
|
||||
input,
|
||||
})
|
||||
|
||||
return new StepResponse(null, { transaction })
|
||||
},
|
||||
async (flow, { container }) => {
|
||||
if (!flow) {
|
||||
return
|
||||
}
|
||||
|
||||
await updateTaxLinesWorkflow(container).cancel({
|
||||
transaction: flow.transaction,
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,53 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { CartDTO, IFulfillmentModuleService } from "@medusajs/types"
|
||||
import { arrayDifference, MedusaError } from "@medusajs/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
cart: CartDTO
|
||||
option_ids: string[]
|
||||
}
|
||||
|
||||
export const validateCartShippingOptionsStepId =
|
||||
"validate-cart-shipping-options"
|
||||
export const validateCartShippingOptionsStep = createStep(
|
||||
validateCartShippingOptionsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { option_ids: optionIds = [], cart } = data
|
||||
|
||||
if (!optionIds.length) {
|
||||
return new StepResponse(void 0)
|
||||
}
|
||||
|
||||
const fulfillmentModule = container.resolve<IFulfillmentModuleService>(
|
||||
ModuleRegistrationName.FULFILLMENT
|
||||
)
|
||||
|
||||
const validShippingOptions =
|
||||
await fulfillmentModule.listShippingOptionsForContext(
|
||||
{
|
||||
id: optionIds,
|
||||
context: { ...cart },
|
||||
address: {
|
||||
country_code: cart.shipping_address?.country_code,
|
||||
province_code: cart.shipping_address?.province,
|
||||
city: cart.shipping_address?.city,
|
||||
postal_expression: cart.shipping_address?.postal_code,
|
||||
},
|
||||
},
|
||||
{ relations: ["rules"] }
|
||||
)
|
||||
|
||||
const validShippingOptionIds = validShippingOptions.map((o) => o.id)
|
||||
const invalidOptionIds = arrayDifference(optionIds, validShippingOptionIds)
|
||||
|
||||
if (invalidOptionIds.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Shipping Options are invalid for cart.`
|
||||
)
|
||||
}
|
||||
|
||||
return new StepResponse(void 0)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { IProductModuleService } from "@medusajs/types"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
variantIds: string[]
|
||||
}
|
||||
|
||||
export const validateVariantsExistStepId = "validate-variants-exist"
|
||||
export const validateVariantsExistStep = createStep(
|
||||
validateVariantsExistStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const productModuleService = container.resolve<IProductModuleService>(
|
||||
ModuleRegistrationName.PRODUCT
|
||||
)
|
||||
|
||||
const variants = await productModuleService.listVariants(
|
||||
{ id: data.variantIds },
|
||||
{ select: ["id"] }
|
||||
)
|
||||
|
||||
const variantIdToData = new Set(variants.map((v) => v.id))
|
||||
|
||||
const notFoundVariants = new Set(
|
||||
[...data.variantIds].filter((x) => !variantIdToData.has(x))
|
||||
)
|
||||
|
||||
if (notFoundVariants.size) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Variants with IDs ${[...notFoundVariants].join(", ")} do not exist`
|
||||
)
|
||||
}
|
||||
|
||||
return new StepResponse(Array.from(variants.map((v) => v.id)))
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,52 @@
|
||||
export const cartFieldsForRefreshSteps = [
|
||||
"region_id",
|
||||
"currency_code",
|
||||
"region.*",
|
||||
"items.*",
|
||||
"items.tax_lines.*",
|
||||
"shipping_address.*",
|
||||
"shipping_methods.*",
|
||||
"shipping_methods.tax_lines*",
|
||||
"customer.*",
|
||||
"customer.groups.*",
|
||||
]
|
||||
|
||||
export const completeCartFields = [
|
||||
"id",
|
||||
"currency_code",
|
||||
"email",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"total",
|
||||
"subtotal",
|
||||
"tax_total",
|
||||
"discount_total",
|
||||
"discount_tax_total",
|
||||
"original_total",
|
||||
"original_tax_total",
|
||||
"item_total",
|
||||
"item_subtotal",
|
||||
"item_tax_total",
|
||||
"sales_channel_id",
|
||||
"original_item_total",
|
||||
"original_item_subtotal",
|
||||
"original_item_tax_total",
|
||||
"shipping_total",
|
||||
"shipping_subtotal",
|
||||
"shipping_tax_total",
|
||||
"original_shipping_tax_total",
|
||||
"original_shipping_tax_subtotal",
|
||||
"original_shipping_total",
|
||||
"items.*",
|
||||
"items.tax_lines.*",
|
||||
"items.adjustments.*",
|
||||
"customer.*",
|
||||
"shipping_methods.*",
|
||||
"shipping_methods.tax_lines.*",
|
||||
"shipping_methods.adjustments.*",
|
||||
"shipping_address.*",
|
||||
"billing_address.*",
|
||||
"region.*",
|
||||
"payment_collection.*",
|
||||
"payment_collection.payment_sessions.*",
|
||||
]
|
||||
@@ -0,0 +1,66 @@
|
||||
import { BigNumberInput } from "@medusajs/types"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
|
||||
interface ConfirmInventoryPreparationInput {
|
||||
product_variant_inventory_items: {
|
||||
variant_id: string
|
||||
inventory_item_id: string
|
||||
required_quantity: number
|
||||
}[]
|
||||
items: { variant_id?: string; quantity: BigNumberInput }[]
|
||||
variants: { id: string; manage_inventory?: boolean }[]
|
||||
location_ids: string[]
|
||||
}
|
||||
|
||||
interface ConfirmInventoryItem {
|
||||
inventory_item_id: string
|
||||
required_quantity: number
|
||||
quantity: number
|
||||
location_ids: string[]
|
||||
}
|
||||
|
||||
export const prepareConfirmInventoryInput = ({
|
||||
product_variant_inventory_items,
|
||||
location_ids,
|
||||
items,
|
||||
variants,
|
||||
}: ConfirmInventoryPreparationInput) => {
|
||||
if (!product_variant_inventory_items.length) {
|
||||
return []
|
||||
}
|
||||
|
||||
const variantsMap = new Map<
|
||||
string,
|
||||
{ id: string; manage_inventory?: boolean }
|
||||
>(variants.map((v) => [v.id, v]))
|
||||
|
||||
const itemsToConfirm: ConfirmInventoryItem[] = []
|
||||
|
||||
items.forEach((item) => {
|
||||
const variant = variantsMap.get(item.variant_id!)
|
||||
|
||||
if (!variant?.manage_inventory) {
|
||||
return
|
||||
}
|
||||
|
||||
const variantInventoryItem = product_variant_inventory_items.find(
|
||||
(i) => i.variant_id === item.variant_id
|
||||
)
|
||||
|
||||
if (!variantInventoryItem) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Variant ${item.variant_id} does not have any inventory items associated with it.`
|
||||
)
|
||||
}
|
||||
|
||||
itemsToConfirm.push({
|
||||
inventory_item_id: variantInventoryItem.inventory_item_id,
|
||||
required_quantity: variantInventoryItem.required_quantity,
|
||||
quantity: item.quantity as number, // TODO: update type to BigNumberInput
|
||||
location_ids: location_ids,
|
||||
})
|
||||
})
|
||||
|
||||
return itemsToConfirm
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import {
|
||||
BigNumberInput,
|
||||
CreateOrderAdjustmentDTO,
|
||||
CreateOrderLineItemTaxLineDTO,
|
||||
ProductVariantDTO,
|
||||
} from "@medusajs/types"
|
||||
|
||||
interface Input {
|
||||
quantity: BigNumberInput
|
||||
metadata?: Record<string, any>
|
||||
unitPrice: BigNumberInput
|
||||
variant: ProductVariantDTO
|
||||
taxLines?: CreateOrderLineItemTaxLineDTO[]
|
||||
adjustments?: CreateOrderAdjustmentDTO[]
|
||||
cartId?: string
|
||||
}
|
||||
|
||||
export function prepareLineItemData(data: Input) {
|
||||
const {
|
||||
variant,
|
||||
unitPrice,
|
||||
quantity,
|
||||
metadata,
|
||||
cartId,
|
||||
taxLines,
|
||||
adjustments,
|
||||
} = data
|
||||
|
||||
if (!variant.product) {
|
||||
throw new Error("Variant does not have a product")
|
||||
}
|
||||
|
||||
const lineItem: any = {
|
||||
quantity,
|
||||
title: variant.title,
|
||||
|
||||
subtitle: variant.product.title,
|
||||
thumbnail: variant.product.thumbnail,
|
||||
|
||||
product_id: variant.product.id,
|
||||
product_title: variant.product.title,
|
||||
product_description: variant.product.description,
|
||||
product_subtitle: variant.product.subtitle,
|
||||
product_type: variant.product.type?.[0].value ?? null,
|
||||
product_collection: variant.product.collection?.[0]?.value ?? null,
|
||||
product_handle: variant.product.handle,
|
||||
|
||||
variant_id: variant.id,
|
||||
variant_sku: variant.sku,
|
||||
variant_barcode: variant.barcode,
|
||||
variant_title: variant.title,
|
||||
|
||||
unit_price: unitPrice,
|
||||
metadata,
|
||||
}
|
||||
|
||||
if (taxLines) {
|
||||
lineItem.tax_lines = prepareTaxLinesData(taxLines)
|
||||
}
|
||||
|
||||
if (adjustments) {
|
||||
lineItem.adjustments = prepareAdjustmentsData(adjustments)
|
||||
}
|
||||
|
||||
if (cartId) {
|
||||
lineItem.cart_id = cartId
|
||||
}
|
||||
|
||||
return lineItem
|
||||
}
|
||||
|
||||
export function prepareTaxLinesData(data: CreateOrderLineItemTaxLineDTO[]) {
|
||||
return data.map((d) => ({
|
||||
description: d.description,
|
||||
tax_rate_id: d.tax_rate_id,
|
||||
code: d.code,
|
||||
rate: d.rate,
|
||||
provider_id: d.provider_id,
|
||||
}))
|
||||
}
|
||||
|
||||
export function prepareAdjustmentsData(data: CreateOrderAdjustmentDTO[]) {
|
||||
return data.map((d) => ({
|
||||
code: d.code,
|
||||
amount: d.amount,
|
||||
description: d.description,
|
||||
promotion_id: d.promotion_id,
|
||||
provider_id: d.promotion_id,
|
||||
}))
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common/steps/use-remote-query"
|
||||
import {
|
||||
addShippingMethodToCartStep,
|
||||
validateCartShippingOptionsStep,
|
||||
} from "../steps"
|
||||
import { refreshCartPromotionsStep } from "../steps/refresh-cart-promotions"
|
||||
import { updateTaxLinesStep } from "../steps/update-tax-lines"
|
||||
import { cartFieldsForRefreshSteps } from "../utils/fields"
|
||||
|
||||
interface AddShippingMethodToCartWorkflowInput {
|
||||
cart_id: string
|
||||
options: {
|
||||
id: string
|
||||
data?: Record<string, unknown>
|
||||
}[]
|
||||
}
|
||||
|
||||
export const addShippingMethodToCartWorkflowId = "add-shipping-method-to-cart"
|
||||
export const addShippingMethodToWorkflow = createWorkflow(
|
||||
addShippingMethodToCartWorkflowId,
|
||||
(
|
||||
input: WorkflowData<AddShippingMethodToCartWorkflowInput>
|
||||
): WorkflowData<void> => {
|
||||
const cart = useRemoteQueryStep({
|
||||
entry_point: "cart",
|
||||
fields: cartFieldsForRefreshSteps,
|
||||
variables: { id: input.cart_id },
|
||||
list: false,
|
||||
})
|
||||
|
||||
const optionIds = transform({ input }, (data) => {
|
||||
return (data.input.options ?? []).map((i) => i.id)
|
||||
})
|
||||
|
||||
validateCartShippingOptionsStep({
|
||||
option_ids: optionIds,
|
||||
cart,
|
||||
})
|
||||
|
||||
const shippingOptions = useRemoteQueryStep({
|
||||
entry_point: "shipping_option",
|
||||
fields: ["id", "name", "calculated_price.calculated_amount"],
|
||||
variables: {
|
||||
id: optionIds,
|
||||
calculated_price: {
|
||||
context: { currency_code: cart.currency_code },
|
||||
},
|
||||
},
|
||||
}).config({ name: "fetch-shipping-option" })
|
||||
|
||||
const shippingMethodInput = transform(
|
||||
{ input, shippingOptions },
|
||||
(data) => {
|
||||
const options = (data.input.options ?? []).map((option) => {
|
||||
const shippingOption = data.shippingOptions.find(
|
||||
(so) => so.id === option.id
|
||||
)!
|
||||
|
||||
return {
|
||||
shipping_option_id: shippingOption.id,
|
||||
amount: shippingOption.calculated_price.calculated_amount,
|
||||
data: option.data ?? {},
|
||||
name: shippingOption.name,
|
||||
cart_id: data.input.cart_id,
|
||||
}
|
||||
})
|
||||
|
||||
return options
|
||||
}
|
||||
)
|
||||
|
||||
const shippingMethods = addShippingMethodToCartStep({
|
||||
shipping_methods: shippingMethodInput,
|
||||
})
|
||||
refreshCartPromotionsStep({ id: input.cart_id })
|
||||
updateTaxLinesStep({
|
||||
cart_or_cart_id: input.cart_id,
|
||||
shipping_methods: shippingMethods,
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,180 @@
|
||||
import {
|
||||
AddToCartWorkflowInputDTO,
|
||||
CreateLineItemForCartDTO,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { useRemoteQueryStep } from "../../../common/steps/use-remote-query"
|
||||
import {
|
||||
addToCartStep,
|
||||
confirmInventoryStep,
|
||||
refreshCartShippingMethodsStep,
|
||||
} from "../steps"
|
||||
import { refreshCartPromotionsStep } from "../steps/refresh-cart-promotions"
|
||||
import { updateTaxLinesStep } from "../steps/update-tax-lines"
|
||||
import { cartFieldsForRefreshSteps } from "../utils/fields"
|
||||
import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input"
|
||||
import { prepareLineItemData } from "../utils/prepare-line-item-data"
|
||||
import { refreshPaymentCollectionForCartStep } from "./refresh-payment-collection"
|
||||
|
||||
// TODO: The AddToCartWorkflow are missing the following steps:
|
||||
// - Refresh/delete shipping methods (fulfillment module)
|
||||
|
||||
export const addToCartWorkflowId = "add-to-cart"
|
||||
export const addToCartWorkflow = createWorkflow(
|
||||
addToCartWorkflowId,
|
||||
(input: WorkflowData<AddToCartWorkflowInputDTO>) => {
|
||||
const variantIds = transform({ input }, (data) => {
|
||||
return (data.input.items ?? []).map((i) => i.variant_id)
|
||||
})
|
||||
|
||||
// TODO: This is on par with the context used in v1.*, but we can be more flexible.
|
||||
const pricingContext = transform({ cart: input.cart }, (data) => {
|
||||
return {
|
||||
currency_code: data.cart.currency_code,
|
||||
region_id: data.cart.region_id,
|
||||
customer_id: data.cart.customer_id,
|
||||
}
|
||||
})
|
||||
|
||||
const variants = useRemoteQueryStep({
|
||||
entry_point: "variants",
|
||||
fields: [
|
||||
"id",
|
||||
"title",
|
||||
"sku",
|
||||
"barcode",
|
||||
"manage_inventory",
|
||||
"product.id",
|
||||
"product.title",
|
||||
"product.description",
|
||||
"product.subtitle",
|
||||
"product.thumbnail",
|
||||
"product.type",
|
||||
"product.collection",
|
||||
"product.handle",
|
||||
|
||||
"calculated_price.calculated_amount",
|
||||
|
||||
"inventory_items.inventory_item_id",
|
||||
"inventory_items.required_quantity",
|
||||
|
||||
"inventory_items.inventory.location_levels.stock_locations.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.name",
|
||||
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.name",
|
||||
],
|
||||
variables: {
|
||||
id: variantIds,
|
||||
calculated_price: {
|
||||
context: pricingContext,
|
||||
},
|
||||
},
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const confirmInventoryInput = transform({ input, variants }, (data) => {
|
||||
const managedVariants = data.variants.filter((v) => v.manage_inventory)
|
||||
if (!managedVariants.length) {
|
||||
return { items: [] }
|
||||
}
|
||||
|
||||
const productVariantInventoryItems: any[] = []
|
||||
|
||||
const stockLocations = data.variants
|
||||
.map((v) => v.inventory_items)
|
||||
.flat()
|
||||
.map((ii) => {
|
||||
productVariantInventoryItems.push({
|
||||
variant_id: ii.variant_id,
|
||||
inventory_item_id: ii.inventory_item_id,
|
||||
required_quantity: ii.required_quantity,
|
||||
})
|
||||
|
||||
return ii.inventory.location_levels
|
||||
})
|
||||
.flat()
|
||||
.map((ll) => ll.stock_locations)
|
||||
.flat()
|
||||
|
||||
const salesChannelId = data.input.cart.sales_channel_id
|
||||
if (salesChannelId) {
|
||||
const salesChannels = stockLocations
|
||||
.map((sl) => sl.sales_channels)
|
||||
.flat()
|
||||
.filter((sc) => sc.id === salesChannelId)
|
||||
|
||||
if (!salesChannels.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Sales channel ${salesChannelId} is not associated with any stock locations.`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const priceNotFound: string[] = data.variants
|
||||
.filter((v) => !v.calculated_price)
|
||||
.map((v) => v.id)
|
||||
|
||||
if (priceNotFound.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Variants with IDs ${priceNotFound.join(", ")} do not have a price`
|
||||
)
|
||||
}
|
||||
|
||||
const items = prepareConfirmInventoryInput({
|
||||
product_variant_inventory_items: productVariantInventoryItems,
|
||||
location_ids: stockLocations.map((l) => l.id),
|
||||
items: data.input.items!,
|
||||
variants: data.variants.map((v) => ({
|
||||
id: v.id,
|
||||
manage_inventory: v.manage_inventory,
|
||||
})),
|
||||
})
|
||||
|
||||
return { items }
|
||||
})
|
||||
|
||||
confirmInventoryStep(confirmInventoryInput)
|
||||
|
||||
const lineItems = transform({ input, variants }, (data) => {
|
||||
const items = (data.input.items ?? []).map((item) => {
|
||||
const variant = data.variants.find((v) => v.id === item.variant_id)!
|
||||
|
||||
return prepareLineItemData({
|
||||
variant: variant,
|
||||
unitPrice: variant.calculated_price.calculated_amount,
|
||||
quantity: item.quantity,
|
||||
metadata: item?.metadata ?? {},
|
||||
cartId: data.input.cart.id,
|
||||
}) as CreateLineItemForCartDTO
|
||||
})
|
||||
|
||||
return items
|
||||
})
|
||||
|
||||
const items = addToCartStep({ items: lineItems })
|
||||
|
||||
const cart = useRemoteQueryStep({
|
||||
entry_point: "cart",
|
||||
fields: cartFieldsForRefreshSteps,
|
||||
variables: { id: input.cart.id },
|
||||
list: false,
|
||||
}).config({ name: "refetch–cart" })
|
||||
|
||||
refreshCartShippingMethodsStep({ cart })
|
||||
// TODO: since refreshCartShippingMethodsStep potentially removes cart shipping methods, we need the updated cart here
|
||||
// for the following 2 steps as they act upon final cart shape
|
||||
updateTaxLinesStep({ cart_or_cart_id: cart, items })
|
||||
refreshCartPromotionsStep({ id: input.cart.id })
|
||||
refreshPaymentCollectionForCartStep({ cart_id: input.cart.id })
|
||||
|
||||
return items
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,43 @@
|
||||
import { CompleteCartWorkflowInputDTO, OrderDTO } from "@medusajs/types"
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import { createOrderFromCartStep } from "../steps"
|
||||
import { updateTaxLinesStep } from "../steps/update-tax-lines"
|
||||
import { completeCartFields } from "../utils/fields"
|
||||
|
||||
/*
|
||||
- [] Create Tax Lines
|
||||
- [] Authorize Payment
|
||||
- fail:
|
||||
- [] Delete Tax lines
|
||||
- [] Reserve Item from inventory (if enabled)
|
||||
- fail:
|
||||
- [] Delete reservations
|
||||
- [] Cancel Payment
|
||||
- [] Create order
|
||||
*/
|
||||
export const completeCartWorkflowId = "complete-cart"
|
||||
export const completeCartWorkflow = createWorkflow(
|
||||
completeCartWorkflowId,
|
||||
(
|
||||
input: WorkflowData<CompleteCartWorkflowInputDTO>
|
||||
): WorkflowData<OrderDTO> => {
|
||||
const cart = useRemoteQueryStep({
|
||||
entry_point: "cart",
|
||||
fields: completeCartFields,
|
||||
variables: { id: input.id },
|
||||
list: false,
|
||||
})
|
||||
|
||||
updateTaxLinesStep({ cart_or_cart_id: cart, force_tax_calculation: true })
|
||||
|
||||
const finalCart = useRemoteQueryStep({
|
||||
entry_point: "cart",
|
||||
fields: completeCartFields,
|
||||
variables: { id: input.id },
|
||||
list: false,
|
||||
}).config({ name: "final-cart" })
|
||||
|
||||
return createOrderFromCartStep({ cart: finalCart })
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,228 @@
|
||||
import { CartDTO, CreateCartWorkflowInputDTO } from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
parallelize,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { useRemoteQueryStep } from "../../../common/steps/use-remote-query"
|
||||
import {
|
||||
confirmInventoryStep,
|
||||
createCartsStep,
|
||||
findOneOrAnyRegionStep,
|
||||
findOrCreateCustomerStep,
|
||||
findSalesChannelStep,
|
||||
getVariantPriceSetsStep,
|
||||
} from "../steps"
|
||||
import { refreshCartPromotionsStep } from "../steps/refresh-cart-promotions"
|
||||
import { updateTaxLinesStep } from "../steps/update-tax-lines"
|
||||
import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input"
|
||||
import { prepareLineItemData } from "../utils/prepare-line-item-data"
|
||||
import { refreshPaymentCollectionForCartStep } from "./refresh-payment-collection"
|
||||
|
||||
// TODO: The createCartWorkflow are missing the following steps:
|
||||
// - Refresh/delete shipping methods (fulfillment module)
|
||||
|
||||
export const createCartWorkflowId = "create-cart"
|
||||
export const createCartWorkflow = createWorkflow(
|
||||
createCartWorkflowId,
|
||||
(input: WorkflowData<CreateCartWorkflowInputDTO>): WorkflowData<CartDTO> => {
|
||||
const variantIds = transform({ input }, (data) => {
|
||||
return (data.input.items ?? []).map((i) => i.variant_id)
|
||||
})
|
||||
|
||||
const [salesChannel, region, customerData] = parallelize(
|
||||
findSalesChannelStep({
|
||||
salesChannelId: input.sales_channel_id,
|
||||
}),
|
||||
findOneOrAnyRegionStep({
|
||||
regionId: input.region_id,
|
||||
}),
|
||||
findOrCreateCustomerStep({
|
||||
customerId: input.customer_id,
|
||||
email: input.email,
|
||||
})
|
||||
)
|
||||
|
||||
// TODO: This is on par with the context used in v1.*, but we can be more flexible.
|
||||
const pricingContext = transform(
|
||||
{ input, region, customerData },
|
||||
(data) => {
|
||||
return {
|
||||
currency_code: data.input.currency_code ?? data.region.currency_code,
|
||||
region_id: data.region.id,
|
||||
customer_id: data.customerData.customer?.id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const variants = useRemoteQueryStep({
|
||||
entry_point: "variants",
|
||||
fields: [
|
||||
"id",
|
||||
"title",
|
||||
"sku",
|
||||
"manage_inventory",
|
||||
"barcode",
|
||||
"product.id",
|
||||
"product.title",
|
||||
"product.description",
|
||||
"product.subtitle",
|
||||
"product.thumbnail",
|
||||
"product.type",
|
||||
"product.collection",
|
||||
"product.handle",
|
||||
|
||||
"calculated_price.calculated_amount",
|
||||
|
||||
"inventory_items.inventory_item_id",
|
||||
"inventory_items.required_quantity",
|
||||
|
||||
"inventory_items.inventory.location_levels.stock_locations.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.name",
|
||||
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.name",
|
||||
],
|
||||
variables: {
|
||||
id: variantIds,
|
||||
calculated_price: {
|
||||
context: pricingContext,
|
||||
},
|
||||
},
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const confirmInventoryInput = transform(
|
||||
{ input, salesChannel, variants },
|
||||
(data) => {
|
||||
const managedVariants = data.variants.filter((v) => v.manage_inventory)
|
||||
if (!managedVariants.length) {
|
||||
return { items: [] }
|
||||
}
|
||||
|
||||
const productVariantInventoryItems: any[] = []
|
||||
|
||||
const stockLocations = managedVariants
|
||||
.map((v) => v.inventory_items)
|
||||
.flat()
|
||||
.map((ii) => {
|
||||
productVariantInventoryItems.push({
|
||||
variant_id: ii.variant_id,
|
||||
inventory_item_id: ii.inventory_item_id,
|
||||
required_quantity: ii.required_quantity,
|
||||
})
|
||||
|
||||
return ii.inventory.location_levels
|
||||
})
|
||||
.flat()
|
||||
.map((ll) => ll.stock_locations)
|
||||
.flat()
|
||||
|
||||
const salesChannelId = data.salesChannel?.id
|
||||
if (salesChannelId) {
|
||||
const salesChannels = stockLocations
|
||||
.map((sl) => sl.sales_channels)
|
||||
.flat()
|
||||
.filter((sc) => sc.id === salesChannelId)
|
||||
|
||||
if (!salesChannels.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Sales channel ${salesChannelId} is not associated with any stock locations.`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const priceNotFound: string[] = data.variants
|
||||
.filter((v) => !v.calculated_price)
|
||||
.map((v) => v.id)
|
||||
|
||||
if (priceNotFound.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Variants with IDs ${priceNotFound.join(", ")} do not have a price`
|
||||
)
|
||||
}
|
||||
|
||||
const items = prepareConfirmInventoryInput({
|
||||
product_variant_inventory_items: productVariantInventoryItems,
|
||||
location_ids: stockLocations.map((l) => l.id),
|
||||
items: data.input.items!,
|
||||
variants: data.variants.map((v) => ({
|
||||
id: v.id,
|
||||
manage_inventory: v.manage_inventory,
|
||||
})),
|
||||
})
|
||||
|
||||
return { items }
|
||||
}
|
||||
)
|
||||
|
||||
confirmInventoryStep(confirmInventoryInput)
|
||||
|
||||
const priceSets = getVariantPriceSetsStep({
|
||||
variantIds,
|
||||
context: pricingContext,
|
||||
})
|
||||
|
||||
const cartInput = transform(
|
||||
{ input, region, customerData, salesChannel },
|
||||
(data) => {
|
||||
const data_ = {
|
||||
...data.input,
|
||||
currency_code: data.input.currency_code ?? data.region.currency_code,
|
||||
region_id: data.region.id,
|
||||
}
|
||||
|
||||
if (data.customerData.customer?.id) {
|
||||
data_.customer_id = data.customerData.customer.id
|
||||
data_.email = data.input?.email ?? data.customerData.customer.email
|
||||
}
|
||||
|
||||
if (data.salesChannel?.id) {
|
||||
data_.sales_channel_id = data.salesChannel.id
|
||||
}
|
||||
|
||||
return data_
|
||||
}
|
||||
)
|
||||
|
||||
const lineItems = transform({ priceSets, input, variants }, (data) => {
|
||||
const items = (data.input.items ?? []).map((item) => {
|
||||
const variant = data.variants.find((v) => v.id === item.variant_id)!
|
||||
|
||||
return prepareLineItemData({
|
||||
variant: variant,
|
||||
unitPrice: data.priceSets[item.variant_id].calculated_amount,
|
||||
quantity: item.quantity,
|
||||
metadata: item?.metadata ?? {},
|
||||
})
|
||||
})
|
||||
|
||||
return items
|
||||
})
|
||||
|
||||
const cartToCreate = transform({ lineItems, cartInput }, (data) => {
|
||||
return {
|
||||
...data.cartInput,
|
||||
items: data.lineItems,
|
||||
}
|
||||
})
|
||||
|
||||
const carts = createCartsStep([cartToCreate])
|
||||
const cart = transform({ carts }, (data) => data.carts?.[0])
|
||||
|
||||
refreshCartPromotionsStep({
|
||||
id: cart.id,
|
||||
promo_codes: input.promo_codes,
|
||||
})
|
||||
updateTaxLinesStep({ cart_or_cart_id: cart.id })
|
||||
refreshPaymentCollectionForCartStep({
|
||||
cart_id: cart.id,
|
||||
})
|
||||
|
||||
return cart
|
||||
}
|
||||
)
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
CartDTO,
|
||||
CreatePaymentCollectionForCartWorkflowInputDTO,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { retrieveCartStep } from "../steps"
|
||||
import { createPaymentCollectionsStep } from "../steps/create-payment-collection"
|
||||
import { linkCartAndPaymentCollectionsStep } from "../steps/link-cart-payment-collection"
|
||||
|
||||
export const createPaymentCollectionForCartWorkflowId =
|
||||
"create-payment-collection-for-cart"
|
||||
export const createPaymentCollectionForCartWorkflow = createWorkflow(
|
||||
createPaymentCollectionForCartWorkflowId,
|
||||
(
|
||||
input: WorkflowData<CreatePaymentCollectionForCartWorkflowInputDTO>
|
||||
): WorkflowData<CartDTO> => {
|
||||
const created = createPaymentCollectionsStep([input])
|
||||
|
||||
const link = transform({ cartId: input.cart_id, created }, (data) => ({
|
||||
links: [
|
||||
{
|
||||
cart_id: data.cartId,
|
||||
payment_collection_id: data.created[0].id,
|
||||
},
|
||||
],
|
||||
}))
|
||||
|
||||
linkCartAndPaymentCollectionsStep(link)
|
||||
|
||||
const cart = retrieveCartStep({ id: input.cart_id })
|
||||
|
||||
return cart
|
||||
}
|
||||
)
|
||||
Loaded 100 of 1436 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user