@aws/nx-plugin 1.0.0-rc.2 → 1.0.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-THIRD-PARTY +716 -570
- package/generators.json +34 -0
- package/package.json +8 -8
- package/src/connection/generator.d.ts +1 -1
- package/src/connection/generator.js +19 -0
- package/src/connection/generator.js.map +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +17 -17
- package/src/preset/__snapshots__/generator.spec.ts.snap +73 -3
- package/src/preset/generator.d.ts +1 -1
- package/src/preset/generator.js +5 -1
- package/src/preset/generator.js.map +1 -1
- package/src/preset/schema.d.ts +1 -0
- package/src/preset/schema.json +5 -0
- package/src/py/agent/__snapshots__/generator.spec.ts.snap +6 -6
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/smithy/project/__snapshots__/generator.spec.ts.snap +2 -0
- package/src/smithy/project/files/build.Dockerfile.template +1 -0
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +1502 -0
- package/src/ts/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +45 -0
- package/src/ts/dynamodb/agent-connection/generator.d.ts +10 -0
- package/src/ts/dynamodb/agent-connection/generator.js +32 -0
- package/src/ts/dynamodb/agent-connection/generator.js.map +1 -0
- package/src/ts/dynamodb/agent-connection/schema.d.ts +14 -0
- package/src/ts/dynamodb/agent-connection/schema.json +22 -0
- package/src/ts/dynamodb/files/scripts/create-local-table.ts.template +161 -0
- package/src/ts/dynamodb/files/scripts/pull-image.ts.template +15 -0
- package/src/ts/dynamodb/files/scripts/start-container.ts.template +81 -0
- package/src/ts/dynamodb/files/src/client.ts.template +45 -0
- package/src/ts/dynamodb/files/src/constants.ts.template +9 -0
- package/src/ts/dynamodb/files/src/entities/example.ts.template +47 -0
- package/src/ts/dynamodb/files/src/entities/index.ts.template +1 -0
- package/src/ts/dynamodb/files/src/gsi.ts.template +14 -0
- package/src/ts/dynamodb/files/src/index.ts.template +11 -0
- package/src/ts/dynamodb/generator.d.ts +10 -0
- package/src/ts/dynamodb/generator.js +108 -0
- package/src/ts/dynamodb/generator.js.map +1 -0
- package/src/ts/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +45 -0
- package/src/ts/dynamodb/mcp-server-connection/generator.d.ts +10 -0
- package/src/ts/dynamodb/mcp-server-connection/generator.js +32 -0
- package/src/ts/dynamodb/mcp-server-connection/generator.js.map +1 -0
- package/src/ts/dynamodb/mcp-server-connection/schema.d.ts +14 -0
- package/src/ts/dynamodb/mcp-server-connection/schema.json +22 -0
- package/src/ts/dynamodb/schema.d.ts +14 -0
- package/src/ts/dynamodb/schema.json +52 -0
- package/src/ts/dynamodb/smithy-connection/__snapshots__/generator.spec.ts.snap +23 -0
- package/src/ts/dynamodb/smithy-connection/generator.d.ts +10 -0
- package/src/ts/dynamodb/smithy-connection/generator.js +30 -0
- package/src/ts/dynamodb/smithy-connection/generator.js.map +1 -0
- package/src/ts/dynamodb/smithy-connection/schema.d.ts +12 -0
- package/src/ts/dynamodb/smithy-connection/schema.json +18 -0
- package/src/ts/dynamodb/trpc-connection/__snapshots__/generator.spec.ts.snap +23 -0
- package/src/ts/dynamodb/trpc-connection/generator.d.ts +10 -0
- package/src/ts/dynamodb/trpc-connection/generator.js +30 -0
- package/src/ts/dynamodb/trpc-connection/generator.js.map +1 -0
- package/src/ts/dynamodb/trpc-connection/schema.d.ts +12 -0
- package/src/ts/dynamodb/trpc-connection/schema.json +18 -0
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +32 -32
- package/src/utils/dynamodb-constructs/dynamodb-constructs.d.ts +18 -0
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js +57 -0
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -0
- package/src/utils/dynamodb-constructs/files/cdk/app/dynamodb/__nameKebabCase__.ts.template +30 -0
- package/src/utils/dynamodb-constructs/files/cdk/core/dynamodb.ts.template +105 -0
- package/src/utils/dynamodb-constructs/files/terraform/app/dynamodb/__nameKebabCase__/__nameKebabCase__.tf.template +65 -0
- package/src/utils/dynamodb-constructs/files/terraform/core/dynamodb/dynamodb.tf.template +155 -0
- package/src/utils/mcp.d.ts +25 -0
- package/src/utils/mcp.js +81 -0
- package/src/utils/mcp.js.map +1 -0
- package/src/utils/port.d.ts +6 -0
- package/src/utils/port.js +23 -2
- package/src/utils/port.js.map +1 -1
- package/src/utils/versions.d.ts +52 -52
- package/src/utils/versions.js +51 -51
- package/src/utils/versions.js.map +1 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Construct } from 'constructs';
|
|
2
|
+
import { PACKAGE_NAME, GLOBAL_SECONDARY_INDEXES } from '<%= dynamoPackageAlias %>';
|
|
3
|
+
import { AttributeType, ProjectionType } from 'aws-cdk-lib/aws-dynamodb';
|
|
4
|
+
import {
|
|
5
|
+
DynamoDBTable,
|
|
6
|
+
DynamoDBTableProps,
|
|
7
|
+
} from '../../core/dynamodb.js';
|
|
8
|
+
|
|
9
|
+
export type <%= nameClassName %>Props = Omit<
|
|
10
|
+
DynamoDBTableProps,
|
|
11
|
+
'runtimeConfigKey'
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export class <%= nameClassName %> extends DynamoDBTable {
|
|
15
|
+
constructor(scope: Construct, id: string, props?: <%= nameClassName %>Props) {
|
|
16
|
+
super(scope, id, {
|
|
17
|
+
...props,
|
|
18
|
+
runtimeConfigKey: PACKAGE_NAME,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
for (const gsi of GLOBAL_SECONDARY_INDEXES) {
|
|
22
|
+
this.table.addGlobalSecondaryIndex({
|
|
23
|
+
indexName: gsi.indexName,
|
|
24
|
+
partitionKey: { name: gsi.partitionKey, type: AttributeType.STRING },
|
|
25
|
+
sortKey: { name: gsi.sortKey, type: AttributeType.STRING },
|
|
26
|
+
projectionType: ProjectionType.ALL,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Construct } from 'constructs';
|
|
2
|
+
import {
|
|
3
|
+
AttributeType,
|
|
4
|
+
BillingMode,
|
|
5
|
+
Table,
|
|
6
|
+
TableEncryption,
|
|
7
|
+
TableProps,
|
|
8
|
+
} from 'aws-cdk-lib/aws-dynamodb';
|
|
9
|
+
import { RemovalPolicy } from 'aws-cdk-lib';
|
|
10
|
+
import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam';
|
|
11
|
+
import { Key } from 'aws-cdk-lib/aws-kms';
|
|
12
|
+
import { RuntimeConfig } from './runtime-config.js';
|
|
13
|
+
|
|
14
|
+
type _DynamoDBTableProps = Omit<TableProps, 'tableName' | 'partitionKey' | 'sortKey' | 'encryption' | 'encryptionKey'>;
|
|
15
|
+
|
|
16
|
+
export interface DynamoDBTableProps extends _DynamoDBTableProps {
|
|
17
|
+
/**
|
|
18
|
+
* The DynamoDB table name. If omitted, CDK auto-generates a unique name
|
|
19
|
+
* from the stack name and construct path.
|
|
20
|
+
*/
|
|
21
|
+
readonly tableName?: string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* RuntimeConfig key used under the `dynamodb` namespace.
|
|
25
|
+
*/
|
|
26
|
+
readonly runtimeConfigKey: string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Whether to enable automatic key rotation on the KMS key used to encrypt the table.
|
|
30
|
+
*
|
|
31
|
+
* @default true
|
|
32
|
+
*/
|
|
33
|
+
readonly enableKeyRotation?: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export abstract class DynamoDBTable extends Construct {
|
|
37
|
+
public readonly table: Table;
|
|
38
|
+
|
|
39
|
+
constructor(
|
|
40
|
+
scope: Construct,
|
|
41
|
+
id: string,
|
|
42
|
+
{
|
|
43
|
+
tableName,
|
|
44
|
+
runtimeConfigKey,
|
|
45
|
+
billingMode = BillingMode.PAY_PER_REQUEST,
|
|
46
|
+
pointInTimeRecoverySpecification = { pointInTimeRecoveryEnabled: true },
|
|
47
|
+
deletionProtection = true,
|
|
48
|
+
removalPolicy = RemovalPolicy.RETAIN,
|
|
49
|
+
enableKeyRotation = true,
|
|
50
|
+
...rest
|
|
51
|
+
}: DynamoDBTableProps,
|
|
52
|
+
) {
|
|
53
|
+
super(scope, id);
|
|
54
|
+
|
|
55
|
+
const key = new Key(this, 'EncryptionKey', { enableKeyRotation });
|
|
56
|
+
|
|
57
|
+
this.table = new Table(this, runtimeConfigKey, {
|
|
58
|
+
...rest,
|
|
59
|
+
...(tableName !== undefined && { tableName }),
|
|
60
|
+
partitionKey: { name: 'pk', type: AttributeType.STRING },
|
|
61
|
+
sortKey: { name: 'sk', type: AttributeType.STRING },
|
|
62
|
+
billingMode,
|
|
63
|
+
pointInTimeRecoverySpecification,
|
|
64
|
+
deletionProtection,
|
|
65
|
+
encryptionKey: key,
|
|
66
|
+
encryption: TableEncryption.CUSTOMER_MANAGED,
|
|
67
|
+
removalPolicy,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const rc = RuntimeConfig.ensure(this);
|
|
71
|
+
rc.set('dynamodb', runtimeConfigKey, { tableName: this.table.tableName });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public grantReadData(grantee: IGrantable): Grant {
|
|
75
|
+
return this.table.grantReadData(grantee);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public grantWriteData(grantee: IGrantable): Grant {
|
|
79
|
+
return this.table.grantWriteData(grantee);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public grantReadWriteData(grantee: IGrantable): Grant {
|
|
83
|
+
return this.table.grantReadWriteData(grantee);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public grantFullAccess(grantee: IGrantable): Grant {
|
|
87
|
+
return this.table.grantFullAccess(grantee);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public grantStreamRead(grantee: IGrantable): Grant {
|
|
91
|
+
return this.table.grantStreamRead(grantee);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public grantTableListStreams(grantee: IGrantable): Grant {
|
|
95
|
+
return this.table.grantTableListStreams(grantee);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public grant(grantee: IGrantable, ...actions: string[]): Grant {
|
|
99
|
+
return this.table.grant(grantee, ...actions);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public grantStream(grantee: IGrantable, ...actions: string[]): Grant {
|
|
103
|
+
return this.table.grantStream(grantee, ...actions);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
terraform {
|
|
2
|
+
required_providers {
|
|
3
|
+
aws = {
|
|
4
|
+
source = "hashicorp/aws"
|
|
5
|
+
version = "~> 6.0"
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
variable "billing_mode" {
|
|
11
|
+
description = "Controls how you are charged for read and write throughput."
|
|
12
|
+
type = string
|
|
13
|
+
default = "PAY_PER_REQUEST"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
variable "point_in_time_recovery_enabled" {
|
|
17
|
+
description = "Whether to enable point-in-time recovery for the table."
|
|
18
|
+
type = bool
|
|
19
|
+
default = true
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
variable "deletion_protection_enabled" {
|
|
23
|
+
description = "Whether to enable deletion protection on the table."
|
|
24
|
+
type = bool
|
|
25
|
+
default = true
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
variable "enable_key_rotation" {
|
|
29
|
+
description = "Whether to enable automatic key rotation on the KMS key used to encrypt the table."
|
|
30
|
+
type = bool
|
|
31
|
+
default = true
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module "dynamodb_table" {
|
|
35
|
+
source = "../../../core/dynamodb"
|
|
36
|
+
name = "<%= tableName %>"
|
|
37
|
+
billing_mode = var.billing_mode
|
|
38
|
+
point_in_time_recovery_enabled = var.point_in_time_recovery_enabled
|
|
39
|
+
deletion_protection_enabled = var.deletion_protection_enabled
|
|
40
|
+
enable_key_rotation = var.enable_key_rotation
|
|
41
|
+
global_secondary_indexes = [
|
|
42
|
+
{
|
|
43
|
+
name = "gsi1pk-gsi1sk-index"
|
|
44
|
+
hash_key = "gsi1pk"
|
|
45
|
+
range_key = "gsi1sk"
|
|
46
|
+
projection_type = "ALL"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name = "gsi2pk-gsi2sk-index"
|
|
50
|
+
hash_key = "gsi2pk"
|
|
51
|
+
range_key = "gsi2sk"
|
|
52
|
+
projection_type = "ALL"
|
|
53
|
+
},
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module "add_to_runtime_config" {
|
|
58
|
+
source = "../../../core/runtime-config/entry"
|
|
59
|
+
|
|
60
|
+
namespace = "dynamodb"
|
|
61
|
+
key = "<%= nameClassName %>"
|
|
62
|
+
value = {
|
|
63
|
+
tableName = module.dynamodb_table.table_name
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
terraform {
|
|
2
|
+
required_version = ">= 1.0"
|
|
3
|
+
|
|
4
|
+
required_providers {
|
|
5
|
+
aws = {
|
|
6
|
+
source = "hashicorp/aws"
|
|
7
|
+
version = "~> 6.0"
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
variable "name" {
|
|
13
|
+
description = "Name for the DynamoDB table."
|
|
14
|
+
type = string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
variable "billing_mode" {
|
|
18
|
+
description = "Controls how you are charged for read and write throughput."
|
|
19
|
+
type = string
|
|
20
|
+
default = "PAY_PER_REQUEST"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
variable "point_in_time_recovery_enabled" {
|
|
24
|
+
description = "Whether to enable point-in-time recovery for the table."
|
|
25
|
+
type = bool
|
|
26
|
+
default = true
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
variable "deletion_protection_enabled" {
|
|
30
|
+
description = "Whether to enable deletion protection on the table."
|
|
31
|
+
type = bool
|
|
32
|
+
default = true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
variable "enable_key_rotation" {
|
|
36
|
+
description = "Whether to enable automatic key rotation on the KMS key used to encrypt the table."
|
|
37
|
+
type = bool
|
|
38
|
+
default = true
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
variable "global_secondary_indexes" {
|
|
42
|
+
description = "Global secondary indexes to create on the table. All key attributes must be of type string."
|
|
43
|
+
type = list(object({
|
|
44
|
+
name = string
|
|
45
|
+
hash_key = string
|
|
46
|
+
range_key = string
|
|
47
|
+
projection_type = string
|
|
48
|
+
}))
|
|
49
|
+
default = []
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
locals {
|
|
53
|
+
gsi_attribute_names = distinct(flatten([
|
|
54
|
+
for gsi in var.global_secondary_indexes : [gsi.hash_key, gsi.range_key]
|
|
55
|
+
]))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
data "aws_caller_identity" "current" {}
|
|
59
|
+
data "aws_partition" "current" {}
|
|
60
|
+
|
|
61
|
+
resource "aws_kms_key" "table" {
|
|
62
|
+
description = "KMS key for DynamoDB table ${var.name}"
|
|
63
|
+
enable_key_rotation = var.enable_key_rotation
|
|
64
|
+
|
|
65
|
+
policy = jsonencode({
|
|
66
|
+
Version = "2012-10-17"
|
|
67
|
+
Statement = [
|
|
68
|
+
{
|
|
69
|
+
Sid = "EnableRootAccess"
|
|
70
|
+
Effect = "Allow"
|
|
71
|
+
Principal = {
|
|
72
|
+
AWS = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:root"
|
|
73
|
+
}
|
|
74
|
+
Action = "kms:*"
|
|
75
|
+
Resource = "*"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
Sid = "AllowDynamoDBService"
|
|
79
|
+
Effect = "Allow"
|
|
80
|
+
Principal = {
|
|
81
|
+
Service = "dynamodb.amazonaws.com"
|
|
82
|
+
}
|
|
83
|
+
Action = [
|
|
84
|
+
"kms:Encrypt",
|
|
85
|
+
"kms:Decrypt",
|
|
86
|
+
"kms:ReEncrypt*",
|
|
87
|
+
"kms:GenerateDataKey*",
|
|
88
|
+
"kms:DescribeKey",
|
|
89
|
+
"kms:CreateGrant"
|
|
90
|
+
]
|
|
91
|
+
Resource = "*"
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
resource "aws_dynamodb_table" "table" {
|
|
98
|
+
name = var.name
|
|
99
|
+
billing_mode = var.billing_mode
|
|
100
|
+
hash_key = "pk"
|
|
101
|
+
range_key = "sk"
|
|
102
|
+
deletion_protection_enabled = var.deletion_protection_enabled
|
|
103
|
+
|
|
104
|
+
attribute {
|
|
105
|
+
name = "pk"
|
|
106
|
+
type = "S"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
attribute {
|
|
110
|
+
name = "sk"
|
|
111
|
+
type = "S"
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
dynamic "attribute" {
|
|
115
|
+
for_each = toset(local.gsi_attribute_names)
|
|
116
|
+
content {
|
|
117
|
+
name = attribute.value
|
|
118
|
+
type = "S"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
dynamic "global_secondary_index" {
|
|
123
|
+
for_each = var.global_secondary_indexes
|
|
124
|
+
content {
|
|
125
|
+
name = global_secondary_index.value.name
|
|
126
|
+
hash_key = global_secondary_index.value.hash_key
|
|
127
|
+
range_key = global_secondary_index.value.range_key
|
|
128
|
+
projection_type = global_secondary_index.value.projection_type
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
point_in_time_recovery {
|
|
133
|
+
enabled = var.point_in_time_recovery_enabled
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
server_side_encryption {
|
|
137
|
+
enabled = true
|
|
138
|
+
kms_key_arn = aws_kms_key.table.arn
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
output "table_name" {
|
|
143
|
+
description = "Name of the DynamoDB table."
|
|
144
|
+
value = aws_dynamodb_table.table.name
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
output "table_arn" {
|
|
148
|
+
description = "ARN of the DynamoDB table."
|
|
149
|
+
value = aws_dynamodb_table.table.arn
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
output "kms_key_arn" {
|
|
153
|
+
description = "ARN of the KMS key used to encrypt the DynamoDB table."
|
|
154
|
+
value = aws_kms_key.table.arn
|
|
155
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
/**
|
|
7
|
+
* Name of the Nx Plugin for AWS MCP server, used as the key in each agent's config.
|
|
8
|
+
*/
|
|
9
|
+
export declare const NX_PLUGIN_MCP_SERVER_NAME = "nx-plugin-for-aws";
|
|
10
|
+
/**
|
|
11
|
+
* Command used to launch the Nx Plugin for AWS MCP server.
|
|
12
|
+
*/
|
|
13
|
+
export declare const NX_PLUGIN_MCP_SERVER_COMMAND = "npx";
|
|
14
|
+
/**
|
|
15
|
+
* Arguments used to launch the Nx Plugin for AWS MCP server.
|
|
16
|
+
*/
|
|
17
|
+
export declare const NX_PLUGIN_MCP_SERVER_ARGS: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Configure the Nx Plugin for AWS MCP server across the project-level config locations
|
|
20
|
+
* used by common coding agents, so agents working in the workspace can use it to scaffold
|
|
21
|
+
* AWS projects with the Nx Plugin for AWS.
|
|
22
|
+
*
|
|
23
|
+
* Existing servers and unrelated config in each file are preserved.
|
|
24
|
+
*/
|
|
25
|
+
export declare const configureMcpServers: (tree: Tree) => void;
|
package/src/utils/mcp.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureMcpServers = exports.NX_PLUGIN_MCP_SERVER_ARGS = exports.NX_PLUGIN_MCP_SERVER_COMMAND = exports.NX_PLUGIN_MCP_SERVER_NAME = 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 toml_1 = require("./toml");
|
|
10
|
+
/**
|
|
11
|
+
* Name of the Nx Plugin for AWS MCP server, used as the key in each agent's config.
|
|
12
|
+
*/
|
|
13
|
+
exports.NX_PLUGIN_MCP_SERVER_NAME = 'nx-plugin-for-aws';
|
|
14
|
+
/**
|
|
15
|
+
* Command used to launch the Nx Plugin for AWS MCP server.
|
|
16
|
+
*/
|
|
17
|
+
exports.NX_PLUGIN_MCP_SERVER_COMMAND = 'npx';
|
|
18
|
+
/**
|
|
19
|
+
* Arguments used to launch the Nx Plugin for AWS MCP server.
|
|
20
|
+
*/
|
|
21
|
+
exports.NX_PLUGIN_MCP_SERVER_ARGS = ['-y', '@aws/nx-plugin-mcp@next'];
|
|
22
|
+
/**
|
|
23
|
+
* A single stdio MCP server entry, shared by agents that use the `mcpServers` config shape.
|
|
24
|
+
*/
|
|
25
|
+
const stdioServerEntry = () => ({
|
|
26
|
+
command: exports.NX_PLUGIN_MCP_SERVER_COMMAND,
|
|
27
|
+
args: exports.NX_PLUGIN_MCP_SERVER_ARGS,
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* Merge the Nx Plugin for AWS MCP server into a JSON config file under the given key,
|
|
31
|
+
* preserving any other servers already configured. Creates the file if it does not exist.
|
|
32
|
+
*/
|
|
33
|
+
const mergeJsonMcpConfig = (tree, filePath, key, entry) => {
|
|
34
|
+
const config = tree.exists(filePath) ? (0, devkit_1.readJson)(tree, filePath) : {};
|
|
35
|
+
config[key] = {
|
|
36
|
+
...config[key],
|
|
37
|
+
[exports.NX_PLUGIN_MCP_SERVER_NAME]: entry,
|
|
38
|
+
};
|
|
39
|
+
(0, devkit_1.writeJson)(tree, filePath, config);
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Configure the Nx Plugin for AWS MCP server across the project-level config locations
|
|
43
|
+
* used by common coding agents, so agents working in the workspace can use it to scaffold
|
|
44
|
+
* AWS projects with the Nx Plugin for AWS.
|
|
45
|
+
*
|
|
46
|
+
* Existing servers and unrelated config in each file are preserved.
|
|
47
|
+
*/
|
|
48
|
+
const configureMcpServers = (tree) => {
|
|
49
|
+
// Agents using the `mcpServers` config shape (Claude Code, Cursor, Kiro, Gemini CLI)
|
|
50
|
+
const mcpServersFiles = [
|
|
51
|
+
'.mcp.json', // Claude Code
|
|
52
|
+
'.cursor/mcp.json', // Cursor
|
|
53
|
+
'.kiro/settings/mcp.json', // Kiro
|
|
54
|
+
'.gemini/settings.json', // Gemini CLI
|
|
55
|
+
];
|
|
56
|
+
for (const filePath of mcpServersFiles) {
|
|
57
|
+
mergeJsonMcpConfig(tree, filePath, 'mcpServers', stdioServerEntry());
|
|
58
|
+
}
|
|
59
|
+
// GitHub Copilot uses the `servers` key with an explicit `type`
|
|
60
|
+
mergeJsonMcpConfig(tree, '.vscode/mcp.json', 'servers', {
|
|
61
|
+
type: 'stdio',
|
|
62
|
+
...stdioServerEntry(),
|
|
63
|
+
});
|
|
64
|
+
// OpenAI Codex CLI uses TOML under the `mcp_servers` table
|
|
65
|
+
const codexConfig = '.codex/config.toml';
|
|
66
|
+
if (!tree.exists(codexConfig)) {
|
|
67
|
+
tree.write(codexConfig, '');
|
|
68
|
+
}
|
|
69
|
+
(0, toml_1.updateToml)(tree, codexConfig, (prev) => ({
|
|
70
|
+
...prev,
|
|
71
|
+
mcp_servers: {
|
|
72
|
+
...prev.mcp_servers,
|
|
73
|
+
[exports.NX_PLUGIN_MCP_SERVER_NAME]: {
|
|
74
|
+
command: exports.NX_PLUGIN_MCP_SERVER_COMMAND,
|
|
75
|
+
args: exports.NX_PLUGIN_MCP_SERVER_ARGS,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
}));
|
|
79
|
+
};
|
|
80
|
+
exports.configureMcpServers = configureMcpServers;
|
|
81
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../../../packages/nx-plugin/src/utils/mcp.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,uCAAuD;AACvD,iCAAoC;AAEpC;;GAEG;AACU,QAAA,yBAAyB,GAAG,mBAAmB,CAAC;AAE7D;;GAEG;AACU,QAAA,4BAA4B,GAAG,KAAK,CAAC;AAElD;;GAEG;AACU,QAAA,yBAAyB,GAAG,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAAC;AAE3E;;GAEG;AACH,MAAM,gBAAgB,GAAG,GAAG,EAAE,CAAC,CAAC;IAC9B,OAAO,EAAE,oCAA4B;IACrC,IAAI,EAAE,iCAAyB;CAChC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,kBAAkB,GAAG,CACzB,IAAU,EACV,QAAgB,EAChB,GAA6B,EAC7B,KAA8B,EAC9B,EAAE;IACF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAA,iBAAQ,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,MAAM,CAAC,GAAG,CAAC,GAAG;QACZ,GAAG,MAAM,CAAC,GAAG,CAAC;QACd,CAAC,iCAAyB,CAAC,EAAE,KAAK;KACnC,CAAC;IACF,IAAA,kBAAS,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF;;;;;;GAMG;AACI,MAAM,mBAAmB,GAAG,CAAC,IAAU,EAAE,EAAE;IAChD,qFAAqF;IACrF,MAAM,eAAe,GAAG;QACtB,WAAW,EAAE,cAAc;QAC3B,kBAAkB,EAAE,SAAS;QAC7B,yBAAyB,EAAE,OAAO;QAClC,uBAAuB,EAAE,aAAa;KACvC,CAAC;IACF,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;QACvC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,gEAAgE;IAChE,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,EAAE,SAAS,EAAE;QACtD,IAAI,EAAE,OAAO;QACb,GAAG,gBAAgB,EAAE;KACtB,CAAC,CAAC;IAEH,2DAA2D;IAC3D,MAAM,WAAW,GAAG,oBAAoB,CAAC;IACzC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC9B,CAAC;IACD,IAAA,iBAAU,EAAC,IAAI,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvC,GAAG,IAAI;QACP,WAAW,EAAE;YACX,GAAI,IAAI,CAAC,WAAsB;YAC/B,CAAC,iCAAyB,CAAC,EAAE;gBAC3B,OAAO,EAAE,oCAA4B;gBACrC,IAAI,EAAE,iCAAyB;aAChC;SACF;KACF,CAAC,CAAC,CAAC;AACN,CAAC,CAAC;AAjCW,QAAA,mBAAmB,uBAiC9B"}
|
package/src/utils/port.d.ts
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { ProjectConfiguration, Tree } from '@nx/devkit';
|
|
6
|
+
/**
|
|
7
|
+
* Assign a port shared across all projects created by the same generator.
|
|
8
|
+
* If a sibling project already has a port assigned, reuse it; otherwise assign a fresh one.
|
|
9
|
+
* Mutates the project to register the port in its metadata.ports.
|
|
10
|
+
*/
|
|
11
|
+
export declare const assignSharedPort: (tree: Tree, project: ProjectConfiguration, generatorId: string, startPort: number) => number;
|
|
6
12
|
/**
|
|
7
13
|
* Assign a port for a particular target within a project.
|
|
8
14
|
* Mutates the project to add/update its metadata.ports with the newly assigned port
|
package/src/utils/port.js
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.assignPort = void 0;
|
|
3
|
+
exports.assignPort = exports.assignSharedPort = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
6
6
|
* SPDX-License-Identifier: Apache-2.0
|
|
7
7
|
*/
|
|
8
8
|
const devkit_1 = require("@nx/devkit");
|
|
9
|
+
/**
|
|
10
|
+
* Assign a port shared across all projects created by the same generator.
|
|
11
|
+
* If a sibling project already has a port assigned, reuse it; otherwise assign a fresh one.
|
|
12
|
+
* Mutates the project to register the port in its metadata.ports.
|
|
13
|
+
*/
|
|
14
|
+
const assignSharedPort = (tree, project, generatorId, startPort) => {
|
|
15
|
+
const existingPort = [...(0, devkit_1.getProjects)(tree).values()].find((p) => p.metadata?.generator === generatorId)?.metadata;
|
|
16
|
+
if (existingPort?.ports?.[0] !== undefined) {
|
|
17
|
+
const port = existingPort.ports[0];
|
|
18
|
+
project.metadata ??= {};
|
|
19
|
+
project.metadata.ports = [
|
|
20
|
+
...(project.metadata.ports ?? []),
|
|
21
|
+
port,
|
|
22
|
+
];
|
|
23
|
+
return port;
|
|
24
|
+
}
|
|
25
|
+
return (0, exports.assignPort)(tree, project, startPort);
|
|
26
|
+
};
|
|
27
|
+
exports.assignSharedPort = assignSharedPort;
|
|
9
28
|
/**
|
|
10
29
|
* Assign a port for a particular target within a project.
|
|
11
30
|
* Mutates the project to add/update its metadata.ports with the newly assigned port
|
|
@@ -19,7 +38,9 @@ const assignPort = (tree, project, startPort) => {
|
|
|
19
38
|
if (metadata?.port && typeof metadata.port === 'number') {
|
|
20
39
|
ports.push(metadata.port);
|
|
21
40
|
}
|
|
22
|
-
if (metadata?.ports &&
|
|
41
|
+
if (metadata?.ports &&
|
|
42
|
+
typeof metadata.ports === 'object' &&
|
|
43
|
+
Array.isArray(metadata.ports)) {
|
|
23
44
|
ports.push(...metadata.ports);
|
|
24
45
|
}
|
|
25
46
|
return ports;
|
package/src/utils/port.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port.js","sourceRoot":"","sources":["../../../../../packages/nx-plugin/src/utils/port.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,uCAAqE;AAErE;;;GAGG;AACI,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"port.js","sourceRoot":"","sources":["../../../../../packages/nx-plugin/src/utils/port.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,uCAAqE;AAErE;;;;GAIG;AACI,MAAM,gBAAgB,GAAG,CAC9B,IAAU,EACV,OAA6B,EAC7B,WAAmB,EACnB,SAAiB,EACT,EAAE;IACV,MAAM,YAAY,GAAG,CAAC,GAAG,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CACvD,CAAC,CAAC,EAAE,EAAE,CAAE,CAAC,CAAC,QAAgB,EAAE,SAAS,KAAK,WAAW,CACtD,EAAE,QAAe,CAAC;IAEnB,IAAI,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC;QAC7C,OAAO,CAAC,QAAQ,KAAK,EAAE,CAAC;QACvB,OAAO,CAAC,QAAgB,CAAC,KAAK,GAAG;YAChC,GAAG,CAAE,OAAO,CAAC,QAAgB,CAAC,KAAK,IAAI,EAAE,CAAC;YAC1C,IAAI;SACL,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAA,kBAAU,EAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC,CAAC;AArBW,QAAA,gBAAgB,oBAqB3B;AAEF;;;GAGG;AACI,MAAM,UAAU,GAAG,CACxB,IAAU,EACV,OAA6B,EAC7B,SAAiB,EACjB,EAAE;IACF,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,CAAC,GAAG,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5C,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAe,CAAC;QACnC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,0EAA0E;QAC1E,IAAI,QAAQ,EAAE,IAAI,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,IACE,QAAQ,EAAE,KAAK;YACf,OAAO,QAAQ,CAAC,KAAK,KAAK,QAAQ;YAClC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAC7B,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CACH,CAAC;IAEF,0DAA0D;IAC1D,IAAI,aAAa,GAAG,SAAS,CAAC;IAC9B,OAAO,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QACnC,aAAa,EAAE,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,QAAQ,KAAK,EAAE,CAAC;IACvB,OAAO,CAAC,QAAgB,CAAC,KAAK,KAAK,EAAE,CAAC;IACtC,OAAO,CAAC,QAAgB,CAAC,KAAK,GAAG;QAChC,GAAI,OAAO,CAAC,QAAgB,CAAC,KAAK;QAClC,aAAa;KACd,CAAC;IAEF,OAAO,aAAa,CAAC;AACvB,CAAC,CAAC;AAvCW,QAAA,UAAU,cAuCrB"}
|