@aws/nx-plugin 1.0.0-rc.54 → 1.0.0-rc.56

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 (284) hide show
  1. package/migrations.json +50 -0
  2. package/package.json +1 -1
  3. package/src/agentcore-gateway/gateway-connection/generator.js +3 -1
  4. package/src/agentcore-gateway/gateway-connection/generator.js.map +1 -1
  5. package/src/agentcore-gateway/generator.d.ts +49 -1
  6. package/src/agentcore-gateway/generator.js +55 -22
  7. package/src/agentcore-gateway/generator.js.map +1 -1
  8. package/src/agentcore-gateway/mcp-connection/generator.js +3 -1
  9. package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -1
  10. package/src/infra/app/__snapshots__/generator.spec.ts.snap +2 -0
  11. package/src/infra/app/generator.d.ts +43 -0
  12. package/src/infra/app/generator.js +47 -18
  13. package/src/infra/app/generator.js.map +1 -1
  14. package/src/init/generator.d.ts +13 -0
  15. package/src/init/generator.js +14 -3
  16. package/src/init/generator.js.map +1 -1
  17. package/src/migrations/latest/backfill-generator-metadata/migration.d.ts +96 -0
  18. package/src/migrations/latest/backfill-generator-metadata/migration.js +670 -0
  19. package/src/migrations/latest/backfill-generator-metadata/migration.js.map +1 -0
  20. package/src/migrations/latest/dynamodb-local-remove-optimize-flag/migration.d.ts +6 -0
  21. package/src/migrations/latest/dynamodb-local-remove-optimize-flag/migration.js +89 -0
  22. package/src/migrations/latest/dynamodb-local-remove-optimize-flag/migration.js.map +1 -0
  23. package/src/migrations/latest/modernize-function-props-cast/migration.js +0 -1
  24. package/src/migrations/latest/modernize-function-props-cast/migration.js.map +1 -1
  25. package/src/migrations/latest/order-access-log-delivery-after-bucket-policy/migration.js +0 -1
  26. package/src/migrations/latest/order-access-log-delivery-after-bucket-policy/migration.js.map +1 -1
  27. package/src/migrations/latest/restrict-cors-to-custom-domains/migration.js +0 -2
  28. package/src/migrations/latest/restrict-cors-to-custom-domains/migration.js.map +1 -1
  29. package/src/migrations/latest/terraform-bootstrap-adopt-existing-bucket/migration.js +0 -1
  30. package/src/migrations/latest/terraform-bootstrap-adopt-existing-bucket/migration.js.map +1 -1
  31. package/src/migrations/latest/user-identity-waf-allow-localhost-callback/migration.js +0 -2
  32. package/src/migrations/latest/user-identity-waf-allow-localhost-callback/migration.js.map +1 -1
  33. package/src/preset/generator.d.ts +13 -0
  34. package/src/preset/generator.js +12 -3
  35. package/src/preset/generator.js.map +1 -1
  36. package/src/py/agent/a2a-connection/generator.d.ts +24 -0
  37. package/src/py/agent/a2a-connection/generator.js +49 -20
  38. package/src/py/agent/a2a-connection/generator.js.map +1 -1
  39. package/src/py/agent/gateway-connection/generator.d.ts +23 -0
  40. package/src/py/agent/gateway-connection/generator.js +45 -11
  41. package/src/py/agent/gateway-connection/generator.js.map +1 -1
  42. package/src/py/agent/generator.d.ts +146 -1
  43. package/src/py/agent/generator.js +173 -76
  44. package/src/py/agent/generator.js.map +1 -1
  45. package/src/py/agent/mcp-connection/generator.d.ts +23 -0
  46. package/src/py/agent/mcp-connection/generator.js +45 -11
  47. package/src/py/agent/mcp-connection/generator.js.map +1 -1
  48. package/src/py/agent/react-connection/generator.d.ts +146 -0
  49. package/src/py/agent/react-connection/generator.js +27 -4
  50. package/src/py/agent/react-connection/generator.js.map +1 -1
  51. package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +0 -2
  52. package/src/py/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +18 -0
  53. package/src/py/dynamodb/agent-connection/generator.js +7 -1
  54. package/src/py/dynamodb/agent-connection/generator.js.map +1 -1
  55. package/src/py/dynamodb/fast-api-connection/__snapshots__/generator.spec.ts.snap +9 -0
  56. package/src/py/dynamodb/fast-api-connection/generator.js +3 -1
  57. package/src/py/dynamodb/fast-api-connection/generator.js.map +1 -1
  58. package/src/py/dynamodb/generator.d.ts +29 -0
  59. package/src/py/dynamodb/generator.js +32 -12
  60. package/src/py/dynamodb/generator.js.map +1 -1
  61. package/src/py/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +18 -0
  62. package/src/py/dynamodb/mcp-server-connection/generator.js +7 -1
  63. package/src/py/dynamodb/mcp-server-connection/generator.js.map +1 -1
  64. package/src/py/fast-api/generator.d.ts +63 -0
  65. package/src/py/fast-api/generator.js +58 -23
  66. package/src/py/fast-api/generator.js.map +1 -1
  67. package/src/py/fast-api/react/generator.d.ts +16 -1
  68. package/src/py/fast-api/react/generator.js +15 -3
  69. package/src/py/fast-api/react/generator.js.map +1 -1
  70. package/src/py/lambda-function/generator.d.ts +21 -0
  71. package/src/py/lambda-function/generator.js +29 -10
  72. package/src/py/lambda-function/generator.js.map +1 -1
  73. package/src/py/mcp-server/generator.d.ts +60 -0
  74. package/src/py/mcp-server/generator.js +62 -25
  75. package/src/py/mcp-server/generator.js.map +1 -1
  76. package/src/py/project/generator.d.ts +13 -0
  77. package/src/py/project/generator.js +29 -10
  78. package/src/py/project/generator.js.map +1 -1
  79. package/src/py/rdb/agent-connection/__snapshots__/generator.spec.ts.snap +19 -0
  80. package/src/py/rdb/agent-connection/generator.js +7 -1
  81. package/src/py/rdb/agent-connection/generator.js.map +1 -1
  82. package/src/py/rdb/fast-api-connection/__snapshots__/generator.spec.ts.snap +7 -0
  83. package/src/py/rdb/fast-api-connection/generator.js +3 -1
  84. package/src/py/rdb/fast-api-connection/generator.js.map +1 -1
  85. package/src/py/rdb/generator.d.ts +89 -0
  86. package/src/py/rdb/generator.js +88 -40
  87. package/src/py/rdb/generator.js.map +1 -1
  88. package/src/py/rdb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +18 -0
  89. package/src/py/rdb/mcp-server-connection/generator.js +7 -1
  90. package/src/py/rdb/mcp-server-connection/generator.js.map +1 -1
  91. package/src/smithy/project/generator.d.ts +7 -0
  92. package/src/smithy/project/generator.js +8 -2
  93. package/src/smithy/project/generator.js.map +1 -1
  94. package/src/smithy/react-connection/generator.d.ts +15 -0
  95. package/src/smithy/react-connection/generator.js +17 -3
  96. package/src/smithy/react-connection/generator.js.map +1 -1
  97. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +1 -0
  98. package/src/smithy/ts/api/generator.d.ts +79 -0
  99. package/src/smithy/ts/api/generator.js +77 -33
  100. package/src/smithy/ts/api/generator.js.map +1 -1
  101. package/src/terraform/project/generator.d.ts +50 -0
  102. package/src/terraform/project/generator.js +63 -17
  103. package/src/terraform/project/generator.js.map +1 -1
  104. package/src/trpc/backend/generator.d.ts +84 -0
  105. package/src/trpc/backend/generator.js +98 -38
  106. package/src/trpc/backend/generator.js.map +1 -1
  107. package/src/trpc/react/generator.d.ts +37 -0
  108. package/src/trpc/react/generator.js +63 -26
  109. package/src/trpc/react/generator.js.map +1 -1
  110. package/src/ts/agent/a2a-connection/generator.d.ts +46 -0
  111. package/src/ts/agent/a2a-connection/generator.js +53 -16
  112. package/src/ts/agent/a2a-connection/generator.js.map +1 -1
  113. package/src/ts/agent/gateway-connection/generator.d.ts +37 -0
  114. package/src/ts/agent/gateway-connection/generator.js +41 -14
  115. package/src/ts/agent/gateway-connection/generator.js.map +1 -1
  116. package/src/ts/agent/generator.d.ts +162 -0
  117. package/src/ts/agent/generator.js +166 -75
  118. package/src/ts/agent/generator.js.map +1 -1
  119. package/src/ts/agent/mcp-connection/generator.d.ts +37 -0
  120. package/src/ts/agent/mcp-connection/generator.js +41 -14
  121. package/src/ts/agent/mcp-connection/generator.js.map +1 -1
  122. package/src/ts/agent/react-connection/generator.d.ts +186 -0
  123. package/src/ts/agent/react-connection/generator.js +70 -21
  124. package/src/ts/agent/react-connection/generator.js.map +1 -1
  125. package/src/ts/astro-docs/generator.d.ts +38 -0
  126. package/src/ts/astro-docs/generator.js +58 -19
  127. package/src/ts/astro-docs/generator.js.map +1 -1
  128. package/src/ts/dcr-proxy/generator.d.ts +24 -0
  129. package/src/ts/dcr-proxy/generator.js +31 -14
  130. package/src/ts/dcr-proxy/generator.js.map +1 -1
  131. package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +0 -2
  132. package/src/ts/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +18 -0
  133. package/src/ts/dynamodb/agent-connection/generator.js +7 -1
  134. package/src/ts/dynamodb/agent-connection/generator.js.map +1 -1
  135. package/src/ts/dynamodb/generator.d.ts +41 -0
  136. package/src/ts/dynamodb/generator.js +47 -20
  137. package/src/ts/dynamodb/generator.js.map +1 -1
  138. package/src/ts/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +18 -0
  139. package/src/ts/dynamodb/mcp-server-connection/generator.js +7 -1
  140. package/src/ts/dynamodb/mcp-server-connection/generator.js.map +1 -1
  141. package/src/ts/dynamodb/smithy-connection/__snapshots__/generator.spec.ts.snap +9 -0
  142. package/src/ts/dynamodb/smithy-connection/generator.js +3 -1
  143. package/src/ts/dynamodb/smithy-connection/generator.js.map +1 -1
  144. package/src/ts/dynamodb/trpc-connection/__snapshots__/generator.spec.ts.snap +9 -0
  145. package/src/ts/dynamodb/trpc-connection/generator.js +3 -1
  146. package/src/ts/dynamodb/trpc-connection/generator.js.map +1 -1
  147. package/src/ts/lambda-function/generator.d.ts +38 -0
  148. package/src/ts/lambda-function/generator.js +49 -20
  149. package/src/ts/lambda-function/generator.js.map +1 -1
  150. package/src/ts/lib/generator.d.ts +7 -0
  151. package/src/ts/lib/generator.js +8 -1
  152. package/src/ts/lib/generator.js.map +1 -1
  153. package/src/ts/lib/ts-project-utils.d.ts +3 -1
  154. package/src/ts/lib/ts-project-utils.js +3 -2
  155. package/src/ts/lib/ts-project-utils.js.map +1 -1
  156. package/src/ts/lib/vitest.d.ts +10 -1
  157. package/src/ts/lib/vitest.js +14 -2
  158. package/src/ts/lib/vitest.js.map +1 -1
  159. package/src/ts/mcp-server/generator.d.ts +71 -0
  160. package/src/ts/mcp-server/generator.js +73 -36
  161. package/src/ts/mcp-server/generator.js.map +1 -1
  162. package/src/ts/nx-generator/generator.d.ts +3 -0
  163. package/src/ts/nx-generator/generator.js +8 -2
  164. package/src/ts/nx-generator/generator.js.map +1 -1
  165. package/src/ts/nx-migration/files/migration.ts.template +4 -0
  166. package/src/ts/nx-migration/generator.d.ts +3 -0
  167. package/src/ts/nx-migration/generator.js +8 -2
  168. package/src/ts/nx-migration/generator.js.map +1 -1
  169. package/src/ts/nx-plugin/generator.d.ts +3 -0
  170. package/src/ts/nx-plugin/generator.js +8 -2
  171. package/src/ts/nx-plugin/generator.js.map +1 -1
  172. package/src/ts/nx-plugin/utils.d.ts +7 -2
  173. package/src/ts/nx-plugin/utils.js +10 -4
  174. package/src/ts/nx-plugin/utils.js.map +1 -1
  175. package/src/ts/rdb/agent-connection/__snapshots__/generator.spec.ts.snap +10 -0
  176. package/src/ts/rdb/agent-connection/generator.js +8 -1
  177. package/src/ts/rdb/agent-connection/generator.js.map +1 -1
  178. package/src/ts/rdb/generator.d.ts +101 -0
  179. package/src/ts/rdb/generator.js +93 -41
  180. package/src/ts/rdb/generator.js.map +1 -1
  181. package/src/ts/rdb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +10 -0
  182. package/src/ts/rdb/mcp-server-connection/generator.js +8 -1
  183. package/src/ts/rdb/mcp-server-connection/generator.js.map +1 -1
  184. package/src/ts/rdb/smithy-connection/__snapshots__/generator.spec.ts.snap +9 -0
  185. package/src/ts/rdb/smithy-connection/generator.js +4 -1
  186. package/src/ts/rdb/smithy-connection/generator.js.map +1 -1
  187. package/src/ts/rdb/trpc-connection/__snapshots__/generator.spec.ts.snap +9 -0
  188. package/src/ts/rdb/trpc-connection/generator.js +3 -1
  189. package/src/ts/rdb/trpc-connection/generator.js.map +1 -1
  190. package/src/ts/react-website/agui/generator.d.ts +86 -0
  191. package/src/ts/react-website/agui/generator.js +63 -28
  192. package/src/ts/react-website/agui/generator.js.map +1 -1
  193. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +8 -2
  194. package/src/ts/react-website/app/generator.d.ts +136 -1
  195. package/src/ts/react-website/app/generator.js +109 -40
  196. package/src/ts/react-website/app/generator.js.map +1 -1
  197. package/src/ts/react-website/cognito-auth/generator.d.ts +19 -0
  198. package/src/ts/react-website/cognito-auth/generator.js +21 -9
  199. package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
  200. package/src/utils/add-dependencies.d.ts +38 -0
  201. package/src/utils/add-dependencies.js +83 -0
  202. package/src/utils/add-dependencies.js.map +1 -0
  203. package/src/utils/agent-connection/agent-connection.d.ts +27 -6
  204. package/src/utils/agent-connection/agent-connection.js +47 -18
  205. package/src/utils/agent-connection/agent-connection.js.map +1 -1
  206. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +19 -1
  207. package/src/utils/agent-core-constructs/agent-core-constructs.js +26 -6
  208. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  209. package/src/utils/api-constructs/api-constructs.d.ts +21 -2
  210. package/src/utils/api-constructs/api-constructs.js +26 -5
  211. package/src/utils/api-constructs/api-constructs.js.map +1 -1
  212. package/src/utils/bundle/bundle.d.ts +6 -1
  213. package/src/utils/bundle/bundle.js +8 -2
  214. package/src/utils/bundle/bundle.js.map +1 -1
  215. package/src/utils/commands.d.ts +5 -4
  216. package/src/utils/commands.js +2 -6
  217. package/src/utils/commands.js.map +1 -1
  218. package/src/utils/connection/open-api/react.d.ts +18 -1
  219. package/src/utils/connection/open-api/react.js +27 -3
  220. package/src/utils/connection/open-api/react.js.map +1 -1
  221. package/src/utils/declared-dependencies.d.ts +140 -0
  222. package/src/utils/declared-dependencies.js +64 -0
  223. package/src/utils/declared-dependencies.js.map +1 -0
  224. package/src/utils/docker.d.ts +10 -1
  225. package/src/utils/docker.js +7 -3
  226. package/src/utils/docker.js.map +1 -1
  227. package/src/utils/files/common/scripts/src/dynamodb/start-container.ts.template +0 -1
  228. package/src/utils/fs.d.ts +15 -4
  229. package/src/utils/fs.js +26 -13
  230. package/src/utils/fs.js.map +1 -1
  231. package/src/utils/init.d.ts +14 -1
  232. package/src/utils/init.js +25 -7
  233. package/src/utils/init.js.map +1 -1
  234. package/src/utils/migration-versions.d.ts +25 -6
  235. package/src/utils/migration-versions.js +72 -14
  236. package/src/utils/migration-versions.js.map +1 -1
  237. package/src/utils/nx.d.ts +18 -0
  238. package/src/utils/nx.js +4 -0
  239. package/src/utils/nx.js.map +1 -1
  240. package/src/utils/py.d.ts +3 -2
  241. package/src/utils/py.js +10 -10
  242. package/src/utils/py.js.map +1 -1
  243. package/src/utils/shared-constructs-constants.d.ts +39 -4
  244. package/src/utils/shared-constructs-constants.js +29 -0
  245. package/src/utils/shared-constructs-constants.js.map +1 -1
  246. package/src/utils/shared-constructs.d.ts +4 -1
  247. package/src/utils/shared-constructs.js +5 -4
  248. package/src/utils/shared-constructs.js.map +1 -1
  249. package/src/utils/shared-dynamodb-scripts.d.ts +8 -1
  250. package/src/utils/shared-dynamodb-scripts.js +11 -3
  251. package/src/utils/shared-dynamodb-scripts.js.map +1 -1
  252. package/src/utils/shared-infra-scripts.d.ts +16 -1
  253. package/src/utils/shared-infra-scripts.js +18 -3
  254. package/src/utils/shared-infra-scripts.js.map +1 -1
  255. package/src/utils/shared-rdb-scripts.d.ts +12 -1
  256. package/src/utils/shared-rdb-scripts.js +17 -3
  257. package/src/utils/shared-rdb-scripts.js.map +1 -1
  258. package/src/utils/shared-shadcn.d.ts +26 -1
  259. package/src/utils/shared-shadcn.js +31 -14
  260. package/src/utils/shared-shadcn.js.map +1 -1
  261. package/src/utils/version-upgrade-migration/migration.d.ts +14 -0
  262. package/src/utils/version-upgrade-migration/migration.js +16 -0
  263. package/src/utils/version-upgrade-migration/migration.js.map +1 -0
  264. package/src/utils/version-upgrade-migration/nx-package-updates.d.ts +45 -0
  265. package/src/utils/version-upgrade-migration/nx-package-updates.js +50 -0
  266. package/src/utils/version-upgrade-migration/nx-package-updates.js.map +1 -0
  267. package/src/utils/version-upgrade-migration/owned-dependencies.d.ts +50 -0
  268. package/src/utils/version-upgrade-migration/owned-dependencies.js +98 -0
  269. package/src/utils/version-upgrade-migration/owned-dependencies.js.map +1 -0
  270. package/src/utils/version-upgrade-migration/register.d.ts +23 -0
  271. package/src/utils/version-upgrade-migration/register.js +38 -0
  272. package/src/utils/version-upgrade-migration/register.js.map +1 -0
  273. package/src/utils/version-upgrade-migration/sync-metrics-version.d.ts +13 -0
  274. package/src/utils/version-upgrade-migration/sync-metrics-version.js +33 -0
  275. package/src/utils/version-upgrade-migration/sync-metrics-version.js.map +1 -0
  276. package/src/utils/version-upgrade-migration/sync-vended-versions.d.ts +10 -0
  277. package/src/utils/version-upgrade-migration/sync-vended-versions.js +504 -0
  278. package/src/utils/version-upgrade-migration/sync-vended-versions.js.map +1 -0
  279. package/src/utils/version-upgrade-migration/vended-upgrade.d.ts +14 -0
  280. package/src/utils/version-upgrade-migration/vended-upgrade.js +40 -0
  281. package/src/utils/version-upgrade-migration/vended-upgrade.js.map +1 -0
  282. package/src/utils/versions.d.ts +25 -5
  283. package/src/utils/versions.js +46 -4
  284. package/src/utils/versions.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/project/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n ensurePackage,\n type GeneratorCallback,\n joinPathFragments,\n readNxJson,\n readProjectConfiguration,\n type Tree,\n updateNxJson,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport {\n addLicenseCheckToLintTarget,\n ensurePythonLicenseCollector,\n} from '../../license/config';\nimport { addDependenciesToPackageJson } from '../../utils/dependencies';\nimport { updateGitIgnore } from '../../utils/git';\nimport { installDependencies } from '../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics';\nimport { normalizeDistributionName, toSnakeCase } from '../../utils/names';\nimport { getNpmScope } from '../../utils/npm-scope';\nimport {\n addDependencyToTargetIfNotPresent,\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx';\nimport type { UVPyprojectToml } from '../../utils/nxlv-python';\nimport {\n migrateToSharedVenvGenerator,\n uvProjectGenerator,\n} from '../../utils/nxlv-python';\nimport { sortObjectKeys } from '../../utils/object';\nimport { addDependenciesToDependencyGroupInPyProjectToml } from '../../utils/py';\nimport { updateToml } from '../../utils/toml';\nimport { withVersions } from '../../utils/versions';\nimport type { PyProjectGeneratorSchema } from './schema';\n\nexport const PY_PROJECT_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\n// Transient artifacts that pytest, coverage and ruff create and remove while\n// the test, typecheck and compile targets run concurrently. `.coverage.*` are\n// the per-process data files pytest-cov writes (`.coverage.<host>.<pid>.<rand>`)\n// before combining them. Both `ty` (which respects .gitignore) and the\n// `@nxlv/python:build` copy (which respects `ignorePaths`) would otherwise fail\n// when they read one of these mid-deletion.\nconst PYTHON_TRANSIENT_ARTIFACTS = [\n '__pycache__',\n '.coverage',\n '.coverage.*',\n '.pytest_cache',\n 'pytest-cache-files-*',\n '.ruff_cache',\n];\n\nexport interface PyProjectDetails {\n /**\n * Fully qualified Nx project id including scope, in dot notation (eg foo.bar).\n * This is the identifier Nx uses (readProjectConfiguration, the project\n * graph, target references) and is intentionally kept dotted.\n */\n readonly fullyQualifiedName: string;\n /**\n * PEP 503 normalised Python distribution name (eg foo-bar). This is the name\n * written to the project's `[project].name`, the root `[tool.uv.sources]`\n * key, and any inter-project dependency string. It is hyphenated (not dotted)\n * so `uv` and `@nxlv/python` can match it: uv writes `uv.lock` keyed by the\n * PEP 503 hyphenated name, and `@nxlv/python`'s dependency inference splits a\n * dotted name on `.` and so would otherwise drop the edge entirely. Keeping\n * the distribution name decoupled from `fullyQualifiedName` is what lets the\n * workspace dependency edge appear in the Nx project graph.\n */\n readonly distributionName: string;\n /**\n * Directory of the library relative to the root\n */\n readonly dir: string;\n /**\n * Module name for the project\n */\n readonly normalizedModuleName: string;\n}\n\n/**\n * Returns details about the Python project to be created\n */\nexport const getPyProjectDetails = (\n tree: Tree,\n schema: {\n name: string;\n directory?: string;\n subDirectory?: string;\n moduleName?: string;\n },\n): PyProjectDetails => {\n const scope = toSnakeCase(getNpmScope(tree));\n const normalizedName = toSnakeCase(schema.name);\n const normalizedModuleName = toSnakeCase(\n schema.moduleName ?? `${scope}_${normalizedName}`,\n );\n const fullyQualifiedName = `${scope}.${normalizedName}`;\n // The Python distribution name is the PEP 503 normalised form of the\n // fully qualified name: hyphenated, never dotted. See PyProjectDetails.\n const distributionName = normalizeDistributionName(fullyQualifiedName);\n // NB: interactive nx generator cli can pass empty string\n const dir = joinPathFragments(\n schema.directory || '.',\n schema.subDirectory || normalizedName,\n );\n return { dir, fullyQualifiedName, distributionName, normalizedModuleName };\n};\n\n/**\n * Generates a Python project\n */\nexport const pyProjectGenerator = async (\n tree: Tree,\n schema: PyProjectGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const { dir, normalizedModuleName, fullyQualifiedName, distributionName } =\n getPyProjectDetails(tree, schema);\n\n const pythonPlugin = withVersions(['@nxlv/python']);\n addDependenciesToPackageJson(tree, {}, pythonPlugin);\n\n Object.entries(pythonPlugin).forEach(([name, version]) =>\n ensurePackage(name, version),\n );\n\n const nxJson = readNxJson(tree);\n\n // Only rewrite nx.json when the plugin needs adding, so re-running does not\n // reserialize (and reformat) the file when nothing has changed.\n if (\n !nxJson.plugins?.find((p) =>\n typeof p === 'string'\n ? p === '@nxlv/python'\n : p.plugin === '@nxlv/python',\n )\n ) {\n nxJson.plugins = [\n ...(nxJson.plugins ?? []),\n {\n plugin: '@nxlv/python',\n options: {\n packageManager: 'uv',\n },\n },\n ];\n updateNxJson(tree, nxJson);\n }\n\n // Only scaffold the project when it does not already exist so re-running with\n // the same name does not throw. The rest of the generator still runs to apply\n // any changed options to the existing project.\n if (!projectExists(tree, fullyQualifiedName)) {\n if (!tree.exists('uv.lock')) {\n await migrateToSharedVenvGenerator(tree, {\n autoActivate: true,\n packageManager: 'uv',\n moveDevDependencies: false,\n pyenvPythonVersion: '3.14.0',\n pyprojectPythonDependency: '>=3.14',\n });\n }\n\n await uvProjectGenerator(tree, {\n // The Nx project id (and `uv.workspace.members` etc.) keys off `name`, so\n // keep it dotted. `packageName` is the separate PEP 503 distribution name\n // written to `[project].name` and the root `[tool.uv.sources]` key; it is\n // hyphenated so `@nxlv/python` infers the workspace dependency edge (it\n // splits a dotted name on `.` and would otherwise drop it). This split is\n // the whole fix (see PyProjectDetails.distributionName).\n name: fullyQualifiedName,\n packageName: distributionName,\n publishable: false,\n buildLockedVersions: true,\n buildBundleLocalDependencies: true,\n linter: 'ruff',\n rootPyprojectDependencyGroup: 'main',\n pyenvPythonVersion: '3.14.0',\n pyprojectPythonDependency: '>=3.14',\n projectType: schema.type,\n projectNameAndRootFormat: 'as-provided',\n moduleName: normalizedModuleName,\n directory: dir,\n unitTestRunner: 'pytest',\n codeCoverage: true,\n codeCoverageHtmlReport: true,\n codeCoverageXmlReport: true,\n unitTestHtmlReport: true,\n unitTestJUnitReport: true,\n buildSystem: 'hatch',\n srcDir: false,\n });\n\n // Remove generated hello.py and test_hello.py as they are not needed\n [\n joinPathFragments(dir, normalizedModuleName, 'hello.py'),\n joinPathFragments(dir, 'tests', 'test_hello.py'),\n ].forEach((f) => tree.delete(f));\n\n // Add a placeholder test so pytest doesn't fail with \"no tests collected\"\n tree.write(\n joinPathFragments(dir, 'tests', 'test_noop.py'),\n 'def test_noop():\\n pass\\n',\n );\n }\n\n const outputPath = '{workspaceRoot}/dist/{projectRoot}';\n const buildOutputPath = joinPathFragments(outputPath, 'build');\n const projectConfiguration = readProjectConfiguration(\n tree,\n fullyQualifiedName,\n );\n projectConfiguration.name = fullyQualifiedName;\n // Derive the compile target from the uv build target, and rewrite build to\n // orchestrate the other targets. This only runs on first creation: on re-run\n // build has already been transformed, so re-deriving would corrupt compile\n // and duplicate the build dependencies.\n if (!projectConfiguration.targets.compile) {\n const buildTarget = projectConfiguration.targets.build;\n projectConfiguration.targets.compile = {\n ...buildTarget,\n inputs: ['default', '^production'],\n outputs: [buildOutputPath],\n options: {\n ...buildTarget.options,\n outputPath: buildOutputPath,\n // The build executor copies the project to a temp folder; exclude the\n // executor defaults plus transient artifacts so the copy does not race\n // a concurrent test/typecheck target deleting a file mid-copy.\n ignorePaths: ['.venv', '.tox', 'tests', ...PYTHON_TRANSIENT_ARTIFACTS],\n },\n };\n projectConfiguration.targets.build = {\n inputs: ['default', '^production'],\n dependsOn: [\n 'lint',\n 'compile',\n 'test',\n 'typecheck',\n ...(buildTarget.dependsOn ?? []),\n ],\n options: {\n outputPath,\n },\n };\n }\n projectConfiguration.targets.typecheck = {\n cache: true,\n inputs: ['default', '^production'],\n executor: '@nxlv/python:run-commands',\n options: {\n command: 'uv run ty check',\n cwd: '{projectRoot}',\n },\n };\n\n // Set the default line length to 120, as 88 is a little too strict\n updateToml(\n tree,\n joinPathFragments(dir, 'pyproject.toml'),\n (pyProjectToml: UVPyprojectToml) => {\n if ((pyProjectToml.tool as any)?.ruff) {\n (pyProjectToml.tool as any).ruff['line-length'] = 120;\n }\n return pyProjectToml;\n },\n );\n\n // Pin ruff to the version generation-time formatting uses (PY_VERSIONS), so\n // generated files stay `ruff format --check`-clean across ruff releases.\n addDependenciesToDependencyGroupInPyProjectToml(tree, '.', 'dev', [\n 'ruff',\n 'ty',\n ]);\n\n // Base format target checks rather than writes (so build/lint don't rewrite\n // source); `fix` writes, and `skip-lint` writes without failing so it stays\n // a no-op when propagated through the lint -> format dependency.\n projectConfiguration.targets.format = {\n ...projectConfiguration.targets.format,\n cache: true,\n inputs: ['default', '^production'],\n options: {\n ...projectConfiguration.targets.format?.options,\n check: true,\n },\n configurations: {\n ...projectConfiguration.targets.format?.configurations,\n fix: {\n check: false,\n },\n 'skip-lint': {\n check: false,\n },\n },\n };\n\n // Add a dependency on the format target for lint in order to reduce the number of\n // fixable lint errors (eg line too long)\n projectConfiguration.targets.lint = {\n ...projectConfiguration.targets.lint,\n cache: true,\n inputs: ['default', '^production'],\n configurations: {\n ...projectConfiguration.targets.lint?.configurations,\n fix: {\n fix: true,\n },\n 'skip-lint': {\n exitZero: true,\n },\n },\n };\n // Append `format` without moving an existing entry, so re-running does not\n // reorder lint dependencies (e.g. relative to a later-added license-check).\n addDependencyToTargetIfNotPresent(projectConfiguration, 'lint', 'format');\n\n projectConfiguration.targets = sortObjectKeys(projectConfiguration.targets);\n updateProjectConfiguration(tree, fullyQualifiedName, projectConfiguration);\n\n addGeneratorMetadata(tree, fullyQualifiedName, PY_PROJECT_GENERATOR_INFO);\n\n // Update root .gitignore\n updateGitIgnore(tree, '.', (patterns) => [...patterns, '/reports']);\n\n // Update project level .gitignore. The cache directories are also kept out\n // of type checking: `ty` respects .gitignore, and pytest creates and removes\n // transient `pytest-cache-files-*` directories while the test and typecheck\n // targets run concurrently, which would otherwise make `ty` fail with an I/O\n // error when it scans one mid-deletion.\n updateGitIgnore(tree, dir, (patterns) => [\n ...patterns,\n '**/__pycache__',\n ...PYTHON_TRANSIENT_ARTIFACTS.filter((p) => p !== '__pycache__'),\n ]);\n\n await addGeneratorMetricsIfApplicable(tree, [PY_PROJECT_GENERATOR_INFO]);\n\n await ensurePythonLicenseCollector(tree);\n\n // If license checking is configured, make this project's lint target depend\n // on the root license-check target. No-op if license checking isn't set up;\n // the license generator wires up existing projects itself, so the dependency\n // is added regardless of which generator runs first.\n addLicenseCheckToLintTarget(tree, fullyQualifiedName);\n\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\nexport default pyProjectGenerator;\n"],"names":["ensurePackage","joinPathFragments","readNxJson","readProjectConfiguration","updateNxJson","updateProjectConfiguration","addLicenseCheckToLintTarget","ensurePythonLicenseCollector","addDependenciesToPackageJson","updateGitIgnore","installDependencies","addGeneratorMetricsIfApplicable","normalizeDistributionName","toSnakeCase","getNpmScope","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","projectExists","migrateToSharedVenvGenerator","uvProjectGenerator","sortObjectKeys","addDependenciesToDependencyGroupInPyProjectToml","updateToml","withVersions","PY_PROJECT_GENERATOR_INFO","filename","PYTHON_TRANSIENT_ARTIFACTS","getPyProjectDetails","tree","schema","scope","normalizedName","name","normalizedModuleName","moduleName","fullyQualifiedName","distributionName","dir","directory","subDirectory","pyProjectGenerator","pythonPlugin","Object","entries","forEach","version","nxJson","plugins","find","p","plugin","options","packageManager","exists","autoActivate","moveDevDependencies","pyenvPythonVersion","pyprojectPythonDependency","packageName","publishable","buildLockedVersions","buildBundleLocalDependencies","linter","rootPyprojectDependencyGroup","projectType","type","projectNameAndRootFormat","unitTestRunner","codeCoverage","codeCoverageHtmlReport","codeCoverageXmlReport","unitTestHtmlReport","unitTestJUnitReport","buildSystem","srcDir","f","delete","write","outputPath","buildOutputPath","projectConfiguration","targets","compile","buildTarget","build","inputs","outputs","ignorePaths","dependsOn","typecheck","cache","executor","command","cwd","pyProjectToml","tool","ruff","format","check","configurations","fix","lint","exitZero","patterns","filter","preferInstallDependencies","languages"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/project/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n ensurePackage,\n type GeneratorCallback,\n joinPathFragments,\n readNxJson,\n readProjectConfiguration,\n type Tree,\n updateNxJson,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport {\n addLicenseCheckToLintTarget,\n ensurePythonLicenseCollector,\n} from '../../license/config';\nimport {\n addPyDependencies,\n addTsDependencies,\n} from '../../utils/add-dependencies';\nimport { declareDependencies } from '../../utils/declared-dependencies';\nimport { updateGitIgnore } from '../../utils/git';\nimport { installDependencies } from '../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics';\nimport { normalizeDistributionName, toSnakeCase } from '../../utils/names';\nimport { getNpmScope } from '../../utils/npm-scope';\nimport {\n addDependencyToTargetIfNotPresent,\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx';\nimport type { UVPyprojectToml } from '../../utils/nxlv-python';\nimport {\n migrateToSharedVenvGenerator,\n uvProjectGenerator,\n} from '../../utils/nxlv-python';\nimport { sortObjectKeys } from '../../utils/object';\nimport { updateToml } from '../../utils/toml';\nimport { withVersions } from '../../utils/versions';\nimport type { PyProjectGeneratorSchema } from './schema';\n\nexport const DEPENDENCIES = declareDependencies()({\n ts: [{ name: '@nxlv/python', dev: true, root: true }],\n py: [\n // The linting and type checking tools live in the workspace root pyproject.\n // Pinned to the version generation-time formatting uses, so generated files\n // stay `ruff format --check`-clean across ruff releases.\n { name: 'ruff', group: 'dev', root: true },\n { name: 'ty', group: 'dev', root: true },\n ],\n});\n\nexport const PY_PROJECT_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\n// Transient artifacts that pytest, coverage and ruff create and remove while\n// the test, typecheck and compile targets run concurrently. `.coverage.*` are\n// the per-process data files pytest-cov writes (`.coverage.<host>.<pid>.<rand>`)\n// before combining them. Both `ty` (which respects .gitignore) and the\n// `@nxlv/python:build` copy (which respects `ignorePaths`) would otherwise fail\n// when they read one of these mid-deletion.\nconst PYTHON_TRANSIENT_ARTIFACTS = [\n '__pycache__',\n '.coverage',\n '.coverage.*',\n '.pytest_cache',\n 'pytest-cache-files-*',\n '.ruff_cache',\n];\n\nexport interface PyProjectDetails {\n /**\n * Fully qualified Nx project id including scope, in dot notation (eg foo.bar).\n * This is the identifier Nx uses (readProjectConfiguration, the project\n * graph, target references) and is intentionally kept dotted.\n */\n readonly fullyQualifiedName: string;\n /**\n * PEP 503 normalised Python distribution name (eg foo-bar). This is the name\n * written to the project's `[project].name`, the root `[tool.uv.sources]`\n * key, and any inter-project dependency string. It is hyphenated (not dotted)\n * so `uv` and `@nxlv/python` can match it: uv writes `uv.lock` keyed by the\n * PEP 503 hyphenated name, and `@nxlv/python`'s dependency inference splits a\n * dotted name on `.` and so would otherwise drop the edge entirely. Keeping\n * the distribution name decoupled from `fullyQualifiedName` is what lets the\n * workspace dependency edge appear in the Nx project graph.\n */\n readonly distributionName: string;\n /**\n * Directory of the library relative to the root\n */\n readonly dir: string;\n /**\n * Module name for the project\n */\n readonly normalizedModuleName: string;\n}\n\n/**\n * Returns details about the Python project to be created\n */\nexport const getPyProjectDetails = (\n tree: Tree,\n schema: {\n name: string;\n directory?: string;\n subDirectory?: string;\n moduleName?: string;\n },\n): PyProjectDetails => {\n const scope = toSnakeCase(getNpmScope(tree));\n const normalizedName = toSnakeCase(schema.name);\n const normalizedModuleName = toSnakeCase(\n schema.moduleName ?? `${scope}_${normalizedName}`,\n );\n const fullyQualifiedName = `${scope}.${normalizedName}`;\n // The Python distribution name is the PEP 503 normalised form of the\n // fully qualified name: hyphenated, never dotted. See PyProjectDetails.\n const distributionName = normalizeDistributionName(fullyQualifiedName);\n // NB: interactive nx generator cli can pass empty string\n const dir = joinPathFragments(\n schema.directory || '.',\n schema.subDirectory || normalizedName,\n );\n return { dir, fullyQualifiedName, distributionName, normalizedModuleName };\n};\n\n/**\n * Generates a Python project\n */\nexport const pyProjectGenerator = async (\n tree: Tree,\n schema: PyProjectGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const { dir, normalizedModuleName, fullyQualifiedName, distributionName } =\n getPyProjectDetails(tree, schema);\n\n addTsDependencies(tree, DEPENDENCIES);\n\n const pythonPlugin = withVersions(DEPENDENCIES, ['@nxlv/python']);\n Object.entries(pythonPlugin).forEach(([name, version]) =>\n ensurePackage(name, version),\n );\n\n const nxJson = readNxJson(tree);\n\n // Only rewrite nx.json when the plugin needs adding, so re-running does not\n // reserialize (and reformat) the file when nothing has changed.\n if (\n !nxJson.plugins?.find((p) =>\n typeof p === 'string'\n ? p === '@nxlv/python'\n : p.plugin === '@nxlv/python',\n )\n ) {\n nxJson.plugins = [\n ...(nxJson.plugins ?? []),\n {\n plugin: '@nxlv/python',\n options: {\n packageManager: 'uv',\n },\n },\n ];\n updateNxJson(tree, nxJson);\n }\n\n // Only scaffold the project when it does not already exist so re-running with\n // the same name does not throw. The rest of the generator still runs to apply\n // any changed options to the existing project.\n if (!projectExists(tree, fullyQualifiedName)) {\n if (!tree.exists('uv.lock')) {\n await migrateToSharedVenvGenerator(tree, {\n autoActivate: true,\n packageManager: 'uv',\n moveDevDependencies: false,\n pyenvPythonVersion: '3.14.0',\n pyprojectPythonDependency: '>=3.14',\n });\n }\n\n await uvProjectGenerator(tree, {\n // The Nx project id (and `uv.workspace.members` etc.) keys off `name`, so\n // keep it dotted. `packageName` is the separate PEP 503 distribution name\n // written to `[project].name` and the root `[tool.uv.sources]` key; it is\n // hyphenated so `@nxlv/python` infers the workspace dependency edge (it\n // splits a dotted name on `.` and would otherwise drop it). This split is\n // the whole fix (see PyProjectDetails.distributionName).\n name: fullyQualifiedName,\n packageName: distributionName,\n publishable: false,\n buildLockedVersions: true,\n buildBundleLocalDependencies: true,\n linter: 'ruff',\n rootPyprojectDependencyGroup: 'main',\n pyenvPythonVersion: '3.14.0',\n pyprojectPythonDependency: '>=3.14',\n projectType: schema.type,\n projectNameAndRootFormat: 'as-provided',\n moduleName: normalizedModuleName,\n directory: dir,\n unitTestRunner: 'pytest',\n codeCoverage: true,\n codeCoverageHtmlReport: true,\n codeCoverageXmlReport: true,\n unitTestHtmlReport: true,\n unitTestJUnitReport: true,\n buildSystem: 'hatch',\n srcDir: false,\n });\n\n // Remove generated hello.py and test_hello.py as they are not needed\n [\n joinPathFragments(dir, normalizedModuleName, 'hello.py'),\n joinPathFragments(dir, 'tests', 'test_hello.py'),\n ].forEach((f) => tree.delete(f));\n\n // Add a placeholder test so pytest doesn't fail with \"no tests collected\"\n tree.write(\n joinPathFragments(dir, 'tests', 'test_noop.py'),\n 'def test_noop():\\n pass\\n',\n );\n }\n\n const outputPath = '{workspaceRoot}/dist/{projectRoot}';\n const buildOutputPath = joinPathFragments(outputPath, 'build');\n const projectConfiguration = readProjectConfiguration(\n tree,\n fullyQualifiedName,\n );\n projectConfiguration.name = fullyQualifiedName;\n // Derive the compile target from the uv build target, and rewrite build to\n // orchestrate the other targets. This only runs on first creation: on re-run\n // build has already been transformed, so re-deriving would corrupt compile\n // and duplicate the build dependencies.\n if (!projectConfiguration.targets.compile) {\n const buildTarget = projectConfiguration.targets.build;\n projectConfiguration.targets.compile = {\n ...buildTarget,\n inputs: ['default', '^production'],\n outputs: [buildOutputPath],\n options: {\n ...buildTarget.options,\n outputPath: buildOutputPath,\n // The build executor copies the project to a temp folder; exclude the\n // executor defaults plus transient artifacts so the copy does not race\n // a concurrent test/typecheck target deleting a file mid-copy.\n ignorePaths: ['.venv', '.tox', 'tests', ...PYTHON_TRANSIENT_ARTIFACTS],\n },\n };\n projectConfiguration.targets.build = {\n inputs: ['default', '^production'],\n dependsOn: [\n 'lint',\n 'compile',\n 'test',\n 'typecheck',\n ...(buildTarget.dependsOn ?? []),\n ],\n options: {\n outputPath,\n },\n };\n }\n projectConfiguration.targets.typecheck = {\n cache: true,\n inputs: ['default', '^production'],\n executor: '@nxlv/python:run-commands',\n options: {\n command: 'uv run ty check',\n cwd: '{projectRoot}',\n },\n };\n\n // Set the default line length to 120, as 88 is a little too strict\n updateToml(\n tree,\n joinPathFragments(dir, 'pyproject.toml'),\n (pyProjectToml: UVPyprojectToml) => {\n if ((pyProjectToml.tool as any)?.ruff) {\n (pyProjectToml.tool as any).ruff['line-length'] = 120;\n }\n return pyProjectToml;\n },\n );\n\n addPyDependencies(tree, DEPENDENCIES);\n\n // Base format target checks rather than writes (so build/lint don't rewrite\n // source); `fix` writes, and `skip-lint` writes without failing so it stays\n // a no-op when propagated through the lint -> format dependency.\n projectConfiguration.targets.format = {\n ...projectConfiguration.targets.format,\n cache: true,\n inputs: ['default', '^production'],\n options: {\n ...projectConfiguration.targets.format?.options,\n check: true,\n },\n configurations: {\n ...projectConfiguration.targets.format?.configurations,\n fix: {\n check: false,\n },\n 'skip-lint': {\n check: false,\n },\n },\n };\n\n // Add a dependency on the format target for lint in order to reduce the number of\n // fixable lint errors (eg line too long)\n projectConfiguration.targets.lint = {\n ...projectConfiguration.targets.lint,\n cache: true,\n inputs: ['default', '^production'],\n configurations: {\n ...projectConfiguration.targets.lint?.configurations,\n fix: {\n fix: true,\n },\n 'skip-lint': {\n exitZero: true,\n },\n },\n };\n // Append `format` without moving an existing entry, so re-running does not\n // reorder lint dependencies (e.g. relative to a later-added license-check).\n addDependencyToTargetIfNotPresent(projectConfiguration, 'lint', 'format');\n\n projectConfiguration.targets = sortObjectKeys(projectConfiguration.targets);\n updateProjectConfiguration(tree, fullyQualifiedName, projectConfiguration);\n\n addGeneratorMetadata(tree, fullyQualifiedName, PY_PROJECT_GENERATOR_INFO);\n\n // Update root .gitignore\n updateGitIgnore(tree, '.', (patterns) => [...patterns, '/reports']);\n\n // Update project level .gitignore. The cache directories are also kept out\n // of type checking: `ty` respects .gitignore, and pytest creates and removes\n // transient `pytest-cache-files-*` directories while the test and typecheck\n // targets run concurrently, which would otherwise make `ty` fail with an I/O\n // error when it scans one mid-deletion.\n updateGitIgnore(tree, dir, (patterns) => [\n ...patterns,\n '**/__pycache__',\n ...PYTHON_TRANSIENT_ARTIFACTS.filter((p) => p !== '__pycache__'),\n ]);\n\n await addGeneratorMetricsIfApplicable(tree, [PY_PROJECT_GENERATOR_INFO]);\n\n await ensurePythonLicenseCollector(tree);\n\n // If license checking is configured, make this project's lint target depend\n // on the root license-check target. No-op if license checking isn't set up;\n // the license generator wires up existing projects itself, so the dependency\n // is added regardless of which generator runs first.\n addLicenseCheckToLintTarget(tree, fullyQualifiedName);\n\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\nexport default pyProjectGenerator;\n"],"names":["ensurePackage","joinPathFragments","readNxJson","readProjectConfiguration","updateNxJson","updateProjectConfiguration","addLicenseCheckToLintTarget","ensurePythonLicenseCollector","addPyDependencies","addTsDependencies","declareDependencies","updateGitIgnore","installDependencies","addGeneratorMetricsIfApplicable","normalizeDistributionName","toSnakeCase","getNpmScope","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","projectExists","migrateToSharedVenvGenerator","uvProjectGenerator","sortObjectKeys","updateToml","withVersions","DEPENDENCIES","ts","name","dev","root","py","group","PY_PROJECT_GENERATOR_INFO","filename","PYTHON_TRANSIENT_ARTIFACTS","getPyProjectDetails","tree","schema","scope","normalizedName","normalizedModuleName","moduleName","fullyQualifiedName","distributionName","dir","directory","subDirectory","pyProjectGenerator","pythonPlugin","Object","entries","forEach","version","nxJson","plugins","find","p","plugin","options","packageManager","exists","autoActivate","moveDevDependencies","pyenvPythonVersion","pyprojectPythonDependency","packageName","publishable","buildLockedVersions","buildBundleLocalDependencies","linter","rootPyprojectDependencyGroup","projectType","type","projectNameAndRootFormat","unitTestRunner","codeCoverage","codeCoverageHtmlReport","codeCoverageXmlReport","unitTestHtmlReport","unitTestJUnitReport","buildSystem","srcDir","f","delete","write","outputPath","buildOutputPath","projectConfiguration","targets","compile","buildTarget","build","inputs","outputs","ignorePaths","dependsOn","typecheck","cache","executor","command","cwd","pyProjectToml","tool","ruff","format","check","configurations","fix","lint","exitZero","patterns","filter","preferInstallDependencies","languages"],"mappings":"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"}
@@ -41,6 +41,15 @@ CMD ["python", "-m", "proj_my_agent.custom_agent.main"]
41
41
  exports[`py#rdb agent-connection generator > should add rdb dev dependency to agent dev 1`] = `
42
42
  {
43
43
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
44
+ "metadata": {
45
+ "components": [
46
+ {
47
+ "generator": "py#rdb#agent-connection",
48
+ "name": "agent-db",
49
+ "path": "packages/db",
50
+ },
51
+ ],
52
+ },
44
53
  "name": "my-agent",
45
54
  "root": "packages/my-agent",
46
55
  "sourceRoot": "packages/my-agent/src/proj_my_agent",
@@ -83,6 +92,16 @@ CMD ["python", "-m", "proj_my_agent.agent.main"]
83
92
  exports[`py#rdb agent-connection generator > should use sourceComponent name when provided 1`] = `
84
93
  {
85
94
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
95
+ "metadata": {
96
+ "components": [
97
+ {
98
+ "generator": "py#rdb#agent-connection",
99
+ "name": "custom-agent-db",
100
+ "path": "packages/db",
101
+ "sourcePath": "src/proj_my_agent/custom_agent",
102
+ },
103
+ ],
104
+ },
86
105
  "name": "my-agent",
87
106
  "root": "packages/my-agent",
88
107
  "sourceRoot": "packages/my-agent/src/proj_my_agent",
@@ -6,7 +6,7 @@ import { formatFilesInSubtree } from "../../../utils/format.js";
6
6
  import { installDependencies } from "../../../utils/install.js";
7
7
  import { addGeneratorMetricsIfApplicable } from "../../../utils/metrics.js";
8
8
  import { toSnakeCase } from "../../../utils/names.js";
9
- import { addDependencyToTargetIfNotPresent, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../../utils/nx.js";
9
+ import { addComponentGeneratorMetadata, addDependencyToTargetIfNotPresent, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../../utils/nx.js";
10
10
  import { addWorkspaceDependencyToPyProject } from "../../../utils/py.js";
11
11
  import { injectRdsCaBundleIntoDockerfile } from "../utils.js";
12
12
  export const PY_RDB_AGENT_CONNECTION_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
@@ -30,6 +30,12 @@ export const pyRdbAgentConnectionGenerator = async (tree, options)=>{
30
30
  });
31
31
  updateProjectConfiguration(tree, sourceProject.name, sourceProject);
32
32
  }
33
+ // Recorded so the version sync can identify this connection.
34
+ addComponentGeneratorMetadata(tree, sourceProject.name, PY_RDB_AGENT_CONNECTION_GENERATOR_INFO, targetProject.root, `${agentName}-${targetProject.name}`, // The source component this connection is made from, so the pair is
35
+ // identifiable rather than just the two projects.
36
+ {
37
+ sourcePath: options.sourceComponent?.path
38
+ });
33
39
  await addGeneratorMetricsIfApplicable(tree, [
34
40
  PY_RDB_AGENT_CONNECTION_GENERATOR_INFO
35
41
  ]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/rdb/agent-connection/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n joinPathFragments,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { installDependencies } from '../../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics';\nimport { toSnakeCase } from '../../../utils/names';\nimport {\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../../utils/nx';\nimport { addWorkspaceDependencyToPyProject } from '../../../utils/py';\nimport { injectRdsCaBundleIntoDockerfile } from '../utils';\nimport type { PyRdbAgentConnectionGeneratorSchema } from './schema';\n\nexport const PY_RDB_AGENT_CONNECTION_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const pyRdbAgentConnectionGenerator = async (\n tree: Tree,\n options: PyRdbAgentConnectionGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const sourceProject = readProjectConfigurationUnqualified(\n tree,\n options.sourceProject,\n );\n const targetProject = readProjectConfigurationUnqualified(\n tree,\n options.targetProject,\n );\n\n addWorkspaceDependencyToPyProject(tree, sourceProject, targetProject);\n\n const agentName = options.sourceComponent?.name ?? 'agent';\n const devTarget = `${agentName}-dev`;\n const agentSourceDir = options.sourceComponent?.path\n ? joinPathFragments(sourceProject.root, options.sourceComponent.path)\n : sourceProject.sourceRoot\n ? joinPathFragments(sourceProject.sourceRoot, toSnakeCase(agentName))\n : undefined;\n const dockerfilePath = agentSourceDir\n ? joinPathFragments(agentSourceDir, 'Dockerfile')\n : undefined;\n\n if (dockerfilePath) {\n injectRdsCaBundleIntoDockerfile(tree, dockerfilePath);\n }\n\n if (sourceProject.targets?.[devTarget]) {\n addDependencyToTargetIfNotPresent(sourceProject, devTarget, {\n projects: [targetProject.name],\n target: 'dev',\n });\n updateProjectConfiguration(tree, sourceProject.name, sourceProject);\n }\n\n await addGeneratorMetricsIfApplicable(tree, [\n PY_RDB_AGENT_CONNECTION_GENERATOR_INFO,\n ]);\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyRdbAgentConnectionGenerator;\n"],"names":["joinPathFragments","updateProjectConfiguration","formatFilesInSubtree","installDependencies","addGeneratorMetricsIfApplicable","toSnakeCase","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","addWorkspaceDependencyToPyProject","injectRdsCaBundleIntoDockerfile","PY_RDB_AGENT_CONNECTION_GENERATOR_INFO","filename","pyRdbAgentConnectionGenerator","tree","options","sourceProject","targetProject","agentName","sourceComponent","name","devTarget","agentSourceDir","path","root","sourceRoot","undefined","dockerfilePath","targets","projects","target","preferInstallDependencies","languages"],"mappings":"AAAA;;;CAGC,GACD,SAEEA,iBAAiB,EAEjBC,0BAA0B,QACrB,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,mBAAmB,QAAQ,4BAAyB;AAC7D,SAASC,+BAA+B,QAAQ,4BAAyB;AACzE,SAASC,WAAW,QAAQ,0BAAuB;AACnD,SACEC,iCAAiC,EACjCC,gBAAgB,EAEhBC,mCAAmC,QAC9B,uBAAoB;AAC3B,SAASC,iCAAiC,QAAQ,uBAAoB;AACtE,SAASC,+BAA+B,QAAQ,cAAW;AAG3D,OAAO,MAAMC,yCACXJ,iBAAiB,YAAYK,QAAQ,EAAE;AAEzC,OAAO,MAAMC,gCAAgC,OAC3CC,MACAC;IAEA,MAAMC,gBAAgBR,oCACpBM,MACAC,QAAQC,aAAa;IAEvB,MAAMC,gBAAgBT,oCACpBM,MACAC,QAAQE,aAAa;IAGvBR,kCAAkCK,MAAME,eAAeC;IAEvD,MAAMC,YAAYH,QAAQI,eAAe,EAAEC,QAAQ;IACnD,MAAMC,YAAY,GAAGH,UAAU,IAAI,CAAC;IACpC,MAAMI,iBAAiBP,QAAQI,eAAe,EAAEI,OAC5CvB,kBAAkBgB,cAAcQ,IAAI,EAAET,QAAQI,eAAe,CAACI,IAAI,IAClEP,cAAcS,UAAU,GACtBzB,kBAAkBgB,cAAcS,UAAU,EAAEpB,YAAYa,cACxDQ;IACN,MAAMC,iBAAiBL,iBACnBtB,kBAAkBsB,gBAAgB,gBAClCI;IAEJ,IAAIC,gBAAgB;QAClBjB,gCAAgCI,MAAMa;IACxC;IAEA,IAAIX,cAAcY,OAAO,EAAE,CAACP,UAAU,EAAE;QACtCf,kCAAkCU,eAAeK,WAAW;YAC1DQ,UAAU;gBAACZ,cAAcG,IAAI;aAAC;YAC9BU,QAAQ;QACV;QACA7B,2BAA2Ba,MAAME,cAAcI,IAAI,EAAEJ;IACvD;IAEA,MAAMZ,gCAAgCU,MAAM;QAC1CH;KACD;IACD,MAAMT,qBAAqBY;IAC3B,OAAO,IACLX,oBAAoBW,MAAMC,QAAQgB,yBAAyB,EAAE;YAC3DC,WAAW;gBAAC;gBAAc;aAAS;QACrC;AACJ,EAAE;AAEF,eAAenB,8BAA8B"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/rdb/agent-connection/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n joinPathFragments,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { installDependencies } from '../../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics';\nimport { toSnakeCase } from '../../../utils/names';\nimport {\n addComponentGeneratorMetadata,\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../../utils/nx';\nimport { addWorkspaceDependencyToPyProject } from '../../../utils/py';\nimport { injectRdsCaBundleIntoDockerfile } from '../utils';\nimport type { PyRdbAgentConnectionGeneratorSchema } from './schema';\n\nexport const PY_RDB_AGENT_CONNECTION_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const pyRdbAgentConnectionGenerator = async (\n tree: Tree,\n options: PyRdbAgentConnectionGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const sourceProject = readProjectConfigurationUnqualified(\n tree,\n options.sourceProject,\n );\n const targetProject = readProjectConfigurationUnqualified(\n tree,\n options.targetProject,\n );\n\n addWorkspaceDependencyToPyProject(tree, sourceProject, targetProject);\n\n const agentName = options.sourceComponent?.name ?? 'agent';\n const devTarget = `${agentName}-dev`;\n const agentSourceDir = options.sourceComponent?.path\n ? joinPathFragments(sourceProject.root, options.sourceComponent.path)\n : sourceProject.sourceRoot\n ? joinPathFragments(sourceProject.sourceRoot, toSnakeCase(agentName))\n : undefined;\n const dockerfilePath = agentSourceDir\n ? joinPathFragments(agentSourceDir, 'Dockerfile')\n : undefined;\n\n if (dockerfilePath) {\n injectRdsCaBundleIntoDockerfile(tree, dockerfilePath);\n }\n\n if (sourceProject.targets?.[devTarget]) {\n addDependencyToTargetIfNotPresent(sourceProject, devTarget, {\n projects: [targetProject.name],\n target: 'dev',\n });\n updateProjectConfiguration(tree, sourceProject.name, sourceProject);\n }\n\n // Recorded so the version sync can identify this connection.\n addComponentGeneratorMetadata(\n tree,\n sourceProject.name,\n PY_RDB_AGENT_CONNECTION_GENERATOR_INFO,\n targetProject.root,\n `${agentName}-${targetProject.name}`,\n // The source component this connection is made from, so the pair is\n // identifiable rather than just the two projects.\n { sourcePath: options.sourceComponent?.path },\n );\n\n await addGeneratorMetricsIfApplicable(tree, [\n PY_RDB_AGENT_CONNECTION_GENERATOR_INFO,\n ]);\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyRdbAgentConnectionGenerator;\n"],"names":["joinPathFragments","updateProjectConfiguration","formatFilesInSubtree","installDependencies","addGeneratorMetricsIfApplicable","toSnakeCase","addComponentGeneratorMetadata","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","addWorkspaceDependencyToPyProject","injectRdsCaBundleIntoDockerfile","PY_RDB_AGENT_CONNECTION_GENERATOR_INFO","filename","pyRdbAgentConnectionGenerator","tree","options","sourceProject","targetProject","agentName","sourceComponent","name","devTarget","agentSourceDir","path","root","sourceRoot","undefined","dockerfilePath","targets","projects","target","sourcePath","preferInstallDependencies","languages"],"mappings":"AAAA;;;CAGC,GACD,SAEEA,iBAAiB,EAEjBC,0BAA0B,QACrB,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,mBAAmB,QAAQ,4BAAyB;AAC7D,SAASC,+BAA+B,QAAQ,4BAAyB;AACzE,SAASC,WAAW,QAAQ,0BAAuB;AACnD,SACEC,6BAA6B,EAC7BC,iCAAiC,EACjCC,gBAAgB,EAEhBC,mCAAmC,QAC9B,uBAAoB;AAC3B,SAASC,iCAAiC,QAAQ,uBAAoB;AACtE,SAASC,+BAA+B,QAAQ,cAAW;AAG3D,OAAO,MAAMC,yCACXJ,iBAAiB,YAAYK,QAAQ,EAAE;AAEzC,OAAO,MAAMC,gCAAgC,OAC3CC,MACAC;IAEA,MAAMC,gBAAgBR,oCACpBM,MACAC,QAAQC,aAAa;IAEvB,MAAMC,gBAAgBT,oCACpBM,MACAC,QAAQE,aAAa;IAGvBR,kCAAkCK,MAAME,eAAeC;IAEvD,MAAMC,YAAYH,QAAQI,eAAe,EAAEC,QAAQ;IACnD,MAAMC,YAAY,GAAGH,UAAU,IAAI,CAAC;IACpC,MAAMI,iBAAiBP,QAAQI,eAAe,EAAEI,OAC5CxB,kBAAkBiB,cAAcQ,IAAI,EAAET,QAAQI,eAAe,CAACI,IAAI,IAClEP,cAAcS,UAAU,GACtB1B,kBAAkBiB,cAAcS,UAAU,EAAErB,YAAYc,cACxDQ;IACN,MAAMC,iBAAiBL,iBACnBvB,kBAAkBuB,gBAAgB,gBAClCI;IAEJ,IAAIC,gBAAgB;QAClBjB,gCAAgCI,MAAMa;IACxC;IAEA,IAAIX,cAAcY,OAAO,EAAE,CAACP,UAAU,EAAE;QACtCf,kCAAkCU,eAAeK,WAAW;YAC1DQ,UAAU;gBAACZ,cAAcG,IAAI;aAAC;YAC9BU,QAAQ;QACV;QACA9B,2BAA2Bc,MAAME,cAAcI,IAAI,EAAEJ;IACvD;IAEA,6DAA6D;IAC7DX,8BACES,MACAE,cAAcI,IAAI,EAClBT,wCACAM,cAAcO,IAAI,EAClB,GAAGN,UAAU,CAAC,EAAED,cAAcG,IAAI,EAAE,EACpC,oEAAoE;IACpE,kDAAkD;IAClD;QAAEW,YAAYhB,QAAQI,eAAe,EAAEI;IAAK;IAG9C,MAAMpB,gCAAgCW,MAAM;QAC1CH;KACD;IACD,MAAMV,qBAAqBa;IAC3B,OAAO,IACLZ,oBAAoBY,MAAMC,QAAQiB,yBAAyB,EAAE;YAC3DC,WAAW;gBAAC;gBAAc;aAAS;QACrC;AACJ,EAAE;AAEF,eAAepB,8BAA8B"}
@@ -5,6 +5,13 @@ exports[`py#rdb fast-api-connection generator > should add rdb dev dependency to
5
5
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
6
6
  "metadata": {
7
7
  "apiName": "api",
8
+ "components": [
9
+ {
10
+ "generator": "py#rdb#fast-api-connection",
11
+ "name": "db",
12
+ "path": "proj_api/dependencies/db.py",
13
+ },
14
+ ],
8
15
  },
9
16
  "name": "api",
10
17
  "root": "packages/api",
@@ -7,7 +7,7 @@ import { installDependencies } from "../../../utils/install.js";
7
7
  import { addGeneratorMetricsIfApplicable } from "../../../utils/metrics.js";
8
8
  import { toClassName, toSnakeCase } from "../../../utils/names.js";
9
9
  import { getNpmScope } from "../../../utils/npm-scope.js";
10
- import { addDependencyToTargetIfNotPresent, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../../utils/nx.js";
10
+ import { addComponentGeneratorMetadata, addDependencyToTargetIfNotPresent, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../../utils/nx.js";
11
11
  import { addWorkspaceDependencyToPyProject } from "../../../utils/py.js";
12
12
  export const PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
13
13
  export const pyRdbFastApiConnectionGenerator = async (tree, options)=>{
@@ -38,6 +38,8 @@ export const pyRdbFastApiConnectionGenerator = async (tree, options)=>{
38
38
  }, {
39
39
  overwriteStrategy: OverwriteStrategy.KeepExisting
40
40
  });
41
+ // Recorded so the version sync can identify this connection.
42
+ addComponentGeneratorMetadata(tree, sourceProject.name, PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO, joinPathFragments(apiModuleName, 'dependencies', `${rdbNameSnake}.py`), rdbNameSnake);
41
43
  await addGeneratorMetricsIfApplicable(tree, [
42
44
  PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO
43
45
  ]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/rdb/fast-api-connection/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { installDependencies } from '../../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics';\nimport { toClassName, toSnakeCase } from '../../../utils/names';\nimport { getNpmScope } from '../../../utils/npm-scope';\nimport {\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../../utils/nx';\nimport { addWorkspaceDependencyToPyProject } from '../../../utils/py';\nimport type { PyRdbFastApiConnectionGeneratorSchema } from './schema';\n\nexport const PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const pyRdbFastApiConnectionGenerator = async (\n tree: Tree,\n options: PyRdbFastApiConnectionGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const sourceProject = readProjectConfigurationUnqualified(\n tree,\n options.sourceProject,\n );\n const targetProject = readProjectConfigurationUnqualified(\n tree,\n options.targetProject,\n );\n\n addWorkspaceDependencyToPyProject(tree, sourceProject, targetProject);\n\n if (sourceProject.targets?.['dev']) {\n addDependencyToTargetIfNotPresent(sourceProject, 'dev', {\n projects: [targetProject.name],\n target: 'dev',\n });\n updateProjectConfiguration(tree, sourceProject.name, sourceProject);\n }\n\n const scope = toSnakeCase(getNpmScope(tree));\n const rdbLocalName = targetProject.name.split('.').pop()!;\n const databasePackageAlias = `${scope}_${rdbLocalName}`;\n const rdbNameSnake = toSnakeCase(rdbLocalName);\n const rdbNameClassName = toClassName(rdbLocalName);\n const apiName = (sourceProject.metadata as any)?.apiName as string;\n const apiModuleName = toSnakeCase(`${scope}_${toSnakeCase(apiName)}`);\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n sourceProject.root,\n { databasePackageAlias, rdbNameSnake, rdbNameClassName, apiModuleName },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n await addGeneratorMetricsIfApplicable(tree, [\n PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO,\n ]);\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyRdbFastApiConnectionGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","formatFilesInSubtree","installDependencies","addGeneratorMetricsIfApplicable","toClassName","toSnakeCase","getNpmScope","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","addWorkspaceDependencyToPyProject","PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO","filename","pyRdbFastApiConnectionGenerator","tree","options","sourceProject","targetProject","targets","projects","name","target","scope","rdbLocalName","split","pop","databasePackageAlias","rdbNameSnake","rdbNameClassName","apiName","metadata","apiModuleName","dirname","root","overwriteStrategy","KeepExisting","preferInstallDependencies","languages"],"mappings":"AAAA;;;CAGC,GACD,SAEEA,aAAa,EACbC,iBAAiB,EACjBC,iBAAiB,EAEjBC,0BAA0B,QACrB,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,mBAAmB,QAAQ,4BAAyB;AAC7D,SAASC,+BAA+B,QAAQ,4BAAyB;AACzE,SAASC,WAAW,EAAEC,WAAW,QAAQ,0BAAuB;AAChE,SAASC,WAAW,QAAQ,8BAA2B;AACvD,SACEC,iCAAiC,EACjCC,gBAAgB,EAEhBC,mCAAmC,QAC9B,uBAAoB;AAC3B,SAASC,iCAAiC,QAAQ,uBAAoB;AAGtE,OAAO,MAAMC,4CACXH,iBAAiB,YAAYI,QAAQ,EAAE;AAEzC,OAAO,MAAMC,kCAAkC,OAC7CC,MACAC;IAEA,MAAMC,gBAAgBP,oCACpBK,MACAC,QAAQC,aAAa;IAEvB,MAAMC,gBAAgBR,oCACpBK,MACAC,QAAQE,aAAa;IAGvBP,kCAAkCI,MAAME,eAAeC;IAEvD,IAAID,cAAcE,OAAO,EAAE,CAAC,MAAM,EAAE;QAClCX,kCAAkCS,eAAe,OAAO;YACtDG,UAAU;gBAACF,cAAcG,IAAI;aAAC;YAC9BC,QAAQ;QACV;QACArB,2BAA2Bc,MAAME,cAAcI,IAAI,EAAEJ;IACvD;IAEA,MAAMM,QAAQjB,YAAYC,YAAYQ;IACtC,MAAMS,eAAeN,cAAcG,IAAI,CAACI,KAAK,CAAC,KAAKC,GAAG;IACtD,MAAMC,uBAAuB,GAAGJ,MAAM,CAAC,EAAEC,cAAc;IACvD,MAAMI,eAAetB,YAAYkB;IACjC,MAAMK,mBAAmBxB,YAAYmB;IACrC,MAAMM,UAAWb,cAAcc,QAAQ,EAAUD;IACjD,MAAME,gBAAgB1B,YAAY,GAAGiB,MAAM,CAAC,EAAEjB,YAAYwB,UAAU;IAEpEhC,cACEiB,MACAhB,kBAAkB,YAAYkC,OAAO,EAAE,UACvChB,cAAciB,IAAI,EAClB;QAAEP;QAAsBC;QAAcC;QAAkBG;IAAc,GACtE;QAAEG,mBAAmBnC,kBAAkBoC,YAAY;IAAC;IAGtD,MAAMhC,gCAAgCW,MAAM;QAC1CH;KACD;IACD,MAAMV,qBAAqBa;IAC3B,OAAO,IACLZ,oBAAoBY,MAAMC,QAAQqB,yBAAyB,EAAE;YAC3DC,WAAW;gBAAC;gBAAc;aAAS;QACrC;AACJ,EAAE;AAEF,eAAexB,gCAAgC"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/rdb/fast-api-connection/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { installDependencies } from '../../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics';\nimport { toClassName, toSnakeCase } from '../../../utils/names';\nimport { getNpmScope } from '../../../utils/npm-scope';\nimport {\n addComponentGeneratorMetadata,\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../../utils/nx';\nimport { addWorkspaceDependencyToPyProject } from '../../../utils/py';\nimport type { PyRdbFastApiConnectionGeneratorSchema } from './schema';\n\nexport const PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const pyRdbFastApiConnectionGenerator = async (\n tree: Tree,\n options: PyRdbFastApiConnectionGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const sourceProject = readProjectConfigurationUnqualified(\n tree,\n options.sourceProject,\n );\n const targetProject = readProjectConfigurationUnqualified(\n tree,\n options.targetProject,\n );\n\n addWorkspaceDependencyToPyProject(tree, sourceProject, targetProject);\n\n if (sourceProject.targets?.['dev']) {\n addDependencyToTargetIfNotPresent(sourceProject, 'dev', {\n projects: [targetProject.name],\n target: 'dev',\n });\n updateProjectConfiguration(tree, sourceProject.name, sourceProject);\n }\n\n const scope = toSnakeCase(getNpmScope(tree));\n const rdbLocalName = targetProject.name.split('.').pop()!;\n const databasePackageAlias = `${scope}_${rdbLocalName}`;\n const rdbNameSnake = toSnakeCase(rdbLocalName);\n const rdbNameClassName = toClassName(rdbLocalName);\n const apiName = (sourceProject.metadata as any)?.apiName as string;\n const apiModuleName = toSnakeCase(`${scope}_${toSnakeCase(apiName)}`);\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n sourceProject.root,\n { databasePackageAlias, rdbNameSnake, rdbNameClassName, apiModuleName },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n // Recorded so the version sync can identify this connection.\n addComponentGeneratorMetadata(\n tree,\n sourceProject.name,\n PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO,\n joinPathFragments(apiModuleName, 'dependencies', `${rdbNameSnake}.py`),\n rdbNameSnake,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [\n PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO,\n ]);\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyRdbFastApiConnectionGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","formatFilesInSubtree","installDependencies","addGeneratorMetricsIfApplicable","toClassName","toSnakeCase","getNpmScope","addComponentGeneratorMetadata","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","addWorkspaceDependencyToPyProject","PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO","filename","pyRdbFastApiConnectionGenerator","tree","options","sourceProject","targetProject","targets","projects","name","target","scope","rdbLocalName","split","pop","databasePackageAlias","rdbNameSnake","rdbNameClassName","apiName","metadata","apiModuleName","dirname","root","overwriteStrategy","KeepExisting","preferInstallDependencies","languages"],"mappings":"AAAA;;;CAGC,GACD,SAEEA,aAAa,EACbC,iBAAiB,EACjBC,iBAAiB,EAEjBC,0BAA0B,QACrB,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,mBAAmB,QAAQ,4BAAyB;AAC7D,SAASC,+BAA+B,QAAQ,4BAAyB;AACzE,SAASC,WAAW,EAAEC,WAAW,QAAQ,0BAAuB;AAChE,SAASC,WAAW,QAAQ,8BAA2B;AACvD,SACEC,6BAA6B,EAC7BC,iCAAiC,EACjCC,gBAAgB,EAEhBC,mCAAmC,QAC9B,uBAAoB;AAC3B,SAASC,iCAAiC,QAAQ,uBAAoB;AAGtE,OAAO,MAAMC,4CACXH,iBAAiB,YAAYI,QAAQ,EAAE;AAEzC,OAAO,MAAMC,kCAAkC,OAC7CC,MACAC;IAEA,MAAMC,gBAAgBP,oCACpBK,MACAC,QAAQC,aAAa;IAEvB,MAAMC,gBAAgBR,oCACpBK,MACAC,QAAQE,aAAa;IAGvBP,kCAAkCI,MAAME,eAAeC;IAEvD,IAAID,cAAcE,OAAO,EAAE,CAAC,MAAM,EAAE;QAClCX,kCAAkCS,eAAe,OAAO;YACtDG,UAAU;gBAACF,cAAcG,IAAI;aAAC;YAC9BC,QAAQ;QACV;QACAtB,2BAA2Be,MAAME,cAAcI,IAAI,EAAEJ;IACvD;IAEA,MAAMM,QAAQlB,YAAYC,YAAYS;IACtC,MAAMS,eAAeN,cAAcG,IAAI,CAACI,KAAK,CAAC,KAAKC,GAAG;IACtD,MAAMC,uBAAuB,GAAGJ,MAAM,CAAC,EAAEC,cAAc;IACvD,MAAMI,eAAevB,YAAYmB;IACjC,MAAMK,mBAAmBzB,YAAYoB;IACrC,MAAMM,UAAWb,cAAcc,QAAQ,EAAUD;IACjD,MAAME,gBAAgB3B,YAAY,GAAGkB,MAAM,CAAC,EAAElB,YAAYyB,UAAU;IAEpEjC,cACEkB,MACAjB,kBAAkB,YAAYmC,OAAO,EAAE,UACvChB,cAAciB,IAAI,EAClB;QAAEP;QAAsBC;QAAcC;QAAkBG;IAAc,GACtE;QAAEG,mBAAmBpC,kBAAkBqC,YAAY;IAAC;IAGtD,6DAA6D;IAC7D7B,8BACEQ,MACAE,cAAcI,IAAI,EAClBT,2CACAd,kBAAkBkC,eAAe,gBAAgB,GAAGJ,aAAa,GAAG,CAAC,GACrEA;IAGF,MAAMzB,gCAAgCY,MAAM;QAC1CH;KACD;IACD,MAAMX,qBAAqBc;IAC3B,OAAO,IACLb,oBAAoBa,MAAMC,QAAQqB,yBAAyB,EAAE;YAC3DC,WAAW;gBAAC;gBAAc;aAAS;QACrC;AACJ,EAAE;AAEF,eAAexB,gCAAgC"}
@@ -1,6 +1,95 @@
1
1
  import { type GeneratorCallback, type Tree } from '@nx/devkit';
2
2
  import { type NxGeneratorInfo } from '../../utils/nx';
3
+ import { type IacMetadata } from '../../utils/shared-constructs-constants';
3
4
  import type { PyRdbGeneratorSchema } from './schema';
5
+ /** The metadata this generator records, which its predicates read. */
6
+ export interface PyRdbMetadata extends IacMetadata {
7
+ readonly engine: PyRdbGeneratorSchema['engine'];
8
+ }
9
+ export declare const DEPENDENCIES: import("../../utils/declared-dependencies").DependencyDeclaration<readonly [{
10
+ readonly name: "mariadb";
11
+ readonly when: (m: PyRdbMetadata) => boolean;
12
+ readonly root: true;
13
+ }, {
14
+ readonly name: "pg";
15
+ readonly when: (m: PyRdbMetadata) => boolean;
16
+ readonly root: true;
17
+ }, {
18
+ readonly name: "@types/pg";
19
+ readonly when: (m: PyRdbMetadata) => boolean;
20
+ readonly dev: true;
21
+ readonly root: true;
22
+ }, {
23
+ readonly name: "ncp";
24
+ } & {
25
+ versionOnly: true;
26
+ }, {
27
+ readonly name: "rimraf";
28
+ } & {
29
+ versionOnly: true;
30
+ }, {
31
+ readonly name: "make-dir-cli";
32
+ } & {
33
+ versionOnly: true;
34
+ }, {
35
+ readonly name: "ncp";
36
+ } & {
37
+ versionOnly: true;
38
+ }, {
39
+ readonly name: "rimraf";
40
+ } & {
41
+ versionOnly: true;
42
+ }, {
43
+ readonly name: "make-dir-cli";
44
+ } & {
45
+ versionOnly: true;
46
+ }, {
47
+ readonly name: "constructs";
48
+ readonly when: (m: IacMetadata) => boolean;
49
+ } & {
50
+ versionOnly: true;
51
+ }, {
52
+ readonly name: "aws-cdk-lib";
53
+ readonly when: (m: IacMetadata) => boolean;
54
+ } & {
55
+ versionOnly: true;
56
+ }, {
57
+ readonly name: "@types/node";
58
+ } & {
59
+ versionOnly: true;
60
+ }, {
61
+ readonly name: "pg";
62
+ } & {
63
+ versionOnly: true;
64
+ }, {
65
+ readonly name: "@types/pg";
66
+ } & {
67
+ versionOnly: true;
68
+ }, {
69
+ readonly name: "mariadb";
70
+ } & {
71
+ versionOnly: true;
72
+ }, {
73
+ readonly name: "tsx";
74
+ } & {
75
+ versionOnly: true;
76
+ }], readonly [{
77
+ readonly name: "sqlmodel";
78
+ }, {
79
+ readonly name: "alembic";
80
+ }, {
81
+ readonly name: "greenlet";
82
+ }, {
83
+ readonly name: "aiomysql";
84
+ readonly when: (m: PyRdbMetadata) => boolean;
85
+ }, {
86
+ readonly name: "asyncpg";
87
+ readonly when: (m: PyRdbMetadata) => boolean;
88
+ }, {
89
+ readonly name: "boto3";
90
+ }, {
91
+ readonly name: "aws-lambda-powertools";
92
+ }]>;
4
93
  export declare const PY_RDB_GENERATOR_INFO: NxGeneratorInfo;
5
94
  export declare const pyRdbGenerator: (tree: Tree, options: PyRdbGeneratorSchema) => Promise<GeneratorCallback>;
6
95
  export default pyRdbGenerator;
@@ -3,12 +3,13 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */ import { relative } from "node:path";
5
5
  import { generateFiles, joinPathFragments, readProjectConfiguration, updateProjectConfiguration } from "@nx/devkit";
6
+ import { addPyDependencies, addTsDependencies } from "../../utils/add-dependencies.js";
6
7
  import { addPythonBundleTarget } from "../../utils/bundle/bundle.js";
7
8
  import { resolveContainers } from "../../utils/containers.js";
8
- import { addDependenciesToPackageJson } from "../../utils/dependencies.js";
9
- import { addDockerScanTarget } from "../../utils/docker.js";
9
+ import { declareDependencies, ownedElsewhere } from "../../utils/declared-dependencies.js";
10
+ import { addDockerScanTarget, DOCKER_DEPENDENCIES } from "../../utils/docker.js";
10
11
  import { formatFilesInSubtree } from "../../utils/format.js";
11
- import { FsCommands } from "../../utils/fs.js";
12
+ import { FS_DEPENDENCIES, FsCommands } from "../../utils/fs.js";
12
13
  import { resolveIac } from "../../utils/iac.js";
13
14
  import { installDependencies } from "../../utils/install.js";
14
15
  import { addGeneratorMetricsIfApplicable } from "../../utils/metrics.js";
@@ -16,13 +17,70 @@ import { kebabCase, snakeCase, toClassName } from "../../utils/names.js";
16
17
  import { getNpmScope } from "../../utils/npm-scope.js";
17
18
  import { addDependencyToTargetIfNotPresent, addGeneratorMetadata, getGeneratorInfo, projectExists } from "../../utils/nx.js";
18
19
  import { assignPort } from "../../utils/port.js";
19
- import { addDependenciesToPyProjectToml } from "../../utils/py.js";
20
20
  import { addRdbInfra } from "../../utils/rdb-constructs/rdb-constructs.js";
21
- import { sharedConstructsGenerator } from "../../utils/shared-constructs.js";
21
+ import { SHARED_CONSTRUCTS_DEPENDENCIES, sharedConstructsGenerator } from "../../utils/shared-constructs.js";
22
22
  import { PACKAGES_DIR, SHARED_SCRIPTS_DIR } from "../../utils/shared-constructs-constants.js";
23
- import { sharedRdbScriptsGenerator } from "../../utils/shared-rdb-scripts.js";
24
- import { PY_VERSIONS, withVersions } from "../../utils/versions.js";
23
+ import { SHARED_RDB_SCRIPTS_DEPENDENCIES, sharedRdbScriptsGenerator } from "../../utils/shared-rdb-scripts.js";
24
+ import { PY_VERSIONS } from "../../utils/versions.js";
25
25
  import pyProjectGenerator, { getPyProjectDetails } from "../project/generator.js";
26
+ /** The Postgres engine, which MySQL takes none of. */ const isPostgres = (m)=>m.engine !== 'mysql';
27
+ // Each entry names the engine branch it belongs to, so the same declaration
28
+ // drives both adding and the version sync.
29
+ export const DEPENDENCIES = declareDependencies()({
30
+ ts: [
31
+ // The engine client the local dev script wait-for-*-db.ts imports.
32
+ {
33
+ name: 'mariadb',
34
+ when: (m)=>m.engine === 'mysql',
35
+ root: true
36
+ },
37
+ {
38
+ name: 'pg',
39
+ when: isPostgres,
40
+ root: true
41
+ },
42
+ {
43
+ name: '@types/pg',
44
+ when: isPostgres,
45
+ dev: true,
46
+ root: true
47
+ },
48
+ // Added by the helpers that own the projects they belong to.
49
+ ...ownedElsewhere(FS_DEPENDENCIES),
50
+ ...ownedElsewhere(DOCKER_DEPENDENCIES),
51
+ ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),
52
+ ...ownedElsewhere(SHARED_RDB_SCRIPTS_DEPENDENCIES)
53
+ ],
54
+ py: [
55
+ {
56
+ name: 'sqlmodel'
57
+ },
58
+ {
59
+ name: 'alembic'
60
+ },
61
+ // SQLAlchemy's async engine (used by connection.py for both engines)
62
+ // requires greenlet at runtime. Vend it explicitly at a pinned version so
63
+ // the dependency graph is fully determined and doesn't float to an
64
+ // unpublished-wheel release at install time.
65
+ {
66
+ name: 'greenlet'
67
+ },
68
+ {
69
+ name: 'aiomysql',
70
+ when: (m)=>m.engine === 'mysql'
71
+ },
72
+ {
73
+ name: 'asyncpg',
74
+ when: (m)=>m.engine !== 'mysql'
75
+ },
76
+ {
77
+ name: 'boto3'
78
+ },
79
+ {
80
+ name: 'aws-lambda-powertools'
81
+ }
82
+ ]
83
+ });
26
84
  export const PY_RDB_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
27
85
  export const pyRdbGenerator = async (tree, options)=>{
28
86
  const nameClassName = toClassName(options.name);
@@ -44,6 +102,17 @@ export const pyRdbGenerator = async (tree, options)=>{
44
102
  }
45
103
  const projectConfig = readProjectConfiguration(tree, fullyQualifiedName);
46
104
  const { engine } = options;
105
+ // Recorded in the metadata below so the version sync can tell a CDK project
106
+ // from a Terraform one; undefined when no infrastructure was generated.
107
+ const iac = options.infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;
108
+ // Recorded below and read by the declaration's predicates, so the packages
109
+ // added here are exactly the ones the version sync will own.
110
+ const metadata = {
111
+ engine,
112
+ ...iac ? {
113
+ iac
114
+ } : {}
115
+ };
47
116
  const localDbPort = assignPort(tree, projectConfig, engine === 'mysql' ? 3306 : 5432);
48
117
  const localDbHost = 'localhost';
49
118
  const localDbUser = engine === 'mysql' ? 'root' : 'dbadmin';
@@ -70,15 +139,9 @@ export const pyRdbGenerator = async (tree, options)=>{
70
139
  awsLambdaPowertoolsVersion: PY_VERSIONS['aws-lambda-powertools']
71
140
  };
72
141
  generateFiles(tree, joinPathFragments(import.meta.dirname, 'files'), dir, templateOptions);
73
- await sharedRdbScriptsGenerator(tree, engine);
74
- // Used by local dev script wait-for-*-db.ts
75
- addDependenciesToPackageJson(tree, withVersions([
76
- engine === 'mysql' ? 'mariadb' : 'pg'
77
- ]), engine === 'mysql' ? {} : withVersions([
78
- '@types/pg'
79
- ]));
142
+ await sharedRdbScriptsGenerator(tree, engine, DEPENDENCIES);
80
143
  const scriptsDir = relative(dir, joinPathFragments(PACKAGES_DIR, SHARED_SCRIPTS_DIR, 'src', 'rdb'));
81
- const fs = new FsCommands(tree);
144
+ const fs = new FsCommands(tree, DEPENDENCIES);
82
145
  const migrationBundleDir = joinPathFragments('dist', projectConfig.root, 'docker', 'migration');
83
146
  const createDbUserBundleDir = joinPathFragments('dist', projectConfig.root, 'docker', 'create-db-user');
84
147
  const migrationDockerImageTag = `${getNpmScope(tree)}-${kebabCase(options.name)}-migration:latest`;
@@ -187,7 +250,6 @@ export const pyRdbGenerator = async (tree, options)=>{
187
250
  }
188
251
  };
189
252
  if (options.infra !== 'none') {
190
- const iac = await resolveIac(tree, options.iac);
191
253
  if (iac === 'terraform') {
192
254
  projectConfig.targets.docker = {
193
255
  cache: true,
@@ -214,20 +276,17 @@ export const pyRdbGenerator = async (tree, options)=>{
214
276
  migrationDockerImageTag,
215
277
  createDbUserDockerImageTag
216
278
  ]
217
- });
279
+ }, DEPENDENCIES);
218
280
  }
219
281
  addDependencyToTargetIfNotPresent(projectConfig, 'build', 'bundle-migration');
220
282
  addDependencyToTargetIfNotPresent(projectConfig, 'build', 'bundle-create-db-user');
221
283
  }
222
284
  updateProjectConfiguration(tree, fullyQualifiedName, projectConfig);
223
- addGeneratorMetadata(tree, fullyQualifiedName, PY_RDB_GENERATOR_INFO, {
224
- engine
225
- });
285
+ addGeneratorMetadata(tree, fullyQualifiedName, PY_RDB_GENERATOR_INFO, metadata);
226
286
  if (options.infra !== 'none') {
227
- const iac = await resolveIac(tree, options.iac);
228
287
  await sharedConstructsGenerator(tree, {
229
288
  iac
230
- });
289
+ }, DEPENDENCIES);
231
290
  await addRdbInfra(tree, {
232
291
  iac,
233
292
  projectName: fullyQualifiedName,
@@ -246,24 +305,13 @@ export const pyRdbGenerator = async (tree, options)=>{
246
305
  containerEngine
247
306
  });
248
307
  }
249
- addDependenciesToPyProjectToml(tree, dir, [
250
- 'sqlmodel',
251
- 'alembic',
252
- // SQLAlchemy's async engine (used by connection.py for both engines)
253
- // requires greenlet at runtime. Vend it explicitly at a pinned version so
254
- // the dependency graph is fully determined and doesn't float to an
255
- // unpublished-wheel release at install time.
256
- 'greenlet',
257
- ...engine === 'mysql' ? [
258
- 'aiomysql',
259
- 'boto3',
260
- 'aws-lambda-powertools'
261
- ] : [
262
- 'asyncpg',
263
- 'boto3',
264
- 'aws-lambda-powertools'
265
- ]
266
- ]);
308
+ addPyDependencies(tree, DEPENDENCIES, {
309
+ metadata,
310
+ projectRoot: dir
311
+ });
312
+ addTsDependencies(tree, DEPENDENCIES, {
313
+ metadata
314
+ });
267
315
  await addGeneratorMetricsIfApplicable(tree, [
268
316
  PY_RDB_GENERATOR_INFO
269
317
  ]);