routup 3.0.0 → 3.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/README.md +10 -8
- package/dist/adapters/node/module.d.ts +7 -0
- package/dist/{utils → adapters/raw}/header.d.ts +1 -1
- package/dist/{layer → adapters/raw}/index.d.ts +1 -1
- package/dist/adapters/raw/module.d.ts +4 -0
- package/dist/{dispatcher/adapters → adapters}/raw/type.d.ts +1 -1
- package/dist/adapters/web/module.d.ts +4 -0
- package/dist/constants.d.ts +7 -7
- package/dist/dispatcher/event/dispatch.d.ts +4 -0
- package/dist/dispatcher/event/error.d.ts +5 -0
- package/dist/dispatcher/event/index.d.ts +5 -0
- package/dist/dispatcher/event/is.d.ts +3 -0
- package/dist/dispatcher/event/module.d.ts +56 -0
- package/dist/dispatcher/event/types.d.ts +9 -0
- package/dist/dispatcher/index.d.ts +1 -2
- package/dist/dispatcher/type.d.ts +2 -30
- package/dist/error/create.d.ts +3 -3
- package/dist/error/is.d.ts +2 -2
- package/dist/error/module.d.ts +1 -1
- package/dist/handler/constants.d.ts +1 -0
- package/dist/handler/core/define.d.ts +4 -3
- package/dist/handler/core/types.d.ts +3 -3
- package/dist/handler/error/define.d.ts +4 -3
- package/dist/handler/error/types.d.ts +5 -5
- package/dist/handler/index.d.ts +1 -0
- package/dist/handler/is.d.ts +3 -1
- package/dist/handler/module.d.ts +23 -0
- package/dist/handler/types-base.d.ts +6 -2
- package/dist/handler/types.d.ts +3 -4
- package/dist/hook/constants.d.ts +8 -0
- package/dist/hook/index.d.ts +3 -0
- package/dist/hook/module.d.ts +19 -0
- package/dist/hook/types.d.ts +5 -0
- package/dist/index.cjs +701 -450
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +692 -443
- package/dist/index.mjs.map +1 -1
- package/dist/response/helpers/send-web-blob.d.ts +1 -1
- package/dist/response/helpers/send-web-response.d.ts +1 -1
- package/dist/router/constants.d.ts +8 -0
- package/dist/router/index.d.ts +0 -1
- package/dist/router/module.d.ts +56 -24
- package/dist/router/types.d.ts +7 -0
- package/dist/types.d.ts +1 -0
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/method.d.ts +3 -0
- package/dist/utils/next.d.ts +2 -0
- package/package.json +15 -15
- package/dist/dispatcher/adapters/node/module.d.ts +0 -7
- package/dist/dispatcher/adapters/raw/module.d.ts +0 -4
- package/dist/dispatcher/adapters/web/index.d.ts +0 -2
- package/dist/dispatcher/adapters/web/module.d.ts +0 -5
- package/dist/dispatcher/utils.d.ts +0 -5
- package/dist/layer/constants.d.ts +0 -1
- package/dist/layer/module.d.ts +0 -17
- package/dist/layer/type.d.ts +0 -8
- package/dist/layer/utils.d.ts +0 -2
- /package/dist/{dispatcher/adapters → adapters}/index.d.ts +0 -0
- /package/dist/{dispatcher/adapters → adapters}/node/index.d.ts +0 -0
- /package/dist/{dispatcher/adapters/raw → adapters/web}/index.d.ts +0 -0
- /package/dist/{dispatcher/adapters → adapters}/web/type.d.ts +0 -0
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var http = require('@ebec/http');
|
|
4
3
|
var smob = require('smob');
|
|
5
4
|
var buffer = require('buffer');
|
|
6
5
|
var uncrypto = require('uncrypto');
|
|
@@ -8,17 +7,18 @@ var proxyAddr = require('proxy-addr');
|
|
|
8
7
|
var mimeExplorer = require('mime-explorer');
|
|
9
8
|
var Negotiator = require('negotiator');
|
|
10
9
|
var readableStream = require('readable-stream');
|
|
10
|
+
var http = require('@ebec/http');
|
|
11
11
|
var pathToRegexp = require('path-to-regexp');
|
|
12
12
|
|
|
13
13
|
exports.MethodName = void 0;
|
|
14
14
|
(function(MethodName) {
|
|
15
|
-
MethodName["GET"] = "
|
|
16
|
-
MethodName["POST"] = "
|
|
17
|
-
MethodName["PUT"] = "
|
|
18
|
-
MethodName["PATCH"] = "
|
|
19
|
-
MethodName["DELETE"] = "
|
|
20
|
-
MethodName["OPTIONS"] = "
|
|
21
|
-
MethodName["HEAD"] = "
|
|
15
|
+
MethodName["GET"] = "GET";
|
|
16
|
+
MethodName["POST"] = "POST";
|
|
17
|
+
MethodName["PUT"] = "PUT";
|
|
18
|
+
MethodName["PATCH"] = "PATCH";
|
|
19
|
+
MethodName["DELETE"] = "DELETE";
|
|
20
|
+
MethodName["OPTIONS"] = "OPTIONS";
|
|
21
|
+
MethodName["HEAD"] = "HEAD";
|
|
22
22
|
})(exports.MethodName || (exports.MethodName = {}));
|
|
23
23
|
exports.HeaderName = void 0;
|
|
24
24
|
(function(HeaderName) {
|
|
@@ -53,32 +53,6 @@ exports.HeaderName = void 0;
|
|
|
53
53
|
HeaderName["X_FORWARDED_PROTO"] = "x-forwarded-proto";
|
|
54
54
|
})(exports.HeaderName || (exports.HeaderName = {}));
|
|
55
55
|
|
|
56
|
-
class ErrorProxy extends http.HTTPError {
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function isError(input) {
|
|
60
|
-
return input instanceof ErrorProxy;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Create an error proxy by
|
|
65
|
-
* - an existing error (accessible via cause property)
|
|
66
|
-
* - options
|
|
67
|
-
* - message
|
|
68
|
-
*
|
|
69
|
-
* @param input
|
|
70
|
-
*/ function createError(input) {
|
|
71
|
-
if (isError(input)) {
|
|
72
|
-
return input;
|
|
73
|
-
}
|
|
74
|
-
if (typeof input === 'string') {
|
|
75
|
-
return new ErrorProxy(input);
|
|
76
|
-
}
|
|
77
|
-
return new ErrorProxy({
|
|
78
|
-
cause: input
|
|
79
|
-
}, input);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
56
|
function isRequestCacheable(req, modifiedTime) {
|
|
83
57
|
const modifiedSince = req.headers[exports.HeaderName.IF_MODIFIED_SINCE];
|
|
84
58
|
if (!modifiedSince) {
|
|
@@ -209,33 +183,6 @@ function setRequestHeader(req, name, value) {
|
|
|
209
183
|
return cookiesStrings;
|
|
210
184
|
}
|
|
211
185
|
|
|
212
|
-
function transformHeaderToTuples(key, value) {
|
|
213
|
-
const output = [];
|
|
214
|
-
if (Array.isArray(value)) {
|
|
215
|
-
for(let j = 0; j < value.length; j++){
|
|
216
|
-
output.push([
|
|
217
|
-
key,
|
|
218
|
-
value[j]
|
|
219
|
-
]);
|
|
220
|
-
}
|
|
221
|
-
} else if (value !== undefined) {
|
|
222
|
-
output.push([
|
|
223
|
-
key,
|
|
224
|
-
String(value)
|
|
225
|
-
]);
|
|
226
|
-
}
|
|
227
|
-
return output;
|
|
228
|
-
}
|
|
229
|
-
function transformHeadersToTuples(input) {
|
|
230
|
-
const output = [];
|
|
231
|
-
const keys = Object.keys(input);
|
|
232
|
-
for(let i = 0; i < keys.length; i++){
|
|
233
|
-
const key = keys[i].toLowerCase();
|
|
234
|
-
output.push(...transformHeaderToTuples(key, input[key]));
|
|
235
|
-
}
|
|
236
|
-
return output;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
186
|
function isObject(item) {
|
|
240
187
|
return !!item && typeof item === 'object' && !Array.isArray(item);
|
|
241
188
|
}
|
|
@@ -348,6 +295,15 @@ function getCharsetForMimeType(type) {
|
|
|
348
295
|
return undefined;
|
|
349
296
|
}
|
|
350
297
|
|
|
298
|
+
function toMethodName(input, alt) {
|
|
299
|
+
if (input) {
|
|
300
|
+
return input.toUpperCase();
|
|
301
|
+
}
|
|
302
|
+
return alt;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const nextPlaceholder = (_err)=>{};
|
|
306
|
+
|
|
351
307
|
/**
|
|
352
308
|
* Based on https://github.com/unjs/pathe v1.1.1 (055f50a6f1131f4e5c56cf259dd8816168fba329)
|
|
353
309
|
*/ function normalizeWindowsPath(input = '') {
|
|
@@ -751,6 +707,35 @@ function createRequest(context) {
|
|
|
751
707
|
return readable;
|
|
752
708
|
}
|
|
753
709
|
|
|
710
|
+
class RoutupError extends http.HTTPError {
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
function isError(input) {
|
|
714
|
+
return input instanceof RoutupError;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Create an internal error object by
|
|
719
|
+
* - an existing error (accessible via cause property)
|
|
720
|
+
* - options
|
|
721
|
+
* - message
|
|
722
|
+
*
|
|
723
|
+
* @param input
|
|
724
|
+
*/ function createError(input) {
|
|
725
|
+
if (isError(input)) {
|
|
726
|
+
return input;
|
|
727
|
+
}
|
|
728
|
+
if (typeof input === 'string') {
|
|
729
|
+
return new RoutupError(input);
|
|
730
|
+
}
|
|
731
|
+
if (!isObject(input)) {
|
|
732
|
+
return new RoutupError();
|
|
733
|
+
}
|
|
734
|
+
return new RoutupError({
|
|
735
|
+
cause: input
|
|
736
|
+
}, input);
|
|
737
|
+
}
|
|
738
|
+
|
|
754
739
|
function setResponseCacheHeaders(res, options) {
|
|
755
740
|
options = options || {};
|
|
756
741
|
const cacheControls = [
|
|
@@ -859,6 +844,78 @@ function setResponseHeaderContentType(res, input, ifNotExists) {
|
|
|
859
844
|
}
|
|
860
845
|
}
|
|
861
846
|
|
|
847
|
+
async function sendStream(res, stream, next) {
|
|
848
|
+
if (isWebStream(stream)) {
|
|
849
|
+
return stream.pipeTo(new WritableStream({
|
|
850
|
+
write (chunk) {
|
|
851
|
+
res.write(chunk);
|
|
852
|
+
}
|
|
853
|
+
})).then(()=>{
|
|
854
|
+
if (next) {
|
|
855
|
+
return next();
|
|
856
|
+
}
|
|
857
|
+
res.end();
|
|
858
|
+
return Promise.resolve();
|
|
859
|
+
}).catch((err)=>{
|
|
860
|
+
if (next) {
|
|
861
|
+
return next(err);
|
|
862
|
+
}
|
|
863
|
+
return Promise.reject(err);
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
return new Promise((resolve, reject)=>{
|
|
867
|
+
stream.on('open', ()=>{
|
|
868
|
+
stream.pipe(res);
|
|
869
|
+
});
|
|
870
|
+
/* istanbul ignore next */ stream.on('error', (err)=>{
|
|
871
|
+
if (next) {
|
|
872
|
+
Promise.resolve().then(()=>next(err)).then(()=>resolve()).catch((e)=>reject(e));
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
res.end();
|
|
876
|
+
reject(err);
|
|
877
|
+
});
|
|
878
|
+
stream.on('close', ()=>{
|
|
879
|
+
if (next) {
|
|
880
|
+
Promise.resolve().then(()=>next()).then(()=>resolve()).catch((e)=>reject(e));
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
res.end();
|
|
884
|
+
resolve();
|
|
885
|
+
});
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
async function sendWebBlob(res, blob) {
|
|
890
|
+
setResponseHeaderContentType(res, blob.type);
|
|
891
|
+
await sendStream(res, blob.stream());
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
async function sendWebResponse(res, webResponse) {
|
|
895
|
+
if (webResponse.redirected) {
|
|
896
|
+
res.setHeader(exports.HeaderName.LOCATION, webResponse.url);
|
|
897
|
+
}
|
|
898
|
+
if (webResponse.status) {
|
|
899
|
+
res.statusCode = webResponse.status;
|
|
900
|
+
}
|
|
901
|
+
if (webResponse.statusText) {
|
|
902
|
+
res.statusMessage = webResponse.statusText;
|
|
903
|
+
}
|
|
904
|
+
webResponse.headers.forEach((value, key)=>{
|
|
905
|
+
if (key === exports.HeaderName.SET_COOKIE) {
|
|
906
|
+
res.appendHeader(key, splitCookiesString(value));
|
|
907
|
+
} else {
|
|
908
|
+
res.setHeader(key, value);
|
|
909
|
+
}
|
|
910
|
+
});
|
|
911
|
+
if (webResponse.body) {
|
|
912
|
+
await sendStream(res, webResponse.body);
|
|
913
|
+
return Promise.resolve();
|
|
914
|
+
}
|
|
915
|
+
res.end();
|
|
916
|
+
return Promise.resolve();
|
|
917
|
+
}
|
|
918
|
+
|
|
862
919
|
async function send(res, chunk) {
|
|
863
920
|
switch(typeof chunk){
|
|
864
921
|
case 'string':
|
|
@@ -870,11 +927,28 @@ async function send(res, chunk) {
|
|
|
870
927
|
case 'number':
|
|
871
928
|
case 'object':
|
|
872
929
|
{
|
|
873
|
-
if (
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
930
|
+
if (chunk !== null) {
|
|
931
|
+
if (chunk instanceof Error) {
|
|
932
|
+
throw chunk;
|
|
933
|
+
}
|
|
934
|
+
if (isStream(chunk)) {
|
|
935
|
+
await sendStream(res, chunk);
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
938
|
+
if (isWebBlob(chunk)) {
|
|
939
|
+
await sendWebBlob(res, chunk);
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
if (isWebResponse(chunk)) {
|
|
943
|
+
await sendWebResponse(res, chunk);
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
if (buffer.Buffer.isBuffer(chunk)) {
|
|
947
|
+
setResponseHeaderContentType(res, 'bin', true);
|
|
948
|
+
} else {
|
|
949
|
+
chunk = JSON.stringify(chunk);
|
|
950
|
+
setResponseHeaderContentType(res, 'application/json', true);
|
|
951
|
+
}
|
|
878
952
|
}
|
|
879
953
|
break;
|
|
880
954
|
}
|
|
@@ -906,7 +980,7 @@ async function send(res, chunk) {
|
|
|
906
980
|
const etagFn = findRouterOption('etag', useRequestRouterPath(res.req));
|
|
907
981
|
const chunkHash = await etagFn(chunk, encoding, len);
|
|
908
982
|
if (isResponseGone(res)) {
|
|
909
|
-
return
|
|
983
|
+
return;
|
|
910
984
|
}
|
|
911
985
|
if (typeof chunkHash === 'string') {
|
|
912
986
|
res.setHeader(exports.HeaderName.ETag, chunkHash);
|
|
@@ -927,23 +1001,22 @@ async function send(res, chunk) {
|
|
|
927
1001
|
res.removeHeader(exports.HeaderName.TRANSFER_ENCODING);
|
|
928
1002
|
}
|
|
929
1003
|
if (isResponseGone(res)) {
|
|
930
|
-
return
|
|
1004
|
+
return;
|
|
931
1005
|
}
|
|
932
|
-
if (res.req.method === 'HEAD') {
|
|
1006
|
+
if (res.req.method === 'HEAD' || res.req.method === 'head') {
|
|
933
1007
|
// skip body for HEAD
|
|
934
1008
|
res.end();
|
|
935
|
-
return
|
|
1009
|
+
return;
|
|
936
1010
|
}
|
|
937
1011
|
if (typeof chunk === 'undefined' || chunk === null) {
|
|
938
1012
|
res.end();
|
|
939
|
-
return
|
|
1013
|
+
return;
|
|
940
1014
|
}
|
|
941
1015
|
if (typeof encoding !== 'undefined') {
|
|
942
1016
|
res.end(chunk, encoding);
|
|
943
|
-
return
|
|
1017
|
+
return;
|
|
944
1018
|
}
|
|
945
1019
|
res.end(chunk);
|
|
946
|
-
return Promise.resolve();
|
|
947
1020
|
}
|
|
948
1021
|
|
|
949
1022
|
function sendAccepted(res, chunk) {
|
|
@@ -958,48 +1031,6 @@ function sendCreated(res, chunk) {
|
|
|
958
1031
|
return send(res, chunk);
|
|
959
1032
|
}
|
|
960
1033
|
|
|
961
|
-
async function sendStream(res, stream, next) {
|
|
962
|
-
if (isWebStream(stream)) {
|
|
963
|
-
return stream.pipeTo(new WritableStream({
|
|
964
|
-
write (chunk) {
|
|
965
|
-
res.write(chunk);
|
|
966
|
-
}
|
|
967
|
-
})).then(()=>{
|
|
968
|
-
if (next) {
|
|
969
|
-
return next();
|
|
970
|
-
}
|
|
971
|
-
res.end();
|
|
972
|
-
return Promise.resolve();
|
|
973
|
-
}).catch((err)=>{
|
|
974
|
-
if (next) {
|
|
975
|
-
return next(err);
|
|
976
|
-
}
|
|
977
|
-
return Promise.reject(err);
|
|
978
|
-
});
|
|
979
|
-
}
|
|
980
|
-
return new Promise((resolve, reject)=>{
|
|
981
|
-
stream.on('open', ()=>{
|
|
982
|
-
stream.pipe(res);
|
|
983
|
-
});
|
|
984
|
-
/* istanbul ignore next */ stream.on('error', (err)=>{
|
|
985
|
-
if (next) {
|
|
986
|
-
Promise.resolve().then(()=>next(err)).then(()=>resolve()).catch((e)=>reject(e));
|
|
987
|
-
return;
|
|
988
|
-
}
|
|
989
|
-
res.end();
|
|
990
|
-
reject(err);
|
|
991
|
-
});
|
|
992
|
-
stream.on('close', ()=>{
|
|
993
|
-
if (next) {
|
|
994
|
-
Promise.resolve().then(()=>next()).then(()=>resolve()).catch((e)=>reject(e));
|
|
995
|
-
return;
|
|
996
|
-
}
|
|
997
|
-
res.end();
|
|
998
|
-
resolve();
|
|
999
|
-
});
|
|
1000
|
-
});
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
1034
|
async function sendFile(res, options, next) {
|
|
1004
1035
|
let stats;
|
|
1005
1036
|
try {
|
|
@@ -1089,35 +1120,6 @@ function sendRedirect(res, location, statusCode = 302) {
|
|
|
1089
1120
|
return send(res, html);
|
|
1090
1121
|
}
|
|
1091
1122
|
|
|
1092
|
-
function sendWebResponse(res, webResponse) {
|
|
1093
|
-
if (webResponse.redirected) {
|
|
1094
|
-
res.setHeader(exports.HeaderName.LOCATION, webResponse.url);
|
|
1095
|
-
}
|
|
1096
|
-
if (webResponse.status) {
|
|
1097
|
-
res.statusCode = webResponse.status;
|
|
1098
|
-
}
|
|
1099
|
-
if (webResponse.statusText) {
|
|
1100
|
-
res.statusMessage = webResponse.statusText;
|
|
1101
|
-
}
|
|
1102
|
-
webResponse.headers.forEach((value, key)=>{
|
|
1103
|
-
if (key === exports.HeaderName.SET_COOKIE) {
|
|
1104
|
-
res.appendHeader(key, splitCookiesString(value));
|
|
1105
|
-
} else {
|
|
1106
|
-
res.setHeader(key, value);
|
|
1107
|
-
}
|
|
1108
|
-
});
|
|
1109
|
-
if (webResponse.body) {
|
|
1110
|
-
return sendStream(res, webResponse.body);
|
|
1111
|
-
}
|
|
1112
|
-
res.end();
|
|
1113
|
-
return Promise.resolve();
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
function sendWebBlob(res, blob) {
|
|
1117
|
-
setResponseHeaderContentType(res, blob.type);
|
|
1118
|
-
return sendStream(res, blob.stream());
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
1123
|
function createResponse(request) {
|
|
1122
1124
|
let output;
|
|
1123
1125
|
let encoding;
|
|
@@ -1263,84 +1265,112 @@ function createResponse(request) {
|
|
|
1263
1265
|
return writable;
|
|
1264
1266
|
}
|
|
1265
1267
|
|
|
1266
|
-
function
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1268
|
+
function dispatch(event, target) {
|
|
1269
|
+
setRequestParams(event.request, event.params);
|
|
1270
|
+
setRequestMountPath(event.request, event.mountPath);
|
|
1271
|
+
setRequestRouterPath(event.request, event.routerPath);
|
|
1272
|
+
return new Promise((resolve, reject)=>{
|
|
1273
|
+
let handled = false;
|
|
1274
|
+
const unsubscribe = ()=>{
|
|
1275
|
+
event.response.off('close', done);
|
|
1276
|
+
event.response.off('error', done);
|
|
1277
|
+
};
|
|
1278
|
+
const shutdown = (dispatched, err)=>{
|
|
1279
|
+
if (handled) {
|
|
1280
|
+
return;
|
|
1281
|
+
}
|
|
1282
|
+
handled = true;
|
|
1283
|
+
unsubscribe();
|
|
1284
|
+
if (err) {
|
|
1285
|
+
reject(createError(err));
|
|
1286
|
+
} else {
|
|
1287
|
+
resolve(dispatched);
|
|
1288
|
+
}
|
|
1289
|
+
};
|
|
1290
|
+
const done = (err)=>shutdown(true, err);
|
|
1291
|
+
const next = (err)=>shutdown(false, err);
|
|
1292
|
+
event.response.once('close', done);
|
|
1293
|
+
event.response.once('error', done);
|
|
1294
|
+
const handle = async (data)=>{
|
|
1295
|
+
if (typeof data === 'undefined' || handled) {
|
|
1296
|
+
return false;
|
|
1297
|
+
}
|
|
1298
|
+
handled = true;
|
|
1299
|
+
unsubscribe();
|
|
1300
|
+
if (!event.dispatched) {
|
|
1301
|
+
await send(event.response, data);
|
|
1302
|
+
}
|
|
1303
|
+
return true;
|
|
1304
|
+
};
|
|
1305
|
+
try {
|
|
1306
|
+
const output = target(next);
|
|
1307
|
+
if (isPromise(output)) {
|
|
1308
|
+
output.then((r)=>handle(r)).then((resolved)=>{
|
|
1309
|
+
if (resolved) {
|
|
1310
|
+
resolve(true);
|
|
1311
|
+
}
|
|
1312
|
+
}).catch((e)=>reject(createError(e)));
|
|
1313
|
+
return;
|
|
1314
|
+
}
|
|
1315
|
+
Promise.resolve().then(()=>handle(output)).then((resolved)=>{
|
|
1316
|
+
if (resolved) {
|
|
1317
|
+
resolve(true);
|
|
1318
|
+
}
|
|
1319
|
+
}).catch((e)=>reject(createError(e)));
|
|
1320
|
+
} catch (error) {
|
|
1321
|
+
next(error);
|
|
1322
|
+
}
|
|
1323
|
+
});
|
|
1273
1324
|
}
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
mountPath: input.mountPath,
|
|
1278
|
-
error: input.error,
|
|
1279
|
-
routerPath: [
|
|
1280
|
-
...input.routerPath
|
|
1281
|
-
],
|
|
1282
|
-
params: cloneDispatcherMetaParams(input.params)
|
|
1283
|
-
};
|
|
1325
|
+
|
|
1326
|
+
function isDispatcherErrorEvent(event) {
|
|
1327
|
+
return typeof event.error !== 'undefined';
|
|
1284
1328
|
}
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1329
|
+
|
|
1330
|
+
class DispatchEvent {
|
|
1331
|
+
get dispatched() {
|
|
1332
|
+
return this._dispatched || this.response.writableEnded || this.response.headersSent;
|
|
1288
1333
|
}
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
return {};
|
|
1334
|
+
set dispatched(value) {
|
|
1335
|
+
this._dispatched = value;
|
|
1292
1336
|
}
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1337
|
+
constructor(context){
|
|
1338
|
+
this.request = context.request;
|
|
1339
|
+
this.response = context.response;
|
|
1340
|
+
this.method = context.method || exports.MethodName.GET;
|
|
1341
|
+
this.methodsAllowed = [];
|
|
1342
|
+
this.mountPath = '/';
|
|
1343
|
+
this.params = {};
|
|
1344
|
+
this.path = context.path || '/';
|
|
1345
|
+
this.routerPath = [];
|
|
1346
|
+
this.next = nextPlaceholder;
|
|
1296
1347
|
}
|
|
1297
|
-
return output;
|
|
1298
1348
|
}
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
return {};
|
|
1302
|
-
}
|
|
1303
|
-
if (!t1 || !t2) {
|
|
1304
|
-
return t1 || t2;
|
|
1305
|
-
}
|
|
1306
|
-
const keys = Object.keys(t2);
|
|
1307
|
-
if (keys.length === 0) {
|
|
1308
|
-
return t1;
|
|
1309
|
-
}
|
|
1310
|
-
for(let i = 0; i < keys.length; i++){
|
|
1311
|
-
t1[keys[i]] = t2[keys[i]];
|
|
1312
|
-
}
|
|
1313
|
-
return t1;
|
|
1349
|
+
|
|
1350
|
+
class DispatchErrorEvent extends DispatchEvent {
|
|
1314
1351
|
}
|
|
1315
1352
|
|
|
1316
|
-
async function dispatchNodeRequest(router,
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
} catch (e) {
|
|
1332
|
-
if (!isResponseGone(res)) {
|
|
1333
|
-
if (isError(e)) {
|
|
1334
|
-
res.statusCode = e.statusCode;
|
|
1335
|
-
if (e.statusMessage) {
|
|
1336
|
-
res.statusMessage = e.statusMessage;
|
|
1337
|
-
}
|
|
1338
|
-
} else {
|
|
1339
|
-
res.statusCode = 500;
|
|
1340
|
-
}
|
|
1341
|
-
res.end();
|
|
1353
|
+
async function dispatchNodeRequest(router, request, response) {
|
|
1354
|
+
const event = new DispatchEvent({
|
|
1355
|
+
request,
|
|
1356
|
+
response,
|
|
1357
|
+
path: useRequestPath(request),
|
|
1358
|
+
method: toMethodName(request.method, exports.MethodName.GET)
|
|
1359
|
+
});
|
|
1360
|
+
await router.dispatch(event);
|
|
1361
|
+
if (event.dispatched) {
|
|
1362
|
+
return;
|
|
1363
|
+
}
|
|
1364
|
+
if (event.error) {
|
|
1365
|
+
event.response.statusCode = event.error.statusCode;
|
|
1366
|
+
if (event.error.statusMessage) {
|
|
1367
|
+
event.response.statusMessage = event.error.statusMessage;
|
|
1342
1368
|
}
|
|
1369
|
+
event.response.end();
|
|
1370
|
+
return;
|
|
1343
1371
|
}
|
|
1372
|
+
event.response.statusCode = 404;
|
|
1373
|
+
event.response.end();
|
|
1344
1374
|
}
|
|
1345
1375
|
function createNodeDispatcher(router) {
|
|
1346
1376
|
return (req, res)=>{
|
|
@@ -1349,10 +1379,38 @@ function createNodeDispatcher(router) {
|
|
|
1349
1379
|
};
|
|
1350
1380
|
}
|
|
1351
1381
|
|
|
1352
|
-
|
|
1382
|
+
function transformHeaderToTuples(key, value) {
|
|
1383
|
+
const output = [];
|
|
1384
|
+
if (Array.isArray(value)) {
|
|
1385
|
+
for(let j = 0; j < value.length; j++){
|
|
1386
|
+
output.push([
|
|
1387
|
+
key,
|
|
1388
|
+
value[j]
|
|
1389
|
+
]);
|
|
1390
|
+
}
|
|
1391
|
+
} else if (value !== undefined) {
|
|
1392
|
+
output.push([
|
|
1393
|
+
key,
|
|
1394
|
+
String(value)
|
|
1395
|
+
]);
|
|
1396
|
+
}
|
|
1397
|
+
return output;
|
|
1398
|
+
}
|
|
1399
|
+
function transformHeadersToTuples(input) {
|
|
1400
|
+
const output = [];
|
|
1401
|
+
const keys = Object.keys(input);
|
|
1402
|
+
for(let i = 0; i < keys.length; i++){
|
|
1403
|
+
const key = keys[i].toLowerCase();
|
|
1404
|
+
output.push(...transformHeaderToTuples(key, input[key]));
|
|
1405
|
+
}
|
|
1406
|
+
return output;
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
async function dispatchRawRequest(router, request) {
|
|
1410
|
+
const method = toMethodName(request.method, exports.MethodName.GET);
|
|
1353
1411
|
const req = createRequest({
|
|
1354
1412
|
url: request.path,
|
|
1355
|
-
method
|
|
1413
|
+
method,
|
|
1356
1414
|
body: request.body,
|
|
1357
1415
|
headers: request.headers
|
|
1358
1416
|
});
|
|
@@ -1377,52 +1435,45 @@ async function dispatchRawRequest(router, request, options = {}) {
|
|
|
1377
1435
|
headers: getHeaders(),
|
|
1378
1436
|
body: res.body
|
|
1379
1437
|
});
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
status: 404
|
|
1392
|
-
});
|
|
1393
|
-
} catch (e) {
|
|
1394
|
-
if (options.throwOnError) {
|
|
1395
|
-
throw e;
|
|
1396
|
-
}
|
|
1397
|
-
if (isError(e)) {
|
|
1398
|
-
return createRawResponse({
|
|
1399
|
-
status: e.statusCode,
|
|
1400
|
-
statusMessage: e.statusMessage
|
|
1401
|
-
});
|
|
1402
|
-
}
|
|
1438
|
+
const event = new DispatchEvent({
|
|
1439
|
+
request: req,
|
|
1440
|
+
response: res,
|
|
1441
|
+
path: request.path,
|
|
1442
|
+
method
|
|
1443
|
+
});
|
|
1444
|
+
await router.dispatch(event);
|
|
1445
|
+
if (event.dispatched) {
|
|
1446
|
+
return createRawResponse();
|
|
1447
|
+
}
|
|
1448
|
+
if (event.error) {
|
|
1403
1449
|
return createRawResponse({
|
|
1404
|
-
status:
|
|
1450
|
+
status: event.error.statusCode,
|
|
1451
|
+
statusMessage: event.error.statusMessage
|
|
1405
1452
|
});
|
|
1406
1453
|
}
|
|
1454
|
+
return createRawResponse({
|
|
1455
|
+
status: 404
|
|
1456
|
+
});
|
|
1407
1457
|
}
|
|
1408
1458
|
function createRawDispatcher(router) {
|
|
1409
1459
|
return async (request)=>dispatchRawRequest(router, request);
|
|
1410
1460
|
}
|
|
1411
1461
|
|
|
1412
|
-
async function dispatchWebRequest(router, request
|
|
1462
|
+
async function dispatchWebRequest(router, request) {
|
|
1413
1463
|
const url = new URL(request.url);
|
|
1414
1464
|
const headers = {};
|
|
1415
1465
|
request.headers.forEach((value, key)=>{
|
|
1416
1466
|
headers[key] = value;
|
|
1417
1467
|
});
|
|
1468
|
+
const method = toMethodName(request.method, exports.MethodName.GET);
|
|
1418
1469
|
const res = await dispatchRawRequest(router, {
|
|
1419
|
-
method
|
|
1470
|
+
method,
|
|
1420
1471
|
path: url.pathname + url.search,
|
|
1421
1472
|
headers,
|
|
1422
1473
|
body: request.body
|
|
1423
|
-
}
|
|
1474
|
+
});
|
|
1424
1475
|
let body;
|
|
1425
|
-
if (
|
|
1476
|
+
if (method === exports.MethodName.HEAD || res.status === 304 || res.status === 101 || res.status === 204 || res.status === 205) {
|
|
1426
1477
|
body = null;
|
|
1427
1478
|
} else {
|
|
1428
1479
|
body = res.body;
|
|
@@ -1442,35 +1493,98 @@ exports.HandlerType = void 0;
|
|
|
1442
1493
|
HandlerType["CORE"] = "core";
|
|
1443
1494
|
HandlerType["ERROR"] = "error";
|
|
1444
1495
|
})(exports.HandlerType || (exports.HandlerType = {}));
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1496
|
+
const HandlerSymbol = Symbol.for('Handler');
|
|
1497
|
+
|
|
1498
|
+
var HookName;
|
|
1499
|
+
(function(HookName) {
|
|
1500
|
+
HookName["ERROR"] = "error";
|
|
1501
|
+
HookName["DISPATCH_START"] = "dispatchStart";
|
|
1502
|
+
HookName["DISPATCH_END"] = "dispatchEnd";
|
|
1503
|
+
HookName["CHILD_MATCH"] = "childMatch";
|
|
1504
|
+
HookName["CHILD_DISPATCH_BEFORE"] = "childDispatchBefore";
|
|
1505
|
+
HookName["CHILD_DISPATCH_AFTER"] = "childDispatchAfter";
|
|
1506
|
+
})(HookName || (HookName = {}));
|
|
1507
|
+
|
|
1508
|
+
class HookManager {
|
|
1509
|
+
// --------------------------------------------------
|
|
1510
|
+
addListener(name, fn) {
|
|
1511
|
+
this.items[name] = this.items[name] || [];
|
|
1512
|
+
this.items[name].push(fn);
|
|
1513
|
+
return ()=>{
|
|
1514
|
+
this.removeListener(name, fn);
|
|
1451
1515
|
};
|
|
1452
1516
|
}
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1517
|
+
removeListener(name, fn) {
|
|
1518
|
+
if (!this.items[name]) {
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
if (typeof fn === 'undefined') {
|
|
1522
|
+
delete this.items[name];
|
|
1523
|
+
return;
|
|
1524
|
+
}
|
|
1525
|
+
if (typeof fn === 'function') {
|
|
1526
|
+
const index = this.items[name].indexOf(fn);
|
|
1527
|
+
if (index !== -1) {
|
|
1528
|
+
this.items[name].splice(index, 1);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
if (this.items[name].length === 0) {
|
|
1532
|
+
delete this.items[name];
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
// --------------------------------------------------
|
|
1536
|
+
/**
|
|
1537
|
+
* @throws RoutupError
|
|
1538
|
+
*
|
|
1539
|
+
* @param name
|
|
1540
|
+
* @param event
|
|
1541
|
+
*/ async trigger(name, event) {
|
|
1542
|
+
if (!this.items[name] || this.items[name].length === 0) {
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
1545
|
+
try {
|
|
1546
|
+
for(let i = 0; i < this.items[name].length; i++){
|
|
1547
|
+
const hook = this.items[name][i];
|
|
1548
|
+
event.dispatched = await dispatch(event, (next)=>Promise.resolve().then(()=>{
|
|
1549
|
+
event.next = next;
|
|
1550
|
+
return this.triggerListener(name, event, hook);
|
|
1551
|
+
}).catch((err)=>next(err)));
|
|
1552
|
+
event.next = nextPlaceholder;
|
|
1553
|
+
if (event.dispatched) {
|
|
1554
|
+
if (event.error) {
|
|
1555
|
+
event.error = undefined;
|
|
1556
|
+
}
|
|
1557
|
+
return;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
} catch (e) {
|
|
1561
|
+
event.error = e;
|
|
1562
|
+
if (!this.isErrorListenerHook(name)) {
|
|
1563
|
+
await this.trigger(HookName.ERROR, event);
|
|
1564
|
+
if (event.dispatched) {
|
|
1565
|
+
if (event.error) {
|
|
1566
|
+
event.error = undefined;
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
triggerListener(name, event, listener) {
|
|
1573
|
+
if (this.isErrorListenerHook(name)) {
|
|
1574
|
+
if (isDispatcherErrorEvent(event)) {
|
|
1575
|
+
return listener(event);
|
|
1576
|
+
}
|
|
1577
|
+
return undefined;
|
|
1578
|
+
}
|
|
1579
|
+
return listener(event);
|
|
1580
|
+
}
|
|
1581
|
+
isErrorListenerHook(input) {
|
|
1582
|
+
return input === HookName.ERROR;
|
|
1583
|
+
}
|
|
1584
|
+
// --------------------------------------------------
|
|
1585
|
+
constructor(){
|
|
1586
|
+
this.items = {};
|
|
1465
1587
|
}
|
|
1466
|
-
return {
|
|
1467
|
-
type: exports.HandlerType.ERROR,
|
|
1468
|
-
...input
|
|
1469
|
-
};
|
|
1470
|
-
}
|
|
1471
|
-
|
|
1472
|
-
function isHandler(input) {
|
|
1473
|
-
return isObject(input) && typeof input.fn === 'function' && typeof input.type === 'string';
|
|
1474
1588
|
}
|
|
1475
1589
|
|
|
1476
1590
|
function decodeParam(val) {
|
|
@@ -1528,93 +1642,59 @@ function isPath(input) {
|
|
|
1528
1642
|
return typeof input === 'string' || input instanceof RegExp;
|
|
1529
1643
|
}
|
|
1530
1644
|
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
class Layer {
|
|
1645
|
+
class Handler {
|
|
1534
1646
|
// --------------------------------------------------
|
|
1535
1647
|
get type() {
|
|
1536
|
-
return this.
|
|
1648
|
+
return this.config.type;
|
|
1537
1649
|
}
|
|
1538
1650
|
get path() {
|
|
1539
|
-
return this.
|
|
1651
|
+
return this.config.path;
|
|
1540
1652
|
}
|
|
1541
1653
|
get method() {
|
|
1542
|
-
|
|
1654
|
+
if (this._method || !this.config.method) {
|
|
1655
|
+
return this._method;
|
|
1656
|
+
}
|
|
1657
|
+
this._method = toMethodName(this.config.method);
|
|
1658
|
+
return this._method;
|
|
1543
1659
|
}
|
|
1544
1660
|
// --------------------------------------------------
|
|
1545
|
-
dispatch(event
|
|
1661
|
+
async dispatch(event) {
|
|
1546
1662
|
if (this.pathMatcher) {
|
|
1547
|
-
const pathMatch = this.pathMatcher.exec(
|
|
1663
|
+
const pathMatch = this.pathMatcher.exec(event.path);
|
|
1548
1664
|
if (pathMatch) {
|
|
1549
|
-
|
|
1665
|
+
event.params = {
|
|
1666
|
+
...event.params,
|
|
1667
|
+
...pathMatch.params
|
|
1668
|
+
};
|
|
1550
1669
|
}
|
|
1551
1670
|
}
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
const shutdown = (dispatched, err)=>{
|
|
1562
|
-
if (handled) {
|
|
1563
|
-
return;
|
|
1564
|
-
}
|
|
1565
|
-
handled = true;
|
|
1566
|
-
unsubscribe();
|
|
1567
|
-
if (err) {
|
|
1568
|
-
reject(createError(err));
|
|
1569
|
-
} else {
|
|
1570
|
-
resolve(dispatched);
|
|
1571
|
-
}
|
|
1572
|
-
};
|
|
1573
|
-
const onFinished = (err)=>shutdown(true, err);
|
|
1574
|
-
const onNext = (err)=>shutdown(false, err);
|
|
1575
|
-
event.res.once('close', onFinished);
|
|
1576
|
-
event.res.once('error', onFinished);
|
|
1577
|
-
const handle = (data)=>{
|
|
1578
|
-
if (typeof data === 'undefined' || handled) {
|
|
1579
|
-
return Promise.resolve();
|
|
1580
|
-
}
|
|
1581
|
-
handled = true;
|
|
1582
|
-
unsubscribe();
|
|
1583
|
-
return this.sendOutput(event.res, data).then(()=>resolve(true)).catch((e)=>reject(createError(e)));
|
|
1584
|
-
};
|
|
1585
|
-
try {
|
|
1586
|
-
let output;
|
|
1587
|
-
if (this.handler.type === exports.HandlerType.ERROR) {
|
|
1588
|
-
if (meta.error) {
|
|
1589
|
-
output = this.handler.fn(meta.error, event.req, event.res, onNext);
|
|
1671
|
+
await this.hookManager.trigger(HookName.CHILD_DISPATCH_BEFORE, event);
|
|
1672
|
+
if (event.dispatched) {
|
|
1673
|
+
return Promise.resolve();
|
|
1674
|
+
}
|
|
1675
|
+
try {
|
|
1676
|
+
event.dispatched = await dispatch(event, (done)=>{
|
|
1677
|
+
if (this.config.type === exports.HandlerType.ERROR) {
|
|
1678
|
+
if (event.error) {
|
|
1679
|
+
return this.config.fn(event.error, event.request, event.response, done);
|
|
1590
1680
|
}
|
|
1591
1681
|
} else {
|
|
1592
|
-
|
|
1682
|
+
return this.config.fn(event.request, event.response, done);
|
|
1593
1683
|
}
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1684
|
+
return undefined;
|
|
1685
|
+
});
|
|
1686
|
+
} catch (e) {
|
|
1687
|
+
if (isError(e)) {
|
|
1688
|
+
event.error = e;
|
|
1689
|
+
await this.hookManager.trigger(HookName.ERROR, event);
|
|
1690
|
+
if (event.dispatched) {
|
|
1691
|
+
event.error = undefined;
|
|
1692
|
+
} else {
|
|
1693
|
+
throw e;
|
|
1597
1694
|
}
|
|
1598
|
-
Promise.resolve().then(()=>handle(output)).catch((e)=>reject(createError(e)));
|
|
1599
|
-
} catch (error) {
|
|
1600
|
-
onNext(error);
|
|
1601
1695
|
}
|
|
1602
|
-
});
|
|
1603
|
-
}
|
|
1604
|
-
sendOutput(res, input) {
|
|
1605
|
-
if (input instanceof Error) {
|
|
1606
|
-
return Promise.reject(createError(input));
|
|
1607
|
-
}
|
|
1608
|
-
if (isStream(input)) {
|
|
1609
|
-
return sendStream(res, input);
|
|
1610
|
-
}
|
|
1611
|
-
if (isWebBlob(input)) {
|
|
1612
|
-
return sendWebBlob(res, input);
|
|
1613
|
-
}
|
|
1614
|
-
if (isWebResponse(input)) {
|
|
1615
|
-
return sendWebResponse(res, input);
|
|
1616
1696
|
}
|
|
1617
|
-
return
|
|
1697
|
+
return this.hookManager.trigger(HookName.CHILD_DISPATCH_AFTER, event);
|
|
1618
1698
|
}
|
|
1619
1699
|
// --------------------------------------------------
|
|
1620
1700
|
matchPath(path) {
|
|
@@ -1623,30 +1703,81 @@ class Layer {
|
|
|
1623
1703
|
}
|
|
1624
1704
|
return this.pathMatcher.test(path);
|
|
1625
1705
|
}
|
|
1706
|
+
setPath(path) {
|
|
1707
|
+
if (typeof path === 'string') {
|
|
1708
|
+
path = withLeadingSlash(path);
|
|
1709
|
+
}
|
|
1710
|
+
this.config.path = path;
|
|
1711
|
+
if (typeof path === 'undefined') {
|
|
1712
|
+
this.pathMatcher = undefined;
|
|
1713
|
+
return;
|
|
1714
|
+
}
|
|
1715
|
+
this.pathMatcher = new PathMatcher(path, {
|
|
1716
|
+
end: !!this.config.method
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
// --------------------------------------------------
|
|
1626
1720
|
matchMethod(method) {
|
|
1627
|
-
|
|
1628
|
-
|
|
1721
|
+
return !this.method || method === this.method || method === exports.MethodName.HEAD && this.method === exports.MethodName.GET;
|
|
1722
|
+
}
|
|
1723
|
+
setMethod(input) {
|
|
1724
|
+
const method = toMethodName(input);
|
|
1725
|
+
this.config.method = method;
|
|
1726
|
+
this._method = method;
|
|
1727
|
+
}
|
|
1728
|
+
// --------------------------------------------------
|
|
1729
|
+
mountHooks() {
|
|
1730
|
+
if (this.config.onBefore) {
|
|
1731
|
+
this.hookManager.addListener(HookName.CHILD_DISPATCH_BEFORE, this.config.onBefore);
|
|
1629
1732
|
}
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1733
|
+
if (this.config.onAfter) {
|
|
1734
|
+
this.hookManager.addListener(HookName.CHILD_DISPATCH_AFTER, this.config.onAfter);
|
|
1735
|
+
}
|
|
1736
|
+
if (this.config.onError) {
|
|
1737
|
+
this.hookManager.addListener(HookName.ERROR, this.config.onError);
|
|
1633
1738
|
}
|
|
1634
|
-
return name === exports.MethodName.HEAD && this.method === exports.MethodName.GET;
|
|
1635
1739
|
}
|
|
1636
1740
|
// --------------------------------------------------
|
|
1637
1741
|
constructor(handler){
|
|
1638
|
-
this['@instanceof'] =
|
|
1639
|
-
this.
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1742
|
+
this['@instanceof'] = HandlerSymbol;
|
|
1743
|
+
this.config = handler;
|
|
1744
|
+
this.hookManager = new HookManager();
|
|
1745
|
+
this.mountHooks();
|
|
1746
|
+
this.setPath(handler.path);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
function coreHandler(input) {
|
|
1751
|
+
if (typeof input === 'function') {
|
|
1752
|
+
return new Handler({
|
|
1753
|
+
type: exports.HandlerType.CORE,
|
|
1754
|
+
fn: input
|
|
1755
|
+
});
|
|
1756
|
+
}
|
|
1757
|
+
return new Handler({
|
|
1758
|
+
type: exports.HandlerType.CORE,
|
|
1759
|
+
...input
|
|
1760
|
+
});
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
function errorHandler(input) {
|
|
1764
|
+
if (typeof input === 'function') {
|
|
1765
|
+
return new Handler({
|
|
1766
|
+
type: exports.HandlerType.ERROR,
|
|
1767
|
+
fn: input
|
|
1768
|
+
});
|
|
1645
1769
|
}
|
|
1770
|
+
return new Handler({
|
|
1771
|
+
type: exports.HandlerType.ERROR,
|
|
1772
|
+
...input
|
|
1773
|
+
});
|
|
1646
1774
|
}
|
|
1647
1775
|
|
|
1648
|
-
function
|
|
1649
|
-
return
|
|
1776
|
+
function isHandlerConfig(input) {
|
|
1777
|
+
return isObject(input) && typeof input.fn === 'function' && typeof input.type === 'string';
|
|
1778
|
+
}
|
|
1779
|
+
function isHandler(input) {
|
|
1780
|
+
return isInstance(input, HandlerSymbol);
|
|
1650
1781
|
}
|
|
1651
1782
|
|
|
1652
1783
|
function isPlugin(input) {
|
|
@@ -1670,6 +1801,15 @@ function transformRouterOptions(input) {
|
|
|
1670
1801
|
}
|
|
1671
1802
|
|
|
1672
1803
|
const RouterSymbol = Symbol.for('Router');
|
|
1804
|
+
var RouterPipelineStep;
|
|
1805
|
+
(function(RouterPipelineStep) {
|
|
1806
|
+
RouterPipelineStep[RouterPipelineStep["START"] = 0] = "START";
|
|
1807
|
+
RouterPipelineStep[RouterPipelineStep["LOOKUP"] = 1] = "LOOKUP";
|
|
1808
|
+
RouterPipelineStep[RouterPipelineStep["CHILD_BEFORE"] = 2] = "CHILD_BEFORE";
|
|
1809
|
+
RouterPipelineStep[RouterPipelineStep["CHILD_DISPATCH"] = 3] = "CHILD_DISPATCH";
|
|
1810
|
+
RouterPipelineStep[RouterPipelineStep["CHILD_AFTER"] = 4] = "CHILD_AFTER";
|
|
1811
|
+
RouterPipelineStep[RouterPipelineStep["FINISH"] = 5] = "FINISH";
|
|
1812
|
+
})(RouterPipelineStep || (RouterPipelineStep = {}));
|
|
1673
1813
|
|
|
1674
1814
|
let nextId = 0;
|
|
1675
1815
|
function generateRouterID() {
|
|
@@ -1681,102 +1821,187 @@ function isRouterInstance(input) {
|
|
|
1681
1821
|
|
|
1682
1822
|
class Router {
|
|
1683
1823
|
// --------------------------------------------------
|
|
1824
|
+
matchPath(path) {
|
|
1825
|
+
if (this.pathMatcher) {
|
|
1826
|
+
return this.pathMatcher.test(path);
|
|
1827
|
+
}
|
|
1828
|
+
return true;
|
|
1829
|
+
}
|
|
1684
1830
|
setPath(value) {
|
|
1685
|
-
if (value === '/' ||
|
|
1831
|
+
if (value === '/' || typeof value === 'undefined') {
|
|
1832
|
+
this.pathMatcher = undefined;
|
|
1686
1833
|
return;
|
|
1687
1834
|
}
|
|
1688
|
-
let path;
|
|
1689
1835
|
if (typeof value === 'string') {
|
|
1690
|
-
|
|
1836
|
+
this.pathMatcher = new PathMatcher(withLeadingSlash(withoutTrailingSlash(`${value}`)), {
|
|
1837
|
+
end: false
|
|
1838
|
+
});
|
|
1691
1839
|
} else {
|
|
1692
|
-
|
|
1840
|
+
this.pathMatcher = new PathMatcher(value, {
|
|
1841
|
+
end: false
|
|
1842
|
+
});
|
|
1693
1843
|
}
|
|
1694
|
-
this.pathMatcher = new PathMatcher(path, {
|
|
1695
|
-
end: false
|
|
1696
|
-
});
|
|
1697
1844
|
}
|
|
1698
1845
|
// --------------------------------------------------
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1846
|
+
async executePipelineStep(context) {
|
|
1847
|
+
switch(context.step){
|
|
1848
|
+
case RouterPipelineStep.START:
|
|
1849
|
+
{
|
|
1850
|
+
return this.executePipelineStepStart(context);
|
|
1851
|
+
}
|
|
1852
|
+
case RouterPipelineStep.LOOKUP:
|
|
1853
|
+
{
|
|
1854
|
+
return this.executePipelineStepLookup(context);
|
|
1855
|
+
}
|
|
1856
|
+
case RouterPipelineStep.CHILD_BEFORE:
|
|
1857
|
+
{
|
|
1858
|
+
return this.executePipelineStepChildBefore(context);
|
|
1859
|
+
}
|
|
1860
|
+
case RouterPipelineStep.CHILD_DISPATCH:
|
|
1861
|
+
{
|
|
1862
|
+
return this.executePipelineStepChildDispatch(context);
|
|
1863
|
+
}
|
|
1864
|
+
case RouterPipelineStep.CHILD_AFTER:
|
|
1865
|
+
{
|
|
1866
|
+
return this.executePipelineStepChildAfter(context);
|
|
1867
|
+
}
|
|
1868
|
+
case RouterPipelineStep.FINISH:
|
|
1869
|
+
default:
|
|
1870
|
+
{
|
|
1871
|
+
return this.executePipelineStepFinish(context);
|
|
1872
|
+
}
|
|
1702
1873
|
}
|
|
1703
|
-
return true;
|
|
1704
1874
|
}
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
meta.mountPath = cleanDoubleSlashes(`${meta.mountPath}/${output.path}`);
|
|
1712
|
-
if (meta.path === output.path) {
|
|
1713
|
-
meta.path = '/';
|
|
1714
|
-
} else {
|
|
1715
|
-
meta.path = withLeadingSlash(meta.path.substring(output.path.length));
|
|
1716
|
-
}
|
|
1717
|
-
meta.params = {
|
|
1718
|
-
...meta.params,
|
|
1719
|
-
...output.params
|
|
1720
|
-
};
|
|
1875
|
+
async executePipelineStepStart(context) {
|
|
1876
|
+
return this.hookManager.trigger(HookName.DISPATCH_START, context.event).then(()=>{
|
|
1877
|
+
if (context.event.dispatched) {
|
|
1878
|
+
context.step = RouterPipelineStep.FINISH;
|
|
1879
|
+
} else {
|
|
1880
|
+
context.step++;
|
|
1721
1881
|
}
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1882
|
+
return this.executePipelineStep(context);
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
async executePipelineStepLookup(context) {
|
|
1886
|
+
if (context.event.dispatched || context.stackIndex >= this.stack.length) {
|
|
1887
|
+
context.step = RouterPipelineStep.FINISH;
|
|
1888
|
+
return this.executePipelineStep(context);
|
|
1889
|
+
}
|
|
1890
|
+
let match;
|
|
1891
|
+
const item = this.stack[context.stackIndex];
|
|
1892
|
+
if (isHandler(item)) {
|
|
1893
|
+
if (context.event.error && item.type === exports.HandlerType.CORE || !context.event.error && item.type === exports.HandlerType.ERROR) {
|
|
1894
|
+
context.stackIndex++;
|
|
1895
|
+
return this.executePipelineStepLookup(context);
|
|
1896
|
+
}
|
|
1897
|
+
match = item.matchPath(context.event.path);
|
|
1898
|
+
if (match) {
|
|
1899
|
+
if (item.method) {
|
|
1900
|
+
context.event.methodsAllowed.push(item.method);
|
|
1733
1901
|
}
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
if (
|
|
1737
|
-
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
allowedMethods.push(item.method);
|
|
1902
|
+
if (item.matchMethod(context.event.method)) {
|
|
1903
|
+
await this.hookManager.trigger(HookName.CHILD_MATCH, context.event);
|
|
1904
|
+
if (context.event.dispatched) {
|
|
1905
|
+
context.step = RouterPipelineStep.FINISH;
|
|
1906
|
+
} else {
|
|
1907
|
+
context.step++;
|
|
1741
1908
|
}
|
|
1909
|
+
return this.executePipelineStep(context);
|
|
1742
1910
|
}
|
|
1743
|
-
} else if (isRouterInstance(item)) {
|
|
1744
|
-
match = item.matchPath(meta.path);
|
|
1745
1911
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1912
|
+
context.stackIndex++;
|
|
1913
|
+
return this.executePipelineStepLookup(context);
|
|
1914
|
+
}
|
|
1915
|
+
match = item.matchPath(context.event.path);
|
|
1916
|
+
if (match) {
|
|
1917
|
+
await this.hookManager.trigger(HookName.CHILD_MATCH, context.event);
|
|
1918
|
+
if (context.event.dispatched) {
|
|
1919
|
+
context.step = RouterPipelineStep.FINISH;
|
|
1920
|
+
} else {
|
|
1921
|
+
context.step++;
|
|
1748
1922
|
}
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1923
|
+
return this.executePipelineStep(context);
|
|
1924
|
+
}
|
|
1925
|
+
context.stackIndex++;
|
|
1926
|
+
return this.executePipelineStepLookup(context);
|
|
1927
|
+
}
|
|
1928
|
+
async executePipelineStepChildBefore(context) {
|
|
1929
|
+
return this.hookManager.trigger(HookName.CHILD_DISPATCH_BEFORE, context.event).then(()=>{
|
|
1930
|
+
if (context.event.dispatched) {
|
|
1931
|
+
context.step = RouterPipelineStep.FINISH;
|
|
1932
|
+
} else {
|
|
1933
|
+
context.step++;
|
|
1752
1934
|
}
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1935
|
+
return this.executePipelineStep(context);
|
|
1936
|
+
});
|
|
1937
|
+
}
|
|
1938
|
+
async executePipelineStepChildAfter(context) {
|
|
1939
|
+
return this.hookManager.trigger(HookName.CHILD_DISPATCH_AFTER, context.event).then(()=>{
|
|
1940
|
+
if (context.event.dispatched) {
|
|
1941
|
+
context.step = RouterPipelineStep.FINISH;
|
|
1942
|
+
} else {
|
|
1943
|
+
context.step = RouterPipelineStep.LOOKUP;
|
|
1762
1944
|
}
|
|
1945
|
+
return this.executePipelineStep(context);
|
|
1946
|
+
});
|
|
1947
|
+
}
|
|
1948
|
+
async executePipelineStepChildDispatch(context) {
|
|
1949
|
+
if (context.event.dispatched || typeof this.stack[context.stackIndex] === 'undefined') {
|
|
1950
|
+
context.step = RouterPipelineStep.FINISH;
|
|
1951
|
+
return this.executePipelineStep(context);
|
|
1952
|
+
}
|
|
1953
|
+
try {
|
|
1954
|
+
await this.stack[context.stackIndex].dispatch(context.event);
|
|
1955
|
+
} catch (e) {
|
|
1956
|
+
context.event.error = e;
|
|
1957
|
+
await this.hookManager.trigger(HookName.ERROR, context.event);
|
|
1763
1958
|
}
|
|
1764
|
-
|
|
1765
|
-
|
|
1959
|
+
context.stackIndex++;
|
|
1960
|
+
context.step++;
|
|
1961
|
+
return this.executePipelineStep(context);
|
|
1962
|
+
}
|
|
1963
|
+
async executePipelineStepFinish(context) {
|
|
1964
|
+
if (context.event.error || context.event.dispatched) {
|
|
1965
|
+
return this.hookManager.trigger(HookName.DISPATCH_END, context.event);
|
|
1766
1966
|
}
|
|
1767
|
-
if (event.
|
|
1768
|
-
if (
|
|
1769
|
-
|
|
1967
|
+
if (!context.event.dispatched && context.event.routerPath.length === 1 && context.event.method && context.event.method === exports.MethodName.OPTIONS) {
|
|
1968
|
+
if (context.event.methodsAllowed.indexOf(exports.MethodName.GET) !== -1) {
|
|
1969
|
+
context.event.methodsAllowed.push(exports.MethodName.HEAD);
|
|
1770
1970
|
}
|
|
1771
|
-
smob.distinctArray(
|
|
1772
|
-
const options =
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1971
|
+
smob.distinctArray(context.event.methodsAllowed);
|
|
1972
|
+
const options = context.event.methodsAllowed.map((key)=>key.toUpperCase()).join(',');
|
|
1973
|
+
context.event.response.setHeader(exports.HeaderName.ALLOW, options);
|
|
1974
|
+
await send(context.event.response, options);
|
|
1975
|
+
context.event.dispatched = true;
|
|
1976
|
+
}
|
|
1977
|
+
return this.hookManager.trigger(HookName.DISPATCH_END, context.event);
|
|
1978
|
+
}
|
|
1979
|
+
// --------------------------------------------------
|
|
1980
|
+
async dispatch(event) {
|
|
1981
|
+
if (this.pathMatcher) {
|
|
1982
|
+
const output = this.pathMatcher.exec(event.path);
|
|
1983
|
+
if (typeof output !== 'undefined') {
|
|
1984
|
+
event.mountPath = cleanDoubleSlashes(`${event.mountPath}/${output.path}`);
|
|
1985
|
+
if (event.path === output.path) {
|
|
1986
|
+
event.path = '/';
|
|
1987
|
+
} else {
|
|
1988
|
+
event.path = withLeadingSlash(event.path.substring(output.path.length));
|
|
1989
|
+
}
|
|
1990
|
+
event.params = {
|
|
1991
|
+
...event.params,
|
|
1992
|
+
...output.params
|
|
1993
|
+
};
|
|
1776
1994
|
}
|
|
1777
|
-
return true;
|
|
1778
1995
|
}
|
|
1779
|
-
|
|
1996
|
+
const context = {
|
|
1997
|
+
step: RouterPipelineStep.START,
|
|
1998
|
+
event,
|
|
1999
|
+
stackIndex: 0
|
|
2000
|
+
};
|
|
2001
|
+
event.routerPath.push(this.id);
|
|
2002
|
+
return this.executePipelineStepStart(context).then(()=>{
|
|
2003
|
+
context.event.routerPath.pop();
|
|
2004
|
+
});
|
|
1780
2005
|
}
|
|
1781
2006
|
delete(...input) {
|
|
1782
2007
|
this.useForMethod(exports.MethodName.DELETE, ...input);
|
|
@@ -1808,33 +2033,40 @@ class Router {
|
|
|
1808
2033
|
}
|
|
1809
2034
|
// --------------------------------------------------
|
|
1810
2035
|
useForMethod(method, ...input) {
|
|
1811
|
-
|
|
1812
|
-
method
|
|
1813
|
-
};
|
|
2036
|
+
let path;
|
|
1814
2037
|
for(let i = 0; i < input.length; i++){
|
|
1815
2038
|
const element = input[i];
|
|
1816
2039
|
if (isPath(element)) {
|
|
1817
|
-
|
|
2040
|
+
path = element;
|
|
1818
2041
|
continue;
|
|
1819
2042
|
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
2043
|
+
if (isHandlerConfig(element)) {
|
|
2044
|
+
if (path) {
|
|
2045
|
+
element.path = path;
|
|
2046
|
+
}
|
|
2047
|
+
element.method = method;
|
|
2048
|
+
this.use(element);
|
|
2049
|
+
continue;
|
|
2050
|
+
}
|
|
2051
|
+
if (isHandler(element)) {
|
|
2052
|
+
if (path) {
|
|
2053
|
+
element.setPath(path);
|
|
2054
|
+
}
|
|
2055
|
+
element.setMethod(method);
|
|
2056
|
+
this.use(element);
|
|
2057
|
+
}
|
|
1824
2058
|
}
|
|
1825
2059
|
}
|
|
1826
2060
|
use(...input) {
|
|
1827
|
-
const modifyPath = (input)=>{
|
|
1828
|
-
if (typeof input === 'string') {
|
|
1829
|
-
return withLeadingSlash(input);
|
|
1830
|
-
}
|
|
1831
|
-
return input;
|
|
1832
|
-
};
|
|
1833
2061
|
let path;
|
|
1834
2062
|
for(let i = 0; i < input.length; i++){
|
|
1835
2063
|
const item = input[i];
|
|
1836
2064
|
if (isPath(item)) {
|
|
1837
|
-
|
|
2065
|
+
if (typeof item === 'string') {
|
|
2066
|
+
path = withLeadingSlash(item);
|
|
2067
|
+
} else {
|
|
2068
|
+
path = item;
|
|
2069
|
+
}
|
|
1838
2070
|
continue;
|
|
1839
2071
|
}
|
|
1840
2072
|
if (isRouterInstance(item)) {
|
|
@@ -1844,9 +2076,14 @@ class Router {
|
|
|
1844
2076
|
this.stack.push(item);
|
|
1845
2077
|
continue;
|
|
1846
2078
|
}
|
|
2079
|
+
if (isHandlerConfig(item)) {
|
|
2080
|
+
item.path = path || item.path;
|
|
2081
|
+
this.stack.push(new Handler(item));
|
|
2082
|
+
continue;
|
|
2083
|
+
}
|
|
1847
2084
|
if (isHandler(item)) {
|
|
1848
|
-
item.path
|
|
1849
|
-
this.stack.push(
|
|
2085
|
+
item.setPath(path || item.path);
|
|
2086
|
+
this.stack.push(item);
|
|
1850
2087
|
continue;
|
|
1851
2088
|
}
|
|
1852
2089
|
if (isPlugin(item)) {
|
|
@@ -1875,6 +2112,17 @@ class Router {
|
|
|
1875
2112
|
}
|
|
1876
2113
|
return this;
|
|
1877
2114
|
}
|
|
2115
|
+
on(name, fn) {
|
|
2116
|
+
return this.hookManager.addListener(name, fn);
|
|
2117
|
+
}
|
|
2118
|
+
off(name, fn) {
|
|
2119
|
+
if (typeof fn === 'undefined') {
|
|
2120
|
+
this.hookManager.removeListener(name);
|
|
2121
|
+
return this;
|
|
2122
|
+
}
|
|
2123
|
+
this.hookManager.removeListener(name, fn);
|
|
2124
|
+
return this;
|
|
2125
|
+
}
|
|
1878
2126
|
// --------------------------------------------------
|
|
1879
2127
|
constructor(options = {}){
|
|
1880
2128
|
this['@instanceof'] = RouterSymbol;
|
|
@@ -1885,20 +2133,21 @@ class Router {
|
|
|
1885
2133
|
*/ this.stack = [];
|
|
1886
2134
|
this.id = generateRouterID();
|
|
1887
2135
|
this.name = options.name;
|
|
2136
|
+
this.hookManager = new HookManager();
|
|
1888
2137
|
this.setPath(options.path);
|
|
1889
2138
|
setRouterOptions(this.id, transformRouterOptions(options));
|
|
1890
2139
|
}
|
|
1891
2140
|
}
|
|
1892
2141
|
|
|
1893
|
-
exports.
|
|
1894
|
-
exports.
|
|
2142
|
+
exports.DispatchErrorEvent = DispatchErrorEvent;
|
|
2143
|
+
exports.DispatchEvent = DispatchEvent;
|
|
2144
|
+
exports.Handler = Handler;
|
|
2145
|
+
exports.HandlerSymbol = HandlerSymbol;
|
|
1895
2146
|
exports.PathMatcher = PathMatcher;
|
|
1896
2147
|
exports.Router = Router;
|
|
2148
|
+
exports.RoutupError = RoutupError;
|
|
1897
2149
|
exports.appendResponseHeader = appendResponseHeader;
|
|
1898
2150
|
exports.appendResponseHeaderDirective = appendResponseHeaderDirective;
|
|
1899
|
-
exports.buildDispatcherMeta = buildDispatcherMeta;
|
|
1900
|
-
exports.cloneDispatcherMeta = cloneDispatcherMeta;
|
|
1901
|
-
exports.cloneDispatcherMetaParams = cloneDispatcherMetaParams;
|
|
1902
2151
|
exports.coreHandler = coreHandler;
|
|
1903
2152
|
exports.createError = createError;
|
|
1904
2153
|
exports.createNodeDispatcher = createNodeDispatcher;
|
|
@@ -1906,6 +2155,7 @@ exports.createRawDispatcher = createRawDispatcher;
|
|
|
1906
2155
|
exports.createRequest = createRequest;
|
|
1907
2156
|
exports.createResponse = createResponse;
|
|
1908
2157
|
exports.createWebDispatcher = createWebDispatcher;
|
|
2158
|
+
exports.dispatch = dispatch;
|
|
1909
2159
|
exports.dispatchNodeRequest = dispatchNodeRequest;
|
|
1910
2160
|
exports.dispatchRawRequest = dispatchRawRequest;
|
|
1911
2161
|
exports.dispatchWebRequest = dispatchWebRequest;
|
|
@@ -1922,16 +2172,15 @@ exports.getRequestHeader = getRequestHeader;
|
|
|
1922
2172
|
exports.getRequestHostName = getRequestHostName;
|
|
1923
2173
|
exports.getRequestIP = getRequestIP;
|
|
1924
2174
|
exports.getRequestProtocol = getRequestProtocol;
|
|
2175
|
+
exports.isDispatcherErrorEvent = isDispatcherErrorEvent;
|
|
1925
2176
|
exports.isError = isError;
|
|
1926
2177
|
exports.isHandler = isHandler;
|
|
1927
|
-
exports.
|
|
2178
|
+
exports.isHandlerConfig = isHandlerConfig;
|
|
1928
2179
|
exports.isPath = isPath;
|
|
1929
2180
|
exports.isPlugin = isPlugin;
|
|
1930
2181
|
exports.isRequestCacheable = isRequestCacheable;
|
|
1931
2182
|
exports.isResponseGone = isResponseGone;
|
|
1932
|
-
exports.isRouterInstance = isRouterInstance;
|
|
1933
2183
|
exports.matchRequestContentType = matchRequestContentType;
|
|
1934
|
-
exports.mergeDispatcherMetaParams = mergeDispatcherMetaParams;
|
|
1935
2184
|
exports.send = send;
|
|
1936
2185
|
exports.sendAccepted = sendAccepted;
|
|
1937
2186
|
exports.sendCreated = sendCreated;
|
|
@@ -1951,6 +2200,8 @@ exports.setResponseCacheHeaders = setResponseCacheHeaders;
|
|
|
1951
2200
|
exports.setResponseContentTypeByFileName = setResponseContentTypeByFileName;
|
|
1952
2201
|
exports.setResponseHeaderAttachment = setResponseHeaderAttachment;
|
|
1953
2202
|
exports.setResponseHeaderContentType = setResponseHeaderContentType;
|
|
2203
|
+
exports.transformHeaderToTuples = transformHeaderToTuples;
|
|
2204
|
+
exports.transformHeadersToTuples = transformHeadersToTuples;
|
|
1954
2205
|
exports.unsetRequestEnv = unsetRequestEnv;
|
|
1955
2206
|
exports.useRequestEnv = useRequestEnv;
|
|
1956
2207
|
exports.useRequestMountPath = useRequestMountPath;
|