@friggframework/devtools 2.0.0--canary.400.bed3308.0 → 2.0.0--canary.404.e9d4980.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 (182) hide show
  1. package/frigg-cli/build-command/index.js +3 -18
  2. package/frigg-cli/deploy-command/index.js +3 -19
  3. package/frigg-cli/index.js +1 -73
  4. package/frigg-cli/install-command/index.js +2 -15
  5. package/frigg-cli/start-command/index.js +2 -17
  6. package/infrastructure/create-frigg-infrastructure.js +2 -2
  7. package/infrastructure/serverless-template.js +79 -529
  8. package/package.json +5 -9
  9. package/frigg-cli/.eslintrc.js +0 -141
  10. package/frigg-cli/__tests__/jest.config.js +0 -102
  11. package/frigg-cli/__tests__/unit/commands/build.test.js +0 -483
  12. package/frigg-cli/__tests__/unit/commands/install.test.js +0 -418
  13. package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -592
  14. package/frigg-cli/__tests__/utils/command-tester.js +0 -170
  15. package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
  16. package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
  17. package/frigg-cli/__tests__/utils/test-setup.js +0 -286
  18. package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -312
  19. package/frigg-cli/generate-command/azure-generator.js +0 -43
  20. package/frigg-cli/generate-command/gcp-generator.js +0 -47
  21. package/frigg-cli/generate-command/index.js +0 -350
  22. package/frigg-cli/generate-command/terraform-generator.js +0 -555
  23. package/frigg-cli/generate-iam-command.js +0 -115
  24. package/frigg-cli/package.json +0 -75
  25. package/frigg-cli/ui-command/index.js +0 -167
  26. package/frigg-cli/utils/app-resolver.js +0 -319
  27. package/frigg-cli/utils/backend-path.js +0 -38
  28. package/frigg-cli/utils/process-manager.js +0 -199
  29. package/frigg-cli/utils/repo-detection.js +0 -405
  30. package/infrastructure/AWS-DISCOVERY-TROUBLESHOOTING.md +0 -245
  31. package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +0 -620
  32. package/infrastructure/DEPLOYMENT-INSTRUCTIONS.md +0 -268
  33. package/infrastructure/GENERATE-IAM-DOCS.md +0 -253
  34. package/infrastructure/IAM-POLICY-TEMPLATES.md +0 -176
  35. package/infrastructure/README-TESTING.md +0 -332
  36. package/infrastructure/README.md +0 -421
  37. package/infrastructure/WEBSOCKET-CONFIGURATION.md +0 -105
  38. package/infrastructure/__tests__/fixtures/mock-aws-resources.js +0 -391
  39. package/infrastructure/__tests__/helpers/test-utils.js +0 -277
  40. package/infrastructure/aws-discovery.js +0 -568
  41. package/infrastructure/aws-discovery.test.js +0 -373
  42. package/infrastructure/build-time-discovery.js +0 -206
  43. package/infrastructure/build-time-discovery.test.js +0 -375
  44. package/infrastructure/frigg-deployment-iam-stack.yaml +0 -393
  45. package/infrastructure/iam-generator.js +0 -810
  46. package/infrastructure/iam-generator.test.js +0 -169
  47. package/infrastructure/iam-policy-basic.json +0 -236
  48. package/infrastructure/iam-policy-full.json +0 -305
  49. package/infrastructure/integration.test.js +0 -383
  50. package/infrastructure/run-discovery.js +0 -110
  51. package/infrastructure/serverless-template.test.js +0 -553
  52. package/management-ui/.eslintrc.js +0 -22
  53. package/management-ui/README.md +0 -203
  54. package/management-ui/components.json +0 -21
  55. package/management-ui/index.html +0 -13
  56. package/management-ui/merge-conflict-cleaner.py +0 -371
  57. package/management-ui/package-lock.json +0 -10997
  58. package/management-ui/package.json +0 -76
  59. package/management-ui/postcss.config.js +0 -6
  60. package/management-ui/server/api/backend.js +0 -256
  61. package/management-ui/server/api/cli.js +0 -315
  62. package/management-ui/server/api/codegen.js +0 -663
  63. package/management-ui/server/api/connections.js +0 -857
  64. package/management-ui/server/api/discovery.js +0 -185
  65. package/management-ui/server/api/environment/index.js +0 -1
  66. package/management-ui/server/api/environment/router.js +0 -378
  67. package/management-ui/server/api/environment.js +0 -328
  68. package/management-ui/server/api/integrations.js +0 -479
  69. package/management-ui/server/api/logs.js +0 -248
  70. package/management-ui/server/api/monitoring.js +0 -282
  71. package/management-ui/server/api/open-ide.js +0 -31
  72. package/management-ui/server/api/project.js +0 -553
  73. package/management-ui/server/api/users/sessions.js +0 -371
  74. package/management-ui/server/api/users/simulation.js +0 -254
  75. package/management-ui/server/api/users.js +0 -362
  76. package/management-ui/server/api-contract.md +0 -275
  77. package/management-ui/server/index.js +0 -428
  78. package/management-ui/server/middleware/errorHandler.js +0 -70
  79. package/management-ui/server/middleware/security.js +0 -32
  80. package/management-ui/server/processManager.js +0 -296
  81. package/management-ui/server/server.js +0 -188
  82. package/management-ui/server/services/aws-monitor.js +0 -413
  83. package/management-ui/server/services/npm-registry.js +0 -347
  84. package/management-ui/server/services/template-engine.js +0 -538
  85. package/management-ui/server/utils/cliIntegration.js +0 -220
  86. package/management-ui/server/utils/environment/auditLogger.js +0 -471
  87. package/management-ui/server/utils/environment/awsParameterStore.js +0 -264
  88. package/management-ui/server/utils/environment/encryption.js +0 -278
  89. package/management-ui/server/utils/environment/envFileManager.js +0 -286
  90. package/management-ui/server/utils/import-commonjs.js +0 -28
  91. package/management-ui/server/utils/response.js +0 -83
  92. package/management-ui/server/websocket/handler.js +0 -325
  93. package/management-ui/src/App.jsx +0 -51
  94. package/management-ui/src/assets/FriggLogo.svg +0 -1
  95. package/management-ui/src/components/AppRouter.jsx +0 -65
  96. package/management-ui/src/components/Button.jsx +0 -2
  97. package/management-ui/src/components/Card.jsx +0 -9
  98. package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
  99. package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
  100. package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
  101. package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
  102. package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
  103. package/management-ui/src/components/ErrorBoundary.jsx +0 -73
  104. package/management-ui/src/components/IntegrationCard.jsx +0 -199
  105. package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -490
  106. package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
  107. package/management-ui/src/components/IntegrationStatus.jsx +0 -235
  108. package/management-ui/src/components/Layout.jsx +0 -250
  109. package/management-ui/src/components/LoadingSpinner.jsx +0 -45
  110. package/management-ui/src/components/RepositoryPicker.jsx +0 -248
  111. package/management-ui/src/components/SessionMonitor.jsx +0 -255
  112. package/management-ui/src/components/StatusBadge.jsx +0 -70
  113. package/management-ui/src/components/UserContextSwitcher.jsx +0 -154
  114. package/management-ui/src/components/UserSimulation.jsx +0 -299
  115. package/management-ui/src/components/Welcome.jsx +0 -434
  116. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
  117. package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
  118. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
  119. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
  120. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
  121. package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
  122. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
  123. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
  124. package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
  125. package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
  126. package/management-ui/src/components/codegen/index.js +0 -10
  127. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
  128. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
  129. package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
  130. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
  131. package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
  132. package/management-ui/src/components/connections/index.js +0 -5
  133. package/management-ui/src/components/index.js +0 -21
  134. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
  135. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
  136. package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
  137. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
  138. package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
  139. package/management-ui/src/components/monitoring/index.js +0 -6
  140. package/management-ui/src/components/monitoring/monitoring.css +0 -218
  141. package/management-ui/src/components/theme-provider.jsx +0 -52
  142. package/management-ui/src/components/theme-toggle.jsx +0 -39
  143. package/management-ui/src/components/ui/badge.tsx +0 -36
  144. package/management-ui/src/components/ui/button.test.jsx +0 -56
  145. package/management-ui/src/components/ui/button.tsx +0 -57
  146. package/management-ui/src/components/ui/card.tsx +0 -76
  147. package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
  148. package/management-ui/src/components/ui/select.tsx +0 -157
  149. package/management-ui/src/components/ui/skeleton.jsx +0 -15
  150. package/management-ui/src/hooks/useFrigg.jsx +0 -387
  151. package/management-ui/src/hooks/useSocket.jsx +0 -58
  152. package/management-ui/src/index.css +0 -194
  153. package/management-ui/src/lib/utils.ts +0 -6
  154. package/management-ui/src/main.jsx +0 -10
  155. package/management-ui/src/pages/CodeGeneration.jsx +0 -14
  156. package/management-ui/src/pages/Connections.jsx +0 -252
  157. package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -427
  158. package/management-ui/src/pages/Dashboard.jsx +0 -311
  159. package/management-ui/src/pages/Environment.jsx +0 -314
  160. package/management-ui/src/pages/IntegrationConfigure.jsx +0 -544
  161. package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -479
  162. package/management-ui/src/pages/IntegrationTest.jsx +0 -494
  163. package/management-ui/src/pages/Integrations.jsx +0 -254
  164. package/management-ui/src/pages/Monitoring.jsx +0 -17
  165. package/management-ui/src/pages/Simulation.jsx +0 -155
  166. package/management-ui/src/pages/Users.jsx +0 -492
  167. package/management-ui/src/services/api.js +0 -41
  168. package/management-ui/src/services/apiModuleService.js +0 -193
  169. package/management-ui/src/services/websocket-handlers.js +0 -120
  170. package/management-ui/src/test/api/project.test.js +0 -273
  171. package/management-ui/src/test/components/Welcome.test.jsx +0 -378
  172. package/management-ui/src/test/mocks/server.js +0 -178
  173. package/management-ui/src/test/setup.js +0 -61
  174. package/management-ui/src/test/utils/test-utils.jsx +0 -134
  175. package/management-ui/src/utils/repository.js +0 -98
  176. package/management-ui/src/utils/repository.test.js +0 -118
  177. package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
  178. package/management-ui/tailwind.config.js +0 -63
  179. package/management-ui/tsconfig.json +0 -37
  180. package/management-ui/tsconfig.node.json +0 -10
  181. package/management-ui/vite.config.js +0 -26
  182. package/management-ui/vitest.config.js +0 -38
@@ -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;