@friggframework/devtools 2.0.0-next.47 → 2.0.0-next.48

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 (69) hide show
  1. package/frigg-cli/README.md +1290 -0
  2. package/frigg-cli/__tests__/unit/commands/build.test.js +279 -0
  3. package/frigg-cli/__tests__/unit/commands/db-setup.test.js +548 -0
  4. package/frigg-cli/__tests__/unit/commands/deploy.test.js +320 -0
  5. package/frigg-cli/__tests__/unit/commands/doctor.test.js +309 -0
  6. package/frigg-cli/__tests__/unit/commands/install.test.js +400 -0
  7. package/frigg-cli/__tests__/unit/commands/ui.test.js +346 -0
  8. package/frigg-cli/__tests__/unit/dependencies.test.js +74 -0
  9. package/frigg-cli/__tests__/unit/utils/database-validator.test.js +366 -0
  10. package/frigg-cli/__tests__/unit/utils/error-messages.test.js +304 -0
  11. package/frigg-cli/__tests__/unit/version-detection.test.js +171 -0
  12. package/frigg-cli/__tests__/utils/mock-factory.js +270 -0
  13. package/frigg-cli/__tests__/utils/prisma-mock.js +194 -0
  14. package/frigg-cli/__tests__/utils/test-fixtures.js +463 -0
  15. package/frigg-cli/__tests__/utils/test-setup.js +287 -0
  16. package/frigg-cli/build-command/index.js +66 -0
  17. package/frigg-cli/db-setup-command/index.js +193 -0
  18. package/frigg-cli/deploy-command/SPEC-DEPLOY-DRY-RUN.md +981 -0
  19. package/frigg-cli/deploy-command/index.js +302 -0
  20. package/frigg-cli/doctor-command/index.js +335 -0
  21. package/frigg-cli/generate-command/__tests__/generate-command.test.js +301 -0
  22. package/frigg-cli/generate-command/azure-generator.js +43 -0
  23. package/frigg-cli/generate-command/gcp-generator.js +47 -0
  24. package/frigg-cli/generate-command/index.js +332 -0
  25. package/frigg-cli/generate-command/terraform-generator.js +555 -0
  26. package/frigg-cli/generate-iam-command.js +118 -0
  27. package/frigg-cli/index.js +173 -0
  28. package/frigg-cli/index.test.js +158 -0
  29. package/frigg-cli/init-command/backend-first-handler.js +756 -0
  30. package/frigg-cli/init-command/index.js +93 -0
  31. package/frigg-cli/init-command/template-handler.js +143 -0
  32. package/frigg-cli/install-command/backend-js.js +33 -0
  33. package/frigg-cli/install-command/commit-changes.js +16 -0
  34. package/frigg-cli/install-command/environment-variables.js +127 -0
  35. package/frigg-cli/install-command/environment-variables.test.js +136 -0
  36. package/frigg-cli/install-command/index.js +54 -0
  37. package/frigg-cli/install-command/install-package.js +13 -0
  38. package/frigg-cli/install-command/integration-file.js +30 -0
  39. package/frigg-cli/install-command/logger.js +12 -0
  40. package/frigg-cli/install-command/template.js +90 -0
  41. package/frigg-cli/install-command/validate-package.js +75 -0
  42. package/frigg-cli/jest.config.js +124 -0
  43. package/frigg-cli/package.json +63 -0
  44. package/frigg-cli/repair-command/index.js +564 -0
  45. package/frigg-cli/start-command/index.js +149 -0
  46. package/frigg-cli/start-command/start-command.test.js +297 -0
  47. package/frigg-cli/test/init-command.test.js +180 -0
  48. package/frigg-cli/test/npm-registry.test.js +319 -0
  49. package/frigg-cli/ui-command/index.js +154 -0
  50. package/frigg-cli/utils/app-resolver.js +319 -0
  51. package/frigg-cli/utils/backend-path.js +25 -0
  52. package/frigg-cli/utils/database-validator.js +154 -0
  53. package/frigg-cli/utils/error-messages.js +257 -0
  54. package/frigg-cli/utils/npm-registry.js +167 -0
  55. package/frigg-cli/utils/process-manager.js +199 -0
  56. package/frigg-cli/utils/repo-detection.js +405 -0
  57. package/infrastructure/create-frigg-infrastructure.js +125 -12
  58. package/infrastructure/docs/PRE-DEPLOYMENT-HEALTH-CHECK-SPEC.md +1317 -0
  59. package/infrastructure/domains/shared/resource-discovery.enhanced.test.js +306 -0
  60. package/infrastructure/domains/shared/resource-discovery.js +31 -2
  61. package/infrastructure/domains/shared/utilities/base-definition-factory.js +1 -1
  62. package/infrastructure/domains/shared/utilities/prisma-layer-manager.js +109 -5
  63. package/infrastructure/domains/shared/utilities/prisma-layer-manager.test.js +310 -4
  64. package/infrastructure/domains/shared/validation/plugin-validator.js +187 -0
  65. package/infrastructure/domains/shared/validation/plugin-validator.test.js +323 -0
  66. package/infrastructure/infrastructure-composer.js +22 -0
  67. package/layers/prisma/.build-complete +3 -0
  68. package/package.json +18 -7
  69. package/management-ui/package-lock.json +0 -16517
@@ -0,0 +1,463 @@
1
+ /**
2
+ * TestFixtures - Centralized test data and fixtures
3
+ * Provides consistent test data across all CLI tests
4
+ */
5
+ class TestFixtures {
6
+ /**
7
+ * Get sample package.json configurations
8
+ */
9
+ static get packageConfigs() {
10
+ return {
11
+ valid: {
12
+ name: 'test-frigg-app',
13
+ version: '1.0.0',
14
+ description: 'Test Frigg application',
15
+ main: 'index.js',
16
+ scripts: {
17
+ start: 'node index.js',
18
+ test: 'jest',
19
+ build: 'webpack --mode production'
20
+ },
21
+ dependencies: {
22
+ '@friggframework/core': '^1.0.0',
23
+ 'express': '^4.18.0'
24
+ },
25
+ devDependencies: {
26
+ 'jest': '^29.0.0',
27
+ 'webpack': '^5.0.0'
28
+ },
29
+ frigg: {
30
+ stage: 'dev',
31
+ region: 'us-east-1'
32
+ }
33
+ },
34
+
35
+ invalid: {
36
+ name: '', // Invalid name
37
+ version: 'not-semver', // Invalid version
38
+ main: 'non-existent.js'
39
+ },
40
+
41
+ minimal: {
42
+ name: 'minimal-app',
43
+ version: '1.0.0',
44
+ main: 'index.js'
45
+ },
46
+
47
+ withFriggConfig: {
48
+ name: 'frigg-configured-app',
49
+ version: '1.0.0',
50
+ main: 'index.js',
51
+ frigg: {
52
+ stage: 'production',
53
+ region: 'eu-west-1',
54
+ profile: 'production',
55
+ backend: {
56
+ runtime: 'nodejs18.x',
57
+ timeout: 30,
58
+ memory: 256
59
+ }
60
+ }
61
+ }
62
+ };
63
+ }
64
+
65
+ /**
66
+ * Get sample Frigg configuration files
67
+ */
68
+ static get friggConfigs() {
69
+ return {
70
+ development: {
71
+ stage: 'dev',
72
+ region: 'us-east-1',
73
+ profile: 'default',
74
+ backend: {
75
+ runtime: 'nodejs18.x',
76
+ timeout: 30,
77
+ memory: 128,
78
+ environment: {
79
+ NODE_ENV: 'development',
80
+ DEBUG: 'true'
81
+ }
82
+ },
83
+ frontend: {
84
+ framework: 'react',
85
+ buildCommand: 'npm run build',
86
+ outputDir: 'dist',
87
+ environment: {
88
+ REACT_APP_API_URL: 'http://localhost:3000'
89
+ }
90
+ }
91
+ },
92
+
93
+ production: {
94
+ stage: 'prod',
95
+ region: 'us-east-1',
96
+ profile: 'production',
97
+ backend: {
98
+ runtime: 'nodejs18.x',
99
+ timeout: 30,
100
+ memory: 256,
101
+ environment: {
102
+ NODE_ENV: 'production'
103
+ }
104
+ },
105
+ frontend: {
106
+ framework: 'react',
107
+ buildCommand: 'npm run build:prod',
108
+ outputDir: 'build',
109
+ environment: {
110
+ REACT_APP_API_URL: 'https://api.example.com'
111
+ }
112
+ },
113
+ monitoring: {
114
+ enabled: true,
115
+ logLevel: 'info'
116
+ }
117
+ },
118
+
119
+ multiStage: {
120
+ stages: {
121
+ dev: {
122
+ region: 'us-east-1',
123
+ profile: 'dev',
124
+ backend: {
125
+ memory: 128
126
+ }
127
+ },
128
+ staging: {
129
+ region: 'us-west-2',
130
+ profile: 'staging',
131
+ backend: {
132
+ memory: 256
133
+ }
134
+ },
135
+ prod: {
136
+ region: 'eu-west-1',
137
+ profile: 'production',
138
+ backend: {
139
+ memory: 512
140
+ }
141
+ }
142
+ }
143
+ }
144
+ };
145
+ }
146
+
147
+ /**
148
+ * Get sample directory structures
149
+ */
150
+ static get directoryStructures() {
151
+ return {
152
+ basicFriggApp: {
153
+ 'package.json': JSON.stringify(this.packageConfigs.valid, null, 2),
154
+ 'frigg.config.json': JSON.stringify(this.friggConfigs.development, null, 2),
155
+ 'backend/': {
156
+ 'index.js': 'module.exports = { handler: () => {} };',
157
+ 'package.json': JSON.stringify({
158
+ name: 'backend',
159
+ version: '1.0.0',
160
+ main: 'index.js'
161
+ }, null, 2)
162
+ },
163
+ 'frontend/': {
164
+ 'package.json': JSON.stringify({
165
+ name: 'frontend',
166
+ version: '1.0.0',
167
+ main: 'src/index.js'
168
+ }, null, 2),
169
+ 'src/': {
170
+ 'index.js': 'console.log("Hello Frigg");'
171
+ }
172
+ }
173
+ },
174
+
175
+ backendOnly: {
176
+ 'package.json': JSON.stringify(this.packageConfigs.minimal, null, 2),
177
+ 'backend/': {
178
+ 'index.js': 'module.exports = { handler: () => {} };',
179
+ 'package.json': JSON.stringify({
180
+ name: 'backend',
181
+ version: '1.0.0',
182
+ main: 'index.js'
183
+ }, null, 2)
184
+ }
185
+ },
186
+
187
+ emptyProject: {
188
+ 'package.json': JSON.stringify(this.packageConfigs.minimal, null, 2)
189
+ }
190
+ };
191
+ }
192
+
193
+ /**
194
+ * Get sample API module configurations
195
+ */
196
+ static get apiModules() {
197
+ return {
198
+ valid: {
199
+ name: 'salesforce',
200
+ packageName: '@friggframework/api-module-salesforce',
201
+ version: '1.0.0',
202
+ description: 'Salesforce API integration',
203
+ dependencies: {
204
+ '@friggframework/core': '^1.0.0',
205
+ 'jsforce': '^2.0.0'
206
+ }
207
+ },
208
+
209
+ invalid: {
210
+ name: 'non-existent-module',
211
+ packageName: '@friggframework/api-module-non-existent',
212
+ error: 'Package not found'
213
+ },
214
+
215
+ deprecated: {
216
+ name: 'old-module',
217
+ packageName: '@friggframework/api-module-old',
218
+ version: '0.5.0',
219
+ deprecated: true,
220
+ replacement: '@friggframework/api-module-new'
221
+ }
222
+ };
223
+ }
224
+
225
+ /**
226
+ * Get sample command arguments and options
227
+ */
228
+ static get commandArgs() {
229
+ return {
230
+ install: {
231
+ valid: [
232
+ ['salesforce'],
233
+ ['hubspot', '--app-path', '/custom/path'],
234
+ ['slack', '--config', '/custom/config.json']
235
+ ],
236
+ invalid: [
237
+ [], // Missing module name
238
+ [''], // Empty module name
239
+ ['invalid-@characters']
240
+ ]
241
+ },
242
+
243
+ build: {
244
+ valid: [
245
+ [],
246
+ ['--stage', 'production'],
247
+ ['--verbose'],
248
+ ['--stage', 'dev', '--verbose']
249
+ ],
250
+ invalid: [
251
+ ['--stage', ''], // Empty stage
252
+ ['--invalid-option']
253
+ ]
254
+ },
255
+
256
+ deploy: {
257
+ valid: [
258
+ [],
259
+ ['--stage', 'production'],
260
+ ['--verbose'],
261
+ ['--stage', 'staging', '--verbose']
262
+ ],
263
+ invalid: [
264
+ ['--stage', 'invalid-stage']
265
+ ]
266
+ },
267
+
268
+ generate: {
269
+ valid: [
270
+ ['--provider', 'aws'],
271
+ ['--provider', 'azure', '--format', 'arm'],
272
+ ['--provider', 'gcp', '--format', 'terraform']
273
+ ],
274
+ invalid: [
275
+ [], // Missing provider
276
+ ['--provider', 'invalid-provider'],
277
+ ['--format', 'invalid-format']
278
+ ]
279
+ }
280
+ };
281
+ }
282
+
283
+ /**
284
+ * Get sample environment variables
285
+ */
286
+ static get environments() {
287
+ return {
288
+ development: {
289
+ NODE_ENV: 'development',
290
+ DEBUG: 'true',
291
+ AWS_PROFILE: 'default',
292
+ AWS_REGION: 'us-east-1'
293
+ },
294
+
295
+ production: {
296
+ NODE_ENV: 'production',
297
+ AWS_PROFILE: 'production',
298
+ AWS_REGION: 'us-east-1'
299
+ },
300
+
301
+ testing: {
302
+ NODE_ENV: 'test',
303
+ DEBUG: 'false',
304
+ AWS_PROFILE: 'test',
305
+ AWS_REGION: 'us-east-1'
306
+ }
307
+ };
308
+ }
309
+
310
+ /**
311
+ * Get sample file contents
312
+ */
313
+ static get fileContents() {
314
+ return {
315
+ validJson: '{"valid": true, "data": {"key": "value"}}',
316
+ invalidJson: '{"invalid": json}',
317
+ emptyJson: '{}',
318
+
319
+ validYaml: `
320
+ stage: dev
321
+ region: us-east-1
322
+ backend:
323
+ runtime: nodejs18.x
324
+ timeout: 30
325
+ `,
326
+
327
+ invalidYaml: `
328
+ invalid: yaml: content
329
+ - missing: structure
330
+ `,
331
+
332
+ basicJavaScript: `
333
+ module.exports = {
334
+ handler: async (event) => {
335
+ return { statusCode: 200, body: 'Hello World' };
336
+ }
337
+ };
338
+ `,
339
+
340
+ packageJsonTemplate: `
341
+ {
342
+ "name": "{{name}}",
343
+ "version": "{{version}}",
344
+ "main": "{{main}}",
345
+ "dependencies": {{dependencies}}
346
+ }
347
+ `
348
+ };
349
+ }
350
+
351
+ /**
352
+ * Get sample error scenarios
353
+ */
354
+ static get errorScenarios() {
355
+ return {
356
+ fileNotFound: {
357
+ code: 'ENOENT',
358
+ message: 'File not found',
359
+ path: '/non/existent/file.json'
360
+ },
361
+
362
+ permissionDenied: {
363
+ code: 'EACCES',
364
+ message: 'Permission denied',
365
+ path: '/protected/file.json'
366
+ },
367
+
368
+ networkError: {
369
+ code: 'ECONNREFUSED',
370
+ message: 'Connection refused',
371
+ address: '127.0.0.1',
372
+ port: 8080
373
+ },
374
+
375
+ validationError: {
376
+ code: 'VALIDATION_ERROR',
377
+ message: 'Invalid configuration',
378
+ details: {
379
+ field: 'stage',
380
+ value: 'invalid-stage',
381
+ allowed: ['dev', 'staging', 'prod']
382
+ }
383
+ },
384
+
385
+ installationError: {
386
+ code: 'INSTALLATION_ERROR',
387
+ message: 'Failed to install package',
388
+ package: '@friggframework/api-module-test',
389
+ reason: 'Package not found in registry'
390
+ }
391
+ };
392
+ }
393
+
394
+ /**
395
+ * Get sample network responses
396
+ */
397
+ static get networkResponses() {
398
+ return {
399
+ packageExists: {
400
+ status: 200,
401
+ data: {
402
+ name: '@friggframework/api-module-test',
403
+ version: '1.0.0',
404
+ description: 'Test API module'
405
+ }
406
+ },
407
+
408
+ packageNotFound: {
409
+ status: 404,
410
+ data: {
411
+ error: 'Package not found'
412
+ }
413
+ },
414
+
415
+ registryError: {
416
+ status: 500,
417
+ data: {
418
+ error: 'Internal server error'
419
+ }
420
+ }
421
+ };
422
+ }
423
+
424
+ /**
425
+ * Create a temporary file structure for testing
426
+ * @param {object} structure - Directory structure object
427
+ * @returns {string} - Temporary directory path
428
+ */
429
+ static createTempStructure(structure) {
430
+ const fs = require('fs');
431
+ const path = require('path');
432
+ const os = require('os');
433
+
434
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'frigg-test-'));
435
+
436
+ const createFiles = (dir, structure) => {
437
+ for (const [name, content] of Object.entries(structure)) {
438
+ const fullPath = path.join(dir, name);
439
+
440
+ if (typeof content === 'object' && content !== null) {
441
+ fs.mkdirSync(fullPath, { recursive: true });
442
+ createFiles(fullPath, content);
443
+ } else {
444
+ fs.writeFileSync(fullPath, content);
445
+ }
446
+ }
447
+ };
448
+
449
+ createFiles(tempDir, structure);
450
+ return tempDir;
451
+ }
452
+
453
+ /**
454
+ * Clean up temporary directory
455
+ * @param {string} tempDir - Temporary directory path
456
+ */
457
+ static cleanupTempStructure(tempDir) {
458
+ const fs = require('fs');
459
+ fs.rmSync(tempDir, { recursive: true, force: true });
460
+ }
461
+ }
462
+
463
+ module.exports = { TestFixtures };