@aws/nx-plugin 0.45.1 → 0.47.0

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 (114) hide show
  1. package/package.json +1 -1
  2. package/src/infra/app/generator.js +4 -1
  3. package/src/infra/app/generator.js.map +1 -1
  4. package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +3729 -0
  5. package/src/py/fast-api/generator.js +57 -50
  6. package/src/py/fast-api/generator.js.map +1 -1
  7. package/src/py/fast-api/react/__snapshots__/generator.spec.ts.snap +1 -0
  8. package/src/py/fast-api/schema.d.ts +1 -0
  9. package/src/py/fast-api/schema.json +8 -0
  10. package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +310 -0
  11. package/src/py/lambda-function/generator.js +15 -25
  12. package/src/py/lambda-function/generator.js.map +1 -1
  13. package/src/py/lambda-function/schema.d.ts +1 -0
  14. package/src/py/lambda-function/schema.json +8 -0
  15. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +590 -0
  16. package/src/py/mcp-server/generator.js +4 -18
  17. package/src/py/mcp-server/generator.js.map +1 -1
  18. package/src/py/mcp-server/schema.d.ts +1 -0
  19. package/src/py/mcp-server/schema.json +8 -0
  20. package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +590 -0
  21. package/src/py/strands-agent/generator.js +4 -18
  22. package/src/py/strands-agent/generator.js.map +1 -1
  23. package/src/py/strands-agent/schema.d.ts +1 -0
  24. package/src/py/strands-agent/schema.json +8 -0
  25. package/src/terraform/project/generator.js +23 -7
  26. package/src/terraform/project/generator.js.map +1 -1
  27. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +3729 -0
  28. package/src/trpc/backend/generator.js +6 -17
  29. package/src/trpc/backend/generator.js.map +1 -1
  30. package/src/trpc/backend/schema.d.ts +1 -0
  31. package/src/trpc/backend/schema.json +8 -0
  32. package/src/trpc/react/__snapshots__/generator.spec.ts.snap +1 -0
  33. package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +310 -0
  34. package/src/ts/lambda-function/generator.js +15 -27
  35. package/src/ts/lambda-function/generator.js.map +1 -1
  36. package/src/ts/lambda-function/schema.d.ts +1 -0
  37. package/src/ts/lambda-function/schema.json +8 -0
  38. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +590 -0
  39. package/src/ts/mcp-server/generator.js +4 -18
  40. package/src/ts/mcp-server/generator.js.map +1 -1
  41. package/src/ts/mcp-server/schema.d.ts +1 -0
  42. package/src/ts/mcp-server/schema.json +8 -0
  43. package/src/ts/nx-plugin/generator.js +1 -0
  44. package/src/ts/nx-plugin/generator.js.map +1 -1
  45. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +756 -0
  46. package/src/ts/react-website/app/generator.js +42 -43
  47. package/src/ts/react-website/app/generator.js.map +1 -1
  48. package/src/ts/react-website/app/schema.d.ts +1 -0
  49. package/src/ts/react-website/app/schema.json +8 -0
  50. package/src/ts/react-website/cognito-auth/__snapshots__/generator.spec.ts.snap +259 -0
  51. package/src/ts/react-website/cognito-auth/generator.js +10 -13
  52. package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
  53. package/src/ts/react-website/cognito-auth/schema.d.ts +1 -0
  54. package/src/ts/react-website/cognito-auth/schema.json +8 -0
  55. package/src/ts/react-website/runtime-config/__snapshots__/generator.spec.ts.snap +0 -40
  56. package/src/ts/react-website/runtime-config/generator.js +0 -2
  57. package/src/ts/react-website/runtime-config/generator.js.map +1 -1
  58. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +11 -5
  59. package/src/utils/agent-core-constructs/agent-core-constructs.js +51 -10
  60. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  61. package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +46 -0
  62. package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +536 -0
  63. package/src/utils/api-constructs/api-constructs.d.ts +4 -4
  64. package/src/utils/api-constructs/api-constructs.js +45 -5
  65. package/src/utils/api-constructs/api-constructs.js.map +1 -1
  66. package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +392 -0
  67. package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +518 -0
  68. package/src/utils/api-constructs/files/terraform/core/api/http/http-api/http-api.tf.template +250 -0
  69. package/src/utils/api-constructs/files/terraform/core/api/rest/rest-api/rest-api.tf.template +150 -0
  70. package/src/utils/files/terraform/src/core/runtime-config/entry/entry.tf.template +119 -0
  71. package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +28 -0
  72. package/src/utils/files/terraform/src/metrics/metrics.tf.template +3 -2
  73. package/src/{py/lambda-function/files/common/constructs/src/app/lambda-functions/__constructFunctionKebabCase__.ts.template → utils/function-constructs/files/cdk/app/lambda-functions/__functionNameKebabCase__.ts.template} +5 -5
  74. package/src/utils/function-constructs/files/terraform/app/lambda-functions/__functionNameKebabCase__/__functionNameKebabCase__.tf.template +150 -0
  75. package/src/utils/function-constructs/function-constructs.d.ts +19 -0
  76. package/src/utils/function-constructs/function-constructs.js +57 -0
  77. package/src/utils/function-constructs/function-constructs.js.map +1 -0
  78. package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +123 -0
  79. package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +421 -0
  80. package/src/utils/identity-constructs/files/terraform/core/user-identity/main.tf.template +47 -0
  81. package/src/utils/identity-constructs/identity-constructs.d.ts +15 -0
  82. package/src/utils/identity-constructs/identity-constructs.js +84 -0
  83. package/src/utils/identity-constructs/identity-constructs.js.map +1 -0
  84. package/src/utils/metrics.js +1 -1
  85. package/src/utils/metrics.js.map +1 -1
  86. package/src/utils/py.d.ts +5 -0
  87. package/src/utils/py.js +9 -1
  88. package/src/utils/py.js.map +1 -1
  89. package/src/utils/shared-constructs-constants.d.ts +2 -0
  90. package/src/utils/shared-constructs-constants.js +3 -1
  91. package/src/utils/shared-constructs-constants.js.map +1 -1
  92. package/src/utils/shared-constructs.js +26 -2
  93. package/src/utils/shared-constructs.js.map +1 -1
  94. package/src/utils/versions.d.ts +3 -1
  95. package/src/utils/versions.js +2 -0
  96. package/src/utils/versions.js.map +1 -1
  97. package/src/utils/website-constructs/files/terraform/app/static-websites/__websiteNameKebabCase__/__websiteNameKebabCase__.tf.template +42 -0
  98. package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +709 -0
  99. package/src/utils/website-constructs/website-constructs.d.ts +18 -0
  100. package/src/utils/website-constructs/website-constructs.js +61 -0
  101. package/src/utils/website-constructs/website-constructs.js.map +1 -0
  102. package/src/ts/lambda-function/files/common/constructs/src/app/lambda-functions/__constructFunctionNameKebabCase__.ts.template +0 -24
  103. /package/src/utils/agent-core-constructs/files/{app → cdk/app}/agent-core/__nameKebabCase__/Dockerfile.template +0 -0
  104. /package/src/utils/agent-core-constructs/files/{app → cdk/app}/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +0 -0
  105. /package/src/utils/agent-core-constructs/files/{core → cdk/core}/agent-core/runtime.ts.template +0 -0
  106. /package/src/utils/api-constructs/files/{app → cdk/app}/apis/http/__apiNameKebabCase__.ts.template +0 -0
  107. /package/src/utils/api-constructs/files/{app → cdk/app}/apis/rest/__apiNameKebabCase__.ts.template +0 -0
  108. /package/src/utils/api-constructs/files/{core → cdk/core}/api/http/http-api.ts.template +0 -0
  109. /package/src/utils/api-constructs/files/{core → cdk/core}/api/rest/rest-api.ts.template +0 -0
  110. /package/src/utils/api-constructs/files/{core → cdk/core}/api/trpc/trpc-utils.ts.template +0 -0
  111. /package/src/utils/api-constructs/files/{core → cdk/core}/api/utils/utils.ts.template +0 -0
  112. /package/src/{ts/react-website/cognito-auth/files/common/constructs/src → utils/identity-constructs/files/cdk}/core/user-identity.ts.template +0 -0
  113. /package/src/{ts/react-website/app/files/common/constructs/src → utils/website-constructs/files/cdk}/app/static-websites/__websiteNameKebabCase__.ts.template +0 -0
  114. /package/src/{ts/react-website/app/files/common/constructs/src → utils/website-constructs/files/cdk}/core/static-website.ts.template +0 -0
@@ -0,0 +1,150 @@
1
+ variable "tags" {
2
+ description = "Tags to apply to resources"
3
+ type = map(string)
4
+ default = {}
5
+ }
6
+
7
+ variable "env" {
8
+ description = "Additional environment variables for the Lambda function"
9
+ type = map(string)
10
+ default = {}
11
+ }
12
+
13
+ variable "additional_iam_policy_statements" {
14
+ description = "Additional IAM policy statements to attach to the Lambda role"
15
+ type = list(object({
16
+ Effect = string
17
+ Action = list(string)
18
+ Resource = list(string)
19
+ }))
20
+ default = []
21
+ }
22
+
23
+ data "aws_caller_identity" "current" {}
24
+ data "aws_region" "current" {}
25
+
26
+ locals {
27
+ aws_account_id = data.aws_caller_identity.current.account_id
28
+ aws_region = data.aws_region.current.name
29
+ }
30
+
31
+ resource "random_string" "suffix" {
32
+ length = 8
33
+ special = false
34
+ upper = false
35
+ }
36
+
37
+ resource "aws_iam_role" "lambda_role" {
38
+ name = "<%- functionNameKebabCase %>-role-${random_string.suffix.result}"
39
+
40
+ assume_role_policy = jsonencode({
41
+ Version = "2012-10-17"
42
+ Statement = [
43
+ {
44
+ Sid = "LambdaAssumeRolePolicy"
45
+ Effect = "Allow"
46
+ Principal = {
47
+ Service = "lambda.amazonaws.com"
48
+ }
49
+ Action = "sts:AssumeRole"
50
+ }
51
+ ]
52
+ })
53
+
54
+ tags = var.tags
55
+ }
56
+
57
+ resource "aws_iam_policy" "lambda_policy" {
58
+ name = "<%- functionNameKebabCase %>-policy-${random_string.suffix.result}"
59
+ description = "Policy for <%- functionNameKebabCase %> Lambda function"
60
+
61
+ policy = jsonencode({
62
+ Version = "2012-10-17"
63
+ Statement = concat([
64
+ {
65
+ Sid = "CloudWatchLogsAccess"
66
+ Effect = "Allow"
67
+ Action = [
68
+ "logs:CreateLogGroup",
69
+ "logs:CreateLogStream",
70
+ "logs:PutLogEvents"
71
+ ]
72
+ Resource = [
73
+ "arn:aws:logs:${local.aws_region}:${local.aws_account_id}:log-group:/aws/lambda/<%- functionNameKebabCase %>-${random_string.suffix.result}:*"
74
+ ]
75
+ },
76
+ {
77
+ Sid = "XRayAccess"
78
+ Effect = "Allow"
79
+ Action = [
80
+ "xray:PutTraceSegments",
81
+ "xray:PutTelemetryRecords"
82
+ ]
83
+ Resource = ["*"]
84
+ }
85
+ ], var.additional_iam_policy_statements)
86
+ })
87
+
88
+ tags = var.tags
89
+ }
90
+
91
+ # Attach the policy to the role
92
+ resource "aws_iam_role_policy_attachment" "lambda_policy_attachment" {
93
+ role = aws_iam_role.lambda_role.name
94
+ policy_arn = aws_iam_policy.lambda_policy.arn
95
+ }
96
+
97
+ data "archive_file" "lambda_zip" {
98
+ type = "zip"
99
+ source_dir = "${path.module}/../../../../../../../<%- bundlePathFromRoot %>"
100
+ output_path = "${path.module}/../../../../../../../dist/packages/common/terraform/lambda-functions/<%- functionNameKebabCase %>/lambda.zip"
101
+ }
102
+
103
+ resource "aws_lambda_function" "lambda_function" {
104
+ #checkov:skip=CKV_AWS_117:Lambda function does not need to be in VPC for this use case
105
+ #checkov:skip=CKV_AWS_116:Dead Letter Queue not required for this simple use case
106
+ #checkov:skip=CKV_AWS_272:Code signing not required for this use case
107
+ #checkov:skip=CKV_AWS_115:Concurrent execution limit not required for this use case
108
+ #checkov:skip=CKV_AWS_173:Lambda environment variables encrypted by managed key
109
+ filename = data.archive_file.lambda_zip.output_path
110
+ function_name = "<%- functionNameKebabCase %>-${random_string.suffix.result}"
111
+ role = aws_iam_role.lambda_role.arn
112
+ handler = "<%- handler %>"
113
+ source_code_hash = data.archive_file.lambda_zip.output_base64sha256
114
+ runtime = "<%- runtime %>"
115
+ timeout = 30
116
+
117
+ tracing_config {
118
+ mode = "Active"
119
+ }
120
+
121
+ environment {
122
+ variables = merge({
123
+ AWS_CONNECTION_REUSE_ENABLED = "1"
124
+ }, var.env)
125
+ }
126
+
127
+ tags = var.tags
128
+
129
+ depends_on = [aws_iam_role_policy_attachment.lambda_policy_attachment]
130
+ }
131
+
132
+ output "function_name" {
133
+ description = "Name of the Lambda function"
134
+ value = aws_lambda_function.lambda_function.function_name
135
+ }
136
+
137
+ output "function_arn" {
138
+ description = "ARN of the Lambda function"
139
+ value = aws_lambda_function.lambda_function.arn
140
+ }
141
+
142
+ output "role_arn" {
143
+ description = "ARN of the Lambda execution role"
144
+ value = aws_iam_role.lambda_role.arn
145
+ }
146
+
147
+ output "role_name" {
148
+ description = "Name of the Lambda execution role"
149
+ value = aws_iam_role.lambda_role.name
150
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { Tree } from '@nx/devkit';
6
+ export interface AddLambdaFunctionConstructOptions {
7
+ functionProjectName: string;
8
+ functionNameClassName: string;
9
+ functionNameKebabCase: string;
10
+ bundlePathFromRoot: string;
11
+ handler: string;
12
+ runtime: 'node' | 'python';
13
+ }
14
+ /**
15
+ * Add infrastructure for a lambda function
16
+ */
17
+ export declare const addLambdaFunctionInfra: (tree: Tree, options: AddLambdaFunctionConstructOptions & {
18
+ iacProvider: "CDK" | "Terraform";
19
+ }) => void;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addLambdaFunctionInfra = void 0;
4
+ /**
5
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+ const devkit_1 = require("@nx/devkit");
9
+ const shared_constructs_constants_1 = require("../shared-constructs-constants");
10
+ const ast_1 = require("../ast");
11
+ /**
12
+ * Add infrastructure for a lambda function
13
+ */
14
+ const addLambdaFunctionInfra = (tree, options) => {
15
+ if (options.iacProvider === 'CDK') {
16
+ addLambdaFunctionCdkConstructs(tree, options);
17
+ }
18
+ else if (options.iacProvider === 'Terraform') {
19
+ addLambdaFunctionTerraformModules(tree, options);
20
+ }
21
+ else {
22
+ throw new Error(`Unsupported iacProvider ${options.iacProvider}`);
23
+ }
24
+ (0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, options.iacProvider === 'CDK'
25
+ ? shared_constructs_constants_1.SHARED_CONSTRUCTS_DIR
26
+ : shared_constructs_constants_1.SHARED_TERRAFORM_DIR, 'project.json'), (config) => {
27
+ var _a;
28
+ if (!config.targets) {
29
+ config.targets = {};
30
+ }
31
+ if (!config.targets.build) {
32
+ config.targets.build = {};
33
+ }
34
+ config.targets.build.dependsOn = [
35
+ ...((_a = config.targets.build.dependsOn) !== null && _a !== void 0 ? _a : []),
36
+ `${options.functionProjectName}:build`,
37
+ ];
38
+ return config;
39
+ });
40
+ };
41
+ exports.addLambdaFunctionInfra = addLambdaFunctionInfra;
42
+ const addLambdaFunctionCdkConstructs = (tree, options) => {
43
+ // Generate app specific CDK construct
44
+ (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', 'cdk', 'app', 'lambda-functions'), (0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_CONSTRUCTS_DIR, 'src', 'app', 'lambda-functions'), Object.assign(Object.assign({}, options), { runtime: `Runtime.${options.runtime === 'python' ? 'PYTHON_3_12' : 'NODEJS_LATEST'}` }), {
45
+ overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting,
46
+ });
47
+ // Export app specific CDK construct
48
+ (0, ast_1.addStarExport)(tree, (0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_CONSTRUCTS_DIR, 'src', 'app', 'lambda-functions', 'index.ts'), `./${options.functionNameKebabCase}.js`);
49
+ (0, ast_1.addStarExport)(tree, (0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_CONSTRUCTS_DIR, 'src', 'app', 'index.ts'), './lambda-functions/index.js');
50
+ };
51
+ const addLambdaFunctionTerraformModules = (tree, options) => {
52
+ // Generate app specific terraform module
53
+ (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', 'terraform', 'app', 'lambda-functions'), (0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_TERRAFORM_DIR, 'src', 'app', 'lambda-functions'), Object.assign(Object.assign({}, options), { runtime: options.runtime === 'python' ? 'python3.12' : 'nodejs22.x' }), {
54
+ overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting,
55
+ });
56
+ };
57
+ //# sourceMappingURL=function-constructs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-constructs.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/utils/function-constructs/function-constructs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ terraform {
2
+ required_providers {
3
+ aws = {
4
+ source = "hashicorp/aws"
5
+ version = "~> 6.0"
6
+ }
7
+ }
8
+ }
9
+
10
+ # Variables
11
+ variable "callback_url" {
12
+ description = "Callback URL to add (e.g., https://d123456789.cloudfront.net)"
13
+ type = string
14
+ }
15
+
16
+ # Read runtime config to get user pool client details
17
+ module "runtime_config_reader" {
18
+ source = "../../runtime-config/read"
19
+ }
20
+
21
+ # Extract cognito details from runtime config
22
+ locals {
23
+ cognito_props = try(module.runtime_config_reader.config.cognitoProps, null)
24
+
25
+ user_pool_id = local.cognito_props != null ? local.cognito_props.userPoolId : null
26
+ user_pool_client_id = local.cognito_props != null ? local.cognito_props.userPoolWebClientId : null
27
+ }
28
+
29
+ # Validation: Ensure cognito props exist in runtime config
30
+ resource "terraform_data" "validate_cognito_props" {
31
+ lifecycle {
32
+ precondition {
33
+ condition = local.cognito_props != null
34
+ error_message = "ERROR: cognitoProps not found in runtime config. Ensure user-identity module has been deployed first and has added cognitoProps to the runtime configuration."
35
+ }
36
+
37
+ precondition {
38
+ condition = local.user_pool_id != null && local.user_pool_id != ""
39
+ error_message = "ERROR: cognitoProps.userPoolId is missing or empty in runtime config. Check that user-identity module completed successfully."
40
+ }
41
+
42
+ precondition {
43
+ condition = local.user_pool_client_id != null && local.user_pool_client_id != ""
44
+ error_message = "ERROR: cognitoProps.userPoolWebClientId is missing or empty in runtime config. Check that user-identity module completed successfully."
45
+ }
46
+ }
47
+ }
48
+
49
+
50
+ # Update the user pool client with additional callback URL
51
+ resource "null_resource" "add_callback_url" {
52
+ triggers = {
53
+ callback_url = var.callback_url
54
+ user_pool_id = local.user_pool_id
55
+ user_pool_client_id = local.user_pool_client_id
56
+ }
57
+
58
+ provisioner "local-exec" {
59
+ command = <<-EOT
60
+ uv run --with boto3 python -c "
61
+ import boto3
62
+ import sys
63
+
64
+ # Configuration
65
+ user_pool_id = '${local.user_pool_id}'
66
+ client_id = '${local.user_pool_client_id}'
67
+ new_callback_url = '${var.callback_url}'
68
+
69
+ # Initialize Cognito client
70
+ cognito = boto3.client('cognito-idp')
71
+
72
+ try:
73
+ # Get current user pool client configuration
74
+ response = cognito.describe_user_pool_client(
75
+ UserPoolId=user_pool_id,
76
+ ClientId=client_id
77
+ )
78
+
79
+ client_config = response['UserPoolClient']
80
+ current_callback_urls = client_config.get('CallbackURLs', [])
81
+ current_logout_urls = client_config.get('LogoutURLs', [])
82
+
83
+ # Check if URL already exists
84
+ if new_callback_url in current_callback_urls:
85
+ print(f'Callback URL {new_callback_url} already exists')
86
+ else:
87
+ # Add new URL to both callback and logout URLs
88
+ updated_callback_urls = current_callback_urls + [new_callback_url]
89
+ updated_logout_urls = current_logout_urls + [new_callback_url]
90
+
91
+ # Update the user pool client
92
+ # Only include valid update parameters (exclude read-only fields and ones we're setting)
93
+ valid_update_params = [
94
+ 'ClientName', 'RefreshTokenValidity', 'AccessTokenValidity', 'IdTokenValidity',
95
+ 'TokenValidityUnits', 'ReadAttributes', 'WriteAttributes', 'ExplicitAuthFlows',
96
+ 'SupportedIdentityProviders', 'DefaultRedirectURI', 'AllowedOAuthFlows',
97
+ 'AllowedOAuthScopes', 'AllowedOAuthFlowsUserPoolClient', 'AnalyticsConfiguration',
98
+ 'PreventUserExistenceErrors', 'EnableTokenRevocation',
99
+ 'EnablePropagateAdditionalUserContextData', 'AuthSessionValidity', 'RefreshTokenRotation'
100
+ ]
101
+
102
+ update_config = {k: v for k, v in client_config.items() if k in valid_update_params}
103
+
104
+ cognito.update_user_pool_client(
105
+ UserPoolId=user_pool_id,
106
+ ClientId=client_id,
107
+ CallbackURLs=updated_callback_urls,
108
+ LogoutURLs=updated_logout_urls,
109
+ **update_config
110
+ )
111
+
112
+ print(f'Successfully added callback URL: {new_callback_url}')
113
+
114
+ except Exception as e:
115
+ print(f'Error updating callback URLs: {e}')
116
+ sys.exit(1)
117
+ "
118
+ EOT
119
+ }
120
+
121
+ depends_on = [terraform_data.validate_cognito_props]
122
+ }
123
+