routup 4.0.2 → 5.0.0-beta.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 +87 -134
- package/dist/bun.cjs +66 -0
- package/dist/bun.cjs.map +1 -0
- package/dist/bun.d.cts +8 -0
- package/dist/bun.d.mts +8 -0
- package/dist/bun.mjs +13 -0
- package/dist/bun.mjs.map +1 -0
- package/dist/cloudflare.cjs +66 -0
- package/dist/cloudflare.cjs.map +1 -0
- package/dist/cloudflare.d.cts +8 -0
- package/dist/cloudflare.d.mts +8 -0
- package/dist/cloudflare.mjs +13 -0
- package/dist/cloudflare.mjs.map +1 -0
- package/dist/deno.cjs +66 -0
- package/dist/deno.cjs.map +1 -0
- package/dist/deno.d.cts +8 -0
- package/dist/deno.d.mts +8 -0
- package/dist/deno.mjs +13 -0
- package/dist/deno.mjs.map +1 -0
- package/dist/generic.cjs +66 -0
- package/dist/generic.cjs.map +1 -0
- package/dist/generic.d.cts +8 -0
- package/dist/generic.d.mts +8 -0
- package/dist/generic.mjs +13 -0
- package/dist/generic.mjs.map +1 -0
- package/dist/index-9K5FcIb3.d.cts +786 -0
- package/dist/index-B6F5CzQy.d.mts +786 -0
- package/dist/node.cjs +70 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +11 -0
- package/dist/node.d.mts +11 -0
- package/dist/node.mjs +16 -0
- package/dist/node.mjs.map +1 -0
- package/dist/service-worker.cjs +66 -0
- package/dist/service-worker.cjs.map +1 -0
- package/dist/service-worker.d.cts +10 -0
- package/dist/service-worker.d.mts +10 -0
- package/dist/service-worker.mjs +13 -0
- package/dist/service-worker.mjs.map +1 -0
- package/dist/src-C789deGE.mjs +1599 -0
- package/dist/src-C789deGE.mjs.map +1 -0
- package/dist/src-Ca2_b8P0.cjs +1939 -0
- package/dist/src-Ca2_b8P0.cjs.map +1 -0
- package/package.json +76 -36
- package/dist/adapters/index.d.ts +0 -3
- package/dist/adapters/node/index.d.ts +0 -1
- package/dist/adapters/node/module.d.ts +0 -6
- package/dist/adapters/raw/header.d.ts +0 -3
- package/dist/adapters/raw/index.d.ts +0 -3
- package/dist/adapters/raw/module.d.ts +0 -4
- package/dist/adapters/raw/type.d.ts +0 -18
- package/dist/adapters/web/index.d.ts +0 -2
- package/dist/adapters/web/module.d.ts +0 -4
- package/dist/adapters/web/type.d.ts +0 -3
- package/dist/constants.d.ts +0 -42
- package/dist/dispatcher/event/dispatch.d.ts +0 -4
- package/dist/dispatcher/event/error.d.ts +0 -5
- package/dist/dispatcher/event/index.d.ts +0 -5
- package/dist/dispatcher/event/is.d.ts +0 -3
- package/dist/dispatcher/event/module.d.ts +0 -56
- package/dist/dispatcher/event/types.d.ts +0 -9
- package/dist/dispatcher/index.d.ts +0 -2
- package/dist/dispatcher/type.d.ts +0 -4
- package/dist/error/create.d.ts +0 -11
- package/dist/error/index.d.ts +0 -3
- package/dist/error/is.d.ts +0 -2
- package/dist/error/module.d.ts +0 -3
- package/dist/handler/constants.d.ts +0 -5
- package/dist/handler/core/define.d.ts +0 -4
- package/dist/handler/core/index.d.ts +0 -2
- package/dist/handler/core/types.d.ts +0 -10
- package/dist/handler/error/define.d.ts +0 -4
- package/dist/handler/error/index.d.ts +0 -2
- package/dist/handler/error/types.d.ts +0 -11
- package/dist/handler/index.d.ts +0 -7
- package/dist/handler/is.d.ts +0 -4
- package/dist/handler/module.d.ts +0 -23
- package/dist/handler/types-base.d.ts +0 -10
- package/dist/handler/types.d.ts +0 -4
- package/dist/hook/constants.d.ts +0 -8
- package/dist/hook/index.d.ts +0 -3
- package/dist/hook/module.d.ts +0 -19
- package/dist/hook/types.d.ts +0 -5
- package/dist/index.cjs +0 -2314
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -11
- package/dist/index.mjs +0 -2235
- package/dist/index.mjs.map +0 -1
- package/dist/path/index.d.ts +0 -3
- package/dist/path/matcher.d.ts +0 -11
- package/dist/path/type.d.ts +0 -7
- package/dist/path/utils.d.ts +0 -2
- package/dist/plugin/index.d.ts +0 -2
- package/dist/plugin/is.d.ts +0 -2
- package/dist/plugin/types.d.ts +0 -23
- package/dist/request/helpers/cache.d.ts +0 -2
- package/dist/request/helpers/env.d.ts +0 -6
- package/dist/request/helpers/header-accept-charset.d.ts +0 -3
- package/dist/request/helpers/header-accept-encoding.d.ts +0 -3
- package/dist/request/helpers/header-accept-language.d.ts +0 -3
- package/dist/request/helpers/header-accept.d.ts +0 -3
- package/dist/request/helpers/header-content-type.d.ts +0 -2
- package/dist/request/helpers/header.d.ts +0 -4
- package/dist/request/helpers/hostname.d.ts +0 -7
- package/dist/request/helpers/http2.d.ts +0 -2
- package/dist/request/helpers/index.d.ts +0 -17
- package/dist/request/helpers/ip.d.ts +0 -7
- package/dist/request/helpers/mount-path.d.ts +0 -3
- package/dist/request/helpers/negotiator.d.ts +0 -3
- package/dist/request/helpers/params.d.ts +0 -5
- package/dist/request/helpers/path.d.ts +0 -2
- package/dist/request/helpers/protocol.d.ts +0 -8
- package/dist/request/helpers/router.d.ts +0 -3
- package/dist/request/index.d.ts +0 -3
- package/dist/request/module.d.ts +0 -3
- package/dist/request/types.d.ts +0 -12
- package/dist/response/helpers/cache.d.ts +0 -7
- package/dist/response/helpers/event-stream/factory.d.ts +0 -3
- package/dist/response/helpers/event-stream/index.d.ts +0 -2
- package/dist/response/helpers/event-stream/module.d.ts +0 -17
- package/dist/response/helpers/event-stream/types.d.ts +0 -24
- package/dist/response/helpers/event-stream/utils.d.ts +0 -2
- package/dist/response/helpers/gone.d.ts +0 -3
- package/dist/response/helpers/header-attachment.d.ts +0 -2
- package/dist/response/helpers/header-content-type.d.ts +0 -2
- package/dist/response/helpers/header.d.ts +0 -4
- package/dist/response/helpers/index.d.ts +0 -16
- package/dist/response/helpers/send-accepted.d.ts +0 -2
- package/dist/response/helpers/send-created.d.ts +0 -2
- package/dist/response/helpers/send-file.d.ts +0 -17
- package/dist/response/helpers/send-format.d.ts +0 -7
- package/dist/response/helpers/send-redirect.d.ts +0 -2
- package/dist/response/helpers/send-stream.d.ts +0 -3
- package/dist/response/helpers/send-web-blob.d.ts +0 -3
- package/dist/response/helpers/send-web-response.d.ts +0 -3
- package/dist/response/helpers/send.d.ts +0 -2
- package/dist/response/helpers/utils.d.ts +0 -2
- package/dist/response/index.d.ts +0 -3
- package/dist/response/module.d.ts +0 -3
- package/dist/response/types.d.ts +0 -3
- package/dist/router/constants.d.ts +0 -9
- package/dist/router/index.d.ts +0 -1
- package/dist/router/module.d.ts +0 -89
- package/dist/router/types.d.ts +0 -7
- package/dist/router/utils.d.ts +0 -3
- package/dist/router-options/index.d.ts +0 -2
- package/dist/router-options/module.d.ts +0 -4
- package/dist/router-options/transform.d.ts +0 -2
- package/dist/router-options/type.d.ts +0 -41
- package/dist/types.d.ts +0 -9
- package/dist/utils/cookie.d.ts +0 -1
- package/dist/utils/etag/index.d.ts +0 -3
- package/dist/utils/etag/module.d.ts +0 -11
- package/dist/utils/etag/type.d.ts +0 -15
- package/dist/utils/etag/utils.d.ts +0 -2
- package/dist/utils/index.d.ts +0 -13
- package/dist/utils/is-instance.d.ts +0 -1
- package/dist/utils/method.d.ts +0 -3
- package/dist/utils/mime.d.ts +0 -2
- package/dist/utils/next.d.ts +0 -2
- package/dist/utils/object.d.ts +0 -3
- package/dist/utils/path.d.ts +0 -5
- package/dist/utils/promise.d.ts +0 -1
- package/dist/utils/stream.d.ts +0 -6
- package/dist/utils/trust-proxy/index.d.ts +0 -2
- package/dist/utils/trust-proxy/module.d.ts +0 -2
- package/dist/utils/trust-proxy/type.d.ts +0 -2
- package/dist/utils/url.d.ts +0 -7
- package/dist/utils/web.d.ts +0 -3
package/dist/index.mjs
DELETED
|
@@ -1,2235 +0,0 @@
|
|
|
1
|
-
import { merge, hasOwnProperty, distinctArray } from 'smob';
|
|
2
|
-
import { Buffer } from 'buffer';
|
|
3
|
-
import { subtle } from 'uncrypto';
|
|
4
|
-
import { compile, all } from 'proxy-addr';
|
|
5
|
-
import { getType, get } from 'mime-explorer';
|
|
6
|
-
import Negotiator from 'negotiator';
|
|
7
|
-
import { Readable, PassThrough, Writable } from 'readable-stream';
|
|
8
|
-
import { HTTPError } from '@ebec/http';
|
|
9
|
-
import { pathToRegexp } from 'path-to-regexp';
|
|
10
|
-
|
|
11
|
-
var MethodName = /*#__PURE__*/ function(MethodName) {
|
|
12
|
-
MethodName["GET"] = "GET";
|
|
13
|
-
MethodName["POST"] = "POST";
|
|
14
|
-
MethodName["PUT"] = "PUT";
|
|
15
|
-
MethodName["PATCH"] = "PATCH";
|
|
16
|
-
MethodName["DELETE"] = "DELETE";
|
|
17
|
-
MethodName["OPTIONS"] = "OPTIONS";
|
|
18
|
-
MethodName["HEAD"] = "HEAD";
|
|
19
|
-
return MethodName;
|
|
20
|
-
}({});
|
|
21
|
-
var HeaderName = /*#__PURE__*/ function(HeaderName) {
|
|
22
|
-
HeaderName["ACCEPT"] = "accept";
|
|
23
|
-
HeaderName["ACCEPT_CHARSET"] = "accept-charset";
|
|
24
|
-
HeaderName["ACCEPT_ENCODING"] = "accept-encoding";
|
|
25
|
-
HeaderName["ACCEPT_LANGUAGE"] = "accept-language";
|
|
26
|
-
HeaderName["ACCEPT_RANGES"] = "accept-ranges";
|
|
27
|
-
HeaderName["ALLOW"] = "allow";
|
|
28
|
-
HeaderName["CACHE_CONTROL"] = "cache-control";
|
|
29
|
-
HeaderName["CONTENT_DISPOSITION"] = "content-disposition";
|
|
30
|
-
HeaderName["CONTENT_ENCODING"] = "content-encoding";
|
|
31
|
-
HeaderName["CONTENT_LENGTH"] = "content-length";
|
|
32
|
-
HeaderName["CONTENT_RANGE"] = "content-range";
|
|
33
|
-
HeaderName["CONTENT_TYPE"] = "content-type";
|
|
34
|
-
HeaderName["CONNECTION"] = "connection";
|
|
35
|
-
HeaderName["COOKIE"] = "cookie";
|
|
36
|
-
HeaderName["ETag"] = "etag";
|
|
37
|
-
HeaderName["HOST"] = "host";
|
|
38
|
-
HeaderName["IF_MODIFIED_SINCE"] = "if-modified-since";
|
|
39
|
-
HeaderName["IF_NONE_MATCH"] = "if-none-match";
|
|
40
|
-
HeaderName["LAST_MODIFIED"] = "last-modified";
|
|
41
|
-
HeaderName["LOCATION"] = "location";
|
|
42
|
-
HeaderName["RANGE"] = "range";
|
|
43
|
-
HeaderName["RATE_LIMIT_LIMIT"] = "ratelimit-limit";
|
|
44
|
-
HeaderName["RATE_LIMIT_REMAINING"] = "ratelimit-remaining";
|
|
45
|
-
HeaderName["RATE_LIMIT_RESET"] = "ratelimit-reset";
|
|
46
|
-
HeaderName["RETRY_AFTER"] = "retry-after";
|
|
47
|
-
HeaderName["SET_COOKIE"] = "set-cookie";
|
|
48
|
-
HeaderName["TRANSFER_ENCODING"] = "transfer-encoding";
|
|
49
|
-
HeaderName["X_ACCEL_BUFFERING"] = "x-accel-buffering";
|
|
50
|
-
HeaderName["X_FORWARDED_HOST"] = "x-forwarded-host";
|
|
51
|
-
HeaderName["X_FORWARDED_FOR"] = "x-forwarded-for";
|
|
52
|
-
HeaderName["X_FORWARDED_PROTO"] = "x-forwarded-proto";
|
|
53
|
-
return HeaderName;
|
|
54
|
-
}({});
|
|
55
|
-
|
|
56
|
-
function isRequestCacheable(req, modifiedTime) {
|
|
57
|
-
const modifiedSince = req.headers[HeaderName.IF_MODIFIED_SINCE];
|
|
58
|
-
if (!modifiedSince) {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
modifiedTime = typeof modifiedTime === 'string' ? new Date(modifiedTime) : modifiedTime;
|
|
62
|
-
return new Date(modifiedSince) >= modifiedTime;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/*
|
|
66
|
-
Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas
|
|
67
|
-
that are within a single set-cookie field-value, such as in the Expires portion.
|
|
68
|
-
|
|
69
|
-
This is uncommon, but explicitly allowed - see https://tools.ietf.org/html/rfc2616#section-4.2
|
|
70
|
-
Node.js does this for every header *except* set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128
|
|
71
|
-
React Native's fetch does this for *every* header, including set-cookie.
|
|
72
|
-
|
|
73
|
-
Based on: https://github.com/google/j2objc/commit/16820fdbc8f76ca0c33472810ce0cb03d20efe25
|
|
74
|
-
Credits to: https://github.com/tomball for original and https://github.com/chrusart for JavaScript implementation
|
|
75
|
-
*/ function splitCookiesString(input) {
|
|
76
|
-
if (Array.isArray(input)) {
|
|
77
|
-
return input.flatMap((el)=>splitCookiesString(el));
|
|
78
|
-
}
|
|
79
|
-
if (typeof input !== 'string') {
|
|
80
|
-
return [];
|
|
81
|
-
}
|
|
82
|
-
const cookiesStrings = [];
|
|
83
|
-
let pos = 0;
|
|
84
|
-
let start;
|
|
85
|
-
let ch;
|
|
86
|
-
let lastComma;
|
|
87
|
-
let nextStart;
|
|
88
|
-
let cookiesSeparatorFound;
|
|
89
|
-
const skipWhitespace = ()=>{
|
|
90
|
-
while(pos < input.length && /\s/.test(input.charAt(pos))){
|
|
91
|
-
pos += 1;
|
|
92
|
-
}
|
|
93
|
-
return pos < input.length;
|
|
94
|
-
};
|
|
95
|
-
const notSpecialChar = ()=>{
|
|
96
|
-
ch = input.charAt(pos);
|
|
97
|
-
return ch !== '=' && ch !== ';' && ch !== ',';
|
|
98
|
-
};
|
|
99
|
-
while(pos < input.length){
|
|
100
|
-
start = pos;
|
|
101
|
-
cookiesSeparatorFound = false;
|
|
102
|
-
while(skipWhitespace()){
|
|
103
|
-
ch = input.charAt(pos);
|
|
104
|
-
if (ch === ',') {
|
|
105
|
-
// ',' is a cookie separator if we have later first '=', not ';' or ','
|
|
106
|
-
lastComma = pos;
|
|
107
|
-
pos += 1;
|
|
108
|
-
skipWhitespace();
|
|
109
|
-
nextStart = pos;
|
|
110
|
-
while(pos < input.length && notSpecialChar()){
|
|
111
|
-
pos += 1;
|
|
112
|
-
}
|
|
113
|
-
// currently special character
|
|
114
|
-
if (pos < input.length && input.charAt(pos) === '=') {
|
|
115
|
-
// we found cookies separator
|
|
116
|
-
cookiesSeparatorFound = true;
|
|
117
|
-
// pos is inside the next cookie, so back up and return it.
|
|
118
|
-
pos = nextStart;
|
|
119
|
-
cookiesStrings.push(input.substring(start, lastComma));
|
|
120
|
-
start = pos;
|
|
121
|
-
} else {
|
|
122
|
-
// in param ',' or param separator ';',
|
|
123
|
-
// we continue from that comma
|
|
124
|
-
pos = lastComma + 1;
|
|
125
|
-
}
|
|
126
|
-
} else {
|
|
127
|
-
pos += 1;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
if (!cookiesSeparatorFound || pos >= input.length) {
|
|
131
|
-
cookiesStrings.push(input.substring(start, input.length));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return cookiesStrings;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function isObject(item) {
|
|
138
|
-
return !!item && typeof item === 'object' && !Array.isArray(item);
|
|
139
|
-
}
|
|
140
|
-
function setProperty(record, property, value) {
|
|
141
|
-
record[property] = value;
|
|
142
|
-
}
|
|
143
|
-
function getProperty(req, property) {
|
|
144
|
-
return req[property];
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Determine if object is a Stats object.
|
|
149
|
-
*
|
|
150
|
-
* @param {object} obj
|
|
151
|
-
* @return {boolean}
|
|
152
|
-
* @api private
|
|
153
|
-
*/ function isStatsObject(obj) {
|
|
154
|
-
// quack quack
|
|
155
|
-
return isObject(obj) && 'ctime' in obj && Object.prototype.toString.call(obj.ctime) === '[object Date]' && 'mtime' in obj && Object.prototype.toString.call(obj.mtime) === '[object Date]' && 'ino' in obj && typeof obj.ino === 'number' && 'size' in obj && typeof obj.size === 'number';
|
|
156
|
-
}
|
|
157
|
-
async function sha1(str) {
|
|
158
|
-
const enc = new TextEncoder();
|
|
159
|
-
const hash = await subtle.digest('SHA-1', enc.encode(str));
|
|
160
|
-
return btoa(String.fromCharCode(...new Uint8Array(hash)));
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Generate an ETag.
|
|
164
|
-
*/ async function generateETag(input) {
|
|
165
|
-
if (isStatsObject(input)) {
|
|
166
|
-
const mtime = input.mtime.getTime().toString(16);
|
|
167
|
-
const size = input.size.toString(16);
|
|
168
|
-
return `"${size}-${mtime}"`;
|
|
169
|
-
}
|
|
170
|
-
if (input.length === 0) {
|
|
171
|
-
// fast-path empty
|
|
172
|
-
return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"';
|
|
173
|
-
}
|
|
174
|
-
const entity = Buffer.isBuffer(input) ? input.toString('utf-8') : input;
|
|
175
|
-
// compute hash of entity
|
|
176
|
-
const hash = await sha1(entity);
|
|
177
|
-
return `"${entity.length.toString(16)}-${hash.substring(0, 27)}"`;
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Create a simple ETag.
|
|
181
|
-
*/ async function createEtag(input, options) {
|
|
182
|
-
options = options || {};
|
|
183
|
-
const weak = typeof options.weak === 'boolean' ? options.weak : isStatsObject(input);
|
|
184
|
-
// generate entity tag
|
|
185
|
-
const tag = await generateETag(input);
|
|
186
|
-
return weak ? `W/${tag}` : tag;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function buildEtagFn(input) {
|
|
190
|
-
if (typeof input === 'function') {
|
|
191
|
-
return input;
|
|
192
|
-
}
|
|
193
|
-
input = input ?? true;
|
|
194
|
-
if (input === false) {
|
|
195
|
-
return ()=>Promise.resolve(undefined);
|
|
196
|
-
}
|
|
197
|
-
let options = {
|
|
198
|
-
weak: true
|
|
199
|
-
};
|
|
200
|
-
if (isObject(input)) {
|
|
201
|
-
options = merge(input, options);
|
|
202
|
-
}
|
|
203
|
-
return async (body, encoding, size)=>{
|
|
204
|
-
const buff = Buffer.isBuffer(body) ? body : Buffer.from(body, encoding);
|
|
205
|
-
if (typeof options.threshold !== 'undefined') {
|
|
206
|
-
size = size ?? Buffer.byteLength(buff);
|
|
207
|
-
if (size <= options.threshold) {
|
|
208
|
-
return undefined;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return createEtag(buff, options);
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function buildTrustProxyFn(input) {
|
|
216
|
-
if (typeof input === 'function') {
|
|
217
|
-
return input;
|
|
218
|
-
}
|
|
219
|
-
if (input === true) {
|
|
220
|
-
return ()=>true;
|
|
221
|
-
}
|
|
222
|
-
if (typeof input === 'number') {
|
|
223
|
-
return (_address, hop)=>hop < input;
|
|
224
|
-
}
|
|
225
|
-
if (typeof input === 'string') {
|
|
226
|
-
input = input.split(',').map((value)=>value.trim());
|
|
227
|
-
}
|
|
228
|
-
return compile(input || []);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
function isInstance(input, sym) {
|
|
232
|
-
if (!isObject(input)) {
|
|
233
|
-
return false;
|
|
234
|
-
}
|
|
235
|
-
return input['@instanceof'] === sym;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function getMimeType(type) {
|
|
239
|
-
if (type.indexOf('/') !== -1) {
|
|
240
|
-
return type;
|
|
241
|
-
}
|
|
242
|
-
return getType(type);
|
|
243
|
-
}
|
|
244
|
-
function getCharsetForMimeType(type) {
|
|
245
|
-
if (/^text\/|^application\/(javascript|json)/.test(type)) {
|
|
246
|
-
return 'utf-8';
|
|
247
|
-
}
|
|
248
|
-
const meta = get(type);
|
|
249
|
-
if (meta && meta.charset) {
|
|
250
|
-
return meta.charset.toLowerCase();
|
|
251
|
-
}
|
|
252
|
-
return undefined;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function toMethodName(input, alt) {
|
|
256
|
-
if (input) {
|
|
257
|
-
return input.toUpperCase();
|
|
258
|
-
}
|
|
259
|
-
return alt;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const nextPlaceholder = (_err)=>{};
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Based on https://github.com/unjs/pathe v1.1.1 (055f50a6f1131f4e5c56cf259dd8816168fba329)
|
|
266
|
-
*/ function normalizeWindowsPath(input = '') {
|
|
267
|
-
if (!input || !input.includes('\\')) {
|
|
268
|
-
return input;
|
|
269
|
-
}
|
|
270
|
-
return input.replace(/\\/g, '/');
|
|
271
|
-
}
|
|
272
|
-
const EXTNAME_RE = /.(\.[^./]+)$/;
|
|
273
|
-
function extname(input) {
|
|
274
|
-
const match = EXTNAME_RE.exec(normalizeWindowsPath(input));
|
|
275
|
-
return match && match[1] || '';
|
|
276
|
-
}
|
|
277
|
-
function basename(input, extension) {
|
|
278
|
-
const lastSegment = normalizeWindowsPath(input).split('/').pop();
|
|
279
|
-
if (!lastSegment) {
|
|
280
|
-
return input;
|
|
281
|
-
}
|
|
282
|
-
return lastSegment;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
function isPromise(p) {
|
|
286
|
-
return isObject(p) && (p instanceof Promise || // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
287
|
-
// @ts-ignore
|
|
288
|
-
typeof p.then === 'function');
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
function isNodeStream(input) {
|
|
292
|
-
return isObject(input) && typeof input.pipe === 'function' && typeof input.read === 'function';
|
|
293
|
-
}
|
|
294
|
-
function isWebStream(input) {
|
|
295
|
-
return isObject(input) && typeof input.pipeTo === 'function';
|
|
296
|
-
}
|
|
297
|
-
function isStream(data) {
|
|
298
|
-
return isNodeStream(data) || isWebStream(data);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const TRAILING_SLASH_RE = /\/$|\/\?/;
|
|
302
|
-
function hasTrailingSlash(input = '', queryParams = false) {
|
|
303
|
-
if (!queryParams) {
|
|
304
|
-
return input.endsWith('/');
|
|
305
|
-
}
|
|
306
|
-
return TRAILING_SLASH_RE.test(input);
|
|
307
|
-
}
|
|
308
|
-
function withoutTrailingSlash(input = '', queryParams = false) {
|
|
309
|
-
if (!queryParams) {
|
|
310
|
-
return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || '/';
|
|
311
|
-
}
|
|
312
|
-
if (!hasTrailingSlash(input, true)) {
|
|
313
|
-
return input || '/';
|
|
314
|
-
}
|
|
315
|
-
const [s0, ...s] = input.split('?');
|
|
316
|
-
return (s0.slice(0, -1) || '/') + (s.length ? `?${s.join('?')}` : '');
|
|
317
|
-
}
|
|
318
|
-
function hasLeadingSlash(input = '') {
|
|
319
|
-
return input.startsWith('/');
|
|
320
|
-
}
|
|
321
|
-
function withLeadingSlash(input = '') {
|
|
322
|
-
return hasLeadingSlash(input) ? input : `/${input}`;
|
|
323
|
-
}
|
|
324
|
-
function cleanDoubleSlashes(input = '') {
|
|
325
|
-
if (input.indexOf('://') !== -1) {
|
|
326
|
-
return input.split('://').map((str)=>cleanDoubleSlashes(str)).join('://');
|
|
327
|
-
}
|
|
328
|
-
return input.replace(/\/+/g, '/');
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
function isWebBlob(input) {
|
|
332
|
-
return typeof Blob !== 'undefined' && input instanceof Blob;
|
|
333
|
-
}
|
|
334
|
-
function isWebResponse(input) {
|
|
335
|
-
return typeof Response !== 'undefined' && input instanceof Response;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
const symbol$4 = Symbol.for('ReqEnv');
|
|
339
|
-
function setRequestEnv(req, key, value) {
|
|
340
|
-
const propertyValue = getProperty(req, symbol$4);
|
|
341
|
-
if (propertyValue) {
|
|
342
|
-
if (typeof key === 'object') {
|
|
343
|
-
if (value) {
|
|
344
|
-
setProperty(req, symbol$4, merge(propertyValue, key));
|
|
345
|
-
} else {
|
|
346
|
-
setProperty(req, symbol$4, key);
|
|
347
|
-
}
|
|
348
|
-
} else {
|
|
349
|
-
propertyValue[key] = value;
|
|
350
|
-
setProperty(req, symbol$4, propertyValue);
|
|
351
|
-
}
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
if (typeof key === 'object') {
|
|
355
|
-
setProperty(req, symbol$4, key);
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
setProperty(req, symbol$4, {
|
|
359
|
-
[key]: value
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
function useRequestEnv(req, key) {
|
|
363
|
-
const propertyValue = getProperty(req, symbol$4);
|
|
364
|
-
if (propertyValue) {
|
|
365
|
-
if (typeof key !== 'undefined') {
|
|
366
|
-
return propertyValue[key];
|
|
367
|
-
}
|
|
368
|
-
return propertyValue;
|
|
369
|
-
}
|
|
370
|
-
if (typeof key !== 'undefined') {
|
|
371
|
-
return undefined;
|
|
372
|
-
}
|
|
373
|
-
return {};
|
|
374
|
-
}
|
|
375
|
-
function unsetRequestEnv(req, key) {
|
|
376
|
-
const propertyValue = getProperty(req, symbol$4);
|
|
377
|
-
if (hasOwnProperty(propertyValue, key)) {
|
|
378
|
-
delete propertyValue[key];
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
function getRequestHeader(req, name) {
|
|
383
|
-
return req.headers[name];
|
|
384
|
-
}
|
|
385
|
-
function setRequestHeader(req, name, value) {
|
|
386
|
-
req.headers[name] = value;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
const symbol$3 = Symbol.for('ReqNegotiator');
|
|
390
|
-
function useRequestNegotiator(req) {
|
|
391
|
-
let value = getProperty(req, symbol$3);
|
|
392
|
-
if (value) {
|
|
393
|
-
return value;
|
|
394
|
-
}
|
|
395
|
-
value = new Negotiator(req);
|
|
396
|
-
setProperty(req, symbol$3, value);
|
|
397
|
-
return value;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
function getRequestAcceptableContentTypes(req) {
|
|
401
|
-
const negotiator = useRequestNegotiator(req);
|
|
402
|
-
return negotiator.mediaTypes();
|
|
403
|
-
}
|
|
404
|
-
function getRequestAcceptableContentType(req, input) {
|
|
405
|
-
input = input || [];
|
|
406
|
-
const items = Array.isArray(input) ? input : [
|
|
407
|
-
input
|
|
408
|
-
];
|
|
409
|
-
if (items.length === 0) {
|
|
410
|
-
return getRequestAcceptableContentTypes(req).shift();
|
|
411
|
-
}
|
|
412
|
-
const header = getRequestHeader(req, HeaderName.ACCEPT);
|
|
413
|
-
if (!header) {
|
|
414
|
-
return items[0];
|
|
415
|
-
}
|
|
416
|
-
let polluted = false;
|
|
417
|
-
const mimeTypes = [];
|
|
418
|
-
for(let i = 0; i < items.length; i++){
|
|
419
|
-
const mimeType = getMimeType(items[i]);
|
|
420
|
-
if (mimeType) {
|
|
421
|
-
mimeTypes.push(mimeType);
|
|
422
|
-
} else {
|
|
423
|
-
polluted = true;
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
const negotiator = useRequestNegotiator(req);
|
|
427
|
-
const matches = negotiator.mediaTypes(mimeTypes);
|
|
428
|
-
if (matches.length > 0) {
|
|
429
|
-
if (polluted) {
|
|
430
|
-
return items[0];
|
|
431
|
-
}
|
|
432
|
-
return items[mimeTypes.indexOf(matches[0])];
|
|
433
|
-
}
|
|
434
|
-
return undefined;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
function getRequestAcceptableCharsets(req) {
|
|
438
|
-
const negotiator = useRequestNegotiator(req);
|
|
439
|
-
return negotiator.charsets();
|
|
440
|
-
}
|
|
441
|
-
function getRequestAcceptableCharset(req, input) {
|
|
442
|
-
input = input || [];
|
|
443
|
-
const items = Array.isArray(input) ? input : [
|
|
444
|
-
input
|
|
445
|
-
];
|
|
446
|
-
if (items.length === 0) {
|
|
447
|
-
return getRequestAcceptableCharsets(req).shift();
|
|
448
|
-
}
|
|
449
|
-
const negotiator = useRequestNegotiator(req);
|
|
450
|
-
return negotiator.charsets(items).shift() || undefined;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function getRequestAcceptableEncodings(req) {
|
|
454
|
-
const negotiator = useRequestNegotiator(req);
|
|
455
|
-
return negotiator.encodings();
|
|
456
|
-
}
|
|
457
|
-
function getRequestAcceptableEncoding(req, input) {
|
|
458
|
-
input = input || [];
|
|
459
|
-
const items = Array.isArray(input) ? input : [
|
|
460
|
-
input
|
|
461
|
-
];
|
|
462
|
-
if (items.length === 0) {
|
|
463
|
-
return getRequestAcceptableEncodings(req).shift();
|
|
464
|
-
}
|
|
465
|
-
const negotiator = useRequestNegotiator(req);
|
|
466
|
-
return negotiator.encodings(items).shift() || undefined;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
function getRequestAcceptableLanguages(req) {
|
|
470
|
-
const negotiator = useRequestNegotiator(req);
|
|
471
|
-
return negotiator.languages();
|
|
472
|
-
}
|
|
473
|
-
function getRequestAcceptableLanguage(req, input) {
|
|
474
|
-
input = input || [];
|
|
475
|
-
const items = Array.isArray(input) ? input : [
|
|
476
|
-
input
|
|
477
|
-
];
|
|
478
|
-
if (items.length === 0) {
|
|
479
|
-
return getRequestAcceptableLanguages(req).shift();
|
|
480
|
-
}
|
|
481
|
-
const negotiator = useRequestNegotiator(req);
|
|
482
|
-
return negotiator.languages(items).shift() || undefined;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
function matchRequestContentType(req, contentType) {
|
|
486
|
-
const header = getRequestHeader(req, HeaderName.CONTENT_TYPE);
|
|
487
|
-
if (!header) {
|
|
488
|
-
return true;
|
|
489
|
-
}
|
|
490
|
-
/* istanbul ignore next */ if (Array.isArray(header)) {
|
|
491
|
-
if (header.length === 0) {
|
|
492
|
-
return true;
|
|
493
|
-
}
|
|
494
|
-
return header[0] === getMimeType(contentType);
|
|
495
|
-
}
|
|
496
|
-
return header.split('; ').shift() === getMimeType(contentType);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
const defaults = {
|
|
500
|
-
trustProxy: ()=>false,
|
|
501
|
-
subdomainOffset: 2,
|
|
502
|
-
etag: buildEtagFn(),
|
|
503
|
-
proxyIpMax: 0
|
|
504
|
-
};
|
|
505
|
-
const instances = {};
|
|
506
|
-
function setRouterOptions(id, input) {
|
|
507
|
-
instances[id] = input;
|
|
508
|
-
}
|
|
509
|
-
function findRouterOption(key, path) {
|
|
510
|
-
if (!path || path.length === 0) {
|
|
511
|
-
return defaults[key];
|
|
512
|
-
}
|
|
513
|
-
if (path.length > 0) {
|
|
514
|
-
for(let i = path.length; i >= 0; i--){
|
|
515
|
-
if (hasOwnProperty(instances, path[i]) && typeof instances[path[i]][key] !== 'undefined') {
|
|
516
|
-
return instances[path[i]][key];
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
return defaults[key];
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
const routerSymbol = Symbol.for('ReqRouterID');
|
|
524
|
-
function setRequestRouterPath(req, path) {
|
|
525
|
-
setProperty(req, routerSymbol, path);
|
|
526
|
-
}
|
|
527
|
-
function useRequestRouterPath(req) {
|
|
528
|
-
return getProperty(req, routerSymbol);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
function getRequestHostName(req, options) {
|
|
532
|
-
options = options || {};
|
|
533
|
-
let trustProxy;
|
|
534
|
-
if (typeof options.trustProxy !== 'undefined') {
|
|
535
|
-
trustProxy = buildTrustProxyFn(options.trustProxy);
|
|
536
|
-
} else {
|
|
537
|
-
trustProxy = findRouterOption('trustProxy', useRequestRouterPath(req));
|
|
538
|
-
}
|
|
539
|
-
let hostname = req.headers[HeaderName.X_FORWARDED_HOST];
|
|
540
|
-
if (!hostname || !req.socket.remoteAddress || !trustProxy(req.socket.remoteAddress, 0)) {
|
|
541
|
-
hostname = req.headers[HeaderName.HOST];
|
|
542
|
-
} else {
|
|
543
|
-
hostname = Array.isArray(hostname) ? hostname.pop() : hostname;
|
|
544
|
-
if (hostname && hostname.indexOf(',') !== -1) {
|
|
545
|
-
hostname = hostname.substring(0, hostname.indexOf(',')).trimEnd();
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
if (!hostname) {
|
|
549
|
-
return undefined;
|
|
550
|
-
}
|
|
551
|
-
// IPv6 literal support
|
|
552
|
-
const offset = hostname[0] === '[' ? hostname.indexOf(']') + 1 : 0;
|
|
553
|
-
const index = hostname.indexOf(':', offset);
|
|
554
|
-
return index !== -1 ? hostname.substring(0, index) : hostname;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
function isRequestHTTP2(req) {
|
|
558
|
-
return typeof getRequestHeader(req, ':path') !== 'undefined' && typeof getRequestHeader(req, ':method') !== 'undefined';
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
function getRequestIP(req, options) {
|
|
562
|
-
options = options || {};
|
|
563
|
-
let trustProxy;
|
|
564
|
-
if (typeof options.trustProxy !== 'undefined') {
|
|
565
|
-
trustProxy = buildTrustProxyFn(options.trustProxy);
|
|
566
|
-
} else {
|
|
567
|
-
trustProxy = findRouterOption('trustProxy', useRequestRouterPath(req));
|
|
568
|
-
}
|
|
569
|
-
const addrs = all(req, trustProxy);
|
|
570
|
-
return addrs[addrs.length - 1];
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
const symbol$2 = Symbol.for('ReqMountPath');
|
|
574
|
-
function useRequestMountPath(req) {
|
|
575
|
-
return getProperty(req, symbol$2) || '/';
|
|
576
|
-
}
|
|
577
|
-
function setRequestMountPath(req, basePath) {
|
|
578
|
-
setProperty(req, symbol$2, basePath);
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
const symbol$1 = Symbol.for('ReqParams');
|
|
582
|
-
function useRequestParams(req) {
|
|
583
|
-
return getProperty(req, symbol$1) || getProperty(req, 'params') || {};
|
|
584
|
-
}
|
|
585
|
-
function useRequestParam(req, key) {
|
|
586
|
-
return useRequestParams(req)[key];
|
|
587
|
-
}
|
|
588
|
-
function setRequestParams(req, data) {
|
|
589
|
-
setProperty(req, symbol$1, data);
|
|
590
|
-
}
|
|
591
|
-
function setRequestParam(req, key, value) {
|
|
592
|
-
const params = useRequestParams(req);
|
|
593
|
-
params[key] = value;
|
|
594
|
-
setRequestParams(req, params);
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
const PathSymbol = Symbol.for('ReqPath');
|
|
598
|
-
function useRequestPath(req) {
|
|
599
|
-
const path = getProperty(req, 'path') || getProperty(req, PathSymbol);
|
|
600
|
-
if (path) {
|
|
601
|
-
return path;
|
|
602
|
-
}
|
|
603
|
-
if (typeof req.url === 'undefined') {
|
|
604
|
-
return '/';
|
|
605
|
-
}
|
|
606
|
-
const parsed = new URL(req.url, 'http://localhost/');
|
|
607
|
-
setProperty(req, PathSymbol, parsed.pathname);
|
|
608
|
-
return parsed.pathname;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
function getRequestProtocol(req, options) {
|
|
612
|
-
options = options || {};
|
|
613
|
-
let trustProxy;
|
|
614
|
-
if (typeof options.trustProxy !== 'undefined') {
|
|
615
|
-
trustProxy = buildTrustProxyFn(options.trustProxy);
|
|
616
|
-
} else {
|
|
617
|
-
trustProxy = findRouterOption('trustProxy', useRequestRouterPath(req));
|
|
618
|
-
}
|
|
619
|
-
let protocol = options.default;
|
|
620
|
-
/* istanbul ignore next */ if (hasOwnProperty(req.socket, 'encrypted') && !!req.socket.encrypted) {
|
|
621
|
-
protocol = 'https';
|
|
622
|
-
} else if (!protocol) {
|
|
623
|
-
protocol = 'http';
|
|
624
|
-
}
|
|
625
|
-
if (!req.socket.remoteAddress || !trustProxy(req.socket.remoteAddress, 0)) {
|
|
626
|
-
return protocol;
|
|
627
|
-
}
|
|
628
|
-
let header = req.headers[HeaderName.X_FORWARDED_PROTO];
|
|
629
|
-
/* istanbul ignore next */ if (Array.isArray(header)) {
|
|
630
|
-
header = header.pop();
|
|
631
|
-
}
|
|
632
|
-
if (!header) {
|
|
633
|
-
return protocol;
|
|
634
|
-
}
|
|
635
|
-
const index = header.indexOf(',');
|
|
636
|
-
return index !== -1 ? header.substring(0, index).trim() : header.trim();
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
function createRequest(context) {
|
|
640
|
-
let readable;
|
|
641
|
-
if (context.body) {
|
|
642
|
-
if (isWebStream(context.body)) {
|
|
643
|
-
readable = Readable.fromWeb(context.body);
|
|
644
|
-
} else {
|
|
645
|
-
readable = Readable.from(context.body);
|
|
646
|
-
}
|
|
647
|
-
} else {
|
|
648
|
-
readable = new Readable();
|
|
649
|
-
}
|
|
650
|
-
const headers = context.headers || {};
|
|
651
|
-
const rawHeaders = [];
|
|
652
|
-
let keys = Object.keys(headers);
|
|
653
|
-
for(let i = 0; i < keys.length; i++){
|
|
654
|
-
const header = headers[keys[i]];
|
|
655
|
-
if (Array.isArray(header)) {
|
|
656
|
-
for(let j = 0; j < header.length; j++){
|
|
657
|
-
rawHeaders.push(keys[i], header[j]);
|
|
658
|
-
}
|
|
659
|
-
} else if (typeof header === 'string') {
|
|
660
|
-
rawHeaders.push(keys[i], header);
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
const headersDistinct = {};
|
|
664
|
-
keys = Object.keys(headers);
|
|
665
|
-
for(let i = 0; i < keys.length; i++){
|
|
666
|
-
const header = headers[keys[i]];
|
|
667
|
-
if (Array.isArray(header)) {
|
|
668
|
-
headersDistinct[keys[i]] = header;
|
|
669
|
-
}
|
|
670
|
-
if (typeof header === 'string') {
|
|
671
|
-
headersDistinct[keys[i]] = [
|
|
672
|
-
header
|
|
673
|
-
];
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
Object.defineProperty(readable, 'connection', {
|
|
677
|
-
get () {
|
|
678
|
-
return {
|
|
679
|
-
remoteAddress: '127.0.0.1'
|
|
680
|
-
};
|
|
681
|
-
}
|
|
682
|
-
});
|
|
683
|
-
Object.defineProperty(readable, 'socket', {
|
|
684
|
-
get () {
|
|
685
|
-
return {
|
|
686
|
-
remoteAddress: '127.0.0.1'
|
|
687
|
-
};
|
|
688
|
-
}
|
|
689
|
-
});
|
|
690
|
-
Object.assign(readable, {
|
|
691
|
-
aborted: false,
|
|
692
|
-
complete: true,
|
|
693
|
-
headers,
|
|
694
|
-
headersDistinct,
|
|
695
|
-
httpVersion: '1.1',
|
|
696
|
-
httpVersionMajor: 1,
|
|
697
|
-
httpVersionMinor: 1,
|
|
698
|
-
method: context.method || 'GET',
|
|
699
|
-
rawHeaders,
|
|
700
|
-
rawTrailers: [],
|
|
701
|
-
trailers: {},
|
|
702
|
-
trailersDistinct: {},
|
|
703
|
-
url: context.url || '/',
|
|
704
|
-
setTimeout (_msecs, _callback) {
|
|
705
|
-
return this;
|
|
706
|
-
}
|
|
707
|
-
});
|
|
708
|
-
return readable;
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
class RoutupError extends HTTPError {
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
function isError(input) {
|
|
715
|
-
return input instanceof RoutupError;
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
/**
|
|
719
|
-
* Create an internal error object by
|
|
720
|
-
* - an existing error (accessible via cause property)
|
|
721
|
-
* - options
|
|
722
|
-
* - message
|
|
723
|
-
*
|
|
724
|
-
* @param input
|
|
725
|
-
*/ function createError(input) {
|
|
726
|
-
if (isError(input)) {
|
|
727
|
-
return input;
|
|
728
|
-
}
|
|
729
|
-
if (typeof input === 'string') {
|
|
730
|
-
return new RoutupError(input);
|
|
731
|
-
}
|
|
732
|
-
if (!isObject(input)) {
|
|
733
|
-
return new RoutupError();
|
|
734
|
-
}
|
|
735
|
-
return new RoutupError({
|
|
736
|
-
cause: input
|
|
737
|
-
}, input);
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
function setResponseCacheHeaders(res, options) {
|
|
741
|
-
options = options || {};
|
|
742
|
-
const cacheControls = [
|
|
743
|
-
'public'
|
|
744
|
-
].concat(options.cacheControls || []);
|
|
745
|
-
if (options.maxAge !== undefined) {
|
|
746
|
-
cacheControls.push(`max-age=${+options.maxAge}`, `s-maxage=${+options.maxAge}`);
|
|
747
|
-
}
|
|
748
|
-
if (options.modifiedTime) {
|
|
749
|
-
const modifiedTime = typeof options.modifiedTime === 'string' ? new Date(options.modifiedTime) : options.modifiedTime;
|
|
750
|
-
res.setHeader('last-modified', modifiedTime.toUTCString());
|
|
751
|
-
}
|
|
752
|
-
res.setHeader('cache-control', cacheControls.join(', '));
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
const symbol = Symbol.for('ResGone');
|
|
756
|
-
function isResponseGone(res) {
|
|
757
|
-
if (res.headersSent || res.writableEnded) {
|
|
758
|
-
return true;
|
|
759
|
-
}
|
|
760
|
-
return getProperty(res, symbol) ?? false;
|
|
761
|
-
}
|
|
762
|
-
function setResponseGone(res, value) {
|
|
763
|
-
setProperty(res, symbol, value);
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
function serializeEventStreamMessage(message) {
|
|
767
|
-
let result = '';
|
|
768
|
-
if (message.id) {
|
|
769
|
-
result += `id: ${message.id}\n`;
|
|
770
|
-
}
|
|
771
|
-
if (message.event) {
|
|
772
|
-
result += `event: ${message.event}\n`;
|
|
773
|
-
}
|
|
774
|
-
if (typeof message.retry === 'number' && Number.isInteger(message.retry)) {
|
|
775
|
-
result += `retry: ${message.retry}\n`;
|
|
776
|
-
}
|
|
777
|
-
result += `data: ${message.data}\n\n`;
|
|
778
|
-
return result;
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
class EventStream {
|
|
782
|
-
open() {
|
|
783
|
-
this.response.req.on('close', ()=>this.end());
|
|
784
|
-
this.response.req.on('error', (err)=>{
|
|
785
|
-
this.emit('error', err);
|
|
786
|
-
this.end();
|
|
787
|
-
});
|
|
788
|
-
this.passThrough.on('data', (chunk)=>this.response.write(chunk));
|
|
789
|
-
this.passThrough.on('error', (err)=>{
|
|
790
|
-
this.emit('error', err);
|
|
791
|
-
this.end();
|
|
792
|
-
});
|
|
793
|
-
this.passThrough.on('close', ()=>this.end());
|
|
794
|
-
this.response.setHeader(HeaderName.CONTENT_TYPE, 'text/event-stream');
|
|
795
|
-
this.response.setHeader(HeaderName.CACHE_CONTROL, 'private, no-cache, no-store, no-transform, must-revalidate, max-age=0');
|
|
796
|
-
this.response.setHeader(HeaderName.X_ACCEL_BUFFERING, 'no');
|
|
797
|
-
if (!isRequestHTTP2(this.response.req)) {
|
|
798
|
-
this.response.setHeader(HeaderName.CONNECTION, 'keep-alive');
|
|
799
|
-
}
|
|
800
|
-
this.response.statusCode = 200;
|
|
801
|
-
}
|
|
802
|
-
write(message) {
|
|
803
|
-
if (typeof message === 'string') {
|
|
804
|
-
this.write({
|
|
805
|
-
data: message
|
|
806
|
-
});
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
if (!this.passThrough.closed && this.passThrough.writable) {
|
|
810
|
-
this.passThrough.write(serializeEventStreamMessage(message));
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
end() {
|
|
814
|
-
if (this.flushed) return;
|
|
815
|
-
this.flushed = true;
|
|
816
|
-
if (!this.passThrough.closed) {
|
|
817
|
-
this.passThrough.end();
|
|
818
|
-
}
|
|
819
|
-
this.emit('close');
|
|
820
|
-
setResponseGone(this.response, true);
|
|
821
|
-
this.response.end();
|
|
822
|
-
}
|
|
823
|
-
on(event, listener) {
|
|
824
|
-
if (typeof this.eventHandlers[event] === 'undefined') {
|
|
825
|
-
this.eventHandlers[event] = [];
|
|
826
|
-
}
|
|
827
|
-
this.eventHandlers[event].push(listener);
|
|
828
|
-
}
|
|
829
|
-
emit(event, ...args) {
|
|
830
|
-
if (typeof this.eventHandlers[event] === 'undefined') {
|
|
831
|
-
return;
|
|
832
|
-
}
|
|
833
|
-
const listeners = this.eventHandlers[event].slice();
|
|
834
|
-
for(let i = 0; i < listeners.length; i++){
|
|
835
|
-
listeners[i].apply(this, args);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
constructor(response){
|
|
839
|
-
this.response = response;
|
|
840
|
-
this.passThrough = new PassThrough({
|
|
841
|
-
encoding: 'utf-8'
|
|
842
|
-
});
|
|
843
|
-
this.flushed = false;
|
|
844
|
-
this.eventHandlers = {};
|
|
845
|
-
this.open();
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
function createEventStream(response) {
|
|
850
|
-
return new EventStream(response);
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
function appendResponseHeader(res, name, value) {
|
|
854
|
-
let header = res.getHeader(name);
|
|
855
|
-
if (!header) {
|
|
856
|
-
res.setHeader(name, value);
|
|
857
|
-
return;
|
|
858
|
-
}
|
|
859
|
-
if (!Array.isArray(header)) {
|
|
860
|
-
header = [
|
|
861
|
-
header.toString()
|
|
862
|
-
];
|
|
863
|
-
}
|
|
864
|
-
res.setHeader(name, [
|
|
865
|
-
...header,
|
|
866
|
-
value
|
|
867
|
-
]);
|
|
868
|
-
}
|
|
869
|
-
function appendResponseHeaderDirective(res, name, value) {
|
|
870
|
-
let header = res.getHeader(name);
|
|
871
|
-
if (!header) {
|
|
872
|
-
if (Array.isArray(value)) {
|
|
873
|
-
res.setHeader(name, value.join('; '));
|
|
874
|
-
return;
|
|
875
|
-
}
|
|
876
|
-
res.setHeader(name, value);
|
|
877
|
-
return;
|
|
878
|
-
}
|
|
879
|
-
if (!Array.isArray(header)) {
|
|
880
|
-
if (typeof header === 'string') {
|
|
881
|
-
// split header by directive(s)
|
|
882
|
-
header = header.split('; ');
|
|
883
|
-
}
|
|
884
|
-
if (typeof header === 'number') {
|
|
885
|
-
header = [
|
|
886
|
-
header.toString()
|
|
887
|
-
];
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
if (Array.isArray(value)) {
|
|
891
|
-
header.push(...value);
|
|
892
|
-
} else {
|
|
893
|
-
header.push(`${value}`);
|
|
894
|
-
}
|
|
895
|
-
header = [
|
|
896
|
-
...new Set(header)
|
|
897
|
-
];
|
|
898
|
-
res.setHeader(name, header.join('; '));
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
function setResponseContentTypeByFileName(res, fileName) {
|
|
902
|
-
const ext = extname(fileName);
|
|
903
|
-
if (ext) {
|
|
904
|
-
let type = getMimeType(ext.substring(1));
|
|
905
|
-
if (type) {
|
|
906
|
-
const charset = getCharsetForMimeType(type);
|
|
907
|
-
if (charset) {
|
|
908
|
-
type += `; charset=${charset}`;
|
|
909
|
-
}
|
|
910
|
-
res.setHeader(HeaderName.CONTENT_TYPE, type);
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
function setResponseHeaderAttachment(res, filename) {
|
|
916
|
-
if (typeof filename === 'string') {
|
|
917
|
-
setResponseContentTypeByFileName(res, filename);
|
|
918
|
-
}
|
|
919
|
-
res.setHeader(HeaderName.CONTENT_DISPOSITION, `attachment${filename ? `; filename="${filename}"` : ''}`);
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
function setResponseHeaderContentType(res, input, ifNotExists) {
|
|
923
|
-
if (ifNotExists) {
|
|
924
|
-
const header = res.getHeader(HeaderName.CONTENT_TYPE);
|
|
925
|
-
if (header) {
|
|
926
|
-
return;
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
const contentType = getMimeType(input);
|
|
930
|
-
if (contentType) {
|
|
931
|
-
res.setHeader(HeaderName.CONTENT_TYPE, contentType);
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
async function sendStream(res, stream, next) {
|
|
936
|
-
if (isWebStream(stream)) {
|
|
937
|
-
return stream.pipeTo(new WritableStream({
|
|
938
|
-
write (chunk) {
|
|
939
|
-
res.write(chunk);
|
|
940
|
-
}
|
|
941
|
-
})).then(()=>{
|
|
942
|
-
if (next) {
|
|
943
|
-
return next();
|
|
944
|
-
}
|
|
945
|
-
res.end();
|
|
946
|
-
return Promise.resolve();
|
|
947
|
-
}).catch((err)=>{
|
|
948
|
-
if (next) {
|
|
949
|
-
return next(err);
|
|
950
|
-
}
|
|
951
|
-
return Promise.reject(err);
|
|
952
|
-
});
|
|
953
|
-
}
|
|
954
|
-
return new Promise((resolve, reject)=>{
|
|
955
|
-
stream.on('open', ()=>{
|
|
956
|
-
stream.pipe(res);
|
|
957
|
-
});
|
|
958
|
-
/* istanbul ignore next */ stream.on('error', (err)=>{
|
|
959
|
-
if (next) {
|
|
960
|
-
Promise.resolve().then(()=>next(err)).then(()=>resolve()).catch((e)=>reject(e));
|
|
961
|
-
return;
|
|
962
|
-
}
|
|
963
|
-
res.end();
|
|
964
|
-
reject(err);
|
|
965
|
-
});
|
|
966
|
-
stream.on('close', ()=>{
|
|
967
|
-
if (next) {
|
|
968
|
-
Promise.resolve().then(()=>next()).then(()=>resolve()).catch((e)=>reject(e));
|
|
969
|
-
return;
|
|
970
|
-
}
|
|
971
|
-
res.end();
|
|
972
|
-
resolve();
|
|
973
|
-
});
|
|
974
|
-
});
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
async function sendWebBlob(res, blob) {
|
|
978
|
-
setResponseHeaderContentType(res, blob.type);
|
|
979
|
-
await sendStream(res, blob.stream());
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
async function sendWebResponse(res, webResponse) {
|
|
983
|
-
if (webResponse.redirected) {
|
|
984
|
-
res.setHeader(HeaderName.LOCATION, webResponse.url);
|
|
985
|
-
}
|
|
986
|
-
if (webResponse.status) {
|
|
987
|
-
res.statusCode = webResponse.status;
|
|
988
|
-
}
|
|
989
|
-
if (webResponse.statusText) {
|
|
990
|
-
res.statusMessage = webResponse.statusText;
|
|
991
|
-
}
|
|
992
|
-
webResponse.headers.forEach((value, key)=>{
|
|
993
|
-
if (key === HeaderName.SET_COOKIE) {
|
|
994
|
-
res.appendHeader(key, splitCookiesString(value));
|
|
995
|
-
} else {
|
|
996
|
-
res.setHeader(key, value);
|
|
997
|
-
}
|
|
998
|
-
});
|
|
999
|
-
if (webResponse.body) {
|
|
1000
|
-
await sendStream(res, webResponse.body);
|
|
1001
|
-
return Promise.resolve();
|
|
1002
|
-
}
|
|
1003
|
-
res.end();
|
|
1004
|
-
return Promise.resolve();
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
async function send(res, chunk) {
|
|
1008
|
-
switch(typeof chunk){
|
|
1009
|
-
case 'string':
|
|
1010
|
-
{
|
|
1011
|
-
setResponseHeaderContentType(res, 'html', true);
|
|
1012
|
-
break;
|
|
1013
|
-
}
|
|
1014
|
-
case 'boolean':
|
|
1015
|
-
case 'number':
|
|
1016
|
-
case 'object':
|
|
1017
|
-
{
|
|
1018
|
-
if (chunk !== null) {
|
|
1019
|
-
if (chunk instanceof Error) {
|
|
1020
|
-
throw chunk;
|
|
1021
|
-
}
|
|
1022
|
-
if (isStream(chunk)) {
|
|
1023
|
-
await sendStream(res, chunk);
|
|
1024
|
-
return;
|
|
1025
|
-
}
|
|
1026
|
-
if (isWebBlob(chunk)) {
|
|
1027
|
-
await sendWebBlob(res, chunk);
|
|
1028
|
-
return;
|
|
1029
|
-
}
|
|
1030
|
-
if (isWebResponse(chunk)) {
|
|
1031
|
-
await sendWebResponse(res, chunk);
|
|
1032
|
-
return;
|
|
1033
|
-
}
|
|
1034
|
-
if (Buffer.isBuffer(chunk)) {
|
|
1035
|
-
setResponseHeaderContentType(res, 'bin', true);
|
|
1036
|
-
} else {
|
|
1037
|
-
chunk = JSON.stringify(chunk);
|
|
1038
|
-
setResponseHeaderContentType(res, 'application/json', true);
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
break;
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
let encoding;
|
|
1045
|
-
if (typeof chunk === 'string') {
|
|
1046
|
-
res.setHeader(HeaderName.CONTENT_ENCODING, 'utf-8');
|
|
1047
|
-
appendResponseHeaderDirective(res, HeaderName.CONTENT_TYPE, 'charset=utf-8');
|
|
1048
|
-
encoding = 'utf-8';
|
|
1049
|
-
}
|
|
1050
|
-
// populate Content-Length
|
|
1051
|
-
let len;
|
|
1052
|
-
if (chunk !== undefined && chunk !== null) {
|
|
1053
|
-
if (Buffer.isBuffer(chunk)) {
|
|
1054
|
-
// get length of Buffer
|
|
1055
|
-
len = chunk.length;
|
|
1056
|
-
} else if (chunk.length < 1000) {
|
|
1057
|
-
// just calculate length when no ETag + small chunk
|
|
1058
|
-
len = Buffer.byteLength(chunk, encoding);
|
|
1059
|
-
} else {
|
|
1060
|
-
// convert chunk to Buffer and calculate
|
|
1061
|
-
chunk = Buffer.from(chunk, encoding);
|
|
1062
|
-
encoding = undefined;
|
|
1063
|
-
len = chunk.length;
|
|
1064
|
-
}
|
|
1065
|
-
res.setHeader(HeaderName.CONTENT_LENGTH, `${len}`);
|
|
1066
|
-
}
|
|
1067
|
-
if (typeof len !== 'undefined') {
|
|
1068
|
-
const etagFn = findRouterOption('etag', useRequestRouterPath(res.req));
|
|
1069
|
-
const chunkHash = await etagFn(chunk, encoding, len);
|
|
1070
|
-
if (isResponseGone(res)) {
|
|
1071
|
-
return;
|
|
1072
|
-
}
|
|
1073
|
-
if (typeof chunkHash === 'string') {
|
|
1074
|
-
res.setHeader(HeaderName.ETag, chunkHash);
|
|
1075
|
-
if (res.req.headers[HeaderName.IF_NONE_MATCH] === chunkHash) {
|
|
1076
|
-
res.statusCode = 304;
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
// strip irrelevant headers
|
|
1081
|
-
if (res.statusCode === 204 || res.statusCode === 304) {
|
|
1082
|
-
res.removeHeader(HeaderName.CONTENT_TYPE);
|
|
1083
|
-
res.removeHeader(HeaderName.CONTENT_LENGTH);
|
|
1084
|
-
res.removeHeader(HeaderName.TRANSFER_ENCODING);
|
|
1085
|
-
}
|
|
1086
|
-
// alter headers for 205
|
|
1087
|
-
if (res.statusCode === 205) {
|
|
1088
|
-
res.setHeader(HeaderName.CONTENT_LENGTH, 0);
|
|
1089
|
-
res.removeHeader(HeaderName.TRANSFER_ENCODING);
|
|
1090
|
-
}
|
|
1091
|
-
if (isResponseGone(res)) {
|
|
1092
|
-
return;
|
|
1093
|
-
}
|
|
1094
|
-
if (res.req.method === 'HEAD' || res.req.method === 'head') {
|
|
1095
|
-
// skip body for HEAD
|
|
1096
|
-
res.end();
|
|
1097
|
-
return;
|
|
1098
|
-
}
|
|
1099
|
-
if (typeof chunk === 'undefined' || chunk === null) {
|
|
1100
|
-
res.end();
|
|
1101
|
-
return;
|
|
1102
|
-
}
|
|
1103
|
-
if (typeof encoding !== 'undefined') {
|
|
1104
|
-
res.end(chunk, encoding);
|
|
1105
|
-
return;
|
|
1106
|
-
}
|
|
1107
|
-
res.end(chunk);
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
function sendAccepted(res, chunk) {
|
|
1111
|
-
res.statusCode = 202;
|
|
1112
|
-
res.statusMessage = 'Accepted';
|
|
1113
|
-
return send(res, chunk);
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
function sendCreated(res, chunk) {
|
|
1117
|
-
res.statusCode = 201;
|
|
1118
|
-
res.statusMessage = 'Created';
|
|
1119
|
-
return send(res, chunk);
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
async function sendFile(res, options, next) {
|
|
1123
|
-
let stats;
|
|
1124
|
-
try {
|
|
1125
|
-
stats = await options.stats();
|
|
1126
|
-
} catch (e) {
|
|
1127
|
-
if (next) {
|
|
1128
|
-
return next(e);
|
|
1129
|
-
}
|
|
1130
|
-
if (isResponseGone(res)) {
|
|
1131
|
-
return Promise.resolve();
|
|
1132
|
-
}
|
|
1133
|
-
return Promise.reject(e);
|
|
1134
|
-
}
|
|
1135
|
-
const name = options.name || stats.name;
|
|
1136
|
-
if (name) {
|
|
1137
|
-
const fileName = basename(name);
|
|
1138
|
-
if (options.attachment) {
|
|
1139
|
-
const dispositionHeader = res.getHeader(HeaderName.CONTENT_DISPOSITION);
|
|
1140
|
-
if (!dispositionHeader) {
|
|
1141
|
-
setResponseHeaderAttachment(res, fileName);
|
|
1142
|
-
}
|
|
1143
|
-
} else {
|
|
1144
|
-
setResponseContentTypeByFileName(res, fileName);
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
const contentOptions = {};
|
|
1148
|
-
if (stats.size) {
|
|
1149
|
-
const rangeHeader = res.req.headers[HeaderName.RANGE];
|
|
1150
|
-
if (rangeHeader) {
|
|
1151
|
-
const [x, y] = rangeHeader.replace('bytes=', '').split('-');
|
|
1152
|
-
contentOptions.end = Math.min(parseInt(y, 10) || stats.size - 1, stats.size - 1);
|
|
1153
|
-
contentOptions.start = parseInt(x, 10) || 0;
|
|
1154
|
-
if (contentOptions.end >= stats.size) {
|
|
1155
|
-
contentOptions.end = stats.size - 1;
|
|
1156
|
-
}
|
|
1157
|
-
if (contentOptions.start >= stats.size) {
|
|
1158
|
-
res.setHeader(HeaderName.CONTENT_RANGE, `bytes */${stats.size}`);
|
|
1159
|
-
res.statusCode = 416;
|
|
1160
|
-
res.end();
|
|
1161
|
-
return Promise.resolve();
|
|
1162
|
-
}
|
|
1163
|
-
res.setHeader(HeaderName.CONTENT_RANGE, `bytes ${contentOptions.start}-${contentOptions.end}/${stats.size}`);
|
|
1164
|
-
res.setHeader(HeaderName.CONTENT_LENGTH, contentOptions.end - contentOptions.start + 1);
|
|
1165
|
-
} else {
|
|
1166
|
-
res.setHeader(HeaderName.CONTENT_LENGTH, stats.size);
|
|
1167
|
-
}
|
|
1168
|
-
res.setHeader(HeaderName.ACCEPT_RANGES, 'bytes');
|
|
1169
|
-
if (stats.mtime) {
|
|
1170
|
-
const mtime = new Date(stats.mtime);
|
|
1171
|
-
res.setHeader(HeaderName.LAST_MODIFIED, mtime.toUTCString());
|
|
1172
|
-
res.setHeader(HeaderName.ETag, `W/"${stats.size}-${mtime.getTime()}"`);
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
try {
|
|
1176
|
-
const content = await options.content(contentOptions);
|
|
1177
|
-
if (isStream(content)) {
|
|
1178
|
-
return await sendStream(res, content, next);
|
|
1179
|
-
}
|
|
1180
|
-
return await send(res, content);
|
|
1181
|
-
} catch (e) {
|
|
1182
|
-
if (next) {
|
|
1183
|
-
return next(e);
|
|
1184
|
-
}
|
|
1185
|
-
if (isResponseGone(res)) {
|
|
1186
|
-
return Promise.resolve();
|
|
1187
|
-
}
|
|
1188
|
-
return Promise.reject(e);
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1192
|
-
function sendFormat(res, input) {
|
|
1193
|
-
const { default: formatDefault, ...formats } = input;
|
|
1194
|
-
const contentTypes = Object.keys(formats);
|
|
1195
|
-
const contentType = getRequestAcceptableContentType(res.req, contentTypes);
|
|
1196
|
-
if (contentType) {
|
|
1197
|
-
formats[contentType]();
|
|
1198
|
-
return;
|
|
1199
|
-
}
|
|
1200
|
-
formatDefault();
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
function sendRedirect(res, location, statusCode = 302) {
|
|
1204
|
-
res.statusCode = statusCode;
|
|
1205
|
-
res.setHeader('location', location);
|
|
1206
|
-
const encodedLoc = location.replace(/"/g, '%22');
|
|
1207
|
-
const html = `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`;
|
|
1208
|
-
return send(res, html);
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
function createResponse(request) {
|
|
1212
|
-
let output;
|
|
1213
|
-
let encoding;
|
|
1214
|
-
const write = (chunk, chunkEncoding, callback)=>{
|
|
1215
|
-
if (typeof chunk !== 'undefined') {
|
|
1216
|
-
const chunkEncoded = typeof chunk === 'string' ? Buffer.from(chunk, chunkEncoding || encoding || 'utf8') : chunk;
|
|
1217
|
-
if (typeof output !== 'undefined') {
|
|
1218
|
-
output = Buffer.concat([
|
|
1219
|
-
output,
|
|
1220
|
-
chunkEncoded
|
|
1221
|
-
]);
|
|
1222
|
-
} else {
|
|
1223
|
-
output = chunkEncoded;
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
encoding = chunkEncoding;
|
|
1227
|
-
if (callback) {
|
|
1228
|
-
callback();
|
|
1229
|
-
}
|
|
1230
|
-
};
|
|
1231
|
-
const writable = new Writable({
|
|
1232
|
-
decodeStrings: false,
|
|
1233
|
-
write (chunk, arg2, arg3) {
|
|
1234
|
-
const chunkEncoding = typeof arg2 === 'string' ? encoding : 'utf-8';
|
|
1235
|
-
let cb;
|
|
1236
|
-
if (typeof arg2 === 'function') {
|
|
1237
|
-
cb = arg2;
|
|
1238
|
-
} else if (typeof arg3 === 'function') {
|
|
1239
|
-
cb = arg3;
|
|
1240
|
-
}
|
|
1241
|
-
write(chunk, chunkEncoding, cb);
|
|
1242
|
-
return true;
|
|
1243
|
-
}
|
|
1244
|
-
});
|
|
1245
|
-
Object.defineProperty(writable, 'body', {
|
|
1246
|
-
get () {
|
|
1247
|
-
if (output) {
|
|
1248
|
-
const arrayBuffer = new ArrayBuffer(output.length);
|
|
1249
|
-
const view = new Uint8Array(arrayBuffer);
|
|
1250
|
-
for(let i = 0; i < output.length; ++i){
|
|
1251
|
-
view[i] = output[i];
|
|
1252
|
-
}
|
|
1253
|
-
return arrayBuffer;
|
|
1254
|
-
}
|
|
1255
|
-
return new ArrayBuffer(0);
|
|
1256
|
-
}
|
|
1257
|
-
});
|
|
1258
|
-
const headers = {};
|
|
1259
|
-
Object.assign(writable, {
|
|
1260
|
-
req: request,
|
|
1261
|
-
chunkedEncoding: false,
|
|
1262
|
-
connection: null,
|
|
1263
|
-
headersSent: false,
|
|
1264
|
-
sendDate: false,
|
|
1265
|
-
shouldKeepAlive: false,
|
|
1266
|
-
socket: null,
|
|
1267
|
-
statusCode: 200,
|
|
1268
|
-
statusMessage: '',
|
|
1269
|
-
strictContentLength: false,
|
|
1270
|
-
useChunkedEncodingByDefault: false,
|
|
1271
|
-
finished: false,
|
|
1272
|
-
addTrailers (_headers) {},
|
|
1273
|
-
appendHeader (name, value) {
|
|
1274
|
-
if (name === HeaderName.SET_COOKIE) {
|
|
1275
|
-
value = splitCookiesString(value);
|
|
1276
|
-
}
|
|
1277
|
-
name = name.toLowerCase();
|
|
1278
|
-
const current = headers[name];
|
|
1279
|
-
const all = [
|
|
1280
|
-
...Array.isArray(current) ? current : [
|
|
1281
|
-
current
|
|
1282
|
-
],
|
|
1283
|
-
...Array.isArray(value) ? value : [
|
|
1284
|
-
value
|
|
1285
|
-
]
|
|
1286
|
-
].filter(Boolean);
|
|
1287
|
-
headers[name] = all.length > 1 ? all : all[0];
|
|
1288
|
-
return this;
|
|
1289
|
-
},
|
|
1290
|
-
assignSocket (_socket) {},
|
|
1291
|
-
detachSocket (_socket) {},
|
|
1292
|
-
flushHeaders () {},
|
|
1293
|
-
getHeader (name) {
|
|
1294
|
-
return headers[name.toLowerCase()];
|
|
1295
|
-
},
|
|
1296
|
-
getHeaderNames () {
|
|
1297
|
-
return Object.keys(headers);
|
|
1298
|
-
},
|
|
1299
|
-
getHeaders () {
|
|
1300
|
-
return headers;
|
|
1301
|
-
},
|
|
1302
|
-
hasHeader (name) {
|
|
1303
|
-
return hasOwnProperty(headers, name.toLowerCase());
|
|
1304
|
-
},
|
|
1305
|
-
removeHeader (name) {
|
|
1306
|
-
delete headers[name.toLowerCase()];
|
|
1307
|
-
},
|
|
1308
|
-
setHeader (name, value) {
|
|
1309
|
-
if (name === HeaderName.SET_COOKIE && typeof value !== 'number') {
|
|
1310
|
-
value = splitCookiesString(value);
|
|
1311
|
-
}
|
|
1312
|
-
headers[name.toLowerCase()] = value;
|
|
1313
|
-
return this;
|
|
1314
|
-
},
|
|
1315
|
-
setHeaders (headers) {
|
|
1316
|
-
if (headers instanceof Map) {
|
|
1317
|
-
headers.entries().forEach(([key, value])=>{
|
|
1318
|
-
this.setHeader(key, value);
|
|
1319
|
-
});
|
|
1320
|
-
return this;
|
|
1321
|
-
}
|
|
1322
|
-
headers.forEach((value, key)=>{
|
|
1323
|
-
this.setHeader(key, value);
|
|
1324
|
-
});
|
|
1325
|
-
return this;
|
|
1326
|
-
},
|
|
1327
|
-
setTimeout (_msecs, _callback) {
|
|
1328
|
-
return this;
|
|
1329
|
-
},
|
|
1330
|
-
writeContinue (_callback) {},
|
|
1331
|
-
writeEarlyHints (_hints, callback) {
|
|
1332
|
-
if (typeof callback !== 'undefined') {
|
|
1333
|
-
callback();
|
|
1334
|
-
}
|
|
1335
|
-
},
|
|
1336
|
-
writeProcessing () {},
|
|
1337
|
-
writeHead (statusCode, arg1, arg2) {
|
|
1338
|
-
this.statusCode = statusCode;
|
|
1339
|
-
if (typeof arg1 === 'string') {
|
|
1340
|
-
this.statusMessage = arg1;
|
|
1341
|
-
arg1 = undefined;
|
|
1342
|
-
}
|
|
1343
|
-
const headers = arg2 || arg1;
|
|
1344
|
-
if (headers) {
|
|
1345
|
-
if (Array.isArray(headers)) {
|
|
1346
|
-
for(let i = 0; i < headers.length; i++){
|
|
1347
|
-
const keys = Object.keys(headers[i]);
|
|
1348
|
-
for(let j = 0; j < keys.length; j++){
|
|
1349
|
-
this.setHeader(keys[i], headers[i][keys[j]]);
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
} else {
|
|
1353
|
-
const keys = Object.keys(headers);
|
|
1354
|
-
for(let i = 0; i < keys.length; i++){
|
|
1355
|
-
this.setHeader(keys[i], headers[keys[i]]);
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1360
|
-
// @ts-ignore
|
|
1361
|
-
this.headersSent = true;
|
|
1362
|
-
return this;
|
|
1363
|
-
}
|
|
1364
|
-
});
|
|
1365
|
-
return writable;
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
function dispatch(event, target) {
|
|
1369
|
-
setRequestParams(event.request, event.params);
|
|
1370
|
-
setRequestMountPath(event.request, event.mountPath);
|
|
1371
|
-
setRequestRouterPath(event.request, event.routerPath);
|
|
1372
|
-
return new Promise((resolve, reject)=>{
|
|
1373
|
-
let handled = false;
|
|
1374
|
-
const unsubscribe = ()=>{
|
|
1375
|
-
event.response.off('close', done);
|
|
1376
|
-
event.response.off('error', done);
|
|
1377
|
-
};
|
|
1378
|
-
const shutdown = (dispatched, err)=>{
|
|
1379
|
-
if (handled) {
|
|
1380
|
-
return;
|
|
1381
|
-
}
|
|
1382
|
-
handled = true;
|
|
1383
|
-
unsubscribe();
|
|
1384
|
-
if (err) {
|
|
1385
|
-
reject(createError(err));
|
|
1386
|
-
} else {
|
|
1387
|
-
resolve(dispatched);
|
|
1388
|
-
}
|
|
1389
|
-
};
|
|
1390
|
-
const done = (err)=>shutdown(true, err);
|
|
1391
|
-
const next = (err)=>shutdown(false, err);
|
|
1392
|
-
event.response.once('close', done);
|
|
1393
|
-
event.response.once('error', done);
|
|
1394
|
-
const handle = async (data)=>{
|
|
1395
|
-
if (typeof data === 'undefined' || handled) {
|
|
1396
|
-
return false;
|
|
1397
|
-
}
|
|
1398
|
-
handled = true;
|
|
1399
|
-
unsubscribe();
|
|
1400
|
-
if (!event.dispatched) {
|
|
1401
|
-
await send(event.response, data);
|
|
1402
|
-
}
|
|
1403
|
-
return true;
|
|
1404
|
-
};
|
|
1405
|
-
try {
|
|
1406
|
-
const output = target(next);
|
|
1407
|
-
if (isPromise(output)) {
|
|
1408
|
-
output.then((r)=>handle(r)).then((resolved)=>{
|
|
1409
|
-
if (resolved) {
|
|
1410
|
-
resolve(true);
|
|
1411
|
-
}
|
|
1412
|
-
}).catch((e)=>reject(createError(e)));
|
|
1413
|
-
return;
|
|
1414
|
-
}
|
|
1415
|
-
Promise.resolve().then(()=>handle(output)).then((resolved)=>{
|
|
1416
|
-
if (resolved) {
|
|
1417
|
-
resolve(true);
|
|
1418
|
-
}
|
|
1419
|
-
}).catch((e)=>reject(createError(e)));
|
|
1420
|
-
} catch (error) {
|
|
1421
|
-
next(error);
|
|
1422
|
-
}
|
|
1423
|
-
});
|
|
1424
|
-
}
|
|
1425
|
-
|
|
1426
|
-
function isDispatcherErrorEvent(event) {
|
|
1427
|
-
return typeof event.error !== 'undefined';
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
class DispatchEvent {
|
|
1431
|
-
get dispatched() {
|
|
1432
|
-
return this._dispatched || this.response.writableEnded || this.response.headersSent;
|
|
1433
|
-
}
|
|
1434
|
-
set dispatched(value) {
|
|
1435
|
-
this._dispatched = value;
|
|
1436
|
-
}
|
|
1437
|
-
constructor(context){
|
|
1438
|
-
this.request = context.request;
|
|
1439
|
-
this.response = context.response;
|
|
1440
|
-
this.method = context.method || MethodName.GET;
|
|
1441
|
-
this.methodsAllowed = [];
|
|
1442
|
-
this.mountPath = '/';
|
|
1443
|
-
this.params = {};
|
|
1444
|
-
this.path = context.path || '/';
|
|
1445
|
-
this.routerPath = [];
|
|
1446
|
-
this.next = nextPlaceholder;
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
|
|
1450
|
-
class DispatchErrorEvent extends DispatchEvent {
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
async function dispatchNodeRequest(router, request, response) {
|
|
1454
|
-
const event = new DispatchEvent({
|
|
1455
|
-
request,
|
|
1456
|
-
response,
|
|
1457
|
-
path: useRequestPath(request),
|
|
1458
|
-
method: toMethodName(request.method, MethodName.GET)
|
|
1459
|
-
});
|
|
1460
|
-
await router.dispatch(event);
|
|
1461
|
-
if (event.dispatched) {
|
|
1462
|
-
return;
|
|
1463
|
-
}
|
|
1464
|
-
if (event.error) {
|
|
1465
|
-
event.response.statusCode = event.error.statusCode;
|
|
1466
|
-
if (event.error.statusMessage) {
|
|
1467
|
-
event.response.statusMessage = event.error.statusMessage;
|
|
1468
|
-
}
|
|
1469
|
-
event.response.end();
|
|
1470
|
-
return;
|
|
1471
|
-
}
|
|
1472
|
-
event.response.statusCode = 404;
|
|
1473
|
-
event.response.end();
|
|
1474
|
-
}
|
|
1475
|
-
function createNodeDispatcher(router) {
|
|
1476
|
-
return (req, res)=>{
|
|
1477
|
-
// eslint-disable-next-line no-void
|
|
1478
|
-
void dispatchNodeRequest(router, req, res);
|
|
1479
|
-
};
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
function transformHeaderToTuples(key, value) {
|
|
1483
|
-
const output = [];
|
|
1484
|
-
if (Array.isArray(value)) {
|
|
1485
|
-
for(let j = 0; j < value.length; j++){
|
|
1486
|
-
output.push([
|
|
1487
|
-
key,
|
|
1488
|
-
value[j]
|
|
1489
|
-
]);
|
|
1490
|
-
}
|
|
1491
|
-
} else if (value !== undefined) {
|
|
1492
|
-
output.push([
|
|
1493
|
-
key,
|
|
1494
|
-
String(value)
|
|
1495
|
-
]);
|
|
1496
|
-
}
|
|
1497
|
-
return output;
|
|
1498
|
-
}
|
|
1499
|
-
function transformHeadersToTuples(input) {
|
|
1500
|
-
const output = [];
|
|
1501
|
-
const keys = Object.keys(input);
|
|
1502
|
-
for(let i = 0; i < keys.length; i++){
|
|
1503
|
-
const key = keys[i].toLowerCase();
|
|
1504
|
-
output.push(...transformHeaderToTuples(key, input[key]));
|
|
1505
|
-
}
|
|
1506
|
-
return output;
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
async function dispatchRawRequest(router, request) {
|
|
1510
|
-
const method = toMethodName(request.method, MethodName.GET);
|
|
1511
|
-
const req = createRequest({
|
|
1512
|
-
url: request.path,
|
|
1513
|
-
method,
|
|
1514
|
-
body: request.body,
|
|
1515
|
-
headers: request.headers
|
|
1516
|
-
});
|
|
1517
|
-
const res = createResponse(req);
|
|
1518
|
-
const getHeaders = ()=>{
|
|
1519
|
-
const output = {};
|
|
1520
|
-
const headers = res.getHeaders();
|
|
1521
|
-
const keys = Object.keys(headers);
|
|
1522
|
-
for(let i = 0; i < keys.length; i++){
|
|
1523
|
-
const header = headers[keys[i]];
|
|
1524
|
-
if (typeof header === 'number') {
|
|
1525
|
-
output[keys[i]] = `${header}`;
|
|
1526
|
-
} else if (header) {
|
|
1527
|
-
output[keys[i]] = header;
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
return output;
|
|
1531
|
-
};
|
|
1532
|
-
const createRawResponse = (input = {})=>({
|
|
1533
|
-
status: input.status || res.statusCode,
|
|
1534
|
-
statusMessage: input.statusMessage || res.statusMessage,
|
|
1535
|
-
headers: getHeaders(),
|
|
1536
|
-
body: res.body
|
|
1537
|
-
});
|
|
1538
|
-
const event = new DispatchEvent({
|
|
1539
|
-
request: req,
|
|
1540
|
-
response: res,
|
|
1541
|
-
path: request.path,
|
|
1542
|
-
method
|
|
1543
|
-
});
|
|
1544
|
-
await router.dispatch(event);
|
|
1545
|
-
if (event.dispatched) {
|
|
1546
|
-
return createRawResponse();
|
|
1547
|
-
}
|
|
1548
|
-
if (event.error) {
|
|
1549
|
-
return createRawResponse({
|
|
1550
|
-
status: event.error.statusCode,
|
|
1551
|
-
statusMessage: event.error.statusMessage
|
|
1552
|
-
});
|
|
1553
|
-
}
|
|
1554
|
-
return createRawResponse({
|
|
1555
|
-
status: 404
|
|
1556
|
-
});
|
|
1557
|
-
}
|
|
1558
|
-
function createRawDispatcher(router) {
|
|
1559
|
-
return async (request)=>dispatchRawRequest(router, request);
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
async function dispatchWebRequest(router, request) {
|
|
1563
|
-
const url = new URL(request.url);
|
|
1564
|
-
const headers = {};
|
|
1565
|
-
request.headers.forEach((value, key)=>{
|
|
1566
|
-
headers[key] = value;
|
|
1567
|
-
});
|
|
1568
|
-
const method = toMethodName(request.method, MethodName.GET);
|
|
1569
|
-
const res = await dispatchRawRequest(router, {
|
|
1570
|
-
method,
|
|
1571
|
-
path: url.pathname + url.search,
|
|
1572
|
-
headers,
|
|
1573
|
-
body: request.body
|
|
1574
|
-
});
|
|
1575
|
-
let body;
|
|
1576
|
-
if (method === MethodName.HEAD || res.status === 304 || res.status === 101 || res.status === 204 || res.status === 205) {
|
|
1577
|
-
body = null;
|
|
1578
|
-
} else {
|
|
1579
|
-
body = res.body;
|
|
1580
|
-
}
|
|
1581
|
-
return new Response(body, {
|
|
1582
|
-
headers: transformHeadersToTuples(res.headers),
|
|
1583
|
-
status: res.status,
|
|
1584
|
-
statusText: res.statusMessage
|
|
1585
|
-
});
|
|
1586
|
-
}
|
|
1587
|
-
function createWebDispatcher(router) {
|
|
1588
|
-
return async (request)=>dispatchWebRequest(router, request);
|
|
1589
|
-
}
|
|
1590
|
-
|
|
1591
|
-
var HandlerType = /*#__PURE__*/ function(HandlerType) {
|
|
1592
|
-
HandlerType["CORE"] = "core";
|
|
1593
|
-
HandlerType["ERROR"] = "error";
|
|
1594
|
-
return HandlerType;
|
|
1595
|
-
}({});
|
|
1596
|
-
const HandlerSymbol = Symbol.for('Handler');
|
|
1597
|
-
|
|
1598
|
-
var HookName = /*#__PURE__*/ function(HookName) {
|
|
1599
|
-
HookName["ERROR"] = "error";
|
|
1600
|
-
HookName["DISPATCH_START"] = "dispatchStart";
|
|
1601
|
-
HookName["DISPATCH_END"] = "dispatchEnd";
|
|
1602
|
-
HookName["CHILD_MATCH"] = "childMatch";
|
|
1603
|
-
HookName["CHILD_DISPATCH_BEFORE"] = "childDispatchBefore";
|
|
1604
|
-
HookName["CHILD_DISPATCH_AFTER"] = "childDispatchAfter";
|
|
1605
|
-
return HookName;
|
|
1606
|
-
}({});
|
|
1607
|
-
|
|
1608
|
-
class HookManager {
|
|
1609
|
-
// --------------------------------------------------
|
|
1610
|
-
addListener(name, fn) {
|
|
1611
|
-
this.items[name] = this.items[name] || [];
|
|
1612
|
-
this.items[name].push(fn);
|
|
1613
|
-
return ()=>{
|
|
1614
|
-
this.removeListener(name, fn);
|
|
1615
|
-
};
|
|
1616
|
-
}
|
|
1617
|
-
removeListener(name, fn) {
|
|
1618
|
-
if (!this.items[name]) {
|
|
1619
|
-
return;
|
|
1620
|
-
}
|
|
1621
|
-
if (typeof fn === 'undefined') {
|
|
1622
|
-
delete this.items[name];
|
|
1623
|
-
return;
|
|
1624
|
-
}
|
|
1625
|
-
if (typeof fn === 'function') {
|
|
1626
|
-
const index = this.items[name].indexOf(fn);
|
|
1627
|
-
if (index !== -1) {
|
|
1628
|
-
this.items[name].splice(index, 1);
|
|
1629
|
-
}
|
|
1630
|
-
}
|
|
1631
|
-
if (this.items[name].length === 0) {
|
|
1632
|
-
delete this.items[name];
|
|
1633
|
-
}
|
|
1634
|
-
}
|
|
1635
|
-
// --------------------------------------------------
|
|
1636
|
-
/**
|
|
1637
|
-
* @throws RoutupError
|
|
1638
|
-
*
|
|
1639
|
-
* @param name
|
|
1640
|
-
* @param event
|
|
1641
|
-
*/ async trigger(name, event) {
|
|
1642
|
-
if (!this.items[name] || this.items[name].length === 0) {
|
|
1643
|
-
return;
|
|
1644
|
-
}
|
|
1645
|
-
try {
|
|
1646
|
-
for(let i = 0; i < this.items[name].length; i++){
|
|
1647
|
-
const hook = this.items[name][i];
|
|
1648
|
-
event.dispatched = await dispatch(event, (next)=>Promise.resolve().then(()=>{
|
|
1649
|
-
event.next = next;
|
|
1650
|
-
return this.triggerListener(name, event, hook);
|
|
1651
|
-
}).catch((err)=>next(err)));
|
|
1652
|
-
event.next = nextPlaceholder;
|
|
1653
|
-
if (event.dispatched) {
|
|
1654
|
-
if (event.error) {
|
|
1655
|
-
event.error = undefined;
|
|
1656
|
-
}
|
|
1657
|
-
return;
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
} catch (e) {
|
|
1661
|
-
event.error = e;
|
|
1662
|
-
if (!this.isErrorListenerHook(name)) {
|
|
1663
|
-
await this.trigger(HookName.ERROR, event);
|
|
1664
|
-
if (event.dispatched) {
|
|
1665
|
-
if (event.error) {
|
|
1666
|
-
event.error = undefined;
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1672
|
-
triggerListener(name, event, listener) {
|
|
1673
|
-
if (this.isErrorListenerHook(name)) {
|
|
1674
|
-
if (isDispatcherErrorEvent(event)) {
|
|
1675
|
-
return listener(event);
|
|
1676
|
-
}
|
|
1677
|
-
return undefined;
|
|
1678
|
-
}
|
|
1679
|
-
return listener(event);
|
|
1680
|
-
}
|
|
1681
|
-
isErrorListenerHook(input) {
|
|
1682
|
-
return input === HookName.ERROR;
|
|
1683
|
-
}
|
|
1684
|
-
// --------------------------------------------------
|
|
1685
|
-
constructor(){
|
|
1686
|
-
this.items = {};
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
|
|
1690
|
-
function decodeParam(val) {
|
|
1691
|
-
/* istanbul ignore next */ if (typeof val !== 'string' || val.length === 0) {
|
|
1692
|
-
return val;
|
|
1693
|
-
}
|
|
1694
|
-
return decodeURIComponent(val);
|
|
1695
|
-
}
|
|
1696
|
-
class PathMatcher {
|
|
1697
|
-
test(path) {
|
|
1698
|
-
return this.regexp.test(path);
|
|
1699
|
-
}
|
|
1700
|
-
exec(path) {
|
|
1701
|
-
if (this.path === '/' && this.regexpOptions.end === false) {
|
|
1702
|
-
return {
|
|
1703
|
-
path: '/',
|
|
1704
|
-
params: {}
|
|
1705
|
-
};
|
|
1706
|
-
}
|
|
1707
|
-
if (this.path === '*') {
|
|
1708
|
-
return {
|
|
1709
|
-
path,
|
|
1710
|
-
params: {
|
|
1711
|
-
0: decodeParam(path)
|
|
1712
|
-
}
|
|
1713
|
-
};
|
|
1714
|
-
}
|
|
1715
|
-
const match = this.regexp.exec(path);
|
|
1716
|
-
if (!match) {
|
|
1717
|
-
return undefined;
|
|
1718
|
-
}
|
|
1719
|
-
const params = {};
|
|
1720
|
-
for(let i = 1; i < match.length; i++){
|
|
1721
|
-
const key = this.regexpKeys[i - 1];
|
|
1722
|
-
const prop = key.name;
|
|
1723
|
-
const val = decodeParam(match[i]);
|
|
1724
|
-
if (typeof val !== 'undefined') {
|
|
1725
|
-
params[prop] = val;
|
|
1726
|
-
}
|
|
1727
|
-
}
|
|
1728
|
-
return {
|
|
1729
|
-
path: match[0],
|
|
1730
|
-
params
|
|
1731
|
-
};
|
|
1732
|
-
}
|
|
1733
|
-
constructor(path, options){
|
|
1734
|
-
this.regexpKeys = [];
|
|
1735
|
-
this.path = path;
|
|
1736
|
-
this.regexpOptions = options || {};
|
|
1737
|
-
const regexp = pathToRegexp(path, options);
|
|
1738
|
-
this.regexp = regexp.regexp;
|
|
1739
|
-
this.regexpKeys = regexp.keys;
|
|
1740
|
-
}
|
|
1741
|
-
}
|
|
1742
|
-
|
|
1743
|
-
function isPath(input) {
|
|
1744
|
-
return typeof input === 'string';
|
|
1745
|
-
}
|
|
1746
|
-
|
|
1747
|
-
class Handler {
|
|
1748
|
-
// --------------------------------------------------
|
|
1749
|
-
get type() {
|
|
1750
|
-
return this.config.type;
|
|
1751
|
-
}
|
|
1752
|
-
get path() {
|
|
1753
|
-
return this.config.path;
|
|
1754
|
-
}
|
|
1755
|
-
get method() {
|
|
1756
|
-
if (this._method || !this.config.method) {
|
|
1757
|
-
return this._method;
|
|
1758
|
-
}
|
|
1759
|
-
this._method = toMethodName(this.config.method);
|
|
1760
|
-
return this._method;
|
|
1761
|
-
}
|
|
1762
|
-
// --------------------------------------------------
|
|
1763
|
-
async dispatch(event) {
|
|
1764
|
-
if (this.pathMatcher) {
|
|
1765
|
-
const pathMatch = this.pathMatcher.exec(event.path);
|
|
1766
|
-
if (pathMatch) {
|
|
1767
|
-
event.params = {
|
|
1768
|
-
...event.params,
|
|
1769
|
-
...pathMatch.params
|
|
1770
|
-
};
|
|
1771
|
-
}
|
|
1772
|
-
}
|
|
1773
|
-
await this.hookManager.trigger(HookName.CHILD_DISPATCH_BEFORE, event);
|
|
1774
|
-
if (event.dispatched) {
|
|
1775
|
-
return Promise.resolve();
|
|
1776
|
-
}
|
|
1777
|
-
try {
|
|
1778
|
-
event.dispatched = await dispatch(event, (done)=>{
|
|
1779
|
-
if (this.config.type === HandlerType.ERROR) {
|
|
1780
|
-
if (event.error) {
|
|
1781
|
-
return this.config.fn(event.error, event.request, event.response, done);
|
|
1782
|
-
}
|
|
1783
|
-
} else {
|
|
1784
|
-
return this.config.fn(event.request, event.response, done);
|
|
1785
|
-
}
|
|
1786
|
-
return undefined;
|
|
1787
|
-
});
|
|
1788
|
-
} catch (e) {
|
|
1789
|
-
if (isError(e)) {
|
|
1790
|
-
event.error = e;
|
|
1791
|
-
await this.hookManager.trigger(HookName.ERROR, event);
|
|
1792
|
-
if (event.dispatched) {
|
|
1793
|
-
event.error = undefined;
|
|
1794
|
-
} else {
|
|
1795
|
-
throw e;
|
|
1796
|
-
}
|
|
1797
|
-
}
|
|
1798
|
-
}
|
|
1799
|
-
return this.hookManager.trigger(HookName.CHILD_DISPATCH_AFTER, event);
|
|
1800
|
-
}
|
|
1801
|
-
// --------------------------------------------------
|
|
1802
|
-
matchPath(path) {
|
|
1803
|
-
if (!this.pathMatcher) {
|
|
1804
|
-
return true;
|
|
1805
|
-
}
|
|
1806
|
-
return this.pathMatcher.test(path);
|
|
1807
|
-
}
|
|
1808
|
-
setPath(path) {
|
|
1809
|
-
if (typeof path === 'string') {
|
|
1810
|
-
path = withLeadingSlash(path);
|
|
1811
|
-
}
|
|
1812
|
-
this.config.path = path;
|
|
1813
|
-
if (typeof path === 'undefined') {
|
|
1814
|
-
this.pathMatcher = undefined;
|
|
1815
|
-
return;
|
|
1816
|
-
}
|
|
1817
|
-
this.pathMatcher = new PathMatcher(path, {
|
|
1818
|
-
end: !!this.config.method
|
|
1819
|
-
});
|
|
1820
|
-
}
|
|
1821
|
-
// --------------------------------------------------
|
|
1822
|
-
matchMethod(method) {
|
|
1823
|
-
return !this.method || method === this.method || method === MethodName.HEAD && this.method === MethodName.GET;
|
|
1824
|
-
}
|
|
1825
|
-
setMethod(input) {
|
|
1826
|
-
const method = toMethodName(input);
|
|
1827
|
-
this.config.method = method;
|
|
1828
|
-
this._method = method;
|
|
1829
|
-
}
|
|
1830
|
-
// --------------------------------------------------
|
|
1831
|
-
mountHooks() {
|
|
1832
|
-
if (this.config.onBefore) {
|
|
1833
|
-
this.hookManager.addListener(HookName.CHILD_DISPATCH_BEFORE, this.config.onBefore);
|
|
1834
|
-
}
|
|
1835
|
-
if (this.config.onAfter) {
|
|
1836
|
-
this.hookManager.addListener(HookName.CHILD_DISPATCH_AFTER, this.config.onAfter);
|
|
1837
|
-
}
|
|
1838
|
-
if (this.config.onError) {
|
|
1839
|
-
this.hookManager.addListener(HookName.ERROR, this.config.onError);
|
|
1840
|
-
}
|
|
1841
|
-
}
|
|
1842
|
-
// --------------------------------------------------
|
|
1843
|
-
constructor(handler){
|
|
1844
|
-
this['@instanceof'] = HandlerSymbol;
|
|
1845
|
-
this.config = handler;
|
|
1846
|
-
this.hookManager = new HookManager();
|
|
1847
|
-
this.mountHooks();
|
|
1848
|
-
this.setPath(handler.path);
|
|
1849
|
-
}
|
|
1850
|
-
}
|
|
1851
|
-
|
|
1852
|
-
function coreHandler(input) {
|
|
1853
|
-
if (typeof input === 'function') {
|
|
1854
|
-
return new Handler({
|
|
1855
|
-
type: HandlerType.CORE,
|
|
1856
|
-
fn: input
|
|
1857
|
-
});
|
|
1858
|
-
}
|
|
1859
|
-
return new Handler({
|
|
1860
|
-
type: HandlerType.CORE,
|
|
1861
|
-
...input
|
|
1862
|
-
});
|
|
1863
|
-
}
|
|
1864
|
-
|
|
1865
|
-
function errorHandler(input) {
|
|
1866
|
-
if (typeof input === 'function') {
|
|
1867
|
-
return new Handler({
|
|
1868
|
-
type: HandlerType.ERROR,
|
|
1869
|
-
fn: input
|
|
1870
|
-
});
|
|
1871
|
-
}
|
|
1872
|
-
return new Handler({
|
|
1873
|
-
type: HandlerType.ERROR,
|
|
1874
|
-
...input
|
|
1875
|
-
});
|
|
1876
|
-
}
|
|
1877
|
-
|
|
1878
|
-
function isHandlerConfig(input) {
|
|
1879
|
-
return isObject(input) && typeof input.fn === 'function' && typeof input.type === 'string';
|
|
1880
|
-
}
|
|
1881
|
-
function isHandler(input) {
|
|
1882
|
-
return isInstance(input, HandlerSymbol);
|
|
1883
|
-
}
|
|
1884
|
-
|
|
1885
|
-
function isPlugin(input) {
|
|
1886
|
-
if (!isObject(input)) {
|
|
1887
|
-
return false;
|
|
1888
|
-
}
|
|
1889
|
-
if (typeof input.name !== 'undefined' && typeof input.name !== 'string') {
|
|
1890
|
-
return false;
|
|
1891
|
-
}
|
|
1892
|
-
return typeof input.install === 'function' && input.install.length === 1;
|
|
1893
|
-
}
|
|
1894
|
-
|
|
1895
|
-
function transformRouterOptions(input) {
|
|
1896
|
-
if (typeof input.etag !== 'undefined') {
|
|
1897
|
-
input.etag = buildEtagFn(input.etag);
|
|
1898
|
-
}
|
|
1899
|
-
if (typeof input.trustProxy !== 'undefined') {
|
|
1900
|
-
input.trustProxy = buildTrustProxyFn(input.trustProxy);
|
|
1901
|
-
}
|
|
1902
|
-
return input;
|
|
1903
|
-
}
|
|
1904
|
-
|
|
1905
|
-
const RouterSymbol = Symbol.for('Router');
|
|
1906
|
-
var RouterPipelineStep = /*#__PURE__*/ function(RouterPipelineStep) {
|
|
1907
|
-
RouterPipelineStep[RouterPipelineStep["START"] = 0] = "START";
|
|
1908
|
-
RouterPipelineStep[RouterPipelineStep["LOOKUP"] = 1] = "LOOKUP";
|
|
1909
|
-
RouterPipelineStep[RouterPipelineStep["CHILD_BEFORE"] = 2] = "CHILD_BEFORE";
|
|
1910
|
-
RouterPipelineStep[RouterPipelineStep["CHILD_DISPATCH"] = 3] = "CHILD_DISPATCH";
|
|
1911
|
-
RouterPipelineStep[RouterPipelineStep["CHILD_AFTER"] = 4] = "CHILD_AFTER";
|
|
1912
|
-
RouterPipelineStep[RouterPipelineStep["FINISH"] = 5] = "FINISH";
|
|
1913
|
-
return RouterPipelineStep;
|
|
1914
|
-
}({});
|
|
1915
|
-
|
|
1916
|
-
let nextId = 0;
|
|
1917
|
-
function generateRouterID() {
|
|
1918
|
-
return ++nextId;
|
|
1919
|
-
}
|
|
1920
|
-
function isRouterInstance(input) {
|
|
1921
|
-
return isInstance(input, RouterSymbol);
|
|
1922
|
-
}
|
|
1923
|
-
|
|
1924
|
-
class Router {
|
|
1925
|
-
// --------------------------------------------------
|
|
1926
|
-
matchPath(path) {
|
|
1927
|
-
if (this.pathMatcher) {
|
|
1928
|
-
return this.pathMatcher.test(path);
|
|
1929
|
-
}
|
|
1930
|
-
return true;
|
|
1931
|
-
}
|
|
1932
|
-
setPath(value) {
|
|
1933
|
-
if (value === '/' || typeof value === 'undefined') {
|
|
1934
|
-
this.pathMatcher = undefined;
|
|
1935
|
-
return;
|
|
1936
|
-
}
|
|
1937
|
-
this.pathMatcher = new PathMatcher(withLeadingSlash(withoutTrailingSlash(`${value}`)), {
|
|
1938
|
-
end: false
|
|
1939
|
-
});
|
|
1940
|
-
}
|
|
1941
|
-
// --------------------------------------------------
|
|
1942
|
-
async executePipelineStep(context) {
|
|
1943
|
-
switch(context.step){
|
|
1944
|
-
case RouterPipelineStep.START:
|
|
1945
|
-
{
|
|
1946
|
-
return this.executePipelineStepStart(context);
|
|
1947
|
-
}
|
|
1948
|
-
case RouterPipelineStep.LOOKUP:
|
|
1949
|
-
{
|
|
1950
|
-
return this.executePipelineStepLookup(context);
|
|
1951
|
-
}
|
|
1952
|
-
case RouterPipelineStep.CHILD_BEFORE:
|
|
1953
|
-
{
|
|
1954
|
-
return this.executePipelineStepChildBefore(context);
|
|
1955
|
-
}
|
|
1956
|
-
case RouterPipelineStep.CHILD_DISPATCH:
|
|
1957
|
-
{
|
|
1958
|
-
return this.executePipelineStepChildDispatch(context);
|
|
1959
|
-
}
|
|
1960
|
-
case RouterPipelineStep.CHILD_AFTER:
|
|
1961
|
-
{
|
|
1962
|
-
return this.executePipelineStepChildAfter(context);
|
|
1963
|
-
}
|
|
1964
|
-
case RouterPipelineStep.FINISH:
|
|
1965
|
-
default:
|
|
1966
|
-
{
|
|
1967
|
-
return this.executePipelineStepFinish(context);
|
|
1968
|
-
}
|
|
1969
|
-
}
|
|
1970
|
-
}
|
|
1971
|
-
async executePipelineStepStart(context) {
|
|
1972
|
-
return this.hookManager.trigger(HookName.DISPATCH_START, context.event).then(()=>{
|
|
1973
|
-
if (context.event.dispatched) {
|
|
1974
|
-
context.step = RouterPipelineStep.FINISH;
|
|
1975
|
-
} else {
|
|
1976
|
-
context.step++;
|
|
1977
|
-
}
|
|
1978
|
-
return this.executePipelineStep(context);
|
|
1979
|
-
});
|
|
1980
|
-
}
|
|
1981
|
-
async executePipelineStepLookup(context) {
|
|
1982
|
-
if (context.event.dispatched || context.stackIndex >= this.stack.length) {
|
|
1983
|
-
context.step = RouterPipelineStep.FINISH;
|
|
1984
|
-
return this.executePipelineStep(context);
|
|
1985
|
-
}
|
|
1986
|
-
let match;
|
|
1987
|
-
const item = this.stack[context.stackIndex];
|
|
1988
|
-
if (isHandler(item)) {
|
|
1989
|
-
if (context.event.error && item.type === HandlerType.CORE || !context.event.error && item.type === HandlerType.ERROR) {
|
|
1990
|
-
context.stackIndex++;
|
|
1991
|
-
return this.executePipelineStepLookup(context);
|
|
1992
|
-
}
|
|
1993
|
-
match = item.matchPath(context.event.path);
|
|
1994
|
-
if (match) {
|
|
1995
|
-
if (item.method) {
|
|
1996
|
-
context.event.methodsAllowed.push(item.method);
|
|
1997
|
-
}
|
|
1998
|
-
if (item.matchMethod(context.event.method)) {
|
|
1999
|
-
await this.hookManager.trigger(HookName.CHILD_MATCH, context.event);
|
|
2000
|
-
if (context.event.dispatched) {
|
|
2001
|
-
context.step = RouterPipelineStep.FINISH;
|
|
2002
|
-
} else {
|
|
2003
|
-
context.step++;
|
|
2004
|
-
}
|
|
2005
|
-
return this.executePipelineStep(context);
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
context.stackIndex++;
|
|
2009
|
-
return this.executePipelineStepLookup(context);
|
|
2010
|
-
}
|
|
2011
|
-
match = item.matchPath(context.event.path);
|
|
2012
|
-
if (match) {
|
|
2013
|
-
await this.hookManager.trigger(HookName.CHILD_MATCH, context.event);
|
|
2014
|
-
if (context.event.dispatched) {
|
|
2015
|
-
context.step = RouterPipelineStep.FINISH;
|
|
2016
|
-
} else {
|
|
2017
|
-
context.step++;
|
|
2018
|
-
}
|
|
2019
|
-
return this.executePipelineStep(context);
|
|
2020
|
-
}
|
|
2021
|
-
context.stackIndex++;
|
|
2022
|
-
return this.executePipelineStepLookup(context);
|
|
2023
|
-
}
|
|
2024
|
-
async executePipelineStepChildBefore(context) {
|
|
2025
|
-
return this.hookManager.trigger(HookName.CHILD_DISPATCH_BEFORE, context.event).then(()=>{
|
|
2026
|
-
if (context.event.dispatched) {
|
|
2027
|
-
context.step = RouterPipelineStep.FINISH;
|
|
2028
|
-
} else {
|
|
2029
|
-
context.step++;
|
|
2030
|
-
}
|
|
2031
|
-
return this.executePipelineStep(context);
|
|
2032
|
-
});
|
|
2033
|
-
}
|
|
2034
|
-
async executePipelineStepChildAfter(context) {
|
|
2035
|
-
return this.hookManager.trigger(HookName.CHILD_DISPATCH_AFTER, context.event).then(()=>{
|
|
2036
|
-
if (context.event.dispatched) {
|
|
2037
|
-
context.step = RouterPipelineStep.FINISH;
|
|
2038
|
-
} else {
|
|
2039
|
-
context.step = RouterPipelineStep.LOOKUP;
|
|
2040
|
-
}
|
|
2041
|
-
return this.executePipelineStep(context);
|
|
2042
|
-
});
|
|
2043
|
-
}
|
|
2044
|
-
async executePipelineStepChildDispatch(context) {
|
|
2045
|
-
if (context.event.dispatched || typeof this.stack[context.stackIndex] === 'undefined') {
|
|
2046
|
-
context.step = RouterPipelineStep.FINISH;
|
|
2047
|
-
return this.executePipelineStep(context);
|
|
2048
|
-
}
|
|
2049
|
-
try {
|
|
2050
|
-
await this.stack[context.stackIndex].dispatch(context.event);
|
|
2051
|
-
} catch (e) {
|
|
2052
|
-
context.event.error = e;
|
|
2053
|
-
await this.hookManager.trigger(HookName.ERROR, context.event);
|
|
2054
|
-
}
|
|
2055
|
-
context.stackIndex++;
|
|
2056
|
-
context.step++;
|
|
2057
|
-
return this.executePipelineStep(context);
|
|
2058
|
-
}
|
|
2059
|
-
async executePipelineStepFinish(context) {
|
|
2060
|
-
if (context.event.error || context.event.dispatched) {
|
|
2061
|
-
return this.hookManager.trigger(HookName.DISPATCH_END, context.event);
|
|
2062
|
-
}
|
|
2063
|
-
if (!context.event.dispatched && context.event.routerPath.length === 1 && context.event.method && context.event.method === MethodName.OPTIONS) {
|
|
2064
|
-
if (context.event.methodsAllowed.indexOf(MethodName.GET) !== -1) {
|
|
2065
|
-
context.event.methodsAllowed.push(MethodName.HEAD);
|
|
2066
|
-
}
|
|
2067
|
-
distinctArray(context.event.methodsAllowed);
|
|
2068
|
-
const options = context.event.methodsAllowed.map((key)=>key.toUpperCase()).join(',');
|
|
2069
|
-
context.event.response.setHeader(HeaderName.ALLOW, options);
|
|
2070
|
-
await send(context.event.response, options);
|
|
2071
|
-
context.event.dispatched = true;
|
|
2072
|
-
}
|
|
2073
|
-
return this.hookManager.trigger(HookName.DISPATCH_END, context.event);
|
|
2074
|
-
}
|
|
2075
|
-
// --------------------------------------------------
|
|
2076
|
-
async dispatch(event) {
|
|
2077
|
-
if (this.pathMatcher) {
|
|
2078
|
-
const output = this.pathMatcher.exec(event.path);
|
|
2079
|
-
if (typeof output !== 'undefined') {
|
|
2080
|
-
event.mountPath = cleanDoubleSlashes(`${event.mountPath}/${output.path}`);
|
|
2081
|
-
if (event.path === output.path) {
|
|
2082
|
-
event.path = '/';
|
|
2083
|
-
} else {
|
|
2084
|
-
event.path = withLeadingSlash(event.path.substring(output.path.length));
|
|
2085
|
-
}
|
|
2086
|
-
event.params = {
|
|
2087
|
-
...event.params,
|
|
2088
|
-
...output.params
|
|
2089
|
-
};
|
|
2090
|
-
}
|
|
2091
|
-
}
|
|
2092
|
-
const context = {
|
|
2093
|
-
step: RouterPipelineStep.START,
|
|
2094
|
-
event,
|
|
2095
|
-
stackIndex: 0
|
|
2096
|
-
};
|
|
2097
|
-
event.routerPath.push(this.id);
|
|
2098
|
-
return this.executePipelineStepStart(context).then(()=>{
|
|
2099
|
-
context.event.routerPath.pop();
|
|
2100
|
-
});
|
|
2101
|
-
}
|
|
2102
|
-
delete(...input) {
|
|
2103
|
-
this.useForMethod(MethodName.DELETE, ...input);
|
|
2104
|
-
return this;
|
|
2105
|
-
}
|
|
2106
|
-
get(...input) {
|
|
2107
|
-
this.useForMethod(MethodName.GET, ...input);
|
|
2108
|
-
return this;
|
|
2109
|
-
}
|
|
2110
|
-
post(...input) {
|
|
2111
|
-
this.useForMethod(MethodName.POST, ...input);
|
|
2112
|
-
return this;
|
|
2113
|
-
}
|
|
2114
|
-
put(...input) {
|
|
2115
|
-
this.useForMethod(MethodName.PUT, ...input);
|
|
2116
|
-
return this;
|
|
2117
|
-
}
|
|
2118
|
-
patch(...input) {
|
|
2119
|
-
this.useForMethod(MethodName.PATCH, ...input);
|
|
2120
|
-
return this;
|
|
2121
|
-
}
|
|
2122
|
-
head(...input) {
|
|
2123
|
-
this.useForMethod(MethodName.HEAD, ...input);
|
|
2124
|
-
return this;
|
|
2125
|
-
}
|
|
2126
|
-
options(...input) {
|
|
2127
|
-
this.useForMethod(MethodName.OPTIONS, ...input);
|
|
2128
|
-
return this;
|
|
2129
|
-
}
|
|
2130
|
-
// --------------------------------------------------
|
|
2131
|
-
useForMethod(method, ...input) {
|
|
2132
|
-
let path;
|
|
2133
|
-
for(let i = 0; i < input.length; i++){
|
|
2134
|
-
const element = input[i];
|
|
2135
|
-
if (isPath(element)) {
|
|
2136
|
-
path = element;
|
|
2137
|
-
continue;
|
|
2138
|
-
}
|
|
2139
|
-
if (isHandlerConfig(element)) {
|
|
2140
|
-
if (path) {
|
|
2141
|
-
element.path = path;
|
|
2142
|
-
}
|
|
2143
|
-
element.method = method;
|
|
2144
|
-
this.use(element);
|
|
2145
|
-
continue;
|
|
2146
|
-
}
|
|
2147
|
-
if (isHandler(element)) {
|
|
2148
|
-
if (path) {
|
|
2149
|
-
element.setPath(path);
|
|
2150
|
-
}
|
|
2151
|
-
element.setMethod(method);
|
|
2152
|
-
this.use(element);
|
|
2153
|
-
}
|
|
2154
|
-
}
|
|
2155
|
-
}
|
|
2156
|
-
use(...input) {
|
|
2157
|
-
let path;
|
|
2158
|
-
for(let i = 0; i < input.length; i++){
|
|
2159
|
-
const item = input[i];
|
|
2160
|
-
if (isPath(item)) {
|
|
2161
|
-
path = withLeadingSlash(item);
|
|
2162
|
-
continue;
|
|
2163
|
-
}
|
|
2164
|
-
if (isRouterInstance(item)) {
|
|
2165
|
-
if (path) {
|
|
2166
|
-
item.setPath(path);
|
|
2167
|
-
}
|
|
2168
|
-
this.stack.push(item);
|
|
2169
|
-
continue;
|
|
2170
|
-
}
|
|
2171
|
-
if (isHandlerConfig(item)) {
|
|
2172
|
-
item.path = path || item.path;
|
|
2173
|
-
this.stack.push(new Handler(item));
|
|
2174
|
-
continue;
|
|
2175
|
-
}
|
|
2176
|
-
if (isHandler(item)) {
|
|
2177
|
-
item.setPath(path || item.path);
|
|
2178
|
-
this.stack.push(item);
|
|
2179
|
-
continue;
|
|
2180
|
-
}
|
|
2181
|
-
if (isPlugin(item)) {
|
|
2182
|
-
if (path) {
|
|
2183
|
-
this.install(item, {
|
|
2184
|
-
path
|
|
2185
|
-
});
|
|
2186
|
-
} else {
|
|
2187
|
-
this.install(item);
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
}
|
|
2191
|
-
return this;
|
|
2192
|
-
}
|
|
2193
|
-
// --------------------------------------------------
|
|
2194
|
-
install(plugin, context = {}) {
|
|
2195
|
-
const name = context.name || plugin.name;
|
|
2196
|
-
const router = new Router({
|
|
2197
|
-
name
|
|
2198
|
-
});
|
|
2199
|
-
plugin.install(router);
|
|
2200
|
-
if (context.path) {
|
|
2201
|
-
this.use(context.path, router);
|
|
2202
|
-
} else {
|
|
2203
|
-
this.use(router);
|
|
2204
|
-
}
|
|
2205
|
-
return this;
|
|
2206
|
-
}
|
|
2207
|
-
on(name, fn) {
|
|
2208
|
-
return this.hookManager.addListener(name, fn);
|
|
2209
|
-
}
|
|
2210
|
-
off(name, fn) {
|
|
2211
|
-
if (typeof fn === 'undefined') {
|
|
2212
|
-
this.hookManager.removeListener(name);
|
|
2213
|
-
return this;
|
|
2214
|
-
}
|
|
2215
|
-
this.hookManager.removeListener(name, fn);
|
|
2216
|
-
return this;
|
|
2217
|
-
}
|
|
2218
|
-
// --------------------------------------------------
|
|
2219
|
-
constructor(options = {}){
|
|
2220
|
-
this['@instanceof'] = RouterSymbol;
|
|
2221
|
-
/**
|
|
2222
|
-
* Array of mounted layers, routes & routers.
|
|
2223
|
-
*
|
|
2224
|
-
* @protected
|
|
2225
|
-
*/ this.stack = [];
|
|
2226
|
-
this.id = generateRouterID();
|
|
2227
|
-
this.name = options.name;
|
|
2228
|
-
this.hookManager = new HookManager();
|
|
2229
|
-
this.setPath(options.path);
|
|
2230
|
-
setRouterOptions(this.id, transformRouterOptions(options));
|
|
2231
|
-
}
|
|
2232
|
-
}
|
|
2233
|
-
|
|
2234
|
-
export { DispatchErrorEvent, DispatchEvent, EventStream, Handler, HandlerSymbol, HandlerType, HeaderName, MethodName, PathMatcher, Router, RoutupError, appendResponseHeader, appendResponseHeaderDirective, coreHandler, createError, createEventStream, createNodeDispatcher, createRawDispatcher, createRequest, createResponse, createWebDispatcher, dispatch, dispatchNodeRequest, dispatchRawRequest, dispatchWebRequest, errorHandler, getRequestAcceptableCharset, getRequestAcceptableCharsets, getRequestAcceptableContentType, getRequestAcceptableContentTypes, getRequestAcceptableEncoding, getRequestAcceptableEncodings, getRequestAcceptableLanguage, getRequestAcceptableLanguages, getRequestHeader, getRequestHostName, getRequestIP, getRequestProtocol, isDispatcherErrorEvent, isError, isHandler, isHandlerConfig, isPath, isPlugin, isRequestCacheable, isRequestHTTP2, isResponseGone, matchRequestContentType, send, sendAccepted, sendCreated, sendFile, sendFormat, sendRedirect, sendStream, sendWebBlob, sendWebResponse, setRequestEnv, setRequestHeader, setRequestMountPath, setRequestParam, setRequestParams, setRequestRouterPath, setResponseCacheHeaders, setResponseContentTypeByFileName, setResponseGone, setResponseHeaderAttachment, setResponseHeaderContentType, transformHeaderToTuples, transformHeadersToTuples, unsetRequestEnv, useRequestEnv, useRequestMountPath, useRequestNegotiator, useRequestParam, useRequestParams, useRequestPath, useRequestRouterPath };
|
|
2235
|
-
//# sourceMappingURL=index.mjs.map
|