@kuldi/create-nestjs 1.1.2 โ 1.1.4
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/LICENSE +21 -0
- package/README.md +24 -12
- package/package.json +1 -1
- package/src/cli.js +37 -26
- package/template/README.md +137 -133
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kuli Digital
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,27 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>๐ @kuldi/create-nestjs</h1>
|
|
3
|
+
<p>The official, interactive, and lightning-fast scaffolding tool for <b>Kuli Digital's NestJS Boilerplate</b>.</p>
|
|
4
|
+
</div>
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
---
|
|
4
7
|
|
|
5
|
-
##
|
|
8
|
+
## โจ Features
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
- **โก๏ธ Instant Setup**: Scaffold a production-ready NestJS architecture in seconds.
|
|
11
|
+
- **๐ Interactive Prompts**: Easily configure your project name, database name, and package manager.
|
|
12
|
+
- **๐ Auto-Configured Environment**: Automatically generates a tailored `.env` file for your database credentials.
|
|
13
|
+
- **๐ Production Ready**: Comes pre-configured with Prisma ORM, Swagger Documentation, JWT Auth, and RBAC (Role-Based Access Control) out of the box.
|
|
14
|
+
|
|
15
|
+
## ๐ Quick Start
|
|
16
|
+
|
|
17
|
+
To generate a new NestJS project, use the `@latest` tag to ensure you get the most recent version of the boilerplate:
|
|
8
18
|
|
|
9
19
|
```bash
|
|
10
|
-
npm create @kuldi/nestjs my-app
|
|
20
|
+
npm create @kuldi/nestjs@latest my-app
|
|
11
21
|
```
|
|
12
22
|
|
|
13
|
-
Or, to create
|
|
23
|
+
Or, to create the project in your **current directory**:
|
|
14
24
|
|
|
15
25
|
```bash
|
|
16
26
|
npm create @kuldi/nestjs .
|
|
17
27
|
```
|
|
18
28
|
|
|
19
|
-
|
|
29
|
+
### Note on Global Installations (Optional)
|
|
30
|
+
If you prefer installing the package globally, you can do so, but using `npm create` (or `npx`) is highly recommended to always fetch the latest updates.
|
|
20
31
|
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
32
|
+
```bash
|
|
33
|
+
npm install -g @kuldi/create-nestjs
|
|
34
|
+
create-nestjs my-app
|
|
35
|
+
```
|
|
24
36
|
|
|
25
|
-
## License
|
|
37
|
+
## ๐ License
|
|
26
38
|
|
|
27
|
-
MIT
|
|
39
|
+
MIT ยฉ Kuli Digital
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -24,20 +24,20 @@ async function run() {
|
|
|
24
24
|
{
|
|
25
25
|
type: 'input',
|
|
26
26
|
name: 'projectName',
|
|
27
|
-
message: '
|
|
27
|
+
message: 'Project Name (or . for current directory):',
|
|
28
28
|
default: argProjectName || 'my-nestjs-app',
|
|
29
29
|
when: !argProjectName,
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
type: 'input',
|
|
33
33
|
name: 'database',
|
|
34
|
-
message: '
|
|
34
|
+
message: 'PostgreSQL Database Name:',
|
|
35
35
|
default: 'kulidigital_db',
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
type: 'confirm',
|
|
39
39
|
name: 'skipInstall',
|
|
40
|
-
message: '
|
|
40
|
+
message: 'Skip package installation (npm install)?',
|
|
41
41
|
default: false,
|
|
42
42
|
},
|
|
43
43
|
]);
|
|
@@ -45,41 +45,52 @@ async function run() {
|
|
|
45
45
|
const projectName = argProjectName || answers.projectName;
|
|
46
46
|
const projectPath = projectName === '.' ? currentPath : path.join(currentPath, projectName);
|
|
47
47
|
|
|
48
|
-
//
|
|
49
|
-
if (
|
|
50
|
-
const files = fs.readdirSync(
|
|
48
|
+
// Check if target directory is empty
|
|
49
|
+
if (fs.existsSync(projectPath)) {
|
|
50
|
+
const files = fs.readdirSync(projectPath).filter(f => !f.startsWith('.git'));
|
|
51
51
|
if (files.length > 0) {
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
const { overwrite } = await inquirer.prompt([
|
|
53
|
+
{
|
|
54
|
+
type: 'confirm',
|
|
55
|
+
name: 'overwrite',
|
|
56
|
+
message: 'Directory is not empty. Do you want to continue? (This will overwrite existing files)',
|
|
57
|
+
default: false,
|
|
58
|
+
}
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
if (!overwrite) {
|
|
62
|
+
console.log(chalk.yellow('\nโ ๏ธ Setup cancelled.\n'));
|
|
63
|
+
process.exit(0);
|
|
64
|
+
}
|
|
54
65
|
}
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
// 2. Salin Template
|
|
58
|
-
const copySpinner = ora('
|
|
69
|
+
const copySpinner = ora('Generating project structure...').start();
|
|
59
70
|
try {
|
|
60
71
|
const templateDir = path.join(__dirname, '../template');
|
|
61
72
|
|
|
62
|
-
// Copy
|
|
73
|
+
// Copy template contents to the target project directory
|
|
63
74
|
fs.cpSync(templateDir, projectPath, { recursive: true });
|
|
64
75
|
|
|
65
|
-
// Rename gitignore
|
|
76
|
+
// Rename gitignore to .gitignore (NPM ignores .gitignore during publish)
|
|
66
77
|
const gitignorePath = path.join(projectPath, 'gitignore');
|
|
67
78
|
if (fs.existsSync(gitignorePath)) {
|
|
68
79
|
fs.renameSync(gitignorePath, path.join(projectPath, '.gitignore'));
|
|
69
80
|
}
|
|
70
81
|
|
|
71
|
-
copySpinner.succeed('
|
|
82
|
+
copySpinner.succeed('Project structure generated successfully.');
|
|
72
83
|
} catch (error) {
|
|
73
|
-
copySpinner.fail('
|
|
84
|
+
copySpinner.fail('Failed to generate project structure.');
|
|
74
85
|
console.error(error.message);
|
|
75
86
|
process.exit(1);
|
|
76
87
|
}
|
|
77
88
|
|
|
78
|
-
//
|
|
89
|
+
// Navigate to project directory
|
|
79
90
|
process.chdir(projectPath);
|
|
80
91
|
|
|
81
92
|
// 3. Setup .env
|
|
82
|
-
const envSpinner = ora('
|
|
93
|
+
const envSpinner = ora('Configuring environment variables...').start();
|
|
83
94
|
try {
|
|
84
95
|
const envExamplePath = path.join(projectPath, '.env.example');
|
|
85
96
|
const envPath = path.join(projectPath, '.env');
|
|
@@ -91,36 +102,36 @@ async function run() {
|
|
|
91
102
|
envContent = envContent.replace(/APP_NAME=my-app/g, `APP_NAME=${projectName === '.' ? path.basename(currentPath) : projectName}`);
|
|
92
103
|
|
|
93
104
|
fs.writeFileSync(envPath, envContent);
|
|
94
|
-
envSpinner.succeed('
|
|
105
|
+
envSpinner.succeed('.env file created successfully.');
|
|
95
106
|
} else {
|
|
96
|
-
envSpinner.warn('
|
|
107
|
+
envSpinner.warn('.env.example not found, skipping .env setup.');
|
|
97
108
|
}
|
|
98
109
|
} catch (error) {
|
|
99
|
-
envSpinner.fail('
|
|
110
|
+
envSpinner.fail('Failed to configure .env file.');
|
|
100
111
|
}
|
|
101
112
|
|
|
102
|
-
// 4.
|
|
113
|
+
// 4. Initialize Git
|
|
103
114
|
try {
|
|
104
115
|
execSync('git init', { stdio: 'ignore' });
|
|
105
116
|
} catch (e) {
|
|
106
|
-
//
|
|
117
|
+
// Ignore if git is not installed
|
|
107
118
|
}
|
|
108
119
|
|
|
109
120
|
// 5. Install Dependencies
|
|
110
121
|
if (!answers.skipInstall) {
|
|
111
|
-
const installSpinner = ora(`
|
|
122
|
+
const installSpinner = ora(`Installing dependencies using npm... (this may take a few minutes)`).start();
|
|
112
123
|
try {
|
|
113
124
|
execSync(`npm install`, { stdio: 'ignore' });
|
|
114
|
-
installSpinner.succeed('Dependencies
|
|
125
|
+
installSpinner.succeed('Dependencies installed successfully.');
|
|
115
126
|
} catch (error) {
|
|
116
|
-
installSpinner.fail('
|
|
117
|
-
console.log(chalk.yellow('\
|
|
127
|
+
installSpinner.fail('Failed to install dependencies.');
|
|
128
|
+
console.log(chalk.yellow('\nYou can install them manually later.'));
|
|
118
129
|
}
|
|
119
130
|
}
|
|
120
131
|
|
|
121
132
|
// 6. Success Message
|
|
122
|
-
console.log(chalk.green.bold('\nโ
Project
|
|
123
|
-
console.log(chalk.white('
|
|
133
|
+
console.log(chalk.green.bold('\nโ
Project successfully created!\n'));
|
|
134
|
+
console.log(chalk.white('Next steps:'));
|
|
124
135
|
|
|
125
136
|
if (projectName !== '.') {
|
|
126
137
|
console.log(chalk.cyan(` cd ${projectName}`));
|
package/template/README.md
CHANGED
|
@@ -1,133 +1,137 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
npm run
|
|
62
|
-
|
|
63
|
-
#
|
|
64
|
-
npm run
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
**
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
โโโ
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>๐ Kuli Digital NestJS Backend</h1>
|
|
3
|
+
<p>The standard backend application architecture built with NestJS following the <b>Kuli Digital Standardization Manual</b>.</p>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## โจ Features
|
|
9
|
+
|
|
10
|
+
- ๐ **JWT Authentication with RBAC**: Secure endpoints using Role-Based Access Control.
|
|
11
|
+
- ๐ **Complete User Management**: Built-in user creation, login, and profile handling.
|
|
12
|
+
- ๐ฏ **Permission-based Access Control**: Fine-grained authorization controls.
|
|
13
|
+
- ๐ **Auto-generated Swagger Documentation**: Interactive API documentation available out of the box.
|
|
14
|
+
- โ
**Input Validation**: Strongly typed DTOs and parameter validation.
|
|
15
|
+
- ๐ **API Versioning**: Scalable route versioning (e.g., `/v1/...`).
|
|
16
|
+
- ๐ **Structured Logging**: Pre-configured global interceptors for request/response logging.
|
|
17
|
+
- ๐๏ธ **Prisma ORM with PostgreSQL**: Fully typed database access.
|
|
18
|
+
- ๐งช **Testing Setup**: Ready-to-go Unit & E2E testing environments.
|
|
19
|
+
|
|
20
|
+
## โ๏ธ Prerequisites
|
|
21
|
+
|
|
22
|
+
Before you begin, ensure you have met the following requirements:
|
|
23
|
+
- Node.js `>= 18.x`
|
|
24
|
+
- PostgreSQL `>= 14.x`
|
|
25
|
+
- npm, yarn, or pnpm
|
|
26
|
+
|
|
27
|
+
## ๐ Installation & Setup
|
|
28
|
+
|
|
29
|
+
1. **Install dependencies:**
|
|
30
|
+
```bash
|
|
31
|
+
npm install
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
2. **Setup environment variables:**
|
|
35
|
+
Your `.env` file should already be generated if you used the CLI tool. If not, copy it from the example:
|
|
36
|
+
```bash
|
|
37
|
+
cp .env.example .env
|
|
38
|
+
```
|
|
39
|
+
*(Ensure `DATABASE_URL` is correctly configured to point to your PostgreSQL database)*
|
|
40
|
+
|
|
41
|
+
3. **Initialize the Database:**
|
|
42
|
+
```bash
|
|
43
|
+
# Generate Prisma Client
|
|
44
|
+
npx prisma generate
|
|
45
|
+
|
|
46
|
+
# Run migrations to create tables
|
|
47
|
+
npx prisma migrate dev
|
|
48
|
+
|
|
49
|
+
# Seed the database with default roles and users
|
|
50
|
+
npx prisma db seed
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## ๐ป Running the Application
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Development mode (Hot-reload)
|
|
57
|
+
npm run start:dev
|
|
58
|
+
|
|
59
|
+
# Production build
|
|
60
|
+
npm run build
|
|
61
|
+
npm run start:prod
|
|
62
|
+
|
|
63
|
+
# Debug mode
|
|
64
|
+
npm run start:debug
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## ๐ Database Commands (Prisma)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Generate Prisma Client (after pulling new schema changes)
|
|
71
|
+
npx prisma generate
|
|
72
|
+
|
|
73
|
+
# Create a new migration (after modifying schema.prisma)
|
|
74
|
+
npx prisma migrate dev --name <migration_name>
|
|
75
|
+
|
|
76
|
+
# Open Prisma Studio (GUI to view your database)
|
|
77
|
+
npx prisma studio
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## ๐งช Testing
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Run Unit tests
|
|
84
|
+
npm run test
|
|
85
|
+
|
|
86
|
+
# Run E2E tests
|
|
87
|
+
npm run test:e2e
|
|
88
|
+
|
|
89
|
+
# Run tests with coverage
|
|
90
|
+
npm run test:cov
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## ๐ API Documentation
|
|
94
|
+
|
|
95
|
+
Once the application is running, you can access the Swagger UI documentation at:
|
|
96
|
+
๐ **[http://localhost:3000/api-docs](http://localhost:3000/api-docs)**
|
|
97
|
+
|
|
98
|
+
## ๐ฅ Default Seeded Users
|
|
99
|
+
|
|
100
|
+
If you ran `npx prisma db seed`, you can log in with the following default credentials:
|
|
101
|
+
|
|
102
|
+
**๐ Admin User:**
|
|
103
|
+
- Email: `admin@kulidigital.com`
|
|
104
|
+
- Password: `password123`
|
|
105
|
+
- *Privileges: All permissions granted*
|
|
106
|
+
|
|
107
|
+
**๐ค Member User:**
|
|
108
|
+
- Email: `member@kulidigital.com`
|
|
109
|
+
- Password: `password123`
|
|
110
|
+
- *Privileges: Limited permissions (VIEW_USER only)*
|
|
111
|
+
|
|
112
|
+
## ๐ Project Structure
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
src/
|
|
116
|
+
โโโ common/ # Shared resources across the app
|
|
117
|
+
โ โโโ constants/ # Global constants (e.g., Permissions)
|
|
118
|
+
โ โโโ decorators/ # Custom decorators (e.g., @GetUser)
|
|
119
|
+
โ โโโ dto/ # Shared DTOs (e.g., Pagination)
|
|
120
|
+
โ โโโ filters/ # Exception filters (e.g., HttpExceptionFilter)
|
|
121
|
+
โ โโโ guards/ # Auth & permission guards
|
|
122
|
+
โ โโโ helpers/ # Helper functions
|
|
123
|
+
โ โโโ interceptors/ # Logging & transform interceptors
|
|
124
|
+
โ โโโ prisma/ # Prisma module & service
|
|
125
|
+
โ โโโ utils/ # Utility functions (e.g., Password hashing)
|
|
126
|
+
โโโ config/ # Configuration files & Environment validation
|
|
127
|
+
โโโ modules/ # Feature-specific modules
|
|
128
|
+
โ โโโ auth/ # Authentication logic & endpoints
|
|
129
|
+
โ โโโ users/ # User management logic & endpoints
|
|
130
|
+
โ โโโ health/ # Health check endpoint
|
|
131
|
+
โโโ app.module.ts # Root module
|
|
132
|
+
โโโ main.ts # Application entry point
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## ๐ License
|
|
136
|
+
|
|
137
|
+
Proprietary - Kuli Digital
|