@ductape/sdk 0.0.4-v5 → 0.0.4-v51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (338) hide show
  1. package/README.md +1 -1
  2. package/dist/api/services/appApi.service.d.ts +48 -2
  3. package/dist/api/services/appApi.service.js +101 -2
  4. package/dist/api/services/appApi.service.js.map +1 -1
  5. package/dist/api/services/pricingApi.service.d.ts +10 -0
  6. package/dist/api/services/pricingApi.service.js +34 -0
  7. package/dist/api/services/pricingApi.service.js.map +1 -0
  8. package/dist/api/services/processorApi.service.d.ts +12 -2
  9. package/dist/api/services/processorApi.service.js +12 -2
  10. package/dist/api/services/processorApi.service.js.map +1 -1
  11. package/dist/api/services/productsApi.service.d.ts +40 -1
  12. package/dist/api/services/productsApi.service.js +105 -1
  13. package/dist/api/services/productsApi.service.js.map +1 -1
  14. package/dist/api/services/userApi.service.js +1 -0
  15. package/dist/api/services/userApi.service.js.map +1 -1
  16. package/dist/api/services/workspaceApi.service.js +1 -0
  17. package/dist/api/services/workspaceApi.service.js.map +1 -1
  18. package/dist/api/services/workspaceSecretsApi.service.d.ts +75 -0
  19. package/dist/api/services/workspaceSecretsApi.service.js +62 -0
  20. package/dist/api/services/workspaceSecretsApi.service.js.map +1 -0
  21. package/dist/api/urls.d.ts +6 -1
  22. package/dist/api/urls.js +12 -2
  23. package/dist/api/urls.js.map +1 -1
  24. package/dist/api/utils/cache.utils.d.ts +1 -1
  25. package/dist/api/utils/cache.utils.js +10 -4
  26. package/dist/api/utils/cache.utils.js.map +1 -1
  27. package/dist/api/utils/strings.utils.d.ts +2 -0
  28. package/dist/api/utils/strings.utils.js +14 -0
  29. package/dist/api/utils/strings.utils.js.map +1 -1
  30. package/dist/apps/services/app.service.d.ts +51 -33
  31. package/dist/apps/services/app.service.js +488 -244
  32. package/dist/apps/services/app.service.js.map +1 -1
  33. package/dist/apps/validators/joi-validators/create.appAction.validator.d.ts +1 -2
  34. package/dist/apps/validators/joi-validators/create.appAction.validator.js +21 -2
  35. package/dist/apps/validators/joi-validators/create.appAction.validator.js.map +1 -1
  36. package/dist/apps/validators/joi-validators/create.appWebhook.validator.d.ts +1 -2
  37. package/dist/apps/validators/joi-validators/create.appWebhook.validator.js +2 -15
  38. package/dist/apps/validators/joi-validators/create.appWebhook.validator.js.map +1 -1
  39. package/dist/apps/validators/joi-validators/update.appAction.validator.js +11 -1
  40. package/dist/apps/validators/joi-validators/update.appAction.validator.js.map +1 -1
  41. package/dist/apps/validators/joi-validators/update.appActionResponse.validator.d.ts +1 -1
  42. package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js +34 -1
  43. package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js.map +1 -1
  44. package/dist/apps/validators/joi-validators/update.appWebhook.validator.d.ts +1 -2
  45. package/dist/apps/validators/joi-validators/update.appWebhook.validator.js +2 -14
  46. package/dist/apps/validators/joi-validators/update.appWebhook.validator.js.map +1 -1
  47. package/dist/clients/pricing.client.d.ts +3 -0
  48. package/dist/clients/pricing.client.js +33 -0
  49. package/dist/clients/pricing.client.js.map +1 -0
  50. package/dist/database/adapters/base.adapter.d.ts +176 -0
  51. package/dist/database/adapters/base.adapter.js +31 -0
  52. package/dist/database/adapters/base.adapter.js.map +1 -0
  53. package/dist/database/adapters/dynamodb.adapter.d.ts +91 -0
  54. package/dist/database/adapters/dynamodb.adapter.js +1608 -0
  55. package/dist/database/adapters/dynamodb.adapter.js.map +1 -0
  56. package/dist/database/adapters/mongodb.adapter.d.ts +71 -0
  57. package/dist/database/adapters/mongodb.adapter.js +1072 -0
  58. package/dist/database/adapters/mongodb.adapter.js.map +1 -0
  59. package/dist/database/adapters/mysql.adapter.d.ts +146 -0
  60. package/dist/database/adapters/mysql.adapter.js +1492 -0
  61. package/dist/database/adapters/mysql.adapter.js.map +1 -0
  62. package/dist/database/adapters/postgresql.adapter.d.ts +147 -0
  63. package/dist/database/adapters/postgresql.adapter.js +1603 -0
  64. package/dist/database/adapters/postgresql.adapter.js.map +1 -0
  65. package/dist/database/database.service.d.ts +232 -0
  66. package/dist/database/database.service.js +802 -0
  67. package/dist/database/database.service.js.map +1 -0
  68. package/dist/database/index.d.ts +18 -0
  69. package/dist/database/index.js +98 -0
  70. package/dist/database/index.js.map +1 -0
  71. package/dist/database/types/aggregation.types.d.ts +261 -0
  72. package/dist/database/types/aggregation.types.js +21 -0
  73. package/dist/database/types/aggregation.types.js.map +1 -0
  74. package/dist/database/types/connection.types.d.ts +132 -0
  75. package/dist/database/types/connection.types.js +6 -0
  76. package/dist/database/types/connection.types.js.map +1 -0
  77. package/dist/database/types/database.types.d.ts +175 -0
  78. package/dist/database/types/database.types.js +75 -0
  79. package/dist/database/types/database.types.js.map +1 -0
  80. package/dist/database/types/index.d.ts +12 -0
  81. package/dist/database/types/index.js +37 -0
  82. package/dist/database/types/index.js.map +1 -0
  83. package/dist/database/types/index.types.d.ts +220 -0
  84. package/dist/database/types/index.types.js +27 -0
  85. package/dist/database/types/index.types.js.map +1 -0
  86. package/dist/database/types/migration.types.d.ts +205 -0
  87. package/dist/database/types/migration.types.js +44 -0
  88. package/dist/database/types/migration.types.js.map +1 -0
  89. package/dist/database/types/query.types.d.ts +305 -0
  90. package/dist/database/types/query.types.js +57 -0
  91. package/dist/database/types/query.types.js.map +1 -0
  92. package/dist/database/types/result.types.d.ts +220 -0
  93. package/dist/database/types/result.types.js +6 -0
  94. package/dist/database/types/result.types.js.map +1 -0
  95. package/dist/database/types/schema.types.d.ts +190 -0
  96. package/dist/database/types/schema.types.js +69 -0
  97. package/dist/database/types/schema.types.js.map +1 -0
  98. package/dist/database/utils/helpers.d.ts +66 -0
  99. package/dist/database/utils/helpers.js +501 -0
  100. package/dist/database/utils/helpers.js.map +1 -0
  101. package/dist/database/utils/migration.utils.d.ts +151 -0
  102. package/dist/database/utils/migration.utils.js +476 -0
  103. package/dist/database/utils/migration.utils.js.map +1 -0
  104. package/dist/database/utils/transaction.d.ts +64 -0
  105. package/dist/database/utils/transaction.js +130 -0
  106. package/dist/database/utils/transaction.js.map +1 -0
  107. package/dist/database/validators/connection.validator.d.ts +20 -0
  108. package/dist/database/validators/connection.validator.js +267 -0
  109. package/dist/database/validators/connection.validator.js.map +1 -0
  110. package/dist/database/validators/query.validator.d.ts +31 -0
  111. package/dist/database/validators/query.validator.js +305 -0
  112. package/dist/database/validators/query.validator.js.map +1 -0
  113. package/dist/database/validators/schema.validator.d.ts +31 -0
  114. package/dist/database/validators/schema.validator.js +334 -0
  115. package/dist/database/validators/schema.validator.js.map +1 -0
  116. package/dist/graph/adapters/arangodb.adapter.d.ts +80 -0
  117. package/dist/graph/adapters/arangodb.adapter.js +1393 -0
  118. package/dist/graph/adapters/arangodb.adapter.js.map +1 -0
  119. package/dist/graph/adapters/base.adapter.d.ts +228 -0
  120. package/dist/graph/adapters/base.adapter.js +38 -0
  121. package/dist/graph/adapters/base.adapter.js.map +1 -0
  122. package/dist/graph/adapters/index.d.ts +10 -0
  123. package/dist/graph/adapters/index.js +23 -0
  124. package/dist/graph/adapters/index.js.map +1 -0
  125. package/dist/graph/adapters/memgraph.adapter.d.ts +85 -0
  126. package/dist/graph/adapters/memgraph.adapter.js +1491 -0
  127. package/dist/graph/adapters/memgraph.adapter.js.map +1 -0
  128. package/dist/graph/adapters/neo4j.adapter.d.ts +88 -0
  129. package/dist/graph/adapters/neo4j.adapter.js +1861 -0
  130. package/dist/graph/adapters/neo4j.adapter.js.map +1 -0
  131. package/dist/graph/adapters/neptune.adapter.d.ts +87 -0
  132. package/dist/graph/adapters/neptune.adapter.js +1430 -0
  133. package/dist/graph/adapters/neptune.adapter.js.map +1 -0
  134. package/dist/graph/graph.service.d.ts +278 -0
  135. package/dist/graph/graph.service.js +687 -0
  136. package/dist/graph/graph.service.js.map +1 -0
  137. package/dist/graph/index.d.ts +11 -0
  138. package/dist/graph/index.js +42 -0
  139. package/dist/graph/index.js.map +1 -0
  140. package/dist/graph/types/connection.types.d.ts +158 -0
  141. package/dist/graph/types/connection.types.js +43 -0
  142. package/dist/graph/types/connection.types.js.map +1 -0
  143. package/dist/graph/types/graph.types.d.ts +144 -0
  144. package/dist/graph/types/graph.types.js +84 -0
  145. package/dist/graph/types/graph.types.js.map +1 -0
  146. package/dist/graph/types/index.d.ts +11 -0
  147. package/dist/graph/types/index.js +35 -0
  148. package/dist/graph/types/index.js.map +1 -0
  149. package/dist/graph/types/node.types.d.ts +193 -0
  150. package/dist/graph/types/node.types.js +49 -0
  151. package/dist/graph/types/node.types.js.map +1 -0
  152. package/dist/graph/types/path.types.d.ts +224 -0
  153. package/dist/graph/types/path.types.js +38 -0
  154. package/dist/graph/types/path.types.js.map +1 -0
  155. package/dist/graph/types/query.types.d.ts +247 -0
  156. package/dist/graph/types/query.types.js +23 -0
  157. package/dist/graph/types/query.types.js.map +1 -0
  158. package/dist/graph/types/relationship.types.d.ts +224 -0
  159. package/dist/graph/types/relationship.types.js +35 -0
  160. package/dist/graph/types/relationship.types.js.map +1 -0
  161. package/dist/graph/types/result.types.d.ts +237 -0
  162. package/dist/graph/types/result.types.js +7 -0
  163. package/dist/graph/types/result.types.js.map +1 -0
  164. package/dist/graph/validators/index.d.ts +81 -0
  165. package/dist/graph/validators/index.js +243 -0
  166. package/dist/graph/validators/index.js.map +1 -0
  167. package/dist/imports/imports.service.d.ts +3 -3
  168. package/dist/imports/imports.service.js +7 -7
  169. package/dist/imports/imports.service.js.map +1 -1
  170. package/dist/imports/imports.types.d.ts +8 -0
  171. package/dist/imports/repos/postmanV21.repo.d.ts +1 -1
  172. package/dist/imports/repos/postmanV21.repo.js +29 -2
  173. package/dist/imports/repos/postmanV21.repo.js.map +1 -1
  174. package/dist/index.d.ts +1244 -150
  175. package/dist/index.js +1309 -209
  176. package/dist/index.js.map +1 -1
  177. package/dist/inputs/inputs.service.js +2 -2
  178. package/dist/inputs/inputs.service.js.map +1 -1
  179. package/dist/inputs/utils/inputs.utils.create.js +1 -1
  180. package/dist/inputs/utils/inputs.utils.create.js.map +1 -1
  181. package/dist/logs/logs.types.d.ts +5 -0
  182. package/dist/logs/logs.types.js +1 -0
  183. package/dist/logs/logs.types.js.map +1 -1
  184. package/dist/parsers/index.d.ts +3 -0
  185. package/dist/parsers/index.js +27 -0
  186. package/dist/parsers/index.js.map +1 -0
  187. package/dist/parsers/pipelines/postman.pipelines.d.ts +15 -0
  188. package/dist/parsers/pipelines/postman.pipelines.js +103 -0
  189. package/dist/parsers/pipelines/postman.pipelines.js.map +1 -0
  190. package/dist/parsers/types/postman.types.d.ts +200 -0
  191. package/dist/parsers/types/postman.types.js +3 -0
  192. package/dist/parsers/types/postman.types.js.map +1 -0
  193. package/dist/parsers/utils/postman.utils.d.ts +12 -0
  194. package/dist/parsers/utils/postman.utils.js +116 -0
  195. package/dist/parsers/utils/postman.utils.js.map +1 -0
  196. package/dist/parsers/validators/postman-auth.validators.d.ts +10 -0
  197. package/dist/parsers/validators/postman-auth.validators.js +127 -0
  198. package/dist/parsers/validators/postman-auth.validators.js.map +1 -0
  199. package/dist/parsers/validators/postman-request.validators.d.ts +13 -0
  200. package/dist/parsers/validators/postman-request.validators.js +139 -0
  201. package/dist/parsers/validators/postman-request.validators.js.map +1 -0
  202. package/dist/parsers/validators/postman-response.validators.d.ts +13 -0
  203. package/dist/parsers/validators/postman-response.validators.js +150 -0
  204. package/dist/parsers/validators/postman-response.validators.js.map +1 -0
  205. package/dist/parsers/validators/postman-variable.validators.d.ts +14 -0
  206. package/dist/parsers/validators/postman-variable.validators.js +163 -0
  207. package/dist/parsers/validators/postman-variable.validators.js.map +1 -0
  208. package/dist/pricing/pricing.repo.d.ts +0 -0
  209. package/dist/pricing/pricing.repo.js +1 -0
  210. package/dist/pricing/pricing.repo.js.map +1 -0
  211. package/dist/pricing/pricing.service.d.ts +24 -0
  212. package/dist/pricing/pricing.service.js +51 -0
  213. package/dist/pricing/pricing.service.js.map +1 -0
  214. package/dist/pricing/pricing.types.d.ts +76 -0
  215. package/dist/pricing/pricing.types.js +21 -0
  216. package/dist/pricing/pricing.types.js.map +1 -0
  217. package/dist/pricing/utils/string.utils.d.ts +1 -0
  218. package/dist/pricing/utils/string.utils.js +9 -0
  219. package/dist/pricing/utils/string.utils.js.map +1 -0
  220. package/dist/processor/repos/sms.repo.d.ts +4 -4
  221. package/dist/processor/repos/sms.repo.js +23 -10
  222. package/dist/processor/repos/sms.repo.js.map +1 -1
  223. package/dist/processor/services/messagebrokers/kafka.service.js +0 -2
  224. package/dist/processor/services/messagebrokers/kafka.service.js.map +1 -1
  225. package/dist/processor/services/messagebrokers/rabbitmq.service.d.ts +9 -1
  226. package/dist/processor/services/messagebrokers/rabbitmq.service.js +40 -11
  227. package/dist/processor/services/messagebrokers/rabbitmq.service.js.map +1 -1
  228. package/dist/processor/services/processor.service.d.ts +38 -10
  229. package/dist/processor/services/processor.service.js +533 -248
  230. package/dist/processor/services/processor.service.js.map +1 -1
  231. package/dist/processor/services/request.service.d.ts +36 -0
  232. package/dist/processor/services/request.service.js +304 -0
  233. package/dist/processor/services/request.service.js.map +1 -0
  234. package/dist/processor/types/request.types.d.ts +14 -0
  235. package/dist/processor/types/request.types.js +3 -0
  236. package/dist/processor/types/request.types.js.map +1 -0
  237. package/dist/processor/utils/processor.utils.d.ts +3 -0
  238. package/dist/processor/utils/processor.utils.js +84 -22
  239. package/dist/processor/utils/processor.utils.js.map +1 -1
  240. package/dist/processor/utils/request.utils.d.ts +20 -0
  241. package/dist/processor/utils/request.utils.js +113 -0
  242. package/dist/processor/utils/request.utils.js.map +1 -0
  243. package/dist/products/services/products.service.d.ts +114 -77
  244. package/dist/products/services/products.service.js +805 -362
  245. package/dist/products/services/products.service.js.map +1 -1
  246. package/dist/products/services/utils/crypt.utils.d.ts +1 -0
  247. package/dist/products/services/utils/crypt.utils.js +17 -0
  248. package/dist/products/services/utils/crypt.utils.js.map +1 -0
  249. package/dist/products/services/utils/functions.utils.d.ts +13 -0
  250. package/dist/products/services/utils/functions.utils.js +289 -0
  251. package/dist/products/services/utils/functions.utils.js.map +1 -0
  252. package/dist/products/services/utils/objects.utils.d.ts +13 -0
  253. package/dist/products/services/utils/objects.utils.js +89 -0
  254. package/dist/products/services/utils/objects.utils.js.map +1 -0
  255. package/dist/products/services/utils/string.utils.d.ts +12 -0
  256. package/dist/products/services/utils/string.utils.js +168 -0
  257. package/dist/products/services/utils/string.utils.js.map +1 -0
  258. package/dist/products/utils/string.utils.d.ts +1 -1
  259. package/dist/products/utils/string.utils.js +14 -2
  260. package/dist/products/utils/string.utils.js.map +1 -1
  261. package/dist/products/validators/index.d.ts +4 -1
  262. package/dist/products/validators/index.js +7 -1
  263. package/dist/products/validators/index.js.map +1 -1
  264. package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.d.ts +15 -4
  265. package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.js +501 -109
  266. package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.js.map +1 -1
  267. package/dist/products/validators/joi-validators/create.productEnv.validator.js +1 -0
  268. package/dist/products/validators/joi-validators/create.productEnv.validator.js.map +1 -1
  269. package/dist/products/validators/joi-validators/create.productGraph.validator.d.ts +3 -0
  270. package/dist/products/validators/joi-validators/create.productGraph.validator.js +82 -0
  271. package/dist/products/validators/joi-validators/create.productGraph.validator.js.map +1 -0
  272. package/dist/products/validators/joi-validators/create.productGraphAction.validator.d.ts +14 -0
  273. package/dist/products/validators/joi-validators/create.productGraphAction.validator.js +696 -0
  274. package/dist/products/validators/joi-validators/create.productGraphAction.validator.js.map +1 -0
  275. package/dist/products/validators/joi-validators/create.productHealthcheck.validator.d.ts +4 -0
  276. package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js +58 -0
  277. package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js.map +1 -0
  278. package/dist/products/validators/joi-validators/create.productMessageBrokerTopic.validator.js +1 -0
  279. package/dist/products/validators/joi-validators/create.productMessageBrokerTopic.validator.js.map +1 -1
  280. package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js +9 -4
  281. package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js.map +1 -1
  282. package/dist/products/validators/joi-validators/create.productNotification.validator.js +5 -2
  283. package/dist/products/validators/joi-validators/create.productNotification.validator.js.map +1 -1
  284. package/dist/products/validators/joi-validators/create.userAuth.validator.js +1 -0
  285. package/dist/products/validators/joi-validators/create.userAuth.validator.js.map +1 -1
  286. package/dist/products/validators/joi-validators/update.dataValue.validator.js +1 -0
  287. package/dist/products/validators/joi-validators/update.dataValue.validator.js.map +1 -1
  288. package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.d.ts +6 -0
  289. package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.js +28 -26
  290. package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.js.map +1 -1
  291. package/dist/products/validators/joi-validators/update.productEnv.validator.js +3 -0
  292. package/dist/products/validators/joi-validators/update.productEnv.validator.js.map +1 -1
  293. package/dist/products/validators/joi-validators/update.productGraph.validator.d.ts +3 -0
  294. package/dist/products/validators/joi-validators/update.productGraph.validator.js +87 -0
  295. package/dist/products/validators/joi-validators/update.productGraph.validator.js.map +1 -0
  296. package/dist/products/validators/joi-validators/update.productGraphAction.validator.d.ts +7 -0
  297. package/dist/products/validators/joi-validators/update.productGraphAction.validator.js +72 -0
  298. package/dist/products/validators/joi-validators/update.productGraphAction.validator.js.map +1 -0
  299. package/dist/products/validators/joi-validators/update.productMessageBrokerTopic.validator.js +1 -0
  300. package/dist/products/validators/joi-validators/update.productMessageBrokerTopic.validator.js.map +1 -1
  301. package/dist/products/validators/joi-validators/update.userAuth.validator.js +1 -0
  302. package/dist/products/validators/joi-validators/update.userAuth.validator.js.map +1 -1
  303. package/dist/test/test.health.d.ts +1 -0
  304. package/dist/test/test.health.js +49 -0
  305. package/dist/test/test.health.js.map +1 -0
  306. package/dist/test/test.import.js +51 -4
  307. package/dist/test/test.import.js.map +1 -1
  308. package/dist/test/test.imports.js +22 -7
  309. package/dist/test/test.imports.js.map +1 -1
  310. package/dist/test/test.notifiers.d.ts +1 -0
  311. package/dist/test/test.notifiers.js +85 -0
  312. package/dist/test/test.notifiers.js.map +1 -0
  313. package/dist/test/test.processor.js +30 -115
  314. package/dist/test/test.processor.js.map +1 -1
  315. package/dist/test/test.products.d.ts +1 -0
  316. package/dist/test/test.products.js +49 -0
  317. package/dist/test/test.products.js.map +1 -0
  318. package/dist/tsconfig.tsbuildinfo +1 -0
  319. package/dist/types/appBuilder.types.d.ts +5 -12
  320. package/dist/types/enums.d.ts +4 -1
  321. package/dist/types/enums.js +3 -0
  322. package/dist/types/enums.js.map +1 -1
  323. package/dist/types/index.types.d.ts +4 -0
  324. package/dist/types/pricing.types.d.ts +4 -0
  325. package/dist/types/pricing.types.js +3 -0
  326. package/dist/types/pricing.types.js.map +1 -0
  327. package/dist/types/processor.types.d.ts +67 -11
  328. package/dist/types/processor.types.js.map +1 -1
  329. package/dist/types/productsBuilder.types.d.ts +132 -14
  330. package/dist/types/productsBuilder.types.js +69 -4
  331. package/dist/types/productsBuilder.types.js.map +1 -1
  332. package/dist/types/request-tracker.interface.d.ts +0 -0
  333. package/dist/types/request-tracker.interface.js +1 -0
  334. package/dist/types/request-tracker.interface.js.map +1 -0
  335. package/dist/utils/constants.d.ts +1 -0
  336. package/dist/utils/constants.js +5 -0
  337. package/dist/utils/constants.js.map +1 -0
  338. package/package.json +17 -3
@@ -0,0 +1,1608 @@
1
+ "use strict";
2
+ /**
3
+ * DynamoDB Database Adapter
4
+ * Implements database operations for Amazon DynamoDB
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.DynamoDBAdapter = void 0;
41
+ const base_adapter_1 = require("./base.adapter");
42
+ const database_types_1 = require("../types/database.types");
43
+ const uuid_1 = require("uuid");
44
+ const schema_types_1 = require("../types/schema.types");
45
+ const migration_types_1 = require("../types/migration.types");
46
+ /**
47
+ * DynamoDB Connection wrapper
48
+ */
49
+ class DynamoDBConnection {
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 {
152
+ constructor() {
153
+ super(...arguments);
154
+ this.type = database_types_1.DatabaseType.DYNAMODB;
155
+ }
156
+ // ==================== Connection Methods ====================
157
+ async connect(config) {
158
+ var _a, _b, _c, _d;
159
+ try {
160
+ // Dynamic import of AWS SDK v3
161
+ const { DynamoDBClient } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
162
+ const { DynamoDBDocumentClient } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
163
+ const clientConfig = {
164
+ region: ((_a = config.options) === null || _a === void 0 ? void 0 : _a.region) || 'us-east-1',
165
+ };
166
+ // Add credentials if provided
167
+ if (((_b = config.options) === null || _b === void 0 ? void 0 : _b.accessKeyId) && ((_c = config.options) === null || _c === void 0 ? void 0 : _c.secretAccessKey)) {
168
+ clientConfig.credentials = {
169
+ accessKeyId: config.options.accessKeyId,
170
+ secretAccessKey: config.options.secretAccessKey,
171
+ sessionToken: config.options.sessionToken,
172
+ };
173
+ }
174
+ // Add endpoint for local development
175
+ if ((_d = config.options) === null || _d === void 0 ? void 0 : _d.endpoint) {
176
+ clientConfig.endpoint = config.options.endpoint;
177
+ }
178
+ const client = new DynamoDBClient(clientConfig);
179
+ const docClient = DynamoDBDocumentClient.from(client);
180
+ return new DynamoDBConnection(`dynamodb-${Date.now()}`, client, docClient);
181
+ }
182
+ catch (error) {
183
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.CONNECTION_ERROR, `Failed to connect to DynamoDB: ${error.message}`, error);
184
+ }
185
+ }
186
+ async disconnect(connection) {
187
+ await connection.disconnect();
188
+ }
189
+ async testConnection(connection) {
190
+ const startTime = Date.now();
191
+ try {
192
+ const { ListTablesCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
193
+ const client = connection.getRawClient();
194
+ await client.send(new ListTablesCommand({ Limit: 1 }));
195
+ return {
196
+ connected: true,
197
+ message: 'DynamoDB connection successful',
198
+ databaseType: 'DynamoDB',
199
+ responseTime: Date.now() - startTime,
200
+ };
201
+ }
202
+ catch (error) {
203
+ return {
204
+ connected: false,
205
+ message: `DynamoDB connection failed: ${error.message}`,
206
+ databaseType: 'DynamoDB',
207
+ responseTime: Date.now() - startTime,
208
+ error: error.message,
209
+ };
210
+ }
211
+ }
212
+ // ==================== Transaction Methods ====================
213
+ async beginTransaction(connection, options) {
214
+ // DynamoDB transactions collect items and execute them atomically on commit
215
+ return new DynamoDBTransaction(connection, options);
216
+ }
217
+ async commitTransaction(_connection, transaction) {
218
+ await transaction.commit();
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.');
231
+ }
232
+ // ==================== Query Methods ====================
233
+ async query(connection, options) {
234
+ const startTime = Date.now();
235
+ try {
236
+ const { ScanCommand, QueryCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
237
+ const docClient = connection.getClient();
238
+ let result;
239
+ // If there's a partition key in where clause, use Query, otherwise use Scan
240
+ const hasPartitionKey = options.where && this.hasPartitionKeyInWhere(options.where);
241
+ if (hasPartitionKey) {
242
+ const params = this.buildQueryParams(options);
243
+ result = await docClient.send(new QueryCommand(params));
244
+ }
245
+ else {
246
+ const params = this.buildScanParams(options);
247
+ result = await docClient.send(new ScanCommand(params));
248
+ }
249
+ const executionTime = Date.now() - startTime;
250
+ return {
251
+ data: (result.Items || []),
252
+ count: result.Count || 0,
253
+ executionTime,
254
+ };
255
+ }
256
+ catch (error) {
257
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB query failed: ${error.message}`, error);
258
+ }
259
+ }
260
+ async insert(connection, options) {
261
+ const startTime = Date.now();
262
+ try {
263
+ const { PutCommand, BatchWriteCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
264
+ const docClient = connection.getClient();
265
+ const dataArray = Array.isArray(options.data) ? options.data : [options.data];
266
+ if (dataArray.length === 1) {
267
+ // Single item insert
268
+ await docClient.send(new PutCommand({
269
+ TableName: options.table,
270
+ Item: dataArray[0],
271
+ }));
272
+ }
273
+ else {
274
+ // Batch insert (max 25 items per batch)
275
+ const batches = this.chunkArray(dataArray, 25);
276
+ for (const batch of batches) {
277
+ await docClient.send(new BatchWriteCommand({
278
+ RequestItems: {
279
+ [options.table]: batch.map((item) => ({
280
+ PutRequest: { Item: item },
281
+ })),
282
+ },
283
+ }));
284
+ }
285
+ }
286
+ const executionTime = Date.now() - startTime;
287
+ return {
288
+ insertedCount: dataArray.length,
289
+ insertedIds: [], // DynamoDB doesn't auto-generate IDs
290
+ data: undefined,
291
+ executionTime,
292
+ success: true,
293
+ };
294
+ }
295
+ catch (error) {
296
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB insert failed: ${error.message}`, error);
297
+ }
298
+ }
299
+ async update(connection, options) {
300
+ const startTime = Date.now();
301
+ try {
302
+ const { UpdateCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
303
+ const docClient = connection.getClient();
304
+ // DynamoDB requires a key to update - extract from where clause
305
+ const key = this.extractKeyFromWhere(options.where);
306
+ // Build update expression
307
+ const { updateExpression, expressionAttributeNames, expressionAttributeValues } = this.buildUpdateExpression(options.data);
308
+ await docClient.send(new UpdateCommand({
309
+ TableName: options.table,
310
+ Key: key,
311
+ UpdateExpression: updateExpression,
312
+ ExpressionAttributeNames: expressionAttributeNames,
313
+ ExpressionAttributeValues: expressionAttributeValues,
314
+ }));
315
+ const executionTime = Date.now() - startTime;
316
+ return {
317
+ updatedCount: 1, // DynamoDB updates one item at a time
318
+ matchedCount: 1,
319
+ data: undefined,
320
+ executionTime,
321
+ success: true,
322
+ };
323
+ }
324
+ catch (error) {
325
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB update failed: ${error.message}`, error);
326
+ }
327
+ }
328
+ async delete(connection, options) {
329
+ const startTime = Date.now();
330
+ try {
331
+ const { DeleteCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
332
+ const docClient = connection.getClient();
333
+ // DynamoDB requires a key to delete - extract from where clause
334
+ const key = this.extractKeyFromWhere(options.where);
335
+ await docClient.send(new DeleteCommand({
336
+ TableName: options.table,
337
+ Key: key,
338
+ }));
339
+ const executionTime = Date.now() - startTime;
340
+ return {
341
+ deletedCount: 1,
342
+ data: undefined,
343
+ executionTime,
344
+ success: true,
345
+ };
346
+ }
347
+ catch (error) {
348
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB delete failed: ${error.message}`, error);
349
+ }
350
+ }
351
+ async upsert(connection, options) {
352
+ const startTime = Date.now();
353
+ try {
354
+ const { PutCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
355
+ const docClient = connection.getClient();
356
+ const data = Array.isArray(options.data) ? options.data[0] : options.data;
357
+ // PutItem automatically does upsert in DynamoDB
358
+ await docClient.send(new PutCommand({
359
+ TableName: options.table,
360
+ Item: data,
361
+ }));
362
+ const executionTime = Date.now() - startTime;
363
+ return {
364
+ insertedCount: 0, // Can't distinguish in DynamoDB
365
+ updatedCount: 0,
366
+ affectedCount: 1,
367
+ data: undefined,
368
+ executionTime,
369
+ success: true,
370
+ };
371
+ }
372
+ catch (error) {
373
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB upsert failed: ${error.message}`, error);
374
+ }
375
+ }
376
+ async executeRaw(connection, options) {
377
+ var _a;
378
+ const startTime = Date.now();
379
+ try {
380
+ const { ExecuteStatementCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
381
+ const client = connection.getRawClient();
382
+ // DynamoDB PartiQL support
383
+ const result = await client.send(new ExecuteStatementCommand({
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,
392
+ };
393
+ }
394
+ catch (error) {
395
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB raw query failed: ${error.message}`, error);
396
+ }
397
+ }
398
+ // ==================== Aggregation Methods ====================
399
+ async count(connection, options) {
400
+ try {
401
+ const { ScanCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
402
+ const docClient = connection.getClient();
403
+ const params = {
404
+ TableName: options.table,
405
+ Select: 'COUNT',
406
+ };
407
+ if (options.where) {
408
+ const { filterExpression, expressionAttributeNames, expressionAttributeValues } = this.buildFilterExpression(options.where);
409
+ params.FilterExpression = filterExpression;
410
+ params.ExpressionAttributeNames = expressionAttributeNames;
411
+ params.ExpressionAttributeValues = expressionAttributeValues;
412
+ }
413
+ const result = await docClient.send(new ScanCommand(params));
414
+ return result.Count || 0;
415
+ }
416
+ catch (error) {
417
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB count failed: ${error.message}`, error);
418
+ }
419
+ }
420
+ async sum(connection, options) {
421
+ // DynamoDB doesn't support aggregations natively - need to scan and calculate
422
+ try {
423
+ const result = await this.query(connection, {
424
+ table: options.table,
425
+ where: options.where,
426
+ env: options.env,
427
+ product: options.product,
428
+ database: options.database,
429
+ });
430
+ return result.data.reduce((sum, item) => sum + (item[options.column] || 0), 0);
431
+ }
432
+ catch (error) {
433
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB sum failed: ${error.message}`, error);
434
+ }
435
+ }
436
+ async avg(connection, options) {
437
+ try {
438
+ const result = await this.query(connection, {
439
+ table: options.table,
440
+ where: options.where,
441
+ env: options.env,
442
+ product: options.product,
443
+ database: options.database,
444
+ });
445
+ const sum = result.data.reduce((total, item) => total + (item[options.column] || 0), 0);
446
+ return result.data.length > 0 ? sum / result.data.length : 0;
447
+ }
448
+ catch (error) {
449
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB avg failed: ${error.message}`, error);
450
+ }
451
+ }
452
+ async min(connection, options) {
453
+ try {
454
+ const result = await this.query(connection, {
455
+ table: options.table,
456
+ where: options.where,
457
+ env: options.env,
458
+ product: options.product,
459
+ database: options.database,
460
+ });
461
+ if (result.data.length === 0)
462
+ return 0;
463
+ return result.data.reduce((min, item) => {
464
+ const value = item[options.column];
465
+ return value < min ? value : min;
466
+ }, result.data[0][options.column]);
467
+ }
468
+ catch (error) {
469
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB min failed: ${error.message}`, error);
470
+ }
471
+ }
472
+ async max(connection, options) {
473
+ try {
474
+ const result = await this.query(connection, {
475
+ table: options.table,
476
+ where: options.where,
477
+ env: options.env,
478
+ product: options.product,
479
+ database: options.database,
480
+ });
481
+ if (result.data.length === 0)
482
+ return 0;
483
+ return result.data.reduce((max, item) => {
484
+ const value = item[options.column];
485
+ return value > max ? value : max;
486
+ }, result.data[0][options.column]);
487
+ }
488
+ catch (error) {
489
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB max failed: ${error.message}`, error);
490
+ }
491
+ }
492
+ async groupBy(connection, options) {
493
+ try {
494
+ // DynamoDB doesn't support GROUP BY - need to scan and group manually
495
+ // WARNING: This scans the entire table - use with caution on large tables
496
+ const result = await this.query(connection, {
497
+ table: options.table,
498
+ where: options.where,
499
+ env: options.env,
500
+ product: options.product,
501
+ database: options.database,
502
+ });
503
+ const groups = new Map();
504
+ result.data.forEach((item) => {
505
+ // Create group key
506
+ const groupKey = options.groupBy.map((col) => item[col]).join('|');
507
+ if (!groups.has(groupKey)) {
508
+ const groupData = {};
509
+ options.groupBy.forEach((col) => {
510
+ groupData[col] = item[col];
511
+ });
512
+ groups.set(groupKey, groupData);
513
+ }
514
+ // Accumulate aggregations
515
+ if (options.aggregate) {
516
+ const groupData = groups.get(groupKey);
517
+ Object.entries(options.aggregate).forEach(([alias, agg]) => {
518
+ const aggObj = agg;
519
+ // Parse operation and column
520
+ let operation;
521
+ let column;
522
+ if (aggObj.$COUNT !== undefined) {
523
+ operation = 'count';
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
+ }
590
+ });
591
+ });
592
+ return results;
593
+ }
594
+ catch (error) {
595
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB groupBy failed: ${error.message}`, error);
596
+ }
597
+ }
598
+ async aggregate(connection, options) {
599
+ try {
600
+ // WARNING: DynamoDB does NOT support native aggregations
601
+ // This implementation scans the entire table - use with caution on large tables
602
+ const result = await this.query(connection, {
603
+ table: options.table,
604
+ where: options.where,
605
+ env: options.env,
606
+ product: options.product,
607
+ database: options.database,
608
+ });
609
+ const aggregateResult = {};
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;
663
+ }
664
+ catch (error) {
665
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `DynamoDB aggregate failed: ${error.message}`, error);
666
+ }
667
+ }
668
+ // ==================== Schema Methods ====================
669
+ async createTable(connection, schema, options) {
670
+ const startTime = Date.now();
671
+ try {
672
+ const { CreateTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
673
+ const client = connection.getRawClient();
674
+ // Extract key schema from columns
675
+ const keySchema = [];
676
+ const attributeDefinitions = [];
677
+ schema.columns.forEach((col) => {
678
+ if (col.primaryKey) {
679
+ keySchema.push({
680
+ AttributeName: col.name,
681
+ KeyType: 'HASH', // Partition key
682
+ });
683
+ attributeDefinitions.push({
684
+ AttributeName: col.name,
685
+ AttributeType: this.mapColumnTypeToDynamoDB(col.type),
686
+ });
687
+ }
688
+ });
689
+ // If no sort key specified, DynamoDB only needs partition key
690
+ await client.send(new CreateTableCommand({
691
+ TableName: schema.name,
692
+ KeySchema: keySchema,
693
+ AttributeDefinitions: attributeDefinitions,
694
+ BillingMode: 'PAY_PER_REQUEST', // On-demand billing
695
+ }));
696
+ const executionTime = Date.now() - startTime;
697
+ return {
698
+ success: true,
699
+ operation: 'create',
700
+ table: schema.name,
701
+ executionTime,
702
+ };
703
+ }
704
+ catch (error) {
705
+ return {
706
+ success: false,
707
+ operation: 'create',
708
+ table: schema.name,
709
+ error: error.message,
710
+ executionTime: Date.now() - startTime,
711
+ };
712
+ }
713
+ }
714
+ async dropTable(connection, tableName) {
715
+ const startTime = Date.now();
716
+ try {
717
+ const { DeleteTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
718
+ const client = connection.getRawClient();
719
+ await client.send(new DeleteTableCommand({
720
+ TableName: tableName,
721
+ }));
722
+ return {
723
+ success: true,
724
+ operation: 'drop',
725
+ table: tableName,
726
+ executionTime: Date.now() - startTime,
727
+ };
728
+ }
729
+ catch (error) {
730
+ return {
731
+ success: false,
732
+ operation: 'drop',
733
+ table: tableName,
734
+ error: error.message,
735
+ executionTime: Date.now() - startTime,
736
+ };
737
+ }
738
+ }
739
+ async alterTable(connection, tableName, alterations, options) {
740
+ // DynamoDB doesn't support schema alterations in the traditional sense
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) {
745
+ try {
746
+ const { DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
747
+ const client = connection.getRawClient();
748
+ const result = await client.send(new DescribeTableCommand({
749
+ TableName: tableName,
750
+ }));
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
+ }
766
+ catch (error) {
767
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.SCHEMA_ERROR, `Failed to get DynamoDB table schema: ${error.message}`, error);
768
+ }
769
+ }
770
+ async listTables(connection) {
771
+ try {
772
+ const { ListTablesCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
773
+ const client = connection.getRawClient();
774
+ const result = await client.send(new ListTablesCommand({}));
775
+ return result.TableNames || [];
776
+ }
777
+ catch (error) {
778
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.SCHEMA_ERROR, `Failed to list DynamoDB tables: ${error.message}`, error);
779
+ }
780
+ }
781
+ async tableExists(connection, tableName) {
782
+ try {
783
+ const { DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
784
+ const client = connection.getRawClient();
785
+ await client.send(new DescribeTableCommand({
786
+ TableName: tableName,
787
+ }));
788
+ return true;
789
+ }
790
+ catch (error) {
791
+ if (error.name === 'ResourceNotFoundException') {
792
+ return false;
793
+ }
794
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.SCHEMA_ERROR, `Failed to check DynamoDB table existence: ${error.message}`, error);
795
+ }
796
+ }
797
+ // ==================== Index Methods ====================
798
+ async createIndex(connection, options) {
799
+ const startTime = Date.now();
800
+ try {
801
+ const { UpdateTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
802
+ const client = connection.getRawClient();
803
+ // Build GSI definition
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
+ ],
826
+ }));
827
+ return {
828
+ success: true,
829
+ operation: 'create',
830
+ indexName: options.index.name,
831
+ table: options.table,
832
+ executionTime: Date.now() - startTime,
833
+ };
834
+ }
835
+ catch (error) {
836
+ return {
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
+ };
844
+ }
845
+ }
846
+ async dropIndex(connection, options) {
847
+ const startTime = Date.now();
848
+ try {
849
+ const { UpdateTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
850
+ const client = connection.getRawClient();
851
+ await client.send(new UpdateTableCommand({
852
+ TableName: options.table,
853
+ GlobalSecondaryIndexUpdates: [
854
+ {
855
+ Delete: {
856
+ IndexName: options.indexName,
857
+ },
858
+ },
859
+ ],
860
+ }));
861
+ return {
862
+ success: true,
863
+ operation: 'drop',
864
+ indexName: options.indexName,
865
+ table: options.table,
866
+ executionTime: Date.now() - startTime,
867
+ };
868
+ }
869
+ catch (error) {
870
+ return {
871
+ success: false,
872
+ operation: 'drop',
873
+ indexName: options.indexName,
874
+ table: options.table,
875
+ error: error.message,
876
+ executionTime: Date.now() - startTime,
877
+ };
878
+ }
879
+ }
880
+ async listIndexes(connection, options) {
881
+ var _a, _b;
882
+ try {
883
+ const { DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
884
+ const client = connection.getRawClient();
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;
924
+ }
925
+ catch (error) {
926
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.INDEX_ERROR, `Failed to list DynamoDB indexes: ${error.message}`, error);
927
+ }
928
+ }
929
+ async getIndexStatistics(connection, tableName, indexName) {
930
+ var _a;
931
+ try {
932
+ const { DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
933
+ const client = connection.getRawClient();
934
+ const result = await client.send(new DescribeTableCommand({
935
+ TableName: tableName,
936
+ }));
937
+ const statistics = [];
938
+ if ((_a = result.Table) === null || _a === void 0 ? void 0 : _a.GlobalSecondaryIndexes) {
939
+ result.Table.GlobalSecondaryIndexes.forEach((gsi) => {
940
+ if (!indexName || gsi.IndexName === indexName) {
941
+ statistics.push({
942
+ indexName: gsi.IndexName,
943
+ table: tableName,
944
+ size: gsi.IndexSizeBytes || 0,
945
+ tuplesRead: gsi.ItemCount || 0,
946
+ });
947
+ }
948
+ });
949
+ }
950
+ return statistics;
951
+ }
952
+ catch (error) {
953
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.INDEX_ERROR, `Failed to get DynamoDB index statistics: ${error.message}`, error);
954
+ }
955
+ }
956
+ // ==================== Migration Methods ====================
957
+ /**
958
+ * Execute a migration operation
959
+ * Note: DynamoDB is schema-less, so column operations are skipped
960
+ */
961
+ async executeMigrationOperation(connection, operation) {
962
+ var _a, _b, _c, _d;
963
+ const { CreateTableCommand, DeleteTableCommand, UpdateTableCommand, ExecuteStatementCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
964
+ const client = connection.getRawClient();
965
+ switch (operation.type) {
966
+ case 'create_table':
967
+ if ((_a = operation.params) === null || _a === void 0 ? void 0 : _a.schema) {
968
+ const schema = operation.params.schema;
969
+ const keySchema = [];
970
+ const attributeDefinitions = [];
971
+ // Extract partition and sort keys from schema
972
+ schema.columns.forEach((col) => {
973
+ if (col.primaryKey) {
974
+ keySchema.push({
975
+ AttributeName: col.name,
976
+ KeyType: 'HASH',
977
+ });
978
+ attributeDefinitions.push({
979
+ AttributeName: col.name,
980
+ AttributeType: this.mapColumnTypeToDynamoDB(col.type),
981
+ });
982
+ }
983
+ });
984
+ await client.send(new CreateTableCommand({
985
+ TableName: schema.name,
986
+ KeySchema: keySchema,
987
+ AttributeDefinitions: attributeDefinitions,
988
+ BillingMode: 'PAY_PER_REQUEST',
989
+ }));
990
+ return { executed: true, command: `CreateTable: ${schema.name}` };
991
+ }
992
+ return { executed: false };
993
+ case 'drop_table':
994
+ if (operation.table) {
995
+ await client.send(new DeleteTableCommand({
996
+ TableName: operation.table,
997
+ }));
998
+ return { executed: true, command: `DropTable: ${operation.table}` };
999
+ }
1000
+ return { executed: false };
1001
+ case 'add_index':
1002
+ if (operation.table && ((_b = operation.params) === null || _b === void 0 ? void 0 : _b.indexName) && ((_c = operation.params) === null || _c === void 0 ? void 0 : _c.columns)) {
1003
+ const keySchema = operation.params.columns.map((col, idx) => ({
1004
+ AttributeName: col,
1005
+ KeyType: idx === 0 ? 'HASH' : 'RANGE',
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 };
1066
+ }
1067
+ }
1068
+ async runMigration(connection, migration, options) {
1069
+ const startTime = Date.now();
1070
+ const statements = [];
1071
+ try {
1072
+ // DynamoDB doesn't support transactions for schema changes
1073
+ // Execute operations sequentially
1074
+ for (const operation of migration.up) {
1075
+ const result = await this.executeMigrationOperation(connection, operation);
1076
+ if (result.command) {
1077
+ statements.push(result.command);
1078
+ }
1079
+ }
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
+ }
1102
+ }
1103
+ async rollbackMigration(connection, migration, options) {
1104
+ const startTime = Date.now();
1105
+ const statements = [];
1106
+ try {
1107
+ // Execute rollback operations
1108
+ for (const operation of migration.down) {
1109
+ const result = await this.executeMigrationOperation(connection, operation);
1110
+ if (result.command) {
1111
+ statements.push(result.command);
1112
+ }
1113
+ }
1114
+ // Remove migration from history table
1115
+ await this.removeMigration(connection, migration.tag);
1116
+ return {
1117
+ tag: migration.tag,
1118
+ status: migration_types_1.MigrationStatus.ROLLED_BACK,
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
+ };
1135
+ }
1136
+ }
1137
+ async getMigrationHistory(connection, options) {
1138
+ try {
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
+ }));
1156
+ }
1157
+ catch (error) {
1158
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.MIGRATION_ERROR, `Failed to get DynamoDB migration history: ${error.message}`, error);
1159
+ }
1160
+ }
1161
+ /**
1162
+ * Ensure migration tracking table exists
1163
+ */
1164
+ async ensureMigrationTable(connection) {
1165
+ try {
1166
+ const { CreateTableCommand, DescribeTableCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-dynamodb')));
1167
+ const client = connection.getRawClient();
1168
+ // Check if table exists
1169
+ try {
1170
+ await client.send(new DescribeTableCommand({
1171
+ TableName: '_ductape_migrations',
1172
+ }));
1173
+ return; // Table exists
1174
+ }
1175
+ catch (error) {
1176
+ if (error.name !== 'ResourceNotFoundException') {
1177
+ throw error;
1178
+ }
1179
+ }
1180
+ // Create migration table
1181
+ await client.send(new CreateTableCommand({
1182
+ TableName: '_ductape_migrations',
1183
+ KeySchema: [
1184
+ {
1185
+ AttributeName: 'tag',
1186
+ KeyType: 'HASH',
1187
+ },
1188
+ ],
1189
+ AttributeDefinitions: [
1190
+ {
1191
+ AttributeName: 'tag',
1192
+ AttributeType: 'S',
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(),
1218
+ },
1219
+ }));
1220
+ }
1221
+ catch (error) {
1222
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.MIGRATION_ERROR, `Failed to record migration: ${error.message}`, error);
1223
+ }
1224
+ }
1225
+ /**
1226
+ * Remove migration from history
1227
+ */
1228
+ async removeMigration(connection, tag) {
1229
+ try {
1230
+ const { DeleteCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/lib-dynamodb')));
1231
+ const docClient = connection.getClient();
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);
1239
+ }
1240
+ }
1241
+ // ==================== Helper Methods ====================
1242
+ hasPartitionKeyInWhere(where) {
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;
1255
+ }
1256
+ if (options.limit) {
1257
+ params.Limit = options.limit;
1258
+ }
1259
+ return params;
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;
1275
+ }
1276
+ /**
1277
+ * Build DynamoDB key condition expression (for Query operations)
1278
+ * Supports both simplified syntax (GT, LT, etc.) and legacy $ prefix operators
1279
+ */
1280
+ buildKeyConditionExpression(where) {
1281
+ const names = {};
1282
+ const values = {};
1283
+ let valueIndex = 0;
1284
+ const buildCondition = (condition) => {
1285
+ if (typeof condition !== 'object' || condition === null) {
1286
+ const valKey = `:val${valueIndex++}`;
1287
+ values[valKey] = condition;
1288
+ return valKey;
1289
+ }
1290
+ const conditions = [];
1291
+ for (const [key, value] of Object.entries(condition)) {
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
+ };
1351
+ }
1352
+ /**
1353
+ * Build DynamoDB filter expression (for Scan and Query operations)
1354
+ * Supports both simplified syntax (GT, LT, AND, OR, etc.) and legacy $ prefix operators
1355
+ */
1356
+ buildFilterExpression(where) {
1357
+ const names = {};
1358
+ const values = {};
1359
+ let valueIndex = 0;
1360
+ const buildCondition = (condition) => {
1361
+ if (typeof condition !== 'object' || condition === null) {
1362
+ const valKey = `:val${valueIndex++}`;
1363
+ values[valKey] = condition;
1364
+ return valKey;
1365
+ }
1366
+ // Handle logical operators (supports $AND, AND, and legacy $and)
1367
+ if (condition.$AND || condition.AND || condition.$and) {
1368
+ const andConditions = condition.$AND || condition.AND || condition.$and;
1369
+ if (typeof andConditions === 'object' && !Array.isArray(andConditions)) {
1370
+ // New syntax: { $AND: { col1: val1, col2: val2 } }
1371
+ return buildCondition(andConditions);
1372
+ }
1373
+ else {
1374
+ // Array syntax: { $AND: [cond1, cond2] }
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
+ }
1521
+ }
1522
+ return conditions.join(' AND ');
1523
+ };
1524
+ const expression = buildCondition(where);
1525
+ return {
1526
+ filterExpression: expression,
1527
+ expressionAttributeNames: names,
1528
+ expressionAttributeValues: values,
1529
+ };
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 || {};
1549
+ }
1550
+ chunkArray(array, size) {
1551
+ const chunks = [];
1552
+ for (let i = 0; i < array.length; i += size) {
1553
+ chunks.push(array.slice(i, i + size));
1554
+ }
1555
+ return chunks;
1556
+ }
1557
+ mapColumnTypeToDynamoDB(type) {
1558
+ // DynamoDB only supports S (String), N (Number), and B (Binary) for keys
1559
+ switch (type) {
1560
+ case schema_types_1.ColumnType.INTEGER:
1561
+ case schema_types_1.ColumnType.BIGINT:
1562
+ case schema_types_1.ColumnType.SMALLINT:
1563
+ case schema_types_1.ColumnType.DECIMAL:
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)';
1605
+ }
1606
+ }
1607
+ exports.DynamoDBAdapter = DynamoDBAdapter;
1608
+ //# sourceMappingURL=dynamodb.adapter.js.map