@ductape/sdk 0.0.4-v51 → 0.0.4-v52
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 +1 -1
- package/dist/agents/agent-context.d.ts +98 -0
- package/dist/agents/agent-context.js +588 -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 +304 -0
- package/dist/agents/agents.service.js +1244 -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 +1225 -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.js +4 -5
- package/dist/api/services/appApi.service.js.map +1 -1
- package/dist/api/services/processorApi.service.d.ts +322 -0
- package/dist/api/services/processorApi.service.js +252 -0
- package/dist/api/services/processorApi.service.js.map +1 -1
- package/dist/api/services/productsApi.service.d.ts +69 -1
- package/dist/api/services/productsApi.service.js +67 -31
- 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 +38 -0
- package/dist/api/services/secretsApi.service.js +96 -0
- package/dist/api/services/secretsApi.service.js.map +1 -0
- package/dist/api/services/userApi.service.js +0 -1
- package/dist/api/services/userApi.service.js.map +1 -1
- package/dist/api/services/workflowApi.service.d.ts +199 -0
- package/dist/api/services/workflowApi.service.js +183 -0
- package/dist/api/services/workflowApi.service.js.map +1 -0
- package/dist/api/services/workspaceApi.service.js +0 -1
- package/dist/api/services/workspaceApi.service.js.map +1 -1
- package/dist/api/urls.d.ts +57 -0
- package/dist/api/urls.js +68 -1
- package/dist/api/urls.js.map +1 -1
- package/dist/api/utils/cache.utils.js +4 -10
- package/dist/api/utils/cache.utils.js.map +1 -1
- package/dist/apps/services/app.service.d.ts +0 -10
- package/dist/apps/services/app.service.js +74 -30
- 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 +405 -0
- package/dist/apps/utils/oauth-manager.js.map +1 -0
- package/dist/apps/validators/joi-validators/create.appWebhook.validator.d.ts +2 -1
- package/dist/apps/validators/joi-validators/create.appWebhook.validator.js +15 -2
- package/dist/apps/validators/joi-validators/create.appWebhook.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/update.appWebhook.validator.d.ts +2 -1
- package/dist/apps/validators/joi-validators/update.appWebhook.validator.js +14 -2
- package/dist/apps/validators/joi-validators/update.appWebhook.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 +257 -0
- package/dist/brokers/brokers.service.js +604 -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 +288 -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/brokers/utils/providers/aws-sqs.service.d.ts +16 -0
- 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/brokers/utils/providers/google-pubsub.service.d.ts +16 -0
- package/dist/brokers/utils/providers/google-pubsub.service.js +43 -0
- 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 +16 -0
- package/dist/brokers/utils/providers/kafka.service.js +52 -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 +14 -0
- package/dist/brokers/utils/providers/rabbitmq.service.js +67 -0
- package/dist/brokers/utils/providers/rabbitmq.service.js.map +1 -0
- package/dist/brokers/utils/providers/redis.service.d.ts +18 -0
- package/dist/brokers/utils/providers/redis.service.js +93 -0
- package/dist/brokers/utils/providers/redis.service.js.map +1 -0
- package/dist/cache/cache.manager.d.ts +159 -0
- package/dist/cache/cache.manager.js +265 -0
- package/dist/cache/cache.manager.js.map +1 -0
- package/dist/cache/cache.service.d.ts +186 -0
- package/dist/cache/cache.service.js +437 -0
- package/dist/cache/cache.service.js.map +1 -0
- package/dist/cache/index.d.ts +52 -0
- package/dist/cache/index.js +79 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/types/index.d.ts +106 -0
- package/dist/cache/types/index.js +6 -0
- package/dist/cache/types/index.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 +307 -90
- package/dist/database/adapters/base.adapter.js +139 -20
- package/dist/database/adapters/base.adapter.js.map +1 -1
- package/dist/database/adapters/cassandra.adapter.d.ts +90 -0
- package/dist/database/adapters/cassandra.adapter.js +1019 -0
- package/dist/database/adapters/cassandra.adapter.js.map +1 -0
- package/dist/database/adapters/dynamodb.adapter.d.ts +94 -77
- package/dist/database/adapters/dynamodb.adapter.js +1162 -1305
- package/dist/database/adapters/dynamodb.adapter.js.map +1 -1
- 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 +105 -57
- package/dist/database/adapters/mongodb.adapter.js +941 -838
- package/dist/database/adapters/mongodb.adapter.js.map +1 -1
- package/dist/database/adapters/mysql.adapter.d.ts +76 -138
- package/dist/database/adapters/mysql.adapter.js +990 -1246
- package/dist/database/adapters/mysql.adapter.js.map +1 -1
- package/dist/database/adapters/postgresql.adapter.d.ts +75 -139
- package/dist/database/adapters/postgresql.adapter.js +1076 -1346
- package/dist/database/adapters/postgresql.adapter.js.map +1 -1
- package/dist/database/databases.service.d.ts +1374 -0
- package/dist/database/databases.service.js +2680 -0
- package/dist/database/databases.service.js.map +1 -0
- package/dist/database/index.d.ts +41 -13
- package/dist/database/index.js +97 -86
- package/dist/database/index.js.map +1 -1
- 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 +132 -0
- package/dist/database/migrations/migration-engine.js +1356 -0
- package/dist/database/migrations/migration-engine.js.map +1 -0
- package/dist/database/operators/aggregation-builder.d.ts +64 -0
- package/dist/database/operators/aggregation-builder.js +746 -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 +55 -0
- package/dist/database/operators/query-builder.js +365 -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 +637 -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 +179 -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/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 +12 -10
- package/dist/database/types/index.js +26 -32
- package/dist/database/types/index.js.map +1 -1
- 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 +199 -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 +398 -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 +208 -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 +78 -72
- package/dist/graph/adapters/arangodb.adapter.js +1310 -1220
- package/dist/graph/adapters/arangodb.adapter.js.map +1 -1
- package/dist/graph/adapters/base.adapter.d.ts +135 -118
- package/dist/graph/adapters/base.adapter.js +46 -20
- package/dist/graph/adapters/base.adapter.js.map +1 -1
- package/dist/graph/adapters/index.d.ts +5 -4
- package/dist/graph/adapters/index.js +6 -8
- package/dist/graph/adapters/index.js.map +1 -1
- package/dist/graph/adapters/memgraph.adapter.d.ts +98 -73
- package/dist/graph/adapters/memgraph.adapter.js +1050 -1202
- package/dist/graph/adapters/memgraph.adapter.js.map +1 -1
- package/dist/graph/adapters/neo4j.adapter.d.ts +71 -78
- package/dist/graph/adapters/neo4j.adapter.js +912 -1605
- package/dist/graph/adapters/neo4j.adapter.js.map +1 -1
- package/dist/graph/adapters/neptune.adapter.d.ts +76 -81
- package/dist/graph/adapters/neptune.adapter.js +1095 -1228
- package/dist/graph/adapters/neptune.adapter.js.map +1 -1
- package/dist/graph/graphs.service.d.ts +524 -0
- package/dist/graph/graphs.service.js +1683 -0
- package/dist/graph/graphs.service.js.map +1 -0
- package/dist/graph/index.d.ts +54 -8
- package/dist/graph/index.js +67 -32
- package/dist/graph/index.js.map +1 -1
- 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 +141 -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 +11 -9
- package/dist/graph/types/index.js +15 -30
- package/dist/graph/types/index.js.map +1 -1
- 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 +168 -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/index.d.ts +1905 -875
- package/dist/index.js +3063 -1282
- package/dist/index.js.map +1 -1
- package/dist/init.interface.d.ts +407 -0
- package/dist/init.interface.js +3 -0
- package/dist/init.interface.js.map +1 -0
- 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.types.d.ts +12 -2
- package/dist/logs/logs.types.js +5 -1
- 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 +252 -0
- package/dist/notifications/notifications.service.js +654 -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 +400 -0
- package/dist/notifications/types/notifications.types.js +49 -0
- package/dist/notifications/types/notifications.types.js.map +1 -0
- package/dist/processor/services/messagebrokers/kafka.service.js +2 -0
- package/dist/processor/services/messagebrokers/kafka.service.js.map +1 -1
- package/dist/processor/services/messagebrokers/rabbitmq.service.d.ts +1 -9
- package/dist/processor/services/messagebrokers/rabbitmq.service.js +11 -40
- package/dist/processor/services/messagebrokers/rabbitmq.service.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +86 -70
- package/dist/processor/services/processor.service.js +1353 -1259
- package/dist/processor/services/processor.service.js.map +1 -1
- package/dist/processor/utils/processor.utils.js +5 -1
- package/dist/processor/utils/processor.utils.js.map +1 -1
- package/dist/products/services/products.service.d.ts +167 -25
- package/dist/products/services/products.service.js +1248 -412
- package/dist/products/services/products.service.js.map +1 -1
- package/dist/products/validators/index.d.ts +6 -3
- package/dist/products/validators/index.js +14 -5
- 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 +218 -0
- package/dist/products/validators/joi-validators/create.productAgent.validator.js.map +1 -0
- 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.productDatabaseAction.validator.d.ts +4 -15
- package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.js +109 -501
- package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productGraph.validator.js +14 -9
- package/dist/products/validators/joi-validators/create.productGraph.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productMessageBrokerTopic.validator.js +0 -1
- package/dist/products/validators/joi-validators/create.productMessageBrokerTopic.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js +87 -30
- 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 +135 -50
- 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 +135 -0
- package/dist/products/validators/joi-validators/create.productVector.validator.js.map +1 -0
- 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.productDatabaseAction.validator.d.ts +0 -6
- package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.js +26 -28
- package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productGraph.validator.js +11 -12
- package/dist/products/validators/joi-validators/update.productGraph.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productMessageBrokerTopic.validator.js +0 -1
- package/dist/products/validators/joi-validators/update.productMessageBrokerTopic.validator.js.map +1 -1
- package/dist/resilience/fallback.service.d.ts +88 -0
- package/dist/resilience/fallback.service.js +511 -0
- package/dist/resilience/fallback.service.js.map +1 -0
- package/dist/resilience/healthcheck.service.d.ts +106 -0
- package/dist/resilience/healthcheck.service.js +379 -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 +90 -0
- package/dist/resilience/quota.service.js +519 -0
- package/dist/resilience/quota.service.js.map +1 -0
- package/dist/resilience/resilience.service.d.ts +95 -0
- package/dist/resilience/resilience.service.js +525 -0
- package/dist/resilience/resilience.service.js.map +1 -0
- package/dist/resilience/types/index.d.ts +479 -0
- package/dist/resilience/types/index.js +26 -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 +233 -0
- package/dist/secrets/secrets.resolver.js.map +1 -0
- package/dist/secrets/secrets.service.d.ts +83 -0
- package/dist/secrets/secrets.service.js +159 -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 +93 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/sessions/sessions.helper.d.ts +68 -0
- package/dist/sessions/sessions.helper.js +116 -0
- package/dist/sessions/sessions.helper.js.map +1 -0
- package/dist/sessions/sessions.resolver.d.ts +150 -0
- package/dist/sessions/sessions.resolver.js +356 -0
- package/dist/sessions/sessions.resolver.js.map +1 -0
- package/dist/sessions/sessions.service.d.ts +170 -0
- package/dist/sessions/sessions.service.js +736 -0
- package/dist/sessions/sessions.service.js.map +1 -0
- package/dist/sessions/types/index.d.ts +290 -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 +98 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/storage.service.d.ts +123 -0
- package/dist/storage/storage.service.js +478 -0
- package/dist/storage/storage.service.js.map +1 -0
- package/dist/storage/types/index.d.ts +207 -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 +51 -0
- package/dist/storage/utils/storage.util.js +402 -0
- package/dist/storage/utils/storage.util.js.map +1 -0
- package/dist/test/index.d.ts +3 -0
- package/dist/test/index.js +13 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test/test.appBuilder.d.ts +0 -1
- package/dist/test/test.appBuilder.js +0 -15
- package/dist/test/test.appBuilder.js.map +1 -1
- package/dist/test/test.database.js +140 -0
- package/dist/test/test.database.js.map +1 -0
- package/dist/test/test.health.d.ts +0 -1
- package/dist/test/test.health.js +0 -48
- package/dist/test/test.health.js.map +1 -1
- package/dist/test/test.import.d.ts +0 -1
- package/dist/test/test.import.js +0 -1506
- package/dist/test/test.import.js.map +1 -1
- package/dist/test/test.import.openapi.d.ts +0 -1
- package/dist/test/test.import.openapi.js +0 -75
- package/dist/test/test.import.openapi.js.map +1 -1
- package/dist/test/test.imports.d.ts +0 -1
- package/dist/test/test.imports.js +0 -76
- package/dist/test/test.imports.js.map +1 -1
- package/dist/test/test.logs.d.ts +0 -1
- package/dist/test/test.logs.js +0 -17
- package/dist/test/test.logs.js.map +1 -1
- package/dist/test/test.notifiers.d.ts +0 -1
- package/dist/test/test.notifiers.js +0 -84
- package/dist/test/test.notifiers.js.map +1 -1
- package/dist/test/test.processor.d.ts +0 -1
- package/dist/test/test.processor.js +0 -37
- package/dist/test/test.processor.js.map +1 -1
- package/dist/test/test.productBuilder.d.ts +0 -1
- package/dist/test/test.productBuilder.js +0 -660
- package/dist/test/test.productBuilder.js.map +1 -1
- package/dist/test/test.products.d.ts +0 -1
- package/dist/test/test.products.js +0 -48
- package/dist/test/test.products.js.map +1 -1
- package/dist/test/test.storage.js +332 -0
- package/dist/test/test.storage.js.map +1 -0
- package/dist/test/test.triggers.js +314 -0
- package/dist/test/test.triggers.js.map +1 -0
- package/dist/types/appBuilder.types.d.ts +1 -1
- package/dist/types/enums.d.ts +6 -1
- package/dist/types/enums.js +5 -0
- package/dist/types/enums.js.map +1 -1
- package/dist/types/processor.types.d.ts +197 -35
- package/dist/types/processor.types.js +9 -1
- package/dist/types/processor.types.js.map +1 -1
- package/dist/types/productsBuilder.types.d.ts +837 -75
- package/dist/types/productsBuilder.types.js +168 -62
- package/dist/types/productsBuilder.types.js.map +1 -1
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +2 -49
- package/dist/utils/index.js.map +1 -1
- package/dist/vector/adapters/base.adapter.d.ts +152 -0
- package/dist/vector/adapters/base.adapter.js +137 -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 +400 -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 +392 -0
- package/dist/vector/adapters/qdrant.adapter.js.map +1 -0
- package/dist/vector/adapters/weaviate.adapter.d.ts +64 -0
- package/dist/vector/adapters/weaviate.adapter.js +478 -0
- package/dist/vector/adapters/weaviate.adapter.js.map +1 -0
- package/dist/vector/index.d.ts +47 -0
- package/dist/vector/index.js +72 -0
- package/dist/vector/index.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 +9 -0
- package/dist/vector/types/index.js +16 -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 +117 -0
- package/dist/vector/utils/vector-error.js.map +1 -0
- package/dist/vector/vector-database.service.d.ts +405 -0
- package/dist/vector/vector-database.service.js +544 -0
- package/dist/vector/vector-database.service.js.map +1 -0
- package/dist/vector/vector.service.d.ts +245 -0
- package/dist/vector/vector.service.js +381 -0
- package/dist/vector/vector.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 +1035 -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 +338 -0
- package/dist/workflows/workflow-builder.js.map +1 -0
- package/dist/workflows/workflow-executor.d.ts +205 -0
- package/dist/workflows/workflow-executor.js +1186 -0
- package/dist/workflows/workflow-executor.js.map +1 -0
- package/dist/workflows/workflows.service.d.ts +398 -0
- package/dist/workflows/workflows.service.js +1595 -0
- package/dist/workflows/workflows.service.js.map +1 -0
- package/package.json +16 -13
- package/dist/actions/actions.repo.d.ts +0 -0
- package/dist/actions/actions.repo.js +0 -13
- package/dist/actions/actions.repo.js.map +0 -1
- package/dist/actions/actions.service.d.ts +0 -0
- 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/api/services/workspaceSecretsApi.service.d.ts +0 -75
- package/dist/api/services/workspaceSecretsApi.service.js +0 -62
- package/dist/api/services/workspaceSecretsApi.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.d.ts +0 -3
- 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.d.ts +0 -3
- 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/database/database.service.d.ts +0 -232
- package/dist/database/database.service.js +0 -802
- package/dist/database/database.service.js.map +0 -1
- package/dist/database/types/aggregation.types.d.ts +0 -261
- package/dist/database/types/aggregation.types.js +0 -21
- package/dist/database/types/aggregation.types.js.map +0 -1
- package/dist/database/types/connection.types.d.ts +0 -132
- package/dist/database/types/connection.types.js +0 -6
- package/dist/database/types/connection.types.js.map +0 -1
- package/dist/database/types/database.types.d.ts +0 -175
- package/dist/database/types/database.types.js +0 -75
- package/dist/database/types/database.types.js.map +0 -1
- package/dist/database/types/index.types.d.ts +0 -220
- package/dist/database/types/index.types.js +0 -27
- package/dist/database/types/index.types.js.map +0 -1
- package/dist/database/types/migration.types.d.ts +0 -205
- package/dist/database/types/migration.types.js +0 -44
- package/dist/database/types/migration.types.js.map +0 -1
- package/dist/database/types/query.types.d.ts +0 -305
- package/dist/database/types/query.types.js +0 -57
- package/dist/database/types/query.types.js.map +0 -1
- package/dist/database/types/result.types.d.ts +0 -220
- package/dist/database/types/result.types.js +0 -6
- package/dist/database/types/result.types.js.map +0 -1
- package/dist/database/types/schema.types.d.ts +0 -190
- package/dist/database/types/schema.types.js +0 -69
- package/dist/database/types/schema.types.js.map +0 -1
- package/dist/database/utils/helpers.d.ts +0 -66
- package/dist/database/utils/helpers.js +0 -501
- package/dist/database/utils/helpers.js.map +0 -1
- package/dist/database/utils/migration.utils.d.ts +0 -151
- package/dist/database/utils/migration.utils.js +0 -476
- package/dist/database/utils/migration.utils.js.map +0 -1
- package/dist/database/utils/transaction.d.ts +0 -64
- package/dist/database/utils/transaction.js +0 -130
- package/dist/database/utils/transaction.js.map +0 -1
- package/dist/database/validators/connection.validator.d.ts +0 -20
- package/dist/database/validators/connection.validator.js +0 -267
- package/dist/database/validators/connection.validator.js.map +0 -1
- package/dist/database/validators/query.validator.d.ts +0 -31
- package/dist/database/validators/query.validator.js +0 -305
- package/dist/database/validators/query.validator.js.map +0 -1
- package/dist/database/validators/schema.validator.d.ts +0 -31
- package/dist/database/validators/schema.validator.js +0 -334
- package/dist/database/validators/schema.validator.js.map +0 -1
- package/dist/graph/graph.service.d.ts +0 -278
- package/dist/graph/graph.service.js +0 -687
- package/dist/graph/graph.service.js.map +0 -1
- package/dist/graph/types/connection.types.d.ts +0 -158
- package/dist/graph/types/connection.types.js +0 -43
- package/dist/graph/types/connection.types.js.map +0 -1
- package/dist/graph/types/graph.types.d.ts +0 -144
- package/dist/graph/types/graph.types.js +0 -84
- package/dist/graph/types/graph.types.js.map +0 -1
- package/dist/graph/types/node.types.d.ts +0 -193
- package/dist/graph/types/node.types.js +0 -49
- package/dist/graph/types/node.types.js.map +0 -1
- package/dist/graph/types/path.types.d.ts +0 -224
- package/dist/graph/types/path.types.js +0 -38
- package/dist/graph/types/path.types.js.map +0 -1
- package/dist/graph/types/query.types.d.ts +0 -247
- package/dist/graph/types/query.types.js +0 -23
- package/dist/graph/types/query.types.js.map +0 -1
- package/dist/graph/types/relationship.types.d.ts +0 -224
- package/dist/graph/types/relationship.types.js +0 -35
- package/dist/graph/types/relationship.types.js.map +0 -1
- package/dist/graph/types/result.types.d.ts +0 -237
- package/dist/graph/types/result.types.js +0 -7
- package/dist/graph/types/result.types.js.map +0 -1
- package/dist/graph/validators/index.d.ts +0 -81
- package/dist/graph/validators/index.js +0 -243
- package/dist/graph/validators/index.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/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/services/utils/crypt.utils.d.ts +0 -1
- package/dist/products/services/utils/crypt.utils.js +0 -17
- package/dist/products/services/utils/crypt.utils.js.map +0 -1
- package/dist/products/services/utils/functions.utils.d.ts +0 -13
- package/dist/products/services/utils/functions.utils.js +0 -289
- package/dist/products/services/utils/functions.utils.js.map +0 -1
- package/dist/products/services/utils/objects.utils.d.ts +0 -13
- package/dist/products/services/utils/objects.utils.js +0 -89
- package/dist/products/services/utils/objects.utils.js.map +0 -1
- package/dist/products/services/utils/string.utils.d.ts +0 -12
- package/dist/products/services/utils/string.utils.js +0 -168
- package/dist/products/services/utils/string.utils.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/products/validators/joi-validators/create.productGraphAction.validator.d.ts +0 -14
- package/dist/products/validators/joi-validators/create.productGraphAction.validator.js +0 -696
- package/dist/products/validators/joi-validators/create.productGraphAction.validator.js.map +0 -1
- package/dist/products/validators/joi-validators/update.productGraphAction.validator.d.ts +0 -7
- package/dist/products/validators/joi-validators/update.productGraphAction.validator.js +0 -72
- package/dist/products/validators/joi-validators/update.productGraphAction.validator.js.map +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.js +0 -28
- package/dist/test.imports.js.map +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/tsconfig.tsbuildinfo +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/{test.appBuilder.d.ts → test/test.database.d.ts} +0 -0
- /package/dist/{test.imports.d.ts → test/test.storage.d.ts} +0 -0
- /package/dist/{test.integrationBuilder.d.ts → test/test.triggers.d.ts} +0 -0
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* DynamoDB
|
|
4
|
-
*
|
|
3
|
+
* DynamoDB Adapter
|
|
4
|
+
*
|
|
5
|
+
* Database adapter for AWS DynamoDB using the '@aws-sdk/client-dynamodb' and
|
|
6
|
+
* '@aws-sdk/lib-dynamodb' libraries.
|
|
7
|
+
* Implements all methods from BaseAdapter with DynamoDB-specific operations.
|
|
8
|
+
*
|
|
9
|
+
* Note: DynamoDB is a NoSQL key-value store with different concepts:
|
|
10
|
+
* - Tables have a partition key (and optional sort key)
|
|
11
|
+
* - No traditional transactions (uses TransactWriteItems/TransactGetItems)
|
|
12
|
+
* - No savepoints
|
|
13
|
+
* - Different query patterns than SQL databases
|
|
5
14
|
*/
|
|
6
15
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
16
|
if (k2 === undefined) k2 = k;
|
|
@@ -39,750 +48,793 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
39
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
49
|
exports.DynamoDBAdapter = void 0;
|
|
41
50
|
const base_adapter_1 = require("./base.adapter");
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
const schema_types_1 = require("../types/schema.types");
|
|
45
|
-
const migration_types_1 = require("../types/migration.types");
|
|
51
|
+
const enums_1 = require("../types/enums");
|
|
52
|
+
const database_error_1 = require("../utils/database-error");
|
|
46
53
|
/**
|
|
47
|
-
* DynamoDB
|
|
54
|
+
* DynamoDB database adapter
|
|
55
|
+
* Provides DynamoDB-specific implementations for all database operations
|
|
48
56
|
*/
|
|
49
|
-
class
|
|
50
|
-
constructor(id, client, docClient) {
|
|
51
|
-
this.id = id;
|
|
52
|
-
this.type = database_types_1.DatabaseType.DYNAMODB;
|
|
53
|
-
this.status = database_types_1.ConnectionStatus.CONNECTED;
|
|
54
|
-
this.client = client;
|
|
55
|
-
this.docClient = docClient;
|
|
56
|
-
}
|
|
57
|
-
async connect() {
|
|
58
|
-
this.status = database_types_1.ConnectionStatus.CONNECTED;
|
|
59
|
-
}
|
|
60
|
-
async disconnect() {
|
|
61
|
-
this.client.destroy();
|
|
62
|
-
this.status = database_types_1.ConnectionStatus.DISCONNECTED;
|
|
63
|
-
}
|
|
64
|
-
isConnected() {
|
|
65
|
-
return this.status === database_types_1.ConnectionStatus.CONNECTED;
|
|
66
|
-
}
|
|
67
|
-
getClient() {
|
|
68
|
-
return this.docClient;
|
|
69
|
-
}
|
|
70
|
-
getRawClient() {
|
|
71
|
-
return this.client;
|
|
72
|
-
}
|
|
73
|
-
getType() {
|
|
74
|
-
return this.type;
|
|
75
|
-
}
|
|
76
|
-
getConfig() {
|
|
77
|
-
throw new Error('Config not stored in connection');
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* DynamoDB Transaction implementation
|
|
82
|
-
* Note: DynamoDB transactions work differently from SQL - they collect items
|
|
83
|
-
* and execute them atomically on commit using TransactWriteItems.
|
|
84
|
-
* Maximum 100 items per transaction.
|
|
85
|
-
* Does NOT support savepoints.
|
|
86
|
-
*/
|
|
87
|
-
class DynamoDBTransaction {
|
|
88
|
-
constructor(connection, _options) {
|
|
89
|
-
this.transactItems = [];
|
|
90
|
-
this.id = (0, uuid_1.v4)();
|
|
91
|
-
this.connection = connection;
|
|
92
|
-
this.status = database_types_1.TransactionStatus.ACTIVE;
|
|
93
|
-
this.createdAt = new Date();
|
|
94
|
-
this.native = { items: this.transactItems };
|
|
95
|
-
}
|
|
96
|
-
async commit() {
|
|
97
|
-
if (this.status !== database_types_1.TransactionStatus.ACTIVE) {
|
|
98
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.TRANSACTION_ERROR, `Cannot commit transaction: status is ${this.status}`);
|
|
99
|
-
}
|
|
100
|
-
if (this.transactItems.length === 0) {
|
|
101
|
-
this.status = database_types_1.TransactionStatus.COMMITTED;
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
if (this.transactItems.length > 100) {
|
|
105
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.TRANSACTION_ERROR, `DynamoDB transactions are limited to 100 items. Current: ${this.transactItems.length}`);
|
|
106
|
-
}
|
|
107
|
-
try {
|
|
108
|
-
const { TransactWriteCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
109
|
-
const docClient = this.connection.getClient();
|
|
110
|
-
await docClient.send(new TransactWriteCommand({
|
|
111
|
-
TransactItems: this.transactItems,
|
|
112
|
-
}));
|
|
113
|
-
this.status = database_types_1.TransactionStatus.COMMITTED;
|
|
114
|
-
}
|
|
115
|
-
catch (error) {
|
|
116
|
-
this.status = database_types_1.TransactionStatus.ROLLED_BACK;
|
|
117
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.TRANSACTION_ERROR, `DynamoDB transaction commit failed: ${error.message}`, error);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
async rollback() {
|
|
121
|
-
if (this.status !== database_types_1.TransactionStatus.ACTIVE) {
|
|
122
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.TRANSACTION_ERROR, `Cannot rollback transaction: status is ${this.status}`);
|
|
123
|
-
}
|
|
124
|
-
// DynamoDB transactions are atomic - just clear items and mark as rolled back
|
|
125
|
-
this.transactItems = [];
|
|
126
|
-
this.status = database_types_1.TransactionStatus.ROLLED_BACK;
|
|
127
|
-
}
|
|
128
|
-
async savepoint(_name) {
|
|
129
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.NOT_SUPPORTED, 'DynamoDB does not support savepoints. Transactions are atomic batch operations.');
|
|
130
|
-
}
|
|
131
|
-
isActive() {
|
|
132
|
-
return this.status === database_types_1.TransactionStatus.ACTIVE;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Add an item to the transaction batch
|
|
136
|
-
* Used internally by the adapter for transactional operations
|
|
137
|
-
*/
|
|
138
|
-
addItem(item) {
|
|
139
|
-
if (this.transactItems.length >= 100) {
|
|
140
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.TRANSACTION_ERROR, 'DynamoDB transactions are limited to 100 items');
|
|
141
|
-
}
|
|
142
|
-
this.transactItems.push(item);
|
|
143
|
-
}
|
|
144
|
-
getItems() {
|
|
145
|
-
return this.transactItems;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* DynamoDB Database Adapter
|
|
150
|
-
*/
|
|
151
|
-
class DynamoDBAdapter extends base_adapter_1.BaseDatabaseAdapter {
|
|
57
|
+
class DynamoDBAdapter extends base_adapter_1.BaseAdapter {
|
|
152
58
|
constructor() {
|
|
153
59
|
super(...arguments);
|
|
154
|
-
this.
|
|
60
|
+
this.databaseType = enums_1.DatabaseType.DYNAMODB;
|
|
61
|
+
this.dynamoClient = null;
|
|
62
|
+
this.docClient = null;
|
|
63
|
+
this.region = '';
|
|
155
64
|
}
|
|
156
|
-
// ====================
|
|
157
|
-
async connect(
|
|
158
|
-
var _a, _b, _c, _d;
|
|
65
|
+
// ==================== CONNECTION METHODS ====================
|
|
66
|
+
async connect(options) {
|
|
159
67
|
try {
|
|
160
|
-
// Dynamic import of AWS SDK
|
|
68
|
+
// Dynamic import of AWS SDK
|
|
161
69
|
const { DynamoDBClient } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
162
70
|
const { DynamoDBDocumentClient } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
71
|
+
this.connectionUrl = options.connectionUrl;
|
|
72
|
+
// Parse connection URL: dynamodb://region/access-key/secret-key
|
|
73
|
+
// Or: dynamodb://region (uses default credentials)
|
|
74
|
+
const url = new URL(options.connectionUrl);
|
|
75
|
+
this.region = url.hostname || 'us-east-1';
|
|
163
76
|
const clientConfig = {
|
|
164
|
-
region:
|
|
77
|
+
region: this.region,
|
|
165
78
|
};
|
|
166
|
-
//
|
|
167
|
-
if (
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
79
|
+
// If credentials are provided in the URL
|
|
80
|
+
if (url.pathname && url.pathname !== '/') {
|
|
81
|
+
const parts = url.pathname.slice(1).split('/');
|
|
82
|
+
if (parts.length >= 2) {
|
|
83
|
+
clientConfig.credentials = {
|
|
84
|
+
accessKeyId: parts[0],
|
|
85
|
+
secretAccessKey: parts[1],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
173
88
|
}
|
|
174
|
-
//
|
|
175
|
-
if (
|
|
176
|
-
clientConfig.endpoint =
|
|
89
|
+
// Custom endpoint for local DynamoDB
|
|
90
|
+
if (url.port) {
|
|
91
|
+
clientConfig.endpoint = `http://${url.hostname}:${url.port}`;
|
|
177
92
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
93
|
+
this.dynamoClient = new DynamoDBClient(clientConfig);
|
|
94
|
+
this.docClient = DynamoDBDocumentClient.from(this.dynamoClient, {
|
|
95
|
+
marshallOptions: {
|
|
96
|
+
removeUndefinedValues: true,
|
|
97
|
+
convertEmptyValues: true,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
// Test connection by listing tables
|
|
101
|
+
const { ListTablesCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
102
|
+
await this.dynamoClient.send(new ListTablesCommand({ Limit: 1 }));
|
|
103
|
+
this.client = this.docClient;
|
|
104
|
+
this.connected = true;
|
|
105
|
+
return {
|
|
106
|
+
connected: true,
|
|
107
|
+
version: `DynamoDB (${this.region})`,
|
|
108
|
+
};
|
|
181
109
|
}
|
|
182
110
|
catch (error) {
|
|
183
|
-
throw
|
|
111
|
+
throw database_error_1.DatabaseError.connectionError(`Failed to connect to DynamoDB: ${error.message}`, error);
|
|
184
112
|
}
|
|
185
113
|
}
|
|
186
|
-
async
|
|
187
|
-
await connection.disconnect();
|
|
188
|
-
}
|
|
189
|
-
async testConnection(connection) {
|
|
190
|
-
const startTime = Date.now();
|
|
114
|
+
async testConnection(options) {
|
|
191
115
|
try {
|
|
192
|
-
const { ListTablesCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
193
|
-
const
|
|
116
|
+
const { DynamoDBClient, ListTablesCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
117
|
+
const url = new URL(options.connectionUrl);
|
|
118
|
+
const region = url.hostname || 'us-east-1';
|
|
119
|
+
const clientConfig = { region };
|
|
120
|
+
if (url.pathname && url.pathname !== '/') {
|
|
121
|
+
const parts = url.pathname.slice(1).split('/');
|
|
122
|
+
if (parts.length >= 2) {
|
|
123
|
+
clientConfig.credentials = {
|
|
124
|
+
accessKeyId: parts[0],
|
|
125
|
+
secretAccessKey: parts[1],
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (url.port) {
|
|
130
|
+
clientConfig.endpoint = `http://${url.hostname}:${url.port}`;
|
|
131
|
+
}
|
|
132
|
+
const client = new DynamoDBClient(clientConfig);
|
|
194
133
|
await client.send(new ListTablesCommand({ Limit: 1 }));
|
|
134
|
+
client.destroy();
|
|
195
135
|
return {
|
|
196
136
|
connected: true,
|
|
197
|
-
|
|
198
|
-
databaseType: 'DynamoDB',
|
|
199
|
-
responseTime: Date.now() - startTime,
|
|
137
|
+
version: `DynamoDB (${region})`,
|
|
200
138
|
};
|
|
201
139
|
}
|
|
202
140
|
catch (error) {
|
|
203
141
|
return {
|
|
204
142
|
connected: false,
|
|
205
|
-
message: `DynamoDB connection failed: ${error.message}`,
|
|
206
|
-
databaseType: 'DynamoDB',
|
|
207
|
-
responseTime: Date.now() - startTime,
|
|
208
143
|
error: error.message,
|
|
209
144
|
};
|
|
210
145
|
}
|
|
211
146
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
async rollbackTransaction(_connection, transaction) {
|
|
221
|
-
await transaction.rollback();
|
|
222
|
-
}
|
|
223
|
-
async createSavepoint(_connection, _transaction, _savepointName) {
|
|
224
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.NOT_SUPPORTED, 'DynamoDB does not support savepoints. Transactions are atomic batch operations.');
|
|
225
|
-
}
|
|
226
|
-
async rollbackToSavepoint(_connection, _transaction, _savepoint) {
|
|
227
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.NOT_SUPPORTED, 'DynamoDB does not support savepoints.');
|
|
228
|
-
}
|
|
229
|
-
async releaseSavepoint(_connection, _transaction, _savepoint) {
|
|
230
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.NOT_SUPPORTED, 'DynamoDB does not support savepoints.');
|
|
147
|
+
async disconnect() {
|
|
148
|
+
if (this.dynamoClient) {
|
|
149
|
+
this.dynamoClient.destroy();
|
|
150
|
+
this.dynamoClient = null;
|
|
151
|
+
this.docClient = null;
|
|
152
|
+
this.client = null;
|
|
153
|
+
this.connected = false;
|
|
154
|
+
}
|
|
231
155
|
}
|
|
232
|
-
// ====================
|
|
233
|
-
async query(
|
|
234
|
-
|
|
156
|
+
// ==================== QUERY METHODS ====================
|
|
157
|
+
async query(query) {
|
|
158
|
+
var _a;
|
|
159
|
+
this.ensureConnected();
|
|
235
160
|
try {
|
|
236
161
|
const { ScanCommand, QueryCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
//
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
162
|
+
const tableName = query.options.table;
|
|
163
|
+
const filter = query.options.where || {};
|
|
164
|
+
// Determine if we can use Query (needs key conditions) or must use Scan
|
|
165
|
+
const { keyCondition, filterCondition } = await this.extractKeyCondition(filter, tableName);
|
|
166
|
+
let items = [];
|
|
167
|
+
let count = 0;
|
|
168
|
+
if (keyCondition) {
|
|
169
|
+
// Use Query command for key-based lookups (much faster than Scan)
|
|
170
|
+
const params = {
|
|
171
|
+
TableName: tableName,
|
|
172
|
+
KeyConditionExpression: keyCondition.expression,
|
|
173
|
+
ExpressionAttributeNames: Object.assign({}, keyCondition.names),
|
|
174
|
+
ExpressionAttributeValues: Object.assign({}, keyCondition.values),
|
|
175
|
+
};
|
|
176
|
+
// Add filter for non-key conditions
|
|
177
|
+
if (filterCondition && filterCondition.expression) {
|
|
178
|
+
params.FilterExpression = filterCondition.expression;
|
|
179
|
+
Object.assign(params.ExpressionAttributeNames, filterCondition.names);
|
|
180
|
+
Object.assign(params.ExpressionAttributeValues, filterCondition.values);
|
|
181
|
+
}
|
|
182
|
+
// Projection
|
|
183
|
+
if (query.options.select) {
|
|
184
|
+
params.ProjectionExpression = query.options.select
|
|
185
|
+
.map((col, i) => {
|
|
186
|
+
params.ExpressionAttributeNames[`#proj${i}`] = col;
|
|
187
|
+
return `#proj${i}`;
|
|
188
|
+
})
|
|
189
|
+
.join(', ');
|
|
190
|
+
}
|
|
191
|
+
// Limit
|
|
192
|
+
if (query.options.limit) {
|
|
193
|
+
params.Limit = query.options.limit;
|
|
194
|
+
}
|
|
195
|
+
// Sort order (only works if there's a sort key)
|
|
196
|
+
if (query.options.orderBy) {
|
|
197
|
+
const orderByArray = Array.isArray(query.options.orderBy)
|
|
198
|
+
? query.options.orderBy
|
|
199
|
+
: [query.options.orderBy];
|
|
200
|
+
// DynamoDB only supports ASC/DESC on sort key
|
|
201
|
+
if (((_a = orderByArray[0]) === null || _a === void 0 ? void 0 : _a.order) === 'DESC') {
|
|
202
|
+
params.ScanIndexForward = false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const response = await this.docClient.send(new QueryCommand(params));
|
|
206
|
+
items = response.Items || [];
|
|
207
|
+
count = response.Count || 0;
|
|
244
208
|
}
|
|
245
209
|
else {
|
|
246
|
-
|
|
247
|
-
|
|
210
|
+
// Use Scan command (less efficient but necessary for non-key queries)
|
|
211
|
+
const params = {
|
|
212
|
+
TableName: tableName,
|
|
213
|
+
};
|
|
214
|
+
// Build filter expression
|
|
215
|
+
const filterExpression = this.buildFilterExpression(filter, {}, {});
|
|
216
|
+
if (filterExpression.expression) {
|
|
217
|
+
params.FilterExpression = filterExpression.expression;
|
|
218
|
+
params.ExpressionAttributeNames = filterExpression.names;
|
|
219
|
+
params.ExpressionAttributeValues = filterExpression.values;
|
|
220
|
+
}
|
|
221
|
+
// Projection
|
|
222
|
+
if (query.options.select) {
|
|
223
|
+
params.ExpressionAttributeNames = params.ExpressionAttributeNames || {};
|
|
224
|
+
params.ProjectionExpression = query.options.select
|
|
225
|
+
.map((col, i) => {
|
|
226
|
+
params.ExpressionAttributeNames[`#proj${i}`] = col;
|
|
227
|
+
return `#proj${i}`;
|
|
228
|
+
})
|
|
229
|
+
.join(', ');
|
|
230
|
+
}
|
|
231
|
+
// Limit
|
|
232
|
+
if (query.options.limit) {
|
|
233
|
+
params.Limit = query.options.limit;
|
|
234
|
+
}
|
|
235
|
+
const response = await this.docClient.send(new ScanCommand(params));
|
|
236
|
+
items = response.Items || [];
|
|
237
|
+
// Use Count (items after filtering) not ScannedCount (items before filtering)
|
|
238
|
+
count = response.Count || items.length;
|
|
239
|
+
}
|
|
240
|
+
// Apply offset (DynamoDB doesn't have native offset)
|
|
241
|
+
if (query.options.offset && query.options.offset > 0) {
|
|
242
|
+
items = items.slice(query.options.offset);
|
|
248
243
|
}
|
|
249
|
-
const executionTime = Date.now() - startTime;
|
|
250
244
|
return {
|
|
251
|
-
data:
|
|
252
|
-
count
|
|
253
|
-
executionTime,
|
|
245
|
+
data: items,
|
|
246
|
+
count,
|
|
254
247
|
};
|
|
255
248
|
}
|
|
256
249
|
catch (error) {
|
|
257
|
-
throw
|
|
250
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
258
251
|
}
|
|
259
252
|
}
|
|
260
|
-
async
|
|
261
|
-
|
|
253
|
+
async raw(options) {
|
|
254
|
+
this.ensureConnected();
|
|
255
|
+
try {
|
|
256
|
+
const { ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
257
|
+
// For DynamoDB, raw query is a PartiQL statement or direct command
|
|
258
|
+
// Here we support simple scan with filter
|
|
259
|
+
const params = Object.assign({ TableName: options.table || options.collection }, options.query);
|
|
260
|
+
const response = await this.docClient.send(new ScanCommand(params));
|
|
261
|
+
return {
|
|
262
|
+
data: (response.Items || []),
|
|
263
|
+
count: response.Count || 0,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// ==================== WRITE METHODS ====================
|
|
271
|
+
async insert(options) {
|
|
272
|
+
var _a, _b;
|
|
273
|
+
this.ensureConnected();
|
|
262
274
|
try {
|
|
263
275
|
const { PutCommand, BatchWriteCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
276
|
+
const data = Array.isArray(options.data) ? options.data : [options.data];
|
|
277
|
+
if (data.length === 0) {
|
|
278
|
+
return { data: [], count: 0, insertedIds: [] };
|
|
279
|
+
}
|
|
280
|
+
const insertedIds = [];
|
|
281
|
+
if (data.length === 1) {
|
|
282
|
+
// Single item put
|
|
283
|
+
await this.docClient.send(new PutCommand({
|
|
269
284
|
TableName: options.table,
|
|
270
|
-
Item:
|
|
285
|
+
Item: data[0],
|
|
286
|
+
ConditionExpression: ((_a = options.onConflict) === null || _a === void 0 ? void 0 : _a.action) === 'ignore'
|
|
287
|
+
? 'attribute_not_exists(#pk)'
|
|
288
|
+
: undefined,
|
|
289
|
+
ExpressionAttributeNames: ((_b = options.onConflict) === null || _b === void 0 ? void 0 : _b.action) === 'ignore'
|
|
290
|
+
? { '#pk': options.onConflict.columns[0] }
|
|
291
|
+
: undefined,
|
|
271
292
|
}));
|
|
293
|
+
insertedIds.push(data[0].id || data[0]._id);
|
|
272
294
|
}
|
|
273
295
|
else {
|
|
274
|
-
// Batch
|
|
275
|
-
const batches = this.chunkArray(
|
|
296
|
+
// Batch write (max 25 items per batch)
|
|
297
|
+
const batches = this.chunkArray(data, 25);
|
|
276
298
|
for (const batch of batches) {
|
|
277
|
-
await docClient.send(new BatchWriteCommand({
|
|
299
|
+
await this.docClient.send(new BatchWriteCommand({
|
|
278
300
|
RequestItems: {
|
|
279
|
-
[options.table]: batch.map(
|
|
301
|
+
[options.table]: batch.map(item => ({
|
|
280
302
|
PutRequest: { Item: item },
|
|
281
303
|
})),
|
|
282
304
|
},
|
|
283
305
|
}));
|
|
306
|
+
batch.forEach(item => insertedIds.push(item.id || item._id));
|
|
284
307
|
}
|
|
285
308
|
}
|
|
286
|
-
const executionTime = Date.now() - startTime;
|
|
287
309
|
return {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
executionTime,
|
|
292
|
-
success: true,
|
|
310
|
+
data: options.returning ? data : [],
|
|
311
|
+
count: data.length,
|
|
312
|
+
insertedIds,
|
|
293
313
|
};
|
|
294
314
|
}
|
|
295
315
|
catch (error) {
|
|
296
|
-
throw
|
|
316
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
297
317
|
}
|
|
298
318
|
}
|
|
299
|
-
async update(
|
|
300
|
-
|
|
319
|
+
async update(options) {
|
|
320
|
+
this.ensureConnected();
|
|
301
321
|
try {
|
|
302
|
-
const { UpdateCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
const { updateExpression, expressionAttributeNames, expressionAttributeValues } = this.buildUpdateExpression(options.data);
|
|
308
|
-
await docClient.send(new UpdateCommand({
|
|
322
|
+
const { UpdateCommand, ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
323
|
+
// First, find items to update
|
|
324
|
+
const filter = options.where || {};
|
|
325
|
+
const filterExpression = this.buildFilterExpression(filter, {}, {});
|
|
326
|
+
const scanParams = {
|
|
309
327
|
TableName: options.table,
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
328
|
+
};
|
|
329
|
+
if (filterExpression.expression) {
|
|
330
|
+
scanParams.FilterExpression = filterExpression.expression;
|
|
331
|
+
scanParams.ExpressionAttributeNames = filterExpression.names;
|
|
332
|
+
scanParams.ExpressionAttributeValues = filterExpression.values;
|
|
333
|
+
}
|
|
334
|
+
const scanResponse = await this.docClient.send(new ScanCommand(scanParams));
|
|
335
|
+
const itemsToUpdate = scanResponse.Items || [];
|
|
336
|
+
// Build update expression
|
|
337
|
+
const { expression, names, values } = this.buildUpdateExpression(options.data);
|
|
338
|
+
let updatedCount = 0;
|
|
339
|
+
const updatedItems = [];
|
|
340
|
+
for (const item of itemsToUpdate) {
|
|
341
|
+
// Get primary key from item
|
|
342
|
+
const key = await this.getTableKey(options.table, item);
|
|
343
|
+
const updateParams = {
|
|
344
|
+
TableName: options.table,
|
|
345
|
+
Key: key,
|
|
346
|
+
UpdateExpression: expression,
|
|
347
|
+
ExpressionAttributeNames: names,
|
|
348
|
+
ExpressionAttributeValues: values,
|
|
349
|
+
ReturnValues: options.returning ? 'ALL_NEW' : 'NONE',
|
|
350
|
+
};
|
|
351
|
+
const response = await this.docClient.send(new UpdateCommand(updateParams));
|
|
352
|
+
updatedCount++;
|
|
353
|
+
if (options.returning && response.Attributes) {
|
|
354
|
+
updatedItems.push(response.Attributes);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
316
357
|
return {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
data: undefined,
|
|
320
|
-
executionTime,
|
|
321
|
-
success: true,
|
|
358
|
+
data: updatedItems,
|
|
359
|
+
count: updatedCount,
|
|
322
360
|
};
|
|
323
361
|
}
|
|
324
362
|
catch (error) {
|
|
325
|
-
throw
|
|
363
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
326
364
|
}
|
|
327
365
|
}
|
|
328
|
-
async delete(
|
|
329
|
-
|
|
366
|
+
async delete(options) {
|
|
367
|
+
this.ensureConnected();
|
|
330
368
|
try {
|
|
331
|
-
const { DeleteCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
|
|
369
|
+
const { DeleteCommand, ScanCommand, BatchWriteCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
370
|
+
// First, find items to delete
|
|
371
|
+
const filter = options.where || {};
|
|
372
|
+
const filterExpression = this.buildFilterExpression(filter, {}, {});
|
|
373
|
+
const scanParams = {
|
|
336
374
|
TableName: options.table,
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
375
|
+
};
|
|
376
|
+
if (filterExpression.expression) {
|
|
377
|
+
scanParams.FilterExpression = filterExpression.expression;
|
|
378
|
+
scanParams.ExpressionAttributeNames = filterExpression.names;
|
|
379
|
+
scanParams.ExpressionAttributeValues = filterExpression.values;
|
|
380
|
+
}
|
|
381
|
+
const scanResponse = await this.docClient.send(new ScanCommand(scanParams));
|
|
382
|
+
const itemsToDelete = scanResponse.Items || [];
|
|
383
|
+
if (itemsToDelete.length === 0) {
|
|
384
|
+
return { count: 0 };
|
|
385
|
+
}
|
|
386
|
+
// Delete items in batches of 25
|
|
387
|
+
const batches = this.chunkArray(itemsToDelete, 25);
|
|
388
|
+
for (const batch of batches) {
|
|
389
|
+
const deleteRequests = await Promise.all(batch.map(async (item) => {
|
|
390
|
+
const key = await this.getTableKey(options.table, item);
|
|
391
|
+
return { DeleteRequest: { Key: key } };
|
|
392
|
+
}));
|
|
393
|
+
await this.docClient.send(new BatchWriteCommand({
|
|
394
|
+
RequestItems: {
|
|
395
|
+
[options.table]: deleteRequests,
|
|
396
|
+
},
|
|
397
|
+
}));
|
|
398
|
+
}
|
|
340
399
|
return {
|
|
341
|
-
|
|
342
|
-
data: undefined,
|
|
343
|
-
executionTime,
|
|
344
|
-
success: true,
|
|
400
|
+
count: itemsToDelete.length,
|
|
401
|
+
data: options.returning ? itemsToDelete : undefined,
|
|
345
402
|
};
|
|
346
403
|
}
|
|
347
404
|
catch (error) {
|
|
348
|
-
throw
|
|
405
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
349
406
|
}
|
|
350
407
|
}
|
|
351
|
-
async upsert(
|
|
352
|
-
|
|
408
|
+
async upsert(options) {
|
|
409
|
+
this.ensureConnected();
|
|
353
410
|
try {
|
|
354
411
|
const { PutCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
// PutItem automatically does upsert in DynamoDB
|
|
358
|
-
await docClient.send(new PutCommand({
|
|
412
|
+
// DynamoDB PutCommand is an upsert by default
|
|
413
|
+
await this.docClient.send(new PutCommand({
|
|
359
414
|
TableName: options.table,
|
|
360
|
-
Item: data,
|
|
415
|
+
Item: options.data,
|
|
416
|
+
ReturnValues: 'NONE',
|
|
361
417
|
}));
|
|
362
|
-
const executionTime = Date.now() - startTime;
|
|
363
418
|
return {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
data: undefined,
|
|
368
|
-
executionTime,
|
|
369
|
-
success: true,
|
|
419
|
+
data: [options.data],
|
|
420
|
+
count: 1,
|
|
421
|
+
operation: 'inserted', // DynamoDB doesn't distinguish
|
|
370
422
|
};
|
|
371
423
|
}
|
|
372
424
|
catch (error) {
|
|
373
|
-
throw
|
|
425
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
374
426
|
}
|
|
375
427
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
428
|
+
// ==================== AGGREGATION METHODS ====================
|
|
429
|
+
async count(options) {
|
|
430
|
+
this.ensureConnected();
|
|
379
431
|
try {
|
|
380
|
-
const {
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
Statement: options.query,
|
|
385
|
-
Parameters: options.params,
|
|
386
|
-
}));
|
|
387
|
-
const executionTime = Date.now() - startTime;
|
|
388
|
-
return {
|
|
389
|
-
rows: (result.Items || []),
|
|
390
|
-
rowCount: ((_a = result.Items) === null || _a === void 0 ? void 0 : _a.length) || 0,
|
|
391
|
-
executionTime,
|
|
432
|
+
const { ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
433
|
+
const params = {
|
|
434
|
+
TableName: options.table,
|
|
435
|
+
Select: 'COUNT',
|
|
392
436
|
};
|
|
437
|
+
if (options.where) {
|
|
438
|
+
const filterExpression = this.buildFilterExpression(options.where, {}, {});
|
|
439
|
+
if (filterExpression.expression) {
|
|
440
|
+
params.FilterExpression = filterExpression.expression;
|
|
441
|
+
params.ExpressionAttributeNames = filterExpression.names;
|
|
442
|
+
params.ExpressionAttributeValues = filterExpression.values;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const response = await this.docClient.send(new ScanCommand(params));
|
|
446
|
+
return response.Count || 0;
|
|
393
447
|
}
|
|
394
448
|
catch (error) {
|
|
395
|
-
throw
|
|
449
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
396
450
|
}
|
|
397
451
|
}
|
|
398
|
-
|
|
399
|
-
|
|
452
|
+
async sum(options) {
|
|
453
|
+
this.ensureConnected();
|
|
400
454
|
try {
|
|
455
|
+
// DynamoDB doesn't have native aggregations, need to scan and sum
|
|
401
456
|
const { ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
402
|
-
const docClient = connection.getClient();
|
|
403
457
|
const params = {
|
|
404
458
|
TableName: options.table,
|
|
405
|
-
|
|
459
|
+
ProjectionExpression: `#col`,
|
|
460
|
+
ExpressionAttributeNames: { '#col': options.column },
|
|
406
461
|
};
|
|
407
462
|
if (options.where) {
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
463
|
+
const filterExpression = this.buildFilterExpression(options.where, params.ExpressionAttributeNames, {});
|
|
464
|
+
if (filterExpression.expression) {
|
|
465
|
+
params.FilterExpression = filterExpression.expression;
|
|
466
|
+
Object.assign(params.ExpressionAttributeNames, filterExpression.names);
|
|
467
|
+
params.ExpressionAttributeValues = filterExpression.values;
|
|
468
|
+
}
|
|
412
469
|
}
|
|
413
|
-
const
|
|
414
|
-
|
|
470
|
+
const response = await this.docClient.send(new ScanCommand(params));
|
|
471
|
+
const items = response.Items || [];
|
|
472
|
+
return items.reduce((sum, item) => sum + (Number(item[options.column]) || 0), 0);
|
|
415
473
|
}
|
|
416
474
|
catch (error) {
|
|
417
|
-
throw
|
|
475
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
418
476
|
}
|
|
419
477
|
}
|
|
420
|
-
async
|
|
421
|
-
|
|
478
|
+
async avg(options) {
|
|
479
|
+
this.ensureConnected();
|
|
422
480
|
try {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
}
|
|
430
|
-
|
|
481
|
+
// DynamoDB doesn't have native aggregations, need to scan and calculate
|
|
482
|
+
const { ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
483
|
+
const params = {
|
|
484
|
+
TableName: options.table,
|
|
485
|
+
ProjectionExpression: `#col`,
|
|
486
|
+
ExpressionAttributeNames: { '#col': options.column },
|
|
487
|
+
};
|
|
488
|
+
if (options.where) {
|
|
489
|
+
const filterExpression = this.buildFilterExpression(options.where, params.ExpressionAttributeNames, {});
|
|
490
|
+
if (filterExpression.expression) {
|
|
491
|
+
params.FilterExpression = filterExpression.expression;
|
|
492
|
+
Object.assign(params.ExpressionAttributeNames, filterExpression.names);
|
|
493
|
+
params.ExpressionAttributeValues = filterExpression.values;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
const response = await this.docClient.send(new ScanCommand(params));
|
|
497
|
+
const items = response.Items || [];
|
|
498
|
+
if (items.length === 0)
|
|
499
|
+
return 0;
|
|
500
|
+
const sum = items.reduce((acc, item) => acc + (Number(item[options.column]) || 0), 0);
|
|
501
|
+
return sum / items.length;
|
|
431
502
|
}
|
|
432
503
|
catch (error) {
|
|
433
|
-
throw
|
|
504
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
434
505
|
}
|
|
435
506
|
}
|
|
436
|
-
async
|
|
507
|
+
async min(options) {
|
|
508
|
+
this.ensureConnected();
|
|
437
509
|
try {
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
510
|
+
const { ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
511
|
+
const params = {
|
|
512
|
+
TableName: options.table,
|
|
513
|
+
ProjectionExpression: `#col`,
|
|
514
|
+
ExpressionAttributeNames: { '#col': options.column },
|
|
515
|
+
};
|
|
516
|
+
if (options.where) {
|
|
517
|
+
const filterExpression = this.buildFilterExpression(options.where, params.ExpressionAttributeNames, {});
|
|
518
|
+
if (filterExpression.expression) {
|
|
519
|
+
params.FilterExpression = filterExpression.expression;
|
|
520
|
+
Object.assign(params.ExpressionAttributeNames, filterExpression.names);
|
|
521
|
+
params.ExpressionAttributeValues = filterExpression.values;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
const response = await this.docClient.send(new ScanCommand(params));
|
|
525
|
+
const items = response.Items || [];
|
|
526
|
+
if (items.length === 0)
|
|
527
|
+
return null;
|
|
528
|
+
return items.reduce((min, item) => {
|
|
529
|
+
const val = item[options.column];
|
|
530
|
+
return min === null || val < min ? val : min;
|
|
531
|
+
}, null);
|
|
447
532
|
}
|
|
448
533
|
catch (error) {
|
|
449
|
-
throw
|
|
534
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
450
535
|
}
|
|
451
536
|
}
|
|
452
|
-
async
|
|
537
|
+
async max(options) {
|
|
538
|
+
this.ensureConnected();
|
|
453
539
|
try {
|
|
454
|
-
const
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
540
|
+
const { ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
541
|
+
const params = {
|
|
542
|
+
TableName: options.table,
|
|
543
|
+
ProjectionExpression: `#col`,
|
|
544
|
+
ExpressionAttributeNames: { '#col': options.column },
|
|
545
|
+
};
|
|
546
|
+
if (options.where) {
|
|
547
|
+
const filterExpression = this.buildFilterExpression(options.where, params.ExpressionAttributeNames, {});
|
|
548
|
+
if (filterExpression.expression) {
|
|
549
|
+
params.FilterExpression = filterExpression.expression;
|
|
550
|
+
Object.assign(params.ExpressionAttributeNames, filterExpression.names);
|
|
551
|
+
params.ExpressionAttributeValues = filterExpression.values;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
const response = await this.docClient.send(new ScanCommand(params));
|
|
555
|
+
const items = response.Items || [];
|
|
556
|
+
if (items.length === 0)
|
|
557
|
+
return null;
|
|
558
|
+
return items.reduce((max, item) => {
|
|
559
|
+
const val = item[options.column];
|
|
560
|
+
return max === null || val > max ? val : max;
|
|
561
|
+
}, null);
|
|
467
562
|
}
|
|
468
563
|
catch (error) {
|
|
469
|
-
throw
|
|
564
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
470
565
|
}
|
|
471
566
|
}
|
|
472
|
-
async
|
|
567
|
+
async aggregate(builtAggregation) {
|
|
568
|
+
this.ensureConnected();
|
|
473
569
|
try {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
570
|
+
// DynamoDB doesn't support native aggregations - scan and compute in memory
|
|
571
|
+
const { ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
572
|
+
const options = builtAggregation.options;
|
|
573
|
+
const params = {
|
|
574
|
+
TableName: options.table,
|
|
575
|
+
};
|
|
576
|
+
if (options.where) {
|
|
577
|
+
const filterExpression = this.buildFilterExpression(options.where, {}, {});
|
|
578
|
+
if (filterExpression.expression) {
|
|
579
|
+
params.FilterExpression = filterExpression.expression;
|
|
580
|
+
params.ExpressionAttributeNames = filterExpression.names;
|
|
581
|
+
params.ExpressionAttributeValues = filterExpression.values;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
const response = await this.docClient.send(new ScanCommand(params));
|
|
585
|
+
const items = response.Items || [];
|
|
586
|
+
// Compute aggregations in memory
|
|
587
|
+
const result = {};
|
|
588
|
+
const operations = options.operations || {};
|
|
589
|
+
for (const [alias, op] of Object.entries(operations)) {
|
|
590
|
+
const operation = op;
|
|
591
|
+
if (operation.$COUNT) {
|
|
592
|
+
result[alias] = items.length;
|
|
593
|
+
}
|
|
594
|
+
else if (operation.$SUM) {
|
|
595
|
+
result[alias] = items.reduce((sum, item) => sum + (Number(item[operation.$SUM]) || 0), 0);
|
|
596
|
+
}
|
|
597
|
+
else if (operation.$AVG) {
|
|
598
|
+
const values = items.map((item) => Number(item[operation.$AVG]) || 0);
|
|
599
|
+
result[alias] = values.length > 0 ? values.reduce((a, b) => a + b, 0) / values.length : 0;
|
|
600
|
+
}
|
|
601
|
+
else if (operation.$MIN) {
|
|
602
|
+
const values = items.map((item) => item[operation.$MIN]).filter((v) => v != null);
|
|
603
|
+
result[alias] = values.length > 0 ? Math.min(...values) : null;
|
|
604
|
+
}
|
|
605
|
+
else if (operation.$MAX) {
|
|
606
|
+
const values = items.map((item) => item[operation.$MAX]).filter((v) => v != null);
|
|
607
|
+
result[alias] = values.length > 0 ? Math.max(...values) : null;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
return result;
|
|
487
611
|
}
|
|
488
612
|
catch (error) {
|
|
489
|
-
throw
|
|
613
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
490
614
|
}
|
|
491
615
|
}
|
|
492
|
-
async groupBy(
|
|
616
|
+
async groupBy(builtGroupBy) {
|
|
617
|
+
this.ensureConnected();
|
|
493
618
|
try {
|
|
494
|
-
// DynamoDB doesn't support GROUP BY -
|
|
495
|
-
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
619
|
+
// DynamoDB doesn't support native GROUP BY - scan and group in memory
|
|
620
|
+
const { ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
621
|
+
const options = builtGroupBy.options;
|
|
622
|
+
const params = {
|
|
623
|
+
TableName: options.table,
|
|
624
|
+
};
|
|
625
|
+
if (options.where) {
|
|
626
|
+
const filterExpression = this.buildFilterExpression(options.where, {}, {});
|
|
627
|
+
if (filterExpression.expression) {
|
|
628
|
+
params.FilterExpression = filterExpression.expression;
|
|
629
|
+
params.ExpressionAttributeNames = filterExpression.names;
|
|
630
|
+
params.ExpressionAttributeValues = filterExpression.values;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
const response = await this.docClient.send(new ScanCommand(params));
|
|
634
|
+
const items = response.Items || [];
|
|
635
|
+
// Group items in memory
|
|
503
636
|
const groups = new Map();
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
const groupKey =
|
|
637
|
+
const groupByColumns = options.groupBy || [];
|
|
638
|
+
for (const item of items) {
|
|
639
|
+
const groupKey = groupByColumns.map((col) => String(item[col])).join('|');
|
|
507
640
|
if (!groups.has(groupKey)) {
|
|
508
|
-
|
|
509
|
-
options.groupBy.forEach((col) => {
|
|
510
|
-
groupData[col] = item[col];
|
|
511
|
-
});
|
|
512
|
-
groups.set(groupKey, groupData);
|
|
641
|
+
groups.set(groupKey, []);
|
|
513
642
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
column = aggObj.$COUNT;
|
|
525
|
-
}
|
|
526
|
-
else if (aggObj.$SUM !== undefined) {
|
|
527
|
-
operation = 'sum';
|
|
528
|
-
column = aggObj.$SUM;
|
|
529
|
-
}
|
|
530
|
-
else if (aggObj.$AVG !== undefined) {
|
|
531
|
-
operation = 'avg';
|
|
532
|
-
column = aggObj.$AVG;
|
|
533
|
-
}
|
|
534
|
-
else if (aggObj.$MIN !== undefined) {
|
|
535
|
-
operation = 'min';
|
|
536
|
-
column = aggObj.$MIN;
|
|
537
|
-
}
|
|
538
|
-
else if (aggObj.$MAX !== undefined) {
|
|
539
|
-
operation = 'max';
|
|
540
|
-
column = aggObj.$MAX;
|
|
541
|
-
}
|
|
542
|
-
else {
|
|
543
|
-
return; // Skip unknown format
|
|
544
|
-
}
|
|
545
|
-
const value = column === '*' ? 1 : item[column];
|
|
546
|
-
if (groupData[alias] === undefined) {
|
|
547
|
-
groupData[alias] = 0;
|
|
548
|
-
if (operation === 'min')
|
|
549
|
-
groupData[alias] = Infinity;
|
|
550
|
-
if (operation === 'max')
|
|
551
|
-
groupData[alias] = -Infinity;
|
|
552
|
-
}
|
|
553
|
-
switch (operation) {
|
|
554
|
-
case 'count':
|
|
555
|
-
groupData[alias]++;
|
|
556
|
-
break;
|
|
557
|
-
case 'sum':
|
|
558
|
-
groupData[alias] += value || 0;
|
|
559
|
-
break;
|
|
560
|
-
case 'avg':
|
|
561
|
-
if (!groupData[`${alias}_sum`])
|
|
562
|
-
groupData[`${alias}_sum`] = 0;
|
|
563
|
-
if (!groupData[`${alias}_count`])
|
|
564
|
-
groupData[`${alias}_count`] = 0;
|
|
565
|
-
groupData[`${alias}_sum`] += value || 0;
|
|
566
|
-
groupData[`${alias}_count`]++;
|
|
567
|
-
groupData[alias] = groupData[`${alias}_sum`] / groupData[`${alias}_count`];
|
|
568
|
-
break;
|
|
569
|
-
case 'min':
|
|
570
|
-
if (value !== undefined && value < groupData[alias]) {
|
|
571
|
-
groupData[alias] = value;
|
|
572
|
-
}
|
|
573
|
-
break;
|
|
574
|
-
case 'max':
|
|
575
|
-
if (value !== undefined && value > groupData[alias]) {
|
|
576
|
-
groupData[alias] = value;
|
|
577
|
-
}
|
|
578
|
-
break;
|
|
579
|
-
}
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
});
|
|
583
|
-
// Clean up helper fields used for avg calculation
|
|
584
|
-
const results = Array.from(groups.values());
|
|
585
|
-
results.forEach((group) => {
|
|
586
|
-
Object.keys(group).forEach((key) => {
|
|
587
|
-
if (key.endsWith('_sum') || key.endsWith('_count')) {
|
|
588
|
-
delete group[key];
|
|
589
|
-
}
|
|
643
|
+
groups.get(groupKey).push(item);
|
|
644
|
+
}
|
|
645
|
+
// Compute aggregations for each group
|
|
646
|
+
const results = [];
|
|
647
|
+
const operations = options.operations || {};
|
|
648
|
+
for (const [groupKey, groupItems] of groups) {
|
|
649
|
+
const group = {};
|
|
650
|
+
const keyParts = groupKey.split('|');
|
|
651
|
+
groupByColumns.forEach((col, i) => {
|
|
652
|
+
group[col] = keyParts[i];
|
|
590
653
|
});
|
|
591
|
-
|
|
654
|
+
const aggregates = {};
|
|
655
|
+
for (const [alias, op] of Object.entries(operations)) {
|
|
656
|
+
const operation = op;
|
|
657
|
+
if (operation.$COUNT) {
|
|
658
|
+
aggregates[alias] = groupItems.length;
|
|
659
|
+
}
|
|
660
|
+
else if (operation.$SUM) {
|
|
661
|
+
aggregates[alias] = groupItems.reduce((sum, item) => sum + (Number(item[operation.$SUM]) || 0), 0);
|
|
662
|
+
}
|
|
663
|
+
else if (operation.$AVG) {
|
|
664
|
+
const values = groupItems.map(item => Number(item[operation.$AVG]) || 0);
|
|
665
|
+
aggregates[alias] = values.length > 0 ? values.reduce((a, b) => a + b, 0) / values.length : 0;
|
|
666
|
+
}
|
|
667
|
+
else if (operation.$MIN) {
|
|
668
|
+
const values = groupItems.map(item => item[operation.$MIN]).filter(v => v != null);
|
|
669
|
+
aggregates[alias] = values.length > 0 ? Math.min(...values) : null;
|
|
670
|
+
}
|
|
671
|
+
else if (operation.$MAX) {
|
|
672
|
+
const values = groupItems.map(item => item[operation.$MAX]).filter(v => v != null);
|
|
673
|
+
aggregates[alias] = values.length > 0 ? Math.max(...values) : null;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
results.push({ group, aggregates: aggregates });
|
|
677
|
+
}
|
|
592
678
|
return results;
|
|
593
679
|
}
|
|
594
680
|
catch (error) {
|
|
595
|
-
throw
|
|
681
|
+
throw database_error_1.DatabaseError.fromDatabaseError(error, 'dynamodb');
|
|
596
682
|
}
|
|
597
683
|
}
|
|
598
|
-
|
|
684
|
+
// ==================== TRANSACTION METHODS ====================
|
|
685
|
+
async beginTransaction(isolationLevel, readOnly, timeout) {
|
|
686
|
+
this.ensureConnected();
|
|
687
|
+
// DynamoDB uses TransactWriteItems for transactions, not traditional BEGIN/COMMIT
|
|
688
|
+
// We create a transaction context that collects operations
|
|
689
|
+
const id = `dynamo_txn_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
690
|
+
return {
|
|
691
|
+
id,
|
|
692
|
+
databaseType: 'dynamodb',
|
|
693
|
+
isolationLevel: enums_1.IsolationLevel.SERIALIZABLE, // DynamoDB transactions are serializable
|
|
694
|
+
readOnly: readOnly || false,
|
|
695
|
+
timeout,
|
|
696
|
+
startedAt: new Date(),
|
|
697
|
+
client: {
|
|
698
|
+
operations: [],
|
|
699
|
+
conditionChecks: [],
|
|
700
|
+
},
|
|
701
|
+
savepoints: new Map(),
|
|
702
|
+
status: 'active',
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
async commitTransaction(context) {
|
|
706
|
+
this.ensureConnected();
|
|
599
707
|
try {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
});
|
|
609
|
-
|
|
610
|
-
Object.entries(options.operations).forEach(([alias, agg]) => {
|
|
611
|
-
const aggObj = agg;
|
|
612
|
-
// Parse operation and column
|
|
613
|
-
let operation;
|
|
614
|
-
let column;
|
|
615
|
-
if (aggObj.$COUNT !== undefined) {
|
|
616
|
-
operation = 'count';
|
|
617
|
-
column = aggObj.$COUNT;
|
|
618
|
-
}
|
|
619
|
-
else if (aggObj.$SUM !== undefined) {
|
|
620
|
-
operation = 'sum';
|
|
621
|
-
column = aggObj.$SUM;
|
|
622
|
-
}
|
|
623
|
-
else if (aggObj.$AVG !== undefined) {
|
|
624
|
-
operation = 'avg';
|
|
625
|
-
column = aggObj.$AVG;
|
|
626
|
-
}
|
|
627
|
-
else if (aggObj.$MIN !== undefined) {
|
|
628
|
-
operation = 'min';
|
|
629
|
-
column = aggObj.$MIN;
|
|
630
|
-
}
|
|
631
|
-
else if (aggObj.$MAX !== undefined) {
|
|
632
|
-
operation = 'max';
|
|
633
|
-
column = aggObj.$MAX;
|
|
634
|
-
}
|
|
635
|
-
else {
|
|
636
|
-
return; // Skip unknown format
|
|
637
|
-
}
|
|
638
|
-
const values = column === '*'
|
|
639
|
-
? result.data.map(() => 1)
|
|
640
|
-
: result.data.map((item) => item[column]);
|
|
641
|
-
switch (operation) {
|
|
642
|
-
case 'count':
|
|
643
|
-
aggregateResult[alias] = result.data.length;
|
|
644
|
-
break;
|
|
645
|
-
case 'sum':
|
|
646
|
-
aggregateResult[alias] = values.reduce((sum, val) => sum + (val || 0), 0);
|
|
647
|
-
break;
|
|
648
|
-
case 'avg':
|
|
649
|
-
const sum = values.reduce((s, val) => s + (val || 0), 0);
|
|
650
|
-
aggregateResult[alias] = values.length > 0 ? sum / values.length : 0;
|
|
651
|
-
break;
|
|
652
|
-
case 'min':
|
|
653
|
-
const minValues = values.filter((v) => v !== undefined && v !== null);
|
|
654
|
-
aggregateResult[alias] = minValues.length > 0 ? Math.min(...minValues) : null;
|
|
655
|
-
break;
|
|
656
|
-
case 'max':
|
|
657
|
-
const maxValues = values.filter((v) => v !== undefined && v !== null);
|
|
658
|
-
aggregateResult[alias] = maxValues.length > 0 ? Math.max(...maxValues) : null;
|
|
659
|
-
break;
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
|
-
return aggregateResult;
|
|
708
|
+
const { TransactWriteCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
709
|
+
const operations = context.client.operations || [];
|
|
710
|
+
if (operations.length === 0) {
|
|
711
|
+
context.status = 'committed';
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
await this.docClient.send(new TransactWriteCommand({
|
|
715
|
+
TransactItems: operations,
|
|
716
|
+
}));
|
|
717
|
+
context.status = 'committed';
|
|
663
718
|
}
|
|
664
719
|
catch (error) {
|
|
665
|
-
|
|
720
|
+
context.status = 'error';
|
|
721
|
+
throw database_error_1.DatabaseError.transactionError(`Failed to commit transaction: ${error.message}`, error);
|
|
666
722
|
}
|
|
667
723
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
724
|
+
async rollbackTransaction(context) {
|
|
725
|
+
// DynamoDB doesn't have explicit rollback - transaction is simply not committed
|
|
726
|
+
context.client.operations = [];
|
|
727
|
+
context.status = 'rolled_back';
|
|
728
|
+
}
|
|
729
|
+
async createSavepoint(context, name) {
|
|
730
|
+
// DynamoDB does not support savepoints
|
|
731
|
+
throw new database_error_1.DatabaseError('DynamoDB does not support savepoints.', enums_1.DatabaseErrorType.NOT_SUPPORTED);
|
|
732
|
+
}
|
|
733
|
+
async releaseSavepoint(context, savepoint) {
|
|
734
|
+
throw new database_error_1.DatabaseError('DynamoDB does not support savepoints.', enums_1.DatabaseErrorType.NOT_SUPPORTED);
|
|
735
|
+
}
|
|
736
|
+
async rollbackToSavepoint(context, savepoint) {
|
|
737
|
+
throw new database_error_1.DatabaseError('DynamoDB does not support savepoints.', enums_1.DatabaseErrorType.NOT_SUPPORTED);
|
|
738
|
+
}
|
|
739
|
+
supportsSavepoints() {
|
|
740
|
+
return false;
|
|
741
|
+
}
|
|
742
|
+
// ==================== SCHEMA METHODS ====================
|
|
743
|
+
async createTable(definition, options) {
|
|
744
|
+
this.ensureConnected();
|
|
671
745
|
try {
|
|
672
746
|
const { CreateTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
747
|
+
// Find primary key column
|
|
748
|
+
const pkColumn = definition.columns.find(c => c.primaryKey);
|
|
749
|
+
if (!pkColumn) {
|
|
750
|
+
throw new Error('DynamoDB tables require a primary key column');
|
|
751
|
+
}
|
|
752
|
+
const keySchema = [
|
|
753
|
+
{ AttributeName: pkColumn.name, KeyType: 'HASH' },
|
|
754
|
+
];
|
|
755
|
+
const attributeDefinitions = [
|
|
756
|
+
{ AttributeName: pkColumn.name, AttributeType: this.mapToDynamoType(pkColumn.type) },
|
|
757
|
+
];
|
|
758
|
+
// Check for sort key (second column marked as primary key or sort key)
|
|
759
|
+
const sortKeyColumn = definition.columns.find(c => c.name !== pkColumn.name && c.sortKey);
|
|
760
|
+
if (sortKeyColumn) {
|
|
761
|
+
keySchema.push({ AttributeName: sortKeyColumn.name, KeyType: 'RANGE' });
|
|
762
|
+
attributeDefinitions.push({
|
|
763
|
+
AttributeName: sortKeyColumn.name,
|
|
764
|
+
AttributeType: this.mapToDynamoType(sortKeyColumn.type),
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
const params = {
|
|
768
|
+
TableName: definition.name,
|
|
692
769
|
KeySchema: keySchema,
|
|
693
770
|
AttributeDefinitions: attributeDefinitions,
|
|
694
|
-
BillingMode: 'PAY_PER_REQUEST', // On-demand
|
|
695
|
-
}));
|
|
696
|
-
const executionTime = Date.now() - startTime;
|
|
697
|
-
return {
|
|
698
|
-
success: true,
|
|
699
|
-
operation: 'create',
|
|
700
|
-
table: schema.name,
|
|
701
|
-
executionTime,
|
|
771
|
+
BillingMode: 'PAY_PER_REQUEST', // On-demand capacity
|
|
702
772
|
};
|
|
773
|
+
await this.dynamoClient.send(new CreateTableCommand(params));
|
|
774
|
+
// Wait for table to be active
|
|
775
|
+
await this.waitForTableActive(definition.name);
|
|
776
|
+
// Create GSIs if defined
|
|
777
|
+
if (definition.indexes) {
|
|
778
|
+
for (const index of definition.indexes) {
|
|
779
|
+
await this.createIndex(index);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
703
782
|
}
|
|
704
783
|
catch (error) {
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
error: error.message,
|
|
710
|
-
executionTime: Date.now() - startTime,
|
|
711
|
-
};
|
|
784
|
+
if ((options === null || options === void 0 ? void 0 : options.ifNotExists) && error.name === 'ResourceInUseException') {
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
throw database_error_1.DatabaseError.schemaError(`Failed to create table: ${error.message}`, error);
|
|
712
788
|
}
|
|
713
789
|
}
|
|
714
|
-
async
|
|
715
|
-
|
|
790
|
+
async alterTable(tableName, operations) {
|
|
791
|
+
this.ensureConnected();
|
|
792
|
+
// DynamoDB has very limited ALTER capabilities
|
|
793
|
+
// Can only modify GSIs and some table settings
|
|
716
794
|
try {
|
|
717
|
-
const
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
operation: 'drop',
|
|
725
|
-
table: tableName,
|
|
726
|
-
executionTime: Date.now() - startTime,
|
|
727
|
-
};
|
|
795
|
+
for (const op of operations) {
|
|
796
|
+
if (op.type === 'ADD' && op.constraint) {
|
|
797
|
+
// Add GSI
|
|
798
|
+
// This would require UpdateTableCommand with GlobalSecondaryIndexUpdates
|
|
799
|
+
throw new database_error_1.DatabaseError('Adding indexes to DynamoDB requires table recreation or GSI updates. Use createIndex instead.', enums_1.DatabaseErrorType.NOT_SUPPORTED);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
728
802
|
}
|
|
729
803
|
catch (error) {
|
|
730
|
-
|
|
731
|
-
success: false,
|
|
732
|
-
operation: 'drop',
|
|
733
|
-
table: tableName,
|
|
734
|
-
error: error.message,
|
|
735
|
-
executionTime: Date.now() - startTime,
|
|
736
|
-
};
|
|
804
|
+
throw database_error_1.DatabaseError.schemaError(`Failed to alter table: ${error.message}`, error);
|
|
737
805
|
}
|
|
738
806
|
}
|
|
739
|
-
async
|
|
740
|
-
|
|
741
|
-
// Can only modify throughput, streams, TTL, etc.
|
|
742
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.SCHEMA_ERROR, 'DynamoDB does not support traditional table alterations. You can only modify table settings.');
|
|
743
|
-
}
|
|
744
|
-
async getTableSchema(connection, tableName) {
|
|
807
|
+
async dropTable(tableName, ifExists, cascade) {
|
|
808
|
+
this.ensureConnected();
|
|
745
809
|
try {
|
|
746
|
-
const {
|
|
747
|
-
|
|
748
|
-
const result = await client.send(new DescribeTableCommand({
|
|
810
|
+
const { DeleteTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
811
|
+
await this.dynamoClient.send(new DeleteTableCommand({
|
|
749
812
|
TableName: tableName,
|
|
750
813
|
}));
|
|
751
|
-
const table = result.Table;
|
|
752
|
-
const columns = table.KeySchema.map((key) => {
|
|
753
|
-
const attr = table.AttributeDefinitions.find((a) => a.AttributeName === key.AttributeName);
|
|
754
|
-
return {
|
|
755
|
-
name: key.AttributeName,
|
|
756
|
-
type: this.mapDynamoDBTypeToColumnType((attr === null || attr === void 0 ? void 0 : attr.AttributeType) || 'S'),
|
|
757
|
-
primaryKey: key.KeyType === 'HASH',
|
|
758
|
-
nullable: false,
|
|
759
|
-
};
|
|
760
|
-
});
|
|
761
|
-
return {
|
|
762
|
-
name: tableName,
|
|
763
|
-
columns,
|
|
764
|
-
};
|
|
765
814
|
}
|
|
766
815
|
catch (error) {
|
|
767
|
-
|
|
816
|
+
if (ifExists && error.name === 'ResourceNotFoundException') {
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
throw database_error_1.DatabaseError.schemaError(`Failed to drop table: ${error.message}`, error);
|
|
768
820
|
}
|
|
769
821
|
}
|
|
770
|
-
async listTables(
|
|
822
|
+
async listTables() {
|
|
823
|
+
this.ensureConnected();
|
|
771
824
|
try {
|
|
772
825
|
const { ListTablesCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
773
|
-
const
|
|
774
|
-
|
|
775
|
-
return result.TableNames || [];
|
|
826
|
+
const response = await this.dynamoClient.send(new ListTablesCommand({}));
|
|
827
|
+
return response.TableNames || [];
|
|
776
828
|
}
|
|
777
829
|
catch (error) {
|
|
778
|
-
throw
|
|
830
|
+
throw database_error_1.DatabaseError.schemaError(`Failed to list tables: ${error.message}`, error);
|
|
779
831
|
}
|
|
780
832
|
}
|
|
781
|
-
async tableExists(
|
|
833
|
+
async tableExists(tableName) {
|
|
834
|
+
this.ensureConnected();
|
|
782
835
|
try {
|
|
783
836
|
const { DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
784
|
-
|
|
785
|
-
await client.send(new DescribeTableCommand({
|
|
837
|
+
await this.dynamoClient.send(new DescribeTableCommand({
|
|
786
838
|
TableName: tableName,
|
|
787
839
|
}));
|
|
788
840
|
return true;
|
|
@@ -791,761 +843,607 @@ class DynamoDBAdapter extends base_adapter_1.BaseDatabaseAdapter {
|
|
|
791
843
|
if (error.name === 'ResourceNotFoundException') {
|
|
792
844
|
return false;
|
|
793
845
|
}
|
|
794
|
-
throw
|
|
846
|
+
throw database_error_1.DatabaseError.schemaError(`Failed to check table existence: ${error.message}`, error);
|
|
795
847
|
}
|
|
796
848
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
849
|
+
async getTableSchema(tableName) {
|
|
850
|
+
var _a;
|
|
851
|
+
this.ensureConnected();
|
|
800
852
|
try {
|
|
801
|
-
const {
|
|
802
|
-
const
|
|
803
|
-
|
|
804
|
-
const keySchema = options.index.columns.map((col, idx) => ({
|
|
805
|
-
AttributeName: col.name,
|
|
806
|
-
KeyType: idx === 0 ? 'HASH' : 'RANGE',
|
|
807
|
-
}));
|
|
808
|
-
const attributeDefinitions = options.index.columns.map((col) => ({
|
|
809
|
-
AttributeName: col.name,
|
|
810
|
-
AttributeType: 'S', // Default to String
|
|
811
|
-
}));
|
|
812
|
-
await client.send(new UpdateTableCommand({
|
|
813
|
-
TableName: options.table,
|
|
814
|
-
AttributeDefinitions: attributeDefinitions,
|
|
815
|
-
GlobalSecondaryIndexUpdates: [
|
|
816
|
-
{
|
|
817
|
-
Create: {
|
|
818
|
-
IndexName: options.index.name,
|
|
819
|
-
KeySchema: keySchema,
|
|
820
|
-
Projection: {
|
|
821
|
-
ProjectionType: 'ALL',
|
|
822
|
-
},
|
|
823
|
-
},
|
|
824
|
-
},
|
|
825
|
-
],
|
|
853
|
+
const { DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
854
|
+
const response = await this.dynamoClient.send(new DescribeTableCommand({
|
|
855
|
+
TableName: tableName,
|
|
826
856
|
}));
|
|
857
|
+
const table = response.Table;
|
|
858
|
+
// Map attribute definitions to columns
|
|
859
|
+
const columns = (table.AttributeDefinitions || []).map((attr) => {
|
|
860
|
+
var _a;
|
|
861
|
+
return ({
|
|
862
|
+
name: attr.AttributeName,
|
|
863
|
+
type: this.mapFromDynamoType(attr.AttributeType),
|
|
864
|
+
nullable: true,
|
|
865
|
+
isPrimaryKey: ((_a = table.KeySchema) === null || _a === void 0 ? void 0 : _a.some((k) => k.AttributeName === attr.AttributeName && k.KeyType === 'HASH')) || false,
|
|
866
|
+
isUnique: false,
|
|
867
|
+
isAutoIncrement: false,
|
|
868
|
+
});
|
|
869
|
+
});
|
|
870
|
+
// Get primary key
|
|
871
|
+
const primaryKey = ((_a = table.KeySchema) === null || _a === void 0 ? void 0 : _a.filter((k) => k.KeyType === 'HASH').map((k) => k.AttributeName)) || [];
|
|
872
|
+
// Get GSIs as indexes
|
|
873
|
+
const indexes = (table.GlobalSecondaryIndexes || []).map((gsi) => {
|
|
874
|
+
var _a;
|
|
875
|
+
return ({
|
|
876
|
+
name: gsi.IndexName,
|
|
877
|
+
table: tableName,
|
|
878
|
+
columns: ((_a = gsi.KeySchema) === null || _a === void 0 ? void 0 : _a.map((k) => k.AttributeName)) || [],
|
|
879
|
+
unique: false,
|
|
880
|
+
primaryKey: false,
|
|
881
|
+
type: 'GSI',
|
|
882
|
+
});
|
|
883
|
+
});
|
|
884
|
+
// Add LSIs
|
|
885
|
+
(table.LocalSecondaryIndexes || []).forEach((lsi) => {
|
|
886
|
+
var _a;
|
|
887
|
+
indexes.push({
|
|
888
|
+
name: lsi.IndexName,
|
|
889
|
+
table: tableName,
|
|
890
|
+
columns: ((_a = lsi.KeySchema) === null || _a === void 0 ? void 0 : _a.map((k) => k.AttributeName)) || [],
|
|
891
|
+
unique: false,
|
|
892
|
+
primaryKey: false,
|
|
893
|
+
type: 'LSI',
|
|
894
|
+
});
|
|
895
|
+
});
|
|
827
896
|
return {
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
897
|
+
name: tableName,
|
|
898
|
+
columns,
|
|
899
|
+
indexes,
|
|
900
|
+
constraints: [],
|
|
901
|
+
primaryKey,
|
|
902
|
+
estimatedRowCount: Number(table.ItemCount) || 0,
|
|
833
903
|
};
|
|
834
904
|
}
|
|
835
905
|
catch (error) {
|
|
836
|
-
|
|
837
|
-
success: false,
|
|
838
|
-
operation: 'create',
|
|
839
|
-
indexName: options.index.name,
|
|
840
|
-
table: options.table,
|
|
841
|
-
error: error.message,
|
|
842
|
-
executionTime: Date.now() - startTime,
|
|
843
|
-
};
|
|
906
|
+
throw database_error_1.DatabaseError.schemaError(`Failed to get table schema: ${error.message}`, error);
|
|
844
907
|
}
|
|
845
908
|
}
|
|
846
|
-
async
|
|
847
|
-
|
|
909
|
+
async createIndex(index, ifNotExists, concurrent) {
|
|
910
|
+
this.ensureConnected();
|
|
911
|
+
// DynamoDB indexes (GSI) can only be created during table creation
|
|
912
|
+
// or via UpdateTable (which is limited)
|
|
913
|
+
throw new database_error_1.DatabaseError('DynamoDB Global Secondary Indexes must be created during table creation or via UpdateTable with specific parameters.', enums_1.DatabaseErrorType.NOT_SUPPORTED);
|
|
914
|
+
}
|
|
915
|
+
async dropIndex(tableName, indexName, ifExists, concurrent, cascade) {
|
|
916
|
+
this.ensureConnected();
|
|
848
917
|
try {
|
|
849
918
|
const { UpdateTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
TableName: options.table,
|
|
919
|
+
await this.dynamoClient.send(new UpdateTableCommand({
|
|
920
|
+
TableName: tableName,
|
|
853
921
|
GlobalSecondaryIndexUpdates: [
|
|
854
922
|
{
|
|
855
923
|
Delete: {
|
|
856
|
-
IndexName:
|
|
924
|
+
IndexName: indexName,
|
|
857
925
|
},
|
|
858
926
|
},
|
|
859
927
|
],
|
|
860
928
|
}));
|
|
861
|
-
return {
|
|
862
|
-
success: true,
|
|
863
|
-
operation: 'drop',
|
|
864
|
-
indexName: options.indexName,
|
|
865
|
-
table: options.table,
|
|
866
|
-
executionTime: Date.now() - startTime,
|
|
867
|
-
};
|
|
868
929
|
}
|
|
869
930
|
catch (error) {
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
table: options.table,
|
|
875
|
-
error: error.message,
|
|
876
|
-
executionTime: Date.now() - startTime,
|
|
877
|
-
};
|
|
931
|
+
if (ifExists && error.name === 'ResourceNotFoundException') {
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
throw database_error_1.DatabaseError.schemaError(`Failed to drop index: ${error.message}`, error);
|
|
878
935
|
}
|
|
879
936
|
}
|
|
880
|
-
async listIndexes(
|
|
881
|
-
|
|
937
|
+
async listIndexes(tableName, includeSystem) {
|
|
938
|
+
this.ensureConnected();
|
|
882
939
|
try {
|
|
883
|
-
const
|
|
884
|
-
|
|
885
|
-
const result = await client.send(new DescribeTableCommand({
|
|
886
|
-
TableName: options.table,
|
|
887
|
-
}));
|
|
888
|
-
const indexes = [];
|
|
889
|
-
// Add GSIs
|
|
890
|
-
if ((_a = result.Table) === null || _a === void 0 ? void 0 : _a.GlobalSecondaryIndexes) {
|
|
891
|
-
result.Table.GlobalSecondaryIndexes.forEach((gsi) => {
|
|
892
|
-
indexes.push({
|
|
893
|
-
name: gsi.IndexName,
|
|
894
|
-
table: options.table,
|
|
895
|
-
columns: gsi.KeySchema.map((key) => key.AttributeName),
|
|
896
|
-
columnDetails: gsi.KeySchema.map((key) => ({
|
|
897
|
-
name: key.AttributeName,
|
|
898
|
-
order: 'ASC',
|
|
899
|
-
})),
|
|
900
|
-
unique: false,
|
|
901
|
-
primaryKey: false,
|
|
902
|
-
type: 'GSI',
|
|
903
|
-
});
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
|
-
// Add LSIs
|
|
907
|
-
if ((_b = result.Table) === null || _b === void 0 ? void 0 : _b.LocalSecondaryIndexes) {
|
|
908
|
-
result.Table.LocalSecondaryIndexes.forEach((lsi) => {
|
|
909
|
-
indexes.push({
|
|
910
|
-
name: lsi.IndexName,
|
|
911
|
-
table: options.table,
|
|
912
|
-
columns: lsi.KeySchema.map((key) => key.AttributeName),
|
|
913
|
-
columnDetails: lsi.KeySchema.map((key) => ({
|
|
914
|
-
name: key.AttributeName,
|
|
915
|
-
order: 'ASC',
|
|
916
|
-
})),
|
|
917
|
-
unique: false,
|
|
918
|
-
primaryKey: false,
|
|
919
|
-
type: 'LSI',
|
|
920
|
-
});
|
|
921
|
-
});
|
|
922
|
-
}
|
|
923
|
-
return indexes;
|
|
940
|
+
const schema = await this.getTableSchema(tableName);
|
|
941
|
+
return schema.indexes;
|
|
924
942
|
}
|
|
925
943
|
catch (error) {
|
|
926
|
-
throw
|
|
944
|
+
throw database_error_1.DatabaseError.schemaError(`Failed to list indexes: ${error.message}`, error);
|
|
927
945
|
}
|
|
928
946
|
}
|
|
929
|
-
async getIndexStatistics(
|
|
930
|
-
|
|
947
|
+
async getIndexStatistics(tableName, indexName) {
|
|
948
|
+
this.ensureConnected();
|
|
931
949
|
try {
|
|
932
950
|
const { DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
933
|
-
const
|
|
934
|
-
const result = await client.send(new DescribeTableCommand({
|
|
951
|
+
const response = await this.dynamoClient.send(new DescribeTableCommand({
|
|
935
952
|
TableName: tableName,
|
|
936
953
|
}));
|
|
937
|
-
const
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
954
|
+
const results = [];
|
|
955
|
+
const table = response.Table;
|
|
956
|
+
// Add table itself as primary index
|
|
957
|
+
if (!indexName || indexName === 'PRIMARY') {
|
|
958
|
+
results.push({
|
|
959
|
+
indexName: 'PRIMARY',
|
|
960
|
+
tableName,
|
|
961
|
+
scans: 0,
|
|
962
|
+
tuplesRead: Number(table.ItemCount) || 0,
|
|
963
|
+
sizeBytes: Number(table.TableSizeBytes) || 0,
|
|
964
|
+
sizeFormatted: this.formatBytes(Number(table.TableSizeBytes) || 0),
|
|
948
965
|
});
|
|
949
966
|
}
|
|
950
|
-
|
|
967
|
+
// Add GSIs
|
|
968
|
+
for (const gsi of table.GlobalSecondaryIndexes || []) {
|
|
969
|
+
if (!indexName || indexName === gsi.IndexName) {
|
|
970
|
+
results.push({
|
|
971
|
+
indexName: gsi.IndexName,
|
|
972
|
+
tableName,
|
|
973
|
+
scans: 0,
|
|
974
|
+
tuplesRead: Number(gsi.ItemCount) || 0,
|
|
975
|
+
sizeBytes: Number(gsi.IndexSizeBytes) || 0,
|
|
976
|
+
sizeFormatted: this.formatBytes(Number(gsi.IndexSizeBytes) || 0),
|
|
977
|
+
});
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
return results;
|
|
951
981
|
}
|
|
952
982
|
catch (error) {
|
|
953
|
-
throw
|
|
983
|
+
throw database_error_1.DatabaseError.schemaError(`Failed to get index statistics: ${error.message}`, error);
|
|
954
984
|
}
|
|
955
985
|
}
|
|
956
|
-
// ====================
|
|
986
|
+
// ==================== UTILITY METHODS ====================
|
|
987
|
+
escapeIdentifier(identifier) {
|
|
988
|
+
return identifier;
|
|
989
|
+
}
|
|
990
|
+
escapeValue(value) {
|
|
991
|
+
return JSON.stringify(value);
|
|
992
|
+
}
|
|
957
993
|
/**
|
|
958
|
-
*
|
|
959
|
-
* Note: DynamoDB is schema-less, so column operations are skipped
|
|
994
|
+
* Check if value is an update operator object
|
|
960
995
|
*/
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
const
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
case '
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
const attributeDefinitions = operation.params.columns.map((col) => ({
|
|
1008
|
-
AttributeName: col,
|
|
1009
|
-
AttributeType: 'S', // Default to String
|
|
1010
|
-
}));
|
|
1011
|
-
await client.send(new UpdateTableCommand({
|
|
1012
|
-
TableName: operation.table,
|
|
1013
|
-
AttributeDefinitions: attributeDefinitions,
|
|
1014
|
-
GlobalSecondaryIndexUpdates: [
|
|
1015
|
-
{
|
|
1016
|
-
Create: {
|
|
1017
|
-
IndexName: operation.params.indexName,
|
|
1018
|
-
KeySchema: keySchema,
|
|
1019
|
-
Projection: {
|
|
1020
|
-
ProjectionType: 'ALL',
|
|
1021
|
-
},
|
|
1022
|
-
},
|
|
1023
|
-
},
|
|
1024
|
-
],
|
|
1025
|
-
}));
|
|
1026
|
-
return { executed: true, command: `AddIndex: ${operation.params.indexName}` };
|
|
1027
|
-
}
|
|
1028
|
-
return { executed: false };
|
|
1029
|
-
case 'drop_index':
|
|
1030
|
-
if (operation.table && ((_d = operation.params) === null || _d === void 0 ? void 0 : _d.indexName)) {
|
|
1031
|
-
await client.send(new UpdateTableCommand({
|
|
1032
|
-
TableName: operation.table,
|
|
1033
|
-
GlobalSecondaryIndexUpdates: [
|
|
1034
|
-
{
|
|
1035
|
-
Delete: {
|
|
1036
|
-
IndexName: operation.params.indexName,
|
|
1037
|
-
},
|
|
1038
|
-
},
|
|
1039
|
-
],
|
|
1040
|
-
}));
|
|
1041
|
-
return { executed: true, command: `DropIndex: ${operation.params.indexName}` };
|
|
1042
|
-
}
|
|
1043
|
-
return { executed: false };
|
|
1044
|
-
case 'raw_sql':
|
|
1045
|
-
if (operation.sql) {
|
|
1046
|
-
// Use PartiQL for raw queries
|
|
1047
|
-
await client.send(new ExecuteStatementCommand({
|
|
1048
|
-
Statement: operation.sql,
|
|
1049
|
-
}));
|
|
1050
|
-
return { executed: true, command: `PartiQL: ${operation.sql.substring(0, 50)}...` };
|
|
1051
|
-
}
|
|
1052
|
-
return { executed: false };
|
|
1053
|
-
// Schema-less operations - skip silently for DynamoDB
|
|
1054
|
-
case 'add_column':
|
|
1055
|
-
case 'drop_column':
|
|
1056
|
-
case 'modify_column':
|
|
1057
|
-
case 'rename_column':
|
|
1058
|
-
case 'alter_table':
|
|
1059
|
-
return { executed: false, command: `Skipped (schema-less): ${operation.type}` };
|
|
1060
|
-
// Constraint operations - not applicable to DynamoDB
|
|
1061
|
-
case 'add_constraint':
|
|
1062
|
-
case 'drop_constraint':
|
|
1063
|
-
return { executed: false, command: `Skipped (no constraints): ${operation.type}` };
|
|
1064
|
-
default:
|
|
1065
|
-
return { executed: false };
|
|
996
|
+
isUpdateOperator(value) {
|
|
997
|
+
if (!value || typeof value !== 'object')
|
|
998
|
+
return false;
|
|
999
|
+
const operators = ['$INC', '$DEC', '$MUL', '$MIN', '$MAX', '$SET', '$UNSET', '$PUSH', '$PULL', '$ADDTOSET'];
|
|
1000
|
+
return operators.some(op => op in value);
|
|
1001
|
+
}
|
|
1002
|
+
getParameterPlaceholder(index) {
|
|
1003
|
+
return `:val${index}`;
|
|
1004
|
+
}
|
|
1005
|
+
getColumnTypeString(columnType, options) {
|
|
1006
|
+
return this.mapToDynamoType(columnType);
|
|
1007
|
+
}
|
|
1008
|
+
getSupportedFeatures() {
|
|
1009
|
+
return [
|
|
1010
|
+
base_adapter_1.DatabaseFeature.TRANSACTIONS,
|
|
1011
|
+
base_adapter_1.DatabaseFeature.TTL,
|
|
1012
|
+
base_adapter_1.DatabaseFeature.GLOBAL_SECONDARY_INDEXES,
|
|
1013
|
+
base_adapter_1.DatabaseFeature.LOCAL_SECONDARY_INDEXES,
|
|
1014
|
+
base_adapter_1.DatabaseFeature.BATCH_OPERATIONS,
|
|
1015
|
+
base_adapter_1.DatabaseFeature.ATOMIC_COUNTERS,
|
|
1016
|
+
base_adapter_1.DatabaseFeature.CHANGE_STREAMS,
|
|
1017
|
+
];
|
|
1018
|
+
}
|
|
1019
|
+
parseError(error) {
|
|
1020
|
+
const name = error.name || error.code;
|
|
1021
|
+
let type = enums_1.DatabaseErrorType.UNKNOWN_ERROR;
|
|
1022
|
+
switch (name) {
|
|
1023
|
+
case 'ConditionalCheckFailedException':
|
|
1024
|
+
type = enums_1.DatabaseErrorType.UNIQUE_VIOLATION;
|
|
1025
|
+
break;
|
|
1026
|
+
case 'ResourceNotFoundException':
|
|
1027
|
+
type = enums_1.DatabaseErrorType.NOT_FOUND;
|
|
1028
|
+
break;
|
|
1029
|
+
case 'ResourceInUseException':
|
|
1030
|
+
type = enums_1.DatabaseErrorType.SCHEMA_ERROR;
|
|
1031
|
+
break;
|
|
1032
|
+
case 'ValidationException':
|
|
1033
|
+
type = enums_1.DatabaseErrorType.VALIDATION_ERROR;
|
|
1034
|
+
break;
|
|
1035
|
+
case 'ProvisionedThroughputExceededException':
|
|
1036
|
+
case 'ThrottlingException':
|
|
1037
|
+
type = enums_1.DatabaseErrorType.QUERY_ERROR;
|
|
1038
|
+
break;
|
|
1039
|
+
case 'AccessDeniedException':
|
|
1040
|
+
type = enums_1.DatabaseErrorType.AUTHENTICATION_ERROR;
|
|
1041
|
+
break;
|
|
1066
1042
|
}
|
|
1043
|
+
return {
|
|
1044
|
+
type,
|
|
1045
|
+
message: error.message || 'Unknown database error',
|
|
1046
|
+
code: name,
|
|
1047
|
+
};
|
|
1067
1048
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1049
|
+
// ==================== PRIVATE HELPER METHODS ====================
|
|
1050
|
+
ensureConnected() {
|
|
1051
|
+
if (!this.connected || !this.docClient) {
|
|
1052
|
+
throw new database_error_1.DatabaseError('Not connected to DynamoDB', enums_1.DatabaseErrorType.CONNECTION_ERROR);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
buildFilterExpression(where, existingNames, existingValues) {
|
|
1056
|
+
const conditions = [];
|
|
1057
|
+
const names = Object.assign({}, existingNames);
|
|
1058
|
+
const values = Object.assign({}, existingValues);
|
|
1059
|
+
let valueIndex = Object.keys(existingValues).length;
|
|
1060
|
+
for (const [key, value] of Object.entries(where)) {
|
|
1061
|
+
if (key === '$AND') {
|
|
1062
|
+
const andConditions = [];
|
|
1063
|
+
for (const [andKey, andValue] of Object.entries(value)) {
|
|
1064
|
+
const result = this.buildFilterExpression({ [andKey]: andValue }, names, values);
|
|
1065
|
+
andConditions.push(result.expression);
|
|
1066
|
+
Object.assign(names, result.names);
|
|
1067
|
+
Object.assign(values, result.values);
|
|
1078
1068
|
}
|
|
1069
|
+
conditions.push(`(${andConditions.join(' AND ')})`);
|
|
1070
|
+
}
|
|
1071
|
+
else if (key === '$OR') {
|
|
1072
|
+
const orConditions = [];
|
|
1073
|
+
for (const [orKey, orValue] of Object.entries(value)) {
|
|
1074
|
+
const result = this.buildFilterExpression({ [orKey]: orValue }, names, values);
|
|
1075
|
+
orConditions.push(result.expression);
|
|
1076
|
+
Object.assign(names, result.names);
|
|
1077
|
+
Object.assign(values, result.values);
|
|
1078
|
+
}
|
|
1079
|
+
conditions.push(`(${orConditions.join(' OR ')})`);
|
|
1080
|
+
}
|
|
1081
|
+
else if (value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)) {
|
|
1082
|
+
const nameKey = `#${key.replace(/[^a-zA-Z0-9]/g, '')}`;
|
|
1083
|
+
names[nameKey] = key;
|
|
1084
|
+
for (const [op, opValue] of Object.entries(value)) {
|
|
1085
|
+
const valueKey = `:val${valueIndex++}`;
|
|
1086
|
+
values[valueKey] = opValue;
|
|
1087
|
+
switch (op) {
|
|
1088
|
+
case '$EQ':
|
|
1089
|
+
conditions.push(`${nameKey} = ${valueKey}`);
|
|
1090
|
+
break;
|
|
1091
|
+
case '$NE':
|
|
1092
|
+
case '$NOT':
|
|
1093
|
+
conditions.push(`${nameKey} <> ${valueKey}`);
|
|
1094
|
+
break;
|
|
1095
|
+
case '$GT':
|
|
1096
|
+
conditions.push(`${nameKey} > ${valueKey}`);
|
|
1097
|
+
break;
|
|
1098
|
+
case '$GTE':
|
|
1099
|
+
conditions.push(`${nameKey} >= ${valueKey}`);
|
|
1100
|
+
break;
|
|
1101
|
+
case '$LT':
|
|
1102
|
+
conditions.push(`${nameKey} < ${valueKey}`);
|
|
1103
|
+
break;
|
|
1104
|
+
case '$LTE':
|
|
1105
|
+
conditions.push(`${nameKey} <= ${valueKey}`);
|
|
1106
|
+
break;
|
|
1107
|
+
case '$IN':
|
|
1108
|
+
// DynamoDB requires separate placeholders for each value in IN clause
|
|
1109
|
+
if (Array.isArray(opValue)) {
|
|
1110
|
+
const inPlaceholders = [];
|
|
1111
|
+
for (const item of opValue) {
|
|
1112
|
+
const itemKey = `:val${valueIndex++}`;
|
|
1113
|
+
values[itemKey] = item;
|
|
1114
|
+
inPlaceholders.push(itemKey);
|
|
1115
|
+
}
|
|
1116
|
+
// Remove the original valueKey since we're using individual placeholders
|
|
1117
|
+
delete values[valueKey];
|
|
1118
|
+
conditions.push(`${nameKey} IN (${inPlaceholders.join(', ')})`);
|
|
1119
|
+
}
|
|
1120
|
+
else {
|
|
1121
|
+
// Single value - treat as equality
|
|
1122
|
+
conditions.push(`${nameKey} = ${valueKey}`);
|
|
1123
|
+
}
|
|
1124
|
+
break;
|
|
1125
|
+
case '$BETWEEN':
|
|
1126
|
+
const [min, max] = opValue;
|
|
1127
|
+
const minKey = `:val${valueIndex++}`;
|
|
1128
|
+
const maxKey = `:val${valueIndex++}`;
|
|
1129
|
+
values[minKey] = min;
|
|
1130
|
+
values[maxKey] = max;
|
|
1131
|
+
conditions.push(`${nameKey} BETWEEN ${minKey} AND ${maxKey}`);
|
|
1132
|
+
break;
|
|
1133
|
+
case '$LIKE':
|
|
1134
|
+
conditions.push(`contains(${nameKey}, ${valueKey})`);
|
|
1135
|
+
break;
|
|
1136
|
+
case '$IS_NULL':
|
|
1137
|
+
if (opValue) {
|
|
1138
|
+
conditions.push(`attribute_not_exists(${nameKey})`);
|
|
1139
|
+
}
|
|
1140
|
+
else {
|
|
1141
|
+
conditions.push(`attribute_exists(${nameKey})`);
|
|
1142
|
+
}
|
|
1143
|
+
delete values[valueKey];
|
|
1144
|
+
break;
|
|
1145
|
+
case '$IS_NOT_NULL':
|
|
1146
|
+
if (opValue) {
|
|
1147
|
+
conditions.push(`attribute_exists(${nameKey})`);
|
|
1148
|
+
}
|
|
1149
|
+
else {
|
|
1150
|
+
conditions.push(`attribute_not_exists(${nameKey})`);
|
|
1151
|
+
}
|
|
1152
|
+
delete values[valueKey];
|
|
1153
|
+
break;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
else {
|
|
1158
|
+
const nameKey = `#${key.replace(/[^a-zA-Z0-9]/g, '')}`;
|
|
1159
|
+
const valueKey = `:val${valueIndex++}`;
|
|
1160
|
+
names[nameKey] = key;
|
|
1161
|
+
values[valueKey] = value;
|
|
1162
|
+
conditions.push(`${nameKey} = ${valueKey}`);
|
|
1079
1163
|
}
|
|
1080
|
-
// Record migration in history table
|
|
1081
|
-
await this.recordMigration(connection, migration);
|
|
1082
|
-
return {
|
|
1083
|
-
tag: migration.tag,
|
|
1084
|
-
status: migration_types_1.MigrationStatus.COMPLETED,
|
|
1085
|
-
direction: migration_types_1.MigrationDirection.UP,
|
|
1086
|
-
executedAt: new Date(),
|
|
1087
|
-
duration: Date.now() - startTime,
|
|
1088
|
-
statements,
|
|
1089
|
-
};
|
|
1090
|
-
}
|
|
1091
|
-
catch (error) {
|
|
1092
|
-
return {
|
|
1093
|
-
tag: migration.tag,
|
|
1094
|
-
status: migration_types_1.MigrationStatus.FAILED,
|
|
1095
|
-
direction: migration_types_1.MigrationDirection.UP,
|
|
1096
|
-
executedAt: new Date(),
|
|
1097
|
-
duration: Date.now() - startTime,
|
|
1098
|
-
error: error.message,
|
|
1099
|
-
statements,
|
|
1100
|
-
};
|
|
1101
1164
|
}
|
|
1165
|
+
return {
|
|
1166
|
+
expression: conditions.join(' AND '),
|
|
1167
|
+
names,
|
|
1168
|
+
values,
|
|
1169
|
+
};
|
|
1102
1170
|
}
|
|
1103
|
-
|
|
1104
|
-
const
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1171
|
+
buildUpdateExpression(data) {
|
|
1172
|
+
const setClauses = [];
|
|
1173
|
+
const addClauses = [];
|
|
1174
|
+
const names = {};
|
|
1175
|
+
const values = {};
|
|
1176
|
+
let valueIndex = 0;
|
|
1177
|
+
for (const [key, value] of Object.entries(data)) {
|
|
1178
|
+
const nameKey = `#${key.replace(/[^a-zA-Z0-9]/g, '')}`;
|
|
1179
|
+
names[nameKey] = key;
|
|
1180
|
+
if (value && typeof value === 'object' && this.isUpdateOperator(value)) {
|
|
1181
|
+
const valueKey = `:val${valueIndex++}`;
|
|
1182
|
+
if ('$INC' in value) {
|
|
1183
|
+
values[valueKey] = value.$INC;
|
|
1184
|
+
addClauses.push(`${nameKey} ${valueKey}`);
|
|
1185
|
+
}
|
|
1186
|
+
else if ('$DEC' in value) {
|
|
1187
|
+
values[valueKey] = -value.$DEC;
|
|
1188
|
+
addClauses.push(`${nameKey} ${valueKey}`);
|
|
1189
|
+
}
|
|
1190
|
+
else if ('$MUL' in value) {
|
|
1191
|
+
// DynamoDB doesn't have native multiply - use SET with expression
|
|
1192
|
+
const mulValueKey = `:mul${valueIndex++}`;
|
|
1193
|
+
values[mulValueKey] = value.$MUL;
|
|
1194
|
+
setClauses.push(`${nameKey} = ${nameKey} * ${mulValueKey}`);
|
|
1195
|
+
}
|
|
1196
|
+
else if ('$MIN' in value) {
|
|
1197
|
+
// DynamoDB doesn't have native min - use if_not_exists or conditional
|
|
1198
|
+
// For simplicity, just set the value (user should use conditional writes for atomic min)
|
|
1199
|
+
values[valueKey] = value.$MIN;
|
|
1200
|
+
setClauses.push(`${nameKey} = if_not_exists(${nameKey}, ${valueKey})`);
|
|
1201
|
+
}
|
|
1202
|
+
else if ('$MAX' in value) {
|
|
1203
|
+
// DynamoDB doesn't have native max - similar to min
|
|
1204
|
+
values[valueKey] = value.$MAX;
|
|
1205
|
+
setClauses.push(`${nameKey} = if_not_exists(${nameKey}, ${valueKey})`);
|
|
1206
|
+
}
|
|
1207
|
+
else if ('$SET' in value) {
|
|
1208
|
+
values[valueKey] = value.$SET;
|
|
1209
|
+
setClauses.push(`${nameKey} = ${valueKey}`);
|
|
1210
|
+
}
|
|
1211
|
+
else if ('$UNSET' in value && value.$UNSET) {
|
|
1212
|
+
// Use REMOVE clause for unsetting
|
|
1213
|
+
// Note: REMOVE is handled separately
|
|
1214
|
+
setClauses.push(`REMOVE ${nameKey}`);
|
|
1215
|
+
}
|
|
1216
|
+
else if ('$PUSH' in value) {
|
|
1217
|
+
// DynamoDB list_append for arrays
|
|
1218
|
+
values[valueKey] = [value.$PUSH];
|
|
1219
|
+
setClauses.push(`${nameKey} = list_append(if_not_exists(${nameKey}, :emptyList), ${valueKey})`);
|
|
1220
|
+
values[':emptyList'] = [];
|
|
1221
|
+
}
|
|
1222
|
+
else if ('$ADDTOSET' in value) {
|
|
1223
|
+
// DynamoDB ADD for sets
|
|
1224
|
+
values[valueKey] = new Set([value.$ADDTOSET]);
|
|
1225
|
+
addClauses.push(`${nameKey} ${valueKey}`);
|
|
1112
1226
|
}
|
|
1113
1227
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
direction: migration_types_1.MigrationDirection.DOWN,
|
|
1120
|
-
executedAt: new Date(),
|
|
1121
|
-
duration: Date.now() - startTime,
|
|
1122
|
-
statements,
|
|
1123
|
-
};
|
|
1124
|
-
}
|
|
1125
|
-
catch (error) {
|
|
1126
|
-
return {
|
|
1127
|
-
tag: migration.tag,
|
|
1128
|
-
status: migration_types_1.MigrationStatus.FAILED,
|
|
1129
|
-
direction: migration_types_1.MigrationDirection.DOWN,
|
|
1130
|
-
executedAt: new Date(),
|
|
1131
|
-
duration: Date.now() - startTime,
|
|
1132
|
-
error: error.message,
|
|
1133
|
-
statements,
|
|
1134
|
-
};
|
|
1228
|
+
else {
|
|
1229
|
+
const valueKey = `:val${valueIndex++}`;
|
|
1230
|
+
values[valueKey] = value;
|
|
1231
|
+
setClauses.push(`${nameKey} = ${valueKey}`);
|
|
1232
|
+
}
|
|
1135
1233
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
const { ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
1140
|
-
const docClient = connection.getClient();
|
|
1141
|
-
// Ensure migration table exists
|
|
1142
|
-
await this.ensureMigrationTable(connection);
|
|
1143
|
-
const result = await docClient.send(new ScanCommand({
|
|
1144
|
-
TableName: '_ductape_migrations',
|
|
1145
|
-
}));
|
|
1146
|
-
return (result.Items || []).map((item) => ({
|
|
1147
|
-
tag: item.tag,
|
|
1148
|
-
name: item.name,
|
|
1149
|
-
env: options.env,
|
|
1150
|
-
product: options.product,
|
|
1151
|
-
database: options.database,
|
|
1152
|
-
status: migration_types_1.MigrationStatus.COMPLETED,
|
|
1153
|
-
direction: migration_types_1.MigrationDirection.UP,
|
|
1154
|
-
appliedAt: new Date(item.executed_at),
|
|
1155
|
-
}));
|
|
1234
|
+
let expression = '';
|
|
1235
|
+
if (setClauses.length > 0) {
|
|
1236
|
+
expression += `SET ${setClauses.join(', ')}`;
|
|
1156
1237
|
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1238
|
+
if (addClauses.length > 0) {
|
|
1239
|
+
if (expression)
|
|
1240
|
+
expression += ' ';
|
|
1241
|
+
expression += `ADD ${addClauses.join(', ')}`;
|
|
1159
1242
|
}
|
|
1243
|
+
return { expression, names, values };
|
|
1160
1244
|
}
|
|
1161
1245
|
/**
|
|
1162
|
-
*
|
|
1246
|
+
* Extract key condition from where clause if partition key is present.
|
|
1247
|
+
* This enables using Query instead of Scan for better performance.
|
|
1163
1248
|
*/
|
|
1164
|
-
async
|
|
1249
|
+
async extractKeyCondition(where, tableName) {
|
|
1250
|
+
var _a, _b, _c;
|
|
1251
|
+
if (!where || Object.keys(where).length === 0) {
|
|
1252
|
+
return { keyCondition: null, filterCondition: null };
|
|
1253
|
+
}
|
|
1165
1254
|
try {
|
|
1166
|
-
const {
|
|
1167
|
-
const
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
}
|
|
1173
|
-
return; // Table exists
|
|
1255
|
+
const { DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
1256
|
+
const response = await this.dynamoClient.send(new DescribeTableCommand({
|
|
1257
|
+
TableName: tableName,
|
|
1258
|
+
}));
|
|
1259
|
+
const keySchema = ((_a = response.Table) === null || _a === void 0 ? void 0 : _a.KeySchema) || [];
|
|
1260
|
+
if (keySchema.length === 0) {
|
|
1261
|
+
return { keyCondition: null, filterCondition: null };
|
|
1174
1262
|
}
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1263
|
+
// Get partition key and sort key names
|
|
1264
|
+
const partitionKeyName = (_b = keySchema.find((k) => k.KeyType === 'HASH')) === null || _b === void 0 ? void 0 : _b.AttributeName;
|
|
1265
|
+
const sortKeyName = (_c = keySchema.find((k) => k.KeyType === 'RANGE')) === null || _c === void 0 ? void 0 : _c.AttributeName;
|
|
1266
|
+
if (!partitionKeyName) {
|
|
1267
|
+
return { keyCondition: null, filterCondition: null };
|
|
1268
|
+
}
|
|
1269
|
+
// Check if partition key is in the where clause
|
|
1270
|
+
const partitionKeyValue = this.getWhereValue(where, partitionKeyName);
|
|
1271
|
+
if (partitionKeyValue === undefined) {
|
|
1272
|
+
// No partition key - must use Scan
|
|
1273
|
+
return { keyCondition: null, filterCondition: null };
|
|
1274
|
+
}
|
|
1275
|
+
// Build key condition expression
|
|
1276
|
+
const keyNames = {};
|
|
1277
|
+
const keyValues = {};
|
|
1278
|
+
const keyConditions = [];
|
|
1279
|
+
// Add partition key condition (must be equality)
|
|
1280
|
+
const pkNameKey = `#pk`;
|
|
1281
|
+
const pkValueKey = `:pkval`;
|
|
1282
|
+
keyNames[pkNameKey] = partitionKeyName;
|
|
1283
|
+
keyValues[pkValueKey] = partitionKeyValue;
|
|
1284
|
+
keyConditions.push(`${pkNameKey} = ${pkValueKey}`);
|
|
1285
|
+
// Check for sort key condition (can be equality or range)
|
|
1286
|
+
if (sortKeyName) {
|
|
1287
|
+
const sortKeyOp = this.getWhereOperator(where, sortKeyName);
|
|
1288
|
+
if (sortKeyOp) {
|
|
1289
|
+
const skNameKey = `#sk`;
|
|
1290
|
+
keyNames[skNameKey] = sortKeyName;
|
|
1291
|
+
if (sortKeyOp.op === '$EQ' || sortKeyOp.op === 'equality') {
|
|
1292
|
+
const skValueKey = `:skval`;
|
|
1293
|
+
keyValues[skValueKey] = sortKeyOp.value;
|
|
1294
|
+
keyConditions.push(`${skNameKey} = ${skValueKey}`);
|
|
1295
|
+
}
|
|
1296
|
+
else if (sortKeyOp.op === '$GT') {
|
|
1297
|
+
const skValueKey = `:skval`;
|
|
1298
|
+
keyValues[skValueKey] = sortKeyOp.value;
|
|
1299
|
+
keyConditions.push(`${skNameKey} > ${skValueKey}`);
|
|
1300
|
+
}
|
|
1301
|
+
else if (sortKeyOp.op === '$GTE') {
|
|
1302
|
+
const skValueKey = `:skval`;
|
|
1303
|
+
keyValues[skValueKey] = sortKeyOp.value;
|
|
1304
|
+
keyConditions.push(`${skNameKey} >= ${skValueKey}`);
|
|
1305
|
+
}
|
|
1306
|
+
else if (sortKeyOp.op === '$LT') {
|
|
1307
|
+
const skValueKey = `:skval`;
|
|
1308
|
+
keyValues[skValueKey] = sortKeyOp.value;
|
|
1309
|
+
keyConditions.push(`${skNameKey} < ${skValueKey}`);
|
|
1310
|
+
}
|
|
1311
|
+
else if (sortKeyOp.op === '$LTE') {
|
|
1312
|
+
const skValueKey = `:skval`;
|
|
1313
|
+
keyValues[skValueKey] = sortKeyOp.value;
|
|
1314
|
+
keyConditions.push(`${skNameKey} <= ${skValueKey}`);
|
|
1315
|
+
}
|
|
1316
|
+
else if (sortKeyOp.op === '$BETWEEN') {
|
|
1317
|
+
const [min, max] = sortKeyOp.value;
|
|
1318
|
+
keyValues[`:skmin`] = min;
|
|
1319
|
+
keyValues[`:skmax`] = max;
|
|
1320
|
+
keyConditions.push(`${skNameKey} BETWEEN :skmin AND :skmax`);
|
|
1321
|
+
}
|
|
1322
|
+
else if (sortKeyOp.op === '$BEGINS_WITH') {
|
|
1323
|
+
const skValueKey = `:skval`;
|
|
1324
|
+
keyValues[skValueKey] = sortKeyOp.value;
|
|
1325
|
+
keyConditions.push(`begins_with(${skNameKey}, ${skValueKey})`);
|
|
1326
|
+
}
|
|
1178
1327
|
}
|
|
1179
1328
|
}
|
|
1180
|
-
//
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
BillingMode: 'PAY_PER_REQUEST',
|
|
1196
|
-
}));
|
|
1197
|
-
// Wait for table to be active
|
|
1198
|
-
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
1199
|
-
}
|
|
1200
|
-
catch (error) {
|
|
1201
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.MIGRATION_ERROR, `Failed to ensure migration table: ${error.message}`, error);
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
/**
|
|
1205
|
-
* Record migration execution
|
|
1206
|
-
*/
|
|
1207
|
-
async recordMigration(connection, migration) {
|
|
1208
|
-
try {
|
|
1209
|
-
const { PutCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
|
|
1210
|
-
const docClient = connection.getClient();
|
|
1211
|
-
await this.ensureMigrationTable(connection);
|
|
1212
|
-
await docClient.send(new PutCommand({
|
|
1213
|
-
TableName: '_ductape_migrations',
|
|
1214
|
-
Item: {
|
|
1215
|
-
tag: migration.tag,
|
|
1216
|
-
name: migration.name,
|
|
1217
|
-
executed_at: new Date().toISOString(),
|
|
1329
|
+
// Build filter condition for remaining where clauses
|
|
1330
|
+
const filterWhere = Object.assign({}, where);
|
|
1331
|
+
delete filterWhere[partitionKeyName];
|
|
1332
|
+
if (sortKeyName) {
|
|
1333
|
+
delete filterWhere[sortKeyName];
|
|
1334
|
+
}
|
|
1335
|
+
let filterCondition = null;
|
|
1336
|
+
if (Object.keys(filterWhere).length > 0) {
|
|
1337
|
+
filterCondition = this.buildFilterExpression(filterWhere, {}, {});
|
|
1338
|
+
}
|
|
1339
|
+
return {
|
|
1340
|
+
keyCondition: {
|
|
1341
|
+
expression: keyConditions.join(' AND '),
|
|
1342
|
+
names: keyNames,
|
|
1343
|
+
values: keyValues,
|
|
1218
1344
|
},
|
|
1219
|
-
|
|
1345
|
+
filterCondition,
|
|
1346
|
+
};
|
|
1220
1347
|
}
|
|
1221
1348
|
catch (error) {
|
|
1222
|
-
|
|
1349
|
+
// If we can't get table metadata, fall back to Scan
|
|
1350
|
+
return { keyCondition: null, filterCondition: null };
|
|
1223
1351
|
}
|
|
1224
1352
|
}
|
|
1225
1353
|
/**
|
|
1226
|
-
*
|
|
1354
|
+
* Get simple value from where clause for a specific field
|
|
1227
1355
|
*/
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
await docClient.send(new DeleteCommand({
|
|
1233
|
-
TableName: '_ductape_migrations',
|
|
1234
|
-
Key: { tag },
|
|
1235
|
-
}));
|
|
1236
|
-
}
|
|
1237
|
-
catch (error) {
|
|
1238
|
-
throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.MIGRATION_ERROR, `Failed to remove migration: ${error.message}`, error);
|
|
1356
|
+
getWhereValue(where, fieldName) {
|
|
1357
|
+
const value = where[fieldName];
|
|
1358
|
+
if (value === undefined) {
|
|
1359
|
+
return undefined;
|
|
1239
1360
|
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
// Simple check - in production would need table metadata
|
|
1244
|
-
return where && typeof where === 'object' && Object.keys(where).length > 0;
|
|
1245
|
-
}
|
|
1246
|
-
buildQueryParams(options) {
|
|
1247
|
-
const params = {
|
|
1248
|
-
TableName: options.table,
|
|
1249
|
-
};
|
|
1250
|
-
if (options.where) {
|
|
1251
|
-
const { keyConditionExpression, expressionAttributeNames, expressionAttributeValues } = this.buildKeyConditionExpression(options.where);
|
|
1252
|
-
params.KeyConditionExpression = keyConditionExpression;
|
|
1253
|
-
params.ExpressionAttributeNames = expressionAttributeNames;
|
|
1254
|
-
params.ExpressionAttributeValues = expressionAttributeValues;
|
|
1361
|
+
// Simple equality check
|
|
1362
|
+
if (typeof value !== 'object' || value === null) {
|
|
1363
|
+
return value;
|
|
1255
1364
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1365
|
+
// Check for $EQ operator
|
|
1366
|
+
if (value.$EQ !== undefined) {
|
|
1367
|
+
return value.$EQ;
|
|
1258
1368
|
}
|
|
1259
|
-
return
|
|
1260
|
-
}
|
|
1261
|
-
buildScanParams(options) {
|
|
1262
|
-
const params = {
|
|
1263
|
-
TableName: options.table,
|
|
1264
|
-
};
|
|
1265
|
-
if (options.where) {
|
|
1266
|
-
const { filterExpression, expressionAttributeNames, expressionAttributeValues } = this.buildFilterExpression(options.where);
|
|
1267
|
-
params.FilterExpression = filterExpression;
|
|
1268
|
-
params.ExpressionAttributeNames = expressionAttributeNames;
|
|
1269
|
-
params.ExpressionAttributeValues = expressionAttributeValues;
|
|
1270
|
-
}
|
|
1271
|
-
if (options.limit) {
|
|
1272
|
-
params.Limit = options.limit;
|
|
1273
|
-
}
|
|
1274
|
-
return params;
|
|
1369
|
+
return undefined;
|
|
1275
1370
|
}
|
|
1276
1371
|
/**
|
|
1277
|
-
*
|
|
1278
|
-
* Supports both simplified syntax (GT, LT, etc.) and legacy $ prefix operators
|
|
1372
|
+
* Get operator and value from where clause for a specific field
|
|
1279
1373
|
*/
|
|
1280
|
-
|
|
1281
|
-
const
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1374
|
+
getWhereOperator(where, fieldName) {
|
|
1375
|
+
const value = where[fieldName];
|
|
1376
|
+
if (value === undefined) {
|
|
1377
|
+
return null;
|
|
1378
|
+
}
|
|
1379
|
+
// Simple equality
|
|
1380
|
+
if (typeof value !== 'object' || value === null) {
|
|
1381
|
+
return { op: 'equality', value };
|
|
1382
|
+
}
|
|
1383
|
+
// Check for operators
|
|
1384
|
+
for (const op of ['$EQ', '$GT', '$GTE', '$LT', '$LTE', '$BETWEEN', '$BEGINS_WITH']) {
|
|
1385
|
+
if (value[op] !== undefined) {
|
|
1386
|
+
return { op, value: value[op] };
|
|
1289
1387
|
}
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
const attrName = `#${key}`;
|
|
1293
|
-
names[attrName] = key;
|
|
1294
|
-
if (typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof Date)) {
|
|
1295
|
-
// Handle comparison operators
|
|
1296
|
-
for (const [op, opValue] of Object.entries(value)) {
|
|
1297
|
-
const valKey = `:val${valueIndex++}`;
|
|
1298
|
-
values[valKey] = opValue;
|
|
1299
|
-
switch (op) {
|
|
1300
|
-
case 'GT':
|
|
1301
|
-
case '$gt':
|
|
1302
|
-
conditions.push(`${attrName} > ${valKey}`);
|
|
1303
|
-
break;
|
|
1304
|
-
case 'GTE':
|
|
1305
|
-
case '$gte':
|
|
1306
|
-
conditions.push(`${attrName} >= ${valKey}`);
|
|
1307
|
-
break;
|
|
1308
|
-
case 'LT':
|
|
1309
|
-
case '$lt':
|
|
1310
|
-
conditions.push(`${attrName} < ${valKey}`);
|
|
1311
|
-
break;
|
|
1312
|
-
case 'LTE':
|
|
1313
|
-
case '$lte':
|
|
1314
|
-
conditions.push(`${attrName} <= ${valKey}`);
|
|
1315
|
-
break;
|
|
1316
|
-
case 'NE':
|
|
1317
|
-
case 'NOT':
|
|
1318
|
-
case '$ne':
|
|
1319
|
-
conditions.push(`${attrName} <> ${valKey}`);
|
|
1320
|
-
break;
|
|
1321
|
-
case 'BETWEEN':
|
|
1322
|
-
case '$between':
|
|
1323
|
-
if (Array.isArray(opValue) && opValue.length === 2) {
|
|
1324
|
-
const valKey2 = `:val${valueIndex++}`;
|
|
1325
|
-
values[valKey] = opValue[0];
|
|
1326
|
-
values[valKey2] = opValue[1];
|
|
1327
|
-
conditions.push(`${attrName} BETWEEN ${valKey} AND ${valKey2}`);
|
|
1328
|
-
}
|
|
1329
|
-
break;
|
|
1330
|
-
default:
|
|
1331
|
-
// Simple equality for unknown operators
|
|
1332
|
-
conditions.push(`${attrName} = ${valKey}`);
|
|
1333
|
-
}
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
else {
|
|
1337
|
-
// Simple equality
|
|
1338
|
-
const valKey = `:val${valueIndex++}`;
|
|
1339
|
-
values[valKey] = value;
|
|
1340
|
-
conditions.push(`${attrName} = ${valKey}`);
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
return conditions.join(' AND ');
|
|
1344
|
-
};
|
|
1345
|
-
const expression = buildCondition(where);
|
|
1346
|
-
return {
|
|
1347
|
-
keyConditionExpression: expression,
|
|
1348
|
-
expressionAttributeNames: names,
|
|
1349
|
-
expressionAttributeValues: values,
|
|
1350
|
-
};
|
|
1388
|
+
}
|
|
1389
|
+
return null;
|
|
1351
1390
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
const
|
|
1359
|
-
|
|
1360
|
-
const
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
const subConditions = andConditions.map(buildCondition);
|
|
1376
|
-
return `(${subConditions.join(' AND ')})`;
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
|
-
if (condition.$OR || condition.OR || condition.$or) {
|
|
1380
|
-
const orConditions = condition.$OR || condition.OR || condition.$or;
|
|
1381
|
-
if (typeof orConditions === 'object' && !Array.isArray(orConditions)) {
|
|
1382
|
-
// New syntax: { $OR: { col1: val1, col2: val2 } }
|
|
1383
|
-
const subConditions = [];
|
|
1384
|
-
for (const [key, value] of Object.entries(orConditions)) {
|
|
1385
|
-
if (key === '$AND' || key === 'AND' || key === '$and' || key === '$OR' || key === 'OR' || key === '$or') {
|
|
1386
|
-
subConditions.push(buildCondition({ [key]: value }));
|
|
1387
|
-
}
|
|
1388
|
-
else {
|
|
1389
|
-
subConditions.push(buildCondition({ [key]: value }));
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
return `(${subConditions.join(' OR ')})`;
|
|
1393
|
-
}
|
|
1394
|
-
else {
|
|
1395
|
-
// Array syntax: { $OR: [cond1, cond2] }
|
|
1396
|
-
const subConditions = orConditions.map(buildCondition);
|
|
1397
|
-
return `(${subConditions.join(' OR ')})`;
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
// Handle column conditions
|
|
1401
|
-
const conditions = [];
|
|
1402
|
-
for (const [key, value] of Object.entries(condition)) {
|
|
1403
|
-
// Skip logical operators at this level
|
|
1404
|
-
if (key === '$AND' || key === 'AND' || key === '$and' || key === '$OR' || key === 'OR' || key === '$or') {
|
|
1405
|
-
continue;
|
|
1406
|
-
}
|
|
1407
|
-
const attrName = `#${key}`;
|
|
1408
|
-
names[attrName] = key;
|
|
1409
|
-
if (typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof Date)) {
|
|
1410
|
-
// Handle comparison operators
|
|
1411
|
-
for (const [op, opValue] of Object.entries(value)) {
|
|
1412
|
-
switch (op) {
|
|
1413
|
-
// Preferred $-prefixed syntax
|
|
1414
|
-
case '$GT':
|
|
1415
|
-
case 'GT':
|
|
1416
|
-
case '$gt': {
|
|
1417
|
-
const valKey = `:val${valueIndex++}`;
|
|
1418
|
-
values[valKey] = opValue;
|
|
1419
|
-
conditions.push(`${attrName} > ${valKey}`);
|
|
1420
|
-
break;
|
|
1421
|
-
}
|
|
1422
|
-
case '$GTE':
|
|
1423
|
-
case 'GTE':
|
|
1424
|
-
case '$gte': {
|
|
1425
|
-
const valKey = `:val${valueIndex++}`;
|
|
1426
|
-
values[valKey] = opValue;
|
|
1427
|
-
conditions.push(`${attrName} >= ${valKey}`);
|
|
1428
|
-
break;
|
|
1429
|
-
}
|
|
1430
|
-
case '$LT':
|
|
1431
|
-
case 'LT':
|
|
1432
|
-
case '$lt': {
|
|
1433
|
-
const valKey = `:val${valueIndex++}`;
|
|
1434
|
-
values[valKey] = opValue;
|
|
1435
|
-
conditions.push(`${attrName} < ${valKey}`);
|
|
1436
|
-
break;
|
|
1437
|
-
}
|
|
1438
|
-
case '$LTE':
|
|
1439
|
-
case 'LTE':
|
|
1440
|
-
case '$lte': {
|
|
1441
|
-
const valKey = `:val${valueIndex++}`;
|
|
1442
|
-
values[valKey] = opValue;
|
|
1443
|
-
conditions.push(`${attrName} <= ${valKey}`);
|
|
1444
|
-
break;
|
|
1445
|
-
}
|
|
1446
|
-
case '$NE':
|
|
1447
|
-
case '$NOT':
|
|
1448
|
-
case 'NE':
|
|
1449
|
-
case 'NOT':
|
|
1450
|
-
case '$ne': {
|
|
1451
|
-
const valKey = `:val${valueIndex++}`;
|
|
1452
|
-
values[valKey] = opValue;
|
|
1453
|
-
conditions.push(`${attrName} <> ${valKey}`);
|
|
1454
|
-
break;
|
|
1455
|
-
}
|
|
1456
|
-
case '$IN':
|
|
1457
|
-
case 'IN':
|
|
1458
|
-
case '$in':
|
|
1459
|
-
if (Array.isArray(opValue)) {
|
|
1460
|
-
const inConditions = opValue.map((val) => {
|
|
1461
|
-
const valKey = `:val${valueIndex++}`;
|
|
1462
|
-
values[valKey] = val;
|
|
1463
|
-
return `${attrName} = ${valKey}`;
|
|
1464
|
-
});
|
|
1465
|
-
conditions.push(`(${inConditions.join(' OR ')})`);
|
|
1466
|
-
}
|
|
1467
|
-
break;
|
|
1468
|
-
case '$NOT_IN':
|
|
1469
|
-
case 'NOT_IN':
|
|
1470
|
-
case '$nin':
|
|
1471
|
-
if (Array.isArray(opValue)) {
|
|
1472
|
-
const notInConditions = opValue.map((val) => {
|
|
1473
|
-
const valKey = `:val${valueIndex++}`;
|
|
1474
|
-
values[valKey] = val;
|
|
1475
|
-
return `${attrName} <> ${valKey}`;
|
|
1476
|
-
});
|
|
1477
|
-
conditions.push(`(${notInConditions.join(' AND ')})`);
|
|
1478
|
-
}
|
|
1479
|
-
break;
|
|
1480
|
-
case '$LIKE':
|
|
1481
|
-
case 'LIKE':
|
|
1482
|
-
case '$like': {
|
|
1483
|
-
// DynamoDB uses contains() function for substring matching
|
|
1484
|
-
const valKey = `:val${valueIndex++}`;
|
|
1485
|
-
// Convert SQL LIKE pattern to substring (remove % wildcards)
|
|
1486
|
-
const searchValue = String(opValue).replace(/%/g, '');
|
|
1487
|
-
values[valKey] = searchValue;
|
|
1488
|
-
conditions.push(`contains(${attrName}, ${valKey})`);
|
|
1489
|
-
break;
|
|
1490
|
-
}
|
|
1491
|
-
case '$IS_NULL':
|
|
1492
|
-
case 'IS_NULL':
|
|
1493
|
-
case '$null':
|
|
1494
|
-
conditions.push(`attribute_not_exists(${attrName})`);
|
|
1495
|
-
break;
|
|
1496
|
-
case '$IS_NOT_NULL':
|
|
1497
|
-
case 'IS_NOT_NULL':
|
|
1498
|
-
case '$notNull':
|
|
1499
|
-
conditions.push(`attribute_exists(${attrName})`);
|
|
1500
|
-
break;
|
|
1501
|
-
case '$BETWEEN':
|
|
1502
|
-
case 'BETWEEN':
|
|
1503
|
-
case '$between':
|
|
1504
|
-
if (Array.isArray(opValue) && opValue.length === 2) {
|
|
1505
|
-
const valKey1 = `:val${valueIndex++}`;
|
|
1506
|
-
const valKey2 = `:val${valueIndex++}`;
|
|
1507
|
-
values[valKey1] = opValue[0];
|
|
1508
|
-
values[valKey2] = opValue[1];
|
|
1509
|
-
conditions.push(`${attrName} BETWEEN ${valKey1} AND ${valKey2}`);
|
|
1510
|
-
}
|
|
1511
|
-
break;
|
|
1512
|
-
}
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
|
-
else {
|
|
1516
|
-
// Simple equality
|
|
1517
|
-
const valKey = `:val${valueIndex++}`;
|
|
1518
|
-
values[valKey] = value;
|
|
1519
|
-
conditions.push(`${attrName} = ${valKey}`);
|
|
1520
|
-
}
|
|
1391
|
+
async getTableKey(tableName, item) {
|
|
1392
|
+
var _a;
|
|
1393
|
+
const { DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
1394
|
+
const response = await this.dynamoClient.send(new DescribeTableCommand({
|
|
1395
|
+
TableName: tableName,
|
|
1396
|
+
}));
|
|
1397
|
+
const key = {};
|
|
1398
|
+
const keySchema = ((_a = response.Table) === null || _a === void 0 ? void 0 : _a.KeySchema) || [];
|
|
1399
|
+
for (const keyDef of keySchema) {
|
|
1400
|
+
key[keyDef.AttributeName] = item[keyDef.AttributeName];
|
|
1401
|
+
}
|
|
1402
|
+
return key;
|
|
1403
|
+
}
|
|
1404
|
+
async waitForTableActive(tableName, maxWait = 60000) {
|
|
1405
|
+
var _a;
|
|
1406
|
+
const { DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
|
|
1407
|
+
const startTime = Date.now();
|
|
1408
|
+
while (Date.now() - startTime < maxWait) {
|
|
1409
|
+
const response = await this.dynamoClient.send(new DescribeTableCommand({
|
|
1410
|
+
TableName: tableName,
|
|
1411
|
+
}));
|
|
1412
|
+
if (((_a = response.Table) === null || _a === void 0 ? void 0 : _a.TableStatus) === 'ACTIVE') {
|
|
1413
|
+
return;
|
|
1521
1414
|
}
|
|
1522
|
-
|
|
1415
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
1416
|
+
}
|
|
1417
|
+
throw new Error(`Table ${tableName} did not become active within ${maxWait}ms`);
|
|
1418
|
+
}
|
|
1419
|
+
mapToDynamoType(columnType) {
|
|
1420
|
+
const typeMap = {
|
|
1421
|
+
[enums_1.ColumnType.INTEGER]: 'N',
|
|
1422
|
+
[enums_1.ColumnType.BIGINT]: 'N',
|
|
1423
|
+
[enums_1.ColumnType.FLOAT]: 'N',
|
|
1424
|
+
[enums_1.ColumnType.DOUBLE]: 'N',
|
|
1425
|
+
[enums_1.ColumnType.DECIMAL]: 'N',
|
|
1426
|
+
[enums_1.ColumnType.STRING]: 'S',
|
|
1427
|
+
[enums_1.ColumnType.TEXT]: 'S',
|
|
1428
|
+
[enums_1.ColumnType.BOOLEAN]: 'BOOL',
|
|
1429
|
+
[enums_1.ColumnType.BINARY]: 'B',
|
|
1430
|
+
[enums_1.ColumnType.UUID]: 'S',
|
|
1523
1431
|
};
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1432
|
+
return typeMap[columnType] || 'S';
|
|
1433
|
+
}
|
|
1434
|
+
mapFromDynamoType(dynamoType) {
|
|
1435
|
+
const typeMap = {
|
|
1436
|
+
'N': 'number',
|
|
1437
|
+
'S': 'string',
|
|
1438
|
+
'B': 'binary',
|
|
1439
|
+
'BOOL': 'boolean',
|
|
1440
|
+
'L': 'list',
|
|
1441
|
+
'M': 'map',
|
|
1442
|
+
'SS': 'stringSet',
|
|
1443
|
+
'NS': 'numberSet',
|
|
1444
|
+
'BS': 'binarySet',
|
|
1529
1445
|
};
|
|
1530
|
-
|
|
1531
|
-
buildUpdateExpression(data) {
|
|
1532
|
-
const names = {};
|
|
1533
|
-
const values = {};
|
|
1534
|
-
const updates = [];
|
|
1535
|
-
Object.entries(data).forEach(([key, value], idx) => {
|
|
1536
|
-
names[`#${key}`] = key;
|
|
1537
|
-
values[`:val${idx}`] = value;
|
|
1538
|
-
updates.push(`#${key} = :val${idx}`);
|
|
1539
|
-
});
|
|
1540
|
-
return {
|
|
1541
|
-
updateExpression: `SET ${updates.join(', ')}`,
|
|
1542
|
-
expressionAttributeNames: names,
|
|
1543
|
-
expressionAttributeValues: values,
|
|
1544
|
-
};
|
|
1545
|
-
}
|
|
1546
|
-
extractKeyFromWhere(where) {
|
|
1547
|
-
// Simple implementation - extract key fields from where clause
|
|
1548
|
-
return where || {};
|
|
1446
|
+
return typeMap[dynamoType] || 'unknown';
|
|
1549
1447
|
}
|
|
1550
1448
|
chunkArray(array, size) {
|
|
1551
1449
|
const chunks = [];
|
|
@@ -1554,54 +1452,13 @@ class DynamoDBAdapter extends base_adapter_1.BaseDatabaseAdapter {
|
|
|
1554
1452
|
}
|
|
1555
1453
|
return chunks;
|
|
1556
1454
|
}
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
case schema_types_1.ColumnType.NUMERIC:
|
|
1565
|
-
case schema_types_1.ColumnType.FLOAT:
|
|
1566
|
-
case schema_types_1.ColumnType.DOUBLE:
|
|
1567
|
-
case schema_types_1.ColumnType.REAL:
|
|
1568
|
-
return 'N';
|
|
1569
|
-
case schema_types_1.ColumnType.BLOB:
|
|
1570
|
-
case schema_types_1.ColumnType.BINARY:
|
|
1571
|
-
return 'B';
|
|
1572
|
-
default:
|
|
1573
|
-
return 'S';
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
mapDynamoDBTypeToColumnType(dynamoType) {
|
|
1577
|
-
switch (dynamoType) {
|
|
1578
|
-
case 'N':
|
|
1579
|
-
return schema_types_1.ColumnType.DECIMAL;
|
|
1580
|
-
case 'B':
|
|
1581
|
-
return schema_types_1.ColumnType.BINARY;
|
|
1582
|
-
default:
|
|
1583
|
-
return schema_types_1.ColumnType.STRING;
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
// ==================== Utility Methods ====================
|
|
1587
|
-
escapeIdentifier(identifier) {
|
|
1588
|
-
// DynamoDB doesn't require escaping identifiers
|
|
1589
|
-
return identifier;
|
|
1590
|
-
}
|
|
1591
|
-
escapeValue(value) {
|
|
1592
|
-
if (value === null || value === undefined) {
|
|
1593
|
-
return 'null';
|
|
1594
|
-
}
|
|
1595
|
-
if (typeof value === 'string') {
|
|
1596
|
-
return `"${value.replace(/"/g, '\\"')}"`;
|
|
1597
|
-
}
|
|
1598
|
-
if (typeof value === 'object') {
|
|
1599
|
-
return JSON.stringify(value);
|
|
1600
|
-
}
|
|
1601
|
-
return String(value);
|
|
1602
|
-
}
|
|
1603
|
-
async getDatabaseVersion(connection) {
|
|
1604
|
-
return 'DynamoDB (AWS Managed)';
|
|
1455
|
+
formatBytes(bytes) {
|
|
1456
|
+
if (bytes === 0)
|
|
1457
|
+
return '0 B';
|
|
1458
|
+
const k = 1024;
|
|
1459
|
+
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
1460
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
1461
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
1605
1462
|
}
|
|
1606
1463
|
}
|
|
1607
1464
|
exports.DynamoDBAdapter = DynamoDBAdapter;
|