@friggframework/devtools 2.0.0-next.62 → 2.0.0-next.63

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 (165) hide show
  1. package/infrastructure/ARCHITECTURE.md +487 -0
  2. package/infrastructure/CLAUDE.md +481 -0
  3. package/infrastructure/HEALTH.md +468 -0
  4. package/infrastructure/README.md +522 -0
  5. package/infrastructure/__tests__/fixtures/mock-aws-resources.js +391 -0
  6. package/infrastructure/__tests__/helpers/test-utils.js +277 -0
  7. package/infrastructure/__tests__/postgres-config.test.js +914 -0
  8. package/infrastructure/__tests__/template-generation.test.js +687 -0
  9. package/infrastructure/create-frigg-infrastructure.js +147 -0
  10. package/infrastructure/docs/POSTGRES-CONFIGURATION.md +630 -0
  11. package/infrastructure/docs/PRE-DEPLOYMENT-HEALTH-CHECK-SPEC.md +1317 -0
  12. package/infrastructure/docs/WEBSOCKET-CONFIGURATION.md +105 -0
  13. package/infrastructure/docs/deployment-instructions.md +268 -0
  14. package/infrastructure/docs/generate-iam-command.md +278 -0
  15. package/infrastructure/docs/iam-policy-templates.md +193 -0
  16. package/infrastructure/domains/database/aurora-builder.js +809 -0
  17. package/infrastructure/domains/database/aurora-builder.test.js +950 -0
  18. package/infrastructure/domains/database/aurora-discovery.js +87 -0
  19. package/infrastructure/domains/database/aurora-discovery.test.js +188 -0
  20. package/infrastructure/domains/database/aurora-resolver.js +210 -0
  21. package/infrastructure/domains/database/aurora-resolver.test.js +347 -0
  22. package/infrastructure/domains/database/migration-builder.js +701 -0
  23. package/infrastructure/domains/database/migration-builder.test.js +321 -0
  24. package/infrastructure/domains/database/migration-resolver.js +163 -0
  25. package/infrastructure/domains/database/migration-resolver.test.js +337 -0
  26. package/infrastructure/domains/health/application/ports/IPropertyReconciler.js +164 -0
  27. package/infrastructure/domains/health/application/ports/IResourceDetector.js +129 -0
  28. package/infrastructure/domains/health/application/ports/IResourceImporter.js +142 -0
  29. package/infrastructure/domains/health/application/ports/IStackRepository.js +131 -0
  30. package/infrastructure/domains/health/application/ports/index.js +26 -0
  31. package/infrastructure/domains/health/application/use-cases/__tests__/execute-resource-import-use-case.test.js +679 -0
  32. package/infrastructure/domains/health/application/use-cases/__tests__/mismatch-analyzer-method-name.test.js +167 -0
  33. package/infrastructure/domains/health/application/use-cases/__tests__/repair-via-import-use-case.test.js +1130 -0
  34. package/infrastructure/domains/health/application/use-cases/execute-resource-import-use-case.js +221 -0
  35. package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.js +152 -0
  36. package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.test.js +343 -0
  37. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.js +535 -0
  38. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.test.js +376 -0
  39. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.js +213 -0
  40. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.test.js +441 -0
  41. package/infrastructure/domains/health/docs/ACME-DEV-DRIFT-ANALYSIS.md +267 -0
  42. package/infrastructure/domains/health/docs/BUILD-VS-DEPLOYED-TEMPLATE-ANALYSIS.md +324 -0
  43. package/infrastructure/domains/health/docs/ORPHAN-DETECTION-ANALYSIS.md +386 -0
  44. package/infrastructure/domains/health/docs/SPEC-CLEANUP-COMMAND.md +1419 -0
  45. package/infrastructure/domains/health/docs/TDD-IMPLEMENTATION-SUMMARY.md +391 -0
  46. package/infrastructure/domains/health/docs/TEMPLATE-COMPARISON-IMPLEMENTATION.md +551 -0
  47. package/infrastructure/domains/health/domain/entities/issue.js +299 -0
  48. package/infrastructure/domains/health/domain/entities/issue.test.js +528 -0
  49. package/infrastructure/domains/health/domain/entities/property-mismatch.js +108 -0
  50. package/infrastructure/domains/health/domain/entities/property-mismatch.test.js +275 -0
  51. package/infrastructure/domains/health/domain/entities/resource.js +159 -0
  52. package/infrastructure/domains/health/domain/entities/resource.test.js +432 -0
  53. package/infrastructure/domains/health/domain/entities/stack-health-report.js +306 -0
  54. package/infrastructure/domains/health/domain/entities/stack-health-report.test.js +601 -0
  55. package/infrastructure/domains/health/domain/services/__tests__/health-score-percentage-based.test.js +380 -0
  56. package/infrastructure/domains/health/domain/services/__tests__/import-progress-monitor.test.js +971 -0
  57. package/infrastructure/domains/health/domain/services/__tests__/import-template-generator.test.js +1150 -0
  58. package/infrastructure/domains/health/domain/services/__tests__/logical-id-mapper.test.js +672 -0
  59. package/infrastructure/domains/health/domain/services/__tests__/template-parser.test.js +496 -0
  60. package/infrastructure/domains/health/domain/services/__tests__/update-progress-monitor.test.js +419 -0
  61. package/infrastructure/domains/health/domain/services/health-score-calculator.js +248 -0
  62. package/infrastructure/domains/health/domain/services/health-score-calculator.test.js +504 -0
  63. package/infrastructure/domains/health/domain/services/import-progress-monitor.js +195 -0
  64. package/infrastructure/domains/health/domain/services/import-template-generator.js +435 -0
  65. package/infrastructure/domains/health/domain/services/logical-id-mapper.js +345 -0
  66. package/infrastructure/domains/health/domain/services/mismatch-analyzer.js +234 -0
  67. package/infrastructure/domains/health/domain/services/mismatch-analyzer.test.js +431 -0
  68. package/infrastructure/domains/health/domain/services/property-mutability-config.js +382 -0
  69. package/infrastructure/domains/health/domain/services/template-parser.js +245 -0
  70. package/infrastructure/domains/health/domain/services/update-progress-monitor.js +192 -0
  71. package/infrastructure/domains/health/domain/value-objects/health-score.js +138 -0
  72. package/infrastructure/domains/health/domain/value-objects/health-score.test.js +267 -0
  73. package/infrastructure/domains/health/domain/value-objects/property-mutability.js +161 -0
  74. package/infrastructure/domains/health/domain/value-objects/property-mutability.test.js +198 -0
  75. package/infrastructure/domains/health/domain/value-objects/resource-state.js +167 -0
  76. package/infrastructure/domains/health/domain/value-objects/resource-state.test.js +196 -0
  77. package/infrastructure/domains/health/domain/value-objects/stack-identifier.js +192 -0
  78. package/infrastructure/domains/health/domain/value-objects/stack-identifier.test.js +262 -0
  79. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-cfn-tagged.test.js +312 -0
  80. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-multi-stack.test.js +367 -0
  81. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-relationship-analysis.test.js +432 -0
  82. package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.js +784 -0
  83. package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.test.js +1133 -0
  84. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.js +565 -0
  85. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.test.js +554 -0
  86. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.js +318 -0
  87. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.test.js +398 -0
  88. package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.js +777 -0
  89. package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.test.js +580 -0
  90. package/infrastructure/domains/integration/integration-builder.js +404 -0
  91. package/infrastructure/domains/integration/integration-builder.test.js +690 -0
  92. package/infrastructure/domains/integration/integration-resolver.js +170 -0
  93. package/infrastructure/domains/integration/integration-resolver.test.js +369 -0
  94. package/infrastructure/domains/integration/websocket-builder.js +69 -0
  95. package/infrastructure/domains/integration/websocket-builder.test.js +195 -0
  96. package/infrastructure/domains/networking/vpc-builder.js +2051 -0
  97. package/infrastructure/domains/networking/vpc-builder.test.js +1960 -0
  98. package/infrastructure/domains/networking/vpc-discovery.js +177 -0
  99. package/infrastructure/domains/networking/vpc-discovery.test.js +350 -0
  100. package/infrastructure/domains/networking/vpc-resolver.js +505 -0
  101. package/infrastructure/domains/networking/vpc-resolver.test.js +801 -0
  102. package/infrastructure/domains/parameters/ssm-builder.js +79 -0
  103. package/infrastructure/domains/parameters/ssm-builder.test.js +189 -0
  104. package/infrastructure/domains/parameters/ssm-discovery.js +84 -0
  105. package/infrastructure/domains/parameters/ssm-discovery.test.js +210 -0
  106. package/infrastructure/domains/security/iam-generator.js +816 -0
  107. package/infrastructure/domains/security/iam-generator.test.js +204 -0
  108. package/infrastructure/domains/security/kms-builder.js +415 -0
  109. package/infrastructure/domains/security/kms-builder.test.js +392 -0
  110. package/infrastructure/domains/security/kms-discovery.js +80 -0
  111. package/infrastructure/domains/security/kms-discovery.test.js +177 -0
  112. package/infrastructure/domains/security/kms-resolver.js +96 -0
  113. package/infrastructure/domains/security/kms-resolver.test.js +216 -0
  114. package/infrastructure/domains/security/templates/frigg-deployment-iam-stack.yaml +401 -0
  115. package/infrastructure/domains/security/templates/iam-policy-basic.json +218 -0
  116. package/infrastructure/domains/security/templates/iam-policy-full.json +288 -0
  117. package/infrastructure/domains/shared/base-builder.js +112 -0
  118. package/infrastructure/domains/shared/base-resolver.js +186 -0
  119. package/infrastructure/domains/shared/base-resolver.test.js +305 -0
  120. package/infrastructure/domains/shared/builder-orchestrator.js +212 -0
  121. package/infrastructure/domains/shared/builder-orchestrator.test.js +213 -0
  122. package/infrastructure/domains/shared/cloudformation-discovery-v2.js +334 -0
  123. package/infrastructure/domains/shared/cloudformation-discovery.js +672 -0
  124. package/infrastructure/domains/shared/cloudformation-discovery.test.js +985 -0
  125. package/infrastructure/domains/shared/environment-builder.js +119 -0
  126. package/infrastructure/domains/shared/environment-builder.test.js +247 -0
  127. package/infrastructure/domains/shared/providers/aws-provider-adapter.js +579 -0
  128. package/infrastructure/domains/shared/providers/aws-provider-adapter.test.js +416 -0
  129. package/infrastructure/domains/shared/providers/azure-provider-adapter.stub.js +93 -0
  130. package/infrastructure/domains/shared/providers/cloud-provider-adapter.js +136 -0
  131. package/infrastructure/domains/shared/providers/gcp-provider-adapter.stub.js +82 -0
  132. package/infrastructure/domains/shared/providers/provider-factory.js +108 -0
  133. package/infrastructure/domains/shared/providers/provider-factory.test.js +170 -0
  134. package/infrastructure/domains/shared/resource-discovery.enhanced.test.js +306 -0
  135. package/infrastructure/domains/shared/resource-discovery.js +233 -0
  136. package/infrastructure/domains/shared/resource-discovery.test.js +588 -0
  137. package/infrastructure/domains/shared/types/app-definition.js +205 -0
  138. package/infrastructure/domains/shared/types/discovery-result.js +106 -0
  139. package/infrastructure/domains/shared/types/discovery-result.test.js +258 -0
  140. package/infrastructure/domains/shared/types/index.js +46 -0
  141. package/infrastructure/domains/shared/types/resource-ownership.js +108 -0
  142. package/infrastructure/domains/shared/types/resource-ownership.test.js +101 -0
  143. package/infrastructure/domains/shared/utilities/base-definition-factory.js +408 -0
  144. package/infrastructure/domains/shared/utilities/base-definition-factory.js.bak +338 -0
  145. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +291 -0
  146. package/infrastructure/domains/shared/utilities/handler-path-resolver.js +134 -0
  147. package/infrastructure/domains/shared/utilities/handler-path-resolver.test.js +268 -0
  148. package/infrastructure/domains/shared/utilities/prisma-layer-manager.js +159 -0
  149. package/infrastructure/domains/shared/utilities/prisma-layer-manager.test.js +444 -0
  150. package/infrastructure/domains/shared/validation/env-validator.js +78 -0
  151. package/infrastructure/domains/shared/validation/env-validator.test.js +173 -0
  152. package/infrastructure/domains/shared/validation/plugin-validator.js +187 -0
  153. package/infrastructure/domains/shared/validation/plugin-validator.test.js +323 -0
  154. package/infrastructure/esbuild.config.js +53 -0
  155. package/infrastructure/index.js +4 -0
  156. package/infrastructure/infrastructure-composer.js +117 -0
  157. package/infrastructure/infrastructure-composer.test.js +1895 -0
  158. package/infrastructure/integration.test.js +383 -0
  159. package/infrastructure/scripts/build-prisma-layer.js +701 -0
  160. package/infrastructure/scripts/build-prisma-layer.test.js +170 -0
  161. package/infrastructure/scripts/build-time-discovery.js +238 -0
  162. package/infrastructure/scripts/build-time-discovery.test.js +379 -0
  163. package/infrastructure/scripts/run-discovery.js +110 -0
  164. package/infrastructure/scripts/verify-prisma-layer.js +72 -0
  165. package/package.json +8 -7
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Resource Discovery Service
3
+ *
4
+ * Domain Service - Hexagonal Architecture
5
+ *
6
+ * Orchestrates discovery of cloud resources (VPC, databases, encryption keys, etc.)
7
+ * using the cloud provider abstraction layer and domain-specific discovery services.
8
+ *
9
+ * This service is cloud-agnostic and delegates to provider-specific implementations.
10
+ */
11
+
12
+ const { CloudProviderFactory } = require('./providers/provider-factory');
13
+ const { CloudFormationDiscovery } = require('./cloudformation-discovery');
14
+ const { VpcDiscovery } = require('../networking/vpc-discovery');
15
+ const { KmsDiscovery } = require('../security/kms-discovery');
16
+ const { AuroraDiscovery } = require('../database/aurora-discovery');
17
+ const { SsmDiscovery } = require('../parameters/ssm-discovery');
18
+
19
+ /**
20
+ * Determine if AWS discovery should run
21
+ *
22
+ * Checks in priority order:
23
+ * 1. AppDefinition.aws.discovery.enabled (explicit opt-in/out)
24
+ * 2. FRIGG_SKIP_AWS_DISCOVERY environment variable
25
+ * 3. Auto-detection based on features enabled (VPC, KMS, SSM, PostgreSQL)
26
+ *
27
+ * @param {Object} appDefinition - Application definition
28
+ * @returns {boolean} True if discovery is needed
29
+ */
30
+ function shouldRunDiscovery(appDefinition) {
31
+ // Priority 1: Check AppDefinition-level configuration
32
+ if (appDefinition.aws?.discovery?.enabled !== undefined) {
33
+ const enabled = appDefinition.aws.discovery.enabled;
34
+ console.log(
35
+ `⚙️ Using AppDefinition.aws.discovery.enabled: ${enabled}`
36
+ );
37
+ return enabled;
38
+ }
39
+
40
+ // Priority 2: Check environment variable
41
+ console.log(
42
+ '⚙️ Checking FRIGG_SKIP_AWS_DISCOVERY:',
43
+ process.env.FRIGG_SKIP_AWS_DISCOVERY
44
+ );
45
+
46
+ if (process.env.FRIGG_SKIP_AWS_DISCOVERY === 'true') {
47
+ console.log(
48
+ '⚙️ Skipping AWS discovery because FRIGG_SKIP_AWS_DISCOVERY is set.'
49
+ );
50
+ return false;
51
+ }
52
+
53
+ // Priority 3: Auto-detect based on enabled features
54
+ return (
55
+ appDefinition.vpc?.enable === true ||
56
+ appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms' ||
57
+ appDefinition.ssm?.enable === true ||
58
+ appDefinition.database?.postgres?.enable === true
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Gather discovered cloud resources
64
+ *
65
+ * Uses cloud provider abstraction to discover resources in a provider-agnostic way.
66
+ *
67
+ * @param {Object} appDefinition - Application definition
68
+ * @returns {Promise<Object>} Discovered cloud resources
69
+ */
70
+ async function gatherDiscoveredResources(appDefinition) {
71
+ if (!shouldRunDiscovery(appDefinition)) {
72
+ console.log('⚙️ Skipping cloud resource discovery (not required for this configuration)');
73
+ return {};
74
+ }
75
+
76
+ console.log('🔍 Running cloud resource discovery...');
77
+
78
+ try {
79
+ // Get cloud provider (defaults to AWS, can be overridden via env var)
80
+ const providerName = process.env.CLOUD_PROVIDER || appDefinition.provider || 'aws';
81
+ const region = process.env.AWS_REGION || 'us-east-1';
82
+
83
+ console.log(` Provider: ${providerName}`);
84
+ console.log(` Region: ${region}`);
85
+
86
+ // Create provider adapter
87
+ const provider = CloudProviderFactory.create(providerName, region);
88
+
89
+ // Build discovery configuration
90
+ const stage = process.env.SLS_STAGE || 'dev';
91
+ const stackName = `${appDefinition.name || 'create-frigg-app'}-${stage}`;
92
+ const serviceName = appDefinition.name || 'create-frigg-app';
93
+
94
+ // Try CloudFormation-first discovery
95
+ const cfDiscovery = new CloudFormationDiscovery(provider, { serviceName, stage });
96
+ const stackResources = await cfDiscovery.discoverFromStack(stackName);
97
+
98
+ // Validate CF discovery results - check for ANY useful infrastructure
99
+ const hasVpcData = stackResources?.defaultVpcId; // VPC resource in stack
100
+ const hasKmsData = stackResources?.defaultKmsKeyId; // KMS resource in stack
101
+ const hasAuroraData = stackResources?.auroraClusterId; // Aurora in stack
102
+
103
+ // Check for routing infrastructure (proves VPC config exists even with external VPC)
104
+ const hasRoutingInfra = stackResources?.routeTableId || // FriggLambdaRouteTable
105
+ stackResources?.natRoute || // FriggNATRoute
106
+ stackResources?.vpcEndpoints?.s3 || // VPC endpoints
107
+ stackResources?.vpcEndpoints?.dynamodb;
108
+
109
+ // Stack is useful if it has EITHER actual resources OR routing infrastructure
110
+ const hasSomeUsefulData = hasVpcData || hasKmsData || hasAuroraData || hasRoutingInfra;
111
+
112
+ if (hasRoutingInfra && !hasVpcData) {
113
+ console.log(' ✓ Found VPC routing infrastructure in stack (external VPC pattern)');
114
+ }
115
+
116
+ // Check if we're in isolated mode (each stage gets its own VPC/Aurora)
117
+ const isIsolatedMode = appDefinition.managementMode === 'managed' &&
118
+ appDefinition.vpcIsolation === 'isolated';
119
+
120
+ if (stackResources && hasSomeUsefulData) {
121
+ console.log(' ✓ Discovered resources from existing CloudFormation stack');
122
+ console.log('✅ Cloud resource discovery completed successfully!');
123
+ return stackResources;
124
+ }
125
+
126
+ // In isolated mode, NEVER fall back to AWS discovery for VPC/Aurora
127
+ // These resources must be isolated per stage, so we either:
128
+ // 1. Use resources from THIS stage's CloudFormation stack (handled above)
129
+ // 2. Return empty to CREATE fresh isolated resources for this stage
130
+ if (isIsolatedMode) {
131
+ console.log(' ℹ Isolated mode: No CloudFormation stack or no VPC/Aurora in stack');
132
+ console.log(' ℹ Will create fresh isolated VPC/Aurora for this stage');
133
+ console.log(' ℹ Checking for shared KMS key...');
134
+
135
+ // KMS keys CAN be shared across stages (encryption keys are safe to reuse)
136
+ const kmsDiscovery = new KmsDiscovery(provider);
137
+ const kmsConfig = {
138
+ serviceName: appDefinition.name || 'create-frigg-app',
139
+ stage,
140
+ keyAlias: `alias/${appDefinition.name || 'create-frigg-app'}-${stage}-frigg-kms`,
141
+ };
142
+ const kmsResult = await kmsDiscovery.discover(kmsConfig);
143
+
144
+ if (kmsResult?.defaultKmsKeyId) {
145
+ console.log(' ✓ Found shared KMS key (can be reused across stages)');
146
+ console.log('✅ Cloud resource discovery completed - will create isolated VPC/Aurora!');
147
+ return kmsResult;
148
+ }
149
+
150
+ console.log(' ℹ No existing KMS key found - will create new one');
151
+ console.log('✅ Cloud resource discovery completed - will create fresh isolated resources!');
152
+ return {};
153
+ }
154
+
155
+ // Fallback to AWS API discovery (fresh deployment, stack not found, or stack has no useful data)
156
+ if (stackResources && !hasSomeUsefulData) {
157
+ console.log(' ℹ Stack found but contains no usable resources - running AWS API discovery...');
158
+ } else {
159
+ console.log(' ℹ No stack found - running AWS API discovery...');
160
+ }
161
+
162
+ // Create domain discovery services with provider
163
+ const vpcDiscovery = new VpcDiscovery(provider);
164
+ const kmsDiscovery = new KmsDiscovery(provider);
165
+ const auroraDiscovery = new AuroraDiscovery(provider);
166
+ const ssmDiscovery = new SsmDiscovery(provider);
167
+
168
+ const config = {
169
+ serviceName: appDefinition.name || 'create-frigg-app',
170
+ stage,
171
+ vpcId: appDefinition.vpc?.vpcId,
172
+ databaseId: appDefinition.database?.postgres?.clusterId ||
173
+ appDefinition.database?.postgres?.instanceId,
174
+ keyAlias: appDefinition.encryption?.keyAlias,
175
+ includeSecrets: true,
176
+ };
177
+
178
+ // Run discoveries in parallel for better performance
179
+ const [vpcResources, kmsResources, dbResources, ssmResources] =
180
+ await Promise.all([
181
+ appDefinition.vpc?.enable ? vpcDiscovery.discover(config) : Promise.resolve({}),
182
+ appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms'
183
+ ? kmsDiscovery.discover(config)
184
+ : Promise.resolve({}),
185
+ appDefinition.database?.postgres?.enable
186
+ ? auroraDiscovery.discover(config)
187
+ : Promise.resolve({}),
188
+ appDefinition.ssm?.enable
189
+ ? ssmDiscovery.discover(config)
190
+ : Promise.resolve({}),
191
+ ]);
192
+
193
+ // Aggregate results
194
+ const discoveredResources = {
195
+ ...vpcResources,
196
+ ...kmsResources,
197
+ ...dbResources,
198
+ ...ssmResources,
199
+ };
200
+
201
+ console.log('✅ Cloud resource discovery completed successfully!');
202
+
203
+ return discoveredResources;
204
+ } catch (error) {
205
+ console.error('❌ Cloud resource discovery failed:', error.message);
206
+ console.error('Stack:', error.stack);
207
+
208
+ // Check if discovery failures should fail the deployment
209
+ const failOnError = appDefinition.aws?.discovery?.failOnError ?? false;
210
+
211
+ if (failOnError) {
212
+ console.error(
213
+ '❌ Discovery failure blocking deployment (aws.discovery.failOnError = true)'
214
+ );
215
+ throw error;
216
+ }
217
+
218
+ // Graceful degradation - return empty resources and let validation handle it
219
+ console.warn(
220
+ '⚠️ Continuing with empty discovered resources. This may cause deployment issues if resources are required.'
221
+ );
222
+ console.warn(
223
+ '💡 Set aws.discovery.failOnError = true in AppDefinition to fail on discovery errors.'
224
+ );
225
+ return {};
226
+ }
227
+ }
228
+
229
+ module.exports = {
230
+ shouldRunDiscovery,
231
+ gatherDiscoveredResources,
232
+ };
233
+