@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.
- package/dist/agents/agents.service.d.ts +8 -2
- package/dist/agents/agents.service.js +5 -0
- package/dist/agents/agents.service.js.map +1 -1
- package/dist/agents/types/agents.types.d.ts +2 -0
- package/dist/agents/types/agents.types.js.map +1 -1
- package/dist/agents/vector-store-adapter.js +5 -5
- package/dist/agents/vector-store-adapter.js.map +1 -1
- package/dist/api/services/appApi.service.d.ts +3 -3
- package/dist/api/services/appApi.service.js.map +1 -1
- package/dist/api/services/productsApi.service.d.ts +1 -1
- package/dist/api/services/productsApi.service.js +20 -13
- package/dist/api/services/productsApi.service.js.map +1 -1
- package/dist/api/services/secretsApi.service.d.ts +12 -0
- package/dist/api/services/secretsApi.service.js +30 -2
- package/dist/api/services/secretsApi.service.js.map +1 -1
- package/dist/api/services/workspaceApi.service.d.ts +8 -0
- package/dist/api/services/workspaceApi.service.js +20 -0
- package/dist/api/services/workspaceApi.service.js.map +1 -1
- package/dist/api/urls.d.ts +2 -0
- package/dist/api/urls.js +10 -15
- package/dist/api/urls.js.map +1 -1
- package/dist/api/utils/auth.utils.d.ts +1 -3
- package/dist/api/utils/auth.utils.js.map +1 -1
- package/dist/apps/utils/oauth-manager.js +27 -3
- package/dist/apps/utils/oauth-manager.js.map +1 -1
- package/dist/brokers/brokers.service.d.ts +8 -0
- package/dist/brokers/brokers.service.js +50 -4
- package/dist/brokers/brokers.service.js.map +1 -1
- package/dist/brokers/types/index.d.ts +26 -0
- package/dist/brokers/utils/providers/kafka.service.d.ts +7 -0
- package/dist/brokers/utils/providers/kafka.service.js +102 -23
- package/dist/brokers/utils/providers/kafka.service.js.map +1 -1
- package/dist/brokers/utils/providers/rabbitmq.service.d.ts +2 -1
- package/dist/brokers/utils/providers/rabbitmq.service.js +99 -15
- package/dist/brokers/utils/providers/rabbitmq.service.js.map +1 -1
- package/dist/database/adapters/cassandra.adapter.d.ts +1 -0
- package/dist/database/adapters/cassandra.adapter.js +100 -44
- package/dist/database/adapters/cassandra.adapter.js.map +1 -1
- package/dist/database/adapters/dynamodb.adapter.d.ts +1 -0
- package/dist/database/adapters/dynamodb.adapter.js +89 -20
- package/dist/database/adapters/dynamodb.adapter.js.map +1 -1
- package/dist/database/adapters/mongodb.adapter.d.ts +1 -0
- package/dist/database/adapters/mongodb.adapter.js +123 -45
- package/dist/database/adapters/mongodb.adapter.js.map +1 -1
- package/dist/database/adapters/mysql.adapter.d.ts +1 -0
- package/dist/database/adapters/mysql.adapter.js +125 -48
- package/dist/database/adapters/mysql.adapter.js.map +1 -1
- package/dist/database/adapters/postgresql.adapter.d.ts +5 -0
- package/dist/database/adapters/postgresql.adapter.js +151 -50
- package/dist/database/adapters/postgresql.adapter.js.map +1 -1
- package/dist/database/databases.service.d.ts +15 -1
- package/dist/database/databases.service.js +143 -2
- package/dist/database/databases.service.js.map +1 -1
- package/dist/database/operators/aggregation-builder.d.ts +11 -8
- package/dist/database/operators/aggregation-builder.js +184 -89
- package/dist/database/operators/aggregation-builder.js.map +1 -1
- package/dist/database/operators/query-builder.d.ts +23 -19
- package/dist/database/operators/query-builder.js +77 -45
- package/dist/database/operators/query-builder.js.map +1 -1
- package/dist/database/types/aggregation.interface.d.ts +21 -15
- package/dist/database/types/query.interface.d.ts +27 -21
- package/dist/database/types/write.interface.d.ts +20 -12
- package/dist/graph/adapters/arangodb.adapter.js +61 -22
- package/dist/graph/adapters/arangodb.adapter.js.map +1 -1
- package/dist/graph/adapters/memgraph.adapter.js +22 -16
- package/dist/graph/adapters/memgraph.adapter.js.map +1 -1
- package/dist/graph/adapters/neo4j.adapter.js +51 -21
- package/dist/graph/adapters/neo4j.adapter.js.map +1 -1
- package/dist/graph/adapters/neptune.adapter.js +32 -16
- package/dist/graph/adapters/neptune.adapter.js.map +1 -1
- package/dist/graph/graphs.service.d.ts +24 -2
- package/dist/graph/graphs.service.js +238 -28
- package/dist/graph/graphs.service.js.map +1 -1
- package/dist/graph/types/connection.interface.d.ts +8 -0
- package/dist/graph/types/query.interface.d.ts +21 -14
- package/dist/index.d.ts +367 -20
- package/dist/index.js +510 -48
- package/dist/index.js.map +1 -1
- package/dist/inputs/inputs.service.d.ts +1 -1
- package/dist/notifications/notifications.service.d.ts +7 -2
- package/dist/notifications/notifications.service.js +2 -0
- package/dist/notifications/notifications.service.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +5 -1
- package/dist/processor/services/processor.service.js +35 -2
- package/dist/processor/services/processor.service.js.map +1 -1
- package/dist/products/services/products.service.d.ts +76 -2
- package/dist/products/services/products.service.js +984 -27
- package/dist/products/services/products.service.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productAgent.validator.js +52 -4
- package/dist/products/validators/joi-validators/create.productAgent.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productGraph.validator.js +2 -0
- package/dist/products/validators/joi-validators/create.productGraph.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js +1 -7
- package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productVector.validator.js +4 -4
- package/dist/products/validators/joi-validators/create.productVector.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productGraph.validator.js +2 -0
- package/dist/products/validators/joi-validators/update.productGraph.validator.js.map +1 -1
- package/dist/resilience/fallback.service.d.ts +4 -1
- package/dist/resilience/fallback.service.js +8 -10
- package/dist/resilience/fallback.service.js.map +1 -1
- package/dist/resilience/healthcheck.service.d.ts +6 -1
- package/dist/resilience/healthcheck.service.js +9 -0
- package/dist/resilience/healthcheck.service.js.map +1 -1
- package/dist/resilience/quota.service.d.ts +4 -1
- package/dist/resilience/quota.service.js +2 -0
- package/dist/resilience/quota.service.js.map +1 -1
- package/dist/resilience/resilience.service.d.ts +4 -1
- package/dist/resilience/resilience.service.js.map +1 -1
- package/dist/secrets/secrets.service.d.ts +11 -1
- package/dist/secrets/secrets.service.js +109 -10
- package/dist/secrets/secrets.service.js.map +1 -1
- package/dist/storage/storage.service.d.ts +4 -1
- package/dist/storage/storage.service.js +6 -1
- package/dist/storage/storage.service.js.map +1 -1
- package/dist/test/index.js +1 -3
- package/dist/test/index.js.map +1 -1
- package/dist/test/test.broker.kafka.d.ts +1 -0
- package/dist/test/test.broker.kafka.js +172 -0
- package/dist/test/test.broker.kafka.js.map +1 -0
- package/dist/test/test.broker.nats.d.ts +1 -0
- package/dist/test/test.broker.nats.js +193 -0
- package/dist/test/test.broker.nats.js.map +1 -0
- package/dist/test/test.broker.pubsub.d.ts +1 -0
- package/dist/test/test.broker.pubsub.js +171 -0
- package/dist/test/test.broker.pubsub.js.map +1 -0
- package/dist/test/test.broker.rabbitmq.d.ts +1 -0
- package/dist/test/test.broker.rabbitmq.js +164 -0
- package/dist/test/test.broker.rabbitmq.js.map +1 -0
- package/dist/test/test.broker.redis.d.ts +1 -0
- package/dist/test/test.broker.redis.js +168 -0
- package/dist/test/test.broker.redis.js.map +1 -0
- package/dist/test/test.broker.sqs.d.ts +1 -0
- package/dist/test/test.broker.sqs.js +158 -0
- package/dist/test/test.broker.sqs.js.map +1 -0
- package/dist/test/test.caches.d.ts +1 -0
- package/dist/test/test.caches.js +231 -0
- package/dist/test/test.caches.js.map +1 -0
- package/dist/test/test.database.dynamo.d.ts +1 -0
- package/dist/test/test.database.dynamo.js +265 -0
- package/dist/test/test.database.dynamo.js.map +1 -0
- package/dist/test/test.database.js +2 -2
- package/dist/test/test.database.js.map +1 -1
- package/dist/test/test.database.mongo.d.ts +1 -0
- package/dist/test/test.database.mongo.js +371 -0
- package/dist/test/test.database.mongo.js.map +1 -0
- package/dist/test/test.database.mysql.d.ts +1 -0
- package/dist/test/test.database.mysql.js +415 -0
- package/dist/test/test.database.mysql.js.map +1 -0
- package/dist/test/test.database.postgres.d.ts +1 -0
- package/dist/test/test.database.postgres.js +412 -0
- package/dist/test/test.database.postgres.js.map +1 -0
- package/dist/test/test.email.brevo.d.ts +1 -0
- package/dist/test/test.email.brevo.js +326 -0
- package/dist/test/test.email.brevo.js.map +1 -0
- package/dist/test/test.email.mailgun.d.ts +1 -0
- package/dist/test/test.email.mailgun.js +352 -0
- package/dist/test/test.email.mailgun.js.map +1 -0
- package/dist/test/test.email.postmark.d.ts +1 -0
- package/dist/test/test.email.postmark.js +316 -0
- package/dist/test/test.email.postmark.js.map +1 -0
- package/dist/test/test.email.sendgrid.d.ts +1 -0
- package/dist/test/test.email.sendgrid.js +365 -0
- package/dist/test/test.email.sendgrid.js.map +1 -0
- package/dist/test/test.email.smtp.d.ts +1 -0
- package/dist/test/test.email.smtp.js +323 -0
- package/dist/test/test.email.smtp.js.map +1 -0
- package/dist/test/test.graph.arangodb.d.ts +1 -0
- package/dist/test/test.graph.arangodb.js +358 -0
- package/dist/test/test.graph.arangodb.js.map +1 -0
- package/dist/test/test.graph.memgraph.d.ts +1 -0
- package/dist/test/test.graph.memgraph.js +320 -0
- package/dist/test/test.graph.memgraph.js.map +1 -0
- package/dist/test/test.graph.neo4j.d.ts +1 -0
- package/dist/test/test.graph.neo4j.js +218 -0
- package/dist/test/test.graph.neo4j.js.map +1 -0
- package/dist/test/test.graph.neptune.d.ts +1 -0
- package/dist/test/test.graph.neptune.js +331 -0
- package/dist/test/test.graph.neptune.js.map +1 -0
- package/dist/test/test.notifications.d.ts +1 -0
- package/dist/test/test.notifications.js +198 -0
- package/dist/test/test.notifications.js.map +1 -0
- package/dist/test/test.push.expo.d.ts +1 -0
- package/dist/test/test.push.expo.js +442 -0
- package/dist/test/test.push.expo.js.map +1 -0
- package/dist/test/test.push.firebase.d.ts +1 -0
- package/dist/test/test.push.firebase.js +409 -0
- package/dist/test/test.push.firebase.js.map +1 -0
- package/dist/test/test.session.d.ts +1 -0
- package/dist/test/test.session.js +299 -0
- package/dist/test/test.session.js.map +1 -0
- package/dist/test/test.sms.nexmo.d.ts +1 -0
- package/dist/test/test.sms.nexmo.js +278 -0
- package/dist/test/test.sms.nexmo.js.map +1 -0
- package/dist/test/test.sms.twilio.d.ts +1 -0
- package/dist/test/test.sms.twilio.js +275 -0
- package/dist/test/test.sms.twilio.js.map +1 -0
- package/dist/test/test.storage.js +169 -299
- package/dist/test/test.storage.js.map +1 -1
- package/dist/test/test.vector.pinecone.d.ts +1 -0
- package/dist/test/test.vector.pinecone.js +238 -0
- package/dist/test/test.vector.pinecone.js.map +1 -0
- package/dist/test/test.vector.qdrant.d.ts +1 -0
- package/dist/test/test.vector.qdrant.js +307 -0
- package/dist/test/test.vector.qdrant.js.map +1 -0
- package/dist/test/test.vector.weaviate.d.ts +1 -0
- package/dist/test/test.vector.weaviate.js +325 -0
- package/dist/test/test.vector.weaviate.js.map +1 -0
- package/dist/types/appBuilder.types.d.ts +6 -2
- package/dist/types/enums.d.ts +2 -0
- package/dist/types/enums.js +2 -0
- package/dist/types/enums.js.map +1 -1
- package/dist/types/index.types.d.ts +2 -4
- package/dist/types/index.types.js +0 -1
- package/dist/types/index.types.js.map +1 -1
- package/dist/types/processor.types.d.ts +18 -0
- package/dist/types/productsBuilder.types.d.ts +19 -15
- package/dist/types/productsBuilder.types.js.map +1 -1
- package/dist/types/requests.types.d.ts +2 -0
- package/dist/utils/index.js +23 -4
- package/dist/utils/index.js.map +1 -1
- package/dist/vector/adapters/base.adapter.d.ts +1 -1
- package/dist/vector/adapters/memory.adapter.d.ts +1 -1
- package/dist/vector/adapters/memory.adapter.js +1 -1
- package/dist/vector/adapters/memory.adapter.js.map +1 -1
- package/dist/vector/adapters/pinecone.adapter.d.ts +1 -1
- package/dist/vector/adapters/pinecone.adapter.js +1 -1
- package/dist/vector/adapters/pinecone.adapter.js.map +1 -1
- package/dist/vector/adapters/qdrant.adapter.d.ts +1 -1
- package/dist/vector/adapters/qdrant.adapter.js +1 -1
- package/dist/vector/adapters/qdrant.adapter.js.map +1 -1
- package/dist/vector/adapters/weaviate.adapter.d.ts +1 -1
- package/dist/vector/adapters/weaviate.adapter.js +1 -1
- package/dist/vector/adapters/weaviate.adapter.js.map +1 -1
- package/dist/vector/index.d.ts +2 -2
- package/dist/vector/index.js +2 -2
- package/dist/vector/utils/vector-error.js +0 -1
- package/dist/vector/utils/vector-error.js.map +1 -1
- package/dist/vector/vector-database.service.d.ts +9 -6
- package/dist/vector/vector-database.service.js +7 -6
- package/dist/vector/vector-database.service.js.map +1 -1
- package/dist/vector/vector.service.d.ts +3 -3
- package/dist/vector/vector.service.js +12 -9
- package/dist/vector/vector.service.js.map +1 -1
- package/dist/workflows/workflow-executor.d.ts +4 -1
- package/dist/workflows/workflow-executor.js +10 -2
- package/dist/workflows/workflow-executor.js.map +1 -1
- package/dist/workflows/workflows.service.d.ts +8 -2
- package/dist/workflows/workflows.service.js +66 -41
- package/dist/workflows/workflows.service.js.map +1 -1
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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:
|
|
2109
|
-
? (0, processor_utils_1.encrypt)(JSON.stringify(
|
|
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:
|
|
2112
|
-
? (0, processor_utils_1.encrypt)(JSON.stringify(
|
|
2403
|
+
emails: processedEnv.emails
|
|
2404
|
+
? (0, processor_utils_1.encrypt)(JSON.stringify(processedEnv.emails), this.product.private_key)
|
|
2113
2405
|
: undefined,
|
|
2114
|
-
callbacks:
|
|
2115
|
-
? (0, processor_utils_1.encrypt)(JSON.stringify(
|
|
2406
|
+
callbacks: processedEnv.callbacks
|
|
2407
|
+
? (0, processor_utils_1.encrypt)(JSON.stringify(processedEnv.callbacks), this.product.private_key)
|
|
2116
2408
|
: undefined,
|
|
2117
|
-
sms:
|
|
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 (
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
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
|