@ductape/sdk 0.0.4 → 0.0.6
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/README.md +87 -53
- package/dist/agents/agent-context.d.ts +100 -0
- package/dist/agents/agent-context.js +604 -0
- package/dist/agents/agent-context.js.map +1 -0
- package/dist/agents/agent-executor.d.ts +180 -0
- package/dist/agents/agent-executor.js +715 -0
- package/dist/agents/agent-executor.js.map +1 -0
- package/dist/agents/agents.service.d.ts +310 -0
- package/dist/agents/agents.service.js +1253 -0
- package/dist/agents/agents.service.js.map +1 -0
- package/dist/agents/index.d.ts +55 -0
- package/dist/agents/index.js +110 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/memory-manager.d.ts +182 -0
- package/dist/agents/memory-manager.js +383 -0
- package/dist/agents/memory-manager.js.map +1 -0
- package/dist/agents/tool-registry.d.ts +141 -0
- package/dist/agents/tool-registry.js +355 -0
- package/dist/agents/tool-registry.js.map +1 -0
- package/dist/agents/types/agents.types.d.ts +1240 -0
- package/dist/agents/types/agents.types.js +12 -0
- package/dist/agents/types/agents.types.js.map +1 -0
- package/dist/agents/types/index.d.ts +6 -0
- package/dist/agents/types/index.js +23 -0
- package/dist/agents/types/index.js.map +1 -0
- package/dist/agents/vector-store-adapter.d.ts +108 -0
- package/dist/agents/vector-store-adapter.js +213 -0
- package/dist/agents/vector-store-adapter.js.map +1 -0
- package/dist/api/services/appApi.service.d.ts +51 -5
- package/dist/api/services/appApi.service.js +116 -9
- package/dist/api/services/appApi.service.js.map +1 -1
- package/dist/api/services/logsApi.service.d.ts +51 -0
- package/dist/api/services/logsApi.service.js +19 -2
- package/dist/api/services/logsApi.service.js.map +1 -1
- package/dist/api/services/pricingApi.service.d.ts +10 -0
- package/dist/api/services/pricingApi.service.js +34 -0
- package/dist/api/services/pricingApi.service.js.map +1 -0
- package/dist/api/services/processorApi.service.d.ts +900 -2
- package/dist/api/services/processorApi.service.js +665 -12
- package/dist/api/services/processorApi.service.js.map +1 -1
- package/dist/api/services/productsApi.service.d.ts +130 -1
- package/dist/api/services/productsApi.service.js +198 -11
- package/dist/api/services/productsApi.service.js.map +1 -1
- package/dist/api/services/resilienceApi.service.d.ts +106 -0
- package/dist/api/services/resilienceApi.service.js +224 -0
- package/dist/api/services/resilienceApi.service.js.map +1 -0
- package/dist/api/services/secretsApi.service.d.ts +50 -0
- package/dist/api/services/secretsApi.service.js +113 -0
- package/dist/api/services/secretsApi.service.js.map +1 -0
- package/dist/api/services/webhooksApi.service.js +13 -6
- package/dist/api/services/webhooksApi.service.js.map +1 -1
- package/dist/api/services/workflowApi.service.d.ts +199 -0
- package/dist/api/services/workflowApi.service.js +201 -0
- package/dist/api/services/workflowApi.service.js.map +1 -0
- 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 +92 -1
- package/dist/api/urls.js +118 -18
- 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/api/utils/cache.utils.d.ts +1 -1
- package/dist/api/utils/cache.utils.js +2 -2
- package/dist/api/utils/cache.utils.js.map +1 -1
- package/dist/api/utils/strings.utils.d.ts +2 -0
- package/dist/api/utils/strings.utils.js +14 -0
- package/dist/api/utils/strings.utils.js.map +1 -1
- package/dist/apps/services/app.service.d.ts +42 -33
- package/dist/apps/services/app.service.js +574 -223
- package/dist/apps/services/app.service.js.map +1 -1
- package/dist/apps/utils/auth-context-manager.d.ts +137 -0
- package/dist/apps/utils/auth-context-manager.js +248 -0
- package/dist/apps/utils/auth-context-manager.js.map +1 -0
- package/dist/apps/utils/credential-manager.d.ts +128 -0
- package/dist/apps/utils/credential-manager.js +199 -0
- package/dist/apps/utils/credential-manager.js.map +1 -0
- package/dist/apps/utils/index.d.ts +10 -0
- package/dist/apps/utils/index.js +54 -0
- package/dist/apps/utils/index.js.map +1 -0
- package/dist/apps/utils/input-helpers.d.ts +67 -0
- package/dist/apps/utils/input-helpers.js +185 -0
- package/dist/apps/utils/input-helpers.js.map +1 -0
- package/dist/apps/utils/input-resolver.d.ts +165 -0
- package/dist/apps/utils/input-resolver.js +477 -0
- package/dist/apps/utils/input-resolver.js.map +1 -0
- package/dist/apps/utils/oauth-manager.d.ts +196 -0
- package/dist/apps/utils/oauth-manager.js +429 -0
- package/dist/apps/utils/oauth-manager.js.map +1 -0
- package/dist/apps/validators/joi-validators/create.appAction.validator.d.ts +1 -2
- package/dist/apps/validators/joi-validators/create.appAction.validator.js +22 -2
- package/dist/apps/validators/joi-validators/create.appAction.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/update.app.validator.js +2 -0
- package/dist/apps/validators/joi-validators/update.app.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/update.appAction.validator.js +23 -2
- package/dist/apps/validators/joi-validators/update.appAction.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/update.appActionResponse.validator.d.ts +1 -1
- package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js +34 -1
- package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js.map +1 -1
- package/dist/bin.d.ts +26 -0
- package/dist/bin.js +28 -0
- package/dist/bin.js.map +1 -0
- package/dist/brokers/brokers.service.d.ts +435 -0
- package/dist/brokers/brokers.service.js +1205 -0
- package/dist/brokers/brokers.service.js.map +1 -0
- package/dist/brokers/index.d.ts +46 -0
- package/dist/brokers/index.js +83 -0
- package/dist/brokers/index.js.map +1 -0
- package/dist/brokers/types/index.d.ts +567 -0
- package/dist/brokers/types/index.js +8 -0
- package/dist/brokers/types/index.js.map +1 -0
- package/dist/brokers/utils/broker.util.d.ts +33 -0
- package/dist/brokers/utils/broker.util.js +125 -0
- package/dist/brokers/utils/broker.util.js.map +1 -0
- package/dist/{processor/services/messagebrokers → brokers/utils/providers}/aws-sqs.service.d.ts +3 -2
- package/dist/brokers/utils/providers/aws-sqs.service.js +71 -0
- package/dist/brokers/utils/providers/aws-sqs.service.js.map +1 -0
- package/dist/{processor/services/messagebrokers → brokers/utils/providers}/google-pubsub.service.d.ts +2 -2
- package/dist/{processor/services/messagebrokers → brokers/utils/providers}/google-pubsub.service.js +16 -7
- package/dist/brokers/utils/providers/google-pubsub.service.js.map +1 -0
- package/dist/brokers/utils/providers/index.d.ts +6 -0
- package/dist/brokers/utils/providers/index.js +16 -0
- package/dist/brokers/utils/providers/index.js.map +1 -0
- package/dist/brokers/utils/providers/kafka.service.d.ts +23 -0
- package/dist/brokers/utils/providers/kafka.service.js +131 -0
- package/dist/brokers/utils/providers/kafka.service.js.map +1 -0
- package/dist/brokers/utils/providers/nats.service.d.ts +18 -0
- package/dist/brokers/utils/providers/nats.service.js +63 -0
- package/dist/brokers/utils/providers/nats.service.js.map +1 -0
- package/dist/brokers/utils/providers/rabbitmq.service.d.ts +25 -0
- package/dist/brokers/utils/providers/rabbitmq.service.js +138 -0
- package/dist/brokers/utils/providers/rabbitmq.service.js.map +1 -0
- package/dist/{processor/services/messagebrokers → brokers/utils/providers}/redis.service.d.ts +3 -3
- package/dist/{processor/services/messagebrokers → brokers/utils/providers}/redis.service.js +25 -14
- package/dist/brokers/utils/providers/redis.service.js.map +1 -0
- package/dist/cache/cache.manager.d.ts +308 -0
- package/dist/cache/cache.manager.js +900 -0
- package/dist/cache/cache.manager.js.map +1 -0
- package/dist/cache/cache.service.d.ts +191 -0
- package/dist/cache/cache.service.js +594 -0
- package/dist/cache/cache.service.js.map +1 -0
- package/dist/cache/index.d.ts +52 -0
- package/dist/cache/index.js +81 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/types/index.d.ts +110 -0
- package/dist/cache/types/index.js +6 -0
- package/dist/cache/types/index.js.map +1 -0
- package/dist/clients/apps.client.js +1 -1
- package/dist/clients/apps.client.js.map +1 -1
- package/dist/clients/pricing.client.d.ts +3 -0
- package/dist/clients/pricing.client.js +33 -0
- package/dist/clients/pricing.client.js.map +1 -0
- package/dist/database/actions/action-manager.d.ts +170 -0
- package/dist/database/actions/action-manager.js +465 -0
- package/dist/database/actions/action-manager.js.map +1 -0
- package/dist/database/actions/index.d.ts +6 -0
- package/dist/database/actions/index.js +13 -0
- package/dist/database/actions/index.js.map +1 -0
- package/dist/database/adapters/adapter.factory.d.ts +62 -0
- package/dist/database/adapters/adapter.factory.js +97 -0
- package/dist/database/adapters/adapter.factory.js.map +1 -0
- package/dist/database/adapters/base.adapter.d.ts +423 -0
- package/dist/database/adapters/base.adapter.js +260 -0
- package/dist/database/adapters/base.adapter.js.map +1 -0
- package/dist/database/adapters/cassandra.adapter.d.ts +92 -0
- package/dist/database/adapters/cassandra.adapter.js +1091 -0
- package/dist/database/adapters/cassandra.adapter.js.map +1 -0
- package/dist/database/adapters/dynamodb.adapter.d.ts +110 -0
- package/dist/database/adapters/dynamodb.adapter.js +1564 -0
- package/dist/database/adapters/dynamodb.adapter.js.map +1 -0
- package/dist/database/adapters/index.d.ts +11 -0
- package/dist/database/adapters/index.js +27 -0
- package/dist/database/adapters/index.js.map +1 -0
- package/dist/database/adapters/mariadb.adapter.d.ts +100 -0
- package/dist/database/adapters/mariadb.adapter.js +247 -0
- package/dist/database/adapters/mariadb.adapter.js.map +1 -0
- package/dist/database/adapters/mongodb.adapter.d.ts +121 -0
- package/dist/database/adapters/mongodb.adapter.js +1284 -0
- package/dist/database/adapters/mongodb.adapter.js.map +1 -0
- package/dist/database/adapters/mysql.adapter.d.ts +86 -0
- package/dist/database/adapters/mysql.adapter.js +1371 -0
- package/dist/database/adapters/mysql.adapter.js.map +1 -0
- package/dist/database/adapters/postgresql.adapter.d.ts +90 -0
- package/dist/database/adapters/postgresql.adapter.js +1487 -0
- package/dist/database/adapters/postgresql.adapter.js.map +1 -0
- package/dist/database/databases.service.d.ts +1476 -0
- package/dist/database/databases.service.js +3068 -0
- package/dist/database/databases.service.js.map +1 -0
- package/dist/database/index.d.ts +46 -0
- package/dist/database/index.js +109 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/migrations/index.d.ts +6 -0
- package/dist/database/migrations/index.js +12 -0
- package/dist/database/migrations/index.js.map +1 -0
- package/dist/database/migrations/migration-engine.d.ts +136 -0
- package/dist/database/migrations/migration-engine.js +1421 -0
- package/dist/database/migrations/migration-engine.js.map +1 -0
- package/dist/database/operators/aggregation-builder.d.ts +67 -0
- package/dist/database/operators/aggregation-builder.js +841 -0
- package/dist/database/operators/aggregation-builder.js.map +1 -0
- package/dist/database/operators/index.d.ts +7 -0
- package/dist/database/operators/index.js +15 -0
- package/dist/database/operators/index.js.map +1 -0
- package/dist/database/operators/query-builder.d.ts +69 -0
- package/dist/database/operators/query-builder.js +447 -0
- package/dist/database/operators/query-builder.js.map +1 -0
- package/dist/database/presave/decrypt.d.ts +25 -0
- package/dist/database/presave/decrypt.js +146 -0
- package/dist/database/presave/decrypt.js.map +1 -0
- package/dist/database/presave/index.d.ts +9 -0
- package/dist/database/presave/index.js +18 -0
- package/dist/database/presave/index.js.map +1 -0
- package/dist/database/presave/presave-processor.d.ts +148 -0
- package/dist/database/presave/presave-processor.js +702 -0
- package/dist/database/presave/presave-processor.js.map +1 -0
- package/dist/database/schema/index.d.ts +7 -0
- package/dist/database/schema/index.js +13 -0
- package/dist/database/schema/index.js.map +1 -0
- package/dist/database/schema/schema-manager.d.ts +258 -0
- package/dist/database/schema/schema-manager.js +638 -0
- package/dist/database/schema/schema-manager.js.map +1 -0
- package/dist/database/transactions/index.d.ts +6 -0
- package/dist/database/transactions/index.js +13 -0
- package/dist/database/transactions/index.js.map +1 -0
- package/dist/database/transactions/transaction-manager.d.ts +113 -0
- package/dist/database/transactions/transaction-manager.js +344 -0
- package/dist/database/transactions/transaction-manager.js.map +1 -0
- package/dist/database/triggers/index.d.ts +7 -0
- package/dist/database/triggers/index.js +14 -0
- package/dist/database/triggers/index.js.map +1 -0
- package/dist/database/triggers/trigger-processor.d.ts +239 -0
- package/dist/database/triggers/trigger-processor.js +1034 -0
- package/dist/database/triggers/trigger-processor.js.map +1 -0
- package/dist/database/types/action.interface.d.ts +148 -0
- package/dist/database/types/action.interface.js +6 -0
- package/dist/database/types/action.interface.js.map +1 -0
- package/dist/database/types/aggregation.interface.d.ts +185 -0
- package/dist/database/types/aggregation.interface.js +6 -0
- package/dist/database/types/aggregation.interface.js.map +1 -0
- package/dist/database/types/connection.interface.d.ts +137 -0
- package/dist/database/types/connection.interface.js +6 -0
- package/dist/database/types/connection.interface.js.map +1 -0
- package/dist/database/types/dashboard.interface.d.ts +74 -0
- package/dist/database/types/dashboard.interface.js +7 -0
- package/dist/database/types/dashboard.interface.js.map +1 -0
- package/dist/database/types/enums.d.ts +195 -0
- package/dist/database/types/enums.js +244 -0
- package/dist/database/types/enums.js.map +1 -0
- package/dist/database/types/index.d.ts +15 -0
- package/dist/database/types/index.js +31 -0
- package/dist/database/types/index.js.map +1 -0
- package/dist/database/types/migration.interface.d.ts +686 -0
- package/dist/database/types/migration.interface.js +9 -0
- package/dist/database/types/migration.interface.js.map +1 -0
- package/dist/database/types/presave.interface.d.ts +292 -0
- package/dist/database/types/presave.interface.js +60 -0
- package/dist/database/types/presave.interface.js.map +1 -0
- package/dist/database/types/query.interface.d.ts +205 -0
- package/dist/database/types/query.interface.js +6 -0
- package/dist/database/types/query.interface.js.map +1 -0
- package/dist/database/types/schema.interface.d.ts +412 -0
- package/dist/database/types/schema.interface.js +6 -0
- package/dist/database/types/schema.interface.js.map +1 -0
- package/dist/database/types/transaction.interface.d.ts +84 -0
- package/dist/database/types/transaction.interface.js +6 -0
- package/dist/database/types/transaction.interface.js.map +1 -0
- package/dist/database/types/trigger.interface.d.ts +612 -0
- package/dist/database/types/trigger.interface.js +121 -0
- package/dist/database/types/trigger.interface.js.map +1 -0
- package/dist/database/types/write.interface.d.ts +216 -0
- package/dist/database/types/write.interface.js +6 -0
- package/dist/database/types/write.interface.js.map +1 -0
- package/dist/database/utils/database-error.d.ts +96 -0
- package/dist/database/utils/database-error.js +221 -0
- package/dist/database/utils/database-error.js.map +1 -0
- package/dist/database/utils/index.d.ts +6 -0
- package/dist/database/utils/index.js +11 -0
- package/dist/database/utils/index.js.map +1 -0
- package/dist/graph/adapters/adapter.factory.d.ts +47 -0
- package/dist/graph/adapters/adapter.factory.js +77 -0
- package/dist/graph/adapters/adapter.factory.js.map +1 -0
- package/dist/graph/adapters/arangodb.adapter.d.ts +86 -0
- package/dist/graph/adapters/arangodb.adapter.js +1588 -0
- package/dist/graph/adapters/arangodb.adapter.js.map +1 -0
- package/dist/graph/adapters/base.adapter.d.ts +264 -0
- package/dist/graph/adapters/base.adapter.js +156 -0
- package/dist/graph/adapters/base.adapter.js.map +1 -0
- package/dist/graph/adapters/index.d.ts +11 -0
- package/dist/graph/adapters/index.js +21 -0
- package/dist/graph/adapters/index.js.map +1 -0
- package/dist/graph/adapters/memgraph.adapter.d.ts +110 -0
- package/dist/graph/adapters/memgraph.adapter.js +1452 -0
- package/dist/graph/adapters/memgraph.adapter.js.map +1 -0
- package/dist/graph/adapters/neo4j.adapter.d.ts +81 -0
- package/dist/graph/adapters/neo4j.adapter.js +1317 -0
- package/dist/graph/adapters/neo4j.adapter.js.map +1 -0
- package/dist/graph/adapters/neptune.adapter.d.ts +82 -0
- package/dist/graph/adapters/neptune.adapter.js +1369 -0
- package/dist/graph/adapters/neptune.adapter.js.map +1 -0
- package/dist/graph/graphs.service.d.ts +606 -0
- package/dist/graph/graphs.service.js +2434 -0
- package/dist/graph/graphs.service.js.map +1 -0
- package/dist/graph/index.d.ts +57 -0
- package/dist/graph/index.js +77 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/transactions/index.d.ts +4 -0
- package/dist/graph/transactions/index.js +9 -0
- package/dist/graph/transactions/index.js.map +1 -0
- package/dist/graph/transactions/transaction-manager.d.ts +61 -0
- package/dist/graph/transactions/transaction-manager.js +126 -0
- package/dist/graph/transactions/transaction-manager.js.map +1 -0
- package/dist/graph/types/connection.interface.d.ts +149 -0
- package/dist/graph/types/connection.interface.js +9 -0
- package/dist/graph/types/connection.interface.js.map +1 -0
- package/dist/graph/types/enums.d.ts +101 -0
- package/dist/graph/types/enums.js +114 -0
- package/dist/graph/types/enums.js.map +1 -0
- package/dist/graph/types/index.d.ts +13 -0
- package/dist/graph/types/index.js +20 -0
- package/dist/graph/types/index.js.map +1 -0
- package/dist/graph/types/node.interface.d.ts +248 -0
- package/dist/graph/types/node.interface.js +9 -0
- package/dist/graph/types/node.interface.js.map +1 -0
- package/dist/graph/types/query.interface.d.ts +175 -0
- package/dist/graph/types/query.interface.js +9 -0
- package/dist/graph/types/query.interface.js.map +1 -0
- package/dist/graph/types/relationship.interface.d.ts +207 -0
- package/dist/graph/types/relationship.interface.js +9 -0
- package/dist/graph/types/relationship.interface.js.map +1 -0
- package/dist/graph/types/schema.interface.d.ts +295 -0
- package/dist/graph/types/schema.interface.js +9 -0
- package/dist/graph/types/schema.interface.js.map +1 -0
- package/dist/graph/types/transaction.interface.d.ts +55 -0
- package/dist/graph/types/transaction.interface.js +9 -0
- package/dist/graph/types/transaction.interface.js.map +1 -0
- package/dist/graph/types/traversal.interface.d.ts +181 -0
- package/dist/graph/types/traversal.interface.js +9 -0
- package/dist/graph/types/traversal.interface.js.map +1 -0
- package/dist/graph/utils/graph-error.d.ts +71 -0
- package/dist/graph/utils/graph-error.js +142 -0
- package/dist/graph/utils/graph-error.js.map +1 -0
- package/dist/graph/utils/index.d.ts +4 -0
- package/dist/graph/utils/index.js +9 -0
- package/dist/graph/utils/index.js.map +1 -0
- package/dist/imports/imports.service.d.ts +3 -3
- package/dist/imports/imports.service.js +8 -7
- package/dist/imports/imports.service.js.map +1 -1
- package/dist/imports/imports.types.d.ts +8 -0
- package/dist/imports/repos/openApi.repo.d.ts +1 -2
- package/dist/imports/repos/openApi.repo.js +409 -70
- package/dist/imports/repos/openApi.repo.js.map +1 -1
- package/dist/imports/repos/postmanV21.repo.d.ts +1 -1
- package/dist/imports/repos/postmanV21.repo.js +126 -83
- package/dist/imports/repos/postmanV21.repo.js.map +1 -1
- package/dist/index.d.ts +3926 -269
- package/dist/index.js +5475 -682
- package/dist/index.js.map +1 -1
- package/dist/init.interface.d.ts +407 -0
- package/dist/{processor/services/messagebrokers/messagebrokers.type.js → init.interface.js} +1 -1
- package/dist/init.interface.js.map +1 -0
- package/dist/inputs/inputs.service.d.ts +1 -1
- package/dist/inputs/inputs.service.js +2 -2
- package/dist/inputs/inputs.service.js.map +1 -1
- package/dist/inputs/utils/inputs.utils.create.js +1 -1
- package/dist/inputs/utils/inputs.utils.create.js.map +1 -1
- package/dist/jobs/index.d.ts +38 -0
- package/dist/jobs/index.js +50 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/jobs.service.d.ts +154 -0
- package/dist/jobs/jobs.service.js +491 -0
- package/dist/jobs/jobs.service.js.map +1 -0
- package/dist/jobs/jobs.state.d.ts +113 -0
- package/dist/jobs/jobs.state.js +447 -0
- package/dist/jobs/jobs.state.js.map +1 -0
- package/dist/jobs/types.d.ts +449 -0
- package/dist/jobs/types.js +74 -0
- package/dist/jobs/types.js.map +1 -0
- package/dist/logs/logs.service.js +6 -1
- package/dist/logs/logs.service.js.map +1 -1
- package/dist/logs/logs.types.d.ts +33 -1
- package/dist/logs/logs.types.js +17 -0
- package/dist/logs/logs.types.js.map +1 -1
- package/dist/models/index.d.ts +6 -0
- package/dist/models/index.js +11 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/models.service.d.ts +137 -0
- package/dist/models/models.service.js +195 -0
- package/dist/models/models.service.js.map +1 -0
- package/dist/notifications/index.d.ts +13 -0
- package/dist/notifications/index.js +26 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/notifications.service.d.ts +268 -0
- package/dist/notifications/notifications.service.js +905 -0
- package/dist/notifications/notifications.service.js.map +1 -0
- package/dist/notifications/types/index.d.ts +4 -0
- package/dist/notifications/types/index.js +21 -0
- package/dist/notifications/types/index.js.map +1 -0
- package/dist/notifications/types/notifications.types.d.ts +452 -0
- package/dist/notifications/types/notifications.types.js +49 -0
- package/dist/notifications/types/notifications.types.js.map +1 -0
- package/dist/parsers/index.d.ts +3 -0
- package/dist/parsers/index.js +27 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/pipelines/postman.pipelines.d.ts +15 -0
- package/dist/parsers/pipelines/postman.pipelines.js +103 -0
- package/dist/parsers/pipelines/postman.pipelines.js.map +1 -0
- package/dist/parsers/types/postman.types.d.ts +200 -0
- package/dist/parsers/types/postman.types.js +3 -0
- package/dist/parsers/types/postman.types.js.map +1 -0
- package/dist/parsers/utils/postman.utils.d.ts +12 -0
- package/dist/parsers/utils/postman.utils.js +116 -0
- package/dist/parsers/utils/postman.utils.js.map +1 -0
- package/dist/parsers/validators/postman-auth.validators.d.ts +10 -0
- package/dist/parsers/validators/postman-auth.validators.js +127 -0
- package/dist/parsers/validators/postman-auth.validators.js.map +1 -0
- package/dist/parsers/validators/postman-request.validators.d.ts +13 -0
- package/dist/parsers/validators/postman-request.validators.js +139 -0
- package/dist/parsers/validators/postman-request.validators.js.map +1 -0
- package/dist/parsers/validators/postman-response.validators.d.ts +13 -0
- package/dist/parsers/validators/postman-response.validators.js +150 -0
- package/dist/parsers/validators/postman-response.validators.js.map +1 -0
- package/dist/parsers/validators/postman-variable.validators.d.ts +14 -0
- package/dist/parsers/validators/postman-variable.validators.js +163 -0
- package/dist/parsers/validators/postman-variable.validators.js.map +1 -0
- package/dist/pricing/pricing.repo.js +1 -0
- package/dist/pricing/pricing.repo.js.map +1 -0
- package/dist/pricing/pricing.service.d.ts +24 -0
- package/dist/pricing/pricing.service.js +51 -0
- package/dist/pricing/pricing.service.js.map +1 -0
- package/dist/pricing/pricing.types.d.ts +76 -0
- package/dist/pricing/pricing.types.js +21 -0
- package/dist/pricing/pricing.types.js.map +1 -0
- package/dist/pricing/utils/string.utils.d.ts +1 -0
- package/dist/pricing/utils/string.utils.js +9 -0
- package/dist/pricing/utils/string.utils.js.map +1 -0
- package/dist/processor/repos/sms.repo.d.ts +4 -4
- package/dist/processor/repos/sms.repo.js +23 -10
- package/dist/processor/repos/sms.repo.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +251 -78
- package/dist/processor/services/processor.service.js +2803 -1495
- package/dist/processor/services/processor.service.js.map +1 -1
- package/dist/processor/services/request.service.d.ts +36 -0
- package/dist/processor/services/request.service.js +304 -0
- package/dist/processor/services/request.service.js.map +1 -0
- package/dist/processor/types/request.types.d.ts +14 -0
- package/dist/processor/types/request.types.js +3 -0
- package/dist/processor/types/request.types.js.map +1 -0
- package/dist/processor/utils/processor.utils.d.ts +8 -0
- package/dist/processor/utils/processor.utils.js +152 -12
- package/dist/processor/utils/processor.utils.js.map +1 -1
- package/dist/processor/utils/request.utils.d.ts +20 -0
- package/dist/processor/utils/request.utils.js +113 -0
- package/dist/processor/utils/request.utils.js.map +1 -0
- package/dist/processor/utils/storage.util.js +63 -40
- package/dist/processor/utils/storage.util.js.map +1 -1
- package/dist/products/services/products.service.d.ts +386 -76
- package/dist/products/services/products.service.js +3221 -419
- package/dist/products/services/products.service.js.map +1 -1
- package/dist/products/utils/string.utils.d.ts +1 -1
- package/dist/products/utils/string.utils.js +14 -2
- package/dist/products/utils/string.utils.js.map +1 -1
- package/dist/products/validators/index.d.ts +7 -1
- package/dist/products/validators/index.js +16 -1
- package/dist/products/validators/index.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productAgent.validator.d.ts +3 -0
- package/dist/products/validators/joi-validators/create.productAgent.validator.js +266 -0
- package/dist/products/validators/joi-validators/create.productAgent.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/create.productApp.validator.js +2 -2
- package/dist/products/validators/joi-validators/create.productApp.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productDatabase.validator.js +5 -0
- package/dist/products/validators/joi-validators/create.productDatabase.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productEnv.validator.js +1 -0
- package/dist/products/validators/joi-validators/create.productEnv.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productFeature.validator.js +1 -1
- package/dist/products/validators/joi-validators/create.productGraph.validator.js +89 -0
- package/dist/products/validators/joi-validators/create.productGraph.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/create.productHealthcheck.validator.d.ts +4 -0
- package/dist/{processor/services/messagebrokers/rabbitmq.service.js → products/validators/joi-validators/create.productHealthcheck.validator.js} +23 -32
- package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/create.productJob.validator.js +2 -2
- package/dist/products/validators/joi-validators/create.productJob.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productMessageBrokerTopic.validator.js +1 -0
- package/dist/products/validators/joi-validators/create.productMessageBrokerTopic.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js +81 -25
- package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productModel.validator.d.ts +3 -0
- package/dist/products/validators/joi-validators/create.productModel.validator.js +132 -0
- package/dist/products/validators/joi-validators/create.productModel.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/create.productNotification.validator.js +150 -51
- package/dist/products/validators/joi-validators/create.productNotification.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productStorage.validator.js +77 -18
- package/dist/products/validators/joi-validators/create.productStorage.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productVector.validator.d.ts +3 -0
- package/dist/products/validators/joi-validators/create.productVector.validator.js +136 -0
- package/dist/products/validators/joi-validators/create.productVector.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/create.userAuth.validator.js +1 -0
- package/dist/products/validators/joi-validators/create.userAuth.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.dataValue.validator.js +1 -0
- package/dist/products/validators/joi-validators/update.dataValue.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productDatabase.validator.js +5 -0
- package/dist/products/validators/joi-validators/update.productDatabase.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productEnv.validator.js +3 -0
- package/dist/products/validators/joi-validators/update.productEnv.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productGraph.validator.js +88 -0
- package/dist/products/validators/joi-validators/update.productGraph.validator.js.map +1 -0
- package/dist/products/validators/joi-validators/update.userAuth.validator.js +1 -0
- package/dist/products/validators/joi-validators/update.userAuth.validator.js.map +1 -1
- package/dist/resilience/fallback.service.d.ts +141 -0
- package/dist/resilience/fallback.service.js +766 -0
- package/dist/resilience/fallback.service.js.map +1 -0
- package/dist/resilience/healthcheck.service.d.ts +159 -0
- package/dist/resilience/healthcheck.service.js +943 -0
- package/dist/resilience/healthcheck.service.js.map +1 -0
- package/dist/resilience/index.d.ts +104 -0
- package/dist/resilience/index.js +140 -0
- package/dist/resilience/index.js.map +1 -0
- package/dist/resilience/quota.service.d.ts +83 -0
- package/dist/resilience/quota.service.js +518 -0
- package/dist/resilience/quota.service.js.map +1 -0
- package/dist/resilience/resilience.service.d.ts +98 -0
- package/dist/resilience/resilience.service.js +560 -0
- package/dist/resilience/resilience.service.js.map +1 -0
- package/dist/resilience/types/index.d.ts +513 -0
- package/dist/resilience/types/index.js +29 -0
- package/dist/resilience/types/index.js.map +1 -0
- package/dist/secrets/index.d.ts +10 -0
- package/dist/secrets/index.js +33 -0
- package/dist/secrets/index.js.map +1 -0
- package/dist/secrets/secrets.resolver.d.ts +52 -0
- package/dist/secrets/secrets.resolver.js +236 -0
- package/dist/secrets/secrets.resolver.js.map +1 -0
- package/dist/secrets/secrets.service.d.ts +93 -0
- package/dist/secrets/secrets.service.js +246 -0
- package/dist/secrets/secrets.service.js.map +1 -0
- package/dist/secrets/secrets.types.d.ts +188 -0
- package/dist/secrets/secrets.types.js +87 -0
- package/dist/secrets/secrets.types.js.map +1 -0
- package/dist/sessions/index.d.ts +50 -0
- package/dist/sessions/index.js +96 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/sessions/sessions.helper.d.ts +88 -0
- package/dist/sessions/sessions.helper.js +133 -0
- package/dist/sessions/sessions.helper.js.map +1 -0
- package/dist/sessions/sessions.resolver.d.ts +188 -0
- package/dist/sessions/sessions.resolver.js +603 -0
- package/dist/sessions/sessions.resolver.js.map +1 -0
- package/dist/sessions/sessions.service.d.ts +194 -0
- package/dist/sessions/sessions.service.js +987 -0
- package/dist/sessions/sessions.service.js.map +1 -0
- package/dist/sessions/types/index.d.ts +342 -0
- package/dist/sessions/types/index.js +6 -0
- package/dist/sessions/types/index.js.map +1 -0
- package/dist/storage/index.d.ts +66 -0
- package/dist/storage/index.js +99 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/storage.service.d.ts +177 -0
- package/dist/storage/storage.service.js +897 -0
- package/dist/storage/storage.service.js.map +1 -0
- package/dist/storage/types/index.d.ts +267 -0
- package/dist/storage/types/index.js +6 -0
- package/dist/storage/types/index.js.map +1 -0
- package/dist/storage/utils/storage.util.d.ts +62 -0
- package/dist/storage/utils/storage.util.js +593 -0
- package/dist/storage/utils/storage.util.js.map +1 -0
- package/dist/types/appBuilder.types.d.ts +13 -14
- package/dist/types/enums.d.ts +11 -1
- package/dist/types/enums.js +10 -0
- package/dist/types/enums.js.map +1 -1
- package/dist/types/index.types.d.ts +9 -4
- package/dist/types/index.types.js +0 -1
- package/dist/types/index.types.js.map +1 -1
- package/dist/types/inputs.types.d.ts +1 -0
- package/dist/types/inputs.types.js +4 -3
- package/dist/types/inputs.types.js.map +1 -1
- package/dist/types/pricing.types.d.ts +4 -0
- package/dist/types/pricing.types.js +3 -0
- package/dist/types/pricing.types.js.map +1 -0
- package/dist/types/processor.types.d.ts +324 -18
- package/dist/types/processor.types.js +9 -1
- package/dist/types/processor.types.js.map +1 -1
- package/dist/types/productsBuilder.types.d.ts +1007 -23
- package/dist/types/productsBuilder.types.js +216 -2
- package/dist/types/productsBuilder.types.js.map +1 -1
- package/dist/types/request-tracker.interface.js +1 -0
- package/dist/types/request-tracker.interface.js.map +1 -0
- package/dist/types/requests.types.d.ts +2 -0
- package/dist/utils/constants.d.ts +1 -0
- package/dist/utils/constants.js +5 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +24 -52
- package/dist/utils/index.js.map +1 -1
- package/dist/vector/actions/action-manager.d.ts +140 -0
- package/dist/vector/actions/action-manager.js +356 -0
- package/dist/vector/actions/action-manager.js.map +1 -0
- package/dist/vector/adapters/base.adapter.d.ts +169 -0
- package/dist/vector/adapters/base.adapter.js +218 -0
- package/dist/vector/adapters/base.adapter.js.map +1 -0
- package/dist/vector/adapters/index.d.ts +10 -0
- package/dist/vector/adapters/index.js +19 -0
- package/dist/vector/adapters/index.js.map +1 -0
- package/dist/vector/adapters/memory.adapter.d.ts +85 -0
- package/dist/vector/adapters/memory.adapter.js +505 -0
- package/dist/vector/adapters/memory.adapter.js.map +1 -0
- package/dist/vector/adapters/pinecone.adapter.d.ts +52 -0
- package/dist/vector/adapters/pinecone.adapter.js +433 -0
- package/dist/vector/adapters/pinecone.adapter.js.map +1 -0
- package/dist/vector/adapters/qdrant.adapter.d.ts +56 -0
- package/dist/vector/adapters/qdrant.adapter.js +442 -0
- package/dist/vector/adapters/qdrant.adapter.js.map +1 -0
- package/dist/vector/adapters/weaviate.adapter.d.ts +68 -0
- package/dist/vector/adapters/weaviate.adapter.js +661 -0
- package/dist/vector/adapters/weaviate.adapter.js.map +1 -0
- package/dist/vector/index.d.ts +36 -0
- package/dist/vector/index.js +70 -0
- package/dist/vector/index.js.map +1 -0
- package/dist/vector/types/action.interface.d.ts +195 -0
- package/dist/vector/types/action.interface.js +100 -0
- package/dist/vector/types/action.interface.js.map +1 -0
- package/dist/vector/types/connection.interface.d.ts +151 -0
- package/dist/vector/types/connection.interface.js +8 -0
- package/dist/vector/types/connection.interface.js.map +1 -0
- package/dist/vector/types/embedding.interface.d.ts +144 -0
- package/dist/vector/types/embedding.interface.js +8 -0
- package/dist/vector/types/embedding.interface.js.map +1 -0
- package/dist/vector/types/enums.d.ts +104 -0
- package/dist/vector/types/enums.js +113 -0
- package/dist/vector/types/enums.js.map +1 -0
- package/dist/vector/types/index.d.ts +11 -0
- package/dist/vector/types/index.js +23 -0
- package/dist/vector/types/index.js.map +1 -0
- package/dist/vector/types/vector.interface.d.ts +315 -0
- package/dist/vector/types/vector.interface.js +8 -0
- package/dist/vector/types/vector.interface.js.map +1 -0
- package/dist/vector/utils/index.d.ts +6 -0
- package/dist/vector/utils/index.js +11 -0
- package/dist/vector/utils/index.js.map +1 -0
- package/dist/vector/utils/vector-error.d.ts +69 -0
- package/dist/vector/utils/vector-error.js +116 -0
- package/dist/vector/utils/vector-error.js.map +1 -0
- package/dist/vector/vector-database.service.d.ts +476 -0
- package/dist/vector/vector-database.service.js +892 -0
- package/dist/vector/vector-database.service.js.map +1 -0
- package/dist/vector/vector.service.d.ts +283 -0
- package/dist/vector/vector.service.js +544 -0
- package/dist/vector/vector.service.js.map +1 -0
- package/dist/warehouse/executor/index.d.ts +5 -0
- package/dist/warehouse/executor/index.js +12 -0
- package/dist/warehouse/executor/index.js.map +1 -0
- package/dist/warehouse/executor/joins/index.d.ts +5 -0
- package/dist/warehouse/executor/joins/index.js +11 -0
- package/dist/warehouse/executor/joins/index.js.map +1 -0
- package/dist/warehouse/executor/joins/join-executor.d.ts +101 -0
- package/dist/warehouse/executor/joins/join-executor.js +493 -0
- package/dist/warehouse/executor/joins/join-executor.js.map +1 -0
- package/dist/warehouse/executor/joins/semantic-join.d.ts +64 -0
- package/dist/warehouse/executor/joins/semantic-join.js +241 -0
- package/dist/warehouse/executor/joins/semantic-join.js.map +1 -0
- package/dist/warehouse/executor/single-source-executor.d.ts +155 -0
- package/dist/warehouse/executor/single-source-executor.js +573 -0
- package/dist/warehouse/executor/single-source-executor.js.map +1 -0
- package/dist/warehouse/index.d.ts +79 -0
- package/dist/warehouse/index.js +111 -0
- package/dist/warehouse/index.js.map +1 -0
- package/dist/warehouse/parser/index.d.ts +4 -0
- package/dist/warehouse/parser/index.js +10 -0
- package/dist/warehouse/parser/index.js.map +1 -0
- package/dist/warehouse/parser/query-parser.d.ts +181 -0
- package/dist/warehouse/parser/query-parser.js +415 -0
- package/dist/warehouse/parser/query-parser.js.map +1 -0
- package/dist/warehouse/registry/data-source-registry.d.ts +207 -0
- package/dist/warehouse/registry/data-source-registry.js +396 -0
- package/dist/warehouse/registry/data-source-registry.js.map +1 -0
- package/dist/warehouse/registry/index.d.ts +4 -0
- package/dist/warehouse/registry/index.js +9 -0
- package/dist/warehouse/registry/index.js.map +1 -0
- package/dist/warehouse/transactions/index.d.ts +4 -0
- package/dist/warehouse/transactions/index.js +9 -0
- package/dist/warehouse/transactions/index.js.map +1 -0
- package/dist/warehouse/transactions/saga-orchestrator.d.ts +92 -0
- package/dist/warehouse/transactions/saga-orchestrator.js +383 -0
- package/dist/warehouse/transactions/saga-orchestrator.js.map +1 -0
- package/dist/warehouse/types/index.d.ts +9 -0
- package/dist/warehouse/types/index.js +33 -0
- package/dist/warehouse/types/index.js.map +1 -0
- package/dist/warehouse/types/join.interface.d.ts +225 -0
- package/dist/warehouse/types/join.interface.js +87 -0
- package/dist/warehouse/types/join.interface.js.map +1 -0
- package/dist/warehouse/types/query.interface.d.ts +232 -0
- package/dist/warehouse/types/query.interface.js +9 -0
- package/dist/warehouse/types/query.interface.js.map +1 -0
- package/dist/warehouse/types/transaction.interface.d.ts +236 -0
- package/dist/warehouse/types/transaction.interface.js +74 -0
- package/dist/warehouse/types/transaction.interface.js.map +1 -0
- package/dist/warehouse/types/where.interface.d.ts +208 -0
- package/dist/warehouse/types/where.interface.js +89 -0
- package/dist/warehouse/types/where.interface.js.map +1 -0
- package/dist/warehouse/warehouse.service.d.ts +200 -0
- package/dist/warehouse/warehouse.service.js +470 -0
- package/dist/warehouse/warehouse.service.js.map +1 -0
- package/dist/workflows/index.d.ts +30 -0
- package/dist/workflows/index.js +64 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/types/index.d.ts +6 -0
- package/dist/workflows/types/index.js +23 -0
- package/dist/workflows/types/index.js.map +1 -0
- package/dist/workflows/types/workflows.types.d.ts +1095 -0
- package/dist/workflows/types/workflows.types.js +13 -0
- package/dist/workflows/types/workflows.types.js.map +1 -0
- package/dist/workflows/workflow-builder.d.ts +70 -0
- package/dist/workflows/workflow-builder.js +353 -0
- package/dist/workflows/workflow-builder.js.map +1 -0
- package/dist/workflows/workflow-executor.d.ts +287 -0
- package/dist/workflows/workflow-executor.js +2399 -0
- package/dist/workflows/workflow-executor.js.map +1 -0
- package/dist/workflows/workflows.service.d.ts +412 -0
- package/dist/workflows/workflows.service.js +2188 -0
- package/dist/workflows/workflows.service.js.map +1 -0
- package/package.json +83 -11
- package/dist/actions/actions.repo.js +0 -13
- package/dist/actions/actions.repo.js.map +0 -1
- package/dist/actions/actions.service.js +0 -24
- package/dist/actions/actions.service.js.map +0 -1
- package/dist/actions/utils/actions.util.read.d.ts +0 -0
- package/dist/actions/utils/actions.util.read.js +0 -427
- package/dist/actions/utils/actions.util.read.js.map +0 -1
- package/dist/api/services/integrationsApi.service.d.ts +0 -18
- package/dist/api/services/integrationsApi.service.js +0 -80
- package/dist/api/services/integrationsApi.service.js.map +0 -1
- package/dist/appBuilder/services/app.service.d.ts +0 -111
- package/dist/appBuilder/services/app.service.js +0 -737
- package/dist/appBuilder/services/app.service.js.map +0 -1
- package/dist/appBuilder/services/appBuilder.service.d.ts +0 -111
- package/dist/appBuilder/services/appBuilder.service.js +0 -662
- package/dist/appBuilder/services/appBuilder.service.js.map +0 -1
- package/dist/appBuilder/utils/objects.utils.d.ts +0 -3
- package/dist/appBuilder/utils/objects.utils.js +0 -9
- package/dist/appBuilder/utils/objects.utils.js.map +0 -1
- package/dist/appBuilder/utils/string.utils.d.ts +0 -2
- package/dist/appBuilder/utils/string.utils.js +0 -57
- package/dist/appBuilder/utils/string.utils.js.map +0 -1
- package/dist/appBuilder/validators/index.d.ts +0 -19
- package/dist/appBuilder/validators/index.js +0 -40
- package/dist/appBuilder/validators/index.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/create.app.validator.js +0 -10
- package/dist/appBuilder/validators/joi-validators/create.app.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/create.appAction.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/create.appAction.validator.js +0 -20
- package/dist/appBuilder/validators/joi-validators/create.appAction.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/create.appActionResponse.validator.d.ts +0 -7
- package/dist/appBuilder/validators/joi-validators/create.appActionResponse.validator.js +0 -44
- package/dist/appBuilder/validators/joi-validators/create.appActionResponse.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/create.appAuth.validator.d.ts +0 -3
- package/dist/appBuilder/validators/joi-validators/create.appAuth.validator.js +0 -31
- package/dist/appBuilder/validators/joi-validators/create.appAuth.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/create.appBody.validators.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/create.appBody.validators.js +0 -11
- package/dist/appBuilder/validators/joi-validators/create.appBody.validators.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/create.appConstants.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/create.appConstants.validator.js +0 -12
- package/dist/appBuilder/validators/joi-validators/create.appConstants.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/create.appEnv.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/create.appEnv.validator.js +0 -17
- package/dist/appBuilder/validators/joi-validators/create.appEnv.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/create.appEvent.validator.d.ts +0 -5
- package/dist/appBuilder/validators/joi-validators/create.appEvent.validator.js +0 -30
- package/dist/appBuilder/validators/joi-validators/create.appEvent.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/create.appVariable.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/create.appVariable.validator.js +0 -14
- package/dist/appBuilder/validators/joi-validators/create.appVariable.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/sample.validator.d.ts +0 -5
- package/dist/appBuilder/validators/joi-validators/sample.validator.js +0 -26
- package/dist/appBuilder/validators/joi-validators/sample.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/update.app.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/update.app.validator.js +0 -34
- package/dist/appBuilder/validators/joi-validators/update.app.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/update.appAction.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/update.appAction.validator.js +0 -23
- package/dist/appBuilder/validators/joi-validators/update.appAction.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/update.appActionResponse.validator.d.ts +0 -3
- package/dist/appBuilder/validators/joi-validators/update.appActionResponse.validator.js +0 -21
- package/dist/appBuilder/validators/joi-validators/update.appActionResponse.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/update.appAuth.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/update.appAuth.validator.js +0 -19
- package/dist/appBuilder/validators/joi-validators/update.appAuth.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/update.appConstants.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/update.appConstants.validator.js +0 -12
- package/dist/appBuilder/validators/joi-validators/update.appConstants.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/update.appEnv.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/update.appEnv.validator.js +0 -17
- package/dist/appBuilder/validators/joi-validators/update.appEnv.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/update.appEvent.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/update.appEvent.validator.js +0 -16
- package/dist/appBuilder/validators/joi-validators/update.appEvent.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/update.appVariables.validator.d.ts +0 -4
- package/dist/appBuilder/validators/joi-validators/update.appVariables.validator.js +0 -14
- package/dist/appBuilder/validators/joi-validators/update.appVariables.validator.js.map +0 -1
- package/dist/appBuilder/validators/joi-validators/update.validation.entityData.validator.js +0 -27
- package/dist/appBuilder/validators/joi-validators/update.validation.entityData.validator.js.map +0 -1
- package/dist/apps/validators/joi-validators/create.appEvent.validator.d.ts +0 -5
- package/dist/apps/validators/joi-validators/create.appEvent.validator.js +0 -30
- package/dist/apps/validators/joi-validators/create.appEvent.validator.js.map +0 -1
- package/dist/apps/validators/joi-validators/update.appEvent.validator.d.ts +0 -4
- package/dist/apps/validators/joi-validators/update.appEvent.validator.js +0 -16
- package/dist/apps/validators/joi-validators/update.appEvent.validator.js.map +0 -1
- package/dist/clients/integrations.client.d.ts +0 -2
- package/dist/clients/integrations.client.js +0 -26
- package/dist/clients/integrations.client.js.map +0 -1
- package/dist/integrationsBuilder/services/integration.service.d.ts +0 -138
- package/dist/integrationsBuilder/services/integration.service.js +0 -1148
- package/dist/integrationsBuilder/services/integration.service.js.map +0 -1
- package/dist/integrationsBuilder/services/integrationBuilder.service.d.ts +0 -130
- package/dist/integrationsBuilder/services/integrationBuilder.service.js +0 -1017
- package/dist/integrationsBuilder/services/integrationBuilder.service.js.map +0 -1
- package/dist/integrationsBuilder/utils/objects.utils.d.ts +0 -2
- package/dist/integrationsBuilder/utils/objects.utils.js +0 -48
- package/dist/integrationsBuilder/utils/objects.utils.js.map +0 -1
- package/dist/integrationsBuilder/utils/string.utils.d.ts +0 -1
- package/dist/integrationsBuilder/utils/string.utils.js +0 -9
- package/dist/integrationsBuilder/utils/string.utils.js.map +0 -1
- package/dist/integrationsBuilder/validators/index.d.ts +0 -18
- package/dist/integrationsBuilder/validators/index.js +0 -38
- package/dist/integrationsBuilder/validators/index.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/create.integration.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/create.integration.validator.js +0 -10
- package/dist/integrationsBuilder/validators/joi-validators/create.integration.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationApp.validator.d.ts +0 -4
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationApp.validator.js +0 -26
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationApp.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationCache.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationCache.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationCache.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationDatabase.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationDatabase.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationDatabase.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationEnv.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationEnv.validator.js +0 -10
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationEnv.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationFeature.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationFeature.validator.js +0 -60
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationFeature.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationFunction.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationFunction.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationFunction.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationJob.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationJob.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationJob.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationNotification.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationNotification.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/create.integrationNotification.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationApp.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationApp.validator.js +0 -9
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationApp.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationCache.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationCache.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationCache.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationDatabase.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationDatabase.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationDatabase.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationEnv.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationEnv.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationEnv.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationFeature.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationFeature.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationFeature.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationFunction.validator copy.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationFunction.validator copy.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationFunction.validator copy.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationJob.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationJob.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationJob.validator.js.map +0 -1
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationNotification.validator.d.ts +0 -3
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationNotification.validator.js +0 -8
- package/dist/integrationsBuilder/validators/joi-validators/update.integrationNotification.validator.js.map +0 -1
- package/dist/postman.d.ts +0 -1
- package/dist/postman.js +0 -21674
- package/dist/postman.js.map +0 -1
- package/dist/processor/services/fallback.service.d.ts +0 -5
- package/dist/processor/services/fallback.service.js +0 -43
- package/dist/processor/services/fallback.service.js.map +0 -1
- package/dist/processor/services/messagebrokers/aws-sqs.service.js +0 -77
- package/dist/processor/services/messagebrokers/aws-sqs.service.js.map +0 -1
- package/dist/processor/services/messagebrokers/google-pubsub.service.js.map +0 -1
- package/dist/processor/services/messagebrokers/index.d.ts +0 -3
- package/dist/processor/services/messagebrokers/index.js +0 -26
- package/dist/processor/services/messagebrokers/index.js.map +0 -1
- package/dist/processor/services/messagebrokers/kafka.service.d.ts +0 -14
- package/dist/processor/services/messagebrokers/kafka.service.js +0 -45
- package/dist/processor/services/messagebrokers/kafka.service.js.map +0 -1
- package/dist/processor/services/messagebrokers/messagebrokers.type.d.ts +0 -6
- package/dist/processor/services/messagebrokers/messagebrokers.type.js.map +0 -1
- package/dist/processor/services/messagebrokers/rabbitmq.service.d.ts +0 -14
- package/dist/processor/services/messagebrokers/rabbitmq.service.js.map +0 -1
- package/dist/processor/services/messagebrokers/redis.service.js.map +0 -1
- package/dist/processor/services/quota.service.d.ts +0 -15
- package/dist/processor/services/quota.service.js +0 -63
- package/dist/processor/services/quota.service.js.map +0 -1
- package/dist/processor/utils/mongo.util.d.ts +0 -0
- package/dist/processor/utils/mongo.util.js +0 -152
- package/dist/processor/utils/mongo.util.js.map +0 -1
- package/dist/processor/utils/postgres.util.d.ts +0 -14
- package/dist/processor/utils/postgres.util.js +0 -83
- package/dist/processor/utils/postgres.util.js.map +0 -1
- package/dist/products/validators/joi-validators/create.product.validator.d.ts +0 -3
- package/dist/products/validators/joi-validators/create.product.validator.js +0 -10
- package/dist/products/validators/joi-validators/create.product.validator.js.map +0 -1
- package/dist/test/test.appBuilder.d.ts +0 -1
- package/dist/test/test.appBuilder.js +0 -16
- package/dist/test/test.appBuilder.js.map +0 -1
- package/dist/test/test.import.d.ts +0 -1
- package/dist/test/test.import.js +0 -1460
- package/dist/test/test.import.js.map +0 -1
- package/dist/test/test.import.openapi.d.ts +0 -1
- package/dist/test/test.import.openapi.js +0 -76
- package/dist/test/test.import.openapi.js.map +0 -1
- package/dist/test/test.imports.d.ts +0 -1
- package/dist/test/test.imports.js +0 -62
- package/dist/test/test.imports.js.map +0 -1
- package/dist/test/test.logs.d.ts +0 -1
- package/dist/test/test.logs.js +0 -18
- package/dist/test/test.logs.js.map +0 -1
- package/dist/test/test.processor.d.ts +0 -1
- package/dist/test/test.processor.js +0 -123
- package/dist/test/test.processor.js.map +0 -1
- package/dist/test/test.productBuilder.d.ts +0 -1
- package/dist/test/test.productBuilder.js +0 -661
- package/dist/test/test.productBuilder.js.map +0 -1
- package/dist/test.appBuilder.d.ts +0 -1
- package/dist/test.appBuilder.js +0 -14
- package/dist/test.appBuilder.js.map +0 -1
- package/dist/test.import.d.ts +0 -0
- package/dist/test.import.js +0 -24
- package/dist/test.import.js.map +0 -1
- package/dist/test.imports.d.ts +0 -1
- package/dist/test.imports.js +0 -28
- package/dist/test.imports.js.map +0 -1
- package/dist/test.integrationBuilder.d.ts +0 -1
- package/dist/test.integrationBuilder.js +0 -276
- package/dist/test.integrationBuilder.js.map +0 -1
- package/dist/test.processor.d.ts +0 -1
- package/dist/test.processor.js +0 -23
- package/dist/test.processor.js.map +0 -1
- package/dist/test.utils.d.ts +0 -1
- package/dist/test.utils.js +0 -25
- package/dist/test.utils.js.map +0 -1
- package/dist/types/integrationsBuilder.types.d.ts +0 -276
- package/dist/types/integrationsBuilder.types.js +0 -51
- package/dist/types/integrationsBuilder.types.js.map +0 -1
- /package/dist/{actions/actions.repo.d.ts → pricing/pricing.repo.d.ts} +0 -0
- /package/dist/{appBuilder/validators/joi-validators/create.app.validator.d.ts → products/validators/joi-validators/create.productGraph.validator.d.ts} +0 -0
- /package/dist/{appBuilder/validators/joi-validators/update.validation.entityData.validator.d.ts → products/validators/joi-validators/update.productGraph.validator.d.ts} +0 -0
- /package/dist/{actions/actions.service.d.ts → types/request-tracker.interface.d.ts} +0 -0
|
@@ -13,6 +13,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
+
var _a, _b;
|
|
16
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
18
|
const appApi_service_1 = require("../../api/services/appApi.service");
|
|
18
19
|
const productsApi_service_1 = require("../../api/services/productsApi.service");
|
|
@@ -36,17 +37,28 @@ const update_productDatabaseMigration_validator_1 = __importDefault(require("../
|
|
|
36
37
|
const create_productNotificationMessage_validator_1 = __importDefault(require("../validators/joi-validators/create.productNotificationMessage.validator"));
|
|
37
38
|
const create_productMessageBrokerTopic_validator_1 = __importDefault(require("../validators/joi-validators/create.productMessageBrokerTopic.validator"));
|
|
38
39
|
const update_productMessageBrokerTopic_validator_1 = __importDefault(require("../validators/joi-validators/update.productMessageBrokerTopic.validator"));
|
|
40
|
+
const secrets_1 = require("../../secrets");
|
|
39
41
|
const update_productNotificationMessage_validator_1 = __importDefault(require("../validators/joi-validators/update.productNotificationMessage.validator"));
|
|
40
42
|
const create_productNotification_validator_1 = require("../validators/joi-validators/create.productNotification.validator");
|
|
41
43
|
const functions_utils_1 = require("../utils/functions.utils");
|
|
42
44
|
const objects_utils_2 = require("../../apps/utils/objects.utils");
|
|
43
45
|
const webhooksApi_service_1 = require("../../api/services/webhooksApi.service");
|
|
44
46
|
class ProductsBuilderService {
|
|
45
|
-
constructor({ workspace_id, public_key, user_id, token, env_type, redis_client }) {
|
|
47
|
+
constructor({ workspace_id, public_key, user_id, token, env_type, redis_client, queues, access_key, workspace_private_key }) {
|
|
48
|
+
this.workspace_private_key = null;
|
|
49
|
+
/** In-memory cache for the current product run (cleared on init) to avoid repeated API calls in workflows */
|
|
50
|
+
this.brokerCache = new Map();
|
|
51
|
+
this.envCache = new Map();
|
|
52
|
+
this._debugLog = (...args) => {
|
|
53
|
+
if (ProductsBuilderService._debug)
|
|
54
|
+
console.log(...args);
|
|
55
|
+
};
|
|
46
56
|
this.workspace_id = workspace_id;
|
|
47
57
|
this.public_key = public_key;
|
|
48
58
|
this.user_id = user_id;
|
|
49
59
|
this.token = token;
|
|
60
|
+
this.access_key = access_key || null;
|
|
61
|
+
this.workspace_private_key = workspace_private_key !== null && workspace_private_key !== void 0 ? workspace_private_key : null;
|
|
50
62
|
this.userApi = new userApi_service_1.UserApiService(env_type, redis_client);
|
|
51
63
|
this.productApi = new productsApi_service_1.ProductsApiService(env_type, redis_client);
|
|
52
64
|
this.workspaceApi = new workspaceApi_service_1.WorkspaceApiService(env_type, redis_client);
|
|
@@ -54,6 +66,150 @@ class ProductsBuilderService {
|
|
|
54
66
|
this.appApi = new appApi_service_1.AppApiService(env_type, redis_client);
|
|
55
67
|
this.inputsService = new inputs_service_1.default();
|
|
56
68
|
this.thirdPartyApps = [];
|
|
69
|
+
if (redis_client) {
|
|
70
|
+
this.redisClient = redis_client;
|
|
71
|
+
// Start healthcheck workers automatically
|
|
72
|
+
//this.startHealthcheckWorkers();
|
|
73
|
+
}
|
|
74
|
+
if (queues) {
|
|
75
|
+
this.queues = queues;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
fetchPrivateKey() {
|
|
79
|
+
return this.product.private_key;
|
|
80
|
+
}
|
|
81
|
+
fetchWorkspaceId() {
|
|
82
|
+
return this.product.workspace_id;
|
|
83
|
+
}
|
|
84
|
+
fetchProductId() {
|
|
85
|
+
return this.product._id;
|
|
86
|
+
}
|
|
87
|
+
async createHealthcheck(data) {
|
|
88
|
+
try {
|
|
89
|
+
await validators_1.CreateProductHealthcheckSchema.validateAsync(data);
|
|
90
|
+
if (!data.tag) {
|
|
91
|
+
throw new Error('tag field is required');
|
|
92
|
+
}
|
|
93
|
+
const exists = await this.fetchHealthcheck(data.app, data.tag);
|
|
94
|
+
if (!exists) {
|
|
95
|
+
const { app: access_tag, event: action } = data;
|
|
96
|
+
const app = await this.fetchThirdPartyAppByAccessTag(access_tag);
|
|
97
|
+
const version = app.versions.find((data) => data.tag === app.version);
|
|
98
|
+
if (!version) {
|
|
99
|
+
throw new Error(`Version ${app.version} not found`);
|
|
100
|
+
}
|
|
101
|
+
const event = version.actions.find((act) => act.tag === action);
|
|
102
|
+
data.envs = await Promise.all(data.envs.map(async (env) => {
|
|
103
|
+
const exists = await this.fetchEnv(env.slug);
|
|
104
|
+
if (!exists) {
|
|
105
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
106
|
+
}
|
|
107
|
+
await this.validateActionDataInput({ input: env.input }, event, env.input, 0, 0);
|
|
108
|
+
env.input = (0, processor_utils_1.encrypt)(JSON.stringify(env.input), this.product.private_key);
|
|
109
|
+
console.log('INPUT', env);
|
|
110
|
+
return env;
|
|
111
|
+
}));
|
|
112
|
+
const envs = await this.fetchEnvs();
|
|
113
|
+
console.log('ENVS ===>>>>', envs);
|
|
114
|
+
console.log('DBENVS ====>>>>', data.envs);
|
|
115
|
+
envs.map((env) => {
|
|
116
|
+
const exists = data.envs.findIndex((dbEnv) => dbEnv.slug === env.slug);
|
|
117
|
+
if (exists === -1) {
|
|
118
|
+
throw new Error(`Product env ${env.slug} is not defined, please provide details`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
console.log('UPDATING VALUE', data);
|
|
122
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { action: enums_1.RequestAction.CREATE, component: enums_1.ProductComponents.HEALTHCHECK }), this.getUserAccess());
|
|
123
|
+
data.envs.map(async (env) => {
|
|
124
|
+
const payload = {
|
|
125
|
+
app: data.app,
|
|
126
|
+
action: data.event,
|
|
127
|
+
input: env.input,
|
|
128
|
+
env: env.slug,
|
|
129
|
+
product: this.product.tag,
|
|
130
|
+
retries: data.retries,
|
|
131
|
+
};
|
|
132
|
+
const jobId = `healthcheck-${data.tag}`;
|
|
133
|
+
const job = await this.queues.health.getJob(jobId);
|
|
134
|
+
if (job) {
|
|
135
|
+
await job.remove();
|
|
136
|
+
}
|
|
137
|
+
await this.queues.health.add(jobId, payload, { jobId, repeat: { every: data.interval } });
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
142
|
+
console.log(e);
|
|
143
|
+
throw e;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async updateHealthcheck(tag, data) {
|
|
147
|
+
try {
|
|
148
|
+
// 1. Fetch the existing healthcheck
|
|
149
|
+
const healthcheck = await this.fetchHealthcheck(data.app, tag);
|
|
150
|
+
if (!healthcheck) {
|
|
151
|
+
throw new Error(`Healthcheck with tag: ${tag} not found`);
|
|
152
|
+
}
|
|
153
|
+
// 2. Validate the incoming data
|
|
154
|
+
await validators_1.CreateProductHealthcheckSchema.validateAsync(data); // No Update schema, use Create
|
|
155
|
+
// 3. Check for tag conflicts
|
|
156
|
+
if (data.tag && data.tag !== tag && (await this.fetchHealthcheck(data.app, data.tag))) {
|
|
157
|
+
throw new Error(`Healthcheck with tag ${data.tag} already exists`);
|
|
158
|
+
}
|
|
159
|
+
// 4. Validate and process envs
|
|
160
|
+
if (data.envs) {
|
|
161
|
+
data.envs = await Promise.all(data.envs.map(async (env) => {
|
|
162
|
+
const exists = await this.fetchEnv(env.slug);
|
|
163
|
+
if (!exists) {
|
|
164
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
165
|
+
}
|
|
166
|
+
// Validate input if present
|
|
167
|
+
if (env.input) {
|
|
168
|
+
const app = await this.fetchThirdPartyAppByAccessTag(data.app);
|
|
169
|
+
const version = app.versions.find((v) => v.tag === app.version);
|
|
170
|
+
if (!version) {
|
|
171
|
+
throw new Error(`Version ${app.version} not found`);
|
|
172
|
+
}
|
|
173
|
+
const event = version.actions.find((act) => act.tag === data.event);
|
|
174
|
+
await this.validateActionDataInput({ input: env.input }, event, env.input, 0, 0);
|
|
175
|
+
env.input = (0, processor_utils_1.encrypt)(JSON.stringify(env.input), this.product.private_key);
|
|
176
|
+
}
|
|
177
|
+
return env;
|
|
178
|
+
}));
|
|
179
|
+
}
|
|
180
|
+
// 5. Ensure all product envs are covered
|
|
181
|
+
const envs = await this.fetchEnvs();
|
|
182
|
+
envs.map((env) => {
|
|
183
|
+
var _a;
|
|
184
|
+
const exists = (_a = data.envs) === null || _a === void 0 ? void 0 : _a.findIndex((dbEnv) => dbEnv.slug === env.slug);
|
|
185
|
+
if (exists === -1) {
|
|
186
|
+
throw new Error(`Product env ${env.slug} is not defined, please provide details`);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
// 6. Update the healthcheck
|
|
190
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({}, healthcheck), data), { tag, component: enums_1.ProductComponents.HEALTHCHECK, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
throw e;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async fetchHealthcheck(access_tag, tag, throwError = false) {
|
|
197
|
+
const healthchecks = await this.productApi.fetchProductComponents(this.product_id, 'healthcheck', this.getUserAccess());
|
|
198
|
+
const health = healthchecks.find((data) => data.tag === tag && data.app === access_tag);
|
|
199
|
+
if (!health && throwError)
|
|
200
|
+
throw new Error(`Healthcheck ${tag} not found`);
|
|
201
|
+
return health || null;
|
|
202
|
+
}
|
|
203
|
+
async fetchHealthchecks(access_tag, throwError = false) {
|
|
204
|
+
const healthchecks = await this.productApi.fetchProductComponents(this.product_id, 'healthcheck', this.getUserAccess());
|
|
205
|
+
const health = healthchecks.filter((data) => data.app === access_tag);
|
|
206
|
+
if (!health && throwError)
|
|
207
|
+
throw new Error(`Access tag ${access_tag} not found`);
|
|
208
|
+
return health;
|
|
209
|
+
}
|
|
210
|
+
async fetchProductHealthchecks() {
|
|
211
|
+
const healthchecks = await this.productApi.fetchProductComponents(this.product_id, 'healthcheck', this.getUserAccess());
|
|
212
|
+
return healthchecks;
|
|
57
213
|
}
|
|
58
214
|
async updateDataValidation(selector, update) {
|
|
59
215
|
if (!selector.startsWith('$Data{') && !selector.startsWith('$Filter')) {
|
|
@@ -68,26 +224,27 @@ class ProductsBuilderService {
|
|
|
68
224
|
if (stages.length < 3) {
|
|
69
225
|
throw new Error(`Invalid selector ${selector}`);
|
|
70
226
|
}
|
|
71
|
-
const tag = stages[0];
|
|
72
|
-
const type = stages[1];
|
|
227
|
+
const tag = String(stages[0]);
|
|
228
|
+
const type = String(stages[1]);
|
|
73
229
|
let size = 2;
|
|
74
230
|
let data;
|
|
75
231
|
switch (type) {
|
|
76
232
|
case productsBuilder_types_1.FeatureEventTypes.DB_ACTION:
|
|
77
|
-
const action = this.fetchDatabaseAction(tag);
|
|
233
|
+
const action = await this.fetchDatabaseAction(tag);
|
|
78
234
|
if (!action)
|
|
79
235
|
throw new Error(`DB Action ${tag} not found`);
|
|
80
236
|
data = useData ? action.data : action.filterData;
|
|
81
237
|
break;
|
|
82
238
|
case productsBuilder_types_1.FeatureEventTypes.NOTIFICATION:
|
|
83
239
|
size = 3;
|
|
84
|
-
|
|
85
|
-
|
|
240
|
+
const stage3Str = String(stages[3]);
|
|
241
|
+
if (!stages[3] || (stage3Str !== 'push' && stage3Str !== 'callback' && stage3Str !== 'email')) {
|
|
242
|
+
throw new Error(`Invalid value ${stage3Str} in ${selector}, expected to be "push", "callback" or "email" in notification`);
|
|
86
243
|
}
|
|
87
|
-
const notification = this.fetchNotificationMessage(tag);
|
|
244
|
+
const notification = await this.fetchNotificationMessage(tag);
|
|
88
245
|
if (!notification)
|
|
89
246
|
throw new Error(`Notification ${tag} not found`);
|
|
90
|
-
if (
|
|
247
|
+
if (stage3Str === 'push') {
|
|
91
248
|
data = notification.push_notification_data;
|
|
92
249
|
}
|
|
93
250
|
if (stages[3] === 'callback') {
|
|
@@ -129,11 +286,11 @@ class ProductsBuilderService {
|
|
|
129
286
|
await validators_1.CreateProductBuilderSchema.validateAsync(data);
|
|
130
287
|
const exists = await this.checkIfProductExists(data.name);
|
|
131
288
|
if (exists && (exists === null || exists === void 0 ? void 0 : exists._id)) {
|
|
132
|
-
await this.initializeProduct(exists
|
|
289
|
+
// await this.initializeProduct(exists?._id);
|
|
133
290
|
}
|
|
134
291
|
else {
|
|
135
292
|
const product = await this.createNewProduct(data);
|
|
136
|
-
await this.initializeProduct(product._id);
|
|
293
|
+
// await this.initializeProduct(product._id);
|
|
137
294
|
}
|
|
138
295
|
}
|
|
139
296
|
catch (e) {
|
|
@@ -144,10 +301,28 @@ class ProductsBuilderService {
|
|
|
144
301
|
if (!this.workspace) {
|
|
145
302
|
this.workspace = await this.workspaceApi.fetchWorkspaceById(this.getUserAccess(), subCheck);
|
|
146
303
|
}
|
|
304
|
+
// Fetch workspace private key using the dedicated endpoint for secrets encryption
|
|
305
|
+
if (!this.workspace_private_key && this.access_key) {
|
|
306
|
+
try {
|
|
307
|
+
this.workspace_private_key = await this.workspaceApi.fetchPrivateKey(this.getUserAccess(), this.access_key);
|
|
308
|
+
}
|
|
309
|
+
catch (e) {
|
|
310
|
+
console.warn('[ProductsBuilderService] Failed to fetch workspace private key:', e);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Get the workspace private key for secrets encryption
|
|
316
|
+
* @returns The workspace private key or null if not available
|
|
317
|
+
*/
|
|
318
|
+
getWorkspacePrivateKey() {
|
|
319
|
+
return this.workspace_private_key;
|
|
147
320
|
}
|
|
148
321
|
async initializeProduct(product_id) {
|
|
149
322
|
try {
|
|
150
|
-
this.
|
|
323
|
+
this.brokerCache.clear();
|
|
324
|
+
this.envCache.clear();
|
|
325
|
+
this.product = (await this.productApi.initProduct(product_id, this.getUserAccess()));
|
|
151
326
|
this.product_id = product_id;
|
|
152
327
|
}
|
|
153
328
|
catch (e) {
|
|
@@ -156,20 +331,96 @@ class ProductsBuilderService {
|
|
|
156
331
|
}
|
|
157
332
|
async initializeProductByTag(tag) {
|
|
158
333
|
try {
|
|
159
|
-
this.product
|
|
334
|
+
if (this.product && this.product.tag === tag) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
this.brokerCache.clear();
|
|
338
|
+
this.envCache.clear();
|
|
339
|
+
this.product = (await this.productApi.initProduct(tag, this.getUserAccess()));
|
|
340
|
+
if (!this.product) {
|
|
341
|
+
throw new Error(`Product with tag "${tag}" not found or failed to fetch`);
|
|
342
|
+
}
|
|
160
343
|
this.product_id = this.product._id;
|
|
161
344
|
}
|
|
162
345
|
catch (e) {
|
|
163
346
|
throw e;
|
|
164
347
|
}
|
|
165
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Bootstrap action - ultra-lightweight API call to fetch action data needed for processAction
|
|
351
|
+
* Replaces 5+ separate API calls: initializeProduct, fetchApp, fetchThirdPartyApp, fetchEnv, initializePricing
|
|
352
|
+
* Returns only the minimal action data needed to execute
|
|
353
|
+
*/
|
|
354
|
+
async bootstrapAction(params) {
|
|
355
|
+
try {
|
|
356
|
+
const result = await this.productApi.bootstrapAction(params, this.getUserAccess());
|
|
357
|
+
// Initialize minimal product data
|
|
358
|
+
if (result.product_id) {
|
|
359
|
+
this.product_id = result.product_id;
|
|
360
|
+
}
|
|
361
|
+
return result;
|
|
362
|
+
}
|
|
363
|
+
catch (e) {
|
|
364
|
+
throw e;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
async bootstrapNotification(params) {
|
|
368
|
+
try {
|
|
369
|
+
const result = await this.productApi.bootstrapNotification(params, this.getUserAccess());
|
|
370
|
+
if (result.product_id) {
|
|
371
|
+
this.product_id = result.product_id;
|
|
372
|
+
}
|
|
373
|
+
if (result.notification && result.private_key) {
|
|
374
|
+
result.notification = this.decryptNotificationChannelConfigs(result.notification, result.private_key);
|
|
375
|
+
}
|
|
376
|
+
return result;
|
|
377
|
+
}
|
|
378
|
+
catch (e) {
|
|
379
|
+
throw e;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
async bootstrapStorage(params) {
|
|
383
|
+
try {
|
|
384
|
+
const result = await this.productApi.bootstrapStorage(params, this.getUserAccess());
|
|
385
|
+
if (result.product_id) {
|
|
386
|
+
this.product_id = result.product_id;
|
|
387
|
+
}
|
|
388
|
+
return result;
|
|
389
|
+
}
|
|
390
|
+
catch (e) {
|
|
391
|
+
throw e;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Bootstrap workflow - fetch all action/notification/storage data for multiple steps in one API call
|
|
396
|
+
*/
|
|
397
|
+
async bootstrapWorkflow(params) {
|
|
398
|
+
try {
|
|
399
|
+
const auth = this.getUserAccess();
|
|
400
|
+
const result = await this.productApi.bootstrapWorkflow(Object.assign(Object.assign({}, params), { workspace_id: auth.workspace_id }), auth);
|
|
401
|
+
if (result && typeof result === 'object') {
|
|
402
|
+
for (const stepTag of Object.keys(result)) {
|
|
403
|
+
const data = result[stepTag];
|
|
404
|
+
if (data === null || data === void 0 ? void 0 : data.product_id) {
|
|
405
|
+
this.product_id = data.product_id;
|
|
406
|
+
}
|
|
407
|
+
if ((data === null || data === void 0 ? void 0 : data.notification) && (data === null || data === void 0 ? void 0 : data.private_key)) {
|
|
408
|
+
result[stepTag] = Object.assign(Object.assign({}, data), { notification: this.decryptNotificationChannelConfigs(data.notification, data.private_key) });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return result !== null && result !== void 0 ? result : {};
|
|
413
|
+
}
|
|
414
|
+
catch (e) {
|
|
415
|
+
throw e;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
166
418
|
async updateProduct(data) {
|
|
167
419
|
try {
|
|
168
420
|
if (!this.app_id)
|
|
169
421
|
throw new Error('Product not initialized');
|
|
170
422
|
await validators_1.CreateProductBuilderSchema.validateAsync(data);
|
|
171
423
|
await this.productApi.updateProduct(this.product_id, Object.assign({}, data), this.getUserAccess());
|
|
172
|
-
await this.initializeProduct(this.product_id);
|
|
173
424
|
}
|
|
174
425
|
catch (e) {
|
|
175
426
|
throw e;
|
|
@@ -186,24 +437,47 @@ class ProductsBuilderService {
|
|
|
186
437
|
return false;
|
|
187
438
|
}
|
|
188
439
|
}
|
|
189
|
-
fetchProduct() {
|
|
440
|
+
async fetchProduct() {
|
|
190
441
|
if (!this.product) {
|
|
191
442
|
throw new Error('Product not yet initiated');
|
|
192
443
|
}
|
|
193
|
-
return this.product;
|
|
444
|
+
return await this.productApi.fetchProductByTag(this.product.tag, this.getUserAccess());
|
|
194
445
|
}
|
|
195
|
-
async createSession(data) {
|
|
446
|
+
async createSession(data, throwErrorIfExists = false) {
|
|
196
447
|
try {
|
|
197
|
-
|
|
198
|
-
if (!
|
|
199
|
-
|
|
448
|
+
await validators_1.CreateProductSessionSchema.validateAsync(data);
|
|
449
|
+
if (!data.tag) {
|
|
450
|
+
throw new Error('tag field is required');
|
|
451
|
+
}
|
|
452
|
+
const exists = await this.fetchSession(data.tag);
|
|
453
|
+
if (!exists) {
|
|
454
|
+
if (!data.selector.startsWith('$Session{')) {
|
|
455
|
+
throw new Error('Selector should be in the format $Session{...}{key}');
|
|
456
|
+
}
|
|
457
|
+
const stages = (0, string_utils_1.extractStages)(data.selector);
|
|
458
|
+
let current = data.schema;
|
|
459
|
+
for (const stage of stages) {
|
|
460
|
+
if (current && typeof current === 'object' && stage in current) {
|
|
461
|
+
current = current[stage];
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
throw new Error(`${data.selector} not found in event sample`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
if (current === null || typeof current === 'undefined' || typeof current === 'object') {
|
|
468
|
+
throw new Error('Selector value is not allowed to be an object|array|null|undefined');
|
|
469
|
+
}
|
|
200
470
|
data.schema_data = (await this.inputsService.parseJson({
|
|
201
471
|
data: data.schema,
|
|
202
472
|
expected: inputs_types_1.ExpectedValues.PARSESAMPLE,
|
|
203
|
-
category: enums_1.Categories.DATA,
|
|
204
473
|
}));
|
|
205
|
-
|
|
206
|
-
|
|
474
|
+
data.selectorValue = current;
|
|
475
|
+
const payload = Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.SESSION, action: enums_1.RequestAction.CREATE });
|
|
476
|
+
await this.productApi.updateProduct(this.product_id, payload, this.getUserAccess());
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
if (throwErrorIfExists)
|
|
480
|
+
throw new Error(`Session ${data.tag} already exists`);
|
|
207
481
|
}
|
|
208
482
|
}
|
|
209
483
|
catch (e) {
|
|
@@ -212,13 +486,13 @@ class ProductsBuilderService {
|
|
|
212
486
|
}
|
|
213
487
|
async updateSession(tag, data) {
|
|
214
488
|
try {
|
|
215
|
-
const
|
|
216
|
-
if (!
|
|
217
|
-
throw new Error(`Session ${tag} not found`);
|
|
489
|
+
const session = await this.fetchSession(tag);
|
|
490
|
+
if (!session) {
|
|
491
|
+
throw new Error(`Session with tag: ${tag} not found`);
|
|
218
492
|
}
|
|
219
493
|
//const { _id } = auth;
|
|
220
494
|
await validators_1.UpdateProductSessionSchema.validateAsync(data); // Change to update;
|
|
221
|
-
if (data.tag && this.
|
|
495
|
+
if (data.tag && this.fetchSession(data.tag) && data.tag !== tag) {
|
|
222
496
|
throw new Error(`tag ${data.tag} is in use`); // TODO: also check on the backend
|
|
223
497
|
}
|
|
224
498
|
if (!data.tag) {
|
|
@@ -230,20 +504,54 @@ class ProductsBuilderService {
|
|
|
230
504
|
expected: inputs_types_1.ExpectedValues.PARSESAMPLE,
|
|
231
505
|
category: enums_1.Categories.DATA,
|
|
232
506
|
}));
|
|
507
|
+
if (!data.selector) {
|
|
508
|
+
throw new Error('Selector is expected when updating schema');
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
if (data.selector) {
|
|
512
|
+
const stages = (0, string_utils_1.extractStages)(data.selector);
|
|
513
|
+
let current = data.schema;
|
|
514
|
+
for (const stage of stages) {
|
|
515
|
+
if (current && typeof current === 'object' && stage in current) {
|
|
516
|
+
current = current[stage];
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
throw new Error(`${data.selector} not found in event sample`);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
if (current === null || typeof current === 'undefined' || typeof current === 'object') {
|
|
523
|
+
throw new Error('Selector value is not allowed to be an object|array|null|undefined');
|
|
524
|
+
}
|
|
233
525
|
}
|
|
234
|
-
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, Object.assign(Object.assign({},
|
|
235
|
-
await this.initializeProduct(this.product_id);
|
|
526
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, Object.assign(Object.assign({}, session), data)), { component: enums_1.ProductComponents.SESSION, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
236
527
|
}
|
|
237
528
|
catch (e) {
|
|
238
529
|
throw e;
|
|
239
530
|
}
|
|
240
531
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
return
|
|
532
|
+
async fetchSessions(version) {
|
|
533
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'session', this.getUserAccess());
|
|
534
|
+
return components;
|
|
535
|
+
}
|
|
536
|
+
async fetchSession(tag) {
|
|
537
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'session', tag, this.getUserAccess());
|
|
538
|
+
return component;
|
|
244
539
|
}
|
|
245
|
-
|
|
246
|
-
|
|
540
|
+
async deleteSession(tag) {
|
|
541
|
+
try {
|
|
542
|
+
const session = await this.fetchSession(tag);
|
|
543
|
+
if (!session) {
|
|
544
|
+
throw new Error(`Session with tag: ${tag} not found`);
|
|
545
|
+
}
|
|
546
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
547
|
+
tag,
|
|
548
|
+
component: enums_1.ProductComponents.SESSION,
|
|
549
|
+
action: enums_1.RequestAction.DELETE,
|
|
550
|
+
}, this.getUserAccess());
|
|
551
|
+
}
|
|
552
|
+
catch (e) {
|
|
553
|
+
throw e;
|
|
554
|
+
}
|
|
247
555
|
}
|
|
248
556
|
async createMessageBrokerTopic(data, throwErrorIfExists = false) {
|
|
249
557
|
try {
|
|
@@ -257,16 +565,17 @@ class ProductsBuilderService {
|
|
|
257
565
|
if (data.sample)
|
|
258
566
|
data.sample = JSON.stringify(data.sample);
|
|
259
567
|
await create_productMessageBrokerTopic_validator_1.default.validateAsync(data);
|
|
260
|
-
const exists = this.fetchMessageBrokerTopic(data.tag);
|
|
261
|
-
const broker = this.fetchMessageBroker(messageBrokerTag);
|
|
262
|
-
|
|
568
|
+
const exists = await this.fetchMessageBrokerTopic(data.tag);
|
|
569
|
+
const broker = await this.fetchMessageBroker(messageBrokerTag);
|
|
570
|
+
if (broker) {
|
|
571
|
+
(0, functions_utils_1.validateAWSSQSQueueUrl)(broker.envs, data.queueUrls);
|
|
572
|
+
}
|
|
263
573
|
data.tag = tag;
|
|
264
574
|
if (!exists) {
|
|
265
575
|
if (data.sample) {
|
|
266
576
|
data.data = (await (0, string_utils_1.extractPlaceholders)(data.sample));
|
|
267
577
|
}
|
|
268
578
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { messageBrokerTag, component: enums_1.ProductComponents.MESSAGEBROKER_TOPIC, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
269
|
-
await this.initializeProduct(this.product_id);
|
|
270
579
|
}
|
|
271
580
|
else {
|
|
272
581
|
if (throwErrorIfExists)
|
|
@@ -289,12 +598,12 @@ class ProductsBuilderService {
|
|
|
289
598
|
if (!messageBrokerTag || !tag) {
|
|
290
599
|
throw new Error(`tag is expected to be defined as "messageBrokr_tag:topic_tag"`);
|
|
291
600
|
}
|
|
292
|
-
const exists = this.fetchMessageBrokerTopic(data.tag);
|
|
601
|
+
const exists = await this.fetchMessageBrokerTopic(data.tag);
|
|
293
602
|
if (!exists) {
|
|
294
603
|
throw new Error(`Topic ${data.tag} not found`);
|
|
295
604
|
}
|
|
296
|
-
const broker = this.fetchMessageBroker(messageBrokerTag);
|
|
297
|
-
if (data.queueUrls) {
|
|
605
|
+
const broker = await this.fetchMessageBroker(messageBrokerTag);
|
|
606
|
+
if (data.queueUrls && broker) {
|
|
298
607
|
(0, functions_utils_1.validateAWSSQSQueueUrl)(broker.envs, data.queueUrls);
|
|
299
608
|
}
|
|
300
609
|
data.tag = tag;
|
|
@@ -303,7 +612,6 @@ class ProductsBuilderService {
|
|
|
303
612
|
data.data = (await (0, string_utils_1.extractPlaceholders)(data.sample));
|
|
304
613
|
}
|
|
305
614
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { messageBrokerTag, component: enums_1.ProductComponents.MESSAGEBROKER_TOPIC, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
306
|
-
await this.initializeProduct(this.product_id);
|
|
307
615
|
}
|
|
308
616
|
else {
|
|
309
617
|
throw new Error(`Message Broker Topic ${data.tag} not found`);
|
|
@@ -313,24 +621,157 @@ class ProductsBuilderService {
|
|
|
313
621
|
throw e;
|
|
314
622
|
}
|
|
315
623
|
}
|
|
316
|
-
fetchMessageBrokerTopic(tag, throwErrorIfExists = false) {
|
|
624
|
+
async fetchMessageBrokerTopic(tag, throwErrorIfExists = false) {
|
|
317
625
|
const [messageBrokerTag, topicTag] = tag.split(':');
|
|
318
626
|
if (!messageBrokerTag || !topicTag) {
|
|
319
627
|
throw new Error(`tag is expected to be defined as "messageBroker_tag:topic_tag"`);
|
|
320
628
|
}
|
|
321
|
-
const messageBroker = this.
|
|
629
|
+
const messageBroker = await this.fetchMessageBroker(messageBrokerTag);
|
|
322
630
|
if (!messageBroker)
|
|
323
631
|
throw new Error(`MessageBroker ${messageBrokerTag} not found`);
|
|
324
|
-
const
|
|
632
|
+
const topics = messageBroker.topics || [];
|
|
633
|
+
const topic = topics.find((data) => data.tag === topicTag);
|
|
325
634
|
if (!topic && throwErrorIfExists)
|
|
326
635
|
throw new Error(`MessageBroker topic ${tag} not found`);
|
|
327
|
-
return topic;
|
|
636
|
+
return topic || null;
|
|
637
|
+
}
|
|
638
|
+
async fetchMessageBrokerTopics(messageBrokerTag) {
|
|
639
|
+
const messageBroker = await this.fetchMessageBroker(messageBrokerTag);
|
|
640
|
+
if (!messageBroker)
|
|
641
|
+
throw new Error(`Message Broker ${messageBrokerTag} not found`);
|
|
642
|
+
return messageBroker.topics || [];
|
|
643
|
+
}
|
|
644
|
+
// ==================== MESSAGE BROKER PRODUCERS ====================
|
|
645
|
+
async createMessageBrokerProducer(data) {
|
|
646
|
+
var _a, _b;
|
|
647
|
+
try {
|
|
648
|
+
const [messageBrokerTag, topicTag] = data.topic.split(':');
|
|
649
|
+
if (!messageBrokerTag || !topicTag) {
|
|
650
|
+
throw new Error(`topic is expected to be defined as "messageBroker_tag:topic_tag"`);
|
|
651
|
+
}
|
|
652
|
+
const broker = await this.fetchMessageBroker(messageBrokerTag);
|
|
653
|
+
if (!broker) {
|
|
654
|
+
throw new Error(`Message Broker ${messageBrokerTag} not found`);
|
|
655
|
+
}
|
|
656
|
+
// Check if topic exists
|
|
657
|
+
const topic = (_a = broker.topics) === null || _a === void 0 ? void 0 : _a.find((t) => t.tag === topicTag);
|
|
658
|
+
if (!topic) {
|
|
659
|
+
throw new Error(`Topic ${topicTag} not found in broker ${messageBrokerTag}`);
|
|
660
|
+
}
|
|
661
|
+
// Check if producer already exists
|
|
662
|
+
const existingProducer = (_b = broker.producers) === null || _b === void 0 ? void 0 : _b.find((p) => p.tag === data.tag);
|
|
663
|
+
if (existingProducer) {
|
|
664
|
+
throw new Error(`Producer ${data.tag} already exists in broker ${messageBrokerTag}`);
|
|
665
|
+
}
|
|
666
|
+
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());
|
|
667
|
+
}
|
|
668
|
+
catch (e) {
|
|
669
|
+
throw e;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
async updateMessageBrokerProducer(data) {
|
|
673
|
+
var _a;
|
|
674
|
+
try {
|
|
675
|
+
const [messageBrokerTag, topicTag] = data.topic.split(':');
|
|
676
|
+
if (!messageBrokerTag || !topicTag) {
|
|
677
|
+
throw new Error(`topic is expected to be defined as "messageBroker_tag:topic_tag"`);
|
|
678
|
+
}
|
|
679
|
+
const broker = await this.fetchMessageBroker(messageBrokerTag);
|
|
680
|
+
if (!broker) {
|
|
681
|
+
throw new Error(`Message Broker ${messageBrokerTag} not found`);
|
|
682
|
+
}
|
|
683
|
+
// Check if producer exists
|
|
684
|
+
const existingProducer = (_a = broker.producers) === null || _a === void 0 ? void 0 : _a.find((p) => p.tag === data.tag);
|
|
685
|
+
if (!existingProducer) {
|
|
686
|
+
throw new Error(`Producer ${data.tag} not found in broker ${messageBrokerTag}`);
|
|
687
|
+
}
|
|
688
|
+
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());
|
|
689
|
+
}
|
|
690
|
+
catch (e) {
|
|
691
|
+
throw e;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
async fetchMessageBrokerProducer(brokerTag, tag) {
|
|
695
|
+
var _a;
|
|
696
|
+
const messageBrokers = this.product.messageBrokers || [];
|
|
697
|
+
const messageBroker = messageBrokers.find((data) => data.tag === brokerTag);
|
|
698
|
+
if (!messageBroker)
|
|
699
|
+
throw new Error(`MessageBroker ${brokerTag} not found`);
|
|
700
|
+
const producer = (_a = messageBroker.producers) === null || _a === void 0 ? void 0 : _a.find((p) => p.tag === tag);
|
|
701
|
+
return producer || null;
|
|
702
|
+
}
|
|
703
|
+
async fetchMessageBrokerProducers(messageBrokerTag) {
|
|
704
|
+
const messageBrokers = this.product.messageBrokers || [];
|
|
705
|
+
const messageBroker = messageBrokers.find((data) => data.tag === messageBrokerTag);
|
|
706
|
+
if (!messageBroker)
|
|
707
|
+
throw new Error(`Message Broker ${messageBrokerTag} not found`);
|
|
708
|
+
return messageBroker.producers || [];
|
|
709
|
+
}
|
|
710
|
+
// ==================== MESSAGE BROKER CONSUMERS ====================
|
|
711
|
+
async createMessageBrokerConsumer(data) {
|
|
712
|
+
var _a, _b;
|
|
713
|
+
try {
|
|
714
|
+
const [messageBrokerTag, topicTag] = data.topic.split(':');
|
|
715
|
+
if (!messageBrokerTag || !topicTag) {
|
|
716
|
+
throw new Error(`topic is expected to be defined as "messageBroker_tag:topic_tag"`);
|
|
717
|
+
}
|
|
718
|
+
const broker = await this.fetchMessageBroker(messageBrokerTag);
|
|
719
|
+
if (!broker) {
|
|
720
|
+
throw new Error(`Message Broker ${messageBrokerTag} not found`);
|
|
721
|
+
}
|
|
722
|
+
// Check if topic exists
|
|
723
|
+
const topic = (_a = broker.topics) === null || _a === void 0 ? void 0 : _a.find((t) => t.tag === topicTag);
|
|
724
|
+
if (!topic) {
|
|
725
|
+
throw new Error(`Topic ${topicTag} not found in broker ${messageBrokerTag}`);
|
|
726
|
+
}
|
|
727
|
+
// Check if consumer already exists
|
|
728
|
+
const existingConsumer = (_b = broker.consumers) === null || _b === void 0 ? void 0 : _b.find((c) => c.tag === data.tag);
|
|
729
|
+
if (existingConsumer) {
|
|
730
|
+
throw new Error(`Consumer ${data.tag} already exists in broker ${messageBrokerTag}`);
|
|
731
|
+
}
|
|
732
|
+
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());
|
|
733
|
+
}
|
|
734
|
+
catch (e) {
|
|
735
|
+
throw e;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
async updateMessageBrokerConsumer(data) {
|
|
739
|
+
var _a;
|
|
740
|
+
try {
|
|
741
|
+
const [messageBrokerTag, topicTag] = data.topic.split(':');
|
|
742
|
+
if (!messageBrokerTag || !topicTag) {
|
|
743
|
+
throw new Error(`topic is expected to be defined as "messageBroker_tag:topic_tag"`);
|
|
744
|
+
}
|
|
745
|
+
const broker = await this.fetchMessageBroker(messageBrokerTag);
|
|
746
|
+
if (!broker) {
|
|
747
|
+
throw new Error(`Message Broker ${messageBrokerTag} not found`);
|
|
748
|
+
}
|
|
749
|
+
// Check if consumer exists
|
|
750
|
+
const existingConsumer = (_a = broker.consumers) === null || _a === void 0 ? void 0 : _a.find((c) => c.tag === data.tag);
|
|
751
|
+
if (!existingConsumer) {
|
|
752
|
+
throw new Error(`Consumer ${data.tag} not found in broker ${messageBrokerTag}`);
|
|
753
|
+
}
|
|
754
|
+
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());
|
|
755
|
+
}
|
|
756
|
+
catch (e) {
|
|
757
|
+
throw e;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
async fetchMessageBrokerConsumer(brokerTag, tag) {
|
|
761
|
+
var _a;
|
|
762
|
+
const messageBrokers = this.product.messageBrokers || [];
|
|
763
|
+
const messageBroker = messageBrokers.find((data) => data.tag === brokerTag);
|
|
764
|
+
if (!messageBroker)
|
|
765
|
+
throw new Error(`MessageBroker ${brokerTag} not found`);
|
|
766
|
+
const consumer = (_a = messageBroker.consumers) === null || _a === void 0 ? void 0 : _a.find((c) => c.tag === tag);
|
|
767
|
+
return consumer || null;
|
|
328
768
|
}
|
|
329
|
-
|
|
330
|
-
const
|
|
769
|
+
async fetchMessageBrokerConsumers(messageBrokerTag) {
|
|
770
|
+
const messageBrokers = this.product.messageBrokers || [];
|
|
771
|
+
const messageBroker = messageBrokers.find((data) => data.tag === messageBrokerTag);
|
|
331
772
|
if (!messageBroker)
|
|
332
773
|
throw new Error(`Message Broker ${messageBrokerTag} not found`);
|
|
333
|
-
return messageBroker.
|
|
774
|
+
return messageBroker.consumers || [];
|
|
334
775
|
}
|
|
335
776
|
async validateQuotaFallbackInputAndOutput(data, type) {
|
|
336
777
|
const input = data.input;
|
|
@@ -364,7 +805,7 @@ class ProductsBuilderService {
|
|
|
364
805
|
this.checkActionQuotaFallbackInput(action.body, option.input.body, input, 'body');
|
|
365
806
|
}
|
|
366
807
|
else {
|
|
367
|
-
const feature = this.fetchFeature(option.event);
|
|
808
|
+
const feature = await this.fetchFeature(option.event);
|
|
368
809
|
if (!feature) {
|
|
369
810
|
throw new Error(`Feature ${option.event} not found`);
|
|
370
811
|
}
|
|
@@ -454,7 +895,7 @@ class ProductsBuilderService {
|
|
|
454
895
|
}
|
|
455
896
|
else {
|
|
456
897
|
// fetch feature
|
|
457
|
-
const feature = this.fetchFeature(option.event);
|
|
898
|
+
const feature = await this.fetchFeature(option.event);
|
|
458
899
|
if (!feature) {
|
|
459
900
|
throw new Error(`Feature ${option.event} not found`);
|
|
460
901
|
}
|
|
@@ -522,7 +963,7 @@ class ProductsBuilderService {
|
|
|
522
963
|
if (!data.tag) {
|
|
523
964
|
throw new Error('tag field is required');
|
|
524
965
|
}
|
|
525
|
-
if (!this.fetchQuota(data.tag)) {
|
|
966
|
+
if (!(await this.fetchQuota(data.tag))) {
|
|
526
967
|
await validators_1.CreateProductQuotaSchema.validateAsync(data);
|
|
527
968
|
await this.validateQuotaFallbackInputAndOutput(data, 'quota');
|
|
528
969
|
data.total_quota = 0;
|
|
@@ -547,7 +988,10 @@ class ProductsBuilderService {
|
|
|
547
988
|
if (!action) {
|
|
548
989
|
throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
|
|
549
990
|
}
|
|
550
|
-
if (action.headers.data.length > 0 ||
|
|
991
|
+
if (action.headers.data.length > 0 ||
|
|
992
|
+
action.body.data.length > 0 ||
|
|
993
|
+
action.params.data.length > 0 ||
|
|
994
|
+
action.query.data.length > 0) {
|
|
551
995
|
throw new Error('Healthcheck action is expected to have no headers, body, params or query');
|
|
552
996
|
}
|
|
553
997
|
}
|
|
@@ -565,7 +1009,7 @@ class ProductsBuilderService {
|
|
|
565
1009
|
}
|
|
566
1010
|
async updateQuota(tag, data) {
|
|
567
1011
|
try {
|
|
568
|
-
const quota = this.fetchQuota(tag);
|
|
1012
|
+
const quota = await this.fetchQuota(tag);
|
|
569
1013
|
if (quota) {
|
|
570
1014
|
await validators_1.UpdateProductQuotaSchema.validateAsync(data);
|
|
571
1015
|
if (data.options) {
|
|
@@ -593,7 +1037,10 @@ class ProductsBuilderService {
|
|
|
593
1037
|
if (!action) {
|
|
594
1038
|
throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
|
|
595
1039
|
}
|
|
596
|
-
if (action.headers.data.length > 0 ||
|
|
1040
|
+
if (action.headers.data.length > 0 ||
|
|
1041
|
+
action.body.data.length > 0 ||
|
|
1042
|
+
action.params.data.length > 0 ||
|
|
1043
|
+
action.query.data.length > 0) {
|
|
597
1044
|
throw new Error('Healthcheck action is expected to have no headers, body, params or query');
|
|
598
1045
|
}
|
|
599
1046
|
}
|
|
@@ -613,18 +1060,36 @@ class ProductsBuilderService {
|
|
|
613
1060
|
throw e;
|
|
614
1061
|
}
|
|
615
1062
|
}
|
|
616
|
-
|
|
617
|
-
|
|
1063
|
+
async fetchQuotas(version) {
|
|
1064
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'quota', this.getUserAccess());
|
|
1065
|
+
return components;
|
|
618
1066
|
}
|
|
619
|
-
|
|
620
|
-
|
|
1067
|
+
async fetchQuota(tag, version) {
|
|
1068
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'quota', tag, this.getUserAccess());
|
|
1069
|
+
return component;
|
|
1070
|
+
}
|
|
1071
|
+
async deleteQuota(tag) {
|
|
1072
|
+
try {
|
|
1073
|
+
const quota = await this.fetchQuota(tag);
|
|
1074
|
+
if (!quota) {
|
|
1075
|
+
throw new Error(`Quota with tag: ${tag} not found`);
|
|
1076
|
+
}
|
|
1077
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
1078
|
+
tag,
|
|
1079
|
+
component: enums_1.ProductComponents.QUOTA,
|
|
1080
|
+
action: enums_1.RequestAction.DELETE,
|
|
1081
|
+
}, this.getUserAccess());
|
|
1082
|
+
}
|
|
1083
|
+
catch (e) {
|
|
1084
|
+
throw e;
|
|
1085
|
+
}
|
|
621
1086
|
}
|
|
622
1087
|
async createFallback(data) {
|
|
623
1088
|
try {
|
|
624
1089
|
if (!data.tag) {
|
|
625
1090
|
throw new Error('tag field is required');
|
|
626
1091
|
}
|
|
627
|
-
if (!this.fetchFallback(data.tag)) {
|
|
1092
|
+
if (!(await this.fetchFallback(data.tag))) {
|
|
628
1093
|
await validators_1.CreateProductFallbackSchema.validateAsync(data);
|
|
629
1094
|
await this.validateQuotaFallbackInputAndOutput(data, 'fallback');
|
|
630
1095
|
await Promise.all(data.options.map(async (d) => {
|
|
@@ -646,7 +1111,10 @@ class ProductsBuilderService {
|
|
|
646
1111
|
if (!action) {
|
|
647
1112
|
throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
|
|
648
1113
|
}
|
|
649
|
-
if (action.headers.data.length > 0 ||
|
|
1114
|
+
if (action.headers.data.length > 0 ||
|
|
1115
|
+
action.body.data.length > 0 ||
|
|
1116
|
+
action.params.data.length > 0 ||
|
|
1117
|
+
action.query.data.length > 0) {
|
|
650
1118
|
throw new Error('Healthcheck action is expected to have no headers, body, params or query');
|
|
651
1119
|
}
|
|
652
1120
|
}
|
|
@@ -664,7 +1132,7 @@ class ProductsBuilderService {
|
|
|
664
1132
|
}
|
|
665
1133
|
async updateFallback(tag, data) {
|
|
666
1134
|
try {
|
|
667
|
-
const fallback = this.fetchFallback(tag);
|
|
1135
|
+
const fallback = await this.fetchFallback(tag);
|
|
668
1136
|
if (fallback) {
|
|
669
1137
|
await validators_1.UpdateProductFallbackSchema.validateAsync(data);
|
|
670
1138
|
if (data.options) {
|
|
@@ -689,7 +1157,10 @@ class ProductsBuilderService {
|
|
|
689
1157
|
if (!action) {
|
|
690
1158
|
throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
|
|
691
1159
|
}
|
|
692
|
-
if (action.headers.data.length > 0 ||
|
|
1160
|
+
if (action.headers.data.length > 0 ||
|
|
1161
|
+
action.body.data.length > 0 ||
|
|
1162
|
+
action.params.data.length > 0 ||
|
|
1163
|
+
action.query.data.length > 0) {
|
|
693
1164
|
throw new Error('Healthcheck action is expected to have no headers, body, params or query');
|
|
694
1165
|
}
|
|
695
1166
|
}
|
|
@@ -709,19 +1180,36 @@ class ProductsBuilderService {
|
|
|
709
1180
|
throw e;
|
|
710
1181
|
}
|
|
711
1182
|
}
|
|
712
|
-
|
|
713
|
-
|
|
1183
|
+
async fetchFallbacks(version) {
|
|
1184
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'fallback', this.getUserAccess());
|
|
1185
|
+
return components;
|
|
1186
|
+
}
|
|
1187
|
+
async fetchFallback(tag, version) {
|
|
1188
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'fallback', tag, this.getUserAccess());
|
|
1189
|
+
return component;
|
|
714
1190
|
}
|
|
715
|
-
|
|
716
|
-
|
|
1191
|
+
async deleteFallback(tag) {
|
|
1192
|
+
try {
|
|
1193
|
+
const fallback = await this.fetchFallback(tag);
|
|
1194
|
+
if (!fallback) {
|
|
1195
|
+
throw new Error(`Fallback with tag: ${tag} not found`);
|
|
1196
|
+
}
|
|
1197
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
1198
|
+
tag,
|
|
1199
|
+
component: enums_1.ProductComponents.FALLBACK,
|
|
1200
|
+
action: enums_1.RequestAction.DELETE,
|
|
1201
|
+
}, this.getUserAccess());
|
|
1202
|
+
}
|
|
1203
|
+
catch (e) {
|
|
1204
|
+
throw e;
|
|
1205
|
+
}
|
|
717
1206
|
}
|
|
718
1207
|
async createEnv(data, throwErrorIfExists = false) {
|
|
719
1208
|
try {
|
|
720
1209
|
// TODO: figure out a way to check if this has run before, halt if it has
|
|
721
|
-
if (!this.fetchEnv(data.slug)) {
|
|
1210
|
+
if (!(await this.fetchEnv(data.slug))) {
|
|
722
1211
|
await validators_1.CreateProductEnvSchema.validateAsync(data);
|
|
723
1212
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.ENV, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
724
|
-
await this.initializeProduct(this.product_id);
|
|
725
1213
|
}
|
|
726
1214
|
else {
|
|
727
1215
|
if (throwErrorIfExists)
|
|
@@ -734,144 +1222,291 @@ class ProductsBuilderService {
|
|
|
734
1222
|
}
|
|
735
1223
|
async updateEnv(slug, data) {
|
|
736
1224
|
try {
|
|
737
|
-
const env = this.fetchEnv(slug
|
|
1225
|
+
const env = await this.fetchEnv(slug);
|
|
738
1226
|
if (!env) {
|
|
739
1227
|
throw new Error(`Env ${slug} not found`);
|
|
740
1228
|
}
|
|
741
1229
|
const { _id } = env;
|
|
742
1230
|
await validators_1.UpdateProductEnvSchema.validateAsync(data); // Change to update;
|
|
743
|
-
if (data.slug && this.fetchEnv(data.slug)) {
|
|
1231
|
+
if (data.slug && (await this.fetchEnv(data.slug))) {
|
|
744
1232
|
throw new Error(`slug ${slug} is in use`); // TODO: also check on the backend
|
|
745
1233
|
}
|
|
746
1234
|
if (!data.slug) {
|
|
747
1235
|
data.slug = slug;
|
|
748
1236
|
}
|
|
749
1237
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, Object.assign(Object.assign({}, env), data)), { component: enums_1.ProductComponents.ENV, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
750
|
-
await this.initializeProduct(this.product_id);
|
|
751
1238
|
}
|
|
752
1239
|
catch (e) {
|
|
753
1240
|
throw e;
|
|
754
1241
|
}
|
|
755
1242
|
}
|
|
756
|
-
fetchEnvs() {
|
|
757
|
-
|
|
1243
|
+
async fetchEnvs(version) {
|
|
1244
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'env', this.getUserAccess());
|
|
1245
|
+
return components;
|
|
758
1246
|
}
|
|
759
|
-
fetchEnv(slug
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
1247
|
+
async fetchEnv(slug) {
|
|
1248
|
+
if (this.product_id && this.envCache.has(slug)) {
|
|
1249
|
+
return this.envCache.get(slug);
|
|
1250
|
+
}
|
|
1251
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'env', slug, this.getUserAccess());
|
|
1252
|
+
const out = component;
|
|
1253
|
+
if (this.product_id)
|
|
1254
|
+
this.envCache.set(slug, out);
|
|
1255
|
+
return out;
|
|
1256
|
+
}
|
|
1257
|
+
async deleteEnv(slug) {
|
|
1258
|
+
try {
|
|
1259
|
+
const env = await this.fetchEnv(slug);
|
|
1260
|
+
if (!env) {
|
|
1261
|
+
throw new Error(`Environment with slug: ${slug} not found`);
|
|
1262
|
+
}
|
|
1263
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
1264
|
+
slug,
|
|
1265
|
+
component: enums_1.ProductComponents.ENV,
|
|
1266
|
+
action: enums_1.RequestAction.DELETE,
|
|
1267
|
+
}, this.getUserAccess());
|
|
1268
|
+
}
|
|
1269
|
+
catch (e) {
|
|
1270
|
+
throw e;
|
|
1271
|
+
}
|
|
764
1272
|
}
|
|
765
1273
|
async createMessageBroker(data, throwErrorIfExists = false) {
|
|
766
|
-
|
|
1274
|
+
var _a;
|
|
1275
|
+
const logPrefix = '[MessageBroker:Create]';
|
|
1276
|
+
console.log(`${logPrefix} Starting creation for broker: ${data.tag}`);
|
|
1277
|
+
console.log(`${logPrefix} Broker name: ${data.name}`);
|
|
1278
|
+
console.log(`${logPrefix} Broker description: ${data.description || 'N/A'}`);
|
|
1279
|
+
console.log(`${logPrefix} Number of environments: ${((_a = data.envs) === null || _a === void 0 ? void 0 : _a.length) || 0}`);
|
|
1280
|
+
const existingBroker = await this.fetchMessageBroker(data.tag);
|
|
1281
|
+
if (!existingBroker) {
|
|
1282
|
+
console.log(`${logPrefix} Broker ${data.tag} does not exist, proceeding with creation`);
|
|
1283
|
+
console.log(`${logPrefix} Validating schema...`);
|
|
767
1284
|
await validators_1.CreateMessageBrokerSchema.validateAsync(data);
|
|
768
|
-
|
|
769
|
-
|
|
1285
|
+
console.log(`${logPrefix} Schema validation passed`);
|
|
1286
|
+
const processedEnvs = [];
|
|
1287
|
+
for (const env of data.envs) {
|
|
1288
|
+
console.log(`${logPrefix} Processing env: ${env.slug} (type: ${env.type})`);
|
|
1289
|
+
const exists = await this.fetchEnv(env.slug);
|
|
770
1290
|
if (!exists) {
|
|
1291
|
+
console.error(`${logPrefix} Env ${env.slug} does not exist`);
|
|
771
1292
|
throw new Error(`Env ${env.slug} does not exist`);
|
|
772
1293
|
}
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
1294
|
+
console.log(`${logPrefix} Env ${env.slug} exists, verified`);
|
|
1295
|
+
// Store sensitive credentials as secrets
|
|
1296
|
+
console.log(`${logPrefix} Processing secrets for env: ${env.slug}...`);
|
|
1297
|
+
env.config = await this.processMessageBrokerConfigSecrets(env.config, env.type, data.tag, env.slug);
|
|
1298
|
+
console.log(`${logPrefix} Secrets processed for env: ${env.slug}`);
|
|
1299
|
+
console.log(`${logPrefix} Encrypting config for env: ${env.slug}...`);
|
|
1300
|
+
env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
|
|
1301
|
+
console.log(`${logPrefix} Config encrypted for env: ${env.slug}`);
|
|
1302
|
+
processedEnvs.push(env);
|
|
1303
|
+
}
|
|
1304
|
+
data.envs = processedEnvs;
|
|
1305
|
+
console.log(`${logPrefix} All environments processed: ${processedEnvs.length}`);
|
|
1306
|
+
const envs = await this.fetchEnvs();
|
|
1307
|
+
console.log(`${logPrefix} Product has ${envs.length} environments defined`);
|
|
1308
|
+
for (const env of envs) {
|
|
778
1309
|
const exists = data.envs.findIndex((dbEnv) => dbEnv.slug === env.slug);
|
|
779
1310
|
if (exists === -1) {
|
|
1311
|
+
console.error(`${logPrefix} Product env ${env.slug} is not defined in broker config`);
|
|
780
1312
|
throw new Error(`Product env ${env.slug} is not defined, please provide connection details`);
|
|
781
1313
|
}
|
|
782
|
-
}
|
|
1314
|
+
}
|
|
1315
|
+
console.log(`${logPrefix} All product environments have broker configs`);
|
|
1316
|
+
console.log(`${logPrefix} Sending create request to API...`);
|
|
783
1317
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.MESSAGEBROKER, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
784
|
-
|
|
1318
|
+
console.log(`${logPrefix} Message broker ${data.tag} created successfully`);
|
|
785
1319
|
}
|
|
786
1320
|
else {
|
|
1321
|
+
console.log(`${logPrefix} Broker ${data.tag} already exists`);
|
|
787
1322
|
if (throwErrorIfExists)
|
|
788
1323
|
throw new Error(`Message Broker ${data.tag} already exists`);
|
|
789
1324
|
}
|
|
790
1325
|
}
|
|
791
1326
|
async updateMessageBroker(tag, data) {
|
|
1327
|
+
var _a, _b;
|
|
1328
|
+
const logPrefix = '[MessageBroker:Update]';
|
|
1329
|
+
console.log(`${logPrefix} Starting update for broker: ${tag}`);
|
|
1330
|
+
console.log(`${logPrefix} New tag (if changed): ${data.tag || 'unchanged'}`);
|
|
1331
|
+
console.log(`${logPrefix} New name: ${data.name || 'unchanged'}`);
|
|
1332
|
+
console.log(`${logPrefix} Number of environments in update: ${((_a = data.envs) === null || _a === void 0 ? void 0 : _a.length) || 0}`);
|
|
792
1333
|
try {
|
|
793
|
-
|
|
1334
|
+
console.log(`${logPrefix} Fetching existing broker: ${tag}`);
|
|
1335
|
+
const messageBroker = await this.fetchMessageBroker(tag);
|
|
794
1336
|
if (!messageBroker) {
|
|
1337
|
+
console.error(`${logPrefix} Broker ${tag} not found`);
|
|
795
1338
|
throw new Error(`Broker ${tag} not found`);
|
|
796
1339
|
}
|
|
1340
|
+
console.log(`${logPrefix} Existing broker found with ${((_b = messageBroker.envs) === null || _b === void 0 ? void 0 : _b.length) || 0} environments`);
|
|
797
1341
|
const { _id, envs } = messageBroker;
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
1342
|
+
console.log(`${logPrefix} Broker ID: ${_id}`);
|
|
1343
|
+
console.log(`${logPrefix} Validating update schema...`);
|
|
1344
|
+
await validators_1.UpdateMessageBrokerSchema.validateAsync(data);
|
|
1345
|
+
console.log(`${logPrefix} Schema validation passed`);
|
|
1346
|
+
if (data.tag && (await this.fetchMessageBroker(data.tag))) {
|
|
1347
|
+
console.error(`${logPrefix} Tag ${data.tag} is already in use`);
|
|
1348
|
+
throw new Error(`tag ${tag} is in use`);
|
|
1349
|
+
}
|
|
1350
|
+
const processedEnvs = [];
|
|
1351
|
+
for (const env of data.envs) {
|
|
1352
|
+
console.log(`${logPrefix} Processing env: ${env.slug} (type: ${env.type})`);
|
|
1353
|
+
const exists = await this.fetchEnv(env.slug);
|
|
805
1354
|
if (!exists) {
|
|
1355
|
+
console.error(`${logPrefix} Env ${env.slug} does not exist`);
|
|
806
1356
|
throw new Error(`Env ${env.slug} does not exist`);
|
|
807
1357
|
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
1358
|
+
console.log(`${logPrefix} Env ${env.slug} exists, verified`);
|
|
1359
|
+
if (env.config) {
|
|
1360
|
+
// Store sensitive credentials as secrets
|
|
1361
|
+
console.log(`${logPrefix} Processing secrets for env: ${env.slug}...`);
|
|
1362
|
+
env.config = await this.processMessageBrokerConfigSecrets(env.config, env.type, data.tag || tag, env.slug);
|
|
1363
|
+
console.log(`${logPrefix} Secrets processed for env: ${env.slug}`);
|
|
1364
|
+
console.log(`${logPrefix} Encrypting config for env: ${env.slug}...`);
|
|
1365
|
+
env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
|
|
1366
|
+
console.log(`${logPrefix} Config encrypted for env: ${env.slug}`);
|
|
1367
|
+
}
|
|
1368
|
+
else {
|
|
1369
|
+
console.log(`${logPrefix} No config provided for env: ${env.slug}, skipping secrets processing`);
|
|
1370
|
+
}
|
|
1371
|
+
processedEnvs.push(env);
|
|
1372
|
+
}
|
|
1373
|
+
data.envs = processedEnvs;
|
|
1374
|
+
console.log(`${logPrefix} All environments processed: ${processedEnvs.length}`);
|
|
812
1375
|
const overwrite = [];
|
|
813
1376
|
const newEnvs = [];
|
|
814
|
-
data.envs
|
|
1377
|
+
for (const dataEnv of data.envs) {
|
|
815
1378
|
const exists = envs.findIndex((env) => env.slug === dataEnv.slug);
|
|
816
|
-
if (!this.fetchEnv(dataEnv.slug)) {
|
|
1379
|
+
if (!(await this.fetchEnv(dataEnv.slug))) {
|
|
1380
|
+
console.error(`${logPrefix} Product Environment ${dataEnv.slug} doesn't exist`);
|
|
817
1381
|
throw new Error(`Product Environment ${dataEnv.slug} doesn't exist`);
|
|
818
1382
|
}
|
|
819
1383
|
if (exists === -1) {
|
|
1384
|
+
console.log(`${logPrefix} Env ${dataEnv.slug} is a NEW environment`);
|
|
820
1385
|
if (!dataEnv.config) {
|
|
1386
|
+
console.error(`${logPrefix} Config is required for new env ${dataEnv.slug}`);
|
|
821
1387
|
throw new Error(`config is required for new env ${data.envs[exists].slug}`);
|
|
822
1388
|
}
|
|
823
1389
|
newEnvs.push(dataEnv);
|
|
824
1390
|
}
|
|
825
1391
|
else {
|
|
1392
|
+
console.log(`${logPrefix} Env ${dataEnv.slug} will OVERWRITE existing config`);
|
|
826
1393
|
if (envs[exists].config) {
|
|
827
|
-
envs[exists].config = (0, processor_utils_1.encrypt)(JSON.stringify(envs[exists].config), this.
|
|
1394
|
+
envs[exists].config = (0, processor_utils_1.encrypt)(JSON.stringify(envs[exists].config), this.product.private_key);
|
|
828
1395
|
}
|
|
829
1396
|
overwrite.push(Object.assign(Object.assign({}, envs[exists]), dataEnv));
|
|
830
1397
|
}
|
|
831
|
-
}
|
|
1398
|
+
}
|
|
832
1399
|
const unchanged = [];
|
|
833
|
-
|
|
1400
|
+
for (const env of envs) {
|
|
834
1401
|
const newEnv = newEnvs.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
835
1402
|
const overwriteEnv = overwrite.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
836
1403
|
if (!newEnv && !overwriteEnv) {
|
|
1404
|
+
console.log(`${logPrefix} Env ${env.slug} is UNCHANGED`);
|
|
837
1405
|
if (env.config) {
|
|
838
|
-
env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.
|
|
1406
|
+
env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
|
|
839
1407
|
}
|
|
840
1408
|
unchanged.push(env);
|
|
841
1409
|
}
|
|
842
|
-
}
|
|
1410
|
+
}
|
|
843
1411
|
data.envs = [...unchanged, ...overwrite, ...newEnvs];
|
|
1412
|
+
console.log(`${logPrefix} Final env breakdown - Unchanged: ${unchanged.length}, Overwrite: ${overwrite.length}, New: ${newEnvs.length}`);
|
|
1413
|
+
console.log(`${logPrefix} Sending update request to API...`);
|
|
844
1414
|
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());
|
|
845
|
-
|
|
1415
|
+
console.log(`${logPrefix} Message broker ${tag} updated successfully`);
|
|
846
1416
|
}
|
|
847
1417
|
catch (e) {
|
|
1418
|
+
console.error(`${logPrefix} Update failed:`, e);
|
|
848
1419
|
throw e;
|
|
849
1420
|
}
|
|
850
1421
|
}
|
|
851
|
-
|
|
852
|
-
const
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1422
|
+
async fetchMessageBrokers(version) {
|
|
1423
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'message_broker', this.getUserAccess());
|
|
1424
|
+
return components;
|
|
1425
|
+
}
|
|
1426
|
+
async fetchMessageBroker(tag, version) {
|
|
1427
|
+
var _a, _b;
|
|
1428
|
+
if (this.product_id && this.brokerCache.has(tag)) {
|
|
1429
|
+
return this.brokerCache.get(tag);
|
|
1430
|
+
}
|
|
1431
|
+
this._debugLog(`[ProductsBuilderService] fetchMessageBroker() called with tag: ${tag}`);
|
|
1432
|
+
this._debugLog(`[ProductsBuilderService] product_id: ${this.product_id}`);
|
|
1433
|
+
this._debugLog(`[ProductsBuilderService] has product: ${!!this.product}`);
|
|
1434
|
+
this._debugLog(`[ProductsBuilderService] product.messageBrokers count: ${((_b = (_a = this.product) === null || _a === void 0 ? void 0 : _a.messageBrokers) === null || _b === void 0 ? void 0 : _b.length) || 0}`);
|
|
1435
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'message_broker', tag, this.getUserAccess());
|
|
1436
|
+
this._debugLog(`[ProductsBuilderService] fetchProductComponentByTag result:`, component ? `found (tag=${component.tag})` : 'null');
|
|
1437
|
+
let result = null;
|
|
1438
|
+
if (component) {
|
|
1439
|
+
// Ensure envs array exists before mapping
|
|
1440
|
+
const envs = component.envs || [];
|
|
1441
|
+
this._debugLog(`[ProductsBuilderService] component.envs count: ${envs.length}`);
|
|
1442
|
+
const decryptedEnvs = envs.map((env) => {
|
|
1443
|
+
return Object.assign(Object.assign({}, env), { config: env.config ? JSON.parse((0, processor_utils_1.decrypt)(env.config, this.product.private_key)) : {} });
|
|
860
1444
|
});
|
|
1445
|
+
this._debugLog(`[ProductsBuilderService] Decrypted ${decryptedEnvs.length} environments`);
|
|
1446
|
+
result = Object.assign(Object.assign({}, component), { envs: decryptedEnvs });
|
|
1447
|
+
}
|
|
1448
|
+
else {
|
|
1449
|
+
this._debugLog(`[ProductsBuilderService] Returning null - component not found`);
|
|
861
1450
|
}
|
|
862
|
-
|
|
1451
|
+
if (this.product_id)
|
|
1452
|
+
this.brokerCache.set(tag, result);
|
|
1453
|
+
return result;
|
|
863
1454
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
1455
|
+
async deleteMessageBroker(tag) {
|
|
1456
|
+
try {
|
|
1457
|
+
const messageBroker = await this.fetchMessageBroker(tag);
|
|
1458
|
+
if (!messageBroker) {
|
|
1459
|
+
throw new Error(`Message broker with tag: ${tag} not found`);
|
|
1460
|
+
}
|
|
1461
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
1462
|
+
tag,
|
|
1463
|
+
component: enums_1.ProductComponents.MESSAGEBROKER,
|
|
1464
|
+
action: enums_1.RequestAction.DELETE,
|
|
1465
|
+
}, this.getUserAccess());
|
|
1466
|
+
}
|
|
1467
|
+
catch (e) {
|
|
1468
|
+
throw e;
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
async fetchStorageFiles(filter) {
|
|
1472
|
+
try {
|
|
1473
|
+
const result = await this.productApi.fetchProductStorageFiles(Object.assign(Object.assign({}, filter), { product: this.product.tag }), this.getUserAccess());
|
|
1474
|
+
if (!result)
|
|
1475
|
+
return [];
|
|
1476
|
+
return result.map((res) => {
|
|
1477
|
+
delete res._id;
|
|
1478
|
+
delete res.workspace_id;
|
|
1479
|
+
delete res.__v;
|
|
1480
|
+
res.url = (0, processor_utils_1.decrypt)(res.url, this.product.private_key);
|
|
1481
|
+
return res;
|
|
1482
|
+
});
|
|
1483
|
+
}
|
|
1484
|
+
catch (e) {
|
|
1485
|
+
throw e;
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
async fetchSessionUsers(filter) {
|
|
1489
|
+
try {
|
|
1490
|
+
const result = await this.productApi.fetchProductSessionUsers(Object.assign(Object.assign({}, filter), { product: this.product.tag }), this.getUserAccess());
|
|
1491
|
+
if (!result)
|
|
1492
|
+
return [];
|
|
1493
|
+
return result.map((res) => {
|
|
1494
|
+
delete res._id;
|
|
1495
|
+
delete res.workspace_id;
|
|
1496
|
+
delete res.__v;
|
|
1497
|
+
return res;
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
catch (e) {
|
|
1501
|
+
throw e;
|
|
1502
|
+
}
|
|
869
1503
|
}
|
|
870
1504
|
async createStorage(data, throwErrorIfExists = false) {
|
|
871
|
-
if (!this.fetchStorage(data.tag
|
|
1505
|
+
if (!(await this.fetchStorage(data.tag))) {
|
|
872
1506
|
await create_productStorage_validator_1.CreateProductStorageSchema.validateAsync(data);
|
|
873
|
-
|
|
874
|
-
|
|
1507
|
+
const processedEnvs = [];
|
|
1508
|
+
for (const env of data.envs) {
|
|
1509
|
+
const exists = await this.fetchEnv(env.slug);
|
|
875
1510
|
if (!exists) {
|
|
876
1511
|
throw new Error(`Env ${env.slug} does not exist`);
|
|
877
1512
|
}
|
|
@@ -879,18 +1514,20 @@ class ProductsBuilderService {
|
|
|
879
1514
|
// @ts-ignore
|
|
880
1515
|
//env.config.config.private_key = gcpPKCSConvert(env.config.config.private_key)
|
|
881
1516
|
}
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
1517
|
+
// Store sensitive credentials as secrets
|
|
1518
|
+
env.config = await this.processStorageConfigSecrets(env.config, env.type, data.tag, env.slug);
|
|
1519
|
+
env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
|
|
1520
|
+
processedEnvs.push(env);
|
|
1521
|
+
}
|
|
1522
|
+
data.envs = processedEnvs;
|
|
1523
|
+
const envs = await this.fetchEnvs();
|
|
1524
|
+
for (const env of envs) {
|
|
887
1525
|
const exists = data.envs.findIndex((dbEnv) => dbEnv.slug === env.slug);
|
|
888
1526
|
if (exists === -1) {
|
|
889
1527
|
throw new Error(`Product env ${env.slug} is not defined, please provide connection details`);
|
|
890
1528
|
}
|
|
891
|
-
}
|
|
1529
|
+
}
|
|
892
1530
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.STORAGE, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
893
|
-
await this.initializeProduct(this.product_id);
|
|
894
1531
|
}
|
|
895
1532
|
else {
|
|
896
1533
|
if (throwErrorIfExists)
|
|
@@ -899,84 +1536,747 @@ class ProductsBuilderService {
|
|
|
899
1536
|
}
|
|
900
1537
|
async updateStorage(tag, data) {
|
|
901
1538
|
try {
|
|
902
|
-
const storage = this.fetchStorage(tag);
|
|
1539
|
+
const storage = await this.fetchStorage(tag);
|
|
903
1540
|
if (!storage) {
|
|
904
1541
|
throw new Error(`Storage ${tag} not found`);
|
|
905
1542
|
}
|
|
906
1543
|
const { _id, envs } = storage;
|
|
907
1544
|
await create_productStorage_validator_1.UpdateProductStorageSchema.validateAsync(data); // Change to update;
|
|
908
|
-
if (data.tag && this.fetchStorage(data.tag)) {
|
|
1545
|
+
if (data.tag && await this.fetchStorage(data.tag)) {
|
|
909
1546
|
throw new Error(`tag ${tag} is in use`); // TODO: also check on the backend
|
|
910
1547
|
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1548
|
+
// Only process envs if they are provided in the update
|
|
1549
|
+
if (data.envs && data.envs.length > 0) {
|
|
1550
|
+
data.envs = await Promise.all(data.envs.map(async (env) => {
|
|
1551
|
+
const exists = await this.fetchEnv(env.slug);
|
|
1552
|
+
if (!exists) {
|
|
1553
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
1554
|
+
}
|
|
1555
|
+
if (env.type === productsBuilder_types_1.StorageProviders.GCP) {
|
|
1556
|
+
// @ts-ignore
|
|
1557
|
+
//env.config.config.private_key = gcpPKCSConvert(env.config.config.private_key)
|
|
1558
|
+
}
|
|
1559
|
+
if (env.config) {
|
|
1560
|
+
// Store sensitive credentials as secrets
|
|
1561
|
+
env.config = await this.processStorageConfigSecrets(env.config, env.type, data.tag || tag, env.slug);
|
|
1562
|
+
env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
|
|
1563
|
+
}
|
|
1564
|
+
return env;
|
|
1565
|
+
}));
|
|
1566
|
+
const overwrite = [];
|
|
1567
|
+
const newEnvs = [];
|
|
1568
|
+
data.envs.map((dataEnv) => {
|
|
1569
|
+
const exists = envs.findIndex((env) => env.slug === dataEnv.slug);
|
|
1570
|
+
if (!this.fetchEnv(dataEnv.slug)) {
|
|
1571
|
+
throw new Error(`Product Environment ${dataEnv.slug} doesn't exist`);
|
|
1572
|
+
}
|
|
1573
|
+
if (exists === -1) {
|
|
1574
|
+
if (!dataEnv.config) {
|
|
1575
|
+
throw new Error(`config is required for new env ${data.envs[exists].slug}`);
|
|
1576
|
+
}
|
|
1577
|
+
newEnvs.push(dataEnv);
|
|
1578
|
+
}
|
|
1579
|
+
else {
|
|
1580
|
+
if (envs[exists].config) {
|
|
1581
|
+
envs[exists].config = (0, processor_utils_1.encrypt)(JSON.stringify(envs[exists].config), this.product.private_key);
|
|
1582
|
+
}
|
|
1583
|
+
overwrite.push(Object.assign(Object.assign({}, envs[exists]), dataEnv));
|
|
1584
|
+
}
|
|
1585
|
+
});
|
|
1586
|
+
const unchanged = [];
|
|
1587
|
+
envs.map((env) => {
|
|
1588
|
+
const newEnv = newEnvs.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
1589
|
+
const overwriteEnv = overwrite.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
1590
|
+
if (!newEnv && !overwriteEnv) {
|
|
1591
|
+
if (env.config) {
|
|
1592
|
+
env.config = (0, processor_utils_1.encrypt)(JSON.stringify(env.config), this.product.private_key);
|
|
1593
|
+
}
|
|
1594
|
+
unchanged.push(env);
|
|
1595
|
+
}
|
|
1596
|
+
});
|
|
1597
|
+
data.envs = [...unchanged, ...overwrite, ...newEnvs];
|
|
1598
|
+
}
|
|
1599
|
+
// Build the update payload - only send fields that are being updated
|
|
1600
|
+
// Remove fields that shouldn't be in the update request
|
|
1601
|
+
const { envs: dataEnvs } = data, dataWithoutEnvs = __rest(data, ["envs"]);
|
|
1602
|
+
// Only include envs if they were explicitly provided and processed
|
|
1603
|
+
// Don't spread ...storage - only send the fields being updated
|
|
1604
|
+
const updatePayload = Object.assign(Object.assign(Object.assign({ _id }, storage), { tag }), dataWithoutEnvs);
|
|
1605
|
+
// Add processed envs only if they were provided in the update
|
|
1606
|
+
if (data.envs && data.envs.length > 0) {
|
|
1607
|
+
updatePayload.envs = data.envs;
|
|
1608
|
+
}
|
|
1609
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, updatePayload), { component: enums_1.ProductComponents.STORAGE, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
1610
|
+
}
|
|
1611
|
+
catch (e) {
|
|
1612
|
+
throw e;
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
async fetchStorages(version) {
|
|
1616
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'storage', this.getUserAccess());
|
|
1617
|
+
return components;
|
|
1618
|
+
}
|
|
1619
|
+
async fetchStorage(tag, version) {
|
|
1620
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'storage', tag, this.getUserAccess());
|
|
1621
|
+
if (component) {
|
|
1622
|
+
const decryptedEnvs = component.envs.map((env) => {
|
|
1623
|
+
return Object.assign(Object.assign({}, env), { config: JSON.parse((0, processor_utils_1.decrypt)(env.config, this.product.private_key)) });
|
|
923
1624
|
});
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1625
|
+
return Object.assign(Object.assign({}, component), { envs: decryptedEnvs });
|
|
1626
|
+
}
|
|
1627
|
+
return component;
|
|
1628
|
+
}
|
|
1629
|
+
async deleteStorage(tag) {
|
|
1630
|
+
try {
|
|
1631
|
+
const storage = await this.fetchStorage(tag);
|
|
1632
|
+
if (!storage) {
|
|
1633
|
+
throw new Error(`Storage with tag: ${tag} not found`);
|
|
1634
|
+
}
|
|
1635
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
1636
|
+
tag,
|
|
1637
|
+
component: enums_1.ProductComponents.STORAGE,
|
|
1638
|
+
action: enums_1.RequestAction.DELETE,
|
|
1639
|
+
}, this.getUserAccess());
|
|
1640
|
+
}
|
|
1641
|
+
catch (e) {
|
|
1642
|
+
throw e;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
// ==================== VECTOR DATABASE METHODS ====================
|
|
1646
|
+
/**
|
|
1647
|
+
* Create a new vector database configuration
|
|
1648
|
+
* @param data Vector database configuration
|
|
1649
|
+
* @param throwErrorIfExists Whether to throw error if vector config already exists
|
|
1650
|
+
*/
|
|
1651
|
+
async createVector(data, throwErrorIfExists = false) {
|
|
1652
|
+
var _a, _b, _c, _d;
|
|
1653
|
+
console.log('[ProductsService.createVector] Starting vector creation:', {
|
|
1654
|
+
tag: data.tag,
|
|
1655
|
+
name: data.name,
|
|
1656
|
+
type: data.type,
|
|
1657
|
+
envsCount: (_a = data.envs) === null || _a === void 0 ? void 0 : _a.length,
|
|
1658
|
+
productTag: (_b = this.product) === null || _b === void 0 ? void 0 : _b.tag,
|
|
1659
|
+
});
|
|
1660
|
+
if (!(await this.fetchVector(data.tag))) {
|
|
1661
|
+
await validators_1.CreateProductVectorSchema.validateAsync(data);
|
|
1662
|
+
const processedEnvs = [];
|
|
1663
|
+
for (const env of data.envs) {
|
|
1664
|
+
console.log('[ProductsService.createVector] Processing env:', {
|
|
1665
|
+
slug: env.slug,
|
|
1666
|
+
hasApiKey: !!env.apiKey,
|
|
1667
|
+
hasEndpoint: !!env.endpoint,
|
|
1668
|
+
});
|
|
1669
|
+
const exists = await this.fetchEnv(env.slug);
|
|
1670
|
+
if (!exists) {
|
|
1671
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
930
1672
|
}
|
|
1673
|
+
// Store API key as secret and encrypt
|
|
1674
|
+
if (env.apiKey) {
|
|
1675
|
+
console.log('[ProductsService.createVector] Converting API key to secret for env:', env.slug);
|
|
1676
|
+
const originalApiKey = env.apiKey;
|
|
1677
|
+
env.apiKey = await this.storeVectorApiKeyAsSecret(env.apiKey, data.tag, env.slug);
|
|
1678
|
+
console.log('[ProductsService.createVector] API key after secret conversion:', {
|
|
1679
|
+
wasConverted: originalApiKey !== env.apiKey,
|
|
1680
|
+
isSecretRef: (_c = env.apiKey) === null || _c === void 0 ? void 0 : _c.startsWith('$Secret{'),
|
|
1681
|
+
});
|
|
1682
|
+
env.apiKey = (0, processor_utils_1.encrypt)(env.apiKey, this.product.private_key);
|
|
1683
|
+
console.log('[ProductsService.createVector] API key encrypted');
|
|
1684
|
+
}
|
|
1685
|
+
// Store endpoint as secret and encrypt
|
|
1686
|
+
if (env.endpoint) {
|
|
1687
|
+
console.log('[ProductsService.createVector] Converting endpoint to secret for env:', env.slug);
|
|
1688
|
+
const originalEndpoint = env.endpoint;
|
|
1689
|
+
env.endpoint = await this.storeVectorEndpointAsSecret(env.endpoint, data.tag, env.slug);
|
|
1690
|
+
console.log('[ProductsService.createVector] Endpoint after secret conversion:', {
|
|
1691
|
+
wasConverted: originalEndpoint !== env.endpoint,
|
|
1692
|
+
isSecretRef: (_d = env.endpoint) === null || _d === void 0 ? void 0 : _d.startsWith('$Secret{'),
|
|
1693
|
+
});
|
|
1694
|
+
env.endpoint = (0, processor_utils_1.encrypt)(env.endpoint, this.product.private_key);
|
|
1695
|
+
console.log('[ProductsService.createVector] Endpoint encrypted');
|
|
1696
|
+
}
|
|
1697
|
+
processedEnvs.push(env);
|
|
1698
|
+
console.log('[ProductsService.createVector] Env processed successfully:', env.slug);
|
|
1699
|
+
}
|
|
1700
|
+
data.envs = processedEnvs;
|
|
1701
|
+
console.log('[ProductsService.createVector] All envs processed, total:', processedEnvs.length);
|
|
1702
|
+
const envs = await this.fetchEnvs();
|
|
1703
|
+
for (const env of envs) {
|
|
1704
|
+
const exists = data.envs.findIndex((vecEnv) => vecEnv.slug === env.slug);
|
|
931
1705
|
if (exists === -1) {
|
|
932
|
-
|
|
933
|
-
|
|
1706
|
+
throw new Error(`Product env ${env.slug} is not defined, please provide connection details`);
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.VECTOR, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
1710
|
+
}
|
|
1711
|
+
else {
|
|
1712
|
+
if (throwErrorIfExists)
|
|
1713
|
+
throw new Error(`Vector ${data.tag} already exists`);
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
/**
|
|
1717
|
+
* Update an existing vector database configuration
|
|
1718
|
+
* @param tag Vector config tag
|
|
1719
|
+
* @param data Updated vector configuration
|
|
1720
|
+
*/
|
|
1721
|
+
async updateVector(tag, data) {
|
|
1722
|
+
var _a, _b;
|
|
1723
|
+
console.log('[ProductsService.updateVector] Starting vector update:', {
|
|
1724
|
+
tag,
|
|
1725
|
+
newTag: data.tag,
|
|
1726
|
+
name: data.name,
|
|
1727
|
+
envsCount: (_a = data.envs) === null || _a === void 0 ? void 0 : _a.length,
|
|
1728
|
+
productTag: (_b = this.product) === null || _b === void 0 ? void 0 : _b.tag,
|
|
1729
|
+
});
|
|
1730
|
+
try {
|
|
1731
|
+
const vector = await this.fetchVector(tag);
|
|
1732
|
+
if (!vector) {
|
|
1733
|
+
throw new Error(`Vector ${tag} not found`);
|
|
1734
|
+
}
|
|
1735
|
+
const { _id, envs } = vector;
|
|
1736
|
+
console.log('[ProductsService.updateVector] Found existing vector:', {
|
|
1737
|
+
_id,
|
|
1738
|
+
existingEnvsCount: envs === null || envs === void 0 ? void 0 : envs.length,
|
|
1739
|
+
});
|
|
1740
|
+
await validators_1.UpdateProductVectorSchema.validateAsync(data);
|
|
1741
|
+
if (data.tag && (await this.fetchVector(data.tag))) {
|
|
1742
|
+
throw new Error(`tag ${data.tag} is in use`);
|
|
1743
|
+
}
|
|
1744
|
+
if (data.envs) {
|
|
1745
|
+
console.log('[ProductsService.updateVector] Processing envs update');
|
|
1746
|
+
data.envs = await Promise.all(data.envs.map(async (env) => {
|
|
1747
|
+
var _a, _b;
|
|
1748
|
+
console.log('[ProductsService.updateVector] Processing env:', {
|
|
1749
|
+
slug: env.slug,
|
|
1750
|
+
hasApiKey: !!env.apiKey,
|
|
1751
|
+
hasEndpoint: !!env.endpoint,
|
|
1752
|
+
});
|
|
1753
|
+
const exists = await this.fetchEnv(env.slug);
|
|
1754
|
+
if (!exists) {
|
|
1755
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
1756
|
+
}
|
|
1757
|
+
// Store API key as secret and encrypt
|
|
1758
|
+
if (env.apiKey) {
|
|
1759
|
+
console.log('[ProductsService.updateVector] Converting API key to secret for env:', env.slug);
|
|
1760
|
+
const originalApiKey = env.apiKey;
|
|
1761
|
+
env.apiKey = await this.storeVectorApiKeyAsSecret(env.apiKey, data.tag || tag, env.slug);
|
|
1762
|
+
console.log('[ProductsService.updateVector] API key after secret conversion:', {
|
|
1763
|
+
wasConverted: originalApiKey !== env.apiKey,
|
|
1764
|
+
isSecretRef: (_a = env.apiKey) === null || _a === void 0 ? void 0 : _a.startsWith('$Secret{'),
|
|
1765
|
+
});
|
|
1766
|
+
env.apiKey = (0, processor_utils_1.encrypt)(env.apiKey, this.product.private_key);
|
|
1767
|
+
console.log('[ProductsService.updateVector] API key encrypted');
|
|
1768
|
+
}
|
|
1769
|
+
// Store endpoint as secret and encrypt
|
|
1770
|
+
if (env.endpoint) {
|
|
1771
|
+
console.log('[ProductsService.updateVector] Converting endpoint to secret for env:', env.slug);
|
|
1772
|
+
const originalEndpoint = env.endpoint;
|
|
1773
|
+
env.endpoint = await this.storeVectorEndpointAsSecret(env.endpoint, data.tag || tag, env.slug);
|
|
1774
|
+
console.log('[ProductsService.updateVector] Endpoint after secret conversion:', {
|
|
1775
|
+
wasConverted: originalEndpoint !== env.endpoint,
|
|
1776
|
+
isSecretRef: (_b = env.endpoint) === null || _b === void 0 ? void 0 : _b.startsWith('$Secret{'),
|
|
1777
|
+
});
|
|
1778
|
+
env.endpoint = (0, processor_utils_1.encrypt)(env.endpoint, this.product.private_key);
|
|
1779
|
+
console.log('[ProductsService.updateVector] Endpoint encrypted');
|
|
1780
|
+
}
|
|
1781
|
+
console.log('[ProductsService.updateVector] Env processed successfully:', env.slug);
|
|
1782
|
+
return env;
|
|
1783
|
+
}));
|
|
1784
|
+
const overwrite = [];
|
|
1785
|
+
const newEnvs = [];
|
|
1786
|
+
data.envs.forEach((dataEnv) => {
|
|
1787
|
+
const existsIdx = envs.findIndex((env) => env.slug === dataEnv.slug);
|
|
1788
|
+
if (existsIdx === -1) {
|
|
1789
|
+
newEnvs.push(dataEnv);
|
|
1790
|
+
}
|
|
1791
|
+
else {
|
|
1792
|
+
overwrite.push(Object.assign(Object.assign({}, envs[existsIdx]), dataEnv));
|
|
1793
|
+
}
|
|
1794
|
+
});
|
|
1795
|
+
const unchanged = [];
|
|
1796
|
+
envs.forEach((env) => {
|
|
1797
|
+
const newEnv = newEnvs.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
1798
|
+
const overwriteEnv = overwrite.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
1799
|
+
if (!newEnv && !overwriteEnv) {
|
|
1800
|
+
unchanged.push(env);
|
|
1801
|
+
}
|
|
1802
|
+
});
|
|
1803
|
+
data.envs = [...unchanged, ...overwrite, ...newEnvs];
|
|
1804
|
+
}
|
|
1805
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({ _id }, vector), data), { component: enums_1.ProductComponents.VECTOR, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
1806
|
+
}
|
|
1807
|
+
catch (e) {
|
|
1808
|
+
throw e;
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
/**
|
|
1812
|
+
* Fetch all vector database configurations
|
|
1813
|
+
* @param version Optional version
|
|
1814
|
+
*/
|
|
1815
|
+
async fetchVectors(version) {
|
|
1816
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'vector', this.getUserAccess());
|
|
1817
|
+
// Decrypt sensitive fields in vector envs to reveal $Secret{key} references
|
|
1818
|
+
const decryptedComponents = components.map((vectorComponent) => {
|
|
1819
|
+
var _a;
|
|
1820
|
+
const decryptedEnvs = (_a = vectorComponent.envs) === null || _a === void 0 ? void 0 : _a.map((env) => {
|
|
1821
|
+
return Object.assign(Object.assign({}, env), { apiKey: env.apiKey ? (0, processor_utils_1.decrypt)(env.apiKey, this.product.private_key) : env.apiKey, endpoint: env.endpoint ? (0, processor_utils_1.decrypt)(env.endpoint, this.product.private_key) : env.endpoint });
|
|
1822
|
+
});
|
|
1823
|
+
return Object.assign(Object.assign({}, vectorComponent), { envs: decryptedEnvs });
|
|
1824
|
+
});
|
|
1825
|
+
return decryptedComponents;
|
|
1826
|
+
}
|
|
1827
|
+
/**
|
|
1828
|
+
* Fetch a specific vector database configuration by tag
|
|
1829
|
+
* @param tag Vector config tag
|
|
1830
|
+
* @param version Optional version
|
|
1831
|
+
*/
|
|
1832
|
+
async fetchVector(tag, version) {
|
|
1833
|
+
var _a;
|
|
1834
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'vector', tag, this.getUserAccess());
|
|
1835
|
+
if (component) {
|
|
1836
|
+
// Decrypt sensitive fields in vector envs to reveal $Secret{key} references
|
|
1837
|
+
const decryptedEnvs = (_a = component.envs) === null || _a === void 0 ? void 0 : _a.map((env) => {
|
|
1838
|
+
return Object.assign(Object.assign({}, env), { apiKey: env.apiKey ? (0, processor_utils_1.decrypt)(env.apiKey, this.product.private_key) : env.apiKey, endpoint: env.endpoint ? (0, processor_utils_1.decrypt)(env.endpoint, this.product.private_key) : env.endpoint });
|
|
1839
|
+
});
|
|
1840
|
+
return Object.assign(Object.assign({}, component), { envs: decryptedEnvs });
|
|
1841
|
+
}
|
|
1842
|
+
return component;
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1845
|
+
* Delete a vector database configuration
|
|
1846
|
+
* @param tag Vector config tag
|
|
1847
|
+
*/
|
|
1848
|
+
async deleteVector(tag) {
|
|
1849
|
+
try {
|
|
1850
|
+
const vector = await this.fetchVector(tag);
|
|
1851
|
+
if (!vector) {
|
|
1852
|
+
throw new Error(`Vector with tag: ${tag} not found`);
|
|
1853
|
+
}
|
|
1854
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
1855
|
+
tag,
|
|
1856
|
+
component: enums_1.ProductComponents.VECTOR,
|
|
1857
|
+
action: enums_1.RequestAction.DELETE,
|
|
1858
|
+
}, this.getUserAccess());
|
|
1859
|
+
}
|
|
1860
|
+
catch (e) {
|
|
1861
|
+
throw e;
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
// ==================== VECTOR ACTION METHODS ====================
|
|
1865
|
+
/**
|
|
1866
|
+
* Create a new vector action
|
|
1867
|
+
* @param vectorTag Vector database tag
|
|
1868
|
+
* @param data Vector action data
|
|
1869
|
+
* @returns Created vector action
|
|
1870
|
+
*/
|
|
1871
|
+
async createVectorAction(vectorTag, data) {
|
|
1872
|
+
try {
|
|
1873
|
+
const vector = await this.fetchVector(vectorTag);
|
|
1874
|
+
if (!vector) {
|
|
1875
|
+
throw new Error(`Vector with tag: ${vectorTag} not found`);
|
|
1876
|
+
}
|
|
1877
|
+
if (!data.tag) {
|
|
1878
|
+
throw new Error('Action tag is required');
|
|
1879
|
+
}
|
|
1880
|
+
if (!data.name) {
|
|
1881
|
+
throw new Error('Action name is required');
|
|
1882
|
+
}
|
|
1883
|
+
// Parse the tag to get action-only part (format: vector_tag:action_tag)
|
|
1884
|
+
const tagParts = data.tag.split(':');
|
|
1885
|
+
const actionTag = tagParts.length > 1 ? tagParts[tagParts.length - 1] : data.tag;
|
|
1886
|
+
// Check if action already exists
|
|
1887
|
+
const existingActions = vector.actions || [];
|
|
1888
|
+
const exists = existingActions.find(a => a.tag === data.tag || a.tag === `${vectorTag}:${actionTag}`);
|
|
1889
|
+
if (exists) {
|
|
1890
|
+
throw new Error(`Vector action with tag: ${data.tag} already exists`);
|
|
1891
|
+
}
|
|
1892
|
+
// Build the full action tag
|
|
1893
|
+
const fullTag = data.tag.includes(':') ? data.tag : `${vectorTag}:${actionTag}`;
|
|
1894
|
+
const newAction = {
|
|
1895
|
+
name: data.name,
|
|
1896
|
+
tag: fullTag,
|
|
1897
|
+
description: data.description,
|
|
1898
|
+
type: data.type,
|
|
1899
|
+
template: data.template || { options: {} },
|
|
1900
|
+
parameters: data.parameters || [],
|
|
1901
|
+
created_at: new Date(),
|
|
1902
|
+
updated_at: new Date(),
|
|
1903
|
+
};
|
|
1904
|
+
// Add to vector's actions array
|
|
1905
|
+
const updatedActions = [...existingActions, newAction];
|
|
1906
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
1907
|
+
tag: vectorTag,
|
|
1908
|
+
actions: updatedActions,
|
|
1909
|
+
component: enums_1.ProductComponents.VECTOR,
|
|
1910
|
+
action: enums_1.RequestAction.UPDATE,
|
|
1911
|
+
}, this.getUserAccess());
|
|
1912
|
+
return newAction;
|
|
1913
|
+
}
|
|
1914
|
+
catch (e) {
|
|
1915
|
+
throw e;
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
/**
|
|
1919
|
+
* Update an existing vector action
|
|
1920
|
+
* @param vectorTag Vector database tag
|
|
1921
|
+
* @param data Vector action update data (must include tag)
|
|
1922
|
+
* @returns Updated vector action
|
|
1923
|
+
*/
|
|
1924
|
+
async updateVectorAction(vectorTag, data) {
|
|
1925
|
+
try {
|
|
1926
|
+
const vector = await this.fetchVector(vectorTag);
|
|
1927
|
+
if (!vector) {
|
|
1928
|
+
throw new Error(`Vector with tag: ${vectorTag} not found`);
|
|
1929
|
+
}
|
|
1930
|
+
if (!data.tag) {
|
|
1931
|
+
throw new Error('Action tag is required');
|
|
1932
|
+
}
|
|
1933
|
+
const existingActions = vector.actions || [];
|
|
1934
|
+
const actionIndex = existingActions.findIndex(a => a.tag === data.tag);
|
|
1935
|
+
if (actionIndex === -1) {
|
|
1936
|
+
throw new Error(`Vector action with tag: ${data.tag} not found`);
|
|
1937
|
+
}
|
|
1938
|
+
// Merge with existing action
|
|
1939
|
+
const updatedAction = Object.assign(Object.assign(Object.assign({}, existingActions[actionIndex]), data), { updated_at: new Date() });
|
|
1940
|
+
// Update in the array
|
|
1941
|
+
const updatedActions = [...existingActions];
|
|
1942
|
+
updatedActions[actionIndex] = updatedAction;
|
|
1943
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
1944
|
+
tag: vectorTag,
|
|
1945
|
+
actions: updatedActions,
|
|
1946
|
+
component: enums_1.ProductComponents.VECTOR,
|
|
1947
|
+
action: enums_1.RequestAction.UPDATE,
|
|
1948
|
+
}, this.getUserAccess());
|
|
1949
|
+
return updatedAction;
|
|
1950
|
+
}
|
|
1951
|
+
catch (e) {
|
|
1952
|
+
throw e;
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
/**
|
|
1956
|
+
* Fetch a specific vector action
|
|
1957
|
+
* @param vectorTag Vector database tag
|
|
1958
|
+
* @param actionTag Action tag
|
|
1959
|
+
* @returns Vector action or null
|
|
1960
|
+
*/
|
|
1961
|
+
async fetchVectorAction(vectorTag, actionTag) {
|
|
1962
|
+
try {
|
|
1963
|
+
const vector = await this.fetchVector(vectorTag);
|
|
1964
|
+
if (!vector) {
|
|
1965
|
+
return null;
|
|
1966
|
+
}
|
|
1967
|
+
const actions = vector.actions || [];
|
|
1968
|
+
const action = actions.find(a => a.tag === actionTag || a.tag === `${vectorTag}:${actionTag}`);
|
|
1969
|
+
return action || null;
|
|
1970
|
+
}
|
|
1971
|
+
catch (e) {
|
|
1972
|
+
throw e;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
/**
|
|
1976
|
+
* Fetch all vector actions for a vector database
|
|
1977
|
+
* @param vectorTag Vector database tag
|
|
1978
|
+
* @returns Array of vector actions
|
|
1979
|
+
*/
|
|
1980
|
+
async fetchVectorActions(vectorTag) {
|
|
1981
|
+
try {
|
|
1982
|
+
const vector = await this.fetchVector(vectorTag);
|
|
1983
|
+
if (!vector) {
|
|
1984
|
+
return [];
|
|
1985
|
+
}
|
|
1986
|
+
return vector.actions || [];
|
|
1987
|
+
}
|
|
1988
|
+
catch (e) {
|
|
1989
|
+
throw e;
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
/**
|
|
1993
|
+
* Delete a vector action
|
|
1994
|
+
* @param vectorTag Vector database tag
|
|
1995
|
+
* @param actionTag Action tag to delete
|
|
1996
|
+
*/
|
|
1997
|
+
async deleteVectorAction(vectorTag, actionTag) {
|
|
1998
|
+
try {
|
|
1999
|
+
const vector = await this.fetchVector(vectorTag);
|
|
2000
|
+
if (!vector) {
|
|
2001
|
+
throw new Error(`Vector with tag: ${vectorTag} not found`);
|
|
2002
|
+
}
|
|
2003
|
+
const existingActions = vector.actions || [];
|
|
2004
|
+
const actionIndex = existingActions.findIndex(a => a.tag === actionTag || a.tag === `${vectorTag}:${actionTag}`);
|
|
2005
|
+
if (actionIndex === -1) {
|
|
2006
|
+
throw new Error(`Vector action with tag: ${actionTag} not found`);
|
|
2007
|
+
}
|
|
2008
|
+
// Remove from array
|
|
2009
|
+
const updatedActions = existingActions.filter((_, idx) => idx !== actionIndex);
|
|
2010
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
2011
|
+
tag: vectorTag,
|
|
2012
|
+
actions: updatedActions,
|
|
2013
|
+
component: enums_1.ProductComponents.VECTOR,
|
|
2014
|
+
action: enums_1.RequestAction.UPDATE,
|
|
2015
|
+
}, this.getUserAccess());
|
|
2016
|
+
}
|
|
2017
|
+
catch (e) {
|
|
2018
|
+
throw e;
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
// ==================== AGENT METHODS ====================
|
|
2022
|
+
/**
|
|
2023
|
+
* Create a new agent configuration
|
|
2024
|
+
* @param data Agent configuration data
|
|
2025
|
+
* @param throwErrorIfExists Whether to throw an error if agent already exists
|
|
2026
|
+
*/
|
|
2027
|
+
async createAgent(data, throwErrorIfExists = false) {
|
|
2028
|
+
if (!(await this.fetchAgent(data.tag))) {
|
|
2029
|
+
await validators_1.CreateProductAgentSchema.validateAsync(data);
|
|
2030
|
+
// Validate envs if provided
|
|
2031
|
+
if (data.envs) {
|
|
2032
|
+
for (const env of data.envs) {
|
|
2033
|
+
const exists = await this.fetchEnv(env.slug);
|
|
2034
|
+
if (!exists) {
|
|
2035
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
934
2036
|
}
|
|
935
|
-
newEnvs.push(dataEnv);
|
|
936
2037
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
2038
|
+
}
|
|
2039
|
+
// Validate that all product envs are configured
|
|
2040
|
+
const envs = await this.fetchEnvs();
|
|
2041
|
+
if (data.envs) {
|
|
2042
|
+
for (const env of envs) {
|
|
2043
|
+
const exists = data.envs.findIndex((agentEnv) => agentEnv.slug === env.slug);
|
|
2044
|
+
if (exists === -1) {
|
|
2045
|
+
// Auto-add missing envs with default config
|
|
2046
|
+
data.envs.push({ slug: env.slug, active: true });
|
|
940
2047
|
}
|
|
941
|
-
overwrite.push(Object.assign(Object.assign({}, envs[exists]), dataEnv));
|
|
942
2048
|
}
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
2049
|
+
}
|
|
2050
|
+
else {
|
|
2051
|
+
// Initialize envs with all product envs
|
|
2052
|
+
data.envs = envs.map((env) => ({ slug: env.slug, active: true }));
|
|
2053
|
+
}
|
|
2054
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.AGENT, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
2055
|
+
}
|
|
2056
|
+
else {
|
|
2057
|
+
if (throwErrorIfExists)
|
|
2058
|
+
throw new Error(`Agent ${data.tag} already exists`);
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
/**
|
|
2062
|
+
* Update an existing agent configuration
|
|
2063
|
+
* @param tag Agent tag
|
|
2064
|
+
* @param data Updated agent configuration
|
|
2065
|
+
*/
|
|
2066
|
+
async updateAgent(tag, data) {
|
|
2067
|
+
try {
|
|
2068
|
+
const agent = await this.fetchAgent(tag);
|
|
2069
|
+
if (!agent) {
|
|
2070
|
+
throw new Error(`Agent ${tag} not found`);
|
|
2071
|
+
}
|
|
2072
|
+
const { _id, envs } = agent;
|
|
2073
|
+
await validators_1.UpdateProductAgentSchema.validateAsync(data);
|
|
2074
|
+
if (data.tag && data.tag !== tag && (await this.fetchAgent(data.tag))) {
|
|
2075
|
+
throw new Error(`tag ${data.tag} is in use`);
|
|
2076
|
+
}
|
|
2077
|
+
if (data.envs) {
|
|
2078
|
+
// Validate that all provided envs exist
|
|
2079
|
+
for (const env of data.envs) {
|
|
2080
|
+
const exists = await this.fetchEnv(env.slug);
|
|
2081
|
+
if (!exists) {
|
|
2082
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
951
2083
|
}
|
|
952
|
-
unchanged.push(env);
|
|
953
2084
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
2085
|
+
const overwrite = [];
|
|
2086
|
+
const newEnvs = [];
|
|
2087
|
+
data.envs.forEach((dataEnv) => {
|
|
2088
|
+
var _a;
|
|
2089
|
+
const existsIdx = (_a = envs === null || envs === void 0 ? void 0 : envs.findIndex((env) => env.slug === dataEnv.slug)) !== null && _a !== void 0 ? _a : -1;
|
|
2090
|
+
if (existsIdx === -1) {
|
|
2091
|
+
newEnvs.push(dataEnv);
|
|
2092
|
+
}
|
|
2093
|
+
else {
|
|
2094
|
+
overwrite.push(Object.assign(Object.assign({}, envs[existsIdx]), dataEnv));
|
|
2095
|
+
}
|
|
2096
|
+
});
|
|
2097
|
+
const unchanged = [];
|
|
2098
|
+
envs === null || envs === void 0 ? void 0 : envs.forEach((env) => {
|
|
2099
|
+
const newEnv = newEnvs.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
2100
|
+
const overwriteEnv = overwrite.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
2101
|
+
if (!newEnv && !overwriteEnv) {
|
|
2102
|
+
unchanged.push(env);
|
|
2103
|
+
}
|
|
2104
|
+
});
|
|
2105
|
+
data.envs = [...unchanged, ...overwrite, ...newEnvs];
|
|
2106
|
+
}
|
|
2107
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({ _id }, agent), data), { component: enums_1.ProductComponents.AGENT, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
958
2108
|
}
|
|
959
2109
|
catch (e) {
|
|
960
2110
|
throw e;
|
|
961
2111
|
}
|
|
962
2112
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
2113
|
+
/**
|
|
2114
|
+
* Fetch all agent configurations
|
|
2115
|
+
* @param version Optional version
|
|
2116
|
+
*/
|
|
2117
|
+
async fetchAgents(version) {
|
|
2118
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'agent', this.getUserAccess());
|
|
2119
|
+
return components;
|
|
2120
|
+
}
|
|
2121
|
+
/**
|
|
2122
|
+
* Fetch a specific agent configuration by tag
|
|
2123
|
+
* @param tag Agent tag
|
|
2124
|
+
* @param version Optional version
|
|
2125
|
+
*/
|
|
2126
|
+
async fetchAgent(tag, version) {
|
|
2127
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'agent', tag, this.getUserAccess());
|
|
2128
|
+
return component;
|
|
2129
|
+
}
|
|
2130
|
+
/**
|
|
2131
|
+
* Delete an agent configuration
|
|
2132
|
+
* @param tag Agent tag
|
|
2133
|
+
*/
|
|
2134
|
+
async deleteAgent(tag) {
|
|
2135
|
+
try {
|
|
2136
|
+
const agent = await this.fetchAgent(tag);
|
|
2137
|
+
if (!agent) {
|
|
2138
|
+
throw new Error(`Agent with tag: ${tag} not found`);
|
|
2139
|
+
}
|
|
2140
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
2141
|
+
tag,
|
|
2142
|
+
component: enums_1.ProductComponents.AGENT,
|
|
2143
|
+
action: enums_1.RequestAction.DELETE,
|
|
2144
|
+
}, this.getUserAccess());
|
|
2145
|
+
}
|
|
2146
|
+
catch (e) {
|
|
2147
|
+
throw e;
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
// ==================== LLM MODEL METHODS ====================
|
|
2151
|
+
/**
|
|
2152
|
+
* Create a new LLM model configuration
|
|
2153
|
+
* API keys are automatically encrypted using the product's private key
|
|
2154
|
+
* @param data LLM model configuration
|
|
2155
|
+
* @param throwErrorIfExists Whether to throw error if model already exists
|
|
2156
|
+
*/
|
|
2157
|
+
async createModel(data, throwErrorIfExists = false) {
|
|
2158
|
+
if (!(await this.fetchModel(data.tag))) {
|
|
2159
|
+
await validators_1.CreateProductModelSchema.validateAsync(data);
|
|
2160
|
+
const processedEnvs = [];
|
|
2161
|
+
for (const env of data.envs) {
|
|
2162
|
+
const exists = await this.fetchEnv(env.slug);
|
|
2163
|
+
if (!exists) {
|
|
2164
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
971
2165
|
}
|
|
972
|
-
|
|
2166
|
+
// Store API key as secret and encrypt
|
|
2167
|
+
if (env.apiKey) {
|
|
2168
|
+
env.apiKey = await this.storeModelApiKeyAsSecret(env.apiKey, data.tag, env.slug);
|
|
2169
|
+
env.apiKey = (0, processor_utils_1.encrypt)(env.apiKey, this.product.private_key);
|
|
2170
|
+
}
|
|
2171
|
+
processedEnvs.push(env);
|
|
2172
|
+
}
|
|
2173
|
+
data.envs = processedEnvs;
|
|
2174
|
+
const envs = await this.fetchEnvs();
|
|
2175
|
+
for (const env of envs) {
|
|
2176
|
+
const exists = data.envs.findIndex((modelEnv) => modelEnv.slug === env.slug);
|
|
2177
|
+
if (exists === -1) {
|
|
2178
|
+
throw new Error(`Product env ${env.slug} is not defined, please provide API key configuration`);
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.MODEL, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
2182
|
+
}
|
|
2183
|
+
else {
|
|
2184
|
+
if (throwErrorIfExists)
|
|
2185
|
+
throw new Error(`Model ${data.tag} already exists`);
|
|
973
2186
|
}
|
|
974
|
-
return storage;
|
|
975
2187
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
2188
|
+
/**
|
|
2189
|
+
* Update an existing LLM model configuration
|
|
2190
|
+
* @param tag Model tag
|
|
2191
|
+
* @param data Updated model configuration
|
|
2192
|
+
*/
|
|
2193
|
+
async updateModel(tag, data) {
|
|
2194
|
+
try {
|
|
2195
|
+
const model = await this.fetchModel(tag);
|
|
2196
|
+
if (!model) {
|
|
2197
|
+
throw new Error(`Model ${tag} not found`);
|
|
2198
|
+
}
|
|
2199
|
+
const { _id, envs } = model;
|
|
2200
|
+
await validators_1.UpdateProductModelSchema.validateAsync(data);
|
|
2201
|
+
if (data.tag && (await this.fetchModel(data.tag))) {
|
|
2202
|
+
throw new Error(`tag ${data.tag} is in use`);
|
|
2203
|
+
}
|
|
2204
|
+
if (data.envs) {
|
|
2205
|
+
data.envs = await Promise.all(data.envs.map(async (env) => {
|
|
2206
|
+
const exists = await this.fetchEnv(env.slug);
|
|
2207
|
+
if (!exists) {
|
|
2208
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
2209
|
+
}
|
|
2210
|
+
// Store API key as secret and encrypt
|
|
2211
|
+
if (env.apiKey) {
|
|
2212
|
+
env.apiKey = await this.storeModelApiKeyAsSecret(env.apiKey, data.tag || tag, env.slug);
|
|
2213
|
+
env.apiKey = (0, processor_utils_1.encrypt)(env.apiKey, this.product.private_key);
|
|
2214
|
+
}
|
|
2215
|
+
return env;
|
|
2216
|
+
}));
|
|
2217
|
+
const overwrite = [];
|
|
2218
|
+
const newEnvs = [];
|
|
2219
|
+
data.envs.forEach((dataEnv) => {
|
|
2220
|
+
const existsIdx = envs.findIndex((env) => env.slug === dataEnv.slug);
|
|
2221
|
+
if (existsIdx === -1) {
|
|
2222
|
+
newEnvs.push(dataEnv);
|
|
2223
|
+
}
|
|
2224
|
+
else {
|
|
2225
|
+
overwrite.push(Object.assign(Object.assign({}, envs[existsIdx]), dataEnv));
|
|
2226
|
+
}
|
|
2227
|
+
});
|
|
2228
|
+
const unchanged = [];
|
|
2229
|
+
envs.forEach((env) => {
|
|
2230
|
+
const newEnv = newEnvs.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
2231
|
+
const overwriteEnv = overwrite.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
2232
|
+
if (!newEnv && !overwriteEnv) {
|
|
2233
|
+
unchanged.push(env);
|
|
2234
|
+
}
|
|
2235
|
+
});
|
|
2236
|
+
data.envs = [...unchanged, ...overwrite, ...newEnvs];
|
|
2237
|
+
}
|
|
2238
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({ _id }, model), data), { component: enums_1.ProductComponents.MODEL, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
2239
|
+
}
|
|
2240
|
+
catch (e) {
|
|
2241
|
+
throw e;
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
/**
|
|
2245
|
+
* Fetch all LLM model configurations
|
|
2246
|
+
* @param version Optional version
|
|
2247
|
+
*/
|
|
2248
|
+
async fetchModels(version) {
|
|
2249
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'model', this.getUserAccess());
|
|
2250
|
+
return components;
|
|
2251
|
+
}
|
|
2252
|
+
/**
|
|
2253
|
+
* Fetch a specific LLM model configuration by tag
|
|
2254
|
+
* @param tag Model tag
|
|
2255
|
+
* @param version Optional version
|
|
2256
|
+
*/
|
|
2257
|
+
async fetchModel(tag, version) {
|
|
2258
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'model', tag, this.getUserAccess());
|
|
2259
|
+
return component;
|
|
2260
|
+
}
|
|
2261
|
+
/**
|
|
2262
|
+
* Delete an LLM model configuration
|
|
2263
|
+
* @param tag Model tag
|
|
2264
|
+
*/
|
|
2265
|
+
async deleteModel(tag) {
|
|
2266
|
+
try {
|
|
2267
|
+
const model = await this.fetchModel(tag);
|
|
2268
|
+
if (!model) {
|
|
2269
|
+
throw new Error(`Model with tag: ${tag} not found`);
|
|
2270
|
+
}
|
|
2271
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
2272
|
+
tag,
|
|
2273
|
+
component: enums_1.ProductComponents.MODEL,
|
|
2274
|
+
action: enums_1.RequestAction.DELETE,
|
|
2275
|
+
}, this.getUserAccess());
|
|
2276
|
+
}
|
|
2277
|
+
catch (e) {
|
|
2278
|
+
throw e;
|
|
2279
|
+
}
|
|
980
2280
|
}
|
|
981
2281
|
async validateAppData(appData, app) {
|
|
982
2282
|
// TODO:
|
|
@@ -999,6 +2299,9 @@ class ProductsBuilderService {
|
|
|
999
2299
|
}
|
|
1000
2300
|
}
|
|
1001
2301
|
validateVariablesValues(variables, appVariables) {
|
|
2302
|
+
if (!variables) {
|
|
2303
|
+
variables = [];
|
|
2304
|
+
}
|
|
1002
2305
|
if (appVariables && appVariables.length) {
|
|
1003
2306
|
appVariables.map((data) => {
|
|
1004
2307
|
const find = variables.find((value) => value.key === data.key);
|
|
@@ -1015,20 +2318,21 @@ class ProductsBuilderService {
|
|
|
1015
2318
|
const { envs: appEnvs } = version;
|
|
1016
2319
|
return envs.map((env) => {
|
|
1017
2320
|
const { auth } = env;
|
|
1018
|
-
this.fetchEnv(env.product_env_slug
|
|
2321
|
+
this.fetchEnv(env.product_env_slug);
|
|
1019
2322
|
const appEnv = appEnvs.find((appEnv) => appEnv.slug === env.app_env_slug);
|
|
1020
2323
|
if (!appEnv) {
|
|
1021
2324
|
throw new Error(`app_slug ${env.app_env_slug} not found`);
|
|
1022
2325
|
}
|
|
1023
|
-
const updates = this.validateAppAuth(auth, version);
|
|
2326
|
+
// const updates = this.validateAppAuth(auth, version);
|
|
1024
2327
|
this.validateVariablesSchema(env.variables, version.variables);
|
|
1025
2328
|
this.validateVariablesValues(env.variables, version.variables);
|
|
1026
|
-
if (updates && updates.data) {
|
|
1027
|
-
|
|
2329
|
+
/*if (updates && updates.data) {
|
|
2330
|
+
env.auth.data = updates.data;
|
|
1028
2331
|
}
|
|
2332
|
+
|
|
1029
2333
|
if (updates && updates.values) {
|
|
1030
|
-
|
|
1031
|
-
}
|
|
2334
|
+
env.auth.values = updates.values;
|
|
2335
|
+
}*/
|
|
1032
2336
|
return env;
|
|
1033
2337
|
});
|
|
1034
2338
|
}
|
|
@@ -1105,10 +2409,10 @@ class ProductsBuilderService {
|
|
|
1105
2409
|
});
|
|
1106
2410
|
(0, inputs_utils_create_1.validateInputSchema)(queryValues, querySchema);
|
|
1107
2411
|
}
|
|
1108
|
-
const updateData = (0, processor_utils_1.encrypt)(JSON.stringify(data), this.
|
|
2412
|
+
const updateData = (0, processor_utils_1.encrypt)(JSON.stringify(data), this.product.private_key);
|
|
1109
2413
|
let updateValues = null;
|
|
1110
2414
|
if (exists.setup_type === enums_1.AuthTypes.TOKEN) {
|
|
1111
|
-
updateValues = (0, processor_utils_1.encrypt)(JSON.stringify(data), this.
|
|
2415
|
+
updateValues = (0, processor_utils_1.encrypt)(JSON.stringify(data), this.product.private_key);
|
|
1112
2416
|
}
|
|
1113
2417
|
return { data: updateData, values: updateValues };
|
|
1114
2418
|
}
|
|
@@ -1131,7 +2435,7 @@ class ProductsBuilderService {
|
|
|
1131
2435
|
try {
|
|
1132
2436
|
await validators_1.CreateProductAppSchema.validateAsync(app);
|
|
1133
2437
|
// TODO: figure out a way to check if this has run before, halt if it has
|
|
1134
|
-
if (!this.fetchApp(app.access_tag, throwErrorIfExists)) {
|
|
2438
|
+
if (!await this.fetchApp(app.access_tag, throwErrorIfExists)) {
|
|
1135
2439
|
const _a = await this.appApi.fetchAccessByTag(app.access_tag, this.getUserAccess()), { version } = _a, access = __rest(_a, ["version"]);
|
|
1136
2440
|
if (!access) {
|
|
1137
2441
|
throw new Error(`Access to app ${app.access_tag} not found`);
|
|
@@ -1141,8 +2445,11 @@ class ProductsBuilderService {
|
|
|
1141
2445
|
throw new Error(`App ${app.access_tag} not found`);
|
|
1142
2446
|
}
|
|
1143
2447
|
const cleanedAppData = await this.validateAppData(appData, app);
|
|
1144
|
-
|
|
1145
|
-
|
|
2448
|
+
if (!cleanedAppData.pricing_tag) {
|
|
2449
|
+
cleanedAppData.pricing_tag = `${appData.tag}:${productsBuilder_types_1.PricingTag.FREE}`;
|
|
2450
|
+
}
|
|
2451
|
+
console.log(cleanedAppData);
|
|
2452
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, cleanedAppData), { app_tag: appData.tag, component: enums_1.ProductComponents.APP, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
1146
2453
|
}
|
|
1147
2454
|
else {
|
|
1148
2455
|
if (throwErrorIfExists)
|
|
@@ -1160,7 +2467,7 @@ class ProductsBuilderService {
|
|
|
1160
2467
|
throw new Error(`App with access tag ${access_tag} not found`);
|
|
1161
2468
|
}
|
|
1162
2469
|
const version = app.versions.find((version) => version.tag === app.version);
|
|
1163
|
-
const status = await this.webhooksApi.fetchWebhooks({
|
|
2470
|
+
//const status = await this.webhooksApi.fetchWebhooks({access_tag, app_tag: app.tag, version: app.version}, this.getUserAccess())
|
|
1164
2471
|
console.log(status);
|
|
1165
2472
|
if (!version) {
|
|
1166
2473
|
throw new Error(`Required app version not found`);
|
|
@@ -1173,7 +2480,7 @@ class ProductsBuilderService {
|
|
|
1173
2480
|
}
|
|
1174
2481
|
async updateApp(access_tag, data) {
|
|
1175
2482
|
try {
|
|
1176
|
-
const app = this.fetchApp(access_tag);
|
|
2483
|
+
const app = await this.fetchApp(access_tag);
|
|
1177
2484
|
if (!app) {
|
|
1178
2485
|
throw new Error(`App ${access_tag} not found`);
|
|
1179
2486
|
}
|
|
@@ -1189,28 +2496,44 @@ class ProductsBuilderService {
|
|
|
1189
2496
|
throw new Error(`access_tag ${access_tag} is in use`); // TODO: also check on the backend
|
|
1190
2497
|
}*/
|
|
1191
2498
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({ _id }, data), { access_tag, component: enums_1.ProductComponents.APP, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
1192
|
-
await this.initializeProduct(this.product_id);
|
|
1193
2499
|
}
|
|
1194
2500
|
catch (e) {
|
|
1195
2501
|
throw e;
|
|
1196
2502
|
}
|
|
1197
2503
|
}
|
|
1198
|
-
fetchApps() {
|
|
1199
|
-
|
|
2504
|
+
async fetchApps() {
|
|
2505
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'app', this.getUserAccess());
|
|
2506
|
+
return components;
|
|
1200
2507
|
}
|
|
1201
|
-
fetchApp(tag, throwErrorIfExists = false) {
|
|
1202
|
-
const
|
|
1203
|
-
if (!
|
|
2508
|
+
async fetchApp(tag, throwErrorIfExists = false) {
|
|
2509
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'app', tag, this.getUserAccess());
|
|
2510
|
+
if (!component && throwErrorIfExists)
|
|
1204
2511
|
throw new Error(`App ${tag} not found`);
|
|
1205
|
-
return
|
|
2512
|
+
return component;
|
|
2513
|
+
}
|
|
2514
|
+
async deleteApp(tag) {
|
|
2515
|
+
try {
|
|
2516
|
+
const app = await this.fetchApp(tag, true);
|
|
2517
|
+
if (!app) {
|
|
2518
|
+
throw new Error(`App with tag: ${tag} not found`);
|
|
2519
|
+
}
|
|
2520
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
2521
|
+
tag: app.access_tag,
|
|
2522
|
+
component: enums_1.ProductComponents.APP,
|
|
2523
|
+
action: enums_1.RequestAction.DELETE,
|
|
2524
|
+
}, this.getUserAccess());
|
|
2525
|
+
}
|
|
2526
|
+
catch (e) {
|
|
2527
|
+
throw e;
|
|
2528
|
+
}
|
|
1206
2529
|
}
|
|
1207
2530
|
async createFunction(data, throwErrorIfExists = false) {
|
|
1208
2531
|
try {
|
|
1209
2532
|
// TODO: figure out a way to check if this has run before, halt if it has
|
|
1210
|
-
if (!this.fetchFunction(data.tag)) {
|
|
2533
|
+
if (!(await this.fetchFunction(data.tag))) {
|
|
1211
2534
|
await validators_1.CreateProductFunctionSchema.validateAsync(data);
|
|
1212
2535
|
data.envs.map((env) => {
|
|
1213
|
-
env.auth = (0, processor_utils_1.encrypt)(JSON.stringify(env.auth), this.
|
|
2536
|
+
env.auth = (0, processor_utils_1.encrypt)(JSON.stringify(env.auth), this.product.private_key);
|
|
1214
2537
|
});
|
|
1215
2538
|
data.sample_data = (await this.inputsService.parseJson({
|
|
1216
2539
|
data: data.sample,
|
|
@@ -1223,7 +2546,6 @@ class ProductsBuilderService {
|
|
|
1223
2546
|
category: enums_1.Categories.DATA,
|
|
1224
2547
|
}));
|
|
1225
2548
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.FUNCTION, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
1226
|
-
await this.initializeProduct(this.product_id);
|
|
1227
2549
|
}
|
|
1228
2550
|
else {
|
|
1229
2551
|
if (throwErrorIfExists)
|
|
@@ -1236,37 +2558,51 @@ class ProductsBuilderService {
|
|
|
1236
2558
|
}
|
|
1237
2559
|
async updateFunction(tag, data) {
|
|
1238
2560
|
try {
|
|
1239
|
-
const func = this.fetchFunction(tag);
|
|
2561
|
+
const func = await this.fetchFunction(tag);
|
|
1240
2562
|
if (!func) {
|
|
1241
2563
|
throw new Error(`Function ${tag} not found`);
|
|
1242
2564
|
}
|
|
1243
2565
|
const { _id } = func;
|
|
1244
2566
|
await validators_1.UpdateProductFunctionSchema.validateAsync(data); // Change to update;
|
|
1245
|
-
if (data.tag && this.fetchFunction(data.tag)) {
|
|
2567
|
+
if (data.tag && (await this.fetchFunction(data.tag))) {
|
|
1246
2568
|
throw new Error(`tag ${tag} is in use`); // TODO: also check on the backend
|
|
1247
2569
|
}
|
|
1248
2570
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({ _id }, func), data), { component: enums_1.ProductComponents.FUNCTION, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
1249
|
-
await this.initializeProduct(this.product_id);
|
|
1250
2571
|
}
|
|
1251
2572
|
catch (e) {
|
|
1252
2573
|
throw e;
|
|
1253
2574
|
}
|
|
1254
2575
|
}
|
|
1255
|
-
fetchFunctions() {
|
|
1256
|
-
|
|
2576
|
+
async fetchFunctions(version) {
|
|
2577
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'function', this.getUserAccess());
|
|
2578
|
+
return components;
|
|
2579
|
+
}
|
|
2580
|
+
async fetchFunction(tag, version) {
|
|
2581
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'function', tag, this.getUserAccess());
|
|
2582
|
+
return component;
|
|
1257
2583
|
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
2584
|
+
async deleteFunction(tag) {
|
|
2585
|
+
try {
|
|
2586
|
+
const func = await this.fetchFunction(tag);
|
|
2587
|
+
if (!func) {
|
|
2588
|
+
throw new Error(`Function with tag: ${tag} not found`);
|
|
2589
|
+
}
|
|
2590
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
2591
|
+
tag,
|
|
2592
|
+
component: enums_1.ProductComponents.FUNCTION,
|
|
2593
|
+
action: enums_1.RequestAction.DELETE,
|
|
2594
|
+
}, this.getUserAccess());
|
|
2595
|
+
}
|
|
2596
|
+
catch (e) {
|
|
2597
|
+
throw e;
|
|
2598
|
+
}
|
|
1262
2599
|
}
|
|
1263
2600
|
async createCache(data, throwErrorIfExists = false) {
|
|
1264
2601
|
try {
|
|
1265
2602
|
// TODO: figure out a way to check if this has run before, halt if it has
|
|
1266
|
-
if (!this.fetchCache(data.tag)) {
|
|
2603
|
+
if (!(await this.fetchCache(data.tag))) {
|
|
1267
2604
|
await validators_1.CreateProductCacheSchema.validateAsync(data);
|
|
1268
2605
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.CACHE, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
1269
|
-
await this.initializeProduct(this.product_id);
|
|
1270
2606
|
}
|
|
1271
2607
|
else {
|
|
1272
2608
|
if (throwErrorIfExists)
|
|
@@ -1279,62 +2615,83 @@ class ProductsBuilderService {
|
|
|
1279
2615
|
}
|
|
1280
2616
|
async updateCache(tag, data) {
|
|
1281
2617
|
try {
|
|
1282
|
-
const cache = this.fetchCache(tag);
|
|
2618
|
+
const cache = await this.fetchCache(tag);
|
|
1283
2619
|
if (!cache) {
|
|
1284
2620
|
throw new Error(`Cache ${tag} not found`);
|
|
1285
2621
|
}
|
|
1286
2622
|
const { _id } = cache;
|
|
1287
2623
|
await validators_1.UpdateProductCacheSchema.validateAsync(data); // Change to update;
|
|
1288
|
-
if (data.tag && this.fetchCache(data.tag)) {
|
|
2624
|
+
if (data.tag && (await this.fetchCache(data.tag))) {
|
|
1289
2625
|
throw new Error(`tag ${tag} is in use`); // TODO: also check on the backend
|
|
1290
2626
|
}
|
|
1291
2627
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({ _id }, data), { component: enums_1.ProductComponents.CACHE, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
1292
|
-
await this.initializeProduct(this.product_id);
|
|
1293
2628
|
}
|
|
1294
2629
|
catch (e) {
|
|
1295
2630
|
throw e;
|
|
1296
2631
|
}
|
|
1297
2632
|
}
|
|
1298
|
-
|
|
1299
|
-
const
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
2633
|
+
async fetchCaches(version) {
|
|
2634
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'cache', this.getUserAccess());
|
|
2635
|
+
return components;
|
|
2636
|
+
}
|
|
2637
|
+
async fetchCache(tag, version) {
|
|
2638
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'cache', tag, this.getUserAccess());
|
|
2639
|
+
return component;
|
|
1303
2640
|
}
|
|
1304
|
-
|
|
1305
|
-
|
|
2641
|
+
async deleteCache(tag) {
|
|
2642
|
+
try {
|
|
2643
|
+
const cache = await this.fetchCache(tag);
|
|
2644
|
+
if (!cache) {
|
|
2645
|
+
throw new Error(`Cache with tag: ${tag} not found`);
|
|
2646
|
+
}
|
|
2647
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
2648
|
+
tag,
|
|
2649
|
+
component: enums_1.ProductComponents.CACHE,
|
|
2650
|
+
action: enums_1.RequestAction.DELETE,
|
|
2651
|
+
}, this.getUserAccess());
|
|
2652
|
+
}
|
|
2653
|
+
catch (e) {
|
|
2654
|
+
throw e;
|
|
2655
|
+
}
|
|
1306
2656
|
}
|
|
1307
2657
|
async createNotification(data, throwErrorIfExists = false) {
|
|
2658
|
+
var _a, _b, _c, _d;
|
|
1308
2659
|
try {
|
|
1309
2660
|
// TODO: figure out a way to check if this has run before, halt if it has
|
|
1310
|
-
if (!this.fetchNotification(data.tag)) {
|
|
2661
|
+
if (!(await this.fetchNotification(data.tag))) {
|
|
1311
2662
|
await validators_1.CreateProductNotificationSchema.validateAsync(data);
|
|
1312
|
-
const envs = this.fetchEnvs();
|
|
1313
|
-
|
|
2663
|
+
const envs = await this.fetchEnvs();
|
|
2664
|
+
for (const env of envs) {
|
|
1314
2665
|
const exists = data.envs.findIndex((nEnv) => nEnv.slug === env.slug);
|
|
1315
2666
|
if (exists === -1) {
|
|
1316
2667
|
throw new Error(`Notification for environment ${env.slug} is not defined, please provide the environment details`);
|
|
1317
2668
|
}
|
|
1318
|
-
}
|
|
2669
|
+
}
|
|
1319
2670
|
for (let i = 0; i < data.envs.length; i++) {
|
|
1320
|
-
const
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
2671
|
+
const rawEnv = data.envs[i];
|
|
2672
|
+
// Process secrets for each notification handler
|
|
2673
|
+
const processedEnv = await this.processNotificationEnvSecrets(rawEnv, data.tag, rawEnv.slug);
|
|
2674
|
+
// Only set encrypted values; fallback to raw env if processed dropped a channel (e.g. missing credentials)
|
|
2675
|
+
const updates = {};
|
|
2676
|
+
const pushVal = (_a = processedEnv.push_notifications) !== null && _a !== void 0 ? _a : rawEnv.push_notifications;
|
|
2677
|
+
if (pushVal) {
|
|
2678
|
+
updates.push_notifications = (0, processor_utils_1.encrypt)(JSON.stringify(pushVal), this.product.private_key);
|
|
2679
|
+
}
|
|
2680
|
+
const emailsVal = (_b = processedEnv.emails) !== null && _b !== void 0 ? _b : rawEnv.emails;
|
|
2681
|
+
if (emailsVal) {
|
|
2682
|
+
updates.emails = (0, processor_utils_1.encrypt)(JSON.stringify(emailsVal), this.product.private_key);
|
|
2683
|
+
}
|
|
2684
|
+
const callbacksVal = (_c = processedEnv.callbacks) !== null && _c !== void 0 ? _c : rawEnv.callbacks;
|
|
2685
|
+
if (callbacksVal) {
|
|
2686
|
+
updates.callbacks = (0, processor_utils_1.encrypt)(JSON.stringify(callbacksVal), this.product.private_key);
|
|
2687
|
+
}
|
|
2688
|
+
const smsVal = (_d = processedEnv.sms) !== null && _d !== void 0 ? _d : rawEnv.sms;
|
|
2689
|
+
if (smsVal) {
|
|
2690
|
+
updates.sms = (0, processor_utils_1.encrypt)(JSON.stringify(smsVal), this.product.private_key);
|
|
2691
|
+
}
|
|
2692
|
+
data.envs[i] = Object.assign(Object.assign({}, rawEnv), updates);
|
|
1335
2693
|
}
|
|
1336
2694
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.NOTIFICATION, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
1337
|
-
await this.initializeProduct(this.product_id);
|
|
1338
2695
|
}
|
|
1339
2696
|
else {
|
|
1340
2697
|
if (throwErrorIfExists)
|
|
@@ -1355,7 +2712,7 @@ class ProductsBuilderService {
|
|
|
1355
2712
|
if (!notificationTag || !tag) {
|
|
1356
2713
|
throw new Error(`tag is expected to be defined as "notification_tag:message_tag"`);
|
|
1357
2714
|
}
|
|
1358
|
-
const exists = this.fetchNotificationMessage(data.tag);
|
|
2715
|
+
const exists = await this.fetchNotificationMessage(data.tag);
|
|
1359
2716
|
data.tag = tag;
|
|
1360
2717
|
if (!exists) {
|
|
1361
2718
|
if (!data.email && !data.push_notification && !data.callback) {
|
|
@@ -1392,7 +2749,6 @@ class ProductsBuilderService {
|
|
|
1392
2749
|
data.sms_data = (0, string_utils_1.extractPlaceholders)(data.sms, '');
|
|
1393
2750
|
}
|
|
1394
2751
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { notificationTag, component: enums_1.ProductComponents.NOTIFICATION_MESSAGE, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
1395
|
-
await this.initializeProduct(this.product_id);
|
|
1396
2752
|
}
|
|
1397
2753
|
else {
|
|
1398
2754
|
if (throwErrorIfExists)
|
|
@@ -1403,28 +2759,31 @@ class ProductsBuilderService {
|
|
|
1403
2759
|
throw e;
|
|
1404
2760
|
}
|
|
1405
2761
|
}
|
|
1406
|
-
fetchNotificationMessage(tag, throwErrorIfExists = false) {
|
|
2762
|
+
async fetchNotificationMessage(tag, throwErrorIfExists = false) {
|
|
2763
|
+
var _a;
|
|
1407
2764
|
const [notificationTag, messageTag] = tag.split(':');
|
|
1408
2765
|
if (!notificationTag || !messageTag) {
|
|
1409
2766
|
throw new Error(`tag is expected to be defined as "notification_tag:message_tag"`);
|
|
1410
2767
|
}
|
|
1411
|
-
const notification = this.fetchNotification(notificationTag);
|
|
2768
|
+
const notification = await this.fetchNotification(notificationTag);
|
|
1412
2769
|
if (!notification)
|
|
1413
2770
|
throw new Error(`Notification ${notificationTag} not found`);
|
|
1414
|
-
const
|
|
2771
|
+
const messages = (_a = notification.messages) !== null && _a !== void 0 ? _a : [];
|
|
2772
|
+
const message = messages.find((data) => data.tag === messageTag);
|
|
1415
2773
|
if (!message && throwErrorIfExists)
|
|
1416
2774
|
throw new Error(`Notification message ${tag} not found`);
|
|
1417
|
-
return message;
|
|
2775
|
+
return message !== null && message !== void 0 ? message : null;
|
|
1418
2776
|
}
|
|
1419
|
-
fetchNotificationMessages(notificationTag, throwErrorIfExists = false) {
|
|
1420
|
-
|
|
2777
|
+
async fetchNotificationMessages(notificationTag, throwErrorIfExists = false) {
|
|
2778
|
+
var _a, _b;
|
|
2779
|
+
const notification = (_a = this.product.notifications) === null || _a === void 0 ? void 0 : _a.find((data) => data.tag === notificationTag);
|
|
1421
2780
|
if (!notification)
|
|
1422
2781
|
throw new Error(`Notification ${notificationTag} not found`);
|
|
1423
|
-
return notification.messages;
|
|
2782
|
+
return (_b = notification.messages) !== null && _b !== void 0 ? _b : [];
|
|
1424
2783
|
}
|
|
1425
2784
|
async updateNotificationMessage(data) {
|
|
1426
2785
|
try {
|
|
1427
|
-
console.log(
|
|
2786
|
+
console.log('NOTIFICATION DATA!!', data);
|
|
1428
2787
|
await update_productNotificationMessage_validator_1.default.validateAsync(data);
|
|
1429
2788
|
if (!data.tag) {
|
|
1430
2789
|
throw new Error('tag field is required');
|
|
@@ -1470,29 +2829,33 @@ class ProductsBuilderService {
|
|
|
1470
2829
|
const payload = Object.assign(Object.assign(Object.assign({}, message), data), { notificationTag, component: enums_1.ProductComponents.NOTIFICATION_MESSAGE, action: enums_1.RequestAction.UPDATE });
|
|
1471
2830
|
// Update product and reinitialize
|
|
1472
2831
|
await this.productApi.updateProduct(this.product_id, payload, this.getUserAccess());
|
|
1473
|
-
await this.initializeProduct(this.product_id);
|
|
1474
2832
|
}
|
|
1475
2833
|
catch (error) {
|
|
1476
2834
|
throw error;
|
|
1477
2835
|
}
|
|
1478
2836
|
}
|
|
1479
2837
|
async updateNotification(tag, data) {
|
|
2838
|
+
var _a, _b, _c, _d;
|
|
1480
2839
|
try {
|
|
1481
|
-
const
|
|
1482
|
-
if (
|
|
2840
|
+
const notificationResult = await this.fetchNotification(tag);
|
|
2841
|
+
if (!notificationResult) {
|
|
2842
|
+
throw new Error(`Notification with tag ${tag} not found`);
|
|
2843
|
+
}
|
|
2844
|
+
const { _id, envs } = notificationResult;
|
|
2845
|
+
if (data.tag && tag !== data.tag && (await this.fetchNotification(data.tag))) {
|
|
1483
2846
|
throw new Error(`Notification of tag ${data.tag} already exists`);
|
|
1484
2847
|
}
|
|
1485
2848
|
await validators_1.UpdateProductNotificationSchema.validateAsync(data); // Change to update;
|
|
1486
|
-
let notification = this.fetchNotification(tag);
|
|
2849
|
+
let notification = await this.fetchNotification(tag);
|
|
1487
2850
|
if (!notification) {
|
|
1488
2851
|
throw new Error(`Notification with tag ${tag} not found`);
|
|
1489
2852
|
}
|
|
1490
2853
|
if (data.envs) {
|
|
1491
2854
|
const overwrite = [];
|
|
1492
2855
|
const newEnvs = [];
|
|
1493
|
-
data.envs
|
|
2856
|
+
for (const dataEnv of data.envs) {
|
|
1494
2857
|
const exists = envs.findIndex((env) => env.slug === dataEnv.slug);
|
|
1495
|
-
if (!this.fetchEnv(dataEnv.slug)) {
|
|
2858
|
+
if (!(await this.fetchEnv(dataEnv.slug))) {
|
|
1496
2859
|
throw new Error(`Product Environment ${dataEnv.slug} doesn't exist`);
|
|
1497
2860
|
}
|
|
1498
2861
|
if (exists === -1) {
|
|
@@ -1502,70 +2865,129 @@ class ProductsBuilderService {
|
|
|
1502
2865
|
else {
|
|
1503
2866
|
overwrite.push(Object.assign(Object.assign({}, envs[exists]), dataEnv));
|
|
1504
2867
|
}
|
|
1505
|
-
}
|
|
2868
|
+
}
|
|
1506
2869
|
const unchanged = [];
|
|
1507
|
-
|
|
2870
|
+
for (const env of envs) {
|
|
1508
2871
|
const newEnv = newEnvs.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
1509
2872
|
const overwriteEnv = overwrite.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
1510
2873
|
if (!newEnv && !overwriteEnv) {
|
|
1511
2874
|
unchanged.push(env);
|
|
1512
2875
|
}
|
|
1513
|
-
}
|
|
2876
|
+
}
|
|
1514
2877
|
data.envs = [...unchanged, ...overwrite, ...newEnvs];
|
|
1515
2878
|
}
|
|
1516
2879
|
const update = Object.assign(Object.assign({}, notification), data);
|
|
1517
|
-
update.envs.
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
2880
|
+
for (let i = 0; i < update.envs.length; i++) {
|
|
2881
|
+
const env = update.envs[i];
|
|
2882
|
+
// Process secrets for each notification handler
|
|
2883
|
+
const processedEnv = await this.processNotificationEnvSecrets(env, data.tag || tag, env.slug);
|
|
2884
|
+
// Use processed value or fallback to existing env so we don't drop a channel (e.g. sandbox)
|
|
2885
|
+
const emailsVal = (_a = processedEnv.emails) !== null && _a !== void 0 ? _a : env.emails;
|
|
2886
|
+
if (emailsVal)
|
|
2887
|
+
update.envs[i].emails = (0, processor_utils_1.encrypt)(JSON.stringify(emailsVal), this.product.private_key);
|
|
2888
|
+
const pushVal = (_b = processedEnv.push_notifications) !== null && _b !== void 0 ? _b : env.push_notifications;
|
|
2889
|
+
if (pushVal)
|
|
2890
|
+
update.envs[i].push_notifications = (0, processor_utils_1.encrypt)(JSON.stringify(pushVal), this.product.private_key);
|
|
2891
|
+
const callbacksVal = (_c = processedEnv.callbacks) !== null && _c !== void 0 ? _c : env.callbacks;
|
|
2892
|
+
if (callbacksVal)
|
|
2893
|
+
update.envs[i].callbacks = (0, processor_utils_1.encrypt)(JSON.stringify(callbacksVal), this.product.private_key);
|
|
2894
|
+
const smsVal = (_d = processedEnv.sms) !== null && _d !== void 0 ? _d : env.sms;
|
|
2895
|
+
if (smsVal)
|
|
2896
|
+
update.envs[i].sms = (0, processor_utils_1.encrypt)(JSON.stringify(smsVal), this.product.private_key);
|
|
2897
|
+
}
|
|
1528
2898
|
const payload = Object.assign(Object.assign({ _id }, update), { component: enums_1.ProductComponents.NOTIFICATION, action: enums_1.RequestAction.UPDATE });
|
|
1529
2899
|
await this.productApi.updateProduct(this.product_id, payload, this.getUserAccess());
|
|
1530
|
-
await this.initializeProduct(this.product_id);
|
|
1531
2900
|
}
|
|
1532
2901
|
catch (e) {
|
|
1533
2902
|
throw e;
|
|
1534
2903
|
}
|
|
1535
2904
|
}
|
|
1536
|
-
|
|
1537
|
-
const
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
2905
|
+
async fetchNotifications(version) {
|
|
2906
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'notification', this.getUserAccess());
|
|
2907
|
+
return components.map((component) => this.decryptNotificationChannelConfigs(component));
|
|
2908
|
+
}
|
|
2909
|
+
async fetchNotification(tag, version) {
|
|
2910
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'notification', tag, this.getUserAccess());
|
|
2911
|
+
if (!component)
|
|
2912
|
+
return null;
|
|
2913
|
+
return this.decryptNotificationChannelConfigs(component);
|
|
2914
|
+
}
|
|
2915
|
+
/**
|
|
2916
|
+
* Decrypt notification env channel configs (push_notifications, emails, callbacks, sms).
|
|
2917
|
+
* @param notification - notification with possibly encrypted env configs
|
|
2918
|
+
* @param privateKey - product private key; when omitted uses this.product.private_key (e.g. from fetch)
|
|
2919
|
+
*/
|
|
2920
|
+
decryptNotificationChannelConfigs(notification, privateKey) {
|
|
2921
|
+
var _a;
|
|
2922
|
+
const key = privateKey !== null && privateKey !== void 0 ? privateKey : (_a = this.product) === null || _a === void 0 ? void 0 : _a.private_key;
|
|
2923
|
+
if (!key)
|
|
2924
|
+
return notification;
|
|
2925
|
+
const envs = notification.envs || [];
|
|
2926
|
+
const decryptedEnvs = envs.map((env) => {
|
|
2927
|
+
const out = Object.assign({}, env);
|
|
2928
|
+
if (env.push_notifications) {
|
|
2929
|
+
try {
|
|
2930
|
+
out.push_notifications =
|
|
2931
|
+
typeof env.push_notifications === 'string' && env.push_notifications.includes(':')
|
|
2932
|
+
? JSON.parse((0, processor_utils_1.decrypt)(env.push_notifications, key))
|
|
2933
|
+
: env.push_notifications;
|
|
2934
|
+
}
|
|
2935
|
+
catch (_a) {
|
|
2936
|
+
out.push_notifications = env.push_notifications;
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
if (env.emails) {
|
|
2940
|
+
try {
|
|
2941
|
+
out.emails =
|
|
2942
|
+
typeof env.emails === 'string' && env.emails.includes(':')
|
|
2943
|
+
? JSON.parse((0, processor_utils_1.decrypt)(env.emails, key))
|
|
2944
|
+
: env.emails;
|
|
1550
2945
|
}
|
|
1551
|
-
|
|
1552
|
-
|
|
2946
|
+
catch (_b) {
|
|
2947
|
+
out.emails = env.emails;
|
|
1553
2948
|
}
|
|
1554
|
-
|
|
1555
|
-
|
|
2949
|
+
}
|
|
2950
|
+
if (env.callbacks) {
|
|
2951
|
+
try {
|
|
2952
|
+
out.callbacks =
|
|
2953
|
+
typeof env.callbacks === 'string' && env.callbacks.includes(':')
|
|
2954
|
+
? JSON.parse((0, processor_utils_1.decrypt)(env.callbacks, key))
|
|
2955
|
+
: env.callbacks;
|
|
1556
2956
|
}
|
|
1557
|
-
|
|
1558
|
-
|
|
2957
|
+
catch (_c) {
|
|
2958
|
+
out.callbacks = env.callbacks;
|
|
1559
2959
|
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
2960
|
+
}
|
|
2961
|
+
if (env.sms) {
|
|
2962
|
+
try {
|
|
2963
|
+
out.sms =
|
|
2964
|
+
typeof env.sms === 'string' && env.sms.includes(':')
|
|
2965
|
+
? JSON.parse((0, processor_utils_1.decrypt)(env.sms, key))
|
|
2966
|
+
: env.sms;
|
|
2967
|
+
}
|
|
2968
|
+
catch (_d) {
|
|
2969
|
+
out.sms = env.sms;
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2972
|
+
return out;
|
|
1568
2973
|
});
|
|
2974
|
+
return Object.assign(Object.assign({}, notification), { envs: decryptedEnvs });
|
|
2975
|
+
}
|
|
2976
|
+
async deleteNotification(tag) {
|
|
2977
|
+
try {
|
|
2978
|
+
const notification = await this.fetchNotification(tag);
|
|
2979
|
+
if (!notification) {
|
|
2980
|
+
throw new Error(`Notification with tag: ${tag} not found`);
|
|
2981
|
+
}
|
|
2982
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
2983
|
+
tag,
|
|
2984
|
+
component: enums_1.ProductComponents.NOTIFICATION,
|
|
2985
|
+
action: enums_1.RequestAction.DELETE,
|
|
2986
|
+
}, this.getUserAccess());
|
|
2987
|
+
}
|
|
2988
|
+
catch (e) {
|
|
2989
|
+
throw e;
|
|
2990
|
+
}
|
|
1569
2991
|
}
|
|
1570
2992
|
validateFeatureSequence(array) {
|
|
1571
2993
|
// Validate uniqueness of sequence_tag
|
|
@@ -1665,24 +3087,27 @@ class ProductsBuilderService {
|
|
|
1665
3087
|
await this.validateActionDataInput(data, action, event.input, event_index, sequence_index);
|
|
1666
3088
|
}
|
|
1667
3089
|
async checkAndValidateFunctionDataInput(data, sequence_index, event, event_index) {
|
|
1668
|
-
const func = this.fetchFunction(event.event);
|
|
3090
|
+
const func = (await this.fetchFunction(event.event));
|
|
1669
3091
|
await this.validateActionDataInput(data, func, event.input, event_index, sequence_index);
|
|
1670
3092
|
}
|
|
1671
3093
|
async checkAndValidateDBActionDataInput(data, sequence_index, event, event_index) {
|
|
1672
3094
|
console.log('EVENTY', event.event);
|
|
1673
|
-
const { filterData, data: dbData, filterTemplate, template } = this.fetchDatabaseAction(event.event);
|
|
3095
|
+
const { filterData, data: dbData, filterTemplate, template } = await this.fetchDatabaseAction(event.event);
|
|
1674
3096
|
await this.validateDBActionDataInput(data, { filterData, data: dbData, template, filter: filterTemplate }, event.input, event_index, sequence_index);
|
|
1675
3097
|
}
|
|
1676
3098
|
async checkAndValidateFeatureDataInput(data, sequence_index, event, event_index) {
|
|
1677
|
-
const
|
|
3099
|
+
const feature = await this.fetchFeature(event.event);
|
|
3100
|
+
if (!feature)
|
|
3101
|
+
throw new Error(`Feature ${event.event} not found`);
|
|
3102
|
+
const { input } = feature;
|
|
1678
3103
|
await this.validateFeatureDataInput(data, input, event.input, event_index, sequence_index);
|
|
1679
3104
|
}
|
|
1680
3105
|
async checkAndValidateNotificationDataInput(data, sequence_index, event, event_index) {
|
|
1681
|
-
const { callback_data: callback, push_notification_data: notification, email_data: email, sms_data: sms, } = this.fetchNotificationMessage(event.event);
|
|
3106
|
+
const { callback_data: callback, push_notification_data: notification, email_data: email, sms_data: sms, } = await this.fetchNotificationMessage(event.event);
|
|
1682
3107
|
await this.validateNotificationDataInput(data, { callback, notification, email, sms }, event.input, event_index, sequence_index);
|
|
1683
3108
|
}
|
|
1684
3109
|
async checkAndValidatePublishDataInput(data, sequence_index, event, event_index) {
|
|
1685
|
-
const topic = this.fetchMessageBrokerTopic(event.event);
|
|
3110
|
+
const topic = await this.fetchMessageBrokerTopic(event.event);
|
|
1686
3111
|
if (!topic) {
|
|
1687
3112
|
throw new Error(`Topic ${event.event} not registered`);
|
|
1688
3113
|
}
|
|
@@ -1690,14 +3115,14 @@ class ProductsBuilderService {
|
|
|
1690
3115
|
//await this.validatePublishTopicDataInput(data, { data: topicData }, event.input, event_index, sequence_index)
|
|
1691
3116
|
}
|
|
1692
3117
|
async checkAndValidateStorageDataInput(data, sequence_index, event, event_index) {
|
|
1693
|
-
const storage = this.fetchStorage(event.event);
|
|
3118
|
+
const storage = await this.fetchStorage(event.event);
|
|
1694
3119
|
if (!storage) {
|
|
1695
3120
|
throw new Error(`Storage ${event.event} does not exist`);
|
|
1696
3121
|
}
|
|
1697
3122
|
//await this.validateStorageDataInput(data, {}, event.input, event_index, sequence_index);
|
|
1698
3123
|
}
|
|
1699
3124
|
async checkAndValidateJobDataInput(data, sequence_index, event, event_index) {
|
|
1700
|
-
const job = this.fetchJob(event.event);
|
|
3125
|
+
const job = await this.fetchJob(event.event);
|
|
1701
3126
|
if (job.type === productsBuilder_types_1.JobEventTypes.ACTION) {
|
|
1702
3127
|
await this.checkAndValidateActionDataInput(data, sequence_index, event, event_index);
|
|
1703
3128
|
}
|
|
@@ -1713,9 +3138,6 @@ class ProductsBuilderService {
|
|
|
1713
3138
|
if (job.type === productsBuilder_types_1.JobEventTypes.PUBLISH) {
|
|
1714
3139
|
await this.checkAndValidatePublishDataInput(data, sequence_index, event, event_index);
|
|
1715
3140
|
}
|
|
1716
|
-
if (job.type === productsBuilder_types_1.JobEventTypes.FUNCTION) {
|
|
1717
|
-
await this.checkAndValidateFunctionDataInput(data, sequence_index, event, event_index);
|
|
1718
|
-
}
|
|
1719
3141
|
}
|
|
1720
3142
|
async checkAndValidateFallbackDataInput(data, sequence_index, event, event_index) { }
|
|
1721
3143
|
async validateEvent(data, sequence_index, event, event_index) {
|
|
@@ -1737,7 +3159,7 @@ class ProductsBuilderService {
|
|
|
1737
3159
|
await this.checkAndValidatePublishDataInput(data, sequence_index, event, event_index);
|
|
1738
3160
|
}
|
|
1739
3161
|
/*if (event.type === FeatureEventTypes.SUBSCRIBE) {
|
|
1740
|
-
const topic = this.fetchMessageBrokerTopic(event.event);
|
|
3162
|
+
const topic = await this.fetchMessageBrokerTopic(event.event);
|
|
1741
3163
|
|
|
1742
3164
|
if(!topic) {
|
|
1743
3165
|
throw new Error(`Topic ${event.event} not registered`);
|
|
@@ -1940,7 +3362,7 @@ class ProductsBuilderService {
|
|
|
1940
3362
|
});
|
|
1941
3363
|
}
|
|
1942
3364
|
async validateActionInputData(data, skipSample = false, option = false, optionIndex = 0) {
|
|
1943
|
-
var _a;
|
|
3365
|
+
var _a, _b;
|
|
1944
3366
|
const { obj } = data, base_data = __rest(data, ["obj"]);
|
|
1945
3367
|
if (!data.sample && Object.keys(obj).length === 0) {
|
|
1946
3368
|
return;
|
|
@@ -1948,8 +3370,8 @@ class ProductsBuilderService {
|
|
|
1948
3370
|
if (!data.sample) {
|
|
1949
3371
|
throw new Error('Something unexpected happened in validating action input');
|
|
1950
3372
|
}
|
|
1951
|
-
const sequence = data.feature.sequence[data.sequence_index];
|
|
1952
|
-
if (obj === undefined || obj === null) {
|
|
3373
|
+
const sequence = data.feature.sequence ? (_a = data.feature) === null || _a === void 0 ? void 0 : _a.sequence[data.sequence_index] : null;
|
|
3374
|
+
if ((obj === undefined || obj === null) && sequence) {
|
|
1953
3375
|
if (!option) {
|
|
1954
3376
|
throw new Error(`sequence ${sequence.tag} event ${sequence.events[data.event_index].event} ${data.type} should not be ${obj}`);
|
|
1955
3377
|
}
|
|
@@ -1957,7 +3379,7 @@ class ProductsBuilderService {
|
|
|
1957
3379
|
throw new Error(`option event index ${optionIndex}, ${data.type} should not be ${obj}`);
|
|
1958
3380
|
}
|
|
1959
3381
|
}
|
|
1960
|
-
if (Object.values(obj).length > 0 && ((
|
|
3382
|
+
if (sequence && Object.values(obj).length > 0 && ((_b = data.sample.data) === null || _b === void 0 ? void 0 : _b.length) === 0) {
|
|
1961
3383
|
if (!option) {
|
|
1962
3384
|
throw new Error(`sequence ${sequence.tag} event ${sequence.events[data.event_index].event} ${data.type} should be an empty object`);
|
|
1963
3385
|
}
|
|
@@ -1968,7 +3390,7 @@ class ProductsBuilderService {
|
|
|
1968
3390
|
if (Object.values(obj).length === 0 && data.sample.data.length === 0 /*data.sample?.data?.length === 0*/) {
|
|
1969
3391
|
return;
|
|
1970
3392
|
}
|
|
1971
|
-
if (Object.values(obj).length === 0 && data.sample.data.length > 0 && !skipSample) {
|
|
3393
|
+
if (sequence && Object.values(obj).length === 0 && data.sample.data.length > 0 && !skipSample) {
|
|
1972
3394
|
//console.log("validity err: ",obj, data.sample)
|
|
1973
3395
|
if (!option) {
|
|
1974
3396
|
throw new Error(`sequence ${sequence.tag} event ${sequence.events[data.event_index].event} ${data.type} should not be an empty object`);
|
|
@@ -2144,7 +3566,9 @@ class ProductsBuilderService {
|
|
|
2144
3566
|
let current_input = input;
|
|
2145
3567
|
for (let i = 0; i < stages.length; i++) {
|
|
2146
3568
|
let stage = stages[i];
|
|
2147
|
-
|
|
3569
|
+
// Convert to string for .match() call
|
|
3570
|
+
const stageStr = String(stage);
|
|
3571
|
+
const matches = stageStr.match(/^\[(\d+)\]$/);
|
|
2148
3572
|
if (matches && matches.length === 2) {
|
|
2149
3573
|
const number = parseInt(matches[1], 10);
|
|
2150
3574
|
if (!isNaN(number)) {
|
|
@@ -2200,14 +3624,16 @@ class ProductsBuilderService {
|
|
|
2200
3624
|
}
|
|
2201
3625
|
else {
|
|
2202
3626
|
//const envs =
|
|
2203
|
-
const app = this.fetchApp(access_tag);
|
|
3627
|
+
const app = await this.fetchApp(access_tag);
|
|
2204
3628
|
const { envs } = app;
|
|
2205
3629
|
await Promise.all(envs.map((env) => {
|
|
2206
3630
|
if (stages[0] !== env.auth.auth_tag) {
|
|
2207
3631
|
throw new Error(`Auth ${stages[0]} does not exist on env ${env.product_env_slug} on app ${access_tag}`);
|
|
2208
3632
|
}
|
|
2209
|
-
const decrypted = JSON.parse((0, processor_utils_1.decrypt)(env.auth.values, this.
|
|
2210
|
-
|
|
3633
|
+
const decrypted = JSON.parse((0, processor_utils_1.decrypt)(env.auth.values, this.product.private_key));
|
|
3634
|
+
// Convert stages to string[] for findFaultyKeys
|
|
3635
|
+
const stringStages = stages.slice(1).map((stage) => String(stage));
|
|
3636
|
+
const check = (0, objects_utils_1.findFaultyKeys)(stringStages, decrypted);
|
|
2211
3637
|
if (check.faultyKeys) {
|
|
2212
3638
|
throw new Error(`Auth Key(s) ${check.faultyKeys.join(', ')} is/are invalid, they do not exist in authorization for ${env.product_env_slug} on app ${access_tag}`);
|
|
2213
3639
|
}
|
|
@@ -2223,7 +3649,9 @@ class ProductsBuilderService {
|
|
|
2223
3649
|
let i = 1;
|
|
2224
3650
|
while (i < stages.length) {
|
|
2225
3651
|
let stage = stages[i];
|
|
2226
|
-
|
|
3652
|
+
// Convert to string for .match() call
|
|
3653
|
+
const stageStr = String(stage);
|
|
3654
|
+
const matches = stageStr.match(/^\[(\d+)\]$/);
|
|
2227
3655
|
if (matches && matches.length === 2) {
|
|
2228
3656
|
const number = parseInt(matches[1], 10);
|
|
2229
3657
|
if (!isNaN(number)) {
|
|
@@ -2297,11 +3725,15 @@ class ProductsBuilderService {
|
|
|
2297
3725
|
// let current_data;
|
|
2298
3726
|
if (i === 0) {
|
|
2299
3727
|
// find sequence by tag, see if it exists and its before current sequence
|
|
2300
|
-
|
|
2301
|
-
|
|
3728
|
+
// Convert stage to string for function calls
|
|
3729
|
+
const stageStr = String(stage);
|
|
3730
|
+
this.validateSequenceInputParents(stageStr, meta.sequence_index, meta.feature.sequence);
|
|
3731
|
+
sequence = this.fetchPriorSequence(meta, stageStr);
|
|
2302
3732
|
}
|
|
2303
3733
|
if (i === 1 && sequence) {
|
|
2304
|
-
|
|
3734
|
+
// Convert stage to string for function calls
|
|
3735
|
+
const stageStr = String(stage);
|
|
3736
|
+
event = this.fetchSequenceEvent(sequence, stageStr);
|
|
2305
3737
|
if (!event) {
|
|
2306
3738
|
throw new Error(`event ${stage} not found in sequence ${sequence.tag}`);
|
|
2307
3739
|
}
|
|
@@ -2330,7 +3762,9 @@ class ProductsBuilderService {
|
|
|
2330
3762
|
if (i > 1 && response) {
|
|
2331
3763
|
let parent_index = 0;
|
|
2332
3764
|
let increment = false;
|
|
2333
|
-
|
|
3765
|
+
// Convert to string for .match() call
|
|
3766
|
+
const stageStr = String(stage);
|
|
3767
|
+
const matches = stageStr.match(/^\[(\d+)\]$/);
|
|
2334
3768
|
if (matches && matches.length === 2) {
|
|
2335
3769
|
const number = parseInt(matches[1], 10);
|
|
2336
3770
|
if (!isNaN(number)) {
|
|
@@ -2388,7 +3822,7 @@ class ProductsBuilderService {
|
|
|
2388
3822
|
if (stages.length > 2) {
|
|
2389
3823
|
throw new Error(`sequence ${sequence.tag} event ${sequence.events[meta.event_index].event} ${meta.type}, has invalid varibale definition ${value}, only two keys is required`);
|
|
2390
3824
|
}
|
|
2391
|
-
const app = this.fetchApp(stages[0]);
|
|
3825
|
+
const app = await this.fetchApp(String(stages[0]));
|
|
2392
3826
|
if (!app) {
|
|
2393
3827
|
throw new Error(`App ${stages[0]} not found in sequence ${sequence.tag} event ${sequence.events[meta.event_index].event} ${meta.type}, has invalid varibale definition ${value}. `);
|
|
2394
3828
|
}
|
|
@@ -2405,8 +3839,8 @@ class ProductsBuilderService {
|
|
|
2405
3839
|
if (stages.length !== 2) {
|
|
2406
3840
|
throw new Error(`When using constants you need to specify the constant in the format $Constant{app_tag}{key} instead of ${value}`);
|
|
2407
3841
|
}
|
|
2408
|
-
const app_tag = stages[0];
|
|
2409
|
-
const key = stages[1];
|
|
3842
|
+
const app_tag = String(stages[0]);
|
|
3843
|
+
const key = String(stages[1]);
|
|
2410
3844
|
const _c = await this.fetchThirdPartyAppByAccessTag(app_tag), { version } = _c, app = __rest(_c, ["version"]);
|
|
2411
3845
|
if (!app) {
|
|
2412
3846
|
throw new Error(`App ${app_tag} not found in constant ${value}`);
|
|
@@ -2496,9 +3930,10 @@ class ProductsBuilderService {
|
|
|
2496
3930
|
return found;
|
|
2497
3931
|
}
|
|
2498
3932
|
validateActionKeyPlacement(data) {
|
|
3933
|
+
var _a;
|
|
2499
3934
|
const actionData = data.sample.data;
|
|
2500
3935
|
const { indexes } = data;
|
|
2501
|
-
const sequence = data.feature.sequence[data.sequence_index];
|
|
3936
|
+
const sequence = data.feature.sequence ? (_a = data.feature) === null || _a === void 0 ? void 0 : _a.sequence[data.sequence_index] : null;
|
|
2502
3937
|
const datapoint = actionData.find((item) => {
|
|
2503
3938
|
return (item.parent_key === indexes.parent_key && item.key === data.key && item.level === indexes.level //&&
|
|
2504
3939
|
//indexes.index === item.index
|
|
@@ -2506,7 +3941,12 @@ class ProductsBuilderService {
|
|
|
2506
3941
|
});
|
|
2507
3942
|
if (!datapoint) {
|
|
2508
3943
|
console.log('VALIDATE', data.key, data.value, actionData, indexes);
|
|
2509
|
-
|
|
3944
|
+
if (sequence) {
|
|
3945
|
+
throw new Error(`Key ${data.key} not found for ${data.type} for sequence ${sequence.tag} event ${sequence.events[data.event_index].event}`);
|
|
3946
|
+
}
|
|
3947
|
+
else {
|
|
3948
|
+
throw new Error(`Key ${data.key} not found`);
|
|
3949
|
+
}
|
|
2510
3950
|
}
|
|
2511
3951
|
return datapoint;
|
|
2512
3952
|
}
|
|
@@ -2537,12 +3977,11 @@ class ProductsBuilderService {
|
|
|
2537
3977
|
}
|
|
2538
3978
|
async createFeature(data, throwErrorIfExists = false) {
|
|
2539
3979
|
try {
|
|
2540
|
-
if (!this.fetchFeature(data.tag
|
|
3980
|
+
if (!(await this.fetchFeature(data.tag))) {
|
|
2541
3981
|
await validators_1.CreateProductFeatureSchema.validateAsync(data);
|
|
2542
3982
|
try {
|
|
2543
3983
|
await this.validateFeatureData(data);
|
|
2544
3984
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.FEATURE, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
2545
|
-
await this.initializeProduct(this.product_id);
|
|
2546
3985
|
}
|
|
2547
3986
|
catch (e) {
|
|
2548
3987
|
throw e;
|
|
@@ -2559,7 +3998,7 @@ class ProductsBuilderService {
|
|
|
2559
3998
|
}
|
|
2560
3999
|
async updateFeature(tag, data) {
|
|
2561
4000
|
try {
|
|
2562
|
-
const feature = this.fetchFeature(tag);
|
|
4001
|
+
const feature = await this.fetchFeature(tag);
|
|
2563
4002
|
if (!feature) {
|
|
2564
4003
|
throw new Error(`Feature ${tag} not found`);
|
|
2565
4004
|
}
|
|
@@ -2571,43 +4010,58 @@ class ProductsBuilderService {
|
|
|
2571
4010
|
}
|
|
2572
4011
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({ _id,
|
|
2573
4012
|
tag }, data), { component: enums_1.ProductComponents.FEATURE, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
2574
|
-
await this.initializeProduct(this.product_id);
|
|
2575
4013
|
}
|
|
2576
4014
|
catch (e) {
|
|
2577
4015
|
throw e;
|
|
2578
4016
|
}
|
|
2579
4017
|
}
|
|
2580
|
-
|
|
2581
|
-
const
|
|
2582
|
-
|
|
2583
|
-
throw new Error(`Feature ${tag} not found`);
|
|
2584
|
-
return feature;
|
|
4018
|
+
async fetchFeatures() {
|
|
4019
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'feature', this.getUserAccess());
|
|
4020
|
+
return components;
|
|
2585
4021
|
}
|
|
2586
|
-
|
|
2587
|
-
|
|
4022
|
+
async fetchFeature(tag) {
|
|
4023
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'feature', tag, this.getUserAccess());
|
|
4024
|
+
return component;
|
|
4025
|
+
}
|
|
4026
|
+
async deleteFeature(tag) {
|
|
4027
|
+
try {
|
|
4028
|
+
const feature = await this.fetchFeature(tag);
|
|
4029
|
+
if (!feature) {
|
|
4030
|
+
throw new Error(`Feature with tag: ${tag} not found`);
|
|
4031
|
+
}
|
|
4032
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4033
|
+
tag,
|
|
4034
|
+
component: enums_1.ProductComponents.FEATURE,
|
|
4035
|
+
action: enums_1.RequestAction.DELETE,
|
|
4036
|
+
}, this.getUserAccess());
|
|
4037
|
+
}
|
|
4038
|
+
catch (e) {
|
|
4039
|
+
throw e;
|
|
4040
|
+
}
|
|
2588
4041
|
}
|
|
2589
4042
|
async createDatabase(data, throwErrorIfExists = false) {
|
|
2590
4043
|
try {
|
|
2591
4044
|
// TODO: figure out a way to check if this has run before, halt if it has
|
|
2592
|
-
if (!this.fetchDatabase(data.tag
|
|
4045
|
+
if (!(await this.fetchDatabase(data.tag))) {
|
|
2593
4046
|
await validators_1.CreateProductDatabaseSchema.validateAsync(data);
|
|
2594
|
-
|
|
2595
|
-
|
|
4047
|
+
const processedEnvs = [];
|
|
4048
|
+
for (const env of data.envs) {
|
|
4049
|
+
const exists = await this.fetchEnv(env.slug);
|
|
2596
4050
|
if (!exists) {
|
|
2597
4051
|
throw new Error(`Env ${env.slug} does not exist`);
|
|
2598
4052
|
}
|
|
2599
|
-
env.connection_url = (0, processor_utils_1.encrypt)(env.connection_url, this.
|
|
2600
|
-
|
|
2601
|
-
}
|
|
2602
|
-
|
|
2603
|
-
envs.
|
|
4053
|
+
env.connection_url = (0, processor_utils_1.encrypt)(env.connection_url, this.product.private_key);
|
|
4054
|
+
processedEnvs.push(env);
|
|
4055
|
+
}
|
|
4056
|
+
data.envs = processedEnvs;
|
|
4057
|
+
const envs = await this.fetchEnvs();
|
|
4058
|
+
for (const env of envs) {
|
|
2604
4059
|
const exists = data.envs.findIndex((dbEnv) => dbEnv.slug === env.slug);
|
|
2605
4060
|
if (exists === -1) {
|
|
2606
4061
|
throw new Error(`Product env ${env.slug} is not defined, please provide connection details`);
|
|
2607
4062
|
}
|
|
2608
|
-
}
|
|
4063
|
+
}
|
|
2609
4064
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.DATABASE, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
2610
|
-
await this.initializeProduct(this.product_id);
|
|
2611
4065
|
}
|
|
2612
4066
|
else {
|
|
2613
4067
|
if (throwErrorIfExists)
|
|
@@ -2620,7 +4074,7 @@ class ProductsBuilderService {
|
|
|
2620
4074
|
}
|
|
2621
4075
|
async updateDatabase(tag, data) {
|
|
2622
4076
|
try {
|
|
2623
|
-
const db = this.fetchDatabase(tag);
|
|
4077
|
+
const db = await this.fetchDatabase(tag);
|
|
2624
4078
|
if (!db) {
|
|
2625
4079
|
throw new Error(`Database ${tag} not found`);
|
|
2626
4080
|
}
|
|
@@ -2629,15 +4083,16 @@ class ProductsBuilderService {
|
|
|
2629
4083
|
if (data.tag && this.fetchDatabase(data.tag)) {
|
|
2630
4084
|
throw new Error(`tag ${tag} is in use`); // TODO: also check on the backend
|
|
2631
4085
|
}
|
|
2632
|
-
data.envs = data.envs.map((env) => {
|
|
2633
|
-
const exists = this.fetchEnv(env.slug);
|
|
4086
|
+
data.envs = await Promise.all(data.envs.map(async (env) => {
|
|
4087
|
+
const exists = await this.fetchEnv(env.slug);
|
|
2634
4088
|
if (!exists) {
|
|
2635
4089
|
throw new Error(`Env ${env.slug} does not exist`);
|
|
2636
4090
|
}
|
|
2637
|
-
if (env.connection_url)
|
|
2638
|
-
env.connection_url = (0, processor_utils_1.encrypt)(env.connection_url, this.
|
|
4091
|
+
if (env.connection_url) {
|
|
4092
|
+
env.connection_url = (0, processor_utils_1.encrypt)(env.connection_url, this.product.private_key);
|
|
4093
|
+
}
|
|
2639
4094
|
return env;
|
|
2640
|
-
});
|
|
4095
|
+
}));
|
|
2641
4096
|
const overwrite = [];
|
|
2642
4097
|
const newEnvs = [];
|
|
2643
4098
|
data.envs.map((dataEnv) => {
|
|
@@ -2666,23 +4121,348 @@ class ProductsBuilderService {
|
|
|
2666
4121
|
data.envs = [...unchanged, ...overwrite, ...newEnvs];
|
|
2667
4122
|
//console.log("UPDATED!!!", JSON.stringify(data.envs))
|
|
2668
4123
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({ _id }, data), { tag, component: enums_1.ProductComponents.DATABASE, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
2669
|
-
await this.initializeProduct(this.product_id);
|
|
2670
4124
|
}
|
|
2671
4125
|
catch (e) {
|
|
2672
4126
|
throw e;
|
|
2673
4127
|
}
|
|
2674
4128
|
}
|
|
2675
|
-
|
|
2676
|
-
const
|
|
2677
|
-
|
|
2678
|
-
|
|
4129
|
+
async fetchDatabases() {
|
|
4130
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'database', this.getUserAccess());
|
|
4131
|
+
const decryptedComponents = components.map((component) => {
|
|
4132
|
+
const dbComponent = component;
|
|
4133
|
+
const decryptedEnvs = dbComponent.envs.map((env) => {
|
|
4134
|
+
return Object.assign(Object.assign({}, env), { connection_url: (0, processor_utils_1.decrypt)(env.connection_url, this.product.private_key) });
|
|
4135
|
+
});
|
|
4136
|
+
return Object.assign(Object.assign({}, dbComponent), { envs: decryptedEnvs });
|
|
2679
4137
|
});
|
|
2680
|
-
|
|
2681
|
-
throw new Error(`Database ${tag} not found`);
|
|
2682
|
-
return database;
|
|
4138
|
+
return decryptedComponents;
|
|
2683
4139
|
}
|
|
2684
|
-
|
|
2685
|
-
|
|
4140
|
+
async fetchDatabase(tag) {
|
|
4141
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'database', tag, this.getUserAccess());
|
|
4142
|
+
if (component) {
|
|
4143
|
+
const decryptedEnvs = component.envs.map((env) => {
|
|
4144
|
+
return Object.assign(Object.assign({}, env), { connection_url: (0, processor_utils_1.decrypt)(env.connection_url, this.product.private_key) });
|
|
4145
|
+
});
|
|
4146
|
+
return Object.assign(Object.assign({}, component), { envs: decryptedEnvs });
|
|
4147
|
+
}
|
|
4148
|
+
return component;
|
|
4149
|
+
}
|
|
4150
|
+
async deleteDatabase(tag) {
|
|
4151
|
+
try {
|
|
4152
|
+
const database = await this.fetchDatabase(tag);
|
|
4153
|
+
if (!database) {
|
|
4154
|
+
throw new Error(`Database with tag: ${tag} not found`);
|
|
4155
|
+
}
|
|
4156
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4157
|
+
tag,
|
|
4158
|
+
component: enums_1.ProductComponents.DATABASE,
|
|
4159
|
+
action: enums_1.RequestAction.DELETE,
|
|
4160
|
+
}, this.getUserAccess());
|
|
4161
|
+
}
|
|
4162
|
+
catch (e) {
|
|
4163
|
+
throw e;
|
|
4164
|
+
}
|
|
4165
|
+
}
|
|
4166
|
+
// GRAPH CRUD METHODS
|
|
4167
|
+
async createGraph(data, throwErrorIfExists = false) {
|
|
4168
|
+
var _a, _b, _c;
|
|
4169
|
+
console.log('[ProductsService.createGraph] Starting graph creation:', {
|
|
4170
|
+
tag: data.tag,
|
|
4171
|
+
name: data.name,
|
|
4172
|
+
type: data.type,
|
|
4173
|
+
envsCount: (_a = data.envs) === null || _a === void 0 ? void 0 : _a.length,
|
|
4174
|
+
productTag: (_b = this.product) === null || _b === void 0 ? void 0 : _b.tag,
|
|
4175
|
+
});
|
|
4176
|
+
try {
|
|
4177
|
+
if (!(await this.fetchGraph(data.tag))) {
|
|
4178
|
+
await validators_1.CreateProductGraphSchema.validateAsync(data);
|
|
4179
|
+
const processedEnvs = [];
|
|
4180
|
+
for (const env of data.envs) {
|
|
4181
|
+
console.log('[ProductsService.createGraph] Processing env:', {
|
|
4182
|
+
slug: env.slug,
|
|
4183
|
+
hasConnectionUrl: !!env.connection_url,
|
|
4184
|
+
hasUsername: !!env.username,
|
|
4185
|
+
hasPassword: !!env.password,
|
|
4186
|
+
});
|
|
4187
|
+
const exists = await this.fetchEnv(env.slug);
|
|
4188
|
+
if (!exists) {
|
|
4189
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
4190
|
+
}
|
|
4191
|
+
// Store connection URL as secret
|
|
4192
|
+
console.log('[ProductsService.createGraph] Converting connection URL to secret for env:', env.slug);
|
|
4193
|
+
const originalUrl = env.connection_url;
|
|
4194
|
+
env.connection_url = await this.storeGraphConnectionUrlAsSecret(env.connection_url, data.tag, env.slug);
|
|
4195
|
+
console.log('[ProductsService.createGraph] Connection URL after secret conversion:', {
|
|
4196
|
+
wasConverted: originalUrl !== env.connection_url,
|
|
4197
|
+
isSecretRef: (_c = env.connection_url) === null || _c === void 0 ? void 0 : _c.startsWith('$Secret{'),
|
|
4198
|
+
});
|
|
4199
|
+
env.connection_url = (0, processor_utils_1.encrypt)(env.connection_url, this.product.private_key);
|
|
4200
|
+
console.log('[ProductsService.createGraph] Connection URL encrypted');
|
|
4201
|
+
// Encrypt username and password if provided
|
|
4202
|
+
if (env.username) {
|
|
4203
|
+
console.log('[ProductsService.createGraph] Encrypting username for env:', env.slug);
|
|
4204
|
+
env.username = (0, processor_utils_1.encrypt)(env.username, this.product.private_key);
|
|
4205
|
+
}
|
|
4206
|
+
if (env.password) {
|
|
4207
|
+
console.log('[ProductsService.createGraph] Encrypting password for env:', env.slug);
|
|
4208
|
+
env.password = (0, processor_utils_1.encrypt)(env.password, this.product.private_key);
|
|
4209
|
+
}
|
|
4210
|
+
processedEnvs.push(env);
|
|
4211
|
+
console.log('[ProductsService.createGraph] Env processed successfully:', env.slug);
|
|
4212
|
+
}
|
|
4213
|
+
data.envs = processedEnvs;
|
|
4214
|
+
console.log('[ProductsService.createGraph] All envs processed, total:', processedEnvs.length);
|
|
4215
|
+
const envs = await this.fetchEnvs();
|
|
4216
|
+
for (const env of envs) {
|
|
4217
|
+
const exists = data.envs.findIndex((graphEnv) => graphEnv.slug === env.slug);
|
|
4218
|
+
if (exists === -1) {
|
|
4219
|
+
throw new Error(`Product env ${env.slug} is not defined, please provide connection details`);
|
|
4220
|
+
}
|
|
4221
|
+
}
|
|
4222
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.GRAPH, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
4223
|
+
}
|
|
4224
|
+
else {
|
|
4225
|
+
if (throwErrorIfExists)
|
|
4226
|
+
throw new Error(`Graph ${data.tag} already exists`);
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
catch (e) {
|
|
4230
|
+
throw e;
|
|
4231
|
+
}
|
|
4232
|
+
}
|
|
4233
|
+
async updateGraph(tag, data) {
|
|
4234
|
+
var _a, _b;
|
|
4235
|
+
console.log('[ProductsService.updateGraph] Starting graph update:', {
|
|
4236
|
+
tag,
|
|
4237
|
+
newTag: data.tag,
|
|
4238
|
+
name: data.name,
|
|
4239
|
+
type: data.type,
|
|
4240
|
+
envsCount: (_a = data.envs) === null || _a === void 0 ? void 0 : _a.length,
|
|
4241
|
+
productTag: (_b = this.product) === null || _b === void 0 ? void 0 : _b.tag,
|
|
4242
|
+
});
|
|
4243
|
+
try {
|
|
4244
|
+
const graph = await this.fetchGraph(tag);
|
|
4245
|
+
if (!graph) {
|
|
4246
|
+
throw new Error(`Graph ${tag} not found`);
|
|
4247
|
+
}
|
|
4248
|
+
const { _id, envs } = graph;
|
|
4249
|
+
console.log('[ProductsService.updateGraph] Found existing graph:', {
|
|
4250
|
+
_id,
|
|
4251
|
+
existingEnvsCount: envs === null || envs === void 0 ? void 0 : envs.length,
|
|
4252
|
+
});
|
|
4253
|
+
await validators_1.UpdateProductGraphSchema.validateAsync(data);
|
|
4254
|
+
if (data.tag && this.fetchGraph(data.tag)) {
|
|
4255
|
+
throw new Error(`tag ${tag} is in use`);
|
|
4256
|
+
}
|
|
4257
|
+
console.log('[ProductsService.updateGraph] Processing envs update');
|
|
4258
|
+
data.envs = await Promise.all(data.envs.map(async (env) => {
|
|
4259
|
+
var _a;
|
|
4260
|
+
console.log('[ProductsService.updateGraph] Processing env:', {
|
|
4261
|
+
slug: env.slug,
|
|
4262
|
+
hasConnectionUrl: !!env.connection_url,
|
|
4263
|
+
hasUsername: !!env.username,
|
|
4264
|
+
hasPassword: !!env.password,
|
|
4265
|
+
});
|
|
4266
|
+
const exists = await this.fetchEnv(env.slug);
|
|
4267
|
+
if (!exists) {
|
|
4268
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
4269
|
+
}
|
|
4270
|
+
if (env.connection_url) {
|
|
4271
|
+
// Store connection URL as secret
|
|
4272
|
+
console.log('[ProductsService.updateGraph] Converting connection URL to secret for env:', env.slug);
|
|
4273
|
+
const originalUrl = env.connection_url;
|
|
4274
|
+
env.connection_url = await this.storeGraphConnectionUrlAsSecret(env.connection_url, data.tag || tag, env.slug);
|
|
4275
|
+
console.log('[ProductsService.updateGraph] Connection URL after secret conversion:', {
|
|
4276
|
+
wasConverted: originalUrl !== env.connection_url,
|
|
4277
|
+
isSecretRef: (_a = env.connection_url) === null || _a === void 0 ? void 0 : _a.startsWith('$Secret{'),
|
|
4278
|
+
});
|
|
4279
|
+
env.connection_url = (0, processor_utils_1.encrypt)(env.connection_url, this.product.private_key);
|
|
4280
|
+
console.log('[ProductsService.updateGraph] Connection URL encrypted');
|
|
4281
|
+
}
|
|
4282
|
+
// Encrypt username and password if provided
|
|
4283
|
+
if (env.username) {
|
|
4284
|
+
console.log('[ProductsService.updateGraph] Encrypting username for env:', env.slug);
|
|
4285
|
+
env.username = (0, processor_utils_1.encrypt)(env.username, this.product.private_key);
|
|
4286
|
+
}
|
|
4287
|
+
if (env.password) {
|
|
4288
|
+
console.log('[ProductsService.updateGraph] Encrypting password for env:', env.slug);
|
|
4289
|
+
env.password = (0, processor_utils_1.encrypt)(env.password, this.product.private_key);
|
|
4290
|
+
}
|
|
4291
|
+
console.log('[ProductsService.updateGraph] Env processed successfully:', env.slug);
|
|
4292
|
+
return env;
|
|
4293
|
+
}));
|
|
4294
|
+
const overwrite = [];
|
|
4295
|
+
const newEnvs = [];
|
|
4296
|
+
data.envs.map((dataEnv) => {
|
|
4297
|
+
const exists = envs.findIndex((env) => env.slug === dataEnv.slug);
|
|
4298
|
+
if (!this.fetchEnv(dataEnv.slug)) {
|
|
4299
|
+
throw new Error(`Product Environment ${dataEnv.slug} doesn't exist`);
|
|
4300
|
+
}
|
|
4301
|
+
if (exists === -1) {
|
|
4302
|
+
if (!dataEnv.connection_url) {
|
|
4303
|
+
throw new Error(`connection_url is required for new env ${data.envs[exists].slug}`);
|
|
4304
|
+
}
|
|
4305
|
+
newEnvs.push(dataEnv);
|
|
4306
|
+
}
|
|
4307
|
+
else {
|
|
4308
|
+
overwrite.push(Object.assign(Object.assign({}, envs[exists]), dataEnv));
|
|
4309
|
+
}
|
|
4310
|
+
});
|
|
4311
|
+
const unchanged = [];
|
|
4312
|
+
envs.map((env) => {
|
|
4313
|
+
const newEnv = newEnvs.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
4314
|
+
const overwriteEnv = overwrite.findIndex((dataEnv) => env.slug === dataEnv.slug) > -1;
|
|
4315
|
+
if (!newEnv && !overwriteEnv) {
|
|
4316
|
+
unchanged.push(env);
|
|
4317
|
+
}
|
|
4318
|
+
});
|
|
4319
|
+
data.envs = [...unchanged, ...overwrite, ...newEnvs];
|
|
4320
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({ _id }, data), { tag, component: enums_1.ProductComponents.GRAPH, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
4321
|
+
}
|
|
4322
|
+
catch (e) {
|
|
4323
|
+
throw e;
|
|
4324
|
+
}
|
|
4325
|
+
}
|
|
4326
|
+
async fetchGraphs() {
|
|
4327
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'graph', this.getUserAccess());
|
|
4328
|
+
// Decrypt sensitive fields in graph envs
|
|
4329
|
+
const decryptedComponents = components.map((component) => {
|
|
4330
|
+
const graphComponent = component;
|
|
4331
|
+
const decryptedEnvs = graphComponent.envs.map((env) => {
|
|
4332
|
+
return Object.assign(Object.assign({}, env), { connection_url: env.connection_url ? (0, processor_utils_1.decrypt)(env.connection_url, this.product.private_key) : env.connection_url, username: env.username ? (0, processor_utils_1.decrypt)(env.username, this.product.private_key) : env.username, password: env.password ? (0, processor_utils_1.decrypt)(env.password, this.product.private_key) : env.password, graphName: env.graphName ? (0, processor_utils_1.decrypt)(env.graphName, this.product.private_key) : env.graphName, region: env.region ? (0, processor_utils_1.decrypt)(env.region, this.product.private_key) : env.region });
|
|
4333
|
+
});
|
|
4334
|
+
return Object.assign(Object.assign({}, graphComponent), { envs: decryptedEnvs });
|
|
4335
|
+
});
|
|
4336
|
+
return decryptedComponents;
|
|
4337
|
+
}
|
|
4338
|
+
async fetchGraph(tag) {
|
|
4339
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'graph', tag, this.getUserAccess());
|
|
4340
|
+
if (component) {
|
|
4341
|
+
// Decrypt sensitive fields in graph envs
|
|
4342
|
+
const decryptedEnvs = component.envs.map((env) => {
|
|
4343
|
+
return Object.assign(Object.assign({}, env), { connection_url: env.connection_url ? (0, processor_utils_1.decrypt)(env.connection_url, this.product.private_key) : env.connection_url, username: env.username ? (0, processor_utils_1.decrypt)(env.username, this.product.private_key) : env.username, password: env.password ? (0, processor_utils_1.decrypt)(env.password, this.product.private_key) : env.password, graphName: env.graphName ? (0, processor_utils_1.decrypt)(env.graphName, this.product.private_key) : env.graphName, region: env.region ? (0, processor_utils_1.decrypt)(env.region, this.product.private_key) : env.region });
|
|
4344
|
+
});
|
|
4345
|
+
return Object.assign(Object.assign({}, component), { envs: decryptedEnvs });
|
|
4346
|
+
}
|
|
4347
|
+
return component;
|
|
4348
|
+
}
|
|
4349
|
+
async deleteGraph(tag) {
|
|
4350
|
+
try {
|
|
4351
|
+
const graph = await this.fetchGraph(tag);
|
|
4352
|
+
if (!graph) {
|
|
4353
|
+
throw new Error(`Graph with tag: ${tag} not found`);
|
|
4354
|
+
}
|
|
4355
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4356
|
+
tag,
|
|
4357
|
+
component: enums_1.ProductComponents.GRAPH,
|
|
4358
|
+
action: enums_1.RequestAction.DELETE,
|
|
4359
|
+
}, this.getUserAccess());
|
|
4360
|
+
}
|
|
4361
|
+
catch (e) {
|
|
4362
|
+
throw e;
|
|
4363
|
+
}
|
|
4364
|
+
}
|
|
4365
|
+
// ==================== GRAPH ACTIONS ====================
|
|
4366
|
+
async createGraphAction(graphTag, data) {
|
|
4367
|
+
try {
|
|
4368
|
+
const graph = await this.fetchGraph(graphTag);
|
|
4369
|
+
if (!graph) {
|
|
4370
|
+
throw new Error(`Graph with tag: ${graphTag} not found`);
|
|
4371
|
+
}
|
|
4372
|
+
// Initialize actions array if it doesn't exist
|
|
4373
|
+
if (!graph.actions) {
|
|
4374
|
+
graph.actions = [];
|
|
4375
|
+
}
|
|
4376
|
+
// Check if action already exists
|
|
4377
|
+
const existingAction = graph.actions.find((a) => a.tag === data.tag);
|
|
4378
|
+
if (existingAction) {
|
|
4379
|
+
throw new Error(`Action with tag: ${data.tag} already exists`);
|
|
4380
|
+
}
|
|
4381
|
+
graph.actions.push(data);
|
|
4382
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4383
|
+
tag: graphTag,
|
|
4384
|
+
actions: graph.actions,
|
|
4385
|
+
component: enums_1.ProductComponents.GRAPH,
|
|
4386
|
+
action: enums_1.RequestAction.UPDATE,
|
|
4387
|
+
}, this.getUserAccess());
|
|
4388
|
+
}
|
|
4389
|
+
catch (e) {
|
|
4390
|
+
throw e;
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4393
|
+
async updateGraphAction(graphTag, actionTag, data) {
|
|
4394
|
+
try {
|
|
4395
|
+
const graph = await this.fetchGraph(graphTag);
|
|
4396
|
+
if (!graph) {
|
|
4397
|
+
throw new Error(`Graph with tag: ${graphTag} not found`);
|
|
4398
|
+
}
|
|
4399
|
+
if (!graph.actions) {
|
|
4400
|
+
throw new Error(`Action with tag: ${actionTag} not found`);
|
|
4401
|
+
}
|
|
4402
|
+
const actionIndex = graph.actions.findIndex((a) => a.tag === actionTag);
|
|
4403
|
+
if (actionIndex === -1) {
|
|
4404
|
+
throw new Error(`Action with tag: ${actionTag} not found`);
|
|
4405
|
+
}
|
|
4406
|
+
graph.actions[actionIndex] = Object.assign(Object.assign({}, graph.actions[actionIndex]), data);
|
|
4407
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4408
|
+
tag: graphTag,
|
|
4409
|
+
actions: graph.actions,
|
|
4410
|
+
component: enums_1.ProductComponents.GRAPH,
|
|
4411
|
+
action: enums_1.RequestAction.UPDATE,
|
|
4412
|
+
}, this.getUserAccess());
|
|
4413
|
+
}
|
|
4414
|
+
catch (e) {
|
|
4415
|
+
throw e;
|
|
4416
|
+
}
|
|
4417
|
+
}
|
|
4418
|
+
async fetchGraphAction(graphTag, actionTag) {
|
|
4419
|
+
try {
|
|
4420
|
+
const graph = await this.fetchGraph(graphTag);
|
|
4421
|
+
if (!graph || !graph.actions) {
|
|
4422
|
+
return null;
|
|
4423
|
+
}
|
|
4424
|
+
return graph.actions.find((a) => a.tag === actionTag) || null;
|
|
4425
|
+
}
|
|
4426
|
+
catch (e) {
|
|
4427
|
+
throw e;
|
|
4428
|
+
}
|
|
4429
|
+
}
|
|
4430
|
+
async fetchGraphActions(graphTag) {
|
|
4431
|
+
try {
|
|
4432
|
+
const graph = await this.fetchGraph(graphTag);
|
|
4433
|
+
if (!graph) {
|
|
4434
|
+
throw new Error(`Graph with tag: ${graphTag} not found`);
|
|
4435
|
+
}
|
|
4436
|
+
return graph.actions || [];
|
|
4437
|
+
}
|
|
4438
|
+
catch (e) {
|
|
4439
|
+
throw e;
|
|
4440
|
+
}
|
|
4441
|
+
}
|
|
4442
|
+
async deleteGraphAction(graphTag, actionTag) {
|
|
4443
|
+
try {
|
|
4444
|
+
const graph = await this.fetchGraph(graphTag);
|
|
4445
|
+
if (!graph) {
|
|
4446
|
+
throw new Error(`Graph with tag: ${graphTag} not found`);
|
|
4447
|
+
}
|
|
4448
|
+
if (!graph.actions) {
|
|
4449
|
+
throw new Error(`Action with tag: ${actionTag} not found`);
|
|
4450
|
+
}
|
|
4451
|
+
const actionIndex = graph.actions.findIndex((a) => a.tag === actionTag);
|
|
4452
|
+
if (actionIndex === -1) {
|
|
4453
|
+
throw new Error(`Action with tag: ${actionTag} not found`);
|
|
4454
|
+
}
|
|
4455
|
+
graph.actions.splice(actionIndex, 1);
|
|
4456
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4457
|
+
tag: graphTag,
|
|
4458
|
+
actions: graph.actions,
|
|
4459
|
+
component: enums_1.ProductComponents.GRAPH,
|
|
4460
|
+
action: enums_1.RequestAction.UPDATE,
|
|
4461
|
+
}, this.getUserAccess());
|
|
4462
|
+
}
|
|
4463
|
+
catch (e) {
|
|
4464
|
+
throw e;
|
|
4465
|
+
}
|
|
2686
4466
|
}
|
|
2687
4467
|
async createDatabaseAction(data, throwErrorIfExists = false) {
|
|
2688
4468
|
try {
|
|
@@ -2693,10 +4473,10 @@ class ProductsBuilderService {
|
|
|
2693
4473
|
if (!databaseTag || !tag) {
|
|
2694
4474
|
throw new Error(`tag is expected to be defined as "database_tag:action_tag"`);
|
|
2695
4475
|
}
|
|
2696
|
-
const exists = this.fetchDatabaseAction(data.tag);
|
|
4476
|
+
const exists = await this.fetchDatabaseAction(data.tag);
|
|
2697
4477
|
data.tag = tag;
|
|
2698
4478
|
if (!exists) {
|
|
2699
|
-
const database = this.fetchDatabase(databaseTag);
|
|
4479
|
+
const database = await this.fetchDatabase(databaseTag);
|
|
2700
4480
|
let values, template;
|
|
2701
4481
|
if (database.type === productsBuilder_types_1.DatabaseTypes.MONGODB) {
|
|
2702
4482
|
await create_productDatabaseAction_validator_1.NOSQLDatabaseActionsSchema.validateAsync(data);
|
|
@@ -2720,7 +4500,6 @@ class ProductsBuilderService {
|
|
|
2720
4500
|
}
|
|
2721
4501
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { data: values, template,
|
|
2722
4502
|
databaseTag, component: enums_1.ProductComponents.DATABASE_ACTION, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
2723
|
-
await this.initializeProduct(this.product_id);
|
|
2724
4503
|
}
|
|
2725
4504
|
else {
|
|
2726
4505
|
if (throwErrorIfExists)
|
|
@@ -2731,7 +4510,7 @@ class ProductsBuilderService {
|
|
|
2731
4510
|
throw e;
|
|
2732
4511
|
}
|
|
2733
4512
|
}
|
|
2734
|
-
fetchDatabaseAction(tag, throwErrorIfExists = false) {
|
|
4513
|
+
async fetchDatabaseAction(tag, throwErrorIfExists = false) {
|
|
2735
4514
|
const [databaseTag, actionTag] = tag.split(':');
|
|
2736
4515
|
if (!databaseTag || !actionTag) {
|
|
2737
4516
|
throw new Error(`tag is expected to be defined as "database_tag:action_tag"`);
|
|
@@ -2758,7 +4537,7 @@ class ProductsBuilderService {
|
|
|
2758
4537
|
throw new Error(`tag is expected to be defined as "database_tag:action_tag"`);
|
|
2759
4538
|
}
|
|
2760
4539
|
// Fetch required data
|
|
2761
|
-
const database = await this.fetchDatabase(databaseTag
|
|
4540
|
+
const database = await this.fetchDatabase(databaseTag);
|
|
2762
4541
|
const action = await this.fetchDatabaseAction(data.tag, true);
|
|
2763
4542
|
// Construct payload
|
|
2764
4543
|
const payload = Object.assign(Object.assign(Object.assign({}, action), data), { databaseTag, component: enums_1.ProductComponents.DATABASE_ACTION, action: enums_1.RequestAction.UPDATE });
|
|
@@ -2786,13 +4565,12 @@ class ProductsBuilderService {
|
|
|
2786
4565
|
}
|
|
2787
4566
|
// Update product and reinitialize
|
|
2788
4567
|
await this.productApi.updateProduct(this.product_id, payload, this.getUserAccess());
|
|
2789
|
-
await this.initializeProduct(this.product_id);
|
|
2790
4568
|
}
|
|
2791
4569
|
catch (error) {
|
|
2792
4570
|
throw error;
|
|
2793
4571
|
}
|
|
2794
4572
|
}
|
|
2795
|
-
fetchDatabaseActions(databaseTag) {
|
|
4573
|
+
async fetchDatabaseActions(databaseTag) {
|
|
2796
4574
|
const database = this.product.databases.find((data) => data.tag === databaseTag);
|
|
2797
4575
|
if (!database)
|
|
2798
4576
|
throw new Error(`Database ${databaseTag} not found`);
|
|
@@ -2802,7 +4580,28 @@ class ProductsBuilderService {
|
|
|
2802
4580
|
return{ ...data,template: JSON.parse(String(data.template))}
|
|
2803
4581
|
})*/
|
|
2804
4582
|
}
|
|
2805
|
-
return actions;
|
|
4583
|
+
return actions;
|
|
4584
|
+
}
|
|
4585
|
+
async deleteDatabaseAction(tag) {
|
|
4586
|
+
try {
|
|
4587
|
+
const [databaseTag, actionTag] = tag.split(':');
|
|
4588
|
+
if (!databaseTag || !actionTag) {
|
|
4589
|
+
throw new Error(`tag is expected to be defined as "database_tag:action_tag"`);
|
|
4590
|
+
}
|
|
4591
|
+
const action = await this.fetchDatabaseAction(tag, true);
|
|
4592
|
+
if (!action) {
|
|
4593
|
+
throw new Error(`Database action with tag: ${tag} not found`);
|
|
4594
|
+
}
|
|
4595
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4596
|
+
tag: actionTag,
|
|
4597
|
+
databaseTag,
|
|
4598
|
+
component: enums_1.ProductComponents.DATABASE_ACTION,
|
|
4599
|
+
action: enums_1.RequestAction.DELETE,
|
|
4600
|
+
}, this.getUserAccess());
|
|
4601
|
+
}
|
|
4602
|
+
catch (e) {
|
|
4603
|
+
throw e;
|
|
4604
|
+
}
|
|
2806
4605
|
}
|
|
2807
4606
|
async createDatabaseMigration(data, throwErrorIfExists) {
|
|
2808
4607
|
if (!data.tag) {
|
|
@@ -2812,22 +4611,48 @@ class ProductsBuilderService {
|
|
|
2812
4611
|
if (!databaseTag || !tag) {
|
|
2813
4612
|
throw new Error(`tag is expected to be defined as "database_tag:migration_tag"`);
|
|
2814
4613
|
}
|
|
2815
|
-
const exists = this.fetchDatabaseMigration(data.tag);
|
|
4614
|
+
const exists = await this.fetchDatabaseMigration(data.tag);
|
|
2816
4615
|
data.tag = tag;
|
|
2817
|
-
await create_productDatabaseMigration_validator_1.default.validateAsync(Object.assign(Object.assign({}, data), { databaseTag }));
|
|
4616
|
+
await create_productDatabaseMigration_validator_1.default.validateAsync(Object.assign(Object.assign({}, data), { databaseTag }));
|
|
2818
4617
|
if (!exists) {
|
|
2819
|
-
const database = this.fetchDatabase(databaseTag
|
|
4618
|
+
const database = await this.fetchDatabase(databaseTag);
|
|
2820
4619
|
if (database.type === productsBuilder_types_1.DatabaseTypes.MONGODB) {
|
|
2821
4620
|
throw new Error(`${database.type} does not support migrations`);
|
|
2822
4621
|
}
|
|
2823
|
-
|
|
2824
|
-
|
|
4622
|
+
// Process migration value - supports both simple strings and rich operations
|
|
4623
|
+
let processedValue = data.value;
|
|
4624
|
+
if (data.value) {
|
|
4625
|
+
processedValue = {
|
|
4626
|
+
up: this.processMigrationOperations(data.value.up),
|
|
4627
|
+
down: this.processMigrationOperations(data.value.down),
|
|
4628
|
+
};
|
|
4629
|
+
}
|
|
4630
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { value: processedValue, databaseTag, component: enums_1.ProductComponents.DATABASE_MIGRATION }), this.getUserAccess());
|
|
2825
4631
|
}
|
|
2826
4632
|
else {
|
|
2827
4633
|
if (throwErrorIfExists)
|
|
2828
|
-
throw new Error(`Database
|
|
4634
|
+
throw new Error(`Database Migration ${data.tag} already exists`);
|
|
2829
4635
|
}
|
|
2830
4636
|
}
|
|
4637
|
+
/**
|
|
4638
|
+
* Process migration operations - handles both string and object formats
|
|
4639
|
+
* Strings are passed through as-is (raw SQL/CQL)
|
|
4640
|
+
* Objects are serialized for storage and executed by the migration engine
|
|
4641
|
+
*/
|
|
4642
|
+
processMigrationOperations(operations) {
|
|
4643
|
+
if (!operations || !Array.isArray(operations))
|
|
4644
|
+
return [];
|
|
4645
|
+
return operations.map((op) => {
|
|
4646
|
+
if (typeof op === 'string') {
|
|
4647
|
+
return op; // Raw SQL/CQL string
|
|
4648
|
+
}
|
|
4649
|
+
// Rich operation object - validate it has required 'type' field
|
|
4650
|
+
if (typeof op === 'object' && op !== null && 'type' in op) {
|
|
4651
|
+
return op;
|
|
4652
|
+
}
|
|
4653
|
+
throw new Error(`Invalid migration operation format. Expected string or object with 'type' field.`);
|
|
4654
|
+
});
|
|
4655
|
+
}
|
|
2831
4656
|
async updateDatabaseMigration(data) {
|
|
2832
4657
|
if (!data.tag) {
|
|
2833
4658
|
throw new Error('tag field is required');
|
|
@@ -2836,16 +4661,23 @@ class ProductsBuilderService {
|
|
|
2836
4661
|
if (!databaseTag || !tag) {
|
|
2837
4662
|
throw new Error(`tag is expected to be defined as "database_tag:migration_tag"`);
|
|
2838
4663
|
}
|
|
2839
|
-
await update_productDatabaseMigration_validator_1.default.validateAsync(Object.assign(Object.assign({}, data), { databaseTag }));
|
|
2840
|
-
const
|
|
2841
|
-
if (!
|
|
4664
|
+
await update_productDatabaseMigration_validator_1.default.validateAsync(Object.assign(Object.assign({}, data), { databaseTag }));
|
|
4665
|
+
const existing = await this.fetchDatabaseMigration(data.tag);
|
|
4666
|
+
if (!existing) {
|
|
2842
4667
|
throw new Error(`Migration ${data.tag} not found`);
|
|
2843
4668
|
}
|
|
2844
4669
|
data.tag = tag;
|
|
2845
|
-
|
|
2846
|
-
|
|
4670
|
+
// Process migration value if provided - supports both simple strings and rich operations
|
|
4671
|
+
let processedValue = data.value;
|
|
4672
|
+
if (data.value) {
|
|
4673
|
+
processedValue = {
|
|
4674
|
+
up: this.processMigrationOperations(data.value.up),
|
|
4675
|
+
down: this.processMigrationOperations(data.value.down),
|
|
4676
|
+
};
|
|
4677
|
+
}
|
|
4678
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({}, existing), data), { value: processedValue || existing.value, databaseTag, component: enums_1.ProductComponents.DATABASE_MIGRATION }), this.getUserAccess());
|
|
2847
4679
|
}
|
|
2848
|
-
fetchDatabaseMigration(tag, throwError = false) {
|
|
4680
|
+
async fetchDatabaseMigration(tag, throwError = false) {
|
|
2849
4681
|
const [databaseTag, migrationTag] = tag.split(':');
|
|
2850
4682
|
if (!databaseTag || !migrationTag) {
|
|
2851
4683
|
throw new Error(`tag is expected to be defined as "database_tag:action_tag"`);
|
|
@@ -2858,13 +4690,126 @@ class ProductsBuilderService {
|
|
|
2858
4690
|
throw new Error(`Database migration ${tag} not found`);
|
|
2859
4691
|
return migration;
|
|
2860
4692
|
}
|
|
2861
|
-
fetchDatabaseMigrations(databaseTag) {
|
|
4693
|
+
async fetchDatabaseMigrations(databaseTag) {
|
|
2862
4694
|
const database = this.product.databases.find((data) => data.tag === databaseTag);
|
|
2863
4695
|
if (!database)
|
|
2864
4696
|
throw new Error(`Database ${databaseTag} not found`);
|
|
2865
4697
|
const migrations = database.migrations;
|
|
2866
4698
|
return migrations;
|
|
2867
4699
|
}
|
|
4700
|
+
async deleteDatabaseMigration(tag) {
|
|
4701
|
+
try {
|
|
4702
|
+
const [databaseTag, migrationTag] = tag.split(':');
|
|
4703
|
+
if (!databaseTag || !migrationTag) {
|
|
4704
|
+
throw new Error(`tag is expected to be defined as "database_tag:migration_tag"`);
|
|
4705
|
+
}
|
|
4706
|
+
const migration = await this.fetchDatabaseMigration(tag, true);
|
|
4707
|
+
if (!migration) {
|
|
4708
|
+
throw new Error(`Database migration with tag: ${tag} not found`);
|
|
4709
|
+
}
|
|
4710
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4711
|
+
tag: migrationTag,
|
|
4712
|
+
databaseTag,
|
|
4713
|
+
component: enums_1.ProductComponents.DATABASE_MIGRATION,
|
|
4714
|
+
action: enums_1.RequestAction.DELETE,
|
|
4715
|
+
}, this.getUserAccess());
|
|
4716
|
+
}
|
|
4717
|
+
catch (e) {
|
|
4718
|
+
throw e;
|
|
4719
|
+
}
|
|
4720
|
+
}
|
|
4721
|
+
// ==================== DATABASE TRIGGER CRUD ====================
|
|
4722
|
+
async createDatabaseTrigger(data, throwErrorIfExists = false) {
|
|
4723
|
+
try {
|
|
4724
|
+
if (!data.tag) {
|
|
4725
|
+
throw new Error('tag field is required');
|
|
4726
|
+
}
|
|
4727
|
+
const [databaseTag, triggerTag] = data.tag.split(':');
|
|
4728
|
+
if (!databaseTag || !triggerTag) {
|
|
4729
|
+
throw new Error(`tag is expected to be defined as "database_tag:trigger_tag"`);
|
|
4730
|
+
}
|
|
4731
|
+
const exists = await this.fetchDatabaseTrigger(data.tag);
|
|
4732
|
+
if (exists) {
|
|
4733
|
+
if (throwErrorIfExists) {
|
|
4734
|
+
throw new Error(`Database trigger with tag: ${data.tag} already exists`);
|
|
4735
|
+
}
|
|
4736
|
+
return;
|
|
4737
|
+
}
|
|
4738
|
+
const database = await this.fetchDatabase(databaseTag);
|
|
4739
|
+
if (!database) {
|
|
4740
|
+
throw new Error(`Database ${databaseTag} not found`);
|
|
4741
|
+
}
|
|
4742
|
+
// Initialize triggers array if not present
|
|
4743
|
+
if (!database.triggers) {
|
|
4744
|
+
database.triggers = [];
|
|
4745
|
+
}
|
|
4746
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { tag: triggerTag, databaseTag, component: enums_1.ProductComponents.DATABASE_TRIGGER, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
4747
|
+
}
|
|
4748
|
+
catch (e) {
|
|
4749
|
+
throw e;
|
|
4750
|
+
}
|
|
4751
|
+
}
|
|
4752
|
+
async updateDatabaseTrigger(data) {
|
|
4753
|
+
try {
|
|
4754
|
+
if (!data.tag) {
|
|
4755
|
+
throw new Error('tag field is required');
|
|
4756
|
+
}
|
|
4757
|
+
const [databaseTag, triggerTag] = data.tag.split(':');
|
|
4758
|
+
if (!databaseTag || !triggerTag) {
|
|
4759
|
+
throw new Error(`tag is expected to be defined as "database_tag:trigger_tag"`);
|
|
4760
|
+
}
|
|
4761
|
+
const exists = await this.fetchDatabaseTrigger(data.tag, true);
|
|
4762
|
+
if (!exists) {
|
|
4763
|
+
throw new Error(`Database trigger with tag: ${data.tag} not found`);
|
|
4764
|
+
}
|
|
4765
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { tag: triggerTag, databaseTag, component: enums_1.ProductComponents.DATABASE_TRIGGER, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
4766
|
+
}
|
|
4767
|
+
catch (e) {
|
|
4768
|
+
throw e;
|
|
4769
|
+
}
|
|
4770
|
+
}
|
|
4771
|
+
async fetchDatabaseTrigger(tag, throwError = false) {
|
|
4772
|
+
const [databaseTag, triggerTag] = tag.split(':');
|
|
4773
|
+
if (!databaseTag || !triggerTag) {
|
|
4774
|
+
throw new Error(`tag is expected to be defined as "database_tag:trigger_tag"`);
|
|
4775
|
+
}
|
|
4776
|
+
const database = this.product.databases.find((data) => data.tag === databaseTag);
|
|
4777
|
+
if (!database)
|
|
4778
|
+
throw new Error(`Database ${databaseTag} not found`);
|
|
4779
|
+
const triggers = database.triggers || [];
|
|
4780
|
+
const trigger = triggers.find((data) => data.tag === triggerTag);
|
|
4781
|
+
if (!trigger && throwError)
|
|
4782
|
+
throw new Error(`Database trigger ${tag} not found`);
|
|
4783
|
+
return trigger || null;
|
|
4784
|
+
}
|
|
4785
|
+
async fetchDatabaseTriggers(databaseTag) {
|
|
4786
|
+
const database = this.product.databases.find((data) => data.tag === databaseTag);
|
|
4787
|
+
if (!database)
|
|
4788
|
+
throw new Error(`Database ${databaseTag} not found`);
|
|
4789
|
+
const triggers = database.triggers || [];
|
|
4790
|
+
return triggers;
|
|
4791
|
+
}
|
|
4792
|
+
async deleteDatabaseTrigger(tag) {
|
|
4793
|
+
try {
|
|
4794
|
+
const [databaseTag, triggerTag] = tag.split(':');
|
|
4795
|
+
if (!databaseTag || !triggerTag) {
|
|
4796
|
+
throw new Error(`tag is expected to be defined as "database_tag:trigger_tag"`);
|
|
4797
|
+
}
|
|
4798
|
+
const trigger = await this.fetchDatabaseTrigger(tag, true);
|
|
4799
|
+
if (!trigger) {
|
|
4800
|
+
throw new Error(`Database trigger with tag: ${tag} not found`);
|
|
4801
|
+
}
|
|
4802
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4803
|
+
tag: triggerTag,
|
|
4804
|
+
databaseTag,
|
|
4805
|
+
component: enums_1.ProductComponents.DATABASE_TRIGGER,
|
|
4806
|
+
action: enums_1.RequestAction.DELETE,
|
|
4807
|
+
}, this.getUserAccess());
|
|
4808
|
+
}
|
|
4809
|
+
catch (e) {
|
|
4810
|
+
throw e;
|
|
4811
|
+
}
|
|
4812
|
+
}
|
|
2868
4813
|
async validateJobEvent(data) {
|
|
2869
4814
|
const { type, app, event } = data;
|
|
2870
4815
|
if (type === productsBuilder_types_1.JobEventTypes.ACTION) {
|
|
@@ -2879,31 +4824,28 @@ class ProductsBuilderService {
|
|
|
2879
4824
|
}
|
|
2880
4825
|
}
|
|
2881
4826
|
if (type === productsBuilder_types_1.JobEventTypes.DATABASE_ACTION) {
|
|
2882
|
-
const found = this.fetchDatabaseAction(event);
|
|
4827
|
+
const found = await this.fetchDatabaseAction(event);
|
|
2883
4828
|
if (!found) {
|
|
2884
4829
|
throw new Error(`Database action ${event} not found`);
|
|
2885
4830
|
}
|
|
2886
4831
|
}
|
|
2887
|
-
if (type === productsBuilder_types_1.JobEventTypes.FUNCTION) {
|
|
2888
|
-
const found = this.fetchFunction(event);
|
|
2889
|
-
if (!found) {
|
|
2890
|
-
throw new Error(`Cloud function ${event} not found`);
|
|
2891
|
-
}
|
|
2892
|
-
}
|
|
2893
4832
|
if (type === productsBuilder_types_1.JobEventTypes.STORAGE) {
|
|
2894
|
-
|
|
4833
|
+
// app = storage tag (e.g. gcp-storage), event = operation (e.g. upload)
|
|
4834
|
+
const found = await this.fetchStorage(app);
|
|
2895
4835
|
if (!found) {
|
|
2896
|
-
throw new Error(`Storage ${
|
|
4836
|
+
throw new Error(`Storage ${app} not found`);
|
|
2897
4837
|
}
|
|
2898
4838
|
}
|
|
2899
4839
|
if (type === productsBuilder_types_1.JobEventTypes.NOTIFICATION) {
|
|
2900
|
-
const found = this.
|
|
4840
|
+
const found = await this.fetchNotificationMessage(data.app + ':' + event);
|
|
4841
|
+
console.log("DATA", data);
|
|
4842
|
+
console.log("FOUND", found);
|
|
2901
4843
|
if (!found) {
|
|
2902
4844
|
throw new Error(`Notification ${event} not found`);
|
|
2903
4845
|
}
|
|
2904
4846
|
}
|
|
2905
4847
|
if (type === productsBuilder_types_1.JobEventTypes.PUBLISH) {
|
|
2906
|
-
const found = this.fetchMessageBroker(event);
|
|
4848
|
+
const found = await this.fetchMessageBroker(event);
|
|
2907
4849
|
if (!found) {
|
|
2908
4850
|
throw new Error(`Message Broker ${event} not found`);
|
|
2909
4851
|
}
|
|
@@ -2912,7 +4854,7 @@ class ProductsBuilderService {
|
|
|
2912
4854
|
async createJob(data, throwErrorIfExists = false) {
|
|
2913
4855
|
try {
|
|
2914
4856
|
// TODO: figure out a way to check if this has run before, halt if it has
|
|
2915
|
-
if (!this.fetchJob(data.tag)) {
|
|
4857
|
+
if (!(await this.fetchJob(data.tag))) {
|
|
2916
4858
|
await validators_1.CreateProductJobSchema.validateAsync(data);
|
|
2917
4859
|
await this.validateJobEvent(data);
|
|
2918
4860
|
if (data.type === productsBuilder_types_1.JobEventTypes.ACTION) {
|
|
@@ -2934,7 +4876,6 @@ class ProductsBuilderService {
|
|
|
2934
4876
|
const dbAction = await this.fetchDatabaseAction(data.event);
|
|
2935
4877
|
}
|
|
2936
4878
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.JOB, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
2937
|
-
await this.initializeProduct(this.product_id);
|
|
2938
4879
|
}
|
|
2939
4880
|
else {
|
|
2940
4881
|
if (throwErrorIfExists)
|
|
@@ -2957,20 +4898,111 @@ class ProductsBuilderService {
|
|
|
2957
4898
|
throw new Error(`tag ${tag} is in use`); // TODO: also check on the backend
|
|
2958
4899
|
}
|
|
2959
4900
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({}, job), data), { component: enums_1.ProductComponents.JOB, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
2960
|
-
await this.initializeProduct(this.product_id);
|
|
2961
4901
|
}
|
|
2962
4902
|
catch (e) {
|
|
2963
4903
|
throw e;
|
|
2964
4904
|
}
|
|
2965
4905
|
}
|
|
2966
|
-
|
|
2967
|
-
const
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
4906
|
+
async fetchJobs() {
|
|
4907
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'job', this.getUserAccess());
|
|
4908
|
+
return components;
|
|
4909
|
+
}
|
|
4910
|
+
async fetchJob(tag) {
|
|
4911
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'job', tag, this.getUserAccess());
|
|
4912
|
+
return component;
|
|
4913
|
+
}
|
|
4914
|
+
async deleteJob(tag) {
|
|
4915
|
+
try {
|
|
4916
|
+
const job = await this.fetchJob(tag);
|
|
4917
|
+
if (!job) {
|
|
4918
|
+
throw new Error(`Job with tag: ${tag} not found`);
|
|
4919
|
+
}
|
|
4920
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4921
|
+
tag,
|
|
4922
|
+
component: enums_1.ProductComponents.JOB,
|
|
4923
|
+
action: enums_1.RequestAction.DELETE,
|
|
4924
|
+
}, this.getUserAccess());
|
|
4925
|
+
}
|
|
4926
|
+
catch (e) {
|
|
4927
|
+
throw e;
|
|
4928
|
+
}
|
|
4929
|
+
}
|
|
4930
|
+
// ==================== WORKFLOW CRUD METHODS ====================
|
|
4931
|
+
async createWorkflow(data, throwErrorIfExists = false) {
|
|
4932
|
+
try {
|
|
4933
|
+
if (!(await this.fetchWorkflow(data.tag))) {
|
|
4934
|
+
// Validate required fields
|
|
4935
|
+
if (!data.name || !data.tag) {
|
|
4936
|
+
throw new Error('Workflow requires name and tag');
|
|
4937
|
+
}
|
|
4938
|
+
// Validate envs if provided
|
|
4939
|
+
if (data.envs && data.envs.length > 0) {
|
|
4940
|
+
for (const env of data.envs) {
|
|
4941
|
+
const exists = await this.fetchEnv(env.slug);
|
|
4942
|
+
if (!exists) {
|
|
4943
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
4944
|
+
}
|
|
4945
|
+
}
|
|
4946
|
+
}
|
|
4947
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.WORKFLOW, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
4948
|
+
}
|
|
4949
|
+
else {
|
|
4950
|
+
if (throwErrorIfExists)
|
|
4951
|
+
throw new Error(`Workflow ${data.tag} already exists`);
|
|
4952
|
+
}
|
|
4953
|
+
}
|
|
4954
|
+
catch (e) {
|
|
4955
|
+
throw e;
|
|
4956
|
+
}
|
|
4957
|
+
}
|
|
4958
|
+
async updateWorkflow(tag, data) {
|
|
4959
|
+
try {
|
|
4960
|
+
const workflow = await this.fetchWorkflow(tag);
|
|
4961
|
+
if (!workflow) {
|
|
4962
|
+
throw new Error(`Workflow ${tag} not found`);
|
|
4963
|
+
}
|
|
4964
|
+
const { _id } = workflow;
|
|
4965
|
+
if (data.tag && data.tag !== tag && (await this.fetchWorkflow(data.tag))) {
|
|
4966
|
+
throw new Error(`tag ${data.tag} is in use`);
|
|
4967
|
+
}
|
|
4968
|
+
// Validate envs if provided
|
|
4969
|
+
if (data.envs && data.envs.length > 0) {
|
|
4970
|
+
for (const env of data.envs) {
|
|
4971
|
+
const exists = await this.fetchEnv(env.slug);
|
|
4972
|
+
if (!exists) {
|
|
4973
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
4974
|
+
}
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({ _id }, data), { tag, component: enums_1.ProductComponents.WORKFLOW, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
4978
|
+
}
|
|
4979
|
+
catch (e) {
|
|
4980
|
+
throw e;
|
|
4981
|
+
}
|
|
4982
|
+
}
|
|
4983
|
+
async fetchWorkflows() {
|
|
4984
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'workflow', this.getUserAccess());
|
|
4985
|
+
return components;
|
|
4986
|
+
}
|
|
4987
|
+
async fetchWorkflow(tag) {
|
|
4988
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'workflow', tag, this.getUserAccess());
|
|
4989
|
+
return component;
|
|
2971
4990
|
}
|
|
2972
|
-
|
|
2973
|
-
|
|
4991
|
+
async deleteWorkflow(tag) {
|
|
4992
|
+
try {
|
|
4993
|
+
const workflow = await this.fetchWorkflow(tag);
|
|
4994
|
+
if (!workflow) {
|
|
4995
|
+
throw new Error(`Workflow with tag: ${tag} not found`);
|
|
4996
|
+
}
|
|
4997
|
+
await this.productApi.updateProduct(this.product_id, {
|
|
4998
|
+
tag,
|
|
4999
|
+
component: enums_1.ProductComponents.WORKFLOW,
|
|
5000
|
+
action: enums_1.RequestAction.DELETE,
|
|
5001
|
+
}, this.getUserAccess());
|
|
5002
|
+
}
|
|
5003
|
+
catch (e) {
|
|
5004
|
+
throw e;
|
|
5005
|
+
}
|
|
2974
5006
|
}
|
|
2975
5007
|
getUserAccess() {
|
|
2976
5008
|
return {
|
|
@@ -2978,8 +5010,778 @@ class ProductsBuilderService {
|
|
|
2978
5010
|
workspace_id: this.workspace_id,
|
|
2979
5011
|
token: this.token,
|
|
2980
5012
|
public_key: this.public_key,
|
|
5013
|
+
access_key: this.access_key,
|
|
5014
|
+
};
|
|
5015
|
+
}
|
|
5016
|
+
async fetchSessionUser(ductape_user_id) {
|
|
5017
|
+
return await this.productApi.fetchProductSessionUser(ductape_user_id, this.getUserAccess());
|
|
5018
|
+
}
|
|
5019
|
+
/**
|
|
5020
|
+
* Process storage config to store sensitive credentials as secrets
|
|
5021
|
+
* Format: STORAGE_{PRODUCT}_{STORAGE_TAG}_{ENV}_{KEY}
|
|
5022
|
+
*
|
|
5023
|
+
* Product parsing: split by ":", select first element
|
|
5024
|
+
* Storage tag: replace "-" with "_"
|
|
5025
|
+
*/
|
|
5026
|
+
async processStorageConfigSecrets(config, providerType, storageTag, envSlug) {
|
|
5027
|
+
console.log(`[Storage Secrets] Processing secrets for storage: ${storageTag}, env: ${envSlug}, provider: ${providerType}`);
|
|
5028
|
+
const secretsService = (0, secrets_1.getSecretsService)();
|
|
5029
|
+
if (!secretsService) {
|
|
5030
|
+
console.log(`[Storage Secrets] No secrets service available, skipping secret storage`);
|
|
5031
|
+
return config;
|
|
5032
|
+
}
|
|
5033
|
+
const generateSecretKey = (keyName) => {
|
|
5034
|
+
const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
|
|
5035
|
+
const productParts = this.product.tag.split(':');
|
|
5036
|
+
const productKey = productParts[1] || productParts[0]; // Use product name (index 1), fallback to index 0
|
|
5037
|
+
const storageKey = storageTag.replace(/-/g, '_');
|
|
5038
|
+
const key = `STORAGE_${sanitize(productKey)}_${sanitize(storageKey)}_${sanitize(envSlug)}_${sanitize(keyName)}`;
|
|
5039
|
+
console.log(`[Storage Secrets] Generated secret key: ${key}`);
|
|
5040
|
+
return key;
|
|
5041
|
+
};
|
|
5042
|
+
const storeAsSecret = async (value, keyName) => {
|
|
5043
|
+
const secretCheck = (0, secrets_1.isSecretReference)(value);
|
|
5044
|
+
if (secretCheck.isSecret) {
|
|
5045
|
+
console.log(`[Storage Secrets] ${keyName} is already a secret reference, skipping`);
|
|
5046
|
+
return value; // Already a secret reference
|
|
5047
|
+
}
|
|
5048
|
+
const secretKey = generateSecretKey(keyName);
|
|
5049
|
+
try {
|
|
5050
|
+
const exists = await secretsService.exists(secretKey);
|
|
5051
|
+
if (exists) {
|
|
5052
|
+
console.log(`[Storage Secrets] Updating existing secret: ${secretKey}`);
|
|
5053
|
+
await secretsService.update(secretKey, { value });
|
|
5054
|
+
}
|
|
5055
|
+
else {
|
|
5056
|
+
console.log(`[Storage Secrets] Creating new secret: ${secretKey}`);
|
|
5057
|
+
await secretsService.create({
|
|
5058
|
+
key: secretKey,
|
|
5059
|
+
value,
|
|
5060
|
+
description: `Storage ${keyName} for ${storageTag} in ${envSlug}`,
|
|
5061
|
+
scope: [this.product.tag, storageTag],
|
|
5062
|
+
envs: [envSlug],
|
|
5063
|
+
});
|
|
5064
|
+
}
|
|
5065
|
+
console.log(`[Storage Secrets] Successfully stored ${keyName} as secret: $Secret{${secretKey}}`);
|
|
5066
|
+
return `$Secret{${secretKey}}`;
|
|
5067
|
+
}
|
|
5068
|
+
catch (error) {
|
|
5069
|
+
console.warn(`[Storage Secrets] Failed to store storage credential as secret: ${error}`);
|
|
5070
|
+
return value;
|
|
5071
|
+
}
|
|
5072
|
+
};
|
|
5073
|
+
if (providerType === productsBuilder_types_1.StorageProviders.AWS) {
|
|
5074
|
+
console.log(`[Storage Secrets] Processing AWS S3 credentials`);
|
|
5075
|
+
const awsConfig = config;
|
|
5076
|
+
const result = Object.assign(Object.assign({}, awsConfig), { accessKeyId: await storeAsSecret(awsConfig.accessKeyId, 'ACCESS_KEY_ID'), secretAccessKey: await storeAsSecret(awsConfig.secretAccessKey, 'SECRET_ACCESS_KEY') });
|
|
5077
|
+
console.log(`[Storage Secrets] AWS S3 config processed successfully`);
|
|
5078
|
+
return result;
|
|
5079
|
+
}
|
|
5080
|
+
else if (providerType === productsBuilder_types_1.StorageProviders.GCP) {
|
|
5081
|
+
console.log(`[Storage Secrets] Processing GCP credentials`);
|
|
5082
|
+
const gcpConfig = config;
|
|
5083
|
+
if (gcpConfig.config) {
|
|
5084
|
+
const processedConfig = Object.assign({}, gcpConfig.config);
|
|
5085
|
+
// Store private_key_id as secret
|
|
5086
|
+
if (processedConfig.private_key_id) {
|
|
5087
|
+
processedConfig.private_key_id = await storeAsSecret(processedConfig.private_key_id, 'PRIVATE_KEY_ID');
|
|
5088
|
+
}
|
|
5089
|
+
// Store private_key as secret
|
|
5090
|
+
if (processedConfig.private_key) {
|
|
5091
|
+
processedConfig.private_key = await storeAsSecret(processedConfig.private_key, 'PRIVATE_KEY');
|
|
5092
|
+
}
|
|
5093
|
+
// Store client_email as secret
|
|
5094
|
+
if (processedConfig.client_email) {
|
|
5095
|
+
processedConfig.client_email = await storeAsSecret(processedConfig.client_email, 'CLIENT_EMAIL');
|
|
5096
|
+
}
|
|
5097
|
+
// Store client_id as secret
|
|
5098
|
+
if (processedConfig.client_id) {
|
|
5099
|
+
processedConfig.client_id = await storeAsSecret(processedConfig.client_id, 'CLIENT_ID');
|
|
5100
|
+
}
|
|
5101
|
+
const result = Object.assign(Object.assign({}, gcpConfig), { config: processedConfig });
|
|
5102
|
+
console.log(`[Storage Secrets] GCP config processed successfully`);
|
|
5103
|
+
console.log(`[Storage Secrets] Converted GCP config:`, JSON.stringify(result, null, 2));
|
|
5104
|
+
return result;
|
|
5105
|
+
}
|
|
5106
|
+
console.log(`[Storage Secrets] GCP config has no nested config, skipping`);
|
|
5107
|
+
return gcpConfig;
|
|
5108
|
+
}
|
|
5109
|
+
else if (providerType === productsBuilder_types_1.StorageProviders.AZURE) {
|
|
5110
|
+
console.log(`[Storage Secrets] Processing Azure Blob credentials`);
|
|
5111
|
+
const azureConfig = config;
|
|
5112
|
+
const result = Object.assign(Object.assign({}, azureConfig), { connectionString: await storeAsSecret(azureConfig.connectionString, 'CONNECTION_STRING') });
|
|
5113
|
+
console.log(`[Storage Secrets] Azure Blob config processed successfully`);
|
|
5114
|
+
return result;
|
|
5115
|
+
}
|
|
5116
|
+
console.log(`[Storage Secrets] Unknown provider type: ${providerType}, returning config as-is`);
|
|
5117
|
+
return config;
|
|
5118
|
+
}
|
|
5119
|
+
/**
|
|
5120
|
+
* Process message broker config to store sensitive credentials as secrets
|
|
5121
|
+
* Format: BROKER_{PRODUCT}_{BROKER_TAG}_{ENV}_{KEY}
|
|
5122
|
+
*
|
|
5123
|
+
* Product parsing: split by ":", select first element
|
|
5124
|
+
* Broker tag: replace "-" with "_"
|
|
5125
|
+
*/
|
|
5126
|
+
async processMessageBrokerConfigSecrets(config, brokerType, brokerTag, envSlug) {
|
|
5127
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
5128
|
+
const logPrefix = '[MessageBroker:Secrets]';
|
|
5129
|
+
console.log(`${logPrefix} Processing secrets for broker: ${brokerTag}, env: ${envSlug}, type: ${brokerType}`);
|
|
5130
|
+
const secretsService = (0, secrets_1.getSecretsService)();
|
|
5131
|
+
if (!secretsService) {
|
|
5132
|
+
console.log(`${logPrefix} No secrets service available, skipping secret storage`);
|
|
5133
|
+
return config;
|
|
5134
|
+
}
|
|
5135
|
+
console.log(`${logPrefix} Secrets service available`);
|
|
5136
|
+
const generateSecretKey = (keyName) => {
|
|
5137
|
+
const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
|
|
5138
|
+
const productParts = this.product.tag.split(':');
|
|
5139
|
+
const productKey = productParts[1] || productParts[0];
|
|
5140
|
+
const brokerKey = brokerTag.replace(/-/g, '_');
|
|
5141
|
+
const key = `BROKER_${sanitize(productKey)}_${sanitize(brokerKey)}_${sanitize(envSlug)}_${sanitize(keyName)}`;
|
|
5142
|
+
console.log(`${logPrefix} Generated secret key: ${key}`);
|
|
5143
|
+
return key;
|
|
5144
|
+
};
|
|
5145
|
+
const storeAsSecret = async (value, keyName) => {
|
|
5146
|
+
console.log(`${logPrefix} Processing field: ${keyName}`);
|
|
5147
|
+
if (!value) {
|
|
5148
|
+
console.log(`${logPrefix} Field ${keyName} is empty, skipping`);
|
|
5149
|
+
return value;
|
|
5150
|
+
}
|
|
5151
|
+
const secretCheck = (0, secrets_1.isSecretReference)(value);
|
|
5152
|
+
if (secretCheck.isSecret) {
|
|
5153
|
+
console.log(`${logPrefix} Field ${keyName} is already a secret reference: ${value}`);
|
|
5154
|
+
return value;
|
|
5155
|
+
}
|
|
5156
|
+
const secretKey = generateSecretKey(keyName);
|
|
5157
|
+
console.log(`${logPrefix} Storing ${keyName} as secret with key: ${secretKey}`);
|
|
5158
|
+
try {
|
|
5159
|
+
const exists = await secretsService.exists(secretKey);
|
|
5160
|
+
console.log(`${logPrefix} Secret ${secretKey} exists: ${exists}`);
|
|
5161
|
+
if (exists) {
|
|
5162
|
+
console.log(`${logPrefix} Updating existing secret: ${secretKey}`);
|
|
5163
|
+
await secretsService.update(secretKey, { value });
|
|
5164
|
+
console.log(`${logPrefix} Secret ${secretKey} updated successfully`);
|
|
5165
|
+
}
|
|
5166
|
+
else {
|
|
5167
|
+
console.log(`${logPrefix} Creating new secret: ${secretKey}`);
|
|
5168
|
+
await secretsService.create({
|
|
5169
|
+
key: secretKey,
|
|
5170
|
+
value,
|
|
5171
|
+
description: `Message broker ${keyName} for ${brokerTag} in ${envSlug}`,
|
|
5172
|
+
scope: [this.product.tag, brokerTag],
|
|
5173
|
+
envs: [envSlug],
|
|
5174
|
+
});
|
|
5175
|
+
console.log(`${logPrefix} Secret ${secretKey} created successfully`);
|
|
5176
|
+
}
|
|
5177
|
+
const secretRef = `$Secret{${secretKey}}`;
|
|
5178
|
+
console.log(`${logPrefix} Field ${keyName} converted to secret reference: ${secretRef}`);
|
|
5179
|
+
return secretRef;
|
|
5180
|
+
}
|
|
5181
|
+
catch (error) {
|
|
5182
|
+
console.error(`${logPrefix} Failed to store ${keyName} as secret:`, error);
|
|
5183
|
+
console.warn(`${logPrefix} Returning original value for ${keyName}`);
|
|
5184
|
+
return value;
|
|
5185
|
+
}
|
|
5186
|
+
};
|
|
5187
|
+
// Handle different broker types - config is passed directly without wrapper
|
|
5188
|
+
console.log(`${logPrefix} Processing broker type: ${brokerType}`);
|
|
5189
|
+
if (brokerType === productsBuilder_types_1.MessageBrokerTypes.REDIS) {
|
|
5190
|
+
console.log(`${logPrefix} Redis config detected`);
|
|
5191
|
+
console.log(`${logPrefix} Redis fields - host: ${config.host}, port: ${config.port}, password: ${config.password ? '[SET]' : '[NOT SET]'}`);
|
|
5192
|
+
if (config.password) {
|
|
5193
|
+
config.password = await storeAsSecret(config.password, 'PASSWORD');
|
|
5194
|
+
}
|
|
5195
|
+
}
|
|
5196
|
+
else if (brokerType === productsBuilder_types_1.MessageBrokerTypes.RABBITMQ) {
|
|
5197
|
+
console.log(`${logPrefix} RabbitMQ config detected`);
|
|
5198
|
+
console.log(`${logPrefix} RabbitMQ fields - url: ${config.url ? '[SET]' : '[NOT SET]'}`);
|
|
5199
|
+
if (config.url) {
|
|
5200
|
+
config.url = await storeAsSecret(config.url, 'URL');
|
|
5201
|
+
}
|
|
5202
|
+
}
|
|
5203
|
+
else if (brokerType === productsBuilder_types_1.MessageBrokerTypes.KAFKA) {
|
|
5204
|
+
console.log(`${logPrefix} Kafka config detected`);
|
|
5205
|
+
console.log(`${logPrefix} Kafka fields - brokers: ${(_a = config.brokers) === null || _a === void 0 ? void 0 : _a.join(', ')}, clientId: ${config.clientId}, ssl: ${config.ssl}`);
|
|
5206
|
+
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]'}`);
|
|
5207
|
+
if ((_e = config.sasl) === null || _e === void 0 ? void 0 : _e.username) {
|
|
5208
|
+
config.sasl.username = await storeAsSecret(config.sasl.username, 'SASL_USERNAME');
|
|
5209
|
+
}
|
|
5210
|
+
if ((_f = config.sasl) === null || _f === void 0 ? void 0 : _f.password) {
|
|
5211
|
+
config.sasl.password = await storeAsSecret(config.sasl.password, 'SASL_PASSWORD');
|
|
5212
|
+
}
|
|
5213
|
+
}
|
|
5214
|
+
else if (brokerType === productsBuilder_types_1.MessageBrokerTypes.AWS_SQS) {
|
|
5215
|
+
console.log(`${logPrefix} AWS SQS config detected`);
|
|
5216
|
+
console.log(`${logPrefix} AWS SQS fields - region: ${config.region}, accessKeyId: ${config.accessKeyId ? '[SET]' : '[NOT SET]'}, secretAccessKey: ${config.secretAccessKey ? '[SET]' : '[NOT SET]'}`);
|
|
5217
|
+
if (config.accessKeyId) {
|
|
5218
|
+
config.accessKeyId = await storeAsSecret(config.accessKeyId, 'ACCESS_KEY_ID');
|
|
5219
|
+
}
|
|
5220
|
+
if (config.secretAccessKey) {
|
|
5221
|
+
config.secretAccessKey = await storeAsSecret(config.secretAccessKey, 'SECRET_ACCESS_KEY');
|
|
5222
|
+
}
|
|
5223
|
+
}
|
|
5224
|
+
else if (brokerType === productsBuilder_types_1.MessageBrokerTypes.NATS) {
|
|
5225
|
+
console.log(`${logPrefix} NATS config detected`);
|
|
5226
|
+
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}`);
|
|
5227
|
+
if (config.token) {
|
|
5228
|
+
config.token = await storeAsSecret(config.token, 'TOKEN');
|
|
5229
|
+
}
|
|
5230
|
+
if (config.user) {
|
|
5231
|
+
config.user = await storeAsSecret(config.user, 'USER');
|
|
5232
|
+
}
|
|
5233
|
+
if (config.pass) {
|
|
5234
|
+
config.pass = await storeAsSecret(config.pass, 'PASSWORD');
|
|
5235
|
+
}
|
|
5236
|
+
}
|
|
5237
|
+
else if (brokerType === productsBuilder_types_1.MessageBrokerTypes.GOOGLE_PUBSUB) {
|
|
5238
|
+
console.log(`${logPrefix} Google Pub/Sub config detected`);
|
|
5239
|
+
console.log(`${logPrefix} Google Pub/Sub fields - projectId: ${config.projectId}, credentials: ${config.credentials ? '[SET]' : '[NOT SET]'}`);
|
|
5240
|
+
if (config.credentials) {
|
|
5241
|
+
console.log(`${logPrefix} Google Pub/Sub credentials - type: ${config.credentials.type}, project_id: ${config.credentials.project_id}`);
|
|
5242
|
+
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]'}`);
|
|
5243
|
+
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]'}`);
|
|
5244
|
+
if (config.credentials.private_key_id) {
|
|
5245
|
+
config.credentials.private_key_id = await storeAsSecret(config.credentials.private_key_id, 'PRIVATE_KEY_ID');
|
|
5246
|
+
}
|
|
5247
|
+
if (config.credentials.private_key) {
|
|
5248
|
+
config.credentials.private_key = await storeAsSecret(config.credentials.private_key, 'PRIVATE_KEY');
|
|
5249
|
+
}
|
|
5250
|
+
if (config.credentials.client_email) {
|
|
5251
|
+
config.credentials.client_email = await storeAsSecret(config.credentials.client_email, 'CLIENT_EMAIL');
|
|
5252
|
+
}
|
|
5253
|
+
if (config.credentials.client_id) {
|
|
5254
|
+
config.credentials.client_id = await storeAsSecret(config.credentials.client_id, 'CLIENT_ID');
|
|
5255
|
+
}
|
|
5256
|
+
}
|
|
5257
|
+
}
|
|
5258
|
+
else {
|
|
5259
|
+
console.log(`${logPrefix} Unknown broker type: ${brokerType}, no secrets processing`);
|
|
5260
|
+
}
|
|
5261
|
+
console.log(`${logPrefix} Secrets processing completed for ${brokerTag}:${envSlug}`);
|
|
5262
|
+
return config;
|
|
5263
|
+
}
|
|
5264
|
+
/**
|
|
5265
|
+
* Process notification environment config to store sensitive credentials as secrets
|
|
5266
|
+
* Format: NOTIFIER_{PRODUCT}_{NOTIFIER_TAG}_{ENV}_{KEY}
|
|
5267
|
+
*
|
|
5268
|
+
* Product parsing: split by ":", select first element
|
|
5269
|
+
* Notifier tag: replace "-" with "_"
|
|
5270
|
+
*/
|
|
5271
|
+
async processNotificationEnvSecrets(env, notifierTag, envSlug) {
|
|
5272
|
+
var _a, _b, _c, _d, _e;
|
|
5273
|
+
const secretsService = (0, secrets_1.getSecretsService)();
|
|
5274
|
+
if (!secretsService) {
|
|
5275
|
+
return env;
|
|
5276
|
+
}
|
|
5277
|
+
const generateSecretKey = (keyName) => {
|
|
5278
|
+
const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
|
|
5279
|
+
// Support both ':' and '.' delimiters for product tags (e.g., 'ductape:rematch' or 'ductape.rematch')
|
|
5280
|
+
const productParts = this.product.tag.includes(':')
|
|
5281
|
+
? this.product.tag.split(':')
|
|
5282
|
+
: this.product.tag.split('.');
|
|
5283
|
+
const productKey = productParts[1] || productParts[0]; // Use product name (index 1), fallback to index 0
|
|
5284
|
+
const workspace = productParts[0];
|
|
5285
|
+
// Support both ':' and '.' delimiters for notification tags
|
|
5286
|
+
const notifierParts = notifierTag.includes(':')
|
|
5287
|
+
? notifierTag.split(':')
|
|
5288
|
+
: notifierTag.split('.');
|
|
5289
|
+
let notifierKey;
|
|
5290
|
+
if (notifierParts.length > 1 && notifierParts[0] === workspace) {
|
|
5291
|
+
// Same workspace prefix, use second part
|
|
5292
|
+
notifierKey = notifierParts[1];
|
|
5293
|
+
}
|
|
5294
|
+
else {
|
|
5295
|
+
// Different or no prefix, use full tag
|
|
5296
|
+
notifierKey = notifierTag;
|
|
5297
|
+
}
|
|
5298
|
+
// Replace '-' with '_' for consistency with Storage/Message Broker pattern
|
|
5299
|
+
notifierKey = notifierKey.replace(/-/g, '_');
|
|
5300
|
+
return `NOTIFIER_${sanitize(productKey)}_${sanitize(notifierKey)}_${sanitize(envSlug)}_${sanitize(keyName)}`;
|
|
5301
|
+
};
|
|
5302
|
+
const storeAsSecret = async (value, keyName) => {
|
|
5303
|
+
if (!value)
|
|
5304
|
+
return value;
|
|
5305
|
+
const secretCheck = (0, secrets_1.isSecretReference)(value);
|
|
5306
|
+
if (secretCheck.isSecret) {
|
|
5307
|
+
return value; // Already a secret reference
|
|
5308
|
+
}
|
|
5309
|
+
const secretKey = generateSecretKey(keyName);
|
|
5310
|
+
try {
|
|
5311
|
+
const exists = await secretsService.exists(secretKey);
|
|
5312
|
+
if (exists) {
|
|
5313
|
+
await secretsService.update(secretKey, { value });
|
|
5314
|
+
}
|
|
5315
|
+
else {
|
|
5316
|
+
await secretsService.create({
|
|
5317
|
+
key: secretKey,
|
|
5318
|
+
value,
|
|
5319
|
+
description: `Notification ${keyName} for ${notifierTag} in ${envSlug}`,
|
|
5320
|
+
scope: [this.product.tag, notifierTag],
|
|
5321
|
+
envs: [envSlug],
|
|
5322
|
+
});
|
|
5323
|
+
}
|
|
5324
|
+
return `$Secret{${secretKey}}`;
|
|
5325
|
+
}
|
|
5326
|
+
catch (error) {
|
|
5327
|
+
console.warn(`Failed to store notification credential as secret: ${error}`);
|
|
5328
|
+
return value;
|
|
5329
|
+
}
|
|
2981
5330
|
};
|
|
5331
|
+
const result = Object.assign({}, env);
|
|
5332
|
+
// Process email handler
|
|
5333
|
+
if (result.emails) {
|
|
5334
|
+
const emailUpdates = Object.assign({}, result.emails);
|
|
5335
|
+
// SMTP: auth.user and auth.pass
|
|
5336
|
+
if ((_a = result.emails.smtp) === null || _a === void 0 ? void 0 : _a.auth) {
|
|
5337
|
+
emailUpdates.smtp = Object.assign(Object.assign({}, result.emails.smtp), { auth: Object.assign(Object.assign({}, result.emails.smtp.auth), { user: result.emails.smtp.auth.user
|
|
5338
|
+
? await storeAsSecret(result.emails.smtp.auth.user, 'EMAIL_SMTP_USER')
|
|
5339
|
+
: result.emails.smtp.auth.user, pass: result.emails.smtp.auth.pass
|
|
5340
|
+
? await storeAsSecret(result.emails.smtp.auth.pass, 'EMAIL_PASSWORD')
|
|
5341
|
+
: result.emails.smtp.auth.pass }) });
|
|
5342
|
+
}
|
|
5343
|
+
// SendGrid: apiKey
|
|
5344
|
+
if ((_b = result.emails.sendgrid) === null || _b === void 0 ? void 0 : _b.apiKey) {
|
|
5345
|
+
emailUpdates.sendgrid = Object.assign(Object.assign({}, result.emails.sendgrid), { apiKey: await storeAsSecret(result.emails.sendgrid.apiKey, 'EMAIL_SENDGRID_API_KEY') });
|
|
5346
|
+
}
|
|
5347
|
+
// Mailgun: apiKey and domain (domain may contain sensitive info)
|
|
5348
|
+
if (result.emails.mailgun) {
|
|
5349
|
+
const mailgunUpdates = Object.assign({}, result.emails.mailgun);
|
|
5350
|
+
if (result.emails.mailgun.apiKey) {
|
|
5351
|
+
mailgunUpdates.apiKey = await storeAsSecret(result.emails.mailgun.apiKey, 'EMAIL_MAILGUN_API_KEY');
|
|
5352
|
+
}
|
|
5353
|
+
if (result.emails.mailgun.domain) {
|
|
5354
|
+
mailgunUpdates.domain = await storeAsSecret(result.emails.mailgun.domain, 'EMAIL_MAILGUN_DOMAIN');
|
|
5355
|
+
}
|
|
5356
|
+
emailUpdates.mailgun = mailgunUpdates;
|
|
5357
|
+
}
|
|
5358
|
+
// Postmark: serverToken
|
|
5359
|
+
if ((_c = result.emails.postmark) === null || _c === void 0 ? void 0 : _c.serverToken) {
|
|
5360
|
+
emailUpdates.postmark = Object.assign(Object.assign({}, result.emails.postmark), { serverToken: await storeAsSecret(result.emails.postmark.serverToken, 'EMAIL_POSTMARK_SERVER_TOKEN') });
|
|
5361
|
+
}
|
|
5362
|
+
// Brevo: apiKey
|
|
5363
|
+
if ((_d = result.emails.brevo) === null || _d === void 0 ? void 0 : _d.apiKey) {
|
|
5364
|
+
emailUpdates.brevo = Object.assign(Object.assign({}, result.emails.brevo), { apiKey: await storeAsSecret(result.emails.brevo.apiKey, 'EMAIL_BREVO_API_KEY') });
|
|
5365
|
+
}
|
|
5366
|
+
// Legacy SMTP format (for backward compatibility)
|
|
5367
|
+
if (result.emails.auth && !result.emails.smtp) {
|
|
5368
|
+
emailUpdates.auth = Object.assign(Object.assign({}, result.emails.auth), { user: result.emails.auth.user
|
|
5369
|
+
? await storeAsSecret(result.emails.auth.user, 'EMAIL_SMTP_USER')
|
|
5370
|
+
: result.emails.auth.user, pass: result.emails.auth.pass
|
|
5371
|
+
? await storeAsSecret(result.emails.auth.pass, 'EMAIL_PASSWORD')
|
|
5372
|
+
: result.emails.auth.pass });
|
|
5373
|
+
}
|
|
5374
|
+
result.emails = emailUpdates;
|
|
5375
|
+
}
|
|
5376
|
+
// Process SMS handler
|
|
5377
|
+
if (result.sms) {
|
|
5378
|
+
const smsUpdates = {};
|
|
5379
|
+
if (result.sms.authToken) {
|
|
5380
|
+
smsUpdates.authToken = await storeAsSecret(result.sms.authToken, 'SMS_AUTH_TOKEN');
|
|
5381
|
+
}
|
|
5382
|
+
if (result.sms.apiSecret) {
|
|
5383
|
+
smsUpdates.apiSecret = await storeAsSecret(result.sms.apiSecret, 'SMS_API_SECRET');
|
|
5384
|
+
}
|
|
5385
|
+
if (result.sms.apiKey) {
|
|
5386
|
+
smsUpdates.apiKey = await storeAsSecret(result.sms.apiKey, 'SMS_API_KEY');
|
|
5387
|
+
}
|
|
5388
|
+
if (result.sms.accountSid) {
|
|
5389
|
+
smsUpdates.accountSid = await storeAsSecret(result.sms.accountSid, 'SMS_ACCOUNT_SID');
|
|
5390
|
+
}
|
|
5391
|
+
result.sms = Object.assign(Object.assign({}, result.sms), smsUpdates);
|
|
5392
|
+
}
|
|
5393
|
+
// Process push notifications handler (Firebase credentials)
|
|
5394
|
+
if ((_e = result.push_notifications) === null || _e === void 0 ? void 0 : _e.credentials) {
|
|
5395
|
+
const creds = result.push_notifications.credentials;
|
|
5396
|
+
const updatedCreds = Object.assign({}, creds);
|
|
5397
|
+
// Store all Firebase credential fields as secrets
|
|
5398
|
+
if (creds.private_key) {
|
|
5399
|
+
updatedCreds.private_key = await storeAsSecret(creds.private_key, 'PUSH_PRIVATE_KEY');
|
|
5400
|
+
}
|
|
5401
|
+
if (creds.private_key_id) {
|
|
5402
|
+
updatedCreds.private_key_id = await storeAsSecret(creds.private_key_id, 'PUSH_PRIVATE_KEY_ID');
|
|
5403
|
+
}
|
|
5404
|
+
if (creds.client_email) {
|
|
5405
|
+
updatedCreds.client_email = await storeAsSecret(creds.client_email, 'PUSH_CLIENT_EMAIL');
|
|
5406
|
+
}
|
|
5407
|
+
if (creds.client_id) {
|
|
5408
|
+
updatedCreds.client_id = await storeAsSecret(creds.client_id, 'PUSH_CLIENT_ID');
|
|
5409
|
+
}
|
|
5410
|
+
if (creds.project_id) {
|
|
5411
|
+
updatedCreds.project_id = await storeAsSecret(creds.project_id, 'PUSH_PROJECT_ID');
|
|
5412
|
+
}
|
|
5413
|
+
result.push_notifications = Object.assign(Object.assign({}, result.push_notifications), { credentials: updatedCreds });
|
|
5414
|
+
// Store databaseUrl as secret if present
|
|
5415
|
+
if (result.push_notifications.databaseUrl) {
|
|
5416
|
+
result.push_notifications.databaseUrl = await storeAsSecret(result.push_notifications.databaseUrl, 'PUSH_DATABASE_URL');
|
|
5417
|
+
}
|
|
5418
|
+
}
|
|
5419
|
+
// Process callbacks handler (webhook configuration)
|
|
5420
|
+
// Cast to extended type: ICallbackHandler only has url/method/auth; runtime may include headers, query, params, body
|
|
5421
|
+
if (result.callbacks) {
|
|
5422
|
+
const callbacks = result.callbacks;
|
|
5423
|
+
const callbackUpdates = Object.assign({}, callbacks);
|
|
5424
|
+
// Store URL as secret (may contain sensitive paths or tokens)
|
|
5425
|
+
if (callbacks.url) {
|
|
5426
|
+
callbackUpdates.url = await storeAsSecret(callbacks.url, 'CALLBACK_URL');
|
|
5427
|
+
}
|
|
5428
|
+
// Process headers
|
|
5429
|
+
if (callbacks.headers) {
|
|
5430
|
+
const headers = callbacks.headers;
|
|
5431
|
+
const updatedHeaders = Object.assign({}, headers);
|
|
5432
|
+
// Store Authorization header as secret
|
|
5433
|
+
if (headers.Authorization) {
|
|
5434
|
+
updatedHeaders.Authorization = await storeAsSecret(headers.Authorization, 'CALLBACK_AUTHORIZATION');
|
|
5435
|
+
}
|
|
5436
|
+
// Store other common auth headers
|
|
5437
|
+
if (headers['X-API-Key']) {
|
|
5438
|
+
updatedHeaders['X-API-Key'] = await storeAsSecret(headers['X-API-Key'], 'CALLBACK_X_API_KEY');
|
|
5439
|
+
}
|
|
5440
|
+
if (headers['X-Api-Key']) {
|
|
5441
|
+
updatedHeaders['X-Api-Key'] = await storeAsSecret(headers['X-Api-Key'], 'CALLBACK_X_API_KEY');
|
|
5442
|
+
}
|
|
5443
|
+
if (headers['api-key']) {
|
|
5444
|
+
updatedHeaders['api-key'] = await storeAsSecret(headers['api-key'], 'CALLBACK_API_KEY');
|
|
5445
|
+
}
|
|
5446
|
+
if (headers['X-Auth-Token']) {
|
|
5447
|
+
updatedHeaders['X-Auth-Token'] = await storeAsSecret(headers['X-Auth-Token'], 'CALLBACK_X_AUTH_TOKEN');
|
|
5448
|
+
}
|
|
5449
|
+
if (headers['X-Access-Token']) {
|
|
5450
|
+
updatedHeaders['X-Access-Token'] = await storeAsSecret(headers['X-Access-Token'], 'CALLBACK_X_ACCESS_TOKEN');
|
|
5451
|
+
}
|
|
5452
|
+
callbackUpdates.headers = updatedHeaders;
|
|
5453
|
+
}
|
|
5454
|
+
// Process query parameters (may contain sensitive data)
|
|
5455
|
+
if (callbacks.query && typeof callbacks.query === 'object') {
|
|
5456
|
+
const query = callbacks.query;
|
|
5457
|
+
const updatedQuery = {};
|
|
5458
|
+
for (const [key, value] of Object.entries(query)) {
|
|
5459
|
+
// Store common sensitive query params as secrets
|
|
5460
|
+
if (key.toLowerCase().includes('token') ||
|
|
5461
|
+
key.toLowerCase().includes('key') ||
|
|
5462
|
+
key.toLowerCase().includes('secret') ||
|
|
5463
|
+
key.toLowerCase().includes('auth') ||
|
|
5464
|
+
key.toLowerCase().includes('password')) {
|
|
5465
|
+
updatedQuery[key] = await storeAsSecret(value, `CALLBACK_QUERY_${key.toUpperCase()}`);
|
|
5466
|
+
}
|
|
5467
|
+
else {
|
|
5468
|
+
updatedQuery[key] = value;
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
callbackUpdates.query = updatedQuery;
|
|
5472
|
+
}
|
|
5473
|
+
// Process path parameters (may contain sensitive data)
|
|
5474
|
+
if (callbacks.params && typeof callbacks.params === 'object') {
|
|
5475
|
+
const params = callbacks.params;
|
|
5476
|
+
const updatedParams = {};
|
|
5477
|
+
for (const [key, value] of Object.entries(params)) {
|
|
5478
|
+
// Store common sensitive path params as secrets
|
|
5479
|
+
if (key.toLowerCase().includes('token') ||
|
|
5480
|
+
key.toLowerCase().includes('key') ||
|
|
5481
|
+
key.toLowerCase().includes('secret') ||
|
|
5482
|
+
key.toLowerCase().includes('auth') ||
|
|
5483
|
+
key.toLowerCase().includes('password')) {
|
|
5484
|
+
updatedParams[key] = await storeAsSecret(value, `CALLBACK_PARAMS_${key.toUpperCase()}`);
|
|
5485
|
+
}
|
|
5486
|
+
else {
|
|
5487
|
+
updatedParams[key] = value;
|
|
5488
|
+
}
|
|
5489
|
+
}
|
|
5490
|
+
callbackUpdates.params = updatedParams;
|
|
5491
|
+
}
|
|
5492
|
+
// Process body (may contain sensitive data - store entire body as secret if it's a string)
|
|
5493
|
+
if (callbacks.body) {
|
|
5494
|
+
if (typeof callbacks.body === 'string') {
|
|
5495
|
+
callbackUpdates.body = await storeAsSecret(callbacks.body, 'CALLBACK_BODY');
|
|
5496
|
+
}
|
|
5497
|
+
else if (typeof callbacks.body === 'object') {
|
|
5498
|
+
// If body is an object, check for sensitive fields
|
|
5499
|
+
const body = callbacks.body;
|
|
5500
|
+
const updatedBody = {};
|
|
5501
|
+
for (const [key, value] of Object.entries(body)) {
|
|
5502
|
+
if (typeof value === 'string' &&
|
|
5503
|
+
(key.toLowerCase().includes('token') ||
|
|
5504
|
+
key.toLowerCase().includes('key') ||
|
|
5505
|
+
key.toLowerCase().includes('secret') ||
|
|
5506
|
+
key.toLowerCase().includes('auth') ||
|
|
5507
|
+
key.toLowerCase().includes('password'))) {
|
|
5508
|
+
updatedBody[key] = await storeAsSecret(value, `CALLBACK_BODY_${key.toUpperCase()}`);
|
|
5509
|
+
}
|
|
5510
|
+
else {
|
|
5511
|
+
updatedBody[key] = value;
|
|
5512
|
+
}
|
|
5513
|
+
}
|
|
5514
|
+
callbackUpdates.body = updatedBody;
|
|
5515
|
+
}
|
|
5516
|
+
}
|
|
5517
|
+
result.callbacks = callbackUpdates;
|
|
5518
|
+
}
|
|
5519
|
+
return result;
|
|
5520
|
+
}
|
|
5521
|
+
/**
|
|
5522
|
+
* Store graph connection URL as a secret
|
|
5523
|
+
* Format: GRAPH_{PRODUCT}_{GRAPH_TAG}_{ENV}_URL
|
|
5524
|
+
*/
|
|
5525
|
+
async storeGraphConnectionUrlAsSecret(connectionUrl, graphTag, envSlug) {
|
|
5526
|
+
var _a;
|
|
5527
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Starting secret conversion:', {
|
|
5528
|
+
graphTag,
|
|
5529
|
+
envSlug,
|
|
5530
|
+
hasConnectionUrl: !!connectionUrl,
|
|
5531
|
+
connectionUrlLength: connectionUrl === null || connectionUrl === void 0 ? void 0 : connectionUrl.length,
|
|
5532
|
+
productTag: (_a = this.product) === null || _a === void 0 ? void 0 : _a.tag,
|
|
5533
|
+
});
|
|
5534
|
+
const secretsService = (0, secrets_1.getSecretsService)();
|
|
5535
|
+
if (!secretsService) {
|
|
5536
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] No secrets service available, returning original value');
|
|
5537
|
+
return connectionUrl;
|
|
5538
|
+
}
|
|
5539
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Secrets service is available');
|
|
5540
|
+
const secretCheck = (0, secrets_1.isSecretReference)(connectionUrl);
|
|
5541
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Secret reference check:', {
|
|
5542
|
+
isSecret: secretCheck.isSecret,
|
|
5543
|
+
secretKey: secretCheck.isSecret ? secretCheck.key : null,
|
|
5544
|
+
});
|
|
5545
|
+
if (secretCheck.isSecret) {
|
|
5546
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Value is already a secret reference, returning as-is');
|
|
5547
|
+
return connectionUrl;
|
|
5548
|
+
}
|
|
5549
|
+
const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
|
|
5550
|
+
const productParts = this.product.tag.split(':');
|
|
5551
|
+
const productKey = productParts[1] || productParts[0]; // Use product name (index 1), fallback to index 0
|
|
5552
|
+
const graphKey = graphTag.replace(/-/g, '_');
|
|
5553
|
+
const secretKey = `GRAPH_${sanitize(productKey)}_${sanitize(graphKey)}_${sanitize(envSlug)}_URL`;
|
|
5554
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Generated secret key:', {
|
|
5555
|
+
secretKey,
|
|
5556
|
+
productParts,
|
|
5557
|
+
productKey,
|
|
5558
|
+
graphKey,
|
|
5559
|
+
});
|
|
5560
|
+
try {
|
|
5561
|
+
const exists = await secretsService.exists(secretKey);
|
|
5562
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Secret exists check:', { secretKey, exists });
|
|
5563
|
+
if (exists) {
|
|
5564
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Updating existing secret:', secretKey);
|
|
5565
|
+
await secretsService.update(secretKey, { value: connectionUrl });
|
|
5566
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Secret updated successfully');
|
|
5567
|
+
}
|
|
5568
|
+
else {
|
|
5569
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Creating new secret:', {
|
|
5570
|
+
secretKey,
|
|
5571
|
+
description: `Graph connection URL for ${graphTag} in ${envSlug}`,
|
|
5572
|
+
scope: [this.product.tag, graphTag],
|
|
5573
|
+
envs: [envSlug],
|
|
5574
|
+
});
|
|
5575
|
+
await secretsService.create({
|
|
5576
|
+
key: secretKey,
|
|
5577
|
+
value: connectionUrl,
|
|
5578
|
+
description: `Graph connection URL for ${graphTag} in ${envSlug}`,
|
|
5579
|
+
scope: [this.product.tag, graphTag],
|
|
5580
|
+
envs: [envSlug],
|
|
5581
|
+
});
|
|
5582
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Secret created successfully');
|
|
5583
|
+
}
|
|
5584
|
+
const secretRef = `$Secret{${secretKey}}`;
|
|
5585
|
+
console.log('[ProductsService.storeGraphConnectionUrlAsSecret] Returning secret reference:', secretRef);
|
|
5586
|
+
return secretRef;
|
|
5587
|
+
}
|
|
5588
|
+
catch (error) {
|
|
5589
|
+
console.error('[ProductsService.storeGraphConnectionUrlAsSecret] Failed to store secret:', {
|
|
5590
|
+
secretKey,
|
|
5591
|
+
error: error instanceof Error ? error.message : String(error),
|
|
5592
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
5593
|
+
});
|
|
5594
|
+
return connectionUrl;
|
|
5595
|
+
}
|
|
5596
|
+
}
|
|
5597
|
+
/**
|
|
5598
|
+
* Generate a secret key for vector configuration field
|
|
5599
|
+
* Format: VECTOR_{PRODUCT}_{ASSET_TAG}_{ENV}_{KEY}
|
|
5600
|
+
*
|
|
5601
|
+
* Where:
|
|
5602
|
+
* - PRODUCT = productTag.split('.')[1] (second part after workspace)
|
|
5603
|
+
* - ASSET_TAG = if vectorTag starts with same workspace prefix, use second part; otherwise sanitize full tag
|
|
5604
|
+
* - All parts are automatically capitalized
|
|
5605
|
+
*/
|
|
5606
|
+
generateVectorSecretKey(vectorTag, envSlug, field) {
|
|
5607
|
+
var _a;
|
|
5608
|
+
console.log('[ProductsService.generateVectorSecretKey] Generating secret key:', {
|
|
5609
|
+
vectorTag,
|
|
5610
|
+
envSlug,
|
|
5611
|
+
field,
|
|
5612
|
+
productTag: (_a = this.product) === null || _a === void 0 ? void 0 : _a.tag,
|
|
5613
|
+
});
|
|
5614
|
+
const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
|
|
5615
|
+
// Support both ':' and '.' delimiters for product tags (e.g., 'ductape:rematch' or 'ductape.rematch')
|
|
5616
|
+
const productParts = this.product.tag.includes(':')
|
|
5617
|
+
? this.product.tag.split(':')
|
|
5618
|
+
: this.product.tag.split('.');
|
|
5619
|
+
const product = productParts[1] || productParts[0]; // Use product name (index 1), fallback to index 0
|
|
5620
|
+
const workspace = productParts[0];
|
|
5621
|
+
console.log('[ProductsService.generateVectorSecretKey] Product parsing:', {
|
|
5622
|
+
productParts,
|
|
5623
|
+
product,
|
|
5624
|
+
workspace,
|
|
5625
|
+
});
|
|
5626
|
+
// Support both ':' and '.' delimiters for vector tags
|
|
5627
|
+
const vectorParts = vectorTag.includes(':') ? vectorTag.split(':') : vectorTag.split('.');
|
|
5628
|
+
let assetTag;
|
|
5629
|
+
if (vectorParts.length > 1 && vectorParts[0] === workspace) {
|
|
5630
|
+
// Same workspace prefix, use second part
|
|
5631
|
+
assetTag = vectorParts[1];
|
|
5632
|
+
console.log('[ProductsService.generateVectorSecretKey] Using second part of vectorTag:', assetTag);
|
|
5633
|
+
}
|
|
5634
|
+
else {
|
|
5635
|
+
// Different or no prefix, use full tag
|
|
5636
|
+
assetTag = vectorTag;
|
|
5637
|
+
console.log('[ProductsService.generateVectorSecretKey] Using full vectorTag:', assetTag);
|
|
5638
|
+
}
|
|
5639
|
+
const secretKey = `VECTOR_${sanitize(product)}_${sanitize(assetTag)}_${sanitize(envSlug)}_${sanitize(field)}`;
|
|
5640
|
+
console.log('[ProductsService.generateVectorSecretKey] Generated secret key:', secretKey);
|
|
5641
|
+
return secretKey;
|
|
5642
|
+
}
|
|
5643
|
+
/**
|
|
5644
|
+
* Store a vector field value as a secret if it exists and is not already a secret reference
|
|
5645
|
+
* @returns The secret reference if stored, or the original value
|
|
5646
|
+
*/
|
|
5647
|
+
async storeVectorFieldAsSecret(value, vectorTag, envSlug, fieldName, description) {
|
|
5648
|
+
var _a;
|
|
5649
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Starting secret conversion:', {
|
|
5650
|
+
vectorTag,
|
|
5651
|
+
envSlug,
|
|
5652
|
+
fieldName,
|
|
5653
|
+
hasValue: !!value,
|
|
5654
|
+
valueLength: value === null || value === void 0 ? void 0 : value.length,
|
|
5655
|
+
productTag: (_a = this.product) === null || _a === void 0 ? void 0 : _a.tag,
|
|
5656
|
+
});
|
|
5657
|
+
if (!value) {
|
|
5658
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] No value provided, returning undefined');
|
|
5659
|
+
return undefined;
|
|
5660
|
+
}
|
|
5661
|
+
const secretsService = (0, secrets_1.getSecretsService)();
|
|
5662
|
+
if (!secretsService) {
|
|
5663
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] No secrets service available, returning original value');
|
|
5664
|
+
return value;
|
|
5665
|
+
}
|
|
5666
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Secrets service is available');
|
|
5667
|
+
const secretCheck = (0, secrets_1.isSecretReference)(value);
|
|
5668
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Secret reference check:', {
|
|
5669
|
+
isSecret: secretCheck.isSecret,
|
|
5670
|
+
secretKey: secretCheck.isSecret ? secretCheck.key : null,
|
|
5671
|
+
});
|
|
5672
|
+
if (secretCheck.isSecret) {
|
|
5673
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Value is already a secret reference, returning as-is');
|
|
5674
|
+
return value;
|
|
5675
|
+
}
|
|
5676
|
+
const secretKey = this.generateVectorSecretKey(vectorTag, envSlug, fieldName);
|
|
5677
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Generated secret key:', secretKey);
|
|
5678
|
+
try {
|
|
5679
|
+
const exists = await secretsService.exists(secretKey);
|
|
5680
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Secret exists check:', { secretKey, exists });
|
|
5681
|
+
if (exists) {
|
|
5682
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Updating existing secret:', secretKey);
|
|
5683
|
+
await secretsService.update(secretKey, { value });
|
|
5684
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Secret updated successfully');
|
|
5685
|
+
}
|
|
5686
|
+
else {
|
|
5687
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Creating new secret:', {
|
|
5688
|
+
secretKey,
|
|
5689
|
+
description,
|
|
5690
|
+
scope: [this.product.tag, vectorTag],
|
|
5691
|
+
envs: [envSlug],
|
|
5692
|
+
});
|
|
5693
|
+
await secretsService.create({
|
|
5694
|
+
key: secretKey,
|
|
5695
|
+
value,
|
|
5696
|
+
description,
|
|
5697
|
+
scope: [this.product.tag, vectorTag],
|
|
5698
|
+
envs: [envSlug],
|
|
5699
|
+
});
|
|
5700
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Secret created successfully');
|
|
5701
|
+
}
|
|
5702
|
+
const secretRef = `$Secret{${secretKey}}`;
|
|
5703
|
+
console.log('[ProductsService.storeVectorFieldAsSecret] Returning secret reference:', secretRef);
|
|
5704
|
+
return secretRef;
|
|
5705
|
+
}
|
|
5706
|
+
catch (error) {
|
|
5707
|
+
console.error('[ProductsService.storeVectorFieldAsSecret] Failed to store secret:', {
|
|
5708
|
+
secretKey,
|
|
5709
|
+
fieldName,
|
|
5710
|
+
error: error instanceof Error ? error.message : String(error),
|
|
5711
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
5712
|
+
});
|
|
5713
|
+
return value;
|
|
5714
|
+
}
|
|
5715
|
+
}
|
|
5716
|
+
async storeVectorApiKeyAsSecret(apiKey, vectorTag, envSlug) {
|
|
5717
|
+
console.log('[ProductsService.storeVectorApiKeyAsSecret] Storing API key as secret:', {
|
|
5718
|
+
vectorTag,
|
|
5719
|
+
envSlug,
|
|
5720
|
+
hasApiKey: !!apiKey,
|
|
5721
|
+
apiKeyLength: apiKey === null || apiKey === void 0 ? void 0 : apiKey.length,
|
|
5722
|
+
});
|
|
5723
|
+
const result = await this.storeVectorFieldAsSecret(apiKey, vectorTag, envSlug, 'API_KEY', `Vector API key for ${vectorTag} in ${envSlug}`);
|
|
5724
|
+
console.log('[ProductsService.storeVectorApiKeyAsSecret] Result:', {
|
|
5725
|
+
hasResult: !!result,
|
|
5726
|
+
isSecretRef: result === null || result === void 0 ? void 0 : result.startsWith('$Secret{'),
|
|
5727
|
+
});
|
|
5728
|
+
return result || apiKey;
|
|
5729
|
+
}
|
|
5730
|
+
async storeVectorEndpointAsSecret(endpoint, vectorTag, envSlug) {
|
|
5731
|
+
console.log('[ProductsService.storeVectorEndpointAsSecret] Storing endpoint as secret:', {
|
|
5732
|
+
vectorTag,
|
|
5733
|
+
envSlug,
|
|
5734
|
+
hasEndpoint: !!endpoint,
|
|
5735
|
+
endpointLength: endpoint === null || endpoint === void 0 ? void 0 : endpoint.length,
|
|
5736
|
+
});
|
|
5737
|
+
const result = await this.storeVectorFieldAsSecret(endpoint, vectorTag, envSlug, 'ENDPOINT', `Vector endpoint for ${vectorTag} in ${envSlug}`);
|
|
5738
|
+
console.log('[ProductsService.storeVectorEndpointAsSecret] Result:', {
|
|
5739
|
+
hasResult: !!result,
|
|
5740
|
+
isSecretRef: result === null || result === void 0 ? void 0 : result.startsWith('$Secret{'),
|
|
5741
|
+
});
|
|
5742
|
+
return result || endpoint;
|
|
5743
|
+
}
|
|
5744
|
+
/**
|
|
5745
|
+
* Store LLM model API key as a secret
|
|
5746
|
+
* Format: MODEL_{PRODUCT}_{MODEL_TAG}_{ENV}_API_KEY
|
|
5747
|
+
*/
|
|
5748
|
+
async storeModelApiKeyAsSecret(apiKey, modelTag, envSlug) {
|
|
5749
|
+
const secretsService = (0, secrets_1.getSecretsService)();
|
|
5750
|
+
if (!secretsService) {
|
|
5751
|
+
return apiKey;
|
|
5752
|
+
}
|
|
5753
|
+
const secretCheck = (0, secrets_1.isSecretReference)(apiKey);
|
|
5754
|
+
if (secretCheck.isSecret) {
|
|
5755
|
+
return apiKey;
|
|
5756
|
+
}
|
|
5757
|
+
const sanitize = (str) => str.toUpperCase().replace(/[^A-Z0-9]/g, '_');
|
|
5758
|
+
const productParts = this.product.tag.split(':');
|
|
5759
|
+
const productKey = productParts[1] || productParts[0]; // Use product name (index 1), fallback to index 0
|
|
5760
|
+
const modelKey = modelTag.replace(/-/g, '_');
|
|
5761
|
+
const secretKey = `MODEL_${sanitize(productKey)}_${sanitize(modelKey)}_${sanitize(envSlug)}_API_KEY`;
|
|
5762
|
+
try {
|
|
5763
|
+
const exists = await secretsService.exists(secretKey);
|
|
5764
|
+
if (exists) {
|
|
5765
|
+
await secretsService.update(secretKey, { value: apiKey });
|
|
5766
|
+
}
|
|
5767
|
+
else {
|
|
5768
|
+
await secretsService.create({
|
|
5769
|
+
key: secretKey,
|
|
5770
|
+
value: apiKey,
|
|
5771
|
+
description: `LLM model API key for ${modelTag} in ${envSlug}`,
|
|
5772
|
+
scope: [this.product.tag, modelTag],
|
|
5773
|
+
envs: [envSlug],
|
|
5774
|
+
});
|
|
5775
|
+
}
|
|
5776
|
+
return `$Secret{${secretKey}}`;
|
|
5777
|
+
}
|
|
5778
|
+
catch (error) {
|
|
5779
|
+
console.warn(`Failed to store model API key as secret: ${error}`);
|
|
5780
|
+
return apiKey;
|
|
5781
|
+
}
|
|
2982
5782
|
}
|
|
2983
5783
|
}
|
|
5784
|
+
/** Only log when DUCTAPE_DEBUG is set (avoids sync I/O cost in workflow hot path) */
|
|
5785
|
+
ProductsBuilderService._debug = typeof process !== 'undefined' && (((_a = process.env) === null || _a === void 0 ? void 0 : _a.DUCTAPE_DEBUG) === 'true' || ((_b = process.env) === null || _b === void 0 ? void 0 : _b.DUCTAPE_DEBUG) === '1');
|
|
2984
5786
|
exports.default = ProductsBuilderService;
|
|
2985
5787
|
//# sourceMappingURL=products.service.js.map
|