@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.
Files changed (75) hide show
  1. package/dist/agents/agents.service.js +2 -0
  2. package/dist/agents/agents.service.js.map +1 -1
  3. package/dist/api/services/processorApi.service.d.ts +15 -10
  4. package/dist/api/services/processorApi.service.js +10 -2
  5. package/dist/api/services/processorApi.service.js.map +1 -1
  6. package/dist/api/services/productsApi.service.d.ts +1 -0
  7. package/dist/api/services/productsApi.service.js.map +1 -1
  8. package/dist/api/services/workspaceApi.service.js +4 -1
  9. package/dist/api/services/workspaceApi.service.js.map +1 -1
  10. package/dist/api/urls.js +3 -3
  11. package/dist/api/urls.js.map +1 -1
  12. package/dist/apps/services/app.service.d.ts +2 -1
  13. package/dist/apps/services/app.service.js +4 -1
  14. package/dist/apps/services/app.service.js.map +1 -1
  15. package/dist/brokers/brokers.service.js +1 -0
  16. package/dist/brokers/brokers.service.js.map +1 -1
  17. package/dist/brokers/types/index.d.ts +2 -0
  18. package/dist/cache/cache.service.d.ts +1 -0
  19. package/dist/cache/cache.service.js +2 -0
  20. package/dist/cache/cache.service.js.map +1 -1
  21. package/dist/cache/types/index.d.ts +2 -0
  22. package/dist/database/databases.service.js +2 -0
  23. package/dist/database/databases.service.js.map +1 -1
  24. package/dist/graph/graphs.service.js +2 -0
  25. package/dist/graph/graphs.service.js.map +1 -1
  26. package/dist/imports/imports.service.d.ts +1 -1
  27. package/dist/imports/imports.service.js +2 -2
  28. package/dist/imports/imports.service.js.map +1 -1
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.js +154 -128
  31. package/dist/index.js.map +1 -1
  32. package/dist/logs/logs.service.d.ts +3 -2
  33. package/dist/logs/logs.service.js +20 -5
  34. package/dist/logs/logs.service.js.map +1 -1
  35. package/dist/logs/logs.types.d.ts +6 -0
  36. package/dist/logs/logs.types.js +4 -0
  37. package/dist/logs/logs.types.js.map +1 -1
  38. package/dist/notifications/notifications.service.js +2 -0
  39. package/dist/notifications/notifications.service.js.map +1 -1
  40. package/dist/notifications/types/notifications.types.d.ts +4 -2
  41. package/dist/notifications/types/notifications.types.js +2 -0
  42. package/dist/notifications/types/notifications.types.js.map +1 -1
  43. package/dist/processor/services/processor.service.d.ts +53 -2
  44. package/dist/processor/services/processor.service.js +709 -251
  45. package/dist/processor/services/processor.service.js.map +1 -1
  46. package/dist/processor/utils/processor.utils.js +6 -1
  47. package/dist/processor/utils/processor.utils.js.map +1 -1
  48. package/dist/products/services/products.service.d.ts +26 -0
  49. package/dist/products/services/products.service.js +48 -1
  50. package/dist/products/services/products.service.js.map +1 -1
  51. package/dist/products/validators/joi-validators/create.productFeature.validator.d.ts +2 -0
  52. package/dist/products/validators/joi-validators/create.productFeature.validator.js +15 -1
  53. package/dist/products/validators/joi-validators/create.productFeature.validator.js.map +1 -1
  54. package/dist/resilience/healthcheck.service.d.ts +7 -3
  55. package/dist/resilience/healthcheck.service.js +82 -13
  56. package/dist/resilience/healthcheck.service.js.map +1 -1
  57. package/dist/sessions/sessions.service.js +1 -0
  58. package/dist/sessions/sessions.service.js.map +1 -1
  59. package/dist/sessions/types/index.d.ts +2 -0
  60. package/dist/storage/storage.service.js +2 -0
  61. package/dist/storage/storage.service.js.map +1 -1
  62. package/dist/types/processor.types.d.ts +2 -2
  63. package/dist/types/productsBuilder.types.d.ts +9 -0
  64. package/dist/types/productsBuilder.types.js.map +1 -1
  65. package/dist/utils/index.js +64 -6
  66. package/dist/utils/index.js.map +1 -1
  67. package/dist/vector/vector-database.service.d.ts +2 -0
  68. package/dist/vector/vector-database.service.js +3 -0
  69. package/dist/vector/vector-database.service.js.map +1 -1
  70. package/dist/workflows/workflow-executor.d.ts +2 -0
  71. package/dist/workflows/workflow-executor.js +17 -4
  72. package/dist/workflows/workflow-executor.js.map +1 -1
  73. package/dist/workflows/workflows.service.js +4 -2
  74. package/dist/workflows/workflows.service.js.map +1 -1
  75. package/package.json +3 -1
package/dist/index.js CHANGED
@@ -63,8 +63,8 @@ const productsApi_service_1 = require("./api/services/productsApi.service");
63
63
  const imports_service_1 = __importDefault(require("./imports/imports.service"));
64
64
  const processor_service_1 = __importDefault(require("./processor/services/processor.service"));
65
65
  const logs_service_1 = __importDefault(require("./logs/logs.service"));
66
+ const utils_1 = require("./utils");
66
67
  const mime = __importStar(require("mime-types"));
67
- const processor_utils_1 = require("./processor/utils/processor.utils");
68
68
  const database_1 = require("./database");
69
69
  const graph_1 = require("./graph");
70
70
  const workflows_1 = require("./workflows");
@@ -81,7 +81,7 @@ const cache_1 = require("./cache");
81
81
  const jobs_1 = require("./jobs");
82
82
  const secrets_1 = require("./secrets");
83
83
  const warehouse_1 = require("./warehouse");
84
- const utils_1 = require("./apps/utils");
84
+ const utils_2 = require("./apps/utils");
85
85
  /**
86
86
  * @typedef {Object} IProduct
87
87
  * @property {string} tag - Unique product tag.
@@ -2003,7 +2003,7 @@ class Ductape {
2003
2003
  const schedule = data.schedule || {};
2004
2004
  const startAt = typeof schedule.start_at === 'string' ? new Date(schedule.start_at).getTime() : schedule.start_at || Date.now();
2005
2005
  // Generate job tag based on type, notification, and event
2006
- const jobTag = `${(0, utils_1.tagify)(data.notification)}:${(0, utils_1.tagify)(data.event)}`;
2006
+ const jobTag = `${(0, utils_2.tagify)(data.notification)}:${(0, utils_2.tagify)(data.event)}`;
2007
2007
  // Check if job exists, if not create it
2008
2008
  const existingJob = await productBuilder.fetchJob(jobTag);
2009
2009
  if (!existingJob) {
@@ -2054,7 +2054,7 @@ class Ductape {
2054
2054
  * @param {string} [options.env] - Environment slug filter (e.g. prd).
2055
2055
  * @param {string} [options.notification_tag] - Notification event filter (e.g. rematch-notifications:order-placed).
2056
2056
  * @param {string} [options.status] - Status filter: pending | sent | failed | reprocessing.
2057
- * @param {string} [options.type] - Type filter: email | push | sms | callback | notification.
2057
+ * @param {string} [options.type] - Type filter: email | push | sms | callback | slack | discord | notification.
2058
2058
  * @param {string|Date} [options.start_date] - Start of time range (ISO string or Date).
2059
2059
  * @param {string|Date} [options.end_date] - End of time range (ISO string or Date).
2060
2060
  * @param {number} [options.page] - Page number (default 1).
@@ -4706,17 +4706,17 @@ class Ductape {
4706
4706
  const schedule = data.schedule || {};
4707
4707
  const startAt = typeof schedule.start_at === 'string' ? new Date(schedule.start_at).getTime() : schedule.start_at || Date.now();
4708
4708
  // Generate job tag based on type, app, and event
4709
- const jobTag = `action:${data.app}:${data.event}`;
4709
+ const jobTag = `action:${data.app}:${data.action}`;
4710
4710
  // Check if job exists, if not create it
4711
4711
  const existingJob = await productBuilder.fetchJob(jobTag);
4712
4712
  if (!existingJob) {
4713
4713
  await productBuilder.createJob({
4714
4714
  tag: jobTag,
4715
- name: `Action: ${data.app}/${data.event}`,
4716
- description: `Auto-created job for action ${data.event} on app ${data.app}`,
4715
+ name: `Action: ${data.app}/${data.action}`,
4716
+ description: `Auto-created job for action ${data.action} on app ${data.app}`,
4717
4717
  type: types_1.JobEventTypes.ACTION,
4718
4718
  app: data.app,
4719
- event: data.event,
4719
+ event: data.action,
4720
4720
  executions: 0,
4721
4721
  intervals: schedule.every || 0,
4722
4722
  start_at: startAt,
@@ -5026,7 +5026,7 @@ class Ductape {
5026
5026
  this.redis_url = redis_url;
5027
5027
  // Services are lazily initialized via factory methods (createNewDatabaseService, etc.)
5028
5028
  // This ensures initUserAuth() is called before service creation
5029
- //return createDeepProxy(this, this.environment);
5029
+ return (0, utils_1.createDeepProxy)(this, this.environment);
5030
5030
  }
5031
5031
  async loadBullMQ() {
5032
5032
  if (typeof window !== 'undefined') {
@@ -5045,118 +5045,129 @@ class Ductape {
5045
5045
  * @returns {Promise<void>} Resolves when Redis and queues are initialized.
5046
5046
  */
5047
5047
  async monitor() {
5048
- if (typeof window !== 'undefined') {
5049
- throw new Error('RedisService can only be used in a server environment.');
5050
- }
5051
- if (!this.redis_url) {
5052
- throw new Error('Redis URL is not provided.');
5053
- }
5054
- if (this.redisClient) {
5055
- // Already connected
5056
- return;
5057
- }
5058
- if (!this.public_key) {
5059
- await this.initUserAuth(false);
5060
- }
5061
- const Redis = await this.loadRedis();
5062
- const { Queue, Worker: BullWorker } = await this.loadBullMQ();
5063
- // Create Redis client with required options for BullMQ
5064
- this.redisClient = new Redis.default(this.redis_url, {
5065
- maxRetriesPerRequest: null, // Required by BullMQ
5066
- });
5067
- // Initialize job queues
5068
- this.jobsQueue = new Queue('ductape_jobs', {
5069
- connection: this.redisClient,
5070
- });
5071
- this.healthCheckQueue = new Queue('ductape_healthchecks', {
5072
- connection: this.redisClient,
5073
- });
5074
- this.healthCheckUpdaterQueue = new Queue('healthchecks-updater', {
5075
- connection: this.redisClient,
5076
- });
5077
- // Schedule healthcheck jobs for all products/environments
5078
- await this.scheduleAllHealthcheckJobs();
5079
- // Initialize job worker
5080
- this.jobsWorker = new BullWorker('ductape_jobs', async (job) => {
5081
- console.log(`Processing job ${job.id} of type ${job.name}`, job.data);
5082
- const processor = await this.createNewProcessor();
5083
- await processor.runJobs(job);
5084
- }, {
5085
- connection: this.redisClient,
5086
- });
5087
- // Initialize health check worker
5088
- this.healthCheckWorker = new BullWorker('ductape_healthchecks', async (job) => {
5089
- console.log(`Running health check job ${job.id}`, job.data);
5090
- const processor = await this.createNewProcessor();
5091
- console.log('FIND JOB!!!!', job.data);
5092
- if (job && job.data && Object.keys(job.data).length) {
5093
- // Call processAction with job.data
5094
- const result = await processor.processAction(job.data);
5095
- // Write result to Redis cache
5096
- await processor.writeHealthcheckResultToCache(job.data, Object.assign({ status: (result === null || result === void 0 ? void 0 : result.status) || 'unknown', lastChecked: Date.now() }, result));
5097
- // Re-enqueue the job for continuous healthchecks
5098
- //await this.scheduleHealthcheckJob(job.data);
5048
+ console.log('[MONITOR] monitor() called');
5049
+ try {
5050
+ if (typeof window !== 'undefined') {
5051
+ throw new Error('RedisService can only be used in a server environment.');
5099
5052
  }
5100
- }, {
5101
- connection: this.redisClient,
5102
- });
5103
- // Add a repeatable job to update DB every 10 minutes
5104
- await this.healthCheckUpdaterQueue.add('healthchecks-updater', {}, {
5105
- jobId: 'healthchecks-updater',
5106
- repeat: { every: 5 * 60 * 1000 },
5107
- });
5108
- // Healthcheck updater worker
5109
- this.healthCheckUpdaterWorker = new BullWorker('healthchecks-updater', async (job) => {
5110
- console.log('Init Processor for healthcheck Updater');
5111
- if (job.name !== 'healthchecks-updater')
5053
+ if (!this.redis_url) {
5054
+ throw new Error('Redis URL is not provided.');
5055
+ }
5056
+ // Skip full setup only if we already have queues and workers (full setup was done)
5057
+ if (this.redisClient && this.healthCheckQueue && this.healthCheckWorker) {
5058
+ console.log('[MONITOR] Already running (Redis + queues + workers present), skipping setup');
5112
5059
  return;
5113
- // Gather all healthcheck results from Redis
5114
- const keys = await this.redisClient.keys('healthcheck:*');
5115
- console.log('Found Keys for healthcheck updater', JSON.stringify(keys));
5116
- const envResults = {};
5117
- for (const key of keys) {
5118
- const [_, productTag, tag, envSlug] = key.split(':');
5119
- console.log(`${productTag} , ${tag}, ${envSlug}`);
5120
- const data = JSON.parse(await this.redisClient.get(key));
5121
- if (!envResults[productTag])
5122
- envResults[productTag] = {};
5123
- if (!envResults[productTag][tag])
5124
- envResults[productTag][tag] = {};
5125
- envResults[productTag][tag][envSlug] = data;
5126
5060
  }
5127
- for (const productTag in envResults) {
5128
- const tagsData = Object.entries(envResults[productTag]).map(([tag, envs]) => ({
5129
- tag,
5130
- environments: Object.entries(envs).map(([slug, data]) => (Object.assign({ slug }, data))),
5131
- }));
5132
- console.log();
5133
- const processor = await this.createNewProcessor();
5134
- console.log('PROCESSING ENV RESULT', productTag, tagsData);
5135
- await processor.updateHealthcheckOnProcessor(productTag, tagsData);
5061
+ if (!this.public_key) {
5062
+ await this.initUserAuth(false);
5136
5063
  }
5137
- }, {
5138
- connection: this.redisClient,
5139
- });
5140
- // Attach error listeners record failed phase on JobExecutionTracker when worker job fails
5141
- this.jobsWorker.on('failed', async (job, err) => {
5142
- var _a;
5143
- console.error(`Job ${job === null || job === void 0 ? void 0 : job.id} failed:`, err);
5144
- const jobId = (_a = job === null || job === void 0 ? void 0 : job.data) === null || _a === void 0 ? void 0 : _a._job_id;
5145
- if (jobId && this.workspace_id) {
5146
- try {
5064
+ if (!this.redisClient) {
5065
+ const Redis = await this.loadRedis();
5066
+ this.redisClient = new Redis.default(this.redis_url, {
5067
+ maxRetriesPerRequest: null, // Required by BullMQ
5068
+ });
5069
+ console.log('[MONITOR] Redis connected');
5070
+ }
5071
+ const { Queue, Worker: BullWorker } = await this.loadBullMQ();
5072
+ // Initialize job queues
5073
+ this.jobsQueue = new Queue('ductape_jobs', {
5074
+ connection: this.redisClient,
5075
+ });
5076
+ this.healthCheckQueue = new Queue('ductape_healthchecks', {
5077
+ connection: this.redisClient,
5078
+ });
5079
+ this.healthCheckUpdaterQueue = new Queue('healthchecks-updater', {
5080
+ connection: this.redisClient,
5081
+ });
5082
+ // Schedule healthcheck jobs for all products/environments
5083
+ await this.scheduleAllHealthcheckJobs();
5084
+ // Initialize job worker
5085
+ this.jobsWorker = new BullWorker('ductape_jobs', async (job) => {
5086
+ console.log(`Processing job ${job.id} of type ${job.name}`, job.data);
5087
+ const processor = await this.createNewProcessor();
5088
+ await processor.runJobs(job);
5089
+ }, {
5090
+ connection: this.redisClient,
5091
+ });
5092
+ // Initialize health check worker (uses ductape.health.run so probe types and secrets are handled by the health service)
5093
+ this.healthCheckWorker = new BullWorker('ductape_healthchecks', async (job) => {
5094
+ const data = job === null || job === void 0 ? void 0 : job.data;
5095
+ if (!(data === null || data === void 0 ? void 0 : data.tag) || !data.env || !data.product)
5096
+ return;
5097
+ const healthcheckService = await this.createNewHealthcheckService();
5098
+ await healthcheckService.run({
5099
+ product: data.product,
5100
+ env: data.env,
5101
+ tag: data.tag,
5102
+ });
5103
+ }, {
5104
+ connection: this.redisClient,
5105
+ });
5106
+ // Add a repeatable job to update DB every 10 minutes
5107
+ await this.healthCheckUpdaterQueue.add('healthchecks-updater', {}, {
5108
+ jobId: 'healthchecks-updater',
5109
+ repeat: { every: 5 * 60 * 1000 },
5110
+ });
5111
+ // Healthcheck updater worker
5112
+ this.healthCheckUpdaterWorker = new BullWorker('healthchecks-updater', async (job) => {
5113
+ console.log('Init Processor for healthcheck Updater');
5114
+ if (job.name !== 'healthchecks-updater')
5115
+ return;
5116
+ // Gather all healthcheck results from Redis
5117
+ const keys = await this.redisClient.keys('healthcheck:*');
5118
+ console.log('Found Keys for healthcheck updater', JSON.stringify(keys));
5119
+ const envResults = {};
5120
+ for (const key of keys) {
5121
+ const [_, productTag, tag, envSlug] = key.split(':');
5122
+ console.log(`${productTag} , ${tag}, ${envSlug}`);
5123
+ const data = JSON.parse(await this.redisClient.get(key));
5124
+ if (!envResults[productTag])
5125
+ envResults[productTag] = {};
5126
+ if (!envResults[productTag][tag])
5127
+ envResults[productTag][tag] = {};
5128
+ envResults[productTag][tag][envSlug] = data;
5129
+ }
5130
+ for (const productTag in envResults) {
5131
+ const tagsData = Object.entries(envResults[productTag]).map(([tag, envs]) => ({
5132
+ tag,
5133
+ environments: Object.entries(envs).map(([slug, data]) => (Object.assign({ slug }, data))),
5134
+ }));
5135
+ console.log();
5147
5136
  const processor = await this.createNewProcessor();
5148
- const msg = err instanceof Error ? err.message : String(err);
5149
- const code = err && typeof err.code === 'string' ? err.code : undefined;
5150
- await processor.recordJobExecutionPhaseFailed(jobId, msg, code);
5137
+ console.log('PROCESSING ENV RESULT', productTag, tagsData);
5138
+ await processor.updateHealthcheckOnProcessor(productTag, tagsData);
5151
5139
  }
5152
- catch (e) {
5153
- console.error('[jobsWorker] failed to record job execution phase (failed)', { jobId, error: e });
5140
+ }, {
5141
+ connection: this.redisClient,
5142
+ });
5143
+ // Attach error listeners — record failed phase on JobExecutionTracker when worker job fails
5144
+ this.jobsWorker.on('failed', async (job, err) => {
5145
+ var _a;
5146
+ console.error(`Job ${job === null || job === void 0 ? void 0 : job.id} failed:`, err);
5147
+ const jobId = (_a = job === null || job === void 0 ? void 0 : job.data) === null || _a === void 0 ? void 0 : _a._job_id;
5148
+ if (jobId && this.workspace_id) {
5149
+ try {
5150
+ const processor = await this.createNewProcessor();
5151
+ const msg = err instanceof Error ? err.message : String(err);
5152
+ const code = err && typeof err.code === 'string' ? err.code : undefined;
5153
+ await processor.recordJobExecutionPhaseFailed(jobId, msg, code);
5154
+ }
5155
+ catch (e) {
5156
+ console.error('[jobsWorker] failed to record job execution phase (failed)', { jobId, error: e });
5157
+ }
5154
5158
  }
5155
- }
5156
- });
5157
- this.healthCheckWorker.on('failed', (job, err) => {
5158
- console.error(`Health check ${job === null || job === void 0 ? void 0 : job.id} failed:`, err);
5159
- });
5159
+ });
5160
+ this.healthCheckWorker.on('failed', (job, err) => {
5161
+ console.error(`Health check ${job === null || job === void 0 ? void 0 : job.id} failed:`, err);
5162
+ });
5163
+ console.log('[MONITOR] Setup complete: Redis, job queue, healthcheck queue and workers are running. Process will stay alive for scheduled jobs.');
5164
+ }
5165
+ catch (e) {
5166
+ console.error('[MONITOR] monitor() error:', e);
5167
+ if (e instanceof Error)
5168
+ console.error('[MONITOR] stack:', e.stack);
5169
+ throw e;
5170
+ }
5160
5171
  }
5161
5172
  /**
5162
5173
  * Schedules all healthcheck jobs for all products and environments.
@@ -5170,36 +5181,40 @@ class Ductape {
5170
5181
  user_id: this.user_id,
5171
5182
  workspace_id: this.workspace_id,
5172
5183
  }));
5184
+ console.log(`[MONITOR] Scheduling healthcheck jobs for ${Array.isArray(products) ? products.length : 0} product(s)`);
5185
+ const auth = {
5186
+ token: this.token,
5187
+ public_key: this.public_key,
5188
+ user_id: this.user_id,
5189
+ workspace_id: this.workspace_id,
5190
+ access_key: this.accessKey,
5191
+ };
5192
+ let scheduledCount = 0;
5173
5193
  for (const product of products) {
5174
- const healthchecks = product.healthchecks || [];
5175
- const privateKey = product.private_key;
5194
+ const productId = product._id != null ? String(product._id) : null;
5195
+ const healthchecks = productId != null
5196
+ ? (await this.productsApi.fetchProductComponents(productId, 'healthcheck', auth)) || []
5197
+ : product.healthchecks || [];
5176
5198
  for (const healthcheck of healthchecks) {
5177
5199
  for (const env of healthcheck.envs) {
5178
- let decryptedInput = env.input;
5179
- if (typeof decryptedInput === 'string') {
5180
- decryptedInput = JSON.parse((0, processor_utils_1.decrypt)(decryptedInput, privateKey));
5181
- }
5182
5200
  const jobData = {
5183
- healthcheck: healthcheck.tag,
5184
- env: env.slug,
5185
5201
  product: product.tag,
5186
- app: healthcheck.app,
5187
- input: decryptedInput,
5188
- event: healthcheck.event,
5189
- retries: healthcheck.retries || 0,
5202
+ env: env.slug,
5203
+ tag: healthcheck.tag,
5190
5204
  };
5191
5205
  const jobId = `healthcheck-exec-${healthcheck.tag}-${env.slug}`;
5192
5206
  await this.scheduleHealthcheckJob(jobId, jobData, healthcheck.interval);
5207
+ scheduledCount++;
5193
5208
  }
5194
5209
  }
5195
5210
  }
5211
+ console.log(`[MONITOR] Scheduled ${scheduledCount} healthcheck job(s)`);
5196
5212
  }
5197
5213
  /**
5198
5214
  * Schedules a single healthcheck job with the given interval (ms).
5199
5215
  * If interval is not provided, defaults to 60s.
5200
5216
  */
5201
5217
  async scheduleHealthcheckJob(jobId, jobData, interval) {
5202
- console.log('JOBBERMAN', { jobId, jobData, interval });
5203
5218
  const job = await this.healthCheckQueue.getJob(jobId);
5204
5219
  if (job) {
5205
5220
  await job.remove();
@@ -5298,11 +5313,12 @@ class Ductape {
5298
5313
  }
5299
5314
  catch (e) {
5300
5315
  const error = ((_b = (_a = e.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.errors) || e.message || 'Unknown error';
5301
- console.log("Errr", e);
5316
+ console.log('Errr', e);
5302
5317
  throw new Error(error);
5303
5318
  }
5304
5319
  }
5305
5320
  createNewLogger(product_id, app_id) {
5321
+ var _a;
5306
5322
  return new logs_service_1.default({
5307
5323
  workspace_id: this.workspace_id,
5308
5324
  public_key: this.public_key,
@@ -5311,6 +5327,7 @@ class Ductape {
5311
5327
  product_id,
5312
5328
  env_type: this.environment,
5313
5329
  app_id,
5330
+ workspace_private_key: (_a = this._privateKey) !== null && _a !== void 0 ? _a : undefined,
5314
5331
  });
5315
5332
  }
5316
5333
  async createNewProductBuilder() {
@@ -5534,6 +5551,7 @@ class Ductape {
5534
5551
  * @returns CacheService instance
5535
5552
  */
5536
5553
  async createNewCacheService() {
5554
+ var _a;
5537
5555
  const subCheck = false;
5538
5556
  await this.initUserAuth(subCheck);
5539
5557
  if (!this._cacheService) {
@@ -5544,6 +5562,7 @@ class Ductape {
5544
5562
  token: this.token,
5545
5563
  env_type: this.environment,
5546
5564
  access_key: this.accessKey,
5565
+ workspace_private_key: (_a = this._privateKey) !== null && _a !== void 0 ? _a : undefined,
5547
5566
  });
5548
5567
  }
5549
5568
  return this._cacheService;
@@ -5614,6 +5633,7 @@ class Ductape {
5614
5633
  * @returns SessionsService instance
5615
5634
  */
5616
5635
  async createNewSessionsService() {
5636
+ var _a;
5617
5637
  const subCheck = false;
5618
5638
  await this.initUserAuth(subCheck);
5619
5639
  return new sessions_1.SessionsService({
@@ -5624,6 +5644,7 @@ class Ductape {
5624
5644
  env_type: this.environment,
5625
5645
  access_key: this.accessKey,
5626
5646
  redis_client: this.redisClient,
5647
+ workspace_private_key: (_a = this._privateKey) !== null && _a !== void 0 ? _a : undefined,
5627
5648
  });
5628
5649
  }
5629
5650
  /**
@@ -5652,6 +5673,7 @@ class Ductape {
5652
5673
  * @returns BrokersService instance
5653
5674
  */
5654
5675
  async createNewBrokersService() {
5676
+ var _a;
5655
5677
  // Return cached instance if available
5656
5678
  if (this._brokersService) {
5657
5679
  return this._brokersService;
@@ -5667,6 +5689,7 @@ class Ductape {
5667
5689
  token: this.token,
5668
5690
  env_type: this.environment,
5669
5691
  access_key: this.accessKey,
5692
+ workspace_private_key: (_a = this._privateKey) !== null && _a !== void 0 ? _a : undefined,
5670
5693
  });
5671
5694
  return this._brokersService;
5672
5695
  }
@@ -5721,6 +5744,9 @@ class Ductape {
5721
5744
  async createNewHealthcheckService() {
5722
5745
  const subCheck = false;
5723
5746
  await this.initUserAuth(subCheck);
5747
+ // Ensure secrets service is initialized and set globally so probe services
5748
+ // (DatabaseService, StorageService, WorkflowService, etc.) can resolve $secret{...}
5749
+ await this.createNewSecretsService();
5724
5750
  if (!this._healthcheckService) {
5725
5751
  this._healthcheckService = new resilience_1.HealthcheckService({
5726
5752
  workspace_id: this.workspace_id,