@kb0912/notification-brevo 1.0.16 → 2.0.0
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.
- package/.medusa/server/src/admin/index.js +1004 -3
- package/.medusa/server/src/admin/index.mjs +1004 -3
- package/.medusa/server/src/api/admin/brevo-plugin-settings/analytics/route.js +78 -0
- package/.medusa/server/src/api/admin/brevo-plugin-settings/route.js +27 -0
- package/.medusa/server/src/api/hooks/brevo-webhook/route.js +40 -0
- package/.medusa/server/src/jobs/abandoned-cart.js +5 -11
- package/.medusa/server/src/jobs/promotion-expiry-reminder.js +122 -0
- package/.medusa/server/src/jobs/review-request.js +106 -0
- package/.medusa/server/src/jobs/winback.js +108 -0
- package/.medusa/server/src/modules/brevo-settings/index.js +13 -0
- package/.medusa/server/src/modules/brevo-settings/migrations/Migration20260306173214.js +15 -0
- package/.medusa/server/src/modules/brevo-settings/migrations/Migration20260307045432.js +14 -0
- package/.medusa/server/src/modules/brevo-settings/migrations/Migration20260307075811.js +14 -0
- package/.medusa/server/src/modules/brevo-settings/models/brevo-settings.js +79 -0
- package/.medusa/server/src/modules/brevo-settings/service.js +114 -0
- package/.medusa/server/src/providers/notifications-brevo/services.js +321 -176
- package/.medusa/server/src/workflows/index.js +25 -0
- package/.medusa/server/src/workflows/send-abandoned-cart.js +37 -8
- package/.medusa/server/src/workflows/send-customer-created.js +159 -4
- package/.medusa/server/src/workflows/send-order-canceled.js +27 -3
- package/.medusa/server/src/workflows/send-order-confirmation.js +63 -10
- package/.medusa/server/src/workflows/send-order-delivered.js +52 -0
- package/.medusa/server/src/workflows/send-review-request.js +37 -0
- package/.medusa/server/src/workflows/send-shipment-confirmation.js +33 -10
- package/.medusa/server/src/workflows/send-winback.js +34 -0
- package/.medusa/server/src/workflows/steps/check-abandoned-carts.js +184 -58
- package/.medusa/server/src/workflows/steps/resolve-locale.js +25 -0
- package/.medusa/server/src/workflows/steps/send-multi-channel.js +81 -0
- package/.medusa/server/src/workflows/steps/send-notification.js +1 -1
- package/.medusa/server/src/workflows/steps/sync-brevo-contact.js +57 -0
- package/.medusa/server/src/workflows/steps/track-brevo-event.js +47 -0
- package/README.md +315 -60
- package/package.json +21 -23
- package/.medusa/server/src/api/admin/plugin/route.js +0 -7
- package/.medusa/server/src/config.js +0 -12
- package/.medusa/server/src/loaders/brevo.js +0 -13
- package/.medusa/server/src/subscribers/password-reset.js +0 -18
- package/.medusa/server/src/subscribers/promotion-new-customer-created.js +0 -21
- package/.medusa/server/src/workflows/send-password-reset.js +0 -30
- package/.medusa/server/src/workflows/send-promotion-notification.js +0 -24
package/README.md
CHANGED
|
@@ -1,35 +1,208 @@
|
|
|
1
|
+
# @kb0912/notification-brevo
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
Not a full-time professional developer so Medusa 2.0 is very hard to learn for me.
|
|
4
|
-
If anyone want to improve this plugin, just submit your PR
|
|
3
|
+
Brevo (formerly Sendinblue) notification plugin for **Medusa v2**. Handles transactional emails, automated marketing campaigns, contact sync, and event tracking — all configurable from the Medusa Admin.
|
|
5
4
|
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
+
### 📧 Transactional Emails
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
Automatically sends Brevo transactional emails on Medusa events:
|
|
10
|
+
|
|
11
|
+
| Event | Trigger | Template Params |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| **Order Placed** | `order.placed` subscriber | `order_id`, `display_id`, `total`, `items[]`, `shipping_address`, `payment_collections[]` |
|
|
14
|
+
| **Order Canceled** | `order.canceled` subscriber | `order_id`, `display_id`, `customer_name` |
|
|
15
|
+
| **Order Delivered** | `order.completed` subscriber | `customer_name`, `order.display_id`, `order.items[]`, `order.total` |
|
|
16
|
+
| **Customer Created** | `customer.created` subscriber | `name`, `phone`, `customer_id` |
|
|
17
|
+
| **Shipment Confirmed** | `shipment.created` subscriber | `customer_name`, `tracking_number`, `tracking_url`, `order.items[]` |
|
|
18
|
+
|
|
19
|
+
Each event can be individually enabled/disabled and assigned its own Brevo template ID from the Admin UI.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
### 🎁 Promotion — New Customer Welcome
|
|
24
|
+
|
|
25
|
+
When a new customer registers, the plugin can auto-create a **unique discount code** and send it via email.
|
|
26
|
+
|
|
27
|
+
**How it works:**
|
|
28
|
+
|
|
29
|
+
1. Customer registers → `customer.created` event fires
|
|
30
|
+
2. Plugin creates a Medusa Promotion with:
|
|
31
|
+
- **Code**: `{PREFIX}-{8-char random}` (e.g. `WELCOME-A3KF8X2N`)
|
|
32
|
+
- **Rules**: `customer_id eq {customer}` (locked to this customer only)
|
|
33
|
+
- **Rules**: `currency_code ne {excluded}` (optional currency exclusions)
|
|
34
|
+
- **Campaign**: time-bounded with `starts_at` / `ends_at`
|
|
35
|
+
- **Budget**: usage limit = 1 (single use)
|
|
36
|
+
3. Sends promotion email with the code
|
|
37
|
+
|
|
38
|
+
**Admin Settings:**
|
|
39
|
+
- Enable/disable auto-create
|
|
40
|
+
- Discount type: `percentage` or `fixed`
|
|
41
|
+
- Discount value (e.g. 10%)
|
|
42
|
+
- Expiry days (default: 30)
|
|
43
|
+
- Code prefix (default: `WELCOME`)
|
|
44
|
+
- Excluded currencies (e.g. VND)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### ⏰ Discount Expiry Reminder
|
|
49
|
+
|
|
50
|
+
A daily scheduled job checks for promotions about to expire and sends reminder emails.
|
|
51
|
+
|
|
52
|
+
**How it works:**
|
|
53
|
+
|
|
54
|
+
1. Job runs daily at 9:00 AM (`0 9 * * *`)
|
|
55
|
+
2. Queries all active promotions matching the configured code prefix
|
|
56
|
+
3. Checks campaign `ends_at` within the reminder window (e.g. 3 days before expiry)
|
|
57
|
+
4. Finds the associated customer via `customer_id` rule on the promotion
|
|
58
|
+
5. Sends reminder email (once per promotion, tracked in customer metadata)
|
|
59
|
+
|
|
60
|
+
**Admin Settings:**
|
|
61
|
+
- Enable/disable reminder
|
|
62
|
+
- Days before expiry to send (default: 3)
|
|
63
|
+
- Reminder template ID
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
### 🛒 Abandoned Cart Recovery
|
|
68
|
+
|
|
69
|
+
Multi-step abandoned cart email sequence with optional discount code on the final email.
|
|
70
|
+
|
|
71
|
+
**How it works:**
|
|
72
|
+
|
|
73
|
+
1. Scheduled job runs every 15 minutes (`*/15 * * * *`)
|
|
74
|
+
2. Finds carts where:
|
|
75
|
+
- `completed_at` is null (not checked out)
|
|
76
|
+
- Has an email address
|
|
77
|
+
- Has at least 1 item
|
|
78
|
+
- Last item activity exceeds the configured interval
|
|
79
|
+
3. Sends emails based on configurable intervals (e.g. 1h, 24h, 72h)
|
|
80
|
+
4. Tracks sent emails in cart metadata (`abandonedcart_mail_1`, `abandonedcart_mail_2`, ...)
|
|
81
|
+
5. Only one email is sent per cart per job run
|
|
82
|
+
|
|
83
|
+
**Discount on final email:**
|
|
84
|
+
|
|
85
|
+
On the last interval, the plugin can auto-create a limited-time discount:
|
|
86
|
+
- **Code**: `{PREFIX}-{8-char random}` (e.g. `COMEBACK-V7KFPPC4`)
|
|
87
|
+
- **Rules**: `customer_id eq {customer}` (if cart has a logged-in customer)
|
|
88
|
+
- **Rules**: `currency_code ne {excluded}` (optional currency exclusions)
|
|
89
|
+
- **Campaign**: time-bounded (default: 48 hours)
|
|
90
|
+
- **Budget**: usage limit (default: 1)
|
|
91
|
+
|
|
92
|
+
**Duplicate prevention:**
|
|
93
|
+
- Discount creation and email sending use separate metadata flags
|
|
94
|
+
- If discount is created but email fails → next run retries email using the existing discount code (no duplicate)
|
|
95
|
+
- If user returns and updates cart → timer resets based on latest item activity, but already-sent email flags persist
|
|
9
96
|
|
|
10
|
-
|
|
97
|
+
**Admin Settings:**
|
|
98
|
+
- Enable/disable abandoned cart
|
|
99
|
+
- Intervals (JSON array of hours, e.g. `[1, 24, 72]`)
|
|
100
|
+
- Max emails per cart
|
|
101
|
+
- Enable/disable discount on final email
|
|
102
|
+
- Discount type, value, max uses, expiry hours
|
|
103
|
+
- Code prefix (default: `COMEBACK`)
|
|
104
|
+
- Excluded currencies
|
|
105
|
+
- Separate template ID for discount email
|
|
11
106
|
|
|
107
|
+
---
|
|
12
108
|
|
|
109
|
+
### ⭐ Review Request
|
|
13
110
|
|
|
14
|
-
|
|
15
|
-
- Send email notifications for order placement, order cancellation, customer creation, and abandoned carts using Brevo.
|
|
16
|
-
- Configurable delays for abandoned cart reminders.
|
|
17
|
-
- Supports multiple notification stages (first, second, third).
|
|
111
|
+
Sends review request emails for completed orders after a configurable delay.
|
|
18
112
|
|
|
19
|
-
|
|
113
|
+
- Job schedule: daily at 10:00 AM
|
|
114
|
+
- Only sends for orders with status "completed" (no returns/refunds)
|
|
115
|
+
- Tracks sent status in order metadata to prevent duplicates
|
|
20
116
|
|
|
21
|
-
|
|
117
|
+
**Admin Settings:**
|
|
118
|
+
- Enable/disable
|
|
119
|
+
- Days after delivery (default: 7)
|
|
120
|
+
- Template ID
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### 💌 Win-back Campaign
|
|
125
|
+
|
|
126
|
+
Re-engages inactive customers who haven't ordered in a while.
|
|
127
|
+
|
|
128
|
+
- Job schedule: daily at 11:00 AM
|
|
129
|
+
- Finds customers whose last completed order was X+ days ago
|
|
130
|
+
- Sends a win-back email (once per customer, tracked in metadata)
|
|
131
|
+
|
|
132
|
+
**Admin Settings:**
|
|
133
|
+
- Enable/disable
|
|
134
|
+
- Days inactive threshold (default: 30)
|
|
135
|
+
- Template ID
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### 👥 Brevo Contact Sync
|
|
140
|
+
|
|
141
|
+
Automatically syncs new customers to a Brevo contact list.
|
|
142
|
+
|
|
143
|
+
- Creates/updates Brevo contacts with `FIRSTNAME`, `LASTNAME`, `PHONE`
|
|
144
|
+
- Optionally adds contacts to a specific list ID
|
|
145
|
+
|
|
146
|
+
**Admin Settings:**
|
|
147
|
+
- Enable/disable
|
|
148
|
+
- Brevo List ID
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### 📊 Event Tracking
|
|
153
|
+
|
|
154
|
+
Sends custom events to Brevo for analytics and automation triggers.
|
|
155
|
+
|
|
156
|
+
Tracked events:
|
|
157
|
+
- `customer_created` — when a new customer registers
|
|
158
|
+
- `order_placed` — when an order is placed
|
|
159
|
+
|
|
160
|
+
**Admin Settings:**
|
|
161
|
+
- Enable/disable
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### 🌐 Multi-language Templates
|
|
166
|
+
|
|
167
|
+
Override template IDs per locale for multilingual stores.
|
|
168
|
+
|
|
169
|
+
**How it works:**
|
|
170
|
+
- Customer's preferred locale is read from `customer.metadata.preferred_locale`
|
|
171
|
+
- If a locale-specific template exists for the event → use it
|
|
172
|
+
- Otherwise → fallback to the default template
|
|
173
|
+
|
|
174
|
+
**Admin Settings:**
|
|
175
|
+
- Enable/disable
|
|
176
|
+
- JSON template map: `{ "vi": { "order.placed": 101, "order.canceled": 102 }, "en": { ... } }`
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Installation
|
|
22
181
|
|
|
23
182
|
```bash
|
|
183
|
+
# Install the plugin
|
|
24
184
|
yarn add @kb0912/notification-brevo
|
|
185
|
+
|
|
186
|
+
# Or link locally for development
|
|
187
|
+
yalc add @kb0912/notification-brevo
|
|
25
188
|
```
|
|
26
189
|
|
|
27
|
-
|
|
28
|
-
Add the plugin to your medusa-config.ts file to enable Brevo notifications in your Medusa project.
|
|
190
|
+
## Configuration
|
|
29
191
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
192
|
+
### 1. Register the plugin in `medusa-config.ts`
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import { defineConfig } from "@medusajs/framework/utils"
|
|
196
|
+
|
|
197
|
+
export default defineConfig({
|
|
198
|
+
// ...
|
|
199
|
+
plugins: [
|
|
200
|
+
{
|
|
201
|
+
resolve: "@kb0912/notification-brevo",
|
|
202
|
+
options: {},
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
modules: [
|
|
33
206
|
{
|
|
34
207
|
resolve: "@medusajs/medusa/notification",
|
|
35
208
|
options: {
|
|
@@ -39,58 +212,140 @@ modules: [
|
|
|
39
212
|
id: "brevo",
|
|
40
213
|
options: {
|
|
41
214
|
channels: ["email"],
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
215
|
+
apiKey: process.env.BREVO_API_KEY,
|
|
216
|
+
from: process.env.BREVO_FROM_EMAIL,
|
|
217
|
+
senderName: process.env.BREVO_SENDER_NAME,
|
|
218
|
+
// Optional: env-level template ID fallbacks
|
|
219
|
+
orderPlacedTemplateId: process.env.BREVO_ORDER_PLACED_TEMPLATE_ID,
|
|
220
|
+
orderCanceledTemplateId: process.env.BREVO_ORDER_CANCELED_TEMPLATE_ID,
|
|
221
|
+
customerCreatedTemplateId: process.env.BREVO_CUSTOMER_CREATED_TEMPLATE_ID,
|
|
222
|
+
shipmentConfirmedTemplateId: process.env.BREVO_SHIPMENT_CONFIRMED_TEMPLATE_ID,
|
|
223
|
+
abandonedCartTemplateId: process.env.BREVO_ABANDONED_CART_TEMPLATE_ID,
|
|
48
224
|
},
|
|
49
225
|
},
|
|
50
226
|
],
|
|
51
|
-
}
|
|
52
227
|
},
|
|
53
|
-
|
|
54
|
-
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
})
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 2. Environment Variables
|
|
234
|
+
|
|
235
|
+
```env
|
|
236
|
+
BREVO_API_KEY=xkeysib-xxxxxxxx
|
|
237
|
+
BREVO_FROM_EMAIL=noreply@yourdomain.com
|
|
238
|
+
BREVO_SENDER_NAME="Your Store"
|
|
55
239
|
```
|
|
56
|
-
|
|
240
|
+
|
|
241
|
+
### 3. Run Migrations
|
|
242
|
+
|
|
57
243
|
```bash
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
244
|
+
npx medusa db:migrate
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 4. Admin Settings
|
|
248
|
+
|
|
249
|
+
Navigate to **Settings → Brevo** in the Medusa Admin to configure:
|
|
250
|
+
- Template IDs for each event
|
|
251
|
+
- Enable/disable individual features
|
|
252
|
+
- Promotion settings (discount type, value, prefix, currency exclusions)
|
|
253
|
+
- Abandoned cart intervals and discount settings
|
|
254
|
+
- Contact sync, event tracking, and multi-language options
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Brevo Template Variables
|
|
259
|
+
|
|
260
|
+
Use these variables in your Brevo email templates:
|
|
261
|
+
|
|
262
|
+
### Order Placed
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
{{ params.order_id }}
|
|
266
|
+
{{ params.display_id }}
|
|
267
|
+
{{ params.customer_name }}
|
|
268
|
+
{{ params.total }}
|
|
269
|
+
{{ params.date_placed }}
|
|
270
|
+
{{ params.shipping_address.first_name }}
|
|
271
|
+
{{ params.shipping_address.address_1 }}
|
|
272
|
+
{{ params.shipping_address.city }}
|
|
273
|
+
{% for item in params.items %}
|
|
274
|
+
{{ item.title }} × {{ item.quantity }} — {{ item.total }}
|
|
275
|
+
{% endfor %}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Customer Created
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
{{ params.name }}
|
|
282
|
+
{{ params.customer_id }}
|
|
68
283
|
```
|
|
69
284
|
|
|
70
|
-
###
|
|
285
|
+
### Promotion (Welcome / Expiry Reminder)
|
|
71
286
|
|
|
72
|
-
|
|
287
|
+
```
|
|
288
|
+
{{ params.first_name }}
|
|
289
|
+
{{ params.promotion_code }}
|
|
290
|
+
{{ params.ends_at }}
|
|
291
|
+
{{ params.days_left }} <!-- expiry reminder only -->
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Abandoned Cart
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
{{ params.name }}
|
|
298
|
+
{% for item in params.items %}
|
|
299
|
+
{{ item.title }} × {{ item.quantity }} — {{ item.unit_price }}
|
|
300
|
+
{% endfor %}
|
|
301
|
+
{{ params.promotion_code }} <!-- if discount enabled -->
|
|
302
|
+
{{ params.discount_value }} <!-- e.g. 10 -->
|
|
303
|
+
{{ params.discount_type }} <!-- "percentage" or "fixed" -->
|
|
304
|
+
{{ params.discount_expires_at }} <!-- ISO date string -->
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Shipment Confirmed
|
|
308
|
+
|
|
309
|
+
```
|
|
310
|
+
{{ params.customer_name }}
|
|
311
|
+
{{ params.tracking_number }}
|
|
312
|
+
{{ params.tracking_url }}
|
|
313
|
+
{{ params.order.display_id }}
|
|
314
|
+
{% for item in params.order.items %}
|
|
315
|
+
{{ item.title }} × {{ item.quantity }}
|
|
316
|
+
{% endfor %}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Review Request
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
{{ params.customer_name }}
|
|
323
|
+
{{ params.display_id }}
|
|
324
|
+
{% for item in params.items %}
|
|
325
|
+
{{ item.title }}
|
|
326
|
+
{% endfor %}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Win-back
|
|
330
|
+
|
|
331
|
+
```
|
|
332
|
+
{{ params.customer_name }}
|
|
333
|
+
{{ params.last_order_date }}
|
|
334
|
+
{{ params.days_inactive }}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Development
|
|
73
340
|
|
|
74
341
|
```bash
|
|
75
|
-
#
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
ENABLE_ABANDONED_CARTS=true
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Usage
|
|
89
|
-
Once configured, the plugin will:
|
|
90
|
-
|
|
91
|
-
Send order confirmation emails when an order is placed.
|
|
92
|
-
Send abandoned cart reminder emails based on the configured delays (e.g., 24, 48, 72 hours) after the cart's last update.
|
|
93
|
-
Prerequisites
|
|
94
|
-
|
|
95
|
-
A Medusa server running v2.x.
|
|
96
|
-
A Brevo account with API key and email templates set up.
|
|
342
|
+
# Watch for changes (plugin development)
|
|
343
|
+
yarn dev
|
|
344
|
+
|
|
345
|
+
# Build for production
|
|
346
|
+
yarn build
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## License
|
|
350
|
+
|
|
351
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb0912/notification-brevo",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Sending email notification using Brevo.",
|
|
5
|
-
"author": "
|
|
5
|
+
"author": "KB (https://medusajs.com)",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"files": [
|
|
8
8
|
".medusa/server"
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
"./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
14
14
|
"./modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
15
15
|
"./providers/*": "./.medusa/server/src/providers/*/index.js",
|
|
16
|
+
"./jobs/*": "./.medusa/server/src/jobs/*.js",
|
|
17
|
+
"./subscribers/*": "./.medusa/server/src/subscribers/*.js",
|
|
18
|
+
"./api/*": "./.medusa/server/src/api/*.js",
|
|
16
19
|
"./*": "./.medusa/server/src/*.js",
|
|
17
20
|
"./admin": {
|
|
18
21
|
"import": "./.medusa/server/src/admin/index.mjs",
|
|
@@ -33,18 +36,13 @@
|
|
|
33
36
|
"prepublishOnly": "medusa plugin:build"
|
|
34
37
|
},
|
|
35
38
|
"devDependencies": {
|
|
36
|
-
"@medusajs/admin-sdk": "^2.
|
|
37
|
-
"@medusajs/cli": "^2.
|
|
38
|
-
"@medusajs/framework": "^2.
|
|
39
|
-
"@medusajs/icons": "^2.
|
|
40
|
-
"@medusajs/medusa": "^2.
|
|
41
|
-
"@medusajs/test-utils": "^2.
|
|
42
|
-
"@medusajs/ui": "^4.
|
|
43
|
-
"@mikro-orm/cli": "6.4.3",
|
|
44
|
-
"@mikro-orm/core": "6.4.3",
|
|
45
|
-
"@mikro-orm/knex": "6.4.3",
|
|
46
|
-
"@mikro-orm/migrations": "6.4.3",
|
|
47
|
-
"@mikro-orm/postgresql": "6.4.3",
|
|
39
|
+
"@medusajs/admin-sdk": "^2.13.3",
|
|
40
|
+
"@medusajs/cli": "^2.13.3",
|
|
41
|
+
"@medusajs/framework": "^2.13.3",
|
|
42
|
+
"@medusajs/icons": "^2.13.3",
|
|
43
|
+
"@medusajs/medusa": "^2.13.3",
|
|
44
|
+
"@medusajs/test-utils": "^2.13.3",
|
|
45
|
+
"@medusajs/ui": "^4.1.3",
|
|
48
46
|
"@swc/core": "1.5.7",
|
|
49
47
|
"@types/node": "^20.0.0",
|
|
50
48
|
"@types/react": "^18.3.2",
|
|
@@ -60,13 +58,13 @@
|
|
|
60
58
|
"yalc": "^1.0.0-pre.53"
|
|
61
59
|
},
|
|
62
60
|
"peerDependencies": {
|
|
63
|
-
"@medusajs/admin-sdk": "2.
|
|
64
|
-
"@medusajs/cli": "2.
|
|
65
|
-
"@medusajs/framework": "2.
|
|
66
|
-
"@medusajs/icons": "2.
|
|
67
|
-
"@medusajs/medusa": "2.
|
|
68
|
-
"@medusajs/test-utils": "2.
|
|
69
|
-
"@medusajs/ui": "4.0
|
|
61
|
+
"@medusajs/admin-sdk": ">=2.13.0",
|
|
62
|
+
"@medusajs/cli": ">=2.13.0",
|
|
63
|
+
"@medusajs/framework": ">=2.13.0",
|
|
64
|
+
"@medusajs/icons": ">=2.13.0",
|
|
65
|
+
"@medusajs/medusa": ">=2.13.0",
|
|
66
|
+
"@medusajs/test-utils": ">=2.13.0",
|
|
67
|
+
"@medusajs/ui": ">=4.1.0",
|
|
70
68
|
"@mikro-orm/cli": "6.4.3",
|
|
71
69
|
"@mikro-orm/core": "6.4.3",
|
|
72
70
|
"@mikro-orm/knex": "6.4.3",
|
|
@@ -80,7 +78,7 @@
|
|
|
80
78
|
},
|
|
81
79
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
|
|
82
80
|
"dependencies": {
|
|
83
|
-
"@getbrevo/brevo": "^
|
|
81
|
+
"@getbrevo/brevo": "^4.0.1"
|
|
84
82
|
},
|
|
85
83
|
"main": "index.js"
|
|
86
|
-
}
|
|
84
|
+
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GET = GET;
|
|
4
|
-
async function GET(req, res) {
|
|
5
|
-
res.sendStatus(200);
|
|
6
|
-
}
|
|
7
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3BsdWdpbi9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLGtCQUtDO0FBTE0sS0FBSyxVQUFVLEdBQUcsQ0FDdkIsR0FBa0IsRUFDbEIsR0FBbUI7SUFFbkIsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0QixDQUFDIn0=
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.abandonedCartConfig = void 0;
|
|
4
|
-
exports.abandonedCartConfig = {
|
|
5
|
-
abandoned_carts: process.env.ENABLE_ABANDONED_CARTS === "true" || false,
|
|
6
|
-
checks: [
|
|
7
|
-
{ delay: process.env.BREVO_CART_FIRST_DELAY || 24 },
|
|
8
|
-
{ delay: process.env.BREVO_CART_SECOND_DELAY },
|
|
9
|
-
{ delay: process.env.BREVO_CART_THIRD_DELAY },
|
|
10
|
-
].filter((check) => check.delay !== undefined && check.delay !== null && check.delay !== ""),
|
|
11
|
-
};
|
|
12
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFLZSxRQUFBLG1CQUFtQixHQUFHO0lBQ2pDLGVBQWUsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixLQUFLLE1BQU0sSUFBSSxLQUFLO0lBQ3ZFLE1BQU0sRUFBRTtRQUNOLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLElBQUksRUFBRSxFQUFDO1FBQ2xELEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLEVBQUU7UUFDOUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsRUFBRTtLQUM5QyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBa0IsRUFBRSxDQUNqQyxLQUFLLENBQUMsS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsS0FBSyxLQUFLLElBQUksSUFBSSxLQUFLLENBQUMsS0FBSyxLQUFLLEVBQUUsQ0FDeEU7Q0FDRixDQUFDIn0=
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.default = abandonedCartLoader;
|
|
7
|
-
const abandoned_cart_1 = __importDefault(require("../jobs/abandoned-cart"));
|
|
8
|
-
async function abandonedCartLoader({ container, options, }) {
|
|
9
|
-
const logger = container.resolve("logger");
|
|
10
|
-
abandoned_cart_1.default;
|
|
11
|
-
logger.info("Initializing abandoned cart loader...");
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJldm8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbG9hZGVycy9icmV2by50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVlBLHNDQVVDO0FBakJELDRFQUE0RDtBQU83QyxLQUFLLFVBQVUsbUJBQW1CLENBQUMsRUFDOUMsU0FBUyxFQUNULE9BQU8sR0FDTztJQUNoQixNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRTNDLHdCQUFzQixDQUFBO0lBQ3RCLE1BQU0sQ0FBQyxJQUFJLENBQUMsdUNBQXVDLENBQUMsQ0FBQztBQUd2RCxDQUFDIn0=
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.config = void 0;
|
|
4
|
-
exports.default = resetPasswordHandler;
|
|
5
|
-
const send_password_reset_1 = require("../workflows/send-password-reset");
|
|
6
|
-
async function resetPasswordHandler({ event: { data }, container, }) {
|
|
7
|
-
await (0, send_password_reset_1.sendPasswordResetWorkflow)(container).run({
|
|
8
|
-
input: {
|
|
9
|
-
email: data.entity_id,
|
|
10
|
-
token: data.token,
|
|
11
|
-
actor_type: data.actor_type,
|
|
12
|
-
},
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
exports.config = {
|
|
16
|
-
event: "auth.password_reset",
|
|
17
|
-
};
|
|
18
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFzc3dvcmQtcmVzZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvc3Vic2NyaWJlcnMvcGFzc3dvcmQtcmVzZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsdUNBV0M7QUFiRCwwRUFBNEU7QUFFN0QsS0FBSyxVQUFVLG9CQUFvQixDQUFDLEVBQ2pELEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxFQUNmLFNBQVMsR0FDZ0U7SUFDekUsTUFBTSxJQUFBLCtDQUF5QixFQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUM3QyxLQUFLLEVBQUU7WUFDTCxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVM7WUFDckIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO1lBQ2pCLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtTQUM1QjtLQUNGLENBQUMsQ0FBQTtBQUNKLENBQUM7QUFFWSxRQUFBLE1BQU0sR0FBcUI7SUFDdEMsS0FBSyxFQUFFLHFCQUFxQjtDQUM3QixDQUFBIn0=
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.config = void 0;
|
|
4
|
-
exports.default = promotionNewCustomerHandler;
|
|
5
|
-
const send_promotion_notification_1 = require("../workflows/send-promotion-notification");
|
|
6
|
-
async function promotionNewCustomerHandler({ event: { data }, container, }) {
|
|
7
|
-
await (0, send_promotion_notification_1.sendPromotionNotificationWorkflow)(container).run({
|
|
8
|
-
input: {
|
|
9
|
-
email: data.email,
|
|
10
|
-
first_name: data.first_name,
|
|
11
|
-
last_name: data.last_name,
|
|
12
|
-
phone: data.phone,
|
|
13
|
-
ends_at: data.ends_at,
|
|
14
|
-
promotion_code: data.promotion_code,
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
exports.config = {
|
|
19
|
-
event: "promotion-new-customer.created",
|
|
20
|
-
};
|
|
21
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbW90aW9uLW5ldy1jdXN0b21lci1jcmVhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3N1YnNjcmliZXJzL3Byb21vdGlvbi1uZXctY3VzdG9tZXItY3JlYXRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFHQSw4Q0FzQkM7QUF4QkQsMEZBQTZGO0FBRTlFLEtBQUssVUFBVSwyQkFBMkIsQ0FBQyxFQUN4RCxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFDZixTQUFTLEdBU1Q7SUFDQSxNQUFNLElBQUEsK0RBQWlDLEVBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3JELEtBQUssRUFBRTtZQUNMLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztZQUNqQixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7WUFDM0IsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQ3pCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztZQUNqQixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87WUFDckIsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjO1NBQ3BDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVZLFFBQUEsTUFBTSxHQUFxQjtJQUN0QyxLQUFLLEVBQUUsZ0NBQWdDO0NBQ3hDLENBQUMifQ==
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// src/workflows/send-password-reset.ts
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.sendPasswordResetWorkflow = void 0;
|
|
5
|
-
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
|
|
6
|
-
const core_flows_1 = require("@medusajs/medusa/core-flows");
|
|
7
|
-
const core_flows_2 = require("@medusajs/medusa/core-flows");
|
|
8
|
-
exports.sendPasswordResetWorkflow = (0, workflows_sdk_1.createWorkflow)("send-password-reset", ({ email, token, actor_type }) => {
|
|
9
|
-
// Optional: fetch customer/admin details if needed for template personalization
|
|
10
|
-
const maybeCustomer = (0, core_flows_1.useQueryGraphStep)({
|
|
11
|
-
entity: "customer",
|
|
12
|
-
fields: ["id", "email", "first_name", "last_name"],
|
|
13
|
-
filters: { email },
|
|
14
|
-
});
|
|
15
|
-
const notifications = (0, core_flows_2.sendNotificationsStep)([
|
|
16
|
-
{
|
|
17
|
-
to: email,
|
|
18
|
-
channel: "email",
|
|
19
|
-
template: "password.reset",
|
|
20
|
-
data: {
|
|
21
|
-
email,
|
|
22
|
-
token,
|
|
23
|
-
actor_type,
|
|
24
|
-
customer: maybeCustomer.data?.[0],
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
]);
|
|
28
|
-
return new workflows_sdk_1.WorkflowResponse(notifications);
|
|
29
|
-
});
|
|
30
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC1wYXNzd29yZC1yZXNldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3Mvc2VuZC1wYXNzd29yZC1yZXNldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsdUNBQXVDOzs7QUFFdkMscUVBQW9GO0FBQ3BGLDREQUErRDtBQUMvRCw0REFBbUU7QUFRdEQsUUFBQSx5QkFBeUIsR0FBRyxJQUFBLDhCQUFjLEVBQ3JELHFCQUFxQixFQUNyQixDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQWlCLEVBQUUsRUFBRTtJQUM5QyxnRkFBZ0Y7SUFDaEYsTUFBTSxhQUFhLEdBQUcsSUFBQSw4QkFBaUIsRUFBQztRQUN0QyxNQUFNLEVBQUUsVUFBVTtRQUNsQixNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLENBQUM7UUFDbEQsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFO0tBQ25CLENBQUMsQ0FBQTtJQUdGLE1BQU0sYUFBYSxHQUFHLElBQUEsa0NBQXFCLEVBQUM7UUFDMUM7WUFDRSxFQUFFLEVBQUUsS0FBSztZQUNULE9BQU8sRUFBRSxPQUFPO1lBQ2hCLFFBQVEsRUFBRSxnQkFBZ0I7WUFDMUIsSUFBSSxFQUFFO2dCQUNKLEtBQUs7Z0JBQ0wsS0FBSztnQkFDTCxVQUFVO2dCQUNWLFFBQVEsRUFBRSxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQ2xDO1NBQ0Y7S0FDRixDQUFDLENBQUE7SUFFRixPQUFPLElBQUksZ0NBQWdCLENBQUMsYUFBYSxDQUFDLENBQUE7QUFDNUMsQ0FBQyxDQUNGLENBQUEifQ==
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sendPromotionNotificationWorkflow = void 0;
|
|
4
|
-
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
|
|
5
|
-
const send_notification_1 = require("./steps/send-notification");
|
|
6
|
-
exports.sendPromotionNotificationWorkflow = (0, workflows_sdk_1.createWorkflow)("send-promotion-notification", (input) => {
|
|
7
|
-
const notificationData = [
|
|
8
|
-
{
|
|
9
|
-
to: input.email,
|
|
10
|
-
channel: "email",
|
|
11
|
-
template: "promotion-new-customer",
|
|
12
|
-
data: {
|
|
13
|
-
first_name: input.first_name,
|
|
14
|
-
last_name: input.last_name,
|
|
15
|
-
phone: input.phone,
|
|
16
|
-
ends_at: input.ends_at,
|
|
17
|
-
promotion_code: input.promotion_code,
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
];
|
|
21
|
-
const notification = (0, send_notification_1.sendNotificationStep)(notificationData);
|
|
22
|
-
return new workflows_sdk_1.WorkflowResponse(notification);
|
|
23
|
-
});
|
|
24
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC1wcm9tb3Rpb24tbm90aWZpY2F0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zZW5kLXByb21vdGlvbi1ub3RpZmljYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQXFGO0FBQ3JGLGlFQUFpRTtBQVlwRCxRQUFBLGlDQUFpQyxHQUFHLElBQUEsOEJBQWMsRUFDN0QsNkJBQTZCLEVBQzdCLENBQUMsS0FBb0IsRUFBRSxFQUFFO0lBQ3ZCLE1BQU0sZ0JBQWdCLEdBQTRCO1FBQ2hEO1lBQ0UsRUFBRSxFQUFFLEtBQUssQ0FBQyxLQUFLO1lBQ2YsT0FBTyxFQUFFLE9BQU87WUFDaEIsUUFBUSxFQUFFLHdCQUF3QjtZQUNsQyxJQUFJLEVBQUU7Z0JBQ0osVUFBVSxFQUFFLEtBQUssQ0FBQyxVQUFVO2dCQUM1QixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7Z0JBQzFCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSztnQkFDbEIsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO2dCQUN0QixjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWM7YUFDckM7U0FDRjtLQUNGLENBQUM7SUFFRixNQUFNLFlBQVksR0FBRyxJQUFBLHdDQUFvQixFQUFDLGdCQUFnQixDQUFDLENBQUM7SUFFNUQsT0FBTyxJQUFJLGdDQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQzVDLENBQUMsQ0FDRixDQUFDIn0=
|