@ductape/sdk 0.0.8 → 0.1.0
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/agents/agents.service.js +2 -0
- package/dist/agents/agents.service.js.map +1 -1
- package/dist/api/services/processorApi.service.d.ts +15 -10
- package/dist/api/services/processorApi.service.js +10 -2
- package/dist/api/services/processorApi.service.js.map +1 -1
- package/dist/api/services/productsApi.service.d.ts +1 -0
- package/dist/api/services/productsApi.service.js.map +1 -1
- package/dist/api/services/workspaceApi.service.js +4 -1
- package/dist/api/services/workspaceApi.service.js.map +1 -1
- package/dist/api/urls.js +3 -3
- package/dist/api/urls.js.map +1 -1
- package/dist/apps/services/app.service.d.ts +2 -1
- package/dist/apps/services/app.service.js +4 -1
- package/dist/apps/services/app.service.js.map +1 -1
- package/dist/brokers/brokers.service.js +1 -0
- package/dist/brokers/brokers.service.js.map +1 -1
- package/dist/brokers/types/index.d.ts +2 -0
- package/dist/cache/cache.service.d.ts +1 -0
- package/dist/cache/cache.service.js +2 -0
- package/dist/cache/cache.service.js.map +1 -1
- package/dist/cache/types/index.d.ts +2 -0
- package/dist/database/databases.service.js +2 -0
- package/dist/database/databases.service.js.map +1 -1
- package/dist/graph/graphs.service.js +2 -0
- package/dist/graph/graphs.service.js.map +1 -1
- package/dist/imports/imports.service.d.ts +1 -1
- package/dist/imports/imports.service.js +2 -2
- package/dist/imports/imports.service.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +154 -128
- package/dist/index.js.map +1 -1
- package/dist/logs/logs.service.d.ts +3 -2
- package/dist/logs/logs.service.js +20 -5
- package/dist/logs/logs.service.js.map +1 -1
- package/dist/logs/logs.types.d.ts +6 -0
- package/dist/logs/logs.types.js +4 -0
- package/dist/logs/logs.types.js.map +1 -1
- package/dist/notifications/notifications.service.js +2 -0
- package/dist/notifications/notifications.service.js.map +1 -1
- package/dist/notifications/types/notifications.types.d.ts +4 -2
- package/dist/notifications/types/notifications.types.js +2 -0
- package/dist/notifications/types/notifications.types.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +53 -2
- package/dist/processor/services/processor.service.js +709 -251
- package/dist/processor/services/processor.service.js.map +1 -1
- package/dist/processor/utils/processor.utils.js +6 -1
- package/dist/processor/utils/processor.utils.js.map +1 -1
- package/dist/products/services/products.service.d.ts +26 -0
- package/dist/products/services/products.service.js +48 -1
- package/dist/products/services/products.service.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productFeature.validator.d.ts +2 -0
- package/dist/products/validators/joi-validators/create.productFeature.validator.js +15 -1
- package/dist/products/validators/joi-validators/create.productFeature.validator.js.map +1 -1
- package/dist/resilience/healthcheck.service.d.ts +7 -3
- package/dist/resilience/healthcheck.service.js +82 -13
- package/dist/resilience/healthcheck.service.js.map +1 -1
- package/dist/sessions/sessions.service.js +1 -0
- package/dist/sessions/sessions.service.js.map +1 -1
- package/dist/sessions/types/index.d.ts +2 -0
- package/dist/storage/storage.service.js +2 -0
- package/dist/storage/storage.service.js.map +1 -1
- package/dist/types/processor.types.d.ts +2 -2
- package/dist/types/productsBuilder.types.d.ts +9 -0
- package/dist/types/productsBuilder.types.js.map +1 -1
- package/dist/utils/index.js +64 -6
- package/dist/utils/index.js.map +1 -1
- package/dist/vector/vector-database.service.d.ts +2 -0
- package/dist/vector/vector-database.service.js +3 -0
- package/dist/vector/vector-database.service.js.map +1 -1
- package/dist/workflows/workflow-executor.d.ts +2 -0
- package/dist/workflows/workflow-executor.js +17 -4
- package/dist/workflows/workflow-executor.js.map +1 -1
- package/dist/workflows/workflows.service.js +4 -2
- package/dist/workflows/workflows.service.js.map +1 -1
- package/package.json +3 -1
|
@@ -75,6 +75,9 @@ const credential_manager_1 = require("../../apps/utils/credential-manager");
|
|
|
75
75
|
const oauth_manager_1 = require("../../apps/utils/oauth-manager");
|
|
76
76
|
const string_utils_2 = require("../../apps/utils/string.utils");
|
|
77
77
|
const secrets_1 = require("../../secrets");
|
|
78
|
+
/** TTL for action bootstrap cache (same app version = same bootstrap). 5 minutes. */
|
|
79
|
+
const ACTION_BOOTSTRAP_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
80
|
+
const ACTION_BOOTSTRAP_REDIS_PREFIX = 'ductape:action_bootstrap:';
|
|
78
81
|
async function loadBrokerService() {
|
|
79
82
|
if (typeof window === 'undefined') {
|
|
80
83
|
const { loadBrokerService: loadBroker } = await Promise.resolve().then(() => __importStar(require('../../brokers')));
|
|
@@ -91,7 +94,9 @@ async function loadJWT() {
|
|
|
91
94
|
}
|
|
92
95
|
/** Only log when DUCTAPE_DEBUG is set to avoid sync I/O and serialization cost in hot path */
|
|
93
96
|
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');
|
|
94
|
-
const debugLog = _processorDebug
|
|
97
|
+
const debugLog = _processorDebug
|
|
98
|
+
? (...args) => console.log(...args)
|
|
99
|
+
: () => { };
|
|
95
100
|
/** Shared mail (SMTP) transporters: one per workspace+product+poolKey. Not exported. */
|
|
96
101
|
const sharedMailRegistry = new Map();
|
|
97
102
|
const sharedMailInFlight = new Map();
|
|
@@ -111,7 +116,7 @@ function getSharedSmsKey(workspaceId, product, poolKey) {
|
|
|
111
116
|
return `sms:${workspaceId}:${product}:${poolKey}`;
|
|
112
117
|
}
|
|
113
118
|
class ProcessorService {
|
|
114
|
-
constructor({ workspace_id, public_key, user_id, token, env_type, private_key, access_key, redis_client, queues, preInitializedProductBuilder }) {
|
|
119
|
+
constructor({ workspace_id, public_key, user_id, token, env_type, private_key, access_key, redis_client, queues, preInitializedProductBuilder, }) {
|
|
115
120
|
/** Reuse broker connections when multiple produce steps use the same broker (avoids ~1–3s connection setup per step). Never logged or exposed. */
|
|
116
121
|
this.brokerServicePool = new Map();
|
|
117
122
|
/** Reuse SMTP transporter so we don't open a new connection per email (avoids multi-second handshake per send). Never logged or exposed. */
|
|
@@ -123,6 +128,14 @@ class ProcessorService {
|
|
|
123
128
|
/** Reuse SMS client per config (Twilio/Nexmo/Plivo). Never logged or exposed. */
|
|
124
129
|
this.smsClientPool = new Map();
|
|
125
130
|
this.smsPoolKeyToSharedKey = new Map();
|
|
131
|
+
/** Action bootstrap cache (internal tier): key -> { data, storedAt }. Same key = same app version scope. */
|
|
132
|
+
this.actionBootstrapCache = new Map();
|
|
133
|
+
/** Healthcheck worker interval IDs; cleared and repopulated only when the healthcheck set or config changes. */
|
|
134
|
+
this.healthcheckWorkerIntervals = [];
|
|
135
|
+
/** Timer that periodically checks for healthcheck list changes (default 60s). Workers are only recreated when the fingerprint changes. */
|
|
136
|
+
this.healthcheckRefreshTimer = null;
|
|
137
|
+
/** Fingerprint of current worker set (tag:env:interval) so we only clear/recreate when the list or config actually changed. */
|
|
138
|
+
this.healthcheckWorkerFingerprint = null;
|
|
126
139
|
this.workspace_id = workspace_id;
|
|
127
140
|
this.public_key = public_key;
|
|
128
141
|
this.user_id = user_id;
|
|
@@ -130,16 +143,17 @@ class ProcessorService {
|
|
|
130
143
|
this.accessKey = access_key;
|
|
131
144
|
this.token = token;
|
|
132
145
|
this.published = false;
|
|
133
|
-
this.productBuilderService =
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
this.productBuilderService =
|
|
147
|
+
preInitializedProductBuilder !== null && preInitializedProductBuilder !== void 0 ? preInitializedProductBuilder : new products_service_1.default({
|
|
148
|
+
workspace_id,
|
|
149
|
+
public_key,
|
|
150
|
+
user_id,
|
|
151
|
+
token,
|
|
152
|
+
env_type,
|
|
153
|
+
redis_client,
|
|
154
|
+
access_key,
|
|
155
|
+
workspace_private_key: private_key || undefined,
|
|
156
|
+
});
|
|
143
157
|
this.appBuilderService = new app_service_1.default({
|
|
144
158
|
workspace_id,
|
|
145
159
|
public_key,
|
|
@@ -147,6 +161,7 @@ class ProcessorService {
|
|
|
147
161
|
token,
|
|
148
162
|
env_type,
|
|
149
163
|
redis_client,
|
|
164
|
+
access_key,
|
|
150
165
|
});
|
|
151
166
|
this.pricingService = new pricing_service_1.default({
|
|
152
167
|
workspace_id,
|
|
@@ -561,50 +576,167 @@ class ProcessorService {
|
|
|
561
576
|
}
|
|
562
577
|
}
|
|
563
578
|
}
|
|
579
|
+
/**
|
|
580
|
+
* Run a single healthcheck (one env) by dispatching to the correct processor based on probe type.
|
|
581
|
+
* Supports app, database, workflow, graph, storage, message_broker. Falls back to processAction when probe is missing (app/event only).
|
|
582
|
+
* Public so the SDK monitor worker can call it with full healthcheck (including probe).
|
|
583
|
+
*/
|
|
584
|
+
async runOneHealthcheck(healthcheck, envSlug, decryptedInput, productTag) {
|
|
585
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
586
|
+
const probe = healthcheck.probe;
|
|
587
|
+
const retries = (_a = healthcheck.retries) !== null && _a !== void 0 ? _a : 0;
|
|
588
|
+
const inferType = () => {
|
|
589
|
+
if (probe === null || probe === void 0 ? void 0 : probe.type)
|
|
590
|
+
return String(probe.type);
|
|
591
|
+
if (probe === null || probe === void 0 ? void 0 : probe.app)
|
|
592
|
+
return 'app';
|
|
593
|
+
if (probe === null || probe === void 0 ? void 0 : probe.database)
|
|
594
|
+
return 'database';
|
|
595
|
+
if (probe === null || probe === void 0 ? void 0 : probe.workflow)
|
|
596
|
+
return 'workflow';
|
|
597
|
+
if (probe === null || probe === void 0 ? void 0 : probe.graph)
|
|
598
|
+
return 'graph';
|
|
599
|
+
if (probe === null || probe === void 0 ? void 0 : probe.storage)
|
|
600
|
+
return 'storage';
|
|
601
|
+
if (probe === null || probe === void 0 ? void 0 : probe.messageBroker)
|
|
602
|
+
return 'message_broker';
|
|
603
|
+
return 'app';
|
|
604
|
+
};
|
|
605
|
+
const type = inferType();
|
|
606
|
+
const event = (_b = probe === null || probe === void 0 ? void 0 : probe.event) !== null && _b !== void 0 ? _b : healthcheck.event;
|
|
607
|
+
switch (type) {
|
|
608
|
+
case 'app': {
|
|
609
|
+
const app = (_d = (_c = healthcheck.app) !== null && _c !== void 0 ? _c : probe === null || probe === void 0 ? void 0 : probe.app) !== null && _d !== void 0 ? _d : '';
|
|
610
|
+
if (!app) {
|
|
611
|
+
throw new Error(`Healthcheck "${healthcheck.tag}" has no app (probe missing or app empty). Ensure healthchecks are fetched with probe from the components API.`);
|
|
612
|
+
}
|
|
613
|
+
return this.processAction({
|
|
614
|
+
env: envSlug,
|
|
615
|
+
product: productTag,
|
|
616
|
+
app,
|
|
617
|
+
action: (_f = (_e = healthcheck.event) !== null && _e !== void 0 ? _e : event) !== null && _f !== void 0 ? _f : '',
|
|
618
|
+
input: decryptedInput !== null && decryptedInput !== void 0 ? decryptedInput : {},
|
|
619
|
+
retries,
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
case 'database':
|
|
623
|
+
return this.processDatabaseAction({
|
|
624
|
+
env: envSlug,
|
|
625
|
+
product: productTag,
|
|
626
|
+
database: probe.database,
|
|
627
|
+
event: event !== null && event !== void 0 ? event : 'test_connection',
|
|
628
|
+
input: decryptedInput !== null && decryptedInput !== void 0 ? decryptedInput : {},
|
|
629
|
+
});
|
|
630
|
+
case 'workflow':
|
|
631
|
+
return this.processWorkflow({
|
|
632
|
+
env: envSlug,
|
|
633
|
+
product: productTag,
|
|
634
|
+
workflow: probe.workflow,
|
|
635
|
+
input: decryptedInput !== null && decryptedInput !== void 0 ? decryptedInput : {},
|
|
636
|
+
});
|
|
637
|
+
case 'graph':
|
|
638
|
+
return this.processGraphAction({
|
|
639
|
+
env: envSlug,
|
|
640
|
+
product: productTag,
|
|
641
|
+
graph: probe.graph,
|
|
642
|
+
event: event !== null && event !== void 0 ? event : 'test_connection',
|
|
643
|
+
input: decryptedInput !== null && decryptedInput !== void 0 ? decryptedInput : {},
|
|
644
|
+
});
|
|
645
|
+
case 'storage': {
|
|
646
|
+
const storageTag = probe.storage;
|
|
647
|
+
const op = event !== null && event !== void 0 ? event : 'test_connection';
|
|
648
|
+
return this.processStorage({
|
|
649
|
+
env: envSlug,
|
|
650
|
+
product: productTag,
|
|
651
|
+
event: `${storageTag}:${op}`,
|
|
652
|
+
input: (decryptedInput && typeof decryptedInput === 'object' ? decryptedInput : {}),
|
|
653
|
+
retries,
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
case 'message_broker': {
|
|
657
|
+
const brokerTag = probe.messageBroker;
|
|
658
|
+
const topicOrAction = event !== null && event !== void 0 ? event : 'health';
|
|
659
|
+
return this.processMessageBrokerPublish({
|
|
660
|
+
env: envSlug,
|
|
661
|
+
product: productTag,
|
|
662
|
+
event: `${brokerTag}:${topicOrAction}`,
|
|
663
|
+
input: { message: typeof decryptedInput === 'object' && decryptedInput != null ? decryptedInput : {} },
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
default:
|
|
667
|
+
return this.processAction({
|
|
668
|
+
env: envSlug,
|
|
669
|
+
product: productTag,
|
|
670
|
+
app: (_g = healthcheck.app) !== null && _g !== void 0 ? _g : '',
|
|
671
|
+
action: (_j = (_h = healthcheck.event) !== null && _h !== void 0 ? _h : event) !== null && _j !== void 0 ? _j : '',
|
|
672
|
+
input: decryptedInput !== null && decryptedInput !== void 0 ? decryptedInput : {},
|
|
673
|
+
retries,
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Build a stable fingerprint for the current healthcheck list so we only recreate workers when the set or config changes.
|
|
679
|
+
*/
|
|
680
|
+
healthcheckFingerprint(healthchecks) {
|
|
681
|
+
var _a, _b;
|
|
682
|
+
const parts = [];
|
|
683
|
+
for (const h of healthchecks) {
|
|
684
|
+
const intervalMs = (_a = h.interval) !== null && _a !== void 0 ? _a : 60000;
|
|
685
|
+
for (const env of (_b = h.envs) !== null && _b !== void 0 ? _b : []) {
|
|
686
|
+
parts.push(`${h.tag}:${env.slug}:${intervalMs}`);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
parts.sort();
|
|
690
|
+
return parts.join('|');
|
|
691
|
+
}
|
|
564
692
|
/**
|
|
565
693
|
* Start healthcheck workers for all products/environments after Redis is connected.
|
|
566
694
|
* This is called automatically in the constructor if redisClient is present.
|
|
695
|
+
* Dispatches to app, database, workflow, graph, storage, or message_broker processor based on probe type.
|
|
696
|
+
* Every HEALTHCHECK_REFRESH_MS we re-fetch the list and only clear/recreate workers when the fingerprint
|
|
697
|
+
* (tag:env:interval set) has changed, so existing timers are not reset when nothing changed.
|
|
567
698
|
*/
|
|
568
699
|
async startHealthcheckWorkers() {
|
|
569
|
-
// Fetch all products (or the current product if context is single-tenant)
|
|
570
|
-
// For demo, we use the current product only
|
|
571
700
|
await this.productBuilderService.initializeProductByTag(this.productTag);
|
|
572
701
|
const healthchecks = await this.productBuilderService.fetchProductHealthchecks();
|
|
702
|
+
const newFingerprint = this.healthcheckFingerprint(healthchecks);
|
|
703
|
+
if (this.healthcheckWorkerFingerprint === newFingerprint) {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
for (const id of this.healthcheckWorkerIntervals) {
|
|
707
|
+
clearInterval(id);
|
|
708
|
+
}
|
|
709
|
+
this.healthcheckWorkerIntervals = [];
|
|
710
|
+
this.healthcheckWorkerFingerprint = newFingerprint;
|
|
573
711
|
const privateKey = this.productBuilderService.fetchPrivateKey();
|
|
574
712
|
for (const healthcheck of healthchecks) {
|
|
575
713
|
for (const env of healthcheck.envs) {
|
|
576
|
-
|
|
577
|
-
const
|
|
578
|
-
setInterval(async () => {
|
|
714
|
+
const intervalMs = healthcheck.interval || 60000;
|
|
715
|
+
const id = setInterval(async () => {
|
|
579
716
|
try {
|
|
580
|
-
// Decrypt input for this env
|
|
581
717
|
let decryptedInput = env.input;
|
|
582
718
|
if (typeof decryptedInput === 'string') {
|
|
583
719
|
decryptedInput = JSON.parse((0, processor_utils_1.decrypt)(decryptedInput, privateKey));
|
|
584
720
|
}
|
|
585
|
-
|
|
586
|
-
const actionInput = {
|
|
587
|
-
env: env.slug,
|
|
588
|
-
product: this.productTag,
|
|
589
|
-
app: healthcheck.app,
|
|
590
|
-
input: decryptedInput,
|
|
591
|
-
action: healthcheck.event,
|
|
592
|
-
retries: healthcheck.retries || 0,
|
|
593
|
-
};
|
|
594
|
-
// Process the action
|
|
595
|
-
const result = await this.processAction(actionInput);
|
|
596
|
-
// Log result (success/failure)
|
|
721
|
+
const result = await this.runOneHealthcheck(healthcheck, env.slug, decryptedInput, this.productTag);
|
|
597
722
|
this.logService.add(Object.assign(Object.assign({}, this.baseLogs), { message: `Healthcheck processed for ${healthcheck.tag} in env ${env.slug}`, data: { result }, status: types_1.LogEventStatus.SUCCESS }));
|
|
598
723
|
}
|
|
599
724
|
catch (e) {
|
|
600
725
|
this.logService.add(Object.assign(Object.assign({}, this.baseLogs), { message: `Healthcheck failed for ${healthcheck.tag} in env ${env.slug}`, data: { error: e.toString() }, status: types_1.LogEventStatus.FAIL }));
|
|
601
726
|
}
|
|
602
|
-
},
|
|
727
|
+
}, intervalMs);
|
|
728
|
+
this.healthcheckWorkerIntervals.push(id);
|
|
603
729
|
}
|
|
604
730
|
}
|
|
731
|
+
if (this.healthcheckRefreshTimer == null) {
|
|
732
|
+
this.healthcheckRefreshTimer = setInterval(() => {
|
|
733
|
+
this.startHealthcheckWorkers();
|
|
734
|
+
}, ProcessorService.HEALTHCHECK_REFRESH_MS);
|
|
735
|
+
}
|
|
605
736
|
}
|
|
606
737
|
/**
|
|
607
|
-
* Manually trigger healthcheck processing for all healthchecks (can be called externally if needed)
|
|
738
|
+
* Manually trigger healthcheck processing for all healthchecks (can be called externally if needed).
|
|
739
|
+
* Dispatches to app, database, workflow, graph, storage, or message_broker processor based on probe type.
|
|
608
740
|
*/
|
|
609
741
|
async processAllHealthchecksForProduct(productTag) {
|
|
610
742
|
await this.productBuilderService.initializeProductByTag(productTag);
|
|
@@ -617,15 +749,7 @@ class ProcessorService {
|
|
|
617
749
|
if (typeof decryptedInput === 'string') {
|
|
618
750
|
decryptedInput = JSON.parse((0, processor_utils_1.decrypt)(decryptedInput, privateKey));
|
|
619
751
|
}
|
|
620
|
-
const
|
|
621
|
-
env: env.slug,
|
|
622
|
-
product: productTag,
|
|
623
|
-
app: healthcheck.app,
|
|
624
|
-
input: decryptedInput,
|
|
625
|
-
action: healthcheck.event,
|
|
626
|
-
retries: healthcheck.retries || 0,
|
|
627
|
-
};
|
|
628
|
-
const result = await this.processAction(actionInput);
|
|
752
|
+
const result = await this.runOneHealthcheck(healthcheck, env.slug, decryptedInput, productTag);
|
|
629
753
|
this.logService.add(Object.assign(Object.assign({}, this.baseLogs), { message: `Manual healthcheck processed for ${healthcheck.tag} in env ${env.slug}`, data: { result }, status: types_1.LogEventStatus.SUCCESS }));
|
|
630
754
|
}
|
|
631
755
|
catch (e) {
|
|
@@ -845,6 +969,7 @@ class ProcessorService {
|
|
|
845
969
|
//return res.link;
|
|
846
970
|
}
|
|
847
971
|
async intializeProduct(additional_logs) {
|
|
972
|
+
var _a;
|
|
848
973
|
if (!this.logService) {
|
|
849
974
|
this.logService = new logs_service_1.default({
|
|
850
975
|
product_id: this.productId,
|
|
@@ -853,6 +978,7 @@ class ProcessorService {
|
|
|
853
978
|
user_id: this.user_id,
|
|
854
979
|
token: this.token,
|
|
855
980
|
env_type: this.environment,
|
|
981
|
+
workspace_private_key: (_a = this._privateKey) !== null && _a !== void 0 ? _a : undefined,
|
|
856
982
|
});
|
|
857
983
|
}
|
|
858
984
|
try {
|
|
@@ -881,6 +1007,7 @@ class ProcessorService {
|
|
|
881
1007
|
}
|
|
882
1008
|
}
|
|
883
1009
|
async initializePricing(additional_logs, access_tag) {
|
|
1010
|
+
var _a, _b;
|
|
884
1011
|
if (!this.logService) {
|
|
885
1012
|
this.logService = new logs_service_1.default({
|
|
886
1013
|
product_id: this.productId,
|
|
@@ -889,6 +1016,7 @@ class ProcessorService {
|
|
|
889
1016
|
user_id: this.user_id,
|
|
890
1017
|
token: this.token,
|
|
891
1018
|
env_type: this.environment,
|
|
1019
|
+
workspace_private_key: (_a = this._privateKey) !== null && _a !== void 0 ? _a : undefined,
|
|
892
1020
|
});
|
|
893
1021
|
}
|
|
894
1022
|
try {
|
|
@@ -897,11 +1025,12 @@ class ProcessorService {
|
|
|
897
1025
|
debugLog(`Found product app: ${JSON.stringify(product_app)}`);
|
|
898
1026
|
const app = await this.productBuilderService.fetchThirdPartyAppByAccessTag(product_app.access_tag);
|
|
899
1027
|
await this.pricingService.initializePricingByTag(product_app.pricing_tag, app._id);
|
|
900
|
-
const
|
|
901
|
-
this.pricingTag = pricing_tag;
|
|
1028
|
+
const res = this.pricingService.fetchPricing();
|
|
1029
|
+
this.pricingTag = (_b = res === null || res === void 0 ? void 0 : res.pricing_tag) !== null && _b !== void 0 ? _b : 'free';
|
|
902
1030
|
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Pricing initialize - success', data: { pricing_tag: this.pricingTag }, status: types_1.LogEventStatus.SUCCESS }));
|
|
903
1031
|
}
|
|
904
1032
|
catch (e) {
|
|
1033
|
+
console.error('ERROR', e);
|
|
905
1034
|
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Pricing initialize - failed', data: e, status: types_1.LogEventStatus.FAIL }));
|
|
906
1035
|
throw e;
|
|
907
1036
|
}
|
|
@@ -1030,6 +1159,7 @@ class ProcessorService {
|
|
|
1030
1159
|
}
|
|
1031
1160
|
}
|
|
1032
1161
|
async generateStringValues(value, app, additional_logs, sample = [], index = {}, key = '', loopIndex = null) {
|
|
1162
|
+
var _a, _b;
|
|
1033
1163
|
value = (0, processor_utils_1.removeWrappingQuotes)(value);
|
|
1034
1164
|
const stages = this.productBuilderService.extractStages(value);
|
|
1035
1165
|
const locatorFor$Index = (0, string_utils_1.validateAndLocateTag)(value);
|
|
@@ -1081,6 +1211,16 @@ class ProcessorService {
|
|
|
1081
1211
|
else if (value === '$Date') {
|
|
1082
1212
|
return new Date().toISOString();
|
|
1083
1213
|
}
|
|
1214
|
+
else if ((0, secrets_1.containsSecretReferences)(value)) {
|
|
1215
|
+
// Resolve $Secret{key} or $secret{key} in action templates (headers, body, params, query)
|
|
1216
|
+
const secretsService = (0, secrets_1.getSecretsService)();
|
|
1217
|
+
if (!secretsService) {
|
|
1218
|
+
throw new Error('Action template contains secret references ($secret{...}) but secrets service is not initialized. Ensure secrets are configured for this environment.');
|
|
1219
|
+
}
|
|
1220
|
+
const envSlug = (_b = (_a = this.processEnv) === null || _a === void 0 ? void 0 : _a.slug) !== null && _b !== void 0 ? _b : '';
|
|
1221
|
+
const resolved = await secretsService.resolve(value, { env: envSlug });
|
|
1222
|
+
return resolved.value;
|
|
1223
|
+
}
|
|
1084
1224
|
else if (!value.startsWith('$')) {
|
|
1085
1225
|
// allow hardcoded values
|
|
1086
1226
|
return value;
|
|
@@ -1652,7 +1792,7 @@ class ProcessorService {
|
|
|
1652
1792
|
}
|
|
1653
1793
|
}
|
|
1654
1794
|
async runJobs(job, additional_logs = {}) {
|
|
1655
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
1795
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
1656
1796
|
const jobId = (_a = job.data) === null || _a === void 0 ? void 0 : _a._job_id;
|
|
1657
1797
|
const jobType = job.name;
|
|
1658
1798
|
const startedAt = Date.now();
|
|
@@ -1674,6 +1814,7 @@ class ProcessorService {
|
|
|
1674
1814
|
user_id: this.user_id,
|
|
1675
1815
|
token: this.token,
|
|
1676
1816
|
env_type: this.environment,
|
|
1817
|
+
workspace_private_key: (_g = this._privateKey) !== null && _g !== void 0 ? _g : undefined,
|
|
1677
1818
|
});
|
|
1678
1819
|
}
|
|
1679
1820
|
if (this.logService) {
|
|
@@ -1681,8 +1822,8 @@ class ProcessorService {
|
|
|
1681
1822
|
product_tag: productTag,
|
|
1682
1823
|
product_id: this.productId,
|
|
1683
1824
|
workspace_id: this.workspace_id,
|
|
1684
|
-
env: (
|
|
1685
|
-
process_id: jobId !== null && jobId !== void 0 ? jobId : (0,
|
|
1825
|
+
env: (_j = (_h = job.data) === null || _h === void 0 ? void 0 : _h.env) !== null && _j !== void 0 ? _j : '',
|
|
1826
|
+
process_id: jobId !== null && jobId !== void 0 ? jobId : (0, uuid_1.v4)(),
|
|
1686
1827
|
type: types_1.LogEventTypes.JOB,
|
|
1687
1828
|
parent_tag: jobParentTag,
|
|
1688
1829
|
child_tag: jobChildTag,
|
|
@@ -1690,8 +1831,8 @@ class ProcessorService {
|
|
|
1690
1831
|
data: {
|
|
1691
1832
|
job_id: jobId,
|
|
1692
1833
|
job_type: jobType,
|
|
1693
|
-
event: (
|
|
1694
|
-
env: (
|
|
1834
|
+
event: (_k = job.data) === null || _k === void 0 ? void 0 : _k.event,
|
|
1835
|
+
env: (_l = job.data) === null || _l === void 0 ? void 0 : _l.env,
|
|
1695
1836
|
},
|
|
1696
1837
|
status: types_1.LogEventStatus.PROCESSING,
|
|
1697
1838
|
start: startedAt,
|
|
@@ -1765,12 +1906,27 @@ class ProcessorService {
|
|
|
1765
1906
|
console.warn('[runJobs] Updating job execution phase (completed) without access_key', { jobId });
|
|
1766
1907
|
const operation = typeof job.event === 'string' && job.event.includes(':')
|
|
1767
1908
|
? job.event.split(':').pop()
|
|
1768
|
-
: (
|
|
1909
|
+
: (_m = job.event) !== null && _m !== void 0 ? _m : undefined;
|
|
1769
1910
|
const outputPayload = result != null
|
|
1770
1911
|
? typeof result === 'object' && result !== null && !Array.isArray(result)
|
|
1771
1912
|
? result
|
|
1772
1913
|
: { value: result }
|
|
1773
1914
|
: undefined;
|
|
1915
|
+
const resultMetadataPayload = result != null ? { result: typeof result === 'object' ? result : { value: result } } : undefined;
|
|
1916
|
+
let encryptedOutput;
|
|
1917
|
+
let encryptedResultMetadata;
|
|
1918
|
+
try {
|
|
1919
|
+
const privateKey = this.productBuilderService.fetchPrivateKey();
|
|
1920
|
+
if (outputPayload)
|
|
1921
|
+
encryptedOutput = (0, processor_utils_1.encrypt)(JSON.stringify(outputPayload), privateKey);
|
|
1922
|
+
if (resultMetadataPayload)
|
|
1923
|
+
encryptedResultMetadata = (0, processor_utils_1.encrypt)(JSON.stringify(resultMetadataPayload), privateKey);
|
|
1924
|
+
}
|
|
1925
|
+
catch (e) {
|
|
1926
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1927
|
+
console.warn('[runJobs] Skipping job execution output/result_metadata (encrypt failed)', { jobId, error: e });
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1774
1930
|
void this.processorApiService
|
|
1775
1931
|
.updateJobExecutionPhase({
|
|
1776
1932
|
workspace_id: this.workspace_id,
|
|
@@ -1778,8 +1934,8 @@ class ProcessorService {
|
|
|
1778
1934
|
phase: 'completed',
|
|
1779
1935
|
completed_at: completedAt,
|
|
1780
1936
|
duration_ms: durationMs,
|
|
1781
|
-
result_metadata:
|
|
1782
|
-
output:
|
|
1937
|
+
result_metadata: encryptedResultMetadata,
|
|
1938
|
+
output: encryptedOutput,
|
|
1783
1939
|
operation,
|
|
1784
1940
|
}, auth)
|
|
1785
1941
|
.catch((err) => console.error('[runJobs] job execution phase completed failed', { jobId, error: err }));
|
|
@@ -1787,10 +1943,10 @@ class ProcessorService {
|
|
|
1787
1943
|
// Log job execution completed so it shows in logs
|
|
1788
1944
|
if (this.logService) {
|
|
1789
1945
|
this.logService.add({
|
|
1790
|
-
product_tag: (
|
|
1946
|
+
product_tag: (_o = this.productTag) !== null && _o !== void 0 ? _o : (_p = job.data) === null || _p === void 0 ? void 0 : _p.product,
|
|
1791
1947
|
product_id: this.productId,
|
|
1792
1948
|
workspace_id: this.workspace_id,
|
|
1793
|
-
env: (
|
|
1949
|
+
env: (_r = (_q = job.data) === null || _q === void 0 ? void 0 : _q.env) !== null && _r !== void 0 ? _r : '',
|
|
1794
1950
|
process_id: jobId !== null && jobId !== void 0 ? jobId : this.process_id,
|
|
1795
1951
|
type: types_1.LogEventTypes.JOB,
|
|
1796
1952
|
parent_tag: jobParentTag,
|
|
@@ -1823,7 +1979,10 @@ class ProcessorService {
|
|
|
1823
1979
|
if (jobId && this.workspace_id) {
|
|
1824
1980
|
const auth = Object.assign(Object.assign({}, this.getUserAccess()), { access_key: this.accessKey });
|
|
1825
1981
|
if (!this.accessKey) {
|
|
1826
|
-
console.warn('[runJobs] Updating job execution phase without access_key — backend may return 401', {
|
|
1982
|
+
console.warn('[runJobs] Updating job execution phase without access_key — backend may return 401', {
|
|
1983
|
+
jobId,
|
|
1984
|
+
phase: 'retry_scheduled',
|
|
1985
|
+
});
|
|
1827
1986
|
}
|
|
1828
1987
|
void this.processorApiService
|
|
1829
1988
|
.updateJobExecutionPhase({
|
|
@@ -1865,12 +2024,14 @@ class ProcessorService {
|
|
|
1865
2024
|
if (jobId && this.workspace_id) {
|
|
1866
2025
|
const auth = Object.assign(Object.assign({}, this.getUserAccess()), { access_key: this.accessKey });
|
|
1867
2026
|
if (!this.accessKey) {
|
|
1868
|
-
console.warn('[runJobs] Updating job execution phase (failed) without access_key — backend may return 401', {
|
|
2027
|
+
console.warn('[runJobs] Updating job execution phase (failed) without access_key — backend may return 401', {
|
|
2028
|
+
jobId,
|
|
2029
|
+
});
|
|
1869
2030
|
}
|
|
1870
2031
|
const durationMs = (jobData === null || jobData === void 0 ? void 0 : jobData.started_at) != null ? failedAt - jobData.started_at : failedAt - startedAt;
|
|
1871
2032
|
const operation = typeof job.event === 'string' && job.event.includes(':')
|
|
1872
2033
|
? job.event.split(':').pop()
|
|
1873
|
-
: (
|
|
2034
|
+
: (_s = job.event) !== null && _s !== void 0 ? _s : undefined;
|
|
1874
2035
|
void this.processorApiService
|
|
1875
2036
|
.updateJobExecutionPhase({
|
|
1876
2037
|
workspace_id: this.workspace_id,
|
|
@@ -1887,10 +2048,10 @@ class ProcessorService {
|
|
|
1887
2048
|
// Log job execution failed so it shows in logs
|
|
1888
2049
|
if (this.logService) {
|
|
1889
2050
|
this.logService.add({
|
|
1890
|
-
product_tag: (
|
|
2051
|
+
product_tag: (_t = this.productTag) !== null && _t !== void 0 ? _t : (_u = job.data) === null || _u === void 0 ? void 0 : _u.product,
|
|
1891
2052
|
product_id: this.productId,
|
|
1892
2053
|
workspace_id: this.workspace_id,
|
|
1893
|
-
env: (
|
|
2054
|
+
env: (_w = (_v = job.data) === null || _v === void 0 ? void 0 : _v.env) !== null && _w !== void 0 ? _w : '',
|
|
1894
2055
|
process_id: jobId !== null && jobId !== void 0 ? jobId : this.process_id,
|
|
1895
2056
|
type: types_1.LogEventTypes.JOB,
|
|
1896
2057
|
parent_tag: jobParentTag,
|
|
@@ -1962,9 +2123,7 @@ class ProcessorService {
|
|
|
1962
2123
|
return;
|
|
1963
2124
|
const jobData = JSON.parse(data);
|
|
1964
2125
|
const oldStatus = jobData.status;
|
|
1965
|
-
const updatedJob = Object.assign(Object.assign(Object.assign({}, jobData), updates), { status, updated_at: Date.now(), execution_count: status === 'completed' || status === 'failed'
|
|
1966
|
-
? (jobData.execution_count || 0) + 1
|
|
1967
|
-
: jobData.execution_count });
|
|
2126
|
+
const updatedJob = Object.assign(Object.assign(Object.assign({}, jobData), updates), { status, updated_at: Date.now(), execution_count: status === 'completed' || status === 'failed' ? (jobData.execution_count || 0) + 1 : jobData.execution_count });
|
|
1968
2127
|
// Update job data
|
|
1969
2128
|
await redis.setex(jobKey, 90 * 24 * 60 * 60, JSON.stringify(updatedJob));
|
|
1970
2129
|
// Update status indices
|
|
@@ -1975,6 +2134,58 @@ class ProcessorService {
|
|
|
1975
2134
|
await redis.sadd(newStatusKey, jobId);
|
|
1976
2135
|
}
|
|
1977
2136
|
}
|
|
2137
|
+
/**
|
|
2138
|
+
* Cache key for action bootstrap. Same app + env + action = same version scope on backend.
|
|
2139
|
+
*/
|
|
2140
|
+
getActionBootstrapCacheKey(product_tag, app, env, action_tag) {
|
|
2141
|
+
return `${ACTION_BOOTSTRAP_REDIS_PREFIX}${this.workspace_id}:${product_tag || ''}:${app}:${env}:${action_tag}`;
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* Get cached action bootstrap (internal cache first, then Redis). Returns null on miss or error.
|
|
2145
|
+
*/
|
|
2146
|
+
async getCachedActionBootstrap(key) {
|
|
2147
|
+
const now = Date.now();
|
|
2148
|
+
const entry = this.actionBootstrapCache.get(key);
|
|
2149
|
+
if (entry && now - entry.storedAt < ACTION_BOOTSTRAP_CACHE_TTL_MS) {
|
|
2150
|
+
return entry.data;
|
|
2151
|
+
}
|
|
2152
|
+
if (entry) {
|
|
2153
|
+
this.actionBootstrapCache.delete(key);
|
|
2154
|
+
}
|
|
2155
|
+
if (!this.redisClient || !this._privateKey)
|
|
2156
|
+
return null;
|
|
2157
|
+
try {
|
|
2158
|
+
const redis = this.redisClient;
|
|
2159
|
+
const raw = await redis.get(key);
|
|
2160
|
+
if (!raw)
|
|
2161
|
+
return null;
|
|
2162
|
+
const decrypted = (0, processor_utils_1.decrypt)(raw, this._privateKey);
|
|
2163
|
+
const data = JSON.parse(decrypted);
|
|
2164
|
+
this.actionBootstrapCache.set(key, { data, storedAt: now });
|
|
2165
|
+
return data;
|
|
2166
|
+
}
|
|
2167
|
+
catch (_a) {
|
|
2168
|
+
return null;
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
/**
|
|
2172
|
+
* Store action bootstrap in internal cache and Redis (fire-and-forget for Redis). Encrypts with workspace key.
|
|
2173
|
+
*/
|
|
2174
|
+
setCachedActionBootstrap(key, data) {
|
|
2175
|
+
const now = Date.now();
|
|
2176
|
+
this.actionBootstrapCache.set(key, { data, storedAt: now });
|
|
2177
|
+
if (!this.redisClient || !this._privateKey)
|
|
2178
|
+
return;
|
|
2179
|
+
const ttlSeconds = Math.ceil(ACTION_BOOTSTRAP_CACHE_TTL_MS / 1000);
|
|
2180
|
+
try {
|
|
2181
|
+
const redis = this.redisClient;
|
|
2182
|
+
const encrypted = (0, processor_utils_1.encrypt)(JSON.stringify(data), this._privateKey);
|
|
2183
|
+
redis.setex(key, ttlSeconds, encrypted).catch(() => { });
|
|
2184
|
+
}
|
|
2185
|
+
catch (_a) {
|
|
2186
|
+
// ignore
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
1978
2189
|
/**
|
|
1979
2190
|
* Add job execution record to history
|
|
1980
2191
|
*/
|
|
@@ -2387,7 +2598,7 @@ class ProcessorService {
|
|
|
2387
2598
|
token: this.token,
|
|
2388
2599
|
env_type: this.environment,
|
|
2389
2600
|
private_key: this._privateKey,
|
|
2390
|
-
access_key: this.accessKey
|
|
2601
|
+
access_key: this.accessKey,
|
|
2391
2602
|
});
|
|
2392
2603
|
// Execute the workflow
|
|
2393
2604
|
const result = await workflowService.execute({
|
|
@@ -2532,7 +2743,7 @@ class ProcessorService {
|
|
|
2532
2743
|
return (0, processor_utils_1.generateIndexes)(operator, iter, init, valueValue);
|
|
2533
2744
|
}
|
|
2534
2745
|
async runAction(event, additional_logs, returnValue = true, bootstrapData) {
|
|
2535
|
-
var _a, _b, _c;
|
|
2746
|
+
var _a, _b, _c, _d;
|
|
2536
2747
|
try {
|
|
2537
2748
|
const { event: action_tag, app: access_tag, condition, cache: cache_tag } = event;
|
|
2538
2749
|
let indexes = [];
|
|
@@ -2563,6 +2774,8 @@ class ProcessorService {
|
|
|
2563
2774
|
app_active = bootstrapData.app_active;
|
|
2564
2775
|
app_env_slug = env.slug;
|
|
2565
2776
|
envMapping = (_a = bootstrapData.product_env_mapping) !== null && _a !== void 0 ? _a : null;
|
|
2777
|
+
// app_id is set in processAction on baseLogs from bootstrap; use it so logs/pricing get valid app_id
|
|
2778
|
+
app_id = (_b = this.baseLogs.app_id) !== null && _b !== void 0 ? _b : '';
|
|
2566
2779
|
additional_logs.app_env = app_env_slug;
|
|
2567
2780
|
}
|
|
2568
2781
|
else {
|
|
@@ -2571,7 +2784,7 @@ class ProcessorService {
|
|
|
2571
2784
|
const { actions, envs: appEnvs, retries: appRetries, workspace_id: appWorkspaceId, active } = appData;
|
|
2572
2785
|
const productApp = await this.productBuilderService.fetchApp(access_tag);
|
|
2573
2786
|
const { envs: productEnvs } = productApp;
|
|
2574
|
-
envMapping = (
|
|
2787
|
+
envMapping = (_c = productEnvs.find((item) => item.product_env_slug === this.processEnv.slug)) !== null && _c !== void 0 ? _c : null;
|
|
2575
2788
|
app_env_slug = (envMapping === null || envMapping === void 0 ? void 0 : envMapping.app_env_slug) || '';
|
|
2576
2789
|
additional_logs.app_env = app_env_slug;
|
|
2577
2790
|
env = appEnvs.find((item) => item.slug === app_env_slug);
|
|
@@ -2602,7 +2815,7 @@ class ProcessorService {
|
|
|
2602
2815
|
}
|
|
2603
2816
|
}
|
|
2604
2817
|
// Resolve {{variable}} and :variable in base_url with product env variables
|
|
2605
|
-
if ((
|
|
2818
|
+
if ((_d = envMapping === null || envMapping === void 0 ? void 0 : envMapping.variables) === null || _d === void 0 ? void 0 : _d.length) {
|
|
2606
2819
|
request_base_url = (0, string_utils_2.resolveBaseUrlVariables)(request_base_url, envMapping.variables);
|
|
2607
2820
|
}
|
|
2608
2821
|
const samples = {
|
|
@@ -2629,7 +2842,7 @@ class ProcessorService {
|
|
|
2629
2842
|
}, additional_logs);
|
|
2630
2843
|
if (check) {
|
|
2631
2844
|
result = JSON.parse(check);
|
|
2632
|
-
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Run action - response from cache', data: { result
|
|
2845
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Run action - response from cache', data: { result }, status: types_1.LogEventStatus.SUCCESS, cache_tag, action: event.event }));
|
|
2633
2846
|
if (returnValue) {
|
|
2634
2847
|
return result;
|
|
2635
2848
|
}
|
|
@@ -2690,12 +2903,14 @@ class ProcessorService {
|
|
|
2690
2903
|
const end = Date.now();
|
|
2691
2904
|
this.requestTime += end - start;
|
|
2692
2905
|
this.totalRequests += 1;
|
|
2693
|
-
const
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2906
|
+
const pricing = await this.processPricingCost(Object.assign(Object.assign({}, additional_logs), { app_id, workspace_id: this.workspace_id }));
|
|
2907
|
+
const log = Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Process http request - success', successful_execution: true, data: { response: results }, status: types_1.LogEventStatus.SUCCESS, app_id, action: event.event, start,
|
|
2908
|
+
end });
|
|
2909
|
+
if (pricing) {
|
|
2910
|
+
const { pricing_tag, pricing_cost, is_overage, currency } = pricing;
|
|
2911
|
+
Object.assign(log, { pricing_tag, pricing_cost, is_overage, currency });
|
|
2912
|
+
}
|
|
2913
|
+
this.logService.add(log);
|
|
2699
2914
|
await this.addToSuccessOutput(event, results, additional_logs);
|
|
2700
2915
|
if (returnValue) {
|
|
2701
2916
|
return { process_id: this.process_id, status: true, data: results };
|
|
@@ -2712,7 +2927,7 @@ class ProcessorService {
|
|
|
2712
2927
|
}
|
|
2713
2928
|
this.requestTime += end - start;
|
|
2714
2929
|
this.totalRequests += 1;
|
|
2715
|
-
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Process http request - failed', failed_execution: true, data: { e: error, input:
|
|
2930
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Process http request - failed', failed_execution: true, data: { e: error, input: payloads }, status: types_1.LogEventStatus.FAIL, app_id, action: event.event, start,
|
|
2716
2931
|
end }));
|
|
2717
2932
|
try {
|
|
2718
2933
|
debugLog(e);
|
|
@@ -2798,7 +3013,7 @@ class ProcessorService {
|
|
|
2798
3013
|
}
|
|
2799
3014
|
catch (e) {
|
|
2800
3015
|
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Process Pricing Cost - failed', data: { error: e }, status: types_1.LogEventStatus.FAIL }));
|
|
2801
|
-
|
|
3016
|
+
return null;
|
|
2802
3017
|
}
|
|
2803
3018
|
}
|
|
2804
3019
|
async addToSuccessOutput(event, output, additional_logs) {
|
|
@@ -2882,7 +3097,7 @@ class ProcessorService {
|
|
|
2882
3097
|
}
|
|
2883
3098
|
if (retries_left > 0) {
|
|
2884
3099
|
setTimeout(() => {
|
|
2885
|
-
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Retrying Request', data: Object.assign(Object.assign({}, output), { payload:
|
|
3100
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Retrying Request', data: Object.assign(Object.assign({}, output), { payload: output.payload }), status: types_1.LogEventStatus.PROCESSING }));
|
|
2886
3101
|
if (event.type === types_1.FeatureEventTypes.ACTION) {
|
|
2887
3102
|
this.processRequest(payload, event, policy, additional_logs);
|
|
2888
3103
|
}
|
|
@@ -2893,7 +3108,7 @@ class ProcessorService {
|
|
|
2893
3108
|
}
|
|
2894
3109
|
if (allow_fail === false && retries_left === 0) {
|
|
2895
3110
|
this.published = true;
|
|
2896
|
-
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Ran out of retries - failed', data: Object.assign(
|
|
3111
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Ran out of retries - failed', data: Object.assign({}, output), status: types_1.LogEventStatus.FAIL }));
|
|
2897
3112
|
//throw new Error("Run out of retries")
|
|
2898
3113
|
this.end = Date.now();
|
|
2899
3114
|
await this.writeResult(types_1.LogEventStatus.FAIL, retryable);
|
|
@@ -2946,13 +3161,13 @@ class ProcessorService {
|
|
|
2946
3161
|
return response.data;
|
|
2947
3162
|
}
|
|
2948
3163
|
catch (e) {
|
|
2949
|
-
|
|
3164
|
+
//// console.error("LOG ERROR", e);
|
|
2950
3165
|
throw e;
|
|
2951
3166
|
}
|
|
2952
3167
|
}
|
|
2953
3168
|
async processStorage(action) {
|
|
2954
3169
|
//TODO: schema validation
|
|
2955
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
3170
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2956
3171
|
const { env, input, retries, event, product: product_tag, session, cache, preloadedBootstrap } = action;
|
|
2957
3172
|
// event is "storage_tag:operation" (e.g. gcp-storage:upload); backend looks up storage by tag only
|
|
2958
3173
|
const storageTag = event.includes(':') ? event.split(':')[0] : event;
|
|
@@ -2973,7 +3188,7 @@ class ProcessorService {
|
|
|
2973
3188
|
this.clone = (0, processor_utils_1.structuredClone)(input);
|
|
2974
3189
|
(0, processor_utils_1.cleanBlob)(this.clone);
|
|
2975
3190
|
this.productTag = product_tag;
|
|
2976
|
-
const process_id = (0,
|
|
3191
|
+
const process_id = (0, uuid_1.v4)();
|
|
2977
3192
|
this.baseLogs = Object.assign({ product_tag: this.productTag, product_id: this.productId, workspace_id: this.workspace_id, env,
|
|
2978
3193
|
process_id, data: this.clone }, additional_logs);
|
|
2979
3194
|
// Use preloaded bootstrap when provided (e.g. workflow batch prefetch), otherwise fetch
|
|
@@ -3011,6 +3226,7 @@ class ProcessorService {
|
|
|
3011
3226
|
user_id: this.user_id,
|
|
3012
3227
|
token: this.token,
|
|
3013
3228
|
env_type: this.environment,
|
|
3229
|
+
workspace_private_key: (_a = this._privateKey) !== null && _a !== void 0 ? _a : undefined,
|
|
3014
3230
|
});
|
|
3015
3231
|
}
|
|
3016
3232
|
this.process_id = process_id;
|
|
@@ -3045,10 +3261,10 @@ class ProcessorService {
|
|
|
3045
3261
|
}
|
|
3046
3262
|
catch (e) {
|
|
3047
3263
|
const err = e;
|
|
3048
|
-
const apiReason = (
|
|
3264
|
+
const apiReason = (_c = (_b = err === null || err === void 0 ? void 0 : err.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.errors;
|
|
3049
3265
|
const reason = typeof apiReason === 'string'
|
|
3050
3266
|
? apiReason
|
|
3051
|
-
: (
|
|
3267
|
+
: (_h = (_g = (_d = apiReason === null || apiReason === void 0 ? void 0 : apiReason.message) !== null && _d !== void 0 ? _d : (_f = (_e = err === null || err === void 0 ? void 0 : err.response) === null || _e === void 0 ? void 0 : _e.data) === null || _f === void 0 ? void 0 : _f.message) !== null && _g !== void 0 ? _g : err === null || err === void 0 ? void 0 : err.message) !== null && _h !== void 0 ? _h : String(e);
|
|
3052
3268
|
const message = `Storing file - failed: ${reason}`;
|
|
3053
3269
|
this.end = Date.now();
|
|
3054
3270
|
if (this.logService) {
|
|
@@ -3074,7 +3290,7 @@ class ProcessorService {
|
|
|
3074
3290
|
await this.validateActionDataMappingInput(data.input, types_1.FeatureEventTypes.STORAGE);
|
|
3075
3291
|
this.start = Date.now();
|
|
3076
3292
|
this.productTag = data.product;
|
|
3077
|
-
const process_id = (0,
|
|
3293
|
+
const process_id = (0, uuid_1.v4)();
|
|
3078
3294
|
this.input = data;
|
|
3079
3295
|
this.baseLogs = Object.assign({ product_tag: this.productTag, product_id: this.productId, workspace_id: this.workspace_id, env: data.env, process_id, data: data.input }, additional_logs);
|
|
3080
3296
|
await this.intializeProduct(additional_logs);
|
|
@@ -3109,7 +3325,7 @@ class ProcessorService {
|
|
|
3109
3325
|
}
|
|
3110
3326
|
}
|
|
3111
3327
|
async processMessageBrokerPublish(data) {
|
|
3112
|
-
var _a, _b, _c, _d;
|
|
3328
|
+
var _a, _b, _c, _d, _e;
|
|
3113
3329
|
const [brokerTag, topicTag] = data.event.split(':');
|
|
3114
3330
|
if (!brokerTag || !topicTag) {
|
|
3115
3331
|
throw new Error(`message broker events should be in the format broker_tag:event_tag`);
|
|
@@ -3130,7 +3346,7 @@ class ProcessorService {
|
|
|
3130
3346
|
this.clone = (0, processor_utils_1.structuredClone)(data.input);
|
|
3131
3347
|
this.input = data;
|
|
3132
3348
|
this.productTag = data.product;
|
|
3133
|
-
const process_id = (0,
|
|
3349
|
+
const process_id = (0, uuid_1.v4)();
|
|
3134
3350
|
this.component = types_1.LogEventTypes.MESSAGEBROKER;
|
|
3135
3351
|
this.baseLogs = Object.assign({ product_tag: this.productTag, workspace_id: this.workspace_id, env: data.env, process_id, data: this.clone }, additional_logs);
|
|
3136
3352
|
await this.intializeProduct(additional_logs);
|
|
@@ -3144,6 +3360,7 @@ class ProcessorService {
|
|
|
3144
3360
|
user_id: this.user_id,
|
|
3145
3361
|
token: this.token,
|
|
3146
3362
|
env_type: this.environment,
|
|
3363
|
+
workspace_private_key: (_a = this._privateKey) !== null && _a !== void 0 ? _a : undefined,
|
|
3147
3364
|
});
|
|
3148
3365
|
}
|
|
3149
3366
|
// Process session if provided - verify and resolve $Session{} references
|
|
@@ -3180,7 +3397,7 @@ class ProcessorService {
|
|
|
3180
3397
|
};
|
|
3181
3398
|
const result = await this.runBrokerPublish(payload);
|
|
3182
3399
|
this.end = Date.now();
|
|
3183
|
-
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Produce to topic - success', data: { input:
|
|
3400
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Produce to topic - success', data: { input: this.clone, result: result !== null && result !== void 0 ? result : {} }, status: types_1.LogEventStatus.SUCCESS }));
|
|
3184
3401
|
await this.writeResult(types_1.LogEventStatus.SUCCESS);
|
|
3185
3402
|
// Fire-and-forget so step latency isn't dominated by log upload (20–50x slower otherwise)
|
|
3186
3403
|
this.logService.publish().catch(() => { });
|
|
@@ -3188,10 +3405,8 @@ class ProcessorService {
|
|
|
3188
3405
|
}
|
|
3189
3406
|
catch (e) {
|
|
3190
3407
|
const err = e;
|
|
3191
|
-
const apiReason = (
|
|
3192
|
-
const reason = typeof apiReason === 'string'
|
|
3193
|
-
? apiReason
|
|
3194
|
-
: (_d = (_c = apiReason === null || apiReason === void 0 ? void 0 : apiReason.message) !== null && _c !== void 0 ? _c : err === null || err === void 0 ? void 0 : err.message) !== null && _d !== void 0 ? _d : String(e);
|
|
3408
|
+
const apiReason = (_c = (_b = err === null || err === void 0 ? void 0 : err.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.errors;
|
|
3409
|
+
const reason = typeof apiReason === 'string' ? apiReason : (_e = (_d = apiReason === null || apiReason === void 0 ? void 0 : apiReason.message) !== null && _d !== void 0 ? _d : err === null || err === void 0 ? void 0 : err.message) !== null && _e !== void 0 ? _e : String(e);
|
|
3195
3410
|
const message = `Publishing to topic - failed: ${reason}`;
|
|
3196
3411
|
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message, data: { e, reason }, status: types_1.LogEventStatus.FAIL }));
|
|
3197
3412
|
this.end = Date.now();
|
|
@@ -3201,7 +3416,7 @@ class ProcessorService {
|
|
|
3201
3416
|
}
|
|
3202
3417
|
}
|
|
3203
3418
|
async processJob(job, additional_logs = {}) {
|
|
3204
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
3419
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
3205
3420
|
await this.productBuilderService.initializeProductByTag(job.product);
|
|
3206
3421
|
const productId = this.productBuilderService.fetchProductId();
|
|
3207
3422
|
if (productId)
|
|
@@ -3219,6 +3434,7 @@ class ProcessorService {
|
|
|
3219
3434
|
user_id: this.user_id,
|
|
3220
3435
|
token: this.token,
|
|
3221
3436
|
env_type: this.environment,
|
|
3437
|
+
workspace_private_key: (_a = this._privateKey) !== null && _a !== void 0 ? _a : undefined,
|
|
3222
3438
|
});
|
|
3223
3439
|
}
|
|
3224
3440
|
await this.validateActionDataMappingInput(job.input, productJob.type);
|
|
@@ -3230,13 +3446,16 @@ class ProcessorService {
|
|
|
3230
3446
|
let jobInput;
|
|
3231
3447
|
let namespace = productJob.type;
|
|
3232
3448
|
if (productJob.type === types_1.JobEventTypes.ACTION) {
|
|
3449
|
+
const actionName = typeof job.event === 'string' && job.event.includes(':')
|
|
3450
|
+
? job.event.split(':').pop()
|
|
3451
|
+
: job.event;
|
|
3233
3452
|
const input = {
|
|
3234
3453
|
env: job.env,
|
|
3235
3454
|
product: job.product,
|
|
3236
3455
|
app: productJob.app,
|
|
3237
3456
|
cache: job.cache,
|
|
3238
3457
|
input: job.input,
|
|
3239
|
-
action:
|
|
3458
|
+
action: actionName,
|
|
3240
3459
|
session: job.session,
|
|
3241
3460
|
};
|
|
3242
3461
|
jobInput = input;
|
|
@@ -3351,7 +3570,7 @@ class ProcessorService {
|
|
|
3351
3570
|
throw new Error(`Job type ${productJob.type} not supported`);
|
|
3352
3571
|
}
|
|
3353
3572
|
// Determine if this is a recurring job
|
|
3354
|
-
const isRecurring = !!(((
|
|
3573
|
+
const isRecurring = !!(((_b = job.repeat) === null || _b === void 0 ? void 0 : _b.cron) || ((_c = job.repeat) === null || _c === void 0 ? void 0 : _c.every));
|
|
3355
3574
|
// Generate a unique job ID
|
|
3356
3575
|
const jobId = `job_${(0, uuid_1.v4)().replace(/-/g, '').substring(0, 16)}`;
|
|
3357
3576
|
// Build queue options
|
|
@@ -3359,7 +3578,7 @@ class ProcessorService {
|
|
|
3359
3578
|
jobId,
|
|
3360
3579
|
};
|
|
3361
3580
|
// Handle `delay` only if repeat.every is not defined
|
|
3362
|
-
if (!((
|
|
3581
|
+
if (!((_d = job.repeat) === null || _d === void 0 ? void 0 : _d.every) && delay > 0) {
|
|
3363
3582
|
options.delay = delay;
|
|
3364
3583
|
}
|
|
3365
3584
|
// Add repeat config if defined
|
|
@@ -3408,17 +3627,17 @@ class ProcessorService {
|
|
|
3408
3627
|
app: productJob.app,
|
|
3409
3628
|
scheduled_at,
|
|
3410
3629
|
recurring: isRecurring,
|
|
3411
|
-
cron: (
|
|
3412
|
-
every: (
|
|
3630
|
+
cron: (_e = job.repeat) === null || _e === void 0 ? void 0 : _e.cron,
|
|
3631
|
+
every: (_f = job.repeat) === null || _f === void 0 ? void 0 : _f.every,
|
|
3413
3632
|
next_run_at,
|
|
3414
3633
|
execution_count: 0,
|
|
3415
|
-
limit: (
|
|
3416
|
-
end_date: ((
|
|
3634
|
+
limit: (_g = job.repeat) === null || _g === void 0 ? void 0 : _g.limit,
|
|
3635
|
+
end_date: ((_h = job.repeat) === null || _h === void 0 ? void 0 : _h.endDate)
|
|
3417
3636
|
? typeof job.repeat.endDate === 'string'
|
|
3418
3637
|
? new Date(job.repeat.endDate).getTime()
|
|
3419
3638
|
: job.repeat.endDate
|
|
3420
3639
|
: undefined,
|
|
3421
|
-
tz: (
|
|
3640
|
+
tz: (_j = job.repeat) === null || _j === void 0 ? void 0 : _j.tz,
|
|
3422
3641
|
retries: job.retries || 0,
|
|
3423
3642
|
retry_count: 0,
|
|
3424
3643
|
input: jobInput,
|
|
@@ -3442,11 +3661,11 @@ class ProcessorService {
|
|
|
3442
3661
|
// Add job input with the job ID for tracking
|
|
3443
3662
|
jobInput._job_id = jobId;
|
|
3444
3663
|
// Add job to queue
|
|
3445
|
-
if (!((
|
|
3664
|
+
if (!((_k = this.queues) === null || _k === void 0 ? void 0 : _k.jobs)) {
|
|
3446
3665
|
throw new Error('Queues not configured. dispatch() requires a queue connection.');
|
|
3447
3666
|
}
|
|
3448
3667
|
await this.queues.jobs.add(productJob.type, jobInput, options);
|
|
3449
|
-
// Record job execution in integrations (so jobexecutiontrackers table is populated)
|
|
3668
|
+
// Record job execution in integrations (so jobexecutiontrackers table is populated). Sensitive fields encrypted with product key.
|
|
3450
3669
|
if (this.workspace_id && this.productId) {
|
|
3451
3670
|
const auth = Object.assign(Object.assign({}, this.getUserAccess()), { access_key: this.accessKey });
|
|
3452
3671
|
if (!this.accessKey) {
|
|
@@ -3454,7 +3673,20 @@ class ProcessorService {
|
|
|
3454
3673
|
}
|
|
3455
3674
|
const operation = typeof job.event === 'string' && job.event.includes(':')
|
|
3456
3675
|
? job.event.split(':').pop()
|
|
3457
|
-
: (
|
|
3676
|
+
: (_l = job.event) !== null && _l !== void 0 ? _l : undefined;
|
|
3677
|
+
let encryptedInput;
|
|
3678
|
+
if (job.input != null && typeof job.input === 'object') {
|
|
3679
|
+
try {
|
|
3680
|
+
const privateKey = this.productBuilderService.fetchPrivateKey();
|
|
3681
|
+
const inputObj = (0, processor_utils_1.truncateInputForApi)(job.input);
|
|
3682
|
+
encryptedInput = (0, processor_utils_1.encrypt)(JSON.stringify(inputObj), privateKey);
|
|
3683
|
+
}
|
|
3684
|
+
catch (e) {
|
|
3685
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
3686
|
+
console.warn('[processJob] Skipping job execution input (encrypt failed)', { jobId, error: e });
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3458
3690
|
void this.processorApiService
|
|
3459
3691
|
.createJobExecution({
|
|
3460
3692
|
job_id: jobId,
|
|
@@ -3467,9 +3699,7 @@ class ProcessorService {
|
|
|
3467
3699
|
phase: delay > 0 ? 'scheduled' : 'queued',
|
|
3468
3700
|
scheduled_at: delay > 0 ? scheduled_at : undefined,
|
|
3469
3701
|
triggered_by: job.triggered_by,
|
|
3470
|
-
input:
|
|
3471
|
-
? (0, processor_utils_1.truncateInputForApi)(job.input)
|
|
3472
|
-
: undefined,
|
|
3702
|
+
input: encryptedInput,
|
|
3473
3703
|
operation,
|
|
3474
3704
|
}, auth)
|
|
3475
3705
|
.catch((err) => console.error('[processJob] job execution create failed', { jobId, error: err }));
|
|
@@ -3554,7 +3784,10 @@ class ProcessorService {
|
|
|
3554
3784
|
(0, processor_utils_1.validateNotification)(template, payload);
|
|
3555
3785
|
debugLog('[ProcessExpoNotification] Validation passed');
|
|
3556
3786
|
const { title, body, data } = (0, processor_utils_1.generateNotificationTemplate)(template, payload);
|
|
3557
|
-
debugLog('[ProcessExpoNotification] Template generated', {
|
|
3787
|
+
debugLog('[ProcessExpoNotification] Template generated', {
|
|
3788
|
+
title: (_b = title === null || title === void 0 ? void 0 : title.slice) === null || _b === void 0 ? void 0 : _b.call(title, 0, 40),
|
|
3789
|
+
bodyLength: body === null || body === void 0 ? void 0 : body.length,
|
|
3790
|
+
});
|
|
3558
3791
|
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: logType, message: 'Generate notification template - success', data: { title, body, data }, status: types_1.LogEventStatus.SUCCESS }));
|
|
3559
3792
|
debugLog('[ProcessExpoNotification] Sending to Expo');
|
|
3560
3793
|
await this.sendExpoNotification({ title, body, data }, payload.device_tokens);
|
|
@@ -3566,14 +3799,17 @@ class ProcessorService {
|
|
|
3566
3799
|
(0, processor_utils_1.validateNotification)(template, payload);
|
|
3567
3800
|
debugLog('[ProcessFirebaseNotification] Validation passed');
|
|
3568
3801
|
const { title, body, data } = (0, processor_utils_1.generateNotificationTemplate)(template, payload);
|
|
3569
|
-
debugLog('[ProcessFirebaseNotification] Template generated', {
|
|
3802
|
+
debugLog('[ProcessFirebaseNotification] Template generated', {
|
|
3803
|
+
title: (_b = title === null || title === void 0 ? void 0 : title.slice) === null || _b === void 0 ? void 0 : _b.call(title, 0, 40),
|
|
3804
|
+
bodyLength: body === null || body === void 0 ? void 0 : body.length,
|
|
3805
|
+
});
|
|
3570
3806
|
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 }));
|
|
3571
3807
|
debugLog('[ProcessFirebaseNotification] Sending to Firebase');
|
|
3572
3808
|
await this.sendFirebaseNotification({ title, body, data }, payload.device_tokens, notification.credentials, scope);
|
|
3573
3809
|
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 }));
|
|
3574
3810
|
}
|
|
3575
3811
|
async runNotification(notification, additional_logs, bootstrapData) {
|
|
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;
|
|
3812
|
+
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, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23;
|
|
3577
3813
|
const { event } = notification;
|
|
3578
3814
|
const input = notification.input;
|
|
3579
3815
|
const logMessageLog = (channelType, status, err) => {
|
|
@@ -3581,7 +3817,12 @@ class ProcessorService {
|
|
|
3581
3817
|
return;
|
|
3582
3818
|
this.fireAndForgetLogNotificationMessage(Object.assign({ workspace_id: this.workspace_id, product_id: this.productId, product_tag: bootstrapData.product_tag, env: bootstrapData.env, notification_tag: event, input: (input !== null && input !== void 0 ? input : {}), type: channelType, status, process_id: bootstrapData.process_id, retries: 0, session: bootstrapData.session, cache: bootstrapData.cache }, (status === 'failed' && err !== undefined && { error: err instanceof Error ? err.message : String(err) })));
|
|
3583
3819
|
};
|
|
3584
|
-
debugLog('[runNotification] ENTRY', {
|
|
3820
|
+
debugLog('[runNotification] ENTRY', {
|
|
3821
|
+
event,
|
|
3822
|
+
env: (_a = notification.env) === null || _a === void 0 ? void 0 : _a.slug,
|
|
3823
|
+
hasBootstrap: !!bootstrapData,
|
|
3824
|
+
inputKeys: input ? Object.keys(input) : [],
|
|
3825
|
+
});
|
|
3585
3826
|
try {
|
|
3586
3827
|
let notificationEvent;
|
|
3587
3828
|
let message;
|
|
@@ -3607,13 +3848,15 @@ class ProcessorService {
|
|
|
3607
3848
|
debugLog('[runNotification] ERROR: env config not found', { envSlug: (_c = notification.env) === null || _c === void 0 ? void 0 : _c.slug });
|
|
3608
3849
|
throw new Error(`Notification env config for ${notification.env.slug} not found`);
|
|
3609
3850
|
}
|
|
3610
|
-
let { push_notifications: notifications, emails, callbacks, sms: smses, } = envConfig;
|
|
3851
|
+
let { push_notifications: notifications, emails, callbacks, sms: smses, slack: slackConfig, discord: discordConfig } = envConfig;
|
|
3611
3852
|
debugLog('[runNotification] Env config channels', {
|
|
3612
3853
|
hasPush: !!notifications,
|
|
3613
3854
|
pushType: notifications === null || notifications === void 0 ? void 0 : notifications.type,
|
|
3614
3855
|
hasEmails: !!emails,
|
|
3615
3856
|
hasCallbacks: !!callbacks,
|
|
3616
3857
|
hasSms: !!smses,
|
|
3858
|
+
hasSlack: !!slackConfig,
|
|
3859
|
+
hasDiscord: !!discordConfig,
|
|
3617
3860
|
});
|
|
3618
3861
|
// Resolve any $Secret{} references in notification configs
|
|
3619
3862
|
const secretsService = (0, secrets_1.getSecretsService)();
|
|
@@ -3634,21 +3877,41 @@ class ProcessorService {
|
|
|
3634
3877
|
const resolved = await secretsService.resolve(smses, { env: notification.env.slug });
|
|
3635
3878
|
smses = resolved.value;
|
|
3636
3879
|
}
|
|
3880
|
+
if (slackConfig && (0, secrets_1.mightContainSecrets)(slackConfig)) {
|
|
3881
|
+
const resolved = await secretsService.resolve(slackConfig, { env: notification.env.slug });
|
|
3882
|
+
slackConfig = resolved.value;
|
|
3883
|
+
}
|
|
3884
|
+
if (discordConfig && (0, secrets_1.mightContainSecrets)(discordConfig)) {
|
|
3885
|
+
const resolved = await secretsService.resolve(discordConfig, { env: notification.env.slug });
|
|
3886
|
+
discordConfig = resolved.value;
|
|
3887
|
+
}
|
|
3637
3888
|
}
|
|
3638
|
-
const { push_notification: push, email, callback, sms } = message;
|
|
3889
|
+
const { push_notification: push, email, callback, sms, slack: slackMessage, discord: discordMessage } = message;
|
|
3639
3890
|
const notifScope = {
|
|
3640
3891
|
workspaceId: (_d = this.workspace_id) !== null && _d !== void 0 ? _d : '',
|
|
3641
3892
|
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
3893
|
};
|
|
3643
|
-
debugLog('[runNotification] Message template flags', {
|
|
3894
|
+
debugLog('[runNotification] Message template flags', {
|
|
3895
|
+
push: !!push,
|
|
3896
|
+
email: !!email,
|
|
3897
|
+
callback: !!callback,
|
|
3898
|
+
sms: !!sms,
|
|
3899
|
+
slack: !!slackMessage,
|
|
3900
|
+
discord: !!discordMessage,
|
|
3901
|
+
});
|
|
3644
3902
|
debugLog('[runNotification] Input channels present', {
|
|
3645
3903
|
push_notification: !!input.push_notification,
|
|
3646
3904
|
email: !!input.email,
|
|
3647
3905
|
callback: !!input.callback,
|
|
3648
3906
|
sms: !!input.sms,
|
|
3907
|
+
slack: !!input.slack,
|
|
3908
|
+
discord: !!input.discord,
|
|
3649
3909
|
});
|
|
3650
3910
|
if (!push && (input.push_notification || notifications)) {
|
|
3651
|
-
debugLog('[runNotification] PUSH: skipped (message has no push template)', {
|
|
3911
|
+
debugLog('[runNotification] PUSH: skipped (message has no push template)', {
|
|
3912
|
+
hasInputPush: !!input.push_notification,
|
|
3913
|
+
hasNotifications: !!notifications,
|
|
3914
|
+
});
|
|
3652
3915
|
}
|
|
3653
3916
|
if (push && !input.push_notification) {
|
|
3654
3917
|
debugLog('[runNotification] PUSH: skipped (no input.push_notification)');
|
|
@@ -3666,7 +3929,10 @@ class ProcessorService {
|
|
|
3666
3929
|
}));
|
|
3667
3930
|
//await this.inputService.validateInput(validationPayload, message.push_notification_data, "Push Notifications");
|
|
3668
3931
|
}
|
|
3669
|
-
if (push &&
|
|
3932
|
+
if (push &&
|
|
3933
|
+
input.push_notification &&
|
|
3934
|
+
(notifications === null || notifications === void 0 ? void 0 : notifications.type) !== types_1.Notifiers.EXPO &&
|
|
3935
|
+
(notifications === null || notifications === void 0 ? void 0 : notifications.type) !== types_1.Notifiers.FIREBASE) {
|
|
3670
3936
|
debugLog('[runNotification] PUSH: skipped (not Expo or Firebase)', { notificationsType: notifications === null || notifications === void 0 ? void 0 : notifications.type });
|
|
3671
3937
|
this.lastNotificationFailureType = types_1.LogEventTypes.PUSH;
|
|
3672
3938
|
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: types_1.LogEventTypes.PUSH, message: 'Push skipped - no Expo or Firebase provider configured', data: { push_type: notifications === null || notifications === void 0 ? void 0 : notifications.type }, status: types_1.LogEventStatus.SUCCESS }));
|
|
@@ -3731,7 +3997,10 @@ class ProcessorService {
|
|
|
3731
3997
|
subject,
|
|
3732
3998
|
template,
|
|
3733
3999
|
};
|
|
3734
|
-
debugLog('[runNotification] EMAIL: sending mail', {
|
|
4000
|
+
debugLog('[runNotification] EMAIL: sending mail', {
|
|
4001
|
+
to: (_g = mailOptions.to) === null || _g === void 0 ? void 0 : _g.length,
|
|
4002
|
+
subject: (_j = (_h = mailOptions.subject) === null || _h === void 0 ? void 0 : _h.slice) === null || _j === void 0 ? void 0 : _j.call(_h, 0, 50),
|
|
4003
|
+
});
|
|
3735
4004
|
try {
|
|
3736
4005
|
const transporter = await this.getMailTransporter(auth, notifScope);
|
|
3737
4006
|
await transporter.sendMail(mailOptions);
|
|
@@ -3771,7 +4040,11 @@ class ProcessorService {
|
|
|
3771
4040
|
//this.inputService.validateInput(validationPayload, message.callback_data);
|
|
3772
4041
|
const callbackUrl = callbacks === null || callbacks === void 0 ? void 0 : callbacks.url;
|
|
3773
4042
|
if (callbackUrl == null || callbackUrl === '') {
|
|
3774
|
-
throw new Error(`Callback config has no url. Env callback config: ${JSON.stringify({
|
|
4043
|
+
throw new Error(`Callback config has no url. Env callback config: ${JSON.stringify({
|
|
4044
|
+
url: callbacks === null || callbacks === void 0 ? void 0 : callbacks.url,
|
|
4045
|
+
method: callbacks === null || callbacks === void 0 ? void 0 : callbacks.method,
|
|
4046
|
+
keys: callbacks ? Object.keys(callbacks) : [],
|
|
4047
|
+
})}`);
|
|
3775
4048
|
}
|
|
3776
4049
|
const url = new URL(callbackUrl);
|
|
3777
4050
|
const requestPayload = {
|
|
@@ -3821,7 +4094,97 @@ class ProcessorService {
|
|
|
3821
4094
|
logMessageLog('sms', 'failed', e);
|
|
3822
4095
|
}
|
|
3823
4096
|
}
|
|
3824
|
-
|
|
4097
|
+
if (slackMessage && slackConfig && !input.slack) {
|
|
4098
|
+
debugLog('[runNotification] SLACK: skipped (no input.slack)');
|
|
4099
|
+
}
|
|
4100
|
+
if (slackMessage && slackConfig && input.slack) {
|
|
4101
|
+
const webhookUrl = typeof slackConfig === 'object' && slackConfig !== null && 'webhook_url' in slackConfig ? slackConfig.webhook_url : undefined;
|
|
4102
|
+
if (!webhookUrl) {
|
|
4103
|
+
debugLog('[runNotification] SLACK: skipped (no webhook_url in config)');
|
|
4104
|
+
}
|
|
4105
|
+
else {
|
|
4106
|
+
this.lastNotificationFailureType = types_1.LogEventTypes.SLACK;
|
|
4107
|
+
try {
|
|
4108
|
+
const slackData = message.slack_data;
|
|
4109
|
+
let text;
|
|
4110
|
+
let blocks = input.slack.blocks;
|
|
4111
|
+
if (slackData === null || slackData === void 0 ? void 0 : slackData.length) {
|
|
4112
|
+
const templateText = (_2 = (typeof slackMessage === 'object' && slackMessage !== null && 'text' in slackMessage ? slackMessage.text : null)) !== null && _2 !== void 0 ? _2 : '';
|
|
4113
|
+
const textInput = input.slack.text !== undefined ? input.slack.text : templateText;
|
|
4114
|
+
const textPayload = await this.generatePayload((typeof textInput === 'object' && textInput !== null ? textInput : { text: textInput }), notification, additional_logs, slackData.filter((d) => d.parent_key === 'text'));
|
|
4115
|
+
text = typeof textPayload === 'object' && textPayload !== null && 'text' in textPayload ? String((_3 = textPayload.text) !== null && _3 !== void 0 ? _3 : '') : String(textPayload !== null && textPayload !== void 0 ? textPayload : '');
|
|
4116
|
+
if (((_4 = input.slack.blocks) === null || _4 === void 0 ? void 0 : _4.length) && slackData.some((d) => d.parent_key === 'blocks')) {
|
|
4117
|
+
blocks = (await this.generatePayload({ blocks: input.slack.blocks }, notification, additional_logs, slackData.filter((d) => d.parent_key === 'blocks')));
|
|
4118
|
+
if (blocks && typeof blocks === 'object' && !Array.isArray(blocks) && 'blocks' in blocks)
|
|
4119
|
+
blocks = blocks.blocks;
|
|
4120
|
+
}
|
|
4121
|
+
}
|
|
4122
|
+
else {
|
|
4123
|
+
const textResolved = await (0, processor_utils_1.replacePlaceholderString)((_7 = (_5 = (typeof slackMessage === 'object' && slackMessage !== null && 'text' in slackMessage ? slackMessage.text : null)) !== null && _5 !== void 0 ? _5 : (_6 = input.slack) === null || _6 === void 0 ? void 0 : _6.text) !== null && _7 !== void 0 ? _7 : '', ((_8 = input.slack) !== null && _8 !== void 0 ? _8 : {}));
|
|
4124
|
+
text = typeof textResolved === 'string' ? textResolved : String((_10 = (_9 = input.slack) === null || _9 === void 0 ? void 0 : _9.text) !== null && _10 !== void 0 ? _10 : '');
|
|
4125
|
+
}
|
|
4126
|
+
const body = (blocks === null || blocks === void 0 ? void 0 : blocks.length) ? { blocks: blocks } : { text: text || '' };
|
|
4127
|
+
if (input.slack.channel)
|
|
4128
|
+
body.channel = input.slack.channel;
|
|
4129
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: types_1.LogEventTypes.SLACK, name: 'Send Slack - initiated', data: { hasText: !!text, hasBlocks: !!((_11 = input.slack.blocks) === null || _11 === void 0 ? void 0 : _11.length) }, status: types_1.LogEventStatus.SUCCESS }));
|
|
4130
|
+
await axios_1.default.post(webhookUrl, body, { headers: { 'Content-Type': 'application/json' }, timeout: 10000 });
|
|
4131
|
+
debugLog('[runNotification] SLACK: success');
|
|
4132
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: types_1.LogEventTypes.SLACK, name: 'Send Slack - success', successful_execution: true, data: {}, status: types_1.LogEventStatus.SUCCESS }));
|
|
4133
|
+
logMessageLog('slack', 'sent');
|
|
4134
|
+
}
|
|
4135
|
+
catch (e) {
|
|
4136
|
+
debugLog('[runNotification] SLACK: failed', e);
|
|
4137
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: types_1.LogEventTypes.SLACK, failed_execution: true, message: 'Send Slack - failed', data: { e }, status: types_1.LogEventStatus.FAIL }));
|
|
4138
|
+
logMessageLog('slack', 'failed', e);
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4141
|
+
}
|
|
4142
|
+
if (discordMessage && discordConfig && !input.discord) {
|
|
4143
|
+
debugLog('[runNotification] DISCORD: skipped (no input.discord)');
|
|
4144
|
+
}
|
|
4145
|
+
if (discordMessage && discordConfig && input.discord) {
|
|
4146
|
+
const webhookUrl = typeof discordConfig === 'object' && discordConfig !== null && 'webhook_url' in discordConfig ? discordConfig.webhook_url : undefined;
|
|
4147
|
+
if (!webhookUrl) {
|
|
4148
|
+
debugLog('[runNotification] DISCORD: skipped (no webhook_url in config)');
|
|
4149
|
+
}
|
|
4150
|
+
else {
|
|
4151
|
+
this.lastNotificationFailureType = types_1.LogEventTypes.DISCORD;
|
|
4152
|
+
try {
|
|
4153
|
+
const discordData = message.discord_data;
|
|
4154
|
+
let content;
|
|
4155
|
+
let embeds = input.discord.embeds;
|
|
4156
|
+
if (discordData === null || discordData === void 0 ? void 0 : discordData.length) {
|
|
4157
|
+
const templateContent = (_12 = (typeof discordMessage === 'object' && discordMessage !== null && 'content' in discordMessage ? discordMessage.content : null)) !== null && _12 !== void 0 ? _12 : '';
|
|
4158
|
+
const contentInput = input.discord.content !== undefined ? input.discord.content : templateContent;
|
|
4159
|
+
const contentPayload = await this.generatePayload((typeof contentInput === 'object' && contentInput !== null ? contentInput : { content: contentInput }), notification, additional_logs, discordData.filter((d) => d.parent_key === 'content'));
|
|
4160
|
+
content = typeof contentPayload === 'object' && contentPayload !== null && 'content' in contentPayload ? String((_13 = contentPayload.content) !== null && _13 !== void 0 ? _13 : '') : String(contentPayload !== null && contentPayload !== void 0 ? contentPayload : '');
|
|
4161
|
+
if (((_14 = input.discord.embeds) === null || _14 === void 0 ? void 0 : _14.length) && discordData.some((d) => d.parent_key === 'embeds')) {
|
|
4162
|
+
const embedsPayload = await this.generatePayload({ embeds: input.discord.embeds }, notification, additional_logs, discordData.filter((d) => d.parent_key === 'embeds'));
|
|
4163
|
+
if (embedsPayload && typeof embedsPayload === 'object' && 'embeds' in embedsPayload)
|
|
4164
|
+
embeds = embedsPayload.embeds;
|
|
4165
|
+
}
|
|
4166
|
+
}
|
|
4167
|
+
else {
|
|
4168
|
+
const contentResolved = await (0, processor_utils_1.replacePlaceholderString)((_17 = (_15 = (typeof discordMessage === 'object' && discordMessage !== null && 'content' in discordMessage ? discordMessage.content : null)) !== null && _15 !== void 0 ? _15 : (_16 = input.discord) === null || _16 === void 0 ? void 0 : _16.content) !== null && _17 !== void 0 ? _17 : '', ((_18 = input.discord) !== null && _18 !== void 0 ? _18 : {}));
|
|
4169
|
+
content = typeof contentResolved === 'string' ? contentResolved : String((_20 = (_19 = input.discord) === null || _19 === void 0 ? void 0 : _19.content) !== null && _20 !== void 0 ? _20 : '');
|
|
4170
|
+
}
|
|
4171
|
+
const body = (embeds === null || embeds === void 0 ? void 0 : embeds.length) ? { embeds: embeds } : { content: content || '' };
|
|
4172
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: types_1.LogEventTypes.DISCORD, name: 'Send Discord - initiated', data: { hasContent: !!content, hasEmbeds: !!((_21 = input.discord.embeds) === null || _21 === void 0 ? void 0 : _21.length) }, status: types_1.LogEventStatus.SUCCESS }));
|
|
4173
|
+
await axios_1.default.post(webhookUrl, body, { headers: { 'Content-Type': 'application/json' }, timeout: 10000 });
|
|
4174
|
+
debugLog('[runNotification] DISCORD: success');
|
|
4175
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: types_1.LogEventTypes.DISCORD, name: 'Send Discord - success', successful_execution: true, data: {}, status: types_1.LogEventStatus.SUCCESS }));
|
|
4176
|
+
logMessageLog('discord', 'sent');
|
|
4177
|
+
}
|
|
4178
|
+
catch (e) {
|
|
4179
|
+
debugLog('[runNotification] DISCORD: failed', e);
|
|
4180
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: types_1.LogEventTypes.DISCORD, failed_execution: true, message: 'Send Discord - failed', data: { e }, status: types_1.LogEventStatus.FAIL }));
|
|
4181
|
+
logMessageLog('discord', 'failed', e);
|
|
4182
|
+
}
|
|
4183
|
+
}
|
|
4184
|
+
}
|
|
4185
|
+
debugLog('[runNotification] DONE: all channels processed', {
|
|
4186
|
+
lastChannelType: (_22 = this.lastNotificationFailureType) !== null && _22 !== void 0 ? _22 : 'NOTIFICATIONS',
|
|
4187
|
+
});
|
|
3825
4188
|
// Only add aggregate success log when we have a subtype (no NOTIFICATIONS-typed logs)
|
|
3826
4189
|
/*if (this.lastNotificationFailureType != null) {
|
|
3827
4190
|
this.logService.add({
|
|
@@ -3835,7 +4198,10 @@ class ProcessorService {
|
|
|
3835
4198
|
}*/
|
|
3836
4199
|
}
|
|
3837
4200
|
catch (e) {
|
|
3838
|
-
debugLog('[runNotification] ERROR', {
|
|
4201
|
+
debugLog('[runNotification] ERROR', {
|
|
4202
|
+
error: e,
|
|
4203
|
+
lastChannelType: (_23 = this.lastNotificationFailureType) !== null && _23 !== void 0 ? _23 : 'NOTIFICATIONS',
|
|
4204
|
+
});
|
|
3839
4205
|
// Only add aggregate failure log when we have a subtype (no NOTIFICATIONS-typed logs)
|
|
3840
4206
|
if (this.lastNotificationFailureType != null) {
|
|
3841
4207
|
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 }));
|
|
@@ -3845,98 +4211,99 @@ class ProcessorService {
|
|
|
3845
4211
|
}
|
|
3846
4212
|
}
|
|
3847
4213
|
/*async runFunction(data: IFeatureEvent, additional_logs: Partial<ILogData>): Promise<any> {
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
4214
|
+
const { product_id, env } = data;
|
|
4215
|
+
const input = data.input as IFunctionRequest;
|
|
4216
|
+
|
|
4217
|
+
this.productId = product_id;
|
|
4218
|
+
|
|
4219
|
+
this.logService = new LogsService({
|
|
4220
|
+
product_id,
|
|
4221
|
+
workspace_id: this.workspace_id,
|
|
4222
|
+
public_key: this.public_key,
|
|
4223
|
+
user_id: this.user_id,
|
|
4224
|
+
token: this.token,
|
|
4225
|
+
env_type: this.environment,
|
|
4226
|
+
workspace_private_key: this._privateKey ?? undefined,
|
|
4227
|
+
});
|
|
4228
|
+
|
|
4229
|
+
const process_id = uuidv4();
|
|
4230
|
+
this.process_id = process_id;
|
|
4231
|
+
|
|
4232
|
+
|
|
4233
|
+
try {
|
|
4234
|
+
await this.intializeProduct(additional_logs);
|
|
4235
|
+
this.logService.add({
|
|
4236
|
+
...this.baseLogs,
|
|
4237
|
+
...additional_logs,
|
|
4238
|
+
message: 'Attempt function - initiated',
|
|
4239
|
+
data,
|
|
4240
|
+
status: LogEventStatus.PROCESSING,
|
|
3860
4241
|
});
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
data: { data, payload: input.payload },
|
|
3927
|
-
status: LogEventStatus.SUCCESS,
|
|
3928
|
-
});
|
|
3929
|
-
} catch (e) {
|
|
3930
|
-
this.logService.add({
|
|
3931
|
-
...this.baseLogs,
|
|
3932
|
-
...additional_logs,
|
|
3933
|
-
message: 'Run function - failed',
|
|
3934
|
-
data: e,
|
|
3935
|
-
status: LogEventStatus.FAIL,
|
|
3936
|
-
});
|
|
3937
|
-
await this.logService.publish();
|
|
3938
|
-
}
|
|
3939
|
-
}*/
|
|
4242
|
+
|
|
4243
|
+
this.logService.add({
|
|
4244
|
+
...this.baseLogs,
|
|
4245
|
+
...additional_logs,
|
|
4246
|
+
message: 'Fetch function - initiated',
|
|
4247
|
+
data: data,
|
|
4248
|
+
status: LogEventStatus.PROCESSING,
|
|
4249
|
+
});
|
|
4250
|
+
|
|
4251
|
+
const cloudFunction = await this.productBuilderService.fetchFunction(data.event);
|
|
4252
|
+
|
|
4253
|
+
this.logService.add({
|
|
4254
|
+
...this.baseLogs,
|
|
4255
|
+
...additional_logs,
|
|
4256
|
+
message: 'Fetch function - success',
|
|
4257
|
+
data: data,
|
|
4258
|
+
status: LogEventStatus.SUCCESS,
|
|
4259
|
+
});
|
|
4260
|
+
|
|
4261
|
+
this.logService.add({
|
|
4262
|
+
...this.baseLogs,
|
|
4263
|
+
...additional_logs,
|
|
4264
|
+
message: 'Validate function payload - initiated',
|
|
4265
|
+
data: { data, payload: input.payload },
|
|
4266
|
+
status: LogEventStatus.PROCESSING,
|
|
4267
|
+
});
|
|
4268
|
+
|
|
4269
|
+
validateFunctionInputKeys(cloudFunction.inputs, input.payload);
|
|
4270
|
+
|
|
4271
|
+
this.logService.add({
|
|
4272
|
+
...this.baseLogs,
|
|
4273
|
+
...additional_logs,
|
|
4274
|
+
message: 'Validate function payload - success',
|
|
4275
|
+
data: { data, payload: input.payload },
|
|
4276
|
+
status: LogEventStatus.SUCCESS,
|
|
4277
|
+
});
|
|
4278
|
+
|
|
4279
|
+
this.logService.add({
|
|
4280
|
+
...this.baseLogs,
|
|
4281
|
+
...additional_logs,
|
|
4282
|
+
message: 'Run function - initiated',
|
|
4283
|
+
data: { data, payload: input.payload },
|
|
4284
|
+
status: LogEventStatus.PROCESSING,
|
|
4285
|
+
});
|
|
4286
|
+
|
|
4287
|
+
const response = await makeFunctionsRequest(cloudFunction, input.payload);
|
|
4288
|
+
|
|
4289
|
+
this.logService.add({
|
|
4290
|
+
...this.baseLogs,
|
|
4291
|
+
...additional_logs,
|
|
4292
|
+
message: 'Run function - success',
|
|
4293
|
+
data: { data, payload: input.payload },
|
|
4294
|
+
status: LogEventStatus.SUCCESS,
|
|
4295
|
+
});
|
|
4296
|
+
} catch (e) {
|
|
4297
|
+
this.logService.add({
|
|
4298
|
+
...this.baseLogs,
|
|
4299
|
+
...additional_logs,
|
|
4300
|
+
message: 'Run function - failed',
|
|
4301
|
+
data: e,
|
|
4302
|
+
status: LogEventStatus.FAIL,
|
|
4303
|
+
});
|
|
4304
|
+
await this.logService.publish();
|
|
4305
|
+
}
|
|
4306
|
+
}*/
|
|
3940
4307
|
async runStorage(data, additional_logs = {}, bootstrapData) {
|
|
3941
4308
|
const { product_id, env, event, cache: cache_tag } = data;
|
|
3942
4309
|
const input = data.input;
|
|
@@ -4106,12 +4473,12 @@ class ProcessorService {
|
|
|
4106
4473
|
url = queueUrl.url;
|
|
4107
4474
|
}
|
|
4108
4475
|
/* this.logService.add({
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4476
|
+
...this.baseLogs,
|
|
4477
|
+
...additional_logs,
|
|
4478
|
+
message: 'Fetch broker details - success',
|
|
4479
|
+
data: { event, broker },
|
|
4480
|
+
status: LogEventStatus.SUCCESS,
|
|
4481
|
+
});*/
|
|
4115
4482
|
let brokerConfig = brokerEnv.config;
|
|
4116
4483
|
if (brokerConfig && (0, secrets_1.mightContainSecrets)(brokerConfig)) {
|
|
4117
4484
|
const secretsService = (0, secrets_1.getSecretsService)();
|
|
@@ -4137,9 +4504,7 @@ class ProcessorService {
|
|
|
4137
4504
|
catch (e) {
|
|
4138
4505
|
const err = e;
|
|
4139
4506
|
const apiReason = (_b = (_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.errors;
|
|
4140
|
-
const reason = typeof apiReason === 'string'
|
|
4141
|
-
? apiReason
|
|
4142
|
-
: (_d = (_c = apiReason === null || apiReason === void 0 ? void 0 : apiReason.message) !== null && _c !== void 0 ? _c : err === null || err === void 0 ? void 0 : err.message) !== null && _d !== void 0 ? _d : String(e);
|
|
4507
|
+
const reason = typeof apiReason === 'string' ? apiReason : (_d = (_c = apiReason === null || apiReason === void 0 ? void 0 : apiReason.message) !== null && _c !== void 0 ? _c : err === null || err === void 0 ? void 0 : err.message) !== null && _d !== void 0 ? _d : String(e);
|
|
4143
4508
|
const message = `Attempt publish to broker topic - failed: ${reason}`;
|
|
4144
4509
|
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { failed_execution: true, message, data: { e, reason }, status: types_1.LogEventStatus.FAIL }));
|
|
4145
4510
|
throw e;
|
|
@@ -4223,6 +4588,8 @@ class ProcessorService {
|
|
|
4223
4588
|
}
|
|
4224
4589
|
}
|
|
4225
4590
|
async writeResult(status, retryable = true) {
|
|
4591
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4592
|
+
const envSlug = (_f = (_d = (_b = (_a = this.processEnv) === null || _a === void 0 ? void 0 : _a.slug) !== null && _b !== void 0 ? _b : (_c = this.input) === null || _c === void 0 ? void 0 : _c.env) !== null && _d !== void 0 ? _d : (_e = this.baseLogs) === null || _e === void 0 ? void 0 : _e.env) !== null && _f !== void 0 ? _f : '';
|
|
4226
4593
|
this.processorApiService.saveResult({
|
|
4227
4594
|
status,
|
|
4228
4595
|
component: this.component,
|
|
@@ -4233,7 +4600,7 @@ class ProcessorService {
|
|
|
4233
4600
|
process_id: this.process_id,
|
|
4234
4601
|
feature_id: null,
|
|
4235
4602
|
product_id: this.productId,
|
|
4236
|
-
env:
|
|
4603
|
+
env: envSlug,
|
|
4237
4604
|
input: (0, processor_utils_1.encrypt)(JSON.stringify(this.input), this.productBuilderService.fetchPrivateKey()),
|
|
4238
4605
|
}, this.getUserAccess());
|
|
4239
4606
|
}
|
|
@@ -4246,8 +4613,10 @@ class ProcessorService {
|
|
|
4246
4613
|
const prefixed = {};
|
|
4247
4614
|
const nonPrefixed = {};
|
|
4248
4615
|
for (const [key, value] of Object.entries(credentials)) {
|
|
4249
|
-
if (key.startsWith('headers:') ||
|
|
4250
|
-
key.startsWith('
|
|
4616
|
+
if (key.startsWith('headers:') ||
|
|
4617
|
+
key.startsWith('body:') ||
|
|
4618
|
+
key.startsWith('params:') ||
|
|
4619
|
+
key.startsWith('query:')) {
|
|
4251
4620
|
prefixed[key] = value;
|
|
4252
4621
|
}
|
|
4253
4622
|
else {
|
|
@@ -4267,7 +4636,7 @@ class ProcessorService {
|
|
|
4267
4636
|
if (!sectionSchema || !sectionSchema.data)
|
|
4268
4637
|
return false;
|
|
4269
4638
|
// Check if the key exists in the schema's data array
|
|
4270
|
-
return sectionSchema.data.some(item => item.key === key);
|
|
4639
|
+
return sectionSchema.data.some((item) => item.key === key);
|
|
4271
4640
|
}
|
|
4272
4641
|
/**
|
|
4273
4642
|
* Apply prefixed credentials (e.g., 'headers:Authorization') to resolved input.
|
|
@@ -4334,7 +4703,7 @@ class ProcessorService {
|
|
|
4334
4703
|
async validateActionDataMappingInput(input, type) {
|
|
4335
4704
|
try {
|
|
4336
4705
|
if (type === types_1.FeatureEventTypes.ACTION || type === types_1.WebhookEventTypes.WEBHOOK_REGISTER) {
|
|
4337
|
-
await
|
|
4706
|
+
//await ActionInputSchema.validateAsync(input);
|
|
4338
4707
|
}
|
|
4339
4708
|
if (type === types_1.FeatureEventTypes.DB_ACTION) {
|
|
4340
4709
|
await create_productFeature_validator_1.DBActionInputSchema.validateAsync(input);
|
|
@@ -4349,8 +4718,15 @@ class ProcessorService {
|
|
|
4349
4718
|
}
|
|
4350
4719
|
}
|
|
4351
4720
|
async processAction(action) {
|
|
4352
|
-
|
|
4353
|
-
|
|
4721
|
+
var _a, _b, _c;
|
|
4722
|
+
await create_productFeature_validator_1.ActionProcessorInputSchema.validateAsync(action, { abortEarly: true }).catch((err) => {
|
|
4723
|
+
var _a, _b, _c, _d;
|
|
4724
|
+
throw new Error((_d = (_c = (_b = (_a = err.details) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) !== null && _c !== void 0 ? _c : err.message) !== null && _d !== void 0 ? _d : 'Invalid action input');
|
|
4725
|
+
});
|
|
4726
|
+
const { env, input, retries, action: event, app, product: product_tag, session, cache, preloadedBootstrap, } = action;
|
|
4727
|
+
// Backend bootstrap looks up action by short tag (e.g. list_countries). Normalize so both
|
|
4728
|
+
// "action:ductape:paystack:list_countries" (legacy/retry payloads) and "list_countries" work.
|
|
4729
|
+
const actionTagForBootstrap = typeof event === 'string' && event.includes(':') ? event.split(':').pop() : event;
|
|
4354
4730
|
const additional_logs = {
|
|
4355
4731
|
parent_tag: (0, string_utils_1.extractOriginAndTag)(app),
|
|
4356
4732
|
child_tag: event,
|
|
@@ -4364,12 +4740,14 @@ class ProcessorService {
|
|
|
4364
4740
|
try {
|
|
4365
4741
|
this.input = action;
|
|
4366
4742
|
this.start = Date.now();
|
|
4367
|
-
const process_id = (0,
|
|
4743
|
+
const process_id = (0, uuid_1.v4)();
|
|
4368
4744
|
if (product_tag) {
|
|
4369
4745
|
this.productTag = product_tag;
|
|
4370
4746
|
}
|
|
4371
4747
|
this.baseLogs = {
|
|
4372
4748
|
product_tag: this.productTag || '',
|
|
4749
|
+
parent_tag: app,
|
|
4750
|
+
child_tag: event,
|
|
4373
4751
|
workspace_id: this.workspace_id,
|
|
4374
4752
|
env,
|
|
4375
4753
|
type: types_1.LogEventTypes.ACTION,
|
|
@@ -4386,21 +4764,59 @@ class ProcessorService {
|
|
|
4386
4764
|
user_id: this.user_id,
|
|
4387
4765
|
token: this.token,
|
|
4388
4766
|
env_type: this.environment,
|
|
4767
|
+
workspace_private_key: (_a = this._privateKey) !== null && _a !== void 0 ? _a : undefined,
|
|
4389
4768
|
});
|
|
4390
4769
|
}
|
|
4391
|
-
// Use preloaded bootstrap when provided (e.g. workflow batch prefetch), otherwise fetch
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4770
|
+
// Use preloaded bootstrap when provided (e.g. workflow batch prefetch), otherwise fetch or read from cache
|
|
4771
|
+
let bootstrapData;
|
|
4772
|
+
if (preloadedBootstrap) {
|
|
4773
|
+
bootstrapData = preloadedBootstrap;
|
|
4774
|
+
}
|
|
4775
|
+
else {
|
|
4776
|
+
const bootstrapCacheKey = this.getActionBootstrapCacheKey(product_tag !== null && product_tag !== void 0 ? product_tag : '', app, env, actionTagForBootstrap);
|
|
4777
|
+
const cached = await this.getCachedActionBootstrap(bootstrapCacheKey);
|
|
4778
|
+
if (cached) {
|
|
4779
|
+
bootstrapData = cached;
|
|
4780
|
+
this.productBuilderService.applyBootstrapActionResult(bootstrapData, product_tag !== null && product_tag !== void 0 ? product_tag : undefined);
|
|
4781
|
+
}
|
|
4782
|
+
else {
|
|
4783
|
+
bootstrapData = (await this.productBuilderService.bootstrapAction({
|
|
4784
|
+
product_tag,
|
|
4785
|
+
env_slug: env,
|
|
4786
|
+
access_tag: app,
|
|
4787
|
+
action_tag: actionTagForBootstrap,
|
|
4788
|
+
}));
|
|
4789
|
+
this.setCachedActionBootstrap(bootstrapCacheKey, bootstrapData);
|
|
4790
|
+
}
|
|
4791
|
+
}
|
|
4400
4792
|
// Initialize from bootstrap data
|
|
4401
4793
|
if (bootstrapData.product_id) {
|
|
4402
4794
|
this.productId = bootstrapData.product_id;
|
|
4403
4795
|
}
|
|
4796
|
+
// console.log("BOOTSTRAP DATA", bootstrapData);
|
|
4797
|
+
if (!bootstrapData) {
|
|
4798
|
+
throw new Error('App not fetched');
|
|
4799
|
+
}
|
|
4800
|
+
// Only set app_id when valid (24-char hex); empty string would fail logs service ObjectId cast
|
|
4801
|
+
const appId = bootstrapData.app_id;
|
|
4802
|
+
if (appId && typeof appId === 'string') {
|
|
4803
|
+
this.baseLogs.app_id = appId;
|
|
4804
|
+
}
|
|
4805
|
+
this.baseLogs.app_tag = app;
|
|
4806
|
+
this.processEnv = {
|
|
4807
|
+
slug: (_b = bootstrapData.product_env_mapping) === null || _b === void 0 ? void 0 : _b.product_env_slug,
|
|
4808
|
+
app_slug: (_c = bootstrapData.product_env_mapping) === null || _c === void 0 ? void 0 : _c.app_env_slug,
|
|
4809
|
+
};
|
|
4810
|
+
// Ensure product is loaded so fetchPrivateKey() works (writeResult, cache, etc.)
|
|
4811
|
+
// Bootstrap may not set product when backend returns no private_key (e.g. access-key path); fallback to full init
|
|
4812
|
+
if (product_tag) {
|
|
4813
|
+
try {
|
|
4814
|
+
this.productBuilderService.fetchPrivateKey();
|
|
4815
|
+
}
|
|
4816
|
+
catch (_d) {
|
|
4817
|
+
await this.productBuilderService.initializeProductByTag(product_tag);
|
|
4818
|
+
}
|
|
4819
|
+
}
|
|
4404
4820
|
// Early cache check - after bootstrap so productBuilderService.product (and fetchPrivateKey) are set
|
|
4405
4821
|
if (cache && this.redisClient) {
|
|
4406
4822
|
const productCache = await this.productBuilderService.fetchCache(cache);
|
|
@@ -4414,7 +4830,7 @@ class ProcessorService {
|
|
|
4414
4830
|
}, additional_logs);
|
|
4415
4831
|
if (cachedResult) {
|
|
4416
4832
|
const result = JSON.parse(cachedResult);
|
|
4417
|
-
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Action response from cache (early check)', data: { result
|
|
4833
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Action response from cache (early check)', data: { result }, status: types_1.LogEventStatus.SUCCESS, cache_tag: cache, action: event }));
|
|
4418
4834
|
this.end = Date.now();
|
|
4419
4835
|
await this.logService.publish();
|
|
4420
4836
|
return result;
|
|
@@ -4524,7 +4940,7 @@ class ProcessorService {
|
|
|
4524
4940
|
product_env_mapping: bootstrapData.product_env_mapping,
|
|
4525
4941
|
});
|
|
4526
4942
|
this.end = Date.now();
|
|
4527
|
-
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Execute action - success', data: { input
|
|
4943
|
+
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Execute action - success', data: { input, result }, status: types_1.LogEventStatus.SUCCESS }));
|
|
4528
4944
|
await this.writeResult(types_1.LogEventStatus.SUCCESS);
|
|
4529
4945
|
await this.logService.publish();
|
|
4530
4946
|
return result;
|
|
@@ -4541,9 +4957,16 @@ class ProcessorService {
|
|
|
4541
4957
|
}
|
|
4542
4958
|
async processNotification(action) {
|
|
4543
4959
|
//TODO: schema validation
|
|
4544
|
-
var _a, _b, _c, _d, _e;
|
|
4960
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4545
4961
|
const { env, input, retries, event, product: product_tag, session, cache, preloadedBootstrap } = action;
|
|
4546
|
-
debugLog('[processNotification] ENTRY', {
|
|
4962
|
+
debugLog('[processNotification] ENTRY', {
|
|
4963
|
+
product: product_tag,
|
|
4964
|
+
env,
|
|
4965
|
+
event,
|
|
4966
|
+
inputKeys: input ? Object.keys(input) : [],
|
|
4967
|
+
hasSession: !!session,
|
|
4968
|
+
hasCache: !!cache,
|
|
4969
|
+
});
|
|
4547
4970
|
const [parent_tag, child_tag] = event.split(':');
|
|
4548
4971
|
if (!parent_tag || !child_tag) {
|
|
4549
4972
|
debugLog('[processNotification] ERROR: invalid event format', { event });
|
|
@@ -4569,7 +4992,7 @@ class ProcessorService {
|
|
|
4569
4992
|
await this.validateActionDataMappingInput(input, types_1.FeatureEventTypes.NOTIFICATION);
|
|
4570
4993
|
this.input = action;
|
|
4571
4994
|
this.start = Date.now();
|
|
4572
|
-
const process_id = (0,
|
|
4995
|
+
const process_id = (0, uuid_1.v4)();
|
|
4573
4996
|
debugLog('[processNotification] process_id', process_id);
|
|
4574
4997
|
this.baseLogs = Object.assign({ product_tag: this.productTag, workspace_id: this.workspace_id, env,
|
|
4575
4998
|
process_id, data: input }, additional_logs);
|
|
@@ -4583,7 +5006,12 @@ class ProcessorService {
|
|
|
4583
5006
|
notification_tag: parent_tag,
|
|
4584
5007
|
message_tag: child_tag,
|
|
4585
5008
|
});
|
|
4586
|
-
debugLog('[processNotification] Bootstrap result', {
|
|
5009
|
+
debugLog('[processNotification] Bootstrap result', {
|
|
5010
|
+
product_id: bootstrapData === null || bootstrapData === void 0 ? void 0 : bootstrapData.product_id,
|
|
5011
|
+
hasNotification: !!(bootstrapData === null || bootstrapData === void 0 ? void 0 : bootstrapData.notification),
|
|
5012
|
+
hasMessage: !!(bootstrapData === null || bootstrapData === void 0 ? void 0 : bootstrapData.message),
|
|
5013
|
+
envActive: (_a = bootstrapData === null || bootstrapData === void 0 ? void 0 : bootstrapData.env) === null || _a === void 0 ? void 0 : _a.active,
|
|
5014
|
+
});
|
|
4587
5015
|
// Initialize from bootstrap data
|
|
4588
5016
|
this.productId = bootstrapData.product_id;
|
|
4589
5017
|
this.processEnv = bootstrapData.env;
|
|
@@ -4596,6 +5024,7 @@ class ProcessorService {
|
|
|
4596
5024
|
user_id: this.user_id,
|
|
4597
5025
|
token: this.token,
|
|
4598
5026
|
env_type: this.environment,
|
|
5027
|
+
workspace_private_key: (_b = this._privateKey) !== null && _b !== void 0 ? _b : undefined,
|
|
4599
5028
|
});
|
|
4600
5029
|
}
|
|
4601
5030
|
this.process_id = process_id;
|
|
@@ -4631,8 +5060,11 @@ class ProcessorService {
|
|
|
4631
5060
|
allow_fail: false,
|
|
4632
5061
|
};
|
|
4633
5062
|
// Find the env config for the notification
|
|
4634
|
-
const envConfig = (
|
|
4635
|
-
debugLog('[processNotification] Calling runNotification', {
|
|
5063
|
+
const envConfig = (_c = bootstrapData.notification.envs) === null || _c === void 0 ? void 0 : _c.find((data) => data.slug === env);
|
|
5064
|
+
debugLog('[processNotification] Calling runNotification', {
|
|
5065
|
+
event,
|
|
5066
|
+
resolvedInputKeys: resolvedInput ? Object.keys(resolvedInput) : [],
|
|
5067
|
+
});
|
|
4636
5068
|
const result = await this.runNotification(payload, additional_logs, {
|
|
4637
5069
|
notification: bootstrapData.notification,
|
|
4638
5070
|
message: bootstrapData.message,
|
|
@@ -4644,7 +5076,11 @@ class ProcessorService {
|
|
|
4644
5076
|
cache,
|
|
4645
5077
|
});
|
|
4646
5078
|
this.end = Date.now();
|
|
4647
|
-
debugLog('[processNotification] SUCCESS', {
|
|
5079
|
+
debugLog('[processNotification] SUCCESS', {
|
|
5080
|
+
process_id,
|
|
5081
|
+
lastChannelType: (_d = this.lastNotificationFailureType) !== null && _d !== void 0 ? _d : 'NOTIFICATIONS',
|
|
5082
|
+
durationMs: this.end - this.start,
|
|
5083
|
+
});
|
|
4648
5084
|
// Only add success log when we have a subtype (no NOTIFICATIONS-typed logs)
|
|
4649
5085
|
/* if (this.lastNotificationFailureType != null) {
|
|
4650
5086
|
this.logService.add({
|
|
@@ -4664,8 +5100,11 @@ class ProcessorService {
|
|
|
4664
5100
|
}
|
|
4665
5101
|
catch (e) {
|
|
4666
5102
|
if (this.logService) {
|
|
4667
|
-
debugLog('[processNotification] FAILED', {
|
|
4668
|
-
|
|
5103
|
+
debugLog('[processNotification] FAILED', {
|
|
5104
|
+
error: e,
|
|
5105
|
+
lastChannelType: (_e = this.lastNotificationFailureType) !== null && _e !== void 0 ? _e : 'NOTIFICATIONS',
|
|
5106
|
+
});
|
|
5107
|
+
// console.error(e);
|
|
4669
5108
|
// Only add failure log when we have a subtype (no NOTIFICATIONS-typed logs)
|
|
4670
5109
|
if (this.lastNotificationFailureType != null) {
|
|
4671
5110
|
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { type: this.lastNotificationFailureType, message: 'Send notification - failed', data: { e: e.toString() }, status: types_1.LogEventStatus.FAIL }));
|
|
@@ -4675,14 +5114,26 @@ class ProcessorService {
|
|
|
4675
5114
|
}
|
|
4676
5115
|
// Fire-and-forget: log failed notification for reprocessing (only when we have productId from bootstrap). Use actual channel type when known.
|
|
4677
5116
|
if (this.productId && this.workspace_id) {
|
|
4678
|
-
const channelType = this.lastNotificationFailureType === types_1.LogEventTypes.PUSH
|
|
5117
|
+
const channelType = this.lastNotificationFailureType === types_1.LogEventTypes.PUSH
|
|
5118
|
+
? 'push'
|
|
5119
|
+
: this.lastNotificationFailureType === types_1.LogEventTypes.EMAIL
|
|
5120
|
+
? 'email'
|
|
5121
|
+
: this.lastNotificationFailureType === types_1.LogEventTypes.SMS
|
|
5122
|
+
? 'sms'
|
|
5123
|
+
: this.lastNotificationFailureType === types_1.LogEventTypes.CALLBACKS
|
|
5124
|
+
? 'callback'
|
|
5125
|
+
: this.lastNotificationFailureType === types_1.LogEventTypes.SLACK
|
|
5126
|
+
? 'slack'
|
|
5127
|
+
: this.lastNotificationFailureType === types_1.LogEventTypes.DISCORD
|
|
5128
|
+
? 'discord'
|
|
5129
|
+
: 'notification';
|
|
4679
5130
|
this.fireAndForgetLogNotificationMessage({
|
|
4680
5131
|
workspace_id: this.workspace_id,
|
|
4681
5132
|
product_id: this.productId,
|
|
4682
5133
|
product_tag,
|
|
4683
5134
|
env,
|
|
4684
5135
|
notification_tag: event,
|
|
4685
|
-
input: ((
|
|
5136
|
+
input: ((_f = resolvedInput !== null && resolvedInput !== void 0 ? resolvedInput : input) !== null && _f !== void 0 ? _f : {}),
|
|
4686
5137
|
type: channelType,
|
|
4687
5138
|
status: 'failed',
|
|
4688
5139
|
process_id: this.process_id,
|
|
@@ -4729,7 +5180,10 @@ class ProcessorService {
|
|
|
4729
5180
|
void this.processorApiService
|
|
4730
5181
|
.logNotificationMessage(Object.assign(Object.assign({}, payload), { input: inputToSend }), Object.assign(Object.assign({}, this.getUserAccess()), { access_key: this.accessKey }))
|
|
4731
5182
|
.then(() => debugLog('[fireAndForgetLogNotificationMessage] POST success', { process_id: payload.process_id }))
|
|
4732
|
-
.catch((err) => console.error('[fireAndForgetLogNotificationMessage] POST failed', {
|
|
5183
|
+
.catch((err) => console.error('[fireAndForgetLogNotificationMessage] POST failed', {
|
|
5184
|
+
process_id: payload.process_id,
|
|
5185
|
+
error: err,
|
|
5186
|
+
}));
|
|
4733
5187
|
}
|
|
4734
5188
|
/**
|
|
4735
5189
|
* Fetch notification message logs (send history) with time filters. Secured via user auth.
|
|
@@ -4811,7 +5265,8 @@ class ProcessorService {
|
|
|
4811
5265
|
expiresAt = new Date(timestamp + expiry);
|
|
4812
5266
|
}
|
|
4813
5267
|
// Use CacheService to store the value (fire-and-forget)
|
|
4814
|
-
this.cacheService
|
|
5268
|
+
this.cacheService
|
|
5269
|
+
.set({
|
|
4815
5270
|
product: product_tag,
|
|
4816
5271
|
cache: cache_tag,
|
|
4817
5272
|
key,
|
|
@@ -4819,9 +5274,11 @@ class ProcessorService {
|
|
|
4819
5274
|
componentTag: component_tag,
|
|
4820
5275
|
componentType: component_type,
|
|
4821
5276
|
expiry: expiresAt,
|
|
4822
|
-
})
|
|
5277
|
+
})
|
|
5278
|
+
.then(() => {
|
|
4823
5279
|
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Cache value stored', data: { key }, successful_execution: true, status: types_1.LogEventStatus.SUCCESS, cache_tag, cache_key: key }));
|
|
4824
|
-
})
|
|
5280
|
+
})
|
|
5281
|
+
.catch((error) => {
|
|
4825
5282
|
this.logService.add(Object.assign(Object.assign(Object.assign({}, this.baseLogs), additional_logs), { message: 'Cache store failed (non-blocking)', data: { key, error: String(error) }, status: types_1.LogEventStatus.FAIL, cache_tag, cache_key: key }));
|
|
4826
5283
|
});
|
|
4827
5284
|
}
|
|
@@ -4882,5 +5339,6 @@ class ProcessorService {
|
|
|
4882
5339
|
return this.productBuilderService.updateHealthcheck(productTag, { envs });
|
|
4883
5340
|
}
|
|
4884
5341
|
}
|
|
5342
|
+
ProcessorService.HEALTHCHECK_REFRESH_MS = 60000;
|
|
4885
5343
|
exports.default = ProcessorService;
|
|
4886
5344
|
//# sourceMappingURL=processor.service.js.map
|