@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.
Files changed (74) hide show
  1. package/LICENSE-THIRD-PARTY +716 -570
  2. package/generators.json +34 -0
  3. package/package.json +8 -8
  4. package/src/connection/generator.d.ts +1 -1
  5. package/src/connection/generator.js +19 -0
  6. package/src/connection/generator.js.map +1 -1
  7. package/src/infra/app/__snapshots__/generator.spec.ts.snap +17 -17
  8. package/src/preset/__snapshots__/generator.spec.ts.snap +73 -3
  9. package/src/preset/generator.d.ts +1 -1
  10. package/src/preset/generator.js +5 -1
  11. package/src/preset/generator.js.map +1 -1
  12. package/src/preset/schema.d.ts +1 -0
  13. package/src/preset/schema.json +5 -0
  14. package/src/py/agent/__snapshots__/generator.spec.ts.snap +6 -6
  15. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +3 -3
  16. package/src/smithy/project/__snapshots__/generator.spec.ts.snap +2 -0
  17. package/src/smithy/project/files/build.Dockerfile.template +1 -0
  18. package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +1502 -0
  19. package/src/ts/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +45 -0
  20. package/src/ts/dynamodb/agent-connection/generator.d.ts +10 -0
  21. package/src/ts/dynamodb/agent-connection/generator.js +32 -0
  22. package/src/ts/dynamodb/agent-connection/generator.js.map +1 -0
  23. package/src/ts/dynamodb/agent-connection/schema.d.ts +14 -0
  24. package/src/ts/dynamodb/agent-connection/schema.json +22 -0
  25. package/src/ts/dynamodb/files/scripts/create-local-table.ts.template +161 -0
  26. package/src/ts/dynamodb/files/scripts/pull-image.ts.template +15 -0
  27. package/src/ts/dynamodb/files/scripts/start-container.ts.template +81 -0
  28. package/src/ts/dynamodb/files/src/client.ts.template +45 -0
  29. package/src/ts/dynamodb/files/src/constants.ts.template +9 -0
  30. package/src/ts/dynamodb/files/src/entities/example.ts.template +47 -0
  31. package/src/ts/dynamodb/files/src/entities/index.ts.template +1 -0
  32. package/src/ts/dynamodb/files/src/gsi.ts.template +14 -0
  33. package/src/ts/dynamodb/files/src/index.ts.template +11 -0
  34. package/src/ts/dynamodb/generator.d.ts +10 -0
  35. package/src/ts/dynamodb/generator.js +108 -0
  36. package/src/ts/dynamodb/generator.js.map +1 -0
  37. package/src/ts/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +45 -0
  38. package/src/ts/dynamodb/mcp-server-connection/generator.d.ts +10 -0
  39. package/src/ts/dynamodb/mcp-server-connection/generator.js +32 -0
  40. package/src/ts/dynamodb/mcp-server-connection/generator.js.map +1 -0
  41. package/src/ts/dynamodb/mcp-server-connection/schema.d.ts +14 -0
  42. package/src/ts/dynamodb/mcp-server-connection/schema.json +22 -0
  43. package/src/ts/dynamodb/schema.d.ts +14 -0
  44. package/src/ts/dynamodb/schema.json +52 -0
  45. package/src/ts/dynamodb/smithy-connection/__snapshots__/generator.spec.ts.snap +23 -0
  46. package/src/ts/dynamodb/smithy-connection/generator.d.ts +10 -0
  47. package/src/ts/dynamodb/smithy-connection/generator.js +30 -0
  48. package/src/ts/dynamodb/smithy-connection/generator.js.map +1 -0
  49. package/src/ts/dynamodb/smithy-connection/schema.d.ts +12 -0
  50. package/src/ts/dynamodb/smithy-connection/schema.json +18 -0
  51. package/src/ts/dynamodb/trpc-connection/__snapshots__/generator.spec.ts.snap +23 -0
  52. package/src/ts/dynamodb/trpc-connection/generator.d.ts +10 -0
  53. package/src/ts/dynamodb/trpc-connection/generator.js +30 -0
  54. package/src/ts/dynamodb/trpc-connection/generator.js.map +1 -0
  55. package/src/ts/dynamodb/trpc-connection/schema.d.ts +12 -0
  56. package/src/ts/dynamodb/trpc-connection/schema.json +18 -0
  57. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +3 -3
  58. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +32 -32
  59. package/src/utils/dynamodb-constructs/dynamodb-constructs.d.ts +18 -0
  60. package/src/utils/dynamodb-constructs/dynamodb-constructs.js +57 -0
  61. package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -0
  62. package/src/utils/dynamodb-constructs/files/cdk/app/dynamodb/__nameKebabCase__.ts.template +30 -0
  63. package/src/utils/dynamodb-constructs/files/cdk/core/dynamodb.ts.template +105 -0
  64. package/src/utils/dynamodb-constructs/files/terraform/app/dynamodb/__nameKebabCase__/__nameKebabCase__.tf.template +65 -0
  65. package/src/utils/dynamodb-constructs/files/terraform/core/dynamodb/dynamodb.tf.template +155 -0
  66. package/src/utils/mcp.d.ts +25 -0
  67. package/src/utils/mcp.js +81 -0
  68. package/src/utils/mcp.js.map +1 -0
  69. package/src/utils/port.d.ts +6 -0
  70. package/src/utils/port.js +23 -2
  71. package/src/utils/port.js.map +1 -1
  72. package/src/utils/versions.d.ts +52 -52
  73. package/src/utils/versions.js +51 -51
  74. 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;
@@ -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"}
@@ -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 && typeof metadata.ports === 'object' && Array.isArray(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;
@@ -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,CAAC,IAAU,EAAE,OAA6B,EAAE,SAAiB,EAAE,EAAE;IACzF,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACrE,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,IAAI,QAAQ,EAAE,KAAK,IAAI,OAAO,QAAQ,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3F,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC,CAAC;IAEJ,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;AA7BW,QAAA,UAAU,cA6BrB"}
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"}