@aws/nx-plugin 1.0.0-rc.84 → 1.0.0-rc.85
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/generators.json +7 -0
- package/migrations.json +6 -1
- package/package.json +1 -1
- package/src/internal/test-matrix/generator.js +16 -0
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/metadata.json +3 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.js +146 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.js.map +1 -0
- package/src/open-api/json-metadata/generator.d.ts +24 -0
- package/src/open-api/json-metadata/generator.js +37 -0
- package/src/open-api/json-metadata/generator.js.map +1 -0
- package/src/open-api/json-metadata/schema.d.js +6 -0
- package/src/open-api/json-metadata/schema.d.js.map +1 -0
- package/src/open-api/json-metadata/schema.d.ts +9 -0
- package/src/open-api/json-metadata/schema.json +20 -0
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +1604 -559
- package/src/py/fast-api/generator.js +2 -1
- package/src/py/fast-api/generator.js.map +1 -1
- package/src/sdk/open-api.d.ts +2 -0
- package/src/sdk/open-api.js +2 -1
- package/src/sdk/open-api.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +1548 -440
- package/src/smithy/ts/api/generator.js +2 -1
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/terraform/project/files/application/bootstrap/providers.tf.template +2 -0
- package/src/terraform/project/files/application/scripts/bootstrap-destroy.ts.template +111 -0
- package/src/terraform/project/files/application/src/providers.tf.template +2 -0
- package/src/terraform/project/files/checkov/checkov.yml.template +8 -0
- package/src/terraform/project/generator.js +47 -4
- package/src/terraform/project/generator.js.map +1 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +1552 -525
- package/src/trpc/backend/files-operations/scripts/generate-operations.ts.template +40 -0
- package/src/trpc/backend/generator.js +10 -0
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/utils/api-constructs/api-constructs.js +11 -0
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +243 -3
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +428 -1
- package/src/utils/api-constructs/open-api-metadata.d.ts +20 -3
- package/src/utils/api-constructs/open-api-metadata.js +64 -8
- package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
- package/src/utils/api-constructs/trpc-operations-metadata.d.ts +21 -0
- package/src/utils/api-constructs/trpc-operations-metadata.js +55 -0
- package/src/utils/api-constructs/trpc-operations-metadata.js.map +1 -0
package/generators.json
CHANGED
|
@@ -124,6 +124,13 @@
|
|
|
124
124
|
"metric": "g19",
|
|
125
125
|
"hidden": true
|
|
126
126
|
},
|
|
127
|
+
"open-api#json-metadata": {
|
|
128
|
+
"factory": "./src/open-api/json-metadata/generator",
|
|
129
|
+
"schema": "./src/open-api/json-metadata/schema.json",
|
|
130
|
+
"description": "Generate a JSON metadata file describing an OpenAPI specification's operations",
|
|
131
|
+
"metric": "g72",
|
|
132
|
+
"hidden": true
|
|
133
|
+
},
|
|
127
134
|
"preset": {
|
|
128
135
|
"factory": "./src/preset/generator",
|
|
129
136
|
"schema": "./src/preset/schema.json",
|
package/migrations.json
CHANGED
|
@@ -72,6 +72,11 @@
|
|
|
72
72
|
"description": "Add VPC, execution role and native field support to the vended Terraform AgentCore Harness module, and scope its managed-memory grant to the service-assigned ARN",
|
|
73
73
|
"implementation": "./src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration"
|
|
74
74
|
},
|
|
75
|
+
"latest-terraform-project-checkov-target-and-bootstrap-destroy": {
|
|
76
|
+
"version": "1.0.0-rc.85",
|
|
77
|
+
"description": "Add the Terraform checkov target and config, make bootstrap-destroy non-interactive, and declare required_version in the vended providers.tf",
|
|
78
|
+
"implementation": "./src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration"
|
|
79
|
+
},
|
|
75
80
|
"v1.0.0-rc.50-0001-modernize-function-props-cast": {
|
|
76
81
|
"version": "1.0.0-rc.50",
|
|
77
82
|
"description": "Replace the legacy angle-bracket FunctionProps type assertion with the modern as syntax in generated API constructs",
|
|
@@ -213,7 +218,7 @@
|
|
|
213
218
|
"implementation": "./src/migrations/v1.0.0-rc.75/0001-ts-agent-session-id-middleware-extraction/migration"
|
|
214
219
|
},
|
|
215
220
|
"sync-vended-versions": {
|
|
216
|
-
"version": "1.0.0-rc.
|
|
221
|
+
"version": "1.0.0-rc.85",
|
|
217
222
|
"description": "Sync vended dependency versions and the tracked plugin version to those vended by this release",
|
|
218
223
|
"implementation": "./src/utils/version-upgrade-migration/migration"
|
|
219
224
|
}
|
package/package.json
CHANGED
|
@@ -111,6 +111,22 @@ import { getNpmScope, getNpmScopePrefix } from "../../utils/npm-scope.js";
|
|
|
111
111
|
auth: 'iam',
|
|
112
112
|
iac: 'inherit'
|
|
113
113
|
},
|
|
114
|
+
// The APIs above take the default `isolated` integration pattern; these
|
|
115
|
+
// cover `shared`.
|
|
116
|
+
{
|
|
117
|
+
name: 'my-api-shared',
|
|
118
|
+
infra: 'rest-lambda',
|
|
119
|
+
auth: 'iam',
|
|
120
|
+
integrationPattern: 'shared',
|
|
121
|
+
iac: 'inherit'
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'my-api-shared-http',
|
|
125
|
+
infra: 'http-lambda',
|
|
126
|
+
auth: 'iam',
|
|
127
|
+
integrationPattern: 'shared',
|
|
128
|
+
iac: 'inherit'
|
|
129
|
+
},
|
|
114
130
|
{
|
|
115
131
|
name: 'my-api-custom',
|
|
116
132
|
infra: 'rest-lambda',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/internal/test-matrix/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { GeneratorCallback, Tree } from '@nx/devkit';\nimport { agentcoreGatewayGenerator } from '../../sdk/agentcore-gateway.js';\nimport { agentcoreHarnessGenerator } from '../../sdk/agentcore-harness.js';\nimport {\n type ConnectionGeneratorSchema,\n connectionGenerator,\n} from '../../sdk/connection.js';\nimport { licenseGenerator } from '../../sdk/license.js';\nimport {\n type PyAgentGeneratorSchema,\n type PyApiGeneratorSchema,\n type PyRdbGeneratorSchema,\n pyAgentGenerator,\n pyApiGenerator,\n pyDynamoDBGenerator,\n pyLambdaFunctionGenerator,\n pyMcpServerGenerator,\n pyProjectGenerator,\n pyRdbGenerator,\n} from '../../sdk/py.js';\nimport { smithyProjectGenerator } from '../../sdk/smithy.js';\nimport { terraformProjectGenerator } from '../../sdk/terraform.js';\nimport {\n type TsAgentGeneratorSchema,\n type TsApiGeneratorSchema,\n type TsNxMigrationGeneratorSchema,\n type TsRdbGeneratorSchema,\n tsAgentGenerator,\n tsApiGenerator,\n tsAstroDocsGenerator,\n tsDcrProxyGenerator,\n tsDynamoDBGenerator,\n tsInfraGenerator,\n tsLambdaFunctionGenerator,\n tsMcpServerGenerator,\n tsNxGeneratorGenerator,\n tsNxMigrationGenerator,\n tsNxPluginGenerator,\n tsProjectGenerator,\n tsRdbGenerator,\n tsWebsiteAuthGenerator,\n tsWebsiteGenerator,\n} from '../../sdk/ts.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { toSnakeCase } from '../../utils/names.js';\nimport { getNpmScope, getNpmScopePrefix } from '../../utils/npm-scope.js';\nimport type { InternalTestMatrixGeneratorSchema } from './schema';\n\n/**\n * Scaffolds every generator, component and connection permutation the e2e tests\n * cover, by composing the generators in-process on a single tree.\n *\n * This ships with the plugin so each released version carries the matrix of the\n * generators *it* had. A test upgrading an old workspace scaffolds with the\n * released version's own matrix and never has to reason about which generators\n * existed when — driving the CLI from the test repo instead would couple the\n * test to a generator list that only describes today's plugin.\n *\n * Hidden and undocumented: it exists for the e2e suite, not for users.\n *\n * Options are typed against each generator's schema, so adding a required option\n * or changing an enum breaks the build here rather than silently reducing\n * coverage.\n *\n * Projects are generated with `preferInstallDependencies: false` by default and\n * the returned callback installs once. Nothing composed here reads the project\n * graph (only `ts#sync` does, which is not part of the matrix), so no\n * intermediate install is needed.\n */\nexport const internalTestMatrixGenerator = async (\n tree: Tree,\n options: InternalTestMatrixGeneratorSchema = {},\n): Promise<GeneratorCallback> => {\n const preferInstallDependencies = options.preferInstallDependencies ?? false;\n const defaults = { preferInstallDependencies };\n const projectDefaults = { ...defaults, directory: 'packages' };\n // Fully-qualified project names, which differ per language: TypeScript\n // projects are scope-prefixed, Python ones are dotted snake_case. Derived from\n // the workspace rather than hardcoded, so the matrix works in any workspace.\n const ts = (name: string) => `${getNpmScopePrefix(tree)}${name}`;\n const py = (name: string) =>\n `${toSnakeCase(getNpmScope(tree))}.${toSnakeCase(name)}`;\n\n // The infrastructure project every other generator deploys into. Which\n // generator owns it depends on the workspace's IaC provider, so the caller\n // asks for the one matching the workspace it created.\n if (options.infra === 'terraform') {\n await terraformProjectGenerator(tree, {\n name: 'infra',\n type: 'application',\n ...projectDefaults,\n });\n } else {\n await tsInfraGenerator(tree, { name: 'infra', ...projectDefaults });\n // A second CDK app with stage config, which only ts#infra offers.\n await tsInfraGenerator(tree, {\n name: 'infra-with-stages',\n stageConfig: true,\n ...projectDefaults,\n });\n }\n\n // Websites (with and without TanStack Router), a docs site, and auth on each.\n await tsWebsiteGenerator(tree, {\n name: 'website',\n iac: 'inherit',\n ...projectDefaults,\n });\n await tsWebsiteGenerator(tree, {\n name: 'website-no-router',\n tanstackRouter: false,\n iac: 'inherit',\n ...projectDefaults,\n });\n await tsAstroDocsGenerator(tree, { name: 'docs-site', ...defaults });\n await tsWebsiteAuthGenerator(tree, {\n project: ts('website'),\n cognitoDomain: 'test',\n allowSignup: true,\n iac: 'inherit',\n ...defaults,\n });\n await tsWebsiteAuthGenerator(tree, {\n project: ts('website-no-router'),\n cognitoDomain: 'test-no-router',\n allowSignup: true,\n iac: 'inherit',\n ...defaults,\n });\n\n // tRPC APIs — REST + HTTP, with Cognito and custom auth.\n const tsApis: TsApiGeneratorSchema[] = [\n { name: 'my-api', infra: 'rest-lambda', auth: 'iam', iac: 'inherit' },\n { name: 'my-api-http', infra: 'http-lambda', auth: 'iam', iac: 'inherit' },\n {\n name: 'my-api-custom',\n infra: 'rest-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'my-api-custom-http',\n infra: 'http-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'my-smithy-api',\n framework: 'smithy',\n infra: 'rest-lambda',\n auth: 'iam',\n iac: 'inherit',\n },\n ];\n for (const api of tsApis) {\n await tsApiGenerator(tree, { ...api, ...projectDefaults });\n }\n\n // A Smithy shape library; `my-smithy-api` covers consuming one.\n await smithyProjectGenerator(tree, {\n name: 'my-shapes',\n type: 'shapes',\n ...projectDefaults,\n });\n\n // Python FastAPI — REST + HTTP, with Cognito and custom auth.\n const pyApis: PyApiGeneratorSchema[] = [\n { name: 'py-api', infra: 'rest-lambda', auth: 'iam', iac: 'inherit' },\n { name: 'py-api-http', infra: 'http-lambda', auth: 'iam', iac: 'inherit' },\n {\n name: 'py-api-custom',\n infra: 'rest-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'py-api-custom-http',\n infra: 'http-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n ];\n for (const api of pyApis) {\n await pyApiGenerator(tree, { ...api, ...projectDefaults });\n }\n\n // Library projects hosting the components below, each with a lambda function.\n await pyProjectGenerator(tree, {\n name: 'py-project',\n type: 'application',\n ...projectDefaults,\n });\n await tsProjectGenerator(tree, { name: 'ts-project', ...projectDefaults });\n await pyLambdaFunctionGenerator(tree, {\n project: py('py-project'),\n name: 'my-function',\n event: 'Any',\n iac: 'inherit',\n ...defaults,\n });\n await tsLambdaFunctionGenerator(tree, {\n project: 'ts-project',\n name: 'my-function',\n event: 'Any',\n iac: 'inherit',\n ...defaults,\n });\n\n // MCP servers — uninfra'd and hosted on AgentCore.\n await pyMcpServerGenerator(tree, {\n project: 'py_project',\n name: 'my-mcp-server',\n infra: 'agentcore',\n iac: 'inherit',\n ...defaults,\n });\n await tsMcpServerGenerator(tree, {\n project: 'ts-project',\n name: 'my-mcp-server',\n infra: 'none',\n iac: 'inherit',\n ...defaults,\n });\n await tsMcpServerGenerator(tree, {\n project: 'ts-project',\n name: 'hosted-mcp-server',\n infra: 'agentcore',\n iac: 'inherit',\n ...defaults,\n });\n\n // OAuth DCR proxy for Cognito-authenticated MCP servers.\n await tsDcrProxyGenerator(tree, {\n name: 'my-dcr-proxy',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // TypeScript agents across every protocol and auth permutation. The unnamed\n // one takes the generator's default name, which the connections below use.\n const tsAgents: TsAgentGeneratorSchema[] = [\n {\n project: 'ts-project',\n name: 'my-ts-agent',\n infra: 'none',\n iac: 'inherit',\n },\n { project: 'ts-project', infra: 'agentcore', iac: 'inherit' },\n {\n project: 'ts-project',\n name: 'my-ts-a2a-agent',\n protocol: 'a2a',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'ts-project',\n name: 'my-ts-a2a-agent-cognito',\n protocol: 'a2a',\n auth: 'cognito',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'ts-project',\n name: 'my-ts-agui-agent',\n protocol: 'ag-ui',\n infra: 'agentcore',\n iac: 'inherit',\n },\n ];\n for (const agent of tsAgents) {\n await tsAgentGenerator(tree, { ...agent, ...defaults });\n }\n\n // Python agents: Strands across every protocol, plus LangChain in its own\n // project — langchain's dependency closure would push the zip-bundled Lambda\n // in py-project past its unzipped size limit.\n const pyAgents: PyAgentGeneratorSchema[] = [\n {\n project: 'py_project',\n name: 'my-agent',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-a2a-agent',\n protocol: 'a2a',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-a2a-agent-cognito',\n protocol: 'a2a',\n auth: 'cognito',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-agui-agent',\n protocol: 'ag-ui',\n infra: 'agentcore',\n iac: 'inherit',\n },\n ];\n for (const agent of pyAgents) {\n await pyAgentGenerator(tree, { ...agent, ...defaults });\n }\n await pyProjectGenerator(tree, {\n name: 'py-langchain-project',\n type: 'application',\n ...projectDefaults,\n });\n const langchainAgents: PyAgentGeneratorSchema[] = [\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-agent',\n protocol: 'ag-ui',\n iac: 'inherit',\n },\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-http-agent',\n protocol: 'http',\n iac: 'inherit',\n },\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-a2a-agent',\n protocol: 'a2a',\n iac: 'inherit',\n },\n ];\n for (const agent of langchainAgents) {\n await pyAgentGenerator(tree, {\n ...agent,\n framework: 'langchain',\n infra: 'agentcore',\n ...defaults,\n });\n }\n\n // AgentCore gateways, including a parent fronting the first (chained), and\n // an http-protocol gateway fronting agent runtime targets.\n await agentcoreGatewayGenerator(tree, {\n name: 'my-gateway',\n iac: 'inherit',\n ...projectDefaults,\n });\n await agentcoreGatewayGenerator(tree, {\n name: 'parent-gateway',\n iac: 'inherit',\n ...projectDefaults,\n });\n await agentcoreGatewayGenerator(tree, {\n name: 'agent-gateway',\n protocol: 'http',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // AgentCore Harness — a standalone invocation project.\n await agentcoreHarnessGenerator(tree, {\n name: 'my-harness',\n infra: 'agentcore',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // Databases — DynamoDB, plus Aurora across both engines and ORMs.\n await tsDynamoDBGenerator(tree, {\n name: 'my-table',\n framework: 'electrodb',\n infra: 'dynamodb',\n iac: 'inherit',\n ...projectDefaults,\n });\n await pyDynamoDBGenerator(tree, {\n name: 'my-py-table',\n framework: 'pynamodb',\n infra: 'dynamodb',\n iac: 'inherit',\n ...projectDefaults,\n });\n const tsRdbs: TsRdbGeneratorSchema[] = [\n {\n name: 'postgres-db',\n infra: 'aurora',\n engine: 'postgres',\n framework: 'prisma',\n iac: 'inherit',\n },\n {\n name: 'my-sql-db',\n infra: 'aurora',\n engine: 'mysql',\n framework: 'prisma',\n iac: 'inherit',\n },\n ];\n for (const rdb of tsRdbs) {\n await tsRdbGenerator(tree, { ...rdb, ...projectDefaults });\n }\n const pyRdbs: PyRdbGeneratorSchema[] = [\n {\n name: 'py-postgres-db',\n infra: 'aurora',\n engine: 'postgres',\n framework: 'sqlmodel',\n iac: 'inherit',\n },\n {\n name: 'py-mysql-db',\n infra: 'aurora',\n engine: 'mysql',\n framework: 'sqlmodel',\n iac: 'inherit',\n },\n ];\n for (const rdb of pyRdbs) {\n await pyRdbGenerator(tree, { ...rdb, ...projectDefaults });\n }\n\n // Every connection edge the matrix covers.\n const connections: ConnectionGeneratorSchema[] = [\n // Website -> API\n { sourceProject: ts('website'), targetProject: ts('my-api') },\n { sourceProject: ts('website-no-router'), targetProject: ts('my-api') },\n { sourceProject: 'website', targetProject: 'py_api' },\n { sourceProject: 'website', targetProject: 'my-smithy-api' },\n // Agent -> MCP server\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-ts-agui-agent',\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n // HTTP agent <-> A2A agent\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n // Agent -> gateway, gateway -> MCP server, gateway -> gateway\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: ts('my-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: ts('my-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n { sourceProject: ts('parent-gateway'), targetProject: ts('my-gateway') },\n // Gateway -> agent (http gateway fronting agent runtime targets: every\n // supported protocol permutation), then website -> gateway.\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-agui-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-py-agui-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: ts('website-no-router'),\n targetProject: ts('agent-gateway'),\n },\n // Website -> agent\n {\n sourceProject: ts('website'),\n targetProject: 'ts-project',\n targetComponent: 'agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-agui-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_project',\n targetComponent: 'my-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_project',\n targetComponent: 'my-py-agui-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_langchain_project',\n targetComponent: 'my-py-langchain-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_langchain_project',\n targetComponent: 'my-py-langchain-http-agent',\n },\n // DynamoDB\n { sourceProject: 'my-api', targetProject: ts('my-table') },\n { sourceProject: 'my-smithy-api', targetProject: ts('my-table') },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-ts-agent',\n targetProject: ts('my-table'),\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-mcp-server',\n targetProject: ts('my-table'),\n },\n { sourceProject: 'py_api', targetProject: 'my_py_table' },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'my_py_table',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-mcp-server',\n targetProject: 'my_py_table',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-http-agent',\n targetProject: 'my_py_table',\n },\n // Relational databases\n { sourceProject: 'py_api', targetProject: 'py_postgres_db' },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_postgres_db',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-mcp-server',\n targetProject: 'py_postgres_db',\n },\n ];\n for (const connection of connections) {\n await connectionGenerator(tree, { ...connection, ...defaults });\n }\n\n // Licensing, then an Nx plugin with a custom generator.\n await licenseGenerator(tree, {\n license: 'Apache-2.0',\n copyrightHolder: 'Amazon.com, Inc. or its affiliates',\n ...defaults,\n });\n await tsNxPluginGenerator(tree, {\n ...projectDefaults,\n name: 'plugin',\n directory: 'tools',\n });\n await tsNxGeneratorGenerator(tree, {\n project: ts('plugin'),\n name: 'my#generator',\n ...defaults,\n });\n\n // A migration of each kind, so the scaffolded codemods compile and the\n // plugin's migrations.json (created by the first run) registers all three.\n const migrations: Omit<TsNxMigrationGeneratorSchema, 'project'>[] = [\n {\n name: 'rename-foo-target',\n description: 'Rename the foo target to bar',\n },\n {\n name: 'migrate-custom-handlers',\n description: 'Update custom handlers for the new API',\n kind: 'agentic',\n },\n {\n name: 'upgrade-framework',\n description: 'Upgrade the framework and reconcile call sites',\n kind: 'hybrid',\n },\n ];\n for (const migration of migrations) {\n await tsNxMigrationGenerator(tree, {\n ...migration,\n project: ts('plugin'),\n ...defaults,\n });\n }\n\n return () =>\n installDependencies(tree, preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default internalTestMatrixGenerator;\n"],"names":["agentcoreGatewayGenerator","agentcoreHarnessGenerator","connectionGenerator","licenseGenerator","pyAgentGenerator","pyApiGenerator","pyDynamoDBGenerator","pyLambdaFunctionGenerator","pyMcpServerGenerator","pyProjectGenerator","pyRdbGenerator","smithyProjectGenerator","terraformProjectGenerator","tsAgentGenerator","tsApiGenerator","tsAstroDocsGenerator","tsDcrProxyGenerator","tsDynamoDBGenerator","tsInfraGenerator","tsLambdaFunctionGenerator","tsMcpServerGenerator","tsNxGeneratorGenerator","tsNxMigrationGenerator","tsNxPluginGenerator","tsProjectGenerator","tsRdbGenerator","tsWebsiteAuthGenerator","tsWebsiteGenerator","installDependencies","toSnakeCase","getNpmScope","getNpmScopePrefix","internalTestMatrixGenerator","tree","options","preferInstallDependencies","defaults","projectDefaults","directory","ts","name","py","infra","type","stageConfig","iac","tanstackRouter","project","cognitoDomain","allowSignup","tsApis","auth","framework","api","pyApis","event","tsAgents","protocol","agent","pyAgents","langchainAgents","tsRdbs","engine","rdb","pyRdbs","connections","sourceProject","targetProject","sourceComponent","targetComponent","connection","license","copyrightHolder","migrations","description","kind","migration","languages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/internal/test-matrix/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { GeneratorCallback, Tree } from '@nx/devkit';\nimport { agentcoreGatewayGenerator } from '../../sdk/agentcore-gateway.js';\nimport { agentcoreHarnessGenerator } from '../../sdk/agentcore-harness.js';\nimport {\n type ConnectionGeneratorSchema,\n connectionGenerator,\n} from '../../sdk/connection.js';\nimport { licenseGenerator } from '../../sdk/license.js';\nimport {\n type PyAgentGeneratorSchema,\n type PyApiGeneratorSchema,\n type PyRdbGeneratorSchema,\n pyAgentGenerator,\n pyApiGenerator,\n pyDynamoDBGenerator,\n pyLambdaFunctionGenerator,\n pyMcpServerGenerator,\n pyProjectGenerator,\n pyRdbGenerator,\n} from '../../sdk/py.js';\nimport { smithyProjectGenerator } from '../../sdk/smithy.js';\nimport { terraformProjectGenerator } from '../../sdk/terraform.js';\nimport {\n type TsAgentGeneratorSchema,\n type TsApiGeneratorSchema,\n type TsNxMigrationGeneratorSchema,\n type TsRdbGeneratorSchema,\n tsAgentGenerator,\n tsApiGenerator,\n tsAstroDocsGenerator,\n tsDcrProxyGenerator,\n tsDynamoDBGenerator,\n tsInfraGenerator,\n tsLambdaFunctionGenerator,\n tsMcpServerGenerator,\n tsNxGeneratorGenerator,\n tsNxMigrationGenerator,\n tsNxPluginGenerator,\n tsProjectGenerator,\n tsRdbGenerator,\n tsWebsiteAuthGenerator,\n tsWebsiteGenerator,\n} from '../../sdk/ts.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { toSnakeCase } from '../../utils/names.js';\nimport { getNpmScope, getNpmScopePrefix } from '../../utils/npm-scope.js';\nimport type { InternalTestMatrixGeneratorSchema } from './schema';\n\n/**\n * Scaffolds every generator, component and connection permutation the e2e tests\n * cover, by composing the generators in-process on a single tree.\n *\n * This ships with the plugin so each released version carries the matrix of the\n * generators *it* had. A test upgrading an old workspace scaffolds with the\n * released version's own matrix and never has to reason about which generators\n * existed when — driving the CLI from the test repo instead would couple the\n * test to a generator list that only describes today's plugin.\n *\n * Hidden and undocumented: it exists for the e2e suite, not for users.\n *\n * Options are typed against each generator's schema, so adding a required option\n * or changing an enum breaks the build here rather than silently reducing\n * coverage.\n *\n * Projects are generated with `preferInstallDependencies: false` by default and\n * the returned callback installs once. Nothing composed here reads the project\n * graph (only `ts#sync` does, which is not part of the matrix), so no\n * intermediate install is needed.\n */\nexport const internalTestMatrixGenerator = async (\n tree: Tree,\n options: InternalTestMatrixGeneratorSchema = {},\n): Promise<GeneratorCallback> => {\n const preferInstallDependencies = options.preferInstallDependencies ?? false;\n const defaults = { preferInstallDependencies };\n const projectDefaults = { ...defaults, directory: 'packages' };\n // Fully-qualified project names, which differ per language: TypeScript\n // projects are scope-prefixed, Python ones are dotted snake_case. Derived from\n // the workspace rather than hardcoded, so the matrix works in any workspace.\n const ts = (name: string) => `${getNpmScopePrefix(tree)}${name}`;\n const py = (name: string) =>\n `${toSnakeCase(getNpmScope(tree))}.${toSnakeCase(name)}`;\n\n // The infrastructure project every other generator deploys into. Which\n // generator owns it depends on the workspace's IaC provider, so the caller\n // asks for the one matching the workspace it created.\n if (options.infra === 'terraform') {\n await terraformProjectGenerator(tree, {\n name: 'infra',\n type: 'application',\n ...projectDefaults,\n });\n } else {\n await tsInfraGenerator(tree, { name: 'infra', ...projectDefaults });\n // A second CDK app with stage config, which only ts#infra offers.\n await tsInfraGenerator(tree, {\n name: 'infra-with-stages',\n stageConfig: true,\n ...projectDefaults,\n });\n }\n\n // Websites (with and without TanStack Router), a docs site, and auth on each.\n await tsWebsiteGenerator(tree, {\n name: 'website',\n iac: 'inherit',\n ...projectDefaults,\n });\n await tsWebsiteGenerator(tree, {\n name: 'website-no-router',\n tanstackRouter: false,\n iac: 'inherit',\n ...projectDefaults,\n });\n await tsAstroDocsGenerator(tree, { name: 'docs-site', ...defaults });\n await tsWebsiteAuthGenerator(tree, {\n project: ts('website'),\n cognitoDomain: 'test',\n allowSignup: true,\n iac: 'inherit',\n ...defaults,\n });\n await tsWebsiteAuthGenerator(tree, {\n project: ts('website-no-router'),\n cognitoDomain: 'test-no-router',\n allowSignup: true,\n iac: 'inherit',\n ...defaults,\n });\n\n // tRPC APIs — REST + HTTP, with Cognito and custom auth.\n const tsApis: TsApiGeneratorSchema[] = [\n { name: 'my-api', infra: 'rest-lambda', auth: 'iam', iac: 'inherit' },\n { name: 'my-api-http', infra: 'http-lambda', auth: 'iam', iac: 'inherit' },\n // The APIs above take the default `isolated` integration pattern; these\n // cover `shared`.\n {\n name: 'my-api-shared',\n infra: 'rest-lambda',\n auth: 'iam',\n integrationPattern: 'shared',\n iac: 'inherit',\n },\n {\n name: 'my-api-shared-http',\n infra: 'http-lambda',\n auth: 'iam',\n integrationPattern: 'shared',\n iac: 'inherit',\n },\n {\n name: 'my-api-custom',\n infra: 'rest-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'my-api-custom-http',\n infra: 'http-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'my-smithy-api',\n framework: 'smithy',\n infra: 'rest-lambda',\n auth: 'iam',\n iac: 'inherit',\n },\n ];\n for (const api of tsApis) {\n await tsApiGenerator(tree, { ...api, ...projectDefaults });\n }\n\n // A Smithy shape library; `my-smithy-api` covers consuming one.\n await smithyProjectGenerator(tree, {\n name: 'my-shapes',\n type: 'shapes',\n ...projectDefaults,\n });\n\n // Python FastAPI — REST + HTTP, with Cognito and custom auth.\n const pyApis: PyApiGeneratorSchema[] = [\n { name: 'py-api', infra: 'rest-lambda', auth: 'iam', iac: 'inherit' },\n { name: 'py-api-http', infra: 'http-lambda', auth: 'iam', iac: 'inherit' },\n {\n name: 'py-api-custom',\n infra: 'rest-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'py-api-custom-http',\n infra: 'http-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n ];\n for (const api of pyApis) {\n await pyApiGenerator(tree, { ...api, ...projectDefaults });\n }\n\n // Library projects hosting the components below, each with a lambda function.\n await pyProjectGenerator(tree, {\n name: 'py-project',\n type: 'application',\n ...projectDefaults,\n });\n await tsProjectGenerator(tree, { name: 'ts-project', ...projectDefaults });\n await pyLambdaFunctionGenerator(tree, {\n project: py('py-project'),\n name: 'my-function',\n event: 'Any',\n iac: 'inherit',\n ...defaults,\n });\n await tsLambdaFunctionGenerator(tree, {\n project: 'ts-project',\n name: 'my-function',\n event: 'Any',\n iac: 'inherit',\n ...defaults,\n });\n\n // MCP servers — uninfra'd and hosted on AgentCore.\n await pyMcpServerGenerator(tree, {\n project: 'py_project',\n name: 'my-mcp-server',\n infra: 'agentcore',\n iac: 'inherit',\n ...defaults,\n });\n await tsMcpServerGenerator(tree, {\n project: 'ts-project',\n name: 'my-mcp-server',\n infra: 'none',\n iac: 'inherit',\n ...defaults,\n });\n await tsMcpServerGenerator(tree, {\n project: 'ts-project',\n name: 'hosted-mcp-server',\n infra: 'agentcore',\n iac: 'inherit',\n ...defaults,\n });\n\n // OAuth DCR proxy for Cognito-authenticated MCP servers.\n await tsDcrProxyGenerator(tree, {\n name: 'my-dcr-proxy',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // TypeScript agents across every protocol and auth permutation. The unnamed\n // one takes the generator's default name, which the connections below use.\n const tsAgents: TsAgentGeneratorSchema[] = [\n {\n project: 'ts-project',\n name: 'my-ts-agent',\n infra: 'none',\n iac: 'inherit',\n },\n { project: 'ts-project', infra: 'agentcore', iac: 'inherit' },\n {\n project: 'ts-project',\n name: 'my-ts-a2a-agent',\n protocol: 'a2a',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'ts-project',\n name: 'my-ts-a2a-agent-cognito',\n protocol: 'a2a',\n auth: 'cognito',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'ts-project',\n name: 'my-ts-agui-agent',\n protocol: 'ag-ui',\n infra: 'agentcore',\n iac: 'inherit',\n },\n ];\n for (const agent of tsAgents) {\n await tsAgentGenerator(tree, { ...agent, ...defaults });\n }\n\n // Python agents: Strands across every protocol, plus LangChain in its own\n // project — langchain's dependency closure would push the zip-bundled Lambda\n // in py-project past its unzipped size limit.\n const pyAgents: PyAgentGeneratorSchema[] = [\n {\n project: 'py_project',\n name: 'my-agent',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-a2a-agent',\n protocol: 'a2a',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-a2a-agent-cognito',\n protocol: 'a2a',\n auth: 'cognito',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-agui-agent',\n protocol: 'ag-ui',\n infra: 'agentcore',\n iac: 'inherit',\n },\n ];\n for (const agent of pyAgents) {\n await pyAgentGenerator(tree, { ...agent, ...defaults });\n }\n await pyProjectGenerator(tree, {\n name: 'py-langchain-project',\n type: 'application',\n ...projectDefaults,\n });\n const langchainAgents: PyAgentGeneratorSchema[] = [\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-agent',\n protocol: 'ag-ui',\n iac: 'inherit',\n },\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-http-agent',\n protocol: 'http',\n iac: 'inherit',\n },\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-a2a-agent',\n protocol: 'a2a',\n iac: 'inherit',\n },\n ];\n for (const agent of langchainAgents) {\n await pyAgentGenerator(tree, {\n ...agent,\n framework: 'langchain',\n infra: 'agentcore',\n ...defaults,\n });\n }\n\n // AgentCore gateways, including a parent fronting the first (chained), and\n // an http-protocol gateway fronting agent runtime targets.\n await agentcoreGatewayGenerator(tree, {\n name: 'my-gateway',\n iac: 'inherit',\n ...projectDefaults,\n });\n await agentcoreGatewayGenerator(tree, {\n name: 'parent-gateway',\n iac: 'inherit',\n ...projectDefaults,\n });\n await agentcoreGatewayGenerator(tree, {\n name: 'agent-gateway',\n protocol: 'http',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // AgentCore Harness — a standalone invocation project.\n await agentcoreHarnessGenerator(tree, {\n name: 'my-harness',\n infra: 'agentcore',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // Databases — DynamoDB, plus Aurora across both engines and ORMs.\n await tsDynamoDBGenerator(tree, {\n name: 'my-table',\n framework: 'electrodb',\n infra: 'dynamodb',\n iac: 'inherit',\n ...projectDefaults,\n });\n await pyDynamoDBGenerator(tree, {\n name: 'my-py-table',\n framework: 'pynamodb',\n infra: 'dynamodb',\n iac: 'inherit',\n ...projectDefaults,\n });\n const tsRdbs: TsRdbGeneratorSchema[] = [\n {\n name: 'postgres-db',\n infra: 'aurora',\n engine: 'postgres',\n framework: 'prisma',\n iac: 'inherit',\n },\n {\n name: 'my-sql-db',\n infra: 'aurora',\n engine: 'mysql',\n framework: 'prisma',\n iac: 'inherit',\n },\n ];\n for (const rdb of tsRdbs) {\n await tsRdbGenerator(tree, { ...rdb, ...projectDefaults });\n }\n const pyRdbs: PyRdbGeneratorSchema[] = [\n {\n name: 'py-postgres-db',\n infra: 'aurora',\n engine: 'postgres',\n framework: 'sqlmodel',\n iac: 'inherit',\n },\n {\n name: 'py-mysql-db',\n infra: 'aurora',\n engine: 'mysql',\n framework: 'sqlmodel',\n iac: 'inherit',\n },\n ];\n for (const rdb of pyRdbs) {\n await pyRdbGenerator(tree, { ...rdb, ...projectDefaults });\n }\n\n // Every connection edge the matrix covers.\n const connections: ConnectionGeneratorSchema[] = [\n // Website -> API\n { sourceProject: ts('website'), targetProject: ts('my-api') },\n { sourceProject: ts('website-no-router'), targetProject: ts('my-api') },\n { sourceProject: 'website', targetProject: 'py_api' },\n { sourceProject: 'website', targetProject: 'my-smithy-api' },\n // Agent -> MCP server\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-ts-agui-agent',\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n // HTTP agent <-> A2A agent\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n // Agent -> gateway, gateway -> MCP server, gateway -> gateway\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: ts('my-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: ts('my-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n { sourceProject: ts('parent-gateway'), targetProject: ts('my-gateway') },\n // Gateway -> agent (http gateway fronting agent runtime targets: every\n // supported protocol permutation), then website -> gateway.\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-agui-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-py-agui-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: ts('website-no-router'),\n targetProject: ts('agent-gateway'),\n },\n // Website -> agent\n {\n sourceProject: ts('website'),\n targetProject: 'ts-project',\n targetComponent: 'agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-agui-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_project',\n targetComponent: 'my-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_project',\n targetComponent: 'my-py-agui-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_langchain_project',\n targetComponent: 'my-py-langchain-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_langchain_project',\n targetComponent: 'my-py-langchain-http-agent',\n },\n // DynamoDB\n { sourceProject: 'my-api', targetProject: ts('my-table') },\n { sourceProject: 'my-smithy-api', targetProject: ts('my-table') },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-ts-agent',\n targetProject: ts('my-table'),\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-mcp-server',\n targetProject: ts('my-table'),\n },\n { sourceProject: 'py_api', targetProject: 'my_py_table' },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'my_py_table',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-mcp-server',\n targetProject: 'my_py_table',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-http-agent',\n targetProject: 'my_py_table',\n },\n // Relational databases\n { sourceProject: 'py_api', targetProject: 'py_postgres_db' },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_postgres_db',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-mcp-server',\n targetProject: 'py_postgres_db',\n },\n ];\n for (const connection of connections) {\n await connectionGenerator(tree, { ...connection, ...defaults });\n }\n\n // Licensing, then an Nx plugin with a custom generator.\n await licenseGenerator(tree, {\n license: 'Apache-2.0',\n copyrightHolder: 'Amazon.com, Inc. or its affiliates',\n ...defaults,\n });\n await tsNxPluginGenerator(tree, {\n ...projectDefaults,\n name: 'plugin',\n directory: 'tools',\n });\n await tsNxGeneratorGenerator(tree, {\n project: ts('plugin'),\n name: 'my#generator',\n ...defaults,\n });\n\n // A migration of each kind, so the scaffolded codemods compile and the\n // plugin's migrations.json (created by the first run) registers all three.\n const migrations: Omit<TsNxMigrationGeneratorSchema, 'project'>[] = [\n {\n name: 'rename-foo-target',\n description: 'Rename the foo target to bar',\n },\n {\n name: 'migrate-custom-handlers',\n description: 'Update custom handlers for the new API',\n kind: 'agentic',\n },\n {\n name: 'upgrade-framework',\n description: 'Upgrade the framework and reconcile call sites',\n kind: 'hybrid',\n },\n ];\n for (const migration of migrations) {\n await tsNxMigrationGenerator(tree, {\n ...migration,\n project: ts('plugin'),\n ...defaults,\n });\n }\n\n return () =>\n installDependencies(tree, preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default internalTestMatrixGenerator;\n"],"names":["agentcoreGatewayGenerator","agentcoreHarnessGenerator","connectionGenerator","licenseGenerator","pyAgentGenerator","pyApiGenerator","pyDynamoDBGenerator","pyLambdaFunctionGenerator","pyMcpServerGenerator","pyProjectGenerator","pyRdbGenerator","smithyProjectGenerator","terraformProjectGenerator","tsAgentGenerator","tsApiGenerator","tsAstroDocsGenerator","tsDcrProxyGenerator","tsDynamoDBGenerator","tsInfraGenerator","tsLambdaFunctionGenerator","tsMcpServerGenerator","tsNxGeneratorGenerator","tsNxMigrationGenerator","tsNxPluginGenerator","tsProjectGenerator","tsRdbGenerator","tsWebsiteAuthGenerator","tsWebsiteGenerator","installDependencies","toSnakeCase","getNpmScope","getNpmScopePrefix","internalTestMatrixGenerator","tree","options","preferInstallDependencies","defaults","projectDefaults","directory","ts","name","py","infra","type","stageConfig","iac","tanstackRouter","project","cognitoDomain","allowSignup","tsApis","auth","integrationPattern","framework","api","pyApis","event","tsAgents","protocol","agent","pyAgents","langchainAgents","tsRdbs","engine","rdb","pyRdbs","connections","sourceProject","targetProject","sourceComponent","targetComponent","connection","license","copyrightHolder","migrations","description","kind","migration","languages"],"mappings":"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"}
|
package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type MigrationReturnObject, type Tree } from '@nx/devkit';
|
|
6
|
+
export default function migration(tree: Tree): Promise<MigrationReturnObject>;
|
package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { generateFiles, getProjects, joinPathFragments, OverwriteStrategy, updateProjectConfiguration } from "@nx/devkit";
|
|
5
|
+
import { TERRAFORM_PROJECT_GENERATOR_INFO } from "../../../terraform/project/generator.js";
|
|
6
|
+
import { applyGritQL, matchGritQL } from "../../../utils/ast.js";
|
|
7
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
8
|
+
import { kebabCase } from "../../../utils/names.js";
|
|
9
|
+
import { normalizeTargetKeyOrder } from "../../../utils/nx.js";
|
|
10
|
+
import { sortObjectKeys } from "../../../utils/object.js";
|
|
11
|
+
/**
|
|
12
|
+
* Terraform projects gained three fixes:
|
|
13
|
+
*
|
|
14
|
+
* - A `checkov` target carries the security scan, matching the name CDK
|
|
15
|
+
* infrastructure projects already use, so `nx run-many --target checkov` no
|
|
16
|
+
* longer skips Terraform projects. An existing `test` target is the user's,
|
|
17
|
+
* so it is left exactly as it is.
|
|
18
|
+
* - A `checkov.yml` gives Terraform users the same central place to configure
|
|
19
|
+
* skips that the CDK app has, wired in via `--config-file`.
|
|
20
|
+
* - `bootstrap-destroy` runs a script that resolves the region from the AWS SDK
|
|
21
|
+
* credential chain and passes it as `-var=aws_region`. The vended
|
|
22
|
+
* `aws_region` variable has no default, so the previous bare
|
|
23
|
+
* `terraform destroy` blocked forever on an input prompt in any non-TTY
|
|
24
|
+
* context.
|
|
25
|
+
* - Both vended `providers.tf` declare `required_version = ">= 1.0"`, matching
|
|
26
|
+
* every other `.tf` file the plugin vends, and the bootstrap one pins the AWS
|
|
27
|
+
* provider.
|
|
28
|
+
*
|
|
29
|
+
* How to write a migration:
|
|
30
|
+
* - https://nx.dev/docs/kb/migration-generators
|
|
31
|
+
* - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject
|
|
32
|
+
*/ const hcl = (pattern)=>`language hcl\n${pattern}`;
|
|
33
|
+
/** The scan command, as the pre-fix generator vended it on `test`. */ const CHECKOV_COMMAND_PATTERN = /uvx --from checkov==/;
|
|
34
|
+
const divergedTargetsStep = (projectName)=>`${projectName}: no 'test' target carrying the checkov scan was found, so no 'checkov' target was added - add one running checkov over the project so 'nx run-many --target checkov' includes this project.`;
|
|
35
|
+
const divergedProvidersStep = (filePath)=>`${filePath}: has diverged from the generated shape - left untouched. Add \`required_version = ">= 1.0"\` to its \`terraform\` block to pin the minimum Terraform version.`;
|
|
36
|
+
const divergedBootstrapDestroyStep = (projectName)=>`${projectName}: its 'bootstrap-destroy' target no longer matches the shape the generator produced - left untouched. Pass \`-var=aws_region=<region>\` to \`terraform destroy\`, otherwise it blocks on an input prompt when run without a TTY.`;
|
|
37
|
+
/**
|
|
38
|
+
* Add `required_version` to a `providers.tf` that omits it.
|
|
39
|
+
*
|
|
40
|
+
* The bootstrap copy has no `terraform` block at all, so it is created;
|
|
41
|
+
* the src copy has one holding `required_providers`, so it is added to.
|
|
42
|
+
*/ const migrateRequiredVersion = async (tree, filePath, nextSteps)=>{
|
|
43
|
+
if (!tree.exists(filePath)) return;
|
|
44
|
+
// Already declared - nothing to do, whatever constraint the user chose.
|
|
45
|
+
if (await matchGritQL(tree, filePath, hcl('`required_version = $_`'))) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const hasRequiredProviders = await matchGritQL(tree, filePath, hcl('`terraform { $body }` where { $body <: contains `required_providers` }'));
|
|
49
|
+
if (hasRequiredProviders) {
|
|
50
|
+
await applyGritQL(tree, filePath, hcl('`terraform { $body }` => `terraform {\n required_version = ">= 1.0"\n\n $body\n}`'));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// No `terraform` block: prepend one ahead of the aws provider block.
|
|
54
|
+
const providerBlock = hcl('`provider "aws" { $body }`');
|
|
55
|
+
if (!await matchGritQL(tree, filePath, providerBlock)) {
|
|
56
|
+
nextSteps.push(divergedProvidersStep(filePath));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
await applyGritQL(tree, filePath, hcl('`provider "aws" { $body }` => `terraform {\n required_version = ">= 1.0"\n}\n\nprovider "aws" {\n $body\n}`'));
|
|
60
|
+
};
|
|
61
|
+
export default async function migration(tree) {
|
|
62
|
+
const nextSteps = [];
|
|
63
|
+
for (const [projectName, project] of getProjects(tree)){
|
|
64
|
+
const generator = project.metadata?.generator;
|
|
65
|
+
if (generator !== TERRAFORM_PROJECT_GENERATOR_INFO.id) continue;
|
|
66
|
+
const targets = project.targets ?? {};
|
|
67
|
+
let changed = false;
|
|
68
|
+
// Add `checkov`, copying the scan from the `test` target the pre-fix
|
|
69
|
+
// generator put it on. `test` itself belongs to the user and is left as it
|
|
70
|
+
// is. Guarded on `checkov` being absent so a re-run is a no-op.
|
|
71
|
+
if (!targets.checkov) {
|
|
72
|
+
const command = targets.test?.options?.command;
|
|
73
|
+
if (typeof command !== 'string' || !CHECKOV_COMMAND_PATTERN.test(command)) {
|
|
74
|
+
nextSteps.push(divergedTargetsStep(projectName));
|
|
75
|
+
} else {
|
|
76
|
+
// The config file is vended below, so wire it in at the same time.
|
|
77
|
+
const withConfigFile = command.includes('--config-file') ? command : command.replace('checkov --directory', 'checkov --config-file ../checkov.yml --directory');
|
|
78
|
+
targets.checkov = normalizeTargetKeyOrder({
|
|
79
|
+
...targets.test,
|
|
80
|
+
options: {
|
|
81
|
+
...targets.test.options,
|
|
82
|
+
command: withConfigFile
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
changed = true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Point `bootstrap-destroy` at the vended script, which resolves the
|
|
89
|
+
// region rather than leaving terraform to prompt for it.
|
|
90
|
+
const bootstrapDestroy = targets['bootstrap-destroy'];
|
|
91
|
+
if (bootstrapDestroy) {
|
|
92
|
+
const scriptCommand = `tsx {projectRoot}/scripts/bootstrap-destroy.ts {projectRoot}`;
|
|
93
|
+
const alreadyMigrated = bootstrapDestroy.options?.commands?.[0] === scriptCommand;
|
|
94
|
+
if (!alreadyMigrated) {
|
|
95
|
+
const command = bootstrapDestroy.options?.command;
|
|
96
|
+
// Only rewrite the exact shape the generator produced.
|
|
97
|
+
const isVendedShape = typeof command === 'string' && /^terraform destroy -state=\S+bootstrap\.tfstate$/.test(command.trim());
|
|
98
|
+
if (!isVendedShape) {
|
|
99
|
+
nextSteps.push(divergedBootstrapDestroyStep(projectName));
|
|
100
|
+
} else {
|
|
101
|
+
targets['bootstrap-destroy'] = normalizeTargetKeyOrder({
|
|
102
|
+
executor: bootstrapDestroy.executor,
|
|
103
|
+
options: {
|
|
104
|
+
forwardAllArgs: true,
|
|
105
|
+
commands: [
|
|
106
|
+
scriptCommand
|
|
107
|
+
],
|
|
108
|
+
cwd: '{workspaceRoot}'
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
changed = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (changed) {
|
|
116
|
+
updateProjectConfiguration(tree, projectName, {
|
|
117
|
+
...project,
|
|
118
|
+
targets: sortObjectKeys(targets)
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
// Vend the checkov config and the bootstrap-destroy script. KeepExisting
|
|
122
|
+
// leaves a user's own copy alone and makes a re-run a no-op.
|
|
123
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, '../../../terraform/project/files/checkov'), project.root, {}, {
|
|
124
|
+
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
125
|
+
});
|
|
126
|
+
// Only application projects have a bootstrap dir to destroy. The scripts
|
|
127
|
+
// dir is shared with the generator's templates, so `stateKeyPrefix` is
|
|
128
|
+
// resolved the same way it computes it; KeepExisting leaves the scripts
|
|
129
|
+
// that already exist untouched regardless.
|
|
130
|
+
if (tree.exists(joinPathFragments(project.root, 'bootstrap'))) {
|
|
131
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, '../../../terraform/project/files/application/scripts'), joinPathFragments(project.root, 'scripts'), {
|
|
132
|
+
stateKeyPrefix: kebabCase(projectName)
|
|
133
|
+
}, {
|
|
134
|
+
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
await migrateRequiredVersion(tree, joinPathFragments(project.root, 'src/providers.tf'), nextSteps);
|
|
138
|
+
await migrateRequiredVersion(tree, joinPathFragments(project.root, 'bootstrap/providers.tf'), nextSteps);
|
|
139
|
+
}
|
|
140
|
+
await formatFilesInSubtree(tree);
|
|
141
|
+
return {
|
|
142
|
+
nextSteps
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n getProjects,\n joinPathFragments,\n type MigrationReturnObject,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { TERRAFORM_PROJECT_GENERATOR_INFO } from '../../../terraform/project/generator.js';\nimport { applyGritQL, matchGritQL } from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport { kebabCase } from '../../../utils/names.js';\nimport { normalizeTargetKeyOrder } from '../../../utils/nx.js';\nimport { sortObjectKeys } from '../../../utils/object.js';\n\n/**\n * Terraform projects gained three fixes:\n *\n * - A `checkov` target carries the security scan, matching the name CDK\n * infrastructure projects already use, so `nx run-many --target checkov` no\n * longer skips Terraform projects. An existing `test` target is the user's,\n * so it is left exactly as it is.\n * - A `checkov.yml` gives Terraform users the same central place to configure\n * skips that the CDK app has, wired in via `--config-file`.\n * - `bootstrap-destroy` runs a script that resolves the region from the AWS SDK\n * credential chain and passes it as `-var=aws_region`. The vended\n * `aws_region` variable has no default, so the previous bare\n * `terraform destroy` blocked forever on an input prompt in any non-TTY\n * context.\n * - Both vended `providers.tf` declare `required_version = \">= 1.0\"`, matching\n * every other `.tf` file the plugin vends, and the bootstrap one pins the AWS\n * provider.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n */\n\nconst hcl = (pattern: string) => `language hcl\\n${pattern}`;\n\n/** The scan command, as the pre-fix generator vended it on `test`. */\nconst CHECKOV_COMMAND_PATTERN = /uvx --from checkov==/;\n\nconst divergedTargetsStep = (projectName: string) =>\n `${projectName}: no 'test' target carrying the checkov scan was found, so no 'checkov' target was added - add one running checkov over the project so 'nx run-many --target checkov' includes this project.`;\n\nconst divergedProvidersStep = (filePath: string) =>\n `${filePath}: has diverged from the generated shape - left untouched. Add \\`required_version = \">= 1.0\"\\` to its \\`terraform\\` block to pin the minimum Terraform version.`;\n\nconst divergedBootstrapDestroyStep = (projectName: string) =>\n `${projectName}: its 'bootstrap-destroy' target no longer matches the shape the generator produced - left untouched. Pass \\`-var=aws_region=<region>\\` to \\`terraform destroy\\`, otherwise it blocks on an input prompt when run without a TTY.`;\n\n/**\n * Add `required_version` to a `providers.tf` that omits it.\n *\n * The bootstrap copy has no `terraform` block at all, so it is created;\n * the src copy has one holding `required_providers`, so it is added to.\n */\nconst migrateRequiredVersion = async (\n tree: Tree,\n filePath: string,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(filePath)) return;\n\n // Already declared - nothing to do, whatever constraint the user chose.\n if (await matchGritQL(tree, filePath, hcl('`required_version = $_`'))) {\n return;\n }\n\n const hasRequiredProviders = await matchGritQL(\n tree,\n filePath,\n hcl(\n '`terraform { $body }` where { $body <: contains `required_providers` }',\n ),\n );\n\n if (hasRequiredProviders) {\n await applyGritQL(\n tree,\n filePath,\n hcl(\n '`terraform { $body }` => `terraform {\\n required_version = \">= 1.0\"\\n\\n $body\\n}`',\n ),\n );\n return;\n }\n\n // No `terraform` block: prepend one ahead of the aws provider block.\n const providerBlock = hcl('`provider \"aws\" { $body }`');\n if (!(await matchGritQL(tree, filePath, providerBlock))) {\n nextSteps.push(divergedProvidersStep(filePath));\n return;\n }\n\n await applyGritQL(\n tree,\n filePath,\n hcl(\n '`provider \"aws\" { $body }` => `terraform {\\n required_version = \">= 1.0\"\\n}\\n\\nprovider \"aws\" {\\n $body\\n}`',\n ),\n );\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n for (const [projectName, project] of getProjects(tree)) {\n const generator = (project.metadata as { generator?: string } | undefined)\n ?.generator;\n if (generator !== TERRAFORM_PROJECT_GENERATOR_INFO.id) continue;\n\n const targets = project.targets ?? {};\n let changed = false;\n\n // Add `checkov`, copying the scan from the `test` target the pre-fix\n // generator put it on. `test` itself belongs to the user and is left as it\n // is. Guarded on `checkov` being absent so a re-run is a no-op.\n if (!targets.checkov) {\n const command = targets.test?.options?.command;\n\n if (\n typeof command !== 'string' ||\n !CHECKOV_COMMAND_PATTERN.test(command)\n ) {\n nextSteps.push(divergedTargetsStep(projectName));\n } else {\n // The config file is vended below, so wire it in at the same time.\n const withConfigFile = command.includes('--config-file')\n ? command\n : command.replace(\n 'checkov --directory',\n 'checkov --config-file ../checkov.yml --directory',\n );\n\n targets.checkov = normalizeTargetKeyOrder({\n ...targets.test,\n options: { ...targets.test.options, command: withConfigFile },\n });\n changed = true;\n }\n }\n\n // Point `bootstrap-destroy` at the vended script, which resolves the\n // region rather than leaving terraform to prompt for it.\n const bootstrapDestroy = targets['bootstrap-destroy'];\n if (bootstrapDestroy) {\n const scriptCommand = `tsx {projectRoot}/scripts/bootstrap-destroy.ts {projectRoot}`;\n const alreadyMigrated =\n bootstrapDestroy.options?.commands?.[0] === scriptCommand;\n\n if (!alreadyMigrated) {\n const command = bootstrapDestroy.options?.command;\n // Only rewrite the exact shape the generator produced.\n const isVendedShape =\n typeof command === 'string' &&\n /^terraform destroy -state=\\S+bootstrap\\.tfstate$/.test(\n command.trim(),\n );\n\n if (!isVendedShape) {\n nextSteps.push(divergedBootstrapDestroyStep(projectName));\n } else {\n targets['bootstrap-destroy'] = normalizeTargetKeyOrder({\n executor: bootstrapDestroy.executor,\n options: {\n forwardAllArgs: true,\n commands: [scriptCommand],\n cwd: '{workspaceRoot}',\n },\n });\n changed = true;\n }\n }\n }\n\n if (changed) {\n updateProjectConfiguration(tree, projectName, {\n ...project,\n targets: sortObjectKeys(targets),\n });\n }\n\n // Vend the checkov config and the bootstrap-destroy script. KeepExisting\n // leaves a user's own copy alone and makes a re-run a no-op.\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n '../../../terraform/project/files/checkov',\n ),\n project.root,\n {},\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n // Only application projects have a bootstrap dir to destroy. The scripts\n // dir is shared with the generator's templates, so `stateKeyPrefix` is\n // resolved the same way it computes it; KeepExisting leaves the scripts\n // that already exist untouched regardless.\n if (tree.exists(joinPathFragments(project.root, 'bootstrap'))) {\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n '../../../terraform/project/files/application/scripts',\n ),\n joinPathFragments(project.root, 'scripts'),\n { stateKeyPrefix: kebabCase(projectName) },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n }\n\n await migrateRequiredVersion(\n tree,\n joinPathFragments(project.root, 'src/providers.tf'),\n nextSteps,\n );\n await migrateRequiredVersion(\n tree,\n joinPathFragments(project.root, 'bootstrap/providers.tf'),\n nextSteps,\n );\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["generateFiles","getProjects","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","TERRAFORM_PROJECT_GENERATOR_INFO","applyGritQL","matchGritQL","formatFilesInSubtree","kebabCase","normalizeTargetKeyOrder","sortObjectKeys","hcl","pattern","CHECKOV_COMMAND_PATTERN","divergedTargetsStep","projectName","divergedProvidersStep","filePath","divergedBootstrapDestroyStep","migrateRequiredVersion","tree","nextSteps","exists","hasRequiredProviders","providerBlock","push","migration","project","generator","metadata","id","targets","changed","checkov","command","test","options","withConfigFile","includes","replace","bootstrapDestroy","scriptCommand","alreadyMigrated","commands","isVendedShape","trim","executor","forwardAllArgs","cwd","dirname","root","overwriteStrategy","KeepExisting","stateKeyPrefix"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type Tree } from '@nx/devkit';
|
|
6
|
+
import type { CodeGenData } from '../utils/codegen-data/types.js';
|
|
7
|
+
import type { OpenApiJsonMetadataGeneratorSchema } from './schema';
|
|
8
|
+
/**
|
|
9
|
+
* File name the operations metadata is written to. The Terraform modules read
|
|
10
|
+
* this by name, so both the producing targets and the modules refer to it here.
|
|
11
|
+
*/
|
|
12
|
+
export declare const OPERATIONS_METADATA_FILE_NAME = "operations.json";
|
|
13
|
+
/**
|
|
14
|
+
* Generates an operations metadata JSON file from an OpenAPI specification,
|
|
15
|
+
* read by the vended Terraform modules to define one integration per operation.
|
|
16
|
+
*/
|
|
17
|
+
export declare const openApiJsonMetadataGenerator: (tree: Tree, options: OpenApiJsonMetadataGeneratorSchema) => Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Write the operations metadata for the given spec to the target directory,
|
|
20
|
+
* sorted by operation name so the file is stable across runs and does not churn
|
|
21
|
+
* the Terraform plan.
|
|
22
|
+
*/
|
|
23
|
+
export declare const generateOpenApiJsonMetadata: (tree: Tree, data: CodeGenData, outputPath: string) => void;
|
|
24
|
+
export default openApiJsonMetadataGenerator;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { joinPathFragments } from "@nx/devkit";
|
|
5
|
+
import { buildOpenApiCodeGenerationData } from "../ts-client/generator.js";
|
|
6
|
+
/**
|
|
7
|
+
* File name the operations metadata is written to. The Terraform modules read
|
|
8
|
+
* this by name, so both the producing targets and the modules refer to it here.
|
|
9
|
+
*/ export const OPERATIONS_METADATA_FILE_NAME = 'operations.json';
|
|
10
|
+
/**
|
|
11
|
+
* Generates an operations metadata JSON file from an OpenAPI specification,
|
|
12
|
+
* read by the vended Terraform modules to define one integration per operation.
|
|
13
|
+
*/ export const openApiJsonMetadataGenerator = async (tree, options)=>{
|
|
14
|
+
const data = await buildOpenApiCodeGenerationData(tree, options.openApiSpecPath);
|
|
15
|
+
generateOpenApiJsonMetadata(tree, data, options.outputPath);
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Write the operations metadata for the given spec to the target directory,
|
|
19
|
+
* sorted by operation name so the file is stable across runs and does not churn
|
|
20
|
+
* the Terraform plan.
|
|
21
|
+
*/ export const generateOpenApiJsonMetadata = (tree, data, outputPath)=>{
|
|
22
|
+
const operations = Object.fromEntries(data.allOperations.map((op)=>({
|
|
23
|
+
name: op.dotNotationName ?? op.name,
|
|
24
|
+
path: op.path,
|
|
25
|
+
method: op.method.toUpperCase()
|
|
26
|
+
})).sort((a, b)=>a.name.localeCompare(b.name)).map(({ name, path, method })=>[
|
|
27
|
+
name,
|
|
28
|
+
{
|
|
29
|
+
path,
|
|
30
|
+
method
|
|
31
|
+
}
|
|
32
|
+
]));
|
|
33
|
+
tree.write(joinPathFragments(outputPath, OPERATIONS_METADATA_FILE_NAME), `${JSON.stringify(operations, null, 2)}\n`);
|
|
34
|
+
};
|
|
35
|
+
export default openApiJsonMetadataGenerator;
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/open-api/json-metadata/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 { buildOpenApiCodeGenerationData } from '../ts-client/generator.js';\nimport type { CodeGenData } from '../utils/codegen-data/types.js';\nimport type { OpenApiJsonMetadataGeneratorSchema } from './schema';\n\n/**\n * File name the operations metadata is written to. The Terraform modules read\n * this by name, so both the producing targets and the modules refer to it here.\n */\nexport const OPERATIONS_METADATA_FILE_NAME = 'operations.json';\n\n/**\n * Generates an operations metadata JSON file from an OpenAPI specification,\n * read by the vended Terraform modules to define one integration per operation.\n */\nexport const openApiJsonMetadataGenerator = async (\n tree: Tree,\n options: OpenApiJsonMetadataGeneratorSchema,\n) => {\n const data = await buildOpenApiCodeGenerationData(\n tree,\n options.openApiSpecPath,\n );\n\n generateOpenApiJsonMetadata(tree, data, options.outputPath);\n};\n\n/**\n * Write the operations metadata for the given spec to the target directory,\n * sorted by operation name so the file is stable across runs and does not churn\n * the Terraform plan.\n */\nexport const generateOpenApiJsonMetadata = (\n tree: Tree,\n data: CodeGenData,\n outputPath: string,\n) => {\n const operations = Object.fromEntries(\n data.allOperations\n .map((op) => ({\n name: op.dotNotationName ?? op.name,\n path: op.path,\n method: op.method.toUpperCase(),\n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n .map(({ name, path, method }) => [name, { path, method }]),\n );\n\n tree.write(\n joinPathFragments(outputPath, OPERATIONS_METADATA_FILE_NAME),\n `${JSON.stringify(operations, null, 2)}\\n`,\n );\n};\n\nexport default openApiJsonMetadataGenerator;\n"],"names":["joinPathFragments","buildOpenApiCodeGenerationData","OPERATIONS_METADATA_FILE_NAME","openApiJsonMetadataGenerator","tree","options","data","openApiSpecPath","generateOpenApiJsonMetadata","outputPath","operations","Object","fromEntries","allOperations","map","op","name","dotNotationName","path","method","toUpperCase","sort","a","b","localeCompare","write","JSON","stringify"],"mappings":"AAAA;;;CAGC,GACD,SAASA,iBAAiB,QAAmB,aAAa;AAC1D,SAASC,8BAA8B,QAAQ,4BAA4B;AAI3E;;;CAGC,GACD,OAAO,MAAMC,gCAAgC,kBAAkB;AAE/D;;;CAGC,GACD,OAAO,MAAMC,+BAA+B,OAC1CC,MACAC;IAEA,MAAMC,OAAO,MAAML,+BACjBG,MACAC,QAAQE,eAAe;IAGzBC,4BAA4BJ,MAAME,MAAMD,QAAQI,UAAU;AAC5D,EAAE;AAEF;;;;CAIC,GACD,OAAO,MAAMD,8BAA8B,CACzCJ,MACAE,MACAG;IAEA,MAAMC,aAAaC,OAAOC,WAAW,CACnCN,KAAKO,aAAa,CACfC,GAAG,CAAC,CAACC,KAAQ,CAAA;YACZC,MAAMD,GAAGE,eAAe,IAAIF,GAAGC,IAAI;YACnCE,MAAMH,GAAGG,IAAI;YACbC,QAAQJ,GAAGI,MAAM,CAACC,WAAW;QAC/B,CAAA,GACCC,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEN,IAAI,CAACQ,aAAa,CAACD,EAAEP,IAAI,GAC1CF,GAAG,CAAC,CAAC,EAAEE,IAAI,EAAEE,IAAI,EAAEC,MAAM,EAAE,GAAK;YAACH;YAAM;gBAAEE;gBAAMC;YAAO;SAAE;IAG7Df,KAAKqB,KAAK,CACRzB,kBAAkBS,YAAYP,gCAC9B,GAAGwB,KAAKC,SAAS,CAACjB,YAAY,MAAM,GAAG,EAAE,CAAC;AAE9C,EAAE;AAEF,eAAeP,6BAA6B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/open-api/json-metadata/schema.d.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport interface OpenApiJsonMetadataGeneratorSchema {\n openApiSpecPath: string;\n outputPath: string;\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAED,WAGC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"$id": "OpenApiJsonMetadata",
|
|
4
|
+
"title": "OpenAPI JSON Metadata",
|
|
5
|
+
"description": "Generate a JSON metadata file describing an OpenAPI specification's operations",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"openApiSpecPath": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Path to the OpenAPI specification relative to the monorepo root",
|
|
11
|
+
"x-priority": "important"
|
|
12
|
+
},
|
|
13
|
+
"outputPath": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "Path to the directory in which to generate the metadata relative to the monorepo root",
|
|
16
|
+
"x-priority": "important"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"required": ["openApiSpecPath", "outputPath"]
|
|
20
|
+
}
|