nestjs-prisma-cli 1.0.10 → 1.0.12

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 CHANGED
@@ -1,4 +1,4 @@
1
- # 🚀 NestJS + Prisma Project Generator
1
+ # NestJS + Prisma Project Generator
2
2
 
3
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](#license)
4
4
 
@@ -6,23 +6,23 @@ A CLI tool to quickly scaffold a **NestJS + Prisma** project with pre-configured
6
6
 
7
7
  ---
8
8
 
9
- ## 📦 NestJS Prisma Generator CLI
9
+ ## NestJS Prisma Generator CLI
10
10
 
11
11
  A CLI tool to quickly scaffold a **NestJS + Prisma** project with built-in support for:
12
12
 
13
- - 🔧 Prisma ORM with migrations and seeding
14
- - 📖 Swagger (OpenAPI) setup
15
- - 🔑 Authentication boilerplate
16
- - ☁️ AWS S3 integration
17
- - 📜 Logging via Winston (rotating logs and DB persistence)
13
+ - Prisma ORM with migrations and seeding
14
+ - Swagger (OpenAPI) setup
15
+ - Authentication boilerplate
16
+ - AWS S3 integration
17
+ - Logging via Winston (rotating logs and DB persistence)
18
18
 
19
19
  Compatible with **Node.js >=18** and **NestJS v10+**.
20
20
 
21
21
  ---
22
22
 
23
- ## 📥 Installation
23
+ ## Installation
24
24
 
25
- ### Quick Start Guide
25
+ ### Quick Start Guide
26
26
 
27
27
  Once the CLI is installed, you can use the following commands:
28
28
 
package/bin/index.js CHANGED
@@ -193,17 +193,17 @@ async function main() {
193
193
  sqlserver: `sqlserver://localhost:1433;database=${dbSafeName};user=sa;password=your_password;encrypt=false`,
194
194
  };
195
195
 
196
- const envContent = `DATABASE_URL="${defaultUrlMap[database.toLowerCase()]}"
196
+ const envContent = `DATABASE_URL=${defaultUrlMap[database.toLowerCase()]}
197
197
 
198
- JWT_ACCESS_SECRET="JWT_ACCESS_SECRET"
199
- JWT_REFRESH_SECRET="JWT_REFRESH_SECRET"
200
- JWT_ACCESS_EXPIRATION_TIME="1d"
201
- JWT_REFRESH_EXPIRATION_TIME="30d"
198
+ JWT_ACCESS_SECRET=JWT_ACCESS_SECRET
199
+ JWT_REFRESH_SECRET=JWT_REFRESH_SECRET
200
+ JWT_ACCESS_EXPIRATION_TIME=1d
201
+ JWT_REFRESH_EXPIRATION_TIME=30d
202
202
 
203
- AWS_ACCESS_KEY_ID="AWS_ACCESS_KEY_ID"
204
- AWS_SECRET_ACCESS_KEY="AWS_SECRET_ACCESS_KEY"
203
+ AWS_ACCESS_KEY_ID=AWS_ACCESS_KEY_ID
204
+ AWS_SECRET_ACCESS_KEY=AWS_SECRET_ACCESS_KEY
205
205
  AWS_REGION=ap-southeast-1
206
- S3_BUCKET="S3_BUCKET"
206
+ S3_BUCKET=S3_BUCKET
207
207
 
208
208
  NODE_ENV=dev
209
209
  PROJECT_NAME=${dbSafeName}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestjs-prisma-cli",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "A CLI to generate NestJS + Prisma project boilerplate with Swagger, Auth, and AWS S3 setup",
5
5
  "type": "module",
6
6
  "main": "bin/index.js",
@@ -10,7 +10,7 @@ on:
10
10
  env:
11
11
  AWS_REGION: ap-southeast-1
12
12
  ECR_REGISTRY: 339713129923.dkr.ecr.ap-southeast-1.amazonaws.com
13
- ECR_REPOSITORY: freshmoe-hrms-api
13
+ ECR_REPOSITORY: ecr-repository-name
14
14
 
15
15
  jobs:
16
16
  deploy:
@@ -4,84 +4,84 @@ import {
4
4
  Body,
5
5
  HttpCode,
6
6
  UnauthorizedException,
7
- } from '@nestjs/common';
8
- import { ApiBody, ApiTags } from '@nestjs/swagger';
9
- import { AuthService } from './auth.service';
10
- import { Public } from '../../common/decorator/public.decorator';
11
- import { JwtService } from '@nestjs/jwt';
12
- import { LoginDto } from './dto/login.dto';
7
+ } from "@nestjs/common";
8
+ import { ApiBody, ApiTags } from "@nestjs/swagger";
9
+ import { AuthService } from "./auth.service";
10
+ import { Public } from "../../common/decorator/public.decorator";
11
+ import { JwtService } from "@nestjs/jwt";
12
+ import { LoginDto } from "./dto/login.dto";
13
13
 
14
- @ApiTags('Authentication')
14
+ @ApiTags("Authentication")
15
15
  @Controller()
16
16
  export class AuthController {
17
17
  constructor(
18
18
  private readonly authService: AuthService,
19
- private readonly jwtService: JwtService,
19
+ private readonly jwtService: JwtService
20
20
  ) {}
21
21
 
22
22
  @Public()
23
- @Post('login')
24
- @ApiBody({ description: 'Login credentials', type: LoginDto })
23
+ @Post("login")
24
+ @ApiBody({ description: "Login credentials", type: LoginDto })
25
25
  async login(@Body() body: LoginDto) {
26
26
  if (!body || !body.userId || !body.password) {
27
- throw new UnauthorizedException('Missing login credentials');
27
+ throw new UnauthorizedException("Missing login credentials");
28
28
  }
29
29
 
30
30
  const user = await this.authService.validateUser(
31
31
  body.userId,
32
- body.password,
32
+ body.password
33
33
  );
34
34
  return this.authService.login(user);
35
35
  }
36
36
 
37
37
  @Public()
38
- @Post('refresh')
38
+ @Post("refresh")
39
39
  @ApiBody({
40
- description: 'Provide your userId and refreshToken',
40
+ description: "Provide your userId and refreshToken",
41
41
  schema: {
42
- type: 'object',
42
+ type: "object",
43
43
  properties: {
44
- userId: { type: 'string', example: 'USER_20250815001' },
45
- refreshToken: { type: 'string', example: 'xxxx.yyyy.zzzz' },
44
+ userId: { type: "string", example: "USER_20250815001" },
45
+ refreshToken: { type: "string", example: "xxxx.yyyy.zzzz" },
46
46
  },
47
- required: ['userId', 'refreshToken'],
47
+ required: ["userId", "refreshToken"],
48
48
  },
49
49
  })
50
50
  async refresh(@Body() body: { userId: string; refreshToken: string }) {
51
51
  if (!body || !body.userId || !body.refreshToken) {
52
- throw new UnauthorizedException('Missing login credentials');
52
+ throw new UnauthorizedException("Missing login credentials");
53
53
  }
54
54
 
55
55
  let payload: any;
56
- const modifiedUserId = body.userId.replace(/\s+/g, '');
56
+ const modifiedUserId = body.userId.replace(/\s+/g, "");
57
57
 
58
58
  try {
59
59
  payload = this.jwtService.verify(body.refreshToken, {
60
60
  secret: process.env.JWT_REFRESH_SECRET,
61
61
  });
62
62
  } catch (err) {
63
- if (err.name === 'TokenExpiredError') {
64
- throw new UnauthorizedException('Refresh Token expired');
63
+ if (err.name === "TokenExpiredError") {
64
+ throw new UnauthorizedException("Refresh Token expired");
65
65
  }
66
- throw new UnauthorizedException('Invalid refresh token');
66
+ throw new UnauthorizedException("Invalid refresh token");
67
67
  }
68
68
 
69
69
  if (String(payload.userId).trim() !== modifiedUserId) {
70
- throw new UnauthorizedException('Unauthorized access');
70
+ throw new UnauthorizedException("Unauthorized access");
71
71
  }
72
72
 
73
73
  const user = await this.authService.getUserByUserId(modifiedUserId);
74
74
 
75
75
  if (!user) {
76
- throw new UnauthorizedException('User not found');
76
+ throw new UnauthorizedException("User not found");
77
77
  }
78
78
 
79
79
  const newAccessToken = this.jwtService.sign(
80
80
  { sub: user.id, userId: user.userId },
81
81
  {
82
82
  secret: process.env.JWT_ACCESS_SECRET,
83
- expiresIn: process.env.JWT_ACCESS_EXPIRATION_TIME,
84
- },
83
+ expiresIn: process.env.JWT_ACCESS_EXPIRATION_TIME as any,
84
+ }
85
85
  );
86
86
 
87
87
  return {
@@ -91,16 +91,16 @@ export class AuthController {
91
91
  }
92
92
 
93
93
  @Public()
94
- @Post('validate')
94
+ @Post("validate")
95
95
  @HttpCode(200)
96
96
  @ApiBody({
97
- description: 'Provide the access token to validate',
97
+ description: "Provide the access token to validate",
98
98
  schema: {
99
- type: 'object',
99
+ type: "object",
100
100
  properties: {
101
- token: { type: 'string', example: 'xxxx.yyyy.zzzz' },
101
+ token: { type: "string", example: "xxxx.yyyy.zzzz" },
102
102
  },
103
- required: ['token'],
103
+ required: ["token"],
104
104
  },
105
105
  })
106
106
  async validate(@Body() body: { token: string }) {
@@ -110,10 +110,10 @@ export class AuthController {
110
110
  });
111
111
  return payload;
112
112
  } catch (err) {
113
- if (err.name === 'TokenExpiredError') {
114
- throw new UnauthorizedException('Token expired');
113
+ if (err.name === "TokenExpiredError") {
114
+ throw new UnauthorizedException("Token expired");
115
115
  }
116
- throw new UnauthorizedException('Invalid token');
116
+ throw new UnauthorizedException("Invalid token");
117
117
  }
118
118
  }
119
119
  }
@@ -1,7 +1,7 @@
1
1
  import { Module } from '@nestjs/common';
2
2
  import { AuthController } from './auth.controller';
3
3
  import { AuthService } from './auth.service';
4
- import { JwtModule } from '@nestjs/jwt';
4
+ import { JwtModule, JwtModuleOptions } from '@nestjs/jwt';
5
5
  import { JwtStrategy } from './jwt/jwt.strategy';
6
6
  import { ConfigModule, ConfigService } from '@nestjs/config';
7
7
 
@@ -11,12 +11,21 @@ import { ConfigModule, ConfigService } from '@nestjs/config';
11
11
  JwtModule.registerAsync({
12
12
  imports: [ConfigModule],
13
13
  inject: [ConfigService],
14
- useFactory: async (configService: ConfigService) => ({
15
- secret: configService.get<string>('JWT_ACCESS_SECRET'),
16
- signOptions: {
17
- expiresIn: configService.get<string>('JWT_ACCESS_EXPIRATION_TIME'),
18
- },
19
- }),
14
+ useFactory: async (configService: ConfigService): Promise<JwtModuleOptions> => {
15
+ const secret = configService.get<string>('JWT_ACCESS_SECRET');
16
+ const expiresIn = configService.get<string>('JWT_ACCESS_EXPIRATION_TIME');
17
+
18
+ if (!secret || !expiresIn) {
19
+ throw new Error('Missing JWT environment variables');
20
+ }
21
+
22
+ return {
23
+ secret,
24
+ signOptions: {
25
+ expiresIn: expiresIn as any,
26
+ },
27
+ };
28
+ },
20
29
  }),
21
30
  ],
22
31
  controllers: [AuthController],
@@ -36,12 +36,12 @@ export class AuthService {
36
36
 
37
37
  const accessToken = this.jwtService.sign(payload, {
38
38
  secret: process.env.JWT_ACCESS_SECRET,
39
- expiresIn: process.env.JWT_ACCESS_EXPIRATION_TIME,
39
+ expiresIn: process.env.JWT_ACCESS_EXPIRATION_TIME as any,
40
40
  });
41
41
 
42
42
  const refreshToken = this.jwtService.sign(payload, {
43
43
  secret: process.env.JWT_REFRESH_SECRET,
44
- expiresIn: process.env.JWT_REFRESH_EXPIRATION_TIME,
44
+ expiresIn: process.env.JWT_REFRESH_EXPIRATION_TIME as any,
45
45
  });
46
46
 
47
47
  return {