@kuldi/create-nestjs 1.0.1 โ†’ 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 (68) hide show
  1. package/README.md +27 -0
  2. package/package.json +13 -3
  3. package/src/cli.js +139 -0
  4. package/template/.editorconfig +12 -0
  5. package/template/.env.example +23 -0
  6. package/template/.eslintrc.js +25 -0
  7. package/template/.prettierrc +8 -0
  8. package/template/README.md +133 -0
  9. package/template/nest-cli.json +10 -0
  10. package/template/package-lock.json +11539 -0
  11. package/template/package.json +99 -0
  12. package/template/prisma/migrations/20260625045841_init/migration.sql +73 -0
  13. package/template/prisma/migrations/migration_lock.toml +3 -0
  14. package/template/prisma/schema.prisma +75 -0
  15. package/template/prisma/seeder/data/permission.seed.ts +67 -0
  16. package/template/prisma/seeder/data/position.seed.ts +21 -0
  17. package/template/prisma/seeder/data/user.seed.ts +39 -0
  18. package/template/prisma/seeder/index.ts +56 -0
  19. package/template/prisma.config.ts +8 -0
  20. package/template/src/app.module.ts +68 -0
  21. package/template/src/common/constants/permissions.constant.ts +27 -0
  22. package/template/src/common/decorators/api-response.decorator.ts +44 -0
  23. package/template/src/common/decorators/get-user.decorator.ts +11 -0
  24. package/template/src/common/decorators/permissions.decorator.ts +5 -0
  25. package/template/src/common/decorators/public.decorator.ts +4 -0
  26. package/template/src/common/dto/api-response.dto.ts +15 -0
  27. package/template/src/common/dto/pagination.dto.ts +33 -0
  28. package/template/src/common/filters/http-exception.filter.ts +54 -0
  29. package/template/src/common/guards/jwt-auth.guard.ts +32 -0
  30. package/template/src/common/guards/permissions.guard.ts +53 -0
  31. package/template/src/common/helpers/function/error-helper.ts +35 -0
  32. package/template/src/common/interceptors/logging.interceptor.ts +37 -0
  33. package/template/src/common/interceptors/transform.interceptor.ts +53 -0
  34. package/template/src/common/prisma/prisma.module.ts +9 -0
  35. package/template/src/common/prisma/prisma.service.ts +52 -0
  36. package/template/src/common/utils/password.util.ts +13 -0
  37. package/template/src/config/app.config.ts +10 -0
  38. package/template/src/config/database.config.ts +5 -0
  39. package/template/src/config/env.validation.ts +30 -0
  40. package/template/src/config/jwt.config.ts +8 -0
  41. package/template/src/config/swagger.config.ts +6 -0
  42. package/template/src/main.ts +84 -0
  43. package/template/src/modules/auth/auth.module.ts +28 -0
  44. package/template/src/modules/auth/auth.service.ts +173 -0
  45. package/template/src/modules/auth/controllers/v1/auth.controller.ts +71 -0
  46. package/template/src/modules/auth/core/dto/auth-response.dto.ts +19 -0
  47. package/template/src/modules/auth/core/dto/login-response.dto.ts +10 -0
  48. package/template/src/modules/auth/core/dto/login.dto.ts +15 -0
  49. package/template/src/modules/auth/core/dto/register.dto.ts +30 -0
  50. package/template/src/modules/auth/core/interfaces/jwt-payload.interface.ts +7 -0
  51. package/template/src/modules/auth/core/strategies/jwt.strategy.ts +59 -0
  52. package/template/src/modules/health/health.controller.ts +29 -0
  53. package/template/src/modules/health/health.module.ts +7 -0
  54. package/template/src/modules/users/controllers/v1/users.controller.ts +120 -0
  55. package/template/src/modules/users/core/dto/change-position.dto.ts +9 -0
  56. package/template/src/modules/users/core/dto/create-user.dto.ts +35 -0
  57. package/template/src/modules/users/core/dto/manage-permissions.dto.ts +13 -0
  58. package/template/src/modules/users/core/dto/update-user.dto.ts +30 -0
  59. package/template/src/modules/users/core/dto/user-query.dto.ts +22 -0
  60. package/template/src/modules/users/core/dto/user-response.dto.ts +32 -0
  61. package/template/src/modules/users/core/entities/user.entity.ts +45 -0
  62. package/template/src/modules/users/core/helpers/user-transform.helper.ts +31 -0
  63. package/template/src/modules/users/users.module.ts +10 -0
  64. package/template/src/modules/users/users.service.ts +344 -0
  65. package/template/test/app.e2e-spec.ts +40 -0
  66. package/template/test/jest-e2e.json +9 -0
  67. package/template/tsconfig.json +30 -0
  68. package/bin/cli.js +0 -71
package/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # @kuldi/create-nestjs
2
+
3
+ The official interactive scaffolding tool for Kuli Digital's NestJS Boilerplate.
4
+
5
+ ## Quick Start
6
+
7
+ To generate a new NestJS project using this boilerplate, simply run:
8
+
9
+ ```bash
10
+ npm create @kuldi/nestjs my-app
11
+ ```
12
+
13
+ Or, to create it in the current directory:
14
+
15
+ ```bash
16
+ npm create @kuldi/nestjs .
17
+ ```
18
+
19
+ ## Features
20
+
21
+ - **Interactive Prompts**: Easily configure your project name and database name.
22
+ - **Auto-Configured Environment**: Automatically generates a `.env` file tailored to your database credentials.
23
+ - **Production Ready**: Scaffolds a full-fledged NestJS architecture with Prisma, Swagger, and JWT Auth out of the box.
24
+
25
+ ## License
26
+
27
+ MIT - Kuli Digital
package/package.json CHANGED
@@ -1,9 +1,14 @@
1
1
  {
2
2
  "name": "@kuldi/create-nestjs",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
+ "type": "module",
4
5
  "description": "Scaffolding tool for Kuli Digital NestJS Boilerplate",
5
- "main": "bin/cli.js",
6
- "bin": "bin/cli.js",
6
+ "main": "src/cli.js",
7
+ "bin": "src/cli.js",
8
+ "files": [
9
+ "src",
10
+ "template"
11
+ ],
7
12
  "scripts": {
8
13
  "test": "echo \"Error: no test specified\" && exit 1"
9
14
  },
@@ -22,5 +27,10 @@
22
27
  "license": "MIT",
23
28
  "publishConfig": {
24
29
  "access": "public"
30
+ },
31
+ "dependencies": {
32
+ "chalk": "^5.6.2",
33
+ "inquirer": "^14.0.2",
34
+ "ora": "^9.4.1"
25
35
  }
26
36
  }
package/src/cli.js ADDED
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execSync } from 'child_process';
4
+ import path from 'path';
5
+ import fs from 'fs';
6
+ import inquirer from 'inquirer';
7
+ import ora from 'ora';
8
+ import chalk from 'chalk';
9
+ import { fileURLToPath } from 'url';
10
+
11
+ const currentPath = process.cwd();
12
+
13
+ // Fallback untuk support Node versi di bawah 20.11 yang belum punya import.meta.dirname
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
16
+
17
+ async function run() {
18
+ console.log(chalk.cyan.bold('\n๐Ÿš€ Kuli Digital NestJS Boilerplate Generator\n'));
19
+
20
+ const argProjectName = process.argv[2];
21
+
22
+ // 1. Tanya-tanya
23
+ const answers = await inquirer.prompt([
24
+ {
25
+ type: 'input',
26
+ name: 'projectName',
27
+ message: 'Nama Project (atau . untuk folder saat ini):',
28
+ default: argProjectName || 'my-nestjs-app',
29
+ when: !argProjectName,
30
+ },
31
+ {
32
+ type: 'input',
33
+ name: 'database',
34
+ message: 'Nama Database PostgreSQL:',
35
+ default: 'kulidigital_db',
36
+ },
37
+ {
38
+ type: 'confirm',
39
+ name: 'skipInstall',
40
+ message: 'Lewati instalasi package (npm install)?',
41
+ default: false,
42
+ },
43
+ ]);
44
+
45
+ const projectName = argProjectName || answers.projectName;
46
+ const projectPath = projectName === '.' ? currentPath : path.join(currentPath, projectName);
47
+
48
+ // Mengecek apakah target directory kosong
49
+ if (projectName === '.') {
50
+ const files = fs.readdirSync(currentPath).filter(f => !f.startsWith('.git'));
51
+ if (files.length > 0) {
52
+ console.log(chalk.red('\nโŒ Folder saat ini tidak kosong! Harap jalankan di folder kosong.\n'));
53
+ process.exit(1);
54
+ }
55
+ }
56
+
57
+ // 2. Salin Template
58
+ const copySpinner = ora('Membuat struktur project...').start();
59
+ try {
60
+ const templateDir = path.join(__dirname, '../template');
61
+
62
+ // Copy seluruh isi folder template ke project tujuan
63
+ fs.cpSync(templateDir, projectPath, { recursive: true });
64
+
65
+ // Rename gitignore menjadi .gitignore (krn NPM mengabaikan .gitignore saat publish)
66
+ const gitignorePath = path.join(projectPath, 'gitignore');
67
+ if (fs.existsSync(gitignorePath)) {
68
+ fs.renameSync(gitignorePath, path.join(projectPath, '.gitignore'));
69
+ }
70
+
71
+ copySpinner.succeed('Struktur project berhasil dibuat.');
72
+ } catch (error) {
73
+ copySpinner.fail('Gagal menyalin struktur template.');
74
+ console.error(error.message);
75
+ process.exit(1);
76
+ }
77
+
78
+ // Masuk ke folder project
79
+ process.chdir(projectPath);
80
+
81
+ // 3. Setup .env
82
+ const envSpinner = ora('Menyiapkan file .env...').start();
83
+ try {
84
+ const envExamplePath = path.join(projectPath, '.env.example');
85
+ const envPath = path.join(projectPath, '.env');
86
+
87
+ if (fs.existsSync(envExamplePath)) {
88
+ let envContent = fs.readFileSync(envExamplePath, 'utf-8');
89
+
90
+ envContent = envContent.replace(/__DATABASE_NAME__/g, answers.database);
91
+ envContent = envContent.replace(/APP_NAME=my-app/g, `APP_NAME=${projectName === '.' ? path.basename(currentPath) : projectName}`);
92
+
93
+ fs.writeFileSync(envPath, envContent);
94
+ envSpinner.succeed('File .env berhasil dibuat.');
95
+ } else {
96
+ envSpinner.warn('File .env.example tidak ditemukan, lewati setup .env.');
97
+ }
98
+ } catch (error) {
99
+ envSpinner.fail('Gagal menyiapkan file .env.');
100
+ }
101
+
102
+ // 4. Inisialisasi Git
103
+ try {
104
+ execSync('git init', { stdio: 'ignore' });
105
+ } catch (e) {
106
+ // Abaikan jika user tidak punya git terinstall
107
+ }
108
+
109
+ // 5. Install Dependencies
110
+ if (!answers.skipInstall) {
111
+ const installSpinner = ora(`Menginstal dependencies menggunakan npm... (ini butuh waktu beberapa menit)`).start();
112
+ try {
113
+ execSync(`npm install`, { stdio: 'ignore' });
114
+ installSpinner.succeed('Dependencies berhasil diinstal.');
115
+ } catch (error) {
116
+ installSpinner.fail('Gagal menginstal dependencies.');
117
+ console.log(chalk.yellow('\nKamu bisa menginstalnya secara manual nanti.'));
118
+ }
119
+ }
120
+
121
+ // 6. Success Message
122
+ console.log(chalk.green.bold('\nโœ… Project Berhasil Dibuat!\n'));
123
+ console.log(chalk.white('Langkah selanjutnya:'));
124
+
125
+ if (projectName !== '.') {
126
+ console.log(chalk.cyan(` cd ${projectName}`));
127
+ }
128
+
129
+ if (answers.skipInstall) {
130
+ console.log(chalk.cyan(` npm install`));
131
+ }
132
+
133
+ console.log(chalk.cyan(` npx prisma migrate dev`));
134
+ console.log(chalk.cyan(` npx prisma db seed`));
135
+ console.log(chalk.cyan(` npm run start:dev\n`));
136
+ console.log(chalk.gray(`Happy Coding! - Kuli Digital\n`));
137
+ }
138
+
139
+ run();
@@ -0,0 +1,12 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ indent_style = space
6
+ indent_size = 2
7
+ end_of_line = lf
8
+ insert_final_newline = true
9
+ trim_trailing_whitespace = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
@@ -0,0 +1,23 @@
1
+ # Application
2
+ NODE_ENV=development
3
+ PORT=3000
4
+ APP_NAME=my-app
5
+
6
+ # Database
7
+ DATABASE_URL="postgresql://username:password@localhost:5432/__DATABASE_NAME__?schema=public"
8
+
9
+ # JWT
10
+ JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
11
+ JWT_EXPIRATION=7d
12
+ JWT_REFRESH_SECRET=your-super-secret-refresh-key-change-this-in-production
13
+ JWT_REFRESH_EXPIRATION=30d
14
+
15
+ # CORS
16
+ CORS_ORIGIN=http://localhost:3001
17
+
18
+ # API
19
+ API_PREFIX=api
20
+
21
+ # Swagger
22
+ SWAGGER_ENABLED=true
23
+ SWAGGER_PATH=docs
@@ -0,0 +1,25 @@
1
+ module.exports = {
2
+ parser: '@typescript-eslint/parser',
3
+ parserOptions: {
4
+ project: 'tsconfig.json',
5
+ tsconfigRootDir: __dirname,
6
+ sourceType: 'module',
7
+ },
8
+ plugins: ['@typescript-eslint/eslint-plugin'],
9
+ extends: [
10
+ 'plugin:@typescript-eslint/recommended',
11
+ 'plugin:prettier/recommended',
12
+ ],
13
+ root: true,
14
+ env: {
15
+ node: true,
16
+ jest: true,
17
+ },
18
+ ignorePatterns: ['.eslintrc.js'],
19
+ rules: {
20
+ '@typescript-eslint/interface-name-prefix': 'off',
21
+ '@typescript-eslint/explicit-function-return-type': 'off',
22
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
23
+ '@typescript-eslint/no-explicit-any': 'off',
24
+ },
25
+ };
@@ -0,0 +1,8 @@
1
+ {
2
+ "singleQuote": true,
3
+ "trailingComma": "all",
4
+ "tabWidth": 2,
5
+ "semi": true,
6
+ "printWidth": 100,
7
+ "arrowParens": "always"
8
+ }
@@ -0,0 +1,133 @@
1
+ # Kuli Digital NestJS Backend
2
+
3
+ Backend application built with NestJS following Kuli Digital standardization manual.
4
+
5
+ ## Features
6
+
7
+ - ๐Ÿ” JWT Authentication with RBAC
8
+ - ๐Ÿ“ Complete User Management
9
+ - ๐ŸŽฏ Permission-based Access Control
10
+ - ๐Ÿ“š Auto-generated Swagger Documentation
11
+ - โœ… Input Validation
12
+ - ๐Ÿ”„ API Versioning
13
+ - ๐Ÿ“Š Structured Logging
14
+ - ๐Ÿ—ƒ๏ธ Prisma ORM with PostgreSQL
15
+ - ๐Ÿงช Testing Setup (Unit & E2E)
16
+
17
+ ## Prerequisites
18
+
19
+ - Node.js >= 18.x
20
+ - PostgreSQL >= 14.x
21
+ - npm/yarn/pnpm
22
+
23
+ ## Installation
24
+ ```bash
25
+ # Install dependencies
26
+ npm install
27
+
28
+ # Setup environment variables
29
+ cp .env.example .env
30
+ # Edit .env with your database credentials
31
+
32
+ # Generate Prisma Client
33
+ npm run prisma:generate
34
+
35
+ # Run migrations
36
+ npm run prisma:migrate
37
+
38
+ # Seed database
39
+ npm run prisma:seed
40
+ ```
41
+
42
+ ## Running the Application
43
+ ```bash
44
+ # Development
45
+ npm run start:dev
46
+
47
+ # Production build
48
+ npm run build
49
+ npm run start:prod
50
+
51
+ # Debug mode
52
+ npm run start:debug
53
+ ```
54
+
55
+ ## Database Commands
56
+ ```bash
57
+ # Generate Prisma Client
58
+ npm run prisma:generate
59
+
60
+ # Create migration
61
+ npm run prisma:migrate
62
+
63
+ # Seed database
64
+ npm run prisma:seed
65
+
66
+ # Open Prisma Studio
67
+ npm run prisma:studio
68
+ ```
69
+
70
+ ## Testing
71
+ ```bash
72
+ # Unit tests
73
+ npm run test
74
+
75
+ # E2E tests
76
+ npm run test:e2e
77
+
78
+ # Test coverage
79
+ npm run test:cov
80
+ ```
81
+
82
+ ## API Documentation
83
+
84
+ After starting the application, visit:
85
+ - Swagger UI: `http://localhost:3000/api-docs`
86
+
87
+ ## Default Users
88
+
89
+ After seeding the database:
90
+
91
+ **Admin User:**
92
+ - Email: `admin@kulidigital.com`
93
+ - Password: `password123`
94
+ - All permissions granted
95
+
96
+ **Member User:**
97
+ - Email: `member@kulidigital.com`
98
+ - Password: `password123`
99
+ - Limited permissions (VIEW_USER only)
100
+
101
+ ## Project Structure
102
+ ```
103
+ src/
104
+ โ”œโ”€โ”€ common/ # Shared resources
105
+ โ”‚ โ”œโ”€โ”€ decorators/ # Custom decorators
106
+ โ”‚ โ”œโ”€โ”€ filters/ # Exception filters
107
+ โ”‚ โ”œโ”€โ”€ guards/ # Auth & permission guards
108
+ โ”‚ โ”œโ”€โ”€ interceptors/ # Logging & transform
109
+ โ”‚ โ”œโ”€โ”€ prisma/ # Prisma service
110
+ โ”‚ โ””โ”€โ”€ utils/ # Helper functions
111
+ โ”œโ”€โ”€ config/ # Configuration files
112
+ โ”œโ”€โ”€ modules/ # Feature modules
113
+ โ”‚ โ”œโ”€โ”€ auth/ # Authentication
114
+ โ”‚ โ”œโ”€โ”€ users/ # User management
115
+ โ”‚ โ””โ”€โ”€ health/ # Health checks
116
+ โ”œโ”€โ”€ app.module.ts # Root module
117
+ โ””โ”€โ”€ main.ts # Application entry point
118
+ ```
119
+
120
+ ## Environment Variables
121
+
122
+ See `.env.example` for all available configuration options.
123
+
124
+ ## License
125
+
126
+ Proprietary - Kuli Digital
127
+ ```
128
+
129
+ ### 20.2 .gitkeep for migrations
130
+
131
+ **templates/nestjs-app/prisma/migrations/.gitkeep**
132
+ ```
133
+ # This file keeps the migrations directory in git
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/nest-cli",
3
+ "collection": "@nestjs/schematics",
4
+ "sourceRoot": "src",
5
+ "compilerOptions": {
6
+ "deleteOutDir": true,
7
+ "webpack": true,
8
+ "tsConfigPath": "tsconfig.json"
9
+ }
10
+ }