@krisanalfa/bunest-adapter 0.3.0 → 0.4.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.js CHANGED
@@ -15,12 +15,50 @@ var __legacyMetadataTS = (k, v) => {
15
15
  };
16
16
 
17
17
  // lib/bun.adapter.ts
18
- var {randomUUIDv7 } = globalThis.Bun;
19
18
  import {
20
- Logger
19
+ Logger as Logger2
21
20
  } from "@nestjs/common";
21
+ var {randomUUIDv7 } = globalThis.Bun;
22
22
  import { AbstractHttpAdapter } from "@nestjs/core";
23
23
 
24
+ // lib/bun.preflight-http-server.ts
25
+ class BunPreflightHttpServer {
26
+ serverInstance;
27
+ constructor(serverInstance) {
28
+ this.serverInstance = serverInstance;
29
+ }
30
+ on(event, callback) {}
31
+ once() {}
32
+ removeListener() {}
33
+ async stop(force) {
34
+ await this.serverInstance.stop(force);
35
+ }
36
+ address() {
37
+ return this.serverInstance.address();
38
+ }
39
+ setWsOptions(options) {
40
+ this.serverInstance.setWsOptions(options);
41
+ }
42
+ registerWsOpenHandler(handler) {
43
+ this.serverInstance.registerWsOpenHandler(handler);
44
+ }
45
+ registerWsMessageHandler(handler) {
46
+ this.serverInstance.registerWsMessageHandler(handler);
47
+ }
48
+ registerWsCloseHandler(handler) {
49
+ this.serverInstance.registerWsCloseHandler(handler);
50
+ }
51
+ getBunServer() {
52
+ return this.serverInstance.getBunServer();
53
+ }
54
+ async close() {
55
+ await this.serverInstance.close();
56
+ }
57
+ }
58
+
59
+ // lib/bun.server-instance.ts
60
+ import { Logger } from "@nestjs/common";
61
+
24
62
  // lib/bun.body-parser.middleware.ts
25
63
  var GET_CODE = 71;
26
64
  var HEAD_CODE = 72;
@@ -179,6 +217,7 @@ class BunCorsMiddleware {
179
217
  }
180
218
 
181
219
  // lib/bun.middleware-engine.ts
220
+ var {peek } = globalThis.Bun;
182
221
  var EMPTY_HANDLERS = new Array(0);
183
222
  var noop = () => {};
184
223
 
@@ -258,6 +297,17 @@ class BunMiddlewareEngine {
258
297
  const keyPathLen = keyPath.length;
259
298
  return path === keyPath || pathLen > keyPathLen && path.charCodeAt(keyPathLen) === 47 && path.startsWith(keyPath);
260
299
  }
300
+ async executeHandler(handler, req, res, next) {
301
+ if (!handler)
302
+ return;
303
+ const result = handler(req, res, next);
304
+ if (result instanceof Promise) {
305
+ const peeked = peek(result);
306
+ if (peeked !== result)
307
+ return;
308
+ await result;
309
+ }
310
+ }
261
311
  async run(options) {
262
312
  try {
263
313
  const middlewares = this.getMiddlewareChain(options.method, options.path);
@@ -333,25 +383,18 @@ class BunMiddlewareEngine {
333
383
  if (err)
334
384
  throw err;
335
385
  if (index < chainLength) {
336
- const handler = chain[index++];
337
- const result = handler(req, res, next);
338
- if (result instanceof Promise)
339
- await result;
386
+ await this.executeHandler(chain[index++], req, res, next);
340
387
  return;
341
388
  }
342
389
  if (index === chainLength) {
343
390
  index++;
344
391
  if (!res.isEnded()) {
345
- const result = requestHandler(req, res, next);
346
- if (result instanceof Promise)
347
- await result;
392
+ await this.executeHandler(requestHandler, req, res, next);
348
393
  }
349
394
  return;
350
395
  }
351
- if (index > chainLength && !res.isEnded()) {
352
- const result = this.notFoundHandler?.(req, res, noop);
353
- if (result instanceof Promise)
354
- await result;
396
+ if (!res.isEnded()) {
397
+ await this.executeHandler(this.notFoundHandler ?? undefined, req, res, () => Promise.resolve());
355
398
  }
356
399
  };
357
400
  await next();
@@ -359,67 +402,17 @@ class BunMiddlewareEngine {
359
402
  async handleError(error, req, res) {
360
403
  if (this.errorHandler !== null) {
361
404
  const result = this.errorHandler(error, req, res, noop);
362
- if (result instanceof Promise)
363
- await result;
405
+ if (result instanceof Promise) {
406
+ const peeked = peek(result);
407
+ if (peeked === result)
408
+ await result;
409
+ }
364
410
  return res;
365
411
  }
366
412
  throw error;
367
413
  }
368
414
  }
369
415
 
370
- // lib/bun.preflight-http-server.ts
371
- class BunPreflightHttpServer {
372
- adapter;
373
- constructor(adapter) {
374
- this.adapter = adapter;
375
- }
376
- on(event, callback) {}
377
- once() {}
378
- removeListener() {}
379
- async stop(force) {
380
- const server = this.adapter.getBunHttpServerInstance();
381
- if (server instanceof BunPreflightHttpServer) {
382
- return;
383
- }
384
- await server.stop(force);
385
- }
386
- address() {
387
- const server = this.adapter.getBunHttpServerInstance();
388
- if (server instanceof BunPreflightHttpServer) {
389
- const options = this.adapter.getBunServerOptions();
390
- return {
391
- address: options.hostname ?? "127.0.0.1",
392
- port: options.port ?? 3000
393
- };
394
- }
395
- return {
396
- address: server.hostname,
397
- port: server.port
398
- };
399
- }
400
- setWsOptions(options) {
401
- this.adapter.setWsOptions(options);
402
- }
403
- registerWsOpenHandler(handler) {
404
- this.adapter.getWsHandlers().onOpen = handler;
405
- }
406
- registerWsMessageHandler(handler) {
407
- this.adapter.getWsHandlers().onMessage = handler;
408
- }
409
- registerWsCloseHandler(handler) {
410
- this.adapter.getWsHandlers().onClose = handler;
411
- }
412
- getWsHandlers() {
413
- return this.adapter.getWsHandlers();
414
- }
415
- getBunServer() {
416
- return this.adapter.getBunHttpServerInstance();
417
- }
418
- async close() {
419
- await this.stop(true);
420
- }
421
- }
422
-
423
416
  // lib/bun.request.ts
424
417
  import { parse } from "qs";
425
418
  var NULL_PROTO = Object.getPrototypeOf(Object.create(null));
@@ -450,7 +443,10 @@ class BunRequest {
450
443
  }
451
444
  get socket() {
452
445
  return {
453
- encrypted: this._parsedUrl.protocol === "https:"
446
+ encrypted: this._parsedUrl.protocol === "https:",
447
+ setKeepAlive: () => {},
448
+ setNoDelay: () => {},
449
+ setTimeout: () => {}
454
450
  };
455
451
  }
456
452
  get url() {
@@ -545,6 +541,18 @@ class BunRequest {
545
541
  cloned._settings = this._settings;
546
542
  return cloned;
547
543
  }
544
+ on(event, listener) {
545
+ return this;
546
+ }
547
+ once(event, listener) {
548
+ return this;
549
+ }
550
+ off(event, listener) {
551
+ return this;
552
+ }
553
+ emit(event, ...args) {
554
+ return true;
555
+ }
548
556
  }
549
557
 
550
558
  // lib/bun.response.ts
@@ -557,11 +565,14 @@ class BunResponse {
557
565
  response;
558
566
  cookieMap = new CookieMap;
559
567
  static textDecoder = new TextDecoder;
568
+ writable = true;
560
569
  headers = null;
561
570
  statusCode = 200;
562
571
  ended = false;
563
572
  cookieHeaders = null;
564
573
  chunks = [];
574
+ streamWriter = null;
575
+ textEncoder = new TextEncoder;
565
576
  constructor() {
566
577
  this.response = new Promise((r) => {
567
578
  this.resolve = r;
@@ -595,6 +606,16 @@ class BunResponse {
595
606
  if (this.ended)
596
607
  return;
597
608
  this.ended = true;
609
+ if (this.streamWriter) {
610
+ try {
611
+ if (body) {
612
+ const bytes = typeof body === "string" ? this.textEncoder.encode(body) : body instanceof Uint8Array ? body : this.textEncoder.encode(JSON.stringify(body));
613
+ this.streamWriter.write(bytes);
614
+ }
615
+ this.streamWriter.close();
616
+ } catch {}
617
+ return;
618
+ }
598
619
  this.applyCookieHeaders();
599
620
  if (this.chunks.length > 0) {
600
621
  const finalBody = this.combineChunks(body);
@@ -604,14 +625,19 @@ class BunResponse {
604
625
  this.sendResponse(body);
605
626
  }
606
627
  applyCookieHeaders() {
628
+ if (this.cookieMap.size === 0)
629
+ return;
607
630
  this.cookieHeaders ??= this.cookieMap.toSetCookieHeaders();
608
- if (this.cookieHeaders.length > 0) {
609
- this.setHeader("set-cookie", this.cookieHeaders.join(`
631
+ this.setHeader("set-cookie", this.cookieHeaders.join(`
610
632
  `));
611
- }
612
633
  }
613
634
  sendResponse(body) {
614
635
  if (body !== null && typeof body === "object") {
636
+ const ctor = body.constructor;
637
+ if (ctor === Object || ctor === Array) {
638
+ this.resolve(this.buildJsonResponse(body));
639
+ return;
640
+ }
615
641
  if (body instanceof Uint8Array || body instanceof Blob) {
616
642
  this.resolve(this.createResponse(body));
617
643
  return;
@@ -695,10 +721,30 @@ class BunResponse {
695
721
  once(event, listener) {
696
722
  return this;
697
723
  }
724
+ emit(event, ...args) {
725
+ return true;
726
+ }
727
+ get writableEnded() {
728
+ return this.ended;
729
+ }
698
730
  write(chunk) {
699
731
  if (this.ended) {
700
732
  return false;
701
733
  }
734
+ const contentType = this.headers?.get("content-type") ?? "";
735
+ const isStreamingResponse = contentType.includes("text/event-stream") || contentType.includes("application/octet-stream");
736
+ if (isStreamingResponse && !this.streamWriter) {
737
+ this.initializeStreamingMode();
738
+ }
739
+ if (this.streamWriter) {
740
+ try {
741
+ const bytes = typeof chunk === "string" ? this.textEncoder.encode(chunk) : chunk instanceof Uint8Array ? chunk : chunk instanceof Buffer ? new Uint8Array(chunk) : this.textEncoder.encode(JSON.stringify(chunk));
742
+ this.streamWriter.write(bytes);
743
+ return true;
744
+ } catch {
745
+ return false;
746
+ }
747
+ }
702
748
  if (typeof chunk === "string") {
703
749
  this.chunks.push(chunk);
704
750
  return true;
@@ -721,6 +767,12 @@ class BunResponse {
721
767
  }
722
768
  return true;
723
769
  }
770
+ initializeStreamingMode() {
771
+ const { readable, writable } = new TransformStream;
772
+ this.streamWriter = writable.getWriter();
773
+ this.applyCookieHeaders();
774
+ this.resolve(this.createResponse(readable));
775
+ }
724
776
  getHeader(name) {
725
777
  return this.headers?.get(name.toLowerCase()) ?? null;
726
778
  }
@@ -764,9 +816,7 @@ class BunResponse {
764
816
  if (headers === null || headers.size === 0) {
765
817
  return Response.json(body, { status: this.statusCode });
766
818
  }
767
- if (!headers.has("content-type")) {
768
- headers.set("content-type", JSON_CONTENT_TYPE);
769
- }
819
+ headers.set("content-type", JSON_CONTENT_TYPE);
770
820
  return Response.json(body, {
771
821
  status: this.statusCode,
772
822
  headers: Object.fromEntries(headers)
@@ -786,13 +836,9 @@ class BunResponse {
786
836
 
787
837
  // lib/bun.version-filter.middleware.ts
788
838
  import { VERSION_NEUTRAL, VersioningType } from "@nestjs/common";
789
- async function executeHandler(handler, req, res, next) {
790
- const result = handler(req, res, next);
791
- return result instanceof Promise ? await result : result;
792
- }
793
- function callNext(next) {
794
- return next();
795
- }
839
+ var CUSTOM_VERSIONING_PHASE_KEY = "_cvp";
840
+ var CUSTOM_VERSIONING_CANDIDATES_KEY = "_cvc";
841
+ var CUSTOM_VERSIONING_BEST_CANDIDATE_KEY = "_cvb";
796
842
 
797
843
  class BunVersionFilterMiddleware {
798
844
  static createFilter(handler, version, versioningOptions) {
@@ -820,24 +866,26 @@ class BunVersionFilterMiddleware {
820
866
  static computeAcceptsNeutral(version) {
821
867
  return version === VERSION_NEUTRAL || Array.isArray(version) && version.includes(VERSION_NEUTRAL);
822
868
  }
823
- static getHeader(req, name) {
824
- return req.headers.get(name) ?? undefined;
825
- }
826
869
  static createCustomVersionFilter(handler, version, options) {
827
870
  const isVersionArray = Array.isArray(version);
828
871
  const versionSet = isVersionArray ? new Set(version) : null;
829
872
  const singleVersion = isVersionArray ? null : version;
830
- return async (req, res, next) => {
873
+ return (req, res, next) => {
831
874
  const extracted = options.extractor(req);
832
- const reqMeta = req;
833
- reqMeta._customVersioningPhase ??= "discovery";
834
- reqMeta._customVersioningCandidates ??= new Map;
835
- const isDiscovery = reqMeta._customVersioningPhase === "discovery";
836
- const extractedIsArray = Array.isArray(extracted);
837
- const extractedVersions = extractedIsArray ? extracted : [extracted];
875
+ let phase = req.get(CUSTOM_VERSIONING_PHASE_KEY);
876
+ if (phase === undefined) {
877
+ phase = 0;
878
+ req.set(CUSTOM_VERSIONING_PHASE_KEY, phase);
879
+ }
880
+ let candidates = req.get(CUSTOM_VERSIONING_CANDIDATES_KEY);
881
+ if (!candidates) {
882
+ candidates = new Map;
883
+ req.set(CUSTOM_VERSIONING_CANDIDATES_KEY, candidates);
884
+ }
885
+ const extractedVersions = Array.isArray(extracted) ? extracted : [extracted];
838
886
  let match;
839
887
  let matchIndex = -1;
840
- for (let i = 0;i < extractedVersions.length; i++) {
888
+ for (let i = 0, len = extractedVersions.length;i < len; i++) {
841
889
  const extractedVersion = extractedVersions[i];
842
890
  if (versionSet ? versionSet.has(extractedVersion) : extractedVersion === singleVersion) {
843
891
  match = extractedVersion;
@@ -846,44 +894,44 @@ class BunVersionFilterMiddleware {
846
894
  }
847
895
  }
848
896
  if (match) {
849
- if (isDiscovery) {
850
- reqMeta._customVersioningCandidates.set(match, {
851
- priority: matchIndex,
852
- execute: () => handler(req, res, next)
853
- });
854
- return callNext(next);
897
+ if (phase === 0) {
898
+ candidates.set(match, matchIndex);
899
+ next();
900
+ return;
855
901
  }
856
- if (reqMeta._customVersioningBestCandidate === match) {
857
- return executeHandler(handler, req, res, next);
902
+ if (req.get(CUSTOM_VERSIONING_BEST_CANDIDATE_KEY) === match) {
903
+ return handler(req, res, next);
858
904
  }
859
905
  }
860
- return callNext(next);
906
+ next();
861
907
  };
862
908
  }
863
909
  static createMediaTypeVersionFilter(handler, version, options) {
864
910
  const acceptsNeutral = this.computeAcceptsNeutral(version);
865
911
  const versionMatches = this.createVersionMatcher(version);
866
- const keyLength = options.key.length;
867
- return async (req, res, next) => {
868
- const acceptHeader = this.getHeader(req, "accept");
912
+ const key = options.key;
913
+ const keyLength = key.length;
914
+ return (req, res, next) => {
915
+ const acceptHeader = req.headers.get("accept");
869
916
  if (acceptHeader) {
870
917
  const semiIndex = acceptHeader.indexOf(";");
871
918
  if (semiIndex !== -1) {
872
919
  const versionPart = acceptHeader.substring(semiIndex + 1).trim();
873
- const keyIndex = versionPart.indexOf(options.key);
920
+ const keyIndex = versionPart.indexOf(key);
874
921
  if (keyIndex !== -1) {
875
922
  const headerVersion = versionPart.substring(keyIndex + keyLength);
876
923
  if (versionMatches(headerVersion)) {
877
- return executeHandler(handler, req, res, next);
924
+ return handler(req, res, next);
878
925
  }
879
- return callNext(next);
926
+ next();
927
+ return;
880
928
  }
881
929
  }
882
930
  }
883
931
  if (acceptsNeutral) {
884
- return executeHandler(handler, req, res, next);
932
+ return handler(req, res, next);
885
933
  }
886
- return callNext(next);
934
+ next();
887
935
  };
888
936
  }
889
937
  static createHeaderVersionFilter(handler, version, options) {
@@ -893,21 +941,25 @@ class BunVersionFilterMiddleware {
893
941
  const hasNeutralDefault = defaultVersion === VERSION_NEUTRAL;
894
942
  const resolvedDefault = this.resolveDefaultVersion(version, defaultVersion);
895
943
  const headerName = options.header;
896
- return async (req, res, next) => {
897
- let headerVersion = this.getHeader(req, headerName)?.trim();
898
- if (headerVersion === "")
899
- headerVersion = undefined;
944
+ return (req, res, next) => {
945
+ let headerVersion = req.headers.get(headerName) ?? undefined;
946
+ if (headerVersion) {
947
+ headerVersion = headerVersion.trim();
948
+ if (headerVersion === "")
949
+ headerVersion = undefined;
950
+ }
900
951
  headerVersion ??= resolvedDefault;
901
952
  if (!headerVersion) {
902
953
  if ((hasNeutralDefault || !defaultVersion) && acceptsNeutral) {
903
- return executeHandler(handler, req, res, next);
954
+ return handler(req, res, next);
904
955
  }
905
- return callNext(next);
956
+ next();
957
+ return;
906
958
  }
907
959
  if (versionMatches(headerVersion)) {
908
- return executeHandler(handler, req, res, next);
960
+ return handler(req, res, next);
909
961
  }
910
- return callNext(next);
962
+ next();
911
963
  };
912
964
  }
913
965
  static resolveDefaultVersion(handlerVersion, defaultVersion) {
@@ -924,12 +976,15 @@ class BunVersionFilterMiddleware {
924
976
  return;
925
977
  }
926
978
  static selectBestCustomVersionCandidate(req) {
927
- const { _customVersioningPhase: phase, _customVersioningCandidates: candidates } = req;
928
- if (phase !== "discovery" || !candidates?.size)
979
+ const phase = req.get(CUSTOM_VERSIONING_PHASE_KEY);
980
+ if (phase !== 0)
981
+ return null;
982
+ const candidates = req.get(CUSTOM_VERSIONING_CANDIDATES_KEY);
983
+ if (!candidates?.size)
929
984
  return null;
930
985
  let bestVersion = null;
931
986
  let bestPriority = Infinity;
932
- for (const [version, { priority }] of candidates) {
987
+ for (const [version, priority] of candidates) {
933
988
  if (priority < bestPriority) {
934
989
  bestPriority = priority;
935
990
  bestVersion = version;
@@ -938,17 +993,19 @@ class BunVersionFilterMiddleware {
938
993
  return bestVersion;
939
994
  }
940
995
  static setCustomVersioningExecutionPhase(req, bestVersion) {
941
- const reqMeta = req;
942
- reqMeta._customVersioningPhase = "execution";
943
- reqMeta._customVersioningBestCandidate = bestVersion;
996
+ req.set(CUSTOM_VERSIONING_PHASE_KEY, 1);
997
+ req.set(CUSTOM_VERSIONING_BEST_CANDIDATE_KEY, bestVersion);
944
998
  }
945
999
  static hasCustomVersioningCandidates(req) {
946
- const { _customVersioningPhase: phase, _customVersioningCandidates: candidates } = req;
947
- return phase === "discovery" && !!candidates?.size;
1000
+ const phase = req.get(CUSTOM_VERSIONING_PHASE_KEY);
1001
+ if (phase !== 0)
1002
+ return false;
1003
+ const candidates = req.get(CUSTOM_VERSIONING_CANDIDATES_KEY);
1004
+ return !!candidates?.size;
948
1005
  }
949
1006
  }
950
1007
 
951
- // lib/bun.adapter.ts
1008
+ // lib/bun.server-instance.ts
952
1009
  var REQUEST_METHOD_STRINGS = [
953
1010
  "GET",
954
1011
  "POST",
@@ -968,9 +1025,9 @@ var REQUEST_METHOD_STRINGS = [
968
1025
  "UNLOCK"
969
1026
  ];
970
1027
 
971
- class BunAdapter extends AbstractHttpAdapter {
1028
+ class BunServerInstance {
972
1029
  bunServeOptions;
973
- logger = new Logger("BunAdapter", { timestamp: true });
1030
+ logger = new Logger("BunServerInstance", { timestamp: true });
974
1031
  middlewareEngine = new BunMiddlewareEngine;
975
1032
  useVersioning = false;
976
1033
  routes = Object.create(null);
@@ -988,35 +1045,26 @@ class BunAdapter extends AbstractHttpAdapter {
988
1045
  wsOptions = {};
989
1046
  useWs = false;
990
1047
  useWsCors = false;
991
- wsCorsHeaders;
992
- constructor(bunServeOptions = {
993
- development: false,
994
- id: randomUUIDv7()
995
- }) {
996
- super();
1048
+ httpServer = null;
1049
+ constructor(bunServeOptions) {
997
1050
  this.bunServeOptions = bunServeOptions;
998
- this.setInstance({
999
- use: (maybePath, maybeHandler) => {
1000
- if (typeof maybePath === "string") {
1001
- let path = maybePath;
1002
- const handler = maybeHandler;
1003
- if (!handler) {
1004
- throw new Error("Handler must be provided when path is a string.");
1005
- }
1006
- if (path.includes("/*")) {
1007
- path = path.substring(0, path.indexOf("/*"));
1008
- }
1009
- this.logger.log(`Registering middleware for path: ${path}`);
1010
- this.middlewareEngine.useRoute("ALL", path, handler);
1011
- } else {
1012
- const handler = maybePath;
1013
- this.middlewareEngine.useGlobal(handler);
1014
- }
1015
- }
1016
- });
1017
1051
  }
1018
- use(middleware) {
1019
- this.middlewareEngine.useGlobal(middleware);
1052
+ use(maybePath, maybeHandler) {
1053
+ if (typeof maybePath === "string") {
1054
+ let path = maybePath;
1055
+ const handler = maybeHandler;
1056
+ if (!handler) {
1057
+ throw new Error("Handler must be provided when path is a string.");
1058
+ }
1059
+ if (path.includes("/*")) {
1060
+ path = path.substring(0, path.indexOf("/*"));
1061
+ }
1062
+ this.logger.log(`Registering middleware for path: ${path}`);
1063
+ this.middlewareEngine.useRoute("ALL", path, handler);
1064
+ } else {
1065
+ const handler = maybePath;
1066
+ this.middlewareEngine.useGlobal(handler);
1067
+ }
1020
1068
  }
1021
1069
  createHttpMethodHandler(httpMethod) {
1022
1070
  return (pathOrHandler, maybeHandler) => {
@@ -1077,95 +1125,87 @@ class BunAdapter extends AbstractHttpAdapter {
1077
1125
  search(pathOrHandler, maybeHandler) {
1078
1126
  this.createUnsupportedMethod()(pathOrHandler, maybeHandler);
1079
1127
  }
1080
- useStaticAssets(...args) {
1081
- throw new Error("Not supported.");
1082
- }
1083
- setViewEngine(engine) {
1084
- throw new Error("Not supported.");
1085
- }
1086
- render(response, view, options) {
1087
- throw new Error("Not supported.");
1128
+ listen(port, hostnameOrCallback, maybeCallback) {
1129
+ const hostname = typeof hostnameOrCallback === "string" ? hostnameOrCallback : this.bunServeOptions.hostname ?? "127.0.0.1";
1130
+ const callback = typeof hostnameOrCallback === "function" ? hostnameOrCallback : maybeCallback;
1131
+ const middlewareEngine = this.middlewareEngine;
1132
+ const notFoundHandler = this.notFoundHandler;
1133
+ const wsHandlers = this.wsHandlers;
1134
+ const bunServeOptions = this.bunServeOptions;
1135
+ this.setupWebSocketIfNeeded(wsHandlers, bunServeOptions);
1136
+ const fetch = async (request, server) => {
1137
+ const bunRequest = new BunRequest(request);
1138
+ if (await this.upgradeWebSocket(request, bunRequest, server)) {
1139
+ return;
1140
+ }
1141
+ const routeHandler = middlewareEngine.findRouteHandler(bunRequest.method, bunRequest.pathname) ?? notFoundHandler;
1142
+ const bunResponse = await middlewareEngine.run({
1143
+ req: bunRequest,
1144
+ res: new BunResponse,
1145
+ method: bunRequest.method,
1146
+ path: bunRequest.pathname,
1147
+ requestHandler: routeHandler
1148
+ });
1149
+ return bunResponse.res();
1150
+ };
1151
+ this.httpServer = this.createServer(port, hostname, bunServeOptions, fetch);
1152
+ callback?.();
1153
+ return this.httpServer;
1088
1154
  }
1089
- async close() {
1090
- await this.httpServer.stop();
1155
+ async stop(force) {
1156
+ const server = this.httpServer;
1157
+ if (!server) {
1158
+ return;
1159
+ }
1160
+ await server.stop(force);
1091
1161
  }
1092
- initHttpServer(options) {
1093
- const preflightServer = new BunPreflightHttpServer({
1094
- getBunHttpServerInstance: () => this.getHttpServer(),
1095
- getBunServerOptions: () => this.bunServeOptions,
1096
- getWsHandlers: () => this.wsHandlers,
1097
- setWsOptions: (wsOptions) => {
1098
- this.wsOptions = wsOptions;
1099
- }
1100
- });
1101
- this.setHttpServer(preflightServer);
1102
- if (options.httpsOptions) {
1103
- this.bunServeOptions.tls = {
1104
- key: options.httpsOptions.key,
1105
- cert: options.httpsOptions.cert,
1106
- passphrase: options.httpsOptions.passphrase,
1107
- ca: options.httpsOptions.ca,
1108
- ciphers: options.httpsOptions.ciphers,
1109
- secureOptions: options.httpsOptions.secureOptions,
1110
- rejectUnauthorized: options.httpsOptions.rejectUnauthorized,
1111
- requestCert: options.httpsOptions.requestCert
1162
+ address() {
1163
+ const server = this.httpServer;
1164
+ if (!server) {
1165
+ const hostname = this.bunServeOptions.hostname;
1166
+ const port = this.bunServeOptions.port;
1167
+ return {
1168
+ address: typeof hostname === "string" ? hostname : "127.0.0.1",
1169
+ port: typeof port === "number" ? port : 3000
1112
1170
  };
1113
1171
  }
1114
- return preflightServer;
1115
- }
1116
- getRequestHostname(request) {
1117
- return request.hostname;
1172
+ return {
1173
+ address: server.hostname ?? "127.0.0.1",
1174
+ port: server.port ?? 3000
1175
+ };
1118
1176
  }
1119
- getRequestMethod(request) {
1120
- return request.method;
1177
+ setWsOptions(options) {
1178
+ this.wsOptions = options;
1121
1179
  }
1122
- getRequestUrl(request) {
1123
- return request.pathname;
1180
+ registerWsOpenHandler(handler) {
1181
+ this.wsHandlers.onOpen = handler;
1124
1182
  }
1125
- status(response, statusCode) {
1126
- response.setStatus(statusCode);
1183
+ registerWsMessageHandler(handler) {
1184
+ this.wsHandlers.onMessage = handler;
1127
1185
  }
1128
- reply(response, body, statusCode) {
1129
- if (statusCode) {
1130
- response.setStatus(statusCode);
1131
- }
1132
- response.end(body);
1186
+ registerWsCloseHandler(handler) {
1187
+ this.wsHandlers.onClose = handler;
1133
1188
  }
1134
- end(response, message) {
1135
- response.end(message);
1189
+ getBunServer() {
1190
+ return this.httpServer;
1136
1191
  }
1137
- redirect(response, statusCode, url) {
1138
- response.redirect(url, statusCode);
1192
+ async close() {
1193
+ await this.stop(true);
1139
1194
  }
1140
- setErrorHandler(handler, prefix) {
1141
- this.middlewareEngine.useErrorHandler(handler);
1195
+ getMiddlewareEngine() {
1196
+ return this.middlewareEngine;
1142
1197
  }
1143
- setNotFoundHandler(handler, prefix) {
1198
+ setNotFoundHandler(handler) {
1144
1199
  this.notFoundHandler = handler;
1145
- this.middlewareEngine.useNotFoundHandler(handler);
1146
- }
1147
- isHeadersSent(response) {
1148
- return response.isEnded();
1149
- }
1150
- getHeader(response, name) {
1151
- return response.getHeader(name);
1152
1200
  }
1153
- setHeader(response, name, value) {
1154
- response.setHeader(name, value);
1155
- }
1156
- appendHeader(response, name, value) {
1157
- response.appendHeader(name, value);
1201
+ setUseVersioning(value) {
1202
+ this.useVersioning = value;
1158
1203
  }
1159
1204
  registerParserMiddleware(prefix, rawBody) {
1160
1205
  this.logger.log(`Registering Body Parser Middleware with prefix: ${prefix || "/"} and rawBody: ${rawBody ? "true" : "false"}`);
1161
1206
  const bodyParser = new BunBodyParserMiddleware({ prefix, rawBody });
1162
1207
  this.middlewareEngine.useGlobal(bodyParser.run.bind(bodyParser));
1163
1208
  }
1164
- enableCors(options, prefix) {
1165
- this.logger.log(`Enabling CORS Middleware with prefix: ${prefix ?? "/"}`);
1166
- const corsMiddleware = new BunCorsMiddleware({ corsOptions: options, prefix });
1167
- this.middlewareEngine.useGlobal(corsMiddleware.run.bind(corsMiddleware));
1168
- }
1169
1209
  createMiddlewareFactory(requestMethod) {
1170
1210
  return (path, callback) => {
1171
1211
  const methodName = this.mapRequestMethodToString(requestMethod);
@@ -1177,41 +1217,10 @@ class BunAdapter extends AbstractHttpAdapter {
1177
1217
  this.middlewareEngine.useRoute(methodName, normalizedPath, callback);
1178
1218
  };
1179
1219
  }
1180
- getType() {
1181
- return "bun";
1182
- }
1183
- applyVersionFilter(handler, version, versioningOptions) {
1184
- this.logger.log(`Applying Version Filter Middleware for version: ${JSON.stringify(version)}`);
1185
- this.useVersioning = true;
1186
- return BunVersionFilterMiddleware.createFilter(handler, version, versioningOptions);
1187
- }
1188
- listen(port, hostnameOrCallback, maybeCallback) {
1189
- const hostname = typeof hostnameOrCallback === "string" ? hostnameOrCallback : this.bunServeOptions.hostname ?? "127.0.0.1";
1190
- const callback = typeof hostnameOrCallback === "function" ? hostnameOrCallback : maybeCallback;
1191
- const middlewareEngine = this.middlewareEngine;
1192
- const notFoundHandler = this.notFoundHandler;
1193
- const wsHandlers = this.wsHandlers;
1194
- const bunServeOptions = this.bunServeOptions;
1195
- this.setupWebSocketIfNeeded(wsHandlers, bunServeOptions);
1196
- const fetch = async (request, server2) => {
1197
- if (await this.upgradeWebSocket(request, server2)) {
1198
- return;
1199
- }
1200
- const bunRequest = new BunRequest(request);
1201
- const bunResponse = new BunResponse;
1202
- const routeHandler = middlewareEngine.findRouteHandler(bunRequest.method, bunRequest.pathname) ?? notFoundHandler;
1203
- await middlewareEngine.run({
1204
- req: bunRequest,
1205
- res: bunResponse,
1206
- method: bunRequest.method,
1207
- path: bunRequest.pathname,
1208
- requestHandler: routeHandler
1209
- });
1210
- return bunResponse.res();
1211
- };
1212
- const server = this.createServer(port, hostname, bunServeOptions, fetch);
1213
- callback?.();
1214
- this.setHttpServer(server);
1220
+ enableCors(corsOptions, prefix) {
1221
+ this.logger.log(`Enabling CORS Middleware with prefix: ${prefix ?? "/"}`);
1222
+ const corsMiddleware = new BunCorsMiddleware({ corsOptions, prefix });
1223
+ this.middlewareEngine.useGlobal(corsMiddleware.run.bind(corsMiddleware));
1215
1224
  }
1216
1225
  static isNumericPort(value) {
1217
1226
  return typeof value === "number" || !isNaN(Number(value));
@@ -1228,11 +1237,7 @@ class BunAdapter extends AbstractHttpAdapter {
1228
1237
  const connectionHeader = request.headers.get("connection");
1229
1238
  return !!(upgradeHeader?.toLowerCase() === "websocket" && connectionHeader?.toLowerCase().includes("upgrade"));
1230
1239
  }
1231
- async handleWebSocketCors(request) {
1232
- if (this.wsCorsHeaders) {
1233
- return this.wsCorsHeaders;
1234
- }
1235
- const bunRequest = new BunRequest(request);
1240
+ async provideCorsHeaders(bunRequest) {
1236
1241
  const bunResponse = new BunResponse;
1237
1242
  await this.wsMiddlewareEngine.run({
1238
1243
  req: bunRequest,
@@ -1244,66 +1249,60 @@ class BunAdapter extends AbstractHttpAdapter {
1244
1249
  }
1245
1250
  });
1246
1251
  const response = await bunResponse.res();
1247
- this.wsCorsHeaders = response.headers;
1248
- return this.wsCorsHeaders;
1252
+ return response.headers;
1249
1253
  }
1250
- async upgradeWebSocket(request, server) {
1254
+ async upgradeWebSocket(request, bunRequest, server) {
1251
1255
  if (!this.useWs || !this.isWebSocketUpgradeRequest(request)) {
1252
1256
  return false;
1253
1257
  }
1254
- if (!this.useWsCors) {
1255
- return server.upgrade(request, {
1256
- data: this.wsOptions.clientDataFactory ? this.wsOptions.clientDataFactory(new BunRequest(request)) : {}
1257
- });
1258
- }
1259
- const headers = await this.handleWebSocketCors(request);
1258
+ const headers = this.useWsCors ? await this.provideCorsHeaders(bunRequest) : undefined;
1260
1259
  return server.upgrade(request, {
1261
1260
  headers,
1262
- data: this.wsOptions.clientDataFactory ? this.wsOptions.clientDataFactory(new BunRequest(request)) : {}
1261
+ data: await this.wsOptions.clientDataFactory?.(bunRequest) ?? {}
1263
1262
  });
1264
1263
  }
1265
1264
  setupWebSocketIfNeeded(wsHandlers, bunServeOptions) {
1266
1265
  const useWs = !!wsHandlers.onOpen && !!wsHandlers.onMessage && !!wsHandlers.onClose;
1267
- this.useWs = useWs;
1268
- if (useWs) {
1269
- const getServer = this.getHttpServer.bind(this);
1270
- const onMessage = wsHandlers.onMessage;
1271
- const onOpen = wsHandlers.onOpen;
1272
- const onClose = wsHandlers.onClose;
1273
- bunServeOptions.websocket = {
1274
- ...this.wsOptions,
1275
- message: (ws, message) => {
1276
- ws.data.onMessageInternal?.(message);
1277
- onMessage?.(ws, message, getServer());
1278
- },
1279
- open: (ws) => {
1280
- onOpen?.(ws);
1281
- },
1282
- close: (ws, code, reason) => {
1283
- ws.data.onCloseInternal?.();
1284
- ws.data.onDisconnect?.(ws);
1285
- onClose?.(ws, code, reason);
1286
- }
1287
- };
1288
- }
1266
+ if (!useWs)
1267
+ return;
1268
+ this.useWs = true;
1269
+ const getServer = () => this.getBunServer();
1270
+ const onMessage = wsHandlers.onMessage;
1271
+ const onOpen = wsHandlers.onOpen;
1272
+ const onClose = wsHandlers.onClose;
1273
+ bunServeOptions.websocket = {
1274
+ ...this.wsOptions,
1275
+ message: (ws, message) => {
1276
+ ws.data.onMessageInternal?.(message);
1277
+ onMessage?.(ws, message, getServer());
1278
+ },
1279
+ open: (ws) => {
1280
+ onOpen?.(ws);
1281
+ },
1282
+ close: (ws, code, reason) => {
1283
+ ws.data.onCloseInternal?.();
1284
+ ws.data.onDisconnect?.(ws);
1285
+ onClose?.(ws, code, reason);
1286
+ }
1287
+ };
1289
1288
  const useWsCors = typeof this.wsOptions.cors !== "undefined";
1290
- this.useWsCors = useWsCors;
1291
- if (useWsCors) {
1292
- const corsMiddleware = new BunCorsMiddleware({
1293
- corsOptions: this.wsOptions.cors === true ? undefined : this.wsOptions.cors
1294
- });
1295
- this.wsMiddlewareEngine.useGlobal(corsMiddleware.run.bind(corsMiddleware));
1296
- }
1289
+ if (!useWsCors)
1290
+ return;
1291
+ this.useWsCors = true;
1292
+ const corsMiddleware = new BunCorsMiddleware({
1293
+ corsOptions: this.wsOptions.cors === true ? undefined : this.wsOptions.cors
1294
+ });
1295
+ this.wsMiddlewareEngine.useGlobal(corsMiddleware.run.bind(corsMiddleware));
1297
1296
  }
1298
1297
  createServer(port, hostname, bunServeOptions, fetch) {
1299
- return BunAdapter.isNumericPort(port) ? Bun.serve({
1298
+ return BunServerInstance.isNumericPort(port) ? Bun.serve({
1300
1299
  ...bunServeOptions,
1301
1300
  hostname,
1302
1301
  port,
1303
1302
  routes: this.routes,
1304
1303
  fetch
1305
1304
  }) : Bun.serve({
1306
- ...BunAdapter.omitKeys(bunServeOptions, "idleTimeout", "port", "hostname"),
1305
+ ...BunServerInstance.omitKeys(bunServeOptions, "idleTimeout", "port", "hostname"),
1307
1306
  unix: port,
1308
1307
  routes: this.routes,
1309
1308
  fetch
@@ -1320,21 +1319,19 @@ class BunAdapter extends AbstractHttpAdapter {
1320
1319
  }
1321
1320
  }
1322
1321
  prepareRequestHandler(method, path, handler) {
1323
- if (!this.useVersioning) {
1322
+ if (!this.useVersioning)
1324
1323
  return handler;
1325
- }
1326
1324
  return this.createChainedHandlerForVersioningResolution(this.createVersioningHandlers(method, path, handler), this.notFoundHandler);
1327
1325
  }
1328
1326
  createRouteFetchHandler(path, method, requestHandler) {
1329
1327
  return async (request, server) => {
1330
- if (path === "/" && await this.upgradeWebSocket(request, server)) {
1328
+ const bunRequest = new BunRequest(request);
1329
+ if (path === "/" && await this.upgradeWebSocket(request, bunRequest, server)) {
1331
1330
  return;
1332
1331
  }
1333
- const bunRequest = new BunRequest(request);
1334
- const bunResponse = new BunResponse;
1335
- await this.middlewareEngine.run({
1332
+ const bunResponse = await this.middlewareEngine.run({
1336
1333
  req: bunRequest,
1337
- res: bunResponse,
1334
+ res: new BunResponse,
1338
1335
  method,
1339
1336
  path,
1340
1337
  requestHandler
@@ -1390,6 +1387,114 @@ class BunAdapter extends AbstractHttpAdapter {
1390
1387
  return { path, handler };
1391
1388
  }
1392
1389
  }
1390
+
1391
+ // lib/bun.adapter.ts
1392
+ class BunAdapter extends AbstractHttpAdapter {
1393
+ bunServeOptions;
1394
+ logger = new Logger2("BunAdapter", { timestamp: true });
1395
+ constructor(bunServeOptions = {
1396
+ development: false,
1397
+ id: randomUUIDv7()
1398
+ }) {
1399
+ super(new BunServerInstance(bunServeOptions));
1400
+ this.bunServeOptions = bunServeOptions;
1401
+ }
1402
+ useStaticAssets(...args) {
1403
+ throw new Error("Not supported.");
1404
+ }
1405
+ setViewEngine(engine) {
1406
+ throw new Error("Not supported.");
1407
+ }
1408
+ render(response, view, options) {
1409
+ throw new Error("Not supported.");
1410
+ }
1411
+ async close() {
1412
+ await this.instance.close();
1413
+ }
1414
+ initHttpServer(options) {
1415
+ this.configureTls(options);
1416
+ const preflightServer = new BunPreflightHttpServer(this.instance);
1417
+ this.setHttpServer(preflightServer);
1418
+ return preflightServer;
1419
+ }
1420
+ getRequestHostname(request) {
1421
+ return request.hostname;
1422
+ }
1423
+ getRequestMethod(request) {
1424
+ return request.method;
1425
+ }
1426
+ getRequestUrl(request) {
1427
+ return request.pathname;
1428
+ }
1429
+ status(response, statusCode) {
1430
+ response.setStatus(statusCode);
1431
+ }
1432
+ reply(response, body, statusCode) {
1433
+ if (statusCode) {
1434
+ response.setStatus(statusCode);
1435
+ }
1436
+ response.end(body);
1437
+ }
1438
+ end(response, message) {
1439
+ response.end(message);
1440
+ }
1441
+ redirect(response, statusCode, url) {
1442
+ response.redirect(url, statusCode);
1443
+ }
1444
+ setErrorHandler(handler, prefix) {
1445
+ this.instance.getMiddlewareEngine().useErrorHandler(handler);
1446
+ }
1447
+ setNotFoundHandler(handler, prefix) {
1448
+ this.instance.setNotFoundHandler(handler);
1449
+ this.instance.getMiddlewareEngine().useNotFoundHandler(handler);
1450
+ }
1451
+ isHeadersSent(response) {
1452
+ return response.isEnded();
1453
+ }
1454
+ getHeader(response, name) {
1455
+ return response.getHeader(name);
1456
+ }
1457
+ setHeader(response, name, value) {
1458
+ response.setHeader(name, value);
1459
+ }
1460
+ appendHeader(response, name, value) {
1461
+ response.appendHeader(name, value);
1462
+ }
1463
+ registerParserMiddleware(prefix, rawBody) {
1464
+ this.instance.registerParserMiddleware(prefix, rawBody);
1465
+ }
1466
+ enableCors(options, prefix) {
1467
+ this.instance.enableCors(options, prefix);
1468
+ }
1469
+ createMiddlewareFactory(requestMethod) {
1470
+ return this.instance.createMiddlewareFactory(requestMethod);
1471
+ }
1472
+ getType() {
1473
+ return "bun";
1474
+ }
1475
+ applyVersionFilter(handler, version, versioningOptions) {
1476
+ this.logger.log(`Applying Version Filter Middleware for version: ${JSON.stringify(version)}`);
1477
+ this.instance.setUseVersioning(true);
1478
+ return BunVersionFilterMiddleware.createFilter(handler, version, versioningOptions);
1479
+ }
1480
+ listen(port, hostnameOrCallback, maybeCallback) {
1481
+ this.setHttpServer(this.instance.listen(port, hostnameOrCallback, maybeCallback));
1482
+ }
1483
+ configureTls(options) {
1484
+ if (options.httpsOptions) {
1485
+ this.bunServeOptions.tls = {
1486
+ key: options.httpsOptions.key,
1487
+ cert: options.httpsOptions.cert,
1488
+ passphrase: options.httpsOptions.passphrase,
1489
+ ca: options.httpsOptions.ca,
1490
+ ciphers: options.httpsOptions.ciphers,
1491
+ secureOptions: options.httpsOptions.secureOptions,
1492
+ rejectUnauthorized: options.httpsOptions.rejectUnauthorized,
1493
+ requestCert: options.httpsOptions.requestCert
1494
+ };
1495
+ }
1496
+ }
1497
+ }
1393
1498
  // lib/bun.file.interceptor.ts
1394
1499
  import { Injectable } from "@nestjs/common";
1395
1500
  import { basename, join } from "path";
@@ -1430,7 +1535,7 @@ import {
1430
1535
  AbstractWsAdapter
1431
1536
  } from "@nestjs/websockets";
1432
1537
  import { EMPTY, Subject, mergeMap } from "rxjs";
1433
- import { Logger as Logger2 } from "@nestjs/common";
1538
+ import { Logger as Logger3 } from "@nestjs/common";
1434
1539
  import { isNil } from "@nestjs/common/utils/shared.utils.js";
1435
1540
  var WS_READY_STATE_OPEN = 1;
1436
1541
  var defaultMessageParser = (data) => {
@@ -1447,7 +1552,7 @@ var defaultMessageParser = (data) => {
1447
1552
  };
1448
1553
 
1449
1554
  class BunWsAdapter extends AbstractWsAdapter {
1450
- logger = new Logger2(BunWsAdapter.name);
1555
+ logger = new Logger3(BunWsAdapter.name);
1451
1556
  nestApp;
1452
1557
  messageParser = defaultMessageParser;
1453
1558
  onOpenHandler;
@@ -1572,6 +1677,7 @@ class BunWsAdapter extends AbstractWsAdapter {
1572
1677
  }
1573
1678
  export {
1574
1679
  BunWsAdapter,
1680
+ BunServerInstance,
1575
1681
  BunResponse,
1576
1682
  BunRequest,
1577
1683
  BunPreflightHttpServer,
@@ -1579,5 +1685,5 @@ export {
1579
1685
  BunAdapter
1580
1686
  };
1581
1687
 
1582
- //# debugId=1BD5D75380392B3E64756E2164756E21
1688
+ //# debugId=813882D1C572F1EC64756E2164756E21
1583
1689
  //# sourceMappingURL=index.js.map