@friggframework/devtools 2.0.0--canary.424.a864ff6.0 → 2.0.0--canary.419.e387a34.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.
@@ -1,290 +0,0 @@
1
- # Frigg CLI Non-Interactive Mode
2
-
3
- This document describes the non-interactive mode implementation for the `frigg init` command, which enables automation, CI/CD pipelines, and Docker containerization.
4
-
5
- ## Overview
6
-
7
- The non-interactive mode allows you to initialize Frigg applications without user prompts, making it suitable for:
8
- - Automation scripts
9
- - CI/CD pipelines
10
- - Docker containerization
11
- - Infrastructure as Code
12
- - Developer onboarding automation
13
-
14
- ## Command Line Options
15
-
16
- ### Basic Non-Interactive Flags
17
-
18
- ```bash
19
- # Use --non-interactive flag
20
- frigg init my-project --non-interactive --mode standalone
21
-
22
- # Use --yes flag (alias for non-interactive with defaults)
23
- frigg init my-project --yes --mode standalone
24
-
25
- # Use --no-interactive flag (legacy support)
26
- frigg init my-project --no-interactive --mode standalone
27
- ```
28
-
29
- ### Configuration Options
30
-
31
- ```bash
32
- # Application purpose
33
- frigg init my-project --non-interactive --app-purpose own-app
34
- frigg init my-project --non-interactive --app-purpose platform
35
- frigg init my-project --non-interactive --app-purpose exploring
36
-
37
- # API module configuration
38
- frigg init my-project --non-interactive --include-api-module
39
- frigg init my-project --non-interactive --no-include-api-module
40
-
41
- # Integration configuration
42
- frigg init my-project --non-interactive --include-integrations
43
- frigg init my-project --non-interactive --no-include-integrations
44
-
45
- # Frontend configuration
46
- frigg init my-project --non-interactive --frontend
47
- frigg init my-project --non-interactive --no-frontend
48
-
49
- # Serverless provider
50
- frigg init my-project --non-interactive --serverless-provider aws
51
- frigg init my-project --non-interactive --serverless-provider local
52
-
53
- # Dependencies and Git
54
- frigg init my-project --non-interactive --install-deps
55
- frigg init my-project --non-interactive --no-install-deps
56
- frigg init my-project --non-interactive --init-git
57
- frigg init my-project --non-interactive --no-init-git
58
- ```
59
-
60
- ### Configuration File Support
61
-
62
- ```bash
63
- # Use configuration file
64
- frigg init my-project --config ./frigg-config.json --non-interactive
65
- ```
66
-
67
- Example configuration file (`frigg-config.json`):
68
- ```json
69
- {
70
- "deploymentMode": "standalone",
71
- "appPurpose": "own-app",
72
- "includeApiModule": true,
73
- "includeIntegrations": true,
74
- "starterIntegrations": ["salesforce", "hubspot"],
75
- "includeFrontend": false,
76
- "frontendFramework": "react",
77
- "demoAuthMode": "mock",
78
- "serverlessProvider": "aws",
79
- "installDependencies": true,
80
- "initializeGit": true
81
- }
82
- ```
83
-
84
- ## Environment Variables
85
-
86
- You can also configure the initialization using environment variables:
87
-
88
- ```bash
89
- # Set environment variables
90
- export FRIGG_DEPLOYMENT_MODE=standalone
91
- export FRIGG_APP_PURPOSE=own-app
92
- export FRIGG_INCLUDE_API_MODULE=true
93
- export FRIGG_INCLUDE_INTEGRATIONS=true
94
- export FRIGG_STARTER_INTEGRATIONS=salesforce,hubspot
95
- export FRIGG_INCLUDE_FRONTEND=false
96
- export FRIGG_FRONTEND_FRAMEWORK=react
97
- export FRIGG_DEMO_AUTH_MODE=mock
98
- export FRIGG_SERVERLESS_PROVIDER=aws
99
- export FRIGG_INSTALL_DEPS=true
100
- export FRIGG_INIT_GIT=true
101
-
102
- # Run init command
103
- frigg init my-project --non-interactive
104
- ```
105
-
106
- ### Available Environment Variables
107
-
108
- | Variable | Description | Values |
109
- |----------|-------------|---------|
110
- | `FRIGG_DEPLOYMENT_MODE` | Deployment mode | `standalone`, `embedded` |
111
- | `FRIGG_APP_PURPOSE` | Application purpose | `own-app`, `platform`, `exploring` |
112
- | `FRIGG_INCLUDE_API_MODULE` | Include custom API module | `true`, `false` |
113
- | `FRIGG_INCLUDE_INTEGRATIONS` | Include starter integrations | `true`, `false` |
114
- | `FRIGG_STARTER_INTEGRATIONS` | Comma-separated list of integrations | `salesforce,hubspot,slack` |
115
- | `FRIGG_INCLUDE_FRONTEND` | Include demo frontend | `true`, `false` |
116
- | `FRIGG_FRONTEND_FRAMEWORK` | Frontend framework | `react`, `vue`, `svelte`, `angular` |
117
- | `FRIGG_DEMO_AUTH_MODE` | Demo authentication mode | `mock`, `real` |
118
- | `FRIGG_SERVERLESS_PROVIDER` | Serverless provider | `aws`, `local` |
119
- | `FRIGG_INSTALL_DEPS` | Install dependencies | `true`, `false` |
120
- | `FRIGG_INIT_GIT` | Initialize Git repository | `true`, `false` |
121
-
122
- ## Default Configuration
123
-
124
- When using non-interactive mode without explicit configuration, the following defaults are used:
125
-
126
- ```javascript
127
- {
128
- deploymentMode: 'standalone',
129
- appPurpose: 'exploring',
130
- needsCustomApiModule: false,
131
- includeIntegrations: false,
132
- starterIntegrations: [],
133
- includeDemoFrontend: false,
134
- frontendFramework: 'react',
135
- demoAuthMode: 'mock',
136
- serverlessProvider: 'aws', // for standalone mode
137
- installDependencies: true,
138
- initializeGit: true
139
- }
140
- ```
141
-
142
- ## Examples
143
-
144
- ### Basic Non-Interactive Setup
145
-
146
- ```bash
147
- # Minimal setup for exploring Frigg
148
- frigg init my-project --non-interactive
149
-
150
- # Standalone application for own use
151
- frigg init my-project --non-interactive --mode standalone --app-purpose own-app
152
-
153
- # Platform application with integrations
154
- frigg init my-project --non-interactive --mode standalone --app-purpose platform --include-integrations
155
- ```
156
-
157
- ### CI/CD Pipeline Example
158
-
159
- ```bash
160
- #!/bin/bash
161
- # CI/CD pipeline script
162
-
163
- # Set configuration via environment variables
164
- export FRIGG_DEPLOYMENT_MODE=standalone
165
- export FRIGG_APP_PURPOSE=own-app
166
- export FRIGG_INCLUDE_API_MODULE=true
167
- export FRIGG_INCLUDE_INTEGRATIONS=true
168
- export FRIGG_STARTER_INTEGRATIONS=salesforce,hubspot
169
- export FRIGG_INSTALL_DEPS=true
170
- export FRIGG_INIT_GIT=true
171
-
172
- # Initialize Frigg application
173
- frigg init my-frigg-app --non-interactive
174
-
175
- # Build and deploy
176
- cd my-frigg-app
177
- npm run build
178
- npm run deploy
179
- ```
180
-
181
- ### Docker Containerization Example
182
-
183
- ```dockerfile
184
- FROM node:18-alpine
185
-
186
- # Install Frigg CLI
187
- RUN npm install -g @friggframework/devtools
188
-
189
- # Set non-interactive configuration
190
- ENV FRIGG_DEPLOYMENT_MODE=standalone
191
- ENV FRIGG_APP_PURPOSE=platform
192
- ENV FRIGG_INCLUDE_INTEGRATIONS=true
193
- ENV FRIGG_INSTALL_DEPS=true
194
- ENV FRIGG_INIT_GIT=false
195
-
196
- # Initialize Frigg application
197
- RUN frigg init my-app --non-interactive
198
-
199
- WORKDIR /my-app
200
- EXPOSE 3001
201
-
202
- CMD ["npm", "start"]
203
- ```
204
-
205
- ### Configuration File Example
206
-
207
- ```bash
208
- # Create configuration file
209
- cat > frigg-config.json << EOF
210
- {
211
- "deploymentMode": "standalone",
212
- "appPurpose": "platform",
213
- "includeApiModule": false,
214
- "includeIntegrations": true,
215
- "starterIntegrations": ["salesforce", "hubspot", "slack"],
216
- "includeFrontend": true,
217
- "frontendFramework": "react",
218
- "demoAuthMode": "mock",
219
- "serverlessProvider": "aws",
220
- "installDependencies": true,
221
- "initializeGit": true
222
- }
223
- EOF
224
-
225
- # Use configuration file
226
- frigg init my-platform --config frigg-config.json --non-interactive
227
- ```
228
-
229
- ## Error Handling
230
-
231
- The non-interactive mode includes proper error handling:
232
-
233
- - **Missing templates**: Creates basic templates if they don't exist
234
- - **Invalid configuration**: Shows clear error messages and exits gracefully
235
- - **Dependency issues**: Continues with warnings if dependency installation fails
236
- - **Git initialization**: Continues if Git initialization fails (not critical)
237
-
238
- ## Testing
239
-
240
- The non-interactive mode is thoroughly tested with:
241
-
242
- - Unit tests for configuration merging
243
- - Integration tests for command-line options
244
- - Environment variable testing
245
- - Configuration file testing
246
- - Error handling scenarios
247
-
248
- Run tests with:
249
- ```bash
250
- npm test -- --testPathPattern="init-command"
251
- ```
252
-
253
- ## Migration from Interactive Mode
254
-
255
- If you have existing scripts using interactive mode, you can migrate them by:
256
-
257
- 1. Adding `--non-interactive` flag
258
- 2. Specifying required options explicitly
259
- 3. Using environment variables for configuration
260
- 4. Creating configuration files for complex setups
261
-
262
- ## Troubleshooting
263
-
264
- ### Common Issues
265
-
266
- 1. **Command hangs**: Make sure you're using `--non-interactive` or `--yes` flag
267
- 2. **Missing templates**: The CLI will create basic templates automatically
268
- 3. **Dependency errors**: Check that you're in a valid Node.js environment
269
- 4. **Configuration conflicts**: Command-line options override environment variables and config files
270
-
271
- ### Debug Mode
272
-
273
- Use `--verbose` flag for detailed output:
274
- ```bash
275
- frigg init my-project --non-interactive --verbose
276
- ```
277
-
278
- ## Implementation Details
279
-
280
- The non-interactive mode is implemented in:
281
-
282
- - `init-command/index.js`: Command-line option parsing and configuration merging
283
- - `init-command/backend-first-handler.js`: Non-interactive logic and default configuration
284
- - `index.js`: CLI argument definitions
285
-
286
- Key features:
287
- - Configuration precedence: CLI options > Environment variables > Config file > Defaults
288
- - Graceful error handling
289
- - Comprehensive testing
290
- - Backward compatibility with existing interactive mode
@@ -1,207 +0,0 @@
1
- const path = require('path');
2
- const fs = require('fs-extra');
3
- const BackendFirstHandler = require('../../../init-command/backend-first-handler');
4
-
5
- // Mock dependencies
6
- jest.mock('fs-extra');
7
- jest.mock('chalk', () => ({
8
- blue: jest.fn(text => text),
9
- green: jest.fn(text => text),
10
- red: jest.fn(text => text),
11
- yellow: jest.fn(text => text),
12
- gray: jest.fn(text => text),
13
- cyan: jest.fn(text => text),
14
- bold: jest.fn(text => text)
15
- }));
16
- jest.mock('@inquirer/prompts');
17
- jest.mock('child_process');
18
- jest.mock('cross-spawn');
19
- jest.mock('../../../utils/npm-registry');
20
- jest.mock('@friggframework/schemas');
21
-
22
- describe('BackendFirstHandler', () => {
23
- const mockTargetPath = '/test/project/path';
24
- let mockConsoleLog;
25
- let mockConsoleError;
26
-
27
- beforeEach(() => {
28
- jest.clearAllMocks();
29
-
30
- // Mock console methods
31
- mockConsoleLog = jest.spyOn(console, 'log').mockImplementation();
32
- mockConsoleError = jest.spyOn(console, 'error').mockImplementation();
33
-
34
- // Mock fs-extra methods
35
- const fs = require('fs-extra');
36
- fs.ensureDir.mockResolvedValue();
37
- fs.pathExists.mockResolvedValue(false);
38
- fs.readdir.mockResolvedValue([]);
39
- fs.writeFile.mockResolvedValue();
40
- fs.writeJSON.mockResolvedValue();
41
- fs.readFile.mockResolvedValue('mock content');
42
- fs.copy.mockResolvedValue();
43
- fs.ensureDirSync.mockImplementation();
44
- fs.readdirSync.mockReturnValue([]);
45
- fs.writeFileSync.mockImplementation();
46
- fs.lstatSync.mockReturnValue({ isDirectory: () => false });
47
- });
48
-
49
- afterEach(() => {
50
- mockConsoleLog.mockRestore();
51
- mockConsoleError.mockRestore();
52
- });
53
-
54
- describe('Non-Interactive Mode', () => {
55
- it('should use default configuration in non-interactive mode', () => {
56
- const options = {
57
- nonInteractive: true,
58
- mode: 'standalone',
59
- appPurpose: 'own-app'
60
- };
61
-
62
- const handler = new BackendFirstHandler(mockTargetPath, options);
63
- const config = handler.getDefaultConfiguration('standalone');
64
-
65
- expect(config).toEqual({
66
- deploymentMode: 'standalone',
67
- appPurpose: 'own-app',
68
- needsCustomApiModule: true, // Should default to true for 'own-app'
69
- includeIntegrations: false,
70
- starterIntegrations: [],
71
- includeDemoFrontend: false,
72
- frontendFramework: 'react',
73
- demoAuthMode: 'mock',
74
- serverlessProvider: 'aws',
75
- installDependencies: true,
76
- initializeGit: true
77
- });
78
- });
79
-
80
- it('should use provided options in non-interactive mode', () => {
81
- const options = {
82
- nonInteractive: true,
83
- mode: 'embedded',
84
- appPurpose: 'platform',
85
- includeApiModule: false,
86
- includeIntegrations: true,
87
- starterIntegrations: ['salesforce', 'hubspot'],
88
- frontend: true,
89
- frontendFramework: 'vue',
90
- demoAuthMode: 'real',
91
- serverlessProvider: 'local',
92
- installDependencies: false,
93
- initializeGit: false
94
- };
95
-
96
- const handler = new BackendFirstHandler(mockTargetPath, options);
97
- const config = handler.getDefaultConfiguration('embedded');
98
-
99
- expect(config).toEqual({
100
- deploymentMode: 'embedded',
101
- appPurpose: 'platform',
102
- needsCustomApiModule: false,
103
- includeIntegrations: true,
104
- starterIntegrations: ['salesforce', 'hubspot'],
105
- includeDemoFrontend: true,
106
- frontendFramework: 'vue',
107
- demoAuthMode: 'real',
108
- serverlessProvider: 'local',
109
- installDependencies: false,
110
- initializeGit: false
111
- });
112
- });
113
-
114
- it('should default to exploring mode when no app purpose specified', () => {
115
- const options = {
116
- nonInteractive: true,
117
- mode: 'standalone'
118
- };
119
-
120
- const handler = new BackendFirstHandler(mockTargetPath, options);
121
- const config = handler.getDefaultConfiguration('standalone');
122
-
123
- expect(config.appPurpose).toBe('exploring');
124
- expect(config.needsCustomApiModule).toBe(false);
125
- });
126
-
127
- it('should handle undefined options gracefully', () => {
128
- const options = {
129
- nonInteractive: true
130
- };
131
-
132
- const handler = new BackendFirstHandler(mockTargetPath, options);
133
- const config = handler.getDefaultConfiguration('standalone');
134
-
135
- expect(config).toEqual({
136
- deploymentMode: 'standalone',
137
- appPurpose: 'exploring',
138
- needsCustomApiModule: false,
139
- includeIntegrations: false,
140
- starterIntegrations: [],
141
- includeDemoFrontend: false,
142
- frontendFramework: 'react',
143
- demoAuthMode: 'mock',
144
- serverlessProvider: 'aws',
145
- installDependencies: true,
146
- initializeGit: true
147
- });
148
- });
149
- });
150
-
151
- describe('Interactive Mode', () => {
152
- it('should use interactive prompts when interactive is true', async () => {
153
- const { select, confirm, multiselect } = require('@inquirer/prompts');
154
-
155
- // Mock the prompts
156
- select.mockResolvedValue('standalone');
157
- confirm.mockResolvedValue(true);
158
- if (multiselect) {
159
- multiselect.mockResolvedValue(['salesforce']);
160
- }
161
-
162
- const options = {
163
- interactive: true,
164
- nonInteractive: false
165
- };
166
-
167
- const handler = new BackendFirstHandler(mockTargetPath, options);
168
-
169
- // Mock the initialize method to avoid full execution
170
- const initializeSpy = jest.spyOn(handler, 'initialize').mockResolvedValue();
171
-
172
- await handler.initialize();
173
-
174
- expect(initializeSpy).toHaveBeenCalled();
175
- });
176
- });
177
-
178
- describe('Configuration Merging', () => {
179
- it('should merge options with defaults correctly', () => {
180
- const options = {
181
- nonInteractive: true,
182
- mode: 'standalone',
183
- appPurpose: 'own-app',
184
- includeApiModule: true,
185
- includeIntegrations: true,
186
- starterIntegrations: ['salesforce'],
187
- frontend: true,
188
- frontendFramework: 'angular',
189
- demoAuthMode: 'real',
190
- serverlessProvider: 'aws',
191
- installDependencies: true,
192
- initializeGit: true
193
- };
194
-
195
- const handler = new BackendFirstHandler(mockTargetPath, options);
196
- const config = handler.getDefaultConfiguration('standalone');
197
-
198
- expect(config.appPurpose).toBe('own-app');
199
- expect(config.needsCustomApiModule).toBe(true);
200
- expect(config.includeIntegrations).toBe(true);
201
- expect(config.starterIntegrations).toEqual(['salesforce']);
202
- expect(config.includeDemoFrontend).toBe(true);
203
- expect(config.frontendFramework).toBe('angular');
204
- expect(config.demoAuthMode).toBe('real');
205
- });
206
- });
207
- });
@@ -1,13 +0,0 @@
1
- {
2
- "deploymentMode": "standalone",
3
- "appPurpose": "own-app",
4
- "includeApiModule": true,
5
- "includeIntegrations": true,
6
- "starterIntegrations": ["salesforce", "hubspot"],
7
- "includeFrontend": false,
8
- "frontendFramework": "react",
9
- "demoAuthMode": "mock",
10
- "serverlessProvider": "aws",
11
- "installDependencies": true,
12
- "initializeGit": true
13
- }
@@ -1,42 +0,0 @@
1
- /**
2
- * Frigg Application Definition
3
- *
4
- * This file defines your Frigg application configuration.
5
- * Modify the integrations array to include the API modules you want to use.
6
- */
7
-
8
- // Import your integrations here
9
- // const ExampleIntegration = require('./src/integrations/ExampleIntegration');
10
-
11
- const appDefinition = {
12
- integrations: [
13
- // Add your integrations here as you install them
14
- // Example:
15
- // ExampleIntegration,
16
- ],
17
- user: {
18
- password: true
19
- },
20
- encryption: {
21
- useDefaultKMSForFieldLevelEncryption: true
22
- },
23
- vpc: {
24
- enable: true
25
- },
26
- security: {
27
- cors: {
28
- origin: 'http://localhost:3000',
29
- credentials: true
30
- }
31
- },
32
- logging: {
33
- level: 'info'
34
- },
35
- custom: {
36
- appName: 'My Frigg Application',
37
- version: '1.0.0',
38
- environment: 'development'
39
- }
40
- };
41
-
42
- module.exports = appDefinition;
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Frigg Infrastructure Management
5
- *
6
- * This script handles starting, building, and deploying your Frigg application.
7
- */
8
-
9
- const { spawn } = require('child_process');
10
- const path = require('path');
11
-
12
- const command = process.argv[2];
13
-
14
- switch (command) {
15
- case 'start':
16
- console.log('Starting Frigg backend...');
17
- // In a real implementation, this would start the Frigg backend
18
- console.log('Backend started on http://localhost:3001');
19
- break;
20
-
21
- case 'package':
22
- console.log('Packaging Frigg application...');
23
- // In a real implementation, this would package the application
24
- console.log('Application packaged successfully');
25
- break;
26
-
27
- case 'deploy':
28
- console.log('Deploying Frigg application...');
29
- // In a real implementation, this would deploy to AWS Lambda
30
- console.log('Application deployed successfully');
31
- break;
32
-
33
- default:
34
- console.log('Usage: node infrastructure.js [start|package|deploy]');
35
- process.exit(1);
36
- }
@@ -1,18 +0,0 @@
1
- {
2
- "name": "frigg-backend-template",
3
- "version": "1.0.0",
4
- "description": "Frigg backend application template",
5
- "main": "index.js",
6
- "scripts": {
7
- "start": "node infrastructure.js start",
8
- "build": "node infrastructure.js package",
9
- "deploy": "node infrastructure.js deploy"
10
- },
11
- "dependencies": {
12
- "@friggframework/core": "^2.0.0"
13
- },
14
- "devDependencies": {
15
- "serverless": "^3.0.0",
16
- "serverless-offline": "^12.0.0"
17
- }
18
- }
@@ -1,25 +0,0 @@
1
- service: frigg-application
2
-
3
- provider:
4
- name: aws
5
- runtime: nodejs18.x
6
- stage: ${opt:stage, 'dev'}
7
- region: ${opt:region, 'us-east-1'}
8
- environment:
9
- NODE_ENV: ${self:provider.stage}
10
-
11
- functions:
12
- api:
13
- handler: index.handler
14
- events:
15
- - http:
16
- path: /{proxy+}
17
- method: ANY
18
- cors: true
19
-
20
- plugins:
21
- - serverless-offline
22
-
23
- custom:
24
- serverless-offline:
25
- httpPort: 3001
@@ -1,48 +0,0 @@
1
- const { Command } = require('commander');
2
-
3
- describe('frigg CLI init command', () => {
4
- const setupProgram = action => {
5
- const program = new Command();
6
- program
7
- .command('init [projectName]')
8
- .option('-m, --mode <mode>', 'deployment mode (embedded|standalone)')
9
- .option('--frontend', 'include demo frontend')
10
- .option('--no-frontend', 'skip demo frontend')
11
- .option('--no-interactive', 'run without interactive prompts')
12
- .option('-f, --force', 'overwrite existing directory')
13
- .option('-v, --verbose', 'enable verbose output')
14
- .action(action);
15
- return program;
16
- };
17
-
18
- it('parses flags and forwards them to initCommand', async () => {
19
- const mockInit = jest.fn();
20
- const program = setupProgram(mockInit);
21
-
22
- await program.parseAsync([
23
- 'node',
24
- 'test',
25
- 'init',
26
- 'my-app',
27
- '--mode',
28
- 'standalone',
29
- '--no-frontend',
30
- '--no-interactive',
31
- '--force',
32
- '--verbose'
33
- ]);
34
-
35
- expect(mockInit).toHaveBeenCalledWith(
36
- 'my-app',
37
- expect.objectContaining({
38
- mode: 'standalone',
39
- frontend: false,
40
- interactive: false,
41
- force: true,
42
- verbose: true
43
- }),
44
- expect.anything()
45
- );
46
- });
47
- });
48
-