raahul-fastify-basic 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 +80 -0
- package/bin/cli.js +129 -0
- package/package.json +30 -0
- package/templates/basic/.env +7 -0
- package/templates/basic/_gitignore +5 -0
- package/templates/basic/nodemon.json +6 -0
- package/templates/basic/package-lock.json +5103 -0
- package/templates/basic/package.json +56 -0
- package/templates/basic/scripts/setup-public.ts +21 -0
- package/templates/basic/src/api/index.ts +14 -0
- package/templates/basic/src/api/v1/index.ts +12 -0
- package/templates/basic/src/config/constants.ts +15 -0
- package/templates/basic/src/config/env.ts +32 -0
- package/templates/basic/src/core/fastify.ts +25 -0
- package/templates/basic/src/core/server.ts +55 -0
- package/templates/basic/src/core/socket.ts +62 -0
- package/templates/basic/src/index.ts +23 -0
- package/templates/basic/src/infra/db/mongodb/mongodb.service.ts +73 -0
- package/templates/basic/src/infra/redis/redis.service.ts +42 -0
- package/templates/basic/src/infra/redis/utils/keys.ts +11 -0
- package/templates/basic/src/infra/redis/utils/lock.ts +118 -0
- package/templates/basic/src/inx.ts +10 -0
- package/templates/basic/src/types/global.d.ts +16 -0
- package/templates/basic/src/utils/assert.ts +7 -0
- package/templates/basic/tsconfig.json +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# create-fastify-basic
|
|
2
|
+
|
|
3
|
+
A command-line tool to quickly generate a production-ready Fastify boilerplate with TypeScript, MongoDB (Mongoose), Socket.io, and Redis integration.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Fastify v5**: Modern, fast, and low-overhead web framework.
|
|
8
|
+
- **TypeScript**: Full TypeScript support out of the box.
|
|
9
|
+
- **Database Support**: MongoDB integration using Mongoose.
|
|
10
|
+
- **WebSockets**: Realtime communication setup using Socket.io and Redis adapter.
|
|
11
|
+
- **Structure**: Clean folder structure dividing modules, plugins, controllers, and services.
|
|
12
|
+
- **Development Friendly**: Auto-reloads on code changes using nodemon.
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
You can generate a starter project instantly using `npx`:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx create-fastify-basic my-fastify-service
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Alternatively, you can install the package globally:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g create-fastify-basic
|
|
26
|
+
create-fastify-basic my-fastify-service
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Running the Generated App
|
|
30
|
+
|
|
31
|
+
1. **Navigate to the directory**:
|
|
32
|
+
```bash
|
|
33
|
+
cd my-fastify-service
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
2. **Configure your environment**:
|
|
37
|
+
Copy `.env` and fill in your details:
|
|
38
|
+
- Database URI (MongoDB)
|
|
39
|
+
- Redis connection details
|
|
40
|
+
- Port settings
|
|
41
|
+
|
|
42
|
+
3. **Run in development mode**:
|
|
43
|
+
```bash
|
|
44
|
+
npm run dev
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
4. **Build for production**:
|
|
48
|
+
```bash
|
|
49
|
+
npm run build
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
5. **Start production server**:
|
|
53
|
+
```bash
|
|
54
|
+
npm start
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Folder Structure
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
├── src
|
|
61
|
+
│ ├── api # Router and endpoints
|
|
62
|
+
│ ├── config # App configurations (database, environment)
|
|
63
|
+
│ ├── core # Core utilities or constants
|
|
64
|
+
│ ├── infra # Database and external infrastructure initializers
|
|
65
|
+
│ ├── lib # Third-party service integrations
|
|
66
|
+
│ ├── modules # Modular components / domain logic
|
|
67
|
+
│ ├── plugins # Fastify plugins
|
|
68
|
+
│ ├── services # Application services (e.g. Email, Socket)
|
|
69
|
+
│ ├── types # TypeScript definitions
|
|
70
|
+
│ ├── utils # Utility functions
|
|
71
|
+
│ └── index.ts # Application entrypoint
|
|
72
|
+
├── scripts # Helper setup/deployment scripts
|
|
73
|
+
├── nodemon.json # Nodemon config for development auto-reloads
|
|
74
|
+
├── tsconfig.json # TypeScript compiler options
|
|
75
|
+
└── package.json # Node.js manifest
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
ISC
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import readline from 'readline';
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
const colors = {
|
|
10
|
+
reset: '\x1b[0m',
|
|
11
|
+
bright: '\x1b[1m',
|
|
12
|
+
green: '\x1b[32m',
|
|
13
|
+
cyan: '\x1b[36m',
|
|
14
|
+
yellow: '\x1b[33m',
|
|
15
|
+
red: '\x1b[31m',
|
|
16
|
+
gray: '\x1b[90m'
|
|
17
|
+
};
|
|
18
|
+
function logSuccess(msg) {
|
|
19
|
+
console.log(`${colors.green}✔${colors.reset} ${msg}`);
|
|
20
|
+
}
|
|
21
|
+
function logInfo(msg) {
|
|
22
|
+
console.log(`${colors.cyan}ℹ${colors.reset} ${msg}`);
|
|
23
|
+
}
|
|
24
|
+
function logWarn(msg) {
|
|
25
|
+
console.log(`${colors.yellow}⚠${colors.reset} ${msg}`);
|
|
26
|
+
}
|
|
27
|
+
function logError(msg) {
|
|
28
|
+
console.error(`${colors.red}✖${colors.reset} ${msg}`);
|
|
29
|
+
}
|
|
30
|
+
async function askQuestion(query) {
|
|
31
|
+
const rl = readline.createInterface({
|
|
32
|
+
input: process.stdin,
|
|
33
|
+
output: process.stdout
|
|
34
|
+
});
|
|
35
|
+
return new Promise((resolve) => rl.question(query, (ans) => {
|
|
36
|
+
rl.close();
|
|
37
|
+
resolve(ans.trim());
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
async function main() {
|
|
41
|
+
console.log(`\n${colors.bright}${colors.cyan}=== Fastify Starter App Generator ===${colors.reset}\n`);
|
|
42
|
+
let targetDir = process.argv[2];
|
|
43
|
+
if (!targetDir) {
|
|
44
|
+
targetDir = await askQuestion(`${colors.bright}Enter project directory name:${colors.reset} `);
|
|
45
|
+
}
|
|
46
|
+
if (!targetDir) {
|
|
47
|
+
logError('Project directory name is required.');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const projectPath = path.resolve(process.cwd(), targetDir);
|
|
51
|
+
const projectName = path.basename(projectPath);
|
|
52
|
+
if (fs.existsSync(projectPath)) {
|
|
53
|
+
const files = fs.readdirSync(projectPath);
|
|
54
|
+
if (files.length > 0) {
|
|
55
|
+
logWarn(`Directory ${colors.bright}${targetDir}${colors.reset} already exists and is not empty.`);
|
|
56
|
+
const answer = await askQuestion('Do you want to overwrite it? (y/N): ');
|
|
57
|
+
if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {
|
|
58
|
+
logInfo('Aborting installation.');
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
fs.mkdirSync(projectPath, { recursive: true });
|
|
64
|
+
}
|
|
65
|
+
const templateDir = path.resolve(__dirname, '../templates/basic');
|
|
66
|
+
if (!fs.existsSync(templateDir)) {
|
|
67
|
+
logError(`Template directory not found at ${templateDir}`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
logInfo(`Creating project in ${colors.bright}${projectPath}${colors.reset}...`);
|
|
71
|
+
function copyRecursive(src, dest) {
|
|
72
|
+
const stats = fs.statSync(src);
|
|
73
|
+
if (stats.isDirectory()) {
|
|
74
|
+
if (!fs.existsSync(dest)) {
|
|
75
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
76
|
+
}
|
|
77
|
+
fs.readdirSync(src).forEach((child) => {
|
|
78
|
+
if (child === 'node_modules') return;
|
|
79
|
+
copyRecursive(path.join(src, child), path.join(dest, child));
|
|
80
|
+
});
|
|
81
|
+
} else {
|
|
82
|
+
const filename = path.basename(src);
|
|
83
|
+
if (filename === '_gitignore') {
|
|
84
|
+
fs.copyFileSync(src, path.join(path.dirname(dest), '.gitignore'));
|
|
85
|
+
} else {
|
|
86
|
+
fs.copyFileSync(src, dest);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
copyRecursive(templateDir, projectPath);
|
|
92
|
+
logSuccess('Template files copied.');
|
|
93
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
94
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
95
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
96
|
+
pkg.name = projectName;
|
|
97
|
+
pkg.description = `Fastify service app generated using create-fastify-basic`;
|
|
98
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2), 'utf8');
|
|
99
|
+
logSuccess('Updated package.json configuration.');
|
|
100
|
+
}
|
|
101
|
+
const runInstall = await askQuestion(`\nDo you want to run ${colors.cyan}npm install${colors.reset} now? (Y/n): `);
|
|
102
|
+
if (runInstall.toLowerCase() === 'y' || runInstall.toLowerCase() === 'yes' || runInstall === '') {
|
|
103
|
+
logInfo('Installing dependencies (this may take a minute)...');
|
|
104
|
+
try {
|
|
105
|
+
execSync('npm install', { cwd: projectPath, stdio: 'inherit' });
|
|
106
|
+
logSuccess('Dependencies installed successfully.');
|
|
107
|
+
} catch (err) {
|
|
108
|
+
logError('Failed to install dependencies. Please run npm install manually.');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
console.log(`\n${colors.green}Success! Created ${projectName} at ${projectPath}${colors.reset}\n`);
|
|
112
|
+
console.log('Inside that directory, you can run several commands:');
|
|
113
|
+
console.log(` ${colors.cyan}npm run dev${colors.reset}`);
|
|
114
|
+
console.log(' Starts the development server.\n');
|
|
115
|
+
console.log(` ${colors.cyan}npm run build${colors.reset}`);
|
|
116
|
+
console.log(' Builds the app for production.\n');
|
|
117
|
+
console.log(` ${colors.cyan}npm start${colors.reset}`);
|
|
118
|
+
console.log(' Runs the built app in production mode.\n');
|
|
119
|
+
console.log('We suggest that you begin by typing:');
|
|
120
|
+
console.log(` ${colors.cyan}cd${colors.reset} ${targetDir}`);
|
|
121
|
+
console.log(` ${colors.cyan}npm run dev${colors.reset}`);
|
|
122
|
+
console.log('\nHappy coding!\n');
|
|
123
|
+
} catch (error) {
|
|
124
|
+
logError(`An error occurred: ${error.message}`);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "raahul-fastify-basic",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI tool to generate a starter Fastify service application with MongoDB, Socket.io, and TypeScript.",
|
|
5
|
+
"main": "bin/cli.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"raahul-fastify-basic": "bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin",
|
|
12
|
+
"templates"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18.0.0"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"fastify",
|
|
19
|
+
"typescript",
|
|
20
|
+
"mongodb",
|
|
21
|
+
"mongoose",
|
|
22
|
+
"socket.io",
|
|
23
|
+
"boilerplate",
|
|
24
|
+
"starter",
|
|
25
|
+
"generator",
|
|
26
|
+
"cli"
|
|
27
|
+
],
|
|
28
|
+
"author": "Raahul Mehta",
|
|
29
|
+
"license": "ISC"
|
|
30
|
+
}
|