fg-tracker-mcp 0.4.0 → 0.6.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.
@@ -0,0 +1,557 @@
1
+ /**
2
+ * Descoberta local de recursos AWS com as credenciais do usuário (CONTRATO.md §27.3, §27.9).
3
+ * Somente chamadas de LEITURA: sts:GetCallerIdentity, resource-explorer-2:GetIndex/Search,
4
+ * resource-explorer-2:ListIndexes, tag:GetResources, cloudformation:ListStacks/ListStackResources/DescribeStacks.
5
+ */
6
+ import { CloudFormationClient, DescribeStacksCommand, ListStackResourcesCommand, ListStacksCommand } from '@aws-sdk/client-cloudformation';
7
+ import { GetIndexCommand, ListIndexesCommand, ResourceExplorer2Client, SearchCommand } from '@aws-sdk/client-resource-explorer-2';
8
+ import { GetResourcesCommand, ResourceGroupsTaggingAPIClient } from '@aws-sdk/client-resource-groups-tagging-api';
9
+ import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';
10
+ import { fromIni, fromNodeProviderChain } from '@aws-sdk/credential-providers';
11
+ import { readFile } from 'node:fs/promises';
12
+ import { homedir } from 'node:os';
13
+ import { join } from 'node:path';
14
+ const EXPLORER_CAP = 2000;
15
+ const TAGGING_CAP = 10_000;
16
+ const STACK_RESOURCES_CAP = 5000;
17
+ function awsCredentials(profile) {
18
+ return profile ? fromIni({ profile }) : fromNodeProviderChain();
19
+ }
20
+ /** Mensagem amigável para erros do AWS SDK (credenciais ausentes/expiradas, acesso negado). */
21
+ export function describeAwsError(err) {
22
+ const e = err;
23
+ const name = e?.name ?? e?.Code ?? 'Error';
24
+ const msg = e?.message ?? String(err);
25
+ if (/CredentialsProviderError|Could not load credentials|ExpiredToken|InvalidClientTokenId|UnrecognizedClient|SSO.*(expired|session)/i.test(`${name} ${msg}`)) {
26
+ return `Credenciais AWS locais indisponíveis ou expiradas (${name}: ${msg}). Rode \`aws sso login --profile <perfil>\` ou \`aws configure\`, ou passe \`profile\`.`;
27
+ }
28
+ if (/AccessDenied|UnauthorizedOperation|not authorized/i.test(`${name} ${msg}`)) {
29
+ return `Acesso negado (${name}): ${msg}`;
30
+ }
31
+ return `${name}: ${msg}`;
32
+ }
33
+ export function parseArn(arn) {
34
+ const parts = arn.split(':');
35
+ if (parts.length < 6 || parts[0] !== 'arn')
36
+ return null;
37
+ const [, partition = '', service = '', region = '', account = ''] = parts;
38
+ const resource = parts.slice(5).join(':');
39
+ let resourceType = '';
40
+ let resourceId = resource;
41
+ const slash = resource.indexOf('/');
42
+ const colon = resource.indexOf(':');
43
+ if (service === 'apigateway') {
44
+ const m = /^\/(restapis|apis|domainnames|usageplans|apikeys)\/([^/]+)/.exec(resource);
45
+ if (m) {
46
+ resourceType = m[1] ?? '';
47
+ resourceId = m[2] ?? resource;
48
+ }
49
+ }
50
+ else if (slash >= 0 && (colon < 0 || slash < colon)) {
51
+ resourceType = resource.slice(0, slash);
52
+ resourceId = resource.slice(slash + 1);
53
+ }
54
+ else if (colon >= 0) {
55
+ resourceType = resource.slice(0, colon);
56
+ resourceId = resource.slice(colon + 1);
57
+ }
58
+ return { partition, service, region, account, resource, resourceType, resourceId };
59
+ }
60
+ const TYPE_MAP = {
61
+ 'lambda:function': 'AWS::Lambda::Function',
62
+ 'lambda:layer': 'AWS::Lambda::LayerVersion',
63
+ 'lambda:event-source-mapping': 'AWS::Lambda::EventSourceMapping',
64
+ 'dynamodb:table': 'AWS::DynamoDB::Table',
65
+ 'ecs:cluster': 'AWS::ECS::Cluster',
66
+ 'ecs:service': 'AWS::ECS::Service',
67
+ 'ecs:task-definition': 'AWS::ECS::TaskDefinition',
68
+ 'ec2:instance': 'AWS::EC2::Instance',
69
+ 'ec2:vpc': 'AWS::EC2::VPC',
70
+ 'ec2:subnet': 'AWS::EC2::Subnet',
71
+ 'ec2:security-group': 'AWS::EC2::SecurityGroup',
72
+ 'ec2:natgateway': 'AWS::EC2::NatGateway',
73
+ 'ec2:internet-gateway': 'AWS::EC2::InternetGateway',
74
+ 'ec2:route-table': 'AWS::EC2::RouteTable',
75
+ 'ec2:volume': 'AWS::EC2::Volume',
76
+ 'ec2:elastic-ip': 'AWS::EC2::EIP',
77
+ 'ec2:launch-template': 'AWS::EC2::LaunchTemplate',
78
+ 'ec2:vpc-endpoint': 'AWS::EC2::VPCEndpoint',
79
+ 'rds:db': 'AWS::RDS::DBInstance',
80
+ 'rds:cluster': 'AWS::RDS::DBCluster',
81
+ 'rds:subgrp': 'AWS::RDS::DBSubnetGroup',
82
+ 'rds:pg': 'AWS::RDS::DBParameterGroup',
83
+ 'rds:cluster-pg': 'AWS::RDS::DBClusterParameterGroup',
84
+ 'apigateway:restapis': 'AWS::ApiGateway::RestApi',
85
+ 'apigateway:apis': 'AWS::ApiGatewayV2::Api',
86
+ 'apigateway:domainnames': 'AWS::ApiGateway::DomainName',
87
+ 'elasticloadbalancing:loadbalancer': 'AWS::ElasticLoadBalancingV2::LoadBalancer',
88
+ 'elasticloadbalancing:targetgroup': 'AWS::ElasticLoadBalancingV2::TargetGroup',
89
+ 'elasticloadbalancing:listener': 'AWS::ElasticLoadBalancingV2::Listener',
90
+ 'elasticloadbalancing:listener-rule': 'AWS::ElasticLoadBalancingV2::ListenerRule',
91
+ 'cloudfront:distribution': 'AWS::CloudFront::Distribution',
92
+ 'events:rule': 'AWS::Events::Rule',
93
+ 'events:event-bus': 'AWS::Events::EventBus',
94
+ 'scheduler:schedule': 'AWS::Scheduler::Schedule',
95
+ 'states:stateMachine': 'AWS::StepFunctions::StateMachine',
96
+ 'ecr:repository': 'AWS::ECR::Repository',
97
+ 'kinesis:stream': 'AWS::Kinesis::Stream',
98
+ 'firehose:deliverystream': 'AWS::KinesisFirehose::DeliveryStream',
99
+ 'codebuild:project': 'AWS::CodeBuild::Project',
100
+ 'cloudformation:stack': 'AWS::CloudFormation::Stack',
101
+ 'logs:log-group': 'AWS::Logs::LogGroup',
102
+ 'iam:role': 'AWS::IAM::Role',
103
+ 'iam:policy': 'AWS::IAM::ManagedPolicy',
104
+ 'iam:user': 'AWS::IAM::User',
105
+ 'secretsmanager:secret': 'AWS::SecretsManager::Secret',
106
+ 'ssm:parameter': 'AWS::SSM::Parameter',
107
+ 'kms:key': 'AWS::KMS::Key',
108
+ 'autoscaling:autoScalingGroup': 'AWS::AutoScaling::AutoScalingGroup',
109
+ 'elasticache:cluster': 'AWS::ElastiCache::CacheCluster',
110
+ 'elasticache:replicationgroup': 'AWS::ElastiCache::ReplicationGroup',
111
+ 'cognito-idp:userpool': 'AWS::Cognito::UserPool',
112
+ 'acm:certificate': 'AWS::CertificateManager::Certificate',
113
+ 'route53:hostedzone': 'AWS::Route53::HostedZone',
114
+ 'cloudwatch:alarm': 'AWS::CloudWatch::Alarm',
115
+ 'appsync:apis': 'AWS::AppSync::GraphQLApi',
116
+ 'wafv2:regional': 'AWS::WAFv2::WebACL',
117
+ 'wafv2:global': 'AWS::WAFv2::WebACL',
118
+ 'efs:file-system': 'AWS::EFS::FileSystem',
119
+ };
120
+ /** ARN → tipo CloudFormation (melhor esforço; null quando desconhecido). */
121
+ export function arnToResourceType(arn) {
122
+ const p = parseArn(arn);
123
+ if (!p)
124
+ return null;
125
+ if (p.service === 's3' && !p.resourceType && !p.resource.includes('/'))
126
+ return 'AWS::S3::Bucket';
127
+ if (p.service === 'sqs')
128
+ return 'AWS::SQS::Queue';
129
+ if (p.service === 'sns')
130
+ return p.resource.includes(':') ? 'AWS::SNS::Subscription' : 'AWS::SNS::Topic';
131
+ if (p.service === 'codepipeline')
132
+ return 'AWS::CodePipeline::Pipeline';
133
+ if (p.service === 'states' && p.resourceType === 'stateMachine')
134
+ return 'AWS::StepFunctions::StateMachine';
135
+ if (p.service === 'autoscaling' && p.resource.startsWith('autoScalingGroup'))
136
+ return 'AWS::AutoScaling::AutoScalingGroup';
137
+ return TYPE_MAP[`${p.service}:${p.resourceType}`] ?? null;
138
+ }
139
+ /** Nome legível a partir do ARN. */
140
+ export function nameFromArn(arn) {
141
+ const p = parseArn(arn);
142
+ if (!p)
143
+ return arn;
144
+ if (p.service === 'cloudformation' && p.resourceType === 'stack')
145
+ return p.resourceId.split('/')[0] ?? p.resourceId;
146
+ if (p.service === 'elasticloadbalancing') {
147
+ const segs = p.resourceId.split('/');
148
+ return (p.resourceType === 'loadbalancer' ? segs[1] : segs[0]) ?? p.resourceId;
149
+ }
150
+ if (p.service === 'autoscaling')
151
+ return /autoScalingGroupName\/(.+)$/.exec(p.resource)?.[1] ?? p.resource;
152
+ if (p.service === 'lambda' && p.resourceType === 'function')
153
+ return p.resourceId.split(':')[0] ?? p.resourceId;
154
+ if (p.service === 'logs' && p.resourceType === 'log-group')
155
+ return p.resourceId.replace(/:\*$/, '');
156
+ if (p.service === 'states')
157
+ return p.resourceId.split(':')[0] ?? p.resourceId;
158
+ const segs = p.resourceId.split(/[/:]/).filter(Boolean);
159
+ return segs[segs.length - 1] ?? p.resourceId;
160
+ }
161
+ /** Serviço amigável (`lambda`, `ecs.service`…) só para o resumo. */
162
+ export function serviceLabel(resourceType, arn) {
163
+ if (resourceType) {
164
+ const [, svc = 'generic', kind = ''] = resourceType.split('::');
165
+ return `${svc.toLowerCase()}${kind ? '.' + kind.toLowerCase() : ''}`;
166
+ }
167
+ return parseArn(arn)?.service ?? 'generic';
168
+ }
169
+ /* ---------------- descoberta ---------------- */
170
+ function tagsFromExplorer(properties) {
171
+ const tagProp = properties?.find((p) => p.Name === 'tags' || p.Name === 'Tags');
172
+ if (!tagProp || !Array.isArray(tagProp.Data))
173
+ return undefined;
174
+ const out = {};
175
+ for (const t of tagProp.Data)
176
+ if (t?.Key)
177
+ out[t.Key] = t.Value ?? '';
178
+ return Object.keys(out).length ? out : undefined;
179
+ }
180
+ async function explorerSearch(region, credentials, budget) {
181
+ const rex = new ResourceExplorer2Client({ region, credentials });
182
+ try {
183
+ const idx = await rex.send(new GetIndexCommand({}));
184
+ if (idx.State !== 'ACTIVE')
185
+ return null;
186
+ }
187
+ catch {
188
+ return null; // sem índice nesta região
189
+ }
190
+ const resources = [];
191
+ let nextToken;
192
+ let complete = true;
193
+ try {
194
+ do {
195
+ const res = await rex.send(new SearchCommand({ QueryString: '*', MaxResults: 1000, NextToken: nextToken }));
196
+ for (const r of res.Resources ?? []) {
197
+ if (!r.Arn)
198
+ continue;
199
+ resources.push({
200
+ arn: r.Arn,
201
+ resourceType: r.CfnResourceType || arnToResourceType(r.Arn),
202
+ region: r.Region || region,
203
+ name: nameFromArn(r.Arn),
204
+ tags: tagsFromExplorer(r.Properties),
205
+ });
206
+ }
207
+ if (res.Count && res.Count.Complete === false)
208
+ complete = false;
209
+ nextToken = res.NextToken;
210
+ } while (nextToken && resources.length < budget);
211
+ if (nextToken)
212
+ complete = false;
213
+ }
214
+ catch (err) {
215
+ const name = err.name ?? '';
216
+ // Sem view padrão: não dá para buscar; cai para o Tagging API.
217
+ if (/UnauthorizedException|ResourceNotFound|ValidationException|AccessDenied/i.test(name))
218
+ return null;
219
+ throw err;
220
+ }
221
+ return { resources: resources.slice(0, budget), complete };
222
+ }
223
+ async function taggingResources(region, credentials) {
224
+ const tagging = new ResourceGroupsTaggingAPIClient({ region, credentials });
225
+ const out = [];
226
+ let token;
227
+ do {
228
+ const res = await tagging.send(new GetResourcesCommand({ PaginationToken: token, ResourcesPerPage: 100 }));
229
+ for (const m of res.ResourceTagMappingList ?? []) {
230
+ if (!m.ResourceARN)
231
+ continue;
232
+ const tags = {};
233
+ for (const t of m.Tags ?? [])
234
+ if (t.Key)
235
+ tags[t.Key] = t.Value ?? '';
236
+ out.push({ arn: m.ResourceARN, resourceType: arnToResourceType(m.ResourceARN), region: parseArn(m.ResourceARN)?.region || region, name: nameFromArn(m.ResourceARN), tags: Object.keys(tags).length ? tags : undefined });
237
+ }
238
+ token = res.PaginationToken || undefined;
239
+ } while (token && out.length < TAGGING_CAP);
240
+ return out;
241
+ }
242
+ const ACTIVE_STACK_STATUSES = [
243
+ 'CREATE_IN_PROGRESS', 'CREATE_COMPLETE', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_FAILED', 'ROLLBACK_COMPLETE', 'DELETE_FAILED',
244
+ 'UPDATE_IN_PROGRESS', 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_COMPLETE', 'UPDATE_FAILED', 'UPDATE_ROLLBACK_IN_PROGRESS',
245
+ 'UPDATE_ROLLBACK_FAILED', 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_ROLLBACK_COMPLETE', 'REVIEW_IN_PROGRESS',
246
+ 'IMPORT_IN_PROGRESS', 'IMPORT_COMPLETE', 'IMPORT_ROLLBACK_IN_PROGRESS', 'IMPORT_ROLLBACK_FAILED', 'IMPORT_ROLLBACK_COMPLETE',
247
+ ];
248
+ /** Constrói o ARN a partir do physical id para os tipos em que isso é determinístico. */
249
+ function arnFromPhysicalId(type, physicalId, region, account, partition = 'aws') {
250
+ if (physicalId.startsWith('arn:'))
251
+ return physicalId;
252
+ switch (type) {
253
+ case 'AWS::Lambda::Function': return `arn:${partition}:lambda:${region}:${account}:function:${physicalId}`;
254
+ case 'AWS::SQS::Queue': {
255
+ const name = physicalId.split('/').pop();
256
+ return name ? `arn:${partition}:sqs:${region}:${account}:${name}` : null;
257
+ }
258
+ case 'AWS::DynamoDB::Table': return `arn:${partition}:dynamodb:${region}:${account}:table/${physicalId}`;
259
+ case 'AWS::S3::Bucket': return `arn:${partition}:s3:::${physicalId}`;
260
+ case 'AWS::ECS::Cluster': return `arn:${partition}:ecs:${region}:${account}:cluster/${physicalId}`;
261
+ case 'AWS::Logs::LogGroup': return `arn:${partition}:logs:${region}:${account}:log-group:${physicalId}`;
262
+ case 'AWS::Kinesis::Stream': return `arn:${partition}:kinesis:${region}:${account}:stream/${physicalId}`;
263
+ case 'AWS::ECR::Repository': return `arn:${partition}:ecr:${region}:${account}:repository/${physicalId}`;
264
+ case 'AWS::RDS::DBInstance': return `arn:${partition}:rds:${region}:${account}:db:${physicalId}`;
265
+ case 'AWS::RDS::DBCluster': return `arn:${partition}:rds:${region}:${account}:cluster:${physicalId}`;
266
+ case 'AWS::CodePipeline::Pipeline': return `arn:${partition}:codepipeline:${region}:${account}:${physicalId}`;
267
+ case 'AWS::CodeBuild::Project': return `arn:${partition}:codebuild:${region}:${account}:project/${physicalId}`;
268
+ case 'AWS::Events::Rule': return `arn:${partition}:events:${region}:${account}:rule/${physicalId}`;
269
+ case 'AWS::EC2::VPC': return `arn:${partition}:ec2:${region}:${account}:vpc/${physicalId}`;
270
+ case 'AWS::EC2::Subnet': return `arn:${partition}:ec2:${region}:${account}:subnet/${physicalId}`;
271
+ case 'AWS::EC2::SecurityGroup': return `arn:${partition}:ec2:${region}:${account}:security-group/${physicalId}`;
272
+ case 'AWS::EC2::Instance': return `arn:${partition}:ec2:${region}:${account}:instance/${physicalId}`;
273
+ case 'AWS::EC2::NatGateway': return `arn:${partition}:ec2:${region}:${account}:natgateway/${physicalId}`;
274
+ case 'AWS::CloudFront::Distribution': return `arn:${partition}:cloudfront::${account}:distribution/${physicalId}`;
275
+ case 'AWS::ApiGateway::RestApi': return `arn:${partition}:apigateway:${region}::/restapis/${physicalId}`;
276
+ case 'AWS::ApiGatewayV2::Api': return `arn:${partition}:apigateway:${region}::/apis/${physicalId}`;
277
+ case 'AWS::IAM::Role': return `arn:${partition}:iam::${account}:role/${physicalId}`;
278
+ default: return null;
279
+ }
280
+ }
281
+ export async function discoverAws(options) {
282
+ const credentials = awsCredentials(options.profile);
283
+ const regions = [...new Set(options.regions)];
284
+ const sts = new STSClient({ region: regions[0] ?? 'us-east-1', credentials });
285
+ const identity = await sts.send(new GetCallerIdentityCommand({}));
286
+ const accountId = identity.Account ?? '';
287
+ const partition = parseArn(identity.Arn ?? '')?.partition || 'aws';
288
+ const byArn = new Map();
289
+ const sources = {};
290
+ const stacks = [];
291
+ const warnings = [];
292
+ const add = (r) => {
293
+ const prev = byArn.get(r.arn);
294
+ if (!prev)
295
+ byArn.set(r.arn, r);
296
+ else
297
+ byArn.set(r.arn, { ...prev, ...Object.fromEntries(Object.entries(r).filter(([, v]) => v !== undefined && v !== null)), tags: { ...(prev.tags ?? {}), ...(r.tags ?? {}) } });
298
+ };
299
+ const regionSet = new Set(regions);
300
+ for (const region of regions) {
301
+ options.onProgress?.(`região ${region}`);
302
+ try {
303
+ const budget = Math.max(0, EXPLORER_CAP - byArn.size);
304
+ const explorer = budget > 0 ? await explorerSearch(region, credentials, budget) : null;
305
+ if (explorer) {
306
+ // Índice agregador devolve outras regiões: mantém só as pedidas + globais.
307
+ for (const r of explorer.resources)
308
+ if (!r.region || r.region === 'global' || regionSet.has(r.region))
309
+ add({ ...r, region: r.region && r.region !== 'global' ? r.region : region });
310
+ sources[region] = 'resource-explorer';
311
+ if (!explorer.complete) {
312
+ for (const r of await taggingResources(region, credentials))
313
+ add(r);
314
+ sources[region] = 'resource-explorer+tagging-api';
315
+ warnings.push(`${region}: Resource Explorer devolveu resultado parcial (limite de ${EXPLORER_CAP}); complementado com o Tagging API.`);
316
+ }
317
+ }
318
+ else {
319
+ for (const r of await taggingResources(region, credentials))
320
+ add({ ...r, region: r.region || region });
321
+ sources[region] = 'tagging-api';
322
+ }
323
+ }
324
+ catch (err) {
325
+ sources[region] = 'error';
326
+ warnings.push(`${region}: inventário falhou — ${describeAwsError(err)}`);
327
+ }
328
+ // CloudFormation: stacks e logical ids.
329
+ try {
330
+ const cfn = new CloudFormationClient({ region, credentials });
331
+ const index = new Map(); // `${type}|${name}` → arn
332
+ for (const r of byArn.values())
333
+ if (r.resourceType && r.name)
334
+ index.set(`${r.resourceType}|${r.name}`, r.arn);
335
+ let token;
336
+ const summaries = [];
337
+ do {
338
+ const res = await cfn.send(new ListStacksCommand({ NextToken: token, StackStatusFilter: ACTIVE_STACK_STATUSES }));
339
+ summaries.push(...(res.StackSummaries ?? []));
340
+ token = res.NextToken;
341
+ } while (token);
342
+ let totalStackResources = 0;
343
+ for (const s of summaries) {
344
+ if (!s.StackName || !s.StackId)
345
+ continue;
346
+ add({ arn: s.StackId, resourceType: 'AWS::CloudFormation::Stack', region, name: s.StackName });
347
+ let rtoken;
348
+ let count = 0;
349
+ let mapped = 0;
350
+ do {
351
+ const res = await cfn.send(new ListStackResourcesCommand({ StackName: s.StackName, NextToken: rtoken }));
352
+ for (const sr of res.StackResourceSummaries ?? []) {
353
+ count++;
354
+ totalStackResources++;
355
+ const type = sr.ResourceType ?? '';
356
+ const physical = sr.PhysicalResourceId ?? '';
357
+ if (!physical || type.startsWith('Custom::') || type === 'AWS::CDK::Metadata')
358
+ continue;
359
+ let arn = physical.startsWith('arn:') ? physical : undefined;
360
+ if (!arn) {
361
+ const name = type === 'AWS::SQS::Queue' ? physical.split('/').pop() ?? physical : physical;
362
+ arn = index.get(`${type}|${name}`);
363
+ }
364
+ if (!arn)
365
+ arn = arnFromPhysicalId(type, physical, region, accountId, partition) ?? undefined;
366
+ if (!arn)
367
+ continue;
368
+ mapped++;
369
+ add({ arn, resourceType: type || arnToResourceType(arn), region, name: nameFromArn(arn), stackName: s.StackName, stackLogicalId: sr.LogicalResourceId });
370
+ }
371
+ rtoken = res.NextToken;
372
+ } while (rtoken && totalStackResources < STACK_RESOURCES_CAP);
373
+ stacks.push({ name: s.StackName, region, status: s.StackStatus ?? '', resources: count, mapped, stackId: s.StackId });
374
+ if (totalStackResources >= STACK_RESOURCES_CAP) {
375
+ warnings.push(`${region}: limite de ${STACK_RESOURCES_CAP} recursos de stacks atingido; stacks restantes sem logical ids.`);
376
+ break;
377
+ }
378
+ }
379
+ }
380
+ catch (err) {
381
+ warnings.push(`${region}: CloudFormation falhou — ${describeAwsError(err)}`);
382
+ }
383
+ }
384
+ return { accountId, callerArn: identity.Arn ?? '', regions, resources: [...byArn.values()], sources, stacks, warnings };
385
+ }
386
+ /** Lê os outputs de um stack (DescribeStacks, somente leitura). */
387
+ export async function readStackOutputs(stackName, region, profile) {
388
+ const cfn = new CloudFormationClient({ region, credentials: awsCredentials(profile) });
389
+ const res = await cfn.send(new DescribeStacksCommand({ StackName: stackName }));
390
+ const out = {};
391
+ for (const o of res.Stacks?.[0]?.Outputs ?? [])
392
+ if (o.OutputKey && o.OutputValue)
393
+ out[o.OutputKey] = o.OutputValue;
394
+ return out;
395
+ }
396
+ export const CANDIDATE_REGIONS = ['us-east-1', 'us-east-2', 'us-west-1', 'us-west-2', 'sa-east-1', 'eu-west-1', 'eu-central-1', 'ap-southeast-1', 'ap-northeast-1'];
397
+ const PROBE_TIMEOUT_MS = 6000;
398
+ const PROFILE_CAP = 10;
399
+ function iniSections(content) {
400
+ const out = [];
401
+ for (const line of content.split(/\r?\n/)) {
402
+ const m = /^\s*\[([^\]]+)\]\s*$/.exec(line);
403
+ if (m?.[1])
404
+ out.push(m[1].trim());
405
+ }
406
+ return out;
407
+ }
408
+ /** Perfis de ~/.aws/config e ~/.aws/credentials (respeita AWS_CONFIG_FILE / AWS_SHARED_CREDENTIALS_FILE) + AWS_PROFILE. */
409
+ export async function listAwsProfiles(env = process.env) {
410
+ const configFile = env.AWS_CONFIG_FILE || join(homedir(), '.aws', 'config');
411
+ const credentialsFile = env.AWS_SHARED_CREDENTIALS_FILE || join(homedir(), '.aws', 'credentials');
412
+ const names = new Set();
413
+ if (env.AWS_PROFILE?.trim())
414
+ names.add(env.AWS_PROFILE.trim());
415
+ const config = await readFile(configFile, 'utf8').catch(() => '');
416
+ for (const section of iniSections(config)) {
417
+ if (section === 'default')
418
+ names.add('default');
419
+ else if (section.startsWith('profile '))
420
+ names.add(section.slice('profile '.length).trim());
421
+ // [sso-session x] e [services x] não são perfis.
422
+ }
423
+ const credentials = await readFile(credentialsFile, 'utf8').catch(() => '');
424
+ for (const section of iniSections(credentials))
425
+ names.add(section);
426
+ return [...names].filter(Boolean);
427
+ }
428
+ /** Classifica o ambiente por dicas no nome do perfil/ARN; null = perguntar ao usuário. */
429
+ export function classifyEnvironment(...hints) {
430
+ for (const hint of hints) {
431
+ if (!hint)
432
+ continue;
433
+ const tokens = hint.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
434
+ if (tokens.some((t) => /^(prod|production|prd|prod\d+|prd\d+)$/.test(t)))
435
+ return 'production';
436
+ if (tokens.some((t) => /^(stag\w*|stage|stg|hml\w*|homolog\w*|qa\d*|uat)$/.test(t)))
437
+ return 'staging';
438
+ if (tokens.some((t) => /^(dev\w*|sandbox\w*|test\w*|tst)$/.test(t)))
439
+ return 'development';
440
+ }
441
+ return null;
442
+ }
443
+ export const ENVIRONMENT_LABEL = { production: 'Produção', staging: 'Staging', development: 'Desenvolvimento' };
444
+ function withTimeout(fn, ms = PROBE_TIMEOUT_MS) {
445
+ const controller = new AbortController();
446
+ const timer = setTimeout(() => controller.abort(), ms);
447
+ return Promise.race([
448
+ fn(controller.signal),
449
+ new Promise((_, reject) => controller.signal.addEventListener('abort', () => reject(new Error(`timeout de ${ms}ms`)), { once: true })),
450
+ ]).finally(() => clearTimeout(timer));
451
+ }
452
+ /**
453
+ * Regiões em uso na conta: índices do Resource Explorer (ListIndexes) quando existem; senão sonda
454
+ * as regiões candidatas com CloudFormation ListStacks (1ª página) e Tagging GetResources (1 recurso).
455
+ */
456
+ export async function detectRegionsInUse(options) {
457
+ const credentials = awsCredentials(options.profile);
458
+ const include = [...new Set(options.includeRegions ?? [])];
459
+ const warnings = [];
460
+ let explorerRegions = [];
461
+ try {
462
+ const rex = new ResourceExplorer2Client({ region: 'us-east-1', credentials, maxAttempts: 1 });
463
+ let token;
464
+ do {
465
+ const res = await withTimeout((abortSignal) => rex.send(new ListIndexesCommand({ NextToken: token, MaxResults: 100 }), { abortSignal }));
466
+ for (const idx of res.Indexes ?? [])
467
+ if (idx.Region)
468
+ explorerRegions.push(idx.Region);
469
+ token = res.NextToken;
470
+ } while (token);
471
+ explorerRegions = [...new Set(explorerRegions)];
472
+ }
473
+ catch (err) {
474
+ warnings.push(`Resource Explorer indisponível (${describeAwsError(err)}); sondando regiões candidatas.`);
475
+ explorerRegions = [];
476
+ }
477
+ const useExplorer = explorerRegions.length > 0;
478
+ const candidates = useExplorer ? [...new Set([...explorerRegions, ...include])] : [...new Set([...CANDIDATE_REGIONS, ...include])];
479
+ const stacksPerRegion = {};
480
+ const inUse = [];
481
+ await Promise.all(candidates.map(async (region) => {
482
+ const cfn = new CloudFormationClient({ region, credentials, maxAttempts: 1 });
483
+ const tagging = new ResourceGroupsTaggingAPIClient({ region, credentials, maxAttempts: 1 });
484
+ const [stacks, tagged] = await Promise.allSettled([
485
+ withTimeout((abortSignal) => cfn.send(new ListStacksCommand({ StackStatusFilter: ACTIVE_STACK_STATUSES }), { abortSignal })),
486
+ withTimeout((abortSignal) => tagging.send(new GetResourcesCommand({ ResourcesPerPage: 1 }), { abortSignal })),
487
+ ]);
488
+ const stackCount = stacks.status === 'fulfilled' ? (stacks.value.StackSummaries ?? []).length : 0;
489
+ const hasResources = tagged.status === 'fulfilled' && (tagged.value.ResourceTagMappingList ?? []).length > 0;
490
+ stacksPerRegion[region] = stackCount;
491
+ if (stacks.status === 'rejected' && tagged.status === 'rejected')
492
+ warnings.push(`${region}: sondagem falhou — ${describeAwsError(stacks.reason)}`);
493
+ if (useExplorer || include.includes(region) || stackCount > 0 || hasResources)
494
+ inUse.push(region);
495
+ }));
496
+ const order = (r) => {
497
+ const i = candidates.indexOf(r);
498
+ return i < 0 ? 999 : i;
499
+ };
500
+ const regionsInUse = inUse.sort((a, b) => (stacksPerRegion[b] ?? 0) - (stacksPerRegion[a] ?? 0) || order(a) - order(b));
501
+ if (!regionsInUse.length)
502
+ warnings.push('Nenhuma região com stacks ou recursos marcados nas candidatas; pergunte ao usuário as regiões ou passe includeRegions.');
503
+ return { regionsInUse, stacksPerRegion, source: useExplorer ? 'resource-explorer' : 'probe', warnings };
504
+ }
505
+ /** GetCallerIdentity por perfil (até 10), deduplica por conta, classifica ambiente e detecta regiões. */
506
+ export async function detectEnvironments(options) {
507
+ const found = options.profiles?.length ? [...new Set(options.profiles)] : await listAwsProfiles();
508
+ const targets = found.slice(0, PROFILE_CAP);
509
+ const skipped = [];
510
+ for (const p of found.slice(PROFILE_CAP))
511
+ skipped.push({ profile: p, reason: `limite de ${PROFILE_CAP} perfis por chamada — passe \`profiles\`` });
512
+ // Cadeia padrão (variáveis de ambiente, SSO/IMDS) quando não há perfis ou há credenciais no ambiente.
513
+ if (!options.profiles?.length && (!targets.length || process.env.AWS_ACCESS_KEY_ID))
514
+ targets.unshift(null);
515
+ const identities = await Promise.all(targets.map(async (profile) => {
516
+ try {
517
+ const sts = new STSClient({ region: 'us-east-1', credentials: awsCredentials(profile ?? undefined), maxAttempts: 1 });
518
+ const id = await withTimeout((abortSignal) => sts.send(new GetCallerIdentityCommand({}), { abortSignal }), 10_000);
519
+ return { profile, accountId: id.Account ?? '', arn: id.Arn ?? '' };
520
+ }
521
+ catch (err) {
522
+ skipped.push({ profile, reason: describeAwsError(err) });
523
+ return null;
524
+ }
525
+ }));
526
+ const byAccount = new Map();
527
+ for (const id of identities) {
528
+ if (!id?.accountId)
529
+ continue;
530
+ const entry = byAccount.get(id.accountId);
531
+ if (entry)
532
+ entry.profiles.push(id.profile);
533
+ else
534
+ byAccount.set(id.accountId, { profiles: [id.profile], arn: id.arn });
535
+ }
536
+ const accounts = await Promise.all([...byAccount].map(async ([accountId, { profiles, arn }]) => {
537
+ // Prefere um perfil nomeado (o comando de deploy precisa de --profile).
538
+ const named = profiles.filter((p) => !!p);
539
+ const profile = named[0] ?? null;
540
+ const environment = classifyEnvironment(...named, arn);
541
+ const regions = await detectRegionsInUse({ profile: profile ?? undefined, includeRegions: options.includeRegions });
542
+ return {
543
+ profile,
544
+ otherProfiles: named.slice(1),
545
+ accountId,
546
+ arn,
547
+ environment,
548
+ regionsInUse: regions.regionsInUse,
549
+ stacksPerRegion: Object.fromEntries(Object.entries(regions.stacksPerRegion).filter(([, n]) => n > 0)),
550
+ regionSource: regions.source,
551
+ suggestedConnectionName: environment ? ENVIRONMENT_LABEL[environment] : `AWS ${accountId}`,
552
+ warnings: regions.warnings,
553
+ };
554
+ }));
555
+ return { accounts, skipped, profilesFound: found };
556
+ }
557
+ //# sourceMappingURL=aws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws.js","sourceRoot":"","sources":["../../src/infra/aws.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /** Gerador de unified diff (compatível com `git apply`) a partir de edições por linha. */
2
+ export interface LineEdit {
3
+ /** Índice 0-based da primeira linha afetada no arquivo original. */
4
+ start: number;
5
+ deleteCount: number;
6
+ insert: string[];
7
+ }
8
+ export declare function splitLines(content: string): {
9
+ lines: string[];
10
+ trailingNewline: boolean;
11
+ };
12
+ export declare function applyEdits(lines: string[], edits: LineEdit[]): string[];
13
+ /** Remove sobreposições (mantém a primeira edição de cada região). */
14
+ export declare function normalizeEdits(edits: LineEdit[]): LineEdit[];
15
+ export declare function unifiedDiff(path: string, content: string | null, rawEdits: LineEdit[], context?: number): string;