@pegasusheavy/nestjs-platform-deno 0.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,1708 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ DenoAdapter: () => DenoAdapter,
24
+ createExpressRequest: () => createExpressRequest,
25
+ createExpressResponse: () => createExpressResponse,
26
+ createFastifyLogger: () => createFastifyLogger,
27
+ createFastifyReply: () => createFastifyReply,
28
+ createFastifyRequest: () => createFastifyRequest,
29
+ wrapExpressMiddleware: () => wrapExpressMiddleware,
30
+ wrapFastifyHook: () => wrapFastifyHook,
31
+ wrapFastifyPlugin: () => wrapFastifyPlugin
32
+ });
33
+ module.exports = __toCommonJS(index_exports);
34
+
35
+ // src/adapters/deno-adapter.ts
36
+ var import_core = require("@nestjs/core");
37
+ var import_common = require("@nestjs/common");
38
+
39
+ // src/compat/express-compat.ts
40
+ var STATUS_MESSAGES = {
41
+ 100: "Continue",
42
+ 101: "Switching Protocols",
43
+ 102: "Processing",
44
+ 200: "OK",
45
+ 201: "Created",
46
+ 202: "Accepted",
47
+ 204: "No Content",
48
+ 206: "Partial Content",
49
+ 301: "Moved Permanently",
50
+ 302: "Found",
51
+ 303: "See Other",
52
+ 304: "Not Modified",
53
+ 307: "Temporary Redirect",
54
+ 308: "Permanent Redirect",
55
+ 400: "Bad Request",
56
+ 401: "Unauthorized",
57
+ 403: "Forbidden",
58
+ 404: "Not Found",
59
+ 405: "Method Not Allowed",
60
+ 406: "Not Acceptable",
61
+ 408: "Request Timeout",
62
+ 409: "Conflict",
63
+ 410: "Gone",
64
+ 413: "Payload Too Large",
65
+ 415: "Unsupported Media Type",
66
+ 422: "Unprocessable Entity",
67
+ 429: "Too Many Requests",
68
+ 500: "Internal Server Error",
69
+ 501: "Not Implemented",
70
+ 502: "Bad Gateway",
71
+ 503: "Service Unavailable",
72
+ 504: "Gateway Timeout"
73
+ };
74
+ function headersToObject(headers) {
75
+ const result = {};
76
+ headers.forEach((value, key) => {
77
+ const existing = result[key.toLowerCase()];
78
+ if (existing) {
79
+ if (Array.isArray(existing)) {
80
+ existing.push(value);
81
+ } else {
82
+ result[key.toLowerCase()] = [existing, value];
83
+ }
84
+ } else {
85
+ result[key.toLowerCase()] = value;
86
+ }
87
+ });
88
+ return result;
89
+ }
90
+ function parseAccept(acceptHeader, types) {
91
+ if (!acceptHeader || types.length === 0) return false;
92
+ const accepts = acceptHeader.split(",").map((part) => {
93
+ const [type, ...params] = part.trim().split(";");
94
+ let q = 1;
95
+ params.forEach((p) => {
96
+ const [key, value] = p.trim().split("=");
97
+ if (key === "q") q = parseFloat(value) || 1;
98
+ });
99
+ return { type: type.trim(), q };
100
+ }).sort((a, b) => b.q - a.q);
101
+ for (const accept of accepts) {
102
+ for (const type of types) {
103
+ if (accept.type === "*/*" || accept.type === type || accept.type.endsWith("/*") && type.startsWith(accept.type.slice(0, -1))) {
104
+ return type;
105
+ }
106
+ }
107
+ }
108
+ return false;
109
+ }
110
+ function serializeCookie(name, value, options = {}) {
111
+ let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
112
+ if (options.maxAge !== void 0) {
113
+ cookie += `; Max-Age=${options.maxAge}`;
114
+ }
115
+ if (options.domain) {
116
+ cookie += `; Domain=${options.domain}`;
117
+ }
118
+ if (options.path) {
119
+ cookie += `; Path=${options.path}`;
120
+ } else {
121
+ cookie += "; Path=/";
122
+ }
123
+ if (options.expires) {
124
+ cookie += `; Expires=${options.expires.toUTCString()}`;
125
+ }
126
+ if (options.httpOnly) {
127
+ cookie += "; HttpOnly";
128
+ }
129
+ if (options.secure) {
130
+ cookie += "; Secure";
131
+ }
132
+ if (options.sameSite) {
133
+ if (options.sameSite === true) {
134
+ cookie += "; SameSite=Strict";
135
+ } else {
136
+ cookie += `; SameSite=${options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1)}`;
137
+ }
138
+ }
139
+ return cookie;
140
+ }
141
+ function createExpressRequest(denoReq) {
142
+ const headersObj = headersToObject(denoReq.headers);
143
+ const cookieHeader = denoReq.headers.get("cookie") || "";
144
+ const cookies = {};
145
+ cookieHeader.split(";").forEach((cookie) => {
146
+ const [name, ...valueParts] = cookie.trim().split("=");
147
+ if (name) {
148
+ cookies[decodeURIComponent(name.trim())] = decodeURIComponent(valueParts.join("="));
149
+ }
150
+ });
151
+ const req = {
152
+ // Core properties
153
+ method: denoReq.method,
154
+ url: denoReq.originalUrl || denoReq.path || "/",
155
+ originalUrl: denoReq.originalUrl || denoReq.path || "/",
156
+ baseUrl: denoReq.baseUrl || "",
157
+ path: denoReq.path || "/",
158
+ hostname: denoReq.hostname || "",
159
+ ip: denoReq.ip,
160
+ protocol: denoReq.protocol || "http",
161
+ secure: denoReq.secure || false,
162
+ headers: headersObj,
163
+ // Parsed data
164
+ params: denoReq.params,
165
+ query: denoReq.query,
166
+ body: denoReq.body,
167
+ // Raw access
168
+ raw: denoReq.raw,
169
+ // Cookies
170
+ cookies,
171
+ signedCookies: {},
172
+ // Computed properties
173
+ xhr: denoReq.headers.get("x-requested-with")?.toLowerCase() === "xmlhttprequest",
174
+ subdomains: denoReq.hostname?.split(".").slice(0, -2).reverse() || [],
175
+ // Methods
176
+ get(name) {
177
+ const key = name.toLowerCase();
178
+ const value = headersObj[key];
179
+ return Array.isArray(value) ? value[0] : value;
180
+ },
181
+ header(name) {
182
+ return this.get(name);
183
+ },
184
+ is(type) {
185
+ const contentType = denoReq.headers.get("content-type");
186
+ if (!contentType) return null;
187
+ const types = Array.isArray(type) ? type : [type];
188
+ for (const t of types) {
189
+ if (contentType.includes(t) || contentType.includes(t.replace("/", ""))) {
190
+ return t;
191
+ }
192
+ }
193
+ return false;
194
+ },
195
+ accepts(...types) {
196
+ return parseAccept(denoReq.headers.get("accept") || void 0, types);
197
+ },
198
+ acceptsEncodings(...encodings) {
199
+ return parseAccept(denoReq.headers.get("accept-encoding") || void 0, encodings);
200
+ },
201
+ acceptsCharsets(...charsets) {
202
+ return parseAccept(denoReq.headers.get("accept-charset") || void 0, charsets);
203
+ },
204
+ acceptsLanguages(...langs) {
205
+ return parseAccept(denoReq.headers.get("accept-language") || void 0, langs);
206
+ }
207
+ };
208
+ const modifiedSince = denoReq.headers.get("if-modified-since");
209
+ const noneMatch = denoReq.headers.get("if-none-match");
210
+ req.fresh = !!(modifiedSince || noneMatch);
211
+ req.stale = !req.fresh;
212
+ return req;
213
+ }
214
+ function createExpressResponse(denoRes) {
215
+ let statusMessage = "OK";
216
+ const cookies = [];
217
+ const res = {
218
+ // Properties
219
+ get statusCode() {
220
+ return denoRes.statusCode;
221
+ },
222
+ set statusCode(code) {
223
+ denoRes.statusCode = code;
224
+ statusMessage = STATUS_MESSAGES[code] || "Unknown";
225
+ },
226
+ get statusMessage() {
227
+ return statusMessage;
228
+ },
229
+ set statusMessage(msg) {
230
+ statusMessage = msg;
231
+ },
232
+ get headersSent() {
233
+ return denoRes.headersSent;
234
+ },
235
+ // Status methods
236
+ status(code) {
237
+ denoRes.status(code);
238
+ statusMessage = STATUS_MESSAGES[code] || "Unknown";
239
+ return this;
240
+ },
241
+ sendStatus(code) {
242
+ this.status(code);
243
+ denoRes.send(STATUS_MESSAGES[code] || String(code));
244
+ return this;
245
+ },
246
+ // Header methods
247
+ set(field, value) {
248
+ if (typeof field === "object") {
249
+ Object.entries(field).forEach(([key, val]) => {
250
+ if (Array.isArray(val)) {
251
+ val.forEach((v) => denoRes.headers.append(key, v));
252
+ } else {
253
+ denoRes.setHeader(key, val);
254
+ }
255
+ });
256
+ } else if (value !== void 0) {
257
+ if (Array.isArray(value)) {
258
+ value.forEach((v) => denoRes.headers.append(field, v));
259
+ } else {
260
+ denoRes.setHeader(field, value);
261
+ }
262
+ }
263
+ return this;
264
+ },
265
+ header(field, value) {
266
+ if (value === void 0) {
267
+ return denoRes.getHeader(field) || void 0;
268
+ }
269
+ return this.set(field, value);
270
+ },
271
+ get(field) {
272
+ return denoRes.getHeader(field) || void 0;
273
+ },
274
+ append(field, value) {
275
+ if (Array.isArray(value)) {
276
+ value.forEach((v) => denoRes.headers.append(field, v));
277
+ } else {
278
+ denoRes.headers.append(field, value);
279
+ }
280
+ return this;
281
+ },
282
+ // Body methods
283
+ send(body) {
284
+ if (body === void 0) {
285
+ denoRes.end();
286
+ } else if (typeof body === "string") {
287
+ if (!denoRes.getHeader("Content-Type")) {
288
+ denoRes.setHeader("Content-Type", "text/html; charset=utf-8");
289
+ }
290
+ denoRes.send(body);
291
+ } else if (Buffer.isBuffer(body)) {
292
+ if (!denoRes.getHeader("Content-Type")) {
293
+ denoRes.setHeader("Content-Type", "application/octet-stream");
294
+ }
295
+ denoRes.send(body);
296
+ } else if (typeof body === "object") {
297
+ return this.json(body);
298
+ } else {
299
+ denoRes.send(String(body));
300
+ }
301
+ return this;
302
+ },
303
+ json(body) {
304
+ denoRes.json(body);
305
+ return this;
306
+ },
307
+ jsonp(body) {
308
+ denoRes.json(body);
309
+ return this;
310
+ },
311
+ end(data) {
312
+ if (data !== void 0) {
313
+ denoRes.end(typeof data === "string" ? data : JSON.stringify(data));
314
+ } else {
315
+ denoRes.end();
316
+ }
317
+ return this;
318
+ },
319
+ // Redirect
320
+ redirect(statusOrUrl, url) {
321
+ if (typeof statusOrUrl === "number" && url) {
322
+ denoRes.redirect(url, statusOrUrl);
323
+ } else if (typeof statusOrUrl === "string") {
324
+ denoRes.redirect(statusOrUrl, 302);
325
+ }
326
+ },
327
+ // Content type
328
+ type(type) {
329
+ const mimeTypes = {
330
+ html: "text/html",
331
+ json: "application/json",
332
+ xml: "application/xml",
333
+ text: "text/plain",
334
+ js: "application/javascript",
335
+ css: "text/css"
336
+ };
337
+ const contentType = mimeTypes[type] || type;
338
+ denoRes.setHeader("Content-Type", contentType);
339
+ return this;
340
+ },
341
+ contentType(type) {
342
+ return this.type(type);
343
+ },
344
+ // Cookies
345
+ cookie(name, value, options = {}) {
346
+ const cookieStr = serializeCookie(name, value, options);
347
+ cookies.push(cookieStr);
348
+ denoRes.headers.append("Set-Cookie", cookieStr);
349
+ return this;
350
+ },
351
+ clearCookie(name, options = {}) {
352
+ const clearOptions = { ...options, expires: /* @__PURE__ */ new Date(0), maxAge: 0 };
353
+ return this.cookie(name, "", clearOptions);
354
+ },
355
+ // Other methods
356
+ location(url) {
357
+ denoRes.setHeader("Location", url);
358
+ return this;
359
+ },
360
+ links(links) {
361
+ const linkHeader = Object.entries(links).map(([rel, href]) => `<${href}>; rel="${rel}"`).join(", ");
362
+ denoRes.setHeader("Link", linkHeader);
363
+ return this;
364
+ },
365
+ vary(field) {
366
+ const existing = denoRes.getHeader("Vary");
367
+ if (existing) {
368
+ denoRes.setHeader("Vary", `${existing}, ${field}`);
369
+ } else {
370
+ denoRes.setHeader("Vary", field);
371
+ }
372
+ return this;
373
+ },
374
+ format(obj) {
375
+ const accept = denoRes.headers.get?.("Accept") || "*/*";
376
+ const types = Object.keys(obj);
377
+ const matched = parseAccept(accept, types);
378
+ if (matched && obj[matched]) {
379
+ obj[matched]();
380
+ } else if (obj.default) {
381
+ obj.default();
382
+ }
383
+ return this;
384
+ }
385
+ };
386
+ return res;
387
+ }
388
+ function wrapExpressMiddleware(middleware) {
389
+ return async (denoReq, denoRes, next) => {
390
+ const expressReq = createExpressRequest(denoReq);
391
+ const expressRes = createExpressResponse(denoRes);
392
+ return new Promise((resolve, reject) => {
393
+ const expressNext = (err) => {
394
+ if (err) {
395
+ if (middleware.length === 4) {
396
+ try {
397
+ const result = middleware(err, expressReq, expressRes, expressNext);
398
+ if (result instanceof Promise) {
399
+ result.catch(reject);
400
+ }
401
+ } catch (e) {
402
+ reject(e);
403
+ }
404
+ } else {
405
+ reject(err);
406
+ }
407
+ } else {
408
+ next().then(resolve).catch(reject);
409
+ }
410
+ };
411
+ try {
412
+ const result = middleware(expressReq, expressRes, expressNext);
413
+ if (result instanceof Promise) {
414
+ result.catch(reject);
415
+ }
416
+ } catch (err) {
417
+ reject(err);
418
+ }
419
+ });
420
+ };
421
+ }
422
+
423
+ // src/compat/fastify-compat.ts
424
+ var requestIdCounter = 0;
425
+ function generateRequestId() {
426
+ return `req-${Date.now()}-${++requestIdCounter}`;
427
+ }
428
+ function headersToObject2(headers) {
429
+ const result = {};
430
+ headers.forEach((value, key) => {
431
+ const lowerKey = key.toLowerCase();
432
+ const existing = result[lowerKey];
433
+ if (existing) {
434
+ if (Array.isArray(existing)) {
435
+ existing.push(value);
436
+ } else {
437
+ result[lowerKey] = [existing, value];
438
+ }
439
+ } else {
440
+ result[lowerKey] = value;
441
+ }
442
+ });
443
+ return result;
444
+ }
445
+ function createFastifyRequest(denoReq) {
446
+ const headersObj = headersToObject2(denoReq.headers);
447
+ const req = {
448
+ id: generateRequestId(),
449
+ params: denoReq.params,
450
+ query: denoReq.query,
451
+ body: denoReq.body,
452
+ headers: headersObj,
453
+ raw: denoReq.raw,
454
+ url: denoReq.originalUrl || denoReq.path || "/",
455
+ originalUrl: denoReq.originalUrl || denoReq.path || "/",
456
+ method: denoReq.method,
457
+ hostname: denoReq.hostname || "",
458
+ ip: denoReq.ip,
459
+ protocol: denoReq.secure ? "https" : "http",
460
+ routerPath: denoReq.path,
461
+ routerMethod: denoReq.method
462
+ };
463
+ return req;
464
+ }
465
+ function createFastifyReply(denoRes) {
466
+ let serializer = JSON.stringify;
467
+ const startTime = Date.now();
468
+ const reply = {
469
+ get statusCode() {
470
+ return denoRes.statusCode;
471
+ },
472
+ set statusCode(code) {
473
+ denoRes.statusCode = code;
474
+ },
475
+ get sent() {
476
+ return denoRes.headersSent;
477
+ },
478
+ raw: denoRes,
479
+ code(statusCode) {
480
+ denoRes.status(statusCode);
481
+ return this;
482
+ },
483
+ status(statusCode) {
484
+ return this.code(statusCode);
485
+ },
486
+ header(key, value) {
487
+ denoRes.setHeader(key, String(value));
488
+ return this;
489
+ },
490
+ headers(headers) {
491
+ Object.entries(headers).forEach(([key, value]) => {
492
+ denoRes.setHeader(key, String(value));
493
+ });
494
+ return this;
495
+ },
496
+ getHeader(key) {
497
+ return denoRes.getHeader(key) || void 0;
498
+ },
499
+ getHeaders() {
500
+ const result = {};
501
+ denoRes.headers.forEach((value, key) => {
502
+ result[key] = value;
503
+ });
504
+ return result;
505
+ },
506
+ removeHeader(key) {
507
+ denoRes.removeHeader(key);
508
+ return this;
509
+ },
510
+ hasHeader(key) {
511
+ return denoRes.getHeader(key) !== null;
512
+ },
513
+ send(payload) {
514
+ if (payload === void 0) {
515
+ denoRes.end();
516
+ } else if (typeof payload === "string") {
517
+ if (!denoRes.getHeader("Content-Type")) {
518
+ denoRes.setHeader("Content-Type", "text/plain; charset=utf-8");
519
+ }
520
+ denoRes.send(payload);
521
+ } else if (payload instanceof Uint8Array || payload instanceof ArrayBuffer) {
522
+ if (!denoRes.getHeader("Content-Type")) {
523
+ denoRes.setHeader("Content-Type", "application/octet-stream");
524
+ }
525
+ denoRes.send(payload);
526
+ } else if (typeof payload === "object") {
527
+ if (!denoRes.getHeader("Content-Type")) {
528
+ denoRes.setHeader("Content-Type", "application/json; charset=utf-8");
529
+ }
530
+ denoRes.send(serializer(payload));
531
+ } else {
532
+ denoRes.send(String(payload));
533
+ }
534
+ return this;
535
+ },
536
+ serialize(payload) {
537
+ return serializer(payload);
538
+ },
539
+ serializer(fn) {
540
+ serializer = fn;
541
+ return this;
542
+ },
543
+ type(contentType) {
544
+ denoRes.setHeader("Content-Type", contentType);
545
+ return this;
546
+ },
547
+ redirect(statusCodeOrUrl, url) {
548
+ if (typeof statusCodeOrUrl === "number" && url) {
549
+ denoRes.redirect(url, statusCodeOrUrl);
550
+ } else if (typeof statusCodeOrUrl === "string") {
551
+ denoRes.redirect(statusCodeOrUrl, 302);
552
+ }
553
+ return this;
554
+ },
555
+ callNotFound() {
556
+ denoRes.status(404).json({
557
+ statusCode: 404,
558
+ error: "Not Found",
559
+ message: "Route not found"
560
+ });
561
+ },
562
+ getResponseTime() {
563
+ return Date.now() - startTime;
564
+ }
565
+ };
566
+ return reply;
567
+ }
568
+ function isAsyncHook(hook) {
569
+ return hook.length <= 2;
570
+ }
571
+ function wrapFastifyHook(hook) {
572
+ return async (denoReq, denoRes, next) => {
573
+ const fastifyReq = createFastifyRequest(denoReq);
574
+ const fastifyReply = createFastifyReply(denoRes);
575
+ if (isAsyncHook(hook)) {
576
+ await hook(fastifyReq, fastifyReply);
577
+ if (!fastifyReply.sent) {
578
+ await next();
579
+ }
580
+ } else {
581
+ return new Promise((resolve, reject) => {
582
+ const done = (err) => {
583
+ if (err) {
584
+ reject(err);
585
+ } else if (!fastifyReply.sent) {
586
+ next().then(resolve).catch(reject);
587
+ } else {
588
+ resolve();
589
+ }
590
+ };
591
+ try {
592
+ hook(fastifyReq, fastifyReply, done);
593
+ } catch (err) {
594
+ reject(err);
595
+ }
596
+ });
597
+ }
598
+ };
599
+ }
600
+ function wrapFastifyPlugin(plugin, instance, opts = {}) {
601
+ return new Promise((resolve, reject) => {
602
+ if (plugin.length <= 2) {
603
+ const result = plugin(instance, opts);
604
+ if (result instanceof Promise) {
605
+ result.then(resolve).catch(reject);
606
+ } else {
607
+ resolve();
608
+ }
609
+ } else {
610
+ try {
611
+ plugin(instance, opts, (err) => {
612
+ if (err) {
613
+ reject(err);
614
+ } else {
615
+ resolve();
616
+ }
617
+ });
618
+ } catch (err) {
619
+ reject(err);
620
+ }
621
+ }
622
+ });
623
+ }
624
+ function createFastifyLogger() {
625
+ const createLogFn = (level) => (msg, ...args) => {
626
+ console.log(`[${level.toUpperCase()}] ${msg}`, ...args);
627
+ };
628
+ return {
629
+ info: createLogFn("info"),
630
+ error: createLogFn("error"),
631
+ debug: createLogFn("debug"),
632
+ warn: createLogFn("warn"),
633
+ trace: createLogFn("trace"),
634
+ fatal: createLogFn("fatal"),
635
+ child(bindings) {
636
+ const prefix = Object.entries(bindings).map(([k, v]) => `${k}=${v}`).join(" ");
637
+ const childLog = createFastifyLogger();
638
+ const wrap = (fn) => (msg, ...args) => fn(`[${prefix}] ${msg}`, ...args);
639
+ return {
640
+ ...childLog,
641
+ info: wrap(childLog.info),
642
+ error: wrap(childLog.error),
643
+ debug: wrap(childLog.debug),
644
+ warn: wrap(childLog.warn),
645
+ trace: wrap(childLog.trace),
646
+ fatal: wrap(childLog.fatal)
647
+ };
648
+ }
649
+ };
650
+ }
651
+
652
+ // src/adapters/deno-adapter.ts
653
+ var DenoAdapter = class _DenoAdapter extends import_core.AbstractHttpAdapter {
654
+ routes = [];
655
+ middlewares = [];
656
+ server;
657
+ abortController;
658
+ corsOptions;
659
+ errorHandler;
660
+ notFoundHandler;
661
+ staticAssetsPath;
662
+ staticAssetsOptions;
663
+ constructor(instance) {
664
+ super(instance || {});
665
+ }
666
+ /**
667
+ * Create a new DenoAdapter instance
668
+ */
669
+ static create() {
670
+ return new _DenoAdapter();
671
+ }
672
+ async listen(port, hostnameOrCallback, callback) {
673
+ const portNum = typeof port === "string" ? parseInt(port, 10) : port;
674
+ const hostname = typeof hostnameOrCallback === "string" ? hostnameOrCallback : "0.0.0.0";
675
+ const cb = typeof hostnameOrCallback === "function" ? hostnameOrCallback : callback;
676
+ this.abortController = new AbortController();
677
+ const serveOptions = {
678
+ port: portNum,
679
+ hostname,
680
+ signal: this.abortController.signal,
681
+ onListen: () => {
682
+ cb?.();
683
+ }
684
+ };
685
+ this.server = Deno.serve(
686
+ serveOptions,
687
+ this.handleRequest.bind(this)
688
+ );
689
+ }
690
+ /**
691
+ * Handle incoming HTTP requests
692
+ */
693
+ async handleRequest(request) {
694
+ const url = new URL(request.url);
695
+ const path = url.pathname;
696
+ const method = request.method.toUpperCase();
697
+ const req = await this.createRequest(request, url);
698
+ const res = this.createResponse();
699
+ try {
700
+ if (this.corsOptions && method === "OPTIONS") {
701
+ this.handleCors(req, res);
702
+ return this.buildResponse(res);
703
+ }
704
+ if (this.corsOptions) {
705
+ this.applyCorsHeaders(req, res);
706
+ }
707
+ if (this.staticAssetsPath && path.startsWith(this.staticAssetsOptions?.prefix || "/")) {
708
+ const staticResponse = await this.serveStaticAsset(path);
709
+ if (staticResponse) {
710
+ return staticResponse;
711
+ }
712
+ }
713
+ await this.runMiddlewares(req, res, path);
714
+ if (res.headersSent) {
715
+ return this.buildResponse(res);
716
+ }
717
+ const route = this.findRoute(path, method);
718
+ if (route) {
719
+ req.params = this.extractParams(route, path);
720
+ await route.handler(req, res);
721
+ } else if (this.notFoundHandler) {
722
+ this.notFoundHandler(req, res);
723
+ } else {
724
+ res.status(import_common.HttpStatus.NOT_FOUND).json({
725
+ statusCode: import_common.HttpStatus.NOT_FOUND,
726
+ message: "Cannot " + method + " " + path,
727
+ error: "Not Found"
728
+ });
729
+ }
730
+ return this.buildResponse(res);
731
+ } catch (error) {
732
+ if (this.errorHandler) {
733
+ this.errorHandler(error, req, res);
734
+ return this.buildResponse(res);
735
+ }
736
+ res.status(import_common.HttpStatus.INTERNAL_SERVER_ERROR).json({
737
+ statusCode: import_common.HttpStatus.INTERNAL_SERVER_ERROR,
738
+ message: error.message || "Internal Server Error",
739
+ error: "Internal Server Error"
740
+ });
741
+ return this.buildResponse(res);
742
+ }
743
+ }
744
+ /**
745
+ * Create a DenoRequest object from a native Request
746
+ */
747
+ async createRequest(request, url) {
748
+ let body = void 0;
749
+ if (["POST", "PUT", "PATCH", "DELETE"].includes(request.method.toUpperCase())) {
750
+ const contentType = request.headers.get("content-type") || "";
751
+ if (contentType.includes("application/json")) {
752
+ try {
753
+ body = await request.json();
754
+ } catch {
755
+ body = void 0;
756
+ }
757
+ } else if (contentType.includes("application/x-www-form-urlencoded")) {
758
+ try {
759
+ const formData = await request.formData();
760
+ const entries = {};
761
+ formData.forEach((value, key) => {
762
+ entries[key] = value;
763
+ });
764
+ body = entries;
765
+ } catch {
766
+ body = void 0;
767
+ }
768
+ } else if (contentType.includes("text/")) {
769
+ try {
770
+ body = await request.text();
771
+ } catch {
772
+ body = void 0;
773
+ }
774
+ } else if (contentType.includes("multipart/form-data")) {
775
+ try {
776
+ body = await request.formData();
777
+ } catch {
778
+ body = void 0;
779
+ }
780
+ }
781
+ }
782
+ const query = {};
783
+ url.searchParams.forEach((value, key) => {
784
+ query[key] = value;
785
+ });
786
+ return {
787
+ raw: request,
788
+ url: request.url,
789
+ method: request.method,
790
+ headers: request.headers,
791
+ params: {},
792
+ query,
793
+ body,
794
+ ip: void 0,
795
+ // Deno doesn't expose client IP in the same way
796
+ hostname: url.hostname,
797
+ protocol: url.protocol.replace(":", ""),
798
+ secure: url.protocol === "https:",
799
+ originalUrl: url.pathname + url.search,
800
+ baseUrl: "",
801
+ path: url.pathname
802
+ };
803
+ }
804
+ /**
805
+ * Create a DenoResponse object
806
+ */
807
+ createResponse() {
808
+ const headers = new Headers();
809
+ let statusCode = 200;
810
+ let body = null;
811
+ let headersSent = false;
812
+ const res = {
813
+ get statusCode() {
814
+ return statusCode;
815
+ },
816
+ set statusCode(code) {
817
+ statusCode = code;
818
+ },
819
+ headers,
820
+ get body() {
821
+ return body;
822
+ },
823
+ set body(b) {
824
+ body = b ?? null;
825
+ },
826
+ get headersSent() {
827
+ return headersSent;
828
+ },
829
+ set headersSent(sent) {
830
+ headersSent = sent;
831
+ },
832
+ status(code) {
833
+ statusCode = code;
834
+ return this;
835
+ },
836
+ setHeader(name, value) {
837
+ headers.set(name, value);
838
+ return this;
839
+ },
840
+ getHeader(name) {
841
+ return headers.get(name);
842
+ },
843
+ removeHeader(name) {
844
+ headers.delete(name);
845
+ return this;
846
+ },
847
+ send(responseBody) {
848
+ headersSent = true;
849
+ if (responseBody === void 0 || responseBody === null) {
850
+ body = null;
851
+ } else if (typeof responseBody === "object" && !(responseBody instanceof Blob) && !(responseBody instanceof ReadableStream) && !(responseBody instanceof FormData) && !(responseBody instanceof URLSearchParams) && !(responseBody instanceof ArrayBuffer)) {
852
+ headers.set("Content-Type", "application/json");
853
+ body = JSON.stringify(responseBody);
854
+ } else {
855
+ body = responseBody;
856
+ }
857
+ },
858
+ json(responseBody) {
859
+ headersSent = true;
860
+ headers.set("Content-Type", "application/json");
861
+ body = JSON.stringify(responseBody);
862
+ },
863
+ redirect(url, code = 302) {
864
+ headersSent = true;
865
+ statusCode = code;
866
+ headers.set("Location", url);
867
+ body = null;
868
+ },
869
+ end(responseBody) {
870
+ headersSent = true;
871
+ body = responseBody ?? null;
872
+ }
873
+ };
874
+ return res;
875
+ }
876
+ /**
877
+ * Build a Response object from DenoResponse
878
+ */
879
+ buildResponse(res) {
880
+ return new Response(res.body, {
881
+ status: res.statusCode,
882
+ headers: res.headers
883
+ });
884
+ }
885
+ /**
886
+ * Run all matching middlewares
887
+ */
888
+ async runMiddlewares(req, res, path) {
889
+ const matchingMiddlewares = this.middlewares.filter(
890
+ (m) => path.startsWith(m.path) || m.path === "*" || m.path === "/"
891
+ );
892
+ let index = 0;
893
+ const next = async () => {
894
+ if (index < matchingMiddlewares.length && !res.headersSent) {
895
+ const middleware = matchingMiddlewares[index++];
896
+ await middleware.handler(req, res, next);
897
+ }
898
+ };
899
+ await next();
900
+ }
901
+ /**
902
+ * Find a matching route
903
+ */
904
+ findRoute(path, method) {
905
+ return this.routes.find((route) => {
906
+ const methodMatch = route.method === method || route.method === "ALL";
907
+ if (typeof route.path === "string") {
908
+ const pattern = this.pathToRegex(route.path);
909
+ return methodMatch && pattern.test(path);
910
+ }
911
+ return methodMatch && route.path.test(path);
912
+ });
913
+ }
914
+ /**
915
+ * Extract route parameters from path
916
+ */
917
+ extractParams(route, path) {
918
+ const params = {};
919
+ if (typeof route.path === "string") {
920
+ const pattern = this.pathToRegex(route.path);
921
+ const match = path.match(pattern);
922
+ if (match) {
923
+ route.keys.forEach((key, index) => {
924
+ params[key] = match[index + 1] || "";
925
+ });
926
+ }
927
+ }
928
+ return params;
929
+ }
930
+ /**
931
+ * Convert a path pattern to a RegExp
932
+ */
933
+ pathToRegex(path) {
934
+ const escaped = path.replace(/([.+?^${}()|[\]\\])/g, "\\$1").replace(/:(\w+)/g, "([^/]+)").replace(/\*/g, ".*");
935
+ return new RegExp(`^${escaped}$`);
936
+ }
937
+ /**
938
+ * Extract parameter keys from path pattern
939
+ */
940
+ extractKeys(path) {
941
+ const keys = [];
942
+ const regex = /:(\w+)/g;
943
+ let match;
944
+ while ((match = regex.exec(path)) !== null) {
945
+ keys.push(match[1]);
946
+ }
947
+ return keys;
948
+ }
949
+ /**
950
+ * Register a route handler
951
+ */
952
+ registerRoute(method, path, handler) {
953
+ this.routes.push({
954
+ path,
955
+ method,
956
+ handler,
957
+ keys: this.extractKeys(path)
958
+ });
959
+ }
960
+ get(pathOrHandler, handler) {
961
+ if (typeof pathOrHandler === "function") {
962
+ this.registerRoute("GET", "/", pathOrHandler);
963
+ } else if (handler) {
964
+ this.registerRoute("GET", pathOrHandler, handler);
965
+ }
966
+ }
967
+ post(pathOrHandler, handler) {
968
+ if (typeof pathOrHandler === "function") {
969
+ this.registerRoute("POST", "/", pathOrHandler);
970
+ } else if (handler) {
971
+ this.registerRoute("POST", pathOrHandler, handler);
972
+ }
973
+ }
974
+ put(pathOrHandler, handler) {
975
+ if (typeof pathOrHandler === "function") {
976
+ this.registerRoute("PUT", "/", pathOrHandler);
977
+ } else if (handler) {
978
+ this.registerRoute("PUT", pathOrHandler, handler);
979
+ }
980
+ }
981
+ delete(pathOrHandler, handler) {
982
+ if (typeof pathOrHandler === "function") {
983
+ this.registerRoute("DELETE", "/", pathOrHandler);
984
+ } else if (handler) {
985
+ this.registerRoute("DELETE", pathOrHandler, handler);
986
+ }
987
+ }
988
+ patch(pathOrHandler, handler) {
989
+ if (typeof pathOrHandler === "function") {
990
+ this.registerRoute("PATCH", "/", pathOrHandler);
991
+ } else if (handler) {
992
+ this.registerRoute("PATCH", pathOrHandler, handler);
993
+ }
994
+ }
995
+ options(pathOrHandler, handler) {
996
+ if (typeof pathOrHandler === "function") {
997
+ this.registerRoute("OPTIONS", "/", pathOrHandler);
998
+ } else if (handler) {
999
+ this.registerRoute("OPTIONS", pathOrHandler, handler);
1000
+ }
1001
+ }
1002
+ head(pathOrHandler, handler) {
1003
+ if (typeof pathOrHandler === "function") {
1004
+ this.registerRoute("HEAD", "/", pathOrHandler);
1005
+ } else if (handler) {
1006
+ this.registerRoute("HEAD", pathOrHandler, handler);
1007
+ }
1008
+ }
1009
+ all(pathOrHandler, handler) {
1010
+ if (typeof pathOrHandler === "function") {
1011
+ this.registerRoute("ALL", "/", pathOrHandler);
1012
+ } else if (handler) {
1013
+ this.registerRoute("ALL", pathOrHandler, handler);
1014
+ }
1015
+ }
1016
+ use(pathOrHandler, handler) {
1017
+ if (typeof pathOrHandler === "function") {
1018
+ this.middlewares.push({
1019
+ path: "*",
1020
+ handler: pathOrHandler
1021
+ });
1022
+ } else if (handler) {
1023
+ this.middlewares.push({
1024
+ path: pathOrHandler,
1025
+ handler
1026
+ });
1027
+ }
1028
+ }
1029
+ useExpressMiddleware(pathOrMiddleware, middleware) {
1030
+ if (typeof pathOrMiddleware === "function") {
1031
+ const wrappedMiddleware = wrapExpressMiddleware(pathOrMiddleware);
1032
+ this.middlewares.push({
1033
+ path: "*",
1034
+ handler: wrappedMiddleware
1035
+ });
1036
+ } else if (middleware) {
1037
+ const wrappedMiddleware = wrapExpressMiddleware(middleware);
1038
+ this.middlewares.push({
1039
+ path: pathOrMiddleware,
1040
+ handler: wrappedMiddleware
1041
+ });
1042
+ }
1043
+ }
1044
+ /**
1045
+ * Create an Express-like app instance for middleware that requires app.use()
1046
+ *
1047
+ * Some Express middleware (like express-session) require an Express app instance.
1048
+ * This creates a compatible shim that routes middleware through the Deno adapter.
1049
+ *
1050
+ * @example
1051
+ * ```typescript
1052
+ * import session from 'express-session';
1053
+ *
1054
+ * const adapter = new DenoAdapter();
1055
+ * const expressApp = adapter.getExpressApp();
1056
+ *
1057
+ * expressApp.use(session({ secret: 'keyboard cat' }));
1058
+ * ```
1059
+ */
1060
+ getExpressApp() {
1061
+ const self = this;
1062
+ const settings = {};
1063
+ const app = {
1064
+ locals: {},
1065
+ settings,
1066
+ use(...args) {
1067
+ if (args.length === 1 && typeof args[0] === "function") {
1068
+ self.useExpressMiddleware(args[0]);
1069
+ } else if (args.length === 2 && typeof args[0] === "string" && typeof args[1] === "function") {
1070
+ self.useExpressMiddleware(args[0], args[1]);
1071
+ } else if (args.length >= 2) {
1072
+ const path = typeof args[0] === "string" ? args[0] : "*";
1073
+ const handlers = typeof args[0] === "string" ? args.slice(1) : args;
1074
+ handlers.forEach((handler) => {
1075
+ if (typeof handler === "function") {
1076
+ self.useExpressMiddleware(path, handler);
1077
+ }
1078
+ });
1079
+ }
1080
+ },
1081
+ get(path, ...handlers) {
1082
+ handlers.forEach((handler) => {
1083
+ self.get(path, async (req, res) => {
1084
+ const expressReq = createExpressRequest(req);
1085
+ const expressRes = createExpressResponse(res);
1086
+ await handler(expressReq, expressRes, () => {
1087
+ });
1088
+ });
1089
+ });
1090
+ },
1091
+ post(path, ...handlers) {
1092
+ handlers.forEach((handler) => {
1093
+ self.post(path, async (req, res) => {
1094
+ const expressReq = createExpressRequest(req);
1095
+ const expressRes = createExpressResponse(res);
1096
+ await handler(expressReq, expressRes, () => {
1097
+ });
1098
+ });
1099
+ });
1100
+ },
1101
+ put(path, ...handlers) {
1102
+ handlers.forEach((handler) => {
1103
+ self.put(path, async (req, res) => {
1104
+ const expressReq = createExpressRequest(req);
1105
+ const expressRes = createExpressResponse(res);
1106
+ await handler(expressReq, expressRes, () => {
1107
+ });
1108
+ });
1109
+ });
1110
+ },
1111
+ delete(path, ...handlers) {
1112
+ handlers.forEach((handler) => {
1113
+ self.delete(path, async (req, res) => {
1114
+ const expressReq = createExpressRequest(req);
1115
+ const expressRes = createExpressResponse(res);
1116
+ await handler(expressReq, expressRes, () => {
1117
+ });
1118
+ });
1119
+ });
1120
+ },
1121
+ patch(path, ...handlers) {
1122
+ handlers.forEach((handler) => {
1123
+ self.patch(path, async (req, res) => {
1124
+ const expressReq = createExpressRequest(req);
1125
+ const expressRes = createExpressResponse(res);
1126
+ await handler(expressReq, expressRes, () => {
1127
+ });
1128
+ });
1129
+ });
1130
+ },
1131
+ options(path, ...handlers) {
1132
+ handlers.forEach((handler) => {
1133
+ self.options(path, async (req, res) => {
1134
+ const expressReq = createExpressRequest(req);
1135
+ const expressRes = createExpressResponse(res);
1136
+ await handler(expressReq, expressRes, () => {
1137
+ });
1138
+ });
1139
+ });
1140
+ },
1141
+ head(path, ...handlers) {
1142
+ handlers.forEach((handler) => {
1143
+ self.head(path, async (req, res) => {
1144
+ const expressReq = createExpressRequest(req);
1145
+ const expressRes = createExpressResponse(res);
1146
+ await handler(expressReq, expressRes, () => {
1147
+ });
1148
+ });
1149
+ });
1150
+ },
1151
+ all(path, ...handlers) {
1152
+ handlers.forEach((handler) => {
1153
+ self.all(path, async (req, res) => {
1154
+ const expressReq = createExpressRequest(req);
1155
+ const expressRes = createExpressResponse(res);
1156
+ await handler(expressReq, expressRes, () => {
1157
+ });
1158
+ });
1159
+ });
1160
+ },
1161
+ set(key, value) {
1162
+ settings[key] = value;
1163
+ },
1164
+ enable(key) {
1165
+ settings[key] = true;
1166
+ },
1167
+ disable(key) {
1168
+ settings[key] = false;
1169
+ },
1170
+ enabled(key) {
1171
+ return Boolean(settings[key]);
1172
+ },
1173
+ disabled(key) {
1174
+ return !settings[key];
1175
+ }
1176
+ };
1177
+ return app;
1178
+ }
1179
+ /**
1180
+ * Use Fastify middleware/hooks with the Deno adapter
1181
+ *
1182
+ * This method wraps Fastify hooks to be compatible with the Deno adapter,
1183
+ * allowing you to use Fastify-style middleware.
1184
+ *
1185
+ * @example
1186
+ * ```typescript
1187
+ * const adapter = new DenoAdapter();
1188
+ *
1189
+ * // Use a Fastify hook
1190
+ * adapter.useFastifyHook('onRequest', async (request, reply) => {
1191
+ * console.log('Request received:', request.url);
1192
+ * });
1193
+ *
1194
+ * // Use with callback style
1195
+ * adapter.useFastifyHook('preHandler', (request, reply, done) => {
1196
+ * // Do something
1197
+ * done();
1198
+ * });
1199
+ * ```
1200
+ */
1201
+ useFastifyHook(_name, hook) {
1202
+ const wrappedHook = wrapFastifyHook(hook);
1203
+ this.middlewares.push({
1204
+ path: "*",
1205
+ handler: wrappedHook
1206
+ });
1207
+ }
1208
+ /**
1209
+ * Register a Fastify plugin with the Deno adapter
1210
+ *
1211
+ * This allows using Fastify plugins that add hooks, decorators, or routes.
1212
+ *
1213
+ * @example
1214
+ * ```typescript
1215
+ * import fastifyCors from '@fastify/cors';
1216
+ * import fastifyHelmet from '@fastify/helmet';
1217
+ *
1218
+ * const adapter = new DenoAdapter();
1219
+ * const fastify = adapter.getFastifyInstance();
1220
+ *
1221
+ * // Register plugins
1222
+ * await adapter.registerFastifyPlugin(fastifyCors, { origin: '*' });
1223
+ * await adapter.registerFastifyPlugin(fastifyHelmet);
1224
+ * ```
1225
+ */
1226
+ async registerFastifyPlugin(plugin, opts) {
1227
+ const instance = this.getFastifyInstance();
1228
+ await wrapFastifyPlugin(plugin, instance, opts);
1229
+ }
1230
+ /**
1231
+ * Get a Fastify-like instance for plugins that require it
1232
+ *
1233
+ * This creates a Fastify-compatible interface that routes hooks and routes
1234
+ * through the Deno adapter.
1235
+ *
1236
+ * @example
1237
+ * ```typescript
1238
+ * const adapter = new DenoAdapter();
1239
+ * const fastify = adapter.getFastifyInstance();
1240
+ *
1241
+ * // Add hooks
1242
+ * fastify.addHook('onRequest', async (request, reply) => {
1243
+ * console.log('Request:', request.method, request.url);
1244
+ * });
1245
+ *
1246
+ * // Add decorators
1247
+ * fastify.decorateRequest('user', null);
1248
+ * ```
1249
+ */
1250
+ getFastifyInstance() {
1251
+ const self = this;
1252
+ const decorators = {};
1253
+ const requestDecorators = {};
1254
+ const replyDecorators = {};
1255
+ const instance = {
1256
+ log: createFastifyLogger(),
1257
+ prefix: "",
1258
+ // Decorators
1259
+ decorate(name, value) {
1260
+ decorators[name] = value;
1261
+ return this;
1262
+ },
1263
+ decorateRequest(name, value) {
1264
+ requestDecorators[name] = value;
1265
+ return this;
1266
+ },
1267
+ decorateReply(name, value) {
1268
+ replyDecorators[name] = value;
1269
+ return this;
1270
+ },
1271
+ hasDecorator(name) {
1272
+ return name in decorators;
1273
+ },
1274
+ hasRequestDecorator(name) {
1275
+ return name in requestDecorators;
1276
+ },
1277
+ hasReplyDecorator(name) {
1278
+ return name in replyDecorators;
1279
+ },
1280
+ // Hooks
1281
+ addHook(name, hook) {
1282
+ if (["onRequest", "preParsing", "preValidation", "preHandler", "onResponse"].includes(name)) {
1283
+ self.useFastifyHook(name, hook);
1284
+ }
1285
+ return this;
1286
+ },
1287
+ // Plugin registration
1288
+ register(plugin, opts) {
1289
+ wrapFastifyPlugin(plugin, this, opts).catch(console.error);
1290
+ return this;
1291
+ },
1292
+ // Routes
1293
+ route(opts) {
1294
+ const methods = Array.isArray(opts.method) ? opts.method : [opts.method];
1295
+ methods.forEach((method) => {
1296
+ const handler = async (req, res) => {
1297
+ const fastifyReq = createFastifyRequest(req);
1298
+ const fastifyReply = createFastifyReply(res);
1299
+ Object.entries(requestDecorators).forEach(([key, value]) => {
1300
+ fastifyReq[key] = typeof value === "function" ? value() : value;
1301
+ });
1302
+ Object.entries(replyDecorators).forEach(([key, value]) => {
1303
+ fastifyReply[key] = typeof value === "function" ? value() : value;
1304
+ });
1305
+ const hooks = [
1306
+ ...opts.onRequest ? Array.isArray(opts.onRequest) ? opts.onRequest : [opts.onRequest] : [],
1307
+ ...opts.preValidation ? Array.isArray(opts.preValidation) ? opts.preValidation : [opts.preValidation] : [],
1308
+ ...opts.preHandler ? Array.isArray(opts.preHandler) ? opts.preHandler : [opts.preHandler] : []
1309
+ ];
1310
+ for (const hook of hooks) {
1311
+ if (fastifyReply.sent) break;
1312
+ await new Promise((resolve, reject) => {
1313
+ if (hook.length <= 2) {
1314
+ hook(fastifyReq, fastifyReply).then(resolve).catch(reject);
1315
+ } else {
1316
+ hook(
1317
+ fastifyReq,
1318
+ fastifyReply,
1319
+ (err) => err ? reject(err) : resolve()
1320
+ );
1321
+ }
1322
+ });
1323
+ }
1324
+ if (!fastifyReply.sent) {
1325
+ const result = await opts.handler(fastifyReq, fastifyReply);
1326
+ if (result !== void 0 && !fastifyReply.sent) {
1327
+ fastifyReply.send(result);
1328
+ }
1329
+ }
1330
+ };
1331
+ switch (method.toUpperCase()) {
1332
+ case "GET":
1333
+ self.get(opts.url, handler);
1334
+ break;
1335
+ case "POST":
1336
+ self.post(opts.url, handler);
1337
+ break;
1338
+ case "PUT":
1339
+ self.put(opts.url, handler);
1340
+ break;
1341
+ case "DELETE":
1342
+ self.delete(opts.url, handler);
1343
+ break;
1344
+ case "PATCH":
1345
+ self.patch(opts.url, handler);
1346
+ break;
1347
+ case "OPTIONS":
1348
+ self.options(opts.url, handler);
1349
+ break;
1350
+ case "HEAD":
1351
+ self.head(opts.url, handler);
1352
+ break;
1353
+ default:
1354
+ self.all(opts.url, handler);
1355
+ }
1356
+ });
1357
+ return this;
1358
+ },
1359
+ // HTTP method shortcuts
1360
+ get(path, optsOrHandler, handler) {
1361
+ const h = typeof optsOrHandler === "function" ? optsOrHandler : handler;
1362
+ const opts = typeof optsOrHandler === "object" ? optsOrHandler : {};
1363
+ return this.route({ ...opts, method: "GET", url: path, handler: h });
1364
+ },
1365
+ post(path, optsOrHandler, handler) {
1366
+ const h = typeof optsOrHandler === "function" ? optsOrHandler : handler;
1367
+ const opts = typeof optsOrHandler === "object" ? optsOrHandler : {};
1368
+ return this.route({ ...opts, method: "POST", url: path, handler: h });
1369
+ },
1370
+ put(path, optsOrHandler, handler) {
1371
+ const h = typeof optsOrHandler === "function" ? optsOrHandler : handler;
1372
+ const opts = typeof optsOrHandler === "object" ? optsOrHandler : {};
1373
+ return this.route({ ...opts, method: "PUT", url: path, handler: h });
1374
+ },
1375
+ delete(path, optsOrHandler, handler) {
1376
+ const h = typeof optsOrHandler === "function" ? optsOrHandler : handler;
1377
+ const opts = typeof optsOrHandler === "object" ? optsOrHandler : {};
1378
+ return this.route({ ...opts, method: "DELETE", url: path, handler: h });
1379
+ },
1380
+ patch(path, optsOrHandler, handler) {
1381
+ const h = typeof optsOrHandler === "function" ? optsOrHandler : handler;
1382
+ const opts = typeof optsOrHandler === "object" ? optsOrHandler : {};
1383
+ return this.route({ ...opts, method: "PATCH", url: path, handler: h });
1384
+ },
1385
+ options(path, optsOrHandler, handler) {
1386
+ const h = typeof optsOrHandler === "function" ? optsOrHandler : handler;
1387
+ const opts = typeof optsOrHandler === "object" ? optsOrHandler : {};
1388
+ return this.route({ ...opts, method: "OPTIONS", url: path, handler: h });
1389
+ },
1390
+ head(path, optsOrHandler, handler) {
1391
+ const h = typeof optsOrHandler === "function" ? optsOrHandler : handler;
1392
+ const opts = typeof optsOrHandler === "object" ? optsOrHandler : {};
1393
+ return this.route({ ...opts, method: "HEAD", url: path, handler: h });
1394
+ },
1395
+ all(path, optsOrHandler, handler) {
1396
+ const h = typeof optsOrHandler === "function" ? optsOrHandler : handler;
1397
+ const opts = typeof optsOrHandler === "object" ? optsOrHandler : {};
1398
+ return this.route({ ...opts, method: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"], url: path, handler: h });
1399
+ }
1400
+ };
1401
+ return instance;
1402
+ }
1403
+ /**
1404
+ * Get the underlying HTTP server
1405
+ */
1406
+ getHttpServer() {
1407
+ return this.server;
1408
+ }
1409
+ /**
1410
+ * Set the HTTP server instance
1411
+ */
1412
+ setHttpServer(server) {
1413
+ this.server = server;
1414
+ }
1415
+ /**
1416
+ * Close the server
1417
+ */
1418
+ async close() {
1419
+ if (this.abortController) {
1420
+ this.abortController.abort();
1421
+ await this.server?.finished;
1422
+ }
1423
+ }
1424
+ /**
1425
+ * Set error handler
1426
+ */
1427
+ setErrorHandler(handler) {
1428
+ this.errorHandler = handler;
1429
+ }
1430
+ /**
1431
+ * Set 404 handler
1432
+ */
1433
+ setNotFoundHandler(handler) {
1434
+ this.notFoundHandler = handler;
1435
+ }
1436
+ /**
1437
+ * Enable CORS
1438
+ */
1439
+ enableCors(options) {
1440
+ this.corsOptions = options || {
1441
+ origin: "*",
1442
+ methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
1443
+ credentials: false
1444
+ };
1445
+ }
1446
+ /**
1447
+ * Handle CORS preflight requests
1448
+ */
1449
+ handleCors(req, res) {
1450
+ this.applyCorsHeaders(req, res);
1451
+ res.status(this.corsOptions?.optionsSuccessStatus || 204).end();
1452
+ }
1453
+ /**
1454
+ * Apply CORS headers to response
1455
+ */
1456
+ applyCorsHeaders(req, res) {
1457
+ if (!this.corsOptions) return;
1458
+ const origin = req.headers.get("origin") || "*";
1459
+ let allowOrigin = "*";
1460
+ if (typeof this.corsOptions.origin === "string") {
1461
+ allowOrigin = this.corsOptions.origin;
1462
+ } else if (typeof this.corsOptions.origin === "boolean") {
1463
+ allowOrigin = this.corsOptions.origin ? origin : "";
1464
+ } else if (Array.isArray(this.corsOptions.origin)) {
1465
+ allowOrigin = this.corsOptions.origin.includes(origin) ? origin : "";
1466
+ } else if (typeof this.corsOptions.origin === "function") {
1467
+ const result = this.corsOptions.origin(origin);
1468
+ allowOrigin = typeof result === "string" ? result : result ? origin : "";
1469
+ }
1470
+ res.setHeader("Access-Control-Allow-Origin", allowOrigin);
1471
+ if (this.corsOptions.credentials) {
1472
+ res.setHeader("Access-Control-Allow-Credentials", "true");
1473
+ }
1474
+ const methods = Array.isArray(this.corsOptions.methods) ? this.corsOptions.methods.join(",") : this.corsOptions.methods || "GET,HEAD,PUT,PATCH,POST,DELETE";
1475
+ res.setHeader("Access-Control-Allow-Methods", methods);
1476
+ if (this.corsOptions.allowedHeaders) {
1477
+ const headers = Array.isArray(this.corsOptions.allowedHeaders) ? this.corsOptions.allowedHeaders.join(",") : this.corsOptions.allowedHeaders;
1478
+ res.setHeader("Access-Control-Allow-Headers", headers);
1479
+ } else {
1480
+ const requestHeaders = req.headers.get("access-control-request-headers");
1481
+ if (requestHeaders) {
1482
+ res.setHeader("Access-Control-Allow-Headers", requestHeaders);
1483
+ }
1484
+ }
1485
+ if (this.corsOptions.exposedHeaders) {
1486
+ const exposed = Array.isArray(this.corsOptions.exposedHeaders) ? this.corsOptions.exposedHeaders.join(",") : this.corsOptions.exposedHeaders;
1487
+ res.setHeader("Access-Control-Expose-Headers", exposed);
1488
+ }
1489
+ if (this.corsOptions.maxAge) {
1490
+ res.setHeader("Access-Control-Max-Age", String(this.corsOptions.maxAge));
1491
+ }
1492
+ }
1493
+ /**
1494
+ * Use static assets
1495
+ */
1496
+ useStaticAssets(path, options) {
1497
+ this.staticAssetsPath = path;
1498
+ this.staticAssetsOptions = options;
1499
+ }
1500
+ /**
1501
+ * Serve static asset
1502
+ */
1503
+ async serveStaticAsset(urlPath) {
1504
+ if (!this.staticAssetsPath) return null;
1505
+ const prefix = this.staticAssetsOptions?.prefix || "/";
1506
+ const relativePath = urlPath.replace(prefix, "").replace(/^\//, "");
1507
+ const filePath = `${this.staticAssetsPath}/${relativePath}`;
1508
+ try {
1509
+ const file = await Deno.open(filePath, { read: true });
1510
+ const stat = await file.stat();
1511
+ if (stat.isDirectory) {
1512
+ file.close();
1513
+ if (this.staticAssetsOptions?.index !== false) {
1514
+ const indexFile = typeof this.staticAssetsOptions?.index === "string" ? this.staticAssetsOptions.index : "index.html";
1515
+ return this.serveStaticAsset(`${urlPath}/${indexFile}`);
1516
+ }
1517
+ return null;
1518
+ }
1519
+ const headers = new Headers();
1520
+ const ext = filePath.split(".").pop()?.toLowerCase();
1521
+ const mimeTypes = {
1522
+ html: "text/html",
1523
+ css: "text/css",
1524
+ js: "application/javascript",
1525
+ json: "application/json",
1526
+ png: "image/png",
1527
+ jpg: "image/jpeg",
1528
+ jpeg: "image/jpeg",
1529
+ gif: "image/gif",
1530
+ svg: "image/svg+xml",
1531
+ ico: "image/x-icon",
1532
+ woff: "font/woff",
1533
+ woff2: "font/woff2",
1534
+ ttf: "font/ttf",
1535
+ eot: "application/vnd.ms-fontobject",
1536
+ txt: "text/plain",
1537
+ xml: "application/xml",
1538
+ pdf: "application/pdf",
1539
+ mp4: "video/mp4",
1540
+ webm: "video/webm",
1541
+ mp3: "audio/mpeg",
1542
+ wav: "audio/wav"
1543
+ };
1544
+ headers.set("Content-Type", mimeTypes[ext || ""] || "application/octet-stream");
1545
+ if (this.staticAssetsOptions?.etag !== false) {
1546
+ headers.set("ETag", `"${stat.size}-${stat.mtime?.getTime() || 0}"`);
1547
+ }
1548
+ if (this.staticAssetsOptions?.lastModified !== false && stat.mtime) {
1549
+ headers.set("Last-Modified", stat.mtime.toUTCString());
1550
+ }
1551
+ if (this.staticAssetsOptions?.maxAge) {
1552
+ let cacheControl = `max-age=${this.staticAssetsOptions.maxAge}`;
1553
+ if (this.staticAssetsOptions.immutable) {
1554
+ cacheControl += ", immutable";
1555
+ }
1556
+ headers.set("Cache-Control", cacheControl);
1557
+ }
1558
+ return new Response(file.readable, {
1559
+ status: 200,
1560
+ headers
1561
+ });
1562
+ } catch (error) {
1563
+ if (error.name === "NotFound") {
1564
+ return null;
1565
+ }
1566
+ throw error;
1567
+ }
1568
+ }
1569
+ /**
1570
+ * Set view engine (not implemented for base adapter)
1571
+ */
1572
+ setViewEngine(_engine) {
1573
+ console.warn("View engine is not supported in the base Deno adapter");
1574
+ }
1575
+ /**
1576
+ * Render view (not implemented for base adapter)
1577
+ */
1578
+ render(_response, _view, _options) {
1579
+ console.warn("Render is not supported in the base Deno adapter");
1580
+ }
1581
+ /**
1582
+ * Get request hostname
1583
+ */
1584
+ getRequestHostname(request) {
1585
+ return request.hostname || request.headers.get("host") || "";
1586
+ }
1587
+ /**
1588
+ * Get request method
1589
+ */
1590
+ getRequestMethod(request) {
1591
+ return request.method;
1592
+ }
1593
+ /**
1594
+ * Get request URL
1595
+ */
1596
+ getRequestUrl(request) {
1597
+ return request.path || new URL(request.url).pathname;
1598
+ }
1599
+ /**
1600
+ * Send a reply
1601
+ */
1602
+ reply(response, body, statusCode) {
1603
+ if (statusCode) {
1604
+ response.status(statusCode);
1605
+ }
1606
+ if (body === void 0 || body === null) {
1607
+ response.end();
1608
+ } else if (typeof body === "object") {
1609
+ response.json(body);
1610
+ } else {
1611
+ response.send(String(body));
1612
+ }
1613
+ }
1614
+ /**
1615
+ * Set response status
1616
+ */
1617
+ status(response, statusCode) {
1618
+ response.status(statusCode);
1619
+ }
1620
+ /**
1621
+ * Redirect response
1622
+ */
1623
+ redirect(response, statusCode, url) {
1624
+ response.redirect(url, statusCode);
1625
+ }
1626
+ /**
1627
+ * Set response header
1628
+ */
1629
+ setHeader(response, name, value) {
1630
+ response.setHeader(name, value);
1631
+ }
1632
+ /**
1633
+ * Get response header
1634
+ */
1635
+ getHeader(response, name) {
1636
+ return response.getHeader(name);
1637
+ }
1638
+ /**
1639
+ * Append value to header
1640
+ */
1641
+ appendHeader(response, name, value) {
1642
+ const existing = response.getHeader(name);
1643
+ if (existing) {
1644
+ response.setHeader(name, `${existing}, ${value}`);
1645
+ } else {
1646
+ response.setHeader(name, value);
1647
+ }
1648
+ }
1649
+ /**
1650
+ * End response
1651
+ */
1652
+ end(response, message) {
1653
+ response.end(message);
1654
+ }
1655
+ /**
1656
+ * Check if headers have been sent
1657
+ */
1658
+ isHeadersSent(response) {
1659
+ return response.headersSent;
1660
+ }
1661
+ /**
1662
+ * Register body parser middleware
1663
+ */
1664
+ registerParserMiddleware() {
1665
+ }
1666
+ /**
1667
+ * Create middleware factory
1668
+ */
1669
+ createMiddlewareFactory(_requestMethod) {
1670
+ return (path, callback) => {
1671
+ this.use(path, async (req, res, next) => {
1672
+ await callback(req, res, next);
1673
+ });
1674
+ };
1675
+ }
1676
+ /**
1677
+ * Initialize the adapter
1678
+ */
1679
+ initHttpServer() {
1680
+ }
1681
+ /**
1682
+ * Get the adapter type
1683
+ */
1684
+ getType() {
1685
+ return "deno";
1686
+ }
1687
+ /**
1688
+ * Apply version filter
1689
+ */
1690
+ applyVersionFilter(handler, _version, _versioningOptions) {
1691
+ return (_req, _res, _next) => {
1692
+ return handler;
1693
+ };
1694
+ }
1695
+ };
1696
+ // Annotate the CommonJS export names for ESM import in node:
1697
+ 0 && (module.exports = {
1698
+ DenoAdapter,
1699
+ createExpressRequest,
1700
+ createExpressResponse,
1701
+ createFastifyLogger,
1702
+ createFastifyReply,
1703
+ createFastifyRequest,
1704
+ wrapExpressMiddleware,
1705
+ wrapFastifyHook,
1706
+ wrapFastifyPlugin
1707
+ });
1708
+ //# sourceMappingURL=index.cjs.map