@nifrajs/middleware 2.11.0 → 2.12.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 (120) hide show
  1. package/dist/_utils.d.ts +14 -2
  2. package/dist/_utils.d.ts.map +1 -1
  3. package/dist/_utils.js +25 -10
  4. package/dist/_utils.js.map +1 -1
  5. package/dist/basic-auth.d.ts +2 -2
  6. package/dist/basic-auth.d.ts.map +1 -1
  7. package/dist/basic-auth.js +2 -2
  8. package/dist/basic-auth.js.map +1 -1
  9. package/dist/cache-control.d.ts +1 -1
  10. package/dist/cache-control.d.ts.map +1 -1
  11. package/dist/cache-control.js +2 -2
  12. package/dist/cache-control.js.map +1 -1
  13. package/dist/cache.d.ts +2 -0
  14. package/dist/cache.d.ts.map +1 -1
  15. package/dist/cache.js +13 -1
  16. package/dist/cache.js.map +1 -1
  17. package/dist/combine.d.ts +11 -5
  18. package/dist/combine.d.ts.map +1 -1
  19. package/dist/combine.js +11 -4
  20. package/dist/combine.js.map +1 -1
  21. package/dist/compression.d.ts +8 -1
  22. package/dist/compression.d.ts.map +1 -1
  23. package/dist/compression.js +9 -2
  24. package/dist/compression.js.map +1 -1
  25. package/dist/csrf.d.ts +11 -4
  26. package/dist/csrf.d.ts.map +1 -1
  27. package/dist/csrf.js +19 -5
  28. package/dist/csrf.js.map +1 -1
  29. package/dist/durable-command.d.ts +2 -2
  30. package/dist/durable-command.d.ts.map +1 -1
  31. package/dist/durable-command.js +2 -2
  32. package/dist/durable-command.js.map +1 -1
  33. package/dist/etag.d.ts +2 -2
  34. package/dist/etag.d.ts.map +1 -1
  35. package/dist/etag.js +3 -3
  36. package/dist/etag.js.map +1 -1
  37. package/dist/healthcheck.d.ts +2 -1
  38. package/dist/healthcheck.d.ts.map +1 -1
  39. package/dist/healthcheck.js +5 -2
  40. package/dist/healthcheck.js.map +1 -1
  41. package/dist/idempotency.d.ts +51 -5
  42. package/dist/idempotency.d.ts.map +1 -1
  43. package/dist/idempotency.js +110 -13
  44. package/dist/idempotency.js.map +1 -1
  45. package/dist/jwt.d.ts +2 -2
  46. package/dist/jwt.d.ts.map +1 -1
  47. package/dist/jwt.js +14 -3
  48. package/dist/jwt.js.map +1 -1
  49. package/dist/language.d.ts +9 -1
  50. package/dist/language.d.ts.map +1 -1
  51. package/dist/language.js +8 -2
  52. package/dist/language.js.map +1 -1
  53. package/dist/logger.d.ts +9 -4
  54. package/dist/logger.d.ts.map +1 -1
  55. package/dist/logger.js +9 -5
  56. package/dist/logger.js.map +1 -1
  57. package/dist/method-override.d.ts +1 -1
  58. package/dist/method-override.d.ts.map +1 -1
  59. package/dist/method-override.js +2 -2
  60. package/dist/method-override.js.map +1 -1
  61. package/dist/openapi.d.ts +2 -1
  62. package/dist/openapi.d.ts.map +1 -1
  63. package/dist/openapi.js +4 -2
  64. package/dist/openapi.js.map +1 -1
  65. package/dist/pretty-json.d.ts +1 -1
  66. package/dist/pretty-json.d.ts.map +1 -1
  67. package/dist/pretty-json.js +2 -2
  68. package/dist/pretty-json.js.map +1 -1
  69. package/dist/problem-details.d.ts +1 -1
  70. package/dist/problem-details.d.ts.map +1 -1
  71. package/dist/problem-details.js +2 -2
  72. package/dist/problem-details.js.map +1 -1
  73. package/dist/rate-limit.d.ts.map +1 -1
  74. package/dist/rate-limit.js +6 -8
  75. package/dist/rate-limit.js.map +1 -1
  76. package/dist/request-id.d.ts +12 -4
  77. package/dist/request-id.d.ts.map +1 -1
  78. package/dist/request-id.js +62 -7
  79. package/dist/request-id.js.map +1 -1
  80. package/dist/security-headers.d.ts +11 -0
  81. package/dist/security-headers.d.ts.map +1 -1
  82. package/dist/security-headers.js +12 -0
  83. package/dist/security-headers.js.map +1 -1
  84. package/dist/timing.d.ts +4 -1
  85. package/dist/timing.d.ts.map +1 -1
  86. package/dist/timing.js +2 -2
  87. package/dist/timing.js.map +1 -1
  88. package/dist/token-auth.d.ts +2 -2
  89. package/dist/token-auth.d.ts.map +1 -1
  90. package/dist/token-auth.js +2 -2
  91. package/dist/token-auth.js.map +1 -1
  92. package/dist/trailing-slash.d.ts +2 -2
  93. package/dist/trailing-slash.d.ts.map +1 -1
  94. package/dist/trailing-slash.js +3 -3
  95. package/dist/trailing-slash.js.map +1 -1
  96. package/package.json +3 -3
  97. package/src/_utils.ts +27 -10
  98. package/src/basic-auth.ts +3 -3
  99. package/src/cache-control.ts +2 -2
  100. package/src/cache.ts +20 -1
  101. package/src/combine.ts +22 -10
  102. package/src/compression.ts +9 -2
  103. package/src/csrf.ts +31 -15
  104. package/src/durable-command.ts +3 -3
  105. package/src/etag.ts +3 -3
  106. package/src/healthcheck.ts +6 -3
  107. package/src/idempotency.ts +146 -18
  108. package/src/jwt.ts +22 -4
  109. package/src/language.ts +26 -16
  110. package/src/logger.ts +10 -6
  111. package/src/method-override.ts +2 -2
  112. package/src/openapi.ts +5 -3
  113. package/src/pretty-json.ts +2 -2
  114. package/src/problem-details.ts +2 -2
  115. package/src/rate-limit.ts +6 -8
  116. package/src/request-id.ts +63 -11
  117. package/src/security-headers.ts +23 -0
  118. package/src/timing.ts +3 -3
  119. package/src/token-auth.ts +3 -3
  120. package/src/trailing-slash.ts +3 -3
@@ -1,9 +1,15 @@
1
- import { definePlugin } from "@nifrajs/core/server";
1
+ import { defineContextPlugin } from "@nifrajs/core/server";
2
+ import { setNodeHeader, withHeaders } from "./_utils.js";
2
3
  /**
3
- * A {@link definePlugin} plugin that gives every request a stable id: it reuses an inbound
4
+ * A {@link defineContextPlugin} plugin that gives every request a stable id: it reuses an inbound
4
5
  * `x-request-id` (or generates one), exposes it on the handler context as **`c.requestId`** (typed,
5
- * threaded by `derive`), and echoes it on the response header. Idempotent - applying it twice is a
6
- * no-op.
6
+ * threaded by `derive`), and echoes it on EVERY response leaving the app - handler-returned raw
7
+ * `Response`s and redirects, `onRequest` short-circuits (an auth 401, an admission 429), and
8
+ * framework-generated 404/405/422/timeout responses included. Core deliberately does not merge
9
+ * `c.set.headers` onto a handler-returned `Response`, so the echo lives in an app-global
10
+ * `onResponse` hook (paired with the derive through a `WeakMap` keyed on the request) with a node
11
+ * twin, keeping the Node adapter on its direct writer with no request-walk cost. Idempotent -
12
+ * applying it twice is a no-op.
7
13
  *
8
14
  * ```ts
9
15
  * app.use(requestId()) // c.requestId available downstream; X-Request-Id on responses
@@ -11,10 +17,59 @@ import { definePlugin } from "@nifrajs/core/server";
11
17
  */
12
18
  export function requestId(options = {}) {
13
19
  const header = options.header ?? "x-request-id";
20
+ // The wire spelling: `c.set.headers` and the Node outcome record both store lowercase names, so
21
+ // the response twin's "already echoed?" probe and the derive's write must agree on it.
22
+ const wireHeader = header.toLowerCase();
14
23
  const generate = options.generate ?? (() => crypto.randomUUID());
15
- return definePlugin("requestId", (app) => app.derive((c) => {
16
- const id = c.header(header) ?? generate();
17
- c.set.headers[header] = id; // echo on the response (route handlers)
24
+ // Web-lane derive-to-response pairing for GENERATED ids (an inbound one is re-readable from the
25
+ // request in onResponse). Entries are deleted in onResponse; a Node-lane derive also writes here
26
+ // but its id travels via the `c.set` write into the outcome record, and the weakly-held entry is
27
+ // simply collected with the request.
28
+ const ids = new WeakMap();
29
+ // defineContextPlugin, not definePlugin: the latter would infer `app` as `AnyServer` here and make
30
+ // `.use(requestId())` return `Server<any, any>`, erasing the route registry for every route the app
31
+ // declares afterwards - and with it the end-to-end types of any typed client built from the app.
32
+ return defineContextPlugin("requestId", (app) => app
33
+ // No `name` on the bundle: the surrounding plugin's "requestId" dedupe already makes the
34
+ // install idempotent, and a bundle named the same would be skipped as already-installed.
35
+ // Response hooks ONLY - no onRequest, so the bundle adds nothing to the request walk and the
36
+ // Node adapter's native request lane stays engaged without needing a no-op twin.
37
+ .use({
38
+ onResponse(res, req) {
39
+ const id = ids.get(req);
40
+ ids.delete(req);
41
+ // Already carried (the derive's `c.set` write merged into a framework-rendered response,
42
+ // or the handler set it explicitly): leave the response untouched.
43
+ if (res.headers.get(header) !== null)
44
+ return res;
45
+ // The id the derive generated; else the inbound header, then a fresh id - so a response
46
+ // no derive saw (a 404, an earlier middleware's short-circuit) is still covered.
47
+ const echo = id ?? req.headers.get(header) ?? generate();
48
+ return withHeaders(res, (headers) => {
49
+ headers.set(header, echo);
50
+ });
51
+ },
52
+ onNodeResponse(res, req) {
53
+ // The common node path (a handler route, whose derive wrote the id through `c.set`) pays
54
+ // exactly this one record-property check. Anything the derive never saw - a 404, a native
55
+ // short-circuit - gets the inbound id or a fresh one here.
56
+ if (res.headers?.[wireHeader] !== undefined)
57
+ return;
58
+ setNodeHeader(res, wireHeader, req.header(header) ?? generate());
59
+ },
60
+ })
61
+ .derive((c) => {
62
+ // Inbound header first (readable on every lane without materializing a Request); generate
63
+ // otherwise, ONCE. A generated id is stored keyed on `c.req` so the Web onResponse hook
64
+ // echoes the exact id a raw-Response handler saw as `c.requestId`; the `c.set` write below
65
+ // carries it into a framework-rendered result on every lane - on Node-direct, into the
66
+ // outcome record, where the response twin sees it as already echoed. Header and
67
+ // `c.requestId` are therefore the same value everywhere with a single generation.
68
+ const inbound = c.header(header);
69
+ const id = inbound ?? generate();
70
+ if (inbound === null)
71
+ ids.set(c.req, id);
72
+ c.set.headers[wireHeader] = id;
18
73
  return { requestId: id };
19
74
  }));
20
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"request-id.js","sourceRoot":"","sources":["../src/request-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AASnD;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,UAA4B,EAAE;IACtD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAA;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;IAChE,OAAO,YAAY,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CACvC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACf,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAA;QACzC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAA,CAAC,wCAAwC;QACnE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,CAAA;IAC1B,CAAC,CAAC,CACH,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"request-id.js","sourceRoot":"","sources":["../src/request-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AASxD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAC,UAA4B,EAAE;IACtD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAA;IAC/C,gGAAgG;IAChG,uFAAuF;IACvF,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,EAAE,CAAA;IACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;IAChE,gGAAgG;IAChG,iGAAiG;IACjG,iGAAiG;IACjG,qCAAqC;IACrC,MAAM,GAAG,GAAG,IAAI,OAAO,EAAmB,CAAA;IAC1C,mGAAmG;IACnG,oGAAoG;IACpG,iGAAiG;IACjG,OAAO,mBAAmB,CAAwB,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CACrE,GAAG;QACD,yFAAyF;QACzF,yFAAyF;QACzF,6FAA6F;QAC7F,iFAAiF;SAChF,GAAG,CAAC;QACH,UAAU,CAAC,GAAG,EAAE,GAAG;YACjB,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACf,yFAAyF;YACzF,mEAAmE;YACnE,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI;gBAAE,OAAO,GAAG,CAAA;YAChD,wFAAwF;YACxF,iFAAiF;YACjF,MAAM,IAAI,GAAG,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAA;YACxD,OAAO,WAAW,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE;gBAClC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YAC3B,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,cAAc,CAAC,GAAG,EAAE,GAAG;YACrB,yFAAyF;YACzF,0FAA0F;YAC1F,2DAA2D;YAC3D,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,KAAK,SAAS;gBAAE,OAAM;YACnD,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAA;QAClE,CAAC;KACF,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACZ,0FAA0F;QAC1F,wFAAwF;QACxF,2FAA2F;QAC3F,uFAAuF;QACvF,gFAAgF;QAChF,kFAAkF;QAClF,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAChC,MAAM,EAAE,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAA;QAChC,IAAI,OAAO,KAAK,IAAI;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;QACxC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,CAAA;QAC9B,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,CAAA;IAC1B,CAAC,CAAC,CACL,CAAA;AACH,CAAC"}
@@ -12,6 +12,17 @@ export interface SecurityHeadersOptions {
12
12
  readonly frameOptions?: "DENY" | "SAMEORIGIN";
13
13
  /** `Referrer-Policy`. Default `"no-referrer"`. */
14
14
  readonly referrerPolicy?: string;
15
+ /** `Cross-Origin-Opener-Policy`. Off by default - isolates the browsing context group; opt in
16
+ * when the app tolerates losing `window.opener` links from cross-origin pages. */
17
+ readonly crossOriginOpenerPolicy?: "same-origin" | "same-origin-allow-popups" | "unsafe-none";
18
+ /** `Cross-Origin-Embedder-Policy`. Off by default - `require-corp` breaks embedding of
19
+ * cross-origin resources that do not opt in, so this is a deliberate decision. */
20
+ readonly crossOriginEmbedderPolicy?: "require-corp" | "credentialless" | "unsafe-none";
21
+ /** `Cross-Origin-Resource-Policy`. Off by default (app-specific: assets meant for other
22
+ * origins need `cross-origin`). */
23
+ readonly crossOriginResourcePolicy?: "same-origin" | "same-site" | "cross-origin";
24
+ /** `Permissions-Policy` value, e.g. `"camera=(), geolocation=()"`. Off by default (app-specific). */
25
+ readonly permissionsPolicy?: string;
15
26
  }
16
27
  /**
17
28
  * A safe-by-default set of response security headers, covering errors and 404s too:
@@ -1 +1 @@
1
- {"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,MAAM,WAAW,sBAAsB;IACrC,+FAA+F;IAC/F,QAAQ,CAAC,IAAI,CAAC,EAAE;QACd,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;QACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAC3B,CAAA;IACD,sEAAsE;IACtE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAA;IACvC,2CAA2C;IAC3C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,CAAA;IAC7C,kDAAkD;IAClD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,UAAU,CAgChF"}
1
+ {"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,MAAM,WAAW,sBAAsB;IACrC,+FAA+F;IAC/F,QAAQ,CAAC,IAAI,CAAC,EAAE;QACd,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;QACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAC3B,CAAA;IACD,sEAAsE;IACtE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAA;IACvC,2CAA2C;IAC3C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,CAAA;IAC7C,kDAAkD;IAClD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC;sFACkF;IAClF,QAAQ,CAAC,uBAAuB,CAAC,EAAE,aAAa,GAAG,0BAA0B,GAAG,aAAa,CAAA;IAC7F;sFACkF;IAClF,QAAQ,CAAC,yBAAyB,CAAC,EAAE,cAAc,GAAG,gBAAgB,GAAG,aAAa,CAAA;IACtF;uCACmC;IACnC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,aAAa,GAAG,WAAW,GAAG,cAAc,CAAA;IACjF,qGAAqG;IACrG,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CACpC;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,UAAU,CA4ChF"}
@@ -31,6 +31,18 @@ export function securityHeaders(options = {}) {
31
31
  declared["strict-transport-security"] = hstsValue;
32
32
  if (csp !== undefined)
33
33
  declared["content-security-policy"] = csp;
34
+ if (options.crossOriginOpenerPolicy !== undefined) {
35
+ declared["cross-origin-opener-policy"] = options.crossOriginOpenerPolicy;
36
+ }
37
+ if (options.crossOriginEmbedderPolicy !== undefined) {
38
+ declared["cross-origin-embedder-policy"] = options.crossOriginEmbedderPolicy;
39
+ }
40
+ if (options.crossOriginResourcePolicy !== undefined) {
41
+ declared["cross-origin-resource-policy"] = options.crossOriginResourcePolicy;
42
+ }
43
+ if (options.permissionsPolicy !== undefined) {
44
+ declared["permissions-policy"] = options.permissionsPolicy;
45
+ }
34
46
  return withRouteAssurance({
35
47
  name: "security-headers",
36
48
  responseHeaders: declared,
@@ -1 +1 @@
1
- {"version":3,"file":"security-headers.js","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAkB7E;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkC,EAAE;IAClE,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,MAAM,CAAA;IACnD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,aAAa,CAAA;IAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,qBAAqB,CAAA;IAEzC,IAAI,SAA6B,CAAA;IACjC,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,CAAC,WAAW,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;QAChD,IAAI,OAAO,CAAC,IAAI,CAAC,iBAAiB;YAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;QACnE,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC/C,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,MAAM,QAAQ,GAA2B;QACvC,wBAAwB,EAAE,SAAS;QACnC,iBAAiB,EAAE,YAAY;QAC/B,iBAAiB,EAAE,cAAc;KAClC,CAAA;IACD,IAAI,SAAS,KAAK,SAAS;QAAE,QAAQ,CAAC,2BAA2B,CAAC,GAAG,SAAS,CAAA;IAC9E,IAAI,GAAG,KAAK,SAAS;QAAE,QAAQ,CAAC,yBAAyB,CAAC,GAAG,GAAG,CAAA;IAEhE,OAAO,kBAAkB,CACvB;QACE,IAAI,EAAE,kBAAkB;QACxB,eAAe,EAAE,QAAQ;KAC1B,EACD;QACE,EAAE,EAAE,eAAe,CAAC,gBAAgB;QACpC,MAAM,EAAE,kBAAkB;QAC1B,KAAK,EAAE,QAAQ;KAChB,CACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"security-headers.js","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AA6B7E;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkC,EAAE;IAClE,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,MAAM,CAAA;IACnD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,aAAa,CAAA;IAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,qBAAqB,CAAA;IAEzC,IAAI,SAA6B,CAAA;IACjC,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,CAAC,WAAW,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;QAChD,IAAI,OAAO,CAAC,IAAI,CAAC,iBAAiB;YAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;QACnE,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC/C,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,MAAM,QAAQ,GAA2B;QACvC,wBAAwB,EAAE,SAAS;QACnC,iBAAiB,EAAE,YAAY;QAC/B,iBAAiB,EAAE,cAAc;KAClC,CAAA;IACD,IAAI,SAAS,KAAK,SAAS;QAAE,QAAQ,CAAC,2BAA2B,CAAC,GAAG,SAAS,CAAA;IAC9E,IAAI,GAAG,KAAK,SAAS;QAAE,QAAQ,CAAC,yBAAyB,CAAC,GAAG,GAAG,CAAA;IAChE,IAAI,OAAO,CAAC,uBAAuB,KAAK,SAAS,EAAE,CAAC;QAClD,QAAQ,CAAC,4BAA4B,CAAC,GAAG,OAAO,CAAC,uBAAuB,CAAA;IAC1E,CAAC;IACD,IAAI,OAAO,CAAC,yBAAyB,KAAK,SAAS,EAAE,CAAC;QACpD,QAAQ,CAAC,8BAA8B,CAAC,GAAG,OAAO,CAAC,yBAAyB,CAAA;IAC9E,CAAC;IACD,IAAI,OAAO,CAAC,yBAAyB,KAAK,SAAS,EAAE,CAAC;QACpD,QAAQ,CAAC,8BAA8B,CAAC,GAAG,OAAO,CAAC,yBAAyB,CAAA;IAC9E,CAAC;IACD,IAAI,OAAO,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;QAC5C,QAAQ,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAA;IAC5D,CAAC;IAED,OAAO,kBAAkB,CACvB;QACE,IAAI,EAAE,kBAAkB;QACxB,eAAe,EAAE,QAAQ;KAC1B,EACD;QACE,EAAE,EAAE,eAAe,CAAC,gBAAgB;QACpC,MAAM,EAAE,kBAAkB;QAC1B,KAAK,EAAE,QAAQ;KAChB,CACF,CAAA;AACH,CAAC"}
package/dist/timing.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type ContextPlugin } from "@nifrajs/core/server";
1
2
  export interface TimingMetric {
2
3
  readonly name: string;
3
4
  readonly duration: number;
@@ -21,5 +22,7 @@ export interface TimingOptions {
21
22
  * Put request-rewriting middleware (for example `methodOverride`) before `timing()` so timing is
22
23
  * attached to the final routed request.
23
24
  */
24
- export declare function timing(options?: TimingOptions): import("@nifrajs/core/server").NifraPlugin<import("@nifrajs/core/server").AnyServer, import("@nifrajs/core/server").Server<any, any>>;
25
+ export declare function timing(options?: TimingOptions): ContextPlugin<{
26
+ timing: TimingControls;
27
+ }>;
25
28
  //# sourceMappingURL=timing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"timing.d.ts","sourceRoot":"","sources":["../src/timing.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACnE;AAED,MAAM,WAAW,aAAa;IAC5B,8FAA8F;IAC9F,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,CAAA;CAC7D;AAqCD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,yIAoEjD"}
1
+ {"version":3,"file":"timing.d.ts","sourceRoot":"","sources":["../src/timing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,sBAAsB,CAAA;AAG9E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACnE;AAED,MAAM,WAAW,aAAa;IAC5B,8FAA8F;IAC9F,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,CAAA;CAC7D;AAqCD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,aAAa,CAAC;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC,CAoE7F"}
package/dist/timing.js CHANGED
@@ -1,4 +1,4 @@
1
- import { definePlugin } from "@nifrajs/core/server";
1
+ import { defineContextPlugin } from "@nifrajs/core/server";
2
2
  import { withHeaders } from "./_utils.js";
3
3
  const TOKEN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
4
4
  function assertMetricName(name) {
@@ -73,7 +73,7 @@ export function timing(options = {}) {
73
73
  }
74
74
  },
75
75
  });
76
- return definePlugin("timing", (app) => app
76
+ return defineContextPlugin("timing", (app) => app
77
77
  .onRequest((req) => {
78
78
  if (!isEnabled(req))
79
79
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"timing.js","sourceRoot":"","sources":["../src/timing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"timing.js","sourceRoot":"","sources":["../src/timing.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { type NifraPlugin } from "@nifrajs/core/server";
1
+ import { type IdentityPlugin } from "@nifrajs/core/server";
2
2
  type MaybePromise<T> = T | Promise<T>;
3
3
  /**
4
4
  * A token-auth plugin (`bearer` / `apiKey`). Apply it with `app.use(auth)` - it rejects unauthorized
@@ -16,7 +16,7 @@ type MaybePromise<T> = T | Promise<T>;
16
16
  * const app = server().use(auth).get("/me", (c) => auth.requirePrincipal(c.req))
17
17
  * ```
18
18
  */
19
- export type AuthPlugin<P> = NifraPlugin & {
19
+ export type AuthPlugin<P> = IdentityPlugin & {
20
20
  /** The verified principal for this request, or `null` (no/invalid token in `optional` mode). */
21
21
  principal(request: Request): P | null;
22
22
  /** The verified principal, or **throws a `401` `Response`** when absent. */
@@ -1 +1 @@
1
- {"version":3,"file":"token-auth.d.ts","sourceRoot":"","sources":["../src/token-auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAErE,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;AAErC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,WAAW,GAAG;IACxC,gGAAgG;IAChG,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,GAAG,IAAI,CAAA;IACrC,4EAA4E;IAC5E,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,CAAA;CACtC,CAAA;AAqDD,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B;uGACmG;IACnG,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,YAAY,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACtE,yGAAyG;IACzG,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAYlE;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,sFAAsF;IACtF,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,YAAY,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACpE,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC;0EACsE;IACtE,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAC5B;AAoCD;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,mBAAmB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;AACxE,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"token-auth.d.ts","sourceRoot":"","sources":["../src/token-auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAEhF,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;AAErC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,cAAc,GAAG;IAC3C,gGAAgG;IAChG,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,GAAG,IAAI,CAAA;IACrC,4EAA4E;IAC5E,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,CAAA;CACtC,CAAA;AAqDD,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B;uGACmG;IACnG,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,YAAY,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACtE,yGAAyG;IACzG,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAYlE;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,sFAAsF;IACtF,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,YAAY,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACpE,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC;0EACsE;IACtE,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAC5B;AAoCD;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,mBAAmB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;AACxE,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { NIFRA_ASSURANCE, withRouteAssurance } from "@nifrajs/core/assurance";
2
- import { definePlugin } from "@nifrajs/core/server";
2
+ import { defineIdentityPlugin } from "@nifrajs/core/server";
3
3
  function createTokenAuth(config) {
4
4
  // Per-request principal cache: verify runs once (in beforeHandle), reads are free + can't desync.
5
5
  const store = new WeakMap();
@@ -7,7 +7,7 @@ function createTokenAuth(config) {
7
7
  status: 401,
8
8
  headers: config.challenge !== undefined ? { "www-authenticate": config.challenge } : {},
9
9
  });
10
- const plugin = definePlugin(config.name, (app) => app.beforeHandle(async (c) => {
10
+ const plugin = defineIdentityPlugin(config.name, (app) => app.beforeHandle(async (c) => {
11
11
  const token = config.extract(c.req);
12
12
  // Empty string is treated as "no credential" - never passed to verify.
13
13
  const principal = token !== undefined && token !== "" ? await config.verify(token) : null;
@@ -1 +1 @@
1
- {"version":3,"file":"token-auth.js","sourceRoot":"","sources":["../src/token-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"token-auth.js","sourceRoot":"","sources":["../src/token-auth.ts"],"names":[],"mappings":"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"}
@@ -14,10 +14,10 @@ export interface TrailingSlashOptions {
14
14
  * Remove trailing slashes from non-root paths. Redirect mode is the production default because it
15
15
  * canonicalizes URLs for clients and caches; rewrite mode is available for compatibility migrations.
16
16
  */
17
- export declare function trimTrailingSlash(options?: TrailingSlashOptions): import("@nifrajs/core/server").NifraPlugin<import("@nifrajs/core/server").AnyServer, import("@nifrajs/core/server").AnyServer>;
17
+ export declare function trimTrailingSlash(options?: TrailingSlashOptions): import("@nifrajs/core").IdentityPlugin;
18
18
  /**
19
19
  * Append a trailing slash to non-root paths. By default it skips file-looking paths such as
20
20
  * `/app.css`, which keeps static assets and extensionful API routes stable.
21
21
  */
22
- export declare function appendTrailingSlash(options?: TrailingSlashOptions): import("@nifrajs/core/server").NifraPlugin<import("@nifrajs/core/server").AnyServer, import("@nifrajs/core/server").AnyServer>;
22
+ export declare function appendTrailingSlash(options?: TrailingSlashOptions): import("@nifrajs/core").IdentityPlugin;
23
23
  //# sourceMappingURL=trailing-slash.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"trailing-slash.d.ts","sourceRoot":"","sources":["../src/trailing-slash.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,mEAAmE;IACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;IACvC,uGAAuG;IACvG,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,oGAAoG;IACpG,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;IACvC,mCAAmC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;CAC9D;AAsCD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,oBAAyB,kIAenE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,kIAiBrE"}
1
+ {"version":3,"file":"trailing-slash.d.ts","sourceRoot":"","sources":["../src/trailing-slash.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,mEAAmE;IACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;IACvC,uGAAuG;IACvG,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,oGAAoG;IACpG,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;IACvC,mCAAmC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;CAC9D;AAsCD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,oBAAyB,0CAenE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,0CAiBrE"}
@@ -1,4 +1,4 @@
1
- import { definePlugin } from "@nifrajs/core/server";
1
+ import { defineRouterPlugin } from "@nifrajs/core/server";
2
2
  const DEFAULT_METHODS = ["GET", "HEAD"];
3
3
  const REDIRECT_STATUSES = new Set([301, 302, 307, 308]);
4
4
  function validateStatus(status) {
@@ -33,7 +33,7 @@ export function trimTrailingSlash(options = {}) {
33
33
  const status = options.status ?? 308;
34
34
  validateStatus(status);
35
35
  const methods = methodsOf(options.methods);
36
- return definePlugin("trimTrailingSlash", (app) => app.onRequest((req) => {
36
+ return defineRouterPlugin("trimTrailingSlash", (app) => app.onRequest((req) => {
37
37
  if (!methods.has(req.method.toUpperCase()))
38
38
  return undefined;
39
39
  const path = new URL(req.url).pathname;
@@ -54,7 +54,7 @@ export function appendTrailingSlash(options = {}) {
54
54
  const ignoreFileExtensions = options.ignoreFileExtensions !== false;
55
55
  validateStatus(status);
56
56
  const methods = methodsOf(options.methods);
57
- return definePlugin("appendTrailingSlash", (app) => app.onRequest((req) => {
57
+ return defineRouterPlugin("appendTrailingSlash", (app) => app.onRequest((req) => {
58
58
  if (!methods.has(req.method.toUpperCase()))
59
59
  return undefined;
60
60
  const path = new URL(req.url).pathname;
@@ -1 +1 @@
1
- {"version":3,"file":"trailing-slash.js","sourceRoot":"","sources":["../src/trailing-slash.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trailing-slash.js","sourceRoot":"","sources":["../src/trailing-slash.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nifrajs/middleware",
3
- "version": "2.11.0",
3
+ "version": "2.12.0",
4
4
  "description": "Composable middleware for nifra - auth, CSRF, JWT/JWKS, IP restriction, CORS, body limits, response cache, timing, and operational helpers.",
5
5
  "keywords": [
6
6
  "bun",
@@ -46,10 +46,10 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@nifrajs/schema": "2.11.0"
49
+ "@nifrajs/schema": "2.12.0"
50
50
  },
51
51
  "peerDependencies": {
52
- "@nifrajs/core": "^2.11.0"
52
+ "@nifrajs/core": "^2.12.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@nifrajs/core": "workspace:*",
package/src/_utils.ts CHANGED
@@ -162,17 +162,34 @@ export function withHeaders(res: Response, apply: (headers: Headers) => void): R
162
162
  return res
163
163
  }
164
164
 
165
- /** Mutate Node-direct response headers without constructing a Web Response. */
166
- export function withNodeHeaders(
165
+ /**
166
+ * Set one Node-direct response header without constructing a Web Response. `name` must already be
167
+ * the lowercase wire spelling - the record documents that contract, and it is what `Headers` emits
168
+ * on every other runtime.
169
+ *
170
+ * The outcome's own record is used AS-IS. Re-homing it into a null-prototype object - the obvious
171
+ * way to make `__proto__` inert - demotes it to V8's dictionary mode for the rest of the request,
172
+ * and everything downstream then pays dictionary lookups on the response hot path: the direct
173
+ * writer's key walk, and Node's own `_storeHeader` walk over every name. Values here are strings and
174
+ * string arrays, so assigning one through the inherited `__proto__` setter is a spec-level no-op
175
+ * rather than pollution; the single name that setter would swallow is defined as an own data
176
+ * property instead. Same trade core's portable header view makes over the same record.
177
+ */
178
+ export function setNodeHeader(
167
179
  res: NodeResponseContext,
168
- apply: (headers: Record<string, string | readonly string[]>) => void,
180
+ name: string,
181
+ value: string | readonly string[],
169
182
  ): void {
170
- if (res.headers === undefined) {
171
- res.headers = Object.create(null) as Record<string, string | readonly string[]>
172
- } else if (Object.getPrototypeOf(res.headers) !== null) {
173
- const safe = Object.create(null) as Record<string, string | readonly string[]>
174
- Object.assign(safe, res.headers)
175
- res.headers = safe
183
+ res.headers ??= {}
184
+ const headers = res.headers
185
+ if (name === "__proto__") {
186
+ Object.defineProperty(headers, name, {
187
+ value,
188
+ writable: true,
189
+ enumerable: true,
190
+ configurable: true,
191
+ })
192
+ return
176
193
  }
177
- apply(res.headers)
194
+ headers[name] = value
178
195
  }
package/src/basic-auth.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { NIFRA_ASSURANCE, withRouteAssurance } from "@nifrajs/core/assurance"
2
- import { definePlugin, type NifraPlugin } from "@nifrajs/core/server"
2
+ import { defineIdentityPlugin, type IdentityPlugin } from "@nifrajs/core/server"
3
3
  import {
4
4
  decodeBase64,
5
5
  jsonError,
@@ -9,7 +9,7 @@ import {
9
9
  timingSafeEqualBytes,
10
10
  } from "./_utils.ts"
11
11
 
12
- export type BasicAuthPlugin<P> = NifraPlugin & {
12
+ export type BasicAuthPlugin<P> = IdentityPlugin & {
13
13
  principal(request: Request): P | null
14
14
  requirePrincipal(request: Request): P
15
15
  }
@@ -87,7 +87,7 @@ export function basicAuth<P>(
87
87
  ? Promise.resolve(options.verify)
88
88
  : staticVerifier(options.username, options.password, options.principal ?? options.username)
89
89
 
90
- const plugin = definePlugin("basicAuth", (app) =>
90
+ const plugin = defineIdentityPlugin("basicAuth", (app) =>
91
91
  app.beforeHandle(async (c: { readonly req: Request }) => {
92
92
  const parsed = credentials(c.req)
93
93
  const principal =
@@ -1,4 +1,4 @@
1
- import { definePlugin, type Middleware } from "@nifrajs/core/server"
1
+ import { defineRouterPlugin, type Middleware } from "@nifrajs/core/server"
2
2
  import { withHeaders } from "./_utils.ts"
3
3
 
4
4
  export interface CacheControlOptions {
@@ -30,7 +30,7 @@ export function cacheControl(
30
30
  const methods = new Set((options.methods ?? ["GET", "HEAD"]).map((m) => m.toUpperCase()))
31
31
  const statusOk = options.status ?? ((status: number) => status >= 200 && status < 300)
32
32
  const respectExisting = options.respectExisting !== false
33
- return definePlugin("cacheControl", (app) => {
33
+ return defineRouterPlugin("cacheControl", (app) => {
34
34
  // A fixed directive needs nothing from the request beyond the method, so it ships as one
35
35
  // portable header hook. A dynamic directive's resolver takes a real `Request`, which only the
36
36
  // Web response walk carries - it keeps the full `onResponse` contract (and its cost).
package/src/cache.ts CHANGED
@@ -89,6 +89,8 @@ export interface CacheOptions {
89
89
  * personalized response (RFC 9111 §3.5), or it would be replayed to other users. Leave this off unless
90
90
  * the cached route is genuinely the same for every caller. */
91
91
  readonly cacheAuthenticated?: boolean
92
+ /** Credential headers that make a request private. Defaults to Authorization, Cookie, and x-api-key. */
93
+ readonly authenticatedHeaders?: readonly string[]
92
94
  /** Response header for cache status. Default `"x-nifra-cache"`; set `false` to disable. */
93
95
  readonly cacheStatusHeader?: string | false
94
96
  }
@@ -199,12 +201,17 @@ export function cache(options: CacheOptions): Middleware {
199
201
  const respectResponseCacheControl = options.respectResponseCacheControl !== false
200
202
  const cacheSetCookie = options.cacheSetCookie === true
201
203
  const cacheAuthenticated = options.cacheAuthenticated === true
204
+ const authenticatedHeaders = (
205
+ options.authenticatedHeaders ?? ["authorization", "cookie", "x-api-key"]
206
+ ).map((header) => header.toLowerCase())
202
207
  const cacheStatusHeader =
203
208
  options.cacheStatusHeader === undefined ? "x-nifra-cache" : options.cacheStatusHeader
204
209
  if (cacheStatusHeader !== false && cacheStatusHeader.trim() === "") {
205
210
  throw new Error("cache: cacheStatusHeader is empty")
206
211
  }
207
212
  const hits = new WeakSet<Request>()
213
+ const hasAuthentication = (req: Request): boolean =>
214
+ authenticatedHeaders.some((header) => req.headers.has(header))
208
215
 
209
216
  return {
210
217
  name: "cache",
@@ -216,6 +223,18 @@ export function cache(options: CacheOptions): Middleware {
216
223
  const key = keyOf(req)
217
224
  const entry = await store.get(key)
218
225
  if (entry === undefined) return undefined
226
+ // Never replay a personalized entry before route-scoped authentication runs. Public entries
227
+ // remain eligible (and are explicitly marked by their response Cache-Control metadata).
228
+ if (
229
+ !cacheAuthenticated &&
230
+ hasAuthentication(req) &&
231
+ !cacheControlHas(new Headers(entry.headers as Array<[string, string]>), [
232
+ "public",
233
+ "s-maxage",
234
+ ])
235
+ ) {
236
+ return undefined
237
+ }
219
238
  if (Date.now() >= entry.expiresAt) {
220
239
  await store.delete?.(key)
221
240
  return undefined
@@ -251,7 +270,7 @@ export function cache(options: CacheOptions): Middleware {
251
270
  // across users. Opt in with `cacheAuthenticated: true` for a route that's the same for everyone.
252
271
  if (
253
272
  !cacheAuthenticated &&
254
- (req.headers.has("authorization") || req.headers.has("cookie")) &&
273
+ hasAuthentication(req) &&
255
274
  !cacheControlHas(res.headers, ["public", "s-maxage"])
256
275
  ) {
257
276
  return withStatusHeader(res, cacheStatusHeader, "BYPASS")
package/src/combine.ts CHANGED
@@ -1,24 +1,36 @@
1
- import { definePlugin, type Middleware, type NifraPlugin } from "@nifrajs/core/server"
1
+ import {
2
+ type AnyServer,
3
+ defineIdentityPlugin,
4
+ type IdentityPlugin,
5
+ type Middleware,
6
+ } from "@nifrajs/core/server"
2
7
 
3
- export type Composable = Middleware | NifraPlugin
8
+ export type Composable = Middleware | IdentityPlugin
4
9
 
5
- function applyAll(app: Parameters<NifraPlugin>[0], items: readonly Composable[]) {
6
- let current = app
10
+ function applyAll<S extends AnyServer>(app: S, items: readonly Composable[]): S {
11
+ let current: AnyServer = app
7
12
  for (const item of items) {
8
13
  // The public `use` overload accepts both shapes; this helper intentionally preserves runtime
9
14
  // composition while leaving advanced context type threading to direct `.use(...)` chains.
10
15
  current = current.use(item as never)
11
16
  }
12
- return current
17
+ return current as S
13
18
  }
14
19
 
15
- /** Compose middleware/plugins into one reusable bundle. Individual named plugins still dedupe. */
16
- export function combine(...items: readonly Composable[]): NifraPlugin {
17
- return ((app) => applyAll(app, items)) as NifraPlugin
20
+ /**
21
+ * Compose middleware/plugins into one reusable bundle. Individual named plugins still dedupe.
22
+ *
23
+ * The bundle is a type **identity**: everything it contains runs, but context a member adds via
24
+ * `derive`/`decorate` is not threaded to the caller's handler types (there is no way to sum unknown
25
+ * members' context at the type level). Apply such a member with its own `.use(...)` instead.
26
+ */
27
+ export function combine(...items: readonly Composable[]): IdentityPlugin {
28
+ // No `pluginName`: an unnamed bundle is applied every time rather than deduped.
29
+ return <S extends AnyServer>(app: S): S => applyAll(app, items)
18
30
  }
19
31
 
20
32
  /** Compose middleware/plugins into one idempotent named bundle. */
21
- export function namedCombine(name: string, ...items: readonly Composable[]): NifraPlugin {
33
+ export function namedCombine(name: string, ...items: readonly Composable[]): IdentityPlugin {
22
34
  if (name.trim() === "") throw new Error("namedCombine: name is empty")
23
- return definePlugin(name, (app) => applyAll(app, items))
35
+ return defineIdentityPlugin(name, (app) => applyAll(app, items))
24
36
  }
@@ -1,4 +1,4 @@
1
- import { definePlugin, type ResponseHeadersView } from "@nifrajs/core/server"
1
+ import { defineRouterPlugin, type ResponseHeadersView } from "@nifrajs/core/server"
2
2
 
3
3
  export interface CompressionOptions {
4
4
  /** Don't compress bodies smaller than this many bytes. Default `1024`. Enforced by peeking the body
@@ -217,6 +217,13 @@ function replayRawResponse(
217
217
  * types, and bodies below `threshold` (gzip's ~20-byte overhead would enlarge them). Adds
218
218
  * `Vary: Accept-Encoding`.
219
219
  *
220
+ * **Security (BREACH).** Compression makes the response length depend on its content, so a response
221
+ * that mixes a secret with attacker-reflected input leaks the secret through the compressed size
222
+ * (the BREACH class of attacks). This applies to any HTTP compression, not this middleware
223
+ * specifically. Nifra's own CSRF tokens are HMAC-signed per session and safe to compress, but if a
224
+ * response body reflects request input **and** carries a per-request secret, exclude that route via
225
+ * `compressible`/route scoping, or split the secret and the reflection into separate responses.
226
+ *
220
227
  * ```ts
221
228
  * app.use(compression())
222
229
  * ```
@@ -227,7 +234,7 @@ export function compression(options: CompressionOptions = {}) {
227
234
  throw new Error("compression: threshold must be a non-negative safe integer")
228
235
  }
229
236
  const isCompressible = options.compressible ?? defaultCompressible
230
- return definePlugin("compression", (app) =>
237
+ return defineRouterPlugin("compression", (app) =>
231
238
  app.use({
232
239
  onResponseBody(body, headers, req, status) {
233
240
  if (!acceptsGzip(req.header("accept-encoding"))) return undefined