sashiko 0.11.4 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +74 -1
  2. package/dist/core/app/core.d.ts +23 -0
  3. package/dist/core/app/core.d.ts.map +1 -0
  4. package/dist/core/app/core.js +2 -0
  5. package/dist/core/app/core.js.map +1 -0
  6. package/dist/core/app/options.d.ts +109 -0
  7. package/dist/core/app/options.d.ts.map +1 -0
  8. package/dist/core/app/options.js +2 -0
  9. package/dist/core/app/options.js.map +1 -0
  10. package/dist/core/app.d.ts +34 -175
  11. package/dist/core/app.d.ts.map +1 -1
  12. package/dist/core/app.js +101 -496
  13. package/dist/core/app.js.map +1 -1
  14. package/dist/core/body-parser.d.ts +6 -3
  15. package/dist/core/body-parser.d.ts.map +1 -1
  16. package/dist/core/body-parser.js +8 -6
  17. package/dist/core/body-parser.js.map +1 -1
  18. package/dist/core/compiler.d.ts +2 -0
  19. package/dist/core/compiler.d.ts.map +1 -1
  20. package/dist/core/compiler.js.map +1 -1
  21. package/dist/core/compose.d.ts +7 -0
  22. package/dist/core/compose.d.ts.map +1 -1
  23. package/dist/core/compose.js +25 -0
  24. package/dist/core/compose.js.map +1 -1
  25. package/dist/core/context.d.ts +61 -14
  26. package/dist/core/context.d.ts.map +1 -1
  27. package/dist/core/context.js +162 -39
  28. package/dist/core/context.js.map +1 -1
  29. package/dist/core/health.js +1 -1
  30. package/dist/core/index.d.ts +3 -2
  31. package/dist/core/index.d.ts.map +1 -1
  32. package/dist/core/index.js.map +1 -1
  33. package/dist/core/inject.d.ts.map +1 -1
  34. package/dist/core/inject.js +6 -0
  35. package/dist/core/inject.js.map +1 -1
  36. package/dist/core/logger.d.ts.map +1 -1
  37. package/dist/core/logger.js +41 -14
  38. package/dist/core/logger.js.map +1 -1
  39. package/dist/core/mounted-group.d.ts +5 -0
  40. package/dist/core/mounted-group.d.ts.map +1 -1
  41. package/dist/core/mounted-group.js +10 -0
  42. package/dist/core/mounted-group.js.map +1 -1
  43. package/dist/core/registry/framework-routes.d.ts +28 -0
  44. package/dist/core/registry/framework-routes.d.ts.map +1 -0
  45. package/dist/core/registry/framework-routes.js +83 -0
  46. package/dist/core/registry/framework-routes.js.map +1 -0
  47. package/dist/core/registry/registry.d.ts +53 -0
  48. package/dist/core/registry/registry.d.ts.map +1 -0
  49. package/dist/core/registry/registry.js +156 -0
  50. package/dist/core/registry/registry.js.map +1 -0
  51. package/dist/core/registry/route-program.d.ts +14 -0
  52. package/dist/core/registry/route-program.d.ts.map +1 -0
  53. package/dist/core/registry/route-program.js +29 -0
  54. package/dist/core/registry/route-program.js.map +1 -0
  55. package/dist/core/response/pipeline.d.ts +51 -0
  56. package/dist/core/response/pipeline.d.ts.map +1 -0
  57. package/dist/core/response/pipeline.js +171 -0
  58. package/dist/core/response/pipeline.js.map +1 -0
  59. package/dist/core/response.d.ts.map +1 -1
  60. package/dist/core/response.js +25 -0
  61. package/dist/core/response.js.map +1 -1
  62. package/dist/core/route-table.d.ts +5 -1
  63. package/dist/core/route-table.d.ts.map +1 -1
  64. package/dist/core/route-table.js +1 -1
  65. package/dist/core/route-table.js.map +1 -1
  66. package/dist/core/runtime/request-handler.d.ts +42 -0
  67. package/dist/core/runtime/request-handler.d.ts.map +1 -0
  68. package/dist/core/runtime/request-handler.js +187 -0
  69. package/dist/core/runtime/request-handler.js.map +1 -0
  70. package/dist/core/runtime/server.d.ts +41 -0
  71. package/dist/core/runtime/server.d.ts.map +1 -0
  72. package/dist/core/runtime/server.js +155 -0
  73. package/dist/core/runtime/server.js.map +1 -0
  74. package/dist/core/streaming/sse.d.ts +35 -0
  75. package/dist/core/streaming/sse.d.ts.map +1 -0
  76. package/dist/core/streaming/sse.js +121 -0
  77. package/dist/core/streaming/sse.js.map +1 -0
  78. package/dist/core/symbols.d.ts +14 -0
  79. package/dist/core/symbols.d.ts.map +1 -0
  80. package/dist/core/symbols.js +14 -0
  81. package/dist/core/symbols.js.map +1 -0
  82. package/dist/openapi/generate.d.ts.map +1 -1
  83. package/dist/openapi/generate.js +2 -0
  84. package/dist/openapi/generate.js.map +1 -1
  85. package/dist/server/static.d.ts +45 -0
  86. package/dist/server/static.d.ts.map +1 -0
  87. package/dist/server/static.js +204 -0
  88. package/dist/server/static.js.map +1 -0
  89. package/dist/utils/content-type.d.ts.map +1 -1
  90. package/dist/utils/content-type.js +26 -6
  91. package/dist/utils/content-type.js.map +1 -1
  92. package/dist/utils/mime.d.ts +2 -0
  93. package/dist/utils/mime.d.ts.map +1 -0
  94. package/dist/utils/mime.js +52 -0
  95. package/dist/utils/mime.js.map +1 -0
  96. package/package.json +1 -1
package/README.md CHANGED
@@ -35,6 +35,7 @@ await app.listen({ port: 3000 });
35
35
  - [Mapeamento manual](#mapeamento-manual)
36
36
  - [Schemas: validação, serialização e tipos](#schemas-validação-serialização-e-tipos)
37
37
  - [Respostas e o `ctx`](#respostas-e-o-ctx)
38
+ - [Arquivos estáticos e streaming](#arquivos-estáticos-e-streaming)
38
39
  - [Middlewares e guards](#middlewares-e-guards)
39
40
  - [Hooks de ciclo de vida](#hooks-de-ciclo-de-vida)
40
41
  - [Erros](#erros)
@@ -348,6 +349,78 @@ Outros campos: `ctx.params`, `ctx.query`, `ctx.body`, `ctx.state`, `ctx.id`, `ct
348
349
 
349
350
  > ⚠️ `ctx.send` não faz escape de HTML; escape o conteúdo dinâmico antes. `ctx.redirect` com uma URL vinda do usuário abre um _open redirect_; valide o destino.
350
351
 
352
+ ## Arquivos estáticos e streaming
353
+
354
+ ### Arquivos estáticos
355
+
356
+ ```ts
357
+ app.static('/assets', './public', { maxAge: '7d', immutable: true });
358
+ app.static('/', './dist', { fallback: 'index.html' }); // SPA (use securityHeaders: 'web')
359
+
360
+ app.group({ host: 'cdn.exemplo.com', guards: [auth] }, (g) => g.static('/files', './uploads'));
361
+ ```
362
+
363
+ - **São rotas de verdade (`GET`/`HEAD prefix/*`):** valem `group()` (host, guards, middlewares), 404/405 e a checagem de conflitos. Não entram no OpenAPI.
364
+ - **Segurança:**
365
+ - o caminho precisa ficar dentro da raiz, inclusive depois de seguir symlinks;
366
+ - `..` (também codificado), barra invertida e byte nulo são recusados;
367
+ - arquivos ocultos (`.env`, `.git`) respondem 404 por padrão (`dotfiles: 'allow'` libera);
368
+ - diretórios nunca são listados (o `index`, padrão `index.html`, é servido quando existe).
369
+ - **HTTP:**
370
+ - `ETag` e `Last-Modified`, com 304 para `If-None-Match` e `If-Modified-Since`;
371
+ - `Range` de um intervalo (206, ou 416 fora do arquivo), com `If-Range`, para vídeo e downloads retomáveis;
372
+ - `Cache-Control` por `maxAge` (`'7d'`, `'12h'`, segundos) e `immutable`;
373
+ - `Content-Type` por uma tabela interna, ampliável com `mimeTypes`.
374
+ - **SPA:** `fallback` serve o arquivo só quando o path **não tem extensão** (`/pedidos/42` → `index.html`), com `no-cache`. Um asset que falta (`/app.js`) continua 404.
375
+ - **Raiz inexistente ou `maxAge` inválido** falham na configuração.
376
+ - **Páginas HTML:** os headers de segurança padrão (`'api'`) bloqueiam scripts. Para servir uma SPA, use `createApp({ securityHeaders: 'web' })`.
377
+
378
+ Num handler, para downloads controlados pela aplicação:
379
+
380
+ ```ts
381
+ @Get('/reports/:id')
382
+ download(ctx: Context<'/reports/:id'>) {
383
+ return ctx.sendFile(`${ctx.params.id}.pdf`, { root: './reports', download: 'relatório.pdf' });
384
+ }
385
+ ```
386
+
387
+ Com `root`, o path é relativo e não pode sair dela. Sem `root`, ele precisa ser absoluto. `download` envia `Content-Disposition: attachment`, com o nome em UTF-8.
388
+
389
+ **Compressão:** fica a cargo da aplicação ou da infraestrutura (proxy, CDN). O core não comprime respostas.
390
+
391
+ ### Server-Sent Events
392
+
393
+ ```ts
394
+ @Get('/events')
395
+ events(ctx: Context) {
396
+ const stream = ctx.sse({ heartbeatMs: 15_000 });
397
+ const off = bus.on('order', (o) => stream.send({ event: 'order', id: o.id, data: o }));
398
+ stream.onClose(off);
399
+ }
400
+ ```
401
+
402
+ - **Headers:** já vêm configurados, inclusive `X-Accel-Buffering: no` para o Nginx não segurar os eventos.
403
+ - **Eventos:** `data` em objeto vira JSON, e texto com várias linhas é dividido. `event` e `id` com quebra de linha geram erro, porque seria injeção de evento.
404
+ - **Conexão:** o heartbeat (`: ping`) mantém a conexão viva atrás de proxies. `stream.lastEventId` traz o `Last-Event-ID` da reconexão.
405
+ - **Encerramento:** `stream.onClose()` roda quando o cliente desconecta, quando o handler chama `close()` ou quando o app encerra.
406
+
407
+ ### Respostas em stream
408
+
409
+ - **`Readable`:** `ctx.send(readable, type)` ou `return readable`, com backpressure.
410
+ - **Async iterable → NDJSON:** um handler que retorna um async generator (ou um cursor de banco) responde em `application/x-ndjson`, uma linha JSON por item:
411
+
412
+ ```ts
413
+ @Get('/export', { response: { 200: { contentType: 'application/x-ndjson', schema: Row } } })
414
+ async *export(ctx: Context) { for await (const row of db.cursor({ signal: ctx.signal })) yield row; }
415
+ ```
416
+
417
+ Com schema, cada item é validado e os campos não declarados são removidos. Uma rota com schema JSON comum que retorna um iterable gera erro, orientando a declarar `application/x-ndjson`.
418
+
419
+ ### `ctx.signal` e encerramento
420
+
421
+ - **`ctx.signal`** é um `AbortSignal` cancelado quando o cliente desconecta antes do fim da resposta. Passe-o a consultas e `fetch` longos, para não continuar um trabalho que ninguém vai ler.
422
+ - **No shutdown:** os streams já iniciados (SSE, NDJSON) recebem o cancelamento e fecham na hora, em vez de segurar o encerramento até o prazo. Requisições comuns continuam até terminar.
423
+
351
424
  ## Middlewares e guards
352
425
 
353
426
  Middlewares seguem o modelo do Koa: `(ctx, next) => Promise<void>`.
@@ -750,7 +823,7 @@ Checklist:
750
823
  | `logRequests` | `false` | Log de cada requisição concluída |
751
824
  | `requestId` | header `x-request-id` | `header`, `trustIncoming`, `generate` |
752
825
 
753
- Métodos do app: `use()`, `mount()`, `group()`, `health()`, `openapi()`, `openapiDocument()`, `onError()`, `onSend()`, `onResponse()`, `onClose()`, `listen()`, `close()`, `callback()`, `inject()`, `log`. O `mount()` devolve um `MountedGroup`, com os verbos do mapeamento manual e os mesmos métodos do app, para continuar o encadeamento.
826
+ Métodos do app: `use()`, `mount()`, `group()`, `static()`, `health()`, `openapi()`, `openapiDocument()`, `onError()`, `onSend()`, `onResponse()`, `onClose()`, `listen()`, `close()`, `callback()`, `inject()`, `log`. O `mount()` devolve um `MountedGroup`, com os verbos do mapeamento manual e os mesmos métodos do app, para continuar o encadeamento.
754
827
 
755
828
  O body só é lido como JSON quando o `Content-Type` é `application/json` ou `application/*+json`.
756
829
 
@@ -0,0 +1,23 @@
1
+ import type http from 'node:http';
2
+ import type { Middleware } from '../compose.ts';
3
+ import type { Context, OnSendHook } from '../context.ts';
4
+ import type { Logger } from '../logger.ts';
5
+ import type { Serializer } from '../response/pipeline.ts';
6
+ import type { AppOptions, OnCloseHook, OnResponseHook } from './options.ts';
7
+ /**
8
+ * Estado compartilhado do app entre a fachada (`SashikoApp`) e os componentes internos (registro,
9
+ * servidor, pipeline da requisição). Só configuração e listas de hooks; nada por requisição.
10
+ */
11
+ export interface AppCore {
12
+ readonly opts: AppOptions;
13
+ readonly log: Logger;
14
+ readonly middlewares: Middleware[];
15
+ readonly errorHandlers: ((err: unknown, ctx: Context) => void | Promise<void>)[];
16
+ readonly onSendHooks: OnSendHook[];
17
+ readonly onResponseHooks: OnResponseHook[];
18
+ readonly onCloseHooks: OnCloseHook[];
19
+ readonly serializers: ReadonlyMap<string, Serializer>;
20
+ readonly allowedHosts: ((hostname: string, host: string) => boolean) | undefined;
21
+ readonly applySecurityHeaders: ((res: http.ServerResponse) => void) | undefined;
22
+ }
23
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/core/app/core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE5E;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC;IACnC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;IACjF,QAAQ,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,WAAW,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACtD,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;IACjF,QAAQ,CAAC,oBAAoB,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACjF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/core/app/core.ts"],"names":[],"mappings":""}
@@ -0,0 +1,109 @@
1
+ import type { Context } from '../context.ts';
2
+ import type { ErrorFormatter } from '../errors.ts';
3
+ import type { Logger } from '../logger.ts';
4
+ import type { Serializer } from '../response/pipeline.ts';
5
+ import type { ShutdownOptions } from '../shutdown.ts';
6
+ import type { TlsOptions } from '../../server/tls.ts';
7
+ import type { ProtoPoisoning } from '../../utils/safe-json.ts';
8
+ import type { SecurityHeadersOptions, SecurityPreset } from '../../middlewares/security-headers.ts';
9
+ /** Depois do envio da resposta (F-04). */
10
+ export type OnResponseHook = (ctx: Context, info: {
11
+ status: number;
12
+ ms: number;
13
+ }) => void | Promise<void>;
14
+ /** No `close()` do app (F-04). */
15
+ export type OnCloseHook = () => void | Promise<void>;
16
+ export interface ListenOptions {
17
+ /** Padrão: 3000. Use 0 para uma porta livre aleatória. */
18
+ port?: number;
19
+ /** Padrão: `127.0.0.1`. Use `0.0.0.0` para aceitar conexões externas (ex.: em containers). */
20
+ host?: string;
21
+ /**
22
+ * Sobe em HTTPS, com os mesmos timeouts, encerramento gracioso e `close()` do HTTP. Atrás de um
23
+ * proxy que termina o TLS (Caddy, Nginx, load balancer), não use: fique em HTTP com `trustProxy`.
24
+ */
25
+ tls?: TlsOptions;
26
+ }
27
+ export interface ServerTimeouts {
28
+ /** Tempo máximo para receber a requisição inteira. Padrão: 30s. */
29
+ requestTimeout?: number;
30
+ /** Tempo máximo para receber os headers (mitiga Slowloris). Padrão: 10s. */
31
+ headersTimeout?: number;
32
+ /** Tempo de conexão keep-alive ociosa. Padrão: 5s. */
33
+ keepAliveTimeout?: number;
34
+ }
35
+ export interface AppOptions {
36
+ /** Tamanho máximo do body JSON em bytes. Padrão: 1 MiB. */
37
+ bodyLimit?: number;
38
+ /**
39
+ * Headers de segurança aplicados a toda resposta (S-04). Padrão: `'api'`.
40
+ * `'web'` libera recursos do próprio site (CSP `'self'`) para quem serve páginas; `false` desliga.
41
+ */
42
+ securityHeaders?: SecurityHeadersOptions | SecurityPreset | false;
43
+ /**
44
+ * Serializadores por content type, para responder em outros formatos (F-31):
45
+ * `{ 'application/yaml': (data) => YAML.stringify(data) }`. JSON e valores crus já são nativos.
46
+ */
47
+ serializers?: Record<string, Serializer>;
48
+ /** Timeouts do servidor HTTP (S-06). */
49
+ timeouts?: ServerTimeouts;
50
+ /**
51
+ * Modo estrito (S-07): exige schema de `body` em POST/PUT/PATCH e schema de `response`
52
+ * em toda rota, falhando no `app.mount()`. Padrão: `false`.
53
+ */
54
+ requireSchemas?: boolean;
55
+ /**
56
+ * Body JSON com `__proto__` ou `constructor.prototype` (S-08): `'error'` responde 400
57
+ * (`PROTO_POISONING`); `'remove'` descarta as chaves e segue. Padrão: `'error'`.
58
+ */
59
+ protoPoisoning?: ProtoPoisoning;
60
+ /** Máximo de pares chave/valor lidos da query string. Padrão: 1000 (S-06). */
61
+ queryMaxKeys?: number;
62
+ /** Logger compatível com pino. Padrão: `consoleLogger()`; `false` desliga (F-06). */
63
+ logger?: Logger | false;
64
+ /** Loga cada requisição concluída (método, path, status, duração) em nível `info`. Padrão: `false`. */
65
+ logRequests?: boolean;
66
+ /** Request id (F-06). */
67
+ requestId?: RequestIdOptions;
68
+ /**
69
+ * Encerramento gracioso nos sinais do processo, ativado pelo `listen()` (F-07).
70
+ * Ligado por padrão (SIGINT/SIGTERM, 10s); `false` desliga.
71
+ */
72
+ shutdown?: ShutdownOptions | false;
73
+ /**
74
+ * Confia nos headers `X-Forwarded-For`, `-Host` e `-Proto` para `ctx.ip`, `ctx.host` e `ctx.protocol`
75
+ * (S-09). Padrão: `false`. Use `true` para confiar em toda a cadeia, ou o número de proxies à frente
76
+ * do app (ex.: `1` para um load balancer). Só ligue atrás de um proxy que reescreve esses headers.
77
+ */
78
+ trustProxy?: boolean | number;
79
+ /**
80
+ * Hosts aceitos (S-09). Requisições com outro `Host` (ou `X-Forwarded-Host` confiável) recebem 400.
81
+ * Protege contra host header injection e DNS rebinding. Padrão: qualquer host válido.
82
+ * - `'api.exemplo.com'` casa com o hostname (qualquer porta); `'api.exemplo.com:8443'` exige a porta;
83
+ * - `'*.exemplo.dev'` aceita só subdomínios;
84
+ * - uma RegExp precisa casar o hostname **inteiro** (como se tivesse `^…$`).
85
+ */
86
+ allowedHosts?: readonly (string | RegExp)[];
87
+ /**
88
+ * Rotas com `host` (virtual hosts) fora do `allowedHosts` nunca são alcançadas (F-35). `'error'` (padrão)
89
+ * falha no registro; `'warn'` só registra um aviso no log; `'off'` não confere.
90
+ */
91
+ unreachableHosts?: 'error' | 'warn' | 'off';
92
+ /**
93
+ * Personaliza o corpo de todos os erros do framework e dos `HttpError` (F-15). Padrão: Problem
94
+ * Details (RFC 9457) em `application/problem+json`. O retorno é enviado como `application/json`.
95
+ */
96
+ formatError?: ErrorFormatter;
97
+ }
98
+ export interface RequestIdOptions {
99
+ /** Header lido da requisição e devolvido na resposta. Padrão: `x-request-id`. `false` não envia. */
100
+ header?: string | false;
101
+ /**
102
+ * Reaproveita o id recebido no header (útil atrás de um gateway). Padrão: `true`.
103
+ * O valor só é aceito se tiver até 128 caracteres de `[A-Za-z0-9._:-]`, para evitar log injection.
104
+ */
105
+ trustIncoming?: boolean;
106
+ /** Gerador de ids. Padrão: `crypto.randomUUID()`. */
107
+ generate?: () => string;
108
+ }
109
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/core/app/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEpG,0CAA0C;AAC1C,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC1G,kCAAkC;AAClC,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,eAAe,CAAC,EAAE,sBAAsB,GAAG,cAAc,GAAG,KAAK,CAAC;IAClE;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzC,wCAAwC;IACxC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,uGAAuG;IACvG,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yBAAyB;IACzB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,GAAG,KAAK,CAAC;IACnC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC5C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;IAC5C;;;OAGG;IACH,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,oGAAoG;IACpG,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/core/app/options.ts"],"names":[],"mappings":""}
@@ -1,147 +1,29 @@
1
- import http from 'node:http';
2
- import https from 'node:https';
3
- import { type TlsOptions } from '../server/tls.ts';
1
+ import type http from 'node:http';
2
+ import type https from 'node:https';
3
+ import '../shims/symbol-metadata.ts';
4
+ import type { TlsOptions } from '../server/tls.ts';
4
5
  import { type GroupOptions, type MountOptions, type RouteScope, type RouterRef } from './compiler.ts';
5
- import { RouteGroupScope } from './mounted-group.ts';
6
- import { MountedGroup } from './mounted-group.ts';
7
- import { type Middleware } from './compose.ts';
8
- import { Context, type OnSendHook } from './context.ts';
6
+ import { MountedGroup, RouteGroupScope } from './mounted-group.ts';
7
+ import type { Middleware } from './compose.ts';
8
+ import type { Context, OnSendHook } from './context.ts';
9
+ import { type StaticOptions } from '../server/static.ts';
9
10
  import { type OpenAPIOptions } from '../openapi/generate.ts';
10
11
  import { type HealthOptions } from './health.ts';
11
- import '../shims/symbol-metadata.ts';
12
- import type { ProtoPoisoning } from '../utils/safe-json.ts';
13
- import { type Serializer } from './response.ts';
14
- import type { ErrorFormatter } from './errors.ts';
15
12
  import { type InjectOptions, type InjectResponse } from './inject.ts';
16
- import { type ShutdownOptions } from './shutdown.ts';
17
13
  import { type Logger } from './logger.ts';
18
- import { type SecurityHeadersOptions, type SecurityPreset } from '../middlewares/security-headers.ts';
19
- /** Depois do envio da resposta (F-04). */
20
- export type OnResponseHook = (ctx: Context, info: {
21
- status: number;
22
- ms: number;
23
- }) => void | Promise<void>;
24
- /** No `close()` do app (F-04). */
25
- export type OnCloseHook = () => void | Promise<void>;
26
- export interface ListenOptions {
27
- /** Padrão: 3000. Use 0 para uma porta livre aleatória. */
28
- port?: number;
29
- /** Padrão: `127.0.0.1`. Use `0.0.0.0` para aceitar conexões externas (ex.: em containers). */
30
- host?: string;
31
- /**
32
- * Sobe em HTTPS, com os mesmos timeouts, encerramento gracioso e `close()` do HTTP. Atrás de um
33
- * proxy que termina o TLS (Caddy, Nginx, load balancer), não use: fique em HTTP com `trustProxy`.
34
- */
35
- tls?: TlsOptions;
36
- }
37
- export interface ServerTimeouts {
38
- /** Tempo máximo para receber a requisição inteira. Padrão: 30s. */
39
- requestTimeout?: number;
40
- /** Tempo máximo para receber os headers (mitiga Slowloris). Padrão: 10s. */
41
- headersTimeout?: number;
42
- /** Tempo de conexão keep-alive ociosa. Padrão: 5s. */
43
- keepAliveTimeout?: number;
44
- }
45
- export interface AppOptions {
46
- /** Tamanho máximo do body JSON em bytes. Padrão: 1 MiB. */
47
- bodyLimit?: number;
48
- /**
49
- * Headers de segurança aplicados a toda resposta (S-04). Padrão: `'api'`.
50
- * `'web'` libera recursos do próprio site (CSP `'self'`) para quem serve páginas; `false` desliga.
51
- */
52
- securityHeaders?: SecurityHeadersOptions | SecurityPreset | false;
53
- /**
54
- * Serializadores por content type, para responder em outros formatos (F-31):
55
- * `{ 'application/yaml': (data) => YAML.stringify(data) }`. JSON e valores crus já são nativos.
56
- */
57
- serializers?: Record<string, Serializer>;
58
- /** Timeouts do servidor HTTP (S-06). */
59
- timeouts?: ServerTimeouts;
60
- /**
61
- * Modo estrito (S-07): exige schema de `body` em POST/PUT/PATCH e schema de `response`
62
- * em toda rota, falhando no `app.mount()`. Padrão: `false`.
63
- */
64
- requireSchemas?: boolean;
65
- /**
66
- * Body JSON com `__proto__` ou `constructor.prototype` (S-08): `'error'` responde 400
67
- * (`PROTO_POISONING`); `'remove'` descarta as chaves e segue. Padrão: `'error'`.
68
- */
69
- protoPoisoning?: ProtoPoisoning;
70
- /** Máximo de pares chave/valor lidos da query string. Padrão: 1000 (S-06). */
71
- queryMaxKeys?: number;
72
- /** Logger compatível com pino. Padrão: `consoleLogger()`; `false` desliga (F-06). */
73
- logger?: Logger | false;
74
- /** Loga cada requisição concluída (método, path, status, duração) em nível `info`. Padrão: `false`. */
75
- logRequests?: boolean;
76
- /** Request id (F-06). */
77
- requestId?: RequestIdOptions;
78
- /**
79
- * Encerramento gracioso nos sinais do processo, ativado pelo `listen()` (F-07).
80
- * Ligado por padrão (SIGINT/SIGTERM, 10s); `false` desliga.
81
- */
82
- shutdown?: ShutdownOptions | false;
83
- /**
84
- * Confia nos headers `X-Forwarded-For`, `-Host` e `-Proto` para `ctx.ip`, `ctx.host` e `ctx.protocol`
85
- * (S-09). Padrão: `false`. Use `true` para confiar em toda a cadeia, ou o número de proxies à frente
86
- * do app (ex.: `1` para um load balancer). Só ligue atrás de um proxy que reescreve esses headers.
87
- */
88
- trustProxy?: boolean | number;
89
- /**
90
- * Hosts aceitos (S-09). Requisições com outro `Host` (ou `X-Forwarded-Host` confiável) recebem 400.
91
- * Protege contra host header injection e DNS rebinding. Padrão: qualquer host válido.
92
- * - `'api.exemplo.com'` casa com o hostname (qualquer porta); `'api.exemplo.com:8443'` exige a porta;
93
- * - `'*.exemplo.dev'` aceita só subdomínios;
94
- * - uma RegExp precisa casar o hostname **inteiro** (como se tivesse `^…$`).
95
- */
96
- allowedHosts?: readonly (string | RegExp)[];
97
- /**
98
- * Rotas com `host` (virtual hosts) fora do `allowedHosts` nunca são alcançadas (F-35). `'error'` (padrão)
99
- * falha no registro; `'warn'` só registra um aviso no log; `'off'` não confere.
100
- */
101
- unreachableHosts?: 'error' | 'warn' | 'off';
102
- /**
103
- * Personaliza o corpo de todos os erros do framework e dos `HttpError` (F-15). Padrão: Problem
104
- * Details (RFC 9457) em `application/problem+json`. O retorno é enviado como `application/json`.
105
- */
106
- formatError?: ErrorFormatter;
107
- }
108
- export interface RequestIdOptions {
109
- /** Header lido da requisição e devolvido na resposta. Padrão: `x-request-id`. `false` não envia. */
110
- header?: string | false;
111
- /**
112
- * Reaproveita o id recebido no header (útil atrás de um gateway). Padrão: `true`.
113
- * O valor só é aceito se tiver até 128 caracteres de `[A-Za-z0-9._:-]`, para evitar log injection.
114
- */
115
- trustIncoming?: boolean;
116
- /** Gerador de ids. Padrão: `crypto.randomUUID()`. */
117
- generate?: () => string;
118
- }
14
+ import type { AppOptions, ListenOptions, OnCloseHook, OnResponseHook } from './app/options.ts';
15
+ export type { AppOptions, ListenOptions, OnCloseHook, OnResponseHook, RequestIdOptions, ServerTimeouts } from './app/options.ts';
16
+ /**
17
+ * O app. É uma fachada (Facade) sobre o registro de rotas, as rotas do próprio framework (health, OpenAPI),
18
+ * o servidor e o pipeline da requisição: a API pública fica aqui, e o trabalho fica nesses componentes.
19
+ */
119
20
  export declare class SashikoApp {
120
- private middlewares;
121
- private router;
122
- private errorHandlers;
123
- private readonly onSendHooks;
124
- private readonly onResponseHooks;
125
- private readonly onCloseHooks;
126
- private readonly routes;
127
- /** Registros pendentes de um `group()` em andamento (duas fases). */
128
- private pending;
129
- private readonly warnedHosts;
130
- private draining;
131
- private healthConfig;
132
- private openapiConfig;
133
- private closeHooksPending;
134
- private applySecurityHeaders;
135
- private readonly opts;
136
- private readonly allowedHosts;
137
- private readonly serializers;
138
- private server;
139
- private tlsState;
140
- /** Respostas em andamento, para o encerramento gracioso não travar em conexões keep-alive. */
141
- private readonly inflight;
142
- private closing;
143
- /** Logger do app (F-06). Use para logs fora de uma requisição. */
144
21
  readonly log: Logger;
22
+ private readonly core;
23
+ private readonly registry;
24
+ private readonly framework;
25
+ private readonly runtime;
26
+ private readonly requests;
145
27
  constructor(opts?: AppOptions);
146
28
  use(mw: Middleware): this;
147
29
  onError(h: (err: unknown, ctx: Context) => void | Promise<void>): this;
@@ -188,6 +70,19 @@ export declare class SashikoApp {
188
70
  group(options: GroupOptions, define: (group: RouteGroupScope) => unknown): this;
189
71
  /** @internal */
190
72
  groupIn(parent: RouteScope, options: GroupOptions, define: (group: RouteGroupScope) => unknown): void;
73
+ /**
74
+ * Serve os arquivos de `root` em `GET prefix/*` (F-13). É uma rota como as outras: vale `group()`
75
+ * (host, guards, middlewares), 404/405 e a checagem de conflitos. Não entra no OpenAPI.
76
+ *
77
+ * ```ts
78
+ * app.static('/assets', './public', { maxAge: '7d', immutable: true });
79
+ * app.static('/', './dist', { fallback: 'index.html' }); // SPA
80
+ * ```
81
+ * Caminhos que saem da raiz (`..`, symlinks), arquivos ocultos e diretórios sem índice respondem 404.
82
+ */
83
+ static(prefix: string, root: string, opts?: StaticOptions): this;
84
+ /** @internal */
85
+ staticIn(scope: RouteScope, prefix: string, root: string, opts: StaticOptions): void;
191
86
  /** @internal */
192
87
  mountIn(scope: RouteScope, ref: RouterRef, options?: MountOptions): MountedGroup<object>;
193
88
  /**
@@ -206,52 +101,20 @@ export declare class SashikoApp {
206
101
  * consumir rate limit); use `guards`/`middlewares` aqui para restringir.
207
102
  */
208
103
  health(opts?: HealthOptions): this;
209
- /** Paths servidos pelo próprio app (`health()`, `openapi()`), que encobririam uma rota GET do usuário. */
210
- private reservedPaths;
211
- /** Um path do framework não pode coincidir com uma rota GET/HEAD registrada nem com outro do framework. */
212
- private assertFreePaths;
213
104
  /**
214
105
  * Documento OpenAPI 3.1 das rotas registradas até agora, para gravar em arquivo ou testar (F-16).
215
106
  * Com virtual hosts, é por host (F-35): `{ host: 'api.exemplo.com' }` traz as rotas desse host e as sem
216
107
  * host; sem `host`, só as sem host. Domínios diferentes nunca se misturam num mesmo documento.
217
108
  */
218
109
  openapiDocument(opts?: OpenAPIOptions): Record<string, unknown>;
219
- /**
220
- * Rotas que o roteador **executaria** num host (F-35): para cada método e path, só a vencedora pela mesma
221
- * prioridade do roteador (exato → curinga mais específico → RegExp → sem host). Assim o OpenAPI documenta
222
- * exatamente o handler que responde. Sem `hostname`, só as rotas sem host.
223
- */
224
- private routesFor;
225
- /** Se a requisição é para `/openapi.json` ou `/docs` (quando ligados), responde e devolve `true`. */
226
- private serveOpenAPI;
227
- /**
228
- * Primeira fase: valida as rotas (schemas obrigatórios, hosts alcançáveis, conflitos com o roteador e
229
- * dentro do próprio lote). Dentro de um `group()`, acumula; fora, efetiva na hora.
230
- */
231
- private stage;
232
- /**
233
- * Segunda fase: registra o lote no roteador. Se algo ainda falhar (um conflito que o `has()` não prevê),
234
- * desfaz o que já entrou, e nenhuma rota do lote fica registrada.
235
- */
236
- private commit;
237
- /**
238
- * Um host de rota sem interseção com o `allowedHosts` nunca seria alcançado: o app responde 400 antes do
239
- * roteamento (F-35). Comprovado: erro (ou aviso, com `unreachableHosts: 'warn'`). Sem como provar
240
- * (RegExp em algum dos lados): aviso.
241
- */
242
- private checkReachableHosts;
110
+ /** Executa o pipeline completo para um contexto já criado. */
243
111
  handle(ctx: Context): Promise<void>;
244
- /**
245
- * Executa os `onError` do usuário. Se um deles lançar, o erro é logado e seguimos
246
- * para a resposta padrão com o erro **original** — nunca deixamos a Promise rejeitar (B-08).
247
- */
248
- private runErrorHandlers;
249
112
  /**
250
113
  * Listener `(req, res)` do app, para usar com qualquer servidor do Node:
251
114
  * `https.createServer(opts, app.callback())`, `http2` em modo compat, testes etc. (F-09).
252
115
  */
253
116
  callback(): (req: http.IncomingMessage, res: http.ServerResponse) => void;
254
- /** Sobe o servidor HTTP e resolve quando ele está aceitando conexões (F-09). */
117
+ /** Sobe o servidor HTTP (ou HTTPS, com `tls`) e resolve quando ele está aceitando conexões (F-09, F-33). */
255
118
  listen(options: ListenOptions & {
256
119
  tls: TlsOptions;
257
120
  }): Promise<https.Server>;
@@ -261,15 +124,11 @@ export declare class SashikoApp {
261
124
  * usam os novos; as abertas seguem com os antigos. Um certificado inválido lança erro e mantém os atuais.
262
125
  */
263
126
  reloadTLS(tls: TlsOptions): void;
264
- /** Ponte entre este app e o coordenador de sinais (F-07). */
265
- private readonly shutdownTarget;
266
127
  /**
267
128
  * Para de aceitar conexões, encerra as ociosas e espera as requisições em andamento terminarem.
268
129
  * Depois de `graceMs`, força o fechamento das restantes.
269
130
  */
270
131
  close(graceMs?: number): Promise<void>;
271
- /** `onClose` uma vez por ciclo (até o próximo `listen`); todos rodam mesmo se algum falhar (F-04). */
272
- private runCloseHooks;
273
132
  /** Executa uma requisição em memória, sem rede. Ideal para testes (F-09). */
274
133
  inject(opts: InjectOptions | string): Promise<InjectResponse>;
275
134
  }
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/core/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/core/app.ts"],"names":[],"mappings":"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"}