@gugananuvem/aws-local-simulator 1.0.8 → 1.0.9

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 (37) hide show
  1. package/bin/aws-local-simulator.js +62 -1
  2. package/package.json +10 -7
  3. package/src/config/config-loader.js +113 -0
  4. package/src/config/default-config.js +65 -0
  5. package/src/config/env-loader.js +67 -0
  6. package/src/index.js +131 -1
  7. package/src/index.mjs +124 -0
  8. package/src/server.js +219 -0
  9. package/src/services/apigateway/index.js +67 -0
  10. package/src/services/apigateway/server.js +435 -0
  11. package/src/services/apigateway/simulator.js +1252 -0
  12. package/src/services/cognito/index.js +66 -0
  13. package/src/services/cognito/server.js +229 -0
  14. package/src/services/cognito/simulator.js +848 -0
  15. package/src/services/dynamodb/index.js +71 -0
  16. package/src/services/dynamodb/server.js +122 -0
  17. package/src/services/dynamodb/simulator.js +614 -0
  18. package/src/services/eventbridge/index.js +85 -0
  19. package/src/services/index.js +19 -0
  20. package/src/services/lambda/handler-loader.js +173 -0
  21. package/src/services/lambda/index.js +73 -0
  22. package/src/services/lambda/route-registry.js +275 -0
  23. package/src/services/lambda/server.js +153 -0
  24. package/src/services/lambda/simulator.js +278 -0
  25. package/src/services/s3/index.js +70 -0
  26. package/src/services/s3/server.js +239 -0
  27. package/src/services/s3/simulator.js +740 -0
  28. package/src/services/sns/index.js +76 -0
  29. package/src/services/sqs/index.js +96 -0
  30. package/src/services/sqs/server.js +274 -0
  31. package/src/services/sqs/simulator.js +660 -0
  32. package/src/template/aws-config-template.js +88 -0
  33. package/src/template/aws-config-template.mjs +91 -0
  34. package/src/template/config-template.json +165 -0
  35. package/src/utils/aws-config.js +92 -0
  36. package/src/utils/local-store.js +68 -0
  37. package/src/utils/logger.js +60 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * AWS SDK v3 Configuration for Local Development
3
+ * Gerado pelo AWS Local Simulator
4
+ */
5
+
6
+ const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
7
+ const { DynamoDBDocumentClient } = require('@aws-sdk/lib-dynamodb');
8
+ const { S3Client } = require('@aws-sdk/client-s3');
9
+ const { SQSClient } = require('@aws-sdk/client-sqs');
10
+ const { SNSClient } = require('@aws-sdk/client-sns');
11
+ const { EventBridgeClient } = require('@aws-sdk/client-eventbridge');
12
+
13
+ // Configurações de ambiente
14
+ const isLocal = process.env.IS_LOCAL === 'true' || process.env.NODE_ENV === 'development';
15
+
16
+ // Endpoints locais (configuráveis via variáveis de ambiente)
17
+ const endpoints = {
18
+ dynamodb: process.env.DYNAMODB_ENDPOINT || 'http://localhost:8000',
19
+ s3: process.env.S3_ENDPOINT || 'http://localhost:4566',
20
+ sqs: process.env.SQS_ENDPOINT || 'http://localhost:9324',
21
+ sns: process.env.SNS_ENDPOINT || 'http://localhost:9911',
22
+ eventbridge: process.env.EVENTBRIDGE_ENDPOINT || 'http://localhost:4010'
23
+ };
24
+
25
+ // Credenciais locais
26
+ const localCredentials = {
27
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'local',
28
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'local'
29
+ };
30
+
31
+ const baseConfig = {
32
+ region: process.env.AWS_REGION || 'us-east-1',
33
+ credentials: isLocal ? localCredentials : undefined
34
+ };
35
+
36
+ // DynamoDB Client
37
+ const dynamoDBClient = new DynamoDBClient({
38
+ ...baseConfig,
39
+ endpoint: isLocal ? endpoints.dynamodb : undefined
40
+ });
41
+
42
+ const dynamoDB = DynamoDBDocumentClient.from(dynamoDBClient);
43
+
44
+ // S3 Client
45
+ const s3 = new S3Client({
46
+ ...baseConfig,
47
+ endpoint: isLocal ? endpoints.s3 : undefined,
48
+ forcePathStyle: isLocal
49
+ });
50
+
51
+ // SQS Client
52
+ const sqs = new SQSClient({
53
+ ...baseConfig,
54
+ endpoint: isLocal ? endpoints.sqs : undefined
55
+ });
56
+
57
+ // SNS Client
58
+ const sns = new SNSClient({
59
+ ...baseConfig,
60
+ endpoint: isLocal ? endpoints.sns : undefined
61
+ });
62
+
63
+ // EventBridge Client
64
+ const eventbridge = new EventBridgeClient({
65
+ ...baseConfig,
66
+ endpoint: isLocal ? endpoints.eventbridge : undefined
67
+ });
68
+
69
+ module.exports = {
70
+ // Clients
71
+ dynamoDB,
72
+ dynamoDBClient,
73
+ s3,
74
+ sqs,
75
+ sns,
76
+ eventbridge,
77
+
78
+ // Utilitários
79
+ isLocal,
80
+ endpoints,
81
+
82
+ // Configuração
83
+ config: {
84
+ region: baseConfig.region,
85
+ isLocal,
86
+ endpoints
87
+ }
88
+ };
@@ -0,0 +1,91 @@
1
+ /**
2
+ * AWS SDK v3 Configuration for Local Development (ES Module)
3
+ * Gerado pelo AWS Local Simulator
4
+ */
5
+
6
+ import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
7
+ import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
8
+ import { S3Client } from '@aws-sdk/client-s3';
9
+ import { SQSClient } from '@aws-sdk/client-sqs';
10
+ import { SNSClient } from '@aws-sdk/client-sns';
11
+ import { EventBridgeClient } from '@aws-sdk/client-eventbridge';
12
+
13
+ // Configurações de ambiente
14
+ const isLocal = process.env.IS_LOCAL === 'true' || process.env.NODE_ENV === 'development';
15
+
16
+ // Endpoints locais
17
+ const endpoints = {
18
+ dynamodb: process.env.DYNAMODB_ENDPOINT || 'http://localhost:8000',
19
+ s3: process.env.S3_ENDPOINT || 'http://localhost:4566',
20
+ sqs: process.env.SQS_ENDPOINT || 'http://localhost:9324',
21
+ sns: process.env.SNS_ENDPOINT || 'http://localhost:9911',
22
+ eventbridge: process.env.EVENTBRIDGE_ENDPOINT || 'http://localhost:4010'
23
+ };
24
+
25
+ // Credenciais locais
26
+ const localCredentials = {
27
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'local',
28
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'local'
29
+ };
30
+
31
+ const baseConfig = {
32
+ region: process.env.AWS_REGION || 'us-east-1',
33
+ credentials: isLocal ? localCredentials : undefined
34
+ };
35
+
36
+ // DynamoDB Client
37
+ const dynamoDBClient = new DynamoDBClient({
38
+ ...baseConfig,
39
+ endpoint: isLocal ? endpoints.dynamodb : undefined
40
+ });
41
+
42
+ const dynamoDB = DynamoDBDocumentClient.from(dynamoDBClient);
43
+
44
+ // S3 Client
45
+ const s3 = new S3Client({
46
+ ...baseConfig,
47
+ endpoint: isLocal ? endpoints.s3 : undefined,
48
+ forcePathStyle: isLocal
49
+ });
50
+
51
+ // SQS Client
52
+ const sqs = new SQSClient({
53
+ ...baseConfig,
54
+ endpoint: isLocal ? endpoints.sqs : undefined
55
+ });
56
+
57
+ // SNS Client
58
+ const sns = new SNSClient({
59
+ ...baseConfig,
60
+ endpoint: isLocal ? endpoints.sns : undefined
61
+ });
62
+
63
+ // EventBridge Client
64
+ const eventbridge = new EventBridgeClient({
65
+ ...baseConfig,
66
+ endpoint: isLocal ? endpoints.eventbridge : undefined
67
+ });
68
+
69
+ export {
70
+ dynamoDB,
71
+ dynamoDBClient,
72
+ s3,
73
+ sqs,
74
+ sns,
75
+ eventbridge,
76
+ isLocal,
77
+ endpoints,
78
+ baseConfig as config
79
+ };
80
+
81
+ export default {
82
+ dynamoDB,
83
+ dynamoDBClient,
84
+ s3,
85
+ sqs,
86
+ sns,
87
+ eventbridge,
88
+ isLocal,
89
+ endpoints,
90
+ config: baseConfig
91
+ };
@@ -0,0 +1,165 @@
1
+ {
2
+ "services": {
3
+ "dynamodb": true,
4
+ "s3": true,
5
+ "sqs": true,
6
+ "lambda": true,
7
+ "sns": false,
8
+ "eventbridge": false,
9
+ "apigateway": true
10
+ },
11
+ "ports": {
12
+ "dynamodb": 8000,
13
+ "s3": 4566,
14
+ "sqs": 9324,
15
+ "lambda": 3001,
16
+ "sns": 9911,
17
+ "eventbridge": 4010
18
+ },
19
+ "lambdas": [
20
+ {
21
+ "path": "/api/users",
22
+ "handler": "./src/handlers/users.js",
23
+ "type": "commonjs",
24
+ "env": {
25
+ "TABLE_NAME": "users-table",
26
+ "BUCKET_NAME": "user-files"
27
+ }
28
+ },
29
+ {
30
+ "path": "/api/products",
31
+ "handler": "./src/handlers/products.mjs",
32
+ "type": "module",
33
+ "env": {
34
+ "TABLE_NAME": "products-table"
35
+ }
36
+ }
37
+ ],
38
+ "dynamodb": {
39
+ "tables": [
40
+ {
41
+ "TableName": "users-table",
42
+ "KeySchema": [
43
+ { "AttributeName": "userId", "KeyType": "HASH" }
44
+ ],
45
+ "AttributeDefinitions": [
46
+ { "AttributeName": "userId", "AttributeType": "S" }
47
+ ],
48
+ "ProvisionedThroughput": {
49
+ "ReadCapacityUnits": 5,
50
+ "WriteCapacityUnits": 5
51
+ }
52
+ }
53
+ ]
54
+ },
55
+ "s3": {
56
+ "buckets": ["users-files", "public-assets"]
57
+ },
58
+ "sqs": {
59
+ "queues": [
60
+ {
61
+ "name": "notifications-queue",
62
+ "lambdaPath": "/api/notifications",
63
+ "batchSize": 10
64
+ }
65
+ ]
66
+ },
67
+ "apigateway": {
68
+ "defaultCors": {
69
+ "allowOrigins": ["http://localhost:3000"],
70
+ "allowMethods": ["GET", "POST", "PUT", "DELETE"],
71
+ "allowHeaders": ["Content-Type", "Authorization"],
72
+ "maxAge": 300
73
+ },
74
+ "defaultThrottling": {
75
+ "burstLimit": 50,
76
+ "rateLimit": 10
77
+ },
78
+ "enableAccessLogging": true
79
+ },
80
+ "restApis": [
81
+ {
82
+ "name": "MyAPI",
83
+ "description": "My REST API",
84
+ "resources": [
85
+ {
86
+ "path": "/users",
87
+ "methods": [
88
+ {
89
+ "httpMethod": "GET",
90
+ "authorizationType": "NONE",
91
+ "integration": {
92
+ "type": "HTTP",
93
+ "uri": "http://localhost:3001/users",
94
+ "httpMethod": "GET"
95
+ }
96
+ },
97
+ {
98
+ "httpMethod": "POST",
99
+ "authorizationType": "NONE",
100
+ "integration": {
101
+ "type": "AWS",
102
+ "uri": "arn:aws:lambda:local:function:createUser"
103
+ }
104
+ }
105
+ ]
106
+ },
107
+ {
108
+ "path": "/users/{userId}",
109
+ "methods": [
110
+ {
111
+ "httpMethod": "GET",
112
+ "authorizationType": "NONE",
113
+ "integration": {
114
+ "type": "HTTP",
115
+ "uri": "http://localhost:3001/users/{userId}",
116
+ "httpMethod": "GET"
117
+ }
118
+ }
119
+ ]
120
+ }
121
+ ],
122
+ "stages": [
123
+ {
124
+ "stageName": "dev",
125
+ "variables": {
126
+ "ENVIRONMENT": "development"
127
+ }
128
+ },
129
+ {
130
+ "stageName": "prod",
131
+ "variables": {
132
+ "ENVIRONMENT": "production"
133
+ }
134
+ }
135
+ ]
136
+ }
137
+ ],
138
+ "apiKeys": [
139
+ {
140
+ "name": "MyAPIKey",
141
+ "description": "Key for MyAPI",
142
+ "enabled": true
143
+ }
144
+ ],
145
+ "usagePlans": [
146
+ {
147
+ "name": "BasicPlan",
148
+ "description": "Basic usage plan",
149
+ "throttle": {
150
+ "burstLimit": 100,
151
+ "rateLimit": 10
152
+ },
153
+ "quota": {
154
+ "limit": 10000,
155
+ "period": "DAY"
156
+ },
157
+ "apiStages": [
158
+ {
159
+ "apiId": "api_123",
160
+ "stage": "dev"
161
+ }
162
+ ]
163
+ }
164
+ ]
165
+ }
@@ -0,0 +1,92 @@
1
+ // src/utils/aws-config.js
2
+
3
+ /**
4
+ * Cria configuração para AWS SDK baseada no ambiente
5
+ */
6
+ function createAWSConfig(options = {}) {
7
+ const isLocal = process.env.NODE_ENV === 'development' || process.env.IS_LOCAL === 'true';
8
+
9
+ const config = {
10
+ region: options.region || process.env.AWS_REGION || 'us-east-1',
11
+ credentials: options.credentials || {
12
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'local',
13
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'local'
14
+ }
15
+ };
16
+
17
+ if (isLocal || options.forceLocal) {
18
+ config.endpoints = {
19
+ dynamoDB: options.dynamoDBEndpoint || process.env.DYNAMODB_ENDPOINT || 'http://localhost:8000',
20
+ s3: options.s3Endpoint || process.env.S3_ENDPOINT || 'http://localhost:4566',
21
+ sqs: options.sqsEndpoint || process.env.SQS_ENDPOINT || 'http://localhost:9324',
22
+ lambda: options.lambdaEndpoint || process.env.LAMBDA_ENDPOINT || 'http://localhost:3001'
23
+ };
24
+ }
25
+
26
+ return config;
27
+ }
28
+
29
+ /**
30
+ * Cria cliente DynamoDB configurado
31
+ */
32
+ function createDynamoDBClient(options = {}) {
33
+ const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
34
+ const config = createAWSConfig(options);
35
+
36
+ const clientConfig = {
37
+ region: config.region,
38
+ credentials: config.credentials
39
+ };
40
+
41
+ if (config.endpoints?.dynamoDB) {
42
+ clientConfig.endpoint = config.endpoints.dynamoDB;
43
+ }
44
+
45
+ return new DynamoDBClient(clientConfig);
46
+ }
47
+
48
+ /**
49
+ * Cria cliente S3 configurado
50
+ */
51
+ function createS3Client(options = {}) {
52
+ const { S3Client } = require('@aws-sdk/client-s3');
53
+ const config = createAWSConfig(options);
54
+
55
+ const clientConfig = {
56
+ region: config.region,
57
+ credentials: config.credentials
58
+ };
59
+
60
+ if (config.endpoints?.s3) {
61
+ clientConfig.endpoint = config.endpoints.s3;
62
+ clientConfig.forcePathStyle = true; // Necessário para S3 local
63
+ }
64
+
65
+ return new S3Client(clientConfig);
66
+ }
67
+
68
+ /**
69
+ * Cria cliente SQS configurado
70
+ */
71
+ function createSQSClient(options = {}) {
72
+ const { SQSClient } = require('@aws-sdk/client-sqs');
73
+ const config = createAWSConfig(options);
74
+
75
+ const clientConfig = {
76
+ region: config.region,
77
+ credentials: config.credentials
78
+ };
79
+
80
+ if (config.endpoints?.sqs) {
81
+ clientConfig.endpoint = config.endpoints.sqs;
82
+ }
83
+
84
+ return new SQSClient(clientConfig);
85
+ }
86
+
87
+ module.exports = {
88
+ createAWSConfig,
89
+ createDynamoDBClient,
90
+ createS3Client,
91
+ createSQSClient
92
+ };
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Local Store - Persistência em arquivos JSON
3
+ */
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const mkdirp = require('mkdirp');
8
+
9
+ class LocalStore {
10
+ constructor(dataDir) {
11
+ this.dataDir = dataDir;
12
+ this.ensureDir();
13
+ }
14
+
15
+ ensureDir() {
16
+ if (!fs.existsSync(this.dataDir)) {
17
+ mkdirp.sync(this.dataDir);
18
+ }
19
+ }
20
+
21
+ getFilePath(entity) {
22
+ return path.join(this.dataDir, `${entity}.json`);
23
+ }
24
+
25
+ read(entity) {
26
+ const filePath = this.getFilePath(entity);
27
+ if (!fs.existsSync(filePath)) return [];
28
+
29
+ try {
30
+ const content = fs.readFileSync(filePath, 'utf8');
31
+ return JSON.parse(content);
32
+ } catch (error) {
33
+ console.error(`Erro ao ler ${entity}:`, error);
34
+ return [];
35
+ }
36
+ }
37
+
38
+ write(entity, data) {
39
+ const filePath = this.getFilePath(entity);
40
+ try {
41
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
42
+ } catch (error) {
43
+ console.error(`Erro ao escrever ${entity}:`, error);
44
+ throw error;
45
+ }
46
+ }
47
+
48
+ delete(entity) {
49
+ const filePath = this.getFilePath(entity);
50
+ if (fs.existsSync(filePath)) {
51
+ fs.unlinkSync(filePath);
52
+ }
53
+ }
54
+
55
+ exists(entity) {
56
+ const filePath = this.getFilePath(entity);
57
+ return fs.existsSync(filePath);
58
+ }
59
+
60
+ list() {
61
+ if (!fs.existsSync(this.dataDir)) return [];
62
+ return fs.readdirSync(this.dataDir)
63
+ .filter(f => f.endsWith('.json'))
64
+ .map(f => f.replace('.json', ''));
65
+ }
66
+ }
67
+
68
+ module.exports = LocalStore;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Logger configurável
3
+ */
4
+
5
+ let currentLogLevel = 'info';
6
+
7
+ const LOG_LEVELS = {
8
+ silent: 0,
9
+ error: 1,
10
+ warn: 2,
11
+ info: 3,
12
+ debug: 4,
13
+ verboso: 5
14
+ };
15
+
16
+ class Logger {
17
+ static setLevel(level) {
18
+ if (LOG_LEVELS[level] !== undefined) {
19
+ currentLogLevel = level;
20
+ }
21
+ }
22
+
23
+ static error(...args) {
24
+ if (LOG_LEVELS[currentLogLevel] >= LOG_LEVELS.error) {
25
+ console.error('\x1b[31m%s\x1b[0m', '❌', ...args);
26
+ }
27
+ }
28
+
29
+ static warn(...args) {
30
+ if (LOG_LEVELS[currentLogLevel] >= LOG_LEVELS.warn) {
31
+ console.warn('\x1b[33m%s\x1b[0m', '⚠️', ...args);
32
+ }
33
+ }
34
+
35
+ static info(...args) {
36
+ if (LOG_LEVELS[currentLogLevel] >= LOG_LEVELS.info) {
37
+ console.log('\x1b[36m%s\x1b[0m', 'ℹ️', ...args);
38
+ }
39
+ }
40
+
41
+ static debug(...args) {
42
+ if (LOG_LEVELS[currentLogLevel] >= LOG_LEVELS.debug) {
43
+ console.debug('\x1b[90m%s\x1b[0m', '🔍', ...args);
44
+ }
45
+ }
46
+
47
+ static verboso(...args) {
48
+ if (LOG_LEVELS[currentLogLevel] >= LOG_LEVELS.verboso) {
49
+ console.log('\x1b[35m%s\x1b[0m', '📝', ...args);
50
+ }
51
+ }
52
+
53
+ static success(...args) {
54
+ if (LOG_LEVELS[currentLogLevel] >= LOG_LEVELS.info) {
55
+ console.log('\x1b[32m%s\x1b[0m', '✅', ...args);
56
+ }
57
+ }
58
+ }
59
+
60
+ module.exports = Logger;