@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.
- package/dist/admin.cjs +1020 -83
- package/dist/admin.js +1021 -84
- package/dist/api.cjs +38 -38
- package/dist/api.js +5 -5
- package/dist/auth.cjs +51 -51
- package/dist/auth.js +3 -3
- package/dist/{chunk-3EOM4V2M.cjs → chunk-4U6DATGZ.cjs} +7 -7
- package/dist/{chunk-BNKZNLEX.js → chunk-6DBDJ4VD.js} +2 -2
- package/dist/{chunk-UQWZUZ5X.cjs → chunk-73WVHINE.cjs} +30 -6
- package/dist/{chunk-UCKN4BBY.cjs → chunk-77I3KS7V.cjs} +4 -1
- package/dist/{chunk-MCCA7WLQ.cjs → chunk-CNAHVRRU.cjs} +533 -167
- package/dist/{chunk-77NUXO6A.cjs → chunk-J7FMZK66.cjs} +10 -2
- package/dist/{chunk-BC22I7C7.cjs → chunk-KM2I6AFP.cjs} +9 -9
- package/dist/{chunk-JIWUVQ6B.js → chunk-MVHDC3XF.js} +10 -2
- package/dist/{chunk-RK5ETF2I.js → chunk-NR44CK5E.js} +1 -1
- package/dist/{chunk-MXIWUFBP.js → chunk-O2642WVS.js} +28 -4
- package/dist/{chunk-HCIRL37O.js → chunk-T3HPSF7K.js} +4 -1
- package/dist/{chunk-BTUEUA5H.js → chunk-UHT4INVW.js} +453 -87
- package/dist/{chunk-HYW3MUXT.js → chunk-URN7GS23.js} +30 -16
- package/dist/{chunk-HXLC56ZK.cjs → chunk-YSYX4GUD.cjs} +32 -18
- package/dist/{emit-order-notification-trigger-HZQPPSFB.js → emit-order-notification-trigger-CZU3V2WE.js} +2 -2
- package/dist/{emit-order-notification-trigger-NR3VN6C6.cjs → emit-order-notification-trigger-TNEZOYEE.cjs} +4 -4
- package/dist/index.cjs +614 -333
- package/dist/index.d.cts +31 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +329 -48
- package/dist/migrations/1782800000000-AddPaymentSuccessFailedRefundTriggers.ts +32 -0
- package/dist/migrations/1782900000000-AddEnableTurnstileToForms.ts +29 -0
- package/dist/{order-notification-dispatcher-2FCZFZUD.cjs → order-notification-dispatcher-KJVGLK5E.cjs} +5 -5
- package/dist/{order-notification-dispatcher-64WDCHHG.js → order-notification-dispatcher-ZSFKEYMP.js} +2 -2
- package/dist/{rbac-debug-db-6EMIVMGF.js → rbac-debug-db-5R6XFPSV.js} +1 -1
- package/dist/{rbac-debug-db-6PWTLBEL.cjs → rbac-debug-db-JKK2MCWF.cjs} +2 -2
- 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-
|
|
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-
|
|
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-
|
|
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
|
|
2448
|
-
|
|
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
|
|
2481
|
+
const rawRuleValue = discountExtractValue(rule.value);
|
|
2451
2482
|
switch (rule.type) {
|
|
2452
|
-
case "minAmount":
|
|
2453
|
-
|
|
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,
|
|
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,
|
|
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:
|
|
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:
|
|
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:
|
|
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 (
|
|
2643
|
-
const excess = totalDiscountApplied -
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
3795
|
-
if (
|
|
3796
|
-
const ids =
|
|
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
|
|
3800
|
-
if (
|
|
3801
|
-
const excludeIds =
|
|
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
|
-
|
|
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)
|
|
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)
|
|
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
|
-
|
|
8724
|
-
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
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
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
8743
|
-
|
|
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))
|
|
8750
|
-
error
|
|
8751
|
-
|
|
8752
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9165
|
-
formId
|
|
9166
|
-
});
|
|
9444
|
+
const incomingFieldIds = /* @__PURE__ */ new Set();
|
|
9167
9445
|
for (let i = 0; i < fields.length; i++) {
|
|
9168
|
-
const
|
|
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
|
-
|
|
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") === "
|
|
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
|
-
|
|
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:
|
|
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-
|
|
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
|
|
29908
|
-
if (
|
|
29909
|
-
|
|
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
|
-
|
|
30252
|
+
const currentStatus = (o.status || "").toLowerCase();
|
|
30253
|
+
if (currentStatus === "cancelled") {
|
|
29929
30254
|
return config.json({
|
|
29930
|
-
error: "
|
|
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-
|
|
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-
|
|
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:
|
|
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,
|