@infuro/cms-core 1.0.34 → 1.0.35

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 (158) hide show
  1. package/README.md +13 -0
  2. package/dist/OrderTrackPage-W3J6WIG2.js +426 -0
  3. package/dist/OrderTrackPage-Z6FCJQYY.cjs +428 -0
  4. package/dist/admin.cjs +34329 -20923
  5. package/dist/admin.d.cts +186 -9
  6. package/dist/admin.d.ts +186 -9
  7. package/dist/admin.js +34140 -20829
  8. package/dist/api.cjs +120 -17515
  9. package/dist/api.d.cts +633 -3
  10. package/dist/api.d.ts +633 -3
  11. package/dist/api.js +14 -17528
  12. package/dist/auth.cjs +192 -1034
  13. package/dist/auth.d.cts +194 -51
  14. package/dist/auth.d.ts +194 -51
  15. package/dist/auth.js +4 -966
  16. package/dist/chunk-2XE4X74C.js +29602 -0
  17. package/dist/chunk-3DZRIZOD.cjs +52 -0
  18. package/dist/chunk-3KPNTQBV.cjs +620 -0
  19. package/dist/chunk-46GKADYE.cjs +84 -0
  20. package/dist/chunk-4TRPKBKO.js +589 -0
  21. package/dist/chunk-5ELSW2UP.js +150 -0
  22. package/dist/chunk-6KPQWRFW.js +171 -0
  23. package/dist/chunk-7NMT3GBR.cjs +29 -0
  24. package/dist/chunk-7YIBMQDR.cjs +86 -0
  25. package/dist/chunk-BGJAV67S.cjs +29710 -0
  26. package/dist/chunk-CNTSLED2.cjs +559 -0
  27. package/dist/chunk-CRFV5WJK.js +16 -0
  28. package/dist/chunk-D5FBNKQM.cjs +104 -0
  29. package/dist/chunk-EF2JBPDM.js +114 -0
  30. package/dist/chunk-EQPITOP6.js +543 -0
  31. package/dist/chunk-GO7PPYNU.js +76 -0
  32. package/dist/chunk-HF3L2GIT.cjs +194 -0
  33. package/dist/chunk-J7XHLOLO.js +830 -0
  34. package/dist/chunk-JBRR5UYL.js +87 -0
  35. package/dist/chunk-JC6DLWTE.js +21 -0
  36. package/dist/chunk-JHF4YYRC.cjs +188 -0
  37. package/dist/chunk-JXF23MPG.js +25 -0
  38. package/dist/chunk-MQBT33IV.js +48 -0
  39. package/dist/chunk-N44BJZ4C.cjs +123 -0
  40. package/dist/chunk-OOTLNH63.cjs +18 -0
  41. package/dist/chunk-PAMVINEX.cjs +577 -0
  42. package/dist/chunk-PNOKNSG2.cjs +222 -0
  43. package/dist/chunk-QM733NUK.js +186 -0
  44. package/dist/chunk-R73BKDRO.cjs +90 -0
  45. package/dist/chunk-SHUYVCID.js +4 -0
  46. package/dist/chunk-SYBOCAWB.js +97 -0
  47. package/dist/chunk-TDV6EJHV.js +192 -0
  48. package/dist/chunk-TFUOHI37.cjs +839 -0
  49. package/dist/chunk-TIAEXJLI.cjs +182 -0
  50. package/dist/chunk-UPLVMVRX.cjs +23 -0
  51. package/dist/chunk-USNT2KNT.cjs +6 -0
  52. package/dist/chunk-WEMDMVHQ.js +216 -0
  53. package/dist/chunk-XDSNZUW7.js +564 -0
  54. package/dist/chunk-XQ3QUHWR.cjs +83 -0
  55. package/dist/chunk-XW5ATPRW.cjs +155 -0
  56. package/dist/chunk-ZQ4X6OAU.js +82 -0
  57. package/dist/chunk-ZSVCP6N3.js +83 -0
  58. package/dist/cli.cjs +103 -84
  59. package/dist/cli.js +62 -27
  60. package/dist/email-FKR4FXFI.js +5 -0
  61. package/dist/email-KVKVPNCL.cjs +58 -0
  62. package/dist/email-queue-CGZBVVAS.js +2 -0
  63. package/dist/email-queue-TPZWLTIV.cjs +23 -0
  64. package/dist/erp-config-enabled-CUMQ6N2V.cjs +11 -0
  65. package/dist/erp-config-enabled-T37X7T34.js +2 -0
  66. package/dist/erp-order-invoice-3YISSOWW.js +3 -0
  67. package/dist/erp-order-invoice-ZR5F2KTA.cjs +12 -0
  68. package/dist/event-order-defaults-6E543227.js +2 -0
  69. package/dist/event-order-defaults-DUGDVGJI.cjs +39 -0
  70. package/dist/event-order-notifications-5GSAOYVS.cjs +27 -0
  71. package/dist/event-order-notifications-IIIF23D5.js +10 -0
  72. package/dist/hooks.cjs +259 -132
  73. package/dist/hooks.d.cts +42 -1
  74. package/dist/hooks.d.ts +42 -1
  75. package/dist/hooks.js +234 -91
  76. package/dist/index.cjs +3884 -22307
  77. package/dist/index.d.cts +2203 -772
  78. package/dist/index.d.ts +2203 -772
  79. package/dist/index.js +2871 -22064
  80. package/dist/interpolate-WAKPN56R.cjs +11 -0
  81. package/dist/interpolate-WDUWDF3I.js +2 -0
  82. package/dist/layout-36UFTHC5.cjs +11 -0
  83. package/dist/layout-AOBN26XG.js +2 -0
  84. package/dist/migrations/1779400000000-ConvertStatusToEnum.ts +142 -0
  85. package/dist/migrations/1779400000000-SeedDefaultCurrencies.ts +33 -0
  86. package/dist/migrations/1779500000000-VendorRolesAndPermissions.ts +102 -0
  87. package/dist/migrations/1779600000000-VendorRegistrationProfile.ts +52 -0
  88. package/dist/migrations/1779700000000-CollectionIsCatalog.ts +22 -0
  89. package/dist/migrations/1779710000000-CollectionPlatformCatalog.ts +60 -0
  90. package/dist/migrations/1779720000000-ProductCategoryPlatformCatalog.ts +157 -0
  91. package/dist/migrations/1779800000000-EventsAndEventProducts.ts +173 -0
  92. package/dist/migrations/1779810000000-BackfillVendorRoleEventsPermissions.ts +38 -0
  93. package/dist/migrations/1779820000000-FixProductsCategoryForeignKey.ts +70 -0
  94. package/dist/migrations/1779830000000-ProductTitleColumn.ts +32 -0
  95. package/dist/migrations/1779840000000-EventAboutAndVisibilityFields.ts +34 -0
  96. package/dist/migrations/1779850000000-EventCityCountrySplit.ts +43 -0
  97. package/dist/migrations/1779860000000-CreateCombos.ts +140 -0
  98. package/dist/migrations/1780100000000-OrderAttendeesEventId.ts +55 -0
  99. package/dist/migrations/1780110000000-EventContactFormId.ts +49 -0
  100. package/dist/migrations/1780130000000-ProductVariants.ts +54 -0
  101. package/dist/migrations/1780140000000-EventManagementEnhancements.ts +44 -0
  102. package/dist/migrations/1780160000000-EventRegistrationGstProductContactForm.ts +79 -0
  103. package/dist/migrations/1780170000000-ComboCurrencyPrices.ts +20 -0
  104. package/dist/migrations/1781110000000-VendorOwnerCombosPermission.ts +38 -0
  105. package/dist/migrations/1781120000000-RefundPoliciesAndRequests.ts +225 -0
  106. package/dist/migrations/1781130000000-CreateAttendees.ts +44 -0
  107. package/dist/migrations/1781140000000-EventOrderNotifications.ts +29 -0
  108. package/dist/migrations/1781150000000-EventNamedLists.ts +28 -0
  109. package/dist/migrations/1781160000000-RefundPolicyEventTiers.ts +27 -0
  110. package/dist/migrations/1781170000000-EventRefundPolicy.ts +42 -0
  111. package/dist/migrations/1781180000000-RemoveCartItemsUniqueConstraint.ts +15 -0
  112. package/dist/migrations/1781190000000-RenameProductTaxesToProductConfig.ts +84 -0
  113. package/dist/migrations/1781200000000-VendorOwnerProductConfigPermissions.ts +51 -0
  114. package/dist/migrations/1781210000000-VendorRoleProductConfigPermissions.ts +46 -0
  115. package/dist/migrations/helpers/vendor-role-seed.ts +243 -0
  116. package/dist/paid-order-erp-3USEG6WL.js +3 -0
  117. package/dist/paid-order-erp-FSQ3GSXE.cjs +12 -0
  118. package/dist/pg-boss-service-4XF2TQ2E.js +2 -0
  119. package/dist/pg-boss-service-L6MTF4EQ.cjs +15 -0
  120. package/dist/razorpay-KLO2KNCB.js +49 -0
  121. package/dist/razorpay-U23LGY72.cjs +56 -0
  122. package/dist/rbac-debug-db-D7ME7QUY.cjs +35 -0
  123. package/dist/rbac-debug-db-MTCTVNNM.js +33 -0
  124. package/dist/sms-defaults-2NL24H57.js +2 -0
  125. package/dist/sms-defaults-KCOPKQBA.cjs +19 -0
  126. package/dist/stripe-4FD27QVJ.js +51 -0
  127. package/dist/stripe-VU6OEG2D.cjs +57 -0
  128. package/dist/theme.cjs +31 -59
  129. package/dist/theme.d.cts +78 -3
  130. package/dist/theme.d.ts +78 -3
  131. package/dist/theme.js +23 -20
  132. package/dist/vendor-invite-status-77O7ZQ3U.cjs +19 -0
  133. package/dist/vendor-invite-status-PWJ3DE76.js +2 -0
  134. package/dist/whatsapp-queue-3DXA4MXU.js +2 -0
  135. package/dist/whatsapp-queue-KG65MXD5.cjs +15 -0
  136. package/package.json +147 -142
  137. package/dist/admin.cjs.map +0 -1
  138. package/dist/admin.js.map +0 -1
  139. package/dist/api.cjs.map +0 -1
  140. package/dist/api.js.map +0 -1
  141. package/dist/auth.cjs.map +0 -1
  142. package/dist/auth.js.map +0 -1
  143. package/dist/cli.cjs.map +0 -1
  144. package/dist/cli.js.map +0 -1
  145. package/dist/config-DJ5CmQvS.d.cts +0 -8
  146. package/dist/config-DJ5CmQvS.d.ts +0 -8
  147. package/dist/hooks.cjs.map +0 -1
  148. package/dist/hooks.js.map +0 -1
  149. package/dist/index-Bf5GO8fu.d.cts +0 -583
  150. package/dist/index-DOiJuMQA.d.ts +0 -583
  151. package/dist/index.cjs.map +0 -1
  152. package/dist/index.js.map +0 -1
  153. package/dist/theme.cjs.map +0 -1
  154. package/dist/theme.js.map +0 -1
  155. package/dist/types-DCVaXlPV.d.cts +0 -78
  156. package/dist/types-DCVaXlPV.d.ts +0 -78
  157. package/dist/vendor-scope-DTYhJk_I.d.cts +0 -129
  158. package/dist/vendor-scope-DTYhJk_I.d.ts +0 -129
@@ -0,0 +1,577 @@
1
+ 'use strict';
2
+
3
+ var chunkXW5ATPRW_cjs = require('./chunk-XW5ATPRW.cjs');
4
+ var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
5
+
6
+ // src/plugins/email/templates/types.ts
7
+ function normalizeSocialLinkItem(o) {
8
+ const url = String(o.url ?? "").trim();
9
+ if (!url) return null;
10
+ let iconUrl = String(o.iconUrl ?? o.icon_image ?? "").trim();
11
+ let icon = String(o.icon ?? "").trim();
12
+ if (!iconUrl && /^https?:\/\//i.test(icon)) {
13
+ iconUrl = icon;
14
+ icon = "";
15
+ }
16
+ const item = {
17
+ url
18
+ };
19
+ if (iconUrl) item.iconUrl = iconUrl;
20
+ if (icon) item.icon = icon;
21
+ return item;
22
+ }
23
+ chunkUSNT2KNT_cjs.__name(normalizeSocialLinkItem, "normalizeSocialLinkItem");
24
+ function parseSocialLinksJson(raw) {
25
+ if (raw == null || raw.trim() === "") return void 0;
26
+ try {
27
+ const parsed = JSON.parse(raw);
28
+ if (!Array.isArray(parsed)) return void 0;
29
+ const out = [];
30
+ for (const item of parsed) {
31
+ if (item && typeof item === "object" && "url" in item) {
32
+ const n = normalizeSocialLinkItem(item);
33
+ if (n) out.push(n);
34
+ }
35
+ }
36
+ return out.length ? out : void 0;
37
+ } catch {
38
+ return void 0;
39
+ }
40
+ }
41
+ chunkUSNT2KNT_cjs.__name(parseSocialLinksJson, "parseSocialLinksJson");
42
+ function mergeEmailLayoutCompanyDetails(branding, emailSettings) {
43
+ const fromBranding = getCompanyDetailsFromSettings(branding);
44
+ const pick = /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((emailVal, fallback) => {
45
+ const t = emailVal?.trim();
46
+ return t || fallback?.trim() || void 0;
47
+ }, "pick");
48
+ const logoUrl = pick(emailSettings.logoUrl ?? emailSettings.emailLogoUrl, fromBranding.logoUrl);
49
+ const companyName = pick(emailSettings.companyName ?? emailSettings.emailCompanyName, fromBranding.companyName);
50
+ const supportEmail = pick(emailSettings.supportEmail ?? emailSettings.emailSupportEmail, fromBranding.supportEmail);
51
+ const supportPhone = pick(emailSettings.supportPhone, void 0);
52
+ const footerDisclaimer = pick(emailSettings.footerDisclaimer, void 0);
53
+ const followUsTitle = pick(emailSettings.followUsTitle, "Follow Us") || "Follow Us";
54
+ const socialFromEmail = parseSocialLinksJson(emailSettings.socialLinks);
55
+ const socialLinks = socialFromEmail?.length ? socialFromEmail : fromBranding.socialLinks;
56
+ return {
57
+ logoUrl,
58
+ companyName,
59
+ supportEmail,
60
+ supportPhone,
61
+ socialLinks,
62
+ footerDisclaimer,
63
+ followUsTitle
64
+ };
65
+ }
66
+ chunkUSNT2KNT_cjs.__name(mergeEmailLayoutCompanyDetails, "mergeEmailLayoutCompanyDetails");
67
+ function getCompanyDetailsFromSettings(settingsGroup) {
68
+ const logoUrl = settingsGroup.logo ?? settingsGroup.logoUrl ?? "";
69
+ const companyName = settingsGroup.companyName ?? settingsGroup.company_name ?? "";
70
+ const supportEmail = settingsGroup.supportEmail ?? settingsGroup.support_email ?? "";
71
+ let socialLinks = [];
72
+ const raw = settingsGroup.socialLinks ?? settingsGroup.social_links;
73
+ if (typeof raw === "string") {
74
+ try {
75
+ const arr = JSON.parse(raw);
76
+ if (Array.isArray(arr)) {
77
+ for (const item of arr) {
78
+ if (item && typeof item === "object") {
79
+ const n = normalizeSocialLinkItem(item);
80
+ if (n) socialLinks.push(n);
81
+ }
82
+ }
83
+ }
84
+ } catch {
85
+ }
86
+ }
87
+ return {
88
+ logoUrl: logoUrl || void 0,
89
+ companyName: companyName || void 0,
90
+ supportEmail: supportEmail || void 0,
91
+ socialLinks: socialLinks.length ? socialLinks : void 0
92
+ };
93
+ }
94
+ chunkUSNT2KNT_cjs.__name(getCompanyDetailsFromSettings, "getCompanyDetailsFromSettings");
95
+
96
+ // src/lib/email-recipients.ts
97
+ function parseEmailRecipientsFromConfig(raw) {
98
+ if (raw == null || raw === "") return [];
99
+ const trimmed = raw.trim();
100
+ if (trimmed.startsWith("[")) {
101
+ try {
102
+ const parsed = JSON.parse(trimmed);
103
+ if (Array.isArray(parsed)) {
104
+ return parsed.map((e) => String(e).trim()).filter(Boolean);
105
+ }
106
+ } catch {
107
+ }
108
+ }
109
+ return trimmed.split(/[,;]+/).map((s) => s.trim()).filter(Boolean);
110
+ }
111
+ chunkUSNT2KNT_cjs.__name(parseEmailRecipientsFromConfig, "parseEmailRecipientsFromConfig");
112
+ function serializeEmailRecipients(emails) {
113
+ return JSON.stringify(emails);
114
+ }
115
+ chunkUSNT2KNT_cjs.__name(serializeEmailRecipients, "serializeEmailRecipients");
116
+ function joinRecipientsForSend(emails) {
117
+ if (!emails.length) return null;
118
+ return emails.join(", ");
119
+ }
120
+ chunkUSNT2KNT_cjs.__name(joinRecipientsForSend, "joinRecipientsForSend");
121
+
122
+ // src/plugins/llm/chat-email-intent.ts
123
+ var NONE_INTENT = "NONE";
124
+ var CHAT_EMAIL_LOG = "[chat-email-tool]";
125
+ function logChatEmail(step, data) {
126
+ if (data && Object.keys(data).length > 0) {
127
+ console.info(CHAT_EMAIL_LOG, step, data);
128
+ } else {
129
+ console.info(CHAT_EMAIL_LOG, step);
130
+ }
131
+ }
132
+ chunkUSNT2KNT_cjs.__name(logChatEmail, "logChatEmail");
133
+ function normalizeIntentKey(raw) {
134
+ return raw.trim().toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
135
+ }
136
+ chunkUSNT2KNT_cjs.__name(normalizeIntentKey, "normalizeIntentKey");
137
+ function parseIntentsJson(raw) {
138
+ if (!raw?.trim()) return null;
139
+ try {
140
+ const parsed = JSON.parse(raw);
141
+ if (!Array.isArray(parsed)) return null;
142
+ const out = [];
143
+ for (const row of parsed) {
144
+ if (!row || typeof row !== "object") continue;
145
+ const o = row;
146
+ const intent = normalizeIntentKey(String(o.intent ?? o.id ?? ""));
147
+ const description = String(o.description ?? "").trim();
148
+ const emailTo = String(o.emailTo ?? o.email ?? "").trim();
149
+ if (!intent || !description || !emailTo) continue;
150
+ out.push({
151
+ intent,
152
+ description,
153
+ emailTo
154
+ });
155
+ }
156
+ return out.length > 0 ? out : null;
157
+ } catch {
158
+ return null;
159
+ }
160
+ }
161
+ chunkUSNT2KNT_cjs.__name(parseIntentsJson, "parseIntentsJson");
162
+ function dedupeIntents(intents) {
163
+ const seen = /* @__PURE__ */ new Set();
164
+ const out = [];
165
+ for (const row of intents) {
166
+ const key = normalizeIntentKey(row.intent);
167
+ if (!key || seen.has(key)) continue;
168
+ seen.add(key);
169
+ out.push({
170
+ intent: key,
171
+ description: row.description.trim(),
172
+ emailTo: row.emailTo.trim()
173
+ });
174
+ }
175
+ return out;
176
+ }
177
+ chunkUSNT2KNT_cjs.__name(dedupeIntents, "dedupeIntents");
178
+ function parseChatEmailToolSettings(map) {
179
+ const fromJson = parseIntentsJson(map.emailIntents);
180
+ const intents = dedupeIntents(fromJson ?? []);
181
+ const legacyPositive = map.emailIntentPrompt?.trim() ?? "";
182
+ const legacyNegative = map.emailNegativeIntentPrompt?.trim() ?? "";
183
+ let classifierInstructions = map.emailClassifierInstructions?.trim() ?? "";
184
+ if (!classifierInstructions && (legacyPositive || legacyNegative)) {
185
+ const parts = [];
186
+ if (legacyPositive) parts.push(`Legacy positive signals:
187
+ ${legacyPositive}`);
188
+ if (legacyNegative) parts.push(`Do NOT assign an intent when:
189
+ ${legacyNegative}`);
190
+ classifierInstructions = parts.join("\n\n");
191
+ }
192
+ return {
193
+ enabled: map.emailToolEnabled === "true",
194
+ intents,
195
+ classifierInstructions,
196
+ toolPrompt: map.emailToolPrompt ?? ""
197
+ };
198
+ }
199
+ chunkUSNT2KNT_cjs.__name(parseChatEmailToolSettings, "parseChatEmailToolSettings");
200
+ var EMAIL_TOOL_VALIDATION_KEY = "emailTool";
201
+ function parseEmailToolObject(raw) {
202
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
203
+ const o = raw;
204
+ const intentsRaw = o.intents;
205
+ let intents;
206
+ if (Array.isArray(intentsRaw)) {
207
+ const parsed = parseIntentsJson(JSON.stringify(intentsRaw));
208
+ if (parsed?.length) intents = parsed;
209
+ }
210
+ return {
211
+ enabled: o.enabled === true,
212
+ classifierInstructions: typeof o.classifierInstructions === "string" ? o.classifierInstructions.trim() : void 0,
213
+ toolPrompt: typeof o.toolPrompt === "string" ? o.toolPrompt.trim() : void 0,
214
+ intents
215
+ };
216
+ }
217
+ chunkUSNT2KNT_cjs.__name(parseEmailToolObject, "parseEmailToolObject");
218
+ function parseEmailToolFromAgentValidationRules(validationRulesText) {
219
+ const raw = validationRulesText?.trim();
220
+ if (!raw) return null;
221
+ try {
222
+ const parsed = JSON.parse(raw);
223
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
224
+ const emailTool = parsed[EMAIL_TOOL_VALIDATION_KEY];
225
+ return parseEmailToolObject(emailTool);
226
+ } catch {
227
+ return null;
228
+ }
229
+ }
230
+ chunkUSNT2KNT_cjs.__name(parseEmailToolFromAgentValidationRules, "parseEmailToolFromAgentValidationRules");
231
+ function resolveChatEmailToolSettings(configMap, sources) {
232
+ const fromConfig = parseChatEmailToolSettings(configMap);
233
+ const resolved = typeof sources === "string" || sources == null ? {
234
+ chatbotValidationRules: typeof sources === "string" ? sources : null
235
+ } : sources;
236
+ const fromChatbot = parseEmailToolFromAgentValidationRules(resolved.chatbotValidationRules);
237
+ const fromNotify = resolved.notifyAgent ? parseEmailToolFromAgentValidationRules(resolved.notifyAgent.validationRules) : null;
238
+ const notifySystem = resolved.notifyAgent?.systemInstruction?.trim() ?? "";
239
+ const intents = fromNotify?.intents?.length ? fromNotify.intents : fromChatbot?.intents?.length ? fromChatbot.intents : fromConfig.intents;
240
+ const classifierParts = [
241
+ notifySystem,
242
+ fromNotify?.classifierInstructions?.trim(),
243
+ fromChatbot?.classifierInstructions?.trim(),
244
+ fromConfig.classifierInstructions.trim()
245
+ ].filter(Boolean);
246
+ const toolPrompt = fromNotify?.toolPrompt?.trim() || fromChatbot?.toolPrompt?.trim() || fromConfig.toolPrompt?.trim() || "";
247
+ return {
248
+ enabled: fromConfig.enabled,
249
+ intents,
250
+ classifierInstructions: classifierParts.join("\n\n"),
251
+ toolPrompt
252
+ };
253
+ }
254
+ chunkUSNT2KNT_cjs.__name(resolveChatEmailToolSettings, "resolveChatEmailToolSettings");
255
+ function intentByKey(intents, key) {
256
+ if (!key) return null;
257
+ const norm = normalizeIntentKey(key);
258
+ return intents.find((i) => i.intent === norm) ?? null;
259
+ }
260
+ chunkUSNT2KNT_cjs.__name(intentByKey, "intentByKey");
261
+ function buildIntentTableForPrompt(intents) {
262
+ return intents.map((i) => `- ${i.intent}: ${i.description} \u2192 notify ${i.emailTo}`).join("\n");
263
+ }
264
+ chunkUSNT2KNT_cjs.__name(buildIntentTableForPrompt, "buildIntentTableForPrompt");
265
+ function buildIntentClassifierSystem(config, agentClassifierInstructions) {
266
+ const table = buildIntentTableForPrompt(config.intents);
267
+ const extra = [
268
+ agentClassifierInstructions?.trim(),
269
+ config.classifierInstructions.trim()
270
+ ].filter(Boolean).join("\n\n");
271
+ const intentKeys = config.intents.map((i) => i.intent).join(", ");
272
+ return `You classify a chat visitor into exactly one lead intent for email routing.
273
+
274
+ Available intents (pick the best match):
275
+ ${table}
276
+
277
+ If the visitor is not ready for a lead email (general FAQ, greetings only, spam, off-topic, no clear business need), use intent "${NONE_INTENT}".
278
+
279
+ Allowed intent values: ${intentKeys}, or ${NONE_INTENT}.
280
+
281
+ ${extra ? `Additional instructions:
282
+ ${extra}
283
+ ` : ""}
284
+ Reply with ONLY valid JSON, no markdown:
285
+ {"intent":"INTENT_KEY","reason":"short explanation"}
286
+ Use "${NONE_INTENT}" when no intent applies.`;
287
+ }
288
+ chunkUSNT2KNT_cjs.__name(buildIntentClassifierSystem, "buildIntentClassifierSystem");
289
+ function buildChatEmailAgentContext(settings) {
290
+ if (!settings.enabled) return "";
291
+ const classifier = settings.classifierInstructions.trim();
292
+ const extra = settings.toolPrompt?.trim() ?? "";
293
+ const parts = [];
294
+ if (settings.intents.length > 0) {
295
+ parts.push("## Lead email routing", "When a visitor message clearly matches an intent below, the system sends one team notification email (per conversation). Continue the conversation normally in all cases.");
296
+ if (classifier) parts.push(`### Routing rules
297
+ ${classifier}`);
298
+ parts.push(`### Intent catalog
299
+ ${buildIntentTableForPrompt(settings.intents)}`);
300
+ } else if (classifier) {
301
+ parts.push(`## Lead email routing
302
+ ${classifier}`);
303
+ }
304
+ if (extra) parts.push(`### Assistant behavior
305
+ ${extra}`);
306
+ return parts.join("\n\n");
307
+ }
308
+ chunkUSNT2KNT_cjs.__name(buildChatEmailAgentContext, "buildChatEmailAgentContext");
309
+ function buildChatbotSystemPromptWithEmailTool(baseSystemInstruction, guardrailsForPrompt, emailSettings) {
310
+ let prompt = (baseSystemInstruction ?? "").trim();
311
+ const guard = guardrailsForPrompt?.trim();
312
+ if (guard) prompt = [
313
+ prompt,
314
+ guard
315
+ ].filter(Boolean).join("\n\n");
316
+ if (emailSettings.enabled) {
317
+ const emailCtx = buildChatEmailAgentContext(emailSettings);
318
+ if (emailCtx) prompt = [
319
+ prompt,
320
+ emailCtx
321
+ ].filter(Boolean).join("\n\n");
322
+ }
323
+ return prompt;
324
+ }
325
+ chunkUSNT2KNT_cjs.__name(buildChatbotSystemPromptWithEmailTool, "buildChatbotSystemPromptWithEmailTool");
326
+ function formatTranscript(history, latestMessage, maxChars = 4e3) {
327
+ const lines = [];
328
+ for (const m of history) {
329
+ const role = m.role === "assistant" ? "Assistant" : m.role === "user" ? "Visitor" : "System";
330
+ lines.push(`${role}: ${m.content}`);
331
+ }
332
+ const last = history[history.length - 1];
333
+ if (!last || last.role !== "user" || last.content !== latestMessage) {
334
+ lines.push(`Visitor: ${latestMessage}`);
335
+ }
336
+ let text = lines.join("\n");
337
+ if (text.length > maxChars) text = text.slice(-maxChars);
338
+ return text;
339
+ }
340
+ chunkUSNT2KNT_cjs.__name(formatTranscript, "formatTranscript");
341
+ function parseIntentJson(raw, intents) {
342
+ const trimmed = raw.trim();
343
+ const fence = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/i);
344
+ const candidate = (fence?.[1] ?? trimmed).trim();
345
+ const tryParse = /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((s) => {
346
+ const o = JSON.parse(s);
347
+ let intentRaw = null;
348
+ if (typeof o.intent === "string") intentRaw = o.intent;
349
+ else if (o.interested === false) intentRaw = NONE_INTENT;
350
+ else if (o.interested === true && intents[0]) intentRaw = intents[0].intent;
351
+ if (intentRaw == null) return null;
352
+ const reason = typeof o.reason === "string" && o.reason.trim() ? o.reason.trim() : "Classified from conversation";
353
+ return {
354
+ intent: normalizeIntentKey(intentRaw),
355
+ reason
356
+ };
357
+ }, "tryParse");
358
+ try {
359
+ return tryParse(candidate);
360
+ } catch {
361
+ const m = candidate.match(/\{[\s\S]*\}/);
362
+ if (!m) return null;
363
+ try {
364
+ return tryParse(m[0]);
365
+ } catch {
366
+ return null;
367
+ }
368
+ }
369
+ }
370
+ chunkUSNT2KNT_cjs.__name(parseIntentJson, "parseIntentJson");
371
+ async function detectChatLeadIntent(llm, params) {
372
+ if (!params.settings.intents.length) {
373
+ logChatEmail("classify skipped", {
374
+ reason: "no_intents_configured"
375
+ });
376
+ return {
377
+ intent: null,
378
+ intentLabel: "NONE",
379
+ reason: "No lead intents configured",
380
+ emailTo: null
381
+ };
382
+ }
383
+ logChatEmail("classify start", {
384
+ intentCount: params.settings.intents.length,
385
+ intentKeys: params.settings.intents.map((i) => i.intent),
386
+ model: params.model?.trim() || "(gateway default)",
387
+ messageChars: params.message.length,
388
+ historyTurns: params.history.length,
389
+ hasClassifierInstructions: Boolean(params.agentClassifierInstructions?.trim() || params.settings.classifierInstructions.trim())
390
+ });
391
+ const transcript = formatTranscript(params.history, params.message);
392
+ const contactLines = [
393
+ params.contact.name?.trim() ? `Name: ${params.contact.name.trim()}` : null,
394
+ params.contact.email?.trim() ? `Email: ${params.contact.email.trim()}` : null,
395
+ params.contact.phone?.trim() ? `Phone: ${params.contact.phone.trim()}` : null
396
+ ].filter(Boolean).join("\n");
397
+ const userPrompt = `Customer:
398
+ ${contactLines || "(unknown)"}
399
+
400
+ Conversation:
401
+ ${transcript}
402
+
403
+ Pick the single best intent for the visitor's latest message.`;
404
+ const res = await llm.chatAgent({
405
+ systemPrompt: buildIntentClassifierSystem(params.settings, params.agentClassifierInstructions),
406
+ userPrompt,
407
+ temperature: 0.1,
408
+ max_tokens: 256,
409
+ ...params.model?.trim() ? {
410
+ model: params.model.trim()
411
+ } : {}
412
+ });
413
+ const rawContent = res.content ?? "";
414
+ logChatEmail("classify llm response", {
415
+ responseChars: rawContent.length,
416
+ responsePreview: rawContent.slice(0, 280) + (rawContent.length > 280 ? "\u2026" : "")
417
+ });
418
+ const parsed = parseIntentJson(rawContent, params.settings.intents);
419
+ if (!parsed) {
420
+ logChatEmail("classify result", {
421
+ matched: false,
422
+ outcome: "parse_failed",
423
+ emailWillSend: false
424
+ });
425
+ return {
426
+ intent: null,
427
+ intentLabel: "Unclassified",
428
+ reason: "Could not parse intent classifier response",
429
+ emailTo: null
430
+ };
431
+ }
432
+ if (parsed.intent === NONE_INTENT) {
433
+ logChatEmail("classify result", {
434
+ matched: false,
435
+ outcome: NONE_INTENT,
436
+ reason: parsed.reason,
437
+ emailWillSend: false
438
+ });
439
+ return {
440
+ intent: null,
441
+ intentLabel: NONE_INTENT,
442
+ reason: parsed.reason,
443
+ emailTo: null
444
+ };
445
+ }
446
+ const matched = intentByKey(params.settings.intents, parsed.intent);
447
+ if (!matched) {
448
+ logChatEmail("classify result", {
449
+ matched: false,
450
+ outcome: "unknown_intent",
451
+ parsedIntent: parsed.intent,
452
+ reason: parsed.reason,
453
+ emailWillSend: false
454
+ });
455
+ return {
456
+ intent: null,
457
+ intentLabel: parsed.intent,
458
+ reason: `Unknown intent "${parsed.intent}": ${parsed.reason}`,
459
+ emailTo: null
460
+ };
461
+ }
462
+ logChatEmail("classify result", {
463
+ matched: true,
464
+ outcome: "intent_found",
465
+ intent: matched.intent,
466
+ emailTo: matched.emailTo,
467
+ reason: parsed.reason,
468
+ emailWillSend: true
469
+ });
470
+ return {
471
+ intent: matched.intent,
472
+ intentLabel: `${matched.intent} \u2014 ${matched.description}`,
473
+ reason: parsed.reason,
474
+ emailTo: matched.emailTo
475
+ };
476
+ }
477
+ chunkUSNT2KNT_cjs.__name(detectChatLeadIntent, "detectChatLeadIntent");
478
+ function buildTranscriptForLeadEmail(history, latestMessage) {
479
+ return formatTranscript(history, latestMessage);
480
+ }
481
+ chunkUSNT2KNT_cjs.__name(buildTranscriptForLeadEmail, "buildTranscriptForLeadEmail");
482
+ function parseIntentRecipientEmails(emailTo) {
483
+ return emailTo.split(/[,;]+/).map((s) => s.trim()).filter((s) => s.length > 0 && s.includes("@"));
484
+ }
485
+ chunkUSNT2KNT_cjs.__name(parseIntentRecipientEmails, "parseIntentRecipientEmails");
486
+
487
+ // src/plugins/email/chat-lead-email.ts
488
+ function resolveLeadRecipients(emailPlugin, emailSettings) {
489
+ const fromCrm = parseEmailRecipientsFromConfig(emailSettings.crmEmails ?? emailSettings.crmEmail ?? "");
490
+ if (fromCrm.length > 0) return fromCrm;
491
+ const fallback = emailPlugin.getDefaultTo?.() ?? "";
492
+ if (fallback.trim()) return [
493
+ fallback.trim()
494
+ ];
495
+ return [];
496
+ }
497
+ chunkUSNT2KNT_cjs.__name(resolveLeadRecipients, "resolveLeadRecipients");
498
+ async function sendChatLeadEmail(cms, emailSettings, brandingSettings, input) {
499
+ console.info(CHAT_EMAIL_LOG, "send start", {
500
+ conversationId: input.conversationId,
501
+ intentCode: input.intentCode ?? null,
502
+ contactEmail: input.contactEmail,
503
+ contactName: input.contactName,
504
+ explicitRecipients: input.recipients?.length ?? 0
505
+ });
506
+ const email = cms.getPlugin("email");
507
+ if (!email?.send || !email.renderTemplate) {
508
+ console.warn(CHAT_EMAIL_LOG, "send failed", {
509
+ conversationId: input.conversationId,
510
+ reason: "email_plugin_disabled"
511
+ });
512
+ return {
513
+ sent: false,
514
+ recipients: [],
515
+ error: "Email plugin is not enabled"
516
+ };
517
+ }
518
+ const recipients = input.recipients?.filter((r) => r.trim().includes("@")).map((r) => r.trim()) ?? resolveLeadRecipients(email, emailSettings);
519
+ if (recipients.length === 0) {
520
+ console.warn(CHAT_EMAIL_LOG, "send failed", {
521
+ conversationId: input.conversationId,
522
+ reason: "no_recipients"
523
+ });
524
+ return {
525
+ sent: false,
526
+ recipients: [],
527
+ error: "No lead email recipients (configure intent Email To, CRM emails, or SMTP default To)"
528
+ };
529
+ }
530
+ console.info(CHAT_EMAIL_LOG, "send recipients resolved", {
531
+ conversationId: input.conversationId,
532
+ recipients,
533
+ source: input.recipients?.length ? "intent_email_to" : "crm_or_smtp_fallback"
534
+ });
535
+ const companyDetails = mergeEmailLayoutCompanyDetails(brandingSettings, emailSettings);
536
+ const ctx = {
537
+ ...input,
538
+ companyDetails: input.companyDetails ?? companyDetails
539
+ };
540
+ let anySent = false;
541
+ for (const to of recipients) {
542
+ await chunkXW5ATPRW_cjs.queueEmail(cms, {
543
+ to,
544
+ templateName: "chatLead",
545
+ ctx
546
+ });
547
+ console.info(CHAT_EMAIL_LOG, "send queued", {
548
+ conversationId: input.conversationId,
549
+ to,
550
+ template: "chatLead"
551
+ });
552
+ anySent = true;
553
+ }
554
+ console.info(CHAT_EMAIL_LOG, "send complete", {
555
+ conversationId: input.conversationId,
556
+ sent: anySent,
557
+ recipientCount: recipients.length
558
+ });
559
+ return {
560
+ sent: anySent,
561
+ recipients
562
+ };
563
+ }
564
+ chunkUSNT2KNT_cjs.__name(sendChatLeadEmail, "sendChatLeadEmail");
565
+
566
+ exports.CHAT_EMAIL_LOG = CHAT_EMAIL_LOG;
567
+ exports.buildChatbotSystemPromptWithEmailTool = buildChatbotSystemPromptWithEmailTool;
568
+ exports.buildTranscriptForLeadEmail = buildTranscriptForLeadEmail;
569
+ exports.detectChatLeadIntent = detectChatLeadIntent;
570
+ exports.getCompanyDetailsFromSettings = getCompanyDetailsFromSettings;
571
+ exports.joinRecipientsForSend = joinRecipientsForSend;
572
+ exports.mergeEmailLayoutCompanyDetails = mergeEmailLayoutCompanyDetails;
573
+ exports.parseEmailRecipientsFromConfig = parseEmailRecipientsFromConfig;
574
+ exports.parseIntentRecipientEmails = parseIntentRecipientEmails;
575
+ exports.resolveChatEmailToolSettings = resolveChatEmailToolSettings;
576
+ exports.sendChatLeadEmail = sendChatLeadEmail;
577
+ exports.serializeEmailRecipients = serializeEmailRecipients;