@gugananuvem/aws-local-simulator 1.0.12 → 1.0.14

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 (57) hide show
  1. package/README.md +235 -11
  2. package/package.json +12 -2
  3. package/src/config/default-config.js +1 -0
  4. package/src/index.js +18 -2
  5. package/src/server.js +36 -32
  6. package/src/services/apigateway/index.js +5 -0
  7. package/src/services/apigateway/server.js +20 -0
  8. package/src/services/apigateway/simulator.js +13 -3
  9. package/src/services/athena/index.js +75 -0
  10. package/src/services/athena/server.js +101 -0
  11. package/src/services/athena/simulador.js +998 -0
  12. package/src/services/athena/simulator.js +346 -0
  13. package/src/services/cloudformation/index.js +106 -0
  14. package/src/services/cloudformation/server.js +417 -0
  15. package/src/services/cloudformation/simulador.js +1045 -0
  16. package/src/services/cloudtrail/index.js +84 -0
  17. package/src/services/cloudtrail/server.js +235 -0
  18. package/src/services/cloudtrail/simulador.js +719 -0
  19. package/src/services/cloudwatch/index.js +84 -0
  20. package/src/services/cloudwatch/server.js +366 -0
  21. package/src/services/cloudwatch/simulador.js +1173 -0
  22. package/src/services/cognito/index.js +5 -0
  23. package/src/services/cognito/simulator.js +4 -0
  24. package/src/services/config/index.js +96 -0
  25. package/src/services/config/server.js +215 -0
  26. package/src/services/config/simulador.js +1260 -0
  27. package/src/services/dynamodb/index.js +7 -3
  28. package/src/services/dynamodb/server.js +4 -2
  29. package/src/services/dynamodb/simulator.js +39 -29
  30. package/src/services/eventbridge/index.js +55 -51
  31. package/src/services/eventbridge/server.js +209 -0
  32. package/src/services/eventbridge/simulator.js +684 -0
  33. package/src/services/index.js +30 -4
  34. package/src/services/kms/index.js +75 -0
  35. package/src/services/kms/server.js +67 -0
  36. package/src/services/kms/simulator.js +324 -0
  37. package/src/services/lambda/index.js +5 -0
  38. package/src/services/lambda/simulator.js +48 -38
  39. package/src/services/parameter-store/index.js +80 -0
  40. package/src/services/parameter-store/server.js +50 -0
  41. package/src/services/parameter-store/simulator.js +201 -0
  42. package/src/services/s3/index.js +7 -3
  43. package/src/services/s3/server.js +20 -13
  44. package/src/services/s3/simulator.js +163 -407
  45. package/src/services/secret-manager/index.js +80 -0
  46. package/src/services/secret-manager/server.js +50 -0
  47. package/src/services/secret-manager/simulator.js +171 -0
  48. package/src/services/sns/index.js +55 -42
  49. package/src/services/sns/server.js +580 -0
  50. package/src/services/sns/simulator.js +1482 -0
  51. package/src/services/sqs/index.js +2 -4
  52. package/src/services/sqs/server.js +4 -2
  53. package/src/services/xray/index.js +83 -0
  54. package/src/services/xray/server.js +308 -0
  55. package/src/services/xray/simulador.js +994 -0
  56. package/src/utils/cloudtrail-audit.js +129 -0
  57. package/src/utils/local-store.js +18 -2
package/README.md CHANGED
@@ -13,13 +13,22 @@ Simulador local completo para serviços AWS. Desenvolva e teste suas aplicaçõe
13
13
  | DynamoDB | ✅ | 8000 | Banco de dados NoSQL |
14
14
  | S3 | ✅ | 4566 | Armazenamento de objetos |
15
15
  | SQS | ✅ | 9324 | Filas de mensagens |
16
- | Lambda | ✅ | 3001 | Funções serverless (invocação por nome) |
16
+ | Lambda | ✅ | 3001 | Funções serverless |
17
17
  | Cognito | ✅ | 9229 | Autenticação e autorização |
18
18
  | API Gateway | ✅ | 4567 | APIs REST e HTTP |
19
- | STS | ✅ | 9326 | Credenciais temporárias (AssumeRole, GetCallerIdentity) |
19
+ | STS | ✅ | 9326 | Credenciais temporárias |
20
+ | SNS | ✅ | 9911 | Notificações pub/sub |
21
+ | EventBridge | ✅ | 4010 | Barramento de eventos |
22
+ | KMS | ✅ | 4000 | Gerenciamento de chaves |
23
+ | Secrets Manager | ✅ | 4001 | Gerenciamento de segredos |
24
+ | Parameter Store | ✅ | 4002 | Armazenamento de parâmetros |
25
+ | CloudWatch | ✅ | 4011 | Logs, métricas e alarmes |
26
+ | CloudTrail | ✅ | 4012 | Auditoria de API calls |
27
+ | AWS Config | ✅ | 4013 | Conformidade e configuração |
28
+ | CloudFormation | ✅ | 4580 | Infraestrutura como código |
29
+ | Athena | ✅ | 4599 | Consultas SQL em dados no S3 |
30
+ | X-Ray | ✅ | 4015 | Rastreamento distribuído |
20
31
  | ECS/Fargate | 🚧 | 8080 | Orquestração de containers (em desenvolvimento) |
21
- | SNS | 🚧 | 9911 | Notificações (em desenvolvimento) |
22
- | EventBridge | 🚧 | 4010 | Barramento de eventos (em desenvolvimento) |
23
32
 
24
33
  ## 📦 Instalação
25
34
 
@@ -40,7 +49,18 @@ npm install --save-dev aws-local-simulator
40
49
  "lambda": true,
41
50
  "cognito": true,
42
51
  "apigateway": true,
43
- "sts": true
52
+ "sts": true,
53
+ "sns": true,
54
+ "eventbridge": true,
55
+ "kms": true,
56
+ "secret-manager": true,
57
+ "parameter-store": true,
58
+ "cloudwatch": true,
59
+ "cloudtrail": true,
60
+ "cloudformation": true,
61
+ "xray": true,
62
+ "config": true,
63
+ "athena": true
44
64
  },
45
65
  "lambdas": [
46
66
  {
@@ -111,6 +131,17 @@ await dynamoDB.send(new PutCommand({
111
131
  | AWS_LOCAL_SIMULATOR_COGNITO | Habilita Cognito | false |
112
132
  | AWS_LOCAL_SIMULATOR_APIGATEWAY | Habilita API Gateway | false |
113
133
  | AWS_LOCAL_SIMULATOR_STS | Habilita STS | true |
134
+ | AWS_LOCAL_SIMULATOR_SNS | Habilita SNS | false |
135
+ | AWS_LOCAL_SIMULATOR_EVENTBRIDGE | Habilita EventBridge | false |
136
+ | AWS_LOCAL_SIMULATOR_KMS | Habilita KMS | false |
137
+ | AWS_LOCAL_SIMULATOR_SECRET_MANAGER | Habilita Secrets Manager | false |
138
+ | AWS_LOCAL_SIMULATOR_PARAMETER_STORE | Habilita Parameter Store | false |
139
+ | AWS_LOCAL_SIMULATOR_CLOUDWATCH | Habilita CloudWatch | false |
140
+ | AWS_LOCAL_SIMULATOR_CLOUDTRAIL | Habilita CloudTrail | false |
141
+ | AWS_LOCAL_SIMULATOR_CLOUDFORMATION | Habilita CloudFormation | false |
142
+ | AWS_LOCAL_SIMULATOR_ATHENA | Habilita Athena | false |
143
+ | AWS_LOCAL_SIMULATOR_XRAY | Habilita X-Ray | false |
144
+ | AWS_LOCAL_SIMULATOR_CONFIG | Habilita AWS Config | false |
114
145
  | AWS_LOCAL_SIMULATOR_ECS | Habilita ECS/Fargate | false |
115
146
  | AWS_LOCAL_SIMULATOR_DYNAMODB_PORT | Porta DynamoDB | 8000 |
116
147
  | AWS_LOCAL_SIMULATOR_S3_PORT | Porta S3 | 4566 |
@@ -119,6 +150,17 @@ await dynamoDB.send(new PutCommand({
119
150
  | AWS_LOCAL_SIMULATOR_COGNITO_PORT | Porta Cognito | 9229 |
120
151
  | AWS_LOCAL_SIMULATOR_APIGATEWAY_PORT | Porta API Gateway | 4567 |
121
152
  | AWS_LOCAL_SIMULATOR_STS_PORT | Porta STS | 9326 |
153
+ | AWS_LOCAL_SIMULATOR_SNS_PORT | Porta SNS | 9911 |
154
+ | AWS_LOCAL_SIMULATOR_EVENTBRIDGE_PORT | Porta EventBridge | 4010 |
155
+ | AWS_LOCAL_SIMULATOR_KMS_PORT | Porta KMS | 4000 |
156
+ | AWS_LOCAL_SIMULATOR_SECRET_MANAGER_PORT | Porta Secrets Manager | 4001 |
157
+ | AWS_LOCAL_SIMULATOR_PARAMETER_STORE_PORT | Porta Parameter Store | 4002 |
158
+ | AWS_LOCAL_SIMULATOR_CLOUDWATCH_PORT | Porta CloudWatch | 4011 |
159
+ | AWS_LOCAL_SIMULATOR_CLOUDTRAIL_PORT | Porta CloudTrail | 4012 |
160
+ | AWS_LOCAL_SIMULATOR_CONFIG_PORT | Porta AWS Config | 4013 |
161
+ | AWS_LOCAL_SIMULATOR_XRAY_PORT | Porta X-Ray | 4015 |
162
+ | AWS_LOCAL_SIMULATOR_CLOUDFORMATION_PORT | Porta CloudFormation | 4580 |
163
+ | AWS_LOCAL_SIMULATOR_ATHENA_PORT | Porta Athena | 4599 |
122
164
  | AWS_LOCAL_SIMULATOR_ECS_PORT | Porta ECS | 8080 |
123
165
  | AWS_LOCAL_SIMULATOR_DATA | Diretório de dados | ./aws-local-simulator-data |
124
166
  | AWS_LOCAL_SIMULATOR_LOG | Nível de log | info |
@@ -153,6 +195,17 @@ npx aws-local-simulator status
153
195
  | Cognito | http://localhost:9229 | http://localhost:9229/__admin/userpools |
154
196
  | API Gateway | http://localhost:4567 | http://localhost:4567/__admin/apis |
155
197
  | STS | http://localhost:9326 | — |
198
+ | SNS | http://localhost:9911 | http://localhost:9911/__admin/health |
199
+ | EventBridge | http://localhost:4010 | — |
200
+ | KMS | http://localhost:4000 | — |
201
+ | Secrets Manager | http://localhost:4001 | — |
202
+ | Parameter Store | http://localhost:4002 | — |
203
+ | CloudWatch | http://localhost:4011 | — |
204
+ | CloudTrail | http://localhost:4012 | — |
205
+ | AWS Config | http://localhost:4013 | — |
206
+ | X-Ray | http://localhost:4015 | — |
207
+ | CloudFormation | http://localhost:4580 | http://localhost:4580/__admin/stacks |
208
+ | Athena | http://localhost:4599 | http://localhost:4599/__admin/health |
156
209
  | ECS | http://localhost:8080 | http://localhost:8080/__admin/clusters |
157
210
 
158
211
  ## 🧪 Testando com AWS CLI
@@ -167,7 +220,7 @@ aws s3 ls --endpoint-url http://localhost:4566
167
220
  # SQS
168
221
  aws sqs list-queues --endpoint-url http://localhost:9324
169
222
 
170
- # Lambda — invocar por nome (não por path HTTP)
223
+ # Lambda
171
224
  aws lambda invoke \
172
225
  --function-name my-function \
173
226
  --payload '{"key":"value"}' \
@@ -184,8 +237,126 @@ aws sts assume-role \
184
237
  --role-session-name "my-session" \
185
238
  --endpoint-url http://localhost:9326
186
239
 
240
+ # SNS
241
+ aws sns list-topics --endpoint-url http://localhost:9911
242
+
243
+ # EventBridge
244
+ aws events list-event-buses --endpoint-url http://localhost:4010
245
+
246
+ # KMS
247
+ aws kms list-keys --endpoint-url http://localhost:4000
248
+
249
+ # Secrets Manager
250
+ aws secretsmanager list-secrets --endpoint-url http://localhost:4001
251
+
252
+ # Criar secret
253
+ aws secretsmanager create-secret \
254
+ --name "local/app/db-credentials" \
255
+ --description "Credenciais do banco" \
256
+ --secret-string '{"username":"admin","password":"secret123"}' \
257
+ --endpoint-url http://localhost:4001
258
+
259
+ # Ler secret
260
+ aws secretsmanager get-secret-value \
261
+ --secret-id "local/app/db-credentials" \
262
+ --endpoint-url http://localhost:4001
263
+
264
+ # Parameter Store
265
+ aws ssm describe-parameters --endpoint-url http://localhost:4002
266
+
267
+ # Criar parâmetro String
268
+ aws ssm put-parameter \
269
+ --name "/local/app/config" \
270
+ --value '{"timeout":30,"maxRetries":3}' \
271
+ --type String \
272
+ --endpoint-url http://localhost:4002
273
+
274
+ # Criar parâmetro SecureString
275
+ aws ssm put-parameter \
276
+ --name "/local/app/api-key" \
277
+ --value "my-secret-api-key" \
278
+ --type SecureString \
279
+ --endpoint-url http://localhost:4002
280
+
281
+ # Ler parâmetro
282
+ aws ssm get-parameter \
283
+ --name "/local/app/config" \
284
+ --endpoint-url http://localhost:4002
285
+
286
+ # CloudWatch
287
+ aws cloudwatch list-metrics --endpoint-url http://localhost:4011
288
+ aws logs describe-log-groups --endpoint-url http://localhost:4011
289
+
290
+ # CloudTrail
291
+ aws cloudtrail describe-trails --endpoint-url http://localhost:4012
292
+
293
+ # CloudFormation
294
+ aws cloudformation list-stacks --endpoint-url http://localhost:4580
295
+
296
+ # X-Ray
297
+ aws xray get-trace-summaries \
298
+ --start-time $(date -d '1 hour ago' +%s) \
299
+ --end-time $(date +%s) \
300
+ --endpoint-url http://localhost:4015
301
+
302
+ # AWS Config
303
+ aws configservice describe-configuration-recorders --endpoint-url http://localhost:4013
304
+
187
305
  # API Gateway
188
306
  aws apigateway get-rest-apis --endpoint-url http://localhost:4567
307
+
308
+ # Cloudformation
309
+ aws cloudformation create-stack \
310
+ --stack-name test-stack \
311
+ --template-body file://templates/test-stack.yaml \
312
+ --parameters \
313
+ ParameterKey=Environment,ParameterValue=local \
314
+ ParameterKey=BucketName,ParameterValue=meu-bucket \
315
+ ParameterKey=QueueName,ParameterValue=minha-fila \
316
+ ParameterKey=TableName,ParameterValue=minha-tabela \
317
+ --endpoint-url http://localhost:4580
318
+
319
+ # Ver Cloudformation resultado
320
+ aws cloudformation describe-stacks \
321
+ --stack-name test-stack \
322
+ --endpoint-url http://localhost:4580
323
+
324
+ # Athena
325
+ # Criar workgroup
326
+ aws athena create-work-group \
327
+ --name my-workgroup \
328
+ --configuration ResultConfiguration={OutputLocation=s3://meu-bucket/athena-results/} \
329
+ --endpoint-url http://localhost:4599
330
+
331
+ # Listar workgroups
332
+ aws athena list-work-groups --endpoint-url http://localhost:4599
333
+
334
+ # Executar query
335
+ aws athena start-query-execution \
336
+ --query-string "SELECT * FROM my_table LIMIT 10" \
337
+ --query-execution-context Database=default \
338
+ --result-configuration OutputLocation=s3://meu-bucket/athena-results/ \
339
+ --endpoint-url http://localhost:4599
340
+
341
+ # Verificar status da query
342
+ aws athena get-query-execution \
343
+ --query-execution-id <id-retornado> \
344
+ --endpoint-url http://localhost:4599
345
+
346
+ # Buscar resultados
347
+ aws athena get-query-results \
348
+ --query-execution-id <id-retornado> \
349
+ --endpoint-url http://localhost:4599
350
+
351
+ # Criar named query
352
+ aws athena create-named-query \
353
+ --name "my-saved-query" \
354
+ --database default \
355
+ --query-string "SELECT id, value FROM my_table WHERE status = 'active'" \
356
+ --endpoint-url http://localhost:4599
357
+
358
+ # Listar named queries
359
+ aws athena list-named-queries --endpoint-url http://localhost:4599
189
360
  ```
190
361
 
191
362
  ## ⚙️ Configuração de Lambdas
@@ -196,8 +367,8 @@ Lambdas são registradas por **nome** e invocadas via API de invocação (igual
196
367
  {
197
368
  "lambdas": [
198
369
  {
199
- "name": "my-function",
200
- "handler": "./src/handlers/my-function.js",
370
+ "name": "my-user-function",
371
+ "handler": "./src/handlers/my-user-function.js",
201
372
  "env": {
202
373
  "TABLE_NAME": "users-table",
203
374
  "BUCKET_NAME": "my-bucket"
@@ -207,6 +378,50 @@ Lambdas são registradas por **nome** e invocadas via API de invocação (igual
207
378
  }
208
379
  ```
209
380
 
381
+ ## ⚙️ Configuração API GATEWAY
382
+
383
+ O valor do **lambdaName** deve igual ao nome Lambda que está registrada com o valor **name**. Ex: "my-user-function".
384
+
385
+ ```json
386
+ {
387
+ "apigateway": {
388
+ "apis": [
389
+ {
390
+ "name": "Users API",
391
+ "description": "API para gerenciamento de usuários",
392
+ "endpoints": [
393
+ {
394
+ "path": "/user",
395
+ "method": "GET",
396
+ "lambdaName": "my-user-function",
397
+ "integrationType": "lambda"
398
+ },
399
+ {
400
+ "path": "/user",
401
+ "method": "POST",
402
+ "lambdaName": "my-user-function",
403
+ "integrationType": "lambda"
404
+ },
405
+ {
406
+ "path": "/user/{id}",
407
+ "method": "GET",
408
+ "lambdaName": "my-user-function",
409
+ "integrationType": "lambda"
410
+ },
411
+ {
412
+ "path": "/user/{id}",
413
+ "method": "DELETE",
414
+ "lambdaName": "my-user-function",
415
+ "integrationType": "lambda"
416
+ }
417
+ ]
418
+ }
419
+ ]
420
+ },
421
+
422
+ }
423
+ ```
424
+
210
425
  O handler deve exportar uma função padrão:
211
426
 
212
427
  ```javascript
@@ -229,13 +444,22 @@ Os dados são persistidos em:
229
444
  ├── sqs/
230
445
  ├── cognito/
231
446
  ├── apigateway/
232
- └── ecs/
447
+ ├── ecs/
448
+ ├── kms/
449
+ ├── secret-manager/
450
+ ├── parameter-store/
451
+ ├── cloudwatch/
452
+ ├── cloudtrail/
453
+ ├── cloudformation/
454
+ ├── athena/
455
+ ├── xray/
456
+ └── config/
233
457
  ```
234
458
 
235
459
  ## 🐛 Debug
236
460
 
237
461
  ```bash
238
- AWS_LOCAL_SIMULATOR_LOG=verboso npx aws-local-simulator start
462
+ AWS_LOCAL_SIMULATOR_LOG=verbose npx aws-local-simulator start
239
463
  ```
240
464
 
241
465
  ## 🤝 Contribuindo
@@ -252,6 +476,6 @@ MIT © Luiz Gustavo Ribeiro
252
476
 
253
477
  ## ⚠️ Limitações
254
478
 
255
- - SNS e EventBridge em desenvolvimento
479
+ - ECS/Fargate em desenvolvimento
256
480
  - WebSocket APIs em desenvolvimento
257
481
  - Para uso em desenvolvimento e testes apenas
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gugananuvem/aws-local-simulator",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "Simulador local completo para serviços AWS",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -45,7 +45,17 @@
45
45
  "lambda",
46
46
  "cognito",
47
47
  "apigateway",
48
+ "kms",
49
+ "config",
50
+ "parameter-store",
51
+ "secret-manager",
52
+ "cloudformation",
53
+ "eventbridge",
54
+ "sns",
48
55
  "ecs",
56
+ "sts",
57
+ "cloudtrail",
58
+ "cloudwatch",
49
59
  "development",
50
60
  "testing"
51
61
  ],
@@ -109,6 +119,6 @@
109
119
  "optional": true
110
120
  }
111
121
  },
112
- "buildDate": "2026-04-04T03:21:21.370Z",
122
+ "buildDate": "2026-04-05T12:32:46.437Z",
113
123
  "published": true
114
124
  }
@@ -29,6 +29,7 @@ module.exports = {
29
29
  cognito: 9229,
30
30
  apigateway: 4567,
31
31
  sts: 9326,
32
+ athena: 4599,
32
33
  },
33
34
  apigateway: {
34
35
  defaultCors: {
package/src/index.js CHANGED
@@ -11,8 +11,16 @@ const DynamoDBService = require('./services/dynamodb');
11
11
  const S3Service = require('./services/s3');
12
12
  const SQSService = require('./services/sqs');
13
13
  const LambdaService = require('./services/lambda');
14
- const SNSService = require('./services/sns');
15
- const EventBridgeService = require('./services/eventbridge');
14
+ const { SNSService } = require('./services/sns');
15
+ const { EventBridgeService } = require('./services/eventbridge');
16
+ const { CloudWatchService } = require('./services/cloudwatch');
17
+ const CloudTrailService = require('./services/cloudtrail');
18
+ const { KMSService } = require('./services/kms');
19
+ const CloudFormationService = require('./services/cloudformation');
20
+ const { XRayService } = require('./services/xray');
21
+ const { SecretManagerService } = require('./services/secret-manager');
22
+ const { ParameterStoreService } = require('./services/parameter-store');
23
+ const { ConfigService } = require('./services/config');
16
24
 
17
25
  // Exporta utilitários
18
26
  const LocalStore = require('./utils/local-store');
@@ -122,6 +130,14 @@ module.exports = {
122
130
  LambdaService,
123
131
  SNSService,
124
132
  EventBridgeService,
133
+ CloudWatchService,
134
+ CloudTrailService,
135
+ KMSService,
136
+ CloudFormationService,
137
+ XRayService,
138
+ SecretManagerService,
139
+ ParameterStoreService,
140
+ ConfigService,
125
141
  LocalStore,
126
142
  HandlerLoader,
127
143
  RouteRegistry
package/src/server.js CHANGED
@@ -12,12 +12,21 @@ const DynamoDBService = require("./services/dynamodb");
12
12
  const S3Service = require("./services/s3");
13
13
  const SQSService = require("./services/sqs");
14
14
  const LambdaService = require("./services/lambda");
15
- const SNSService = require("./services/sns");
16
- const EventBridgeService = require("./services/eventbridge");
15
+ const { SNSService } = require("./services/sns");
16
+ const { EventBridgeService } = require("./services/eventbridge");
17
17
  const CognitoService = require("./services/cognito");
18
18
  const APIGatewayService = require("./services/apigateway");
19
19
  const ECSService = require("./services/ecs");
20
20
  const STSService = require("./services/sts");
21
+ const { CloudWatchService } = require("./services/cloudwatch");
22
+ const CloudTrailService = require("./services/cloudtrail");
23
+ const { KMSService } = require("./services/kms");
24
+ const CloudFormationService = require("./services/cloudformation");
25
+ const { XRayService } = require("./services/xray");
26
+ const { SecretManagerService } = require("./services/secret-manager");
27
+ const { ParameterStoreService } = require("./services/parameter-store");
28
+ const { ConfigService } = require("./services/config");
29
+ const { AthenaService } = require("./services/athena");
21
30
 
22
31
  class Server {
23
32
  constructor(config) {
@@ -64,24 +73,31 @@ class Server {
64
73
  }
65
74
 
66
75
  async initializeServices() {
67
- // Ordem de inicialização importante
68
76
  const serviceOrder = [
69
- { name: "sts", class: STSService, depends: [] },
70
- { name: "lambda", class: LambdaService, depends: [] },
71
- { name: "dynamodb", class: DynamoDBService, depends: [] },
72
- { name: "s3", class: S3Service, depends: [] },
73
- { name: "sqs", class: SQSService, depends: ["lambda"] },
74
- { name: "sns", class: SNSService, depends: [] },
75
- { name: "eventbridge", class: EventBridgeService, depends: [] },
76
- { name: "cognito", class: CognitoService, depends: [] },
77
- { name: "ecs", class: ECSService, depends: [] },
78
- { name: "apigateway", class: APIGatewayService, depends: ["lambda"] },
77
+ { name: "sts", class: STSService, depends: [] },
78
+ { name: "lambda", class: LambdaService, depends: [] },
79
+ { name: "dynamodb", class: DynamoDBService, depends: [] },
80
+ { name: "s3", class: S3Service, depends: [] },
81
+ { name: "sqs", class: SQSService, depends: ["lambda"] },
82
+ { name: "sns", class: SNSService, depends: [] },
83
+ { name: "eventbridge", class: EventBridgeService, depends: [] },
84
+ { name: "cognito", class: CognitoService, depends: [] },
85
+ { name: "ecs", class: ECSService, depends: [] },
86
+ { name: "apigateway", class: APIGatewayService, depends: ["lambda"] },
87
+ { name: "kms", class: KMSService, depends: [] },
88
+ { name: "cloudwatch", class: CloudWatchService, depends: [] },
89
+ { name: "cloudtrail", class: CloudTrailService, depends: [] },
90
+ { name: "cloudformation", class: CloudFormationService, depends: [] },
91
+ { name: "xray", class: XRayService, depends: [] },
92
+ { name: "secret-manager", class: SecretManagerService, depends: [] },
93
+ { name: "parameter-store",class: ParameterStoreService, depends: [] },
94
+ { name: "config", class: ConfigService, depends: [] },
95
+ { name: "athena", class: AthenaService, depends: [] },
79
96
  ];
80
97
 
81
98
  for (const serviceDef of serviceOrder) {
82
99
  if (this.config.services[serviceDef.name]) {
83
100
  try {
84
- // Resolve dependências
85
101
  const dependencies = {};
86
102
  for (const dep of serviceDef.depends) {
87
103
  dependencies[dep] = this.servicesMap.get(dep);
@@ -96,29 +112,17 @@ class Server {
96
112
  logger.success(`✅ ${serviceDef.name.toUpperCase()} Service inicializado`);
97
113
  } catch (error) {
98
114
  logger.error(`❌ Erro ao inicializar ${serviceDef.name}:`, error);
99
- if (serviceDef.name === "lambda") {
100
- throw error; // Lambda é essencial
101
- }
115
+ if (serviceDef.name === "lambda") throw error;
102
116
  }
103
117
  }
104
118
  }
105
119
 
106
- /*
107
- // Cognito Service (opcional)
108
- if (this.config.services.cognito) {
109
- const cognitoService = new CognitoService(this.config);
110
- await cognitoService.initialize();
111
- this.services.push(cognitoService);
112
- this.servicesMap.set("cognito", cognitoService);
113
- logger.success("✅ Cognito Service inicializado");
120
+ // Injeta dependências cross-service nos serviços que suportam
121
+ for (const service of this.services) {
122
+ if (typeof service.injectDependencies === "function") {
123
+ service.injectDependencies(this);
124
+ }
114
125
  }
115
- if (this.config.services.apigateway) {
116
- const apigatewayService = new APIGatewayService(this.config);
117
- await apigatewayService.initialize();
118
- this.services.push(apigatewayService);
119
- this.servicesMap.set("apigateway", apigatewayService);
120
- logger.success("✅ API Gateway Service inicializado");
121
- }*/
122
126
  }
123
127
 
124
128
  async startServices() {
@@ -33,6 +33,11 @@ class APIGatewayService {
33
33
  logger.debug('API Gateway Service inicializado');
34
34
  }
35
35
 
36
+ injectDependencies(server) {
37
+ const ct = server.getService('cloudtrail');
38
+ if (ct?.simulator) this.simulator.audit.setTrail(ct.simulator);
39
+ }
40
+
36
41
  async start() {
37
42
  if (this.isRunning) return;
38
43
  await this.server.start();
@@ -19,6 +19,26 @@ class APIGatewayServer {
19
19
  setupMiddlewares() {
20
20
  this.app.use(express.json({ limit: '10mb' }));
21
21
  this.app.use(express.urlencoded({ extended: true, limit: '10mb' }));
22
+ // Parse bodies with AWS content types (e.g. application/x-amz-json-1.1)
23
+ this.app.use((req, res, next) => {
24
+ const ct = req.headers['content-type'] || '';
25
+ if ((req.body && JSON.stringify(req.body) == "{}") && ct.includes('application/x-amz-json')) {
26
+ let data = "";
27
+ req.on("data", (chunk) => {
28
+ data += chunk;
29
+ });
30
+ req.on("end", () => {
31
+ try {
32
+ req.body = JSON.parse(data);
33
+ } catch (error) {
34
+ req.body = {};
35
+ }
36
+ next();
37
+ });
38
+ } else {
39
+ next();
40
+ }
41
+ });
22
42
  this.app.use(cors());
23
43
 
24
44
  if (logger.currentLogLevel === 'verboso') {
@@ -9,14 +9,15 @@ const logger = require('../../utils/logger');
9
9
  const LocalStore = require('../../utils/local-store');
10
10
  const path = require('path');
11
11
  const { URLPattern } = require('urlpattern-polyfill');
12
+ const { CloudTrailAudit } = require('../../utils/cloudtrail-audit');
12
13
 
13
14
  class APIGatewaySimulator {
14
15
  constructor(config) {
15
16
  this.config = config;
16
17
  this.dataDir = path.join(process.env.AWS_LOCAL_SIMULATOR_DATA_DIR, 'apigateway');
17
18
  this.store = new LocalStore(this.dataDir);
18
- this.apis = new Map(); // REST/HTTP APIs
19
- this.websocketApis = new Map(); // WebSocket APIs
19
+ this.apis = new Map();
20
+ this.websocketApis = new Map();
20
21
  this.deployments = new Map();
21
22
  this.stages = new Map();
22
23
  this.resources = new Map();
@@ -26,6 +27,7 @@ class APIGatewaySimulator {
26
27
  this.usagePlans = new Map();
27
28
  this.apiKeys = new Map();
28
29
  this.domainNames = new Map();
30
+ this.audit = new CloudTrailAudit('execute-api.amazonaws.com');
29
31
  }
30
32
 
31
33
  async initialize() {
@@ -734,7 +736,15 @@ class APIGatewaySimulator {
734
736
  response.headers = { ...response.headers, ...integrationResponse.responseParameters };
735
737
  response.body = this.applyResponseTemplate(integrationResponse, response.body);
736
738
  }
737
-
739
+
740
+ this.audit.record({
741
+ eventName: 'Invoke',
742
+ readOnly: method === 'GET' || method === 'HEAD',
743
+ isDataEvent: true,
744
+ resources: [{ ARN: `arn:aws:execute-api:local:000000000000:${apiId}/${stageName}/${method}${path}`, type: 'AWS::APIGateway::Stage' }],
745
+ requestParameters: { apiId, stageName, method, path },
746
+ });
747
+
738
748
  return response;
739
749
  }
740
750
 
@@ -0,0 +1,75 @@
1
+ 'use strict';
2
+
3
+ const http = require('http');
4
+ const path = require('path');
5
+ const { AthenaSimulator } = require('./simulator');
6
+ const { createAthenaServer } = require('./server');
7
+ const LocalStore = require('../../utils/local-store');
8
+
9
+ class AthenaService {
10
+ constructor(config) {
11
+ this.config = config;
12
+ this.logger = require('../../utils/logger');
13
+ this.name = 'athena';
14
+ this.port = config?.ports?.athena || 4599;
15
+ this.store = null;
16
+ this.simulator = null;
17
+ this._server = null;
18
+ this.isRunning = false;
19
+ }
20
+
21
+ async initialize() {
22
+ this.logger.debug(`Inicializando Athena Service na porta ${this.port}...`);
23
+ const dataDir = process.env.AWS_LOCAL_SIMULATOR_DATA_DIR;
24
+ this.store = new LocalStore(path.join(dataDir, 'athena'));
25
+ this.simulator = new AthenaSimulator(this.config, this.store, this.logger);
26
+ await this.simulator.initialize();
27
+ this.app = createAthenaServer(this.simulator, this.logger);
28
+ this.logger.debug('Athena Service inicializado');
29
+ }
30
+
31
+ injectDependencies(server) {
32
+ const ct = server.getService('cloudtrail');
33
+ if (ct?.simulator) this.simulator.audit.setTrail(ct.simulator);
34
+ }
35
+
36
+ async start() {
37
+ if (this.isRunning) return;
38
+ return new Promise((resolve, reject) => {
39
+ this._server = http.createServer(this.app);
40
+ this._server.listen(this.port, () => {
41
+ this.isRunning = true;
42
+ this.logger.info(`🔍 Athena rodando em http://localhost:${this.port}`);
43
+ resolve();
44
+ });
45
+ this._server.on('error', reject);
46
+ });
47
+ }
48
+
49
+ async stop() {
50
+ if (!this.isRunning || !this._server) return;
51
+ return new Promise((resolve) => {
52
+ this._server.close(() => {
53
+ this.isRunning = false;
54
+ resolve();
55
+ });
56
+ });
57
+ }
58
+
59
+ async reset() {
60
+ await this.simulator.reset();
61
+ }
62
+
63
+ getStatus() {
64
+ return {
65
+ running: this.isRunning,
66
+ port: this.port,
67
+ endpoint: `http://localhost:${this.port}`,
68
+ ...this.simulator?.getStats(),
69
+ };
70
+ }
71
+
72
+ getSimulator() { return this.simulator; }
73
+ }
74
+
75
+ module.exports = { AthenaService };