@jango-blockchained/hoox-shared 1.0.9 → 1.1.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 (74) hide show
  1. package/README.md +17 -0
  2. package/dist/analytics.d.ts +23 -1
  3. package/dist/analytics.d.ts.map +1 -1
  4. package/dist/analytics.js +14 -3
  5. package/dist/api-client.d.ts +12 -2
  6. package/dist/api-client.d.ts.map +1 -1
  7. package/dist/api-client.js +74 -7
  8. package/dist/colors.d.ts +63 -24
  9. package/dist/colors.d.ts.map +1 -1
  10. package/dist/colors.js +60 -19
  11. package/dist/config.d.ts +34 -1
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/config.js +61 -6
  14. package/dist/cron-handler.d.ts +2 -2
  15. package/dist/cron-handler.d.ts.map +1 -1
  16. package/dist/d1/index.js +1 -0
  17. package/dist/d1/repository.js +297 -0
  18. package/dist/d1/schemas.js +81 -0
  19. package/dist/exchanges/base-exchange-client.js +120 -0
  20. package/dist/exchanges/types.js +1 -0
  21. package/dist/index.d.ts +21 -11
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +580 -60
  24. package/dist/middleware/auth.d.ts +42 -6
  25. package/dist/middleware/auth.d.ts.map +1 -1
  26. package/dist/middleware/auth.js +151 -0
  27. package/dist/middleware/cors.d.ts +28 -2
  28. package/dist/middleware/cors.d.ts.map +1 -1
  29. package/dist/middleware/cors.js +77 -0
  30. package/dist/middleware/index.d.ts +2 -2
  31. package/dist/middleware/index.d.ts.map +1 -1
  32. package/dist/middleware/index.js +192 -107
  33. package/dist/middleware/logger.js +202 -0
  34. package/dist/middleware/rate-limit.d.ts.map +1 -1
  35. package/dist/middleware/rate-limit.js +181 -0
  36. package/dist/middleware/security-headers.js +58 -0
  37. package/dist/middleware/validate.js +56 -0
  38. package/dist/operator-transport.d.ts +61 -0
  39. package/dist/operator-transport.d.ts.map +1 -0
  40. package/dist/operator-transport.js +87 -0
  41. package/dist/path-utils.d.ts +59 -1
  42. package/dist/path-utils.d.ts.map +1 -1
  43. package/dist/path-utils.js +89 -2
  44. package/dist/queue-handler.d.ts +3 -3
  45. package/dist/queue-handler.d.ts.map +1 -1
  46. package/dist/router.d.ts +2 -2
  47. package/dist/router.d.ts.map +1 -1
  48. package/dist/schemas/index.js +7 -4
  49. package/dist/schemas/registry.js +387 -0
  50. package/dist/schemas/types.js +1 -0
  51. package/dist/schemas/validators.d.ts.map +1 -1
  52. package/dist/schemas/validators.js +290 -0
  53. package/dist/service-bindings.d.ts +65 -0
  54. package/dist/service-bindings.d.ts.map +1 -1
  55. package/dist/service-bindings.js +216 -1
  56. package/dist/session.d.ts.map +1 -1
  57. package/dist/session.js +97 -2
  58. package/dist/sse.d.ts +12 -3
  59. package/dist/sse.d.ts.map +1 -1
  60. package/dist/sse.js +70 -7
  61. package/dist/stores/config-store.d.ts.map +1 -1
  62. package/dist/stores/config-store.js +129 -6
  63. package/dist/stores/service-store.d.ts.map +1 -1
  64. package/dist/stores/service-store.js +96 -25
  65. package/dist/types.d.ts +66 -1
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/types.js +11 -0
  68. package/dist/wizard/engine.js +501 -0
  69. package/dist/wizard/index.js +2 -1
  70. package/dist/wizard/persistence.js +31 -0
  71. package/dist/wizard/presets.js +199 -0
  72. package/dist/wizard/provisioner.js +1 -0
  73. package/dist/wizard/types.js +1 -0
  74. package/package.json +38 -12
@@ -141,6 +141,184 @@ var Errors = {
141
141
  }
142
142
  };
143
143
 
144
+ // src/middleware/auth.ts
145
+ function timingSafeEqual(a, b) {
146
+ const encoder = new TextEncoder;
147
+ const aBuf = encoder.encode(a);
148
+ const bBuf = encoder.encode(b);
149
+ const len = Math.max(aBuf.length, bBuf.length);
150
+ let result = aBuf.length === bBuf.length ? 0 : 1;
151
+ for (let i = 0;i < len; i++) {
152
+ const av = i < aBuf.length ? aBuf[i] : 0;
153
+ const bv = i < bBuf.length ? bBuf[i] : 0;
154
+ result |= av ^ bv;
155
+ }
156
+ return result === 0;
157
+ }
158
+ function resolveOperatorApiKey(env) {
159
+ const preferred = env.OPERATOR_API_KEY;
160
+ if (typeof preferred === "string" && preferred.length > 0) {
161
+ return preferred;
162
+ }
163
+ const legacy = env.INTERNAL_API_KEY;
164
+ if (typeof legacy === "string" && legacy.length > 0) {
165
+ return legacy;
166
+ }
167
+ return;
168
+ }
169
+ async function requireAuth(request, env) {
170
+ return requireOperatorAuth(request, env);
171
+ }
172
+ async function requireOperatorAuth(request, env) {
173
+ const apiKey = resolveOperatorApiKey(env);
174
+ if (!apiKey) {
175
+ return new Response(JSON.stringify({
176
+ error: "Operator API key not configured",
177
+ hint: "Set OPERATOR_API_KEY (preferred) or INTERNAL_API_KEY on the Worker"
178
+ }), { status: 401, headers: { "Content-Type": "application/json" } });
179
+ }
180
+ const authHeader = request.headers.get("Authorization");
181
+ const expectedHeader = `Bearer ${apiKey}`;
182
+ if (!authHeader || !timingSafeEqual(authHeader, expectedHeader)) {
183
+ return new Response(JSON.stringify({ error: "Unauthorized" }), {
184
+ status: 401,
185
+ headers: { "Content-Type": "application/json" }
186
+ });
187
+ }
188
+ return null;
189
+ }
190
+ function createOperatorAuthMiddleware() {
191
+ return async (request, env, _ctx) => {
192
+ const denied = await requireOperatorAuth(request, env);
193
+ if (denied)
194
+ return denied;
195
+ return;
196
+ };
197
+ }
198
+ function normalizeKeyNames(keyName) {
199
+ if (typeof keyName === "string") {
200
+ return [keyName];
201
+ }
202
+ return [...keyName];
203
+ }
204
+ function collectInternalAuthKeys(env, keyNames) {
205
+ const keys = [];
206
+ for (const name of normalizeKeyNames(keyNames)) {
207
+ const value = env[name];
208
+ if (typeof value === "string" && value.length > 0) {
209
+ keys.push(value);
210
+ }
211
+ }
212
+ return keys;
213
+ }
214
+ function matchesAnyInternalAuthKey(providedKey, expectedKeys) {
215
+ for (const expected of expectedKeys) {
216
+ if (timingSafeEqual(providedKey, expected)) {
217
+ return true;
218
+ }
219
+ }
220
+ return false;
221
+ }
222
+ function internalAuthNotConfiguredResponse(keyNames) {
223
+ const label = normalizeKeyNames(keyNames).join(" | ");
224
+ return new Response(JSON.stringify({
225
+ success: false,
226
+ error: `Internal auth key(s) not configured: ${label}`
227
+ }), { status: 401, headers: { "Content-Type": "application/json" } });
228
+ }
229
+ function requireInternalAuth(request, env, keyName = "INTERNAL_KEY_BINDING") {
230
+ const expectedKeys = collectInternalAuthKeys(env, keyName);
231
+ if (expectedKeys.length === 0) {
232
+ return internalAuthNotConfiguredResponse(keyName);
233
+ }
234
+ const providedKey = request.headers.get("X-Internal-Auth-Key");
235
+ if (!providedKey || !matchesAnyInternalAuthKey(providedKey, expectedKeys)) {
236
+ return new Response(JSON.stringify({ success: false, error: "Unauthorized" }), { status: 401, headers: { "Content-Type": "application/json" } });
237
+ }
238
+ return null;
239
+ }
240
+ function createInternalAuthMiddleware(keyName = "INTERNAL_KEY_BINDING") {
241
+ return async (request, env, _ctx) => {
242
+ const expectedKeys = collectInternalAuthKeys(env, keyName);
243
+ if (expectedKeys.length === 0) {
244
+ return internalAuthNotConfiguredResponse(keyName);
245
+ }
246
+ const providedKey = request.headers.get("X-Internal-Auth-Key");
247
+ if (!providedKey || !matchesAnyInternalAuthKey(providedKey, expectedKeys)) {
248
+ return new Response(JSON.stringify({ success: false, error: "Unauthorized" }), { status: 401, headers: { "Content-Type": "application/json" } });
249
+ }
250
+ return;
251
+ };
252
+ }
253
+ function checkInternalAuth(request, env, keyName = "INTERNAL_KEY_BINDING") {
254
+ const expectedKeys = collectInternalAuthKeys(env, keyName);
255
+ if (expectedKeys.length === 0) {
256
+ return {
257
+ authorized: false,
258
+ error: `${normalizeKeyNames(keyName).join(" | ")} not configured`
259
+ };
260
+ }
261
+ const providedKey = request.headers.get("X-Internal-Auth-Key");
262
+ if (!providedKey || !matchesAnyInternalAuthKey(providedKey, expectedKeys)) {
263
+ return { authorized: false, error: "Unauthorized" };
264
+ }
265
+ return { authorized: true };
266
+ }
267
+
268
+ // src/middleware/cors.ts
269
+ var DEFAULT_OPTIONS = {
270
+ allowOrigin: "",
271
+ allowMethods: "GET, POST, OPTIONS, PUT, DELETE",
272
+ allowHeaders: "Content-Type, Authorization, X-Request-ID",
273
+ allowCredentials: false,
274
+ maxAge: 86400
275
+ };
276
+ function corsHeaders(options) {
277
+ const opts = { ...DEFAULT_OPTIONS, ...options };
278
+ const headers = {
279
+ "Access-Control-Allow-Methods": opts.allowMethods,
280
+ "Access-Control-Allow-Headers": opts.allowHeaders,
281
+ "Access-Control-Max-Age": String(opts.maxAge)
282
+ };
283
+ if (opts.allowOrigin) {
284
+ headers["Access-Control-Allow-Origin"] = opts.allowOrigin;
285
+ }
286
+ if (opts.allowCredentials) {
287
+ headers["Access-Control-Allow-Credentials"] = "true";
288
+ }
289
+ return headers;
290
+ }
291
+ function publicCorsHeaders(origin = "*", options) {
292
+ return corsHeaders({ ...options, allowOrigin: origin });
293
+ }
294
+ function internalCorsHeaders() {
295
+ return {};
296
+ }
297
+ function resolveCorsOptions(request, env) {
298
+ const raw = env && typeof env === "object" && "CORS_ALLOW_ORIGIN" in env && typeof env.CORS_ALLOW_ORIGIN === "string" ? env.CORS_ALLOW_ORIGIN : undefined;
299
+ const configured = raw?.trim();
300
+ if (!configured) {
301
+ return {};
302
+ }
303
+ const allowed = configured.split(",").map((entry) => entry.trim()).filter(Boolean);
304
+ const origin = request.headers.get("Origin");
305
+ if (origin && allowed.includes(origin)) {
306
+ return { allowOrigin: origin, allowCredentials: true };
307
+ }
308
+ if (!origin && allowed.length === 1) {
309
+ return { allowOrigin: allowed[0] };
310
+ }
311
+ return {};
312
+ }
313
+ function handleCorsPreflightRequest(request, options) {
314
+ if (request.method !== "OPTIONS")
315
+ return null;
316
+ return new Response(null, {
317
+ status: 204,
318
+ headers: corsHeaders(options)
319
+ });
320
+ }
321
+
144
322
  // src/middleware/logger.ts
145
323
  function createLogger(ctx) {
146
324
  const base = { service: ctx.service, module: ctx.module };
@@ -196,75 +374,7 @@ function withRequestLog(handler, logCtx) {
196
374
  }
197
375
  };
198
376
  }
199
- // src/middleware/auth.ts
200
- function timingSafeEqual(a, b) {
201
- if (a.length !== b.length)
202
- return false;
203
- const encoder = new TextEncoder;
204
- const aBuf = encoder.encode(a);
205
- const bBuf = encoder.encode(b);
206
- let result = 0;
207
- for (let i = 0;i < aBuf.length; i++) {
208
- result |= aBuf[i] ^ bBuf[i];
209
- }
210
- return result === 0;
211
- }
212
- async function requireAuth(request, env) {
213
- const apiKey = env.INTERNAL_API_KEY;
214
- if (!apiKey) {
215
- return new Response(JSON.stringify({ error: "Internal API key not configured" }), { status: 401, headers: { "Content-Type": "application/json" } });
216
- }
217
- const authHeader = request.headers.get("Authorization");
218
- const expectedHeader = `Bearer ${apiKey}`;
219
- if (!authHeader || !timingSafeEqual(authHeader, expectedHeader)) {
220
- return new Response(JSON.stringify({ error: "Unauthorized" }), {
221
- status: 401,
222
- headers: { "Content-Type": "application/json" }
223
- });
224
- }
225
- return null;
226
- }
227
- function requireInternalAuth(request, env, keyName = "INTERNAL_KEY_BINDING") {
228
- const expectedKey = env[keyName];
229
- if (!expectedKey) {
230
- return new Response(JSON.stringify({
231
- success: false,
232
- error: `Internal auth key ${keyName} not configured`
233
- }), { status: 401, headers: { "Content-Type": "application/json" } });
234
- }
235
- const providedKey = request.headers.get("X-Internal-Auth-Key");
236
- if (!providedKey || !timingSafeEqual(providedKey, expectedKey)) {
237
- return new Response(JSON.stringify({ success: false, error: "Unauthorized" }), { status: 401, headers: { "Content-Type": "application/json" } });
238
- }
239
- return null;
240
- }
241
- function createInternalAuthMiddleware(keyName = "INTERNAL_KEY_BINDING") {
242
- return async (request, env, _ctx) => {
243
- const expectedKey = env[keyName];
244
- if (!expectedKey) {
245
- return new Response(JSON.stringify({
246
- success: false,
247
- error: `Internal auth key ${keyName} not configured`
248
- }), { status: 401, headers: { "Content-Type": "application/json" } });
249
- }
250
- const providedKey = request.headers.get("X-Internal-Auth-Key");
251
- if (!providedKey || !timingSafeEqual(providedKey, expectedKey)) {
252
- return new Response(JSON.stringify({ success: false, error: "Unauthorized" }), { status: 401, headers: { "Content-Type": "application/json" } });
253
- }
254
- return;
255
- };
256
- }
257
- function checkInternalAuth(request, env, keyName = "INTERNAL_KEY_BINDING") {
258
- const expectedKey = env[keyName];
259
- if (!expectedKey) {
260
- return { authorized: false, error: `${keyName} not configured` };
261
- }
262
- const providedKey = request.headers.get("X-Internal-Auth-Key");
263
- if (!providedKey || !timingSafeEqual(providedKey, expectedKey)) {
264
- return { authorized: false, error: "Unauthorized" };
265
- }
266
- return { authorized: true };
267
- }
377
+
268
378
  // src/middleware/rate-limit.ts
269
379
  function createStorage(kv) {
270
380
  if (!kv) {
@@ -338,16 +448,11 @@ function createStorage(kv) {
338
448
  await kv.put(key, value, opts);
339
449
  },
340
450
  async incr(key, opts) {
341
- const maxRetries = 3;
342
- for (let attempt = 0;attempt < maxRetries; attempt++) {
343
- const current2 = await kv.get(key);
344
- const count = current2 ? parseInt(current2, 10) : 0;
345
- const next = count + 1;
346
- await kv.put(key, String(next), opts);
347
- return next;
348
- }
349
451
  const current = await kv.get(key);
350
- return current ? parseInt(current, 10) + 1 : 1;
452
+ const count = current ? parseInt(current, 10) : 0;
453
+ const next = count + 1;
454
+ await kv.put(key, String(next), opts);
455
+ return next;
351
456
  }
352
457
  };
353
458
  }
@@ -431,6 +536,7 @@ function createRateLimiter(kv, config) {
431
536
  }
432
537
  return { check, enforce, checkKey, enforceKey };
433
538
  }
539
+
434
540
  // src/middleware/validate.ts
435
541
  function validateJson(schema, data) {
436
542
  const result = schema.safeParse(data);
@@ -464,35 +570,7 @@ function optionalField(body, field, defaultValue) {
464
570
  return defaultValue;
465
571
  return body[field];
466
572
  }
467
- // src/middleware/cors.ts
468
- var DEFAULT_OPTIONS = {
469
- allowOrigin: "*",
470
- allowMethods: "GET, POST, OPTIONS, PUT, DELETE",
471
- allowHeaders: "Content-Type, Authorization, X-Request-ID, X-Internal-Auth-Key",
472
- allowCredentials: false,
473
- maxAge: 86400
474
- };
475
- function corsHeaders(options) {
476
- const opts = { ...DEFAULT_OPTIONS, ...options };
477
- const headers = {
478
- "Access-Control-Allow-Origin": opts.allowOrigin,
479
- "Access-Control-Allow-Methods": opts.allowMethods,
480
- "Access-Control-Allow-Headers": opts.allowHeaders,
481
- "Access-Control-Max-Age": String(opts.maxAge)
482
- };
483
- if (opts.allowCredentials) {
484
- headers["Access-Control-Allow-Credentials"] = "true";
485
- }
486
- return headers;
487
- }
488
- function handleCorsPreflightRequest(request, options) {
489
- if (request.method !== "OPTIONS")
490
- return null;
491
- return new Response(null, {
492
- status: 204,
493
- headers: corsHeaders(options)
494
- });
495
- }
573
+
496
574
  // src/middleware/security-headers.ts
497
575
  var SECURITY_HEADERS_DEFAULTS = {
498
576
  xContentTypeOptions: "nosniff",
@@ -536,15 +614,22 @@ export {
536
614
  validateJson,
537
615
  timingSafeEqual,
538
616
  secureHeaders,
617
+ resolveOperatorApiKey,
618
+ resolveCorsOptions,
619
+ requireOperatorAuth,
539
620
  requireInternalAuth,
540
621
  requireField,
541
622
  requireAuth,
623
+ publicCorsHeaders,
542
624
  optionalField,
625
+ internalCorsHeaders,
543
626
  handleCorsPreflightRequest,
544
627
  createRateLimiter,
628
+ createOperatorAuthMiddleware,
545
629
  createLogger,
546
630
  createInternalAuthMiddleware,
547
631
  corsHeaders,
632
+ collectInternalAuthKeys,
548
633
  checkInternalAuth,
549
634
  SECURITY_HEADERS_DEFAULTS
550
635
  };
@@ -0,0 +1,202 @@
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
+ // src/errors.ts
19
+ function toError(err, fallback = "Unknown error") {
20
+ if (err instanceof Error)
21
+ return err.message;
22
+ if (typeof err === "string")
23
+ return err;
24
+ if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
25
+ return err.message;
26
+ }
27
+ if (err === null || err === undefined)
28
+ return fallback;
29
+ try {
30
+ return JSON.stringify(err) || fallback;
31
+ } catch {
32
+ return fallback;
33
+ }
34
+ }
35
+ var SENSITIVE_FIELDS = new Set([
36
+ "password",
37
+ "token",
38
+ "secret",
39
+ "api_key",
40
+ "apiKey",
41
+ "authorization"
42
+ ]);
43
+ function hasSensitiveFields(obj) {
44
+ for (const key of Object.keys(obj)) {
45
+ if (SENSITIVE_FIELDS.has(key))
46
+ return true;
47
+ }
48
+ return false;
49
+ }
50
+ function hasErrorValues(obj) {
51
+ for (const v of Object.values(obj)) {
52
+ if (v instanceof Error)
53
+ return true;
54
+ }
55
+ return false;
56
+ }
57
+ function sanitizeOutput(data) {
58
+ if (data === null || data === undefined)
59
+ return data;
60
+ const t = typeof data;
61
+ if (t === "string" || t === "number" || t === "boolean")
62
+ return data;
63
+ if (data instanceof Error) {
64
+ return { name: data.name, message: data.message };
65
+ }
66
+ if (Array.isArray(data)) {
67
+ return data.map(sanitizeOutput);
68
+ }
69
+ if (t === "object") {
70
+ const obj = data;
71
+ const keys = Object.keys(obj);
72
+ if (keys.length < 10) {
73
+ const sanitized2 = {};
74
+ for (const k of keys) {
75
+ if (k === "stack" || k === "cause")
76
+ continue;
77
+ const v = obj[k];
78
+ sanitized2[k] = v instanceof Error ? { name: v.name, message: v.message } : sanitizeOutput(v);
79
+ }
80
+ return sanitized2;
81
+ }
82
+ if (!hasSensitiveFields(obj) && !hasErrorValues(obj)) {
83
+ return obj;
84
+ }
85
+ const sanitized = {};
86
+ for (const k of keys) {
87
+ if (k === "stack" || k === "cause")
88
+ continue;
89
+ const v = obj[k];
90
+ sanitized[k] = v instanceof Error ? { name: v.name, message: v.message } : sanitizeOutput(v);
91
+ }
92
+ return sanitized;
93
+ }
94
+ return data;
95
+ }
96
+ function createJsonResponse(data, status = 200) {
97
+ return new Response(JSON.stringify(sanitizeOutput(data)), {
98
+ status,
99
+ headers: { "Content-Type": "application/json" }
100
+ });
101
+ }
102
+ function createSuccessResponse(result) {
103
+ return createJsonResponse({ success: true, result }, 200);
104
+ }
105
+ function createErrorResponse(error, status) {
106
+ const message = typeof error === "string" ? error : error.message;
107
+ const statusCode = typeof error === "string" ? status ?? 500 : error.status ?? 500;
108
+ const body = { success: false, error: message };
109
+ if (typeof error !== "string" && error.code)
110
+ body.code = error.code;
111
+ if (typeof error !== "string" && error.details !== undefined)
112
+ body.details = error.details;
113
+ return new Response(JSON.stringify(body), {
114
+ status: statusCode,
115
+ headers: { "Content-Type": "application/json" }
116
+ });
117
+ }
118
+ var Errors = {
119
+ badRequest: (message) => createErrorResponse({ message, status: 400, code: "BAD_REQUEST" }),
120
+ unauthorized: (message = "Unauthorized") => createErrorResponse({ message, status: 401, code: "UNAUTHORIZED" }),
121
+ forbidden: (message = "Forbidden") => createErrorResponse({ message, status: 403, code: "FORBIDDEN" }),
122
+ notFound: (message = "Not found") => createErrorResponse({ message, status: 404, code: "NOT_FOUND" }),
123
+ methodNotAllowed: (message = "Method not allowed") => createErrorResponse({ message, status: 405, code: "METHOD_NOT_ALLOWED" }),
124
+ rateLimited: (retryAfter) => {
125
+ const res = createErrorResponse({
126
+ message: "Rate limit exceeded",
127
+ status: 429,
128
+ code: "RATE_LIMITED"
129
+ });
130
+ if (retryAfter)
131
+ res.headers.set("Retry-After", String(retryAfter));
132
+ return res;
133
+ },
134
+ internal: (err) => {
135
+ const message = err ? toError(err, "Internal server error") : "Internal server error";
136
+ return createErrorResponse({
137
+ message,
138
+ status: 500,
139
+ code: "INTERNAL_ERROR"
140
+ });
141
+ }
142
+ };
143
+
144
+ // src/middleware/logger.ts
145
+ function createLogger(ctx) {
146
+ const base = { service: ctx.service, module: ctx.module };
147
+ function emit(level, message, context) {
148
+ const entry = {
149
+ level,
150
+ timestamp: new Date().toISOString(),
151
+ ...base,
152
+ message,
153
+ ...context && { context }
154
+ };
155
+ const line = JSON.stringify(entry);
156
+ if (level === "error")
157
+ console.error(line);
158
+ else if (level === "warn")
159
+ console.warn(line);
160
+ else if (level === "debug")
161
+ console.debug(line);
162
+ else
163
+ console.info(line);
164
+ }
165
+ return {
166
+ debug: (msg, ctx2) => emit("debug", msg, ctx2),
167
+ info: (msg, ctx2) => emit("info", msg, ctx2),
168
+ warn: (msg, ctx2) => emit("warn", msg, ctx2),
169
+ error: (msg, ctx2) => emit("error", msg, ctx2)
170
+ };
171
+ }
172
+ function withRequestLog(handler, logCtx) {
173
+ return async (request, env, ctx) => {
174
+ const start = Date.now();
175
+ const logger = createLogger(logCtx);
176
+ try {
177
+ const response = await handler(request, env, ctx);
178
+ const duration = Date.now() - start;
179
+ const url = new URL(request.url);
180
+ logger.info(`${request.method} ${url.pathname}`, {
181
+ method: request.method,
182
+ path: url.pathname,
183
+ status: response.status,
184
+ durationMs: duration
185
+ });
186
+ return response;
187
+ } catch (error) {
188
+ const duration = Date.now() - start;
189
+ logger.error("Request failed", {
190
+ method: request.method,
191
+ path: new URL(request.url).pathname,
192
+ durationMs: duration,
193
+ error: toError(error)
194
+ });
195
+ throw error;
196
+ }
197
+ };
198
+ }
199
+ export {
200
+ withRequestLog,
201
+ createLogger
202
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;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;AA6HD,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;;;;;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"}