@gugananuvem/aws-local-simulator 1.0.12 → 1.0.15

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 (77) hide show
  1. package/README.md +594 -257
  2. package/bin/aws-local-simulator.js +63 -63
  3. package/package.json +21 -10
  4. package/src/config/config-loader.js +114 -114
  5. package/src/config/default-config.js +68 -67
  6. package/src/config/env-loader.js +68 -68
  7. package/src/index.js +146 -130
  8. package/src/index.mjs +123 -123
  9. package/src/server.js +227 -223
  10. package/src/services/apigateway/index.js +73 -68
  11. package/src/services/apigateway/server.js +507 -487
  12. package/src/services/apigateway/simulator.js +1261 -1251
  13. package/src/services/athena/index.js +75 -0
  14. package/src/services/athena/server.js +101 -0
  15. package/src/services/athena/simulador.js +998 -0
  16. package/src/services/athena/simulator.js +346 -0
  17. package/src/services/cloudformation/index.js +106 -0
  18. package/src/services/cloudformation/server.js +417 -0
  19. package/src/services/cloudformation/simulador.js +1045 -0
  20. package/src/services/cloudtrail/index.js +84 -0
  21. package/src/services/cloudtrail/server.js +235 -0
  22. package/src/services/cloudtrail/simulador.js +719 -0
  23. package/src/services/cloudwatch/index.js +84 -0
  24. package/src/services/cloudwatch/server.js +366 -0
  25. package/src/services/cloudwatch/simulador.js +1173 -0
  26. package/src/services/cognito/index.js +79 -65
  27. package/src/services/cognito/server.js +301 -279
  28. package/src/services/cognito/simulator.js +1655 -1115
  29. package/src/services/config/index.js +96 -0
  30. package/src/services/config/server.js +215 -0
  31. package/src/services/config/simulador.js +1260 -0
  32. package/src/services/dynamodb/index.js +74 -70
  33. package/src/services/dynamodb/server.js +125 -121
  34. package/src/services/dynamodb/simulator.js +630 -620
  35. package/src/services/ecs/index.js +65 -65
  36. package/src/services/ecs/server.js +235 -233
  37. package/src/services/ecs/simulator.js +844 -844
  38. package/src/services/eventbridge/index.js +89 -85
  39. package/src/services/eventbridge/server.js +209 -0
  40. package/src/services/eventbridge/simulator.js +684 -0
  41. package/src/services/index.js +45 -19
  42. package/src/services/kms/index.js +75 -0
  43. package/src/services/kms/server.js +67 -0
  44. package/src/services/kms/simulator.js +324 -0
  45. package/src/services/lambda/handler-loader.js +183 -183
  46. package/src/services/lambda/index.js +78 -73
  47. package/src/services/lambda/route-registry.js +274 -274
  48. package/src/services/lambda/server.js +145 -145
  49. package/src/services/lambda/simulator.js +199 -172
  50. package/src/services/parameter-store/index.js +80 -0
  51. package/src/services/parameter-store/server.js +50 -0
  52. package/src/services/parameter-store/simulator.js +201 -0
  53. package/src/services/s3/index.js +73 -69
  54. package/src/services/s3/server.js +329 -238
  55. package/src/services/s3/simulator.js +565 -740
  56. package/src/services/secret-manager/index.js +80 -0
  57. package/src/services/secret-manager/server.js +50 -0
  58. package/src/services/secret-manager/simulator.js +171 -0
  59. package/src/services/sns/index.js +89 -76
  60. package/src/services/sns/server.js +580 -0
  61. package/src/services/sns/simulator.js +1482 -0
  62. package/src/services/sqs/index.js +93 -95
  63. package/src/services/sqs/server.js +349 -345
  64. package/src/services/sqs/simulator.js +441 -441
  65. package/src/services/sts/index.js +37 -37
  66. package/src/services/sts/server.js +144 -142
  67. package/src/services/sts/simulator.js +69 -69
  68. package/src/services/xray/index.js +83 -0
  69. package/src/services/xray/server.js +308 -0
  70. package/src/services/xray/simulador.js +994 -0
  71. package/src/template/aws-config-template.js +87 -87
  72. package/src/template/aws-config-template.mjs +90 -90
  73. package/src/template/config-template.json +203 -203
  74. package/src/utils/aws-config.js +91 -91
  75. package/src/utils/cloudtrail-audit.js +129 -0
  76. package/src/utils/local-store.js +83 -67
  77. package/src/utils/logger.js +59 -59
@@ -1,146 +1,146 @@
1
- /**
2
- * Lambda Server - Servidor HTTP para Lambda (API Gateway style)
3
- */
4
-
5
- const express = require('express');
6
- const cors = require('cors');
7
- const LambdaSimulator = require('./simulator');
8
- const logger = require('../../utils/logger');
9
-
10
- class LambdaServer {
11
- constructor(port, config) {
12
- this.port = port;
13
- this.config = config;
14
- this.app = express();
15
- this.simulator = null;
16
- this.server = null;
17
- this.setupMiddlewares();
18
- }
19
-
20
- setupMiddlewares() {
21
- this.app.use(express.json({ limit: '10mb' }));
22
- this.app.use(express.urlencoded({ extended: true }));
23
- this.app.use(cors());
24
-
25
- // Logging de requisições
26
- if (logger.currentLogLevel === 'verboso') {
27
- this.app.use((req, res, next) => {
28
- const start = Date.now();
29
- res.on('finish', () => {
30
- const duration = Date.now() - start;
31
- logger.verboso(`Lambda: ${req.method} ${req.path} - ${duration}ms`);
32
- });
33
- next();
34
- });
35
- }
36
- }
37
-
38
- async initialize() {
39
- this.simulator = new LambdaSimulator(this.config);
40
- await this.simulator.initialize();
41
- this.setupRoutes();
42
- }
43
-
44
- setupRoutes() {
45
- // Health check
46
- this.app.get('/health', (req, res) => {
47
- res.json({ status: 'healthy', lambdas: this.simulator.getLambdasCount() });
48
- });
49
-
50
- // AWS Lambda Invoke API: POST /2015-03-31/functions/{functionName}/invocations
51
- this.app.post('/2015-03-31/functions/:functionName/invocations', async (req, res) => {
52
- const { functionName } = req.params;
53
- const invocationType = req.headers['x-amz-invocation-type'] || 'RequestResponse';
54
- const event = req.body || {};
55
-
56
- logger.debug(`Lambda invoke: ${functionName} (${invocationType})`);
57
-
58
- try {
59
- const result = await this.simulator.invoke(functionName, event, invocationType);
60
-
61
- if (invocationType === 'Event') {
62
- return res.status(202).send();
63
- }
64
-
65
- res.status(result.StatusCode || 200).json(result.Payload);
66
- } catch (err) {
67
- if (err.message && err.message.includes('Function not found')) {
68
- return res.status(404).json({ __type: 'ResourceNotFoundException', message: err.message });
69
- }
70
- logger.error('Lambda invoke error:', err);
71
- res.status(500).json({ __type: 'ServiceException', message: err.message });
72
- }
73
- });
74
-
75
- // Admin endpoints
76
- this.setupAdminRoutes();
77
- }
78
-
79
- setupAdminRoutes() {
80
- this.app.get('/__admin/functions', (req, res) => {
81
- res.json(this.simulator.listLambdas());
82
- });
83
-
84
- this.app.post('/__admin/reload', async (req, res) => {
85
- await this.simulator.reloadLambdas();
86
- res.json({ message: 'Lambdas recarregadas', count: this.simulator.getLambdasCount() });
87
- });
88
-
89
- this.app.post('/__admin/env', (req, res) => {
90
- const { key, value } = req.body;
91
- if (key && value !== undefined) {
92
- this.simulator.setEnvironmentVariable(key, value);
93
- res.json({ message: `Environment variable ${key} set` });
94
- } else {
95
- res.status(400).json({ error: 'Missing key or value' });
96
- }
97
- });
98
-
99
- this.app.get('/__admin/env', (req, res) => {
100
- res.json(this.simulator.getEnvironmentVariables());
101
- });
102
-
103
- this.app.get('/__admin/stats', (req, res) => {
104
- res.json(this.simulator.getStats());
105
- });
106
- }
107
-
108
- start() {
109
- return new Promise((resolve) => {
110
- this.server = this.app.listen(this.port, () => {
111
- logger.info(`🚀 Lambda API rodando em http://localhost:${this.port}`);
112
- this.printRoutes();
113
- resolve();
114
- });
115
- });
116
- }
117
-
118
- printRoutes() {
119
- logger.info('\n📚 Lambdas registradas:');
120
- const lambdas = this.simulator.listLambdas();
121
- for (const lambda of lambdas) {
122
- logger.info(` ${lambda.name.padEnd(30)} -> ${lambda.handlerName || 'anonymous'}`);
123
- }
124
- }
125
-
126
- stop() {
127
- return new Promise((resolve) => {
128
- if (this.server) {
129
- this.server.close(() => resolve());
130
- } else {
131
- resolve();
132
- }
133
- });
134
- }
135
-
136
- getStatus() {
137
- return {
138
- running: !!this.server,
139
- port: this.port,
140
- endpoint: `http://localhost:${this.port}`,
141
- lambdasCount: this.simulator?.getLambdasCount() || 0
142
- };
143
- }
144
- }
145
-
1
+ /**
2
+ * Lambda Server - Servidor HTTP para Lambda (API Gateway style)
3
+ */
4
+
5
+ const express = require('express');
6
+ const cors = require('cors');
7
+ const LambdaSimulator = require('./simulator');
8
+ const logger = require('../../utils/logger');
9
+
10
+ class LambdaServer {
11
+ constructor(port, config) {
12
+ this.port = port;
13
+ this.config = config;
14
+ this.app = express();
15
+ this.simulator = null;
16
+ this.server = null;
17
+ this.setupMiddlewares();
18
+ }
19
+
20
+ setupMiddlewares() {
21
+ this.app.use(express.json({ limit: '10mb' }));
22
+ this.app.use(express.urlencoded({ extended: true }));
23
+ this.app.use(cors());
24
+
25
+ // Logging de requisições
26
+ if (logger.currentLogLevel === 'verboso') {
27
+ this.app.use((req, res, next) => {
28
+ const start = Date.now();
29
+ res.on('finish', () => {
30
+ const duration = Date.now() - start;
31
+ logger.verboso(`Lambda: ${req.method} ${req.path} - ${duration}ms`);
32
+ });
33
+ next();
34
+ });
35
+ }
36
+ }
37
+
38
+ async initialize() {
39
+ this.simulator = new LambdaSimulator(this.config);
40
+ await this.simulator.initialize();
41
+ this.setupRoutes();
42
+ }
43
+
44
+ setupRoutes() {
45
+ // Health check
46
+ this.app.get('/health', (req, res) => {
47
+ res.json({ status: 'healthy', lambdas: this.simulator.getLambdasCount() });
48
+ });
49
+
50
+ // AWS Lambda Invoke API: POST /2015-03-31/functions/{functionName}/invocations
51
+ this.app.post('/2015-03-31/functions/:functionName/invocations', async (req, res) => {
52
+ const { functionName } = req.params;
53
+ const invocationType = req.headers['x-amz-invocation-type'] || 'RequestResponse';
54
+ const event = req.body || {};
55
+
56
+ logger.debug(`Lambda invoke: ${functionName} (${invocationType})`);
57
+
58
+ try {
59
+ const result = await this.simulator.invoke(functionName, event, invocationType);
60
+
61
+ if (invocationType === 'Event') {
62
+ return res.status(202).send();
63
+ }
64
+
65
+ res.status(result.StatusCode || 200).json(result.Payload);
66
+ } catch (err) {
67
+ if (err.message && err.message.includes('Function not found')) {
68
+ return res.status(404).json({ __type: 'ResourceNotFoundException', message: err.message });
69
+ }
70
+ logger.error('Lambda invoke error:', err);
71
+ res.status(500).json({ __type: 'ServiceException', message: err.message });
72
+ }
73
+ });
74
+
75
+ // Admin endpoints
76
+ this.setupAdminRoutes();
77
+ }
78
+
79
+ setupAdminRoutes() {
80
+ this.app.get('/__admin/functions', (req, res) => {
81
+ res.json(this.simulator.listLambdas());
82
+ });
83
+
84
+ this.app.post('/__admin/reload', async (req, res) => {
85
+ await this.simulator.reloadLambdas();
86
+ res.json({ message: 'Lambdas recarregadas', count: this.simulator.getLambdasCount() });
87
+ });
88
+
89
+ this.app.post('/__admin/env', (req, res) => {
90
+ const { key, value } = req.body;
91
+ if (key && value !== undefined) {
92
+ this.simulator.setEnvironmentVariable(key, value);
93
+ res.json({ message: `Environment variable ${key} set` });
94
+ } else {
95
+ res.status(400).json({ error: 'Missing key or value' });
96
+ }
97
+ });
98
+
99
+ this.app.get('/__admin/env', (req, res) => {
100
+ res.json(this.simulator.getEnvironmentVariables());
101
+ });
102
+
103
+ this.app.get('/__admin/stats', (req, res) => {
104
+ res.json(this.simulator.getStats());
105
+ });
106
+ }
107
+
108
+ start() {
109
+ return new Promise((resolve) => {
110
+ this.server = this.app.listen(this.port, () => {
111
+ logger.info(`🚀 Lambda API rodando em http://localhost:${this.port}`);
112
+ this.printRoutes();
113
+ resolve();
114
+ });
115
+ });
116
+ }
117
+
118
+ printRoutes() {
119
+ logger.info('\n📚 Lambdas registradas:');
120
+ const lambdas = this.simulator.listLambdas();
121
+ for (const lambda of lambdas) {
122
+ logger.info(` ${lambda.name.padEnd(30)} -> ${lambda.handlerName || 'anonymous'}`);
123
+ }
124
+ }
125
+
126
+ stop() {
127
+ return new Promise((resolve) => {
128
+ if (this.server) {
129
+ this.server.close(() => resolve());
130
+ } else {
131
+ resolve();
132
+ }
133
+ });
134
+ }
135
+
136
+ getStatus() {
137
+ return {
138
+ running: !!this.server,
139
+ port: this.port,
140
+ endpoint: `http://localhost:${this.port}`,
141
+ lambdasCount: this.simulator?.getLambdasCount() || 0
142
+ };
143
+ }
144
+ }
145
+
146
146
  module.exports = LambdaServer;
@@ -1,172 +1,199 @@
1
- /**
2
- * Lambda Simulator - Simula execução de funções Lambda
3
- */
4
-
5
- const HandlerLoader = require('./handler-loader');
6
- const logger = require('../../utils/logger');
7
-
8
- class LambdaSimulator {
9
- constructor(config) {
10
- this.config = config;
11
- this.lambdas = new Map(); // functionName -> { handler, env, config }
12
- this.environment = { ...process.env };
13
- }
14
-
15
- async initialize() {
16
- logger.debug('Inicializando Lambda Simulator...');
17
-
18
- if (this.config.lambdas && this.config.lambdas.length > 0) {
19
- for (const lambdaConfig of this.config.lambdas) {
20
- await this.registerLambda(lambdaConfig);
21
- }
22
- }
23
-
24
- logger.debug(`✅ ${this.lambdas.size} Lambdas registradas`);
25
- }
26
-
27
- async registerLambda(lambdaConfig) {
28
- try {
29
- const { name, handler: handlerPath, env = {}, type = 'auto' } = lambdaConfig;
30
-
31
- if (!name) {
32
- logger.warn(`Lambda sem nome ignorada: ${JSON.stringify(lambdaConfig)}`);
33
- return;
34
- }
35
-
36
- const handler = await HandlerLoader.load(handlerPath, type);
37
-
38
- this.lambdas.set(name, {
39
- name,
40
- handler,
41
- handlerPath,
42
- handlerName: handler.name || 'anonymous',
43
- env,
44
- type,
45
- registeredAt: new Date().toISOString()
46
- });
47
-
48
- logger.debug(`✅ Lambda registrada: ${name} -> ${handlerPath}`);
49
- } catch (error) {
50
- logger.error(`❌ Erro ao registrar Lambda ${lambdaConfig.name}:`, error);
51
- throw error;
52
- }
53
- }
54
-
55
- async invoke(functionName, event, invocationType = 'RequestResponse') {
56
- const lambda = this.lambdas.get(functionName);
57
-
58
- if (!lambda) {
59
- throw new Error(`Function not found: ${functionName}`);
60
- }
61
-
62
- this.applyEnvironment(lambda.env);
63
- logger.debug(`🎯 Invocando Lambda: ${functionName}`);
64
-
65
- if (invocationType === 'Event') {
66
- this.executeHandler(lambda.handler, event).catch(err =>
67
- logger.error(`❌ Async Lambda error (${functionName}):`, err)
68
- );
69
- return { StatusCode: 202 };
70
- }
71
-
72
- const result = await this.executeHandler(lambda.handler, event);
73
- return { StatusCode: result.statusCode || 200, Payload: result };
74
- }
75
-
76
- async executeHandler(handler, event) {
77
- try {
78
- const context = this.createContext();
79
- const result = await handler(event, context);
80
- return result;
81
- } catch (error) {
82
- logger.error('❌ Erro no handler:', error);
83
- return {
84
- statusCode: 500,
85
- body: JSON.stringify({ error: 'Internal Server Error', message: error.message })
86
- };
87
- }
88
- }
89
-
90
- createContext() {
91
- return {
92
- awsRequestId: Math.random().toString(36).substring(7),
93
- functionName: 'local-lambda',
94
- functionVersion: '$LATEST',
95
- invokedFunctionArn: 'arn:aws:lambda:local:000000000000:function:local-lambda',
96
- memoryLimitInMB: '1024',
97
- logGroupName: '/aws/lambda/local-lambda',
98
- logStreamName: 'local-stream',
99
- getRemainingTimeInMillis: () => 30000,
100
- callbackWaitsForEmptyEventLoop: true,
101
- identity: null,
102
- clientContext: null
103
- };
104
- }
105
-
106
- applyEnvironment(env) {
107
- for (const [key, value] of Object.entries(env)) {
108
- process.env[key] = value;
109
- this.environment[key] = value;
110
- }
111
- }
112
-
113
- setEnvironmentVariable(key, value) {
114
- process.env[key] = value;
115
- this.environment[key] = value;
116
- }
117
-
118
- getEnvironmentVariables() {
119
- return { ...this.environment };
120
- }
121
-
122
- listLambdas() {
123
- return Array.from(this.lambdas.values()).map(l => ({
124
- name: l.name,
125
- handlerName: l.handlerName,
126
- handlerPath: l.handlerPath,
127
- type: l.type,
128
- env: l.env,
129
- registeredAt: l.registeredAt
130
- }));
131
- }
132
-
133
- getLambda(name) {
134
- return this.lambdas.get(name);
135
- }
136
-
137
- getLambdasCount() {
138
- return this.lambdas.size;
139
- }
140
-
141
- async reloadLambdas() {
142
- logger.info('🔄 Recarregando Lambdas...');
143
-
144
- for (const [name, lambda] of this.lambdas.entries()) {
145
- try {
146
- const newHandler = await HandlerLoader.reload(lambda.handlerPath, lambda.type);
147
- lambda.handler = newHandler;
148
- lambda.handlerName = newHandler.name || 'anonymous';
149
- logger.debug(`✅ Lambda recarregada: ${name}`);
150
- } catch (error) {
151
- logger.error(`❌ Erro ao recarregar Lambda ${name}:`, error);
152
- }
153
- }
154
-
155
- logger.info(`✅ ${this.lambdas.size} Lambdas recarregadas`);
156
- }
157
-
158
- getStats() {
159
- return {
160
- totalLambdas: this.lambdas.size,
161
- lambdas: this.listLambdas().map(l => ({ name: l.name, handler: l.handlerName }))
162
- };
163
- }
164
-
165
- async reset() {
166
- await this.reloadLambdas();
167
- this.environment = { ...process.env };
168
- logger.debug('Lambda: Estado resetado');
169
- }
170
- }
171
-
172
- module.exports = LambdaSimulator;
1
+ /**
2
+ * Lambda Simulator - Simula execução de funções Lambda
3
+ */
4
+
5
+ const HandlerLoader = require("./handler-loader");
6
+ const logger = require("../../utils/logger");
7
+ const { CloudTrailAudit } = require("../../utils/cloudtrail-audit");
8
+
9
+ class LambdaSimulator {
10
+ constructor(config) {
11
+ this.config = config;
12
+ this.lambdas = new Map(); // functionName -> { handler, env, config }
13
+ this.environment = { ...process.env };
14
+ this.audit = new CloudTrailAudit("lambda.amazonaws.com");
15
+ }
16
+
17
+ async initialize() {
18
+ logger.debug("Inicializando Lambda Simulator...");
19
+
20
+ // Build global lambda defaults from config.global
21
+ const globalDefaults = this.config.global || {};
22
+ this.globalEnv = globalDefaults.env || {};
23
+ this.globalTimeout = globalDefaults.timeout || null;
24
+ this.globalMemorySize = globalDefaults.memorySize || null;
25
+
26
+ if (this.config.lambdas && this.config.lambdas.length > 0) {
27
+ for (const lambdaConfig of this.config.lambdas) {
28
+ await this.registerLambda(lambdaConfig);
29
+ }
30
+ }
31
+
32
+ logger.debug(`✅ ${this.lambdas.size} Lambdas registradas`);
33
+ }
34
+
35
+ async registerLambda(lambdaConfig) {
36
+ try {
37
+ const { name, handler: handlerPath, type = "auto" } = lambdaConfig;
38
+
39
+ if (!name) {
40
+ logger.warn(`Lambda sem nome ignorada: ${JSON.stringify(lambdaConfig)}`);
41
+ return;
42
+ }
43
+
44
+ // Merge: global env as base, lambda-specific env overrides
45
+ const env = {
46
+ ...(this.globalEnv || {}),
47
+ ...(lambdaConfig.env || {}),
48
+ };
49
+
50
+ const timeout = lambdaConfig.timeout ?? this.globalTimeout ?? 30;
51
+ const memorySize = lambdaConfig.memorySize ?? this.globalMemorySize ?? 128;
52
+
53
+ const handler = await HandlerLoader.load(handlerPath, type);
54
+ if (handler != undefined) {
55
+ this.lambdas.set(name, {
56
+ name,
57
+ handler,
58
+ handlerPath,
59
+ handlerName: handler.name || "anonymous",
60
+ env,
61
+ timeout,
62
+ memorySize,
63
+ type,
64
+ registeredAt: new Date().toISOString(),
65
+ });
66
+ }
67
+ logger.debug(`✅ Lambda registrada: ${name} -> ${handlerPath}`);
68
+ } catch (error) {
69
+ if (error.message.indexOf("Handler não encontrado") == -1){
70
+ logger.error(`Erro ao registrar Lambda ${lambdaConfig.name}:`, error);
71
+ throw error;
72
+ }else{
73
+ logger.error(`Erro ao registrar Lambda ${lambdaConfig.name}:`);
74
+ }
75
+ }
76
+ }
77
+
78
+ async invoke(functionName, event, invocationType = "RequestResponse") {
79
+ const lambda = this.lambdas.get(functionName);
80
+
81
+ if (!lambda) {
82
+ throw new Error(`Function not found: ${functionName}`);
83
+ }
84
+
85
+ this.applyEnvironment(lambda.env);
86
+ logger.debug(`🎯 Invocando Lambda: ${functionName}`);
87
+
88
+ if (invocationType === "Event") {
89
+ this.executeHandler(lambda.handler, event).catch((err) => logger.error(`❌ Async Lambda error (${functionName}):`, err));
90
+ return { StatusCode: 202 };
91
+ }
92
+
93
+ const result = await this.executeHandler(lambda.handler, event);
94
+ this.audit.record({
95
+ eventName: "Invoke",
96
+ readOnly: false,
97
+ resources: [{ ARN: `arn:aws:lambda:local:000000000000:function:${functionName}`, type: "AWS::Lambda::Function" }],
98
+ requestParameters: { functionName, invocationType },
99
+ });
100
+ return { StatusCode: result.statusCode || 200, Payload: result };
101
+ }
102
+
103
+ async executeHandler(handler, event) {
104
+ try {
105
+ const context = this.createContext();
106
+ const result = await handler(event, context);
107
+ return result;
108
+ } catch (error) {
109
+ logger.error("❌ Erro no handler:", error);
110
+ return {
111
+ statusCode: 500,
112
+ body: JSON.stringify({ error: "Internal Server Error", message: error.message }),
113
+ };
114
+ }
115
+ }
116
+
117
+ createContext() {
118
+ return {
119
+ awsRequestId: Math.random().toString(36).substring(7),
120
+ functionName: "local-lambda",
121
+ functionVersion: "$LATEST",
122
+ invokedFunctionArn: "arn:aws:lambda:local:000000000000:function:local-lambda",
123
+ memoryLimitInMB: "1024",
124
+ logGroupName: "/aws/lambda/local-lambda",
125
+ logStreamName: "local-stream",
126
+ getRemainingTimeInMillis: () => 30000,
127
+ callbackWaitsForEmptyEventLoop: true,
128
+ identity: null,
129
+ clientContext: null,
130
+ };
131
+ }
132
+
133
+ applyEnvironment(env) {
134
+ for (const [key, value] of Object.entries(env)) {
135
+ process.env[key] = value;
136
+ this.environment[key] = value;
137
+ }
138
+ }
139
+
140
+ setEnvironmentVariable(key, value) {
141
+ process.env[key] = value;
142
+ this.environment[key] = value;
143
+ }
144
+
145
+ getEnvironmentVariables() {
146
+ return { ...this.environment };
147
+ }
148
+
149
+ listLambdas() {
150
+ return Array.from(this.lambdas.values()).map((l) => ({
151
+ name: l.name,
152
+ handlerName: l.handlerName,
153
+ handlerPath: l.handlerPath,
154
+ type: l.type,
155
+ env: l.env,
156
+ registeredAt: l.registeredAt,
157
+ }));
158
+ }
159
+
160
+ getLambda(name) {
161
+ return this.lambdas.get(name);
162
+ }
163
+
164
+ getLambdasCount() {
165
+ return this.lambdas.size;
166
+ }
167
+
168
+ async reloadLambdas() {
169
+ logger.info("🔄 Recarregando Lambdas...");
170
+
171
+ for (const [name, lambda] of this.lambdas.entries()) {
172
+ try {
173
+ const newHandler = await HandlerLoader.reload(lambda.handlerPath, lambda.type);
174
+ lambda.handler = newHandler;
175
+ lambda.handlerName = newHandler.name || "anonymous";
176
+ logger.debug(`✅ Lambda recarregada: ${name}`);
177
+ } catch (error) {
178
+ logger.error(`❌ Erro ao recarregar Lambda ${name}:`, error);
179
+ }
180
+ }
181
+
182
+ logger.info(`✅ ${this.lambdas.size} Lambdas recarregadas`);
183
+ }
184
+
185
+ getStats() {
186
+ return {
187
+ totalLambdas: this.lambdas.size,
188
+ lambdas: this.listLambdas().map((l) => ({ name: l.name, handler: l.handlerName })),
189
+ };
190
+ }
191
+
192
+ async reset() {
193
+ await this.reloadLambdas();
194
+ this.environment = { ...process.env };
195
+ logger.debug("Lambda: Estado resetado");
196
+ }
197
+ }
198
+
199
+ module.exports = LambdaSimulator;