srvx 0.1.3 → 0.2.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/adapters/bun.d.mts +22 -0
- package/dist/adapters/bun.mjs +51 -0
- package/dist/adapters/cloudflare.d.mts +9 -0
- package/dist/adapters/cloudflare.mjs +44 -0
- package/dist/adapters/deno.d.mts +23 -0
- package/dist/adapters/deno.mjs +67 -0
- package/dist/adapters/node.d.mts +48 -0
- package/dist/{shared/srvx.1e3bbf3a.mjs → adapters/node.mjs} +361 -108
- package/dist/shared/srvx.DhN4g5wJ.mjs +76 -0
- package/dist/shared/srvx.PbkQy9Ck.mjs +18 -0
- package/dist/types.d.mts +90 -95
- package/package.json +35 -32
- package/dist/bun.d.mts +0 -8
- package/dist/bun.d.ts +0 -8
- package/dist/bun.mjs +0 -42
- package/dist/deno.d.mts +0 -8
- package/dist/deno.d.ts +0 -8
- package/dist/deno.mjs +0 -56
- package/dist/node-utils/index.d.mts +0 -138
- package/dist/node-utils/index.d.ts +0 -138
- package/dist/node-utils/index.mjs +0 -229
- package/dist/node.d.mts +0 -8
- package/dist/node.d.ts +0 -8
- package/dist/node.mjs +0 -70
- package/dist/shared/srvx.4f681732.mjs +0 -112
- package/dist/types.d.ts +0 -175
- package/dist/types.mjs +0 -1
|
@@ -1,7 +1,80 @@
|
|
|
1
|
+
import NodeHttp from 'node:http';
|
|
1
2
|
import { splitSetCookieString } from 'cookie-es';
|
|
3
|
+
import { r as resolvePort, f as fmtURL } from '../shared/srvx.PbkQy9Ck.mjs';
|
|
4
|
+
import { w as wrapFetch } from '../shared/srvx.DhN4g5wJ.mjs';
|
|
5
|
+
|
|
6
|
+
async function sendNodeResponse(nodeRes, webRes) {
|
|
7
|
+
if (!webRes) {
|
|
8
|
+
nodeRes.statusCode = 500;
|
|
9
|
+
return endNodeResponse(nodeRes);
|
|
10
|
+
}
|
|
11
|
+
if (webRes.nodeResponse) {
|
|
12
|
+
const res = webRes.nodeResponse();
|
|
13
|
+
nodeRes.writeHead(res.status, res.statusText, res.headers);
|
|
14
|
+
if (res.body instanceof ReadableStream) {
|
|
15
|
+
return streamBody(res.body, nodeRes);
|
|
16
|
+
}
|
|
17
|
+
nodeRes.write(res.body);
|
|
18
|
+
return endNodeResponse(nodeRes);
|
|
19
|
+
}
|
|
20
|
+
const headerEntries = [];
|
|
21
|
+
for (const [key, value] of webRes.headers) {
|
|
22
|
+
if (key === "set-cookie") {
|
|
23
|
+
for (const setCookie of splitSetCookieString(value)) {
|
|
24
|
+
headerEntries.push(["set-cookie", setCookie]);
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
headerEntries.push([key, value]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
nodeRes.writeHead(webRes.status || 200, webRes.statusText, headerEntries);
|
|
31
|
+
return webRes.body ? streamBody(webRes.body, nodeRes) : endNodeResponse(nodeRes);
|
|
32
|
+
}
|
|
33
|
+
function endNodeResponse(nodeRes) {
|
|
34
|
+
return new Promise((resolve) => nodeRes.end(resolve));
|
|
35
|
+
}
|
|
36
|
+
function streamBody(stream, nodeRes) {
|
|
37
|
+
if (nodeRes.destroyed) {
|
|
38
|
+
stream.cancel();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const reader = stream.getReader();
|
|
42
|
+
function streamCancel(error) {
|
|
43
|
+
reader.cancel(error).catch(() => {
|
|
44
|
+
});
|
|
45
|
+
if (error) {
|
|
46
|
+
nodeRes.destroy(error);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function streamHandle({
|
|
50
|
+
done,
|
|
51
|
+
value
|
|
52
|
+
}) {
|
|
53
|
+
try {
|
|
54
|
+
if (done) {
|
|
55
|
+
nodeRes.end();
|
|
56
|
+
} else if (nodeRes.write(value)) {
|
|
57
|
+
reader.read().then(streamHandle, streamCancel);
|
|
58
|
+
} else {
|
|
59
|
+
nodeRes.once(
|
|
60
|
+
"drain",
|
|
61
|
+
() => reader.read().then(streamHandle, streamCancel)
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
} catch (error) {
|
|
65
|
+
streamCancel(error instanceof Error ? error : void 0);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
nodeRes.on("close", streamCancel);
|
|
69
|
+
nodeRes.on("error", streamCancel);
|
|
70
|
+
reader.read().then(streamHandle, streamCancel);
|
|
71
|
+
return reader.closed.finally(() => {
|
|
72
|
+
nodeRes.off("close", streamCancel);
|
|
73
|
+
nodeRes.off("error", streamCancel);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
2
76
|
|
|
3
77
|
const kNodeReq = /* @__PURE__ */ Symbol.for("srvx.node.request");
|
|
4
|
-
const kNodeRes = /* @__PURE__ */ Symbol.for("srvx.node.response");
|
|
5
78
|
const kNodeInspect = /* @__PURE__ */ Symbol.for(
|
|
6
79
|
"nodejs.util.inspect.custom"
|
|
7
80
|
);
|
|
@@ -11,6 +84,7 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => class NodeReqHeadersProxy {
|
|
|
11
84
|
this[kNodeReq] = req;
|
|
12
85
|
}
|
|
13
86
|
append(name, value) {
|
|
87
|
+
name = name.toLowerCase();
|
|
14
88
|
const _headers = this[kNodeReq].headers;
|
|
15
89
|
const _current = _headers[name];
|
|
16
90
|
if (_current) {
|
|
@@ -24,9 +98,11 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => class NodeReqHeadersProxy {
|
|
|
24
98
|
}
|
|
25
99
|
}
|
|
26
100
|
delete(name) {
|
|
101
|
+
name = name.toLowerCase();
|
|
27
102
|
this[kNodeReq].headers[name] = void 0;
|
|
28
103
|
}
|
|
29
104
|
get(name) {
|
|
105
|
+
name = name.toLowerCase();
|
|
30
106
|
return _normalizeValue(this[kNodeReq].headers[name]);
|
|
31
107
|
}
|
|
32
108
|
getSetCookie() {
|
|
@@ -37,11 +113,19 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => class NodeReqHeadersProxy {
|
|
|
37
113
|
return splitSetCookieString(setCookie);
|
|
38
114
|
}
|
|
39
115
|
has(name) {
|
|
116
|
+
name = name.toLowerCase();
|
|
40
117
|
return !!this[kNodeReq].headers[name];
|
|
41
118
|
}
|
|
42
119
|
set(name, value) {
|
|
120
|
+
name = name.toLowerCase();
|
|
43
121
|
this[kNodeReq].headers[name] = value;
|
|
44
122
|
}
|
|
123
|
+
get count() {
|
|
124
|
+
throw new Error("Method not implemented.");
|
|
125
|
+
}
|
|
126
|
+
getAll(_name) {
|
|
127
|
+
throw new Error("Method not implemented.");
|
|
128
|
+
}
|
|
45
129
|
toJSON() {
|
|
46
130
|
const _headers = this[kNodeReq].headers;
|
|
47
131
|
const result = {};
|
|
@@ -93,73 +177,6 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => class NodeReqHeadersProxy {
|
|
|
93
177
|
return Object.fromEntries(this.entries());
|
|
94
178
|
}
|
|
95
179
|
})();
|
|
96
|
-
const NodeResHeadersProxy = /* @__PURE__ */ (() => class NodeResHeadersProxy {
|
|
97
|
-
constructor(res) {
|
|
98
|
-
this[kNodeRes] = res;
|
|
99
|
-
}
|
|
100
|
-
append(name, value) {
|
|
101
|
-
this[kNodeRes].appendHeader(name, value);
|
|
102
|
-
}
|
|
103
|
-
delete(name) {
|
|
104
|
-
this[kNodeRes].removeHeader(name);
|
|
105
|
-
}
|
|
106
|
-
get(name) {
|
|
107
|
-
return _normalizeValue(this[kNodeRes].getHeader(name));
|
|
108
|
-
}
|
|
109
|
-
getSetCookie() {
|
|
110
|
-
const setCookie = _normalizeValue(this[kNodeRes].getHeader("set-cookie"));
|
|
111
|
-
if (!setCookie) {
|
|
112
|
-
return [];
|
|
113
|
-
}
|
|
114
|
-
return splitSetCookieString(setCookie);
|
|
115
|
-
}
|
|
116
|
-
has(name) {
|
|
117
|
-
return this[kNodeRes].hasHeader(name);
|
|
118
|
-
}
|
|
119
|
-
set(name, value) {
|
|
120
|
-
this[kNodeRes].setHeader(name, value);
|
|
121
|
-
}
|
|
122
|
-
forEach(cb, thisArg) {
|
|
123
|
-
const _headers = this[kNodeRes].getHeaders();
|
|
124
|
-
for (const key in _headers) {
|
|
125
|
-
if (_headers[key]) {
|
|
126
|
-
cb.call(
|
|
127
|
-
thisArg,
|
|
128
|
-
_normalizeValue(_headers[key]),
|
|
129
|
-
key,
|
|
130
|
-
this
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
*entries() {
|
|
136
|
-
const _headers = this[kNodeRes].getHeaders();
|
|
137
|
-
for (const key in _headers) {
|
|
138
|
-
yield [key, _normalizeValue(_headers[key])];
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
*keys() {
|
|
142
|
-
const keys = this[kNodeRes].getHeaderNames();
|
|
143
|
-
for (const key of keys) {
|
|
144
|
-
yield key;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
*values() {
|
|
148
|
-
const values = Object.values(this[kNodeRes].getHeaders());
|
|
149
|
-
for (const value of values) {
|
|
150
|
-
yield _normalizeValue(value);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
[(Symbol.iterator)]() {
|
|
154
|
-
return this.entries()[Symbol.iterator]();
|
|
155
|
-
}
|
|
156
|
-
get [Symbol.toStringTag]() {
|
|
157
|
-
return "Headers";
|
|
158
|
-
}
|
|
159
|
-
[kNodeInspect]() {
|
|
160
|
-
return Object.fromEntries(this.entries());
|
|
161
|
-
}
|
|
162
|
-
})();
|
|
163
180
|
function _normalizeValue(value) {
|
|
164
181
|
if (Array.isArray(value)) {
|
|
165
182
|
return value.join(", ");
|
|
@@ -348,7 +365,7 @@ const NodeRequestProxy = /* @__PURE__ */ (() => class NodeRequestProxy2 {
|
|
|
348
365
|
#jsonBody;
|
|
349
366
|
#textBody;
|
|
350
367
|
#bodyStream;
|
|
351
|
-
get
|
|
368
|
+
get remoteAddress() {
|
|
352
369
|
return this[kNodeReq].socket?.remoteAddress;
|
|
353
370
|
}
|
|
354
371
|
clone() {
|
|
@@ -479,51 +496,287 @@ async function _readStream(stream) {
|
|
|
479
496
|
return Buffer.concat(chunks);
|
|
480
497
|
}
|
|
481
498
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
499
|
+
const NodeFastResponse = /* @__PURE__ */ (() => (
|
|
500
|
+
/**
|
|
501
|
+
* Fast Response for Node.js runtime
|
|
502
|
+
*
|
|
503
|
+
* It is faster because in most cases it doesn't create a full Response instance.
|
|
504
|
+
*/
|
|
505
|
+
class NodeFastResponse {
|
|
506
|
+
#body;
|
|
507
|
+
#init;
|
|
508
|
+
constructor(body, init) {
|
|
509
|
+
this.#body = body;
|
|
510
|
+
this.#init = init;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Prepare Node.js response object
|
|
514
|
+
*/
|
|
515
|
+
nodeResponse() {
|
|
516
|
+
const status = this.#init?.status ?? 200;
|
|
517
|
+
const statusText = this.#init?.statusText ?? "";
|
|
518
|
+
const headers = [];
|
|
519
|
+
let headersInit = this.#init?.headers;
|
|
520
|
+
if (headersInit) {
|
|
521
|
+
if (typeof headersInit === "object") {
|
|
522
|
+
headersInit = Object.entries(headersInit);
|
|
523
|
+
}
|
|
524
|
+
for (const [key, value] of headersInit) {
|
|
525
|
+
if (key === "set-cookie") {
|
|
526
|
+
for (const setCookie of splitSetCookieString(value)) {
|
|
527
|
+
headers.push(["set-cookie", setCookie]);
|
|
528
|
+
}
|
|
529
|
+
} else {
|
|
530
|
+
headers.push([key, value]);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
const bodyInit = this.#body;
|
|
535
|
+
let body;
|
|
536
|
+
if (bodyInit) {
|
|
537
|
+
if (typeof bodyInit === "string") {
|
|
538
|
+
body = bodyInit;
|
|
539
|
+
} else if (bodyInit instanceof ReadableStream) {
|
|
540
|
+
body = bodyInit;
|
|
541
|
+
} else if (bodyInit instanceof ArrayBuffer) {
|
|
542
|
+
body = Buffer.from(bodyInit);
|
|
543
|
+
} else if (bodyInit instanceof Uint8Array) {
|
|
544
|
+
body = Buffer.from(bodyInit);
|
|
545
|
+
} else if (bodyInit instanceof DataView) {
|
|
546
|
+
body = Buffer.from(bodyInit.buffer);
|
|
547
|
+
} else if (bodyInit instanceof Blob) {
|
|
548
|
+
body = bodyInit.stream();
|
|
549
|
+
if (bodyInit.type) {
|
|
550
|
+
headers.push(["content-type", bodyInit.type]);
|
|
551
|
+
}
|
|
552
|
+
} else {
|
|
553
|
+
const res = new Response(bodyInit);
|
|
554
|
+
body = res.body;
|
|
555
|
+
for (const [key, value] of res.headers) {
|
|
556
|
+
headers.push([key, value]);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
this.#body = void 0;
|
|
561
|
+
this.#init = void 0;
|
|
562
|
+
return {
|
|
563
|
+
status,
|
|
564
|
+
statusText,
|
|
565
|
+
headers,
|
|
566
|
+
body
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
// ... the rest is for interface compatibility only and usually not to be used ...
|
|
570
|
+
/** Lazy initialized response instance */
|
|
571
|
+
#responseObj;
|
|
572
|
+
/** Lazy initialized headers instance */
|
|
573
|
+
#headersObj;
|
|
574
|
+
clone() {
|
|
575
|
+
if (this.#responseObj) {
|
|
576
|
+
return this.#responseObj.clone();
|
|
577
|
+
}
|
|
578
|
+
return new Response(this.#body, this.#init);
|
|
579
|
+
}
|
|
580
|
+
get #response() {
|
|
581
|
+
if (!this.#responseObj) {
|
|
582
|
+
this.#responseObj = new Response(this.#body, this.#init);
|
|
583
|
+
this.#body = void 0;
|
|
584
|
+
this.#init = void 0;
|
|
585
|
+
this.#headersObj = void 0;
|
|
586
|
+
}
|
|
587
|
+
return this.#responseObj;
|
|
494
588
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
const headerEntries = [];
|
|
499
|
-
for (const [key, value] of webRes.headers) {
|
|
500
|
-
if (key === "set-cookie") {
|
|
501
|
-
for (const setCookie of splitSetCookieString(value)) {
|
|
502
|
-
headerEntries.push(["set-cookie", setCookie]);
|
|
589
|
+
get headers() {
|
|
590
|
+
if (this.#responseObj) {
|
|
591
|
+
return this.#responseObj.headers;
|
|
503
592
|
}
|
|
504
|
-
|
|
505
|
-
|
|
593
|
+
if (!this.#headersObj) {
|
|
594
|
+
this.#headersObj = new Headers(this.#init?.headers);
|
|
595
|
+
}
|
|
596
|
+
return this.#headersObj;
|
|
597
|
+
}
|
|
598
|
+
get ok() {
|
|
599
|
+
if (this.#responseObj) {
|
|
600
|
+
return this.#responseObj.ok;
|
|
601
|
+
}
|
|
602
|
+
const status = this.#init?.status ?? 200;
|
|
603
|
+
return status >= 200 && status < 300;
|
|
604
|
+
}
|
|
605
|
+
get redirected() {
|
|
606
|
+
if (this.#responseObj) {
|
|
607
|
+
return this.#responseObj.redirected;
|
|
608
|
+
}
|
|
609
|
+
return false;
|
|
610
|
+
}
|
|
611
|
+
get status() {
|
|
612
|
+
if (this.#responseObj) {
|
|
613
|
+
return this.#responseObj.status;
|
|
614
|
+
}
|
|
615
|
+
return this.#init?.status ?? 200;
|
|
616
|
+
}
|
|
617
|
+
get statusText() {
|
|
618
|
+
if (this.#responseObj) {
|
|
619
|
+
return this.#responseObj.statusText;
|
|
620
|
+
}
|
|
621
|
+
return this.#init?.statusText ?? "";
|
|
622
|
+
}
|
|
623
|
+
get type() {
|
|
624
|
+
if (this.#responseObj) {
|
|
625
|
+
return this.#responseObj.type;
|
|
626
|
+
}
|
|
627
|
+
return "default";
|
|
628
|
+
}
|
|
629
|
+
get url() {
|
|
630
|
+
if (this.#responseObj) {
|
|
631
|
+
return this.#responseObj.url;
|
|
632
|
+
}
|
|
633
|
+
return "";
|
|
634
|
+
}
|
|
635
|
+
// --- body ---
|
|
636
|
+
#fastBody(as) {
|
|
637
|
+
const bodyInit = this.#body;
|
|
638
|
+
if (bodyInit === null || bodyInit === void 0) {
|
|
639
|
+
return null;
|
|
640
|
+
}
|
|
641
|
+
if (bodyInit instanceof as) {
|
|
642
|
+
return bodyInit;
|
|
643
|
+
}
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
get body() {
|
|
647
|
+
if (this.#responseObj) {
|
|
648
|
+
return this.#responseObj.body;
|
|
649
|
+
}
|
|
650
|
+
const fastBody = this.#fastBody(ReadableStream);
|
|
651
|
+
if (fastBody !== false) {
|
|
652
|
+
return fastBody;
|
|
653
|
+
}
|
|
654
|
+
return this.#response.body;
|
|
655
|
+
}
|
|
656
|
+
get bodyUsed() {
|
|
657
|
+
if (this.#responseObj) {
|
|
658
|
+
return this.#responseObj.bodyUsed;
|
|
659
|
+
}
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
arrayBuffer() {
|
|
663
|
+
if (this.#responseObj) {
|
|
664
|
+
return this.#responseObj.arrayBuffer();
|
|
665
|
+
}
|
|
666
|
+
const fastBody = this.#fastBody(ArrayBuffer);
|
|
667
|
+
if (fastBody !== false) {
|
|
668
|
+
return Promise.resolve(fastBody || new ArrayBuffer(0));
|
|
669
|
+
}
|
|
670
|
+
return this.#response.arrayBuffer();
|
|
671
|
+
}
|
|
672
|
+
blob() {
|
|
673
|
+
if (this.#responseObj) {
|
|
674
|
+
return this.#responseObj.blob();
|
|
675
|
+
}
|
|
676
|
+
const fastBody = this.#fastBody(Blob);
|
|
677
|
+
if (fastBody !== false) {
|
|
678
|
+
return Promise.resolve(fastBody || new Blob());
|
|
679
|
+
}
|
|
680
|
+
return this.#response.blob();
|
|
681
|
+
}
|
|
682
|
+
bytes() {
|
|
683
|
+
if (this.#responseObj) {
|
|
684
|
+
return this.#responseObj.bytes();
|
|
685
|
+
}
|
|
686
|
+
const fastBody = this.#fastBody(Uint8Array);
|
|
687
|
+
if (fastBody !== false) {
|
|
688
|
+
return Promise.resolve(fastBody || new Uint8Array());
|
|
689
|
+
}
|
|
690
|
+
return this.#response.bytes();
|
|
691
|
+
}
|
|
692
|
+
formData() {
|
|
693
|
+
if (this.#responseObj) {
|
|
694
|
+
return this.#responseObj.formData();
|
|
695
|
+
}
|
|
696
|
+
const fastBody = this.#fastBody(FormData);
|
|
697
|
+
if (fastBody !== false) {
|
|
698
|
+
return Promise.resolve(fastBody || new FormData());
|
|
699
|
+
}
|
|
700
|
+
return this.#response.formData();
|
|
701
|
+
}
|
|
702
|
+
text() {
|
|
703
|
+
if (this.#responseObj) {
|
|
704
|
+
return this.#responseObj.text();
|
|
705
|
+
}
|
|
706
|
+
const bodyInit = this.#body;
|
|
707
|
+
if (bodyInit === null || bodyInit === void 0) {
|
|
708
|
+
return Promise.resolve("");
|
|
709
|
+
}
|
|
710
|
+
if (typeof bodyInit === "string") {
|
|
711
|
+
return Promise.resolve(bodyInit);
|
|
712
|
+
}
|
|
713
|
+
return this.#response.text();
|
|
714
|
+
}
|
|
715
|
+
json() {
|
|
716
|
+
if (this.#responseObj) {
|
|
717
|
+
return this.#responseObj.json();
|
|
718
|
+
}
|
|
719
|
+
return this.text().then((text) => JSON.parse(text));
|
|
506
720
|
}
|
|
507
721
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
return new Promise((resolve) => nodeRes.end(resolve));
|
|
722
|
+
))();
|
|
723
|
+
|
|
724
|
+
function serve(options) {
|
|
725
|
+
return new NodeServer(options);
|
|
513
726
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
nodeRes
|
|
727
|
+
class NodeServer {
|
|
728
|
+
constructor(options) {
|
|
729
|
+
this.runtime = "node";
|
|
730
|
+
this.options = options;
|
|
731
|
+
const fetchHandler = wrapFetch(this, this.options.fetch);
|
|
732
|
+
this.fetch = fetchHandler;
|
|
733
|
+
const handler = (nodeReq, nodeRes) => {
|
|
734
|
+
const request = new NodeRequestProxy(nodeReq);
|
|
735
|
+
request.node = { req: nodeReq, res: nodeRes };
|
|
736
|
+
const res = fetchHandler(request);
|
|
737
|
+
return res instanceof Promise ? res.then((resolvedRes) => sendNodeResponse(nodeRes, resolvedRes)) : sendNodeResponse(nodeRes, res);
|
|
738
|
+
};
|
|
739
|
+
this.serveOptions = {
|
|
740
|
+
port: resolvePort(this.options.port, globalThis.process?.env.PORT),
|
|
741
|
+
host: this.options.hostname,
|
|
742
|
+
exclusive: !this.options.reusePort,
|
|
743
|
+
...this.options.node
|
|
744
|
+
};
|
|
745
|
+
const server = NodeHttp.createServer(this.serveOptions, handler);
|
|
746
|
+
this.node = { server, handler };
|
|
747
|
+
if (!options.manual) {
|
|
748
|
+
this.serve();
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
#listeningPromise;
|
|
752
|
+
serve() {
|
|
753
|
+
if (this.#listeningPromise) {
|
|
754
|
+
return Promise.resolve(this.#listeningPromise).then(() => this);
|
|
755
|
+
}
|
|
756
|
+
this.#listeningPromise = new Promise((resolve) => {
|
|
757
|
+
this.node.server.listen(this.serveOptions, () => resolve());
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
get url() {
|
|
761
|
+
const addr = this.node?.server?.address();
|
|
762
|
+
if (!addr) {
|
|
763
|
+
return;
|
|
523
764
|
}
|
|
524
|
-
|
|
525
|
-
|
|
765
|
+
return typeof addr === "string" ? addr : fmtURL(addr.address, addr.port);
|
|
766
|
+
}
|
|
767
|
+
ready() {
|
|
768
|
+
return Promise.resolve(this.#listeningPromise).then(() => this);
|
|
769
|
+
}
|
|
770
|
+
close(closeAll) {
|
|
771
|
+
return new Promise((resolve, reject) => {
|
|
772
|
+
if (closeAll) {
|
|
773
|
+
this.node?.server?.closeAllConnections?.();
|
|
774
|
+
}
|
|
775
|
+
this.node?.server?.close(
|
|
776
|
+
(error) => error ? reject(error) : resolve()
|
|
777
|
+
);
|
|
778
|
+
});
|
|
526
779
|
}
|
|
527
780
|
}
|
|
528
781
|
|
|
529
|
-
export {
|
|
782
|
+
export { NodeFastResponse as Response, serve };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
function wrapFetch(server, fetchHandler) {
|
|
2
|
+
const plugins = server.options.plugins;
|
|
3
|
+
if (!plugins?.length) {
|
|
4
|
+
return fetchHandler;
|
|
5
|
+
}
|
|
6
|
+
const requestHooks = [];
|
|
7
|
+
const responseHooks = [];
|
|
8
|
+
for (const ctor of plugins) {
|
|
9
|
+
const plugin = typeof ctor === "function" ? ctor(server) : ctor;
|
|
10
|
+
if (plugin.request) {
|
|
11
|
+
requestHooks.push(plugin.request);
|
|
12
|
+
}
|
|
13
|
+
if (plugin.response) {
|
|
14
|
+
responseHooks.push(plugin.response);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const hasRequestHooks = requestHooks.length > 0;
|
|
18
|
+
const hasResponseHooks = responseHooks.length > 0;
|
|
19
|
+
if (!hasRequestHooks && !hasResponseHooks) {
|
|
20
|
+
return fetchHandler;
|
|
21
|
+
}
|
|
22
|
+
return (request) => {
|
|
23
|
+
let resValue;
|
|
24
|
+
let resPromise;
|
|
25
|
+
if (hasRequestHooks) {
|
|
26
|
+
for (const reqHook of requestHooks) {
|
|
27
|
+
if (resPromise) {
|
|
28
|
+
resPromise = resPromise.then((res) => res || reqHook(request));
|
|
29
|
+
} else {
|
|
30
|
+
const res = reqHook(request);
|
|
31
|
+
if (res) {
|
|
32
|
+
if (res instanceof Promise) {
|
|
33
|
+
resPromise = res;
|
|
34
|
+
} else {
|
|
35
|
+
return res;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (resPromise) {
|
|
42
|
+
resPromise = resPromise.then((res) => res || fetchHandler(request));
|
|
43
|
+
} else {
|
|
44
|
+
const res = fetchHandler(request);
|
|
45
|
+
if (res instanceof Promise) {
|
|
46
|
+
resPromise = res;
|
|
47
|
+
} else {
|
|
48
|
+
resValue = res;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (hasResponseHooks) {
|
|
52
|
+
for (const resHook of responseHooks) {
|
|
53
|
+
if (resPromise) {
|
|
54
|
+
resPromise = resPromise.then((res) => {
|
|
55
|
+
if (res) {
|
|
56
|
+
resValue = res;
|
|
57
|
+
}
|
|
58
|
+
return resHook(request, resValue);
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
const res = resHook(request, resValue);
|
|
62
|
+
if (res) {
|
|
63
|
+
if (res instanceof Promise) {
|
|
64
|
+
resPromise = res;
|
|
65
|
+
} else {
|
|
66
|
+
resValue = res;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return resPromise ? resPromise.then((res) => res || resValue) : resValue;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { wrapFetch as w };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function resolvePort(portOptions, portEnv) {
|
|
2
|
+
const portInput = portOptions ?? portEnv;
|
|
3
|
+
if (portInput === void 0) {
|
|
4
|
+
return 3e3;
|
|
5
|
+
}
|
|
6
|
+
return typeof portInput === "number" ? portInput : Number.parseInt(portInput, 10);
|
|
7
|
+
}
|
|
8
|
+
function fmtURL(host, port, ssl) {
|
|
9
|
+
if (!host || !port) {
|
|
10
|
+
return void 0;
|
|
11
|
+
}
|
|
12
|
+
if (host.includes(":")) {
|
|
13
|
+
host = `[${host}]`;
|
|
14
|
+
}
|
|
15
|
+
return `http${""}://${host}:${port}/`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { fmtURL as f, resolvePort as r };
|