@aws/nx-plugin 1.0.0-rc.4 → 1.0.0-rc.41

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 (1138) hide show
  1. package/LICENSE-THIRD-PARTY +5449 -4980
  2. package/README.md +7 -7
  3. package/executors.json +9 -0
  4. package/generators.json +101 -2
  5. package/package.json +35 -17
  6. package/src/agentcore-gateway/attach-upstream.d.ts +33 -0
  7. package/src/agentcore-gateway/attach-upstream.js +38 -0
  8. package/src/agentcore-gateway/attach-upstream.js.map +1 -0
  9. package/src/agentcore-gateway/files/cedar/policies/README.md +52 -0
  10. package/src/agentcore-gateway/files/cedar/policies/permit-all.cedar +11 -0
  11. package/src/agentcore-gateway/files/project/local-dev.ts.template +134 -0
  12. package/src/agentcore-gateway/gateway-connection/generator.d.ts +21 -0
  13. package/src/agentcore-gateway/gateway-connection/generator.js +101 -0
  14. package/src/agentcore-gateway/gateway-connection/generator.js.map +1 -0
  15. package/src/agentcore-gateway/gateway-connection/schema.d.js +6 -0
  16. package/src/agentcore-gateway/gateway-connection/schema.d.js.map +1 -0
  17. package/src/agentcore-gateway/gateway-connection/schema.d.ts +13 -0
  18. package/src/agentcore-gateway/gateway-connection/schema.json +31 -0
  19. package/src/agentcore-gateway/generator.d.ts +25 -0
  20. package/src/agentcore-gateway/generator.js +149 -0
  21. package/src/agentcore-gateway/generator.js.map +1 -0
  22. package/src/agentcore-gateway/mcp-connection/generator.d.ts +19 -0
  23. package/src/agentcore-gateway/mcp-connection/generator.js +59 -0
  24. package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -0
  25. package/src/agentcore-gateway/mcp-connection/schema.d.js +6 -0
  26. package/src/agentcore-gateway/mcp-connection/schema.d.js.map +1 -0
  27. package/src/agentcore-gateway/mcp-connection/schema.d.ts +13 -0
  28. package/src/agentcore-gateway/mcp-connection/schema.json +31 -0
  29. package/src/agentcore-gateway/schema.d.js +6 -0
  30. package/src/agentcore-gateway/schema.d.js.map +1 -0
  31. package/src/agentcore-gateway/schema.d.ts +17 -0
  32. package/src/agentcore-gateway/schema.json +70 -0
  33. package/src/bin/aws-nx-mcp.js +14 -0
  34. package/src/bin/aws-nx-mcp.js.map +1 -0
  35. package/src/connection/{agent-serve-local.d.ts → agent-local-dev.d.ts} +7 -7
  36. package/src/connection/agent-local-dev.js +42 -0
  37. package/src/connection/agent-local-dev.js.map +1 -0
  38. package/src/connection/agent-runtime-config.d.ts +1 -1
  39. package/src/connection/agent-runtime-config.js +9 -14
  40. package/src/connection/agent-runtime-config.js.map +1 -1
  41. package/src/connection/generator.d.ts +7 -14
  42. package/src/connection/generator.js +167 -194
  43. package/src/connection/generator.js.map +1 -1
  44. package/src/connection/local-dev.d.ts +15 -0
  45. package/src/connection/local-dev.js +37 -0
  46. package/src/connection/local-dev.js.map +1 -0
  47. package/src/connection/schema.d.js +6 -0
  48. package/src/connection/schema.d.js.map +1 -0
  49. package/src/connection/schema.d.ts +1 -0
  50. package/src/connection/schema.json +5 -0
  51. package/src/connection/supported-connections.d.ts +107 -0
  52. package/src/connection/supported-connections.js +151 -0
  53. package/src/connection/supported-connections.js.map +1 -0
  54. package/src/index.js +2 -5
  55. package/src/index.js.map +1 -1
  56. package/src/infra/app/__snapshots__/generator.spec.ts.snap +97 -85
  57. package/src/infra/app/files/app/src/main.ts.template +1 -1
  58. package/src/infra/app/files/app/src/stages/application-stage.ts.template +1 -1
  59. package/src/infra/app/generator.d.ts +3 -3
  60. package/src/infra/app/generator.js +142 -122
  61. package/src/infra/app/generator.js.map +1 -1
  62. package/src/infra/app/schema.d.js +6 -0
  63. package/src/infra/app/schema.d.js.map +1 -0
  64. package/src/infra/app/schema.d.ts +1 -1
  65. package/src/infra/app/schema.json +5 -0
  66. package/src/init/generator.d.ts +18 -0
  67. package/src/init/generator.js +35 -0
  68. package/src/init/generator.js.map +1 -0
  69. package/src/init/schema.d.js +6 -0
  70. package/src/init/schema.d.js.map +1 -0
  71. package/src/init/schema.d.ts +16 -0
  72. package/src/init/schema.json +35 -0
  73. package/src/license/__snapshots__/config.spec.ts.snap +23 -0
  74. package/src/license/config-types.d.ts +18 -1
  75. package/src/license/config-types.js +8 -2
  76. package/src/license/config-types.js.map +1 -1
  77. package/src/license/config.d.ts +65 -7
  78. package/src/license/config.js +442 -109
  79. package/src/license/config.js.map +1 -1
  80. package/src/license/dependency-check/check.d.ts +16 -0
  81. package/src/license/dependency-check/check.js +116 -0
  82. package/src/license/dependency-check/check.js.map +1 -0
  83. package/src/license/dependency-check/collectors/collector.d.ts +21 -0
  84. package/src/license/dependency-check/collectors/collector.js +46 -0
  85. package/src/license/dependency-check/collectors/collector.js.map +1 -0
  86. package/src/license/dependency-check/collectors/npm-collector.d.ts +10 -0
  87. package/src/license/dependency-check/collectors/npm-collector.js +68 -0
  88. package/src/license/dependency-check/collectors/npm-collector.js.map +1 -0
  89. package/src/license/dependency-check/collectors/python-collector.d.ts +23 -0
  90. package/src/license/dependency-check/collectors/python-collector.js +114 -0
  91. package/src/license/dependency-check/collectors/python-collector.js.map +1 -0
  92. package/src/license/dependency-check/evaluator.d.ts +9 -0
  93. package/src/license/dependency-check/evaluator.js +94 -0
  94. package/src/license/dependency-check/evaluator.js.map +1 -0
  95. package/src/license/dependency-check/executor-schema.json +6 -0
  96. package/src/license/dependency-check/executor.d.ts +9 -0
  97. package/src/license/dependency-check/executor.js +51 -0
  98. package/src/license/dependency-check/executor.js.map +1 -0
  99. package/src/license/dependency-check/pre-approved.d.ts +6 -0
  100. package/src/license/dependency-check/pre-approved.js +1893 -0
  101. package/src/license/dependency-check/pre-approved.js.map +1 -0
  102. package/src/license/dependency-check/types.d.ts +45 -0
  103. package/src/license/dependency-check/types.js +6 -0
  104. package/src/license/dependency-check/types.js.map +1 -0
  105. package/src/license/generator.d.ts +3 -3
  106. package/src/license/generator.js +126 -30
  107. package/src/license/generator.js.map +1 -1
  108. package/src/license/index.d.ts +8 -0
  109. package/src/license/index.js +7 -0
  110. package/src/license/index.js.map +1 -0
  111. package/src/license/known-exceptions.d.ts +7 -0
  112. package/src/license/known-exceptions.js +39 -0
  113. package/src/license/known-exceptions.js.map +1 -0
  114. package/src/license/schema.d.js +6 -0
  115. package/src/license/schema.d.js.map +1 -0
  116. package/src/license/schema.d.ts +7 -0
  117. package/src/license/schema.json +11 -0
  118. package/src/license/sync/generator.d.ts +2 -2
  119. package/src/license/sync/generator.js +100 -125
  120. package/src/license/sync/generator.js.map +1 -1
  121. package/src/license/sync/project-file-sync.d.ts +3 -3
  122. package/src/license/sync/project-file-sync.js +28 -35
  123. package/src/license/sync/project-file-sync.js.map +1 -1
  124. package/src/mcp-server/generator-info.d.ts +5 -1
  125. package/src/mcp-server/generator-info.js +149 -165
  126. package/src/mcp-server/generator-info.js.map +1 -1
  127. package/src/mcp-server/guide-pipeline.d.ts +1 -1
  128. package/src/mcp-server/guide-pipeline.js +199 -206
  129. package/src/mcp-server/guide-pipeline.js.map +1 -1
  130. package/src/mcp-server/guide-render.js +10 -25
  131. package/src/mcp-server/guide-render.js.map +1 -1
  132. package/src/mcp-server/index.js +6 -10
  133. package/src/mcp-server/index.js.map +1 -1
  134. package/src/mcp-server/mdx-ast.js +42 -56
  135. package/src/mcp-server/mdx-ast.js.map +1 -1
  136. package/src/mcp-server/option-filter.js +33 -47
  137. package/src/mcp-server/option-filter.js.map +1 -1
  138. package/src/mcp-server/schema-registry.d.ts +9 -3
  139. package/src/mcp-server/schema-registry.js +41 -38
  140. package/src/mcp-server/schema-registry.js.map +1 -1
  141. package/src/mcp-server/schema.js +9 -7
  142. package/src/mcp-server/schema.js.map +1 -1
  143. package/src/mcp-server/server.js +22 -24
  144. package/src/mcp-server/server.js.map +1 -1
  145. package/src/mcp-server/tools/add-to-existing-project.d.ts +12 -0
  146. package/src/mcp-server/tools/add-to-existing-project.js +36 -0
  147. package/src/mcp-server/tools/add-to-existing-project.js.map +1 -0
  148. package/src/mcp-server/tools/create-workspace-command.d.ts +1 -1
  149. package/src/mcp-server/tools/create-workspace-command.js +23 -24
  150. package/src/mcp-server/tools/create-workspace-command.js.map +1 -1
  151. package/src/mcp-server/tools/general-guidance.d.ts +3 -3
  152. package/src/mcp-server/tools/general-guidance.js +47 -25
  153. package/src/mcp-server/tools/general-guidance.js.map +1 -1
  154. package/src/mcp-server/tools/generator-guide.d.ts +2 -2
  155. package/src/mcp-server/tools/generator-guide.js +29 -37
  156. package/src/mcp-server/tools/generator-guide.js.map +1 -1
  157. package/src/mcp-server/tools/list-generators.d.ts +2 -2
  158. package/src/mcp-server/tools/list-generators.js +19 -25
  159. package/src/mcp-server/tools/list-generators.js.map +1 -1
  160. package/src/open-api/ts-client/__snapshots__/generator.additional-properties.spec.ts.snap +147 -33
  161. package/src/open-api/ts-client/__snapshots__/generator.arrays.spec.ts.snap +308 -75
  162. package/src/open-api/ts-client/__snapshots__/generator.complex-types.spec.ts.snap +298 -74
  163. package/src/open-api/ts-client/__snapshots__/generator.composite-types.spec.ts.snap +748 -103
  164. package/src/open-api/ts-client/__snapshots__/generator.content-type.spec.ts.snap +230 -37
  165. package/src/open-api/ts-client/__snapshots__/generator.duplicate-types.spec.ts.snap +249 -52
  166. package/src/open-api/ts-client/__snapshots__/generator.edge-cases.spec.ts.snap +5535 -0
  167. package/src/open-api/ts-client/__snapshots__/generator.fast-api-gaps.spec.ts.snap +736 -0
  168. package/src/open-api/ts-client/__snapshots__/generator.fast-api.spec.ts.snap +305 -71
  169. package/src/open-api/ts-client/__snapshots__/generator.multipart.spec.ts.snap +298 -0
  170. package/src/open-api/ts-client/__snapshots__/generator.primitive-types.spec.ts.snap +353 -82
  171. package/src/open-api/ts-client/__snapshots__/generator.request.spec.ts.snap +176 -55
  172. package/src/open-api/ts-client/__snapshots__/generator.reserved-keywords.spec.ts.snap +101 -25
  173. package/src/open-api/ts-client/__snapshots__/generator.response.spec.ts.snap +147 -33
  174. package/src/open-api/ts-client/__snapshots__/generator.spec-compliance.spec.ts.snap +1883 -0
  175. package/src/open-api/ts-client/__snapshots__/generator.streaming.spec.ts.snap +392 -88
  176. package/src/open-api/ts-client/__snapshots__/generator.tags.spec.ts.snap +200 -48
  177. package/src/open-api/ts-client/files/client.gen.ts.template +358 -24
  178. package/src/open-api/ts-client/files/types.gen.ts.template +6 -4
  179. package/src/open-api/ts-client/generator.d.ts +3 -3
  180. package/src/open-api/ts-client/generator.js +41 -26
  181. package/src/open-api/ts-client/generator.js.map +1 -1
  182. package/src/open-api/ts-client/schema.d.js +6 -0
  183. package/src/open-api/ts-client/schema.d.js.map +1 -0
  184. package/src/open-api/ts-hooks/files/options-proxy.gen.ts.template +7 -2
  185. package/src/open-api/ts-hooks/generator.d.ts +3 -3
  186. package/src/open-api/ts-hooks/generator.js +17 -21
  187. package/src/open-api/ts-hooks/generator.js.map +1 -1
  188. package/src/open-api/ts-hooks/generator.spec.tsx +84 -14
  189. package/src/open-api/ts-hooks/schema.d.js +6 -0
  190. package/src/open-api/ts-hooks/schema.d.js.map +1 -0
  191. package/src/open-api/ts-metadata/generator.d.ts +3 -3
  192. package/src/open-api/ts-metadata/generator.js +12 -20
  193. package/src/open-api/ts-metadata/generator.js.map +1 -1
  194. package/src/open-api/ts-metadata/schema.d.js +6 -0
  195. package/src/open-api/ts-metadata/schema.d.js.map +1 -0
  196. package/src/open-api/utils/codegen-data/languages.d.ts +3 -5
  197. package/src/open-api/utils/codegen-data/languages.js +59 -66
  198. package/src/open-api/utils/codegen-data/languages.js.map +1 -1
  199. package/src/open-api/utils/codegen-data/types.d.ts +255 -10
  200. package/src/open-api/utils/codegen-data/types.js +54 -30
  201. package/src/open-api/utils/codegen-data/types.js.map +1 -1
  202. package/src/open-api/utils/codegen-data.d.ts +8 -4
  203. package/src/open-api/utils/codegen-data.js +494 -674
  204. package/src/open-api/utils/codegen-data.js.map +1 -1
  205. package/src/open-api/utils/normalise.d.ts +5 -1
  206. package/src/open-api/utils/normalise.js +437 -246
  207. package/src/open-api/utils/normalise.js.map +1 -1
  208. package/src/open-api/utils/parse.d.ts +2 -2
  209. package/src/open-api/utils/parse.js +11 -13
  210. package/src/open-api/utils/parse.js.map +1 -1
  211. package/src/open-api/utils/parser.d.ts +55 -0
  212. package/src/open-api/utils/parser.js +787 -0
  213. package/src/open-api/utils/parser.js.map +1 -0
  214. package/src/open-api/utils/refs.d.ts +1 -1
  215. package/src/open-api/utils/refs.js +12 -22
  216. package/src/open-api/utils/refs.js.map +1 -1
  217. package/src/open-api/utils/types.d.ts +18 -0
  218. package/src/open-api/utils/types.js +5 -2
  219. package/src/open-api/utils/types.js.map +1 -1
  220. package/src/preset/__snapshots__/generator.spec.ts.snap +109 -28
  221. package/src/preset/generator.d.ts +4 -4
  222. package/src/preset/generator.js +64 -147
  223. package/src/preset/generator.js.map +1 -1
  224. package/src/preset/schema.d.js +6 -0
  225. package/src/preset/schema.d.js.map +1 -0
  226. package/src/preset/schema.d.ts +5 -2
  227. package/src/preset/schema.json +11 -5
  228. package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +320 -0
  229. package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +734 -0
  230. package/src/py/agent/__snapshots__/{generator.spec.ts.snap → generator.protocols.spec.ts.snap} +182 -314
  231. package/src/py/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +189 -0
  232. package/src/py/agent/a2a-connection/files/agent-connection/app/__targetAgentSnakeCase___client_strands.py.template +30 -0
  233. package/src/py/agent/a2a-connection/files/langchain/agent-connection/app/__targetAgentSnakeCase___client_langchain.py.template +28 -0
  234. package/src/py/agent/a2a-connection/generator.d.ts +3 -3
  235. package/src/py/agent/a2a-connection/generator.js +113 -85
  236. package/src/py/agent/a2a-connection/generator.js.map +1 -1
  237. package/src/py/agent/a2a-connection/schema.d.js +8 -0
  238. package/src/py/agent/a2a-connection/schema.d.js.map +1 -0
  239. package/src/py/agent/a2a-connection/schema.d.ts +1 -0
  240. package/src/py/agent/a2a-connection/schema.json +5 -0
  241. package/src/py/agent/files/a2a-langchain/main.py.template +89 -0
  242. package/src/py/agent/files/ag-ui-langchain/main.py.template +83 -0
  243. package/src/py/agent/files/common/agent.py.template +2 -0
  244. package/src/py/agent/files/common-langchain/agent.py.template +30 -0
  245. package/src/py/agent/files/deploy/Dockerfile.template +1 -1
  246. package/src/py/agent/files/http/init.py.template +7 -25
  247. package/src/py/agent/files/http/main.py.template +3 -4
  248. package/src/py/agent/files/http-langchain/main.py.template +84 -0
  249. package/src/py/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +184 -0
  250. package/src/py/agent/gateway-connection/files/agent-connection/app/__gatewaySnakeCase___client_strands.py.template +35 -0
  251. package/src/py/agent/gateway-connection/files/langchain/agent-connection/app/__gatewaySnakeCase___client_langchain.py.template +34 -0
  252. package/src/py/agent/gateway-connection/generator.d.ts +10 -0
  253. package/src/py/agent/gateway-connection/generator.js +119 -0
  254. package/src/py/agent/gateway-connection/generator.js.map +1 -0
  255. package/src/py/agent/gateway-connection/schema.d.js +6 -0
  256. package/src/py/agent/gateway-connection/schema.d.js.map +1 -0
  257. package/src/py/agent/gateway-connection/schema.d.ts +13 -0
  258. package/src/py/agent/gateway-connection/schema.json +31 -0
  259. package/src/py/agent/generator.d.ts +3 -3
  260. package/src/py/agent/generator.js +290 -179
  261. package/src/py/agent/generator.js.map +1 -1
  262. package/src/py/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +153 -89
  263. package/src/py/agent/mcp-connection/files/agent-connection/app/__mcpServerSnakeCase___client_strands.py.template +30 -0
  264. package/src/py/agent/mcp-connection/files/langchain/agent-connection/app/__mcpServerSnakeCase___client_langchain.py.template +30 -0
  265. package/src/py/agent/mcp-connection/generator.d.ts +3 -3
  266. package/src/py/agent/mcp-connection/generator.js +65 -126
  267. package/src/py/agent/mcp-connection/generator.js.map +1 -1
  268. package/src/py/agent/mcp-connection/schema.d.js +8 -0
  269. package/src/py/agent/mcp-connection/schema.d.js.map +1 -0
  270. package/src/py/agent/mcp-connection/schema.d.ts +1 -0
  271. package/src/py/agent/mcp-connection/schema.json +5 -0
  272. package/src/py/agent/react-connection/__snapshots__/generator.spec.ts.snap +11 -19
  273. package/src/py/agent/react-connection/generator.d.ts +4 -4
  274. package/src/py/agent/react-connection/generator.js +55 -59
  275. package/src/py/agent/react-connection/generator.js.map +1 -1
  276. package/src/py/agent/react-connection/{serve-local.d.ts → local-dev.d.ts} +6 -6
  277. package/src/py/agent/react-connection/local-dev.js +36 -0
  278. package/src/py/agent/react-connection/local-dev.js.map +1 -0
  279. package/src/py/agent/react-connection/schema.d.js +8 -0
  280. package/src/py/agent/react-connection/schema.d.js.map +1 -0
  281. package/src/py/agent/react-connection/schema.d.ts +1 -0
  282. package/src/py/agent/react-connection/schema.json +5 -0
  283. package/src/py/agent/schema.d.js +6 -0
  284. package/src/py/agent/schema.d.js.map +1 -0
  285. package/src/py/agent/schema.d.ts +2 -1
  286. package/src/py/agent/schema.json +6 -1
  287. package/src/py/api/generator.d.ts +3 -3
  288. package/src/py/api/generator.js +12 -11
  289. package/src/py/api/generator.js.map +1 -1
  290. package/src/py/api/schema.d.js +6 -0
  291. package/src/py/api/schema.d.js.map +1 -0
  292. package/src/py/api/schema.d.ts +1 -0
  293. package/src/py/api/schema.json +5 -0
  294. package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +1526 -0
  295. package/src/py/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +45 -0
  296. package/src/py/dynamodb/agent-connection/generator.d.ts +10 -0
  297. package/src/py/dynamodb/agent-connection/generator.js +39 -0
  298. package/src/py/dynamodb/agent-connection/generator.js.map +1 -0
  299. package/src/py/dynamodb/agent-connection/schema.d.js +8 -0
  300. package/src/py/dynamodb/agent-connection/schema.d.js.map +1 -0
  301. package/src/py/dynamodb/agent-connection/schema.d.ts +15 -0
  302. package/src/py/dynamodb/agent-connection/schema.json +27 -0
  303. package/src/py/dynamodb/fast-api-connection/__snapshots__/generator.spec.ts.snap +23 -0
  304. package/src/py/dynamodb/fast-api-connection/generator.d.ts +10 -0
  305. package/src/py/dynamodb/fast-api-connection/generator.js +37 -0
  306. package/src/py/dynamodb/fast-api-connection/generator.js.map +1 -0
  307. package/src/py/dynamodb/fast-api-connection/schema.d.js +8 -0
  308. package/src/py/dynamodb/fast-api-connection/schema.d.js.map +1 -0
  309. package/src/py/dynamodb/fast-api-connection/schema.d.ts +13 -0
  310. package/src/py/dynamodb/fast-api-connection/schema.json +23 -0
  311. package/src/py/dynamodb/files/__name__/__init__.py.template +6 -0
  312. package/src/py/dynamodb/files/__name__/client.py.template +39 -0
  313. package/src/py/dynamodb/files/__name__/entities/__init__.py.template +4 -0
  314. package/src/py/dynamodb/files/__name__/entities/base.py.template +63 -0
  315. package/src/py/dynamodb/files/__name__/entities/example.py.template +64 -0
  316. package/src/py/dynamodb/files/config.json.template +24 -0
  317. package/src/py/dynamodb/generator.d.ts +10 -0
  318. package/src/py/dynamodb/generator.js +110 -0
  319. package/src/py/dynamodb/generator.js.map +1 -0
  320. package/src/py/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +45 -0
  321. package/src/py/dynamodb/mcp-server-connection/generator.d.ts +10 -0
  322. package/src/py/dynamodb/mcp-server-connection/generator.js +39 -0
  323. package/src/py/dynamodb/mcp-server-connection/generator.js.map +1 -0
  324. package/src/py/dynamodb/mcp-server-connection/schema.d.js +8 -0
  325. package/src/py/dynamodb/mcp-server-connection/schema.d.js.map +1 -0
  326. package/src/py/dynamodb/mcp-server-connection/schema.d.ts +15 -0
  327. package/src/py/dynamodb/mcp-server-connection/schema.json +27 -0
  328. package/src/py/dynamodb/schema.d.js +6 -0
  329. package/src/py/dynamodb/schema.d.js.map +1 -0
  330. package/src/py/dynamodb/schema.d.ts +16 -0
  331. package/src/py/dynamodb/schema.json +75 -0
  332. package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +212 -4678
  333. package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +5409 -0
  334. package/src/py/fast-api/files/app/__name__/init.py.template +5 -22
  335. package/src/py/fast-api/files/app/__name__/main.py.template +4 -1
  336. package/src/py/fast-api/generator.d.ts +3 -3
  337. package/src/py/fast-api/generator.js +90 -87
  338. package/src/py/fast-api/generator.js.map +1 -1
  339. package/src/py/fast-api/react/__snapshots__/generator.spec.ts.snap +4 -3
  340. package/src/py/fast-api/react/generator.d.ts +4 -4
  341. package/src/py/fast-api/react/generator.js +25 -25
  342. package/src/py/fast-api/react/generator.js.map +1 -1
  343. package/src/py/fast-api/react/open-api.d.ts +1 -1
  344. package/src/py/fast-api/react/open-api.js +31 -29
  345. package/src/py/fast-api/react/open-api.js.map +1 -1
  346. package/src/py/fast-api/react/schema.d.js +6 -0
  347. package/src/py/fast-api/react/schema.d.js.map +1 -0
  348. package/src/py/fast-api/react/schema.d.ts +1 -0
  349. package/src/py/fast-api/react/schema.json +5 -0
  350. package/src/py/fast-api/schema.d.js +6 -0
  351. package/src/py/fast-api/schema.d.js.map +1 -0
  352. package/src/py/fast-api/schema.d.ts +1 -0
  353. package/src/py/fast-api/schema.json +5 -0
  354. package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +4 -4
  355. package/src/py/lambda-function/generator.d.ts +3 -3
  356. package/src/py/lambda-function/generator.js +60 -59
  357. package/src/py/lambda-function/generator.js.map +1 -1
  358. package/src/py/lambda-function/schema.d.js +6 -0
  359. package/src/py/lambda-function/schema.d.js.map +1 -0
  360. package/src/py/lambda-function/schema.d.ts +1 -0
  361. package/src/py/lambda-function/schema.json +5 -0
  362. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +208 -19
  363. package/src/py/mcp-server/files/deploy/Dockerfile.template +1 -1
  364. package/src/py/mcp-server/generator.d.ts +3 -3
  365. package/src/py/mcp-server/generator.js +162 -124
  366. package/src/py/mcp-server/generator.js.map +1 -1
  367. package/src/py/mcp-server/schema.d.js +6 -0
  368. package/src/py/mcp-server/schema.d.js.map +1 -0
  369. package/src/py/mcp-server/schema.d.ts +1 -0
  370. package/src/py/mcp-server/schema.json +5 -0
  371. package/src/py/project/generator.d.ts +17 -4
  372. package/src/py/project/generator.js +205 -127
  373. package/src/py/project/generator.js.map +1 -1
  374. package/src/py/project/schema.d.js +6 -0
  375. package/src/py/project/schema.d.js.map +1 -0
  376. package/src/py/project/schema.d.ts +1 -0
  377. package/src/py/project/schema.json +5 -0
  378. package/src/py/rdb/__snapshots__/generator.spec.ts.snap +2038 -0
  379. package/src/py/rdb/agent-connection/__snapshots__/generator.spec.ts.snap +104 -0
  380. package/src/py/rdb/agent-connection/generator.d.ts +10 -0
  381. package/src/py/rdb/agent-connection/generator.js +46 -0
  382. package/src/py/rdb/agent-connection/generator.js.map +1 -0
  383. package/src/py/rdb/agent-connection/schema.d.js +8 -0
  384. package/src/py/rdb/agent-connection/schema.d.js.map +1 -0
  385. package/src/py/rdb/agent-connection/schema.d.ts +15 -0
  386. package/src/py/rdb/agent-connection/schema.json +27 -0
  387. package/src/py/rdb/fast-api-connection/__snapshots__/generator.spec.ts.snap +44 -0
  388. package/src/py/rdb/fast-api-connection/files/__apiModuleName__/dependencies/__rdbNameSnake__.py.template +14 -0
  389. package/src/py/rdb/fast-api-connection/generator.d.ts +10 -0
  390. package/src/py/rdb/fast-api-connection/generator.js +54 -0
  391. package/src/py/rdb/fast-api-connection/generator.js.map +1 -0
  392. package/src/py/rdb/fast-api-connection/schema.d.js +8 -0
  393. package/src/py/rdb/fast-api-connection/schema.d.js.map +1 -0
  394. package/src/py/rdb/fast-api-connection/schema.d.ts +13 -0
  395. package/src/py/rdb/fast-api-connection/schema.json +23 -0
  396. package/src/py/rdb/files/Dockerfile.create-db-user.template +10 -0
  397. package/src/py/rdb/files/Dockerfile.migration.template +10 -0
  398. package/src/py/rdb/files/__name__/__init__.py.template +3 -0
  399. package/src/py/rdb/files/__name__/connection.py.template +55 -0
  400. package/src/py/rdb/files/__name__/create_db_user_handler.py.template +97 -0
  401. package/src/py/rdb/files/__name__/migration_handler.py.template +36 -0
  402. package/src/py/rdb/files/__name__/models/__init__.py.template +3 -0
  403. package/src/py/rdb/files/__name__/models/example.py.template +8 -0
  404. package/src/py/rdb/files/__name__/utils.py.template +104 -0
  405. package/src/py/rdb/files/alembic.ini.template +38 -0
  406. package/src/py/rdb/files/config.json.template +14 -0
  407. package/src/py/rdb/files/migrations/env.py.template +80 -0
  408. package/src/py/rdb/files/migrations/script.py.mako.template +28 -0
  409. package/src/py/rdb/generator.d.ts +6 -0
  410. package/src/py/rdb/generator.js +274 -0
  411. package/src/py/rdb/generator.js.map +1 -0
  412. package/src/py/rdb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +101 -0
  413. package/src/py/rdb/mcp-server-connection/generator.d.ts +10 -0
  414. package/src/py/rdb/mcp-server-connection/generator.js +46 -0
  415. package/src/py/rdb/mcp-server-connection/generator.js.map +1 -0
  416. package/src/py/rdb/mcp-server-connection/schema.d.js +8 -0
  417. package/src/py/rdb/mcp-server-connection/schema.d.js.map +1 -0
  418. package/src/py/rdb/mcp-server-connection/schema.d.ts +15 -0
  419. package/src/py/rdb/mcp-server-connection/schema.json +27 -0
  420. package/src/py/rdb/schema.d.js +6 -0
  421. package/src/py/rdb/schema.d.js.map +1 -0
  422. package/src/py/rdb/schema.d.ts +16 -0
  423. package/src/py/rdb/schema.json +77 -0
  424. package/src/py/rdb/utils.d.ts +6 -0
  425. package/src/py/rdb/utils.js +16 -0
  426. package/src/py/rdb/utils.js.map +1 -0
  427. package/src/sdk/agentcore-gateway.d.ts +6 -0
  428. package/src/sdk/agentcore-gateway.js +7 -0
  429. package/src/sdk/agentcore-gateway.js.map +1 -0
  430. package/src/sdk/connection.d.ts +6 -0
  431. package/src/sdk/connection.js +6 -0
  432. package/src/sdk/connection.js.map +1 -0
  433. package/src/sdk/license.d.ts +8 -0
  434. package/src/sdk/license.js +7 -0
  435. package/src/sdk/license.js.map +1 -0
  436. package/src/sdk/open-api.d.ts +10 -0
  437. package/src/sdk/open-api.js +8 -0
  438. package/src/sdk/open-api.js.map +1 -0
  439. package/src/sdk/py.d.ts +16 -0
  440. package/src/sdk/py.js +11 -0
  441. package/src/sdk/py.js.map +1 -0
  442. package/src/sdk/terraform.d.ts +6 -0
  443. package/src/sdk/terraform.js +7 -0
  444. package/src/sdk/terraform.js.map +1 -0
  445. package/src/sdk/ts.d.ts +33 -0
  446. package/src/sdk/ts.js +35 -0
  447. package/src/sdk/ts.js.map +1 -0
  448. package/{sdk → src/sdk}/utils/ast.d.ts +1 -2
  449. package/src/sdk/utils/ast.js +6 -0
  450. package/src/sdk/utils/ast.js.map +1 -0
  451. package/{sdk → src/sdk}/utils/format.d.ts +1 -1
  452. package/src/sdk/utils/format.js +6 -0
  453. package/src/sdk/utils/format.js.map +1 -0
  454. package/{sdk → src/sdk}/utils/test.d.ts +1 -1
  455. package/src/sdk/utils/test.js +6 -0
  456. package/src/sdk/utils/test.js.map +1 -0
  457. package/src/smithy/project/__snapshots__/generator.spec.ts.snap +19 -24
  458. package/src/smithy/project/files/build.Dockerfile.template +1 -4
  459. package/src/smithy/project/files/src/operations/echo.smithy.template +1 -0
  460. package/src/smithy/project/generator.d.ts +3 -3
  461. package/src/smithy/project/generator.js +64 -57
  462. package/src/smithy/project/generator.js.map +1 -1
  463. package/src/smithy/project/schema.d.js +6 -0
  464. package/src/smithy/project/schema.d.js.map +1 -0
  465. package/src/smithy/project/schema.d.ts +1 -0
  466. package/src/smithy/project/schema.json +5 -0
  467. package/src/smithy/react-connection/__snapshots__/generator.spec.ts.snap +1 -1
  468. package/src/smithy/react-connection/generator.d.ts +3 -3
  469. package/src/smithy/react-connection/generator.js +39 -47
  470. package/src/smithy/react-connection/generator.js.map +1 -1
  471. package/src/smithy/react-connection/schema.d.js +6 -0
  472. package/src/smithy/react-connection/schema.d.js.map +1 -0
  473. package/src/smithy/react-connection/schema.d.ts +1 -0
  474. package/src/smithy/react-connection/schema.json +5 -0
  475. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +824 -120
  476. package/src/smithy/ts/api/files/handler.ts.template +2 -2
  477. package/src/smithy/ts/api/files/local-server.ts.template +2 -2
  478. package/src/smithy/ts/api/files/operations/echo.ts.template +2 -2
  479. package/src/smithy/ts/api/files/service.ts.template +3 -3
  480. package/src/smithy/ts/api/generator.d.ts +3 -3
  481. package/src/smithy/ts/api/generator.js +128 -105
  482. package/src/smithy/ts/api/generator.js.map +1 -1
  483. package/src/smithy/ts/api/schema.d.js +6 -0
  484. package/src/smithy/ts/api/schema.d.js.map +1 -0
  485. package/src/smithy/ts/api/schema.d.ts +1 -0
  486. package/src/smithy/ts/api/schema.json +5 -0
  487. package/src/terraform/project/files/application/src/main.tf.template +6 -1
  488. package/src/terraform/project/files/application/src/providers.tf.template +1 -1
  489. package/src/terraform/project/generator.d.ts +3 -3
  490. package/src/terraform/project/generator.js +156 -104
  491. package/src/terraform/project/generator.js.map +1 -1
  492. package/src/terraform/project/schema.d.js +9 -0
  493. package/src/terraform/project/schema.d.js.map +1 -0
  494. package/src/terraform/project/schema.d.ts +1 -0
  495. package/src/terraform/project/schema.json +5 -0
  496. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +1099 -134
  497. package/src/trpc/backend/files/src/client/index.ts.template +1 -1
  498. package/src/trpc/backend/files/src/handler.ts.template +1 -1
  499. package/src/trpc/backend/files/src/index.ts.template +5 -5
  500. package/src/trpc/backend/files/src/init.ts.template +1 -1
  501. package/src/trpc/backend/files/src/local-server.ts.template +1 -1
  502. package/src/trpc/backend/files/src/middleware/index.ts.template +7 -7
  503. package/src/trpc/backend/files/src/procedures/echo.ts.template +3 -3
  504. package/src/trpc/backend/files/src/router.ts.template +2 -2
  505. package/src/trpc/backend/files/src/schema/echo.ts.template +2 -2
  506. package/src/trpc/backend/files/src/schema/index.ts.template +1 -1
  507. package/src/trpc/backend/generator.d.ts +4 -4
  508. package/src/trpc/backend/generator.js +98 -84
  509. package/src/trpc/backend/generator.js.map +1 -1
  510. package/src/trpc/backend/schema.d.js +6 -0
  511. package/src/trpc/backend/schema.d.js.map +1 -0
  512. package/src/trpc/backend/schema.d.ts +3 -2
  513. package/src/trpc/backend/schema.json +5 -0
  514. package/src/trpc/react/__snapshots__/generator.spec.ts.snap +4 -4
  515. package/src/trpc/react/files/src/components/__apiNameClassName__ClientProvider.tsx.template +3 -3
  516. package/src/trpc/react/generator.d.ts +4 -4
  517. package/src/trpc/react/generator.js +63 -58
  518. package/src/trpc/react/generator.js.map +1 -1
  519. package/src/trpc/react/schema.d.js +6 -0
  520. package/src/trpc/react/schema.d.js.map +1 -0
  521. package/src/trpc/react/schema.d.ts +1 -0
  522. package/src/trpc/react/schema.json +5 -0
  523. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +781 -22
  524. package/src/ts/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +256 -0
  525. package/src/ts/agent/a2a-connection/files/agent-connection/app/__targetAgentKebabCase__-client-strands.ts.template +23 -0
  526. package/src/ts/agent/a2a-connection/generator.d.ts +3 -3
  527. package/src/ts/agent/a2a-connection/generator.js +64 -55
  528. package/src/ts/agent/a2a-connection/generator.js.map +1 -1
  529. package/src/ts/agent/a2a-connection/schema.d.js +8 -0
  530. package/src/ts/agent/a2a-connection/schema.d.js.map +1 -0
  531. package/src/ts/agent/a2a-connection/schema.d.ts +1 -0
  532. package/src/ts/agent/a2a-connection/schema.json +5 -0
  533. package/src/ts/agent/files/a2a/index.ts.template +1 -1
  534. package/src/ts/agent/files/ag-ui/index.ts.template +1 -1
  535. package/src/ts/agent/files/common/agent.ts.template +6 -2
  536. package/src/ts/agent/files/deploy/Dockerfile.template +4 -1
  537. package/src/ts/agent/files/http/client.ts.template +2 -2
  538. package/src/ts/agent/files/http/index.ts.template +2 -2
  539. package/src/ts/agent/files/http/router.ts.template +5 -5
  540. package/src/ts/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +220 -0
  541. package/src/ts/agent/gateway-connection/files/agent-connection/app/__gatewayKebabCase__-client-strands.ts.template +30 -0
  542. package/src/ts/agent/gateway-connection/generator.d.ts +10 -0
  543. package/src/ts/agent/gateway-connection/generator.js +116 -0
  544. package/src/ts/agent/gateway-connection/generator.js.map +1 -0
  545. package/src/ts/agent/gateway-connection/schema.d.js +6 -0
  546. package/src/ts/agent/gateway-connection/schema.d.js.map +1 -0
  547. package/src/ts/agent/gateway-connection/schema.d.ts +13 -0
  548. package/src/ts/agent/gateway-connection/schema.json +31 -0
  549. package/src/ts/agent/generator.d.ts +3 -3
  550. package/src/ts/agent/generator.js +203 -144
  551. package/src/ts/agent/generator.js.map +1 -1
  552. package/src/ts/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +192 -111
  553. package/src/ts/agent/mcp-connection/files/agent-connection/app/__mcpServerKebabCase__-client-strands.ts.template +22 -0
  554. package/src/ts/agent/mcp-connection/generator.d.ts +3 -3
  555. package/src/ts/agent/mcp-connection/generator.js +54 -59
  556. package/src/ts/agent/mcp-connection/generator.js.map +1 -1
  557. package/src/ts/agent/mcp-connection/schema.d.js +8 -0
  558. package/src/ts/agent/mcp-connection/schema.d.js.map +1 -0
  559. package/src/ts/agent/mcp-connection/schema.d.ts +1 -0
  560. package/src/ts/agent/mcp-connection/schema.json +5 -0
  561. package/src/ts/agent/react-connection/generator.d.ts +4 -4
  562. package/src/ts/agent/react-connection/generator.js +86 -80
  563. package/src/ts/agent/react-connection/generator.js.map +1 -1
  564. package/src/ts/agent/react-connection/local-dev.d.ts +13 -0
  565. package/src/ts/agent/react-connection/local-dev.js +17 -0
  566. package/src/ts/agent/react-connection/local-dev.js.map +1 -0
  567. package/src/ts/agent/react-connection/schema.d.js +8 -0
  568. package/src/ts/agent/react-connection/schema.d.js.map +1 -0
  569. package/src/ts/agent/react-connection/schema.d.ts +1 -0
  570. package/src/ts/agent/react-connection/schema.json +5 -0
  571. package/src/ts/agent/schema.d.js +6 -0
  572. package/src/ts/agent/schema.d.js.map +1 -0
  573. package/src/ts/agent/schema.d.ts +1 -0
  574. package/src/ts/agent/schema.json +5 -0
  575. package/src/ts/api/generator.d.ts +3 -3
  576. package/src/ts/api/generator.js +16 -16
  577. package/src/ts/api/generator.js.map +1 -1
  578. package/src/ts/api/schema.d.js +6 -0
  579. package/src/ts/api/schema.d.js.map +1 -0
  580. package/src/ts/api/schema.d.ts +3 -1
  581. package/src/ts/api/schema.json +5 -0
  582. package/src/ts/astro-docs/__snapshots__/generator.spec.ts.snap +15 -16
  583. package/src/ts/astro-docs/files/translation/scripts/translate.ts.template +3 -2
  584. package/src/ts/astro-docs/generator.d.ts +3 -3
  585. package/src/ts/astro-docs/generator.js +71 -54
  586. package/src/ts/astro-docs/generator.js.map +1 -1
  587. package/src/ts/astro-docs/schema.d.js +6 -0
  588. package/src/ts/astro-docs/schema.d.js.map +1 -0
  589. package/src/ts/astro-docs/schema.d.ts +2 -2
  590. package/src/ts/astro-docs/schema.json +3 -3
  591. package/src/ts/docs/generator.d.ts +3 -3
  592. package/src/ts/docs/generator.js +10 -10
  593. package/src/ts/docs/generator.js.map +1 -1
  594. package/src/ts/docs/schema.d.js +6 -0
  595. package/src/ts/docs/schema.d.js.map +1 -0
  596. package/src/ts/docs/schema.d.ts +1 -4
  597. package/src/ts/docs/schema.json +3 -3
  598. package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +400 -512
  599. package/src/ts/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +5 -5
  600. package/src/ts/dynamodb/agent-connection/generator.d.ts +3 -3
  601. package/src/ts/dynamodb/agent-connection/generator.js +21 -23
  602. package/src/ts/dynamodb/agent-connection/generator.js.map +1 -1
  603. package/src/ts/dynamodb/agent-connection/schema.d.js +8 -0
  604. package/src/ts/dynamodb/agent-connection/schema.d.js.map +1 -0
  605. package/src/ts/dynamodb/agent-connection/schema.d.ts +1 -0
  606. package/src/ts/dynamodb/agent-connection/schema.json +5 -0
  607. package/src/ts/dynamodb/files/config.json.template +24 -0
  608. package/src/ts/dynamodb/files/src/client.ts.template +30 -11
  609. package/src/ts/dynamodb/files/src/entities/example.ts.template +1 -1
  610. package/src/ts/dynamodb/files/src/entities/index.ts.template +1 -1
  611. package/src/ts/dynamodb/files/src/index.ts.template +2 -11
  612. package/src/ts/dynamodb/generator.d.ts +3 -3
  613. package/src/ts/dynamodb/generator.js +73 -63
  614. package/src/ts/dynamodb/generator.js.map +1 -1
  615. package/src/ts/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +5 -5
  616. package/src/ts/dynamodb/mcp-server-connection/generator.d.ts +3 -3
  617. package/src/ts/dynamodb/mcp-server-connection/generator.js +21 -23
  618. package/src/ts/dynamodb/mcp-server-connection/generator.js.map +1 -1
  619. package/src/ts/dynamodb/mcp-server-connection/schema.d.js +8 -0
  620. package/src/ts/dynamodb/mcp-server-connection/schema.d.js.map +1 -0
  621. package/src/ts/dynamodb/mcp-server-connection/schema.d.ts +1 -0
  622. package/src/ts/dynamodb/mcp-server-connection/schema.json +5 -0
  623. package/src/ts/dynamodb/schema.d.js +6 -0
  624. package/src/ts/dynamodb/schema.d.js.map +1 -0
  625. package/src/ts/dynamodb/schema.d.ts +2 -0
  626. package/src/ts/dynamodb/schema.json +25 -2
  627. package/src/ts/dynamodb/smithy-connection/__snapshots__/generator.spec.ts.snap +3 -3
  628. package/src/ts/dynamodb/smithy-connection/generator.d.ts +3 -3
  629. package/src/ts/dynamodb/smithy-connection/generator.js +20 -22
  630. package/src/ts/dynamodb/smithy-connection/generator.js.map +1 -1
  631. package/src/ts/dynamodb/smithy-connection/schema.d.js +8 -0
  632. package/src/ts/dynamodb/smithy-connection/schema.d.js.map +1 -0
  633. package/src/ts/dynamodb/smithy-connection/schema.d.ts +1 -0
  634. package/src/ts/dynamodb/smithy-connection/schema.json +5 -0
  635. package/src/ts/dynamodb/trpc-connection/__snapshots__/generator.spec.ts.snap +3 -3
  636. package/src/ts/dynamodb/trpc-connection/generator.d.ts +3 -3
  637. package/src/ts/dynamodb/trpc-connection/generator.js +20 -22
  638. package/src/ts/dynamodb/trpc-connection/generator.js.map +1 -1
  639. package/src/ts/dynamodb/trpc-connection/schema.d.js +8 -0
  640. package/src/ts/dynamodb/trpc-connection/schema.d.js.map +1 -0
  641. package/src/ts/dynamodb/trpc-connection/schema.d.ts +1 -0
  642. package/src/ts/dynamodb/trpc-connection/schema.json +5 -0
  643. package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +4 -4
  644. package/src/ts/lambda-function/generator.d.ts +3 -3
  645. package/src/ts/lambda-function/generator.js +59 -56
  646. package/src/ts/lambda-function/generator.js.map +1 -1
  647. package/src/ts/lambda-function/io.js +83 -52
  648. package/src/ts/lambda-function/io.js.map +1 -1
  649. package/src/ts/lambda-function/schema.d.js +6 -0
  650. package/src/ts/lambda-function/schema.d.js.map +1 -0
  651. package/src/ts/lambda-function/schema.d.ts +1 -0
  652. package/src/ts/lambda-function/schema.json +5 -0
  653. package/src/ts/lib/__snapshots__/generator.spec.ts.snap +98 -93
  654. package/src/ts/lib/__snapshots__/vitest.spec.ts.snap +24 -0
  655. package/src/ts/lib/biome.d.ts +7 -0
  656. package/src/ts/lib/biome.js +91 -0
  657. package/src/ts/lib/biome.js.map +1 -0
  658. package/src/ts/lib/generator.d.ts +3 -3
  659. package/src/ts/lib/generator.js +107 -108
  660. package/src/ts/lib/generator.js.map +1 -1
  661. package/src/ts/lib/grit/vitest-pass-with-no-tests.grit +1 -4
  662. package/src/ts/lib/schema.d.js +6 -0
  663. package/src/ts/lib/schema.d.js.map +1 -0
  664. package/src/ts/lib/schema.d.ts +1 -1
  665. package/src/ts/lib/schema.json +5 -0
  666. package/src/ts/lib/ts-project-utils.d.ts +12 -2
  667. package/src/ts/lib/ts-project-utils.js +90 -67
  668. package/src/ts/lib/ts-project-utils.js.map +1 -1
  669. package/src/ts/lib/types.d.ts +6 -0
  670. package/src/ts/lib/types.js +5 -2
  671. package/src/ts/lib/types.js.map +1 -1
  672. package/src/ts/lib/vitest.d.ts +2 -2
  673. package/src/ts/lib/vitest.js +29 -26
  674. package/src/ts/lib/vitest.js.map +1 -1
  675. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +208 -42
  676. package/src/ts/mcp-server/files/Dockerfile.template +4 -1
  677. package/src/ts/mcp-server/generator.d.ts +3 -3
  678. package/src/ts/mcp-server/generator.js +181 -136
  679. package/src/ts/mcp-server/generator.js.map +1 -1
  680. package/src/ts/mcp-server/schema.d.js +6 -0
  681. package/src/ts/mcp-server/schema.d.js.map +1 -0
  682. package/src/ts/mcp-server/schema.d.ts +1 -0
  683. package/src/ts/mcp-server/schema.json +5 -0
  684. package/src/ts/nx-generator/__snapshots__/generator.spec.ts.snap +46 -26
  685. package/src/ts/nx-generator/files/common/schema.d.ts.template +1 -0
  686. package/src/ts/nx-generator/files/common/schema.json.template +5 -0
  687. package/src/ts/nx-generator/files/local/generator.ts.template +3 -3
  688. package/src/ts/nx-generator/files/nx-plugin-for-aws/generator/generator.ts.template +6 -7
  689. package/src/ts/nx-generator/generator.d.ts +2 -2
  690. package/src/ts/nx-generator/generator.js +113 -73
  691. package/src/ts/nx-generator/generator.js.map +1 -1
  692. package/src/ts/nx-generator/schema.d.js +6 -0
  693. package/src/ts/nx-generator/schema.d.js.map +1 -0
  694. package/src/ts/nx-generator/schema.d.ts +1 -0
  695. package/src/ts/nx-generator/schema.json +5 -0
  696. package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +30 -18
  697. package/src/ts/nx-plugin/files/mcp-server/server.ts.template +5 -5
  698. package/src/ts/nx-plugin/files/mcp-server/tools/create-workspace-command.ts.template +2 -2
  699. package/src/ts/nx-plugin/files/mcp-server/tools/general-guidance.ts.template +1 -1
  700. package/src/ts/nx-plugin/files/mcp-server/tools/generator-guide.ts.template +2 -2
  701. package/src/ts/nx-plugin/files/mcp-server/tools/list-generators.ts.template +2 -2
  702. package/src/ts/nx-plugin/files/mcp-server/utils.ts.template +3 -3
  703. package/src/ts/nx-plugin/generator.d.ts +3 -3
  704. package/src/ts/nx-plugin/generator.js +61 -50
  705. package/src/ts/nx-plugin/generator.js.map +1 -1
  706. package/src/ts/nx-plugin/schema.d.js +9 -0
  707. package/src/ts/nx-plugin/schema.d.js.map +1 -0
  708. package/src/ts/nx-plugin/schema.json +5 -0
  709. package/src/ts/nx-plugin/utils.d.ts +1 -1
  710. package/src/ts/nx-plugin/utils.js +36 -39
  711. package/src/ts/nx-plugin/utils.js.map +1 -1
  712. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +455 -646
  713. package/src/ts/rdb/agent-connection/__snapshots__/generator.spec.ts.snap +6 -6
  714. package/src/ts/rdb/agent-connection/generator.d.ts +3 -3
  715. package/src/ts/rdb/agent-connection/generator.js +38 -39
  716. package/src/ts/rdb/agent-connection/generator.js.map +1 -1
  717. package/src/ts/rdb/agent-connection/schema.d.js +8 -0
  718. package/src/ts/rdb/agent-connection/schema.d.js.map +1 -0
  719. package/src/ts/rdb/agent-connection/schema.d.ts +1 -0
  720. package/src/ts/rdb/agent-connection/schema.json +5 -0
  721. package/src/ts/rdb/files/Dockerfile.template +8 -1
  722. package/src/ts/rdb/files/config.json.template +14 -0
  723. package/src/ts/rdb/files/prisma.config.ts.template +6 -5
  724. package/src/ts/rdb/files/src/create-db-user-handler.ts.template +9 -11
  725. package/src/ts/rdb/files/src/index.ts.template +1 -2
  726. package/src/ts/rdb/files/src/migration-handler.ts.template +2 -29
  727. package/src/ts/rdb/files/src/prisma.ts.template +33 -25
  728. package/src/ts/rdb/files/src/utils.ts.template +3 -0
  729. package/src/ts/rdb/generator.d.ts +3 -7
  730. package/src/ts/rdb/generator.js +173 -131
  731. package/src/ts/rdb/generator.js.map +1 -1
  732. package/src/ts/rdb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +6 -6
  733. package/src/ts/rdb/mcp-server-connection/generator.d.ts +3 -3
  734. package/src/ts/rdb/mcp-server-connection/generator.js +36 -37
  735. package/src/ts/rdb/mcp-server-connection/generator.js.map +1 -1
  736. package/src/ts/rdb/mcp-server-connection/schema.d.js +8 -0
  737. package/src/ts/rdb/mcp-server-connection/schema.d.js.map +1 -0
  738. package/src/ts/rdb/mcp-server-connection/schema.d.ts +1 -0
  739. package/src/ts/rdb/mcp-server-connection/schema.json +5 -0
  740. package/src/ts/rdb/schema.d.js +6 -0
  741. package/src/ts/rdb/schema.d.js.map +1 -0
  742. package/src/ts/rdb/schema.d.ts +1 -0
  743. package/src/ts/rdb/schema.json +6 -1
  744. package/src/ts/rdb/smithy-connection/__snapshots__/generator.spec.ts.snap +3 -3
  745. package/src/ts/rdb/smithy-connection/generator.d.ts +3 -3
  746. package/src/ts/rdb/smithy-connection/generator.js +46 -43
  747. package/src/ts/rdb/smithy-connection/generator.js.map +1 -1
  748. package/src/ts/rdb/smithy-connection/schema.d.js +8 -0
  749. package/src/ts/rdb/smithy-connection/schema.d.js.map +1 -0
  750. package/src/ts/rdb/smithy-connection/schema.d.ts +1 -0
  751. package/src/ts/rdb/smithy-connection/schema.json +5 -0
  752. package/src/ts/rdb/trpc-connection/__snapshots__/generator.spec.ts.snap +3 -3
  753. package/src/ts/rdb/trpc-connection/generator.d.ts +3 -3
  754. package/src/ts/rdb/trpc-connection/generator.js +36 -31
  755. package/src/ts/rdb/trpc-connection/generator.js.map +1 -1
  756. package/src/ts/rdb/trpc-connection/schema.d.js +8 -0
  757. package/src/ts/rdb/trpc-connection/schema.d.js.map +1 -0
  758. package/src/ts/rdb/trpc-connection/schema.d.ts +1 -0
  759. package/src/ts/rdb/trpc-connection/schema.json +5 -0
  760. package/src/ts/rdb/utils.d.ts +1 -1
  761. package/src/ts/rdb/utils.js +9 -11
  762. package/src/ts/rdb/utils.js.map +1 -1
  763. package/src/ts/react-website/agui/files/common/src/hooks/useAgui__agentNameClassName__.tsx.template +1 -16
  764. package/src/ts/react-website/agui/generator.d.ts +1 -1
  765. package/src/ts/react-website/agui/generator.js +69 -62
  766. package/src/ts/react-website/agui/generator.js.map +1 -1
  767. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +1190 -799
  768. package/src/ts/react-website/app/generator.d.ts +4 -4
  769. package/src/ts/react-website/app/generator.js +217 -192
  770. package/src/ts/react-website/app/generator.js.map +1 -1
  771. package/src/ts/react-website/app/schema.d.js +6 -0
  772. package/src/ts/react-website/app/schema.d.js.map +1 -0
  773. package/src/ts/react-website/app/schema.d.ts +1 -1
  774. package/src/ts/react-website/app/schema.json +11 -6
  775. package/src/ts/react-website/cognito-auth/__snapshots__/generator.spec.ts.snap +129 -18
  776. package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +36 -10
  777. package/src/ts/react-website/cognito-auth/__snapshots__/generator.ux-provider.spec.ts.snap +0 -20
  778. package/src/ts/react-website/cognito-auth/files/app/components/CognitoAuth/index.tsx.template +2 -2
  779. package/src/ts/react-website/cognito-auth/generator.d.ts +4 -4
  780. package/src/ts/react-website/cognito-auth/generator.js +64 -63
  781. package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
  782. package/src/ts/react-website/cognito-auth/grit/cloudscape-auth-menu.grit +8 -6
  783. package/src/ts/react-website/cognito-auth/grit/cognito-auth-wrapper.grit +1 -1
  784. package/src/ts/react-website/cognito-auth/grit/none-auth-menu.grit +1 -0
  785. package/src/ts/react-website/cognito-auth/grit/shadcn-auth-menu.grit +3 -1
  786. package/src/ts/react-website/cognito-auth/grit/shadcn-state-declarations.grit +3 -1
  787. package/src/ts/react-website/cognito-auth/schema.d.js +6 -0
  788. package/src/ts/react-website/cognito-auth/schema.d.js.map +1 -0
  789. package/src/ts/react-website/cognito-auth/schema.d.ts +1 -0
  790. package/src/ts/react-website/cognito-auth/schema.json +5 -0
  791. package/src/ts/react-website/cognito-auth/utils.d.ts +1 -1
  792. package/src/ts/react-website/cognito-auth/utils.js +34 -32
  793. package/src/ts/react-website/cognito-auth/utils.js.map +1 -1
  794. package/src/ts/react-website/runtime-config/__snapshots__/generator.spec.ts.snap +2 -2
  795. package/src/ts/react-website/runtime-config/files/app/components/RuntimeConfig/index.tsx.template +2 -2
  796. package/src/ts/react-website/runtime-config/generator.d.ts +3 -3
  797. package/src/ts/react-website/runtime-config/generator.js +29 -31
  798. package/src/ts/react-website/runtime-config/generator.js.map +1 -1
  799. package/src/ts/react-website/runtime-config/schema.d.js +6 -0
  800. package/src/ts/react-website/runtime-config/schema.d.js.map +1 -0
  801. package/src/ts/react-website/runtime-config/schema.d.ts +1 -0
  802. package/src/ts/react-website/runtime-config/schema.json +5 -0
  803. package/src/ts/sync/generator.d.ts +3 -3
  804. package/src/ts/sync/generator.js +58 -59
  805. package/src/ts/sync/generator.js.map +1 -1
  806. package/src/ts/website/app/generator.d.ts +3 -3
  807. package/src/ts/website/app/generator.js +10 -10
  808. package/src/ts/website/app/generator.js.map +1 -1
  809. package/src/ts/website/app/schema.d.js +6 -0
  810. package/src/ts/website/app/schema.d.js.map +1 -0
  811. package/src/ts/website/app/schema.d.ts +1 -1
  812. package/src/ts/website/app/schema.json +11 -6
  813. package/src/ts/website/auth/generator.d.ts +4 -4
  814. package/src/ts/website/auth/generator.js +11 -10
  815. package/src/ts/website/auth/generator.js.map +1 -1
  816. package/src/ts/website/auth/schema.d.js +6 -0
  817. package/src/ts/website/auth/schema.d.js.map +1 -0
  818. package/src/ts/website/auth/schema.d.ts +1 -0
  819. package/src/ts/website/auth/schema.json +5 -0
  820. package/src/utils/agent-chat/agent-chat.d.ts +31 -0
  821. package/src/utils/agent-chat/agent-chat.js +31 -0
  822. package/src/utils/agent-chat/agent-chat.js.map +1 -0
  823. package/src/utils/agent-chat/files/a2a/chat.ts.template +33 -0
  824. package/src/utils/agent-chat/files/ag-ui/chat.ts.template +17 -0
  825. package/src/utils/agent-chat/files/common/agentcore.ts.template +81 -0
  826. package/src/utils/agent-chat/files/http-py/chat.ts.template +43 -0
  827. package/src/utils/agent-chat/files/http-ts/chat.ts.template +54 -0
  828. package/src/utils/agent-connection/agent-connection.d.ts +117 -25
  829. package/src/utils/agent-connection/agent-connection.js +414 -103
  830. package/src/utils/agent-connection/agent-connection.js.map +1 -1
  831. package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client-config.ts.template +93 -0
  832. package/src/utils/agent-connection/files/core-auth/agentcore-endpoints.ts.template +37 -0
  833. package/src/utils/agent-connection/files/core-auth/agentcore-fetch.ts.template +54 -0
  834. package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-transport.ts.template +41 -0
  835. package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-transport.ts.template +70 -0
  836. package/src/utils/agent-connection/files/core-runtime-config/runtime-config.ts.template +22 -32
  837. package/src/utils/agent-connection/files/core-shared/agentcore-transport.ts.template +39 -0
  838. package/src/utils/agent-connection/files/core-strands/a2a/agentcore-a2a-client-strands.ts.template +61 -0
  839. package/src/utils/agent-connection/files/core-strands/base/model-errors-strands.ts.template +36 -0
  840. package/src/utils/agent-connection/files/{core-runtime-config/with-session-id.ts.template → core-strands/base/with-session-id-strands.ts.template} +1 -1
  841. package/src/utils/agent-connection/files/core-strands/gateway/agentcore-gateway-mcp-client-strands.ts.template +26 -0
  842. package/src/utils/agent-connection/files/core-strands/mcp/agentcore-mcp-client-strands.ts.template +27 -0
  843. package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client_config.py.template +43 -0
  844. package/src/utils/agent-connection/files/py-core-auth/agentcore_endpoints.py.template +47 -0
  845. package/src/utils/agent-connection/files/py-core-auth/auth/session.py.template +51 -0
  846. package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_transport.py.template +28 -0
  847. package/src/utils/agent-connection/files/py-core-langchain/a2a/agentcore_a2a_client_langchain.py.template +99 -0
  848. package/src/utils/agent-connection/files/py-core-langchain/gateway/agentcore_gateway_mcp_client_langchain.py.template +57 -0
  849. package/src/utils/agent-connection/files/py-core-langchain/mcp/agentcore_mcp_client_langchain.py.template +64 -0
  850. package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_transport.py.template +34 -0
  851. package/src/utils/agent-connection/files/py-core-runtime-config/runtime_config.py.template +5 -18
  852. package/src/utils/agent-connection/files/py-core-shared/agentcore_transport.py.template +40 -0
  853. package/src/utils/agent-connection/files/py-core-strands/a2a/agentcore_a2a_client_strands.py.template +66 -0
  854. package/src/utils/agent-connection/files/py-core-strands/base/model_errors_strands.py.template +40 -0
  855. package/src/utils/agent-connection/files/py-core-strands/gateway/agentcore_gateway_mcp_client_strands.py.template +22 -0
  856. package/src/utils/agent-connection/files/py-core-strands/mcp/agentcore_mcp_client_strands.py.template +30 -0
  857. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +11 -3
  858. package/src/utils/agent-core-constructs/agent-core-constructs.js +93 -38
  859. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  860. package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +31 -4
  861. package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +50 -0
  862. package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +487 -0
  863. package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/readiness-probe/index.js.template +55 -0
  864. package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +32 -0
  865. package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +449 -0
  866. package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/render-cedar.cjs.template +13 -0
  867. package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +151 -13
  868. package/src/utils/agent-core-constructs/files/terraform/core/agentcore-gateway/gateway.tf.template +14 -0
  869. package/src/utils/api-constructs/api-constructs.d.ts +2 -2
  870. package/src/utils/api-constructs/api-constructs.js +36 -31
  871. package/src/utils/api-constructs/api-constructs.js.map +1 -1
  872. package/src/utils/api-constructs/files/cdk/app/apis/http/__apiNameKebabCase__.ts.template +8 -8
  873. package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +11 -8
  874. package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +26 -9
  875. package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account/index.js.template +70 -0
  876. package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account.ts.template +82 -0
  877. package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +54 -18
  878. package/src/utils/api-constructs/files/cdk/core/api/trpc/trpc-utils.ts.template +1 -1
  879. package/src/utils/api-constructs/files/cdk/core/api/utils/utils.ts.template +61 -7
  880. package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +101 -12
  881. package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +194 -8
  882. package/src/utils/api-constructs/files/terraform/core/api/http/http-api/http-api.tf.template +1 -1
  883. package/src/utils/api-constructs/files/terraform/core/api/rest/api-gateway-account/api-gateway-account.tf.template +83 -0
  884. package/src/utils/api-constructs/files/terraform/core/api/rest/rest-api/rest-api.tf.template +5 -11
  885. package/src/utils/api-constructs/open-api-metadata.d.ts +2 -2
  886. package/src/utils/api-constructs/open-api-metadata.js +22 -22
  887. package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
  888. package/src/utils/ast/website.d.ts +5 -1
  889. package/src/utils/ast/website.js +18 -20
  890. package/src/utils/ast/website.js.map +1 -1
  891. package/src/utils/ast.d.ts +33 -1
  892. package/src/utils/ast.js +146 -70
  893. package/src/utils/ast.js.map +1 -1
  894. package/src/utils/base-tsconfig.d.ts +30 -0
  895. package/src/utils/base-tsconfig.js +32 -0
  896. package/src/utils/base-tsconfig.js.map +1 -0
  897. package/src/utils/bundle/bundle.d.ts +1 -1
  898. package/src/utils/bundle/bundle.js +50 -47
  899. package/src/utils/bundle/bundle.js.map +1 -1
  900. package/src/utils/commands.d.ts +10 -3
  901. package/src/utils/commands.js +60 -26
  902. package/src/utils/commands.js.map +1 -1
  903. package/src/utils/config/index.d.ts +5 -5
  904. package/src/utils/config/index.js +5 -4
  905. package/src/utils/config/index.js.map +1 -1
  906. package/src/utils/config/utils.d.ts +13 -3
  907. package/src/utils/config/utils.js +65 -43
  908. package/src/utils/config/utils.js.map +1 -1
  909. package/src/utils/connection/open-api/files/components/__apiNameClassName__Provider.tsx.template +1 -1
  910. package/src/utils/connection/open-api/react.d.ts +6 -6
  911. package/src/utils/connection/open-api/react.js +81 -77
  912. package/src/utils/connection/open-api/react.js.map +1 -1
  913. package/src/utils/containers.d.ts +1 -1
  914. package/src/utils/containers.js +22 -23
  915. package/src/utils/containers.js.map +1 -1
  916. package/src/utils/docker.d.ts +44 -0
  917. package/src/utils/docker.js +81 -0
  918. package/src/utils/docker.js.map +1 -0
  919. package/src/utils/dynamodb-constructs/dynamodb-constructs.d.ts +3 -3
  920. package/src/utils/dynamodb-constructs/dynamodb-constructs.js +39 -41
  921. package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -1
  922. package/src/utils/dynamodb-constructs/files/cdk/app/dynamodb/__nameKebabCase__.ts.template +18 -5
  923. package/src/utils/dynamodb-constructs/files/cdk/core/dynamodb.ts.template +1 -1
  924. package/src/utils/dynamodb-constructs/files/terraform/app/dynamodb/__nameKebabCase__/__nameKebabCase__.tf.template +24 -17
  925. package/src/utils/dynamodb-constructs/files/terraform/core/dynamodb/dynamodb.tf.template +1 -1
  926. package/src/utils/files/common/constructs/src/core/index.ts.template +4 -4
  927. package/src/utils/files/common/constructs/src/index.ts.template +2 -2
  928. package/src/utils/files/common/infra-config/src/index.ts.template +3 -3
  929. package/src/utils/files/common/infra-config/src/resolve-stage.ts.template +2 -2
  930. package/src/utils/files/common/infra-config/src/stages.config.ts.template +1 -1
  931. package/src/{ts/dynamodb/files/scripts → utils/files/common/scripts/src/dynamodb}/create-local-table.ts.template +65 -31
  932. package/src/utils/files/common/scripts/src/dynamodb/pull-image.ts.template +13 -0
  933. package/src/utils/files/common/scripts/src/dynamodb/start-container.ts.template +106 -0
  934. package/src/utils/files/common/scripts/src/infra/infra-deploy.ts.template +2 -0
  935. package/src/utils/files/common/scripts/src/infra/infra-destroy.ts.template +2 -0
  936. package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/cdk-command.ts.template +6 -3
  937. package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/run.ts.template +3 -3
  938. package/src/utils/files/common/scripts/src/rdb/mysql/wait-for-mysql-db.ts.template +32 -0
  939. package/src/utils/files/common/scripts/src/rdb/postgres/wait-for-postgres-db.ts.template +32 -0
  940. package/src/utils/files/common/scripts/src/rdb/shared/pull-image.ts.template +16 -0
  941. package/src/utils/files/common/scripts/src/rdb/shared/start-container.ts.template +117 -0
  942. package/src/utils/files/common/shadcn/src/index.ts.template +2 -2
  943. package/src/utils/files/terraform/src/core/asset-bucket/asset-bucket.tf.template +63 -72
  944. package/src/utils/files/terraform/src/core/runtime-config/appconfig/appconfig.tf.template +1 -1
  945. package/src/utils/files/terraform/src/core/runtime-config/appconfig-deployment/appconfig-deployment.tf.template +12 -6
  946. package/src/utils/files/terraform/src/core/runtime-config/entry/entry.tf.template +1 -1
  947. package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +9 -4
  948. package/src/utils/files/website/hooks/sigv4/useSigV4.tsx.template +1 -1
  949. package/src/utils/format.d.ts +45 -2
  950. package/src/utils/format.js +332 -81
  951. package/src/utils/format.js.map +1 -1
  952. package/src/utils/fs.d.ts +1 -1
  953. package/src/utils/fs.js +14 -13
  954. package/src/utils/fs.js.map +1 -1
  955. package/src/utils/function-constructs/files/cdk/app/lambda-functions/__nameKebabCase__.ts.template +1 -1
  956. package/src/utils/function-constructs/files/terraform/app/lambda-functions/__nameKebabCase__/__nameKebabCase__.tf.template +2 -2
  957. package/src/utils/function-constructs/function-constructs.d.ts +2 -2
  958. package/src/utils/function-constructs/function-constructs.js +22 -25
  959. package/src/utils/function-constructs/function-constructs.js.map +1 -1
  960. package/src/utils/generators.d.ts +4 -0
  961. package/src/utils/generators.js +18 -20
  962. package/src/utils/generators.js.map +1 -1
  963. package/src/utils/git.d.ts +1 -1
  964. package/src/utils/git.js +19 -34
  965. package/src/utils/git.js.map +1 -1
  966. package/src/utils/iac-providers.js +5 -5
  967. package/src/utils/iac-providers.js.map +1 -1
  968. package/src/utils/iac.d.ts +1 -1
  969. package/src/utils/iac.js +12 -14
  970. package/src/utils/iac.js.map +1 -1
  971. package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +125 -16
  972. package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +28 -9
  973. package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +106 -6
  974. package/src/utils/identity-constructs/files/terraform/core/user-identity/main.tf.template +7 -0
  975. package/src/utils/identity-constructs/identity-constructs.d.ts +2 -2
  976. package/src/utils/identity-constructs/identity-constructs.js +28 -28
  977. package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
  978. package/src/utils/init.d.ts +53 -0
  979. package/src/utils/init.js +252 -0
  980. package/src/utils/init.js.map +1 -0
  981. package/src/utils/install.d.ts +32 -0
  982. package/src/utils/install.js +56 -0
  983. package/src/utils/install.js.map +1 -0
  984. package/src/utils/js.d.ts +4 -0
  985. package/src/utils/js.js +27 -20
  986. package/src/utils/js.js.map +1 -1
  987. package/src/utils/mcp.d.ts +1 -1
  988. package/src/utils/mcp.js +34 -41
  989. package/src/utils/mcp.js.map +1 -1
  990. package/src/utils/metrics.d.ts +9 -3
  991. package/src/utils/metrics.js +61 -46
  992. package/src/utils/metrics.js.map +1 -1
  993. package/src/utils/mock-project-graph.js +8 -12
  994. package/src/utils/mock-project-graph.js.map +1 -1
  995. package/src/utils/module-format.d.ts +28 -0
  996. package/src/utils/module-format.js +28 -0
  997. package/src/utils/module-format.js.map +1 -0
  998. package/src/utils/names.d.ts +22 -0
  999. package/src/utils/names.js +44 -48
  1000. package/src/utils/names.js.map +1 -1
  1001. package/src/utils/npm-scope.d.ts +1 -1
  1002. package/src/utils/npm-scope.js +9 -17
  1003. package/src/utils/npm-scope.js.map +1 -1
  1004. package/src/utils/nx.d.ts +39 -4
  1005. package/src/utils/nx.js +169 -75
  1006. package/src/utils/nx.js.map +1 -1
  1007. package/src/utils/nxlv-python.d.ts +1 -1
  1008. package/src/utils/nxlv-python.js +27 -15
  1009. package/src/utils/nxlv-python.js.map +1 -1
  1010. package/src/utils/object.js +5 -11
  1011. package/src/utils/object.js.map +1 -1
  1012. package/src/utils/paths.d.ts +1 -1
  1013. package/src/utils/paths.js +11 -15
  1014. package/src/utils/paths.js.map +1 -1
  1015. package/src/utils/pkg-manager.js +4 -9
  1016. package/src/utils/pkg-manager.js.map +1 -1
  1017. package/src/utils/pnpm-workspace.d.ts +1 -1
  1018. package/src/utils/pnpm-workspace.js +22 -22
  1019. package/src/utils/pnpm-workspace.js.map +1 -1
  1020. package/src/utils/port.d.ts +29 -7
  1021. package/src/utils/port.js +67 -28
  1022. package/src/utils/port.js.map +1 -1
  1023. package/src/utils/py.d.ts +16 -3
  1024. package/src/utils/py.js +72 -47
  1025. package/src/utils/py.js.map +1 -1
  1026. package/src/utils/rdb-constructs/files/cdk/app/dbs/__nameKebabCase__.ts.template +72 -18
  1027. package/src/utils/rdb-constructs/files/cdk/core/rdb/aurora.ts.template +97 -88
  1028. package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +127 -53
  1029. package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +36 -48
  1030. package/src/utils/rdb-constructs/rdb-constructs.d.ts +16 -5
  1031. package/src/utils/rdb-constructs/rdb-constructs.js +38 -41
  1032. package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
  1033. package/src/utils/shared-constructs-constants.d.ts +1 -0
  1034. package/src/utils/shared-constructs-constants.js +16 -15
  1035. package/src/utils/shared-constructs-constants.js.map +1 -1
  1036. package/src/utils/shared-constructs.d.ts +2 -2
  1037. package/src/utils/shared-constructs.js +60 -67
  1038. package/src/utils/shared-constructs.js.map +1 -1
  1039. package/src/utils/shared-dynamodb-scripts.d.ts +11 -0
  1040. package/src/utils/shared-dynamodb-scripts.js +25 -0
  1041. package/src/utils/shared-dynamodb-scripts.js.map +1 -0
  1042. package/src/utils/shared-infra-config.d.ts +1 -1
  1043. package/src/utils/shared-infra-config.js +31 -30
  1044. package/src/utils/shared-infra-config.js.map +1 -1
  1045. package/src/utils/shared-infra-scripts.d.ts +11 -0
  1046. package/src/utils/shared-infra-scripts.js +42 -0
  1047. package/src/utils/shared-infra-scripts.js.map +1 -0
  1048. package/src/utils/shared-rdb-scripts.d.ts +16 -0
  1049. package/src/utils/shared-rdb-scripts.js +32 -0
  1050. package/src/utils/shared-rdb-scripts.js.map +1 -0
  1051. package/src/utils/shared-scripts.d.ts +2 -5
  1052. package/src/utils/shared-scripts.js +12 -38
  1053. package/src/utils/shared-scripts.js.map +1 -1
  1054. package/src/utils/shared-shadcn.d.ts +1 -1
  1055. package/src/utils/shared-shadcn.js +65 -71
  1056. package/src/utils/shared-shadcn.js.map +1 -1
  1057. package/src/utils/test.d.ts +15 -1
  1058. package/src/utils/test.js +41 -23
  1059. package/src/utils/test.js.map +1 -1
  1060. package/src/utils/toml.d.ts +1 -1
  1061. package/src/utils/toml.js +10 -14
  1062. package/src/utils/toml.js.map +1 -1
  1063. package/src/utils/versions.d.ts +150 -97
  1064. package/src/utils/versions.js +157 -115
  1065. package/src/utils/versions.js.map +1 -1
  1066. package/src/utils/warm-ruff-cache.d.ts +12 -0
  1067. package/src/utils/warm-ruff-cache.js +39 -0
  1068. package/src/utils/warm-ruff-cache.js.map +1 -0
  1069. package/src/utils/website-constructs/files/cdk/app/static-websites/__websiteNameKebabCase__.ts.template +2 -2
  1070. package/src/utils/website-constructs/files/cdk/core/static-website.ts.template +200 -41
  1071. package/src/utils/website-constructs/files/terraform/app/static-websites/__websiteNameKebabCase__/__websiteNameKebabCase__.tf.template +1 -1
  1072. package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +145 -93
  1073. package/src/utils/website-constructs/website-constructs.d.ts +2 -2
  1074. package/src/utils/website-constructs/website-constructs.js +38 -30
  1075. package/src/utils/website-constructs/website-constructs.js.map +1 -1
  1076. package/bin/aws-nx-mcp.js +0 -17
  1077. package/bin/aws-nx-mcp.js.map +0 -1
  1078. package/sdk/connection.d.ts +0 -6
  1079. package/sdk/connection.js +0 -10
  1080. package/sdk/connection.js.map +0 -1
  1081. package/sdk/open-api.d.ts +0 -10
  1082. package/sdk/open-api.js +0 -15
  1083. package/sdk/open-api.js.map +0 -1
  1084. package/sdk/py.d.ts +0 -14
  1085. package/sdk/py.js +0 -18
  1086. package/sdk/py.js.map +0 -1
  1087. package/sdk/terraform.d.ts +0 -6
  1088. package/sdk/terraform.js +0 -11
  1089. package/sdk/terraform.js.map +0 -1
  1090. package/sdk/ts.d.ts +0 -29
  1091. package/sdk/ts.js +0 -47
  1092. package/sdk/ts.js.map +0 -1
  1093. package/sdk/utils/ast.js +0 -12
  1094. package/sdk/utils/ast.js.map +0 -1
  1095. package/sdk/utils/format.js +0 -10
  1096. package/sdk/utils/format.js.map +0 -1
  1097. package/sdk/utils/test.js +0 -10
  1098. package/sdk/utils/test.js.map +0 -1
  1099. package/src/connection/agent-serve-local.js +0 -48
  1100. package/src/connection/agent-serve-local.js.map +0 -1
  1101. package/src/connection/serve-local.d.ts +0 -15
  1102. package/src/connection/serve-local.js +0 -41
  1103. package/src/connection/serve-local.js.map +0 -1
  1104. package/src/py/agent/a2a-connection/files/agent-connection/app/__targetAgentSnakeCase___client.py.template +0 -22
  1105. package/src/py/agent/mcp-connection/files/agent-connection/app/__mcpServerSnakeCase___client.py.template +0 -22
  1106. package/src/py/agent/react-connection/serve-local.js +0 -30
  1107. package/src/py/agent/react-connection/serve-local.js.map +0 -1
  1108. package/src/py/agent/scripts/http/chat.ts.template +0 -38
  1109. package/src/ts/agent/a2a-connection/files/agent-connection/app/__targetAgentKebabCase__-client.ts.template +0 -19
  1110. package/src/ts/agent/mcp-connection/files/agent-connection/app/__mcpServerKebabCase__-client.ts.template +0 -19
  1111. package/src/ts/agent/react-connection/serve-local.d.ts +0 -13
  1112. package/src/ts/agent/react-connection/serve-local.js +0 -19
  1113. package/src/ts/agent/react-connection/serve-local.js.map +0 -1
  1114. package/src/ts/agent/scripts/http/chat.ts.template +0 -35
  1115. package/src/ts/dynamodb/files/scripts/pull-image.ts.template +0 -15
  1116. package/src/ts/dynamodb/files/scripts/start-container.ts.template +0 -81
  1117. package/src/ts/dynamodb/files/src/constants.ts.template +0 -9
  1118. package/src/ts/dynamodb/files/src/gsi.ts.template +0 -14
  1119. package/src/ts/lib/eslint.d.ts +0 -14
  1120. package/src/ts/lib/eslint.js +0 -90
  1121. package/src/ts/lib/eslint.js.map +0 -1
  1122. package/src/ts/lib/grit/eslint-dependency-checks-warn.grit +0 -1
  1123. package/src/ts/rdb/files/scripts/docker-pull.ts.template +0 -15
  1124. package/src/ts/rdb/files/scripts/docker-start.ts.template +0 -84
  1125. package/src/ts/rdb/files/scripts/wait-for-db.ts.template +0 -55
  1126. package/src/ts/rdb/files/src/constants.ts.template +0 -8
  1127. package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client.ts.template +0 -123
  1128. package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-client.ts.template +0 -128
  1129. package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client.py.template +0 -120
  1130. package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_client.py.template +0 -89
  1131. package/src/utils/files/common/scripts/src/infra-deploy.ts.template +0 -2
  1132. package/src/utils/files/common/scripts/src/infra-destroy.ts.template +0 -2
  1133. package/src/utils/files/terraform/scripts/reset-runtime-config.ts.template +0 -25
  1134. /package/{bin → src/bin}/aws-nx-mcp.d.ts +0 -0
  1135. /package/src/utils/agent-connection/files/{py-core-runtime-config/with_session_id.py.template → py-core-strands/base/with_session_id_strands.py.template} +0 -0
  1136. /package/src/utils/files/common/scripts/src/{index.ts.template → infra/index.ts.template} +0 -0
  1137. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/credentials.ts.template +0 -0
  1138. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/stage-parser.ts.template +0 -0
@@ -0,0 +1,2038 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`py#rdb generator > should generate MySQL dependencies and templates 1`] = `
4
+ "import ssl
5
+ from collections.abc import AsyncGenerator
6
+ from contextlib import asynccontextmanager
7
+
8
+ import boto3
9
+ from sqlalchemy import event
10
+ from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
11
+
12
+ from .utils import build_database_url, get_database_config, get_local_dev_config, is_local_dev
13
+
14
+ # Generated: must match runtimeConfigKey in config.json
15
+ _runtime_config_key = "Db"
16
+
17
+ _engine = None
18
+
19
+
20
+ def get_engine():
21
+ global _engine
22
+ if _engine is not None:
23
+ return _engine
24
+ if is_local_dev():
25
+ cfg = get_local_dev_config()
26
+ url = build_database_url(cfg["dbUser"], cfg["host"], cfg["port"], cfg["dbName"])
27
+ ssl_args: dict = {}
28
+ else:
29
+ config = get_database_config(_runtime_config_key)
30
+ url = build_database_url(
31
+ config["dbUser"],
32
+ config["hostname"],
33
+ config["port"],
34
+ config["database"],
35
+ )
36
+ ssl_args = {"ssl": ssl.create_default_context()}
37
+ _engine = create_async_engine(url, connect_args=ssl_args)
38
+
39
+ @event.listens_for(_engine.sync_engine, "do_connect")
40
+ def provide_password(_dialect, _connection_record, _cargs, connection_params):
41
+ if is_local_dev():
42
+ connection_params["password"] = get_local_dev_config()["dbPassword"]
43
+ else:
44
+ config = get_database_config(_runtime_config_key)
45
+ connection_params["password"] = boto3.client(
46
+ "rds",
47
+ region_name=config["region"],
48
+ ).generate_db_auth_token(
49
+ DBHostname=config["hostname"],
50
+ Port=config["port"],
51
+ DBUsername=config["dbUser"],
52
+ )
53
+
54
+ return _engine
55
+
56
+
57
+ @asynccontextmanager
58
+ async def session_context() -> AsyncGenerator[AsyncSession]:
59
+ async with AsyncSession(get_engine()) as session:
60
+ yield session
61
+ "
62
+ `;
63
+
64
+ exports[`py#rdb generator > should generate MySQL dependencies and templates 2`] = `
65
+ "import asyncio
66
+ import ssl
67
+
68
+ from alembic import command
69
+ from alembic.config import Config
70
+ from sqlalchemy.ext.asyncio import create_async_engine
71
+ from sqlalchemy.pool import NullPool
72
+
73
+ from .utils import build_database_url, get_database_secret, with_connection_retry
74
+
75
+
76
+ def _apply_migrations(sync_conn, alembic_cfg: Config) -> None:
77
+ alembic_cfg.attributes["connection"] = sync_conn
78
+ command.upgrade(alembic_cfg, "head")
79
+
80
+
81
+ async def _run_migrations() -> None:
82
+ secret = get_database_secret()
83
+ database_url = build_database_url(
84
+ secret["username"],
85
+ secret["host"],
86
+ secret["port"],
87
+ secret["dbname"],
88
+ password=secret["password"],
89
+ )
90
+ alembic_cfg = Config("alembic.ini")
91
+ engine = create_async_engine(
92
+ database_url,
93
+ poolclass=NullPool,
94
+ connect_args={"ssl": ssl.create_default_context()},
95
+ )
96
+ try:
97
+ async with engine.begin() as conn:
98
+ await conn.run_sync(lambda c: _apply_migrations(c, alembic_cfg))
99
+ finally:
100
+ await engine.dispose()
101
+
102
+
103
+ def handler(_event, _context):
104
+ with_connection_retry(lambda: asyncio.run(_run_migrations()))
105
+ "
106
+ `;
107
+
108
+ exports[`py#rdb generator > should generate MySQL dependencies and templates 3`] = `
109
+ "import asyncio
110
+ import secrets
111
+ import ssl
112
+ from typing import Any
113
+
114
+ import aiomysql
115
+
116
+ from .utils import get_database_secret, with_connection_retry
117
+
118
+
119
+ async def _ensure_database_user(db_user: str) -> None:
120
+ secret = get_database_secret()
121
+ conn = await aiomysql.connect(
122
+ host=secret["host"],
123
+ port=int(secret["port"]),
124
+ db=secret["dbname"],
125
+ user=secret["username"],
126
+ password=secret["password"],
127
+ ssl=ssl.create_default_context(),
128
+ )
129
+ try:
130
+ async with conn.cursor() as cursor:
131
+ await cursor.execute(
132
+ "CREATE USER IF NOT EXISTS %s@'%%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'",
133
+ (db_user,),
134
+ )
135
+ await cursor.execute(
136
+ "ALTER USER %s@'%%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS' REQUIRE SSL",
137
+ (db_user,),
138
+ )
139
+ await cursor.execute(
140
+ f"GRANT SELECT, INSERT, UPDATE, DELETE ON \`{secret['dbname']}\`.* TO %s@'%%'",
141
+ (db_user,),
142
+ )
143
+ await conn.commit()
144
+ finally:
145
+ conn.close()
146
+
147
+
148
+ _PHYSICAL_RESOURCE_ID_PREFIX = "db-user:"
149
+
150
+
151
+ def _resolve_db_user(physical_resource_id: str | None) -> str:
152
+ if physical_resource_id and physical_resource_id.startswith(_PHYSICAL_RESOURCE_ID_PREFIX):
153
+ return physical_resource_id[len(_PHYSICAL_RESOURCE_ID_PREFIX) :]
154
+ return f"db_{secrets.token_hex(8)}"
155
+
156
+
157
+ def handler(event: dict[str, Any], _context: Any) -> dict[str, Any]:
158
+ db_user = _resolve_db_user(event.get("PhysicalResourceId"))
159
+
160
+ if event.get("RequestType") != "Delete":
161
+ with_connection_retry(lambda: asyncio.run(_ensure_database_user(db_user)))
162
+
163
+ return {
164
+ "PhysicalResourceId": f"{_PHYSICAL_RESOURCE_ID_PREFIX}{db_user}",
165
+ "Data": {"dbUser": db_user},
166
+ }
167
+ "
168
+ `;
169
+
170
+ exports[`py#rdb generator > should generate MySQL dependencies and templates 4`] = `
171
+ "FROM public.ecr.aws/lambda/python:3.14
172
+
173
+ WORKDIR \${LAMBDA_TASK_ROOT}
174
+
175
+ COPY . .
176
+
177
+ ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /etc/pki/ca-trust/source/anchors/global-bundle.pem
178
+ RUN update-ca-trust
179
+
180
+ CMD ["proj_db.migration_handler.handler"]
181
+ "
182
+ `;
183
+
184
+ exports[`py#rdb generator > should generate MySQL dependencies and templates 5`] = `
185
+ "FROM public.ecr.aws/lambda/python:3.14
186
+
187
+ WORKDIR \${LAMBDA_TASK_ROOT}
188
+
189
+ COPY . .
190
+
191
+ ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /etc/pki/ca-trust/source/anchors/global-bundle.pem
192
+ RUN update-ca-trust
193
+
194
+ CMD ["proj_db.create_db_user_handler.handler"]
195
+ "
196
+ `;
197
+
198
+ exports[`py#rdb generator > should generate Terraform modules 1`] = `
199
+ "terraform {
200
+ required_version = ">= 1.0"
201
+
202
+ required_providers {
203
+ archive = {
204
+ source = "hashicorp/archive"
205
+ version = "2.8.0"
206
+ }
207
+ aws = {
208
+ source = "hashicorp/aws"
209
+ version = "6.54.0"
210
+ }
211
+ null = {
212
+ source = "hashicorp/null"
213
+ version = "3.3.0"
214
+ }
215
+ random = {
216
+ source = "hashicorp/random"
217
+ version = "3.9.0"
218
+ }
219
+ }
220
+ }
221
+
222
+ variable "vpc_id" {
223
+ description = "VPC where the Aurora cluster will be deployed."
224
+ type = string
225
+ }
226
+
227
+ variable "database_subnet_ids" {
228
+ description = "Subnet IDs for the Aurora cluster and RDS Proxy. Private isolated subnets are fine — no outbound egress required."
229
+ type = list(string)
230
+ }
231
+
232
+ variable "lambda_subnet_ids" {
233
+ description = "Subnet IDs for the create-db-user and migration Lambda functions. Must have outbound egress to AWS service endpoints (e.g. Secrets Manager) — use private subnets with a NAT gateway."
234
+ type = list(string)
235
+ }
236
+
237
+ variable "engine_version" {
238
+ description = "Aurora engine version."
239
+ type = string
240
+ default = null
241
+ }
242
+
243
+ variable "port" {
244
+ description = "Database port for the selected Aurora engine."
245
+ type = number
246
+ default = null
247
+ }
248
+
249
+ variable "serverless_min_capacity" {
250
+ description = "Minimum Aurora Serverless v2 ACUs."
251
+ type = number
252
+ default = 0.5
253
+ }
254
+
255
+ variable "serverless_max_capacity" {
256
+ description = "Maximum Aurora Serverless v2 ACUs."
257
+ type = number
258
+ default = 4
259
+ }
260
+
261
+ variable "instance_count" {
262
+ description = "Number of Aurora instances to create."
263
+ type = number
264
+ default = 1
265
+ }
266
+
267
+ variable "deletion_protection" {
268
+ description = "Whether deletion protection is enabled."
269
+ type = bool
270
+ default = true
271
+ }
272
+
273
+ variable "skip_final_snapshot" {
274
+ description = "Whether to skip the final snapshot on deletion."
275
+ type = bool
276
+ default = false
277
+ }
278
+
279
+ variable "enable_rds_proxy" {
280
+ description = "Whether to provision an RDS Proxy in front of the Aurora cluster."
281
+ type = bool
282
+ default = true
283
+ }
284
+
285
+ variable "enable_credential_rotation" {
286
+ description = "Whether to enable automatic credential rotation for the admin secret."
287
+ type = bool
288
+ default = true
289
+ }
290
+
291
+ variable "enable_cloudwatch_logs" {
292
+ description = "Whether to export Aurora engine logs to CloudWatch. PostgreSQL also enables verbose statement logging."
293
+ type = bool
294
+ default = false
295
+ }
296
+
297
+ variable "enable_performance_insights" {
298
+ description = "Whether to enable Performance Insights on Aurora cluster instances."
299
+ type = bool
300
+ default = true
301
+ }
302
+
303
+ variable "performance_insights_retention_period" {
304
+ description = "Retention period, in days, for Performance Insights data when enabled."
305
+ type = number
306
+ default = 7
307
+ }
308
+
309
+ variable "enable_backup" {
310
+ description = "Whether to provision an AWS Backup plan for the Aurora cluster."
311
+ type = bool
312
+ default = false
313
+ }
314
+
315
+ variable "tags" {
316
+ description = "Tags to apply to all resources."
317
+ type = map(string)
318
+ default = {}
319
+ }
320
+
321
+ variable "migration_docker_image_tag" {
322
+ description = "Docker image tag for the migration handler. Defaults to the tag built by the Nx docker target."
323
+ type = string
324
+ default = "proj-db-migration:latest"
325
+ }
326
+
327
+ variable "create_db_user_docker_image_tag" {
328
+ description = "Docker image tag for the Python create-db-user handler. Defaults to the tag built by the Nx docker target."
329
+ type = string
330
+ default = "proj-db-create-db-user:latest"
331
+ }
332
+
333
+
334
+ data "aws_region" "current" {}
335
+ data "aws_caller_identity" "current" {}
336
+
337
+ resource "random_string" "suffix" {
338
+ length = 8
339
+ special = false
340
+ upper = false
341
+ }
342
+
343
+ locals {
344
+ config = jsondecode(file("\${path.module}/../../../../../../../packages/db/config.json"))
345
+ runtime_config_key = local.config.runtimeConfigKey
346
+ migration_function_name = "db-migration-\${random_string.suffix.result}"
347
+ create_db_user_function_name = "db-create-db-user-\${random_string.suffix.result}"
348
+ database_runtime_user = "db_\${random_string.suffix.result}"
349
+ }
350
+
351
+ module "aurora" {
352
+ source = "../../../core/rdb/aurora"
353
+ #checkov:skip=CKV_AWS_139:Deletion protection is enabled but checkov is unable to detect it correctly
354
+ name = "db"
355
+ vpc_id = var.vpc_id
356
+ subnet_ids = var.database_subnet_ids
357
+ lambda_subnet_ids = var.lambda_subnet_ids
358
+ engine = "aurora-postgresql"
359
+ engine_version = var.engine_version
360
+ database_name = "database_name"
361
+ admin_user = "databaseUser"
362
+ port = var.port
363
+ serverless_min_capacity = var.serverless_min_capacity
364
+ serverless_max_capacity = var.serverless_max_capacity
365
+ instance_count = var.instance_count
366
+ deletion_protection = var.deletion_protection
367
+ skip_final_snapshot = var.skip_final_snapshot
368
+ enable_rds_proxy = var.enable_rds_proxy
369
+ enable_credential_rotation = var.enable_credential_rotation
370
+ enable_cloudwatch_logs = var.enable_cloudwatch_logs
371
+ enable_performance_insights = var.enable_performance_insights
372
+ performance_insights_retention_period = var.performance_insights_retention_period
373
+ enable_backup = var.enable_backup
374
+ tags = var.tags
375
+ }
376
+
377
+ resource "aws_iam_role_policy" "proxy_db_user_connect" {
378
+ count = var.enable_rds_proxy ? 1 : 0
379
+
380
+ role = module.aurora.proxy_role_name
381
+
382
+ policy = jsonencode({
383
+ Version = "2012-10-17"
384
+ Statement = [
385
+ {
386
+ Effect = "Allow"
387
+ Action = ["rds-db:connect"]
388
+ Resource = [
389
+ "arn:aws:rds-db:\${data.aws_region.current.region}:\${data.aws_caller_identity.current.account_id}:dbuser:\${module.aurora.cluster_resource_id}/\${local.database_runtime_user}"
390
+ ]
391
+ }
392
+ ]
393
+ })
394
+ }
395
+
396
+
397
+ module "add_rdb_to_runtime_config" {
398
+ source = "../../../core/runtime-config/entry"
399
+
400
+ namespace = "database"
401
+ key = local.runtime_config_key
402
+ value = {
403
+ hostname = module.aurora.cluster_endpoint
404
+ port = module.aurora.cluster_port
405
+ database = module.aurora.database_name
406
+ adminUser = module.aurora.admin_user
407
+ dbUser = local.database_runtime_user
408
+ region = data.aws_region.current.region
409
+ }
410
+ }
411
+
412
+ resource "aws_ecr_repository" "migration_handler" {
413
+ #checkov:skip=CKV_AWS_136:AES256 encryption is sufficient for ECR repositories
414
+ name = "db-migration-\${random_string.suffix.result}"
415
+ image_tag_mutability = "IMMUTABLE"
416
+ force_delete = true
417
+
418
+ image_scanning_configuration {
419
+ scan_on_push = true
420
+ }
421
+
422
+ tags = var.tags
423
+ }
424
+
425
+ resource "aws_ecr_repository_policy" "migration_handler" {
426
+ repository = aws_ecr_repository.migration_handler.name
427
+
428
+ policy = jsonencode({
429
+ Version = "2012-10-17"
430
+ Statement = [
431
+ {
432
+ Sid = "AllowPushPull"
433
+ Effect = "Allow"
434
+ Principal = {
435
+ AWS = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:root"
436
+ }
437
+ Action = [
438
+ "ecr:BatchCheckLayerAvailability",
439
+ "ecr:CompleteLayerUpload",
440
+ "ecr:GetDownloadUrlForLayer",
441
+ "ecr:InitiateLayerUpload",
442
+ "ecr:PutImage",
443
+ "ecr:UploadLayerPart"
444
+ ]
445
+ },
446
+ {
447
+ Sid = "AllowLambdaPull"
448
+ Effect = "Allow"
449
+ Principal = {
450
+ Service = "lambda.amazonaws.com"
451
+ }
452
+ Action = [
453
+ "ecr:BatchCheckLayerAvailability",
454
+ "ecr:BatchGetImage",
455
+ "ecr:GetDownloadUrlForLayer"
456
+ ]
457
+ }
458
+ ]
459
+ })
460
+ }
461
+
462
+ data "external" "docker_digest" {
463
+ program = ["sh", "-c", "echo '{\\"digest\\":\\"'$(docker inspect \${var.migration_docker_image_tag} --format '{{.Id}}')'\\"}' "]
464
+ }
465
+
466
+ locals {
467
+ # Content-based, immutable image tag derived from the local image digest
468
+ image_tag = replace(data.external.docker_digest.result.digest, "sha256:", "")
469
+ }
470
+ data "external" "create_db_user_docker_digest" {
471
+ program = ["sh", "-c", "echo '{\\"digest\\":\\"'$(docker inspect \${var.create_db_user_docker_image_tag} --format '{{.Id}}')'\\"}' "]
472
+ }
473
+
474
+ locals {
475
+ create_db_user_image_tag = replace(data.external.create_db_user_docker_digest.result.digest, "sha256:", "")
476
+ }
477
+
478
+ resource "null_resource" "docker_publish" {
479
+ triggers = {
480
+ docker_digest = data.external.docker_digest.result.digest
481
+ repository_url = aws_ecr_repository.migration_handler.repository_url
482
+ migration_docker_image_tag = var.migration_docker_image_tag
483
+ image_tag = local.image_tag
484
+ create_db_user_docker_digest = data.external.create_db_user_docker_digest.result.digest
485
+ create_db_user_docker_image_tag = var.create_db_user_docker_image_tag
486
+ create_db_user_image_tag = local.create_db_user_image_tag
487
+ }
488
+
489
+ provisioner "local-exec" {
490
+ command = <<-EOT
491
+ aws ecr get-login-password --region "$AWS_REGION" | docker login --username AWS --password-stdin "$REPOSITORY_URL"
492
+ docker tag "$MIGRATION_DOCKER_IMAGE_TAG" "$REPOSITORY_URL:$IMAGE_TAG"
493
+ docker push "$REPOSITORY_URL:$IMAGE_TAG"
494
+ docker tag "$CREATE_DB_USER_DOCKER_IMAGE_TAG" "$REPOSITORY_URL:create-db-user-$CREATE_DB_USER_IMAGE_TAG"
495
+ docker push "$REPOSITORY_URL:create-db-user-$CREATE_DB_USER_IMAGE_TAG"
496
+ EOT
497
+ environment = {
498
+ AWS_REGION = data.aws_region.current.region
499
+ REPOSITORY_URL = self.triggers.repository_url
500
+ MIGRATION_DOCKER_IMAGE_TAG = self.triggers.migration_docker_image_tag
501
+ IMAGE_TAG = self.triggers.image_tag
502
+ CREATE_DB_USER_DOCKER_IMAGE_TAG = self.triggers.create_db_user_docker_image_tag
503
+ CREATE_DB_USER_IMAGE_TAG = self.triggers.create_db_user_image_tag
504
+ }
505
+ }
506
+
507
+ depends_on = [aws_ecr_repository_policy.migration_handler]
508
+ }
509
+
510
+ resource "aws_iam_role" "migration_handler" {
511
+ name = "DbMigrationHandlerRole-\${random_string.suffix.result}"
512
+
513
+ assume_role_policy = jsonencode({
514
+ Version = "2012-10-17"
515
+ Statement = [
516
+ {
517
+ Effect = "Allow"
518
+ Principal = {
519
+ Service = "lambda.amazonaws.com"
520
+ }
521
+ Action = "sts:AssumeRole"
522
+ }
523
+ ]
524
+ })
525
+
526
+ tags = var.tags
527
+ }
528
+
529
+ resource "aws_iam_role_policy_attachment" "migration_handler_basic_execution" {
530
+ role = aws_iam_role.migration_handler.name
531
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
532
+ }
533
+
534
+ resource "aws_iam_role_policy_attachment" "migration_handler_vpc_access" {
535
+ role = aws_iam_role.migration_handler.name
536
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
537
+ }
538
+
539
+ resource "aws_iam_role_policy_attachment" "migration_handler_xray" {
540
+ role = aws_iam_role.migration_handler.name
541
+ policy_arn = "arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess"
542
+ }
543
+
544
+ resource "aws_iam_role_policy" "migration_handler_access" {
545
+ role = aws_iam_role.migration_handler.name
546
+
547
+ policy = jsonencode({
548
+ Version = "2012-10-17"
549
+ Statement = [
550
+ {
551
+ Effect = "Allow"
552
+ Action = [
553
+ "secretsmanager:GetSecretValue"
554
+ ]
555
+ Resource = [module.aurora.secret_arn]
556
+ },
557
+ {
558
+ Effect = "Allow"
559
+ Action = [
560
+ "kms:Decrypt"
561
+ ]
562
+ Resource = [module.aurora.kms_key_arn]
563
+ }
564
+ ]
565
+ })
566
+ }
567
+
568
+ resource "aws_iam_role" "create_db_user" {
569
+ name = "DbCreateDbUserRole-\${random_string.suffix.result}"
570
+
571
+ assume_role_policy = jsonencode({
572
+ Version = "2012-10-17"
573
+ Statement = [
574
+ {
575
+ Effect = "Allow"
576
+ Principal = {
577
+ Service = "lambda.amazonaws.com"
578
+ }
579
+ Action = "sts:AssumeRole"
580
+ }
581
+ ]
582
+ })
583
+
584
+ tags = var.tags
585
+ }
586
+
587
+ resource "aws_iam_role_policy_attachment" "create_db_user_basic_execution" {
588
+ role = aws_iam_role.create_db_user.name
589
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
590
+ }
591
+
592
+ resource "aws_iam_role_policy_attachment" "create_db_user_vpc_access" {
593
+ role = aws_iam_role.create_db_user.name
594
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
595
+ }
596
+
597
+ resource "aws_iam_role_policy_attachment" "create_db_user_xray" {
598
+ role = aws_iam_role.create_db_user.name
599
+ policy_arn = "arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess"
600
+ }
601
+
602
+ resource "aws_iam_role_policy" "create_db_user_secret_access" {
603
+ role = aws_iam_role.create_db_user.name
604
+
605
+ policy = jsonencode({
606
+ Version = "2012-10-17"
607
+ Statement = [
608
+ {
609
+ Effect = "Allow"
610
+ Action = [
611
+ "secretsmanager:GetSecretValue"
612
+ ]
613
+ Resource = [module.aurora.secret_arn]
614
+ },
615
+ {
616
+ Effect = "Allow"
617
+ Action = [
618
+ "kms:Decrypt"
619
+ ]
620
+ Resource = [module.aurora.kms_key_arn]
621
+ }
622
+ ]
623
+ })
624
+ }
625
+
626
+ resource "aws_cloudwatch_log_group" "migration_handler" {
627
+ #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
628
+ #checkov:skip=CKV_AWS_338:Log retention set to forever
629
+ #checkov:skip=CKV_AWS_66:Log retention set to forever
630
+ name = "/aws/lambda/\${local.migration_function_name}"
631
+ tags = var.tags
632
+ }
633
+
634
+ resource "aws_cloudwatch_log_group" "create_db_user" {
635
+ #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
636
+ #checkov:skip=CKV_AWS_338:Log retention set to forever
637
+ #checkov:skip=CKV_AWS_66:Log retention set to forever
638
+ name = "/aws/lambda/\${local.create_db_user_function_name}"
639
+ tags = var.tags
640
+ }
641
+
642
+ resource "aws_security_group" "migration_handler" {
643
+ name_prefix = "db-migration-"
644
+ description = "Security group for the migration Lambda function"
645
+ vpc_id = var.vpc_id
646
+ tags = var.tags
647
+ }
648
+
649
+ resource "aws_vpc_security_group_egress_rule" "migration_handler_to_database" {
650
+ security_group_id = aws_security_group.migration_handler.id
651
+ referenced_security_group_id = module.aurora.database_security_group_id
652
+ from_port = module.aurora.cluster_port
653
+ to_port = module.aurora.cluster_port
654
+ ip_protocol = "tcp"
655
+ description = "Allow outbound traffic to Aurora on database port"
656
+ }
657
+
658
+ resource "aws_vpc_security_group_egress_rule" "migration_handler_https" {
659
+ security_group_id = aws_security_group.migration_handler.id
660
+ cidr_ipv4 = "0.0.0.0/0"
661
+ from_port = 443
662
+ to_port = 443
663
+ ip_protocol = "tcp"
664
+ description = "Allow outbound HTTPS to AWS service endpoints"
665
+ }
666
+
667
+ resource "aws_security_group" "create_db_user" {
668
+ name_prefix = "db-create-db-user-"
669
+ description = "Security group for the create-db-user Lambda function"
670
+ vpc_id = var.vpc_id
671
+ tags = var.tags
672
+ }
673
+
674
+ resource "aws_vpc_security_group_egress_rule" "create_db_user_to_database" {
675
+ security_group_id = aws_security_group.create_db_user.id
676
+ referenced_security_group_id = module.aurora.database_security_group_id
677
+ from_port = module.aurora.cluster_port
678
+ to_port = module.aurora.cluster_port
679
+ ip_protocol = "tcp"
680
+ description = "Allow outbound traffic to Aurora on database port"
681
+ }
682
+
683
+ resource "aws_vpc_security_group_egress_rule" "create_db_user_https" {
684
+ security_group_id = aws_security_group.create_db_user.id
685
+ cidr_ipv4 = "0.0.0.0/0"
686
+ from_port = 443
687
+ to_port = 443
688
+ ip_protocol = "tcp"
689
+ description = "Allow outbound HTTPS to AWS service endpoints"
690
+ }
691
+
692
+ resource "aws_vpc_security_group_ingress_rule" "migration_handler_to_database" {
693
+ security_group_id = module.aurora.database_security_group_id
694
+ referenced_security_group_id = aws_security_group.migration_handler.id
695
+ from_port = module.aurora.cluster_port
696
+ to_port = module.aurora.cluster_port
697
+ ip_protocol = "tcp"
698
+ description = "Allow inbound traffic from migration Lambda on database port"
699
+ }
700
+
701
+ resource "aws_vpc_security_group_ingress_rule" "create_db_user_to_database" {
702
+ security_group_id = module.aurora.database_security_group_id
703
+ referenced_security_group_id = aws_security_group.create_db_user.id
704
+ from_port = module.aurora.cluster_port
705
+ to_port = module.aurora.cluster_port
706
+ ip_protocol = "tcp"
707
+ description = "Allow inbound traffic from create-db-user Lambda on database port"
708
+ }
709
+
710
+ resource "aws_lambda_function" "create_db_user" {
711
+ #checkov:skip=CKV_AWS_116:Dead Letter Queue not required for the create-db-user handler
712
+ #checkov:skip=CKV_AWS_115:Concurrent execution limit not required for the create-db-user handler
713
+ #checkov:skip=CKV_AWS_173:Lambda environment variables encrypted by managed key
714
+ #checkov:skip=CKV_AWS_272:Code signing not configured as deployment packages are built and deployed within the same pipeline
715
+ package_type = "Image"
716
+ image_uri = "\${aws_ecr_repository.migration_handler.repository_url}:create-db-user-\${local.create_db_user_image_tag}"
717
+ function_name = local.create_db_user_function_name
718
+ role = aws_iam_role.create_db_user.arn
719
+ timeout = 300
720
+ architectures = ["arm64"]
721
+
722
+ image_config {
723
+ command = ["proj_db.create_db_user_handler.handler"]
724
+ }
725
+
726
+ tracing_config {
727
+ mode = "Active"
728
+ }
729
+
730
+ vpc_config {
731
+ subnet_ids = var.lambda_subnet_ids
732
+ security_group_ids = [aws_security_group.create_db_user.id]
733
+ }
734
+
735
+ environment {
736
+ variables = {
737
+ DATABASE_SECRET_ARN = module.aurora.secret_arn
738
+ }
739
+ }
740
+
741
+ tags = var.tags
742
+
743
+ depends_on = [
744
+ null_resource.docker_publish,
745
+ aws_iam_role_policy_attachment.create_db_user_basic_execution,
746
+ aws_iam_role_policy_attachment.create_db_user_vpc_access,
747
+ aws_iam_role_policy_attachment.create_db_user_xray,
748
+ aws_iam_role_policy.create_db_user_secret_access,
749
+ aws_cloudwatch_log_group.create_db_user,
750
+ aws_vpc_security_group_ingress_rule.create_db_user_to_database
751
+ ]
752
+ }
753
+
754
+ resource "null_resource" "create_db_user_trigger" {
755
+ triggers = {
756
+ cluster_arn = module.aurora.cluster_arn
757
+ function_name = aws_lambda_function.create_db_user.function_name
758
+ db_user = local.database_runtime_user
759
+ bundle_hash = data.external.create_db_user_docker_digest.result.digest
760
+ }
761
+
762
+ provisioner "local-exec" {
763
+ command = <<-EOT
764
+ output_file=$(mktemp)
765
+ response=$(aws lambda invoke \\
766
+ --region "$AWS_REGION" \\
767
+ --function-name "$FUNCTION_NAME" \\
768
+ --cli-binary-format raw-in-base64-out \\
769
+ --payload "{\\"RequestType\\":\\"Create\\",\\"PhysicalResourceId\\":\\"db-user:$DB_USER\\"}" \\
770
+ "$output_file")
771
+ cat "$output_file"
772
+ echo "$response"
773
+ if echo "$response" | grep -q '"FunctionError"'; then
774
+ rm -f "$output_file"
775
+ exit 1
776
+ fi
777
+ rm -f "$output_file"
778
+ EOT
779
+ environment = {
780
+ AWS_REGION = data.aws_region.current.region
781
+ FUNCTION_NAME = self.triggers.function_name
782
+ DB_USER = self.triggers.db_user
783
+ }
784
+ }
785
+
786
+ depends_on = [aws_lambda_function.create_db_user, module.aurora]
787
+ }
788
+
789
+ resource "aws_lambda_function" "migration_handler" {
790
+ #checkov:skip=CKV_AWS_116:Dead Letter Queue not required for the migration handler
791
+ #checkov:skip=CKV_AWS_115:Concurrent execution limit not required for the migration handler
792
+ #checkov:skip=CKV_AWS_173:Lambda environment variables encrypted by managed key
793
+ #checkov:skip=CKV_AWS_272:Code signing does not apply to container image Lambda functions
794
+ package_type = "Image"
795
+ function_name = local.migration_function_name
796
+ role = aws_iam_role.migration_handler.arn
797
+ image_uri = "\${aws_ecr_repository.migration_handler.repository_url}:\${local.image_tag}"
798
+ memory_size = 1024
799
+ timeout = 300
800
+ architectures = ["arm64"]
801
+
802
+ tracing_config {
803
+ mode = "Active"
804
+ }
805
+
806
+ vpc_config {
807
+ subnet_ids = var.lambda_subnet_ids
808
+ security_group_ids = [aws_security_group.migration_handler.id]
809
+ }
810
+
811
+ environment {
812
+ variables = {
813
+ DATABASE_SECRET_ARN = module.aurora.secret_arn
814
+ }
815
+ }
816
+
817
+ tags = var.tags
818
+
819
+ depends_on = [
820
+ null_resource.docker_publish,
821
+ aws_iam_role_policy_attachment.migration_handler_basic_execution,
822
+ aws_iam_role_policy_attachment.migration_handler_vpc_access,
823
+ aws_iam_role_policy_attachment.migration_handler_xray,
824
+ aws_iam_role_policy.migration_handler_access,
825
+ aws_cloudwatch_log_group.migration_handler,
826
+ aws_vpc_security_group_ingress_rule.migration_handler_to_database
827
+ ]
828
+ }
829
+
830
+ resource "null_resource" "migration_trigger" {
831
+ triggers = {
832
+ docker_digest = data.external.docker_digest.result.digest
833
+ cluster_arn = module.aurora.cluster_arn
834
+ database_ready = module.aurora.database_ready
835
+ function_name = aws_lambda_function.migration_handler.function_name
836
+ }
837
+
838
+ provisioner "local-exec" {
839
+ command = <<-EOT
840
+ output_file=$(mktemp)
841
+ response=$(aws lambda invoke \\
842
+ --region "$AWS_REGION" \\
843
+ --function-name "$FUNCTION_NAME" \\
844
+ --cli-binary-format raw-in-base64-out \\
845
+ "$output_file")
846
+ cat "$output_file"
847
+ echo "$response"
848
+ if echo "$response" | grep -q '"FunctionError"'; then
849
+ rm -f "$output_file"
850
+ exit 1
851
+ fi
852
+ rm -f "$output_file"
853
+ EOT
854
+ environment = {
855
+ AWS_REGION = data.aws_region.current.region
856
+ FUNCTION_NAME = self.triggers.function_name
857
+ }
858
+ }
859
+
860
+ depends_on = [
861
+ aws_lambda_function.migration_handler,
862
+ module.aurora,
863
+ null_resource.create_db_user_trigger,
864
+ aws_iam_role_policy.proxy_db_user_connect
865
+ ]
866
+ }
867
+
868
+ output "security_group_id" {
869
+ description = "Security group ID to allow inbound connections to the database (proxy SG if RDS Proxy is enabled, otherwise DB SG)."
870
+ value = module.aurora.security_group_id
871
+ }
872
+
873
+ output "database_security_group_id" {
874
+ description = "Security group ID of the Aurora cluster directly, used for direct DB access rules (e.g. when RDS Proxy is disabled)."
875
+ value = module.aurora.database_security_group_id
876
+ }
877
+
878
+ output "cluster_resource_id" {
879
+ description = "Resource ID of the Aurora cluster, used for IAM rds-db:connect policies."
880
+ value = module.aurora.cluster_resource_id
881
+ }
882
+
883
+ output "proxy_resource_id" {
884
+ description = "Resource identifier of the RDS Proxy (prx-XXXX), used for IAM rds-db:connect policies when connecting through the proxy. Null if RDS Proxy is disabled."
885
+ value = module.aurora.proxy_resource_id
886
+ }
887
+
888
+ output "connect_resource_id" {
889
+ description = "Resource ID to use in IAM rds-db:connect policies for the application database user. Resolves to the RDS Proxy resource ID when the proxy is enabled (the default), or the Aurora cluster resource ID when it is disabled — connecting through the proxy and connecting directly to the cluster are different IAM permission boundaries."
890
+ value = module.aurora.connect_resource_id
891
+ }
892
+
893
+ output "kms_key_arn" {
894
+ description = "ARN of the KMS key protecting Aurora and the admin credentials secret, used to grant decrypt access alongside secret_arn."
895
+ value = module.aurora.kms_key_arn
896
+ }
897
+
898
+ output "cluster_arn" {
899
+ description = "ARN of the Aurora cluster."
900
+ value = module.aurora.cluster_arn
901
+ }
902
+
903
+ output "cluster_endpoint" {
904
+ description = "Writer endpoint of the Aurora cluster."
905
+ value = module.aurora.cluster_endpoint
906
+ }
907
+
908
+ output "reader_endpoint" {
909
+ description = "Reader endpoint of the Aurora cluster."
910
+ value = module.aurora.reader_endpoint
911
+ }
912
+
913
+ output "cluster_port" {
914
+ description = "Port exposed by the Aurora cluster."
915
+ value = module.aurora.cluster_port
916
+ }
917
+
918
+ output "secret_arn" {
919
+ description = "ARN of the generated admin credentials secret."
920
+ value = module.aurora.secret_arn
921
+ }
922
+
923
+ output "database_runtime_user" {
924
+ description = "Application database user created for IAM-authenticated access."
925
+ value = local.database_runtime_user
926
+ }
927
+ "
928
+ `;
929
+
930
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic > packages/db/migrations/env.py 1`] = `
931
+ "import asyncio
932
+ import json
933
+ import os
934
+ from logging.config import fileConfig
935
+
936
+ from alembic import context
937
+ from sqlalchemy import URL
938
+ from sqlalchemy.ext.asyncio import create_async_engine
939
+ from sqlmodel import SQLModel
940
+
941
+ # Import all models to register them in SQLModel.metadata
942
+ from proj_db.models import * # noqa: F401, F403
943
+
944
+ config = context.config
945
+
946
+ if config.config_file_name is not None:
947
+ fileConfig(config.config_file_name)
948
+
949
+ target_metadata = SQLModel.metadata
950
+
951
+
952
+ def _get_local_url():
953
+ if os.environ.get("LOCAL_DEV") == "true":
954
+ config_path = os.path.join(os.path.dirname(__file__), "..", "config.json")
955
+ with open(config_path) as f:
956
+ cfg = json.load(f)["localDev"]
957
+ engine = cfg["dbEngine"]
958
+ driver = "mysql+aiomysql" if engine == "mysql" else "postgresql+asyncpg"
959
+ return URL.create(
960
+ driver,
961
+ username=cfg["dbUser"],
962
+ password=cfg["dbPassword"],
963
+ host=cfg["host"],
964
+ port=cfg["port"],
965
+ database=cfg["dbName"],
966
+ )
967
+
968
+ raise RuntimeError("Run alembic via nx run <project>:alembic")
969
+
970
+
971
+ # Generates SQL script without a live DB connection (alembic upgrade head --sql)
972
+ def run_migrations_offline() -> None:
973
+ context.configure(
974
+ url=_get_local_url(),
975
+ target_metadata=target_metadata,
976
+ literal_binds=True,
977
+ dialect_opts={"paramstyle": "named"},
978
+ )
979
+ with context.begin_transaction():
980
+ context.run_migrations()
981
+
982
+
983
+ def _run_migrations_sync(sync_conn) -> None:
984
+ context.configure(connection=sync_conn, target_metadata=target_metadata)
985
+ with context.begin_transaction():
986
+ context.run_migrations()
987
+
988
+
989
+ # Runs migrations against a live DB connection
990
+ def run_migrations_online() -> None:
991
+ supplied_connection = config.attributes.get("connection")
992
+ # Connection injected by migration_handler.py (Lambda)
993
+ if supplied_connection is not None:
994
+ _run_migrations_sync(supplied_connection)
995
+ return
996
+
997
+ # Local alembic commands run via nx run <project>:alembic
998
+ async def _run_async() -> None:
999
+ engine = create_async_engine(_get_local_url())
1000
+ async with engine.begin() as conn:
1001
+ await conn.run_sync(_run_migrations_sync)
1002
+ await engine.dispose()
1003
+
1004
+ asyncio.run(_run_async())
1005
+
1006
+
1007
+ if context.is_offline_mode():
1008
+ run_migrations_offline()
1009
+ else:
1010
+ run_migrations_online()
1011
+ "
1012
+ `;
1013
+
1014
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic > packages/db/migrations/script.py.mako 1`] = `
1015
+ """"\${message}
1016
+
1017
+ Revision ID: \${up_revision}
1018
+ Revises: \${down_revision | comma,n}
1019
+ Create Date: \${create_date}
1020
+
1021
+ """
1022
+ from typing import Sequence, Union
1023
+
1024
+ from alembic import op
1025
+ import sqlalchemy as sa
1026
+ \${imports if imports else ""}
1027
+
1028
+ # revision identifiers, used by Alembic.
1029
+ revision: str = \${repr(up_revision)}
1030
+ down_revision: Union[str, Sequence[str], None] = \${repr(down_revision)}
1031
+ branch_labels: Union[str, Sequence[str], None] = \${repr(branch_labels)}
1032
+ depends_on: Union[str, Sequence[str], None] = \${repr(depends_on)}
1033
+
1034
+
1035
+ def upgrade() -> None:
1036
+ """Upgrade schema."""
1037
+ \${upgrades if upgrades else "pass"}
1038
+
1039
+
1040
+ def downgrade() -> None:
1041
+ """Downgrade schema."""
1042
+ \${downgrades if downgrades else "pass"}
1043
+ "
1044
+ `;
1045
+
1046
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic > packages/db/migrations/versions/.gitkeep 1`] = `""`;
1047
+
1048
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic > packages/db/proj_db/__init__.py 1`] = `
1049
+ "from .connection import get_engine, is_local_dev, session_context
1050
+
1051
+ __all__ = ["get_engine", "is_local_dev", "session_context"]
1052
+ "
1053
+ `;
1054
+
1055
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic > packages/db/proj_db/connection.py 1`] = `
1056
+ "import ssl
1057
+ from collections.abc import AsyncGenerator
1058
+ from contextlib import asynccontextmanager
1059
+
1060
+ import boto3
1061
+ from sqlalchemy import event
1062
+ from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
1063
+
1064
+ from .utils import build_database_url, get_database_config, get_local_dev_config, is_local_dev
1065
+
1066
+ # Generated: must match runtimeConfigKey in config.json
1067
+ _runtime_config_key = "Db"
1068
+
1069
+ _engine = None
1070
+
1071
+
1072
+ def get_engine():
1073
+ global _engine
1074
+ if _engine is not None:
1075
+ return _engine
1076
+ if is_local_dev():
1077
+ cfg = get_local_dev_config()
1078
+ url = build_database_url(cfg["dbUser"], cfg["host"], cfg["port"], cfg["dbName"])
1079
+ ssl_args: dict = {}
1080
+ else:
1081
+ config = get_database_config(_runtime_config_key)
1082
+ url = build_database_url(
1083
+ config["dbUser"],
1084
+ config["hostname"],
1085
+ config["port"],
1086
+ config["database"],
1087
+ )
1088
+ ssl_args = {"ssl": ssl.create_default_context()}
1089
+ _engine = create_async_engine(url, connect_args=ssl_args)
1090
+
1091
+ @event.listens_for(_engine.sync_engine, "do_connect")
1092
+ def provide_password(_dialect, _connection_record, _cargs, connection_params):
1093
+ if is_local_dev():
1094
+ connection_params["password"] = get_local_dev_config()["dbPassword"]
1095
+ else:
1096
+ config = get_database_config(_runtime_config_key)
1097
+ connection_params["password"] = boto3.client(
1098
+ "rds",
1099
+ region_name=config["region"],
1100
+ ).generate_db_auth_token(
1101
+ DBHostname=config["hostname"],
1102
+ Port=config["port"],
1103
+ DBUsername=config["dbUser"],
1104
+ )
1105
+
1106
+ return _engine
1107
+
1108
+
1109
+ @asynccontextmanager
1110
+ async def session_context() -> AsyncGenerator[AsyncSession]:
1111
+ async with AsyncSession(get_engine()) as session:
1112
+ yield session
1113
+ "
1114
+ `;
1115
+
1116
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic > packages/db/proj_db/create_db_user_handler.py 1`] = `
1117
+ "import asyncio
1118
+ import secrets
1119
+ import ssl
1120
+ from typing import Any
1121
+
1122
+ import asyncpg
1123
+
1124
+ from .utils import get_database_secret, with_connection_retry
1125
+
1126
+
1127
+ async def _ensure_database_user(db_user: str) -> None:
1128
+ secret = get_database_secret()
1129
+ conn = await asyncpg.connect(
1130
+ host=secret["host"],
1131
+ port=int(secret["port"]),
1132
+ database=secret["dbname"],
1133
+ user=secret["username"],
1134
+ password=secret["password"],
1135
+ ssl=ssl.create_default_context(),
1136
+ )
1137
+ try:
1138
+ quoted = await conn.fetchrow(
1139
+ "SELECT quote_ident($1) AS role_q, quote_ident($2) AS db_q",
1140
+ db_user,
1141
+ secret["dbname"],
1142
+ )
1143
+ role_q, db_q = quoted["role_q"], quoted["db_q"]
1144
+ row = await conn.fetchrow("SELECT 1 FROM pg_roles WHERE rolname = $1", db_user)
1145
+ if row is None:
1146
+ await conn.execute(f"CREATE ROLE {role_q} WITH LOGIN")
1147
+ await conn.execute(f"""
1148
+ ALTER ROLE {role_q} WITH LOGIN;
1149
+ GRANT CONNECT ON DATABASE {db_q} TO {role_q};
1150
+ GRANT USAGE ON SCHEMA public TO {role_q};
1151
+ GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO {role_q};
1152
+ GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO {role_q};
1153
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
1154
+ GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO {role_q};
1155
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
1156
+ GRANT USAGE, SELECT ON SEQUENCES TO {role_q};
1157
+ GRANT rds_iam TO {role_q};
1158
+ """)
1159
+ finally:
1160
+ await conn.close()
1161
+
1162
+
1163
+ _PHYSICAL_RESOURCE_ID_PREFIX = "db-user:"
1164
+
1165
+
1166
+ def _resolve_db_user(physical_resource_id: str | None) -> str:
1167
+ if physical_resource_id and physical_resource_id.startswith(_PHYSICAL_RESOURCE_ID_PREFIX):
1168
+ return physical_resource_id[len(_PHYSICAL_RESOURCE_ID_PREFIX) :]
1169
+ return f"db_{secrets.token_hex(8)}"
1170
+
1171
+
1172
+ def handler(event: dict[str, Any], _context: Any) -> dict[str, Any]:
1173
+ db_user = _resolve_db_user(event.get("PhysicalResourceId"))
1174
+
1175
+ if event.get("RequestType") != "Delete":
1176
+ with_connection_retry(lambda: asyncio.run(_ensure_database_user(db_user)))
1177
+
1178
+ return {
1179
+ "PhysicalResourceId": f"{_PHYSICAL_RESOURCE_ID_PREFIX}{db_user}",
1180
+ "Data": {"dbUser": db_user},
1181
+ }
1182
+ "
1183
+ `;
1184
+
1185
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic > packages/db/proj_db/migration_handler.py 1`] = `
1186
+ "import asyncio
1187
+ import ssl
1188
+
1189
+ from alembic import command
1190
+ from alembic.config import Config
1191
+ from sqlalchemy.ext.asyncio import create_async_engine
1192
+ from sqlalchemy.pool import NullPool
1193
+
1194
+ from .utils import build_database_url, get_database_secret, with_connection_retry
1195
+
1196
+
1197
+ def _apply_migrations(sync_conn, alembic_cfg: Config) -> None:
1198
+ alembic_cfg.attributes["connection"] = sync_conn
1199
+ command.upgrade(alembic_cfg, "head")
1200
+
1201
+
1202
+ async def _run_migrations() -> None:
1203
+ secret = get_database_secret()
1204
+ database_url = build_database_url(
1205
+ secret["username"],
1206
+ secret["host"],
1207
+ secret["port"],
1208
+ secret["dbname"],
1209
+ password=secret["password"],
1210
+ )
1211
+ alembic_cfg = Config("alembic.ini")
1212
+ engine = create_async_engine(
1213
+ database_url,
1214
+ poolclass=NullPool,
1215
+ connect_args={"ssl": ssl.create_default_context()},
1216
+ )
1217
+ try:
1218
+ async with engine.begin() as conn:
1219
+ await conn.run_sync(lambda c: _apply_migrations(c, alembic_cfg))
1220
+ finally:
1221
+ await engine.dispose()
1222
+
1223
+
1224
+ def handler(_event, _context):
1225
+ with_connection_retry(lambda: asyncio.run(_run_migrations()))
1226
+ "
1227
+ `;
1228
+
1229
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic > packages/db/proj_db/models/__init__.py 1`] = `
1230
+ "from .example import ExampleModel
1231
+
1232
+ __all__ = ["ExampleModel"]
1233
+ "
1234
+ `;
1235
+
1236
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic > packages/db/proj_db/models/example.py 1`] = `
1237
+ "from sqlalchemy import Column, String
1238
+ from sqlmodel import Field, SQLModel
1239
+
1240
+
1241
+ class ExampleModel(SQLModel, table=True):
1242
+ id: int | None = Field(default=None, primary_key=True)
1243
+ name: str = Field(sa_column=Column(String(255), nullable=False))
1244
+ description: str | None = Field(default=None, sa_column=Column(String(255), nullable=True))
1245
+ "
1246
+ `;
1247
+
1248
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic > packages/db/proj_db/utils.py 1`] = `
1249
+ "import json
1250
+ import os
1251
+ import time
1252
+ from collections.abc import Callable
1253
+ from typing import Any
1254
+
1255
+ import boto3
1256
+ from aws_lambda_powertools.utilities.parameters import AppConfigProvider
1257
+ from sqlalchemy import URL
1258
+
1259
+ DatabaseConfig = dict[str, Any]
1260
+ DatabaseSecret = dict[str, Any]
1261
+
1262
+
1263
+ def build_database_url(
1264
+ username: str,
1265
+ host: str,
1266
+ port: int,
1267
+ database: str,
1268
+ password: str | None = None,
1269
+ ) -> URL:
1270
+ return URL.create(
1271
+ drivername="postgresql+asyncpg",
1272
+ username=username,
1273
+ password=password,
1274
+ host=host,
1275
+ port=port,
1276
+ database=database,
1277
+ )
1278
+
1279
+
1280
+ def is_local_dev() -> bool:
1281
+ return os.environ.get("LOCAL_DEV") == "true"
1282
+
1283
+
1284
+ def get_local_dev_config() -> dict:
1285
+ config_path = os.path.join(os.path.dirname(__file__), "..", "config.json")
1286
+ with open(config_path) as f:
1287
+ return json.load(f)["localDev"]
1288
+
1289
+
1290
+ def get_database_secret() -> DatabaseSecret:
1291
+ secret_arn = os.environ.get("DATABASE_SECRET_ARN")
1292
+ if not secret_arn:
1293
+ raise ValueError("Missing required environment variable DATABASE_SECRET_ARN.")
1294
+ client = boto3.client("secretsmanager")
1295
+ response = client.get_secret_value(SecretId=secret_arn)
1296
+ return json.loads(response["SecretString"])
1297
+
1298
+
1299
+ _database_config: dict[str, DatabaseConfig] = {}
1300
+
1301
+
1302
+ def get_database_config(runtime_config_key: str) -> DatabaseConfig:
1303
+ if runtime_config_key not in _database_config:
1304
+ app_id = os.environ.get("RUNTIME_CONFIG_APP_ID")
1305
+ if not app_id:
1306
+ raise ValueError("Missing required environment variable RUNTIME_CONFIG_APP_ID.")
1307
+ provider = AppConfigProvider(application=app_id, environment="default")
1308
+ config = provider.get("database", transform="json")
1309
+ if not isinstance(config, dict):
1310
+ raise ValueError("Unexpected RuntimeConfig format: expected JSON object.")
1311
+ db_config = config.get(runtime_config_key)
1312
+ if not db_config:
1313
+ raise ValueError(f"RuntimeConfig is missing database.{runtime_config_key}.")
1314
+ _database_config[runtime_config_key] = db_config
1315
+ return _database_config[runtime_config_key]
1316
+
1317
+
1318
+ _TRANSIENT_ERROR_PATTERNS = [
1319
+ "timeout",
1320
+ "connection refused",
1321
+ "could not connect",
1322
+ "connection reset",
1323
+ "connection timed out",
1324
+ "operationalerror",
1325
+ "password authentication failed",
1326
+ "access denied",
1327
+ "temporary failure",
1328
+ ]
1329
+
1330
+
1331
+ def is_transient_connection_error(error: Exception) -> bool:
1332
+ error_str = str(error).lower()
1333
+ return any(p in error_str for p in _TRANSIENT_ERROR_PATTERNS)
1334
+
1335
+
1336
+ def with_connection_retry[T](
1337
+ fn: Callable[[], T],
1338
+ max_attempts: int = 6,
1339
+ delay_seconds: float = 10.0,
1340
+ ) -> T:
1341
+ for attempt in range(1, max_attempts + 1):
1342
+ try:
1343
+ return fn()
1344
+ except Exception as e:
1345
+ if attempt == max_attempts or not is_transient_connection_error(e):
1346
+ raise
1347
+ wait = delay_seconds * attempt
1348
+ print(f"Transient connection error (attempt {attempt}/{max_attempts}), retrying in {wait:.0f}s: {e}")
1349
+ time.sleep(wait)
1350
+ raise RuntimeError("unreachable")
1351
+ "
1352
+ `;
1353
+
1354
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic 1`] = `
1355
+ "[alembic]
1356
+ script_location = migrations
1357
+ file_template = %%(year)d%%(month).2d%%(day).2d_%%(hour).2d%%(minute).2d_%%(rev)s_%%(slug)s
1358
+ prepend_sys_path = .
1359
+
1360
+ [loggers]
1361
+ keys = root,sqlalchemy,alembic
1362
+
1363
+ [handlers]
1364
+ keys = console
1365
+
1366
+ [formatters]
1367
+ keys = generic
1368
+
1369
+ [logger_root]
1370
+ level = WARN
1371
+ handlers = console
1372
+ qualname =
1373
+
1374
+ [logger_sqlalchemy]
1375
+ level = WARN
1376
+ handlers =
1377
+ qualname = sqlalchemy.engine
1378
+
1379
+ [logger_alembic]
1380
+ level = INFO
1381
+ handlers =
1382
+ qualname = alembic
1383
+
1384
+ [handler_console]
1385
+ class = StreamHandler
1386
+ args = (sys.stderr,)
1387
+ level = NOTSET
1388
+ formatter = generic
1389
+
1390
+ [formatter_generic]
1391
+ format = %(levelname)-5.5s [%(name)s] %(message)s
1392
+ datefmt = %H:%M:%S
1393
+ "
1394
+ `;
1395
+
1396
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic 2`] = `
1397
+ "FROM public.ecr.aws/lambda/python:3.14
1398
+
1399
+ WORKDIR \${LAMBDA_TASK_ROOT}
1400
+
1401
+ COPY . .
1402
+
1403
+ ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /etc/pki/ca-trust/source/anchors/global-bundle.pem
1404
+ RUN update-ca-trust
1405
+
1406
+ CMD ["proj_db.migration_handler.handler"]
1407
+ "
1408
+ `;
1409
+
1410
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic 3`] = `
1411
+ "FROM public.ecr.aws/lambda/python:3.14
1412
+
1413
+ WORKDIR \${LAMBDA_TASK_ROOT}
1414
+
1415
+ COPY . .
1416
+
1417
+ ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /etc/pki/ca-trust/source/anchors/global-bundle.pem
1418
+ RUN update-ca-trust
1419
+
1420
+ CMD ["proj_db.create_db_user_handler.handler"]
1421
+ "
1422
+ `;
1423
+
1424
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic 4`] = `
1425
+ "{
1426
+ "runtimeConfigKey": "Db",
1427
+ "localDev": {
1428
+ "containerEngine": "docker",
1429
+ "containerName": "proj-database_name",
1430
+ "image": "public.ecr.aws/docker/library/postgres:17.7",
1431
+ "port": 5432,
1432
+ "host": "localhost",
1433
+ "dbName": "database_name",
1434
+ "dbUser": "dbadmin",
1435
+ "dbPassword": "password",
1436
+ "dbEngine": "postgres"
1437
+ }
1438
+ }
1439
+ "
1440
+ `;
1441
+
1442
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic 5`] = `
1443
+ "[tool.coverage.run]
1444
+ branch = true
1445
+ source = [ "proj_db" ]
1446
+
1447
+ [tool.coverage.report]
1448
+ exclude_lines = [ "if TYPE_CHECKING:" ]
1449
+ show_missing = true
1450
+
1451
+ [tool.pytest.ini_options]
1452
+ addopts = """
1453
+ --cov
1454
+ --cov-report html:'../../coverage/packages/db/html'
1455
+ --cov-report xml:'../../coverage/packages/db/coverage.xml'
1456
+ --html='../../reports/packages/db/unittests/html/index.html'
1457
+ --junitxml='../../reports/packages/db/unittests/junit.xml'
1458
+ """
1459
+
1460
+ [tool.hatch.build.targets.wheel]
1461
+ packages = [ "proj_db" ]
1462
+
1463
+ [tool.hatch.metadata]
1464
+ allow-direct-references = true
1465
+
1466
+ [tool.ruff]
1467
+ exclude = [ ".ruff_cache", ".svn", ".tox", ".venv", "dist" ]
1468
+ line-length = 120
1469
+ indent-width = 4
1470
+
1471
+ [tool.ruff.lint]
1472
+ select = [ "E", "F", "UP", "B", "SIM", "I" ]
1473
+ ignore = [ ]
1474
+ fixable = [ "ALL" ]
1475
+ unfixable = [ ]
1476
+
1477
+ [project]
1478
+ name = "proj-db"
1479
+ version = "1.0.0"
1480
+ description = "Automatically generated by Nx."
1481
+ requires-python = ">=3.14"
1482
+ readme = "README.md"
1483
+ dependencies = [
1484
+ "sqlmodel==0.0.38",
1485
+ "alembic==1.18.4",
1486
+ "asyncpg==0.31.0",
1487
+ "boto3==1.43.46",
1488
+ "aws-lambda-powertools==3.31.0"
1489
+ ]
1490
+
1491
+ [build-system]
1492
+ requires = [ "hatchling" ]
1493
+ build-backend = "hatchling.build"
1494
+ "
1495
+ `;
1496
+
1497
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic 6`] = `
1498
+ "import * as path from 'path';
1499
+ import * as url from 'url';
1500
+ import { readFileSync } from 'fs';
1501
+ import { Construct } from 'constructs';
1502
+ import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
1503
+ import {
1504
+ DockerImageCode,
1505
+ DockerImageFunction,
1506
+ Function,
1507
+ FunctionOptions,
1508
+ } from 'aws-cdk-lib/aws-lambda';
1509
+ import {
1510
+ AuroraDatabase,
1511
+ AuroraDatabaseEngines,
1512
+ AuroraDatabaseProps,
1513
+ } from '../../core/rdb/aurora.js';
1514
+ import { findWorkspaceRoot } from '../../core/workspace.js';
1515
+
1516
+ const { runtimeConfigKey } = JSON.parse(
1517
+ readFileSync(
1518
+ path.join(
1519
+ findWorkspaceRoot(url.fileURLToPath(new URL(import.meta.url))),
1520
+ 'packages/db/config.json',
1521
+ ),
1522
+ 'utf-8',
1523
+ ),
1524
+ ) as { runtimeConfigKey: string };
1525
+
1526
+ const migrationBundleDir = path.join(
1527
+ findWorkspaceRoot(url.fileURLToPath(new URL(import.meta.url))),
1528
+ 'dist/packages/db/docker/migration',
1529
+ );
1530
+
1531
+ const createDbUserBundleDir = path.join(
1532
+ findWorkspaceRoot(url.fileURLToPath(new URL(import.meta.url))),
1533
+ 'dist/packages/db/docker/create-db-user',
1534
+ );
1535
+
1536
+ export type DbProps = Omit<
1537
+ AuroraDatabaseProps,
1538
+ 'databaseName' | 'adminUser' | 'runtimeConfigKey' | 'engine'
1539
+ >;
1540
+
1541
+ /**
1542
+ * CDK construct that provisions an Aurora Serverless v2 cluster.
1543
+ */
1544
+ export class Db extends AuroraDatabase {
1545
+ constructor(scope: Construct, id: string, props: DbProps) {
1546
+ super(scope, id, {
1547
+ ...props,
1548
+ databaseName: 'database_name',
1549
+ adminUser: 'databaseUser',
1550
+ runtimeConfigKey,
1551
+ engine: AuroraDatabaseEngines.postgres({}),
1552
+ });
1553
+ }
1554
+
1555
+ protected override createDbUserHandler(baseProps: FunctionOptions): Function {
1556
+ return new DockerImageFunction(this, 'CreateDbUserHandler', {
1557
+ ...baseProps,
1558
+ code: DockerImageCode.fromImageAsset(createDbUserBundleDir, {
1559
+ platform: Platform.LINUX_ARM64,
1560
+ }),
1561
+ });
1562
+ }
1563
+
1564
+ protected override createMigrationHandler(
1565
+ baseProps: FunctionOptions,
1566
+ ): Function {
1567
+ return new DockerImageFunction(this, 'MigrationHandler', {
1568
+ ...baseProps,
1569
+ code: DockerImageCode.fromImageAsset(migrationBundleDir, {
1570
+ platform: Platform.LINUX_ARM64,
1571
+ }),
1572
+ });
1573
+ }
1574
+ }
1575
+ "
1576
+ `;
1577
+
1578
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic 7`] = `
1579
+ "import asyncio
1580
+ import secrets
1581
+ import ssl
1582
+ from typing import Any
1583
+
1584
+ import asyncpg
1585
+
1586
+ from .utils import get_database_secret, with_connection_retry
1587
+
1588
+
1589
+ async def _ensure_database_user(db_user: str) -> None:
1590
+ secret = get_database_secret()
1591
+ conn = await asyncpg.connect(
1592
+ host=secret["host"],
1593
+ port=int(secret["port"]),
1594
+ database=secret["dbname"],
1595
+ user=secret["username"],
1596
+ password=secret["password"],
1597
+ ssl=ssl.create_default_context(),
1598
+ )
1599
+ try:
1600
+ quoted = await conn.fetchrow(
1601
+ "SELECT quote_ident($1) AS role_q, quote_ident($2) AS db_q",
1602
+ db_user,
1603
+ secret["dbname"],
1604
+ )
1605
+ role_q, db_q = quoted["role_q"], quoted["db_q"]
1606
+ row = await conn.fetchrow("SELECT 1 FROM pg_roles WHERE rolname = $1", db_user)
1607
+ if row is None:
1608
+ await conn.execute(f"CREATE ROLE {role_q} WITH LOGIN")
1609
+ await conn.execute(f"""
1610
+ ALTER ROLE {role_q} WITH LOGIN;
1611
+ GRANT CONNECT ON DATABASE {db_q} TO {role_q};
1612
+ GRANT USAGE ON SCHEMA public TO {role_q};
1613
+ GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO {role_q};
1614
+ GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO {role_q};
1615
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
1616
+ GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO {role_q};
1617
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
1618
+ GRANT USAGE, SELECT ON SEQUENCES TO {role_q};
1619
+ GRANT rds_iam TO {role_q};
1620
+ """)
1621
+ finally:
1622
+ await conn.close()
1623
+
1624
+
1625
+ _PHYSICAL_RESOURCE_ID_PREFIX = "db-user:"
1626
+
1627
+
1628
+ def _resolve_db_user(physical_resource_id: str | None) -> str:
1629
+ if physical_resource_id and physical_resource_id.startswith(_PHYSICAL_RESOURCE_ID_PREFIX):
1630
+ return physical_resource_id[len(_PHYSICAL_RESOURCE_ID_PREFIX) :]
1631
+ return f"db_{secrets.token_hex(8)}"
1632
+
1633
+
1634
+ def handler(event: dict[str, Any], _context: Any) -> dict[str, Any]:
1635
+ db_user = _resolve_db_user(event.get("PhysicalResourceId"))
1636
+
1637
+ if event.get("RequestType") != "Delete":
1638
+ with_connection_retry(lambda: asyncio.run(_ensure_database_user(db_user)))
1639
+
1640
+ return {
1641
+ "PhysicalResourceId": f"{_PHYSICAL_RESOURCE_ID_PREFIX}{db_user}",
1642
+ "Data": {"dbUser": db_user},
1643
+ }
1644
+ "
1645
+ `;
1646
+
1647
+ exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic 8`] = `
1648
+ "import { CfnOutput, Duration, RemovalPolicy, Stack } from 'aws-cdk-lib';
1649
+ import { CustomResource } from 'aws-cdk-lib';
1650
+ import { IConnectable, IVpc, Port, SubnetType } from 'aws-cdk-lib/aws-ec2';
1651
+ import { IGrantable, Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
1652
+ import { Key } from 'aws-cdk-lib/aws-kms';
1653
+ import {
1654
+ Architecture,
1655
+ Function,
1656
+ FunctionOptions,
1657
+ Tracing,
1658
+ } from 'aws-cdk-lib/aws-lambda';
1659
+ import {
1660
+ AuroraMysqlEngineVersion,
1661
+ AuroraPostgresEngineVersion,
1662
+ ClusterInstance,
1663
+ Credentials,
1664
+ DatabaseCluster,
1665
+ DatabaseClusterEngine,
1666
+ DatabaseClusterProps,
1667
+ DatabaseProxy,
1668
+ DefaultAuthScheme,
1669
+ IClusterEngine,
1670
+ } from 'aws-cdk-lib/aws-rds';
1671
+ import { Provider } from 'aws-cdk-lib/custom-resources';
1672
+ import { Trigger } from 'aws-cdk-lib/triggers';
1673
+ import { Construct } from 'constructs';
1674
+ import { RuntimeConfig } from '../runtime-config.js';
1675
+
1676
+ export type AuroraDatabaseEngineVersion =
1677
+ | AuroraMysqlEngineVersion
1678
+ | AuroraPostgresEngineVersion;
1679
+
1680
+ export interface AuroraDatabaseEngine {
1681
+ /**
1682
+ * Discriminant identifying the engine type.
1683
+ */
1684
+ readonly type: 'mysql' | 'postgres';
1685
+
1686
+ /**
1687
+ * Default Aurora engine version used when one is not explicitly provided.
1688
+ */
1689
+ readonly defaultVersion: AuroraDatabaseEngineVersion;
1690
+
1691
+ /**
1692
+ * Builds the CDK cluster engine for the provided engine version.
1693
+ */
1694
+ clusterEngine(version: AuroraDatabaseEngineVersion): IClusterEngine;
1695
+ }
1696
+
1697
+ export class AuroraDatabaseEngines {
1698
+ public static mysql({
1699
+ defaultVersion = AuroraMysqlEngineVersion.VER_3_12_0,
1700
+ }: {
1701
+ defaultVersion?: AuroraMysqlEngineVersion;
1702
+ }): AuroraDatabaseEngine {
1703
+ return {
1704
+ type: 'mysql',
1705
+ defaultVersion,
1706
+ clusterEngine: (version) =>
1707
+ DatabaseClusterEngine.auroraMysql({
1708
+ version: version as AuroraMysqlEngineVersion,
1709
+ }),
1710
+ };
1711
+ }
1712
+
1713
+ public static postgres({
1714
+ defaultVersion = AuroraPostgresEngineVersion.VER_17_7,
1715
+ }: {
1716
+ defaultVersion?: AuroraPostgresEngineVersion;
1717
+ }): AuroraDatabaseEngine {
1718
+ return {
1719
+ type: 'postgres',
1720
+ defaultVersion,
1721
+ clusterEngine: (version) =>
1722
+ DatabaseClusterEngine.auroraPostgres({
1723
+ version: version as AuroraPostgresEngineVersion,
1724
+ }),
1725
+ };
1726
+ }
1727
+ }
1728
+
1729
+ type _AuroraDatabaseProps = Omit<
1730
+ DatabaseClusterProps,
1731
+ | 'credentials'
1732
+ | 'defaultDatabaseName'
1733
+ | 'engine'
1734
+ | 'iamAuthentication'
1735
+ | 'instanceProps'
1736
+ | 'writer'
1737
+ >;
1738
+
1739
+ export interface AuroraDatabaseProps extends _AuroraDatabaseProps {
1740
+ /**
1741
+ * VPC where the Aurora cluster will be deployed.
1742
+ */
1743
+ readonly vpc: IVpc;
1744
+
1745
+ /**
1746
+ * Aurora engine preset used to build the cluster.
1747
+ */
1748
+ readonly engine: AuroraDatabaseEngine;
1749
+
1750
+ /**
1751
+ * The engine version to deploy.
1752
+ *
1753
+ * @default - engine.defaultVersion
1754
+ */
1755
+ readonly engineVersion?: AuroraDatabaseEngineVersion;
1756
+
1757
+ /**
1758
+ * Admin username used when generating credentials.
1759
+ */
1760
+ readonly adminUser: string;
1761
+
1762
+ /**
1763
+ * The initial database created in the cluster.
1764
+ */
1765
+ readonly databaseName: string;
1766
+
1767
+ /**
1768
+ * RuntimeConfig key used under the \`database\` namespace.
1769
+ */
1770
+ readonly runtimeConfigKey: string;
1771
+
1772
+ /**
1773
+ * Writer instance for the Aurora cluster.
1774
+ */
1775
+ readonly writer?: DatabaseClusterProps['writer'];
1776
+
1777
+ /**
1778
+ * Whether to provision an RDS Proxy in front of the Aurora cluster.
1779
+ *
1780
+ * @default true
1781
+ */
1782
+ readonly enableRdsProxy?: boolean;
1783
+
1784
+ /**
1785
+ * Whether to enable automatic credential rotation for the admin secret.
1786
+ *
1787
+ * @default true
1788
+ */
1789
+ readonly enableCredentialRotation?: boolean;
1790
+
1791
+ /**
1792
+ * Whether to enable deletion protection on the Aurora cluster.
1793
+ *
1794
+ * @default true
1795
+ */
1796
+ readonly deletionProtection?: boolean;
1797
+
1798
+ /**
1799
+ * Removal policy applied to the Aurora cluster.
1800
+ *
1801
+ * @default RemovalPolicy.RETAIN
1802
+ */
1803
+ readonly removalPolicy?: RemovalPolicy;
1804
+
1805
+ /**
1806
+ * Whether to enable automatic key rotation on the KMS key used to encrypt the Aurora cluster and its credentials secret.
1807
+ *
1808
+ * @default true
1809
+ */
1810
+ readonly enableKeyRotation?: boolean;
1811
+
1812
+ /**
1813
+ * Whether to export Aurora engine logs to CloudWatch Logs.
1814
+ * See https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_LogAccess.html
1815
+ *
1816
+ * @default false
1817
+ */
1818
+ readonly enableCloudwatchLogs?: boolean;
1819
+
1820
+ /**
1821
+ * Whether to enable Performance Insights on the Aurora writer instance.
1822
+ *
1823
+ * @default true
1824
+ */
1825
+ readonly enablePerformanceInsights?: boolean;
1826
+ }
1827
+
1828
+ /**
1829
+ * Reusable Aurora database construct that supports different Aurora engines
1830
+ * through typed engine presets.
1831
+ */
1832
+ export abstract class AuroraDatabase extends Construct {
1833
+ public readonly cluster: DatabaseCluster;
1834
+ public readonly proxy?: DatabaseProxy;
1835
+ private readonly adminUser: string;
1836
+ private readonly dbUser: string;
1837
+
1838
+ constructor(
1839
+ scope: Construct,
1840
+ id: string,
1841
+ {
1842
+ vpc,
1843
+ adminUser,
1844
+ databaseName,
1845
+ runtimeConfigKey,
1846
+ vpcSubnets,
1847
+ writer,
1848
+ enableRdsProxy = true,
1849
+ enableCredentialRotation = true,
1850
+ deletionProtection = true,
1851
+ removalPolicy = RemovalPolicy.RETAIN,
1852
+ enableKeyRotation = true,
1853
+ enableCloudwatchLogs = false,
1854
+ enablePerformanceInsights = true,
1855
+ engine,
1856
+ engineVersion,
1857
+ ...clusterProps
1858
+ }: AuroraDatabaseProps,
1859
+ ) {
1860
+ super(scope, id);
1861
+
1862
+ this.adminUser = adminUser;
1863
+
1864
+ const key = new Key(this, 'EncryptionKey', { enableKeyRotation });
1865
+ this.cluster = new DatabaseCluster(this, 'DatabaseCluster', {
1866
+ ...clusterProps,
1867
+ vpc,
1868
+ vpcSubnets,
1869
+ engine: engine.clusterEngine(engineVersion ?? engine.defaultVersion),
1870
+ writer:
1871
+ writer ??
1872
+ ClusterInstance.serverlessV2('writer', {
1873
+ enablePerformanceInsights,
1874
+ performanceInsightEncryptionKey: enablePerformanceInsights
1875
+ ? key
1876
+ : undefined,
1877
+ }),
1878
+ credentials: Credentials.fromGeneratedSecret(adminUser, {
1879
+ encryptionKey: key,
1880
+ }),
1881
+ iamAuthentication: true,
1882
+ monitoringInterval: Duration.seconds(5),
1883
+ cloudwatchLogsExports: enableCloudwatchLogs
1884
+ ? engine.type === 'mysql'
1885
+ ? ['audit', 'error', 'general', 'slowquery']
1886
+ : ['postgresql']
1887
+ : undefined,
1888
+ defaultDatabaseName: databaseName,
1889
+ storageEncrypted: true,
1890
+ storageEncryptionKey: key,
1891
+ deletionProtection,
1892
+ removalPolicy,
1893
+ });
1894
+
1895
+ if (enableCredentialRotation) {
1896
+ this.cluster.addRotationSingleUser({
1897
+ automaticallyAfter: Duration.days(30),
1898
+ vpcSubnets: {
1899
+ subnetType: SubnetType.PRIVATE_WITH_EGRESS,
1900
+ },
1901
+ });
1902
+ }
1903
+
1904
+ const proxyRole = enableRdsProxy
1905
+ ? new Role(this, 'DatabaseProxyRole', {
1906
+ assumedBy: new ServicePrincipal('rds.amazonaws.com'),
1907
+ })
1908
+ : undefined;
1909
+
1910
+ if (enableRdsProxy) {
1911
+ this.proxy = this.cluster.addProxy('DatabaseProxy', {
1912
+ vpc,
1913
+ vpcSubnets,
1914
+ defaultAuthScheme: DefaultAuthScheme.IAM_AUTH,
1915
+ role: proxyRole,
1916
+ });
1917
+ }
1918
+
1919
+ const databaseHostname =
1920
+ this.proxy?.endpoint ?? this.cluster.clusterEndpoint.hostname;
1921
+ const databasePort = this.cluster.clusterEndpoint.port;
1922
+
1923
+ const commonProps: FunctionOptions = {
1924
+ vpc,
1925
+ timeout: Duration.minutes(5),
1926
+ tracing: Tracing.ACTIVE,
1927
+ architecture: Architecture.ARM_64,
1928
+ };
1929
+
1930
+ const createDbUserHandler = this.createDbUserHandler({
1931
+ ...commonProps,
1932
+ vpcSubnets: {
1933
+ subnetType: SubnetType.PRIVATE_WITH_EGRESS,
1934
+ },
1935
+ });
1936
+ createDbUserHandler.addEnvironment(
1937
+ 'DATABASE_SECRET_ARN',
1938
+ this.cluster.secret!.secretArn,
1939
+ );
1940
+ this.cluster.connections.allowDefaultPortFrom(
1941
+ createDbUserHandler,
1942
+ 'Allow the create-db-user handler to connect to the database',
1943
+ );
1944
+ this.grantSecretRead(createDbUserHandler);
1945
+
1946
+ const createDbUserProvider = new Provider(this, 'CreateDbUserProvider', {
1947
+ onEventHandler: createDbUserHandler,
1948
+ });
1949
+
1950
+ const createDbUserResource = new CustomResource(
1951
+ this,
1952
+ 'CreateDbUserResource',
1953
+ {
1954
+ serviceToken: createDbUserProvider.serviceToken,
1955
+ properties: {
1956
+ clusterIdentifier: this.cluster.clusterIdentifier,
1957
+ },
1958
+ },
1959
+ );
1960
+ createDbUserResource.node.addDependency(this.cluster);
1961
+ this.dbUser = createDbUserResource.getAttString('dbUser');
1962
+ if (this.proxy && proxyRole) {
1963
+ this.cluster.grantConnect(proxyRole, this.dbUser);
1964
+ }
1965
+
1966
+ const rc = RuntimeConfig.ensure(this);
1967
+ rc.set('database', runtimeConfigKey, {
1968
+ hostname: databaseHostname,
1969
+ port: databasePort,
1970
+ database: databaseName,
1971
+ adminUser: this.adminUser,
1972
+ dbUser: this.dbUser,
1973
+ region: Stack.of(this).region,
1974
+ });
1975
+
1976
+ const migrationHandler = this.createMigrationHandler({
1977
+ ...commonProps,
1978
+ memorySize: 1024,
1979
+ });
1980
+ migrationHandler.addEnvironment(
1981
+ 'DATABASE_SECRET_ARN',
1982
+ this.cluster.secret!.secretArn,
1983
+ );
1984
+ this.cluster.connections.allowDefaultPortFrom(migrationHandler);
1985
+ this.grantSecretRead(migrationHandler);
1986
+
1987
+ const migrationTrigger = new Trigger(this, 'MigrationTrigger', {
1988
+ handler: migrationHandler,
1989
+ });
1990
+ migrationTrigger.node.addDependency(createDbUserResource);
1991
+
1992
+ new CfnOutput(this, 'ClusterEndpoint', {
1993
+ value: this.cluster.clusterEndpoint.hostname,
1994
+ });
1995
+
1996
+ if (this.proxy?.endpoint) {
1997
+ new CfnOutput(this, 'ProxyEndpoint', {
1998
+ value: this.proxy?.endpoint,
1999
+ });
2000
+ }
2001
+ }
2002
+
2003
+ /**
2004
+ * Creates the Lambda handler used to create or reconcile the application database user.
2005
+ */
2006
+ protected abstract createDbUserHandler(baseProps: FunctionOptions): Function;
2007
+
2008
+ /**
2009
+ * Creates the Lambda handler used to run database migrations.
2010
+ */
2011
+ protected abstract createMigrationHandler(
2012
+ baseProps: FunctionOptions,
2013
+ ): Function;
2014
+
2015
+ public allowDefaultPortFrom(other: IConnectable, description?: string): void {
2016
+ if (this.proxy) {
2017
+ this.proxy.connections.allowFrom(
2018
+ other,
2019
+ Port.tcp(this.cluster.clusterEndpoint.port),
2020
+ description,
2021
+ );
2022
+ } else {
2023
+ this.cluster.connections.allowDefaultPortFrom(other, description);
2024
+ }
2025
+ }
2026
+
2027
+ public grantSecretRead(grantee: IGrantable) {
2028
+ return this.cluster.secret!.grantRead(grantee);
2029
+ }
2030
+
2031
+ public grantConnect(grantee: IGrantable) {
2032
+ return this.proxy
2033
+ ? this.proxy.grantConnect(grantee, this.dbUser)
2034
+ : this.cluster.grantConnect(grantee, this.dbUser);
2035
+ }
2036
+ }
2037
+ "
2038
+ `;