@gugananuvem/aws-local-simulator 1.0.11 → 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 (65) hide show
  1. package/README.md +349 -72
  2. package/package.json +12 -2
  3. package/src/config/config-loader.js +2 -0
  4. package/src/config/default-config.js +3 -0
  5. package/src/index.js +18 -2
  6. package/src/server.js +37 -31
  7. package/src/services/apigateway/index.js +10 -3
  8. package/src/services/apigateway/server.js +73 -0
  9. package/src/services/apigateway/simulator.js +13 -3
  10. package/src/services/athena/index.js +75 -0
  11. package/src/services/athena/server.js +101 -0
  12. package/src/services/athena/simulador.js +998 -0
  13. package/src/services/athena/simulator.js +346 -0
  14. package/src/services/cloudformation/index.js +106 -0
  15. package/src/services/cloudformation/server.js +417 -0
  16. package/src/services/cloudformation/simulador.js +1045 -0
  17. package/src/services/cloudtrail/index.js +84 -0
  18. package/src/services/cloudtrail/server.js +235 -0
  19. package/src/services/cloudtrail/simulador.js +719 -0
  20. package/src/services/cloudwatch/index.js +84 -0
  21. package/src/services/cloudwatch/server.js +366 -0
  22. package/src/services/cloudwatch/simulador.js +1173 -0
  23. package/src/services/cognito/index.js +5 -0
  24. package/src/services/cognito/server.js +54 -3
  25. package/src/services/cognito/simulator.js +273 -2
  26. package/src/services/config/index.js +96 -0
  27. package/src/services/config/server.js +215 -0
  28. package/src/services/config/simulador.js +1260 -0
  29. package/src/services/dynamodb/index.js +7 -3
  30. package/src/services/dynamodb/server.js +4 -2
  31. package/src/services/dynamodb/simulator.js +39 -29
  32. package/src/services/eventbridge/index.js +55 -51
  33. package/src/services/eventbridge/server.js +209 -0
  34. package/src/services/eventbridge/simulator.js +684 -0
  35. package/src/services/index.js +30 -4
  36. package/src/services/kms/index.js +75 -0
  37. package/src/services/kms/server.js +67 -0
  38. package/src/services/kms/simulator.js +324 -0
  39. package/src/services/lambda/handler-loader.js +13 -2
  40. package/src/services/lambda/index.js +7 -1
  41. package/src/services/lambda/server.js +32 -39
  42. package/src/services/lambda/simulator.js +78 -181
  43. package/src/services/parameter-store/index.js +80 -0
  44. package/src/services/parameter-store/server.js +50 -0
  45. package/src/services/parameter-store/simulator.js +201 -0
  46. package/src/services/s3/index.js +7 -3
  47. package/src/services/s3/server.js +20 -13
  48. package/src/services/s3/simulator.js +163 -407
  49. package/src/services/secret-manager/index.js +80 -0
  50. package/src/services/secret-manager/server.js +50 -0
  51. package/src/services/secret-manager/simulator.js +171 -0
  52. package/src/services/sns/index.js +55 -42
  53. package/src/services/sns/server.js +580 -0
  54. package/src/services/sns/simulator.js +1482 -0
  55. package/src/services/sqs/index.js +2 -4
  56. package/src/services/sqs/server.js +92 -18
  57. package/src/services/sqs/simulator.js +79 -298
  58. package/src/services/sts/index.js +37 -0
  59. package/src/services/sts/server.js +142 -0
  60. package/src/services/sts/simulator.js +69 -0
  61. package/src/services/xray/index.js +83 -0
  62. package/src/services/xray/server.js +308 -0
  63. package/src/services/xray/simulador.js +994 -0
  64. package/src/utils/cloudtrail-audit.js +129 -0
  65. package/src/utils/local-store.js +18 -2
@@ -21,16 +21,14 @@ class SQSService {
21
21
  const logger = require('../../utils/logger');
22
22
  logger.debug(`Inicializando SQS Service na porta ${this.port}...`);
23
23
 
24
- // Cria o simulador
25
24
  this.simulator = new SQSSimulator(this.config, this.lambdaService);
26
-
27
- // Cria o servidor HTTP
25
+ await this.simulator.initialize();
26
+
28
27
  this.server = new SQSServer(this.port, this.config, this.lambdaService);
29
28
  this.server.simulator = this.simulator;
30
29
 
31
30
  await this.server.initialize();
32
31
 
33
- // Configura filas associadas a Lambdas
34
32
  await this.setupQueueTriggers();
35
33
 
36
34
  logger.debug('SQS Service inicializado');
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  const express = require('express');
6
+ const crypto = require('crypto');
6
7
  const SQSSimulator = require('./simulator');
7
8
  const logger = require('../../utils/logger');
8
9
 
@@ -18,8 +19,23 @@ class SQSServer {
18
19
  }
19
20
 
20
21
  setupMiddlewares() {
21
- this.app.use(express.json());
22
- this.app.use(express.urlencoded({ extended: true }));
22
+ this.app.use(express.raw({ type: '*/*', limit: '10mb' }));
23
+ this.app.use((req, res, next) => {
24
+ if (req.body && Buffer.isBuffer(req.body)) {
25
+ const str = req.body.toString('utf8');
26
+ const contentType = req.headers['content-type'] || '';
27
+ if (contentType.includes('application/x-amz-json-1.0') || contentType.includes('application/json')) {
28
+ try { req.body = JSON.parse(str); } catch (e) { req.body = {}; }
29
+ } else if (contentType.includes('application/x-www-form-urlencoded')) {
30
+ req.body = Object.fromEntries(new URLSearchParams(str));
31
+ } else {
32
+ try { req.body = JSON.parse(str); } catch (e) { req.body = {}; }
33
+ }
34
+ } else if (!req.body) {
35
+ req.body = {};
36
+ }
37
+ next();
38
+ });
23
39
 
24
40
  // Logging de requisições
25
41
  if (logger.currentLogLevel === 'verboso') {
@@ -35,23 +51,44 @@ class SQSServer {
35
51
  }
36
52
 
37
53
  async initialize() {
38
- this.simulator = new SQSSimulator(this.config, this.lambdaService);
39
- await this.simulator.initialize();
54
+ if (!this.simulator) {
55
+ this.simulator = new SQSSimulator(this.config, this.lambdaService);
56
+ await this.simulator.initialize();
57
+ }
40
58
  this.setupRoutes();
41
59
  }
42
60
 
43
61
  setupRoutes() {
44
62
  // Endpoint principal
63
+ this.app.use((req, res, next) => {
64
+ logger.info(`SQS incoming: ${req.method} ${req.path} headers=${JSON.stringify(req.headers)} query=${JSON.stringify(req.query)} body=${JSON.stringify(req.body)}`);
65
+ next();
66
+ });
67
+
45
68
  this.app.post('/', (req, res) => {
46
- const action = req.query.Action || req.body.Action;
69
+ const action = req.query.Action || req.body.Action ||
70
+ (req.headers['x-amz-target'] && req.headers['x-amz-target'].split('.')[1]);
71
+ logger.info(`SQS action resolved: ${action}`);
47
72
  const result = this.simulator.handleRequest(action, req, res);
48
-
73
+ const isJsonProtocol = req.headers['content-type'] && req.headers['content-type'].includes('application/x-amz-json-1.0');
74
+
49
75
  if (result && result.error) {
50
- res.status(result.status).send(this.simulator.generateErrorResponse(result.error.code, result.error.message));
76
+ const isJsonProtocol = req.headers['content-type'] && req.headers['content-type'].includes('application/x-amz-json-1.0');
77
+ if (isJsonProtocol) {
78
+ res.status(result.status).json({ __type: result.error.code, message: result.error.message });
79
+ } else {
80
+ res.status(result.status).send(this.simulator.generateErrorResponse(result.error.code, result.error.message));
81
+ }
51
82
  } else if (result) {
52
- // Gera resposta XML
53
- res.set('Content-Type', 'application/xml');
54
- res.send(this.generateResponse(action, result));
83
+ if (isJsonProtocol) {
84
+ res.set('Content-Type', 'application/x-amz-json-1.0');
85
+ res.json(this.generateJsonResponse(action, result));
86
+ } else {
87
+ const xml = this.generateResponse(action, result);
88
+ logger.info(`SQS response for ${action}: ${xml}`);
89
+ res.set('Content-Type', 'application/xml');
90
+ res.send(xml);
91
+ }
55
92
  }
56
93
  });
57
94
 
@@ -105,6 +142,37 @@ class SQSServer {
105
142
  });
106
143
  }
107
144
 
145
+ generateJsonResponse(action, result) {
146
+ switch (action) {
147
+ case 'CreateQueue':
148
+ return { QueueUrl: result.queueUrl };
149
+ case 'SendMessage':
150
+ return { MD5OfMessageBody: result.md5, MessageId: result.messageId };
151
+ case 'SendMessageBatch':
152
+ return {
153
+ Successful: (result.successful || []).map(s => ({ Id: s.Id, MessageId: s.MessageId, MD5OfMessageBody: s.MD5OfMessageBody })),
154
+ Failed: result.failed || []
155
+ };
156
+ case 'ReceiveMessage':
157
+ return {
158
+ Messages: (result.messages || []).map(m => ({
159
+ MessageId: m.MessageId,
160
+ ReceiptHandle: m.ReceiptHandle,
161
+ MD5OfBody: m.MD5OfBody,
162
+ Body: m.Body
163
+ }))
164
+ };
165
+ case 'DeleteMessage':
166
+ return {};
167
+ case 'GetQueueUrl':
168
+ return { QueueUrl: result.queueUrl };
169
+ case 'ListQueues':
170
+ return { QueueUrls: (result.queues || []).map(q => q.url) };
171
+ default:
172
+ return result;
173
+ }
174
+ }
175
+
108
176
  generateResponse(action, result) {
109
177
  switch(action) {
110
178
  case 'CreateQueue':
@@ -128,26 +196,28 @@ class SQSServer {
128
196
 
129
197
  generateCreateQueueResponse(queueUrl) {
130
198
  return `<?xml version="1.0" encoding="UTF-8"?>
131
- <CreateQueueResponse>
199
+ <CreateQueueResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
132
200
  <CreateQueueResult>
133
201
  <QueueUrl>${queueUrl}</QueueUrl>
134
202
  </CreateQueueResult>
203
+ <ResponseMetadata><RequestId>${crypto.randomUUID()}</RequestId></ResponseMetadata>
135
204
  </CreateQueueResponse>`;
136
205
  }
137
206
 
138
207
  generateSendMessageResponse(messageId, md5) {
139
208
  return `<?xml version="1.0" encoding="UTF-8"?>
140
- <SendMessageResponse>
209
+ <SendMessageResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
141
210
  <SendMessageResult>
142
211
  <MD5OfMessageBody>${md5}</MD5OfMessageBody>
143
212
  <MessageId>${messageId}</MessageId>
144
213
  </SendMessageResult>
214
+ <ResponseMetadata><RequestId>${crypto.randomUUID()}</RequestId></ResponseMetadata>
145
215
  </SendMessageResponse>`;
146
216
  }
147
217
 
148
218
  generateSendMessageBatchResponse(successful, failed) {
149
219
  let xml = `<?xml version="1.0" encoding="UTF-8"?>
150
- <SendMessageBatchResponse>
220
+ <SendMessageBatchResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
151
221
  <SendMessageBatchResult>`;
152
222
 
153
223
  for (const s of successful) {
@@ -170,6 +240,7 @@ class SQSServer {
170
240
 
171
241
  xml += `
172
242
  </SendMessageBatchResult>
243
+ <ResponseMetadata><RequestId>${crypto.randomUUID()}</RequestId></ResponseMetadata>
173
244
  </SendMessageBatchResponse>`;
174
245
 
175
246
  return xml;
@@ -177,7 +248,7 @@ class SQSServer {
177
248
 
178
249
  generateReceiveMessageResponse(messages) {
179
250
  let xml = `<?xml version="1.0" encoding="UTF-8"?>
180
- <ReceiveMessageResponse>
251
+ <ReceiveMessageResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
181
252
  <ReceiveMessageResult>`;
182
253
 
183
254
  for (const msg of messages) {
@@ -192,6 +263,7 @@ class SQSServer {
192
263
 
193
264
  xml += `
194
265
  </ReceiveMessageResult>
266
+ <ResponseMetadata><RequestId>${crypto.randomUUID()}</RequestId></ResponseMetadata>
195
267
  </ReceiveMessageResponse>`;
196
268
 
197
269
  return xml;
@@ -199,25 +271,26 @@ class SQSServer {
199
271
 
200
272
  generateDeleteMessageResponse() {
201
273
  return `<?xml version="1.0" encoding="UTF-8"?>
202
- <DeleteMessageResponse>
274
+ <DeleteMessageResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
203
275
  <ResponseMetadata>
204
- <RequestId>${Math.random().toString(36).substring(7)}</RequestId>
276
+ <RequestId>${crypto.randomUUID()}</RequestId>
205
277
  </ResponseMetadata>
206
278
  </DeleteMessageResponse>`;
207
279
  }
208
280
 
209
281
  generateGetQueueUrlResponse(queueUrl) {
210
282
  return `<?xml version="1.0" encoding="UTF-8"?>
211
- <GetQueueUrlResponse>
283
+ <GetQueueUrlResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
212
284
  <GetQueueUrlResult>
213
285
  <QueueUrl>${queueUrl}</QueueUrl>
214
286
  </GetQueueUrlResult>
287
+ <ResponseMetadata><RequestId>${crypto.randomUUID()}</RequestId></ResponseMetadata>
215
288
  </GetQueueUrlResponse>`;
216
289
  }
217
290
 
218
291
  generateListQueuesResponse(queues) {
219
292
  let xml = `<?xml version="1.0" encoding="UTF-8"?>
220
- <ListQueuesResponse>
293
+ <ListQueuesResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
221
294
  <ListQueuesResult>`;
222
295
 
223
296
  for (const queue of queues) {
@@ -226,6 +299,7 @@ class SQSServer {
226
299
 
227
300
  xml += `
228
301
  </ListQueuesResult>
302
+ <ResponseMetadata><RequestId>${crypto.randomUUID()}</RequestId></ResponseMetadata>
229
303
  </ListQueuesResponse>`;
230
304
 
231
305
  return xml;