@aws/nx-plugin 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE-THIRD-PARTY +3 -3
  2. package/migrations.json +26 -1
  3. package/package.json +1 -1
  4. package/src/infra/app/__snapshots__/generator.spec.ts.snap +10 -0
  5. package/src/infra/app/files/app/README.md.template +12 -0
  6. package/src/infra/app/generator.js +8 -0
  7. package/src/infra/app/generator.js.map +1 -1
  8. package/src/migrations/latest/cache-inputs-outputs/metadata.json +3 -0
  9. package/src/migrations/latest/cache-inputs-outputs/migration.d.ts +6 -0
  10. package/src/migrations/latest/cache-inputs-outputs/migration.js +176 -0
  11. package/src/migrations/latest/cache-inputs-outputs/migration.js.map +1 -0
  12. package/src/migrations/latest/infra-test-loop/metadata.json +3 -0
  13. package/src/migrations/latest/infra-test-loop/migration.d.ts +6 -0
  14. package/src/migrations/latest/infra-test-loop/migration.js +110 -0
  15. package/src/migrations/latest/infra-test-loop/migration.js.map +1 -0
  16. package/src/migrations/latest/pin-strands-express-peer/metadata.json +3 -0
  17. package/src/migrations/latest/pin-strands-express-peer/migration.d.ts +29 -0
  18. package/src/migrations/latest/pin-strands-express-peer/migration.js +58 -0
  19. package/src/migrations/latest/pin-strands-express-peer/migration.js.map +1 -0
  20. package/src/migrations/latest/py-dynamodb-type-base-model-meta/metadata.json +3 -0
  21. package/src/migrations/latest/py-dynamodb-type-base-model-meta/migration.d.ts +6 -0
  22. package/src/migrations/latest/py-dynamodb-type-base-model-meta/migration.js +87 -0
  23. package/src/migrations/latest/py-dynamodb-type-base-model-meta/migration.js.map +1 -0
  24. package/src/migrations/latest/rdb-drop-lambda-rie/metadata.json +3 -0
  25. package/src/migrations/latest/rdb-drop-lambda-rie/migration.d.ts +6 -0
  26. package/src/migrations/latest/rdb-drop-lambda-rie/migration.js +105 -0
  27. package/src/migrations/latest/rdb-drop-lambda-rie/migration.js.map +1 -0
  28. package/src/migrations/v1.0.0-rc.90/0004-python-test-input-scoping/migration.js +8 -2
  29. package/src/migrations/v1.0.0-rc.90/0004-python-test-input-scoping/migration.js.map +1 -1
  30. package/src/open-api/py-client/files/client/__clientModuleName__.py.template +17 -6
  31. package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +4 -4
  32. package/src/py/dynamodb/files/__name__/entities/base.py.template +2 -2
  33. package/src/py/rdb/__snapshots__/generator.spec.ts.snap +20 -8
  34. package/src/py/rdb/files/Dockerfile.create-db-user.template +5 -2
  35. package/src/py/rdb/files/Dockerfile.migration.template +5 -2
  36. package/src/smithy/project/__snapshots__/generator.spec.ts.snap +9 -0
  37. package/src/smithy/project/generator.d.ts +9 -0
  38. package/src/smithy/project/generator.js +15 -0
  39. package/src/smithy/project/generator.js.map +1 -1
  40. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +2 -0
  41. package/src/terraform/project/generator.js +2 -4
  42. package/src/terraform/project/generator.js.map +1 -1
  43. package/src/ts/agent/a2a-connection/generator.d.ts +26 -30
  44. package/src/ts/agent/a2a-connection/generator.js +9 -5
  45. package/src/ts/agent/a2a-connection/generator.js.map +1 -1
  46. package/src/ts/agent/gateway-connection/generator.d.ts +5 -7
  47. package/src/ts/agent/gateway-connection/generator.js +12 -0
  48. package/src/ts/agent/gateway-connection/generator.js.map +1 -1
  49. package/src/ts/agent/generator.d.ts +3 -8
  50. package/src/ts/agent/generator.js +16 -2
  51. package/src/ts/agent/generator.js.map +1 -1
  52. package/src/ts/agent/mcp-connection/generator.d.ts +5 -7
  53. package/src/ts/agent/mcp-connection/generator.js +12 -0
  54. package/src/ts/agent/mcp-connection/generator.js.map +1 -1
  55. package/src/ts/astro-docs/generator.d.ts +4 -4
  56. package/src/ts/astro-docs/generator.js +10 -4
  57. package/src/ts/astro-docs/generator.js.map +1 -1
  58. package/src/ts/lib/__snapshots__/generator.spec.ts.snap +1 -1
  59. package/src/ts/lib/generator.d.ts +14 -3
  60. package/src/ts/lib/generator.js +18 -7
  61. package/src/ts/lib/generator.js.map +1 -1
  62. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +4 -2
  63. package/src/ts/rdb/files/Dockerfile.template +4 -2
  64. package/src/ts/rdb/generator.js +4 -0
  65. package/src/ts/rdb/generator.js.map +1 -1
  66. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +102 -2
  67. package/src/utils/__snapshots__/cdk-test-setup.spec.ts.snap +25 -0
  68. package/src/utils/agent-connection/agent-connection.d.ts +28 -5
  69. package/src/utils/agent-connection/agent-connection.js +39 -14
  70. package/src/utils/agent-connection/agent-connection.js.map +1 -1
  71. package/src/utils/cdk-test-setup.d.ts +22 -0
  72. package/src/utils/cdk-test-setup.js +38 -0
  73. package/src/utils/cdk-test-setup.js.map +1 -0
  74. package/src/utils/files/cdk-test-setup/tests/global-setup.ts.template +45 -0
  75. package/src/utils/shared-constructs.js +2 -0
  76. package/src/utils/shared-constructs.js.map +1 -1
  77. package/src/utils/test/python-dependencies.d.ts +6 -0
  78. package/src/utils/test/python-dependencies.js +9 -0
  79. package/src/utils/test/python-dependencies.js.map +1 -1
  80. package/src/utils/test/warm-python-cache.js +40 -21
  81. package/src/utils/test/warm-python-cache.js.map +1 -1
  82. package/src/utils/versions.d.ts +2 -2
  83. package/src/utils/versions.js +2 -2
  84. package/src/utils/versions.js.map +1 -1
@@ -4274,7 +4274,7 @@ SOFTWARE.
4274
4274
 
4275
4275
  ---
4276
4276
 
4277
- The following software may be included in this product: @oxc-project/types (0.151.0)
4277
+ The following software may be included in this product: @oxc-project/types (0.152.0)
4278
4278
  This software contains the following license and notice below:
4279
4279
 
4280
4280
  MIT License
@@ -13381,7 +13381,7 @@ SOFTWARE.**
13381
13381
 
13382
13382
  ---
13383
13383
 
13384
- The following software may be included in this product: proxy-addr (2.0.7)
13384
+ The following software may be included in this product: proxy-addr (2.0.8)
13385
13385
  This software contains the following license and notice below:
13386
13386
 
13387
13387
  (The MIT License)
@@ -14165,7 +14165,7 @@ SOFTWARE.
14165
14165
 
14166
14166
  ---
14167
14167
 
14168
- The following software may be included in this product: rolldown (1.2.11)
14168
+ The following software may be included in this product: rolldown (1.2.12)
14169
14169
  This software contains the following license and notice below:
14170
14170
 
14171
14171
  MIT License
package/migrations.json CHANGED
@@ -2,6 +2,31 @@
2
2
  "$schema": "http://json-schema.org/schema",
3
3
  "name": "@aws/nx-plugin",
4
4
  "generators": {
5
+ "latest-pin-strands-express-peer": {
6
+ "version": "1.0.7",
7
+ "description": "Declare express in every project that declares @strands-agents/sdk without it so @strands-agents/sdk resolves to a single peer-suffixed instance",
8
+ "implementation": "./src/migrations/latest/pin-strands-express-peer/migration"
9
+ },
10
+ "latest-rdb-drop-lambda-rie": {
11
+ "version": "1.0.7",
12
+ "description": "Remove the Lambda Runtime Interface Emulator from vended ts#rdb and py#rdb Dockerfiles so its known HIGH vulnerabilities are not present in the image",
13
+ "implementation": "./src/migrations/latest/rdb-drop-lambda-rie/migration"
14
+ },
15
+ "latest-infra-test-loop": {
16
+ "version": "1.0.8",
17
+ "description": "Run CDK infrastructure tests against the artifacts their stacks deploy rather than every upstream build, in a per-run temp directory with CDK asset bundling skipped",
18
+ "implementation": "./src/migrations/latest/infra-test-loop/migration"
19
+ },
20
+ "latest-py-dynamodb-type-base-model-meta": {
21
+ "version": "1.0.8",
22
+ "description": "Declare the py#dynamodb BaseModel Meta class as a subclass of pynamodb's MetaProtocol so the generated project type checks with ty 0.0.86",
23
+ "implementation": "./src/migrations/latest/py-dynamodb-type-base-model-meta/migration"
24
+ },
25
+ "latest-cache-inputs-outputs": {
26
+ "version": "1.0.8",
27
+ "description": "Keep checkov reports and vitest coverage out of downstream task hashes, declare Smithy build inputs, cache ts#rdb Prisma client generation and stop caching Terraform output",
28
+ "implementation": "./src/migrations/latest/cache-inputs-outputs/migration"
29
+ },
5
30
  "v1.0.0-rc.50-0001-modernize-function-props-cast": {
6
31
  "version": "1.0.0-rc.50",
7
32
  "description": "Replace the legacy angle-bracket FunctionProps type assertion with the modern as syntax in generated API constructs",
@@ -383,7 +408,7 @@
383
408
  "implementation": "./src/migrations/v1.0.5/0001-api-custom-domain-runtime-config/migration"
384
409
  },
385
410
  "sync-vended-versions": {
386
- "version": "1.0.6",
411
+ "version": "1.0.8",
387
412
  "description": "Sync vended dependency versions and the tracked plugin version to those vended by this release",
388
413
  "implementation": "./src/utils/version-upgrade-migration/migration"
389
414
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws/nx-plugin",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/awslabs/nx-plugin-for-aws.git",
@@ -281,6 +281,11 @@ exports[`infra generator > should configure project.json with correct targets >
281
281
  "{workspaceRoot}/dist/{projectRoot}/cdk.out",
282
282
  ],
283
283
  },
284
+ "test": {
285
+ "dependsOn": [
286
+ "^assemble",
287
+ ],
288
+ },
284
289
  },
285
290
  }
286
291
  `;
@@ -893,6 +898,11 @@ exports[`infra generator > should handle custom project names correctly > custom
893
898
  "{workspaceRoot}/dist/{projectRoot}/cdk.out",
894
899
  ],
895
900
  },
901
+ "test": {
902
+ "dependsOn": [
903
+ "^assemble",
904
+ ],
905
+ },
896
906
  },
897
907
  }
898
908
  `;
@@ -9,6 +9,18 @@ Run `<%= pkgMgrCmd %> nx build <%= fullyQualifiedName %> [--skip-nx-cache]` to b
9
9
 
10
10
  Run `<%= pkgMgrCmd %> nx test <%= fullyQualifiedName %>` to execute the unit tests via Vitest.
11
11
 
12
+ Tests run against the artifacts each deployed project's `assemble` target produces (bundles, packages and, where a project builds a container image, the image build), rather than every upstream project's lint, test and type-check gates. Projects that build a container image (container agents and MCP servers, RDB) still run their image build under `test`, because that build also stages the asset the construct reads.
13
+
14
+ `tests/global-setup.ts` gives each test run its own temporary directory, removed afterwards, and skips CDK asset bundling (`aws:cdk:bundling-stacks: []`). To bundle assets in a single test, opt back in:
15
+
16
+ ```ts
17
+ const app = new App({
18
+ postCliContext: { 'aws:cdk:bundling-stacks': ['**'] },
19
+ });
20
+ ```
21
+
22
+ `synth` is the check that every vended asset exists, because it stages the real assets. Run `<%= pkgMgrCmd %> nx synth <%= fullyQualifiedName %>`.
23
+
12
24
  ### Updating snapshots
13
25
 
14
26
  To update snapshots, run the following command:
@@ -6,6 +6,7 @@ import path from "path";
6
6
  import tsProjectGenerator, { getTsLibDetails } from "../../ts/lib/generator.js";
7
7
  import { mergeTsReferences } from "../../ts/lib/ts-project-utils.js";
8
8
  import { addTsDependencies } from "../../utils/add-dependencies.js";
9
+ import { addCdkTestGlobalSetup } from "../../utils/cdk-test-setup.js";
9
10
  import { resolveContainers } from "../../utils/containers.js";
10
11
  import { declareDependencies, ownedElsewhere } from "../../utils/declared-dependencies.js";
11
12
  import { formatFilesInSubtree } from "../../utils/format.js";
@@ -115,8 +116,11 @@ export async function tsInfraGenerator(tree, schema) {
115
116
  const sandboxStagePattern = `"${namespace}-sandbox/**"`;
116
117
  // `tsProjectGenerator` scaffolds a library `src`, which the CDK app layout
117
118
  // replaces. Only on creation — on a re-run this is the user's infrastructure.
119
+ // Likewise its generic README, which would otherwise keep the infra README
120
+ // below from being written (it is generated `KeepExisting`).
118
121
  if (isNewProject) {
119
122
  tree.delete(joinPathFragments(libraryRoot, 'src'));
123
+ tree.delete(joinPathFragments(libraryRoot, 'README.md'));
120
124
  }
121
125
  // The guide walks through declaring resources in
122
126
  // `src/stacks/application-stack.ts` and adding stages to `src/main.ts`, so
@@ -134,12 +138,16 @@ export async function tsInfraGenerator(tree, schema) {
134
138
  }, {
135
139
  overwriteStrategy: OverwriteStrategy.KeepExisting
136
140
  });
141
+ await addCdkTestGlobalSetup(tree, libraryRoot);
137
142
  updateJson(tree, `${libraryRoot}/project.json`, (config)=>{
138
143
  config.projectType = 'application';
139
144
  // `synth` is the CDK artifact, so it belongs on `assemble` too; `checkov`
140
145
  // is a quality gate, so it stays on `build` alone.
141
146
  addArtifactDependencyToTargets(config, 'synth');
142
147
  addDependencyToTargetIfNotPresent(config, 'build', 'checkov');
148
+ // Infra tests read the deployed projects' artifacts, not their quality
149
+ // gates, so they replace the `^build` target default with `^assemble`.
150
+ addDependencyToTargetIfNotPresent(config, 'test', '^assemble');
143
151
  config.targets.compile.outputs = [
144
152
  '{workspaceRoot}/dist/{projectRoot}/tsc'
145
153
  ];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/nx-plugin/src/infra/app/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n readProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport path from 'path';\nimport tsProjectGenerator, { getTsLibDetails } from '../../ts/lib/generator.js';\nimport { mergeTsReferences } from '../../ts/lib/ts-project-utils.js';\nimport { addTsDependencies } from '../../utils/add-dependencies.js';\nimport { resolveContainers } from '../../utils/containers.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addLocalProjectDependency } from '../../utils/local-project-dependency.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { esmVars } from '../../utils/module-format.js';\nimport { kebabCase } from '../../utils/names.js';\nimport { getNpmScopePrefix } from '../../utils/npm-scope.js';\nimport {\n addArtifactDependencyToTargets,\n addDependencyToTargetIfNotPresent,\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx.js';\nimport { sortObjectKeys } from '../../utils/object.js';\nimport { getPackageManagerDisplayCommands } from '../../utils/pkg-manager.js';\nimport { uvxCommand } from '../../utils/py.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../utils/shared-constructs.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_INFRA_CONFIG_DIR,\n} from '../../utils/shared-constructs-constants.js';\nimport { sharedInfraConfigGenerator } from '../../utils/shared-infra-config.js';\nimport {\n SHARED_INFRA_SCRIPTS_DEPENDENCIES,\n sharedInfraScriptsGenerator,\n} from '../../utils/shared-infra-scripts.js';\nimport type { TsInfraGeneratorSchema } from './schema';\n\n// This generator records no metadata, so nothing a predicate could read: the\n// CDK app always needs the app libraries, and the CLI, bundler and tsx are\n// shared tooling.\nexport const DEPENDENCIES = declareDependencies()({\n ts: [\n { name: 'aws-cdk-lib' },\n { name: 'constructs' },\n { name: 'source-map-support' },\n // The `aws-cdk` CLI, esbuild (CDK bundling) and tsx are shared tooling.\n { name: 'aws-cdk', dev: true, root: true },\n { name: 'esbuild', dev: true, root: true },\n { name: 'tsx', dev: true, root: true },\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ...ownedElsewhere(SHARED_INFRA_SCRIPTS_DEPENDENCIES),\n ],\n});\n\nexport const INFRA_APP_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport async function tsInfraGenerator(\n tree: Tree,\n schema: TsInfraGeneratorSchema,\n): Promise<GeneratorCallback> {\n const lib = getTsLibDetails(tree, schema);\n\n const isNewProject = !projectExists(tree, lib.fullyQualifiedName);\n if (isNewProject) {\n await tsProjectGenerator(tree, {\n ...schema,\n preferInstallDependencies: false,\n });\n }\n\n // CDK shells out to a container engine to build image assets. Default\n // (docker) needs no env override; finch is set via CDK_DOCKER per\n // https://docs.aws.amazon.com/cdk/v2/guide/build-containers.html#build-container-replace.\n const containers = await resolveContainers(tree, 'inherit');\n const cdkEnv: Record<string, string> | undefined =\n containers === 'docker' ? undefined : { CDK_DOCKER: containers };\n const withCdkEnv = <T extends Record<string, unknown>>(opts: T): T => {\n if (!cdkEnv) return opts;\n const existingEnv = (opts.env as Record<string, string> | undefined) ?? {};\n return { ...opts, env: { ...existingEnv, ...cdkEnv } } as T;\n };\n\n // This generator IS the CDK infrastructure project, so the provider is fixed.\n addGeneratorMetadata(tree, lib.fullyQualifiedName, INFRA_APP_GENERATOR_INFO, {\n iac: 'cdk',\n });\n\n // Shared constructs always in CDK for typescript infra generator\n await sharedConstructsGenerator(\n tree,\n {\n iac: 'cdk',\n },\n DEPENDENCIES,\n );\n\n // Shared infra-config and infra-scripts packages (lazy creation, only when enabled)\n const stageConfig = schema.stageConfig ?? false;\n if (stageConfig) {\n await sharedInfraConfigGenerator(tree);\n await sharedInfraScriptsGenerator(tree, DEPENDENCIES);\n }\n\n const synthDirFromRoot = `/dist/${lib.dir}/cdk.out`;\n const synthDirFromProject =\n lib.dir\n .split('/')\n .map(() => '..')\n .join('/') + `/dist/${lib.dir}/cdk.out`;\n const distDirFromProjectRoot =\n lib.dir\n .split('/')\n .map(() => '..')\n .join('/') + '/dist/{projectRoot}/cdk.out';\n const projectConfig = readProjectConfiguration(tree, lib.fullyQualifiedName);\n const libraryRoot = projectConfig.root;\n const npmScopePrefix = getNpmScopePrefix(tree);\n const scopeAlias = npmScopePrefix;\n const fullyQualifiedName = `${npmScopePrefix}${schema.name}`;\n const namespace = kebabCase(fullyQualifiedName);\n // The stage instantiated in main.ts. `**` so the pattern also selects stacks\n // nested below the stage's own stacks, such as the `us-east-1` WebACL stack a\n // website creates - `cdk destroy` only deletes the stacks its pattern selects,\n // so a single `*` leaves those behind. Quoted so the shell does not glob.\n const sandboxStagePattern = `\"${namespace}-sandbox/**\"`;\n\n // `tsProjectGenerator` scaffolds a library `src`, which the CDK app layout\n // replaces. Only on creation — on a re-run this is the user's infrastructure.\n if (isNewProject) {\n tree.delete(joinPathFragments(libraryRoot, 'src'));\n }\n\n // The guide walks through declaring resources in\n // `src/stacks/application-stack.ts` and adding stages to `src/main.ts`, so\n // everything here is scaffolded once and then left alone.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, './files/app'),\n libraryRoot,\n {\n synthDir: synthDirFromProject,\n scopeAlias: scopeAlias,\n namespace,\n fullyQualifiedName,\n pkgMgrCmd: getPackageManagerDisplayCommands().exec,\n dir: lib.dir,\n stageConfig,\n ...schema,\n ...esmVars(tree),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n updateJson(\n tree,\n `${libraryRoot}/project.json`,\n (config: ProjectConfiguration) => {\n config.projectType = 'application';\n // `synth` is the CDK artifact, so it belongs on `assemble` too; `checkov`\n // is a quality gate, so it stays on `build` alone.\n addArtifactDependencyToTargets(config, 'synth');\n addDependencyToTargetIfNotPresent(config, 'build', 'checkov');\n config.targets.compile.outputs = [\n '{workspaceRoot}/dist/{projectRoot}/tsc',\n ];\n config.targets.synth = {\n cache: true,\n executor: 'nx:run-commands',\n inputs: ['default'],\n outputs: ['{workspaceRoot}/dist/{projectRoot}/cdk.out'],\n dependsOn: ['^assemble', 'compile'], // compile clobbers dist directory, so ensure synth runs afterwards\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk synth',\n }),\n };\n // `default` rather than the synth directory: `dist` is gitignored, so a\n // fileset input pointed at it matches no tracked file and hashes to a\n // constant — the scan would cache-hit forever and pass on infrastructure\n // it never read. `default` carries the project's own sources plus the\n // transitive `dependentTasksOutputFiles` entry, which resolves against\n // the upstream `synth` task and so hashes the template actually scanned.\n config.targets.checkov = {\n cache: true,\n executor: 'nx:run-commands',\n inputs: ['default'],\n outputs: ['{workspaceRoot}/dist/{projectRoot}/checkov'],\n dependsOn: ['synth'],\n options: {\n command: uvxCommand(\n 'checkov',\n '--config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation',\n ),\n },\n };\n config.targets.deploy = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n // No --express: this target deploys whichever stage is named, including\n // beta and prod, so it waits for full resource stabilization. Express\n // mode belongs to `deploy-sandbox`, which only ever deploys a sandbox.\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-deploy.ts ${libraryRoot}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk deploy --require-approval=never',\n }),\n };\n config.targets['deploy-sandbox'] = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-deploy.ts ${libraryRoot} ${sandboxStagePattern} --express`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk deploy --require-approval=never ${sandboxStagePattern} --express`,\n }),\n };\n config.targets['deploy-ci'] = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk deploy --require-approval=never --app ${distDirFromProjectRoot}`,\n }),\n };\n config.targets.destroy = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-destroy.ts ${libraryRoot}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk destroy',\n }),\n };\n config.targets['destroy-sandbox'] = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-destroy.ts ${libraryRoot} ${sandboxStagePattern}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk destroy ${sandboxStagePattern}`,\n }),\n };\n config.targets['destroy-ci'] = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk destroy --app ${distDirFromProjectRoot}`,\n }),\n };\n config.targets.cdk = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk',\n }),\n };\n config.targets.bootstrap = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk bootstrap',\n }),\n };\n config.targets = sortObjectKeys(config.targets);\n return config;\n },\n );\n\n addTsDependencies(tree, DEPENDENCIES, { projectRoot: libraryRoot });\n\n updateJson(tree, `${libraryRoot}/tsconfig.lib.json`, (tsConfig) => ({\n ...tsConfig,\n references: mergeTsReferences(tsConfig.references, [\n {\n path: `${path.relative(\n libraryRoot,\n `${tree.root}/${PACKAGES_DIR}`,\n )}/${SHARED_CONSTRUCTS_DIR}/tsconfig.lib.json`,\n },\n ...(stageConfig\n ? [\n {\n path: `${path.relative(\n libraryRoot,\n `${tree.root}/${PACKAGES_DIR}`,\n )}/${SHARED_INFRA_CONFIG_DIR}/tsconfig.json`,\n },\n ]\n : []),\n ]),\n }));\n\n // `main.ts` and the application stack import the shared constructs.\n addLocalProjectDependency(tree, {\n consumerRoot: libraryRoot,\n dependencyRoot: joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR),\n });\n if (stageConfig) {\n addLocalProjectDependency(tree, {\n consumerRoot: libraryRoot,\n dependencyRoot: joinPathFragments(PACKAGES_DIR, SHARED_INFRA_CONFIG_DIR),\n });\n }\n\n await addGeneratorMetricsIfApplicable(tree, [INFRA_APP_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript'],\n });\n}\nexport default tsInfraGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","readProjectConfiguration","updateJson","path","tsProjectGenerator","getTsLibDetails","mergeTsReferences","addTsDependencies","resolveContainers","declareDependencies","ownedElsewhere","formatFilesInSubtree","installDependencies","addLocalProjectDependency","addGeneratorMetricsIfApplicable","esmVars","kebabCase","getNpmScopePrefix","addArtifactDependencyToTargets","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","projectExists","sortObjectKeys","getPackageManagerDisplayCommands","uvxCommand","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_INFRA_CONFIG_DIR","sharedInfraConfigGenerator","SHARED_INFRA_SCRIPTS_DEPENDENCIES","sharedInfraScriptsGenerator","DEPENDENCIES","ts","name","dev","root","INFRA_APP_GENERATOR_INFO","filename","tsInfraGenerator","tree","schema","lib","isNewProject","fullyQualifiedName","preferInstallDependencies","containers","cdkEnv","undefined","CDK_DOCKER","withCdkEnv","opts","existingEnv","env","iac","stageConfig","synthDirFromRoot","dir","synthDirFromProject","split","map","join","distDirFromProjectRoot","projectConfig","libraryRoot","npmScopePrefix","scopeAlias","namespace","sandboxStagePattern","delete","dirname","synthDir","pkgMgrCmd","exec","overwriteStrategy","KeepExisting","config","projectType","targets","compile","outputs","synth","cache","executor","inputs","dependsOn","options","cwd","command","checkov","deploy","destroy","cdk","bootstrap","projectRoot","tsConfig","references","relative","consumerRoot","dependencyRoot","languages"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/infra/app/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n readProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport path from 'path';\nimport tsProjectGenerator, { getTsLibDetails } from '../../ts/lib/generator.js';\nimport { mergeTsReferences } from '../../ts/lib/ts-project-utils.js';\nimport { addTsDependencies } from '../../utils/add-dependencies.js';\nimport { addCdkTestGlobalSetup } from '../../utils/cdk-test-setup.js';\nimport { resolveContainers } from '../../utils/containers.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addLocalProjectDependency } from '../../utils/local-project-dependency.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { esmVars } from '../../utils/module-format.js';\nimport { kebabCase } from '../../utils/names.js';\nimport { getNpmScopePrefix } from '../../utils/npm-scope.js';\nimport {\n addArtifactDependencyToTargets,\n addDependencyToTargetIfNotPresent,\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx.js';\nimport { sortObjectKeys } from '../../utils/object.js';\nimport { getPackageManagerDisplayCommands } from '../../utils/pkg-manager.js';\nimport { uvxCommand } from '../../utils/py.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../utils/shared-constructs.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_INFRA_CONFIG_DIR,\n} from '../../utils/shared-constructs-constants.js';\nimport { sharedInfraConfigGenerator } from '../../utils/shared-infra-config.js';\nimport {\n SHARED_INFRA_SCRIPTS_DEPENDENCIES,\n sharedInfraScriptsGenerator,\n} from '../../utils/shared-infra-scripts.js';\nimport type { TsInfraGeneratorSchema } from './schema';\n\n// This generator records no metadata, so nothing a predicate could read: the\n// CDK app always needs the app libraries, and the CLI, bundler and tsx are\n// shared tooling.\nexport const DEPENDENCIES = declareDependencies()({\n ts: [\n { name: 'aws-cdk-lib' },\n { name: 'constructs' },\n { name: 'source-map-support' },\n // The `aws-cdk` CLI, esbuild (CDK bundling) and tsx are shared tooling.\n { name: 'aws-cdk', dev: true, root: true },\n { name: 'esbuild', dev: true, root: true },\n { name: 'tsx', dev: true, root: true },\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ...ownedElsewhere(SHARED_INFRA_SCRIPTS_DEPENDENCIES),\n ],\n});\n\nexport const INFRA_APP_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport async function tsInfraGenerator(\n tree: Tree,\n schema: TsInfraGeneratorSchema,\n): Promise<GeneratorCallback> {\n const lib = getTsLibDetails(tree, schema);\n\n const isNewProject = !projectExists(tree, lib.fullyQualifiedName);\n if (isNewProject) {\n await tsProjectGenerator(tree, {\n ...schema,\n preferInstallDependencies: false,\n });\n }\n\n // CDK shells out to a container engine to build image assets. Default\n // (docker) needs no env override; finch is set via CDK_DOCKER per\n // https://docs.aws.amazon.com/cdk/v2/guide/build-containers.html#build-container-replace.\n const containers = await resolveContainers(tree, 'inherit');\n const cdkEnv: Record<string, string> | undefined =\n containers === 'docker' ? undefined : { CDK_DOCKER: containers };\n const withCdkEnv = <T extends Record<string, unknown>>(opts: T): T => {\n if (!cdkEnv) return opts;\n const existingEnv = (opts.env as Record<string, string> | undefined) ?? {};\n return { ...opts, env: { ...existingEnv, ...cdkEnv } } as T;\n };\n\n // This generator IS the CDK infrastructure project, so the provider is fixed.\n addGeneratorMetadata(tree, lib.fullyQualifiedName, INFRA_APP_GENERATOR_INFO, {\n iac: 'cdk',\n });\n\n // Shared constructs always in CDK for typescript infra generator\n await sharedConstructsGenerator(\n tree,\n {\n iac: 'cdk',\n },\n DEPENDENCIES,\n );\n\n // Shared infra-config and infra-scripts packages (lazy creation, only when enabled)\n const stageConfig = schema.stageConfig ?? false;\n if (stageConfig) {\n await sharedInfraConfigGenerator(tree);\n await sharedInfraScriptsGenerator(tree, DEPENDENCIES);\n }\n\n const synthDirFromRoot = `/dist/${lib.dir}/cdk.out`;\n const synthDirFromProject =\n lib.dir\n .split('/')\n .map(() => '..')\n .join('/') + `/dist/${lib.dir}/cdk.out`;\n const distDirFromProjectRoot =\n lib.dir\n .split('/')\n .map(() => '..')\n .join('/') + '/dist/{projectRoot}/cdk.out';\n const projectConfig = readProjectConfiguration(tree, lib.fullyQualifiedName);\n const libraryRoot = projectConfig.root;\n const npmScopePrefix = getNpmScopePrefix(tree);\n const scopeAlias = npmScopePrefix;\n const fullyQualifiedName = `${npmScopePrefix}${schema.name}`;\n const namespace = kebabCase(fullyQualifiedName);\n // The stage instantiated in main.ts. `**` so the pattern also selects stacks\n // nested below the stage's own stacks, such as the `us-east-1` WebACL stack a\n // website creates - `cdk destroy` only deletes the stacks its pattern selects,\n // so a single `*` leaves those behind. Quoted so the shell does not glob.\n const sandboxStagePattern = `\"${namespace}-sandbox/**\"`;\n\n // `tsProjectGenerator` scaffolds a library `src`, which the CDK app layout\n // replaces. Only on creation — on a re-run this is the user's infrastructure.\n // Likewise its generic README, which would otherwise keep the infra README\n // below from being written (it is generated `KeepExisting`).\n if (isNewProject) {\n tree.delete(joinPathFragments(libraryRoot, 'src'));\n tree.delete(joinPathFragments(libraryRoot, 'README.md'));\n }\n\n // The guide walks through declaring resources in\n // `src/stacks/application-stack.ts` and adding stages to `src/main.ts`, so\n // everything here is scaffolded once and then left alone.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, './files/app'),\n libraryRoot,\n {\n synthDir: synthDirFromProject,\n scopeAlias: scopeAlias,\n namespace,\n fullyQualifiedName,\n pkgMgrCmd: getPackageManagerDisplayCommands().exec,\n dir: lib.dir,\n stageConfig,\n ...schema,\n ...esmVars(tree),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n await addCdkTestGlobalSetup(tree, libraryRoot);\n\n updateJson(\n tree,\n `${libraryRoot}/project.json`,\n (config: ProjectConfiguration) => {\n config.projectType = 'application';\n // `synth` is the CDK artifact, so it belongs on `assemble` too; `checkov`\n // is a quality gate, so it stays on `build` alone.\n addArtifactDependencyToTargets(config, 'synth');\n addDependencyToTargetIfNotPresent(config, 'build', 'checkov');\n // Infra tests read the deployed projects' artifacts, not their quality\n // gates, so they replace the `^build` target default with `^assemble`.\n addDependencyToTargetIfNotPresent(config, 'test', '^assemble');\n config.targets.compile.outputs = [\n '{workspaceRoot}/dist/{projectRoot}/tsc',\n ];\n config.targets.synth = {\n cache: true,\n executor: 'nx:run-commands',\n inputs: ['default'],\n outputs: ['{workspaceRoot}/dist/{projectRoot}/cdk.out'],\n dependsOn: ['^assemble', 'compile'], // compile clobbers dist directory, so ensure synth runs afterwards\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk synth',\n }),\n };\n // `default` rather than the synth directory: `dist` is gitignored, so a\n // fileset input pointed at it matches no tracked file and hashes to a\n // constant — the scan would cache-hit forever and pass on infrastructure\n // it never read. `default` carries the project's own sources plus the\n // transitive `dependentTasksOutputFiles` entry, which resolves against\n // the upstream `synth` task and so hashes the template actually scanned.\n config.targets.checkov = {\n cache: true,\n executor: 'nx:run-commands',\n inputs: ['default'],\n outputs: ['{workspaceRoot}/dist/{projectRoot}/checkov'],\n dependsOn: ['synth'],\n options: {\n command: uvxCommand(\n 'checkov',\n '--config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation',\n ),\n },\n };\n config.targets.deploy = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n // No --express: this target deploys whichever stage is named, including\n // beta and prod, so it waits for full resource stabilization. Express\n // mode belongs to `deploy-sandbox`, which only ever deploys a sandbox.\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-deploy.ts ${libraryRoot}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk deploy --require-approval=never',\n }),\n };\n config.targets['deploy-sandbox'] = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-deploy.ts ${libraryRoot} ${sandboxStagePattern} --express`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk deploy --require-approval=never ${sandboxStagePattern} --express`,\n }),\n };\n config.targets['deploy-ci'] = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk deploy --require-approval=never --app ${distDirFromProjectRoot}`,\n }),\n };\n config.targets.destroy = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-destroy.ts ${libraryRoot}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk destroy',\n }),\n };\n config.targets['destroy-sandbox'] = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-destroy.ts ${libraryRoot} ${sandboxStagePattern}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk destroy ${sandboxStagePattern}`,\n }),\n };\n config.targets['destroy-ci'] = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk destroy --app ${distDirFromProjectRoot}`,\n }),\n };\n config.targets.cdk = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk',\n }),\n };\n config.targets.bootstrap = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk bootstrap',\n }),\n };\n config.targets = sortObjectKeys(config.targets);\n return config;\n },\n );\n\n addTsDependencies(tree, DEPENDENCIES, { projectRoot: libraryRoot });\n\n updateJson(tree, `${libraryRoot}/tsconfig.lib.json`, (tsConfig) => ({\n ...tsConfig,\n references: mergeTsReferences(tsConfig.references, [\n {\n path: `${path.relative(\n libraryRoot,\n `${tree.root}/${PACKAGES_DIR}`,\n )}/${SHARED_CONSTRUCTS_DIR}/tsconfig.lib.json`,\n },\n ...(stageConfig\n ? [\n {\n path: `${path.relative(\n libraryRoot,\n `${tree.root}/${PACKAGES_DIR}`,\n )}/${SHARED_INFRA_CONFIG_DIR}/tsconfig.json`,\n },\n ]\n : []),\n ]),\n }));\n\n // `main.ts` and the application stack import the shared constructs.\n addLocalProjectDependency(tree, {\n consumerRoot: libraryRoot,\n dependencyRoot: joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR),\n });\n if (stageConfig) {\n addLocalProjectDependency(tree, {\n consumerRoot: libraryRoot,\n dependencyRoot: joinPathFragments(PACKAGES_DIR, SHARED_INFRA_CONFIG_DIR),\n });\n }\n\n await addGeneratorMetricsIfApplicable(tree, [INFRA_APP_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript'],\n });\n}\nexport default tsInfraGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","readProjectConfiguration","updateJson","path","tsProjectGenerator","getTsLibDetails","mergeTsReferences","addTsDependencies","addCdkTestGlobalSetup","resolveContainers","declareDependencies","ownedElsewhere","formatFilesInSubtree","installDependencies","addLocalProjectDependency","addGeneratorMetricsIfApplicable","esmVars","kebabCase","getNpmScopePrefix","addArtifactDependencyToTargets","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","projectExists","sortObjectKeys","getPackageManagerDisplayCommands","uvxCommand","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_INFRA_CONFIG_DIR","sharedInfraConfigGenerator","SHARED_INFRA_SCRIPTS_DEPENDENCIES","sharedInfraScriptsGenerator","DEPENDENCIES","ts","name","dev","root","INFRA_APP_GENERATOR_INFO","filename","tsInfraGenerator","tree","schema","lib","isNewProject","fullyQualifiedName","preferInstallDependencies","containers","cdkEnv","undefined","CDK_DOCKER","withCdkEnv","opts","existingEnv","env","iac","stageConfig","synthDirFromRoot","dir","synthDirFromProject","split","map","join","distDirFromProjectRoot","projectConfig","libraryRoot","npmScopePrefix","scopeAlias","namespace","sandboxStagePattern","delete","dirname","synthDir","pkgMgrCmd","exec","overwriteStrategy","KeepExisting","config","projectType","targets","compile","outputs","synth","cache","executor","inputs","dependsOn","options","cwd","command","checkov","deploy","destroy","cdk","bootstrap","projectRoot","tsConfig","references","relative","consumerRoot","dependencyRoot","languages"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Keep checkov reports and vitest coverage out of downstream task hashes, declare Smithy build inputs, cache ts#rdb Prisma client generation and stop caching Terraform output"
3
+ }
@@ -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>;
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { getProjects, readNxJson, updateNxJson, updateProjectConfiguration } from "@nx/devkit";
5
+ import { SMITHY_PROJECT_GENERATOR_INFO, SMITHY_TARGET_INPUTS } from "../../../smithy/project/generator.js";
6
+ import { TERRAFORM_PROJECT_GENERATOR_INFO } from "../../../terraform/project/generator.js";
7
+ import { DEPENDENT_TASKS_OUTPUT_FILES_INPUT, VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS } from "../../../ts/lib/generator.js";
8
+ import { TS_RDB_GENERATOR_INFO } from "../../../ts/rdb/generator.js";
9
+ import { formatFilesInSubtree } from "../../../utils/format.js";
10
+ /**
11
+ * Fix what four generated targets hash, so cached results follow what each
12
+ * task actually reads:
13
+ *
14
+ * - `nx.json`'s `default` input no longer hashes checkov reports
15
+ * (`dist/<project>/checkov/checkov_report.json`, CDK and Terraform) or vitest
16
+ * coverage (`dist/<project>/test-output/vitest/coverage/`) from upstream
17
+ * tasks. Nothing downstream reads them, and an uncached scan or coverage run
18
+ * rewrites them, which missed every dependent task.
19
+ * - A Smithy project's `compile` and `generate-ssdk` declare `["default"]`,
20
+ * their own sources plus the outputs of the tasks they depend on, rather
21
+ * than relying on whatever target default applies. That hashes a consumed
22
+ * shape library's output only in a workspace where nx.json's `default`
23
+ * carries the `dependentTasksOutputFiles` entry, which only
24
+ * ts/lib/generator.ts writes.
25
+ * - A ts#rdb project's `generate` (`prisma generate`) is cached on
26
+ * `["default"]`, which covers the Prisma schema and config. The Prisma
27
+ * version is hashed through the lockfile.
28
+ * - A Terraform project's `output` is no longer cached: it reads remote state,
29
+ * which no input can hash, so a hit could replay values from before an apply.
30
+ *
31
+ * Each edit uses the generator's own constants, so a migrated workspace is
32
+ * byte-identical to a freshly generated one, keys in the same order. A target
33
+ * or glob that has diverged from the generated shape is left untouched and
34
+ * reported.
35
+ *
36
+ * Changing `namedInputs.default` changes every task hash, so the first build
37
+ * after migrating misses the cache throughout. Removing a churning input can
38
+ * also let a target that reads a file it does not declare replay a stale
39
+ * result, so that risk is reported whenever the glob is rewritten.
40
+ */ const CURRENT_GLOB = DEPENDENT_TASKS_OUTPUT_FILES_INPUT.dependentTasksOutputFiles;
41
+ const STALE_PASS_ADVISORY = "nx.json's 'default' input no longer hashes checkov reports or vitest coverage from upstream tasks. A target that reads a file it does not declare as an input (for example a test reading README.md) can now replay a cached result after that file changes; add such files to the target's inputs.";
42
+ const SMITHY_TARGETS = [
43
+ 'compile',
44
+ 'generate-ssdk'
45
+ ];
46
+ const RDB_INPUTS = [
47
+ 'default'
48
+ ];
49
+ const PRE_FIX_TERRAFORM_OUTPUT_INPUTS = [
50
+ 'default'
51
+ ];
52
+ const sameInputs = (inputs, expected)=>Array.isArray(inputs) && inputs.length === expected.length && inputs.every((input, index)=>input === expected[index]);
53
+ const command = (target)=>target.options?.command;
54
+ /** Rewrites a previously vended glob; returns whether it did. */ const migrateGlob = (tree, nextSteps)=>{
55
+ const nxJson = readNxJson(tree);
56
+ const defaultInputs = nxJson?.namedInputs?.default;
57
+ if (!nxJson || !Array.isArray(defaultInputs)) return false;
58
+ // A dependentTasksOutputFiles entry is "vended" if it is already current or
59
+ // is one of the globs this plugin has shipped (and so would be rewritten to
60
+ // the current one below). An extra entry a user added beside it - neither
61
+ // current nor vended - is their own scoping decision and is reported only
62
+ // when no vended-or-current entry exists; otherwise it would be reported on
63
+ // every run with advice that could widen hashing.
64
+ const hasVendedOrCurrentEntry = defaultInputs.some((input)=>typeof input === 'object' && input !== null && 'dependentTasksOutputFiles' in input && (input.dependentTasksOutputFiles === CURRENT_GLOB || input.transitive && VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS.includes(input.dependentTasksOutputFiles)));
65
+ let rewrote = false;
66
+ nxJson.namedInputs.default = defaultInputs.map((input)=>{
67
+ if (typeof input !== 'object' || !('dependentTasksOutputFiles' in input)) {
68
+ return input;
69
+ }
70
+ const glob = input.dependentTasksOutputFiles;
71
+ if (glob === CURRENT_GLOB) return input;
72
+ if (input.transitive && VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS.includes(glob)) {
73
+ rewrote = true;
74
+ return {
75
+ ...input,
76
+ dependentTasksOutputFiles: CURRENT_GLOB
77
+ };
78
+ }
79
+ if (!hasVendedOrCurrentEntry) {
80
+ nextSteps.push(`nx.json: the 'default' input's dependentTasksOutputFiles '${glob}' has diverged from the generated shape - left untouched. Consider excluding checkov reports and vitest coverage ('${CURRENT_GLOB}'), which otherwise miss every dependent task whenever a scan or coverage run rewrites them.`);
81
+ }
82
+ return input;
83
+ });
84
+ if (rewrote) updateNxJson(tree, nxJson);
85
+ return rewrote;
86
+ };
87
+ const diverged = (projectName, targetName, advice)=>`${projectName}:${targetName}: has diverged from the generated shape - left untouched. ${advice}`;
88
+ /** Inserts `inputs` after `cache`, where the generator writes it. */ const migrateSmithyTarget = (projectName, targetName, target, nextSteps)=>{
89
+ if (sameInputs(target.inputs, SMITHY_TARGET_INPUTS)) return undefined;
90
+ if (target.inputs !== undefined || target.executor !== 'nx:run-commands') {
91
+ nextSteps.push(diverged(projectName, targetName, "Confirm its inputs cover the Smithy sources and the outputs of the tasks it depends on, as ['default'] does."));
92
+ return undefined;
93
+ }
94
+ const { cache, ...rest } = target;
95
+ return {
96
+ cache,
97
+ inputs: [
98
+ ...SMITHY_TARGET_INPUTS
99
+ ],
100
+ ...rest
101
+ };
102
+ };
103
+ /** Inserts `cache` and `inputs` after `executor`, where the generator writes them. */ const migrateRdbGenerate = (projectName, target, nextSteps)=>{
104
+ if (target.cache === true && sameInputs(target.inputs, RDB_INPUTS)) {
105
+ return undefined;
106
+ }
107
+ if (target.executor !== 'nx:run-commands' || command(target) !== 'prisma generate' || target.cache !== undefined || target.inputs !== undefined) {
108
+ nextSteps.push(diverged(projectName, 'generate', "To cache Prisma client generation, set cache: true and inputs: ['default'], which covers the Prisma schema and config."));
109
+ return undefined;
110
+ }
111
+ const { executor, ...rest } = target;
112
+ return {
113
+ executor,
114
+ cache: true,
115
+ inputs: [
116
+ ...RDB_INPUTS
117
+ ],
118
+ ...rest
119
+ };
120
+ };
121
+ /** Stops caching `output` in place and drops its inputs. */ const migrateTerraformOutput = (projectName, target, nextSteps)=>{
122
+ if (target.cache !== true) return undefined;
123
+ if (!sameInputs(target.inputs, PRE_FIX_TERRAFORM_OUTPUT_INPUTS) || command(target) !== 'terraform output -json') {
124
+ nextSteps.push(diverged(projectName, 'output', 'A cached output can replay stale values after an apply; set cache: false.'));
125
+ return undefined;
126
+ }
127
+ const { inputs: _inputs, ...rest } = target;
128
+ return {
129
+ ...rest,
130
+ cache: false
131
+ };
132
+ };
133
+ const migrateProject = (projectName, project, nextSteps)=>{
134
+ const generator = project.metadata?.generator;
135
+ const targets = project.targets ?? {};
136
+ const migrations = generator === SMITHY_PROJECT_GENERATOR_INFO.id ? SMITHY_TARGETS.map((name)=>[
137
+ name,
138
+ ()=>migrateSmithyTarget(projectName, name, targets[name], nextSteps)
139
+ ]) : generator === TS_RDB_GENERATOR_INFO.id ? [
140
+ [
141
+ 'generate',
142
+ ()=>migrateRdbGenerate(projectName, targets.generate, nextSteps)
143
+ ]
144
+ ] : generator === TERRAFORM_PROJECT_GENERATOR_INFO.id ? [
145
+ [
146
+ 'output',
147
+ ()=>migrateTerraformOutput(projectName, targets.output, nextSteps)
148
+ ]
149
+ ] : [];
150
+ let changed = false;
151
+ for (const [name, migrate] of migrations){
152
+ if (!targets[name]) continue;
153
+ const migrated = migrate();
154
+ if (migrated) {
155
+ targets[name] = migrated;
156
+ changed = true;
157
+ }
158
+ }
159
+ return changed;
160
+ };
161
+ export default async function migration(tree) {
162
+ const nextSteps = [];
163
+ const rewroteGlob = migrateGlob(tree, nextSteps);
164
+ for (const [projectName, project] of getProjects(tree)){
165
+ if (migrateProject(projectName, project, nextSteps)) {
166
+ updateProjectConfiguration(tree, projectName, project);
167
+ }
168
+ }
169
+ if (rewroteGlob) nextSteps.push(STALE_PASS_ADVISORY);
170
+ await formatFilesInSubtree(tree);
171
+ return {
172
+ nextSteps
173
+ };
174
+ }
175
+
176
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/cache-inputs-outputs/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n type MigrationReturnObject,\n type ProjectConfiguration,\n readNxJson,\n type TargetConfiguration,\n type Tree,\n updateNxJson,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport {\n SMITHY_PROJECT_GENERATOR_INFO,\n SMITHY_TARGET_INPUTS,\n} from '../../../smithy/project/generator.js';\nimport { TERRAFORM_PROJECT_GENERATOR_INFO } from '../../../terraform/project/generator.js';\nimport {\n DEPENDENT_TASKS_OUTPUT_FILES_INPUT,\n VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS,\n} from '../../../ts/lib/generator.js';\nimport { TS_RDB_GENERATOR_INFO } from '../../../ts/rdb/generator.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\n\n/**\n * Fix what four generated targets hash, so cached results follow what each\n * task actually reads:\n *\n * - `nx.json`'s `default` input no longer hashes checkov reports\n * (`dist/<project>/checkov/checkov_report.json`, CDK and Terraform) or vitest\n * coverage (`dist/<project>/test-output/vitest/coverage/`) from upstream\n * tasks. Nothing downstream reads them, and an uncached scan or coverage run\n * rewrites them, which missed every dependent task.\n * - A Smithy project's `compile` and `generate-ssdk` declare `[\"default\"]`,\n * their own sources plus the outputs of the tasks they depend on, rather\n * than relying on whatever target default applies. That hashes a consumed\n * shape library's output only in a workspace where nx.json's `default`\n * carries the `dependentTasksOutputFiles` entry, which only\n * ts/lib/generator.ts writes.\n * - A ts#rdb project's `generate` (`prisma generate`) is cached on\n * `[\"default\"]`, which covers the Prisma schema and config. The Prisma\n * version is hashed through the lockfile.\n * - A Terraform project's `output` is no longer cached: it reads remote state,\n * which no input can hash, so a hit could replay values from before an apply.\n *\n * Each edit uses the generator's own constants, so a migrated workspace is\n * byte-identical to a freshly generated one, keys in the same order. A target\n * or glob that has diverged from the generated shape is left untouched and\n * reported.\n *\n * Changing `namedInputs.default` changes every task hash, so the first build\n * after migrating misses the cache throughout. Removing a churning input can\n * also let a target that reads a file it does not declare replay a stale\n * result, so that risk is reported whenever the glob is rewritten.\n */\n\nconst CURRENT_GLOB =\n DEPENDENT_TASKS_OUTPUT_FILES_INPUT.dependentTasksOutputFiles;\n\nconst STALE_PASS_ADVISORY =\n \"nx.json's 'default' input no longer hashes checkov reports or vitest coverage from upstream tasks. A target that reads a file it does not declare as an input (for example a test reading README.md) can now replay a cached result after that file changes; add such files to the target's inputs.\";\n\nconst SMITHY_TARGETS = ['compile', 'generate-ssdk'];\nconst RDB_INPUTS = ['default'];\nconst PRE_FIX_TERRAFORM_OUTPUT_INPUTS = ['default'];\n\nconst sameInputs = (\n inputs: TargetConfiguration['inputs'],\n expected: string[],\n): boolean =>\n Array.isArray(inputs) &&\n inputs.length === expected.length &&\n inputs.every((input, index) => input === expected[index]);\n\nconst command = (target: TargetConfiguration): unknown =>\n target.options?.command;\n\n/** Rewrites a previously vended glob; returns whether it did. */\nconst migrateGlob = (tree: Tree, nextSteps: string[]): boolean => {\n const nxJson = readNxJson(tree);\n const defaultInputs = nxJson?.namedInputs?.default;\n if (!nxJson || !Array.isArray(defaultInputs)) return false;\n\n // A dependentTasksOutputFiles entry is \"vended\" if it is already current or\n // is one of the globs this plugin has shipped (and so would be rewritten to\n // the current one below). An extra entry a user added beside it - neither\n // current nor vended - is their own scoping decision and is reported only\n // when no vended-or-current entry exists; otherwise it would be reported on\n // every run with advice that could widen hashing.\n const hasVendedOrCurrentEntry = defaultInputs.some(\n (input) =>\n typeof input === 'object' &&\n input !== null &&\n 'dependentTasksOutputFiles' in input &&\n (input.dependentTasksOutputFiles === CURRENT_GLOB ||\n (input.transitive &&\n VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS.includes(\n input.dependentTasksOutputFiles,\n ))),\n );\n\n let rewrote = false;\n nxJson.namedInputs.default = defaultInputs.map((input) => {\n if (typeof input !== 'object' || !('dependentTasksOutputFiles' in input)) {\n return input;\n }\n const glob = input.dependentTasksOutputFiles;\n if (glob === CURRENT_GLOB) return input;\n if (\n input.transitive &&\n VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS.includes(glob)\n ) {\n rewrote = true;\n return { ...input, dependentTasksOutputFiles: CURRENT_GLOB };\n }\n if (!hasVendedOrCurrentEntry) {\n nextSteps.push(\n `nx.json: the 'default' input's dependentTasksOutputFiles '${glob}' has diverged from the generated shape - left untouched. Consider excluding checkov reports and vitest coverage ('${CURRENT_GLOB}'), which otherwise miss every dependent task whenever a scan or coverage run rewrites them.`,\n );\n }\n return input;\n });\n\n if (rewrote) updateNxJson(tree, nxJson);\n return rewrote;\n};\n\nconst diverged = (projectName: string, targetName: string, advice: string) =>\n `${projectName}:${targetName}: has diverged from the generated shape - left untouched. ${advice}`;\n\n/** Inserts `inputs` after `cache`, where the generator writes it. */\nconst migrateSmithyTarget = (\n projectName: string,\n targetName: string,\n target: TargetConfiguration,\n nextSteps: string[],\n): TargetConfiguration | undefined => {\n if (sameInputs(target.inputs, SMITHY_TARGET_INPUTS)) return undefined;\n if (target.inputs !== undefined || target.executor !== 'nx:run-commands') {\n nextSteps.push(\n diverged(\n projectName,\n targetName,\n \"Confirm its inputs cover the Smithy sources and the outputs of the tasks it depends on, as ['default'] does.\",\n ),\n );\n return undefined;\n }\n const { cache, ...rest } = target;\n return { cache, inputs: [...SMITHY_TARGET_INPUTS], ...rest };\n};\n\n/** Inserts `cache` and `inputs` after `executor`, where the generator writes them. */\nconst migrateRdbGenerate = (\n projectName: string,\n target: TargetConfiguration,\n nextSteps: string[],\n): TargetConfiguration | undefined => {\n if (target.cache === true && sameInputs(target.inputs, RDB_INPUTS)) {\n return undefined;\n }\n if (\n target.executor !== 'nx:run-commands' ||\n command(target) !== 'prisma generate' ||\n target.cache !== undefined ||\n target.inputs !== undefined\n ) {\n nextSteps.push(\n diverged(\n projectName,\n 'generate',\n \"To cache Prisma client generation, set cache: true and inputs: ['default'], which covers the Prisma schema and config.\",\n ),\n );\n return undefined;\n }\n const { executor, ...rest } = target;\n return { executor, cache: true, inputs: [...RDB_INPUTS], ...rest };\n};\n\n/** Stops caching `output` in place and drops its inputs. */\nconst migrateTerraformOutput = (\n projectName: string,\n target: TargetConfiguration,\n nextSteps: string[],\n): TargetConfiguration | undefined => {\n if (target.cache !== true) return undefined;\n if (\n !sameInputs(target.inputs, PRE_FIX_TERRAFORM_OUTPUT_INPUTS) ||\n command(target) !== 'terraform output -json'\n ) {\n nextSteps.push(\n diverged(\n projectName,\n 'output',\n 'A cached output can replay stale values after an apply; set cache: false.',\n ),\n );\n return undefined;\n }\n const { inputs: _inputs, ...rest } = target;\n return { ...rest, cache: false };\n};\n\nconst migrateProject = (\n projectName: string,\n project: ProjectConfiguration,\n nextSteps: string[],\n): boolean => {\n const generator = (project.metadata as { generator?: string } | undefined)\n ?.generator;\n const targets = project.targets ?? {};\n\n const migrations: [string, () => TargetConfiguration | undefined][] =\n generator === SMITHY_PROJECT_GENERATOR_INFO.id\n ? SMITHY_TARGETS.map((name) => [\n name,\n () =>\n migrateSmithyTarget(projectName, name, targets[name], nextSteps),\n ])\n : generator === TS_RDB_GENERATOR_INFO.id\n ? [\n [\n 'generate',\n () =>\n migrateRdbGenerate(projectName, targets.generate, nextSteps),\n ],\n ]\n : generator === TERRAFORM_PROJECT_GENERATOR_INFO.id\n ? [\n [\n 'output',\n () =>\n migrateTerraformOutput(\n projectName,\n targets.output,\n nextSteps,\n ),\n ],\n ]\n : [];\n\n let changed = false;\n for (const [name, migrate] of migrations) {\n if (!targets[name]) continue;\n const migrated = migrate();\n if (migrated) {\n targets[name] = migrated;\n changed = true;\n }\n }\n return changed;\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n const rewroteGlob = migrateGlob(tree, nextSteps);\n\n for (const [projectName, project] of getProjects(tree)) {\n if (migrateProject(projectName, project, nextSteps)) {\n updateProjectConfiguration(tree, projectName, project);\n }\n }\n\n if (rewroteGlob) nextSteps.push(STALE_PASS_ADVISORY);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","readNxJson","updateNxJson","updateProjectConfiguration","SMITHY_PROJECT_GENERATOR_INFO","SMITHY_TARGET_INPUTS","TERRAFORM_PROJECT_GENERATOR_INFO","DEPENDENT_TASKS_OUTPUT_FILES_INPUT","VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS","TS_RDB_GENERATOR_INFO","formatFilesInSubtree","CURRENT_GLOB","dependentTasksOutputFiles","STALE_PASS_ADVISORY","SMITHY_TARGETS","RDB_INPUTS","PRE_FIX_TERRAFORM_OUTPUT_INPUTS","sameInputs","inputs","expected","Array","isArray","length","every","input","index","command","target","options","migrateGlob","tree","nextSteps","nxJson","defaultInputs","namedInputs","default","hasVendedOrCurrentEntry","some","transitive","includes","rewrote","map","glob","push","diverged","projectName","targetName","advice","migrateSmithyTarget","undefined","executor","cache","rest","migrateRdbGenerate","migrateTerraformOutput","_inputs","migrateProject","project","generator","metadata","targets","migrations","id","name","generate","output","changed","migrate","migrated","migration","rewroteGlob"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Run CDK infrastructure tests against the artifacts their stacks deploy rather than every upstream build, in a per-run temp directory with CDK asset bundling skipped"
3
+ }
@@ -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>;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { getProjects, joinPathFragments, updateProjectConfiguration } from "@nx/devkit";
5
+ import { INFRA_APP_GENERATOR_INFO } from "../../../infra/app/generator.js";
6
+ import { matchGritQL } from "../../../utils/ast.js";
7
+ import { addCdkTestGlobalSetup, CDK_TEST_GLOBAL_SETUP, CDK_TEST_GLOBAL_SETUP_ENTRY, findVitestConfig, renderCdkTestGlobalSetup } from "../../../utils/cdk-test-setup.js";
8
+ import { formatFilesInSubtree } from "../../../utils/format.js";
9
+ import { sortObjectKeys } from "../../../utils/object.js";
10
+ import { PACKAGES_DIR, SHARED_CONSTRUCTS_DIR } from "../../../utils/shared-constructs-constants.js";
11
+ /**
12
+ * Run CDK infrastructure tests against the artifacts their stacks deploy, in a
13
+ * per-run temp directory with CDK asset bundling skipped.
14
+ *
15
+ * The infra `test` target inherited the `^build` target default, so every
16
+ * infra test run first ran every deployed project's lint, test, type-check and
17
+ * bundle. The stacks only need the bundles: `Code.fromAsset` and its siblings
18
+ * throw on a missing asset path, so the edge is narrowed to `^assemble` (the
19
+ * artifact-only chain `synth` and `deploy` already use) rather than removed.
20
+ *
21
+ * Each `new App()` in a test synthesizes into a fresh `cdk.out*` directory
22
+ * under the OS temp dir, which nothing removed, so a workspace's tests leaked
23
+ * into the shared `/tmp`. The vended `tests/global-setup.ts` points `TMPDIR`,
24
+ * `TEMP` and `TMP` at a directory of its own for the run and removes it in
25
+ * teardown. aws-cdk-lib deletes the `cdk.out*` directories an `App` created
26
+ * from a `process.on('exit')` handler, and vitest runs the global teardown
27
+ * while its forked workers are still exiting, so a single `rmSync` can race
28
+ * that delete and return with the directory still there. The teardown
29
+ * therefore retries every 50 ms for up to 2 s, and warns (naming the
30
+ * directory) rather than failing the run if it is still there. It also merges `aws:cdk:bundling-stacks: []` into
31
+ * `CDK_CONTEXT_JSON`, which only affects user-written bundling constructs
32
+ * (`NodejsFunction`, `PythonFunction`); the vended constructs read prebuilt
33
+ * bundles. The setup is registered in the infra project's and the shared
34
+ * constructs' vitest configs.
35
+ *
36
+ * Only the exact shape the generator wrote before is changed. A `test` target,
37
+ * a `globalSetup`, a vitest config or a `tests/global-setup.ts` that differs is
38
+ * left untouched and reported, and a setup file the plugin did not write is
39
+ * never registered. The migration writes the generator's own template, so a migrated project is
40
+ * byte-identical to a freshly generated one. Infra READMEs are left alone: the
41
+ * generator writes them `KeepExisting`, and users edit them.
42
+ */ const TEST_TARGET = 'test';
43
+ const TEST_DEPENDS_ON = [
44
+ '^assemble'
45
+ ];
46
+ const isFixedTestTarget = (target)=>Object.keys(target).length === 1 && Array.isArray(target.dependsOn) && target.dependsOn.length === TEST_DEPENDS_ON.length && target.dependsOn.every((dep, index)=>dep === TEST_DEPENDS_ON[index]);
47
+ /** Any `globalSetup` property in the config. */ const ANY_GLOBAL_SETUP = '`globalSetup: $_`';
48
+ /** Exactly the entry the generator registers. */ const VENDED_GLOBAL_SETUP = `\`globalSetup: ['${CDK_TEST_GLOBAL_SETUP_ENTRY}']\``;
49
+ /** The `defineConfig(() => ({ test: { ... } }))` shape the generator inserts into. */ const RECOGNISED_CONFIG = `\`test: { $props }\` where { $props <: within \`defineConfig($_)\` }`;
50
+ /**
51
+ * Vend and register the global setup for one project, unless any of its files
52
+ * has diverged from the generated shape. Returns the reason it was skipped.
53
+ */ const migrateGlobalSetup = async (tree, projectName, root)=>{
54
+ const setupPath = joinPathFragments(root, CDK_TEST_GLOBAL_SETUP);
55
+ const configPath = findVitestConfig(tree, root);
56
+ if (!configPath) {
57
+ return `${projectName}: no vitest config found in ${root} - add \`globalSetup: ['${CDK_TEST_GLOBAL_SETUP_ENTRY}']\` to its \`test\` options to give each test run its own temp directory.`;
58
+ }
59
+ if (tree.exists(setupPath) && (tree.read(setupPath, 'utf-8') ?? '') !== renderCdkTestGlobalSetup()) {
60
+ return `${projectName}: ${setupPath} differs from the vended global setup - left untouched and not registered. Compare it with a freshly generated one, which gives each test run its own temp directory and skips CDK asset bundling, then add \`globalSetup: ['${CDK_TEST_GLOBAL_SETUP_ENTRY}']\` to ${configPath}.`;
61
+ }
62
+ if (await matchGritQL(tree, configPath, ANY_GLOBAL_SETUP)) {
63
+ if (await matchGritQL(tree, configPath, VENDED_GLOBAL_SETUP)) {
64
+ await addCdkTestGlobalSetup(tree, root);
65
+ return undefined;
66
+ }
67
+ return `${projectName}: ${configPath} already declares a \`globalSetup\` - left untouched. Add '${CDK_TEST_GLOBAL_SETUP_ENTRY}' to it to give each test run its own temp directory.`;
68
+ }
69
+ if (!await matchGritQL(tree, configPath, RECOGNISED_CONFIG)) {
70
+ return `${projectName}: ${configPath} has diverged from the generated shape - left untouched. Add \`globalSetup: ['${CDK_TEST_GLOBAL_SETUP_ENTRY}']\` to its \`test\` options to give each test run its own temp directory.`;
71
+ }
72
+ await addCdkTestGlobalSetup(tree, root);
73
+ return undefined;
74
+ };
75
+ export default async function migration(tree) {
76
+ const nextSteps = [];
77
+ for (const [projectName, project] of getProjects(tree)){
78
+ const generator = project.metadata?.generator;
79
+ if (generator !== INFRA_APP_GENERATOR_INFO.id) continue;
80
+ const testTarget = project.targets?.[TEST_TARGET];
81
+ if (!testTarget) {
82
+ updateProjectConfiguration(tree, projectName, {
83
+ ...project,
84
+ targets: sortObjectKeys({
85
+ ...project.targets,
86
+ [TEST_TARGET]: {
87
+ dependsOn: [
88
+ ...TEST_DEPENDS_ON
89
+ ]
90
+ }
91
+ })
92
+ });
93
+ } else if (!isFixedTestTarget(testTarget)) {
94
+ nextSteps.push(`${projectName}: the \`test\` target in ${joinPathFragments(project.root, 'project.json')} has diverged from the generated shape - left untouched. Set its \`dependsOn\` to ["^assemble"] so tests build the deployed projects' artifacts rather than every upstream build.`);
95
+ }
96
+ const skipped = await migrateGlobalSetup(tree, projectName, project.root);
97
+ if (skipped) nextSteps.push(skipped);
98
+ }
99
+ const constructsRoot = joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR);
100
+ if (tree.exists(joinPathFragments(constructsRoot, 'project.json'))) {
101
+ const skipped = await migrateGlobalSetup(tree, constructsRoot, constructsRoot);
102
+ if (skipped) nextSteps.push(skipped);
103
+ }
104
+ await formatFilesInSubtree(tree);
105
+ return {
106
+ nextSteps
107
+ };
108
+ }
109
+
110
+ //# sourceMappingURL=migration.js.map