build-app-with 2.0.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 (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +240 -0
  3. package/bin/cli.js +18 -0
  4. package/index.js +3 -0
  5. package/package.json +80 -0
  6. package/src/__tests__/core/error-handler.test.js +99 -0
  7. package/src/__tests__/core/logger.test.js +93 -0
  8. package/src/__tests__/e2e/cli-integration.test.js +220 -0
  9. package/src/__tests__/e2e/framework-generation.test.js +249 -0
  10. package/src/__tests__/setup.js +70 -0
  11. package/src/config/package-mappings.js +110 -0
  12. package/src/constants/index.js +42 -0
  13. package/src/core/error-handler.js +89 -0
  14. package/src/core/logger.js +89 -0
  15. package/src/core/package-manager.js +114 -0
  16. package/src/create-app.js +90 -0
  17. package/src/generators/express/index.js +52 -0
  18. package/src/generators/express/project-generator.js +367 -0
  19. package/src/generators/express/prompts.js +74 -0
  20. package/src/generators/express/simple-generator.js +275 -0
  21. package/src/generators/express/templates/app.js +73 -0
  22. package/src/generators/express/templates/config/database.js +122 -0
  23. package/src/generators/express/templates/config.js +37 -0
  24. package/src/generators/express/templates/controllers.js +49 -0
  25. package/src/generators/express/templates/docker.js +72 -0
  26. package/src/generators/express/templates/middleware/errorHandler.js +49 -0
  27. package/src/generators/express/templates/middleware.js +59 -0
  28. package/src/generators/express/templates/models.js +77 -0
  29. package/src/generators/express/templates/package-json.js +55 -0
  30. package/src/generators/express/templates/readme.js +310 -0
  31. package/src/generators/express/templates/routes.js +36 -0
  32. package/src/generators/express/templates/server.js +59 -0
  33. package/src/generators/express/templates/services.js +55 -0
  34. package/src/generators/express/templates/tests.js +46 -0
  35. package/src/generators/express/templates/utils/logger.js +54 -0
  36. package/src/generators/fastify/index.js +46 -0
  37. package/src/generators/fastify/project-generator.js +373 -0
  38. package/src/generators/fastify/prompts.js +76 -0
  39. package/src/generators/fastify/templates/app.js +179 -0
  40. package/src/generators/fastify/templates/config.js +33 -0
  41. package/src/generators/fastify/templates/docker.js +73 -0
  42. package/src/generators/fastify/templates/models.js +77 -0
  43. package/src/generators/fastify/templates/package-json.js +57 -0
  44. package/src/generators/fastify/templates/plugins.js +38 -0
  45. package/src/generators/fastify/templates/readme.js +328 -0
  46. package/src/generators/fastify/templates/routes.js +32 -0
  47. package/src/generators/fastify/templates/server.js +71 -0
  48. package/src/generators/fastify/templates/services.js +50 -0
  49. package/src/generators/fastify/templates/tests.js +60 -0
  50. package/src/generators/nextjs/dependency-manager.js +99 -0
  51. package/src/generators/nextjs/file-generator.js +256 -0
  52. package/src/generators/nextjs/nextjs-generator.js +177 -0
  53. package/src/generators/nextjs/nextjs-project-generator.js +896 -0
  54. package/src/generators/nextjs/package-mappings.js +51 -0
  55. package/src/generators/nextjs/templates.js +272 -0
  56. package/src/generators/package-json-generator.js +117 -0
  57. package/src/generators/vite/components/CreditComponent.jsx +41 -0
  58. package/src/generators/vite/components/app-component.js +359 -0
  59. package/src/generators/vite/components/main-file.js +88 -0
  60. package/src/generators/vite/eslint-config-generator.js +20 -0
  61. package/src/generators/vite/file-generator.js +796 -0
  62. package/src/generators/vite/prettier-config-generator.js +10 -0
  63. package/src/generators/vite/structures/domain-driven-structure.js +465 -0
  64. package/src/generators/vite/structures/feature-based-structure.js +342 -0
  65. package/src/generators/vite/structures/simple-structure.js +62 -0
  66. package/src/generators/vite/styles/index-css.js +130 -0
  67. package/src/generators/vite/tailwind-config-generator.js +14 -0
  68. package/src/generators/vite/vite-config-generator.js +22 -0
  69. package/src/generators/vite/vite-project-generator.js +263 -0
  70. package/src/generators/vite-project-generator.js +136 -0
  71. package/src/prompts/index.js +262 -0
  72. package/src/types/index.js +113 -0
  73. package/src/utils/answer-helpers.js +24 -0
  74. package/src/utils/credits.js +192 -0
  75. package/src/utils/dependencies.js +25 -0
  76. package/src/utils/messages.js +27 -0
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Winston logger configuration template
3
+ */
4
+
5
+ export function generateLogger(answers) {
6
+ return `import winston from 'winston';
7
+
8
+ const { combine, timestamp, errors, json, printf, colorize } = winston.format;
9
+
10
+ // Custom format for console output
11
+ const consoleFormat = printf(({ level, message, timestamp, stack }) => {
12
+ return \`\${timestamp} [\${level}]: \${stack || message}\`;
13
+ });
14
+
15
+ // Create logger instance
16
+ const logger = winston.createLogger({
17
+ level: process.env.LOG_LEVEL || 'info',
18
+ format: combine(
19
+ timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
20
+ errors({ stack: true }),
21
+ json()
22
+ ),
23
+ defaultMeta: { service: '${answers.projectName}' },
24
+ transports: [
25
+ // Write all logs with level 'error' and below to 'error.log'
26
+ new winston.transports.File({
27
+ filename: 'logs/error.log',
28
+ level: 'error',
29
+ maxsize: 5242880, // 5MB
30
+ maxFiles: 5
31
+ }),
32
+ // Write all logs to 'combined.log'
33
+ new winston.transports.File({
34
+ filename: 'logs/combined.log',
35
+ maxsize: 5242880, // 5MB
36
+ maxFiles: 5
37
+ })
38
+ ]
39
+ });
40
+
41
+ // If we're not in production, log to the console as well
42
+ if (process.env.NODE_ENV !== 'production') {
43
+ logger.add(new winston.transports.Console({
44
+ format: combine(
45
+ colorize(),
46
+ timestamp({ format: 'HH:mm:ss' }),
47
+ consoleFormat
48
+ )
49
+ }));
50
+ }
51
+
52
+ export { logger };
53
+ `;
54
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Fastify project generator
3
+ */
4
+
5
+ import fs from 'fs-extra';
6
+ import path from 'path';
7
+ import inquirer from 'inquirer';
8
+ import { logger } from '../../core/logger.js';
9
+ import { handleError, validateProjectName, validateFramework } from '../../core/error-handler.js';
10
+ import { packageManager } from '../../core/package-manager.js';
11
+ import { generateFastifyProject } from './project-generator.js';
12
+ import { getFastifyPrompts } from './prompts.js';
13
+ import { FRAMEWORKS } from '../../types/index.js';
14
+
15
+ export async function generateFastifyApp(projectPath, rawAnswers) {
16
+ try {
17
+ validateProjectName(rawAnswers.projectName);
18
+ validateFramework(FRAMEWORKS.FASTIFY);
19
+
20
+ const spinner = logger.startSpinner('Setting up Fastify project...');
21
+
22
+ // Get additional Fastify-specific prompts
23
+ const fastifyPrompts = getFastifyPrompts(rawAnswers);
24
+ const fastifyAnswers = await inquirer.prompt(fastifyPrompts);
25
+
26
+ const answers = { ...rawAnswers, ...fastifyAnswers };
27
+
28
+ // Create project directory
29
+ await fs.ensureDir(projectPath);
30
+
31
+ // Generate Fastify project structure
32
+ await generateFastifyProject(projectPath, answers);
33
+
34
+ spinner.succeed('Fastify project created successfully!');
35
+
36
+ // Post-setup instructions
37
+ logger.success(`\n🎉 Your Fastify project "${answers.projectName}" is ready!`);
38
+ logger.info('\nNext steps:');
39
+ logger.info(` cd ${path.basename(projectPath)}`);
40
+ logger.info(' npm install');
41
+ logger.info(' npm run dev');
42
+
43
+ } catch (error) {
44
+ handleError(error, 'Failed to create Fastify project:');
45
+ }
46
+ }
@@ -0,0 +1,373 @@
1
+ /**
2
+ * Fastify project structure generator
3
+ */
4
+
5
+ import fs from 'fs-extra';
6
+ import path from 'path';
7
+ import { logger } from '../../core/logger.js';
8
+ import { packageManager } from '../../core/package-manager.js';
9
+ import { featurePackageMap, frameworkBasePackages } from '../../config/package-mappings.js';
10
+ import { FRAMEWORKS, FEATURES, DATABASES, AUTH_STRATEGIES } from '../../types/index.js';
11
+ import { generatePackageJson } from './templates/package-json.js';
12
+ import { generateAppJs } from './templates/app.js';
13
+ import { generateServerJs } from './templates/server.js';
14
+ import { generatePlugins } from './templates/plugins.js';
15
+ import { generateRoutes } from './templates/routes.js';
16
+ import { generateConfig } from './templates/config.js';
17
+ import { generateModels } from './templates/models.js';
18
+ import { generateServices } from './templates/services.js';
19
+ import { generateTests } from './templates/tests.js';
20
+ import { generateDocker } from './templates/docker.js';
21
+ import { generateReadme } from './templates/readme.js';
22
+
23
+ export async function generateFastifyProject(projectPath, answers) {
24
+ const spinner = logger.startSpinner('Generating Fastify project structure...');
25
+
26
+ try {
27
+ // Generate package.json
28
+ const packageJson = generatePackageJson(answers);
29
+ await fs.writeJSON(path.join(projectPath, 'package.json'), packageJson, { spaces: 2 });
30
+
31
+ // Generate main application files
32
+ await generateAppJs(projectPath, answers);
33
+ await generateServerJs(projectPath, answers);
34
+
35
+ // Generate project structure based on choice
36
+ switch (answers.projectStructure) {
37
+ case 'simple':
38
+ await generateSimpleStructure(projectPath, answers);
39
+ break;
40
+ case 'modular':
41
+ await generateModularStructure(projectPath, answers);
42
+ break;
43
+ case 'plugin-based':
44
+ await generatePluginBasedStructure(projectPath, answers);
45
+ break;
46
+ }
47
+
48
+
49
+ // Generate database models if needed
50
+ if (answers.database !== 'none') {
51
+ const modelsContent = generateModels(projectPath, answers);
52
+ await fs.ensureDir(path.join(projectPath, 'src', 'models'));
53
+ await fs.writeFile(path.join(projectPath, 'src', 'models', 'index.js'), modelsContent);
54
+ }
55
+
56
+ // Generate additional files
57
+ const pluginsContent = generatePlugins(projectPath, answers);
58
+ const routesContent = generateRoutes(projectPath, answers);
59
+ const configContent = generateConfig(projectPath, answers);
60
+ const servicesContent = generateServices(projectPath, answers);
61
+
62
+ // Write plugin files
63
+ await fs.ensureDir(path.join(projectPath, 'src', 'plugins'));
64
+ await fs.writeFile(path.join(projectPath, 'src', 'plugins', 'error-handler.js'), pluginsContent);
65
+
66
+ // Write routes files
67
+ await fs.ensureDir(path.join(projectPath, 'src', 'routes'));
68
+ await fs.writeFile(path.join(projectPath, 'src', 'routes', 'index.js'), routesContent);
69
+
70
+ // Write config files
71
+ await fs.ensureDir(path.join(projectPath, 'src', 'config'));
72
+ await fs.writeFile(path.join(projectPath, 'src', 'config', 'index.js'), configContent);
73
+
74
+ // Write services files
75
+ await fs.ensureDir(path.join(projectPath, 'src', 'services'));
76
+ await fs.writeFile(path.join(projectPath, 'src', 'services', 'index.js'), servicesContent);
77
+
78
+ // Generate tests if requested
79
+ if (answers.includeTests) {
80
+ const testsContent = generateTests(projectPath, answers);
81
+ await fs.ensureDir(path.join(projectPath, 'tests'));
82
+ await fs.writeFile(path.join(projectPath, 'tests', 'app.test.js'), testsContent);
83
+ }
84
+
85
+ // Generate Docker files if requested
86
+ if (answers.includeDocker) {
87
+ const { dockerfile, dockerCompose } = generateDocker(projectPath, answers);
88
+ await fs.writeFile(path.join(projectPath, 'Dockerfile'), dockerfile);
89
+ await fs.writeFile(path.join(projectPath, 'docker-compose.yml'), dockerCompose);
90
+ }
91
+
92
+ // Generate README
93
+ await generateReadme(projectPath, answers);
94
+
95
+ // Generate .gitignore
96
+ await generateGitignore(projectPath);
97
+
98
+ // Generate .env.example
99
+ await generateEnvExample(projectPath, answers);
100
+
101
+ spinner.succeed('Project structure generated successfully!');
102
+
103
+ // Skip dependency installation for now - let user install manually
104
+ logger.info('Project structure created! Next steps:');
105
+ logger.info(` cd ${path.basename(projectPath)}`);
106
+ logger.info(' npm install');
107
+ logger.info(' npm run dev');
108
+
109
+ } catch (error) {
110
+ spinner.fail('Failed to generate project structure');
111
+ throw error;
112
+ }
113
+ }
114
+
115
+ async function generateSimpleStructure(projectPath, answers) {
116
+ const srcDir = path.join(projectPath, 'src');
117
+ await fs.ensureDir(srcDir);
118
+
119
+ // Create basic structure
120
+ await fs.ensureDir(path.join(srcDir, 'routes'));
121
+ await fs.ensureDir(path.join(srcDir, 'plugins'));
122
+ await fs.ensureDir(path.join(srcDir, 'utils'));
123
+ await fs.ensureDir(path.join(srcDir, 'config'));
124
+ }
125
+
126
+ async function generateModularStructure(projectPath, answers) {
127
+ const srcDir = path.join(projectPath, 'src');
128
+ await fs.ensureDir(srcDir);
129
+
130
+ // Create modular structure
131
+ const modules = ['auth', 'users', 'api'];
132
+ for (const module of modules) {
133
+ await fs.ensureDir(path.join(srcDir, 'modules', module, 'routes'));
134
+ await fs.ensureDir(path.join(srcDir, 'modules', module, 'services'));
135
+ await fs.ensureDir(path.join(srcDir, 'modules', module, 'models'));
136
+ await fs.ensureDir(path.join(srcDir, 'modules', module, 'plugins'));
137
+ }
138
+
139
+ await fs.ensureDir(path.join(srcDir, 'shared', 'plugins'));
140
+ await fs.ensureDir(path.join(srcDir, 'shared', 'utils'));
141
+ await fs.ensureDir(path.join(srcDir, 'shared', 'config'));
142
+ }
143
+
144
+ async function generatePluginBasedStructure(projectPath, answers) {
145
+ const srcDir = path.join(projectPath, 'src');
146
+ await fs.ensureDir(srcDir);
147
+
148
+ // Create plugin-based structure
149
+ await fs.ensureDir(path.join(srcDir, 'plugins'));
150
+ await fs.ensureDir(path.join(srcDir, 'routes'));
151
+ await fs.ensureDir(path.join(srcDir, 'services'));
152
+ await fs.ensureDir(path.join(srcDir, 'models'));
153
+ await fs.ensureDir(path.join(srcDir, 'utils'));
154
+ await fs.ensureDir(path.join(srcDir, 'config'));
155
+ await fs.ensureDir(path.join(srcDir, 'schemas'));
156
+ }
157
+
158
+ async function generateGitignore(projectPath) {
159
+ const gitignore = `# Dependencies
160
+ node_modules/
161
+ npm-debug.log*
162
+ yarn-debug.log*
163
+ yarn-error.log*
164
+ pnpm-debug.log*
165
+
166
+ # Environment variables
167
+ .env
168
+ .env.local
169
+ .env.development.local
170
+ .env.test.local
171
+ .env.production.local
172
+
173
+ # Logs
174
+ logs
175
+ *.log
176
+
177
+ # Runtime data
178
+ pids
179
+ *.pid
180
+ *.seed
181
+ *.pid.lock
182
+
183
+ # Coverage directory used by tools like istanbul
184
+ coverage/
185
+ *.lcov
186
+
187
+ # nyc test coverage
188
+ .nyc_output
189
+
190
+ # Dependency directories
191
+ node_modules/
192
+ jspm_packages/
193
+
194
+ # Optional npm cache directory
195
+ .npm
196
+
197
+ # Optional eslint cache
198
+ .eslintcache
199
+
200
+ # Optional REPL history
201
+ .node_repl_history
202
+
203
+ # Output of 'npm pack'
204
+ *.tgz
205
+
206
+ # Yarn Integrity file
207
+ .yarn-integrity
208
+
209
+ # dotenv environment variables file
210
+ .env
211
+ .env.test
212
+
213
+ # parcel-bundler cache (https://parceljs.org/)
214
+ .cache
215
+ .parcel-cache
216
+
217
+ # next.js build output
218
+ .next
219
+
220
+ # nuxt.js build output
221
+ .nuxt
222
+
223
+ # vuepress build output
224
+ .vuepress/dist
225
+
226
+ # Serverless directories
227
+ .serverless/
228
+
229
+ # FuseBox cache
230
+ .fusebox/
231
+
232
+ # DynamoDB Local files
233
+ .dynamodb/
234
+
235
+ # TernJS port file
236
+ .tern-port
237
+
238
+ # IDE
239
+ .vscode/
240
+ .idea/
241
+ *.swp
242
+ *.swo
243
+
244
+ # OS
245
+ .DS_Store
246
+ Thumbs.db
247
+
248
+ # Build output
249
+ dist/
250
+ build/
251
+ `;
252
+
253
+ await fs.writeFile(path.join(projectPath, '.gitignore'), gitignore);
254
+ }
255
+
256
+ async function generateEnvExample(projectPath, answers) {
257
+ let envContent = `# Server Configuration
258
+ PORT=3000
259
+ NODE_ENV=development
260
+ HOST=0.0.0.0
261
+
262
+ # Database Configuration
263
+ `;
264
+
265
+ if (answers.database === DATABASES.MONGODB) {
266
+ envContent += `MONGODB_URI=mongodb://localhost:27017/${answers.projectName}
267
+ `;
268
+ } else if (answers.database === DATABASES.POSTGRESQL) {
269
+ envContent += `DATABASE_URL=postgresql://username:password@localhost:5432/${answers.projectName}
270
+ `;
271
+ } else if (answers.database === DATABASES.MYSQL) {
272
+ envContent += `DB_HOST=localhost
273
+ DB_PORT=3306
274
+ DB_NAME=${answers.projectName}
275
+ DB_USER=root
276
+ DB_PASSWORD=password
277
+ `;
278
+ } else if (answers.database === DATABASES.SQLITE) {
279
+ envContent += `DATABASE_URL=file:./dev.db
280
+ `;
281
+ }
282
+
283
+ if (answers.authStrategy && answers.authStrategy !== 'none') {
284
+ envContent += `
285
+ # Authentication
286
+ JWT_SECRET=your-super-secret-jwt-key
287
+ JWT_EXPIRES_IN=7d
288
+ `;
289
+ }
290
+
291
+ if (answers.features.includes(FEATURES.CORS)) {
292
+ envContent += `
293
+ # CORS
294
+ CORS_ORIGIN=http://localhost:3000
295
+ `;
296
+ }
297
+
298
+ if (answers.features.includes('rate-limit')) {
299
+ envContent += `
300
+ # Rate Limiting
301
+ RATE_LIMIT_MAX=100
302
+ RATE_LIMIT_TIME_WINDOW=60000
303
+ `;
304
+ }
305
+
306
+ await fs.writeFile(path.join(projectPath, '.env.example'), envContent);
307
+ }
308
+
309
+ async function installDependencies(projectPath, answers) {
310
+ const packages = [];
311
+
312
+ // Add base Fastify packages
313
+ const basePackages = frameworkBasePackages[FRAMEWORKS.FASTIFY];
314
+ packages.push(...basePackages.deps.map(name => ({ name, version: 'latest', dev: false })));
315
+ packages.push(...basePackages.devDeps.map(name => ({ name, version: 'latest', dev: true })));
316
+
317
+ // Add database packages
318
+ if (answers.database === DATABASES.MONGODB) {
319
+ packages.push({ name: 'mongoose', version: 'latest', dev: false });
320
+ } else if (answers.database === DATABASES.POSTGRESQL || answers.database === DATABASES.SQLITE) {
321
+ packages.push({ name: '@prisma/client', version: 'latest', dev: false });
322
+ packages.push({ name: 'prisma', version: 'latest', dev: true });
323
+ } else if (answers.database === DATABASES.MYSQL) {
324
+ packages.push({ name: 'sequelize', version: 'latest', dev: false });
325
+ packages.push({ name: 'mysql2', version: 'latest', dev: false });
326
+ }
327
+
328
+ // Add authentication packages
329
+ if (answers.authStrategy === AUTH_STRATEGIES.JWT) {
330
+ packages.push({ name: 'jsonwebtoken', version: 'latest', dev: false });
331
+ packages.push({ name: 'bcryptjs', version: 'latest', dev: false });
332
+ } else if (answers.authStrategy === AUTH_STRATEGIES.OAUTH) {
333
+ packages.push({ name: 'passport', version: 'latest', dev: false });
334
+ packages.push({ name: 'passport-local', version: 'latest', dev: false });
335
+ }
336
+
337
+ // Add Fastify-specific packages
338
+ packages.push({ name: '@fastify/cors', version: 'latest', dev: false });
339
+ packages.push({ name: '@fastify/helmet', version: 'latest', dev: false });
340
+ packages.push({ name: '@fastify/rate-limit', version: 'latest', dev: false });
341
+ packages.push({ name: '@fastify/env', version: 'latest', dev: false });
342
+
343
+ // Add feature packages
344
+ for (const feature of answers.features || []) {
345
+ if (feature === 'websocket') {
346
+ packages.push({ name: '@fastify/websocket', version: 'latest', dev: false });
347
+ } else if (feature === 'graphql') {
348
+ packages.push({ name: '@fastify/gql', version: 'latest', dev: false });
349
+ } else if (feature === 'swagger') {
350
+ packages.push({ name: '@fastify/swagger', version: 'latest', dev: false });
351
+ packages.push({ name: '@fastify/swagger-ui', version: 'latest', dev: false });
352
+ } else {
353
+ const featureInfo = featurePackageMap[feature];
354
+ if (featureInfo) {
355
+ if (featureInfo.deps) {
356
+ packages.push(...featureInfo.deps.map(name => ({ name, version: 'latest', dev: false })));
357
+ }
358
+ if (featureInfo.devDeps) {
359
+ packages.push(...featureInfo.devDeps.map(name => ({ name, version: 'latest', dev: true })));
360
+ }
361
+ }
362
+ }
363
+ }
364
+
365
+ // Add testing packages if requested
366
+ if (answers.includeTests) {
367
+ packages.push({ name: 'jest', version: 'latest', dev: true });
368
+ packages.push({ name: 'tap', version: 'latest', dev: true });
369
+ packages.push({ name: '@types/jest', version: 'latest', dev: true });
370
+ }
371
+
372
+ await packageManager.installDependencies(projectPath, packages);
373
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Fastify specific prompts
3
+ */
4
+
5
+ import { FRAMEWORKS, FEATURES, DATABASES, AUTH_STRATEGIES } from '../../types/index.js';
6
+
7
+ export function getFastifyPrompts(answers) {
8
+ return [
9
+ {
10
+ type: 'list',
11
+ name: 'database',
12
+ message: 'Choose a database:',
13
+ choices: [
14
+ { name: 'MongoDB (with Mongoose)', value: DATABASES.MONGODB },
15
+ { name: 'PostgreSQL (with Prisma)', value: DATABASES.POSTGRESQL },
16
+ { name: 'MySQL (with Sequelize)', value: DATABASES.MYSQL },
17
+ { name: 'SQLite (with Prisma)', value: DATABASES.SQLITE },
18
+ { name: 'None', value: 'none' }
19
+ ],
20
+ default: DATABASES.MONGODB
21
+ },
22
+ {
23
+ type: 'list',
24
+ name: 'authStrategy',
25
+ message: 'Choose authentication strategy:',
26
+ choices: [
27
+ { name: 'JWT (JSON Web Tokens)', value: AUTH_STRATEGIES.JWT },
28
+ { name: 'Session-based', value: AUTH_STRATEGIES.SESSION },
29
+ { name: 'OAuth (Passport.js)', value: AUTH_STRATEGIES.OAUTH },
30
+ { name: 'None', value: 'none' }
31
+ ],
32
+ default: AUTH_STRATEGIES.JWT,
33
+ when: (answers) => answers.database !== 'none'
34
+ },
35
+ {
36
+ type: 'checkbox',
37
+ name: 'features',
38
+ message: 'Select additional features:',
39
+ choices: [
40
+ { name: 'CORS support', value: FEATURES.CORS },
41
+ { name: 'Rate limiting', value: 'rate-limit' },
42
+ { name: 'Request logging', value: FEATURES.MORGAN },
43
+ { name: 'Winston logger', value: FEATURES.WINSTON },
44
+ { name: 'Request validation', value: 'fastify-validation' },
45
+ { name: 'API documentation (Swagger)', value: FEATURES.SWAGGER },
46
+ { name: 'Environment variables (.env)', value: FEATURES.DOTENV },
47
+ { name: 'WebSocket support', value: 'websocket' },
48
+ { name: 'GraphQL support', value: 'graphql' }
49
+ ],
50
+ default: [FEATURES.CORS, 'rate-limit', FEATURES.MORGAN, FEATURES.DOTENV]
51
+ },
52
+ {
53
+ type: 'list',
54
+ name: 'projectStructure',
55
+ message: 'Choose project structure:',
56
+ choices: [
57
+ { name: 'Simple (Basic structure)', value: 'simple' },
58
+ { name: 'Modular (Organized by features)', value: 'modular' },
59
+ { name: 'Plugin-based (Fastify plugins)', value: 'plugin-based' }
60
+ ],
61
+ default: 'plugin-based'
62
+ },
63
+ {
64
+ type: 'confirm',
65
+ name: 'includeTests',
66
+ message: 'Include testing setup?',
67
+ default: true
68
+ },
69
+ {
70
+ type: 'confirm',
71
+ name: 'includeDocker',
72
+ message: 'Include Docker configuration?',
73
+ default: false
74
+ }
75
+ ];
76
+ }