@friggframework/devtools 2.0.0--canary.522.923dfae.0 ā 2.0.0--canary.540.c5ef83f.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.
- package/frigg-cli/README.md +1 -1
- package/frigg-cli/__tests__/unit/commands/doctor.test.js +2 -0
- package/frigg-cli/__tests__/unit/commands/install.test.js +19 -23
- package/frigg-cli/__tests__/unit/dependencies.test.js +2 -2
- package/frigg-cli/doctor-command/index.js +16 -17
- package/frigg-cli/index.js +6 -21
- package/frigg-cli/index.test.js +2 -7
- package/frigg-cli/init-command/backend-first-handler.js +42 -124
- package/frigg-cli/init-command/index.js +1 -2
- package/frigg-cli/init-command/template-handler.js +3 -13
- package/frigg-cli/install-command/backend-js.js +3 -3
- package/frigg-cli/install-command/environment-variables.js +19 -16
- package/frigg-cli/install-command/environment-variables.test.js +13 -12
- package/frigg-cli/install-command/index.js +9 -14
- package/frigg-cli/install-command/integration-file.js +3 -3
- package/frigg-cli/install-command/logger.js +12 -0
- package/frigg-cli/install-command/validate-package.js +9 -5
- package/frigg-cli/jest.config.js +1 -4
- package/frigg-cli/repair-command/index.js +128 -101
- package/frigg-cli/start-command/index.js +2 -246
- package/frigg-cli/ui-command/index.js +36 -58
- package/frigg-cli/utils/repo-detection.js +37 -85
- package/infrastructure/docs/iam-policy-templates.md +1 -1
- package/infrastructure/domains/networking/vpc-builder.test.js +4 -2
- package/infrastructure/domains/networking/vpc-resolver.test.js +1 -1
- package/infrastructure/domains/shared/cloudformation-discovery.test.js +7 -4
- package/infrastructure/domains/shared/resource-discovery.js +5 -5
- package/infrastructure/domains/shared/types/app-definition.js +0 -21
- package/infrastructure/domains/shared/types/discovery-result.test.js +1 -1
- package/infrastructure/domains/shared/utilities/base-definition-factory.js +1 -10
- package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +2 -2
- package/infrastructure/infrastructure-composer.test.js +2 -2
- package/management-ui/README.md +109 -245
- package/package.json +7 -8
- package/frigg-cli/__tests__/application/use-cases/AddApiModuleToIntegrationUseCase.test.js +0 -326
- package/frigg-cli/__tests__/application/use-cases/CreateApiModuleUseCase.test.js +0 -337
- package/frigg-cli/__tests__/domain/entities/ApiModule.test.js +0 -373
- package/frigg-cli/__tests__/domain/entities/AppDefinition.test.js +0 -313
- package/frigg-cli/__tests__/domain/services/IntegrationValidator.test.js +0 -269
- package/frigg-cli/__tests__/domain/value-objects/IntegrationName.test.js +0 -82
- package/frigg-cli/__tests__/infrastructure/adapters/IntegrationJsUpdater.test.js +0 -408
- package/frigg-cli/__tests__/infrastructure/repositories/FileSystemApiModuleRepository.test.js +0 -583
- package/frigg-cli/__tests__/infrastructure/repositories/FileSystemAppDefinitionRepository.test.js +0 -314
- package/frigg-cli/__tests__/infrastructure/repositories/FileSystemIntegrationRepository.test.js +0 -383
- package/frigg-cli/__tests__/unit/commands/init.test.js +0 -406
- package/frigg-cli/__tests__/unit/commands/repair.test.js +0 -275
- package/frigg-cli/__tests__/unit/start-command/application/RunPreflightChecksUseCase.test.js +0 -411
- package/frigg-cli/__tests__/unit/start-command/infrastructure/DatabaseAdapter.test.js +0 -405
- package/frigg-cli/__tests__/unit/start-command/infrastructure/DockerAdapter.test.js +0 -496
- package/frigg-cli/__tests__/unit/start-command/presentation/InteractivePromptAdapter.test.js +0 -474
- package/frigg-cli/__tests__/unit/utils/output.test.js +0 -196
- package/frigg-cli/application/use-cases/AddApiModuleToIntegrationUseCase.js +0 -93
- package/frigg-cli/application/use-cases/CreateApiModuleUseCase.js +0 -93
- package/frigg-cli/application/use-cases/CreateIntegrationUseCase.js +0 -103
- package/frigg-cli/container.js +0 -172
- package/frigg-cli/docs/OUTPUT_MIGRATION_GUIDE.md +0 -286
- package/frigg-cli/domain/entities/ApiModule.js +0 -272
- package/frigg-cli/domain/entities/AppDefinition.js +0 -227
- package/frigg-cli/domain/entities/Integration.js +0 -198
- package/frigg-cli/domain/exceptions/DomainException.js +0 -24
- package/frigg-cli/domain/ports/IApiModuleRepository.js +0 -53
- package/frigg-cli/domain/ports/IAppDefinitionRepository.js +0 -43
- package/frigg-cli/domain/ports/IIntegrationRepository.js +0 -61
- package/frigg-cli/domain/services/IntegrationValidator.js +0 -185
- package/frigg-cli/domain/value-objects/IntegrationId.js +0 -42
- package/frigg-cli/domain/value-objects/IntegrationName.js +0 -60
- package/frigg-cli/domain/value-objects/SemanticVersion.js +0 -70
- package/frigg-cli/infrastructure/UnitOfWork.js +0 -46
- package/frigg-cli/infrastructure/adapters/BackendJsUpdater.js +0 -197
- package/frigg-cli/infrastructure/adapters/FileSystemAdapter.js +0 -224
- package/frigg-cli/infrastructure/adapters/IntegrationJsUpdater.js +0 -249
- package/frigg-cli/infrastructure/adapters/SchemaValidator.js +0 -92
- package/frigg-cli/infrastructure/repositories/FileSystemApiModuleRepository.js +0 -373
- package/frigg-cli/infrastructure/repositories/FileSystemAppDefinitionRepository.js +0 -116
- package/frigg-cli/infrastructure/repositories/FileSystemIntegrationRepository.js +0 -277
- package/frigg-cli/package-lock.json +0 -16226
- package/frigg-cli/start-command/application/RunPreflightChecksUseCase.js +0 -376
- package/frigg-cli/start-command/infrastructure/DatabaseAdapter.js +0 -591
- package/frigg-cli/start-command/infrastructure/DockerAdapter.js +0 -306
- package/frigg-cli/start-command/presentation/InteractivePromptAdapter.js +0 -329
- package/frigg-cli/templates/backend/.env.example +0 -62
- package/frigg-cli/templates/backend/.eslintrc.json +0 -12
- package/frigg-cli/templates/backend/.prettierrc +0 -6
- package/frigg-cli/templates/backend/docker-compose.yml +0 -22
- package/frigg-cli/templates/backend/index.js +0 -96
- package/frigg-cli/templates/backend/infrastructure.js +0 -12
- package/frigg-cli/templates/backend/jest.config.js +0 -17
- package/frigg-cli/templates/backend/package.json +0 -50
- package/frigg-cli/templates/backend/src/api-modules/.gitkeep +0 -10
- package/frigg-cli/templates/backend/src/base/.gitkeep +0 -7
- package/frigg-cli/templates/backend/src/integrations/.gitkeep +0 -10
- package/frigg-cli/templates/backend/src/integrations/ExampleIntegration.js +0 -65
- package/frigg-cli/templates/backend/src/utils/.gitkeep +0 -7
- package/frigg-cli/templates/backend/test/setup.js +0 -30
- package/frigg-cli/templates/backend/ui-extensions/.gitkeep +0 -0
- package/frigg-cli/templates/backend/ui-extensions/README.md +0 -77
- package/frigg-cli/utils/__tests__/repo-detection.test.js +0 -436
- package/frigg-cli/utils/output.js +0 -382
- package/frigg-cli/validate-command/__tests__/adapters/validate-command.test.js +0 -205
- package/frigg-cli/validate-command/__tests__/application/validate-app-use-case.test.js +0 -104
- package/frigg-cli/validate-command/__tests__/domain/fix-suggestion.test.js +0 -153
- package/frigg-cli/validate-command/__tests__/domain/validation-error.test.js +0 -162
- package/frigg-cli/validate-command/__tests__/domain/validation-result.test.js +0 -152
- package/frigg-cli/validate-command/__tests__/infrastructure/api-module-validator.test.js +0 -332
- package/frigg-cli/validate-command/__tests__/infrastructure/app-definition-validator.test.js +0 -191
- package/frigg-cli/validate-command/__tests__/infrastructure/integration-class-validator.test.js +0 -146
- package/frigg-cli/validate-command/__tests__/infrastructure/template-validation.test.js +0 -155
- package/frigg-cli/validate-command/adapters/cli/validate-command.js +0 -199
- package/frigg-cli/validate-command/application/use-cases/validate-app-use-case.js +0 -35
- package/frigg-cli/validate-command/domain/entities/validation-result.js +0 -74
- package/frigg-cli/validate-command/domain/value-objects/fix-suggestion.js +0 -74
- package/frigg-cli/validate-command/domain/value-objects/validation-error.js +0 -68
- package/frigg-cli/validate-command/infrastructure/validators/api-module-validator.js +0 -181
- package/frigg-cli/validate-command/infrastructure/validators/app-definition-validator.js +0 -128
- package/frigg-cli/validate-command/infrastructure/validators/integration-class-validator.js +0 -113
- package/infrastructure/domains/admin-scripts/admin-script-builder.js +0 -200
- package/infrastructure/domains/admin-scripts/admin-script-builder.test.js +0 -499
- package/infrastructure/domains/admin-scripts/index.js +0 -5
- package/infrastructure/jest.config.js +0 -16
package/frigg-cli/README.md
CHANGED
|
@@ -1281,7 +1281,7 @@ npm install @friggframework/frigg-cli@latest
|
|
|
1281
1281
|
npm install -g @friggframework/frigg-cli
|
|
1282
1282
|
|
|
1283
1283
|
# Local project dependencies
|
|
1284
|
-
frigg
|
|
1284
|
+
npx create-frigg-app my-app
|
|
1285
1285
|
# (Will automatically include @friggframework/frigg-cli in package.json)
|
|
1286
1286
|
```
|
|
1287
1287
|
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Tests stack listing, selection, and health check orchestration
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
const { describe, test, expect, jest, beforeEach } = require('@jest/globals');
|
|
7
|
+
|
|
6
8
|
describe('Doctor Command - Stack Listing and Selection', () => {
|
|
7
9
|
let mockCloudFormationClient;
|
|
8
10
|
let mockSelect;
|
|
@@ -26,7 +26,7 @@ jest.mock('../../../install-command/validate-package', () => ({
|
|
|
26
26
|
validatePackageExists: jest.fn(), // External: npm registry
|
|
27
27
|
searchAndSelectPackage: jest.fn() // External: interactive selection
|
|
28
28
|
}));
|
|
29
|
-
jest.mock('@friggframework/core
|
|
29
|
+
jest.mock('@friggframework/core', () => ({
|
|
30
30
|
findNearestBackendPackageJson: jest.fn(),
|
|
31
31
|
validateBackendPath: jest.fn()
|
|
32
32
|
}));
|
|
@@ -43,13 +43,13 @@ const { installPackage } = require('../../../install-command/install-package');
|
|
|
43
43
|
const { commitChanges } = require('../../../install-command/commit-changes');
|
|
44
44
|
const { handleEnvVariables } = require('../../../install-command/environment-variables');
|
|
45
45
|
const { validatePackageExists, searchAndSelectPackage } = require('../../../install-command/validate-package');
|
|
46
|
-
const { findNearestBackendPackageJson, validateBackendPath } = require('@friggframework/core
|
|
46
|
+
const { findNearestBackendPackageJson, validateBackendPath } = require('@friggframework/core');
|
|
47
47
|
const { installCommand } = require('../../../install-command');
|
|
48
|
-
const output = require('../../../utils/output');
|
|
49
48
|
|
|
50
49
|
describe('CLI Command: install', () => {
|
|
51
50
|
let processExitSpy;
|
|
52
|
-
|
|
51
|
+
let consoleLogSpy;
|
|
52
|
+
let consoleErrorSpy;
|
|
53
53
|
const mockBackendPath = '/mock/backend/package.json';
|
|
54
54
|
const mockBackendDir = '/mock/backend';
|
|
55
55
|
|
|
@@ -59,14 +59,9 @@ describe('CLI Command: install', () => {
|
|
|
59
59
|
// Mock process.exit to prevent actual exit
|
|
60
60
|
processExitSpy = jest.spyOn(process, 'exit').mockImplementation();
|
|
61
61
|
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
output.spinner = jest.fn().mockReturnValue({
|
|
66
|
-
start: jest.fn(),
|
|
67
|
-
succeed: jest.fn(),
|
|
68
|
-
fail: jest.fn()
|
|
69
|
-
});
|
|
62
|
+
// Spy on console for logger (don't mock logger - test it!)
|
|
63
|
+
consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
64
|
+
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
70
65
|
|
|
71
66
|
// Setup fs-extra mocks - Let Frigg code run, just mock I/O
|
|
72
67
|
fs.ensureDirSync = jest.fn();
|
|
@@ -103,7 +98,8 @@ describe('CLI Command: install', () => {
|
|
|
103
98
|
|
|
104
99
|
afterEach(() => {
|
|
105
100
|
processExitSpy.mockRestore();
|
|
106
|
-
|
|
101
|
+
consoleLogSpy.mockRestore();
|
|
102
|
+
consoleErrorSpy.mockRestore();
|
|
107
103
|
jest.resetModules(); // Clear module cache after each test
|
|
108
104
|
});
|
|
109
105
|
|
|
@@ -209,9 +205,9 @@ describe('CLI Command: install', () => {
|
|
|
209
205
|
it('should log info messages during installation', async () => {
|
|
210
206
|
await installCommand('slack');
|
|
211
207
|
|
|
212
|
-
// Verify
|
|
213
|
-
expect(
|
|
214
|
-
expect.stringContaining('
|
|
208
|
+
// Verify logger actually logged (we spy on console)
|
|
209
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
210
|
+
expect.stringContaining('Successfully installed @friggframework/api-module-slack')
|
|
215
211
|
);
|
|
216
212
|
});
|
|
217
213
|
|
|
@@ -338,8 +334,8 @@ describe('CLI Command: install', () => {
|
|
|
338
334
|
|
|
339
335
|
await installCommand('slack');
|
|
340
336
|
|
|
341
|
-
// Verify error logged via
|
|
342
|
-
expect(
|
|
337
|
+
// Verify error logged via console.error (we spy on it)
|
|
338
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('An error occurred:', error);
|
|
343
339
|
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
344
340
|
});
|
|
345
341
|
|
|
@@ -349,7 +345,7 @@ describe('CLI Command: install', () => {
|
|
|
349
345
|
|
|
350
346
|
await installCommand('slack');
|
|
351
347
|
|
|
352
|
-
expect(
|
|
348
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('An error occurred:', error);
|
|
353
349
|
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
354
350
|
});
|
|
355
351
|
|
|
@@ -361,7 +357,7 @@ describe('CLI Command: install', () => {
|
|
|
361
357
|
|
|
362
358
|
await installCommand('slack');
|
|
363
359
|
|
|
364
|
-
expect(
|
|
360
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('An error occurred:', error);
|
|
365
361
|
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
366
362
|
});
|
|
367
363
|
|
|
@@ -374,7 +370,7 @@ describe('CLI Command: install', () => {
|
|
|
374
370
|
|
|
375
371
|
await installCommand('slack');
|
|
376
372
|
|
|
377
|
-
expect(
|
|
373
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('An error occurred:', expect.any(Error));
|
|
378
374
|
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
379
375
|
});
|
|
380
376
|
|
|
@@ -387,7 +383,7 @@ describe('CLI Command: install', () => {
|
|
|
387
383
|
|
|
388
384
|
await installCommand('slack');
|
|
389
385
|
|
|
390
|
-
expect(
|
|
386
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('An error occurred:', expect.any(Error));
|
|
391
387
|
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
392
388
|
});
|
|
393
389
|
|
|
@@ -397,7 +393,7 @@ describe('CLI Command: install', () => {
|
|
|
397
393
|
|
|
398
394
|
await installCommand('slack');
|
|
399
395
|
|
|
400
|
-
expect(
|
|
396
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('An error occurred:', error);
|
|
401
397
|
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
402
398
|
});
|
|
403
399
|
});
|
|
@@ -51,8 +51,8 @@ describe('frigg-cli dependencies', () => {
|
|
|
51
51
|
expect(packageJson.dependencies.commander).toBeDefined();
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
it('should have @friggframework/devtools
|
|
55
|
-
expect(packageJson.
|
|
54
|
+
it('should have @friggframework/devtools for infrastructure', () => {
|
|
55
|
+
expect(packageJson.dependencies['@friggframework/devtools']).toBeDefined();
|
|
56
56
|
});
|
|
57
57
|
});
|
|
58
58
|
|
|
@@ -12,9 +12,8 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
const path = require('path');
|
|
15
|
-
const output = require('../utils/output');
|
|
16
15
|
const fs = require('fs');
|
|
17
|
-
|
|
16
|
+
const { select } = require('@inquirer/prompts');
|
|
18
17
|
const { CloudFormationClient, ListStacksCommand } = require('@aws-sdk/client-cloudformation');
|
|
19
18
|
|
|
20
19
|
// Domain and Application Layer
|
|
@@ -161,9 +160,9 @@ function formatJsonOutput(report) {
|
|
|
161
160
|
function writeOutputFile(content, filePath) {
|
|
162
161
|
try {
|
|
163
162
|
fs.writeFileSync(filePath, content, 'utf8');
|
|
164
|
-
|
|
163
|
+
console.log(`\nā Report saved to: ${filePath}`);
|
|
165
164
|
} catch (error) {
|
|
166
|
-
|
|
165
|
+
console.error(`\nā Failed to write output file: ${error.message}`);
|
|
167
166
|
process.exit(1);
|
|
168
167
|
}
|
|
169
168
|
}
|
|
@@ -205,17 +204,17 @@ async function listStacks(region) {
|
|
|
205
204
|
* @returns {Promise<string>} Selected stack name
|
|
206
205
|
*/
|
|
207
206
|
async function promptForStackSelection(region) {
|
|
208
|
-
|
|
207
|
+
console.log(`\nš Fetching CloudFormation stacks in ${region}...`);
|
|
209
208
|
|
|
210
209
|
const stacks = await listStacks(region);
|
|
211
210
|
|
|
212
211
|
if (stacks.length === 0) {
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
console.error(`\nā No CloudFormation stacks found in ${region}`);
|
|
213
|
+
console.log(' Make sure you have stacks deployed and the correct AWS credentials configured.');
|
|
215
214
|
process.exit(1);
|
|
216
215
|
}
|
|
217
216
|
|
|
218
|
-
|
|
217
|
+
console.log(`\nā Found ${stacks.length} stack(s)\n`);
|
|
219
218
|
|
|
220
219
|
// Create choices with stack name and metadata
|
|
221
220
|
const choices = stacks.map(stack => {
|
|
@@ -231,7 +230,7 @@ async function promptForStackSelection(region) {
|
|
|
231
230
|
};
|
|
232
231
|
});
|
|
233
232
|
|
|
234
|
-
const selectedStack = await
|
|
233
|
+
const selectedStack = await select({
|
|
235
234
|
message: 'Select a stack to run health check:',
|
|
236
235
|
choices,
|
|
237
236
|
pageSize: 15,
|
|
@@ -258,7 +257,7 @@ async function doctorCommand(stackName, options = {}) {
|
|
|
258
257
|
}
|
|
259
258
|
|
|
260
259
|
// Show progress to user (always, not just verbose mode)
|
|
261
|
-
|
|
260
|
+
console.log(`\nš„ Running health check on stack: ${stackName} (${region})\n`);
|
|
262
261
|
|
|
263
262
|
// 1. Create stack identifier
|
|
264
263
|
const stackIdentifier = new StackIdentifier({ stackName, region });
|
|
@@ -282,9 +281,9 @@ async function doctorCommand(stackName, options = {}) {
|
|
|
282
281
|
// Progress callback to show execution status
|
|
283
282
|
const progressCallback = (step, message) => {
|
|
284
283
|
if (verbose) {
|
|
285
|
-
|
|
284
|
+
console.log(` ${message}`);
|
|
286
285
|
} else {
|
|
287
|
-
|
|
286
|
+
console.log(`${step} ${message}`);
|
|
288
287
|
}
|
|
289
288
|
};
|
|
290
289
|
|
|
@@ -293,7 +292,7 @@ async function doctorCommand(stackName, options = {}) {
|
|
|
293
292
|
onProgress: progressCallback
|
|
294
293
|
});
|
|
295
294
|
|
|
296
|
-
|
|
295
|
+
console.log('ā Health check complete!\n');
|
|
297
296
|
|
|
298
297
|
// 5. Format and output results
|
|
299
298
|
if (format === 'json') {
|
|
@@ -302,11 +301,11 @@ async function doctorCommand(stackName, options = {}) {
|
|
|
302
301
|
if (options.output) {
|
|
303
302
|
writeOutputFile(jsonOutput, options.output);
|
|
304
303
|
} else {
|
|
305
|
-
|
|
304
|
+
console.log(jsonOutput);
|
|
306
305
|
}
|
|
307
306
|
} else {
|
|
308
307
|
const consoleOutput = formatConsoleOutput(report, options);
|
|
309
|
-
|
|
308
|
+
console.log(consoleOutput);
|
|
310
309
|
|
|
311
310
|
if (options.output) {
|
|
312
311
|
writeOutputFile(consoleOutput, options.output);
|
|
@@ -323,10 +322,10 @@ async function doctorCommand(stackName, options = {}) {
|
|
|
323
322
|
process.exit(0);
|
|
324
323
|
}
|
|
325
324
|
} catch (error) {
|
|
326
|
-
|
|
325
|
+
console.error(`\nā Health check failed: ${error.message}`);
|
|
327
326
|
|
|
328
327
|
if (options.verbose && error.stack) {
|
|
329
|
-
|
|
328
|
+
console.error(`\nStack trace:\n${error.stack}`);
|
|
330
329
|
}
|
|
331
330
|
|
|
332
331
|
process.exit(1);
|
package/frigg-cli/index.js
CHANGED
|
@@ -86,23 +86,15 @@ const { dbSetupCommand } = require('./db-setup-command');
|
|
|
86
86
|
const { doctorCommand } = require('./doctor-command');
|
|
87
87
|
const { repairCommand } = require('./repair-command');
|
|
88
88
|
const { authCommand } = require('./auth-command');
|
|
89
|
-
const { createValidateCommand } = require('./validate-command/adapters/cli/validate-command');
|
|
90
89
|
|
|
91
90
|
const program = new Command();
|
|
92
91
|
|
|
93
|
-
// Add version command using package.json version
|
|
94
|
-
const packageJson = require('./package.json');
|
|
95
92
|
program
|
|
96
|
-
.
|
|
97
|
-
|
|
98
|
-
program
|
|
99
|
-
.command('init <projectName>')
|
|
93
|
+
.command('init [templateName]')
|
|
100
94
|
.description('Initialize a new Frigg application')
|
|
101
|
-
.option('-
|
|
102
|
-
.option('-
|
|
103
|
-
.option('--
|
|
104
|
-
.option('-y, --yes', 'accept defaults without prompting')
|
|
105
|
-
.option('--verbose', 'enable verbose output')
|
|
95
|
+
.option('-t, --template <template>', 'template to use', 'backend-only')
|
|
96
|
+
.option('-n, --name <name>', 'project name')
|
|
97
|
+
.option('-d, --directory <directory>', 'target directory')
|
|
106
98
|
.action(initCommand);
|
|
107
99
|
|
|
108
100
|
program
|
|
@@ -115,8 +107,6 @@ program
|
|
|
115
107
|
.description('Run the backend and optional frontend')
|
|
116
108
|
.option('-s, --stage <stage>', 'deployment stage', 'dev')
|
|
117
109
|
.option('-v, --verbose', 'enable verbose output')
|
|
118
|
-
.option('--ipc', 'enable IPC mode for Management UI communication')
|
|
119
|
-
.option('--no-interactive', 'skip interactive pre-flight prompts')
|
|
120
110
|
.action(startCommand);
|
|
121
111
|
|
|
122
112
|
program
|
|
@@ -179,8 +169,6 @@ program
|
|
|
179
169
|
.option('-v, --verbose', 'enable verbose output')
|
|
180
170
|
.action(repairCommand);
|
|
181
171
|
|
|
182
|
-
createValidateCommand(program);
|
|
183
|
-
|
|
184
172
|
// Auth command group for testing API module authentication
|
|
185
173
|
const authProgram = program
|
|
186
174
|
.command('auth')
|
|
@@ -215,9 +203,6 @@ authProgram
|
|
|
215
203
|
.option('-y, --yes', 'Skip confirmation')
|
|
216
204
|
.action(authCommand.delete);
|
|
217
205
|
|
|
218
|
-
|
|
219
|
-
if (require.main === module) {
|
|
220
|
-
program.parse(process.argv);
|
|
221
|
-
}
|
|
206
|
+
program.parse(process.argv);
|
|
222
207
|
|
|
223
|
-
module.exports = { initCommand, installCommand, startCommand, buildCommand, deployCommand, generateIamCommand, uiCommand, dbSetupCommand, doctorCommand, repairCommand, authCommand
|
|
208
|
+
module.exports = { initCommand, installCommand, startCommand, buildCommand, deployCommand, generateIamCommand, uiCommand, dbSetupCommand, doctorCommand, repairCommand, authCommand };
|
package/frigg-cli/index.test.js
CHANGED
|
@@ -6,14 +6,9 @@ const { installPackage } = require('./install-command/install-package');
|
|
|
6
6
|
const { createIntegrationFile } = require('./install-command/integration-file');
|
|
7
7
|
const { updateBackendJsFile } = require('./install-command/backend-js');
|
|
8
8
|
const { commitChanges } = require('./install-command/commit-changes');
|
|
9
|
+
const { logInfo, logError } = require('./install-command/logger');
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
* @group unit
|
|
12
|
-
* @group infrastructure
|
|
13
|
-
*/
|
|
14
|
-
// TODO: Fix these tests - they have issues with Commander.js mocking
|
|
15
|
-
// The mocks need to be set up before the module is loaded, not inline in tests
|
|
16
|
-
describe.skip('CLI Command Tests', () => {
|
|
11
|
+
describe('CLI Command Tests', () => {
|
|
17
12
|
it('should successfully install an API module when all steps complete without errors', async () => {
|
|
18
13
|
const mockApiModuleName = 'testModule';
|
|
19
14
|
const mockPackageName = `@friggframework/api-module-${mockApiModuleName}`;
|
|
@@ -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,
|
|
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
|
|
40
|
-
if (config.needsCustomApiModule
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
|
317
|
-
const
|
|
318
|
-
name:
|
|
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
|
-
|
|
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
|
-
|
|
367
|
-
|
|
368
|
-
|
|
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
|
-
|
|
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
|
|
316
|
+
await this.updateAppDefinition(config.starterIntegrations);
|
|
389
317
|
}
|
|
390
318
|
|
|
391
319
|
// Validate generated app definition against schema
|
|
392
|
-
const appDefPath = path.join(
|
|
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(
|
|
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(
|
|
509
|
+
async configureAWSServerless() {
|
|
582
510
|
// Update serverless.yml for AWS
|
|
583
|
-
const serverlessPath = path.join(
|
|
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
|
|
536
|
+
* Install dependencies
|
|
609
537
|
*/
|
|
610
538
|
async installDependencies(config) {
|
|
611
|
-
console.log(chalk.blue('\nš¦ Installing dependencies
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
674
|
-
const appDefPath = path.join(
|
|
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.
|
|
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(`
|
|
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(`
|
|
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.
|
|
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
|
}
|