@infuro/cms-core 1.0.57 → 1.0.59

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  var chunkXQ3QUHWR_cjs = require('./chunk-XQ3QUHWR.cjs');
4
4
  var chunkHY3AXLOI_cjs = require('./chunk-HY3AXLOI.cjs');
5
- var chunkJN4AFHZ4_cjs = require('./chunk-JN4AFHZ4.cjs');
5
+ var chunkHXLC56ZK_cjs = require('./chunk-HXLC56ZK.cjs');
6
6
  var chunk7NMT3GBR_cjs = require('./chunk-7NMT3GBR.cjs');
7
7
  var chunkV25RDUOU_cjs = require('./chunk-V25RDUOU.cjs');
8
8
  var chunkBXYZDMTZ_cjs = require('./chunk-BXYZDMTZ.cjs');
@@ -1520,6 +1520,36 @@ async function validateLlmAgentScopeForWrite(dataSource, entityMap, scope, exclu
1520
1520
  chunkUSNT2KNT_cjs.__name(validateLlmAgentScopeForWrite, "validateLlmAgentScopeForWrite");
1521
1521
 
1522
1522
  // src/api/crud.ts
1523
+ async function autoExpireOrderIfPaymentTimeExceeded(dataSource, entityMap, order) {
1524
+ if (!order || typeof order !== "object") return order;
1525
+ const status = String(order.status ?? "").toLowerCase();
1526
+ if (status !== "pending") return order;
1527
+ const meta = typeof order.metadata === "object" && order.metadata ? order.metadata : {};
1528
+ const expiresAtStr = meta.paymentExpiresAt ? String(meta.paymentExpiresAt) : null;
1529
+ if (!expiresAtStr) return order;
1530
+ const expiresMs = new Date(expiresAtStr).getTime();
1531
+ if (Number.isNaN(expiresMs) || Date.now() <= expiresMs) return order;
1532
+ try {
1533
+ const orderId = Number(order.id);
1534
+ if (orderId && entityMap.orders) {
1535
+ const orderRepo = dataSource.getRepository(entityMap.orders);
1536
+ const updatedMeta = {
1537
+ ...meta,
1538
+ cancelReason: "Payment window expired (10 minutes)"
1539
+ };
1540
+ await orderRepo.update(orderId, {
1541
+ status: "cancelled",
1542
+ metadata: updatedMeta
1543
+ });
1544
+ order.status = "cancelled";
1545
+ order.metadata = updatedMeta;
1546
+ }
1547
+ } catch (err) {
1548
+ console.error("[payment-expiry] Auto-cancelling expired order failed", err);
1549
+ }
1550
+ return order;
1551
+ }
1552
+ chunkUSNT2KNT_cjs.__name(autoExpireOrderIfPaymentTimeExceeded, "autoExpireOrderIfPaymentTimeExceeded");
1523
1553
  var CRUD_LOG = "[cms-crud]";
1524
1554
  function logCrudClientError(op, detail) {
1525
1555
  console.warn(CRUD_LOG, op, detail);
@@ -3564,6 +3594,12 @@ function createCrudHandler(dataSource, entityMap, options) {
3564
3594
  }
3565
3595
  const itemsSummary = parts.join(", ") || "\u2014";
3566
3596
  const { payments: _payments, ...orderWithoutPayments } = order;
3597
+ const rawPayStatus = String(orderPayments[0]?.status ?? "unpaid").toLowerCase();
3598
+ const orderStatus = String(order.status ?? "").toLowerCase();
3599
+ let paymentStatus2 = rawPayStatus;
3600
+ if (orderStatus === "cancelled" && rawPayStatus !== "paid" && rawPayStatus !== "captured" && rawPayStatus !== "refunded") {
3601
+ paymentStatus2 = "unpaid";
3602
+ }
3567
3603
  return {
3568
3604
  ...orderWithoutPayments,
3569
3605
  contact: contact ? {
@@ -3573,7 +3609,7 @@ function createCrudHandler(dataSource, entityMap, options) {
3573
3609
  phone: contact.phone
3574
3610
  } : null,
3575
3611
  itemsSummary,
3576
- paymentStatus: orderPayments[0]?.status ?? "unpaid"
3612
+ paymentStatus: paymentStatus2
3577
3613
  };
3578
3614
  }));
3579
3615
  return json({
@@ -5458,6 +5494,9 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
5458
5494
  "payments"
5459
5495
  ]
5460
5496
  });
5497
+ if (order) {
5498
+ await autoExpireOrderIfPaymentTimeExceeded(dataSource, entityMap, order);
5499
+ }
5461
5500
  const orderDenied = await vendorScopeAccessJson(order, scope2, resource);
5462
5501
  if (orderDenied) return orderDenied;
5463
5502
  const relatedOrders = await repo.find({
@@ -10798,7 +10837,7 @@ function createChatHandlers(config) {
10798
10837
  const notifyEmailAgent = await findLlmAgentByScope(dataSource, entityMap, LLM_AGENT_SCOPE_EMAIL_INTENT_CHATBOT, {
10799
10838
  enabledOnly: false
10800
10839
  });
10801
- const emailTool = chunkJN4AFHZ4_cjs.resolveChatEmailToolSettings(llmSettings, {
10840
+ const emailTool = chunkHXLC56ZK_cjs.resolveChatEmailToolSettings(llmSettings, {
10802
10841
  chatbotValidationRules: agentRow?.validationRules ?? null,
10803
10842
  notifyAgent: notifyEmailAgent ? {
10804
10843
  systemInstruction: notifyEmailAgent.systemInstruction,
@@ -10808,7 +10847,7 @@ function createChatHandlers(config) {
10808
10847
  const emailPlugin2 = cms.getPlugin("email");
10809
10848
  const convLeadSent = conv.leadEmailSentAt;
10810
10849
  const chatAgentFn = llm.chatAgent?.bind(llm);
10811
- console.info(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "pipeline check", {
10850
+ console.info(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "pipeline check", {
10812
10851
  conversationId,
10813
10852
  enabled: emailTool.enabled,
10814
10853
  intentCount: emailTool.intents.length,
@@ -10822,27 +10861,27 @@ function createChatHandlers(config) {
10822
10861
  mergedPromptIncludesNotify: Boolean(notifyEmailAgent?.systemInstruction?.trim())
10823
10862
  });
10824
10863
  if (!emailTool.enabled) {
10825
- console.info(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10864
+ console.info(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10826
10865
  conversationId,
10827
10866
  reason: "email_tool_disabled"
10828
10867
  });
10829
10868
  } else if (emailTool.intents.length === 0) {
10830
- console.info(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10869
+ console.info(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10831
10870
  conversationId,
10832
10871
  reason: "no_intents_configured"
10833
10872
  });
10834
10873
  } else if (!emailPlugin2) {
10835
- console.info(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10874
+ console.info(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10836
10875
  conversationId,
10837
10876
  reason: "email_plugin_missing"
10838
10877
  });
10839
10878
  } else if (!chatAgentFn) {
10840
- console.info(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10879
+ console.info(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10841
10880
  conversationId,
10842
10881
  reason: "llm_chat_agent_unavailable"
10843
10882
  });
10844
10883
  } else if (convLeadSent) {
10845
- console.info(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10884
+ console.info(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10846
10885
  conversationId,
10847
10886
  reason: "lead_email_already_sent",
10848
10887
  leadEmailSentAt: convLeadSent
@@ -10855,7 +10894,7 @@ function createChatHandlers(config) {
10855
10894
  }
10856
10895
  });
10857
10896
  if (!contactRow) {
10858
- console.warn(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10897
+ console.warn(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
10859
10898
  conversationId,
10860
10899
  reason: "contact_not_found",
10861
10900
  contactId
@@ -10863,7 +10902,7 @@ function createChatHandlers(config) {
10863
10902
  } else {
10864
10903
  const c = contactRow;
10865
10904
  try {
10866
- const intent = await chunkJN4AFHZ4_cjs.detectChatLeadIntent({
10905
+ const intent = await chunkHXLC56ZK_cjs.detectChatLeadIntent({
10867
10906
  chatAgent: chatAgentFn
10868
10907
  }, {
10869
10908
  settings: emailTool,
@@ -10877,15 +10916,15 @@ function createChatHandlers(config) {
10877
10916
  model: agentRow?.model?.trim() || notifyEmailAgent?.model?.trim() || void 0
10878
10917
  });
10879
10918
  if (!intent.intent || !intent.emailTo) {
10880
- console.info(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "no email sent", {
10919
+ console.info(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "no email sent", {
10881
10920
  conversationId,
10882
10921
  reason: intent.intent ? "missing_email_to" : "no_intent_match",
10883
10922
  intentLabel: intent.intentLabel,
10884
10923
  classifierReason: intent.reason
10885
10924
  });
10886
10925
  } else {
10887
- const intentRecipients = chunkJN4AFHZ4_cjs.parseIntentRecipientEmails(intent.emailTo);
10888
- console.info(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "intent matched \u2014 sending", {
10926
+ const intentRecipients = chunkHXLC56ZK_cjs.parseIntentRecipientEmails(intent.emailTo);
10927
+ console.info(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "intent matched \u2014 sending", {
10889
10928
  conversationId,
10890
10929
  intent: intent.intent,
10891
10930
  emailTo: intent.emailTo,
@@ -10895,7 +10934,7 @@ function createChatHandlers(config) {
10895
10934
  const emailSettings = await loadSettingsGroupMap(dataSource, entityMap, "email");
10896
10935
  const brandingSettings = await loadSettingsGroupMap(dataSource, entityMap, "branding");
10897
10936
  const companyDetails = chunkBXYZDMTZ_cjs.mergeEmailLayoutCompanyDetails(brandingSettings, emailSettings);
10898
- const leadResult = await chunkJN4AFHZ4_cjs.sendChatLeadEmail(cms, emailSettings, brandingSettings, {
10937
+ const leadResult = await chunkHXLC56ZK_cjs.sendChatLeadEmail(cms, emailSettings, brandingSettings, {
10899
10938
  contactName: String(c.name ?? "").trim() || "Visitor",
10900
10939
  contactEmail: String(c.email ?? "").trim(),
10901
10940
  contactPhone: c.phone ?? null,
@@ -10903,7 +10942,7 @@ function createChatHandlers(config) {
10903
10942
  latestMessage: message,
10904
10943
  intentCode: intent.intent,
10905
10944
  intentReason: intent.intentLabel || intent.reason,
10906
- transcript: chunkJN4AFHZ4_cjs.buildTranscriptForLeadEmail(history, message),
10945
+ transcript: chunkHXLC56ZK_cjs.buildTranscriptForLeadEmail(history, message),
10907
10946
  companyDetails,
10908
10947
  recipients: intentRecipients.length > 0 ? intentRecipients : void 0
10909
10948
  });
@@ -10911,13 +10950,13 @@ function createChatHandlers(config) {
10911
10950
  await convRepo().update(conversationId, {
10912
10951
  leadEmailSentAt: /* @__PURE__ */ new Date()
10913
10952
  });
10914
- console.info(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "lead email recorded", {
10953
+ console.info(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "lead email recorded", {
10915
10954
  conversationId,
10916
10955
  sent: true,
10917
10956
  recipients: leadResult.recipients
10918
10957
  });
10919
10958
  } else {
10920
- console.warn(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "lead email not sent", {
10959
+ console.warn(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "lead email not sent", {
10921
10960
  conversationId,
10922
10961
  sent: false,
10923
10962
  error: leadResult.error ?? "unknown",
@@ -10926,7 +10965,7 @@ function createChatHandlers(config) {
10926
10965
  }
10927
10966
  }
10928
10967
  } catch (intentErr) {
10929
- console.warn(chunkJN4AFHZ4_cjs.CHAT_EMAIL_LOG, "pipeline error", {
10968
+ console.warn(chunkHXLC56ZK_cjs.CHAT_EMAIL_LOG, "pipeline error", {
10930
10969
  conversationId,
10931
10970
  error: intentErr instanceof Error ? intentErr.message : String(intentErr)
10932
10971
  });
@@ -10943,7 +10982,7 @@ function createChatHandlers(config) {
10943
10982
  });
10944
10983
  if (agentRow && llm.chatAgent) {
10945
10984
  const fromAgent = llmAgentToChatAgentOptions(agentRow);
10946
- const systemPrompt = chunkJN4AFHZ4_cjs.buildChatbotSystemPromptWithEmailTool(fromAgent.systemPrompt, parsedValidation.guardrailsForPrompt, emailTool);
10985
+ const systemPrompt = chunkHXLC56ZK_cjs.buildChatbotSystemPromptWithEmailTool(fromAgent.systemPrompt, parsedValidation.guardrailsForPrompt, emailTool);
10947
10986
  const res = await llm.chatAgent({
10948
10987
  ...fromAgent,
10949
10988
  systemPrompt: systemPrompt || void 0,
@@ -10964,7 +11003,7 @@ ${contextParts.join("\n\n")}` : "";
10964
11003
  agentRow.systemInstruction?.trim(),
10965
11004
  ragSystem
10966
11005
  ].filter(Boolean).join("\n\n");
10967
- systemContent = chunkJN4AFHZ4_cjs.buildChatbotSystemPromptWithEmailTool(mergedBase || defaultSystem, parsedValidation.guardrailsForPrompt, emailTool) || defaultSystem;
11006
+ systemContent = chunkHXLC56ZK_cjs.buildChatbotSystemPromptWithEmailTool(mergedBase || defaultSystem, parsedValidation.guardrailsForPrompt, emailTool) || defaultSystem;
10968
11007
  } else {
10969
11008
  systemContent = ragSystem || defaultSystem;
10970
11009
  }
@@ -12066,6 +12105,7 @@ exports.UserDeviceToken = class UserDeviceToken {
12066
12105
  chunkUSNT2KNT_cjs.__name(this, "UserDeviceToken");
12067
12106
  }
12068
12107
  id;
12108
+ /** Staff/vendor app store. Null for customer/marketplace tokens (membership is `vendor_customers`). */
12069
12109
  vendorId;
12070
12110
  vendor;
12071
12111
  userId;
@@ -12086,13 +12126,15 @@ _ts_decorate2([
12086
12126
  _ts_decorate2([
12087
12127
  typeorm.Column({
12088
12128
  type: "integer",
12089
- name: "vendor_id"
12129
+ name: "vendor_id",
12130
+ nullable: true
12090
12131
  }),
12091
- _ts_metadata2("design:type", Number)
12132
+ _ts_metadata2("design:type", Object)
12092
12133
  ], exports.UserDeviceToken.prototype, "vendorId", void 0);
12093
12134
  _ts_decorate2([
12094
12135
  typeorm.ManyToOne("Vendor", {
12095
- onDelete: "CASCADE"
12136
+ onDelete: "CASCADE",
12137
+ nullable: true
12096
12138
  }),
12097
12139
  typeorm.JoinColumn({
12098
12140
  name: "vendor_id"
@@ -12189,6 +12231,22 @@ exports.UserDeviceToken = _ts_decorate2([
12189
12231
  ], exports.UserDeviceToken);
12190
12232
 
12191
12233
  // src/api/device-tokens-handlers.ts
12234
+ function parseRequiredPositiveInt(value, field) {
12235
+ const n = parseInt(String(value ?? "").trim(), 10);
12236
+ if (!Number.isFinite(n) || n <= 0) {
12237
+ return {
12238
+ error: `${field} must be a positive integer`
12239
+ };
12240
+ }
12241
+ return n;
12242
+ }
12243
+ chunkUSNT2KNT_cjs.__name(parseRequiredPositiveInt, "parseRequiredPositiveInt");
12244
+ function parseOptionalVendorId(value) {
12245
+ if (value == null) return null;
12246
+ if (typeof value === "string" && value.trim() === "") return null;
12247
+ return parseRequiredPositiveInt(value, "vendor_id");
12248
+ }
12249
+ chunkUSNT2KNT_cjs.__name(parseOptionalVendorId, "parseOptionalVendorId");
12192
12250
  function createDeviceTokensHandlers(config) {
12193
12251
  const { dataSource, entityMap, json } = config;
12194
12252
  return /* @__PURE__ */ chunkUSNT2KNT_cjs.__name(async function handleDeviceTokensApi(req, pathSegments) {
@@ -12200,7 +12258,7 @@ function createDeviceTokensHandlers(config) {
12200
12258
  const title = body.title?.trim() || "Test Push Notification";
12201
12259
  const msgBody = body.body?.trim() || "Firebase Push Notification setup is working!";
12202
12260
  if (!token || token === "validate" || token === "validate_only") {
12203
- const valRes = await validateFcmCredentials(dataSource, entityMap);
12261
+ const valRes = await chunkHXLC56ZK_cjs.validateFcmCredentials(dataSource, entityMap);
12204
12262
  if (!valRes.success) {
12205
12263
  return json({
12206
12264
  success: false,
@@ -12217,7 +12275,7 @@ function createDeviceTokensHandlers(config) {
12217
12275
  clientEmail: valRes.clientEmail
12218
12276
  });
12219
12277
  }
12220
- const res = await chunkJN4AFHZ4_cjs.sendFcmPushNotification(dataSource, entityMap, {
12278
+ const res = await chunkHXLC56ZK_cjs.sendFcmPushNotification(dataSource, entityMap, {
12221
12279
  token,
12222
12280
  title,
12223
12281
  body: msgBody,
@@ -12260,18 +12318,28 @@ function createDeviceTokensHandlers(config) {
12260
12318
  if (method === "POST") {
12261
12319
  try {
12262
12320
  const body = await req.json().catch(() => ({}));
12263
- const vendorId = body.vendor_id?.trim();
12264
- const userId = body.user_id?.trim();
12321
+ const vendorParsed = parseOptionalVendorId(body.vendor_id);
12322
+ const userParsed = parseRequiredPositiveInt(body.user_id, "user_id");
12265
12323
  const token = body.token?.trim();
12266
12324
  const platformRaw = body.platform?.trim().toLowerCase();
12267
- if (!vendorId || !userId || !token || !platformRaw) {
12325
+ if (vendorParsed !== null && typeof vendorParsed === "object") {
12326
+ return json({
12327
+ success: false,
12328
+ error: vendorParsed.error
12329
+ }, {
12330
+ status: 400
12331
+ });
12332
+ }
12333
+ if (typeof userParsed === "object" || !token || !platformRaw) {
12268
12334
  return json({
12269
12335
  success: false,
12270
- error: "vendor_id, user_id, token, and platform (android|ios) are required"
12336
+ error: (typeof userParsed === "object" ? userParsed.error : null) || "user_id, token, and platform (android|ios) are required"
12271
12337
  }, {
12272
12338
  status: 400
12273
12339
  });
12274
12340
  }
12341
+ const vendorId = vendorParsed;
12342
+ const userId = userParsed;
12275
12343
  if (platformRaw !== "android" && platformRaw !== "ios") {
12276
12344
  return json({
12277
12345
  success: false,
@@ -12337,13 +12405,35 @@ function createDeviceTokensHandlers(config) {
12337
12405
  if (method === "GET") {
12338
12406
  try {
12339
12407
  const url = new URL(req.url);
12340
- const userId = url.searchParams.get("userId")?.trim();
12341
- const vendorId = url.searchParams.get("vendorId")?.trim();
12408
+ const userIdRaw = url.searchParams.get("userId")?.trim();
12409
+ const vendorIdRaw = url.searchParams.get("vendorId")?.trim();
12342
12410
  const whereCondition = {
12343
12411
  isActive: true
12344
12412
  };
12345
- if (userId) whereCondition.userId = userId;
12346
- if (vendorId) whereCondition.vendorId = vendorId;
12413
+ if (userIdRaw) {
12414
+ const userId = parseRequiredPositiveInt(userIdRaw, "userId");
12415
+ if (typeof userId === "object") {
12416
+ return json({
12417
+ success: false,
12418
+ error: userId.error
12419
+ }, {
12420
+ status: 400
12421
+ });
12422
+ }
12423
+ whereCondition.userId = userId;
12424
+ }
12425
+ if (vendorIdRaw) {
12426
+ const vendorId = parseRequiredPositiveInt(vendorIdRaw, "vendorId");
12427
+ if (typeof vendorId === "object") {
12428
+ return json({
12429
+ success: false,
12430
+ error: vendorId.error
12431
+ }, {
12432
+ status: 400
12433
+ });
12434
+ }
12435
+ whereCondition.vendorId = vendorId;
12436
+ }
12347
12437
  const tokens = await tokenRepo.find({
12348
12438
  where: whereCondition,
12349
12439
  order: {
@@ -12370,16 +12460,17 @@ function createDeviceTokensHandlers(config) {
12370
12460
  if (method === "DELETE") {
12371
12461
  try {
12372
12462
  const body = await req.json().catch(() => ({}));
12373
- const userId = body.user_id?.trim();
12463
+ const userParsed = parseRequiredPositiveInt(body.user_id, "user_id");
12374
12464
  const token = body.token?.trim();
12375
- if (!userId || !token) {
12465
+ if (typeof userParsed === "object" || !token) {
12376
12466
  return json({
12377
12467
  success: false,
12378
- error: "user_id and token are required to deactivate"
12468
+ error: (typeof userParsed === "object" ? userParsed.error : null) || "user_id and token are required to deactivate"
12379
12469
  }, {
12380
12470
  status: 400
12381
12471
  });
12382
12472
  }
12473
+ const userId = userParsed;
12383
12474
  await tokenRepo.update({
12384
12475
  userId,
12385
12476
  token
@@ -13179,7 +13270,7 @@ async function sendVendorOnboardEmails(input, deps) {
13179
13270
  getVendorEmails(deps)
13180
13271
  ]);
13181
13272
  const companyDetails = chunkBXYZDMTZ_cjs.mergeEmailLayoutCompanyDetails(branding, emailSettings);
13182
- const configuredNotify = chunkJN4AFHZ4_cjs.parseEmailRecipientsFromConfig(emailSettings.salesTeamEmails ?? emailSettings.salesTeamEmail);
13273
+ const configuredNotify = chunkHXLC56ZK_cjs.parseEmailRecipientsFromConfig(emailSettings.salesTeamEmails ?? emailSettings.salesTeamEmail);
13183
13274
  const ownerEmail = input.ownerEmail?.trim() || "";
13184
13275
  const ownerEmailLower = ownerEmail.toLowerCase();
13185
13276
  const sendToOwner = input.sendToOwner !== false;
@@ -27748,16 +27839,16 @@ function whatsappPlugin(config = {}) {
27748
27839
  db = await getWhatsAppSettings?.() ?? {};
27749
27840
  } catch {
27750
27841
  }
27751
- if (!chunkJN4AFHZ4_cjs.isWhatsAppPluginEnabled(db)) {
27842
+ if (!chunkHXLC56ZK_cjs.isWhatsAppPluginEnabled(db)) {
27752
27843
  context.logger.warn("WhatsApp plugin skipped: disabled in Plugins \u2192 WhatsApp");
27753
27844
  return null;
27754
27845
  }
27755
- const merged = chunkJN4AFHZ4_cjs.mergeWhatsAppConfigLayers(env, db, staticRest);
27756
- if (!getWhatsAppSettings && !chunkJN4AFHZ4_cjs.whatsAppConfigured(merged)) {
27846
+ const merged = chunkHXLC56ZK_cjs.mergeWhatsAppConfigLayers(env, db, staticRest);
27847
+ if (!getWhatsAppSettings && !chunkHXLC56ZK_cjs.whatsAppConfigured(merged)) {
27757
27848
  context.logger.warn("WhatsApp plugin skipped: set WHATSAPP_ACCESS_TOKEN and WHATSAPP_PHONE_NUMBER_ID, or pass getWhatsAppSettings");
27758
27849
  return null;
27759
27850
  }
27760
- const svc = new chunkJN4AFHZ4_cjs.WhatsAppService(env, staticRest, getWhatsAppSettings, getMessageTemplateRow);
27851
+ const svc = new chunkHXLC56ZK_cjs.WhatsAppService(env, staticRest, getWhatsAppSettings, getMessageTemplateRow);
27761
27852
  return {
27762
27853
  send: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((opts) => svc.send(opts), "send")
27763
27854
  };
@@ -27834,7 +27925,7 @@ function registerMessagingQueueProcessors(cms, entityMap) {
27834
27925
  getDataSource: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name(async () => cms.dataSource, "getDataSource"),
27835
27926
  entityMap
27836
27927
  });
27837
- chunkJN4AFHZ4_cjs.registerWhatsAppQueueProcessor(cms);
27928
+ chunkHXLC56ZK_cjs.registerWhatsAppQueueProcessor(cms);
27838
27929
  }
27839
27930
  chunkUSNT2KNT_cjs.__name(registerMessagingQueueProcessors, "registerMessagingQueueProcessors");
27840
27931
  async function ensureMessagingPluginsOnCms(base, options) {
@@ -27863,7 +27954,7 @@ async function ensureMessagingPluginsOnCms(base, options) {
27863
27954
  }
27864
27955
  if (!cms.getPlugin("email")) {
27865
27956
  try {
27866
- const instance = await chunkJN4AFHZ4_cjs.emailPlugin({
27957
+ const instance = await chunkHXLC56ZK_cjs.emailPlugin({
27867
27958
  type: "SMTP",
27868
27959
  from: config.SMTP_FROM ?? "no-reply@localhost",
27869
27960
  to: config.SMTP_TO ?? ""
@@ -27904,7 +27995,7 @@ function messagingPlugins(options) {
27904
27995
  const config = options.config ?? (typeof process !== "undefined" ? process.env : {});
27905
27996
  return [
27906
27997
  queuePlugin(),
27907
- chunkJN4AFHZ4_cjs.emailPlugin({
27998
+ chunkHXLC56ZK_cjs.emailPlugin({
27908
27999
  type: "SMTP",
27909
28000
  from: config.SMTP_FROM ?? "no-reply@localhost",
27910
28001
  to: config.SMTP_TO ?? ""
@@ -28038,7 +28129,7 @@ function createCmsApiHandler(config) {
28038
28129
  } : void 0;
28039
28130
  const entityMap = withLlmKnowledgeEntityFallbacks(rawEntityMap);
28040
28131
  if (getCms) {
28041
- chunkJN4AFHZ4_cjs.initWhatsappTriggerDispatcher({
28132
+ chunkHXLC56ZK_cjs.initWhatsappTriggerDispatcher({
28042
28133
  dataSource,
28043
28134
  entityMap,
28044
28135
  getCms
@@ -29801,7 +29892,7 @@ function createCmsApiHandler(config) {
29801
29892
  status: 400
29802
29893
  });
29803
29894
  }
29804
- const { resendOrderNotification } = await import('./order-notification-dispatcher-YBAWDOIO.cjs');
29895
+ const { resendOrderNotification } = await import('./order-notification-dispatcher-2FCZFZUD.cjs');
29805
29896
  const result = await resendOrderNotification(triggerKey, orderId, {
29806
29897
  dataSource,
29807
29898
  entityMap,
@@ -32842,6 +32933,23 @@ function createStorefrontApiHandler(config) {
32842
32933
  });
32843
32934
  return json(body);
32844
32935
  }
32936
+ if (path2[0] === "cart" && path2.length === 1 && method === "DELETE") {
32937
+ const { cart, err } = await getOrCreateCart(req);
32938
+ if (err) return err;
32939
+ const cartId = cart?.id;
32940
+ if (cartId && Number.isFinite(cartId) && cartId > 0) {
32941
+ await cartItemRepo().delete({
32942
+ cartId
32943
+ });
32944
+ await cartRepo().update(cartId, {
32945
+ updatedAt: /* @__PURE__ */ new Date()
32946
+ });
32947
+ }
32948
+ return json({
32949
+ ok: true,
32950
+ message: "Cart cleared"
32951
+ });
32952
+ }
32845
32953
  if (path2[0] === "cart" && path2[1] === "items" && path2.length === 2 && method === "POST") {
32846
32954
  const body = await req.json().catch(() => ({}));
32847
32955
  const capCart = await assertCaptchaOk(getCms, body, req, json);
@@ -33361,7 +33469,8 @@ function createStorefrontApiHandler(config) {
33361
33469
  total: prepOrd.orderTotal,
33362
33470
  currency: cart.currency || "INR",
33363
33471
  metadata: {
33364
- cartId
33472
+ cartId,
33473
+ paymentExpiresAt: new Date(Date.now() + 10 * 60 * 1e3).toISOString()
33365
33474
  }
33366
33475
  }));
33367
33476
  const oid = ord.id;
@@ -33434,7 +33543,11 @@ function createStorefrontApiHandler(config) {
33434
33543
  tax: prepChk.orderTax,
33435
33544
  discount: 0,
33436
33545
  total: prepChk.orderTotal,
33437
- currency: cart.currency || "INR"
33546
+ currency: cart.currency || "INR",
33547
+ metadata: {
33548
+ cartId: cart.id,
33549
+ paymentExpiresAt: new Date(Date.now() + 10 * 60 * 1e3).toISOString()
33550
+ }
33438
33551
  }));
33439
33552
  const oid = ord.id;
33440
33553
  await orderRepo().update(oid, {
@@ -33680,6 +33793,7 @@ function createStorefrontApiHandler(config) {
33680
33793
  status: 404
33681
33794
  });
33682
33795
  const o = order;
33796
+ await autoExpireOrderIfPaymentTimeExceeded(dataSource, entityMap, o);
33683
33797
  const lines = (o.items || []).map((line) => {
33684
33798
  const p = line.product;
33685
33799
  return {
@@ -33740,6 +33854,73 @@ function createStorefrontApiHandler(config) {
33740
33854
  fulfillmentPreview: fulfillmentPreview || void 0
33741
33855
  });
33742
33856
  }
33857
+ if (path2[0] === "orders" && path2.length === 3 && path2[2] === "cancel" && method === "POST") {
33858
+ const orderId = parseInt(path2[1], 10);
33859
+ if (!Number.isFinite(orderId)) return json({
33860
+ error: "Invalid order id"
33861
+ }, {
33862
+ status: 400
33863
+ });
33864
+ const order = await orderRepo().findOne({
33865
+ where: {
33866
+ id: orderId,
33867
+ deleted: false
33868
+ }
33869
+ });
33870
+ if (!order) return json({
33871
+ error: "Not found"
33872
+ }, {
33873
+ status: 404
33874
+ });
33875
+ const o = order;
33876
+ const status = String(o.status || "").toLowerCase();
33877
+ if (status === "pending") {
33878
+ const meta = typeof o.metadata === "object" && o.metadata ? o.metadata : {};
33879
+ const updatedMeta = {
33880
+ ...meta,
33881
+ cancelReason: "Cancelled by user during payment window"
33882
+ };
33883
+ await orderRepo().update(orderId, {
33884
+ status: "cancelled",
33885
+ metadata: updatedMeta
33886
+ });
33887
+ try {
33888
+ if (entityMap.payments) {
33889
+ const payRepo = dataSource.getRepository(entityMap.payments);
33890
+ const pendingPayment = await payRepo.findOne({
33891
+ where: {
33892
+ orderId,
33893
+ status: "pending"
33894
+ }
33895
+ });
33896
+ if (pendingPayment) {
33897
+ await payRepo.update(pendingPayment.id, {
33898
+ status: "unpaid"
33899
+ });
33900
+ }
33901
+ }
33902
+ } catch {
33903
+ }
33904
+ try {
33905
+ const { cart } = await getOrCreateCart(req);
33906
+ const cartId = cart?.id;
33907
+ if (cartId && Number.isFinite(cartId) && cartId > 0) {
33908
+ await cartItemRepo().delete({
33909
+ cartId
33910
+ });
33911
+ await cartRepo().update(cartId, {
33912
+ updatedAt: /* @__PURE__ */ new Date()
33913
+ });
33914
+ }
33915
+ } catch {
33916
+ }
33917
+ }
33918
+ return json({
33919
+ ok: true,
33920
+ orderId,
33921
+ status: "cancelled"
33922
+ });
33923
+ }
33743
33924
  return json({
33744
33925
  error: "Not found"
33745
33926
  }, {
@@ -33779,6 +33960,7 @@ exports.assertCaptchaOk = assertCaptchaOk;
33779
33960
  exports.assertContactAllowedForVendorOrder = assertContactAllowedForVendorOrder;
33780
33961
  exports.assertEventApprovalUpdate = assertEventApprovalUpdate;
33781
33962
  exports.assertProductApprovalUpdate = assertProductApprovalUpdate;
33963
+ exports.autoExpireOrderIfPaymentTimeExceeded = autoExpireOrderIfPaymentTimeExceeded;
33782
33964
  exports.buildBlogMetadataUserPrompt = buildBlogMetadataUserPrompt;
33783
33965
  exports.buildCronFromSchedule = buildCronFromSchedule;
33784
33966
  exports.buildRssUserPromptFromFeeds = buildRssUserPromptFromFeeds;