@friggframework/devtools 2.0.0-next.45 → 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 -2094
  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
@@ -1,366 +0,0 @@
1
- // Mock dependencies BEFORE importing database-validator
2
- jest.mock('@friggframework/core/database/config', () => ({
3
- getDatabaseType: jest.fn()
4
- }));
5
-
6
- jest.mock('@friggframework/core/database/prisma', () => ({
7
- connectPrisma: jest.fn(),
8
- disconnectPrisma: jest.fn()
9
- }));
10
-
11
- const {
12
- validateDatabaseUrl,
13
- getDatabaseType,
14
- testDatabaseConnection,
15
- checkPrismaClientGenerated
16
- } = require('../../../utils/database-validator');
17
- const {
18
- createMockPrismaClient,
19
- createPrismaError,
20
- PrismaErrors
21
- } = require('../../utils/prisma-mock');
22
-
23
- const { getDatabaseType: getDatabaseTypeFromCore } = require('@friggframework/core/database/config');
24
- const { connectPrisma, disconnectPrisma } = require('@friggframework/core/database/prisma');
25
-
26
- describe('Database Validator Utility', () => {
27
- beforeEach(() => {
28
- jest.clearAllMocks();
29
- delete process.env.DATABASE_URL;
30
- });
31
-
32
- afterEach(() => {
33
- delete process.env.DATABASE_URL;
34
- });
35
-
36
- describe('validateDatabaseUrl()', () => {
37
- it('should return valid when DATABASE_URL exists with value', () => {
38
- process.env.DATABASE_URL = 'mongodb://localhost:27017/test';
39
-
40
- const result = validateDatabaseUrl();
41
-
42
- expect(result.valid).toBe(true);
43
- expect(result.url).toBe('mongodb://localhost:27017/test');
44
- expect(result.error).toBeUndefined();
45
- });
46
-
47
- it('should return error when DATABASE_URL is undefined', () => {
48
- delete process.env.DATABASE_URL;
49
-
50
- const result = validateDatabaseUrl();
51
-
52
- expect(result.valid).toBe(false);
53
- expect(result.error).toBe('DATABASE_URL environment variable not found');
54
- expect(result.url).toBeUndefined();
55
- });
56
-
57
- it('should return error when DATABASE_URL is empty string', () => {
58
- // Set to empty string explicitly
59
- process.env.DATABASE_URL = '';
60
-
61
- const result = validateDatabaseUrl();
62
-
63
- expect(result.valid).toBe(false);
64
- // Node.js treats empty string env vars as undefined in some contexts
65
- expect(result.error).toMatch(/DATABASE_URL environment variable (is empty|not found)/);
66
- });
67
-
68
- it('should return error when DATABASE_URL contains only whitespace', () => {
69
- process.env.DATABASE_URL = ' ';
70
-
71
- const result = validateDatabaseUrl();
72
-
73
- expect(result.valid).toBe(false);
74
- expect(result.error).toBe('DATABASE_URL environment variable is empty');
75
- });
76
-
77
- it('should accept valid MongoDB connection strings', () => {
78
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg?replicaSet=rs0';
79
-
80
- const result = validateDatabaseUrl();
81
-
82
- expect(result.valid).toBe(true);
83
- expect(result.url).toContain('mongodb://');
84
- });
85
-
86
- it('should accept valid PostgreSQL connection strings', () => {
87
- process.env.DATABASE_URL = 'postgresql://postgres:pass@localhost:5432/frigg';
88
-
89
- const result = validateDatabaseUrl();
90
-
91
- expect(result.valid).toBe(true);
92
- expect(result.url).toContain('postgresql://');
93
- });
94
- });
95
-
96
- describe('getDatabaseType()', () => {
97
- it('should return postgresql when core returns postgresql', () => {
98
- getDatabaseTypeFromCore.mockReturnValue('postgresql');
99
-
100
- const result = getDatabaseType();
101
-
102
- expect(result.dbType).toBe('postgresql');
103
- expect(result.error).toBeUndefined();
104
- expect(getDatabaseTypeFromCore).toHaveBeenCalled();
105
- });
106
-
107
- it('should return mongodb when core returns mongodb', () => {
108
- getDatabaseTypeFromCore.mockReturnValue('mongodb');
109
-
110
- const result = getDatabaseType();
111
-
112
- expect(result.dbType).toBe('mongodb');
113
- expect(result.error).toBeUndefined();
114
- });
115
-
116
- it('should return error when core throws error', () => {
117
- getDatabaseTypeFromCore.mockImplementation(() => {
118
- throw new Error('[Frigg] Database not configured');
119
- });
120
-
121
- const result = getDatabaseType();
122
-
123
- expect(result.dbType).toBeUndefined();
124
- expect(result.error).toBe('Database not configured');
125
- });
126
-
127
- it('should strip [Frigg] prefix from error messages', () => {
128
- getDatabaseTypeFromCore.mockImplementation(() => {
129
- throw new Error('[Frigg] No database enabled');
130
- });
131
-
132
- const result = getDatabaseType();
133
-
134
- expect(result.error).toBe('No database enabled');
135
- expect(result.error).not.toContain('[Frigg]');
136
- });
137
-
138
- it('should handle errors without [Frigg] prefix', () => {
139
- getDatabaseTypeFromCore.mockImplementation(() => {
140
- throw new Error('Custom error message');
141
- });
142
-
143
- const result = getDatabaseType();
144
-
145
- expect(result.error).toBe('Custom error message');
146
- });
147
-
148
- it('should handle complex error messages', () => {
149
- getDatabaseTypeFromCore.mockImplementation(() => {
150
- throw new Error('[Frigg] App definition missing database configuration');
151
- });
152
-
153
- const result = getDatabaseType();
154
-
155
- expect(result.error).toContain('App definition');
156
- expect(result.error).not.toContain('[Frigg]');
157
- });
158
- });
159
-
160
- describe('testDatabaseConnection()', () => {
161
- let mockClient;
162
-
163
- beforeEach(() => {
164
- mockClient = createMockPrismaClient();
165
- connectPrisma.mockResolvedValue(mockClient);
166
- disconnectPrisma.mockResolvedValue(undefined);
167
- });
168
-
169
- it('should connect successfully to MongoDB and use $runCommandRaw', async () => {
170
- const result = await testDatabaseConnection('mongodb://localhost', 'mongodb');
171
-
172
- expect(result.connected).toBe(true);
173
- expect(result.error).toBeUndefined();
174
- expect(connectPrisma).toHaveBeenCalled();
175
- expect(mockClient.$runCommandRaw).toHaveBeenCalledWith({ ping: 1 });
176
- expect(mockClient.$queryRaw).not.toHaveBeenCalled(); // MongoDB doesn't use SQL
177
- expect(disconnectPrisma).toHaveBeenCalled();
178
- });
179
-
180
- it('should connect successfully to PostgreSQL and use $queryRaw', async () => {
181
- const result = await testDatabaseConnection('postgresql://localhost', 'postgresql');
182
-
183
- expect(result.connected).toBe(true);
184
- expect(result.error).toBeUndefined();
185
- expect(connectPrisma).toHaveBeenCalled();
186
- expect(mockClient.$queryRaw).toHaveBeenCalled();
187
- expect(mockClient.$runCommandRaw).not.toHaveBeenCalled(); // PostgreSQL doesn't use Mongo commands
188
- expect(disconnectPrisma).toHaveBeenCalled();
189
- });
190
-
191
- it('should handle connection timeout', async () => {
192
- connectPrisma.mockImplementation(() =>
193
- new Promise((resolve) => setTimeout(resolve, 10000))
194
- );
195
-
196
- const result = await testDatabaseConnection('mongodb://localhost', 'mongodb', 100);
197
-
198
- expect(result.connected).toBe(false);
199
- expect(result.error).toBe('Connection timeout');
200
- });
201
-
202
- it('should handle connection errors', async () => {
203
- const error = createPrismaError('CONNECTION_ERROR');
204
- connectPrisma.mockRejectedValue(error);
205
-
206
- const result = await testDatabaseConnection('mongodb://localhost', 'mongodb');
207
-
208
- expect(result.connected).toBe(false);
209
- expect(result.error).toContain('reach database server');
210
- });
211
-
212
- it('should handle authentication errors', async () => {
213
- const error = createPrismaError('AUTH_ERROR');
214
- connectPrisma.mockRejectedValue(error);
215
-
216
- const result = await testDatabaseConnection('postgresql://localhost', 'postgresql');
217
-
218
- expect(result.connected).toBe(false);
219
- expect(result.error).toBeDefined();
220
- });
221
-
222
- it('should handle database not found errors', async () => {
223
- const error = createPrismaError('DATABASE_NOT_FOUND');
224
- connectPrisma.mockRejectedValue(error);
225
-
226
- const result = await testDatabaseConnection('mongodb://localhost', 'mongodb');
227
-
228
- expect(result.connected).toBe(false);
229
- expect(result.error).toContain('does not exist');
230
- });
231
-
232
- it('should handle MongoDB command execution errors', async () => {
233
- mockClient.$runCommandRaw.mockRejectedValue(new Error('Ping failed'));
234
-
235
- const result = await testDatabaseConnection('mongodb://localhost', 'mongodb');
236
-
237
- expect(result.connected).toBe(false);
238
- expect(result.error).toBe('Ping failed');
239
- });
240
-
241
- it('should handle PostgreSQL query execution errors', async () => {
242
- mockClient.$queryRaw.mockRejectedValue(new Error('Query failed'));
243
-
244
- const result = await testDatabaseConnection('postgresql://localhost', 'postgresql');
245
-
246
- expect(result.connected).toBe(false);
247
- expect(result.error).toBe('Query failed');
248
- });
249
-
250
- it('should disconnect even after successful test', async () => {
251
- await testDatabaseConnection('mongodb://localhost', 'mongodb');
252
-
253
- expect(disconnectPrisma).toHaveBeenCalled();
254
- });
255
-
256
- it('should handle disconnect errors gracefully', async () => {
257
- // Set up successful connection but failing disconnect
258
- mockClient.$runCommandRaw.mockResolvedValue({ ok: 1 });
259
- disconnectPrisma.mockRejectedValue(new Error('Disconnect failed'));
260
-
261
- const result = await testDatabaseConnection('mongodb://localhost', 'mongodb');
262
-
263
- // Should still report success despite disconnect error
264
- // Note: Current implementation returns error if ANY exception occurs
265
- // This is actually safer behavior, so we accept connected: false
266
- expect(result.connected).toBe(false);
267
- expect(result.error).toContain('Disconnect failed');
268
- });
269
-
270
- it('should attempt disconnect even when connection fails', async () => {
271
- connectPrisma.mockRejectedValue(new Error('Connection failed'));
272
-
273
- await testDatabaseConnection('mongodb://localhost', 'mongodb');
274
-
275
- expect(disconnectPrisma).toHaveBeenCalled();
276
- });
277
-
278
- it('should respect custom timeout values', async () => {
279
- connectPrisma.mockImplementation(() =>
280
- new Promise((resolve) => setTimeout(resolve, 500))
281
- );
282
-
283
- const result = await testDatabaseConnection('mongodb://localhost', 'mongodb', 100);
284
-
285
- expect(result.connected).toBe(false);
286
- expect(result.error).toBe('Connection timeout');
287
- });
288
-
289
- it('should use default timeout when not specified', async () => {
290
- // Mock a slow connection that takes 6 seconds
291
- connectPrisma.mockImplementation(() =>
292
- new Promise((resolve) => setTimeout(() => resolve(mockClient), 6000))
293
- );
294
-
295
- const result = await testDatabaseConnection('mongodb://localhost', 'mongodb');
296
-
297
- expect(result.connected).toBe(false);
298
- expect(result.error).toBe('Connection timeout');
299
- }, 10000); // Increase timeout to 10 seconds for this test
300
- });
301
-
302
- describe('checkPrismaClientGenerated()', () => {
303
- // Note: Testing require.resolve behavior requires integration tests with real packages
304
- // These unit tests focus on error handling and package name selection
305
-
306
- it('should use correct package name for MongoDB', () => {
307
- // When MongoDB client doesn't exist, error message reveals the package name used
308
- const result = checkPrismaClientGenerated('mongodb', '/nonexistent/path');
309
-
310
- expect(result.generated).toBe(false);
311
- expect(result.error).toContain('@prisma-mongodb/client');
312
- });
313
-
314
- it('should use correct package name for PostgreSQL', () => {
315
- // When PostgreSQL client doesn't exist, error message reveals the package name used
316
- const result = checkPrismaClientGenerated('postgresql', '/nonexistent/path');
317
-
318
- expect(result.generated).toBe(false);
319
- expect(result.error).toContain('@prisma-postgresql/client');
320
- });
321
-
322
- it('should return error when MongoDB client not found', () => {
323
- const result = checkPrismaClientGenerated('mongodb', '/nonexistent/path');
324
-
325
- expect(result.generated).toBe(false);
326
- expect(result.error).toBeDefined();
327
- expect(result.error).toContain('not found');
328
- expect(result.error).toContain('@prisma-mongodb/client');
329
- expect(result.error).toContain('frigg db:setup');
330
- });
331
-
332
- it('should return error when PostgreSQL client not found', () => {
333
- const result = checkPrismaClientGenerated('postgresql', '/nonexistent/path');
334
-
335
- expect(result.generated).toBe(false);
336
- expect(result.error).toBeDefined();
337
- expect(result.error).toContain('not found');
338
- expect(result.error).toContain('@prisma-postgresql/client');
339
- expect(result.error).toContain('frigg db:setup');
340
- });
341
-
342
- it('should provide helpful error message suggesting db:setup command', () => {
343
- const result = checkPrismaClientGenerated('mongodb', '/nonexistent/path');
344
-
345
- expect(result.error).toContain('frigg db:setup');
346
- });
347
-
348
- it('should use process.cwd() by default when no project root specified', () => {
349
- // We can't easily mock require.resolve, but we can verify it doesn't throw
350
- // when called without projectRoot parameter
351
- expect(() => {
352
- checkPrismaClientGenerated('mongodb');
353
- }).not.toThrow();
354
- });
355
-
356
- it('should accept custom project root parameter', () => {
357
- // Verify custom project root doesn't cause runtime errors
358
- const customRoot = '/custom/project/root';
359
- const result = checkPrismaClientGenerated('mongodb', customRoot);
360
-
361
- // Should return an error result, not throw
362
- expect(result).toHaveProperty('generated');
363
- expect(result.generated).toBe(false);
364
- });
365
- });
366
- });
@@ -1,304 +0,0 @@
1
- const {
2
- DATABASE_URL_EXAMPLES,
3
- getDatabaseUrlMissingError,
4
- getDatabaseTypeNotConfiguredError,
5
- getDatabaseConnectionError,
6
- getPrismaClientNotGeneratedError,
7
- getPrismaCommandError,
8
- getDatabaseSetupSuccess
9
- } = require('../../../utils/error-messages');
10
-
11
- describe('Error Messages Utility', () => {
12
- describe('DATABASE_URL_EXAMPLES', () => {
13
- it('should include MongoDB connection string example', () => {
14
- expect(DATABASE_URL_EXAMPLES.mongodb).toBeDefined();
15
- expect(DATABASE_URL_EXAMPLES.mongodb).toContain('mongodb://');
16
- expect(DATABASE_URL_EXAMPLES.mongodb).toContain('replicaSet=rs0');
17
- });
18
-
19
- it('should include PostgreSQL connection string example', () => {
20
- expect(DATABASE_URL_EXAMPLES.postgresql).toBeDefined();
21
- expect(DATABASE_URL_EXAMPLES.postgresql).toContain('postgresql://');
22
- expect(DATABASE_URL_EXAMPLES.postgresql).toContain('schema=public');
23
- });
24
- });
25
-
26
- describe('getDatabaseUrlMissingError()', () => {
27
- it('should return formatted error message', () => {
28
- const message = getDatabaseUrlMissingError();
29
-
30
- expect(message).toBeTruthy();
31
- expect(typeof message).toBe('string');
32
- });
33
-
34
- it('should include both database type examples', () => {
35
- const message = getDatabaseUrlMissingError();
36
-
37
- expect(message).toContain('MongoDB');
38
- expect(message).toContain('PostgreSQL');
39
- });
40
-
41
- it('should include example connection strings', () => {
42
- const message = getDatabaseUrlMissingError();
43
-
44
- expect(message).toContain(DATABASE_URL_EXAMPLES.mongodb);
45
- expect(message).toContain(DATABASE_URL_EXAMPLES.postgresql);
46
- });
47
-
48
- it('should suggest running frigg db:setup', () => {
49
- const message = getDatabaseUrlMissingError();
50
-
51
- expect(message).toContain('frigg db:setup');
52
- });
53
-
54
- it('should mention .env file', () => {
55
- const message = getDatabaseUrlMissingError();
56
-
57
- expect(message).toContain('.env');
58
- });
59
- });
60
-
61
- describe('getDatabaseTypeNotConfiguredError()', () => {
62
- it('should return formatted error message', () => {
63
- const message = getDatabaseTypeNotConfiguredError();
64
-
65
- expect(message).toBeTruthy();
66
- expect(typeof message).toBe('string');
67
- });
68
-
69
- it('should include PostgreSQL configuration example', () => {
70
- const message = getDatabaseTypeNotConfiguredError();
71
-
72
- expect(message).toContain('postgres');
73
- expect(message).toContain('enable: true');
74
- });
75
-
76
- it('should include MongoDB configuration example', () => {
77
- const message = getDatabaseTypeNotConfiguredError();
78
-
79
- expect(message).toContain('mongoDB');
80
- expect(message).toContain('enable: true');
81
- });
82
-
83
- it('should include DocumentDB configuration example', () => {
84
- const message = getDatabaseTypeNotConfiguredError();
85
-
86
- expect(message).toContain('documentDB');
87
- expect(message).toContain('enable: true');
88
- });
89
-
90
- it('should mention app definition location', () => {
91
- const message = getDatabaseTypeNotConfiguredError();
92
-
93
- expect(message).toContain('backend/index.js');
94
- expect(message).toContain('index.js');
95
- });
96
- });
97
-
98
- describe('getDatabaseConnectionError()', () => {
99
- const mockError = 'Connection refused';
100
-
101
- it('should include error message for MongoDB', () => {
102
- const message = getDatabaseConnectionError(mockError, 'mongodb');
103
-
104
- expect(message).toContain(mockError);
105
- });
106
-
107
- it('should include error message for PostgreSQL', () => {
108
- const message = getDatabaseConnectionError(mockError, 'postgresql');
109
-
110
- expect(message).toContain(mockError);
111
- });
112
-
113
- it('should include MongoDB-specific troubleshooting for MongoDB', () => {
114
- const message = getDatabaseConnectionError(mockError, 'mongodb');
115
-
116
- expect(message).toContain('replica set');
117
- expect(message).toContain('rs.initiate');
118
- expect(message).toContain('mongosh');
119
- expect(message).toContain('27017');
120
- });
121
-
122
- it('should include PostgreSQL-specific troubleshooting for PostgreSQL', () => {
123
- const message = getDatabaseConnectionError(mockError, 'postgresql');
124
-
125
- expect(message).toContain('pg_hba.conf');
126
- expect(message).toContain('pg_isready');
127
- expect(message).toContain('psql');
128
- expect(message).toContain('5432');
129
- });
130
-
131
- it('should not include PostgreSQL troubleshooting for MongoDB', () => {
132
- const message = getDatabaseConnectionError(mockError, 'mongodb');
133
-
134
- expect(message).not.toContain('pg_hba.conf');
135
- expect(message).not.toContain('pg_isready');
136
- });
137
-
138
- it('should not include MongoDB troubleshooting for PostgreSQL', () => {
139
- const message = getDatabaseConnectionError(mockError, 'postgresql');
140
-
141
- expect(message).not.toContain('replica set');
142
- expect(message).not.toContain('rs.initiate');
143
- });
144
-
145
- it('should include general troubleshooting steps', () => {
146
- const messageMongo = getDatabaseConnectionError(mockError, 'mongodb');
147
- const messagePostgres = getDatabaseConnectionError(mockError, 'postgresql');
148
-
149
- expect(messageMongo).toContain('Troubleshooting');
150
- expect(messagePostgres).toContain('Troubleshooting');
151
- });
152
-
153
- it('should show DATABASE_URL when available', () => {
154
- process.env.DATABASE_URL = 'mongodb://test';
155
- const message = getDatabaseConnectionError(mockError, 'mongodb');
156
-
157
- expect(message).toContain('mongodb://test');
158
- delete process.env.DATABASE_URL;
159
- });
160
-
161
- it('should handle missing DATABASE_URL gracefully', () => {
162
- delete process.env.DATABASE_URL;
163
- const message = getDatabaseConnectionError(mockError, 'mongodb');
164
-
165
- expect(message).toContain('not set');
166
- });
167
- });
168
-
169
- describe('getPrismaClientNotGeneratedError()', () => {
170
- it('should return error message for MongoDB', () => {
171
- const message = getPrismaClientNotGeneratedError('mongodb');
172
-
173
- expect(message).toBeTruthy();
174
- expect(message).toContain('mongodb');
175
- });
176
-
177
- it('should return error message for PostgreSQL', () => {
178
- const message = getPrismaClientNotGeneratedError('postgresql');
179
-
180
- expect(message).toBeTruthy();
181
- expect(message).toContain('postgresql');
182
- });
183
-
184
- it('should include correct client package name for MongoDB', () => {
185
- const message = getPrismaClientNotGeneratedError('mongodb');
186
-
187
- expect(message).toContain('@prisma-mongodb/client');
188
- });
189
-
190
- it('should include correct client package name for PostgreSQL', () => {
191
- const message = getPrismaClientNotGeneratedError('postgresql');
192
-
193
- expect(message).toContain('@prisma-postgresql/client');
194
- });
195
-
196
- it('should suggest running frigg db:setup', () => {
197
- const message = getPrismaClientNotGeneratedError('mongodb');
198
-
199
- expect(message).toContain('frigg db:setup');
200
- });
201
-
202
- it('should explain what will happen when running db:setup', () => {
203
- const message = getPrismaClientNotGeneratedError('mongodb');
204
-
205
- expect(message).toContain('Generate the Prisma client');
206
- expect(message).toContain('Set up database schema');
207
- });
208
- });
209
-
210
- describe('getPrismaCommandError()', () => {
211
- const mockCommand = 'generate';
212
- const mockError = 'Schema validation failed';
213
-
214
- it('should include command name', () => {
215
- const message = getPrismaCommandError(mockCommand, mockError);
216
-
217
- expect(message).toContain('generate');
218
- });
219
-
220
- it('should include error message', () => {
221
- const message = getPrismaCommandError(mockCommand, mockError);
222
-
223
- expect(message).toContain(mockError);
224
- });
225
-
226
- it('should list common causes', () => {
227
- const message = getPrismaCommandError(mockCommand, mockError);
228
-
229
- expect(message).toContain('Common causes');
230
- expect(message).toContain('schema');
231
- });
232
-
233
- it('should suggest running frigg db:setup', () => {
234
- const message = getPrismaCommandError(mockCommand, mockError);
235
-
236
- expect(message).toContain('frigg db:setup');
237
- });
238
-
239
- it('should suggest checking DATABASE_URL', () => {
240
- const message = getPrismaCommandError(mockCommand, mockError);
241
-
242
- expect(message).toContain('DATABASE_URL');
243
- });
244
-
245
- it('should work with different command names', () => {
246
- const migrateMessage = getPrismaCommandError('migrate', mockError);
247
- const pushMessage = getPrismaCommandError('db push', mockError);
248
-
249
- expect(migrateMessage).toContain('migrate');
250
- expect(pushMessage).toContain('db push');
251
- });
252
- });
253
-
254
- describe('getDatabaseSetupSuccess()', () => {
255
- it('should include database type for MongoDB', () => {
256
- const message = getDatabaseSetupSuccess('mongodb', 'development');
257
-
258
- expect(message).toContain('mongodb');
259
- });
260
-
261
- it('should include database type for PostgreSQL', () => {
262
- const message = getDatabaseSetupSuccess('postgresql', 'production');
263
-
264
- expect(message).toContain('postgresql');
265
- });
266
-
267
- it('should include stage information', () => {
268
- const devMessage = getDatabaseSetupSuccess('mongodb', 'development');
269
- const prodMessage = getDatabaseSetupSuccess('postgresql', 'production');
270
-
271
- expect(devMessage).toContain('development');
272
- expect(prodMessage).toContain('production');
273
- });
274
-
275
- it('should mention different operations for MongoDB vs PostgreSQL', () => {
276
- const mongoMessage = getDatabaseSetupSuccess('mongodb', 'development');
277
- const postgresMessage = getDatabaseSetupSuccess('postgresql', 'development');
278
-
279
- expect(mongoMessage).toContain('Schema pushed');
280
- expect(postgresMessage).toContain('Migrations applied');
281
- });
282
-
283
- it('should suggest next steps', () => {
284
- const message = getDatabaseSetupSuccess('mongodb', 'development');
285
-
286
- expect(message).toContain('frigg start');
287
- expect(message).toContain('Next steps');
288
- });
289
-
290
- it('should confirm what happened during setup', () => {
291
- const message = getDatabaseSetupSuccess('mongodb', 'development');
292
-
293
- expect(message).toContain('Prisma client generated');
294
- expect(message).toContain('Database connection verified');
295
- });
296
-
297
- it('should show success indicators', () => {
298
- const message = getDatabaseSetupSuccess('mongodb', 'development');
299
-
300
- expect(message).toContain('successfully');
301
- expect(message).toContain('completed');
302
- });
303
- });
304
- });