@infuro/cms-core 1.0.36 → 1.0.39
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 +459 -496
- package/dist/admin.js +459 -496
- package/dist/api.cjs +36 -36
- package/dist/api.js +4 -4
- package/dist/auth.cjs +51 -51
- package/dist/auth.js +3 -3
- package/dist/{chunk-COBORIJH.cjs → chunk-22FFHLTO.cjs} +39 -56
- package/dist/{chunk-X6H5VBQ2.cjs → chunk-E6WVP7BK.cjs} +6 -6
- package/dist/{chunk-2AEVFOQP.cjs → chunk-ERJK5QXN.cjs} +418 -139
- package/dist/{chunk-VMY2S32H.js → chunk-NNQBWDCI.js} +39 -56
- package/dist/{chunk-WO2DW4AU.cjs → chunk-OIGCAGH7.cjs} +7 -7
- package/dist/{chunk-UF3BYUXY.js → chunk-P7QCLE5W.js} +4 -3
- package/dist/{chunk-FG6I64HP.js → chunk-SBRBR3VO.js} +1 -1
- package/dist/{chunk-JS2W7XZ4.js → chunk-SFDZMGHD.js} +351 -72
- package/dist/{chunk-LI2IXVAY.js → chunk-UXMDSNIG.js} +1 -1
- package/dist/{chunk-KPKFNLQQ.cjs → chunk-WMXPKKXU.cjs} +4 -3
- package/dist/index.cjs +260 -260
- package/dist/index.d.cts +12 -5
- package/dist/index.d.ts +12 -5
- package/dist/index.js +8 -8
- package/dist/migrations/1775500000000-RssFeedsAndArticles.ts +0 -1
- package/dist/migrations/1775700000000-JobSchedules.ts +0 -1
- package/dist/migrations/1781260000000-RenameWhatsappTriggerBindingsToOrderNotificationBindings.ts +92 -0
- package/dist/migrations/1781270000000-ComboVendorId.ts +58 -0
- package/dist/{whatsapp-trigger-dispatcher-ONHXI7UY.cjs → order-notification-dispatcher-RU7BTGGX.cjs} +3 -4
- package/dist/{whatsapp-trigger-dispatcher-PWFI4FKP.js → order-notification-dispatcher-XWIJYDGA.js} +1 -2
- package/dist/{rbac-debug-db-HWP65A4O.cjs → rbac-debug-db-KHG4FJC3.cjs} +2 -2
- package/dist/{rbac-debug-db-QJH3AD34.js → rbac-debug-db-QWHOENBR.js} +1 -1
- package/package.json +147 -147
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk22FFHLTO_cjs = require('./chunk-22FFHLTO.cjs');
|
|
4
4
|
var chunk7NMT3GBR_cjs = require('./chunk-7NMT3GBR.cjs');
|
|
5
5
|
var chunkPNOKNSG2_cjs = require('./chunk-PNOKNSG2.cjs');
|
|
6
6
|
var chunkXW5ATPRW_cjs = require('./chunk-XW5ATPRW.cjs');
|
|
7
7
|
var chunk3DZRIZOD_cjs = require('./chunk-3DZRIZOD.cjs');
|
|
8
8
|
var chunkSPQFNIYJ_cjs = require('./chunk-SPQFNIYJ.cjs');
|
|
9
9
|
var chunkXQ3QUHWR_cjs = require('./chunk-XQ3QUHWR.cjs');
|
|
10
|
-
var
|
|
11
|
-
var
|
|
10
|
+
var chunkOIGCAGH7_cjs = require('./chunk-OIGCAGH7.cjs');
|
|
11
|
+
var chunkWMXPKKXU_cjs = require('./chunk-WMXPKKXU.cjs');
|
|
12
12
|
var chunkD5FBNKQM_cjs = require('./chunk-D5FBNKQM.cjs');
|
|
13
13
|
var chunkUPLVMVRX_cjs = require('./chunk-UPLVMVRX.cjs');
|
|
14
14
|
var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
|
|
@@ -87,7 +87,7 @@ async function loadUserVendorContext(dataSource, userId, preferredVendorId) {
|
|
|
87
87
|
`, [
|
|
88
88
|
primary.vendorRoleId
|
|
89
89
|
]);
|
|
90
|
-
vendorEntityPerms =
|
|
90
|
+
vendorEntityPerms = chunkWMXPKKXU_cjs.permissionRowsToRecord(permRows);
|
|
91
91
|
} catch (err) {
|
|
92
92
|
if (!isMissingVendorRoleSchemaError(err)) throw err;
|
|
93
93
|
}
|
|
@@ -120,7 +120,7 @@ async function hydrateVendorSessionUser(dataSource, user) {
|
|
|
120
120
|
]);
|
|
121
121
|
const resolvedId = Number(byEmailRows[0]?.id);
|
|
122
122
|
if (!Number.isFinite(resolvedId)) {
|
|
123
|
-
|
|
123
|
+
chunkWMXPKKXU_cjs.logRbac("hydrateVendorSessionUser: unable to resolve numeric user id", {
|
|
124
124
|
email: user.email,
|
|
125
125
|
rawSessionId: user.id ?? null
|
|
126
126
|
});
|
|
@@ -140,7 +140,7 @@ async function hydrateVendorSessionUser(dataSource, user) {
|
|
|
140
140
|
const groupName = rows[0]?.groupName ?? user.groupName ?? null;
|
|
141
141
|
const groupId = rows[0]?.groupId ?? user.groupId ?? void 0;
|
|
142
142
|
const adminAccess = rows[0]?.adminAccess ?? user.adminAccess;
|
|
143
|
-
const isRBACAdmin = user.isRBACAdmin ??
|
|
143
|
+
const isRBACAdmin = user.isRBACAdmin ?? chunkWMXPKKXU_cjs.isSuperAdmin({
|
|
144
144
|
groupId,
|
|
145
145
|
groupName,
|
|
146
146
|
isRBACAdmin: user.isRBACAdmin
|
|
@@ -153,7 +153,7 @@ async function hydrateVendorSessionUser(dataSource, user) {
|
|
|
153
153
|
};
|
|
154
154
|
if (multiVendorEnabled) {
|
|
155
155
|
ctx = await loadUserVendorContext(dataSource, id, user.activeVendorId);
|
|
156
|
-
flags =
|
|
156
|
+
flags = chunkWMXPKKXU_cjs.vendorPortalFlagsFromUser({
|
|
157
157
|
email: user.email,
|
|
158
158
|
isRBACAdmin,
|
|
159
159
|
groupName,
|
|
@@ -188,7 +188,7 @@ async function hydrateVendorSessionUser(dataSource, user) {
|
|
|
188
188
|
isVendorPortal: flags.isVendorPortal,
|
|
189
189
|
isVendorOwner: flags.isVendorOwner
|
|
190
190
|
};
|
|
191
|
-
|
|
191
|
+
chunkWMXPKKXU_cjs.logRbac("hydrateVendorSessionUser", {
|
|
192
192
|
email: user.email,
|
|
193
193
|
userId: id,
|
|
194
194
|
groupName,
|
|
@@ -332,7 +332,7 @@ function repoHasVendorIdColumn(repo) {
|
|
|
332
332
|
}
|
|
333
333
|
chunkUSNT2KNT_cjs.__name(repoHasVendorIdColumn, "repoHasVendorIdColumn");
|
|
334
334
|
function resourceUsesVendorScope(resource) {
|
|
335
|
-
return resource === "vendors" ||
|
|
335
|
+
return resource === "vendors" || chunkWMXPKKXU_cjs.VENDOR_SCOPED_STORE_ENTITIES.has(resource);
|
|
336
336
|
}
|
|
337
337
|
chunkUSNT2KNT_cjs.__name(resourceUsesVendorScope, "resourceUsesVendorScope");
|
|
338
338
|
function mergeVendorScopeIntoWhere(where, scope, resource) {
|
|
@@ -2617,10 +2617,11 @@ async function calculateOrderTotalsFromLines(dataSource, entityMap, lineInputs,
|
|
|
2617
2617
|
}
|
|
2618
2618
|
});
|
|
2619
2619
|
if (combo) {
|
|
2620
|
-
const
|
|
2620
|
+
const comboVendorId = Number(combo.vendorId);
|
|
2621
|
+
const comboRows = await dataSource.query(`SELECT ci."productId" as "firstProductId"
|
|
2621
2622
|
FROM combo_items ci
|
|
2622
2623
|
JOIN products p ON p.id = ci."productId"
|
|
2623
|
-
WHERE ci."comboId" = $1 AND p.deleted = false
|
|
2624
|
+
WHERE ci."comboId" = $1 AND p.deleted = false
|
|
2624
2625
|
LIMIT 1`, [
|
|
2625
2626
|
productId
|
|
2626
2627
|
]);
|
|
@@ -2637,7 +2638,8 @@ async function calculateOrderTotalsFromLines(dataSource, entityMap, lineInputs,
|
|
|
2637
2638
|
...childProduct,
|
|
2638
2639
|
id: productId,
|
|
2639
2640
|
price: combo.price,
|
|
2640
|
-
name: combo.name
|
|
2641
|
+
name: combo.name,
|
|
2642
|
+
vendorId: Number.isFinite(comboVendorId) && comboVendorId > 0 ? comboVendorId : childProduct.vendorId
|
|
2641
2643
|
};
|
|
2642
2644
|
}
|
|
2643
2645
|
}
|
|
@@ -5193,6 +5195,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
5193
5195
|
});
|
|
5194
5196
|
}
|
|
5195
5197
|
if (resource === "combos") {
|
|
5198
|
+
const scope2 = await resolveScopeById();
|
|
5196
5199
|
const combo = await repo.findOne({
|
|
5197
5200
|
where: {
|
|
5198
5201
|
id: Number(id),
|
|
@@ -5203,6 +5206,8 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
5203
5206
|
"items.product"
|
|
5204
5207
|
]
|
|
5205
5208
|
});
|
|
5209
|
+
const comboDenied = vendorScopeAccessJson(combo, scope2, resource);
|
|
5210
|
+
if (comboDenied) return comboDenied;
|
|
5206
5211
|
return combo ? json(combo) : json({
|
|
5207
5212
|
message: "Not found"
|
|
5208
5213
|
}, {
|
|
@@ -7408,7 +7413,7 @@ function createVendorDashboardHandler(config) {
|
|
|
7408
7413
|
if (pe) return pe;
|
|
7409
7414
|
}
|
|
7410
7415
|
const user = await getSessionUser();
|
|
7411
|
-
if (!user || !
|
|
7416
|
+
if (!user || !chunkWMXPKKXU_cjs.isVendorPortalUser(user)) {
|
|
7412
7417
|
return json({
|
|
7413
7418
|
error: "Forbidden"
|
|
7414
7419
|
}, {
|
|
@@ -9632,7 +9637,7 @@ function createChatHandlers(config) {
|
|
|
9632
9637
|
const notifyEmailAgent = await findLlmAgentByScope(dataSource, entityMap, LLM_AGENT_SCOPE_EMAIL_INTENT_CHATBOT, {
|
|
9633
9638
|
enabledOnly: false
|
|
9634
9639
|
});
|
|
9635
|
-
const emailTool =
|
|
9640
|
+
const emailTool = chunk22FFHLTO_cjs.resolveChatEmailToolSettings(llmSettings, {
|
|
9636
9641
|
chatbotValidationRules: agentRow?.validationRules ?? null,
|
|
9637
9642
|
notifyAgent: notifyEmailAgent ? {
|
|
9638
9643
|
systemInstruction: notifyEmailAgent.systemInstruction,
|
|
@@ -9642,7 +9647,7 @@ function createChatHandlers(config) {
|
|
|
9642
9647
|
const emailPlugin2 = cms.getPlugin("email");
|
|
9643
9648
|
const convLeadSent = conv.leadEmailSentAt;
|
|
9644
9649
|
const chatAgentFn = llm.chatAgent?.bind(llm);
|
|
9645
|
-
console.info(
|
|
9650
|
+
console.info(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "pipeline check", {
|
|
9646
9651
|
conversationId,
|
|
9647
9652
|
enabled: emailTool.enabled,
|
|
9648
9653
|
intentCount: emailTool.intents.length,
|
|
@@ -9656,27 +9661,27 @@ function createChatHandlers(config) {
|
|
|
9656
9661
|
mergedPromptIncludesNotify: Boolean(notifyEmailAgent?.systemInstruction?.trim())
|
|
9657
9662
|
});
|
|
9658
9663
|
if (!emailTool.enabled) {
|
|
9659
|
-
console.info(
|
|
9664
|
+
console.info(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
9660
9665
|
conversationId,
|
|
9661
9666
|
reason: "email_tool_disabled"
|
|
9662
9667
|
});
|
|
9663
9668
|
} else if (emailTool.intents.length === 0) {
|
|
9664
|
-
console.info(
|
|
9669
|
+
console.info(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
9665
9670
|
conversationId,
|
|
9666
9671
|
reason: "no_intents_configured"
|
|
9667
9672
|
});
|
|
9668
9673
|
} else if (!emailPlugin2) {
|
|
9669
|
-
console.info(
|
|
9674
|
+
console.info(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
9670
9675
|
conversationId,
|
|
9671
9676
|
reason: "email_plugin_missing"
|
|
9672
9677
|
});
|
|
9673
9678
|
} else if (!chatAgentFn) {
|
|
9674
|
-
console.info(
|
|
9679
|
+
console.info(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
9675
9680
|
conversationId,
|
|
9676
9681
|
reason: "llm_chat_agent_unavailable"
|
|
9677
9682
|
});
|
|
9678
9683
|
} else if (convLeadSent) {
|
|
9679
|
-
console.info(
|
|
9684
|
+
console.info(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
9680
9685
|
conversationId,
|
|
9681
9686
|
reason: "lead_email_already_sent",
|
|
9682
9687
|
leadEmailSentAt: convLeadSent
|
|
@@ -9689,7 +9694,7 @@ function createChatHandlers(config) {
|
|
|
9689
9694
|
}
|
|
9690
9695
|
});
|
|
9691
9696
|
if (!contactRow) {
|
|
9692
|
-
console.warn(
|
|
9697
|
+
console.warn(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
9693
9698
|
conversationId,
|
|
9694
9699
|
reason: "contact_not_found",
|
|
9695
9700
|
contactId
|
|
@@ -9697,7 +9702,7 @@ function createChatHandlers(config) {
|
|
|
9697
9702
|
} else {
|
|
9698
9703
|
const c = contactRow;
|
|
9699
9704
|
try {
|
|
9700
|
-
const intent = await
|
|
9705
|
+
const intent = await chunk22FFHLTO_cjs.detectChatLeadIntent({
|
|
9701
9706
|
chatAgent: chatAgentFn
|
|
9702
9707
|
}, {
|
|
9703
9708
|
settings: emailTool,
|
|
@@ -9711,15 +9716,15 @@ function createChatHandlers(config) {
|
|
|
9711
9716
|
model: agentRow?.model?.trim() || notifyEmailAgent?.model?.trim() || void 0
|
|
9712
9717
|
});
|
|
9713
9718
|
if (!intent.intent || !intent.emailTo) {
|
|
9714
|
-
console.info(
|
|
9719
|
+
console.info(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "no email sent", {
|
|
9715
9720
|
conversationId,
|
|
9716
9721
|
reason: intent.intent ? "missing_email_to" : "no_intent_match",
|
|
9717
9722
|
intentLabel: intent.intentLabel,
|
|
9718
9723
|
classifierReason: intent.reason
|
|
9719
9724
|
});
|
|
9720
9725
|
} else {
|
|
9721
|
-
const intentRecipients =
|
|
9722
|
-
console.info(
|
|
9726
|
+
const intentRecipients = chunk22FFHLTO_cjs.parseIntentRecipientEmails(intent.emailTo);
|
|
9727
|
+
console.info(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "intent matched \u2014 sending", {
|
|
9723
9728
|
conversationId,
|
|
9724
9729
|
intent: intent.intent,
|
|
9725
9730
|
emailTo: intent.emailTo,
|
|
@@ -9728,8 +9733,8 @@ function createChatHandlers(config) {
|
|
|
9728
9733
|
});
|
|
9729
9734
|
const emailSettings = await loadSettingsGroupMap(dataSource, entityMap, "email");
|
|
9730
9735
|
const brandingSettings = await loadSettingsGroupMap(dataSource, entityMap, "branding");
|
|
9731
|
-
const companyDetails =
|
|
9732
|
-
const leadResult = await
|
|
9736
|
+
const companyDetails = chunk22FFHLTO_cjs.mergeEmailLayoutCompanyDetails(brandingSettings, emailSettings);
|
|
9737
|
+
const leadResult = await chunk22FFHLTO_cjs.sendChatLeadEmail(cms, emailSettings, brandingSettings, {
|
|
9733
9738
|
contactName: String(c.name ?? "").trim() || "Visitor",
|
|
9734
9739
|
contactEmail: String(c.email ?? "").trim(),
|
|
9735
9740
|
contactPhone: c.phone ?? null,
|
|
@@ -9737,7 +9742,7 @@ function createChatHandlers(config) {
|
|
|
9737
9742
|
latestMessage: message,
|
|
9738
9743
|
intentCode: intent.intent,
|
|
9739
9744
|
intentReason: intent.intentLabel || intent.reason,
|
|
9740
|
-
transcript:
|
|
9745
|
+
transcript: chunk22FFHLTO_cjs.buildTranscriptForLeadEmail(history, message),
|
|
9741
9746
|
companyDetails,
|
|
9742
9747
|
recipients: intentRecipients.length > 0 ? intentRecipients : void 0
|
|
9743
9748
|
});
|
|
@@ -9745,13 +9750,13 @@ function createChatHandlers(config) {
|
|
|
9745
9750
|
await convRepo().update(conversationId, {
|
|
9746
9751
|
leadEmailSentAt: /* @__PURE__ */ new Date()
|
|
9747
9752
|
});
|
|
9748
|
-
console.info(
|
|
9753
|
+
console.info(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "lead email recorded", {
|
|
9749
9754
|
conversationId,
|
|
9750
9755
|
sent: true,
|
|
9751
9756
|
recipients: leadResult.recipients
|
|
9752
9757
|
});
|
|
9753
9758
|
} else {
|
|
9754
|
-
console.warn(
|
|
9759
|
+
console.warn(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "lead email not sent", {
|
|
9755
9760
|
conversationId,
|
|
9756
9761
|
sent: false,
|
|
9757
9762
|
error: leadResult.error ?? "unknown",
|
|
@@ -9760,7 +9765,7 @@ function createChatHandlers(config) {
|
|
|
9760
9765
|
}
|
|
9761
9766
|
}
|
|
9762
9767
|
} catch (intentErr) {
|
|
9763
|
-
console.warn(
|
|
9768
|
+
console.warn(chunk22FFHLTO_cjs.CHAT_EMAIL_LOG, "pipeline error", {
|
|
9764
9769
|
conversationId,
|
|
9765
9770
|
error: intentErr instanceof Error ? intentErr.message : String(intentErr)
|
|
9766
9771
|
});
|
|
@@ -9777,7 +9782,7 @@ function createChatHandlers(config) {
|
|
|
9777
9782
|
});
|
|
9778
9783
|
if (agentRow && llm.chatAgent) {
|
|
9779
9784
|
const fromAgent = llmAgentToChatAgentOptions(agentRow);
|
|
9780
|
-
const systemPrompt =
|
|
9785
|
+
const systemPrompt = chunk22FFHLTO_cjs.buildChatbotSystemPromptWithEmailTool(fromAgent.systemPrompt, parsedValidation.guardrailsForPrompt, emailTool);
|
|
9781
9786
|
const res = await llm.chatAgent({
|
|
9782
9787
|
...fromAgent,
|
|
9783
9788
|
systemPrompt: systemPrompt || void 0,
|
|
@@ -9798,7 +9803,7 @@ ${contextParts.join("\n\n")}` : "";
|
|
|
9798
9803
|
agentRow.systemInstruction?.trim(),
|
|
9799
9804
|
ragSystem
|
|
9800
9805
|
].filter(Boolean).join("\n\n");
|
|
9801
|
-
systemContent =
|
|
9806
|
+
systemContent = chunk22FFHLTO_cjs.buildChatbotSystemPromptWithEmailTool(mergedBase || defaultSystem, parsedValidation.guardrailsForPrompt, emailTool) || defaultSystem;
|
|
9802
9807
|
} else {
|
|
9803
9808
|
systemContent = ragSystem || defaultSystem;
|
|
9804
9809
|
}
|
|
@@ -11209,7 +11214,7 @@ chunkUSNT2KNT_cjs.__name(findActiveRefundPolicyForVendor, "findActiveRefundPolic
|
|
|
11209
11214
|
// src/api/admin-roles-handlers.ts
|
|
11210
11215
|
function createAdminRolesHandlers(config) {
|
|
11211
11216
|
const { dataSource, entityMap, json, getSessionUser } = config;
|
|
11212
|
-
const baseEntities =
|
|
11217
|
+
const baseEntities = chunkWMXPKKXU_cjs.getPermissionableEntityKeys(entityMap);
|
|
11213
11218
|
const allowEntities = /* @__PURE__ */ new Set([
|
|
11214
11219
|
...baseEntities,
|
|
11215
11220
|
"users"
|
|
@@ -11224,7 +11229,7 @@ function createAdminRolesHandlers(config) {
|
|
|
11224
11229
|
}, {
|
|
11225
11230
|
status: 401
|
|
11226
11231
|
});
|
|
11227
|
-
if (!
|
|
11232
|
+
if (!chunkOIGCAGH7_cjs.canManageRoles(u) && !chunkWMXPKKXU_cjs.canManageVendorRoles(u)) {
|
|
11228
11233
|
return json({
|
|
11229
11234
|
error: "Forbidden"
|
|
11230
11235
|
}, {
|
|
@@ -11235,11 +11240,11 @@ function createAdminRolesHandlers(config) {
|
|
|
11235
11240
|
}
|
|
11236
11241
|
chunkUSNT2KNT_cjs.__name(gate, "gate");
|
|
11237
11242
|
function isVendorRolesOnly(u) {
|
|
11238
|
-
return
|
|
11243
|
+
return chunkWMXPKKXU_cjs.canManageVendorRoles(u) && !chunkOIGCAGH7_cjs.canManageRoles(u);
|
|
11239
11244
|
}
|
|
11240
11245
|
chunkUSNT2KNT_cjs.__name(isVendorRolesOnly, "isVendorRolesOnly");
|
|
11241
11246
|
const vendorRoleEntities = [
|
|
11242
|
-
...
|
|
11247
|
+
...chunkWMXPKKXU_cjs.VENDOR_STORE_RBAC_ENTITIES,
|
|
11243
11248
|
"dashboard",
|
|
11244
11249
|
"settings"
|
|
11245
11250
|
].sort();
|
|
@@ -11396,7 +11401,7 @@ function createAdminRolesHandlers(config) {
|
|
|
11396
11401
|
}, {
|
|
11397
11402
|
status: 404
|
|
11398
11403
|
});
|
|
11399
|
-
if (
|
|
11404
|
+
if (chunkWMXPKKXU_cjs.isSuperAdminGroupName(g.name) && !chunkWMXPKKXU_cjs.isSuperAdminGroupName(name)) {
|
|
11400
11405
|
return json({
|
|
11401
11406
|
error: "Cannot rename the administrator group"
|
|
11402
11407
|
}, {
|
|
@@ -11453,7 +11458,7 @@ function createAdminRolesHandlers(config) {
|
|
|
11453
11458
|
}, {
|
|
11454
11459
|
status: 404
|
|
11455
11460
|
});
|
|
11456
|
-
if (
|
|
11461
|
+
if (chunkWMXPKKXU_cjs.isSuperAdminGroupName(g.name)) return json({
|
|
11457
11462
|
error: "Cannot delete the administrator group"
|
|
11458
11463
|
}, {
|
|
11459
11464
|
status: 400
|
|
@@ -11592,8 +11597,8 @@ async function sendVendorOnboardEmails(input, deps) {
|
|
|
11592
11597
|
getSettingsGroup(deps, "branding"),
|
|
11593
11598
|
getSettingsGroup(deps, "email")
|
|
11594
11599
|
]);
|
|
11595
|
-
const companyDetails =
|
|
11596
|
-
const notifyEmails =
|
|
11600
|
+
const companyDetails = chunk22FFHLTO_cjs.mergeEmailLayoutCompanyDetails(branding, emailSettings);
|
|
11601
|
+
const notifyEmails = chunk22FFHLTO_cjs.parseEmailRecipientsFromConfig(emailSettings.salesTeamEmails ?? emailSettings.salesTeamEmail);
|
|
11597
11602
|
const sendToOwner = input.sendToOwner !== false;
|
|
11598
11603
|
const ownerEmail = input.ownerEmail?.trim() || "";
|
|
11599
11604
|
const cms = await deps.getCms();
|
|
@@ -11621,7 +11626,7 @@ chunkUSNT2KNT_cjs.__name(sendVendorOnboardEmails, "sendVendorOnboardEmails");
|
|
|
11621
11626
|
|
|
11622
11627
|
// src/lib/seed-vendor-roles.ts
|
|
11623
11628
|
async function insertRolePermissions(exec, vendorRoleId, permissions) {
|
|
11624
|
-
for (const entity of
|
|
11629
|
+
for (const entity of chunkWMXPKKXU_cjs.VENDOR_RBAC_ENTITIES) {
|
|
11625
11630
|
const flags = permissions[entity];
|
|
11626
11631
|
if (!flags) continue;
|
|
11627
11632
|
await exec.query(`
|
|
@@ -11652,7 +11657,7 @@ async function seedVendorDefaultRoles(em, vendorId) {
|
|
|
11652
11657
|
for (const r of existing) {
|
|
11653
11658
|
roleIdsByName2[r.name] = Number(r.id);
|
|
11654
11659
|
if (r.isOwnerRole) ownerRoleId2 = Number(r.id);
|
|
11655
|
-
if (r.name ===
|
|
11660
|
+
if (r.name === chunkWMXPKKXU_cjs.VENDOR_VIEWER_ROLE_NAME) viewerRoleId2 = Number(r.id);
|
|
11656
11661
|
}
|
|
11657
11662
|
return {
|
|
11658
11663
|
roleIdsByName: roleIdsByName2,
|
|
@@ -11663,7 +11668,7 @@ async function seedVendorDefaultRoles(em, vendorId) {
|
|
|
11663
11668
|
const roleIdsByName = {};
|
|
11664
11669
|
let ownerRoleId = 0;
|
|
11665
11670
|
let viewerRoleId = 0;
|
|
11666
|
-
for (const def of
|
|
11671
|
+
for (const def of chunkWMXPKKXU_cjs.DEFAULT_VENDOR_ROLE_DEFS) {
|
|
11667
11672
|
const inserted = await exec.query(`
|
|
11668
11673
|
INSERT INTO "vendor_roles"
|
|
11669
11674
|
("vendorId", "name", "description", "isSystem", "isOwnerRole")
|
|
@@ -11680,7 +11685,7 @@ async function seedVendorDefaultRoles(em, vendorId) {
|
|
|
11680
11685
|
if (!roleId) continue;
|
|
11681
11686
|
roleIdsByName[def.name] = roleId;
|
|
11682
11687
|
if (def.isOwnerRole) ownerRoleId = roleId;
|
|
11683
|
-
if (def.name ===
|
|
11688
|
+
if (def.name === chunkWMXPKKXU_cjs.VENDOR_VIEWER_ROLE_NAME) viewerRoleId = roleId;
|
|
11684
11689
|
await insertRolePermissions(exec, roleId, def.permissions);
|
|
11685
11690
|
}
|
|
11686
11691
|
return {
|
|
@@ -11701,7 +11706,7 @@ async function backfillVendorUserRoleIds(em, vendorId, seeded) {
|
|
|
11701
11706
|
vendorId
|
|
11702
11707
|
]);
|
|
11703
11708
|
}
|
|
11704
|
-
const viewerId = seeded.viewerRoleId || seeded.roleIdsByName[
|
|
11709
|
+
const viewerId = seeded.viewerRoleId || seeded.roleIdsByName[chunkWMXPKKXU_cjs.VENDOR_VIEWER_ROLE_NAME];
|
|
11705
11710
|
if (viewerId) {
|
|
11706
11711
|
await em.query(`
|
|
11707
11712
|
UPDATE "vendor_users"
|
|
@@ -11727,7 +11732,7 @@ async function getDefaultStaffRoleIdForVendor(em, vendorId) {
|
|
|
11727
11732
|
LIMIT 1
|
|
11728
11733
|
`, [
|
|
11729
11734
|
vendorId,
|
|
11730
|
-
|
|
11735
|
+
chunkWMXPKKXU_cjs.VENDOR_VIEWER_ROLE_NAME
|
|
11731
11736
|
]);
|
|
11732
11737
|
const id = rows[0]?.id;
|
|
11733
11738
|
return id != null ? Number(id) : null;
|
|
@@ -11816,6 +11821,84 @@ function slugify(input) {
|
|
|
11816
11821
|
return input.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
11817
11822
|
}
|
|
11818
11823
|
chunkUSNT2KNT_cjs.__name(slugify, "slugify");
|
|
11824
|
+
function vendorOnboardErrorResponse(json, err) {
|
|
11825
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
11826
|
+
console.error("[vendor-onboard]", err);
|
|
11827
|
+
if (msg === "VENDOR_SLUG_EXISTS") {
|
|
11828
|
+
return json({
|
|
11829
|
+
error: "Vendor slug already exists"
|
|
11830
|
+
}, {
|
|
11831
|
+
status: 400
|
|
11832
|
+
});
|
|
11833
|
+
}
|
|
11834
|
+
if (msg === "USER_EMAIL_EXISTS") {
|
|
11835
|
+
return json({
|
|
11836
|
+
error: "User with this email already exists"
|
|
11837
|
+
}, {
|
|
11838
|
+
status: 400
|
|
11839
|
+
});
|
|
11840
|
+
}
|
|
11841
|
+
if (msg === "VENDOR_OWNER_GROUP_MISSING") {
|
|
11842
|
+
return json({
|
|
11843
|
+
error: "Vendor Owner group not found. Run migrations (VendorOwnerRbacSeed)."
|
|
11844
|
+
}, {
|
|
11845
|
+
status: 500
|
|
11846
|
+
});
|
|
11847
|
+
}
|
|
11848
|
+
if (msg === "VENDOR_ROLES_SEED_FAILED") {
|
|
11849
|
+
return json({
|
|
11850
|
+
error: "Failed to seed store roles for vendor. Run migrations."
|
|
11851
|
+
}, {
|
|
11852
|
+
status: 500
|
|
11853
|
+
});
|
|
11854
|
+
}
|
|
11855
|
+
if (/vendor_roles|vendor_role_permissions/i.test(msg)) {
|
|
11856
|
+
return json({
|
|
11857
|
+
error: "Vendor roles tables missing. Run migrations."
|
|
11858
|
+
}, {
|
|
11859
|
+
status: 500
|
|
11860
|
+
});
|
|
11861
|
+
}
|
|
11862
|
+
if (/relation .* does not exist|column .* does not exist/i.test(msg)) {
|
|
11863
|
+
return json({
|
|
11864
|
+
error: "Database schema is outdated on this environment. Run migrations.",
|
|
11865
|
+
detail: msg
|
|
11866
|
+
}, {
|
|
11867
|
+
status: 500
|
|
11868
|
+
});
|
|
11869
|
+
}
|
|
11870
|
+
if (/duplicate key|unique constraint/i.test(msg)) {
|
|
11871
|
+
if (/email/i.test(msg)) {
|
|
11872
|
+
return json({
|
|
11873
|
+
error: "A user or record with this email already exists",
|
|
11874
|
+
detail: msg
|
|
11875
|
+
}, {
|
|
11876
|
+
status: 409
|
|
11877
|
+
});
|
|
11878
|
+
}
|
|
11879
|
+
if (/slug/i.test(msg)) {
|
|
11880
|
+
return json({
|
|
11881
|
+
error: "Vendor slug already exists",
|
|
11882
|
+
detail: msg
|
|
11883
|
+
}, {
|
|
11884
|
+
status: 409
|
|
11885
|
+
});
|
|
11886
|
+
}
|
|
11887
|
+
return json({
|
|
11888
|
+
error: "Duplicate value conflicts with an existing record",
|
|
11889
|
+
detail: msg
|
|
11890
|
+
}, {
|
|
11891
|
+
status: 409
|
|
11892
|
+
});
|
|
11893
|
+
}
|
|
11894
|
+
return json({
|
|
11895
|
+
error: "Server error",
|
|
11896
|
+
detail: msg
|
|
11897
|
+
}, {
|
|
11898
|
+
status: 500
|
|
11899
|
+
});
|
|
11900
|
+
}
|
|
11901
|
+
chunkUSNT2KNT_cjs.__name(vendorOnboardErrorResponse, "vendorOnboardErrorResponse");
|
|
11819
11902
|
function createVendorOnboardHandlers(config) {
|
|
11820
11903
|
const { dataSource, entityMap, json, getSessionUser, baseUrl, getCms, hashPassword, minPasswordLength = 6 } = config;
|
|
11821
11904
|
async function gateAdmin() {
|
|
@@ -11825,7 +11908,7 @@ function createVendorOnboardHandlers(config) {
|
|
|
11825
11908
|
}, {
|
|
11826
11909
|
status: 401
|
|
11827
11910
|
});
|
|
11828
|
-
if (!
|
|
11911
|
+
if (!chunkWMXPKKXU_cjs.isPlatformAdministrator(u)) return json({
|
|
11829
11912
|
error: "Forbidden",
|
|
11830
11913
|
reason: "admin_only"
|
|
11831
11914
|
}, {
|
|
@@ -11835,7 +11918,7 @@ function createVendorOnboardHandlers(config) {
|
|
|
11835
11918
|
}
|
|
11836
11919
|
chunkUSNT2KNT_cjs.__name(gateAdmin, "gateAdmin");
|
|
11837
11920
|
async function resolveActiveVendorId(u) {
|
|
11838
|
-
const scope =
|
|
11921
|
+
const scope = chunkWMXPKKXU_cjs.resolveVendorScopeFromSessionUser(u);
|
|
11839
11922
|
if (scope.type === "vendor") return scope.vendorId;
|
|
11840
11923
|
if (scope.type === "all") {
|
|
11841
11924
|
const id = u.activeVendorId ?? u.vendorIds?.[0];
|
|
@@ -11851,7 +11934,7 @@ function createVendorOnboardHandlers(config) {
|
|
|
11851
11934
|
}, {
|
|
11852
11935
|
status: 401
|
|
11853
11936
|
});
|
|
11854
|
-
if (!
|
|
11937
|
+
if (!chunkWMXPKKXU_cjs.canManageVendorTeam(u)) return json({
|
|
11855
11938
|
error: "Forbidden"
|
|
11856
11939
|
}, {
|
|
11857
11940
|
status: 403
|
|
@@ -11984,12 +12067,28 @@ function createVendorOnboardHandlers(config) {
|
|
|
11984
12067
|
}
|
|
11985
12068
|
});
|
|
11986
12069
|
if (dupVendor) throw new Error("VENDOR_SLUG_EXISTS");
|
|
11987
|
-
|
|
12070
|
+
let ownerGroup = await groupRepo.findOne({
|
|
11988
12071
|
where: {
|
|
11989
|
-
name:
|
|
12072
|
+
name: chunkWMXPKKXU_cjs.VENDOR_OWNER_GROUP_NAME,
|
|
11990
12073
|
deleted: false
|
|
11991
12074
|
}
|
|
11992
12075
|
});
|
|
12076
|
+
if (!ownerGroup) {
|
|
12077
|
+
try {
|
|
12078
|
+
await groupRepo.save(groupRepo.create({
|
|
12079
|
+
name: chunkWMXPKKXU_cjs.VENDOR_OWNER_GROUP_NAME,
|
|
12080
|
+
deleted: false
|
|
12081
|
+
}));
|
|
12082
|
+
ownerGroup = await groupRepo.findOne({
|
|
12083
|
+
where: {
|
|
12084
|
+
name: chunkWMXPKKXU_cjs.VENDOR_OWNER_GROUP_NAME,
|
|
12085
|
+
deleted: false
|
|
12086
|
+
}
|
|
12087
|
+
});
|
|
12088
|
+
} catch (seedErr) {
|
|
12089
|
+
console.error("[vendor-onboard] failed to seed Vendor Owner group", seedErr);
|
|
12090
|
+
}
|
|
12091
|
+
}
|
|
11993
12092
|
if (!ownerGroup) throw new Error("VENDOR_OWNER_GROUP_MISSING");
|
|
11994
12093
|
const existingUser = await userRepo.findOne({
|
|
11995
12094
|
where: {
|
|
@@ -12078,14 +12177,18 @@ function createVendorOnboardHandlers(config) {
|
|
|
12078
12177
|
});
|
|
12079
12178
|
}
|
|
12080
12179
|
if (entityMap.customer) {
|
|
12081
|
-
|
|
12082
|
-
|
|
12083
|
-
|
|
12084
|
-
|
|
12085
|
-
|
|
12086
|
-
|
|
12087
|
-
|
|
12088
|
-
|
|
12180
|
+
try {
|
|
12181
|
+
await ensureCustomerForUser(em, entityMap.customer, {
|
|
12182
|
+
id: newUser.id,
|
|
12183
|
+
name: userName,
|
|
12184
|
+
email: userEmail,
|
|
12185
|
+
phone: trimOrNull(body.vendor?.phone) ?? ownerPhone
|
|
12186
|
+
}, {
|
|
12187
|
+
phone: trimOrNull(body.vendor?.phone) ?? ownerPhone
|
|
12188
|
+
});
|
|
12189
|
+
} catch (customerErr) {
|
|
12190
|
+
console.error("[vendor-onboard] ensureCustomerForUser skipped", customerErr);
|
|
12191
|
+
}
|
|
12089
12192
|
}
|
|
12090
12193
|
return {
|
|
12091
12194
|
vendor,
|
|
@@ -12135,46 +12238,7 @@ function createVendorOnboardHandlers(config) {
|
|
|
12135
12238
|
status: 201
|
|
12136
12239
|
});
|
|
12137
12240
|
} catch (e) {
|
|
12138
|
-
|
|
12139
|
-
if (process.env.NODE_ENV === "development") {
|
|
12140
|
-
console.error("[vendor-onboard]", e);
|
|
12141
|
-
}
|
|
12142
|
-
if (msg === "VENDOR_SLUG_EXISTS") return json({
|
|
12143
|
-
error: "Vendor slug already exists"
|
|
12144
|
-
}, {
|
|
12145
|
-
status: 400
|
|
12146
|
-
});
|
|
12147
|
-
if (msg === "USER_EMAIL_EXISTS") return json({
|
|
12148
|
-
error: "User with this email already exists"
|
|
12149
|
-
}, {
|
|
12150
|
-
status: 400
|
|
12151
|
-
});
|
|
12152
|
-
if (msg === "VENDOR_OWNER_GROUP_MISSING") {
|
|
12153
|
-
return json({
|
|
12154
|
-
error: "Vendor Owner group not found. Run migrations."
|
|
12155
|
-
}, {
|
|
12156
|
-
status: 500
|
|
12157
|
-
});
|
|
12158
|
-
}
|
|
12159
|
-
if (msg === "VENDOR_ROLES_SEED_FAILED") {
|
|
12160
|
-
return json({
|
|
12161
|
-
error: "Failed to seed store roles for vendor. Run migrations."
|
|
12162
|
-
}, {
|
|
12163
|
-
status: 500
|
|
12164
|
-
});
|
|
12165
|
-
}
|
|
12166
|
-
if (/vendor_roles|vendor_role_permissions/i.test(msg)) {
|
|
12167
|
-
return json({
|
|
12168
|
-
error: "Vendor roles tables missing. Run migrations."
|
|
12169
|
-
}, {
|
|
12170
|
-
status: 500
|
|
12171
|
-
});
|
|
12172
|
-
}
|
|
12173
|
-
return json({
|
|
12174
|
-
error: "Server error"
|
|
12175
|
-
}, {
|
|
12176
|
-
status: 500
|
|
12177
|
-
});
|
|
12241
|
+
return vendorOnboardErrorResponse(json, e);
|
|
12178
12242
|
}
|
|
12179
12243
|
},
|
|
12180
12244
|
/** POST /api/admin/vendor/switch — set active vendor in session (JWT update via client) */
|
|
@@ -12368,7 +12432,7 @@ function createVendorOnboardHandlers(config) {
|
|
|
12368
12432
|
if (!groupId) {
|
|
12369
12433
|
const g = await groupRepo.findOne({
|
|
12370
12434
|
where: {
|
|
12371
|
-
name:
|
|
12435
|
+
name: chunkWMXPKKXU_cjs.VENDOR_OWNER_GROUP_NAME,
|
|
12372
12436
|
deleted: false
|
|
12373
12437
|
}
|
|
12374
12438
|
});
|
|
@@ -12678,10 +12742,10 @@ chunkUSNT2KNT_cjs.__name(createVendorOnboardHandlers, "createVendorOnboardHandle
|
|
|
12678
12742
|
function createVendorRolesHandlers(config) {
|
|
12679
12743
|
const { dataSource, entityMap, json, getSessionUser } = config;
|
|
12680
12744
|
const vendorRoleEntities = [
|
|
12681
|
-
...
|
|
12745
|
+
...chunkWMXPKKXU_cjs.VENDOR_RBAC_ENTITIES
|
|
12682
12746
|
].sort();
|
|
12683
12747
|
async function resolveActiveVendorId(u) {
|
|
12684
|
-
const scope =
|
|
12748
|
+
const scope = chunkWMXPKKXU_cjs.resolveVendorScopeFromSessionUser(u);
|
|
12685
12749
|
if (scope.type === "vendor") return scope.vendorId;
|
|
12686
12750
|
if (scope.type === "all") {
|
|
12687
12751
|
const id = u.activeVendorId ?? u.vendorIds?.[0];
|
|
@@ -12697,7 +12761,7 @@ function createVendorRolesHandlers(config) {
|
|
|
12697
12761
|
}, {
|
|
12698
12762
|
status: 401
|
|
12699
12763
|
});
|
|
12700
|
-
if (!
|
|
12764
|
+
if (!chunkWMXPKKXU_cjs.canManageVendorRoles(u)) return json({
|
|
12701
12765
|
error: "Forbidden"
|
|
12702
12766
|
}, {
|
|
12703
12767
|
status: 403
|
|
@@ -20855,6 +20919,8 @@ exports.Combo = class Combo {
|
|
|
20855
20919
|
chunkUSNT2KNT_cjs.__name(this, "Combo");
|
|
20856
20920
|
}
|
|
20857
20921
|
id;
|
|
20922
|
+
vendorId;
|
|
20923
|
+
vendor;
|
|
20858
20924
|
name;
|
|
20859
20925
|
desc;
|
|
20860
20926
|
eventId;
|
|
@@ -20880,6 +20946,19 @@ _ts_decorate63([
|
|
|
20880
20946
|
typeorm.PrimaryGeneratedColumn(),
|
|
20881
20947
|
_ts_metadata63("design:type", Number)
|
|
20882
20948
|
], exports.Combo.prototype, "id", void 0);
|
|
20949
|
+
_ts_decorate63([
|
|
20950
|
+
typeorm.Column("int"),
|
|
20951
|
+
_ts_metadata63("design:type", Number)
|
|
20952
|
+
], exports.Combo.prototype, "vendorId", void 0);
|
|
20953
|
+
_ts_decorate63([
|
|
20954
|
+
typeorm.ManyToOne(() => exports.Vendor, {
|
|
20955
|
+
onDelete: "RESTRICT"
|
|
20956
|
+
}),
|
|
20957
|
+
typeorm.JoinColumn({
|
|
20958
|
+
name: "vendorId"
|
|
20959
|
+
}),
|
|
20960
|
+
_ts_metadata63("design:type", typeof exports.Vendor === "undefined" ? Object : exports.Vendor)
|
|
20961
|
+
], exports.Combo.prototype, "vendor", void 0);
|
|
20883
20962
|
_ts_decorate63([
|
|
20884
20963
|
typeorm.Column({
|
|
20885
20964
|
type: "varchar"
|
|
@@ -21224,12 +21303,18 @@ function _ts_metadata66(k, v) {
|
|
|
21224
21303
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
21225
21304
|
}
|
|
21226
21305
|
chunkUSNT2KNT_cjs.__name(_ts_metadata66, "_ts_metadata");
|
|
21227
|
-
|
|
21306
|
+
var NotificationChannel = /* @__PURE__ */ (function(NotificationChannel2) {
|
|
21307
|
+
NotificationChannel2["WHATSAPP"] = "whatsapp";
|
|
21308
|
+
NotificationChannel2["EMAIL"] = "email";
|
|
21309
|
+
return NotificationChannel2;
|
|
21310
|
+
})({});
|
|
21311
|
+
exports.OrderNotificationBinding = class OrderNotificationBinding {
|
|
21228
21312
|
static {
|
|
21229
|
-
chunkUSNT2KNT_cjs.__name(this, "
|
|
21313
|
+
chunkUSNT2KNT_cjs.__name(this, "OrderNotificationBinding");
|
|
21230
21314
|
}
|
|
21231
21315
|
id;
|
|
21232
21316
|
triggerKey;
|
|
21317
|
+
channel;
|
|
21233
21318
|
messageTemplateId;
|
|
21234
21319
|
enabled;
|
|
21235
21320
|
createdAt;
|
|
@@ -21238,39 +21323,52 @@ exports.WhatsappTriggerBinding = class WhatsappTriggerBinding {
|
|
|
21238
21323
|
_ts_decorate66([
|
|
21239
21324
|
typeorm.PrimaryGeneratedColumn(),
|
|
21240
21325
|
_ts_metadata66("design:type", Number)
|
|
21241
|
-
], exports.
|
|
21326
|
+
], exports.OrderNotificationBinding.prototype, "id", void 0);
|
|
21242
21327
|
_ts_decorate66([
|
|
21243
21328
|
typeorm.Column({
|
|
21244
|
-
type: "varchar"
|
|
21245
|
-
unique: true
|
|
21329
|
+
type: "varchar"
|
|
21246
21330
|
}),
|
|
21247
21331
|
_ts_metadata66("design:type", String)
|
|
21248
|
-
], exports.
|
|
21332
|
+
], exports.OrderNotificationBinding.prototype, "triggerKey", void 0);
|
|
21333
|
+
_ts_decorate66([
|
|
21334
|
+
typeorm.Column({
|
|
21335
|
+
type: "enum",
|
|
21336
|
+
enum: NotificationChannel,
|
|
21337
|
+
default: "whatsapp"
|
|
21338
|
+
}),
|
|
21339
|
+
_ts_metadata66("design:type", String)
|
|
21340
|
+
], exports.OrderNotificationBinding.prototype, "channel", void 0);
|
|
21249
21341
|
_ts_decorate66([
|
|
21250
21342
|
typeorm.Column({
|
|
21251
21343
|
type: "int",
|
|
21252
21344
|
nullable: true
|
|
21253
21345
|
}),
|
|
21254
21346
|
_ts_metadata66("design:type", Object)
|
|
21255
|
-
], exports.
|
|
21347
|
+
], exports.OrderNotificationBinding.prototype, "messageTemplateId", void 0);
|
|
21256
21348
|
_ts_decorate66([
|
|
21257
21349
|
typeorm.Column({
|
|
21258
21350
|
type: "boolean",
|
|
21259
21351
|
default: true
|
|
21260
21352
|
}),
|
|
21261
21353
|
_ts_metadata66("design:type", Boolean)
|
|
21262
|
-
], exports.
|
|
21354
|
+
], exports.OrderNotificationBinding.prototype, "enabled", void 0);
|
|
21263
21355
|
_ts_decorate66([
|
|
21264
21356
|
typeorm.CreateDateColumn(),
|
|
21265
21357
|
_ts_metadata66("design:type", typeof Date === "undefined" ? Object : Date)
|
|
21266
|
-
], exports.
|
|
21358
|
+
], exports.OrderNotificationBinding.prototype, "createdAt", void 0);
|
|
21267
21359
|
_ts_decorate66([
|
|
21268
21360
|
typeorm.UpdateDateColumn(),
|
|
21269
21361
|
_ts_metadata66("design:type", typeof Date === "undefined" ? Object : Date)
|
|
21270
|
-
], exports.
|
|
21271
|
-
exports.
|
|
21272
|
-
typeorm.Entity("
|
|
21273
|
-
|
|
21362
|
+
], exports.OrderNotificationBinding.prototype, "updatedAt", void 0);
|
|
21363
|
+
exports.OrderNotificationBinding = _ts_decorate66([
|
|
21364
|
+
typeorm.Entity("order_notification_bindings"),
|
|
21365
|
+
typeorm.Index([
|
|
21366
|
+
"triggerKey",
|
|
21367
|
+
"channel"
|
|
21368
|
+
], {
|
|
21369
|
+
unique: true
|
|
21370
|
+
})
|
|
21371
|
+
], exports.OrderNotificationBinding);
|
|
21274
21372
|
function _ts_decorate67(decorators, target, key, desc) {
|
|
21275
21373
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
21276
21374
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -21420,7 +21518,7 @@ var CMS_ENTITY_MAP = {
|
|
|
21420
21518
|
refund_policies: exports.RefundPolicy,
|
|
21421
21519
|
refund_requests: exports.RefundRequest,
|
|
21422
21520
|
attendees: exports.Attendee,
|
|
21423
|
-
|
|
21521
|
+
order_notification_bindings: exports.OrderNotificationBinding,
|
|
21424
21522
|
order_notification_triggers: exports.OrderNotificationTrigger
|
|
21425
21523
|
};
|
|
21426
21524
|
|
|
@@ -24523,6 +24621,173 @@ function createWhatsappMessageTemplatesHandlers(config) {
|
|
|
24523
24621
|
};
|
|
24524
24622
|
}
|
|
24525
24623
|
chunkUSNT2KNT_cjs.__name(createWhatsappMessageTemplatesHandlers, "createWhatsappMessageTemplatesHandlers");
|
|
24624
|
+
|
|
24625
|
+
// src/api/email-message-templates-handlers.ts
|
|
24626
|
+
function slugify2(input) {
|
|
24627
|
+
return input.toLowerCase().trim().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 64) || "template";
|
|
24628
|
+
}
|
|
24629
|
+
chunkUSNT2KNT_cjs.__name(slugify2, "slugify");
|
|
24630
|
+
function createEmailMessageTemplatesHandlers(config) {
|
|
24631
|
+
const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;
|
|
24632
|
+
const templateRepo = /* @__PURE__ */ chunkUSNT2KNT_cjs.__name(() => dataSource.getRepository(entityMap.message_templates), "templateRepo");
|
|
24633
|
+
async function requireRead(req, entity) {
|
|
24634
|
+
const a = await requireAuth(req);
|
|
24635
|
+
if (a) return a;
|
|
24636
|
+
if (requireEntityPermission) {
|
|
24637
|
+
const pe = await requireEntityPermission(req, entity, "read");
|
|
24638
|
+
if (pe) return pe;
|
|
24639
|
+
}
|
|
24640
|
+
return null;
|
|
24641
|
+
}
|
|
24642
|
+
chunkUSNT2KNT_cjs.__name(requireRead, "requireRead");
|
|
24643
|
+
async function requireUpdate(req, entity) {
|
|
24644
|
+
const a = await requireAuth(req);
|
|
24645
|
+
if (a) return a;
|
|
24646
|
+
if (requireEntityPermission) {
|
|
24647
|
+
const pe = await requireEntityPermission(req, entity, "update");
|
|
24648
|
+
if (pe) return pe;
|
|
24649
|
+
}
|
|
24650
|
+
return null;
|
|
24651
|
+
}
|
|
24652
|
+
chunkUSNT2KNT_cjs.__name(requireUpdate, "requireUpdate");
|
|
24653
|
+
return {
|
|
24654
|
+
async listCached(req) {
|
|
24655
|
+
const err = await requireRead(req, "settings");
|
|
24656
|
+
if (err) return err;
|
|
24657
|
+
try {
|
|
24658
|
+
const rows = await templateRepo().find({
|
|
24659
|
+
where: {
|
|
24660
|
+
channel: "email",
|
|
24661
|
+
deleted: false
|
|
24662
|
+
},
|
|
24663
|
+
order: {
|
|
24664
|
+
name: "ASC"
|
|
24665
|
+
}
|
|
24666
|
+
});
|
|
24667
|
+
return json({
|
|
24668
|
+
items: rows
|
|
24669
|
+
});
|
|
24670
|
+
} catch {
|
|
24671
|
+
return json({
|
|
24672
|
+
error: "Failed to load templates"
|
|
24673
|
+
}, {
|
|
24674
|
+
status: 500
|
|
24675
|
+
});
|
|
24676
|
+
}
|
|
24677
|
+
},
|
|
24678
|
+
async create(req) {
|
|
24679
|
+
const err = await requireUpdate(req, "settings");
|
|
24680
|
+
if (err) return err;
|
|
24681
|
+
let body;
|
|
24682
|
+
try {
|
|
24683
|
+
body = await req.json();
|
|
24684
|
+
} catch {
|
|
24685
|
+
return json({
|
|
24686
|
+
error: "Invalid JSON body"
|
|
24687
|
+
}, {
|
|
24688
|
+
status: 400
|
|
24689
|
+
});
|
|
24690
|
+
}
|
|
24691
|
+
const name = typeof body.name === "string" ? body.name.trim() : "";
|
|
24692
|
+
const subject = typeof body.subject === "string" ? body.subject : "";
|
|
24693
|
+
const bodyText = typeof body.body === "string" ? body.body : "";
|
|
24694
|
+
if (!name) return json({
|
|
24695
|
+
error: "name is required"
|
|
24696
|
+
}, {
|
|
24697
|
+
status: 400
|
|
24698
|
+
});
|
|
24699
|
+
if (!bodyText.trim()) return json({
|
|
24700
|
+
error: "body is required"
|
|
24701
|
+
}, {
|
|
24702
|
+
status: 400
|
|
24703
|
+
});
|
|
24704
|
+
const baseKey = slugify2(name);
|
|
24705
|
+
let templateKey = baseKey;
|
|
24706
|
+
let suffix = 1;
|
|
24707
|
+
while (await templateRepo().findOne({
|
|
24708
|
+
where: {
|
|
24709
|
+
channel: "email",
|
|
24710
|
+
templateKey,
|
|
24711
|
+
deleted: false
|
|
24712
|
+
}
|
|
24713
|
+
})) {
|
|
24714
|
+
suffix += 1;
|
|
24715
|
+
templateKey = `${baseKey}_${suffix}`;
|
|
24716
|
+
}
|
|
24717
|
+
const row = await templateRepo().save(templateRepo().create({
|
|
24718
|
+
channel: "email",
|
|
24719
|
+
templateKey,
|
|
24720
|
+
name,
|
|
24721
|
+
subject,
|
|
24722
|
+
body: bodyText,
|
|
24723
|
+
externalTemplateRef: null,
|
|
24724
|
+
providerMeta: null,
|
|
24725
|
+
enabled: true,
|
|
24726
|
+
deleted: false
|
|
24727
|
+
}));
|
|
24728
|
+
return json({
|
|
24729
|
+
item: row
|
|
24730
|
+
}, {
|
|
24731
|
+
status: 201
|
|
24732
|
+
});
|
|
24733
|
+
},
|
|
24734
|
+
async update(req, id) {
|
|
24735
|
+
const err = await requireUpdate(req, "settings");
|
|
24736
|
+
if (err) return err;
|
|
24737
|
+
const numId = Number(id);
|
|
24738
|
+
if (!Number.isFinite(numId)) return json({
|
|
24739
|
+
error: "Invalid id"
|
|
24740
|
+
}, {
|
|
24741
|
+
status: 400
|
|
24742
|
+
});
|
|
24743
|
+
let body;
|
|
24744
|
+
try {
|
|
24745
|
+
body = await req.json();
|
|
24746
|
+
} catch {
|
|
24747
|
+
return json({
|
|
24748
|
+
error: "Invalid JSON body"
|
|
24749
|
+
}, {
|
|
24750
|
+
status: 400
|
|
24751
|
+
});
|
|
24752
|
+
}
|
|
24753
|
+
const existing = await templateRepo().findOne({
|
|
24754
|
+
where: {
|
|
24755
|
+
id: numId,
|
|
24756
|
+
channel: "email",
|
|
24757
|
+
deleted: false
|
|
24758
|
+
}
|
|
24759
|
+
});
|
|
24760
|
+
if (!existing) return json({
|
|
24761
|
+
error: "Template not found"
|
|
24762
|
+
}, {
|
|
24763
|
+
status: 404
|
|
24764
|
+
});
|
|
24765
|
+
const patch = {
|
|
24766
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
24767
|
+
};
|
|
24768
|
+
if (typeof body.name === "string" && body.name.trim()) patch.name = body.name.trim();
|
|
24769
|
+
if (typeof body.subject === "string") patch.subject = body.subject;
|
|
24770
|
+
if (typeof body.body === "string") {
|
|
24771
|
+
if (!body.body.trim()) return json({
|
|
24772
|
+
error: "body cannot be empty"
|
|
24773
|
+
}, {
|
|
24774
|
+
status: 400
|
|
24775
|
+
});
|
|
24776
|
+
patch.body = body.body;
|
|
24777
|
+
}
|
|
24778
|
+
await templateRepo().update(numId, patch);
|
|
24779
|
+
const updated = await templateRepo().findOne({
|
|
24780
|
+
where: {
|
|
24781
|
+
id: numId
|
|
24782
|
+
}
|
|
24783
|
+
});
|
|
24784
|
+
return json({
|
|
24785
|
+
item: updated
|
|
24786
|
+
});
|
|
24787
|
+
}
|
|
24788
|
+
};
|
|
24789
|
+
}
|
|
24790
|
+
chunkUSNT2KNT_cjs.__name(createEmailMessageTemplatesHandlers, "createEmailMessageTemplatesHandlers");
|
|
24526
24791
|
function connectionFromUrl(redisUrl) {
|
|
24527
24792
|
const u = new URL(redisUrl);
|
|
24528
24793
|
return {
|
|
@@ -24680,16 +24945,16 @@ function whatsappPlugin(config = {}) {
|
|
|
24680
24945
|
db = await getWhatsAppSettings?.() ?? {};
|
|
24681
24946
|
} catch {
|
|
24682
24947
|
}
|
|
24683
|
-
if (!
|
|
24948
|
+
if (!chunk22FFHLTO_cjs.isWhatsAppPluginEnabled(db)) {
|
|
24684
24949
|
context.logger.warn("WhatsApp plugin skipped: disabled in Plugins \u2192 WhatsApp");
|
|
24685
24950
|
return null;
|
|
24686
24951
|
}
|
|
24687
|
-
const merged =
|
|
24688
|
-
if (!getWhatsAppSettings && !
|
|
24952
|
+
const merged = chunk22FFHLTO_cjs.mergeWhatsAppConfigLayers(env, db, staticRest);
|
|
24953
|
+
if (!getWhatsAppSettings && !chunk22FFHLTO_cjs.whatsAppConfigured(merged)) {
|
|
24689
24954
|
context.logger.warn("WhatsApp plugin skipped: set WHATSAPP_ACCESS_TOKEN and WHATSAPP_PHONE_NUMBER_ID, or pass getWhatsAppSettings");
|
|
24690
24955
|
return null;
|
|
24691
24956
|
}
|
|
24692
|
-
const svc = new
|
|
24957
|
+
const svc = new chunk22FFHLTO_cjs.WhatsAppService(env, staticRest, getWhatsAppSettings, getMessageTemplateRow);
|
|
24693
24958
|
return {
|
|
24694
24959
|
send: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((opts) => svc.send(opts), "send")
|
|
24695
24960
|
};
|
|
@@ -24763,7 +25028,7 @@ function createMessageTemplateRowLoader(dataSource, entityMap) {
|
|
|
24763
25028
|
chunkUSNT2KNT_cjs.__name(createMessageTemplateRowLoader, "createMessageTemplateRowLoader");
|
|
24764
25029
|
function registerMessagingQueueProcessors(cms) {
|
|
24765
25030
|
chunkXW5ATPRW_cjs.registerEmailQueueProcessor(cms);
|
|
24766
|
-
|
|
25031
|
+
chunk22FFHLTO_cjs.registerWhatsAppQueueProcessor(cms);
|
|
24767
25032
|
}
|
|
24768
25033
|
chunkUSNT2KNT_cjs.__name(registerMessagingQueueProcessors, "registerMessagingQueueProcessors");
|
|
24769
25034
|
async function ensureMessagingPluginsOnCms(base, options) {
|
|
@@ -24792,7 +25057,7 @@ async function ensureMessagingPluginsOnCms(base, options) {
|
|
|
24792
25057
|
}
|
|
24793
25058
|
if (!cms.getPlugin("email")) {
|
|
24794
25059
|
try {
|
|
24795
|
-
const instance = await
|
|
25060
|
+
const instance = await chunk22FFHLTO_cjs.emailPlugin({
|
|
24796
25061
|
type: "SMTP",
|
|
24797
25062
|
from: config.SMTP_FROM ?? "no-reply@localhost",
|
|
24798
25063
|
to: config.SMTP_TO ?? ""
|
|
@@ -24833,7 +25098,7 @@ function messagingPlugins(options) {
|
|
|
24833
25098
|
const config = options.config ?? (typeof process !== "undefined" ? process.env : {});
|
|
24834
25099
|
return [
|
|
24835
25100
|
queuePlugin(),
|
|
24836
|
-
|
|
25101
|
+
chunk22FFHLTO_cjs.emailPlugin({
|
|
24837
25102
|
type: "SMTP",
|
|
24838
25103
|
from: config.SMTP_FROM ?? "no-reply@localhost",
|
|
24839
25104
|
to: config.SMTP_TO ?? ""
|
|
@@ -24880,7 +25145,7 @@ function withLlmKnowledgeEntityFallbacks(base) {
|
|
|
24880
25145
|
"rss_feeds",
|
|
24881
25146
|
"rss_articles",
|
|
24882
25147
|
"order_notification_triggers",
|
|
24883
|
-
"
|
|
25148
|
+
"order_notification_bindings",
|
|
24884
25149
|
"message_templates"
|
|
24885
25150
|
];
|
|
24886
25151
|
const patch = {};
|
|
@@ -24967,7 +25232,7 @@ function createCmsApiHandler(config) {
|
|
|
24967
25232
|
} : void 0;
|
|
24968
25233
|
const entityMap = withLlmKnowledgeEntityFallbacks(rawEntityMap);
|
|
24969
25234
|
if (getCms) {
|
|
24970
|
-
|
|
25235
|
+
chunk22FFHLTO_cjs.initWhatsappTriggerDispatcher({
|
|
24971
25236
|
dataSource,
|
|
24972
25237
|
entityMap,
|
|
24973
25238
|
getCms
|
|
@@ -24980,7 +25245,7 @@ function createCmsApiHandler(config) {
|
|
|
24980
25245
|
] : baseCrudResources;
|
|
24981
25246
|
const requireEntityPermissionEffective = /* @__PURE__ */ chunkUSNT2KNT_cjs.__name(async (_req, entity, action) => {
|
|
24982
25247
|
if (!resolveSessionUser) {
|
|
24983
|
-
|
|
25248
|
+
chunkWMXPKKXU_cjs.logRbac("requireEntityPermission: getSessionUser not passed \u2014 vendor store APIs may 403", {
|
|
24984
25249
|
entity,
|
|
24985
25250
|
action,
|
|
24986
25251
|
hint: "Pass getSessionUser: auth.getAuthenticatedUser from createCmsAuthBundle()"
|
|
@@ -24990,7 +25255,7 @@ function createCmsApiHandler(config) {
|
|
|
24990
25255
|
const raw = await resolveSessionUser();
|
|
24991
25256
|
const u = await hydrateVendorSessionUser(dataSource, raw);
|
|
24992
25257
|
if (!u?.email) {
|
|
24993
|
-
|
|
25258
|
+
chunkWMXPKKXU_cjs.logRbac("requireEntityPermission: no session user", {
|
|
24994
25259
|
entity,
|
|
24995
25260
|
action
|
|
24996
25261
|
});
|
|
@@ -25000,13 +25265,13 @@ function createCmsApiHandler(config) {
|
|
|
25000
25265
|
status: 401
|
|
25001
25266
|
});
|
|
25002
25267
|
}
|
|
25003
|
-
const allowed =
|
|
25004
|
-
await
|
|
25268
|
+
const allowed = chunkOIGCAGH7_cjs.sessionHasEntityAccess(u, entity, action);
|
|
25269
|
+
await chunkWMXPKKXU_cjs.logEntityAccessDecision(dataSource, "cmsApi.requireEntityPermission", u, entity, action, {
|
|
25005
25270
|
allowed,
|
|
25006
25271
|
resolvePath: "hydrated_session"
|
|
25007
25272
|
});
|
|
25008
25273
|
if (allowed) return null;
|
|
25009
|
-
const { reason } =
|
|
25274
|
+
const { reason } = chunkWMXPKKXU_cjs.explainSessionEntityAccess(u, entity, action);
|
|
25010
25275
|
return config.json({
|
|
25011
25276
|
error: "Forbidden",
|
|
25012
25277
|
entity,
|
|
@@ -25017,7 +25282,7 @@ function createCmsApiHandler(config) {
|
|
|
25017
25282
|
});
|
|
25018
25283
|
}
|
|
25019
25284
|
if (userRequireEntityPermission) {
|
|
25020
|
-
|
|
25285
|
+
chunkWMXPKKXU_cjs.logRbac("requireEntityPermission: using app callback only (no getSessionUser)", {
|
|
25021
25286
|
entity,
|
|
25022
25287
|
action
|
|
25023
25288
|
});
|
|
@@ -25104,10 +25369,10 @@ function createCmsApiHandler(config) {
|
|
|
25104
25369
|
getVendorScope: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name(async () => {
|
|
25105
25370
|
const multiVendorEnabled = await checkMultiVendorEnabled(dataSource);
|
|
25106
25371
|
if (!multiVendorEnabled) {
|
|
25107
|
-
return
|
|
25372
|
+
return chunkWMXPKKXU_cjs.resolveDisabledMultiVendorScope(dataSource);
|
|
25108
25373
|
}
|
|
25109
25374
|
const u = await hydrateVendorSessionUser(dataSource, await resolveSessionUser());
|
|
25110
|
-
return
|
|
25375
|
+
return chunkWMXPKKXU_cjs.resolveVendorScopeFromSessionUser(u ?? null);
|
|
25111
25376
|
}, "getVendorScope"),
|
|
25112
25377
|
getHydratedSessionUser: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name(async () => {
|
|
25113
25378
|
const u = await hydrateVendorSessionUser(dataSource, await resolveSessionUser());
|
|
@@ -25238,6 +25503,13 @@ function createCmsApiHandler(config) {
|
|
|
25238
25503
|
requireEntityPermission: requireEntityPermissionEffective,
|
|
25239
25504
|
settingsEncryptionKey: settingsConfig?.encryptionKey
|
|
25240
25505
|
});
|
|
25506
|
+
const emailMessageTemplatesHandlers = createEmailMessageTemplatesHandlers({
|
|
25507
|
+
dataSource,
|
|
25508
|
+
entityMap,
|
|
25509
|
+
json: config.json,
|
|
25510
|
+
requireAuth: config.requireAuth,
|
|
25511
|
+
requireEntityPermission: requireEntityPermissionEffective
|
|
25512
|
+
});
|
|
25241
25513
|
const chatHandlers = chatConfig ? createChatHandlers(chatConfig) : null;
|
|
25242
25514
|
const llmAgentKnowledgeMerged = llmAgentKnowledgeConfig ?? (chatConfig ? {
|
|
25243
25515
|
dataSource: chatConfig.dataSource,
|
|
@@ -26210,6 +26482,13 @@ function createCmsApiHandler(config) {
|
|
|
26210
26482
|
if (path2[0] === "message-templates" && path2[1] === "whatsapp" && path2.length === 3 && path2[2] !== "sync") {
|
|
26211
26483
|
if (m === "PATCH") return whatsappMessageTemplatesHandlers.setParamOrder(req, path2[2]);
|
|
26212
26484
|
}
|
|
26485
|
+
if (path2[0] === "message-templates" && path2[1] === "email" && path2.length === 2) {
|
|
26486
|
+
if (m === "GET") return emailMessageTemplatesHandlers.listCached(req);
|
|
26487
|
+
if (m === "POST") return emailMessageTemplatesHandlers.create(req);
|
|
26488
|
+
}
|
|
26489
|
+
if (path2[0] === "message-templates" && path2[1] === "email" && path2.length === 3) {
|
|
26490
|
+
if (m === "PATCH") return emailMessageTemplatesHandlers.update(req, path2[2]);
|
|
26491
|
+
}
|
|
26213
26492
|
if (path2[0] === "llm_agents") {
|
|
26214
26493
|
if (!entityMap.llm_agents) {
|
|
26215
26494
|
console.error(CMS_API_LOG, "llm_agents route: entity missing after merge", {
|
|
@@ -26338,7 +26617,7 @@ function createCmsApiHandler(config) {
|
|
|
26338
26617
|
let vendorId = null;
|
|
26339
26618
|
if (resolveSessionUser) {
|
|
26340
26619
|
const u = await hydrateVendorSessionUser(dataSource, await resolveSessionUser());
|
|
26341
|
-
const scope =
|
|
26620
|
+
const scope = chunkWMXPKKXU_cjs.resolveVendorScopeFromSessionUser(u ?? null);
|
|
26342
26621
|
if (scope.type === "vendor") vendorId = scope.vendorId;
|
|
26343
26622
|
}
|
|
26344
26623
|
const result = await validateCoupon(dataSource, entityMap, couponCode, orderLinesNorm, currency, contactId, isAutomatic, discountId ?? void 0, vendorId);
|
|
@@ -26418,7 +26697,7 @@ function createCmsApiHandler(config) {
|
|
|
26418
26697
|
let vendorId = null;
|
|
26419
26698
|
if (resolveSessionUser) {
|
|
26420
26699
|
const u = await hydrateVendorSessionUser(dataSource, await resolveSessionUser());
|
|
26421
|
-
const scope =
|
|
26700
|
+
const scope = chunkWMXPKKXU_cjs.resolveVendorScopeFromSessionUser(u ?? null);
|
|
26422
26701
|
if (scope.type === "vendor") vendorId = scope.vendorId;
|
|
26423
26702
|
}
|
|
26424
26703
|
const orderLinesNorm = normalizeOrderLinesInput(body?.orderLines);
|
|
@@ -26624,7 +26903,7 @@ function createCmsApiHandler(config) {
|
|
|
26624
26903
|
status: 400
|
|
26625
26904
|
});
|
|
26626
26905
|
}
|
|
26627
|
-
const { resendOrderNotification } = await import('./
|
|
26906
|
+
const { resendOrderNotification } = await import('./order-notification-dispatcher-RU7BTGGX.cjs');
|
|
26628
26907
|
const result = await resendOrderNotification(triggerKey, orderId, {
|
|
26629
26908
|
dataSource,
|
|
26630
26909
|
entityMap,
|
|
@@ -27032,7 +27311,7 @@ function createCmsApiHandler(config) {
|
|
|
27032
27311
|
if (resolveSessionUser) {
|
|
27033
27312
|
const raw = await resolveSessionUser();
|
|
27034
27313
|
const u = await hydrateVendorSessionUser(dataSource, raw);
|
|
27035
|
-
const scope =
|
|
27314
|
+
const scope = chunkWMXPKKXU_cjs.resolveVendorScopeFromSessionUser(u ?? null);
|
|
27036
27315
|
if (scope.type === "vendor") {
|
|
27037
27316
|
scopedVendorIds = scope.vendorIds;
|
|
27038
27317
|
}
|