@hoox-sh/hoox-shared 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +6 -0
  2. package/dist/agent-config-fields.d.ts +5 -0
  3. package/dist/agent-config-fields.d.ts.map +1 -1
  4. package/dist/agent-config-fields.js +21 -29
  5. package/dist/analytics.d.ts +3 -4
  6. package/dist/analytics.d.ts.map +1 -1
  7. package/dist/analytics.js +64 -19
  8. package/dist/api-client.js +12 -21
  9. package/dist/colors.js +5 -21
  10. package/dist/config.d.ts +10 -2
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +267 -51
  13. package/dist/cron-handler.js +0 -16
  14. package/dist/d1/index.js +8 -25
  15. package/dist/d1/repository.js +3 -19
  16. package/dist/d1/schemas.js +4 -20
  17. package/dist/dashboard-manifest.d.ts +2 -1
  18. package/dist/dashboard-manifest.d.ts.map +1 -1
  19. package/dist/dashboard-manifest.js +37 -33
  20. package/dist/entitlements.d.ts +46 -0
  21. package/dist/entitlements.d.ts.map +1 -0
  22. package/dist/entitlements.js +15 -0
  23. package/dist/errors.d.ts +1 -0
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +7 -23
  26. package/dist/exchange-client.d.ts +0 -19
  27. package/dist/exchange-client.d.ts.map +1 -1
  28. package/dist/exchange-client.js +1 -83
  29. package/dist/exchanges/base-exchange-client.d.ts.map +1 -1
  30. package/dist/exchanges/base-exchange-client.js +4 -19
  31. package/dist/exchanges/index.js +4 -19
  32. package/dist/format-time.js +2 -18
  33. package/dist/formatters.js +12 -28
  34. package/dist/health.js +3 -19
  35. package/dist/index.d.ts +7 -4
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +3568 -3766
  38. package/dist/kill-switch.js +12 -20
  39. package/dist/kvKeys.d.ts +8 -0
  40. package/dist/kvKeys.d.ts.map +1 -1
  41. package/dist/kvKeys.js +42 -46
  42. package/dist/kvUtils.js +8 -24
  43. package/dist/legal.js +5 -21
  44. package/dist/middleware/auth.d.ts +9 -0
  45. package/dist/middleware/auth.d.ts.map +1 -1
  46. package/dist/middleware/auth.js +9 -25
  47. package/dist/middleware/cors.js +4 -20
  48. package/dist/middleware/index.js +144 -165
  49. package/dist/middleware/logger.d.ts +2 -0
  50. package/dist/middleware/logger.d.ts.map +1 -1
  51. package/dist/middleware/logger.js +9 -25
  52. package/dist/middleware/rate-limit.d.ts +7 -0
  53. package/dist/middleware/rate-limit.d.ts.map +1 -1
  54. package/dist/middleware/rate-limit.js +5 -20
  55. package/dist/middleware/security-headers.js +2 -18
  56. package/dist/middleware/validate.d.ts +2 -0
  57. package/dist/middleware/validate.d.ts.map +1 -1
  58. package/dist/middleware/validate.js +5 -21
  59. package/dist/middleware/wait-until.js +2 -18
  60. package/dist/operator-transport.js +13 -17
  61. package/dist/path-utils.d.ts.map +1 -1
  62. package/dist/path-utils.js +28 -34
  63. package/dist/queue-handler.d.ts.map +1 -1
  64. package/dist/queue-handler.js +19 -24
  65. package/dist/router.d.ts +5 -0
  66. package/dist/router.d.ts.map +1 -1
  67. package/dist/router.js +0 -16
  68. package/dist/schemas/index.js +75 -50
  69. package/dist/schemas/registry.d.ts.map +1 -1
  70. package/dist/schemas/registry.js +33 -21
  71. package/dist/schemas/validators.d.ts.map +1 -1
  72. package/dist/schemas/validators.js +41 -43
  73. package/dist/service-bindings.d.ts +4 -0
  74. package/dist/service-bindings.d.ts.map +1 -1
  75. package/dist/service-bindings.js +13 -29
  76. package/dist/session.d.ts +10 -3
  77. package/dist/session.d.ts.map +1 -1
  78. package/dist/session.js +111 -51
  79. package/dist/sse.d.ts.map +1 -1
  80. package/dist/sse.js +34 -24
  81. package/dist/stores/config-store.d.ts +2 -50
  82. package/dist/stores/config-store.d.ts.map +1 -1
  83. package/dist/stores/config-store.js +153 -156
  84. package/dist/stores/service-store.d.ts +2 -192
  85. package/dist/stores/service-store.d.ts.map +1 -1
  86. package/dist/stores/service-store.js +40 -35
  87. package/dist/stores/ui-store.d.ts +2 -48
  88. package/dist/stores/ui-store.d.ts.map +1 -1
  89. package/dist/stores/ui-store.js +0 -16
  90. package/dist/tenant.d.ts +62 -0
  91. package/dist/tenant.d.ts.map +1 -0
  92. package/dist/tenant.js +56 -0
  93. package/dist/test-utils.js +11 -27
  94. package/dist/types.d.ts +10 -3
  95. package/dist/types.d.ts.map +1 -1
  96. package/dist/types.js +29 -24
  97. package/dist/wizard/engine.d.ts.map +1 -1
  98. package/dist/wizard/engine.js +33 -27
  99. package/dist/wizard/index.d.ts +1 -0
  100. package/dist/wizard/index.d.ts.map +1 -1
  101. package/dist/wizard/index.js +48 -39
  102. package/dist/wizard/persistence.d.ts +4 -0
  103. package/dist/wizard/persistence.d.ts.map +1 -1
  104. package/dist/wizard/persistence.js +7 -19
  105. package/dist/wizard/presets.d.ts.map +1 -1
  106. package/dist/wizard/presets.js +13 -25
  107. package/dist/wizard/types.d.ts +6 -0
  108. package/dist/wizard/types.d.ts.map +1 -1
  109. package/dist/wizard/types.js +5 -0
  110. package/package.json +7 -2
@@ -1,20 +1,4 @@
1
1
  // @bun
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
16
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
-
18
2
  // src/errors.ts
19
3
  function toError(err, fallback = "Unknown error") {
20
4
  if (err instanceof Error)
@@ -72,14 +56,14 @@ function sanitizeOutput(data) {
72
56
  const obj = data;
73
57
  const keys = Object.keys(obj);
74
58
  if (keys.length < 10) {
75
- const sanitized2 = {};
59
+ const sanitized = {};
76
60
  for (const k of keys) {
77
61
  if (k === "stack" || k === "cause")
78
62
  continue;
79
63
  const v = obj[k];
80
- sanitized2[k] = v instanceof Error ? { name: v.name, message: v.message } : sanitizeOutput(v);
64
+ sanitized[k] = v instanceof Error ? { name: v.name, message: v.message } : sanitizeOutput(v);
81
65
  }
82
- return sanitized2;
66
+ return sanitized;
83
67
  }
84
68
  if (!hasSensitiveFields(obj) && !hasErrorValues(obj)) {
85
69
  return obj;
@@ -143,6 +127,61 @@ var Errors = {
143
127
  }
144
128
  };
145
129
 
130
+ // src/middleware/logger.ts
131
+ function createLogger(ctx) {
132
+ const base = { service: ctx.service, module: ctx.module };
133
+ function emit(level, message, context) {
134
+ const entry = {
135
+ level,
136
+ timestamp: new Date().toISOString(),
137
+ ...base,
138
+ message,
139
+ ...context && { context }
140
+ };
141
+ const line = JSON.stringify(entry);
142
+ if (level === "error")
143
+ console.error(line);
144
+ else if (level === "warn")
145
+ console.warn(line);
146
+ else if (level === "debug")
147
+ console.debug(line);
148
+ else
149
+ console.info(line);
150
+ }
151
+ return {
152
+ debug: (msg, ctx) => emit("debug", msg, ctx),
153
+ info: (msg, ctx) => emit("info", msg, ctx),
154
+ warn: (msg, ctx) => emit("warn", msg, ctx),
155
+ error: (msg, ctx) => emit("error", msg, ctx)
156
+ };
157
+ }
158
+ function withRequestLog(handler, logCtx) {
159
+ return async (request, env, ctx) => {
160
+ const start = Date.now();
161
+ const logger = createLogger(logCtx);
162
+ try {
163
+ const response = await handler(request, env, ctx);
164
+ const duration = Date.now() - start;
165
+ const url = new URL(request.url);
166
+ logger.info(`${request.method} ${url.pathname}`, {
167
+ method: request.method,
168
+ path: url.pathname,
169
+ status: response.status,
170
+ durationMs: duration
171
+ });
172
+ return response;
173
+ } catch (error) {
174
+ const duration = Date.now() - start;
175
+ logger.error("Request failed", {
176
+ method: request.method,
177
+ path: new URL(request.url).pathname,
178
+ durationMs: duration,
179
+ error: toError(error)
180
+ });
181
+ throw error;
182
+ }
183
+ };
184
+ }
146
185
  // src/middleware/auth.ts
147
186
  function timingSafeEqual(a, b) {
148
187
  const encoder = new TextEncoder;
@@ -279,117 +318,6 @@ function checkInternalAuth(request, env, keyName = "INTERNAL_KEY_BINDING") {
279
318
  }
280
319
  return { authorized: true };
281
320
  }
282
-
283
- // src/middleware/cors.ts
284
- var DEFAULT_OPTIONS = {
285
- allowOrigin: "",
286
- allowMethods: "GET, POST, OPTIONS, PUT, DELETE",
287
- allowHeaders: "Content-Type, Authorization, X-Request-ID",
288
- allowCredentials: false,
289
- maxAge: 86400
290
- };
291
- function corsHeaders(options) {
292
- const opts = { ...DEFAULT_OPTIONS, ...options };
293
- const headers = {
294
- "Access-Control-Allow-Methods": opts.allowMethods,
295
- "Access-Control-Allow-Headers": opts.allowHeaders,
296
- "Access-Control-Max-Age": String(opts.maxAge)
297
- };
298
- if (opts.allowOrigin) {
299
- headers["Access-Control-Allow-Origin"] = opts.allowOrigin;
300
- }
301
- if (opts.allowCredentials) {
302
- headers["Access-Control-Allow-Credentials"] = "true";
303
- }
304
- return headers;
305
- }
306
- function publicCorsHeaders(origin = "*", options) {
307
- return corsHeaders({ ...options, allowOrigin: origin });
308
- }
309
- function internalCorsHeaders() {
310
- return {};
311
- }
312
- function resolveCorsOptions(request, env) {
313
- const raw = env && typeof env === "object" && "CORS_ALLOW_ORIGIN" in env && typeof env.CORS_ALLOW_ORIGIN === "string" ? env.CORS_ALLOW_ORIGIN : undefined;
314
- const configured = raw?.trim();
315
- if (!configured) {
316
- return {};
317
- }
318
- const allowed = configured.split(",").map((entry) => entry.trim()).filter(Boolean);
319
- const origin = request.headers.get("Origin");
320
- if (origin && allowed.includes(origin)) {
321
- return { allowOrigin: origin, allowCredentials: true };
322
- }
323
- if (!origin && allowed.length === 1) {
324
- return { allowOrigin: allowed[0] };
325
- }
326
- return {};
327
- }
328
- function handleCorsPreflightRequest(request, options) {
329
- if (request.method !== "OPTIONS")
330
- return null;
331
- return new Response(null, {
332
- status: 204,
333
- headers: corsHeaders(options)
334
- });
335
- }
336
-
337
- // src/middleware/logger.ts
338
- function createLogger(ctx) {
339
- const base = { service: ctx.service, module: ctx.module };
340
- function emit(level, message, context) {
341
- const entry = {
342
- level,
343
- timestamp: new Date().toISOString(),
344
- ...base,
345
- message,
346
- ...context && { context }
347
- };
348
- const line = JSON.stringify(entry);
349
- if (level === "error")
350
- console.error(line);
351
- else if (level === "warn")
352
- console.warn(line);
353
- else if (level === "debug")
354
- console.debug(line);
355
- else
356
- console.info(line);
357
- }
358
- return {
359
- debug: (msg, ctx2) => emit("debug", msg, ctx2),
360
- info: (msg, ctx2) => emit("info", msg, ctx2),
361
- warn: (msg, ctx2) => emit("warn", msg, ctx2),
362
- error: (msg, ctx2) => emit("error", msg, ctx2)
363
- };
364
- }
365
- function withRequestLog(handler, logCtx) {
366
- return async (request, env, ctx) => {
367
- const start = Date.now();
368
- const logger = createLogger(logCtx);
369
- try {
370
- const response = await handler(request, env, ctx);
371
- const duration = Date.now() - start;
372
- const url = new URL(request.url);
373
- logger.info(`${request.method} ${url.pathname}`, {
374
- method: request.method,
375
- path: url.pathname,
376
- status: response.status,
377
- durationMs: duration
378
- });
379
- return response;
380
- } catch (error) {
381
- const duration = Date.now() - start;
382
- logger.error("Request failed", {
383
- method: request.method,
384
- path: new URL(request.url).pathname,
385
- durationMs: duration,
386
- error: toError(error)
387
- });
388
- throw error;
389
- }
390
- };
391
- }
392
-
393
321
  // src/middleware/rate-limit.ts
394
322
  function createStorage(kv) {
395
323
  if (!kv) {
@@ -444,8 +372,8 @@ function createStorage(kv) {
444
372
  attempts++;
445
373
  if (attempts >= maxAttempts) {
446
374
  const current = await this.get(key);
447
- const count2 = current ? parseInt(current, 10) : 0;
448
- newValue = count2 + 1;
375
+ const count = current ? parseInt(current, 10) : 0;
376
+ newValue = count + 1;
449
377
  const ttl = opts?.expirationTtl ?? 0;
450
378
  const expiresAt = ttl > 0 ? Date.now() + ttl * 1000 : Infinity;
451
379
  memory.set(key, { value: String(newValue), expiresAt });
@@ -493,7 +421,7 @@ function createRateLimiter(kv, config) {
493
421
  };
494
422
  }
495
423
  const newCount = await storage.incr(fullKey, {
496
- expirationTtl: config.windowSeconds
424
+ expirationTtl: Math.max(60, config.windowSeconds)
497
425
  });
498
426
  if (newCount > config.maxRequests) {
499
427
  const retryAfter = Math.ceil(config.windowSeconds - Date.now() % (config.windowSeconds * 1000) / 1000);
@@ -530,7 +458,8 @@ function createRateLimiter(kv, config) {
530
458
  return null;
531
459
  }
532
460
  async function checkKey(key) {
533
- const fullKey = `${prefix}:${key}`;
461
+ const windowStart = Math.floor(Date.now() / (config.windowSeconds * 1000));
462
+ const fullKey = `${prefix}:${key}:${windowStart}`;
534
463
  return checkWithKey(fullKey);
535
464
  }
536
465
  async function enforceKey(key) {
@@ -551,7 +480,6 @@ function createRateLimiter(kv, config) {
551
480
  }
552
481
  return { check, enforce, checkKey, enforceKey };
553
482
  }
554
-
555
483
  // src/middleware/validate.ts
556
484
  var DEFAULT_MAX_JSON_BODY_BYTES = 1048576;
557
485
  function validateJson(schema, data) {
@@ -619,7 +547,6 @@ function optionalField(body, field, defaultValue) {
619
547
  return defaultValue;
620
548
  return body[field];
621
549
  }
622
-
623
550
  // src/middleware/wait-until.ts
624
551
  function safeWaitUntil(ctx, promise, onError) {
625
552
  ctx.waitUntil(promise.catch((err) => {
@@ -645,7 +572,59 @@ function waitUntilAll(ctx, promises, onError) {
645
572
  }
646
573
  }), onError);
647
574
  }
648
-
575
+ // src/middleware/cors.ts
576
+ var DEFAULT_OPTIONS = {
577
+ allowOrigin: "",
578
+ allowMethods: "GET, POST, OPTIONS, PUT, DELETE",
579
+ allowHeaders: "Content-Type, Authorization, X-Request-ID",
580
+ allowCredentials: false,
581
+ maxAge: 86400
582
+ };
583
+ function corsHeaders(options) {
584
+ const opts = { ...DEFAULT_OPTIONS, ...options };
585
+ const headers = {
586
+ "Access-Control-Allow-Methods": opts.allowMethods,
587
+ "Access-Control-Allow-Headers": opts.allowHeaders,
588
+ "Access-Control-Max-Age": String(opts.maxAge)
589
+ };
590
+ if (opts.allowOrigin) {
591
+ headers["Access-Control-Allow-Origin"] = opts.allowOrigin;
592
+ }
593
+ if (opts.allowCredentials) {
594
+ headers["Access-Control-Allow-Credentials"] = "true";
595
+ }
596
+ return headers;
597
+ }
598
+ function publicCorsHeaders(origin = "*", options) {
599
+ return corsHeaders({ ...options, allowOrigin: origin });
600
+ }
601
+ function internalCorsHeaders() {
602
+ return {};
603
+ }
604
+ function resolveCorsOptions(request, env) {
605
+ const raw = env && typeof env === "object" && "CORS_ALLOW_ORIGIN" in env && typeof env.CORS_ALLOW_ORIGIN === "string" ? env.CORS_ALLOW_ORIGIN : undefined;
606
+ const configured = raw?.trim();
607
+ if (!configured) {
608
+ return {};
609
+ }
610
+ const allowed = configured.split(",").map((entry) => entry.trim()).filter(Boolean);
611
+ const origin = request.headers.get("Origin");
612
+ if (origin && allowed.includes(origin)) {
613
+ return { allowOrigin: origin, allowCredentials: true };
614
+ }
615
+ if (!origin && allowed.length === 1) {
616
+ return { allowOrigin: allowed[0] };
617
+ }
618
+ return {};
619
+ }
620
+ function handleCorsPreflightRequest(request, options) {
621
+ if (request.method !== "OPTIONS")
622
+ return null;
623
+ return new Response(null, {
624
+ status: 204,
625
+ headers: corsHeaders(options)
626
+ });
627
+ }
649
628
  // src/middleware/security-headers.ts
650
629
  var SECURITY_HEADERS_DEFAULTS = {
651
630
  xContentTypeOptions: "nosniff",
@@ -683,33 +662,33 @@ function wrapWithSecurityHeaders(response, options) {
683
662
  });
684
663
  }
685
664
  export {
686
- wrapWithSecurityHeaders,
687
- withRequestLog,
688
- waitUntilAll,
689
- validateJsonLegacy,
690
- validateJson,
691
- timingSafeEqualAsync,
692
- timingSafeEqual,
693
- secureHeaders,
694
- safeWaitUntil,
695
- resolveOperatorApiKey,
696
- resolveCorsOptions,
697
- requireOperatorAuth,
698
- requireInternalAuth,
699
- requireField,
700
- requireAuth,
701
- publicCorsHeaders,
702
- parseJsonBody,
703
- optionalField,
704
- internalCorsHeaders,
705
- handleCorsPreflightRequest,
706
- createRateLimiter,
707
- createOperatorAuthMiddleware,
708
- createLogger,
709
- createInternalAuthMiddleware,
710
- corsHeaders,
711
- collectInternalAuthKeys,
712
- checkInternalAuth,
665
+ DEFAULT_MAX_JSON_BODY_BYTES,
713
666
  SECURITY_HEADERS_DEFAULTS,
714
- DEFAULT_MAX_JSON_BODY_BYTES
667
+ checkInternalAuth,
668
+ collectInternalAuthKeys,
669
+ corsHeaders,
670
+ createInternalAuthMiddleware,
671
+ createLogger,
672
+ createOperatorAuthMiddleware,
673
+ createRateLimiter,
674
+ handleCorsPreflightRequest,
675
+ internalCorsHeaders,
676
+ optionalField,
677
+ parseJsonBody,
678
+ publicCorsHeaders,
679
+ requireAuth,
680
+ requireField,
681
+ requireInternalAuth,
682
+ requireOperatorAuth,
683
+ resolveCorsOptions,
684
+ resolveOperatorApiKey,
685
+ safeWaitUntil,
686
+ secureHeaders,
687
+ timingSafeEqual,
688
+ timingSafeEqualAsync,
689
+ validateJson,
690
+ validateJsonLegacy,
691
+ waitUntilAll,
692
+ withRequestLog,
693
+ wrapWithSecurityHeaders
715
694
  };
@@ -12,6 +12,8 @@ export interface Logger {
12
12
  warn(message: string, context?: Record<string, unknown>): void;
13
13
  error(message: string, context?: Record<string, unknown>): void;
14
14
  }
15
+ /** JSON-line logger bound to a service/module context. */
15
16
  export declare function createLogger(ctx: LogContext): Logger;
17
+ /** Wrap a fetch handler so each request logs method, path, status, and duration. */
16
18
  export declare function withRequestLog<E>(handler: (request: Request, env: E, ctx: ExecutionContext) => Promise<Response>, logCtx: LogContext): (request: Request, env: E, ctx: ExecutionContext) => Promise<Response>;
17
19
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/middleware/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACjE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CA4BpD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,CACP,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,CAAC,EACN,GAAG,EAAE,gBAAgB,KAClB,OAAO,CAAC,QAAQ,CAAC,EACtB,MAAM,EAAE,UAAU,GACjB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,CAAC,CA2BxE"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/middleware/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACjE;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CA4BpD;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,CACP,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,CAAC,EACN,GAAG,EAAE,gBAAgB,KAClB,OAAO,CAAC,QAAQ,CAAC,EACtB,MAAM,EAAE,UAAU,GACjB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,CAAC,CA2BxE"}
@@ -1,20 +1,4 @@
1
1
  // @bun
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
16
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
-
18
2
  // src/errors.ts
19
3
  function toError(err, fallback = "Unknown error") {
20
4
  if (err instanceof Error)
@@ -72,14 +56,14 @@ function sanitizeOutput(data) {
72
56
  const obj = data;
73
57
  const keys = Object.keys(obj);
74
58
  if (keys.length < 10) {
75
- const sanitized2 = {};
59
+ const sanitized = {};
76
60
  for (const k of keys) {
77
61
  if (k === "stack" || k === "cause")
78
62
  continue;
79
63
  const v = obj[k];
80
- sanitized2[k] = v instanceof Error ? { name: v.name, message: v.message } : sanitizeOutput(v);
64
+ sanitized[k] = v instanceof Error ? { name: v.name, message: v.message } : sanitizeOutput(v);
81
65
  }
82
- return sanitized2;
66
+ return sanitized;
83
67
  }
84
68
  if (!hasSensitiveFields(obj) && !hasErrorValues(obj)) {
85
69
  return obj;
@@ -165,10 +149,10 @@ function createLogger(ctx) {
165
149
  console.info(line);
166
150
  }
167
151
  return {
168
- debug: (msg, ctx2) => emit("debug", msg, ctx2),
169
- info: (msg, ctx2) => emit("info", msg, ctx2),
170
- warn: (msg, ctx2) => emit("warn", msg, ctx2),
171
- error: (msg, ctx2) => emit("error", msg, ctx2)
152
+ debug: (msg, ctx) => emit("debug", msg, ctx),
153
+ info: (msg, ctx) => emit("info", msg, ctx),
154
+ warn: (msg, ctx) => emit("warn", msg, ctx),
155
+ error: (msg, ctx) => emit("error", msg, ctx)
172
156
  };
173
157
  }
174
158
  function withRequestLog(handler, logCtx) {
@@ -199,6 +183,6 @@ function withRequestLog(handler, logCtx) {
199
183
  };
200
184
  }
201
185
  export {
202
- withRequestLog,
203
- createLogger
186
+ createLogger,
187
+ withRequestLog
204
188
  };
@@ -25,6 +25,13 @@ export interface RateLimiter {
25
25
  checkKey(key: string): Promise<RateLimitResult>;
26
26
  enforceKey(key: string): Promise<Response | null>;
27
27
  }
28
+ /**
29
+ * Create a KV- or memory-backed rate limiter.
30
+ *
31
+ * `check` / `enforce` key by client IP and a clock window.
32
+ * `checkKey` / `enforceKey` key by the caller string plus the same window
33
+ * (so a busy key does not accumulate forever).
34
+ */
28
35
  export declare function createRateLimiter(kv: Env["CONFIG_KV"] | undefined, config: RateLimitConfig): RateLimiter;
29
36
  export {};
30
37
  //# sourceMappingURL=rate-limit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAClD,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACpD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAChD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;CACnD;AAuHD,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,GAAG,CAAC,WAAW,CAAC,GAAG,SAAS,EAChC,MAAM,EAAE,eAAe,GACtB,WAAW,CAiHb"}
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAClD,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACpD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAChD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;CACnD;AAuHD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,GAAG,CAAC,WAAW,CAAC,GAAG,SAAS,EAChC,MAAM,EAAE,eAAe,GACtB,WAAW,CAoHb"}
@@ -1,20 +1,4 @@
1
1
  // @bun
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
16
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
-
18
2
  // src/middleware/rate-limit.ts
19
3
  function createStorage(kv) {
20
4
  if (!kv) {
@@ -69,8 +53,8 @@ function createStorage(kv) {
69
53
  attempts++;
70
54
  if (attempts >= maxAttempts) {
71
55
  const current = await this.get(key);
72
- const count2 = current ? parseInt(current, 10) : 0;
73
- newValue = count2 + 1;
56
+ const count = current ? parseInt(current, 10) : 0;
57
+ newValue = count + 1;
74
58
  const ttl = opts?.expirationTtl ?? 0;
75
59
  const expiresAt = ttl > 0 ? Date.now() + ttl * 1000 : Infinity;
76
60
  memory.set(key, { value: String(newValue), expiresAt });
@@ -118,7 +102,7 @@ function createRateLimiter(kv, config) {
118
102
  };
119
103
  }
120
104
  const newCount = await storage.incr(fullKey, {
121
- expirationTtl: config.windowSeconds
105
+ expirationTtl: Math.max(60, config.windowSeconds)
122
106
  });
123
107
  if (newCount > config.maxRequests) {
124
108
  const retryAfter = Math.ceil(config.windowSeconds - Date.now() % (config.windowSeconds * 1000) / 1000);
@@ -155,7 +139,8 @@ function createRateLimiter(kv, config) {
155
139
  return null;
156
140
  }
157
141
  async function checkKey(key) {
158
- const fullKey = `${prefix}:${key}`;
142
+ const windowStart = Math.floor(Date.now() / (config.windowSeconds * 1000));
143
+ const fullKey = `${prefix}:${key}:${windowStart}`;
159
144
  return checkWithKey(fullKey);
160
145
  }
161
146
  async function enforceKey(key) {
@@ -1,20 +1,4 @@
1
1
  // @bun
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
16
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
-
18
2
  // src/middleware/security-headers.ts
19
3
  var SECURITY_HEADERS_DEFAULTS = {
20
4
  xContentTypeOptions: "nosniff",
@@ -52,7 +36,7 @@ function wrapWithSecurityHeaders(response, options) {
52
36
  });
53
37
  }
54
38
  export {
55
- wrapWithSecurityHeaders,
39
+ SECURITY_HEADERS_DEFAULTS,
56
40
  secureHeaders,
57
- SECURITY_HEADERS_DEFAULTS
41
+ wrapWithSecurityHeaders
58
42
  };
@@ -36,6 +36,8 @@ export declare function parseJsonBody<T extends z.ZodTypeAny>(request: Request,
36
36
  * Kept for backward compatibility with existing workers.
37
37
  */
38
38
  export declare function validateJsonLegacy(request: Request): Promise<Result<Record<string, unknown>>>;
39
+ /** Require `field` on a parsed JSON body; fail with a missing-field error. */
39
40
  export declare function requireField<T>(body: Record<string, unknown>, field: string): Result<T>;
41
+ /** Read `field` from a parsed JSON body, or `defaultValue` when absent. */
40
42
  export declare function optionalField<T>(body: Record<string, unknown>, field: string, defaultValue: T): T;
41
43
  //# sourceMappingURL=validate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/middleware/validate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,8DAA8D;AAC9D,eAAO,MAAM,2BAA2B,UAAY,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EACjD,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,OAAO,GACZ,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAWpB;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EACxD,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,CAAC,EACT,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAsC7B;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAU1C;AAED,wBAAgB,YAAY,CAAC,CAAC,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,EAAE,MAAM,GACZ,MAAM,CAAC,CAAC,CAAC,CAKX;AAED,wBAAgB,aAAa,CAAC,CAAC,EAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,CAAC,GACd,CAAC,CAGH"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/middleware/validate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,8DAA8D;AAC9D,eAAO,MAAM,2BAA2B,UAAY,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EACjD,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,OAAO,GACZ,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAWpB;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EACxD,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,CAAC,EACT,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAsC7B;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAU1C;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,CAAC,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,EAAE,MAAM,GACZ,MAAM,CAAC,CAAC,CAAC,CAKX;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,CAAC,EAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,CAAC,GACd,CAAC,CAGH"}
@@ -1,20 +1,4 @@
1
1
  // @bun
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
16
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
-
18
2
  // src/middleware/validate.ts
19
3
  var DEFAULT_MAX_JSON_BODY_BYTES = 1048576;
20
4
  function validateJson(schema, data) {
@@ -83,10 +67,10 @@ function optionalField(body, field, defaultValue) {
83
67
  return body[field];
84
68
  }
85
69
  export {
86
- validateJsonLegacy,
87
- validateJson,
88
- requireField,
89
- parseJsonBody,
70
+ DEFAULT_MAX_JSON_BODY_BYTES,
90
71
  optionalField,
91
- DEFAULT_MAX_JSON_BODY_BYTES
72
+ parseJsonBody,
73
+ requireField,
74
+ validateJson,
75
+ validateJsonLegacy
92
76
  };
@@ -1,20 +1,4 @@
1
1
  // @bun
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
16
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
-
18
2
  // src/middleware/wait-until.ts
19
3
  function safeWaitUntil(ctx, promise, onError) {
20
4
  ctx.waitUntil(promise.catch((err) => {
@@ -41,6 +25,6 @@ function waitUntilAll(ctx, promises, onError) {
41
25
  }), onError);
42
26
  }
43
27
  export {
44
- waitUntilAll,
45
- safeWaitUntil
28
+ safeWaitUntil,
29
+ waitUntilAll
46
30
  };