@aws/nx-plugin 1.0.0-rc.54 → 1.0.0-rc.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/migrations.json +50 -0
- package/package.json +1 -1
- package/src/agentcore-gateway/gateway-connection/generator.js +3 -1
- package/src/agentcore-gateway/gateway-connection/generator.js.map +1 -1
- package/src/agentcore-gateway/generator.d.ts +49 -1
- package/src/agentcore-gateway/generator.js +55 -22
- package/src/agentcore-gateway/generator.js.map +1 -1
- package/src/agentcore-gateway/mcp-connection/generator.js +3 -1
- package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +2 -0
- package/src/infra/app/generator.d.ts +43 -0
- package/src/infra/app/generator.js +47 -18
- package/src/infra/app/generator.js.map +1 -1
- package/src/init/generator.d.ts +13 -0
- package/src/init/generator.js +14 -3
- package/src/init/generator.js.map +1 -1
- package/src/migrations/latest/backfill-generator-metadata/migration.d.ts +96 -0
- package/src/migrations/latest/backfill-generator-metadata/migration.js +670 -0
- package/src/migrations/latest/backfill-generator-metadata/migration.js.map +1 -0
- package/src/migrations/latest/dynamodb-local-remove-optimize-flag/migration.d.ts +6 -0
- package/src/migrations/latest/dynamodb-local-remove-optimize-flag/migration.js +89 -0
- package/src/migrations/latest/dynamodb-local-remove-optimize-flag/migration.js.map +1 -0
- package/src/migrations/latest/modernize-function-props-cast/migration.js +0 -1
- package/src/migrations/latest/modernize-function-props-cast/migration.js.map +1 -1
- package/src/migrations/latest/order-access-log-delivery-after-bucket-policy/migration.js +0 -1
- package/src/migrations/latest/order-access-log-delivery-after-bucket-policy/migration.js.map +1 -1
- package/src/migrations/latest/restrict-cors-to-custom-domains/migration.js +0 -2
- package/src/migrations/latest/restrict-cors-to-custom-domains/migration.js.map +1 -1
- package/src/migrations/latest/terraform-bootstrap-adopt-existing-bucket/migration.js +0 -1
- package/src/migrations/latest/terraform-bootstrap-adopt-existing-bucket/migration.js.map +1 -1
- package/src/migrations/latest/user-identity-waf-allow-localhost-callback/migration.js +0 -2
- package/src/migrations/latest/user-identity-waf-allow-localhost-callback/migration.js.map +1 -1
- package/src/preset/generator.d.ts +13 -0
- package/src/preset/generator.js +12 -3
- package/src/preset/generator.js.map +1 -1
- package/src/py/agent/a2a-connection/generator.d.ts +24 -0
- package/src/py/agent/a2a-connection/generator.js +49 -20
- package/src/py/agent/a2a-connection/generator.js.map +1 -1
- package/src/py/agent/gateway-connection/generator.d.ts +23 -0
- package/src/py/agent/gateway-connection/generator.js +45 -11
- package/src/py/agent/gateway-connection/generator.js.map +1 -1
- package/src/py/agent/generator.d.ts +146 -1
- package/src/py/agent/generator.js +173 -76
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/mcp-connection/generator.d.ts +23 -0
- package/src/py/agent/mcp-connection/generator.js +45 -11
- package/src/py/agent/mcp-connection/generator.js.map +1 -1
- package/src/py/agent/react-connection/generator.d.ts +146 -0
- package/src/py/agent/react-connection/generator.js +27 -4
- package/src/py/agent/react-connection/generator.js.map +1 -1
- package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +0 -2
- package/src/py/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +18 -0
- package/src/py/dynamodb/agent-connection/generator.js +7 -1
- package/src/py/dynamodb/agent-connection/generator.js.map +1 -1
- package/src/py/dynamodb/fast-api-connection/__snapshots__/generator.spec.ts.snap +9 -0
- package/src/py/dynamodb/fast-api-connection/generator.js +3 -1
- package/src/py/dynamodb/fast-api-connection/generator.js.map +1 -1
- package/src/py/dynamodb/generator.d.ts +29 -0
- package/src/py/dynamodb/generator.js +32 -12
- package/src/py/dynamodb/generator.js.map +1 -1
- package/src/py/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +18 -0
- package/src/py/dynamodb/mcp-server-connection/generator.js +7 -1
- package/src/py/dynamodb/mcp-server-connection/generator.js.map +1 -1
- package/src/py/fast-api/generator.d.ts +63 -0
- package/src/py/fast-api/generator.js +58 -23
- package/src/py/fast-api/generator.js.map +1 -1
- package/src/py/fast-api/react/generator.d.ts +16 -1
- package/src/py/fast-api/react/generator.js +15 -3
- package/src/py/fast-api/react/generator.js.map +1 -1
- package/src/py/lambda-function/generator.d.ts +21 -0
- package/src/py/lambda-function/generator.js +29 -10
- package/src/py/lambda-function/generator.js.map +1 -1
- package/src/py/mcp-server/generator.d.ts +60 -0
- package/src/py/mcp-server/generator.js +62 -25
- package/src/py/mcp-server/generator.js.map +1 -1
- package/src/py/project/generator.d.ts +13 -0
- package/src/py/project/generator.js +29 -10
- package/src/py/project/generator.js.map +1 -1
- package/src/py/rdb/agent-connection/__snapshots__/generator.spec.ts.snap +19 -0
- package/src/py/rdb/agent-connection/generator.js +7 -1
- package/src/py/rdb/agent-connection/generator.js.map +1 -1
- package/src/py/rdb/fast-api-connection/__snapshots__/generator.spec.ts.snap +7 -0
- package/src/py/rdb/fast-api-connection/generator.js +3 -1
- package/src/py/rdb/fast-api-connection/generator.js.map +1 -1
- package/src/py/rdb/generator.d.ts +89 -0
- package/src/py/rdb/generator.js +88 -40
- package/src/py/rdb/generator.js.map +1 -1
- package/src/py/rdb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +18 -0
- package/src/py/rdb/mcp-server-connection/generator.js +7 -1
- package/src/py/rdb/mcp-server-connection/generator.js.map +1 -1
- package/src/smithy/project/generator.d.ts +7 -0
- package/src/smithy/project/generator.js +8 -2
- package/src/smithy/project/generator.js.map +1 -1
- package/src/smithy/react-connection/generator.d.ts +15 -0
- package/src/smithy/react-connection/generator.js +17 -3
- package/src/smithy/react-connection/generator.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +1 -0
- package/src/smithy/ts/api/generator.d.ts +79 -0
- package/src/smithy/ts/api/generator.js +77 -33
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/terraform/project/generator.d.ts +50 -0
- package/src/terraform/project/generator.js +63 -17
- package/src/terraform/project/generator.js.map +1 -1
- package/src/trpc/backend/generator.d.ts +84 -0
- package/src/trpc/backend/generator.js +98 -38
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/trpc/react/generator.d.ts +37 -0
- package/src/trpc/react/generator.js +63 -26
- package/src/trpc/react/generator.js.map +1 -1
- package/src/ts/agent/a2a-connection/generator.d.ts +46 -0
- package/src/ts/agent/a2a-connection/generator.js +53 -16
- package/src/ts/agent/a2a-connection/generator.js.map +1 -1
- package/src/ts/agent/gateway-connection/generator.d.ts +37 -0
- package/src/ts/agent/gateway-connection/generator.js +41 -14
- package/src/ts/agent/gateway-connection/generator.js.map +1 -1
- package/src/ts/agent/generator.d.ts +162 -0
- package/src/ts/agent/generator.js +166 -75
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/generator.d.ts +37 -0
- package/src/ts/agent/mcp-connection/generator.js +41 -14
- package/src/ts/agent/mcp-connection/generator.js.map +1 -1
- package/src/ts/agent/react-connection/generator.d.ts +186 -0
- package/src/ts/agent/react-connection/generator.js +70 -21
- package/src/ts/agent/react-connection/generator.js.map +1 -1
- package/src/ts/astro-docs/generator.d.ts +38 -0
- package/src/ts/astro-docs/generator.js +58 -19
- package/src/ts/astro-docs/generator.js.map +1 -1
- package/src/ts/dcr-proxy/generator.d.ts +24 -0
- package/src/ts/dcr-proxy/generator.js +31 -14
- package/src/ts/dcr-proxy/generator.js.map +1 -1
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +0 -2
- package/src/ts/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +18 -0
- package/src/ts/dynamodb/agent-connection/generator.js +7 -1
- package/src/ts/dynamodb/agent-connection/generator.js.map +1 -1
- package/src/ts/dynamodb/generator.d.ts +41 -0
- package/src/ts/dynamodb/generator.js +47 -20
- package/src/ts/dynamodb/generator.js.map +1 -1
- package/src/ts/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +18 -0
- package/src/ts/dynamodb/mcp-server-connection/generator.js +7 -1
- package/src/ts/dynamodb/mcp-server-connection/generator.js.map +1 -1
- package/src/ts/dynamodb/smithy-connection/__snapshots__/generator.spec.ts.snap +9 -0
- package/src/ts/dynamodb/smithy-connection/generator.js +3 -1
- package/src/ts/dynamodb/smithy-connection/generator.js.map +1 -1
- package/src/ts/dynamodb/trpc-connection/__snapshots__/generator.spec.ts.snap +9 -0
- package/src/ts/dynamodb/trpc-connection/generator.js +3 -1
- package/src/ts/dynamodb/trpc-connection/generator.js.map +1 -1
- package/src/ts/lambda-function/generator.d.ts +38 -0
- package/src/ts/lambda-function/generator.js +49 -20
- package/src/ts/lambda-function/generator.js.map +1 -1
- package/src/ts/lib/generator.d.ts +7 -0
- package/src/ts/lib/generator.js +8 -1
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/ts-project-utils.d.ts +3 -1
- package/src/ts/lib/ts-project-utils.js +3 -2
- package/src/ts/lib/ts-project-utils.js.map +1 -1
- package/src/ts/lib/vitest.d.ts +10 -1
- package/src/ts/lib/vitest.js +14 -2
- package/src/ts/lib/vitest.js.map +1 -1
- package/src/ts/mcp-server/generator.d.ts +71 -0
- package/src/ts/mcp-server/generator.js +73 -36
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/nx-generator/generator.d.ts +3 -0
- package/src/ts/nx-generator/generator.js +8 -2
- package/src/ts/nx-generator/generator.js.map +1 -1
- package/src/ts/nx-migration/files/migration.ts.template +4 -0
- package/src/ts/nx-migration/generator.d.ts +3 -0
- package/src/ts/nx-migration/generator.js +8 -2
- package/src/ts/nx-migration/generator.js.map +1 -1
- package/src/ts/nx-plugin/generator.d.ts +3 -0
- package/src/ts/nx-plugin/generator.js +8 -2
- package/src/ts/nx-plugin/generator.js.map +1 -1
- package/src/ts/nx-plugin/utils.d.ts +7 -2
- package/src/ts/nx-plugin/utils.js +10 -4
- package/src/ts/nx-plugin/utils.js.map +1 -1
- package/src/ts/rdb/agent-connection/__snapshots__/generator.spec.ts.snap +10 -0
- package/src/ts/rdb/agent-connection/generator.js +8 -1
- package/src/ts/rdb/agent-connection/generator.js.map +1 -1
- package/src/ts/rdb/generator.d.ts +101 -0
- package/src/ts/rdb/generator.js +93 -41
- package/src/ts/rdb/generator.js.map +1 -1
- package/src/ts/rdb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +10 -0
- package/src/ts/rdb/mcp-server-connection/generator.js +8 -1
- package/src/ts/rdb/mcp-server-connection/generator.js.map +1 -1
- package/src/ts/rdb/smithy-connection/__snapshots__/generator.spec.ts.snap +9 -0
- package/src/ts/rdb/smithy-connection/generator.js +4 -1
- package/src/ts/rdb/smithy-connection/generator.js.map +1 -1
- package/src/ts/rdb/trpc-connection/__snapshots__/generator.spec.ts.snap +9 -0
- package/src/ts/rdb/trpc-connection/generator.js +3 -1
- package/src/ts/rdb/trpc-connection/generator.js.map +1 -1
- package/src/ts/react-website/agui/generator.d.ts +86 -0
- package/src/ts/react-website/agui/generator.js +63 -28
- package/src/ts/react-website/agui/generator.js.map +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +8 -2
- package/src/ts/react-website/app/generator.d.ts +136 -1
- package/src/ts/react-website/app/generator.js +109 -40
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/ts/react-website/cognito-auth/generator.d.ts +19 -0
- package/src/ts/react-website/cognito-auth/generator.js +21 -9
- package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
- package/src/utils/add-dependencies.d.ts +38 -0
- package/src/utils/add-dependencies.js +83 -0
- package/src/utils/add-dependencies.js.map +1 -0
- package/src/utils/agent-connection/agent-connection.d.ts +27 -6
- package/src/utils/agent-connection/agent-connection.js +47 -18
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +19 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.js +26 -6
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/api-constructs/api-constructs.d.ts +21 -2
- package/src/utils/api-constructs/api-constructs.js +26 -5
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/bundle/bundle.d.ts +6 -1
- package/src/utils/bundle/bundle.js +8 -2
- package/src/utils/bundle/bundle.js.map +1 -1
- package/src/utils/commands.d.ts +5 -4
- package/src/utils/commands.js +2 -6
- package/src/utils/commands.js.map +1 -1
- package/src/utils/connection/open-api/react.d.ts +18 -1
- package/src/utils/connection/open-api/react.js +27 -3
- package/src/utils/connection/open-api/react.js.map +1 -1
- package/src/utils/declared-dependencies.d.ts +140 -0
- package/src/utils/declared-dependencies.js +64 -0
- package/src/utils/declared-dependencies.js.map +1 -0
- package/src/utils/docker.d.ts +10 -1
- package/src/utils/docker.js +7 -3
- package/src/utils/docker.js.map +1 -1
- package/src/utils/files/common/scripts/src/dynamodb/start-container.ts.template +0 -1
- package/src/utils/fs.d.ts +15 -4
- package/src/utils/fs.js +26 -13
- package/src/utils/fs.js.map +1 -1
- package/src/utils/init.d.ts +14 -1
- package/src/utils/init.js +25 -7
- package/src/utils/init.js.map +1 -1
- package/src/utils/migration-versions.d.ts +25 -6
- package/src/utils/migration-versions.js +72 -14
- package/src/utils/migration-versions.js.map +1 -1
- package/src/utils/nx.d.ts +18 -0
- package/src/utils/nx.js +4 -0
- package/src/utils/nx.js.map +1 -1
- package/src/utils/py.d.ts +3 -2
- package/src/utils/py.js +10 -10
- package/src/utils/py.js.map +1 -1
- package/src/utils/shared-constructs-constants.d.ts +39 -4
- package/src/utils/shared-constructs-constants.js +29 -0
- package/src/utils/shared-constructs-constants.js.map +1 -1
- package/src/utils/shared-constructs.d.ts +4 -1
- package/src/utils/shared-constructs.js +5 -4
- package/src/utils/shared-constructs.js.map +1 -1
- package/src/utils/shared-dynamodb-scripts.d.ts +8 -1
- package/src/utils/shared-dynamodb-scripts.js +11 -3
- package/src/utils/shared-dynamodb-scripts.js.map +1 -1
- package/src/utils/shared-infra-scripts.d.ts +16 -1
- package/src/utils/shared-infra-scripts.js +18 -3
- package/src/utils/shared-infra-scripts.js.map +1 -1
- package/src/utils/shared-rdb-scripts.d.ts +12 -1
- package/src/utils/shared-rdb-scripts.js +17 -3
- package/src/utils/shared-rdb-scripts.js.map +1 -1
- package/src/utils/shared-shadcn.d.ts +26 -1
- package/src/utils/shared-shadcn.js +31 -14
- package/src/utils/shared-shadcn.js.map +1 -1
- package/src/utils/version-upgrade-migration/migration.d.ts +14 -0
- package/src/utils/version-upgrade-migration/migration.js +16 -0
- package/src/utils/version-upgrade-migration/migration.js.map +1 -0
- package/src/utils/version-upgrade-migration/nx-package-updates.d.ts +45 -0
- package/src/utils/version-upgrade-migration/nx-package-updates.js +50 -0
- package/src/utils/version-upgrade-migration/nx-package-updates.js.map +1 -0
- package/src/utils/version-upgrade-migration/owned-dependencies.d.ts +50 -0
- package/src/utils/version-upgrade-migration/owned-dependencies.js +98 -0
- package/src/utils/version-upgrade-migration/owned-dependencies.js.map +1 -0
- package/src/utils/version-upgrade-migration/register.d.ts +23 -0
- package/src/utils/version-upgrade-migration/register.js +38 -0
- package/src/utils/version-upgrade-migration/register.js.map +1 -0
- package/src/utils/version-upgrade-migration/sync-metrics-version.d.ts +13 -0
- package/src/utils/version-upgrade-migration/sync-metrics-version.js +33 -0
- package/src/utils/version-upgrade-migration/sync-metrics-version.js.map +1 -0
- package/src/utils/version-upgrade-migration/sync-vended-versions.d.ts +10 -0
- package/src/utils/version-upgrade-migration/sync-vended-versions.js +504 -0
- package/src/utils/version-upgrade-migration/sync-vended-versions.js.map +1 -0
- package/src/utils/version-upgrade-migration/vended-upgrade.d.ts +14 -0
- package/src/utils/version-upgrade-migration/vended-upgrade.js +40 -0
- package/src/utils/version-upgrade-migration/vended-upgrade.js.map +1 -0
- package/src/utils/versions.d.ts +25 -5
- package/src/utils/versions.js +46 -4
- package/src/utils/versions.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/fast-api/react/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/fast-api/react/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { joinPathFragments, type Tree } from '@nx/devkit';\nimport {\n addOpenApiReactClient,\n OPEN_API_REACT_DEPENDENCIES,\n} from '../../../utils/connection/open-api/react';\nimport { declareDependencies } from '../../../utils/declared-dependencies';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { installDependencies } from '../../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics';\nimport { toClassName } from '../../../utils/names';\nimport {\n addComponentGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../../utils/nx';\nimport { toProjectRelativePath } from '../../../utils/paths';\nimport { addOpenApiGeneration } from './open-api';\nimport type { FastApiReactGeneratorSchema } from './schema';\n\nexport const DEPENDENCIES = declareDependencies()({\n ts: [...OPEN_API_REACT_DEPENDENCIES],\n});\n\nexport const FAST_API_REACT_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport const fastApiReactGenerator = async (\n tree: Tree,\n options: FastApiReactGeneratorSchema,\n) => {\n const frontendProjectConfig = readProjectConfigurationUnqualified(\n tree,\n options.frontendProjectName,\n );\n const fastApiProjectConfig = readProjectConfigurationUnqualified(\n tree,\n options.fastApiProjectName,\n );\n\n // Add OpenAPI spec generation to the project, run as part of build\n const { specPath } = addOpenApiGeneration(tree, {\n project: fastApiProjectConfig,\n });\n\n const metadata = fastApiProjectConfig.metadata as any;\n const apiName = metadata?.apiName;\n const auth = (metadata?.auth ?? 'iam').toLowerCase();\n const port = metadata?.port ?? metadata?.ports?.[0] ?? 8000;\n\n await addOpenApiReactClient(\n tree,\n {\n apiName,\n frontendProjectConfig,\n backendProjectConfig: fastApiProjectConfig,\n specBuildProject: fastApiProjectConfig,\n specPath,\n specBuildTargetName: `${fastApiProjectConfig.name}:openapi`,\n auth,\n port,\n },\n DEPENDENCIES,\n );\n\n const apiNameClassName = toClassName(apiName);\n\n // Recorded so the version sync knows this connection's dependencies are ours.\n addComponentGeneratorMetadata(\n tree,\n frontendProjectConfig.name,\n FAST_API_REACT_GENERATOR_INFO,\n toProjectRelativePath(\n frontendProjectConfig,\n joinPathFragments(\n frontendProjectConfig.sourceRoot,\n 'components',\n `${apiNameClassName}Provider`,\n ),\n ),\n apiNameClassName,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [FAST_API_REACT_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\nexport default fastApiReactGenerator;\n"],"names":["joinPathFragments","addOpenApiReactClient","OPEN_API_REACT_DEPENDENCIES","declareDependencies","formatFilesInSubtree","installDependencies","addGeneratorMetricsIfApplicable","toClassName","addComponentGeneratorMetadata","getGeneratorInfo","readProjectConfigurationUnqualified","toProjectRelativePath","addOpenApiGeneration","DEPENDENCIES","ts","FAST_API_REACT_GENERATOR_INFO","filename","fastApiReactGenerator","tree","options","frontendProjectConfig","frontendProjectName","fastApiProjectConfig","fastApiProjectName","specPath","project","metadata","apiName","auth","toLowerCase","port","ports","backendProjectConfig","specBuildProject","specBuildTargetName","name","apiNameClassName","sourceRoot","preferInstallDependencies","languages"],"mappings":"AAAA;;;CAGC,GACD,SAASA,iBAAiB,QAAmB,aAAa;AAC1D,SACEC,qBAAqB,EACrBC,2BAA2B,QACtB,8CAA2C;AAClD,SAASC,mBAAmB,QAAQ,0CAAuC;AAC3E,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,mBAAmB,QAAQ,4BAAyB;AAC7D,SAASC,+BAA+B,QAAQ,4BAAyB;AACzE,SAASC,WAAW,QAAQ,0BAAuB;AACnD,SACEC,6BAA6B,EAC7BC,gBAAgB,EAEhBC,mCAAmC,QAC9B,uBAAoB;AAC3B,SAASC,qBAAqB,QAAQ,0BAAuB;AAC7D,SAASC,oBAAoB,QAAQ,gBAAa;AAGlD,OAAO,MAAMC,eAAeV,sBAAsB;IAChDW,IAAI;WAAIZ;KAA4B;AACtC,GAAG;AAEH,OAAO,MAAMa,gCAAiDN,iBAC5D,YAAYO,QAAQ,EACpB;AAEF,OAAO,MAAMC,wBAAwB,OACnCC,MACAC;IAEA,MAAMC,wBAAwBV,oCAC5BQ,MACAC,QAAQE,mBAAmB;IAE7B,MAAMC,uBAAuBZ,oCAC3BQ,MACAC,QAAQI,kBAAkB;IAG5B,mEAAmE;IACnE,MAAM,EAAEC,QAAQ,EAAE,GAAGZ,qBAAqBM,MAAM;QAC9CO,SAASH;IACX;IAEA,MAAMI,WAAWJ,qBAAqBI,QAAQ;IAC9C,MAAMC,UAAUD,UAAUC;IAC1B,MAAMC,OAAO,AAACF,CAAAA,UAAUE,QAAQ,KAAI,EAAGC,WAAW;IAClD,MAAMC,OAAOJ,UAAUI,QAAQJ,UAAUK,OAAO,CAAC,EAAE,IAAI;IAEvD,MAAM9B,sBACJiB,MACA;QACES;QACAP;QACAY,sBAAsBV;QACtBW,kBAAkBX;QAClBE;QACAU,qBAAqB,GAAGZ,qBAAqBa,IAAI,CAAC,QAAQ,CAAC;QAC3DP;QACAE;IACF,GACAjB;IAGF,MAAMuB,mBAAmB7B,YAAYoB;IAErC,8EAA8E;IAC9EnB,8BACEU,MACAE,sBAAsBe,IAAI,EAC1BpB,+BACAJ,sBACES,uBACApB,kBACEoB,sBAAsBiB,UAAU,EAChC,cACA,GAAGD,iBAAiB,QAAQ,CAAC,IAGjCA;IAGF,MAAM9B,gCAAgCY,MAAM;QAACH;KAA8B;IAE3E,MAAMX,qBAAqBc;IAC3B,OAAO,IACLb,oBAAoBa,MAAMC,QAAQmB,yBAAyB,EAAE;YAC3DC,WAAW;gBAAC;aAAa;QAC3B;AACJ,EAAE;AAEF,eAAetB,sBAAsB"}
|
|
@@ -5,6 +5,27 @@
|
|
|
5
5
|
import { type GeneratorCallback, type Tree } from '@nx/devkit';
|
|
6
6
|
import { type NxGeneratorInfo } from '../../utils/nx';
|
|
7
7
|
import type { PyLambdaFunctionGeneratorSchema } from './schema';
|
|
8
|
+
export declare const DEPENDENCIES: import("../../utils/declared-dependencies").DependencyDeclaration<readonly [{
|
|
9
|
+
readonly name: "constructs";
|
|
10
|
+
readonly when: (m: import("../../utils/shared-constructs-constants").IacMetadata) => boolean;
|
|
11
|
+
} & {
|
|
12
|
+
versionOnly: true;
|
|
13
|
+
}, {
|
|
14
|
+
readonly name: "aws-cdk-lib";
|
|
15
|
+
readonly when: (m: import("../../utils/shared-constructs-constants").IacMetadata) => boolean;
|
|
16
|
+
} & {
|
|
17
|
+
versionOnly: true;
|
|
18
|
+
}, {
|
|
19
|
+
readonly name: "@types/node";
|
|
20
|
+
} & {
|
|
21
|
+
versionOnly: true;
|
|
22
|
+
}], readonly [{
|
|
23
|
+
readonly name: "aws-lambda-powertools";
|
|
24
|
+
}, {
|
|
25
|
+
readonly name: "aws-lambda-powertools[tracer]";
|
|
26
|
+
}, {
|
|
27
|
+
readonly name: "aws-lambda-powertools[parser]";
|
|
28
|
+
}]>;
|
|
8
29
|
export declare const LAMBDA_FUNCTION_GENERATOR_INFO: NxGeneratorInfo;
|
|
9
30
|
export interface LambdaFunctionDetails {
|
|
10
31
|
/**
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/ import { generateFiles, joinPathFragments, OverwriteStrategy, updateProjectConfiguration } from "@nx/devkit";
|
|
5
|
+
import { addPyDependencies } from "../../utils/add-dependencies.js";
|
|
5
6
|
import { addPythonBundleTarget } from "../../utils/bundle/bundle.js";
|
|
7
|
+
import { declareDependencies, ownedElsewhere } from "../../utils/declared-dependencies.js";
|
|
6
8
|
import { formatFilesInSubtree } from "../../utils/format.js";
|
|
7
9
|
import { addLambdaFunctionInfra } from "../../utils/function-constructs/function-constructs.js";
|
|
8
10
|
import { resolveIac } from "../../utils/iac.js";
|
|
@@ -13,8 +15,23 @@ import { getNpmScope } from "../../utils/npm-scope.js";
|
|
|
13
15
|
import { addComponentGeneratorMetadata, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../utils/nx.js";
|
|
14
16
|
import { sortObjectKeys } from "../../utils/object.js";
|
|
15
17
|
import { toProjectRelativePath } from "../../utils/paths.js";
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
+
import { SHARED_CONSTRUCTS_DEPENDENCIES, sharedConstructsGenerator } from "../../utils/shared-constructs.js";
|
|
19
|
+
export const DEPENDENCIES = declareDependencies()({
|
|
20
|
+
ts: [
|
|
21
|
+
...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES)
|
|
22
|
+
],
|
|
23
|
+
py: [
|
|
24
|
+
{
|
|
25
|
+
name: 'aws-lambda-powertools'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'aws-lambda-powertools[tracer]'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'aws-lambda-powertools[parser]'
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
});
|
|
18
35
|
export const LAMBDA_FUNCTION_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
|
|
19
36
|
const getLambdaFunctionDetails = (tree, schema)=>{
|
|
20
37
|
const scope = toSnakeCase(getNpmScope(tree));
|
|
@@ -63,11 +80,13 @@ const getLambdaFunctionDetails = (tree, schema)=>{
|
|
|
63
80
|
}
|
|
64
81
|
// Check if the project has a bundle target and if not add it
|
|
65
82
|
const { bundleOutputDir } = addPythonBundleTarget(projectConfig);
|
|
83
|
+
// Recorded below so the version sync can tell a CDK project from a
|
|
84
|
+
// Terraform one; undefined when no infrastructure was generated.
|
|
85
|
+
const iac = infra !== 'none' ? await resolveIac(tree, schema.iac) : undefined;
|
|
66
86
|
if (infra !== 'none') {
|
|
67
|
-
const iac = await resolveIac(tree, schema.iac);
|
|
68
87
|
await sharedConstructsGenerator(tree, {
|
|
69
88
|
iac
|
|
70
|
-
});
|
|
89
|
+
}, DEPENDENCIES);
|
|
71
90
|
await addLambdaFunctionInfra(tree, {
|
|
72
91
|
functionProjectName: projectConfig.name,
|
|
73
92
|
nameClassName: constructFunctionClassName,
|
|
@@ -94,12 +113,12 @@ const getLambdaFunctionDetails = (tree, schema)=>{
|
|
|
94
113
|
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'tests'), joinPathFragments(dir, 'tests'), enhancedOptions, {
|
|
95
114
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
96
115
|
});
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
116
|
+
addPyDependencies(tree, DEPENDENCIES, {
|
|
117
|
+
projectRoot: dir
|
|
118
|
+
});
|
|
119
|
+
addComponentGeneratorMetadata(tree, projectConfig.name, LAMBDA_FUNCTION_GENERATOR_INFO, toProjectRelativePath(projectConfig, functionPath), lambdaFunctionKebabCase, iac ? {
|
|
120
|
+
iac
|
|
121
|
+
} : {});
|
|
103
122
|
await addGeneratorMetricsIfApplicable(tree, [
|
|
104
123
|
LAMBDA_FUNCTION_GENERATOR_INFO
|
|
105
124
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/lambda-function/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 { addPythonBundleTarget } from '../../utils/bundle/bundle';\nimport { formatFilesInSubtree } from '../../utils/format';\nimport { addLambdaFunctionInfra } from '../../utils/function-constructs/function-constructs';\nimport { resolveIac } from '../../utils/iac';\nimport { installDependencies } from '../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics';\nimport {\n toClassName,\n toDotNotation,\n toKebabCase,\n toSnakeCase,\n} from '../../utils/names';\nimport { getNpmScope } from '../../utils/npm-scope';\nimport {\n addComponentGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../utils/nx';\nimport { sortObjectKeys } from '../../utils/object';\nimport { toProjectRelativePath } from '../../utils/paths';\nimport { addDependenciesToPyProjectToml } from '../../utils/py';\nimport { sharedConstructsGenerator } from '../../utils/shared-constructs';\nimport type { PyLambdaFunctionGeneratorSchema } from './schema';\n\nexport const LAMBDA_FUNCTION_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport interface LambdaFunctionDetails {\n /**\n * The normalized name of the lambda handler project\n */\n readonly normalizedFunctionName: string;\n /**\n * The full package name of the lambda handler construct\n */\n readonly fullyQualifiedFunctionName: string;\n /**\n * The normalized python path to the lambda handler file in dot notation (e.g. `app.lambda_functions.lambda_handler`)\n */\n readonly normalizedFunctionPath: string;\n}\n\nconst getLambdaFunctionDetails = (\n tree: Tree,\n schema: { moduleName: string; name: string; functionPath?: string },\n): LambdaFunctionDetails => {\n const scope = toSnakeCase(getNpmScope(tree));\n const normalizedFunctionName = toSnakeCase(schema.name);\n const fullyQualifiedFunctionName = `${scope}.${normalizedFunctionName}`;\n const normalizedFunctionPath = `${schema.moduleName}.${schema.functionPath ? `${toDotNotation(schema.functionPath)}.` : ''}${normalizedFunctionName}.lambda_handler`;\n\n return {\n fullyQualifiedFunctionName,\n normalizedFunctionName,\n normalizedFunctionPath,\n };\n};\n\n/**\n * Generates a Python Lambda Function to add to a python project\n */\nexport const pyLambdaFunctionGenerator = async (\n tree: Tree,\n schema: PyLambdaFunctionGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const projectConfig = readProjectConfigurationUnqualified(\n tree,\n schema.project,\n );\n\n const pyProjectPath = joinPathFragments(projectConfig.root, 'pyproject.toml');\n\n // Check if the project has a pyproject.toml file\n if (!pyProjectPath) {\n throw new Error(\n `This generator does not support selected project ${schema.project}`,\n );\n }\n\n if (!projectConfig.sourceRoot) {\n throw new Error(\n `This project does not have a source root. Please add a source root to the project configuration before running this generator.`,\n );\n }\n\n const dir = projectConfig.root;\n const projectNameWithOutScope = projectConfig.name.split('.').pop();\n const normalizedProjectName = toSnakeCase(projectNameWithOutScope);\n\n // Module name is the last part of the source root,\n const sourceParts = projectConfig.sourceRoot.split('/');\n const moduleName = sourceParts[sourceParts.length - 1];\n\n const { normalizedFunctionName, normalizedFunctionPath } =\n getLambdaFunctionDetails(tree, {\n moduleName,\n name: schema.name,\n functionPath: schema.functionPath,\n });\n\n const constructFunctionName = `${normalizedProjectName}_${normalizedFunctionName}`;\n const constructFunctionClassName = toClassName(constructFunctionName);\n const constructFunctionKebabCase = toKebabCase(constructFunctionName);\n const lambdaFunctionClassName = toClassName(schema.name);\n const lambdaFunctionKebabCase = toKebabCase(schema.name);\n\n const functionPath = joinPathFragments(\n projectConfig.sourceRoot,\n schema.functionPath ?? '',\n `${normalizedFunctionName}.py`,\n );\n\n const infra = schema.infra ?? 'lambda';\n const handlerAlreadyExists = tree.exists(functionPath);\n\n if (handlerAlreadyExists && infra === 'none') {\n throw new Error(\n `This project already has a lambda function with the name ${normalizedFunctionName}. Please remove the lambda function before running this generator or use a different name.`,\n );\n }\n\n // Check if the project has a bundle target and if not add it\n const { bundleOutputDir } = addPythonBundleTarget(projectConfig);\n\n if (infra !== 'none') {\n const iac = await resolveIac(tree, schema.iac);\n\n await sharedConstructsGenerator(tree, {\n iac,\n });\n\n await addLambdaFunctionInfra(tree, {\n functionProjectName: projectConfig.name,\n nameClassName: constructFunctionClassName,\n nameKebabCase: constructFunctionKebabCase,\n handler: normalizedFunctionPath,\n bundlePathFromRoot: bundleOutputDir,\n runtime: 'python',\n iac,\n });\n }\n\n const enhancedOptions = {\n ...schema,\n dir,\n lambdaFunctionClassName,\n lambdaFunctionSnakeCase: normalizedFunctionName,\n };\n\n projectConfig.targets = sortObjectKeys(projectConfig.targets);\n updateProjectConfiguration(tree, projectConfig.name, projectConfig);\n\n // Generate the lambda handler file\n generateFiles(\n tree, // the virtual file system\n joinPathFragments(import.meta.dirname, 'files', 'handler'), // path to the file templates\n joinPathFragments(projectConfig.sourceRoot, schema.functionPath ?? ''),\n enhancedOptions,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n // Generate the lambda handler test file\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'tests'),\n joinPathFragments(dir, 'tests'),\n enhancedOptions,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n addDependenciesToPyProjectToml(tree, dir, [\n 'aws-lambda-powertools',\n 'aws-lambda-powertools[tracer]',\n 'aws-lambda-powertools[parser]',\n ]);\n\n addComponentGeneratorMetadata(\n tree,\n projectConfig.name,\n LAMBDA_FUNCTION_GENERATOR_INFO,\n toProjectRelativePath(projectConfig, functionPath),\n lambdaFunctionKebabCase,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [LAMBDA_FUNCTION_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\nexport default pyLambdaFunctionGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","addPythonBundleTarget","formatFilesInSubtree","addLambdaFunctionInfra","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","toClassName","toDotNotation","toKebabCase","toSnakeCase","getNpmScope","addComponentGeneratorMetadata","getGeneratorInfo","readProjectConfigurationUnqualified","sortObjectKeys","toProjectRelativePath","addDependenciesToPyProjectToml","sharedConstructsGenerator","LAMBDA_FUNCTION_GENERATOR_INFO","filename","getLambdaFunctionDetails","tree","schema","scope","normalizedFunctionName","name","fullyQualifiedFunctionName","normalizedFunctionPath","moduleName","functionPath","pyLambdaFunctionGenerator","projectConfig","project","pyProjectPath","root","Error","sourceRoot","dir","projectNameWithOutScope","split","pop","normalizedProjectName","sourceParts","length","constructFunctionName","constructFunctionClassName","constructFunctionKebabCase","lambdaFunctionClassName","lambdaFunctionKebabCase","infra","handlerAlreadyExists","exists","bundleOutputDir","iac","functionProjectName","nameClassName","nameKebabCase","handler","bundlePathFromRoot","runtime","enhancedOptions","lambdaFunctionSnakeCase","targets","dirname","overwriteStrategy","KeepExisting","preferInstallDependencies","languages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/lambda-function/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 { addPyDependencies } from '../../utils/add-dependencies';\nimport { addPythonBundleTarget } from '../../utils/bundle/bundle';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies';\nimport { formatFilesInSubtree } from '../../utils/format';\nimport { addLambdaFunctionInfra } from '../../utils/function-constructs/function-constructs';\nimport { resolveIac } from '../../utils/iac';\nimport { installDependencies } from '../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics';\nimport {\n toClassName,\n toDotNotation,\n toKebabCase,\n toSnakeCase,\n} from '../../utils/names';\nimport { getNpmScope } from '../../utils/npm-scope';\nimport {\n addComponentGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../utils/nx';\nimport { sortObjectKeys } from '../../utils/object';\nimport { toProjectRelativePath } from '../../utils/paths';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../utils/shared-constructs';\nimport type { PyLambdaFunctionGeneratorSchema } from './schema';\n\nexport const DEPENDENCIES = declareDependencies()({\n ts: [...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES)],\n py: [\n { name: 'aws-lambda-powertools' },\n { name: 'aws-lambda-powertools[tracer]' },\n { name: 'aws-lambda-powertools[parser]' },\n ],\n});\n\nexport const LAMBDA_FUNCTION_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport interface LambdaFunctionDetails {\n /**\n * The normalized name of the lambda handler project\n */\n readonly normalizedFunctionName: string;\n /**\n * The full package name of the lambda handler construct\n */\n readonly fullyQualifiedFunctionName: string;\n /**\n * The normalized python path to the lambda handler file in dot notation (e.g. `app.lambda_functions.lambda_handler`)\n */\n readonly normalizedFunctionPath: string;\n}\n\nconst getLambdaFunctionDetails = (\n tree: Tree,\n schema: { moduleName: string; name: string; functionPath?: string },\n): LambdaFunctionDetails => {\n const scope = toSnakeCase(getNpmScope(tree));\n const normalizedFunctionName = toSnakeCase(schema.name);\n const fullyQualifiedFunctionName = `${scope}.${normalizedFunctionName}`;\n const normalizedFunctionPath = `${schema.moduleName}.${schema.functionPath ? `${toDotNotation(schema.functionPath)}.` : ''}${normalizedFunctionName}.lambda_handler`;\n\n return {\n fullyQualifiedFunctionName,\n normalizedFunctionName,\n normalizedFunctionPath,\n };\n};\n\n/**\n * Generates a Python Lambda Function to add to a python project\n */\nexport const pyLambdaFunctionGenerator = async (\n tree: Tree,\n schema: PyLambdaFunctionGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const projectConfig = readProjectConfigurationUnqualified(\n tree,\n schema.project,\n );\n\n const pyProjectPath = joinPathFragments(projectConfig.root, 'pyproject.toml');\n\n // Check if the project has a pyproject.toml file\n if (!pyProjectPath) {\n throw new Error(\n `This generator does not support selected project ${schema.project}`,\n );\n }\n\n if (!projectConfig.sourceRoot) {\n throw new Error(\n `This project does not have a source root. Please add a source root to the project configuration before running this generator.`,\n );\n }\n\n const dir = projectConfig.root;\n const projectNameWithOutScope = projectConfig.name.split('.').pop();\n const normalizedProjectName = toSnakeCase(projectNameWithOutScope);\n\n // Module name is the last part of the source root,\n const sourceParts = projectConfig.sourceRoot.split('/');\n const moduleName = sourceParts[sourceParts.length - 1];\n\n const { normalizedFunctionName, normalizedFunctionPath } =\n getLambdaFunctionDetails(tree, {\n moduleName,\n name: schema.name,\n functionPath: schema.functionPath,\n });\n\n const constructFunctionName = `${normalizedProjectName}_${normalizedFunctionName}`;\n const constructFunctionClassName = toClassName(constructFunctionName);\n const constructFunctionKebabCase = toKebabCase(constructFunctionName);\n const lambdaFunctionClassName = toClassName(schema.name);\n const lambdaFunctionKebabCase = toKebabCase(schema.name);\n\n const functionPath = joinPathFragments(\n projectConfig.sourceRoot,\n schema.functionPath ?? '',\n `${normalizedFunctionName}.py`,\n );\n\n const infra = schema.infra ?? 'lambda';\n const handlerAlreadyExists = tree.exists(functionPath);\n\n if (handlerAlreadyExists && infra === 'none') {\n throw new Error(\n `This project already has a lambda function with the name ${normalizedFunctionName}. Please remove the lambda function before running this generator or use a different name.`,\n );\n }\n\n // Check if the project has a bundle target and if not add it\n const { bundleOutputDir } = addPythonBundleTarget(projectConfig);\n\n // Recorded below so the version sync can tell a CDK project from a\n // Terraform one; undefined when no infrastructure was generated.\n const iac = infra !== 'none' ? await resolveIac(tree, schema.iac) : undefined;\n\n if (infra !== 'none') {\n await sharedConstructsGenerator(\n tree,\n {\n iac,\n },\n DEPENDENCIES,\n );\n\n await addLambdaFunctionInfra(tree, {\n functionProjectName: projectConfig.name,\n nameClassName: constructFunctionClassName,\n nameKebabCase: constructFunctionKebabCase,\n handler: normalizedFunctionPath,\n bundlePathFromRoot: bundleOutputDir,\n runtime: 'python',\n iac,\n });\n }\n\n const enhancedOptions = {\n ...schema,\n dir,\n lambdaFunctionClassName,\n lambdaFunctionSnakeCase: normalizedFunctionName,\n };\n\n projectConfig.targets = sortObjectKeys(projectConfig.targets);\n updateProjectConfiguration(tree, projectConfig.name, projectConfig);\n\n // Generate the lambda handler file\n generateFiles(\n tree, // the virtual file system\n joinPathFragments(import.meta.dirname, 'files', 'handler'), // path to the file templates\n joinPathFragments(projectConfig.sourceRoot, schema.functionPath ?? ''),\n enhancedOptions,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n // Generate the lambda handler test file\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'tests'),\n joinPathFragments(dir, 'tests'),\n enhancedOptions,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n addPyDependencies(tree, DEPENDENCIES, { projectRoot: dir });\n\n addComponentGeneratorMetadata(\n tree,\n projectConfig.name,\n LAMBDA_FUNCTION_GENERATOR_INFO,\n toProjectRelativePath(projectConfig, functionPath),\n lambdaFunctionKebabCase,\n iac ? { iac } : {},\n );\n\n await addGeneratorMetricsIfApplicable(tree, [LAMBDA_FUNCTION_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\nexport default pyLambdaFunctionGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","addPyDependencies","addPythonBundleTarget","declareDependencies","ownedElsewhere","formatFilesInSubtree","addLambdaFunctionInfra","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","toClassName","toDotNotation","toKebabCase","toSnakeCase","getNpmScope","addComponentGeneratorMetadata","getGeneratorInfo","readProjectConfigurationUnqualified","sortObjectKeys","toProjectRelativePath","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","DEPENDENCIES","ts","py","name","LAMBDA_FUNCTION_GENERATOR_INFO","filename","getLambdaFunctionDetails","tree","schema","scope","normalizedFunctionName","fullyQualifiedFunctionName","normalizedFunctionPath","moduleName","functionPath","pyLambdaFunctionGenerator","projectConfig","project","pyProjectPath","root","Error","sourceRoot","dir","projectNameWithOutScope","split","pop","normalizedProjectName","sourceParts","length","constructFunctionName","constructFunctionClassName","constructFunctionKebabCase","lambdaFunctionClassName","lambdaFunctionKebabCase","infra","handlerAlreadyExists","exists","bundleOutputDir","iac","undefined","functionProjectName","nameClassName","nameKebabCase","handler","bundlePathFromRoot","runtime","enhancedOptions","lambdaFunctionSnakeCase","targets","dirname","overwriteStrategy","KeepExisting","projectRoot","preferInstallDependencies","languages"],"mappings":"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"}
|
|
@@ -4,7 +4,67 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { type GeneratorCallback, type Tree } from '@nx/devkit';
|
|
6
6
|
import { type NxGeneratorInfo } from '../../utils/nx';
|
|
7
|
+
import type { IacMetadata } from '../../utils/shared-constructs-constants';
|
|
7
8
|
import type { PyMcpServerGeneratorSchema } from './schema';
|
|
9
|
+
/** The metadata this generator records, which its predicates read. */
|
|
10
|
+
export interface PyMcpServerMetadata extends IacMetadata {
|
|
11
|
+
readonly port: number;
|
|
12
|
+
readonly rc: string;
|
|
13
|
+
readonly auth: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const DEPENDENCIES: import("../../utils/declared-dependencies").DependencyDeclaration<readonly [{
|
|
16
|
+
readonly name: "@modelcontextprotocol/inspector";
|
|
17
|
+
readonly dev: true;
|
|
18
|
+
readonly root: true;
|
|
19
|
+
}, {
|
|
20
|
+
readonly name: "ncp";
|
|
21
|
+
} & {
|
|
22
|
+
versionOnly: true;
|
|
23
|
+
}, {
|
|
24
|
+
readonly name: "rimraf";
|
|
25
|
+
} & {
|
|
26
|
+
versionOnly: true;
|
|
27
|
+
}, {
|
|
28
|
+
readonly name: "make-dir-cli";
|
|
29
|
+
} & {
|
|
30
|
+
versionOnly: true;
|
|
31
|
+
}, {
|
|
32
|
+
readonly name: "ncp";
|
|
33
|
+
} & {
|
|
34
|
+
versionOnly: true;
|
|
35
|
+
}, {
|
|
36
|
+
readonly name: "rimraf";
|
|
37
|
+
} & {
|
|
38
|
+
versionOnly: true;
|
|
39
|
+
}, {
|
|
40
|
+
readonly name: "make-dir-cli";
|
|
41
|
+
} & {
|
|
42
|
+
versionOnly: true;
|
|
43
|
+
}, {
|
|
44
|
+
readonly name: "constructs";
|
|
45
|
+
readonly when: (m: IacMetadata) => boolean;
|
|
46
|
+
} & {
|
|
47
|
+
versionOnly: true;
|
|
48
|
+
}, {
|
|
49
|
+
readonly name: "aws-cdk-lib";
|
|
50
|
+
readonly when: (m: IacMetadata) => boolean;
|
|
51
|
+
} & {
|
|
52
|
+
versionOnly: true;
|
|
53
|
+
}, {
|
|
54
|
+
readonly name: "@types/node";
|
|
55
|
+
} & {
|
|
56
|
+
versionOnly: true;
|
|
57
|
+
}], readonly [{
|
|
58
|
+
readonly name: "aws-lambda-powertools";
|
|
59
|
+
}, {
|
|
60
|
+
readonly name: "mcp";
|
|
61
|
+
}, {
|
|
62
|
+
readonly name: "uvicorn";
|
|
63
|
+
}, {
|
|
64
|
+
readonly name: "boto3";
|
|
65
|
+
}, {
|
|
66
|
+
readonly name: "aws-opentelemetry-distro";
|
|
67
|
+
}]>;
|
|
8
68
|
export declare const PY_MCP_SERVER_GENERATOR_INFO: NxGeneratorInfo;
|
|
9
69
|
export declare const pyMcpServerGenerator: (tree: Tree, options: PyMcpServerGeneratorSchema) => Promise<GeneratorCallback>;
|
|
10
70
|
export default pyMcpServerGenerator;
|
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
*/ import { generateFiles, joinPathFragments, OverwriteStrategy, updateProjectConfiguration } from "@nx/devkit";
|
|
5
5
|
import { ensureLicenseExceptions } from "../../license/config.js";
|
|
6
6
|
import { MCP_INSPECTOR_EXCEPTIONS } from "../../license/known-exceptions.js";
|
|
7
|
+
import { addPyDependencies, addTsDependencies } from "../../utils/add-dependencies.js";
|
|
7
8
|
import { addMcpServerInfra } from "../../utils/agent-core-constructs/agent-core-constructs.js";
|
|
8
9
|
import { addPythonBundleTarget } from "../../utils/bundle/bundle.js";
|
|
9
10
|
import { resolveContainers } from "../../utils/containers.js";
|
|
10
|
-
import {
|
|
11
|
-
import { addDockerScanTarget } from "../../utils/docker.js";
|
|
11
|
+
import { declareDependencies, ownedElsewhere } from "../../utils/declared-dependencies.js";
|
|
12
|
+
import { addDockerScanTarget, DOCKER_DEPENDENCIES } from "../../utils/docker.js";
|
|
12
13
|
import { formatFilesInSubtree } from "../../utils/format.js";
|
|
13
|
-
import { FsCommands } from "../../utils/fs.js";
|
|
14
|
+
import { FS_DEPENDENCIES, FsCommands } from "../../utils/fs.js";
|
|
14
15
|
import { resolveIac } from "../../utils/iac.js";
|
|
15
16
|
import { installDependencies } from "../../utils/install.js";
|
|
16
17
|
import { addGeneratorMetricsIfApplicable } from "../../utils/metrics.js";
|
|
@@ -19,9 +20,39 @@ import { getNpmScope } from "../../utils/npm-scope.js";
|
|
|
19
20
|
import { addComponentDevTarget, addComponentGeneratorMetadata, addDependencyToTargetIfNotPresent, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../utils/nx.js";
|
|
20
21
|
import { toProjectRelativePath } from "../../utils/paths.js";
|
|
21
22
|
import { assignPort } from "../../utils/port.js";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
|
|
23
|
+
import { SHARED_CONSTRUCTS_DEPENDENCIES, sharedConstructsGenerator } from "../../utils/shared-constructs.js";
|
|
24
|
+
import { BASE_IMAGES } from "../../utils/versions.js";
|
|
25
|
+
export const DEPENDENCIES = declareDependencies()({
|
|
26
|
+
ts: [
|
|
27
|
+
// The MCP inspector is shared tooling.
|
|
28
|
+
{
|
|
29
|
+
name: '@modelcontextprotocol/inspector',
|
|
30
|
+
dev: true,
|
|
31
|
+
root: true
|
|
32
|
+
},
|
|
33
|
+
// Added by the helpers that own the projects they belong to.
|
|
34
|
+
...ownedElsewhere(FS_DEPENDENCIES),
|
|
35
|
+
...ownedElsewhere(DOCKER_DEPENDENCIES),
|
|
36
|
+
...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES)
|
|
37
|
+
],
|
|
38
|
+
py: [
|
|
39
|
+
{
|
|
40
|
+
name: 'aws-lambda-powertools'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'mcp'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'uvicorn'
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'boto3'
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'aws-opentelemetry-distro'
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
});
|
|
25
56
|
export const PY_MCP_SERVER_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
|
|
26
57
|
export const pyMcpServerGenerator = async (tree, options)=>{
|
|
27
58
|
const project = readProjectConfigurationUnqualified(tree, options.project);
|
|
@@ -42,6 +73,10 @@ export const pyMcpServerGenerator = async (tree, options)=>{
|
|
|
42
73
|
const mcpServerNameClassName = toClassName(name);
|
|
43
74
|
const targetSourceDir = joinPathFragments(project.sourceRoot, mcpServerNameSnakeCase);
|
|
44
75
|
const infra = options.infra ?? 'agentcore';
|
|
76
|
+
// Recorded in the metadata below so the version sync can tell a CDK
|
|
77
|
+
// project from a Terraform one; undefined when no infrastructure was
|
|
78
|
+
// generated, in which case neither provider's packages were added.
|
|
79
|
+
const iac = infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;
|
|
45
80
|
if (infra === 'none' && options.auth && options.auth !== 'iam') {
|
|
46
81
|
console.warn('Warning: auth is ignored when no infrastructure is configured (no infrastructure is generated)');
|
|
47
82
|
}
|
|
@@ -55,13 +90,6 @@ export const pyMcpServerGenerator = async (tree, options)=>{
|
|
|
55
90
|
}, {
|
|
56
91
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
57
92
|
});
|
|
58
|
-
addDependenciesToPyProjectToml(tree, project.root, [
|
|
59
|
-
'aws-lambda-powertools',
|
|
60
|
-
'mcp',
|
|
61
|
-
'uvicorn',
|
|
62
|
-
'boto3',
|
|
63
|
-
'aws-opentelemetry-distro'
|
|
64
|
-
]);
|
|
65
93
|
if (infra === 'agentcore') {
|
|
66
94
|
const containers = await resolveContainers(tree, 'inherit');
|
|
67
95
|
const dockerImageTag = `${getNpmScope(tree)}-${name}:latest`;
|
|
@@ -80,7 +108,7 @@ export const pyMcpServerGenerator = async (tree, options)=>{
|
|
|
80
108
|
const dockerOutputDir = joinPathFragments('dist', project.root, 'docker', name);
|
|
81
109
|
const dockerTargetName = `${mcpTargetPrefix}-docker`;
|
|
82
110
|
// Add a docker target that prepares the docker context and builds the image
|
|
83
|
-
const fs = new FsCommands(tree);
|
|
111
|
+
const fs = new FsCommands(tree, DEPENDENCIES);
|
|
84
112
|
project.targets[dockerTargetName] = {
|
|
85
113
|
cache: true,
|
|
86
114
|
executor: 'nx:run-commands',
|
|
@@ -108,12 +136,11 @@ export const pyMcpServerGenerator = async (tree, options)=>{
|
|
|
108
136
|
imageTags: [
|
|
109
137
|
dockerImageTag
|
|
110
138
|
]
|
|
111
|
-
});
|
|
139
|
+
}, DEPENDENCIES);
|
|
112
140
|
// Add shared constructs
|
|
113
|
-
const iac = await resolveIac(tree, options.iac);
|
|
114
141
|
await sharedConstructsGenerator(tree, {
|
|
115
142
|
iac
|
|
116
|
-
});
|
|
143
|
+
}, DEPENDENCIES);
|
|
117
144
|
// Add the construct to deploy the mcp server
|
|
118
145
|
await addMcpServerInfra(tree, {
|
|
119
146
|
mcpServerNameKebabCase: name,
|
|
@@ -132,6 +159,23 @@ export const pyMcpServerGenerator = async (tree, options)=>{
|
|
|
132
159
|
name: mcpTargetPrefix
|
|
133
160
|
}
|
|
134
161
|
});
|
|
162
|
+
// Recorded below and read by the declaration's predicates, so the packages
|
|
163
|
+
// added here are exactly the ones the version sync will own.
|
|
164
|
+
const metadata = {
|
|
165
|
+
port: localDevPort,
|
|
166
|
+
rc: mcpServerNameClassName,
|
|
167
|
+
auth,
|
|
168
|
+
...iac ? {
|
|
169
|
+
iac
|
|
170
|
+
} : {}
|
|
171
|
+
};
|
|
172
|
+
addPyDependencies(tree, DEPENDENCIES, {
|
|
173
|
+
metadata,
|
|
174
|
+
projectRoot: project.root
|
|
175
|
+
});
|
|
176
|
+
addTsDependencies(tree, DEPENDENCIES, {
|
|
177
|
+
metadata
|
|
178
|
+
});
|
|
135
179
|
const mcpTargets = {
|
|
136
180
|
...project.targets,
|
|
137
181
|
// Add targets for running the MCP server
|
|
@@ -205,14 +249,7 @@ export const pyMcpServerGenerator = async (tree, options)=>{
|
|
|
205
249
|
...project,
|
|
206
250
|
targets: mcpTargets
|
|
207
251
|
});
|
|
208
|
-
|
|
209
|
-
'@modelcontextprotocol/inspector'
|
|
210
|
-
]));
|
|
211
|
-
addComponentGeneratorMetadata(tree, project.name, PY_MCP_SERVER_GENERATOR_INFO, toProjectRelativePath(project, targetSourceDir), mcpTargetPrefix, {
|
|
212
|
-
port: localDevPort,
|
|
213
|
-
rc: mcpServerNameClassName,
|
|
214
|
-
auth
|
|
215
|
-
});
|
|
252
|
+
addComponentGeneratorMetadata(tree, project.name, PY_MCP_SERVER_GENERATOR_INFO, toProjectRelativePath(project, targetSourceDir), mcpTargetPrefix, metadata);
|
|
216
253
|
await addGeneratorMetricsIfApplicable(tree, [
|
|
217
254
|
PY_MCP_SERVER_GENERATOR_INFO
|
|
218
255
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/mcp-server/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 { ensureLicenseExceptions } from '../../license/config';\nimport { MCP_INSPECTOR_EXCEPTIONS } from '../../license/known-exceptions';\nimport { addMcpServerInfra } from '../../utils/agent-core-constructs/agent-core-constructs';\nimport { addPythonBundleTarget } from '../../utils/bundle/bundle';\nimport { resolveContainers } from '../../utils/containers';\nimport { addDependenciesToPackageJson } from '../../utils/dependencies';\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, toClassName, toSnakeCase } from '../../utils/names';\nimport { getNpmScope } from '../../utils/npm-scope';\nimport {\n addComponentDevTarget,\n addComponentGeneratorMetadata,\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../utils/nx';\nimport { toProjectRelativePath } from '../../utils/paths';\nimport { assignPort } from '../../utils/port';\nimport { addDependenciesToPyProjectToml } from '../../utils/py';\nimport { sharedConstructsGenerator } from '../../utils/shared-constructs';\nimport { BASE_IMAGES, withVersions } from '../../utils/versions';\nimport type { PyMcpServerGeneratorSchema } from './schema';\n\nexport const PY_MCP_SERVER_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport const pyMcpServerGenerator = async (\n tree: Tree,\n options: PyMcpServerGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const project = readProjectConfigurationUnqualified(tree, options.project);\n\n const pyProjectPath = joinPathFragments(project.root, 'pyproject.toml');\n\n // Check if the project has a pyproject.toml file\n if (!pyProjectPath) {\n throw new Error(\n `Unsupported project ${options.project}. Expected a Python project (with a pyproject.toml)`,\n );\n }\n\n if (!project.sourceRoot) {\n throw new Error(\n `This project does not have a source root. Please add a source root to the project configuration before running this generator.`,\n );\n }\n\n // Module name is the last part of the source root,\n const sourceParts = project.sourceRoot.split('/');\n const moduleName = sourceParts[sourceParts.length - 1];\n\n const name = kebabCase(\n options.name || `${kebabCase(project.name.split('.').pop())}-mcp-server`,\n );\n const mcpTargetPrefix = options.name ? name : 'mcp-server';\n\n const mcpServerNameSnakeCase = toSnakeCase(options.name || 'mcp-server');\n const mcpServerNameClassName = toClassName(name);\n\n const targetSourceDir = joinPathFragments(\n project.sourceRoot,\n mcpServerNameSnakeCase,\n );\n\n const infra = options.infra ?? 'agentcore';\n\n if (infra === 'none' && options.auth && options.auth !== 'iam') {\n console.warn(\n 'Warning: auth is ignored when no infrastructure is configured (no infrastructure is generated)',\n );\n }\n\n const auth = options.auth ?? 'iam';\n\n // Generate example server\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'app'),\n targetSourceDir,\n {\n name,\n mcpServerNameSnakeCase,\n mcpServerNameClassName,\n moduleName,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n addDependenciesToPyProjectToml(tree, project.root, [\n 'aws-lambda-powertools',\n 'mcp',\n 'uvicorn',\n 'boto3',\n 'aws-opentelemetry-distro',\n ]);\n\n if (infra === 'agentcore') {\n const containers = await resolveContainers(tree, 'inherit');\n const dockerImageTag = `${getNpmScope(tree)}-${name}:latest`;\n\n // Add bundle target\n const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(\n project,\n {\n pythonPlatform: 'aarch64-manylinux_2_28',\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'deploy'),\n targetSourceDir,\n {\n mcpServerNameSnakeCase,\n moduleName,\n bundleOutputDir,\n pythonBaseImage: BASE_IMAGES.python,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n const dockerOutputDir = joinPathFragments(\n 'dist',\n project.root,\n 'docker',\n name,\n );\n const dockerTargetName = `${mcpTargetPrefix}-docker`;\n\n // Add a docker target that prepares the docker context and builds the image\n const fs = new FsCommands(tree);\n project.targets[dockerTargetName] = {\n cache: true,\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(dockerOutputDir),\n fs.mkdir(dockerOutputDir),\n fs.cp(bundleOutputDir, dockerOutputDir),\n fs.cp(\n `${targetSourceDir}/Dockerfile`,\n `${dockerOutputDir}/Dockerfile`,\n ),\n `${containers} build --platform linux/arm64 -t ${dockerImageTag} ${dockerOutputDir}`,\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n\n addDependencyToTargetIfNotPresent(project, 'docker', dockerTargetName);\n addDependencyToTargetIfNotPresent(project, 'build', 'docker');\n\n addDockerScanTarget(tree, {\n project,\n containerEngine: containers,\n trivyTargetName: `${mcpTargetPrefix}-trivy`,\n dockerTargetName,\n imageTags: [dockerImageTag],\n });\n\n // Add shared constructs\n const iac = await resolveIac(tree, options.iac);\n await sharedConstructsGenerator(tree, { iac });\n\n // Add the construct to deploy the mcp server\n await addMcpServerInfra(tree, {\n mcpServerNameKebabCase: name,\n mcpServerNameClassName,\n projectName: project.name,\n dockerImageTag,\n dockerOutputDir,\n iac,\n auth,\n containers,\n });\n }\n\n const localDevPort = assignPort(tree, project, 8000, {\n component: { info: PY_MCP_SERVER_GENERATOR_INFO, name: mcpTargetPrefix },\n });\n\n const mcpTargets = {\n ...project.targets,\n // Add targets for running the MCP server\n [`${mcpTargetPrefix}-serve-stdio`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [`uv run -m ${moduleName}.${mcpServerNameSnakeCase}.stdio`],\n cwd: '{projectRoot}',\n },\n },\n [`${mcpTargetPrefix}-serve`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `uv run uvicorn --reload ${moduleName}.${mcpServerNameSnakeCase}.http:app --host 0.0.0.0 --port ${localDevPort}`,\n ],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n },\n },\n },\n [`${mcpTargetPrefix}-dev`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `uv run uvicorn --reload ${moduleName}.${mcpServerNameSnakeCase}.http:app --host 0.0.0.0 --port ${localDevPort}`,\n ],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n LOCAL_DEV: 'true',\n },\n },\n },\n [`${mcpTargetPrefix}-inspect`]: {\n executor: 'nx:run-commands',\n continuous: true,\n // Launch the inspector against the locally served HTTP server. The dev\n // target starts the server and any connected dependencies (e.g. a local\n // database).\n dependsOn: [`${mcpTargetPrefix}-dev`],\n options: {\n commands: [\n `mcp-inspector --transport http --server-url http://localhost:${localDevPort}/mcp`,\n ],\n cwd: '{projectRoot}',\n },\n },\n [`${mcpTargetPrefix}-inspect-stdio`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `mcp-inspector -- uv run -m ${moduleName}.${mcpServerNameSnakeCase}.stdio`,\n ],\n cwd: '{projectRoot}',\n },\n },\n };\n\n // Aggregate `<mcp>-dev` under the project-level `dev` target.\n addComponentDevTarget(mcpTargets, `${mcpTargetPrefix}-dev`);\n\n updateProjectConfiguration(tree, project.name, {\n ...project,\n targets: mcpTargets,\n });\n\n addDependenciesToPackageJson(\n tree,\n {},\n withVersions(['@modelcontextprotocol/inspector']),\n );\n\n addComponentGeneratorMetadata(\n tree,\n project.name,\n PY_MCP_SERVER_GENERATOR_INFO,\n toProjectRelativePath(project, targetSourceDir),\n mcpTargetPrefix,\n {\n port: localDevPort,\n rc: mcpServerNameClassName,\n auth,\n },\n );\n\n await addGeneratorMetricsIfApplicable(tree, [PY_MCP_SERVER_GENERATOR_INFO]);\n\n await ensureLicenseExceptions(tree, MCP_INSPECTOR_EXCEPTIONS);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyMcpServerGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","ensureLicenseExceptions","MCP_INSPECTOR_EXCEPTIONS","addMcpServerInfra","addPythonBundleTarget","resolveContainers","addDependenciesToPackageJson","addDockerScanTarget","formatFilesInSubtree","FsCommands","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","toSnakeCase","getNpmScope","addComponentDevTarget","addComponentGeneratorMetadata","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","toProjectRelativePath","assignPort","addDependenciesToPyProjectToml","sharedConstructsGenerator","BASE_IMAGES","withVersions","PY_MCP_SERVER_GENERATOR_INFO","filename","pyMcpServerGenerator","tree","options","project","pyProjectPath","root","Error","sourceRoot","sourceParts","split","moduleName","length","name","pop","mcpTargetPrefix","mcpServerNameSnakeCase","mcpServerNameClassName","targetSourceDir","infra","auth","console","warn","dirname","overwriteStrategy","KeepExisting","containers","dockerImageTag","bundleTargetName","bundleOutputDir","pythonPlatform","pythonBaseImage","python","dockerOutputDir","dockerTargetName","fs","targets","cache","executor","commands","rm","mkdir","cp","parallel","dependsOn","containerEngine","trivyTargetName","imageTags","iac","mcpServerNameKebabCase","projectName","localDevPort","component","info","mcpTargets","continuous","cwd","env","PORT","LOCAL_DEV","port","rc","preferInstallDependencies","languages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/mcp-server/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 { ensureLicenseExceptions } from '../../license/config';\nimport { MCP_INSPECTOR_EXCEPTIONS } from '../../license/known-exceptions';\nimport {\n addPyDependencies,\n addTsDependencies,\n} from '../../utils/add-dependencies';\nimport { addMcpServerInfra } from '../../utils/agent-core-constructs/agent-core-constructs';\nimport { addPythonBundleTarget } from '../../utils/bundle/bundle';\nimport { resolveContainers } from '../../utils/containers';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies';\nimport { addDockerScanTarget, DOCKER_DEPENDENCIES } from '../../utils/docker';\nimport { formatFilesInSubtree } from '../../utils/format';\nimport { FS_DEPENDENCIES, FsCommands } from '../../utils/fs';\nimport { resolveIac } from '../../utils/iac';\nimport { installDependencies } from '../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics';\nimport { kebabCase, toClassName, toSnakeCase } from '../../utils/names';\nimport { getNpmScope } from '../../utils/npm-scope';\nimport {\n addComponentDevTarget,\n addComponentGeneratorMetadata,\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../utils/nx';\nimport { toProjectRelativePath } from '../../utils/paths';\nimport { assignPort } from '../../utils/port';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../utils/shared-constructs';\nimport type { IacMetadata } from '../../utils/shared-constructs-constants';\nimport { BASE_IMAGES } from '../../utils/versions';\nimport type { PyMcpServerGeneratorSchema } from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface PyMcpServerMetadata extends IacMetadata {\n readonly port: number;\n readonly rc: string;\n readonly auth: string;\n}\n\nexport const DEPENDENCIES = declareDependencies<PyMcpServerMetadata>()({\n ts: [\n // The MCP inspector is shared tooling.\n { name: '@modelcontextprotocol/inspector', dev: true, root: true },\n // Added by the helpers that own the projects they belong to.\n ...ownedElsewhere(FS_DEPENDENCIES),\n ...ownedElsewhere(DOCKER_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: [\n { name: 'aws-lambda-powertools' },\n { name: 'mcp' },\n { name: 'uvicorn' },\n { name: 'boto3' },\n { name: 'aws-opentelemetry-distro' },\n ],\n});\n\nexport const PY_MCP_SERVER_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport const pyMcpServerGenerator = async (\n tree: Tree,\n options: PyMcpServerGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const project = readProjectConfigurationUnqualified(tree, options.project);\n\n const pyProjectPath = joinPathFragments(project.root, 'pyproject.toml');\n\n // Check if the project has a pyproject.toml file\n if (!pyProjectPath) {\n throw new Error(\n `Unsupported project ${options.project}. Expected a Python project (with a pyproject.toml)`,\n );\n }\n\n if (!project.sourceRoot) {\n throw new Error(\n `This project does not have a source root. Please add a source root to the project configuration before running this generator.`,\n );\n }\n\n // Module name is the last part of the source root,\n const sourceParts = project.sourceRoot.split('/');\n const moduleName = sourceParts[sourceParts.length - 1];\n\n const name = kebabCase(\n options.name || `${kebabCase(project.name.split('.').pop())}-mcp-server`,\n );\n const mcpTargetPrefix = options.name ? name : 'mcp-server';\n\n const mcpServerNameSnakeCase = toSnakeCase(options.name || 'mcp-server');\n const mcpServerNameClassName = toClassName(name);\n\n const targetSourceDir = joinPathFragments(\n project.sourceRoot,\n mcpServerNameSnakeCase,\n );\n\n const infra = options.infra ?? 'agentcore';\n\n // Recorded in the metadata below so the version sync can tell a CDK\n // project from a Terraform one; undefined when no infrastructure was\n // generated, in which case neither provider's packages were added.\n const iac =\n infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;\n\n if (infra === 'none' && options.auth && options.auth !== 'iam') {\n console.warn(\n 'Warning: auth is ignored when no infrastructure is configured (no infrastructure is generated)',\n );\n }\n\n const auth = options.auth ?? 'iam';\n\n // Generate example server\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'app'),\n targetSourceDir,\n {\n name,\n mcpServerNameSnakeCase,\n mcpServerNameClassName,\n moduleName,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n if (infra === 'agentcore') {\n const containers = await resolveContainers(tree, 'inherit');\n const dockerImageTag = `${getNpmScope(tree)}-${name}:latest`;\n\n // Add bundle target\n const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(\n project,\n {\n pythonPlatform: 'aarch64-manylinux_2_28',\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'deploy'),\n targetSourceDir,\n {\n mcpServerNameSnakeCase,\n moduleName,\n bundleOutputDir,\n pythonBaseImage: BASE_IMAGES.python,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n const dockerOutputDir = joinPathFragments(\n 'dist',\n project.root,\n 'docker',\n name,\n );\n const dockerTargetName = `${mcpTargetPrefix}-docker`;\n\n // Add a docker target that prepares the docker context and builds the image\n const fs = new FsCommands(tree, DEPENDENCIES);\n project.targets[dockerTargetName] = {\n cache: true,\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(dockerOutputDir),\n fs.mkdir(dockerOutputDir),\n fs.cp(bundleOutputDir, dockerOutputDir),\n fs.cp(\n `${targetSourceDir}/Dockerfile`,\n `${dockerOutputDir}/Dockerfile`,\n ),\n `${containers} build --platform linux/arm64 -t ${dockerImageTag} ${dockerOutputDir}`,\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n\n addDependencyToTargetIfNotPresent(project, 'docker', dockerTargetName);\n addDependencyToTargetIfNotPresent(project, 'build', 'docker');\n\n addDockerScanTarget(\n tree,\n {\n project,\n containerEngine: containers,\n trivyTargetName: `${mcpTargetPrefix}-trivy`,\n dockerTargetName,\n imageTags: [dockerImageTag],\n },\n DEPENDENCIES,\n );\n\n // Add shared constructs\n await sharedConstructsGenerator(tree, { iac }, DEPENDENCIES);\n\n // Add the construct to deploy the mcp server\n await addMcpServerInfra(tree, {\n mcpServerNameKebabCase: name,\n mcpServerNameClassName,\n projectName: project.name,\n dockerImageTag,\n dockerOutputDir,\n iac,\n auth,\n containers,\n });\n }\n\n const localDevPort = assignPort(tree, project, 8000, {\n component: { info: PY_MCP_SERVER_GENERATOR_INFO, name: mcpTargetPrefix },\n });\n\n // Recorded below and read by the declaration's predicates, so the packages\n // added here are exactly the ones the version sync will own.\n const metadata: PyMcpServerMetadata = {\n port: localDevPort,\n rc: mcpServerNameClassName,\n auth,\n ...(iac ? { iac } : {}),\n };\n\n addPyDependencies(tree, DEPENDENCIES, {\n metadata,\n projectRoot: project.root,\n });\n addTsDependencies(tree, DEPENDENCIES, { metadata });\n\n const mcpTargets = {\n ...project.targets,\n // Add targets for running the MCP server\n [`${mcpTargetPrefix}-serve-stdio`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [`uv run -m ${moduleName}.${mcpServerNameSnakeCase}.stdio`],\n cwd: '{projectRoot}',\n },\n },\n [`${mcpTargetPrefix}-serve`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `uv run uvicorn --reload ${moduleName}.${mcpServerNameSnakeCase}.http:app --host 0.0.0.0 --port ${localDevPort}`,\n ],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n },\n },\n },\n [`${mcpTargetPrefix}-dev`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `uv run uvicorn --reload ${moduleName}.${mcpServerNameSnakeCase}.http:app --host 0.0.0.0 --port ${localDevPort}`,\n ],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n LOCAL_DEV: 'true',\n },\n },\n },\n [`${mcpTargetPrefix}-inspect`]: {\n executor: 'nx:run-commands',\n continuous: true,\n // Launch the inspector against the locally served HTTP server. The dev\n // target starts the server and any connected dependencies (e.g. a local\n // database).\n dependsOn: [`${mcpTargetPrefix}-dev`],\n options: {\n commands: [\n `mcp-inspector --transport http --server-url http://localhost:${localDevPort}/mcp`,\n ],\n cwd: '{projectRoot}',\n },\n },\n [`${mcpTargetPrefix}-inspect-stdio`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `mcp-inspector -- uv run -m ${moduleName}.${mcpServerNameSnakeCase}.stdio`,\n ],\n cwd: '{projectRoot}',\n },\n },\n };\n\n // Aggregate `<mcp>-dev` under the project-level `dev` target.\n addComponentDevTarget(mcpTargets, `${mcpTargetPrefix}-dev`);\n\n updateProjectConfiguration(tree, project.name, {\n ...project,\n targets: mcpTargets,\n });\n\n addComponentGeneratorMetadata(\n tree,\n project.name,\n PY_MCP_SERVER_GENERATOR_INFO,\n toProjectRelativePath(project, targetSourceDir),\n mcpTargetPrefix,\n metadata,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [PY_MCP_SERVER_GENERATOR_INFO]);\n\n await ensureLicenseExceptions(tree, MCP_INSPECTOR_EXCEPTIONS);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyMcpServerGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","ensureLicenseExceptions","MCP_INSPECTOR_EXCEPTIONS","addPyDependencies","addTsDependencies","addMcpServerInfra","addPythonBundleTarget","resolveContainers","declareDependencies","ownedElsewhere","addDockerScanTarget","DOCKER_DEPENDENCIES","formatFilesInSubtree","FS_DEPENDENCIES","FsCommands","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","toSnakeCase","getNpmScope","addComponentDevTarget","addComponentGeneratorMetadata","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","toProjectRelativePath","assignPort","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","BASE_IMAGES","DEPENDENCIES","ts","name","dev","root","py","PY_MCP_SERVER_GENERATOR_INFO","filename","pyMcpServerGenerator","tree","options","project","pyProjectPath","Error","sourceRoot","sourceParts","split","moduleName","length","pop","mcpTargetPrefix","mcpServerNameSnakeCase","mcpServerNameClassName","targetSourceDir","infra","iac","undefined","auth","console","warn","dirname","overwriteStrategy","KeepExisting","containers","dockerImageTag","bundleTargetName","bundleOutputDir","pythonPlatform","pythonBaseImage","python","dockerOutputDir","dockerTargetName","fs","targets","cache","executor","commands","rm","mkdir","cp","parallel","dependsOn","containerEngine","trivyTargetName","imageTags","mcpServerNameKebabCase","projectName","localDevPort","component","info","metadata","port","rc","projectRoot","mcpTargets","continuous","cwd","env","PORT","LOCAL_DEV","preferInstallDependencies","languages"],"mappings":"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"}
|
|
@@ -5,6 +5,19 @@
|
|
|
5
5
|
import { type GeneratorCallback, type Tree } from '@nx/devkit';
|
|
6
6
|
import { type NxGeneratorInfo } from '../../utils/nx';
|
|
7
7
|
import type { PyProjectGeneratorSchema } from './schema';
|
|
8
|
+
export declare const DEPENDENCIES: import("../../utils/declared-dependencies").DependencyDeclaration<readonly [{
|
|
9
|
+
readonly name: "@nxlv/python";
|
|
10
|
+
readonly dev: true;
|
|
11
|
+
readonly root: true;
|
|
12
|
+
}], readonly [{
|
|
13
|
+
readonly name: "ruff";
|
|
14
|
+
readonly group: "dev";
|
|
15
|
+
readonly root: true;
|
|
16
|
+
}, {
|
|
17
|
+
readonly name: "ty";
|
|
18
|
+
readonly group: "dev";
|
|
19
|
+
readonly root: true;
|
|
20
|
+
}]>;
|
|
8
21
|
export declare const PY_PROJECT_GENERATOR_INFO: NxGeneratorInfo;
|
|
9
22
|
export interface PyProjectDetails {
|
|
10
23
|
/**
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/ import { ensurePackage, joinPathFragments, readNxJson, readProjectConfiguration, updateNxJson, updateProjectConfiguration } from "@nx/devkit";
|
|
5
5
|
import { addLicenseCheckToLintTarget, ensurePythonLicenseCollector } from "../../license/config.js";
|
|
6
|
-
import {
|
|
6
|
+
import { addPyDependencies, addTsDependencies } from "../../utils/add-dependencies.js";
|
|
7
|
+
import { declareDependencies } from "../../utils/declared-dependencies.js";
|
|
7
8
|
import { updateGitIgnore } from "../../utils/git.js";
|
|
8
9
|
import { installDependencies } from "../../utils/install.js";
|
|
9
10
|
import { addGeneratorMetricsIfApplicable } from "../../utils/metrics.js";
|
|
@@ -12,9 +13,32 @@ import { getNpmScope } from "../../utils/npm-scope.js";
|
|
|
12
13
|
import { addDependencyToTargetIfNotPresent, addGeneratorMetadata, getGeneratorInfo, projectExists } from "../../utils/nx.js";
|
|
13
14
|
import { migrateToSharedVenvGenerator, uvProjectGenerator } from "../../utils/nxlv-python.js";
|
|
14
15
|
import { sortObjectKeys } from "../../utils/object.js";
|
|
15
|
-
import { addDependenciesToDependencyGroupInPyProjectToml } from "../../utils/py.js";
|
|
16
16
|
import { updateToml } from "../../utils/toml.js";
|
|
17
17
|
import { withVersions } from "../../utils/versions.js";
|
|
18
|
+
export const DEPENDENCIES = declareDependencies()({
|
|
19
|
+
ts: [
|
|
20
|
+
{
|
|
21
|
+
name: '@nxlv/python',
|
|
22
|
+
dev: true,
|
|
23
|
+
root: true
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
py: [
|
|
27
|
+
// The linting and type checking tools live in the workspace root pyproject.
|
|
28
|
+
// Pinned to the version generation-time formatting uses, so generated files
|
|
29
|
+
// stay `ruff format --check`-clean across ruff releases.
|
|
30
|
+
{
|
|
31
|
+
name: 'ruff',
|
|
32
|
+
group: 'dev',
|
|
33
|
+
root: true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'ty',
|
|
37
|
+
group: 'dev',
|
|
38
|
+
root: true
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
});
|
|
18
42
|
export const PY_PROJECT_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
|
|
19
43
|
// Transient artifacts that pytest, coverage and ruff create and remove while
|
|
20
44
|
// the test, typecheck and compile targets run concurrently. `.coverage.*` are
|
|
@@ -53,10 +77,10 @@ const PYTHON_TRANSIENT_ARTIFACTS = [
|
|
|
53
77
|
* Generates a Python project
|
|
54
78
|
*/ export const pyProjectGenerator = async (tree, schema)=>{
|
|
55
79
|
const { dir, normalizedModuleName, fullyQualifiedName, distributionName } = getPyProjectDetails(tree, schema);
|
|
56
|
-
|
|
80
|
+
addTsDependencies(tree, DEPENDENCIES);
|
|
81
|
+
const pythonPlugin = withVersions(DEPENDENCIES, [
|
|
57
82
|
'@nxlv/python'
|
|
58
83
|
]);
|
|
59
|
-
addDependenciesToPackageJson(tree, {}, pythonPlugin);
|
|
60
84
|
Object.entries(pythonPlugin).forEach(([name, version])=>ensurePackage(name, version));
|
|
61
85
|
const nxJson = readNxJson(tree);
|
|
62
86
|
// Only rewrite nx.json when the plugin needs adding, so re-running does not
|
|
@@ -192,12 +216,7 @@ const PYTHON_TRANSIENT_ARTIFACTS = [
|
|
|
192
216
|
}
|
|
193
217
|
return pyProjectToml;
|
|
194
218
|
});
|
|
195
|
-
|
|
196
|
-
// generated files stay `ruff format --check`-clean across ruff releases.
|
|
197
|
-
addDependenciesToDependencyGroupInPyProjectToml(tree, '.', 'dev', [
|
|
198
|
-
'ruff',
|
|
199
|
-
'ty'
|
|
200
|
-
]);
|
|
219
|
+
addPyDependencies(tree, DEPENDENCIES);
|
|
201
220
|
// Base format target checks rather than writes (so build/lint don't rewrite
|
|
202
221
|
// source); `fix` writes, and `skip-lint` writes without failing so it stays
|
|
203
222
|
// a no-op when propagated through the lint -> format dependency.
|