@aws/nx-plugin 1.0.0-rc.10 → 1.0.0-rc.12
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/generators.json +31 -1
- package/package.json +1 -1
- package/sdk/agentcore-gateway.d.ts +6 -0
- package/sdk/agentcore-gateway.js +11 -0
- package/sdk/agentcore-gateway.js.map +1 -0
- package/sdk/license.d.ts +4 -4
- package/sdk/license.js +5 -4
- package/sdk/license.js.map +1 -1
- package/sdk/py.d.ts +6 -6
- package/sdk/py.js +7 -7
- package/sdk/py.js.map +1 -1
- package/sdk/ts.d.ts +18 -14
- package/sdk/ts.js +38 -32
- package/sdk/ts.js.map +1 -1
- package/src/agentcore-gateway/files/cedar/policies/README.md +52 -0
- package/src/agentcore-gateway/files/cedar/policies/permit-all.cedar +11 -0
- package/src/agentcore-gateway/files/project/serve-local.ts.template +133 -0
- package/src/agentcore-gateway/generator.d.ts +25 -0
- package/src/agentcore-gateway/generator.js +129 -0
- package/src/agentcore-gateway/generator.js.map +1 -0
- package/src/agentcore-gateway/mcp-connection/generator.d.ts +19 -0
- package/src/agentcore-gateway/mcp-connection/generator.js +79 -0
- package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -0
- package/src/agentcore-gateway/mcp-connection/schema.d.ts +12 -0
- package/src/agentcore-gateway/mcp-connection/schema.json +26 -0
- package/src/agentcore-gateway/schema.d.ts +16 -0
- package/src/agentcore-gateway/schema.json +65 -0
- package/src/connection/generator.d.ts +1 -1
- package/src/connection/generator.js +64 -46
- package/src/connection/generator.js.map +1 -1
- package/src/mcp-server/schema-registry.d.ts +9 -3
- package/src/mcp-server/schema-registry.js +22 -6
- package/src/mcp-server/schema-registry.js.map +1 -1
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -0
- package/src/py/agent/__snapshots__/generator.spec.ts.snap +55 -2
- package/src/py/agent/a2a-connection/files/agent-connection/app/__targetAgentSnakeCase___client.py.template +9 -3
- package/src/py/agent/a2a-connection/generator.js +1 -1
- package/src/py/agent/a2a-connection/generator.js.map +1 -1
- package/src/py/agent/gateway-connection/files/agent-connection/app/__gatewaySnakeCase___client.py.template +35 -0
- package/src/py/agent/gateway-connection/generator.d.ts +10 -0
- package/src/py/agent/gateway-connection/generator.js +106 -0
- package/src/py/agent/gateway-connection/generator.js.map +1 -0
- package/src/py/agent/gateway-connection/schema.d.ts +12 -0
- package/src/py/agent/gateway-connection/schema.json +26 -0
- package/src/py/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +8 -4
- package/src/py/agent/mcp-connection/files/agent-connection/app/__mcpServerSnakeCase___client.py.template +9 -3
- package/src/py/agent/mcp-connection/generator.js +2 -72
- package/src/py/agent/mcp-connection/generator.js.map +1 -1
- package/src/py/agent/react-connection/__snapshots__/generator.spec.ts.snap +7 -16
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +57 -2
- package/src/smithy/ts/api/generator.js +1 -1
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +55 -2
- package/src/ts/agent/a2a-connection/files/agent-connection/app/__targetAgentKebabCase__-client.ts.template +10 -6
- package/src/ts/agent/gateway-connection/files/agent-connection/app/__gatewayKebabCase__-client.ts.template +30 -0
- package/src/ts/agent/gateway-connection/generator.d.ts +10 -0
- package/src/ts/agent/gateway-connection/generator.js +106 -0
- package/src/ts/agent/gateway-connection/generator.js.map +1 -0
- package/src/ts/agent/gateway-connection/schema.d.ts +12 -0
- package/src/ts/agent/gateway-connection/schema.json +26 -0
- package/src/ts/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +9 -4
- package/src/ts/agent/mcp-connection/files/agent-connection/app/__mcpServerKebabCase__-client.ts.template +9 -6
- package/src/ts/agent/mcp-connection/generator.js +1 -13
- package/src/ts/agent/mcp-connection/generator.js.map +1 -1
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +135 -76
- package/src/ts/dynamodb/files/dynamodb.config.json +14 -0
- package/src/ts/dynamodb/files/scripts/create-local-table.ts.template +14 -7
- package/src/ts/dynamodb/files/src/index.ts.template +0 -1
- package/src/ts/dynamodb/generator.js +3 -1
- package/src/ts/dynamodb/generator.js.map +1 -1
- package/src/ts/lib/grit/vitest-pass-with-no-tests.grit +1 -4
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +57 -2
- package/src/ts/nx-generator/generator.js +29 -0
- package/src/ts/nx-generator/generator.js.map +1 -1
- package/src/ts/react-website/agui/files/common/src/hooks/useAgui__agentNameClassName__.tsx.template +1 -16
- package/src/ts/react-website/agui/generator.js +0 -1
- package/src/ts/react-website/agui/generator.js.map +1 -1
- package/src/utils/agent-connection/agent-connection.d.ts +17 -0
- package/src/utils/agent-connection/agent-connection.js +94 -0
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-client.ts.template +78 -0
- package/src/utils/agent-connection/files/core-runtime-config/runtime-config.ts.template +22 -32
- package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_client.py.template +78 -0
- package/src/utils/agent-connection/files/py-core-runtime-config/runtime_config.py.template +5 -18
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +8 -0
- package/src/utils/agent-core-constructs/agent-core-constructs.js +54 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +4 -0
- package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +37 -0
- package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +293 -0
- package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/readiness-probe/index.js.template +55 -0
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +242 -0
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/render-cedar.cjs.template +13 -0
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +55 -2
- package/src/utils/agent-core-constructs/files/terraform/core/agentcore-gateway/gateway.tf.template +14 -0
- package/src/utils/dynamodb-constructs/dynamodb-constructs.d.ts +1 -0
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -1
- package/src/utils/dynamodb-constructs/files/cdk/app/dynamodb/__nameKebabCase__.ts.template +17 -3
- package/src/utils/dynamodb-constructs/files/terraform/app/dynamodb/__nameKebabCase__/__nameKebabCase__.tf.template +11 -14
- package/src/utils/versions.d.ts +7 -5
- package/src/utils/versions.js +6 -4
- package/src/utils/versions.js.map +1 -1
- package/src/ts/dynamodb/files/src/gsi.ts.template +0 -14
|
@@ -9,7 +9,20 @@ exports[`ts#dynamodb generator > should generate scripts for finch engine > pack
|
|
|
9
9
|
ResourceInUseException,
|
|
10
10
|
UpdateTableCommand,
|
|
11
11
|
} from '@aws-sdk/client-dynamodb';
|
|
12
|
-
import {
|
|
12
|
+
import { readFileSync } from 'fs';
|
|
13
|
+
import { join, dirname } from 'path';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
15
|
+
|
|
16
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const { globalSecondaryIndexes } = JSON.parse(
|
|
18
|
+
readFileSync(join(__dirname, '../dynamodb.config.json'), 'utf-8'),
|
|
19
|
+
) as {
|
|
20
|
+
globalSecondaryIndexes: {
|
|
21
|
+
indexName: string;
|
|
22
|
+
partitionKey: string;
|
|
23
|
+
sortKey?: string;
|
|
24
|
+
}[];
|
|
25
|
+
};
|
|
13
26
|
|
|
14
27
|
const [tableName, port] = process.argv.slice(2);
|
|
15
28
|
const endpoint = \`http://localhost:\${port}\`;
|
|
@@ -48,11 +61,13 @@ const waitForTableActive = async (
|
|
|
48
61
|
const ensureTable = async (
|
|
49
62
|
tblClient: DynamoDBClient,
|
|
50
63
|
tblName: string,
|
|
51
|
-
gsIs: { indexName: string; partitionKey: string; sortKey
|
|
64
|
+
gsIs: { indexName: string; partitionKey: string; sortKey?: string }[],
|
|
52
65
|
): Promise<void> => {
|
|
53
66
|
const gsiAttributeDefinitions = gsIs.flatMap((gsi) => [
|
|
54
67
|
{ AttributeName: gsi.partitionKey, AttributeType: 'S' as const },
|
|
55
|
-
|
|
68
|
+
...(gsi.sortKey
|
|
69
|
+
? [{ AttributeName: gsi.sortKey, AttributeType: 'S' as const }]
|
|
70
|
+
: []),
|
|
56
71
|
]);
|
|
57
72
|
const attributeDefinitions = [
|
|
58
73
|
{ AttributeName: 'pk', AttributeType: 'S' as const },
|
|
@@ -66,7 +81,9 @@ const ensureTable = async (
|
|
|
66
81
|
IndexName: gsi.indexName,
|
|
67
82
|
KeySchema: [
|
|
68
83
|
{ AttributeName: gsi.partitionKey, KeyType: 'HASH' as const },
|
|
69
|
-
|
|
84
|
+
...(gsi.sortKey
|
|
85
|
+
? [{ AttributeName: gsi.sortKey, KeyType: 'RANGE' as const }]
|
|
86
|
+
: []),
|
|
70
87
|
],
|
|
71
88
|
Projection: { ProjectionType: 'ALL' as const },
|
|
72
89
|
}));
|
|
@@ -133,7 +150,14 @@ const ensureTable = async (
|
|
|
133
150
|
TableName: tblName,
|
|
134
151
|
AttributeDefinitions: [
|
|
135
152
|
{ AttributeName: gsi.partitionKey, AttributeType: 'S' },
|
|
136
|
-
|
|
153
|
+
...(gsi.sortKey
|
|
154
|
+
? [
|
|
155
|
+
{
|
|
156
|
+
AttributeName: gsi.sortKey,
|
|
157
|
+
AttributeType: 'S' as const,
|
|
158
|
+
},
|
|
159
|
+
]
|
|
160
|
+
: []),
|
|
137
161
|
],
|
|
138
162
|
GlobalSecondaryIndexUpdates: [
|
|
139
163
|
{
|
|
@@ -141,7 +165,9 @@ const ensureTable = async (
|
|
|
141
165
|
IndexName: gsi.indexName,
|
|
142
166
|
KeySchema: [
|
|
143
167
|
{ AttributeName: gsi.partitionKey, KeyType: 'HASH' },
|
|
144
|
-
|
|
168
|
+
...(gsi.sortKey
|
|
169
|
+
? [{ AttributeName: gsi.sortKey, KeyType: 'RANGE' }]
|
|
170
|
+
: []),
|
|
145
171
|
],
|
|
146
172
|
Projection: { ProjectionType: 'ALL' },
|
|
147
173
|
},
|
|
@@ -161,7 +187,7 @@ const ensureTable = async (
|
|
|
161
187
|
}
|
|
162
188
|
};
|
|
163
189
|
|
|
164
|
-
await ensureTable(client, tableName,
|
|
190
|
+
await ensureTable(client, tableName, globalSecondaryIndexes);
|
|
165
191
|
"
|
|
166
192
|
`;
|
|
167
193
|
|
|
@@ -458,6 +484,16 @@ variable "enable_key_rotation" {
|
|
|
458
484
|
default = true
|
|
459
485
|
}
|
|
460
486
|
|
|
487
|
+
locals {
|
|
488
|
+
dynamodb_config = jsondecode(file("\${path.module}/../../../../../../../packages/my-table/dynamodb.config.json"))
|
|
489
|
+
global_secondary_indexes = [for gsi in local.dynamodb_config.globalSecondaryIndexes : {
|
|
490
|
+
name = gsi.indexName
|
|
491
|
+
hash_key = gsi.partitionKey
|
|
492
|
+
range_key = try(gsi.sortKey, null)
|
|
493
|
+
projection_type = "ALL"
|
|
494
|
+
}]
|
|
495
|
+
}
|
|
496
|
+
|
|
461
497
|
module "dynamodb_table" {
|
|
462
498
|
source = "../../../core/dynamodb"
|
|
463
499
|
name = "proj-my-table"
|
|
@@ -465,20 +501,7 @@ module "dynamodb_table" {
|
|
|
465
501
|
point_in_time_recovery_enabled = var.point_in_time_recovery_enabled
|
|
466
502
|
deletion_protection_enabled = var.deletion_protection_enabled
|
|
467
503
|
enable_key_rotation = var.enable_key_rotation
|
|
468
|
-
global_secondary_indexes
|
|
469
|
-
{
|
|
470
|
-
name = "gsi1pk-gsi1sk-index"
|
|
471
|
-
hash_key = "gsi1pk"
|
|
472
|
-
range_key = "gsi1sk"
|
|
473
|
-
projection_type = "ALL"
|
|
474
|
-
},
|
|
475
|
-
{
|
|
476
|
-
name = "gsi2pk-gsi2sk-index"
|
|
477
|
-
hash_key = "gsi2pk"
|
|
478
|
-
range_key = "gsi2sk"
|
|
479
|
-
projection_type = "ALL"
|
|
480
|
-
},
|
|
481
|
-
]
|
|
504
|
+
global_secondary_indexes = local.global_secondary_indexes
|
|
482
505
|
}
|
|
483
506
|
|
|
484
507
|
module "add_to_runtime_config" {
|
|
@@ -502,7 +525,20 @@ exports[`ts#dynamodb generator > should generate the dynamodb project > packages
|
|
|
502
525
|
ResourceInUseException,
|
|
503
526
|
UpdateTableCommand,
|
|
504
527
|
} from '@aws-sdk/client-dynamodb';
|
|
505
|
-
import {
|
|
528
|
+
import { readFileSync } from 'fs';
|
|
529
|
+
import { join, dirname } from 'path';
|
|
530
|
+
import { fileURLToPath } from 'url';
|
|
531
|
+
|
|
532
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
533
|
+
const { globalSecondaryIndexes } = JSON.parse(
|
|
534
|
+
readFileSync(join(__dirname, '../dynamodb.config.json'), 'utf-8'),
|
|
535
|
+
) as {
|
|
536
|
+
globalSecondaryIndexes: {
|
|
537
|
+
indexName: string;
|
|
538
|
+
partitionKey: string;
|
|
539
|
+
sortKey?: string;
|
|
540
|
+
}[];
|
|
541
|
+
};
|
|
506
542
|
|
|
507
543
|
const [tableName, port] = process.argv.slice(2);
|
|
508
544
|
const endpoint = \`http://localhost:\${port}\`;
|
|
@@ -541,11 +577,13 @@ const waitForTableActive = async (
|
|
|
541
577
|
const ensureTable = async (
|
|
542
578
|
tblClient: DynamoDBClient,
|
|
543
579
|
tblName: string,
|
|
544
|
-
gsIs: { indexName: string; partitionKey: string; sortKey
|
|
580
|
+
gsIs: { indexName: string; partitionKey: string; sortKey?: string }[],
|
|
545
581
|
): Promise<void> => {
|
|
546
582
|
const gsiAttributeDefinitions = gsIs.flatMap((gsi) => [
|
|
547
583
|
{ AttributeName: gsi.partitionKey, AttributeType: 'S' as const },
|
|
548
|
-
|
|
584
|
+
...(gsi.sortKey
|
|
585
|
+
? [{ AttributeName: gsi.sortKey, AttributeType: 'S' as const }]
|
|
586
|
+
: []),
|
|
549
587
|
]);
|
|
550
588
|
const attributeDefinitions = [
|
|
551
589
|
{ AttributeName: 'pk', AttributeType: 'S' as const },
|
|
@@ -559,7 +597,9 @@ const ensureTable = async (
|
|
|
559
597
|
IndexName: gsi.indexName,
|
|
560
598
|
KeySchema: [
|
|
561
599
|
{ AttributeName: gsi.partitionKey, KeyType: 'HASH' as const },
|
|
562
|
-
|
|
600
|
+
...(gsi.sortKey
|
|
601
|
+
? [{ AttributeName: gsi.sortKey, KeyType: 'RANGE' as const }]
|
|
602
|
+
: []),
|
|
563
603
|
],
|
|
564
604
|
Projection: { ProjectionType: 'ALL' as const },
|
|
565
605
|
}));
|
|
@@ -626,7 +666,14 @@ const ensureTable = async (
|
|
|
626
666
|
TableName: tblName,
|
|
627
667
|
AttributeDefinitions: [
|
|
628
668
|
{ AttributeName: gsi.partitionKey, AttributeType: 'S' },
|
|
629
|
-
|
|
669
|
+
...(gsi.sortKey
|
|
670
|
+
? [
|
|
671
|
+
{
|
|
672
|
+
AttributeName: gsi.sortKey,
|
|
673
|
+
AttributeType: 'S' as const,
|
|
674
|
+
},
|
|
675
|
+
]
|
|
676
|
+
: []),
|
|
630
677
|
],
|
|
631
678
|
GlobalSecondaryIndexUpdates: [
|
|
632
679
|
{
|
|
@@ -634,7 +681,9 @@ const ensureTable = async (
|
|
|
634
681
|
IndexName: gsi.indexName,
|
|
635
682
|
KeySchema: [
|
|
636
683
|
{ AttributeName: gsi.partitionKey, KeyType: 'HASH' },
|
|
637
|
-
|
|
684
|
+
...(gsi.sortKey
|
|
685
|
+
? [{ AttributeName: gsi.sortKey, KeyType: 'RANGE' }]
|
|
686
|
+
: []),
|
|
638
687
|
],
|
|
639
688
|
Projection: { ProjectionType: 'ALL' },
|
|
640
689
|
},
|
|
@@ -654,7 +703,7 @@ const ensureTable = async (
|
|
|
654
703
|
}
|
|
655
704
|
};
|
|
656
705
|
|
|
657
|
-
await ensureTable(client, tableName,
|
|
706
|
+
await ensureTable(client, tableName, globalSecondaryIndexes);
|
|
658
707
|
"
|
|
659
708
|
`;
|
|
660
709
|
|
|
@@ -889,24 +938,6 @@ exports[`ts#dynamodb generator > should generate the dynamodb project > packages
|
|
|
889
938
|
"
|
|
890
939
|
`;
|
|
891
940
|
|
|
892
|
-
exports[`ts#dynamodb generator > should generate the dynamodb project > packages/my-table/src/gsi.ts 1`] = `
|
|
893
|
-
"// GSIs to synchronize on the local table at startup and provision in infrastructure.
|
|
894
|
-
// ElectroDB names GSI keys gsi{n}pk / gsi{n}sk — add one entry per index defined in your entities.
|
|
895
|
-
export const GLOBAL_SECONDARY_INDEXES = [
|
|
896
|
-
{
|
|
897
|
-
indexName: 'gsi1pk-gsi1sk-index',
|
|
898
|
-
partitionKey: 'gsi1pk',
|
|
899
|
-
sortKey: 'gsi1sk',
|
|
900
|
-
},
|
|
901
|
-
{
|
|
902
|
-
indexName: 'gsi2pk-gsi2sk-index',
|
|
903
|
-
partitionKey: 'gsi2pk',
|
|
904
|
-
sortKey: 'gsi2sk',
|
|
905
|
-
},
|
|
906
|
-
];
|
|
907
|
-
"
|
|
908
|
-
`;
|
|
909
|
-
|
|
910
941
|
exports[`ts#dynamodb generator > should generate the dynamodb project > packages/my-table/src/index.ts 1`] = `
|
|
911
942
|
"export {
|
|
912
943
|
PACKAGE_NAME,
|
|
@@ -917,7 +948,6 @@ exports[`ts#dynamodb generator > should generate the dynamodb project > packages
|
|
|
917
948
|
LOCAL_TABLE_NAME,
|
|
918
949
|
} from './constants.js';
|
|
919
950
|
export { getDynamoDBClient, resolveTableName } from './client.js';
|
|
920
|
-
export { GLOBAL_SECONDARY_INDEXES } from './gsi.js';
|
|
921
951
|
export * from './entities/index.js';
|
|
922
952
|
"
|
|
923
953
|
`;
|
|
@@ -1036,9 +1066,13 @@ export abstract class DynamoDBTable extends Construct {
|
|
|
1036
1066
|
|
|
1037
1067
|
exports[`ts#dynamodb generator > should generate the dynamodb project 2`] = `
|
|
1038
1068
|
"import { Construct } from 'constructs';
|
|
1039
|
-
import { PACKAGE_NAME
|
|
1069
|
+
import { PACKAGE_NAME } from ':proj/my-table';
|
|
1040
1070
|
import { AttributeType, ProjectionType } from 'aws-cdk-lib/aws-dynamodb';
|
|
1041
1071
|
import { DynamoDBTable, DynamoDBTableProps } from '../../core/dynamodb.js';
|
|
1072
|
+
import { findWorkspaceRoot } from '../../core/workspace.js';
|
|
1073
|
+
import { readFileSync } from 'fs';
|
|
1074
|
+
import { join } from 'path';
|
|
1075
|
+
import { fileURLToPath } from 'url';
|
|
1042
1076
|
|
|
1043
1077
|
export type MyTableProps = Omit<DynamoDBTableProps, 'runtimeConfigKey'>;
|
|
1044
1078
|
|
|
@@ -1049,11 +1083,29 @@ export class MyTable extends DynamoDBTable {
|
|
|
1049
1083
|
runtimeConfigKey: PACKAGE_NAME,
|
|
1050
1084
|
});
|
|
1051
1085
|
|
|
1052
|
-
|
|
1086
|
+
const { globalSecondaryIndexes } = JSON.parse(
|
|
1087
|
+
readFileSync(
|
|
1088
|
+
join(
|
|
1089
|
+
findWorkspaceRoot(fileURLToPath(new URL(import.meta.url))),
|
|
1090
|
+
'packages/my-table/dynamodb.config.json',
|
|
1091
|
+
),
|
|
1092
|
+
'utf-8',
|
|
1093
|
+
),
|
|
1094
|
+
) as {
|
|
1095
|
+
globalSecondaryIndexes: {
|
|
1096
|
+
indexName: string;
|
|
1097
|
+
partitionKey: string;
|
|
1098
|
+
sortKey?: string;
|
|
1099
|
+
}[];
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
for (const gsi of globalSecondaryIndexes) {
|
|
1053
1103
|
this.table.addGlobalSecondaryIndex({
|
|
1054
1104
|
indexName: gsi.indexName,
|
|
1055
1105
|
partitionKey: { name: gsi.partitionKey, type: AttributeType.STRING },
|
|
1056
|
-
|
|
1106
|
+
...(gsi.sortKey && {
|
|
1107
|
+
sortKey: { name: gsi.sortKey, type: AttributeType.STRING },
|
|
1108
|
+
}),
|
|
1057
1109
|
projectionType: ProjectionType.ALL,
|
|
1058
1110
|
});
|
|
1059
1111
|
}
|
|
@@ -1081,7 +1133,20 @@ exports[`ts#dynamodb generator > should generate with infra=none then upgrade to
|
|
|
1081
1133
|
ResourceInUseException,
|
|
1082
1134
|
UpdateTableCommand,
|
|
1083
1135
|
} from '@aws-sdk/client-dynamodb';
|
|
1084
|
-
import {
|
|
1136
|
+
import { readFileSync } from 'fs';
|
|
1137
|
+
import { join, dirname } from 'path';
|
|
1138
|
+
import { fileURLToPath } from 'url';
|
|
1139
|
+
|
|
1140
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
1141
|
+
const { globalSecondaryIndexes } = JSON.parse(
|
|
1142
|
+
readFileSync(join(__dirname, '../dynamodb.config.json'), 'utf-8'),
|
|
1143
|
+
) as {
|
|
1144
|
+
globalSecondaryIndexes: {
|
|
1145
|
+
indexName: string;
|
|
1146
|
+
partitionKey: string;
|
|
1147
|
+
sortKey?: string;
|
|
1148
|
+
}[];
|
|
1149
|
+
};
|
|
1085
1150
|
|
|
1086
1151
|
const [tableName, port] = process.argv.slice(2);
|
|
1087
1152
|
const endpoint = \`http://localhost:\${port}\`;
|
|
@@ -1120,11 +1185,13 @@ const waitForTableActive = async (
|
|
|
1120
1185
|
const ensureTable = async (
|
|
1121
1186
|
tblClient: DynamoDBClient,
|
|
1122
1187
|
tblName: string,
|
|
1123
|
-
gsIs: { indexName: string; partitionKey: string; sortKey
|
|
1188
|
+
gsIs: { indexName: string; partitionKey: string; sortKey?: string }[],
|
|
1124
1189
|
): Promise<void> => {
|
|
1125
1190
|
const gsiAttributeDefinitions = gsIs.flatMap((gsi) => [
|
|
1126
1191
|
{ AttributeName: gsi.partitionKey, AttributeType: 'S' as const },
|
|
1127
|
-
|
|
1192
|
+
...(gsi.sortKey
|
|
1193
|
+
? [{ AttributeName: gsi.sortKey, AttributeType: 'S' as const }]
|
|
1194
|
+
: []),
|
|
1128
1195
|
]);
|
|
1129
1196
|
const attributeDefinitions = [
|
|
1130
1197
|
{ AttributeName: 'pk', AttributeType: 'S' as const },
|
|
@@ -1138,7 +1205,9 @@ const ensureTable = async (
|
|
|
1138
1205
|
IndexName: gsi.indexName,
|
|
1139
1206
|
KeySchema: [
|
|
1140
1207
|
{ AttributeName: gsi.partitionKey, KeyType: 'HASH' as const },
|
|
1141
|
-
|
|
1208
|
+
...(gsi.sortKey
|
|
1209
|
+
? [{ AttributeName: gsi.sortKey, KeyType: 'RANGE' as const }]
|
|
1210
|
+
: []),
|
|
1142
1211
|
],
|
|
1143
1212
|
Projection: { ProjectionType: 'ALL' as const },
|
|
1144
1213
|
}));
|
|
@@ -1205,7 +1274,14 @@ const ensureTable = async (
|
|
|
1205
1274
|
TableName: tblName,
|
|
1206
1275
|
AttributeDefinitions: [
|
|
1207
1276
|
{ AttributeName: gsi.partitionKey, AttributeType: 'S' },
|
|
1208
|
-
|
|
1277
|
+
...(gsi.sortKey
|
|
1278
|
+
? [
|
|
1279
|
+
{
|
|
1280
|
+
AttributeName: gsi.sortKey,
|
|
1281
|
+
AttributeType: 'S' as const,
|
|
1282
|
+
},
|
|
1283
|
+
]
|
|
1284
|
+
: []),
|
|
1209
1285
|
],
|
|
1210
1286
|
GlobalSecondaryIndexUpdates: [
|
|
1211
1287
|
{
|
|
@@ -1213,7 +1289,9 @@ const ensureTable = async (
|
|
|
1213
1289
|
IndexName: gsi.indexName,
|
|
1214
1290
|
KeySchema: [
|
|
1215
1291
|
{ AttributeName: gsi.partitionKey, KeyType: 'HASH' },
|
|
1216
|
-
|
|
1292
|
+
...(gsi.sortKey
|
|
1293
|
+
? [{ AttributeName: gsi.sortKey, KeyType: 'RANGE' }]
|
|
1294
|
+
: []),
|
|
1217
1295
|
],
|
|
1218
1296
|
Projection: { ProjectionType: 'ALL' },
|
|
1219
1297
|
},
|
|
@@ -1233,7 +1311,7 @@ const ensureTable = async (
|
|
|
1233
1311
|
}
|
|
1234
1312
|
};
|
|
1235
1313
|
|
|
1236
|
-
await ensureTable(client, tableName,
|
|
1314
|
+
await ensureTable(client, tableName, globalSecondaryIndexes);
|
|
1237
1315
|
"
|
|
1238
1316
|
`;
|
|
1239
1317
|
|
|
@@ -1468,24 +1546,6 @@ exports[`ts#dynamodb generator > should generate with infra=none then upgrade to
|
|
|
1468
1546
|
"
|
|
1469
1547
|
`;
|
|
1470
1548
|
|
|
1471
|
-
exports[`ts#dynamodb generator > should generate with infra=none then upgrade to infra=dynamodb > packages/my-table/src/gsi.ts 1`] = `
|
|
1472
|
-
"// GSIs to synchronize on the local table at startup and provision in infrastructure.
|
|
1473
|
-
// ElectroDB names GSI keys gsi{n}pk / gsi{n}sk — add one entry per index defined in your entities.
|
|
1474
|
-
export const GLOBAL_SECONDARY_INDEXES = [
|
|
1475
|
-
{
|
|
1476
|
-
indexName: 'gsi1pk-gsi1sk-index',
|
|
1477
|
-
partitionKey: 'gsi1pk',
|
|
1478
|
-
sortKey: 'gsi1sk',
|
|
1479
|
-
},
|
|
1480
|
-
{
|
|
1481
|
-
indexName: 'gsi2pk-gsi2sk-index',
|
|
1482
|
-
partitionKey: 'gsi2pk',
|
|
1483
|
-
sortKey: 'gsi2sk',
|
|
1484
|
-
},
|
|
1485
|
-
];
|
|
1486
|
-
"
|
|
1487
|
-
`;
|
|
1488
|
-
|
|
1489
1549
|
exports[`ts#dynamodb generator > should generate with infra=none then upgrade to infra=dynamodb > packages/my-table/src/index.ts 1`] = `
|
|
1490
1550
|
"export {
|
|
1491
1551
|
PACKAGE_NAME,
|
|
@@ -1496,7 +1556,6 @@ exports[`ts#dynamodb generator > should generate with infra=none then upgrade to
|
|
|
1496
1556
|
LOCAL_TABLE_NAME,
|
|
1497
1557
|
} from './constants.js';
|
|
1498
1558
|
export { getDynamoDBClient, resolveTableName } from './client.js';
|
|
1499
|
-
export { GLOBAL_SECONDARY_INDEXES } from './gsi.js';
|
|
1500
1559
|
export * from './entities/index.js';
|
|
1501
1560
|
"
|
|
1502
1561
|
`;
|
|
@@ -6,7 +6,14 @@ import {
|
|
|
6
6
|
ResourceInUseException,
|
|
7
7
|
UpdateTableCommand,
|
|
8
8
|
} from '@aws-sdk/client-dynamodb';
|
|
9
|
-
import {
|
|
9
|
+
import { readFileSync } from 'fs';
|
|
10
|
+
import { join, dirname } from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const { globalSecondaryIndexes } = JSON.parse(
|
|
15
|
+
readFileSync(join(__dirname, '../dynamodb.config.json'), 'utf-8'),
|
|
16
|
+
) as { globalSecondaryIndexes: { indexName: string; partitionKey: string; sortKey?: string }[] };
|
|
10
17
|
|
|
11
18
|
const [tableName, port] = process.argv.slice(2);
|
|
12
19
|
const endpoint = `http://localhost:${port}`;
|
|
@@ -45,11 +52,11 @@ const waitForTableActive = async (
|
|
|
45
52
|
const ensureTable = async (
|
|
46
53
|
tblClient: DynamoDBClient,
|
|
47
54
|
tblName: string,
|
|
48
|
-
gsIs: { indexName: string; partitionKey: string; sortKey
|
|
55
|
+
gsIs: { indexName: string; partitionKey: string; sortKey?: string }[],
|
|
49
56
|
): Promise<void> => {
|
|
50
57
|
const gsiAttributeDefinitions = gsIs.flatMap((gsi) => [
|
|
51
58
|
{ AttributeName: gsi.partitionKey, AttributeType: 'S' as const },
|
|
52
|
-
{ AttributeName: gsi.sortKey, AttributeType: 'S' as const },
|
|
59
|
+
...(gsi.sortKey ? [{ AttributeName: gsi.sortKey, AttributeType: 'S' as const }] : []),
|
|
53
60
|
]);
|
|
54
61
|
const attributeDefinitions = [
|
|
55
62
|
{ AttributeName: 'pk', AttributeType: 'S' as const },
|
|
@@ -63,7 +70,7 @@ const ensureTable = async (
|
|
|
63
70
|
IndexName: gsi.indexName,
|
|
64
71
|
KeySchema: [
|
|
65
72
|
{ AttributeName: gsi.partitionKey, KeyType: 'HASH' as const },
|
|
66
|
-
{ AttributeName: gsi.sortKey, KeyType: 'RANGE' as const },
|
|
73
|
+
...(gsi.sortKey ? [{ AttributeName: gsi.sortKey, KeyType: 'RANGE' as const }] : []),
|
|
67
74
|
],
|
|
68
75
|
Projection: { ProjectionType: 'ALL' as const },
|
|
69
76
|
}));
|
|
@@ -130,7 +137,7 @@ const ensureTable = async (
|
|
|
130
137
|
TableName: tblName,
|
|
131
138
|
AttributeDefinitions: [
|
|
132
139
|
{ AttributeName: gsi.partitionKey, AttributeType: 'S' },
|
|
133
|
-
{ AttributeName: gsi.sortKey, AttributeType: 'S' },
|
|
140
|
+
...(gsi.sortKey ? [{ AttributeName: gsi.sortKey, AttributeType: 'S' as const }] : []),
|
|
134
141
|
],
|
|
135
142
|
GlobalSecondaryIndexUpdates: [
|
|
136
143
|
{
|
|
@@ -138,7 +145,7 @@ const ensureTable = async (
|
|
|
138
145
|
IndexName: gsi.indexName,
|
|
139
146
|
KeySchema: [
|
|
140
147
|
{ AttributeName: gsi.partitionKey, KeyType: 'HASH' },
|
|
141
|
-
{ AttributeName: gsi.sortKey, KeyType: 'RANGE' },
|
|
148
|
+
...(gsi.sortKey ? [{ AttributeName: gsi.sortKey, KeyType: 'RANGE' }] : []),
|
|
142
149
|
],
|
|
143
150
|
Projection: { ProjectionType: 'ALL' },
|
|
144
151
|
},
|
|
@@ -158,4 +165,4 @@ const ensureTable = async (
|
|
|
158
165
|
}
|
|
159
166
|
};
|
|
160
167
|
|
|
161
|
-
await ensureTable(client, tableName,
|
|
168
|
+
await ensureTable(client, tableName, globalSecondaryIndexes);
|
|
@@ -88,13 +88,15 @@ const tsDynamoDBGenerator = async (tree, options) => {
|
|
|
88
88
|
nameKebabCase,
|
|
89
89
|
dynamoPackageAlias: (0, npm_scope_1.toScopeAlias)(fullyQualifiedName),
|
|
90
90
|
tableName: localTableName,
|
|
91
|
+
projectRoot: dir,
|
|
91
92
|
});
|
|
92
93
|
}
|
|
93
94
|
(0, devkit_1.addDependenciesToPackageJson)(tree, (0, versions_1.withVersions)([
|
|
94
95
|
'@aws-sdk/client-dynamodb',
|
|
95
96
|
'electrodb',
|
|
96
97
|
'@aws-lambda-powertools/parameters',
|
|
97
|
-
|
|
98
|
+
'@aws-sdk/client-appconfigdata',
|
|
99
|
+
]), (0, versions_1.withVersions)(['tsx', '@types/aws-lambda', '@types/node']));
|
|
98
100
|
await (0, metrics_1.addGeneratorMetricsIfApplicable)(tree, [exports.TS_DYNAMODB_GENERATOR_INFO]);
|
|
99
101
|
await (0, format_1.formatFilesInSubtree)(tree);
|
|
100
102
|
return () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/ts/dynamodb/generator.ts"],"names":[],"mappings":";;;;AAAA;;;GAGG;AACH,uCASoB;AACpB,uDAA2D;AAC3D,6FAAuF;AACvF,+CAA0D;AAC1D,yCAA6C;AAC7C,iDAAsE;AACtE,6CAA2D;AAC3D,qDAAkE;AAClE,uCAIwB;AACxB,2CAAoD;AACpD,qEAA0E;AAC1E,mDAAoD;AACpD,sEAAuE;AAG1D,QAAA,0BAA0B,GACrC,IAAA,qBAAgB,EAAC,UAAU,CAAC,CAAC;AAE/B,MAAM,oBAAoB,GACxB,6DAA6D,CAAC;AAEzD,MAAM,mBAAmB,GAAG,KAAK,EACtC,IAAU,EACV,OAAkC,EACN,EAAE;IAC9B,MAAM,aAAa,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAG,IAAA,mBAAW,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,GAAG,IAAA,uBAAW,EAAC,IAAI,CAAC,IAAI,IAAA,iBAAS,EAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IAC9F,MAAM,eAAe,GAAG,MAAM,IAAA,8BAAiB,EAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjE,MAAM,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG,IAAA,2BAAe,EAAC,IAAI,EAAE;QACxD,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;IAEH,IAAI,aAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,IAAA,iCAAwB,EAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;QACnD,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,aAAa,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAA,mBAAkB,EAAC,IAAI,EAAE;YAC7B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,aAAa,GAAG,IAAA,iCAAwB,EAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IAEzE,MAAM,eAAe,GAAG,IAAA,uBAAgB,EACtC,IAAI,EACJ,aAAa,EACb,kCAA0B,CAAC,EAAE,EAC7B,IAAI,CACL,CAAC;IAEF,MAAM,eAAe,GAAG;QACtB,gBAAgB,EAAE,aAAa;QAC/B,kBAAkB,EAAE,IAAA,wBAAY,EAAC,kBAAkB,CAAC;QACpD,eAAe;QACf,cAAc;QACd,eAAe;KAChB,CAAC;IAEF,IAAA,sBAAa,EACX,IAAI,EACJ,IAAA,0BAAiB,EAAC,SAAS,EAAE,OAAO,CAAC,EACrC,GAAG,EACH,eAAe,CAChB,CAAC;IAEF,MAAM,aAAa,GAAG,GAAG,IAAA,uBAAW,EAAC,IAAI,CAAC,WAAW,CAAC;IAEtD,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG;QACpC,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE;YACP,OAAO,EAAE,6BAA6B,oBAAoB,EAAE;YAC5D,GAAG,EAAE,eAAe;SACrB;KACF,CAAC;IACF,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG;QACrC,QAAQ,EAAE,iBAAiB;QAC3B,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,CAAC,YAAY,CAAC;QACzB,OAAO,EAAE;YACP,QAAQ,EAAE;gBACR,kCAAkC,aAAa,IAAI,oBAAoB,IAAI,eAAe,EAAE;gBAC5F,qCAAqC,cAAc,IAAI,eAAe,EAAE;aACzE;YACD,QAAQ,EAAE,IAAI;YACd,GAAG,EAAE,eAAe;SACrB;KACF,CAAC;IAEF,IAAA,mCAA0B,EAAC,IAAI,EAAE,kBAAkB,EAAE,aAAa,CAAC,CAAC;IACpE,IAAA,yBAAoB,EAAC,IAAI,EAAE,kBAAkB,EAAE,kCAA0B,CAAC,CAAC;IAE3E,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,MAAM,IAAA,gBAAU,EAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,MAAM,IAAA,6CAAyB,EAAC,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/C,MAAM,IAAA,sCAAgB,EAAC,IAAI,EAAE;YAC3B,GAAG;YACH,WAAW,EAAE,kBAAkB;YAC/B,aAAa;YACb,aAAa;YACb,kBAAkB,EAAE,IAAA,wBAAY,EAAC,kBAAkB,CAAC;YACpD,SAAS,EAAE,cAAc;
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/ts/dynamodb/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -44,6 +44,8 @@ export class SnapshotBedrockServer
|
|
|
44
44
|
{
|
|
45
45
|
public readonly dockerImage: AgentRuntimeArtifact;
|
|
46
46
|
public readonly agentCoreRuntime: Runtime;
|
|
47
|
+
/** Default Gateway target name for this MCP server. */
|
|
48
|
+
public readonly mcpServerName = 'snapshot-bedrock-server';
|
|
47
49
|
|
|
48
50
|
constructor(
|
|
49
51
|
scope: Construct,
|
|
@@ -464,6 +466,59 @@ resource "aws_bedrockagentcore_agent_runtime" "agent_runtime" {
|
|
|
464
466
|
]
|
|
465
467
|
}
|
|
466
468
|
|
|
469
|
+
# MCP consumers (e.g. gateway targets, which fetch tools at creation) can race
|
|
470
|
+
# the runtime's first cold start, so probe it until it serves MCP. The ARN
|
|
471
|
+
# output is routed through this resource so consumers wait for readiness.
|
|
472
|
+
resource "null_resource" "runtime_ready" {
|
|
473
|
+
count = var.server_protocol == "MCP" ? 1 : 0
|
|
474
|
+
|
|
475
|
+
triggers = {
|
|
476
|
+
runtime_arn = aws_bedrockagentcore_agent_runtime.agent_runtime.agent_runtime_arn
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
provisioner "local-exec" {
|
|
480
|
+
command = <<-EOT
|
|
481
|
+
uv run --with boto3 python -c "
|
|
482
|
+
import boto3
|
|
483
|
+
import json
|
|
484
|
+
import time
|
|
485
|
+
import uuid
|
|
486
|
+
|
|
487
|
+
runtime_arn = '\${self.triggers.runtime_arn}'
|
|
488
|
+
client = boto3.client('bedrock-agentcore')
|
|
489
|
+
initialize_request = json.dumps({
|
|
490
|
+
'jsonrpc': '2.0',
|
|
491
|
+
'id': 1,
|
|
492
|
+
'method': 'initialize',
|
|
493
|
+
'params': {
|
|
494
|
+
'protocolVersion': '2025-03-26',
|
|
495
|
+
'capabilities': {},
|
|
496
|
+
'clientInfo': {'name': 'readiness-probe', 'version': '1.0'},
|
|
497
|
+
},
|
|
498
|
+
})
|
|
499
|
+
|
|
500
|
+
deadline = time.time() + 3 * 60
|
|
501
|
+
while True:
|
|
502
|
+
try:
|
|
503
|
+
client.invoke_agent_runtime(
|
|
504
|
+
agentRuntimeArn=runtime_arn,
|
|
505
|
+
runtimeSessionId=f'readiness-probe-{uuid.uuid4()}',
|
|
506
|
+
contentType='application/json',
|
|
507
|
+
accept='application/json, text/event-stream',
|
|
508
|
+
payload=initialize_request,
|
|
509
|
+
)
|
|
510
|
+
break
|
|
511
|
+
except Exception:
|
|
512
|
+
if time.time() >= deadline:
|
|
513
|
+
raise
|
|
514
|
+
time.sleep(5)
|
|
515
|
+
|
|
516
|
+
print(f'Runtime {runtime_arn} is serving MCP')
|
|
517
|
+
"
|
|
518
|
+
EOT
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
467
522
|
# Outputs
|
|
468
523
|
output "agent_core_runtime_role_arn" {
|
|
469
524
|
description = "ARN of the Agent Core Runtime IAM role"
|
|
@@ -481,8 +536,8 @@ output "agent_runtime_name" {
|
|
|
481
536
|
}
|
|
482
537
|
|
|
483
538
|
output "agent_core_runtime_arn" {
|
|
484
|
-
description = "ARN of the Bedrock Agent Core runtime"
|
|
485
|
-
value = aws_bedrockagentcore_agent_runtime.agent_runtime.agent_runtime_arn
|
|
539
|
+
description = "ARN of the Bedrock Agent Core runtime. For MCP runtimes the value flows through the readiness probe, so consumers wait until the runtime serves MCP."
|
|
540
|
+
value = var.server_protocol == "MCP" ? null_resource.runtime_ready[0].triggers.runtime_arn : aws_bedrockagentcore_agent_runtime.agent_runtime.agent_runtime_arn
|
|
486
541
|
}
|
|
487
542
|
|
|
488
543
|
output "agent_runtime_id" {
|
|
@@ -64,6 +64,8 @@ const tsNxGeneratorGenerator = async (tree, options) => {
|
|
|
64
64
|
}, { overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting });
|
|
65
65
|
// Update the docs config to add the page entry to the Generator guides sidebar section
|
|
66
66
|
await (0, ast_1.applyGritQL)(tree, (0, devkit_1.joinPathFragments)('docs', 'astro.config.mjs'), `\`items: [$items]\` where { $items <: within \`sidebar: [$_]\`, $items <: contains \`'ts#project'\`, $items <: not contains \`'/guides/${enhancedOptions.nameKebabCase}'\`, $items += \`, { label: '${name}', link: '/guides/${enhancedOptions.nameKebabCase}' }\` }`);
|
|
67
|
+
// Expose the generator from the SDK for known prefixes (ts# / py#)
|
|
68
|
+
addSdkExport(tree, plugin.root, name, generatorSubDir, enhancedOptions);
|
|
67
69
|
}
|
|
68
70
|
else {
|
|
69
71
|
// Local generator in a project other than nx-plugin-for-aws
|
|
@@ -116,5 +118,32 @@ const incrementMetric = (metrics) => {
|
|
|
116
118
|
const maxMetric = Math.max(...metrics.map((m) => Number(m.slice(1))));
|
|
117
119
|
return `g${maxMetric + 1}`;
|
|
118
120
|
};
|
|
121
|
+
// Maps a generator name prefix to the SDK entry point that should re-export it
|
|
122
|
+
const SDK_EXPORT_PREFIXES = {
|
|
123
|
+
'ts#': 'ts',
|
|
124
|
+
'py#': 'py',
|
|
125
|
+
};
|
|
126
|
+
// Re-exports a generated generator from the matching SDK entry point so it is
|
|
127
|
+
// available programmatically as part of @aws/nx-plugin's SDK
|
|
128
|
+
const addSdkExport = (tree, pluginRoot, name, generatorSubDir, options) => {
|
|
129
|
+
const prefix = Object.keys(SDK_EXPORT_PREFIXES).find((p) => name.startsWith(p));
|
|
130
|
+
if (!prefix) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const sdkPath = (0, devkit_1.joinPathFragments)(pluginRoot, 'sdk', `${SDK_EXPORT_PREFIXES[prefix]}.ts`);
|
|
134
|
+
const generatorExport = `${options.nameCamelCase}Generator`;
|
|
135
|
+
const schemaExport = `${options.namePascalCase}GeneratorSchema`;
|
|
136
|
+
const moduleBase = `../src/${generatorSubDir}`;
|
|
137
|
+
const contents = tree.exists(sdkPath) ? tree.read(sdkPath).toString() : '';
|
|
138
|
+
// Idempotent: skip if this generator is already exported
|
|
139
|
+
if (contents.includes(`${moduleBase}/generator`)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const block = `// ${options.namePascalCase} Generator\nexport { ${generatorExport} } from '${moduleBase}/generator';\nexport type { ${schemaExport} } from '${moduleBase}/schema';\n`;
|
|
143
|
+
const prefixContents = contents.trim()
|
|
144
|
+
? `${contents.replace(/\s*$/, '')}\n\n`
|
|
145
|
+
: '';
|
|
146
|
+
tree.write(sdkPath, `${prefixContents}${block}`);
|
|
147
|
+
};
|
|
119
148
|
exports.default = exports.tsNxGeneratorGenerator;
|
|
120
149
|
//# sourceMappingURL=generator.js.map
|