@aws/nx-plugin 1.0.0-rc.89 → 1.0.0-rc.90
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/README.md +22 -22
- package/executors.json +5 -0
- package/generators.json +2 -1
- package/migrations.json +47 -2
- package/package.json +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +24 -12
- package/src/infra/app/generator.js +9 -7
- package/src/infra/app/generator.js.map +1 -1
- package/src/mcp-server/generator-info.d.ts +5 -0
- package/src/mcp-server/generator-info.js +6 -2
- package/src/mcp-server/generator-info.js.map +1 -1
- package/src/migrations/latest/add-assemble-target/metadata.json +3 -0
- package/src/migrations/latest/add-assemble-target/migration.d.ts +6 -0
- package/src/migrations/latest/add-assemble-target/migration.js +241 -0
- package/src/migrations/latest/add-assemble-target/migration.js.map +1 -0
- package/src/migrations/latest/declare-cacheable-target-inputs/metadata.json +3 -0
- package/src/migrations/latest/declare-cacheable-target-inputs/migration.d.ts +6 -0
- package/src/migrations/latest/declare-cacheable-target-inputs/migration.js +94 -0
- package/src/migrations/latest/declare-cacheable-target-inputs/migration.js.map +1 -0
- package/src/migrations/latest/dev-target-depends-on-pull-image/metadata.json +3 -0
- package/src/migrations/latest/dev-target-depends-on-pull-image/migration.d.ts +6 -0
- package/src/migrations/latest/dev-target-depends-on-pull-image/migration.js +67 -0
- package/src/migrations/latest/dev-target-depends-on-pull-image/migration.js.map +1 -0
- package/src/migrations/latest/docker-target-cache-soundness/metadata.json +3 -0
- package/src/migrations/latest/docker-target-cache-soundness/migration.d.ts +6 -0
- package/src/migrations/latest/docker-target-cache-soundness/migration.js +95 -0
- package/src/migrations/latest/docker-target-cache-soundness/migration.js.map +1 -0
- package/src/migrations/latest/open-api-codegen-executor/metadata.json +3 -0
- package/src/migrations/latest/open-api-codegen-executor/migration.d.ts +6 -0
- package/src/migrations/latest/open-api-codegen-executor/migration.js +100 -0
- package/src/migrations/latest/open-api-codegen-executor/migration.js.map +1 -0
- package/src/migrations/latest/python-test-input-scoping/metadata.json +3 -0
- package/src/migrations/latest/python-test-input-scoping/migration.d.ts +6 -0
- package/src/migrations/latest/python-test-input-scoping/migration.js +142 -0
- package/src/migrations/latest/python-test-input-scoping/migration.js.map +1 -0
- package/src/migrations/latest/terraform-fmt-check/metadata.json +3 -0
- package/src/migrations/latest/terraform-fmt-check/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-fmt-check/migration.js +165 -0
- package/src/migrations/latest/terraform-fmt-check/migration.js.map +1 -0
- package/src/migrations/latest/terraform-provider-plugin-cache/metadata.json +3 -0
- package/src/migrations/latest/terraform-provider-plugin-cache/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-provider-plugin-cache/migration.js +164 -0
- package/src/migrations/latest/terraform-provider-plugin-cache/migration.js.map +1 -0
- package/src/migrations/latest/vitest-coverage-output-dir/metadata.json +3 -0
- package/src/migrations/latest/vitest-coverage-output-dir/migration.d.ts +6 -0
- package/src/migrations/latest/vitest-coverage-output-dir/migration.js +177 -0
- package/src/migrations/latest/vitest-coverage-output-dir/migration.js.map +1 -0
- package/src/open-api/codegen/executor-schema.d.js +6 -0
- package/src/open-api/codegen/executor-schema.d.js.map +1 -0
- package/src/open-api/codegen/executor-schema.d.ts +18 -0
- package/src/open-api/codegen/executor-schema.json +33 -0
- package/src/open-api/codegen/executor.d.ts +18 -0
- package/src/open-api/codegen/executor.js +56 -0
- package/src/open-api/codegen/executor.js.map +1 -0
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -1
- package/src/py/agent/generator.js +21 -22
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/react-connection/generator.js +9 -0
- package/src/py/agent/react-connection/generator.js.map +1 -1
- package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +0 -30
- package/src/py/fast-api/react/open-api.js +19 -7
- package/src/py/fast-api/react/open-api.js.map +1 -1
- package/src/py/mcp-server/generator.js +4 -4
- package/src/py/mcp-server/generator.js.map +1 -1
- package/src/py/project/generator.d.ts +9 -0
- package/src/py/project/generator.js +51 -1
- package/src/py/project/generator.js.map +1 -1
- package/src/py/rdb/generator.js +10 -4
- package/src/py/rdb/generator.js.map +1 -1
- package/src/smithy/project/__snapshots__/generator.spec.ts.snap +15 -0
- package/src/smithy/project/generator.js +10 -0
- package/src/smithy/project/generator.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +7 -0
- package/src/terraform/project/files/application/scripts/env.ts.template +11 -0
- package/src/terraform/project/files/application/scripts/init.ts.template +2 -1
- package/src/terraform/project/files/application/src/providers.tf.template +2 -2
- package/src/terraform/project/generator.d.ts +11 -1
- package/src/terraform/project/generator.js +104 -20
- package/src/terraform/project/generator.js.map +1 -1
- package/src/trpc/backend/generator.js +2 -2
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/ts/agent/generator.js +4 -7
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/astro-docs/generator.js +5 -0
- package/src/ts/astro-docs/generator.js.map +1 -1
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +0 -30
- package/src/ts/dynamodb/generator.js +3 -0
- package/src/ts/dynamodb/generator.js.map +1 -1
- package/src/ts/lib/__snapshots__/generator.spec.ts.snap +10 -1
- package/src/ts/lib/__snapshots__/vitest.spec.ts.snap +1 -1
- package/src/ts/lib/generator.d.ts +16 -0
- package/src/ts/lib/generator.js +31 -5
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/vitest.d.ts +11 -0
- package/src/ts/lib/vitest.js +31 -2
- package/src/ts/lib/vitest.js.map +1 -1
- package/src/ts/mcp-server/generator.js +4 -7
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/rdb/generator.js +8 -5
- package/src/ts/rdb/generator.js.map +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +27 -11
- package/src/ts/react-website/app/generator.js +9 -1
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/ts/sync/generator.js +19 -2
- package/src/ts/sync/generator.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.js +3 -3
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/api-constructs/api-constructs.js +2 -2
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/open-api-metadata.js +15 -36
- package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
- package/src/utils/api-constructs/trpc-operations-metadata.js +9 -3
- package/src/utils/api-constructs/trpc-operations-metadata.js.map +1 -1
- package/src/utils/bundle/bundle.js +13 -4
- package/src/utils/bundle/bundle.js.map +1 -1
- package/src/utils/connection/open-api/react.js +7 -17
- package/src/utils/connection/open-api/react.js.map +1 -1
- package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js +2 -2
- package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js.map +1 -1
- package/src/utils/docker.d.ts +22 -10
- package/src/utils/docker.js +27 -17
- package/src/utils/docker.js.map +1 -1
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js +2 -2
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -1
- package/src/utils/files/common/scripts/src/dynamodb/start-container.ts.template +0 -15
- package/src/utils/files/common/scripts/src/rdb/shared/start-container.ts.template +0 -15
- package/src/utils/format.d.ts +5 -0
- package/src/utils/format.js +5 -0
- package/src/utils/format.js.map +1 -1
- package/src/utils/function-constructs/function-constructs.js +2 -2
- package/src/utils/function-constructs/function-constructs.js.map +1 -1
- package/src/utils/generators.d.ts +33 -0
- package/src/utils/generators.js +18 -3
- package/src/utils/generators.js.map +1 -1
- package/src/utils/init.js +4 -6
- package/src/utils/init.js.map +1 -1
- package/src/utils/mock-project-graph.js +5 -2
- package/src/utils/mock-project-graph.js.map +1 -1
- package/src/utils/nx.d.ts +19 -0
- package/src/utils/nx.js +23 -0
- package/src/utils/nx.js.map +1 -1
- package/src/utils/open-api-codegen-target.d.ts +28 -0
- package/src/utils/open-api-codegen-target.js +31 -0
- package/src/utils/open-api-codegen-target.js.map +1 -0
- package/src/utils/rdb-constructs/rdb-constructs.js +2 -2
- package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
- package/src/utils/website-constructs/website-constructs.js +2 -2
- package/src/utils/website-constructs/website-constructs.js.map +1 -1
|
@@ -30,6 +30,9 @@ exports[`smithyProjectGenerator > shape libraries > should generate a shape libr
|
|
|
30
30
|
"build": {
|
|
31
31
|
"dependsOn": ["compile"]
|
|
32
32
|
},
|
|
33
|
+
"assemble": {
|
|
34
|
+
"dependsOn": ["compile"]
|
|
35
|
+
},
|
|
33
36
|
"compile": {
|
|
34
37
|
"cache": true,
|
|
35
38
|
"outputs": [
|
|
@@ -104,6 +107,9 @@ exports[`smithyProjectGenerator > should generate smithy project with all custom
|
|
|
104
107
|
"build": {
|
|
105
108
|
"dependsOn": ["compile", "generate-ssdk"]
|
|
106
109
|
},
|
|
110
|
+
"assemble": {
|
|
111
|
+
"dependsOn": ["compile", "generate-ssdk"]
|
|
112
|
+
},
|
|
107
113
|
"compile": {
|
|
108
114
|
"cache": true,
|
|
109
115
|
"outputs": [
|
|
@@ -158,6 +164,9 @@ exports[`smithyProjectGenerator > should generate smithy project with custom dir
|
|
|
158
164
|
"build": {
|
|
159
165
|
"dependsOn": ["compile", "generate-ssdk"]
|
|
160
166
|
},
|
|
167
|
+
"assemble": {
|
|
168
|
+
"dependsOn": ["compile", "generate-ssdk"]
|
|
169
|
+
},
|
|
161
170
|
"compile": {
|
|
162
171
|
"cache": true,
|
|
163
172
|
"outputs": [
|
|
@@ -304,6 +313,9 @@ exports[`smithyProjectGenerator > should generate smithy project with default op
|
|
|
304
313
|
"build": {
|
|
305
314
|
"dependsOn": ["compile", "generate-ssdk"]
|
|
306
315
|
},
|
|
316
|
+
"assemble": {
|
|
317
|
+
"dependsOn": ["compile", "generate-ssdk"]
|
|
318
|
+
},
|
|
307
319
|
"compile": {
|
|
308
320
|
"cache": true,
|
|
309
321
|
"outputs": [
|
|
@@ -444,6 +456,9 @@ exports[`smithyProjectGenerator > should generate smithy project with subdirecto
|
|
|
444
456
|
"build": {
|
|
445
457
|
"dependsOn": ["compile", "generate-ssdk"]
|
|
446
458
|
},
|
|
459
|
+
"assemble": {
|
|
460
|
+
"dependsOn": ["compile", "generate-ssdk"]
|
|
461
|
+
},
|
|
447
462
|
"compile": {
|
|
448
463
|
"cache": true,
|
|
449
464
|
"outputs": [
|
|
@@ -163,6 +163,16 @@ export const smithyProjectGenerator = async (tree, options)=>{
|
|
|
163
163
|
'generate-ssdk'
|
|
164
164
|
]
|
|
165
165
|
},
|
|
166
|
+
// Everything this project's build does is artifact production, so
|
|
167
|
+
// `assemble` carries the same dependencies.
|
|
168
|
+
assemble: {
|
|
169
|
+
dependsOn: type === 'shapes' ? [
|
|
170
|
+
'compile'
|
|
171
|
+
] : [
|
|
172
|
+
'compile',
|
|
173
|
+
'generate-ssdk'
|
|
174
|
+
]
|
|
175
|
+
},
|
|
166
176
|
compile: {
|
|
167
177
|
cache: true,
|
|
168
178
|
outputs: smithyCompileOutputs(type),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/smithy/project/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addProjectConfiguration,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n} from '@nx/devkit';\nimport { getTsLibDetails } from '../../ts/lib/generator.js';\nimport { addTsDependencies } from '../../utils/add-dependencies.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { FS_DEPENDENCIES, FsCommands } from '../../utils/fs.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { toClassName, toKebabCase } from '../../utils/names.js';\nimport { getNpmScope } from '../../utils/npm-scope.js';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx.js';\nimport { getRelativePathToRootByDirectory } from '../../utils/paths.js';\nimport {\n smithyCliCommand,\n smithyMavenVersions,\n warnIfSmithyMissing,\n} from '../../utils/smithy.js';\nimport type { SmithyProjectGeneratorSchema } from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface SmithyProjectMetadata {\n readonly smithyType: NonNullable<SmithyProjectGeneratorSchema['type']>;\n readonly namespace: string;\n}\n\n/**\n * Only a service project generates a Server SDK, so only a service needs the\n * bundler that turns it into the single module its backend imports. A shape\n * library assembles a model and stops.\n */\nconst isService = (metadata: SmithyProjectMetadata) =>\n metadata.smithyType === 'service';\n\n/**\n * Everything a Smithy build runs, all of it workspace tooling in the root\n * manifest rather than anything the model itself imports.\n *\n * Neither the Smithy CLI nor `mise` is among them: the compile target fetches mise\n * with `npx` and mise resolves the CLI, so neither is a workspace dependency — see\n * `utils/smithy.ts`.\n */\nexport const DEPENDENCIES = declareDependencies<SmithyProjectMetadata>()({\n ts: [\n // Added to the root by `FsCommands` as it builds each command.\n ...ownedElsewhere(FS_DEPENDENCIES),\n { name: 'rolldown', dev: true, root: true, when: isService },\n { name: 'rolldown-plugin-dts', dev: true, root: true, when: isService },\n // Resolved by `rolldown-plugin-dts` to emit the bundled declaration.\n { name: 'typescript', dev: true, root: true, when: isService },\n ],\n});\n\nexport const SMITHY_PROJECT_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\n/**\n * Where the Smithy CLI writes its artifacts, and where the build publishes the\n * ones consumers read. Both sit under `dist` so a build writes nothing into the\n * project, keeping the source tree clean and the target's outputs cacheable.\n *\n * The CLI's own output is kept beside the published tree rather than inside it:\n * it holds the generated SSDK package and its installed `node_modules`, which\n * must not be mistaken for a build artifact.\n */\nconst SMITHY_OUT_DIR = 'dist/{projectRoot}/smithy';\nconst BUILD_DIR = 'dist/{projectRoot}/build';\n\n/** The projection every generated `smithy-build.json` builds. */\nconst SOURCE_PROJECTION = `${SMITHY_OUT_DIR}/source`;\n\n/** Where the generated TypeScript Server SDK lands before it is bundled. */\nconst SSDK_CODEGEN_DIR = `${SOURCE_PROJECTION}/typescript-ssdk-codegen`;\n\n/**\n * The commands that build a Smithy project's model, run from the workspace root.\n *\n * This is the whole of a shape library's build. A service's Server SDK is built\n * separately by {@link smithyGenerateSsdkCommands}, from the codegen output this\n * leaves under {@link SMITHY_OUT_DIR}.\n */\nexport const smithyCompileCommands = (\n cmd: FsCommands<typeof DEPENDENCIES>,\n type: SmithyProjectGeneratorSchema['type'],\n): string[] => [\n cmd.rm(BUILD_DIR),\n cmd.rm(SMITHY_OUT_DIR),\n cmd.mkdir(BUILD_DIR),\n // `imports` in smithy-build.json resolve relative to that file, so a shape\n // library is referenced by its path from the consuming project.\n `${smithyCliCommand()} build -c {projectRoot}/smithy-build.json --output ${SMITHY_OUT_DIR}`,\n ...(type === 'shapes'\n ? [\n cmd.cp(\n `${SOURCE_PROJECTION}/model/model.json`,\n `${BUILD_DIR}/model.json`,\n ),\n ]\n : [\n // Named after the service shape by the OpenAPI plugin, so it is matched\n // rather than named, and published under a stable name.\n cmd.cpGlobToFile(\n `${SOURCE_PROJECTION}/openapi/*.openapi.json`,\n `${BUILD_DIR}/openapi`,\n 'openapi.json',\n ),\n ]),\n];\n\n/**\n * The commands that turn a service's generated TypeScript Server SDK into the\n * single module its consumer imports, run from the workspace root.\n *\n * Only a service has one, and it reads what the model build left behind, so this\n * runs after `compile`.\n */\nexport const smithyGenerateSsdkCommands = (): string[] => [\n // `npm` regardless of the workspace's package manager: this installs a generated\n // package under `dist` that is not a workspace member, and npm ships with Node so\n // it is always present. It reads the user's `.npmrc`, so a private registry still\n // applies. `--include=dev` because the bundler resolves types from the generated\n // package's devDependencies, which `NODE_ENV=production` would otherwise omit.\n `npm install --prefix ${SSDK_CODEGEN_DIR} --include=dev --ignore-scripts --no-audit --no-fund`,\n // Bundled straight from the generated TypeScript sources, emitting the module and\n // its declarations together — see ssdk.rolldown.config.mjs for why the sources\n // rather than a `tsc` pre-pass.\n `rolldown -c {projectRoot}/ssdk.rolldown.config.mjs`,\n];\n\n/**\n * What the model build publishes, listed per artifact rather than as the whole\n * `build` directory: a service's `generate-ssdk` writes into that directory too, and\n * restoring `compile` from cache would otherwise discard the Server SDK beside it.\n */\nexport const smithyCompileOutputs = (\n type: SmithyProjectGeneratorSchema['type'],\n): string[] => [\n `{workspaceRoot}/${SMITHY_OUT_DIR}`,\n type === 'shapes'\n ? `{workspaceRoot}/${BUILD_DIR}/model.json`\n : `{workspaceRoot}/${BUILD_DIR}/openapi`,\n];\n\n/**\n * The target that builds a service's Server SDK, shared with the migration moving\n * an existing project onto it.\n */\nexport const smithyGenerateSsdkTarget = () => ({\n cache: true,\n outputs: [`{workspaceRoot}/${BUILD_DIR}/ssdk`],\n executor: 'nx:run-commands',\n dependsOn: ['compile'],\n options: {\n commands: smithyGenerateSsdkCommands(),\n parallel: false,\n cwd: '{workspaceRoot}',\n },\n});\n\n/**\n * Write the rolldown config that bundles a service's generated Server SDK.\n *\n * Shared with the migration moving an existing project off the container build,\n * so a migrated project's config cannot drift from a freshly generated one.\n */\nexport const writeSsdkBundleConfig = (tree: Tree, projectRoot: string): void =>\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'ssdk-bundle'),\n projectRoot,\n // The config's paths are workspace-root relative, so it needs only the\n // project's root — the compile target runs from the workspace root.\n { projectRoot },\n // Generated configuration rather than anything the user edits, so a re-run\n // refreshes it — unlike the models beside it.\n { overwriteStrategy: OverwriteStrategy.Overwrite },\n );\n\nexport const smithyProjectGenerator = async (\n tree: Tree,\n options: SmithyProjectGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const cmd = new FsCommands(tree, DEPENDENCIES);\n const type = options.type ?? 'service';\n\n // Create project.json\n const { fullyQualifiedName, dir } = getTsLibDetails(tree, options);\n\n if (!projectExists(tree, fullyQualifiedName)) {\n addProjectConfiguration(tree, fullyQualifiedName, {\n name: fullyQualifiedName,\n root: dir,\n sourceRoot: joinPathFragments(dir, 'src'),\n projectType: 'library',\n targets: {\n build: {\n dependsOn:\n type === 'shapes' ? ['compile'] : ['compile', 'generate-ssdk'],\n },\n compile: {\n cache: true,\n outputs: smithyCompileOutputs(type),\n executor: 'nx:run-commands',\n options: {\n commands: smithyCompileCommands(cmd, type),\n parallel: false,\n cwd: '{workspaceRoot}',\n },\n },\n // Only a service generates a Server SDK, and it is built from what the\n // model build leaves behind.\n ...(type === 'shapes'\n ? {}\n : { 'generate-ssdk': smithyGenerateSsdkTarget() }),\n },\n });\n }\n\n const serviceName = options.serviceName ?? options.name;\n const serviceNameClassName = toClassName(serviceName);\n const serviceNameKebabCase = toKebabCase(serviceName);\n const scope = getNpmScope(tree);\n const namespace = options.namespace ?? toKebabCase(scope).replace(/-/g, '.');\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', type),\n dir,\n {\n namespace,\n serviceNameClassName,\n serviceNameKebabCase,\n scope,\n projectRoot: dir,\n relativePathToWorkspaceRoot: getRelativePathToRootByDirectory(dir),\n ...smithyMavenVersions(),\n },\n {\n // Smithy models are user-owned — a re-run must not discard edits\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n if (type === 'service') {\n writeSsdkBundleConfig(tree, dir);\n }\n\n // Recorded here and read by the declaration's predicates, so the packages\n // added below are exactly the ones the version sync will own.\n const metadata: SmithyProjectMetadata = { smithyType: type, namespace };\n\n addGeneratorMetadata(\n tree,\n fullyQualifiedName,\n SMITHY_PROJECT_GENERATOR_INFO,\n {\n ...metadata,\n ...(type === 'service' ? { apiName: options.name } : {}),\n },\n );\n\n // No projectRoot: a Smithy model project has no manifest of its own, and every\n // dependency here is workspace tooling the build runs rather than anything the\n // model imports.\n addTsDependencies(tree, DEPENDENCIES, { metadata });\n\n await addGeneratorMetricsIfApplicable(tree, [SMITHY_PROJECT_GENERATOR_INFO]);\n\n // On Windows the build runs the Smithy CLI from the PATH rather than through\n // mise, so flag a missing prerequisite while the project is still being set up.\n warnIfSmithyMissing();\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\nexport default smithyProjectGenerator;\n"],"names":["addProjectConfiguration","generateFiles","joinPathFragments","OverwriteStrategy","getTsLibDetails","addTsDependencies","declareDependencies","ownedElsewhere","formatFilesInSubtree","FS_DEPENDENCIES","FsCommands","installDependencies","addGeneratorMetricsIfApplicable","toClassName","toKebabCase","getNpmScope","addGeneratorMetadata","getGeneratorInfo","projectExists","getRelativePathToRootByDirectory","smithyCliCommand","smithyMavenVersions","warnIfSmithyMissing","isService","metadata","smithyType","DEPENDENCIES","ts","name","dev","root","when","SMITHY_PROJECT_GENERATOR_INFO","filename","SMITHY_OUT_DIR","BUILD_DIR","SOURCE_PROJECTION","SSDK_CODEGEN_DIR","smithyCompileCommands","cmd","type","rm","mkdir","cp","cpGlobToFile","smithyGenerateSsdkCommands","smithyCompileOutputs","smithyGenerateSsdkTarget","cache","outputs","executor","dependsOn","options","commands","parallel","cwd","writeSsdkBundleConfig","tree","projectRoot","dirname","overwriteStrategy","Overwrite","smithyProjectGenerator","fullyQualifiedName","dir","sourceRoot","projectType","targets","build","compile","serviceName","serviceNameClassName","serviceNameKebabCase","scope","namespace","replace","relativePathToWorkspaceRoot","KeepExisting","apiName","preferInstallDependencies","languages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/smithy/project/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addProjectConfiguration,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n} from '@nx/devkit';\nimport { getTsLibDetails } from '../../ts/lib/generator.js';\nimport { addTsDependencies } from '../../utils/add-dependencies.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { FS_DEPENDENCIES, FsCommands } from '../../utils/fs.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { toClassName, toKebabCase } from '../../utils/names.js';\nimport { getNpmScope } from '../../utils/npm-scope.js';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx.js';\nimport { getRelativePathToRootByDirectory } from '../../utils/paths.js';\nimport {\n smithyCliCommand,\n smithyMavenVersions,\n warnIfSmithyMissing,\n} from '../../utils/smithy.js';\nimport type { SmithyProjectGeneratorSchema } from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface SmithyProjectMetadata {\n readonly smithyType: NonNullable<SmithyProjectGeneratorSchema['type']>;\n readonly namespace: string;\n}\n\n/**\n * Only a service project generates a Server SDK, so only a service needs the\n * bundler that turns it into the single module its backend imports. A shape\n * library assembles a model and stops.\n */\nconst isService = (metadata: SmithyProjectMetadata) =>\n metadata.smithyType === 'service';\n\n/**\n * Everything a Smithy build runs, all of it workspace tooling in the root\n * manifest rather than anything the model itself imports.\n *\n * Neither the Smithy CLI nor `mise` is among them: the compile target fetches mise\n * with `npx` and mise resolves the CLI, so neither is a workspace dependency — see\n * `utils/smithy.ts`.\n */\nexport const DEPENDENCIES = declareDependencies<SmithyProjectMetadata>()({\n ts: [\n // Added to the root by `FsCommands` as it builds each command.\n ...ownedElsewhere(FS_DEPENDENCIES),\n { name: 'rolldown', dev: true, root: true, when: isService },\n { name: 'rolldown-plugin-dts', dev: true, root: true, when: isService },\n // Resolved by `rolldown-plugin-dts` to emit the bundled declaration.\n { name: 'typescript', dev: true, root: true, when: isService },\n ],\n});\n\nexport const SMITHY_PROJECT_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\n/**\n * Where the Smithy CLI writes its artifacts, and where the build publishes the\n * ones consumers read. Both sit under `dist` so a build writes nothing into the\n * project, keeping the source tree clean and the target's outputs cacheable.\n *\n * The CLI's own output is kept beside the published tree rather than inside it:\n * it holds the generated SSDK package and its installed `node_modules`, which\n * must not be mistaken for a build artifact.\n */\nconst SMITHY_OUT_DIR = 'dist/{projectRoot}/smithy';\nconst BUILD_DIR = 'dist/{projectRoot}/build';\n\n/** The projection every generated `smithy-build.json` builds. */\nconst SOURCE_PROJECTION = `${SMITHY_OUT_DIR}/source`;\n\n/** Where the generated TypeScript Server SDK lands before it is bundled. */\nconst SSDK_CODEGEN_DIR = `${SOURCE_PROJECTION}/typescript-ssdk-codegen`;\n\n/**\n * The commands that build a Smithy project's model, run from the workspace root.\n *\n * This is the whole of a shape library's build. A service's Server SDK is built\n * separately by {@link smithyGenerateSsdkCommands}, from the codegen output this\n * leaves under {@link SMITHY_OUT_DIR}.\n */\nexport const smithyCompileCommands = (\n cmd: FsCommands<typeof DEPENDENCIES>,\n type: SmithyProjectGeneratorSchema['type'],\n): string[] => [\n cmd.rm(BUILD_DIR),\n cmd.rm(SMITHY_OUT_DIR),\n cmd.mkdir(BUILD_DIR),\n // `imports` in smithy-build.json resolve relative to that file, so a shape\n // library is referenced by its path from the consuming project.\n `${smithyCliCommand()} build -c {projectRoot}/smithy-build.json --output ${SMITHY_OUT_DIR}`,\n ...(type === 'shapes'\n ? [\n cmd.cp(\n `${SOURCE_PROJECTION}/model/model.json`,\n `${BUILD_DIR}/model.json`,\n ),\n ]\n : [\n // Named after the service shape by the OpenAPI plugin, so it is matched\n // rather than named, and published under a stable name.\n cmd.cpGlobToFile(\n `${SOURCE_PROJECTION}/openapi/*.openapi.json`,\n `${BUILD_DIR}/openapi`,\n 'openapi.json',\n ),\n ]),\n];\n\n/**\n * The commands that turn a service's generated TypeScript Server SDK into the\n * single module its consumer imports, run from the workspace root.\n *\n * Only a service has one, and it reads what the model build left behind, so this\n * runs after `compile`.\n */\nexport const smithyGenerateSsdkCommands = (): string[] => [\n // `npm` regardless of the workspace's package manager: this installs a generated\n // package under `dist` that is not a workspace member, and npm ships with Node so\n // it is always present. It reads the user's `.npmrc`, so a private registry still\n // applies. `--include=dev` because the bundler resolves types from the generated\n // package's devDependencies, which `NODE_ENV=production` would otherwise omit.\n `npm install --prefix ${SSDK_CODEGEN_DIR} --include=dev --ignore-scripts --no-audit --no-fund`,\n // Bundled straight from the generated TypeScript sources, emitting the module and\n // its declarations together — see ssdk.rolldown.config.mjs for why the sources\n // rather than a `tsc` pre-pass.\n `rolldown -c {projectRoot}/ssdk.rolldown.config.mjs`,\n];\n\n/**\n * What the model build publishes, listed per artifact rather than as the whole\n * `build` directory: a service's `generate-ssdk` writes into that directory too, and\n * restoring `compile` from cache would otherwise discard the Server SDK beside it.\n */\nexport const smithyCompileOutputs = (\n type: SmithyProjectGeneratorSchema['type'],\n): string[] => [\n `{workspaceRoot}/${SMITHY_OUT_DIR}`,\n type === 'shapes'\n ? `{workspaceRoot}/${BUILD_DIR}/model.json`\n : `{workspaceRoot}/${BUILD_DIR}/openapi`,\n];\n\n/**\n * The target that builds a service's Server SDK, shared with the migration moving\n * an existing project onto it.\n */\nexport const smithyGenerateSsdkTarget = () => ({\n cache: true,\n outputs: [`{workspaceRoot}/${BUILD_DIR}/ssdk`],\n executor: 'nx:run-commands',\n dependsOn: ['compile'],\n options: {\n commands: smithyGenerateSsdkCommands(),\n parallel: false,\n cwd: '{workspaceRoot}',\n },\n});\n\n/**\n * Write the rolldown config that bundles a service's generated Server SDK.\n *\n * Shared with the migration moving an existing project off the container build,\n * so a migrated project's config cannot drift from a freshly generated one.\n */\nexport const writeSsdkBundleConfig = (tree: Tree, projectRoot: string): void =>\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'ssdk-bundle'),\n projectRoot,\n // The config's paths are workspace-root relative, so it needs only the\n // project's root — the compile target runs from the workspace root.\n { projectRoot },\n // Generated configuration rather than anything the user edits, so a re-run\n // refreshes it — unlike the models beside it.\n { overwriteStrategy: OverwriteStrategy.Overwrite },\n );\n\nexport const smithyProjectGenerator = async (\n tree: Tree,\n options: SmithyProjectGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const cmd = new FsCommands(tree, DEPENDENCIES);\n const type = options.type ?? 'service';\n\n // Create project.json\n const { fullyQualifiedName, dir } = getTsLibDetails(tree, options);\n\n if (!projectExists(tree, fullyQualifiedName)) {\n addProjectConfiguration(tree, fullyQualifiedName, {\n name: fullyQualifiedName,\n root: dir,\n sourceRoot: joinPathFragments(dir, 'src'),\n projectType: 'library',\n targets: {\n build: {\n dependsOn:\n type === 'shapes' ? ['compile'] : ['compile', 'generate-ssdk'],\n },\n // Everything this project's build does is artifact production, so\n // `assemble` carries the same dependencies.\n assemble: {\n dependsOn:\n type === 'shapes' ? ['compile'] : ['compile', 'generate-ssdk'],\n },\n compile: {\n cache: true,\n outputs: smithyCompileOutputs(type),\n executor: 'nx:run-commands',\n options: {\n commands: smithyCompileCommands(cmd, type),\n parallel: false,\n cwd: '{workspaceRoot}',\n },\n },\n // Only a service generates a Server SDK, and it is built from what the\n // model build leaves behind.\n ...(type === 'shapes'\n ? {}\n : { 'generate-ssdk': smithyGenerateSsdkTarget() }),\n },\n });\n }\n\n const serviceName = options.serviceName ?? options.name;\n const serviceNameClassName = toClassName(serviceName);\n const serviceNameKebabCase = toKebabCase(serviceName);\n const scope = getNpmScope(tree);\n const namespace = options.namespace ?? toKebabCase(scope).replace(/-/g, '.');\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', type),\n dir,\n {\n namespace,\n serviceNameClassName,\n serviceNameKebabCase,\n scope,\n projectRoot: dir,\n relativePathToWorkspaceRoot: getRelativePathToRootByDirectory(dir),\n ...smithyMavenVersions(),\n },\n {\n // Smithy models are user-owned — a re-run must not discard edits\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n if (type === 'service') {\n writeSsdkBundleConfig(tree, dir);\n }\n\n // Recorded here and read by the declaration's predicates, so the packages\n // added below are exactly the ones the version sync will own.\n const metadata: SmithyProjectMetadata = { smithyType: type, namespace };\n\n addGeneratorMetadata(\n tree,\n fullyQualifiedName,\n SMITHY_PROJECT_GENERATOR_INFO,\n {\n ...metadata,\n ...(type === 'service' ? { apiName: options.name } : {}),\n },\n );\n\n // No projectRoot: a Smithy model project has no manifest of its own, and every\n // dependency here is workspace tooling the build runs rather than anything the\n // model imports.\n addTsDependencies(tree, DEPENDENCIES, { metadata });\n\n await addGeneratorMetricsIfApplicable(tree, [SMITHY_PROJECT_GENERATOR_INFO]);\n\n // On Windows the build runs the Smithy CLI from the PATH rather than through\n // mise, so flag a missing prerequisite while the project is still being set up.\n warnIfSmithyMissing();\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\nexport default smithyProjectGenerator;\n"],"names":["addProjectConfiguration","generateFiles","joinPathFragments","OverwriteStrategy","getTsLibDetails","addTsDependencies","declareDependencies","ownedElsewhere","formatFilesInSubtree","FS_DEPENDENCIES","FsCommands","installDependencies","addGeneratorMetricsIfApplicable","toClassName","toKebabCase","getNpmScope","addGeneratorMetadata","getGeneratorInfo","projectExists","getRelativePathToRootByDirectory","smithyCliCommand","smithyMavenVersions","warnIfSmithyMissing","isService","metadata","smithyType","DEPENDENCIES","ts","name","dev","root","when","SMITHY_PROJECT_GENERATOR_INFO","filename","SMITHY_OUT_DIR","BUILD_DIR","SOURCE_PROJECTION","SSDK_CODEGEN_DIR","smithyCompileCommands","cmd","type","rm","mkdir","cp","cpGlobToFile","smithyGenerateSsdkCommands","smithyCompileOutputs","smithyGenerateSsdkTarget","cache","outputs","executor","dependsOn","options","commands","parallel","cwd","writeSsdkBundleConfig","tree","projectRoot","dirname","overwriteStrategy","Overwrite","smithyProjectGenerator","fullyQualifiedName","dir","sourceRoot","projectType","targets","build","assemble","compile","serviceName","serviceNameClassName","serviceNameKebabCase","scope","namespace","replace","relativePathToWorkspaceRoot","KeepExisting","apiName","preferInstallDependencies","languages"],"mappings":"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"}
|
|
@@ -1828,6 +1828,9 @@ exports[`tsSmithyApiGenerator > should generate smithy ts api with default optio
|
|
|
1828
1828
|
"ports": [3001]
|
|
1829
1829
|
},
|
|
1830
1830
|
"targets": {
|
|
1831
|
+
"assemble": {
|
|
1832
|
+
"dependsOn": ["compile", "bundle"]
|
|
1833
|
+
},
|
|
1831
1834
|
"build": {
|
|
1832
1835
|
"dependsOn": ["lint", "compile", "test", "bundle"]
|
|
1833
1836
|
},
|
|
@@ -1877,6 +1880,7 @@ exports[`tsSmithyApiGenerator > should generate smithy ts api with default optio
|
|
|
1877
1880
|
"executor": "nx:run-commands",
|
|
1878
1881
|
"dependsOn": ["compile"],
|
|
1879
1882
|
"cache": true,
|
|
1883
|
+
"inputs": ["default"],
|
|
1880
1884
|
"outputs": ["{workspaceRoot}/dist/{projectRoot}/bundle"],
|
|
1881
1885
|
"options": {
|
|
1882
1886
|
"command": "rolldown -c rolldown.config.ts",
|
|
@@ -2091,6 +2095,9 @@ exports[`tsSmithyApiGenerator > should generate smithy ts api with default optio
|
|
|
2091
2095
|
"build": {
|
|
2092
2096
|
"dependsOn": ["compile", "generate-ssdk"]
|
|
2093
2097
|
},
|
|
2098
|
+
"assemble": {
|
|
2099
|
+
"dependsOn": ["compile", "generate-ssdk"]
|
|
2100
|
+
},
|
|
2094
2101
|
"compile": {
|
|
2095
2102
|
"cache": true,
|
|
2096
2103
|
"outputs": [
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { mkdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
/** Environment variables for Terraform to cache plugins */
|
|
5
|
+
export const pluginCacheEnv = (projectRootRel: string): NodeJS.ProcessEnv => {
|
|
6
|
+
const dir =
|
|
7
|
+
process.env.TF_PLUGIN_CACHE_DIR ??
|
|
8
|
+
join(process.cwd(), '.terraform', 'plugin-cache', projectRootRel);
|
|
9
|
+
mkdirSync(dir, { recursive: true });
|
|
10
|
+
return { ...process.env, TF_PLUGIN_CACHE_DIR: dir };
|
|
11
|
+
};
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { execFileSync } from 'node:child_process';
|
|
8
8
|
import { join, resolve } from 'node:path';
|
|
9
9
|
import { resolveAwsConfig } from './aws-config';
|
|
10
|
+
import { pluginCacheEnv } from './env';
|
|
10
11
|
|
|
11
12
|
const STATE_KEY_PREFIX = '<%- stateKeyPrefix %>';
|
|
12
13
|
|
|
@@ -34,7 +35,7 @@ const main = async () => {
|
|
|
34
35
|
`-backend-config=key=${key}`,
|
|
35
36
|
...process.argv.slice(3),
|
|
36
37
|
],
|
|
37
|
-
{ cwd: srcDir, stdio: 'inherit' },
|
|
38
|
+
{ cwd: srcDir, stdio: 'inherit', env: pluginCacheEnv(projectRootRel) },
|
|
38
39
|
);
|
|
39
40
|
};
|
|
40
41
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
|
-
import { type GeneratorCallback, type Tree } from '@nx/devkit';
|
|
5
|
+
import { type GeneratorCallback, type TargetConfiguration, type Tree } from '@nx/devkit';
|
|
6
6
|
import { type NxGeneratorInfo } from '../../utils/nx.js';
|
|
7
7
|
import type { TerraformProjectGeneratorSchema } from './schema';
|
|
8
8
|
export declare const DEPENDENCIES: import("../../utils/declared-dependencies.js").DependencyDeclaration<readonly [{
|
|
@@ -56,5 +56,15 @@ export declare const DEPENDENCIES: import("../../utils/declared-dependencies.js"
|
|
|
56
56
|
versionOnly: true;
|
|
57
57
|
}], readonly import("../../utils/declared-dependencies.js").DeclaredPyDependency<"a2a-sdk" | "ag-ui-langgraph" | "ag-ui-protocol" | "ag-ui-strands" | "aiosqlite" | "aws-lambda-powertools" | "aws-lambda-powertools[tracer]" | "aws-lambda-powertools[parser]" | "aws-opentelemetry-distro" | "bedrock-agentcore" | "boto3" | "checkov" | "fastapi" | "fastapi[standard]" | "httpx" | "langchain" | "langchain-aws" | "langchain-mcp-adapters" | "langgraph" | "langgraph-checkpoint-aws" | "langgraph-checkpoint-sqlite" | "mcp" | "pip-check-updates" | "pip-licenses" | "ruff" | "strands-agents" | "strands-agents[a2a]" | "strands-agents-tools" | "ty" | "pynamodb" | "uvicorn" | "sqlmodel" | "alembic" | "aiomysql" | "asyncpg" | "greenlet", Record<string, never>>[]>;
|
|
58
58
|
export declare const TERRAFORM_PROJECT_GENERATOR_INFO: NxGeneratorInfo;
|
|
59
|
+
/**
|
|
60
|
+
* Checks formatting, mirroring the TypeScript and Python `format` targets: the
|
|
61
|
+
* base target fails on an unformatted file and the `fix` configuration rewrites
|
|
62
|
+
* it. Writing from the base target would rewrite the `default` input the hash is
|
|
63
|
+
* computed over, so the target could never cache-hit.
|
|
64
|
+
*
|
|
65
|
+
* Scoped to the project's own `src` rather than `-recursive`, so it checks the
|
|
66
|
+
* files the vended templates cover. `-diff` names what to fix when it fails.
|
|
67
|
+
*/
|
|
68
|
+
export declare const TERRAFORM_FORMAT_TARGET: TargetConfiguration;
|
|
59
69
|
export declare function terraformProjectGenerator(tree: Tree, schema: TerraformProjectGeneratorSchema): Promise<GeneratorCallback>;
|
|
60
70
|
export default terraformProjectGenerator;
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/ import { addProjectConfiguration, detectPackageManager, generateFiles, joinPathFragments, OverwriteStrategy, readNxJson, updateJson, updateNxJson } from "@nx/devkit";
|
|
5
5
|
import { join, relative } from "path";
|
|
6
|
+
import { addLicenseCheckToLintTarget } from "../../license/config.js";
|
|
6
7
|
import { getTsLibDetails } from "../../ts/lib/generator.js";
|
|
7
8
|
import { addTsDependencies } from "../../utils/add-dependencies.js";
|
|
8
9
|
import { declareDependencies, ownedElsewhere } from "../../utils/declared-dependencies.js";
|
|
10
|
+
import { formatFilesInSubtree } from "../../utils/format.js";
|
|
9
11
|
import { updateGitIgnore } from "../../utils/git.js";
|
|
10
12
|
import { installDependencies } from "../../utils/install.js";
|
|
11
13
|
import { addGeneratorMetricsIfApplicable } from "../../utils/metrics.js";
|
|
@@ -71,6 +73,35 @@ export const DEPENDENCIES = declareDependencies()({
|
|
|
71
73
|
});
|
|
72
74
|
const NX_EXTEND_PLUGIN = '@nx-extend/terraform';
|
|
73
75
|
export const TERRAFORM_PROJECT_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
|
|
76
|
+
/**
|
|
77
|
+
* Checks formatting, mirroring the TypeScript and Python `format` targets: the
|
|
78
|
+
* base target fails on an unformatted file and the `fix` configuration rewrites
|
|
79
|
+
* it. Writing from the base target would rewrite the `default` input the hash is
|
|
80
|
+
* computed over, so the target could never cache-hit.
|
|
81
|
+
*
|
|
82
|
+
* Scoped to the project's own `src` rather than `-recursive`, so it checks the
|
|
83
|
+
* files the vended templates cover. `-diff` names what to fix when it fails.
|
|
84
|
+
*/ export const TERRAFORM_FORMAT_TARGET = {
|
|
85
|
+
executor: 'nx:run-commands',
|
|
86
|
+
cache: true,
|
|
87
|
+
inputs: [
|
|
88
|
+
'default'
|
|
89
|
+
],
|
|
90
|
+
options: {
|
|
91
|
+
command: 'terraform fmt -check -diff',
|
|
92
|
+
forwardAllArgs: true,
|
|
93
|
+
cwd: '{projectRoot}/src'
|
|
94
|
+
},
|
|
95
|
+
configurations: {
|
|
96
|
+
fix: {
|
|
97
|
+
command: 'terraform fmt'
|
|
98
|
+
},
|
|
99
|
+
'skip-lint': {
|
|
100
|
+
// Cross-platform no-op (`true` is not available on Windows cmd).
|
|
101
|
+
command: 'node -e ""'
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
74
105
|
export async function terraformProjectGenerator(tree, schema) {
|
|
75
106
|
// Just use getTsLibDetails as it isn't specific to TS
|
|
76
107
|
const lib = getTsLibDetails(tree, schema);
|
|
@@ -84,6 +115,19 @@ export async function terraformProjectGenerator(tree, schema) {
|
|
|
84
115
|
// `test` keeps its `.terraform` here rather than in `src`, so initialising it
|
|
85
116
|
// never races the backend-configured targets over the shared one.
|
|
86
117
|
const testDataDir = joinPathFragments(distDir, 'terraform-test');
|
|
118
|
+
// Provider downloads persist here, so a target whose `.terraform` was cleaned
|
|
119
|
+
// links the providers it already has rather than re-downloading them. Nx does
|
|
120
|
+
// not interpolate `{workspaceRoot}` inside `env`, so this is relative to the
|
|
121
|
+
// target's `cwd`. It sits under `.terraform`, which this generator gitignores
|
|
122
|
+
// — that is also what keeps the providers out of Nx's file walk — and unlike
|
|
123
|
+
// `.nx/cache` it survives `nx reset`.
|
|
124
|
+
//
|
|
125
|
+
// One cache per project rather than one for the workspace: two `terraform
|
|
126
|
+
// init` runs filling a shared cache concurrently each compute a different hash
|
|
127
|
+
// for the same provider, because the hash covers a directory the other is
|
|
128
|
+
// still writing, and terraform then rejects the mismatch against the lock
|
|
129
|
+
// file. Per project, no two writers ever meet, so the targets stay parallel.
|
|
130
|
+
const pluginCacheDir = joinPathFragments(outDirToRootRelativePath, '.terraform', 'plugin-cache', '{projectRoot}');
|
|
87
131
|
// Calculate relative path from current project to common/terraform/metrics
|
|
88
132
|
// Use forward slashes for terraform module source paths (even on Windows)
|
|
89
133
|
const metricsModulePath = relative(join(tree.root, lib.dir, 'src'), join(tree.root, 'packages', SHARED_TERRAFORM_DIR, 'src', 'metrics')).replace(/\\/g, '/');
|
|
@@ -130,7 +174,7 @@ export async function terraformProjectGenerator(tree, schema) {
|
|
|
130
174
|
},
|
|
131
175
|
build: {
|
|
132
176
|
dependsOn: [
|
|
133
|
-
'
|
|
177
|
+
'format',
|
|
134
178
|
'checkov',
|
|
135
179
|
'test',
|
|
136
180
|
`${sharedTfProjectName}:build`
|
|
@@ -141,6 +185,12 @@ export async function terraformProjectGenerator(tree, schema) {
|
|
|
141
185
|
'apply'
|
|
142
186
|
]
|
|
143
187
|
},
|
|
188
|
+
// The artifact-only sibling of build, which `plan` depends on.
|
|
189
|
+
assemble: {
|
|
190
|
+
dependsOn: [
|
|
191
|
+
`${sharedTfProjectName}:assemble`
|
|
192
|
+
]
|
|
193
|
+
},
|
|
144
194
|
destroy: {
|
|
145
195
|
executor: 'nx:run-commands',
|
|
146
196
|
defaultConfiguration: 'dev',
|
|
@@ -210,46 +260,65 @@ export async function terraformProjectGenerator(tree, schema) {
|
|
|
210
260
|
'init',
|
|
211
261
|
'validate',
|
|
212
262
|
'^validate',
|
|
213
|
-
'
|
|
263
|
+
'assemble'
|
|
214
264
|
]
|
|
215
265
|
}
|
|
216
266
|
};
|
|
217
267
|
const libTargets = {
|
|
218
268
|
build: {
|
|
219
269
|
dependsOn: [
|
|
220
|
-
'
|
|
270
|
+
'format',
|
|
221
271
|
'checkov',
|
|
222
272
|
'test'
|
|
223
273
|
]
|
|
224
274
|
},
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
275
|
+
// A Terraform library vends modules rather than a deployable artifact, so
|
|
276
|
+
// its `assemble` carries only whatever the consuming projects register on it.
|
|
277
|
+
assemble: {
|
|
278
|
+
executor: 'nx:noop'
|
|
279
|
+
},
|
|
280
|
+
format: TERRAFORM_FORMAT_TARGET,
|
|
281
|
+
// Terraform has no linter of its own, so `lint` orchestrates the format
|
|
282
|
+
// check. It exists so `nx run-many --target lint` reaches terraform
|
|
283
|
+
// projects, and so `--configuration=fix` and `--configuration=skip-lint`
|
|
284
|
+
// propagate to `format` the way they do for TypeScript and Python projects.
|
|
285
|
+
lint: {
|
|
286
|
+
dependsOn: [
|
|
287
|
+
'format'
|
|
288
|
+
]
|
|
236
289
|
},
|
|
237
290
|
init: {
|
|
238
291
|
executor: 'nx:run-commands',
|
|
239
292
|
defaultConfiguration: 'dev',
|
|
240
293
|
configurations: {
|
|
241
294
|
dev: {
|
|
242
|
-
|
|
295
|
+
commands: [
|
|
296
|
+
{
|
|
297
|
+
command: `make-dir ${pluginCacheDir}`,
|
|
298
|
+
forwardAllArgs: false
|
|
299
|
+
},
|
|
300
|
+
'terraform init'
|
|
301
|
+
]
|
|
243
302
|
}
|
|
244
303
|
},
|
|
245
304
|
options: {
|
|
246
305
|
forwardAllArgs: true,
|
|
247
|
-
cwd: '{projectRoot}/src'
|
|
306
|
+
cwd: '{projectRoot}/src',
|
|
307
|
+
parallel: false,
|
|
308
|
+
env: {
|
|
309
|
+
TF_PLUGIN_CACHE_DIR: pluginCacheDir
|
|
310
|
+
}
|
|
248
311
|
}
|
|
249
312
|
},
|
|
313
|
+
// `^production` mirrors `test`: checkov resolves the relative modules a
|
|
314
|
+
// project consumes, so a change in one must invalidate the scan.
|
|
250
315
|
checkov: {
|
|
251
316
|
executor: 'nx:run-commands',
|
|
252
317
|
cache: true,
|
|
318
|
+
inputs: [
|
|
319
|
+
'default',
|
|
320
|
+
'^production'
|
|
321
|
+
],
|
|
253
322
|
outputs: [
|
|
254
323
|
'{workspaceRoot}/dist/{projectRoot}/checkov'
|
|
255
324
|
],
|
|
@@ -268,6 +337,12 @@ export async function terraformProjectGenerator(tree, schema) {
|
|
|
268
337
|
// so it never races the backend-configured targets over the shared one.
|
|
269
338
|
// `^production` is what invalidates the cache when a consumed module
|
|
270
339
|
// changes; `{projectRoot}/**/*` alone would serve a stale pass.
|
|
340
|
+
//
|
|
341
|
+
// `TF_DATA_DIR` is terraform's working directory, not an artifact: its
|
|
342
|
+
// provider entries are symlinks into the shared plugin cache, so restoring
|
|
343
|
+
// it on another machine would yield dangling links while the commands that
|
|
344
|
+
// repopulate them are skipped. Declaring no outputs keeps a cache hit to
|
|
345
|
+
// what it actually asserts — that the tests passed for these inputs.
|
|
271
346
|
test: {
|
|
272
347
|
executor: 'nx:run-commands',
|
|
273
348
|
cache: true,
|
|
@@ -275,11 +350,13 @@ export async function terraformProjectGenerator(tree, schema) {
|
|
|
275
350
|
'default',
|
|
276
351
|
'^production'
|
|
277
352
|
],
|
|
278
|
-
outputs: [
|
|
279
|
-
`{workspaceRoot}/dist/{projectRoot}/terraform-test`
|
|
280
|
-
],
|
|
353
|
+
outputs: [],
|
|
281
354
|
options: {
|
|
282
355
|
commands: [
|
|
356
|
+
{
|
|
357
|
+
command: `make-dir ${pluginCacheDir}`,
|
|
358
|
+
forwardAllArgs: false
|
|
359
|
+
},
|
|
283
360
|
'terraform init -backend=false',
|
|
284
361
|
'terraform test'
|
|
285
362
|
],
|
|
@@ -287,7 +364,8 @@ export async function terraformProjectGenerator(tree, schema) {
|
|
|
287
364
|
cwd: '{projectRoot}/src',
|
|
288
365
|
parallel: false,
|
|
289
366
|
env: {
|
|
290
|
-
TF_DATA_DIR: testDataDir
|
|
367
|
+
TF_DATA_DIR: testDataDir,
|
|
368
|
+
TF_PLUGIN_CACHE_DIR: pluginCacheDir
|
|
291
369
|
}
|
|
292
370
|
}
|
|
293
371
|
},
|
|
@@ -321,6 +399,9 @@ export async function terraformProjectGenerator(tree, schema) {
|
|
|
321
399
|
if (!projectExists(tree, lib.fullyQualifiedName)) {
|
|
322
400
|
addProjectConfiguration(tree, lib.fullyQualifiedName, projectConfiguration);
|
|
323
401
|
}
|
|
402
|
+
// The `lint` target checks licenses alongside formatting, as it does for
|
|
403
|
+
// TypeScript and Python projects.
|
|
404
|
+
addLicenseCheckToLintTarget(tree, lib.fullyQualifiedName);
|
|
324
405
|
// This generator IS the Terraform project, so the provider is fixed.
|
|
325
406
|
addGeneratorMetadata(tree, lib.fullyQualifiedName, TERRAFORM_PROJECT_GENERATOR_INFO, {
|
|
326
407
|
iac: 'terraform'
|
|
@@ -367,6 +448,9 @@ export async function terraformProjectGenerator(tree, schema) {
|
|
|
367
448
|
return packageJson;
|
|
368
449
|
});
|
|
369
450
|
}
|
|
451
|
+
// `updateProjectConfiguration` re-serialises project.json with every inline
|
|
452
|
+
// array expanded, which the vended `format` target rejects.
|
|
453
|
+
await formatFilesInSubtree(tree);
|
|
370
454
|
// `@nx-extend/terraform` is registered as an Nx plugin in nx.json, so Nx
|
|
371
455
|
// loads it when computing the project graph — it must resolve even if the
|
|
372
456
|
// caller would otherwise prefer to defer installing.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/terraform/project/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addProjectConfiguration,\n detectPackageManager,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n readNxJson,\n type TargetConfiguration,\n type Tree,\n updateJson,\n updateNxJson,\n} from '@nx/devkit';\nimport { join, relative } from 'path';\nimport { getTsLibDetails } from '../../ts/lib/generator.js';\nimport { addTsDependencies } from '../../utils/add-dependencies.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport { updateGitIgnore } from '../../utils/git.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { kebabCase } from '../../utils/names.js';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx.js';\nimport { sortObjectKeys } from '../../utils/object.js';\nimport { uvxCommand } from '../../utils/py.js';\nimport { sharedConstructsGenerator } from '../../utils/shared-constructs.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n SHARED_TERRAFORM_DIR,\n SHARED_TERRAFORM_NAME,\n} from '../../utils/shared-constructs-constants.js';\nimport {\n terraformProviderVersions,\n withVersions,\n} from '../../utils/versions.js';\nimport type { TerraformProjectGeneratorSchema } from './schema';\n\n// Terraform projects carry no package.json, so their build tooling and the AWS\n// SDK the vended deploy scripts import are declared at the workspace root. This\n// generator records no metadata, so nothing a predicate could read.\nexport const DEPENDENCIES = declareDependencies()({\n ts: [\n { name: '@nx-extend/terraform', dev: true, root: true },\n { name: 'make-dir-cli', dev: true, root: true },\n { name: 'tsx', dev: true, root: true },\n { name: '@aws-sdk/client-s3', dev: true, root: true },\n { name: '@aws-sdk/client-sts', dev: true, root: true },\n { name: '@aws-sdk/credential-providers', dev: true, root: true },\n { name: '@smithy/config-resolver', dev: true, root: true },\n { name: '@smithy/node-config-provider', dev: true, root: true },\n // Declared for its pinned version, which goes into npm's `overrides` below.\n { name: '@nx/devkit', versionOnly: true },\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n});\n\nconst NX_EXTEND_PLUGIN = '@nx-extend/terraform';\nexport const TERRAFORM_PROJECT_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport async function terraformProjectGenerator(\n tree: Tree,\n schema: TerraformProjectGeneratorSchema,\n): Promise<GeneratorCallback> {\n // Just use getTsLibDetails as it isn't specific to TS\n const lib = getTsLibDetails(tree, schema);\n const { fullyQualifiedName: sharedTfProjectName } = getTsLibDetails(tree, {\n name: SHARED_TERRAFORM_NAME,\n });\n\n const outDirToRootRelativePath = relative(\n join(tree.root, lib.dir, 'src'),\n tree.root,\n ).replace(/\\\\/g, '/');\n const distDir = joinPathFragments(\n outDirToRootRelativePath,\n 'dist',\n '{projectRoot}',\n );\n const tfDistDir = joinPathFragments(distDir, 'terraform');\n const checkovReportJsonPath = joinPathFragments(\n distDir,\n 'checkov',\n 'checkov_report.json',\n );\n // `test` keeps its `.terraform` here rather than in `src`, so initialising it\n // never races the backend-configured targets over the shared one.\n const testDataDir = joinPathFragments(distDir, 'terraform-test');\n\n // Calculate relative path from current project to common/terraform/metrics\n // Use forward slashes for terraform module source paths (even on Windows)\n const metricsModulePath = relative(\n join(tree.root, lib.dir, 'src'),\n join(tree.root, 'packages', SHARED_TERRAFORM_DIR, 'src', 'metrics'),\n ).replace(/\\\\/g, '/');\n\n updateGitIgnore(tree, '.', (patterns) => [...patterns, '.terraform']);\n\n const applicationTargets: {\n [targetName: string]: TargetConfiguration;\n } = {\n apply: {\n executor: 'nx:run-commands',\n defaultConfiguration: 'dev',\n configurations: {\n dev: {\n command: `terraform apply ${tfDistDir}/dev.tfplan`,\n },\n },\n options: {\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n dependsOn: ['plan'],\n },\n bootstrap: {\n executor: 'nx:run-commands',\n options: {\n forwardAllArgs: true,\n commands: ['tsx {projectRoot}/scripts/bootstrap.ts {projectRoot}'],\n cwd: '{workspaceRoot}',\n },\n },\n 'bootstrap-destroy': {\n executor: 'nx:run-commands',\n options: {\n forwardAllArgs: true,\n commands: [\n 'tsx {projectRoot}/scripts/bootstrap-destroy.ts {projectRoot}',\n ],\n cwd: '{workspaceRoot}',\n },\n },\n build: {\n dependsOn: ['fmt', 'checkov', 'test', `${sharedTfProjectName}:build`],\n },\n deploy: {\n dependsOn: ['apply'],\n },\n destroy: {\n executor: 'nx:run-commands',\n defaultConfiguration: 'dev',\n configurations: {\n dev: {\n command: 'terraform destroy -var-file=env/dev.tfvars',\n },\n },\n options: {\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n dependsOn: ['init'],\n },\n init: {\n executor: 'nx:run-commands',\n defaultConfiguration: 'dev',\n configurations: {\n dev: {\n env: { TF_ENV: 'dev' },\n },\n },\n options: {\n forwardAllArgs: true,\n commands: ['tsx {projectRoot}/scripts/init.ts {projectRoot}'],\n cwd: '{workspaceRoot}',\n },\n dependsOn: ['^init'],\n },\n output: {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default'],\n options: {\n command: 'terraform output -json',\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n },\n plan: {\n executor: 'nx:run-commands',\n defaultConfiguration: 'dev',\n configurations: {\n dev: {\n commands: [\n `make-dir ${tfDistDir}`,\n `terraform plan -var-file=env/dev.tfvars -out=${tfDistDir}/dev.tfplan`,\n ],\n },\n },\n options: {\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n parallel: false,\n },\n dependsOn: ['init', 'validate', '^validate', 'build'],\n },\n };\n\n const libTargets: {\n [targetName: string]: TargetConfiguration;\n } = {\n build: {\n dependsOn: ['fmt', 'checkov', 'test'],\n },\n fmt: {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default'],\n options: {\n command: 'terraform fmt',\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n },\n init: {\n executor: 'nx:run-commands',\n defaultConfiguration: 'dev',\n configurations: {\n dev: {\n command: 'terraform init',\n },\n },\n options: {\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n },\n checkov: {\n executor: 'nx:run-commands',\n cache: true,\n outputs: ['{workspaceRoot}/dist/{projectRoot}/checkov'],\n options: {\n command: uvxCommand(\n 'checkov',\n `--config-file ../checkov.yml --directory . -o cli -o json --output-file-path console,${checkovReportJsonPath}`,\n ),\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n },\n // Terraform's native test framework, which runs any `.tftest.hcl` files.\n // A project with none is a no-op success.\n //\n // `-backend=false` installs the modules and providers the tests need\n // without configuring the S3 backend, so this runs before `bootstrap` and\n // needs no credentials. `TF_DATA_DIR` keeps that `.terraform` out of `src`,\n // so it never races the backend-configured targets over the shared one.\n // `^production` is what invalidates the cache when a consumed module\n // changes; `{projectRoot}/**/*` alone would serve a stale pass.\n test: {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default', '^production'],\n outputs: [`{workspaceRoot}/dist/{projectRoot}/terraform-test`],\n options: {\n commands: ['terraform init -backend=false', 'terraform test'],\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n parallel: false,\n env: { TF_DATA_DIR: testDataDir },\n },\n },\n validate: {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default'],\n options: {\n command: 'terraform validate',\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n dependsOn: ['init'],\n },\n };\n\n const projectConfiguration = {\n root: lib.dir,\n projectType: schema.type,\n sourceRoot: joinPathFragments(lib.dir, 'src'),\n targets: sortObjectKeys({\n ...libTargets,\n ...(schema.type === 'application' ? applicationTargets : {}),\n }),\n };\n\n // Only create the project configuration on first run; skip it on re-run so\n // existing project.json customisations are preserved.\n if (!projectExists(tree, lib.fullyQualifiedName)) {\n addProjectConfiguration(tree, lib.fullyQualifiedName, projectConfiguration);\n }\n // This generator IS the Terraform project, so the provider is fixed.\n addGeneratorMetadata(\n tree,\n lib.fullyQualifiedName,\n TERRAFORM_PROJECT_GENERATOR_INFO,\n { iac: 'terraform' },\n );\n\n generateFiles(\n tree, // the virtual file system\n joinPathFragments(import.meta.dirname, `./files/${schema.type}`), // path to the file templates\n lib.dir, // destination path of the files\n {\n metricsModulePath,\n stateKeyPrefix: kebabCase(lib.fullyQualifiedName),\n ...terraformProviderVersions(),\n },\n {\n overwriteStrategy: OverwriteStrategy.Overwrite,\n },\n );\n\n // Checkov skips are the user's to curate, so preserve any they have added.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, './files/checkov'),\n lib.dir,\n {},\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n const nxJson = readNxJson(tree);\n\n if (\n !nxJson.plugins?.find((p) =>\n typeof p === 'string'\n ? p === NX_EXTEND_PLUGIN\n : p.plugin === NX_EXTEND_PLUGIN,\n )\n ) {\n nxJson.plugins = [...(nxJson.plugins ?? []), NX_EXTEND_PLUGIN];\n updateNxJson(tree, nxJson);\n }\n\n // Ensure shared constructs for Terraform are created\n await sharedConstructsGenerator(tree, { iac: 'terraform' }, DEPENDENCIES);\n\n // Add Terraform metrics\n await addGeneratorMetricsIfApplicable(tree, [\n TERRAFORM_PROJECT_GENERATOR_INFO,\n ]);\n\n addTsDependencies(tree, DEPENDENCIES);\n\n // @nx-extend/terraform has a peer dependency on @nx/devkit ^21.0.0 which causes\n // npm install to fail, so for NPM we add a resolution\n // Can remove when https://github.com/TriPSs/nx-extend/issues/407 is addressed\n if (detectPackageManager() === 'npm') {\n updateJson(tree, 'package.json', (packageJson) => {\n packageJson.overrides = {\n ...packageJson.overrides,\n ...withVersions(DEPENDENCIES, ['@nx/devkit']),\n };\n return packageJson;\n });\n }\n\n // `@nx-extend/terraform` is registered as an Nx plugin in nx.json, so Nx\n // loads it when computing the project graph — it must resolve even if the\n // caller would otherwise prefer to defer installing.\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript'],\n ensureResolvable: [NX_EXTEND_PLUGIN],\n });\n}\nexport default terraformProjectGenerator;\n"],"names":["addProjectConfiguration","detectPackageManager","generateFiles","joinPathFragments","OverwriteStrategy","readNxJson","updateJson","updateNxJson","join","relative","getTsLibDetails","addTsDependencies","declareDependencies","ownedElsewhere","updateGitIgnore","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","addGeneratorMetadata","getGeneratorInfo","projectExists","sortObjectKeys","uvxCommand","sharedConstructsGenerator","SHARED_CONSTRUCTS_DEPENDENCIES","SHARED_TERRAFORM_DIR","SHARED_TERRAFORM_NAME","terraformProviderVersions","withVersions","DEPENDENCIES","ts","name","dev","root","versionOnly","NX_EXTEND_PLUGIN","TERRAFORM_PROJECT_GENERATOR_INFO","filename","terraformProjectGenerator","tree","schema","lib","fullyQualifiedName","sharedTfProjectName","outDirToRootRelativePath","dir","replace","distDir","tfDistDir","checkovReportJsonPath","testDataDir","metricsModulePath","patterns","applicationTargets","apply","executor","defaultConfiguration","configurations","command","options","forwardAllArgs","cwd","dependsOn","bootstrap","commands","build","deploy","destroy","init","env","TF_ENV","output","cache","inputs","plan","parallel","libTargets","fmt","checkov","outputs","test","TF_DATA_DIR","validate","projectConfiguration","projectType","type","sourceRoot","targets","iac","dirname","stateKeyPrefix","overwriteStrategy","Overwrite","KeepExisting","nxJson","plugins","find","p","plugin","packageJson","overrides","preferInstallDependencies","languages","ensureResolvable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/terraform/project/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addProjectConfiguration,\n detectPackageManager,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n readNxJson,\n type TargetConfiguration,\n type Tree,\n updateJson,\n updateNxJson,\n} from '@nx/devkit';\nimport { join, relative } from 'path';\nimport { addLicenseCheckToLintTarget } from '../../license/config.js';\nimport { getTsLibDetails } from '../../ts/lib/generator.js';\nimport { addTsDependencies } from '../../utils/add-dependencies.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { updateGitIgnore } from '../../utils/git.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { kebabCase } from '../../utils/names.js';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx.js';\nimport { sortObjectKeys } from '../../utils/object.js';\nimport { uvxCommand } from '../../utils/py.js';\nimport { sharedConstructsGenerator } from '../../utils/shared-constructs.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n SHARED_TERRAFORM_DIR,\n SHARED_TERRAFORM_NAME,\n} from '../../utils/shared-constructs-constants.js';\nimport {\n terraformProviderVersions,\n withVersions,\n} from '../../utils/versions.js';\nimport type { TerraformProjectGeneratorSchema } from './schema';\n\n// Terraform projects carry no package.json, so their build tooling and the AWS\n// SDK the vended deploy scripts import are declared at the workspace root. This\n// generator records no metadata, so nothing a predicate could read.\nexport const DEPENDENCIES = declareDependencies()({\n ts: [\n { name: '@nx-extend/terraform', dev: true, root: true },\n { name: 'make-dir-cli', dev: true, root: true },\n { name: 'tsx', dev: true, root: true },\n { name: '@aws-sdk/client-s3', dev: true, root: true },\n { name: '@aws-sdk/client-sts', dev: true, root: true },\n { name: '@aws-sdk/credential-providers', dev: true, root: true },\n { name: '@smithy/config-resolver', dev: true, root: true },\n { name: '@smithy/node-config-provider', dev: true, root: true },\n // Declared for its pinned version, which goes into npm's `overrides` below.\n { name: '@nx/devkit', versionOnly: true },\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n});\n\nconst NX_EXTEND_PLUGIN = '@nx-extend/terraform';\nexport const TERRAFORM_PROJECT_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\n/**\n * Checks formatting, mirroring the TypeScript and Python `format` targets: the\n * base target fails on an unformatted file and the `fix` configuration rewrites\n * it. Writing from the base target would rewrite the `default` input the hash is\n * computed over, so the target could never cache-hit.\n *\n * Scoped to the project's own `src` rather than `-recursive`, so it checks the\n * files the vended templates cover. `-diff` names what to fix when it fails.\n */\nexport const TERRAFORM_FORMAT_TARGET: TargetConfiguration = {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default'],\n options: {\n command: 'terraform fmt -check -diff',\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n configurations: {\n fix: {\n command: 'terraform fmt',\n },\n 'skip-lint': {\n // Cross-platform no-op (`true` is not available on Windows cmd).\n command: 'node -e \"\"',\n },\n },\n};\n\nexport async function terraformProjectGenerator(\n tree: Tree,\n schema: TerraformProjectGeneratorSchema,\n): Promise<GeneratorCallback> {\n // Just use getTsLibDetails as it isn't specific to TS\n const lib = getTsLibDetails(tree, schema);\n const { fullyQualifiedName: sharedTfProjectName } = getTsLibDetails(tree, {\n name: SHARED_TERRAFORM_NAME,\n });\n\n const outDirToRootRelativePath = relative(\n join(tree.root, lib.dir, 'src'),\n tree.root,\n ).replace(/\\\\/g, '/');\n const distDir = joinPathFragments(\n outDirToRootRelativePath,\n 'dist',\n '{projectRoot}',\n );\n const tfDistDir = joinPathFragments(distDir, 'terraform');\n const checkovReportJsonPath = joinPathFragments(\n distDir,\n 'checkov',\n 'checkov_report.json',\n );\n // `test` keeps its `.terraform` here rather than in `src`, so initialising it\n // never races the backend-configured targets over the shared one.\n const testDataDir = joinPathFragments(distDir, 'terraform-test');\n\n // Provider downloads persist here, so a target whose `.terraform` was cleaned\n // links the providers it already has rather than re-downloading them. Nx does\n // not interpolate `{workspaceRoot}` inside `env`, so this is relative to the\n // target's `cwd`. It sits under `.terraform`, which this generator gitignores\n // — that is also what keeps the providers out of Nx's file walk — and unlike\n // `.nx/cache` it survives `nx reset`.\n //\n // One cache per project rather than one for the workspace: two `terraform\n // init` runs filling a shared cache concurrently each compute a different hash\n // for the same provider, because the hash covers a directory the other is\n // still writing, and terraform then rejects the mismatch against the lock\n // file. Per project, no two writers ever meet, so the targets stay parallel.\n const pluginCacheDir = joinPathFragments(\n outDirToRootRelativePath,\n '.terraform',\n 'plugin-cache',\n '{projectRoot}',\n );\n\n // Calculate relative path from current project to common/terraform/metrics\n // Use forward slashes for terraform module source paths (even on Windows)\n const metricsModulePath = relative(\n join(tree.root, lib.dir, 'src'),\n join(tree.root, 'packages', SHARED_TERRAFORM_DIR, 'src', 'metrics'),\n ).replace(/\\\\/g, '/');\n\n updateGitIgnore(tree, '.', (patterns) => [...patterns, '.terraform']);\n\n const applicationTargets: {\n [targetName: string]: TargetConfiguration;\n } = {\n apply: {\n executor: 'nx:run-commands',\n defaultConfiguration: 'dev',\n configurations: {\n dev: {\n command: `terraform apply ${tfDistDir}/dev.tfplan`,\n },\n },\n options: {\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n dependsOn: ['plan'],\n },\n bootstrap: {\n executor: 'nx:run-commands',\n options: {\n forwardAllArgs: true,\n commands: ['tsx {projectRoot}/scripts/bootstrap.ts {projectRoot}'],\n cwd: '{workspaceRoot}',\n },\n },\n 'bootstrap-destroy': {\n executor: 'nx:run-commands',\n options: {\n forwardAllArgs: true,\n commands: [\n 'tsx {projectRoot}/scripts/bootstrap-destroy.ts {projectRoot}',\n ],\n cwd: '{workspaceRoot}',\n },\n },\n build: {\n dependsOn: ['format', 'checkov', 'test', `${sharedTfProjectName}:build`],\n },\n deploy: {\n dependsOn: ['apply'],\n },\n // The artifact-only sibling of build, which `plan` depends on.\n assemble: {\n dependsOn: [`${sharedTfProjectName}:assemble`],\n },\n destroy: {\n executor: 'nx:run-commands',\n defaultConfiguration: 'dev',\n configurations: {\n dev: {\n command: 'terraform destroy -var-file=env/dev.tfvars',\n },\n },\n options: {\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n dependsOn: ['init'],\n },\n init: {\n executor: 'nx:run-commands',\n defaultConfiguration: 'dev',\n configurations: {\n dev: {\n env: { TF_ENV: 'dev' },\n },\n },\n options: {\n forwardAllArgs: true,\n commands: ['tsx {projectRoot}/scripts/init.ts {projectRoot}'],\n cwd: '{workspaceRoot}',\n },\n dependsOn: ['^init'],\n },\n output: {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default'],\n options: {\n command: 'terraform output -json',\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n },\n plan: {\n executor: 'nx:run-commands',\n defaultConfiguration: 'dev',\n configurations: {\n dev: {\n commands: [\n `make-dir ${tfDistDir}`,\n `terraform plan -var-file=env/dev.tfvars -out=${tfDistDir}/dev.tfplan`,\n ],\n },\n },\n options: {\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n parallel: false,\n },\n dependsOn: ['init', 'validate', '^validate', 'assemble'],\n },\n };\n\n const libTargets: {\n [targetName: string]: TargetConfiguration;\n } = {\n build: {\n dependsOn: ['format', 'checkov', 'test'],\n },\n // A Terraform library vends modules rather than a deployable artifact, so\n // its `assemble` carries only whatever the consuming projects register on it.\n assemble: {\n executor: 'nx:noop',\n },\n format: TERRAFORM_FORMAT_TARGET,\n // Terraform has no linter of its own, so `lint` orchestrates the format\n // check. It exists so `nx run-many --target lint` reaches terraform\n // projects, and so `--configuration=fix` and `--configuration=skip-lint`\n // propagate to `format` the way they do for TypeScript and Python projects.\n lint: {\n dependsOn: ['format'],\n },\n init: {\n executor: 'nx:run-commands',\n defaultConfiguration: 'dev',\n configurations: {\n dev: {\n commands: [\n { command: `make-dir ${pluginCacheDir}`, forwardAllArgs: false },\n 'terraform init',\n ],\n },\n },\n options: {\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n parallel: false,\n env: { TF_PLUGIN_CACHE_DIR: pluginCacheDir },\n },\n },\n // `^production` mirrors `test`: checkov resolves the relative modules a\n // project consumes, so a change in one must invalidate the scan.\n checkov: {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default', '^production'],\n outputs: ['{workspaceRoot}/dist/{projectRoot}/checkov'],\n options: {\n command: uvxCommand(\n 'checkov',\n `--config-file ../checkov.yml --directory . -o cli -o json --output-file-path console,${checkovReportJsonPath}`,\n ),\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n },\n // Terraform's native test framework, which runs any `.tftest.hcl` files.\n // A project with none is a no-op success.\n //\n // `-backend=false` installs the modules and providers the tests need\n // without configuring the S3 backend, so this runs before `bootstrap` and\n // needs no credentials. `TF_DATA_DIR` keeps that `.terraform` out of `src`,\n // so it never races the backend-configured targets over the shared one.\n // `^production` is what invalidates the cache when a consumed module\n // changes; `{projectRoot}/**/*` alone would serve a stale pass.\n //\n // `TF_DATA_DIR` is terraform's working directory, not an artifact: its\n // provider entries are symlinks into the shared plugin cache, so restoring\n // it on another machine would yield dangling links while the commands that\n // repopulate them are skipped. Declaring no outputs keeps a cache hit to\n // what it actually asserts — that the tests passed for these inputs.\n test: {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default', '^production'],\n outputs: [],\n options: {\n commands: [\n { command: `make-dir ${pluginCacheDir}`, forwardAllArgs: false },\n 'terraform init -backend=false',\n 'terraform test',\n ],\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n parallel: false,\n env: { TF_DATA_DIR: testDataDir, TF_PLUGIN_CACHE_DIR: pluginCacheDir },\n },\n },\n validate: {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default'],\n options: {\n command: 'terraform validate',\n forwardAllArgs: true,\n cwd: '{projectRoot}/src',\n },\n dependsOn: ['init'],\n },\n };\n\n const projectConfiguration = {\n root: lib.dir,\n projectType: schema.type,\n sourceRoot: joinPathFragments(lib.dir, 'src'),\n targets: sortObjectKeys({\n ...libTargets,\n ...(schema.type === 'application' ? applicationTargets : {}),\n }),\n };\n\n // Only create the project configuration on first run; skip it on re-run so\n // existing project.json customisations are preserved.\n if (!projectExists(tree, lib.fullyQualifiedName)) {\n addProjectConfiguration(tree, lib.fullyQualifiedName, projectConfiguration);\n }\n\n // The `lint` target checks licenses alongside formatting, as it does for\n // TypeScript and Python projects.\n addLicenseCheckToLintTarget(tree, lib.fullyQualifiedName);\n\n // This generator IS the Terraform project, so the provider is fixed.\n addGeneratorMetadata(\n tree,\n lib.fullyQualifiedName,\n TERRAFORM_PROJECT_GENERATOR_INFO,\n { iac: 'terraform' },\n );\n\n generateFiles(\n tree, // the virtual file system\n joinPathFragments(import.meta.dirname, `./files/${schema.type}`), // path to the file templates\n lib.dir, // destination path of the files\n {\n metricsModulePath,\n stateKeyPrefix: kebabCase(lib.fullyQualifiedName),\n ...terraformProviderVersions(),\n },\n {\n overwriteStrategy: OverwriteStrategy.Overwrite,\n },\n );\n\n // Checkov skips are the user's to curate, so preserve any they have added.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, './files/checkov'),\n lib.dir,\n {},\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n const nxJson = readNxJson(tree);\n\n if (\n !nxJson.plugins?.find((p) =>\n typeof p === 'string'\n ? p === NX_EXTEND_PLUGIN\n : p.plugin === NX_EXTEND_PLUGIN,\n )\n ) {\n nxJson.plugins = [...(nxJson.plugins ?? []), NX_EXTEND_PLUGIN];\n updateNxJson(tree, nxJson);\n }\n\n // Ensure shared constructs for Terraform are created\n await sharedConstructsGenerator(tree, { iac: 'terraform' }, DEPENDENCIES);\n\n // Add Terraform metrics\n await addGeneratorMetricsIfApplicable(tree, [\n TERRAFORM_PROJECT_GENERATOR_INFO,\n ]);\n\n addTsDependencies(tree, DEPENDENCIES);\n\n // @nx-extend/terraform has a peer dependency on @nx/devkit ^21.0.0 which causes\n // npm install to fail, so for NPM we add a resolution\n // Can remove when https://github.com/TriPSs/nx-extend/issues/407 is addressed\n if (detectPackageManager() === 'npm') {\n updateJson(tree, 'package.json', (packageJson) => {\n packageJson.overrides = {\n ...packageJson.overrides,\n ...withVersions(DEPENDENCIES, ['@nx/devkit']),\n };\n return packageJson;\n });\n }\n\n // `updateProjectConfiguration` re-serialises project.json with every inline\n // array expanded, which the vended `format` target rejects.\n await formatFilesInSubtree(tree);\n\n // `@nx-extend/terraform` is registered as an Nx plugin in nx.json, so Nx\n // loads it when computing the project graph — it must resolve even if the\n // caller would otherwise prefer to defer installing.\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript'],\n ensureResolvable: [NX_EXTEND_PLUGIN],\n });\n}\nexport default terraformProjectGenerator;\n"],"names":["addProjectConfiguration","detectPackageManager","generateFiles","joinPathFragments","OverwriteStrategy","readNxJson","updateJson","updateNxJson","join","relative","addLicenseCheckToLintTarget","getTsLibDetails","addTsDependencies","declareDependencies","ownedElsewhere","formatFilesInSubtree","updateGitIgnore","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","addGeneratorMetadata","getGeneratorInfo","projectExists","sortObjectKeys","uvxCommand","sharedConstructsGenerator","SHARED_CONSTRUCTS_DEPENDENCIES","SHARED_TERRAFORM_DIR","SHARED_TERRAFORM_NAME","terraformProviderVersions","withVersions","DEPENDENCIES","ts","name","dev","root","versionOnly","NX_EXTEND_PLUGIN","TERRAFORM_PROJECT_GENERATOR_INFO","filename","TERRAFORM_FORMAT_TARGET","executor","cache","inputs","options","command","forwardAllArgs","cwd","configurations","fix","terraformProjectGenerator","tree","schema","lib","fullyQualifiedName","sharedTfProjectName","outDirToRootRelativePath","dir","replace","distDir","tfDistDir","checkovReportJsonPath","testDataDir","pluginCacheDir","metricsModulePath","patterns","applicationTargets","apply","defaultConfiguration","dependsOn","bootstrap","commands","build","deploy","assemble","destroy","init","env","TF_ENV","output","plan","parallel","libTargets","format","lint","TF_PLUGIN_CACHE_DIR","checkov","outputs","test","TF_DATA_DIR","validate","projectConfiguration","projectType","type","sourceRoot","targets","iac","dirname","stateKeyPrefix","overwriteStrategy","Overwrite","KeepExisting","nxJson","plugins","find","p","plugin","packageJson","overrides","preferInstallDependencies","languages","ensureResolvable"],"mappings":"AAAA;;;CAGC,GACD,SACEA,uBAAuB,EACvBC,oBAAoB,EAEpBC,aAAa,EACbC,iBAAiB,EACjBC,iBAAiB,EACjBC,UAAU,EAGVC,UAAU,EACVC,YAAY,QACP,aAAa;AACpB,SAASC,IAAI,EAAEC,QAAQ,QAAQ,OAAO;AACtC,SAASC,2BAA2B,QAAQ,0BAA0B;AACtE,SAASC,eAAe,QAAQ,4BAA4B;AAC5D,SAASC,iBAAiB,QAAQ,kCAAkC;AACpE,SACEC,mBAAmB,EACnBC,cAAc,QACT,uCAAuC;AAC9C,SAASC,oBAAoB,QAAQ,wBAAwB;AAC7D,SAASC,eAAe,QAAQ,qBAAqB;AACrD,SAASC,mBAAmB,QAAQ,yBAAyB;AAC7D,SAASC,+BAA+B,QAAQ,yBAAyB;AACzE,SAASC,SAAS,QAAQ,uBAAuB;AACjD,SACEC,oBAAoB,EACpBC,gBAAgB,EAEhBC,aAAa,QACR,oBAAoB;AAC3B,SAASC,cAAc,QAAQ,wBAAwB;AACvD,SAASC,UAAU,QAAQ,oBAAoB;AAC/C,SAASC,yBAAyB,QAAQ,mCAAmC;AAC7E,SACEC,8BAA8B,EAC9BC,oBAAoB,EACpBC,qBAAqB,QAChB,6CAA6C;AACpD,SACEC,yBAAyB,EACzBC,YAAY,QACP,0BAA0B;AAGjC,+EAA+E;AAC/E,gFAAgF;AAChF,oEAAoE;AACpE,OAAO,MAAMC,eAAelB,sBAAsB;IAChDmB,IAAI;QACF;YAAEC,MAAM;YAAwBC,KAAK;YAAMC,MAAM;QAAK;QACtD;YAAEF,MAAM;YAAgBC,KAAK;YAAMC,MAAM;QAAK;QAC9C;YAAEF,MAAM;YAAOC,KAAK;YAAMC,MAAM;QAAK;QACrC;YAAEF,MAAM;YAAsBC,KAAK;YAAMC,MAAM;QAAK;QACpD;YAAEF,MAAM;YAAuBC,KAAK;YAAMC,MAAM;QAAK;QACrD;YAAEF,MAAM;YAAiCC,KAAK;YAAMC,MAAM;QAAK;QAC/D;YAAEF,MAAM;YAA2BC,KAAK;YAAMC,MAAM;QAAK;QACzD;YAAEF,MAAM;YAAgCC,KAAK;YAAMC,MAAM;QAAK;QAC9D,4EAA4E;QAC5E;YAAEF,MAAM;YAAcG,aAAa;QAAK;WACrCtB,eAAeY;KACnB;AACH,GAAG;AAEH,MAAMW,mBAAmB;AACzB,OAAO,MAAMC,mCACXjB,iBAAiB,YAAYkB,QAAQ,EAAE;AAEzC;;;;;;;;CAQC,GACD,OAAO,MAAMC,0BAA+C;IAC1DC,UAAU;IACVC,OAAO;IACPC,QAAQ;QAAC;KAAU;IACnBC,SAAS;QACPC,SAAS;QACTC,gBAAgB;QAChBC,KAAK;IACP;IACAC,gBAAgB;QACdC,KAAK;YACHJ,SAAS;QACX;QACA,aAAa;YACX,iEAAiE;YACjEA,SAAS;QACX;IACF;AACF,EAAE;AAEF,OAAO,eAAeK,0BACpBC,IAAU,EACVC,MAAuC;IAEvC,sDAAsD;IACtD,MAAMC,MAAM1C,gBAAgBwC,MAAMC;IAClC,MAAM,EAAEE,oBAAoBC,mBAAmB,EAAE,GAAG5C,gBAAgBwC,MAAM;QACxElB,MAAML;IACR;IAEA,MAAM4B,2BAA2B/C,SAC/BD,KAAK2C,KAAKhB,IAAI,EAAEkB,IAAII,GAAG,EAAE,QACzBN,KAAKhB,IAAI,EACTuB,OAAO,CAAC,OAAO;IACjB,MAAMC,UAAUxD,kBACdqD,0BACA,QACA;IAEF,MAAMI,YAAYzD,kBAAkBwD,SAAS;IAC7C,MAAME,wBAAwB1D,kBAC5BwD,SACA,WACA;IAEF,8EAA8E;IAC9E,kEAAkE;IAClE,MAAMG,cAAc3D,kBAAkBwD,SAAS;IAE/C,8EAA8E;IAC9E,8EAA8E;IAC9E,6EAA6E;IAC7E,8EAA8E;IAC9E,6EAA6E;IAC7E,sCAAsC;IACtC,EAAE;IACF,0EAA0E;IAC1E,+EAA+E;IAC/E,0EAA0E;IAC1E,0EAA0E;IAC1E,6EAA6E;IAC7E,MAAMI,iBAAiB5D,kBACrBqD,0BACA,cACA,gBACA;IAGF,2EAA2E;IAC3E,0EAA0E;IAC1E,MAAMQ,oBAAoBvD,SACxBD,KAAK2C,KAAKhB,IAAI,EAAEkB,IAAII,GAAG,EAAE,QACzBjD,KAAK2C,KAAKhB,IAAI,EAAE,YAAYR,sBAAsB,OAAO,YACzD+B,OAAO,CAAC,OAAO;IAEjB1C,gBAAgBmC,MAAM,KAAK,CAACc,WAAa;eAAIA;YAAU;SAAa;IAEpE,MAAMC,qBAEF;QACFC,OAAO;YACL1B,UAAU;YACV2B,sBAAsB;YACtBpB,gBAAgB;gBACdd,KAAK;oBACHW,SAAS,CAAC,gBAAgB,EAAEe,UAAU,WAAW,CAAC;gBACpD;YACF;YACAhB,SAAS;gBACPE,gBAAgB;gBAChBC,KAAK;YACP;YACAsB,WAAW;gBAAC;aAAO;QACrB;QACAC,WAAW;YACT7B,UAAU;YACVG,SAAS;gBACPE,gBAAgB;gBAChByB,UAAU;oBAAC;iBAAuD;gBAClExB,KAAK;YACP;QACF;QACA,qBAAqB;YACnBN,UAAU;YACVG,SAAS;gBACPE,gBAAgB;gBAChByB,UAAU;oBACR;iBACD;gBACDxB,KAAK;YACP;QACF;QACAyB,OAAO;YACLH,WAAW;gBAAC;gBAAU;gBAAW;gBAAQ,GAAGd,oBAAoB,MAAM,CAAC;aAAC;QAC1E;QACAkB,QAAQ;YACNJ,WAAW;gBAAC;aAAQ;QACtB;QACA,+DAA+D;QAC/DK,UAAU;YACRL,WAAW;gBAAC,GAAGd,oBAAoB,SAAS,CAAC;aAAC;QAChD;QACAoB,SAAS;YACPlC,UAAU;YACV2B,sBAAsB;YACtBpB,gBAAgB;gBACdd,KAAK;oBACHW,SAAS;gBACX;YACF;YACAD,SAAS;gBACPE,gBAAgB;gBAChBC,KAAK;YACP;YACAsB,WAAW;gBAAC;aAAO;QACrB;QACAO,MAAM;YACJnC,UAAU;YACV2B,sBAAsB;YACtBpB,gBAAgB;gBACdd,KAAK;oBACH2C,KAAK;wBAAEC,QAAQ;oBAAM;gBACvB;YACF;YACAlC,SAAS;gBACPE,gBAAgB;gBAChByB,UAAU;oBAAC;iBAAkD;gBAC7DxB,KAAK;YACP;YACAsB,WAAW;gBAAC;aAAQ;QACtB;QACAU,QAAQ;YACNtC,UAAU;YACVC,OAAO;YACPC,QAAQ;gBAAC;aAAU;YACnBC,SAAS;gBACPC,SAAS;gBACTC,gBAAgB;gBAChBC,KAAK;YACP;QACF;QACAiC,MAAM;YACJvC,UAAU;YACV2B,sBAAsB;YACtBpB,gBAAgB;gBACdd,KAAK;oBACHqC,UAAU;wBACR,CAAC,SAAS,EAAEX,WAAW;wBACvB,CAAC,6CAA6C,EAAEA,UAAU,WAAW,CAAC;qBACvE;gBACH;YACF;YACAhB,SAAS;gBACPE,gBAAgB;gBAChBC,KAAK;gBACLkC,UAAU;YACZ;YACAZ,WAAW;gBAAC;gBAAQ;gBAAY;gBAAa;aAAW;QAC1D;IACF;IAEA,MAAMa,aAEF;QACFV,OAAO;YACLH,WAAW;gBAAC;gBAAU;gBAAW;aAAO;QAC1C;QACA,0EAA0E;QAC1E,8EAA8E;QAC9EK,UAAU;YACRjC,UAAU;QACZ;QACA0C,QAAQ3C;QACR,wEAAwE;QACxE,oEAAoE;QACpE,yEAAyE;QACzE,4EAA4E;QAC5E4C,MAAM;YACJf,WAAW;gBAAC;aAAS;QACvB;QACAO,MAAM;YACJnC,UAAU;YACV2B,sBAAsB;YACtBpB,gBAAgB;gBACdd,KAAK;oBACHqC,UAAU;wBACR;4BAAE1B,SAAS,CAAC,SAAS,EAAEkB,gBAAgB;4BAAEjB,gBAAgB;wBAAM;wBAC/D;qBACD;gBACH;YACF;YACAF,SAAS;gBACPE,gBAAgB;gBAChBC,KAAK;gBACLkC,UAAU;gBACVJ,KAAK;oBAAEQ,qBAAqBtB;gBAAe;YAC7C;QACF;QACA,wEAAwE;QACxE,iEAAiE;QACjEuB,SAAS;YACP7C,UAAU;YACVC,OAAO;YACPC,QAAQ;gBAAC;gBAAW;aAAc;YAClC4C,SAAS;gBAAC;aAA6C;YACvD3C,SAAS;gBACPC,SAASrB,WACP,WACA,CAAC,qFAAqF,EAAEqC,uBAAuB;gBAEjHf,gBAAgB;gBAChBC,KAAK;YACP;QACF;QACA,yEAAyE;QACzE,0CAA0C;QAC1C,EAAE;QACF,qEAAqE;QACrE,0EAA0E;QAC1E,4EAA4E;QAC5E,wEAAwE;QACxE,qEAAqE;QACrE,gEAAgE;QAChE,EAAE;QACF,uEAAuE;QACvE,2EAA2E;QAC3E,2EAA2E;QAC3E,yEAAyE;QACzE,qEAAqE;QACrEyC,MAAM;YACJ/C,UAAU;YACVC,OAAO;YACPC,QAAQ;gBAAC;gBAAW;aAAc;YAClC4C,SAAS,EAAE;YACX3C,SAAS;gBACP2B,UAAU;oBACR;wBAAE1B,SAAS,CAAC,SAAS,EAAEkB,gBAAgB;wBAAEjB,gBAAgB;oBAAM;oBAC/D;oBACA;iBACD;gBACDA,gBAAgB;gBAChBC,KAAK;gBACLkC,UAAU;gBACVJ,KAAK;oBAAEY,aAAa3B;oBAAauB,qBAAqBtB;gBAAe;YACvE;QACF;QACA2B,UAAU;YACRjD,UAAU;YACVC,OAAO;YACPC,QAAQ;gBAAC;aAAU;YACnBC,SAAS;gBACPC,SAAS;gBACTC,gBAAgB;gBAChBC,KAAK;YACP;YACAsB,WAAW;gBAAC;aAAO;QACrB;IACF;IAEA,MAAMsB,uBAAuB;QAC3BxD,MAAMkB,IAAII,GAAG;QACbmC,aAAaxC,OAAOyC,IAAI;QACxBC,YAAY3F,kBAAkBkD,IAAII,GAAG,EAAE;QACvCsC,SAASxE,eAAe;YACtB,GAAG2D,UAAU;YACb,GAAI9B,OAAOyC,IAAI,KAAK,gBAAgB3B,qBAAqB,CAAC,CAAC;QAC7D;IACF;IAEA,2EAA2E;IAC3E,sDAAsD;IACtD,IAAI,CAAC5C,cAAc6B,MAAME,IAAIC,kBAAkB,GAAG;QAChDtD,wBAAwBmD,MAAME,IAAIC,kBAAkB,EAAEqC;IACxD;IAEA,yEAAyE;IACzE,kCAAkC;IAClCjF,4BAA4ByC,MAAME,IAAIC,kBAAkB;IAExD,qEAAqE;IACrElC,qBACE+B,MACAE,IAAIC,kBAAkB,EACtBhB,kCACA;QAAE0D,KAAK;IAAY;IAGrB9F,cACEiD,MACAhD,kBAAkB,YAAY8F,OAAO,EAAE,CAAC,QAAQ,EAAE7C,OAAOyC,IAAI,EAAE,GAC/DxC,IAAII,GAAG,EACP;QACEO;QACAkC,gBAAgB/E,UAAUkC,IAAIC,kBAAkB;QAChD,GAAGzB,2BAA2B;IAChC,GACA;QACEsE,mBAAmB/F,kBAAkBgG,SAAS;IAChD;IAGF,2EAA2E;IAC3ElG,cACEiD,MACAhD,kBAAkB,YAAY8F,OAAO,EAAE,oBACvC5C,IAAII,GAAG,EACP,CAAC,GACD;QACE0C,mBAAmB/F,kBAAkBiG,YAAY;IACnD;IAGF,MAAMC,SAASjG,WAAW8C;IAE1B,IACE,CAACmD,OAAOC,OAAO,EAAEC,KAAK,CAACC,IACrB,OAAOA,MAAM,WACTA,MAAMpE,mBACNoE,EAAEC,MAAM,KAAKrE,mBAEnB;QACAiE,OAAOC,OAAO,GAAG;eAAKD,OAAOC,OAAO,IAAI,EAAE;YAAGlE;SAAiB;QAC9D9B,aAAa4C,MAAMmD;IACrB;IAEA,qDAAqD;IACrD,MAAM7E,0BAA0B0B,MAAM;QAAE6C,KAAK;IAAY,GAAGjE;IAE5D,wBAAwB;IACxB,MAAMb,gCAAgCiC,MAAM;QAC1Cb;KACD;IAED1B,kBAAkBuC,MAAMpB;IAExB,gFAAgF;IAChF,sDAAsD;IACtD,8EAA8E;IAC9E,IAAI9B,2BAA2B,OAAO;QACpCK,WAAW6C,MAAM,gBAAgB,CAACwD;YAChCA,YAAYC,SAAS,GAAG;gBACtB,GAAGD,YAAYC,SAAS;gBACxB,GAAG9E,aAAaC,cAAc;oBAAC;iBAAa,CAAC;YAC/C;YACA,OAAO4E;QACT;IACF;IAEA,4EAA4E;IAC5E,4DAA4D;IAC5D,MAAM5F,qBAAqBoC;IAE3B,yEAAyE;IACzE,0EAA0E;IAC1E,qDAAqD;IACrD,OAAO,IACLlC,oBAAoBkC,MAAMC,OAAOyD,yBAAyB,EAAE;YAC1DC,WAAW;gBAAC;aAAa;YACzBC,kBAAkB;gBAAC1E;aAAiB;QACtC;AACJ;AACA,eAAea,0BAA0B"}
|
|
@@ -15,7 +15,7 @@ import { addGeneratorMetricsIfApplicable } from "../../utils/metrics.js";
|
|
|
15
15
|
import { esmVars } from "../../utils/module-format.js";
|
|
16
16
|
import { kebabCase, toClassName } from "../../utils/names.js";
|
|
17
17
|
import { getNpmScopePrefix } from "../../utils/npm-scope.js";
|
|
18
|
-
import {
|
|
18
|
+
import { addArtifactDependencyToTargets, addGeneratorMetadata, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../utils/nx.js";
|
|
19
19
|
import { sortObjectKeys } from "../../utils/object.js";
|
|
20
20
|
import { getPackageManagerDisplayCommands } from "../../utils/pkg-manager.js";
|
|
21
21
|
import { assignPort } from "../../utils/port.js";
|
|
@@ -216,7 +216,7 @@ export async function tsTrpcApiGenerator(tree, options) {
|
|
|
216
216
|
]
|
|
217
217
|
}, DEPENDENCIES);
|
|
218
218
|
}
|
|
219
|
-
|
|
219
|
+
addArtifactDependencyToTargets(projectConfig, 'bundle');
|
|
220
220
|
// Terraform defines one Lambda function per operation from a generated
|
|
221
221
|
// metadata file; CDK derives the same information from the router's types.
|
|
222
222
|
if (iac === 'terraform' && getIntegrationPattern(options) === 'isolated') {
|