@aws/nx-plugin 1.0.0-rc.44 → 1.0.0-rc.46

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 (81) hide show
  1. package/generators.json +13 -7
  2. package/package.json +1 -1
  3. package/src/agentcore-gateway/files/cedar/policies/README.md +9 -0
  4. package/src/agentcore-gateway/files/cedar/policies/permit-all.cedar +15 -0
  5. package/src/agentcore-gateway/generator.js +12 -5
  6. package/src/agentcore-gateway/generator.js.map +1 -1
  7. package/src/agentcore-gateway/schema.d.js.map +1 -1
  8. package/src/agentcore-gateway/schema.d.ts +1 -1
  9. package/src/agentcore-gateway/schema.json +3 -2
  10. package/src/mcp-server/tools/general-guidance.js +1 -1
  11. package/src/mcp-server/tools/general-guidance.js.map +1 -1
  12. package/src/preset/__snapshots__/generator.spec.ts.snap +5 -2
  13. package/src/py/agent/gateway-connection/generator.js +1 -1
  14. package/src/py/agent/gateway-connection/generator.js.map +1 -1
  15. package/src/py/rdb/__snapshots__/generator.spec.ts.snap +17 -0
  16. package/src/py/rdb/files/Dockerfile.create-db-user.template +4 -0
  17. package/src/py/rdb/files/Dockerfile.migration.template +4 -0
  18. package/src/py/rdb/generator.js +5 -0
  19. package/src/py/rdb/generator.js.map +1 -1
  20. package/src/sdk/ts.d.ts +2 -0
  21. package/src/sdk/ts.js +2 -0
  22. package/src/sdk/ts.js.map +1 -1
  23. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +5 -1
  24. package/src/ts/agent/files/deploy/Dockerfile.template +5 -1
  25. package/src/ts/agent/gateway-connection/generator.js +1 -1
  26. package/src/ts/agent/gateway-connection/generator.js.map +1 -1
  27. package/src/ts/agent/generator.js +6 -0
  28. package/src/ts/agent/generator.js.map +1 -1
  29. package/src/ts/dcr-proxy/__snapshots__/generator.spec.ts.snap +982 -0
  30. package/src/ts/dcr-proxy/generator.d.ts +10 -0
  31. package/src/ts/dcr-proxy/generator.js +98 -0
  32. package/src/ts/dcr-proxy/generator.js.map +1 -0
  33. package/src/ts/dcr-proxy/schema.d.js +6 -0
  34. package/src/ts/dcr-proxy/schema.d.js.map +1 -0
  35. package/src/ts/dcr-proxy/schema.d.ts +13 -0
  36. package/src/ts/dcr-proxy/schema.json +44 -0
  37. package/src/ts/mcp-server/files/Dockerfile.template +5 -1
  38. package/src/ts/mcp-server/generator.js +1 -0
  39. package/src/ts/mcp-server/generator.js.map +1 -1
  40. package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +2 -2
  41. package/src/ts/nx-plugin/files/mcp-server/resources/GENERAL_GUIDANCE.md.template +1 -1
  42. package/src/ts/nx-plugin/files/mcp-server/utils.ts.template +1 -1
  43. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +7 -0
  44. package/src/ts/rdb/files/Dockerfile.template +7 -0
  45. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +13 -4
  46. package/src/ts/react-website/cognito-auth/__snapshots__/generator.spec.ts.snap +11 -6
  47. package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +12 -2
  48. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +1 -0
  49. package/src/utils/agent-core-constructs/agent-core-constructs.js +2 -0
  50. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  51. package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +38 -3
  52. package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +13 -3
  53. package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +22 -1
  54. package/src/utils/commands.js +1 -1
  55. package/src/utils/commands.js.map +1 -1
  56. package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.d.ts +38 -0
  57. package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js +93 -0
  58. package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js.map +1 -0
  59. package/src/utils/dcr-proxy-constructs/files/cdk/app/dcr-proxies/__nameKebabCase__/__nameKebabCase__.ts.template +227 -0
  60. package/src/utils/dcr-proxy-constructs/files/project/src/handlers/authorization-server-metadata.ts.template +39 -0
  61. package/src/utils/dcr-proxy-constructs/files/project/src/handlers/authorize.ts.template +26 -0
  62. package/src/utils/dcr-proxy-constructs/files/project/src/handlers/mcp-proxy.ts.template +89 -0
  63. package/src/utils/dcr-proxy-constructs/files/project/src/handlers/protected-resource-metadata.ts.template +13 -0
  64. package/src/utils/dcr-proxy-constructs/files/project/src/handlers/register.ts.template +70 -0
  65. package/src/utils/dcr-proxy-constructs/files/project/src/handlers/token.ts.template +75 -0
  66. package/src/utils/dcr-proxy-constructs/files/terraform/app/dcr-proxies/__nameKebabCase__/__nameKebabCase__.tf.template +410 -0
  67. package/src/utils/docker.d.ts +4 -3
  68. package/src/utils/docker.js +11 -7
  69. package/src/utils/docker.js.map +1 -1
  70. package/src/utils/format.d.ts +1 -1
  71. package/src/utils/format.js +3 -2
  72. package/src/utils/format.js.map +1 -1
  73. package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +11 -6
  74. package/src/utils/identity-constructs/identity-constructs.js +14 -3
  75. package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
  76. package/src/utils/init.js +4 -0
  77. package/src/utils/init.js.map +1 -1
  78. package/src/utils/versions.d.ts +4 -1
  79. package/src/utils/versions.js +9 -1
  80. package/src/utils/versions.js.map +1 -1
  81. package/src/utils/website-constructs/files/cdk/core/static-website.ts.template +3 -0
package/generators.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "factory": "./src/init/generator",
8
8
  "schema": "./src/init/schema.json",
9
9
  "description": "Configure an existing Nx workspace to use the @aws/nx-plugin",
10
- "metric": "g57",
10
+ "metric": "g66",
11
11
  "guidePages": ["existing-project"]
12
12
  },
13
13
  "agentcore-gateway": {
@@ -27,7 +27,7 @@
27
27
  "factory": "./src/agentcore-gateway/gateway-connection/generator",
28
28
  "schema": "./src/agentcore-gateway/gateway-connection/schema.json",
29
29
  "description": "Connect an AgentCore Gateway to another AgentCore Gateway",
30
- "metric": "g52",
30
+ "metric": "g65",
31
31
  "hidden": true
32
32
  },
33
33
  "connection": {
@@ -211,6 +211,12 @@
211
211
  "description": "Generate a TypeScript lambda function",
212
212
  "metric": "g21"
213
213
  },
214
+ "ts#dcr-proxy": {
215
+ "factory": "./src/ts/dcr-proxy/generator",
216
+ "schema": "./src/ts/dcr-proxy/schema.json",
217
+ "description": "Generate an OAuth Dynamic Client Registration (DCR) proxy construct for Cognito-authenticated MCP servers",
218
+ "metric": "g67"
219
+ },
214
220
  "ts#mcp-server": {
215
221
  "factory": "./src/ts/mcp-server/generator",
216
222
  "schema": "./src/ts/mcp-server/schema.json",
@@ -242,7 +248,7 @@
242
248
  "factory": "./src/ts/website/app/generator",
243
249
  "schema": "./src/ts/website/app/schema.json",
244
250
  "description": "Generates a website application",
245
- "metric": "g43",
251
+ "metric": "g60",
246
252
  "guidePages": ["website", "react-website"]
247
253
  },
248
254
  "ts#website#auth": {
@@ -399,27 +405,27 @@
399
405
  "factory": "./src/ts/dynamodb/generator",
400
406
  "schema": "./src/ts/dynamodb/schema.json",
401
407
  "description": "Create a TypeScript DynamoDB project",
402
- "metric": "g43"
408
+ "metric": "g61"
403
409
  },
404
410
  "ts#dynamodb#trpc-connection": {
405
411
  "factory": "./src/ts/dynamodb/trpc-connection/generator",
406
412
  "schema": "./src/ts/dynamodb/trpc-connection/schema.json",
407
413
  "description": "Connect a ts#trpc-api project to a ts#dynamodb project",
408
- "metric": "g44",
414
+ "metric": "g62",
409
415
  "hidden": true
410
416
  },
411
417
  "ts#dynamodb#smithy-connection": {
412
418
  "factory": "./src/ts/dynamodb/smithy-connection/generator",
413
419
  "schema": "./src/ts/dynamodb/smithy-connection/schema.json",
414
420
  "description": "Connect a Smithy backend to a ts#dynamodb project",
415
- "metric": "g45",
421
+ "metric": "g63",
416
422
  "hidden": true
417
423
  },
418
424
  "ts#dynamodb#agent-connection": {
419
425
  "factory": "./src/ts/dynamodb/agent-connection/generator",
420
426
  "schema": "./src/ts/dynamodb/agent-connection/schema.json",
421
427
  "description": "Connect a ts#agent to a ts#dynamodb project",
422
- "metric": "g46",
428
+ "metric": "g64",
423
429
  "hidden": true
424
430
  },
425
431
  "ts#dynamodb#mcp-server-connection": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws/nx-plugin",
3
- "version": "1.0.0-rc.44",
3
+ "version": "1.0.0-rc.46",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/awslabs/nx-plugin-for-aws.git",
@@ -7,10 +7,19 @@ runtime.
7
7
 
8
8
  ## Default policy
9
9
 
10
+ <%_ if (auth === 'cognito') { _%>
11
+ `permit-all.cedar` permits any Cognito-authenticated caller
12
+ (`principal is AgentCore::OAuthUser`). The gateway's JWT authorizer already
13
+ validates the token's user pool and client before policies are evaluated, so
14
+ any principal that reaches the engine is an authenticated OAuth user. Tighten
15
+ this by matching JWT claims (e.g. `principal.scope`) — see the
16
+ [AgentCore common policy patterns](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/policy-common-patterns.html).
17
+ <%_ } else { _%>
10
18
  `permit-all.cedar` permits any IAM caller from the deploying AWS account.
11
19
  It is scoped to your account because AgentCore's policy validator rejects
12
20
  truly unrestricted permits (`permit (principal, action, resource)`) as
13
21
  "Overly Permissive".
22
+ <%_ } _%>
14
23
 
15
24
  **If you delete this file without adding replacement `permit` policies, the
16
25
  gateway will deny every request** — Cedar uses a default-deny evaluation
@@ -1,3 +1,17 @@
1
+ <%_ if (auth === 'cognito') { _%>
2
+ // Default policy: permit any Cognito-authenticated caller.
3
+ // The gateway's JWT authorizer already validates the token's user pool and
4
+ // client, so any principal reaching policy evaluation is an authenticated
5
+ // OAuth user. The PolicyEngine runs in ENFORCE mode (default-deny) — deleting
6
+ // this file without a replacement permit denies every call. See
7
+ // policies/README.md.
8
+
9
+ permit (
10
+ principal is AgentCore::OAuthUser,
11
+ action,
12
+ resource == AgentCore::Gateway::"<%%= gatewayArn %>"
13
+ );
14
+ <%_ } else { _%>
1
15
  // Default policy: permit any IAM caller from the deploying AWS account.
2
16
  // The PolicyEngine runs in ENFORCE mode (default-deny) — deleting this file
3
17
  // without a replacement permit denies every call. See policies/README.md.
@@ -9,3 +23,4 @@ permit (
9
23
  ) when {
10
24
  principal.id like "arn:aws:*::<%%= accountId %>:*"
11
25
  };
26
+ <%_ } _%>
@@ -21,11 +21,13 @@ export const agentcoreGatewayGenerator = async (tree, options)=>{
21
21
  const subDir = options.subDirectory ?? name;
22
22
  const projectRoot = joinPathFragments(parentDir, subDir);
23
23
  const fullyQualifiedName = `${getNpmScopePrefix(tree)}${name}`;
24
- // Protocol / auth are fixed to mcp / iam in v1 the enums accept only
25
- // these values, but we still persist the resolved value in metadata so
26
- // that connection generators can read it uniformly (and future additions
27
- // are non-breaking).
24
+ // Protocol is fixed to mcp the enum accepts only this value, but we still
25
+ // persist the resolved value in metadata so connection generators can read
26
+ // it uniformly (and future additions are non-breaking).
28
27
  const protocol = options.protocol ?? 'mcp';
28
+ // Inbound auth is iam (default) or cognito. Persisted in metadata so
29
+ // connection generators can validate it (agent -> gateway connections
30
+ // require an IAM gateway).
29
31
  const auth = options.auth ?? 'iam';
30
32
  const cedarPolicy = options.cedarPolicy ?? true;
31
33
  const infra = options.infra ?? 'agentcore';
@@ -84,8 +86,12 @@ export const agentcoreGatewayGenerator = async (tree, options)=>{
84
86
  overwriteStrategy: OverwriteStrategy.KeepExisting
85
87
  });
86
88
  if (cedarPolicy) {
89
+ // The default permit-all policy differs by auth type: AgentCore represents
90
+ // IAM callers as `AgentCore::IamEntity` and Cognito/JWT callers as
91
+ // `AgentCore::OAuthUser`, so the two policies match different principals.
87
92
  generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'cedar'), projectRoot, {
88
- nameClassName
93
+ nameClassName,
94
+ auth
89
95
  }, {
90
96
  overwriteStrategy: OverwriteStrategy.KeepExisting
91
97
  });
@@ -121,6 +127,7 @@ export const agentcoreGatewayGenerator = async (tree, options)=>{
121
127
  projectName: fullyQualifiedName,
122
128
  projectDirectory: projectRoot,
123
129
  cedarPolicy,
130
+ auth,
124
131
  iac
125
132
  });
126
133
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../packages/nx-plugin/src/agentcore-gateway/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addDependenciesToPackageJson,\n addProjectConfiguration,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addAgentCoreGatewayInfra } from '../utils/agent-core-constructs/agent-core-constructs';\nimport { formatFilesInSubtree } from '../utils/format';\nimport { resolveIac } from '../utils/iac';\nimport { installDependencies } from '../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../utils/metrics';\nimport { kebabCase, toClassName } from '../utils/names';\nimport { getNpmScopePrefix } from '../utils/npm-scope';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n readProjectConfigurationUnqualified,\n} from '../utils/nx';\nimport { assignPort } from '../utils/port';\nimport { sharedConstructsGenerator } from '../utils/shared-constructs';\nimport { withVersions } from '../utils/versions';\nimport type { AgentcoreGatewayGeneratorSchema } from './schema';\n\nexport const AGENTCORE_GATEWAY_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const agentcoreGatewayGenerator = async (\n tree: Tree,\n options: AgentcoreGatewayGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const name = kebabCase(options.name);\n const nameClassName = toClassName(name);\n const parentDir = options.directory ?? 'packages';\n const subDir = options.subDirectory ?? name;\n const projectRoot = joinPathFragments(parentDir, subDir);\n const fullyQualifiedName = `${getNpmScopePrefix(tree)}${name}`;\n\n // Protocol / auth are fixed to mcp / iam in v1 — the enums accept only\n // these values, but we still persist the resolved value in metadata so\n // that connection generators can read it uniformly (and future additions\n // are non-breaking).\n const protocol = options.protocol ?? 'mcp';\n const auth = options.auth ?? 'iam';\n const cedarPolicy = options.cedarPolicy ?? true;\n const infra = options.infra ?? 'agentcore';\n\n // local-dev.ts is the local gateway: a continuous MCP aggregator chaining\n // onto attached MCP servers' dev targets (added by the mcp-connection\n // generator), so a single `nx dev <gateway>` boots the gateway and every\n // attached MCP server together.\n //\n // `serve` exists for parity with other generators; the deployed Gateway is\n // a managed AWS resource, so `serve`-mode agents talk to it via runtime\n // config and the local gateway sits idle.\n const localGatewayTarget = (port: number) => ({\n executor: 'nx:run-commands' as const,\n continuous: true,\n options: {\n command: 'tsx local-dev.ts',\n cwd: '{projectRoot}',\n env: { PORT: `${port}` },\n },\n dependsOn: [] as Array<string | { projects: string[]; target: string }>,\n });\n let project: ProjectConfiguration;\n if (projectExists(tree, fullyQualifiedName)) {\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n } else {\n addProjectConfiguration(tree, fullyQualifiedName, {\n name: fullyQualifiedName,\n root: projectRoot,\n projectType: 'library',\n sourceRoot: projectRoot,\n tags: [],\n targets: {},\n metadata: {\n generator: AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n } as any,\n });\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n }\n const port = assignPort(tree, project, 8100);\n // A gateway is its own standalone project, so it uses plain `serve` / `dev`\n // targets. Re-run: keep existing targets (their dependsOn may have been\n // populated by the mcp-connection generator), just ensure both exist.\n project.targets ??= {};\n project.targets['serve'] ??= localGatewayTarget(port);\n project.targets['dev'] ??= localGatewayTarget(port);\n updateProjectConfiguration(tree, project.name, project);\n\n // Scaffold the gateway project: local-dev.ts (+ Cedar policies if requested)\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'project'),\n projectRoot,\n { nameClassName, nameKebabCase: name, port, attachedMcpServers: [] },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n if (cedarPolicy) {\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cedar'),\n projectRoot,\n { nameClassName },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n }\n\n addGeneratorMetadata(\n tree,\n fullyQualifiedName,\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n {\n name,\n rc: nameClassName,\n protocol,\n auth,\n port,\n },\n );\n\n // local-dev.ts dependencies (+ ejs for Cedar policy rendering in the\n // shared gateway construct)\n addDependenciesToPackageJson(\n tree,\n withVersions(['@modelcontextprotocol/sdk', 'express']),\n withVersions(['tsx', '@types/express', 'ejs', '@types/ejs']),\n );\n\n // Wire up infra (CDK or Terraform); re-running with infra=agentcore adds\n // the infrastructure to a previously infra-less gateway.\n if (infra === 'agentcore') {\n const iac = await resolveIac(tree, options.iac);\n await sharedConstructsGenerator(tree, { iac });\n\n await addAgentCoreGatewayInfra(tree, {\n gatewayNameClassName: nameClassName,\n gatewayNameKebabCase: name,\n projectName: fullyQualifiedName,\n projectDirectory: projectRoot,\n cedarPolicy,\n iac,\n });\n }\n\n await addGeneratorMetricsIfApplicable(tree, [\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n ]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\n/**\n * Gateway details stored in the gateway project's metadata.\n */\nexport interface AgentCoreGatewayMetadata {\n name: string;\n rc: string;\n protocol: string;\n auth: string;\n port: number;\n}\n\n/**\n * Read a gateway project's metadata, validating it was generated by the\n * agentcore-gateway generator.\n */\nexport const readAgentCoreGatewayMetadata = (\n project: ProjectConfiguration,\n): AgentCoreGatewayMetadata => {\n const metadata = project.metadata as any;\n if (metadata?.generator !== AGENTCORE_GATEWAY_GENERATOR_INFO.id) {\n throw new Error(\n `Project '${project.name}' was not generated by the '${AGENTCORE_GATEWAY_GENERATOR_INFO.id}' generator.`,\n );\n }\n return metadata as AgentCoreGatewayMetadata;\n};\n\nexport default agentcoreGatewayGenerator;\n"],"names":["addDependenciesToPackageJson","addProjectConfiguration","generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","addAgentCoreGatewayInfra","formatFilesInSubtree","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","getNpmScopePrefix","addGeneratorMetadata","getGeneratorInfo","projectExists","readProjectConfigurationUnqualified","assignPort","sharedConstructsGenerator","withVersions","AGENTCORE_GATEWAY_GENERATOR_INFO","filename","agentcoreGatewayGenerator","tree","options","name","nameClassName","parentDir","directory","subDir","subDirectory","projectRoot","fullyQualifiedName","protocol","auth","cedarPolicy","infra","localGatewayTarget","port","executor","continuous","command","cwd","env","PORT","dependsOn","project","root","projectType","sourceRoot","tags","targets","metadata","generator","id","dirname","nameKebabCase","attachedMcpServers","overwriteStrategy","KeepExisting","rc","iac","gatewayNameClassName","gatewayNameKebabCase","projectName","projectDirectory","preferInstallDependencies","languages","readAgentCoreGatewayMetadata","Error"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../packages/nx-plugin/src/agentcore-gateway/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addDependenciesToPackageJson,\n addProjectConfiguration,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addAgentCoreGatewayInfra } from '../utils/agent-core-constructs/agent-core-constructs';\nimport { formatFilesInSubtree } from '../utils/format';\nimport { resolveIac } from '../utils/iac';\nimport { installDependencies } from '../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../utils/metrics';\nimport { kebabCase, toClassName } from '../utils/names';\nimport { getNpmScopePrefix } from '../utils/npm-scope';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n readProjectConfigurationUnqualified,\n} from '../utils/nx';\nimport { assignPort } from '../utils/port';\nimport { sharedConstructsGenerator } from '../utils/shared-constructs';\nimport { withVersions } from '../utils/versions';\nimport type { AgentcoreGatewayGeneratorSchema } from './schema';\n\nexport const AGENTCORE_GATEWAY_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const agentcoreGatewayGenerator = async (\n tree: Tree,\n options: AgentcoreGatewayGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const name = kebabCase(options.name);\n const nameClassName = toClassName(name);\n const parentDir = options.directory ?? 'packages';\n const subDir = options.subDirectory ?? name;\n const projectRoot = joinPathFragments(parentDir, subDir);\n const fullyQualifiedName = `${getNpmScopePrefix(tree)}${name}`;\n\n // Protocol is fixed to mcp — the enum accepts only this value, but we still\n // persist the resolved value in metadata so connection generators can read\n // it uniformly (and future additions are non-breaking).\n const protocol = options.protocol ?? 'mcp';\n // Inbound auth is iam (default) or cognito. Persisted in metadata so\n // connection generators can validate it (agent -> gateway connections\n // require an IAM gateway).\n const auth = options.auth ?? 'iam';\n const cedarPolicy = options.cedarPolicy ?? true;\n const infra = options.infra ?? 'agentcore';\n\n // local-dev.ts is the local gateway: a continuous MCP aggregator chaining\n // onto attached MCP servers' dev targets (added by the mcp-connection\n // generator), so a single `nx dev <gateway>` boots the gateway and every\n // attached MCP server together.\n //\n // `serve` exists for parity with other generators; the deployed Gateway is\n // a managed AWS resource, so `serve`-mode agents talk to it via runtime\n // config and the local gateway sits idle.\n const localGatewayTarget = (port: number) => ({\n executor: 'nx:run-commands' as const,\n continuous: true,\n options: {\n command: 'tsx local-dev.ts',\n cwd: '{projectRoot}',\n env: { PORT: `${port}` },\n },\n dependsOn: [] as Array<string | { projects: string[]; target: string }>,\n });\n let project: ProjectConfiguration;\n if (projectExists(tree, fullyQualifiedName)) {\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n } else {\n addProjectConfiguration(tree, fullyQualifiedName, {\n name: fullyQualifiedName,\n root: projectRoot,\n projectType: 'library',\n sourceRoot: projectRoot,\n tags: [],\n targets: {},\n metadata: {\n generator: AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n } as any,\n });\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n }\n const port = assignPort(tree, project, 8100);\n // A gateway is its own standalone project, so it uses plain `serve` / `dev`\n // targets. Re-run: keep existing targets (their dependsOn may have been\n // populated by the mcp-connection generator), just ensure both exist.\n project.targets ??= {};\n project.targets['serve'] ??= localGatewayTarget(port);\n project.targets['dev'] ??= localGatewayTarget(port);\n updateProjectConfiguration(tree, project.name, project);\n\n // Scaffold the gateway project: local-dev.ts (+ Cedar policies if requested)\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'project'),\n projectRoot,\n { nameClassName, nameKebabCase: name, port, attachedMcpServers: [] },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n if (cedarPolicy) {\n // The default permit-all policy differs by auth type: AgentCore represents\n // IAM callers as `AgentCore::IamEntity` and Cognito/JWT callers as\n // `AgentCore::OAuthUser`, so the two policies match different principals.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cedar'),\n projectRoot,\n { nameClassName, auth },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n }\n\n addGeneratorMetadata(\n tree,\n fullyQualifiedName,\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n {\n name,\n rc: nameClassName,\n protocol,\n auth,\n port,\n },\n );\n\n // local-dev.ts dependencies (+ ejs for Cedar policy rendering in the\n // shared gateway construct)\n addDependenciesToPackageJson(\n tree,\n withVersions(['@modelcontextprotocol/sdk', 'express']),\n withVersions(['tsx', '@types/express', 'ejs', '@types/ejs']),\n );\n\n // Wire up infra (CDK or Terraform); re-running with infra=agentcore adds\n // the infrastructure to a previously infra-less gateway.\n if (infra === 'agentcore') {\n const iac = await resolveIac(tree, options.iac);\n await sharedConstructsGenerator(tree, { iac });\n\n await addAgentCoreGatewayInfra(tree, {\n gatewayNameClassName: nameClassName,\n gatewayNameKebabCase: name,\n projectName: fullyQualifiedName,\n projectDirectory: projectRoot,\n cedarPolicy,\n auth,\n iac,\n });\n }\n\n await addGeneratorMetricsIfApplicable(tree, [\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n ]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\n/**\n * Gateway details stored in the gateway project's metadata.\n */\nexport interface AgentCoreGatewayMetadata {\n name: string;\n rc: string;\n protocol: string;\n auth: string;\n port: number;\n}\n\n/**\n * Read a gateway project's metadata, validating it was generated by the\n * agentcore-gateway generator.\n */\nexport const readAgentCoreGatewayMetadata = (\n project: ProjectConfiguration,\n): AgentCoreGatewayMetadata => {\n const metadata = project.metadata as any;\n if (metadata?.generator !== AGENTCORE_GATEWAY_GENERATOR_INFO.id) {\n throw new Error(\n `Project '${project.name}' was not generated by the '${AGENTCORE_GATEWAY_GENERATOR_INFO.id}' generator.`,\n );\n }\n return metadata as AgentCoreGatewayMetadata;\n};\n\nexport default agentcoreGatewayGenerator;\n"],"names":["addDependenciesToPackageJson","addProjectConfiguration","generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","addAgentCoreGatewayInfra","formatFilesInSubtree","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","getNpmScopePrefix","addGeneratorMetadata","getGeneratorInfo","projectExists","readProjectConfigurationUnqualified","assignPort","sharedConstructsGenerator","withVersions","AGENTCORE_GATEWAY_GENERATOR_INFO","filename","agentcoreGatewayGenerator","tree","options","name","nameClassName","parentDir","directory","subDir","subDirectory","projectRoot","fullyQualifiedName","protocol","auth","cedarPolicy","infra","localGatewayTarget","port","executor","continuous","command","cwd","env","PORT","dependsOn","project","root","projectType","sourceRoot","tags","targets","metadata","generator","id","dirname","nameKebabCase","attachedMcpServers","overwriteStrategy","KeepExisting","rc","iac","gatewayNameClassName","gatewayNameKebabCase","projectName","projectDirectory","preferInstallDependencies","languages","readAgentCoreGatewayMetadata","Error"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../packages/nx-plugin/src/agentcore-gateway/schema.d.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { IacOption } from '../utils/iac';\n\nexport interface AgentcoreGatewayGeneratorSchema {\n name: string;\n directory?: string;\n subDirectory?: string;\n protocol?: 'mcp';\n auth?: 'iam';\n cedarPolicy?: boolean;\n infra?: 'agentcore' | 'none';\n iac: IacOption;\n preferInstallDependencies?: boolean;\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAGD,WAUC"}
1
+ {"version":3,"sources":["../../../../../packages/nx-plugin/src/agentcore-gateway/schema.d.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { IacOption } from '../utils/iac';\n\nexport interface AgentcoreGatewayGeneratorSchema {\n name: string;\n directory?: string;\n subDirectory?: string;\n protocol?: 'mcp';\n auth?: 'iam' | 'cognito';\n cedarPolicy?: boolean;\n infra?: 'agentcore' | 'none';\n iac: IacOption;\n preferInstallDependencies?: boolean;\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAGD,WAUC"}
@@ -9,7 +9,7 @@ export interface AgentcoreGatewayGeneratorSchema {
9
9
  directory?: string;
10
10
  subDirectory?: string;
11
11
  protocol?: 'mcp';
12
- auth?: 'iam';
12
+ auth?: 'iam' | 'cognito';
13
13
  cedarPolicy?: boolean;
14
14
  infra?: 'agentcore' | 'none';
15
15
  iac: IacOption;
@@ -33,9 +33,10 @@
33
33
  },
34
34
  "auth": {
35
35
  "type": "string",
36
- "description": "The method used to authenticate inbound requests to your gateway. Only iam is supported today; cognito and custom-jwt may be added in future.",
37
- "enum": ["iam"],
36
+ "description": "The method used to authenticate inbound requests to your gateway. Only applicable when infra is set (ignored when infra is none).",
37
+ "enum": ["iam", "cognito"],
38
38
  "default": "iam",
39
+ "x-prompt": "How would you like to authenticate inbound requests to your gateway?",
39
40
  "x-priority": "important"
40
41
  },
41
42
  "cedarPolicy": {
@@ -46,7 +46,7 @@ ${PACKAGE_MANAGERS.map((pm)=>buildNxCommand('<options>', pm)).join(' - \n')}
46
46
  - pnpm add -w -D <package>
47
47
  - yarn add -D <package>
48
48
  - npm install --legacy-peer-deps -D <package>
49
- - bun install -D <package>
49
+ - bun add -D <package>
50
50
  - (Omit -D for production dependencies)
51
51
  - When specifying project names as arguments to generators, prefer the _fully qualified_ project name, for example \`@workspace-name/project-name\`. Check the \`project.json\` file for the specific package to find its fully qualified name
52
52
  - When no generator exists for a specific framework required, use the base \`ts#project\` and \`py#project\` generators and build on top.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/general-guidance.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { NxGeneratorInfo } from '../../utils/generators';\nimport { IAC_PROVIDERS } from '../../utils/iac-providers';\nimport { buildNxCommand, fetchGuidePages } from '../generator-info';\nimport { PACKAGE_MANAGERS } from '../schema';\n\nexport const TOOL_SELECTION_GUIDE = `## Tool Selection Guide\n\n- Use the \\`general-guidance\\` tool for guidance and best practices for working with Nx and the Nx Plugin for AWS.\n- Use the \\`create-workspace-command\\` tool to discover how to create a workspace to start a new project.\n- Use the \\`add-to-existing-project\\` tool when adding the plugin to an existing Nx workspace or non-Nx monorepo, or when troubleshooting configuration errors in such a workspace.\n- Use the \\`list-generators\\` tool to discover the available generators and how to run them.\n- Use the \\`generator-guide\\` tool to retrieve detailed information about a specific generator.`;\n\n/**\n * Add a tool which provides general guidance for using Nx and the Nx Plugin for AWS\n */\nexport const addGeneralGuidanceTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'general-guidance',\n {\n title: 'General Guidance',\n description:\n 'Tool for guidance and best practices for working with Nx and the Nx Plugin for AWS',\n },\n async () => ({\n content: [\n {\n type: 'text' as const,\n text: `# Nx Plugin for AWS Guidance\n\n${TOOL_SELECTION_GUIDE}\n\n## Getting Started\n\n- Choose a package manager first. You can choose between ${PACKAGE_MANAGERS.join(', ')}. It's recommended to use \"pnpm\" if the user has no preference\n- Choose an infrastructure as code (IaC) provider next. You can choose between ${IAC_PROVIDERS.join(', ')}. It's recommended to use CDK if the user has no preference\n- Next, you must create an Nx workspace. Use the \\`create-workspace-command\\` tool for more details, and provide it with your chosen package manager\n- After this, you can start scaffolding the main components of your application using generators. Use the \\`list-generators\\` tool to discover available generators, and the \\`generator-guide\\` tool for more detailed information about a specific generator\n\n## Nx Primer\n\n- Prefix nx commands with the appropriate prefix for your package manager, for example:\n${PACKAGE_MANAGERS.map((pm) => buildNxCommand('<options>', pm)).join(' - \\n')}\n- Each project in your workspace has a file named \\`project.json\\` which contains important project information such as its name, and defines the \"targets\" which can be run for that project, for example building or testing the project\n- Use the command \\`nx reset\\` to reset the Nx daemon when unexpected issues arise\n- After adding dependencies between TypeScript projects, use \\`nx sync\\` to ensure project references are set up correctly\n\n## General Instructions\n\n- Workspaces contain a single \\`package.json\\` file at the root which defines the dependencies for all projects. Therefore when installing dependencies, you must add these to the root workspace using the appropriate command for your package manager:\n - pnpm add -w -D <package>\n - yarn add -D <package>\n - npm install --legacy-peer-deps -D <package>\n - bun install -D <package>\n - (Omit -D for production dependencies)\n- When specifying project names as arguments to generators, prefer the _fully qualified_ project name, for example \\`@workspace-name/project-name\\`. Check the \\`project.json\\` file for the specific package to find its fully qualified name\n- When no generator exists for a specific framework required, use the base \\`ts#project\\` and \\`py#project\\` generators and build on top.\n- Leave the \\`--infra\\` option at its default value unless the user has explicitly instructed otherwise. Generators choose a sensible default type of infrastructure to deploy the project with, so only override \\`--infra\\` when the user has specified a particular requirement.\n\n## Useful Commands\n\n- Fix lint issues with \\`nx run-many --target lint --configuration=fix --all --output-style=stream\\`\n- Build all projects with \\`nx run-many --target build --all --output-style=stream\\`\n- Prefer importing the CDK constructs vended by generators in \\`packages/common/constructs\\` over writing your own\n\n## Best Practices\n\n- After running a generator, use the \\`nx show projects\\` command to check which projects have been added (if any)\n- Carefully examine the files that have been generated and always refer back to the generator guide when working in a generated project\n- Generate all projects into the \\`packages/\\` directory\n- After making changes to your projects, fix linting issues, then run a full build\n- When it's time to start testing a project, suggest to the user that infrastructure is deployed to AWS. For websites, if a runtime-config.json is needed, use the load:runtime-config target after a deployment to point a local website at a sandbox stack.\n\n## Batching Generators\n\nWhen scaffolding several projects in one go, chain generators to avoid a slow dependency install after every generator:\n\n- **Chain generators** with \\`&&\\` in a single command. Pass \\`--prefer-install-dependencies=false\\` on each generator except the last so dependencies install once at the end, for example:\n\n${PACKAGE_MANAGERS.map(\n (pm) => ` \\`\\`\\`bash\n ${buildNxCommand('g @aws/nx-plugin:ts#trpc-api --no-interactive --name=my-app-api --auth=IAM --prefer-install-dependencies=false', pm)} && \\\\\n ${buildNxCommand('g @aws/nx-plugin:ts#react-website --no-interactive --name=my-app-website --prefer-install-dependencies=false', pm)} && \\\\\n ${buildNxCommand('g @aws/nx-plugin:connection --no-interactive --sourceProject=@my-app/my-app-website --targetProject=@my-app/my-app-api --prefer-install-dependencies=false', pm)} && \\\\\n ${buildNxCommand('g @aws/nx-plugin:ts#infra --no-interactive --name=infra', pm)} && \\\\\n ${buildNxCommand('sync', pm)}\n \\`\\`\\``,\n).join('\\n')}\n\n- **\\`--prefer-install-dependencies=false\\`** asks a generator to defer its dependency install so the batch installs once at the end (the final generator above omits the flag and installs everything).\n- **\\`nx sync\\`** is required before building — generators modify TypeScript project references.\n\n## Detailed Guides\n\nPlease refer to the below documentation for important details regarding workspaces and working with TypeScript or Python projects.\n\n${await fetchGuidePages(['workspace', 'typescript-project', 'python-project'], generators)}\n\n `,\n },\n ],\n }),\n );\n};\n"],"names":["IAC_PROVIDERS","buildNxCommand","fetchGuidePages","PACKAGE_MANAGERS","TOOL_SELECTION_GUIDE","addGeneralGuidanceTool","server","generators","registerTool","title","description","content","type","text","join","map","pm"],"mappings":"AAAA;;;CAGC,GAGD,SAASA,aAAa,QAAQ,+BAA4B;AAC1D,SAASC,cAAc,EAAEC,eAAe,QAAQ,uBAAoB;AACpE,SAASC,gBAAgB,QAAQ,eAAY;AAE7C,OAAO,MAAMC,uBAAuB,CAAC;;;;;;+FAM0D,CAAC,CAAC;AAEjG;;CAEC,GACD,OAAO,MAAMC,yBAAyB,CACpCC,QACAC;IAEAD,OAAOE,YAAY,CACjB,oBACA;QACEC,OAAO;QACPC,aACE;IACJ,GACA,UAAa,CAAA;YACXC,SAAS;gBACP;oBACEC,MAAM;oBACNC,MAAM,CAAC;;AAEjB,EAAET,qBAAqB;;;;yDAIkC,EAAED,iBAAiBW,IAAI,CAAC,MAAM;+EACR,EAAEd,cAAcc,IAAI,CAAC,MAAM;;;;;;;AAO1G,EAAEX,iBAAiBY,GAAG,CAAC,CAACC,KAAOf,eAAe,aAAae,KAAKF,IAAI,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqC9E,EAAEX,iBAAiBY,GAAG,CACpB,CAACC,KAAO,CAAC;EACT,EAAEf,eAAe,kHAAkHe,IAAI;IACrI,EAAEf,eAAe,gHAAgHe,IAAI;IACrI,EAAEf,eAAe,8JAA8Je,IAAI;IACnL,EAAEf,eAAe,2DAA2De,IAAI;IAChF,EAAEf,eAAe,QAAQe,IAAI;QACzB,CAAC,EACPF,IAAI,CAAC,MAAM;;;;;;;;;AASb,EAAE,MAAMZ,gBAAgB;wBAAC;wBAAa;wBAAsB;qBAAiB,EAAEK,YAAY;;IAEvF,CAAC;gBACG;aACD;QACH,CAAA;AAEJ,EAAE"}
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/general-guidance.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { NxGeneratorInfo } from '../../utils/generators';\nimport { IAC_PROVIDERS } from '../../utils/iac-providers';\nimport { buildNxCommand, fetchGuidePages } from '../generator-info';\nimport { PACKAGE_MANAGERS } from '../schema';\n\nexport const TOOL_SELECTION_GUIDE = `## Tool Selection Guide\n\n- Use the \\`general-guidance\\` tool for guidance and best practices for working with Nx and the Nx Plugin for AWS.\n- Use the \\`create-workspace-command\\` tool to discover how to create a workspace to start a new project.\n- Use the \\`add-to-existing-project\\` tool when adding the plugin to an existing Nx workspace or non-Nx monorepo, or when troubleshooting configuration errors in such a workspace.\n- Use the \\`list-generators\\` tool to discover the available generators and how to run them.\n- Use the \\`generator-guide\\` tool to retrieve detailed information about a specific generator.`;\n\n/**\n * Add a tool which provides general guidance for using Nx and the Nx Plugin for AWS\n */\nexport const addGeneralGuidanceTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'general-guidance',\n {\n title: 'General Guidance',\n description:\n 'Tool for guidance and best practices for working with Nx and the Nx Plugin for AWS',\n },\n async () => ({\n content: [\n {\n type: 'text' as const,\n text: `# Nx Plugin for AWS Guidance\n\n${TOOL_SELECTION_GUIDE}\n\n## Getting Started\n\n- Choose a package manager first. You can choose between ${PACKAGE_MANAGERS.join(', ')}. It's recommended to use \"pnpm\" if the user has no preference\n- Choose an infrastructure as code (IaC) provider next. You can choose between ${IAC_PROVIDERS.join(', ')}. It's recommended to use CDK if the user has no preference\n- Next, you must create an Nx workspace. Use the \\`create-workspace-command\\` tool for more details, and provide it with your chosen package manager\n- After this, you can start scaffolding the main components of your application using generators. Use the \\`list-generators\\` tool to discover available generators, and the \\`generator-guide\\` tool for more detailed information about a specific generator\n\n## Nx Primer\n\n- Prefix nx commands with the appropriate prefix for your package manager, for example:\n${PACKAGE_MANAGERS.map((pm) => buildNxCommand('<options>', pm)).join(' - \\n')}\n- Each project in your workspace has a file named \\`project.json\\` which contains important project information such as its name, and defines the \"targets\" which can be run for that project, for example building or testing the project\n- Use the command \\`nx reset\\` to reset the Nx daemon when unexpected issues arise\n- After adding dependencies between TypeScript projects, use \\`nx sync\\` to ensure project references are set up correctly\n\n## General Instructions\n\n- Workspaces contain a single \\`package.json\\` file at the root which defines the dependencies for all projects. Therefore when installing dependencies, you must add these to the root workspace using the appropriate command for your package manager:\n - pnpm add -w -D <package>\n - yarn add -D <package>\n - npm install --legacy-peer-deps -D <package>\n - bun add -D <package>\n - (Omit -D for production dependencies)\n- When specifying project names as arguments to generators, prefer the _fully qualified_ project name, for example \\`@workspace-name/project-name\\`. Check the \\`project.json\\` file for the specific package to find its fully qualified name\n- When no generator exists for a specific framework required, use the base \\`ts#project\\` and \\`py#project\\` generators and build on top.\n- Leave the \\`--infra\\` option at its default value unless the user has explicitly instructed otherwise. Generators choose a sensible default type of infrastructure to deploy the project with, so only override \\`--infra\\` when the user has specified a particular requirement.\n\n## Useful Commands\n\n- Fix lint issues with \\`nx run-many --target lint --configuration=fix --all --output-style=stream\\`\n- Build all projects with \\`nx run-many --target build --all --output-style=stream\\`\n- Prefer importing the CDK constructs vended by generators in \\`packages/common/constructs\\` over writing your own\n\n## Best Practices\n\n- After running a generator, use the \\`nx show projects\\` command to check which projects have been added (if any)\n- Carefully examine the files that have been generated and always refer back to the generator guide when working in a generated project\n- Generate all projects into the \\`packages/\\` directory\n- After making changes to your projects, fix linting issues, then run a full build\n- When it's time to start testing a project, suggest to the user that infrastructure is deployed to AWS. For websites, if a runtime-config.json is needed, use the load:runtime-config target after a deployment to point a local website at a sandbox stack.\n\n## Batching Generators\n\nWhen scaffolding several projects in one go, chain generators to avoid a slow dependency install after every generator:\n\n- **Chain generators** with \\`&&\\` in a single command. Pass \\`--prefer-install-dependencies=false\\` on each generator except the last so dependencies install once at the end, for example:\n\n${PACKAGE_MANAGERS.map(\n (pm) => ` \\`\\`\\`bash\n ${buildNxCommand('g @aws/nx-plugin:ts#trpc-api --no-interactive --name=my-app-api --auth=IAM --prefer-install-dependencies=false', pm)} && \\\\\n ${buildNxCommand('g @aws/nx-plugin:ts#react-website --no-interactive --name=my-app-website --prefer-install-dependencies=false', pm)} && \\\\\n ${buildNxCommand('g @aws/nx-plugin:connection --no-interactive --sourceProject=@my-app/my-app-website --targetProject=@my-app/my-app-api --prefer-install-dependencies=false', pm)} && \\\\\n ${buildNxCommand('g @aws/nx-plugin:ts#infra --no-interactive --name=infra', pm)} && \\\\\n ${buildNxCommand('sync', pm)}\n \\`\\`\\``,\n).join('\\n')}\n\n- **\\`--prefer-install-dependencies=false\\`** asks a generator to defer its dependency install so the batch installs once at the end (the final generator above omits the flag and installs everything).\n- **\\`nx sync\\`** is required before building — generators modify TypeScript project references.\n\n## Detailed Guides\n\nPlease refer to the below documentation for important details regarding workspaces and working with TypeScript or Python projects.\n\n${await fetchGuidePages(['workspace', 'typescript-project', 'python-project'], generators)}\n\n `,\n },\n ],\n }),\n );\n};\n"],"names":["IAC_PROVIDERS","buildNxCommand","fetchGuidePages","PACKAGE_MANAGERS","TOOL_SELECTION_GUIDE","addGeneralGuidanceTool","server","generators","registerTool","title","description","content","type","text","join","map","pm"],"mappings":"AAAA;;;CAGC,GAGD,SAASA,aAAa,QAAQ,+BAA4B;AAC1D,SAASC,cAAc,EAAEC,eAAe,QAAQ,uBAAoB;AACpE,SAASC,gBAAgB,QAAQ,eAAY;AAE7C,OAAO,MAAMC,uBAAuB,CAAC;;;;;;+FAM0D,CAAC,CAAC;AAEjG;;CAEC,GACD,OAAO,MAAMC,yBAAyB,CACpCC,QACAC;IAEAD,OAAOE,YAAY,CACjB,oBACA;QACEC,OAAO;QACPC,aACE;IACJ,GACA,UAAa,CAAA;YACXC,SAAS;gBACP;oBACEC,MAAM;oBACNC,MAAM,CAAC;;AAEjB,EAAET,qBAAqB;;;;yDAIkC,EAAED,iBAAiBW,IAAI,CAAC,MAAM;+EACR,EAAEd,cAAcc,IAAI,CAAC,MAAM;;;;;;;AAO1G,EAAEX,iBAAiBY,GAAG,CAAC,CAACC,KAAOf,eAAe,aAAae,KAAKF,IAAI,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqC9E,EAAEX,iBAAiBY,GAAG,CACpB,CAACC,KAAO,CAAC;EACT,EAAEf,eAAe,kHAAkHe,IAAI;IACrI,EAAEf,eAAe,gHAAgHe,IAAI;IACrI,EAAEf,eAAe,8JAA8Je,IAAI;IACnL,EAAEf,eAAe,2DAA2De,IAAI;IAChF,EAAEf,eAAe,QAAQe,IAAI;QACzB,CAAC,EACPF,IAAI,CAAC,MAAM;;;;;;;;;AASb,EAAE,MAAMZ,gBAAgB;wBAAC;wBAAa;wBAAsB;qBAAiB,EAAEK,YAAY;;IAEvF,CAAC;gBACG;aACD;QACH,CAAA;AAEJ,EAAE"}
@@ -116,6 +116,8 @@ The following list of generators are what is currently available in the \`@aws/n
116
116
 
117
117
  - **ts#lambda-function**: Generate a TypeScript lambda function
118
118
 
119
+ - **ts#dcr-proxy**: Generate an OAuth Dynamic Client Registration (DCR) proxy construct for Cognito-authenticated MCP servers
120
+
119
121
  - **ts#mcp-server**: Generate a TypeScript Model Context Protocol (MCP) server for providing context to Large Language Models
120
122
 
121
123
  - **ts#nx-generator**: Generator for adding an Nx Generator to an existing TypeScript project
@@ -243,7 +245,7 @@ export default {
243
245
 
244
246
  exports[`preset generator > should run successfully > biome.json 1`] = `
245
247
  "{
246
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
248
+ "$schema": "https://biomejs.dev/schemas/2.5.4/schema.json",
247
249
  "root": true,
248
250
  "formatter": {
249
251
  "enabled": true,
@@ -268,7 +270,7 @@ exports[`preset generator > should run successfully > biome.json 1`] = `
268
270
  "linter": {
269
271
  "enabled": true,
270
272
  "rules": {
271
- "recommended": false,
273
+ "preset": "none",
272
274
  "correctness": {
273
275
  "noUndeclaredDependencies": "warn"
274
276
  }
@@ -354,6 +356,7 @@ exports[`preset generator > should run successfully > package.json 1`] = `
354
356
  "build": "nx run-many --target build",
355
357
  "lint": "nx run-many --target lint --configuration=fix",
356
358
  "test": "nx run-many --target test --all",
359
+ "trivy": "nx run-many --target trivy --all",
357
360
  "build:skip-lint": "nx run-many --target build --configuration=skip-lint",
358
361
  "build:all": "nx run-many --target build --all",
359
362
  "affected:all": "nx affected --target build"
@@ -24,7 +24,7 @@ export const pyAgentGatewayConnectionGenerator = async (tree, options)=>{
24
24
  throw new Error(`Gateway '${gateway.name}' has protocol='${gateway.protocol}'. Only MCP-protocol gateways are supported.`);
25
25
  }
26
26
  if (gateway.auth !== 'iam') {
27
- throw new Error(`Gateway '${gateway.name}' uses auth='${gateway.auth}'. Only IAM-authenticated gateways are supported in v1.`);
27
+ throw new Error(`Gateway '${gateway.name}' uses auth='${gateway.auth}'. Agent connections currently require the gateway to use IAM authentication.`);
28
28
  }
29
29
  if (agentComponent.auth && agentComponent.auth !== 'iam') {
30
30
  throw new Error(`Agent '${agentComponent.name}' uses auth='${agentComponent.auth}'. Only IAM-authenticated agents can connect to IAM gateways.`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/agent/gateway-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 { readAgentCoreGatewayMetadata } from '../../../agentcore-gateway/generator';\nimport {\n addPythonCoreClient,\n addPythonReExport,\n ensurePythonAgentConnectionProject,\n getPythonAgentConnectionModuleName,\n getPythonAgentConnectionProject,\n getPythonAgentConnectionProjectDir,\n PY_MCP_FAMILY_CONNECTIONS,\n resolveAgentFramework,\n} from '../../../utils/agent-connection/agent-connection';\nimport { addPythonDestructuredImport } from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { installDependencies } from '../../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics';\nimport { snakeCase } from '../../../utils/names';\nimport {\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../../utils/nx';\nimport {\n addDependenciesToPyProjectToml,\n addWorkspaceDependencyToPyProject,\n} from '../../../utils/py';\nimport type { PyAgentGatewayConnectionGeneratorSchema } from './schema';\n\nexport const PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const pyAgentGatewayConnectionGenerator = async (\n tree: Tree,\n options: PyAgentGatewayConnectionGeneratorSchema,\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 const agentComponent = options.sourceComponent;\n if (!agentComponent) {\n throw new Error(\n 'sourceComponent must be provided for py#agent -> agentcore-gateway connections',\n );\n }\n const gateway = readAgentCoreGatewayMetadata(targetProject);\n\n if (gateway.protocol !== 'mcp') {\n throw new Error(\n `Gateway '${gateway.name}' has protocol='${gateway.protocol}'. Only MCP-protocol gateways are supported.`,\n );\n }\n if (gateway.auth !== 'iam') {\n throw new Error(\n `Gateway '${gateway.name}' uses auth='${gateway.auth}'. Only IAM-authenticated gateways are supported in v1.`,\n );\n }\n if (agentComponent.auth && agentComponent.auth !== 'iam') {\n throw new Error(\n `Agent '${agentComponent.name}' uses auth='${agentComponent.auth}'. Only IAM-authenticated agents can connect to IAM gateways.`,\n );\n }\n\n const gatewayClassName = gateway.rc;\n const gatewaySnakeCase = snakeCase(gatewayClassName);\n // A gateway is its own standalone project, so it exposes plain serve / dev.\n const gatewayServeTargetName = 'serve';\n const gatewayDevTargetName = 'dev';\n\n // The source agent's framework selects the client shape, dependencies and the\n // agent.py transform — see PY_MCP_FAMILY_CONNECTIONS (keyed by framework, not a\n // boolean, so a third framework is an additive entry there). A Gateway exposes\n // its tools over MCP, so it reuses the same wiring as an MCP server connection.\n const framework = resolveAgentFramework(agentComponent.framework);\n const connection = PY_MCP_FAMILY_CONNECTIONS[framework];\n\n await ensurePythonAgentConnectionProject(tree);\n await addPythonCoreClient(tree, 'gateway', framework);\n\n const agentConnectionProjectDir = getPythonAgentConnectionProjectDir(tree);\n const agentConnectionModuleName = getPythonAgentConnectionModuleName(tree);\n\n // Shared MCP transport + signed httpx auth deps, plus whatever extra deps the\n // framework's MCP client needs (e.g. langchain-mcp-adapters for LangChain).\n addDependenciesToPyProjectToml(tree, agentConnectionProjectDir, [\n 'boto3',\n 'httpx',\n 'mcp',\n ...connection.deps,\n ]);\n\n const appDir = joinPathFragments(\n agentConnectionProjectDir,\n agentConnectionModuleName,\n 'app',\n );\n // Local mode points at the gateway project's local gateway port.\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n connection.appTemplateSubdir,\n ),\n appDir,\n {\n gatewaySnakeCase,\n gatewayClassName,\n agentConnectionModuleName,\n gatewayPort: gateway.port,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n const appInitPath = joinPathFragments(appDir, '__init__.py');\n if (!tree.exists(appInitPath)) {\n tree.write(appInitPath, '');\n }\n\n const moduleInitPath = joinPathFragments(\n agentConnectionProjectDir,\n agentConnectionModuleName,\n '__init__.py',\n );\n await addPythonReExport(\n tree,\n moduleInitPath,\n `.app.${gatewaySnakeCase}_client_${connection.clientModuleSuffix}`,\n `${gatewayClassName}Client${connection.clientClassSuffix}`,\n );\n\n const agentSourceDir = joinPathFragments(\n sourceProject.root,\n agentComponent.path ?? 'src',\n );\n const agentFilePath = joinPathFragments(agentSourceDir, 'agent.py');\n\n if (tree.exists(agentFilePath)) {\n const clientClassName = `${gatewayClassName}Client${connection.clientClassSuffix}`;\n const clientVarName = gatewaySnakeCase;\n\n await addPythonDestructuredImport(\n tree,\n agentFilePath,\n [clientClassName],\n agentConnectionModuleName,\n );\n await connection.wireClientIntoAgent(\n tree,\n agentFilePath,\n clientClassName,\n clientVarName,\n );\n }\n\n addWorkspaceDependencyToPyProject(\n tree,\n sourceProject,\n getPythonAgentConnectionProject(tree),\n );\n\n const agentName = agentComponent.name ?? 'agent';\n const serveTargetName = `${agentName}-serve`;\n const devTargetName = `${agentName}-dev`;\n let projectConfigChanged = false;\n if (sourceProject.targets?.[serveTargetName]) {\n addDependencyToTargetIfNotPresent(sourceProject, serveTargetName, {\n projects: [targetProject.name],\n target: gatewayServeTargetName,\n });\n projectConfigChanged = true;\n }\n if (sourceProject.targets?.[devTargetName]) {\n addDependencyToTargetIfNotPresent(sourceProject, devTargetName, {\n projects: [targetProject.name],\n target: gatewayDevTargetName,\n });\n projectConfigChanged = true;\n }\n if (projectConfigChanged) {\n updateProjectConfiguration(tree, sourceProject.name, sourceProject);\n }\n\n await addGeneratorMetricsIfApplicable(tree, [\n PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO,\n ]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\nexport default pyAgentGatewayConnectionGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","readAgentCoreGatewayMetadata","addPythonCoreClient","addPythonReExport","ensurePythonAgentConnectionProject","getPythonAgentConnectionModuleName","getPythonAgentConnectionProject","getPythonAgentConnectionProjectDir","PY_MCP_FAMILY_CONNECTIONS","resolveAgentFramework","addPythonDestructuredImport","formatFilesInSubtree","installDependencies","addGeneratorMetricsIfApplicable","snakeCase","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","addDependenciesToPyProjectToml","addWorkspaceDependencyToPyProject","PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO","filename","pyAgentGatewayConnectionGenerator","tree","options","sourceProject","targetProject","agentComponent","sourceComponent","Error","gateway","protocol","name","auth","gatewayClassName","rc","gatewaySnakeCase","gatewayServeTargetName","gatewayDevTargetName","framework","connection","agentConnectionProjectDir","agentConnectionModuleName","deps","appDir","dirname","appTemplateSubdir","gatewayPort","port","overwriteStrategy","KeepExisting","appInitPath","exists","write","moduleInitPath","clientModuleSuffix","clientClassSuffix","agentSourceDir","root","path","agentFilePath","clientClassName","clientVarName","wireClientIntoAgent","agentName","serveTargetName","devTargetName","projectConfigChanged","targets","projects","target","preferInstallDependencies","languages"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/agent/gateway-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 { readAgentCoreGatewayMetadata } from '../../../agentcore-gateway/generator';\nimport {\n addPythonCoreClient,\n addPythonReExport,\n ensurePythonAgentConnectionProject,\n getPythonAgentConnectionModuleName,\n getPythonAgentConnectionProject,\n getPythonAgentConnectionProjectDir,\n PY_MCP_FAMILY_CONNECTIONS,\n resolveAgentFramework,\n} from '../../../utils/agent-connection/agent-connection';\nimport { addPythonDestructuredImport } from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { installDependencies } from '../../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics';\nimport { snakeCase } from '../../../utils/names';\nimport {\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../../utils/nx';\nimport {\n addDependenciesToPyProjectToml,\n addWorkspaceDependencyToPyProject,\n} from '../../../utils/py';\nimport type { PyAgentGatewayConnectionGeneratorSchema } from './schema';\n\nexport const PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const pyAgentGatewayConnectionGenerator = async (\n tree: Tree,\n options: PyAgentGatewayConnectionGeneratorSchema,\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 const agentComponent = options.sourceComponent;\n if (!agentComponent) {\n throw new Error(\n 'sourceComponent must be provided for py#agent -> agentcore-gateway connections',\n );\n }\n const gateway = readAgentCoreGatewayMetadata(targetProject);\n\n if (gateway.protocol !== 'mcp') {\n throw new Error(\n `Gateway '${gateway.name}' has protocol='${gateway.protocol}'. Only MCP-protocol gateways are supported.`,\n );\n }\n if (gateway.auth !== 'iam') {\n throw new Error(\n `Gateway '${gateway.name}' uses auth='${gateway.auth}'. Agent connections currently require the gateway to use IAM authentication.`,\n );\n }\n if (agentComponent.auth && agentComponent.auth !== 'iam') {\n throw new Error(\n `Agent '${agentComponent.name}' uses auth='${agentComponent.auth}'. Only IAM-authenticated agents can connect to IAM gateways.`,\n );\n }\n\n const gatewayClassName = gateway.rc;\n const gatewaySnakeCase = snakeCase(gatewayClassName);\n // A gateway is its own standalone project, so it exposes plain serve / dev.\n const gatewayServeTargetName = 'serve';\n const gatewayDevTargetName = 'dev';\n\n // The source agent's framework selects the client shape, dependencies and the\n // agent.py transform — see PY_MCP_FAMILY_CONNECTIONS (keyed by framework, not a\n // boolean, so a third framework is an additive entry there). A Gateway exposes\n // its tools over MCP, so it reuses the same wiring as an MCP server connection.\n const framework = resolveAgentFramework(agentComponent.framework);\n const connection = PY_MCP_FAMILY_CONNECTIONS[framework];\n\n await ensurePythonAgentConnectionProject(tree);\n await addPythonCoreClient(tree, 'gateway', framework);\n\n const agentConnectionProjectDir = getPythonAgentConnectionProjectDir(tree);\n const agentConnectionModuleName = getPythonAgentConnectionModuleName(tree);\n\n // Shared MCP transport + signed httpx auth deps, plus whatever extra deps the\n // framework's MCP client needs (e.g. langchain-mcp-adapters for LangChain).\n addDependenciesToPyProjectToml(tree, agentConnectionProjectDir, [\n 'boto3',\n 'httpx',\n 'mcp',\n ...connection.deps,\n ]);\n\n const appDir = joinPathFragments(\n agentConnectionProjectDir,\n agentConnectionModuleName,\n 'app',\n );\n // Local mode points at the gateway project's local gateway port.\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n connection.appTemplateSubdir,\n ),\n appDir,\n {\n gatewaySnakeCase,\n gatewayClassName,\n agentConnectionModuleName,\n gatewayPort: gateway.port,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n const appInitPath = joinPathFragments(appDir, '__init__.py');\n if (!tree.exists(appInitPath)) {\n tree.write(appInitPath, '');\n }\n\n const moduleInitPath = joinPathFragments(\n agentConnectionProjectDir,\n agentConnectionModuleName,\n '__init__.py',\n );\n await addPythonReExport(\n tree,\n moduleInitPath,\n `.app.${gatewaySnakeCase}_client_${connection.clientModuleSuffix}`,\n `${gatewayClassName}Client${connection.clientClassSuffix}`,\n );\n\n const agentSourceDir = joinPathFragments(\n sourceProject.root,\n agentComponent.path ?? 'src',\n );\n const agentFilePath = joinPathFragments(agentSourceDir, 'agent.py');\n\n if (tree.exists(agentFilePath)) {\n const clientClassName = `${gatewayClassName}Client${connection.clientClassSuffix}`;\n const clientVarName = gatewaySnakeCase;\n\n await addPythonDestructuredImport(\n tree,\n agentFilePath,\n [clientClassName],\n agentConnectionModuleName,\n );\n await connection.wireClientIntoAgent(\n tree,\n agentFilePath,\n clientClassName,\n clientVarName,\n );\n }\n\n addWorkspaceDependencyToPyProject(\n tree,\n sourceProject,\n getPythonAgentConnectionProject(tree),\n );\n\n const agentName = agentComponent.name ?? 'agent';\n const serveTargetName = `${agentName}-serve`;\n const devTargetName = `${agentName}-dev`;\n let projectConfigChanged = false;\n if (sourceProject.targets?.[serveTargetName]) {\n addDependencyToTargetIfNotPresent(sourceProject, serveTargetName, {\n projects: [targetProject.name],\n target: gatewayServeTargetName,\n });\n projectConfigChanged = true;\n }\n if (sourceProject.targets?.[devTargetName]) {\n addDependencyToTargetIfNotPresent(sourceProject, devTargetName, {\n projects: [targetProject.name],\n target: gatewayDevTargetName,\n });\n projectConfigChanged = true;\n }\n if (projectConfigChanged) {\n updateProjectConfiguration(tree, sourceProject.name, sourceProject);\n }\n\n await addGeneratorMetricsIfApplicable(tree, [\n PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO,\n ]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\nexport default pyAgentGatewayConnectionGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","readAgentCoreGatewayMetadata","addPythonCoreClient","addPythonReExport","ensurePythonAgentConnectionProject","getPythonAgentConnectionModuleName","getPythonAgentConnectionProject","getPythonAgentConnectionProjectDir","PY_MCP_FAMILY_CONNECTIONS","resolveAgentFramework","addPythonDestructuredImport","formatFilesInSubtree","installDependencies","addGeneratorMetricsIfApplicable","snakeCase","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","addDependenciesToPyProjectToml","addWorkspaceDependencyToPyProject","PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO","filename","pyAgentGatewayConnectionGenerator","tree","options","sourceProject","targetProject","agentComponent","sourceComponent","Error","gateway","protocol","name","auth","gatewayClassName","rc","gatewaySnakeCase","gatewayServeTargetName","gatewayDevTargetName","framework","connection","agentConnectionProjectDir","agentConnectionModuleName","deps","appDir","dirname","appTemplateSubdir","gatewayPort","port","overwriteStrategy","KeepExisting","appInitPath","exists","write","moduleInitPath","clientModuleSuffix","clientClassSuffix","agentSourceDir","root","path","agentFilePath","clientClassName","clientVarName","wireClientIntoAgent","agentName","serveTargetName","devTargetName","projectConfigChanged","targets","projects","target","preferInstallDependencies","languages"],"mappings":"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"}
@@ -170,6 +170,10 @@ def handler(event: dict[str, Any], _context: Any) -> dict[str, Any]:
170
170
  exports[`py#rdb generator > should generate MySQL dependencies and templates 4`] = `
171
171
  "FROM public.ecr.aws/lambda/python:3.14
172
172
 
173
+ # Patch OS packages beyond the base image's pinned release so the image is
174
+ # free of known HIGH/CRITICAL vulnerabilities
175
+ RUN microdnf upgrade -y --releasever latest && microdnf clean all
176
+
173
177
  WORKDIR \${LAMBDA_TASK_ROOT}
174
178
 
175
179
  COPY . .
@@ -184,6 +188,10 @@ CMD ["proj_db.migration_handler.handler"]
184
188
  exports[`py#rdb generator > should generate MySQL dependencies and templates 5`] = `
185
189
  "FROM public.ecr.aws/lambda/python:3.14
186
190
 
191
+ # Patch OS packages beyond the base image's pinned release so the image is
192
+ # free of known HIGH/CRITICAL vulnerabilities
193
+ RUN microdnf upgrade -y --releasever latest && microdnf clean all
194
+
187
195
  WORKDIR \${LAMBDA_TASK_ROOT}
188
196
 
189
197
  COPY . .
@@ -1396,6 +1404,10 @@ datefmt = %H:%M:%S
1396
1404
  exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic 2`] = `
1397
1405
  "FROM public.ecr.aws/lambda/python:3.14
1398
1406
 
1407
+ # Patch OS packages beyond the base image's pinned release so the image is
1408
+ # free of known HIGH/CRITICAL vulnerabilities
1409
+ RUN microdnf upgrade -y --releasever latest && microdnf clean all
1410
+
1399
1411
  WORKDIR \${LAMBDA_TASK_ROOT}
1400
1412
 
1401
1413
  COPY . .
@@ -1410,6 +1422,10 @@ CMD ["proj_db.migration_handler.handler"]
1410
1422
  exports[`py#rdb generator > should generate a PostgreSQL SQLModel project with Alembic 3`] = `
1411
1423
  "FROM public.ecr.aws/lambda/python:3.14
1412
1424
 
1425
+ # Patch OS packages beyond the base image's pinned release so the image is
1426
+ # free of known HIGH/CRITICAL vulnerabilities
1427
+ RUN microdnf upgrade -y --releasever latest && microdnf clean all
1428
+
1413
1429
  WORKDIR \${LAMBDA_TASK_ROOT}
1414
1430
 
1415
1431
  COPY . .
@@ -1483,6 +1499,7 @@ readme = "README.md"
1483
1499
  dependencies = [
1484
1500
  "sqlmodel==0.0.39",
1485
1501
  "alembic==1.18.5",
1502
+ "greenlet==3.5.4",
1486
1503
  "asyncpg==0.31.0",
1487
1504
  "boto3==1.43.51",
1488
1505
  "aws-lambda-powertools==3.31.1"
@@ -1,5 +1,9 @@
1
1
  FROM public.ecr.aws/lambda/python:3.14
2
2
 
3
+ # Patch OS packages beyond the base image's pinned release so the image is
4
+ # free of known HIGH/CRITICAL vulnerabilities
5
+ RUN microdnf upgrade -y --releasever latest && microdnf clean all
6
+
3
7
  WORKDIR ${LAMBDA_TASK_ROOT}
4
8
 
5
9
  COPY . .
@@ -1,5 +1,9 @@
1
1
  FROM public.ecr.aws/lambda/python:3.14
2
2
 
3
+ # Patch OS packages beyond the base image's pinned release so the image is
4
+ # free of known HIGH/CRITICAL vulnerabilities
5
+ RUN microdnf upgrade -y --releasever latest && microdnf clean all
6
+
3
7
  WORKDIR ${LAMBDA_TASK_ROOT}
4
8
 
5
9
  COPY . .
@@ -248,6 +248,11 @@ export const pyRdbGenerator = async (tree, options)=>{
248
248
  addDependenciesToPyProjectToml(tree, dir, [
249
249
  'sqlmodel',
250
250
  'alembic',
251
+ // SQLAlchemy's async engine (used by connection.py for both engines)
252
+ // requires greenlet at runtime. Vend it explicitly at a pinned version so
253
+ // the dependency graph is fully determined and doesn't float to an
254
+ // unpublished-wheel release at install time.
255
+ 'greenlet',
251
256
  ...engine === 'mysql' ? [
252
257
  'aiomysql',
253
258
  'boto3',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/rdb/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { relative } from 'node:path';\nimport {\n addDependenciesToPackageJson,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n readProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addPythonBundleTarget } from '../../utils/bundle/bundle';\nimport { resolveContainers } from '../../utils/containers';\nimport { addDockerScanTarget } from '../../utils/docker';\nimport { formatFilesInSubtree } from '../../utils/format';\nimport { FsCommands } from '../../utils/fs';\nimport { resolveIac } from '../../utils/iac';\nimport { installDependencies } from '../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics';\nimport { kebabCase, snakeCase, toClassName } 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 { assignPort } from '../../utils/port';\nimport { addDependenciesToPyProjectToml } from '../../utils/py';\nimport { addRdbInfra } from '../../utils/rdb-constructs/rdb-constructs';\nimport { sharedConstructsGenerator } from '../../utils/shared-constructs';\nimport {\n PACKAGES_DIR,\n SHARED_SCRIPTS_DIR,\n} from '../../utils/shared-constructs-constants';\nimport { sharedRdbScriptsGenerator } from '../../utils/shared-rdb-scripts';\nimport { PY_VERSIONS, withVersions } from '../../utils/versions';\nimport pyProjectGenerator, { getPyProjectDetails } from '../project/generator';\nimport type { PyRdbGeneratorSchema } from './schema';\n\nexport const PY_RDB_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport const pyRdbGenerator = async (\n tree: Tree,\n options: PyRdbGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const nameClassName = toClassName(options.name);\n const databaseUser = options.databaseUser ?? 'dbadmin';\n const databaseName = snakeCase(options.databaseName ?? options.name);\n const containerEngine = await resolveContainers(tree, 'inherit');\n\n const { fullyQualifiedName, dir, normalizedModuleName } = getPyProjectDetails(\n tree,\n {\n name: options.name,\n directory: options.directory,\n subDirectory: options.subDirectory,\n },\n );\n\n if (!projectExists(tree, fullyQualifiedName)) {\n await pyProjectGenerator(tree, {\n name: options.name,\n directory: options.directory,\n subDirectory: options.subDirectory,\n type: 'library',\n });\n }\n\n const projectConfig = readProjectConfiguration(tree, fullyQualifiedName);\n\n const { engine } = options;\n const localDbPort = assignPort(\n tree,\n projectConfig,\n engine === 'mysql' ? 3306 : 5432,\n );\n const localDbHost = 'localhost';\n const localDbUser = engine === 'mysql' ? 'root' : 'dbadmin';\n const localDbPassword = 'password';\n const containerName = `${getNpmScope(tree)}-${databaseName}`;\n const dockerImage =\n engine === 'mysql'\n ? 'public.ecr.aws/docker/library/mysql:8.0.44'\n : 'public.ecr.aws/docker/library/postgres:17.7';\n\n const templateOptions = {\n name: normalizedModuleName,\n runtimeConfigKey: nameClassName,\n engine,\n localDbPort,\n localDbHost,\n localDbName: databaseName,\n localDbUser,\n localDbPassword,\n containerEngine,\n containerName,\n dockerImage,\n sqlmodelVersion: PY_VERSIONS.sqlmodel,\n alembicVersion: PY_VERSIONS.alembic,\n aiomysqlVersion: PY_VERSIONS.aiomysql,\n asyncpgVersion: PY_VERSIONS.asyncpg,\n boto3Version: PY_VERSIONS.boto3,\n awsLambdaPowertoolsVersion: PY_VERSIONS['aws-lambda-powertools'],\n };\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n dir,\n templateOptions,\n );\n\n await sharedRdbScriptsGenerator(tree, engine);\n // Used by local dev script wait-for-*-db.ts\n addDependenciesToPackageJson(\n tree,\n withVersions([engine === 'mysql' ? 'mariadb' : 'pg']),\n engine === 'mysql' ? {} : withVersions(['@types/pg']),\n );\n const scriptsDir = relative(\n dir,\n joinPathFragments(PACKAGES_DIR, SHARED_SCRIPTS_DIR, 'src', 'rdb'),\n );\n const fs = new FsCommands(tree);\n\n const migrationBundleDir = joinPathFragments(\n 'dist',\n projectConfig.root,\n 'docker',\n 'migration',\n );\n const createDbUserBundleDir = joinPathFragments(\n 'dist',\n projectConfig.root,\n 'docker',\n 'create-db-user',\n );\n const migrationDockerImageTag = `${getNpmScope(tree)}-${kebabCase(options.name)}-migration:latest`;\n const createDbUserDockerImageTag = `${getNpmScope(tree)}-${kebabCase(\n options.name,\n )}-create-db-user:latest`;\n\n if (options.infra !== 'none') {\n const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(\n projectConfig,\n { pythonPlatform: 'aarch64-manylinux_2_28' },\n );\n\n projectConfig.targets['bundle-migration'] = {\n cache: true,\n outputs: ['{workspaceRoot}/dist/{projectRoot}/docker/migration'],\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(migrationBundleDir),\n fs.mkdir(migrationBundleDir),\n fs.cp(bundleOutputDir, migrationBundleDir),\n fs.cp(\n joinPathFragments(dir, 'migrations'),\n joinPathFragments(migrationBundleDir, 'migrations'),\n ),\n fs.cp(\n joinPathFragments(dir, 'alembic.ini'),\n joinPathFragments(migrationBundleDir, 'alembic.ini'),\n ),\n fs.cp(\n joinPathFragments(dir, 'Dockerfile.migration'),\n joinPathFragments(migrationBundleDir, 'Dockerfile'),\n ),\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n projectConfig.targets['bundle-create-db-user'] = {\n cache: true,\n outputs: ['{workspaceRoot}/dist/{projectRoot}/docker/create-db-user'],\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(createDbUserBundleDir),\n fs.mkdir(createDbUserBundleDir),\n fs.cp(bundleOutputDir, createDbUserBundleDir),\n fs.cp(\n joinPathFragments(dir, 'Dockerfile.create-db-user'),\n joinPathFragments(createDbUserBundleDir, 'Dockerfile'),\n ),\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'bundle',\n 'bundle-migration',\n );\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'bundle',\n 'bundle-create-db-user',\n );\n }\n\n projectConfig.targets['pull-image'] = {\n executor: 'nx:run-commands',\n options: {\n command: `tsx ${scriptsDir}/pull-image.ts`,\n cwd: '{projectRoot}',\n },\n };\n projectConfig.targets['dev'] = {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n command: `tsx ${scriptsDir}/start-container.ts`,\n cwd: '{projectRoot}',\n },\n dependsOn: ['pull-image'],\n };\n projectConfig.targets['wait-for-db'] = {\n executor: 'nx:run-commands',\n dependsOn: ['dev'],\n options: {\n command: `tsx ${scriptsDir}/wait-for-${engine}-db.ts`,\n cwd: '{projectRoot}',\n },\n };\n projectConfig.targets.migrate = {\n executor: 'nx:run-commands',\n dependsOn: ['dev', 'wait-for-db'],\n options: {\n command: 'uv run alembic upgrade head',\n cwd: '{projectRoot}',\n env: {\n LOCAL_DEV: 'true',\n },\n },\n };\n projectConfig.targets.alembic = {\n executor: 'nx:run-commands',\n dependsOn: ['dev', 'wait-for-db'],\n options: {\n command: 'uv run alembic',\n cwd: '{projectRoot}',\n env: {\n LOCAL_DEV: 'true',\n },\n },\n };\n\n if (options.infra !== 'none') {\n const iac = await resolveIac(tree, options.iac);\n if (iac === 'terraform') {\n projectConfig.targets.docker = {\n cache: true,\n executor: 'nx:run-commands',\n options: {\n commands: [\n `${containerEngine} build --platform linux/arm64 --provenance=false -t ${migrationDockerImageTag} ${migrationBundleDir}`,\n `${containerEngine} build --platform linux/arm64 --provenance=false -t ${createDbUserDockerImageTag} ${createDbUserBundleDir}`,\n ],\n parallel: false,\n },\n dependsOn: ['bundle-migration', 'bundle-create-db-user'],\n };\n addDependencyToTargetIfNotPresent(projectConfig, 'build', 'docker');\n\n addDockerScanTarget(tree, {\n project: projectConfig,\n containerEngine,\n trivyTargetName: 'trivy',\n dockerTargetName: 'docker',\n imageTags: [migrationDockerImageTag, createDbUserDockerImageTag],\n });\n }\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'build',\n 'bundle-migration',\n );\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'build',\n 'bundle-create-db-user',\n );\n }\n\n updateProjectConfiguration(tree, fullyQualifiedName, projectConfig);\n addGeneratorMetadata(tree, fullyQualifiedName, PY_RDB_GENERATOR_INFO, {\n engine,\n });\n\n if (options.infra !== 'none') {\n const iac = await resolveIac(tree, options.iac);\n await sharedConstructsGenerator(tree, { iac });\n await addRdbInfra(tree, {\n iac,\n projectName: fullyQualifiedName,\n projectRoot: dir,\n nameClassName,\n nameKebabCase: kebabCase(options.name),\n databasePackageAlias: normalizedModuleName,\n databaseName,\n adminUser: databaseUser,\n engine,\n migrationBundleDir,\n createDbUserBundleDir,\n framework: 'sqlmodel',\n createDbUserDockerImageTag,\n migrationDockerImageTag,\n containerEngine,\n });\n }\n\n addDependenciesToPyProjectToml(tree, dir, [\n 'sqlmodel',\n 'alembic',\n ...(engine === 'mysql'\n ? (['aiomysql', 'boto3', 'aws-lambda-powertools'] as const)\n : (['asyncpg', 'boto3', 'aws-lambda-powertools'] as const)),\n ]);\n\n await addGeneratorMetricsIfApplicable(tree, [PY_RDB_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyRdbGenerator;\n"],"names":["relative","addDependenciesToPackageJson","generateFiles","joinPathFragments","readProjectConfiguration","updateProjectConfiguration","addPythonBundleTarget","resolveContainers","addDockerScanTarget","formatFilesInSubtree","FsCommands","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","snakeCase","toClassName","getNpmScope","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","projectExists","assignPort","addDependenciesToPyProjectToml","addRdbInfra","sharedConstructsGenerator","PACKAGES_DIR","SHARED_SCRIPTS_DIR","sharedRdbScriptsGenerator","PY_VERSIONS","withVersions","pyProjectGenerator","getPyProjectDetails","PY_RDB_GENERATOR_INFO","filename","pyRdbGenerator","tree","options","nameClassName","name","databaseUser","databaseName","containerEngine","fullyQualifiedName","dir","normalizedModuleName","directory","subDirectory","type","projectConfig","engine","localDbPort","localDbHost","localDbUser","localDbPassword","containerName","dockerImage","templateOptions","runtimeConfigKey","localDbName","sqlmodelVersion","sqlmodel","alembicVersion","alembic","aiomysqlVersion","aiomysql","asyncpgVersion","asyncpg","boto3Version","boto3","awsLambdaPowertoolsVersion","dirname","scriptsDir","fs","migrationBundleDir","root","createDbUserBundleDir","migrationDockerImageTag","createDbUserDockerImageTag","infra","bundleTargetName","bundleOutputDir","pythonPlatform","targets","cache","outputs","executor","commands","rm","mkdir","cp","parallel","dependsOn","command","cwd","continuous","migrate","env","LOCAL_DEV","iac","docker","project","trivyTargetName","dockerTargetName","imageTags","projectName","projectRoot","nameKebabCase","databasePackageAlias","adminUser","framework","preferInstallDependencies","languages"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/rdb/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { relative } from 'node:path';\nimport {\n addDependenciesToPackageJson,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n readProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addPythonBundleTarget } from '../../utils/bundle/bundle';\nimport { resolveContainers } from '../../utils/containers';\nimport { addDockerScanTarget } from '../../utils/docker';\nimport { formatFilesInSubtree } from '../../utils/format';\nimport { FsCommands } from '../../utils/fs';\nimport { resolveIac } from '../../utils/iac';\nimport { installDependencies } from '../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics';\nimport { kebabCase, snakeCase, toClassName } 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 { assignPort } from '../../utils/port';\nimport { addDependenciesToPyProjectToml } from '../../utils/py';\nimport { addRdbInfra } from '../../utils/rdb-constructs/rdb-constructs';\nimport { sharedConstructsGenerator } from '../../utils/shared-constructs';\nimport {\n PACKAGES_DIR,\n SHARED_SCRIPTS_DIR,\n} from '../../utils/shared-constructs-constants';\nimport { sharedRdbScriptsGenerator } from '../../utils/shared-rdb-scripts';\nimport { PY_VERSIONS, withVersions } from '../../utils/versions';\nimport pyProjectGenerator, { getPyProjectDetails } from '../project/generator';\nimport type { PyRdbGeneratorSchema } from './schema';\n\nexport const PY_RDB_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport const pyRdbGenerator = async (\n tree: Tree,\n options: PyRdbGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const nameClassName = toClassName(options.name);\n const databaseUser = options.databaseUser ?? 'dbadmin';\n const databaseName = snakeCase(options.databaseName ?? options.name);\n const containerEngine = await resolveContainers(tree, 'inherit');\n\n const { fullyQualifiedName, dir, normalizedModuleName } = getPyProjectDetails(\n tree,\n {\n name: options.name,\n directory: options.directory,\n subDirectory: options.subDirectory,\n },\n );\n\n if (!projectExists(tree, fullyQualifiedName)) {\n await pyProjectGenerator(tree, {\n name: options.name,\n directory: options.directory,\n subDirectory: options.subDirectory,\n type: 'library',\n });\n }\n\n const projectConfig = readProjectConfiguration(tree, fullyQualifiedName);\n\n const { engine } = options;\n const localDbPort = assignPort(\n tree,\n projectConfig,\n engine === 'mysql' ? 3306 : 5432,\n );\n const localDbHost = 'localhost';\n const localDbUser = engine === 'mysql' ? 'root' : 'dbadmin';\n const localDbPassword = 'password';\n const containerName = `${getNpmScope(tree)}-${databaseName}`;\n const dockerImage =\n engine === 'mysql'\n ? 'public.ecr.aws/docker/library/mysql:8.0.44'\n : 'public.ecr.aws/docker/library/postgres:17.7';\n\n const templateOptions = {\n name: normalizedModuleName,\n runtimeConfigKey: nameClassName,\n engine,\n localDbPort,\n localDbHost,\n localDbName: databaseName,\n localDbUser,\n localDbPassword,\n containerEngine,\n containerName,\n dockerImage,\n sqlmodelVersion: PY_VERSIONS.sqlmodel,\n alembicVersion: PY_VERSIONS.alembic,\n aiomysqlVersion: PY_VERSIONS.aiomysql,\n asyncpgVersion: PY_VERSIONS.asyncpg,\n boto3Version: PY_VERSIONS.boto3,\n awsLambdaPowertoolsVersion: PY_VERSIONS['aws-lambda-powertools'],\n };\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n dir,\n templateOptions,\n );\n\n await sharedRdbScriptsGenerator(tree, engine);\n // Used by local dev script wait-for-*-db.ts\n addDependenciesToPackageJson(\n tree,\n withVersions([engine === 'mysql' ? 'mariadb' : 'pg']),\n engine === 'mysql' ? {} : withVersions(['@types/pg']),\n );\n const scriptsDir = relative(\n dir,\n joinPathFragments(PACKAGES_DIR, SHARED_SCRIPTS_DIR, 'src', 'rdb'),\n );\n const fs = new FsCommands(tree);\n\n const migrationBundleDir = joinPathFragments(\n 'dist',\n projectConfig.root,\n 'docker',\n 'migration',\n );\n const createDbUserBundleDir = joinPathFragments(\n 'dist',\n projectConfig.root,\n 'docker',\n 'create-db-user',\n );\n const migrationDockerImageTag = `${getNpmScope(tree)}-${kebabCase(options.name)}-migration:latest`;\n const createDbUserDockerImageTag = `${getNpmScope(tree)}-${kebabCase(\n options.name,\n )}-create-db-user:latest`;\n\n if (options.infra !== 'none') {\n const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(\n projectConfig,\n { pythonPlatform: 'aarch64-manylinux_2_28' },\n );\n\n projectConfig.targets['bundle-migration'] = {\n cache: true,\n outputs: ['{workspaceRoot}/dist/{projectRoot}/docker/migration'],\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(migrationBundleDir),\n fs.mkdir(migrationBundleDir),\n fs.cp(bundleOutputDir, migrationBundleDir),\n fs.cp(\n joinPathFragments(dir, 'migrations'),\n joinPathFragments(migrationBundleDir, 'migrations'),\n ),\n fs.cp(\n joinPathFragments(dir, 'alembic.ini'),\n joinPathFragments(migrationBundleDir, 'alembic.ini'),\n ),\n fs.cp(\n joinPathFragments(dir, 'Dockerfile.migration'),\n joinPathFragments(migrationBundleDir, 'Dockerfile'),\n ),\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n projectConfig.targets['bundle-create-db-user'] = {\n cache: true,\n outputs: ['{workspaceRoot}/dist/{projectRoot}/docker/create-db-user'],\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(createDbUserBundleDir),\n fs.mkdir(createDbUserBundleDir),\n fs.cp(bundleOutputDir, createDbUserBundleDir),\n fs.cp(\n joinPathFragments(dir, 'Dockerfile.create-db-user'),\n joinPathFragments(createDbUserBundleDir, 'Dockerfile'),\n ),\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'bundle',\n 'bundle-migration',\n );\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'bundle',\n 'bundle-create-db-user',\n );\n }\n\n projectConfig.targets['pull-image'] = {\n executor: 'nx:run-commands',\n options: {\n command: `tsx ${scriptsDir}/pull-image.ts`,\n cwd: '{projectRoot}',\n },\n };\n projectConfig.targets['dev'] = {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n command: `tsx ${scriptsDir}/start-container.ts`,\n cwd: '{projectRoot}',\n },\n dependsOn: ['pull-image'],\n };\n projectConfig.targets['wait-for-db'] = {\n executor: 'nx:run-commands',\n dependsOn: ['dev'],\n options: {\n command: `tsx ${scriptsDir}/wait-for-${engine}-db.ts`,\n cwd: '{projectRoot}',\n },\n };\n projectConfig.targets.migrate = {\n executor: 'nx:run-commands',\n dependsOn: ['dev', 'wait-for-db'],\n options: {\n command: 'uv run alembic upgrade head',\n cwd: '{projectRoot}',\n env: {\n LOCAL_DEV: 'true',\n },\n },\n };\n projectConfig.targets.alembic = {\n executor: 'nx:run-commands',\n dependsOn: ['dev', 'wait-for-db'],\n options: {\n command: 'uv run alembic',\n cwd: '{projectRoot}',\n env: {\n LOCAL_DEV: 'true',\n },\n },\n };\n\n if (options.infra !== 'none') {\n const iac = await resolveIac(tree, options.iac);\n if (iac === 'terraform') {\n projectConfig.targets.docker = {\n cache: true,\n executor: 'nx:run-commands',\n options: {\n commands: [\n `${containerEngine} build --platform linux/arm64 --provenance=false -t ${migrationDockerImageTag} ${migrationBundleDir}`,\n `${containerEngine} build --platform linux/arm64 --provenance=false -t ${createDbUserDockerImageTag} ${createDbUserBundleDir}`,\n ],\n parallel: false,\n },\n dependsOn: ['bundle-migration', 'bundle-create-db-user'],\n };\n addDependencyToTargetIfNotPresent(projectConfig, 'build', 'docker');\n\n addDockerScanTarget(tree, {\n project: projectConfig,\n containerEngine,\n trivyTargetName: 'trivy',\n dockerTargetName: 'docker',\n imageTags: [migrationDockerImageTag, createDbUserDockerImageTag],\n });\n }\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'build',\n 'bundle-migration',\n );\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'build',\n 'bundle-create-db-user',\n );\n }\n\n updateProjectConfiguration(tree, fullyQualifiedName, projectConfig);\n addGeneratorMetadata(tree, fullyQualifiedName, PY_RDB_GENERATOR_INFO, {\n engine,\n });\n\n if (options.infra !== 'none') {\n const iac = await resolveIac(tree, options.iac);\n await sharedConstructsGenerator(tree, { iac });\n await addRdbInfra(tree, {\n iac,\n projectName: fullyQualifiedName,\n projectRoot: dir,\n nameClassName,\n nameKebabCase: kebabCase(options.name),\n databasePackageAlias: normalizedModuleName,\n databaseName,\n adminUser: databaseUser,\n engine,\n migrationBundleDir,\n createDbUserBundleDir,\n framework: 'sqlmodel',\n createDbUserDockerImageTag,\n migrationDockerImageTag,\n containerEngine,\n });\n }\n\n addDependenciesToPyProjectToml(tree, dir, [\n 'sqlmodel',\n 'alembic',\n // SQLAlchemy's async engine (used by connection.py for both engines)\n // requires greenlet at runtime. Vend it explicitly at a pinned version so\n // the dependency graph is fully determined and doesn't float to an\n // unpublished-wheel release at install time.\n 'greenlet',\n ...(engine === 'mysql'\n ? (['aiomysql', 'boto3', 'aws-lambda-powertools'] as const)\n : (['asyncpg', 'boto3', 'aws-lambda-powertools'] as const)),\n ]);\n\n await addGeneratorMetricsIfApplicable(tree, [PY_RDB_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyRdbGenerator;\n"],"names":["relative","addDependenciesToPackageJson","generateFiles","joinPathFragments","readProjectConfiguration","updateProjectConfiguration","addPythonBundleTarget","resolveContainers","addDockerScanTarget","formatFilesInSubtree","FsCommands","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","snakeCase","toClassName","getNpmScope","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","projectExists","assignPort","addDependenciesToPyProjectToml","addRdbInfra","sharedConstructsGenerator","PACKAGES_DIR","SHARED_SCRIPTS_DIR","sharedRdbScriptsGenerator","PY_VERSIONS","withVersions","pyProjectGenerator","getPyProjectDetails","PY_RDB_GENERATOR_INFO","filename","pyRdbGenerator","tree","options","nameClassName","name","databaseUser","databaseName","containerEngine","fullyQualifiedName","dir","normalizedModuleName","directory","subDirectory","type","projectConfig","engine","localDbPort","localDbHost","localDbUser","localDbPassword","containerName","dockerImage","templateOptions","runtimeConfigKey","localDbName","sqlmodelVersion","sqlmodel","alembicVersion","alembic","aiomysqlVersion","aiomysql","asyncpgVersion","asyncpg","boto3Version","boto3","awsLambdaPowertoolsVersion","dirname","scriptsDir","fs","migrationBundleDir","root","createDbUserBundleDir","migrationDockerImageTag","createDbUserDockerImageTag","infra","bundleTargetName","bundleOutputDir","pythonPlatform","targets","cache","outputs","executor","commands","rm","mkdir","cp","parallel","dependsOn","command","cwd","continuous","migrate","env","LOCAL_DEV","iac","docker","project","trivyTargetName","dockerTargetName","imageTags","projectName","projectRoot","nameKebabCase","databasePackageAlias","adminUser","framework","preferInstallDependencies","languages"],"mappings":"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"}