nestforge-generator 0.3.0 → 0.4.1

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 (137) hide show
  1. package/README.md +13 -1
  2. package/README.pt-BR.md +13 -1
  3. package/dist/features/auth-strategy.js +7 -7
  4. package/dist/features/dependencies.js +3 -3
  5. package/dist/features/language.js +1 -1
  6. package/dist/features/language.js.map +1 -1
  7. package/dist/features/markers.js +11 -11
  8. package/dist/features/markers.js.map +1 -1
  9. package/dist/generator.js +7 -1
  10. package/dist/generator.js.map +1 -1
  11. package/dist/index.js +4 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/project-name.js +50 -0
  14. package/dist/project-name.js.map +1 -0
  15. package/dist/prompts.js +12 -10
  16. package/dist/prompts.js.map +1 -1
  17. package/package.json +1 -1
  18. package/templates/drizzle/drizzle.config.ts +2 -2
  19. package/templates/drizzle/src/auth/auth.controller.ts +35 -35
  20. package/templates/drizzle/src/auth/auth.service.spec.ts +4 -4
  21. package/templates/drizzle/src/auth/auth.service.ts +9 -9
  22. package/templates/drizzle/src/auth/dto/forgot-password.dto.ts +2 -2
  23. package/templates/drizzle/src/auth/dto/login.dto.ts +3 -3
  24. package/templates/drizzle/src/auth/dto/register.dto.ts +4 -4
  25. package/templates/drizzle/src/auth/dto/reset-password.dto.ts +3 -3
  26. package/templates/drizzle/src/auth/guards/github-auth.guard.ts +2 -2
  27. package/templates/drizzle/src/auth/guards/google-auth.guard.ts +2 -2
  28. package/templates/drizzle/src/auth/guards/session-auth.guard.spec.ts +4 -4
  29. package/templates/drizzle/src/auth/guards/session-auth.guard.ts +2 -2
  30. package/templates/drizzle/src/auth/session.service.spec.ts +5 -5
  31. package/templates/drizzle/src/auth/session.service.ts +5 -5
  32. package/templates/drizzle/src/auth/strategies/github.strategy.ts +3 -3
  33. package/templates/drizzle/src/auth/token.service.ts +3 -3
  34. package/templates/drizzle/src/common/filters/http-exception.filter.ts +1 -1
  35. package/templates/drizzle/src/common/guards/permissions.guard.spec.ts +7 -7
  36. package/templates/drizzle/src/common/guards/roles.guard.spec.ts +4 -4
  37. package/templates/drizzle/src/common/middleware/csrf.middleware.spec.ts +5 -5
  38. package/templates/drizzle/src/common/middleware/csrf.middleware.ts +2 -2
  39. package/templates/drizzle/src/common/utils/avatar-storage.util.ts +2 -2
  40. package/templates/drizzle/src/config/env.validation.ts +1 -1
  41. package/templates/drizzle/src/database/seed.ts +4 -4
  42. package/templates/drizzle/src/health/health.controller.ts +2 -2
  43. package/templates/drizzle/src/health/indicators/drizzle-health.indicator.spec.ts +5 -5
  44. package/templates/drizzle/src/health/indicators/drizzle-health.indicator.ts +2 -2
  45. package/templates/drizzle/src/health/indicators/redis-health.indicator.spec.ts +5 -5
  46. package/templates/drizzle/src/health/indicators/redis-health.indicator.ts +3 -3
  47. package/templates/drizzle/src/mail/mail.processor.ts +4 -4
  48. package/templates/drizzle/src/mail/templates/email-templates.ts +7 -7
  49. package/templates/drizzle/src/metrics/metrics.service.ts +3 -3
  50. package/templates/drizzle/src/users/dto/create-user.dto.ts +5 -5
  51. package/templates/drizzle/src/users/dto/find-users-query.dto.ts +3 -3
  52. package/templates/drizzle/src/users/users.controller.ts +21 -21
  53. package/templates/drizzle/src/users/users.service.spec.ts +12 -12
  54. package/templates/drizzle/src/users/users.service.ts +4 -4
  55. package/templates/drizzle/test/auth.e2e-spec.ts +8 -8
  56. package/templates/drizzle/test/session-auth.e2e-spec.ts +9 -9
  57. package/templates/drizzle/test/users.e2e-spec.ts +18 -18
  58. package/templates/prisma/prisma/seed.ts +46 -46
  59. package/templates/prisma/src/auth/auth.controller.ts +35 -35
  60. package/templates/prisma/src/auth/auth.service.spec.ts +3 -3
  61. package/templates/prisma/src/auth/auth.service.ts +11 -11
  62. package/templates/prisma/src/auth/dto/forgot-password.dto.ts +2 -2
  63. package/templates/prisma/src/auth/dto/login.dto.ts +3 -3
  64. package/templates/prisma/src/auth/dto/register.dto.ts +4 -4
  65. package/templates/prisma/src/auth/dto/reset-password.dto.ts +3 -3
  66. package/templates/prisma/src/auth/guards/github-auth.guard.ts +10 -10
  67. package/templates/prisma/src/auth/guards/google-auth.guard.ts +10 -10
  68. package/templates/prisma/src/auth/guards/session-auth.guard.spec.ts +4 -4
  69. package/templates/prisma/src/auth/guards/session-auth.guard.ts +2 -2
  70. package/templates/prisma/src/auth/session.service.spec.ts +5 -5
  71. package/templates/prisma/src/auth/session.service.ts +5 -5
  72. package/templates/prisma/src/auth/strategies/github.strategy.ts +3 -3
  73. package/templates/prisma/src/auth/token.service.ts +2 -2
  74. package/templates/prisma/src/common/filters/http-exception.filter.ts +34 -34
  75. package/templates/prisma/src/common/guards/permissions.guard.spec.ts +7 -7
  76. package/templates/prisma/src/common/guards/roles.guard.spec.ts +4 -4
  77. package/templates/prisma/src/common/middleware/csrf.middleware.spec.ts +5 -5
  78. package/templates/prisma/src/common/middleware/csrf.middleware.ts +2 -2
  79. package/templates/prisma/src/common/utils/avatar-storage.util.ts +32 -32
  80. package/templates/prisma/src/config/env.validation.ts +1 -1
  81. package/templates/prisma/src/health/health.controller.ts +2 -2
  82. package/templates/prisma/src/health/indicators/prisma-health.indicator.spec.ts +4 -4
  83. package/templates/prisma/src/health/indicators/prisma-health.indicator.ts +1 -1
  84. package/templates/prisma/src/health/indicators/redis-health.indicator.spec.ts +5 -5
  85. package/templates/prisma/src/health/indicators/redis-health.indicator.ts +3 -3
  86. package/templates/prisma/src/mail/mail.processor.ts +4 -4
  87. package/templates/prisma/src/mail/templates/email-templates.ts +7 -7
  88. package/templates/prisma/src/metrics/metrics.service.ts +34 -34
  89. package/templates/prisma/src/users/dto/create-user.dto.ts +12 -12
  90. package/templates/prisma/src/users/dto/find-users-query.dto.ts +12 -12
  91. package/templates/prisma/src/users/users.controller.ts +21 -21
  92. package/templates/prisma/src/users/users.service.spec.ts +11 -11
  93. package/templates/prisma/src/users/users.service.ts +4 -4
  94. package/templates/prisma/test/auth.e2e-spec.ts +8 -8
  95. package/templates/prisma/test/session-auth.e2e-spec.ts +9 -9
  96. package/templates/prisma/test/users.e2e-spec.ts +14 -14
  97. package/templates/typeorm/src/auth/auth.controller.ts +35 -35
  98. package/templates/typeorm/src/auth/auth.service.spec.ts +4 -4
  99. package/templates/typeorm/src/auth/auth.service.ts +9 -9
  100. package/templates/typeorm/src/auth/dto/forgot-password.dto.ts +2 -2
  101. package/templates/typeorm/src/auth/dto/login.dto.ts +3 -3
  102. package/templates/typeorm/src/auth/dto/register.dto.ts +4 -4
  103. package/templates/typeorm/src/auth/dto/reset-password.dto.ts +3 -3
  104. package/templates/typeorm/src/auth/guards/github-auth.guard.ts +2 -2
  105. package/templates/typeorm/src/auth/guards/google-auth.guard.ts +2 -2
  106. package/templates/typeorm/src/auth/guards/session-auth.guard.spec.ts +4 -4
  107. package/templates/typeorm/src/auth/guards/session-auth.guard.ts +2 -2
  108. package/templates/typeorm/src/auth/session.service.spec.ts +5 -5
  109. package/templates/typeorm/src/auth/session.service.ts +5 -5
  110. package/templates/typeorm/src/auth/strategies/github.strategy.ts +3 -3
  111. package/templates/typeorm/src/auth/token.service.ts +3 -3
  112. package/templates/typeorm/src/common/filters/http-exception.filter.ts +1 -1
  113. package/templates/typeorm/src/common/guards/permissions.guard.spec.ts +7 -7
  114. package/templates/typeorm/src/common/guards/roles.guard.spec.ts +4 -4
  115. package/templates/typeorm/src/common/middleware/csrf.middleware.spec.ts +5 -5
  116. package/templates/typeorm/src/common/middleware/csrf.middleware.ts +2 -2
  117. package/templates/typeorm/src/common/utils/avatar-storage.util.ts +2 -2
  118. package/templates/typeorm/src/config/env.validation.ts +1 -1
  119. package/templates/typeorm/src/database/data-source.ts +2 -2
  120. package/templates/typeorm/src/database/seed.ts +3 -3
  121. package/templates/typeorm/src/database/typeorm-options.ts +2 -2
  122. package/templates/typeorm/src/health/health.controller.ts +2 -2
  123. package/templates/typeorm/src/health/indicators/redis-health.indicator.spec.ts +5 -5
  124. package/templates/typeorm/src/health/indicators/redis-health.indicator.ts +3 -3
  125. package/templates/typeorm/src/health/indicators/typeorm-health.indicator.spec.ts +4 -4
  126. package/templates/typeorm/src/health/indicators/typeorm-health.indicator.ts +2 -2
  127. package/templates/typeorm/src/mail/mail.processor.ts +4 -4
  128. package/templates/typeorm/src/mail/templates/email-templates.ts +7 -7
  129. package/templates/typeorm/src/metrics/metrics.service.ts +3 -3
  130. package/templates/typeorm/src/users/dto/create-user.dto.ts +5 -5
  131. package/templates/typeorm/src/users/dto/find-users-query.dto.ts +3 -3
  132. package/templates/typeorm/src/users/users.controller.ts +21 -21
  133. package/templates/typeorm/src/users/users.service.spec.ts +12 -12
  134. package/templates/typeorm/src/users/users.service.ts +4 -4
  135. package/templates/typeorm/test/auth.e2e-spec.ts +8 -8
  136. package/templates/typeorm/test/session-auth.e2e-spec.ts +9 -9
  137. package/templates/typeorm/test/users.e2e-spec.ts +18 -18
@@ -24,7 +24,7 @@ export class TypeOrmHealthIndicator {
24
24
  };
25
25
  } catch (error) {
26
26
  throw new HealthCheckError(
27
- 'Banco de dados indisponível',
27
+ 'Database unavailable',
28
28
  {
29
29
  [key]: {
30
30
  status: 'down',
@@ -34,4 +34,4 @@ export class TypeOrmHealthIndicator {
34
34
  );
35
35
  }
36
36
  }
37
- }
37
+ }
@@ -27,13 +27,13 @@ export class MailProcessor extends WorkerHost {
27
27
 
28
28
  switch (job.name) {
29
29
  case MailJob.VerifyEmail:
30
- await this.send(to, 'Confirme seu e-mail', verifyEmailTemplate(name, token));
30
+ await this.send(to, 'Confirm your email', verifyEmailTemplate(name, token));
31
31
  break;
32
32
  case MailJob.ResetPassword:
33
- await this.send(to, 'Redefinição de senha', resetPasswordTemplate(name, token));
33
+ await this.send(to, 'Password reset', resetPasswordTemplate(name, token));
34
34
  break;
35
35
  default:
36
- this.logger.warn(`Job de e-mail desconhecido: ${job.name}`);
36
+ this.logger.warn(`Unknown email job: ${job.name}`);
37
37
  }
38
38
  }
39
39
 
@@ -45,4 +45,4 @@ export class MailProcessor extends WorkerHost {
45
45
  html,
46
46
  });
47
47
  }
48
- }
48
+ }
@@ -6,10 +6,10 @@ export function verifyEmailTemplate(name: string, token: string): string {
6
6
 
7
7
  return `
8
8
  <div style="font-family: sans-serif; line-height: 1.5;">
9
- <h2>Olá, ${name}!</h2>
10
- <p>Confirme seu e-mail clicando no link abaixo:</p>
9
+ <h2>Hello, ${name}!</h2>
10
+ <p>Confirm your email by clicking the link below:</p>
11
11
  <p><a href="${link}">${link}</a></p>
12
- <p>Esse link expira em 24 horas.</p>
12
+ <p>This link expires in 24 hours.</p>
13
13
  </div>
14
14
  `;
15
15
  }
@@ -19,10 +19,10 @@ export function resetPasswordTemplate(name: string, token: string): string {
19
19
 
20
20
  return `
21
21
  <div style="font-family: sans-serif; line-height: 1.5;">
22
- <h2>Olá, ${name}!</h2>
23
- <p>Recebemos um pedido para redefinir sua senha. Clique no link abaixo para continuar:</p>
22
+ <h2>Hello, ${name}!</h2>
23
+ <p>We received a request to reset your password. Click the link below to continue:</p>
24
24
  <p><a href="${link}">${link}</a></p>
25
- <p>Se você não pediu isso, pode ignorar este e-mail. O link expira em 1 hora.</p>
25
+ <p>If you did not request this, you can ignore this email. The link expires in 1 hour.</p>
26
26
  </div>
27
27
  `;
28
- }
28
+ }
@@ -7,7 +7,7 @@ export class MetricsService {
7
7
 
8
8
  readonly httpRequestDuration = new client.Histogram({
9
9
  name: 'http_request_duration_seconds',
10
- help: 'Duração das requisições HTTP em segundos',
10
+ help: 'HTTP request duration in seconds',
11
11
  labelNames: ['method', 'route', 'status_code'],
12
12
  buckets: [0.05, 0.1, 0.3, 0.5, 1, 2, 5],
13
13
  registers: [this.registry],
@@ -15,7 +15,7 @@ export class MetricsService {
15
15
 
16
16
  readonly httpRequestsTotal = new client.Counter({
17
17
  name: 'http_requests_total',
18
- help: 'Total de requisições HTTP recebidas',
18
+ help: 'Total number of HTTP requests received',
19
19
  labelNames: ['method', 'route', 'status_code'],
20
20
  registers: [this.registry],
21
21
  });
@@ -31,4 +31,4 @@ export class MetricsService {
31
31
  getContentType(): string {
32
32
  return this.registry.contentType;
33
33
  }
34
- }
34
+ }
@@ -3,10 +3,10 @@ import { createZodDto } from 'nestjs-zod';
3
3
  import { Role } from '../../common/constants/role.enum';
4
4
 
5
5
  export const createUserSchema = z.object({
6
- name: z.string().min(2).describe('Nome completo'),
7
- email: z.string().email().describe('E-mail do usuário'),
8
- password: z.string().min(8).describe('Senha (mínimo 8 caracteres)'),
9
- role: z.nativeEnum(Role).optional().describe('Role do usuário (padrão: USER)'),
6
+ name: z.string().min(2).describe('Full name'),
7
+ email: z.string().email().describe('User email'),
8
+ password: z.string().min(8).describe('Password (minimum 8 characters)'),
9
+ role: z.nativeEnum(Role).optional().describe('User role (default: USER)'),
10
10
  });
11
11
 
12
- export class CreateUserDto extends createZodDto(createUserSchema) { }
12
+ export class CreateUserDto extends createZodDto(createUserSchema) { }
@@ -3,10 +3,10 @@ import { createZodDto } from 'nestjs-zod';
3
3
  import { Role } from '../../common/constants/role.enum';
4
4
 
5
5
  export const findUsersQuerySchema = z.object({
6
- page: z.coerce.number().int().min(1).default(1).describe('Página atual'),
7
- limit: z.coerce.number().int().min(1).max(100).default(10).describe('Itens por página (máx. 100)'),
6
+ page: z.coerce.number().int().min(1).default(1).describe('Current page'),
7
+ limit: z.coerce.number().int().min(1).max(100).default(10).describe('Items per page (maximum 100)'),
8
8
  search: z.string().optional().describe('Busca por nome ou e-mail'),
9
9
  role: z.nativeEnum(Role).optional().describe('Filtra por role'),
10
10
  });
11
11
 
12
- export class FindUsersQueryDto extends createZodDto(findUsersQuerySchema) { }
12
+ export class FindUsersQueryDto extends createZodDto(findUsersQuerySchema) { }
@@ -57,9 +57,9 @@ export class UsersController {
57
57
  @Permissions(Permission.UserCreate)
58
58
  // nestforge:feature:rbac:end
59
59
  // nestforge:feature:swagger
60
- @ApiOperation({ summary: 'Cria um usuário (requer permissão user:create)' })
61
- @ApiResponse({ status: 201, description: 'Usuário criado', schema: { example: USER_EXAMPLE } })
62
- @ApiResponse({ status: 403, description: 'Sem a permissão user:create', schema: { example: FORBIDDEN_EXAMPLE } })
60
+ @ApiOperation({ summary: 'Creates a user (requires the user:create permission)' })
61
+ @ApiResponse({ status: 201, description: 'User created', schema: { example: USER_EXAMPLE } })
62
+ @ApiResponse({ status: 403, description: 'Missing the user:create permission', schema: { example: FORBIDDEN_EXAMPLE } })
63
63
  // nestforge:feature:swagger:end
64
64
  create(@Body() dto: CreateUserDto) {
65
65
  return this.usersService.create(dto);
@@ -70,10 +70,10 @@ export class UsersController {
70
70
  @Permissions(Permission.UserRead)
71
71
  // nestforge:feature:rbac:end
72
72
  // nestforge:feature:swagger
73
- @ApiOperation({ summary: 'Lista usuários com paginação e filtros (requer permissão user:read)' })
73
+ @ApiOperation({ summary: 'Lists users with pagination and filters (requires the user:read permission)' })
74
74
  @ApiResponse({
75
75
  status: 200,
76
- description: 'Lista paginada',
76
+ description: 'Paginated list',
77
77
  schema: {
78
78
  example: {
79
79
  data: [USER_EXAMPLE],
@@ -88,8 +88,8 @@ export class UsersController {
88
88
 
89
89
  @Get('me')
90
90
  // nestforge:feature:swagger
91
- @ApiOperation({ summary: 'Retorna o usuário autenticado' })
92
- @ApiResponse({ status: 200, description: 'Usuário autenticado', schema: { example: USER_EXAMPLE } })
91
+ @ApiOperation({ summary: 'Returns the authenticated user' })
92
+ @ApiResponse({ status: 200, description: 'Authenticated user', schema: { example: USER_EXAMPLE } })
93
93
  // nestforge:feature:swagger:end
94
94
  findMe(@CurrentUser() user: { id: string }) {
95
95
  return this.usersService.findOne(user.id);
@@ -97,17 +97,17 @@ export class UsersController {
97
97
 
98
98
  @Post('me/avatar')
99
99
  // nestforge:feature:swagger
100
- @ApiOperation({ summary: 'Faz upload do avatar do usuário autenticado' })
100
+ @ApiOperation({ summary: 'Uploads an avatar for the authenticated user' })
101
101
  @ApiConsumes('multipart/form-data')
102
102
  @ApiResponse({
103
103
  status: 201,
104
- description: 'Avatar atualizado',
104
+ description: 'Avatar updated',
105
105
  schema: { example: { ...USER_EXAMPLE, avatarUrl: '/uploads/avatars/f47ac10b.png' } },
106
106
  })
107
107
  @ApiResponse({
108
108
  status: 400,
109
- description: 'Formato de imagem não suportado ou arquivo maior que 2MB',
110
- schema: { example: { statusCode: 400, message: 'Formato de imagem não suportado (use PNG, JPEG ou WEBP)' } },
109
+ description: 'Unsupported image format or file larger than 2 MB',
110
+ schema: { example: { statusCode: 400, message: 'Unsupported image format (use PNG, JPEG, or WEBP)' } },
111
111
  })
112
112
  // nestforge:feature:swagger:end
113
113
  @UseInterceptors(
@@ -129,9 +129,9 @@ export class UsersController {
129
129
  @Permissions(Permission.UserRead)
130
130
  // nestforge:feature:rbac:end
131
131
  // nestforge:feature:swagger
132
- @ApiOperation({ summary: 'Busca um usuário por id (requer permissão user:read)' })
133
- @ApiResponse({ status: 200, description: 'Usuário encontrado', schema: { example: USER_EXAMPLE } })
134
- @ApiResponse({ status: 404, description: 'Usuário não encontrado', schema: { example: { statusCode: 404, message: 'Usuário não encontrado' } } })
132
+ @ApiOperation({ summary: 'Finds a user by ID (requires the user:read permission)' })
133
+ @ApiResponse({ status: 200, description: 'User found', schema: { example: USER_EXAMPLE } })
134
+ @ApiResponse({ status: 404, description: 'User not found', schema: { example: { statusCode: 404, message: 'User not found' } } })
135
135
  // nestforge:feature:swagger:end
136
136
  findOne(@Param('id') id: string) {
137
137
  return this.usersService.findOne(id);
@@ -142,9 +142,9 @@ export class UsersController {
142
142
  @Permissions(Permission.UserUpdate)
143
143
  // nestforge:feature:rbac:end
144
144
  // nestforge:feature:swagger
145
- @ApiOperation({ summary: 'Atualiza um usuário (requer permissão user:update)' })
146
- @ApiResponse({ status: 200, description: 'Usuário atualizado', schema: { example: USER_EXAMPLE } })
147
- @ApiResponse({ status: 403, description: 'Sem a permissão user:update', schema: { example: FORBIDDEN_EXAMPLE } })
145
+ @ApiOperation({ summary: 'Updates a user (requires the user:update permission)' })
146
+ @ApiResponse({ status: 200, description: 'User updated', schema: { example: USER_EXAMPLE } })
147
+ @ApiResponse({ status: 403, description: 'Missing the user:update permission', schema: { example: FORBIDDEN_EXAMPLE } })
148
148
  // nestforge:feature:swagger:end
149
149
  update(@Param('id') id: string, @Body() dto: UpdateUserDto) {
150
150
  return this.usersService.update(id, dto);
@@ -155,11 +155,11 @@ export class UsersController {
155
155
  @Permissions(Permission.UserDelete)
156
156
  // nestforge:feature:rbac:end
157
157
  // nestforge:feature:swagger
158
- @ApiOperation({ summary: 'Remove um usuário (requer permissão user:delete)' })
159
- @ApiResponse({ status: 200, description: 'Usuário removido', schema: { example: { message: 'Usuário removido com sucesso' } } })
160
- @ApiResponse({ status: 403, description: 'Sem a permissão user:delete', schema: { example: FORBIDDEN_EXAMPLE } })
158
+ @ApiOperation({ summary: 'Deletes a user (requires the user:delete permission)' })
159
+ @ApiResponse({ status: 200, description: 'User deleted', schema: { example: { message: 'User deleted successfully' } } })
160
+ @ApiResponse({ status: 403, description: 'Missing the user:delete permission', schema: { example: FORBIDDEN_EXAMPLE } })
161
161
  // nestforge:feature:swagger:end
162
162
  remove(@Param('id') id: string) {
163
163
  return this.usersService.remove(id);
164
164
  }
165
- }
165
+ }
@@ -49,19 +49,19 @@ describe('UsersService', () => {
49
49
  );
50
50
  });
51
51
 
52
- it('deve lançar ConflictException se o e-mail já existir ao criar', async () => {
52
+ it('throws ConflictException when the email already exists during creation', async () => {
53
53
  usersRepository.findOne.mockResolvedValue(mockUser);
54
54
 
55
55
  await expect(
56
56
  usersService.create({
57
57
  name: 'Jeiel',
58
58
  email: 'jeiel@example.com',
59
- password: 'senhaForte123',
59
+ password: 'strongPassword123',
60
60
  }),
61
61
  ).rejects.toBeInstanceOf(ConflictException);
62
62
  });
63
63
 
64
- it('deve criar um usuário e esconder o passwordHash na serialização', async () => {
64
+ it('creates a user and hides passwordHash during serialization', async () => {
65
65
  usersRepository.findOne.mockResolvedValue(null);
66
66
  usersRepository.create.mockReturnValue(mockUser);
67
67
  usersRepository.save.mockResolvedValue(mockUser);
@@ -69,7 +69,7 @@ describe('UsersService', () => {
69
69
  const result = await usersService.create({
70
70
  name: 'Jeiel',
71
71
  email: 'jeiel@example.com',
72
- password: 'senhaForte123',
72
+ password: 'strongPassword123',
73
73
  });
74
74
 
75
75
  expect(result.email).toBe('jeiel@example.com');
@@ -78,7 +78,7 @@ describe('UsersService', () => {
78
78
  expect(usersRepository.save).toHaveBeenCalledWith(mockUser);
79
79
  });
80
80
 
81
- it('deve lançar NotFoundException se o usuário não existir', async () => {
81
+ it('throws NotFoundException when the user does not exist', async () => {
82
82
  usersRepository.findOne.mockResolvedValue(null);
83
83
 
84
84
  await expect(
@@ -86,7 +86,7 @@ describe('UsersService', () => {
86
86
  ).rejects.toBeInstanceOf(NotFoundException);
87
87
  });
88
88
 
89
- it('deve retornar dados paginados em findAll', async () => {
89
+ it('returns paginated data from findAll', async () => {
90
90
  queryBuilder.getManyAndCount.mockResolvedValue([[mockUser], 1]);
91
91
 
92
92
  const result = await usersService.findAll({
@@ -105,7 +105,7 @@ describe('UsersService', () => {
105
105
  expect(queryBuilder.take).toHaveBeenCalledWith(10);
106
106
  });
107
107
 
108
- it('deve aplicar busca e filtro por role em findAll', async () => {
108
+ it('applies search and role filters in findAll', async () => {
109
109
  queryBuilder.getManyAndCount.mockResolvedValue([[mockUser], 1]);
110
110
 
111
111
  await usersService.findAll({
@@ -126,7 +126,7 @@ describe('UsersService', () => {
126
126
  );
127
127
  });
128
128
 
129
- it('deve atualizar um usuário existente', async () => {
129
+ it('updates an existing user', async () => {
130
130
  usersRepository.findOne.mockResolvedValue(mockUser);
131
131
  usersRepository.save.mockImplementation(
132
132
  async (user: UserEntity) => user,
@@ -147,7 +147,7 @@ describe('UsersService', () => {
147
147
  );
148
148
  });
149
149
 
150
- it('deve remover um usuário existente', async () => {
150
+ it('deletes an existing user', async () => {
151
151
  usersRepository.findOne.mockResolvedValue(mockUser);
152
152
  usersRepository.remove.mockResolvedValue(mockUser);
153
153
 
@@ -155,11 +155,11 @@ describe('UsersService', () => {
155
155
 
156
156
  expect(usersRepository.remove).toHaveBeenCalledWith(mockUser);
157
157
  expect(result).toEqual({
158
- message: 'Usuário removido com sucesso',
158
+ message: 'User deleted successfully',
159
159
  });
160
160
  });
161
161
 
162
- it('deve atualizar o avatar de um usuário', async () => {
162
+ it('updates a user avatar', async () => {
163
163
  usersRepository.findOne.mockResolvedValue(mockUser);
164
164
  usersRepository.save.mockImplementation(
165
165
  async (user: UserEntity) => user,
@@ -180,4 +180,4 @@ describe('UsersService', () => {
180
180
  }),
181
181
  );
182
182
  });
183
- });
183
+ });
@@ -24,7 +24,7 @@ export class UsersService {
24
24
  });
25
25
 
26
26
  if (existing) {
27
- throw new ConflictException('E-mail já cadastrado');
27
+ throw new ConflictException('Email already registered');
28
28
  }
29
29
 
30
30
  const passwordHash = await bcrypt.hash(dto.password, 10);
@@ -83,7 +83,7 @@ export class UsersService {
83
83
  });
84
84
 
85
85
  if (!user) {
86
- throw new NotFoundException('Usuário não encontrado');
86
+ throw new NotFoundException('User not found');
87
87
  }
88
88
 
89
89
  return new UserEntity(user);
@@ -109,7 +109,7 @@ export class UsersService {
109
109
 
110
110
  await this.usersRepository.remove(user);
111
111
 
112
- return { message: 'Usuário removido com sucesso' };
112
+ return { message: 'User deleted successfully' };
113
113
  }
114
114
 
115
115
  async updateAvatar(id: string, avatarUrl: string) {
@@ -121,4 +121,4 @@ export class UsersService {
121
121
 
122
122
  return new UserEntity(updatedUser);
123
123
  }
124
- }
124
+ }
@@ -22,7 +22,7 @@ describe('Auth (e2e)', () => {
22
22
  await app.close();
23
23
  });
24
24
 
25
- it('deve registrar, logar, renovar e revogar o token', async () => {
25
+ it('registers, logs in, refreshes, and revokes the token', async () => {
26
26
  const server = app.getHttpServer();
27
27
 
28
28
  const registerResponse = await request(server)
@@ -30,7 +30,7 @@ describe('Auth (e2e)', () => {
30
30
  .send({
31
31
  name: 'Jeiel',
32
32
  email: 'jeiel.e2e@example.com',
33
- password: 'senhaForte123',
33
+ password: 'strongPassword123',
34
34
  })
35
35
  .expect(201);
36
36
 
@@ -46,7 +46,7 @@ describe('Auth (e2e)', () => {
46
46
  .post('/auth/login')
47
47
  .send({
48
48
  email: 'jeiel.e2e@example.com',
49
- password: 'senhaForte123',
49
+ password: 'strongPassword123',
50
50
  })
51
51
  .expect(200);
52
52
 
@@ -79,13 +79,13 @@ describe('Auth (e2e)', () => {
79
79
  .expect(401);
80
80
  });
81
81
 
82
- it('não deve permitir cadastro com e-mail duplicado', async () => {
82
+ it('rejects registration with a duplicate email', async () => {
83
83
  const server = app.getHttpServer();
84
84
 
85
85
  const payload = {
86
86
  name: 'Jeiel',
87
- email: 'duplicado.e2e@example.com',
88
- password: 'senhaForte123',
87
+ email: 'duplicate.e2e@example.com',
88
+ password: 'strongPassword123',
89
89
  };
90
90
 
91
91
  await request(server)
@@ -99,7 +99,7 @@ describe('Auth (e2e)', () => {
99
99
  .expect(409);
100
100
  });
101
101
 
102
- it('deve rejeitar login com credenciais inválidas', async () => {
102
+ it('rejects login with invalid credentials', async () => {
103
103
  await request(app.getHttpServer())
104
104
  .post('/auth/login')
105
105
  .send({
@@ -108,4 +108,4 @@ describe('Auth (e2e)', () => {
108
108
  })
109
109
  .expect(401);
110
110
  });
111
- });
111
+ });
@@ -24,7 +24,7 @@ describe('Session auth (e2e)', () => {
24
24
  }
25
25
  });
26
26
 
27
- it('registra, autentica e encerra uma sessão protegida por CSRF', async () => {
27
+ it('registers, authenticates, and closes a CSRF-protected session', async () => {
28
28
  const agent = request.agent(app.getHttpServer());
29
29
 
30
30
  await agent
@@ -39,13 +39,13 @@ describe('Session auth (e2e)', () => {
39
39
 
40
40
  expect(csrfToken).toMatch(/^[a-f0-9]{64}$/);
41
41
 
42
- // Requisições que alteram estado devem ser rejeitadas sem o token.
42
+ // State-changing requests must be rejected without the token.
43
43
  await agent
44
44
  .post('/auth/register')
45
45
  .send({
46
46
  name: 'Jeiel',
47
47
  email: 'jeiel.session@example.com',
48
- password: 'senhaForte123',
48
+ password: 'strongPassword123',
49
49
  })
50
50
  .expect(403);
51
51
 
@@ -55,7 +55,7 @@ describe('Session auth (e2e)', () => {
55
55
  .send({
56
56
  name: 'Jeiel',
57
57
  email: 'jeiel.session@example.com',
58
- password: 'senhaForte123',
58
+ password: 'strongPassword123',
59
59
  })
60
60
  .expect(201);
61
61
 
@@ -93,7 +93,7 @@ describe('Session auth (e2e)', () => {
93
93
  .expect(401);
94
94
  });
95
95
 
96
- it('realiza login e renova o token CSRF da sessão', async () => {
96
+ it('logs in and refreshes the session CSRF token', async () => {
97
97
  const registrationAgent = request.agent(
98
98
  app.getHttpServer(),
99
99
  );
@@ -109,9 +109,9 @@ describe('Session auth (e2e)', () => {
109
109
  .post('/auth/register')
110
110
  .set('x-csrf-token', registrationCsrfToken)
111
111
  .send({
112
- name: 'Usuário de sessão',
112
+ name: 'Session User',
113
113
  email: 'login.session@example.com',
114
- password: 'senhaForte123',
114
+ password: 'strongPassword123',
115
115
  })
116
116
  .expect(201);
117
117
 
@@ -137,7 +137,7 @@ describe('Session auth (e2e)', () => {
137
137
  .set('x-csrf-token', loginCsrfToken)
138
138
  .send({
139
139
  email: 'login.session@example.com',
140
- password: 'senhaForte123',
140
+ password: 'strongPassword123',
141
141
  })
142
142
  .expect(200);
143
143
 
@@ -156,4 +156,4 @@ describe('Session auth (e2e)', () => {
156
156
  .get('/users/me')
157
157
  .expect(200);
158
158
  });
159
- });
159
+ });
@@ -27,7 +27,7 @@ describe('Users (e2e)', () => {
27
27
  );
28
28
 
29
29
  const user = usersRepository.create({
30
- name: 'Usuário de teste',
30
+ name: 'Test User',
31
31
  email,
32
32
  passwordHash,
33
33
  role,
@@ -66,22 +66,22 @@ describe('Users (e2e)', () => {
66
66
  await app.close();
67
67
  });
68
68
 
69
- it('rejeita acesso sem token', async () => {
69
+ it('rejects access without a token', async () => {
70
70
  await request(app.getHttpServer())
71
71
  .get('/users')
72
72
  .expect(401);
73
73
  });
74
74
 
75
- it('ADMIN consegue criar, listar, atualizar e remover um usuário', async () => {
75
+ it('allows ADMIN to create, list, update, and delete a user', async () => {
76
76
  await createUserWithRole(
77
77
  'admin.e2e@example.com',
78
- 'senhaForte123',
78
+ 'strongPassword123',
79
79
  Role.ADMIN,
80
80
  );
81
81
 
82
82
  const token = await loginAndGetToken(
83
83
  'admin.e2e@example.com',
84
- 'senhaForte123',
84
+ 'strongPassword123',
85
85
  );
86
86
 
87
87
  const server = app.getHttpServer();
@@ -90,9 +90,9 @@ describe('Users (e2e)', () => {
90
90
  .post('/users')
91
91
  .set('Authorization', `Bearer ${token}`)
92
92
  .send({
93
- name: 'Novo Usuário',
94
- email: 'novo.e2e@example.com',
95
- password: 'senhaForte123',
93
+ name: 'New User',
94
+ email: 'new.e2e@example.com',
95
+ password: 'strongPassword123',
96
96
  })
97
97
  .expect(201);
98
98
 
@@ -126,16 +126,16 @@ describe('Users (e2e)', () => {
126
126
  });
127
127
 
128
128
  // nestforge:feature:rbac
129
- it('USER consegue ler mas não consegue criar usuário', async () => {
129
+ it('allows USER to read but not create users', async () => {
130
130
  await createUserWithRole(
131
131
  'user.e2e@example.com',
132
- 'senhaForte123',
132
+ 'strongPassword123',
133
133
  Role.USER,
134
134
  );
135
135
 
136
136
  const token = await loginAndGetToken(
137
137
  'user.e2e@example.com',
138
- 'senhaForte123',
138
+ 'strongPassword123',
139
139
  );
140
140
 
141
141
  const server = app.getHttpServer();
@@ -149,24 +149,24 @@ describe('Users (e2e)', () => {
149
149
  .post('/users')
150
150
  .set('Authorization', `Bearer ${token}`)
151
151
  .send({
152
- name: 'Não deveria criar',
153
- email: 'bloqueado.e2e@example.com',
154
- password: 'senhaForte123',
152
+ name: 'Should Not Be Created',
153
+ email: 'blocked.e2e@example.com',
154
+ password: 'strongPassword123',
155
155
  })
156
156
  .expect(403);
157
157
  });
158
158
  // nestforge:feature:rbac:end
159
159
 
160
- it('GET /users/me retorna o usuário autenticado', async () => {
160
+ it('returns the authenticated user from GET /users/me', async () => {
161
161
  await createUserWithRole(
162
162
  'me.e2e@example.com',
163
- 'senhaForte123',
163
+ 'strongPassword123',
164
164
  Role.USER,
165
165
  );
166
166
 
167
167
  const token = await loginAndGetToken(
168
168
  'me.e2e@example.com',
169
- 'senhaForte123',
169
+ 'strongPassword123',
170
170
  );
171
171
 
172
172
  const response = await request(
@@ -180,4 +180,4 @@ describe('Users (e2e)', () => {
180
180
  'me.e2e@example.com',
181
181
  );
182
182
  });
183
- });
183
+ });