@friggframework/devtools 2.0.0--canary.400.bed3308.0 → 2.0.0--canary.400.545e7a8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/frigg-cli/build-command/index.js +2 -15
  2. package/frigg-cli/deploy-command/index.js +2 -15
  3. package/frigg-cli/index.js +4 -66
  4. package/frigg-cli/install-command/index.js +2 -15
  5. package/frigg-cli/start-command/index.js +2 -17
  6. package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +19 -43
  7. package/infrastructure/IAM-POLICY-TEMPLATES.md +1 -1
  8. package/infrastructure/frigg-deployment-iam-stack.yaml +2 -16
  9. package/infrastructure/iam-generator.js +6 -129
  10. package/infrastructure/iam-policy-basic.json +5 -29
  11. package/infrastructure/iam-policy-full.json +5 -28
  12. package/infrastructure/serverless-template.js +3 -190
  13. package/infrastructure/serverless-template.test.js +0 -12
  14. package/management-ui/dist/assets/index-CbM64Oba.js +1221 -0
  15. package/management-ui/dist/assets/index-CkvseXTC.css +1 -0
  16. package/management-ui/{index.html → dist/index.html} +2 -1
  17. package/package.json +5 -5
  18. package/frigg-cli/.eslintrc.js +0 -141
  19. package/frigg-cli/__tests__/jest.config.js +0 -102
  20. package/frigg-cli/__tests__/unit/commands/build.test.js +0 -483
  21. package/frigg-cli/__tests__/unit/commands/install.test.js +0 -418
  22. package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -592
  23. package/frigg-cli/__tests__/utils/command-tester.js +0 -170
  24. package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
  25. package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
  26. package/frigg-cli/__tests__/utils/test-setup.js +0 -286
  27. package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -312
  28. package/frigg-cli/generate-command/azure-generator.js +0 -43
  29. package/frigg-cli/generate-command/gcp-generator.js +0 -47
  30. package/frigg-cli/generate-command/index.js +0 -350
  31. package/frigg-cli/generate-command/terraform-generator.js +0 -555
  32. package/frigg-cli/package.json +0 -75
  33. package/frigg-cli/ui-command/index.js +0 -167
  34. package/frigg-cli/utils/app-resolver.js +0 -319
  35. package/frigg-cli/utils/backend-path.js +0 -38
  36. package/frigg-cli/utils/process-manager.js +0 -199
  37. package/frigg-cli/utils/repo-detection.js +0 -405
  38. package/management-ui/.eslintrc.js +0 -22
  39. package/management-ui/README.md +0 -203
  40. package/management-ui/components.json +0 -21
  41. package/management-ui/merge-conflict-cleaner.py +0 -371
  42. package/management-ui/package-lock.json +0 -10997
  43. package/management-ui/package.json +0 -76
  44. package/management-ui/postcss.config.js +0 -6
  45. package/management-ui/server/api/backend.js +0 -256
  46. package/management-ui/server/api/cli.js +0 -315
  47. package/management-ui/server/api/codegen.js +0 -663
  48. package/management-ui/server/api/connections.js +0 -857
  49. package/management-ui/server/api/discovery.js +0 -185
  50. package/management-ui/server/api/environment/index.js +0 -1
  51. package/management-ui/server/api/environment/router.js +0 -378
  52. package/management-ui/server/api/environment.js +0 -328
  53. package/management-ui/server/api/integrations.js +0 -479
  54. package/management-ui/server/api/logs.js +0 -248
  55. package/management-ui/server/api/monitoring.js +0 -282
  56. package/management-ui/server/api/open-ide.js +0 -31
  57. package/management-ui/server/api/project.js +0 -553
  58. package/management-ui/server/api/users/sessions.js +0 -371
  59. package/management-ui/server/api/users/simulation.js +0 -254
  60. package/management-ui/server/api/users.js +0 -362
  61. package/management-ui/server/api-contract.md +0 -275
  62. package/management-ui/server/index.js +0 -428
  63. package/management-ui/server/middleware/errorHandler.js +0 -70
  64. package/management-ui/server/middleware/security.js +0 -32
  65. package/management-ui/server/processManager.js +0 -296
  66. package/management-ui/server/server.js +0 -188
  67. package/management-ui/server/services/aws-monitor.js +0 -413
  68. package/management-ui/server/services/npm-registry.js +0 -347
  69. package/management-ui/server/services/template-engine.js +0 -538
  70. package/management-ui/server/utils/cliIntegration.js +0 -220
  71. package/management-ui/server/utils/environment/auditLogger.js +0 -471
  72. package/management-ui/server/utils/environment/awsParameterStore.js +0 -264
  73. package/management-ui/server/utils/environment/encryption.js +0 -278
  74. package/management-ui/server/utils/environment/envFileManager.js +0 -286
  75. package/management-ui/server/utils/import-commonjs.js +0 -28
  76. package/management-ui/server/utils/response.js +0 -83
  77. package/management-ui/server/websocket/handler.js +0 -325
  78. package/management-ui/src/App.jsx +0 -51
  79. package/management-ui/src/components/AppRouter.jsx +0 -65
  80. package/management-ui/src/components/Button.jsx +0 -2
  81. package/management-ui/src/components/Card.jsx +0 -9
  82. package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
  83. package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
  84. package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
  85. package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
  86. package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
  87. package/management-ui/src/components/ErrorBoundary.jsx +0 -73
  88. package/management-ui/src/components/IntegrationCard.jsx +0 -199
  89. package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -490
  90. package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
  91. package/management-ui/src/components/IntegrationStatus.jsx +0 -235
  92. package/management-ui/src/components/Layout.jsx +0 -250
  93. package/management-ui/src/components/LoadingSpinner.jsx +0 -45
  94. package/management-ui/src/components/RepositoryPicker.jsx +0 -248
  95. package/management-ui/src/components/SessionMonitor.jsx +0 -255
  96. package/management-ui/src/components/StatusBadge.jsx +0 -70
  97. package/management-ui/src/components/UserContextSwitcher.jsx +0 -154
  98. package/management-ui/src/components/UserSimulation.jsx +0 -299
  99. package/management-ui/src/components/Welcome.jsx +0 -434
  100. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
  101. package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
  102. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
  103. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
  104. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
  105. package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
  106. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
  107. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
  108. package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
  109. package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
  110. package/management-ui/src/components/codegen/index.js +0 -10
  111. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
  112. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
  113. package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
  114. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
  115. package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
  116. package/management-ui/src/components/connections/index.js +0 -5
  117. package/management-ui/src/components/index.js +0 -21
  118. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
  119. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
  120. package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
  121. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
  122. package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
  123. package/management-ui/src/components/monitoring/index.js +0 -6
  124. package/management-ui/src/components/monitoring/monitoring.css +0 -218
  125. package/management-ui/src/components/theme-provider.jsx +0 -52
  126. package/management-ui/src/components/theme-toggle.jsx +0 -39
  127. package/management-ui/src/components/ui/badge.tsx +0 -36
  128. package/management-ui/src/components/ui/button.test.jsx +0 -56
  129. package/management-ui/src/components/ui/button.tsx +0 -57
  130. package/management-ui/src/components/ui/card.tsx +0 -76
  131. package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
  132. package/management-ui/src/components/ui/select.tsx +0 -157
  133. package/management-ui/src/components/ui/skeleton.jsx +0 -15
  134. package/management-ui/src/hooks/useFrigg.jsx +0 -387
  135. package/management-ui/src/hooks/useSocket.jsx +0 -58
  136. package/management-ui/src/index.css +0 -194
  137. package/management-ui/src/lib/utils.ts +0 -6
  138. package/management-ui/src/main.jsx +0 -10
  139. package/management-ui/src/pages/CodeGeneration.jsx +0 -14
  140. package/management-ui/src/pages/Connections.jsx +0 -252
  141. package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -427
  142. package/management-ui/src/pages/Dashboard.jsx +0 -311
  143. package/management-ui/src/pages/Environment.jsx +0 -314
  144. package/management-ui/src/pages/IntegrationConfigure.jsx +0 -544
  145. package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -479
  146. package/management-ui/src/pages/IntegrationTest.jsx +0 -494
  147. package/management-ui/src/pages/Integrations.jsx +0 -254
  148. package/management-ui/src/pages/Monitoring.jsx +0 -17
  149. package/management-ui/src/pages/Simulation.jsx +0 -155
  150. package/management-ui/src/pages/Users.jsx +0 -492
  151. package/management-ui/src/services/api.js +0 -41
  152. package/management-ui/src/services/apiModuleService.js +0 -193
  153. package/management-ui/src/services/websocket-handlers.js +0 -120
  154. package/management-ui/src/test/api/project.test.js +0 -273
  155. package/management-ui/src/test/components/Welcome.test.jsx +0 -378
  156. package/management-ui/src/test/mocks/server.js +0 -178
  157. package/management-ui/src/test/setup.js +0 -61
  158. package/management-ui/src/test/utils/test-utils.jsx +0 -134
  159. package/management-ui/src/utils/repository.js +0 -98
  160. package/management-ui/src/utils/repository.test.js +0 -118
  161. package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
  162. package/management-ui/tailwind.config.js +0 -63
  163. package/management-ui/tsconfig.json +0 -37
  164. package/management-ui/tsconfig.node.json +0 -10
  165. package/management-ui/vite.config.js +0 -26
  166. package/management-ui/vitest.config.js +0 -38
  167. /package/management-ui/{src/assets/FriggLogo.svg → dist/assets/FriggLogo-B7Xx8ZW1.svg} +0 -0
@@ -1,797 +0,0 @@
1
- import React, { useState, useCallback } from 'react';
2
- import { Card } from '../Card';
3
- import { Button } from '../Button';
4
-
5
- const PROJECT_TEMPLATES = {
6
- 'basic-backend': {
7
- name: 'Basic Backend',
8
- description: 'Simple Frigg backend with core functionality',
9
- features: ['Express server', 'MongoDB integration', 'Basic authentication', 'Environment configuration']
10
- },
11
- 'microservices': {
12
- name: 'Microservices',
13
- description: 'Multi-service architecture with API Gateway',
14
- features: ['API Gateway', 'Service discovery', 'Load balancing', 'Circuit breakers']
15
- },
16
- 'serverless': {
17
- name: 'Serverless',
18
- description: 'AWS Lambda-based serverless backend',
19
- features: ['Lambda functions', 'API Gateway', 'DynamoDB', 'CloudWatch logging']
20
- },
21
- 'full-stack': {
22
- name: 'Full Stack',
23
- description: 'Complete application with frontend and backend',
24
- features: ['React frontend', 'Express backend', 'Database integration', 'Authentication']
25
- }
26
- };
27
-
28
- const INTEGRATION_OPTIONS = [
29
- { id: 'hubspot', name: 'HubSpot', category: 'CRM' },
30
- { id: 'salesforce', name: 'Salesforce', category: 'CRM' },
31
- { id: 'slack', name: 'Slack', category: 'Communication' },
32
- { id: 'mailchimp', name: 'Mailchimp', category: 'Marketing' },
33
- { id: 'stripe', name: 'Stripe', category: 'Payments' },
34
- { id: 'twilio', name: 'Twilio', category: 'Communication' },
35
- { id: 'google-analytics', name: 'Google Analytics', category: 'Analytics' },
36
- { id: 'microsoft-teams', name: 'Microsoft Teams', category: 'Communication' }
37
- ];
38
-
39
- const DATABASE_OPTIONS = [
40
- { value: 'mongodb', label: 'MongoDB', description: 'Document database' },
41
- { value: 'postgresql', label: 'PostgreSQL', description: 'Relational database' },
42
- { value: 'mysql', label: 'MySQL', description: 'Relational database' },
43
- { value: 'dynamodb', label: 'DynamoDB', description: 'AWS NoSQL database' },
44
- { value: 'redis', label: 'Redis', description: 'In-memory cache' }
45
- ];
46
-
47
- const ProjectScaffoldWizard = ({ onGenerate }) => {
48
- const [projectData, setProjectData] = useState({
49
- name: '',
50
- description: '',
51
- template: 'basic-backend',
52
- database: 'mongodb',
53
- integrations: [],
54
- features: {
55
- authentication: true,
56
- logging: true,
57
- monitoring: true,
58
- testing: true,
59
- docker: true,
60
- ci: false
61
- },
62
- deployment: {
63
- platform: 'aws',
64
- environment: 'development'
65
- }
66
- });
67
-
68
- const [currentStep, setCurrentStep] = useState(0);
69
-
70
- const steps = [
71
- { title: 'Project Info', description: 'Basic project configuration' },
72
- { title: 'Template', description: 'Choose project template' },
73
- { title: 'Database', description: 'Select database options' },
74
- { title: 'Integrations', description: 'Choose integrations' },
75
- { title: 'Features', description: 'Enable additional features' },
76
- { title: 'Deployment', description: 'Deployment configuration' }
77
- ];
78
-
79
- const handleInputChange = useCallback((field, value) => {
80
- setProjectData(prev => ({
81
- ...prev,
82
- [field]: value
83
- }));
84
- }, []);
85
-
86
- const handleFeatureToggle = useCallback((feature) => {
87
- setProjectData(prev => ({
88
- ...prev,
89
- features: {
90
- ...prev.features,
91
- [feature]: !prev.features[feature]
92
- }
93
- }));
94
- }, []);
95
-
96
- const handleIntegrationToggle = useCallback((integrationId) => {
97
- setProjectData(prev => ({
98
- ...prev,
99
- integrations: prev.integrations.includes(integrationId)
100
- ? prev.integrations.filter(id => id !== integrationId)
101
- : [...prev.integrations, integrationId]
102
- }));
103
- }, []);
104
-
105
- const generateProjectFiles = useCallback(() => {
106
- const template = PROJECT_TEMPLATES[projectData.template];
107
-
108
- // Generate package.json
109
- const packageJson = {
110
- name: projectData.name,
111
- version: '1.0.0',
112
- description: projectData.description,
113
- main: 'app.js',
114
- scripts: {
115
- start: 'node app.js',
116
- dev: 'nodemon app.js',
117
- test: projectData.features.testing ? 'jest' : undefined,
118
- build: projectData.template === 'serverless' ? 'serverless package' : undefined,
119
- deploy: projectData.template === 'serverless' ? 'serverless deploy' : undefined
120
- },
121
- dependencies: {
122
- '@friggframework/core': '^1.0.0',
123
- express: '^4.18.0',
124
- ...(projectData.database === 'mongodb' ? { mongoose: '^7.0.0' } : {}),
125
- ...(projectData.database === 'postgresql' ? { pg: '^8.8.0', 'pg-hstore': '^2.3.4' } : {}),
126
- ...(projectData.database === 'mysql' ? { mysql2: '^3.0.0' } : {}),
127
- ...(projectData.features.authentication ? { passport: '^0.6.0', 'passport-jwt': '^4.0.0' } : {}),
128
- ...(projectData.features.logging ? { winston: '^3.8.0' } : {}),
129
- ...(projectData.integrations.map(id => ({ [`@friggframework/api-module-${id}`]: '^1.0.0' })).reduce((acc, obj) => ({ ...acc, ...obj }), {}))
130
- },
131
- devDependencies: {
132
- nodemon: '^2.0.0',
133
- ...(projectData.features.testing ? { jest: '^29.0.0', supertest: '^6.3.0' } : {})
134
- }
135
- };
136
-
137
- // Generate app.js
138
- const appJs = generateAppJs();
139
-
140
- // Generate serverless.yml (if serverless template)
141
- const serverlessYml = projectData.template === 'serverless' ? generateServerlessYml() : null;
142
-
143
- // Generate docker files (if docker enabled)
144
- const dockerfile = projectData.features.docker ? generateDockerfile() : null;
145
- const dockerCompose = projectData.features.docker ? generateDockerCompose() : null;
146
-
147
- // Generate README
148
- const readme = generateReadme();
149
-
150
- // Generate environment files
151
- const envExample = generateEnvExample();
152
-
153
- const files = [
154
- { name: 'package.json', content: JSON.stringify(packageJson, null, 2) },
155
- { name: 'app.js', content: appJs },
156
- { name: 'README.md', content: readme },
157
- { name: '.env.example', content: envExample },
158
- ...(serverlessYml ? [{ name: 'serverless.yml', content: serverlessYml }] : []),
159
- ...(dockerfile ? [{ name: 'Dockerfile', content: dockerfile }] : []),
160
- ...(dockerCompose ? [{ name: 'docker-compose.yml', content: dockerCompose }] : []),
161
- ...(projectData.features.ci ? [{ name: '.github/workflows/ci.yml', content: generateCIConfig() }] : [])
162
- ];
163
-
164
- const metadata = {
165
- name: projectData.name,
166
- template: projectData.template,
167
- type: 'project-scaffold',
168
- files
169
- };
170
-
171
- onGenerate(projectData, { files }, metadata);
172
- }, [projectData, onGenerate]);
173
-
174
- const generateAppJs = () => {
175
- return `const express = require('express');
176
- const { FriggManager } = require('@friggframework/core');
177
- ${projectData.features.logging ? "const winston = require('winston');" : ''}
178
- ${projectData.database === 'mongodb' ? "const mongoose = require('mongoose');" : ''}
179
-
180
- const app = express();
181
- const port = process.env.PORT || 3000;
182
-
183
- // Middleware
184
- app.use(express.json());
185
- app.use(express.urlencoded({ extended: true }));
186
-
187
- ${projectData.features.logging ? `
188
- // Logging configuration
189
- const logger = winston.createLogger({
190
- level: 'info',
191
- format: winston.format.combine(
192
- winston.format.timestamp(),
193
- winston.format.json()
194
- ),
195
- transports: [
196
- new winston.transports.Console(),
197
- new winston.transports.File({ filename: 'app.log' })
198
- ]
199
- });
200
- ` : ''}
201
-
202
- ${projectData.database === 'mongodb' ? `
203
- // Database connection
204
- mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/${projectData.name}', {
205
- useNewUrlParser: true,
206
- useUnifiedTopology: true
207
- });
208
- ` : ''}
209
-
210
- // Frigg Manager initialization
211
- const friggManager = new FriggManager({
212
- database: '${projectData.database}',
213
- integrations: [
214
- ${projectData.integrations.map(id => ` require('@friggframework/api-module-${id}')`).join(',\n')}
215
- ]
216
- });
217
-
218
- // Routes
219
- app.get('/', (req, res) => {
220
- res.json({
221
- message: 'Welcome to ${projectData.name}',
222
- status: 'running',
223
- integrations: [${projectData.integrations.map(id => `'${id}'`).join(', ')}]
224
- });
225
- });
226
-
227
- app.get('/health', (req, res) => {
228
- res.json({ status: 'healthy', timestamp: new Date().toISOString() });
229
- });
230
-
231
- // Start server
232
- app.listen(port, () => {
233
- ${projectData.features.logging ? 'logger.info' : 'console.log'}(\`Server running on port \${port}\`);
234
- });
235
-
236
- module.exports = app;`;
237
- };
238
-
239
- const generateServerlessYml = () => {
240
- return `service: ${projectData.name}
241
-
242
- frameworkVersion: '3'
243
-
244
- provider:
245
- name: aws
246
- runtime: nodejs18.x
247
- stage: \${opt:stage, 'dev'}
248
- region: \${opt:region, 'us-east-1'}
249
- environment:
250
- NODE_ENV: \${self:provider.stage}
251
- ${projectData.integrations.map(id => `${id.toUpperCase()}_API_KEY: \${env:${id.toUpperCase()}_API_KEY}`).join('\n ')}
252
-
253
- functions:
254
- app:
255
- handler: app.handler
256
- events:
257
- - http:
258
- path: /{proxy+}
259
- method: ANY
260
- cors: true
261
- - http:
262
- path: /
263
- method: ANY
264
- cors: true
265
-
266
- ${projectData.database === 'dynamodb' ? `
267
- resources:
268
- Resources:
269
- ${projectData.name}Table:
270
- Type: AWS::DynamoDB::Table
271
- Properties:
272
- TableName: \${self:provider.stage}-${projectData.name}
273
- AttributeDefinitions:
274
- - AttributeName: id
275
- AttributeType: S
276
- KeySchema:
277
- - AttributeName: id
278
- KeyType: HASH
279
- BillingMode: PAY_PER_REQUEST
280
- ` : ''}
281
-
282
- plugins:
283
- - serverless-offline`;
284
- };
285
-
286
- const generateDockerfile = () => {
287
- return `FROM node:18-alpine
288
-
289
- WORKDIR /app
290
-
291
- COPY package*.json ./
292
- RUN npm ci --only=production
293
-
294
- COPY . .
295
-
296
- EXPOSE 3000
297
-
298
- CMD ["npm", "start"]`;
299
- };
300
-
301
- const generateDockerCompose = () => {
302
- return `version: '3.8'
303
-
304
- services:
305
- app:
306
- build: .
307
- ports:
308
- - "3000:3000"
309
- environment:
310
- - NODE_ENV=development
311
- ${projectData.database === 'mongodb' ? '- MONGODB_URI=mongodb://mongo:27017/' + projectData.name : ''}
312
- depends_on:
313
- ${projectData.database === 'mongodb' ? '- mongo' : ''}
314
- volumes:
315
- - .:/app
316
- - /app/node_modules
317
-
318
- ${projectData.database === 'mongodb' ? ` mongo:
319
- image: mongo:5
320
- ports:
321
- - "27017:27017"
322
- volumes:
323
- - mongo_data:/data/db
324
-
325
- volumes:
326
- mongo_data:` : ''}`;
327
- };
328
-
329
- const generateReadme = () => {
330
- const template = PROJECT_TEMPLATES[projectData.template];
331
-
332
- return `# ${projectData.name}
333
-
334
- ${projectData.description}
335
-
336
- ## Project Template: ${template.name}
337
-
338
- ${template.description}
339
-
340
- ### Features
341
-
342
- ${template.features.map(feature => `- ${feature}`).join('\n')}
343
-
344
- ### Integrations
345
-
346
- ${projectData.integrations.length > 0
347
- ? projectData.integrations.map(id => {
348
- const integration = INTEGRATION_OPTIONS.find(i => i.id === id);
349
- return `- ${integration?.name} (${integration?.category})`;
350
- }).join('\n')
351
- : 'No integrations configured'
352
- }
353
-
354
- ### Database
355
-
356
- - ${DATABASE_OPTIONS.find(db => db.value === projectData.database)?.label}
357
-
358
- ### Additional Features
359
-
360
- ${Object.entries(projectData.features)
361
- .filter(([, enabled]) => enabled)
362
- .map(([feature]) => `- ${feature.charAt(0).toUpperCase() + feature.slice(1)}`)
363
- .join('\n')}
364
-
365
- ## Getting Started
366
-
367
- 1. Install dependencies:
368
- \`\`\`bash
369
- npm install
370
- \`\`\`
371
-
372
- 2. Copy environment variables:
373
- \`\`\`bash
374
- cp .env.example .env
375
- \`\`\`
376
-
377
- 3. Update environment variables in \`.env\`
378
-
379
- ${projectData.features.docker ? `4. Start with Docker:
380
- \`\`\`bash
381
- docker-compose up
382
- \`\`\`
383
-
384
- Or start locally:` : '4. Start the application:'}
385
- \`\`\`bash
386
- npm run dev
387
- \`\`\`
388
-
389
- ## API Endpoints
390
-
391
- - \`GET /\` - Welcome message and status
392
- - \`GET /health\` - Health check
393
-
394
- ## Deployment
395
-
396
- ${projectData.template === 'serverless'
397
- ? `This project uses Serverless Framework for deployment:
398
-
399
- \`\`\`bash
400
- npm run deploy
401
- \`\`\``
402
- : `Configure your deployment platform (${projectData.deployment.platform}) according to your needs.`
403
- }
404
-
405
- ## License
406
-
407
- MIT`;
408
- };
409
-
410
- const generateEnvExample = () => {
411
- return `# Environment Configuration
412
- NODE_ENV=development
413
- PORT=3000
414
-
415
- # Database
416
- ${projectData.database === 'mongodb' ? `MONGODB_URI=mongodb://localhost:27017/${projectData.name}` : ''}
417
- ${projectData.database === 'postgresql' ? `DATABASE_URL=postgresql://user:password@localhost:5432/${projectData.name}` : ''}
418
- ${projectData.database === 'mysql' ? `DATABASE_URL=mysql://user:password@localhost:3306/${projectData.name}` : ''}
419
-
420
- # Integration API Keys
421
- ${projectData.integrations.map(id => `${id.toUpperCase()}_API_KEY=your_${id}_api_key_here`).join('\n')}
422
-
423
- # Authentication (if enabled)
424
- ${projectData.features.authentication ? `JWT_SECRET=your_jwt_secret_here
425
- JWT_EXPIRES_IN=24h` : ''}
426
-
427
- # AWS Configuration (if using AWS services)
428
- ${projectData.deployment.platform === 'aws' ? `AWS_ACCESS_KEY_ID=your_access_key
429
- AWS_SECRET_ACCESS_KEY=your_secret_key
430
- AWS_REGION=us-east-1` : ''}`;
431
- };
432
-
433
- const generateCIConfig = () => {
434
- return `name: CI/CD Pipeline
435
-
436
- on:
437
- push:
438
- branches: [ main, develop ]
439
- pull_request:
440
- branches: [ main ]
441
-
442
- jobs:
443
- test:
444
- runs-on: ubuntu-latest
445
-
446
- strategy:
447
- matrix:
448
- node-version: [16.x, 18.x]
449
-
450
- steps:
451
- - uses: actions/checkout@v3
452
-
453
- - name: Use Node.js \${{ matrix.node-version }}
454
- uses: actions/setup-node@v3
455
- with:
456
- node-version: \${{ matrix.node-version }}
457
- cache: 'npm'
458
-
459
- - run: npm ci
460
-
461
- ${projectData.features.testing ? '- run: npm test' : ''}
462
-
463
- - run: npm run lint
464
-
465
- deploy:
466
- needs: test
467
- runs-on: ubuntu-latest
468
- if: github.ref == 'refs/heads/main'
469
-
470
- steps:
471
- - uses: actions/checkout@v3
472
-
473
- - name: Use Node.js 18.x
474
- uses: actions/setup-node@v3
475
- with:
476
- node-version: 18.x
477
- cache: 'npm'
478
-
479
- - run: npm ci
480
-
481
- ${projectData.template === 'serverless' ? '- run: npm run deploy' : '# Add your deployment steps here'}`;
482
- };
483
-
484
- const nextStep = () => {
485
- if (currentStep < steps.length - 1) {
486
- setCurrentStep(currentStep + 1);
487
- }
488
- };
489
-
490
- const prevStep = () => {
491
- if (currentStep > 0) {
492
- setCurrentStep(currentStep - 1);
493
- }
494
- };
495
-
496
- const canProceed = () => {
497
- switch (currentStep) {
498
- case 0:
499
- return projectData.name && projectData.description;
500
- case 1:
501
- return projectData.template;
502
- case 2:
503
- return projectData.database;
504
- default:
505
- return true;
506
- }
507
- };
508
-
509
- const renderStep = () => {
510
- switch (currentStep) {
511
- case 0:
512
- return (
513
- <div className="space-y-4">
514
- <h3 className="text-lg font-medium">Project Information</h3>
515
- <div className="grid grid-cols-1 gap-4">
516
- <div>
517
- <label className="block text-sm font-medium text-gray-700 mb-2">
518
- Project Name *
519
- </label>
520
- <input
521
- type="text"
522
- value={projectData.name}
523
- onChange={(e) => handleInputChange('name', e.target.value)}
524
- placeholder="my-frigg-project"
525
- className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
526
- />
527
- </div>
528
- <div>
529
- <label className="block text-sm font-medium text-gray-700 mb-2">
530
- Description *
531
- </label>
532
- <textarea
533
- value={projectData.description}
534
- onChange={(e) => handleInputChange('description', e.target.value)}
535
- placeholder="Brief description of your project"
536
- rows={3}
537
- className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
538
- />
539
- </div>
540
- </div>
541
- </div>
542
- );
543
-
544
- case 1:
545
- return (
546
- <div className="space-y-4">
547
- <h3 className="text-lg font-medium">Choose Project Template</h3>
548
- <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
549
- {Object.entries(PROJECT_TEMPLATES).map(([key, template]) => (
550
- <Card
551
- key={key}
552
- className={`cursor-pointer transition-all p-4 ${
553
- projectData.template === key
554
- ? 'border-blue-500 bg-blue-50'
555
- : 'hover:border-gray-300'
556
- }`}
557
- onClick={() => handleInputChange('template', key)}
558
- >
559
- <div className="flex items-start justify-between mb-2">
560
- <h4 className="font-medium">{template.name}</h4>
561
- <input
562
- type="radio"
563
- checked={projectData.template === key}
564
- onChange={() => handleInputChange('template', key)}
565
- className="mt-1"
566
- />
567
- </div>
568
- <p className="text-sm text-gray-600 mb-3">{template.description}</p>
569
- <div className="space-y-1">
570
- {template.features.map((feature, index) => (
571
- <div key={index} className="text-xs text-gray-500 flex items-center">
572
- <span className="w-1 h-1 bg-gray-400 rounded-full mr-2"></span>
573
- {feature}
574
- </div>
575
- ))}
576
- </div>
577
- </Card>
578
- ))}
579
- </div>
580
- </div>
581
- );
582
-
583
- case 2:
584
- return (
585
- <div className="space-y-4">
586
- <h3 className="text-lg font-medium">Database Configuration</h3>
587
- <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
588
- {DATABASE_OPTIONS.map((db) => (
589
- <Card
590
- key={db.value}
591
- className={`cursor-pointer transition-all p-4 ${
592
- projectData.database === db.value
593
- ? 'border-blue-500 bg-blue-50'
594
- : 'hover:border-gray-300'
595
- }`}
596
- onClick={() => handleInputChange('database', db.value)}
597
- >
598
- <div className="flex items-start justify-between mb-2">
599
- <h4 className="font-medium">{db.label}</h4>
600
- <input
601
- type="radio"
602
- checked={projectData.database === db.value}
603
- onChange={() => handleInputChange('database', db.value)}
604
- className="mt-1"
605
- />
606
- </div>
607
- <p className="text-sm text-gray-600">{db.description}</p>
608
- </Card>
609
- ))}
610
- </div>
611
- </div>
612
- );
613
-
614
- case 3:
615
- return (
616
- <div className="space-y-4">
617
- <h3 className="text-lg font-medium">Select Integrations</h3>
618
- <p className="text-sm text-gray-600">Choose the integrations you want to include in your project.</p>
619
-
620
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
621
- {INTEGRATION_OPTIONS.map((integration) => (
622
- <div
623
- key={integration.id}
624
- className={`border rounded p-3 cursor-pointer transition-all ${
625
- projectData.integrations.includes(integration.id)
626
- ? 'border-blue-500 bg-blue-50'
627
- : 'hover:border-gray-300'
628
- }`}
629
- onClick={() => handleIntegrationToggle(integration.id)}
630
- >
631
- <div className="flex items-center justify-between">
632
- <div>
633
- <h4 className="font-medium text-sm">{integration.name}</h4>
634
- <p className="text-xs text-gray-500">{integration.category}</p>
635
- </div>
636
- <input
637
- type="checkbox"
638
- checked={projectData.integrations.includes(integration.id)}
639
- onChange={() => handleIntegrationToggle(integration.id)}
640
- />
641
- </div>
642
- </div>
643
- ))}
644
- </div>
645
- </div>
646
- );
647
-
648
- case 4:
649
- return (
650
- <div className="space-y-4">
651
- <h3 className="text-lg font-medium">Additional Features</h3>
652
- <p className="text-sm text-gray-600">Enable additional features for your project.</p>
653
-
654
- <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
655
- {Object.entries(projectData.features).map(([feature, enabled]) => (
656
- <div key={feature} className="flex items-center justify-between p-3 border rounded">
657
- <div>
658
- <h4 className="font-medium capitalize">{feature.replace(/([A-Z])/g, ' $1')}</h4>
659
- <p className="text-sm text-gray-500">
660
- {feature === 'authentication' && 'JWT-based authentication system'}
661
- {feature === 'logging' && 'Winston logging configuration'}
662
- {feature === 'monitoring' && 'Health checks and metrics'}
663
- {feature === 'testing' && 'Jest testing framework'}
664
- {feature === 'docker' && 'Docker and docker-compose files'}
665
- {feature === 'ci' && 'GitHub Actions CI/CD pipeline'}
666
- </p>
667
- </div>
668
- <input
669
- type="checkbox"
670
- checked={enabled}
671
- onChange={() => handleFeatureToggle(feature)}
672
- />
673
- </div>
674
- ))}
675
- </div>
676
- </div>
677
- );
678
-
679
- case 5:
680
- return (
681
- <div className="space-y-4">
682
- <h3 className="text-lg font-medium">Deployment Configuration</h3>
683
-
684
- <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
685
- <div>
686
- <label className="block text-sm font-medium text-gray-700 mb-2">
687
- Platform
688
- </label>
689
- <select
690
- value={projectData.deployment.platform}
691
- onChange={(e) => handleInputChange('deployment', { ...projectData.deployment, platform: e.target.value })}
692
- className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
693
- >
694
- <option value="aws">AWS</option>
695
- <option value="gcp">Google Cloud</option>
696
- <option value="azure">Microsoft Azure</option>
697
- <option value="heroku">Heroku</option>
698
- <option value="vercel">Vercel</option>
699
- <option value="netlify">Netlify</option>
700
- </select>
701
- </div>
702
- <div>
703
- <label className="block text-sm font-medium text-gray-700 mb-2">
704
- Environment
705
- </label>
706
- <select
707
- value={projectData.deployment.environment}
708
- onChange={(e) => handleInputChange('deployment', { ...projectData.deployment, environment: e.target.value })}
709
- className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
710
- >
711
- <option value="development">Development</option>
712
- <option value="staging">Staging</option>
713
- <option value="production">Production</option>
714
- </select>
715
- </div>
716
- </div>
717
-
718
- <div className="bg-blue-50 p-4 rounded-md">
719
- <h4 className="font-medium text-blue-900 mb-2">Project Summary</h4>
720
- <div className="text-sm text-blue-800 space-y-1">
721
- <p><strong>Name:</strong> {projectData.name}</p>
722
- <p><strong>Template:</strong> {PROJECT_TEMPLATES[projectData.template].name}</p>
723
- <p><strong>Database:</strong> {DATABASE_OPTIONS.find(db => db.value === projectData.database)?.label}</p>
724
- <p><strong>Integrations:</strong> {projectData.integrations.length > 0 ? projectData.integrations.join(', ') : 'None'}</p>
725
- <p><strong>Features:</strong> {Object.entries(projectData.features).filter(([, enabled]) => enabled).map(([feature]) => feature).join(', ')}</p>
726
- </div>
727
- </div>
728
- </div>
729
- );
730
-
731
- default:
732
- return null;
733
- }
734
- };
735
-
736
- return (
737
- <div className="space-y-6">
738
- <h2 className="text-2xl font-bold">Project Scaffold Wizard</h2>
739
-
740
- {/* Progress indicator */}
741
- <div className="flex items-center justify-between mb-8">
742
- {steps.map((step, index) => (
743
- <div key={index} className="flex items-center">
744
- <div className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium ${
745
- index <= currentStep
746
- ? 'bg-blue-600 text-white'
747
- : 'bg-gray-200 text-gray-500'
748
- }`}>
749
- {index + 1}
750
- </div>
751
- <div className="ml-2 text-sm">
752
- <div className={`font-medium ${index <= currentStep ? 'text-blue-600' : 'text-gray-500'}`}>
753
- {step.title}
754
- </div>
755
- <div className="text-gray-400 text-xs">{step.description}</div>
756
- </div>
757
- {index < steps.length - 1 && (
758
- <div className={`w-16 h-px mx-4 ${index < currentStep ? 'bg-blue-600' : 'bg-gray-200'}`} />
759
- )}
760
- </div>
761
- ))}
762
- </div>
763
-
764
- <Card className="p-6">
765
- {renderStep()}
766
- </Card>
767
-
768
- <div className="flex justify-between">
769
- <Button
770
- variant="outline"
771
- onClick={prevStep}
772
- disabled={currentStep === 0}
773
- >
774
- Previous
775
- </Button>
776
-
777
- {currentStep === steps.length - 1 ? (
778
- <Button
779
- onClick={generateProjectFiles}
780
- className="bg-green-600 hover:bg-green-700"
781
- >
782
- Generate Project
783
- </Button>
784
- ) : (
785
- <Button
786
- onClick={nextStep}
787
- disabled={!canProceed()}
788
- >
789
- Next
790
- </Button>
791
- )}
792
- </div>
793
- </div>
794
- );
795
- };
796
-
797
- export default ProjectScaffoldWizard;