@codee-sh/medusa-plugin-automations 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/.medusa/server/src/admin/_chunks/__admin-extensions__-DIB2k6nJ +10452 -0
  2. package/.medusa/server/src/admin/_chunks/__admin-extensions__-rqdPN7M1 +10450 -0
  3. package/.medusa/server/src/admin/_chunks/base-config-DbRWuXsL +7891 -0
  4. package/.medusa/server/src/admin/_chunks/base-config-ro-vFPBg +7908 -0
  5. package/.medusa/server/src/admin/index.js +2 -9930
  6. package/.medusa/server/src/admin/index.mjs +2 -9927
  7. package/.medusa/server/src/api/admin/mpn/automations/actions/route.js +4 -4
  8. package/.medusa/server/src/api/admin/mpn/automations/available-actions/route.js +1 -1
  9. package/.medusa/server/src/api/admin/mpn/automations/available-events/route.js +1 -1
  10. package/.medusa/server/src/api/admin/mpn/automations/available-triggers/route.js +1 -1
  11. package/.medusa/server/src/api/admin/mpn/automations/route.js +13 -15
  12. package/.medusa/server/src/api/admin/mpn/automations/rules/route.js +12 -7
  13. package/.medusa/server/src/api/middlewares.js +6 -3
  14. package/.medusa/server/src/hooks/api/automations/automations.js +3 -3
  15. package/.medusa/server/src/hooks/api/automations-actions/automations-actions.js +3 -3
  16. package/.medusa/server/src/hooks/api/automations-rules/automations-rules.js +3 -3
  17. package/.medusa/server/src/hooks/api/available-actions/actions.js +3 -3
  18. package/.medusa/server/src/hooks/api/available-events/events.js +3 -3
  19. package/.medusa/server/src/hooks/api/available-triggers/triggers.js +3 -3
  20. package/.medusa/server/src/modules/mpn-automation/actions-handlers/base-action-handler.js +32 -0
  21. package/.medusa/server/src/modules/mpn-automation/actions-handlers/email-action-handler.js +71 -0
  22. package/.medusa/server/src/modules/mpn-automation/actions-handlers/index.js +10 -0
  23. package/.medusa/server/src/modules/mpn-automation/actions-handlers/slack-action-handler.js +43 -0
  24. package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251127115228.js +1 -1
  25. package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251127193345.js +1 -1
  26. package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251127195615.js +1 -1
  27. package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251130144047.js +1 -1
  28. package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251207172856.js +24 -0
  29. package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251208090654.js +14 -0
  30. package/.medusa/server/src/modules/mpn-automation/models/mpn_automation_rule.js +3 -2
  31. package/.medusa/server/src/modules/mpn-automation/models/mpn_automation_rule_value.js +3 -4
  32. package/.medusa/server/src/modules/mpn-automation/models/mpn_automation_state.js +2 -3
  33. package/.medusa/server/src/modules/mpn-automation/models/mpn_automation_trigger.js +11 -6
  34. package/.medusa/server/src/modules/mpn-automation/models/npm_automation_action.js +1 -1
  35. package/.medusa/server/src/modules/mpn-automation/services/service.js +77 -16
  36. package/.medusa/server/src/modules/mpn-automation/types/action-handler.js +3 -0
  37. package/.medusa/server/src/modules/mpn-automation/types/index.js +20 -0
  38. package/.medusa/server/src/modules/mpn-automation/{interfaces.js → types/interfaces.js} +1 -1
  39. package/.medusa/server/src/modules/mpn-automation/types/types.js +193 -0
  40. package/.medusa/server/src/providers/slack/index.js +8 -0
  41. package/.medusa/server/src/providers/slack/service.js +99 -0
  42. package/.medusa/server/src/subscribers/inventory-item-updated.js +1 -1
  43. package/.medusa/server/src/subscribers/inventory-level-updated.js +6 -5
  44. package/.medusa/server/src/subscribers/inventory-reservation-item-updated.js +1 -1
  45. package/.medusa/server/src/subscribers/mpn.automation.action.email.executed.js +6 -5
  46. package/.medusa/server/src/subscribers/mpn.automation.action.slack.executed.js +43 -0
  47. package/.medusa/server/src/subscribers/order-completed.js +2 -2
  48. package/.medusa/server/src/subscribers/order-placed.js +2 -2
  49. package/.medusa/server/src/subscribers/payment-captured.js +2 -2
  50. package/.medusa/server/src/utils/index.js +1 -1
  51. package/.medusa/server/src/utils/plugins.js +4 -2
  52. package/.medusa/server/src/utils/types/index.js +3 -3
  53. package/.medusa/server/src/utils/validate-rules.js +1 -1
  54. package/.medusa/server/src/workflows/inventory/get-inventory-level-by-id.js +1 -1
  55. package/.medusa/server/src/workflows/inventory/steps/get-inventory-level-by-id.js +1 -1
  56. package/.medusa/server/src/workflows/mpn-automation/create-automation.js +1 -1
  57. package/.medusa/server/src/workflows/mpn-automation/delete-automation.js +14 -0
  58. package/.medusa/server/src/workflows/mpn-automation/edit-automation-actions.js +2 -2
  59. package/.medusa/server/src/workflows/mpn-automation/edit-automation-rules.js +2 -2
  60. package/.medusa/server/src/workflows/mpn-automation/edit-automation.js +1 -1
  61. package/.medusa/server/src/workflows/mpn-automation/index.js +3 -1
  62. package/.medusa/server/src/workflows/mpn-automation/run-automation.js +32 -25
  63. package/.medusa/server/src/workflows/mpn-automation/save-automation-state.js +16 -0
  64. package/.medusa/server/src/workflows/mpn-automation/send-email-action.js +1 -1
  65. package/.medusa/server/src/workflows/mpn-automation/send-slack-action.js +69 -0
  66. package/.medusa/server/src/workflows/mpn-automation/steps/create-automation.js +2 -2
  67. package/.medusa/server/src/workflows/mpn-automation/steps/delete-automation.js +14 -0
  68. package/.medusa/server/src/workflows/mpn-automation/steps/edit-automation-actions.js +4 -2
  69. package/.medusa/server/src/workflows/mpn-automation/steps/edit-automation-rules.js +11 -7
  70. package/.medusa/server/src/workflows/mpn-automation/steps/edit-automation.js +2 -2
  71. package/.medusa/server/src/workflows/mpn-automation/steps/index.js +3 -1
  72. package/.medusa/server/src/workflows/mpn-automation/steps/retrieve-automation-triggers-by-event.js +2 -4
  73. package/.medusa/server/src/workflows/mpn-automation/steps/run-automation-actions.js +39 -50
  74. package/.medusa/server/src/workflows/mpn-automation/steps/save-automation-state.js +40 -0
  75. package/.medusa/server/src/workflows/mpn-automation/steps/validate-automation-triggers.js +8 -6
  76. package/.medusa/server/src/workflows/mpn-automation/validate-automation-triggers-by-event.js +6 -6
  77. package/.medusa/server/src/workflows/notifications/index.js +1 -1
  78. package/.medusa/server/src/workflows/notifications/send-email.js +1 -1
  79. package/.medusa/server/src/workflows/notifications/send-slack.js +44 -0
  80. package/.medusa/server/src/workflows/notifications/steps/send-email.js +6 -3
  81. package/.medusa/server/src/workflows/notifications/steps/send-slack.js +74 -0
  82. package/.medusa/server/src/workflows/steps/log-step.js +1 -1
  83. package/README.md +22 -11
  84. package/package.json +4 -2
  85. package/.medusa/server/src/modules/mpn-automation/types.js +0 -199
package/README.md CHANGED
@@ -1,16 +1,19 @@
1
1
  # Medusa plugin automations
2
2
 
3
- A comprehensive notification automation plugin for Medusa v2 that provides a flexible rule-based notification system with triggers, conditions, and actions. Create automated notifications based on events, schedules, or manual triggers with customizable rules.
3
+ A comprehensive automation plugin for Medusa v2 that provides a flexible rule-based automation system with triggers, conditions, and actions. Create automated workflows that can send notifications (email, Slack), execute custom actions, or trigger other processes based on events, schedules, or manual triggers with customizable rules.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Automation Triggers**: Create notification automations triggered by events, schedules, or manual actions
7
+ - **Automation Triggers**: Create automations triggered by events, schedules, or manual actions
8
+ - **Automation Management**: Create, edit, and delete automation triggers with automatic cleanup of related data
8
9
  - **Rule-Based Conditions**: Define complex conditions using rule attributes (e.g., inventory levels, order status)
10
+ - **Multiple Action Types**: Execute various actions including email notifications, Slack messages, SMS, push notifications, and custom actions
9
11
  - **Event Subscribers**: Built-in subscribers for common Medusa events (inventory updates, order events, payment events)
10
12
  - **Admin Panel**: Manage automations directly from Medusa Admin
11
13
  - **Flexible Rules**: Support for multiple rule types and operators (equals, greater than, less than, contains, etc.)
14
+ - **Slack Notifications**: Rich Slack notifications with Block Kit support including headers, action buttons, and dividers
15
+ - **Extensible Actions**: Add custom action handlers to extend automation capabilities
12
16
  - **Type-Safe**: Full TypeScript support with exported types and workflows
13
- - **Extensible**: Add custom rule attributes and extend functionality via plugin options
14
17
 
15
18
  ## Compatibility
16
19
 
@@ -61,18 +64,26 @@ Navigate to **Notifications > Automations** in your Medusa Admin dashboard, or d
61
64
 
62
65
  Automations are triggered by:
63
66
  - **Events**: Medusa events (e.g., `inventory.inventory-level.updated`, `order.placed`)
64
- - **Schedule**: Time-based triggers with configurable intervals
67
+ - **Schedule**: Time-based triggers with configurable intervals (In progress)
65
68
  - **Manual**: Triggered manually from the admin panel
66
69
 
67
70
  ### Rules and Conditions
68
71
 
69
- Each automation can have multiple rules that define when notifications should be sent:
72
+ Each automation can have multiple rules that define when actions should be executed:
70
73
 
71
- - **Rule Attributes**: Available attributes for conditions (e.g., `inventory_level.available_quantity`, `inventory_item.sku`)
74
+ - **Rule Attributes**: Available attributes for conditions
72
75
  - **Operators**: Comparison operators (equals, greater than, less than, contains, in, etc.)
73
76
  - **Rule Values**: Values to compare against
74
77
 
75
- See [Configuration Documentation](./docs/configuration.md) for details on built-in subscribers, available rule attributes, and extending functionality.
78
+ ### Actions
79
+
80
+ When automation rules pass, actions are executed. Supported action types include:
81
+
82
+ - **Email**: Send email notifications
83
+ - **Slack**: Send Slack messages with Block Kit formatting
84
+ - **Custom**: Extend with custom action handlers
85
+
86
+ See [Configuration Documentation](./docs/configuration.md) for details on built-in subscribers, available actions, and extending functionality.
76
87
 
77
88
  ## Admin Panel
78
89
 
@@ -87,13 +98,13 @@ Access the automations management interface in Medusa Admin at `/app/notificatio
87
98
 
88
99
  The plugin exports the following:
89
100
 
90
- - `@codee-sh/medusa-plugin-notification/workflows` - Workflow functions for automation management
91
- - `@codee-sh/medusa-plugin-notification/modules/mpn-automation` - Automation module service
92
- - `@codee-sh/medusa-plugin-notification/utils` - Utility functions
101
+ - `@codee-sh/medusa-plugin-automations/workflows` - Workflow functions for automation management
102
+ - `@codee-sh/medusa-plugin-automations/modules/mpn-automation` - Automation module service
103
+ - `@codee-sh/medusa-plugin-automations/utils` - Utility functions
93
104
 
94
105
  ## Related Plugins
95
106
 
96
- For email templates and rendering functionality, see [@codee-sh/medusa-plugin-notification-emails](https://github.com/codee-sh/medusa-plugin-notification-emails).
107
+ For email templates and rendering functionality, see [@codee-sh/medusa-plugin-automations-emails](https://github.com/codee-sh/medusa-plugin-notification-emails).
97
108
 
98
109
  ## License
99
110
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codee-sh/medusa-plugin-automations",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Medusa plugin for automations.",
5
5
  "author": "Codee (https://codee.dev)",
6
6
  "license": "MIT",
@@ -37,7 +37,9 @@
37
37
  "dev": "medusa plugin:develop",
38
38
  "prepublishOnly": "medusa plugin:build",
39
39
  "publish-local": "npx medusa plugin:publish",
40
- "publish-package": "dotenv npm publish --access public"
40
+ "publish-package": "dotenv npm publish --access public",
41
+ "format": "prettier --write \"src/**/*.{ts,tsx}\"",
42
+ "format:check": "prettier --check \"src/**/*.{ts,tsx}\""
41
43
  },
42
44
  "devDependencies": {
43
45
  "@medusajs/admin-sdk": "2.8.8",
@@ -1,199 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ALL_EVENTS = exports.EVENT_ORDER_TYPES = exports.EVENT_CUSTOMER_TYPES = exports.EVENT_INVENTORY_TYPES = exports.INVENTORY_LEVEL_ATTRIBUTES = exports.INVENTORY_ITEM_ATTRIBUTES = exports.ACTION_TYPES = exports.TRIGGER_TYPES = exports.OPERATOR_TYPES = exports.OperatorType = exports.ActionType = exports.TriggerType = void 0;
4
- var TriggerType;
5
- (function (TriggerType) {
6
- TriggerType["EVENT"] = "event";
7
- TriggerType["SCHEDULE"] = "schedule";
8
- TriggerType["MANUAL"] = "manual";
9
- })(TriggerType || (exports.TriggerType = TriggerType = {}));
10
- var ActionType;
11
- (function (ActionType) {
12
- ActionType["EMAIL"] = "email";
13
- ActionType["SMS"] = "sms";
14
- ActionType["PUSH"] = "push";
15
- ActionType["IN_APP"] = "in_app";
16
- ActionType["SLACK"] = "slack";
17
- ActionType["ADMIN"] = "admin";
18
- })(ActionType || (exports.ActionType = ActionType = {}));
19
- var OperatorType;
20
- (function (OperatorType) {
21
- OperatorType["EQUAL"] = "eq";
22
- OperatorType["NOT_EQUAL"] = "neq";
23
- OperatorType["GREATER_THAN"] = "gt";
24
- OperatorType["LESS_THAN"] = "lt";
25
- OperatorType["GREATER_THAN_OR_EQUAL"] = "gte";
26
- OperatorType["LESS_THAN_OR_EQUAL"] = "lte";
27
- })(OperatorType || (exports.OperatorType = OperatorType = {}));
28
- exports.OPERATOR_TYPES = [
29
- {
30
- value: OperatorType.EQUAL,
31
- label: "Equal"
32
- },
33
- {
34
- value: OperatorType.NOT_EQUAL,
35
- label: "Not Equal"
36
- },
37
- {
38
- value: OperatorType.GREATER_THAN,
39
- label: "Greater Than"
40
- },
41
- {
42
- value: OperatorType.LESS_THAN,
43
- label: "Less Than"
44
- },
45
- {
46
- value: OperatorType.GREATER_THAN_OR_EQUAL,
47
- label: "Greater Than or Equal"
48
- },
49
- {
50
- value: OperatorType.LESS_THAN_OR_EQUAL,
51
- label: "Less Than or Equal"
52
- },
53
- ];
54
- exports.TRIGGER_TYPES = [
55
- {
56
- value: TriggerType.EVENT,
57
- label: "Event"
58
- },
59
- {
60
- value: TriggerType.SCHEDULE,
61
- label: "Schedule"
62
- },
63
- {
64
- value: TriggerType.MANUAL,
65
- label: "Manual"
66
- }
67
- ];
68
- exports.ACTION_TYPES = [
69
- {
70
- value: ActionType.EMAIL,
71
- label: "Email"
72
- },
73
- {
74
- value: ActionType.SMS,
75
- label: "SMS"
76
- },
77
- {
78
- value: ActionType.PUSH,
79
- label: "Push"
80
- },
81
- {
82
- value: ActionType.IN_APP,
83
- label: "In App"
84
- },
85
- {
86
- value: ActionType.SLACK,
87
- label: "Slack"
88
- },
89
- {
90
- value: ActionType.ADMIN,
91
- label: "Admin"
92
- },
93
- ];
94
- exports.INVENTORY_ITEM_ATTRIBUTES = [
95
- {
96
- value: "inventory_item.stocked_quantity",
97
- label: "Stocked Quantity"
98
- },
99
- {
100
- value: "inventory_item.reserved_quantity",
101
- label: "Reserved Quantity"
102
- },
103
- {
104
- value: "inventory_item.available_quantity",
105
- label: "Available Quantity"
106
- },
107
- {
108
- value: "inventory_item.incoming_quantity",
109
- label: "Incoming Quantity"
110
- },
111
- {
112
- value: "inventory_item.location_id",
113
- label: "Location ID"
114
- },
115
- ];
116
- exports.INVENTORY_LEVEL_ATTRIBUTES = [
117
- {
118
- value: "inventory_level.stocked_quantity",
119
- label: "Stocked Quantity"
120
- },
121
- {
122
- value: "inventory_level.reserved_quantity",
123
- label: "Reserved Quantity"
124
- },
125
- {
126
- value: "inventory_level.available_quantity",
127
- label: "Available Quantity"
128
- },
129
- {
130
- value: "inventory_level.incoming_quantity",
131
- label: "Incoming Quantity"
132
- },
133
- {
134
- value: "inventory_level.location_id",
135
- label: "Location ID"
136
- },
137
- ];
138
- exports.EVENT_INVENTORY_TYPES = [
139
- {
140
- value: "inventory.inventory-level.created",
141
- label: "Inventory Level Created",
142
- attributes: exports.INVENTORY_LEVEL_ATTRIBUTES
143
- },
144
- {
145
- value: "inventory.inventory-level.updated",
146
- label: "Inventory Level Updated",
147
- attributes: exports.INVENTORY_LEVEL_ATTRIBUTES
148
- },
149
- {
150
- value: "inventory.inventory-level.deleted",
151
- label: "Inventory Level Deleted",
152
- attributes: exports.INVENTORY_LEVEL_ATTRIBUTES
153
- }
154
- ];
155
- exports.EVENT_CUSTOMER_TYPES = [
156
- {
157
- value: "customer.created",
158
- label: "Customer Created"
159
- },
160
- {
161
- value: "customer.updated",
162
- label: "Customer Updated"
163
- }
164
- ];
165
- exports.EVENT_ORDER_TYPES = [
166
- {
167
- value: "order.placed",
168
- label: "Order Placed"
169
- },
170
- {
171
- value: "order.completed",
172
- label: "Order Completed"
173
- },
174
- {
175
- value: "order.shipped",
176
- label: "Order Shipped"
177
- }
178
- ];
179
- exports.ALL_EVENTS = [
180
- {
181
- name: "Inventory",
182
- events: [
183
- ...exports.EVENT_INVENTORY_TYPES,
184
- ]
185
- },
186
- {
187
- name: "Customer",
188
- events: [
189
- ...exports.EVENT_CUSTOMER_TYPES,
190
- ]
191
- },
192
- {
193
- name: "Order",
194
- events: [
195
- ...exports.EVENT_ORDER_TYPES,
196
- ]
197
- }
198
- ];
199
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9tcG4tYXV0b21hdGlvbi90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUEwQkEsSUFBWSxXQUlYO0FBSkQsV0FBWSxXQUFXO0lBQ3JCLDhCQUFlLENBQUE7SUFDZixvQ0FBcUIsQ0FBQTtJQUNyQixnQ0FBaUIsQ0FBQTtBQUNuQixDQUFDLEVBSlcsV0FBVywyQkFBWCxXQUFXLFFBSXRCO0FBRUQsSUFBWSxVQU9YO0FBUEQsV0FBWSxVQUFVO0lBQ3BCLDZCQUFlLENBQUE7SUFDZix5QkFBVyxDQUFBO0lBQ1gsMkJBQWEsQ0FBQTtJQUNiLCtCQUFpQixDQUFBO0lBQ2pCLDZCQUFlLENBQUE7SUFDZiw2QkFBZSxDQUFBO0FBQ2pCLENBQUMsRUFQVyxVQUFVLDBCQUFWLFVBQVUsUUFPckI7QUFFRCxJQUFZLFlBT1g7QUFQRCxXQUFZLFlBQVk7SUFDdEIsNEJBQVksQ0FBQTtJQUNaLGlDQUFpQixDQUFBO0lBQ2pCLG1DQUFtQixDQUFBO0lBQ25CLGdDQUFnQixDQUFBO0lBQ2hCLDZDQUE2QixDQUFBO0lBQzdCLDBDQUEwQixDQUFBO0FBQzVCLENBQUMsRUFQVyxZQUFZLDRCQUFaLFlBQVksUUFPdkI7QUFFWSxRQUFBLGNBQWMsR0FBRztJQUM1QjtRQUNFLEtBQUssRUFBRSxZQUFZLENBQUMsS0FBSztRQUN6QixLQUFLLEVBQUUsT0FBTztLQUNmO0lBQ0Q7UUFDRSxLQUFLLEVBQUUsWUFBWSxDQUFDLFNBQVM7UUFDN0IsS0FBSyxFQUFFLFdBQVc7S0FDbkI7SUFDRDtRQUNFLEtBQUssRUFBRSxZQUFZLENBQUMsWUFBWTtRQUNoQyxLQUFLLEVBQUUsY0FBYztLQUN0QjtJQUNEO1FBQ0UsS0FBSyxFQUFFLFlBQVksQ0FBQyxTQUFTO1FBQzdCLEtBQUssRUFBRSxXQUFXO0tBQ25CO0lBQ0Q7UUFDRSxLQUFLLEVBQUUsWUFBWSxDQUFDLHFC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