@aws/nx-plugin 1.0.0-rc.2 → 1.0.0-rc.21

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 (633) hide show
  1. package/LICENSE-THIRD-PARTY +3552 -4179
  2. package/README.md +8 -8
  3. package/executors.json +9 -0
  4. package/generators.json +100 -1
  5. package/package.json +16 -12
  6. package/sdk/agentcore-gateway.d.ts +6 -0
  7. package/sdk/agentcore-gateway.js +11 -0
  8. package/sdk/agentcore-gateway.js.map +1 -0
  9. package/sdk/license.d.ts +8 -0
  10. package/sdk/license.js +14 -0
  11. package/sdk/license.js.map +1 -0
  12. package/sdk/py.d.ts +6 -6
  13. package/sdk/py.js +7 -7
  14. package/sdk/py.js.map +1 -1
  15. package/sdk/ts.d.ts +18 -14
  16. package/sdk/ts.js +38 -32
  17. package/sdk/ts.js.map +1 -1
  18. package/src/agentcore-gateway/attach-upstream.d.ts +33 -0
  19. package/src/agentcore-gateway/attach-upstream.js +41 -0
  20. package/src/agentcore-gateway/attach-upstream.js.map +1 -0
  21. package/src/agentcore-gateway/files/cedar/policies/README.md +52 -0
  22. package/src/agentcore-gateway/files/cedar/policies/permit-all.cedar +11 -0
  23. package/src/agentcore-gateway/files/project/serve-local.ts.template +134 -0
  24. package/src/agentcore-gateway/gateway-connection/generator.d.ts +21 -0
  25. package/src/agentcore-gateway/gateway-connection/generator.js +102 -0
  26. package/src/agentcore-gateway/gateway-connection/generator.js.map +1 -0
  27. package/src/agentcore-gateway/gateway-connection/schema.d.ts +12 -0
  28. package/src/agentcore-gateway/gateway-connection/schema.json +26 -0
  29. package/src/agentcore-gateway/generator.d.ts +25 -0
  30. package/src/agentcore-gateway/generator.js +129 -0
  31. package/src/agentcore-gateway/generator.js.map +1 -0
  32. package/src/agentcore-gateway/mcp-connection/generator.d.ts +19 -0
  33. package/src/agentcore-gateway/mcp-connection/generator.js +63 -0
  34. package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -0
  35. package/src/agentcore-gateway/mcp-connection/schema.d.ts +12 -0
  36. package/src/agentcore-gateway/mcp-connection/schema.json +26 -0
  37. package/src/agentcore-gateway/schema.d.ts +16 -0
  38. package/src/agentcore-gateway/schema.json +65 -0
  39. package/src/connection/agent-runtime-config.d.ts +1 -1
  40. package/src/connection/agent-runtime-config.js.map +1 -1
  41. package/src/connection/agent-serve-local.d.ts +2 -2
  42. package/src/connection/agent-serve-local.js +1 -1
  43. package/src/connection/agent-serve-local.js.map +1 -1
  44. package/src/connection/generator.d.ts +5 -5
  45. package/src/connection/generator.js +93 -37
  46. package/src/connection/generator.js.map +1 -1
  47. package/src/connection/serve-local.d.ts +1 -1
  48. package/src/connection/serve-local.js +1 -1
  49. package/src/connection/serve-local.js.map +1 -1
  50. package/src/infra/app/__snapshots__/generator.spec.ts.snap +47 -58
  51. package/src/infra/app/generator.d.ts +3 -3
  52. package/src/infra/app/generator.js +19 -17
  53. package/src/infra/app/generator.js.map +1 -1
  54. package/src/license/__snapshots__/config.spec.ts.snap +23 -0
  55. package/src/license/config-types.d.ts +18 -1
  56. package/src/license/config-types.js +4 -0
  57. package/src/license/config-types.js.map +1 -1
  58. package/src/license/config.d.ts +65 -7
  59. package/src/license/config.js +315 -7
  60. package/src/license/config.js.map +1 -1
  61. package/src/license/dependency-check/check.d.ts +16 -0
  62. package/src/license/dependency-check/check.js +111 -0
  63. package/src/license/dependency-check/check.js.map +1 -0
  64. package/src/license/dependency-check/collectors/collector.d.ts +21 -0
  65. package/src/license/dependency-check/collectors/collector.js +76 -0
  66. package/src/license/dependency-check/collectors/collector.js.map +1 -0
  67. package/src/license/dependency-check/collectors/npm-collector.d.ts +10 -0
  68. package/src/license/dependency-check/collectors/npm-collector.js +75 -0
  69. package/src/license/dependency-check/collectors/npm-collector.js.map +1 -0
  70. package/src/license/dependency-check/collectors/python-collector.d.ts +23 -0
  71. package/src/license/dependency-check/collectors/python-collector.js +121 -0
  72. package/src/license/dependency-check/collectors/python-collector.js.map +1 -0
  73. package/src/license/dependency-check/evaluator.d.ts +9 -0
  74. package/src/license/dependency-check/evaluator.js +122 -0
  75. package/src/license/dependency-check/evaluator.js.map +1 -0
  76. package/src/license/dependency-check/executor-schema.json +6 -0
  77. package/src/license/dependency-check/executor.d.ts +9 -0
  78. package/src/license/dependency-check/executor.js +43 -0
  79. package/src/license/dependency-check/executor.js.map +1 -0
  80. package/src/license/dependency-check/pre-approved.d.ts +6 -0
  81. package/src/license/dependency-check/pre-approved.js +1280 -0
  82. package/src/license/dependency-check/pre-approved.js.map +1 -0
  83. package/src/license/dependency-check/types.d.ts +45 -0
  84. package/src/license/dependency-check/types.js +7 -0
  85. package/src/license/dependency-check/types.js.map +1 -0
  86. package/src/license/generator.d.ts +3 -3
  87. package/src/license/generator.js +102 -14
  88. package/src/license/generator.js.map +1 -1
  89. package/src/license/index.d.ts +8 -0
  90. package/src/license/index.js +13 -0
  91. package/src/license/index.js.map +1 -0
  92. package/src/license/known-exceptions.d.ts +6 -0
  93. package/src/license/known-exceptions.js +26 -0
  94. package/src/license/known-exceptions.js.map +1 -0
  95. package/src/license/schema.d.ts +5 -0
  96. package/src/license/schema.json +6 -0
  97. package/src/license/sync/generator.d.ts +2 -2
  98. package/src/license/sync/generator.js +15 -15
  99. package/src/license/sync/generator.js.map +1 -1
  100. package/src/license/sync/project-file-sync.d.ts +3 -3
  101. package/src/license/sync/project-file-sync.js.map +1 -1
  102. package/src/mcp-server/generator-info.d.ts +5 -1
  103. package/src/mcp-server/generator-info.js +7 -7
  104. package/src/mcp-server/generator-info.js.map +1 -1
  105. package/src/mcp-server/guide-pipeline.d.ts +1 -1
  106. package/src/mcp-server/guide-pipeline.js +2 -2
  107. package/src/mcp-server/guide-pipeline.js.map +1 -1
  108. package/src/mcp-server/mdx-ast.js +4 -0
  109. package/src/mcp-server/mdx-ast.js.map +1 -1
  110. package/src/mcp-server/schema-registry.d.ts +9 -3
  111. package/src/mcp-server/schema-registry.js +22 -6
  112. package/src/mcp-server/schema-registry.js.map +1 -1
  113. package/src/mcp-server/server.js +3 -3
  114. package/src/mcp-server/server.js.map +1 -1
  115. package/src/mcp-server/tools/create-workspace-command.d.ts +1 -1
  116. package/src/mcp-server/tools/create-workspace-command.js +4 -4
  117. package/src/mcp-server/tools/create-workspace-command.js.map +1 -1
  118. package/src/mcp-server/tools/general-guidance.d.ts +2 -2
  119. package/src/mcp-server/tools/general-guidance.js +2 -2
  120. package/src/mcp-server/tools/general-guidance.js.map +1 -1
  121. package/src/mcp-server/tools/generator-guide.d.ts +2 -2
  122. package/src/mcp-server/tools/generator-guide.js.map +1 -1
  123. package/src/mcp-server/tools/list-generators.d.ts +2 -2
  124. package/src/mcp-server/tools/list-generators.js +1 -1
  125. package/src/mcp-server/tools/list-generators.js.map +1 -1
  126. package/src/open-api/ts-client/__snapshots__/generator.reserved-keywords.spec.ts.snap +1 -1
  127. package/src/open-api/ts-client/generator.d.ts +3 -3
  128. package/src/open-api/ts-client/generator.js +2 -2
  129. package/src/open-api/ts-client/generator.js.map +1 -1
  130. package/src/open-api/ts-hooks/generator.d.ts +3 -3
  131. package/src/open-api/ts-hooks/generator.js +2 -2
  132. package/src/open-api/ts-hooks/generator.js.map +1 -1
  133. package/src/open-api/ts-hooks/generator.spec.tsx +14 -14
  134. package/src/open-api/ts-metadata/generator.d.ts +3 -3
  135. package/src/open-api/ts-metadata/generator.js +1 -1
  136. package/src/open-api/ts-metadata/generator.js.map +1 -1
  137. package/src/open-api/utils/codegen-data/languages.d.ts +5 -1
  138. package/src/open-api/utils/codegen-data/languages.js +4 -4
  139. package/src/open-api/utils/codegen-data/languages.js.map +1 -1
  140. package/src/open-api/utils/codegen-data.d.ts +6 -2
  141. package/src/open-api/utils/codegen-data.js +6 -6
  142. package/src/open-api/utils/codegen-data.js.map +1 -1
  143. package/src/open-api/utils/normalise.d.ts +5 -1
  144. package/src/open-api/utils/normalise.js +5 -5
  145. package/src/open-api/utils/normalise.js.map +1 -1
  146. package/src/open-api/utils/parse.d.ts +2 -2
  147. package/src/open-api/utils/parse.js +4 -0
  148. package/src/open-api/utils/parse.js.map +1 -1
  149. package/src/open-api/utils/refs.d.ts +1 -1
  150. package/src/preset/__snapshots__/generator.spec.ts.snap +131 -13
  151. package/src/preset/generator.d.ts +4 -4
  152. package/src/preset/generator.js +21 -14
  153. package/src/preset/generator.js.map +1 -1
  154. package/src/preset/schema.d.ts +3 -1
  155. package/src/preset/schema.json +5 -0
  156. package/src/py/agent/__snapshots__/generator.spec.ts.snap +659 -21
  157. package/src/py/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +201 -0
  158. package/src/py/agent/a2a-connection/files/agent-connection/app/__targetAgentSnakeCase___client_strands.py.template +30 -0
  159. package/src/py/agent/a2a-connection/generator.d.ts +3 -3
  160. package/src/py/agent/a2a-connection/generator.js +11 -10
  161. package/src/py/agent/a2a-connection/generator.js.map +1 -1
  162. package/src/py/agent/files/common/agent.py.template +2 -0
  163. package/src/py/agent/files/http/init.py.template +7 -25
  164. package/src/py/agent/files/http/main.py.template +2 -3
  165. package/src/py/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +197 -0
  166. package/src/py/agent/gateway-connection/files/agent-connection/app/__gatewaySnakeCase___client_strands.py.template +35 -0
  167. package/src/py/agent/gateway-connection/generator.d.ts +10 -0
  168. package/src/py/agent/gateway-connection/generator.js +106 -0
  169. package/src/py/agent/gateway-connection/generator.js.map +1 -0
  170. package/src/py/agent/gateway-connection/schema.d.ts +12 -0
  171. package/src/py/agent/gateway-connection/schema.json +26 -0
  172. package/src/py/agent/generator.d.ts +3 -3
  173. package/src/py/agent/generator.js +47 -38
  174. package/src/py/agent/generator.js.map +1 -1
  175. package/src/py/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +167 -81
  176. package/src/py/agent/mcp-connection/files/agent-connection/app/__mcpServerSnakeCase___client_strands.py.template +30 -0
  177. package/src/py/agent/mcp-connection/generator.d.ts +3 -3
  178. package/src/py/agent/mcp-connection/generator.js +11 -81
  179. package/src/py/agent/mcp-connection/generator.js.map +1 -1
  180. package/src/py/agent/react-connection/__snapshots__/generator.spec.ts.snap +8 -17
  181. package/src/py/agent/react-connection/generator.d.ts +3 -3
  182. package/src/py/agent/react-connection/generator.js +4 -4
  183. package/src/py/agent/react-connection/generator.js.map +1 -1
  184. package/src/py/agent/react-connection/serve-local.d.ts +2 -2
  185. package/src/py/agent/react-connection/serve-local.js.map +1 -1
  186. package/src/py/api/generator.d.ts +3 -3
  187. package/src/py/api/generator.js.map +1 -1
  188. package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +1486 -0
  189. package/src/py/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +45 -0
  190. package/src/py/dynamodb/agent-connection/generator.d.ts +10 -0
  191. package/src/py/dynamodb/agent-connection/generator.js +39 -0
  192. package/src/py/dynamodb/agent-connection/generator.js.map +1 -0
  193. package/src/py/dynamodb/agent-connection/schema.d.ts +14 -0
  194. package/src/py/dynamodb/agent-connection/schema.json +22 -0
  195. package/src/py/dynamodb/fast-api-connection/__snapshots__/generator.spec.ts.snap +23 -0
  196. package/src/py/dynamodb/fast-api-connection/generator.d.ts +10 -0
  197. package/src/py/dynamodb/fast-api-connection/generator.js +37 -0
  198. package/src/py/dynamodb/fast-api-connection/generator.js.map +1 -0
  199. package/src/py/dynamodb/fast-api-connection/schema.d.ts +12 -0
  200. package/src/py/dynamodb/fast-api-connection/schema.json +18 -0
  201. package/src/py/dynamodb/files/__name__/__init__.py.template +6 -0
  202. package/src/py/dynamodb/files/__name__/client.py.template +39 -0
  203. package/src/py/dynamodb/files/__name__/entities/__init__.py.template +4 -0
  204. package/src/py/dynamodb/files/__name__/entities/base.py.template +63 -0
  205. package/src/py/dynamodb/files/__name__/entities/example.py.template +64 -0
  206. package/src/py/dynamodb/files/config.json.template +24 -0
  207. package/src/py/dynamodb/generator.d.ts +10 -0
  208. package/src/py/dynamodb/generator.js +106 -0
  209. package/src/py/dynamodb/generator.js.map +1 -0
  210. package/src/py/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +45 -0
  211. package/src/py/dynamodb/mcp-server-connection/generator.d.ts +10 -0
  212. package/src/py/dynamodb/mcp-server-connection/generator.js +39 -0
  213. package/src/py/dynamodb/mcp-server-connection/generator.js.map +1 -0
  214. package/src/py/dynamodb/mcp-server-connection/schema.d.ts +14 -0
  215. package/src/py/dynamodb/mcp-server-connection/schema.json +22 -0
  216. package/src/py/dynamodb/schema.d.ts +15 -0
  217. package/src/py/dynamodb/schema.json +70 -0
  218. package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +167 -39
  219. package/src/py/fast-api/files/app/__name__/init.py.template +5 -22
  220. package/src/py/fast-api/files/app/__name__/main.py.template +4 -1
  221. package/src/py/fast-api/generator.d.ts +3 -3
  222. package/src/py/fast-api/generator.js +23 -17
  223. package/src/py/fast-api/generator.js.map +1 -1
  224. package/src/py/fast-api/react/__snapshots__/generator.spec.ts.snap +1 -1
  225. package/src/py/fast-api/react/generator.d.ts +3 -3
  226. package/src/py/fast-api/react/generator.js +2 -2
  227. package/src/py/fast-api/react/generator.js.map +1 -1
  228. package/src/py/fast-api/react/open-api.d.ts +1 -1
  229. package/src/py/fast-api/react/open-api.js +5 -2
  230. package/src/py/fast-api/react/open-api.js.map +1 -1
  231. package/src/py/lambda-function/generator.d.ts +3 -3
  232. package/src/py/lambda-function/generator.js +11 -11
  233. package/src/py/lambda-function/generator.js.map +1 -1
  234. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +83 -13
  235. package/src/py/mcp-server/generator.d.ts +3 -3
  236. package/src/py/mcp-server/generator.js +33 -26
  237. package/src/py/mcp-server/generator.js.map +1 -1
  238. package/src/py/project/generator.d.ts +3 -3
  239. package/src/py/project/generator.js +96 -70
  240. package/src/py/project/generator.js.map +1 -1
  241. package/src/smithy/project/__snapshots__/generator.spec.ts.snap +19 -16
  242. package/src/smithy/project/files/build.Dockerfile.template +1 -0
  243. package/src/smithy/project/files/src/operations/echo.smithy.template +1 -0
  244. package/src/smithy/project/generator.d.ts +3 -3
  245. package/src/smithy/project/generator.js +30 -28
  246. package/src/smithy/project/generator.js.map +1 -1
  247. package/src/smithy/react-connection/__snapshots__/generator.spec.ts.snap +1 -1
  248. package/src/smithy/react-connection/generator.d.ts +3 -3
  249. package/src/smithy/react-connection/generator.js +3 -3
  250. package/src/smithy/react-connection/generator.js.map +1 -1
  251. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +14 -34
  252. package/src/smithy/ts/api/generator.d.ts +3 -3
  253. package/src/smithy/ts/api/generator.js +18 -12
  254. package/src/smithy/ts/api/generator.js.map +1 -1
  255. package/src/terraform/project/files/application/src/main.tf.template +6 -1
  256. package/src/terraform/project/generator.d.ts +3 -3
  257. package/src/terraform/project/generator.js +13 -8
  258. package/src/terraform/project/generator.js.map +1 -1
  259. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +163 -18
  260. package/src/trpc/backend/files/src/procedures/echo.ts.template +1 -1
  261. package/src/trpc/backend/files/src/schema/echo.ts.template +2 -2
  262. package/src/trpc/backend/generator.d.ts +3 -3
  263. package/src/trpc/backend/generator.js +11 -10
  264. package/src/trpc/backend/generator.js.map +1 -1
  265. package/src/trpc/backend/schema.d.ts +2 -2
  266. package/src/trpc/react/__snapshots__/generator.spec.ts.snap +3 -3
  267. package/src/trpc/react/files/src/components/__apiNameClassName__ClientProvider.tsx.template +3 -3
  268. package/src/trpc/react/generator.d.ts +3 -3
  269. package/src/trpc/react/generator.js +5 -5
  270. package/src/trpc/react/generator.js.map +1 -1
  271. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +652 -14
  272. package/src/ts/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +256 -0
  273. package/src/ts/agent/a2a-connection/files/agent-connection/app/__targetAgentKebabCase__-client-strands.ts.template +23 -0
  274. package/src/ts/agent/a2a-connection/generator.d.ts +3 -3
  275. package/src/ts/agent/a2a-connection/generator.js +8 -8
  276. package/src/ts/agent/a2a-connection/generator.js.map +1 -1
  277. package/src/ts/agent/files/common/agent.ts.template +6 -2
  278. package/src/ts/agent/files/http/router.ts.template +1 -1
  279. package/src/ts/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +220 -0
  280. package/src/ts/agent/gateway-connection/files/agent-connection/app/__gatewayKebabCase__-client-strands.ts.template +30 -0
  281. package/src/ts/agent/gateway-connection/generator.d.ts +10 -0
  282. package/src/ts/agent/gateway-connection/generator.js +106 -0
  283. package/src/ts/agent/gateway-connection/generator.js.map +1 -0
  284. package/src/ts/agent/gateway-connection/schema.d.ts +12 -0
  285. package/src/ts/agent/gateway-connection/schema.json +26 -0
  286. package/src/ts/agent/generator.d.ts +3 -3
  287. package/src/ts/agent/generator.js +44 -32
  288. package/src/ts/agent/generator.js.map +1 -1
  289. package/src/ts/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +191 -110
  290. package/src/ts/agent/mcp-connection/files/agent-connection/app/__mcpServerKebabCase__-client-strands.ts.template +22 -0
  291. package/src/ts/agent/mcp-connection/generator.d.ts +3 -3
  292. package/src/ts/agent/mcp-connection/generator.js +9 -21
  293. package/src/ts/agent/mcp-connection/generator.js.map +1 -1
  294. package/src/ts/agent/react-connection/generator.d.ts +3 -3
  295. package/src/ts/agent/react-connection/generator.js +9 -9
  296. package/src/ts/agent/react-connection/generator.js.map +1 -1
  297. package/src/ts/agent/react-connection/serve-local.d.ts +2 -2
  298. package/src/ts/api/generator.d.ts +3 -3
  299. package/src/ts/api/generator.js +4 -4
  300. package/src/ts/api/generator.js.map +1 -1
  301. package/src/ts/api/schema.d.ts +2 -1
  302. package/src/ts/astro-docs/__snapshots__/generator.spec.ts.snap +7 -8
  303. package/src/ts/astro-docs/generator.d.ts +3 -3
  304. package/src/ts/astro-docs/generator.js +14 -11
  305. package/src/ts/astro-docs/generator.js.map +1 -1
  306. package/src/ts/docs/generator.d.ts +3 -3
  307. package/src/ts/docs/generator.js.map +1 -1
  308. package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +1352 -0
  309. package/src/ts/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +45 -0
  310. package/src/ts/dynamodb/agent-connection/generator.d.ts +10 -0
  311. package/src/ts/dynamodb/agent-connection/generator.js +32 -0
  312. package/src/ts/dynamodb/agent-connection/generator.js.map +1 -0
  313. package/src/ts/dynamodb/agent-connection/schema.d.ts +14 -0
  314. package/src/ts/dynamodb/agent-connection/schema.json +22 -0
  315. package/src/ts/dynamodb/files/config.json.template +24 -0
  316. package/src/ts/dynamodb/files/src/client.ts.template +61 -0
  317. package/src/ts/dynamodb/files/src/entities/example.ts.template +47 -0
  318. package/src/ts/dynamodb/files/src/entities/index.ts.template +1 -0
  319. package/src/ts/dynamodb/files/src/index.ts.template +2 -0
  320. package/src/ts/dynamodb/generator.d.ts +10 -0
  321. package/src/ts/dynamodb/generator.js +111 -0
  322. package/src/ts/dynamodb/generator.js.map +1 -0
  323. package/src/ts/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +45 -0
  324. package/src/ts/dynamodb/mcp-server-connection/generator.d.ts +10 -0
  325. package/src/ts/dynamodb/mcp-server-connection/generator.js +32 -0
  326. package/src/ts/dynamodb/mcp-server-connection/generator.js.map +1 -0
  327. package/src/ts/dynamodb/mcp-server-connection/schema.d.ts +14 -0
  328. package/src/ts/dynamodb/mcp-server-connection/schema.json +22 -0
  329. package/src/ts/dynamodb/schema.d.ts +15 -0
  330. package/src/ts/dynamodb/schema.json +70 -0
  331. package/src/ts/dynamodb/smithy-connection/__snapshots__/generator.spec.ts.snap +23 -0
  332. package/src/ts/dynamodb/smithy-connection/generator.d.ts +10 -0
  333. package/src/ts/dynamodb/smithy-connection/generator.js +30 -0
  334. package/src/ts/dynamodb/smithy-connection/generator.js.map +1 -0
  335. package/src/ts/dynamodb/smithy-connection/schema.d.ts +12 -0
  336. package/src/ts/dynamodb/smithy-connection/schema.json +18 -0
  337. package/src/ts/dynamodb/trpc-connection/__snapshots__/generator.spec.ts.snap +23 -0
  338. package/src/ts/dynamodb/trpc-connection/generator.d.ts +10 -0
  339. package/src/ts/dynamodb/trpc-connection/generator.js +30 -0
  340. package/src/ts/dynamodb/trpc-connection/generator.js.map +1 -0
  341. package/src/ts/dynamodb/trpc-connection/schema.d.ts +12 -0
  342. package/src/ts/dynamodb/trpc-connection/schema.json +18 -0
  343. package/src/ts/lambda-function/generator.d.ts +3 -3
  344. package/src/ts/lambda-function/generator.js +8 -8
  345. package/src/ts/lambda-function/generator.js.map +1 -1
  346. package/src/ts/lib/__snapshots__/generator.spec.ts.snap +32 -65
  347. package/src/ts/lib/__snapshots__/vitest.spec.ts.snap +24 -0
  348. package/src/ts/lib/biome.d.ts +7 -0
  349. package/src/ts/lib/biome.js +58 -0
  350. package/src/ts/lib/biome.js.map +1 -0
  351. package/src/ts/lib/generator.d.ts +3 -3
  352. package/src/ts/lib/generator.js +27 -29
  353. package/src/ts/lib/generator.js.map +1 -1
  354. package/src/ts/lib/grit/vitest-pass-with-no-tests.grit +1 -4
  355. package/src/ts/lib/ts-project-utils.d.ts +12 -2
  356. package/src/ts/lib/ts-project-utils.js +30 -10
  357. package/src/ts/lib/ts-project-utils.js.map +1 -1
  358. package/src/ts/lib/vitest.d.ts +2 -2
  359. package/src/ts/lib/vitest.js +1 -1
  360. package/src/ts/lib/vitest.js.map +1 -1
  361. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +82 -12
  362. package/src/ts/mcp-server/generator.d.ts +3 -3
  363. package/src/ts/mcp-server/generator.js +34 -12
  364. package/src/ts/mcp-server/generator.js.map +1 -1
  365. package/src/ts/nx-generator/__snapshots__/generator.spec.ts.snap +19 -14
  366. package/src/ts/nx-generator/generator.d.ts +2 -2
  367. package/src/ts/nx-generator/generator.js +52 -19
  368. package/src/ts/nx-generator/generator.js.map +1 -1
  369. package/src/ts/nx-plugin/generator.d.ts +3 -3
  370. package/src/ts/nx-plugin/generator.js +10 -9
  371. package/src/ts/nx-plugin/generator.js.map +1 -1
  372. package/src/ts/nx-plugin/utils.d.ts +1 -1
  373. package/src/ts/nx-plugin/utils.js +10 -4
  374. package/src/ts/nx-plugin/utils.js.map +1 -1
  375. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +252 -388
  376. package/src/ts/rdb/agent-connection/generator.d.ts +3 -3
  377. package/src/ts/rdb/agent-connection/generator.js +4 -4
  378. package/src/ts/rdb/agent-connection/generator.js.map +1 -1
  379. package/src/ts/rdb/files/config.json.template +14 -0
  380. package/src/ts/rdb/files/prisma.config.ts.template +5 -4
  381. package/src/ts/rdb/files/src/index.ts.template +0 -1
  382. package/src/ts/rdb/files/src/prisma.ts.template +26 -21
  383. package/src/ts/rdb/generator.d.ts +3 -7
  384. package/src/ts/rdb/generator.js +52 -41
  385. package/src/ts/rdb/generator.js.map +1 -1
  386. package/src/ts/rdb/mcp-server-connection/generator.d.ts +3 -3
  387. package/src/ts/rdb/mcp-server-connection/generator.js +4 -4
  388. package/src/ts/rdb/mcp-server-connection/generator.js.map +1 -1
  389. package/src/ts/rdb/smithy-connection/generator.d.ts +3 -3
  390. package/src/ts/rdb/smithy-connection/generator.js +4 -4
  391. package/src/ts/rdb/smithy-connection/generator.js.map +1 -1
  392. package/src/ts/rdb/trpc-connection/generator.d.ts +3 -3
  393. package/src/ts/rdb/trpc-connection/generator.js +3 -3
  394. package/src/ts/rdb/trpc-connection/generator.js.map +1 -1
  395. package/src/ts/rdb/utils.d.ts +1 -1
  396. package/src/ts/react-website/agui/files/common/src/hooks/useAgui__agentNameClassName__.tsx.template +1 -16
  397. package/src/ts/react-website/agui/generator.d.ts +1 -1
  398. package/src/ts/react-website/agui/generator.js +4 -5
  399. package/src/ts/react-website/agui/generator.js.map +1 -1
  400. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +530 -367
  401. package/src/ts/react-website/app/generator.d.ts +3 -3
  402. package/src/ts/react-website/app/generator.js +21 -17
  403. package/src/ts/react-website/app/generator.js.map +1 -1
  404. package/src/ts/react-website/cognito-auth/__snapshots__/generator.spec.ts.snap +1 -7
  405. package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +9 -3
  406. package/src/ts/react-website/cognito-auth/__snapshots__/generator.ux-provider.spec.ts.snap +0 -20
  407. package/src/ts/react-website/cognito-auth/generator.d.ts +3 -3
  408. package/src/ts/react-website/cognito-auth/generator.js +10 -13
  409. package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
  410. package/src/ts/react-website/cognito-auth/grit/cloudscape-auth-menu.grit +8 -6
  411. package/src/ts/react-website/cognito-auth/grit/cognito-auth-wrapper.grit +1 -1
  412. package/src/ts/react-website/cognito-auth/grit/none-auth-menu.grit +1 -0
  413. package/src/ts/react-website/cognito-auth/grit/shadcn-auth-menu.grit +3 -1
  414. package/src/ts/react-website/cognito-auth/grit/shadcn-state-declarations.grit +3 -1
  415. package/src/ts/react-website/cognito-auth/utils.d.ts +1 -1
  416. package/src/ts/react-website/cognito-auth/utils.js +1 -1
  417. package/src/ts/react-website/cognito-auth/utils.js.map +1 -1
  418. package/src/ts/react-website/runtime-config/generator.d.ts +3 -3
  419. package/src/ts/react-website/runtime-config/generator.js +4 -4
  420. package/src/ts/react-website/runtime-config/generator.js.map +1 -1
  421. package/src/ts/sync/generator.d.ts +3 -3
  422. package/src/ts/sync/generator.js +2 -2
  423. package/src/ts/sync/generator.js.map +1 -1
  424. package/src/ts/website/app/generator.d.ts +3 -3
  425. package/src/ts/website/app/generator.js +1 -1
  426. package/src/ts/website/app/generator.js.map +1 -1
  427. package/src/ts/website/auth/generator.d.ts +3 -3
  428. package/src/ts/website/auth/generator.js +1 -1
  429. package/src/ts/website/auth/generator.js.map +1 -1
  430. package/src/utils/agent-chat/agent-chat.d.ts +31 -0
  431. package/src/utils/agent-chat/agent-chat.js +30 -0
  432. package/src/utils/agent-chat/agent-chat.js.map +1 -0
  433. package/src/utils/agent-chat/files/a2a/chat.ts.template +33 -0
  434. package/src/utils/agent-chat/files/ag-ui/chat.ts.template +17 -0
  435. package/src/utils/agent-chat/files/common/agentcore.ts.template +81 -0
  436. package/src/utils/agent-chat/files/http-py/chat.ts.template +43 -0
  437. package/src/utils/agent-chat/files/http-ts/chat.ts.template +54 -0
  438. package/src/utils/agent-connection/agent-connection.d.ts +67 -24
  439. package/src/utils/agent-connection/agent-connection.js +236 -44
  440. package/src/utils/agent-connection/agent-connection.js.map +1 -1
  441. package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client-config.ts.template +93 -0
  442. package/src/utils/agent-connection/files/core-auth/agentcore-endpoints.ts.template +37 -0
  443. package/src/utils/agent-connection/files/core-auth/agentcore-fetch.ts.template +54 -0
  444. package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-transport.ts.template +41 -0
  445. package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-transport.ts.template +70 -0
  446. package/src/utils/agent-connection/files/core-runtime-config/runtime-config.ts.template +22 -32
  447. package/src/utils/agent-connection/files/core-shared/agentcore-transport.ts.template +39 -0
  448. package/src/utils/agent-connection/files/core-strands/a2a/agentcore-a2a-client-strands.ts.template +61 -0
  449. package/src/utils/agent-connection/files/core-strands/base/model-errors-strands.ts.template +36 -0
  450. package/src/utils/agent-connection/files/core-strands/gateway/agentcore-gateway-mcp-client-strands.ts.template +26 -0
  451. package/src/utils/agent-connection/files/core-strands/mcp/agentcore-mcp-client-strands.ts.template +27 -0
  452. package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client_config.py.template +43 -0
  453. package/src/utils/agent-connection/files/py-core-auth/agentcore_endpoints.py.template +47 -0
  454. package/src/utils/agent-connection/files/py-core-auth/auth/session.py.template +51 -0
  455. package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_transport.py.template +28 -0
  456. package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_transport.py.template +34 -0
  457. package/src/utils/agent-connection/files/py-core-runtime-config/runtime_config.py.template +5 -18
  458. package/src/utils/agent-connection/files/py-core-shared/agentcore_transport.py.template +40 -0
  459. package/src/utils/agent-connection/files/py-core-strands/a2a/agentcore_a2a_client_strands.py.template +66 -0
  460. package/src/utils/agent-connection/files/py-core-strands/base/model_errors_strands.py.template +40 -0
  461. package/src/utils/agent-connection/files/py-core-strands/gateway/agentcore_gateway_mcp_client_strands.py.template +22 -0
  462. package/src/utils/agent-connection/files/py-core-strands/mcp/agentcore_mcp_client_strands.py.template +30 -0
  463. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +11 -3
  464. package/src/utils/agent-core-constructs/agent-core-constructs.js +57 -12
  465. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  466. package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +4 -0
  467. package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +40 -0
  468. package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +375 -0
  469. package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/readiness-probe/index.js.template +55 -0
  470. package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +335 -0
  471. package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/render-cedar.cjs.template +13 -0
  472. package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +77 -9
  473. package/src/utils/agent-core-constructs/files/terraform/core/agentcore-gateway/gateway.tf.template +14 -0
  474. package/src/utils/api-constructs/api-constructs.d.ts +2 -2
  475. package/src/utils/api-constructs/api-constructs.js +1 -1
  476. package/src/utils/api-constructs/api-constructs.js.map +1 -1
  477. package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +3 -0
  478. package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +9 -0
  479. package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +23 -1
  480. package/src/utils/api-constructs/files/cdk/core/api/utils/utils.ts.template +61 -7
  481. package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +3 -0
  482. package/src/utils/api-constructs/open-api-metadata.d.ts +2 -2
  483. package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
  484. package/src/utils/ast/website.d.ts +5 -1
  485. package/src/utils/ast/website.js +3 -3
  486. package/src/utils/ast/website.js.map +1 -1
  487. package/src/utils/ast.d.ts +33 -1
  488. package/src/utils/ast.js +89 -4
  489. package/src/utils/ast.js.map +1 -1
  490. package/src/utils/bundle/bundle.d.ts +1 -1
  491. package/src/utils/bundle/bundle.js +2 -2
  492. package/src/utils/bundle/bundle.js.map +1 -1
  493. package/src/utils/config/index.d.ts +5 -5
  494. package/src/utils/config/utils.d.ts +13 -3
  495. package/src/utils/config/utils.js +37 -5
  496. package/src/utils/config/utils.js.map +1 -1
  497. package/src/utils/connection/open-api/files/components/__apiNameClassName__Provider.tsx.template +1 -1
  498. package/src/utils/connection/open-api/react.d.ts +1 -1
  499. package/src/utils/connection/open-api/react.js +4 -4
  500. package/src/utils/connection/open-api/react.js.map +1 -1
  501. package/src/utils/containers.d.ts +1 -1
  502. package/src/utils/dynamodb-constructs/dynamodb-constructs.d.ts +18 -0
  503. package/src/utils/dynamodb-constructs/dynamodb-constructs.js +49 -0
  504. package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -0
  505. package/src/utils/dynamodb-constructs/files/cdk/app/dynamodb/__nameKebabCase__.ts.template +43 -0
  506. package/src/utils/dynamodb-constructs/files/cdk/core/dynamodb.ts.template +105 -0
  507. package/src/utils/dynamodb-constructs/files/terraform/app/dynamodb/__nameKebabCase__/__nameKebabCase__.tf.template +62 -0
  508. package/src/utils/dynamodb-constructs/files/terraform/core/dynamodb/dynamodb.tf.template +155 -0
  509. package/src/utils/files/common/scripts/src/dynamodb/create-local-table.ts.template +195 -0
  510. package/src/utils/files/common/scripts/src/dynamodb/pull-image.ts.template +13 -0
  511. package/src/utils/files/common/scripts/src/dynamodb/start-container.ts.template +91 -0
  512. package/src/utils/files/common/scripts/src/rdb/pull-image.ts.template +16 -0
  513. package/src/utils/files/common/scripts/src/rdb/start-container.ts.template +102 -0
  514. package/src/utils/files/common/scripts/src/rdb/wait-for-db.ts.template +59 -0
  515. package/src/utils/files/terraform/src/core/runtime-config/appconfig-deployment/appconfig-deployment.tf.template +9 -3
  516. package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +7 -2
  517. package/src/utils/format.d.ts +45 -2
  518. package/src/utils/format.js +167 -46
  519. package/src/utils/format.js.map +1 -1
  520. package/src/utils/fs.d.ts +1 -1
  521. package/src/utils/fs.js.map +1 -1
  522. package/src/utils/function-constructs/function-constructs.d.ts +2 -2
  523. package/src/utils/function-constructs/function-constructs.js +1 -1
  524. package/src/utils/function-constructs/function-constructs.js.map +1 -1
  525. package/src/utils/generators.d.ts +4 -0
  526. package/src/utils/generators.js +4 -4
  527. package/src/utils/generators.js.map +1 -1
  528. package/src/utils/git.d.ts +1 -1
  529. package/src/utils/git.js.map +1 -1
  530. package/src/utils/iac.d.ts +1 -1
  531. package/src/utils/iac.js.map +1 -1
  532. package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +1 -5
  533. package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +9 -3
  534. package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +2 -4
  535. package/src/utils/identity-constructs/identity-constructs.d.ts +2 -2
  536. package/src/utils/identity-constructs/identity-constructs.js +1 -1
  537. package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
  538. package/src/utils/js.d.ts +4 -0
  539. package/src/utils/js.js +4 -4
  540. package/src/utils/js.js.map +1 -1
  541. package/src/utils/mcp.d.ts +25 -0
  542. package/src/utils/mcp.js +81 -0
  543. package/src/utils/mcp.js.map +1 -0
  544. package/src/utils/metrics.d.ts +9 -3
  545. package/src/utils/metrics.js +58 -28
  546. package/src/utils/metrics.js.map +1 -1
  547. package/src/utils/npm-scope.d.ts +1 -1
  548. package/src/utils/npm-scope.js.map +1 -1
  549. package/src/utils/nx.d.ts +7 -2
  550. package/src/utils/nx.js +46 -14
  551. package/src/utils/nx.js.map +1 -1
  552. package/src/utils/nxlv-python.d.ts +1 -1
  553. package/src/utils/paths.d.ts +1 -1
  554. package/src/utils/pnpm-workspace.d.ts +1 -1
  555. package/src/utils/pnpm-workspace.js.map +1 -1
  556. package/src/utils/port.d.ts +31 -3
  557. package/src/utils/port.js +74 -4
  558. package/src/utils/port.js.map +1 -1
  559. package/src/utils/py.d.ts +2 -2
  560. package/src/utils/py.js +13 -6
  561. package/src/utils/py.js.map +1 -1
  562. package/src/utils/rdb-constructs/files/cdk/app/dbs/__nameKebabCase__.ts.template +12 -2
  563. package/src/utils/rdb-constructs/files/cdk/core/rdb/aurora.ts.template +30 -1
  564. package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +38 -16
  565. package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +28 -13
  566. package/src/utils/rdb-constructs/rdb-constructs.d.ts +5 -4
  567. package/src/utils/rdb-constructs/rdb-constructs.js +3 -11
  568. package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
  569. package/src/utils/shared-constructs-constants.d.ts +1 -0
  570. package/src/utils/shared-constructs-constants.js +2 -1
  571. package/src/utils/shared-constructs-constants.js.map +1 -1
  572. package/src/utils/shared-constructs.d.ts +2 -2
  573. package/src/utils/shared-constructs.js +7 -7
  574. package/src/utils/shared-constructs.js.map +1 -1
  575. package/src/utils/shared-dynamodb-scripts.d.ts +11 -0
  576. package/src/utils/shared-dynamodb-scripts.js +23 -0
  577. package/src/utils/shared-dynamodb-scripts.js.map +1 -0
  578. package/src/utils/shared-infra-config.d.ts +1 -1
  579. package/src/utils/shared-infra-config.js +1 -1
  580. package/src/utils/shared-infra-config.js.map +1 -1
  581. package/src/utils/shared-infra-scripts.d.ts +11 -0
  582. package/src/utils/shared-infra-scripts.js +35 -0
  583. package/src/utils/shared-infra-scripts.js.map +1 -0
  584. package/src/utils/shared-rdb-scripts.d.ts +11 -0
  585. package/src/utils/shared-rdb-scripts.js +20 -0
  586. package/src/utils/shared-rdb-scripts.js.map +1 -0
  587. package/src/utils/shared-scripts.d.ts +2 -5
  588. package/src/utils/shared-scripts.js +2 -23
  589. package/src/utils/shared-scripts.js.map +1 -1
  590. package/src/utils/shared-shadcn.d.ts +1 -1
  591. package/src/utils/shared-shadcn.js +1 -13
  592. package/src/utils/shared-shadcn.js.map +1 -1
  593. package/src/utils/test.d.ts +5 -1
  594. package/src/utils/test.js +9 -5
  595. package/src/utils/test.js.map +1 -1
  596. package/src/utils/toml.d.ts +1 -1
  597. package/src/utils/toml.js +4 -0
  598. package/src/utils/toml.js.map +1 -1
  599. package/src/utils/versions.d.ts +82 -83
  600. package/src/utils/versions.js +81 -82
  601. package/src/utils/versions.js.map +1 -1
  602. package/src/utils/website-constructs/files/cdk/core/static-website.ts.template +72 -5
  603. package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +63 -15
  604. package/src/utils/website-constructs/website-constructs.d.ts +2 -2
  605. package/src/utils/website-constructs/website-constructs.js +1 -1
  606. package/src/utils/website-constructs/website-constructs.js.map +1 -1
  607. package/src/py/agent/a2a-connection/files/agent-connection/app/__targetAgentSnakeCase___client.py.template +0 -22
  608. package/src/py/agent/mcp-connection/files/agent-connection/app/__mcpServerSnakeCase___client.py.template +0 -22
  609. package/src/py/agent/scripts/http/chat.ts.template +0 -38
  610. package/src/ts/agent/a2a-connection/files/agent-connection/app/__targetAgentKebabCase__-client.ts.template +0 -19
  611. package/src/ts/agent/mcp-connection/files/agent-connection/app/__mcpServerKebabCase__-client.ts.template +0 -19
  612. package/src/ts/agent/scripts/http/chat.ts.template +0 -35
  613. package/src/ts/lib/eslint.d.ts +0 -14
  614. package/src/ts/lib/eslint.js +0 -90
  615. package/src/ts/lib/eslint.js.map +0 -1
  616. package/src/ts/lib/grit/eslint-dependency-checks-warn.grit +0 -1
  617. package/src/ts/rdb/files/scripts/docker-pull.ts.template +0 -15
  618. package/src/ts/rdb/files/scripts/docker-start.ts.template +0 -84
  619. package/src/ts/rdb/files/scripts/wait-for-db.ts.template +0 -55
  620. package/src/ts/rdb/files/src/constants.ts.template +0 -8
  621. package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client.ts.template +0 -123
  622. package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-client.ts.template +0 -128
  623. package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client.py.template +0 -120
  624. package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_client.py.template +0 -89
  625. /package/src/utils/agent-connection/files/{core-runtime-config/with-session-id.ts.template → core-strands/base/with-session-id-strands.ts.template} +0 -0
  626. /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
  627. /package/src/utils/files/common/scripts/src/{index.ts.template → infra/index.ts.template} +0 -0
  628. /package/src/utils/files/common/scripts/src/{infra-deploy.ts.template → infra/infra-deploy.ts.template} +0 -0
  629. /package/src/utils/files/common/scripts/src/{infra-destroy.ts.template → infra/infra-destroy.ts.template} +0 -0
  630. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/cdk-command.ts.template +0 -0
  631. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/credentials.ts.template +0 -0
  632. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/run.ts.template +0 -0
  633. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/stage-parser.ts.template +0 -0
@@ -0,0 +1,1352 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`ts#dynamodb generator > should generate scripts for finch engine 1`] = `
4
+ "{
5
+ "runtimeConfigKey": "MyTable",
6
+ "serveLocal": {
7
+ "port": 8000,
8
+ "tableName": "proj-my-table",
9
+ "image": "public.ecr.aws/aws-dynamodb-local/aws-dynamodb-local:latest",
10
+ "containerName": "proj-dynamodb",
11
+ "containerEngine": "finch"
12
+ },
13
+ "tableConfig": {
14
+ "globalSecondaryIndexes": [
15
+ {
16
+ "indexName": "gsi1pk-gsi1sk-index",
17
+ "partitionKey": "gsi1pk",
18
+ "sortKey": "gsi1sk"
19
+ },
20
+ {
21
+ "indexName": "gsi2pk-gsi2sk-index",
22
+ "partitionKey": "gsi2pk",
23
+ "sortKey": "gsi2sk"
24
+ }
25
+ ]
26
+ }
27
+ }
28
+ "
29
+ `;
30
+
31
+ exports[`ts#dynamodb generator > should generate terraform modules when iac is terraform 1`] = `
32
+ "terraform {
33
+ required_version = ">= 1.0"
34
+
35
+ required_providers {
36
+ aws = {
37
+ source = "hashicorp/aws"
38
+ version = "~> 6.0"
39
+ }
40
+ }
41
+ }
42
+
43
+ variable "name" {
44
+ description = "Name for the DynamoDB table."
45
+ type = string
46
+ }
47
+
48
+ variable "billing_mode" {
49
+ description = "Controls how you are charged for read and write throughput."
50
+ type = string
51
+ default = "PAY_PER_REQUEST"
52
+ }
53
+
54
+ variable "point_in_time_recovery_enabled" {
55
+ description = "Whether to enable point-in-time recovery for the table."
56
+ type = bool
57
+ default = true
58
+ }
59
+
60
+ variable "deletion_protection_enabled" {
61
+ description = "Whether to enable deletion protection on the table."
62
+ type = bool
63
+ default = true
64
+ }
65
+
66
+ variable "enable_key_rotation" {
67
+ description = "Whether to enable automatic key rotation on the KMS key used to encrypt the table."
68
+ type = bool
69
+ default = true
70
+ }
71
+
72
+ variable "global_secondary_indexes" {
73
+ description = "Global secondary indexes to create on the table. All key attributes must be of type string."
74
+ type = list(object({
75
+ name = string
76
+ hash_key = string
77
+ range_key = string
78
+ projection_type = string
79
+ }))
80
+ default = []
81
+ }
82
+
83
+ locals {
84
+ gsi_attribute_names = distinct(flatten([
85
+ for gsi in var.global_secondary_indexes : [gsi.hash_key, gsi.range_key]
86
+ ]))
87
+ }
88
+
89
+ data "aws_caller_identity" "current" {}
90
+ data "aws_partition" "current" {}
91
+
92
+ resource "aws_kms_key" "table" {
93
+ description = "KMS key for DynamoDB table \${var.name}"
94
+ enable_key_rotation = var.enable_key_rotation
95
+
96
+ policy = jsonencode({
97
+ Version = "2012-10-17"
98
+ Statement = [
99
+ {
100
+ Sid = "EnableRootAccess"
101
+ Effect = "Allow"
102
+ Principal = {
103
+ AWS = "arn:\${data.aws_partition.current.partition}:iam::\${data.aws_caller_identity.current.account_id}:root"
104
+ }
105
+ Action = "kms:*"
106
+ Resource = "*"
107
+ },
108
+ {
109
+ Sid = "AllowDynamoDBService"
110
+ Effect = "Allow"
111
+ Principal = {
112
+ Service = "dynamodb.amazonaws.com"
113
+ }
114
+ Action = [
115
+ "kms:Encrypt",
116
+ "kms:Decrypt",
117
+ "kms:ReEncrypt*",
118
+ "kms:GenerateDataKey*",
119
+ "kms:DescribeKey",
120
+ "kms:CreateGrant"
121
+ ]
122
+ Resource = "*"
123
+ }
124
+ ]
125
+ })
126
+ }
127
+
128
+ resource "aws_dynamodb_table" "table" {
129
+ name = var.name
130
+ billing_mode = var.billing_mode
131
+ hash_key = "pk"
132
+ range_key = "sk"
133
+ deletion_protection_enabled = var.deletion_protection_enabled
134
+
135
+ attribute {
136
+ name = "pk"
137
+ type = "S"
138
+ }
139
+
140
+ attribute {
141
+ name = "sk"
142
+ type = "S"
143
+ }
144
+
145
+ dynamic "attribute" {
146
+ for_each = toset(local.gsi_attribute_names)
147
+ content {
148
+ name = attribute.value
149
+ type = "S"
150
+ }
151
+ }
152
+
153
+ dynamic "global_secondary_index" {
154
+ for_each = var.global_secondary_indexes
155
+ content {
156
+ name = global_secondary_index.value.name
157
+ hash_key = global_secondary_index.value.hash_key
158
+ range_key = global_secondary_index.value.range_key
159
+ projection_type = global_secondary_index.value.projection_type
160
+ }
161
+ }
162
+
163
+ point_in_time_recovery {
164
+ enabled = var.point_in_time_recovery_enabled
165
+ }
166
+
167
+ server_side_encryption {
168
+ enabled = true
169
+ kms_key_arn = aws_kms_key.table.arn
170
+ }
171
+ }
172
+
173
+ output "table_name" {
174
+ description = "Name of the DynamoDB table."
175
+ value = aws_dynamodb_table.table.name
176
+ }
177
+
178
+ output "table_arn" {
179
+ description = "ARN of the DynamoDB table."
180
+ value = aws_dynamodb_table.table.arn
181
+ }
182
+
183
+ output "kms_key_arn" {
184
+ description = "ARN of the KMS key used to encrypt the DynamoDB table."
185
+ value = aws_kms_key.table.arn
186
+ }
187
+ "
188
+ `;
189
+
190
+ exports[`ts#dynamodb generator > should generate terraform modules when iac is terraform 2`] = `
191
+ "terraform {
192
+ required_providers {
193
+ aws = {
194
+ source = "hashicorp/aws"
195
+ version = "~> 6.0"
196
+ }
197
+ }
198
+ }
199
+
200
+ variable "billing_mode" {
201
+ description = "Controls how you are charged for read and write throughput."
202
+ type = string
203
+ default = "PAY_PER_REQUEST"
204
+ }
205
+
206
+ variable "point_in_time_recovery_enabled" {
207
+ description = "Whether to enable point-in-time recovery for the table."
208
+ type = bool
209
+ default = true
210
+ }
211
+
212
+ variable "deletion_protection_enabled" {
213
+ description = "Whether to enable deletion protection on the table."
214
+ type = bool
215
+ default = true
216
+ }
217
+
218
+ variable "enable_key_rotation" {
219
+ description = "Whether to enable automatic key rotation on the KMS key used to encrypt the table."
220
+ type = bool
221
+ default = true
222
+ }
223
+
224
+ locals {
225
+ dynamodb_config = jsondecode(file("\${path.module}/../../../../../../../packages/my-table/config.json"))
226
+ global_secondary_indexes = [for gsi in local.dynamodb_config.tableConfig.globalSecondaryIndexes : {
227
+ name = gsi.indexName
228
+ hash_key = gsi.partitionKey
229
+ range_key = try(gsi.sortKey, null)
230
+ projection_type = "ALL"
231
+ }]
232
+ }
233
+
234
+ module "dynamodb_table" {
235
+ source = "../../../core/dynamodb"
236
+ name = "proj-my-table"
237
+ billing_mode = var.billing_mode
238
+ point_in_time_recovery_enabled = var.point_in_time_recovery_enabled
239
+ deletion_protection_enabled = var.deletion_protection_enabled
240
+ enable_key_rotation = var.enable_key_rotation
241
+ global_secondary_indexes = local.global_secondary_indexes
242
+ }
243
+
244
+ module "add_to_runtime_config" {
245
+ source = "../../../core/runtime-config/entry"
246
+
247
+ namespace = "dynamodb"
248
+ key = local.dynamodb_config.runtimeConfigKey
249
+ value = {
250
+ tableName = module.dynamodb_table.table_name
251
+ }
252
+ }
253
+ "
254
+ `;
255
+
256
+ exports[`ts#dynamodb generator > should generate the dynamodb project > packages/common/scripts/src/dynamodb/create-local-table.ts 1`] = `
257
+ "import {
258
+ BillingMode,
259
+ CreateTableCommand,
260
+ DescribeTableCommand,
261
+ DynamoDBClient,
262
+ GlobalSecondaryIndexDescription,
263
+ IndexStatus,
264
+ KeyType,
265
+ ProjectionType,
266
+ ResourceInUseException,
267
+ ScalarAttributeType,
268
+ TableStatus,
269
+ UpdateTableCommand,
270
+ } from '@aws-sdk/client-dynamodb';
271
+ import { readFileSync } from 'fs';
272
+
273
+ const {
274
+ serveLocal: { port, tableName },
275
+ tableConfig: { globalSecondaryIndexes },
276
+ } = JSON.parse(readFileSync('config.json', 'utf-8')) as {
277
+ serveLocal: { port: number; tableName: string };
278
+ tableConfig: {
279
+ globalSecondaryIndexes: {
280
+ indexName: string;
281
+ partitionKey: string;
282
+ sortKey?: string;
283
+ }[];
284
+ };
285
+ };
286
+
287
+ const timeoutSignal = () => AbortSignal.timeout(10000);
288
+
289
+ const client = new DynamoDBClient({
290
+ endpoint: \`http://localhost:\${port}\`,
291
+ region: 'us-east-1',
292
+ credentials: { accessKeyId: 'UNUSED', secretAccessKey: 'UNUSED' },
293
+ });
294
+
295
+ const waitForTableActive = async (
296
+ waitClient: DynamoDBClient,
297
+ waitTableName: string,
298
+ ): Promise<void> => {
299
+ for (;;) {
300
+ const { Table } = await waitClient.send(
301
+ new DescribeTableCommand({ TableName: waitTableName }),
302
+ { abortSignal: timeoutSignal() },
303
+ );
304
+ const allActive =
305
+ Table?.TableStatus === TableStatus.ACTIVE &&
306
+ (Table?.GlobalSecondaryIndexes ?? []).every(
307
+ (g: GlobalSecondaryIndexDescription) =>
308
+ g.IndexStatus === IndexStatus.ACTIVE,
309
+ );
310
+ if (allActive) return;
311
+ await new Promise((resolve) => setTimeout(resolve, 500));
312
+ }
313
+ };
314
+
315
+ const ensureTable = async (
316
+ tblClient: DynamoDBClient,
317
+ tblName: string,
318
+ gsIs: { indexName: string; partitionKey: string; sortKey?: string }[],
319
+ ): Promise<void> => {
320
+ const gsiAttributeDefinitions = gsIs.flatMap((gsi) => [
321
+ { AttributeName: gsi.partitionKey, AttributeType: ScalarAttributeType.S },
322
+ ...(gsi.sortKey
323
+ ? [{ AttributeName: gsi.sortKey, AttributeType: ScalarAttributeType.S }]
324
+ : []),
325
+ ]);
326
+ const attributeDefinitions = [
327
+ { AttributeName: 'pk', AttributeType: ScalarAttributeType.S },
328
+ { AttributeName: 'sk', AttributeType: ScalarAttributeType.S },
329
+ ...gsiAttributeDefinitions.filter(
330
+ (a, i, arr) =>
331
+ arr.findIndex((b) => b.AttributeName === a.AttributeName) === i,
332
+ ),
333
+ ];
334
+ const globalSecondaryIndexes = gsIs.map((gsi) => ({
335
+ IndexName: gsi.indexName,
336
+ KeySchema: [
337
+ { AttributeName: gsi.partitionKey, KeyType: KeyType.HASH },
338
+ ...(gsi.sortKey
339
+ ? [{ AttributeName: gsi.sortKey, KeyType: KeyType.RANGE }]
340
+ : []),
341
+ ],
342
+ Projection: { ProjectionType: ProjectionType.ALL },
343
+ }));
344
+
345
+ for (let attempt = 0; attempt < 30; attempt++) {
346
+ try {
347
+ // New table: create with all GSIs in one shot.
348
+ await tblClient.send(
349
+ new CreateTableCommand({
350
+ TableName: tblName,
351
+ AttributeDefinitions: attributeDefinitions,
352
+ KeySchema: [
353
+ { AttributeName: 'pk', KeyType: KeyType.HASH },
354
+ { AttributeName: 'sk', KeyType: KeyType.RANGE },
355
+ ],
356
+ BillingMode: BillingMode.PAY_PER_REQUEST,
357
+ ...(globalSecondaryIndexes.length > 0 && {
358
+ GlobalSecondaryIndexes: globalSecondaryIndexes,
359
+ }),
360
+ }),
361
+ { abortSignal: timeoutSignal() },
362
+ );
363
+ console.log(\`Created table: \${tblName}\`);
364
+ for (const gsi of globalSecondaryIndexes) {
365
+ console.log(\`Created GSI: \${gsi.IndexName}\`);
366
+ }
367
+ return;
368
+ } catch (e) {
369
+ // Table already exists: sync GSIs to match desired state.
370
+ if (e instanceof ResourceInUseException) {
371
+ const { Table } = await tblClient.send(
372
+ new DescribeTableCommand({ TableName: tblName }),
373
+ { abortSignal: timeoutSignal() },
374
+ );
375
+ const existingGSIs = Table?.GlobalSecondaryIndexes ?? [];
376
+ const existingNames = new Set(
377
+ existingGSIs.map(
378
+ (g: GlobalSecondaryIndexDescription) => g.IndexName ?? '',
379
+ ),
380
+ );
381
+ const desiredNames = new Set(gsIs.map((g) => g.indexName));
382
+
383
+ // DynamoDB Local only allows one GSI to be created or deleted at a time.
384
+ for (const existing of existingGSIs) {
385
+ if (!existing.IndexName || desiredNames.has(existing.IndexName))
386
+ continue;
387
+ await tblClient.send(
388
+ new UpdateTableCommand({
389
+ TableName: tblName,
390
+ GlobalSecondaryIndexUpdates: [
391
+ { Delete: { IndexName: existing.IndexName } },
392
+ ],
393
+ }),
394
+ { abortSignal: timeoutSignal() },
395
+ );
396
+ console.log(\`Deleted GSI: \${existing.IndexName}\`);
397
+ await waitForTableActive(tblClient, tblName);
398
+ }
399
+
400
+ for (const gsi of gsIs) {
401
+ if (existingNames.has(gsi.indexName)) continue;
402
+ await tblClient.send(
403
+ new UpdateTableCommand({
404
+ TableName: tblName,
405
+ AttributeDefinitions: [
406
+ {
407
+ AttributeName: gsi.partitionKey,
408
+ AttributeType: ScalarAttributeType.S,
409
+ },
410
+ ...(gsi.sortKey
411
+ ? [
412
+ {
413
+ AttributeName: gsi.sortKey,
414
+ AttributeType: ScalarAttributeType.S,
415
+ },
416
+ ]
417
+ : []),
418
+ ],
419
+ GlobalSecondaryIndexUpdates: [
420
+ {
421
+ Create: {
422
+ IndexName: gsi.indexName,
423
+ KeySchema: [
424
+ {
425
+ AttributeName: gsi.partitionKey,
426
+ KeyType: KeyType.HASH,
427
+ },
428
+ ...(gsi.sortKey
429
+ ? [
430
+ {
431
+ AttributeName: gsi.sortKey,
432
+ KeyType: KeyType.RANGE,
433
+ },
434
+ ]
435
+ : []),
436
+ ],
437
+ Projection: { ProjectionType: ProjectionType.ALL },
438
+ },
439
+ },
440
+ ],
441
+ }),
442
+ { abortSignal: timeoutSignal() },
443
+ );
444
+ console.log(\`Created GSI: \${gsi.indexName}\`);
445
+ await waitForTableActive(tblClient, tblName);
446
+ }
447
+ return;
448
+ }
449
+ if (attempt === 29) throw e;
450
+ await new Promise((resolve) => setTimeout(resolve, 1000));
451
+ }
452
+ }
453
+ };
454
+
455
+ await ensureTable(client, tableName, globalSecondaryIndexes);
456
+ "
457
+ `;
458
+
459
+ exports[`ts#dynamodb generator > should generate the dynamodb project > packages/common/scripts/src/dynamodb/pull-image.ts 1`] = `
460
+ "import { spawnSync } from 'child_process';
461
+ import { readFileSync } from 'fs';
462
+
463
+ const { containerEngine, image } = JSON.parse(
464
+ readFileSync('config.json', 'utf-8'),
465
+ ).serveLocal;
466
+
467
+ const inspect = spawnSync(containerEngine, ['image', 'inspect', image], {
468
+ stdio: 'ignore',
469
+ });
470
+ if (inspect.status !== 0) {
471
+ const pull = spawnSync(containerEngine, ['pull', image], {
472
+ stdio: 'inherit',
473
+ });
474
+ if (pull.status !== 0) {
475
+ process.exit(pull.status ?? 1);
476
+ }
477
+ }
478
+ "
479
+ `;
480
+
481
+ exports[`ts#dynamodb generator > should generate the dynamodb project > packages/common/scripts/src/dynamodb/start-container.ts 1`] = `
482
+ "import { spawn, spawnSync } from 'child_process';
483
+ import { readFileSync } from 'fs';
484
+
485
+ const { containerEngine, containerName, image, port } = JSON.parse(
486
+ readFileSync('config.json', 'utf-8'),
487
+ ).serveLocal;
488
+
489
+ const containerExists = (): boolean =>
490
+ spawnSync(containerEngine, ['container', 'inspect', containerName], {
491
+ stdio: 'ignore',
492
+ }).status === 0;
493
+
494
+ const isRunning = (): boolean => {
495
+ const result = spawnSync(
496
+ containerEngine,
497
+ ['container', 'inspect', '-f', '{{.State.Running}}', containerName],
498
+ { encoding: 'utf-8' },
499
+ );
500
+ return result.status === 0 && result.stdout.trim() === 'true';
501
+ };
502
+
503
+ // Multiple dynamo table packages run serve-local in parallel sharing the same
504
+ // container. All processes stream logs, but only the one that created the
505
+ // container stops it on exit — others just detach.
506
+ let created = false;
507
+ let runRetries = 0;
508
+
509
+ for (;;) {
510
+ if (containerExists()) {
511
+ if (!isRunning()) {
512
+ // Another process may have started it between our inspect and start — container engine start
513
+ // exits 0 even if the container is already running, so no special-casing needed.
514
+ const start = spawnSync(containerEngine, ['start', containerName], {
515
+ stdio: 'inherit',
516
+ });
517
+ if (start.status !== 0) process.exit(start.status ?? 1);
518
+ }
519
+ break;
520
+ }
521
+ const runArgs = [
522
+ 'run',
523
+ ...(containerEngine === 'docker' ? ['--rm'] : []),
524
+ '--name',
525
+ containerName,
526
+ '-u',
527
+ 'root',
528
+ '-w',
529
+ '/home/dynamodblocal',
530
+ \`-p\`,
531
+ \`\${port}:\${port}\`,
532
+ '-v',
533
+ \`\${containerName}-data:/home/dynamodblocal/data\`,
534
+ '-d',
535
+ image,
536
+ '-jar',
537
+ 'DynamoDBLocal.jar',
538
+ '-sharedDb',
539
+ '-dbPath',
540
+ './data',
541
+ '-port',
542
+ \`\${port}\`,
543
+ '-optimizeDbBeforeStartup',
544
+ ];
545
+ const create = spawnSync(containerEngine, runArgs, { stdio: 'pipe' });
546
+ if (create.status === 0) {
547
+ created = true;
548
+ break;
549
+ }
550
+ if (!containerExists() && ++runRetries > 3) {
551
+ process.stderr.write(create.stderr);
552
+ process.exit(create.status ?? 1);
553
+ }
554
+ }
555
+
556
+ const logs = spawn(containerEngine, ['logs', '-f', containerName], {
557
+ stdio: ['ignore', 'inherit', 'inherit'],
558
+ });
559
+
560
+ let exiting = false;
561
+
562
+ const cleanup = () => {
563
+ if (exiting) return;
564
+ exiting = true;
565
+ if (created) {
566
+ if (containerEngine === 'docker') {
567
+ spawnSync(containerEngine, ['stop', containerName], { stdio: 'ignore' });
568
+ } else {
569
+ spawnSync(containerEngine, ['rm', '-f', containerName], {
570
+ stdio: 'ignore',
571
+ });
572
+ }
573
+ }
574
+ logs.kill();
575
+ process.exit(0);
576
+ };
577
+
578
+ process.on('SIGTERM', cleanup);
579
+ process.on('SIGINT', cleanup);
580
+ process.on('SIGHUP', cleanup);
581
+
582
+ logs.on('exit', (code) => {
583
+ if (!exiting) process.exit(code ?? 0);
584
+ });
585
+ "
586
+ `;
587
+
588
+ exports[`ts#dynamodb generator > should generate the dynamodb project > packages/my-table/src/client.ts 1`] = `
589
+ "import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
590
+ import { getAppConfig } from '@aws-lambda-powertools/parameters/appconfig';
591
+ import { readFileSync } from 'fs';
592
+ import { join, dirname } from 'path';
593
+ import { fileURLToPath } from 'url';
594
+
595
+ // Generated: must match runtimeConfigKey in config.json
596
+ const runtimeConfigKey = 'MyTable';
597
+
598
+ const __dirname = dirname(fileURLToPath(import.meta.url));
599
+ // config.json is only present in local dev (not included in the deployed bundle); guard with SERVE_LOCAL check
600
+ const serveLocal = () =>
601
+ JSON.parse(readFileSync(join(__dirname, '../config.json'), 'utf-8'))
602
+ .serveLocal;
603
+
604
+ let _client: DynamoDBClient | undefined;
605
+
606
+ export const getDynamoDBClient = (): DynamoDBClient => {
607
+ if (!_client) {
608
+ if (process.env.SERVE_LOCAL === 'true') {
609
+ const { port } = serveLocal();
610
+ _client = new DynamoDBClient({
611
+ endpoint: \`http://localhost:\${port}\`,
612
+ region: 'us-east-1',
613
+ credentials: { accessKeyId: 'UNUSED', secretAccessKey: 'UNUSED' },
614
+ });
615
+ } else {
616
+ _client = new DynamoDBClient({});
617
+ }
618
+ }
619
+ return _client;
620
+ };
621
+
622
+ type DynamoDBConfig = {
623
+ tableName: string;
624
+ };
625
+
626
+ let _tableName: string | undefined;
627
+
628
+ export const resolveTableName = async (): Promise<string> => {
629
+ if (process.env.SERVE_LOCAL === 'true') {
630
+ const { tableName } = serveLocal();
631
+ return tableName;
632
+ }
633
+ if (_tableName === undefined) {
634
+ const appId = process.env.RUNTIME_CONFIG_APP_ID;
635
+ if (!appId) {
636
+ throw new Error('RUNTIME_CONFIG_APP_ID environment variable is not set');
637
+ }
638
+ const config = await getAppConfig<{
639
+ [key: string]: DynamoDBConfig | undefined;
640
+ }>('dynamodb', {
641
+ application: appId,
642
+ environment: 'default',
643
+ transform: 'json',
644
+ });
645
+ const tableName = config?.[runtimeConfigKey]?.tableName;
646
+ if (!tableName) {
647
+ throw new Error('Could not resolve table name from runtime config');
648
+ }
649
+ _tableName = tableName;
650
+ }
651
+ return _tableName!;
652
+ };
653
+ "
654
+ `;
655
+
656
+ exports[`ts#dynamodb generator > should generate the dynamodb project > packages/my-table/src/entities/example.ts 1`] = `
657
+ "import { Entity } from 'electrodb';
658
+ import { getDynamoDBClient, resolveTableName } from '../client.js';
659
+
660
+ // Example entity - replace with your own entities using ElectroDB
661
+ // See https://electrodb.dev/en/modeling/entities/ for documentation
662
+ export const createExampleEntity = async () =>
663
+ new Entity(
664
+ {
665
+ model: {
666
+ entity: 'example',
667
+ version: '1',
668
+ service: 'MyTable',
669
+ },
670
+ attributes: {
671
+ id: {
672
+ type: 'string',
673
+ required: true,
674
+ },
675
+ createdAt: {
676
+ type: 'string',
677
+ required: true,
678
+ default: () => new Date().toISOString(),
679
+ readOnly: true,
680
+ },
681
+ updatedAt: {
682
+ type: 'string',
683
+ required: true,
684
+ default: () => new Date().toISOString(),
685
+ watch: '*',
686
+ set: () => new Date().toISOString(),
687
+ },
688
+ },
689
+ indexes: {
690
+ primary: {
691
+ pk: {
692
+ field: 'pk',
693
+ composite: ['id'],
694
+ },
695
+ sk: {
696
+ field: 'sk',
697
+ composite: [],
698
+ },
699
+ },
700
+ },
701
+ },
702
+ { client: getDynamoDBClient(), table: await resolveTableName() },
703
+ );
704
+ "
705
+ `;
706
+
707
+ exports[`ts#dynamodb generator > should generate the dynamodb project > packages/my-table/src/entities/index.ts 1`] = `
708
+ "export { createExampleEntity } from './example.js';
709
+ "
710
+ `;
711
+
712
+ exports[`ts#dynamodb generator > should generate the dynamodb project > packages/my-table/src/index.ts 1`] = `
713
+ "export { getDynamoDBClient, resolveTableName } from './client.js';
714
+ export * from './entities/index.js';
715
+ "
716
+ `;
717
+
718
+ exports[`ts#dynamodb generator > should generate the dynamodb project 1`] = `
719
+ "import { Construct } from 'constructs';
720
+ import {
721
+ AttributeType,
722
+ BillingMode,
723
+ Table,
724
+ TableEncryption,
725
+ TableProps,
726
+ } from 'aws-cdk-lib/aws-dynamodb';
727
+ import { RemovalPolicy } from 'aws-cdk-lib';
728
+ import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam';
729
+ import { Key } from 'aws-cdk-lib/aws-kms';
730
+ import { RuntimeConfig } from './runtime-config.js';
731
+
732
+ type _DynamoDBTableProps = Omit<
733
+ TableProps,
734
+ 'tableName' | 'partitionKey' | 'sortKey' | 'encryption' | 'encryptionKey'
735
+ >;
736
+
737
+ export interface DynamoDBTableProps extends _DynamoDBTableProps {
738
+ /**
739
+ * The DynamoDB table name. If omitted, CDK auto-generates a unique name
740
+ * from the stack name and construct path.
741
+ */
742
+ readonly tableName?: string;
743
+
744
+ /**
745
+ * RuntimeConfig key used under the \`dynamodb\` namespace.
746
+ */
747
+ readonly runtimeConfigKey: string;
748
+
749
+ /**
750
+ * Whether to enable automatic key rotation on the KMS key used to encrypt the table.
751
+ *
752
+ * @default true
753
+ */
754
+ readonly enableKeyRotation?: boolean;
755
+ }
756
+
757
+ export abstract class DynamoDBTable extends Construct {
758
+ public readonly table: Table;
759
+
760
+ constructor(
761
+ scope: Construct,
762
+ id: string,
763
+ {
764
+ tableName,
765
+ runtimeConfigKey,
766
+ billingMode = BillingMode.PAY_PER_REQUEST,
767
+ pointInTimeRecoverySpecification = { pointInTimeRecoveryEnabled: true },
768
+ deletionProtection = true,
769
+ removalPolicy = RemovalPolicy.RETAIN,
770
+ enableKeyRotation = true,
771
+ ...rest
772
+ }: DynamoDBTableProps,
773
+ ) {
774
+ super(scope, id);
775
+
776
+ const key = new Key(this, 'EncryptionKey', { enableKeyRotation });
777
+
778
+ this.table = new Table(this, runtimeConfigKey, {
779
+ ...rest,
780
+ ...(tableName !== undefined && { tableName }),
781
+ partitionKey: { name: 'pk', type: AttributeType.STRING },
782
+ sortKey: { name: 'sk', type: AttributeType.STRING },
783
+ billingMode,
784
+ pointInTimeRecoverySpecification,
785
+ deletionProtection,
786
+ encryptionKey: key,
787
+ encryption: TableEncryption.CUSTOMER_MANAGED,
788
+ removalPolicy,
789
+ });
790
+
791
+ const rc = RuntimeConfig.ensure(this);
792
+ rc.set('dynamodb', runtimeConfigKey, { tableName: this.table.tableName });
793
+ }
794
+
795
+ public grantReadData(grantee: IGrantable): Grant {
796
+ return this.table.grantReadData(grantee);
797
+ }
798
+
799
+ public grantWriteData(grantee: IGrantable): Grant {
800
+ return this.table.grantWriteData(grantee);
801
+ }
802
+
803
+ public grantReadWriteData(grantee: IGrantable): Grant {
804
+ return this.table.grantReadWriteData(grantee);
805
+ }
806
+
807
+ public grantFullAccess(grantee: IGrantable): Grant {
808
+ return this.table.grantFullAccess(grantee);
809
+ }
810
+
811
+ public grantStreamRead(grantee: IGrantable): Grant {
812
+ return this.table.grantStreamRead(grantee);
813
+ }
814
+
815
+ public grantTableListStreams(grantee: IGrantable): Grant {
816
+ return this.table.grantTableListStreams(grantee);
817
+ }
818
+
819
+ public grant(grantee: IGrantable, ...actions: string[]): Grant {
820
+ return this.table.grant(grantee, ...actions);
821
+ }
822
+
823
+ public grantStream(grantee: IGrantable, ...actions: string[]): Grant {
824
+ return this.table.grantStream(grantee, ...actions);
825
+ }
826
+ }
827
+ "
828
+ `;
829
+
830
+ exports[`ts#dynamodb generator > should generate the dynamodb project 2`] = `
831
+ "import { Construct } from 'constructs';
832
+ import { AttributeType, ProjectionType } from 'aws-cdk-lib/aws-dynamodb';
833
+ import { DynamoDBTable, DynamoDBTableProps } from '../../core/dynamodb.js';
834
+ import { findWorkspaceRoot } from '../../core/workspace.js';
835
+ import { readFileSync } from 'fs';
836
+ import { join } from 'path';
837
+ import { fileURLToPath } from 'url';
838
+
839
+ const { runtimeConfigKey, tableConfig } = JSON.parse(
840
+ readFileSync(
841
+ join(
842
+ findWorkspaceRoot(fileURLToPath(new URL(import.meta.url))),
843
+ 'packages/my-table/config.json',
844
+ ),
845
+ 'utf-8',
846
+ ),
847
+ ) as {
848
+ runtimeConfigKey: string;
849
+ tableConfig: {
850
+ globalSecondaryIndexes: {
851
+ indexName: string;
852
+ partitionKey: string;
853
+ sortKey?: string;
854
+ }[];
855
+ };
856
+ };
857
+
858
+ export type MyTableProps = Omit<DynamoDBTableProps, 'runtimeConfigKey'>;
859
+
860
+ export class MyTable extends DynamoDBTable {
861
+ constructor(scope: Construct, id: string, props?: MyTableProps) {
862
+ super(scope, id, {
863
+ ...props,
864
+ runtimeConfigKey,
865
+ });
866
+
867
+ for (const gsi of tableConfig.globalSecondaryIndexes) {
868
+ this.table.addGlobalSecondaryIndex({
869
+ indexName: gsi.indexName,
870
+ partitionKey: { name: gsi.partitionKey, type: AttributeType.STRING },
871
+ ...(gsi.sortKey && {
872
+ sortKey: { name: gsi.sortKey, type: AttributeType.STRING },
873
+ }),
874
+ projectionType: ProjectionType.ALL,
875
+ });
876
+ }
877
+ }
878
+ }
879
+ "
880
+ `;
881
+
882
+ exports[`ts#dynamodb generator > should generate the dynamodb project 3`] = `
883
+ "export * from './my-table.js';
884
+ "
885
+ `;
886
+
887
+ exports[`ts#dynamodb generator > should generate the dynamodb project 4`] = `
888
+ "export * from './dynamodb/index.js';
889
+ "
890
+ `;
891
+
892
+ exports[`ts#dynamodb generator > should generate with infra=none then upgrade to infra=dynamodb > packages/common/scripts/src/dynamodb/create-local-table.ts 1`] = `
893
+ "import {
894
+ BillingMode,
895
+ CreateTableCommand,
896
+ DescribeTableCommand,
897
+ DynamoDBClient,
898
+ GlobalSecondaryIndexDescription,
899
+ IndexStatus,
900
+ KeyType,
901
+ ProjectionType,
902
+ ResourceInUseException,
903
+ ScalarAttributeType,
904
+ TableStatus,
905
+ UpdateTableCommand,
906
+ } from '@aws-sdk/client-dynamodb';
907
+ import { readFileSync } from 'fs';
908
+
909
+ const {
910
+ serveLocal: { port, tableName },
911
+ tableConfig: { globalSecondaryIndexes },
912
+ } = JSON.parse(readFileSync('config.json', 'utf-8')) as {
913
+ serveLocal: { port: number; tableName: string };
914
+ tableConfig: {
915
+ globalSecondaryIndexes: {
916
+ indexName: string;
917
+ partitionKey: string;
918
+ sortKey?: string;
919
+ }[];
920
+ };
921
+ };
922
+
923
+ const timeoutSignal = () => AbortSignal.timeout(10000);
924
+
925
+ const client = new DynamoDBClient({
926
+ endpoint: \`http://localhost:\${port}\`,
927
+ region: 'us-east-1',
928
+ credentials: { accessKeyId: 'UNUSED', secretAccessKey: 'UNUSED' },
929
+ });
930
+
931
+ const waitForTableActive = async (
932
+ waitClient: DynamoDBClient,
933
+ waitTableName: string,
934
+ ): Promise<void> => {
935
+ for (;;) {
936
+ const { Table } = await waitClient.send(
937
+ new DescribeTableCommand({ TableName: waitTableName }),
938
+ { abortSignal: timeoutSignal() },
939
+ );
940
+ const allActive =
941
+ Table?.TableStatus === TableStatus.ACTIVE &&
942
+ (Table?.GlobalSecondaryIndexes ?? []).every(
943
+ (g: GlobalSecondaryIndexDescription) =>
944
+ g.IndexStatus === IndexStatus.ACTIVE,
945
+ );
946
+ if (allActive) return;
947
+ await new Promise((resolve) => setTimeout(resolve, 500));
948
+ }
949
+ };
950
+
951
+ const ensureTable = async (
952
+ tblClient: DynamoDBClient,
953
+ tblName: string,
954
+ gsIs: { indexName: string; partitionKey: string; sortKey?: string }[],
955
+ ): Promise<void> => {
956
+ const gsiAttributeDefinitions = gsIs.flatMap((gsi) => [
957
+ { AttributeName: gsi.partitionKey, AttributeType: ScalarAttributeType.S },
958
+ ...(gsi.sortKey
959
+ ? [{ AttributeName: gsi.sortKey, AttributeType: ScalarAttributeType.S }]
960
+ : []),
961
+ ]);
962
+ const attributeDefinitions = [
963
+ { AttributeName: 'pk', AttributeType: ScalarAttributeType.S },
964
+ { AttributeName: 'sk', AttributeType: ScalarAttributeType.S },
965
+ ...gsiAttributeDefinitions.filter(
966
+ (a, i, arr) =>
967
+ arr.findIndex((b) => b.AttributeName === a.AttributeName) === i,
968
+ ),
969
+ ];
970
+ const globalSecondaryIndexes = gsIs.map((gsi) => ({
971
+ IndexName: gsi.indexName,
972
+ KeySchema: [
973
+ { AttributeName: gsi.partitionKey, KeyType: KeyType.HASH },
974
+ ...(gsi.sortKey
975
+ ? [{ AttributeName: gsi.sortKey, KeyType: KeyType.RANGE }]
976
+ : []),
977
+ ],
978
+ Projection: { ProjectionType: ProjectionType.ALL },
979
+ }));
980
+
981
+ for (let attempt = 0; attempt < 30; attempt++) {
982
+ try {
983
+ // New table: create with all GSIs in one shot.
984
+ await tblClient.send(
985
+ new CreateTableCommand({
986
+ TableName: tblName,
987
+ AttributeDefinitions: attributeDefinitions,
988
+ KeySchema: [
989
+ { AttributeName: 'pk', KeyType: KeyType.HASH },
990
+ { AttributeName: 'sk', KeyType: KeyType.RANGE },
991
+ ],
992
+ BillingMode: BillingMode.PAY_PER_REQUEST,
993
+ ...(globalSecondaryIndexes.length > 0 && {
994
+ GlobalSecondaryIndexes: globalSecondaryIndexes,
995
+ }),
996
+ }),
997
+ { abortSignal: timeoutSignal() },
998
+ );
999
+ console.log(\`Created table: \${tblName}\`);
1000
+ for (const gsi of globalSecondaryIndexes) {
1001
+ console.log(\`Created GSI: \${gsi.IndexName}\`);
1002
+ }
1003
+ return;
1004
+ } catch (e) {
1005
+ // Table already exists: sync GSIs to match desired state.
1006
+ if (e instanceof ResourceInUseException) {
1007
+ const { Table } = await tblClient.send(
1008
+ new DescribeTableCommand({ TableName: tblName }),
1009
+ { abortSignal: timeoutSignal() },
1010
+ );
1011
+ const existingGSIs = Table?.GlobalSecondaryIndexes ?? [];
1012
+ const existingNames = new Set(
1013
+ existingGSIs.map(
1014
+ (g: GlobalSecondaryIndexDescription) => g.IndexName ?? '',
1015
+ ),
1016
+ );
1017
+ const desiredNames = new Set(gsIs.map((g) => g.indexName));
1018
+
1019
+ // DynamoDB Local only allows one GSI to be created or deleted at a time.
1020
+ for (const existing of existingGSIs) {
1021
+ if (!existing.IndexName || desiredNames.has(existing.IndexName))
1022
+ continue;
1023
+ await tblClient.send(
1024
+ new UpdateTableCommand({
1025
+ TableName: tblName,
1026
+ GlobalSecondaryIndexUpdates: [
1027
+ { Delete: { IndexName: existing.IndexName } },
1028
+ ],
1029
+ }),
1030
+ { abortSignal: timeoutSignal() },
1031
+ );
1032
+ console.log(\`Deleted GSI: \${existing.IndexName}\`);
1033
+ await waitForTableActive(tblClient, tblName);
1034
+ }
1035
+
1036
+ for (const gsi of gsIs) {
1037
+ if (existingNames.has(gsi.indexName)) continue;
1038
+ await tblClient.send(
1039
+ new UpdateTableCommand({
1040
+ TableName: tblName,
1041
+ AttributeDefinitions: [
1042
+ {
1043
+ AttributeName: gsi.partitionKey,
1044
+ AttributeType: ScalarAttributeType.S,
1045
+ },
1046
+ ...(gsi.sortKey
1047
+ ? [
1048
+ {
1049
+ AttributeName: gsi.sortKey,
1050
+ AttributeType: ScalarAttributeType.S,
1051
+ },
1052
+ ]
1053
+ : []),
1054
+ ],
1055
+ GlobalSecondaryIndexUpdates: [
1056
+ {
1057
+ Create: {
1058
+ IndexName: gsi.indexName,
1059
+ KeySchema: [
1060
+ {
1061
+ AttributeName: gsi.partitionKey,
1062
+ KeyType: KeyType.HASH,
1063
+ },
1064
+ ...(gsi.sortKey
1065
+ ? [
1066
+ {
1067
+ AttributeName: gsi.sortKey,
1068
+ KeyType: KeyType.RANGE,
1069
+ },
1070
+ ]
1071
+ : []),
1072
+ ],
1073
+ Projection: { ProjectionType: ProjectionType.ALL },
1074
+ },
1075
+ },
1076
+ ],
1077
+ }),
1078
+ { abortSignal: timeoutSignal() },
1079
+ );
1080
+ console.log(\`Created GSI: \${gsi.indexName}\`);
1081
+ await waitForTableActive(tblClient, tblName);
1082
+ }
1083
+ return;
1084
+ }
1085
+ if (attempt === 29) throw e;
1086
+ await new Promise((resolve) => setTimeout(resolve, 1000));
1087
+ }
1088
+ }
1089
+ };
1090
+
1091
+ await ensureTable(client, tableName, globalSecondaryIndexes);
1092
+ "
1093
+ `;
1094
+
1095
+ exports[`ts#dynamodb generator > should generate with infra=none then upgrade to infra=dynamodb > packages/common/scripts/src/dynamodb/pull-image.ts 1`] = `
1096
+ "import { spawnSync } from 'child_process';
1097
+ import { readFileSync } from 'fs';
1098
+
1099
+ const { containerEngine, image } = JSON.parse(
1100
+ readFileSync('config.json', 'utf-8'),
1101
+ ).serveLocal;
1102
+
1103
+ const inspect = spawnSync(containerEngine, ['image', 'inspect', image], {
1104
+ stdio: 'ignore',
1105
+ });
1106
+ if (inspect.status !== 0) {
1107
+ const pull = spawnSync(containerEngine, ['pull', image], {
1108
+ stdio: 'inherit',
1109
+ });
1110
+ if (pull.status !== 0) {
1111
+ process.exit(pull.status ?? 1);
1112
+ }
1113
+ }
1114
+ "
1115
+ `;
1116
+
1117
+ exports[`ts#dynamodb generator > should generate with infra=none then upgrade to infra=dynamodb > packages/common/scripts/src/dynamodb/start-container.ts 1`] = `
1118
+ "import { spawn, spawnSync } from 'child_process';
1119
+ import { readFileSync } from 'fs';
1120
+
1121
+ const { containerEngine, containerName, image, port } = JSON.parse(
1122
+ readFileSync('config.json', 'utf-8'),
1123
+ ).serveLocal;
1124
+
1125
+ const containerExists = (): boolean =>
1126
+ spawnSync(containerEngine, ['container', 'inspect', containerName], {
1127
+ stdio: 'ignore',
1128
+ }).status === 0;
1129
+
1130
+ const isRunning = (): boolean => {
1131
+ const result = spawnSync(
1132
+ containerEngine,
1133
+ ['container', 'inspect', '-f', '{{.State.Running}}', containerName],
1134
+ { encoding: 'utf-8' },
1135
+ );
1136
+ return result.status === 0 && result.stdout.trim() === 'true';
1137
+ };
1138
+
1139
+ // Multiple dynamo table packages run serve-local in parallel sharing the same
1140
+ // container. All processes stream logs, but only the one that created the
1141
+ // container stops it on exit — others just detach.
1142
+ let created = false;
1143
+ let runRetries = 0;
1144
+
1145
+ for (;;) {
1146
+ if (containerExists()) {
1147
+ if (!isRunning()) {
1148
+ // Another process may have started it between our inspect and start — container engine start
1149
+ // exits 0 even if the container is already running, so no special-casing needed.
1150
+ const start = spawnSync(containerEngine, ['start', containerName], {
1151
+ stdio: 'inherit',
1152
+ });
1153
+ if (start.status !== 0) process.exit(start.status ?? 1);
1154
+ }
1155
+ break;
1156
+ }
1157
+ const runArgs = [
1158
+ 'run',
1159
+ ...(containerEngine === 'docker' ? ['--rm'] : []),
1160
+ '--name',
1161
+ containerName,
1162
+ '-u',
1163
+ 'root',
1164
+ '-w',
1165
+ '/home/dynamodblocal',
1166
+ \`-p\`,
1167
+ \`\${port}:\${port}\`,
1168
+ '-v',
1169
+ \`\${containerName}-data:/home/dynamodblocal/data\`,
1170
+ '-d',
1171
+ image,
1172
+ '-jar',
1173
+ 'DynamoDBLocal.jar',
1174
+ '-sharedDb',
1175
+ '-dbPath',
1176
+ './data',
1177
+ '-port',
1178
+ \`\${port}\`,
1179
+ '-optimizeDbBeforeStartup',
1180
+ ];
1181
+ const create = spawnSync(containerEngine, runArgs, { stdio: 'pipe' });
1182
+ if (create.status === 0) {
1183
+ created = true;
1184
+ break;
1185
+ }
1186
+ if (!containerExists() && ++runRetries > 3) {
1187
+ process.stderr.write(create.stderr);
1188
+ process.exit(create.status ?? 1);
1189
+ }
1190
+ }
1191
+
1192
+ const logs = spawn(containerEngine, ['logs', '-f', containerName], {
1193
+ stdio: ['ignore', 'inherit', 'inherit'],
1194
+ });
1195
+
1196
+ let exiting = false;
1197
+
1198
+ const cleanup = () => {
1199
+ if (exiting) return;
1200
+ exiting = true;
1201
+ if (created) {
1202
+ if (containerEngine === 'docker') {
1203
+ spawnSync(containerEngine, ['stop', containerName], { stdio: 'ignore' });
1204
+ } else {
1205
+ spawnSync(containerEngine, ['rm', '-f', containerName], {
1206
+ stdio: 'ignore',
1207
+ });
1208
+ }
1209
+ }
1210
+ logs.kill();
1211
+ process.exit(0);
1212
+ };
1213
+
1214
+ process.on('SIGTERM', cleanup);
1215
+ process.on('SIGINT', cleanup);
1216
+ process.on('SIGHUP', cleanup);
1217
+
1218
+ logs.on('exit', (code) => {
1219
+ if (!exiting) process.exit(code ?? 0);
1220
+ });
1221
+ "
1222
+ `;
1223
+
1224
+ exports[`ts#dynamodb generator > should generate with infra=none then upgrade to infra=dynamodb > packages/my-table/src/client.ts 1`] = `
1225
+ "import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
1226
+ import { getAppConfig } from '@aws-lambda-powertools/parameters/appconfig';
1227
+ import { readFileSync } from 'fs';
1228
+ import { join, dirname } from 'path';
1229
+ import { fileURLToPath } from 'url';
1230
+
1231
+ // Generated: must match runtimeConfigKey in config.json
1232
+ const runtimeConfigKey = 'MyTable';
1233
+
1234
+ const __dirname = dirname(fileURLToPath(import.meta.url));
1235
+ // config.json is only present in local dev (not included in the deployed bundle); guard with SERVE_LOCAL check
1236
+ const serveLocal = () =>
1237
+ JSON.parse(readFileSync(join(__dirname, '../config.json'), 'utf-8'))
1238
+ .serveLocal;
1239
+
1240
+ let _client: DynamoDBClient | undefined;
1241
+
1242
+ export const getDynamoDBClient = (): DynamoDBClient => {
1243
+ if (!_client) {
1244
+ if (process.env.SERVE_LOCAL === 'true') {
1245
+ const { port } = serveLocal();
1246
+ _client = new DynamoDBClient({
1247
+ endpoint: \`http://localhost:\${port}\`,
1248
+ region: 'us-east-1',
1249
+ credentials: { accessKeyId: 'UNUSED', secretAccessKey: 'UNUSED' },
1250
+ });
1251
+ } else {
1252
+ _client = new DynamoDBClient({});
1253
+ }
1254
+ }
1255
+ return _client;
1256
+ };
1257
+
1258
+ type DynamoDBConfig = {
1259
+ tableName: string;
1260
+ };
1261
+
1262
+ let _tableName: string | undefined;
1263
+
1264
+ export const resolveTableName = async (): Promise<string> => {
1265
+ if (process.env.SERVE_LOCAL === 'true') {
1266
+ const { tableName } = serveLocal();
1267
+ return tableName;
1268
+ }
1269
+ if (_tableName === undefined) {
1270
+ const appId = process.env.RUNTIME_CONFIG_APP_ID;
1271
+ if (!appId) {
1272
+ throw new Error('RUNTIME_CONFIG_APP_ID environment variable is not set');
1273
+ }
1274
+ const config = await getAppConfig<{
1275
+ [key: string]: DynamoDBConfig | undefined;
1276
+ }>('dynamodb', {
1277
+ application: appId,
1278
+ environment: 'default',
1279
+ transform: 'json',
1280
+ });
1281
+ const tableName = config?.[runtimeConfigKey]?.tableName;
1282
+ if (!tableName) {
1283
+ throw new Error('Could not resolve table name from runtime config');
1284
+ }
1285
+ _tableName = tableName;
1286
+ }
1287
+ return _tableName!;
1288
+ };
1289
+ "
1290
+ `;
1291
+
1292
+ exports[`ts#dynamodb generator > should generate with infra=none then upgrade to infra=dynamodb > packages/my-table/src/entities/example.ts 1`] = `
1293
+ "import { Entity } from 'electrodb';
1294
+ import { getDynamoDBClient, resolveTableName } from '../client.js';
1295
+
1296
+ // Example entity - replace with your own entities using ElectroDB
1297
+ // See https://electrodb.dev/en/modeling/entities/ for documentation
1298
+ export const createExampleEntity = async () =>
1299
+ new Entity(
1300
+ {
1301
+ model: {
1302
+ entity: 'example',
1303
+ version: '1',
1304
+ service: 'MyTable',
1305
+ },
1306
+ attributes: {
1307
+ id: {
1308
+ type: 'string',
1309
+ required: true,
1310
+ },
1311
+ createdAt: {
1312
+ type: 'string',
1313
+ required: true,
1314
+ default: () => new Date().toISOString(),
1315
+ readOnly: true,
1316
+ },
1317
+ updatedAt: {
1318
+ type: 'string',
1319
+ required: true,
1320
+ default: () => new Date().toISOString(),
1321
+ watch: '*',
1322
+ set: () => new Date().toISOString(),
1323
+ },
1324
+ },
1325
+ indexes: {
1326
+ primary: {
1327
+ pk: {
1328
+ field: 'pk',
1329
+ composite: ['id'],
1330
+ },
1331
+ sk: {
1332
+ field: 'sk',
1333
+ composite: [],
1334
+ },
1335
+ },
1336
+ },
1337
+ },
1338
+ { client: getDynamoDBClient(), table: await resolveTableName() },
1339
+ );
1340
+ "
1341
+ `;
1342
+
1343
+ exports[`ts#dynamodb generator > should generate with infra=none then upgrade to infra=dynamodb > packages/my-table/src/entities/index.ts 1`] = `
1344
+ "export { createExampleEntity } from './example.js';
1345
+ "
1346
+ `;
1347
+
1348
+ exports[`ts#dynamodb generator > should generate with infra=none then upgrade to infra=dynamodb > packages/my-table/src/index.ts 1`] = `
1349
+ "export { getDynamoDBClient, resolveTableName } from './client.js';
1350
+ export * from './entities/index.js';
1351
+ "
1352
+ `;