@aws/nx-plugin 0.76.0 → 0.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-THIRD-PARTY +96 -10
- package/package.json +9 -9
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +378 -7
- package/src/infra/app/files/app/src/main.ts.template +17 -2
- package/src/infra/app/generator.js +34 -9
- package/src/infra/app/generator.js.map +1 -1
- package/src/infra/app/schema.d.ts +1 -0
- package/src/infra/app/schema.json +6 -0
- package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +16 -13
- package/src/py/fast-api/react/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +6 -6
- package/src/smithy/react-connection/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +23 -17
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +60 -34
- package/src/trpc/backend/files/src/handler.ts.template +48 -0
- package/src/trpc/backend/files/src/index.ts.template +1 -1
- package/src/trpc/backend/files/src/router.ts.template +0 -38
- package/src/trpc/backend/files/src/schema/z-async-iterable.ts.template +115 -0
- package/src/trpc/backend/generator.js +6 -2
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/trpc/react/__snapshots__/generator.spec.ts.snap +274 -27
- package/src/trpc/react/files/src/components/__apiNameClassName__ClientProvider.tsx.template +57 -1
- package/src/trpc/react/generator.js +11 -1
- package/src/trpc/react/generator.js.map +1 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +13 -13
- package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +13 -1
- package/src/utils/api-constructs/files/cdk/core/api/trpc/trpc-utils.ts.template +3 -3
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +8 -3
- package/src/utils/api-constructs/files/terraform/core/api/rest/rest-api/rest-api.tf.template +1 -1
- package/src/utils/connection/open-api/files/components/__apiNameClassName__Provider.tsx.template +1 -1
- package/src/utils/files/common/infra-config/src/index.ts.template +3 -0
- package/src/utils/files/common/infra-config/src/resolve-stage.ts.template +23 -0
- package/src/utils/files/common/infra-config/src/stages.config.ts.template +48 -0
- package/src/utils/files/common/infra-config/src/stages.types.ts.template +66 -0
- package/src/utils/files/common/scripts/src/index.ts.template +1 -0
- package/src/utils/files/common/scripts/src/infra-deploy.ts.template +2 -0
- package/src/utils/files/common/scripts/src/infra-destroy.ts.template +2 -0
- package/src/utils/files/common/scripts/src/stage-credentials/cdk-command.ts.template +18 -0
- package/src/utils/files/common/scripts/src/stage-credentials/credentials.ts.template +100 -0
- package/src/utils/files/common/scripts/src/stage-credentials/run.ts.template +52 -0
- package/src/utils/files/common/scripts/src/stage-credentials/stage-parser.ts.template +15 -0
- package/src/utils/files/website/hooks/sigv4/useSigV4.tsx.template +81 -33
- package/src/utils/shared-constructs-constants.d.ts +4 -0
- package/src/utils/shared-constructs-constants.js +5 -1
- package/src/utils/shared-constructs-constants.js.map +1 -1
- package/src/utils/shared-infra-config.d.ts +11 -0
- package/src/utils/shared-infra-config.js +47 -0
- package/src/utils/shared-infra-config.js.map +1 -0
- package/src/utils/shared-scripts.d.ts +12 -0
- package/src/utils/shared-scripts.js +49 -0
- package/src/utils/shared-scripts.js.map +1 -0
- package/src/utils/versions.d.ts +31 -28
- package/src/utils/versions.js +30 -27
- package/src/utils/versions.js.map +1 -1
|
@@ -28,9 +28,11 @@ function reactGenerator(tree, options) {
|
|
|
28
28
|
const apiName = metadata.apiName;
|
|
29
29
|
const auth = (_a = metadata.auth) !== null && _a !== void 0 ? _a : 'IAM';
|
|
30
30
|
const port = (_d = (_b = metadata.port) !== null && _b !== void 0 ? _b : (_c = metadata.ports) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : 2022;
|
|
31
|
+
const isRestApi = metadata.computeType === 'ServerlessApiGatewayRestApi';
|
|
31
32
|
const apiNameClassName = (0, names_1.toClassName)(apiName);
|
|
32
33
|
const backendProjectAlias = (0, npm_scope_1.toScopeAlias)(backendProjectConfig.name);
|
|
33
34
|
(0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files'), frontendProjectConfig.root, Object.assign(Object.assign({ apiName, apiNameClassName: (0, names_1.toClassName)(apiName) }, options), { auth,
|
|
35
|
+
isRestApi,
|
|
34
36
|
backendProjectAlias }), {
|
|
35
37
|
overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting,
|
|
36
38
|
});
|
|
@@ -70,6 +72,9 @@ function reactGenerator(tree, options) {
|
|
|
70
72
|
'@trpc/tanstack-react-query',
|
|
71
73
|
'@tanstack/react-query',
|
|
72
74
|
'@tanstack/react-query-devtools',
|
|
75
|
+
...(isRestApi && auth !== 'None'
|
|
76
|
+
? ['event-source-polyfill']
|
|
77
|
+
: []),
|
|
73
78
|
...(auth === 'IAM'
|
|
74
79
|
? [
|
|
75
80
|
'oidc-client-ts',
|
|
@@ -80,7 +85,12 @@ function reactGenerator(tree, options) {
|
|
|
80
85
|
]
|
|
81
86
|
: []),
|
|
82
87
|
...(auth === 'Cognito' ? ['react-oidc-context'] : []),
|
|
83
|
-
]), (0, versions_1.withVersions)([
|
|
88
|
+
]), (0, versions_1.withVersions)([
|
|
89
|
+
'@smithy/types',
|
|
90
|
+
...(isRestApi && auth !== 'None'
|
|
91
|
+
? ['@types/event-source-polyfill']
|
|
92
|
+
: []),
|
|
93
|
+
]));
|
|
84
94
|
yield (0, metrics_1.addGeneratorMetricsIfApplicable)(tree, [exports.TRPC_REACT_GENERATOR_INFO]);
|
|
85
95
|
yield (0, format_1.formatFilesInSubtree)(tree);
|
|
86
96
|
return () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/trpc/react/generator.ts"],"names":[],"mappings":";;;AAoCA,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/trpc/react/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -640,7 +640,7 @@ exports[`ts#mcp-server generator > should match snapshot for generated files > u
|
|
|
640
640
|
"snapshot-server": "./src/snapshot-server/stdio.js"
|
|
641
641
|
},
|
|
642
642
|
"dependencies": {
|
|
643
|
-
"@modelcontextprotocol/sdk": "1.
|
|
643
|
+
"@modelcontextprotocol/sdk": "1.27.0",
|
|
644
644
|
"express": "5.2.1",
|
|
645
645
|
"zod": "4.3.6"
|
|
646
646
|
},
|
|
@@ -248,7 +248,7 @@ export const registerCreateWorkspaceCommandTool = (server: McpServer) => {
|
|
|
248
248
|
text: \`Run the following command to create a workspace:
|
|
249
249
|
|
|
250
250
|
\\\`\\\`\\\`bash
|
|
251
|
-
npx create-nx-workspace@22.5.
|
|
251
|
+
npx create-nx-workspace@22.5.1 \${workspaceName} --pm=\${packageManager} --preset=@aws/nx-plugin --ci=skip --aiAgents
|
|
252
252
|
\\\`\\\`\\\`
|
|
253
253
|
|
|
254
254
|
This will create a new workspace within the \${workspaceName} directory.
|
|
@@ -1045,11 +1045,11 @@ exports[`react-website generator > Tanstack router integration > should generate
|
|
|
1045
1045
|
"{
|
|
1046
1046
|
"name": "@proj/source",
|
|
1047
1047
|
"dependencies": {
|
|
1048
|
-
"@cloudscape-design/board-components": "3.0.
|
|
1049
|
-
"@cloudscape-design/components": "3.0.
|
|
1048
|
+
"@cloudscape-design/board-components": "3.0.149",
|
|
1049
|
+
"@cloudscape-design/components": "3.0.1204",
|
|
1050
1050
|
"@cloudscape-design/global-styles": "1.0.50",
|
|
1051
1051
|
"aws-cdk-lib": "2.238.0",
|
|
1052
|
-
"constructs": "10.
|
|
1052
|
+
"constructs": "10.5.0",
|
|
1053
1053
|
"react": "19.2.4",
|
|
1054
1054
|
"react-dom": "19.2.4",
|
|
1055
1055
|
"tailwindcss": "4.1.18"
|
|
@@ -2460,12 +2460,12 @@ exports[`react-website generator > Tanstack router integration > should generate
|
|
|
2460
2460
|
"{
|
|
2461
2461
|
"name": "@proj/source",
|
|
2462
2462
|
"dependencies": {
|
|
2463
|
-
"@cloudscape-design/board-components": "3.0.
|
|
2464
|
-
"@cloudscape-design/components": "3.0.
|
|
2463
|
+
"@cloudscape-design/board-components": "3.0.149",
|
|
2464
|
+
"@cloudscape-design/components": "3.0.1204",
|
|
2465
2465
|
"@cloudscape-design/global-styles": "1.0.50",
|
|
2466
|
-
"@tanstack/react-router": "1.
|
|
2466
|
+
"@tanstack/react-router": "1.160.2",
|
|
2467
2467
|
"aws-cdk-lib": "2.238.0",
|
|
2468
|
-
"constructs": "10.
|
|
2468
|
+
"constructs": "10.5.0",
|
|
2469
2469
|
"react": "19.2.4",
|
|
2470
2470
|
"react-dom": "19.2.4",
|
|
2471
2471
|
"tailwindcss": "4.1.18"
|
|
@@ -2484,8 +2484,8 @@ exports[`react-website generator > Tanstack router integration > should generate
|
|
|
2484
2484
|
"@swc/core": "~1.15.5",
|
|
2485
2485
|
"@swc/helpers": "~0.5.18",
|
|
2486
2486
|
"@tailwindcss/vite": "4.1.18",
|
|
2487
|
-
"@tanstack/router-generator": "1.
|
|
2488
|
-
"@tanstack/router-plugin": "1.
|
|
2487
|
+
"@tanstack/router-generator": "1.160.1",
|
|
2488
|
+
"@tanstack/router-plugin": "1.160.2",
|
|
2489
2489
|
"@tanstack/router-utils": "1.158.0",
|
|
2490
2490
|
"@tanstack/virtual-file-routes": "1.154.7",
|
|
2491
2491
|
"@testing-library/dom": "10.4.0",
|
|
@@ -4529,12 +4529,12 @@ root &&
|
|
|
4529
4529
|
|
|
4530
4530
|
exports[`react-website generator > should handle npm scope prefix correctly > scoped-dependencies 1`] = `
|
|
4531
4531
|
{
|
|
4532
|
-
"@cloudscape-design/board-components": "3.0.
|
|
4533
|
-
"@cloudscape-design/components": "3.0.
|
|
4532
|
+
"@cloudscape-design/board-components": "3.0.149",
|
|
4533
|
+
"@cloudscape-design/components": "3.0.1204",
|
|
4534
4534
|
"@cloudscape-design/global-styles": "1.0.50",
|
|
4535
|
-
"@tanstack/react-router": "1.
|
|
4535
|
+
"@tanstack/react-router": "1.160.2",
|
|
4536
4536
|
"aws-cdk-lib": "2.238.0",
|
|
4537
|
-
"constructs": "10.
|
|
4537
|
+
"constructs": "10.5.0",
|
|
4538
4538
|
"react": "19.2.4",
|
|
4539
4539
|
"react-dom": "19.2.4",
|
|
4540
4540
|
"tailwindcss": "4.1.18",
|
|
@@ -12,6 +12,9 @@ import {
|
|
|
12
12
|
AuthorizationType,
|
|
13
13
|
Cors,
|
|
14
14
|
LambdaIntegration,
|
|
15
|
+
<%_ if (backend.type === 'trpc') { _%>
|
|
16
|
+
ResponseTransferMode,
|
|
17
|
+
<%_ } _%>
|
|
15
18
|
<%_ if (auth === 'Cognito') { _%>
|
|
16
19
|
CognitoUserPoolsAuthorizer,
|
|
17
20
|
<%_ } _%>
|
|
@@ -124,7 +127,16 @@ export class <%= apiNameClassName %><
|
|
|
124
127
|
} satisfies FunctionProps,
|
|
125
128
|
buildDefaultIntegration: (op, props: FunctionProps) => {
|
|
126
129
|
const handler = new Function(scope, `<%= apiNameClassName %>${op}Handler`, props);
|
|
127
|
-
return {
|
|
130
|
+
return {
|
|
131
|
+
handler,
|
|
132
|
+
<%_ if (backend.type === 'trpc') { _%>
|
|
133
|
+
integration: new LambdaIntegration(handler, {
|
|
134
|
+
responseTransferMode: ResponseTransferMode.STREAM,
|
|
135
|
+
}),
|
|
136
|
+
<%_ } else { _%>
|
|
137
|
+
integration: new LambdaIntegration(handler),
|
|
138
|
+
<%_ } _%>
|
|
139
|
+
};
|
|
128
140
|
},
|
|
129
141
|
});
|
|
130
142
|
};
|
|
@@ -55,9 +55,9 @@ export const routerToOperations = <TRouter extends AnyTRPCRouter>(
|
|
|
55
55
|
{
|
|
56
56
|
path: fullPath,
|
|
57
57
|
method:
|
|
58
|
-
procedureOrRouter._def.type === '
|
|
59
|
-
? HttpMethod.
|
|
60
|
-
: HttpMethod.
|
|
58
|
+
procedureOrRouter._def.type === 'mutation'
|
|
59
|
+
? HttpMethod.POST
|
|
60
|
+
: HttpMethod.GET,
|
|
61
61
|
},
|
|
62
62
|
],
|
|
63
63
|
];
|
|
@@ -4,7 +4,7 @@ terraform {
|
|
|
4
4
|
required_providers {
|
|
5
5
|
aws = {
|
|
6
6
|
source = "hashicorp/aws"
|
|
7
|
-
version = "~> 6.
|
|
7
|
+
version = "~> 6.33"
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
}
|
|
@@ -210,8 +210,13 @@ resource "aws_api_gateway_integration" "lambda_integration" {
|
|
|
210
210
|
http_method = aws_api_gateway_method.proxy_method.http_method
|
|
211
211
|
|
|
212
212
|
integration_http_method = "POST"
|
|
213
|
-
type
|
|
214
|
-
|
|
213
|
+
type = "AWS_PROXY"
|
|
214
|
+
<%_ if (backend.type === 'trpc') { _%>
|
|
215
|
+
uri = aws_lambda_function.api_lambda.response_streaming_invoke_arn
|
|
216
|
+
response_transfer_mode = "STREAM"
|
|
217
|
+
<%_ } else { _%>
|
|
218
|
+
uri = aws_lambda_function.api_lambda.invoke_arn
|
|
219
|
+
<%_ } _%>
|
|
215
220
|
|
|
216
221
|
depends_on = [aws_lambda_function.api_lambda]
|
|
217
222
|
}
|
package/src/utils/connection/open-api/files/components/__apiNameClassName__Provider.tsx.template
CHANGED
|
@@ -42,7 +42,7 @@ const useCreate<%- apiNameClassName %>Client = (): <%- apiNameClassName %> => {
|
|
|
42
42
|
return useMemo(() => new <%- apiNameClassName %>({
|
|
43
43
|
url: apiUrl,
|
|
44
44
|
<%_ if(auth === 'IAM') { _%>
|
|
45
|
-
fetch: sigv4Client,
|
|
45
|
+
fetch: sigv4Client.fetch,
|
|
46
46
|
<%_ } else if(auth === 'Cognito') { _%>
|
|
47
47
|
fetch: cognitoClient,
|
|
48
48
|
<%_ } _%>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { StageConfig, StagesConfig } from './stages.types.js';
|
|
2
|
+
import stagesConfig from './stages.config.js';
|
|
3
|
+
|
|
4
|
+
// Widen the narrow `as const` type to StagesConfig for dynamic key access
|
|
5
|
+
const config: StagesConfig = stagesConfig;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Resolves stage config for a given project and stage name.
|
|
9
|
+
* Project-specific fields take priority over shared ones.
|
|
10
|
+
*
|
|
11
|
+
* @param projectPath - Project path relative to workspace root (e.g., 'packages/infra')
|
|
12
|
+
* @param stageName - CDK stage name (e.g., 'my-app-dev')
|
|
13
|
+
* @returns Merged StageConfig or undefined if no config exists for this stage
|
|
14
|
+
*/
|
|
15
|
+
export function resolveStage(
|
|
16
|
+
projectPath: string,
|
|
17
|
+
stageName: string,
|
|
18
|
+
): StageConfig | undefined {
|
|
19
|
+
const shared = config.shared?.stages?.[stageName];
|
|
20
|
+
const project = config.projects?.[projectPath]?.stages?.[stageName];
|
|
21
|
+
if (!shared && !project) return undefined;
|
|
22
|
+
return { ...shared, ...project } as StageConfig;
|
|
23
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stage configuration for CDK deployments.
|
|
3
|
+
*
|
|
4
|
+
* This file maps CDK stage names to their deployment settings. When you run
|
|
5
|
+
* `<%= pkgMgrRunNx %> run <project>:deploy <stage-name>/*`, the infra-deploy script
|
|
6
|
+
* automatically resolves and applies the correct credentials.
|
|
7
|
+
*
|
|
8
|
+
* Project keys are the project path relative to the workspace root
|
|
9
|
+
* (e.g., 'packages/infra').
|
|
10
|
+
*
|
|
11
|
+
* Stage names must match the CDK stage identifiers defined in your main.ts —
|
|
12
|
+
* the first argument to `new ApplicationStage(app, '<stage-name>', ...)`.
|
|
13
|
+
* For example, if main.ts has `new ApplicationStage(app, 'my-app-dev', ...)`
|
|
14
|
+
* then the stage name here is 'my-app-dev'.
|
|
15
|
+
*
|
|
16
|
+
* We recommend committing this file so the team shares a single source of truth.
|
|
17
|
+
* If it contains personal profile names, you can add it to .gitignore instead.
|
|
18
|
+
*/
|
|
19
|
+
import type { StagesConfig } from './stages.types.js';
|
|
20
|
+
|
|
21
|
+
export default {
|
|
22
|
+
projects: {
|
|
23
|
+
// Example: map stages for a specific infra project
|
|
24
|
+
// 'packages/infra': {
|
|
25
|
+
// stages: {
|
|
26
|
+
// 'my-app-dev': {
|
|
27
|
+
// credentials: { type: 'profile', profile: 'dev-account' },
|
|
28
|
+
// region: 'us-east-1',
|
|
29
|
+
// // account is optional — if omitted, CDK infers from the profile
|
|
30
|
+
// },
|
|
31
|
+
// 'my-app-prod': {
|
|
32
|
+
// credentials: { type: 'assumeRole', assumeRole: 'arn:aws:iam::123456789012:role/DeployRole' },
|
|
33
|
+
// region: 'us-west-2',
|
|
34
|
+
// account: '123456789012',
|
|
35
|
+
// },
|
|
36
|
+
// },
|
|
37
|
+
// },
|
|
38
|
+
},
|
|
39
|
+
shared: {
|
|
40
|
+
stages: {
|
|
41
|
+
// Example: shared sandbox stage available to all projects
|
|
42
|
+
// 'sandbox': {
|
|
43
|
+
// credentials: { type: 'profile', profile: 'sandbox-profile' },
|
|
44
|
+
// region: 'us-east-1',
|
|
45
|
+
// },
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
} as const satisfies StagesConfig;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for stage and project configuration.
|
|
3
|
+
*
|
|
4
|
+
* These types are used by both stages.config.ts and the infra-deploy/
|
|
5
|
+
* infra-destroy scripts. They live in a shared package so any
|
|
6
|
+
* project in the workspace can import them.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Use an AWS CLI profile from ~/.aws/config */
|
|
10
|
+
export type ProfileCredentials = {
|
|
11
|
+
type: 'profile';
|
|
12
|
+
/** AWS CLI profile name */
|
|
13
|
+
profile: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/** Assume an IAM role via STS, optionally using a profile as the source credentials */
|
|
17
|
+
export type AssumeRoleCredentials = {
|
|
18
|
+
type: 'assumeRole';
|
|
19
|
+
/** IAM Role ARN to assume */
|
|
20
|
+
assumeRole: string;
|
|
21
|
+
/** Optional: AWS CLI profile to use as source credentials for the AssumeRole call */
|
|
22
|
+
profile?: string;
|
|
23
|
+
/** Optional: External ID required by the role's trust policy */
|
|
24
|
+
externalId?: string;
|
|
25
|
+
/** Optional: Session duration in seconds (default: 3600). Increase for long deployments. */
|
|
26
|
+
sessionDuration?: number;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Credentials for deploying to a specific CDK stage.
|
|
31
|
+
* The `type` field determines which credential strategy is used.
|
|
32
|
+
*/
|
|
33
|
+
export type StageCredentials = ProfileCredentials | AssumeRoleCredentials;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Configuration for a single CDK stage.
|
|
37
|
+
* Includes credentials, region, and optionally account.
|
|
38
|
+
*/
|
|
39
|
+
export type StageConfig = {
|
|
40
|
+
/** How to authenticate when deploying this stage */
|
|
41
|
+
credentials: StageCredentials;
|
|
42
|
+
/** AWS region for this stage (e.g., 'us-east-1') */
|
|
43
|
+
region: string;
|
|
44
|
+
/** AWS account ID. If omitted, CDK infers it from the active credentials. */
|
|
45
|
+
account?: string;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Configuration for a single infrastructure project.
|
|
50
|
+
* The key in the parent map is the project path relative to workspace root
|
|
51
|
+
* (e.g., 'packages/infra').
|
|
52
|
+
*/
|
|
53
|
+
export type ProjectConfig = {
|
|
54
|
+
/** Map of CDK stage names to their configuration */
|
|
55
|
+
stages: { [stageName: string]: StageConfig };
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/** Top-level configuration mapping projects and stages to their settings. */
|
|
59
|
+
export type StagesConfig = {
|
|
60
|
+
/** Project-specific config. Key is the project path relative to workspace root. */
|
|
61
|
+
projects?: { [projectPath: string]: ProjectConfig };
|
|
62
|
+
/** Shared stage config available to all projects. */
|
|
63
|
+
shared?: {
|
|
64
|
+
stages: { [stageName: string]: StageConfig };
|
|
65
|
+
};
|
|
66
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Scripts (infra-deploy, infra-destroy) are the public interface of this package.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the CDK command as an array of arguments for spawnSync.
|
|
3
|
+
*
|
|
4
|
+
* Defaults to --require-approval=never (standard for local dev deploys).
|
|
5
|
+
* If the user explicitly passes --require-approval with any value, we
|
|
6
|
+
* respect their choice and don't add the default.
|
|
7
|
+
*/
|
|
8
|
+
export function buildCdkCommand(
|
|
9
|
+
action: string,
|
|
10
|
+
remainingArgs: string[],
|
|
11
|
+
): string[] {
|
|
12
|
+
const hasRequireApproval = remainingArgs.some(
|
|
13
|
+
(a) => a === '--require-approval' || a.startsWith('--require-approval='),
|
|
14
|
+
);
|
|
15
|
+
return hasRequireApproval
|
|
16
|
+
? ['cdk', action, ...remainingArgs]
|
|
17
|
+
: ['cdk', action, '--require-approval=never', ...remainingArgs];
|
|
18
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
StageCredentials,
|
|
3
|
+
StagesConfig,
|
|
4
|
+
} from '<%= scopeAlias %>common-infra-config';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Looks up credentials for a given project + stage combination.
|
|
8
|
+
*
|
|
9
|
+
* Lookup order:
|
|
10
|
+
* 1. Project-specific: config.projects[projectPath].stages[stageName].credentials
|
|
11
|
+
* 2. Shared: config.shared.stages[stageName].credentials
|
|
12
|
+
* 3. No match: returns undefined — caller falls back to env vars
|
|
13
|
+
*/
|
|
14
|
+
export function lookupCredentials(
|
|
15
|
+
config: StagesConfig | undefined,
|
|
16
|
+
projectPath: string,
|
|
17
|
+
stageName: string,
|
|
18
|
+
): { credentials: StageCredentials | undefined; source: string } {
|
|
19
|
+
const projectCreds =
|
|
20
|
+
config?.projects?.[projectPath]?.stages?.[stageName]?.credentials;
|
|
21
|
+
if (projectCreds) {
|
|
22
|
+
return { credentials: projectCreds, source: 'project-specific' };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const sharedCreds = config?.shared?.stages?.[stageName]?.credentials;
|
|
26
|
+
if (sharedCreds) {
|
|
27
|
+
return { credentials: sharedCreds, source: 'shared' };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return { credentials: undefined, source: 'environment fallback' };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Builds a child process environment with the resolved credentials overlaid.
|
|
35
|
+
* Never modifies process.env — returns a new object.
|
|
36
|
+
*/
|
|
37
|
+
export async function buildChildEnv(
|
|
38
|
+
credentials: StageCredentials,
|
|
39
|
+
projectPath: string,
|
|
40
|
+
): Promise<Record<string, string | undefined>> {
|
|
41
|
+
const env = { ...process.env };
|
|
42
|
+
|
|
43
|
+
switch (credentials.type) {
|
|
44
|
+
case 'profile': {
|
|
45
|
+
env.AWS_PROFILE = credentials.profile;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
case 'assumeRole': {
|
|
49
|
+
let STSClient: typeof import('@aws-sdk/client-sts').STSClient;
|
|
50
|
+
let AssumeRoleCommand: typeof import('@aws-sdk/client-sts').AssumeRoleCommand;
|
|
51
|
+
try {
|
|
52
|
+
({ STSClient, AssumeRoleCommand } =
|
|
53
|
+
await import('@aws-sdk/client-sts'));
|
|
54
|
+
} catch {
|
|
55
|
+
console.error(
|
|
56
|
+
'[infra-deploy] Error: @aws-sdk/client-sts is required for assumeRole credentials but is not installed.',
|
|
57
|
+
);
|
|
58
|
+
console.error('[infra-deploy] Please install @aws-sdk/client-sts');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// If a source profile is specified, configure the STS client to use it
|
|
63
|
+
const stsClientOptions: Record<string, unknown> = {};
|
|
64
|
+
if (credentials.profile) {
|
|
65
|
+
const { fromIni } = await import('@aws-sdk/credential-providers');
|
|
66
|
+
stsClientOptions.credentials = fromIni({
|
|
67
|
+
profile: credentials.profile,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const response = await new STSClient(stsClientOptions).send(
|
|
72
|
+
new AssumeRoleCommand({
|
|
73
|
+
RoleArn: credentials.assumeRole,
|
|
74
|
+
RoleSessionName: `infra-deploy-${projectPath.replace(/\//g, '-')}`,
|
|
75
|
+
...(credentials.externalId
|
|
76
|
+
? { ExternalId: credentials.externalId }
|
|
77
|
+
: {}),
|
|
78
|
+
...(credentials.sessionDuration
|
|
79
|
+
? { DurationSeconds: credentials.sessionDuration }
|
|
80
|
+
: {}),
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
env.AWS_ACCESS_KEY_ID = response.Credentials?.AccessKeyId;
|
|
85
|
+
env.AWS_SECRET_ACCESS_KEY = response.Credentials?.SecretAccessKey;
|
|
86
|
+
env.AWS_SESSION_TOKEN = response.Credentials?.SessionToken;
|
|
87
|
+
delete env.AWS_PROFILE;
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return env;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Human-readable description of credentials for logging */
|
|
96
|
+
export function describeCredentials(creds: StageCredentials): string {
|
|
97
|
+
return creds.type === 'profile'
|
|
98
|
+
? `profile '${creds.profile}'`
|
|
99
|
+
: `role '${creds.assumeRole}'`;
|
|
100
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
import stagesConfig from '<%= scopeAlias %>common-infra-config';
|
|
3
|
+
import { parseStageName } from './stage-parser.js';
|
|
4
|
+
import {
|
|
5
|
+
lookupCredentials,
|
|
6
|
+
buildChildEnv,
|
|
7
|
+
describeCredentials,
|
|
8
|
+
} from './credentials.js';
|
|
9
|
+
import { buildCdkCommand } from './cdk-command.js';
|
|
10
|
+
|
|
11
|
+
const log = (msg: string) => console.error(`[infra-deploy] ${msg}`);
|
|
12
|
+
|
|
13
|
+
export async function run(action: 'deploy' | 'destroy'): Promise<void> {
|
|
14
|
+
const [projectPath, ...remainingArgs] = process.argv.slice(2);
|
|
15
|
+
|
|
16
|
+
if (!projectPath) {
|
|
17
|
+
log(`Usage: infra-${action} <project-path> [stage/*] [cdk-args...]`);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const stageName = parseStageName(remainingArgs[0]);
|
|
22
|
+
let childEnv: Record<string, string | undefined> = { ...process.env };
|
|
23
|
+
|
|
24
|
+
if (stageName) {
|
|
25
|
+
const { credentials, source } = lookupCredentials(
|
|
26
|
+
stagesConfig,
|
|
27
|
+
projectPath,
|
|
28
|
+
stageName,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
if (credentials) {
|
|
32
|
+
log(
|
|
33
|
+
`Using ${describeCredentials(credentials)} for '${stageName}' (${source})`,
|
|
34
|
+
);
|
|
35
|
+
childEnv = await buildChildEnv(credentials, projectPath);
|
|
36
|
+
} else {
|
|
37
|
+
log(`No credentials for '${stageName}' — using environment`);
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
log('No stage specified — using environment credentials');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Run CDK from the project directory so it finds cdk.json
|
|
44
|
+
const cmd = buildCdkCommand(action, remainingArgs);
|
|
45
|
+
const { status } = spawnSync(cmd[0], cmd.slice(1), {
|
|
46
|
+
stdio: 'inherit',
|
|
47
|
+
env: childEnv,
|
|
48
|
+
cwd: projectPath,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
process.exit(status ?? 1);
|
|
52
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts the CDK stage name from the first positional argument.
|
|
3
|
+
*
|
|
4
|
+
* Examples:
|
|
5
|
+
* parseStageName('my-app-dev/*') → 'my-app-dev'
|
|
6
|
+
* parseStageName('my-app-dev') → 'my-app-dev'
|
|
7
|
+
* parseStageName('--verbose') → undefined (flag, not a stage)
|
|
8
|
+
* parseStageName(undefined) → undefined
|
|
9
|
+
*/
|
|
10
|
+
export function parseStageName(
|
|
11
|
+
firstArg: string | undefined,
|
|
12
|
+
): string | undefined {
|
|
13
|
+
if (!firstArg || firstArg.startsWith('-')) return undefined;
|
|
14
|
+
return firstArg.includes('/') ? firstArg.split('/')[0] : firstArg;
|
|
15
|
+
}
|