@friggframework/devtools 2.0.0-next.44 → 2.0.0-next.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/infrastructure/ARCHITECTURE.md +487 -0
  2. package/infrastructure/HEALTH.md +468 -0
  3. package/infrastructure/README.md +51 -0
  4. package/infrastructure/__tests__/postgres-config.test.js +914 -0
  5. package/infrastructure/__tests__/template-generation.test.js +687 -0
  6. package/infrastructure/create-frigg-infrastructure.js +1 -1
  7. package/infrastructure/docs/POSTGRES-CONFIGURATION.md +630 -0
  8. package/infrastructure/{DEPLOYMENT-INSTRUCTIONS.md → docs/deployment-instructions.md} +3 -3
  9. package/infrastructure/{IAM-POLICY-TEMPLATES.md → docs/iam-policy-templates.md} +9 -10
  10. package/infrastructure/domains/database/aurora-builder.js +809 -0
  11. package/infrastructure/domains/database/aurora-builder.test.js +950 -0
  12. package/infrastructure/domains/database/aurora-discovery.js +87 -0
  13. package/infrastructure/domains/database/aurora-discovery.test.js +188 -0
  14. package/infrastructure/domains/database/aurora-resolver.js +210 -0
  15. package/infrastructure/domains/database/aurora-resolver.test.js +347 -0
  16. package/infrastructure/domains/database/migration-builder.js +633 -0
  17. package/infrastructure/domains/database/migration-builder.test.js +294 -0
  18. package/infrastructure/domains/database/migration-resolver.js +163 -0
  19. package/infrastructure/domains/database/migration-resolver.test.js +337 -0
  20. package/infrastructure/domains/health/application/ports/IPropertyReconciler.js +164 -0
  21. package/infrastructure/domains/health/application/ports/IResourceDetector.js +129 -0
  22. package/infrastructure/domains/health/application/ports/IResourceImporter.js +142 -0
  23. package/infrastructure/domains/health/application/ports/IStackRepository.js +131 -0
  24. package/infrastructure/domains/health/application/ports/index.js +26 -0
  25. package/infrastructure/domains/health/application/use-cases/__tests__/execute-resource-import-use-case.test.js +679 -0
  26. package/infrastructure/domains/health/application/use-cases/__tests__/mismatch-analyzer-method-name.test.js +167 -0
  27. package/infrastructure/domains/health/application/use-cases/__tests__/repair-via-import-use-case.test.js +1130 -0
  28. package/infrastructure/domains/health/application/use-cases/execute-resource-import-use-case.js +221 -0
  29. package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.js +152 -0
  30. package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.test.js +343 -0
  31. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.js +535 -0
  32. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.test.js +376 -0
  33. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.js +213 -0
  34. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.test.js +441 -0
  35. package/infrastructure/domains/health/docs/ACME-DEV-DRIFT-ANALYSIS.md +267 -0
  36. package/infrastructure/domains/health/docs/BUILD-VS-DEPLOYED-TEMPLATE-ANALYSIS.md +324 -0
  37. package/infrastructure/domains/health/docs/ORPHAN-DETECTION-ANALYSIS.md +386 -0
  38. package/infrastructure/domains/health/docs/SPEC-CLEANUP-COMMAND.md +1419 -0
  39. package/infrastructure/domains/health/docs/TDD-IMPLEMENTATION-SUMMARY.md +391 -0
  40. package/infrastructure/domains/health/docs/TEMPLATE-COMPARISON-IMPLEMENTATION.md +551 -0
  41. package/infrastructure/domains/health/domain/entities/issue.js +299 -0
  42. package/infrastructure/domains/health/domain/entities/issue.test.js +528 -0
  43. package/infrastructure/domains/health/domain/entities/property-mismatch.js +108 -0
  44. package/infrastructure/domains/health/domain/entities/property-mismatch.test.js +275 -0
  45. package/infrastructure/domains/health/domain/entities/resource.js +159 -0
  46. package/infrastructure/domains/health/domain/entities/resource.test.js +432 -0
  47. package/infrastructure/domains/health/domain/entities/stack-health-report.js +306 -0
  48. package/infrastructure/domains/health/domain/entities/stack-health-report.test.js +601 -0
  49. package/infrastructure/domains/health/domain/services/__tests__/health-score-percentage-based.test.js +380 -0
  50. package/infrastructure/domains/health/domain/services/__tests__/import-progress-monitor.test.js +971 -0
  51. package/infrastructure/domains/health/domain/services/__tests__/import-template-generator.test.js +1150 -0
  52. package/infrastructure/domains/health/domain/services/__tests__/logical-id-mapper.test.js +672 -0
  53. package/infrastructure/domains/health/domain/services/__tests__/template-parser.test.js +496 -0
  54. package/infrastructure/domains/health/domain/services/__tests__/update-progress-monitor.test.js +419 -0
  55. package/infrastructure/domains/health/domain/services/health-score-calculator.js +248 -0
  56. package/infrastructure/domains/health/domain/services/health-score-calculator.test.js +504 -0
  57. package/infrastructure/domains/health/domain/services/import-progress-monitor.js +195 -0
  58. package/infrastructure/domains/health/domain/services/import-template-generator.js +435 -0
  59. package/infrastructure/domains/health/domain/services/logical-id-mapper.js +345 -0
  60. package/infrastructure/domains/health/domain/services/mismatch-analyzer.js +234 -0
  61. package/infrastructure/domains/health/domain/services/mismatch-analyzer.test.js +431 -0
  62. package/infrastructure/domains/health/domain/services/property-mutability-config.js +382 -0
  63. package/infrastructure/domains/health/domain/services/template-parser.js +245 -0
  64. package/infrastructure/domains/health/domain/services/update-progress-monitor.js +192 -0
  65. package/infrastructure/domains/health/domain/value-objects/health-score.js +138 -0
  66. package/infrastructure/domains/health/domain/value-objects/health-score.test.js +267 -0
  67. package/infrastructure/domains/health/domain/value-objects/property-mutability.js +161 -0
  68. package/infrastructure/domains/health/domain/value-objects/property-mutability.test.js +198 -0
  69. package/infrastructure/domains/health/domain/value-objects/resource-state.js +167 -0
  70. package/infrastructure/domains/health/domain/value-objects/resource-state.test.js +196 -0
  71. package/infrastructure/domains/health/domain/value-objects/stack-identifier.js +192 -0
  72. package/infrastructure/domains/health/domain/value-objects/stack-identifier.test.js +262 -0
  73. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-cfn-tagged.test.js +312 -0
  74. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-multi-stack.test.js +367 -0
  75. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-relationship-analysis.test.js +432 -0
  76. package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.js +784 -0
  77. package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.test.js +1133 -0
  78. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.js +565 -0
  79. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.test.js +554 -0
  80. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.js +318 -0
  81. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.test.js +398 -0
  82. package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.js +777 -0
  83. package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.test.js +580 -0
  84. package/infrastructure/domains/integration/integration-builder.js +397 -0
  85. package/infrastructure/domains/integration/integration-builder.test.js +593 -0
  86. package/infrastructure/domains/integration/integration-resolver.js +170 -0
  87. package/infrastructure/domains/integration/integration-resolver.test.js +369 -0
  88. package/infrastructure/domains/integration/websocket-builder.js +69 -0
  89. package/infrastructure/domains/integration/websocket-builder.test.js +195 -0
  90. package/infrastructure/domains/networking/vpc-builder.js +1829 -0
  91. package/infrastructure/domains/networking/vpc-builder.test.js +1262 -0
  92. package/infrastructure/domains/networking/vpc-discovery.js +177 -0
  93. package/infrastructure/domains/networking/vpc-discovery.test.js +350 -0
  94. package/infrastructure/domains/networking/vpc-resolver.js +324 -0
  95. package/infrastructure/domains/networking/vpc-resolver.test.js +501 -0
  96. package/infrastructure/domains/parameters/ssm-builder.js +79 -0
  97. package/infrastructure/domains/parameters/ssm-builder.test.js +189 -0
  98. package/infrastructure/domains/parameters/ssm-discovery.js +84 -0
  99. package/infrastructure/domains/parameters/ssm-discovery.test.js +210 -0
  100. package/infrastructure/{iam-generator.js → domains/security/iam-generator.js} +2 -2
  101. package/infrastructure/domains/security/kms-builder.js +366 -0
  102. package/infrastructure/domains/security/kms-builder.test.js +374 -0
  103. package/infrastructure/domains/security/kms-discovery.js +80 -0
  104. package/infrastructure/domains/security/kms-discovery.test.js +177 -0
  105. package/infrastructure/domains/security/kms-resolver.js +96 -0
  106. package/infrastructure/domains/security/kms-resolver.test.js +216 -0
  107. package/infrastructure/domains/shared/base-builder.js +112 -0
  108. package/infrastructure/domains/shared/base-resolver.js +186 -0
  109. package/infrastructure/domains/shared/base-resolver.test.js +305 -0
  110. package/infrastructure/domains/shared/builder-orchestrator.js +212 -0
  111. package/infrastructure/domains/shared/builder-orchestrator.test.js +213 -0
  112. package/infrastructure/domains/shared/cloudformation-discovery-v2.js +334 -0
  113. package/infrastructure/domains/shared/cloudformation-discovery.js +375 -0
  114. package/infrastructure/domains/shared/cloudformation-discovery.test.js +590 -0
  115. package/infrastructure/domains/shared/environment-builder.js +119 -0
  116. package/infrastructure/domains/shared/environment-builder.test.js +247 -0
  117. package/infrastructure/domains/shared/providers/aws-provider-adapter.js +544 -0
  118. package/infrastructure/domains/shared/providers/aws-provider-adapter.test.js +377 -0
  119. package/infrastructure/domains/shared/providers/azure-provider-adapter.stub.js +93 -0
  120. package/infrastructure/domains/shared/providers/cloud-provider-adapter.js +136 -0
  121. package/infrastructure/domains/shared/providers/gcp-provider-adapter.stub.js +82 -0
  122. package/infrastructure/domains/shared/providers/provider-factory.js +108 -0
  123. package/infrastructure/domains/shared/providers/provider-factory.test.js +170 -0
  124. package/infrastructure/domains/shared/resource-discovery.js +192 -0
  125. package/infrastructure/domains/shared/resource-discovery.test.js +552 -0
  126. package/infrastructure/domains/shared/types/app-definition.js +205 -0
  127. package/infrastructure/domains/shared/types/discovery-result.js +106 -0
  128. package/infrastructure/domains/shared/types/discovery-result.test.js +258 -0
  129. package/infrastructure/domains/shared/types/index.js +46 -0
  130. package/infrastructure/domains/shared/types/resource-ownership.js +108 -0
  131. package/infrastructure/domains/shared/types/resource-ownership.test.js +101 -0
  132. package/infrastructure/domains/shared/utilities/base-definition-factory.js +380 -0
  133. package/infrastructure/domains/shared/utilities/base-definition-factory.js.bak +338 -0
  134. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +248 -0
  135. package/infrastructure/domains/shared/utilities/handler-path-resolver.js +134 -0
  136. package/infrastructure/domains/shared/utilities/handler-path-resolver.test.js +268 -0
  137. package/infrastructure/domains/shared/utilities/prisma-layer-manager.js +55 -0
  138. package/infrastructure/domains/shared/utilities/prisma-layer-manager.test.js +138 -0
  139. package/infrastructure/{env-validator.js → domains/shared/validation/env-validator.js} +2 -1
  140. package/infrastructure/domains/shared/validation/env-validator.test.js +173 -0
  141. package/infrastructure/esbuild.config.js +53 -0
  142. package/infrastructure/infrastructure-composer.js +87 -0
  143. package/infrastructure/{serverless-template.test.js → infrastructure-composer.test.js} +115 -24
  144. package/infrastructure/scripts/build-prisma-layer.js +553 -0
  145. package/infrastructure/scripts/build-prisma-layer.test.js +102 -0
  146. package/infrastructure/{build-time-discovery.js → scripts/build-time-discovery.js} +80 -48
  147. package/infrastructure/{build-time-discovery.test.js → scripts/build-time-discovery.test.js} +5 -4
  148. package/layers/prisma/nodejs/package.json +8 -0
  149. package/management-ui/server/utils/cliIntegration.js +1 -1
  150. package/management-ui/server/utils/environment/awsParameterStore.js +29 -18
  151. package/package.json +11 -11
  152. package/frigg-cli/.eslintrc.js +0 -141
  153. package/frigg-cli/__tests__/unit/commands/build.test.js +0 -251
  154. package/frigg-cli/__tests__/unit/commands/db-setup.test.js +0 -548
  155. package/frigg-cli/__tests__/unit/commands/install.test.js +0 -400
  156. package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -346
  157. package/frigg-cli/__tests__/unit/utils/database-validator.test.js +0 -366
  158. package/frigg-cli/__tests__/unit/utils/error-messages.test.js +0 -304
  159. package/frigg-cli/__tests__/unit/utils/prisma-runner.test.js +0 -486
  160. package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
  161. package/frigg-cli/__tests__/utils/prisma-mock.js +0 -194
  162. package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
  163. package/frigg-cli/__tests__/utils/test-setup.js +0 -287
  164. package/frigg-cli/build-command/index.js +0 -65
  165. package/frigg-cli/db-setup-command/index.js +0 -193
  166. package/frigg-cli/deploy-command/index.js +0 -175
  167. package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -301
  168. package/frigg-cli/generate-command/azure-generator.js +0 -43
  169. package/frigg-cli/generate-command/gcp-generator.js +0 -47
  170. package/frigg-cli/generate-command/index.js +0 -332
  171. package/frigg-cli/generate-command/terraform-generator.js +0 -555
  172. package/frigg-cli/generate-iam-command.js +0 -118
  173. package/frigg-cli/index.js +0 -75
  174. package/frigg-cli/index.test.js +0 -158
  175. package/frigg-cli/init-command/backend-first-handler.js +0 -756
  176. package/frigg-cli/init-command/index.js +0 -93
  177. package/frigg-cli/init-command/template-handler.js +0 -143
  178. package/frigg-cli/install-command/backend-js.js +0 -33
  179. package/frigg-cli/install-command/commit-changes.js +0 -16
  180. package/frigg-cli/install-command/environment-variables.js +0 -127
  181. package/frigg-cli/install-command/environment-variables.test.js +0 -136
  182. package/frigg-cli/install-command/index.js +0 -54
  183. package/frigg-cli/install-command/install-package.js +0 -13
  184. package/frigg-cli/install-command/integration-file.js +0 -30
  185. package/frigg-cli/install-command/logger.js +0 -12
  186. package/frigg-cli/install-command/template.js +0 -90
  187. package/frigg-cli/install-command/validate-package.js +0 -75
  188. package/frigg-cli/jest.config.js +0 -124
  189. package/frigg-cli/package.json +0 -54
  190. package/frigg-cli/start-command/index.js +0 -149
  191. package/frigg-cli/start-command/start-command.test.js +0 -297
  192. package/frigg-cli/test/init-command.test.js +0 -180
  193. package/frigg-cli/test/npm-registry.test.js +0 -319
  194. package/frigg-cli/ui-command/index.js +0 -154
  195. package/frigg-cli/utils/app-resolver.js +0 -319
  196. package/frigg-cli/utils/backend-path.js +0 -25
  197. package/frigg-cli/utils/database-validator.js +0 -161
  198. package/frigg-cli/utils/error-messages.js +0 -257
  199. package/frigg-cli/utils/npm-registry.js +0 -167
  200. package/frigg-cli/utils/prisma-runner.js +0 -280
  201. package/frigg-cli/utils/process-manager.js +0 -199
  202. package/frigg-cli/utils/repo-detection.js +0 -405
  203. package/infrastructure/aws-discovery.js +0 -1176
  204. package/infrastructure/aws-discovery.test.js +0 -1220
  205. package/infrastructure/serverless-template.js +0 -2074
  206. /package/infrastructure/{WEBSOCKET-CONFIGURATION.md → docs/WEBSOCKET-CONFIGURATION.md} +0 -0
  207. /package/infrastructure/{GENERATE-IAM-DOCS.md → docs/generate-iam-command.md} +0 -0
  208. /package/infrastructure/{iam-generator.test.js → domains/security/iam-generator.test.js} +0 -0
  209. /package/infrastructure/{frigg-deployment-iam-stack.yaml → domains/security/templates/frigg-deployment-iam-stack.yaml} +0 -0
  210. /package/infrastructure/{iam-policy-basic.json → domains/security/templates/iam-policy-basic.json} +0 -0
  211. /package/infrastructure/{iam-policy-full.json → domains/security/templates/iam-policy-full.json} +0 -0
  212. /package/infrastructure/{run-discovery.js → scripts/run-discovery.js} +0 -0
@@ -0,0 +1,544 @@
1
+ /**
2
+ * AWS Provider Adapter
3
+ *
4
+ * Adapter - Hexagonal Architecture
5
+ *
6
+ * Implements CloudProviderAdapter interface for Amazon Web Services.
7
+ * Handles AWS-specific resource discovery using AWS SDK v3.
8
+ *
9
+ * This adapter lazy-loads AWS SDK clients to minimize cold start time
10
+ * and memory usage when not all discovery features are needed.
11
+ */
12
+
13
+ const { CloudProviderAdapter } = require('./cloud-provider-adapter');
14
+
15
+ // Lazy-loaded AWS SDK clients
16
+ let EC2Client, DescribeVpcsCommand, DescribeSubnetsCommand, DescribeSecurityGroupsCommand,
17
+ DescribeRouteTablesCommand, DescribeNatGatewaysCommand, DescribeInternetGatewaysCommand,
18
+ DescribeVpcEndpointsCommand;
19
+ let KMSClient, ListKeysCommand, DescribeKeyCommand, ListAliasesCommand;
20
+ let RDSClient, DescribeDBClustersCommand, DescribeDBInstancesCommand;
21
+ let SSMClient, GetParameterCommand, GetParametersByPathCommand;
22
+ let SecretsManagerClient, ListSecretsCommand, GetSecretValueCommand;
23
+ let CloudFormationClient, DescribeStacksCommand, ListStackResourcesCommand;
24
+
25
+ /**
26
+ * Lazy load EC2 SDK
27
+ */
28
+ function loadEC2() {
29
+ if (!EC2Client) {
30
+ const ec2Module = require('@aws-sdk/client-ec2');
31
+ EC2Client = ec2Module.EC2Client;
32
+ DescribeVpcsCommand = ec2Module.DescribeVpcsCommand;
33
+ DescribeSubnetsCommand = ec2Module.DescribeSubnetsCommand;
34
+ DescribeSecurityGroupsCommand = ec2Module.DescribeSecurityGroupsCommand;
35
+ DescribeRouteTablesCommand = ec2Module.DescribeRouteTablesCommand;
36
+ DescribeNatGatewaysCommand = ec2Module.DescribeNatGatewaysCommand;
37
+ DescribeInternetGatewaysCommand = ec2Module.DescribeInternetGatewaysCommand;
38
+ DescribeVpcEndpointsCommand = ec2Module.DescribeVpcEndpointsCommand;
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Lazy load KMS SDK
44
+ */
45
+ function loadKMS() {
46
+ if (!KMSClient) {
47
+ const kmsModule = require('@aws-sdk/client-kms');
48
+ KMSClient = kmsModule.KMSClient;
49
+ ListKeysCommand = kmsModule.ListKeysCommand;
50
+ DescribeKeyCommand = kmsModule.DescribeKeyCommand;
51
+ ListAliasesCommand = kmsModule.ListAliasesCommand;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Lazy load RDS SDK
57
+ */
58
+ function loadRDS() {
59
+ if (!RDSClient) {
60
+ const rdsModule = require('@aws-sdk/client-rds');
61
+ RDSClient = rdsModule.RDSClient;
62
+ DescribeDBClustersCommand = rdsModule.DescribeDBClustersCommand;
63
+ DescribeDBInstancesCommand = rdsModule.DescribeDBInstancesCommand;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Lazy load SSM SDK
69
+ */
70
+ function loadSSM() {
71
+ if (!SSMClient) {
72
+ const ssmModule = require('@aws-sdk/client-ssm');
73
+ SSMClient = ssmModule.SSMClient;
74
+ GetParameterCommand = ssmModule.GetParameterCommand;
75
+ GetParametersByPathCommand = ssmModule.GetParametersByPathCommand;
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Lazy load Secrets Manager SDK
81
+ */
82
+ function loadSecretsManager() {
83
+ if (!SecretsManagerClient) {
84
+ const smModule = require('@aws-sdk/client-secrets-manager');
85
+ SecretsManagerClient = smModule.SecretsManagerClient;
86
+ ListSecretsCommand = smModule.ListSecretsCommand;
87
+ GetSecretValueCommand = smModule.GetSecretValueCommand;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Lazy load CloudFormation SDK
93
+ */
94
+ function loadCloudFormation() {
95
+ if (!CloudFormationClient) {
96
+ const cfModule = require('@aws-sdk/client-cloudformation');
97
+ CloudFormationClient = cfModule.CloudFormationClient;
98
+ DescribeStacksCommand = cfModule.DescribeStacksCommand;
99
+ ListStackResourcesCommand = cfModule.ListStackResourcesCommand;
100
+ }
101
+ }
102
+
103
+ class AWSProviderAdapter extends CloudProviderAdapter {
104
+ constructor(region, credentials = {}) {
105
+ super();
106
+ this.region = region || process.env.AWS_REGION || 'us-east-1';
107
+ this.credentials = credentials;
108
+
109
+ // Initialize clients as null - will be lazy loaded
110
+ this.ec2 = null;
111
+ this.kms = null;
112
+ this.rds = null;
113
+ this.ssm = null;
114
+ this.secretsManager = null;
115
+ this.cloudformation = null;
116
+ }
117
+
118
+ /**
119
+ * Get EC2 client (lazy loaded)
120
+ */
121
+ getEC2Client() {
122
+ if (!this.ec2) {
123
+ loadEC2();
124
+ this.ec2 = new EC2Client({
125
+ region: this.region,
126
+ ...this.credentials,
127
+ });
128
+ }
129
+ return this.ec2;
130
+ }
131
+
132
+ /**
133
+ * Get KMS client (lazy loaded)
134
+ */
135
+ getKMSClient() {
136
+ if (!this.kms) {
137
+ loadKMS();
138
+ this.kms = new KMSClient({
139
+ region: this.region,
140
+ ...this.credentials,
141
+ });
142
+ }
143
+ return this.kms;
144
+ }
145
+
146
+ /**
147
+ * Get RDS client (lazy loaded)
148
+ */
149
+ getRDSClient() {
150
+ if (!this.rds) {
151
+ loadRDS();
152
+ this.rds = new RDSClient({
153
+ region: this.region,
154
+ ...this.credentials,
155
+ });
156
+ }
157
+ return this.rds;
158
+ }
159
+
160
+ /**
161
+ * Get SSM client (lazy loaded)
162
+ */
163
+ getSSMClient() {
164
+ if (!this.ssm) {
165
+ loadSSM();
166
+ this.ssm = new SSMClient({
167
+ region: this.region,
168
+ ...this.credentials,
169
+ });
170
+ }
171
+ return this.ssm;
172
+ }
173
+
174
+ /**
175
+ * Get Secrets Manager client (lazy loaded)
176
+ */
177
+ getSecretsManagerClient() {
178
+ if (!this.secretsManager) {
179
+ loadSecretsManager();
180
+ this.secretsManager = new SecretsManagerClient({
181
+ region: this.region,
182
+ ...this.credentials,
183
+ });
184
+ }
185
+ return this.secretsManager;
186
+ }
187
+
188
+ /**
189
+ * Get CloudFormation client (lazy loaded)
190
+ */
191
+ getCloudFormationClient() {
192
+ if (!this.cloudformation) {
193
+ loadCloudFormation();
194
+ this.cloudformation = new CloudFormationClient({
195
+ region: this.region,
196
+ ...this.credentials,
197
+ });
198
+ }
199
+ return this.cloudformation;
200
+ }
201
+
202
+ getName() {
203
+ return 'aws';
204
+ }
205
+
206
+ getSupportedRegions() {
207
+ return [
208
+ 'us-east-1', 'us-east-2', 'us-west-1', 'us-west-2',
209
+ 'eu-west-1', 'eu-west-2', 'eu-west-3', 'eu-central-1',
210
+ 'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1', 'ap-northeast-2',
211
+ 'sa-east-1', 'ca-central-1',
212
+ ];
213
+ }
214
+
215
+ /**
216
+ * Discover VPC resources
217
+ *
218
+ * @param {Object} config - Discovery configuration
219
+ * @returns {Promise<Object>} Discovered VPC resources
220
+ */
221
+ async discoverVpc(config) {
222
+ const ec2 = this.getEC2Client();
223
+ const result = {
224
+ vpcId: null,
225
+ vpcCidr: null,
226
+ subnets: [],
227
+ securityGroups: [],
228
+ routeTables: [],
229
+ natGateways: [],
230
+ internetGateways: [],
231
+ vpcEndpoints: [],
232
+ };
233
+
234
+ try {
235
+ // Discover VPC
236
+ const vpcFilter = config.vpcId
237
+ ? [{ Name: 'vpc-id', Values: [config.vpcId] }]
238
+ : [{ Name: 'isDefault', Values: ['true'] }];
239
+
240
+ const vpcsResponse = await ec2.send(new DescribeVpcsCommand({
241
+ Filters: vpcFilter,
242
+ }));
243
+
244
+ if (vpcsResponse.Vpcs && vpcsResponse.Vpcs.length > 0) {
245
+ const vpc = vpcsResponse.Vpcs[0];
246
+ result.vpcId = vpc.VpcId;
247
+ result.vpcCidr = vpc.CidrBlock;
248
+
249
+ // Discover subnets in VPC
250
+ const subnetsResponse = await ec2.send(new DescribeSubnetsCommand({
251
+ Filters: [{ Name: 'vpc-id', Values: [result.vpcId] }],
252
+ }));
253
+ result.subnets = subnetsResponse.Subnets || [];
254
+
255
+ // Discover security groups
256
+ const sgResponse = await ec2.send(new DescribeSecurityGroupsCommand({
257
+ Filters: [{ Name: 'vpc-id', Values: [result.vpcId] }],
258
+ }));
259
+ result.securityGroups = sgResponse.SecurityGroups || [];
260
+
261
+ // Discover route tables
262
+ const rtResponse = await ec2.send(new DescribeRouteTablesCommand({
263
+ Filters: [{ Name: 'vpc-id', Values: [result.vpcId] }],
264
+ }));
265
+ result.routeTables = rtResponse.RouteTables || [];
266
+
267
+ // Discover NAT gateways
268
+ const natResponse = await ec2.send(new DescribeNatGatewaysCommand({
269
+ Filter: [{ Name: 'vpc-id', Values: [result.vpcId] }],
270
+ }));
271
+ result.natGateways = natResponse.NatGateways || [];
272
+
273
+ // Discover Internet gateways
274
+ const igwResponse = await ec2.send(new DescribeInternetGatewaysCommand({
275
+ Filters: [
276
+ { Name: 'attachment.vpc-id', Values: [result.vpcId] },
277
+ ],
278
+ }));
279
+ result.internetGateways = igwResponse.InternetGateways || [];
280
+
281
+ // Discover VPC Endpoints
282
+ const vpcEndpointsResponse = await ec2.send(new DescribeVpcEndpointsCommand({
283
+ Filters: [
284
+ { Name: 'vpc-id', Values: [result.vpcId] },
285
+ ],
286
+ }));
287
+ result.vpcEndpoints = vpcEndpointsResponse.VpcEndpoints || [];
288
+ }
289
+ } catch (error) {
290
+ console.error('AWS VPC discovery failed:', error);
291
+ throw new Error(`Failed to discover AWS VPC: ${error.message}`);
292
+ }
293
+
294
+ return result;
295
+ }
296
+
297
+ /**
298
+ * Discover KMS keys
299
+ *
300
+ * @param {Object} config - Discovery configuration
301
+ * @returns {Promise<Object>} Discovered KMS keys
302
+ */
303
+ async discoverKmsKeys(config) {
304
+ const kms = this.getKMSClient();
305
+ const result = {
306
+ keys: [],
307
+ aliases: [],
308
+ defaultKey: null,
309
+ };
310
+
311
+ try {
312
+ // List KMS keys
313
+ const keysResponse = await kms.send(new ListKeysCommand({}));
314
+
315
+ if (keysResponse.Keys && keysResponse.Keys.length > 0) {
316
+ // Get details for each key
317
+ for (const key of keysResponse.Keys) {
318
+ try {
319
+ const keyDetails = await kms.send(new DescribeKeyCommand({
320
+ KeyId: key.KeyId,
321
+ }));
322
+
323
+ if (keyDetails.KeyMetadata && keyDetails.KeyMetadata.Enabled) {
324
+ result.keys.push(keyDetails.KeyMetadata);
325
+
326
+ // Set first enabled key as default
327
+ if (!result.defaultKey) {
328
+ result.defaultKey = keyDetails.KeyMetadata;
329
+ }
330
+ }
331
+ } catch (error) {
332
+ // Skip keys we can't access
333
+ console.warn(`Could not describe key ${key.KeyId}:`, error.message);
334
+ }
335
+ }
336
+ }
337
+
338
+ // List KMS aliases
339
+ const aliasesResponse = await kms.send(new ListAliasesCommand({}));
340
+ result.aliases = aliasesResponse.Aliases || [];
341
+
342
+ // If a specific alias is requested, find it
343
+ if (config.keyAlias) {
344
+ const alias = result.aliases.find(a => a.AliasName === config.keyAlias);
345
+ if (alias && alias.TargetKeyId) {
346
+ const key = result.keys.find(k => k.KeyId === alias.TargetKeyId);
347
+ if (key) {
348
+ result.defaultKey = key;
349
+ }
350
+ }
351
+ }
352
+ } catch (error) {
353
+ console.error('AWS KMS discovery failed:', error);
354
+ throw new Error(`Failed to discover AWS KMS keys: ${error.message}`);
355
+ }
356
+
357
+ return result;
358
+ }
359
+
360
+ /**
361
+ * Discover database resources (RDS/Aurora)
362
+ *
363
+ * @param {Object} config - Discovery configuration
364
+ * @returns {Promise<Object>} Discovered database resources
365
+ */
366
+ async discoverDatabase(config) {
367
+ const rds = this.getRDSClient();
368
+ const result = {
369
+ clusters: [],
370
+ instances: [],
371
+ endpoint: null,
372
+ port: null,
373
+ engine: null,
374
+ securityGroupIds: [],
375
+ };
376
+
377
+ try {
378
+ // Discover Aurora clusters
379
+ const clustersResponse = await rds.send(new DescribeDBClustersCommand({}));
380
+
381
+ if (clustersResponse.DBClusters) {
382
+ result.clusters = clustersResponse.DBClusters;
383
+
384
+ // Find cluster matching config
385
+ if (config.databaseId) {
386
+ const cluster = result.clusters.find(c =>
387
+ c.DBClusterIdentifier === config.databaseId
388
+ );
389
+ if (cluster) {
390
+ result.endpoint = cluster.Endpoint;
391
+ result.port = cluster.Port;
392
+ result.engine = cluster.Engine;
393
+ result.securityGroupIds = (cluster.VpcSecurityGroups || []).map(sg => sg.VpcSecurityGroupId);
394
+ }
395
+ } else if (result.clusters.length > 0) {
396
+ // Use first available cluster
397
+ const cluster = result.clusters[0];
398
+ result.endpoint = cluster.Endpoint;
399
+ result.port = cluster.Port;
400
+ result.engine = cluster.Engine;
401
+ result.securityGroupIds = (cluster.VpcSecurityGroups || []).map(sg => sg.VpcSecurityGroupId);
402
+ }
403
+ }
404
+
405
+ // Discover RDS instances (if no cluster found)
406
+ if (!result.endpoint) {
407
+ const instancesResponse = await rds.send(new DescribeDBInstancesCommand({}));
408
+ if (instancesResponse.DBInstances) {
409
+ result.instances = instancesResponse.DBInstances;
410
+
411
+ if (config.databaseId) {
412
+ const instance = result.instances.find(i =>
413
+ i.DBInstanceIdentifier === config.databaseId
414
+ );
415
+ if (instance) {
416
+ result.endpoint = instance.Endpoint?.Address;
417
+ result.port = instance.Endpoint?.Port;
418
+ result.engine = instance.Engine;
419
+ }
420
+ } else if (result.instances.length > 0) {
421
+ const instance = result.instances[0];
422
+ result.endpoint = instance.Endpoint?.Address;
423
+ result.port = instance.Endpoint?.Port;
424
+ result.engine = instance.Engine;
425
+ }
426
+ }
427
+ }
428
+ } catch (error) {
429
+ console.error('AWS RDS discovery failed:', error);
430
+ throw new Error(`Failed to discover AWS databases: ${error.message}`);
431
+ }
432
+
433
+ return result;
434
+ }
435
+
436
+ /**
437
+ * Discover SSM parameters
438
+ *
439
+ * @param {Object} config - Discovery configuration
440
+ * @returns {Promise<Object>} Discovered parameters
441
+ */
442
+ async discoverParameters(config) {
443
+ const ssm = this.getSSMClient();
444
+ const result = {
445
+ parameters: [],
446
+ secrets: [],
447
+ };
448
+
449
+ try {
450
+ if (config.parameterPath) {
451
+ const response = await ssm.send(new GetParametersByPathCommand({
452
+ Path: config.parameterPath,
453
+ Recursive: true,
454
+ }));
455
+ result.parameters = response.Parameters || [];
456
+ }
457
+
458
+ // Discover secrets if enabled
459
+ if (config.includeSecrets) {
460
+ const sm = this.getSecretsManagerClient();
461
+ const secretsResponse = await sm.send(new ListSecretsCommand({}));
462
+ result.secrets = secretsResponse.SecretList || [];
463
+ }
464
+ } catch (error) {
465
+ console.error('AWS SSM discovery failed:', error);
466
+ throw new Error(`Failed to discover AWS parameters: ${error.message}`);
467
+ }
468
+
469
+ return result;
470
+ }
471
+
472
+ /**
473
+ * Describe KMS key by key ID or alias
474
+ *
475
+ * @param {string} keyIdOrAlias - Key ID or alias name
476
+ * @returns {Promise<Object>} Key metadata
477
+ */
478
+ async describeKmsKey(keyIdOrAlias) {
479
+ const kms = this.getKMSClient();
480
+
481
+ try {
482
+ const response = await kms.send(new DescribeKeyCommand({
483
+ KeyId: keyIdOrAlias,
484
+ }));
485
+
486
+ return response.KeyMetadata;
487
+ } catch (error) {
488
+ throw new Error(`Failed to describe KMS key ${keyIdOrAlias}: ${error.message}`);
489
+ }
490
+ }
491
+
492
+ /**
493
+ * Describe CloudFormation stack
494
+ *
495
+ * @param {string} stackName - Name of the CloudFormation stack
496
+ * @returns {Promise<Object>} Stack details including outputs
497
+ */
498
+ async describeStack(stackName) {
499
+ const cf = this.getCloudFormationClient();
500
+
501
+ try {
502
+ const response = await cf.send(new DescribeStacksCommand({
503
+ StackName: stackName,
504
+ }));
505
+
506
+ if (!response.Stacks || response.Stacks.length === 0) {
507
+ throw new Error(`Stack ${stackName} not found`);
508
+ }
509
+
510
+ return response.Stacks[0];
511
+ } catch (error) {
512
+ if (error.message && error.message.includes('does not exist')) {
513
+ throw new Error(`Stack with id ${stackName} does not exist`);
514
+ }
515
+ throw error;
516
+ }
517
+ }
518
+
519
+ /**
520
+ * List CloudFormation stack resources
521
+ *
522
+ * @param {string} stackName - Name of the CloudFormation stack
523
+ * @returns {Promise<Array>} List of stack resources
524
+ */
525
+ async listStackResources(stackName) {
526
+ const cf = this.getCloudFormationClient();
527
+
528
+ try {
529
+ const response = await cf.send(new ListStackResourcesCommand({
530
+ StackName: stackName,
531
+ }));
532
+
533
+ return response.StackResourceSummaries || [];
534
+ } catch (error) {
535
+ console.warn(`Failed to list stack resources for ${stackName}:`, error.message);
536
+ return [];
537
+ }
538
+ }
539
+ }
540
+
541
+ module.exports = {
542
+ AWSProviderAdapter,
543
+ };
544
+