sashiko 0.5.0 → 0.6.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
@@ -273,6 +273,9 @@ Os schemas de resposta valem para o que o **handler** envia. Middlewares e guard
273
273
  | `ctx.text(str)` | `text/plain; charset=utf-8`, pelo pipeline |
274
274
  | `ctx.send(body, contentType?)` | Qualquer corpo pelo pipeline: string, bytes, stream ou objeto (negociado pelo `Accept`) |
275
275
  | `ctx.redirect(url, status?)` | 302 por padrão; aceita 301, 303, 307, 308 |
276
+ | `ctx.cookies` | Cookies da requisição (objeto sem protótipo) |
277
+ | `ctx.setCookie(name, value, opts?)` | Adiciona um `Set-Cookie`, com `HttpOnly`, `Secure`, `SameSite=Lax` e `Path=/` por padrão |
278
+ | `ctx.clearCookie(name, opts?)` | Remove um cookie (use o mesmo `path` e `domain` da criação) |
276
279
  | `ctx.throw(status, message)` | Lança um `HttpError` |
277
280
 
278
281
  Outros campos: `ctx.params`, `ctx.query`, `ctx.body`, `ctx.state`, `ctx.id`, `ctx.log`, `ctx.sentBody`, `ctx.sentType`, `ctx.ip`, `ctx.host`, `ctx.hostname`, `ctx.protocol`, `ctx.method`, `ctx.path`, `ctx.url`, `ctx.req` e `ctx.res`.
@@ -392,7 +395,7 @@ Ligado por padrão:
392
395
  Opt-in:
393
396
 
394
397
  ```ts
395
- import { cors, createApp, rateLimit } from 'sashiko';
398
+ import { cors, createApp, csrf, rateLimit } from 'sashiko';
396
399
 
397
400
  createApp({
398
401
  requireSchemas: true,
@@ -416,7 +419,15 @@ createApp({
416
419
  - **Prefira o curinga à RegExp:** uma regex mal escrita pode ser lenta com uma entrada maliciosa (ReDoS).
417
420
  - **Regras inválidas falham na inicialização,** por exemplo uma origem sem esquema (`'app.exemplo.com'`).
418
421
  - **`rateLimit()`:** guarda os contadores em memória por padrão. Para várias instâncias, implemente `RateLimitStore` (Redis etc.).
419
- - **Cookies e CSRF:** ainda não há proteção de CSRF embutida. Se a autenticação usar cookies, valide `Origin` num middleware e use `SameSite=Lax` ou `Strict`.
422
+ - **Cookies:** `ctx.setCookie()` usa `HttpOnly`, `Secure`, `SameSite=Lax` e `Path=/` por padrão (os navegadores aceitam `Secure` em `http://localhost`). Nome, `path` e `domain` são validados contra injeção de atributos, e os prefixos `__Host-` e `__Secure-` têm as regras conferidas.
423
+ - **`csrf()`: ative sempre que a autenticação usar cookies.** Métodos que alteram estado (todos menos GET, HEAD e OPTIONS) vindos de outra origem recebem 403. A checagem usa o `Sec-Fetch-Site` e, na falta dele, compara o `Origin` com a própria origem. Requisições sem esses headers (curl, servidor a servidor) passam, porque não há navegador para anexar os cookies da vítima.
424
+
425
+ ```ts
426
+ app.use(csrf()); // checagem de origem
427
+ app.use(csrf({ trustedOrigins: ['https://app.exemplo.com'] })); // front em outra origem
428
+ app.use(csrf({ token: true })); // + double-submit token
429
+ ```
430
+ Com `token: true`, o middleware cria o cookie `__Host-csrf` (legível pelo JS, `SameSite=Strict`) e o expõe em `ctx.state.csrfToken`; o cliente o devolve no header `X-CSRF-Token`. Rotas GET nunca devem alterar estado.
420
431
  - **Atrás de proxy:** `ctx.ip`, `ctx.host` e `ctx.protocol` usam o socket e o `Host` por padrão. Com `trustProxy: 1` (o número de proxies à frente do app) ou `true` (toda a cadeia), passam a usar o `X-Forwarded-For`, o `-Host` e o `-Proto`. Só ligue isso atrás de um proxy que reescreve esses headers, porque o cliente pode forjá-los.
421
432
  - **`allowedHosts`:** com `allowedHosts: ['api.exemplo.com', '*.exemplo.dev']`, qualquer outro `Host` recebe 400. Protege contra host header injection e DNS rebinding. Um host sem porta aceita qualquer porta; com porta (`'api.exemplo.com:8443'`), exige a porta exata.
422
433
  - **Links absolutos** (reset de senha, redirects): prefira uma URL base da configuração em vez do host pedido pelo cliente.
@@ -1,5 +1,6 @@
1
1
  import type { IncomingMessage, OutgoingHttpHeader, ServerResponse } from 'node:http';
2
2
  import { Readable } from 'node:stream';
3
+ import { type CookieOptions } from '../utils/cookie.ts';
3
4
  import { type Logger } from './logger.ts';
4
5
  import type { InferBody, InferParams, InferQuery, InferResponse } from './infer.ts';
5
6
  import type { RouteSchemas } from './metadata.ts';
@@ -125,6 +126,16 @@ export declare class Context<S extends RouteSchemas = RouteSchemas> {
125
126
  get sent(): boolean;
126
127
  /** Lê um header da requisição (case-insensitive). Headers repetidos são unidos com `, `. */
127
128
  get(name: string): string | undefined;
129
+ private parsedCookies;
130
+ /** Cookies da requisição (objeto sem protótipo; em nomes repetidos vale o primeiro). */
131
+ get cookies(): Readonly<Record<string, string>>;
132
+ /**
133
+ * Adiciona um `Set-Cookie`. Padrões: `HttpOnly`, `Secure`, `SameSite=Lax` e `Path=/`.
134
+ * Se usar cookies para autenticar, ative também o middleware `csrf()`.
135
+ */
136
+ setCookie(name: string, value: string, opts?: CookieOptions): this;
137
+ /** Remove um cookie. Informe o mesmo `path` e `domain` usados ao criá-lo. */
138
+ clearCookie(name: string, opts?: Omit<CookieOptions, 'maxAge' | 'expires'>): this;
128
139
  /** Define um header da resposta. */
129
140
  header(name: string, value: OutgoingHttpHeader): this;
130
141
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { Readable } from 'node:stream';
2
2
  import { pipeline } from 'node:stream/promises';
3
3
  import { HttpError } from './errors.js';
4
4
  import { parseQuery } from '../utils/query.js';
5
+ import { parseCookies, serializeCookie } from '../utils/cookie.js';
5
6
  import { hostnameOf, isValidHost, parseRequestTarget, pickForwarded } from '../utils/request-target.js';
6
7
  import { silentLogger } from './logger.js';
7
8
  import { sendResult } from './response.js';
@@ -113,6 +114,23 @@ export class Context {
113
114
  const value = this.req.headers[name.toLowerCase()];
114
115
  return Array.isArray(value) ? value.join(', ') : value;
115
116
  }
117
+ parsedCookies;
118
+ /** Cookies da requisição (objeto sem protótipo; em nomes repetidos vale o primeiro). */
119
+ get cookies() {
120
+ return (this.parsedCookies ??= parseCookies(this.get('cookie')));
121
+ }
122
+ /**
123
+ * Adiciona um `Set-Cookie`. Padrões: `HttpOnly`, `Secure`, `SameSite=Lax` e `Path=/`.
124
+ * Se usar cookies para autenticar, ative também o middleware `csrf()`.
125
+ */
126
+ setCookie(name, value, opts) {
127
+ this.res.appendHeader('Set-Cookie', serializeCookie(name, value, opts));
128
+ return this;
129
+ }
130
+ /** Remove um cookie. Informe o mesmo `path` e `domain` usados ao criá-lo. */
131
+ clearCookie(name, opts = {}) {
132
+ return this.setCookie(name, '', { ...opts, maxAge: 0, expires: new Date(0) });
133
+ }
116
134
  /** Define um header da resposta. */
117
135
  header(name, value) {
118
136
  this.res.setHeader(name, value);
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ export type { Guard } from './guard.ts';
8
8
  export type { InferBody, InferHeaders, InferParams, InferQuery, InferResponse, InferSchema } from './infer.ts';
9
9
  export type { ShutdownOptions } from './shutdown.ts';
10
10
  export type { Serializer } from './response.ts';
11
+ export type { CookieOptions } from '../utils/cookie.ts';
11
12
  export { consoleLogger, silentLogger, type ConsoleLoggerOptions, type Logger, type LogLevel } from './logger.ts';
12
13
  export { Context, type BodyFor, type OnSendHook, type SendPayload, type ContextOptions, type ContextState, type DeclaredStatus, type StatusContext } from './context.ts';
13
14
  export { badRequest, forbidden, HttpError, internal, isHttpError, notFound, unauthorized, type HttpErrorOptions } from './errors.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACzK,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAClH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC/G,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,oBAAoB,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjH,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACzK,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACrI,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3L,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACzK,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAClH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC/G,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,oBAAoB,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjH,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACzK,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACrI,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3L,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,UAAU,EAA0H,MAAM,UAAU,CAAC;AAGzK,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMlD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAyD,MAAM,aAAa,CAAC;AACjH,OAAO,EAAE,OAAO,EAAoI,MAAM,cAAc,CAAC;AACzK,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAyB,MAAM,aAAa,CAAC;AACrI,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAyG,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,UAAU,EAA0H,MAAM,UAAU,CAAC;AAGzK,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAOlD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAyD,MAAM,aAAa,CAAC;AACjH,OAAO,EAAE,OAAO,EAAoI,MAAM,cAAc,CAAC;AACzK,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAyB,MAAM,aAAa,CAAC;AACrI,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAyG,MAAM,eAAe,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { Middleware } from '../core/compose.ts';
2
+ import { type CookieOptions } from '../utils/cookie.ts';
3
+ import { type MatchRule } from '../utils/origin-match.ts';
4
+ declare module '../core/context.ts' {
5
+ interface ContextState {
6
+ /** Token CSRF da requisição, com `csrf({ token: true })`. Envie-o ao front no header configurado. */
7
+ csrfToken?: string;
8
+ }
9
+ }
10
+ export interface CsrfTokenOptions {
11
+ /** Padrão: `'__Host-csrf'`, que não pode ser definido por subdomínios. */
12
+ cookieName?: string;
13
+ /** Header onde o cliente devolve o token. Padrão: `'X-CSRF-Token'`. */
14
+ headerName?: string;
15
+ /** Atributos do cookie. `httpOnly` é sempre `false` (o front precisa ler) e `SameSite` padrão é `Strict`. */
16
+ cookie?: Omit<CookieOptions, 'httpOnly'>;
17
+ }
18
+ export interface CsrfOptions {
19
+ /**
20
+ * Outras origens confiáveis além da própria (`ctx.protocol://ctx.host`), com as mesmas regras do
21
+ * `cors()`: `'https://app.exemplo.com'`, `'https://*.exemplo.dev'` ou RegExp de casamento inteiro.
22
+ */
23
+ trustedOrigins?: readonly MatchRule[];
24
+ /** Ativa também o double-submit token. `true` usa os padrões de {@link CsrfTokenOptions}. */
25
+ token?: boolean | CsrfTokenOptions;
26
+ }
27
+ /**
28
+ * Proteção contra CSRF. Use sempre que a autenticação for por cookie.
29
+ *
30
+ * Métodos que alteram estado (todos menos GET, HEAD e OPTIONS) são recusados com 403 quando vêm de
31
+ * outra origem:
32
+ * 1. `Sec-Fetch-Site: same-origin` ou `none` (navegação do próprio usuário) passa; `same-site` e
33
+ * `cross-site` só passam se o `Origin` estiver em `trustedOrigins`;
34
+ * 2. sem `Sec-Fetch-Site`, o `Origin` precisa ser a própria origem ou uma confiável;
35
+ * 3. sem nenhum dos dois, a requisição não veio de um navegador (curl, servidor a servidor) e passa,
36
+ * porque CSRF depende de um navegador que anexe os cookies da vítima.
37
+ *
38
+ * Com `token`, além disso, exige o double-submit: o valor do header deve ser igual ao do cookie.
39
+ * Por isso, rotas GET nunca devem alterar estado.
40
+ */
41
+ export declare function csrf(opts?: CsrfOptions): Middleware;
42
+ //# sourceMappingURL=csrf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.d.ts","sourceRoot":"","sources":["../../src/middlewares/csrf.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAyC,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAEjG,OAAO,QAAQ,oBAAoB,CAAC;IAClC,UAAU,YAAY;QACpB,qGAAqG;QACrG,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;CACF;AAED,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6GAA6G;IAC7G,MAAM,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,6FAA6F;IAC7F,KAAK,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;CACpC;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAAC,IAAI,GAAE,WAAgB,GAAG,UAAU,CAgCvD"}
@@ -0,0 +1,70 @@
1
+ import { randomBytes, timingSafeEqual } from 'node:crypto';
2
+ import { HttpError } from '../core/errors.js';
3
+ import { serializeCookie } from '../utils/cookie.js';
4
+ import { compileOriginMatcher, normalizeOrigin } from '../utils/origin-match.js';
5
+ const SAFE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);
6
+ /**
7
+ * Proteção contra CSRF. Use sempre que a autenticação for por cookie.
8
+ *
9
+ * Métodos que alteram estado (todos menos GET, HEAD e OPTIONS) são recusados com 403 quando vêm de
10
+ * outra origem:
11
+ * 1. `Sec-Fetch-Site: same-origin` ou `none` (navegação do próprio usuário) passa; `same-site` e
12
+ * `cross-site` só passam se o `Origin` estiver em `trustedOrigins`;
13
+ * 2. sem `Sec-Fetch-Site`, o `Origin` precisa ser a própria origem ou uma confiável;
14
+ * 3. sem nenhum dos dois, a requisição não veio de um navegador (curl, servidor a servidor) e passa,
15
+ * porque CSRF depende de um navegador que anexe os cookies da vítima.
16
+ *
17
+ * Com `token`, além disso, exige o double-submit: o valor do header deve ser igual ao do cookie.
18
+ * Por isso, rotas GET nunca devem alterar estado.
19
+ */
20
+ export function csrf(opts = {}) {
21
+ const trusted = compileOriginMatcher(opts.trustedOrigins ?? []);
22
+ const token = opts.token ? (opts.token === true ? {} : opts.token) : undefined;
23
+ const cookieName = token?.cookieName ?? '__Host-csrf';
24
+ const headerName = (token?.headerName ?? 'X-CSRF-Token').toLowerCase();
25
+ const cookieOpts = { sameSite: 'Strict', ...token?.cookie, httpOnly: false };
26
+ // Valida nome e atributos já na criação, e não na primeira requisição.
27
+ if (token)
28
+ serializeCookie(cookieName, 'x', cookieOpts);
29
+ return async (ctx, next) => {
30
+ const safe = SAFE_METHODS.has(ctx.method);
31
+ if (!safe && !originAllowed(ctx, trusted)) {
32
+ throw new HttpError(403, 'Cross-origin request blocked', 'CSRF_ORIGIN');
33
+ }
34
+ if (token) {
35
+ const current = ctx.cookies[cookieName];
36
+ if (!safe) {
37
+ const sent = ctx.get(headerName);
38
+ if (!current || !sent || !equal(current, sent)) {
39
+ throw new HttpError(403, 'Invalid CSRF token', 'CSRF_TOKEN');
40
+ }
41
+ }
42
+ if (current && current.length >= 32) {
43
+ ctx.state.csrfToken = current;
44
+ }
45
+ else {
46
+ ctx.state.csrfToken = randomBytes(32).toString('base64url');
47
+ ctx.setCookie(cookieName, ctx.state.csrfToken, cookieOpts);
48
+ }
49
+ }
50
+ await next();
51
+ };
52
+ }
53
+ function originAllowed(ctx, trusted) {
54
+ const origin = ctx.get('origin');
55
+ const site = ctx.get('sec-fetch-site');
56
+ if (site === 'same-origin' || site === 'none')
57
+ return true;
58
+ if (site !== undefined)
59
+ return origin !== undefined && trusted(origin);
60
+ if (origin === undefined)
61
+ return true;
62
+ const own = ctx.host ? normalizeOrigin(`${ctx.protocol}://${ctx.host}`) : undefined;
63
+ return (own !== undefined && normalizeOrigin(origin) === own) || trusted(origin);
64
+ }
65
+ function equal(a, b) {
66
+ const x = Buffer.from(a);
67
+ const y = Buffer.from(b);
68
+ return x.length === y.length && timingSafeEqual(x, y);
69
+ }
70
+ //# sourceMappingURL=csrf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.js","sourceRoot":"","sources":["../../src/middlewares/csrf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG3D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAsB,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAkB,MAAM,0BAA0B,CAAC;AA4BjG,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAEzD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,IAAI,CAAC,IAAI,GAAgB,EAAE;IACzC,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,MAAM,UAAU,GAAG,KAAK,EAAE,UAAU,IAAI,aAAa,CAAC;IACtD,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,UAAU,IAAI,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;IACvE,MAAM,UAAU,GAAkB,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC5F,uEAAuE;IACvE,IAAI,KAAK;QAAE,eAAe,CAAC,UAAU,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;IAExD,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,8BAA8B,EAAE,aAAa,CAAC,CAAC;QAC1E,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACjC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;oBAC/C,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,oBAAoB,EAAE,YAAY,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;YACD,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;gBACpC,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG,OAAO,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAC5D,GAAG,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QACD,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,GAAY,EAAE,OAAoC;IACvE,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACvC,IAAI,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC3D,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACvE,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,GAAG,CAAC,QAAQ,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpF,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,eAAe,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,KAAK,CAAC,CAAS,EAAE,CAAS;IACjC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export { cors, type CorsOptions, type CorsOrigin } from './cors.ts';
2
2
  export { MemoryRateLimitStore, rateLimit, type RateLimitOptions, type RateLimitStore } from './rate-limit.ts';
3
3
  export { buildSecurityHeaders, type SecurityHeadersOptions, type SecurityPreset } from './security-headers.ts';
4
+ export { csrf, type CsrfOptions, type CsrfTokenOptions } from './csrf.ts';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middlewares/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC9G,OAAO,EAAE,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middlewares/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC9G,OAAO,EAAE,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC/G,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export { cors } from './cors.js';
2
2
  export { MemoryRateLimitStore, rateLimit } from './rate-limit.js';
3
3
  export { buildSecurityHeaders } from './security-headers.js';
4
+ export { csrf } from './csrf.js';
4
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middlewares/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAqC,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAA8C,MAAM,iBAAiB,CAAC;AAC9G,OAAO,EAAE,oBAAoB,EAAoD,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middlewares/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAqC,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAA8C,MAAM,iBAAiB,CAAC;AAC9G,OAAO,EAAE,oBAAoB,EAAoD,MAAM,uBAAuB,CAAC;AAC/G,OAAO,EAAE,IAAI,EAA2C,MAAM,WAAW,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Leitura e escrita de cookies (RFC 6265), seguras por padrão.
3
+ *
4
+ * - **Leitura:** o resultado é um objeto sem protótipo (`__proto__` vira um cookie comum, sem poluir
5
+ * nada); em nomes repetidos vale o primeiro, como nos navegadores; um valor com `%` inválido fica cru.
6
+ * - **Escrita:** `HttpOnly`, `Secure`, `SameSite=Lax` e `Path=/` por padrão. Nome, `Domain` e `Path`
7
+ * são validados (sem `;`, quebra de linha nem caracteres de controle), então não dá para injetar
8
+ * atributos. O valor é codificado com `encodeURIComponent`.
9
+ * - **Prefixos:** `__Host-` exige `Secure`, `Path=/` e nenhum `Domain`; `__Secure-` exige `Secure`.
10
+ * `SameSite=None` exige `Secure`. Violações lançam erro na hora de definir o cookie.
11
+ */
12
+ export interface CookieOptions {
13
+ /** Padrão: `true`. Impede a leitura por JavaScript no navegador. */
14
+ httpOnly?: boolean;
15
+ /** Padrão: `true`. Os navegadores aceitam cookies `Secure` em `http://localhost`. */
16
+ secure?: boolean;
17
+ /** Padrão: `'Lax'`. `'None'` exige `secure`. */
18
+ sameSite?: 'Strict' | 'Lax' | 'None' | false;
19
+ /** Padrão: `'/'`. */
20
+ path?: string;
21
+ /** Sem `domain`, o cookie vale só para o host atual (o mais restrito). */
22
+ domain?: string;
23
+ /** Duração em segundos. `0` remove o cookie. */
24
+ maxAge?: number;
25
+ expires?: Date;
26
+ /** Cookie particionado (CHIPS), para uso em iframes de terceiros. Exige `secure`. */
27
+ partitioned?: boolean;
28
+ priority?: 'Low' | 'Medium' | 'High';
29
+ }
30
+ /** Lê o header `Cookie` num objeto sem protótipo. */
31
+ export declare function parseCookies(header: string | undefined): Record<string, string>;
32
+ /** Monta o valor de um header `Set-Cookie`, aplicando os padrões seguros. */
33
+ export declare function serializeCookie(name: string, value: string, opts?: CookieOptions): string;
34
+ //# sourceMappingURL=cookie.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie.d.ts","sourceRoot":"","sources":["../../src/utils/cookie.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qFAAqF;IACrF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;IAC7C,qBAAqB;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,qFAAqF;IACrF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACtC;AAOD,qDAAqD;AACrD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAa/E;AAWD,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,MAAM,CAoC7F"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Leitura e escrita de cookies (RFC 6265), seguras por padrão.
3
+ *
4
+ * - **Leitura:** o resultado é um objeto sem protótipo (`__proto__` vira um cookie comum, sem poluir
5
+ * nada); em nomes repetidos vale o primeiro, como nos navegadores; um valor com `%` inválido fica cru.
6
+ * - **Escrita:** `HttpOnly`, `Secure`, `SameSite=Lax` e `Path=/` por padrão. Nome, `Domain` e `Path`
7
+ * são validados (sem `;`, quebra de linha nem caracteres de controle), então não dá para injetar
8
+ * atributos. O valor é codificado com `encodeURIComponent`.
9
+ * - **Prefixos:** `__Host-` exige `Secure`, `Path=/` e nenhum `Domain`; `__Secure-` exige `Secure`.
10
+ * `SameSite=None` exige `Secure`. Violações lançam erro na hora de definir o cookie.
11
+ */
12
+ /** `token` da RFC 7230: o que um nome de cookie pode conter. */
13
+ const TOKEN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
14
+ /** Domain e Path: nada de `;`, controle (inclui CR/LF) nem DEL. */
15
+ const ATTR_VALUE = /^[^\x00-\x1f\x7f;]*$/;
16
+ /** Lê o header `Cookie` num objeto sem protótipo. */
17
+ export function parseCookies(header) {
18
+ const out = Object.create(null);
19
+ if (!header)
20
+ return out;
21
+ for (const part of header.split(';')) {
22
+ const eq = part.indexOf('=');
23
+ if (eq === -1)
24
+ continue;
25
+ const name = part.slice(0, eq).trim();
26
+ if (!name || name in out)
27
+ continue;
28
+ let value = part.slice(eq + 1).trim();
29
+ if (value.length >= 2 && value.startsWith('"') && value.endsWith('"'))
30
+ value = value.slice(1, -1);
31
+ out[name] = safeDecode(value);
32
+ }
33
+ return out;
34
+ }
35
+ function safeDecode(value) {
36
+ if (!value.includes('%'))
37
+ return value;
38
+ try {
39
+ return decodeURIComponent(value);
40
+ }
41
+ catch {
42
+ return value;
43
+ }
44
+ }
45
+ /** Monta o valor de um header `Set-Cookie`, aplicando os padrões seguros. */
46
+ export function serializeCookie(name, value, opts = {}) {
47
+ if (!TOKEN.test(name))
48
+ throw new Error(`[sashiko] invalid cookie name "${name}".`);
49
+ const httpOnly = opts.httpOnly ?? true;
50
+ const secure = opts.secure ?? true;
51
+ const sameSite = opts.sameSite ?? 'Lax';
52
+ const path = opts.path ?? '/';
53
+ if (!ATTR_VALUE.test(path))
54
+ throw new Error(`[sashiko] invalid cookie path "${path}".`);
55
+ if (opts.domain !== undefined && (!opts.domain || !ATTR_VALUE.test(opts.domain))) {
56
+ throw new Error(`[sashiko] invalid cookie domain "${opts.domain}".`);
57
+ }
58
+ if (sameSite === 'None' && !secure)
59
+ throw new Error(`[sashiko] cookie "${name}": SameSite=None requires secure.`);
60
+ if (opts.partitioned && !secure)
61
+ throw new Error(`[sashiko] cookie "${name}": partitioned requires secure.`);
62
+ if (name.startsWith('__Secure-') && !secure)
63
+ throw new Error(`[sashiko] cookie "${name}": the __Secure- prefix requires secure.`);
64
+ if (name.startsWith('__Host-') && (!secure || path !== '/' || opts.domain !== undefined)) {
65
+ throw new Error(`[sashiko] cookie "${name}": the __Host- prefix requires secure, path "/" and no domain.`);
66
+ }
67
+ let out = `${name}=${encodeURIComponent(value)}`;
68
+ if (opts.maxAge !== undefined) {
69
+ if (!Number.isFinite(opts.maxAge))
70
+ throw new Error(`[sashiko] cookie "${name}": invalid maxAge.`);
71
+ out += `; Max-Age=${Math.floor(opts.maxAge)}`;
72
+ }
73
+ if (opts.expires) {
74
+ if (Number.isNaN(opts.expires.getTime()))
75
+ throw new Error(`[sashiko] cookie "${name}": invalid expires.`);
76
+ out += `; Expires=${opts.expires.toUTCString()}`;
77
+ }
78
+ if (opts.domain !== undefined)
79
+ out += `; Domain=${opts.domain}`;
80
+ out += `; Path=${path}`;
81
+ if (httpOnly)
82
+ out += '; HttpOnly';
83
+ if (secure)
84
+ out += '; Secure';
85
+ if (sameSite)
86
+ out += `; SameSite=${sameSite}`;
87
+ if (opts.partitioned)
88
+ out += '; Partitioned';
89
+ if (opts.priority)
90
+ out += `; Priority=${opts.priority}`;
91
+ return out;
92
+ }
93
+ //# sourceMappingURL=cookie.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie.js","sourceRoot":"","sources":["../../src/utils/cookie.ts"],"names":[],"mappings":"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"}
@@ -3,4 +3,5 @@ export { joinPaths } from './path.ts';
3
3
  export { DEFAULT_MAX_QUERY_KEYS, parseQuery, type ParsedQuery } from './query.ts';
4
4
  export { hostnameOf, isValidHost, parseRequestTarget, pickForwarded } from './request-target.ts';
5
5
  export { compileHostMatcher, compileOriginMatcher, normalizeOrigin, toFullMatch, type MatchRule } from './origin-match.ts';
6
+ export { parseCookies, serializeCookie, type CookieOptions } from './cookie.ts';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,eAAe,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,eAAe,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC3H,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -3,4 +3,5 @@ export { joinPaths } from './path.js';
3
3
  export { DEFAULT_MAX_QUERY_KEYS, parseQuery } from './query.js';
4
4
  export { hostnameOf, isValidHost, parseRequestTarget, pickForwarded } from './request-target.js';
5
5
  export { compileHostMatcher, compileOriginMatcher, normalizeOrigin, toFullMatch } from './origin-match.js';
6
+ export { parseCookies, serializeCookie } from './cookie.js';
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAoB,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,eAAe,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAoB,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,eAAe,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAC3H,OAAO,EAAE,YAAY,EAAE,eAAe,EAAsB,MAAM,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sashiko",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Micro-framework HTTP para Node.js com decorators TC39 nativos, schema-first (TypeBox + Ajv) e defaults seguros.",
5
5
  "keywords": [
6
6
  "http",