@ductape/sdk 0.0.4-v59 → 0.0.4-v60

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 (251) hide show
  1. package/dist/agents/agents.service.d.ts +8 -2
  2. package/dist/agents/agents.service.js +5 -0
  3. package/dist/agents/agents.service.js.map +1 -1
  4. package/dist/agents/types/agents.types.d.ts +2 -0
  5. package/dist/agents/types/agents.types.js.map +1 -1
  6. package/dist/agents/vector-store-adapter.js +5 -5
  7. package/dist/agents/vector-store-adapter.js.map +1 -1
  8. package/dist/api/services/appApi.service.d.ts +3 -3
  9. package/dist/api/services/appApi.service.js.map +1 -1
  10. package/dist/api/services/productsApi.service.d.ts +1 -1
  11. package/dist/api/services/productsApi.service.js +20 -13
  12. package/dist/api/services/productsApi.service.js.map +1 -1
  13. package/dist/api/services/secretsApi.service.d.ts +12 -0
  14. package/dist/api/services/secretsApi.service.js +30 -2
  15. package/dist/api/services/secretsApi.service.js.map +1 -1
  16. package/dist/api/services/workspaceApi.service.d.ts +8 -0
  17. package/dist/api/services/workspaceApi.service.js +20 -0
  18. package/dist/api/services/workspaceApi.service.js.map +1 -1
  19. package/dist/api/urls.d.ts +2 -0
  20. package/dist/api/urls.js +10 -15
  21. package/dist/api/urls.js.map +1 -1
  22. package/dist/api/utils/auth.utils.d.ts +1 -3
  23. package/dist/api/utils/auth.utils.js.map +1 -1
  24. package/dist/apps/utils/oauth-manager.js +27 -3
  25. package/dist/apps/utils/oauth-manager.js.map +1 -1
  26. package/dist/brokers/brokers.service.d.ts +8 -0
  27. package/dist/brokers/brokers.service.js +50 -4
  28. package/dist/brokers/brokers.service.js.map +1 -1
  29. package/dist/brokers/types/index.d.ts +26 -0
  30. package/dist/brokers/utils/providers/kafka.service.d.ts +7 -0
  31. package/dist/brokers/utils/providers/kafka.service.js +102 -23
  32. package/dist/brokers/utils/providers/kafka.service.js.map +1 -1
  33. package/dist/brokers/utils/providers/rabbitmq.service.d.ts +2 -1
  34. package/dist/brokers/utils/providers/rabbitmq.service.js +99 -15
  35. package/dist/brokers/utils/providers/rabbitmq.service.js.map +1 -1
  36. package/dist/database/adapters/cassandra.adapter.d.ts +1 -0
  37. package/dist/database/adapters/cassandra.adapter.js +100 -44
  38. package/dist/database/adapters/cassandra.adapter.js.map +1 -1
  39. package/dist/database/adapters/dynamodb.adapter.d.ts +1 -0
  40. package/dist/database/adapters/dynamodb.adapter.js +89 -20
  41. package/dist/database/adapters/dynamodb.adapter.js.map +1 -1
  42. package/dist/database/adapters/mongodb.adapter.d.ts +1 -0
  43. package/dist/database/adapters/mongodb.adapter.js +123 -45
  44. package/dist/database/adapters/mongodb.adapter.js.map +1 -1
  45. package/dist/database/adapters/mysql.adapter.d.ts +1 -0
  46. package/dist/database/adapters/mysql.adapter.js +125 -48
  47. package/dist/database/adapters/mysql.adapter.js.map +1 -1
  48. package/dist/database/adapters/postgresql.adapter.d.ts +5 -0
  49. package/dist/database/adapters/postgresql.adapter.js +151 -50
  50. package/dist/database/adapters/postgresql.adapter.js.map +1 -1
  51. package/dist/database/databases.service.d.ts +15 -1
  52. package/dist/database/databases.service.js +143 -2
  53. package/dist/database/databases.service.js.map +1 -1
  54. package/dist/database/operators/aggregation-builder.d.ts +11 -8
  55. package/dist/database/operators/aggregation-builder.js +184 -89
  56. package/dist/database/operators/aggregation-builder.js.map +1 -1
  57. package/dist/database/operators/query-builder.d.ts +23 -19
  58. package/dist/database/operators/query-builder.js +77 -45
  59. package/dist/database/operators/query-builder.js.map +1 -1
  60. package/dist/database/types/aggregation.interface.d.ts +21 -15
  61. package/dist/database/types/query.interface.d.ts +27 -21
  62. package/dist/database/types/write.interface.d.ts +20 -12
  63. package/dist/graph/adapters/arangodb.adapter.js +61 -22
  64. package/dist/graph/adapters/arangodb.adapter.js.map +1 -1
  65. package/dist/graph/adapters/memgraph.adapter.js +22 -16
  66. package/dist/graph/adapters/memgraph.adapter.js.map +1 -1
  67. package/dist/graph/adapters/neo4j.adapter.js +51 -21
  68. package/dist/graph/adapters/neo4j.adapter.js.map +1 -1
  69. package/dist/graph/adapters/neptune.adapter.js +32 -16
  70. package/dist/graph/adapters/neptune.adapter.js.map +1 -1
  71. package/dist/graph/graphs.service.d.ts +24 -2
  72. package/dist/graph/graphs.service.js +238 -28
  73. package/dist/graph/graphs.service.js.map +1 -1
  74. package/dist/graph/types/connection.interface.d.ts +8 -0
  75. package/dist/graph/types/query.interface.d.ts +21 -14
  76. package/dist/index.d.ts +367 -20
  77. package/dist/index.js +510 -48
  78. package/dist/index.js.map +1 -1
  79. package/dist/inputs/inputs.service.d.ts +1 -1
  80. package/dist/notifications/notifications.service.d.ts +7 -2
  81. package/dist/notifications/notifications.service.js +2 -0
  82. package/dist/notifications/notifications.service.js.map +1 -1
  83. package/dist/processor/services/processor.service.d.ts +5 -1
  84. package/dist/processor/services/processor.service.js +35 -2
  85. package/dist/processor/services/processor.service.js.map +1 -1
  86. package/dist/products/services/products.service.d.ts +76 -2
  87. package/dist/products/services/products.service.js +984 -27
  88. package/dist/products/services/products.service.js.map +1 -1
  89. package/dist/products/validators/joi-validators/create.productAgent.validator.js +52 -4
  90. package/dist/products/validators/joi-validators/create.productAgent.validator.js.map +1 -1
  91. package/dist/products/validators/joi-validators/create.productGraph.validator.js +2 -0
  92. package/dist/products/validators/joi-validators/create.productGraph.validator.js.map +1 -1
  93. package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js +1 -7
  94. package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js.map +1 -1
  95. package/dist/products/validators/joi-validators/create.productVector.validator.js +4 -4
  96. package/dist/products/validators/joi-validators/create.productVector.validator.js.map +1 -1
  97. package/dist/products/validators/joi-validators/update.productGraph.validator.js +2 -0
  98. package/dist/products/validators/joi-validators/update.productGraph.validator.js.map +1 -1
  99. package/dist/resilience/fallback.service.d.ts +4 -1
  100. package/dist/resilience/fallback.service.js +8 -10
  101. package/dist/resilience/fallback.service.js.map +1 -1
  102. package/dist/resilience/healthcheck.service.d.ts +6 -1
  103. package/dist/resilience/healthcheck.service.js +9 -0
  104. package/dist/resilience/healthcheck.service.js.map +1 -1
  105. package/dist/resilience/quota.service.d.ts +4 -1
  106. package/dist/resilience/quota.service.js +2 -0
  107. package/dist/resilience/quota.service.js.map +1 -1
  108. package/dist/resilience/resilience.service.d.ts +4 -1
  109. package/dist/resilience/resilience.service.js.map +1 -1
  110. package/dist/secrets/secrets.service.d.ts +11 -1
  111. package/dist/secrets/secrets.service.js +109 -10
  112. package/dist/secrets/secrets.service.js.map +1 -1
  113. package/dist/storage/storage.service.d.ts +4 -1
  114. package/dist/storage/storage.service.js +6 -1
  115. package/dist/storage/storage.service.js.map +1 -1
  116. package/dist/test/index.js +1 -3
  117. package/dist/test/index.js.map +1 -1
  118. package/dist/test/test.broker.kafka.d.ts +1 -0
  119. package/dist/test/test.broker.kafka.js +172 -0
  120. package/dist/test/test.broker.kafka.js.map +1 -0
  121. package/dist/test/test.broker.nats.d.ts +1 -0
  122. package/dist/test/test.broker.nats.js +193 -0
  123. package/dist/test/test.broker.nats.js.map +1 -0
  124. package/dist/test/test.broker.pubsub.d.ts +1 -0
  125. package/dist/test/test.broker.pubsub.js +171 -0
  126. package/dist/test/test.broker.pubsub.js.map +1 -0
  127. package/dist/test/test.broker.rabbitmq.d.ts +1 -0
  128. package/dist/test/test.broker.rabbitmq.js +164 -0
  129. package/dist/test/test.broker.rabbitmq.js.map +1 -0
  130. package/dist/test/test.broker.redis.d.ts +1 -0
  131. package/dist/test/test.broker.redis.js +168 -0
  132. package/dist/test/test.broker.redis.js.map +1 -0
  133. package/dist/test/test.broker.sqs.d.ts +1 -0
  134. package/dist/test/test.broker.sqs.js +158 -0
  135. package/dist/test/test.broker.sqs.js.map +1 -0
  136. package/dist/test/test.caches.d.ts +1 -0
  137. package/dist/test/test.caches.js +231 -0
  138. package/dist/test/test.caches.js.map +1 -0
  139. package/dist/test/test.database.dynamo.d.ts +1 -0
  140. package/dist/test/test.database.dynamo.js +265 -0
  141. package/dist/test/test.database.dynamo.js.map +1 -0
  142. package/dist/test/test.database.js +2 -2
  143. package/dist/test/test.database.js.map +1 -1
  144. package/dist/test/test.database.mongo.d.ts +1 -0
  145. package/dist/test/test.database.mongo.js +371 -0
  146. package/dist/test/test.database.mongo.js.map +1 -0
  147. package/dist/test/test.database.mysql.d.ts +1 -0
  148. package/dist/test/test.database.mysql.js +415 -0
  149. package/dist/test/test.database.mysql.js.map +1 -0
  150. package/dist/test/test.database.postgres.d.ts +1 -0
  151. package/dist/test/test.database.postgres.js +412 -0
  152. package/dist/test/test.database.postgres.js.map +1 -0
  153. package/dist/test/test.email.brevo.d.ts +1 -0
  154. package/dist/test/test.email.brevo.js +326 -0
  155. package/dist/test/test.email.brevo.js.map +1 -0
  156. package/dist/test/test.email.mailgun.d.ts +1 -0
  157. package/dist/test/test.email.mailgun.js +352 -0
  158. package/dist/test/test.email.mailgun.js.map +1 -0
  159. package/dist/test/test.email.postmark.d.ts +1 -0
  160. package/dist/test/test.email.postmark.js +316 -0
  161. package/dist/test/test.email.postmark.js.map +1 -0
  162. package/dist/test/test.email.sendgrid.d.ts +1 -0
  163. package/dist/test/test.email.sendgrid.js +365 -0
  164. package/dist/test/test.email.sendgrid.js.map +1 -0
  165. package/dist/test/test.email.smtp.d.ts +1 -0
  166. package/dist/test/test.email.smtp.js +323 -0
  167. package/dist/test/test.email.smtp.js.map +1 -0
  168. package/dist/test/test.graph.arangodb.d.ts +1 -0
  169. package/dist/test/test.graph.arangodb.js +358 -0
  170. package/dist/test/test.graph.arangodb.js.map +1 -0
  171. package/dist/test/test.graph.memgraph.d.ts +1 -0
  172. package/dist/test/test.graph.memgraph.js +320 -0
  173. package/dist/test/test.graph.memgraph.js.map +1 -0
  174. package/dist/test/test.graph.neo4j.d.ts +1 -0
  175. package/dist/test/test.graph.neo4j.js +218 -0
  176. package/dist/test/test.graph.neo4j.js.map +1 -0
  177. package/dist/test/test.graph.neptune.d.ts +1 -0
  178. package/dist/test/test.graph.neptune.js +331 -0
  179. package/dist/test/test.graph.neptune.js.map +1 -0
  180. package/dist/test/test.notifications.d.ts +1 -0
  181. package/dist/test/test.notifications.js +198 -0
  182. package/dist/test/test.notifications.js.map +1 -0
  183. package/dist/test/test.push.expo.d.ts +1 -0
  184. package/dist/test/test.push.expo.js +442 -0
  185. package/dist/test/test.push.expo.js.map +1 -0
  186. package/dist/test/test.push.firebase.d.ts +1 -0
  187. package/dist/test/test.push.firebase.js +409 -0
  188. package/dist/test/test.push.firebase.js.map +1 -0
  189. package/dist/test/test.session.d.ts +1 -0
  190. package/dist/test/test.session.js +299 -0
  191. package/dist/test/test.session.js.map +1 -0
  192. package/dist/test/test.sms.nexmo.d.ts +1 -0
  193. package/dist/test/test.sms.nexmo.js +278 -0
  194. package/dist/test/test.sms.nexmo.js.map +1 -0
  195. package/dist/test/test.sms.twilio.d.ts +1 -0
  196. package/dist/test/test.sms.twilio.js +275 -0
  197. package/dist/test/test.sms.twilio.js.map +1 -0
  198. package/dist/test/test.storage.js +169 -299
  199. package/dist/test/test.storage.js.map +1 -1
  200. package/dist/test/test.vector.pinecone.d.ts +1 -0
  201. package/dist/test/test.vector.pinecone.js +238 -0
  202. package/dist/test/test.vector.pinecone.js.map +1 -0
  203. package/dist/test/test.vector.qdrant.d.ts +1 -0
  204. package/dist/test/test.vector.qdrant.js +307 -0
  205. package/dist/test/test.vector.qdrant.js.map +1 -0
  206. package/dist/test/test.vector.weaviate.d.ts +1 -0
  207. package/dist/test/test.vector.weaviate.js +325 -0
  208. package/dist/test/test.vector.weaviate.js.map +1 -0
  209. package/dist/types/appBuilder.types.d.ts +6 -2
  210. package/dist/types/enums.d.ts +2 -0
  211. package/dist/types/enums.js +2 -0
  212. package/dist/types/enums.js.map +1 -1
  213. package/dist/types/index.types.d.ts +2 -4
  214. package/dist/types/index.types.js +0 -1
  215. package/dist/types/index.types.js.map +1 -1
  216. package/dist/types/processor.types.d.ts +18 -0
  217. package/dist/types/productsBuilder.types.d.ts +19 -15
  218. package/dist/types/productsBuilder.types.js.map +1 -1
  219. package/dist/types/requests.types.d.ts +2 -0
  220. package/dist/utils/index.js +23 -4
  221. package/dist/utils/index.js.map +1 -1
  222. package/dist/vector/adapters/base.adapter.d.ts +1 -1
  223. package/dist/vector/adapters/memory.adapter.d.ts +1 -1
  224. package/dist/vector/adapters/memory.adapter.js +1 -1
  225. package/dist/vector/adapters/memory.adapter.js.map +1 -1
  226. package/dist/vector/adapters/pinecone.adapter.d.ts +1 -1
  227. package/dist/vector/adapters/pinecone.adapter.js +1 -1
  228. package/dist/vector/adapters/pinecone.adapter.js.map +1 -1
  229. package/dist/vector/adapters/qdrant.adapter.d.ts +1 -1
  230. package/dist/vector/adapters/qdrant.adapter.js +1 -1
  231. package/dist/vector/adapters/qdrant.adapter.js.map +1 -1
  232. package/dist/vector/adapters/weaviate.adapter.d.ts +1 -1
  233. package/dist/vector/adapters/weaviate.adapter.js +1 -1
  234. package/dist/vector/adapters/weaviate.adapter.js.map +1 -1
  235. package/dist/vector/index.d.ts +2 -2
  236. package/dist/vector/index.js +2 -2
  237. package/dist/vector/utils/vector-error.js +0 -1
  238. package/dist/vector/utils/vector-error.js.map +1 -1
  239. package/dist/vector/vector-database.service.d.ts +9 -6
  240. package/dist/vector/vector-database.service.js +7 -6
  241. package/dist/vector/vector-database.service.js.map +1 -1
  242. package/dist/vector/vector.service.d.ts +3 -3
  243. package/dist/vector/vector.service.js +12 -9
  244. package/dist/vector/vector.service.js.map +1 -1
  245. package/dist/workflows/workflow-executor.d.ts +4 -1
  246. package/dist/workflows/workflow-executor.js +10 -2
  247. package/dist/workflows/workflow-executor.js.map +1 -1
  248. package/dist/workflows/workflows.service.d.ts +8 -2
  249. package/dist/workflows/workflows.service.js +66 -41
  250. package/dist/workflows/workflows.service.js.map +1 -1
  251. package/package.json +29 -4
@@ -36,17 +36,20 @@ const update_productDatabaseMigration_validator_1 = __importDefault(require("../
36
36
  const create_productNotificationMessage_validator_1 = __importDefault(require("../validators/joi-validators/create.productNotificationMessage.validator"));
37
37
  const create_productMessageBrokerTopic_validator_1 = __importDefault(require("../validators/joi-validators/create.productMessageBrokerTopic.validator"));
38
38
  const update_productMessageBrokerTopic_validator_1 = __importDefault(require("../validators/joi-validators/update.productMessageBrokerTopic.validator"));
39
+ const secrets_1 = require("../../secrets");
39
40
  const update_productNotificationMessage_validator_1 = __importDefault(require("../validators/joi-validators/update.productNotificationMessage.validator"));
40
41
  const create_productNotification_validator_1 = require("../validators/joi-validators/create.productNotification.validator");
41
42
  const functions_utils_1 = require("../utils/functions.utils");
42
43
  const objects_utils_2 = require("../../apps/utils/objects.utils");
43
44
  const webhooksApi_service_1 = require("../../api/services/webhooksApi.service");
44
45
  class ProductsBuilderService {
45
- constructor({ workspace_id, public_key, user_id, token, env_type, redis_client, queues }) {
46
+ constructor({ workspace_id, public_key, user_id, token, env_type, redis_client, queues, access_key }) {
47
+ this.workspace_private_key = null;
46
48
  this.workspace_id = workspace_id;
47
49
  this.public_key = public_key;
48
50
  this.user_id = user_id;
49
51
  this.token = token;
52
+ this.access_key = access_key || null;
50
53
  this.userApi = new userApi_service_1.UserApiService(env_type, redis_client);
51
54
  this.productApi = new productsApi_service_1.ProductsApiService(env_type, redis_client);
52
55
  this.workspaceApi = new workspaceApi_service_1.WorkspaceApiService(env_type, redis_client);
@@ -289,6 +292,22 @@ class ProductsBuilderService {
289
292
  if (!this.workspace) {
290
293
  this.workspace = await this.workspaceApi.fetchWorkspaceById(this.getUserAccess(), subCheck);
291
294
  }
295
+ // Fetch workspace private key using the dedicated endpoint for secrets encryption
296
+ if (!this.workspace_private_key && this.access_key) {
297
+ try {
298
+ this.workspace_private_key = await this.workspaceApi.fetchPrivateKey(this.getUserAccess(), this.access_key);
299
+ }
300
+ catch (e) {
301
+ console.warn('[ProductsBuilderService] Failed to fetch workspace private key:', e);
302
+ }
303
+ }
304
+ }
305
+ /**
306
+ * Get the workspace private key for secrets encryption
307
+ * @returns The workspace private key or null if not available
308
+ */
309
+ getWorkspacePrivateKey() {
310
+ return this.workspace_private_key;
292
311
  }
293
312
  async initializeProduct(product_id) {
294
313
  try {
@@ -578,6 +597,134 @@ class ProductsBuilderService {
578
597
  throw new Error(`Message Broker ${messageBrokerTag} not found`);
579
598
  return messageBroker.topics;
580
599
  }
600
+ // ==================== MESSAGE BROKER PRODUCERS ====================
601
+ async createMessageBrokerProducer(data) {
602
+ var _a, _b;
603
+ try {
604
+ const [messageBrokerTag, topicTag] = data.topic.split(':');
605
+ if (!messageBrokerTag || !topicTag) {
606
+ throw new Error(`topic is expected to be defined as "messageBroker_tag:topic_tag"`);
607
+ }
608
+ const broker = await this.fetchMessageBroker(messageBrokerTag);
609
+ if (!broker) {
610
+ throw new Error(`Message Broker ${messageBrokerTag} not found`);
611
+ }
612
+ // Check if topic exists
613
+ const topic = (_a = broker.topics) === null || _a === void 0 ? void 0 : _a.find((t) => t.tag === topicTag);
614
+ if (!topic) {
615
+ throw new Error(`Topic ${topicTag} not found in broker ${messageBrokerTag}`);
616
+ }
617
+ // Check if producer already exists
618
+ const existingProducer = (_b = broker.producers) === null || _b === void 0 ? void 0 : _b.find((p) => p.tag === data.tag);
619
+ if (existingProducer) {
620
+ throw new Error(`Producer ${data.tag} already exists in broker ${messageBrokerTag}`);
621
+ }
622
+ await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { messageBrokerTag, component: enums_1.ProductComponents.MESSAGEBROKER_PRODUCER, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
623
+ }
624
+ catch (e) {
625
+ throw e;
626
+ }
627
+ }
628
+ async updateMessageBrokerProducer(data) {
629
+ var _a;
630
+ try {
631
+ const [messageBrokerTag, topicTag] = data.topic.split(':');
632
+ if (!messageBrokerTag || !topicTag) {
633
+ throw new Error(`topic is expected to be defined as "messageBroker_tag:topic_tag"`);
634
+ }
635
+ const broker = await this.fetchMessageBroker(messageBrokerTag);
636
+ if (!broker) {
637
+ throw new Error(`Message Broker ${messageBrokerTag} not found`);
638
+ }
639
+ // Check if producer exists
640
+ const existingProducer = (_a = broker.producers) === null || _a === void 0 ? void 0 : _a.find((p) => p.tag === data.tag);
641
+ if (!existingProducer) {
642
+ throw new Error(`Producer ${data.tag} not found in broker ${messageBrokerTag}`);
643
+ }
644
+ await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { messageBrokerTag, component: enums_1.ProductComponents.MESSAGEBROKER_PRODUCER, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
645
+ }
646
+ catch (e) {
647
+ throw e;
648
+ }
649
+ }
650
+ async fetchMessageBrokerProducer(brokerTag, tag) {
651
+ var _a;
652
+ const messageBroker = this.product.messageBrokers.find((data) => data.tag === brokerTag);
653
+ if (!messageBroker)
654
+ throw new Error(`MessageBroker ${brokerTag} not found`);
655
+ const producer = (_a = messageBroker.producers) === null || _a === void 0 ? void 0 : _a.find((p) => p.tag === tag);
656
+ return producer || null;
657
+ }
658
+ async fetchMessageBrokerProducers(messageBrokerTag) {
659
+ const messageBroker = this.product.messageBrokers.find((data) => data.tag === messageBrokerTag);
660
+ if (!messageBroker)
661
+ throw new Error(`Message Broker ${messageBrokerTag} not found`);
662
+ return messageBroker.producers || [];
663
+ }
664
+ // ==================== MESSAGE BROKER CONSUMERS ====================
665
+ async createMessageBrokerConsumer(data) {
666
+ var _a, _b;
667
+ try {
668
+ const [messageBrokerTag, topicTag] = data.topic.split(':');
669
+ if (!messageBrokerTag || !topicTag) {
670
+ throw new Error(`topic is expected to be defined as "messageBroker_tag:topic_tag"`);
671
+ }
672
+ const broker = await this.fetchMessageBroker(messageBrokerTag);
673
+ if (!broker) {
674
+ throw new Error(`Message Broker ${messageBrokerTag} not found`);
675
+ }
676
+ // Check if topic exists
677
+ const topic = (_a = broker.topics) === null || _a === void 0 ? void 0 : _a.find((t) => t.tag === topicTag);
678
+ if (!topic) {
679
+ throw new Error(`Topic ${topicTag} not found in broker ${messageBrokerTag}`);
680
+ }
681
+ // Check if consumer already exists
682
+ const existingConsumer = (_b = broker.consumers) === null || _b === void 0 ? void 0 : _b.find((c) => c.tag === data.tag);
683
+ if (existingConsumer) {
684
+ throw new Error(`Consumer ${data.tag} already exists in broker ${messageBrokerTag}`);
685
+ }
686
+ await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { messageBrokerTag, component: enums_1.ProductComponents.MESSAGEBROKER_CONSUMER, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
687
+ }
688
+ catch (e) {
689
+ throw e;
690
+ }
691
+ }
692
+ async updateMessageBrokerConsumer(data) {
693
+ var _a;
694
+ try {
695
+ const [messageBrokerTag, topicTag] = data.topic.split(':');
696
+ if (!messageBrokerTag || !topicTag) {
697
+ throw new Error(`topic is expected to be defined as "messageBroker_tag:topic_tag"`);
698
+ }
699
+ const broker = await this.fetchMessageBroker(messageBrokerTag);
700
+ if (!broker) {
701
+ throw new Error(`Message Broker ${messageBrokerTag} not found`);
702
+ }
703
+ // Check if consumer exists
704
+ const existingConsumer = (_a = broker.consumers) === null || _a === void 0 ? void 0 : _a.find((c) => c.tag === data.tag);
705
+ if (!existingConsumer) {
706
+ throw new Error(`Consumer ${data.tag} not found in broker ${messageBrokerTag}`);
707
+ }
708
+ await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { messageBrokerTag, component: enums_1.ProductComponents.MESSAGEBROKER_CONSUMER, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
709
+ }
710
+ catch (e) {
711
+ throw e;
712
+ }
713
+ }
714
+ async fetchMessageBrokerConsumer(brokerTag, tag) {
715
+ var _a;
716
+ const messageBroker = this.product.messageBrokers.find((data) => data.tag === brokerTag);
717
+ if (!messageBroker)
718
+ throw new Error(`MessageBroker ${brokerTag} not found`);
719
+ const consumer = (_a = messageBroker.consumers) === null || _a === void 0 ? void 0 : _a.find((c) => c.tag === tag);
720
+ return consumer || null;
721
+ }
722
+ async fetchMessageBrokerConsumers(messageBrokerTag) {
723
+ const messageBroker = this.product.messageBrokers.find((data) => data.tag === messageBrokerTag);
724
+ if (!messageBroker)
725
+ throw new Error(`Message Broker ${messageBrokerTag} not found`);
726
+ return messageBroker.consumers || [];
727
+ }
581
728
  async validateQuotaFallbackInputAndOutput(data, type) {
582
729
  const input = data.input;
583
730
  await Promise.all(data.options.map(async (d, index) => {
@@ -1071,69 +1218,125 @@ class ProductsBuilderService {
1071
1218
  }
1072
1219
  }
1073
1220
  async createMessageBroker(data, throwErrorIfExists = false) {
1074
- if (!(await this.fetchMessageBroker(data.tag))) {
1221
+ var _a;
1222
+ const logPrefix = '[MessageBroker:Create]';
1223
+ console.log(`${logPrefix} Starting creation for broker: ${data.tag}`);
1224
+ console.log(`${logPrefix} Broker name: ${data.name}`);
1225
+ console.log(`${logPrefix} Broker description: ${data.description || 'N/A'}`);
1226
+ console.log(`${logPrefix} Number of environments: ${((_a = data.envs) === null || _a === void 0 ? void 0 : _a.length) || 0}`);
1227
+ const existingBroker = await this.fetchMessageBroker(data.tag);
1228
+ if (!existingBroker) {
1229
+ console.log(`${logPrefix} Broker ${data.tag} does not exist, proceeding with creation`);
1230
+ console.log(`${logPrefix} Validating schema...`);
1075
1231
  await validators_1.CreateMessageBrokerSchema.validateAsync(data);
1232
+ console.log(`${logPrefix} Schema validation passed`);
1076
1233
  const processedEnvs = [];
1077
1234
  for (const env of data.envs) {
1235
+ console.log(`${logPrefix} Processing env: ${env.slug} (type: ${env.type})`);
1078
1236
  const exists = await this.fetchEnv(env.slug);
1079
1237
  if (!exists) {
1238
+ console.error(`${logPrefix} Env ${env.slug} does not exist`);
1080
1239
  throw new Error(`Env ${env.slug} does not exist`);
1081
1240
  }
1241
+ console.log(`${logPrefix} Env ${env.slug} exists, verified`);
1242
+ // Store sensitive credentials as secrets
1243
+ console.log(`${logPrefix} Processing secrets for env: ${env.slug}...`);
1244
+ env.config = await this.processMessageBrokerConfigSecrets(env.config, env.type, data.tag, env.slug);
1245
+ console.log(`${logPrefix} Secrets processed for env: ${env.slug}`);
1246
+ console.log(`${logPrefix} Encrypting config for env: ${env.slug}...`);
1082
1247
  env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
1248
+ console.log(`${logPrefix} Config encrypted for env: ${env.slug}`);
1083
1249
  processedEnvs.push(env);
1084
1250
  }
1085
1251
  data.envs = processedEnvs;
1252
+ console.log(`${logPrefix} All environments processed: ${processedEnvs.length}`);
1086
1253
  const envs = await this.fetchEnvs();
1254
+ console.log(`${logPrefix} Product has ${envs.length} environments defined`);
1087
1255
  for (const env of envs) {
1088
1256
  const exists = data.envs.findIndex((dbEnv) => dbEnv.slug === env.slug);
1089
1257
  if (exists === -1) {
1258
+ console.error(`${logPrefix} Product env ${env.slug} is not defined in broker config`);
1090
1259
  throw new Error(`Product env ${env.slug} is not defined, please provide connection details`);
1091
1260
  }
1092
1261
  }
1262
+ console.log(`${logPrefix} All product environments have broker configs`);
1263
+ console.log(`${logPrefix} Sending create request to API...`);
1093
1264
  await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.MESSAGEBROKER, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
1265
+ console.log(`${logPrefix} Message broker ${data.tag} created successfully`);
1094
1266
  }
1095
1267
  else {
1268
+ console.log(`${logPrefix} Broker ${data.tag} already exists`);
1096
1269
  if (throwErrorIfExists)
1097
1270
  throw new Error(`Message Broker ${data.tag} already exists`);
1098
1271
  }
1099
1272
  }
1100
1273
  async updateMessageBroker(tag, data) {
1274
+ var _a, _b;
1275
+ const logPrefix = '[MessageBroker:Update]';
1276
+ console.log(`${logPrefix} Starting update for broker: ${tag}`);
1277
+ console.log(`${logPrefix} New tag (if changed): ${data.tag || 'unchanged'}`);
1278
+ console.log(`${logPrefix} New name: ${data.name || 'unchanged'}`);
1279
+ console.log(`${logPrefix} Number of environments in update: ${((_a = data.envs) === null || _a === void 0 ? void 0 : _a.length) || 0}`);
1101
1280
  try {
1281
+ console.log(`${logPrefix} Fetching existing broker: ${tag}`);
1102
1282
  const messageBroker = await this.fetchMessageBroker(tag);
1103
1283
  if (!messageBroker) {
1284
+ console.error(`${logPrefix} Broker ${tag} not found`);
1104
1285
  throw new Error(`Broker ${tag} not found`);
1105
1286
  }
1287
+ console.log(`${logPrefix} Existing broker found with ${((_b = messageBroker.envs) === null || _b === void 0 ? void 0 : _b.length) || 0} environments`);
1106
1288
  const { _id, envs } = messageBroker;
1107
- await validators_1.UpdateMessageBrokerSchema.validateAsync(data); // Change to update;
1289
+ console.log(`${logPrefix} Broker ID: ${_id}`);
1290
+ console.log(`${logPrefix} Validating update schema...`);
1291
+ await validators_1.UpdateMessageBrokerSchema.validateAsync(data);
1292
+ console.log(`${logPrefix} Schema validation passed`);
1108
1293
  if (data.tag && (await this.fetchMessageBroker(data.tag))) {
1109
- throw new Error(`tag ${tag} is in use`); // TODO: also check on the backend
1294
+ console.error(`${logPrefix} Tag ${data.tag} is already in use`);
1295
+ throw new Error(`tag ${tag} is in use`);
1110
1296
  }
1111
- console.log('2', data.envs);
1112
1297
  const processedEnvs = [];
1113
1298
  for (const env of data.envs) {
1299
+ console.log(`${logPrefix} Processing env: ${env.slug} (type: ${env.type})`);
1114
1300
  const exists = await this.fetchEnv(env.slug);
1115
1301
  if (!exists) {
1302
+ console.error(`${logPrefix} Env ${env.slug} does not exist`);
1116
1303
  throw new Error(`Env ${env.slug} does not exist`);
1117
1304
  }
1118
- if (env.config)
1305
+ console.log(`${logPrefix} Env ${env.slug} exists, verified`);
1306
+ if (env.config) {
1307
+ // Store sensitive credentials as secrets
1308
+ console.log(`${logPrefix} Processing secrets for env: ${env.slug}...`);
1309
+ env.config = await this.processMessageBrokerConfigSecrets(env.config, env.type, data.tag || tag, env.slug);
1310
+ console.log(`${logPrefix} Secrets processed for env: ${env.slug}`);
1311
+ console.log(`${logPrefix} Encrypting config for env: ${env.slug}...`);
1119
1312
  env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
1313
+ console.log(`${logPrefix} Config encrypted for env: ${env.slug}`);
1314
+ }
1315
+ else {
1316
+ console.log(`${logPrefix} No config provided for env: ${env.slug}, skipping secrets processing`);
1317
+ }
1120
1318
  processedEnvs.push(env);
1121
1319
  }
1122
1320
  data.envs = processedEnvs;
1321
+ console.log(`${logPrefix} All environments processed: ${processedEnvs.length}`);
1123
1322
  const overwrite = [];
1124
1323
  const newEnvs = [];
1125
1324
  for (const dataEnv of data.envs) {
1126
1325
  const exists = envs.findIndex((env) => env.slug === dataEnv.slug);
1127
1326
  if (!(await this.fetchEnv(dataEnv.slug))) {
1327
+ console.error(`${logPrefix} Product Environment ${dataEnv.slug} doesn't exist`);
1128
1328
  throw new Error(`Product Environment ${dataEnv.slug} doesn't exist`);
1129
1329
  }
1130
1330
  if (exists === -1) {
1331
+ console.log(`${logPrefix} Env ${dataEnv.slug} is a NEW environment`);
1131
1332
  if (!dataEnv.config) {
1333
+ console.error(`${logPrefix} Config is required for new env ${dataEnv.slug}`);
1132
1334
  throw new Error(`config is required for new env ${data.envs[exists].slug}`);
1133
1335
  }
1134
1336
  newEnvs.push(dataEnv);
1135
1337
  }
1136
1338
  else {
1339
+ console.log(`${logPrefix} Env ${dataEnv.slug} will OVERWRITE existing config`);
1137
1340
  if (envs[exists].config) {
1138
1341
  envs[exists].config = (0, processor_utils_1.encrypt)(JSON.stringify(envs[exists].config), this.product.private_key);
1139
1342
  }
@@ -1145,6 +1348,7 @@ class ProductsBuilderService {
1145
1348
  const newEnv = newEnvs.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
1146
1349
  const overwriteEnv = overwrite.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
1147
1350
  if (!newEnv && !overwriteEnv) {
1351
+ console.log(`${logPrefix} Env ${env.slug} is UNCHANGED`);
1148
1352
  if (env.config) {
1149
1353
  env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
1150
1354
  }
@@ -1152,9 +1356,13 @@ class ProductsBuilderService {
1152
1356
  }
1153
1357
  }
1154
1358
  data.envs = [...unchanged, ...overwrite, ...newEnvs];
1359
+ console.log(`${logPrefix} Final env breakdown - Unchanged: ${unchanged.length}, Overwrite: ${overwrite.length}, New: ${newEnvs.length}`);
1360
+ console.log(`${logPrefix} Sending update request to API...`);
1155
1361
  await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({ _id }, messageBroker), data), { component: enums_1.ProductComponents.MESSAGEBROKER, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
1362
+ console.log(`${logPrefix} Message broker ${tag} updated successfully`);
1156
1363
  }
1157
1364
  catch (e) {
1365
+ console.error(`${logPrefix} Update failed:`, e);
1158
1366
  throw e;
1159
1367
  }
1160
1368
  }
@@ -1228,6 +1436,8 @@ class ProductsBuilderService {
1228
1436
  // @ts-ignore
1229
1437
  //env.config.config.private_key = gcpPKCSConvert(env.config.config.private_key)
1230
1438
  }
1439
+ // Store sensitive credentials as secrets
1440
+ env.config = await this.processStorageConfigSecrets(env.config, env.type, data.tag, env.slug);
1231
1441
  env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
1232
1442
  processedEnvs.push(env);
1233
1443
  }
@@ -1266,8 +1476,11 @@ class ProductsBuilderService {
1266
1476
  // @ts-ignore
1267
1477
  //env.config.config.private_key = gcpPKCSConvert(env.config.config.private_key)
1268
1478
  }
1269
- if (env.config)
1479
+ if (env.config) {
1480
+ // Store sensitive credentials as secrets
1481
+ env.config = await this.processStorageConfigSecrets(env.config, env.type, data.tag || tag, env.slug);
1270
1482
  env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
1483
+ }
1271
1484
  return env;
1272
1485
  }));
1273
1486
  const overwrite = [];
@@ -1339,21 +1552,56 @@ class ProductsBuilderService {
1339
1552
  * @param throwErrorIfExists Whether to throw error if vector config already exists
1340
1553
  */
1341
1554
  async createVector(data, throwErrorIfExists = false) {
1555
+ var _a, _b, _c, _d;
1556
+ console.log('[ProductsService.createVector] Starting vector creation:', {
1557
+ tag: data.tag,
1558
+ name: data.name,
1559
+ type: data.type,
1560
+ envsCount: (_a = data.envs) === null || _a === void 0 ? void 0 : _a.length,
1561
+ productTag: (_b = this.product) === null || _b === void 0 ? void 0 : _b.tag,
1562
+ });
1342
1563
  if (!(await this.fetchVector(data.tag))) {
1343
1564
  await validators_1.CreateProductVectorSchema.validateAsync(data);
1344
1565
  const processedEnvs = [];
1345
1566
  for (const env of data.envs) {
1567
+ console.log('[ProductsService.createVector] Processing env:', {
1568
+ slug: env.slug,
1569
+ hasApiKey: !!env.apiKey,
1570
+ hasEndpoint: !!env.endpoint,
1571
+ });
1346
1572
  const exists = await this.fetchEnv(env.slug);
1347
1573
  if (!exists) {
1348
1574
  throw new Error(`Env ${env.slug} does not exist`);
1349
1575
  }
1350
- // Encrypt API key if provided
1576
+ // Store API key as secret and encrypt
1351
1577
  if (env.apiKey) {
1578
+ console.log('[ProductsService.createVector] Converting API key to secret for env:', env.slug);
1579
+ const originalApiKey = env.apiKey;
1580
+ env.apiKey = await this.storeVectorApiKeyAsSecret(env.apiKey, data.tag, env.slug);
1581
+ console.log('[ProductsService.createVector] API key after secret conversion:', {
1582
+ wasConverted: originalApiKey !== env.apiKey,
1583
+ isSecretRef: (_c = env.apiKey) === null || _c === void 0 ? void 0 : _c.startsWith('$Secret{'),
1584
+ });
1352
1585
  env.apiKey = (0, processor_utils_1.encrypt)(env.apiKey, this.product.private_key);
1586
+ console.log('[ProductsService.createVector] API key encrypted');
1587
+ }
1588
+ // Store endpoint as secret and encrypt
1589
+ if (env.endpoint) {
1590
+ console.log('[ProductsService.createVector] Converting endpoint to secret for env:', env.slug);
1591
+ const originalEndpoint = env.endpoint;
1592
+ env.endpoint = await this.storeVectorEndpointAsSecret(env.endpoint, data.tag, env.slug);
1593
+ console.log('[ProductsService.createVector] Endpoint after secret conversion:', {
1594
+ wasConverted: originalEndpoint !== env.endpoint,
1595
+ isSecretRef: (_d = env.endpoint) === null || _d === void 0 ? void 0 : _d.startsWith('$Secret{'),
1596
+ });
1597
+ env.endpoint = (0, processor_utils_1.encrypt)(env.endpoint, this.product.private_key);
1598
+ console.log('[ProductsService.createVector] Endpoint encrypted');
1353
1599
  }
1354
1600
  processedEnvs.push(env);
1601
+ console.log('[ProductsService.createVector] Env processed successfully:', env.slug);
1355
1602
  }
1356
1603
  data.envs = processedEnvs;
1604
+ console.log('[ProductsService.createVector] All envs processed, total:', processedEnvs.length);
1357
1605
  const envs = await this.fetchEnvs();
1358
1606
  for (const env of envs) {
1359
1607
  const exists = data.envs.findIndex((vecEnv) => vecEnv.slug === env.slug);
@@ -1374,26 +1622,66 @@ class ProductsBuilderService {
1374
1622
  * @param data Updated vector configuration
1375
1623
  */
1376
1624
  async updateVector(tag, data) {
1625
+ var _a, _b;
1626
+ console.log('[ProductsService.updateVector] Starting vector update:', {
1627
+ tag,
1628
+ newTag: data.tag,
1629
+ name: data.name,
1630
+ envsCount: (_a = data.envs) === null || _a === void 0 ? void 0 : _a.length,
1631
+ productTag: (_b = this.product) === null || _b === void 0 ? void 0 : _b.tag,
1632
+ });
1377
1633
  try {
1378
1634
  const vector = await this.fetchVector(tag);
1379
1635
  if (!vector) {
1380
1636
  throw new Error(`Vector ${tag} not found`);
1381
1637
  }
1382
1638
  const { _id, envs } = vector;
1639
+ console.log('[ProductsService.updateVector] Found existing vector:', {
1640
+ _id,
1641
+ existingEnvsCount: envs === null || envs === void 0 ? void 0 : envs.length,
1642
+ });
1383
1643
  await validators_1.UpdateProductVectorSchema.validateAsync(data);
1384
1644
  if (data.tag && (await this.fetchVector(data.tag))) {
1385
1645
  throw new Error(`tag ${data.tag} is in use`);
1386
1646
  }
1387
1647
  if (data.envs) {
1648
+ console.log('[ProductsService.updateVector] Processing envs update');
1388
1649
  data.envs = await Promise.all(data.envs.map(async (env) => {
1650
+ var _a, _b;
1651
+ console.log('[ProductsService.updateVector] Processing env:', {
1652
+ slug: env.slug,
1653
+ hasApiKey: !!env.apiKey,
1654
+ hasEndpoint: !!env.endpoint,
1655
+ });
1389
1656
  const exists = await this.fetchEnv(env.slug);
1390
1657
  if (!exists) {
1391
1658
  throw new Error(`Env ${env.slug} does not exist`);
1392
1659
  }
1393
- // Encrypt API key if provided
1660
+ // Store API key as secret and encrypt
1394
1661
  if (env.apiKey) {
1662
+ console.log('[ProductsService.updateVector] Converting API key to secret for env:', env.slug);
1663
+ const originalApiKey = env.apiKey;
1664
+ env.apiKey = await this.storeVectorApiKeyAsSecret(env.apiKey, data.tag || tag, env.slug);
1665
+ console.log('[ProductsService.updateVector] API key after secret conversion:', {
1666
+ wasConverted: originalApiKey !== env.apiKey,
1667
+ isSecretRef: (_a = env.apiKey) === null || _a === void 0 ? void 0 : _a.startsWith('$Secret{'),
1668
+ });
1395
1669
  env.apiKey = (0, processor_utils_1.encrypt)(env.apiKey, this.product.private_key);
1670
+ console.log('[ProductsService.updateVector] API key encrypted');
1396
1671
  }
1672
+ // Store endpoint as secret and encrypt
1673
+ if (env.endpoint) {
1674
+ console.log('[ProductsService.updateVector] Converting endpoint to secret for env:', env.slug);
1675
+ const originalEndpoint = env.endpoint;
1676
+ env.endpoint = await this.storeVectorEndpointAsSecret(env.endpoint, data.tag || tag, env.slug);
1677
+ console.log('[ProductsService.updateVector] Endpoint after secret conversion:', {
1678
+ wasConverted: originalEndpoint !== env.endpoint,
1679
+ isSecretRef: (_b = env.endpoint) === null || _b === void 0 ? void 0 : _b.startsWith('$Secret{'),
1680
+ });
1681
+ env.endpoint = (0, processor_utils_1.encrypt)(env.endpoint, this.product.private_key);
1682
+ console.log('[ProductsService.updateVector] Endpoint encrypted');
1683
+ }
1684
+ console.log('[ProductsService.updateVector] Env processed successfully:', env.slug);
1397
1685
  return env;
1398
1686
  }));
1399
1687
  const overwrite = [];
@@ -1605,8 +1893,9 @@ class ProductsBuilderService {
1605
1893
  if (!exists) {
1606
1894
  throw new Error(`Env ${env.slug} does not exist`);
1607
1895
  }
1608
- // Encrypt API key if provided
1896
+ // Store API key as secret and encrypt
1609
1897
  if (env.apiKey) {
1898
+ env.apiKey = await this.storeModelApiKeyAsSecret(env.apiKey, data.tag, env.slug);
1610
1899
  env.apiKey = (0, processor_utils_1.encrypt)(env.apiKey, this.product.private_key);
1611
1900
  }
1612
1901
  processedEnvs.push(env);
@@ -1648,8 +1937,9 @@ class ProductsBuilderService {
1648
1937
  if (!exists) {
1649
1938
  throw new Error(`Env ${env.slug} does not exist`);
1650
1939
  }
1651
- // Encrypt API key if provided
1940
+ // Store API key as secret and encrypt
1652
1941
  if (env.apiKey) {
1942
+ env.apiKey = await this.storeModelApiKeyAsSecret(env.apiKey, data.tag || tag, env.slug);
1653
1943
  env.apiKey = (0, processor_utils_1.encrypt)(env.apiKey, this.product.private_key);
1654
1944
  }
1655
1945
  return env;
@@ -2104,17 +2394,19 @@ class ProductsBuilderService {
2104
2394
  }
2105
2395
  }
2106
2396
  for (let i = 0; i < data.envs.length; i++) {
2397
+ // Process secrets for each notification handler
2398
+ const processedEnv = await this.processNotificationEnvSecrets(data.envs[i], data.tag, data.envs[i].slug);
2107
2399
  const updates = {
2108
- push_notifications: data.envs[i].push_notifications
2109
- ? (0, processor_utils_1.encrypt)(JSON.stringify(data.envs[i].push_notifications), this.product.private_key)
2400
+ push_notifications: processedEnv.push_notifications
2401
+ ? (0, processor_utils_1.encrypt)(JSON.stringify(processedEnv.push_notifications), this.product.private_key)
2110
2402
  : undefined,
2111
- emails: data.envs[i].emails
2112
- ? (0, processor_utils_1.encrypt)(JSON.stringify(data.envs[i].emails), this.product.private_key)
2403
+ emails: processedEnv.emails
2404
+ ? (0, processor_utils_1.encrypt)(JSON.stringify(processedEnv.emails), this.product.private_key)
2113
2405
  : undefined,
2114
- callbacks: data.envs[i].callbacks
2115
- ? (0, processor_utils_1.encrypt)(JSON.stringify(data.envs[i].callbacks), this.product.private_key)
2406
+ callbacks: processedEnv.callbacks
2407
+ ? (0, processor_utils_1.encrypt)(JSON.stringify(processedEnv.callbacks), this.product.private_key)
2116
2408
  : undefined,
2117
- sms: data.envs[i].sms ? (0, processor_utils_1.encrypt)(JSON.stringify(data.envs[i].sms), this.product.private_key) : undefined,
2409
+ sms: processedEnv.sms ? (0, processor_utils_1.encrypt)(JSON.stringify(processedEnv.sms), this.product.private_key) : undefined,
2118
2410
  };
2119
2411
  data.envs[i] = Object.assign(Object.assign({}, data.envs[i]), updates);
2120
2412
  }
@@ -2300,15 +2592,18 @@ class ProductsBuilderService {
2300
2592
  data.envs = [...unchanged, ...overwrite, ...newEnvs];
2301
2593
  }
2302
2594
  const update = Object.assign(Object.assign({}, notification), data);
2303
- for (const env of update.envs) {
2304
- if (env.emails)
2305
- env.emails = (0, processor_utils_1.encrypt)(JSON.stringify(env.emails), this.product.private_key);
2306
- if (env.push_notifications)
2307
- env.push_notifications = (0, processor_utils_1.encrypt)(JSON.stringify(env.push_notifications), this.product.private_key);
2308
- if (env.callbacks)
2309
- env.callbacks = (0, processor_utils_1.encrypt)(JSON.stringify(env.callbacks), this.product.private_key);
2310
- if (env.sms)
2311
- env.sms = (0, processor_utils_1.encrypt)(JSON.stringify(env.sms), this.product.private_key);
2595
+ for (let i = 0; i < update.envs.length; i++) {
2596
+ const env = update.envs[i];
2597
+ // Process secrets for each notification handler
2598
+ const processedEnv = await this.processNotificationEnvSecrets(env, data.tag || tag, env.slug);
2599
+ if (processedEnv.emails)
2600
+ update.envs[i].emails = (0, processor_utils_1.encrypt)(JSON.stringify(processedEnv.emails), this.product.private_key);
2601
+ if (processedEnv.push_notifications)
2602
+ update.envs[i].push_notifications = (0, processor_utils_1.encrypt)(JSON.stringify(processedEnv.push_notifications), this.product.private_key);
2603
+ if (processedEnv.callbacks)
2604
+ update.envs[i].callbacks = (0, processor_utils_1.encrypt)(JSON.stringify(processedEnv.callbacks), this.product.private_key);
2605
+ if (processedEnv.sms)
2606
+ update.envs[i].sms = (0, processor_utils_1.encrypt)(JSON.stringify(processedEnv.sms), this.product.private_key);
2312
2607
  }
2313
2608
  const payload = Object.assign(Object.assign({ _id }, update), { component: enums_1.ProductComponents.NOTIFICATION, action: enums_1.RequestAction.UPDATE });
2314
2609
  await this.productApi.updateProduct(this.product_id, payload, this.getUserAccess());
@@ -3517,19 +3812,53 @@ class ProductsBuilderService {
3517
3812
  }
3518
3813
  // GRAPH CRUD METHODS
3519
3814
  async createGraph(data, throwErrorIfExists = false) {
3815
+ var _a, _b, _c;
3816
+ console.log('[ProductsService.createGraph] Starting graph creation:', {
3817
+ tag: data.tag,
3818
+ name: data.name,
3819
+ type: data.type,
3820
+ envsCount: (_a = data.envs) === null || _a === void 0 ? void 0 : _a.length,
3821
+ productTag: (_b = this.product) === null || _b === void 0 ? void 0 : _b.tag,
3822
+ });
3520
3823
  try {
3521
3824
  if (!(await this.fetchGraph(data.tag))) {
3522
3825
  await validators_1.CreateProductGraphSchema.validateAsync(data);
3523
3826
  const processedEnvs = [];
3524
3827
  for (const env of data.envs) {
3828
+ console.log('[ProductsService.createGraph] Processing env:', {
3829
+ slug: env.slug,
3830
+ hasConnectionUrl: !!env.connection_url,
3831
+ hasUsername: !!env.username,
3832
+ hasPassword: !!env.password,
3833
+ });
3525
3834
  const exists = await this.fetchEnv(env.slug);
3526
3835
  if (!exists) {
3527
3836
  throw new Error(`Env ${env.slug} does not exist`);
3528
3837
  }
3838
+ // Store connection URL as secret
3839
+ console.log('[ProductsService.createGraph] Converting connection URL to secret for env:', env.slug);
3840
+ const originalUrl = env.connection_url;
3841
+ env.connection_url = await this.storeGraphConnectionUrlAsSecret(env.connection_url, data.tag, env.slug);
3842
+ console.log('[ProductsService.createGraph] Connection URL after secret conversion:', {
3843
+ wasConverted: originalUrl !== env.connection_url,
3844
+ isSecretRef: (_c = env.connection_url) === null || _c === void 0 ? void 0 : _c.startsWith('$Secret{'),
3845
+ });
3529
3846
  env.connection_url = (0, processor_utils_1.encrypt)(env.connection_url, this.product.private_key);
3847
+ console.log('[ProductsService.createGraph] Connection URL encrypted');
3848
+ // Encrypt username and password if provided
3849
+ if (env.username) {
3850
+ console.log('[ProductsService.createGraph] Encrypting username for env:', env.slug);
3851
+ env.username = (0, processor_utils_1.encrypt)(env.username, this.product.private_key);
3852
+ }
3853
+ if (env.password) {
3854
+ console.log('[ProductsService.createGraph] Encrypting password for env:', env.slug);
3855
+ env.password = (0, processor_utils_1.encrypt)(env.password, this.product.private_key);
3856
+ }
3530
3857
  processedEnvs.push(env);
3858
+ console.log('[ProductsService.createGraph] Env processed successfully:', env.slug);
3531
3859
  }
3532
3860
  data.envs = processedEnvs;
3861
+ console.log('[ProductsService.createGraph] All envs processed, total:', processedEnvs.length);
3533
3862
  const envs = await this.fetchEnvs();
3534
3863
  for (const env of envs) {
3535
3864
  const exists = data.envs.findIndex((graphEnv) => graphEnv.slug === env.slug);
@@ -3549,24 +3878,64 @@ class ProductsBuilderService {
3549
3878
  }
3550
3879
  }
3551
3880
  async updateGraph(tag, data) {
3881
+ var _a, _b;
3882
+ console.log('[ProductsService.updateGraph] Starting graph update:', {
3883
+ tag,
3884
+ newTag: data.tag,
3885
+ name: data.name,
3886
+ type: data.type,
3887
+ envsCount: (_a = data.envs) === null || _a === void 0 ? void 0 : _a.length,
3888
+ productTag: (_b = this.product) === null || _b === void 0 ? void 0 : _b.tag,
3889
+ });
3552
3890
  try {
3553
3891
  const graph = await this.fetchGraph(tag);
3554
3892
  if (!graph) {
3555
3893
  throw new Error(`Graph ${tag} not found`);
3556
3894
  }
3557
3895
  const { _id, envs } = graph;
3896
+ console.log('[ProductsService.updateGraph] Found existing graph:', {
3897
+ _id,
3898
+ existingEnvsCount: envs === null || envs === void 0 ? void 0 : envs.length,
3899
+ });
3558
3900
  await validators_1.UpdateProductGraphSchema.validateAsync(data);
3559
3901
  if (data.tag && this.fetchGraph(data.tag)) {
3560
3902
  throw new Error(`tag ${tag} is in use`);
3561
3903
  }
3904
+ console.log('[ProductsService.updateGraph] Processing envs update');
3562
3905
  data.envs = await Promise.all(data.envs.map(async (env) => {
3906
+ var _a;
3907
+ console.log('[ProductsService.updateGraph] Processing env:', {
3908
+ slug: env.slug,
3909
+ hasConnectionUrl: !!env.connection_url,
3910
+ hasUsername: !!env.username,
3911
+ hasPassword: !!env.password,
3912
+ });
3563
3913
  const exists = await this.fetchEnv(env.slug);
3564
3914
  if (!exists) {
3565
3915
  throw new Error(`Env ${env.slug} does not exist`);
3566
3916
  }
3567
3917
  if (env.connection_url) {
3918
+ // Store connection URL as secret
3919
+ console.log('[ProductsService.updateGraph] Converting connection URL to secret for env:', env.slug);
3920
+ const originalUrl = env.connection_url;
3921
+ env.connection_url = await this.storeGraphConnectionUrlAsSecret(env.connection_url, data.tag || tag, env.slug);
3922
+ console.log('[ProductsService.updateGraph] Connection URL after secret conversion:', {
3923
+ wasConverted: originalUrl !== env.connection_url,
3924
+ isSecretRef: (_a = env.connection_url) === null || _a === void 0 ? void 0 : _a.startsWith('$Secret{'),
3925
+ });
3568
3926
  env.connection_url = (0, processor_utils_1.encrypt)(env.connection_url, this.product.private_key);
3927
+ console.log('[ProductsService.updateGraph] Connection URL encrypted');
3928
+ }
3929
+ // Encrypt username and password if provided
3930
+ if (env.username) {
3931
+ console.log('[ProductsService.updateGraph] Encrypting username for env:', env.slug);
3932
+ env.username = (0, processor_utils_1.encrypt)(env.username, this.product.private_key);
3569
3933
  }
3934
+ if (env.password) {
3935
+ console.log('[ProductsService.updateGraph] Encrypting password for env:', env.slug);
3936
+ env.password = (0, processor_utils_1.encrypt)(env.password, this.product.private_key);
3937
+ }
3938
+ console.log('[ProductsService.updateGraph] Env processed successfully:', env.slug);
3570
3939
  return env;
3571
3940
  }));
3572
3941
  const overwrite = [];
@@ -4270,11 +4639,599 @@ class ProductsBuilderService {
4270
4639
  workspace_id: this.workspace_id,
4271
4640
  token: this.token,
4272
4641
  public_key: this.public_key,
4642
+ access_key: this.access_key,
4273
4643
  };
4274
4644
  }
4275
4645
  async fetchSessionUser(ductape_user_id) {
4276
4646
  return await this.productApi.fetchProductSessionUser(ductape_user_id, this.getUserAccess());
4277
4647
  }
4648
+ /**
4649
+ * Process storage config to store sensitive credentials as secrets
4650
+ * Format: STORAGE_{PRODUCT}_{STORAGE_TAG}_{ENV}_{KEY}
4651
+ *
4652
+ * Product parsing: split by ":", select first element
4653
+ * Storage tag: replace "-" with "_"
4654
+ */
4655
+ async processStorageConfigSecrets(config, providerType, storageTag, envSlug) {
4656
+ console.log(`[Storage Secrets] Processing secrets for storage: ${storageTag}, env: ${envSlug}, provider: ${providerType}`);
4657
+ const secretsService = (0, secrets_1.getSecretsService)();
4658
+ if (!secretsService) {
4659
+ console.log(`[Storage Secrets] No secrets service available, skipping secret storage`);
4660
+ return config;
4661
+ }
4662
+ const generateSecretKey = (keyName) => {
4663
+ const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
4664
+ const productParts = this.product.tag.split(':');
4665
+ const productKey = productParts[1] || productParts[0]; // Use product name (index 1), fallback to index 0
4666
+ const storageKey = storageTag.replace(/-/g, '_');
4667
+ const key = `STORAGE_${sanitize(productKey)}_${sanitize(storageKey)}_${sanitize(envSlug)}_${sanitize(keyName)}`;
4668
+ console.log(`[Storage Secrets] Generated secret key: ${key}`);
4669
+ return key;
4670
+ };
4671
+ const storeAsSecret = async (value, keyName) => {
4672
+ const secretCheck = (0, secrets_1.isSecretReference)(value);
4673
+ if (secretCheck.isSecret) {
4674
+ console.log(`[Storage Secrets] ${keyName} is already a secret reference, skipping`);
4675
+ return value; // Already a secret reference
4676
+ }
4677
+ const secretKey = generateSecretKey(keyName);
4678
+ try {
4679
+ const exists = await secretsService.exists(secretKey);
4680
+ if (exists) {
4681
+ console.log(`[Storage Secrets] Updating existing secret: ${secretKey}`);
4682
+ await secretsService.update(secretKey, { value });
4683
+ }
4684
+ else {
4685
+ console.log(`[Storage Secrets] Creating new secret: ${secretKey}`);
4686
+ await secretsService.create({
4687
+ key: secretKey,
4688
+ value,
4689
+ description: `Storage ${keyName} for ${storageTag} in ${envSlug}`,
4690
+ scope: [this.product.tag, storageTag],
4691
+ envs: [envSlug],
4692
+ });
4693
+ }
4694
+ console.log(`[Storage Secrets] Successfully stored ${keyName} as secret: $Secret{${secretKey}}`);
4695
+ return `$Secret{${secretKey}}`;
4696
+ }
4697
+ catch (error) {
4698
+ console.warn(`[Storage Secrets] Failed to store storage credential as secret: ${error}`);
4699
+ return value;
4700
+ }
4701
+ };
4702
+ if (providerType === productsBuilder_types_1.StorageProviders.AWS) {
4703
+ console.log(`[Storage Secrets] Processing AWS S3 credentials`);
4704
+ const awsConfig = config;
4705
+ const result = Object.assign(Object.assign({}, awsConfig), { accessKeyId: await storeAsSecret(awsConfig.accessKeyId, 'ACCESS_KEY_ID'), secretAccessKey: await storeAsSecret(awsConfig.secretAccessKey, 'SECRET_ACCESS_KEY') });
4706
+ console.log(`[Storage Secrets] AWS S3 config processed successfully`);
4707
+ return result;
4708
+ }
4709
+ else if (providerType === productsBuilder_types_1.StorageProviders.GCP) {
4710
+ console.log(`[Storage Secrets] Processing GCP credentials`);
4711
+ const gcpConfig = config;
4712
+ if (gcpConfig.config) {
4713
+ const processedConfig = Object.assign({}, gcpConfig.config);
4714
+ // Store private_key_id as secret
4715
+ if (processedConfig.private_key_id) {
4716
+ processedConfig.private_key_id = await storeAsSecret(processedConfig.private_key_id, 'PRIVATE_KEY_ID');
4717
+ }
4718
+ // Store private_key as secret
4719
+ if (processedConfig.private_key) {
4720
+ processedConfig.private_key = await storeAsSecret(processedConfig.private_key, 'PRIVATE_KEY');
4721
+ }
4722
+ // Store client_email as secret
4723
+ if (processedConfig.client_email) {
4724
+ processedConfig.client_email = await storeAsSecret(processedConfig.client_email, 'CLIENT_EMAIL');
4725
+ }
4726
+ // Store client_id as secret
4727
+ if (processedConfig.client_id) {
4728
+ processedConfig.client_id = await storeAsSecret(processedConfig.client_id, 'CLIENT_ID');
4729
+ }
4730
+ const result = Object.assign(Object.assign({}, gcpConfig), { config: processedConfig });
4731
+ console.log(`[Storage Secrets] GCP config processed successfully`);
4732
+ console.log(`[Storage Secrets] Converted GCP config:`, JSON.stringify(result, null, 2));
4733
+ return result;
4734
+ }
4735
+ console.log(`[Storage Secrets] GCP config has no nested config, skipping`);
4736
+ return gcpConfig;
4737
+ }
4738
+ else if (providerType === productsBuilder_types_1.StorageProviders.AZURE) {
4739
+ console.log(`[Storage Secrets] Processing Azure Blob credentials`);
4740
+ const azureConfig = config;
4741
+ const result = Object.assign(Object.assign({}, azureConfig), { connectionString: await storeAsSecret(azureConfig.connectionString, 'CONNECTION_STRING') });
4742
+ console.log(`[Storage Secrets] Azure Blob config processed successfully`);
4743
+ return result;
4744
+ }
4745
+ console.log(`[Storage Secrets] Unknown provider type: ${providerType}, returning config as-is`);
4746
+ return config;
4747
+ }
4748
+ /**
4749
+ * Process message broker config to store sensitive credentials as secrets
4750
+ * Format: BROKER_{PRODUCT}_{BROKER_TAG}_{ENV}_{KEY}
4751
+ *
4752
+ * Product parsing: split by ":", select first element
4753
+ * Broker tag: replace "-" with "_"
4754
+ */
4755
+ async processMessageBrokerConfigSecrets(config, brokerType, brokerTag, envSlug) {
4756
+ var _a, _b, _c, _d, _e, _f, _g;
4757
+ const logPrefix = '[MessageBroker:Secrets]';
4758
+ console.log(`${logPrefix} Processing secrets for broker: ${brokerTag}, env: ${envSlug}, type: ${brokerType}`);
4759
+ const secretsService = (0, secrets_1.getSecretsService)();
4760
+ if (!secretsService) {
4761
+ console.log(`${logPrefix} No secrets service available, skipping secret storage`);
4762
+ return config;
4763
+ }
4764
+ console.log(`${logPrefix} Secrets service available`);
4765
+ const generateSecretKey = (keyName) => {
4766
+ const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
4767
+ const productParts = this.product.tag.split(':');
4768
+ const productKey = productParts[1] || productParts[0];
4769
+ const brokerKey = brokerTag.replace(/-/g, '_');
4770
+ const key = `BROKER_${sanitize(productKey)}_${sanitize(brokerKey)}_${sanitize(envSlug)}_${sanitize(keyName)}`;
4771
+ console.log(`${logPrefix} Generated secret key: ${key}`);
4772
+ return key;
4773
+ };
4774
+ const storeAsSecret = async (value, keyName) => {
4775
+ console.log(`${logPrefix} Processing field: ${keyName}`);
4776
+ if (!value) {
4777
+ console.log(`${logPrefix} Field ${keyName} is empty, skipping`);
4778
+ return value;
4779
+ }
4780
+ const secretCheck = (0, secrets_1.isSecretReference)(value);
4781
+ if (secretCheck.isSecret) {
4782
+ console.log(`${logPrefix} Field ${keyName} is already a secret reference: ${value}`);
4783
+ return value;
4784
+ }
4785
+ const secretKey = generateSecretKey(keyName);
4786
+ console.log(`${logPrefix} Storing ${keyName} as secret with key: ${secretKey}`);
4787
+ try {
4788
+ const exists = await secretsService.exists(secretKey);
4789
+ console.log(`${logPrefix} Secret ${secretKey} exists: ${exists}`);
4790
+ if (exists) {
4791
+ console.log(`${logPrefix} Updating existing secret: ${secretKey}`);
4792
+ await secretsService.update(secretKey, { value });
4793
+ console.log(`${logPrefix} Secret ${secretKey} updated successfully`);
4794
+ }
4795
+ else {
4796
+ console.log(`${logPrefix} Creating new secret: ${secretKey}`);
4797
+ await secretsService.create({
4798
+ key: secretKey,
4799
+ value,
4800
+ description: `Message broker ${keyName} for ${brokerTag} in ${envSlug}`,
4801
+ scope: [this.product.tag, brokerTag],
4802
+ envs: [envSlug],
4803
+ });
4804
+ console.log(`${logPrefix} Secret ${secretKey} created successfully`);
4805
+ }
4806
+ const secretRef = `$Secret{${secretKey}}`;
4807
+ console.log(`${logPrefix} Field ${keyName} converted to secret reference: ${secretRef}`);
4808
+ return secretRef;
4809
+ }
4810
+ catch (error) {
4811
+ console.error(`${logPrefix} Failed to store ${keyName} as secret:`, error);
4812
+ console.warn(`${logPrefix} Returning original value for ${keyName}`);
4813
+ return value;
4814
+ }
4815
+ };
4816
+ // Handle different broker types - config is passed directly without wrapper
4817
+ console.log(`${logPrefix} Processing broker type: ${brokerType}`);
4818
+ if (brokerType === productsBuilder_types_1.MessageBrokerTypes.REDIS) {
4819
+ console.log(`${logPrefix} Redis config detected`);
4820
+ console.log(`${logPrefix} Redis fields - host: ${config.host}, port: ${config.port}, password: ${config.password ? '[SET]' : '[NOT SET]'}`);
4821
+ if (config.password) {
4822
+ config.password = await storeAsSecret(config.password, 'PASSWORD');
4823
+ }
4824
+ }
4825
+ else if (brokerType === productsBuilder_types_1.MessageBrokerTypes.RABBITMQ) {
4826
+ console.log(`${logPrefix} RabbitMQ config detected`);
4827
+ console.log(`${logPrefix} RabbitMQ fields - url: ${config.url ? '[SET]' : '[NOT SET]'}`);
4828
+ if (config.url) {
4829
+ config.url = await storeAsSecret(config.url, 'URL');
4830
+ }
4831
+ }
4832
+ else if (brokerType === productsBuilder_types_1.MessageBrokerTypes.KAFKA) {
4833
+ console.log(`${logPrefix} Kafka config detected`);
4834
+ console.log(`${logPrefix} Kafka fields - brokers: ${(_a = config.brokers) === null || _a === void 0 ? void 0 : _a.join(', ')}, clientId: ${config.clientId}, ssl: ${config.ssl}`);
4835
+ console.log(`${logPrefix} Kafka SASL - mechanism: ${((_b = config.sasl) === null || _b === void 0 ? void 0 : _b.mechanism) || 'N/A'}, username: ${((_c = config.sasl) === null || _c === void 0 ? void 0 : _c.username) ? '[SET]' : '[NOT SET]'}, password: ${((_d = config.sasl) === null || _d === void 0 ? void 0 : _d.password) ? '[SET]' : '[NOT SET]'}`);
4836
+ if ((_e = config.sasl) === null || _e === void 0 ? void 0 : _e.username) {
4837
+ config.sasl.username = await storeAsSecret(config.sasl.username, 'SASL_USERNAME');
4838
+ }
4839
+ if ((_f = config.sasl) === null || _f === void 0 ? void 0 : _f.password) {
4840
+ config.sasl.password = await storeAsSecret(config.sasl.password, 'SASL_PASSWORD');
4841
+ }
4842
+ }
4843
+ else if (brokerType === productsBuilder_types_1.MessageBrokerTypes.AWS_SQS) {
4844
+ console.log(`${logPrefix} AWS SQS config detected`);
4845
+ console.log(`${logPrefix} AWS SQS fields - region: ${config.region}, accessKeyId: ${config.accessKeyId ? '[SET]' : '[NOT SET]'}, secretAccessKey: ${config.secretAccessKey ? '[SET]' : '[NOT SET]'}`);
4846
+ if (config.accessKeyId) {
4847
+ config.accessKeyId = await storeAsSecret(config.accessKeyId, 'ACCESS_KEY_ID');
4848
+ }
4849
+ if (config.secretAccessKey) {
4850
+ config.secretAccessKey = await storeAsSecret(config.secretAccessKey, 'SECRET_ACCESS_KEY');
4851
+ }
4852
+ }
4853
+ else if (brokerType === productsBuilder_types_1.MessageBrokerTypes.NATS) {
4854
+ console.log(`${logPrefix} NATS config detected`);
4855
+ console.log(`${logPrefix} NATS fields - servers: ${(_g = config.servers) === null || _g === void 0 ? void 0 : _g.join(', ')}, token: ${config.token ? '[SET]' : '[NOT SET]'}, user: ${config.user ? '[SET]' : '[NOT SET]'}, pass: ${config.pass ? '[SET]' : '[NOT SET]'}, tls: ${config.tls}`);
4856
+ if (config.token) {
4857
+ config.token = await storeAsSecret(config.token, 'TOKEN');
4858
+ }
4859
+ if (config.user) {
4860
+ config.user = await storeAsSecret(config.user, 'USER');
4861
+ }
4862
+ if (config.pass) {
4863
+ config.pass = await storeAsSecret(config.pass, 'PASSWORD');
4864
+ }
4865
+ }
4866
+ else if (brokerType === productsBuilder_types_1.MessageBrokerTypes.GOOGLE_PUBSUB) {
4867
+ console.log(`${logPrefix} Google Pub/Sub config detected`);
4868
+ console.log(`${logPrefix} Google Pub/Sub fields - projectId: ${config.projectId}, credentials: ${config.credentials ? '[SET]' : '[NOT SET]'}`);
4869
+ if (config.credentials) {
4870
+ console.log(`${logPrefix} Google Pub/Sub credentials - type: ${config.credentials.type}, project_id: ${config.credentials.project_id}`);
4871
+ console.log(`${logPrefix} Google Pub/Sub credentials - private_key_id: ${config.credentials.private_key_id ? '[SET]' : '[NOT SET]'}, private_key: ${config.credentials.private_key ? '[SET]' : '[NOT SET]'}`);
4872
+ console.log(`${logPrefix} Google Pub/Sub credentials - client_email: ${config.credentials.client_email ? '[SET]' : '[NOT SET]'}, client_id: ${config.credentials.client_id ? '[SET]' : '[NOT SET]'}`);
4873
+ if (config.credentials.private_key_id) {
4874
+ config.credentials.private_key_id = await storeAsSecret(config.credentials.private_key_id, 'PRIVATE_KEY_ID');
4875
+ }
4876
+ if (config.credentials.private_key) {
4877
+ config.credentials.private_key = await storeAsSecret(config.credentials.private_key, 'PRIVATE_KEY');
4878
+ }
4879
+ if (config.credentials.client_email) {
4880
+ config.credentials.client_email = await storeAsSecret(config.credentials.client_email, 'CLIENT_EMAIL');
4881
+ }
4882
+ if (config.credentials.client_id) {
4883
+ config.credentials.client_id = await storeAsSecret(config.credentials.client_id, 'CLIENT_ID');
4884
+ }
4885
+ }
4886
+ }
4887
+ else {
4888
+ console.log(`${logPrefix} Unknown broker type: ${brokerType}, no secrets processing`);
4889
+ }
4890
+ console.log(`${logPrefix} Secrets processing completed for ${brokerTag}:${envSlug}`);
4891
+ return config;
4892
+ }
4893
+ /**
4894
+ * Process notification environment config to store sensitive credentials as secrets
4895
+ * Format: NOTIFIER_{PRODUCT}_{NOTIFIER_TAG}_{ENV}_{KEY}
4896
+ *
4897
+ * Product parsing: split by ":", select first element
4898
+ * Notifier tag: replace "-" with "_"
4899
+ */
4900
+ async processNotificationEnvSecrets(env, notifierTag, envSlug) {
4901
+ var _a, _b;
4902
+ const secretsService = (0, secrets_1.getSecretsService)();
4903
+ if (!secretsService) {
4904
+ return env;
4905
+ }
4906
+ const generateSecretKey = (keyName) => {
4907
+ const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
4908
+ const productParts = this.product.tag.split(':');
4909
+ const productKey = productParts[1] || productParts[0]; // Use product name (index 1), fallback to index 0
4910
+ const notifierKey = notifierTag.replace(/-/g, '_');
4911
+ return `NOTIFIER_${sanitize(productKey)}_${sanitize(notifierKey)}_${sanitize(envSlug)}_${sanitize(keyName)}`;
4912
+ };
4913
+ const storeAsSecret = async (value, keyName) => {
4914
+ if (!value)
4915
+ return value;
4916
+ const secretCheck = (0, secrets_1.isSecretReference)(value);
4917
+ if (secretCheck.isSecret) {
4918
+ return value; // Already a secret reference
4919
+ }
4920
+ const secretKey = generateSecretKey(keyName);
4921
+ try {
4922
+ const exists = await secretsService.exists(secretKey);
4923
+ if (exists) {
4924
+ await secretsService.update(secretKey, { value });
4925
+ }
4926
+ else {
4927
+ await secretsService.create({
4928
+ key: secretKey,
4929
+ value,
4930
+ description: `Notification ${keyName} for ${notifierTag} in ${envSlug}`,
4931
+ scope: [this.product.tag, notifierTag],
4932
+ envs: [envSlug],
4933
+ });
4934
+ }
4935
+ return `$Secret{${secretKey}}`;
4936
+ }
4937
+ catch (error) {
4938
+ console.warn(`Failed to store notification credential as secret: ${error}`);
4939
+ return value;
4940
+ }
4941
+ };
4942
+ const result = Object.assign({}, env);
4943
+ // Process email handler
4944
+ if ((_a = result.emails) === null || _a === void 0 ? void 0 : _a.auth) {
4945
+ result.emails = Object.assign(Object.assign({}, result.emails), { auth: Object.assign(Object.assign({}, result.emails.auth), { pass: await storeAsSecret(result.emails.auth.pass, 'EMAIL_PASSWORD') }) });
4946
+ }
4947
+ // Process SMS handler
4948
+ if (result.sms) {
4949
+ const smsUpdates = {};
4950
+ if (result.sms.authToken) {
4951
+ smsUpdates.authToken = await storeAsSecret(result.sms.authToken, 'SMS_AUTH_TOKEN');
4952
+ }
4953
+ if (result.sms.apiSecret) {
4954
+ smsUpdates.apiSecret = await storeAsSecret(result.sms.apiSecret, 'SMS_API_SECRET');
4955
+ }
4956
+ if (result.sms.apiKey) {
4957
+ smsUpdates.apiKey = await storeAsSecret(result.sms.apiKey, 'SMS_API_KEY');
4958
+ }
4959
+ if (result.sms.accountSid) {
4960
+ smsUpdates.accountSid = await storeAsSecret(result.sms.accountSid, 'SMS_ACCOUNT_SID');
4961
+ }
4962
+ result.sms = Object.assign(Object.assign({}, result.sms), smsUpdates);
4963
+ }
4964
+ // Process push notifications handler (Firebase credentials)
4965
+ if ((_b = result.push_notifications) === null || _b === void 0 ? void 0 : _b.credentials) {
4966
+ const creds = result.push_notifications.credentials;
4967
+ if (creds.private_key) {
4968
+ result.push_notifications = Object.assign(Object.assign({}, result.push_notifications), { credentials: Object.assign(Object.assign({}, creds), { private_key: await storeAsSecret(creds.private_key, 'PUSH_PRIVATE_KEY') }) });
4969
+ }
4970
+ }
4971
+ return result;
4972
+ }
4973
+ /**
4974
+ * Store graph connection URL as a secret
4975
+ * Format: GRAPH_{PRODUCT}_{GRAPH_TAG}_{ENV}_URL
4976
+ */
4977
+ async storeGraphConnectionUrlAsSecret(connectionUrl, graphTag, envSlug) {
4978
+ var _a;
4979
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Starting secret conversion:', {
4980
+ graphTag,
4981
+ envSlug,
4982
+ hasConnectionUrl: !!connectionUrl,
4983
+ connectionUrlLength: connectionUrl === null || connectionUrl === void 0 ? void 0 : connectionUrl.length,
4984
+ productTag: (_a = this.product) === null || _a === void 0 ? void 0 : _a.tag,
4985
+ });
4986
+ const secretsService = (0, secrets_1.getSecretsService)();
4987
+ if (!secretsService) {
4988
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] No secrets service available, returning original value');
4989
+ return connectionUrl;
4990
+ }
4991
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Secrets service is available');
4992
+ const secretCheck = (0, secrets_1.isSecretReference)(connectionUrl);
4993
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Secret reference check:', {
4994
+ isSecret: secretCheck.isSecret,
4995
+ secretKey: secretCheck.isSecret ? secretCheck.key : null,
4996
+ });
4997
+ if (secretCheck.isSecret) {
4998
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Value is already a secret reference, returning as-is');
4999
+ return connectionUrl;
5000
+ }
5001
+ const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
5002
+ const productParts = this.product.tag.split(':');
5003
+ const productKey = productParts[1] || productParts[0]; // Use product name (index 1), fallback to index 0
5004
+ const graphKey = graphTag.replace(/-/g, '_');
5005
+ const secretKey = `GRAPH_${sanitize(productKey)}_${sanitize(graphKey)}_${sanitize(envSlug)}_URL`;
5006
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Generated secret key:', {
5007
+ secretKey,
5008
+ productParts,
5009
+ productKey,
5010
+ graphKey,
5011
+ });
5012
+ try {
5013
+ const exists = await secretsService.exists(secretKey);
5014
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Secret exists check:', { secretKey, exists });
5015
+ if (exists) {
5016
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Updating existing secret:', secretKey);
5017
+ await secretsService.update(secretKey, { value: connectionUrl });
5018
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Secret updated successfully');
5019
+ }
5020
+ else {
5021
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Creating new secret:', {
5022
+ secretKey,
5023
+ description: `Graph connection URL for ${graphTag} in ${envSlug}`,
5024
+ scope: [this.product.tag, graphTag],
5025
+ envs: [envSlug],
5026
+ });
5027
+ await secretsService.create({
5028
+ key: secretKey,
5029
+ value: connectionUrl,
5030
+ description: `Graph connection URL for ${graphTag} in ${envSlug}`,
5031
+ scope: [this.product.tag, graphTag],
5032
+ envs: [envSlug],
5033
+ });
5034
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Secret created successfully');
5035
+ }
5036
+ const secretRef = `$Secret{${secretKey}}`;
5037
+ console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Returning secret reference:', secretRef);
5038
+ return secretRef;
5039
+ }
5040
+ catch (error) {
5041
+ console.error('[ProductsService.storeGraphConnectionUrlAsSecret] Failed to store secret:', {
5042
+ secretKey,
5043
+ error: error instanceof Error ? error.message : String(error),
5044
+ stack: error instanceof Error ? error.stack : undefined,
5045
+ });
5046
+ return connectionUrl;
5047
+ }
5048
+ }
5049
+ /**
5050
+ * Generate a secret key for vector configuration field
5051
+ * Format: VECTOR_{PRODUCT}_{ASSET_TAG}_{ENV}_{KEY}
5052
+ *
5053
+ * Where:
5054
+ * - PRODUCT = productTag.split('.')[1] (second part after workspace)
5055
+ * - ASSET_TAG = if vectorTag starts with same workspace prefix, use second part; otherwise sanitize full tag
5056
+ * - All parts are automatically capitalized
5057
+ */
5058
+ generateVectorSecretKey(vectorTag, envSlug, field) {
5059
+ var _a;
5060
+ console.log('[ProductsService.generateVectorSecretKey] Generating secret key:', {
5061
+ vectorTag,
5062
+ envSlug,
5063
+ field,
5064
+ productTag: (_a = this.product) === null || _a === void 0 ? void 0 : _a.tag,
5065
+ });
5066
+ const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
5067
+ // Support both ':' and '.' delimiters for product tags (e.g., 'ductape:rematch' or 'ductape.rematch')
5068
+ const productParts = this.product.tag.includes(':')
5069
+ ? this.product.tag.split(':')
5070
+ : this.product.tag.split('.');
5071
+ const product = productParts[1] || productParts[0]; // Use product name (index 1), fallback to index 0
5072
+ const workspace = productParts[0];
5073
+ console.log('[ProductsService.generateVectorSecretKey] Product parsing:', {
5074
+ productParts,
5075
+ product,
5076
+ workspace,
5077
+ });
5078
+ // Support both ':' and '.' delimiters for vector tags
5079
+ const vectorParts = vectorTag.includes(':') ? vectorTag.split(':') : vectorTag.split('.');
5080
+ let assetTag;
5081
+ if (vectorParts.length > 1 && vectorParts[0] === workspace) {
5082
+ // Same workspace prefix, use second part
5083
+ assetTag = vectorParts[1];
5084
+ console.log('[ProductsService.generateVectorSecretKey] Using second part of vectorTag:', assetTag);
5085
+ }
5086
+ else {
5087
+ // Different or no prefix, use full tag
5088
+ assetTag = vectorTag;
5089
+ console.log('[ProductsService.generateVectorSecretKey] Using full vectorTag:', assetTag);
5090
+ }
5091
+ const secretKey = `VECTOR_${sanitize(product)}_${sanitize(assetTag)}_${sanitize(envSlug)}_${sanitize(field)}`;
5092
+ console.log('[ProductsService.generateVectorSecretKey] Generated secret key:', secretKey);
5093
+ return secretKey;
5094
+ }
5095
+ /**
5096
+ * Store a vector field value as a secret if it exists and is not already a secret reference
5097
+ * @returns The secret reference if stored, or the original value
5098
+ */
5099
+ async storeVectorFieldAsSecret(value, vectorTag, envSlug, fieldName, description) {
5100
+ var _a;
5101
+ console.log('[ProductsService.storeVectorFieldAsSecret] Starting secret conversion:', {
5102
+ vectorTag,
5103
+ envSlug,
5104
+ fieldName,
5105
+ hasValue: !!value,
5106
+ valueLength: value === null || value === void 0 ? void 0 : value.length,
5107
+ productTag: (_a = this.product) === null || _a === void 0 ? void 0 : _a.tag,
5108
+ });
5109
+ if (!value) {
5110
+ console.log('[ProductsService.storeVectorFieldAsSecret] No value provided, returning undefined');
5111
+ return undefined;
5112
+ }
5113
+ const secretsService = (0, secrets_1.getSecretsService)();
5114
+ if (!secretsService) {
5115
+ console.log('[ProductsService.storeVectorFieldAsSecret] No secrets service available, returning original value');
5116
+ return value;
5117
+ }
5118
+ console.log('[ProductsService.storeVectorFieldAsSecret] Secrets service is available');
5119
+ const secretCheck = (0, secrets_1.isSecretReference)(value);
5120
+ console.log('[ProductsService.storeVectorFieldAsSecret] Secret reference check:', {
5121
+ isSecret: secretCheck.isSecret,
5122
+ secretKey: secretCheck.isSecret ? secretCheck.key : null,
5123
+ });
5124
+ if (secretCheck.isSecret) {
5125
+ console.log('[ProductsService.storeVectorFieldAsSecret] Value is already a secret reference, returning as-is');
5126
+ return value;
5127
+ }
5128
+ const secretKey = this.generateVectorSecretKey(vectorTag, envSlug, fieldName);
5129
+ console.log('[ProductsService.storeVectorFieldAsSecret] Generated secret key:', secretKey);
5130
+ try {
5131
+ const exists = await secretsService.exists(secretKey);
5132
+ console.log('[ProductsService.storeVectorFieldAsSecret] Secret exists check:', { secretKey, exists });
5133
+ if (exists) {
5134
+ console.log('[ProductsService.storeVectorFieldAsSecret] Updating existing secret:', secretKey);
5135
+ await secretsService.update(secretKey, { value });
5136
+ console.log('[ProductsService.storeVectorFieldAsSecret] Secret updated successfully');
5137
+ }
5138
+ else {
5139
+ console.log('[ProductsService.storeVectorFieldAsSecret] Creating new secret:', {
5140
+ secretKey,
5141
+ description,
5142
+ scope: [this.product.tag, vectorTag],
5143
+ envs: [envSlug],
5144
+ });
5145
+ await secretsService.create({
5146
+ key: secretKey,
5147
+ value,
5148
+ description,
5149
+ scope: [this.product.tag, vectorTag],
5150
+ envs: [envSlug],
5151
+ });
5152
+ console.log('[ProductsService.storeVectorFieldAsSecret] Secret created successfully');
5153
+ }
5154
+ const secretRef = `$Secret{${secretKey}}`;
5155
+ console.log('[ProductsService.storeVectorFieldAsSecret] Returning secret reference:', secretRef);
5156
+ return secretRef;
5157
+ }
5158
+ catch (error) {
5159
+ console.error('[ProductsService.storeVectorFieldAsSecret] Failed to store secret:', {
5160
+ secretKey,
5161
+ fieldName,
5162
+ error: error instanceof Error ? error.message : String(error),
5163
+ stack: error instanceof Error ? error.stack : undefined,
5164
+ });
5165
+ return value;
5166
+ }
5167
+ }
5168
+ async storeVectorApiKeyAsSecret(apiKey, vectorTag, envSlug) {
5169
+ console.log('[ProductsService.storeVectorApiKeyAsSecret] Storing API key as secret:', {
5170
+ vectorTag,
5171
+ envSlug,
5172
+ hasApiKey: !!apiKey,
5173
+ apiKeyLength: apiKey === null || apiKey === void 0 ? void 0 : apiKey.length,
5174
+ });
5175
+ const result = await this.storeVectorFieldAsSecret(apiKey, vectorTag, envSlug, 'API_KEY', `Vector API key for ${vectorTag} in ${envSlug}`);
5176
+ console.log('[ProductsService.storeVectorApiKeyAsSecret] Result:', {
5177
+ hasResult: !!result,
5178
+ isSecretRef: result === null || result === void 0 ? void 0 : result.startsWith('$Secret{'),
5179
+ });
5180
+ return result || apiKey;
5181
+ }
5182
+ async storeVectorEndpointAsSecret(endpoint, vectorTag, envSlug) {
5183
+ console.log('[ProductsService.storeVectorEndpointAsSecret] Storing endpoint as secret:', {
5184
+ vectorTag,
5185
+ envSlug,
5186
+ hasEndpoint: !!endpoint,
5187
+ endpointLength: endpoint === null || endpoint === void 0 ? void 0 : endpoint.length,
5188
+ });
5189
+ const result = await this.storeVectorFieldAsSecret(endpoint, vectorTag, envSlug, 'ENDPOINT', `Vector endpoint for ${vectorTag} in ${envSlug}`);
5190
+ console.log('[ProductsService.storeVectorEndpointAsSecret] Result:', {
5191
+ hasResult: !!result,
5192
+ isSecretRef: result === null || result === void 0 ? void 0 : result.startsWith('$Secret{'),
5193
+ });
5194
+ return result || endpoint;
5195
+ }
5196
+ /**
5197
+ * Store LLM model API key as a secret
5198
+ * Format: MODEL_{PRODUCT}_{MODEL_TAG}_{ENV}_API_KEY
5199
+ */
5200
+ async storeModelApiKeyAsSecret(apiKey, modelTag, envSlug) {
5201
+ const secretsService = (0, secrets_1.getSecretsService)();
5202
+ if (!secretsService) {
5203
+ return apiKey;
5204
+ }
5205
+ const secretCheck = (0, secrets_1.isSecretReference)(apiKey);
5206
+ if (secretCheck.isSecret) {
5207
+ return apiKey;
5208
+ }
5209
+ const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
5210
+ const productParts = this.product.tag.split(':');
5211
+ const productKey = productParts[1] || productParts[0]; // Use product name (index 1), fallback to index 0
5212
+ const modelKey = modelTag.replace(/-/g, '_');
5213
+ const secretKey = `MODEL_${sanitize(productKey)}_${sanitize(modelKey)}_${sanitize(envSlug)}_API_KEY`;
5214
+ try {
5215
+ const exists = await secretsService.exists(secretKey);
5216
+ if (exists) {
5217
+ await secretsService.update(secretKey, { value: apiKey });
5218
+ }
5219
+ else {
5220
+ await secretsService.create({
5221
+ key: secretKey,
5222
+ value: apiKey,
5223
+ description: `LLM model API key for ${modelTag} in ${envSlug}`,
5224
+ scope: [this.product.tag, modelTag],
5225
+ envs: [envSlug],
5226
+ });
5227
+ }
5228
+ return `$Secret{${secretKey}}`;
5229
+ }
5230
+ catch (error) {
5231
+ console.warn(`Failed to store model API key as secret: ${error}`);
5232
+ return apiKey;
5233
+ }
5234
+ }
4278
5235
  }
4279
5236
  exports.default = ProductsBuilderService;
4280
5237
  //# sourceMappingURL=products.service.js.map