@infuro/cms-core 1.0.63 → 1.0.65
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/dist/admin.cjs +183 -65
- package/dist/admin.js +183 -65
- package/dist/api.cjs +40 -40
- package/dist/api.d.cts +2 -0
- package/dist/api.d.ts +2 -0
- package/dist/api.js +8 -8
- package/dist/{chunk-KAOHOHCA.js → chunk-6YOQ7G5O.js} +92 -51
- package/dist/{chunk-BWOITUNI.js → chunk-ACBN6UWZ.js} +320 -81
- package/dist/chunk-BXAKL2TF.cjs +84 -0
- package/dist/{chunk-7L556RGL.cjs → chunk-GLD263KW.cjs} +3 -3
- package/dist/{chunk-EWXG4E74.cjs → chunk-NIRYYJIJ.cjs} +330 -91
- package/dist/{chunk-MWEK7N3F.js → chunk-OPJEV44S.js} +2 -2
- package/dist/{chunk-DTUL3Q5L.js → chunk-RDEVZMO5.js} +36 -20
- package/dist/{chunk-77YWLP4X.js → chunk-SANKKGB3.js} +68 -32
- package/dist/chunk-THL5JDWJ.cjs +101 -0
- package/dist/{chunk-RXTUSF3R.js → chunk-TU23GJPJ.js} +2 -2
- package/dist/{chunk-JLDHK2QE.cjs → chunk-TZEMLHSP.cjs} +20 -14
- package/dist/{chunk-RHYVNRYG.cjs → chunk-V6EYAC7X.cjs} +38 -22
- package/dist/{chunk-YVP4NQII.cjs → chunk-VM6OVUUM.cjs} +93 -52
- package/dist/{chunk-MXABMVF7.cjs → chunk-XFDIIVZB.cjs} +4 -4
- package/dist/chunk-XJNNOSJR.js +98 -0
- package/dist/chunk-YEAXE4U2.js +77 -0
- package/dist/{chunk-CJEOH6QC.cjs → chunk-YHEITFHR.cjs} +112 -76
- package/dist/{chunk-3VZAAQUV.js → chunk-YRCKEGL2.js} +20 -14
- package/dist/{email-queue-VTYL2KFA.cjs → email-queue-4OY45JIU.cjs} +7 -7
- package/dist/{email-queue-YPRSVG56.js → email-queue-HGXB2FIS.js} +3 -3
- package/dist/{email-service-ATCPJFWG.cjs → email-service-5O24BSFR.cjs} +7 -7
- package/dist/{email-service-DPKVQOKP.js → email-service-ADDF52PJ.js} +2 -2
- package/dist/{emit-order-notification-trigger-WI4HGMKH.cjs → emit-order-notification-trigger-DR74TQXN.cjs} +4 -4
- package/dist/{emit-order-notification-trigger-XVG2B5ZF.js → emit-order-notification-trigger-UCKJHDQK.js} +2 -2
- package/dist/{erp-order-invoice-3UGWLICU.js → erp-order-invoice-H6HCJ7YS.js} +2 -2
- package/dist/{erp-order-invoice-KJYJNWMG.cjs → erp-order-invoice-YUSPZ7CE.cjs} +6 -6
- package/dist/index.cjs +279 -265
- package/dist/index.d.cts +46 -22
- package/dist/index.d.ts +46 -22
- package/dist/index.js +43 -29
- package/dist/migrations/1783000000000-AddOrderPendingProcessingCompletedTriggers.ts +15 -39
- package/dist/migrations/1783300000000-SeedOrderNotificationTriggersAndTemplates.ts +155 -0
- package/dist/{order-completion-otp-handlers-WGM7HWG4.js → order-completion-otp-handlers-CH22ZRAI.js} +5 -5
- package/dist/{order-completion-otp-handlers-IMMQGHDR.cjs → order-completion-otp-handlers-RW5RSXH3.cjs} +7 -7
- package/dist/{order-notification-dispatcher-JKFQJYGG.js → order-notification-dispatcher-3TXUAJ7L.js} +6 -6
- package/dist/{order-notification-dispatcher-5TUFCDU7.cjs → order-notification-dispatcher-Y7NZAALH.cjs} +11 -11
- package/dist/{pg-boss-service-L6MTF4EQ.cjs → pg-boss-service-BDGOKM2T.cjs} +3 -3
- package/dist/pg-boss-service-WCBJD4JB.js +2 -0
- package/package.json +1 -1
- package/dist/chunk-AYWDQFJZ.js +0 -27
- package/dist/chunk-GO7PPYNU.js +0 -76
- package/dist/chunk-UEE4PTTB.cjs +0 -30
- package/dist/chunk-XQ3QUHWR.cjs +0 -83
- package/dist/pg-boss-service-4XF2TQ2E.js +0 -2
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkBXAKL2TF_cjs = require('./chunk-BXAKL2TF.cjs');
|
|
4
4
|
var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
|
|
5
5
|
|
|
6
6
|
// src/lib/emit-order-notification-trigger.ts
|
|
7
|
-
function maskPhone(raw) {
|
|
8
|
-
const digits = String(raw ?? "").replace(/\D/g, "");
|
|
9
|
-
if (digits.length <= 4) return "(none)";
|
|
10
|
-
return `***${digits.slice(-4)}`;
|
|
11
|
-
}
|
|
12
|
-
chunkUSNT2KNT_cjs.__name(maskPhone, "maskPhone");
|
|
13
7
|
async function emitOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
|
|
14
8
|
if (!deps.entityMap.orders) {
|
|
15
|
-
|
|
9
|
+
chunkBXAKL2TF_cjs.notifyLog.skip("TRIGGER", "orders entity missing from entityMap", {
|
|
16
10
|
triggerKey,
|
|
17
11
|
orderId
|
|
18
12
|
});
|
|
19
13
|
return;
|
|
20
14
|
}
|
|
21
|
-
const listenerCount =
|
|
15
|
+
const listenerCount = chunkBXAKL2TF_cjs.notificationTriggerEmitter.listenerCount("__any__");
|
|
22
16
|
if (listenerCount === 0) {
|
|
23
|
-
|
|
17
|
+
chunkBXAKL2TF_cjs.notifyLog.skip("TRIGGER", "no dispatcher listener \u2014 will try direct dispatch (pass getCms to createCmsApiHandler)", {
|
|
18
|
+
triggerKey,
|
|
19
|
+
orderId
|
|
20
|
+
});
|
|
24
21
|
}
|
|
25
22
|
const orderRepo = deps.dataSource.getRepository(deps.entityMap.orders);
|
|
26
23
|
const fullOrder = await orderRepo.findOne({
|
|
@@ -33,7 +30,7 @@ async function emitOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
|
|
|
33
30
|
]
|
|
34
31
|
});
|
|
35
32
|
if (!fullOrder) {
|
|
36
|
-
|
|
33
|
+
chunkBXAKL2TF_cjs.notifyLog.skip("TRIGGER", "order not found", {
|
|
37
34
|
triggerKey,
|
|
38
35
|
orderId
|
|
39
36
|
});
|
|
@@ -41,15 +38,18 @@ async function emitOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
|
|
|
41
38
|
}
|
|
42
39
|
const fo = fullOrder;
|
|
43
40
|
const phone = fo.contact?.phone ?? null;
|
|
44
|
-
|
|
41
|
+
chunkBXAKL2TF_cjs.notifyLog.trigger("emit", {
|
|
45
42
|
triggerKey,
|
|
46
43
|
orderId,
|
|
47
44
|
orderNumber: fo.orderNumber ?? null,
|
|
48
|
-
phone:
|
|
49
|
-
listeners: listenerCount
|
|
45
|
+
phone: chunkBXAKL2TF_cjs.maskNotifyPhone(phone),
|
|
46
|
+
listeners: listenerCount,
|
|
47
|
+
vendorId: fo.vendorId ?? null,
|
|
48
|
+
source: extra?.source ?? "api"
|
|
50
49
|
});
|
|
51
50
|
if (!phone?.trim()) {
|
|
52
|
-
|
|
51
|
+
chunkBXAKL2TF_cjs.notifyLog.skip("WHATSAPP", "order contact has no phone", {
|
|
52
|
+
triggerKey,
|
|
53
53
|
orderId
|
|
54
54
|
});
|
|
55
55
|
}
|
|
@@ -91,28 +91,44 @@ async function emitOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
|
|
|
91
91
|
refundAmount: resolvedRefundAmount
|
|
92
92
|
};
|
|
93
93
|
if (listenerCount === 0) {
|
|
94
|
+
chunkBXAKL2TF_cjs.notifyLog.trigger("direct dispatch (no in-process listener)", {
|
|
95
|
+
triggerKey,
|
|
96
|
+
orderId
|
|
97
|
+
});
|
|
94
98
|
try {
|
|
95
|
-
const { dispatchOrderNotificationDirectly } = await import('./order-notification-dispatcher-
|
|
99
|
+
const { dispatchOrderNotificationDirectly } = await import('./order-notification-dispatcher-Y7NZAALH.cjs');
|
|
96
100
|
await dispatchOrderNotificationDirectly(triggerKey, triggerPayload, deps.dataSource, deps.entityMap);
|
|
97
101
|
} catch (err) {
|
|
98
|
-
|
|
102
|
+
chunkBXAKL2TF_cjs.notifyLog.error("TRIGGER", "direct dispatch failed", {
|
|
99
103
|
triggerKey,
|
|
100
104
|
orderId,
|
|
101
|
-
err
|
|
105
|
+
error: err instanceof Error ? err.message : String(err),
|
|
106
|
+
stack: err instanceof Error ? err.stack : void 0
|
|
102
107
|
});
|
|
103
108
|
}
|
|
104
109
|
} else {
|
|
105
|
-
|
|
110
|
+
chunkBXAKL2TF_cjs.notifyLog.trigger("emit to dispatcher listener", {
|
|
111
|
+
triggerKey,
|
|
112
|
+
orderId,
|
|
113
|
+
listeners: listenerCount
|
|
114
|
+
});
|
|
115
|
+
chunkBXAKL2TF_cjs.notificationTriggerEmitter.emitTrigger(triggerKey, triggerPayload);
|
|
106
116
|
}
|
|
107
117
|
}
|
|
108
118
|
chunkUSNT2KNT_cjs.__name(emitOrderNotificationTrigger, "emitOrderNotificationTrigger");
|
|
109
119
|
function fireOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
|
|
110
|
-
|
|
120
|
+
chunkBXAKL2TF_cjs.notifyLog.trigger("FIRE", {
|
|
111
121
|
triggerKey,
|
|
112
|
-
orderId
|
|
122
|
+
orderId,
|
|
123
|
+
source: extra?.source ?? "api"
|
|
113
124
|
});
|
|
114
125
|
void emitOrderNotificationTrigger(triggerKey, orderId, deps, extra).catch((err) => {
|
|
115
|
-
|
|
126
|
+
chunkBXAKL2TF_cjs.notifyLog.error("TRIGGER", "fire failed", {
|
|
127
|
+
triggerKey,
|
|
128
|
+
orderId,
|
|
129
|
+
error: err instanceof Error ? err.message : String(err),
|
|
130
|
+
stack: err instanceof Error ? err.stack : void 0
|
|
131
|
+
});
|
|
116
132
|
});
|
|
117
133
|
}
|
|
118
134
|
chunkUSNT2KNT_cjs.__name(fireOrderNotificationTrigger, "fireOrderNotificationTrigger");
|
|
@@ -17,41 +17,65 @@ function escapeHtml(s) {
|
|
|
17
17
|
chunkUSNT2KNT_cjs.__name(escapeHtml, "escapeHtml");
|
|
18
18
|
function socialLinkInnerHtml(s) {
|
|
19
19
|
if (s.iconUrl?.trim()) {
|
|
20
|
-
return `<img src="${escapeHtml(s.iconUrl.trim())}" alt="" width="
|
|
20
|
+
return `<img src="${escapeHtml(s.iconUrl.trim())}" alt="" width="22" height="22" style="display:block;border:0;border-radius:4px;" />`;
|
|
21
21
|
}
|
|
22
|
-
const label = s.icon && s.icon.trim() || "\
|
|
23
|
-
return escapeHtml(label)
|
|
22
|
+
const label = s.icon && s.icon.trim() || "\u2022";
|
|
23
|
+
return `<span style="display:inline-block;width:28px;height:28px;line-height:28px;text-align:center;border-radius:999px;background:#ffffff;color:#1e293b;font-size:14px;">${escapeHtml(label)}</span>`;
|
|
24
24
|
}
|
|
25
25
|
chunkUSNT2KNT_cjs.__name(socialLinkInnerHtml, "socialLinkInnerHtml");
|
|
26
|
-
function supportLinesHtml(supportEmail, supportPhone) {
|
|
27
|
-
const parts = [];
|
|
28
|
-
if (supportEmail) {
|
|
29
|
-
parts.push(`<a href="mailto:${escapeHtml(supportEmail)}" style="color:#6b7280;text-decoration:none;font-size:13px;">${escapeHtml(supportEmail)}</a>`);
|
|
30
|
-
}
|
|
31
|
-
if (supportPhone) {
|
|
32
|
-
parts.push(`<span style="color:#6b7280;font-size:13px;">${escapeHtml(supportPhone)}</span>`);
|
|
33
|
-
}
|
|
34
|
-
return parts.join('<span style="color:#d1d5db;padding:0 8px;">\xB7</span>');
|
|
35
|
-
}
|
|
36
|
-
chunkUSNT2KNT_cjs.__name(supportLinesHtml, "supportLinesHtml");
|
|
37
26
|
function renderLayout(options) {
|
|
38
27
|
const { bodyHtml, companyDetails } = options;
|
|
39
|
-
const { logoUrl, companyName, supportEmail, supportPhone, socialLinks, footerDisclaimer, followUsTitle = "Follow Us" } = companyDetails;
|
|
28
|
+
const { logoUrl, companyName, supportEmail, supportPhone, companyAddress, socialLinks, footerDisclaimer, followUsTitle = "Follow Us" } = companyDetails;
|
|
40
29
|
const brand = (companyName || "Store").trim();
|
|
30
|
+
const year = (/* @__PURE__ */ new Date()).getFullYear();
|
|
31
|
+
const slate = "#0f172a";
|
|
32
|
+
const slateSoft = "#1e293b";
|
|
41
33
|
const accent = "#ea580c";
|
|
42
|
-
const
|
|
34
|
+
const accentSoft = "#ffedd5";
|
|
35
|
+
const pageBg = "#eef2f7";
|
|
36
|
+
const muted = "#64748b";
|
|
37
|
+
const border = "#e2e8f0";
|
|
38
|
+
const logoBlock = logoUrl ? `<table role="presentation" cellpadding="0" cellspacing="0" style="margin:0 auto;border-collapse:collapse;">
|
|
39
|
+
<tr>
|
|
40
|
+
<td align="center" style="background:#ffffff;border-radius:14px;padding:14px 22px;box-shadow:0 8px 24px rgba(15,23,42,0.18);">
|
|
41
|
+
<img src="${escapeHtml(logoUrl)}" alt="${escapeHtml(brand)}" width="148" style="max-height:52px;max-width:148px;height:auto;width:auto;display:block;border:0;margin:0 auto;" />
|
|
42
|
+
</td>
|
|
43
|
+
</tr>
|
|
44
|
+
</table>` : `<div style="font-family:Georgia,'Times New Roman',serif;font-size:26px;font-weight:700;letter-spacing:-0.02em;color:#ffffff;">${escapeHtml(brand)}</div>`;
|
|
43
45
|
const hasSocial = Boolean(socialLinks?.length);
|
|
44
|
-
const socialRowHtml = hasSocial && socialLinks ? `<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
const socialRowHtml = hasSocial && socialLinks ? `<table role="presentation" cellpadding="0" cellspacing="0" style="margin:14px auto 0 auto;border-collapse:collapse;">
|
|
47
|
+
<tr>
|
|
48
|
+
${socialLinks.map((s) => `<td style="padding:0 6px;">
|
|
49
|
+
<a href="${escapeHtml(s.url)}" style="display:inline-block;text-decoration:none;border:1px solid ${border};border-radius:999px;padding:6px;background:#ffffff;">
|
|
50
|
+
${socialLinkInnerHtml(s)}
|
|
51
|
+
</a>
|
|
52
|
+
</td>`).join("")}
|
|
53
|
+
</tr>
|
|
54
|
+
</table>` : "";
|
|
55
|
+
const followTitleHtml = hasSocial && followUsTitle ? `<div style="font-size:11px;font-weight:700;color:${muted};text-transform:uppercase;letter-spacing:0.08em;margin:0;">${escapeHtml(followUsTitle)}</div>` : "";
|
|
56
|
+
const contactRows = [];
|
|
57
|
+
if (supportEmail) {
|
|
58
|
+
contactRows.push(`<a href="mailto:${escapeHtml(supportEmail)}" style="color:${slateSoft};text-decoration:none;font-size:13px;font-weight:500;">${escapeHtml(supportEmail)}</a>`);
|
|
59
|
+
}
|
|
60
|
+
if (supportPhone) {
|
|
61
|
+
contactRows.push(`<span style="color:${muted};font-size:13px;">${escapeHtml(supportPhone)}</span>`);
|
|
62
|
+
}
|
|
63
|
+
if (companyAddress?.trim()) {
|
|
64
|
+
contactRows.push(`<span style="color:${muted};font-size:12px;line-height:1.5;display:inline-block;max-width:360px;">${escapeHtml(companyAddress.trim()).replace(/\n/g, "<br/>")}</span>`);
|
|
65
|
+
}
|
|
66
|
+
const contactHtml = contactRows.length ? `<div style="margin-top:12px;line-height:1.7;">${contactRows.join("<br/>")}</div>` : "";
|
|
67
|
+
const disclaimerBlock = footerDisclaimer ? `<div style="margin-top:14px;font-size:11px;line-height:1.55;color:#94a3b8;max-width:420px;margin-left:auto;margin-right:auto;">${escapeHtml(footerDisclaimer).replace(/\n/g, "<br/>")}</div>` : "";
|
|
48
68
|
const responsiveCss = `
|
|
49
69
|
@media only screen and (max-width: 620px) {
|
|
50
|
-
.email-shell { padding:
|
|
51
|
-
.email-
|
|
52
|
-
.email-body { padding:
|
|
53
|
-
.email-
|
|
54
|
-
}
|
|
70
|
+
.email-shell { padding: 12px 8px !important; }
|
|
71
|
+
.email-header { padding: 28px 18px 24px 18px !important; }
|
|
72
|
+
.email-body { padding: 26px 18px 8px 18px !important; }
|
|
73
|
+
.email-footer { padding: 22px 18px 28px 18px !important; }
|
|
74
|
+
.email-accent-label { display: none !important; }
|
|
75
|
+
}
|
|
76
|
+
.email-body p { margin: 0 0 14px 0 !important; }
|
|
77
|
+
.email-body h1, .email-body h2, .email-body h3 { margin: 0 0 12px 0 !important; color: ${slate} !important; }
|
|
78
|
+
.email-body a { color: ${accent} !important; }
|
|
55
79
|
`;
|
|
56
80
|
return `<!DOCTYPE html>
|
|
57
81
|
<html lang="en">
|
|
@@ -60,39 +84,56 @@ function renderLayout(options) {
|
|
|
60
84
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
61
85
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
62
86
|
<title>${escapeHtml(brand)}</title>
|
|
87
|
+
<!--[if mso]>
|
|
88
|
+
<style type="text/css">
|
|
89
|
+
body, table, td { font-family: Arial, Helvetica, sans-serif !important; }
|
|
90
|
+
</style>
|
|
91
|
+
<![endif]-->
|
|
63
92
|
<style type="text/css">${responsiveCss}</style>
|
|
64
93
|
</head>
|
|
65
|
-
<body style="margin:0;padding:0;background
|
|
66
|
-
<
|
|
94
|
+
<body style="margin:0;padding:0;background:${pageBg};-webkit-font-smoothing:antialiased;">
|
|
95
|
+
<div style="display:none;max-height:0;overflow:hidden;opacity:0;color:transparent;mso-hide:all;">
|
|
96
|
+
Update from ${escapeHtml(brand)}
|
|
97
|
+
</div>
|
|
98
|
+
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background:${pageBg};border-collapse:collapse;">
|
|
67
99
|
<tr>
|
|
68
|
-
<td class="email-shell" align="center" style="padding:
|
|
69
|
-
<table role="presentation"
|
|
70
|
-
<tr>
|
|
71
|
-
<td class="email-header" align="center" style="padding:28px 32px 20px 32px;background:#ffffff;">
|
|
72
|
-
${logoHtml}
|
|
73
|
-
${logoUrl && companyName ? `<div style="margin-top:10px;font-size:13px;color:#6b7280;">${escapeHtml(companyName)}</div>` : ""}
|
|
74
|
-
</td>
|
|
75
|
-
</tr>
|
|
76
|
-
<tr>
|
|
77
|
-
<td style="height:4px;line-height:4px;font-size:0;background:${accent};"> </td>
|
|
78
|
-
</tr>
|
|
79
|
-
<tr>
|
|
80
|
-
<td class="email-body" style="padding:28px 32px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-size:15px;line-height:1.65;color:#1f2937;">
|
|
81
|
-
${bodyHtml}
|
|
82
|
-
</td>
|
|
83
|
-
</tr>
|
|
100
|
+
<td class="email-shell" align="center" style="padding:40px 16px;">
|
|
101
|
+
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="max-width:600px;border-collapse:collapse;">
|
|
84
102
|
<tr>
|
|
85
|
-
<td style="
|
|
86
|
-
<
|
|
103
|
+
<td style="background:#ffffff;border-radius:18px;overflow:hidden;border:1px solid ${border};box-shadow:0 12px 40px rgba(15,23,42,0.08);">
|
|
104
|
+
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border-collapse:collapse;">
|
|
105
|
+
<tr>
|
|
106
|
+
<td class="email-header" align="center" style="padding:36px 32px 30px 32px;background:linear-gradient(165deg, ${slate} 0%, ${slateSoft} 100%);background-color:${slate};">
|
|
107
|
+
<div class="email-accent-label" style="display:inline-block;margin:0 0 18px 0;padding:5px 12px;border-radius:999px;background:rgba(234,88,12,0.18);border:1px solid rgba(251,146,60,0.35);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:0.06em;text-transform:uppercase;color:${accentSoft};">
|
|
108
|
+
${escapeHtml(brand)}
|
|
109
|
+
</div>
|
|
110
|
+
${logoBlock}
|
|
111
|
+
${logoUrl ? `<div style="margin-top:16px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-size:13px;color:#94a3b8;">${escapeHtml(brand)}</div>` : ""}
|
|
112
|
+
</td>
|
|
113
|
+
</tr>
|
|
114
|
+
<tr>
|
|
115
|
+
<td style="height:5px;line-height:5px;font-size:0;background:linear-gradient(90deg, ${accent} 0%, #f59e0b 55%, #fb923c 100%);background-color:${accent};"> </td>
|
|
116
|
+
</tr>
|
|
117
|
+
<tr>
|
|
118
|
+
<td class="email-body" style="padding:32px 36px 12px 36px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-size:15px;line-height:1.7;color:#334155;background:#ffffff;">
|
|
119
|
+
${bodyHtml}
|
|
120
|
+
</td>
|
|
121
|
+
</tr>
|
|
122
|
+
<tr>
|
|
123
|
+
<td class="email-footer" align="center" style="padding:24px 32px 32px 32px;background:#f8fafc;border-top:1px solid ${border};font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;">
|
|
124
|
+
${followTitleHtml}
|
|
125
|
+
${socialRowHtml}
|
|
126
|
+
${contactHtml}
|
|
127
|
+
<div style="margin-top:18px;font-size:12px;color:#94a3b8;">\xA9 ${year} ${escapeHtml(brand)}. All rights reserved.</div>
|
|
128
|
+
${disclaimerBlock}
|
|
129
|
+
</td>
|
|
130
|
+
</tr>
|
|
131
|
+
</table>
|
|
87
132
|
</td>
|
|
88
133
|
</tr>
|
|
89
134
|
<tr>
|
|
90
|
-
<td align="center" style="padding:
|
|
91
|
-
${
|
|
92
|
-
${socialRowHtml}
|
|
93
|
-
${supportHtml ? `<div style="margin-top:14px;">${supportHtml}</div>` : ""}
|
|
94
|
-
<div style="margin-top:12px;font-size:12px;color:#9ca3af;">\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} ${escapeHtml(brand)}</div>
|
|
95
|
-
${disclaimerBlock}
|
|
135
|
+
<td align="center" style="padding:18px 8px 0 8px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-size:11px;line-height:1.5;color:#94a3b8;">
|
|
136
|
+
You\u2019re receiving this because of activity on your ${escapeHtml(brand)} account.
|
|
96
137
|
</td>
|
|
97
138
|
</tr>
|
|
98
139
|
</table>
|
|
@@ -700,7 +741,7 @@ function renderEmail(templateName, ctx, options) {
|
|
|
700
741
|
chunkUSNT2KNT_cjs.__name(renderEmail, "renderEmail");
|
|
701
742
|
|
|
702
743
|
// src/plugins/email/email-service.ts
|
|
703
|
-
var require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-
|
|
744
|
+
var require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-VM6OVUUM.cjs', document.baseURI).href)));
|
|
704
745
|
var MailComposer = require2("nodemailer/lib/mail-composer");
|
|
705
746
|
var SES_REGIONS_WITHOUT_SMTP = /* @__PURE__ */ new Set([
|
|
706
747
|
"af-south-1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkGLD263KW_cjs = require('./chunk-GLD263KW.cjs');
|
|
4
4
|
var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
|
|
5
5
|
|
|
6
6
|
// src/plugins/email/email-queue.ts
|
|
@@ -50,13 +50,13 @@ async function resolveInvoiceAttachmentForJob(cms, payload, options) {
|
|
|
50
50
|
invoiceAttached: false
|
|
51
51
|
};
|
|
52
52
|
const o = order;
|
|
53
|
-
if (!
|
|
53
|
+
if (!chunkGLD263KW_cjs.isOrderEligibleForInvoiceEmail(o.status, o.orderKind)) {
|
|
54
54
|
return {
|
|
55
55
|
attachments: payload.attachments,
|
|
56
56
|
invoiceAttached: false
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
const resolved = await
|
|
59
|
+
const resolved = await chunkGLD263KW_cjs.resolveOrderInvoicePdfBytes(cms, dataSource, entityMap, payload.orderId);
|
|
60
60
|
if ("error" in resolved) {
|
|
61
61
|
console.warn("[email] order invoice attach failed", {
|
|
62
62
|
orderId: payload.orderId,
|
|
@@ -133,7 +133,7 @@ async function queueEmail(cms, payload) {
|
|
|
133
133
|
let email = cms && typeof cms.getPlugin === "function" ? cms.getPlugin("email") : void 0;
|
|
134
134
|
if (!email) {
|
|
135
135
|
try {
|
|
136
|
-
const { EmailService } = await import('./email-service-
|
|
136
|
+
const { EmailService } = await import('./email-service-5O24BSFR.cjs');
|
|
137
137
|
const env = typeof process !== "undefined" && process.env ? process.env : {};
|
|
138
138
|
const type = String(env.SMTP_TYPE || "SMTP").toUpperCase();
|
|
139
139
|
const port = env.SMTP_PORT ? parseInt(env.SMTP_PORT, 10) : void 0;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { __name } from './chunk-SHUYVCID.js';
|
|
2
|
+
|
|
3
|
+
// src/plugins/pg-boss/pg-boss-service.ts
|
|
4
|
+
var JOB_RUNNER_QUEUE = "job-runner";
|
|
5
|
+
var PgBossService = class {
|
|
6
|
+
static {
|
|
7
|
+
__name(this, "PgBossService");
|
|
8
|
+
}
|
|
9
|
+
connectionString;
|
|
10
|
+
schema;
|
|
11
|
+
boss = null;
|
|
12
|
+
bossPromise = null;
|
|
13
|
+
started = false;
|
|
14
|
+
workRegistered = /* @__PURE__ */ new Set();
|
|
15
|
+
constructor(connectionString, schema) {
|
|
16
|
+
this.connectionString = connectionString;
|
|
17
|
+
this.schema = schema?.trim() ? schema.trim() : void 0;
|
|
18
|
+
}
|
|
19
|
+
async getBoss() {
|
|
20
|
+
if (this.boss) return this.boss;
|
|
21
|
+
if (this.bossPromise) return this.bossPromise;
|
|
22
|
+
this.bossPromise = (async () => {
|
|
23
|
+
const mod = await import('pg-boss');
|
|
24
|
+
const PgBossClass = mod?.PgBoss ?? mod?.default ?? mod;
|
|
25
|
+
const instance = new PgBossClass({
|
|
26
|
+
connectionString: this.connectionString,
|
|
27
|
+
...this.schema ? {
|
|
28
|
+
schema: this.schema
|
|
29
|
+
} : {},
|
|
30
|
+
schedule: true
|
|
31
|
+
});
|
|
32
|
+
instance.on("error", (err) => {
|
|
33
|
+
console.error("[pg-boss]", err);
|
|
34
|
+
});
|
|
35
|
+
this.boss = instance;
|
|
36
|
+
return instance;
|
|
37
|
+
})();
|
|
38
|
+
return this.bossPromise;
|
|
39
|
+
}
|
|
40
|
+
async start() {
|
|
41
|
+
if (this.started) return;
|
|
42
|
+
const boss = await this.getBoss();
|
|
43
|
+
await boss.start();
|
|
44
|
+
await this.ensureQueue(JOB_RUNNER_QUEUE);
|
|
45
|
+
this.started = true;
|
|
46
|
+
}
|
|
47
|
+
async stop() {
|
|
48
|
+
if (!this.started || !this.boss) return;
|
|
49
|
+
await this.boss.stop({
|
|
50
|
+
graceful: true,
|
|
51
|
+
timeout: 1e4
|
|
52
|
+
});
|
|
53
|
+
this.started = false;
|
|
54
|
+
this.workRegistered.clear();
|
|
55
|
+
}
|
|
56
|
+
get raw() {
|
|
57
|
+
return this.boss;
|
|
58
|
+
}
|
|
59
|
+
async ensureQueue(name) {
|
|
60
|
+
const boss = await this.getBoss();
|
|
61
|
+
const existing = await boss.getQueue(name);
|
|
62
|
+
if (!existing) {
|
|
63
|
+
await boss.createQueue(name);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async send(queue, data) {
|
|
67
|
+
await this.ensureQueue(queue);
|
|
68
|
+
const boss = await this.getBoss();
|
|
69
|
+
return boss.send(queue, data, {
|
|
70
|
+
retryLimit: 2
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async schedule(name, cron, data, options) {
|
|
74
|
+
await this.ensureQueue(name);
|
|
75
|
+
const boss = await this.getBoss();
|
|
76
|
+
await boss.schedule(name, cron, data, options);
|
|
77
|
+
}
|
|
78
|
+
async unschedule(name) {
|
|
79
|
+
try {
|
|
80
|
+
const boss = await this.getBoss();
|
|
81
|
+
await boss.unschedule(name);
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async registerWork(queue, handler) {
|
|
86
|
+
if (this.workRegistered.has(queue)) return;
|
|
87
|
+
await this.ensureQueue(queue);
|
|
88
|
+
const boss = await this.getBoss();
|
|
89
|
+
await boss.work(queue, async (jobs) => {
|
|
90
|
+
for (const job of jobs) {
|
|
91
|
+
await handler(job.data);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
this.workRegistered.add(queue);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export { JOB_RUNNER_QUEUE, PgBossService };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { __name } from './chunk-SHUYVCID.js';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
|
|
4
|
+
var KNOWN_NOTIFICATION_TRIGGERS = {
|
|
5
|
+
ORDER_PENDING: "order_pending",
|
|
6
|
+
ORDER_PROCESSING: "order_processing",
|
|
7
|
+
ORDER_COMPLETED: "order_completed",
|
|
8
|
+
ORDER_PLACED: "order_placed",
|
|
9
|
+
ORDER_CANCELLED: "order_cancelled",
|
|
10
|
+
PAYMENT_SUCCESS: "payment_success",
|
|
11
|
+
PAYMENT_FAILED: "payment_failed",
|
|
12
|
+
PAYMENT_REFUND_INITIATED: "payment_refund_initiated"
|
|
13
|
+
};
|
|
14
|
+
var NotificationTriggerEmitter = class NotificationTriggerEmitter2 extends EventEmitter {
|
|
15
|
+
static {
|
|
16
|
+
__name(this, "NotificationTriggerEmitter");
|
|
17
|
+
}
|
|
18
|
+
emitTrigger(triggerKey, payload) {
|
|
19
|
+
this.emit("__any__", triggerKey, payload);
|
|
20
|
+
}
|
|
21
|
+
onAnyTrigger(listener) {
|
|
22
|
+
this.on("__any__", listener);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var notificationTriggerEmitter = new NotificationTriggerEmitter();
|
|
26
|
+
|
|
27
|
+
// src/lib/notify-log.ts
|
|
28
|
+
function maskTail(raw, keep = 6) {
|
|
29
|
+
const s = String(raw ?? "").trim();
|
|
30
|
+
if (!s) return "(none)";
|
|
31
|
+
if (s.length <= keep) return "***";
|
|
32
|
+
return `***${s.slice(-keep)}`;
|
|
33
|
+
}
|
|
34
|
+
__name(maskTail, "maskTail");
|
|
35
|
+
function maskNotifyPhone(raw) {
|
|
36
|
+
const digits = String(raw ?? "").replace(/\D/g, "");
|
|
37
|
+
if (digits.length <= 4) return "(none)";
|
|
38
|
+
return `***${digits.slice(-4)}`;
|
|
39
|
+
}
|
|
40
|
+
__name(maskNotifyPhone, "maskNotifyPhone");
|
|
41
|
+
function maskNotifyEmail(raw) {
|
|
42
|
+
const e = String(raw ?? "").trim();
|
|
43
|
+
if (!e || !e.includes("@")) return "(none)";
|
|
44
|
+
const [user, domain] = e.split("@");
|
|
45
|
+
const u = user.length <= 2 ? "**" : `${user.slice(0, 2)}***`;
|
|
46
|
+
return `${u}@${domain}`;
|
|
47
|
+
}
|
|
48
|
+
__name(maskNotifyEmail, "maskNotifyEmail");
|
|
49
|
+
function maskNotifyToken(raw) {
|
|
50
|
+
return maskTail(raw, 8);
|
|
51
|
+
}
|
|
52
|
+
__name(maskNotifyToken, "maskNotifyToken");
|
|
53
|
+
function write(level, channel, message, data) {
|
|
54
|
+
const banner = `========== [NOTIFY] ${channel} | ${message} ==========`;
|
|
55
|
+
const payload = data ?? {};
|
|
56
|
+
if (level === "error") {
|
|
57
|
+
console.error(`
|
|
58
|
+
${banner}`, payload);
|
|
59
|
+
} else if (level === "warn") {
|
|
60
|
+
console.warn(`
|
|
61
|
+
${banner}`, payload);
|
|
62
|
+
} else {
|
|
63
|
+
console.info(`
|
|
64
|
+
${banner}`, payload);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
__name(write, "write");
|
|
68
|
+
var notifyLog = {
|
|
69
|
+
trigger: /* @__PURE__ */ __name((message, data) => write("info", "TRIGGER", message, data), "trigger"),
|
|
70
|
+
email: /* @__PURE__ */ __name((message, data) => write("info", "EMAIL", message, data), "email"),
|
|
71
|
+
whatsapp: /* @__PURE__ */ __name((message, data) => write("info", "WHATSAPP", message, data), "whatsapp"),
|
|
72
|
+
push: /* @__PURE__ */ __name((message, data) => write("info", "PUSH", message, data), "push"),
|
|
73
|
+
skip: /* @__PURE__ */ __name((channel, message, data) => write("warn", `SKIP ${channel}`, message, data), "skip"),
|
|
74
|
+
error: /* @__PURE__ */ __name((channel, message, data) => write("error", channel, message, data), "error")
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export { KNOWN_NOTIFICATION_TRIGGERS, maskNotifyEmail, maskNotifyPhone, maskNotifyToken, notificationTriggerEmitter, notifyLog };
|