@koalarx/nest 1.16.2 → 1.17.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
CHANGED
|
@@ -4,333 +4,388 @@
|
|
|
4
4
|
|
|
5
5
|
<h1 align="center">@koalarx/nest</h1>
|
|
6
6
|
|
|
7
|
-
<p align="center">Uma abstração <a href="https://nestjs.com" target="_blank">
|
|
7
|
+
<p align="center">Uma abstração <a href="https://nestjs.com" target="_blank">NestJS</a> robusta para criar APIs escaláveis seguindo os princípios do Domain-Driven Design (DDD).</p>
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
1. [Introdução](#introdução)
|
|
11
|
-
2. [Estrutura do Projeto](#estrutura-do-projeto)
|
|
12
|
-
3. [Uso da CLI @koalarx/nest-cli](#uso-da-cli-koalarxnest-cli)
|
|
13
|
-
4. [Recursos Optionais](#recursos-opcionais)
|
|
9
|
+
<div align="center">
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
[](https://opensource.org/licenses/MIT)
|
|
12
|
+
[](https://nodejs.org/)
|
|
13
|
+
[](https://www.typescriptlang.org/)
|
|
14
|
+
[](https://www.npmjs.com/package/@koalarx/nest-cli)
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
</div>
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
## Documentação Completa
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
Toda a documentação está organizada em arquivos separados para facilitar a navegação:
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
| Documento | Descrição |
|
|
23
|
+
|-----------|-----------|
|
|
24
|
+
| [**CLI Reference**](./docs/00-cli-reference.md) | Guia da CLI oficial - Forma rápida de criar projetos |
|
|
25
|
+
| [**Guia de Instalação**](./docs/01-guia-instalacao.md) | Como instalar e configurar a biblioteca |
|
|
26
|
+
| [**Configuração Inicial**](./docs/02-configuracao-inicial.md) | Setup do projeto com KoalaNestModule e KoalaApp |
|
|
27
|
+
| [**Exemplo Prático**](./docs/03-exemplo-pratico.md) | Criar uma API completa de usuários passo a passo |
|
|
28
|
+
| [**Tratamento de Erros**](./docs/04-tratamento-erros.md) | Sistema robusto de tratamento e filtros de exceção |
|
|
29
|
+
| [**Features Avançadas**](./docs/05-features-avancadas.md) | Cron Jobs, Event Handlers, Guards, Redis, Transações |
|
|
30
|
+
| [**Decoradores**](./docs/06-decoradores.md) | @IsPublic, @Upload, @Cookies e mais |
|
|
24
31
|
|
|
25
|
-
##
|
|
32
|
+
## Quick Start
|
|
26
33
|
|
|
27
|
-
|
|
34
|
+
### Forma Rápida com CLI (Recomendado)
|
|
28
35
|
|
|
29
|
-
|
|
36
|
+
```bash
|
|
37
|
+
# Instalar a CLI globalmente
|
|
38
|
+
npm install -g @koalarx/nest-cli
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
# Criar novo projeto estruturado
|
|
41
|
+
koala-nest new meu-projeto
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
# Entrar na pasta
|
|
44
|
+
cd meu-projeto
|
|
34
45
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- **host**: Controladores e ponto de entrada da aplicação.
|
|
39
|
-
- **infra**: Implementações de infraestrutura, como banco de dados e serviços externos.
|
|
46
|
+
# Iniciar em modo desenvolvimento
|
|
47
|
+
npm run start:dev
|
|
48
|
+
```
|
|
40
49
|
|
|
41
|
-
|
|
50
|
+
**Pronto!** Seu projeto está estruturado com:
|
|
51
|
+
- [x] Módulo DDD configurado
|
|
52
|
+
- [x] Documentação da API (Scalar UI)
|
|
53
|
+
- [x] Tratamento de erros robusto
|
|
54
|
+
- [x] Autenticação JWT
|
|
55
|
+
- [x] Banco de dados Prisma
|
|
56
|
+
- [x] Redis para background services
|
|
42
57
|
|
|
43
|
-
|
|
58
|
+
### Forma Manual
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
```bash
|
|
61
|
+
npm install @koalarx/nest
|
|
62
|
+
```
|
|
46
63
|
|
|
47
|
-
|
|
64
|
+
### 2. Criar Módulo Principal
|
|
48
65
|
|
|
49
|
-
```
|
|
50
|
-
|
|
66
|
+
```typescript
|
|
67
|
+
// src/host/app.module.ts
|
|
68
|
+
import { KoalaNestModule } from '@koalarx/nest/core/koala-nest.module'
|
|
69
|
+
import { Module } from '@nestjs/common'
|
|
70
|
+
import { env } from '../core/env'
|
|
71
|
+
import { UserModule } from './controllers/user/user.module'
|
|
72
|
+
|
|
73
|
+
@Module({
|
|
74
|
+
imports: [
|
|
75
|
+
KoalaNestModule.register({
|
|
76
|
+
env,
|
|
77
|
+
controllers: [UserModule],
|
|
78
|
+
}),
|
|
79
|
+
],
|
|
80
|
+
})
|
|
81
|
+
export class AppModule {}
|
|
51
82
|
```
|
|
52
83
|
|
|
53
|
-
###
|
|
84
|
+
### 3. Inicializar Aplicação
|
|
54
85
|
|
|
55
|
-
|
|
86
|
+
```typescript
|
|
87
|
+
// src/main.ts
|
|
88
|
+
import 'dotenv/config'
|
|
89
|
+
import { NestFactory } from '@nestjs/core'
|
|
90
|
+
import { KoalaApp } from '@koalarx/nest/core/koala-app'
|
|
91
|
+
import { AppModule } from './host/app.module'
|
|
92
|
+
|
|
93
|
+
async function bootstrap() {
|
|
94
|
+
const app = await NestFactory.create(AppModule)
|
|
95
|
+
|
|
96
|
+
await new KoalaApp(app)
|
|
97
|
+
.useDoc({
|
|
98
|
+
ui: 'scalar',
|
|
99
|
+
endpoint: '/doc',
|
|
100
|
+
title: 'Minha API',
|
|
101
|
+
version: '1.0.0',
|
|
102
|
+
})
|
|
103
|
+
.enableCors()
|
|
104
|
+
.buildAndServe()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
bootstrap()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 4. Executar
|
|
56
111
|
|
|
57
112
|
```bash
|
|
58
|
-
|
|
113
|
+
npm run start:dev
|
|
59
114
|
```
|
|
60
115
|
|
|
61
|
-
|
|
116
|
+
Acesse `http://localhost:3000/doc` para a documentação interativa!
|
|
62
117
|
|
|
63
|
-
|
|
118
|
+
## Principais Features
|
|
64
119
|
|
|
65
|
-
|
|
120
|
+
### Segurança
|
|
66
121
|
|
|
67
|
-
|
|
122
|
+
- **Guards Globais**: Proteja endpoints com autenticação
|
|
123
|
+
- **API Key Strategy**: Autenticação via chave de API integrada
|
|
124
|
+
- **@IsPublic()**: Marca endpoints como públicos
|
|
68
125
|
|
|
69
|
-
|
|
126
|
+
### Tratamento de Erros
|
|
70
127
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
├── guards
|
|
77
|
-
│ └── auth.guard.ts
|
|
78
|
-
└── security.module.ts
|
|
79
|
-
```
|
|
128
|
+
Filtros automáticos para:
|
|
129
|
+
- **Domain Errors** (ConflictError, ResourceNotFoundError, etc)
|
|
130
|
+
- **Prisma Validation** (validação de banco de dados)
|
|
131
|
+
- **Zod Validation** (validação de dados de entrada)
|
|
132
|
+
- **Global Exceptions** (erros não capturados)
|
|
80
133
|
|
|
81
|
-
|
|
134
|
+
```typescript
|
|
135
|
+
throw new ConflictError('Email já registrado') // 409
|
|
136
|
+
throw new ResourceNotFoundError('Usuário não encontrado') // 404
|
|
137
|
+
throw new BadRequestError('Dados inválidos') // 400
|
|
138
|
+
```
|
|
82
139
|
|
|
83
|
-
|
|
84
|
-
```ts
|
|
85
|
-
import {
|
|
86
|
-
DoneFn,
|
|
87
|
-
ApiKeyStrategy as KoalaApiKeyStrategy,
|
|
88
|
-
} from '@koalarx/nest/core/security/strategies/api-key.strategy'
|
|
89
|
-
import { Injectable } from '@nestjs/common'
|
|
90
|
-
import { PassportStrategy } from '@nestjs/passport'
|
|
91
|
-
import { Request } from 'express'
|
|
140
|
+
### Processamento em Background
|
|
92
141
|
|
|
142
|
+
**Cron Jobs** - Execute tarefas agendadas:
|
|
143
|
+
```typescript
|
|
93
144
|
@Injectable()
|
|
94
|
-
export class
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
) {
|
|
98
|
-
constructor() {
|
|
99
|
-
super({ header: 'ApiKey' })
|
|
145
|
+
export class SendReportJob extends CronJobHandlerBase {
|
|
146
|
+
protected async settings() {
|
|
147
|
+
return { isActive: true, timeInMinutes: 1440 }
|
|
100
148
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// Por exemplo, verifique se ela corresponde a um valor específico
|
|
105
|
-
if (apikey === 'valid-api-key') {
|
|
106
|
-
// Se for válida, chame done com o objeto do usuário
|
|
107
|
-
return done(null, { userId: 1, username: 'testuser' })
|
|
108
|
-
} else {
|
|
109
|
-
// Se for inválida, chame done com false
|
|
110
|
-
return done(null, false)
|
|
111
|
-
}
|
|
149
|
+
protected async run(): Promise<CronJobResponse> {
|
|
150
|
+
await emailService.sendReport()
|
|
151
|
+
return ok(null)
|
|
112
152
|
}
|
|
113
153
|
}
|
|
114
|
-
```
|
|
115
154
|
|
|
116
|
-
|
|
117
|
-
```
|
|
118
|
-
import { IS_PUBLIC_KEY } from '@koalarx/nest/decorators/is-public.decorator'
|
|
119
|
-
import { ExecutionContext, Injectable } from '@nestjs/common'
|
|
120
|
-
import { Reflector } from '@nestjs/core'
|
|
121
|
-
import { AuthGuard as NestAuthGuard } from '@nestjs/passport'
|
|
155
|
+
.addCronJob(SendReportJob)
|
|
156
|
+
```
|
|
122
157
|
|
|
158
|
+
**Event Handlers** - Processe eventos assincronamente:
|
|
159
|
+
```typescript
|
|
123
160
|
@Injectable()
|
|
124
|
-
export class
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
161
|
+
export class UserCreatedHandler extends EventHandlerBase {
|
|
162
|
+
get eventName(): string { return 'user:created' }
|
|
163
|
+
async handle(data: any): Promise<void> { /* sua lógica */ }
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.addEventJob(UserCreatedHandler)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Banco de Dados
|
|
128
170
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
context.getClass(),
|
|
133
|
-
])
|
|
171
|
+
- **Prisma ORM** com suporte a todos os drivers (PostgreSQL, MySQL, SQLite, MariaDB, SQL Server, MongoDB)
|
|
172
|
+
- **Transações Automáticas** com context gerenciado
|
|
173
|
+
- **Query Logging** em desenvolvimento
|
|
134
174
|
|
|
135
|
-
|
|
175
|
+
### Documentação
|
|
136
176
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
177
|
+
Dois UIs disponíveis:
|
|
178
|
+
- **Scalar** - Interface moderna e interativa
|
|
179
|
+
- **Swagger UI** - Documentação clássica
|
|
140
180
|
|
|
141
|
-
|
|
181
|
+
```typescript
|
|
182
|
+
.useDoc({
|
|
183
|
+
ui: 'scalar', // ou 'swagger'
|
|
184
|
+
endpoint: '/doc',
|
|
185
|
+
title: 'API Documentation',
|
|
186
|
+
version: '1.0.0',
|
|
187
|
+
})
|
|
188
|
+
```
|
|
142
189
|
|
|
143
|
-
|
|
144
|
-
return canActivate
|
|
145
|
-
}
|
|
190
|
+
### Funcionalidades Adicionais
|
|
146
191
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
192
|
+
- **Redis Integration** - Sincronização de Cron Jobs e Event Handlers (RedLock)
|
|
193
|
+
- **CORS** - Requisições cross-origin
|
|
194
|
+
- **Zod Validation** - Validação de dados com tipos
|
|
195
|
+
- **Ngrok** - Exposição segura em desenvolvimento
|
|
196
|
+
- **Decoradores Customizados** - @Upload, @Cookies, @ApiPropertyEnum
|
|
150
197
|
|
|
151
|
-
|
|
152
|
-
request.user = user
|
|
153
|
-
}
|
|
154
|
-
}
|
|
198
|
+
## Exemplo Completo
|
|
155
199
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
200
|
+
Veja como criar um CRUD de usuários:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// src/domain/entities/user.entity.ts
|
|
204
|
+
export interface UserEntity {
|
|
205
|
+
id: string
|
|
206
|
+
name: string
|
|
207
|
+
email: string
|
|
208
|
+
createdAt: Date
|
|
159
209
|
}
|
|
160
210
|
```
|
|
161
211
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
import {
|
|
165
|
-
import { Module } from '@nestjs/common'
|
|
166
|
-
import { PassportModule } from '@nestjs/passport'
|
|
167
|
-
import { ApiKeyStrategy } from './strategies/api-key.strategy'
|
|
212
|
+
```typescript
|
|
213
|
+
// src/domain/dtos/create-user.dto.ts
|
|
214
|
+
import { z } from 'zod'
|
|
168
215
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
216
|
+
export const CreateUserSchema = z.object({
|
|
217
|
+
name: z.string().min(1),
|
|
218
|
+
email: z.string().email(),
|
|
172
219
|
})
|
|
173
|
-
|
|
220
|
+
|
|
221
|
+
export type CreateUserDto = z.infer<typeof CreateUserSchema>
|
|
174
222
|
```
|
|
175
223
|
|
|
176
|
-
|
|
224
|
+
```typescript
|
|
225
|
+
// src/domain/services/user.service.ts
|
|
226
|
+
import { Injectable } from '@nestjs/common'
|
|
227
|
+
import { ConflictError } from '@koalarx/nest/core/errors/conflict.error'
|
|
228
|
+
import { ResourceNotFoundError } from '@koalarx/nest/core/errors/resource-not-found.error'
|
|
177
229
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
230
|
+
@Injectable()
|
|
231
|
+
export class UserService {
|
|
232
|
+
constructor(private readonly repository: IUserRepository) {}
|
|
233
|
+
|
|
234
|
+
async create(data: CreateUserDto): Promise<UserEntity> {
|
|
235
|
+
const exists = await this.repository.findByEmail(data.email)
|
|
236
|
+
if (exists) throw new ConflictError('Email já registrado')
|
|
237
|
+
|
|
238
|
+
return this.repository.create(data)
|
|
239
|
+
}
|
|
188
240
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
export class AppModule {}
|
|
241
|
+
async findById(id: string): Promise<UserEntity> {
|
|
242
|
+
const user = await this.repository.findById(id)
|
|
243
|
+
if (!user) throw new ResourceNotFoundError('Usuário não encontrado')
|
|
244
|
+
return user
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
async delete(id: string): Promise<void> {
|
|
248
|
+
await this.findById(id) // Valida existência
|
|
249
|
+
await this.repository.delete(id)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
201
252
|
```
|
|
202
253
|
|
|
203
|
-
|
|
254
|
+
```typescript
|
|
255
|
+
// src/host/controllers/user/user.controller.ts
|
|
256
|
+
import { Controller, Get, Post, Delete, Body, Param } from '@nestjs/common'
|
|
257
|
+
import { ApiTags, ApiCreatedResponse } from '@nestjs/swagger'
|
|
258
|
+
import { IsPublic } from '@koalarx/nest/decorators/is-public.decorator'
|
|
259
|
+
|
|
260
|
+
@ApiTags('Users')
|
|
261
|
+
@Controller('users')
|
|
262
|
+
export class UserController {
|
|
263
|
+
constructor(private readonly service: UserService) {}
|
|
264
|
+
|
|
265
|
+
@Post()
|
|
266
|
+
@IsPublic()
|
|
267
|
+
@ApiCreatedResponse({ type: UserResponseDto })
|
|
268
|
+
async create(@Body() data: CreateUserRequestDto) {
|
|
269
|
+
const validated = CreateUserSchema.parse(data)
|
|
270
|
+
return this.service.create(validated)
|
|
271
|
+
}
|
|
204
272
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
import { InactivePersonHandler } from '@/application/person/events/inactive-person/inactive-person-handler'
|
|
210
|
-
import { DbTransactionContext } from '@/infra/database/db-transaction-context'
|
|
211
|
-
import { KoalaApp } from '@koalarx/nest/core/koala-app'
|
|
212
|
-
import { NestFactory } from '@nestjs/core'
|
|
213
|
-
import { AppModule } from './app.module'
|
|
214
|
-
import { AuthGuard } from './security/guards/auth.guard'
|
|
273
|
+
@Get(':id')
|
|
274
|
+
async findOne(@Param('id') id: string) {
|
|
275
|
+
return this.service.findById(id)
|
|
276
|
+
}
|
|
215
277
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
ui: 'scalar',
|
|
221
|
-
endpoint: '/doc',
|
|
222
|
-
title: 'API de Demonstração',
|
|
223
|
-
version: '1.0',
|
|
224
|
-
authorizations: [
|
|
225
|
-
{ name: 'ApiKey', config: { type: 'apiKey', name: 'ApiKey' } },
|
|
226
|
-
],
|
|
227
|
-
})
|
|
228
|
-
.addGlobalGuard(AuthGuard)
|
|
229
|
-
.addCronJob(CreatePersonJob)
|
|
230
|
-
.addCronJob(DeleteInactiveJob)
|
|
231
|
-
.addEventJob(InactivePersonHandler)
|
|
232
|
-
.setAppName('example')
|
|
233
|
-
.setInternalUserName('integration.bot')
|
|
234
|
-
.setDbTransactionContext(DbTransactionContext)
|
|
235
|
-
.enableCors()
|
|
236
|
-
.buildAndServe(),
|
|
237
|
-
)
|
|
278
|
+
@Delete(':id')
|
|
279
|
+
async delete(@Param('id') id: string) {
|
|
280
|
+
await this.service.delete(id)
|
|
281
|
+
}
|
|
238
282
|
}
|
|
239
|
-
bootstrap()
|
|
240
283
|
```
|
|
241
284
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
[Ngrok](https://ngrok.com) é uma ferramenta que cria túneis seguros para expor servidores locais à internet. Ele é útil para testar webhooks, compartilhar aplicações em desenvolvimento ou acessar serviços locais remotamente.
|
|
285
|
+
Erros são automaticamente transformados em respostas HTTP apropriadas!
|
|
245
286
|
|
|
246
|
-
|
|
287
|
+
## Estrutura de Projeto Recomendada
|
|
247
288
|
|
|
248
|
-
|
|
289
|
+
Seguindo DDD:
|
|
249
290
|
|
|
250
|
-
|
|
291
|
+
```
|
|
292
|
+
src/
|
|
293
|
+
├── application/ # Lógica de aplicação e mapeadores
|
|
294
|
+
├── core/ # Configurações globais
|
|
295
|
+
├── domain/ # Lógica de negócio
|
|
296
|
+
│ ├── entities/
|
|
297
|
+
│ ├── dtos/
|
|
298
|
+
│ ├── repositories/ # Interfaces
|
|
299
|
+
│ └── services/
|
|
300
|
+
├── host/ # Controladores e entrada
|
|
301
|
+
│ ├── controllers/
|
|
302
|
+
│ ├── security/ # Guards e estratégias
|
|
303
|
+
│ └── app.module.ts
|
|
304
|
+
├── infra/ # Implementações de infraestrutura
|
|
305
|
+
│ ├── database/
|
|
306
|
+
│ ├── repositories/ # Implementações
|
|
307
|
+
│ └── services/
|
|
308
|
+
└── main.ts
|
|
309
|
+
```
|
|
251
310
|
|
|
252
|
-
|
|
253
|
-
```ts
|
|
254
|
-
...
|
|
255
|
-
import { KoalaApp } from '@koalarx/nest/core/koala-app'
|
|
256
|
-
import { NestFactory } from '@nestjs/core'
|
|
257
|
-
import { AppModule } from './app.module'
|
|
311
|
+
## Configuração de Ambiente
|
|
258
312
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
.buildAndServe(),
|
|
266
|
-
)
|
|
267
|
-
}
|
|
268
|
-
bootstrap()
|
|
313
|
+
```env
|
|
314
|
+
NODE_ENV=develop
|
|
315
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/db
|
|
316
|
+
REDIS_URL=redis://localhost:6379
|
|
317
|
+
SWAGGER_USERNAME=admin
|
|
318
|
+
SWAGGER_PASSWORD=password123
|
|
269
319
|
```
|
|
270
320
|
|
|
271
|
-
|
|
321
|
+
## Índice da Documentação Original
|
|
272
322
|
|
|
273
|
-
|
|
323
|
+
A documentação abaixo foi mantida para referência de recursos específicos:
|
|
274
324
|
|
|
275
|
-
|
|
325
|
+
### API Key Strategy
|
|
276
326
|
|
|
277
|
-
|
|
278
|
-
- **options.enum** - A enumeração a ser documentada. Deve ser um objeto onde as chaves são os nomes dos enums e os valores são suas representações numéricas.
|
|
279
|
-
- **options.required** - (Opcional) Indica se a propriedade é obrigatória.
|
|
327
|
+
Uma estratégia de autenticação via chave de API integrada ao Passport.js:
|
|
280
328
|
|
|
281
|
-
|
|
329
|
+
[Ver documentação completa →](./docs/01-guia-instalacao.md#api-key-strategy)
|
|
282
330
|
|
|
283
|
-
|
|
284
|
-
import { ApiPropertyEnum } from './decorators/api-property-enum.decorator';
|
|
331
|
+
### Ngrok
|
|
285
332
|
|
|
286
|
-
|
|
287
|
-
Ativo = 1,
|
|
288
|
-
Inativo = 2,
|
|
289
|
-
}
|
|
333
|
+
Exponha sua aplicação local na internet com segurança:
|
|
290
334
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
status: Status;
|
|
294
|
-
}
|
|
335
|
+
```typescript
|
|
336
|
+
.useNgrok(process.env.NGROK_AUTH_TOKEN!)
|
|
295
337
|
```
|
|
296
338
|
|
|
297
|
-
|
|
339
|
+
[Ver documentação completa →](./docs/05-features-avancadas.md#10-ngrok-exposição-em-produção)
|
|
298
340
|
|
|
299
|
-
|
|
300
|
-
Ativo: 1
|
|
301
|
-
Inativo: 2
|
|
302
|
-
```
|
|
341
|
+
### Decoradores
|
|
303
342
|
|
|
304
|
-
|
|
343
|
+
- **@ApiPropertyEnum()** - Documento enums no Swagger
|
|
344
|
+
- **@ApiPropertyOnlyDevelop()** - Propriedades apenas em dev
|
|
345
|
+
- **@ApiExcludeEndpointDiffDevelop()** - Endpoints apenas em dev
|
|
346
|
+
- **@Upload()** - Documentação de upload de arquivos
|
|
347
|
+
- **@Cookies()** - Extrai cookies da requisição
|
|
348
|
+
- **@IsPublic()** - Marca endpoint como público
|
|
305
349
|
|
|
306
|
-
|
|
350
|
+
[Ver todos os decoradores →](./docs/06-decoradores.md)
|
|
307
351
|
|
|
308
|
-
|
|
352
|
+
## Arquitetura
|
|
309
353
|
|
|
310
|
-
|
|
311
|
-
- Caso contrário, o endpoint será excluído da documentação.
|
|
354
|
+
A biblioteca utiliza duas classes principais:
|
|
312
355
|
|
|
313
|
-
|
|
356
|
+
1. **KoalaNestModule** - Módulo NestJS com configuração
|
|
357
|
+
2. **KoalaApp** - Classe fluent para setup da aplicação
|
|
314
358
|
|
|
315
|
-
|
|
359
|
+
Ambas seguem o padrão de **Fluent Interface** para configuração clara e intuitiva.
|
|
316
360
|
|
|
317
|
-
|
|
361
|
+
## Dependências Principais
|
|
318
362
|
|
|
319
|
-
|
|
363
|
+
- `@nestjs/*` - Framework NestJS
|
|
364
|
+
- `@prisma/client` - ORM Prisma
|
|
365
|
+
- `zod` - Validação de dados
|
|
366
|
+
- `ioredis` - Cliente Redis
|
|
367
|
+
- `@nestjs/swagger` - Documentação automática
|
|
320
368
|
|
|
321
|
-
|
|
369
|
+
## Links Importantes
|
|
322
370
|
|
|
323
|
-
|
|
324
|
-
|
|
371
|
+
- **[CLI (@koalarx/nest-cli)](https://www.npmjs.com/package/@koalarx/nest-cli)** - Ferramenta oficial para criar projetos rapidamente
|
|
372
|
+
- **[GitHub da Library](https://github.com/igordrangel/koala-nest)** - Repositório principal
|
|
373
|
+
- **[GitHub da CLI](https://github.com/igordrangel/koala-nest-cli)** - Repositório da CLI
|
|
325
374
|
|
|
326
|
-
|
|
375
|
+
## Licença
|
|
327
376
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
334
|
-
```
|
|
377
|
+
MIT License © 2023-2025 Igor D. Rangel
|
|
378
|
+
|
|
379
|
+
## Contribuindo
|
|
380
|
+
|
|
381
|
+
Contribuições são bem-vindas! Abra uma issue ou pull request no repositório.
|
|
335
382
|
|
|
336
|
-
|
|
383
|
+
## Suporte
|
|
384
|
+
|
|
385
|
+
Para dúvidas, abra uma issue no repositório ou consulte a [documentação completa](./docs).
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
<p align="center">
|
|
390
|
+
Feito para desenvolvedores NestJS
|
|
391
|
+
</p>
|
|
@@ -2,6 +2,7 @@ import { EnvService } from '@koalarx/nest/env/env.service';
|
|
|
2
2
|
import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
|
3
3
|
import { Prisma, PrismaClient } from '@prisma/client';
|
|
4
4
|
import { PrismaClientWithCustomTransaction } from './prisma-client-with-custom-transaction.interface';
|
|
5
|
+
export declare function setPrismaClientOptions(options: Record<string, any>): void;
|
|
5
6
|
export declare class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy, PrismaClientWithCustomTransaction {
|
|
6
7
|
private readonly env;
|
|
7
8
|
constructor(env: EnvService);
|
|
@@ -10,19 +10,28 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.PrismaService = void 0;
|
|
13
|
+
exports.setPrismaClientOptions = setPrismaClientOptions;
|
|
13
14
|
const env_service_1 = require("../../env/env.service");
|
|
14
15
|
const common_1 = require("@nestjs/common");
|
|
15
16
|
const client_1 = require("@prisma/client");
|
|
17
|
+
let globalPrismaOptions = {};
|
|
18
|
+
function setPrismaClientOptions(options) {
|
|
19
|
+
globalPrismaOptions = options;
|
|
20
|
+
}
|
|
16
21
|
let PrismaService = class PrismaService extends client_1.PrismaClient {
|
|
17
22
|
env;
|
|
18
23
|
constructor(env) {
|
|
19
|
-
|
|
24
|
+
const defaultOptions = {
|
|
20
25
|
log: [
|
|
21
26
|
{
|
|
22
27
|
emit: 'event',
|
|
23
28
|
level: 'query',
|
|
24
29
|
},
|
|
25
30
|
],
|
|
31
|
+
};
|
|
32
|
+
super({
|
|
33
|
+
...defaultOptions,
|
|
34
|
+
...globalPrismaOptions,
|
|
26
35
|
});
|
|
27
36
|
this.env = env;
|
|
28
37
|
}
|