infrawise 0.3.0 → 0.4.0
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/README.md +6 -1
- package/dist/adapters/aws.js +1 -1
- package/dist/adapters/logs.js +2 -2
- package/dist/cli/commands/analyze.js +1 -1
- package/dist/context/index.js +59 -20
- package/dist/graph/index.js +16 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -220,6 +220,9 @@ lambda:
|
|
|
220
220
|
rds:
|
|
221
221
|
enabled: false
|
|
222
222
|
|
|
223
|
+
kafka:
|
|
224
|
+
enabled: false
|
|
225
|
+
|
|
223
226
|
cloudwatchLogs:
|
|
224
227
|
enabled: false
|
|
225
228
|
logGroupPrefixes: []
|
|
@@ -284,6 +287,7 @@ Works from AWS APIs, database schema introspection, and IaC files — no depende
|
|
|
284
287
|
| PostgreSQL / MySQL schema | Tables, indexes, column types |
|
|
285
288
|
| MongoDB schema | Collections, indexes |
|
|
286
289
|
| SQS | Missing DLQs, unencrypted queues, large backlogs |
|
|
290
|
+
| Kafka (kafkajs) | Producer/consumer topic mapping from code |
|
|
287
291
|
| Secrets Manager | Missing secret rotation |
|
|
288
292
|
| Lambda | Default memory (128 MB), high timeouts |
|
|
289
293
|
| RDS | Publicly accessible, no backups, unencrypted, no deletion protection, single-AZ |
|
|
@@ -309,7 +313,7 @@ Uses [ts-morph](https://ts-morph.com/) AST analysis to detect which functions ca
|
|
|
309
313
|
|
|
310
314
|
Non-TypeScript/JavaScript projects still get full value from infrastructure-level analyzers — code correlation (function-to-table mapping, N+1 patterns) is skipped.
|
|
311
315
|
|
|
312
|
-
The scanner supports: AWS SDK v3/v2 for DynamoDB, `pg`/Prisma/Knex for PostgreSQL, `mysql2`/Knex for MySQL, driver/Mongoose for MongoDB,
|
|
316
|
+
The scanner supports: AWS SDK v3/v2 for DynamoDB, `pg`/Prisma/Knex for PostgreSQL, `mysql2`/Knex for MySQL, driver/Mongoose for MongoDB, AWS SDK v3 for SQS/SNS/SSM/Secrets/Lambda, and `kafkajs` for Kafka topics (producer/consumer).
|
|
313
317
|
|
|
314
318
|
---
|
|
315
319
|
|
|
@@ -399,6 +403,7 @@ src/
|
|
|
399
403
|
- Kubernetes workload graphing
|
|
400
404
|
- VS Code extension
|
|
401
405
|
- Infrastructure drift detection
|
|
406
|
+
- MSK (Amazon Managed Streaming for Apache Kafka) — cluster metadata + topic listing via MSK API and Kafka admin client
|
|
402
407
|
|
|
403
408
|
### Under consideration
|
|
404
409
|
- OpenTelemetry integration
|
package/dist/adapters/aws.js
CHANGED
|
@@ -244,7 +244,7 @@ async function extractRDSMetadata(cfg = {}) {
|
|
|
244
244
|
instanceClass: db.DBInstanceClass ?? '',
|
|
245
245
|
publiclyAccessible: db.PubliclyAccessible ?? false,
|
|
246
246
|
storageEncrypted: db.StorageEncrypted ?? false,
|
|
247
|
-
|
|
247
|
+
backupRetentionDays: db.BackupRetentionPeriod ?? 0,
|
|
248
248
|
deletionProtection: db.DeletionProtection ?? false,
|
|
249
249
|
multiAZ: db.MultiAZ ?? false,
|
|
250
250
|
dbInstanceStatus: db.DBInstanceStatus ?? '',
|
package/dist/adapters/logs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.extractLogsMetadata = extractLogsMetadata;
|
|
4
4
|
exports.validateLogsAccess = validateLogsAccess;
|
|
5
5
|
const client_cloudwatch_logs_1 = require("@aws-sdk/client-cloudwatch-logs");
|
|
6
6
|
const credential_providers_1 = require("@aws-sdk/credential-providers");
|
|
@@ -44,7 +44,7 @@ function topPatterns(messages, limit = 5) {
|
|
|
44
44
|
.slice(0, limit)
|
|
45
45
|
.map(([pattern, count]) => ({ pattern, count }));
|
|
46
46
|
}
|
|
47
|
-
async function
|
|
47
|
+
async function extractLogsMetadata(cfg = {}) {
|
|
48
48
|
const client = new client_cloudwatch_logs_1.CloudWatchLogsClient(clientConfig(cfg));
|
|
49
49
|
const windowMs = (cfg.windowHours ?? 24) * 60 * 60 * 1000;
|
|
50
50
|
const startTime = Date.now() - windowMs;
|
|
@@ -194,7 +194,7 @@ async function runAnalyze(options = {}) {
|
|
|
194
194
|
if (config.cloudwatchLogs?.enabled) {
|
|
195
195
|
const spin = (0, ora_1.default)({ text: chalk_1.default.dim('Sampling CloudWatch Logs (errors only, max 50 groups)...'), color: 'cyan' }).start();
|
|
196
196
|
try {
|
|
197
|
-
const result = await (0, logs_1.
|
|
197
|
+
const result = await (0, logs_1.extractLogsMetadata)({
|
|
198
198
|
...awsCfg,
|
|
199
199
|
logGroupPrefixes: config.cloudwatchLogs.logGroupPrefixes,
|
|
200
200
|
windowHours: config.cloudwatchLogs.windowHours,
|
package/dist/context/index.js
CHANGED
|
@@ -82,6 +82,11 @@ const MONGO_COLLECTION_METHODS = new Set(['collection']);
|
|
|
82
82
|
// ── AWS service patterns ──────────────────────────────────────────────────────
|
|
83
83
|
const SQS_COMMANDS = new Set(['SendMessageCommand', 'SendMessageBatchCommand', 'ReceiveMessageCommand', 'DeleteMessageCommand', 'sendMessage', 'sendMessageBatch', 'receiveMessage']);
|
|
84
84
|
const SNS_COMMANDS = new Set(['PublishCommand', 'PublishBatchCommand', 'publish', 'publishBatch']);
|
|
85
|
+
// kafkajs patterns — detection relies on variable naming (producer/consumer/kafka)
|
|
86
|
+
const KAFKA_PRODUCER_METHODS = new Set(['send', 'sendBatch']);
|
|
87
|
+
const KAFKA_CONSUMER_METHODS = new Set(['subscribe']);
|
|
88
|
+
const KAFKA_CLIENT_PATTERNS = ['kafka', 'producer', 'consumer'];
|
|
89
|
+
const KAFKA_TOPIC_KEYS = ['topic'];
|
|
85
90
|
const SSM_COMMANDS = new Set(['GetParameterCommand', 'GetParametersCommand', 'GetParametersByPathCommand', 'getParameter', 'getParameters', 'getParametersByPath']);
|
|
86
91
|
const SECRETS_COMMANDS = new Set(['GetSecretValueCommand', 'getSecretValue']);
|
|
87
92
|
const LAMBDA_COMMANDS = new Set(['InvokeCommand', 'InvokeAsyncCommand', 'invoke', 'invokeAsync']);
|
|
@@ -158,7 +163,7 @@ function detectDynamoOperations(callExpr, filePath) {
|
|
|
158
163
|
return {
|
|
159
164
|
functionName: getEnclosingFunctionName(callExpr),
|
|
160
165
|
operationType: className,
|
|
161
|
-
|
|
166
|
+
serviceType: 'dynamodb',
|
|
162
167
|
target: tableName,
|
|
163
168
|
filePath,
|
|
164
169
|
};
|
|
@@ -173,7 +178,7 @@ function detectDynamoOperations(callExpr, filePath) {
|
|
|
173
178
|
return {
|
|
174
179
|
functionName: getEnclosingFunctionName(callExpr),
|
|
175
180
|
operationType: methodName,
|
|
176
|
-
|
|
181
|
+
serviceType: 'dynamodb',
|
|
177
182
|
target: tableName,
|
|
178
183
|
filePath,
|
|
179
184
|
};
|
|
@@ -229,7 +234,7 @@ function detectPostgresOperations(callExpr, filePath) {
|
|
|
229
234
|
return {
|
|
230
235
|
functionName: getEnclosingFunctionName(callExpr),
|
|
231
236
|
operationType: 'query',
|
|
232
|
-
|
|
237
|
+
serviceType: 'postgres',
|
|
233
238
|
target: tableName,
|
|
234
239
|
filePath,
|
|
235
240
|
};
|
|
@@ -245,7 +250,7 @@ function detectPostgresOperations(callExpr, filePath) {
|
|
|
245
250
|
return {
|
|
246
251
|
functionName: getEnclosingFunctionName(callExpr),
|
|
247
252
|
operationType: methodName,
|
|
248
|
-
|
|
253
|
+
serviceType: 'postgres',
|
|
249
254
|
target: modelName,
|
|
250
255
|
filePath,
|
|
251
256
|
};
|
|
@@ -262,7 +267,7 @@ function detectPostgresOperations(callExpr, filePath) {
|
|
|
262
267
|
return {
|
|
263
268
|
functionName: getEnclosingFunctionName(callExpr),
|
|
264
269
|
operationType: methodName,
|
|
265
|
-
|
|
270
|
+
serviceType: 'postgres',
|
|
266
271
|
target: 'unknown',
|
|
267
272
|
filePath,
|
|
268
273
|
};
|
|
@@ -278,7 +283,7 @@ function detectPostgresOperations(callExpr, filePath) {
|
|
|
278
283
|
return {
|
|
279
284
|
functionName: getEnclosingFunctionName(callExpr),
|
|
280
285
|
operationType: methodName,
|
|
281
|
-
|
|
286
|
+
serviceType: 'postgres',
|
|
282
287
|
target: tableName,
|
|
283
288
|
filePath,
|
|
284
289
|
};
|
|
@@ -315,7 +320,7 @@ function detectMySQLOperations(callExpr, filePath) {
|
|
|
315
320
|
return {
|
|
316
321
|
functionName: getEnclosingFunctionName(callExpr),
|
|
317
322
|
operationType: 'query',
|
|
318
|
-
|
|
323
|
+
serviceType: 'mysql',
|
|
319
324
|
target: tableName,
|
|
320
325
|
filePath,
|
|
321
326
|
};
|
|
@@ -334,7 +339,7 @@ function detectMySQLOperations(callExpr, filePath) {
|
|
|
334
339
|
return {
|
|
335
340
|
functionName: getEnclosingFunctionName(callExpr),
|
|
336
341
|
operationType: methodName,
|
|
337
|
-
|
|
342
|
+
serviceType: 'mysql',
|
|
338
343
|
target: tableName,
|
|
339
344
|
filePath,
|
|
340
345
|
};
|
|
@@ -382,7 +387,7 @@ function detectMongoOperations(callExpr, filePath) {
|
|
|
382
387
|
return {
|
|
383
388
|
functionName: getEnclosingFunctionName(callExpr),
|
|
384
389
|
operationType: opType,
|
|
385
|
-
|
|
390
|
+
serviceType: 'mongodb',
|
|
386
391
|
target: collectionName,
|
|
387
392
|
filePath,
|
|
388
393
|
};
|
|
@@ -399,7 +404,7 @@ function detectMongoOperations(callExpr, filePath) {
|
|
|
399
404
|
return {
|
|
400
405
|
functionName: getEnclosingFunctionName(callExpr),
|
|
401
406
|
operationType: 'query',
|
|
402
|
-
|
|
407
|
+
serviceType: 'mongodb',
|
|
403
408
|
target: collectionName,
|
|
404
409
|
filePath,
|
|
405
410
|
};
|
|
@@ -422,6 +427,35 @@ function extractArgValue(arg, ...keys) {
|
|
|
422
427
|
}
|
|
423
428
|
return 'unknown';
|
|
424
429
|
}
|
|
430
|
+
function detectKafkaOperations(callExpr, filePath) {
|
|
431
|
+
const expr = callExpr.getExpression();
|
|
432
|
+
const args = callExpr.getArguments();
|
|
433
|
+
if (!ts_morph_1.Node.isPropertyAccessExpression(expr))
|
|
434
|
+
return null;
|
|
435
|
+
const methodName = expr.getName();
|
|
436
|
+
const objText = expr.getExpression().getText().toLowerCase();
|
|
437
|
+
if (!KAFKA_CLIENT_PATTERNS.some((p) => objText.includes(p)))
|
|
438
|
+
return null;
|
|
439
|
+
if (KAFKA_PRODUCER_METHODS.has(methodName)) {
|
|
440
|
+
return {
|
|
441
|
+
functionName: getEnclosingFunctionName(callExpr),
|
|
442
|
+
operationType: methodName,
|
|
443
|
+
serviceType: 'kafka',
|
|
444
|
+
target: args.length > 0 ? extractArgValue(args[0], ...KAFKA_TOPIC_KEYS) : 'unknown',
|
|
445
|
+
filePath,
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
if (KAFKA_CONSUMER_METHODS.has(methodName)) {
|
|
449
|
+
return {
|
|
450
|
+
functionName: getEnclosingFunctionName(callExpr),
|
|
451
|
+
operationType: methodName,
|
|
452
|
+
serviceType: 'kafka',
|
|
453
|
+
target: args.length > 0 ? extractArgValue(args[0], ...KAFKA_TOPIC_KEYS) : 'unknown',
|
|
454
|
+
filePath,
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
425
459
|
function detectAWSServiceOperations(callExpr, filePath) {
|
|
426
460
|
const expr = callExpr.getExpression();
|
|
427
461
|
const args = callExpr.getArguments();
|
|
@@ -435,7 +469,7 @@ function detectAWSServiceOperations(callExpr, filePath) {
|
|
|
435
469
|
return {
|
|
436
470
|
functionName: getEnclosingFunctionName(callExpr),
|
|
437
471
|
operationType: className,
|
|
438
|
-
|
|
472
|
+
serviceType: 'sqs',
|
|
439
473
|
target: cmdArgs.length > 0 ? extractArgValue(cmdArgs[0], ...SQS_ARG_KEYS) : 'unknown',
|
|
440
474
|
filePath,
|
|
441
475
|
};
|
|
@@ -444,7 +478,7 @@ function detectAWSServiceOperations(callExpr, filePath) {
|
|
|
444
478
|
return {
|
|
445
479
|
functionName: getEnclosingFunctionName(callExpr),
|
|
446
480
|
operationType: className,
|
|
447
|
-
|
|
481
|
+
serviceType: 'sns',
|
|
448
482
|
target: cmdArgs.length > 0 ? extractArgValue(cmdArgs[0], ...SNS_ARG_KEYS) : 'unknown',
|
|
449
483
|
filePath,
|
|
450
484
|
};
|
|
@@ -453,7 +487,7 @@ function detectAWSServiceOperations(callExpr, filePath) {
|
|
|
453
487
|
return {
|
|
454
488
|
functionName: getEnclosingFunctionName(callExpr),
|
|
455
489
|
operationType: className,
|
|
456
|
-
|
|
490
|
+
serviceType: 'ssm',
|
|
457
491
|
target: cmdArgs.length > 0 ? extractArgValue(cmdArgs[0], ...SSM_ARG_KEYS) : 'unknown',
|
|
458
492
|
filePath,
|
|
459
493
|
};
|
|
@@ -462,7 +496,7 @@ function detectAWSServiceOperations(callExpr, filePath) {
|
|
|
462
496
|
return {
|
|
463
497
|
functionName: getEnclosingFunctionName(callExpr),
|
|
464
498
|
operationType: className,
|
|
465
|
-
|
|
499
|
+
serviceType: 'secretsmanager',
|
|
466
500
|
target: cmdArgs.length > 0 ? extractArgValue(cmdArgs[0], ...SECRETS_ARG_KEYS) : 'unknown',
|
|
467
501
|
filePath,
|
|
468
502
|
};
|
|
@@ -471,7 +505,7 @@ function detectAWSServiceOperations(callExpr, filePath) {
|
|
|
471
505
|
return {
|
|
472
506
|
functionName: getEnclosingFunctionName(callExpr),
|
|
473
507
|
operationType: className,
|
|
474
|
-
|
|
508
|
+
serviceType: 'lambda',
|
|
475
509
|
target: cmdArgs.length > 0 ? extractArgValue(cmdArgs[0], ...LAMBDA_ARG_KEYS) : 'unknown',
|
|
476
510
|
filePath,
|
|
477
511
|
};
|
|
@@ -486,7 +520,7 @@ function detectAWSServiceOperations(callExpr, filePath) {
|
|
|
486
520
|
return {
|
|
487
521
|
functionName: getEnclosingFunctionName(callExpr),
|
|
488
522
|
operationType: methodName,
|
|
489
|
-
|
|
523
|
+
serviceType: 'sqs',
|
|
490
524
|
target: args.length > 0 ? extractArgValue(args[0], ...SQS_ARG_KEYS) : 'unknown',
|
|
491
525
|
filePath,
|
|
492
526
|
};
|
|
@@ -495,7 +529,7 @@ function detectAWSServiceOperations(callExpr, filePath) {
|
|
|
495
529
|
return {
|
|
496
530
|
functionName: getEnclosingFunctionName(callExpr),
|
|
497
531
|
operationType: methodName,
|
|
498
|
-
|
|
532
|
+
serviceType: 'sns',
|
|
499
533
|
target: args.length > 0 ? extractArgValue(args[0], ...SNS_ARG_KEYS) : 'unknown',
|
|
500
534
|
filePath,
|
|
501
535
|
};
|
|
@@ -504,7 +538,7 @@ function detectAWSServiceOperations(callExpr, filePath) {
|
|
|
504
538
|
return {
|
|
505
539
|
functionName: getEnclosingFunctionName(callExpr),
|
|
506
540
|
operationType: methodName,
|
|
507
|
-
|
|
541
|
+
serviceType: 'ssm',
|
|
508
542
|
target: args.length > 0 ? extractArgValue(args[0], ...SSM_ARG_KEYS) : 'unknown',
|
|
509
543
|
filePath,
|
|
510
544
|
};
|
|
@@ -513,7 +547,7 @@ function detectAWSServiceOperations(callExpr, filePath) {
|
|
|
513
547
|
return {
|
|
514
548
|
functionName: getEnclosingFunctionName(callExpr),
|
|
515
549
|
operationType: methodName,
|
|
516
|
-
|
|
550
|
+
serviceType: 'secretsmanager',
|
|
517
551
|
target: args.length > 0 ? extractArgValue(args[0], ...SECRETS_ARG_KEYS) : 'unknown',
|
|
518
552
|
filePath,
|
|
519
553
|
};
|
|
@@ -522,7 +556,7 @@ function detectAWSServiceOperations(callExpr, filePath) {
|
|
|
522
556
|
return {
|
|
523
557
|
functionName: getEnclosingFunctionName(callExpr),
|
|
524
558
|
operationType: methodName,
|
|
525
|
-
|
|
559
|
+
serviceType: 'lambda',
|
|
526
560
|
target: args.length > 0 ? extractArgValue(args[0], ...LAMBDA_ARG_KEYS) : 'unknown',
|
|
527
561
|
filePath,
|
|
528
562
|
};
|
|
@@ -586,6 +620,11 @@ async function scanRepository(repoPath) {
|
|
|
586
620
|
operations.push(mongoOp);
|
|
587
621
|
continue;
|
|
588
622
|
}
|
|
623
|
+
const kafkaOp = detectKafkaOperations(callExpr, filePath);
|
|
624
|
+
if (kafkaOp) {
|
|
625
|
+
operations.push(kafkaOp);
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
589
628
|
const awsOp = detectAWSServiceOperations(callExpr, filePath);
|
|
590
629
|
if (awsOp) {
|
|
591
630
|
operations.push(awsOp);
|
package/dist/graph/index.js
CHANGED
|
@@ -140,7 +140,7 @@ function buildGraph(operations, dynamoMeta, postgresMeta, mysqlMeta = [], mongoM
|
|
|
140
140
|
instanceClass: db.instanceClass,
|
|
141
141
|
publiclyAccessible: db.publiclyAccessible,
|
|
142
142
|
storageEncrypted: db.storageEncrypted,
|
|
143
|
-
backupRetentionDays: db.
|
|
143
|
+
backupRetentionDays: db.backupRetentionDays,
|
|
144
144
|
deletionProtection: db.deletionProtection,
|
|
145
145
|
multiAZ: db.multiAZ,
|
|
146
146
|
});
|
|
@@ -153,31 +153,38 @@ function buildGraph(operations, dynamoMeta, postgresMeta, mysqlMeta = [], mongoM
|
|
|
153
153
|
nodeIds.add(funcNodeId);
|
|
154
154
|
}
|
|
155
155
|
// AWS service operations create edges to service nodes
|
|
156
|
-
if (op.
|
|
156
|
+
if (op.serviceType === 'sqs') {
|
|
157
157
|
const queueId = `queue:aws:${op.target}`;
|
|
158
158
|
addNode({ id: queueId, type: 'queue', name: op.target, provider: 'aws', hasDLQ: false, encrypted: false });
|
|
159
159
|
edges.push({ from: funcNodeId, to: queueId, type: 'publishes_to' });
|
|
160
160
|
continue;
|
|
161
161
|
}
|
|
162
|
-
if (op.
|
|
162
|
+
if (op.serviceType === 'sns') {
|
|
163
163
|
const topicId = `topic:aws:${op.target}`;
|
|
164
164
|
addNode({ id: topicId, type: 'topic', name: op.target, provider: 'aws', encrypted: false });
|
|
165
165
|
edges.push({ from: funcNodeId, to: topicId, type: 'publishes_to' });
|
|
166
166
|
continue;
|
|
167
167
|
}
|
|
168
|
-
if (op.
|
|
168
|
+
if (op.serviceType === 'kafka') {
|
|
169
|
+
const topicId = `topic:kafka:${op.target}`;
|
|
170
|
+
addNode({ id: topicId, type: 'topic', name: op.target, provider: 'kafka', encrypted: false });
|
|
171
|
+
const edgeType = op.operationType === 'subscribe' ? 'subscribes_to' : 'publishes_to';
|
|
172
|
+
edges.push({ from: funcNodeId, to: topicId, type: edgeType });
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (op.serviceType === 'ssm') {
|
|
169
176
|
const paramId = `parameter:aws:${op.target}`;
|
|
170
177
|
addNode({ id: paramId, type: 'parameter', name: op.target, provider: 'aws', paramType: 'String', tier: 'Standard' });
|
|
171
178
|
edges.push({ from: funcNodeId, to: paramId, type: 'reads_parameter' });
|
|
172
179
|
continue;
|
|
173
180
|
}
|
|
174
|
-
if (op.
|
|
181
|
+
if (op.serviceType === 'secretsmanager') {
|
|
175
182
|
const secretId = `secret:aws:${op.target}`;
|
|
176
183
|
addNode({ id: secretId, type: 'secret', name: op.target, provider: 'aws', rotationEnabled: false });
|
|
177
184
|
edges.push({ from: funcNodeId, to: secretId, type: 'reads_secret' });
|
|
178
185
|
continue;
|
|
179
186
|
}
|
|
180
|
-
if (op.
|
|
187
|
+
if (op.serviceType === 'lambda') {
|
|
181
188
|
const lambdaId = `lambda:aws:${op.target}`;
|
|
182
189
|
addNode({ id: lambdaId, type: 'lambda', name: op.target });
|
|
183
190
|
edges.push({ from: funcNodeId, to: lambdaId, type: 'triggers' });
|
|
@@ -185,16 +192,16 @@ function buildGraph(operations, dynamoMeta, postgresMeta, mysqlMeta = [], mongoM
|
|
|
185
192
|
}
|
|
186
193
|
// Database operations
|
|
187
194
|
let tableNodeId;
|
|
188
|
-
if (op.
|
|
195
|
+
if (op.serviceType === 'dynamodb') {
|
|
189
196
|
tableNodeId = `table:dynamo:${op.target}`;
|
|
190
197
|
addNode({ id: tableNodeId, type: 'table', name: op.target, databaseType: 'dynamodb' });
|
|
191
198
|
}
|
|
192
|
-
else if (op.
|
|
199
|
+
else if (op.serviceType === 'mysql') {
|
|
193
200
|
const q = op.target.includes('.') ? op.target : `default.${op.target}`;
|
|
194
201
|
tableNodeId = `table:mysql:${q}`;
|
|
195
202
|
addNode({ id: tableNodeId, type: 'table', name: q, databaseType: 'mysql' });
|
|
196
203
|
}
|
|
197
|
-
else if (op.
|
|
204
|
+
else if (op.serviceType === 'mongodb') {
|
|
198
205
|
const q = op.target.includes('.') ? op.target : `default.${op.target}`;
|
|
199
206
|
tableNodeId = `table:mongodb:${q}`;
|
|
200
207
|
addNode({ id: tableNodeId, type: 'table', name: q, databaseType: 'mongodb' });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "infrawise",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "CLI-first infrastructure intelligence platform — analyzes DynamoDB, PostgreSQL, MySQL, MongoDB, SQS, SNS, SSM, Secrets Manager, Lambda, CloudWatch Logs and exposes findings as an MCP server for Claude Code",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"infrastructure",
|