@friggframework/devtools 2.0.0-next.44 → 2.0.0-next.46

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 (212) hide show
  1. package/infrastructure/ARCHITECTURE.md +487 -0
  2. package/infrastructure/HEALTH.md +468 -0
  3. package/infrastructure/README.md +51 -0
  4. package/infrastructure/__tests__/postgres-config.test.js +914 -0
  5. package/infrastructure/__tests__/template-generation.test.js +687 -0
  6. package/infrastructure/create-frigg-infrastructure.js +1 -1
  7. package/infrastructure/docs/POSTGRES-CONFIGURATION.md +630 -0
  8. package/infrastructure/{DEPLOYMENT-INSTRUCTIONS.md → docs/deployment-instructions.md} +3 -3
  9. package/infrastructure/{IAM-POLICY-TEMPLATES.md → docs/iam-policy-templates.md} +9 -10
  10. package/infrastructure/domains/database/aurora-builder.js +809 -0
  11. package/infrastructure/domains/database/aurora-builder.test.js +950 -0
  12. package/infrastructure/domains/database/aurora-discovery.js +87 -0
  13. package/infrastructure/domains/database/aurora-discovery.test.js +188 -0
  14. package/infrastructure/domains/database/aurora-resolver.js +210 -0
  15. package/infrastructure/domains/database/aurora-resolver.test.js +347 -0
  16. package/infrastructure/domains/database/migration-builder.js +633 -0
  17. package/infrastructure/domains/database/migration-builder.test.js +294 -0
  18. package/infrastructure/domains/database/migration-resolver.js +163 -0
  19. package/infrastructure/domains/database/migration-resolver.test.js +337 -0
  20. package/infrastructure/domains/health/application/ports/IPropertyReconciler.js +164 -0
  21. package/infrastructure/domains/health/application/ports/IResourceDetector.js +129 -0
  22. package/infrastructure/domains/health/application/ports/IResourceImporter.js +142 -0
  23. package/infrastructure/domains/health/application/ports/IStackRepository.js +131 -0
  24. package/infrastructure/domains/health/application/ports/index.js +26 -0
  25. package/infrastructure/domains/health/application/use-cases/__tests__/execute-resource-import-use-case.test.js +679 -0
  26. package/infrastructure/domains/health/application/use-cases/__tests__/mismatch-analyzer-method-name.test.js +167 -0
  27. package/infrastructure/domains/health/application/use-cases/__tests__/repair-via-import-use-case.test.js +1130 -0
  28. package/infrastructure/domains/health/application/use-cases/execute-resource-import-use-case.js +221 -0
  29. package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.js +152 -0
  30. package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.test.js +343 -0
  31. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.js +535 -0
  32. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.test.js +376 -0
  33. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.js +213 -0
  34. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.test.js +441 -0
  35. package/infrastructure/domains/health/docs/ACME-DEV-DRIFT-ANALYSIS.md +267 -0
  36. package/infrastructure/domains/health/docs/BUILD-VS-DEPLOYED-TEMPLATE-ANALYSIS.md +324 -0
  37. package/infrastructure/domains/health/docs/ORPHAN-DETECTION-ANALYSIS.md +386 -0
  38. package/infrastructure/domains/health/docs/SPEC-CLEANUP-COMMAND.md +1419 -0
  39. package/infrastructure/domains/health/docs/TDD-IMPLEMENTATION-SUMMARY.md +391 -0
  40. package/infrastructure/domains/health/docs/TEMPLATE-COMPARISON-IMPLEMENTATION.md +551 -0
  41. package/infrastructure/domains/health/domain/entities/issue.js +299 -0
  42. package/infrastructure/domains/health/domain/entities/issue.test.js +528 -0
  43. package/infrastructure/domains/health/domain/entities/property-mismatch.js +108 -0
  44. package/infrastructure/domains/health/domain/entities/property-mismatch.test.js +275 -0
  45. package/infrastructure/domains/health/domain/entities/resource.js +159 -0
  46. package/infrastructure/domains/health/domain/entities/resource.test.js +432 -0
  47. package/infrastructure/domains/health/domain/entities/stack-health-report.js +306 -0
  48. package/infrastructure/domains/health/domain/entities/stack-health-report.test.js +601 -0
  49. package/infrastructure/domains/health/domain/services/__tests__/health-score-percentage-based.test.js +380 -0
  50. package/infrastructure/domains/health/domain/services/__tests__/import-progress-monitor.test.js +971 -0
  51. package/infrastructure/domains/health/domain/services/__tests__/import-template-generator.test.js +1150 -0
  52. package/infrastructure/domains/health/domain/services/__tests__/logical-id-mapper.test.js +672 -0
  53. package/infrastructure/domains/health/domain/services/__tests__/template-parser.test.js +496 -0
  54. package/infrastructure/domains/health/domain/services/__tests__/update-progress-monitor.test.js +419 -0
  55. package/infrastructure/domains/health/domain/services/health-score-calculator.js +248 -0
  56. package/infrastructure/domains/health/domain/services/health-score-calculator.test.js +504 -0
  57. package/infrastructure/domains/health/domain/services/import-progress-monitor.js +195 -0
  58. package/infrastructure/domains/health/domain/services/import-template-generator.js +435 -0
  59. package/infrastructure/domains/health/domain/services/logical-id-mapper.js +345 -0
  60. package/infrastructure/domains/health/domain/services/mismatch-analyzer.js +234 -0
  61. package/infrastructure/domains/health/domain/services/mismatch-analyzer.test.js +431 -0
  62. package/infrastructure/domains/health/domain/services/property-mutability-config.js +382 -0
  63. package/infrastructure/domains/health/domain/services/template-parser.js +245 -0
  64. package/infrastructure/domains/health/domain/services/update-progress-monitor.js +192 -0
  65. package/infrastructure/domains/health/domain/value-objects/health-score.js +138 -0
  66. package/infrastructure/domains/health/domain/value-objects/health-score.test.js +267 -0
  67. package/infrastructure/domains/health/domain/value-objects/property-mutability.js +161 -0
  68. package/infrastructure/domains/health/domain/value-objects/property-mutability.test.js +198 -0
  69. package/infrastructure/domains/health/domain/value-objects/resource-state.js +167 -0
  70. package/infrastructure/domains/health/domain/value-objects/resource-state.test.js +196 -0
  71. package/infrastructure/domains/health/domain/value-objects/stack-identifier.js +192 -0
  72. package/infrastructure/domains/health/domain/value-objects/stack-identifier.test.js +262 -0
  73. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-cfn-tagged.test.js +312 -0
  74. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-multi-stack.test.js +367 -0
  75. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-relationship-analysis.test.js +432 -0
  76. package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.js +784 -0
  77. package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.test.js +1133 -0
  78. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.js +565 -0
  79. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.test.js +554 -0
  80. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.js +318 -0
  81. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.test.js +398 -0
  82. package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.js +777 -0
  83. package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.test.js +580 -0
  84. package/infrastructure/domains/integration/integration-builder.js +397 -0
  85. package/infrastructure/domains/integration/integration-builder.test.js +593 -0
  86. package/infrastructure/domains/integration/integration-resolver.js +170 -0
  87. package/infrastructure/domains/integration/integration-resolver.test.js +369 -0
  88. package/infrastructure/domains/integration/websocket-builder.js +69 -0
  89. package/infrastructure/domains/integration/websocket-builder.test.js +195 -0
  90. package/infrastructure/domains/networking/vpc-builder.js +1829 -0
  91. package/infrastructure/domains/networking/vpc-builder.test.js +1262 -0
  92. package/infrastructure/domains/networking/vpc-discovery.js +177 -0
  93. package/infrastructure/domains/networking/vpc-discovery.test.js +350 -0
  94. package/infrastructure/domains/networking/vpc-resolver.js +324 -0
  95. package/infrastructure/domains/networking/vpc-resolver.test.js +501 -0
  96. package/infrastructure/domains/parameters/ssm-builder.js +79 -0
  97. package/infrastructure/domains/parameters/ssm-builder.test.js +189 -0
  98. package/infrastructure/domains/parameters/ssm-discovery.js +84 -0
  99. package/infrastructure/domains/parameters/ssm-discovery.test.js +210 -0
  100. package/infrastructure/{iam-generator.js → domains/security/iam-generator.js} +2 -2
  101. package/infrastructure/domains/security/kms-builder.js +366 -0
  102. package/infrastructure/domains/security/kms-builder.test.js +374 -0
  103. package/infrastructure/domains/security/kms-discovery.js +80 -0
  104. package/infrastructure/domains/security/kms-discovery.test.js +177 -0
  105. package/infrastructure/domains/security/kms-resolver.js +96 -0
  106. package/infrastructure/domains/security/kms-resolver.test.js +216 -0
  107. package/infrastructure/domains/shared/base-builder.js +112 -0
  108. package/infrastructure/domains/shared/base-resolver.js +186 -0
  109. package/infrastructure/domains/shared/base-resolver.test.js +305 -0
  110. package/infrastructure/domains/shared/builder-orchestrator.js +212 -0
  111. package/infrastructure/domains/shared/builder-orchestrator.test.js +213 -0
  112. package/infrastructure/domains/shared/cloudformation-discovery-v2.js +334 -0
  113. package/infrastructure/domains/shared/cloudformation-discovery.js +375 -0
  114. package/infrastructure/domains/shared/cloudformation-discovery.test.js +590 -0
  115. package/infrastructure/domains/shared/environment-builder.js +119 -0
  116. package/infrastructure/domains/shared/environment-builder.test.js +247 -0
  117. package/infrastructure/domains/shared/providers/aws-provider-adapter.js +544 -0
  118. package/infrastructure/domains/shared/providers/aws-provider-adapter.test.js +377 -0
  119. package/infrastructure/domains/shared/providers/azure-provider-adapter.stub.js +93 -0
  120. package/infrastructure/domains/shared/providers/cloud-provider-adapter.js +136 -0
  121. package/infrastructure/domains/shared/providers/gcp-provider-adapter.stub.js +82 -0
  122. package/infrastructure/domains/shared/providers/provider-factory.js +108 -0
  123. package/infrastructure/domains/shared/providers/provider-factory.test.js +170 -0
  124. package/infrastructure/domains/shared/resource-discovery.js +192 -0
  125. package/infrastructure/domains/shared/resource-discovery.test.js +552 -0
  126. package/infrastructure/domains/shared/types/app-definition.js +205 -0
  127. package/infrastructure/domains/shared/types/discovery-result.js +106 -0
  128. package/infrastructure/domains/shared/types/discovery-result.test.js +258 -0
  129. package/infrastructure/domains/shared/types/index.js +46 -0
  130. package/infrastructure/domains/shared/types/resource-ownership.js +108 -0
  131. package/infrastructure/domains/shared/types/resource-ownership.test.js +101 -0
  132. package/infrastructure/domains/shared/utilities/base-definition-factory.js +380 -0
  133. package/infrastructure/domains/shared/utilities/base-definition-factory.js.bak +338 -0
  134. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +248 -0
  135. package/infrastructure/domains/shared/utilities/handler-path-resolver.js +134 -0
  136. package/infrastructure/domains/shared/utilities/handler-path-resolver.test.js +268 -0
  137. package/infrastructure/domains/shared/utilities/prisma-layer-manager.js +55 -0
  138. package/infrastructure/domains/shared/utilities/prisma-layer-manager.test.js +138 -0
  139. package/infrastructure/{env-validator.js → domains/shared/validation/env-validator.js} +2 -1
  140. package/infrastructure/domains/shared/validation/env-validator.test.js +173 -0
  141. package/infrastructure/esbuild.config.js +53 -0
  142. package/infrastructure/infrastructure-composer.js +87 -0
  143. package/infrastructure/{serverless-template.test.js → infrastructure-composer.test.js} +115 -24
  144. package/infrastructure/scripts/build-prisma-layer.js +553 -0
  145. package/infrastructure/scripts/build-prisma-layer.test.js +102 -0
  146. package/infrastructure/{build-time-discovery.js → scripts/build-time-discovery.js} +80 -48
  147. package/infrastructure/{build-time-discovery.test.js → scripts/build-time-discovery.test.js} +5 -4
  148. package/layers/prisma/nodejs/package.json +8 -0
  149. package/management-ui/server/utils/cliIntegration.js +1 -1
  150. package/management-ui/server/utils/environment/awsParameterStore.js +29 -18
  151. package/package.json +11 -11
  152. package/frigg-cli/.eslintrc.js +0 -141
  153. package/frigg-cli/__tests__/unit/commands/build.test.js +0 -251
  154. package/frigg-cli/__tests__/unit/commands/db-setup.test.js +0 -548
  155. package/frigg-cli/__tests__/unit/commands/install.test.js +0 -400
  156. package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -346
  157. package/frigg-cli/__tests__/unit/utils/database-validator.test.js +0 -366
  158. package/frigg-cli/__tests__/unit/utils/error-messages.test.js +0 -304
  159. package/frigg-cli/__tests__/unit/utils/prisma-runner.test.js +0 -486
  160. package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
  161. package/frigg-cli/__tests__/utils/prisma-mock.js +0 -194
  162. package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
  163. package/frigg-cli/__tests__/utils/test-setup.js +0 -287
  164. package/frigg-cli/build-command/index.js +0 -65
  165. package/frigg-cli/db-setup-command/index.js +0 -193
  166. package/frigg-cli/deploy-command/index.js +0 -175
  167. package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -301
  168. package/frigg-cli/generate-command/azure-generator.js +0 -43
  169. package/frigg-cli/generate-command/gcp-generator.js +0 -47
  170. package/frigg-cli/generate-command/index.js +0 -332
  171. package/frigg-cli/generate-command/terraform-generator.js +0 -555
  172. package/frigg-cli/generate-iam-command.js +0 -118
  173. package/frigg-cli/index.js +0 -75
  174. package/frigg-cli/index.test.js +0 -158
  175. package/frigg-cli/init-command/backend-first-handler.js +0 -756
  176. package/frigg-cli/init-command/index.js +0 -93
  177. package/frigg-cli/init-command/template-handler.js +0 -143
  178. package/frigg-cli/install-command/backend-js.js +0 -33
  179. package/frigg-cli/install-command/commit-changes.js +0 -16
  180. package/frigg-cli/install-command/environment-variables.js +0 -127
  181. package/frigg-cli/install-command/environment-variables.test.js +0 -136
  182. package/frigg-cli/install-command/index.js +0 -54
  183. package/frigg-cli/install-command/install-package.js +0 -13
  184. package/frigg-cli/install-command/integration-file.js +0 -30
  185. package/frigg-cli/install-command/logger.js +0 -12
  186. package/frigg-cli/install-command/template.js +0 -90
  187. package/frigg-cli/install-command/validate-package.js +0 -75
  188. package/frigg-cli/jest.config.js +0 -124
  189. package/frigg-cli/package.json +0 -54
  190. package/frigg-cli/start-command/index.js +0 -149
  191. package/frigg-cli/start-command/start-command.test.js +0 -297
  192. package/frigg-cli/test/init-command.test.js +0 -180
  193. package/frigg-cli/test/npm-registry.test.js +0 -319
  194. package/frigg-cli/ui-command/index.js +0 -154
  195. package/frigg-cli/utils/app-resolver.js +0 -319
  196. package/frigg-cli/utils/backend-path.js +0 -25
  197. package/frigg-cli/utils/database-validator.js +0 -161
  198. package/frigg-cli/utils/error-messages.js +0 -257
  199. package/frigg-cli/utils/npm-registry.js +0 -167
  200. package/frigg-cli/utils/prisma-runner.js +0 -280
  201. package/frigg-cli/utils/process-manager.js +0 -199
  202. package/frigg-cli/utils/repo-detection.js +0 -405
  203. package/infrastructure/aws-discovery.js +0 -1176
  204. package/infrastructure/aws-discovery.test.js +0 -1220
  205. package/infrastructure/serverless-template.js +0 -2074
  206. /package/infrastructure/{WEBSOCKET-CONFIGURATION.md → docs/WEBSOCKET-CONFIGURATION.md} +0 -0
  207. /package/infrastructure/{GENERATE-IAM-DOCS.md → docs/generate-iam-command.md} +0 -0
  208. /package/infrastructure/{iam-generator.test.js → domains/security/iam-generator.test.js} +0 -0
  209. /package/infrastructure/{frigg-deployment-iam-stack.yaml → domains/security/templates/frigg-deployment-iam-stack.yaml} +0 -0
  210. /package/infrastructure/{iam-policy-basic.json → domains/security/templates/iam-policy-basic.json} +0 -0
  211. /package/infrastructure/{iam-policy-full.json → domains/security/templates/iam-policy-full.json} +0 -0
  212. /package/infrastructure/{run-discovery.js → scripts/run-discovery.js} +0 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Environment Builder Service
3
+ *
4
+ * Domain Service - Hexagonal Architecture
5
+ *
6
+ * Builds Lambda environment variable configuration from:
7
+ * 1. AppDefinition environment flags
8
+ * 2. Discovered AWS resources (VPC IDs, KMS keys, etc.)
9
+ * 3. Generated resource references
10
+ */
11
+
12
+ /**
13
+ * Get environment variables from AppDefinition
14
+ *
15
+ * Extracts environment variable definitions where value is true,
16
+ * and creates Serverless variable references.
17
+ *
18
+ * @param {Object} appDefinition - Application definition
19
+ * @returns {Object} Environment variable mappings
20
+ */
21
+ function getAppEnvironmentVars(appDefinition) {
22
+ const envVars = {};
23
+ const reservedVars = new Set([
24
+ '_HANDLER',
25
+ '_X_AMZN_TRACE_ID',
26
+ 'AWS_DEFAULT_REGION',
27
+ 'AWS_EXECUTION_ENV',
28
+ 'AWS_REGION',
29
+ 'AWS_LAMBDA_FUNCTION_NAME',
30
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE',
31
+ 'AWS_LAMBDA_FUNCTION_VERSION',
32
+ 'AWS_LAMBDA_INITIALIZATION_TYPE',
33
+ 'AWS_LAMBDA_LOG_GROUP_NAME',
34
+ 'AWS_LAMBDA_LOG_STREAM_NAME',
35
+ 'AWS_ACCESS_KEY',
36
+ 'AWS_ACCESS_KEY_ID',
37
+ 'AWS_SECRET_ACCESS_KEY',
38
+ 'AWS_SESSION_TOKEN',
39
+ ]);
40
+
41
+ if (!appDefinition.environment) {
42
+ return envVars;
43
+ }
44
+
45
+ console.log('📋 Loading environment variables from appDefinition...');
46
+ const envKeys = [];
47
+ const skippedKeys = [];
48
+
49
+ for (const [key, value] of Object.entries(appDefinition.environment)) {
50
+ if (value !== true) continue;
51
+ if (reservedVars.has(key)) {
52
+ skippedKeys.push(key);
53
+ continue;
54
+ }
55
+ envVars[key] = `\${env:${key}, ''}`;
56
+ envKeys.push(key);
57
+ }
58
+
59
+ if (envKeys.length > 0) {
60
+ console.log(
61
+ ` Found ${envKeys.length} environment variables: ${envKeys.join(
62
+ ', '
63
+ )}`
64
+ );
65
+ }
66
+ if (skippedKeys.length > 0) {
67
+ console.log(
68
+ ` ⚠️ Skipped ${skippedKeys.length
69
+ } reserved AWS Lambda variables: ${skippedKeys.join(', ')}`
70
+ );
71
+ }
72
+
73
+ return envVars;
74
+ }
75
+
76
+ /**
77
+ * Build complete environment configuration for Lambda functions
78
+ *
79
+ * Combines app environment vars with discovered AWS resource references
80
+ *
81
+ * @param {Object} appEnvironmentVars - Environment vars from AppDefinition
82
+ * @param {Object} discoveredResources - Discovered AWS resources
83
+ * @returns {Object} Complete environment configuration
84
+ */
85
+ function buildEnvironment(appEnvironmentVars, discoveredResources) {
86
+ const environment = {
87
+ ...appEnvironmentVars,
88
+ STAGE: '${self:provider.stage}', // Used by encryption bypass logic
89
+ FRIGG_STACK: '${self:service}',
90
+ FRIGG_STAGE: '${self:provider.stage}',
91
+ FRIGG_REGION: '${self:provider.region}',
92
+ };
93
+
94
+ // Add KMS key if discovered or created
95
+ if (discoveredResources.kmsKeyId) {
96
+ environment.KMS_KEY_ARN = discoveredResources.kmsKeyId;
97
+ } else if (discoveredResources.kmsKeyArn) {
98
+ environment.KMS_KEY_ARN = discoveredResources.kmsKeyArn;
99
+ }
100
+
101
+ // Add database connection info if discovered
102
+ if (discoveredResources.auroraClusterEndpoint) {
103
+ environment.DATABASE_HOST = discoveredResources.auroraClusterEndpoint;
104
+ environment.DATABASE_PORT = String(discoveredResources.auroraPort || 5432);
105
+ }
106
+
107
+ // Add secrets manager secret ARN if discovered
108
+ if (discoveredResources.databaseSecretArn) {
109
+ environment.DATABASE_SECRET_ARN = discoveredResources.databaseSecretArn;
110
+ }
111
+
112
+ return environment;
113
+ }
114
+
115
+ module.exports = {
116
+ getAppEnvironmentVars,
117
+ buildEnvironment,
118
+ };
119
+
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Tests for Environment Builder Service
3
+ *
4
+ * Tests environment variable extraction and building
5
+ */
6
+
7
+ const { getAppEnvironmentVars, buildEnvironment } = require('./environment-builder');
8
+
9
+ describe('Environment Builder', () => {
10
+ describe('getAppEnvironmentVars()', () => {
11
+ it('should extract environment variables with value true', () => {
12
+ const appDefinition = {
13
+ environment: {
14
+ API_KEY: true,
15
+ DATABASE_URL: true,
16
+ CUSTOM_VAR: true,
17
+ },
18
+ };
19
+
20
+ const result = getAppEnvironmentVars(appDefinition);
21
+
22
+ expect(result.API_KEY).toBe("${env:API_KEY, ''}");
23
+ expect(result.DATABASE_URL).toBe("${env:DATABASE_URL, ''}");
24
+ expect(result.CUSTOM_VAR).toBe("${env:CUSTOM_VAR, ''}");
25
+ });
26
+
27
+ it('should ignore environment variables with value false', () => {
28
+ const appDefinition = {
29
+ environment: {
30
+ ENABLED_VAR: true,
31
+ DISABLED_VAR: false,
32
+ },
33
+ };
34
+
35
+ const result = getAppEnvironmentVars(appDefinition);
36
+
37
+ expect(result.ENABLED_VAR).toBeDefined();
38
+ expect(result.DISABLED_VAR).toBeUndefined();
39
+ });
40
+
41
+ it('should ignore environment variables with non-boolean values', () => {
42
+ const appDefinition = {
43
+ environment: {
44
+ VALID: true,
45
+ STRING_VALUE: 'some-value',
46
+ NUMBER_VALUE: 123,
47
+ },
48
+ };
49
+
50
+ const result = getAppEnvironmentVars(appDefinition);
51
+
52
+ expect(result.VALID).toBeDefined();
53
+ expect(result.STRING_VALUE).toBeUndefined();
54
+ expect(result.NUMBER_VALUE).toBeUndefined();
55
+ });
56
+
57
+ it('should skip reserved AWS Lambda variables', () => {
58
+ const appDefinition = {
59
+ environment: {
60
+ CUSTOM_VAR: true,
61
+ AWS_REGION: true,
62
+ AWS_ACCESS_KEY_ID: true,
63
+ AWS_SECRET_ACCESS_KEY: true,
64
+ _HANDLER: true,
65
+ AWS_LAMBDA_FUNCTION_NAME: true,
66
+ },
67
+ };
68
+
69
+ const result = getAppEnvironmentVars(appDefinition);
70
+
71
+ expect(result.CUSTOM_VAR).toBeDefined();
72
+ expect(result.AWS_REGION).toBeUndefined();
73
+ expect(result.AWS_ACCESS_KEY_ID).toBeUndefined();
74
+ expect(result.AWS_SECRET_ACCESS_KEY).toBeUndefined();
75
+ expect(result._HANDLER).toBeUndefined();
76
+ expect(result.AWS_LAMBDA_FUNCTION_NAME).toBeUndefined();
77
+ });
78
+
79
+ it('should return empty object if no environment defined', () => {
80
+ const appDefinition = {};
81
+
82
+ const result = getAppEnvironmentVars(appDefinition);
83
+
84
+ expect(result).toEqual({});
85
+ });
86
+
87
+ it('should handle empty environment object', () => {
88
+ const appDefinition = {
89
+ environment: {},
90
+ };
91
+
92
+ const result = getAppEnvironmentVars(appDefinition);
93
+
94
+ expect(result).toEqual({});
95
+ });
96
+
97
+ it('should create serverless variable references', () => {
98
+ const appDefinition = {
99
+ environment: {
100
+ MY_VAR: true,
101
+ },
102
+ };
103
+
104
+ const result = getAppEnvironmentVars(appDefinition);
105
+
106
+ // Should use serverless variable syntax with empty string fallback
107
+ expect(result.MY_VAR).toBe("${env:MY_VAR, ''}");
108
+ });
109
+ });
110
+
111
+ describe('buildEnvironment()', () => {
112
+ it('should combine app vars with standard Frigg variables', () => {
113
+ const appEnvironmentVars = {
114
+ API_KEY: "${env:API_KEY, ''}",
115
+ };
116
+ const discoveredResources = {};
117
+
118
+ const result = buildEnvironment(appEnvironmentVars, discoveredResources);
119
+
120
+ expect(result.API_KEY).toBe("${env:API_KEY, ''}");
121
+ expect(result.STAGE).toBe('${self:provider.stage}');
122
+ expect(result.FRIGG_STACK).toBe('${self:service}');
123
+ expect(result.FRIGG_STAGE).toBe('${self:provider.stage}');
124
+ expect(result.FRIGG_REGION).toBe('${self:provider.region}');
125
+ });
126
+
127
+ it('should add KMS key ARN if discovered', () => {
128
+ const appEnvironmentVars = {};
129
+ const discoveredResources = {
130
+ kmsKeyId: 'arn:aws:kms:us-east-1:123456:key/abc-123',
131
+ };
132
+
133
+ const result = buildEnvironment(appEnvironmentVars, discoveredResources);
134
+
135
+ expect(result.KMS_KEY_ARN).toBe('arn:aws:kms:us-east-1:123456:key/abc-123');
136
+ });
137
+
138
+ it('should prefer kmsKeyId over kmsKeyArn if both present', () => {
139
+ const appEnvironmentVars = {};
140
+ const discoveredResources = {
141
+ kmsKeyId: 'arn:aws:kms:us-east-1:123456:key/primary',
142
+ kmsKeyArn: 'arn:aws:kms:us-east-1:123456:key/secondary',
143
+ };
144
+
145
+ const result = buildEnvironment(appEnvironmentVars, discoveredResources);
146
+
147
+ // Implementation uses if/else-if, so kmsKeyId takes priority
148
+ expect(result.KMS_KEY_ARN).toBe('arn:aws:kms:us-east-1:123456:key/primary');
149
+ });
150
+
151
+ it('should add database connection info if discovered', () => {
152
+ const appEnvironmentVars = {};
153
+ const discoveredResources = {
154
+ auroraClusterEndpoint: 'cluster.abc.us-east-1.rds.amazonaws.com',
155
+ auroraPort: 5432,
156
+ };
157
+
158
+ const result = buildEnvironment(appEnvironmentVars, discoveredResources);
159
+
160
+ expect(result.DATABASE_HOST).toBe('cluster.abc.us-east-1.rds.amazonaws.com');
161
+ expect(result.DATABASE_PORT).toBe('5432');
162
+ });
163
+
164
+ it('should default database port to 5432 if not specified', () => {
165
+ const appEnvironmentVars = {};
166
+ const discoveredResources = {
167
+ auroraClusterEndpoint: 'cluster.example.com',
168
+ };
169
+
170
+ const result = buildEnvironment(appEnvironmentVars, discoveredResources);
171
+
172
+ expect(result.DATABASE_HOST).toBe('cluster.example.com');
173
+ expect(result.DATABASE_PORT).toBe('5432');
174
+ });
175
+
176
+ it('should add database secret ARN if discovered', () => {
177
+ const appEnvironmentVars = {};
178
+ const discoveredResources = {
179
+ databaseSecretArn: 'arn:aws:secretsmanager:us-east-1:123456:secret:db-secret',
180
+ };
181
+
182
+ const result = buildEnvironment(appEnvironmentVars, discoveredResources);
183
+
184
+ expect(result.DATABASE_SECRET_ARN).toBe('arn:aws:secretsmanager:us-east-1:123456:secret:db-secret');
185
+ });
186
+
187
+ it('should combine all discovered resources', () => {
188
+ const appEnvironmentVars = {
189
+ CUSTOM_VAR: "${env:CUSTOM_VAR, ''}",
190
+ };
191
+ const discoveredResources = {
192
+ kmsKeyArn: 'arn:aws:kms:us-east-1:123456:key/abc',
193
+ auroraClusterEndpoint: 'db.example.com',
194
+ auroraPort: 3306,
195
+ databaseSecretArn: 'arn:aws:secretsmanager:us-east-1:123456:secret:db',
196
+ };
197
+
198
+ const result = buildEnvironment(appEnvironmentVars, discoveredResources);
199
+
200
+ expect(result.CUSTOM_VAR).toBe("${env:CUSTOM_VAR, ''}");
201
+ expect(result.FRIGG_STACK).toBe('${self:service}');
202
+ expect(result.FRIGG_STAGE).toBe('${self:provider.stage}');
203
+ expect(result.FRIGG_REGION).toBe('${self:provider.region}');
204
+ expect(result.KMS_KEY_ARN).toBe('arn:aws:kms:us-east-1:123456:key/abc');
205
+ expect(result.DATABASE_HOST).toBe('db.example.com');
206
+ expect(result.DATABASE_PORT).toBe('3306');
207
+ expect(result.DATABASE_SECRET_ARN).toBe('arn:aws:secretsmanager:us-east-1:123456:secret:db');
208
+ });
209
+
210
+ it('should handle empty discoveredResources', () => {
211
+ const appEnvironmentVars = {
212
+ API_KEY: "${env:API_KEY, ''}",
213
+ };
214
+ const discoveredResources = {};
215
+
216
+ const result = buildEnvironment(appEnvironmentVars, discoveredResources);
217
+
218
+ expect(result.API_KEY).toBe("${env:API_KEY, ''}");
219
+ expect(result.FRIGG_STACK).toBe('${self:service}');
220
+ expect(result.KMS_KEY_ARN).toBeUndefined();
221
+ expect(result.DATABASE_HOST).toBeUndefined();
222
+ });
223
+
224
+ it('should handle empty discoveredResources gracefully', () => {
225
+ const appEnvironmentVars = {};
226
+
227
+ const result = buildEnvironment(appEnvironmentVars, {});
228
+
229
+ expect(result.FRIGG_STACK).toBe('${self:service}');
230
+ expect(result.KMS_KEY_ARN).toBeUndefined();
231
+ });
232
+
233
+ it('should convert database port to string', () => {
234
+ const appEnvironmentVars = {};
235
+ const discoveredResources = {
236
+ auroraClusterEndpoint: 'db.example.com',
237
+ auroraPort: 3306, // Number
238
+ };
239
+
240
+ const result = buildEnvironment(appEnvironmentVars, discoveredResources);
241
+
242
+ expect(result.DATABASE_PORT).toBe('3306'); // String
243
+ expect(typeof result.DATABASE_PORT).toBe('string');
244
+ });
245
+ });
246
+ });
247
+