create-jerry 1.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.
package/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # JERRIT: Backend Project Scaffolding Tool
2
+ ---
3
+
4
+ ## Problem Statement:
5
+ A Project Scaffolding Framework similar to Vite.js and Next.js that aims to provide a ready-to-code boilerplate for working with MongoDB or MySQL databases through express.js server. The Project aims to minimize the setup time for building a MERN or SERN app, enhancing productivity and efficiency for developers.
6
+
7
+ ---
8
+
9
+
10
+ ## Project Structure:
11
+ ```
12
+ XeoBuilds/
13
+ |_ Templates/
14
+ | |_ db-mongo.js
15
+ | |_ db-sql.js
16
+ | |_ express.js
17
+ |
18
+ |_ .gitignore
19
+ |_ fileCreator.js
20
+ |_ folderCreator.js
21
+ |_ installer.js
22
+ |_ index.js
23
+ |_ package.json
24
+ |_ package-lock.json
25
+ |_ README.md
26
+ ```
27
+ ---
28
+
29
+
30
+ ## Libraries used to build:
31
+ - inquirer
32
+ - chalk
33
+ - chalkAnimation
34
+ - execSync
35
+ - nanospinner
36
+ - fs module
37
+ <!-- fs/promises module -->
38
+ ---
39
+
40
+
41
+ ## Packages/Libraries for Backend:
42
+ - express
43
+ - cors
44
+ - mongoose
45
+ - mysql2
46
+ - dotenv
47
+ - router
48
+ ---
49
+
50
+
51
+ ## Backend Generated:
52
+ ```
53
+ project-name/
54
+ |_ Models/
55
+ | |_ db.js
56
+ |
57
+ |_ Controller/
58
+ | |_ index.js
59
+ |
60
+ |_ Middleware/
61
+ | |_ handler.js
62
+ |
63
+ |_ Config/
64
+ | |_ .env
65
+ |
66
+ |_ app.js
67
+ |_ package.json
68
+ ```
69
+ ---
70
+
71
+
72
+ ## Demo Video:
73
+ Video Link: https://drive.google.com/file/d/1o_9_5RMI21Inew4knCqXlCmeArhAG3xD/view?usp=sharing
74
+ <!-- ![]() -->
75
+ ---
76
+
77
+
78
+
79
+ <!-- ## Low Level Daigram ## Challenges -->
80
+ # Thank You, Don't forget to add a ⭐
81
+
@@ -0,0 +1,20 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ const userSchema = new mongoose.Schema({
4
+ username: {
5
+ type: String,
6
+ required: true,
7
+ unique: true,
8
+ },
9
+ email: {
10
+ type: String,
11
+ required: true,
12
+ unique: true,
13
+ },
14
+ password: {
15
+ type: String,
16
+ required: true,
17
+ },
18
+ }, { timestamps: true });
19
+
20
+ export const User = mongoose.model('User', userSchema);
@@ -0,0 +1,35 @@
1
+ import mysql from 'mysql2'
2
+ import dotenv from 'dotenv'
3
+ dotenv.config()
4
+
5
+ const pool = mysql.createPool({
6
+ host: process.env.MYSQL_HOST ,
7
+ user: process.env.MYSQL_USER ,
8
+ password: process.env.MYSQL_PASSWORD ,
9
+ database: process.env.MYSQL_DATABASE
10
+ }).promise()
11
+
12
+ export async function getData() {
13
+ const [rows] = await pool.query("SELECT * FROM Db")
14
+ return rows
15
+ }
16
+
17
+ export async function getDataById(id) {
18
+ const [rows] = await pool.query(`
19
+ SELECT * FROM Db
20
+ WHERE id = ${id};
21
+ `)
22
+ return rows[0]
23
+ }
24
+
25
+ export async function createData(title, contents) {
26
+ const [result] = await pool.query(`
27
+ INSERT INTO Db (title, contents)
28
+ VALUES(?, ?);
29
+ `, [title, contents])
30
+ const id = result.insertId
31
+ return getData(id)
32
+ }
33
+
34
+ const result = await createData('test', 'test')
35
+ console.log(result)
@@ -0,0 +1,35 @@
1
+ import express from 'express'
2
+ import cors from 'cors'
3
+ const app = express()
4
+
5
+ app.use(cors())
6
+ app.use(json)
7
+
8
+
9
+ //get the details
10
+ app.get('/view', async (req, res) => {
11
+ res.send('hello')
12
+ })
13
+
14
+ //add new details
15
+ app.post('/add', (req, res) => {
16
+
17
+ })
18
+
19
+ //make changes in the database
20
+ app.put('/edit', (req, res) => {
21
+
22
+ })
23
+
24
+ //delete in the database
25
+ app.delete('/delete', (req, res) => {
26
+
27
+ })
28
+
29
+ app.listen(3000, () => {
30
+ try {
31
+ console.log(`The server is running on port: ${process.env.PORT}`)
32
+ } catch(err) {
33
+ console.log(err)
34
+ }
35
+ })
package/fileCreator.js ADDED
@@ -0,0 +1,49 @@
1
+ import { fileURLToPath } from 'url';
2
+ import path from 'path';
3
+ import * as fs from 'node:fs/promises';
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+
8
+ // Stable reference to your Templates folder in scaff/
9
+ const templateDir = path.join(__dirname, 'Templates');
10
+
11
+ // 🟡 Create empty .env
12
+ export const writeEnvFile = async () => {
13
+ const envPath = path.join(process.cwd(), 'src', 'config', '.env');
14
+ try {
15
+ await fs.writeFile(envPath, '', 'utf-8');
16
+ console.log('✅ .env file created in src/config');
17
+ } catch (error) {
18
+ console.error('❌ Failed to create .env file:', error);
19
+ }
20
+ };
21
+
22
+ // 🔵 Generate db.js from template
23
+ export const writeDbFiles = async (dbchoice) => {
24
+ const dbfile = dbchoice === 'MySQL' ? 'db-sql.js' : 'db-mongo.js';
25
+ const dbTemplatePath = path.join(templateDir, dbfile);
26
+ const targetPath = path.join(process.cwd(), 'src', 'models', 'db.js');
27
+
28
+ try {
29
+ const content = await fs.readFile(dbTemplatePath, 'utf-8');
30
+ await fs.writeFile(targetPath, content);
31
+ console.log('✅ db.js created successfully');
32
+ } catch (error) {
33
+ console.error('❌ Failed to create db.js:', error);
34
+ }
35
+ };
36
+
37
+ // 🟢 Generate app.js from express.js
38
+ export const writeServerFiles = async () => {
39
+ const serverTemplatePath = path.join(templateDir, 'express.js');
40
+ const targetPath = path.join(process.cwd(), 'app.js');
41
+
42
+ try {
43
+ const content = await fs.readFile(serverTemplatePath, 'utf-8');
44
+ await fs.writeFile(targetPath, content);
45
+ console.log('✅ app.js created successfully');
46
+ } catch (error) {
47
+ console.error('❌ Failed to create app.js:', error);
48
+ }
49
+ };
@@ -0,0 +1,34 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ /**
5
+ * Creates multiple nested folders inside the project.
6
+ * @param {string[]} paths - Relative paths from project root (e.g., ['src/config', 'src/models'])
7
+ */
8
+
9
+
10
+ export const createProjectDir = (rawProjectName) => {
11
+ const projectDir = path.join(process.cwd(), rawProjectName);
12
+
13
+ // Create the project folder
14
+ if (!fs.existsSync(projectDir)) {
15
+ fs.mkdirSync(projectDir);
16
+ console.log(`📁 Project root created: ${rawProjectName}`);
17
+ }
18
+
19
+ // Switch working directory
20
+ process.chdir(projectDir);
21
+ }
22
+
23
+
24
+ export const createFolders = (paths) => {
25
+ paths.forEach((folderPath) => {
26
+ const fullPath = path.join(process.cwd(), folderPath);
27
+ if (!fs.existsSync(fullPath)) {
28
+ fs.mkdirSync(fullPath, { recursive: true });
29
+ console.log(`📁 Folder created: ${folderPath}`);
30
+ } else {
31
+ console.log(`📂 Folder already exists: ${folderPath}`);
32
+ }
33
+ });
34
+ };
package/index.js ADDED
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env node
2
+
3
+ import chalk from 'chalk';
4
+ import chalkAnimation from 'chalk-animation';
5
+ import inquirer from 'inquirer';
6
+ import { installer } from './installer.js';
7
+ import {
8
+ writeDbFiles,
9
+ writeServerFiles,
10
+ writeEnvFile
11
+ } from './fileCreator.js';
12
+ import { createFolders, createProjectDir } from './folderCreater.js';
13
+ import { createPackageJson } from './packageJsonCreator.js';
14
+
15
+ // global responses
16
+ let rawProjectName;
17
+ let dbchoice;
18
+ let langchoice;
19
+
20
+ // timeout
21
+ export const sleep = (ms = 1000) => new Promise((r) => setTimeout(r, ms));
22
+
23
+ // welcome function
24
+ async function welcome() {
25
+ const rainbowTitle = chalkAnimation.rainbow("\n Welcome to JERRIT \n");
26
+ await sleep();
27
+ rainbowTitle.stop();
28
+ }
29
+
30
+ // project name
31
+ async function askName() {
32
+ const res = await inquirer.prompt({
33
+ name: 'admin_name',
34
+ type: 'input',
35
+ message: `${chalk.magentaBright('Project name ?')}`,
36
+ default() {
37
+ return 'my-app';
38
+ },
39
+ });
40
+
41
+ return res.admin_name;
42
+ }
43
+
44
+ // database selection
45
+ async function askDb() {
46
+ const res = await inquirer.prompt({
47
+ name: 'db_name',
48
+ type: 'list',
49
+ message: `${chalk.yellowBright('Select your Database ...')}`,
50
+ choices: [
51
+ { name: chalk.greenBright('MongoDB'), value: 'MongoDB' },
52
+ { name: chalk.whiteBright('MySQL'), value: 'MySQL' },
53
+ ],
54
+ });
55
+
56
+ dbchoice = res.db_name;
57
+ }
58
+
59
+ // language selection
60
+ async function askLang() {
61
+ const res = await inquirer.prompt({
62
+ name: 'lang_name',
63
+ type: 'list',
64
+ message: `${chalk.green('Select your Language...')}`,
65
+ choices: [
66
+ `${chalk.cyanBright('Typescript')}`,
67
+ `${chalk.yellowBright('Javascript')}`,
68
+ ],
69
+ });
70
+
71
+ langchoice = res.lang_name;
72
+ }
73
+
74
+ // exit function
75
+ export async function exit(str) {
76
+ const rainbowTitle = chalkAnimation.rainbow(str);
77
+ await sleep();
78
+ rainbowTitle.stop();
79
+ }
80
+
81
+ // Main execution
82
+ await welcome();
83
+
84
+ rawProjectName = await askName();
85
+
86
+ // Creating root directory
87
+ createProjectDir(rawProjectName);
88
+
89
+ await askDb();
90
+ await askLang();
91
+
92
+ console.log("\n");
93
+
94
+ // Project setup execution calls
95
+ console.log(chalk.whiteBright("Setting up your Project ... "));
96
+
97
+ // 1. Create folder structure
98
+ const backendFolders = [
99
+ 'src/config',
100
+ 'src/controllers',
101
+ 'src/middlewares',
102
+ 'src/models',
103
+ 'src/routes',
104
+ ];
105
+ createFolders(backendFolders);
106
+
107
+ // 2. Create configuration and code files
108
+ await writeEnvFile();
109
+ await writeServerFiles();
110
+ await writeDbFiles(dbchoice);
111
+
112
+ // 3. Generate package.json
113
+ await createPackageJson(rawProjectName, dbchoice, langchoice);
114
+
115
+ // 4. Install dependencies
116
+ installer();
package/installer.js ADDED
@@ -0,0 +1,32 @@
1
+ import { createSpinner } from 'nanospinner';
2
+ import { execSync } from 'child_process';
3
+ import chalk from 'chalk';
4
+ import { exit } from './index.js';
5
+
6
+ /**
7
+ * Installs dependencies using npm install
8
+ * Assumes package.json already exists in the current directory
9
+ */
10
+ export function installer() {
11
+ const spinner = createSpinner(chalk.whiteBright('Installing Dependencies...')).start();
12
+
13
+ try {
14
+ // Simple npm install command - reads from package.json
15
+ execSync('npm install', { stdio: 'inherit' });
16
+
17
+ console.log('\n');
18
+
19
+ spinner.success({
20
+ text: `${chalk.greenBright('Dependencies Installed Successfully!\n')}`
21
+ });
22
+
23
+ exit("Get Started !!!\n");
24
+
25
+ } catch (err) {
26
+ spinner.error({
27
+ text: `${chalk.redBright('Failed to Install Dependencies')}`
28
+ });
29
+ console.error(err);
30
+ exit("Try Again !!!");
31
+ }
32
+ }
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "create-jerry",
3
+ "version": "1.0.0",
4
+ "description": "A CLI tool to scaffold Express backend projects with MongoDB or MySQL",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "create-jerry": "./index.js"
9
+ },
10
+ "scripts": {
11
+ "test": "echo \"Error: no test specified\" && exit 1"
12
+ },
13
+ "keywords": [
14
+ "cli",
15
+ "scaffold",
16
+ "backend",
17
+ "express",
18
+ "mongodb",
19
+ "mysql",
20
+ "generator",
21
+ "boilerplate",
22
+ "nodejs"
23
+ ],
24
+ "author": "Tanmay Khanna",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/TomLucasakaTGeek/JerrIt"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/TomLucasakaTGeek/JerrIt/issues"
32
+ },
33
+ "homepage": "https://github.com/TomLucasakaTGeek/JerrIt#readme",
34
+ "dependencies": {
35
+ "chalk": "^5.4.1",
36
+ "chalk-animation": "^2.0.3",
37
+ "inquirer": "^12.3.0",
38
+ "nanospinner": "^1.2.2"
39
+ },
40
+ "engines": {
41
+ "node": ">=18.0.0"
42
+ },
43
+ "files": [
44
+ "index.js",
45
+ "installer.js",
46
+ "fileCreator.js",
47
+ "folderCreater.js",
48
+ "packageJsonCreator.js",
49
+ "Templates/",
50
+ "README.md"
51
+ ]
52
+ }
@@ -0,0 +1,92 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import path from 'path';
3
+
4
+ /**
5
+ * Generates package.json file based on project configuration
6
+ * @param {string} projectName - Name of the project
7
+ * @param {string} dbchoice - Database choice ('MongoDB' or 'MySQL')
8
+ * @param {string} langchoice - Language choice ('Typescript' or 'Javascript')
9
+ */
10
+ export const createPackageJson = async (projectName, dbchoice, langchoice) => {
11
+ // Base dependencies that every project needs
12
+ const baseDependencies = {
13
+ express: '^4.18.2',
14
+ dotenv: '^16.3.1',
15
+ cors: '^2.8.5'
16
+ };
17
+
18
+ // Database-specific dependencies
19
+ const dbDependencies = {
20
+ MongoDB: {
21
+ mongoose: '^8.0.3'
22
+ },
23
+ MySQL: {
24
+ mysql2: '^3.6.5'
25
+ }
26
+ };
27
+
28
+ // Merge base dependencies with database-specific ones
29
+ const dependencies = {
30
+ ...baseDependencies,
31
+ ...dbDependencies[dbchoice]
32
+ };
33
+
34
+ // Development dependencies (common for both JS and TS)
35
+ const devDependencies = {
36
+ nodemon: '^3.0.2'
37
+ };
38
+
39
+ // Add TypeScript-specific dev dependencies if needed
40
+ if (langchoice.includes('Typescript')) {
41
+ devDependencies['typescript'] = '^5.3.3';
42
+ devDependencies['@types/node'] = '^20.10.6';
43
+ devDependencies['@types/express'] = '^4.17.21';
44
+ devDependencies['@types/cors'] = '^2.8.17';
45
+ devDependencies['ts-node'] = '^10.9.2';
46
+ }
47
+
48
+ // Scripts configuration
49
+ const scripts = {
50
+ start: 'node app.js',
51
+ dev: 'nodemon app.js',
52
+ test: 'echo "Error: no test specified" && exit 1'
53
+ };
54
+
55
+ // Modify scripts for TypeScript
56
+ if (langchoice.includes('Typescript')) {
57
+ scripts.start = 'node dist/app.js';
58
+ scripts.dev = 'nodemon --exec ts-node app.ts';
59
+ scripts.build = 'tsc';
60
+ }
61
+
62
+ // Complete package.json object
63
+ const packageJson = {
64
+ name: projectName.toLowerCase().replace(/\s+/g, '-'),
65
+ version: '1.0.0',
66
+ description: `A ${dbchoice} backend project scaffolded with JerrIt`,
67
+ main: langchoice.includes('Typescript') ? 'dist/app.js' : 'app.js',
68
+ type: 'module',
69
+ scripts,
70
+ keywords: ['express', 'backend', dbchoice.toLowerCase()],
71
+ author: '',
72
+ license: 'ISC',
73
+ dependencies,
74
+ devDependencies
75
+ };
76
+
77
+ // Write package.json to the project root
78
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
79
+
80
+ try {
81
+ await fs.writeFile(
82
+ packageJsonPath,
83
+ JSON.stringify(packageJson, null, 2),
84
+ 'utf-8'
85
+ );
86
+ console.log('✅ package.json created successfully');
87
+ return true;
88
+ } catch (error) {
89
+ console.error('❌ Failed to create package.json:', error);
90
+ return false;
91
+ }
92
+ };