@aws/nx-plugin 1.0.0-rc.81 → 1.0.0-rc.83

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 (42) hide show
  1. package/migrations.json +26 -1
  2. package/package.json +1 -1
  3. package/src/agentcore-gateway/generator.d.ts +7 -6
  4. package/src/agentcore-gateway/generator.js +2 -12
  5. package/src/agentcore-gateway/generator.js.map +1 -1
  6. package/src/migrations/latest/dynamodb-terraform-app-module-outputs/metadata.json +3 -0
  7. package/src/migrations/latest/dynamodb-terraform-app-module-outputs/migration.d.ts +6 -0
  8. package/src/migrations/latest/dynamodb-terraform-app-module-outputs/migration.js +69 -0
  9. package/src/migrations/latest/dynamodb-terraform-app-module-outputs/migration.js.map +1 -0
  10. package/src/migrations/latest/runtime-config-namespace-defaults/metadata.json +3 -0
  11. package/src/migrations/latest/runtime-config-namespace-defaults/migration.d.ts +6 -0
  12. package/src/migrations/latest/runtime-config-namespace-defaults/migration.js +131 -0
  13. package/src/migrations/latest/runtime-config-namespace-defaults/migration.js.map +1 -0
  14. package/src/migrations/latest/terraform-data-resource-destroy-protection/__snapshots__/migration.spec.ts.snap +75 -0
  15. package/src/migrations/latest/terraform-data-resource-destroy-protection/metadata.json +3 -0
  16. package/src/migrations/latest/terraform-data-resource-destroy-protection/migration.d.ts +6 -0
  17. package/src/migrations/latest/terraform-data-resource-destroy-protection/migration.js +78 -0
  18. package/src/migrations/latest/terraform-data-resource-destroy-protection/migration.js.map +1 -0
  19. package/src/migrations/latest/terraform-gateway-cedar-render-root-ejs/metadata.json +3 -0
  20. package/src/migrations/latest/terraform-gateway-cedar-render-root-ejs/migration.d.ts +6 -0
  21. package/src/migrations/latest/terraform-gateway-cedar-render-root-ejs/migration.js +38 -0
  22. package/src/migrations/latest/terraform-gateway-cedar-render-root-ejs/migration.js.map +1 -0
  23. package/src/migrations/latest/terraform-load-runtime-config-src-path/metadata.json +3 -0
  24. package/src/migrations/latest/terraform-load-runtime-config-src-path/migration.d.ts +6 -0
  25. package/src/migrations/latest/terraform-load-runtime-config-src-path/migration.js +48 -0
  26. package/src/migrations/latest/terraform-load-runtime-config-src-path/migration.js.map +1 -0
  27. package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +21 -0
  28. package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +21 -0
  29. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +12 -0
  30. package/src/ts/react-website/app/generator.js +2 -2
  31. package/src/ts/react-website/app/generator.js.map +1 -1
  32. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +9 -2
  33. package/src/utils/agent-core-constructs/agent-core-constructs.js +22 -8
  34. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  35. package/src/utils/dynamodb-constructs/files/terraform/app/dynamodb/__nameKebabCase__/__nameKebabCase__.tf.template +15 -0
  36. package/src/utils/dynamodb-constructs/files/terraform/core/dynamodb/dynamodb.tf.template +6 -0
  37. package/src/utils/files/terraform/src/core/runtime-config/appconfig/appconfig.tf.template +2 -2
  38. package/src/utils/files/terraform/src/core/runtime-config/appconfig-deployment/appconfig-deployment.tf.template +1 -1
  39. package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +6 -0
  40. package/src/utils/shared-constructs-constants.d.ts +22 -0
  41. package/src/utils/shared-constructs-constants.js +18 -0
  42. package/src/utils/shared-constructs-constants.js.map +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/terraform-data-resource-destroy-protection/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport { applyGritQL, matchGritQL } from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Bring existing workspaces up to the destroy protection the generators now\n * vend on the data-bearing Terraform resources:\n *\n * - The DynamoDB table and the Aurora cluster gain\n * `lifecycle { prevent_destroy = true }`. This is a second, independent layer\n * on top of the service-side `deletion_protection_enabled` /\n * `deletion_protection` flags, matching the two guards the CDK constructs\n * already have (`deletionProtection` plus `RemovalPolicy.RETAIN`). Without it,\n * clearing the service-side flag destroys the data in the same apply.\n * `prevent_destroy` cannot reference a variable, so it is vended as a literal\n * and removed to tear down.\n * - Their KMS keys pin `deletion_window_in_days = 30`, the provider maximum and\n * the CDK default. Restoring either resource from a point-in-time backup or\n * snapshot requires its key, so the window in which a scheduled key deletion\n * can still be cancelled matters as much as the backup itself.\n *\n * These files are generated with `KeepExisting`, so without this an upgraded\n * workspace keeps the weaker single-layer protection. Diverged files are left\n * untouched and reported via `nextSteps`.\n */\n\nconst TERRAFORM_DYNAMODB_FILE = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/core/dynamodb/dynamodb.tf`;\nconst TERRAFORM_AURORA_FILE = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/core/rdb/aurora/aurora.tf`;\n\nconst hcl = (pattern: string) => `language hcl\\n${pattern}`;\n\nconst divergedMessage = (filePath: string, resource: string) =>\n `${filePath}: has diverged from the generated shape - left untouched. To protect the ${resource} from being destroyed when the service-side deletion protection flag is cleared, add \\`lifecycle { prevent_destroy = true }\\` to it, and set \\`deletion_window_in_days = 30\\` on its KMS key.`;\n\n/**\n * Add the maximum KMS pending window to a key that omits it, so a scheduled\n * deletion stays cancellable for as long as the provider allows.\n */\nconst migrateKmsKey = async (\n tree: Tree,\n filePath: string,\n keyLabel: string,\n): Promise<void> => {\n const keyBlock = hcl(`\\`resource \"aws_kms_key\" \"${keyLabel}\" { $props }\\``);\n\n // Already pinned - nothing to do.\n if (\n await matchGritQL(\n tree,\n filePath,\n hcl(\n `\\`resource \"aws_kms_key\" \"${keyLabel}\" { $props }\\` where { $props <: contains \\`deletion_window_in_days = $_\\` }`,\n ),\n )\n ) {\n return;\n }\n\n if (!(await matchGritQL(tree, filePath, keyBlock))) {\n return; // Reported by the caller, which matches the data resource too.\n }\n\n await applyGritQL(\n tree,\n filePath,\n hcl(\n `\\`resource \"aws_kms_key\" \"${keyLabel}\" { $props }\\` where { $props <: contains \\`enable_key_rotation = $rotation\\` => \\`enable_key_rotation = $rotation\\n\\n deletion_window_in_days = 30\\` }`,\n ),\n );\n};\n\n/**\n * Add `lifecycle { prevent_destroy = true }` to a data-bearing resource.\n */\nconst migrateDataResource = async (\n tree: Tree,\n filePath: string,\n resourceType: string,\n resourceLabel: string,\n nextSteps: string[],\n description: string,\n): Promise<boolean> => {\n const resourceBlock = hcl(\n `\\`resource \"${resourceType}\" \"${resourceLabel}\" { $props }\\``,\n );\n\n if (!(await matchGritQL(tree, filePath, resourceBlock))) {\n nextSteps.push(divergedMessage(filePath, description));\n return false;\n }\n\n // Already guarded - keep the user's block, whatever it is set to.\n if (\n await matchGritQL(\n tree,\n filePath,\n hcl(\n `\\`resource \"${resourceType}\" \"${resourceLabel}\" { $props }\\` where { $props <: contains \\`prevent_destroy = $_\\` }`,\n ),\n )\n ) {\n return true;\n }\n\n await applyGritQL(\n tree,\n filePath,\n hcl(\n `\\`resource \"${resourceType}\" \"${resourceLabel}\" { $props }\\` => \\`resource \"${resourceType}\" \"${resourceLabel}\" {\\n $props\\n\\n lifecycle {\\n prevent_destroy = true\\n }\\n}\\``,\n ),\n );\n\n return true;\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n if (tree.exists(TERRAFORM_DYNAMODB_FILE)) {\n if (\n await migrateDataResource(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n 'aws_dynamodb_table',\n 'table',\n nextSteps,\n 'DynamoDB table',\n )\n ) {\n await migrateKmsKey(tree, TERRAFORM_DYNAMODB_FILE, 'table');\n }\n }\n\n if (tree.exists(TERRAFORM_AURORA_FILE)) {\n if (\n await migrateDataResource(\n tree,\n TERRAFORM_AURORA_FILE,\n 'aws_rds_cluster',\n 'database',\n nextSteps,\n 'Aurora cluster',\n )\n ) {\n await migrateKmsKey(tree, TERRAFORM_AURORA_FILE, 'database');\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["applyGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_TERRAFORM_DIR","TERRAFORM_DYNAMODB_FILE","TERRAFORM_AURORA_FILE","hcl","pattern","divergedMessage","filePath","resource","migrateKmsKey","tree","keyLabel","keyBlock","migrateDataResource","resourceType","resourceLabel","nextSteps","description","resourceBlock","push","migration","exists"],"mappings":"AAAA;;;CAGC,GAED,SAASA,WAAW,EAAEC,WAAW,QAAQ,wBAAwB;AACjE,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SACEC,YAAY,EACZC,oBAAoB,QACf,gDAAgD;AAEvD;;;;;;;;;;;;;;;;;;;;CAoBC,GAED,MAAMC,0BAA0B,GAAGF,aAAa,CAAC,EAAEC,qBAAqB,8BAA8B,CAAC;AACvG,MAAME,wBAAwB,GAAGH,aAAa,CAAC,EAAEC,qBAAqB,8BAA8B,CAAC;AAErG,MAAMG,MAAM,CAACC,UAAoB,CAAC,cAAc,EAAEA,SAAS;AAE3D,MAAMC,kBAAkB,CAACC,UAAkBC,WACzC,GAAGD,SAAS,yEAAyE,EAAEC,SAAS,6LAA6L,CAAC;AAEhS;;;CAGC,GACD,MAAMC,gBAAgB,OACpBC,MACAH,UACAI;IAEA,MAAMC,WAAWR,IAAI,CAAC,0BAA0B,EAAEO,SAAS,cAAc,CAAC;IAE1E,kCAAkC;IAClC,IACE,MAAMb,YACJY,MACAH,UACAH,IACE,CAAC,0BAA0B,EAAEO,SAAS,4EAA4E,CAAC,IAGvH;QACA;IACF;IAEA,IAAI,CAAE,MAAMb,YAAYY,MAAMH,UAAUK,WAAY;QAClD,QAAQ,+DAA+D;IACzE;IAEA,MAAMf,YACJa,MACAH,UACAH,IACE,CAAC,0BAA0B,EAAEO,SAAS,wJAAwJ,CAAC;AAGrM;AAEA;;CAEC,GACD,MAAME,sBAAsB,OAC1BH,MACAH,UACAO,cACAC,eACAC,WACAC;IAEA,MAAMC,gBAAgBd,IACpB,CAAC,YAAY,EAAEU,aAAa,GAAG,EAAEC,cAAc,cAAc,CAAC;IAGhE,IAAI,CAAE,MAAMjB,YAAYY,MAAMH,UAAUW,gBAAiB;QACvDF,UAAUG,IAAI,CAACb,gBAAgBC,UAAUU;QACzC,OAAO;IACT;IAEA,kEAAkE;IAClE,IACE,MAAMnB,YACJY,MACAH,UACAH,IACE,CAAC,YAAY,EAAEU,aAAa,GAAG,EAAEC,cAAc,oEAAoE,CAAC,IAGxH;QACA,OAAO;IACT;IAEA,MAAMlB,YACJa,MACAH,UACAH,IACE,CAAC,YAAY,EAAEU,aAAa,GAAG,EAAEC,cAAc,8BAA8B,EAAED,aAAa,GAAG,EAAEC,cAAc,oEAAoE,CAAC;IAIxL,OAAO;AACT;AAEA,eAAe,eAAeK,UAC5BV,IAAU;IAEV,MAAMM,YAAsB,EAAE;IAE9B,IAAIN,KAAKW,MAAM,CAACnB,0BAA0B;QACxC,IACE,MAAMW,oBACJH,MACAR,yBACA,sBACA,SACAc,WACA,mBAEF;YACA,MAAMP,cAAcC,MAAMR,yBAAyB;QACrD;IACF;IAEA,IAAIQ,KAAKW,MAAM,CAAClB,wBAAwB;QACtC,IACE,MAAMU,oBACJH,MACAP,uBACA,mBACA,YACAa,WACA,mBAEF;YACA,MAAMP,cAAcC,MAAMP,uBAAuB;QACnD;IACF;IAEA,MAAMJ,qBAAqBW;IAE3B,OAAO;QAAEM;IAAU;AACrB"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Declare ejs at the workspace root so the Terraform gateway's Cedar render script resolves it"
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,38 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { getProjects, joinPathFragments } from "@nx/devkit";
5
+ import { AGENTCORE_GATEWAY_GENERATOR_INFO } from "../../../agentcore-gateway/generator.js";
6
+ import { addDependenciesToPackageJson } from "../../../utils/dependencies.js";
7
+ import { formatFilesInSubtree } from "../../../utils/format.js";
8
+ import { PACKAGES_DIR, SHARED_TERRAFORM_DIR } from "../../../utils/shared-constructs-constants.js";
9
+ import { TS_VERSIONS } from "../../../utils/versions.js";
10
+ /**
11
+ * Declare `ejs` at the workspace root for Terraform gateways with Cedar
12
+ * policies, which is where `render-cedar.cjs` resolves it from: the script runs
13
+ * in the shared terraform project, which has no `package.json` of its own.
14
+ */ const RENDER_SCRIPT = 'render-cedar.cjs';
15
+ export default async function migration(tree) {
16
+ const gatewaysDir = joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'app', 'gateways');
17
+ let needsRootEjs = false;
18
+ for (const project of getProjects(tree).values()){
19
+ const metadata = project.metadata;
20
+ if (metadata?.generator !== AGENTCORE_GATEWAY_GENERATOR_INFO.id) {
21
+ continue;
22
+ }
23
+ // Only a Terraform gateway with Cedar policies vends the render script; a
24
+ // CDK one resolves ejs from the shared constructs project instead.
25
+ if (tree.exists(joinPathFragments(gatewaysDir, metadata.name ?? '', RENDER_SCRIPT))) {
26
+ needsRootEjs = true;
27
+ }
28
+ }
29
+ if (needsRootEjs) {
30
+ addDependenciesToPackageJson(tree, {}, {
31
+ ejs: TS_VERSIONS.ejs
32
+ });
33
+ }
34
+ await formatFilesInSubtree(tree);
35
+ return {};
36
+ }
37
+
38
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/terraform-gateway-cedar-render-root-ejs/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 joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport { AGENTCORE_GATEWAY_GENERATOR_INFO } from '../../../agentcore-gateway/generator.js';\nimport { addDependenciesToPackageJson } from '../../../utils/dependencies.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants.js';\nimport { TS_VERSIONS } from '../../../utils/versions.js';\n\n/**\n * Declare `ejs` at the workspace root for Terraform gateways with Cedar\n * policies, which is where `render-cedar.cjs` resolves it from: the script runs\n * in the shared terraform project, which has no `package.json` of its own.\n */\n\nconst RENDER_SCRIPT = 'render-cedar.cjs';\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const gatewaysDir = joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'gateways',\n );\n let needsRootEjs = false;\n\n for (const project of getProjects(tree).values()) {\n const metadata = project.metadata as\n | { generator?: string; name?: string }\n | undefined;\n if (metadata?.generator !== AGENTCORE_GATEWAY_GENERATOR_INFO.id) {\n continue;\n }\n\n // Only a Terraform gateway with Cedar policies vends the render script; a\n // CDK one resolves ejs from the shared constructs project instead.\n if (\n tree.exists(\n joinPathFragments(gatewaysDir, metadata.name ?? '', RENDER_SCRIPT),\n )\n ) {\n needsRootEjs = true;\n }\n }\n\n if (needsRootEjs) {\n addDependenciesToPackageJson(tree, {}, { ejs: TS_VERSIONS.ejs });\n }\n\n await formatFilesInSubtree(tree);\n\n return {};\n}\n"],"names":["getProjects","joinPathFragments","AGENTCORE_GATEWAY_GENERATOR_INFO","addDependenciesToPackageJson","formatFilesInSubtree","PACKAGES_DIR","SHARED_TERRAFORM_DIR","TS_VERSIONS","RENDER_SCRIPT","migration","tree","gatewaysDir","needsRootEjs","project","values","metadata","generator","id","exists","name","ejs"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EACXC,iBAAiB,QAGZ,aAAa;AACpB,SAASC,gCAAgC,QAAQ,0CAA0C;AAC3F,SAASC,4BAA4B,QAAQ,iCAAiC;AAC9E,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SACEC,YAAY,EACZC,oBAAoB,QACf,gDAAgD;AACvD,SAASC,WAAW,QAAQ,6BAA6B;AAEzD;;;;CAIC,GAED,MAAMC,gBAAgB;AAEtB,eAAe,eAAeC,UAC5BC,IAAU;IAEV,MAAMC,cAAcV,kBAClBI,cACAC,sBACA,OACA,OACA;IAEF,IAAIM,eAAe;IAEnB,KAAK,MAAMC,WAAWb,YAAYU,MAAMI,MAAM,GAAI;QAChD,MAAMC,WAAWF,QAAQE,QAAQ;QAGjC,IAAIA,UAAUC,cAAcd,iCAAiCe,EAAE,EAAE;YAC/D;QACF;QAEA,0EAA0E;QAC1E,mEAAmE;QACnE,IACEP,KAAKQ,MAAM,CACTjB,kBAAkBU,aAAaI,SAASI,IAAI,IAAI,IAAIX,iBAEtD;YACAI,eAAe;QACjB;IACF;IAEA,IAAIA,cAAc;QAChBT,6BAA6BO,MAAM,CAAC,GAAG;YAAEU,KAAKb,YAAYa,GAAG;QAAC;IAChE;IAEA,MAAMhB,qBAAqBM;IAE3B,OAAO,CAAC;AACV"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Point the react website's terraform load-runtime-config target at the runtime-config file the terraform aggregation actually writes"
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,48 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { getProjects, updateProjectConfiguration } from "@nx/devkit";
5
+ import { formatFilesInSubtree } from "../../../utils/format.js";
6
+ import { TERRAFORM_WEBSITE_RUNTIME_CONFIG_FILE } from "../../../utils/shared-constructs-constants.js";
7
+ /**
8
+ * The Terraform `load-runtime-config` target copied
9
+ * `dist/packages/common/terraform/runtime-config.json`, which nothing writes:
10
+ * the vended runtime-config modules aggregate per namespace into the
11
+ * `runtime-config` *directory*, so the website's config lands at
12
+ * `runtime-config/connection.json`. Copying the directory path always failed
13
+ * with ENOENT, so point it at the file the aggregation actually writes.
14
+ *
15
+ * Both target names are rewritten — `load-runtime-config` and the
16
+ * `load:runtime-config` it was cloned from, which is left in place for
17
+ * workspaces that still reference it.
18
+ *
19
+ * How to write a migration:
20
+ * - https://nx.dev/docs/kb/migration-generators
21
+ * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject
22
+ */ const TARGETS = [
23
+ 'load-runtime-config',
24
+ 'load:runtime-config'
25
+ ];
26
+ /** The path the target used to name, which never existed on disk. */ const BROKEN_SRC_FILE = 'dist/packages/common/terraform/runtime-config.json';
27
+ export default async function migration(tree) {
28
+ for (const [projectName, project] of getProjects(tree)){
29
+ let updated = false;
30
+ for (const targetName of TARGETS){
31
+ const env = project.targets?.[targetName]?.options?.env;
32
+ // Only the broken path is rewritten, so a workspace that pointed the
33
+ // target somewhere of its own keeps it.
34
+ if (env?.SRC_FILE !== BROKEN_SRC_FILE) {
35
+ continue;
36
+ }
37
+ env.SRC_FILE = TERRAFORM_WEBSITE_RUNTIME_CONFIG_FILE;
38
+ updated = true;
39
+ }
40
+ if (updated) {
41
+ updateProjectConfiguration(tree, projectName, project);
42
+ }
43
+ }
44
+ await formatFilesInSubtree(tree);
45
+ return {};
46
+ }
47
+
48
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/terraform-load-runtime-config-src-path/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 Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport { TERRAFORM_WEBSITE_RUNTIME_CONFIG_FILE } from '../../../utils/shared-constructs-constants.js';\n\n/**\n * The Terraform `load-runtime-config` target copied\n * `dist/packages/common/terraform/runtime-config.json`, which nothing writes:\n * the vended runtime-config modules aggregate per namespace into the\n * `runtime-config` *directory*, so the website's config lands at\n * `runtime-config/connection.json`. Copying the directory path always failed\n * with ENOENT, so point it at the file the aggregation actually writes.\n *\n * Both target names are rewritten — `load-runtime-config` and the\n * `load:runtime-config` it was cloned from, which is left in place for\n * workspaces that still reference it.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n */\n\nconst TARGETS = ['load-runtime-config', 'load:runtime-config'];\n\n/** The path the target used to name, which never existed on disk. */\nconst BROKEN_SRC_FILE = 'dist/packages/common/terraform/runtime-config.json';\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n for (const [projectName, project] of getProjects(tree)) {\n let updated = false;\n\n for (const targetName of TARGETS) {\n const env = project.targets?.[targetName]?.options?.env;\n // Only the broken path is rewritten, so a workspace that pointed the\n // target somewhere of its own keeps it.\n if (env?.SRC_FILE !== BROKEN_SRC_FILE) {\n continue;\n }\n env.SRC_FILE = TERRAFORM_WEBSITE_RUNTIME_CONFIG_FILE;\n updated = true;\n }\n\n if (updated) {\n updateProjectConfiguration(tree, projectName, project);\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return {};\n}\n"],"names":["getProjects","updateProjectConfiguration","formatFilesInSubtree","TERRAFORM_WEBSITE_RUNTIME_CONFIG_FILE","TARGETS","BROKEN_SRC_FILE","migration","tree","projectName","project","updated","targetName","env","targets","options","SRC_FILE"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EAGXC,0BAA0B,QACrB,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SAASC,qCAAqC,QAAQ,gDAAgD;AAEtG;;;;;;;;;;;;;;;CAeC,GAED,MAAMC,UAAU;IAAC;IAAuB;CAAsB;AAE9D,mEAAmE,GACnE,MAAMC,kBAAkB;AAExB,eAAe,eAAeC,UAC5BC,IAAU;IAEV,KAAK,MAAM,CAACC,aAAaC,QAAQ,IAAIT,YAAYO,MAAO;QACtD,IAAIG,UAAU;QAEd,KAAK,MAAMC,cAAcP,QAAS;YAChC,MAAMQ,MAAMH,QAAQI,OAAO,EAAE,CAACF,WAAW,EAAEG,SAASF;YACpD,qEAAqE;YACrE,wCAAwC;YACxC,IAAIA,KAAKG,aAAaV,iBAAiB;gBACrC;YACF;YACAO,IAAIG,QAAQ,GAAGZ;YACfO,UAAU;QACZ;QAEA,IAAIA,SAAS;YACXT,2BAA2BM,MAAMC,aAAaC;QAChD;IACF;IAEA,MAAMP,qBAAqBK;IAE3B,OAAO,CAAC;AACV"}
@@ -126,6 +126,8 @@ resource "aws_kms_key" "table" {
126
126
  description = "KMS key for DynamoDB table \${var.name}"
127
127
  enable_key_rotation = var.enable_key_rotation
128
128
 
129
+ deletion_window_in_days = 30
130
+
129
131
  policy = jsonencode({
130
132
  Version = "2012-10-17"
131
133
  Statement = [
@@ -202,6 +204,10 @@ resource "aws_dynamodb_table" "table" {
202
204
  enabled = var.encryption != "DEFAULT"
203
205
  kms_key_arn = local.table_kms_key_arn
204
206
  }
207
+
208
+ lifecycle {
209
+ prevent_destroy = true
210
+ }
205
211
  }
206
212
 
207
213
  output "table_name" {
@@ -320,6 +326,21 @@ module "add_to_runtime_config" {
320
326
  tableName = module.dynamodb_table.table_name
321
327
  }
322
328
  }
329
+
330
+ output "table_name" {
331
+ description = "Name of the DynamoDB table"
332
+ value = module.dynamodb_table.table_name
333
+ }
334
+
335
+ output "table_arn" {
336
+ description = "ARN of the DynamoDB table, for use in IAM policies granting access to the table. Suffix with /index/* to cover its global secondary indexes."
337
+ value = module.dynamodb_table.table_arn
338
+ }
339
+
340
+ output "kms_key_arn" {
341
+ description = "ARN of the KMS key used to encrypt the DynamoDB table, for use in IAM policies granting access to the table. Null when using the AWS owned key (encryption = DEFAULT)."
342
+ value = module.dynamodb_table.kms_key_arn
343
+ }
323
344
  "
324
345
  `;
325
346
 
@@ -126,6 +126,8 @@ resource "aws_kms_key" "table" {
126
126
  description = "KMS key for DynamoDB table \${var.name}"
127
127
  enable_key_rotation = var.enable_key_rotation
128
128
 
129
+ deletion_window_in_days = 30
130
+
129
131
  policy = jsonencode({
130
132
  Version = "2012-10-17"
131
133
  Statement = [
@@ -202,6 +204,10 @@ resource "aws_dynamodb_table" "table" {
202
204
  enabled = var.encryption != "DEFAULT"
203
205
  kms_key_arn = local.table_kms_key_arn
204
206
  }
207
+
208
+ lifecycle {
209
+ prevent_destroy = true
210
+ }
205
211
  }
206
212
 
207
213
  output "table_name" {
@@ -320,6 +326,21 @@ module "add_to_runtime_config" {
320
326
  tableName = module.dynamodb_table.table_name
321
327
  }
322
328
  }
329
+
330
+ output "table_name" {
331
+ description = "Name of the DynamoDB table"
332
+ value = module.dynamodb_table.table_name
333
+ }
334
+
335
+ output "table_arn" {
336
+ description = "ARN of the DynamoDB table, for use in IAM policies granting access to the table. Suffix with /index/* to cover its global secondary indexes."
337
+ value = module.dynamodb_table.table_arn
338
+ }
339
+
340
+ output "kms_key_arn" {
341
+ description = "ARN of the KMS key used to encrypt the DynamoDB table, for use in IAM policies granting access to the table. Null when using the AWS owned key (encryption = DEFAULT)."
342
+ value = module.dynamodb_table.kms_key_arn
343
+ }
323
344
  "
324
345
  `;
325
346
 
@@ -1008,6 +1008,8 @@ resource "aws_kms_key" "database" {
1008
1008
  description = "KMS key for Aurora cluster \${var.name}"
1009
1009
  enable_key_rotation = var.enable_key_rotation
1010
1010
 
1011
+ deletion_window_in_days = 30
1012
+
1011
1013
  policy = jsonencode({
1012
1014
  Version = "2012-10-17"
1013
1015
  Statement = [
@@ -1150,6 +1152,10 @@ resource "aws_rds_cluster" "database" {
1150
1152
  tags = merge(var.tags, {
1151
1153
  Name = "\${var.name}-aurora"
1152
1154
  })
1155
+
1156
+ lifecycle {
1157
+ prevent_destroy = true
1158
+ }
1153
1159
  }
1154
1160
 
1155
1161
  resource "aws_rds_cluster_instance" "database" {
@@ -2494,6 +2500,8 @@ resource "aws_kms_key" "database" {
2494
2500
  description = "KMS key for Aurora cluster \${var.name}"
2495
2501
  enable_key_rotation = var.enable_key_rotation
2496
2502
 
2503
+ deletion_window_in_days = 30
2504
+
2497
2505
  policy = jsonencode({
2498
2506
  Version = "2012-10-17"
2499
2507
  Statement = [
@@ -2636,6 +2644,10 @@ resource "aws_rds_cluster" "database" {
2636
2644
  tags = merge(var.tags, {
2637
2645
  Name = "\${var.name}-aurora"
2638
2646
  })
2647
+
2648
+ lifecycle {
2649
+ prevent_destroy = true
2650
+ }
2639
2651
  }
2640
2652
 
2641
2653
  resource "aws_rds_cluster_instance" "database" {
@@ -18,7 +18,7 @@ import { sortObjectKeys } from "../../../utils/object.js";
18
18
  import { getRelativePathToRoot } from "../../../utils/paths.js";
19
19
  import { getPackageManagerDisplayCommands } from "../../../utils/pkg-manager.js";
20
20
  import { SHARED_CONSTRUCTS_DEPENDENCIES, sharedConstructsGenerator } from "../../../utils/shared-constructs.js";
21
- import { PACKAGES_DIR, SHARED_SHADCN_DIR } from "../../../utils/shared-constructs-constants.js";
21
+ import { PACKAGES_DIR, SHARED_SHADCN_DIR, TERRAFORM_WEBSITE_RUNTIME_CONFIG_FILE } from "../../../utils/shared-constructs-constants.js";
22
22
  import { SHADCN_DEPENDENCIES, sharedShadcnGenerator } from "../../../utils/shared-shadcn.js";
23
23
  import { addWebsiteInfra, WEBSITE_CONSTRUCTS_PY_DEPENDENCIES } from "../../../utils/website-constructs/website-constructs.js";
24
24
  import { configureTsProject } from "../../lib/ts-project-utils.js";
@@ -202,7 +202,7 @@ export async function tsReactWebsiteGenerator(tree, schema) {
202
202
  options: {
203
203
  command: 'node -e "const fs=require(\'fs\');fs.mkdirSync(process.env.DEST_DIR,{recursive:true});fs.copyFileSync(process.env.SRC_FILE,process.env.DEST_FILE);"',
204
204
  env: {
205
- SRC_FILE: 'dist/packages/common/terraform/runtime-config.json',
205
+ SRC_FILE: TERRAFORM_WEBSITE_RUNTIME_CONFIG_FILE,
206
206
  DEST_DIR: `{projectRoot}/public`,
207
207
  DEST_FILE: `{projectRoot}/public/runtime-config.json`
208
208
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/ts/react-website/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 generateFiles,\n joinPathFragments,\n names,\n OverwriteStrategy,\n readProjectConfiguration,\n removeDependenciesFromPackageJson,\n type Tree,\n updateJson,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { applicationGenerator } from '@nx/react';\nimport { relative, sep } from 'path';\nimport { addTsDependencies } from '../../../utils/add-dependencies.js';\nimport {\n addDestructuredImport,\n addSingleImport,\n appendToArrayViaGritQL,\n applyGritQL,\n} from '../../../utils/ast.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport { resolveIac } from '../../../utils/iac.js';\nimport { installDependencies } from '../../../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics.js';\nimport { kebabCase, toClassName, toKebabCase } from '../../../utils/names.js';\nimport { getNpmScopePrefix } from '../../../utils/npm-scope.js';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n} from '../../../utils/nx.js';\nimport { sortObjectKeys } from '../../../utils/object.js';\nimport { getRelativePathToRoot } from '../../../utils/paths.js';\nimport { getPackageManagerDisplayCommands } from '../../../utils/pkg-manager.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../../utils/shared-constructs.js';\nimport {\n type IacMetadata,\n PACKAGES_DIR,\n SHARED_SHADCN_DIR,\n} from '../../../utils/shared-constructs-constants.js';\nimport {\n SHADCN_DEPENDENCIES,\n sharedShadcnGenerator,\n} from '../../../utils/shared-shadcn.js';\nimport {\n addWebsiteInfra,\n WEBSITE_CONSTRUCTS_PY_DEPENDENCIES,\n} from '../../../utils/website-constructs/website-constructs.js';\nimport { configureTsProject } from '../../lib/ts-project-utils.js';\nimport { VITEST_DEPENDENCIES } from '../../lib/vitest.js';\n// typescript factory imports removed — now using GritQL for vite config transforms\nimport type {\n TsReactWebsiteGeneratorSchema,\n WebsiteInfraOption,\n} from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface TsReactWebsiteMetadata extends IacMetadata {\n readonly ux: UxOption;\n readonly framework: string;\n readonly infra: WebsiteInfraOption;\n readonly tailwind: boolean;\n readonly tanstackRouter: boolean;\n}\n\n// Each entry names the branch it belongs to, so the same declaration drives both\n// adding and the version sync.\nexport const DEPENDENCIES = declareDependencies<TsReactWebsiteMetadata>()({\n ts: [\n { name: 'react' },\n { name: 'react-dom' },\n // Build/test tooling imported only from vite.config.mts stays at the root.\n { name: '@nx/react', dev: true, root: true },\n { name: '@vitest/ui', dev: true, root: true },\n {\n name: '@cloudscape-design/components',\n when: (m) => m.ux === 'cloudscape',\n },\n {\n name: '@cloudscape-design/board-components',\n when: (m) => m.ux === 'cloudscape',\n },\n {\n name: '@cloudscape-design/global-styles',\n when: (m) => m.ux === 'cloudscape',\n },\n // Shared shadcn components live in the common/shadcn package, but the\n // website's own generated components (e.g. the tanstack-router sidebar)\n // import lucide-react directly, so the website must declare it.\n {\n name: 'lucide-react',\n when: (m) => m.ux === 'shadcn' && m.tanstackRouter,\n },\n { name: 'tailwindcss', when: (m) => m.tailwind },\n {\n name: '@tailwindcss/vite',\n when: (m) => m.tailwind,\n dev: true,\n root: true,\n },\n { name: '@tanstack/react-router', when: (m) => m.tanstackRouter },\n {\n name: '@tanstack/router-plugin',\n when: (m) => m.tanstackRouter,\n dev: true,\n root: true,\n },\n {\n name: '@tanstack/router-generator',\n when: (m) => m.tanstackRouter,\n dev: true,\n root: true,\n },\n {\n name: '@tanstack/virtual-file-routes',\n when: (m) => m.tanstackRouter,\n dev: true,\n root: true,\n },\n {\n name: '@tanstack/router-utils',\n when: (m) => m.tanstackRouter,\n dev: true,\n root: true,\n },\n ...ownedElsewhere(SHADCN_DEPENDENCIES),\n ...ownedElsewhere(VITEST_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: ownedElsewhere(WEBSITE_CONSTRUCTS_PY_DEPENDENCIES),\n});\n\nexport const SUPPORTED_UX_PROVIDERS = ['none', 'cloudscape', 'shadcn'] as const;\n\nexport type UxOption = (typeof SUPPORTED_UX_PROVIDERS)[number];\n\nexport type Ux = UxOption;\n\nexport const REACT_WEBSITE_APP_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport async function tsReactWebsiteGenerator(\n tree: Tree,\n schema: TsReactWebsiteGeneratorSchema,\n) {\n const tailwind = schema.tailwind ?? true;\n const tanstackRouter = schema.tanstackRouter ?? true;\n const ux: Ux = schema.ux ?? 'shadcn';\n if (ux === 'shadcn' && !tailwind) {\n throw new Error('Shadcn requires TailwindCSS to be enabled.');\n }\n const npmScopePrefix = getNpmScopePrefix(tree);\n const scopeAlias = npmScopePrefix;\n const websiteNameClassName = toClassName(schema.name);\n const websiteNameKebabCase = toKebabCase(schema.name);\n const fullyQualifiedName = `${npmScopePrefix}${websiteNameKebabCase}`;\n // NB: interactive nx generator cli can pass empty string\n const websiteContentPath = joinPathFragments(\n schema.directory || '.',\n schema.subDirectory || websiteNameKebabCase,\n );\n\n const projectAlreadyExists = tree.exists(\n joinPathFragments(websiteContentPath, 'project.json'),\n );\n\n // TODO: consider exposing and supporting e2e tests\n const e2eTestRunner = 'none';\n\n if (!projectAlreadyExists) {\n await applicationGenerator(tree, {\n ...schema,\n name: fullyQualifiedName,\n directory: websiteContentPath,\n routing: false,\n e2eTestRunner,\n linter: 'none',\n bundler: 'vite',\n unitTestRunner: 'vitest',\n useProjectJson: true,\n style: 'css',\n // Register the @nx/vite and @nx/vitest plugins so build/serve/test\n // targets are inferred rather than emitting deprecated executor targets.\n addPlugin: true,\n });\n\n // Pin the inferred target names. The vite production build is exposed as\n // `bundle` (which produces the deployable artifact), leaving `build` as an\n // aggregator over lint/compile/test/bundle. vite's own typecheck is dropped\n // in favour of the tsc `compile`.\n updateJson(tree, 'nx.json', (nxJson) => {\n for (const plugin of nxJson.plugins ?? []) {\n if (typeof plugin === 'string') continue;\n if (plugin.plugin === '@nx/vite/plugin') {\n plugin.options = {\n ...plugin.options,\n buildTargetName: 'bundle',\n // Map both of vite's inferred dev-server targets onto `serve` so the\n // plugin doesn't emit a separate `dev`; we author our own `dev`\n // below running the local-dev vite mode.\n serveTargetName: 'serve',\n devTargetName: 'serve',\n previewTargetName: 'preview',\n serveStaticTargetName: 'serve-static',\n typecheckTargetName: 'vite:typecheck',\n };\n } else if (plugin.plugin === '@nx/vitest') {\n plugin.options = {\n ...plugin.options,\n testTargetName: 'test',\n };\n }\n }\n return nxJson;\n });\n\n // Replace with simpler sample source code\n tree.delete(joinPathFragments(websiteContentPath, 'src'));\n }\n\n const projectConfiguration = readProjectConfiguration(\n tree,\n fullyQualifiedName,\n );\n\n const targets = projectConfiguration.targets;\n\n const infra = schema.infra ?? 'cloudfront-s3';\n\n // Configure load-runtime-config target based on IaC provider (only when infra is not none)\n const iac = infra !== 'none' ? await resolveIac(tree, schema.iac) : undefined;\n\n if (iac === 'cdk') {\n targets['load-runtime-config'] = {\n executor: 'nx:run-commands',\n metadata: {\n description: `Load runtime config from your deployed stack for dev purposes. You must set your AWS CLI credentials whilst calling '${getPackageManagerDisplayCommands().exec} nx load-runtime-config ${fullyQualifiedName}'`,\n },\n options: {\n command: `aws s3 cp s3://\\`aws cloudformation describe-stacks --query \"Stacks[?starts_with(StackName, '${kebabCase(npmScopePrefix)}-')][].Outputs[] | [?contains(OutputKey, '${websiteNameClassName}WebsiteBucketName')].OutputValue\" --output text\\`/runtime-config.json \"{projectRoot}/public/runtime-config.json\"`,\n },\n };\n } else if (iac === 'terraform') {\n targets['load-runtime-config'] = {\n executor: 'nx:run-commands',\n metadata: {\n description:\n \"Load runtime config from most recently applied terraform env for dev purposes. Copies the runtime config from the Terraform dist directory to the website's public directory.\",\n },\n options: {\n command:\n 'node -e \"const fs=require(\\'fs\\');fs.mkdirSync(process.env.DEST_DIR,{recursive:true});fs.copyFileSync(process.env.SRC_FILE,process.env.DEST_FILE);\"',\n env: {\n SRC_FILE: 'dist/packages/common/terraform/runtime-config.json',\n DEST_DIR: `{projectRoot}/public`,\n DEST_FILE: `{projectRoot}/public/runtime-config.json`,\n },\n },\n };\n }\n\n if (!projectAlreadyExists) {\n targets['compile'] = {\n dependsOn: ['^build'],\n executor: 'nx:run-commands',\n outputs: ['{workspaceRoot}/dist/{projectRoot}/tsc'],\n options: {\n command: 'tsc --build tsconfig.app.json',\n cwd: '{projectRoot}',\n },\n };\n // bundle is the @nx/vite/plugin inferred `vite build` (writing to the\n // bundle dir configured in vite.config) — it produces the deployable\n // artifact. build aggregates lint/compile/test/bundle.\n targets['build'] = {\n dependsOn: ['lint', 'compile', 'test', 'bundle'],\n };\n\n // Run the website and its connected dependencies locally. Mirrors the\n // inferred `serve` target but with the local-dev vite mode.\n targets['dev'] = {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n command: 'vite --mode local-dev',\n cwd: '{projectRoot}',\n },\n };\n }\n\n projectConfiguration.targets = sortObjectKeys(targets);\n\n updateProjectConfiguration(tree, fullyQualifiedName, projectConfiguration);\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: TsReactWebsiteMetadata = {\n ux,\n framework: 'react',\n infra,\n tailwind,\n tanstackRouter,\n // Undefined when no infrastructure was generated, so neither provider's\n // packages were added.\n ...(iac ? { iac } : {}),\n };\n addGeneratorMetadata(\n tree,\n projectConfiguration.name,\n REACT_WEBSITE_APP_GENERATOR_INFO,\n metadata,\n );\n\n await configureTsProject(\n tree,\n {\n dir: websiteContentPath,\n fullyQualifiedName,\n },\n DEPENDENCIES,\n );\n\n if (ux === 'shadcn') {\n await sharedShadcnGenerator(tree, DEPENDENCIES);\n }\n\n if (iac) {\n await sharedConstructsGenerator(\n tree,\n {\n iac,\n },\n DEPENDENCIES,\n );\n\n await addWebsiteInfra(tree, {\n iac,\n websiteProjectName: fullyQualifiedName,\n scopeAlias,\n websiteContentPath: joinPathFragments('dist', websiteContentPath),\n websiteNameKebabCase,\n websiteNameClassName,\n });\n }\n\n const projectConfig = readProjectConfiguration(tree, fullyQualifiedName);\n const libraryRoot = projectConfig.root;\n const sharedShadcnStylesImport = relative(\n joinPathFragments(libraryRoot, 'src'),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_SHADCN_DIR,\n 'src',\n 'styles',\n 'globals.css',\n ),\n )\n .split(sep)\n .join('/');\n const sharedShadcnTsconfigRef = relative(\n joinPathFragments(tree.root, websiteContentPath),\n joinPathFragments(\n tree.root,\n PACKAGES_DIR,\n SHARED_SHADCN_DIR,\n 'tsconfig.json',\n ),\n )\n .split(sep)\n .join('/');\n const templateOptions = {\n ...schema,\n fullyQualifiedName,\n pkgMgrCmd: getPackageManagerDisplayCommands().exec,\n tailwind,\n tanstackRouter,\n scopeAlias,\n sharedShadcnStylesImport,\n };\n tree.delete(joinPathFragments(libraryRoot, 'src', 'app'));\n const appCommonTemplatePath = joinPathFragments(\n import.meta.dirname,\n './files/app/common',\n );\n const appTemplatePath = joinPathFragments(\n import.meta.dirname,\n `./files/app/${ux.toLowerCase()}`,\n );\n\n generateFiles(\n tree, // the virtual file system\n appCommonTemplatePath, // path to the file templates\n libraryRoot, // destination path of the files\n templateOptions, // config object to replace variable in file templates\n {\n // User-editable source - preserve any edits on re-run\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree, // the virtual file system\n appTemplatePath, // path to the file templates\n libraryRoot, // destination path of the files\n templateOptions, // config object to replace variable in file templates\n {\n // User-editable source - preserve any edits on re-run\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n if (tanstackRouter) {\n const routerCommonTemplatePath = joinPathFragments(\n import.meta.dirname,\n './files/tanstack-router/common',\n );\n const routerTemplatePath = joinPathFragments(\n import.meta.dirname,\n `./files/tanstack-router/${ux.toLowerCase()}`,\n );\n\n generateFiles(\n tree,\n routerCommonTemplatePath,\n libraryRoot,\n templateOptions,\n {\n // User-editable source (and the TanStack-managed route tree) - preserve on re-run\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n routerTemplatePath,\n libraryRoot,\n templateOptions, // config object to replace variable in file templates\n {\n // User-editable source - preserve any edits on re-run\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n tree.delete(joinPathFragments(websiteContentPath, 'src', 'app.tsx'));\n }\n\n if (e2eTestRunner !== 'none') {\n const e2eFullyQualifiedName = `${fullyQualifiedName}-e2e`;\n const e2eRoot = readProjectConfiguration(tree, e2eFullyQualifiedName).root;\n generateFiles(\n tree, // the virtual file system\n joinPathFragments(import.meta.dirname, `./files/e2e/${e2eTestRunner}`), // path to the file templates\n e2eRoot, // destination path of the files\n { ...schema, ...names(fullyQualifiedName) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n await configureTsProject(\n tree,\n {\n fullyQualifiedName: e2eFullyQualifiedName,\n dir: e2eRoot,\n },\n DEPENDENCIES,\n );\n }\n const viteConfigPath = joinPathFragments(libraryRoot, 'vite.config.mts');\n\n if (tree.exists(viteConfigPath)) {\n // Add Tanstack Router import if enabled\n if (tanstackRouter) {\n await addDestructuredImport(\n tree,\n viteConfigPath,\n ['tanstackRouter'],\n '@tanstack/router-plugin/vite',\n );\n\n await addDestructuredImport(tree, viteConfigPath, ['resolve'], 'path');\n }\n\n // Add TailwindCSS import if enabled\n if (tailwind) {\n await addSingleImport(\n tree,\n viteConfigPath,\n 'tailwindcss',\n '@tailwindcss/vite',\n );\n }\n\n // Update build.outDir. The inferred `vite build` target writes here, so\n // point it at the bundle dir the website infrastructure consumes.\n const outDir = joinPathFragments(\n getRelativePathToRoot(tree, fullyQualifiedName),\n 'dist',\n websiteContentPath,\n 'bundle',\n );\n await applyGritQL(\n tree,\n viteConfigPath,\n `\\`build: { $bprops }\\` where { $bprops <: contains \\`outDir: $_\\` => \\`outDir: '${outDir}'\\` }`,\n );\n\n // Add plugins to the plugins array\n if (tanstackRouter) {\n // Prepend tanstackRouter (must be first plugin) — rewrite works for both single/multi-element\n await applyGritQL(\n tree,\n viteConfigPath,\n \"`plugins: [$items]` => `plugins: [tanstackRouter({ routesDirectory: resolve(import.meta.dirname, 'src/routes'), generatedRouteTree: resolve(import.meta.dirname, 'src/routeTree.gen.ts') }), $items]` where { $items <: within `defineConfig($_)`, $items <: not contains `tanstackRouter` }\",\n );\n }\n\n if (tailwind) {\n await appendToArrayViaGritQL(\n tree,\n viteConfigPath,\n 'plugins:',\n 'tailwindcss()',\n { scope: 'defineConfig($_)' },\n );\n }\n\n // Use Vite's native tsconfig paths resolution (replaces vite-tsconfig-paths).\n // `dedupe` forces a single copy of react/react-dom into the bundle: each\n // project declares its own react dependency, so without this a workspace\n // library's hoisted copy can produce a second React instance and the\n // \"Invalid hook call\" runtime crash.\n await applyGritQL(\n tree,\n viteConfigPath,\n \"or { `defineConfig(() => ({ $props }))` where { $props <: not some `resolve: $_`, $props += `resolve: { tsconfigPaths: true, dedupe: ['react', 'react-dom'] }` }, `defineConfig({ $props })` where { $props <: not some `resolve: $_`, $props += `resolve: { tsconfigPaths: true, dedupe: ['react', 'react-dom'] }` } }\",\n );\n\n // Add define: { global: {} } to the config (handles both callback and direct forms)\n await applyGritQL(\n tree,\n viteConfigPath,\n 'or { `defineConfig(() => ({ $props }))` where { $props <: not contains `define`, $props += `define: { global: {} }` }, `defineConfig({ $props })` where { $props <: not contains `define`, $props += `define: { global: {} }` } }',\n );\n }\n\n updateJson(\n tree,\n joinPathFragments(websiteContentPath, 'tsconfig.json'),\n (tsconfig) => ({\n ...tsconfig,\n compilerOptions: {\n ...tsconfig.compilerOptions,\n moduleResolution: 'Bundler',\n module: 'Preserve',\n },\n }),\n );\n const outDirToRootRelativePath = relative(\n joinPathFragments(tree.root, websiteContentPath),\n tree.root,\n );\n const distDir = joinPathFragments(\n outDirToRootRelativePath,\n 'dist',\n websiteContentPath,\n 'tsc',\n );\n updateJson(\n tree,\n joinPathFragments(websiteContentPath, 'tsconfig.app.json'),\n (tsconfig) => ({\n ...tsconfig,\n compilerOptions: {\n ...tsconfig.compilerOptions,\n outDir: distDir,\n tsBuildInfoFile: joinPathFragments(distDir, 'tsconfig.lib.tsbuildinfo'),\n lib: ['DOM'],\n },\n references:\n ux === 'shadcn'\n ? [\n ...(tsconfig.references ?? []).filter(\n (ref) => ref.path !== sharedShadcnTsconfigRef,\n ),\n {\n path: sharedShadcnTsconfigRef,\n },\n ]\n : tsconfig.references,\n }),\n );\n\n addTsDependencies(tree, DEPENDENCIES, { metadata, projectRoot: libraryRoot });\n\n // @nx/react's applicationGenerator seeds react/react-dom into the root\n // manifest. The website now declares its own pinned versions, so drop the\n // root copies: without catalogs (npm) the root's floating range resolves to\n // a different version than the website's pin, installing a second React and\n // producing the \"Invalid hook call\" runtime crash.\n removeDependenciesFromPackageJson(tree, ['react', 'react-dom'], []);\n\n await addGeneratorMetricsIfApplicable(tree, [\n REACT_WEBSITE_APP_GENERATOR_INFO,\n ]);\n\n // TanStack Router's vite plugin owns this website's route tree and rewrites it\n // in its own (unformatted) shape whenever the config is loaded — including when\n // Nx computes the project graph — so formatting it here would only make\n // generation non-idempotent. The vended biome config excludes `**/*.gen.*`, so\n // the workspace's own `format` target leaves it alone too.\n await formatFilesInSubtree(tree, undefined, {\n ignore: tanstackRouter\n ? [joinPathFragments(libraryRoot, 'src', 'routeTree.gen.ts')]\n : [],\n });\n // The generated vite.config.mts imports these, and Nx's inferred `@nx/vite`\n // plugin loads that config when computing the project graph — so they must be\n // installed even if the caller would otherwise prefer to defer.\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript'],\n ensureResolvable: [\n ...(tailwind ? (['@tailwindcss/vite'] as const) : []),\n ...(tanstackRouter ? (['@tanstack/router-plugin'] as const) : []),\n ],\n });\n}\nexport default tsReactWebsiteGenerator;\n"],"names":["generateFiles","joinPathFragments","names","OverwriteStrategy","readProjectConfiguration","removeDependenciesFromPackageJson","updateJson","updateProjectConfiguration","applicationGenerator","relative","sep","addTsDependencies","addDestructuredImport","addSingleImport","appendToArrayViaGritQL","applyGritQL","declareDependencies","ownedElsewhere","formatFilesInSubtree","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","toKebabCase","getNpmScopePrefix","addGeneratorMetadata","getGeneratorInfo","sortObjectKeys","getRelativePathToRoot","getPackageManagerDisplayCommands","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","PACKAGES_DIR","SHARED_SHADCN_DIR","SHADCN_DEPENDENCIES","sharedShadcnGenerator","addWebsiteInfra","WEBSITE_CONSTRUCTS_PY_DEPENDENCIES","configureTsProject","VITEST_DEPENDENCIES","DEPENDENCIES","ts","name","dev","root","when","m","ux","tanstackRouter","tailwind","py","SUPPORTED_UX_PROVIDERS","REACT_WEBSITE_APP_GENERATOR_INFO","filename","tsReactWebsiteGenerator","tree","schema","Error","npmScopePrefix","scopeAlias","websiteNameClassName","websiteNameKebabCase","fullyQualifiedName","websiteContentPath","directory","subDirectory","projectAlreadyExists","exists","e2eTestRunner","routing","linter","bundler","unitTestRunner","useProjectJson","style","addPlugin","nxJson","plugin","plugins","options","buildTargetName","serveTargetName","devTargetName","previewTargetName","serveStaticTargetName","typecheckTargetName","testTargetName","delete","projectConfiguration","targets","infra","iac","undefined","executor","metadata","description","exec","command","env","SRC_FILE","DEST_DIR","DEST_FILE","dependsOn","outputs","cwd","continuous","framework","dir","websiteProjectName","projectConfig","libraryRoot","sharedShadcnStylesImport","split","join","sharedShadcnTsconfigRef","templateOptions","pkgMgrCmd","appCommonTemplatePath","dirname","appTemplatePath","toLowerCase","overwriteStrategy","KeepExisting","routerCommonTemplatePath","routerTemplatePath","e2eFullyQualifiedName","e2eRoot","viteConfigPath","outDir","scope","tsconfig","compilerOptions","moduleResolution","module","outDirToRootRelativePath","distDir","tsBuildInfoFile","lib","references","filter","ref","path","projectRoot","ignore","preferInstallDependencies","languages","ensureResolvable"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/ts/react-website/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 generateFiles,\n joinPathFragments,\n names,\n OverwriteStrategy,\n readProjectConfiguration,\n removeDependenciesFromPackageJson,\n type Tree,\n updateJson,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { applicationGenerator } from '@nx/react';\nimport { relative, sep } from 'path';\nimport { addTsDependencies } from '../../../utils/add-dependencies.js';\nimport {\n addDestructuredImport,\n addSingleImport,\n appendToArrayViaGritQL,\n applyGritQL,\n} from '../../../utils/ast.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport { resolveIac } from '../../../utils/iac.js';\nimport { installDependencies } from '../../../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics.js';\nimport { kebabCase, toClassName, toKebabCase } from '../../../utils/names.js';\nimport { getNpmScopePrefix } from '../../../utils/npm-scope.js';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n} from '../../../utils/nx.js';\nimport { sortObjectKeys } from '../../../utils/object.js';\nimport { getRelativePathToRoot } from '../../../utils/paths.js';\nimport { getPackageManagerDisplayCommands } from '../../../utils/pkg-manager.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../../utils/shared-constructs.js';\nimport {\n type IacMetadata,\n PACKAGES_DIR,\n SHARED_SHADCN_DIR,\n TERRAFORM_WEBSITE_RUNTIME_CONFIG_FILE,\n} from '../../../utils/shared-constructs-constants.js';\nimport {\n SHADCN_DEPENDENCIES,\n sharedShadcnGenerator,\n} from '../../../utils/shared-shadcn.js';\nimport {\n addWebsiteInfra,\n WEBSITE_CONSTRUCTS_PY_DEPENDENCIES,\n} from '../../../utils/website-constructs/website-constructs.js';\nimport { configureTsProject } from '../../lib/ts-project-utils.js';\nimport { VITEST_DEPENDENCIES } from '../../lib/vitest.js';\n// typescript factory imports removed — now using GritQL for vite config transforms\nimport type {\n TsReactWebsiteGeneratorSchema,\n WebsiteInfraOption,\n} from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface TsReactWebsiteMetadata extends IacMetadata {\n readonly ux: UxOption;\n readonly framework: string;\n readonly infra: WebsiteInfraOption;\n readonly tailwind: boolean;\n readonly tanstackRouter: boolean;\n}\n\n// Each entry names the branch it belongs to, so the same declaration drives both\n// adding and the version sync.\nexport const DEPENDENCIES = declareDependencies<TsReactWebsiteMetadata>()({\n ts: [\n { name: 'react' },\n { name: 'react-dom' },\n // Build/test tooling imported only from vite.config.mts stays at the root.\n { name: '@nx/react', dev: true, root: true },\n { name: '@vitest/ui', dev: true, root: true },\n {\n name: '@cloudscape-design/components',\n when: (m) => m.ux === 'cloudscape',\n },\n {\n name: '@cloudscape-design/board-components',\n when: (m) => m.ux === 'cloudscape',\n },\n {\n name: '@cloudscape-design/global-styles',\n when: (m) => m.ux === 'cloudscape',\n },\n // Shared shadcn components live in the common/shadcn package, but the\n // website's own generated components (e.g. the tanstack-router sidebar)\n // import lucide-react directly, so the website must declare it.\n {\n name: 'lucide-react',\n when: (m) => m.ux === 'shadcn' && m.tanstackRouter,\n },\n { name: 'tailwindcss', when: (m) => m.tailwind },\n {\n name: '@tailwindcss/vite',\n when: (m) => m.tailwind,\n dev: true,\n root: true,\n },\n { name: '@tanstack/react-router', when: (m) => m.tanstackRouter },\n {\n name: '@tanstack/router-plugin',\n when: (m) => m.tanstackRouter,\n dev: true,\n root: true,\n },\n {\n name: '@tanstack/router-generator',\n when: (m) => m.tanstackRouter,\n dev: true,\n root: true,\n },\n {\n name: '@tanstack/virtual-file-routes',\n when: (m) => m.tanstackRouter,\n dev: true,\n root: true,\n },\n {\n name: '@tanstack/router-utils',\n when: (m) => m.tanstackRouter,\n dev: true,\n root: true,\n },\n ...ownedElsewhere(SHADCN_DEPENDENCIES),\n ...ownedElsewhere(VITEST_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: ownedElsewhere(WEBSITE_CONSTRUCTS_PY_DEPENDENCIES),\n});\n\nexport const SUPPORTED_UX_PROVIDERS = ['none', 'cloudscape', 'shadcn'] as const;\n\nexport type UxOption = (typeof SUPPORTED_UX_PROVIDERS)[number];\n\nexport type Ux = UxOption;\n\nexport const REACT_WEBSITE_APP_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport async function tsReactWebsiteGenerator(\n tree: Tree,\n schema: TsReactWebsiteGeneratorSchema,\n) {\n const tailwind = schema.tailwind ?? true;\n const tanstackRouter = schema.tanstackRouter ?? true;\n const ux: Ux = schema.ux ?? 'shadcn';\n if (ux === 'shadcn' && !tailwind) {\n throw new Error('Shadcn requires TailwindCSS to be enabled.');\n }\n const npmScopePrefix = getNpmScopePrefix(tree);\n const scopeAlias = npmScopePrefix;\n const websiteNameClassName = toClassName(schema.name);\n const websiteNameKebabCase = toKebabCase(schema.name);\n const fullyQualifiedName = `${npmScopePrefix}${websiteNameKebabCase}`;\n // NB: interactive nx generator cli can pass empty string\n const websiteContentPath = joinPathFragments(\n schema.directory || '.',\n schema.subDirectory || websiteNameKebabCase,\n );\n\n const projectAlreadyExists = tree.exists(\n joinPathFragments(websiteContentPath, 'project.json'),\n );\n\n // TODO: consider exposing and supporting e2e tests\n const e2eTestRunner = 'none';\n\n if (!projectAlreadyExists) {\n await applicationGenerator(tree, {\n ...schema,\n name: fullyQualifiedName,\n directory: websiteContentPath,\n routing: false,\n e2eTestRunner,\n linter: 'none',\n bundler: 'vite',\n unitTestRunner: 'vitest',\n useProjectJson: true,\n style: 'css',\n // Register the @nx/vite and @nx/vitest plugins so build/serve/test\n // targets are inferred rather than emitting deprecated executor targets.\n addPlugin: true,\n });\n\n // Pin the inferred target names. The vite production build is exposed as\n // `bundle` (which produces the deployable artifact), leaving `build` as an\n // aggregator over lint/compile/test/bundle. vite's own typecheck is dropped\n // in favour of the tsc `compile`.\n updateJson(tree, 'nx.json', (nxJson) => {\n for (const plugin of nxJson.plugins ?? []) {\n if (typeof plugin === 'string') continue;\n if (plugin.plugin === '@nx/vite/plugin') {\n plugin.options = {\n ...plugin.options,\n buildTargetName: 'bundle',\n // Map both of vite's inferred dev-server targets onto `serve` so the\n // plugin doesn't emit a separate `dev`; we author our own `dev`\n // below running the local-dev vite mode.\n serveTargetName: 'serve',\n devTargetName: 'serve',\n previewTargetName: 'preview',\n serveStaticTargetName: 'serve-static',\n typecheckTargetName: 'vite:typecheck',\n };\n } else if (plugin.plugin === '@nx/vitest') {\n plugin.options = {\n ...plugin.options,\n testTargetName: 'test',\n };\n }\n }\n return nxJson;\n });\n\n // Replace with simpler sample source code\n tree.delete(joinPathFragments(websiteContentPath, 'src'));\n }\n\n const projectConfiguration = readProjectConfiguration(\n tree,\n fullyQualifiedName,\n );\n\n const targets = projectConfiguration.targets;\n\n const infra = schema.infra ?? 'cloudfront-s3';\n\n // Configure load-runtime-config target based on IaC provider (only when infra is not none)\n const iac = infra !== 'none' ? await resolveIac(tree, schema.iac) : undefined;\n\n if (iac === 'cdk') {\n targets['load-runtime-config'] = {\n executor: 'nx:run-commands',\n metadata: {\n description: `Load runtime config from your deployed stack for dev purposes. You must set your AWS CLI credentials whilst calling '${getPackageManagerDisplayCommands().exec} nx load-runtime-config ${fullyQualifiedName}'`,\n },\n options: {\n command: `aws s3 cp s3://\\`aws cloudformation describe-stacks --query \"Stacks[?starts_with(StackName, '${kebabCase(npmScopePrefix)}-')][].Outputs[] | [?contains(OutputKey, '${websiteNameClassName}WebsiteBucketName')].OutputValue\" --output text\\`/runtime-config.json \"{projectRoot}/public/runtime-config.json\"`,\n },\n };\n } else if (iac === 'terraform') {\n targets['load-runtime-config'] = {\n executor: 'nx:run-commands',\n metadata: {\n description:\n \"Load runtime config from most recently applied terraform env for dev purposes. Copies the runtime config from the Terraform dist directory to the website's public directory.\",\n },\n options: {\n command:\n 'node -e \"const fs=require(\\'fs\\');fs.mkdirSync(process.env.DEST_DIR,{recursive:true});fs.copyFileSync(process.env.SRC_FILE,process.env.DEST_FILE);\"',\n env: {\n SRC_FILE: TERRAFORM_WEBSITE_RUNTIME_CONFIG_FILE,\n DEST_DIR: `{projectRoot}/public`,\n DEST_FILE: `{projectRoot}/public/runtime-config.json`,\n },\n },\n };\n }\n\n if (!projectAlreadyExists) {\n targets['compile'] = {\n dependsOn: ['^build'],\n executor: 'nx:run-commands',\n outputs: ['{workspaceRoot}/dist/{projectRoot}/tsc'],\n options: {\n command: 'tsc --build tsconfig.app.json',\n cwd: '{projectRoot}',\n },\n };\n // bundle is the @nx/vite/plugin inferred `vite build` (writing to the\n // bundle dir configured in vite.config) — it produces the deployable\n // artifact. build aggregates lint/compile/test/bundle.\n targets['build'] = {\n dependsOn: ['lint', 'compile', 'test', 'bundle'],\n };\n\n // Run the website and its connected dependencies locally. Mirrors the\n // inferred `serve` target but with the local-dev vite mode.\n targets['dev'] = {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n command: 'vite --mode local-dev',\n cwd: '{projectRoot}',\n },\n };\n }\n\n projectConfiguration.targets = sortObjectKeys(targets);\n\n updateProjectConfiguration(tree, fullyQualifiedName, projectConfiguration);\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: TsReactWebsiteMetadata = {\n ux,\n framework: 'react',\n infra,\n tailwind,\n tanstackRouter,\n // Undefined when no infrastructure was generated, so neither provider's\n // packages were added.\n ...(iac ? { iac } : {}),\n };\n addGeneratorMetadata(\n tree,\n projectConfiguration.name,\n REACT_WEBSITE_APP_GENERATOR_INFO,\n metadata,\n );\n\n await configureTsProject(\n tree,\n {\n dir: websiteContentPath,\n fullyQualifiedName,\n },\n DEPENDENCIES,\n );\n\n if (ux === 'shadcn') {\n await sharedShadcnGenerator(tree, DEPENDENCIES);\n }\n\n if (iac) {\n await sharedConstructsGenerator(\n tree,\n {\n iac,\n },\n DEPENDENCIES,\n );\n\n await addWebsiteInfra(tree, {\n iac,\n websiteProjectName: fullyQualifiedName,\n scopeAlias,\n websiteContentPath: joinPathFragments('dist', websiteContentPath),\n websiteNameKebabCase,\n websiteNameClassName,\n });\n }\n\n const projectConfig = readProjectConfiguration(tree, fullyQualifiedName);\n const libraryRoot = projectConfig.root;\n const sharedShadcnStylesImport = relative(\n joinPathFragments(libraryRoot, 'src'),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_SHADCN_DIR,\n 'src',\n 'styles',\n 'globals.css',\n ),\n )\n .split(sep)\n .join('/');\n const sharedShadcnTsconfigRef = relative(\n joinPathFragments(tree.root, websiteContentPath),\n joinPathFragments(\n tree.root,\n PACKAGES_DIR,\n SHARED_SHADCN_DIR,\n 'tsconfig.json',\n ),\n )\n .split(sep)\n .join('/');\n const templateOptions = {\n ...schema,\n fullyQualifiedName,\n pkgMgrCmd: getPackageManagerDisplayCommands().exec,\n tailwind,\n tanstackRouter,\n scopeAlias,\n sharedShadcnStylesImport,\n };\n tree.delete(joinPathFragments(libraryRoot, 'src', 'app'));\n const appCommonTemplatePath = joinPathFragments(\n import.meta.dirname,\n './files/app/common',\n );\n const appTemplatePath = joinPathFragments(\n import.meta.dirname,\n `./files/app/${ux.toLowerCase()}`,\n );\n\n generateFiles(\n tree, // the virtual file system\n appCommonTemplatePath, // path to the file templates\n libraryRoot, // destination path of the files\n templateOptions, // config object to replace variable in file templates\n {\n // User-editable source - preserve any edits on re-run\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree, // the virtual file system\n appTemplatePath, // path to the file templates\n libraryRoot, // destination path of the files\n templateOptions, // config object to replace variable in file templates\n {\n // User-editable source - preserve any edits on re-run\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n if (tanstackRouter) {\n const routerCommonTemplatePath = joinPathFragments(\n import.meta.dirname,\n './files/tanstack-router/common',\n );\n const routerTemplatePath = joinPathFragments(\n import.meta.dirname,\n `./files/tanstack-router/${ux.toLowerCase()}`,\n );\n\n generateFiles(\n tree,\n routerCommonTemplatePath,\n libraryRoot,\n templateOptions,\n {\n // User-editable source (and the TanStack-managed route tree) - preserve on re-run\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n routerTemplatePath,\n libraryRoot,\n templateOptions, // config object to replace variable in file templates\n {\n // User-editable source - preserve any edits on re-run\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n tree.delete(joinPathFragments(websiteContentPath, 'src', 'app.tsx'));\n }\n\n if (e2eTestRunner !== 'none') {\n const e2eFullyQualifiedName = `${fullyQualifiedName}-e2e`;\n const e2eRoot = readProjectConfiguration(tree, e2eFullyQualifiedName).root;\n generateFiles(\n tree, // the virtual file system\n joinPathFragments(import.meta.dirname, `./files/e2e/${e2eTestRunner}`), // path to the file templates\n e2eRoot, // destination path of the files\n { ...schema, ...names(fullyQualifiedName) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n await configureTsProject(\n tree,\n {\n fullyQualifiedName: e2eFullyQualifiedName,\n dir: e2eRoot,\n },\n DEPENDENCIES,\n );\n }\n const viteConfigPath = joinPathFragments(libraryRoot, 'vite.config.mts');\n\n if (tree.exists(viteConfigPath)) {\n // Add Tanstack Router import if enabled\n if (tanstackRouter) {\n await addDestructuredImport(\n tree,\n viteConfigPath,\n ['tanstackRouter'],\n '@tanstack/router-plugin/vite',\n );\n\n await addDestructuredImport(tree, viteConfigPath, ['resolve'], 'path');\n }\n\n // Add TailwindCSS import if enabled\n if (tailwind) {\n await addSingleImport(\n tree,\n viteConfigPath,\n 'tailwindcss',\n '@tailwindcss/vite',\n );\n }\n\n // Update build.outDir. The inferred `vite build` target writes here, so\n // point it at the bundle dir the website infrastructure consumes.\n const outDir = joinPathFragments(\n getRelativePathToRoot(tree, fullyQualifiedName),\n 'dist',\n websiteContentPath,\n 'bundle',\n );\n await applyGritQL(\n tree,\n viteConfigPath,\n `\\`build: { $bprops }\\` where { $bprops <: contains \\`outDir: $_\\` => \\`outDir: '${outDir}'\\` }`,\n );\n\n // Add plugins to the plugins array\n if (tanstackRouter) {\n // Prepend tanstackRouter (must be first plugin) — rewrite works for both single/multi-element\n await applyGritQL(\n tree,\n viteConfigPath,\n \"`plugins: [$items]` => `plugins: [tanstackRouter({ routesDirectory: resolve(import.meta.dirname, 'src/routes'), generatedRouteTree: resolve(import.meta.dirname, 'src/routeTree.gen.ts') }), $items]` where { $items <: within `defineConfig($_)`, $items <: not contains `tanstackRouter` }\",\n );\n }\n\n if (tailwind) {\n await appendToArrayViaGritQL(\n tree,\n viteConfigPath,\n 'plugins:',\n 'tailwindcss()',\n { scope: 'defineConfig($_)' },\n );\n }\n\n // Use Vite's native tsconfig paths resolution (replaces vite-tsconfig-paths).\n // `dedupe` forces a single copy of react/react-dom into the bundle: each\n // project declares its own react dependency, so without this a workspace\n // library's hoisted copy can produce a second React instance and the\n // \"Invalid hook call\" runtime crash.\n await applyGritQL(\n tree,\n viteConfigPath,\n \"or { `defineConfig(() => ({ $props }))` where { $props <: not some `resolve: $_`, $props += `resolve: { tsconfigPaths: true, dedupe: ['react', 'react-dom'] }` }, `defineConfig({ $props })` where { $props <: not some `resolve: $_`, $props += `resolve: { tsconfigPaths: true, dedupe: ['react', 'react-dom'] }` } }\",\n );\n\n // Add define: { global: {} } to the config (handles both callback and direct forms)\n await applyGritQL(\n tree,\n viteConfigPath,\n 'or { `defineConfig(() => ({ $props }))` where { $props <: not contains `define`, $props += `define: { global: {} }` }, `defineConfig({ $props })` where { $props <: not contains `define`, $props += `define: { global: {} }` } }',\n );\n }\n\n updateJson(\n tree,\n joinPathFragments(websiteContentPath, 'tsconfig.json'),\n (tsconfig) => ({\n ...tsconfig,\n compilerOptions: {\n ...tsconfig.compilerOptions,\n moduleResolution: 'Bundler',\n module: 'Preserve',\n },\n }),\n );\n const outDirToRootRelativePath = relative(\n joinPathFragments(tree.root, websiteContentPath),\n tree.root,\n );\n const distDir = joinPathFragments(\n outDirToRootRelativePath,\n 'dist',\n websiteContentPath,\n 'tsc',\n );\n updateJson(\n tree,\n joinPathFragments(websiteContentPath, 'tsconfig.app.json'),\n (tsconfig) => ({\n ...tsconfig,\n compilerOptions: {\n ...tsconfig.compilerOptions,\n outDir: distDir,\n tsBuildInfoFile: joinPathFragments(distDir, 'tsconfig.lib.tsbuildinfo'),\n lib: ['DOM'],\n },\n references:\n ux === 'shadcn'\n ? [\n ...(tsconfig.references ?? []).filter(\n (ref) => ref.path !== sharedShadcnTsconfigRef,\n ),\n {\n path: sharedShadcnTsconfigRef,\n },\n ]\n : tsconfig.references,\n }),\n );\n\n addTsDependencies(tree, DEPENDENCIES, { metadata, projectRoot: libraryRoot });\n\n // @nx/react's applicationGenerator seeds react/react-dom into the root\n // manifest. The website now declares its own pinned versions, so drop the\n // root copies: without catalogs (npm) the root's floating range resolves to\n // a different version than the website's pin, installing a second React and\n // producing the \"Invalid hook call\" runtime crash.\n removeDependenciesFromPackageJson(tree, ['react', 'react-dom'], []);\n\n await addGeneratorMetricsIfApplicable(tree, [\n REACT_WEBSITE_APP_GENERATOR_INFO,\n ]);\n\n // TanStack Router's vite plugin owns this website's route tree and rewrites it\n // in its own (unformatted) shape whenever the config is loaded — including when\n // Nx computes the project graph — so formatting it here would only make\n // generation non-idempotent. The vended biome config excludes `**/*.gen.*`, so\n // the workspace's own `format` target leaves it alone too.\n await formatFilesInSubtree(tree, undefined, {\n ignore: tanstackRouter\n ? [joinPathFragments(libraryRoot, 'src', 'routeTree.gen.ts')]\n : [],\n });\n // The generated vite.config.mts imports these, and Nx's inferred `@nx/vite`\n // plugin loads that config when computing the project graph — so they must be\n // installed even if the caller would otherwise prefer to defer.\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript'],\n ensureResolvable: [\n ...(tailwind ? (['@tailwindcss/vite'] as const) : []),\n ...(tanstackRouter ? (['@tanstack/router-plugin'] as const) : []),\n ],\n });\n}\nexport default tsReactWebsiteGenerator;\n"],"names":["generateFiles","joinPathFragments","names","OverwriteStrategy","readProjectConfiguration","removeDependenciesFromPackageJson","updateJson","updateProjectConfiguration","applicationGenerator","relative","sep","addTsDependencies","addDestructuredImport","addSingleImport","appendToArrayViaGritQL","applyGritQL","declareDependencies","ownedElsewhere","formatFilesInSubtree","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","toKebabCase","getNpmScopePrefix","addGeneratorMetadata","getGeneratorInfo","sortObjectKeys","getRelativePathToRoot","getPackageManagerDisplayCommands","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","PACKAGES_DIR","SHARED_SHADCN_DIR","TERRAFORM_WEBSITE_RUNTIME_CONFIG_FILE","SHADCN_DEPENDENCIES","sharedShadcnGenerator","addWebsiteInfra","WEBSITE_CONSTRUCTS_PY_DEPENDENCIES","configureTsProject","VITEST_DEPENDENCIES","DEPENDENCIES","ts","name","dev","root","when","m","ux","tanstackRouter","tailwind","py","SUPPORTED_UX_PROVIDERS","REACT_WEBSITE_APP_GENERATOR_INFO","filename","tsReactWebsiteGenerator","tree","schema","Error","npmScopePrefix","scopeAlias","websiteNameClassName","websiteNameKebabCase","fullyQualifiedName","websiteContentPath","directory","subDirectory","projectAlreadyExists","exists","e2eTestRunner","routing","linter","bundler","unitTestRunner","useProjectJson","style","addPlugin","nxJson","plugin","plugins","options","buildTargetName","serveTargetName","devTargetName","previewTargetName","serveStaticTargetName","typecheckTargetName","testTargetName","delete","projectConfiguration","targets","infra","iac","undefined","executor","metadata","description","exec","command","env","SRC_FILE","DEST_DIR","DEST_FILE","dependsOn","outputs","cwd","continuous","framework","dir","websiteProjectName","projectConfig","libraryRoot","sharedShadcnStylesImport","split","join","sharedShadcnTsconfigRef","templateOptions","pkgMgrCmd","appCommonTemplatePath","dirname","appTemplatePath","toLowerCase","overwriteStrategy","KeepExisting","routerCommonTemplatePath","routerTemplatePath","e2eFullyQualifiedName","e2eRoot","viteConfigPath","outDir","scope","tsconfig","compilerOptions","moduleResolution","module","outDirToRootRelativePath","distDir","tsBuildInfoFile","lib","references","filter","ref","path","projectRoot","ignore","preferInstallDependencies","languages","ensureResolvable"],"mappings":"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"}
@@ -13,8 +13,10 @@ type IACProvider = {
13
13
  /**
14
14
  * Dependencies a caller must declare to add an AgentCore Gateway construct.
15
15
  *
16
- * Gated on infrastructure having been generated, since the construct helpers only
17
- * run on that branch.
16
+ * Both providers render Cedar policies with `ejs`, each from a different
17
+ * manifest: the CDK construct imports it from the shared constructs project,
18
+ * while Terraform's `render-cedar.cjs` resolves it from the workspace root,
19
+ * since the shared terraform project it runs in has no `package.json`.
18
20
  */
19
21
  export declare const AGENT_CORE_CONSTRUCTS_DEPENDENCIES: readonly [{
20
22
  readonly name: "ejs";
@@ -25,6 +27,11 @@ export declare const AGENT_CORE_CONSTRUCTS_DEPENDENCIES: readonly [{
25
27
  }, {
26
28
  readonly name: "@types/ejs";
27
29
  readonly when: (m: IacMetadata) => boolean;
30
+ }, {
31
+ readonly name: "ejs";
32
+ readonly when: (m: IacMetadata) => boolean;
33
+ readonly dev: true;
34
+ readonly root: true;
28
35
  }];
29
36
  /**
30
37
  * Python versions the generated Terraform pins in an inline `uv run --with`
@@ -7,25 +7,33 @@ import { forDependencies } from "../declared-dependencies.js";
7
7
  import { addDependenciesToPackageJson } from "../dependencies.js";
8
8
  import { esmVars } from "../module-format.js";
9
9
  import { addDependencyToTargetIfNotPresent } from "../nx.js";
10
- import { generatedInfrastructure, generatedTerraform, PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, SHARED_TERRAFORM_DIR } from "../shared-constructs-constants.js";
10
+ import { generatedCdk, generatedTerraform, PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, SHARED_TERRAFORM_DIR } from "../shared-constructs-constants.js";
11
11
  import { PY_VERSIONS, terraformProviderVersions, withVersions } from "../versions.js";
12
12
  /**
13
13
  * Dependencies a caller must declare to add an AgentCore Gateway construct.
14
14
  *
15
- * Gated on infrastructure having been generated, since the construct helpers only
16
- * run on that branch.
15
+ * Both providers render Cedar policies with `ejs`, each from a different
16
+ * manifest: the CDK construct imports it from the shared constructs project,
17
+ * while Terraform's `render-cedar.cjs` resolves it from the workspace root,
18
+ * since the shared terraform project it runs in has no `package.json`.
17
19
  */ export const AGENT_CORE_CONSTRUCTS_DEPENDENCIES = [
18
20
  {
19
21
  name: 'ejs',
20
- when: generatedInfrastructure
22
+ when: generatedCdk
21
23
  },
22
24
  {
23
25
  name: '@aws-sdk/client-bedrock-agentcore',
24
- when: generatedInfrastructure
26
+ when: generatedCdk
25
27
  },
26
28
  {
27
29
  name: '@types/ejs',
28
- when: generatedInfrastructure
30
+ when: generatedCdk
31
+ },
32
+ {
33
+ name: 'ejs',
34
+ when: generatedTerraform,
35
+ dev: true,
36
+ root: true
29
37
  }
30
38
  ];
31
39
  /**
@@ -134,7 +142,7 @@ export const addAgentCoreGatewayInfra = async (tree, options, declaration)=>{
134
142
  await addAgentCoreGatewayCDKInfra(tree, options, declaration);
135
143
  break;
136
144
  case 'terraform':
137
- addAgentCoreGatewayTerraformInfra(tree, options);
145
+ addAgentCoreGatewayTerraformInfra(tree, options, declaration);
138
146
  break;
139
147
  }
140
148
  updateJson(tree, joinPathFragments(PACKAGES_DIR, options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR, 'project.json'), (config)=>{
@@ -173,7 +181,7 @@ const addAgentCoreGatewayCDKInfra = async (tree, options, declaration)=>{
173
181
  '@types/ejs'
174
182
  ]), joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'package.json'));
175
183
  };
176
- const addAgentCoreGatewayTerraformInfra = (tree, options)=>{
184
+ const addAgentCoreGatewayTerraformInfra = (tree, options, declaration)=>{
177
185
  generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'terraform', 'core', 'agentcore-gateway'), joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'core', 'agentcore-gateway'), {
178
186
  ...terraformProviderVersions()
179
187
  }, {
@@ -199,7 +207,13 @@ const addAgentCoreGatewayTerraformInfra = (tree, options)=>{
199
207
  if (tree.exists(renderScript)) {
200
208
  tree.delete(renderScript);
201
209
  }
210
+ return;
202
211
  }
212
+ // render-cedar.cjs resolves ejs from the workspace root, since the shared
213
+ // terraform project it runs in has no package.json.
214
+ addDependenciesToPackageJson(tree, {}, withVersions(forDependencies(declaration), [
215
+ 'ejs'
216
+ ]));
203
217
  };
204
218
  /**
205
219
  * Add AgentCore Harness infrastructure for the selected IaC provider.