@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,170 @@
1
+ /**
2
+ * Tests for Prisma Lambda Layer Builder
3
+ * Validates database client selection logic
4
+ */
5
+
6
+ const {
7
+ getGeneratedClientPackages,
8
+ getMigrationsPackages,
9
+ getMigrationSourcePath,
10
+ getMigrationDestinationPath,
11
+ } = require('./build-prisma-layer');
12
+
13
+ // Mock the log function
14
+ jest.mock('./build-prisma-layer', () => {
15
+ const actual = jest.requireActual('./build-prisma-layer');
16
+ return {
17
+ ...actual,
18
+ getGeneratedClientPackages: actual.getGeneratedClientPackages,
19
+ getMigrationsPackages: actual.getMigrationsPackages,
20
+ getMigrationSourcePath: actual.getMigrationSourcePath,
21
+ getMigrationDestinationPath: actual.getMigrationDestinationPath,
22
+ };
23
+ });
24
+
25
+ describe('getGeneratedClientPackages()', () => {
26
+ it('should include MongoDB client when mongoDB.enable is true', () => {
27
+ const databaseConfig = {
28
+ mongoDB: { enable: true },
29
+ };
30
+
31
+ const packages = getGeneratedClientPackages(databaseConfig);
32
+
33
+ expect(packages).toContain('generated/prisma-mongodb');
34
+ });
35
+
36
+ it('should include MongoDB client when documentDB.enable is true', () => {
37
+ const databaseConfig = {
38
+ documentDB: { enable: true },
39
+ };
40
+
41
+ const packages = getGeneratedClientPackages(databaseConfig);
42
+
43
+ expect(packages).toContain('generated/prisma-mongodb');
44
+ });
45
+
46
+ it('should include PostgreSQL client when postgres.enable is true', () => {
47
+ const databaseConfig = {
48
+ postgres: { enable: true },
49
+ };
50
+
51
+ const packages = getGeneratedClientPackages(databaseConfig);
52
+
53
+ expect(packages).toContain('generated/prisma-postgresql');
54
+ });
55
+
56
+ it('should include both clients when both databases are enabled', () => {
57
+ const databaseConfig = {
58
+ mongoDB: { enable: true },
59
+ postgres: { enable: true },
60
+ };
61
+
62
+ const packages = getGeneratedClientPackages(databaseConfig);
63
+
64
+ expect(packages).toContain('generated/prisma-mongodb');
65
+ expect(packages).toContain('generated/prisma-postgresql');
66
+ expect(packages).toHaveLength(2);
67
+ });
68
+
69
+ it('should include both clients when documentDB and postgres are enabled', () => {
70
+ const databaseConfig = {
71
+ documentDB: { enable: true },
72
+ postgres: { enable: true },
73
+ };
74
+
75
+ const packages = getGeneratedClientPackages(databaseConfig);
76
+
77
+ expect(packages).toContain('generated/prisma-mongodb');
78
+ expect(packages).toContain('generated/prisma-postgresql');
79
+ expect(packages).toHaveLength(2);
80
+ });
81
+
82
+ it('should default to PostgreSQL when no database config provided', () => {
83
+ const packages = getGeneratedClientPackages({});
84
+
85
+ expect(packages).toContain('generated/prisma-postgresql');
86
+ expect(packages).toHaveLength(1);
87
+ });
88
+
89
+ it('should default to PostgreSQL when database config is null', () => {
90
+ const packages = getGeneratedClientPackages(null);
91
+
92
+ expect(packages).toContain('generated/prisma-postgresql');
93
+ expect(packages).toHaveLength(1);
94
+ });
95
+
96
+ it('should only include MongoDB when postgres.enable is false and mongoDB is true', () => {
97
+ const databaseConfig = {
98
+ mongoDB: { enable: true },
99
+ postgres: { enable: false },
100
+ };
101
+
102
+ const packages = getGeneratedClientPackages(databaseConfig);
103
+
104
+ expect(packages).toContain('generated/prisma-mongodb');
105
+ expect(packages).not.toContain('generated/prisma-postgresql');
106
+ expect(packages).toHaveLength(1);
107
+ });
108
+ });
109
+
110
+ describe('getMigrationsPackages()', () => {
111
+ it('should extract database types from client packages', () => {
112
+ const clientPackages = [
113
+ 'generated/prisma-postgresql',
114
+ 'generated/prisma-mongodb',
115
+ ];
116
+ const migrations = getMigrationsPackages(clientPackages);
117
+
118
+ expect(migrations).toEqual([
119
+ {
120
+ dbType: 'postgresql',
121
+ clientPackage: 'generated/prisma-postgresql',
122
+ },
123
+ { dbType: 'mongodb', clientPackage: 'generated/prisma-mongodb' },
124
+ ]);
125
+ });
126
+
127
+ it('should handle single client package', () => {
128
+ const clientPackages = ['generated/prisma-postgresql'];
129
+ const migrations = getMigrationsPackages(clientPackages);
130
+
131
+ expect(migrations).toEqual([
132
+ {
133
+ dbType: 'postgresql',
134
+ clientPackage: 'generated/prisma-postgresql',
135
+ },
136
+ ]);
137
+ });
138
+
139
+ it('should handle empty array', () => {
140
+ const migrations = getMigrationsPackages([]);
141
+ expect(migrations).toEqual([]);
142
+ });
143
+ });
144
+
145
+ describe('getMigrationSourcePath()', () => {
146
+ it('should return correct source path for database type', () => {
147
+ const searchPaths = ['/workspace/packages/core'];
148
+ const dbType = 'postgresql';
149
+
150
+ const sourcePath = getMigrationSourcePath(searchPaths, dbType);
151
+ expect(sourcePath).toBe(
152
+ '/workspace/packages/core/prisma-postgresql/migrations'
153
+ );
154
+ });
155
+ });
156
+
157
+ describe('getMigrationDestinationPath()', () => {
158
+ it('should return correct destination path for client package', () => {
159
+ const layerNodeModules = '/layers/prisma/nodejs/node_modules';
160
+ const clientPackage = 'generated/prisma-postgresql';
161
+
162
+ const destPath = getMigrationDestinationPath(
163
+ layerNodeModules,
164
+ clientPackage
165
+ );
166
+ expect(destPath).toBe(
167
+ '/layers/prisma/nodejs/node_modules/generated/prisma-postgresql/migrations'
168
+ );
169
+ });
170
+ });
@@ -0,0 +1,238 @@
1
+ const fs = require('fs');
2
+ let AWSDiscovery;
3
+
4
+ function loadAWSDiscovery() {
5
+ if (!AWSDiscovery) {
6
+ ({ AWSDiscovery } = require('./aws-discovery'));
7
+ }
8
+ }
9
+
10
+ /**
11
+ * Build-time AWS resource discovery and configuration injection
12
+ * This utility runs during the build process to discover AWS resources
13
+ * and inject them into the serverless configuration
14
+ */
15
+ class BuildTimeDiscovery {
16
+ /**
17
+ * Creates an instance of BuildTimeDiscovery
18
+ * @param {string} [region=process.env.AWS_REGION || 'us-east-1'] - AWS region for discovery
19
+ */
20
+ constructor(region = process.env.AWS_REGION || 'us-east-1') {
21
+ loadAWSDiscovery();
22
+ this.region = region;
23
+ this.discovery = new AWSDiscovery(region);
24
+ }
25
+
26
+ /**
27
+ * Discover AWS resources and create a configuration file
28
+ * @param {string} [outputPath='./aws-discovery-config.json'] - Path to write the configuration file
29
+ * @returns {Promise<Object>} Configuration object containing discovered resources
30
+ * @throws {Error} If AWS resource discovery fails
31
+ */
32
+ async discoverAndCreateConfig(outputPath = './aws-discovery-config.json') {
33
+ try {
34
+ console.log('Starting AWS resource discovery for build...');
35
+
36
+ const resources = await this.discovery.discoverResources();
37
+
38
+ // Create configuration object
39
+ const config = {
40
+ awsDiscovery: resources,
41
+ generatedAt: new Date().toISOString(),
42
+ region: this.region,
43
+ };
44
+
45
+ // Write configuration to file
46
+ fs.writeFileSync(outputPath, JSON.stringify(config, null, 2));
47
+ console.log(
48
+ `AWS discovery configuration written to: ${outputPath}`,
49
+ );
50
+
51
+ return config;
52
+ } catch (error) {
53
+ console.error(
54
+ 'Error during AWS resource discovery:',
55
+ error.message,
56
+ );
57
+ throw error;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Replace placeholders in serverless template with discovered values
63
+ * @param {string} templateContent - The template content with placeholders
64
+ * @param {Object} discoveredResources - Object containing discovered AWS resource IDs
65
+ * @returns {string} Updated template content with placeholders replaced
66
+ */
67
+ replaceTemplateVariables(templateContent, discoveredResources) {
68
+ let updatedContent = templateContent;
69
+
70
+ // Replace AWS discovery placeholders
71
+ const replacements = {
72
+ '${self:custom.awsDiscovery.defaultVpcId}':
73
+ discoveredResources.defaultVpcId,
74
+ '${self:custom.awsDiscovery.defaultSecurityGroupId}':
75
+ discoveredResources.defaultSecurityGroupId,
76
+ '${self:custom.awsDiscovery.privateSubnetId1}':
77
+ discoveredResources.privateSubnetId1,
78
+ '${self:custom.awsDiscovery.privateSubnetId2}':
79
+ discoveredResources.privateSubnetId2,
80
+ '${self:custom.awsDiscovery.privateRouteTableId}':
81
+ discoveredResources.privateRouteTableId,
82
+ '${self:custom.awsDiscovery.defaultKmsKeyId}':
83
+ discoveredResources.defaultKmsKeyId,
84
+ };
85
+
86
+ for (const [placeholder, value] of Object.entries(replacements)) {
87
+ // Use a more targeted replacement to avoid replacing similar strings
88
+ updatedContent = updatedContent.replace(
89
+ new RegExp(
90
+ placeholder.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'),
91
+ 'g',
92
+ ),
93
+ value,
94
+ );
95
+ }
96
+
97
+ return updatedContent;
98
+ }
99
+
100
+ /**
101
+ * Process serverless configuration and inject discovered resources
102
+ * @param {string} configPath - Path to the serverless configuration file
103
+ * @param {string} [outputPath=null] - Output path for updated config (defaults to overwriting original)
104
+ * @returns {Promise<Object>} Object containing discovered AWS resources
105
+ * @throws {Error} If processing the serverless configuration fails
106
+ */
107
+ async processServerlessConfig(configPath, outputPath = null) {
108
+ try {
109
+ console.log(`Processing serverless configuration: ${configPath}`);
110
+
111
+ // Read the current serverless configuration
112
+ const configContent = fs.readFileSync(configPath, 'utf8');
113
+
114
+ // Discover AWS resources
115
+ const resources = await this.discovery.discoverResources();
116
+
117
+ // Replace placeholders with discovered values
118
+ const updatedContent = this.replaceTemplateVariables(
119
+ configContent,
120
+ resources,
121
+ );
122
+
123
+ // Write to output file or overwrite original
124
+ const finalPath = outputPath || configPath;
125
+ fs.writeFileSync(finalPath, updatedContent);
126
+
127
+ console.log(
128
+ `Updated serverless configuration written to: ${finalPath}`,
129
+ );
130
+
131
+ return resources;
132
+ } catch (error) {
133
+ console.error(
134
+ 'Error processing serverless configuration:',
135
+ error.message,
136
+ );
137
+ throw error;
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Generate a custom serverless configuration section for discovered resources
143
+ * @param {Object} discoveredResources - Object containing discovered AWS resource IDs
144
+ * @returns {Object} Custom section object for serverless configuration
145
+ */
146
+ generateCustomSection(discoveredResources) {
147
+ return {
148
+ awsDiscovery: discoveredResources,
149
+ };
150
+ }
151
+
152
+ /**
153
+ * Pre-build hook to discover resources and prepare configuration
154
+ * @param {Object} appDefinition - Application definition object
155
+ * @param {string} region - AWS region for discovery
156
+ * @returns {Promise<Object|null>} Discovered resources or null if discovery not needed
157
+ * @throws {Error} If pre-build AWS discovery fails
158
+ */
159
+ async preBuildHook(appDefinition, region) {
160
+ try {
161
+ console.log('Running pre-build AWS discovery hook...');
162
+
163
+ // Only run discovery if VPC, KMS, or SSM features are enabled
164
+ const needsDiscovery =
165
+ appDefinition.vpc?.enable ||
166
+ appDefinition.encryption?.fieldLevelEncryptionMethod ===
167
+ 'kms' ||
168
+ appDefinition.ssm?.enable;
169
+
170
+ if (!needsDiscovery) {
171
+ console.log('No AWS discovery needed based on app definition');
172
+ return null;
173
+ }
174
+
175
+ // Create discovery instance with specified region
176
+ loadAWSDiscovery();
177
+ const discovery = new AWSDiscovery(region);
178
+ const resources = await discovery.discoverResources();
179
+
180
+ // Create environment variables for serverless
181
+ const envVars = {
182
+ AWS_DISCOVERY_VPC_ID: resources.defaultVpcId,
183
+ AWS_DISCOVERY_SECURITY_GROUP_ID:
184
+ resources.defaultSecurityGroupId,
185
+ AWS_DISCOVERY_SUBNET_ID_1: resources.privateSubnetId1,
186
+ AWS_DISCOVERY_SUBNET_ID_2: resources.privateSubnetId2,
187
+ AWS_DISCOVERY_PUBLIC_SUBNET_ID: resources.publicSubnetId,
188
+ AWS_DISCOVERY_ROUTE_TABLE_ID: resources.privateRouteTableId,
189
+ AWS_DISCOVERY_KMS_KEY_ID: resources.defaultKmsKeyId, // Keep consistent naming convention (even though it's an ARN)
190
+ };
191
+
192
+ // Set environment variables for serverless to use
193
+ Object.assign(process.env, envVars);
194
+
195
+ console.log(
196
+ 'AWS discovery completed and environment variables set',
197
+ );
198
+ return resources;
199
+ } catch (error) {
200
+ console.error(
201
+ 'Error in pre-build AWS discovery hook:',
202
+ error.message,
203
+ );
204
+ throw error;
205
+ }
206
+ }
207
+ }
208
+
209
+ /**
210
+ * CLI utility function for build-time discovery
211
+ * @param {Object} [options={}] - Options for build-time discovery
212
+ * @param {string} [options.region=process.env.AWS_REGION || 'us-east-1'] - AWS region
213
+ * @param {string} [options.outputPath='./aws-discovery-config.json'] - Output path for config file
214
+ * @param {string} [options.configPath=null] - Path to existing serverless config to process
215
+ * @returns {Promise<Object>} Discovered AWS resources
216
+ */
217
+ async function runBuildTimeDiscovery(options = {}) {
218
+ const {
219
+ region = process.env.AWS_REGION || 'us-east-1',
220
+ outputPath = './aws-discovery-config.json',
221
+ configPath = null,
222
+ } = options;
223
+
224
+ const discovery = new BuildTimeDiscovery(region);
225
+
226
+ if (configPath) {
227
+ // Process existing serverless configuration
228
+ return await discovery.processServerlessConfig(configPath);
229
+ } else {
230
+ // Just discover and create config file
231
+ return await discovery.discoverAndCreateConfig(outputPath);
232
+ }
233
+ }
234
+
235
+ module.exports = {
236
+ BuildTimeDiscovery,
237
+ runBuildTimeDiscovery,
238
+ };