@aws/nx-plugin 0.76.0 → 0.77.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 +60 -2
- 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/mcp-server/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +6 -6
- 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/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/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 +29 -28
- package/src/utils/versions.js +28 -27
- package/src/utils/versions.js.map +1 -1
package/LICENSE-THIRD-PARTY
CHANGED
|
@@ -3903,7 +3903,7 @@ THE SOFTWARE.
|
|
|
3903
3903
|
|
|
3904
3904
|
---
|
|
3905
3905
|
|
|
3906
|
-
The following software may be included in this product: @modelcontextprotocol/sdk (1.
|
|
3906
|
+
The following software may be included in this product: @modelcontextprotocol/sdk (1.27.0)
|
|
3907
3907
|
This software contains the following license and notice below:
|
|
3908
3908
|
|
|
3909
3909
|
MIT License
|
|
@@ -8493,6 +8493,35 @@ SOFTWARE.
|
|
|
8493
8493
|
|
|
8494
8494
|
---
|
|
8495
8495
|
|
|
8496
|
+
The following software may be included in this product: balanced-match (4.0.4)
|
|
8497
|
+
This software contains the following license and notice below:
|
|
8498
|
+
|
|
8499
|
+
(MIT)
|
|
8500
|
+
|
|
8501
|
+
Original code Copyright Julian Gruber <julian@juliangruber.com>
|
|
8502
|
+
|
|
8503
|
+
Port to TypeScript Copyright Isaac Z. Schlueter <i@izs.me>
|
|
8504
|
+
|
|
8505
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
8506
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
8507
|
+
the Software without restriction, including without limitation the rights to
|
|
8508
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
8509
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
8510
|
+
so, subject to the following conditions:
|
|
8511
|
+
|
|
8512
|
+
The above copyright notice and this permission notice shall be included in all
|
|
8513
|
+
copies or substantial portions of the Software.
|
|
8514
|
+
|
|
8515
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
8516
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
8517
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
8518
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
8519
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
8520
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
8521
|
+
SOFTWARE.
|
|
8522
|
+
|
|
8523
|
+
---
|
|
8524
|
+
|
|
8496
8525
|
The following software may be included in this product: base64-js (1.5.1)
|
|
8497
8526
|
This software contains the following license and notice below:
|
|
8498
8527
|
|
|
@@ -8737,6 +8766,35 @@ SOFTWARE.
|
|
|
8737
8766
|
|
|
8738
8767
|
---
|
|
8739
8768
|
|
|
8769
|
+
The following software may be included in this product: brace-expansion (5.0.3)
|
|
8770
|
+
This software contains the following license and notice below:
|
|
8771
|
+
|
|
8772
|
+
MIT License
|
|
8773
|
+
|
|
8774
|
+
Copyright Julian Gruber <julian@juliangruber.com>
|
|
8775
|
+
|
|
8776
|
+
TypeScript port Copyright Isaac Z. Schlueter <i@izs.me>
|
|
8777
|
+
|
|
8778
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8779
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8780
|
+
in the Software without restriction, including without limitation the rights
|
|
8781
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8782
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8783
|
+
furnished to do so, subject to the following conditions:
|
|
8784
|
+
|
|
8785
|
+
The above copyright notice and this permission notice shall be included in all
|
|
8786
|
+
copies or substantial portions of the Software.
|
|
8787
|
+
|
|
8788
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
8789
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
8790
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
8791
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
8792
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
8793
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
8794
|
+
SOFTWARE.
|
|
8795
|
+
|
|
8796
|
+
---
|
|
8797
|
+
|
|
8740
8798
|
The following software may be included in this product: braces (3.0.3)
|
|
8741
8799
|
This software contains the following license and notice below:
|
|
8742
8800
|
|
|
@@ -39041,7 +39099,7 @@ software or this license, under any kind of legal claim._**
|
|
|
39041
39099
|
|
|
39042
39100
|
---
|
|
39043
39101
|
|
|
39044
|
-
The following software may be included in this product: minimatch (10.
|
|
39102
|
+
The following software may be included in this product: minimatch (10.2.2)
|
|
39045
39103
|
This software contains the following license and notice below:
|
|
39046
39104
|
|
|
39047
39105
|
# Blue Oak Model License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws/nx-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.77.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/awslabs/nx-plugin-for-aws.git",
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
},
|
|
20
20
|
"generators": "./generators.json",
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"nx": "~22.5.
|
|
22
|
+
"nx": "~22.5.1",
|
|
23
23
|
"prettier": "^3.8.1"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@apidevtools/swagger-parser": "^10.1.1",
|
|
27
27
|
"@hey-api/openapi-ts": "0.64.13",
|
|
28
28
|
"@iarna/toml": "^2.2.5",
|
|
29
|
-
"@modelcontextprotocol/sdk": "~1.
|
|
30
|
-
"@nx/devkit": "~22.5.
|
|
31
|
-
"@nx/eslint": "~22.5.
|
|
32
|
-
"@nx/js": "~22.5.
|
|
33
|
-
"@nx/react": "~22.5.
|
|
34
|
-
"@nx/vite": "~22.5.
|
|
29
|
+
"@modelcontextprotocol/sdk": "~1.27.0",
|
|
30
|
+
"@nx/devkit": "~22.5.1",
|
|
31
|
+
"@nx/eslint": "~22.5.1",
|
|
32
|
+
"@nx/js": "~22.5.1",
|
|
33
|
+
"@nx/react": "~22.5.1",
|
|
34
|
+
"@nx/vite": "~22.5.1",
|
|
35
35
|
"@nxlv/python": "~22.1.0",
|
|
36
36
|
"@phenomnomnominal/tsquery": "6.1.4",
|
|
37
37
|
"enquirer": "^2.4.1",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"lodash.orderby": "^4.6.0",
|
|
43
43
|
"lodash.trim": "^4.5.1",
|
|
44
44
|
"lodash.uniqby": "^4.7.0",
|
|
45
|
-
"minimatch": "^10.1
|
|
45
|
+
"minimatch": "^10.2.1",
|
|
46
46
|
"openapi-types": "^12.1.3",
|
|
47
47
|
"pip-requirements-js": "^0.2.1",
|
|
48
48
|
"typescript": "~5.9.3",
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`infra generator > should add required dependencies to package.json > dependencies 1`] = `
|
|
4
4
|
{
|
|
5
|
-
"aws-cdk": "2.
|
|
5
|
+
"aws-cdk": "2.1106.0",
|
|
6
6
|
"aws-cdk-lib": "2.238.0",
|
|
7
|
-
"constructs": "10.
|
|
7
|
+
"constructs": "10.5.0",
|
|
8
8
|
"esbuild": "0.27.3",
|
|
9
9
|
"source-map-support": "0.5.21",
|
|
10
10
|
}
|
|
@@ -39,9 +39,9 @@ exports[`infra generator > should add required dependencies to package.json > de
|
|
|
39
39
|
exports[`infra generator > should add required dependencies to package.json > package-json 1`] = `
|
|
40
40
|
{
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"aws-cdk": "2.
|
|
42
|
+
"aws-cdk": "2.1106.0",
|
|
43
43
|
"aws-cdk-lib": "2.238.0",
|
|
44
|
-
"constructs": "10.
|
|
44
|
+
"constructs": "10.5.0",
|
|
45
45
|
"esbuild": "0.27.3",
|
|
46
46
|
"source-map-support": "0.5.21",
|
|
47
47
|
},
|
|
@@ -84,7 +84,7 @@ exports[`infra generator > should configure Checkov target correctly > checkov-t
|
|
|
84
84
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
85
85
|
],
|
|
86
86
|
"options": {
|
|
87
|
-
"command": "uvx checkov==3.2.
|
|
87
|
+
"command": "uvx checkov==3.2.505 --config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation",
|
|
88
88
|
},
|
|
89
89
|
"outputs": [
|
|
90
90
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -177,7 +177,7 @@ exports[`infra generator > should configure project.json with correct targets >
|
|
|
177
177
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
178
178
|
],
|
|
179
179
|
"options": {
|
|
180
|
-
"command": "uvx checkov==3.2.
|
|
180
|
+
"command": "uvx checkov==3.2.505 --config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation",
|
|
181
181
|
},
|
|
182
182
|
"outputs": [
|
|
183
183
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -727,7 +727,7 @@ exports[`infra generator > should handle custom project names correctly > custom
|
|
|
727
727
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
728
728
|
],
|
|
729
729
|
"options": {
|
|
730
|
-
"command": "uvx checkov==3.2.
|
|
730
|
+
"command": "uvx checkov==3.2.505 --config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation",
|
|
731
731
|
},
|
|
732
732
|
"outputs": [
|
|
733
733
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -812,3 +812,374 @@ exports[`infra generator > should handle custom project names correctly > custom
|
|
|
812
812
|
},
|
|
813
813
|
}
|
|
814
814
|
`;
|
|
815
|
+
|
|
816
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated infra-config src directory > packages/common/infra-config/src/index.ts 1`] = `
|
|
817
|
+
"export * from './stages.types.js';
|
|
818
|
+
export { default } from './stages.config.js';
|
|
819
|
+
export { resolveStage } from './resolve-stage.js';
|
|
820
|
+
"
|
|
821
|
+
`;
|
|
822
|
+
|
|
823
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated infra-config src directory > packages/common/infra-config/src/resolve-stage.ts 1`] = `
|
|
824
|
+
"import type { StageConfig, StagesConfig } from './stages.types.js';
|
|
825
|
+
import stagesConfig from './stages.config.js';
|
|
826
|
+
|
|
827
|
+
// Widen the narrow \`as const\` type to StagesConfig for dynamic key access
|
|
828
|
+
const config: StagesConfig = stagesConfig;
|
|
829
|
+
|
|
830
|
+
/**
|
|
831
|
+
* Resolves stage config for a given project and stage name.
|
|
832
|
+
* Project-specific fields take priority over shared ones.
|
|
833
|
+
*
|
|
834
|
+
* @param projectPath - Project path relative to workspace root (e.g., 'packages/infra')
|
|
835
|
+
* @param stageName - CDK stage name (e.g., 'my-app-dev')
|
|
836
|
+
* @returns Merged StageConfig or undefined if no config exists for this stage
|
|
837
|
+
*/
|
|
838
|
+
export function resolveStage(
|
|
839
|
+
projectPath: string,
|
|
840
|
+
stageName: string,
|
|
841
|
+
): StageConfig | undefined {
|
|
842
|
+
const shared = config.shared?.stages?.[stageName];
|
|
843
|
+
const project = config.projects?.[projectPath]?.stages?.[stageName];
|
|
844
|
+
if (!shared && !project) return undefined;
|
|
845
|
+
return { ...shared, ...project } as StageConfig;
|
|
846
|
+
}
|
|
847
|
+
"
|
|
848
|
+
`;
|
|
849
|
+
|
|
850
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated infra-config src directory > packages/common/infra-config/src/stages.config.ts 1`] = `
|
|
851
|
+
"/**
|
|
852
|
+
* Stage configuration for CDK deployments.
|
|
853
|
+
*
|
|
854
|
+
* This file maps CDK stage names to their deployment settings. When you run
|
|
855
|
+
* \`npx nx run <project>:deploy <stage-name>/*\`, the infra-deploy script
|
|
856
|
+
* automatically resolves and applies the correct credentials.
|
|
857
|
+
*
|
|
858
|
+
* Project keys are the project path relative to the workspace root
|
|
859
|
+
* (e.g., 'packages/infra').
|
|
860
|
+
*
|
|
861
|
+
* Stage names must match the CDK stage identifiers defined in your main.ts —
|
|
862
|
+
* the first argument to \`new ApplicationStage(app, '<stage-name>', ...)\`.
|
|
863
|
+
* For example, if main.ts has \`new ApplicationStage(app, 'my-app-dev', ...)\`
|
|
864
|
+
* then the stage name here is 'my-app-dev'.
|
|
865
|
+
*
|
|
866
|
+
* We recommend committing this file so the team shares a single source of truth.
|
|
867
|
+
* If it contains personal profile names, you can add it to .gitignore instead.
|
|
868
|
+
*/
|
|
869
|
+
import type { StagesConfig } from './stages.types.js';
|
|
870
|
+
|
|
871
|
+
export default {
|
|
872
|
+
projects: {
|
|
873
|
+
// Example: map stages for a specific infra project
|
|
874
|
+
// 'packages/infra': {
|
|
875
|
+
// stages: {
|
|
876
|
+
// 'my-app-dev': {
|
|
877
|
+
// credentials: { type: 'profile', profile: 'dev-account' },
|
|
878
|
+
// region: 'us-east-1',
|
|
879
|
+
// // account is optional — if omitted, CDK infers from the profile
|
|
880
|
+
// },
|
|
881
|
+
// 'my-app-prod': {
|
|
882
|
+
// credentials: { type: 'assumeRole', assumeRole: 'arn:aws:iam::123456789012:role/DeployRole' },
|
|
883
|
+
// region: 'us-west-2',
|
|
884
|
+
// account: '123456789012',
|
|
885
|
+
// },
|
|
886
|
+
// },
|
|
887
|
+
// },
|
|
888
|
+
},
|
|
889
|
+
shared: {
|
|
890
|
+
stages: {
|
|
891
|
+
// Example: shared sandbox stage available to all projects
|
|
892
|
+
// 'sandbox': {
|
|
893
|
+
// credentials: { type: 'profile', profile: 'sandbox-profile' },
|
|
894
|
+
// region: 'us-east-1',
|
|
895
|
+
// },
|
|
896
|
+
},
|
|
897
|
+
},
|
|
898
|
+
} as const satisfies StagesConfig;
|
|
899
|
+
"
|
|
900
|
+
`;
|
|
901
|
+
|
|
902
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated infra-config src directory > packages/common/infra-config/src/stages.types.ts 1`] = `
|
|
903
|
+
"/**
|
|
904
|
+
* Type definitions for stage and project configuration.
|
|
905
|
+
*
|
|
906
|
+
* These types are used by both stages.config.ts and the infra-deploy/
|
|
907
|
+
* infra-destroy scripts. They live in a shared package so any
|
|
908
|
+
* project in the workspace can import them.
|
|
909
|
+
*/
|
|
910
|
+
|
|
911
|
+
/** Use an AWS CLI profile from ~/.aws/config */
|
|
912
|
+
export type ProfileCredentials = {
|
|
913
|
+
type: 'profile';
|
|
914
|
+
/** AWS CLI profile name */
|
|
915
|
+
profile: string;
|
|
916
|
+
};
|
|
917
|
+
|
|
918
|
+
/** Assume an IAM role via STS, optionally using a profile as the source credentials */
|
|
919
|
+
export type AssumeRoleCredentials = {
|
|
920
|
+
type: 'assumeRole';
|
|
921
|
+
/** IAM Role ARN to assume */
|
|
922
|
+
assumeRole: string;
|
|
923
|
+
/** Optional: AWS CLI profile to use as source credentials for the AssumeRole call */
|
|
924
|
+
profile?: string;
|
|
925
|
+
/** Optional: External ID required by the role's trust policy */
|
|
926
|
+
externalId?: string;
|
|
927
|
+
/** Optional: Session duration in seconds (default: 3600). Increase for long deployments. */
|
|
928
|
+
sessionDuration?: number;
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* Credentials for deploying to a specific CDK stage.
|
|
933
|
+
* The \`type\` field determines which credential strategy is used.
|
|
934
|
+
*/
|
|
935
|
+
export type StageCredentials = ProfileCredentials | AssumeRoleCredentials;
|
|
936
|
+
|
|
937
|
+
/**
|
|
938
|
+
* Configuration for a single CDK stage.
|
|
939
|
+
* Includes credentials, region, and optionally account.
|
|
940
|
+
*/
|
|
941
|
+
export type StageConfig = {
|
|
942
|
+
/** How to authenticate when deploying this stage */
|
|
943
|
+
credentials: StageCredentials;
|
|
944
|
+
/** AWS region for this stage (e.g., 'us-east-1') */
|
|
945
|
+
region: string;
|
|
946
|
+
/** AWS account ID. If omitted, CDK infers it from the active credentials. */
|
|
947
|
+
account?: string;
|
|
948
|
+
};
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* Configuration for a single infrastructure project.
|
|
952
|
+
* The key in the parent map is the project path relative to workspace root
|
|
953
|
+
* (e.g., 'packages/infra').
|
|
954
|
+
*/
|
|
955
|
+
export type ProjectConfig = {
|
|
956
|
+
/** Map of CDK stage names to their configuration */
|
|
957
|
+
stages: { [stageName: string]: StageConfig };
|
|
958
|
+
};
|
|
959
|
+
|
|
960
|
+
/** Top-level configuration mapping projects and stages to their settings. */
|
|
961
|
+
export type StagesConfig = {
|
|
962
|
+
/** Project-specific config. Key is the project path relative to workspace root. */
|
|
963
|
+
projects?: { [projectPath: string]: ProjectConfig };
|
|
964
|
+
/** Shared stage config available to all projects. */
|
|
965
|
+
shared?: {
|
|
966
|
+
stages: { [stageName: string]: StageConfig };
|
|
967
|
+
};
|
|
968
|
+
};
|
|
969
|
+
"
|
|
970
|
+
`;
|
|
971
|
+
|
|
972
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated scripts src directory > packages/common/scripts/src/index.ts 1`] = `
|
|
973
|
+
"// Scripts (infra-deploy, infra-destroy) are the public interface of this package.
|
|
974
|
+
"
|
|
975
|
+
`;
|
|
976
|
+
|
|
977
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated scripts src directory > packages/common/scripts/src/infra-deploy.ts 1`] = `
|
|
978
|
+
"import { run } from './stage-credentials/run.js';
|
|
979
|
+
run('deploy');
|
|
980
|
+
"
|
|
981
|
+
`;
|
|
982
|
+
|
|
983
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated scripts src directory > packages/common/scripts/src/infra-destroy.ts 1`] = `
|
|
984
|
+
"import { run } from './stage-credentials/run.js';
|
|
985
|
+
run('destroy');
|
|
986
|
+
"
|
|
987
|
+
`;
|
|
988
|
+
|
|
989
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated scripts src directory > packages/common/scripts/src/stage-credentials/cdk-command.ts 1`] = `
|
|
990
|
+
"/**
|
|
991
|
+
* Builds the CDK command as an array of arguments for spawnSync.
|
|
992
|
+
*
|
|
993
|
+
* Defaults to --require-approval=never (standard for local dev deploys).
|
|
994
|
+
* If the user explicitly passes --require-approval with any value, we
|
|
995
|
+
* respect their choice and don't add the default.
|
|
996
|
+
*/
|
|
997
|
+
export function buildCdkCommand(
|
|
998
|
+
action: string,
|
|
999
|
+
remainingArgs: string[],
|
|
1000
|
+
): string[] {
|
|
1001
|
+
const hasRequireApproval = remainingArgs.some(
|
|
1002
|
+
(a) => a === '--require-approval' || a.startsWith('--require-approval='),
|
|
1003
|
+
);
|
|
1004
|
+
return hasRequireApproval
|
|
1005
|
+
? ['cdk', action, ...remainingArgs]
|
|
1006
|
+
: ['cdk', action, '--require-approval=never', ...remainingArgs];
|
|
1007
|
+
}
|
|
1008
|
+
"
|
|
1009
|
+
`;
|
|
1010
|
+
|
|
1011
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated scripts src directory > packages/common/scripts/src/stage-credentials/credentials.ts 1`] = `
|
|
1012
|
+
"import type { StageCredentials, StagesConfig } from ':proj/common-infra-config';
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Looks up credentials for a given project + stage combination.
|
|
1016
|
+
*
|
|
1017
|
+
* Lookup order:
|
|
1018
|
+
* 1. Project-specific: config.projects[projectPath].stages[stageName].credentials
|
|
1019
|
+
* 2. Shared: config.shared.stages[stageName].credentials
|
|
1020
|
+
* 3. No match: returns undefined — caller falls back to env vars
|
|
1021
|
+
*/
|
|
1022
|
+
export function lookupCredentials(
|
|
1023
|
+
config: StagesConfig | undefined,
|
|
1024
|
+
projectPath: string,
|
|
1025
|
+
stageName: string,
|
|
1026
|
+
): { credentials: StageCredentials | undefined; source: string } {
|
|
1027
|
+
const projectCreds =
|
|
1028
|
+
config?.projects?.[projectPath]?.stages?.[stageName]?.credentials;
|
|
1029
|
+
if (projectCreds) {
|
|
1030
|
+
return { credentials: projectCreds, source: 'project-specific' };
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
const sharedCreds = config?.shared?.stages?.[stageName]?.credentials;
|
|
1034
|
+
if (sharedCreds) {
|
|
1035
|
+
return { credentials: sharedCreds, source: 'shared' };
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
return { credentials: undefined, source: 'environment fallback' };
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
/**
|
|
1042
|
+
* Builds a child process environment with the resolved credentials overlaid.
|
|
1043
|
+
* Never modifies process.env — returns a new object.
|
|
1044
|
+
*/
|
|
1045
|
+
export async function buildChildEnv(
|
|
1046
|
+
credentials: StageCredentials,
|
|
1047
|
+
projectPath: string,
|
|
1048
|
+
): Promise<Record<string, string | undefined>> {
|
|
1049
|
+
const env = { ...process.env };
|
|
1050
|
+
|
|
1051
|
+
switch (credentials.type) {
|
|
1052
|
+
case 'profile': {
|
|
1053
|
+
env.AWS_PROFILE = credentials.profile;
|
|
1054
|
+
break;
|
|
1055
|
+
}
|
|
1056
|
+
case 'assumeRole': {
|
|
1057
|
+
let STSClient: typeof import('@aws-sdk/client-sts').STSClient;
|
|
1058
|
+
let AssumeRoleCommand: typeof import('@aws-sdk/client-sts').AssumeRoleCommand;
|
|
1059
|
+
try {
|
|
1060
|
+
({ STSClient, AssumeRoleCommand } =
|
|
1061
|
+
await import('@aws-sdk/client-sts'));
|
|
1062
|
+
} catch {
|
|
1063
|
+
console.error(
|
|
1064
|
+
'[infra-deploy] Error: @aws-sdk/client-sts is required for assumeRole credentials but is not installed.',
|
|
1065
|
+
);
|
|
1066
|
+
console.error('[infra-deploy] Please install @aws-sdk/client-sts');
|
|
1067
|
+
process.exit(1);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
// If a source profile is specified, configure the STS client to use it
|
|
1071
|
+
const stsClientOptions: Record<string, unknown> = {};
|
|
1072
|
+
if (credentials.profile) {
|
|
1073
|
+
const { fromIni } = await import('@aws-sdk/credential-providers');
|
|
1074
|
+
stsClientOptions.credentials = fromIni({
|
|
1075
|
+
profile: credentials.profile,
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
const response = await new STSClient(stsClientOptions).send(
|
|
1080
|
+
new AssumeRoleCommand({
|
|
1081
|
+
RoleArn: credentials.assumeRole,
|
|
1082
|
+
RoleSessionName: \`infra-deploy-\${projectPath.replace(/\\//g, '-')}\`,
|
|
1083
|
+
...(credentials.externalId
|
|
1084
|
+
? { ExternalId: credentials.externalId }
|
|
1085
|
+
: {}),
|
|
1086
|
+
...(credentials.sessionDuration
|
|
1087
|
+
? { DurationSeconds: credentials.sessionDuration }
|
|
1088
|
+
: {}),
|
|
1089
|
+
}),
|
|
1090
|
+
);
|
|
1091
|
+
|
|
1092
|
+
env.AWS_ACCESS_KEY_ID = response.Credentials?.AccessKeyId;
|
|
1093
|
+
env.AWS_SECRET_ACCESS_KEY = response.Credentials?.SecretAccessKey;
|
|
1094
|
+
env.AWS_SESSION_TOKEN = response.Credentials?.SessionToken;
|
|
1095
|
+
delete env.AWS_PROFILE;
|
|
1096
|
+
break;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
return env;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
/** Human-readable description of credentials for logging */
|
|
1104
|
+
export function describeCredentials(creds: StageCredentials): string {
|
|
1105
|
+
return creds.type === 'profile'
|
|
1106
|
+
? \`profile '\${creds.profile}'\`
|
|
1107
|
+
: \`role '\${creds.assumeRole}'\`;
|
|
1108
|
+
}
|
|
1109
|
+
"
|
|
1110
|
+
`;
|
|
1111
|
+
|
|
1112
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated scripts src directory > packages/common/scripts/src/stage-credentials/run.ts 1`] = `
|
|
1113
|
+
"import { spawnSync } from 'child_process';
|
|
1114
|
+
import stagesConfig from ':proj/common-infra-config';
|
|
1115
|
+
import { parseStageName } from './stage-parser.js';
|
|
1116
|
+
import {
|
|
1117
|
+
lookupCredentials,
|
|
1118
|
+
buildChildEnv,
|
|
1119
|
+
describeCredentials,
|
|
1120
|
+
} from './credentials.js';
|
|
1121
|
+
import { buildCdkCommand } from './cdk-command.js';
|
|
1122
|
+
|
|
1123
|
+
const log = (msg: string) => console.error(\`[infra-deploy] \${msg}\`);
|
|
1124
|
+
|
|
1125
|
+
export async function run(action: 'deploy' | 'destroy'): Promise<void> {
|
|
1126
|
+
const [projectPath, ...remainingArgs] = process.argv.slice(2);
|
|
1127
|
+
|
|
1128
|
+
if (!projectPath) {
|
|
1129
|
+
log(\`Usage: infra-\${action} <project-path> [stage/*] [cdk-args...]\`);
|
|
1130
|
+
process.exit(1);
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
const stageName = parseStageName(remainingArgs[0]);
|
|
1134
|
+
let childEnv: Record<string, string | undefined> = { ...process.env };
|
|
1135
|
+
|
|
1136
|
+
if (stageName) {
|
|
1137
|
+
const { credentials, source } = lookupCredentials(
|
|
1138
|
+
stagesConfig,
|
|
1139
|
+
projectPath,
|
|
1140
|
+
stageName,
|
|
1141
|
+
);
|
|
1142
|
+
|
|
1143
|
+
if (credentials) {
|
|
1144
|
+
log(
|
|
1145
|
+
\`Using \${describeCredentials(credentials)} for '\${stageName}' (\${source})\`,
|
|
1146
|
+
);
|
|
1147
|
+
childEnv = await buildChildEnv(credentials, projectPath);
|
|
1148
|
+
} else {
|
|
1149
|
+
log(\`No credentials for '\${stageName}' — using environment\`);
|
|
1150
|
+
}
|
|
1151
|
+
} else {
|
|
1152
|
+
log('No stage specified — using environment credentials');
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
// Run CDK from the project directory so it finds cdk.json
|
|
1156
|
+
const cmd = buildCdkCommand(action, remainingArgs);
|
|
1157
|
+
const { status } = spawnSync(cmd[0], cmd.slice(1), {
|
|
1158
|
+
stdio: 'inherit',
|
|
1159
|
+
env: childEnv,
|
|
1160
|
+
cwd: projectPath,
|
|
1161
|
+
});
|
|
1162
|
+
|
|
1163
|
+
process.exit(status ?? 1);
|
|
1164
|
+
}
|
|
1165
|
+
"
|
|
1166
|
+
`;
|
|
1167
|
+
|
|
1168
|
+
exports[`infra generator > with enableStageConfig > should snapshot generated scripts src directory > packages/common/scripts/src/stage-credentials/stage-parser.ts 1`] = `
|
|
1169
|
+
"/**
|
|
1170
|
+
* Extracts the CDK stage name from the first positional argument.
|
|
1171
|
+
*
|
|
1172
|
+
* Examples:
|
|
1173
|
+
* parseStageName('my-app-dev/*') → 'my-app-dev'
|
|
1174
|
+
* parseStageName('my-app-dev') → 'my-app-dev'
|
|
1175
|
+
* parseStageName('--verbose') → undefined (flag, not a stage)
|
|
1176
|
+
* parseStageName(undefined) → undefined
|
|
1177
|
+
*/
|
|
1178
|
+
export function parseStageName(
|
|
1179
|
+
firstArg: string | undefined,
|
|
1180
|
+
): string | undefined {
|
|
1181
|
+
if (!firstArg || firstArg.startsWith('-')) return undefined;
|
|
1182
|
+
return firstArg.includes('/') ? firstArg.split('/')[0] : firstArg;
|
|
1183
|
+
}
|
|
1184
|
+
"
|
|
1185
|
+
`;
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import { ApplicationStage } from './stages/application-stage.js';
|
|
2
2
|
import { App } from '<%= scopeAlias %>common-constructs';
|
|
3
|
-
|
|
3
|
+
<% if (enableStageConfig) { %>import { resolveStage } from '<%= scopeAlias %>common-infra-config';
|
|
4
|
+
<% } %>
|
|
4
5
|
const app = new App();
|
|
6
|
+
<% if (enableStageConfig) { %>
|
|
7
|
+
// Stage configuration is defined in packages/common/infra-config/src/stages.config.ts
|
|
8
|
+
// The project path '<%= dir %>' is used as the key in the config.
|
|
9
|
+
// Project-specific settings override shared settings for the same stage name.
|
|
5
10
|
|
|
11
|
+
// Sandbox stage — uses your CLI credentials by default.
|
|
12
|
+
// Add an entry in stages.config.ts to configure specific credentials.
|
|
13
|
+
const sandboxConfig = resolveStage('<%= dir %>', '<%= namespace %>-sandbox');
|
|
14
|
+
new ApplicationStage(app, '<%= namespace %>-sandbox', {
|
|
15
|
+
env: {
|
|
16
|
+
account: sandboxConfig?.account ?? process.env.CDK_DEFAULT_ACCOUNT,
|
|
17
|
+
region: sandboxConfig?.region ?? process.env.CDK_DEFAULT_REGION,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
<% } else { %>
|
|
6
21
|
// Use this to deploy your own sandbox environment (assumes your CLI credentials)
|
|
7
22
|
new ApplicationStage(app, '<%= namespace %>-sandbox', {
|
|
8
23
|
env: {
|
|
@@ -10,5 +25,5 @@ new ApplicationStage(app, '<%= namespace %>-sandbox', {
|
|
|
10
25
|
region: process.env.CDK_DEFAULT_REGION,
|
|
11
26
|
},
|
|
12
27
|
});
|
|
13
|
-
|
|
28
|
+
<% } %>
|
|
14
29
|
app.synth();
|
|
@@ -12,6 +12,8 @@ const generator_1 = tslib_1.__importStar(require("../../ts/lib/generator"));
|
|
|
12
12
|
const versions_1 = require("../../utils/versions");
|
|
13
13
|
const npm_scope_1 = require("../../utils/npm-scope");
|
|
14
14
|
const shared_constructs_1 = require("../../utils/shared-constructs");
|
|
15
|
+
const shared_infra_config_1 = require("../../utils/shared-infra-config");
|
|
16
|
+
const shared_scripts_1 = require("../../utils/shared-scripts");
|
|
15
17
|
const shared_constructs_constants_1 = require("../../utils/shared-constructs-constants");
|
|
16
18
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
17
19
|
const format_1 = require("../../utils/format");
|
|
@@ -23,6 +25,7 @@ const py_1 = require("../../utils/py");
|
|
|
23
25
|
exports.INFRA_APP_GENERATOR_INFO = (0, nx_1.getGeneratorInfo)(__filename);
|
|
24
26
|
function tsInfraGenerator(tree, schema) {
|
|
25
27
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
var _a;
|
|
26
29
|
const lib = (0, generator_1.getTsLibDetails)(tree, schema);
|
|
27
30
|
yield (0, generator_1.default)(tree, schema);
|
|
28
31
|
(0, nx_1.addGeneratorMetadata)(tree, lib.fullyQualifiedName, exports.INFRA_APP_GENERATOR_INFO);
|
|
@@ -30,6 +33,13 @@ function tsInfraGenerator(tree, schema) {
|
|
|
30
33
|
yield (0, shared_constructs_1.sharedConstructsGenerator)(tree, {
|
|
31
34
|
iacProvider: 'CDK',
|
|
32
35
|
});
|
|
36
|
+
// Shared infra-config and infra-scripts packages (lazy creation, only when enabled)
|
|
37
|
+
const enableStageConfig = (_a = schema.enableStageConfig) !== null && _a !== void 0 ? _a : false;
|
|
38
|
+
if (enableStageConfig) {
|
|
39
|
+
yield (0, shared_infra_config_1.sharedInfraConfigGenerator)(tree);
|
|
40
|
+
yield (0, shared_scripts_1.sharedScriptsGenerator)(tree);
|
|
41
|
+
}
|
|
42
|
+
const synthDirFromRoot = `/dist/${lib.dir}/cdk.out`;
|
|
33
43
|
const synthDirFromProject = lib.dir
|
|
34
44
|
.split('/')
|
|
35
45
|
.map(() => '..')
|
|
@@ -46,7 +56,7 @@ function tsInfraGenerator(tree, schema) {
|
|
|
46
56
|
tree.delete((0, devkit_1.joinPathFragments)(libraryRoot, 'src'));
|
|
47
57
|
(0, devkit_1.generateFiles)(tree, // the virtual file system
|
|
48
58
|
(0, devkit_1.joinPathFragments)(__dirname, './files/app'), // path to the file templates
|
|
49
|
-
libraryRoot, Object.assign({ synthDir: synthDirFromProject, scopeAlias: scopeAlias, namespace: (0, names_1.kebabCase)(fullyQualifiedName), fullyQualifiedName, pkgMgrCmd: (0, devkit_1.getPackageManagerCommand)().exec, dir: lib.dir }, schema), {
|
|
59
|
+
libraryRoot, Object.assign({ synthDir: synthDirFromProject, scopeAlias: scopeAlias, namespace: (0, names_1.kebabCase)(fullyQualifiedName), fullyQualifiedName, pkgMgrCmd: (0, devkit_1.getPackageManagerCommand)().exec, dir: lib.dir, enableStageConfig }, schema), {
|
|
50
60
|
overwriteStrategy: devkit_1.OverwriteStrategy.Overwrite,
|
|
51
61
|
});
|
|
52
62
|
(0, devkit_1.updateJson)(tree, `${libraryRoot}/project.json`, (config) => {
|
|
@@ -84,10 +94,14 @@ function tsInfraGenerator(tree, schema) {
|
|
|
84
94
|
config.targets.deploy = {
|
|
85
95
|
executor: 'nx:run-commands',
|
|
86
96
|
dependsOn: ['^build', 'compile'],
|
|
87
|
-
options:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
97
|
+
options: enableStageConfig
|
|
98
|
+
? {
|
|
99
|
+
command: `tsx packages/common/scripts/src/infra-deploy.ts ${libraryRoot}`,
|
|
100
|
+
}
|
|
101
|
+
: {
|
|
102
|
+
cwd: '{projectRoot}',
|
|
103
|
+
command: 'cdk deploy --require-approval=never',
|
|
104
|
+
},
|
|
91
105
|
};
|
|
92
106
|
config.targets['deploy-ci'] = {
|
|
93
107
|
executor: 'nx:run-commands',
|
|
@@ -99,10 +113,14 @@ function tsInfraGenerator(tree, schema) {
|
|
|
99
113
|
config.targets.destroy = {
|
|
100
114
|
executor: 'nx:run-commands',
|
|
101
115
|
dependsOn: ['^build', 'compile'],
|
|
102
|
-
options:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
116
|
+
options: enableStageConfig
|
|
117
|
+
? {
|
|
118
|
+
command: `tsx packages/common/scripts/src/infra-destroy.ts ${libraryRoot}`,
|
|
119
|
+
}
|
|
120
|
+
: {
|
|
121
|
+
cwd: '{projectRoot}',
|
|
122
|
+
command: 'cdk destroy --require-approval=never',
|
|
123
|
+
},
|
|
106
124
|
};
|
|
107
125
|
config.targets['destroy-ci'] = {
|
|
108
126
|
executor: 'nx:run-commands',
|
|
@@ -140,6 +158,13 @@ function tsInfraGenerator(tree, schema) {
|
|
|
140
158
|
{
|
|
141
159
|
path: `${path_1.default.relative(libraryRoot, `${tree.root}/${shared_constructs_constants_1.PACKAGES_DIR}`)}/${shared_constructs_constants_1.SHARED_CONSTRUCTS_DIR}/tsconfig.lib.json`,
|
|
142
160
|
},
|
|
161
|
+
...(enableStageConfig
|
|
162
|
+
? [
|
|
163
|
+
{
|
|
164
|
+
path: `${path_1.default.relative(libraryRoot, `${tree.root}/${shared_constructs_constants_1.PACKAGES_DIR}`)}/${shared_constructs_constants_1.SHARED_INFRA_CONFIG_DIR}/tsconfig.json`,
|
|
165
|
+
},
|
|
166
|
+
]
|
|
167
|
+
: []),
|
|
143
168
|
] })));
|
|
144
169
|
yield (0, metrics_1.addGeneratorMetricsIfApplicable)(tree, [exports.INFRA_APP_GENERATOR_INFO]);
|
|
145
170
|
yield (0, format_1.formatFilesInSubtree)(tree);
|