@wooksjs/event-http 0.4.10 → 0.4.12
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 +148 -251
- package/dist/index.d.ts +519 -559
- package/dist/index.mjs +148 -251
- package/package.json +12 -4
package/dist/index.cjs
CHANGED
|
@@ -8,14 +8,13 @@ var http = require('http');
|
|
|
8
8
|
|
|
9
9
|
function createHttpContext(data, options) {
|
|
10
10
|
return eventCore.createEventContext({
|
|
11
|
-
event:
|
|
11
|
+
event: {
|
|
12
|
+
...data,
|
|
13
|
+
type: 'HTTP',
|
|
14
|
+
},
|
|
12
15
|
options,
|
|
13
16
|
});
|
|
14
17
|
}
|
|
15
|
-
/**
|
|
16
|
-
* Wrapper on useEventContext with HTTP event types
|
|
17
|
-
* @returns set of hooks { getCtx, restoreCtx, clearCtx, hookStore, getStore, setStore }
|
|
18
|
-
*/
|
|
19
18
|
function useHttpContext() {
|
|
20
19
|
return eventCore.useEventContext('HTTP');
|
|
21
20
|
}
|
|
@@ -42,20 +41,20 @@ function useRequest() {
|
|
|
42
41
|
});
|
|
43
42
|
const reqId = eventCore.useEventId().getId;
|
|
44
43
|
const forwardedIp = () => init('forwardedIp', () => {
|
|
45
|
-
var _a;
|
|
46
44
|
if (typeof req.headers[xForwardedFor] === 'string' &&
|
|
47
45
|
req.headers[xForwardedFor]) {
|
|
48
|
-
return
|
|
46
|
+
return req.headers[xForwardedFor]
|
|
49
47
|
.split(',')
|
|
50
|
-
.shift()
|
|
48
|
+
.shift()
|
|
49
|
+
?.trim();
|
|
51
50
|
}
|
|
52
51
|
else {
|
|
53
52
|
return '';
|
|
54
53
|
}
|
|
55
54
|
});
|
|
56
|
-
const remoteIp = () => init('remoteIp', () =>
|
|
55
|
+
const remoteIp = () => init('remoteIp', () => req.socket?.remoteAddress || req.connection?.remoteAddress || '');
|
|
57
56
|
function getIp(options) {
|
|
58
|
-
if (options
|
|
57
|
+
if (options?.trustProxy) {
|
|
59
58
|
return forwardedIp() || getIp();
|
|
60
59
|
}
|
|
61
60
|
else {
|
|
@@ -63,10 +62,9 @@ function useRequest() {
|
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
const getIpList = () => init('ipList', () => {
|
|
66
|
-
var _a, _b;
|
|
67
65
|
return {
|
|
68
|
-
remoteIp:
|
|
69
|
-
|
|
66
|
+
remoteIp: req.socket?.remoteAddress ||
|
|
67
|
+
req.connection?.remoteAddress ||
|
|
70
68
|
'',
|
|
71
69
|
forwarded: (req.headers[xForwardedFor] || '')
|
|
72
70
|
.split(',')
|
|
@@ -157,12 +155,12 @@ function useAuthorization() {
|
|
|
157
155
|
authorization,
|
|
158
156
|
authType,
|
|
159
157
|
authRawCredentials,
|
|
160
|
-
isBasic: () =>
|
|
161
|
-
isBearer: () =>
|
|
158
|
+
isBasic: () => authType()?.toLocaleLowerCase() === 'basic',
|
|
159
|
+
isBearer: () => authType()?.toLocaleLowerCase() === 'bearer',
|
|
162
160
|
basicCredentials: () => init('basicCredentials', () => {
|
|
163
161
|
if (authorization) {
|
|
164
162
|
const type = authType();
|
|
165
|
-
if (
|
|
163
|
+
if (type?.toLocaleLowerCase() === 'basic') {
|
|
166
164
|
const creds = Buffer.from(authRawCredentials() || '', 'base64').toString('ascii');
|
|
167
165
|
const [username, password] = creds.split(':');
|
|
168
166
|
return { username, password };
|
|
@@ -213,7 +211,6 @@ function renderCacheControl(data) {
|
|
|
213
211
|
}
|
|
214
212
|
return attrs;
|
|
215
213
|
}
|
|
216
|
-
// rfc7234#section-5.2.2
|
|
217
214
|
const cacheControlFunc = {
|
|
218
215
|
mustRevalidate: (v) => v ? 'must-revalidate' : '',
|
|
219
216
|
noCache: (v) => v ? (typeof v === 'string' ? `no-cache="${v}"` : 'no-cache') : '',
|
|
@@ -231,7 +228,6 @@ const renderExpires = (v) => typeof v === 'string' || typeof v === 'number'
|
|
|
231
228
|
? new Date(v).toUTCString()
|
|
232
229
|
: v.toUTCString();
|
|
233
230
|
const renderPragmaNoCache = (v) => (v ? 'no-cache' : '');
|
|
234
|
-
// rfc7234#section-5.2.2
|
|
235
231
|
function useSetCacheControl() {
|
|
236
232
|
const { setHeader } = useSetHeaders();
|
|
237
233
|
const setAge = (value) => {
|
|
@@ -375,12 +371,12 @@ function useSetCookie(name) {
|
|
|
375
371
|
name,
|
|
376
372
|
type: 'cookie',
|
|
377
373
|
}, {
|
|
378
|
-
get: () =>
|
|
379
|
-
set: (value) =>
|
|
374
|
+
get: () => getCookie(name)?.value,
|
|
375
|
+
set: (value) => setCookie(name, value, getCookie(name)?.attrs),
|
|
380
376
|
});
|
|
381
377
|
return eventCore.attachHook(valueHook, {
|
|
382
|
-
get: () =>
|
|
383
|
-
set: (attrs) =>
|
|
378
|
+
get: () => getCookie(name)?.attrs,
|
|
379
|
+
set: (attrs) => setCookie(name, getCookie(name)?.value || '', attrs),
|
|
384
380
|
}, 'attrs');
|
|
385
381
|
}
|
|
386
382
|
|
|
@@ -419,58 +415,6 @@ function useSearchParams() {
|
|
|
419
415
|
};
|
|
420
416
|
}
|
|
421
417
|
|
|
422
|
-
/******************************************************************************
|
|
423
|
-
Copyright (c) Microsoft Corporation.
|
|
424
|
-
|
|
425
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
426
|
-
purpose with or without fee is hereby granted.
|
|
427
|
-
|
|
428
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
429
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
430
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
431
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
432
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
433
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
434
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
435
|
-
***************************************************************************** */
|
|
436
|
-
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
440
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
441
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
442
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
443
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
444
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
445
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
function __values(o) {
|
|
450
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
451
|
-
if (m) return m.call(o);
|
|
452
|
-
if (o && typeof o.length === "number") return {
|
|
453
|
-
next: function () {
|
|
454
|
-
if (o && i >= o.length) o = void 0;
|
|
455
|
-
return { value: o && o[i++], done: !o };
|
|
456
|
-
}
|
|
457
|
-
};
|
|
458
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
function __asyncValues(o) {
|
|
462
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
463
|
-
var m = o[Symbol.asyncIterator], i;
|
|
464
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
465
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
466
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
470
|
-
var e = new Error(message);
|
|
471
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
472
|
-
};
|
|
473
|
-
|
|
474
418
|
class BaseHttpResponseRenderer {
|
|
475
419
|
render(response) {
|
|
476
420
|
if (typeof response.body === 'string' ||
|
|
@@ -702,7 +646,10 @@ class BaseHttpResponse {
|
|
|
702
646
|
for (const cookie of newCookies) {
|
|
703
647
|
removeCookie(cookie.slice(0, cookie.indexOf('=')));
|
|
704
648
|
}
|
|
705
|
-
this._headers =
|
|
649
|
+
this._headers = {
|
|
650
|
+
...headers(),
|
|
651
|
+
...this._headers,
|
|
652
|
+
};
|
|
706
653
|
const setCookie = [...newCookies, ...cookies()];
|
|
707
654
|
if (setCookie && setCookie.length) {
|
|
708
655
|
this._headers['set-cookie'] = setCookie;
|
|
@@ -727,96 +674,85 @@ class BaseHttpResponse {
|
|
|
727
674
|
logger.error(error);
|
|
728
675
|
throw error;
|
|
729
676
|
}
|
|
730
|
-
respond() {
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
677
|
+
async respond() {
|
|
678
|
+
const { rawResponse, hasResponded } = useResponse();
|
|
679
|
+
const { method, rawRequest } = useRequest();
|
|
680
|
+
const logger = eventCore.useEventLogger('http-response');
|
|
681
|
+
if (hasResponded()) {
|
|
682
|
+
this.panic('The response was already sent.', logger);
|
|
683
|
+
}
|
|
684
|
+
this.mergeHeaders();
|
|
685
|
+
const res = rawResponse();
|
|
686
|
+
if (this.body instanceof stream.Readable) {
|
|
687
|
+
const stream = this.body;
|
|
688
|
+
this.mergeStatus('ok');
|
|
689
|
+
res.writeHead(this.status, {
|
|
690
|
+
...this._headers,
|
|
691
|
+
});
|
|
692
|
+
rawRequest.once('close', () => {
|
|
693
|
+
stream.destroy();
|
|
694
|
+
});
|
|
695
|
+
if (method === 'HEAD') {
|
|
696
|
+
stream.destroy();
|
|
697
|
+
res.end();
|
|
737
698
|
}
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
res.writeHead(this.status, Object.assign({}, this._headers));
|
|
745
|
-
rawRequest.once('close', () => {
|
|
746
|
-
stream.destroy();
|
|
747
|
-
});
|
|
748
|
-
if (method === 'HEAD') {
|
|
749
|
-
stream.destroy();
|
|
750
|
-
res.end();
|
|
751
|
-
}
|
|
752
|
-
else {
|
|
753
|
-
return new Promise((resolve, reject) => {
|
|
754
|
-
stream.on('error', (e) => {
|
|
755
|
-
stream.destroy();
|
|
756
|
-
res.end();
|
|
757
|
-
reject(e);
|
|
758
|
-
});
|
|
759
|
-
stream.on('close', () => {
|
|
760
|
-
stream.destroy();
|
|
761
|
-
resolve(undefined);
|
|
762
|
-
});
|
|
763
|
-
stream.pipe(res);
|
|
699
|
+
else {
|
|
700
|
+
return new Promise((resolve, reject) => {
|
|
701
|
+
stream.on('error', (e) => {
|
|
702
|
+
stream.destroy();
|
|
703
|
+
res.end();
|
|
704
|
+
reject(e);
|
|
764
705
|
});
|
|
765
|
-
|
|
706
|
+
stream.on('close', () => {
|
|
707
|
+
stream.destroy();
|
|
708
|
+
resolve(undefined);
|
|
709
|
+
});
|
|
710
|
+
stream.pipe(res);
|
|
711
|
+
});
|
|
766
712
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
else {
|
|
774
|
-
const additionalHeaders = {};
|
|
775
|
-
if (this.body.headers.get('content-length')) {
|
|
776
|
-
additionalHeaders['content-length'] = this.body.headers.get('content-length');
|
|
777
|
-
}
|
|
778
|
-
if (this.body.headers.get('content-type')) {
|
|
779
|
-
additionalHeaders['content-type'] = this.body.headers.get('content-type');
|
|
780
|
-
}
|
|
781
|
-
res.writeHead(this.status, Object.assign(Object.assign({}, additionalHeaders), this._headers));
|
|
782
|
-
yield respondWithFetch(this.body.body, res);
|
|
783
|
-
}
|
|
713
|
+
}
|
|
714
|
+
else if (globalThis.Response &&
|
|
715
|
+
this.body instanceof Response) {
|
|
716
|
+
this.mergeFetchStatus(this.body.status);
|
|
717
|
+
if (method === 'HEAD') {
|
|
718
|
+
res.end();
|
|
784
719
|
}
|
|
785
720
|
else {
|
|
786
|
-
const
|
|
787
|
-
this.
|
|
788
|
-
|
|
789
|
-
}
|
|
790
|
-
});
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
function respondWithFetch(fetchBody, res) {
|
|
794
|
-
var _a, e_1, _b, _c;
|
|
795
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
796
|
-
if (fetchBody) {
|
|
797
|
-
try {
|
|
798
|
-
try {
|
|
799
|
-
for (var _d = true, _e = __asyncValues(fetchBody), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
|
|
800
|
-
_c = _f.value;
|
|
801
|
-
_d = false;
|
|
802
|
-
const chunk = _c;
|
|
803
|
-
res.write(chunk);
|
|
804
|
-
}
|
|
721
|
+
const additionalHeaders = {};
|
|
722
|
+
if (this.body.headers.get('content-length')) {
|
|
723
|
+
additionalHeaders['content-length'] = this.body.headers.get('content-length');
|
|
805
724
|
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
try {
|
|
809
|
-
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
810
|
-
}
|
|
811
|
-
finally { if (e_1) throw e_1.error; }
|
|
725
|
+
if (this.body.headers.get('content-type')) {
|
|
726
|
+
additionalHeaders['content-type'] = this.body.headers.get('content-type');
|
|
812
727
|
}
|
|
728
|
+
res.writeHead(this.status, {
|
|
729
|
+
...additionalHeaders,
|
|
730
|
+
...this._headers,
|
|
731
|
+
});
|
|
732
|
+
await respondWithFetch(this.body.body, res);
|
|
813
733
|
}
|
|
814
|
-
|
|
815
|
-
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
const renderedBody = this.renderer.render(this);
|
|
737
|
+
this.mergeStatus(renderedBody);
|
|
738
|
+
res.writeHead(this.status, {
|
|
739
|
+
'content-length': Buffer.byteLength(renderedBody),
|
|
740
|
+
...this._headers,
|
|
741
|
+
}).end(method !== 'HEAD' ? renderedBody : '');
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
async function respondWithFetch(fetchBody, res) {
|
|
746
|
+
if (fetchBody) {
|
|
747
|
+
try {
|
|
748
|
+
for await (const chunk of fetchBody) {
|
|
749
|
+
res.write(chunk);
|
|
816
750
|
}
|
|
817
751
|
}
|
|
818
|
-
|
|
819
|
-
|
|
752
|
+
catch (e) {
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
res.end();
|
|
820
756
|
}
|
|
821
757
|
|
|
822
758
|
const preStyles = 'font-family: monospace;' +
|
|
@@ -836,9 +772,14 @@ class HttpErrorRenderer extends BaseHttpResponseRenderer {
|
|
|
836
772
|
`<head><title>${data.statusCode} ${httpStatusCodes[data.statusCode]}</title></head>` +
|
|
837
773
|
`<body><center><h1>${data.statusCode} ${httpStatusCodes[data.statusCode]}</h1></center>` +
|
|
838
774
|
`<center><h4>${data.message}</h1></center><hr color="#666">` +
|
|
839
|
-
`<center style="color: #666;"> Wooks v${"0.4.
|
|
775
|
+
`<center style="color: #666;"> Wooks v${"0.4.12"} </center>` +
|
|
840
776
|
`${keys.length
|
|
841
|
-
? `<pre style="${preStyles}">${JSON.stringify(
|
|
777
|
+
? `<pre style="${preStyles}">${JSON.stringify({
|
|
778
|
+
...data,
|
|
779
|
+
statusCode: undefined,
|
|
780
|
+
message: undefined,
|
|
781
|
+
error: undefined,
|
|
782
|
+
}, null, ' ')}</pre>`
|
|
842
783
|
: ''}` +
|
|
843
784
|
'</body></html>');
|
|
844
785
|
}
|
|
@@ -848,7 +789,12 @@ class HttpErrorRenderer extends BaseHttpResponseRenderer {
|
|
|
848
789
|
const keys = Object.keys(data).filter((key) => !['statusCode', 'error', 'message'].includes(key));
|
|
849
790
|
return (`${data.statusCode} ${httpStatusCodes[data.statusCode]}\n${data.message}` +
|
|
850
791
|
`\n\n${keys.length
|
|
851
|
-
? `${JSON.stringify(
|
|
792
|
+
? `${JSON.stringify({
|
|
793
|
+
...data,
|
|
794
|
+
statusCode: undefined,
|
|
795
|
+
message: undefined,
|
|
796
|
+
error: undefined,
|
|
797
|
+
}, null, ' ')}`
|
|
852
798
|
: ''}`);
|
|
853
799
|
}
|
|
854
800
|
renderJson(response) {
|
|
@@ -866,9 +812,8 @@ class HttpErrorRenderer extends BaseHttpResponseRenderer {
|
|
|
866
812
|
: ''}}`);
|
|
867
813
|
}
|
|
868
814
|
render(response) {
|
|
869
|
-
var _a;
|
|
870
815
|
const { acceptsJson, acceptsText, acceptsHtml } = useAccept();
|
|
871
|
-
response.status =
|
|
816
|
+
response.status = response.body?.statusCode || 500;
|
|
872
817
|
if (acceptsJson()) {
|
|
873
818
|
return this.renderJson(response);
|
|
874
819
|
}
|
|
@@ -902,7 +847,12 @@ class HttpError extends Error {
|
|
|
902
847
|
message: this.message,
|
|
903
848
|
error: httpStatusCodes[this.code],
|
|
904
849
|
}
|
|
905
|
-
:
|
|
850
|
+
: {
|
|
851
|
+
...this._body,
|
|
852
|
+
statusCode: this.code,
|
|
853
|
+
message: this.message,
|
|
854
|
+
error: httpStatusCodes[this.code],
|
|
855
|
+
};
|
|
906
856
|
}
|
|
907
857
|
attachRenderer(renderer) {
|
|
908
858
|
this.renderer = renderer;
|
|
@@ -912,11 +862,7 @@ class HttpError extends Error {
|
|
|
912
862
|
}
|
|
913
863
|
}
|
|
914
864
|
|
|
915
|
-
function createWooksResponder(
|
|
916
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
917
|
-
renderer = new BaseHttpResponseRenderer(),
|
|
918
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
919
|
-
errorRenderer = new HttpErrorRenderer()) {
|
|
865
|
+
function createWooksResponder(renderer = new BaseHttpResponseRenderer(), errorRenderer = new HttpErrorRenderer()) {
|
|
920
866
|
function createResponse(data) {
|
|
921
867
|
const { hasResponded } = useResponse();
|
|
922
868
|
if (hasResponded())
|
|
@@ -942,16 +888,16 @@ errorRenderer = new HttpErrorRenderer()) {
|
|
|
942
888
|
}
|
|
943
889
|
return {
|
|
944
890
|
createResponse,
|
|
945
|
-
respond: (data) =>
|
|
891
|
+
respond: (data) => createResponse(data)?.respond(),
|
|
946
892
|
};
|
|
947
893
|
}
|
|
948
894
|
|
|
949
895
|
class WooksHttp extends wooks.WooksAdapterBase {
|
|
950
896
|
constructor(opts, wooks) {
|
|
951
|
-
super(wooks, opts
|
|
897
|
+
super(wooks, opts?.logger, opts?.router);
|
|
952
898
|
this.opts = opts;
|
|
953
899
|
this.responder = createWooksResponder();
|
|
954
|
-
this.logger =
|
|
900
|
+
this.logger = opts?.logger || this.getLogger('wooks-http');
|
|
955
901
|
}
|
|
956
902
|
all(path, handler) {
|
|
957
903
|
return this.on('*', path, handler);
|
|
@@ -977,80 +923,42 @@ class WooksHttp extends wooks.WooksAdapterBase {
|
|
|
977
923
|
options(path, handler) {
|
|
978
924
|
return this.on('OPTIONS', path, handler);
|
|
979
925
|
}
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
987
|
-
const server = (this.server = http.createServer(this.getServerCb()));
|
|
988
|
-
return new Promise((resolve, reject) => {
|
|
989
|
-
server.once('listening', resolve);
|
|
990
|
-
server.once('error', reject);
|
|
991
|
-
server.listen(...args);
|
|
992
|
-
});
|
|
926
|
+
async listen(...args) {
|
|
927
|
+
const server = (this.server = http.createServer(this.getServerCb()));
|
|
928
|
+
return new Promise((resolve, reject) => {
|
|
929
|
+
server.once('listening', resolve);
|
|
930
|
+
server.once('error', reject);
|
|
931
|
+
server.listen(...args);
|
|
993
932
|
});
|
|
994
933
|
}
|
|
995
|
-
/**
|
|
996
|
-
* Stops the server if it was attached or passed via argument
|
|
997
|
-
* @param server
|
|
998
|
-
*/
|
|
999
934
|
close(server) {
|
|
1000
935
|
const srv = server || this.server;
|
|
1001
936
|
return new Promise((resolve, reject) => {
|
|
1002
|
-
srv
|
|
937
|
+
srv?.close((err) => {
|
|
1003
938
|
if (err)
|
|
1004
939
|
return reject(err);
|
|
1005
940
|
resolve(srv);
|
|
1006
941
|
});
|
|
1007
942
|
});
|
|
1008
943
|
}
|
|
1009
|
-
/**
|
|
1010
|
-
* Returns http(s) server that was attached to Wooks
|
|
1011
|
-
*
|
|
1012
|
-
* See attachServer method docs
|
|
1013
|
-
* @returns Server
|
|
1014
|
-
*/
|
|
1015
944
|
getServer() {
|
|
1016
945
|
return this.server;
|
|
1017
946
|
}
|
|
1018
|
-
/**
|
|
1019
|
-
* Attaches http(s) server instance
|
|
1020
|
-
* to Wooks.
|
|
1021
|
-
*
|
|
1022
|
-
* Use it only if you want to `close` method to stop the server.
|
|
1023
|
-
* @param server Server
|
|
1024
|
-
*/
|
|
1025
947
|
attachServer(server) {
|
|
1026
948
|
this.server = server;
|
|
1027
949
|
}
|
|
1028
950
|
respond(data) {
|
|
1029
|
-
|
|
1030
|
-
void ((_a = this.responder.respond(data)) === null || _a === void 0 ? void 0 : _a.catch((e) => {
|
|
951
|
+
void this.responder.respond(data)?.catch((e) => {
|
|
1031
952
|
this.logger.error('Uncought response exception', e);
|
|
1032
|
-
})
|
|
953
|
+
});
|
|
1033
954
|
}
|
|
1034
|
-
/**
|
|
1035
|
-
* Returns server callback function
|
|
1036
|
-
* that can be passed to any node server:
|
|
1037
|
-
* ```js
|
|
1038
|
-
* import { createHttpApp } from '@wooksjs/event-http'
|
|
1039
|
-
* import http from 'http'
|
|
1040
|
-
*
|
|
1041
|
-
* const app = createHttpApp()
|
|
1042
|
-
* const server = http.createServer(app.getServerCb())
|
|
1043
|
-
* server.listen(3000)
|
|
1044
|
-
* ```
|
|
1045
|
-
*/
|
|
1046
955
|
getServerCb() {
|
|
1047
|
-
return (req, res) =>
|
|
1048
|
-
|
|
1049
|
-
const { restoreCtx, clearCtx } = createHttpContext({ req, res }, this.mergeEventOptions((_a = this.opts) === null || _a === void 0 ? void 0 : _a.eventOptions));
|
|
956
|
+
return async (req, res) => {
|
|
957
|
+
const { restoreCtx, clearCtx } = createHttpContext({ req, res }, this.mergeEventOptions(this.opts?.eventOptions));
|
|
1050
958
|
const { handlers } = this.wooks.lookup(req.method, req.url);
|
|
1051
|
-
if (handlers ||
|
|
959
|
+
if (handlers || this.opts?.onNotFound) {
|
|
1052
960
|
try {
|
|
1053
|
-
|
|
961
|
+
await this.processHandlers(handlers || [this.opts?.onNotFound]);
|
|
1054
962
|
}
|
|
1055
963
|
catch (e) {
|
|
1056
964
|
this.logger.error('Internal error, please report', e);
|
|
@@ -1060,48 +968,37 @@ class WooksHttp extends wooks.WooksAdapterBase {
|
|
|
1060
968
|
}
|
|
1061
969
|
}
|
|
1062
970
|
else {
|
|
1063
|
-
// not found
|
|
1064
971
|
this.logger.debug(`404 Not found (${req.method})${req.url}`);
|
|
1065
972
|
this.respond(new HttpError(404));
|
|
1066
973
|
clearCtx();
|
|
1067
974
|
}
|
|
1068
|
-
}
|
|
975
|
+
};
|
|
1069
976
|
}
|
|
1070
|
-
processHandlers(handlers) {
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
977
|
+
async processHandlers(handlers) {
|
|
978
|
+
const { restoreCtx, clearCtx, store } = useHttpContext();
|
|
979
|
+
for (const [i, handler] of handlers.entries()) {
|
|
980
|
+
const isLastHandler = handlers.length === i + 1;
|
|
981
|
+
try {
|
|
982
|
+
restoreCtx();
|
|
983
|
+
const promise = handler();
|
|
984
|
+
clearCtx();
|
|
985
|
+
const result = await promise;
|
|
986
|
+
restoreCtx();
|
|
987
|
+
this.respond(result);
|
|
988
|
+
clearCtx();
|
|
989
|
+
break;
|
|
990
|
+
}
|
|
991
|
+
catch (e) {
|
|
992
|
+
this.logger.error(`Uncought route handler exception: ${store('event').get('req').url || ''}`, e);
|
|
993
|
+
if (isLastHandler) {
|
|
1082
994
|
restoreCtx();
|
|
1083
|
-
this.respond(
|
|
995
|
+
this.respond(e);
|
|
1084
996
|
clearCtx();
|
|
1085
|
-
break;
|
|
1086
|
-
}
|
|
1087
|
-
catch (e) {
|
|
1088
|
-
this.logger.error(`Uncought route handler exception: ${store('event').get('req').url || ''}`, e);
|
|
1089
|
-
if (isLastHandler) {
|
|
1090
|
-
restoreCtx();
|
|
1091
|
-
this.respond(e);
|
|
1092
|
-
clearCtx();
|
|
1093
|
-
}
|
|
1094
997
|
}
|
|
1095
998
|
}
|
|
1096
|
-
}
|
|
999
|
+
}
|
|
1097
1000
|
}
|
|
1098
1001
|
}
|
|
1099
|
-
/**
|
|
1100
|
-
* Factory for WooksHttp App
|
|
1101
|
-
* @param opts TWooksHttpOptions
|
|
1102
|
-
* @param wooks Wooks | WooksAdapterBase
|
|
1103
|
-
* @returns WooksHttp
|
|
1104
|
-
*/
|
|
1105
1002
|
function createHttpApp(opts, wooks) {
|
|
1106
1003
|
return new WooksHttp(opts, wooks);
|
|
1107
1004
|
}
|