@orkestrel/middleware 0.0.19 → 0.0.20
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 +16 -11
- package/dist/src/core/index.cjs +78 -60
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +150 -81
- package/dist/src/core/index.d.ts +150 -81
- package/dist/src/core/index.js +78 -60
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +43 -41
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +62 -60
- package/dist/src/server/index.d.ts +62 -60
- package/dist/src/server/index.js +43 -41
- package/dist/src/server/index.js.map +1 -1
- package/package.json +21 -22
package/dist/src/core/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Connection } from '@orkestrel/server';
|
|
2
|
-
import { CookieOptions } from '@orkestrel/server';
|
|
3
|
-
import { Encoding } from '@orkestrel/server';
|
|
4
|
-
import { Guard } from '@orkestrel/contract';
|
|
1
|
+
import type { Connection } from '@orkestrel/server';
|
|
2
|
+
import type { CookieOptions } from '@orkestrel/server';
|
|
3
|
+
import type { Encoding } from '@orkestrel/server';
|
|
4
|
+
import type { Guard } from '@orkestrel/contract';
|
|
5
5
|
import { JSONShape } from '@orkestrel/contract';
|
|
6
|
-
import { MiddlewareContext } from '@orkestrel/server';
|
|
7
|
-
import { MiddlewareHandler } from '@orkestrel/server';
|
|
6
|
+
import type { MiddlewareContext } from '@orkestrel/server';
|
|
7
|
+
import type { MiddlewareHandler } from '@orkestrel/server';
|
|
8
8
|
import { NumberShape } from '@orkestrel/contract';
|
|
9
9
|
import { StringShape } from '@orkestrel/contract';
|
|
10
|
-
import { TableInterface } from '@orkestrel/database';
|
|
11
|
-
import { TokenSecret } from '@orkestrel/server';
|
|
10
|
+
import type { TableInterface } from '@orkestrel/database';
|
|
11
|
+
import type { TokenSecret } from '@orkestrel/server';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Configures `createBearer` — bearer-token authentication.
|
|
@@ -18,9 +18,9 @@ import { TokenSecret } from '@orkestrel/server';
|
|
|
18
18
|
* token against (rotation-aware).
|
|
19
19
|
* - `header` — the header the token is read from; defaults to
|
|
20
20
|
* {@link DEFAULT_BEARER_HEADER}.
|
|
21
|
-
* - `scheme` — the scheme prefix stripped before verification
|
|
22
|
-
* insensitive); defaults to {@link DEFAULT_BEARER_SCHEME}. An empty
|
|
23
|
-
* means the whole header value is the raw token.
|
|
21
|
+
* - `scheme` — the scheme prefix stripped before verification
|
|
22
|
+
* (case-insensitive); defaults to {@link DEFAULT_BEARER_SCHEME}. An empty
|
|
23
|
+
* string means the whole header value is the raw token.
|
|
24
24
|
*/
|
|
25
25
|
export declare interface BearerOptions {
|
|
26
26
|
readonly secret: TokenSecret;
|
|
@@ -171,7 +171,7 @@ export declare function compressBytes(bytes: Uint8Array<ArrayBuffer>, encoding:
|
|
|
171
171
|
* - `threshold` — the minimum buffered body size (bytes) worth compressing;
|
|
172
172
|
* defaults to {@link DEFAULT_COMPRESSION_THRESHOLD}.
|
|
173
173
|
* - `encodings` — the codings offered, in preference order, intersected at
|
|
174
|
-
*
|
|
174
|
+
* construction with what the runtime's `CompressionStream` actually
|
|
175
175
|
* supports; defaults to {@link DEFAULT_COMPRESSION_ENCODINGS}.
|
|
176
176
|
* - `filter` — an optional per-response opt-out predicate (the BREACH
|
|
177
177
|
* posture escape hatch); a response the predicate declines is never
|
|
@@ -194,7 +194,7 @@ export declare interface CompressionOptions {
|
|
|
194
194
|
* even when a later skip declines to compress) → `negotiateEncoding` over
|
|
195
195
|
* `options.encodings` → {@link isCompressionNegotiated} → `isCompressibleType`
|
|
196
196
|
* on `Content-Type` → a fast skip when the response already carries a
|
|
197
|
-
* numeric `Content-Length`
|
|
197
|
+
* numeric `Content-Length` below `options.threshold` (avoids buffering a
|
|
198
198
|
* body known too small to be worth compressing) → buffer through
|
|
199
199
|
* `response.arrayBuffer()` → a threshold passthrough when the buffered size
|
|
200
200
|
* is still below `options.threshold` → `options.compress` → set
|
|
@@ -282,7 +282,8 @@ export declare interface CorsOptions {
|
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
/**
|
|
285
|
-
* Creates the bearer-token authentication battery
|
|
285
|
+
* Creates the bearer-token authentication battery — reads the token from its header and
|
|
286
|
+
* verifies it with `verifyToken`.
|
|
286
287
|
*
|
|
287
288
|
* @typeParam TState - The consumer's opaque per-request state type, must carry {@link BearerState}
|
|
288
289
|
* @param options - See {@link BearerOptions}
|
|
@@ -310,7 +311,7 @@ export declare function createBearer<TState extends BearerState>(options: Bearer
|
|
|
310
311
|
* The shipped `MiddlewareContext.body()` is a parameterless, server-owned
|
|
311
312
|
* cache (`ServerOptions.limit` governs its size cap) — this battery carries
|
|
312
313
|
* no `limit`/`decompression` options. `state.body` is
|
|
313
|
-
* stashed from the
|
|
314
|
+
* stashed from the same awaited call the 400 check reads — `context.body()`
|
|
314
315
|
* is never invoked twice.
|
|
315
316
|
*
|
|
316
317
|
* @example
|
|
@@ -329,9 +330,20 @@ export declare function createBody<TState extends BodyState = BodyState>(): Midd
|
|
|
329
330
|
* @returns A `MiddlewareHandler<TState>`
|
|
330
331
|
* @throws {TypeError} When `options.expose` or `options.report` is malformed
|
|
331
332
|
*
|
|
332
|
-
* @example
|
|
333
|
+
* @example Mount a battery
|
|
333
334
|
* ```ts
|
|
335
|
+
* import { createBoundary, createSecurity } from '@orkestrel/middleware'
|
|
336
|
+
* import type { IdentifierState } from '@orkestrel/middleware'
|
|
337
|
+
* import { compose } from '@orkestrel/server'
|
|
338
|
+
*
|
|
339
|
+
* interface State extends IdentifierState {}
|
|
340
|
+
*
|
|
334
341
|
* const boundary = createBoundary({ expose: false })
|
|
342
|
+
* const security = createSecurity({ hsts: true })
|
|
343
|
+
*
|
|
344
|
+
* const handle = compose<State>([boundary, security], async (_request, context) => {
|
|
345
|
+
* return Response.json({ identifier: context.state.identifier })
|
|
346
|
+
* })
|
|
335
347
|
* ```
|
|
336
348
|
*/
|
|
337
349
|
export declare function createBoundary<TState>(options?: BoundaryOptions): MiddlewareHandler<TState>;
|
|
@@ -368,7 +380,8 @@ export declare function createCompression<TState>(options?: CompressionOptions):
|
|
|
368
380
|
export declare function createCookieTransport(options: CookieTransportOptions): SessionTransportInterface;
|
|
369
381
|
|
|
370
382
|
/**
|
|
371
|
-
* Creates the Cross-Origin Resource Sharing battery
|
|
383
|
+
* Creates the Cross-Origin Resource Sharing battery — answers a preflight itself, and
|
|
384
|
+
* reflects an allow-listed origin or serves the configured wildcard.
|
|
372
385
|
*
|
|
373
386
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
374
387
|
* @param options - See {@link CorsOptions}
|
|
@@ -433,7 +446,7 @@ export declare function createDatabaseSessionStore<S extends SessionInterface =
|
|
|
433
446
|
* @throws {TypeError} When `options.ms` or `options.status` is malformed
|
|
434
447
|
*
|
|
435
448
|
* @remarks
|
|
436
|
-
*
|
|
449
|
+
* Mount this battery outside `createBody` in the chain — it reconstructs the inbound
|
|
437
450
|
* `Request` (to link its `signal` to the deadline `signal`), which throws if
|
|
438
451
|
* the body was already consumed upstream (for example by `createBody`'s cached read).
|
|
439
452
|
*
|
|
@@ -445,7 +458,7 @@ export declare function createDatabaseSessionStore<S extends SessionInterface =
|
|
|
445
458
|
export declare function createDeadline<TState>(options: DeadlineOptions): MiddlewareHandler<TState>;
|
|
446
459
|
|
|
447
460
|
/**
|
|
448
|
-
* Creates the dynamic response `ETag` + conditional GET battery.
|
|
461
|
+
* Creates the dynamic response `ETag` + conditional GET battery (RFC 7232).
|
|
449
462
|
*
|
|
450
463
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
451
464
|
* @param options - See {@link ETagOptions}
|
|
@@ -460,7 +473,8 @@ export declare function createDeadline<TState>(options: DeadlineOptions): Middle
|
|
|
460
473
|
export declare function createETag<TState>(options?: ETagOptions): MiddlewareHandler<TState>;
|
|
461
474
|
|
|
462
475
|
/**
|
|
463
|
-
* Creates the trusted-proxy client-IP resolver battery
|
|
476
|
+
* Creates the trusted-proxy client-IP resolver battery — walks `X-Forwarded-For` past
|
|
477
|
+
* the hops its options declare trusted.
|
|
464
478
|
*
|
|
465
479
|
* @typeParam TState - The consumer's opaque per-request state type, must carry {@link ClientState} and {@link ConnectionState}
|
|
466
480
|
* @param options - See {@link ForwardedOptions}
|
|
@@ -490,7 +504,8 @@ export declare function createForwarded<TState extends ClientState & ConnectionS
|
|
|
490
504
|
export declare function createHeaderTransport(options?: HeaderTransportOptions): SessionTransportInterface;
|
|
491
505
|
|
|
492
506
|
/**
|
|
493
|
-
* Creates the fixed-window rate-limiting battery
|
|
507
|
+
* Creates the fixed-window rate-limiting battery — checks a key's budget before
|
|
508
|
+
* consuming it, so one window admits exactly `max` requests.
|
|
494
509
|
*
|
|
495
510
|
* @typeParam TState - The consumer's opaque per-request state type, must carry {@link BearerState}, {@link ClientState}, and {@link ConnectionState}
|
|
496
511
|
* @param options - See {@link LimiterOptions}
|
|
@@ -540,7 +555,8 @@ export declare function createMemorySessionStore<S extends SessionInterface>(opt
|
|
|
540
555
|
export declare function createRestoredSession(value: unknown): Session | undefined;
|
|
541
556
|
|
|
542
557
|
/**
|
|
543
|
-
* Creates the security-headers + request-identifier battery
|
|
558
|
+
* Creates the security-headers + request-identifier battery — sets each documented
|
|
559
|
+
* header default, and mints or echoes a request identifier.
|
|
544
560
|
*
|
|
545
561
|
* @typeParam TState - The consumer's opaque per-request state type, must carry {@link IdentifierState}
|
|
546
562
|
* @param options - See {@link SecurityOptions}
|
|
@@ -638,7 +654,7 @@ export declare interface CSRFState {
|
|
|
638
654
|
* {@link MemorySessionStore}. `delete` of an absent id is a no-op (the
|
|
639
655
|
* table's `remove` contract).
|
|
640
656
|
*
|
|
641
|
-
* A malformed-snapshot or failed-guard `undefined`
|
|
657
|
+
* A malformed-snapshot or failed-guard `undefined` leaves the row in place —
|
|
642
658
|
* unlike the expired path, which removes it. This is deliberate: a
|
|
643
659
|
* caller-contextual guard may reject a session that is still perfectly
|
|
644
660
|
* valid for another flow reading the same table (a differently-shaped `S`,
|
|
@@ -676,22 +692,22 @@ export declare interface DeadlineOptions {
|
|
|
676
692
|
readonly status?: number;
|
|
677
693
|
}
|
|
678
694
|
|
|
679
|
-
/** Names the default header `createBearer` reads the token from. */
|
|
695
|
+
/** Names `'authorization'`, the default header `createBearer` reads the token from. */
|
|
680
696
|
export declare const DEFAULT_BEARER_HEADER = "authorization";
|
|
681
697
|
|
|
682
|
-
/** Names the default scheme prefix `createBearer` strips before verification. */
|
|
698
|
+
/** Names `'Bearer'`, the default scheme prefix `createBearer` strips before verification. */
|
|
683
699
|
export declare const DEFAULT_BEARER_SCHEME = "Bearer";
|
|
684
700
|
|
|
685
|
-
/** Holds the default `Origin-Agent-Cluster` value `createSecurity` sets. */
|
|
701
|
+
/** Holds `'?1'`, the default `Origin-Agent-Cluster` value `createSecurity` sets. */
|
|
686
702
|
export declare const DEFAULT_CLUSTER = "?1";
|
|
687
703
|
|
|
688
|
-
/** Holds the value `createSecurity` sets for `Cross-Origin-Embedder-Policy` when `coep: true`. */
|
|
704
|
+
/** Holds `'require-corp'`, the value `createSecurity` sets for `Cross-Origin-Embedder-Policy` when `coep: true`. */
|
|
689
705
|
export declare const DEFAULT_COEP = "require-corp";
|
|
690
706
|
|
|
691
707
|
/**
|
|
692
|
-
* Lists the default content-codings `createCompression` offers
|
|
693
|
-
* intersected at construction with what the runtime's
|
|
694
|
-
* actually supports.
|
|
708
|
+
* Lists `['gzip', 'deflate']`, the default content-codings `createCompression` offers in
|
|
709
|
+
* preference order — intersected at construction with what the runtime's
|
|
710
|
+
* `CompressionStream` actually supports.
|
|
695
711
|
*
|
|
696
712
|
* @remarks
|
|
697
713
|
* The shipped `@orkestrel/server` peer's {@link Encoding} union is
|
|
@@ -702,13 +718,13 @@ export declare const DEFAULT_COEP = "require-corp";
|
|
|
702
718
|
*/
|
|
703
719
|
export declare const DEFAULT_COMPRESSION_ENCODINGS: readonly Encoding[];
|
|
704
720
|
|
|
705
|
-
/** Holds the default minimum buffered body size
|
|
721
|
+
/** Holds `1024`, the default minimum buffered body size in bytes `createCompression` will compress. */
|
|
706
722
|
export declare const DEFAULT_COMPRESSION_THRESHOLD = 1024;
|
|
707
723
|
|
|
708
|
-
/** Holds the default `Cross-Origin-Opener-Policy` value `createSecurity` sets. */
|
|
724
|
+
/** Holds `'same-origin'`, the default `Cross-Origin-Opener-Policy` value `createSecurity` sets. */
|
|
709
725
|
export declare const DEFAULT_COOP = "same-origin";
|
|
710
726
|
|
|
711
|
-
/** Holds the default `Cross-Origin-Resource-Policy` value `createSecurity` sets. */
|
|
727
|
+
/** Holds `'same-origin'`, the default `Cross-Origin-Resource-Policy` value `createSecurity` sets. */
|
|
712
728
|
export declare const DEFAULT_CORP = "same-origin";
|
|
713
729
|
|
|
714
730
|
/** Lists the default headers `createCors` advertises on a preflight response. */
|
|
@@ -718,54 +734,55 @@ export declare const DEFAULT_CORS_HEADERS: readonly string[];
|
|
|
718
734
|
export declare const DEFAULT_CORS_METHODS: readonly string[];
|
|
719
735
|
|
|
720
736
|
/**
|
|
721
|
-
* Holds
|
|
722
|
-
* `
|
|
737
|
+
* Holds `"default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'self'; form-action 'self'"`,
|
|
738
|
+
* the default `Content-Security-Policy` value `createSecurity` sets — a custom
|
|
739
|
+
* `csp` option replaces this wholesale, never merges.
|
|
723
740
|
*/
|
|
724
741
|
export declare const DEFAULT_CSP = "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'self'; form-action 'self'";
|
|
725
742
|
|
|
726
|
-
/** Names the default signed cookie `createCSRF` writes the CSRF token under. */
|
|
743
|
+
/** Names `'csrf'`, the default signed cookie `createCSRF` writes the CSRF token under. */
|
|
727
744
|
export declare const DEFAULT_CSRF_COOKIE = "csrf";
|
|
728
745
|
|
|
729
|
-
/** Names the default body field `createCSRF` falls back to reading a mutating request's submitted token from. */
|
|
746
|
+
/** Names `'_csrf'`, the default body field `createCSRF` falls back to reading a mutating request's submitted token from. */
|
|
730
747
|
export declare const DEFAULT_CSRF_FIELD = "_csrf";
|
|
731
748
|
|
|
732
|
-
/** Names the default header `createCSRF` reads a mutating request's submitted token from. */
|
|
749
|
+
/** Names `'x-csrf-token'`, the default header `createCSRF` reads a mutating request's submitted token from. */
|
|
733
750
|
export declare const DEFAULT_CSRF_HEADER = "x-csrf-token";
|
|
734
751
|
|
|
735
|
-
/** Lists the default methods `createCSRF` treats as safe (mint instead of verify). */
|
|
752
|
+
/** Lists `['GET', 'HEAD', 'OPTIONS']`, the default methods `createCSRF` treats as safe (mint instead of verify). */
|
|
736
753
|
export declare const DEFAULT_CSRF_SAFE_METHODS: readonly string[];
|
|
737
754
|
|
|
738
|
-
/** Holds the default response status `createDeadline` returns when its deadline fires first. */
|
|
755
|
+
/** Holds `503`, the default response status `createDeadline` returns when its deadline fires first. */
|
|
739
756
|
export declare const DEFAULT_DEADLINE_STATUS = 503;
|
|
740
757
|
|
|
741
|
-
/** Holds the default `X-Frame-Options` value `createSecurity` sets. */
|
|
758
|
+
/** Holds `'DENY'`, the default `X-Frame-Options` value `createSecurity` sets. */
|
|
742
759
|
export declare const DEFAULT_FRAME_OPTIONS = "DENY";
|
|
743
760
|
|
|
744
|
-
/** Holds the value `createSecurity` sets for `Strict-Transport-Security` when `hsts: true`. */
|
|
761
|
+
/** Holds `'max-age=31536000; includeSubDomains'`, the value `createSecurity` sets for `Strict-Transport-Security` when `hsts: true`. */
|
|
745
762
|
export declare const DEFAULT_HSTS = "max-age=31536000; includeSubDomains";
|
|
746
763
|
|
|
747
|
-
/** Names the default header `createSecurity` mints
|
|
764
|
+
/** Names `'x-request-id'`, the default header `createSecurity` mints or echoes a request identifier into. */
|
|
748
765
|
export declare const DEFAULT_IDENTIFIER_HEADER = "x-request-id";
|
|
749
766
|
|
|
750
|
-
/** Holds the default maximum number of distinct rate-limit keys `createLimiter` tracks before LRU eviction. */
|
|
767
|
+
/** Holds `10_000`, the default maximum number of distinct rate-limit keys `createLimiter` tracks before LRU eviction. */
|
|
751
768
|
export declare const DEFAULT_LIMITER_CAPACITY = 10000;
|
|
752
769
|
|
|
753
|
-
/** Holds the default 429 body message `createLimiter` sends when a key is over budget. */
|
|
770
|
+
/** Holds `'rate limit exceeded'`, the default 429 body message `createLimiter` sends when a key is over budget. */
|
|
754
771
|
export declare const DEFAULT_LIMITER_MESSAGE = "rate limit exceeded";
|
|
755
772
|
|
|
756
|
-
/** Holds the default `Permissions-Policy` value `createSecurity` sets. */
|
|
773
|
+
/** Holds `'camera=(), microphone=(), geolocation=()'`, the default `Permissions-Policy` value `createSecurity` sets. */
|
|
757
774
|
export declare const DEFAULT_PERMISSIONS_POLICY = "camera=(), microphone=(), geolocation=()";
|
|
758
775
|
|
|
759
|
-
/** Holds the default `Referrer-Policy` value `createSecurity` sets. */
|
|
776
|
+
/** Holds `'strict-origin-when-cross-origin'`, the default `Referrer-Policy` value `createSecurity` sets. */
|
|
760
777
|
export declare const DEFAULT_REFERRER_POLICY = "strict-origin-when-cross-origin";
|
|
761
778
|
|
|
762
|
-
/** Holds the default maximum number of distinct session ids `createMemorySessionStore` tracks before LRU (by last write) eviction. */
|
|
779
|
+
/** Holds `10_000`, the default maximum number of distinct session ids `createMemorySessionStore` tracks before LRU (by last write) eviction. */
|
|
763
780
|
export declare const DEFAULT_SESSION_CAPACITY = 10000;
|
|
764
781
|
|
|
765
|
-
/** Names the default cookie `createCookieTransport` writes the signed session id under. */
|
|
782
|
+
/** Names `'session'`, the default cookie `createCookieTransport` writes the signed session id under. */
|
|
766
783
|
export declare const DEFAULT_SESSION_COOKIE = "session";
|
|
767
784
|
|
|
768
|
-
/** Names the default header `createHeaderTransport` carries the session id in. */
|
|
785
|
+
/** Names `'session-id'`, the default header `createHeaderTransport` carries the session id in. */
|
|
769
786
|
export declare const DEFAULT_SESSION_HEADER = "session-id";
|
|
770
787
|
|
|
771
788
|
/**
|
|
@@ -823,8 +840,8 @@ export declare interface ETagOptions {
|
|
|
823
840
|
}
|
|
824
841
|
|
|
825
842
|
/**
|
|
826
|
-
* Scopes a battery to
|
|
827
|
-
*
|
|
843
|
+
* Scopes a battery to every pathname outside a set of exact ones — on that set it
|
|
844
|
+
* steps aside through `next()`.
|
|
828
845
|
*
|
|
829
846
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
830
847
|
* @param paths - One pathname, or a set of pathnames, matched exactly against `context.url.pathname`
|
|
@@ -842,8 +859,8 @@ export declare function except<TState>(paths: string | readonly string[], handle
|
|
|
842
859
|
* Configures `createForwarded` — the trusted-proxy client-IP resolver.
|
|
843
860
|
*
|
|
844
861
|
* @remarks
|
|
845
|
-
* Construction requires
|
|
846
|
-
*
|
|
862
|
+
* Construction requires either `proxies` or `trusted`, never both and never
|
|
863
|
+
* neither (a `TypeError` guards each):
|
|
847
864
|
* - `proxies` — trust exactly this many hops from the right of
|
|
848
865
|
* `X-Forwarded-For` / `Forwarded`.
|
|
849
866
|
* - `trusted` — trust every hop matching one of these CIDR entries.
|
|
@@ -874,16 +891,17 @@ export declare interface IdentifierState {
|
|
|
874
891
|
}
|
|
875
892
|
|
|
876
893
|
/**
|
|
877
|
-
* Checks whether a response
|
|
894
|
+
* Checks whether a response must skip the compression and ETag buffering pipeline
|
|
878
895
|
* — the shared cheap-skip predicate both batteries apply before ever touching
|
|
879
|
-
* `response.arrayBuffer()
|
|
896
|
+
* `response.arrayBuffer()`, true for a `HEAD` request, a `204`/`304` or
|
|
897
|
+
* otherwise bodyless response, an `event-stream` response, and a response
|
|
898
|
+
* already carrying the header the caller is about to set.
|
|
880
899
|
*
|
|
881
900
|
* @remarks
|
|
882
|
-
*
|
|
883
|
-
*
|
|
884
|
-
*
|
|
885
|
-
*
|
|
886
|
-
* ETag battery).
|
|
901
|
+
* Buffering an `event-stream` response would hang the connection, so SSE skips
|
|
902
|
+
* whatever its size. `skipHeader` is the header whose presence already answers
|
|
903
|
+
* the question — `Content-Encoding` for compression, `ETag` for the ETag
|
|
904
|
+
* battery.
|
|
887
905
|
*
|
|
888
906
|
* @param method - The request's HTTP method
|
|
889
907
|
* @param response - The candidate response
|
|
@@ -950,7 +968,7 @@ export declare function isMultipartBody(value: unknown): value is MultipartBody;
|
|
|
950
968
|
export declare function isMultipartFile(value: unknown): value is MultipartFile;
|
|
951
969
|
|
|
952
970
|
/**
|
|
953
|
-
* Determines whether a request is a CORS
|
|
971
|
+
* Determines whether a request is a CORS preflight — an `OPTIONS` request
|
|
954
972
|
* carrying an `Access-Control-Request-Method` header.
|
|
955
973
|
*
|
|
956
974
|
* @param method - The request's HTTP method
|
|
@@ -968,8 +986,8 @@ export declare function isPreflight(method: string, headers: Headers): boolean;
|
|
|
968
986
|
* Determines whether a value implements {@link SessionInterface} — a total
|
|
969
987
|
* structural guard: an `id` string, a `state` `Map`, and the `set`, `delete`,
|
|
970
988
|
* and `clear` mutators. Prototype-agnostic — accepts a plain object, a
|
|
971
|
-
* null-prototype object,
|
|
972
|
-
* restored
|
|
989
|
+
* null-prototype object, and a class instance (a real `Session`), because a
|
|
990
|
+
* restored or stored session is routinely a class instance rather than a literal.
|
|
973
991
|
*
|
|
974
992
|
* @param value - The candidate value
|
|
975
993
|
* @returns True if `value` is shaped like a {@link SessionInterface}; false otherwise
|
|
@@ -1041,7 +1059,7 @@ export declare interface LimiterOptions<TState = unknown> {
|
|
|
1041
1059
|
* never claims full CIDR generality beyond IPv4.
|
|
1042
1060
|
*
|
|
1043
1061
|
* @remarks
|
|
1044
|
-
* An IPv6 `trusted` roster entry is compared as an
|
|
1062
|
+
* An IPv6 `trusted` roster entry is compared as an exact string — it must be
|
|
1045
1063
|
* supplied in canonical form (no zero-compression normalization, no case
|
|
1046
1064
|
* folding) by the caller; this function performs no IPv6 normalization of
|
|
1047
1065
|
* its own.
|
|
@@ -1068,7 +1086,7 @@ export declare function matchesTrustedEntry(address: string, entry: string): boo
|
|
|
1068
1086
|
* @remarks
|
|
1069
1087
|
* `get` evicts a session whose idle time (`now - seen >= ttl`) or
|
|
1070
1088
|
* absolute lifetime (`now - created >= lifetime`) has elapsed — the
|
|
1071
|
-
* lifetime check fires
|
|
1089
|
+
* lifetime check fires even if the session was continuously touched, because
|
|
1072
1090
|
* `created` is stamped once at the first `set` and preserved across every
|
|
1073
1091
|
* later re-`set` of the same id. A live read touches `seen`. `delete` of
|
|
1074
1092
|
* an absent id is a no-op.
|
|
@@ -1162,8 +1180,8 @@ export declare interface MultipartState {
|
|
|
1162
1180
|
}
|
|
1163
1181
|
|
|
1164
1182
|
/**
|
|
1165
|
-
* Scopes a battery to
|
|
1166
|
-
* steps aside through `next()`.
|
|
1183
|
+
* Scopes a battery to a set of exact pathnames and nowhere else — outside that set
|
|
1184
|
+
* it steps aside through `next()`.
|
|
1167
1185
|
*
|
|
1168
1186
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
1169
1187
|
* @param paths - One pathname, or a set of pathnames, matched exactly against `context.url.pathname`
|
|
@@ -1197,13 +1215,13 @@ export declare function only<TState>(paths: string | readonly string[], handler:
|
|
|
1197
1215
|
export declare function rebuildResponse(body: ConstructorParameters<typeof Response>[0], response: Response, headers?: ConstructorParameters<typeof Headers>[0]): Response;
|
|
1198
1216
|
|
|
1199
1217
|
/**
|
|
1200
|
-
* Walks `X-Forwarded-For` right-to-left and resolves the first
|
|
1218
|
+
* Walks `X-Forwarded-For` right-to-left and resolves the first untrusted hop
|
|
1201
1219
|
* address — `createForwarded`'s core algorithm.
|
|
1202
1220
|
*
|
|
1203
1221
|
* @remarks
|
|
1204
1222
|
* Parses `X-Forwarded-For` only. With `proxies` set, trusts exactly that
|
|
1205
1223
|
* many hops counted from the right (the closest to this server) and returns
|
|
1206
|
-
* the next one left of them; with `trusted` set, trusts every
|
|
1224
|
+
* the next one left of them; with `trusted` set, trusts every consecutive
|
|
1207
1225
|
* hop from the right that matches one of the roster
|
|
1208
1226
|
* ({@link matchesTrustedEntry}) and returns the first hop that does not. If
|
|
1209
1227
|
* the rightmost hop (the immediate sender) does not match the roster, the
|
|
@@ -1213,7 +1231,7 @@ export declare function rebuildResponse(body: ConstructorParameters<typeof Respo
|
|
|
1213
1231
|
* socket peer).
|
|
1214
1232
|
*
|
|
1215
1233
|
* @param header - The raw `X-Forwarded-For` header value (comma-separated hops), if present
|
|
1216
|
-
* @param trust - The {@link ForwardedOptions} form in force — a trusted hop
|
|
1234
|
+
* @param trust - The {@link ForwardedOptions} form in force — a trusted hop count or a `trusted` CIDR/exact roster
|
|
1217
1235
|
* @returns The first untrusted hop address, or `undefined` when none qualifies
|
|
1218
1236
|
*
|
|
1219
1237
|
* @example
|
|
@@ -1249,7 +1267,7 @@ export declare function resolveKey(state: BearerState & ClientState & Connection
|
|
|
1249
1267
|
|
|
1250
1268
|
/**
|
|
1251
1269
|
* Resolves an opt-in, value-bearing security header — `string | boolean`
|
|
1252
|
-
* (default
|
|
1270
|
+
* (off by default, `true` uses the secure default), the shape `createSecurity`'s
|
|
1253
1271
|
* `coep`/`hsts` options use, distinct from the plain value-or-`false` shape
|
|
1254
1272
|
* `resolveSecurityHeader` (the peer substrate) handles.
|
|
1255
1273
|
*
|
|
@@ -1293,11 +1311,11 @@ export declare type SecurityIdentifierOptions = {
|
|
|
1293
1311
|
* - `coop` — `Cross-Origin-Opener-Policy`; default {@link DEFAULT_COOP}.
|
|
1294
1312
|
* - `corp` — `Cross-Origin-Resource-Policy`; default {@link DEFAULT_CORP}.
|
|
1295
1313
|
* - `cluster` — `Origin-Agent-Cluster`; default {@link DEFAULT_CLUSTER}.
|
|
1296
|
-
* - `coep` — `Cross-Origin-Embedder-Policy`; `string | boolean`,
|
|
1314
|
+
* - `coep` — `Cross-Origin-Embedder-Policy`; `string | boolean`, off by
|
|
1297
1315
|
* default (opt-in, breaks cross-origin subresources); `true` → {@link DEFAULT_COEP}.
|
|
1298
|
-
* - `hsts` — `Strict-Transport-Security`; `string | boolean`,
|
|
1316
|
+
* - `hsts` — `Strict-Transport-Security`; `string | boolean`, off by default
|
|
1299
1317
|
* (opt-in, destructive if misconfigured); `true` → {@link DEFAULT_HSTS}.
|
|
1300
|
-
* - `identifier` — {@link SecurityIdentifierOptions};
|
|
1318
|
+
* - `identifier` — {@link SecurityIdentifierOptions}; on by default (mints
|
|
1301
1319
|
* and stashes {@link IdentifierState}).
|
|
1302
1320
|
*/
|
|
1303
1321
|
export declare interface SecurityOptions {
|
|
@@ -1343,7 +1361,7 @@ export declare class Session implements SessionInterface {
|
|
|
1343
1361
|
|
|
1344
1362
|
/**
|
|
1345
1363
|
* Holds the `@orkestrel/database` column shape for a
|
|
1346
|
-
* {@link import('./types.js').SessionRow} table
|
|
1364
|
+
* {@link import('./types.js').SessionRow} table. Pass it as-is to
|
|
1347
1365
|
* `createDatabase({ tables: { sessions: sessionColumns } })` so an app
|
|
1348
1366
|
* declaring a durable session table never hand-writes the shape.
|
|
1349
1367
|
*
|
|
@@ -1373,13 +1391,15 @@ export declare const sessionColumns: {
|
|
|
1373
1391
|
* session itself — the OWASP anti-fixation / logout primitives.
|
|
1374
1392
|
*
|
|
1375
1393
|
* @remarks
|
|
1376
|
-
* `regenerate` and `destroy` record intent
|
|
1394
|
+
* `regenerate` and `destroy` record intent synchronously when called; the
|
|
1377
1395
|
* store I/O and transport write happen after the handler's `next()` returns
|
|
1378
1396
|
* (`destroy` supersedes a prior `regenerate`). `regenerate` mints a new id,
|
|
1379
1397
|
* carries the session's `state` over, and invalidates the old id.
|
|
1380
1398
|
*/
|
|
1381
1399
|
export declare interface SessionControlInterface {
|
|
1400
|
+
/** Mints a fresh id, carries the session's `state` over, and invalidates the old id. */
|
|
1382
1401
|
regenerate(): void;
|
|
1402
|
+
/** Ends the session — deletes it from the store and clears its transport. */
|
|
1383
1403
|
destroy(): void;
|
|
1384
1404
|
}
|
|
1385
1405
|
|
|
@@ -1437,8 +1457,21 @@ export declare function sessionExpired(cursors: SessionCursors, now: number, lim
|
|
|
1437
1457
|
export declare interface SessionInterface {
|
|
1438
1458
|
readonly id: string;
|
|
1439
1459
|
readonly state: ReadonlyMap<string, unknown>;
|
|
1460
|
+
/**
|
|
1461
|
+
* Writes one key's value into the session's state.
|
|
1462
|
+
*
|
|
1463
|
+
* @param key - The state key to write
|
|
1464
|
+
* @param value - The value to store under `key`
|
|
1465
|
+
*/
|
|
1440
1466
|
set(key: string, value: unknown): void;
|
|
1467
|
+
/**
|
|
1468
|
+
* Removes one key from the session's state.
|
|
1469
|
+
*
|
|
1470
|
+
* @param key - The state key to remove
|
|
1471
|
+
* @returns True when the session held `key`; false otherwise
|
|
1472
|
+
*/
|
|
1441
1473
|
delete(key: string): boolean;
|
|
1474
|
+
/** Empties the state, leaving the session and its id alive. */
|
|
1442
1475
|
clear(): void;
|
|
1443
1476
|
}
|
|
1444
1477
|
|
|
@@ -1469,10 +1502,10 @@ export declare interface SessionLimits {
|
|
|
1469
1502
|
* `createMemorySessionStore({ ttl, lifetime, capacity, evict })`.
|
|
1470
1503
|
* - `ttl` — the idle timeout in milliseconds.
|
|
1471
1504
|
* - `lifetime` — the absolute session lifetime in milliseconds from mint.
|
|
1472
|
-
* - `capacity` — the maximum number of distinct session ids the
|
|
1505
|
+
* - `capacity` — the maximum number of distinct session ids the default
|
|
1473
1506
|
* memory store tracks before LRU eviction; ignored when `store` is
|
|
1474
1507
|
* provided. Defaults to {@link DEFAULT_SESSION_CAPACITY}.
|
|
1475
|
-
* - `evict` — invoked with a session id evicted by the
|
|
1508
|
+
* - `evict` — invoked with a session id evicted by the default memory
|
|
1476
1509
|
* store's own policy; ignored when `store` is provided. It is a
|
|
1477
1510
|
* notification sink only — it must never call back into the store
|
|
1478
1511
|
* (no re-entrant `get`/`set`); mutations during eviction are unsupported.
|
|
@@ -1566,8 +1599,28 @@ export declare interface SessionState {
|
|
|
1566
1599
|
* constructed with.
|
|
1567
1600
|
*/
|
|
1568
1601
|
export declare interface SessionStoreInterface<S extends SessionInterface> {
|
|
1602
|
+
/**
|
|
1603
|
+
* Reads a session by id, applying the idle and absolute expiry against `now`.
|
|
1604
|
+
*
|
|
1605
|
+
* @param id - The session id to read
|
|
1606
|
+
* @param now - The caller's clock reading the expiry is measured against
|
|
1607
|
+
* @returns The stored session, or `undefined` when it is absent or expired
|
|
1608
|
+
*/
|
|
1569
1609
|
get(id: string, now: number): Promise<S | undefined>;
|
|
1610
|
+
/**
|
|
1611
|
+
* Persists a session under its own `id`, refreshing its idle window.
|
|
1612
|
+
*
|
|
1613
|
+
* @param session - The session to persist, keyed by its own `id`
|
|
1614
|
+
* @param now - The caller's clock reading stamped as the session's `seen`
|
|
1615
|
+
* @returns A promise that resolves once the session is stored
|
|
1616
|
+
*/
|
|
1570
1617
|
set(session: S, now: number): Promise<void>;
|
|
1618
|
+
/**
|
|
1619
|
+
* Removes a session by id — a no-op on an absent id, never throws.
|
|
1620
|
+
*
|
|
1621
|
+
* @param id - The session id to remove
|
|
1622
|
+
* @returns A promise that resolves once the id is absent from the store
|
|
1623
|
+
*/
|
|
1571
1624
|
delete(id: string): Promise<void>;
|
|
1572
1625
|
}
|
|
1573
1626
|
|
|
@@ -1577,7 +1630,7 @@ export declare interface SessionStoreInterface<S extends SessionInterface> {
|
|
|
1577
1630
|
*
|
|
1578
1631
|
* @remarks
|
|
1579
1632
|
* `read` is total (a malformed/tampered credential resolves `undefined`,
|
|
1580
|
-
* never throws). `write` and `clear` mutate the
|
|
1633
|
+
* never throws). `write` and `clear` mutate the returned `Response` on the
|
|
1581
1634
|
* way out — the returning onion makes "before send" automatic. `write` is
|
|
1582
1635
|
* called only when a session is freshly minted or regenerated; `clear` is
|
|
1583
1636
|
* called on `destroy()`. `write`'s `encrypted` flag is the request's resolved
|
|
@@ -1586,8 +1639,24 @@ export declare interface SessionStoreInterface<S extends SessionInterface> {
|
|
|
1586
1639
|
* without re-deriving connection facts itself.
|
|
1587
1640
|
*/
|
|
1588
1641
|
export declare interface SessionTransportInterface {
|
|
1642
|
+
/**
|
|
1643
|
+
* Reads the incoming session id from the request — `undefined` on any failure.
|
|
1644
|
+
*
|
|
1645
|
+
* @param request - The inbound request the credential travels on
|
|
1646
|
+
* @returns The session id, or `undefined` when none is present or readable
|
|
1647
|
+
*/
|
|
1589
1648
|
read(request: Request): string | undefined | Promise<string | undefined>;
|
|
1649
|
+
/**
|
|
1650
|
+
* Writes a freshly minted or regenerated session id onto the response, together with
|
|
1651
|
+
* the request's encrypted-transport fact.
|
|
1652
|
+
*
|
|
1653
|
+
* @param response - The outgoing response the credential is written onto
|
|
1654
|
+
* @param id - The session id carried to the client
|
|
1655
|
+
* @param encrypted - Whether the request arrived over an encrypted transport
|
|
1656
|
+
* @returns Nothing, or a promise that resolves once the credential is written
|
|
1657
|
+
*/
|
|
1590
1658
|
write(response: Response, id: string, encrypted: boolean): void | Promise<void>;
|
|
1659
|
+
/** Clears the transport's credential on `destroy()`. */
|
|
1591
1660
|
clear(response: Response): void;
|
|
1592
1661
|
}
|
|
1593
1662
|
|
|
@@ -1602,7 +1671,7 @@ export declare interface SessionTransportInterface {
|
|
|
1602
1671
|
* @remarks
|
|
1603
1672
|
* `state` is built on a null-prototype object (`Object.create(null)`), never
|
|
1604
1673
|
* a `{}` literal — a session key literally named `__proto__` must round-trip
|
|
1605
|
-
* as an
|
|
1674
|
+
* as an own enumerable property instead of hitting `Object.prototype`'s
|
|
1606
1675
|
* `__proto__` accessor (which would silently drop the entry and risk
|
|
1607
1676
|
* polluting the shared prototype).
|
|
1608
1677
|
*
|