@infuro/cms-core 1.0.59 → 1.0.61

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 (33) hide show
  1. package/dist/admin.cjs +1020 -83
  2. package/dist/admin.js +1021 -84
  3. package/dist/api.cjs +38 -38
  4. package/dist/api.js +5 -5
  5. package/dist/auth.cjs +51 -51
  6. package/dist/auth.js +3 -3
  7. package/dist/{chunk-3EOM4V2M.cjs → chunk-4U6DATGZ.cjs} +7 -7
  8. package/dist/{chunk-BNKZNLEX.js → chunk-6DBDJ4VD.js} +2 -2
  9. package/dist/{chunk-UQWZUZ5X.cjs → chunk-73WVHINE.cjs} +30 -6
  10. package/dist/{chunk-UCKN4BBY.cjs → chunk-77I3KS7V.cjs} +4 -1
  11. package/dist/{chunk-MCCA7WLQ.cjs → chunk-CNAHVRRU.cjs} +533 -167
  12. package/dist/{chunk-77NUXO6A.cjs → chunk-J7FMZK66.cjs} +10 -2
  13. package/dist/{chunk-BC22I7C7.cjs → chunk-KM2I6AFP.cjs} +9 -9
  14. package/dist/{chunk-JIWUVQ6B.js → chunk-MVHDC3XF.js} +10 -2
  15. package/dist/{chunk-RK5ETF2I.js → chunk-NR44CK5E.js} +1 -1
  16. package/dist/{chunk-MXIWUFBP.js → chunk-O2642WVS.js} +28 -4
  17. package/dist/{chunk-HCIRL37O.js → chunk-T3HPSF7K.js} +4 -1
  18. package/dist/{chunk-BTUEUA5H.js → chunk-UHT4INVW.js} +453 -87
  19. package/dist/{chunk-HYW3MUXT.js → chunk-URN7GS23.js} +30 -16
  20. package/dist/{chunk-HXLC56ZK.cjs → chunk-YSYX4GUD.cjs} +32 -18
  21. package/dist/{emit-order-notification-trigger-HZQPPSFB.js → emit-order-notification-trigger-CZU3V2WE.js} +2 -2
  22. package/dist/{emit-order-notification-trigger-NR3VN6C6.cjs → emit-order-notification-trigger-TNEZOYEE.cjs} +4 -4
  23. package/dist/index.cjs +614 -333
  24. package/dist/index.d.cts +31 -0
  25. package/dist/index.d.ts +31 -0
  26. package/dist/index.js +329 -48
  27. package/dist/migrations/1782800000000-AddPaymentSuccessFailedRefundTriggers.ts +32 -0
  28. package/dist/migrations/1782900000000-AddEnableTurnstileToForms.ts +29 -0
  29. package/dist/{order-notification-dispatcher-2FCZFZUD.cjs → order-notification-dispatcher-KJVGLK5E.cjs} +5 -5
  30. package/dist/{order-notification-dispatcher-64WDCHHG.js → order-notification-dispatcher-ZSFKEYMP.js} +2 -2
  31. package/dist/{rbac-debug-db-6EMIVMGF.js → rbac-debug-db-5R6XFPSV.js} +1 -1
  32. package/dist/{rbac-debug-db-6PWTLBEL.cjs → rbac-debug-db-JKK2MCWF.cjs} +2 -2
  33. package/package.json +1 -1
@@ -1,15 +1,15 @@
1
1
  import { JOB_RUNNER_QUEUE } from './chunk-GO7PPYNU.js';
2
2
  import { validateInventoryForConfirmedOrderLines, orderStatusHoldsStock, reconcileOrderInventoryBetweenSnapshots, orderInventorySnapshotFromRow, validateInventoryForOrderBecomingConfirmed } from './chunk-3K5AIEIZ.js';
3
- import { resolveChatEmailToolSettings, CHAT_EMAIL_LOG, detectChatLeadIntent, parseIntentRecipientEmails, sendChatLeadEmail, buildTranscriptForLeadEmail, buildChatbotSystemPromptWithEmailTool, validateFcmCredentials, sendFcmPushNotification, parseEmailRecipientsFromConfig, isWhatsAppPluginEnabled, mergeWhatsAppConfigLayers, whatsAppConfigured, WhatsAppService, registerWhatsAppQueueProcessor, emailPlugin, initWhatsappTriggerDispatcher } from './chunk-HYW3MUXT.js';
3
+ import { resolveChatEmailToolSettings, CHAT_EMAIL_LOG, detectChatLeadIntent, parseIntentRecipientEmails, sendChatLeadEmail, buildTranscriptForLeadEmail, buildChatbotSystemPromptWithEmailTool, validateFcmCredentials, sendFcmPushNotification, parseEmailRecipientsFromConfig, isWhatsAppPluginEnabled, mergeWhatsAppConfigLayers, whatsAppConfigured, WhatsAppService, registerWhatsAppQueueProcessor, emailPlugin, initWhatsappTriggerDispatcher } from './chunk-URN7GS23.js';
4
4
  import { inviteStatusForActivation } from './chunk-JXF23MPG.js';
5
5
  import { queueEmail, queueVendorOnboardEmails, registerEmailQueueProcessor } from './chunk-L3525VXI.js';
6
6
  import { mergeEmailLayoutCompanyDetails, unwrapErpReadData, mapErpPayloadToFulfillment, extractChildOrderRefsFromSalePayload, mapErpPayloadToInvoiceNumber, streamOrderInvoicePdf } from './chunk-2KUCQVAQ.js';
7
7
  import { isErpIntegrationEnabled } from './chunk-JC6DLWTE.js';
8
8
  import { getSmsTemplateDefault, SMS_MESSAGE_TEMPLATE_DEFAULTS } from './chunk-MQBT33IV.js';
9
9
  import { EVENT_ORDER_MESSAGE_TEMPLATE_DEFAULTS, EVENT_ORDER_TEMPLATE_KEY, EVENT_ORDER_TEMPLATE_VARIABLES } from './chunk-AYERBA7I.js';
10
- import { ensureCustomerRecord, linkUnclaimedContactToUser, ensureCustomerForUser, canManageRoles, sessionHasEntityAccess } from './chunk-RK5ETF2I.js';
10
+ import { ensureCustomerRecord, linkUnclaimedContactToUser, ensureCustomerForUser, canManageRoles, sessionHasEntityAccess } from './chunk-NR44CK5E.js';
11
11
  import { retireSoftDeletedUniqueValue, activeUniqueValueExists } from './chunk-DBPSJYLZ.js';
12
- import { permissionRowsToRecord, logRbac, isSuperAdmin, vendorPortalFlagsFromUser, VENDOR_SCOPED_STORE_ENTITIES, isVendorPortalUser, getPermissionableEntityKeys, VENDOR_STORE_RBAC_ENTITIES, isSuperAdminGroupName, VENDOR_RBAC_ENTITIES, VENDOR_VIEWER_ROLE_NAME, DEFAULT_VENDOR_ROLE_DEFS, VENDOR_GROUP_NAME, resolveVendorScopeFromSessionUser, canManageVendorRoles, isPlatformAdministrator, canManageVendorTeam, resolveDisabledMultiVendorScope, logEntityAccessDecision, explainSessionEntityAccess } from './chunk-JIWUVQ6B.js';
12
+ import { permissionRowsToRecord, logRbac, isSuperAdmin, vendorPortalFlagsFromUser, VENDOR_SCOPED_STORE_ENTITIES, isVendorPortalUser, getPermissionableEntityKeys, VENDOR_STORE_RBAC_ENTITIES, isSuperAdminGroupName, VENDOR_RBAC_ENTITIES, VENDOR_VIEWER_ROLE_NAME, DEFAULT_VENDOR_ROLE_DEFS, VENDOR_GROUP_NAME, resolveVendorScopeFromSessionUser, canManageVendorRoles, isPlatformAdministrator, canManageVendorTeam, resolveDisabledMultiVendorScope, logEntityAccessDecision, explainSessionEntityAccess } from './chunk-MVHDC3XF.js';
13
13
  import { queueErp } from './chunk-SYBOCAWB.js';
14
14
  import { __name } from './chunk-SHUYVCID.js';
15
15
  import { PrimaryGeneratedColumn, Column, Entity, ManyToOne, JoinColumn, CreateDateColumn, UpdateDateColumn, Unique, OneToMany, Index, ManyToMany, JoinTable, In, ILike, Between, MoreThanOrEqual, LessThanOrEqual, Not, MoreThan, IsNull } from 'typeorm';
@@ -2444,13 +2444,46 @@ function discountCompare(cartValue, op, ruleValue) {
2444
2444
  }
2445
2445
  }
2446
2446
  __name(discountCompare, "discountCompare");
2447
- function discountEvaluateRule(rule, cartLines, cartTotal) {
2448
- if (rule.conditionType === "group") return discountEvaluateGroup(rule, cartLines, cartTotal);
2447
+ async function getExchangeRate(dataSource, entityMap, fromCurrency, toCurrency) {
2448
+ const from = (fromCurrency || "INR").trim().toUpperCase();
2449
+ const to = (toCurrency || "INR").trim().toUpperCase();
2450
+ if (from === to) return 1;
2451
+ if (entityMap["currency_exchange"]) {
2452
+ try {
2453
+ const exchangeRepo = dataSource.getRepository(entityMap["currency_exchange"]);
2454
+ const direct = await exchangeRepo.findOne({
2455
+ where: {
2456
+ fromCurrency: from,
2457
+ toCurrency: to
2458
+ }
2459
+ });
2460
+ if (direct && Number(direct.rate) > 0) {
2461
+ return Number(direct.rate);
2462
+ }
2463
+ const inverse = await exchangeRepo.findOne({
2464
+ where: {
2465
+ fromCurrency: to,
2466
+ toCurrency: from
2467
+ }
2468
+ });
2469
+ if (inverse && Number(inverse.rate) > 0) {
2470
+ return 1 / Number(inverse.rate);
2471
+ }
2472
+ } catch {
2473
+ }
2474
+ }
2475
+ return 1;
2476
+ }
2477
+ __name(getExchangeRate, "getExchangeRate");
2478
+ function discountEvaluateRule(rule, cartLines, cartTotal, exchangeRate = 1) {
2479
+ if (rule.conditionType === "group") return discountEvaluateGroup(rule, cartLines, cartTotal, exchangeRate);
2449
2480
  if (rule.type === "reward") return true;
2450
- const ruleValue = discountExtractValue(rule.value);
2481
+ const rawRuleValue = discountExtractValue(rule.value);
2451
2482
  switch (rule.type) {
2452
- case "minAmount":
2453
- return discountCompare(cartTotal, rule.comparisonOperator, ruleValue);
2483
+ case "minAmount": {
2484
+ const convertedValue = typeof rawRuleValue === "number" ? rawRuleValue * exchangeRate : !isNaN(Number(rawRuleValue)) ? Number(rawRuleValue) * exchangeRate : rawRuleValue;
2485
+ return discountCompare(cartTotal, rule.comparisonOperator, convertedValue);
2486
+ }
2454
2487
  case "quantity": {
2455
2488
  if (rule.subType === "productId" && rule.value?.productId) {
2456
2489
  const targetProductId = Number(rule.value.productId);
@@ -2459,11 +2492,11 @@ function discountEvaluateRule(rule, cartLines, cartTotal) {
2459
2492
  return discountCompare(productQty, rule.comparisonOperator, requiredQty);
2460
2493
  }
2461
2494
  const totalQty = cartLines.reduce((s, l) => s + l.quantity, 0);
2462
- return discountCompare(totalQty, rule.comparisonOperator, ruleValue);
2495
+ return discountCompare(totalQty, rule.comparisonOperator, rawRuleValue);
2463
2496
  }
2464
2497
  case "product":
2465
2498
  if (rule.subType === "productId") {
2466
- return cartLines.some((l) => discountCompare(l.productId, rule.comparisonOperator, ruleValue));
2499
+ return cartLines.some((l) => discountCompare(l.productId, rule.comparisonOperator, rawRuleValue));
2467
2500
  }
2468
2501
  return false;
2469
2502
  // These require external context (user session, payment method, time) —
@@ -2487,11 +2520,11 @@ function discountEvaluateRule(rule, cartLines, cartTotal) {
2487
2520
  }
2488
2521
  }
2489
2522
  __name(discountEvaluateRule, "discountEvaluateRule");
2490
- function discountEvaluateGroup(group, cartLines, cartTotal) {
2523
+ function discountEvaluateGroup(group, cartLines, cartTotal, exchangeRate = 1) {
2491
2524
  if (!group.children?.length) return true;
2492
2525
  const op = (group.conditionOperator ?? "and").toLowerCase();
2493
- if (op === "and") return group.children.every((child) => discountEvaluateRule(child, cartLines, cartTotal));
2494
- if (op === "or") return group.children.some((child) => discountEvaluateRule(child, cartLines, cartTotal));
2526
+ if (op === "and") return group.children.every((child) => discountEvaluateRule(child, cartLines, cartTotal, exchangeRate));
2527
+ if (op === "or") return group.children.some((child) => discountEvaluateRule(child, cartLines, cartTotal, exchangeRate));
2495
2528
  return true;
2496
2529
  }
2497
2530
  __name(discountEvaluateGroup, "discountEvaluateGroup");
@@ -2538,19 +2571,19 @@ function discountExtractBuyProductId(nodes) {
2538
2571
  return null;
2539
2572
  }
2540
2573
  __name(discountExtractBuyProductId, "discountExtractBuyProductId");
2541
- function discountBuildUniversalResult(discount, cartLines) {
2574
+ function discountBuildUniversalResult(discount, cartLines, effectiveValue) {
2542
2575
  return {
2543
2576
  rewardLines: cartLines.map((l) => ({
2544
2577
  productId: l.productId,
2545
2578
  quantity: l.quantity,
2546
- discountRate: Number(discount.value),
2579
+ discountRate: effectiveValue,
2547
2580
  discountType: discount.discountType
2548
2581
  })),
2549
2582
  conditionsMet: true
2550
2583
  };
2551
2584
  }
2552
2585
  __name(discountBuildUniversalResult, "discountBuildUniversalResult");
2553
- function evaluateDiscount(discount, cartLines) {
2586
+ function evaluateDiscount(discount, cartLines, exchangeRate = 1) {
2554
2587
  const empty = {
2555
2588
  rewardLines: [],
2556
2589
  conditionsMet: false
@@ -2574,16 +2607,17 @@ function evaluateDiscount(discount, cartLines) {
2574
2607
  reason: "discount usage limit reached"
2575
2608
  };
2576
2609
  }
2610
+ const effectiveValue = discount.discountType === "FLAT" ? Number(discount.value) * exchangeRate : Number(discount.value);
2577
2611
  const cartTotal = cartLines.reduce((s, l) => s + l.subtotal, 0);
2578
2612
  const tree = discountBuildTree(discount.rules ?? []);
2579
- if (tree.length === 0) return discountBuildUniversalResult(discount, cartLines);
2580
- const conditionsMet = tree.every((node) => discountEvaluateRule(node, cartLines, cartTotal));
2613
+ if (tree.length === 0) return discountBuildUniversalResult(discount, cartLines, effectiveValue);
2614
+ const conditionsMet = tree.every((node) => discountEvaluateRule(node, cartLines, cartTotal, exchangeRate));
2581
2615
  if (!conditionsMet) return {
2582
2616
  ...empty,
2583
2617
  reason: "conditions not met"
2584
2618
  };
2585
2619
  const rewardRules = discountCollectRewardRules(tree);
2586
- if (rewardRules.length === 0) return discountBuildUniversalResult(discount, cartLines);
2620
+ if (rewardRules.length === 0) return discountBuildUniversalResult(discount, cartLines, effectiveValue);
2587
2621
  const requiredBuyQty = discountExtractRequiredBuyQty(tree);
2588
2622
  const buyProductId = discountExtractBuyProductId(tree);
2589
2623
  let dealMultiplier = 1;
@@ -2601,7 +2635,7 @@ function evaluateDiscount(discount, cartLines) {
2601
2635
  rewardLines.push({
2602
2636
  productId: rewardProductId,
2603
2637
  quantity: dealMultiplier,
2604
- discountRate: Number(discount.value),
2638
+ discountRate: effectiveValue,
2605
2639
  discountType: discount.discountType
2606
2640
  });
2607
2641
  } else {
@@ -2610,7 +2644,7 @@ function evaluateDiscount(discount, cartLines) {
2610
2644
  rewardLines.push({
2611
2645
  productId: rewardProductId,
2612
2646
  quantity: rewardQty,
2613
- discountRate: Number(discount.value),
2647
+ discountRate: effectiveValue,
2614
2648
  discountType: discount.discountType
2615
2649
  });
2616
2650
  }
@@ -2621,8 +2655,9 @@ function evaluateDiscount(discount, cartLines) {
2621
2655
  };
2622
2656
  }
2623
2657
  __name(evaluateDiscount, "evaluateDiscount");
2624
- function applyDiscountToOrderLines(lines, evalResult, maxDiscountAmount) {
2658
+ function applyDiscountToOrderLines(lines, evalResult, maxDiscountAmount, exchangeRate = 1) {
2625
2659
  if (!evalResult.conditionsMet || evalResult.rewardLines.length === 0) return 0;
2660
+ const effectiveMaxDiscountAmount = maxDiscountAmount != null ? Number(maxDiscountAmount) * exchangeRate : null;
2626
2661
  let totalDiscountApplied = 0;
2627
2662
  for (const reward of evalResult.rewardLines) {
2628
2663
  const line = lines.find((l) => l.productId === reward.productId);
@@ -2639,8 +2674,8 @@ function applyDiscountToOrderLines(lines, evalResult, maxDiscountAmount) {
2639
2674
  line.subtotal = line.unitPrice * line.quantity;
2640
2675
  line.total = Math.max(0, line.subtotal - (line.discount ?? 0));
2641
2676
  }
2642
- if (maxDiscountAmount != null && totalDiscountApplied > maxDiscountAmount) {
2643
- const excess = totalDiscountApplied - maxDiscountAmount;
2677
+ if (effectiveMaxDiscountAmount != null && totalDiscountApplied > effectiveMaxDiscountAmount) {
2678
+ const excess = totalDiscountApplied - effectiveMaxDiscountAmount;
2644
2679
  for (let i = evalResult.rewardLines.length - 1; i >= 0; i--) {
2645
2680
  const reward = evalResult.rewardLines[i];
2646
2681
  const line = lines.find((l) => l.productId === reward.productId);
@@ -2650,7 +2685,7 @@ function applyDiscountToOrderLines(lines, evalResult, maxDiscountAmount) {
2650
2685
  line.total = Math.max(0, line.total + rollback);
2651
2686
  if (rollback > 0) break;
2652
2687
  }
2653
- totalDiscountApplied = maxDiscountAmount;
2688
+ totalDiscountApplied = effectiveMaxDiscountAmount;
2654
2689
  }
2655
2690
  return totalDiscountApplied;
2656
2691
  }
@@ -2756,7 +2791,9 @@ async function validateCoupon(dataSource, entityMap, couponCode, orderLines, cur
2756
2791
  unitPrice: l.unitPrice,
2757
2792
  subtotal: l.subtotal
2758
2793
  }));
2759
- const evalResult = evaluateDiscount(discountForEval, cartLines);
2794
+ const dCurrency = d.currency || "INR";
2795
+ const exchangeRate = await getExchangeRate(dataSource, entityMap, dCurrency, currency);
2796
+ const evalResult = evaluateDiscount(discountForEval, cartLines, exchangeRate);
2760
2797
  if (!evalResult.conditionsMet) {
2761
2798
  return {
2762
2799
  valid: false,
@@ -2766,7 +2803,7 @@ async function validateCoupon(dataSource, entityMap, couponCode, orderLines, cur
2766
2803
  const clonedLines = lines.map((l) => ({
2767
2804
  ...l
2768
2805
  }));
2769
- const calculatedDiscount = applyDiscountToOrderLines(clonedLines, evalResult, d.maxDiscountAmount);
2806
+ const calculatedDiscount = applyDiscountToOrderLines(clonedLines, evalResult, d.maxDiscountAmount, exchangeRate);
2770
2807
  const rewardProductIds = evalResult.rewardLines.map((r) => r.productId);
2771
2808
  return {
2772
2809
  valid: true,
@@ -3051,9 +3088,11 @@ async function calculateOrderTotalsFromLines(dataSource, entityMap, lineInputs,
3051
3088
  unitPrice: l.unitPrice,
3052
3089
  subtotal: l.subtotal
3053
3090
  }));
3054
- const evalResult = evaluateDiscount(discountForEval, cartLines);
3091
+ const dCurrency = discountRow.currency || "INR";
3092
+ const exchangeRate2 = await getExchangeRate(dataSource, entityMap, dCurrency, currency);
3093
+ const evalResult = evaluateDiscount(discountForEval, cartLines, exchangeRate2);
3055
3094
  if (evalResult.conditionsMet) {
3056
- const totalDiscountApplied = applyDiscountToOrderLines(lines, evalResult, discountRow.maxDiscountAmount);
3095
+ const totalDiscountApplied = applyDiscountToOrderLines(lines, evalResult, discountRow.maxDiscountAmount, exchangeRate2);
3057
3096
  orderDiscount += totalDiscountApplied;
3058
3097
  }
3059
3098
  }
@@ -3166,9 +3205,25 @@ async function calculateOrderTotals(dataSource, entityMap, itemsSummary, discoun
3166
3205
  unitPrice: l.unitPrice,
3167
3206
  subtotal: l.subtotal
3168
3207
  }));
3169
- const evalResult = evaluateDiscount(discountForEval, cartLines);
3208
+ const dCurrency = discountRow.currency || "INR";
3209
+ let storeCurrency = "INR";
3210
+ if (entityMap["configs"]) {
3211
+ try {
3212
+ const configRepo = dataSource.getRepository(entityMap["configs"]);
3213
+ const curr = await configRepo.findOne({
3214
+ where: {
3215
+ settings: "store",
3216
+ key: "currency"
3217
+ }
3218
+ });
3219
+ storeCurrency = curr?.value?.toUpperCase() ?? "INR";
3220
+ } catch {
3221
+ }
3222
+ }
3223
+ const exchangeRate = await getExchangeRate(dataSource, entityMap, dCurrency, storeCurrency);
3224
+ const evalResult = evaluateDiscount(discountForEval, cartLines, exchangeRate);
3170
3225
  if (evalResult.conditionsMet) {
3171
- const totalDiscountApplied = applyDiscountToOrderLines(lines, evalResult, discountRow.maxDiscountAmount);
3226
+ const totalDiscountApplied = applyDiscountToOrderLines(lines, evalResult, discountRow.maxDiscountAmount, exchangeRate);
3172
3227
  for (const line of lines) {
3173
3228
  if (!line.found || line.taxRate === 0) continue;
3174
3229
  const discountedAmount = line.subtotal - (line.discount ?? 0);
@@ -3791,14 +3846,14 @@ function createCrudHandler(dataSource, entityMap, options) {
3791
3846
  if (Number.isFinite(n)) productWhere[key] = n;
3792
3847
  }
3793
3848
  }
3794
- const idsParam = searchParams.get("ids")?.trim();
3795
- if (idsParam) {
3796
- const ids = idsParam.split(",").map((s) => Number(s.trim())).filter((n) => Number.isFinite(n) && n > 0);
3849
+ const idsParam2 = searchParams.get("ids")?.trim();
3850
+ if (idsParam2) {
3851
+ const ids = idsParam2.split(",").map((s) => Number(s.trim())).filter((n) => Number.isFinite(n) && n > 0);
3797
3852
  productWhere.id = ids.length > 0 ? In(ids) : -1;
3798
3853
  } else {
3799
- const excludeIdsParam = searchParams.get("excludeIds")?.trim();
3800
- if (excludeIdsParam) {
3801
- const excludeIds = excludeIdsParam.split(",").map((s) => Number(s.trim())).filter((n) => Number.isFinite(n) && n > 0);
3854
+ const excludeIdsParam2 = searchParams.get("excludeIds")?.trim();
3855
+ if (excludeIdsParam2) {
3856
+ const excludeIds = excludeIdsParam2.split(",").map((s) => Number(s.trim())).filter((n) => Number.isFinite(n) && n > 0);
3802
3857
  if (excludeIds.length > 0) productWhere.id = Not(In(excludeIds));
3803
3858
  }
3804
3859
  }
@@ -4075,6 +4130,24 @@ function createCrudHandler(dataSource, entityMap, options) {
4075
4130
  }
4076
4131
  }
4077
4132
  where = mergeDeletedFalseWhere(repo, where);
4133
+ const idsParam = searchParams.get("ids")?.trim();
4134
+ if (idsParam && columnNames.has("id")) {
4135
+ const idList = idsParam.split(",").map((s) => Number(s.trim())).filter((n) => Number.isFinite(n) && n > 0);
4136
+ if (idList.length > 0) {
4137
+ where = mergeListWhereAnd(where, {
4138
+ id: In(idList)
4139
+ });
4140
+ }
4141
+ }
4142
+ const excludeIdsParam = searchParams.get("excludeIds")?.trim();
4143
+ if (excludeIdsParam && columnNames.has("id")) {
4144
+ const excludeIdList = excludeIdsParam.split(",").map((s) => Number(s.trim())).filter((n) => Number.isFinite(n) && n > 0);
4145
+ if (excludeIdList.length > 0) {
4146
+ where = mergeListWhereAnd(where, {
4147
+ id: Not(In(excludeIdList))
4148
+ });
4149
+ }
4150
+ }
4078
4151
  if (resourceUsesVendorScope(resource)) {
4079
4152
  const scope = await resolveScope();
4080
4153
  const catalogFlags = await getVendorCatalogCreateFlags(dataSource);
@@ -5117,11 +5190,18 @@ function createCrudHandler(dataSource, entityMap, options) {
5117
5190
  await recordDiscountUsage2(dataSource, entityMap, created.id, orderDiscountId, persistBody.contactId, discount);
5118
5191
  }
5119
5192
  const orderIdForNotify = created.id;
5120
- void import('./emit-order-notification-trigger-HZQPPSFB.js').then(({ fireOrderNotificationTrigger }) => {
5193
+ const initialPayStatus = String(persistBody.paymentStatus ?? "unpaid").toLowerCase();
5194
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
5121
5195
  fireOrderNotificationTrigger("order_placed", orderIdForNotify, {
5122
5196
  dataSource,
5123
5197
  entityMap
5124
5198
  });
5199
+ if (initialPayStatus === "paid" || initialPayStatus === "captured") {
5200
+ fireOrderNotificationTrigger("payment_success", orderIdForNotify, {
5201
+ dataSource,
5202
+ entityMap
5203
+ });
5204
+ }
5125
5205
  });
5126
5206
  }
5127
5207
  } catch (err) {
@@ -6588,6 +6668,43 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6588
6668
  await retireSoftDeletedUniquesFromBody(repo, updatePayload);
6589
6669
  try {
6590
6670
  await repo.update(numericId, updatePayload);
6671
+ if (resource === "payments" && updatePayload.status) {
6672
+ const updatedPay = await repo.findOne({
6673
+ where: {
6674
+ id: numericId
6675
+ }
6676
+ });
6677
+ const pOrder = updatedPay?.orderId;
6678
+ const newPayStatus = String(updatePayload.status).toLowerCase();
6679
+ if (pOrder && Number.isFinite(pOrder)) {
6680
+ if (newPayStatus === "paid" || newPayStatus === "captured") {
6681
+ if (entityMap.orders) {
6682
+ await dataSource.getRepository(entityMap.orders).update(pOrder, {
6683
+ status: "confirmed"
6684
+ });
6685
+ }
6686
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
6687
+ fireOrderNotificationTrigger("order_placed", pOrder, {
6688
+ dataSource,
6689
+ entityMap
6690
+ });
6691
+ fireOrderNotificationTrigger("payment_success", pOrder, {
6692
+ dataSource,
6693
+ entityMap
6694
+ });
6695
+ }).catch(() => {
6696
+ });
6697
+ } else if (newPayStatus === "failed") {
6698
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
6699
+ fireOrderNotificationTrigger("payment_failed", pOrder, {
6700
+ dataSource,
6701
+ entityMap
6702
+ });
6703
+ }).catch(() => {
6704
+ });
6705
+ }
6706
+ }
6707
+ }
6591
6708
  } catch (err) {
6592
6709
  if (resource === "events" && isSlugUniqueViolation(err)) {
6593
6710
  return json({
@@ -8711,25 +8828,79 @@ function createUploadHandler(config) {
8711
8828
  "application/x-zip-compressed"
8712
8829
  ];
8713
8830
  return /* @__PURE__ */ __name(async function POST(req) {
8831
+ const reqId = `req-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
8832
+ console.info("[upload] POST /api/upload start", {
8833
+ reqId,
8834
+ method: req.method,
8835
+ contentType: req.headers.get("content-type"),
8836
+ contentLength: req.headers.get("content-length"),
8837
+ hasStorageConfig: storage != null
8838
+ });
8714
8839
  const authErr = await requireAuth(req);
8715
- if (authErr) return authErr;
8840
+ if (authErr) {
8841
+ console.error("[upload] auth failed", {
8842
+ reqId,
8843
+ status: authErr.status
8844
+ });
8845
+ return authErr;
8846
+ }
8847
+ console.info("[upload] auth ok", {
8848
+ reqId
8849
+ });
8716
8850
  if (requireEntityPermission) {
8717
8851
  const pe = await requireEntityPermission(req, "upload", "create");
8718
- if (pe) return pe;
8852
+ if (pe) {
8853
+ console.error("[upload] permission denied", {
8854
+ reqId,
8855
+ status: pe.status
8856
+ });
8857
+ return pe;
8858
+ }
8859
+ console.info("[upload] permission ok", {
8860
+ reqId,
8861
+ entity: "upload",
8862
+ action: "create"
8863
+ });
8719
8864
  }
8720
8865
  try {
8866
+ console.info("[upload] parsing formData", {
8867
+ reqId
8868
+ });
8721
8869
  const formData = await req.formData();
8722
8870
  const file = formData.get("file");
8723
- if (!file) return json({
8724
- error: "No file uploaded"
8725
- }, {
8726
- status: 400
8727
- });
8728
- if (!allowed.includes(file.type)) return json({
8729
- error: "File type not allowed"
8730
- }, {
8731
- status: 400
8871
+ console.info("[upload] formData parsed", {
8872
+ reqId,
8873
+ hasFile: Boolean(file),
8874
+ fileName: file?.name ?? null,
8875
+ fileType: file?.type ?? null,
8876
+ fileSize: file?.size ?? null,
8877
+ formKeys: [
8878
+ ...formData.keys()
8879
+ ]
8732
8880
  });
8881
+ if (!file) {
8882
+ console.error("[upload] no file in formData", {
8883
+ reqId
8884
+ });
8885
+ return json({
8886
+ error: "No file uploaded"
8887
+ }, {
8888
+ status: 400
8889
+ });
8890
+ }
8891
+ if (!allowed.includes(file.type)) {
8892
+ console.error("[upload] file type not allowed", {
8893
+ reqId,
8894
+ fileType: file.type,
8895
+ fileName: file.name,
8896
+ allowed
8897
+ });
8898
+ return json({
8899
+ error: "File type not allowed"
8900
+ }, {
8901
+ status: 400
8902
+ });
8903
+ }
8733
8904
  const defaultMax = 10 * 1024 * 1024;
8734
8905
  const maxZipBytes = 80 * 1024 * 1024;
8735
8906
  const maxVideoBytes = 100 * 1024 * 1024;
@@ -8737,25 +8908,51 @@ function createUploadHandler(config) {
8737
8908
  const isZip = file.type === "application/zip" || file.type === "application/x-zip-compressed";
8738
8909
  const isVideo = file.type === "video/mp4" || file.type === "video/webm" || file.type === "video/quicktime";
8739
8910
  const effectiveMax = isZip ? Math.max(baseMax, maxZipBytes) : isVideo ? Math.max(baseMax, maxVideoBytes) : baseMax;
8740
- if (file.size > effectiveMax) return json({
8741
- error: "File size exceeds limit"
8742
- }, {
8743
- status: 400
8911
+ console.info("[upload] size check", {
8912
+ reqId,
8913
+ fileSize: file.size,
8914
+ effectiveMax,
8915
+ isZip,
8916
+ isVideo,
8917
+ isImage: file.type.startsWith("image/")
8744
8918
  });
8919
+ if (file.size > effectiveMax) {
8920
+ console.error("[upload] file too large", {
8921
+ reqId,
8922
+ fileSize: file.size,
8923
+ effectiveMax,
8924
+ fileName: file.name
8925
+ });
8926
+ return json({
8927
+ error: "File size exceeds limit"
8928
+ }, {
8929
+ status: 400
8930
+ });
8931
+ }
8745
8932
  const parentRaw = formData.get("parentId");
8746
8933
  let parentId = null;
8747
8934
  if (parentRaw != null && String(parentRaw).trim() !== "") {
8748
8935
  const n = Number(parentRaw);
8749
- if (!Number.isFinite(n)) return json({
8750
- error: "Invalid parentId"
8751
- }, {
8752
- status: 400
8753
- });
8936
+ if (!Number.isFinite(n)) {
8937
+ console.error("[upload] invalid parentId", {
8938
+ reqId,
8939
+ parentRaw
8940
+ });
8941
+ return json({
8942
+ error: "Invalid parentId"
8943
+ }, {
8944
+ status: 400
8945
+ });
8946
+ }
8754
8947
  parentId = n;
8755
8948
  }
8756
8949
  let folder = "";
8757
8950
  if (parentId != null) {
8758
8951
  if (!dataSource || !entityMap?.media) {
8952
+ console.error("[upload] missing dataSource/entityMap for folder upload", {
8953
+ reqId,
8954
+ parentId
8955
+ });
8759
8956
  return json({
8760
8957
  error: "Upload handler needs dataSource and entityMap for folder uploads"
8761
8958
  }, {
@@ -8769,6 +8966,12 @@ function createUploadHandler(config) {
8769
8966
  }
8770
8967
  });
8771
8968
  if (!p || p.kind !== "folder") {
8969
+ console.error("[upload] parent is not a folder", {
8970
+ reqId,
8971
+ parentId,
8972
+ found: Boolean(p),
8973
+ kind: p ? p.kind : null
8974
+ });
8772
8975
  return json({
8773
8976
  error: "parent must be a folder"
8774
8977
  }, {
@@ -8776,25 +8979,90 @@ function createUploadHandler(config) {
8776
8979
  });
8777
8980
  }
8778
8981
  folder = await relativePathFromMediaParentId(dataSource, entityMap, parentId);
8982
+ console.info("[upload] resolved folder from parentId", {
8983
+ reqId,
8984
+ parentId,
8985
+ folder
8986
+ });
8779
8987
  } else {
8780
8988
  const folderRawLegacy = formData.get("folder") ?? formData.get("folderPath");
8781
8989
  if (folderRawLegacy && typeof folderRawLegacy === "string" && folderRawLegacy.trim()) {
8782
8990
  folder = sanitizeMediaFolderPath(folderRawLegacy);
8991
+ console.info("[upload] resolved folder from legacy field", {
8992
+ reqId,
8993
+ folder
8994
+ });
8783
8995
  }
8784
8996
  }
8997
+ console.info("[upload] reading file into buffer", {
8998
+ reqId,
8999
+ fileName: file.name,
9000
+ fileType: file.type,
9001
+ fileSize: file.size
9002
+ });
8785
9003
  const buffer = Buffer.from(await file.arrayBuffer());
8786
9004
  const fileName = `${Date.now()}-${file.name}`;
8787
9005
  const contentType = file.type || "application/octet-stream";
8788
9006
  const relativeUnderUploads = folder ? `${folder}/${fileName}` : fileName;
9007
+ const storageKey = `uploads/${relativeUnderUploads}`;
9008
+ console.info("[upload] S3/storage key prepared", {
9009
+ reqId,
9010
+ originalFileName: file.name,
9011
+ stampedFileName: fileName,
9012
+ folder: folder || "(root)",
9013
+ relativeUnderUploads,
9014
+ storageKey,
9015
+ contentType,
9016
+ bytes: buffer.length
9017
+ });
8789
9018
  const raw = typeof storage === "function" ? storage() : storage;
9019
+ console.info("[upload] resolving storage service", {
9020
+ reqId,
9021
+ storageKey,
9022
+ storageIsFunction: typeof storage === "function",
9023
+ rawIsPromise: raw instanceof Promise,
9024
+ rawIsNullish: raw == null
9025
+ });
8790
9026
  const storageService = raw instanceof Promise ? await raw : raw;
9027
+ console.info("[upload] storage service resolved", {
9028
+ reqId,
9029
+ storageKey,
9030
+ hasStorageService: Boolean(storageService)
9031
+ });
8791
9032
  if (storageService) {
8792
- const fileUrl = await storageService.upload(buffer, `uploads/${relativeUnderUploads}`, contentType);
9033
+ console.info("[upload] calling storage.upload", {
9034
+ reqId,
9035
+ storageKey,
9036
+ contentType,
9037
+ bytes: buffer.length
9038
+ });
9039
+ const uploadStarted = Date.now();
9040
+ let fileUrl;
9041
+ try {
9042
+ fileUrl = await storageService.upload(buffer, storageKey, contentType);
9043
+ } catch (storageErr) {
9044
+ console.error("[upload] storage.upload threw", {
9045
+ reqId,
9046
+ storageKey,
9047
+ contentType,
9048
+ bytes: buffer.length,
9049
+ ms: Date.now() - uploadStarted,
9050
+ error: storageErr instanceof Error ? storageErr.message : String(storageErr),
9051
+ name: storageErr instanceof Error ? storageErr.name : void 0,
9052
+ stack: storageErr instanceof Error ? storageErr.stack : void 0,
9053
+ code: storageErr && typeof storageErr === "object" && ("Code" in storageErr || "code" in storageErr) ? storageErr.Code ?? storageErr.code : void 0,
9054
+ metadata: storageErr && typeof storageErr === "object" && "$metadata" in storageErr ? storageErr.$metadata : void 0
9055
+ });
9056
+ throw storageErr;
9057
+ }
8793
9058
  console.info("[upload] stored via storage plugin", {
8794
- key: `uploads/${relativeUnderUploads}`,
9059
+ reqId,
9060
+ key: storageKey,
9061
+ fullS3KeyHint: storageKey,
8795
9062
  contentType,
8796
9063
  bytes: buffer.length,
8797
- fileUrl
9064
+ fileUrl,
9065
+ ms: Date.now() - uploadStarted
8798
9066
  });
8799
9067
  return json({
8800
9068
  filePath: fileUrl,
@@ -8802,8 +9070,10 @@ function createUploadHandler(config) {
8802
9070
  });
8803
9071
  }
8804
9072
  console.warn("[upload] no storage plugin \u2014 writing local disk (broken on most deploys)", {
9073
+ reqId,
8805
9074
  localUploadDir,
8806
- key: relativeUnderUploads
9075
+ key: relativeUnderUploads,
9076
+ storageKey
8807
9077
  });
8808
9078
  const fs2 = await import('fs/promises');
8809
9079
  const path2 = await import('path');
@@ -8814,6 +9084,12 @@ function createUploadHandler(config) {
8814
9084
  });
8815
9085
  await fs2.writeFile(filePath, buffer);
8816
9086
  const urlRel = `${localUploadDir.replace(/^\/+/, "").replace(/\\/g, "/")}/${relativeUnderUploads.replace(/\\/g, "/")}`;
9087
+ console.info("[upload] local write ok", {
9088
+ reqId,
9089
+ diskPath: filePath,
9090
+ filePath: `/${urlRel}`,
9091
+ key: relativeUnderUploads
9092
+ });
8817
9093
  return json({
8818
9094
  filePath: `/${urlRel}`,
8819
9095
  parentId
@@ -8822,11 +9098,13 @@ function createUploadHandler(config) {
8822
9098
  const message = err instanceof Error ? err.message : String(err);
8823
9099
  const awsMeta = err && typeof err === "object" && "$metadata" in err ? err.$metadata : void 0;
8824
9100
  console.error("[upload] File upload failed", {
9101
+ reqId,
8825
9102
  error: message,
8826
9103
  stack: err instanceof Error ? err.stack : void 0,
8827
9104
  name: err instanceof Error ? err.name : void 0,
8828
9105
  code: err && typeof err === "object" && ("Code" in err || "code" in err) ? err.Code ?? err.code : void 0,
8829
- metadata: awsMeta
9106
+ metadata: awsMeta,
9107
+ raw: err instanceof Error ? void 0 : String(err)
8830
9108
  });
8831
9109
  if (/Failed to parse body as FormData/i.test(message)) {
8832
9110
  return json({
@@ -9142,7 +9420,9 @@ function createFormSaveHandlers(config) {
9142
9420
  "description",
9143
9421
  "campaign",
9144
9422
  "slug",
9145
- "published"
9423
+ "published",
9424
+ "enableTurnstile",
9425
+ "enable_turnstile"
9146
9426
  ]) {
9147
9427
  if (body[key] !== void 0) formRow[key] = body[key];
9148
9428
  }
@@ -9161,13 +9441,43 @@ function createFormSaveHandlers(config) {
9161
9441
  }
9162
9442
  }
9163
9443
  if (Object.keys(formRow).length > 0) await formRepo().update(formId, formRow);
9164
- await fieldRepo().delete({
9165
- formId
9166
- });
9444
+ const incomingFieldIds = /* @__PURE__ */ new Set();
9167
9445
  for (let i = 0; i < fields.length; i++) {
9168
- const row = normalizeFieldRow(fields[i], formId);
9446
+ const f = fields[i];
9447
+ const fieldId = f.id != null && Number.isFinite(Number(f.id)) && Number(f.id) > 0 ? Number(f.id) : null;
9448
+ const row = normalizeFieldRow(f, formId);
9169
9449
  row.order = i + 1;
9170
- await fieldRepo().save(fieldRepo().create(row));
9450
+ if (fieldId) {
9451
+ const existingField = await fieldRepo().findOne({
9452
+ where: {
9453
+ id: fieldId,
9454
+ formId
9455
+ }
9456
+ });
9457
+ if (existingField) {
9458
+ incomingFieldIds.add(fieldId);
9459
+ await fieldRepo().update({
9460
+ id: fieldId,
9461
+ formId
9462
+ }, row);
9463
+ continue;
9464
+ }
9465
+ }
9466
+ const created = await fieldRepo().save(fieldRepo().create(row));
9467
+ if (created?.id) incomingFieldIds.add(created.id);
9468
+ }
9469
+ const allCurrentFields = await fieldRepo().find({
9470
+ where: {
9471
+ formId
9472
+ }
9473
+ });
9474
+ for (const existingField of allCurrentFields) {
9475
+ if (!incomingFieldIds.has(existingField.id)) {
9476
+ await fieldRepo().delete({
9477
+ id: existingField.id,
9478
+ formId
9479
+ });
9480
+ }
9171
9481
  }
9172
9482
  const saved = await formRepo().findOne({
9173
9483
  where: {
@@ -9321,7 +9631,7 @@ function createFormSubmissionListHandler(config) {
9321
9631
  const limit = Math.min(100, Number(searchParams.get("limit")) || 10);
9322
9632
  const skip = (page - 1) * limit;
9323
9633
  const sortField = searchParams.get("sortField") || "createdAt";
9324
- const sortOrder = searchParams.get("sortOrder") === "desc" ? "DESC" : "ASC";
9634
+ const sortOrder = searchParams.get("sortOrder") === "asc" ? "ASC" : "DESC";
9325
9635
  const [data, total] = await repo.findAndCount({
9326
9636
  skip,
9327
9637
  take: limit,
@@ -17038,6 +17348,7 @@ var Form = class {
17038
17348
  campaign;
17039
17349
  slug;
17040
17350
  published;
17351
+ enableTurnstile;
17041
17352
  createdAt;
17042
17353
  updatedAt;
17043
17354
  deletedAt;
@@ -17080,6 +17391,14 @@ _ts_decorate14([
17080
17391
  }),
17081
17392
  _ts_metadata14("design:type", Boolean)
17082
17393
  ], Form.prototype, "published", void 0);
17394
+ _ts_decorate14([
17395
+ Column("boolean", {
17396
+ default: false,
17397
+ name: "enable_turnstile",
17398
+ nullable: true
17399
+ }),
17400
+ _ts_metadata14("design:type", Boolean)
17401
+ ], Form.prototype, "enableTurnstile", void 0);
17083
17402
  _ts_decorate14([
17084
17403
  Column({
17085
17404
  type: "timestamp",
@@ -29217,7 +29536,7 @@ function createCmsApiHandler(config) {
29217
29536
  }
29218
29537
  if (path2[0] === "settings" && path2.length === 2 && settingsHandlers) {
29219
29538
  const group = path2[1];
29220
- const isPublic = group === "multi_vendor" || settingsConfig?.publicGetGroups?.includes(group);
29539
+ const isPublic = group === "multi_vendor" || group === "turnstile" || group === "auth_providers" || settingsConfig?.publicGetGroups?.includes(group);
29221
29540
  if (m === "GET") {
29222
29541
  if (!isPublic) {
29223
29542
  const a = await config.requireAuth(req);
@@ -29875,14 +30194,21 @@ function createCmsApiHandler(config) {
29875
30194
  body = {};
29876
30195
  }
29877
30196
  const triggerKey = String(body.triggerKey ?? "order_placed").trim() || "order_placed";
29878
- if (triggerKey !== "order_placed" && triggerKey !== "order_cancelled") {
30197
+ const validTriggers = [
30198
+ "order_placed",
30199
+ "order_cancelled",
30200
+ "payment_success",
30201
+ "payment_failed",
30202
+ "payment_refund_initiated"
30203
+ ];
30204
+ if (!validTriggers.includes(triggerKey)) {
29879
30205
  return config.json({
29880
- error: "Invalid triggerKey; use order_placed or order_cancelled"
30206
+ error: `Invalid triggerKey; use one of: ${validTriggers.join(", ")}`
29881
30207
  }, {
29882
30208
  status: 400
29883
30209
  });
29884
30210
  }
29885
- const { resendOrderNotification } = await import('./order-notification-dispatcher-64WDCHHG.js');
30211
+ const { resendOrderNotification } = await import('./order-notification-dispatcher-ZSFKEYMP.js');
29886
30212
  const result = await resendOrderNotification(triggerKey, orderId, {
29887
30213
  dataSource,
29888
30214
  entityMap,
@@ -29904,11 +30230,9 @@ function createCmsApiHandler(config) {
29904
30230
  if (path2[0] === "orders" && path2.length === 3 && path2[2] === "cancel" && m === "POST") {
29905
30231
  const a = await config.requireAuth(req);
29906
30232
  if (a) return a;
29907
- const pe = await requireEntityPermissionEffective(req, "orders", "update");
29908
- if (pe) return pe;
29909
- const orderId = Number(path2[1]);
29910
- if (!Number.isFinite(orderId)) return config.json({
29911
- error: "Invalid id"
30233
+ const orderId = parseInt(path2[1], 10);
30234
+ if (Number.isNaN(orderId)) return config.json({
30235
+ error: "Invalid order ID"
29912
30236
  }, {
29913
30237
  status: 400
29914
30238
  });
@@ -29925,9 +30249,10 @@ function createCmsApiHandler(config) {
29925
30249
  status: 404
29926
30250
  });
29927
30251
  const o = order;
29928
- if (o.status !== "confirmed" && o.status !== "completed") {
30252
+ const currentStatus = (o.status || "").toLowerCase();
30253
+ if (currentStatus === "cancelled") {
29929
30254
  return config.json({
29930
- error: "Only confirmed or completed orders can be cancelled"
30255
+ error: "Order is already cancelled"
29931
30256
  }, {
29932
30257
  status: 400
29933
30258
  });
@@ -29950,7 +30275,7 @@ function createCmsApiHandler(config) {
29950
30275
  }
29951
30276
  });
29952
30277
  if (payment) {
29953
- paymentStatus = String(payment.status ?? "unpaid");
30278
+ paymentStatus = String(payment.status ?? "unpaid").toLowerCase();
29954
30279
  paymentId = Number(payment.id);
29955
30280
  }
29956
30281
  }
@@ -29982,13 +30307,26 @@ function createCmsApiHandler(config) {
29982
30307
  status: "cancelled"
29983
30308
  });
29984
30309
  const fireOrderCancelledNotification = /* @__PURE__ */ __name((refundAmount) => {
29985
- void import('./emit-order-notification-trigger-HZQPPSFB.js').then(({ fireOrderNotificationTrigger }) => {
30310
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
29986
30311
  fireOrderNotificationTrigger("order_cancelled", orderId, {
29987
30312
  dataSource,
29988
30313
  entityMap
29989
30314
  }, refundAmount != null && refundAmount > 0 ? {
29990
30315
  refundAmount
29991
30316
  } : void 0);
30317
+ if (paymentStatus === "paid" || paymentStatus === "captured") {
30318
+ fireOrderNotificationTrigger("payment_refund_initiated", orderId, {
30319
+ dataSource,
30320
+ entityMap
30321
+ }, refundAmount != null && refundAmount > 0 ? {
30322
+ refundAmount
30323
+ } : void 0);
30324
+ } else {
30325
+ fireOrderNotificationTrigger("payment_failed", orderId, {
30326
+ dataSource,
30327
+ entityMap
30328
+ });
30329
+ }
29992
30330
  });
29993
30331
  }, "fireOrderCancelledNotification");
29994
30332
  if (paymentStatus === "paid" && entityMap.payments && paymentId) {
@@ -31014,12 +31352,23 @@ function createStorefrontApiHandler(config) {
31014
31352
  const otpFlags = config.otpFlags;
31015
31353
  const otpPepper = config.otpPepper;
31016
31354
  const defaultPhoneCc = config.defaultPhoneCountryCode;
31017
- function fireOrderPlacedNotification(orderId) {
31018
- void import('./emit-order-notification-trigger-HZQPPSFB.js').then(({ fireOrderNotificationTrigger }) => {
31355
+ function fireOrderPlacedNotification(orderId, isPaid) {
31356
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
31019
31357
  fireOrderNotificationTrigger("order_placed", orderId, {
31020
31358
  dataSource,
31021
31359
  entityMap
31022
31360
  });
31361
+ if (isPaid) {
31362
+ fireOrderNotificationTrigger("payment_success", orderId, {
31363
+ dataSource,
31364
+ entityMap
31365
+ });
31366
+ } else {
31367
+ fireOrderNotificationTrigger("payment_failed", orderId, {
31368
+ dataSource,
31369
+ entityMap
31370
+ });
31371
+ }
31023
31372
  }).catch((err) => console.error("[notification-triggers] import failed", err));
31024
31373
  }
31025
31374
  __name(fireOrderPlacedNotification, "fireOrderPlacedNotification");
@@ -31054,7 +31403,7 @@ function createStorefrontApiHandler(config) {
31054
31403
  const meta = it.metadata && typeof it.metadata === "object" && !Array.isArray(it.metadata) ? it.metadata : {};
31055
31404
  const fromMeta = Number(meta.comboId ?? meta.combo_id);
31056
31405
  if (Number.isInteger(fromMeta) && fromMeta > 0) return fromMeta;
31057
- if (meta.isCombo === true || meta.type === "combo" || meta.lineType === "combo") {
31406
+ if (meta.isCombo === true || meta.type === "combo" || meta.lineType === "combo" || meta.lineKind === "combo" || meta.itemType === "combo") {
31058
31407
  const pid = Number(it.productId);
31059
31408
  if (Number.isInteger(pid) && pid > 0) return pid;
31060
31409
  }
@@ -33183,7 +33532,10 @@ function createStorefrontApiHandler(config) {
33183
33532
  });
33184
33533
  if (existing) {
33185
33534
  await cartItemRepo().update(existing.id, {
33186
- quantity: existing.quantity + gi.quantity
33535
+ quantity: gi.quantity,
33536
+ ...gi.metadata ? {
33537
+ metadata: gi.metadata
33538
+ } : {}
33187
33539
  });
33188
33540
  } else {
33189
33541
  await cartItemRepo().save(cartItemRepo().create({
@@ -33904,6 +34256,20 @@ function createStorefrontApiHandler(config) {
33904
34256
  }
33905
34257
  } catch {
33906
34258
  }
34259
+ try {
34260
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
34261
+ fireOrderNotificationTrigger("order_cancelled", orderId, {
34262
+ dataSource,
34263
+ entityMap
34264
+ });
34265
+ fireOrderNotificationTrigger("payment_failed", orderId, {
34266
+ dataSource,
34267
+ entityMap
34268
+ });
34269
+ }).catch(() => {
34270
+ });
34271
+ } catch {
34272
+ }
33907
34273
  }
33908
34274
  return json({
33909
34275
  ok: true,