@gugananuvem/aws-local-simulator 1.0.22 → 1.0.25

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.
package/aws-config ADDED
@@ -0,0 +1,154 @@
1
+ // lambda/layer/utils/aws-config.js
2
+ const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
3
+ const { DynamoDBDocumentClient } = require('@aws-sdk/lib-dynamodb');
4
+ const { S3Client } = require('@aws-sdk/client-s3');
5
+ const { SQSClient } = require('@aws-sdk/client-sqs');
6
+ const { LambdaClient } = require('@aws-sdk/client-lambda');
7
+ const { CognitoIdentityProviderClient } = require("@aws-sdk/client-cognito-identity-provider");
8
+
9
+ // Detecta ambiente local
10
+ const isLocal = process.env.IS_LOCAL === 'true' ||
11
+ process.env.NODE_ENV === 'development' ||
12
+ process.env.AWS_SAM_LOCAL === 'true';
13
+
14
+ const isLocalS3 = process.env.IS_LOCAL_S3 === 'true'
15
+ const isLocalSQS = process.env.IS_LOCAL_SQS === 'true'
16
+ const isLocalDynamoDB = process.env.IS_LOCAL_DYNAMODB === 'true'
17
+ const isLocalLambda = process.env.IS_LOCAL_LAMBDA === 'true'
18
+ const isLocalCognito = process.env.IS_LOCAL_COGNITO === 'true'
19
+
20
+ // Endpoints locais (configuráveis via variáveis de ambiente)
21
+ const localEndpoints = {
22
+ dynamodb: process.env.DYNAMODB_ENDPOINT || 'http://localhost:8000',
23
+ s3: process.env.S3_ENDPOINT || 'http://localhost:4566',
24
+ sqs: process.env.SQS_ENDPOINT || 'http://localhost:9324',
25
+ lambda: process.env.LAMBDA_ENDPOINT || 'http://localhost:3001',
26
+ cognito: process.env.LOCAL_COGNITO || 'http://localhost:9229'
27
+ };
28
+
29
+ // Credenciais para ambiente local (não são validadas)
30
+ const localCredentials = {
31
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'local',
32
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'local',
33
+ sessionToken: process.env.AWS_SESSION_TOKEN || undefined
34
+ };
35
+
36
+ // Configuração base para todos os clients
37
+ const baseConfig = {
38
+ region: process.env.AWS_REGION || 'us-east-1',
39
+ credentials: isLocal ? localCredentials : undefined
40
+ };
41
+
42
+ // ============ DynamoDB Client ============
43
+ const dynamoDBClient = new DynamoDBClient({
44
+ ...baseConfig,
45
+ endpoint: isLocalDynamoDB ? localEndpoints.dynamodb : undefined,
46
+ region: process.env.AWS_REGION || "us-east-1"
47
+ });
48
+
49
+ const dynamoDBDocClient = DynamoDBDocumentClient.from(dynamoDBClient, {
50
+ marshallOptions: {
51
+ removeUndefinedValues: true,
52
+ convertEmptyValues: false
53
+ },
54
+ unmarshallOptions: {
55
+ wrapNumbers: false
56
+ }
57
+ });
58
+
59
+ const cognitoClient = new CognitoIdentityProviderClient({
60
+ ...baseConfig,
61
+ endpoint: isLocalCognito ? localEndpoints.cognito : undefined,
62
+ region: process.env.AWS_REGION || 'us-east-1'
63
+ });
64
+
65
+ // ============ S3 Client ============
66
+ const s3Client = new S3Client({
67
+ ...baseConfig,
68
+ endpoint: isLocalS3 ? localEndpoints.s3 : undefined,
69
+ forcePathStyle: true, // Necessário para S3 local (LocalStack, MinIO, etc)
70
+ // Para S3 real, não usar forcePathStyle
71
+ ...(isLocalS3 ? {} : { forcePathStyle: false })
72
+ });
73
+
74
+ // ============ SQS Client ============
75
+ const sqsClient = new SQSClient({
76
+ ...baseConfig,
77
+ endpoint: isLocalSQS ? localEndpoints.sqs : undefined
78
+ });
79
+
80
+ // ============ Lambda Client ============
81
+ const lambdaClient = new LambdaClient({
82
+ ...baseConfig,
83
+ endpoint: isLocalLambda ? localEndpoints.lambda : undefined
84
+ });
85
+
86
+ // Log de configuração (apenas em desenvolvimento)
87
+ if (isLocalDynamoDB || isLocalS3 || isLocalSQS || isLocalLambda) {
88
+ console.log('🔧 Ambiente LOCAL detectado:');
89
+ console.log(` DynamoDB: ${localEndpoints.dynamodb}`);
90
+ console.log(` S3: ${localEndpoints.s3} (forcePathStyle: true)`);
91
+ console.log(` SQS: ${localEndpoints.sqs}`);
92
+ console.log(` Lambda: ${localEndpoints.lambda}`);
93
+ console.log(` Region: ${baseConfig.region}`);
94
+ }
95
+ if (isLocalDynamoDB || isLocalS3 || isLocalSQS || isLocalLambda) {
96
+ console.log('🔧 Ambiente LOCAL detectado:');
97
+ console.log(` Region: ${baseConfig.region}`);
98
+ }
99
+
100
+ if (isLocalDynamoDB) {
101
+ console.log(` DynamoDB: ${localEndpoints.dynamodb}`);
102
+ }
103
+ if (isLocalS3) {
104
+ console.log(` S3: ${localEndpoints.s3} (forcePathStyle: true)`);
105
+ }
106
+
107
+ if (isLocalSQS) {
108
+ console.log(` SQS: ${localEndpoints.sqs}`);
109
+ }
110
+
111
+ if (isLocalLambda) {
112
+ console.log(` Lambda: ${localEndpoints.lambda}`);
113
+ }
114
+
115
+ if (isLocalCognito){
116
+ console.log(` Cognito: ${localEndpoints.cognito}`);
117
+ }
118
+
119
+ module.exports = {
120
+ // Clients
121
+ dynamoDB: dynamoDBDocClient,
122
+ cognitoClient,
123
+ dynamoDBClient,
124
+ s3: s3Client,
125
+ sqs: sqsClient,
126
+ lambda: lambdaClient,
127
+
128
+ // Utilitários
129
+ isLocal,
130
+ localEndpoints,
131
+
132
+ // Configuração
133
+ config: {
134
+ region: baseConfig.region,
135
+ isLocal,
136
+ endpoints: localEndpoints
137
+ },
138
+
139
+ // Função para criar clients customizados (útil para testes)
140
+ createS3Client: (customEndpoint) => {
141
+ return new S3Client({
142
+ ...baseConfig,
143
+ endpoint: customEndpoint || localEndpoints.s3,
144
+ forcePathStyle: true
145
+ });
146
+ },
147
+
148
+ createDynamoDBClient: (customEndpoint) => {
149
+ return new DynamoDBClient({
150
+ ...baseConfig,
151
+ endpoint: customEndpoint || localEndpoints.dynamodb
152
+ });
153
+ }
154
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gugananuvem/aws-local-simulator",
3
- "version": "1.0.22",
3
+ "version": "1.0.25",
4
4
  "description": "Simulador local completo para serviços AWS",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -75,7 +75,8 @@
75
75
  "src/",
76
76
  "bin/",
77
77
  "README.md",
78
- "LICENSE"
78
+ "LICENSE",
79
+ "aws-config"
79
80
  ],
80
81
  "publishConfig": {
81
82
  "directory": "dist"
@@ -84,11 +85,11 @@
84
85
  "cors": "^2.8.5",
85
86
  "dotenv": "^16.3.1",
86
87
  "express": "^4.18.2",
87
- "glob": "^10.3.0",
88
+ "glob": "10.5.0",
88
89
  "jsonwebtoken": "^9.0.2",
89
90
  "mkdirp": "^3.0.1",
90
91
  "urlpattern-polyfill": "^10.0.0",
91
- "uuid": "^9.0.0"
92
+ "uuid": "14.0.0"
92
93
  },
93
94
  "peerDependencies": {
94
95
  "@aws-sdk/client-api-gateway": "^3.0.0",
@@ -120,6 +121,6 @@
120
121
  "optional": true
121
122
  }
122
123
  },
123
- "buildDate": "2026-04-22T18:03:41.660Z",
124
+ "buildDate": "2026-04-24T17:52:50.093Z",
124
125
  "published": true
125
126
  }
@@ -87,10 +87,35 @@ class CognitoSimulator {
87
87
  this.loadIdentityPools();
88
88
  this.loadUsers();
89
89
  this.loadSessions();
90
+ this._watchUsersFile();
90
91
 
91
92
  logger.debug(`✅ Cognito Simulator inicializado com ${this.userPools.size} user pools, ${this.identityPools.size} identity pools, ${this.users.size} usuários`);
92
93
  }
93
94
 
95
+ _watchUsersFile() {
96
+ const fs = require("fs");
97
+ const usersFilePath = this.store.getFilePath("__users__");
98
+ if (!fs.existsSync(usersFilePath)) return;
99
+
100
+ let reloadTimeout = null;
101
+ fs.watch(usersFilePath, (eventType) => {
102
+ if (eventType !== "change") return;
103
+ // Debounce para evitar múltiplos reloads em edições rápidas
104
+ clearTimeout(reloadTimeout);
105
+ reloadTimeout = setTimeout(() => {
106
+ try {
107
+ this.users.clear();
108
+ this.loadUsers();
109
+ logger.info(`🔄 Cognito users recarregados do disco (${this.users.size} usuários)`);
110
+ } catch (err) {
111
+ logger.warn(`⚠️ Erro ao recarregar users: ${err.message}`);
112
+ }
113
+ }, 200);
114
+ });
115
+
116
+ logger.debug(`👁️ Watching: ${usersFilePath}`);
117
+ }
118
+
94
119
  // ============ User Pool Operations ============
95
120
 
96
121
  createUserPool(params) {
@@ -25,9 +25,38 @@ class DynamoDBSimulator {
25
25
  async initialize() {
26
26
  logger.debug("Inicializando DynamoDB Simulator...");
27
27
  this.loadTables();
28
+ this._watchTablesFile();
28
29
  logger.debug(`✅ DynamoDB Simulator inicializado com ${this.tables.size} tabelas`);
29
30
  }
30
31
 
32
+ _watchTablesFile() {
33
+ const fs = require("fs");
34
+ const tablesFilePath = this.store.getFilePath("__tables__");
35
+ if (!fs.existsSync(tablesFilePath)) return;
36
+
37
+ let reloadTimeout = null;
38
+ fs.watch(tablesFilePath, (eventType) => {
39
+ if (eventType !== "change") return;
40
+ clearTimeout(reloadTimeout);
41
+ reloadTimeout = setTimeout(() => {
42
+ try {
43
+ this.tables.clear();
44
+ const savedTables = this.store.read("__tables__");
45
+ if (savedTables) {
46
+ for (const [name, definition] of Object.entries(savedTables)) {
47
+ this.tables.set(name, definition);
48
+ }
49
+ }
50
+ logger.info(`🔄 DynamoDB schema recarregado (${this.tables.size} tabelas)`);
51
+ } catch (err) {
52
+ logger.warn(`⚠️ Erro ao recarregar schema: ${err.message}`);
53
+ }
54
+ }, 200);
55
+ });
56
+
57
+ logger.debug(`👁️ Watching: ${tablesFilePath}`);
58
+ }
59
+
31
60
  loadTables() {
32
61
  // Carrega tabelas existentes do disco PRIMEIRO para evitar sobrescrever definições persistidas
33
62
  const savedTables = this.store.read("__tables__");
@@ -350,8 +379,12 @@ class DynamoDBSimulator {
350
379
  response.Attributes = this.marshallItem(oldItem, table);
351
380
  break;
352
381
  case "ALL_NEW":
382
+ case "UPDATED_NEW":
353
383
  response.Attributes = this.marshallItem(updatedItem, table);
354
384
  break;
385
+ case "UPDATED_OLD":
386
+ response.Attributes = this.marshallItem(oldItem, table);
387
+ break;
355
388
  default:
356
389
  break;
357
390
  }