@friggframework/devtools 2.0.0--canary.474.86c5119.0 → 2.0.0--canary.474.898a56c.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.
Files changed (24) hide show
  1. package/infrastructure/domains/health/application/use-cases/__tests__/mismatch-analyzer-method-name.test.js +167 -0
  2. package/infrastructure/domains/health/application/use-cases/__tests__/repair-via-import-use-case.test.js +762 -0
  3. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.js +154 -1
  4. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.js +20 -5
  5. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.test.js +3 -3
  6. package/infrastructure/domains/health/docs/ACME-DEV-DRIFT-ANALYSIS.md +267 -0
  7. package/infrastructure/domains/health/docs/BUILD-VS-DEPLOYED-TEMPLATE-ANALYSIS.md +324 -0
  8. package/infrastructure/domains/health/docs/ORPHAN-DETECTION-ANALYSIS.md +386 -0
  9. package/infrastructure/domains/health/docs/SPEC-CLEANUP-COMMAND.md +1419 -0
  10. package/infrastructure/domains/health/docs/TDD-IMPLEMENTATION-SUMMARY.md +391 -0
  11. package/infrastructure/domains/health/docs/TEMPLATE-COMPARISON-IMPLEMENTATION.md +551 -0
  12. package/infrastructure/domains/health/domain/services/__tests__/health-score-percentage-based.test.js +380 -0
  13. package/infrastructure/domains/health/domain/services/__tests__/logical-id-mapper.test.js +645 -0
  14. package/infrastructure/domains/health/domain/services/__tests__/template-parser.test.js +496 -0
  15. package/infrastructure/domains/health/domain/services/health-score-calculator.js +174 -91
  16. package/infrastructure/domains/health/domain/services/health-score-calculator.test.js +332 -228
  17. package/infrastructure/domains/health/domain/services/logical-id-mapper.js +330 -0
  18. package/infrastructure/domains/health/domain/services/template-parser.js +245 -0
  19. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-cfn-tagged.test.js +312 -0
  20. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-multi-stack.test.js +367 -0
  21. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-relationship-analysis.test.js +432 -0
  22. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.js +108 -14
  23. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.test.js +69 -12
  24. package/package.json +6 -6
@@ -439,23 +439,53 @@ describe('AWSResourceDetector', () => {
439
439
  });
440
440
 
441
441
  describe('findOrphanedResources', () => {
442
- it('should find orphaned RDS DBCluster', async () => {
442
+ const StackIdentifier = require('../../domain/value-objects/stack-identifier');
443
+
444
+ it('should find orphaned RDS DBCluster with frigg:stack tag', async () => {
445
+ const stackIdentifier = new StackIdentifier({
446
+ stackName: 'my-app-prod',
447
+ region: 'us-east-1',
448
+ });
449
+
450
+ const stackResources = [
451
+ {
452
+ logicalId: 'MyDBCluster',
453
+ physicalId: 'managed-cluster',
454
+ resourceType: 'AWS::RDS::DBCluster',
455
+ },
456
+ ];
457
+
443
458
  mockRDSSend.mockResolvedValue({
444
459
  DBClusters: [
445
460
  {
461
+ // Managed by CloudFormation - not orphaned
462
+ DBClusterIdentifier: 'managed-cluster',
463
+ DBClusterArn: 'arn:aws:rds:us-east-1:123456789012:cluster:managed-cluster',
464
+ Engine: 'aurora-postgresql',
465
+ Status: 'available',
466
+ ClusterCreateTime: new Date('2024-01-01T00:00:00Z'),
467
+ TagList: [
468
+ { Key: 'aws:cloudformation:stack-name', Value: 'my-app-prod' },
469
+ { Key: 'frigg:stack', Value: 'my-app-prod' },
470
+ ],
471
+ },
472
+ {
473
+ // Has frigg:stack tag but no CloudFormation tag - orphaned
446
474
  DBClusterIdentifier: 'orphan-cluster',
447
475
  DBClusterArn: 'arn:aws:rds:us-east-1:123456789012:cluster:orphan-cluster',
448
476
  Engine: 'aurora-postgresql',
449
477
  Status: 'available',
450
478
  ClusterCreateTime: new Date('2024-01-01T00:00:00Z'),
451
- TagList: [],
479
+ TagList: [
480
+ { Key: 'frigg:stack', Value: 'my-app-prod' },
481
+ ],
452
482
  },
453
483
  ],
454
484
  });
455
485
 
456
486
  const orphans = await detector.findOrphanedResources({
457
- region: 'us-east-1',
458
- resourceTypes: ['AWS::RDS::DBCluster'],
487
+ stackIdentifier,
488
+ stackResources,
459
489
  });
460
490
 
461
491
  expect(orphans).toHaveLength(1);
@@ -464,22 +494,49 @@ describe('AWSResourceDetector', () => {
464
494
  expect(orphans[0].reason).toContain('not managed by CloudFormation');
465
495
  });
466
496
 
467
- it('should exclude specified physical IDs', async () => {
497
+ it('should not return resources managed by CloudFormation', async () => {
498
+ const stackIdentifier = new StackIdentifier({
499
+ stackName: 'my-app-prod',
500
+ region: 'us-east-1',
501
+ });
502
+
503
+ const stackResources = [
504
+ {
505
+ logicalId: 'MyVPC',
506
+ physicalId: 'vpc-123',
507
+ resourceType: 'AWS::EC2::VPC',
508
+ },
509
+ ];
510
+
468
511
  mockEC2Send.mockResolvedValue({
469
512
  Vpcs: [
470
- { VpcId: 'vpc-123', CidrBlock: '10.0.0.0/16', State: 'available', Tags: [] },
471
- { VpcId: 'vpc-456', CidrBlock: '10.1.0.0/16', State: 'available', Tags: [] },
513
+ {
514
+ VpcId: 'vpc-123',
515
+ CidrBlock: '10.0.0.0/16',
516
+ State: 'available',
517
+ Tags: [
518
+ { Key: 'aws:cloudformation:stack-name', Value: 'my-app-prod' },
519
+ { Key: 'frigg:stack', Value: 'my-app-prod' },
520
+ ],
521
+ },
522
+ {
523
+ VpcId: 'vpc-456',
524
+ CidrBlock: '10.1.0.0/16',
525
+ State: 'available',
526
+ Tags: [
527
+ { Key: 'aws:cloudformation:stack-name', Value: 'other-stack' },
528
+ ],
529
+ },
472
530
  ],
473
531
  });
474
532
 
475
533
  const orphans = await detector.findOrphanedResources({
476
- region: 'us-east-1',
477
- resourceTypes: ['AWS::EC2::VPC'],
478
- excludePhysicalIds: ['vpc-123'],
534
+ stackIdentifier,
535
+ stackResources,
479
536
  });
480
537
 
481
- expect(orphans).toHaveLength(1);
482
- expect(orphans[0].physicalId).toBe('vpc-456');
538
+ // Should not find any orphans - both VPCs are CloudFormation-managed
539
+ expect(orphans).toEqual([]);
483
540
  });
484
541
  });
485
542
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/devtools",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.474.86c5119.0",
4
+ "version": "2.0.0--canary.474.898a56c.0",
5
5
  "dependencies": {
6
6
  "@aws-sdk/client-ec2": "^3.835.0",
7
7
  "@aws-sdk/client-kms": "^3.835.0",
@@ -11,8 +11,8 @@
11
11
  "@babel/eslint-parser": "^7.18.9",
12
12
  "@babel/parser": "^7.25.3",
13
13
  "@babel/traverse": "^7.25.3",
14
- "@friggframework/schemas": "2.0.0--canary.474.86c5119.0",
15
- "@friggframework/test": "2.0.0--canary.474.86c5119.0",
14
+ "@friggframework/schemas": "2.0.0--canary.474.898a56c.0",
15
+ "@friggframework/test": "2.0.0--canary.474.898a56c.0",
16
16
  "@hapi/boom": "^10.0.1",
17
17
  "@inquirer/prompts": "^5.3.8",
18
18
  "axios": "^1.7.2",
@@ -34,8 +34,8 @@
34
34
  "serverless-http": "^2.7.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@friggframework/eslint-config": "2.0.0--canary.474.86c5119.0",
38
- "@friggframework/prettier-config": "2.0.0--canary.474.86c5119.0",
37
+ "@friggframework/eslint-config": "2.0.0--canary.474.898a56c.0",
38
+ "@friggframework/prettier-config": "2.0.0--canary.474.898a56c.0",
39
39
  "aws-sdk-client-mock": "^4.1.0",
40
40
  "aws-sdk-client-mock-jest": "^4.1.0",
41
41
  "jest": "^30.1.3",
@@ -67,5 +67,5 @@
67
67
  "publishConfig": {
68
68
  "access": "public"
69
69
  },
70
- "gitHead": "86c5119f607135820a24b687fa53501345e0d6ef"
70
+ "gitHead": "898a56c40d5fe1b6f0603f87e4caf2a6833f046a"
71
71
  }