servcraft 0.4.5 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "servcraft",
3
- "version": "0.4.5",
3
+ "version": "0.4.8",
4
4
  "description": "A modular, production-ready Node.js backend framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -926,3 +926,6 @@ async function performSmartMerge(
926
926
 
927
927
  InteractivePrompt.showMergeSummary(stats);
928
928
  }
929
+
930
+ // Export helper functions for use in other commands
931
+ export { generateModuleFiles, EnvManager, TemplateManager };
@@ -7,6 +7,7 @@ import chalk from 'chalk';
7
7
  import { execSync } from 'child_process';
8
8
  import { ensureDir, writeFile, error, warn } from '../utils/helpers.js';
9
9
  import { DryRunManager } from '../utils/dry-run.js';
10
+ import { generateModuleFiles } from './add-module.js';
10
11
 
11
12
  interface InitOptions {
12
13
  name: string;
@@ -49,15 +50,36 @@ export const initCommand = new Command('init')
49
50
  console.log(chalk.yellow('\n⚠ DRY RUN MODE - No files will be written\n'));
50
51
  }
51
52
 
53
+ console.log('');
54
+ console.log(chalk.cyan('╭───────────────────────────────────────╮'));
55
+ console.log(chalk.cyan('│') + ' ' + chalk.cyan('│'));
52
56
  console.log(
53
- chalk.blue(`
54
- ╔═══════════════════════════════════════════╗
55
- ║ ║
56
- ║ ${chalk.bold('🚀 Servcraft Project Generator')} ║
57
- ║ ║
58
- ╚═══════════════════════════════════════════╝
59
- `)
57
+ chalk.cyan('│') +
58
+ ' ' +
59
+ chalk.bold.white('🚀 Servcraft') +
60
+ chalk.gray(' - Project Generator') +
61
+ ' ' +
62
+ chalk.cyan('│')
60
63
  );
64
+ console.log(
65
+ chalk.cyan('│') +
66
+ ' ' +
67
+ chalk.gray('by ') +
68
+ chalk.blue('Yao Logan') +
69
+ chalk.gray(' (@Le-Sourcier)') +
70
+ ' ' +
71
+ chalk.cyan('│')
72
+ );
73
+ console.log(
74
+ chalk.cyan('│') +
75
+ ' ' +
76
+ chalk.bgBlue.white(' in/yao-logan ') +
77
+ ' ' +
78
+ chalk.cyan('│')
79
+ );
80
+ console.log(chalk.cyan('│') + ' ' + chalk.cyan('│'));
81
+ console.log(chalk.cyan('╰───────────────────────────────────────╯'));
82
+ console.log('');
61
83
 
62
84
  let options: InitOptions;
63
85
 
@@ -77,11 +99,11 @@ export const initCommand = new Command('init')
77
99
  {
78
100
  type: 'input',
79
101
  name: 'name',
80
- message: 'Project name:',
102
+ message: '📦 Project name:',
81
103
  default: name || 'my-servcraft-app',
82
104
  validate: (input: string) => {
83
105
  if (!/^[a-z0-9-_]+$/i.test(input)) {
84
- return 'Project name can only contain letters, numbers, hyphens, and underscores';
106
+ return 'Project name can only contain letters, numbers, hyphens, and underscores';
85
107
  }
86
108
  return true;
87
109
  },
@@ -89,58 +111,58 @@ export const initCommand = new Command('init')
89
111
  {
90
112
  type: 'list',
91
113
  name: 'language',
92
- message: 'Select language:',
114
+ message: '💻 Select language:',
93
115
  choices: [
94
- { name: 'TypeScript (Recommended)', value: 'typescript' },
95
- { name: 'JavaScript', value: 'javascript' },
116
+ { name: 'TypeScript (Recommended)', value: 'typescript' },
117
+ { name: ' JavaScript', value: 'javascript' },
96
118
  ],
97
119
  default: 'typescript',
98
120
  },
99
121
  {
100
122
  type: 'list',
101
123
  name: 'moduleSystem',
102
- message: 'Select module system:',
124
+ message: '📦 Select module system:',
103
125
  choices: [
104
- { name: 'ESM (import/export) - Recommended', value: 'esm' },
105
- { name: 'CommonJS (require/module.exports)', value: 'commonjs' },
126
+ { name: 'ESM (import/export) - Recommended', value: 'esm' },
127
+ { name: ' CommonJS (require/module.exports)', value: 'commonjs' },
106
128
  ],
107
129
  default: 'esm',
108
130
  },
109
131
  {
110
132
  type: 'list',
111
133
  name: 'database',
112
- message: 'Select database:',
134
+ message: '🗄️ Select database:',
113
135
  choices: [
114
- { name: 'PostgreSQL (Recommended for SQL)', value: 'postgresql' },
115
- { name: 'MySQL', value: 'mysql' },
116
- { name: 'SQLite (Development)', value: 'sqlite' },
117
- { name: 'MongoDB (NoSQL)', value: 'mongodb' },
118
- { name: 'None (Add later)', value: 'none' },
136
+ { name: 'PostgreSQL (Recommended)', value: 'postgresql' },
137
+ { name: ' MySQL', value: 'mysql' },
138
+ { name: ' SQLite (Development)', value: 'sqlite' },
139
+ { name: ' MongoDB (NoSQL)', value: 'mongodb' },
140
+ { name: ' None (Add later)', value: 'none' },
119
141
  ],
120
142
  default: 'postgresql',
121
143
  },
122
144
  {
123
145
  type: 'list',
124
146
  name: 'validator',
125
- message: 'Select validation library:',
147
+ message: 'Select validation library:',
126
148
  choices: [
127
- { name: 'Zod (Recommended - TypeScript-first)', value: 'zod' },
128
- { name: 'Joi (Battle-tested, feature-rich)', value: 'joi' },
129
- { name: 'Yup (Inspired by Joi, lighter)', value: 'yup' },
149
+ { name: 'Zod (TypeScript-first)', value: 'zod' },
150
+ { name: ' Joi (Battle-tested)', value: 'joi' },
151
+ { name: ' Yup (Lightweight)', value: 'yup' },
130
152
  ],
131
153
  default: 'zod',
132
154
  },
133
155
  {
134
156
  type: 'checkbox',
135
157
  name: 'features',
136
- message: 'Select features to include:',
158
+ message: '🔧 Select features to include:',
137
159
  choices: [
138
160
  { name: 'Authentication (JWT)', value: 'auth', checked: true },
139
161
  { name: 'User Management', value: 'users', checked: true },
140
162
  { name: 'Email Service', value: 'email', checked: true },
141
163
  { name: 'Audit Logs', value: 'audit', checked: false },
142
164
  { name: 'File Upload', value: 'upload', checked: false },
143
- { name: 'Redis Cache', value: 'redis', checked: false },
165
+ { name: 'Redis Cache', value: 'cache', checked: false },
144
166
  ],
145
167
  },
146
168
  ]);
@@ -284,6 +306,24 @@ export const initCommand = new Command('init')
284
306
 
285
307
  spinner.succeed('Project files generated!');
286
308
 
309
+ // Install selected feature modules
310
+ if (options.features && options.features.length > 0 && !cmdOptions?.dryRun) {
311
+ const moduleSpinner = ora('Installing selected modules...').start();
312
+
313
+ try {
314
+ for (const feature of options.features) {
315
+ moduleSpinner.text = `Installing ${feature} module...`;
316
+ const moduleDir = path.join(projectDir, 'src/modules', feature);
317
+ await ensureDir(moduleDir);
318
+ await generateModuleFiles(feature, moduleDir);
319
+ }
320
+ moduleSpinner.succeed(`${options.features.length} module(s) installed!`);
321
+ } catch (err) {
322
+ moduleSpinner.fail('Failed to install some modules');
323
+ warn(` Error: ${err instanceof Error ? err.message : 'Unknown error'}`);
324
+ }
325
+ }
326
+
287
327
  // Install dependencies (skip in dry-run mode)
288
328
  if (!cmdOptions?.dryRun) {
289
329
  const installSpinner = ora('Installing dependencies...').start();