@infuro/cms-core 1.0.35 → 1.0.36

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 (65) hide show
  1. package/dist/admin.cjs +861 -626
  2. package/dist/admin.d.cts +6 -0
  3. package/dist/admin.d.ts +6 -0
  4. package/dist/admin.js +863 -628
  5. package/dist/api.cjs +40 -39
  6. package/dist/api.js +8 -7
  7. package/dist/auth.cjs +51 -51
  8. package/dist/auth.d.cts +3 -3
  9. package/dist/auth.d.ts +3 -3
  10. package/dist/auth.js +3 -3
  11. package/dist/{chunk-BGJAV67S.cjs → chunk-2AEVFOQP.cjs} +7923 -7197
  12. package/dist/chunk-COBORIJH.cjs +2373 -0
  13. package/dist/{chunk-EQPITOP6.js → chunk-FG6I64HP.js} +70 -9
  14. package/dist/chunk-HCIRL37O.js +21 -0
  15. package/dist/chunk-HT5DI3XW.cjs +82 -0
  16. package/dist/{chunk-2XE4X74C.js → chunk-JS2W7XZ4.js} +7510 -6800
  17. package/dist/{chunk-EF2JBPDM.js → chunk-KFFB6EMZ.js} +9 -0
  18. package/dist/{chunk-3KPNTQBV.cjs → chunk-KPKFNLQQ.cjs} +50 -22
  19. package/dist/{chunk-6KPQWRFW.js → chunk-LI2IXVAY.js} +1 -1
  20. package/dist/{chunk-N44BJZ4C.cjs → chunk-SPQFNIYJ.cjs} +9 -0
  21. package/dist/chunk-UCKN4BBY.cjs +24 -0
  22. package/dist/{chunk-4TRPKBKO.js → chunk-UF3BYUXY.js} +50 -23
  23. package/dist/chunk-VMY2S32H.js +2342 -0
  24. package/dist/{chunk-TIAEXJLI.cjs → chunk-WO2DW4AU.cjs} +7 -7
  25. package/dist/chunk-X47PBV4I.js +79 -0
  26. package/dist/{chunk-CNTSLED2.cjs → chunk-X6H5VBQ2.cjs} +75 -14
  27. package/dist/cli.cjs +4 -2
  28. package/dist/cli.js +4 -2
  29. package/dist/emit-order-notification-trigger-D2N3KFHL.cjs +16 -0
  30. package/dist/emit-order-notification-trigger-IVLWKKJL.js +3 -0
  31. package/dist/{event-order-defaults-DUGDVGJI.cjs → event-order-defaults-EMWBIGL3.cjs} +9 -9
  32. package/dist/{event-order-defaults-6E543227.js → event-order-defaults-SDRNAZHC.js} +1 -1
  33. package/dist/index.cjs +805 -1059
  34. package/dist/index.d.cts +827 -728
  35. package/dist/index.d.ts +827 -728
  36. package/dist/index.js +385 -724
  37. package/dist/migrations/1781220000000-AddWhatsappTriggerBindings.ts +23 -0
  38. package/dist/migrations/1781230000000-AddOrderNotificationTriggers.ts +46 -0
  39. package/dist/migrations/1781240000000-DropEventOrderNotificationColumns.ts +29 -0
  40. package/dist/migrations/1781250000000-RemoveOrderRefundedTrigger.ts +36 -0
  41. package/dist/{rbac-debug-db-D7ME7QUY.cjs → rbac-debug-db-HWP65A4O.cjs} +2 -2
  42. package/dist/{rbac-debug-db-MTCTVNNM.js → rbac-debug-db-QJH3AD34.js} +1 -1
  43. package/dist/whatsapp-trigger-dispatcher-ONHXI7UY.cjs +19 -0
  44. package/dist/whatsapp-trigger-dispatcher-PWFI4FKP.js +6 -0
  45. package/package.json +1 -1
  46. package/dist/chunk-46GKADYE.cjs +0 -84
  47. package/dist/chunk-7YIBMQDR.cjs +0 -86
  48. package/dist/chunk-J7XHLOLO.js +0 -830
  49. package/dist/chunk-JBRR5UYL.js +0 -87
  50. package/dist/chunk-JHF4YYRC.cjs +0 -188
  51. package/dist/chunk-PAMVINEX.cjs +0 -577
  52. package/dist/chunk-QM733NUK.js +0 -186
  53. package/dist/chunk-R73BKDRO.cjs +0 -90
  54. package/dist/chunk-TFUOHI37.cjs +0 -839
  55. package/dist/chunk-XDSNZUW7.js +0 -564
  56. package/dist/chunk-ZQ4X6OAU.js +0 -82
  57. package/dist/chunk-ZSVCP6N3.js +0 -83
  58. package/dist/email-FKR4FXFI.js +0 -5
  59. package/dist/email-KVKVPNCL.cjs +0 -58
  60. package/dist/event-order-notifications-5GSAOYVS.cjs +0 -27
  61. package/dist/event-order-notifications-IIIF23D5.js +0 -10
  62. package/dist/layout-36UFTHC5.cjs +0 -11
  63. package/dist/layout-AOBN26XG.js +0 -2
  64. package/dist/whatsapp-queue-3DXA4MXU.js +0 -2
  65. package/dist/whatsapp-queue-KG65MXD5.cjs +0 -15
@@ -0,0 +1,23 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ export class AddWhatsappTriggerBindings1781220000000 implements MigrationInterface {
4
+ name = 'AddWhatsappTriggerBindings1781220000000';
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`
8
+ CREATE TABLE "whatsapp_trigger_bindings" (
9
+ "id" SERIAL PRIMARY KEY,
10
+ "triggerKey" varchar NOT NULL UNIQUE,
11
+ "messageTemplateId" int NOT NULL,
12
+ "enabled" boolean NOT NULL DEFAULT true,
13
+ "createdAt" timestamp NOT NULL DEFAULT now(),
14
+ "updatedAt" timestamp NOT NULL DEFAULT now(),
15
+ CONSTRAINT "FK_whatsapp_trigger_bindings_template" FOREIGN KEY ("messageTemplateId") REFERENCES "message_templates"("id") ON DELETE CASCADE
16
+ );
17
+ `);
18
+ }
19
+
20
+ public async down(queryRunner: QueryRunner): Promise<void> {
21
+ await queryRunner.query(`DROP TABLE "whatsapp_trigger_bindings";`);
22
+ }
23
+ }
@@ -0,0 +1,46 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ export class AddOrderNotificationTriggers1781230000000 implements MigrationInterface {
4
+ name = 'AddOrderNotificationTriggers1781230000000';
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`
8
+ CREATE TABLE "order_notification_triggers" (
9
+ "id" SERIAL PRIMARY KEY,
10
+ "triggerKey" varchar NOT NULL UNIQUE,
11
+ "label" varchar NOT NULL,
12
+ "description" text,
13
+ "category" varchar NOT NULL DEFAULT 'order',
14
+ "enabled" boolean NOT NULL DEFAULT true,
15
+ "sortOrder" int NOT NULL DEFAULT 0,
16
+ "createdAt" timestamp NOT NULL DEFAULT now(),
17
+ "updatedAt" timestamp NOT NULL DEFAULT now()
18
+ );
19
+ `);
20
+
21
+ await queryRunner.query(`
22
+ INSERT INTO "order_notification_triggers" ("triggerKey", "label", "description", "category", "sortOrder")
23
+ VALUES
24
+ ('order_placed', 'Order placed', 'Fires when a new order is created (storefront checkout or admin).', 'order', 1),
25
+ ('order_cancelled', 'Order cancelled', 'Fires when an order is cancelled.', 'order', 2),
26
+ ('order_refunded', 'Order refunded', 'Fires when a refund amount is processed on cancellation.', 'order', 3)
27
+ ON CONFLICT ("triggerKey") DO NOTHING;
28
+ `);
29
+
30
+ await queryRunner.query(`
31
+ ALTER TABLE "whatsapp_trigger_bindings"
32
+ ALTER COLUMN "messageTemplateId" DROP NOT NULL;
33
+ `);
34
+ }
35
+
36
+ public async down(queryRunner: QueryRunner): Promise<void> {
37
+ await queryRunner.query(`
38
+ DELETE FROM "whatsapp_trigger_bindings" WHERE "messageTemplateId" IS NULL;
39
+ `);
40
+ await queryRunner.query(`
41
+ ALTER TABLE "whatsapp_trigger_bindings"
42
+ ALTER COLUMN "messageTemplateId" SET NOT NULL;
43
+ `);
44
+ await queryRunner.query(`DROP TABLE "order_notification_triggers";`);
45
+ }
46
+ }
@@ -0,0 +1,29 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ export class DropEventOrderNotificationColumns1781240000000 implements MigrationInterface {
4
+ name = 'DropEventOrderNotificationColumns1781240000000';
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ if (!(await queryRunner.hasTable('events'))) return;
8
+ await queryRunner.query(`ALTER TABLE "events" DROP COLUMN IF EXISTS "orderNotificationTemplates"`);
9
+ await queryRunner.query(`ALTER TABLE "events" DROP COLUMN IF EXISTS "orderNotificationChannels"`);
10
+ await queryRunner.query(`ALTER TABLE "events" DROP COLUMN IF EXISTS "orderNotificationsEnabled"`);
11
+ }
12
+
13
+ public async down(queryRunner: QueryRunner): Promise<void> {
14
+ if (!(await queryRunner.hasTable('events'))) return;
15
+
16
+ const table = await queryRunner.getTable('events');
17
+ if (!table?.findColumnByName('orderNotificationsEnabled')) {
18
+ await queryRunner.query(
19
+ `ALTER TABLE "events" ADD COLUMN "orderNotificationsEnabled" boolean NOT NULL DEFAULT false`,
20
+ );
21
+ }
22
+ if (!table?.findColumnByName('orderNotificationChannels')) {
23
+ await queryRunner.query(`ALTER TABLE "events" ADD COLUMN "orderNotificationChannels" jsonb;`);
24
+ }
25
+ if (!table?.findColumnByName('orderNotificationTemplates')) {
26
+ await queryRunner.query(`ALTER TABLE "events" ADD COLUMN "orderNotificationTemplates" jsonb;`);
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,36 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /** Keep only order_placed and order_cancelled notification triggers. */
4
+ export class RemoveOrderRefundedTrigger1781250000000 implements MigrationInterface {
5
+ name = 'RemoveOrderRefundedTrigger1781250000000';
6
+
7
+ public async up(queryRunner: QueryRunner): Promise<void> {
8
+ await queryRunner.query(`
9
+ DELETE FROM "whatsapp_trigger_bindings" WHERE "triggerKey" = 'order_refunded';
10
+ `);
11
+ await queryRunner.query(`
12
+ DELETE FROM "order_notification_triggers" WHERE "triggerKey" = 'order_refunded';
13
+ `);
14
+ await queryRunner.query(`
15
+ UPDATE "order_notification_triggers"
16
+ SET
17
+ "description" = 'Fires when an order is cancelled (includes refund amount when applicable).',
18
+ "updatedAt" = now()
19
+ WHERE "triggerKey" = 'order_cancelled';
20
+ `);
21
+ }
22
+
23
+ public async down(queryRunner: QueryRunner): Promise<void> {
24
+ await queryRunner.query(`
25
+ INSERT INTO "order_notification_triggers" ("triggerKey", "label", "description", "category", "sortOrder")
26
+ VALUES
27
+ ('order_refunded', 'Order refunded', 'Fires when a refund amount is processed on cancellation.', 'order', 3)
28
+ ON CONFLICT ("triggerKey") DO NOTHING;
29
+ `);
30
+ await queryRunner.query(`
31
+ UPDATE "order_notification_triggers"
32
+ SET "description" = 'Fires when an order is cancelled.', "updatedAt" = now()
33
+ WHERE "triggerKey" = 'order_cancelled';
34
+ `);
35
+ }
36
+ }
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk3KPNTQBV_cjs = require('./chunk-3KPNTQBV.cjs');
3
+ var chunkKPKFNLQQ_cjs = require('./chunk-KPKFNLQQ.cjs');
4
4
  var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
5
5
 
6
6
  // src/auth/rbac-debug-db.ts
@@ -27,7 +27,7 @@ async function loadDbPermissionsForUser(dataSource, userId) {
27
27
  return {
28
28
  groupId,
29
29
  groupName,
30
- dbEntityPerms: chunk3KPNTQBV_cjs.summarizeEntityPerms(chunk3KPNTQBV_cjs.permissionRowsToRecord(permRows))
30
+ dbEntityPerms: chunkKPKFNLQQ_cjs.summarizeEntityPerms(chunkKPKFNLQQ_cjs.permissionRowsToRecord(permRows))
31
31
  };
32
32
  }
33
33
  chunkUSNT2KNT_cjs.__name(loadDbPermissionsForUser, "loadDbPermissionsForUser");
@@ -1,4 +1,4 @@
1
- import { summarizeEntityPerms, permissionRowsToRecord } from './chunk-4TRPKBKO.js';
1
+ import { summarizeEntityPerms, permissionRowsToRecord } from './chunk-UF3BYUXY.js';
2
2
  import { __name } from './chunk-SHUYVCID.js';
3
3
 
4
4
  // src/auth/rbac-debug-db.ts
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ var chunkCOBORIJH_cjs = require('./chunk-COBORIJH.cjs');
4
+ require('./chunk-UCKN4BBY.cjs');
5
+ require('./chunk-XW5ATPRW.cjs');
6
+ require('./chunk-OOTLNH63.cjs');
7
+ require('./chunk-SPQFNIYJ.cjs');
8
+ require('./chunk-USNT2KNT.cjs');
9
+
10
+
11
+
12
+ Object.defineProperty(exports, "initWhatsappTriggerDispatcher", {
13
+ enumerable: true,
14
+ get: function () { return chunkCOBORIJH_cjs.initWhatsappTriggerDispatcher; }
15
+ });
16
+ Object.defineProperty(exports, "resendOrderNotification", {
17
+ enumerable: true,
18
+ get: function () { return chunkCOBORIJH_cjs.resendOrderNotification; }
19
+ });
@@ -0,0 +1,6 @@
1
+ export { initWhatsappTriggerDispatcher, resendOrderNotification } from './chunk-VMY2S32H.js';
2
+ import './chunk-HCIRL37O.js';
3
+ import './chunk-5ELSW2UP.js';
4
+ import './chunk-CRFV5WJK.js';
5
+ import './chunk-KFFB6EMZ.js';
6
+ import './chunk-SHUYVCID.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infuro/cms-core",
3
- "version": "1.0.35",
3
+ "version": "1.0.36",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -1,84 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
4
-
5
- // src/plugins/email/templates/layout.ts
6
- function escapeHtml(s) {
7
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
8
- }
9
- chunkUSNT2KNT_cjs.__name(escapeHtml, "escapeHtml");
10
- function socialLinkInnerHtml(s) {
11
- if (s.iconUrl?.trim()) {
12
- return `<img src="${escapeHtml(s.iconUrl.trim())}" alt="" width="20" height="20" style="display:inline-block;vertical-align:middle;border:0;" />`;
13
- }
14
- const label = s.icon && s.icon.trim() || "\u{1F517}";
15
- return escapeHtml(label);
16
- }
17
- chunkUSNT2KNT_cjs.__name(socialLinkInnerHtml, "socialLinkInnerHtml");
18
- function supportLinesHtml(supportEmail, supportPhone, opts) {
19
- const parts = [];
20
- const top = opts?.tightTop ? "margin-top:0;" : "margin-top:4px;";
21
- if (supportEmail) {
22
- parts.push(`<div style="font-size:13px;color:#444;${top}">&#128231; ${escapeHtml(supportEmail)}</div>`);
23
- }
24
- if (supportPhone) {
25
- parts.push(`<div style="font-size:13px;color:#444;margin-top:2px;">&#128222; ${escapeHtml(supportPhone)}</div>`);
26
- }
27
- return parts.join("");
28
- }
29
- chunkUSNT2KNT_cjs.__name(supportLinesHtml, "supportLinesHtml");
30
- function renderLayout(options) {
31
- const { bodyHtml, companyDetails } = options;
32
- const { logoUrl, companyName, supportEmail, supportPhone, socialLinks, footerDisclaimer, followUsTitle = "Follow Us" } = companyDetails;
33
- const supportFooterHtml = supportLinesHtml(supportEmail, supportPhone, {
34
- tightTop: true
35
- });
36
- const hasSocial = Boolean(socialLinks?.length);
37
- const brandFooterInner = [];
38
- if (logoUrl) {
39
- brandFooterInner.push(`<img src="${escapeHtml(logoUrl)}" alt="" style="max-height:28px;max-width:160px;height:auto;width:auto;display:inline-block;vertical-align:middle;margin-right:10px;border:0;" />`);
40
- }
41
- if (companyName) {
42
- brandFooterInner.push(`<span style="font-size:14px;font-weight:600;color:#111;vertical-align:middle;">${escapeHtml(companyName)}</span>`);
43
- }
44
- const brandFooterHtml = brandFooterInner.length ? `<div style="line-height:1.4;">${brandFooterInner.join("")}</div>` : "";
45
- const followTitleHtml = hasSocial && followUsTitle ? `<div class="footer-follow-title" style="font-size:13px;font-weight:600;color:#555;margin:0;">${escapeHtml(followUsTitle)}</div>` : "";
46
- const socialRowHtml = hasSocial && socialLinks ? `<div class="footer-social-icons" style="margin-top:6px;text-align:left;font-size:0;line-height:0;">${socialLinks.map((s) => `<a href="${escapeHtml(s.url)}" style="display:inline-block;margin-right:12px;text-decoration:none;color:#333;font-size:18px;line-height:1;vertical-align:middle;">${socialLinkInnerHtml(s)}</a>`).join("")}</div>` : "";
47
- const rowSupport = supportFooterHtml ? `<tr><td class="footer-support-cell" colspan="2" valign="top" style="padding:0 0 10px 0;">${supportFooterHtml}</td></tr>` : "";
48
- let footerBlock = "";
49
- if (brandFooterHtml || followTitleHtml || socialRowHtml || footerDisclaimer || rowSupport) {
50
- const rowBrand = brandFooterHtml ? `<tr><td class="footer-brand-cell" colspan="2" valign="top" style="padding:0 0 10px 0;">${brandFooterHtml}</td></tr>` : "";
51
- const rowFollowTitle = followTitleHtml ? `<tr><td class="footer-follow-cell" colspan="2" valign="top" style="padding:14px 0 0 0;text-align:left;">${followTitleHtml}</td></tr>` : "";
52
- const rowSocial = socialRowHtml ? `<tr><td class="footer-social-cell" colspan="2" style="padding:0;text-align:left;">${socialRowHtml}</td></tr>` : "";
53
- footerBlock = `<table role="presentation" class="footer-main" width="100%" cellpadding="0" cellspacing="0" style="margin-top:28px;padding-top:16px;">${rowBrand}${rowSupport}${rowFollowTitle}${rowSocial}</table>`;
54
- }
55
- const disclaimerBlock = footerDisclaimer ? `<div style="margin-top:20px;padding-top:12px;font-size:11px;line-height:1.5;color:#888;">${escapeHtml(footerDisclaimer).replace(/\n/g, "<br/>")}</div>` : "";
56
- const responsiveCss = `
57
- @media only screen and (max-width: 600px) {
58
- .email-wrap { padding-left: 12px !important; padding-right: 12px !important; }
59
- .footer-follow-cell { padding-top: 12px !important; }
60
- }
61
- `;
62
- return `<!DOCTYPE html>
63
- <html>
64
- <head>
65
- <meta charset="utf-8">
66
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
67
- <style type="text/css">${responsiveCss}</style>
68
- </head>
69
- <body style="margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;font-size:14px;line-height:1.5;color:#333;background:#fff;">
70
- <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background:#fff;">
71
- <tr><td class="email-wrap" style="padding:16px;">
72
- <div>
73
- ${bodyHtml}
74
- </div>
75
- ${footerBlock}
76
- ${disclaimerBlock}
77
- </td></tr>
78
- </table>
79
- </body>
80
- </html>`;
81
- }
82
- chunkUSNT2KNT_cjs.__name(renderLayout, "renderLayout");
83
-
84
- exports.renderLayout = renderLayout;
@@ -1,86 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
4
-
5
- // src/plugins/whatsapp/whatsapp-queue.ts
6
- var WHATSAPP_QUEUE_NAME = "whatsapp";
7
- function maskPhone(raw) {
8
- const digits = raw.replace(/\D/g, "");
9
- if (digits.length <= 4) return "****";
10
- return `${"*".repeat(Math.max(0, digits.length - 4))}${digits.slice(-4)}`;
11
- }
12
- chunkUSNT2KNT_cjs.__name(maskPhone, "maskPhone");
13
- function registerWhatsAppQueueProcessor(cms) {
14
- const queue = cms.getPlugin("queue");
15
- const whatsapp = cms.getPlugin("whatsapp");
16
- if (!queue) {
17
- console.warn("[whatsapp] queue processor not registered: queue plugin missing");
18
- return;
19
- }
20
- if (!whatsapp || typeof whatsapp.send !== "function") {
21
- console.warn("[whatsapp] queue processor not registered: whatsapp plugin missing or not configured");
22
- return;
23
- }
24
- queue.registerProcessor(WHATSAPP_QUEUE_NAME, async (data) => {
25
- const payload = data;
26
- if (!payload.to) {
27
- console.warn("[whatsapp] queue job skipped: missing recipient");
28
- return;
29
- }
30
- console.log("[whatsapp] queue job processing", {
31
- to: maskPhone(payload.to),
32
- templateKey: payload.templateKey ?? null,
33
- externalTemplateRef: payload.externalTemplateRef ?? null
34
- });
35
- try {
36
- const ok = await whatsapp.send(payload);
37
- if (ok) {
38
- console.log("[whatsapp] queue job completed", {
39
- to: maskPhone(payload.to),
40
- sent: true
41
- });
42
- } else {
43
- console.warn("[whatsapp] queue job completed without delivery", {
44
- to: maskPhone(payload.to),
45
- sent: false
46
- });
47
- }
48
- } catch (err) {
49
- console.error("[whatsapp] queue job failed", {
50
- to: maskPhone(payload.to),
51
- error: err instanceof Error ? err.message : String(err)
52
- });
53
- }
54
- });
55
- console.log("[whatsapp] queue processor registered", {
56
- queue: WHATSAPP_QUEUE_NAME
57
- });
58
- }
59
- chunkUSNT2KNT_cjs.__name(registerWhatsAppQueueProcessor, "registerWhatsAppQueueProcessor");
60
- async function queueWhatsApp(cms, payload) {
61
- const queue = cms.getPlugin("queue");
62
- if (queue) {
63
- console.log("[whatsapp] enqueue", {
64
- to: maskPhone(payload.to),
65
- templateKey: payload.templateKey ?? null,
66
- externalTemplateRef: payload.externalTemplateRef ?? null
67
- });
68
- await queue.add(WHATSAPP_QUEUE_NAME, payload);
69
- return true;
70
- }
71
- const whatsapp = cms.getPlugin("whatsapp");
72
- if (whatsapp && typeof whatsapp.send === "function") {
73
- console.log("[whatsapp] no queue plugin \u2014 sending immediately", {
74
- to: maskPhone(payload.to)
75
- });
76
- return whatsapp.send(payload);
77
- }
78
- console.warn("[whatsapp] send skipped: neither queue nor whatsapp plugin available", {
79
- to: maskPhone(payload.to)
80
- });
81
- return false;
82
- }
83
- chunkUSNT2KNT_cjs.__name(queueWhatsApp, "queueWhatsApp");
84
-
85
- exports.queueWhatsApp = queueWhatsApp;
86
- exports.registerWhatsAppQueueProcessor = registerWhatsAppQueueProcessor;