@friggframework/devtools 2.0.0--canary.424.a864ff6.0 → 2.0.0--canary.419.daed467.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.
@@ -12,27 +12,11 @@ const { uiCommand } = require('./ui-command');
12
12
  const program = new Command();
13
13
 
14
14
  program
15
- .command('init [projectName]')
15
+ .command('init [templateName]')
16
16
  .description('Initialize a new Frigg application')
17
- .option('-m, --mode <mode>', 'deployment mode (embedded|standalone)')
18
- .option('--frontend', 'include demo frontend')
19
- .option('--no-frontend', 'skip demo frontend')
20
- .option('--no-interactive', 'run without interactive prompts')
21
- .option('--non-interactive', 'run without interactive prompts (alias for --no-interactive)')
22
- .option('--yes', 'auto-accept all defaults (non-interactive mode)')
23
- .option('--app-purpose <purpose>', 'application purpose (own-app|platform|exploring)')
24
- .option('--include-integrations', 'include starter integrations')
25
- .option('--no-include-integrations', 'skip starter integrations')
26
- .option('--include-api-module', 'create custom API module')
27
- .option('--no-include-api-module', 'skip custom API module')
28
- .option('--serverless-provider <provider>', 'serverless provider (aws|local)')
29
- .option('--install-deps', 'install dependencies')
30
- .option('--no-install-deps', 'skip dependency installation')
31
- .option('--init-git', 'initialize git repository')
32
- .option('--no-init-git', 'skip git initialization')
33
- .option('--config <path>', 'configuration file path')
34
- .option('-f, --force', 'overwrite existing directory')
35
- .option('-v, --verbose', 'enable verbose output')
17
+ .option('-t, --template <template>', 'template to use', 'backend-only')
18
+ .option('-n, --name <name>', 'project name')
19
+ .option('-d, --directory <directory>', 'target directory')
36
20
  .action(initCommand);
37
21
 
38
22
  program
@@ -77,17 +61,6 @@ program
77
61
  .option('--no-open', 'do not open browser automatically')
78
62
  .action(uiCommand);
79
63
 
80
- if (require.main === module) {
81
- program.parse(process.argv);
82
- }
64
+ program.parse(process.argv);
83
65
 
84
- module.exports = {
85
- program,
86
- initCommand,
87
- installCommand,
88
- startCommand,
89
- buildCommand,
90
- deployCommand,
91
- generateIamCommand,
92
- uiCommand
93
- };
66
+ module.exports = { initCommand, installCommand, startCommand, buildCommand, deployCommand, generateIamCommand, uiCommand };
@@ -8,7 +8,7 @@ const { updateBackendJsFile } = require('./install-command/backend-js');
8
8
  const { commitChanges } = require('./install-command/commit-changes');
9
9
  const { logInfo, logError } = require('./install-command/logger');
10
10
 
11
- describe.skip('CLI Command Tests', () => {
11
+ describe('CLI Command Tests', () => {
12
12
  it('should successfully install an API module when all steps complete without errors', async () => {
13
13
  const mockApiModuleName = 'testModule';
14
14
  const mockPackageName = `@friggframework/api-module-${mockApiModuleName}`;
@@ -46,7 +46,7 @@ describe.skip('CLI Command Tests', () => {
46
46
  .description('Install an API module')
47
47
  .action(installCommand);
48
48
 
49
- await program.parseAsync(['node', 'test', 'install', mockApiModuleName]);
49
+ await program.parseAsync(['node', 'install', mockApiModuleName]);
50
50
 
51
51
  expect(validatePackageExists).toHaveBeenCalledWith(mockPackageName);
52
52
  expect(findNearestBackendPackageJson).toHaveBeenCalled();
@@ -94,7 +94,7 @@ describe.skip('CLI Command Tests', () => {
94
94
  .description('Install an API module')
95
95
  .action(installCommand);
96
96
 
97
- await program.parseAsync(['node', 'test', 'install', 'nonexistent-package']);
97
+ await program.parseAsync(['node', 'install', 'nonexistent-package']);
98
98
 
99
99
  expect(mockValidatePackageExists).toHaveBeenCalledWith(
100
100
  '@friggframework/api-module-nonexistent-package'
@@ -141,7 +141,7 @@ describe.skip('CLI Command Tests', () => {
141
141
  .description('Install an API module')
142
142
  .action(installCommand);
143
143
 
144
- await program.parseAsync(['node', 'test', 'install', 'test-module']);
144
+ await program.parseAsync(['node', 'install', 'test-module']);
145
145
 
146
146
  expect(mockLogError).toHaveBeenCalledWith(
147
147
  'An error occurred:',
@@ -14,7 +14,7 @@ class BackendFirstHandler {
14
14
  constructor(targetPath, options = {}) {
15
15
  this.targetPath = targetPath;
16
16
  this.appName = path.basename(targetPath);
17
- this.options = { interactive: true, ...options };
17
+ this.options = options;
18
18
  this.templatesDir = path.join(__dirname, '..', 'templates');
19
19
  }
20
20
 
@@ -36,8 +36,8 @@ class BackendFirstHandler {
36
36
 
37
37
  console.log(chalk.green('\n✅ Frigg application created successfully!'));
38
38
 
39
- // If user needs custom API module, prompt to create it (only in interactive mode)
40
- if (config.needsCustomApiModule && this.options.interactive && !this.options.nonInteractive) {
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?',
@@ -49,11 +49,6 @@ class BackendFirstHandler {
49
49
  console.log(chalk.cyan(` cd ${path.relative(process.cwd(), this.targetPath)}`));
50
50
  console.log(chalk.cyan(' frigg generate:api-module\n'));
51
51
  }
52
- } else if (config.needsCustomApiModule && (this.options.nonInteractive || !this.options.interactive)) {
53
- console.log(chalk.cyan('\n🔧 Custom API module needed'));
54
- console.log(chalk.gray('\n Run this command after setup:'));
55
- console.log(chalk.cyan(` cd ${path.relative(process.cwd(), this.targetPath)}`));
56
- console.log(chalk.cyan(' frigg generate:api-module\n'));
57
52
  }
58
53
 
59
54
  this.displayNextSteps(deploymentMode, config);
@@ -67,10 +62,6 @@ class BackendFirstHandler {
67
62
  return this.options.mode;
68
63
  }
69
64
 
70
- if (!this.options.interactive || this.options.nonInteractive) {
71
- return 'standalone';
72
- }
73
-
74
65
  const mode = await select({
75
66
  message: 'How will you deploy this Frigg application?',
76
67
  choices: [
@@ -91,42 +82,12 @@ class BackendFirstHandler {
91
82
  return mode;
92
83
  }
93
84
 
94
- /**
95
- * Get default configuration for non-interactive mode
96
- */
97
- getDefaultConfiguration(deploymentMode) {
98
- const config = {
99
- deploymentMode,
100
- appPurpose: this.options.appPurpose || 'exploring',
101
- needsCustomApiModule: this.options.includeApiModule || false,
102
- includeIntegrations: this.options.includeIntegrations || false,
103
- starterIntegrations: this.options.starterIntegrations || [],
104
- includeDemoFrontend: this.options.frontend === true,
105
- frontendFramework: this.options.frontendFramework || 'react',
106
- demoAuthMode: this.options.demoAuthMode || 'mock',
107
- serverlessProvider: this.options.serverlessProvider || (deploymentMode === 'standalone' ? 'aws' : undefined),
108
- installDependencies: this.options.installDependencies !== false,
109
- initializeGit: this.options.initializeGit !== false
110
- };
111
-
112
- // If app purpose is 'own-app' and no explicit API module setting, default to true
113
- if (config.appPurpose === 'own-app' && this.options.includeApiModule === undefined) {
114
- config.needsCustomApiModule = true;
115
- }
116
-
117
- return config;
118
- }
119
-
120
85
  /**
121
86
  * Get project configuration based on deployment mode
122
87
  */
123
88
  async getProjectConfiguration(deploymentMode) {
124
89
  const config = { deploymentMode };
125
90
 
126
- if (!this.options.interactive || this.options.nonInteractive) {
127
- return this.getDefaultConfiguration(deploymentMode);
128
- }
129
-
130
91
  // Ask about the purpose of this Frigg application
131
92
  config.appPurpose = await select({
132
93
  message: 'What are you building with Frigg?',
@@ -9,7 +9,6 @@
9
9
 
10
10
  const path = require('path');
11
11
  const chalk = require('chalk');
12
- const fs = require('fs-extra');
13
12
  const validateProjectName = require('validate-npm-package-name');
14
13
  const semver = require('semver');
15
14
  const BackendFirstHandler = require('./backend-first-handler');
@@ -55,10 +54,6 @@ async function initCommand(projectName, options) {
55
54
  const verbose = options.verbose || false;
56
55
  const force = options.force || false;
57
56
 
58
- // Handle non-interactive mode flags
59
- const nonInteractive = options.nonInteractive || options['no-interactive'] || options.yes || false;
60
- const interactive = !nonInteractive;
61
-
62
57
  checkNodeVersion();
63
58
 
64
59
  const root = path.resolve(projectName);
@@ -66,56 +61,15 @@ async function initCommand(projectName, options) {
66
61
 
67
62
  checkAppName(appName);
68
63
 
69
- // Load configuration from file if provided
70
- let configFromFile = {};
71
- if (options.config) {
72
- try {
73
- const configPath = path.resolve(options.config);
74
- if (await fs.pathExists(configPath)) {
75
- configFromFile = await fs.readJSON(configPath);
76
- } else {
77
- console.log(chalk.yellow(`Warning: Config file not found: ${configPath}`));
78
- }
79
- } catch (error) {
80
- console.log(chalk.yellow(`Warning: Could not load config file: ${error.message}`));
81
- }
82
- }
83
-
84
- // Merge options with environment variables and config file
85
- const mergedOptions = {
86
- force,
87
- verbose,
88
- mode: options.mode || process.env.FRIGG_DEPLOYMENT_MODE || configFromFile.deploymentMode,
89
- frontend: options.frontend !== undefined ? options.frontend :
90
- process.env.FRIGG_INCLUDE_FRONTEND !== undefined ? process.env.FRIGG_INCLUDE_FRONTEND === 'true' :
91
- configFromFile.includeFrontend,
92
- interactive,
93
- nonInteractive,
94
- appPurpose: options.appPurpose || process.env.FRIGG_APP_PURPOSE || configFromFile.appPurpose,
95
- includeIntegrations: options.includeIntegrations !== undefined ? options.includeIntegrations :
96
- process.env.FRIGG_INCLUDE_INTEGRATIONS !== undefined ? process.env.FRIGG_INCLUDE_INTEGRATIONS === 'true' :
97
- configFromFile.includeIntegrations,
98
- includeApiModule: options.includeApiModule !== undefined ? options.includeApiModule :
99
- process.env.FRIGG_INCLUDE_API_MODULE !== undefined ? process.env.FRIGG_INCLUDE_API_MODULE === 'true' :
100
- configFromFile.includeApiModule,
101
- serverlessProvider: options.serverlessProvider || process.env.FRIGG_SERVERLESS_PROVIDER || configFromFile.serverlessProvider,
102
- installDependencies: options.installDeps !== undefined ? options.installDeps :
103
- process.env.FRIGG_INSTALL_DEPS !== undefined ? process.env.FRIGG_INSTALL_DEPS === 'true' :
104
- configFromFile.installDependencies,
105
- initializeGit: options.initGit !== undefined ? options.initGit :
106
- process.env.FRIGG_INIT_GIT !== undefined ? process.env.FRIGG_INIT_GIT === 'true' :
107
- configFromFile.initializeGit,
108
- starterIntegrations: process.env.FRIGG_STARTER_INTEGRATIONS ?
109
- process.env.FRIGG_STARTER_INTEGRATIONS.split(',').map(s => s.trim()) :
110
- configFromFile.starterIntegrations,
111
- frontendFramework: process.env.FRIGG_FRONTEND_FRAMEWORK || configFromFile.frontendFramework,
112
- demoAuthMode: process.env.FRIGG_DEMO_AUTH_MODE || configFromFile.demoAuthMode
113
- };
114
-
115
64
  // Use backend-first handler by default
116
65
  if (!options.template && !options.legacyFrontend) {
117
66
  try {
118
- const handler = new BackendFirstHandler(root, mergedOptions);
67
+ const handler = new BackendFirstHandler(root, {
68
+ force,
69
+ verbose,
70
+ mode: options.mode,
71
+ frontend: options.frontend
72
+ });
119
73
 
120
74
  await handler.initialize();
121
75
  return;
@@ -128,89 +128,15 @@ describe('Init Command', () => {
128
128
  force: true,
129
129
  verbose: true,
130
130
  mode: 'standalone',
131
- frontend: false,
132
- interactive: false
131
+ frontend: false
133
132
  };
134
-
135
- await initCommand(mockProjectName, options);
136
-
137
- expect(BackendFirstHandler).toHaveBeenCalledWith(
138
- expect.any(String),
139
- expect.objectContaining({
140
- force: true,
141
- verbose: true,
142
- mode: 'standalone',
143
- frontend: false,
144
- interactive: true, // This gets set to true because interactive: false is not the same as nonInteractive: true
145
- nonInteractive: false
146
- })
147
- );
148
- });
149
-
150
- it('should handle non-interactive mode with --non-interactive flag', async () => {
151
- const options = {
152
- nonInteractive: true,
153
- mode: 'standalone',
154
- appPurpose: 'own-app'
155
- };
156
-
157
- await initCommand(mockProjectName, options);
158
-
159
- expect(BackendFirstHandler).toHaveBeenCalledWith(
160
- expect.any(String),
161
- expect.objectContaining({
162
- nonInteractive: true,
163
- interactive: false,
164
- mode: 'standalone',
165
- appPurpose: 'own-app'
166
- })
167
- );
168
- });
169
-
170
- it('should handle non-interactive mode with --yes flag', async () => {
171
- const options = {
172
- yes: true,
173
- mode: 'embedded'
174
- };
175
-
176
- await initCommand(mockProjectName, options);
177
-
178
- expect(BackendFirstHandler).toHaveBeenCalledWith(
179
- expect.any(String),
180
- expect.objectContaining({
181
- nonInteractive: true,
182
- interactive: false,
183
- mode: 'embedded'
184
- })
185
- );
186
- });
187
-
188
- it('should handle environment variables', async () => {
189
- const originalEnv = process.env.FRIGG_DEPLOYMENT_MODE;
190
- process.env.FRIGG_DEPLOYMENT_MODE = 'embedded';
191
- process.env.FRIGG_APP_PURPOSE = 'platform';
192
-
193
- const options = {
194
- nonInteractive: true
195
- };
196
-
133
+
197
134
  await initCommand(mockProjectName, options);
198
-
135
+
199
136
  expect(BackendFirstHandler).toHaveBeenCalledWith(
200
137
  expect.any(String),
201
- expect.objectContaining({
202
- mode: 'embedded',
203
- appPurpose: 'platform'
204
- })
138
+ expect.objectContaining(options)
205
139
  );
206
-
207
- // Clean up
208
- if (originalEnv !== undefined) {
209
- process.env.FRIGG_DEPLOYMENT_MODE = originalEnv;
210
- } else {
211
- delete process.env.FRIGG_DEPLOYMENT_MODE;
212
- }
213
- delete process.env.FRIGG_APP_PURPOSE;
214
140
  });
215
141
 
216
142
  it('should handle initialization errors gracefully', async () => {
@@ -2,7 +2,7 @@ const axios = require('axios');
2
2
 
3
3
  // Mock dependencies
4
4
  jest.mock('axios');
5
- jest.mock('node-cache', () => jest.fn(), { virtual: true });
5
+ jest.mock('node-cache');
6
6
 
7
7
  describe('NPMRegistryService', () => {
8
8
  let npmRegistry;