@ductape/sdk 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/apps/services/app.service.js +14 -5
  2. package/dist/apps/services/app.service.js.map +1 -1
  3. package/dist/apps/utils/string.utils.d.ts +7 -0
  4. package/dist/apps/utils/string.utils.js +33 -1
  5. package/dist/apps/utils/string.utils.js.map +1 -1
  6. package/dist/apps/validators/joi-validators/create.appEnv.validator.js +1 -0
  7. package/dist/apps/validators/joi-validators/create.appEnv.validator.js.map +1 -1
  8. package/dist/apps/validators/joi-validators/update.appEnv.validator.js +1 -0
  9. package/dist/apps/validators/joi-validators/update.appEnv.validator.js.map +1 -1
  10. package/dist/brokers/brokers.service.d.ts +4 -1
  11. package/dist/brokers/brokers.service.js +104 -20
  12. package/dist/brokers/brokers.service.js.map +1 -1
  13. package/dist/database/databases.service.d.ts +15 -0
  14. package/dist/database/databases.service.js +183 -14
  15. package/dist/database/databases.service.js.map +1 -1
  16. package/dist/graph/graphs.service.d.ts +6 -0
  17. package/dist/graph/graphs.service.js +155 -35
  18. package/dist/graph/graphs.service.js.map +1 -1
  19. package/dist/index.d.ts +28 -10
  20. package/dist/index.js +88 -10
  21. package/dist/index.js.map +1 -1
  22. package/dist/processor/services/processor.service.d.ts +15 -2
  23. package/dist/processor/services/processor.service.js +246 -28
  24. package/dist/processor/services/processor.service.js.map +1 -1
  25. package/dist/products/services/products.service.js +23 -24
  26. package/dist/products/services/products.service.js.map +1 -1
  27. package/dist/types/appBuilder.types.d.ts +6 -0
  28. package/dist/vector/vector-database.service.d.ts +6 -0
  29. package/dist/vector/vector-database.service.js +138 -31
  30. package/dist/vector/vector-database.service.js.map +1 -1
  31. package/dist/workflows/workflow-executor.js +99 -44
  32. package/dist/workflows/workflow-executor.js.map +1 -1
  33. package/dist/workflows/workflows.service.js +63 -20
  34. package/dist/workflows/workflows.service.js.map +1 -1
  35. package/package.json +1 -1
@@ -73,6 +73,7 @@ const app_service_1 = __importDefault(require("../../apps/services/app.service")
73
73
  const utils_1 = require("../../apps/utils");
74
74
  const credential_manager_1 = require("../../apps/utils/credential-manager");
75
75
  const oauth_manager_1 = require("../../apps/utils/oauth-manager");
76
+ const string_utils_2 = require("../../apps/utils/string.utils");
76
77
  const secrets_1 = require("../../secrets");
77
78
  async function loadBrokerService() {
78
79
  if (typeof window === 'undefined') {
@@ -91,16 +92,37 @@ async function loadJWT() {
91
92
  /** Only log when DUCTAPE_DEBUG is set to avoid sync I/O and serialization cost in hot path */
92
93
  const _processorDebug = typeof process !== 'undefined' && (((_a = process.env) === null || _a === void 0 ? void 0 : _a.DUCTAPE_DEBUG) === 'true' || ((_b = process.env) === null || _b === void 0 ? void 0 : _b.DUCTAPE_DEBUG) === '1');
93
94
  const debugLog = _processorDebug ? (...args) => console.log(...args) : () => { };
95
+ /** Shared mail (SMTP) transporters: one per workspace+product+poolKey. Not exported. */
96
+ const sharedMailRegistry = new Map();
97
+ const sharedMailInFlight = new Map();
98
+ function getSharedMailKey(workspaceId, product, poolKey) {
99
+ return `mail:${workspaceId}:${product}:${poolKey}`;
100
+ }
101
+ /** Shared Firebase apps: one per workspace+product+projectId. Not exported. */
102
+ const sharedFirebaseRegistry = new Map();
103
+ const sharedFirebaseInFlight = new Map();
104
+ function getSharedFirebaseKey(workspaceId, product, projectId) {
105
+ return `firebase:${workspaceId}:${product}:${projectId}`;
106
+ }
107
+ /** Shared SMS clients: one per workspace+product+poolKey. Not exported. */
108
+ const sharedSmsRegistry = new Map();
109
+ const sharedSmsInFlight = new Map();
110
+ function getSharedSmsKey(workspaceId, product, poolKey) {
111
+ return `sms:${workspaceId}:${product}:${poolKey}`;
112
+ }
94
113
  class ProcessorService {
95
114
  constructor({ workspace_id, public_key, user_id, token, env_type, private_key, access_key, redis_client, queues, preInitializedProductBuilder }) {
96
115
  /** Reuse broker connections when multiple produce steps use the same broker (avoids ~1–3s connection setup per step). Never logged or exposed. */
97
116
  this.brokerServicePool = new Map();
98
117
  /** Reuse SMTP transporter so we don't open a new connection per email (avoids multi-second handshake per send). Never logged or exposed. */
99
118
  this.mailTransporterPool = new Map();
119
+ this.mailPoolKeyToSharedKey = new Map();
100
120
  /** Reuse Firebase Admin app per project (avoids re-init per push). Never logged or exposed. */
101
121
  this.firebaseAppPool = new Map();
122
+ this.firebasePoolKeyToSharedKey = new Map();
102
123
  /** Reuse SMS client per config (Twilio/Nexmo/Plivo). Never logged or exposed. */
103
124
  this.smsClientPool = new Map();
125
+ this.smsPoolKeyToSharedKey = new Map();
104
126
  this.workspace_id = workspace_id;
105
127
  this.public_key = public_key;
106
128
  this.user_id = user_id;
@@ -223,12 +245,72 @@ class ProcessorService {
223
245
  }
224
246
  /**
225
247
  * Get or create a mail transporter so we reuse the same SMTP connection instead of opening a new one per send.
248
+ * When scope.workspaceId and scope.product are provided, uses shared registry across instances.
226
249
  */
227
- async getMailTransporter(auth) {
250
+ async getMailTransporter(auth, scope) {
251
+ var _a, _b;
228
252
  const key = this.getMailTransporterPoolKey(auth);
229
253
  const existing = this.mailTransporterPool.get(key);
230
254
  if (existing)
231
255
  return existing;
256
+ const workspaceId = (_a = scope === null || scope === void 0 ? void 0 : scope.workspaceId) !== null && _a !== void 0 ? _a : '';
257
+ const product = (_b = scope === null || scope === void 0 ? void 0 : scope.product) !== null && _b !== void 0 ? _b : '';
258
+ const useShared = workspaceId !== '' && product !== '';
259
+ if (useShared) {
260
+ const sharedKey = getSharedMailKey(workspaceId, product, key);
261
+ const existingShared = sharedMailRegistry.get(sharedKey);
262
+ if (existingShared) {
263
+ this.mailTransporterPool.set(key, existingShared);
264
+ this.mailPoolKeyToSharedKey.set(key, sharedKey);
265
+ return existingShared;
266
+ }
267
+ const inFlight = sharedMailInFlight.get(sharedKey);
268
+ if (inFlight) {
269
+ const transporter = await inFlight;
270
+ this.mailTransporterPool.set(key, transporter);
271
+ this.mailPoolKeyToSharedKey.set(key, sharedKey);
272
+ return transporter;
273
+ }
274
+ const createPromise = (async () => {
275
+ const existingInRegistry = sharedMailRegistry.get(sharedKey);
276
+ if (existingInRegistry) {
277
+ try {
278
+ const close = existingInRegistry.close;
279
+ if (typeof close === 'function')
280
+ await close();
281
+ }
282
+ catch (_a) {
283
+ // Non-fatal
284
+ }
285
+ sharedMailRegistry.delete(sharedKey);
286
+ }
287
+ const transporter = await (0, processor_utils_1.mailerClient)(auth);
288
+ const raceExisting = sharedMailRegistry.get(sharedKey);
289
+ if (raceExisting) {
290
+ try {
291
+ const close = raceExisting.close;
292
+ if (typeof close === 'function')
293
+ await close();
294
+ }
295
+ catch (_b) {
296
+ // Non-fatal
297
+ }
298
+ sharedMailRegistry.delete(sharedKey);
299
+ }
300
+ sharedMailRegistry.set(sharedKey, transporter);
301
+ return transporter;
302
+ })();
303
+ sharedMailInFlight.set(sharedKey, createPromise);
304
+ try {
305
+ const transporter = await createPromise;
306
+ this.mailTransporterPool.set(key, transporter);
307
+ this.mailPoolKeyToSharedKey.set(key, sharedKey);
308
+ return transporter;
309
+ }
310
+ finally {
311
+ sharedMailInFlight.delete(sharedKey);
312
+ }
313
+ }
232
314
  const transporter = await (0, processor_utils_1.mailerClient)(auth);
233
315
  this.mailTransporterPool.set(key, transporter);
234
316
  return transporter;
@@ -237,7 +319,7 @@ class ProcessorService {
237
319
  * Close all pooled mail transporters (e.g. at end of workflow run). Safe if pool is empty.
238
320
  */
239
321
  async disconnectMailTransporters() {
240
- for (const transporter of this.mailTransporterPool.values()) {
322
+ for (const [key, transporter] of this.mailTransporterPool.entries()) {
241
323
  try {
242
324
  const close = transporter.close;
243
325
  if (typeof close === 'function')
@@ -246,26 +328,96 @@ class ProcessorService {
246
328
  catch (_a) {
247
329
  // Non-fatal
248
330
  }
331
+ const sharedKey = this.mailPoolKeyToSharedKey.get(key);
332
+ if (sharedKey)
333
+ sharedMailRegistry.delete(sharedKey);
249
334
  }
250
335
  this.mailTransporterPool.clear();
336
+ this.mailPoolKeyToSharedKey.clear();
251
337
  }
252
338
  /**
253
339
  * Get or create Firebase Admin app by project_id so we reuse the same app per project (Expo client is already module-level singleton).
340
+ * When scope.workspaceId and scope.product are provided, uses shared registry across instances.
254
341
  */
255
- async getFirebaseApp(credentials) {
256
- var _a, _b;
342
+ async getFirebaseApp(credentials, scope) {
343
+ var _a, _b, _c, _d;
257
344
  const creds = typeof credentials === 'string' ? JSON.parse(credentials) : credentials;
258
345
  const projectId = (_a = creds === null || creds === void 0 ? void 0 : creds.project_id) !== null && _a !== void 0 ? _a : `fb-${String((_b = creds === null || creds === void 0 ? void 0 : creds.client_email) !== null && _b !== void 0 ? _b : '').slice(0, 20)}`;
259
346
  const existing = this.firebaseAppPool.get(projectId);
260
347
  if (existing)
261
348
  return existing;
349
+ const workspaceId = (_c = scope === null || scope === void 0 ? void 0 : scope.workspaceId) !== null && _c !== void 0 ? _c : '';
350
+ const product = (_d = scope === null || scope === void 0 ? void 0 : scope.product) !== null && _d !== void 0 ? _d : '';
351
+ const useShared = workspaceId !== '' && product !== '';
352
+ if (useShared) {
353
+ const sharedKey = getSharedFirebaseKey(workspaceId, product, projectId);
354
+ const existingShared = sharedFirebaseRegistry.get(sharedKey);
355
+ if (existingShared) {
356
+ this.firebaseAppPool.set(projectId, existingShared);
357
+ this.firebasePoolKeyToSharedKey.set(projectId, sharedKey);
358
+ return existingShared;
359
+ }
360
+ const inFlight = sharedFirebaseInFlight.get(sharedKey);
361
+ if (inFlight) {
362
+ const app = await inFlight;
363
+ this.firebaseAppPool.set(projectId, app);
364
+ this.firebasePoolKeyToSharedKey.set(projectId, sharedKey);
365
+ return app;
366
+ }
367
+ const createPromise = (async () => {
368
+ const existingInRegistry = sharedFirebaseRegistry.get(sharedKey);
369
+ if (existingInRegistry) {
370
+ try {
371
+ const del = existingInRegistry.delete;
372
+ if (typeof del === 'function')
373
+ await del();
374
+ }
375
+ catch (_a) {
376
+ // Non-fatal
377
+ }
378
+ sharedFirebaseRegistry.delete(sharedKey);
379
+ }
380
+ const admin = require('firebase-admin');
381
+ let app;
382
+ try {
383
+ app = admin.app(projectId);
384
+ }
385
+ catch (_b) {
386
+ app = admin.initializeApp({ credential: admin.credential.cert(credentials) }, projectId);
387
+ }
388
+ const raceExisting = sharedFirebaseRegistry.get(sharedKey);
389
+ if (raceExisting) {
390
+ try {
391
+ const del = raceExisting.delete;
392
+ if (typeof del === 'function')
393
+ await del();
394
+ }
395
+ catch (_c) {
396
+ // Non-fatal
397
+ }
398
+ sharedFirebaseRegistry.delete(sharedKey);
399
+ }
400
+ sharedFirebaseRegistry.set(sharedKey, app);
401
+ return app;
402
+ })();
403
+ sharedFirebaseInFlight.set(sharedKey, createPromise);
404
+ try {
405
+ const app = await createPromise;
406
+ this.firebaseAppPool.set(projectId, app);
407
+ this.firebasePoolKeyToSharedKey.set(projectId, sharedKey);
408
+ return app;
409
+ }
410
+ finally {
411
+ sharedFirebaseInFlight.delete(sharedKey);
412
+ }
413
+ }
262
414
  const admin = require('firebase-admin');
263
415
  try {
264
416
  const app = admin.app(projectId);
265
417
  this.firebaseAppPool.set(projectId, app);
266
418
  return app;
267
419
  }
268
- catch (_c) {
420
+ catch (_e) {
269
421
  const app = admin.initializeApp({ credential: admin.credential.cert(credentials) }, projectId);
270
422
  this.firebaseAppPool.set(projectId, app);
271
423
  return app;
@@ -275,7 +427,7 @@ class ProcessorService {
275
427
  * Close all pooled Firebase apps (e.g. at end of workflow run). Safe if pool is empty.
276
428
  */
277
429
  async disconnectFirebaseApps() {
278
- for (const app of this.firebaseAppPool.values()) {
430
+ for (const [projectId, app] of this.firebaseAppPool.entries()) {
279
431
  try {
280
432
  const del = app.delete;
281
433
  if (typeof del === 'function')
@@ -284,8 +436,12 @@ class ProcessorService {
284
436
  catch (_a) {
285
437
  // Non-fatal
286
438
  }
439
+ const sharedKey = this.firebasePoolKeyToSharedKey.get(projectId);
440
+ if (sharedKey)
441
+ sharedFirebaseRegistry.delete(sharedKey);
287
442
  }
288
443
  this.firebaseAppPool.clear();
444
+ this.firebasePoolKeyToSharedKey.clear();
289
445
  }
290
446
  /**
291
447
  * Pool key for SMS client (provider + identifier + sender; no secrets). Same config => reuse client.
@@ -299,12 +455,55 @@ class ProcessorService {
299
455
  }
300
456
  /**
301
457
  * Get or create SMS client so we reuse Twilio/Nexmo/Plivo client per config.
458
+ * When scope.workspaceId and scope.product are provided, uses shared registry across instances.
302
459
  */
303
- async getSmsClient(config) {
460
+ async getSmsClient(config, scope) {
461
+ var _a, _b;
304
462
  const key = this.getSmsClientPoolKey(config);
305
463
  const existing = this.smsClientPool.get(key);
306
464
  if (existing)
307
465
  return existing;
466
+ const workspaceId = (_a = scope === null || scope === void 0 ? void 0 : scope.workspaceId) !== null && _a !== void 0 ? _a : '';
467
+ const product = (_b = scope === null || scope === void 0 ? void 0 : scope.product) !== null && _b !== void 0 ? _b : '';
468
+ const useShared = workspaceId !== '' && product !== '';
469
+ if (useShared) {
470
+ const sharedKey = getSharedSmsKey(workspaceId, product, key);
471
+ const existingShared = sharedSmsRegistry.get(sharedKey);
472
+ if (existingShared) {
473
+ this.smsClientPool.set(key, existingShared);
474
+ this.smsPoolKeyToSharedKey.set(key, sharedKey);
475
+ return existingShared;
476
+ }
477
+ const inFlight = sharedSmsInFlight.get(sharedKey);
478
+ if (inFlight) {
479
+ const client = await inFlight;
480
+ this.smsClientPool.set(key, client);
481
+ this.smsPoolKeyToSharedKey.set(key, sharedKey);
482
+ return client;
483
+ }
484
+ const createPromise = (async () => {
485
+ sharedSmsRegistry.delete(sharedKey);
486
+ const SmsClientClass = await (0, sms_repo_1.loadSMSClient)();
487
+ if (!SmsClientClass)
488
+ throw new Error('SMS client not loaded (e.g. browser).');
489
+ const client = new SmsClientClass(config);
490
+ const raceExisting = sharedSmsRegistry.get(sharedKey);
491
+ if (raceExisting)
492
+ sharedSmsRegistry.delete(sharedKey);
493
+ sharedSmsRegistry.set(sharedKey, client);
494
+ return client;
495
+ })();
496
+ sharedSmsInFlight.set(sharedKey, createPromise);
497
+ try {
498
+ const client = await createPromise;
499
+ this.smsClientPool.set(key, client);
500
+ this.smsPoolKeyToSharedKey.set(key, sharedKey);
501
+ return client;
502
+ }
503
+ finally {
504
+ sharedSmsInFlight.delete(sharedKey);
505
+ }
506
+ }
308
507
  const SmsClientClass = await (0, sms_repo_1.loadSMSClient)();
309
508
  if (!SmsClientClass)
310
509
  throw new Error('SMS client not loaded (e.g. browser).');
@@ -316,7 +515,13 @@ class ProcessorService {
316
515
  * Clear pooled SMS clients (e.g. at end of workflow run). Safe if pool is empty.
317
516
  */
318
517
  async disconnectSmsClients() {
518
+ for (const [key] of this.smsClientPool.entries()) {
519
+ const sharedKey = this.smsPoolKeyToSharedKey.get(key);
520
+ if (sharedKey)
521
+ sharedSmsRegistry.delete(sharedKey);
522
+ }
319
523
  this.smsClientPool.clear();
524
+ this.smsPoolKeyToSharedKey.clear();
320
525
  }
321
526
  /**
322
527
  * Pre-warm broker connections for the given product/env and broker tags.
@@ -2327,6 +2532,7 @@ class ProcessorService {
2327
2532
  return (0, processor_utils_1.generateIndexes)(operator, iter, init, valueValue);
2328
2533
  }
2329
2534
  async runAction(event, additional_logs, returnValue = true, bootstrapData) {
2535
+ var _a, _b, _c;
2330
2536
  try {
2331
2537
  const { event: action_tag, app: access_tag, condition, cache: cache_tag } = event;
2332
2538
  let indexes = [];
@@ -2346,6 +2552,8 @@ class ProcessorService {
2346
2552
  let app_active;
2347
2553
  let app_id = '';
2348
2554
  let app_env_slug = '';
2555
+ /** Product app env mapping (includes variables for base_url resolution). */
2556
+ let envMapping = null;
2349
2557
  // Use bootstrap data if provided, otherwise fetch via API
2350
2558
  if (bootstrapData) {
2351
2559
  action = bootstrapData.action;
@@ -2354,6 +2562,7 @@ class ProcessorService {
2354
2562
  recipient_workspace_id = bootstrapData.recipient_workspace_id;
2355
2563
  app_active = bootstrapData.app_active;
2356
2564
  app_env_slug = env.slug;
2565
+ envMapping = (_a = bootstrapData.product_env_mapping) !== null && _a !== void 0 ? _a : null;
2357
2566
  additional_logs.app_env = app_env_slug;
2358
2567
  }
2359
2568
  else {
@@ -2362,7 +2571,7 @@ class ProcessorService {
2362
2571
  const { actions, envs: appEnvs, retries: appRetries, workspace_id: appWorkspaceId, active } = appData;
2363
2572
  const productApp = await this.productBuilderService.fetchApp(access_tag);
2364
2573
  const { envs: productEnvs } = productApp;
2365
- const envMapping = productEnvs.find((item) => item.product_env_slug === this.processEnv.slug);
2574
+ envMapping = (_b = productEnvs.find((item) => item.product_env_slug === this.processEnv.slug)) !== null && _b !== void 0 ? _b : null;
2366
2575
  app_env_slug = (envMapping === null || envMapping === void 0 ? void 0 : envMapping.app_env_slug) || '';
2367
2576
  additional_logs.app_env = app_env_slug;
2368
2577
  env = appEnvs.find((item) => item.slug === app_env_slug);
@@ -2392,6 +2601,10 @@ class ProcessorService {
2392
2601
  request_base_url = actionEnv.base_url;
2393
2602
  }
2394
2603
  }
2604
+ // Resolve {{variable}} and :variable in base_url with product env variables
2605
+ if ((_c = envMapping === null || envMapping === void 0 ? void 0 : envMapping.variables) === null || _c === void 0 ? void 0 : _c.length) {
2606
+ request_base_url = (0, string_utils_2.resolveBaseUrlVariables)(request_base_url, envMapping.variables);
2607
+ }
2395
2608
  const samples = {
2396
2609
  query: (query === null || query === void 0 ? void 0 : query.data) || [],
2397
2610
  headers: (headers === null || headers === void 0 ? void 0 : headers.data) || [],
@@ -3317,7 +3530,7 @@ class ProcessorService {
3317
3530
  throw e;
3318
3531
  }
3319
3532
  }
3320
- async sendFirebaseNotification(payload, device_tokens, credentials) {
3533
+ async sendFirebaseNotification(payload, device_tokens, credentials, scope) {
3321
3534
  const message = {
3322
3535
  notification: {
3323
3536
  title: payload.title,
@@ -3326,7 +3539,7 @@ class ProcessorService {
3326
3539
  tokens: device_tokens,
3327
3540
  };
3328
3541
  try {
3329
- const app = await this.getFirebaseApp(credentials);
3542
+ const app = await this.getFirebaseApp(credentials, scope);
3330
3543
  await app.messaging().sendEachForMulticast(message);
3331
3544
  }
3332
3545
  catch (e) {
@@ -3347,7 +3560,7 @@ class ProcessorService {
3347
3560
  await this.sendExpoNotification({ title, body, data }, payload.device_tokens);
3348
3561
  this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: logType, message: 'Send Expo notification - success', data: { title, body, data }, status: types_1.LogEventStatus.SUCCESS }));
3349
3562
  }
3350
- async ProcessFirebaseNotification(notification, template, payload, additional_logs, logType = types_1.LogEventTypes.PUSH) {
3563
+ async ProcessFirebaseNotification(notification, template, payload, additional_logs, logType = types_1.LogEventTypes.PUSH, scope) {
3351
3564
  var _a, _b;
3352
3565
  debugLog('[ProcessFirebaseNotification] ENTRY', { deviceTokens: (_a = payload === null || payload === void 0 ? void 0 : payload.device_tokens) === null || _a === void 0 ? void 0 : _a.length, logType });
3353
3566
  (0, processor_utils_1.validateNotification)(template, payload);
@@ -3356,11 +3569,11 @@ class ProcessorService {
3356
3569
  debugLog('[ProcessFirebaseNotification] Template generated', { title: (_b = title === null || title === void 0 ? void 0 : title.slice) === null || _b === void 0 ? void 0 : _b.call(title, 0, 40), bodyLength: body === null || body === void 0 ? void 0 : body.length });
3357
3570
  this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: logType, message: 'Generate Firebase notification template - success', data: { title, body, data }, status: types_1.LogEventStatus.SUCCESS }));
3358
3571
  debugLog('[ProcessFirebaseNotification] Sending to Firebase');
3359
- await this.sendFirebaseNotification({ title, body, data }, payload.device_tokens, notification.credentials);
3572
+ await this.sendFirebaseNotification({ title, body, data }, payload.device_tokens, notification.credentials, scope);
3360
3573
  this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: logType, message: 'Send Firebase notification - success', data: { title, body, data }, status: types_1.LogEventStatus.SUCCESS }));
3361
3574
  }
3362
3575
  async runNotification(notification, additional_logs, bootstrapData) {
3363
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
3576
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
3364
3577
  const { event } = notification;
3365
3578
  const input = notification.input;
3366
3579
  const logMessageLog = (channelType, status, err) => {
@@ -3423,6 +3636,10 @@ class ProcessorService {
3423
3636
  }
3424
3637
  }
3425
3638
  const { push_notification: push, email, callback, sms } = message;
3639
+ const notifScope = {
3640
+ workspaceId: (_d = this.workspace_id) !== null && _d !== void 0 ? _d : '',
3641
+ product: (_f = (_e = bootstrapData === null || bootstrapData === void 0 ? void 0 : bootstrapData.product_tag) !== null && _e !== void 0 ? _e : this.productTag) !== null && _f !== void 0 ? _f : '',
3642
+ };
3426
3643
  debugLog('[runNotification] Message template flags', { push: !!push, email: !!email, callback: !!callback, sms: !!sms });
3427
3644
  debugLog('[runNotification] Input channels present', {
3428
3645
  push_notification: !!input.push_notification,
@@ -3473,7 +3690,7 @@ class ProcessorService {
3473
3690
  debugLog('[runNotification] PUSH: processing Firebase');
3474
3691
  this.lastNotificationFailureType = types_1.LogEventTypes.PUSH;
3475
3692
  try {
3476
- await this.ProcessFirebaseNotification(notifications, message, input.push_notification, additional_logs);
3693
+ await this.ProcessFirebaseNotification(notifications, message, input.push_notification, additional_logs, undefined, notifScope);
3477
3694
  this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: types_1.LogEventTypes.PUSH, successful_execution: true, message: 'Processing Firebase notification - success', data: { notification }, status: types_1.LogEventStatus.SUCCESS }));
3478
3695
  logMessageLog('push', 'sent');
3479
3696
  debugLog('[runNotification] PUSH (Firebase): success');
@@ -3514,9 +3731,9 @@ class ProcessorService {
3514
3731
  subject,
3515
3732
  template,
3516
3733
  };
3517
- debugLog('[runNotification] EMAIL: sending mail', { to: (_d = mailOptions.to) === null || _d === void 0 ? void 0 : _d.length, subject: (_f = (_e = mailOptions.subject) === null || _e === void 0 ? void 0 : _e.slice) === null || _f === void 0 ? void 0 : _f.call(_e, 0, 50) });
3734
+ debugLog('[runNotification] EMAIL: sending mail', { to: (_g = mailOptions.to) === null || _g === void 0 ? void 0 : _g.length, subject: (_j = (_h = mailOptions.subject) === null || _h === void 0 ? void 0 : _h.slice) === null || _j === void 0 ? void 0 : _j.call(_h, 0, 50) });
3518
3735
  try {
3519
- const transporter = await this.getMailTransporter(auth);
3736
+ const transporter = await this.getMailTransporter(auth, notifScope);
3520
3737
  await transporter.sendMail(mailOptions);
3521
3738
  logMessageLog('email', 'sent');
3522
3739
  }
@@ -3538,10 +3755,10 @@ class ProcessorService {
3538
3755
  debugLog('[runNotification] CALLBACK: processing', { url: callbacks.url, method: callbacks.method });
3539
3756
  this.lastNotificationFailureType = types_1.LogEventTypes.CALLBACKS;
3540
3757
  const payload = {
3541
- query: Object.assign(Object.assign({}, (_g = input.callback) === null || _g === void 0 ? void 0 : _g.query), (_h = callbacks.auth) === null || _h === void 0 ? void 0 : _h.query),
3542
- headers: Object.assign(Object.assign({}, (_j = input.callback) === null || _j === void 0 ? void 0 : _j.headers), (_k = callbacks.auth) === null || _k === void 0 ? void 0 : _k.headers),
3543
- params: Object.assign(Object.assign({}, (_l = input.callback) === null || _l === void 0 ? void 0 : _l.params), (_m = callbacks.auth) === null || _m === void 0 ? void 0 : _m.params),
3544
- body: Object.assign(Object.assign({}, (_o = input.callback) === null || _o === void 0 ? void 0 : _o.body), (_p = callbacks.auth) === null || _p === void 0 ? void 0 : _p.body),
3758
+ query: Object.assign(Object.assign({}, (_k = input.callback) === null || _k === void 0 ? void 0 : _k.query), (_l = callbacks.auth) === null || _l === void 0 ? void 0 : _l.query),
3759
+ headers: Object.assign(Object.assign({}, (_m = input.callback) === null || _m === void 0 ? void 0 : _m.headers), (_o = callbacks.auth) === null || _o === void 0 ? void 0 : _o.headers),
3760
+ params: Object.assign(Object.assign({}, (_p = input.callback) === null || _p === void 0 ? void 0 : _p.params), (_q = callbacks.auth) === null || _q === void 0 ? void 0 : _q.params),
3761
+ body: Object.assign(Object.assign({}, (_r = input.callback) === null || _r === void 0 ? void 0 : _r.body), (_s = callbacks.auth) === null || _s === void 0 ? void 0 : _s.body),
3545
3762
  };
3546
3763
  input.callback.body = await this.generatePayload(payload.body, notification, additional_logs, message.callback_data.filter((data) => data.parent_key === 'body'));
3547
3764
  input.callback.query = await this.generatePayload(payload.query, notification, additional_logs, message.callback_data.filter((data) => data.parent_key === 'query'));
@@ -3558,10 +3775,10 @@ class ProcessorService {
3558
3775
  }
3559
3776
  const url = new URL(callbackUrl);
3560
3777
  const requestPayload = {
3561
- query: Object.assign(Object.assign({}, (_q = input.callback) === null || _q === void 0 ? void 0 : _q.query), (_r = callbacks.auth) === null || _r === void 0 ? void 0 : _r.query),
3562
- headers: Object.assign(Object.assign({}, (_s = input.callback) === null || _s === void 0 ? void 0 : _s.headers), (_t = callbacks.auth) === null || _t === void 0 ? void 0 : _t.headers),
3563
- params: Object.assign(Object.assign({}, (_u = input.callback) === null || _u === void 0 ? void 0 : _u.params), (_v = callbacks.auth) === null || _v === void 0 ? void 0 : _v.params),
3564
- body: Object.assign(Object.assign({}, (_w = input.callback) === null || _w === void 0 ? void 0 : _w.body), (_x = callbacks.auth) === null || _x === void 0 ? void 0 : _x.body),
3778
+ query: Object.assign(Object.assign({}, (_t = input.callback) === null || _t === void 0 ? void 0 : _t.query), (_u = callbacks.auth) === null || _u === void 0 ? void 0 : _u.query),
3779
+ headers: Object.assign(Object.assign({}, (_v = input.callback) === null || _v === void 0 ? void 0 : _v.headers), (_w = callbacks.auth) === null || _w === void 0 ? void 0 : _w.headers),
3780
+ params: Object.assign(Object.assign({}, (_x = input.callback) === null || _x === void 0 ? void 0 : _x.params), (_y = callbacks.auth) === null || _y === void 0 ? void 0 : _y.params),
3781
+ body: Object.assign(Object.assign({}, (_z = input.callback) === null || _z === void 0 ? void 0 : _z.body), (_0 = callbacks.auth) === null || _0 === void 0 ? void 0 : _0.body),
3565
3782
  };
3566
3783
  try {
3567
3784
  await this.sendActionRequest(url.origin, url.pathname, requestPayload, callbacks.method, '');
@@ -3584,11 +3801,11 @@ class ProcessorService {
3584
3801
  debugLog('[runNotification] SMS: skipped (no input.sms)');
3585
3802
  }
3586
3803
  if (sms && smses && input.sms) {
3587
- debugLog('[runNotification] SMS: processing', { recipients: (_y = input.sms.recipients) === null || _y === void 0 ? void 0 : _y.length });
3804
+ debugLog('[runNotification] SMS: processing', { recipients: (_1 = input.sms.recipients) === null || _1 === void 0 ? void 0 : _1.length });
3588
3805
  this.lastNotificationFailureType = types_1.LogEventTypes.SMS;
3589
3806
  try {
3590
3807
  input.sms.body = (await (0, processor_utils_1.replacePlaceholderString)(sms, input.sms.body));
3591
- const smsClient = await this.getSmsClient(smses);
3808
+ const smsClient = await this.getSmsClient(smses, notifScope);
3592
3809
  this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: types_1.LogEventTypes.SMS, name: 'Send sms - initiated', data: { message: input.sms.body, config: smses }, status: types_1.LogEventStatus.SUCCESS }));
3593
3810
  const res = await smsClient.sendMessage(input.sms.body, input.sms.recipients);
3594
3811
  if (res && res.success !== undefined && !res.success) {
@@ -3604,7 +3821,7 @@ class ProcessorService {
3604
3821
  logMessageLog('sms', 'failed', e);
3605
3822
  }
3606
3823
  }
3607
- debugLog('[runNotification] DONE: all channels processed', { lastChannelType: (_z = this.lastNotificationFailureType) !== null && _z !== void 0 ? _z : 'NOTIFICATIONS' });
3824
+ debugLog('[runNotification] DONE: all channels processed', { lastChannelType: (_2 = this.lastNotificationFailureType) !== null && _2 !== void 0 ? _2 : 'NOTIFICATIONS' });
3608
3825
  // Only add aggregate success log when we have a subtype (no NOTIFICATIONS-typed logs)
3609
3826
  /*if (this.lastNotificationFailureType != null) {
3610
3827
  this.logService.add({
@@ -3618,7 +3835,7 @@ class ProcessorService {
3618
3835
  }*/
3619
3836
  }
3620
3837
  catch (e) {
3621
- debugLog('[runNotification] ERROR', { error: e, lastChannelType: (_0 = this.lastNotificationFailureType) !== null && _0 !== void 0 ? _0 : 'NOTIFICATIONS' });
3838
+ debugLog('[runNotification] ERROR', { error: e, lastChannelType: (_3 = this.lastNotificationFailureType) !== null && _3 !== void 0 ? _3 : 'NOTIFICATIONS' });
3622
3839
  // Only add aggregate failure log when we have a subtype (no NOTIFICATIONS-typed logs)
3623
3840
  if (this.lastNotificationFailureType != null) {
3624
3841
  this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: this.lastNotificationFailureType, failed_execution: true, message: 'Attempt notification - failed', data: { e: e.toString() }, status: types_1.LogEventStatus.FAIL }));
@@ -4304,6 +4521,7 @@ class ProcessorService {
4304
4521
  retries: bootstrapData.retries,
4305
4522
  app_active: bootstrapData.app_active,
4306
4523
  recipient_workspace_id: bootstrapData.recipient_workspace_id,
4524
+ product_env_mapping: bootstrapData.product_env_mapping,
4307
4525
  });
4308
4526
  this.end = Date.now();
4309
4527
  this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Execute action - success', data: { input: (0, processor_utils_1.anonymizeObject)(input), result: (0, processor_utils_1.anonymizeObject)(result) }, status: types_1.LogEventStatus.SUCCESS }));