@aws/nx-plugin 1.0.3 → 1.0.5

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 (39) hide show
  1. package/LICENSE-THIRD-PARTY +7 -7
  2. package/migrations.json +10 -5
  3. package/package.json +4 -4
  4. package/src/infra/app/__snapshots__/generator.spec.ts.snap +3 -3
  5. package/src/license/dependency-check/collectors/npm-collector.d.ts +14 -0
  6. package/src/license/dependency-check/collectors/npm-collector.js +35 -1
  7. package/src/license/dependency-check/collectors/npm-collector.js.map +1 -1
  8. package/src/migrations/latest/api-custom-domain-runtime-config/metadata.json +3 -0
  9. package/src/migrations/latest/api-custom-domain-runtime-config/migration.js +362 -0
  10. package/src/migrations/latest/api-custom-domain-runtime-config/migration.js.map +1 -0
  11. package/src/migrations/v1.0.3/0001-terraform-init-target/migration.d.ts +6 -0
  12. package/src/migrations/v1.0.3/0001-terraform-init-target/migration.js.map +1 -0
  13. package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +3 -3
  14. package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +3 -3
  15. package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +1 -1
  16. package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +54 -6
  17. package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +378 -6
  18. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +3 -3
  19. package/src/py/rdb/__snapshots__/generator.spec.ts.snap +2 -2
  20. package/src/smithy/project/__snapshots__/generator.spec.ts.snap +16 -16
  21. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +253 -5
  22. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +432 -12
  23. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +2 -2
  24. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +1 -1
  25. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +1 -1
  26. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +13 -13
  27. package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +1 -1
  28. package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +34 -4
  29. package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +20 -2
  30. package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +63 -1
  31. package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +63 -1
  32. package/src/utils/docker.d.ts +1 -1
  33. package/src/utils/versions.d.ts +54 -54
  34. package/src/utils/versions.js +54 -54
  35. package/src/utils/versions.js.map +1 -1
  36. package/src/migrations/latest/terraform-init-target/migration.js.map +0 -1
  37. /package/src/migrations/latest/{terraform-init-target → api-custom-domain-runtime-config}/migration.d.ts +0 -0
  38. /package/src/migrations/{latest/terraform-init-target → v1.0.3/0001-terraform-init-target}/metadata.json +0 -0
  39. /package/src/migrations/{latest/terraform-init-target → v1.0.3/0001-terraform-init-target}/migration.js +0 -0
@@ -650,7 +650,7 @@ RUN apt-get update && \\
650
650
  rm -rf /var/lib/apt/lists/*
651
651
 
652
652
  # Upgrade npm to a version free of known HIGH/CRITICAL vulnerabilities
653
- RUN npm install -g npm@12.0.2
653
+ RUN npm install -g npm@12.1.0
654
654
 
655
655
  WORKDIR /app
656
656
 
@@ -1666,7 +1666,7 @@ resource "null_resource" "runtime_ready" {
1666
1666
 
1667
1667
  provisioner "local-exec" {
1668
1668
  command = <<-EOT
1669
- uv run --with boto3==1.43.98 python -c "
1669
+ uv run --with boto3==1.43.103 python -c "
1670
1670
  import boto3
1671
1671
  import json
1672
1672
  import os
@@ -514,7 +514,7 @@ resource "null_resource" "runtime_ready" {
514
514
 
515
515
  provisioner "local-exec" {
516
516
  command = <<-EOT
517
- uv run --with boto3==1.43.98 python -c "
517
+ uv run --with boto3==1.43.103 python -c "
518
518
  import boto3
519
519
  import json
520
520
  import os
@@ -4520,7 +4520,7 @@ exports[`ts#rdb generator > should generate the aurora shared construct 4`] = `
4520
4520
  "FROM public.ecr.aws/lambda/nodejs:24
4521
4521
 
4522
4522
  # Upgrade npm to a version free of known HIGH/CRITICAL vulnerabilities
4523
- RUN npm install -g npm@12.0.2
4523
+ RUN npm install -g npm@12.1.0
4524
4524
 
4525
4525
  # Patch OS packages beyond the base image's pinned release, and drop the
4526
4526
  # runtime's convenience copy of the AWS SDK (the handler bundle inlines its
@@ -745,7 +745,7 @@ resource "null_resource" "upload_website_files" {
745
745
  provisioner "local-exec" {
746
746
  command = <<-EOT
747
747
  cd "$ROOT_PATH"
748
- uv run --with boto3==1.43.98 python3 -c "
748
+ uv run --with boto3==1.43.103 python3 -c "
749
749
  import os
750
750
  import sys
751
751
  import boto3
@@ -868,7 +868,7 @@ resource "null_resource" "cloudfront_invalidation" {
868
868
 
869
869
  provisioner "local-exec" {
870
870
  command = <<-EOT
871
- uv run --with boto3==1.43.98 python3 -c "
871
+ uv run --with boto3==1.43.103 python3 -c "
872
872
  import boto3
873
873
  import os
874
874
  import sys
@@ -2325,18 +2325,18 @@ exports[`react-website generator > Tanstack router integration > should generate
2325
2325
  - test-app
2326
2326
  - packages/common/*
2327
2327
  catalog:
2328
- '@types/node': 26.6.2
2329
- vite: 8.3.0
2328
+ '@types/node': 26.6.3
2329
+ vite: 8.3.1
2330
2330
  vitest: 4.1.11
2331
2331
  '@vitest/coverage-v8': 4.1.11
2332
2332
  jsdom: 29.1.1
2333
2333
  '@nx/vitest': 23.2.1
2334
2334
  constructs: 10.8.1
2335
- aws-cdk-lib: 2.270.0
2335
+ aws-cdk-lib: 2.271.0
2336
2336
  react: 19.3.0
2337
2337
  react-dom: 19.3.0
2338
- '@cloudscape-design/components': 3.0.1382
2339
- '@cloudscape-design/board-components': 3.0.232
2338
+ '@cloudscape-design/components': 3.0.1387
2339
+ '@cloudscape-design/board-components': 3.0.234
2340
2340
  '@cloudscape-design/global-styles': 1.0.70
2341
2341
  tailwindcss: 4.3.3
2342
2342
  '@nx/react': 23.2.1
@@ -4205,21 +4205,21 @@ exports[`react-website generator > Tanstack router integration > should generate
4205
4205
  - test-app
4206
4206
  - packages/common/*
4207
4207
  catalog:
4208
- '@types/node': 26.6.2
4209
- vite: 8.3.0
4208
+ '@types/node': 26.6.3
4209
+ vite: 8.3.1
4210
4210
  vitest: 4.1.11
4211
4211
  '@vitest/coverage-v8': 4.1.11
4212
4212
  jsdom: 29.1.1
4213
4213
  '@nx/vitest': 23.2.1
4214
4214
  constructs: 10.8.1
4215
- aws-cdk-lib: 2.270.0
4215
+ aws-cdk-lib: 2.271.0
4216
4216
  react: 19.3.0
4217
4217
  react-dom: 19.3.0
4218
- '@cloudscape-design/components': 3.0.1382
4219
- '@cloudscape-design/board-components': 3.0.232
4218
+ '@cloudscape-design/components': 3.0.1387
4219
+ '@cloudscape-design/board-components': 3.0.234
4220
4220
  '@cloudscape-design/global-styles': 1.0.70
4221
4221
  tailwindcss: 4.3.3
4222
- '@tanstack/react-router': 1.170.38
4222
+ '@tanstack/react-router': 1.170.39
4223
4223
  '@nx/react': 23.2.1
4224
4224
  '@vitest/ui': 4.1.11
4225
4225
  '@tailwindcss/vite': 4.3.3
@@ -67,7 +67,7 @@ resource "null_resource" "add_callback_url" {
67
67
 
68
68
  provisioner "local-exec" {
69
69
  command = <<-EOT
70
- uv run --with boto3==1.43.98 python -c "
70
+ uv run --with boto3==1.43.103 python -c "
71
71
  import boto3
72
72
  import os
73
73
  import sys
@@ -7,10 +7,12 @@ import {
7
7
  } from './utils<% if (esm) { %>.js<% } %>';
8
8
  import { CfnOutput, Stack } from 'aws-cdk-lib';
9
9
  import {
10
+ DomainMappingOptions,
10
11
  HttpApi as _HttpApi,
11
12
  HttpApiProps as _HttpApiProps,
12
13
  HttpMethod,
13
14
  HttpStage,
15
+ IDomainName,
14
16
  LogGroupLogDestination,
15
17
  ThrottleSettings,
16
18
  } from 'aws-cdk-lib/aws-apigatewayv2';
@@ -28,7 +30,7 @@ import { suppressRules } from '../checkov<% if (esm) { %>.js<% } %>';
28
30
  export interface HttpApiProps<
29
31
  TIntegrations extends ApiIntegrations<TOperation, HttpApiIntegration>,
30
32
  TOperation extends string,
31
- > extends _HttpApiProps {
33
+ > extends Omit<_HttpApiProps, 'defaultDomainMapping'> {
32
34
  /**
33
35
  * Unique name for the API, used in runtime configuration
34
36
  */
@@ -47,6 +49,12 @@ export interface HttpApiProps<
47
49
  * @default { rateLimit: 10000, burstLimit: 5000 }
48
50
  */
49
51
  readonly throttle?: ThrottleSettings;
52
+ /**
53
+ * Custom domain mapped to the API's default stage
54
+ */
55
+ readonly defaultDomainMapping?: DomainMappingOptions & {
56
+ readonly domainName: IDomainName;
57
+ };
50
58
  }
51
59
 
52
60
  /**
@@ -70,6 +78,9 @@ export class HttpApi<
70
78
  /** Default auto-deployed stage */
71
79
  public readonly defaultStage: HttpStage;
72
80
 
81
+ /** The URL clients call: the custom domain's if one is mapped, otherwise the stage's */
82
+ private readonly apiUrl: string;
83
+
73
84
  /** Map of operation names to their API Gateway integrations */
74
85
  public readonly integrations: TIntegrations;
75
86
 
@@ -81,6 +92,7 @@ export class HttpApi<
81
92
  operations,
82
93
  integrations,
83
94
  throttle = { rateLimit: 10000, burstLimit: 5000 },
95
+ defaultDomainMapping,
84
96
  ...props
85
97
  }: HttpApiProps<TIntegrations, TOperation>,
86
98
  ) {
@@ -113,12 +125,16 @@ export class HttpApi<
113
125
 
114
126
  this.defaultStage = new HttpStage(this, 'DefaultStage', {
115
127
  httpApi: this.api,
128
+ domainMapping: defaultDomainMapping,
116
129
  autoDeploy: true,
117
130
  throttle,
118
131
  accessLogSettings: {
119
132
  destination: new LogGroupLogDestination(accessLogGroup),
120
133
  },
121
134
  });
135
+ this.apiUrl = defaultDomainMapping
136
+ ? this.defaultStage.domainUrl
137
+ : this.defaultStage.url!;
122
138
 
123
139
  // Resolve the integration for a given operation.
124
140
  // If the operation has a dedicated integration, use it; otherwise fall back to $router.
@@ -151,21 +167,35 @@ export class HttpApi<
151
167
  );
152
168
 
153
169
  new CfnOutput(this, `${apiName}Url`, {
154
- value: this.defaultStage.url!,
170
+ value: this.apiUrl,
155
171
  });
156
172
 
157
173
  // Register the API URL in runtime configuration for client discovery
158
174
  const rc = RuntimeConfig.ensure(this);
159
175
  rc.set('connection', 'apis', {
160
176
  ...rc.get('connection').apis,
161
- [apiName]: this.defaultStage.url!,
177
+ [apiName]: this.apiUrl,
162
178
  });
179
+
180
+ // Target for the custom domain's DNS record
181
+ if (defaultDomainMapping) {
182
+ new CfnOutput(this, `${apiName}DomainNameAlias`, {
183
+ value: defaultDomainMapping.domainName.regionalDomainName,
184
+ description:
185
+ 'Regional domain name to point a CNAME record at for the custom domain, with any DNS provider',
186
+ });
187
+ new CfnOutput(this, `${apiName}DomainNameAliasHostedZoneId`, {
188
+ value: defaultDomainMapping.domainName.regionalHostedZoneId,
189
+ description:
190
+ 'Hosted zone ID of the regional domain name, needed only for a Route 53 alias record',
191
+ });
192
+ }
163
193
  }
164
194
 
165
195
  /**
166
196
  * Return the API url
167
197
  */
168
198
  public get url() {
169
- return this.defaultStage.url;
199
+ return this.apiUrl;
170
200
  }
171
201
  }
@@ -10,7 +10,7 @@ import {
10
10
  Stage,
11
11
  ThrottleSettings,
12
12
  } from 'aws-cdk-lib/aws-apigateway';
13
- import { IAspect, RemovalPolicy, Stack } from 'aws-cdk-lib';
13
+ import { CfnOutput, IAspect, RemovalPolicy, Stack } from 'aws-cdk-lib';
14
14
  import {
15
15
  CfnLoggingConfiguration,
16
16
  CfnWebACL,
@@ -99,6 +99,7 @@ export class RestApi<
99
99
  integrations,
100
100
  enableWaf = true,
101
101
  throttle = { rateLimit: 10000, burstLimit: 5000 },
102
+ domainName,
102
103
  ...props
103
104
  }: RestApiProps<TIntegrations, TOperation>,
104
105
  ) {
@@ -124,6 +125,7 @@ export class RestApi<
124
125
  // Create the API Gateway REST API
125
126
  this.api = new _RestApi(this, 'Api', {
126
127
  ...props,
128
+ domainName,
127
129
  deployOptions: {
128
130
  accessLogDestination: new LogGroupLogDestination(accessLogs),
129
131
  accessLogFormat: AccessLogFormat.jsonWithStandardFields(),
@@ -265,8 +267,24 @@ export class RestApi<
265
267
  const rc = RuntimeConfig.ensure(this);
266
268
  rc.set('connection', 'apis', {
267
269
  ...rc.get('connection').apis,
268
- [apiName]: this.api.url!,
270
+ [apiName]: domainName
271
+ ? `https://${domainName.domainName}/${domainName.basePath ? `${domainName.basePath}/` : ''}`
272
+ : this.api.url!,
269
273
  });
274
+
275
+ // Target for the custom domain's DNS record
276
+ if (domainName) {
277
+ new CfnOutput(this, `${apiName}DomainNameAlias`, {
278
+ value: this.api.domainName!.domainNameAliasDomainName,
279
+ description:
280
+ 'Domain name of the API Gateway endpoint (regional or edge) to point a CNAME record at for the custom domain, with any DNS provider',
281
+ });
282
+ new CfnOutput(this, `${apiName}DomainNameAliasHostedZoneId`, {
283
+ value: this.api.domainName!.domainNameAliasHostedZoneId,
284
+ description:
285
+ 'Hosted zone ID of that domain name, needed only for a Route 53 alias record',
286
+ });
287
+ }
270
288
  }
271
289
 
272
290
  /**
@@ -125,6 +125,19 @@ variable "tags" {
125
125
  default = {}
126
126
  }
127
127
 
128
+ # Custom domain configuration
129
+ variable "custom_domain_name" {
130
+ description = "Custom domain name for the API. Requires acm_certificate_arn."
131
+ type = string
132
+ default = null
133
+ }
134
+
135
+ variable "acm_certificate_arn" {
136
+ description = "ARN of an ACM certificate (in the API's region) for the custom domain name."
137
+ type = string
138
+ default = null
139
+ }
140
+
128
141
  # Get current AWS region and account ID
129
142
  data "aws_region" "current" {}
130
143
  data "aws_caller_identity" "current" {}
@@ -431,6 +444,10 @@ locals {
431
444
  <%_ } _%>
432
445
  }
433
446
 
447
+ locals {
448
+ api_url = var.custom_domain_name == null ? module.http_api.stage_invoke_url : "https://${var.custom_domain_name}/"
449
+ }
450
+
434
451
  # CloudWatch Log Group for Lambda
435
452
  resource "aws_cloudwatch_log_group" "lambda_logs" {
436
453
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -674,11 +691,41 @@ module "add_url_to_runtime_config" {
674
691
 
675
692
  namespace = "connection"
676
693
  key = "apis"
677
- value = { "<%- apiNameClassName %>" = module.http_api.stage_invoke_url }
694
+ value = { "<%- apiNameClassName %>" = local.api_url }
678
695
 
679
696
  depends_on = [module.http_api]
680
697
  }
681
698
 
699
+ # Custom domain for the API
700
+ resource "aws_apigatewayv2_domain_name" "custom_domain" {
701
+ count = var.custom_domain_name == null ? 0 : 1
702
+
703
+ domain_name = var.custom_domain_name
704
+
705
+ domain_name_configuration {
706
+ certificate_arn = var.acm_certificate_arn
707
+ endpoint_type = "REGIONAL"
708
+ security_policy = "TLS_1_2"
709
+ }
710
+
711
+ tags = var.tags
712
+
713
+ lifecycle {
714
+ precondition {
715
+ condition = var.acm_certificate_arn != null
716
+ error_message = "acm_certificate_arn is required when custom_domain_name is set."
717
+ }
718
+ }
719
+ }
720
+
721
+ resource "aws_apigatewayv2_api_mapping" "custom_domain" {
722
+ count = var.custom_domain_name == null ? 0 : 1
723
+
724
+ api_id = module.http_api.api_id
725
+ stage = module.http_api.stage_id
726
+ domain_name = aws_apigatewayv2_domain_name.custom_domain[0].domain_name
727
+ }
728
+
682
729
  # Lambda permission for API Gateway to invoke the function<% if (backend.type === 'fastapi') { %> via alias<% } %>
683
730
  resource "aws_lambda_permission" "api_gateway_invoke" {
684
731
  <%_ if (backend.integrationPattern === 'isolated') { _%>
@@ -738,6 +785,21 @@ output "stage_invoke_url" {
738
785
  value = module.http_api.stage_invoke_url
739
786
  }
740
787
 
788
+ output "api_url" {
789
+ description = "URL clients should call: the custom domain if configured, otherwise the stage invoke URL"
790
+ value = local.api_url
791
+ }
792
+
793
+ output "custom_domain_target_domain_name" {
794
+ description = "Target domain name to point a DNS alias or CNAME record at for the custom domain"
795
+ value = var.custom_domain_name == null ? null : aws_apigatewayv2_domain_name.custom_domain[0].domain_name_configuration[0].target_domain_name
796
+ }
797
+
798
+ output "custom_domain_hosted_zone_id" {
799
+ description = "Hosted zone ID to use for a Route 53 alias record for the custom domain"
800
+ value = var.custom_domain_name == null ? null : aws_apigatewayv2_domain_name.custom_domain[0].domain_name_configuration[0].hosted_zone_id
801
+ }
802
+
741
803
  output "stage_arn" {
742
804
  description = "ARN of the API Gateway stage"
743
805
  value = module.http_api.stage_arn
@@ -121,6 +121,19 @@ variable "tags" {
121
121
  default = {}
122
122
  }
123
123
 
124
+ # Custom domain configuration
125
+ variable "custom_domain_name" {
126
+ description = "Custom domain name for the API. Requires acm_certificate_arn."
127
+ type = string
128
+ default = null
129
+ }
130
+
131
+ variable "acm_certificate_arn" {
132
+ description = "ARN of an ACM certificate (in the API's region) for the custom domain name."
133
+ type = string
134
+ default = null
135
+ }
136
+
124
137
  # Get current AWS region and account ID
125
138
  data "aws_region" "current" {}
126
139
  data "aws_caller_identity" "current" {}
@@ -485,6 +498,10 @@ locals {
485
498
  <%_ } _%>
486
499
  }
487
500
 
501
+ locals {
502
+ api_url = var.custom_domain_name == null ? "${aws_api_gateway_stage.api_stage.invoke_url}/" : "https://${var.custom_domain_name}/"
503
+ }
504
+
488
505
  # CloudWatch Log Group for Lambda
489
506
  resource "aws_cloudwatch_log_group" "lambda_logs" {
490
507
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -1139,11 +1156,41 @@ module "add_url_to_runtime_config" {
1139
1156
 
1140
1157
  namespace = "connection"
1141
1158
  key = "apis"
1142
- value = { "<%- apiNameClassName %>" = "${aws_api_gateway_stage.api_stage.invoke_url}/" }
1159
+ value = { "<%- apiNameClassName %>" = local.api_url }
1143
1160
 
1144
1161
  depends_on = [aws_api_gateway_stage.api_stage]
1145
1162
  }
1146
1163
 
1164
+ # Custom domain for the API, served without the stage path prefix
1165
+ resource "aws_api_gateway_domain_name" "custom_domain" {
1166
+ count = var.custom_domain_name == null ? 0 : 1
1167
+
1168
+ domain_name = var.custom_domain_name
1169
+ regional_certificate_arn = var.acm_certificate_arn
1170
+ security_policy = "TLS_1_2"
1171
+
1172
+ endpoint_configuration {
1173
+ types = ["REGIONAL"]
1174
+ }
1175
+
1176
+ tags = var.tags
1177
+
1178
+ lifecycle {
1179
+ precondition {
1180
+ condition = var.acm_certificate_arn != null
1181
+ error_message = "acm_certificate_arn is required when custom_domain_name is set."
1182
+ }
1183
+ }
1184
+ }
1185
+
1186
+ resource "aws_api_gateway_base_path_mapping" "custom_domain" {
1187
+ count = var.custom_domain_name == null ? 0 : 1
1188
+
1189
+ api_id = module.rest_api.api_id
1190
+ stage_name = aws_api_gateway_stage.api_stage.stage_name
1191
+ domain_name = aws_api_gateway_domain_name.custom_domain[0].domain_name
1192
+ }
1193
+
1147
1194
  # Outputs
1148
1195
 
1149
1196
  # API Gateway Outputs (from core module)
@@ -1172,6 +1219,21 @@ output "stage_invoke_url" {
1172
1219
  value = aws_api_gateway_stage.api_stage.invoke_url
1173
1220
  }
1174
1221
 
1222
+ output "api_url" {
1223
+ description = "URL clients should call: the custom domain if configured, otherwise the stage invoke URL"
1224
+ value = local.api_url
1225
+ }
1226
+
1227
+ output "custom_domain_target_domain_name" {
1228
+ description = "Target domain name to point a DNS alias or CNAME record at for the custom domain"
1229
+ value = var.custom_domain_name == null ? null : aws_api_gateway_domain_name.custom_domain[0].regional_domain_name
1230
+ }
1231
+
1232
+ output "custom_domain_hosted_zone_id" {
1233
+ description = "Hosted zone ID to use for a Route 53 alias record for the custom domain"
1234
+ value = var.custom_domain_name == null ? null : aws_api_gateway_domain_name.custom_domain[0].regional_zone_id
1235
+ }
1236
+
1175
1237
  output "stage_arn" {
1176
1238
  description = "ARN of the API Gateway stage"
1177
1239
  value = aws_api_gateway_stage.api_stage.arn
@@ -25,7 +25,7 @@ export declare const IMAGE_BUILD_CACHE = false;
25
25
  * version to install globally, and the versions its dependency overrides pin.
26
26
  */
27
27
  export declare const nodeImageVersions: () => {
28
- npmVersion: "12.0.2";
28
+ npmVersion: "12.1.0";
29
29
  minimatchVersion: "10.2.6";
30
30
  };
31
31
  /**