@apexkrrish/create-node-app 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cli.js CHANGED
@@ -1,189 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { program } from 'commander';
4
- import inquirer from 'inquirer';
5
- import fs from 'fs';
6
- import path from 'path';
7
- import { fileURLToPath } from 'url';
8
- import chalk from 'chalk';
9
- import { execSync } from 'child_process';
10
- import ora from 'ora';
11
-
12
- const __filename = fileURLToPath(import.meta.url);
13
- const __dirname = path.dirname(__filename);
14
-
15
- // ==========================================
16
- // Helper Functions
17
- // ==========================================
18
-
19
- async function promptUser(projectDirectory) {
20
- let targetDir = projectDirectory;
21
-
22
- if (!targetDir) {
23
- const answers = await inquirer.prompt([
24
- {
25
- type: 'input',
26
- name: 'projectDirectory',
27
- message: 'What is your project named?',
28
- default: 'my-app'
29
- }
30
- ]);
31
- targetDir = answers.projectDirectory;
32
- }
33
-
34
- const { packageManager, database } = await inquirer.prompt([
35
- {
36
- type: 'list',
37
- name: 'packageManager',
38
- message: 'Which package manager would you like to use?',
39
- choices: ['npm', 'yarn', 'pnpm'],
40
- default: 'npm'
41
- },
42
- {
43
- type: 'list',
44
- name: 'database',
45
- message: 'Which database would you like to use?',
46
- choices: ['MongoDB (Mongoose)', 'PostgreSQL (Sequelize)', 'None'],
47
- default: 'MongoDB (Mongoose)'
48
- }
49
- ]);
50
-
51
- return { targetDir, packageManager, database };
52
- }
53
-
54
- function copyTemplateFiles(templateDir, targetPath) {
55
- const spinner = ora('Copying template files...').start();
56
-
57
- if (fs.existsSync(targetPath)) {
58
- spinner.fail(`Directory ${path.basename(targetPath)} already exists.`);
59
- process.exit(1);
60
- }
61
-
62
- fs.mkdirSync(targetPath, { recursive: true });
63
-
64
- const copyRecursiveSync = (src, dest) => {
65
- const exists = fs.existsSync(src);
66
- const stats = exists && fs.statSync(src);
67
- if (exists && stats.isDirectory()) {
68
- if (!fs.existsSync(dest)) fs.mkdirSync(dest);
69
- fs.readdirSync(src).forEach((child) => {
70
- if (child === 'node_modules') return;
71
- copyRecursiveSync(path.join(src, child), path.join(dest, child));
72
- });
73
- } else {
74
- fs.copyFileSync(src, dest);
75
- }
76
- };
77
-
78
- try {
79
- copyRecursiveSync(templateDir, targetPath);
80
- spinner.succeed('Template copied successfully.');
81
- } catch (err) {
82
- spinner.fail('Failed to copy template.');
83
- console.error(err);
84
- process.exit(1);
85
- }
86
- }
87
-
88
- function configureDatabase(targetPath, database) {
89
- const packageJsonPath = path.join(targetPath, 'package.json');
90
- if (!fs.existsSync(packageJsonPath)) return;
91
-
92
- const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
93
- pkg.name = path.basename(targetPath);
94
-
95
- const dbConfigPath = path.join(targetPath, 'config', 'db.config.js');
96
- const targetConfigDir = path.dirname(dbConfigPath);
97
- if (!fs.existsSync(targetConfigDir)) {
98
- fs.mkdirSync(targetConfigDir, { recursive: true });
99
- }
100
-
101
- if (database === 'MongoDB (Mongoose)') {
102
- pkg.dependencies = pkg.dependencies || {};
103
- pkg.dependencies.mongoose = '^8.0.0';
104
-
105
- const mongooseContent = `import mongoose from "mongoose"
106
-
107
- const options = {
108
- serverSelectionTimeoutMS: 10000,
109
- dbName: '',
110
- }
111
-
112
- const connectDB = async () => {
113
- try {
114
- await mongoose.connect('', options)
115
- console.log(\`✅ MongoDB connected!\`)
116
- } catch (error) {
117
- console.error(\`❌ MongoDB connection error: \${error.message}\`)
118
- process.exit(1)
119
- }
120
- }
121
-
122
- export default connectDB`;
123
- fs.writeFileSync(dbConfigPath, mongooseContent);
124
-
125
- } else if (database === 'PostgreSQL (Sequelize)') {
126
- pkg.dependencies = pkg.dependencies || {};
127
- pkg.dependencies.sequelize = '^6.35.0';
128
- pkg.dependencies.pg = '^8.11.3';
129
- pkg.dependencies.pg_hstore = '^2.3.4';
130
-
131
- const sequelizeContent = `import { Sequelize } from "sequelize"
132
-
133
- export const sequelize = new Sequelize(
134
- '', // DB name
135
- '', // User
136
- '', // Password
137
- {
138
- host: '',
139
- dialect: 'postgres',
140
- logging: false,
141
- port: ''
142
- }
143
- )
144
-
145
- // Test connection
146
- // (async () => {
147
- // try {
148
- // await sequelize.authenticate();
149
- // console.log("PostgreSQL connected with Sequelize");
150
- // } catch (err) {
151
- // console.error("Error:", err.message);
152
- // }
153
- // })()
154
-
155
- export default sequelize
156
- `;
157
- fs.writeFileSync(dbConfigPath, sequelizeContent);
158
-
159
- } else {
160
- fs.writeFileSync(dbConfigPath, '// No database configured\n');
161
- }
162
-
163
- // Save updated package.json
164
- fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2));
165
- }
166
-
167
- function installDependencies(targetPath, packageManager) {
168
- const installSpinner = ora(`Installing dependencies using ${packageManager}...`).start();
169
- try {
170
- execSync(`${packageManager} install`, { cwd: targetPath, stdio: 'pipe' });
171
- installSpinner.succeed('Dependencies installed successfully.');
172
- } catch (err) {
173
- installSpinner.fail('Failed to install dependencies.');
174
- console.error(err);
175
- }
176
- }
177
-
178
- function showSuccessMessage(targetDir, targetPath, packageManager) {
179
- console.log(`\n${chalk.green('Success!')} Created ${path.basename(targetPath)} at ${targetPath}`);
180
- console.log('\nInside that directory, you can run several commands:\n');
181
- console.log(` ${chalk.cyan(`${packageManager} run dev`)}`);
182
- console.log(' Starts the development server with nodemon.\n');
183
- console.log('We suggest that you begin by typing:\n');
184
- console.log(` ${chalk.cyan('cd')} ${targetDir}`);
185
- console.log(` ${chalk.cyan(`${packageManager} run dev`)}\n`);
186
- }
4
+ import { initCommand } from './commands/init.js';
5
+ import { createServiceCommand } from './commands/createService.js';
187
6
 
188
7
  // ==========================================
189
8
  // CLI Application
@@ -191,28 +10,17 @@ function showSuccessMessage(targetDir, targetPath, packageManager) {
191
10
 
192
11
  program
193
12
  .name('create-node-app')
194
- .description('Scaffold a new Node.js application')
195
- .argument('[project-directory]', 'Directory to create the project in')
196
- .action(async (projectDirectory) => {
197
-
198
- // 1. Prompt User
199
- const { targetDir, packageManager, database } = await promptUser(projectDirectory);
200
- const targetPath = path.resolve(process.cwd(), targetDir);
201
- const templateDir = path.join(__dirname, '..', 'template');
202
-
203
- console.log(`\nCreating a new Node.js app in ${chalk.green(targetPath)}\n`);
13
+ .description('Scaffold a new Node.js application');
204
14
 
205
- // 2. Copy Template Files
206
- copyTemplateFiles(templateDir, targetPath);
207
-
208
- // 3. Configure Database
209
- configureDatabase(targetPath, database);
210
-
211
- // 4. Install Dependencies
212
- installDependencies(targetPath, packageManager);
15
+ program
16
+ .command('init [project-directory]', { isDefault: true })
17
+ .description('Initialize a new Node.js project (Default command)')
18
+ .action(initCommand);
213
19
 
214
- // 5. Success Message
215
- showSuccessMessage(targetDir, targetPath, packageManager);
216
- });
20
+ program
21
+ .command('create-service <serviceName>')
22
+ .alias('create')
23
+ .description('Scaffold a new service (model, controller, routes)')
24
+ .action(createServiceCommand);
217
25
 
218
26
  program.parse(process.argv);
@@ -0,0 +1,147 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+
6
+ export async function createServiceCommand(serviceName, targetDir = process.cwd()) {
7
+ if (!serviceName) {
8
+ console.error(chalk.red('Please provide a service name. Example: create-node-app create-service auth'));
9
+ process.exit(1);
10
+ }
11
+
12
+ const currentDir = targetDir;
13
+ const packageJsonPath = path.join(currentDir, 'package.json');
14
+
15
+ // Default to no database if not found
16
+ let dbType = 'none';
17
+
18
+ if (fs.existsSync(packageJsonPath)) {
19
+ try {
20
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
21
+ const deps = pkg.dependencies || {};
22
+ if (deps.mongoose) {
23
+ dbType = 'mongoose';
24
+ } else if (deps.sequelize) {
25
+ dbType = 'sequelize';
26
+ }
27
+ } catch (error) {
28
+ console.warn(chalk.yellow('Could not parse package.json. Defaulting to standard model generation.'));
29
+ }
30
+ } else {
31
+ console.warn(chalk.yellow('No package.json found in current directory. Generating service without database dependencies.'));
32
+ }
33
+
34
+ const serviceDir = path.join(currentDir, 'services', serviceName);
35
+ const controllerDir = path.join(serviceDir, 'controller');
36
+ const modelDir = path.join(serviceDir, 'model');
37
+ const routesDir = path.join(serviceDir, 'routes');
38
+
39
+ const spinner = ora(`Generating ${serviceName} service...`).start();
40
+
41
+ try {
42
+ // Create directories
43
+ fs.mkdirSync(controllerDir, { recursive: true });
44
+ fs.mkdirSync(modelDir, { recursive: true });
45
+ fs.mkdirSync(routesDir, { recursive: true });
46
+
47
+ // Generate Controller
48
+ const controllerContent = `export default {
49
+ // Add your controller methods here
50
+ // exampleMethod: async (req, res, next) => { ... }
51
+ }
52
+ `;
53
+ fs.writeFileSync(path.join(controllerDir, `${serviceName}.controller.js`), controllerContent);
54
+
55
+ // Generate Routes
56
+ const routesContent = `import express from 'express'
57
+ import ${serviceName}Controller from '../controller/${serviceName}.controller.js'
58
+
59
+ const router = express.Router({ caseSensitive: true })
60
+
61
+ // Add your routes here
62
+ // router.get('/', ${serviceName}Controller.exampleMethod)
63
+
64
+ export default router
65
+ `;
66
+ fs.writeFileSync(path.join(routesDir, `${serviceName}.routes.js`), routesContent);
67
+
68
+ // Generate Model
69
+ let modelContent = '';
70
+ if (dbType === 'sequelize') {
71
+ modelContent = `import { DataTypes } from 'sequelize'
72
+ import sequelize from '../../../config/db.config.js'
73
+
74
+ const ${serviceName.charAt(0).toUpperCase() + serviceName.slice(1)} = sequelize.define('${serviceName}', {
75
+ name: {
76
+ type: DataTypes.STRING,
77
+ allowNull: false
78
+ }
79
+ }, {
80
+ timestamps: true
81
+ })
82
+
83
+ export default ${serviceName.charAt(0).toUpperCase() + serviceName.slice(1)}
84
+ `;
85
+ } else {
86
+ // Default to mongoose structure
87
+ modelContent = `import mongoose from "mongoose";
88
+
89
+ const ${serviceName}Schema = new mongoose.Schema({
90
+
91
+ })
92
+
93
+ export default mongoose.model('${serviceName}', ${serviceName}Schema);
94
+ `;
95
+ }
96
+
97
+ fs.writeFileSync(path.join(modelDir, `${serviceName}.model.js`), modelContent);
98
+
99
+ // Try to update app.js automatically
100
+ const appJsPath = path.join(currentDir, 'app.js');
101
+ if (fs.existsSync(appJsPath)) {
102
+ let appJsContent = fs.readFileSync(appJsPath, 'utf8');
103
+
104
+ const importStatement = `import ${serviceName}Routes from './services/${serviceName}/routes/${serviceName}.routes.js'`;
105
+ const useStatement = `app.use('/api/${serviceName}', ${serviceName}Routes)`;
106
+
107
+ // Inject import statement after the last import
108
+ if (!appJsContent.includes(importStatement)) {
109
+ const lastImportIndex = appJsContent.lastIndexOf('import ');
110
+ if (lastImportIndex !== -1) {
111
+ const endOfLastImport = appJsContent.indexOf('\n', lastImportIndex);
112
+ appJsContent = appJsContent.slice(0, endOfLastImport + 1) + importStatement + '\n' + appJsContent.slice(endOfLastImport + 1);
113
+ } else {
114
+ appJsContent = importStatement + '\n' + appJsContent;
115
+ }
116
+ }
117
+
118
+ // Inject app.use statement before app.get('/', or before export default
119
+ if (!appJsContent.includes(useStatement)) {
120
+ const appGetIndex = appJsContent.indexOf("app.get('/'");
121
+ if (appGetIndex !== -1) {
122
+ appJsContent = appJsContent.slice(0, appGetIndex) + useStatement + '\n\n' + appJsContent.slice(appGetIndex);
123
+ } else {
124
+ const exportIndex = appJsContent.lastIndexOf('export default app');
125
+ if (exportIndex !== -1) {
126
+ appJsContent = appJsContent.slice(0, exportIndex) + useStatement + '\n\n' + appJsContent.slice(exportIndex);
127
+ } else {
128
+ appJsContent += '\n' + useStatement + '\n';
129
+ }
130
+ }
131
+ }
132
+
133
+ fs.writeFileSync(appJsPath, appJsContent);
134
+ spinner.succeed(`Successfully created ${chalk.green(serviceName)} service and updated app.js`);
135
+ } else {
136
+ spinner.succeed(`Successfully created ${chalk.green(serviceName)} service at ./services/${serviceName}`);
137
+ console.log(`\nDon't forget to register your routes in ${chalk.cyan('app.js')}!`);
138
+ console.log(` import ${serviceName}Routes from './services/${serviceName}/routes/${serviceName}.routes.js'`);
139
+ console.log(` app.use('/api/${serviceName}', ${serviceName}Routes)\n`);
140
+ }
141
+
142
+ } catch (err) {
143
+ spinner.fail(`Failed to create ${serviceName} service.`);
144
+ console.error(err);
145
+ process.exit(1);
146
+ }
147
+ }
@@ -0,0 +1,33 @@
1
+ import path from 'path';
2
+ import chalk from 'chalk';
3
+ import { fileURLToPath } from 'url';
4
+ import { promptUser, copyTemplateFiles, installDependencies, showSuccessMessage } from '../utils/helpers.js';
5
+ import { configureDatabase } from '../utils/database.js';
6
+ import { createServiceCommand } from './createService.js';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+
11
+ export async function initCommand(projectDirectory) {
12
+ // 1. Prompt User
13
+ const { targetDir, packageManager, database } = await promptUser(projectDirectory);
14
+ const targetPath = path.resolve(process.cwd(), targetDir);
15
+ const templateDir = path.join(__dirname, '..', '..', 'template');
16
+
17
+ console.log(`\nCreating a new Node.js app in ${chalk.green(targetPath)}\n`);
18
+
19
+ // 2. Copy Template Files
20
+ copyTemplateFiles(templateDir, targetPath);
21
+
22
+ // 3. Configure Database
23
+ configureDatabase(targetPath, database);
24
+
25
+ // 4. Dynamically generate the 'auth' service so it uses the correct DB model
26
+ await createServiceCommand('auth', targetPath);
27
+
28
+ // 5. Install Dependencies
29
+ installDependencies(targetPath, packageManager);
30
+
31
+ // 6. Success Message
32
+ showSuccessMessage(targetDir, targetPath, packageManager);
33
+ }
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { program } from 'commander';
4
+ import { createServiceCommand } from './commands/createService.js';
5
+
6
+ program
7
+ .name('create-service')
8
+ .description('Scaffold a new service (model, controller, routes)')
9
+ .argument('<serviceName>', 'Name of the service to create')
10
+ .action(createServiceCommand);
11
+
12
+ program.parse(process.argv);
@@ -0,0 +1,81 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ export function configureDatabase(targetPath, database) {
5
+ const packageJsonPath = path.join(targetPath, 'package.json');
6
+ if (!fs.existsSync(packageJsonPath)) return;
7
+
8
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
9
+ pkg.name = path.basename(targetPath);
10
+
11
+ const dbConfigPath = path.join(targetPath, 'config', 'db.config.js');
12
+ const targetConfigDir = path.dirname(dbConfigPath);
13
+ if (!fs.existsSync(targetConfigDir)) {
14
+ fs.mkdirSync(targetConfigDir, { recursive: true });
15
+ }
16
+
17
+ if (database === 'MongoDB (Mongoose)') {
18
+ pkg.dependencies = pkg.dependencies || {};
19
+ pkg.dependencies.mongoose = '^8.0.0';
20
+
21
+ const mongooseContent = `import mongoose from "mongoose"
22
+
23
+ const options = {
24
+ serverSelectionTimeoutMS: 10000,
25
+ dbName: '',
26
+ }
27
+
28
+ const connectDB = async () => {
29
+ try {
30
+ await mongoose.connect('', options)
31
+ console.log(\`✅ MongoDB connected!\`)
32
+ } catch (error) {
33
+ console.error(\`❌ MongoDB connection error: \${error.message}\`)
34
+ process.exit(1)
35
+ }
36
+ }
37
+
38
+ export default connectDB`;
39
+ fs.writeFileSync(dbConfigPath, mongooseContent);
40
+
41
+ } else if (database === 'PostgreSQL (Sequelize)') {
42
+ pkg.dependencies = pkg.dependencies || {};
43
+ pkg.dependencies.sequelize = '^6.35.0';
44
+ pkg.dependencies.pg = '^8.11.3';
45
+ pkg.dependencies['pg-hstore'] = '^2.3.4';
46
+
47
+ const sequelizeContent = `import { Sequelize } from "sequelize"
48
+
49
+ export const sequelize = new Sequelize(
50
+ '', // DB name
51
+ '', // User
52
+ '', // Password
53
+ {
54
+ host: '',
55
+ dialect: 'postgres',
56
+ logging: false,
57
+ port: ''
58
+ }
59
+ )
60
+
61
+ // Test connection
62
+ // (async () => {
63
+ // try {
64
+ // await sequelize.authenticate();
65
+ // console.log("PostgreSQL connected with Sequelize");
66
+ // } catch (err) {
67
+ // console.error("Error:", err.message);
68
+ // }
69
+ // })()
70
+
71
+ export default sequelize
72
+ `;
73
+ fs.writeFileSync(dbConfigPath, sequelizeContent);
74
+
75
+ } else {
76
+ fs.writeFileSync(dbConfigPath, '// No database configured\n');
77
+ }
78
+
79
+ // Save updated package.json
80
+ fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2));
81
+ }
@@ -0,0 +1,96 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import { execSync } from 'child_process';
5
+ import ora from 'ora';
6
+ import inquirer from 'inquirer';
7
+
8
+ export async function promptUser(projectDirectory) {
9
+ let targetDir = projectDirectory;
10
+
11
+ if (!targetDir) {
12
+ const answers = await inquirer.prompt([
13
+ {
14
+ type: 'input',
15
+ name: 'projectDirectory',
16
+ message: 'What is your project named?',
17
+ default: 'my-app'
18
+ }
19
+ ]);
20
+ targetDir = answers.projectDirectory;
21
+ }
22
+
23
+ const { packageManager, database } = await inquirer.prompt([
24
+ {
25
+ type: 'list',
26
+ name: 'packageManager',
27
+ message: 'Which package manager would you like to use?',
28
+ choices: ['npm', 'yarn', 'pnpm'],
29
+ default: 'npm'
30
+ },
31
+ {
32
+ type: 'list',
33
+ name: 'database',
34
+ message: 'Which database would you like to use?',
35
+ choices: ['MongoDB (Mongoose)', 'PostgreSQL (Sequelize)', 'None'],
36
+ default: 'MongoDB (Mongoose)'
37
+ }
38
+ ]);
39
+
40
+ return { targetDir, packageManager, database };
41
+ }
42
+
43
+ export function copyTemplateFiles(templateDir, targetPath) {
44
+ const spinner = ora('Copying template files...').start();
45
+
46
+ if (fs.existsSync(targetPath)) {
47
+ spinner.fail(`Directory ${path.basename(targetPath)} already exists.`);
48
+ process.exit(1);
49
+ }
50
+
51
+ fs.mkdirSync(targetPath, { recursive: true });
52
+
53
+ const copyRecursiveSync = (src, dest) => {
54
+ const exists = fs.existsSync(src);
55
+ const stats = exists && fs.statSync(src);
56
+ if (exists && stats.isDirectory()) {
57
+ if (!fs.existsSync(dest)) fs.mkdirSync(dest);
58
+ fs.readdirSync(src).forEach((child) => {
59
+ if (child === 'node_modules') return;
60
+ copyRecursiveSync(path.join(src, child), path.join(dest, child));
61
+ });
62
+ } else {
63
+ fs.copyFileSync(src, dest);
64
+ }
65
+ };
66
+
67
+ try {
68
+ copyRecursiveSync(templateDir, targetPath);
69
+ spinner.succeed('Template copied successfully.');
70
+ } catch (err) {
71
+ spinner.fail('Failed to copy template.');
72
+ console.error(err);
73
+ process.exit(1);
74
+ }
75
+ }
76
+
77
+ export function installDependencies(targetPath, packageManager) {
78
+ const installSpinner = ora(`Installing dependencies using ${packageManager}...`).start();
79
+ try {
80
+ execSync(`${packageManager} install`, { cwd: targetPath, stdio: 'pipe' });
81
+ installSpinner.succeed('Dependencies installed successfully.');
82
+ } catch (err) {
83
+ installSpinner.fail('Failed to install dependencies.');
84
+ console.error(err);
85
+ }
86
+ }
87
+
88
+ export function showSuccessMessage(targetDir, targetPath, packageManager) {
89
+ console.log(`\n${chalk.green('Success!')} Created ${path.basename(targetPath)} at ${targetPath}`);
90
+ console.log('\nInside that directory, you can run several commands:\n');
91
+ console.log(` ${chalk.cyan(`${packageManager} run dev`)}`);
92
+ console.log(' Starts the development server with nodemon.\n');
93
+ console.log('We suggest that you begin by typing:\n');
94
+ console.log(` ${chalk.cyan('cd')} ${targetDir}`);
95
+ console.log(` ${chalk.cyan(`${packageManager} run dev`)}\n`);
96
+ }
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "@apexkrrish/create-node-app",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "A CLI tool to scaffold Node.js applications.",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "private": false,
8
8
  "bin": {
9
- "create-node-app": "bin/cli.js"
9
+ "create-node-app": "bin/cli.js",
10
+ "create-service": "bin/create-service-cli.js"
10
11
  },
11
12
  "scripts": {
12
- "start": "node ./bin/cli.js"
13
+ "start": "node ./bin/cli.js",
14
+ "create-service": "node ./bin/cli.js create-service"
13
15
  },
14
16
  "dependencies": {
15
17
  "chalk": "^5.3.0",
package/readme.md CHANGED
@@ -1,51 +1,83 @@
1
- # create-node-app
1
+ # @apexkrrish/create-node-app
2
2
 
3
- A fast and interactive CLI tool to scaffold Node.js applications.
3
+ A powerful and fast CLI tool to scaffold production-ready Node.js applications with built-in database configurations and modular service generation.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Interactive Prompts**: Choose your project name, package manager, and database just by answering simple questions.
8
- - **Multiple Package Managers**: Supports `npm`, `yarn`, and `pnpm`.
9
- - **Database Configuration**: Automatically configures database connections with pre-written boilerplate for:
10
- - MongoDB (using Mongoose)
11
- - PostgreSQL (using Sequelize)
12
- - None (no database setup out-of-the-box)
13
- - **Ready to Go**: Automatically installs dependencies and sets up the basic folder structure based on the provided template.
7
+ - Scaffolds a complete Express.js server structure.
8
+ - Automatic database setup (MongoDB/Mongoose or PostgreSQL/Sequelize).
9
+ - Integrated auto-generator for new service modules (Controllers, Models, Routes).
10
+ - Pre-configured `app.js` with best practices (CORS, compression, error handlers).
14
11
 
15
- ## Usage
12
+ ## Installation & Usage
16
13
 
17
- You can use the CLI directly:
14
+ You don't need to install this globally (though you can if you want). The easiest way to use it is with `npx`.
15
+
16
+ ### 1. Create a New Application
17
+
18
+ To create a brand new Node.js app, simply run:
18
19
 
19
20
  ```bash
20
- npx create-node-app [project-directory]
21
+ npx @apexkrrish/create-node-app my-app
21
22
  ```
23
+ *(If you leave out the `my-app` name, the CLI will ask you for it!)*
24
+
25
+ The CLI will prompt you to choose:
26
+ - Your preferred package manager (`npm`, `yarn`, `pnpm`).
27
+ - Your preferred database (`MongoDB`, `PostgreSQL`, or `None`).
28
+
29
+ It will then automatically scaffold your project, configure the database connection, generate an initial `auth` service tailored to your selected database, and install dependencies!
22
30
 
23
- Or, if you clone locally and link:
31
+ ### 2. Run Your Application
24
32
 
25
33
  ```bash
26
- npm start -- my-new-project
34
+ cd my-app
35
+ npm run dev
27
36
  ```
28
37
 
29
- ### Interactive Prompts
30
-
31
- If you do not provide a project directory, the CLI will ask you for one. It will then prompt you to answer the following:
38
+ ---
32
39
 
33
- 1. **What is your project named?** (if no folder name was supplied)
34
- 2. **Which package manager would you like to use?**
35
- - npm
36
- - yarn
37
- - pnpm
38
- 3. **Which database would you like to use?**
39
- - MongoDB (Mongoose)
40
- - PostgreSQL (Sequelize)
41
- - None
40
+ ## Code Generator: Create Services
42
41
 
43
- ### After Setup
42
+ Once your application is created, this tool comes with an amazing built-in code generator that saves you from writing boilerplate.
44
43
 
45
- Once the tool has finished scaffolding the project and installing dependencies, you can navigate into your new app and start the development server:
44
+ To generate a new service module (for example, a `user` service), navigate into your project folder and run:
46
45
 
47
46
  ```bash
48
- cd <your-project-directory>
49
- npm run dev
47
+ npx create-service user
48
+ ```
49
+
50
+ *(If you installed the CLI globally via `npm install -g @apexkrrish/create-node-app`, you can just type `create-service user`)*
51
+
52
+ ### What it does:
53
+ 1. It creates `services/user/controller/user.controller.js`
54
+ 2. It creates `services/user/routes/user.routes.js`
55
+ 3. It detects the database you chose during setup (Mongoose or Sequelize) and generates the correct `services/user/model/user.model.js` structure automatically!
56
+ 4. **It automatically updates your `app.js` file** to import and register your new routes!
57
+
58
+ ---
59
+
60
+ ## Folder Structure Generated
61
+
62
+ ```
63
+ my-app/
64
+ ├── bin/
65
+ │ └── www
66
+ ├── config/
67
+ │ └── db.config.js # Database connection
68
+ ├── public/
69
+ ├── services/
70
+ │ ├── auth/ # Automatically generated on init
71
+ │ │ ├── controller/
72
+ │ │ ├── model/
73
+ │ │ └── routes/
74
+ │ └── <your-service>/ # Generated via 'create-service'
75
+ ├── utils/
76
+ │ └── helper.utils.js
77
+ ├── app.js # Express configuration (auto-updated)
78
+ └── package.json
50
79
  ```
51
- *(Replace `npm` with your chosen package manager!)*
80
+
81
+ ## License
82
+
83
+ ISC License.