@friggframework/devtools 2.0.0--canary.545.c459392.0 → 2.0.0--canary.547.67ebb53.0

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 (128) hide show
  1. package/frigg-cli/README.md +1 -1
  2. package/frigg-cli/__tests__/unit/commands/build.test.js +1 -1
  3. package/frigg-cli/__tests__/unit/commands/doctor.test.js +2 -0
  4. package/frigg-cli/__tests__/unit/commands/install.test.js +19 -23
  5. package/frigg-cli/__tests__/unit/dependencies.test.js +2 -2
  6. package/frigg-cli/build-command/index.js +11 -123
  7. package/frigg-cli/deploy-command/index.js +1 -83
  8. package/frigg-cli/doctor-command/index.js +16 -37
  9. package/frigg-cli/generate-iam-command.js +1 -21
  10. package/frigg-cli/index.js +6 -21
  11. package/frigg-cli/index.test.js +2 -7
  12. package/frigg-cli/init-command/backend-first-handler.js +42 -124
  13. package/frigg-cli/init-command/index.js +1 -2
  14. package/frigg-cli/init-command/template-handler.js +3 -13
  15. package/frigg-cli/install-command/backend-js.js +3 -3
  16. package/frigg-cli/install-command/environment-variables.js +19 -16
  17. package/frigg-cli/install-command/environment-variables.test.js +13 -12
  18. package/frigg-cli/install-command/index.js +9 -14
  19. package/frigg-cli/install-command/integration-file.js +3 -3
  20. package/frigg-cli/install-command/logger.js +12 -0
  21. package/frigg-cli/install-command/validate-package.js +9 -5
  22. package/frigg-cli/jest.config.js +1 -4
  23. package/frigg-cli/repair-command/index.js +128 -121
  24. package/frigg-cli/start-command/index.js +2 -324
  25. package/frigg-cli/ui-command/index.js +36 -58
  26. package/frigg-cli/utils/repo-detection.js +37 -85
  27. package/infrastructure/create-frigg-infrastructure.js +0 -93
  28. package/infrastructure/docs/iam-policy-templates.md +1 -1
  29. package/infrastructure/domains/networking/vpc-builder.test.js +4 -2
  30. package/infrastructure/domains/networking/vpc-resolver.test.js +1 -1
  31. package/infrastructure/domains/shared/cloudformation-discovery.test.js +7 -4
  32. package/infrastructure/domains/shared/resource-discovery.js +5 -5
  33. package/infrastructure/domains/shared/types/app-definition.js +0 -21
  34. package/infrastructure/domains/shared/types/discovery-result.test.js +1 -1
  35. package/infrastructure/domains/shared/utilities/base-definition-factory.js +1 -10
  36. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +2 -2
  37. package/infrastructure/infrastructure-composer.js +0 -2
  38. package/infrastructure/infrastructure-composer.test.js +2 -2
  39. package/management-ui/README.md +109 -245
  40. package/package.json +7 -8
  41. package/frigg-cli/__tests__/application/use-cases/AddApiModuleToIntegrationUseCase.test.js +0 -326
  42. package/frigg-cli/__tests__/application/use-cases/CreateApiModuleUseCase.test.js +0 -337
  43. package/frigg-cli/__tests__/domain/entities/ApiModule.test.js +0 -373
  44. package/frigg-cli/__tests__/domain/entities/AppDefinition.test.js +0 -313
  45. package/frigg-cli/__tests__/domain/services/IntegrationValidator.test.js +0 -269
  46. package/frigg-cli/__tests__/domain/value-objects/IntegrationName.test.js +0 -82
  47. package/frigg-cli/__tests__/infrastructure/adapters/IntegrationJsUpdater.test.js +0 -408
  48. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemApiModuleRepository.test.js +0 -583
  49. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemAppDefinitionRepository.test.js +0 -314
  50. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemIntegrationRepository.test.js +0 -383
  51. package/frigg-cli/__tests__/unit/commands/init.test.js +0 -406
  52. package/frigg-cli/__tests__/unit/commands/provider-dispatch.test.js +0 -383
  53. package/frigg-cli/__tests__/unit/commands/repair.test.js +0 -275
  54. package/frigg-cli/__tests__/unit/start-command/application/RunPreflightChecksUseCase.test.js +0 -411
  55. package/frigg-cli/__tests__/unit/start-command/infrastructure/DatabaseAdapter.test.js +0 -405
  56. package/frigg-cli/__tests__/unit/start-command/infrastructure/DockerAdapter.test.js +0 -496
  57. package/frigg-cli/__tests__/unit/start-command/presentation/InteractivePromptAdapter.test.js +0 -474
  58. package/frigg-cli/__tests__/unit/utils/output.test.js +0 -196
  59. package/frigg-cli/application/use-cases/AddApiModuleToIntegrationUseCase.js +0 -93
  60. package/frigg-cli/application/use-cases/CreateApiModuleUseCase.js +0 -93
  61. package/frigg-cli/application/use-cases/CreateIntegrationUseCase.js +0 -103
  62. package/frigg-cli/container.js +0 -172
  63. package/frigg-cli/docs/OUTPUT_MIGRATION_GUIDE.md +0 -286
  64. package/frigg-cli/domain/entities/ApiModule.js +0 -272
  65. package/frigg-cli/domain/entities/AppDefinition.js +0 -227
  66. package/frigg-cli/domain/entities/Integration.js +0 -198
  67. package/frigg-cli/domain/exceptions/DomainException.js +0 -24
  68. package/frigg-cli/domain/ports/IApiModuleRepository.js +0 -53
  69. package/frigg-cli/domain/ports/IAppDefinitionRepository.js +0 -43
  70. package/frigg-cli/domain/ports/IIntegrationRepository.js +0 -61
  71. package/frigg-cli/domain/services/IntegrationValidator.js +0 -185
  72. package/frigg-cli/domain/value-objects/IntegrationId.js +0 -42
  73. package/frigg-cli/domain/value-objects/IntegrationName.js +0 -60
  74. package/frigg-cli/domain/value-objects/SemanticVersion.js +0 -70
  75. package/frigg-cli/infrastructure/UnitOfWork.js +0 -46
  76. package/frigg-cli/infrastructure/adapters/BackendJsUpdater.js +0 -197
  77. package/frigg-cli/infrastructure/adapters/FileSystemAdapter.js +0 -224
  78. package/frigg-cli/infrastructure/adapters/IntegrationJsUpdater.js +0 -249
  79. package/frigg-cli/infrastructure/adapters/SchemaValidator.js +0 -92
  80. package/frigg-cli/infrastructure/repositories/FileSystemApiModuleRepository.js +0 -373
  81. package/frigg-cli/infrastructure/repositories/FileSystemAppDefinitionRepository.js +0 -116
  82. package/frigg-cli/infrastructure/repositories/FileSystemIntegrationRepository.js +0 -277
  83. package/frigg-cli/package-lock.json +0 -16226
  84. package/frigg-cli/start-command/application/RunPreflightChecksUseCase.js +0 -376
  85. package/frigg-cli/start-command/infrastructure/DatabaseAdapter.js +0 -591
  86. package/frigg-cli/start-command/infrastructure/DockerAdapter.js +0 -306
  87. package/frigg-cli/start-command/presentation/InteractivePromptAdapter.js +0 -329
  88. package/frigg-cli/templates/backend/.env.example +0 -62
  89. package/frigg-cli/templates/backend/.eslintrc.json +0 -12
  90. package/frigg-cli/templates/backend/.prettierrc +0 -6
  91. package/frigg-cli/templates/backend/docker-compose.yml +0 -22
  92. package/frigg-cli/templates/backend/index.js +0 -96
  93. package/frigg-cli/templates/backend/infrastructure.js +0 -12
  94. package/frigg-cli/templates/backend/jest.config.js +0 -17
  95. package/frigg-cli/templates/backend/package.json +0 -50
  96. package/frigg-cli/templates/backend/src/api-modules/.gitkeep +0 -10
  97. package/frigg-cli/templates/backend/src/base/.gitkeep +0 -7
  98. package/frigg-cli/templates/backend/src/integrations/.gitkeep +0 -10
  99. package/frigg-cli/templates/backend/src/integrations/ExampleIntegration.js +0 -65
  100. package/frigg-cli/templates/backend/src/utils/.gitkeep +0 -7
  101. package/frigg-cli/templates/backend/test/setup.js +0 -30
  102. package/frigg-cli/templates/backend/ui-extensions/.gitkeep +0 -0
  103. package/frigg-cli/templates/backend/ui-extensions/README.md +0 -77
  104. package/frigg-cli/utils/__tests__/provider-helper.test.js +0 -55
  105. package/frigg-cli/utils/__tests__/repo-detection.test.js +0 -436
  106. package/frigg-cli/utils/output.js +0 -382
  107. package/frigg-cli/utils/provider-helper.js +0 -75
  108. package/frigg-cli/validate-command/__tests__/adapters/validate-command.test.js +0 -205
  109. package/frigg-cli/validate-command/__tests__/application/validate-app-use-case.test.js +0 -104
  110. package/frigg-cli/validate-command/__tests__/domain/fix-suggestion.test.js +0 -153
  111. package/frigg-cli/validate-command/__tests__/domain/validation-error.test.js +0 -162
  112. package/frigg-cli/validate-command/__tests__/domain/validation-result.test.js +0 -152
  113. package/frigg-cli/validate-command/__tests__/infrastructure/api-module-validator.test.js +0 -332
  114. package/frigg-cli/validate-command/__tests__/infrastructure/app-definition-validator.test.js +0 -191
  115. package/frigg-cli/validate-command/__tests__/infrastructure/integration-class-validator.test.js +0 -146
  116. package/frigg-cli/validate-command/__tests__/infrastructure/template-validation.test.js +0 -155
  117. package/frigg-cli/validate-command/adapters/cli/validate-command.js +0 -199
  118. package/frigg-cli/validate-command/application/use-cases/validate-app-use-case.js +0 -35
  119. package/frigg-cli/validate-command/domain/entities/validation-result.js +0 -74
  120. package/frigg-cli/validate-command/domain/value-objects/fix-suggestion.js +0 -74
  121. package/frigg-cli/validate-command/domain/value-objects/validation-error.js +0 -68
  122. package/frigg-cli/validate-command/infrastructure/validators/api-module-validator.js +0 -181
  123. package/frigg-cli/validate-command/infrastructure/validators/app-definition-validator.js +0 -128
  124. package/frigg-cli/validate-command/infrastructure/validators/integration-class-validator.js +0 -113
  125. package/infrastructure/domains/admin-scripts/admin-script-builder.js +0 -200
  126. package/infrastructure/domains/admin-scripts/admin-script-builder.test.js +0 -499
  127. package/infrastructure/domains/admin-scripts/index.js +0 -5
  128. package/infrastructure/jest.config.js +0 -16
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
  const chalk = require('chalk');
4
- const { select, confirm, checkbox } = require('@inquirer/prompts');
4
+ const { select, confirm, multiselect } = require('@inquirer/prompts');
5
5
  const { execSync } = require('child_process');
6
6
  const spawn = require('cross-spawn');
7
7
  const npmRegistry = require('../utils/npm-registry');
@@ -35,15 +35,15 @@ class BackendFirstHandler {
35
35
  await this.createProject(deploymentMode, config);
36
36
 
37
37
  console.log(chalk.green('\n✅ Frigg application created successfully!'));
38
-
39
- // If user needs custom API module, prompt to create it (skip in --yes mode)
40
- if (config.needsCustomApiModule && !this.options.yes) {
38
+
39
+ // If user needs custom API module, prompt to create it
40
+ if (config.needsCustomApiModule) {
41
41
  console.log(chalk.cyan('\n🔧 Now let\'s create your custom API module...'));
42
42
  const createModule = await confirm({
43
43
  message: 'Would you like to create your custom API module now?',
44
44
  default: true
45
45
  });
46
-
46
+
47
47
  if (createModule) {
48
48
  console.log(chalk.gray('\n Run this command after setup:'));
49
49
  console.log(chalk.cyan(` cd ${path.relative(process.cwd(), this.targetPath)}`));
@@ -62,11 +62,6 @@ class BackendFirstHandler {
62
62
  return this.options.mode;
63
63
  }
64
64
 
65
- // If --yes flag is set, use default
66
- if (this.options.yes) {
67
- return 'standalone';
68
- }
69
-
70
65
  const mode = await select({
71
66
  message: 'How will you deploy this Frigg application?',
72
67
  choices: [
@@ -93,21 +88,6 @@ class BackendFirstHandler {
93
88
  async getProjectConfiguration(deploymentMode) {
94
89
  const config = { deploymentMode };
95
90
 
96
- // If --yes flag is set, use all defaults
97
- if (this.options.yes) {
98
- return {
99
- deploymentMode,
100
- appPurpose: 'exploring',
101
- needsCustomApiModule: false,
102
- includeIntegrations: false,
103
- starterIntegrations: [],
104
- includeDemoFrontend: false,
105
- serverlessProvider: deploymentMode === 'standalone' ? 'aws' : undefined,
106
- installDependencies: true,
107
- initializeGit: true,
108
- };
109
- }
110
-
111
91
  // Ask about the purpose of this Frigg application
112
92
  config.appPurpose = await select({
113
93
  message: 'What are you building with Frigg?',
@@ -178,7 +158,7 @@ class BackendFirstHandler {
178
158
  }
179
159
  });
180
160
 
181
- config.starterIntegrations = await checkbox({
161
+ config.starterIntegrations = await multiselect({
182
162
  message: 'Select API modules to integrate (space to select, enter to confirm):',
183
163
  choices,
184
164
  instructions: '\n Press <space> to select, <a> to toggle all, <enter> to confirm\n',
@@ -286,115 +266,63 @@ class BackendFirstHandler {
286
266
 
287
267
  /**
288
268
  * Create standalone Frigg service
289
- *
290
- * Structure:
291
- * my-app/
292
- * ├── package.json # Root - delegates to backend with "cd backend &&"
293
- * ├── backend/ # Actual Frigg app with its own package.json & node_modules
294
- * │ ├── index.js
295
- * │ ├── infrastructure.js
296
- * │ ├── package.json
297
- * │ └── src/
298
- * └── ui-extensions/ # Platform-specific UI extensions
299
- * └── README.md
300
269
  */
301
270
  async createStandaloneProject(config) {
302
- const backendPath = path.join(this.targetPath, 'backend');
303
- const uiExtensionsPath = path.join(this.targetPath, 'ui-extensions');
304
-
305
- // Copy backend template to backend/ subdirectory
271
+ // Copy backend template
306
272
  const backendTemplate = path.join(this.templatesDir, 'backend');
307
- await fs.copy(backendTemplate, backendPath);
308
-
309
- // Read template package.json
310
- const templatePackageJsonPath = path.join(backendPath, 'package.json');
311
- let templatePackageJson = {};
312
- if (await fs.pathExists(templatePackageJsonPath)) {
313
- templatePackageJson = await fs.readJSON(templatePackageJsonPath);
314
- }
273
+ await fs.copy(backendTemplate, this.targetPath);
315
274
 
316
- // Create backend package.json with all dependencies
317
- const backendPackageJson = {
318
- name: `${this.appName}-backend`,
275
+ // Create package.json for standalone mode
276
+ const packageJson = {
277
+ name: this.appName,
319
278
  version: '0.1.0',
320
279
  private: true,
321
- prettier: templatePackageJson.prettier || '@friggframework/prettier-config',
322
280
  scripts: {
323
- ...templatePackageJson.scripts,
324
281
  "backend-start": "node infrastructure.js start",
325
282
  "start": "npm run backend-start",
326
283
  "build": "node infrastructure.js package",
327
284
  "deploy": "node infrastructure.js deploy",
285
+ "test": "jest"
328
286
  },
329
287
  dependencies: {
330
- ...templatePackageJson.dependencies,
331
- "@friggframework/core": "2.0.0-next.58"
332
- },
333
- devDependencies: {
334
- ...templatePackageJson.devDependencies
335
- }
336
- };
337
-
338
- // Add selected integrations as dependencies to backend
339
- if (config.starterIntegrations && config.starterIntegrations.length > 0) {
340
- for (const integration of config.starterIntegrations) {
341
- backendPackageJson.dependencies[`@friggframework/api-module-${integration}`] = '^2.0.0';
342
- }
343
- }
344
-
345
- await fs.writeJSON(templatePackageJsonPath, backendPackageJson, { spaces: 2 });
346
-
347
- // Create root package.json that delegates to backend
348
- const rootPackageJson = {
349
- name: this.appName,
350
- version: '0.1.0',
351
- private: true,
352
- scripts: {
353
- "start": "cd backend && npm run frigg:start",
354
- "docker:start": "cd backend && npm run docker:start",
355
- "docker:stop": "cd backend && npm run docker:stop",
356
- "test": "cd backend && npm test",
357
- "build": "cd backend && npm run build",
358
- "deploy": "cd backend && npm run deploy",
359
- "lint": "cd backend && npm run lint",
360
- "format": "cd backend && npm run format"
288
+ "@friggframework/core": "^2.0.0"
361
289
  }
362
290
  };
363
291
 
364
292
  // Add demo frontend if requested
365
293
  if (config.includeDemoFrontend) {
366
- rootPackageJson.scripts['dev'] = 'concurrently "cd backend && npm run backend-start" "cd frontend && npm run dev"';
367
- rootPackageJson.scripts['frontend:dev'] = 'cd frontend && npm run dev';
368
- rootPackageJson.devDependencies = { concurrently: '^8.2.2' };
369
-
294
+ packageJson.workspaces = ['backend', 'frontend'];
295
+ packageJson.scripts['dev'] = 'concurrently "npm run backend-start" "npm run frontend:dev"';
296
+ packageJson.scripts['frontend:dev'] = 'cd frontend && npm run dev';
297
+
370
298
  await this.createDemoFrontend(config);
371
299
  }
372
300
 
301
+ // Add selected integrations as dependencies
302
+ if (config.starterIntegrations && config.starterIntegrations.length > 0) {
303
+ for (const integration of config.starterIntegrations) {
304
+ packageJson.dependencies[`@friggframework/api-module-${integration}`] = '^2.0.0';
305
+ }
306
+ }
307
+
373
308
  await fs.writeJSON(
374
309
  path.join(this.targetPath, 'package.json'),
375
- rootPackageJson,
310
+ packageJson,
376
311
  { spaces: 2 }
377
312
  );
378
313
 
379
- // Create ui-extensions directory with README
380
- await fs.ensureDir(uiExtensionsPath);
381
- const uiExtensionsReadme = path.join(this.templatesDir, 'backend', 'ui-extensions', 'README.md');
382
- if (await fs.pathExists(uiExtensionsReadme)) {
383
- await fs.copy(uiExtensionsReadme, path.join(uiExtensionsPath, 'README.md'));
384
- }
385
-
386
314
  // Update index.js with selected integrations
387
315
  if (config.starterIntegrations && config.starterIntegrations.length > 0) {
388
- await this.updateAppDefinition(config.starterIntegrations, backendPath);
316
+ await this.updateAppDefinition(config.starterIntegrations);
389
317
  }
390
318
 
391
319
  // Validate generated app definition against schema
392
- const appDefPath = path.join(backendPath, 'index.js');
320
+ const appDefPath = path.join(this.targetPath, 'index.js');
393
321
  await this.validateGeneratedAppDefinition(appDefPath);
394
322
 
395
323
  // Update serverless.yml based on provider
396
324
  if (config.serverlessProvider === 'aws') {
397
- await this.configureAWSServerless(backendPath);
325
+ await this.configureAWSServerless();
398
326
  }
399
327
  }
400
328
 
@@ -578,9 +506,9 @@ To integrate Frigg into your production application:
578
506
  /**
579
507
  * Configure AWS serverless
580
508
  */
581
- async configureAWSServerless(targetDir = this.targetPath) {
509
+ async configureAWSServerless() {
582
510
  // Update serverless.yml for AWS
583
- const serverlessPath = path.join(targetDir, 'serverless.yml');
511
+ const serverlessPath = path.join(this.targetPath, 'serverless.yml');
584
512
  if (await fs.pathExists(serverlessPath)) {
585
513
  // Keep existing AWS configuration
586
514
  console.log(chalk.gray('AWS Lambda configuration ready'));
@@ -605,25 +533,23 @@ To integrate Frigg into your production application:
605
533
  }
606
534
 
607
535
  /**
608
- * Install dependencies in the backend directory
536
+ * Install dependencies
609
537
  */
610
538
  async installDependencies(config) {
611
- console.log(chalk.blue('\n📦 Installing dependencies in backend...'));
612
-
539
+ console.log(chalk.blue('\n📦 Installing dependencies...'));
540
+
613
541
  const useYarn = this.isUsingYarn();
614
542
  const command = useYarn ? 'yarn' : 'npm';
615
543
  const args = useYarn ? [] : ['install'];
616
544
 
617
- // Install in backend directory where package.json with dependencies lives
618
- const backendPath = path.join(this.targetPath, 'backend');
619
545
  const proc = spawn.sync(command, args, {
620
- cwd: backendPath,
546
+ cwd: this.targetPath,
621
547
  stdio: 'inherit'
622
548
  });
623
549
 
624
550
  if (proc.status !== 0) {
625
551
  console.log(chalk.yellow('\n⚠️ Dependency installation failed'));
626
- console.log(chalk.gray(`You can install manually with: cd backend && ${command} install`));
552
+ console.log(chalk.gray(`You can install manually with: ${command} install`));
627
553
  }
628
554
  }
629
555
 
@@ -651,7 +577,7 @@ To integrate Frigg into your production application:
651
577
  * Select from default integrations when npm is unavailable
652
578
  */
653
579
  async selectDefaultIntegrations() {
654
- return await checkbox({
580
+ return await multiselect({
655
581
  message: 'Select starter integrations (space to select, enter to confirm):',
656
582
  choices: [
657
583
  { name: 'Salesforce - CRM integration', value: 'salesforce' },
@@ -670,8 +596,8 @@ To integrate Frigg into your production application:
670
596
  /**
671
597
  * Update index.js with selected integrations
672
598
  */
673
- async updateAppDefinition(integrations, targetDir = this.targetPath) {
674
- const appDefPath = path.join(targetDir, 'index.js');
599
+ async updateAppDefinition(integrations) {
600
+ const appDefPath = path.join(this.targetPath, 'index.js');
675
601
  if (await fs.pathExists(appDefPath)) {
676
602
  let content = await fs.readFile(appDefPath, 'utf8');
677
603
 
@@ -794,18 +720,14 @@ To integrate Frigg into your production application:
794
720
  console.log(chalk.cyan(` cd ${cdPath}\n`));
795
721
 
796
722
  if (deploymentMode === 'standalone') {
797
- console.log(`2. Install backend dependencies:`);
798
- console.log(chalk.cyan(` cd backend && npm install\n`));
799
-
800
- console.log(`3. Start the development server:`);
723
+ console.log(`2. Start the development server:`);
801
724
  console.log(chalk.cyan(` npm start\n`));
802
- console.log(chalk.gray(` (or from backend: npm run frigg:start)\n`));
803
725
 
804
- console.log(`4. Open the Frigg UI for development:`);
726
+ console.log(`3. Open the Frigg UI for development:`);
805
727
  console.log(chalk.cyan(` frigg ui\n`));
806
728
 
807
729
  if (config.serverlessProvider === 'aws') {
808
- console.log(`5. Deploy to AWS Lambda:`);
730
+ console.log(`4. Deploy to AWS Lambda:`);
809
731
  console.log(chalk.cyan(` npm run deploy\n`));
810
732
  }
811
733
  } else {
@@ -825,12 +747,8 @@ To integrate Frigg into your production application:
825
747
  console.log(chalk.gray(' See frontend/README.md for integration guidance.'));
826
748
  }
827
749
 
828
- console.log(chalk.gray('\n📁 Project Structure:'));
829
- console.log(chalk.gray(' backend/ - Frigg app (run npm install here)'));
830
- console.log(chalk.gray(' ui-extensions/ - Platform-specific UI extensions'));
831
-
832
750
  console.log(chalk.green('\n🎉 Happy integrating with Frigg!\n'));
833
- console.log(chalk.gray('Documentation: https://docs.friggframework.org'));
751
+ console.log(chalk.gray('Documentation: https://docs.frigg.dev'));
834
752
  console.log(chalk.gray('Support: https://github.com/friggframework/frigg/issues'));
835
753
  }
836
754
  }
@@ -68,8 +68,7 @@ async function initCommand(projectName, options) {
68
68
  force,
69
69
  verbose,
70
70
  mode: options.mode,
71
- frontend: options.frontend,
72
- yes: options.yes
71
+ frontend: options.frontend
73
72
  });
74
73
 
75
74
  await handler.initialize();
@@ -75,16 +75,6 @@ class TemplateHandler {
75
75
  return !['node_modules', '.serverless', 'dist', 'build'].includes(basename);
76
76
  }
77
77
  });
78
-
79
- // Rename .env.default to .env if it exists and .env doesn't already exist
80
- const envDefaultPath = path.join(target, '.env.default');
81
- const envPath = path.join(target, '.env');
82
- if (fs.existsSync(envDefaultPath) && !fs.existsSync(envPath)) {
83
- await fs.rename(envDefaultPath, envPath);
84
- } else if (fs.existsSync(envDefaultPath)) {
85
- // Remove the .env.default if .env already exists
86
- await fs.remove(envDefaultPath);
87
- }
88
78
  }
89
79
 
90
80
  /**
@@ -110,14 +100,14 @@ class TemplateHandler {
110
100
  async updateServerlessConfig() {
111
101
  const serverlessPath = path.join(this.targetPath, 'serverless.yml');
112
102
  let serverlessContent = await fs.readFile(serverlessPath, 'utf8');
113
-
103
+
114
104
  // Update service name based on directory name
115
105
  const projectName = path.basename(this.targetPath);
116
106
  serverlessContent = serverlessContent.replace(
117
- /^service: frigg-app$/m,
107
+ /^service: create-frigg-app$/m,
118
108
  `service: ${projectName}`
119
109
  );
120
-
110
+
121
111
  await fs.writeFile(serverlessPath, serverlessContent);
122
112
  }
123
113
 
@@ -1,12 +1,12 @@
1
1
  const fs = require('fs-extra');
2
2
  const path = require('path');
3
- const output = require('../utils/output');
3
+ const { logInfo } = require('./logger');
4
4
  const INTEGRATIONS_DIR = 'src/integrations';
5
5
  const BACKEND_JS = 'backend.js';
6
6
 
7
7
  function updateBackendJsFile(backendPath, apiModuleName) {
8
8
  const backendJsPath = path.join(path.dirname(backendPath), BACKEND_JS);
9
- output.debug(`Updating backend.js: ${backendJsPath}`);
9
+ logInfo(`Updating backend.js: ${backendJsPath}`);
10
10
  updateBackendJs(backendJsPath, apiModuleName);
11
11
  }
12
12
 
@@ -21,7 +21,7 @@ function updateBackendJs(backendJsPath, apiModuleName) {
21
21
  );
22
22
  fs.writeFileSync(backendJsPath, importStatement + updatedContent);
23
23
  } else {
24
- output.debug(
24
+ logInfo(
25
25
  `Import statement for ${apiModuleName}Integration already exists in backend.js`
26
26
  );
27
27
  }
@@ -1,8 +1,9 @@
1
1
  const fs = require('fs');
2
2
  const dotenv = require('dotenv');
3
3
  const { readFileSync, writeFileSync, existsSync } = require('fs');
4
- const output = require('../utils/output');
4
+ const { logInfo } = require('./logger');
5
5
  const { resolve } = require('node:path');
6
+ const { confirm, input } = require('@inquirer/prompts');
6
7
  const { parse } = require('@babel/parser');
7
8
  const traverse = require('@babel/traverse').default;
8
9
 
@@ -42,14 +43,15 @@ const extractRawEnvVariables = (modulePath) => {
42
43
  return envVariables;
43
44
  };
44
45
  const handleEnvVariables = async (backendPath, modulePath) => {
45
- output.info('Searching for missing environment variables...');
46
+ logInfo('Searching for missing environment variables...');
46
47
  const Definition = { env: extractRawEnvVariables(modulePath) };
47
48
  if (Definition && Definition.env) {
48
- output.debug('Definition.env:', JSON.stringify(Definition.env));
49
+ console.log('Here is Definition.env:', Definition.env);
49
50
  const envVars = Object.values(Definition.env);
50
51
 
51
- output.info(
52
- `Found environment variables in API module: ${envVars.join(', ')}`
52
+ console.log(
53
+ 'Found the following environment variables in the API module:',
54
+ envVars
53
55
  );
54
56
 
55
57
  const localEnvPath = resolve(backendPath, '../.env');
@@ -76,19 +78,23 @@ const handleEnvVariables = async (backendPath, modulePath) => {
76
78
  (envVar) => !localEnvVars[envVar] && !localDevConfig[envVar]
77
79
  );
78
80
 
79
- if (missingEnvVars.length > 0) {
80
- output.warn(`Missing environment variables: ${missingEnvVars.join(', ')}`);
81
+ logInfo(`Missing environment variables: ${missingEnvVars.join(', ')}`);
81
82
 
82
- const addEnvVars = await output.confirm(
83
- `The following environment variables are required: ${missingEnvVars.join(
83
+ if (missingEnvVars.length > 0) {
84
+ const addEnvVars = await confirm({
85
+ message: `The following environment variables are required: ${missingEnvVars.join(
84
86
  ', '
85
- )}. Do you want to add them now?`
86
- );
87
+ )}. Do you want to add them now?`,
88
+ });
87
89
 
88
90
  if (addEnvVars) {
89
91
  const envValues = {};
90
92
  for (const envVar of missingEnvVars) {
91
- const value = await output.input(`Enter value for ${envVar}:`);
93
+ const value = await input({
94
+ type: 'input',
95
+ name: 'value',
96
+ message: `Enter value for ${envVar}:`,
97
+ });
92
98
  envValues[envVar] = value;
93
99
  }
94
100
 
@@ -111,12 +117,9 @@ const handleEnvVariables = async (backendPath, modulePath) => {
111
117
  JSON.stringify(updatedDevConfig, null, 2)
112
118
  );
113
119
  }
114
- output.success('Environment variables added successfully');
115
120
  } else {
116
- output.info("Edit whenever you're able, safe travels friend!");
121
+ logInfo("Edit whenever you're able, safe travels friend!");
117
122
  }
118
- } else {
119
- output.success('All required environment variables are already configured');
120
123
  }
121
124
  }
122
125
  };
@@ -1,14 +1,16 @@
1
1
  const { handleEnvVariables } = require('./environment-variables');
2
- const output = require('../utils/output');
2
+ const { logInfo } = require('./logger');
3
+ const inquirer = require('inquirer');
3
4
  const fs = require('fs');
4
5
  const dotenv = require('dotenv');
5
6
  const { resolve } = require('node:path');
6
7
  const { parse } = require('@babel/parser');
7
8
  const traverse = require('@babel/traverse');
8
9
 
9
- jest.mock('../utils/output');
10
+ jest.mock('inquirer');
10
11
  jest.mock('fs');
11
12
  jest.mock('dotenv');
13
+ jest.mock('./logger');
12
14
  jest.mock('@babel/parser');
13
15
  jest.mock('@babel/traverse');
14
16
 
@@ -97,23 +99,22 @@ describe('handleEnvVariables', () => {
97
99
  return '';
98
100
  });
99
101
 
100
- output.confirm.mockResolvedValueOnce(true);
101
- output.input
102
- .mockResolvedValueOnce('client_id_value')
103
- .mockResolvedValueOnce('client_secret_value')
104
- .mockResolvedValueOnce('redirect_uri_value')
105
- .mockResolvedValueOnce('scope_value');
102
+ inquirer.prompt
103
+ .mockResolvedValueOnce({ addEnvVars: true })
104
+ .mockResolvedValueOnce({ value: 'client_id_value' })
105
+ .mockResolvedValueOnce({ value: 'client_secret_value' })
106
+ .mockResolvedValueOnce({ value: 'redirect_uri_value' })
107
+ .mockResolvedValueOnce({ value: 'scope_value' });
106
108
 
107
109
  await handleEnvVariables(backendPath, modulePath);
108
110
 
109
- expect(output.info).toHaveBeenCalledWith(
111
+ expect(logInfo).toHaveBeenCalledWith(
110
112
  'Searching for missing environment variables...'
111
113
  );
112
- expect(output.warn).toHaveBeenCalledWith(
114
+ expect(logInfo).toHaveBeenCalledWith(
113
115
  'Missing environment variables: GOOGLE_CALENDAR_CLIENT_ID, GOOGLE_CALENDAR_CLIENT_SECRET, REDIRECT_URI, GOOGLE_CALENDAR_SCOPE'
114
116
  );
115
- expect(output.confirm).toHaveBeenCalledTimes(1);
116
- expect(output.input).toHaveBeenCalledTimes(4);
117
+ expect(inquirer.prompt).toHaveBeenCalledTimes(5);
117
118
  expect(fs.appendFileSync).toHaveBeenCalledWith(
118
119
  localEnvPath,
119
120
  '\nGOOGLE_CALENDAR_CLIENT_ID=client_id_value\nGOOGLE_CALENDAR_CLIENT_SECRET=client_secret_value\nREDIRECT_URI=redirect_uri_value\nGOOGLE_CALENDAR_SCOPE=scope_value'
@@ -2,7 +2,7 @@ const { installPackage } = require('./install-package');
2
2
  const { createIntegrationFile } = require('./integration-file');
3
3
  const { resolve } = require('node:path');
4
4
  const { updateBackendJsFile } = require('./backend-js');
5
- const output = require('../utils/output');
5
+ const { logInfo, logError } = require('./logger');
6
6
  const { commitChanges } = require('./commit-changes');
7
7
  const { handleEnvVariables } = require('./environment-variables');
8
8
  const {
@@ -35,23 +35,18 @@ const installCommand = async (apiModuleName) => {
35
35
  const sanitizedLabel = label.replace(
36
36
  /[<>:"/\\|?*\x00-\x1F\s]/g,
37
37
  ''
38
- ); // Remove invalid characters and spaces
39
-
40
- const spinner = output.spinner(`Installing integration for ${sanitizedLabel}...`);
41
- try {
42
- createIntegrationFile(backendPath, sanitizedLabel, ApiClass);
43
- updateBackendJsFile(backendPath, sanitizedLabel);
44
- commitChanges(backendPath, sanitizedLabel);
45
- spinner.succeed(`Successfully installed ${packageName} and updated the project.`);
46
- } catch (innerError) {
47
- spinner.fail(`Failed to install ${packageName}`);
48
- throw innerError;
49
- }
38
+ ); // Remove invalid characters and spaces console.log('Installing integration for:', sanitizedLabel);
39
+ createIntegrationFile(backendPath, sanitizedLabel, ApiClass);
40
+ updateBackendJsFile(backendPath, sanitizedLabel);
41
+ commitChanges(backendPath, sanitizedLabel);
42
+ logInfo(
43
+ `Successfully installed ${packageName} and updated the project.`
44
+ );
50
45
 
51
46
  await handleEnvVariables(backendPath, modulePath);
52
47
  }
53
48
  } catch (error) {
54
- output.error('An error occurred:', error);
49
+ logError('An error occurred:', error);
55
50
  process.exit(1);
56
51
  }
57
52
  };
@@ -1,6 +1,6 @@
1
1
  const fs = require('fs-extra');
2
2
  const path = require('path');
3
- const output = require('../utils/output');
3
+ const { logInfo } = require('./logger');
4
4
  const { getIntegrationTemplate } = require('./template');
5
5
  const INTEGRATIONS_DIR = 'src/integrations';
6
6
 
@@ -9,14 +9,14 @@ function createIntegrationFile(backendPath, apiModuleName, ApiClass) {
9
9
  path.dirname(backendPath),
10
10
  INTEGRATIONS_DIR
11
11
  );
12
- output.debug(`Ensuring directory exists: ${integrationDir}`);
12
+ logInfo(`Ensuring directory exists: ${integrationDir}`);
13
13
  fs.ensureDirSync(integrationDir);
14
14
 
15
15
  const integrationFilePath = path.join(
16
16
  integrationDir,
17
17
  `${apiModuleName}Integration.js`
18
18
  );
19
- output.debug(`Writing integration file: ${integrationFilePath}`);
19
+ logInfo(`Writing integration file: ${integrationFilePath}`);
20
20
  const integrationTemplate = getIntegrationTemplate(
21
21
  apiModuleName,
22
22
  backendPath,
@@ -0,0 +1,12 @@
1
+ function logInfo(message) {
2
+ console.log(message);
3
+ }
4
+
5
+ function logError(message, error) {
6
+ console.error(message, error);
7
+ }
8
+
9
+ module.exports = {
10
+ logInfo,
11
+ logError,
12
+ };
@@ -1,6 +1,7 @@
1
1
  const { execSync } = require('child_process');
2
2
  const axios = require('axios');
3
- const output = require('../utils/output');
3
+ const { logError } = require('./logger');
4
+ const { checkbox } = require('@inquirer/prompts');
4
5
 
5
6
  async function searchPackages(apiModuleName) {
6
7
  const searchCommand = `npm search @friggframework/api-module-${apiModuleName} --json`;
@@ -30,7 +31,7 @@ const searchAndSelectPackage = async (apiModuleName) => {
30
31
  const searchResults = await searchPackages(apiModuleName || '');
31
32
 
32
33
  if (searchResults.length === 0) {
33
- output.error(`No packages found matching ${apiModuleName}`);
34
+ logError(`No packages found matching ${apiModuleName}`);
34
35
  process.exit(1);
35
36
  }
36
37
 
@@ -43,7 +44,7 @@ const searchAndSelectPackage = async (apiModuleName) => {
43
44
  const earlierVersions = searchResults
44
45
  .map((pkg) => `${pkg.name} (${pkg.version})`)
45
46
  .join(', ');
46
- output.error(
47
+ logError(
47
48
  `No packages found with version 1.0.0 or above for ${apiModuleName}. Found earlier versions: ${earlierVersions}`
48
49
  );
49
50
  process.exit(1);
@@ -57,8 +58,11 @@ const searchAndSelectPackage = async (apiModuleName) => {
57
58
  };
58
59
  });
59
60
 
60
- const selectedPackages = await output.checkbox('Select the packages to install:', choices);
61
- output.info(`Selected packages: ${selectedPackages.join(', ')}`);
61
+ const selectedPackages = await checkbox({
62
+ message: 'Select the packages to install:',
63
+ choices,
64
+ });
65
+ console.log('Selected packages:', selectedPackages);
62
66
 
63
67
  return selectedPackages.map((choice) => choice.split(' ')[0]);
64
68
  };
@@ -1,8 +1,5 @@
1
- const path = require('path');
2
-
3
1
  module.exports = {
4
2
  displayName: 'Frigg CLI Tests',
5
- rootDir: __dirname,
6
3
  testMatch: [
7
4
  '<rootDir>/__tests__/**/*.test.js',
8
5
  '<rootDir>/__tests__/**/*.spec.js',
@@ -96,7 +93,7 @@ module.exports = {
96
93
  }
97
94
  },
98
95
  setupFilesAfterEnv: [
99
- path.join(__dirname, '__tests__', 'utils', 'test-setup.js')
96
+ '<rootDir>/__tests__/utils/test-setup.js'
100
97
  ],
101
98
  testTimeout: 10000,
102
99
  maxWorkers: '50%',