@ismael1361/router 1.0.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 ADDED
@@ -0,0 +1,988 @@
1
+ # @ismael1361/router
2
+
3
+ Esse módulo foi criado para preparar e centralizar rotas em um Express.js com tipagem encadeada, útil para tipar conteúdo de escobo e propriedades de requisição como `body`, `params` e `query`. Também oferece a geração de documentação OpenAPI/Swagger integrada.
4
+
5
+ ## Instalação
6
+
7
+ ```bash
8
+ npm install @ismael1361/router
9
+ # ou
10
+ yarn add @ismael1361/router
11
+ ```
12
+
13
+ ---
14
+
15
+ ## Indice
16
+
17
+ - [@ismael1361/router](#ismael1361router)
18
+ - [Instalação](#instalação)
19
+ - [Indice](#indice)
20
+ - [`create`](#create)
21
+ - [Parâmetros](#parâmetros)
22
+ - [Retorno](#retorno)
23
+ - [Exemplo de Uso](#exemplo-de-uso)
24
+ - [`middleware`](#middleware)
25
+ - [Parâmetros](#parâmetros-1)
26
+ - [Retorno](#retorno-1)
27
+ - [Exemplo de Uso](#exemplo-de-uso-1)
28
+ - [`route`](#route)
29
+ - [Parâmetros](#parâmetros-2)
30
+ - [Retorno](#retorno-2)
31
+ - [Exemplo de Uso](#exemplo-de-uso-2)
32
+ - [`Router`](#router)
33
+ - [Propriedades da Instância](#propriedades-da-instância)
34
+ - [`router`](#router-1)
35
+ - [`routes`](#routes)
36
+ - [Métodos da Instância](#métodos-da-instância)
37
+ - [`get`](#get)
38
+ - [`post`](#post)
39
+ - [`put`](#put)
40
+ - [`delete`](#delete)
41
+ - [`patch`](#patch)
42
+ - [`options`](#options)
43
+ - [`head`](#head)
44
+ - [`all`](#all)
45
+ - [`use`](#use)
46
+ - [`route`](#route-1)
47
+ - [`middleware`](#middleware-1)
48
+ - [`handler`](#handler)
49
+ - [`by`](#by)
50
+ - [`getSwagger`](#getswagger)
51
+
52
+ ---
53
+
54
+ ## `create`
55
+
56
+ ```typescript
57
+ create<Req extends Request, Res extends Response>(app?: express.Express | express.Router): Router<Req, Res>;
58
+ ```
59
+
60
+ A função `create` é o ponto de partida para a criação de rotas. Ela inicializa uma instância de um roteador aprimorado que pode ser anexado a uma aplicação Express existente ou usado de forma independente.
61
+
62
+ Este roteador oferece uma API fluente e fortemente tipada para definir rotas, ao mesmo tempo que integra a geração de documentação OpenAPI (Swagger).
63
+
64
+ ### Parâmetros
65
+
66
+ - `app` (opcional): Uma instância de uma aplicação `Express` ou `Router` do Express. Se fornecido, o novo roteador será montado diretamente nesta instância.
67
+
68
+ ### Retorno
69
+
70
+ Retorna uma nova instância do `Router`, que possui métodos encadeáveis (`.get()`, `.post()`, etc.) para a definição de rotas com metadados para a documentação.
71
+
72
+ ### Exemplo de Uso
73
+
74
+ ```typescript
75
+ import express from 'express';
76
+ import { create, Request, Response } from '@ismael1361/router';
77
+
78
+ // 1. (Opcional) Estenda os tipos de Request e Response se precisar de propriedades customizadas
79
+ interface CustomRequest extends Request {
80
+ user?: { id: string; name: string };
81
+ }
82
+
83
+ interface CustomResponse extends Response {
84
+ // ... propriedades customizadas para a resposta
85
+ }
86
+
87
+ const app = express();
88
+
89
+ // 2. Crie a instância do roteador, passando a aplicação Express
90
+ const router = create<CustomRequest, CustomResponse>(app).middleware(express.json());
91
+
92
+ // 3. Defina as rotas usando a API fluente
93
+ router
94
+ .get('/users/:id')
95
+ .handle((req, res) => {
96
+ // req.params.id é totalmente tipado aqui
97
+ res.json({ id: req.params.id, name: 'John Doe' });
98
+ }).doc({
99
+ summary: 'Obter um usuário pelo ID',
100
+ description: 'Retorna os detalhes de um usuário específico.',
101
+ tags: ['Users'],
102
+ params: {
103
+ id: {
104
+ description: 'ID do usuário',
105
+ type: 'string',
106
+ required: true,
107
+ },
108
+ },
109
+ responses: {
110
+ 200: { description: 'Usuário encontrado' },
111
+ 404: { description: 'Usuário não encontrado' },
112
+ },
113
+ });
114
+
115
+ // O roteador já está montado na 'app' e as rotas estão ativas.
116
+ app.listen(3000, () => {
117
+ console.log('Servidor rodando na porta 3000');
118
+ });
119
+ ```
120
+
121
+ ---
122
+
123
+ ## `middleware`
124
+
125
+ ```ts
126
+ middleware<Req extends Request, Res extends Response>(
127
+ callback: MiddlewareFC<Req, Res>,
128
+ doc?: MiddlewareFCDoc
129
+ ): MiddlewareFC<Req, Res>;
130
+ ```
131
+
132
+ A função `middleware` é um wrapper que permite criar middlewares reutilizáveis para o Express, enriquecendo-os com metadados para a documentação OpenAPI (Swagger).
133
+
134
+ Ao envolver sua lógica de middleware com esta função, você pode definir como ele deve ser documentado (ex: quais cabeçalhos ele espera, quais respostas de erro ele pode retornar). Quando este middleware é aplicado a uma rota, sua documentação é automaticamente mesclada com a documentação da rota.
135
+
136
+ ### Parâmetros
137
+
138
+ - `callback`: A função de middleware padrão do Express, com a assinatura `(req, res, next)`. É aqui que a lógica do seu middleware (autenticação, logging, etc.) reside.
139
+ - `doc` (opcional): Um objeto que descreve o middleware para a documentação OpenAPI. É útil para documentar requisitos globais como autenticação.
140
+
141
+ ### Retorno
142
+
143
+ Retorna a própria função de `callback` do middleware, mas com os metadados da documentação anexados a ela. Isso permite que o roteador a utilize tanto como um middleware funcional quanto como uma fonte de documentação.
144
+
145
+ ### Exemplo de Uso
146
+
147
+ Vamos criar e usar um middleware de autenticação que verifica um token no cabeçalho `Authorization`.
148
+
149
+ ```typescript
150
+ import express from 'express';
151
+ import { create, middleware, Request, Response } from '@ismael1361/router';
152
+
153
+ interface AuthRequest extends Request {
154
+ user: { id: string; roles: string[] };
155
+ }
156
+
157
+ // 1. Crie o middleware de autenticação com sua documentação
158
+ const isAuthenticated = middleware<AuthRequest>(
159
+ (req, res, next) => {
160
+ const token = req.headers.authorization;
161
+ if (token === 'Bearer meu-token-secreto') {
162
+ req.user = { id: '123', roles: ['admin', 'user'] };
163
+ return next(); // Token válido, continue
164
+ }
165
+ res.status(401).json({ message: 'Não autorizado' });
166
+ },
167
+ {
168
+ // 2. Documente os requisitos e possíveis respostas do middleware
169
+ security: [{ bearerAuth: [] }], // Indica que a rota requer autenticação Bearer
170
+ responses: {
171
+ 401: { description: 'Token de autenticação inválido ou não fornecido' },
172
+ },
173
+ }
174
+ );
175
+
176
+ const app = express();
177
+ const router = create(app);
178
+
179
+ // 3. Aplique o middleware a uma rota específica
180
+ router
181
+ .get('/profile')
182
+ .middleware(isAuthenticated) // O middleware é aplicado aqui
183
+ .handle((req, res) => {
184
+ res.json({ user: req.user });
185
+ }).doc({
186
+ summary: 'Obter perfil do usuário',
187
+ description: 'Acessa informações do usuário autenticado. Requer um token válido.',
188
+ tags: ['Users'],
189
+ responses: {
190
+ 200: { description: 'Perfil do usuário' },
191
+ },
192
+ });
193
+
194
+ // A documentação OpenAPI gerada para a rota GET /profile agora incluirá
195
+ // automaticamente as seções 'security' e a resposta '401' definidas no middleware.
196
+
197
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
198
+ ```
199
+
200
+ ---
201
+
202
+ ## `route`
203
+
204
+ ```ts
205
+ route<Req extends Request, Res extends Response>(path: string): Router<Req, Res>;
206
+ ```
207
+
208
+ A função `route` cria uma instância de rota encadeável para um caminho (path) específico. Isso permite agrupar múltiplos métodos HTTP (como GET, POST, PUT, etc.) para o mesmo endpoint de URL, o que é uma prática comum para organizar APIs RESTful.
209
+
210
+ Ao invés de definir `router.get('/tasks', ...)` e `router.post('/tasks', ...)` separadamente, você pode agrupar ambos sob `router.route('/tasks')`.
211
+
212
+ ### Parâmetros
213
+
214
+ - `path`: A string do caminho da URL para a qual a rota será criada.
215
+
216
+ ### Retorno
217
+
218
+ Retorna uma nova instância do `Router` que está "travada" no `path` especificado. Você pode então encadear os métodos HTTP (`.get()`, `.post()`, etc.) diretamente a esta instância.
219
+
220
+ ### Exemplo de Uso
221
+
222
+ Vamos criar um endpoint `/tasks` que lida com a listagem (GET) e a criação (POST) de tarefas.
223
+
224
+ ```typescript
225
+ import express from 'express';
226
+ import { route, Request, Response } from '@ismael1361/router';
227
+
228
+ const app = express();
229
+ const main = create(app).middleware(express.json());
230
+
231
+ // 1. Crie uma rota para o caminho '/tasks'
232
+ const router = route('/tasks');
233
+
234
+ // 2. Defina o handler para o método GET nesta rota
235
+ router
236
+ .get("/items")
237
+ .handle((req, res) => {
238
+ res.json([{ id: 1, title: 'Aprender a usar o @ismael1361/router' }]);
239
+ }).doc({
240
+ summary: 'Listar todas as tarefas',
241
+ tags: ['Tasks'],
242
+ responses: { 200: { description: 'Lista de tarefas' } },
243
+ });
244
+
245
+ // 3. Defina o handler para o método POST na mesma rota
246
+ router
247
+ .post("item")
248
+ .handle((req, res) => {
249
+ const newTask = req.body;
250
+ res.status(201).json({ id: 2, ...newTask });
251
+ }).doc({
252
+ summary: 'Criar uma nova tarefa',
253
+ tags: ['Tasks'],
254
+ body: { description: 'Dados da nova tarefa' },
255
+ responses: { 201: { description: 'Tarefa criada com sucesso' } },
256
+ });
257
+
258
+ // 4. Adicione a rota ao roteador principal
259
+ main.by(router);
260
+ // ou diretamente ao app
261
+ // app.use(router.router);
262
+
263
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
264
+ ```
265
+
266
+ ---
267
+
268
+ ## `Router`
269
+
270
+ ```ts
271
+ Router<Rq extends Request, Rs extends Response>;
272
+ ```
273
+
274
+ A classe `Router` é o principal objeto com o qual você irá interagir. Ela encapsula o roteador do Express, fornecendo uma API encadeável e fortemente tipada para definir rotas, aplicar middlewares e gerar documentação OpenAPI.
275
+
276
+ Uma instância do `Router` é retornada pela função `create` ou pelo método `.route()`.
277
+
278
+ ---
279
+
280
+ ### Propriedades da Instância
281
+
282
+ #### `router`
283
+
284
+ ```ts
285
+ .router: express.Router;
286
+ ```
287
+
288
+ A instância do roteador do Express. Usada internamente para definir rotas e middlewares.
289
+
290
+ ---
291
+
292
+ #### `routes`
293
+
294
+ ```ts
295
+ .routes: Array<{
296
+ path: string;
297
+ methods: string[];
298
+ type: "ROUTE" | "MIDDLEWARE";
299
+ swagger?: Pick<swaggerJSDoc.OAS3Definition, "paths" | "components">;
300
+ }>;
301
+ ```
302
+
303
+ Um array que armazena as rotas e middlewares definidos na instância. Essas rotas e middlewares serão usadas para gerar a documentação OpenAPI.
304
+
305
+ ---
306
+
307
+ ### Métodos da Instância
308
+
309
+ #### `get`
310
+
311
+ ```ts
312
+ .get(path: string): RequestHandler<Rq, Rs>;
313
+ ```
314
+
315
+ Registra uma rota que responde a requisições HTTP do método GET. Este método é o ponto de partida para definir um endpoint que recupera dados.
316
+
317
+ Após chamar `.get()`, você deve encadear o método `.handle()` para fornecer a lógica do controlador e, opcionalmente, o método `.doc()` para adicionar a documentação OpenAPI.
318
+
319
+ * **Parâmetros**
320
+ - `path` (string): A string do caminho da URL para a rota. O caminho é relativo ao prefixo do roteador. Pode conter parâmetros de rota, como `/users/:id`.
321
+
322
+ * **Retorno**
323
+ Retorna uma instância de `RequestHandler`, que é um objeto intermediário com os seguintes métodos encadeáveis:
324
+ - `.middleware()`: Para aplicar middlewares específicos a esta rota.
325
+ - `.handle()`: Para definir a função controladora que processará a requisição.
326
+ - `.doc()`: Para fornecer metadados de documentação OpenAPI para a rota.
327
+
328
+ * **Exemplo de Uso**
329
+ ```typescript
330
+ import express from 'express';
331
+ import { create, Request, Response } from '@ismael1361/router';
332
+
333
+ const app = express();
334
+ const router = create(app);
335
+
336
+ // Exemplo 1: Rota GET simples
337
+ router
338
+ .get('/status')
339
+ .handle((req, res) => {
340
+ res.json({ status: 'ok' });
341
+ })
342
+ .doc({
343
+ summary: 'Verificar o status da API',
344
+ tags: ['Health'],
345
+ responses: {
346
+ 200: { description: 'A API está funcionando corretamente' },
347
+ },
348
+ });
349
+
350
+ // Exemplo 2: Rota GET com parâmetros
351
+ router
352
+ .get('/users/:id')
353
+ .handle((req, res) => {
354
+ // 'req.params.id' é totalmente tipado como string
355
+ const userId = req.params.id;
356
+ // Lógica para buscar o usuário...
357
+ res.json({ id: userId, name: 'Usuário Exemplo' });
358
+ })
359
+ .doc({
360
+ summary: 'Obter um usuário pelo ID',
361
+ tags: ['Users'],
362
+ params: { id: { description: 'ID do usuário', type: 'string', required: true } },
363
+ responses: { 200: { description: 'Dados do usuário' }, 404: { description: 'Usuário não encontrado' } },
364
+ });
365
+
366
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
367
+ ```
368
+
369
+ ---
370
+
371
+ #### `post`
372
+
373
+ ```ts
374
+ .post(path: string): RequestHandler<Rq, Rs>;
375
+ ```
376
+
377
+ Registra uma rota que responde a requisições HTTP do método POST. Este método é comumente utilizado para **criar novos recursos** no servidor.
378
+
379
+ Após chamar `.post()`, você deve encadear o método `.handle()` para fornecer a lógica do controlador (que geralmente acessa `req.body`) e, opcionalmente, o método `.doc()` para documentar o corpo da requisição e as possíveis respostas.
380
+
381
+ * **Parâmetros**
382
+ - `path` (string): A string do caminho da URL para a rota.
383
+
384
+ * **Retorno**
385
+ Retorna uma instância de `RequestHandler` para encadeamento dos métodos `.middleware()`, `.handle()` e `.doc()`.
386
+
387
+ * **Exemplo de Uso**
388
+ ```typescript
389
+ import express from 'express';
390
+ import { create, Request, Response } from '@ismael1361/router';
391
+
392
+ const app = express();
393
+ // É essencial usar um middleware para parsear o corpo da requisição JSON
394
+ const router = create(app).middleware(express.json());
395
+
396
+ router
397
+ .post('/users')
398
+ .handle((req, res) => {
399
+ // req.body contém os dados enviados pelo cliente
400
+ const newUser = req.body;
401
+ // Lógica para salvar o novo usuário no banco de dados...
402
+ const createdUser = { id: Date.now().toString(), ...newUser };
403
+ res.status(201).json(createdUser);
404
+ })
405
+ .doc({
406
+ summary: 'Criar um novo usuário',
407
+ tags: ['Users'],
408
+ body: {
409
+ description: 'Dados do novo usuário a ser criado.',
410
+ required: true,
411
+ // Você pode fornecer um schema para o corpo da requisição
412
+ schema: {
413
+ type: 'object',
414
+ properties: {
415
+ name: { type: 'string', example: 'Jane Doe' },
416
+ email: { type: 'string', example: 'jane.doe@example.com' },
417
+ },
418
+ required: ['name', 'email'],
419
+ },
420
+ },
421
+ responses: {
422
+ 201: { description: 'Usuário criado com sucesso' },
423
+ 400: { description: 'Dados inválidos fornecidos' },
424
+ },
425
+ });
426
+
427
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
428
+ ```
429
+
430
+ ---
431
+
432
+ #### `put`
433
+
434
+ ```ts
435
+ .put(path: string): RequestHandler<Rq, Rs>;
436
+ ```
437
+
438
+ Registra uma rota que responde a requisições HTTP do método PUT. Este método é usado para **substituir completamente um recurso existente** com os novos dados fornecidos no corpo da requisição.
439
+
440
+ * **Parâmetros**
441
+ - `path` (string): O caminho da URL, geralmente contendo um parâmetro para identificar o recurso a ser atualizado (ex: `/users/:id`).
442
+
443
+ * **Retorno**
444
+ Retorna uma instância de `RequestHandler` para encadeamento.
445
+
446
+ * **Exemplo de Uso**
447
+ ```typescript
448
+ import express from 'express';
449
+ import { create, Request, Response } from '@ismael1361/router';
450
+
451
+ const app = express();
452
+ const router = create(app).middleware(express.json());
453
+
454
+ router
455
+ .put('/users/:id')
456
+ .handle((req, res) => {
457
+ const { id } = req.params;
458
+ const updatedData = req.body;
459
+ // Lógica para substituir o usuário com o ID fornecido...
460
+ res.json({ id, ...updatedData });
461
+ })
462
+ .doc({
463
+ summary: 'Atualizar um usuário (substituição completa)',
464
+ tags: ['Users'],
465
+ params: { id: { description: 'ID do usuário a ser atualizado', type: 'string', required: true } },
466
+ body: { description: 'Dados completos do usuário para substituição.' },
467
+ responses: {
468
+ 200: { description: 'Usuário atualizado com sucesso' },
469
+ 404: { description: 'Usuário não encontrado' },
470
+ },
471
+ });
472
+
473
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
474
+ ```
475
+
476
+ ---
477
+
478
+ #### `delete`
479
+
480
+ ```ts
481
+ .delete(path: string): RequestHandler<Rq, Rs>;
482
+ ```
483
+
484
+ Registra uma rota que responde a requisições HTTP do método DELETE. Este método é utilizado para **remover um recurso específico**.
485
+
486
+ * **Parâmetros**
487
+ - `path` (string): O caminho da URL, que deve conter um parâmetro para identificar o recurso a ser removido (ex: `/items/:id`).
488
+
489
+ * **Retorno**
490
+ Retorna uma instância de `RequestHandler` para encadeamento.
491
+
492
+ * **Exemplo de Uso**
493
+ ```typescript
494
+ import express from 'express';
495
+ import { create, Request, Response } from '@ismael1361/router';
496
+
497
+ const app = express();
498
+ const router = create(app);
499
+
500
+ router
501
+ .delete('/items/:id')
502
+ .handle((req, res) => {
503
+ const { id } = req.params;
504
+ // Lógica para deletar o item do banco de dados...
505
+ console.log(`Item ${id} deletado.`);
506
+ // Uma boa prática é retornar 204 (No Content) em caso de sucesso.
507
+ res.status(204).send();
508
+ })
509
+ .doc({
510
+ summary: 'Deletar um item',
511
+ tags: ['Items'],
512
+ params: { id: { description: 'ID do item a ser deletado', type: 'string', required: true } },
513
+ responses: {
514
+ 204: { description: 'Item deletado com sucesso' },
515
+ 404: { description: 'Item não encontrado' },
516
+ },
517
+ });
518
+
519
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
520
+ ```
521
+
522
+ ---
523
+
524
+ #### `patch`
525
+
526
+ ```ts
527
+ .patch(path: string): RequestHandler<Rq, Rs>;
528
+ ```
529
+
530
+ Registra uma rota que responde a requisições HTTP do método PATCH. É usado para aplicar **atualizações parciais** a um recurso, modificando apenas os campos enviados no corpo da requisição.
531
+
532
+ * **Parâmetros**
533
+ - `path` (string): O caminho da URL, geralmente com um parâmetro para identificar o recurso (ex: `/tasks/:id`).
534
+
535
+ * **Retorno**
536
+ Retorna uma instância de `RequestHandler` para encadeamento.
537
+
538
+ * **Exemplo de Uso**
539
+ ```typescript
540
+ import express from 'express';
541
+ import { create, Request, Response } from '@ismael1361/router';
542
+
543
+ const app = express();
544
+ const router = create(app).middleware(express.json());
545
+
546
+ router
547
+ .patch('/tasks/:id')
548
+ .handle((req, res) => {
549
+ const { id } = req.params;
550
+ const partialUpdates = req.body; // ex: { "completed": true }
551
+ // Lógica para aplicar a atualização parcial na tarefa...
552
+ res.json({ id, message: 'Tarefa atualizada parcialmente.', changes: partialUpdates });
553
+ })
554
+ .doc({
555
+ summary: 'Atualizar uma tarefa (parcialmente)',
556
+ tags: ['Tasks'],
557
+ params: { id: { description: 'ID da tarefa', type: 'string', required: true } },
558
+ body: { description: 'Campos da tarefa a serem atualizados.' },
559
+ responses: {
560
+ 200: { description: 'Tarefa atualizada' },
561
+ 404: { description: 'Tarefa não encontrada' },
562
+ },
563
+ });
564
+
565
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
566
+ ```
567
+
568
+ ---
569
+
570
+ #### `options`
571
+
572
+ ```ts
573
+ .options(path: string): RequestHandler<Rq, Rs>;
574
+ ```
575
+
576
+ Registra uma rota que responde a requisições HTTP do método OPTIONS. Este método é usado pelo navegador para determinar as opções de comunicação para um recurso de destino, principalmente em requisições de **pré-voo (pre-flight) do CORS**.
577
+
578
+ * **Parâmetros**
579
+ - `path` (string): O caminho da URL do recurso.
580
+
581
+ * **Retorno**
582
+ Retorna uma instância de `RequestHandler` para encadeamento.
583
+
584
+ * **Exemplo de Uso**
585
+ ```typescript
586
+ import express from 'express';
587
+ import { create, Request, Response } from '@ismael1361/router';
588
+
589
+ const app = express();
590
+ const router = create(app);
591
+
592
+ // Para um recurso específico, informa quais métodos são permitidos
593
+ router
594
+ .options('/articles/:id')
595
+ .handle((req, res) => {
596
+ res.header('Access-Control-Allow-Methods', 'GET, PUT, DELETE');
597
+ res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
598
+ res.status(204).send();
599
+ })
600
+ .doc({
601
+ summary: 'Verificar opções de comunicação para um artigo',
602
+ tags: ['Articles'],
603
+ responses: {
604
+ 204: { description: 'Sucesso. Os métodos permitidos estão nos cabeçalhos de resposta.' },
605
+ },
606
+ });
607
+
608
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
609
+ ```
610
+
611
+ ---
612
+
613
+ #### `head`
614
+
615
+ ```ts
616
+ .head(path: string): RequestHandler<Rq, Rs>;
617
+ ```
618
+
619
+ Registra uma rota que responde a requisições HTTP do método HEAD. É idêntico ao GET, mas o servidor **não envia o corpo da resposta**. É útil para verificar metadados de um recurso, como `Content-Length` ou `Last-Modified`, sem precisar baixar o conteúdo completo.
620
+
621
+ * **Parâmetros**
622
+ - `path` (string): O caminho da URL do recurso.
623
+
624
+ * **Retorno**
625
+ Retorna uma instância de `RequestHandler` para encadeamento.
626
+
627
+ * **Exemplo de Uso**
628
+ ```typescript
629
+ import express from 'express';
630
+ import { create, Request, Response } from '@ismael1361/router';
631
+
632
+ const app = express();
633
+ const router = create(app);
634
+
635
+ // O Express lida com HEAD automaticamente se você tiver uma rota GET correspondente.
636
+ // No entanto, você pode definir um handler específico se precisar de lógica customizada.
637
+ router
638
+ .head('/large-file.zip')
639
+ .handle((req, res) => {
640
+ // Lógica para obter o tamanho do arquivo sem lê-lo
641
+ const fileSize = 104857600; // 100 MB
642
+ res.header('Content-Length', fileSize.toString());
643
+ res.status(200).send(); // O corpo é omitido pelo Express
644
+ })
645
+ .doc({
646
+ summary: 'Obter metadados de um arquivo',
647
+ tags: ['Files'],
648
+ responses: {
649
+ 200: { description: 'Metadados do arquivo nos cabeçalhos.' },
650
+ 404: { description: 'Arquivo não encontrado.' },
651
+ },
652
+ });
653
+
654
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
655
+ ```
656
+
657
+ ---
658
+
659
+ #### `all`
660
+
661
+ ```ts
662
+ .all(path: string): RequestHandler<Rq, Rs>;
663
+ ```
664
+
665
+ Registra uma rota que responde a **todos os métodos HTTP** (GET, POST, PUT, etc.) para um caminho específico. É útil para aplicar lógica genérica a um endpoint, como logging ou validações que independem do método.
666
+
667
+ * **Parâmetros**
668
+ - `path` (string): O caminho da URL.
669
+
670
+ * **Retorno**
671
+ Retorna uma instância de `RequestHandler` para encadeamento.
672
+
673
+ * **Exemplo de Uso**
674
+ ```typescript
675
+ import express from 'express';
676
+ import { create, Request, Response } from '@ismael1361/router';
677
+
678
+ const app = express();
679
+ const router = create(app);
680
+
681
+ router
682
+ .all('/secret-data')
683
+ .handle((req, res) => {
684
+ // Este handler será executado para GET, POST, DELETE, etc. em '/secret-data'
685
+ console.log(`Requisição ${req.method} recebida em /secret-data`);
686
+ res.status(403).send('Acesso negado a este endpoint.');
687
+ })
688
+ .doc({
689
+ summary: 'Endpoint genérico de captura',
690
+ tags: ['Utils'],
691
+ description: 'Este endpoint responde a todos os métodos HTTP com uma mensagem padrão.',
692
+ responses: {
693
+ 403: { description: 'Acesso sempre negado.' },
694
+ },
695
+ });
696
+
697
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
698
+ ```
699
+
700
+ ---
701
+
702
+ #### `use`
703
+
704
+ ```ts
705
+ .use(path: string): Router<Rq, Rs>;
706
+ ```
707
+
708
+ Monta uma função de middleware ou uma série de middlewares em um caminho específico. Diferente dos métodos de rota (GET, POST, etc.), `use` é projetado para interceptar requisições e executar código **antes** que elas cheguem ao handler final da rota.
709
+
710
+ É ideal para tarefas como logging, parsing de corpo de requisição, autenticação e tratamento de erros. Se nenhum caminho for especificado, o middleware será aplicado a todas as rotas definidas no roteador.
711
+
712
+ * **Parâmetros**
713
+ - `path` (opcional): O caminho no qual o middleware será aplicado. Suporta wildcards (ex: `/api/*`).
714
+
715
+ * **Retorno**
716
+ Retorna a própria instância do `Router`, permitindo o encadeamento de mais definições.
717
+
718
+ * **Exemplo de Uso**
719
+ ```typescript
720
+ import express from 'express';
721
+ import { create, Request, Response, NextFunction } from '@ismael1361/router';
722
+
723
+ const app = express();
724
+ const router = create(app);
725
+
726
+ // Aplica o middleware no caminho /api
727
+ router.use('/api').handle((req, res, next) => {
728
+ console.log(`[${new Date().toISOString()}] ${req.method} ${req.originalUrl}`);
729
+ next(); // Passa o controle para o próximo middleware ou handler
730
+ });
731
+
732
+ // Define uma rota dentro do escopo do middleware
733
+ router
734
+ .get('/api/status')
735
+ .handle((req, res) => {
736
+ res.json({ status: 'ok' });
737
+ });
738
+
739
+ // Uma requisição para GET /api/status irá primeiro executar o loggerMiddleware.
740
+
741
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
742
+ ```
743
+
744
+ ---
745
+
746
+ #### `route`
747
+
748
+ ```ts
749
+ .route(path: string): Router<Rq, Rs>;
750
+ ```
751
+
752
+ Cria e retorna uma nova instância de `Router` que é montada sob um caminho (prefixo) específico. É uma maneira poderosa de agrupar um conjunto de rotas relacionadas sob um namespace comum, promovendo a organização e a modularidade do código.
753
+
754
+ Todas as rotas definidas no roteador retornado serão relativas ao `path` fornecido.
755
+
756
+ * **Parâmetros**
757
+ - `path` (string): O caminho do prefixo para o novo roteador. Por exemplo, `/api/v1`.
758
+
759
+ * **Retorno**
760
+ Retorna uma nova instância de `Router` que pode ser usada para definir um grupo de rotas.
761
+
762
+ * **Exemplo de Uso**
763
+ ```typescript
764
+ import express from 'express';
765
+ import { create, Request, Response } from '@ismael1361/router';
766
+
767
+ const app = express();
768
+ const mainRouter = create(app);
769
+
770
+ // 1. Crie um sub-roteador para os endpoints de usuários
771
+ const usersRouter = mainRouter.route('/users');
772
+
773
+ // 2. Defina as rotas neste sub-roteador. Os caminhos são relativos a '/users'.
774
+ usersRouter
775
+ .get('/')
776
+ .handle((req, res) => {
777
+ // Este handler responde a GET /users
778
+ res.json([{ id: '1', name: 'Alice' }]);
779
+ })
780
+ .doc({ summary: 'Listar todos os usuários', tags: ['Users'] });
781
+
782
+ usersRouter
783
+ .get('/:id')
784
+ .handle((req, res) => {
785
+ // Este handler responde a GET /users/:id
786
+ res.json({ id: req.params.id, name: 'Alice' });
787
+ })
788
+ .doc({ summary: 'Obter um usuário pelo ID', tags: ['Users'] });
789
+
790
+ // O mainRouter já está conectado ao 'app', então as rotas estão ativas.
791
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
792
+ ```
793
+
794
+ ---
795
+
796
+ #### `middleware`
797
+
798
+ ```ts
799
+ .middleware<Req extends Request, Res extends Response>(callback: MiddlewareFC<Req, Res>): Router<Rq & Req, Rs & Res>;
800
+ ```
801
+
802
+ Aplica uma função de middleware a **todas as rotas subsequentes** definidas nesta instância do roteador. É o método ideal para aplicar middlewares que devem ser executados para um grupo de endpoints, como parsing de corpo de requisição (`express.json()`) ou autenticação.
803
+
804
+ A tipagem do `Request` e `Response` é inteligentemente mesclada, garantindo que as propriedades adicionadas por um middleware (ex: `req.user`) estejam disponíveis e corretamente tipadas nos handlers das rotas.
805
+
806
+ * **Parâmetros**
807
+ - `callbacks`: Uma função de middleware do Express.
808
+
809
+ * **Retorno**
810
+ Retorna a própria instância do `Router`, com os tipos de `Request` e `Response` atualizados, permitindo o encadeamento contínuo.
811
+
812
+ * **Exemplo de Uso**
813
+ ```typescript
814
+ import express from 'express';
815
+ import { create, middleware, Request, Response, NextFunction } from '@ismael1361/router';
816
+
817
+ interface AuthRequest extends Request {
818
+ user?: { id: string };
819
+ }
820
+
821
+ const app = express();
822
+
823
+ // Middleware de autenticação simples
824
+ const authMiddleware = middleware<AuthRequest>((req, res, next) => {
825
+ req.user = { id: 'user-123' };
826
+ next();
827
+ });
828
+
829
+ // 1. Crie o roteador e aplique middlewares globais a ele
830
+ const router = create<AuthRequest>(app)
831
+ .middleware(express.json());
832
+
833
+ // 2. Todas as rotas definidas a partir daqui terão acesso a `req.body` e `req.user`
834
+ router
835
+ .get('/profile')
836
+ .middleware(authMiddleware)
837
+ .handle((req, res) => {
838
+ // req.user é totalmente tipado como { id: string }
839
+ res.json({ profile: req.user });
840
+ });
841
+
842
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
843
+ ```
844
+
845
+ ---
846
+
847
+ #### `handler`
848
+
849
+ ```ts
850
+ .handler<Req extends Request, Res extends Response>(callback: HandlerFC<Req, Res>): PreparedHandler<Rq & Req, Rs & Res>;
851
+ ```
852
+
853
+ Define a função controladora (handler) que processará a requisição para uma rota ou middleware específico. Este método é o coração da sua rota, onde a lógica de negócios é executada.
854
+
855
+ Ele deve ser encadeado após a definição de um método HTTP (como `.get()`, `.post()`) ou de um middleware (`.use()`). A função de `callback` recebe os objetos `req` e `res`, que são fortemente tipados com base nos middlewares aplicados anteriormente.
856
+
857
+ * **Parâmetros**
858
+ - `callback`: A função controladora que processará a requisição, com a assinatura `(req, res, next)`.
859
+
860
+ * **Retorno**
861
+ Retorna uma instância de `PreparedHandler`, que permite encadear o método `.doc()` para adicionar a documentação OpenAPI.
862
+
863
+ * **Exemplo de Uso**
864
+ ```typescript
865
+ import express from 'express';
866
+ import { create, Request, Response, NextFunction } from '@ismael1361/router';
867
+
868
+ const app = express();
869
+ const router = create(app);
870
+
871
+ // Exemplo 1: Handler para uma rota GET
872
+ router
873
+ .get('/status')
874
+ .handler((req, res) => {
875
+ res.json({ status: 'ok' });
876
+ });
877
+
878
+ // Exemplo 2: Handler para um middleware
879
+ router.use('/api').handler((req, res, next) => {
880
+ console.log('Requisição recebida na API');
881
+ next(); // Passa para o próximo handler
882
+ });
883
+
884
+ app.listen(3000, () => {
885
+ console.log('Servidor rodando na porta 3000');
886
+ console.log('Acesse /status ou /health-check');
887
+ });
888
+ ```
889
+
890
+ ---
891
+
892
+ #### `by`
893
+
894
+ ```ts
895
+ .by(router: ExpressRouter | Router<Request, Response>): this;
896
+ ```
897
+
898
+ Anexa um roteador existente (seja uma instância do `Router` desta biblioteca ou um `express.Router` padrão) ao roteador atual. Este método é uma forma conveniente de compor e modularizar sua aplicação, permitindo que você defina grupos de rotas em arquivos separados e depois os integre ao roteador principal.
899
+
900
+ * **Parâmetros**
901
+ - `router`: A instância do roteador a ser anexada.
902
+
903
+ * **Retorno**
904
+ - Retorna a própria instância do `Router` (`this`), permitindo o encadeamento de mais chamadas.
905
+
906
+ * **Exemplo de Uso**
907
+ ```typescript
908
+ import express from 'express';
909
+ import { create, route, Request, Response } from '@ismael1361/router';
910
+
911
+ const app = express();
912
+ const mainRouter = create(app);
913
+
914
+ // 1. Crie um roteador separado para as rotas de produtos
915
+ const productsRouter = route('/products');
916
+
917
+ productsRouter
918
+ .get('/')
919
+ .handle((req, res) => {
920
+ res.json([{ id: 'p1', name: 'Laptop' }]);
921
+ })
922
+ .doc({ summary: 'Listar produtos', tags: ['Products'] });
923
+
924
+ // 2. Use o método .by() para anexar o roteador de produtos ao roteador principal
925
+ mainRouter.by(productsRouter);
926
+
927
+ // A rota GET /products está agora ativa na aplicação.
928
+ app.listen(3000, () => console.log('Servidor rodando na porta 3000'));
929
+ ```
930
+
931
+ ---
932
+
933
+ #### `getSwagger`
934
+
935
+ ```ts
936
+ .getSwagger(options?: swaggerJSDoc.OAS3Definition, defaultResponses?: swaggerJSDoc.Responses): swaggerJSDoc.Options;
937
+ ```
938
+
939
+ Coleta todas as informações de documentação fornecidas através dos métodos `.doc()` em todas as rotas e as compila em um objeto de opções compatível com a biblioteca `swagger-jsdoc`. Este objeto pode ser usado para gerar a especificação OpenAPI completa (geralmente um arquivo `swagger.json`).
940
+
941
+ * **Parâmetros**
942
+ - `options` (opcional): Um objeto de definição base do OpenAPI 3.0. Aqui você define informações globais da sua API, como `info` (título, versão), `servers`, `components` (schemas, securitySchemes), etc.
943
+ - `defaultResponses` (opcional): Um objeto para definir respostas padrão que serão mescladas em todas as rotas, como `500: { description: 'Erro interno do servidor' }`.
944
+
945
+ * **Retorno**
946
+ - Retorna um objeto de opções (`swaggerJSDoc.Options`) que pode ser passado diretamente para a função `swaggerJSDoc()` para gerar a documentação.
947
+
948
+ * **Exemplo de Uso**
949
+ ```typescript
950
+ import swaggerJSDoc from 'swagger-jsdoc';
951
+ import swaggerUi from 'swagger-ui-express';
952
+
953
+ // ... (definição do seu app e rotas com .doc())
954
+
955
+ // 1. Defina as opções base para a sua documentação OpenAPI
956
+ const swaggerDefinition: swaggerJSDoc.OAS3Definition = {
957
+ openapi: '3.0.0',
958
+ info: {
959
+ title: 'Minha API Incrível',
960
+ version: '1.0.0',
961
+ description: 'Documentação da API criada com @ismael1361/router',
962
+ },
963
+ servers: [{ url: 'http://localhost:3000' }],
964
+ components: {
965
+ securitySchemes: {
966
+ bearerAuth: {
967
+ type: 'http',
968
+ scheme: 'bearer',
969
+ bearerFormat: 'JWT',
970
+ },
971
+ },
972
+ },
973
+ };
974
+
975
+ // 2. Gere as opções completas usando o método .getSwagger() do seu roteador
976
+ const swaggerOptions = router.getSwagger(swaggerDefinition);
977
+
978
+ // 3. Gere a especificação final com swagger-jsdoc
979
+ const swaggerSpec = swaggerJSDoc(swaggerOptions);
980
+
981
+ // 4. Sirva a documentação usando swagger-ui-express
982
+ app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
983
+
984
+ app.listen(3000, () => {
985
+ console.log('Servidor rodando na porta 3000');
986
+ console.log('Documentação disponível em http://localhost:3000/api-docs');
987
+ });
988
+ ```