@friggframework/devtools 2.0.0--canary.545.69acce5.0 → 2.0.0--canary.549.b074651.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/build.test.js +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/build-command/index.js +11 -123
- package/frigg-cli/deploy-command/index.js +1 -83
- package/frigg-cli/doctor-command/index.js +16 -37
- package/frigg-cli/generate-iam-command.js +1 -21
- 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 -121
- package/frigg-cli/start-command/index.js +2 -324
- package/frigg-cli/ui-command/index.js +36 -58
- package/frigg-cli/utils/repo-detection.js +37 -85
- package/infrastructure/create-frigg-infrastructure.js +0 -93
- 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/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.js +0 -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/provider-dispatch.test.js +0 -383
- 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__/provider-helper.test.js +0 -55
- package/frigg-cli/utils/__tests__/repo-detection.test.js +0 -436
- package/frigg-cli/utils/output.js +0 -382
- package/frigg-cli/utils/provider-helper.js +0 -75
- 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
|
@@ -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
|
}
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
46
|
+
logInfo('Searching for missing environment variables...');
|
|
46
47
|
const Definition = { env: extractRawEnvVariables(modulePath) };
|
|
47
48
|
if (Definition && Definition.env) {
|
|
48
|
-
|
|
49
|
+
console.log('Here is Definition.env:', Definition.env);
|
|
49
50
|
const envVars = Object.values(Definition.env);
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
80
|
-
output.warn(`Missing environment variables: ${missingEnvVars.join(', ')}`);
|
|
81
|
+
logInfo(`Missing environment variables: ${missingEnvVars.join(', ')}`);
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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('
|
|
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
|
-
|
|
101
|
-
|
|
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(
|
|
111
|
+
expect(logInfo).toHaveBeenCalledWith(
|
|
110
112
|
'Searching for missing environment variables...'
|
|
111
113
|
);
|
|
112
|
-
expect(
|
|
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(
|
|
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
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
19
|
+
logInfo(`Writing integration file: ${integrationFilePath}`);
|
|
20
20
|
const integrationTemplate = getIntegrationTemplate(
|
|
21
21
|
apiModuleName,
|
|
22
22
|
backendPath,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { execSync } = require('child_process');
|
|
2
2
|
const axios = require('axios');
|
|
3
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
61
|
-
|
|
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
|
};
|
package/frigg-cli/jest.config.js
CHANGED
|
@@ -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
|
-
|
|
96
|
+
'<rootDir>/__tests__/utils/test-setup.js'
|
|
100
97
|
],
|
|
101
98
|
testTimeout: 10000,
|
|
102
99
|
maxWorkers: '50%',
|