create-express-mongo-ts 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.
Files changed (3) hide show
  1. package/README.md +3 -3
  2. package/bin/cli.js +185 -130
  3. package/package.json +6 -2
package/README.md CHANGED
@@ -1,14 +1,14 @@
1
- # create-express-mongo
1
+ # create-express-mongo-ts
2
2
 
3
3
  Create Express + MongoDB applications with TypeScript, authentication, and best practices out of the box.
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/create-express-mongo.svg)](https://www.npmjs.com/package/create-express-mongo)
5
+ [![npm version](https://img.shields.io/npm/v/create-express-mongo-ts.svg)](https://www.npmjs.com/package/create-express-mongo-ts)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
 
8
8
  ## Quick Start
9
9
 
10
10
  ```bash
11
- npx create-express-mongo my-app
11
+ npx create-express-mongo-ts my-app
12
12
  cd my-app
13
13
  npm install
14
14
  cp .env.example .env
package/bin/cli.js CHANGED
@@ -1,104 +1,128 @@
1
- #!/usr/bin/env node
2
-
3
- const { execSync } = require('child_process');
4
- const path = require('path');
5
- const fs = require('fs');
6
-
7
- // Colors for console output
8
- const colors = {
9
- reset: '\x1b[0m',
10
- bright: '\x1b[1m',
11
- green: '\x1b[32m',
12
- cyan: '\x1b[36m',
13
- yellow: '\x1b[33m',
14
- red: '\x1b[31m',
15
- };
1
+ import inquirer from 'inquirer';
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import chalk from 'chalk';
5
+ import { execSync } from 'child_process';
6
+ import { fileURLToPath } from 'url';
16
7
 
17
- const log = {
18
- info: (msg) => console.log(`${colors.cyan}ℹ${colors.reset} ${msg}`),
19
- success: (msg) => console.log(`${colors.green}✔${colors.reset} ${msg}`),
20
- warn: (msg) => console.log(`${colors.yellow}⚠${colors.reset} ${msg}`),
21
- error: (msg) => console.log(`${colors.red}✖${colors.reset} ${msg}`),
22
- };
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
23
10
 
24
- // Get project name from command line arguments
25
- const projectName = process.argv[2];
11
+ const GITLAB_CI_FILE = '.gitlab-ci.yml';
12
+ const GITHUB_CI_FOLDER = '.github';
13
+ const PACKAGE_JSON = 'package.json';
26
14
 
27
- if (!projectName) {
28
- log.error('Please specify the project directory:');
29
- console.log(
30
- ` ${colors.cyan}npx create-express-mongo${colors.reset} ${colors.green}<project-directory>${colors.reset}`,
31
- );
32
- console.log();
33
- console.log('For example:');
15
+ const styles = {
16
+ command: (cmd) => chalk.cyan.bold(cmd),
17
+ path: (p) => chalk.gray(p),
18
+ success: (msg) => chalk.green(msg),
19
+ warning: (msg) => chalk.yellow(msg),
20
+ error: (msg) => chalk.red(msg),
21
+ heading: (msg) => chalk.bold(msg),
22
+ };
23
+
24
+ async function createExpressMongo() {
34
25
  console.log(
35
- ` ${colors.cyan}npx create-express-mongo${colors.reset} ${colors.green}my-app${colors.reset}`,
26
+ chalk.cyan.bold('\n🚀 Create Express MongoDB TypeScript App\n'),
36
27
  );
37
- process.exit(1);
38
- }
39
28
 
40
- const currentPath = process.cwd();
41
- const projectPath = path.join(currentPath, projectName);
42
- const templatePath = path.join(__dirname, '..', 'template');
29
+ // Get project name from command line or prompt
30
+ let projectName = process.argv[2];
43
31
 
44
- // Check if directory already exists
45
- if (fs.existsSync(projectPath)) {
46
- log.error(
47
- `The directory ${colors.green}${projectName}${colors.reset} already exists.`,
48
- );
49
- log.info(
50
- 'Please choose a different project name or delete the existing directory.',
51
- );
52
- process.exit(1);
32
+ const answers = await inquirer.prompt([
33
+ {
34
+ type: 'input',
35
+ name: 'appName',
36
+ message: 'What is your app name?',
37
+ default: projectName || 'my-express-mongo-app',
38
+ validate(input) {
39
+ if (!input.trim()) return 'App name cannot be empty';
40
+ if (!/^[a-z0-9-_]+$/i.test(input))
41
+ return 'App name can only contain letters, numbers, hyphens and underscores';
42
+ return true;
43
+ },
44
+ },
45
+ {
46
+ type: 'list',
47
+ name: 'gitProvider',
48
+ message: 'Which Git provider do you want to use?',
49
+ choices: [
50
+ { name: 'GitHub', value: 'github' },
51
+ { name: 'GitLab', value: 'gitlab' },
52
+ { name: 'None', value: 'none' },
53
+ ],
54
+ default: 'github',
55
+ },
56
+ {
57
+ type: 'confirm',
58
+ name: 'initGit',
59
+ message: 'Initialize a git repository?',
60
+ default: true,
61
+ },
62
+ ]);
63
+
64
+ createApp(answers);
53
65
  }
54
66
 
55
- console.log();
56
- console.log(
57
- `${colors.bright}Creating a new Express + MongoDB app in ${colors.green}${projectPath}${colors.reset}`,
58
- );
59
- console.log();
67
+ function createApp({ appName, gitProvider, initGit }) {
68
+ const targetDir = path.join(process.cwd(), appName);
69
+ const templateDir = path.join(__dirname, '../template');
60
70
 
61
- // Create project directory
62
- fs.mkdirSync(projectPath, { recursive: true });
71
+ // Check if directory exists
72
+ if (fs.existsSync(targetDir)) {
73
+ console.log(styles.error(`\n✖ Folder "${appName}" already exists.`));
74
+ process.exit(1);
75
+ }
63
76
 
64
- // Function to copy directory recursively
65
- function copyDir(src, dest) {
66
- fs.mkdirSync(dest, { recursive: true });
67
- const entries = fs.readdirSync(src, { withFileTypes: true });
77
+ console.log(
78
+ styles.heading(
79
+ `\nCreating a new Express + MongoDB app in ${styles.path(
80
+ targetDir,
81
+ )}\n`,
82
+ ),
83
+ );
68
84
 
69
- for (const entry of entries) {
70
- const srcPath = path.join(src, entry.name);
71
- const destPath = path.join(dest, entry.name);
85
+ // Copy template files
86
+ console.log(chalk.cyan('ℹ') + ' Copying template files...');
87
+ copyDir(templateDir, targetDir);
88
+ console.log(styles.success('✔ Template files copied successfully.'));
72
89
 
73
- if (entry.isDirectory()) {
74
- copyDir(srcPath, destPath);
75
- } else {
76
- fs.copyFileSync(srcPath, destPath);
90
+ // Handle git provider - remove unused CI files
91
+ if (gitProvider === 'github') {
92
+ const gitlabPath = path.join(targetDir, GITLAB_CI_FILE);
93
+ if (fs.existsSync(gitlabPath)) {
94
+ fs.rmSync(gitlabPath, { recursive: true, force: true });
95
+ }
96
+ } else if (gitProvider === 'gitlab') {
97
+ const githubPath = path.join(targetDir, GITHUB_CI_FOLDER);
98
+ if (fs.existsSync(githubPath)) {
99
+ fs.rmSync(githubPath, { recursive: true, force: true });
77
100
  }
101
+ } else {
102
+ // Remove both if none selected
103
+ const gitlabPath = path.join(targetDir, GITLAB_CI_FILE);
104
+ const githubPath = path.join(targetDir, GITHUB_CI_FOLDER);
105
+ if (fs.existsSync(gitlabPath))
106
+ fs.rmSync(gitlabPath, { recursive: true, force: true });
107
+ if (fs.existsSync(githubPath))
108
+ fs.rmSync(githubPath, { recursive: true, force: true });
78
109
  }
79
- }
80
-
81
- try {
82
- // Copy template files
83
- log.info('Copying template files...');
84
- copyDir(templatePath, projectPath);
85
- log.success('Template files copied successfully.');
86
110
 
87
111
  // Update package.json with project name
88
- const packageJsonPath = path.join(projectPath, 'package.json');
89
- if (fs.existsSync(packageJsonPath)) {
90
- const packageJson = JSON.parse(
91
- fs.readFileSync(packageJsonPath, 'utf8'),
112
+ const pkgPath = path.join(targetDir, PACKAGE_JSON);
113
+ if (fs.existsSync(pkgPath)) {
114
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
115
+ pkg.name = appName;
116
+ pkg.version = '1.0.0';
117
+ pkg.description = `${appName} - Express + MongoDB TypeScript application`;
118
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
119
+ console.log(
120
+ styles.success('✔ Updated package.json with project name.'),
92
121
  );
93
- packageJson.name = projectName;
94
- packageJson.version = '1.0.0';
95
- packageJson.description = `${projectName} - Express + MongoDB application`;
96
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
97
- log.success('Updated package.json with project name.');
98
122
  }
99
123
 
100
124
  // Create .env.example file
101
- const envExamplePath = path.join(projectPath, '.env.example');
125
+ const envExamplePath = path.join(targetDir, '.env.example');
102
126
  if (!fs.existsSync(envExamplePath)) {
103
127
  const envContent = `# Server Configuration
104
128
  PORT=3000
@@ -107,35 +131,38 @@ NODE_ENV=development
107
131
  # Database Configuration
108
132
  DB_HOST=localhost
109
133
  DB_PORT=27017
110
- DB_NAME=${projectName}
134
+ DB_NAME=${appName}
111
135
  DB_USER=
112
- DB_PASSWORD=
136
+ DB_USER_PASSWORD=
113
137
  DB_MIN_POOL_SIZE=2
114
138
  DB_MAX_POOL_SIZE=5
115
139
 
116
140
  # JWT Configuration
117
141
  ACCESS_TOKEN_VALIDITY_SEC=3600
118
142
  REFRESH_TOKEN_VALIDITY_SEC=86400
143
+ TOKEN_ISSUER=${appName}
144
+ TOKEN_AUDIENCE=${appName}
119
145
 
120
146
  # CORS Configuration
121
- CORS_URL=*
147
+ ORIGIN_URL=*
122
148
 
123
149
  # Logging
124
- LOG_DIR=logs
150
+ LOG_DIRECTORY=logs
125
151
  `;
126
152
  fs.writeFileSync(envExamplePath, envContent);
127
- log.success('Created .env.example file.');
153
+ console.log(styles.success('Created .env.example file.'));
128
154
  }
129
155
 
130
156
  // Initialize git repository
131
- log.info('Initializing git repository...');
132
- try {
133
- execSync('git init', { cwd: projectPath, stdio: 'ignore' });
134
-
135
- // Create .gitignore if it doesn't exist
136
- const gitignorePath = path.join(projectPath, '.gitignore');
137
- if (!fs.existsSync(gitignorePath)) {
138
- const gitignoreContent = `# Dependencies
157
+ if (initGit) {
158
+ console.log(chalk.cyan('ℹ') + ' Initializing git repository...');
159
+ try {
160
+ execSync('git init', { cwd: targetDir, stdio: 'ignore' });
161
+
162
+ // Create .gitignore if it doesn't exist
163
+ const gitignorePath = path.join(targetDir, '.gitignore');
164
+ if (!fs.existsSync(gitignorePath)) {
165
+ const gitignoreContent = `# Dependencies
139
166
  node_modules/
140
167
 
141
168
  # Build output
@@ -169,49 +196,77 @@ keys/*.key
169
196
  # TypeScript cache
170
197
  *.tsbuildinfo
171
198
  `;
172
- fs.writeFileSync(gitignorePath, gitignoreContent);
199
+ fs.writeFileSync(gitignorePath, gitignoreContent);
200
+ }
201
+ console.log(styles.success('✔ Initialized git repository.'));
202
+ } catch (error) {
203
+ console.log(
204
+ styles.warning('⚠ Could not initialize git repository.'),
205
+ );
173
206
  }
174
- log.success('Initialized git repository.');
175
- } catch (error) {
176
- log.warn(
177
- 'Could not initialize git repository. Please initialize it manually.',
178
- );
179
207
  }
180
208
 
181
209
  // Success message
182
- console.log();
183
210
  console.log(
184
- `${colors.green}${colors.bright}Success!${colors.reset} Created ${colors.cyan}${projectName}${colors.reset} at ${colors.green}${projectPath}${colors.reset}`,
211
+ styles.success(`\n✨ Success! Created ${appName} at ${targetDir}\n`),
212
+ );
213
+
214
+ console.log(styles.heading('Next Steps:\n'));
215
+ console.log(
216
+ ` 👉 Go to project directory: ${styles.command(`cd ${appName}`)}`,
217
+ );
218
+ console.log(
219
+ ` 👉 Install dependencies: ${styles.command('npm install')}`,
220
+ );
221
+ console.log(
222
+ ` 👉 Set up environment: ${styles.command(
223
+ 'cp .env.example .env',
224
+ )}`,
225
+ );
226
+ console.log(
227
+ ` 👉 Run the application: ${styles.command('npm run dev')}`,
185
228
  );
186
229
  console.log();
187
- console.log('Inside that directory, you can run several commands:');
188
- console.log();
189
- console.log(` ${colors.cyan}npm install${colors.reset}`);
190
- console.log(' Installs all dependencies.');
191
- console.log();
192
- console.log(` ${colors.cyan}npm run dev${colors.reset}`);
193
- console.log(' Starts the development server with hot-reload.');
194
- console.log();
195
- console.log(` ${colors.cyan}npm run build${colors.reset}`);
196
- console.log(' Builds the app for production.');
197
- console.log();
198
- console.log(` ${colors.cyan}npm start${colors.reset}`);
199
- console.log(' Builds and runs the production server.');
200
- console.log();
201
- console.log(` ${colors.cyan}npm test${colors.reset}`);
202
- console.log(' Runs the test suite.');
203
- console.log();
204
- console.log('We suggest that you begin by typing:');
205
- console.log();
206
- console.log(` ${colors.cyan}cd${colors.reset} ${projectName}`);
207
- console.log(` ${colors.cyan}npm install${colors.reset}`);
208
- console.log(` ${colors.cyan}cp .env.example .env${colors.reset}`);
209
- console.log(` ${colors.cyan}npm run dev${colors.reset}`);
210
- console.log();
211
- console.log(`${colors.bright}Happy coding!${colors.reset} 🚀`);
230
+ console.log(styles.heading('Available Commands:\n'));
231
+ console.log(
232
+ ` ${styles.command(
233
+ 'npm run dev',
234
+ )} - Start development server with hot-reload`,
235
+ );
236
+ console.log(
237
+ ` ${styles.command('npm run build')} - Build for production`,
238
+ );
239
+ console.log(
240
+ ` ${styles.command(
241
+ 'npm start',
242
+ )} - Build and run production server`,
243
+ );
244
+ console.log(` ${styles.command('npm test')} - Run test suite`);
245
+ console.log(
246
+ ` ${styles.command('npm run lint')} - Check for linting errors`,
247
+ );
212
248
  console.log();
213
- } catch (error) {
214
- log.error('An error occurred while creating the project:');
215
- console.error(error);
216
- process.exit(1);
249
+ console.log(chalk.bold('Happy coding! 🚀\n'));
250
+ }
251
+
252
+ // Recursively copy all files and folders
253
+ function copyDir(src, dest) {
254
+ fs.mkdirSync(dest, { recursive: true });
255
+
256
+ for (const file of fs.readdirSync(src)) {
257
+ const srcPath = path.join(src, file);
258
+ const destPath = path.join(dest, file);
259
+
260
+ if (fs.statSync(srcPath).isDirectory()) {
261
+ copyDir(srcPath, destPath);
262
+ continue;
263
+ }
264
+
265
+ fs.copyFileSync(srcPath, destPath);
266
+ }
217
267
  }
268
+
269
+ createExpressMongo().catch((error) => {
270
+ console.error(styles.error('An error occurred:'), error);
271
+ process.exit(1);
272
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-express-mongo-ts",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Create Express + MongoDB applications with TypeScript, authentication, and best practices out of the box",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {
@@ -36,8 +36,12 @@
36
36
  "url": "https://github.com/sofikulsk02/express-mongobd-template/issues"
37
37
  },
38
38
  "homepage": "https://github.com/sofikulsk02/express-mongobd-template#readme",
39
- "type": "commonjs",
39
+ "type": "module",
40
40
  "engines": {
41
41
  "node": ">=18.0.0"
42
+ },
43
+ "dependencies": {
44
+ "chalk": "^5.3.0",
45
+ "inquirer": "^9.2.12"
42
46
  }
43
47
  }