@erenthedeveloper0/zen-middleware 0.1.0-alpha.2 → 0.1.0-alpha.4

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
@@ -68,6 +68,11 @@ works in the browser and one that works only in Postman.
68
68
  The pack orders itself: register them in any order and they run request id →
69
69
  security headers → CORS → rate limit.
70
70
 
71
+ Each factory has an options schema, checked at boot before any plugin runs, so
72
+ `rateLimit({ limt: 100 })` fails with `"limt" is not an option of rate-limit —
73
+ did you mean "limit"?` rather than running with the default limit. The refusal
74
+ names the key, never the value.
75
+
71
76
  ## Behind a proxy
72
77
 
73
78
  `ctx.ip` — and so the rate limiter — reads `X-Forwarded-For` only when the app
@@ -1 +1 @@
1
- {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"AAAA,OAAO,EAEU,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,KAAK,MAAM,EAC3D,MAAM,6BAA6B,CAAA;AAIpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,MAAM,MAAM,UAAU,GAClB,GAAG,GACH,MAAM,GACN,SAAS,MAAM,EAAE,GACjB,MAAM,GACN,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAA;AAEjC,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;IACxC;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,GAAG,SAAS,CAAA;IACpD;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,SAAS,CAAA;IACnE,mHAAmH;IACnH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IACvD,gFAAgF;IAChF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC1C;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IACtC,0EAA0E;IAC1E,QAAQ,CAAC,eAAe,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,SAAS,CAAA;CACjD;AAID,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,GAAG,SAAS,CAAA;IACvD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;CAC9B;AA2BD,wBAAgB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAqGhE"}
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"AAAA,OAAO,EAEU,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,KAAK,MAAM,EAC3D,MAAM,6BAA6B,CAAA;AAOpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,MAAM,MAAM,UAAU,GAClB,GAAG,GACH,MAAM,GACN,SAAS,MAAM,EAAE,GACjB,MAAM,GACN,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAA;AAEjC,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;IACxC;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,GAAG,SAAS,CAAA;IACpD;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,SAAS,CAAA;IACnE,mHAAmH;IACnH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IACvD,gFAAgF;IAChF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC1C;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IACtC,0EAA0E;IAC1E,QAAQ,CAAC,eAAe,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,SAAS,CAAA;CACjD;AAID,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,GAAG,SAAS,CAAA;IACvD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;CAC9B;AAsCD,wBAAgB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAuGhE"}
package/dist/cors.js CHANGED
@@ -1,11 +1,23 @@
1
1
  import { definePlugin, parseDuration, Codes, ZenError, } from '@erenthedeveloper0/zen-core';
2
2
  import { assertCorsCorpConsistent } from "./consistency.js";
3
- import { headerOf, isPreflight } from "./shared.js";
3
+ import { BOOLEAN, DURATION, FUNCTION, REGEXP, STRING, STRINGS, either, headerOf, isPreflight, oneOf, optionsSchema, } from "./shared.js";
4
4
  const DEFAULT_METHODS = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'];
5
+ /** §10.5 step 2 — checked at boot, so `cors({ credential: true })` is refused with "did you mean "credentials"?". */
6
+ const OPTIONS = optionsSchema('cors', {
7
+ origin: either(STRING, STRINGS, REGEXP, FUNCTION),
8
+ methods: STRINGS,
9
+ allowedHeaders: either(oneOf('reflect'), STRINGS),
10
+ exposedHeaders: STRINGS,
11
+ credentials: BOOLEAN,
12
+ maxAge: DURATION,
13
+ preflightStatus: oneOf(200, 204),
14
+ });
5
15
  export function cors(options = {}) {
6
16
  return definePlugin({
7
17
  name: 'cors',
8
18
  version: '0.1.0',
19
+ options: OPTIONS,
20
+ boundOptions: options,
9
21
  // The pack orders itself (§10.5 step 4). A 429 or a 404 must carry
10
22
  // `Access-Control-Allow-Origin` or the browser reports a rate limit as a
11
23
  // CORS failure, so this hook has to be staged before the limiter can
@@ -176,11 +188,16 @@ function compile(written, config, pluginName) {
176
188
  ? ((only) => (o) => o === only)(list[0])
177
189
  : ((set) => (o) => set.has(o))(new Set(list))
178
190
  : origin instanceof RegExp
179
- // A fresh test each call: a global regex carries `lastIndex` between
180
- // calls and would match every other request. §19.3 forbids unbounded
181
- // backtracking in framework source; a user's own pattern is their
182
- // choice, and it is named in `explainRoute` as `cors`.
183
- ? ((re) => (o) => new RegExp(re.source, re.flags.replace('g', '')).test(o))(origin)
191
+ // Compiled once, here, without the `g` flag — I1 keeps regex compilation
192
+ // off the request path, and this hook runs on every request with an
193
+ // `Origin`. A global regex carries `lastIndex` between calls and would
194
+ // match every other request; so does a sticky one, whose anchoring is
195
+ // the point of writing `y`, so `lastIndex` is put back to 0 before each
196
+ // test rather than the flag being dropped. The copy is ours, so the
197
+ // application's own RegExp object is never touched. §19.3 forbids
198
+ // unbounded backtracking in framework source; a user's own pattern is
199
+ // their choice, and it is named in `explainRoute` as `cors`.
200
+ ? ((re) => (o) => { re.lastIndex = 0; return re.test(o); })(new RegExp(origin.source, origin.flags.replace('g', '')))
184
201
  : origin;
185
202
  return {
186
203
  anyOrigin,
package/dist/cors.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cors.js","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cors.js","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EAAE,KAAK,MAAM,EAC3B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAe,KAAK,KAAK,EAAc,MAAM,YAAY,CAAA;AAGhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,SAAS,CAAA;IACrE,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAA;IAClC,+GAA+G;IAC/G,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC5C,yEAAyE;IACzE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9C,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,GAAG,EAAE;QAAE,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;CAC1D;AAID,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CA4F1E"}
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EAAE,KAAK,MAAM,EAC3B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAe,KAAK,KAAK,EAAc,MAAM,YAAY,CAAA;AAMhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,SAAS,CAAA;IACrE,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAA;IAClC,+GAA+G;IAC/G,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC5C,yEAAyE;IACzE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9C,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,GAAG,EAAE;QAAE,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;CAC1D;AAiBD,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CA8F1E"}
@@ -1,10 +1,24 @@
1
1
  import { definePlugin, parseDuration, Codes, TooManyRequests, ZenError, } from '@erenthedeveloper0/zen-core';
2
2
  import { MemoryStore } from "./store.js";
3
+ import { BOOLEAN, DURATION, FUNCTION, NUMBER, STRING, optionsSchema, } from "./shared.js";
3
4
  const DEFAULTS = { limit: 100, window: '1m' };
5
+ /** A store is anything with `hit` — `store.ts`'s contract, checked by shape. */
6
+ const STORE = {
7
+ expected: 'a store with a hit() method',
8
+ accepts: (v) => typeof v === 'object' && v !== null && typeof v.hit === 'function',
9
+ json: { type: 'object' },
10
+ };
11
+ /** §10.5 step 2 — checked at boot, so `rateLimit({ limt: 100 })` is refused with "did you mean "limit"?". */
12
+ const OPTIONS = optionsSchema('rateLimit', {
13
+ limit: NUMBER, window: DURATION, key: FUNCTION, store: STORE,
14
+ legacyHeaders: BOOLEAN, standardHeaders: BOOLEAN, message: STRING,
15
+ });
4
16
  export function rateLimit(options = {}) {
5
17
  return definePlugin({
6
18
  name: 'rate-limit',
7
19
  version: '0.1.0',
20
+ options: OPTIONS,
21
+ boundOptions: options,
8
22
  config: { namespace: 'rateLimit', defaults: { limit: DEFAULTS.limit, window: DEFAULTS.window } },
9
23
  setup(app) {
10
24
  // §16.1 layer order: an explicit option beats the plugin's own layer-2
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"request-id.d.ts","sourceRoot":"","sources":["../src/request-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,MAAM,EAAE,MAAM,6BAA6B,CAAA;AAwDxF,MAAM,WAAW,gBAAgB;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA;IAC5C;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IACnD,kEAAkE;IAClE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA;CACrD;AAaD,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CA8C1E"}
1
+ {"version":3,"file":"request-id.d.ts","sourceRoot":"","sources":["../src/request-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,MAAM,EAAE,MAAM,6BAA6B,CAAA;AA4DxF,MAAM,WAAW,gBAAgB;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA;IAC5C;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IACnD,kEAAkE;IAClE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA;CACrD;AAoBD,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAgD1E"}
@@ -1,4 +1,5 @@
1
1
  import { definePlugin, Codes, ZenError } from '@erenthedeveloper0/zen-core';
2
+ import { BOOLEAN, STRING, either, oneOf, optionsSchema, } from "./shared.js";
2
3
  /**
3
4
  * 8–128 of `[A-Za-z0-9._-]`.
4
5
  *
@@ -9,6 +10,12 @@ import { definePlugin, Codes, ZenError } from '@erenthedeveloper0/zen-core';
9
10
  * request, so an unbounded one is an amplification the caller chooses.
10
11
  */
11
12
  const ACCEPTABLE = /^[A-Za-z0-9._-]{8,128}$/;
13
+ /** §10.5 step 2 — checked at boot, so `requestId({ trustHeaders: true })` is refused with "did you mean "trustHeader"?". */
14
+ const OPTIONS = optionsSchema('requestId', {
15
+ header: either(STRING, oneOf(false)),
16
+ trustHeader: either(BOOLEAN, STRING),
17
+ rejectedHeader: either(STRING, oneOf(false)),
18
+ });
12
19
  export function requestId(options = {}) {
13
20
  const echo = options.header === undefined ? 'x-request-id' : options.header;
14
21
  const trust = options.trustHeader === undefined || options.trustHeader === false ? null
@@ -27,6 +34,8 @@ export function requestId(options = {}) {
27
34
  return definePlugin({
28
35
  name: 'request-id',
29
36
  version: '0.1.0',
37
+ options: OPTIONS,
38
+ boundOptions: options,
30
39
  // First in the pack: a preflight answered by `cors` and a 429 refused by
31
40
  // `rate-limit` both short-circuit, and both should still carry the id that
32
41
  // the log line for them will be filed under.
@@ -1 +1 @@
1
- {"version":3,"file":"request-id.js","sourceRoot":"","sources":["../src/request-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAe,MAAM,6BAA6B,CAAA;AAuExF;;;;;;;;GAQG;AACH,MAAM,UAAU,GAAG,yBAAyB,CAAA;AAE5C,MAAM,UAAU,SAAS,CAAC,UAA4B,EAAE;IACtD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAA;IAC3E,MAAM,KAAK,GACT,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI;QACzE,CAAC,CAAC,OAAO,CAAC,WAAW,KAAK,IAAI;YAC5B,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1C,CAAC,CAAC,OAAO,CAAC,WAAW,CAAA;IACzB,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAA;IAExG,IAAI,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACrC,MAAM,IAAI,QAAQ,CAChB,KAAK,CAAC,cAAc,EACpB,qGAAqG,EACrG;YACE,MAAM,EAAE,GAAG;YACX,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,0GAA0G;YAChH,WAAW,EAAE,4EAA4E;SAC1F,CACF,CAAA;IACH,CAAC;IAED,OAAO,YAAY,CAAW;QAC5B,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;QAChB,yEAAyE;QACzE,2EAA2E;QAC3E,6CAA6C;QAC7C,MAAM,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,kBAAkB,CAAC;QAElD,KAAK,CAAC,GAAG;YACP,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,SAAS,CAAC,GAAqC;gBAC5E,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBACnB,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;oBACrC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;wBAC1B,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;4BAAE,GAAG,CAAC,EAAE,GAAG,OAAO,CAAA;6BACzC,IAAI,QAAQ,KAAK,KAAK;4BAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;oBAC5D,CAAC;gBACH,CAAC;gBACD,IAAI,IAAI,KAAK,KAAK;oBAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;gBAChD,OAAO,SAAS,CAAA;YAClB,CAAC,EAAE,YAAY,CAAC,CAAA;YAEhB,OAAO,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAA;QACrD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"request-id.js","sourceRoot":"","sources":["../src/request-id.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,6BAA6B,CAAA;AAKvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,4BAA4B,GAC5B,QAAQ,GACR,0BAA0B,GAC1B,aAAa,GACb,eAAe,GACf,iCAAiC,GACjC,YAAY,CAAA;AAEhB,MAAM,WAAW,sBAAsB;IACrC,0GAA0G;IAC1G,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACtC,mGAAmG;IACnG,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,KAAK,GAAG,SAAS,CAAA;IACjE,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,KAAK,GAAG,SAAS,CAAA;IAC5D,oCAAoC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,aAAa,GAAG,0BAA0B,GAAG,aAAa,GAAG,KAAK,GAAG,SAAS,CAAA;IAC3G;;;;;;;OAOG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,aAAa,GAAG,WAAW,GAAG,cAAc,GAAG,KAAK,GAAG,SAAS,CAAA;IAC/F;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,KAAK,GAAG,SAAS,CAAA;IAClI;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA;IAC3D,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;CAChE;AAKD,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CA8BtF"}
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,6BAA6B,CAAA;AAOvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,4BAA4B,GAC5B,QAAQ,GACR,0BAA0B,GAC1B,aAAa,GACb,eAAe,GACf,iCAAiC,GACjC,YAAY,CAAA;AAEhB,MAAM,WAAW,sBAAsB;IACrC,0GAA0G;IAC1G,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACtC,mGAAmG;IACnG,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,KAAK,GAAG,SAAS,CAAA;IACjE,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,KAAK,GAAG,SAAS,CAAA;IAC5D,oCAAoC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,aAAa,GAAG,0BAA0B,GAAG,aAAa,GAAG,KAAK,GAAG,SAAS,CAAA;IAC3G;;;;;;;OAOG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,aAAa,GAAG,WAAW,GAAG,cAAc,GAAG,KAAK,GAAG,SAAS,CAAA;IAC/F;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,KAAK,GAAG,SAAS,CAAA;IAClI;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA;IAC3D,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;CAChE;AAyCD,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAgCtF"}
package/dist/security.js CHANGED
@@ -1,9 +1,41 @@
1
1
  import { definePlugin } from '@erenthedeveloper0/zen-core';
2
2
  import { assertCorsCorpConsistent } from "./consistency.js";
3
+ import { BOOLEAN, STRING, STRING_RECORD, either, oneOf, optionsSchema, } from "./shared.js";
4
+ const HSTS = {
5
+ expected: 'false, or { maxAge?: number, includeSubDomains?: boolean, preload?: boolean }',
6
+ accepts: (v) => v === false ||
7
+ (typeof v === 'object' && v !== null && !Array.isArray(v) &&
8
+ Object.entries(v).every(([key, value]) => key === 'maxAge' ? typeof value === 'number'
9
+ : key === 'includeSubDomains' || key === 'preload' ? typeof value === 'boolean'
10
+ : false)),
11
+ json: {
12
+ anyOf: [
13
+ { const: false },
14
+ {
15
+ type: 'object',
16
+ properties: { maxAge: { type: 'number' }, includeSubDomains: { type: 'boolean' }, preload: { type: 'boolean' } },
17
+ additionalProperties: false,
18
+ },
19
+ ],
20
+ },
21
+ };
22
+ /** §10.5 step 2 — checked at boot, so `securityHeaders({ frameOption: 'DENY' })` is refused by name. */
23
+ const OPTIONS = optionsSchema('securityHeaders', {
24
+ noSniff: BOOLEAN,
25
+ frameOptions: oneOf('DENY', 'SAMEORIGIN', false),
26
+ referrerPolicy: oneOf('no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'same-origin', 'strict-origin', 'strict-origin-when-cross-origin', 'unsafe-url', false),
27
+ crossOriginOpener: oneOf('same-origin', 'same-origin-allow-popups', 'unsafe-none', false),
28
+ crossOriginResource: oneOf('same-origin', 'same-site', 'cross-origin', false),
29
+ hsts: HSTS,
30
+ contentSecurityPolicy: either(STRING, oneOf(false)),
31
+ headers: STRING_RECORD,
32
+ });
3
33
  export function securityHeaders(options = {}) {
4
34
  return definePlugin({
5
35
  name: 'security-headers',
6
36
  version: '0.1.0',
37
+ options: OPTIONS,
38
+ boundOptions: options,
7
39
  // Before everything that can short-circuit. `cors` answers preflights and
8
40
  // `rate-limit` throws 429s; a hook that runs after either is absent from
9
41
  // exactly the responses §19.2 most wants these headers on. Hints on
@@ -1 +1 @@
1
- {"version":3,"file":"security.js","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"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"}
package/dist/shared.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ReplyBuilder, Reply, LowercaseName } from '@erenthedeveloper0/zen-core';
1
+ import type { AnySchema, JsonSchemaNode, LowercaseName, Reply, ReplyBuilder } from '@erenthedeveloper0/zen-core';
2
2
  /**
3
3
  * What this pack touches on a context, declared structurally — §10.4.
4
4
  *
@@ -52,4 +52,46 @@ export declare function headerOf(ctx: RawReading, name: LowercaseName): string |
52
52
  * that route with something the application did not write.
53
53
  */
54
54
  export declare function isPreflight(ctx: RawReading): boolean;
55
+ /** One option a factory accepts, stated twice: as a check, and as JSON Schema. */
56
+ export interface OptionField {
57
+ /** What the option must be, completing "expected …". */
58
+ readonly expected: string;
59
+ readonly accepts: (value: unknown) => boolean;
60
+ readonly json: JsonSchemaNode;
61
+ }
62
+ /**
63
+ * The options schema of a factory in this pack.
64
+ *
65
+ * §8.6's motivating sentence is "`rateLimit({ limt: 100 })` fails at startup
66
+ * with a spelling suggestion, not at 3 a.m. under load", and the pack is where
67
+ * that sentence is about. A factory hands its options to core as
68
+ * `Plugin.boundOptions`, against this schema as `Plugin.options`, and they are
69
+ * checked at boot before any plugin's `setup` runs.
70
+ *
71
+ * Hand-written Standard Schemas, so the pack keeps its zero dependencies. The
72
+ * work is split with core so nothing is reported twice: `validate` checks the
73
+ * type of each option that is present, and core reads the schema's JSON Schema
74
+ * — a closed object — to name every key it does not declare, with the one it
75
+ * was probably meant to be. A schema that also refused unknown keys would put
76
+ * every typo in the diagnostic twice.
77
+ *
78
+ * It returns the options it was given, unchanged: a factory reads them from
79
+ * its closure, so what it was built with is exactly what boot checked. The
80
+ * checks a value needs beyond its type — a `limit` below one, an origin with a
81
+ * trailing slash — stay in the factory, because configuration supplies the
82
+ * same values and must meet the same rule.
83
+ */
84
+ export declare function optionsSchema(factory: string, fields: Readonly<Record<string, OptionField>>): AnySchema;
85
+ export declare const BOOLEAN: OptionField;
86
+ export declare const STRING: OptionField;
87
+ export declare const NUMBER: OptionField;
88
+ export declare const FUNCTION: OptionField;
89
+ export declare const REGEXP: OptionField;
90
+ export declare const DURATION: OptionField;
91
+ export declare const STRINGS: OptionField;
92
+ export declare const STRING_RECORD: OptionField;
93
+ /** Exactly one of these values. */
94
+ export declare function oneOf(...values: readonly (string | number | boolean)[]): OptionField;
95
+ /** Any one of these fields. */
96
+ export declare function either(...fields: readonly OptionField[]): OptionField;
55
97
  //# sourceMappingURL=shared.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAErF;;;;;;;;;;;;;GAaG;AAEH,mEAAmE;AACnE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,GAAG,EAAE;QAAE,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;CAClE;AAED,2EAA2E;AAC3E,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAA;CAC3B;AAED,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IAC5C,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;CACvD;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,CAAA;AAEhD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAEjF;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAEpD"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAAc,cAAc,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAC1E,MAAM,6BAA6B,CAAA;AAEpC;;;;;;;;;;;;;GAaG;AAEH,mEAAmE;AACnE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,GAAG,EAAE;QAAE,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;CAClE;AAED,2EAA2E;AAC3E,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAA;CAC3B;AAED,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IAC5C,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;CACvD;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,CAAA;AAEhD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAEjF;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAEpD;AAMD,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;IAC7C,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,GAAG,SAAS,CA0BvG;AAKD,eAAO,MAAM,OAAO,aAA6E,CAAA;AACjG,eAAO,MAAM,MAAM,aAAsE,CAAA;AACzF,eAAO,MAAM,MAAM,aAAsE,CAAA;AACzF,eAAO,MAAM,QAAQ,aAAsD,CAAA;AAC3E,eAAO,MAAM,MAAM,aAAgD,CAAA;AACnE,eAAO,MAAM,QAAQ,aAIpB,CAAA;AACD,eAAO,MAAM,OAAO,aAInB,CAAA;AACD,eAAO,MAAM,aAAa,aAIzB,CAAA;AAED,mCAAmC;AACnC,wBAAgB,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,GAAG,WAAW,CAEpF;AAED,+BAA+B;AAC/B,wBAAgB,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,CAMrE"}
package/dist/shared.js CHANGED
@@ -22,4 +22,72 @@ export function headerOf(ctx, name) {
22
22
  export function isPreflight(ctx) {
23
23
  return ctx.method === 'OPTIONS' && ctx.raw.header('access-control-request-method') !== undefined;
24
24
  }
25
+ /**
26
+ * The options schema of a factory in this pack.
27
+ *
28
+ * §8.6's motivating sentence is "`rateLimit({ limt: 100 })` fails at startup
29
+ * with a spelling suggestion, not at 3 a.m. under load", and the pack is where
30
+ * that sentence is about. A factory hands its options to core as
31
+ * `Plugin.boundOptions`, against this schema as `Plugin.options`, and they are
32
+ * checked at boot before any plugin's `setup` runs.
33
+ *
34
+ * Hand-written Standard Schemas, so the pack keeps its zero dependencies. The
35
+ * work is split with core so nothing is reported twice: `validate` checks the
36
+ * type of each option that is present, and core reads the schema's JSON Schema
37
+ * — a closed object — to name every key it does not declare, with the one it
38
+ * was probably meant to be. A schema that also refused unknown keys would put
39
+ * every typo in the diagnostic twice.
40
+ *
41
+ * It returns the options it was given, unchanged: a factory reads them from
42
+ * its closure, so what it was built with is exactly what boot checked. The
43
+ * checks a value needs beyond its type — a `limit` below one, an origin with a
44
+ * trailing slash — stay in the factory, because configuration supplies the
45
+ * same values and must meet the same rule.
46
+ */
47
+ export function optionsSchema(factory, fields) {
48
+ const properties = {};
49
+ for (const key of Object.keys(fields))
50
+ properties[key] = fields[key].json;
51
+ const shape = { type: 'object', properties, additionalProperties: false };
52
+ return {
53
+ '~standard': {
54
+ version: 1,
55
+ vendor: 'zen-middleware',
56
+ validate(value) {
57
+ if (value === undefined)
58
+ return { value: {} };
59
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
60
+ return { issues: [{ message: `${factory}() takes an options object` }] };
61
+ }
62
+ const given = value;
63
+ const issues = [];
64
+ for (const key of Object.keys(fields)) {
65
+ const option = given[key];
66
+ const field = fields[key];
67
+ if (option !== undefined && !field.accepts(option))
68
+ issues.push({ message: `expected ${field.expected}`, path: [key] });
69
+ }
70
+ return issues.length === 0 ? { value } : { issues };
71
+ },
72
+ },
73
+ toJsonSchema: () => shape,
74
+ };
75
+ }
76
+ const field = (expected, accepts, json = {}) => ({ expected, accepts, json });
77
+ export const BOOLEAN = field('true or false', (v) => typeof v === 'boolean', { type: 'boolean' });
78
+ export const STRING = field('a string', (v) => typeof v === 'string', { type: 'string' });
79
+ export const NUMBER = field('a number', (v) => typeof v === 'number', { type: 'number' });
80
+ export const FUNCTION = field('a function', (v) => typeof v === 'function');
81
+ export const REGEXP = field('a RegExp', (v) => v instanceof RegExp);
82
+ export const DURATION = field("a duration — milliseconds, or a string such as '10m'", (v) => typeof v === 'number' || typeof v === 'string', { type: ['number', 'string'] });
83
+ export const STRINGS = field('a list of strings', (v) => Array.isArray(v) && v.every((item) => typeof item === 'string'), { type: 'array', items: { type: 'string' } });
84
+ export const STRING_RECORD = field('an object of string values', (v) => typeof v === 'object' && v !== null && !Array.isArray(v) && Object.values(v).every((item) => typeof item === 'string'), { type: 'object', additionalProperties: { type: 'string' } });
85
+ /** Exactly one of these values. */
86
+ export function oneOf(...values) {
87
+ return field(values.map((value) => JSON.stringify(value)).join(', '), (v) => values.includes(v), { enum: [...values] });
88
+ }
89
+ /** Any one of these fields. */
90
+ export function either(...fields) {
91
+ return field(fields.map((f) => f.expected).join(', or '), (v) => fields.some((f) => f.accepts(v)), { anyOf: fields.map((f) => f.json) });
92
+ }
25
93
  //# sourceMappingURL=shared.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAoCA;;;;;;;;;GASG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAe,EAAE,IAAmB;IAC3D,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,GAAe;IACzC,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,+BAA+B,CAAC,KAAK,SAAS,CAAA;AAClG,CAAC"}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erenthedeveloper0/zen-middleware",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.4",
4
4
  "description": "Zen first-party middleware: CORS, security headers, request ids and rate limiting, as hooks that also run on unmatched requests.",
5
5
  "keywords": [
6
6
  "cors",
@@ -52,7 +52,7 @@
52
52
  "test": "node --test \"test/**/*.test.ts\""
53
53
  },
54
54
  "dependencies": {
55
- "@erenthedeveloper0/zen-core": "0.1.0-alpha.2"
55
+ "@erenthedeveloper0/zen-core": "0.1.0-alpha.4"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "typescript": ">=5.0"
package/src/cors.ts CHANGED
@@ -3,7 +3,10 @@ import {
3
3
  type AppGraph, type Duration, type HttpMethod, type Plugin, type Reply,
4
4
  } from '@erenthedeveloper0/zen-core'
5
5
  import { assertCorsCorpConsistent } from './consistency.ts'
6
- import { type CorsRequest, type Staging, headerOf, isPreflight } from './shared.ts'
6
+ import {
7
+ BOOLEAN, DURATION, FUNCTION, REGEXP, STRING, STRINGS, either, headerOf, isPreflight, oneOf, optionsSchema,
8
+ type CorsRequest, type OptionField, type Staging,
9
+ } from './shared.ts'
7
10
 
8
11
  /**
9
12
  * CORS — rfcs/0001 §19.2, §4.2 stage 5, §9.2.
@@ -148,10 +151,23 @@ interface Compiled {
148
151
  allowMethods: string
149
152
  }
150
153
 
154
+ /** §10.5 step 2 — checked at boot, so `cors({ credential: true })` is refused with "did you mean "credentials"?". */
155
+ const OPTIONS = optionsSchema('cors', {
156
+ origin: either(STRING, STRINGS, REGEXP, FUNCTION),
157
+ methods: STRINGS,
158
+ allowedHeaders: either(oneOf('reflect'), STRINGS),
159
+ exposedHeaders: STRINGS,
160
+ credentials: BOOLEAN,
161
+ maxAge: DURATION,
162
+ preflightStatus: oneOf(200, 204),
163
+ } satisfies Record<keyof CorsOptions, OptionField>)
164
+
151
165
  export function cors(options: CorsOptions = {}): Plugin<void, {}> {
152
166
  return definePlugin<void, {}>({
153
167
  name: 'cors',
154
168
  version: '0.1.0',
169
+ options: OPTIONS,
170
+ boundOptions: options,
155
171
  // The pack orders itself (§10.5 step 4). A 429 or a 404 must carry
156
172
  // `Access-Control-Allow-Origin` or the browser reports a rate limit as a
157
173
  // CORS failure, so this hook has to be staged before the limiter can
@@ -351,11 +367,16 @@ function compile(
351
367
  ? ((only) => (o) => o === only)(list[0] as string)
352
368
  : ((set) => (o) => set.has(o))(new Set(list))
353
369
  : origin instanceof RegExp
354
- // A fresh test each call: a global regex carries `lastIndex` between
355
- // calls and would match every other request. §19.3 forbids unbounded
356
- // backtracking in framework source; a user's own pattern is their
357
- // choice, and it is named in `explainRoute` as `cors`.
358
- ? ((re) => (o) => new RegExp(re.source, re.flags.replace('g', '')).test(o))(origin)
370
+ // Compiled once, here, without the `g` flag — I1 keeps regex compilation
371
+ // off the request path, and this hook runs on every request with an
372
+ // `Origin`. A global regex carries `lastIndex` between calls and would
373
+ // match every other request; so does a sticky one, whose anchoring is
374
+ // the point of writing `y`, so `lastIndex` is put back to 0 before each
375
+ // test rather than the flag being dropped. The copy is ours, so the
376
+ // application's own RegExp object is never touched. §19.3 forbids
377
+ // unbounded backtracking in framework source; a user's own pattern is
378
+ // their choice, and it is named in `explainRoute` as `cors`.
379
+ ? ((re) => (o: string) => { re.lastIndex = 0; return re.test(o) })(new RegExp(origin.source, origin.flags.replace('g', '')))
359
380
  : (origin as (o: string) => boolean)
360
381
 
361
382
  return {
package/src/rate-limit.ts CHANGED
@@ -3,7 +3,10 @@ import {
3
3
  type Duration, type Plugin, type Reply,
4
4
  } from '@erenthedeveloper0/zen-core'
5
5
  import { MemoryStore, type Store, type Tally } from './store.ts'
6
- import type { Answering, RawReading, Staging } from './shared.ts'
6
+ import {
7
+ BOOLEAN, DURATION, FUNCTION, NUMBER, STRING, optionsSchema,
8
+ type Answering, type OptionField, type RawReading, type Staging,
9
+ } from './shared.ts'
7
10
 
8
11
  /**
9
12
  * Rate limiting — rfcs/0001 §9.2, §19.2, §19.4, Annex B `ZEN_RATE_LIMITED`.
@@ -74,10 +77,25 @@ export interface RateLimitContext {
74
77
 
75
78
  const DEFAULTS = { limit: 100, window: '1m' } as const
76
79
 
80
+ /** A store is anything with `hit` — `store.ts`'s contract, checked by shape. */
81
+ const STORE: OptionField = {
82
+ expected: 'a store with a hit() method',
83
+ accepts: (v) => typeof v === 'object' && v !== null && typeof (v as { hit?: unknown }).hit === 'function',
84
+ json: { type: 'object' },
85
+ }
86
+
87
+ /** §10.5 step 2 — checked at boot, so `rateLimit({ limt: 100 })` is refused with "did you mean "limit"?". */
88
+ const OPTIONS = optionsSchema('rateLimit', {
89
+ limit: NUMBER, window: DURATION, key: FUNCTION, store: STORE,
90
+ legacyHeaders: BOOLEAN, standardHeaders: BOOLEAN, message: STRING,
91
+ } satisfies Record<keyof RateLimitOptions, OptionField>)
92
+
77
93
  export function rateLimit(options: RateLimitOptions = {}): Plugin<void, {}> {
78
94
  return definePlugin<void, {}>({
79
95
  name: 'rate-limit',
80
96
  version: '0.1.0',
97
+ options: OPTIONS,
98
+ boundOptions: options,
81
99
  config: { namespace: 'rateLimit', defaults: { limit: DEFAULTS.limit, window: DEFAULTS.window } },
82
100
 
83
101
  setup(app) {
package/src/request-id.ts CHANGED
@@ -1,13 +1,17 @@
1
1
  import { definePlugin, Codes, ZenError, type Plugin } from '@erenthedeveloper0/zen-core'
2
- import type { RawReading, Staging } from './shared.ts'
2
+ import {
3
+ BOOLEAN, STRING, either, oneOf, optionsSchema, type OptionField, type RawReading, type Staging,
4
+ } from './shared.ts'
3
5
 
4
6
  /**
5
7
  * Request id — rfcs/0001 §19.4, §31.1.
6
8
  *
7
9
  * Zen already generates one: the dispatcher assigns `ctx.id` before the first
8
- * hook runs, so `ctx.log` and the RFC 9457 problem document already carry a
9
- * correlation key with no plugin at all. This adds the two halves that need a
10
- * decision rather than a default.
10
+ * hook runs, so the RFC 9457 problem document and the framework's own error log
11
+ * lines already carry a correlation key with no plugin at all. (`ctx.log` does
12
+ * not yet: it is the application's logger, not bound to the request — §31.1,
13
+ * §28.8 — so a handler adds `requestId: ctx.id` itself.) This adds the two
14
+ * halves that need a decision rather than a default.
11
15
  *
12
16
  * ### Echoing it
13
17
  *
@@ -80,6 +84,13 @@ export interface RequestIdOptions {
80
84
  */
81
85
  const ACCEPTABLE = /^[A-Za-z0-9._-]{8,128}$/
82
86
 
87
+ /** §10.5 step 2 — checked at boot, so `requestId({ trustHeaders: true })` is refused with "did you mean "trustHeader"?". */
88
+ const OPTIONS = optionsSchema('requestId', {
89
+ header: either(STRING, oneOf(false)),
90
+ trustHeader: either(BOOLEAN, STRING),
91
+ rejectedHeader: either(STRING, oneOf(false)),
92
+ } satisfies Record<keyof RequestIdOptions, OptionField>)
93
+
83
94
  export function requestId(options: RequestIdOptions = {}): Plugin<void, {}> {
84
95
  const echo = options.header === undefined ? 'x-request-id' : options.header
85
96
  const trust =
@@ -105,6 +116,8 @@ export function requestId(options: RequestIdOptions = {}): Plugin<void, {}> {
105
116
  return definePlugin<void, {}>({
106
117
  name: 'request-id',
107
118
  version: '0.1.0',
119
+ options: OPTIONS,
120
+ boundOptions: options,
108
121
  // First in the pack: a preflight answered by `cors` and a 429 refused by
109
122
  // `rate-limit` both short-circuit, and both should still carry the id that
110
123
  // the log line for them will be filed under.
package/src/security.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { definePlugin, type Plugin } from '@erenthedeveloper0/zen-core'
2
2
  import { assertCorsCorpConsistent } from './consistency.ts'
3
3
  import type { CorsExports } from './cors.ts'
4
- import type { Staging } from './shared.ts'
4
+ import {
5
+ BOOLEAN, STRING, STRING_RECORD, either, oneOf, optionsSchema, type OptionField, type Staging,
6
+ } from './shared.ts'
5
7
 
6
8
  /**
7
9
  * Security response headers — rfcs/0001 §19.2.
@@ -90,10 +92,48 @@ export interface SecurityHeadersOptions {
90
92
  /** One resolved header, so the set is data and the hook is a loop over it. */
91
93
  type Pair = readonly [name: string, value: string]
92
94
 
95
+ const HSTS: OptionField = {
96
+ expected: 'false, or { maxAge?: number, includeSubDomains?: boolean, preload?: boolean }',
97
+ accepts: (v) =>
98
+ v === false ||
99
+ (typeof v === 'object' && v !== null && !Array.isArray(v) &&
100
+ Object.entries(v).every(([key, value]) =>
101
+ key === 'maxAge' ? typeof value === 'number'
102
+ : key === 'includeSubDomains' || key === 'preload' ? typeof value === 'boolean'
103
+ : false)),
104
+ json: {
105
+ anyOf: [
106
+ { const: false },
107
+ {
108
+ type: 'object',
109
+ properties: { maxAge: { type: 'number' }, includeSubDomains: { type: 'boolean' }, preload: { type: 'boolean' } },
110
+ additionalProperties: false,
111
+ },
112
+ ],
113
+ },
114
+ }
115
+
116
+ /** §10.5 step 2 — checked at boot, so `securityHeaders({ frameOption: 'DENY' })` is refused by name. */
117
+ const OPTIONS = optionsSchema('securityHeaders', {
118
+ noSniff: BOOLEAN,
119
+ frameOptions: oneOf('DENY', 'SAMEORIGIN', false),
120
+ referrerPolicy: oneOf(
121
+ 'no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'same-origin',
122
+ 'strict-origin', 'strict-origin-when-cross-origin', 'unsafe-url', false,
123
+ ),
124
+ crossOriginOpener: oneOf('same-origin', 'same-origin-allow-popups', 'unsafe-none', false),
125
+ crossOriginResource: oneOf('same-origin', 'same-site', 'cross-origin', false),
126
+ hsts: HSTS,
127
+ contentSecurityPolicy: either(STRING, oneOf(false)),
128
+ headers: STRING_RECORD,
129
+ } satisfies Record<keyof SecurityHeadersOptions, OptionField>)
130
+
93
131
  export function securityHeaders(options: SecurityHeadersOptions = {}): Plugin<void, {}> {
94
132
  return definePlugin<void, {}>({
95
133
  name: 'security-headers',
96
134
  version: '0.1.0',
135
+ options: OPTIONS,
136
+ boundOptions: options,
97
137
  // Before everything that can short-circuit. `cors` answers preflights and
98
138
  // `rate-limit` throws 429s; a hook that runs after either is absent from
99
139
  // exactly the responses §19.2 most wants these headers on. Hints on
package/src/shared.ts CHANGED
@@ -1,4 +1,6 @@
1
- import type { ReplyBuilder, Reply, LowercaseName } from '@erenthedeveloper0/zen-core'
1
+ import type {
2
+ AnySchema, JsonSchema, JsonSchemaNode, LowercaseName, Reply, ReplyBuilder, StandardIssue,
3
+ } from '@erenthedeveloper0/zen-core'
2
4
 
3
5
  /**
4
6
  * What this pack touches on a context, declared structurally — §10.4.
@@ -59,3 +61,103 @@ export function headerOf(ctx: RawReading, name: LowercaseName): string | undefin
59
61
  export function isPreflight(ctx: RawReading): boolean {
60
62
  return ctx.method === 'OPTIONS' && ctx.raw.header('access-control-request-method') !== undefined
61
63
  }
64
+
65
+ // ─────────────────────────────────────────────────────────────────────────────
66
+ // Options schemas — rfcs/0001 §10.5 step 2
67
+ // ─────────────────────────────────────────────────────────────────────────────
68
+
69
+ /** One option a factory accepts, stated twice: as a check, and as JSON Schema. */
70
+ export interface OptionField {
71
+ /** What the option must be, completing "expected …". */
72
+ readonly expected: string
73
+ readonly accepts: (value: unknown) => boolean
74
+ readonly json: JsonSchemaNode
75
+ }
76
+
77
+ /**
78
+ * The options schema of a factory in this pack.
79
+ *
80
+ * §8.6's motivating sentence is "`rateLimit({ limt: 100 })` fails at startup
81
+ * with a spelling suggestion, not at 3 a.m. under load", and the pack is where
82
+ * that sentence is about. A factory hands its options to core as
83
+ * `Plugin.boundOptions`, against this schema as `Plugin.options`, and they are
84
+ * checked at boot before any plugin's `setup` runs.
85
+ *
86
+ * Hand-written Standard Schemas, so the pack keeps its zero dependencies. The
87
+ * work is split with core so nothing is reported twice: `validate` checks the
88
+ * type of each option that is present, and core reads the schema's JSON Schema
89
+ * — a closed object — to name every key it does not declare, with the one it
90
+ * was probably meant to be. A schema that also refused unknown keys would put
91
+ * every typo in the diagnostic twice.
92
+ *
93
+ * It returns the options it was given, unchanged: a factory reads them from
94
+ * its closure, so what it was built with is exactly what boot checked. The
95
+ * checks a value needs beyond its type — a `limit` below one, an origin with a
96
+ * trailing slash — stay in the factory, because configuration supplies the
97
+ * same values and must meet the same rule.
98
+ */
99
+ export function optionsSchema(factory: string, fields: Readonly<Record<string, OptionField>>): AnySchema {
100
+ const properties: Record<string, JsonSchemaNode> = {}
101
+ for (const key of Object.keys(fields)) properties[key] = (fields[key] as OptionField).json
102
+ const shape: JsonSchema = { type: 'object', properties, additionalProperties: false }
103
+
104
+ return {
105
+ '~standard': {
106
+ version: 1,
107
+ vendor: 'zen-middleware',
108
+ validate(value: unknown) {
109
+ if (value === undefined) return { value: {} }
110
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
111
+ return { issues: [{ message: `${factory}() takes an options object` }] }
112
+ }
113
+ const given = value as Readonly<Record<string, unknown>>
114
+ const issues: StandardIssue[] = []
115
+ for (const key of Object.keys(fields)) {
116
+ const option = given[key]
117
+ const field = fields[key] as OptionField
118
+ if (option !== undefined && !field.accepts(option)) issues.push({ message: `expected ${field.expected}`, path: [key] })
119
+ }
120
+ return issues.length === 0 ? { value } : { issues }
121
+ },
122
+ },
123
+ toJsonSchema: () => shape,
124
+ } as AnySchema
125
+ }
126
+
127
+ const field = (expected: string, accepts: (value: unknown) => boolean, json: JsonSchemaNode = {}): OptionField =>
128
+ ({ expected, accepts, json })
129
+
130
+ export const BOOLEAN = field('true or false', (v) => typeof v === 'boolean', { type: 'boolean' })
131
+ export const STRING = field('a string', (v) => typeof v === 'string', { type: 'string' })
132
+ export const NUMBER = field('a number', (v) => typeof v === 'number', { type: 'number' })
133
+ export const FUNCTION = field('a function', (v) => typeof v === 'function')
134
+ export const REGEXP = field('a RegExp', (v) => v instanceof RegExp)
135
+ export const DURATION = field(
136
+ "a duration — milliseconds, or a string such as '10m'",
137
+ (v) => typeof v === 'number' || typeof v === 'string',
138
+ { type: ['number', 'string'] },
139
+ )
140
+ export const STRINGS = field(
141
+ 'a list of strings',
142
+ (v) => Array.isArray(v) && v.every((item) => typeof item === 'string'),
143
+ { type: 'array', items: { type: 'string' } },
144
+ )
145
+ export const STRING_RECORD = field(
146
+ 'an object of string values',
147
+ (v) => typeof v === 'object' && v !== null && !Array.isArray(v) && Object.values(v).every((item) => typeof item === 'string'),
148
+ { type: 'object', additionalProperties: { type: 'string' } },
149
+ )
150
+
151
+ /** Exactly one of these values. */
152
+ export function oneOf(...values: readonly (string | number | boolean)[]): OptionField {
153
+ return field(values.map((value) => JSON.stringify(value)).join(', '), (v) => values.includes(v as never), { enum: [...values] })
154
+ }
155
+
156
+ /** Any one of these fields. */
157
+ export function either(...fields: readonly OptionField[]): OptionField {
158
+ return field(
159
+ fields.map((f) => f.expected).join(', or '),
160
+ (v) => fields.some((f) => f.accepts(v)),
161
+ { anyOf: fields.map((f) => f.json) },
162
+ )
163
+ }