@visulima/storage 1.0.0-alpha.6 → 1.0.0-alpha.7
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/CHANGELOG.md +25 -0
- package/LICENSE.md +4 -4
- package/dist/handler/http/fetch/index.js +4 -4
- package/dist/handler/http/hono/index.js +3 -3
- package/dist/handler/http/nextjs/index.d.ts +2 -2
- package/dist/handler/http/nextjs/index.js +4 -4
- package/dist/handler/http/node/index.js +8 -4
- package/dist/handler/http/solid-start/index.js +3 -3
- package/dist/index.js +1 -1
- package/dist/openapi/index.js +3 -3
- package/dist/packem_shared/{GCSMetaStorage-D2UXIUl1.js → GCSMetaStorage-B-a0EEAN.js} +1 -1
- package/dist/packem_shared/{GCStorage-CKKUTi6G.js → GCStorage-0CRe9ItT.js} +1 -1
- package/dist/packem_shared/{Multipart-CNFK_Okz.js → Multipart-5Xpy7WhY.js} +3 -3
- package/dist/packem_shared/{Multipart-CtUL7BQw.js → Multipart-C-iU9LXj.js} +4 -4
- package/dist/packem_shared/{Rest-CAOAEkOj.js → Rest-DO7OslCs.js} +4 -4
- package/dist/packem_shared/{Rest-DNuLwBrK.js → Rest-DTaszQ6n.js} +4 -4
- package/dist/packem_shared/{TUS_RESUMABLE-GJzZ9R-f.js → TUS_RESUMABLE-BfguFdM1.js} +1 -1
- package/dist/packem_shared/{Tus-B8PmlMgR.js → Tus-BQItPVAC.js} +4 -4
- package/dist/packem_shared/{Tus-C4F1aYOl.js → Tus-BibjweWH.js} +5 -5
- package/dist/packem_shared/{base-handler-core-BKuf4YLT.js → base-handler-core-DLEVHemv.js} +1 -1
- package/dist/packem_shared/{base-handler-fetch-Cr0hLiqg.js → base-handler-fetch-A7V0N6AJ.js} +2 -2
- package/dist/packem_shared/{base-handler-node-gk5aN9Cx.js → base-handler-node-Dx7ce3sU.js} +2 -2
- package/dist/packem_shared/{gcs-meta-storage-DD2FFN7j.js → gcs-meta-storage-cb2Wp-p-.js} +1 -1
- package/dist/packem_shared/headers-C9DasoT1.js +1318 -0
- package/dist/packem_shared/{multipart-base-B3i67SSX.js → multipart-base-BY0rhkw5.js} +1 -1
- package/dist/packem_shared/{rest-base-GRCcnan7.js → rest-base-Bt9Np3M8.js} +2 -2
- package/dist/packem_shared/{restOpenApiSpec-CwcHHY2C.js → restOpenApiSpec-D1JC_Jto.js} +1 -1
- package/dist/packem_shared/{tusOpenApiSpec-6ohiToBy.js → tusOpenApiSpec-mBZkl7he.js} +1 -1
- package/dist/packem_shared/{xhrOpenApiSpec-DS17brnx.js → xhrOpenApiSpec-B1V5Dxrj.js} +1 -1
- package/dist/storage/gcs/index.js +2 -2
- package/dist/utils/headers.d.ts +4 -4
- package/package.json +4 -4
- package/dist/packem_shared/headers-DoS5nwM-.js +0 -3220
|
@@ -1,3220 +0,0 @@
|
|
|
1
|
-
import { g as getDefaultExportFromCjs } from './_commonjsHelpers-B85MJLTf.js';
|
|
2
|
-
import require$$0 from 'path';
|
|
3
|
-
|
|
4
|
-
var httpErrors = {exports: {}};
|
|
5
|
-
|
|
6
|
-
var depd_1;
|
|
7
|
-
var hasRequiredDepd;
|
|
8
|
-
|
|
9
|
-
function requireDepd () {
|
|
10
|
-
if (hasRequiredDepd) return depd_1;
|
|
11
|
-
hasRequiredDepd = 1;
|
|
12
|
-
/*!
|
|
13
|
-
* depd
|
|
14
|
-
* Copyright(c) 2014-2018 Douglas Christopher Wilson
|
|
15
|
-
* MIT Licensed
|
|
16
|
-
*/
|
|
17
|
-
var relative = require$$0.relative;
|
|
18
|
-
depd_1 = depd;
|
|
19
|
-
var basePath = process.cwd();
|
|
20
|
-
function containsNamespace(str, namespace) {
|
|
21
|
-
var vals = str.split(/[ ,]+/);
|
|
22
|
-
var ns = String(namespace).toLowerCase();
|
|
23
|
-
for (var i = 0; i < vals.length; i++) {
|
|
24
|
-
var val = vals[i];
|
|
25
|
-
if (val && (val === "*" || val.toLowerCase() === ns)) {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
function convertDataDescriptorToAccessor(obj, prop, message) {
|
|
32
|
-
var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
|
|
33
|
-
var value = descriptor.value;
|
|
34
|
-
descriptor.get = function getter() {
|
|
35
|
-
return value;
|
|
36
|
-
};
|
|
37
|
-
if (descriptor.writable) {
|
|
38
|
-
descriptor.set = function setter(val) {
|
|
39
|
-
return value = val;
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
delete descriptor.value;
|
|
43
|
-
delete descriptor.writable;
|
|
44
|
-
Object.defineProperty(obj, prop, descriptor);
|
|
45
|
-
return descriptor;
|
|
46
|
-
}
|
|
47
|
-
function createArgumentsString(arity) {
|
|
48
|
-
var str = "";
|
|
49
|
-
for (var i = 0; i < arity; i++) {
|
|
50
|
-
str += ", arg" + i;
|
|
51
|
-
}
|
|
52
|
-
return str.substr(2);
|
|
53
|
-
}
|
|
54
|
-
function createStackString(stack) {
|
|
55
|
-
var str = this.name + ": " + this.namespace;
|
|
56
|
-
if (this.message) {
|
|
57
|
-
str += " deprecated " + this.message;
|
|
58
|
-
}
|
|
59
|
-
for (var i = 0; i < stack.length; i++) {
|
|
60
|
-
str += "\n at " + stack[i].toString();
|
|
61
|
-
}
|
|
62
|
-
return str;
|
|
63
|
-
}
|
|
64
|
-
function depd(namespace) {
|
|
65
|
-
if (!namespace) {
|
|
66
|
-
throw new TypeError("argument namespace is required");
|
|
67
|
-
}
|
|
68
|
-
var stack = getStack();
|
|
69
|
-
var site = callSiteLocation(stack[1]);
|
|
70
|
-
var file = site[0];
|
|
71
|
-
function deprecate(message) {
|
|
72
|
-
log.call(deprecate, message);
|
|
73
|
-
}
|
|
74
|
-
deprecate._file = file;
|
|
75
|
-
deprecate._ignored = isignored(namespace);
|
|
76
|
-
deprecate._namespace = namespace;
|
|
77
|
-
deprecate._traced = istraced(namespace);
|
|
78
|
-
deprecate._warned = /* @__PURE__ */ Object.create(null);
|
|
79
|
-
deprecate.function = wrapfunction;
|
|
80
|
-
deprecate.property = wrapproperty;
|
|
81
|
-
return deprecate;
|
|
82
|
-
}
|
|
83
|
-
function eehaslisteners(emitter, type) {
|
|
84
|
-
var count = typeof emitter.listenerCount !== "function" ? emitter.listeners(type).length : emitter.listenerCount(type);
|
|
85
|
-
return count > 0;
|
|
86
|
-
}
|
|
87
|
-
function isignored(namespace) {
|
|
88
|
-
if (process.noDeprecation) {
|
|
89
|
-
return true;
|
|
90
|
-
}
|
|
91
|
-
var str = process.env.NO_DEPRECATION || "";
|
|
92
|
-
return containsNamespace(str, namespace);
|
|
93
|
-
}
|
|
94
|
-
function istraced(namespace) {
|
|
95
|
-
if (process.traceDeprecation) {
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
var str = process.env.TRACE_DEPRECATION || "";
|
|
99
|
-
return containsNamespace(str, namespace);
|
|
100
|
-
}
|
|
101
|
-
function log(message, site) {
|
|
102
|
-
var haslisteners = eehaslisteners(process, "deprecation");
|
|
103
|
-
if (!haslisteners && this._ignored) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
var caller;
|
|
107
|
-
var callFile;
|
|
108
|
-
var callSite;
|
|
109
|
-
var depSite;
|
|
110
|
-
var i = 0;
|
|
111
|
-
var seen = false;
|
|
112
|
-
var stack = getStack();
|
|
113
|
-
var file = this._file;
|
|
114
|
-
if (site) {
|
|
115
|
-
depSite = site;
|
|
116
|
-
callSite = callSiteLocation(stack[1]);
|
|
117
|
-
callSite.name = depSite.name;
|
|
118
|
-
file = callSite[0];
|
|
119
|
-
} else {
|
|
120
|
-
i = 2;
|
|
121
|
-
depSite = callSiteLocation(stack[i]);
|
|
122
|
-
callSite = depSite;
|
|
123
|
-
}
|
|
124
|
-
for (; i < stack.length; i++) {
|
|
125
|
-
caller = callSiteLocation(stack[i]);
|
|
126
|
-
callFile = caller[0];
|
|
127
|
-
if (callFile === file) {
|
|
128
|
-
seen = true;
|
|
129
|
-
} else if (callFile === this._file) {
|
|
130
|
-
file = this._file;
|
|
131
|
-
} else if (seen) {
|
|
132
|
-
break;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
var key = caller ? depSite.join(":") + "__" + caller.join(":") : void 0;
|
|
136
|
-
if (key !== void 0 && key in this._warned) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
this._warned[key] = true;
|
|
140
|
-
var msg = message;
|
|
141
|
-
if (!msg) {
|
|
142
|
-
msg = callSite === depSite || !callSite.name ? defaultMessage(depSite) : defaultMessage(callSite);
|
|
143
|
-
}
|
|
144
|
-
if (haslisteners) {
|
|
145
|
-
var err = DeprecationError(this._namespace, msg, stack.slice(i));
|
|
146
|
-
process.emit("deprecation", err);
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
var format = process.stderr.isTTY ? formatColor : formatPlain;
|
|
150
|
-
var output = format.call(this, msg, caller, stack.slice(i));
|
|
151
|
-
process.stderr.write(output + "\n", "utf8");
|
|
152
|
-
}
|
|
153
|
-
function callSiteLocation(callSite) {
|
|
154
|
-
var file = callSite.getFileName() || "<anonymous>";
|
|
155
|
-
var line = callSite.getLineNumber();
|
|
156
|
-
var colm = callSite.getColumnNumber();
|
|
157
|
-
if (callSite.isEval()) {
|
|
158
|
-
file = callSite.getEvalOrigin() + ", " + file;
|
|
159
|
-
}
|
|
160
|
-
var site = [file, line, colm];
|
|
161
|
-
site.callSite = callSite;
|
|
162
|
-
site.name = callSite.getFunctionName();
|
|
163
|
-
return site;
|
|
164
|
-
}
|
|
165
|
-
function defaultMessage(site) {
|
|
166
|
-
var callSite = site.callSite;
|
|
167
|
-
var funcName = site.name;
|
|
168
|
-
if (!funcName) {
|
|
169
|
-
funcName = "<anonymous@" + formatLocation(site) + ">";
|
|
170
|
-
}
|
|
171
|
-
var context = callSite.getThis();
|
|
172
|
-
var typeName = context && callSite.getTypeName();
|
|
173
|
-
if (typeName === "Object") {
|
|
174
|
-
typeName = void 0;
|
|
175
|
-
}
|
|
176
|
-
if (typeName === "Function") {
|
|
177
|
-
typeName = context.name || typeName;
|
|
178
|
-
}
|
|
179
|
-
return typeName && callSite.getMethodName() ? typeName + "." + funcName : funcName;
|
|
180
|
-
}
|
|
181
|
-
function formatPlain(msg, caller, stack) {
|
|
182
|
-
var timestamp = (/* @__PURE__ */ new Date()).toUTCString();
|
|
183
|
-
var formatted = timestamp + " " + this._namespace + " deprecated " + msg;
|
|
184
|
-
if (this._traced) {
|
|
185
|
-
for (var i = 0; i < stack.length; i++) {
|
|
186
|
-
formatted += "\n at " + stack[i].toString();
|
|
187
|
-
}
|
|
188
|
-
return formatted;
|
|
189
|
-
}
|
|
190
|
-
if (caller) {
|
|
191
|
-
formatted += " at " + formatLocation(caller);
|
|
192
|
-
}
|
|
193
|
-
return formatted;
|
|
194
|
-
}
|
|
195
|
-
function formatColor(msg, caller, stack) {
|
|
196
|
-
var formatted = "\x1B[36;1m" + this._namespace + "\x1B[22;39m \x1B[33;1mdeprecated\x1B[22;39m \x1B[0m" + msg + "\x1B[39m";
|
|
197
|
-
if (this._traced) {
|
|
198
|
-
for (var i = 0; i < stack.length; i++) {
|
|
199
|
-
formatted += "\n \x1B[36mat " + stack[i].toString() + "\x1B[39m";
|
|
200
|
-
}
|
|
201
|
-
return formatted;
|
|
202
|
-
}
|
|
203
|
-
if (caller) {
|
|
204
|
-
formatted += " \x1B[36m" + formatLocation(caller) + "\x1B[39m";
|
|
205
|
-
}
|
|
206
|
-
return formatted;
|
|
207
|
-
}
|
|
208
|
-
function formatLocation(callSite) {
|
|
209
|
-
return relative(basePath, callSite[0]) + ":" + callSite[1] + ":" + callSite[2];
|
|
210
|
-
}
|
|
211
|
-
function getStack() {
|
|
212
|
-
var limit = Error.stackTraceLimit;
|
|
213
|
-
var obj = {};
|
|
214
|
-
var prep = Error.prepareStackTrace;
|
|
215
|
-
Error.prepareStackTrace = prepareObjectStackTrace;
|
|
216
|
-
Error.stackTraceLimit = Math.max(10, limit);
|
|
217
|
-
Error.captureStackTrace(obj);
|
|
218
|
-
var stack = obj.stack.slice(1);
|
|
219
|
-
Error.prepareStackTrace = prep;
|
|
220
|
-
Error.stackTraceLimit = limit;
|
|
221
|
-
return stack;
|
|
222
|
-
}
|
|
223
|
-
function prepareObjectStackTrace(obj, stack) {
|
|
224
|
-
return stack;
|
|
225
|
-
}
|
|
226
|
-
function wrapfunction(fn, message) {
|
|
227
|
-
if (typeof fn !== "function") {
|
|
228
|
-
throw new TypeError("argument fn must be a function");
|
|
229
|
-
}
|
|
230
|
-
var args = createArgumentsString(fn.length);
|
|
231
|
-
var stack = getStack();
|
|
232
|
-
var site = callSiteLocation(stack[1]);
|
|
233
|
-
site.name = fn.name;
|
|
234
|
-
var deprecatedfn = new Function(
|
|
235
|
-
"fn",
|
|
236
|
-
"log",
|
|
237
|
-
"deprecate",
|
|
238
|
-
"message",
|
|
239
|
-
"site",
|
|
240
|
-
'"use strict"\nreturn function (' + args + ") {log.call(deprecate, message, site)\nreturn fn.apply(this, arguments)\n}"
|
|
241
|
-
)(fn, log, this, message, site);
|
|
242
|
-
return deprecatedfn;
|
|
243
|
-
}
|
|
244
|
-
function wrapproperty(obj, prop, message) {
|
|
245
|
-
if (!obj || typeof obj !== "object" && typeof obj !== "function") {
|
|
246
|
-
throw new TypeError("argument obj must be object");
|
|
247
|
-
}
|
|
248
|
-
var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
|
|
249
|
-
if (!descriptor) {
|
|
250
|
-
throw new TypeError("must call property on owner object");
|
|
251
|
-
}
|
|
252
|
-
if (!descriptor.configurable) {
|
|
253
|
-
throw new TypeError("property must be configurable");
|
|
254
|
-
}
|
|
255
|
-
var deprecate = this;
|
|
256
|
-
var stack = getStack();
|
|
257
|
-
var site = callSiteLocation(stack[1]);
|
|
258
|
-
site.name = prop;
|
|
259
|
-
if ("value" in descriptor) {
|
|
260
|
-
descriptor = convertDataDescriptorToAccessor(obj, prop);
|
|
261
|
-
}
|
|
262
|
-
var get = descriptor.get;
|
|
263
|
-
var set = descriptor.set;
|
|
264
|
-
if (typeof get === "function") {
|
|
265
|
-
descriptor.get = function getter() {
|
|
266
|
-
log.call(deprecate, message, site);
|
|
267
|
-
return get.apply(this, arguments);
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
if (typeof set === "function") {
|
|
271
|
-
descriptor.set = function setter() {
|
|
272
|
-
log.call(deprecate, message, site);
|
|
273
|
-
return set.apply(this, arguments);
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
Object.defineProperty(obj, prop, descriptor);
|
|
277
|
-
}
|
|
278
|
-
function DeprecationError(namespace, message, stack) {
|
|
279
|
-
var error = new Error();
|
|
280
|
-
var stackString;
|
|
281
|
-
Object.defineProperty(error, "constructor", {
|
|
282
|
-
value: DeprecationError
|
|
283
|
-
});
|
|
284
|
-
Object.defineProperty(error, "message", {
|
|
285
|
-
configurable: true,
|
|
286
|
-
enumerable: false,
|
|
287
|
-
value: message,
|
|
288
|
-
writable: true
|
|
289
|
-
});
|
|
290
|
-
Object.defineProperty(error, "name", {
|
|
291
|
-
enumerable: false,
|
|
292
|
-
configurable: true,
|
|
293
|
-
value: "DeprecationError",
|
|
294
|
-
writable: true
|
|
295
|
-
});
|
|
296
|
-
Object.defineProperty(error, "namespace", {
|
|
297
|
-
configurable: true,
|
|
298
|
-
enumerable: false,
|
|
299
|
-
value: namespace,
|
|
300
|
-
writable: true
|
|
301
|
-
});
|
|
302
|
-
Object.defineProperty(error, "stack", {
|
|
303
|
-
configurable: true,
|
|
304
|
-
enumerable: false,
|
|
305
|
-
get: function() {
|
|
306
|
-
if (stackString !== void 0) {
|
|
307
|
-
return stackString;
|
|
308
|
-
}
|
|
309
|
-
return stackString = createStackString.call(this, stack);
|
|
310
|
-
},
|
|
311
|
-
set: function setter(val) {
|
|
312
|
-
stackString = val;
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
return error;
|
|
316
|
-
}
|
|
317
|
-
return depd_1;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
var setprototypeof;
|
|
321
|
-
var hasRequiredSetprototypeof;
|
|
322
|
-
|
|
323
|
-
function requireSetprototypeof () {
|
|
324
|
-
if (hasRequiredSetprototypeof) return setprototypeof;
|
|
325
|
-
hasRequiredSetprototypeof = 1;
|
|
326
|
-
setprototypeof = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties);
|
|
327
|
-
function setProtoOf(obj, proto) {
|
|
328
|
-
obj.__proto__ = proto;
|
|
329
|
-
return obj;
|
|
330
|
-
}
|
|
331
|
-
function mixinProperties(obj, proto) {
|
|
332
|
-
for (var prop in proto) {
|
|
333
|
-
if (!Object.prototype.hasOwnProperty.call(obj, prop)) {
|
|
334
|
-
obj[prop] = proto[prop];
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
return obj;
|
|
338
|
-
}
|
|
339
|
-
return setprototypeof;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
var codes;
|
|
343
|
-
var hasRequiredCodes;
|
|
344
|
-
|
|
345
|
-
function requireCodes () {
|
|
346
|
-
if (hasRequiredCodes) return codes;
|
|
347
|
-
hasRequiredCodes = 1;
|
|
348
|
-
codes = {
|
|
349
|
-
"100": "Continue",
|
|
350
|
-
"101": "Switching Protocols",
|
|
351
|
-
"102": "Processing",
|
|
352
|
-
"103": "Early Hints",
|
|
353
|
-
"200": "OK",
|
|
354
|
-
"201": "Created",
|
|
355
|
-
"202": "Accepted",
|
|
356
|
-
"203": "Non-Authoritative Information",
|
|
357
|
-
"204": "No Content",
|
|
358
|
-
"205": "Reset Content",
|
|
359
|
-
"206": "Partial Content",
|
|
360
|
-
"207": "Multi-Status",
|
|
361
|
-
"208": "Already Reported",
|
|
362
|
-
"226": "IM Used",
|
|
363
|
-
"300": "Multiple Choices",
|
|
364
|
-
"301": "Moved Permanently",
|
|
365
|
-
"302": "Found",
|
|
366
|
-
"303": "See Other",
|
|
367
|
-
"304": "Not Modified",
|
|
368
|
-
"305": "Use Proxy",
|
|
369
|
-
"307": "Temporary Redirect",
|
|
370
|
-
"308": "Permanent Redirect",
|
|
371
|
-
"400": "Bad Request",
|
|
372
|
-
"401": "Unauthorized",
|
|
373
|
-
"402": "Payment Required",
|
|
374
|
-
"403": "Forbidden",
|
|
375
|
-
"404": "Not Found",
|
|
376
|
-
"405": "Method Not Allowed",
|
|
377
|
-
"406": "Not Acceptable",
|
|
378
|
-
"407": "Proxy Authentication Required",
|
|
379
|
-
"408": "Request Timeout",
|
|
380
|
-
"409": "Conflict",
|
|
381
|
-
"410": "Gone",
|
|
382
|
-
"411": "Length Required",
|
|
383
|
-
"412": "Precondition Failed",
|
|
384
|
-
"413": "Payload Too Large",
|
|
385
|
-
"414": "URI Too Long",
|
|
386
|
-
"415": "Unsupported Media Type",
|
|
387
|
-
"416": "Range Not Satisfiable",
|
|
388
|
-
"417": "Expectation Failed",
|
|
389
|
-
"418": "I'm a Teapot",
|
|
390
|
-
"421": "Misdirected Request",
|
|
391
|
-
"422": "Unprocessable Entity",
|
|
392
|
-
"423": "Locked",
|
|
393
|
-
"424": "Failed Dependency",
|
|
394
|
-
"425": "Too Early",
|
|
395
|
-
"426": "Upgrade Required",
|
|
396
|
-
"428": "Precondition Required",
|
|
397
|
-
"429": "Too Many Requests",
|
|
398
|
-
"431": "Request Header Fields Too Large",
|
|
399
|
-
"451": "Unavailable For Legal Reasons",
|
|
400
|
-
"500": "Internal Server Error",
|
|
401
|
-
"501": "Not Implemented",
|
|
402
|
-
"502": "Bad Gateway",
|
|
403
|
-
"503": "Service Unavailable",
|
|
404
|
-
"504": "Gateway Timeout",
|
|
405
|
-
"505": "HTTP Version Not Supported",
|
|
406
|
-
"506": "Variant Also Negotiates",
|
|
407
|
-
"507": "Insufficient Storage",
|
|
408
|
-
"508": "Loop Detected",
|
|
409
|
-
"509": "Bandwidth Limit Exceeded",
|
|
410
|
-
"510": "Not Extended",
|
|
411
|
-
"511": "Network Authentication Required"
|
|
412
|
-
};
|
|
413
|
-
return codes;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
var statuses;
|
|
417
|
-
var hasRequiredStatuses;
|
|
418
|
-
|
|
419
|
-
function requireStatuses () {
|
|
420
|
-
if (hasRequiredStatuses) return statuses;
|
|
421
|
-
hasRequiredStatuses = 1;
|
|
422
|
-
/*!
|
|
423
|
-
* statuses
|
|
424
|
-
* Copyright(c) 2014 Jonathan Ong
|
|
425
|
-
* Copyright(c) 2016 Douglas Christopher Wilson
|
|
426
|
-
* MIT Licensed
|
|
427
|
-
*/
|
|
428
|
-
var codes = requireCodes();
|
|
429
|
-
statuses = status;
|
|
430
|
-
status.message = codes;
|
|
431
|
-
status.code = createMessageToStatusCodeMap(codes);
|
|
432
|
-
status.codes = createStatusCodeList(codes);
|
|
433
|
-
status.redirect = {
|
|
434
|
-
300: true,
|
|
435
|
-
301: true,
|
|
436
|
-
302: true,
|
|
437
|
-
303: true,
|
|
438
|
-
305: true,
|
|
439
|
-
307: true,
|
|
440
|
-
308: true
|
|
441
|
-
};
|
|
442
|
-
status.empty = {
|
|
443
|
-
204: true,
|
|
444
|
-
205: true,
|
|
445
|
-
304: true
|
|
446
|
-
};
|
|
447
|
-
status.retry = {
|
|
448
|
-
502: true,
|
|
449
|
-
503: true,
|
|
450
|
-
504: true
|
|
451
|
-
};
|
|
452
|
-
function createMessageToStatusCodeMap(codes2) {
|
|
453
|
-
var map = {};
|
|
454
|
-
Object.keys(codes2).forEach(function forEachCode(code) {
|
|
455
|
-
var message = codes2[code];
|
|
456
|
-
var status2 = Number(code);
|
|
457
|
-
map[message.toLowerCase()] = status2;
|
|
458
|
-
});
|
|
459
|
-
return map;
|
|
460
|
-
}
|
|
461
|
-
function createStatusCodeList(codes2) {
|
|
462
|
-
return Object.keys(codes2).map(function mapCode(code) {
|
|
463
|
-
return Number(code);
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
function getStatusCode(message) {
|
|
467
|
-
var msg = message.toLowerCase();
|
|
468
|
-
if (!Object.prototype.hasOwnProperty.call(status.code, msg)) {
|
|
469
|
-
throw new Error('invalid status message: "' + message + '"');
|
|
470
|
-
}
|
|
471
|
-
return status.code[msg];
|
|
472
|
-
}
|
|
473
|
-
function getStatusMessage(code) {
|
|
474
|
-
if (!Object.prototype.hasOwnProperty.call(status.message, code)) {
|
|
475
|
-
throw new Error("invalid status code: " + code);
|
|
476
|
-
}
|
|
477
|
-
return status.message[code];
|
|
478
|
-
}
|
|
479
|
-
function status(code) {
|
|
480
|
-
if (typeof code === "number") {
|
|
481
|
-
return getStatusMessage(code);
|
|
482
|
-
}
|
|
483
|
-
if (typeof code !== "string") {
|
|
484
|
-
throw new TypeError("code must be a number or string");
|
|
485
|
-
}
|
|
486
|
-
var n = parseInt(code, 10);
|
|
487
|
-
if (!isNaN(n)) {
|
|
488
|
-
return getStatusMessage(n);
|
|
489
|
-
}
|
|
490
|
-
return getStatusCode(code);
|
|
491
|
-
}
|
|
492
|
-
return statuses;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
var inherits = {exports: {}};
|
|
496
|
-
|
|
497
|
-
var inherits_browser = {exports: {}};
|
|
498
|
-
|
|
499
|
-
var hasRequiredInherits_browser;
|
|
500
|
-
|
|
501
|
-
function requireInherits_browser () {
|
|
502
|
-
if (hasRequiredInherits_browser) return inherits_browser.exports;
|
|
503
|
-
hasRequiredInherits_browser = 1;
|
|
504
|
-
if (typeof Object.create === "function") {
|
|
505
|
-
inherits_browser.exports = function inherits(ctor, superCtor) {
|
|
506
|
-
if (superCtor) {
|
|
507
|
-
ctor.super_ = superCtor;
|
|
508
|
-
ctor.prototype = Object.create(superCtor.prototype, {
|
|
509
|
-
constructor: {
|
|
510
|
-
value: ctor,
|
|
511
|
-
enumerable: false,
|
|
512
|
-
writable: true,
|
|
513
|
-
configurable: true
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
};
|
|
518
|
-
} else {
|
|
519
|
-
inherits_browser.exports = function inherits(ctor, superCtor) {
|
|
520
|
-
if (superCtor) {
|
|
521
|
-
ctor.super_ = superCtor;
|
|
522
|
-
var TempCtor = function() {
|
|
523
|
-
};
|
|
524
|
-
TempCtor.prototype = superCtor.prototype;
|
|
525
|
-
ctor.prototype = new TempCtor();
|
|
526
|
-
ctor.prototype.constructor = ctor;
|
|
527
|
-
}
|
|
528
|
-
};
|
|
529
|
-
}
|
|
530
|
-
return inherits_browser.exports;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
var hasRequiredInherits;
|
|
534
|
-
|
|
535
|
-
function requireInherits () {
|
|
536
|
-
if (hasRequiredInherits) return inherits.exports;
|
|
537
|
-
hasRequiredInherits = 1;
|
|
538
|
-
try {
|
|
539
|
-
var util = require("util");
|
|
540
|
-
if (typeof util.inherits !== "function") throw "";
|
|
541
|
-
inherits.exports = util.inherits;
|
|
542
|
-
} catch (e) {
|
|
543
|
-
inherits.exports = requireInherits_browser();
|
|
544
|
-
}
|
|
545
|
-
return inherits.exports;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
var toidentifier;
|
|
549
|
-
var hasRequiredToidentifier;
|
|
550
|
-
|
|
551
|
-
function requireToidentifier () {
|
|
552
|
-
if (hasRequiredToidentifier) return toidentifier;
|
|
553
|
-
hasRequiredToidentifier = 1;
|
|
554
|
-
/*!
|
|
555
|
-
* toidentifier
|
|
556
|
-
* Copyright(c) 2016 Douglas Christopher Wilson
|
|
557
|
-
* MIT Licensed
|
|
558
|
-
*/
|
|
559
|
-
toidentifier = toIdentifier;
|
|
560
|
-
function toIdentifier(str) {
|
|
561
|
-
return str.split(" ").map(function(token) {
|
|
562
|
-
return token.slice(0, 1).toUpperCase() + token.slice(1);
|
|
563
|
-
}).join("").replace(/[^ _0-9a-z]/gi, "");
|
|
564
|
-
}
|
|
565
|
-
return toidentifier;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
var hasRequiredHttpErrors;
|
|
569
|
-
|
|
570
|
-
function requireHttpErrors () {
|
|
571
|
-
if (hasRequiredHttpErrors) return httpErrors.exports;
|
|
572
|
-
hasRequiredHttpErrors = 1;
|
|
573
|
-
(function (module) {
|
|
574
|
-
/*!
|
|
575
|
-
* http-errors
|
|
576
|
-
* Copyright(c) 2014 Jonathan Ong
|
|
577
|
-
* Copyright(c) 2016 Douglas Christopher Wilson
|
|
578
|
-
* MIT Licensed
|
|
579
|
-
*/
|
|
580
|
-
var deprecate = requireDepd()("http-errors");
|
|
581
|
-
var setPrototypeOf = requireSetprototypeof();
|
|
582
|
-
var statuses = requireStatuses();
|
|
583
|
-
var inherits = requireInherits();
|
|
584
|
-
var toIdentifier = requireToidentifier();
|
|
585
|
-
module.exports = createError;
|
|
586
|
-
module.exports.HttpError = createHttpErrorConstructor();
|
|
587
|
-
module.exports.isHttpError = createIsHttpErrorFunction(module.exports.HttpError);
|
|
588
|
-
populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError);
|
|
589
|
-
function codeClass(status) {
|
|
590
|
-
return Number(String(status).charAt(0) + "00");
|
|
591
|
-
}
|
|
592
|
-
function createError() {
|
|
593
|
-
var err;
|
|
594
|
-
var msg;
|
|
595
|
-
var status = 500;
|
|
596
|
-
var props = {};
|
|
597
|
-
for (var i = 0; i < arguments.length; i++) {
|
|
598
|
-
var arg = arguments[i];
|
|
599
|
-
var type = typeof arg;
|
|
600
|
-
if (type === "object" && arg instanceof Error) {
|
|
601
|
-
err = arg;
|
|
602
|
-
status = err.status || err.statusCode || status;
|
|
603
|
-
} else if (type === "number" && i === 0) {
|
|
604
|
-
status = arg;
|
|
605
|
-
} else if (type === "string") {
|
|
606
|
-
msg = arg;
|
|
607
|
-
} else if (type === "object") {
|
|
608
|
-
props = arg;
|
|
609
|
-
} else {
|
|
610
|
-
throw new TypeError("argument #" + (i + 1) + " unsupported type " + type);
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
if (typeof status === "number" && (status < 400 || status >= 600)) {
|
|
614
|
-
deprecate("non-error status code; use only 4xx or 5xx status codes");
|
|
615
|
-
}
|
|
616
|
-
if (typeof status !== "number" || !statuses.message[status] && (status < 400 || status >= 600)) {
|
|
617
|
-
status = 500;
|
|
618
|
-
}
|
|
619
|
-
var HttpError = createError[status] || createError[codeClass(status)];
|
|
620
|
-
if (!err) {
|
|
621
|
-
err = HttpError ? new HttpError(msg) : new Error(msg || statuses.message[status]);
|
|
622
|
-
Error.captureStackTrace(err, createError);
|
|
623
|
-
}
|
|
624
|
-
if (!HttpError || !(err instanceof HttpError) || err.status !== status) {
|
|
625
|
-
err.expose = status < 500;
|
|
626
|
-
err.status = err.statusCode = status;
|
|
627
|
-
}
|
|
628
|
-
for (var key in props) {
|
|
629
|
-
if (key !== "status" && key !== "statusCode") {
|
|
630
|
-
err[key] = props[key];
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
return err;
|
|
634
|
-
}
|
|
635
|
-
function createHttpErrorConstructor() {
|
|
636
|
-
function HttpError() {
|
|
637
|
-
throw new TypeError("cannot construct abstract class");
|
|
638
|
-
}
|
|
639
|
-
inherits(HttpError, Error);
|
|
640
|
-
return HttpError;
|
|
641
|
-
}
|
|
642
|
-
function createClientErrorConstructor(HttpError, name, code) {
|
|
643
|
-
var className = toClassName(name);
|
|
644
|
-
function ClientError(message) {
|
|
645
|
-
var msg = message != null ? message : statuses.message[code];
|
|
646
|
-
var err = new Error(msg);
|
|
647
|
-
Error.captureStackTrace(err, ClientError);
|
|
648
|
-
setPrototypeOf(err, ClientError.prototype);
|
|
649
|
-
Object.defineProperty(err, "message", {
|
|
650
|
-
enumerable: true,
|
|
651
|
-
configurable: true,
|
|
652
|
-
value: msg,
|
|
653
|
-
writable: true
|
|
654
|
-
});
|
|
655
|
-
Object.defineProperty(err, "name", {
|
|
656
|
-
enumerable: false,
|
|
657
|
-
configurable: true,
|
|
658
|
-
value: className,
|
|
659
|
-
writable: true
|
|
660
|
-
});
|
|
661
|
-
return err;
|
|
662
|
-
}
|
|
663
|
-
inherits(ClientError, HttpError);
|
|
664
|
-
nameFunc(ClientError, className);
|
|
665
|
-
ClientError.prototype.status = code;
|
|
666
|
-
ClientError.prototype.statusCode = code;
|
|
667
|
-
ClientError.prototype.expose = true;
|
|
668
|
-
return ClientError;
|
|
669
|
-
}
|
|
670
|
-
function createIsHttpErrorFunction(HttpError) {
|
|
671
|
-
return function isHttpError(val) {
|
|
672
|
-
if (!val || typeof val !== "object") {
|
|
673
|
-
return false;
|
|
674
|
-
}
|
|
675
|
-
if (val instanceof HttpError) {
|
|
676
|
-
return true;
|
|
677
|
-
}
|
|
678
|
-
return val instanceof Error && typeof val.expose === "boolean" && typeof val.statusCode === "number" && val.status === val.statusCode;
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
function createServerErrorConstructor(HttpError, name, code) {
|
|
682
|
-
var className = toClassName(name);
|
|
683
|
-
function ServerError(message) {
|
|
684
|
-
var msg = message != null ? message : statuses.message[code];
|
|
685
|
-
var err = new Error(msg);
|
|
686
|
-
Error.captureStackTrace(err, ServerError);
|
|
687
|
-
setPrototypeOf(err, ServerError.prototype);
|
|
688
|
-
Object.defineProperty(err, "message", {
|
|
689
|
-
enumerable: true,
|
|
690
|
-
configurable: true,
|
|
691
|
-
value: msg,
|
|
692
|
-
writable: true
|
|
693
|
-
});
|
|
694
|
-
Object.defineProperty(err, "name", {
|
|
695
|
-
enumerable: false,
|
|
696
|
-
configurable: true,
|
|
697
|
-
value: className,
|
|
698
|
-
writable: true
|
|
699
|
-
});
|
|
700
|
-
return err;
|
|
701
|
-
}
|
|
702
|
-
inherits(ServerError, HttpError);
|
|
703
|
-
nameFunc(ServerError, className);
|
|
704
|
-
ServerError.prototype.status = code;
|
|
705
|
-
ServerError.prototype.statusCode = code;
|
|
706
|
-
ServerError.prototype.expose = false;
|
|
707
|
-
return ServerError;
|
|
708
|
-
}
|
|
709
|
-
function nameFunc(func, name) {
|
|
710
|
-
var desc = Object.getOwnPropertyDescriptor(func, "name");
|
|
711
|
-
if (desc && desc.configurable) {
|
|
712
|
-
desc.value = name;
|
|
713
|
-
Object.defineProperty(func, "name", desc);
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
function populateConstructorExports(exports$1, codes, HttpError) {
|
|
717
|
-
codes.forEach(function forEachCode(code) {
|
|
718
|
-
var CodeError;
|
|
719
|
-
var name = toIdentifier(statuses.message[code]);
|
|
720
|
-
switch (codeClass(code)) {
|
|
721
|
-
case 400:
|
|
722
|
-
CodeError = createClientErrorConstructor(HttpError, name, code);
|
|
723
|
-
break;
|
|
724
|
-
case 500:
|
|
725
|
-
CodeError = createServerErrorConstructor(HttpError, name, code);
|
|
726
|
-
break;
|
|
727
|
-
}
|
|
728
|
-
if (CodeError) {
|
|
729
|
-
exports$1[code] = CodeError;
|
|
730
|
-
exports$1[name] = CodeError;
|
|
731
|
-
}
|
|
732
|
-
});
|
|
733
|
-
}
|
|
734
|
-
function toClassName(name) {
|
|
735
|
-
return name.slice(-5) === "Error" ? name : name + "Error";
|
|
736
|
-
}
|
|
737
|
-
} (httpErrors));
|
|
738
|
-
return httpErrors.exports;
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
var httpErrorsExports = requireHttpErrors();
|
|
742
|
-
const createHttpError = /*@__PURE__*/getDefaultExportFromCjs(httpErrorsExports);
|
|
743
|
-
|
|
744
|
-
function parseParams(input, delimiter = ";") {
|
|
745
|
-
let parser = delimiter === ";" ? /(?:^|;)\s*([^=;\s]+)(\s*=\s*(?:"((?:[^"\\]|\\.)*)"|((?:[^;]|\\\;)+))?)?/g : /(?:^|,)\s*([^=,\s]+)(\s*=\s*(?:"((?:[^"\\]|\\.)*)"|((?:[^,]|\\\,)+))?)?/g;
|
|
746
|
-
let params = [];
|
|
747
|
-
let match;
|
|
748
|
-
while ((match = parser.exec(input)) !== null) {
|
|
749
|
-
let key = match[1].trim();
|
|
750
|
-
let value;
|
|
751
|
-
if (match[2]) {
|
|
752
|
-
value = (match[3] || match[4] || "").replace(/\\(.)/g, "$1").trim();
|
|
753
|
-
}
|
|
754
|
-
params.push([key, value]);
|
|
755
|
-
}
|
|
756
|
-
return params;
|
|
757
|
-
}
|
|
758
|
-
function quote(value) {
|
|
759
|
-
if (value.includes('"') || value.includes(";") || value.includes(" ")) {
|
|
760
|
-
return `"${value.replace(/"/g, '\\"')}"`;
|
|
761
|
-
}
|
|
762
|
-
return value;
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
function capitalize(str) {
|
|
766
|
-
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
767
|
-
}
|
|
768
|
-
function isIterable(value) {
|
|
769
|
-
return value != null && typeof value[Symbol.iterator] === "function";
|
|
770
|
-
}
|
|
771
|
-
function isValidDate(date) {
|
|
772
|
-
return date instanceof Date && !isNaN(date.getTime());
|
|
773
|
-
}
|
|
774
|
-
function quoteEtag(tag) {
|
|
775
|
-
return tag === "*" ? tag : /^(W\/)?".*"$/.test(tag) ? tag : `"${tag}"`;
|
|
776
|
-
}
|
|
777
|
-
function removeMilliseconds(time) {
|
|
778
|
-
let timestamp = time instanceof Date ? time.getTime() : time;
|
|
779
|
-
return Math.floor(timestamp / 1e3);
|
|
780
|
-
}
|
|
781
|
-
const imfFixdatePattern = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d{2}) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d{2}):(\d{2}):(\d{2}) GMT$/;
|
|
782
|
-
function parseHttpDate(dateString) {
|
|
783
|
-
if (!imfFixdatePattern.test(dateString)) {
|
|
784
|
-
return null;
|
|
785
|
-
}
|
|
786
|
-
let timestamp = Date.parse(dateString);
|
|
787
|
-
if (isNaN(timestamp)) {
|
|
788
|
-
return null;
|
|
789
|
-
}
|
|
790
|
-
return timestamp;
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
class Accept {
|
|
794
|
-
#map;
|
|
795
|
-
/**
|
|
796
|
-
* @param init A string, iterable, or record to initialize the header
|
|
797
|
-
*/
|
|
798
|
-
constructor(init) {
|
|
799
|
-
this.#map = /* @__PURE__ */ new Map();
|
|
800
|
-
if (init) {
|
|
801
|
-
if (typeof init === "string") {
|
|
802
|
-
for (let piece of init.split(/\s*,\s*/)) {
|
|
803
|
-
let params = parseParams(piece);
|
|
804
|
-
if (params.length < 1)
|
|
805
|
-
continue;
|
|
806
|
-
let mediaType = params[0][0];
|
|
807
|
-
let weight = 1;
|
|
808
|
-
for (let i = 1; i < params.length; i++) {
|
|
809
|
-
let [key, value] = params[i];
|
|
810
|
-
if (key === "q") {
|
|
811
|
-
weight = Number(value);
|
|
812
|
-
break;
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
this.#map.set(mediaType.toLowerCase(), weight);
|
|
816
|
-
}
|
|
817
|
-
} else if (isIterable(init)) {
|
|
818
|
-
for (let mediaType of init) {
|
|
819
|
-
if (Array.isArray(mediaType)) {
|
|
820
|
-
this.#map.set(mediaType[0].toLowerCase(), mediaType[1]);
|
|
821
|
-
} else {
|
|
822
|
-
this.#map.set(mediaType.toLowerCase(), 1);
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
} else {
|
|
826
|
-
for (let mediaType of Object.getOwnPropertyNames(init)) {
|
|
827
|
-
this.#map.set(mediaType.toLowerCase(), init[mediaType]);
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
this.#sort();
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
#sort() {
|
|
834
|
-
this.#map = new Map([...this.#map].sort((a, b) => b[1] - a[1]));
|
|
835
|
-
}
|
|
836
|
-
/**
|
|
837
|
-
* An array of all media types in the header.
|
|
838
|
-
*/
|
|
839
|
-
get mediaTypes() {
|
|
840
|
-
return Array.from(this.#map.keys());
|
|
841
|
-
}
|
|
842
|
-
/**
|
|
843
|
-
* An array of all weights (q values) in the header.
|
|
844
|
-
*/
|
|
845
|
-
get weights() {
|
|
846
|
-
return Array.from(this.#map.values());
|
|
847
|
-
}
|
|
848
|
-
/**
|
|
849
|
-
* The number of media types in the `Accept` header.
|
|
850
|
-
*/
|
|
851
|
-
get size() {
|
|
852
|
-
return this.#map.size;
|
|
853
|
-
}
|
|
854
|
-
/**
|
|
855
|
-
* Returns `true` if the header matches the given media type (i.e. it is "acceptable").
|
|
856
|
-
*
|
|
857
|
-
* @param mediaType The media type to check
|
|
858
|
-
* @return `true` if the media type is acceptable, `false` otherwise
|
|
859
|
-
*/
|
|
860
|
-
accepts(mediaType) {
|
|
861
|
-
return this.getWeight(mediaType) > 0;
|
|
862
|
-
}
|
|
863
|
-
/**
|
|
864
|
-
* Gets the weight of a given media type. Also supports wildcards, so e.g. `text/*` will match `text/html`.
|
|
865
|
-
*
|
|
866
|
-
* @param mediaType The media type to get the weight of
|
|
867
|
-
* @return The weight of the media type
|
|
868
|
-
*/
|
|
869
|
-
getWeight(mediaType) {
|
|
870
|
-
let [type, subtype] = mediaType.toLowerCase().split("/");
|
|
871
|
-
for (let [key, value] of this) {
|
|
872
|
-
let [t, s] = key.split("/");
|
|
873
|
-
if ((t === type || t === "*" || type === "*") && (s === subtype || s === "*" || subtype === "*")) {
|
|
874
|
-
return value;
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
return 0;
|
|
878
|
-
}
|
|
879
|
-
/**
|
|
880
|
-
* Returns the most preferred media type from the given list of media types.
|
|
881
|
-
*
|
|
882
|
-
* @param mediaTypes The list of media types to choose from
|
|
883
|
-
* @return The most preferred media type or `null` if none match
|
|
884
|
-
*/
|
|
885
|
-
getPreferred(mediaTypes) {
|
|
886
|
-
let sorted = mediaTypes.map((mediaType) => [mediaType, this.getWeight(mediaType)]).sort((a, b) => b[1] - a[1]);
|
|
887
|
-
let first = sorted[0];
|
|
888
|
-
return first !== void 0 && first[1] > 0 ? first[0] : null;
|
|
889
|
-
}
|
|
890
|
-
/**
|
|
891
|
-
* Returns the weight of a media type. If it is not in the header verbatim, this returns `null`.
|
|
892
|
-
*
|
|
893
|
-
* @param mediaType The media type to get the weight of
|
|
894
|
-
* @return The weight of the media type, or `null` if it is not in the header
|
|
895
|
-
*/
|
|
896
|
-
get(mediaType) {
|
|
897
|
-
return this.#map.get(mediaType.toLowerCase()) ?? null;
|
|
898
|
-
}
|
|
899
|
-
/**
|
|
900
|
-
* Sets a media type with the given weight.
|
|
901
|
-
*
|
|
902
|
-
* @param mediaType The media type to set
|
|
903
|
-
* @param weight The weight of the media type (default: `1`)
|
|
904
|
-
*/
|
|
905
|
-
set(mediaType, weight = 1) {
|
|
906
|
-
this.#map.set(mediaType.toLowerCase(), weight);
|
|
907
|
-
this.#sort();
|
|
908
|
-
}
|
|
909
|
-
/**
|
|
910
|
-
* Removes the given media type from the header.
|
|
911
|
-
*
|
|
912
|
-
* @param mediaType The media type to remove
|
|
913
|
-
*/
|
|
914
|
-
delete(mediaType) {
|
|
915
|
-
this.#map.delete(mediaType.toLowerCase());
|
|
916
|
-
}
|
|
917
|
-
/**
|
|
918
|
-
* Checks if a media type is in the header.
|
|
919
|
-
*
|
|
920
|
-
* @param mediaType The media type to check
|
|
921
|
-
* @return `true` if the media type is in the header (verbatim), `false` otherwise
|
|
922
|
-
*/
|
|
923
|
-
has(mediaType) {
|
|
924
|
-
return this.#map.has(mediaType.toLowerCase());
|
|
925
|
-
}
|
|
926
|
-
/**
|
|
927
|
-
* Removes all media types from the header.
|
|
928
|
-
*/
|
|
929
|
-
clear() {
|
|
930
|
-
this.#map.clear();
|
|
931
|
-
}
|
|
932
|
-
/**
|
|
933
|
-
* Returns an iterator of all media type and weight pairs.
|
|
934
|
-
*
|
|
935
|
-
* @return An iterator of `[mediaType, weight]` tuples
|
|
936
|
-
*/
|
|
937
|
-
entries() {
|
|
938
|
-
return this.#map.entries();
|
|
939
|
-
}
|
|
940
|
-
[Symbol.iterator]() {
|
|
941
|
-
return this.entries();
|
|
942
|
-
}
|
|
943
|
-
/**
|
|
944
|
-
* Invokes the callback for each media type and weight pair.
|
|
945
|
-
*
|
|
946
|
-
* @param callback The function to call for each pair
|
|
947
|
-
* @param thisArg The value to use as `this` when calling the callback
|
|
948
|
-
*/
|
|
949
|
-
forEach(callback, thisArg) {
|
|
950
|
-
for (let [mediaType, weight] of this) {
|
|
951
|
-
callback.call(thisArg, mediaType, weight, this);
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
/**
|
|
955
|
-
* Returns the string representation of the header value.
|
|
956
|
-
*
|
|
957
|
-
* @return The header value as a string
|
|
958
|
-
*/
|
|
959
|
-
toString() {
|
|
960
|
-
let pairs = [];
|
|
961
|
-
for (let [mediaType, weight] of this.#map) {
|
|
962
|
-
pairs.push(`${mediaType}${weight === 1 ? "" : `;q=${weight}`}`);
|
|
963
|
-
}
|
|
964
|
-
return pairs.join(",");
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
class AcceptEncoding {
|
|
969
|
-
#map;
|
|
970
|
-
/**
|
|
971
|
-
* @param init A string, iterable, or record to initialize the header
|
|
972
|
-
*/
|
|
973
|
-
constructor(init) {
|
|
974
|
-
this.#map = /* @__PURE__ */ new Map();
|
|
975
|
-
if (init) {
|
|
976
|
-
if (typeof init === "string") {
|
|
977
|
-
for (let piece of init.split(/\s*,\s*/)) {
|
|
978
|
-
let params = parseParams(piece);
|
|
979
|
-
if (params.length < 1)
|
|
980
|
-
continue;
|
|
981
|
-
let encoding = params[0][0];
|
|
982
|
-
let weight = 1;
|
|
983
|
-
for (let i = 1; i < params.length; i++) {
|
|
984
|
-
let [key, value] = params[i];
|
|
985
|
-
if (key === "q") {
|
|
986
|
-
weight = Number(value);
|
|
987
|
-
break;
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
this.#map.set(encoding.toLowerCase(), weight);
|
|
991
|
-
}
|
|
992
|
-
} else if (isIterable(init)) {
|
|
993
|
-
for (let value of init) {
|
|
994
|
-
if (Array.isArray(value)) {
|
|
995
|
-
this.#map.set(value[0].toLowerCase(), value[1]);
|
|
996
|
-
} else {
|
|
997
|
-
this.#map.set(value.toLowerCase(), 1);
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
} else {
|
|
1001
|
-
for (let encoding of Object.getOwnPropertyNames(init)) {
|
|
1002
|
-
this.#map.set(encoding.toLowerCase(), init[encoding]);
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
this.#sort();
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
#sort() {
|
|
1009
|
-
this.#map = new Map([...this.#map].sort((a, b) => b[1] - a[1]));
|
|
1010
|
-
}
|
|
1011
|
-
/**
|
|
1012
|
-
* An array of all encodings in the header.
|
|
1013
|
-
*/
|
|
1014
|
-
get encodings() {
|
|
1015
|
-
return Array.from(this.#map.keys());
|
|
1016
|
-
}
|
|
1017
|
-
/**
|
|
1018
|
-
* An array of all weights (q values) in the header.
|
|
1019
|
-
*/
|
|
1020
|
-
get weights() {
|
|
1021
|
-
return Array.from(this.#map.values());
|
|
1022
|
-
}
|
|
1023
|
-
/**
|
|
1024
|
-
* The number of encodings in the header.
|
|
1025
|
-
*/
|
|
1026
|
-
get size() {
|
|
1027
|
-
return this.#map.size;
|
|
1028
|
-
}
|
|
1029
|
-
/**
|
|
1030
|
-
* Returns `true` if the header matches the given encoding (i.e. it is "acceptable").
|
|
1031
|
-
*
|
|
1032
|
-
* @param encoding The encoding to check
|
|
1033
|
-
* @return `true` if the encoding is acceptable, `false` otherwise
|
|
1034
|
-
*/
|
|
1035
|
-
accepts(encoding) {
|
|
1036
|
-
return encoding.toLowerCase() === "identity" || this.getWeight(encoding) > 0;
|
|
1037
|
-
}
|
|
1038
|
-
/**
|
|
1039
|
-
* Gets the weight an encoding. Performs wildcard matching so `*` matches all encodings.
|
|
1040
|
-
*
|
|
1041
|
-
* @param encoding The encoding to get
|
|
1042
|
-
* @return The weight of the encoding, or `0` if it is not in the header
|
|
1043
|
-
*/
|
|
1044
|
-
getWeight(encoding) {
|
|
1045
|
-
let lower = encoding.toLowerCase();
|
|
1046
|
-
for (let [enc, weight] of this) {
|
|
1047
|
-
if (enc === lower || enc === "*" || lower === "*") {
|
|
1048
|
-
return weight;
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
return 0;
|
|
1052
|
-
}
|
|
1053
|
-
/**
|
|
1054
|
-
* Returns the most preferred encoding from the given list of encodings.
|
|
1055
|
-
*
|
|
1056
|
-
* @param encodings The encodings to choose from
|
|
1057
|
-
* @return The most preferred encoding or `null` if none match
|
|
1058
|
-
*/
|
|
1059
|
-
getPreferred(encodings) {
|
|
1060
|
-
let sorted = encodings.map((encoding) => [encoding, this.getWeight(encoding)]).sort((a, b) => b[1] - a[1]);
|
|
1061
|
-
let first = sorted[0];
|
|
1062
|
-
return first !== void 0 && first[1] > 0 ? first[0] : null;
|
|
1063
|
-
}
|
|
1064
|
-
/**
|
|
1065
|
-
* Gets the weight of an encoding. If it is not in the header verbatim, this returns `null`.
|
|
1066
|
-
*
|
|
1067
|
-
* @param encoding The encoding to get
|
|
1068
|
-
* @return The weight of the encoding, or `null` if it is not in the header
|
|
1069
|
-
*/
|
|
1070
|
-
get(encoding) {
|
|
1071
|
-
return this.#map.get(encoding.toLowerCase()) ?? null;
|
|
1072
|
-
}
|
|
1073
|
-
/**
|
|
1074
|
-
* Sets an encoding with the given weight.
|
|
1075
|
-
*
|
|
1076
|
-
* @param encoding The encoding to set
|
|
1077
|
-
* @param weight The weight of the encoding (default: `1`)
|
|
1078
|
-
*/
|
|
1079
|
-
set(encoding, weight = 1) {
|
|
1080
|
-
this.#map.set(encoding.toLowerCase(), weight);
|
|
1081
|
-
this.#sort();
|
|
1082
|
-
}
|
|
1083
|
-
/**
|
|
1084
|
-
* Removes the given encoding from the header.
|
|
1085
|
-
*
|
|
1086
|
-
* @param encoding The encoding to remove
|
|
1087
|
-
*/
|
|
1088
|
-
delete(encoding) {
|
|
1089
|
-
this.#map.delete(encoding.toLowerCase());
|
|
1090
|
-
}
|
|
1091
|
-
/**
|
|
1092
|
-
* Checks if the header contains a given encoding.
|
|
1093
|
-
*
|
|
1094
|
-
* @param encoding The encoding to check
|
|
1095
|
-
* @return `true` if the encoding is in the header, `false` otherwise
|
|
1096
|
-
*/
|
|
1097
|
-
has(encoding) {
|
|
1098
|
-
return this.#map.has(encoding.toLowerCase());
|
|
1099
|
-
}
|
|
1100
|
-
/**
|
|
1101
|
-
* Removes all encodings from the header.
|
|
1102
|
-
*/
|
|
1103
|
-
clear() {
|
|
1104
|
-
this.#map.clear();
|
|
1105
|
-
}
|
|
1106
|
-
/**
|
|
1107
|
-
* Returns an iterator of all encoding and weight pairs.
|
|
1108
|
-
*
|
|
1109
|
-
* @return An iterator of `[encoding, weight]` tuples
|
|
1110
|
-
*/
|
|
1111
|
-
entries() {
|
|
1112
|
-
return this.#map.entries();
|
|
1113
|
-
}
|
|
1114
|
-
[Symbol.iterator]() {
|
|
1115
|
-
return this.entries();
|
|
1116
|
-
}
|
|
1117
|
-
/**
|
|
1118
|
-
* Invokes the callback for each encoding and weight pair.
|
|
1119
|
-
*
|
|
1120
|
-
* @param callback The function to call for each pair
|
|
1121
|
-
* @param thisArg The value to use as `this` when calling the callback
|
|
1122
|
-
*/
|
|
1123
|
-
forEach(callback, thisArg) {
|
|
1124
|
-
for (let [encoding, weight] of this) {
|
|
1125
|
-
callback.call(thisArg, encoding, weight, this);
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
/**
|
|
1129
|
-
* Returns the string representation of the header value.
|
|
1130
|
-
*
|
|
1131
|
-
* @return The header value as a string
|
|
1132
|
-
*/
|
|
1133
|
-
toString() {
|
|
1134
|
-
let pairs = [];
|
|
1135
|
-
for (let [encoding, weight] of this.#map) {
|
|
1136
|
-
pairs.push(`${encoding}${weight === 1 ? "" : `;q=${weight}`}`);
|
|
1137
|
-
}
|
|
1138
|
-
return pairs.join(",");
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
class AcceptLanguage {
|
|
1143
|
-
#map;
|
|
1144
|
-
/**
|
|
1145
|
-
* @param init A string, iterable, or record to initialize the header
|
|
1146
|
-
*/
|
|
1147
|
-
constructor(init) {
|
|
1148
|
-
this.#map = /* @__PURE__ */ new Map();
|
|
1149
|
-
if (init) {
|
|
1150
|
-
if (typeof init === "string") {
|
|
1151
|
-
for (let piece of init.split(/\s*,\s*/)) {
|
|
1152
|
-
let params = parseParams(piece);
|
|
1153
|
-
if (params.length < 1)
|
|
1154
|
-
continue;
|
|
1155
|
-
let language = params[0][0];
|
|
1156
|
-
let weight = 1;
|
|
1157
|
-
for (let i = 1; i < params.length; i++) {
|
|
1158
|
-
let [key, value] = params[i];
|
|
1159
|
-
if (key === "q") {
|
|
1160
|
-
weight = Number(value);
|
|
1161
|
-
break;
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
this.#map.set(language.toLowerCase(), weight);
|
|
1165
|
-
}
|
|
1166
|
-
} else if (isIterable(init)) {
|
|
1167
|
-
for (let value of init) {
|
|
1168
|
-
if (Array.isArray(value)) {
|
|
1169
|
-
this.#map.set(value[0].toLowerCase(), value[1]);
|
|
1170
|
-
} else {
|
|
1171
|
-
this.#map.set(value.toLowerCase(), 1);
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
} else {
|
|
1175
|
-
for (let language of Object.getOwnPropertyNames(init)) {
|
|
1176
|
-
this.#map.set(language.toLowerCase(), init[language]);
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
this.#sort();
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
#sort() {
|
|
1183
|
-
this.#map = new Map([...this.#map].sort((a, b) => b[1] - a[1]));
|
|
1184
|
-
}
|
|
1185
|
-
/**
|
|
1186
|
-
* An array of all languages in the header.
|
|
1187
|
-
*/
|
|
1188
|
-
get languages() {
|
|
1189
|
-
return Array.from(this.#map.keys());
|
|
1190
|
-
}
|
|
1191
|
-
/**
|
|
1192
|
-
* An array of all weights (q values) in the header.
|
|
1193
|
-
*/
|
|
1194
|
-
get weights() {
|
|
1195
|
-
return Array.from(this.#map.values());
|
|
1196
|
-
}
|
|
1197
|
-
/**
|
|
1198
|
-
* The number of languages in the header.
|
|
1199
|
-
*/
|
|
1200
|
-
get size() {
|
|
1201
|
-
return this.#map.size;
|
|
1202
|
-
}
|
|
1203
|
-
/**
|
|
1204
|
-
* Returns `true` if the header matches the given language (i.e. it is "acceptable").
|
|
1205
|
-
*
|
|
1206
|
-
* @param language The locale identifier of the language to check
|
|
1207
|
-
* @return `true` if the language is acceptable, `false` otherwise
|
|
1208
|
-
*/
|
|
1209
|
-
accepts(language) {
|
|
1210
|
-
return this.getWeight(language) > 0;
|
|
1211
|
-
}
|
|
1212
|
-
/**
|
|
1213
|
-
* Gets the weight of a language with the given locale identifier. Performs wildcard and subtype
|
|
1214
|
-
* matching, so `en` matches `en-US` and `en-GB`, and `*` matches all languages.
|
|
1215
|
-
*
|
|
1216
|
-
* @param language The locale identifier of the language to get
|
|
1217
|
-
* @return The weight of the language, or `0` if it is not in the header
|
|
1218
|
-
*/
|
|
1219
|
-
getWeight(language) {
|
|
1220
|
-
let [base, subtype] = language.toLowerCase().split("-");
|
|
1221
|
-
for (let [key, value] of this) {
|
|
1222
|
-
let [b, s] = key.split("-");
|
|
1223
|
-
if ((b === base || b === "*" || base === "*") && (s === subtype || s === void 0 || subtype === void 0)) {
|
|
1224
|
-
return value;
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
return 0;
|
|
1228
|
-
}
|
|
1229
|
-
/**
|
|
1230
|
-
* Returns the most preferred language from the given list of languages.
|
|
1231
|
-
*
|
|
1232
|
-
* @param languages The locale identifiers of the languages to choose from
|
|
1233
|
-
* @return The most preferred language or `null` if none match
|
|
1234
|
-
*/
|
|
1235
|
-
getPreferred(languages) {
|
|
1236
|
-
let sorted = languages.map((language) => [language, this.getWeight(language)]).sort((a, b) => b[1] - a[1]);
|
|
1237
|
-
let first = sorted[0];
|
|
1238
|
-
return first !== void 0 && first[1] > 0 ? first[0] : null;
|
|
1239
|
-
}
|
|
1240
|
-
/**
|
|
1241
|
-
* Gets the weight of a language with the given locale identifier. If it is not in the header
|
|
1242
|
-
* verbatim, this returns `null`.
|
|
1243
|
-
*
|
|
1244
|
-
* @param language The locale identifier of the language to get
|
|
1245
|
-
* @return The weight of the language, or `null` if it is not in the header
|
|
1246
|
-
*/
|
|
1247
|
-
get(language) {
|
|
1248
|
-
return this.#map.get(language.toLowerCase()) ?? null;
|
|
1249
|
-
}
|
|
1250
|
-
/**
|
|
1251
|
-
* Sets a language with the given weight.
|
|
1252
|
-
*
|
|
1253
|
-
* @param language The locale identifier of the language to set
|
|
1254
|
-
* @param weight The weight of the language (default: `1`)
|
|
1255
|
-
*/
|
|
1256
|
-
set(language, weight = 1) {
|
|
1257
|
-
this.#map.set(language.toLowerCase(), weight);
|
|
1258
|
-
this.#sort();
|
|
1259
|
-
}
|
|
1260
|
-
/**
|
|
1261
|
-
* Removes a language with the given locale identifier.
|
|
1262
|
-
*
|
|
1263
|
-
* @param language The locale identifier of the language to remove
|
|
1264
|
-
*/
|
|
1265
|
-
delete(language) {
|
|
1266
|
-
this.#map.delete(language.toLowerCase());
|
|
1267
|
-
}
|
|
1268
|
-
/**
|
|
1269
|
-
* Checks if the header contains a language with the given locale identifier.
|
|
1270
|
-
*
|
|
1271
|
-
* @param language The locale identifier of the language to check
|
|
1272
|
-
* @return `true` if the language is in the header, `false` otherwise
|
|
1273
|
-
*/
|
|
1274
|
-
has(language) {
|
|
1275
|
-
return this.#map.has(language.toLowerCase());
|
|
1276
|
-
}
|
|
1277
|
-
/**
|
|
1278
|
-
* Removes all languages from the header.
|
|
1279
|
-
*/
|
|
1280
|
-
clear() {
|
|
1281
|
-
this.#map.clear();
|
|
1282
|
-
}
|
|
1283
|
-
/**
|
|
1284
|
-
* Returns an iterator of all language and weight pairs.
|
|
1285
|
-
*
|
|
1286
|
-
* @return An iterator of `[language, weight]` tuples
|
|
1287
|
-
*/
|
|
1288
|
-
entries() {
|
|
1289
|
-
return this.#map.entries();
|
|
1290
|
-
}
|
|
1291
|
-
[Symbol.iterator]() {
|
|
1292
|
-
return this.entries();
|
|
1293
|
-
}
|
|
1294
|
-
/**
|
|
1295
|
-
* Invokes the callback for each language and weight pair.
|
|
1296
|
-
*
|
|
1297
|
-
* @param callback The function to call for each pair
|
|
1298
|
-
* @param thisArg The value to use as `this` when calling the callback
|
|
1299
|
-
*/
|
|
1300
|
-
forEach(callback, thisArg) {
|
|
1301
|
-
for (let [language, weight] of this) {
|
|
1302
|
-
callback.call(thisArg, language, weight, this);
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
/**
|
|
1306
|
-
* Returns the string representation of the header value.
|
|
1307
|
-
*
|
|
1308
|
-
* @return The header value as a string
|
|
1309
|
-
*/
|
|
1310
|
-
toString() {
|
|
1311
|
-
let pairs = [];
|
|
1312
|
-
for (let [language, weight] of this.#map) {
|
|
1313
|
-
pairs.push(`${language}${weight === 1 ? "" : `;q=${weight}`}`);
|
|
1314
|
-
}
|
|
1315
|
-
return pairs.join(",");
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
|
-
class CacheControl {
|
|
1320
|
-
maxAge;
|
|
1321
|
-
maxStale;
|
|
1322
|
-
minFresh;
|
|
1323
|
-
sMaxage;
|
|
1324
|
-
noCache;
|
|
1325
|
-
noStore;
|
|
1326
|
-
noTransform;
|
|
1327
|
-
onlyIfCached;
|
|
1328
|
-
mustRevalidate;
|
|
1329
|
-
proxyRevalidate;
|
|
1330
|
-
mustUnderstand;
|
|
1331
|
-
private;
|
|
1332
|
-
public;
|
|
1333
|
-
immutable;
|
|
1334
|
-
staleWhileRevalidate;
|
|
1335
|
-
staleIfError;
|
|
1336
|
-
/**
|
|
1337
|
-
* @param init A string or object to initialize the header
|
|
1338
|
-
*/
|
|
1339
|
-
constructor(init) {
|
|
1340
|
-
if (init) {
|
|
1341
|
-
if (typeof init === "string") {
|
|
1342
|
-
let params = parseParams(init, ",");
|
|
1343
|
-
if (params.length > 0) {
|
|
1344
|
-
for (let [name, value] of params) {
|
|
1345
|
-
switch (name) {
|
|
1346
|
-
case "max-age":
|
|
1347
|
-
this.maxAge = Number(value);
|
|
1348
|
-
break;
|
|
1349
|
-
case "max-stale":
|
|
1350
|
-
this.maxStale = Number(value);
|
|
1351
|
-
break;
|
|
1352
|
-
case "min-fresh":
|
|
1353
|
-
this.minFresh = Number(value);
|
|
1354
|
-
break;
|
|
1355
|
-
case "s-maxage":
|
|
1356
|
-
this.sMaxage = Number(value);
|
|
1357
|
-
break;
|
|
1358
|
-
case "no-cache":
|
|
1359
|
-
this.noCache = true;
|
|
1360
|
-
break;
|
|
1361
|
-
case "no-store":
|
|
1362
|
-
this.noStore = true;
|
|
1363
|
-
break;
|
|
1364
|
-
case "no-transform":
|
|
1365
|
-
this.noTransform = true;
|
|
1366
|
-
break;
|
|
1367
|
-
case "only-if-cached":
|
|
1368
|
-
this.onlyIfCached = true;
|
|
1369
|
-
break;
|
|
1370
|
-
case "must-revalidate":
|
|
1371
|
-
this.mustRevalidate = true;
|
|
1372
|
-
break;
|
|
1373
|
-
case "proxy-revalidate":
|
|
1374
|
-
this.proxyRevalidate = true;
|
|
1375
|
-
break;
|
|
1376
|
-
case "must-understand":
|
|
1377
|
-
this.mustUnderstand = true;
|
|
1378
|
-
break;
|
|
1379
|
-
case "private":
|
|
1380
|
-
this.private = true;
|
|
1381
|
-
break;
|
|
1382
|
-
case "public":
|
|
1383
|
-
this.public = true;
|
|
1384
|
-
break;
|
|
1385
|
-
case "immutable":
|
|
1386
|
-
this.immutable = true;
|
|
1387
|
-
break;
|
|
1388
|
-
case "stale-while-revalidate":
|
|
1389
|
-
this.staleWhileRevalidate = Number(value);
|
|
1390
|
-
break;
|
|
1391
|
-
case "stale-if-error":
|
|
1392
|
-
this.staleIfError = Number(value);
|
|
1393
|
-
break;
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
} else {
|
|
1398
|
-
this.maxAge = init.maxAge;
|
|
1399
|
-
this.maxStale = init.maxStale;
|
|
1400
|
-
this.minFresh = init.minFresh;
|
|
1401
|
-
this.sMaxage = init.sMaxage;
|
|
1402
|
-
this.noCache = init.noCache;
|
|
1403
|
-
this.noStore = init.noStore;
|
|
1404
|
-
this.noTransform = init.noTransform;
|
|
1405
|
-
this.onlyIfCached = init.onlyIfCached;
|
|
1406
|
-
this.mustRevalidate = init.mustRevalidate;
|
|
1407
|
-
this.proxyRevalidate = init.proxyRevalidate;
|
|
1408
|
-
this.mustUnderstand = init.mustUnderstand;
|
|
1409
|
-
this.private = init.private;
|
|
1410
|
-
this.public = init.public;
|
|
1411
|
-
this.immutable = init.immutable;
|
|
1412
|
-
this.staleWhileRevalidate = init.staleWhileRevalidate;
|
|
1413
|
-
this.staleIfError = init.staleIfError;
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
/**
|
|
1418
|
-
* Returns the string representation of the header value.
|
|
1419
|
-
*
|
|
1420
|
-
* @return The header value as a string
|
|
1421
|
-
*/
|
|
1422
|
-
toString() {
|
|
1423
|
-
let parts = [];
|
|
1424
|
-
if (this.public) {
|
|
1425
|
-
parts.push("public");
|
|
1426
|
-
}
|
|
1427
|
-
if (this.private) {
|
|
1428
|
-
parts.push("private");
|
|
1429
|
-
}
|
|
1430
|
-
if (typeof this.maxAge === "number") {
|
|
1431
|
-
parts.push(`max-age=${this.maxAge}`);
|
|
1432
|
-
}
|
|
1433
|
-
if (typeof this.sMaxage === "number") {
|
|
1434
|
-
parts.push(`s-maxage=${this.sMaxage}`);
|
|
1435
|
-
}
|
|
1436
|
-
if (this.noCache) {
|
|
1437
|
-
parts.push("no-cache");
|
|
1438
|
-
}
|
|
1439
|
-
if (this.noStore) {
|
|
1440
|
-
parts.push("no-store");
|
|
1441
|
-
}
|
|
1442
|
-
if (this.noTransform) {
|
|
1443
|
-
parts.push("no-transform");
|
|
1444
|
-
}
|
|
1445
|
-
if (this.onlyIfCached) {
|
|
1446
|
-
parts.push("only-if-cached");
|
|
1447
|
-
}
|
|
1448
|
-
if (this.mustRevalidate) {
|
|
1449
|
-
parts.push("must-revalidate");
|
|
1450
|
-
}
|
|
1451
|
-
if (this.proxyRevalidate) {
|
|
1452
|
-
parts.push("proxy-revalidate");
|
|
1453
|
-
}
|
|
1454
|
-
if (this.mustUnderstand) {
|
|
1455
|
-
parts.push("must-understand");
|
|
1456
|
-
}
|
|
1457
|
-
if (this.immutable) {
|
|
1458
|
-
parts.push("immutable");
|
|
1459
|
-
}
|
|
1460
|
-
if (typeof this.staleWhileRevalidate === "number") {
|
|
1461
|
-
parts.push(`stale-while-revalidate=${this.staleWhileRevalidate}`);
|
|
1462
|
-
}
|
|
1463
|
-
if (typeof this.staleIfError === "number") {
|
|
1464
|
-
parts.push(`stale-if-error=${this.staleIfError}`);
|
|
1465
|
-
}
|
|
1466
|
-
if (typeof this.maxStale === "number") {
|
|
1467
|
-
parts.push(`max-stale=${this.maxStale}`);
|
|
1468
|
-
}
|
|
1469
|
-
if (typeof this.minFresh === "number") {
|
|
1470
|
-
parts.push(`min-fresh=${this.minFresh}`);
|
|
1471
|
-
}
|
|
1472
|
-
return parts.join(", ");
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
|
|
1476
|
-
class ContentDisposition {
|
|
1477
|
-
filename;
|
|
1478
|
-
filenameSplat;
|
|
1479
|
-
name;
|
|
1480
|
-
type;
|
|
1481
|
-
/**
|
|
1482
|
-
* @param init A string or object to initialize the header
|
|
1483
|
-
*/
|
|
1484
|
-
constructor(init) {
|
|
1485
|
-
if (init) {
|
|
1486
|
-
if (typeof init === "string") {
|
|
1487
|
-
let params = parseParams(init);
|
|
1488
|
-
if (params.length > 0) {
|
|
1489
|
-
this.type = params[0][0];
|
|
1490
|
-
for (let [name, value] of params.slice(1)) {
|
|
1491
|
-
if (name === "filename") {
|
|
1492
|
-
this.filename = value;
|
|
1493
|
-
} else if (name === "filename*") {
|
|
1494
|
-
this.filenameSplat = value;
|
|
1495
|
-
} else if (name === "name") {
|
|
1496
|
-
this.name = value;
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
} else {
|
|
1501
|
-
this.filename = init.filename;
|
|
1502
|
-
this.filenameSplat = init.filenameSplat;
|
|
1503
|
-
this.name = init.name;
|
|
1504
|
-
this.type = init.type;
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
}
|
|
1508
|
-
/**
|
|
1509
|
-
* The preferred filename for the content, using the `filename*` parameter if present, falling back to the `filename` parameter.
|
|
1510
|
-
*
|
|
1511
|
-
* From [RFC 6266](https://tools.ietf.org/html/rfc6266):
|
|
1512
|
-
*
|
|
1513
|
-
* Many user agent implementations predating this specification do not understand the "filename*" parameter.
|
|
1514
|
-
* Therefore, when both "filename" and "filename*" are present in a single header field value, recipients SHOULD
|
|
1515
|
-
* pick "filename*" and ignore "filename". This way, senders can avoid special-casing specific user agents by
|
|
1516
|
-
* sending both the more expressive "filename*" parameter, and the "filename" parameter as fallback for legacy recipients.
|
|
1517
|
-
*/
|
|
1518
|
-
get preferredFilename() {
|
|
1519
|
-
let filenameSplat = this.filenameSplat;
|
|
1520
|
-
if (filenameSplat) {
|
|
1521
|
-
let decodedFilename = decodeFilenameSplat(filenameSplat);
|
|
1522
|
-
if (decodedFilename)
|
|
1523
|
-
return decodedFilename;
|
|
1524
|
-
}
|
|
1525
|
-
return this.filename;
|
|
1526
|
-
}
|
|
1527
|
-
/**
|
|
1528
|
-
* Returns the string representation of the header value.
|
|
1529
|
-
*
|
|
1530
|
-
* @return The header value as a string
|
|
1531
|
-
*/
|
|
1532
|
-
toString() {
|
|
1533
|
-
if (!this.type) {
|
|
1534
|
-
return "";
|
|
1535
|
-
}
|
|
1536
|
-
let parts = [this.type];
|
|
1537
|
-
if (this.name) {
|
|
1538
|
-
parts.push(`name=${quote(this.name)}`);
|
|
1539
|
-
}
|
|
1540
|
-
if (this.filename) {
|
|
1541
|
-
parts.push(`filename=${quote(this.filename)}`);
|
|
1542
|
-
}
|
|
1543
|
-
if (this.filenameSplat) {
|
|
1544
|
-
parts.push(`filename*=${quote(this.filenameSplat)}`);
|
|
1545
|
-
}
|
|
1546
|
-
return parts.join("; ");
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
function decodeFilenameSplat(value) {
|
|
1550
|
-
let match = value.match(/^([\w-]+)'([^']*)'(.+)$/);
|
|
1551
|
-
if (!match)
|
|
1552
|
-
return null;
|
|
1553
|
-
let [, charset, , encodedFilename] = match;
|
|
1554
|
-
let decodedFilename = percentDecode(encodedFilename);
|
|
1555
|
-
try {
|
|
1556
|
-
let decoder = new TextDecoder(charset);
|
|
1557
|
-
let bytes = new Uint8Array(decodedFilename.split("").map((char) => char.charCodeAt(0)));
|
|
1558
|
-
return decoder.decode(bytes);
|
|
1559
|
-
} catch (error) {
|
|
1560
|
-
console.warn(`Failed to decode filename from charset ${charset}:`, error);
|
|
1561
|
-
return decodedFilename;
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
function percentDecode(value) {
|
|
1565
|
-
return value.replace(/\+/g, " ").replace(/%([0-9A-Fa-f]{2})/g, (_, hex) => {
|
|
1566
|
-
return String.fromCharCode(parseInt(hex, 16));
|
|
1567
|
-
});
|
|
1568
|
-
}
|
|
1569
|
-
|
|
1570
|
-
class ContentRange {
|
|
1571
|
-
unit = "";
|
|
1572
|
-
start = null;
|
|
1573
|
-
end = null;
|
|
1574
|
-
size;
|
|
1575
|
-
/**
|
|
1576
|
-
* @param init A string or object to initialize the header
|
|
1577
|
-
*/
|
|
1578
|
-
constructor(init) {
|
|
1579
|
-
if (init) {
|
|
1580
|
-
if (typeof init === "string") {
|
|
1581
|
-
let match = init.match(/^(\w+)\s+(?:(\d+)-(\d+)|\*)\/((?:\d+|\*))$/);
|
|
1582
|
-
if (match) {
|
|
1583
|
-
this.unit = match[1];
|
|
1584
|
-
this.start = match[2] ? parseInt(match[2], 10) : null;
|
|
1585
|
-
this.end = match[3] ? parseInt(match[3], 10) : null;
|
|
1586
|
-
this.size = match[4] === "*" ? "*" : parseInt(match[4], 10);
|
|
1587
|
-
}
|
|
1588
|
-
} else {
|
|
1589
|
-
if (init.unit !== void 0)
|
|
1590
|
-
this.unit = init.unit;
|
|
1591
|
-
if (init.start !== void 0)
|
|
1592
|
-
this.start = init.start;
|
|
1593
|
-
if (init.end !== void 0)
|
|
1594
|
-
this.end = init.end;
|
|
1595
|
-
if (init.size !== void 0)
|
|
1596
|
-
this.size = init.size;
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
|
-
/**
|
|
1601
|
-
* Returns the string representation of the header value.
|
|
1602
|
-
*
|
|
1603
|
-
* @return The header value as a string
|
|
1604
|
-
*/
|
|
1605
|
-
toString() {
|
|
1606
|
-
if (!this.unit || this.size === void 0)
|
|
1607
|
-
return "";
|
|
1608
|
-
let range = this.start !== null && this.end !== null ? `${this.start}-${this.end}` : "*";
|
|
1609
|
-
return `${this.unit} ${range}/${this.size}`;
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
|
|
1613
|
-
class ContentType {
|
|
1614
|
-
boundary;
|
|
1615
|
-
charset;
|
|
1616
|
-
mediaType;
|
|
1617
|
-
/**
|
|
1618
|
-
* @param init A string or object to initialize the header
|
|
1619
|
-
*/
|
|
1620
|
-
constructor(init) {
|
|
1621
|
-
if (init) {
|
|
1622
|
-
if (typeof init === "string") {
|
|
1623
|
-
let params = parseParams(init);
|
|
1624
|
-
if (params.length > 0) {
|
|
1625
|
-
this.mediaType = params[0][0];
|
|
1626
|
-
for (let [name, value] of params.slice(1)) {
|
|
1627
|
-
if (name === "boundary") {
|
|
1628
|
-
this.boundary = value;
|
|
1629
|
-
} else if (name === "charset") {
|
|
1630
|
-
this.charset = value;
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
} else {
|
|
1635
|
-
this.boundary = init.boundary;
|
|
1636
|
-
this.charset = init.charset;
|
|
1637
|
-
this.mediaType = init.mediaType;
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
/**
|
|
1642
|
-
* Returns the string representation of the header value.
|
|
1643
|
-
*
|
|
1644
|
-
* @return The header value as a string
|
|
1645
|
-
*/
|
|
1646
|
-
toString() {
|
|
1647
|
-
if (!this.mediaType) {
|
|
1648
|
-
return "";
|
|
1649
|
-
}
|
|
1650
|
-
let parts = [this.mediaType];
|
|
1651
|
-
if (this.charset) {
|
|
1652
|
-
parts.push(`charset=${quote(this.charset)}`);
|
|
1653
|
-
}
|
|
1654
|
-
if (this.boundary) {
|
|
1655
|
-
parts.push(`boundary=${quote(this.boundary)}`);
|
|
1656
|
-
}
|
|
1657
|
-
return parts.join("; ");
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
|
|
1661
|
-
class Cookie {
|
|
1662
|
-
#map;
|
|
1663
|
-
/**
|
|
1664
|
-
* @param init A string, iterable, or record to initialize the header
|
|
1665
|
-
*/
|
|
1666
|
-
constructor(init) {
|
|
1667
|
-
this.#map = /* @__PURE__ */ new Map();
|
|
1668
|
-
if (init) {
|
|
1669
|
-
if (typeof init === "string") {
|
|
1670
|
-
let params = parseParams(init);
|
|
1671
|
-
for (let [name, value] of params) {
|
|
1672
|
-
this.#map.set(name, value ?? "");
|
|
1673
|
-
}
|
|
1674
|
-
} else if (isIterable(init)) {
|
|
1675
|
-
for (let [name, value] of init) {
|
|
1676
|
-
this.#map.set(name, value);
|
|
1677
|
-
}
|
|
1678
|
-
} else {
|
|
1679
|
-
for (let name of Object.getOwnPropertyNames(init)) {
|
|
1680
|
-
this.#map.set(name, init[name]);
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1685
|
-
/**
|
|
1686
|
-
* An array of the names of the cookies in the header.
|
|
1687
|
-
*/
|
|
1688
|
-
get names() {
|
|
1689
|
-
return Array.from(this.#map.keys());
|
|
1690
|
-
}
|
|
1691
|
-
/**
|
|
1692
|
-
* An array of the values of the cookies in the header.
|
|
1693
|
-
*/
|
|
1694
|
-
get values() {
|
|
1695
|
-
return Array.from(this.#map.values());
|
|
1696
|
-
}
|
|
1697
|
-
/**
|
|
1698
|
-
* The number of cookies in the header.
|
|
1699
|
-
*/
|
|
1700
|
-
get size() {
|
|
1701
|
-
return this.#map.size;
|
|
1702
|
-
}
|
|
1703
|
-
/**
|
|
1704
|
-
* Gets the value of a cookie with the given name from the header.
|
|
1705
|
-
*
|
|
1706
|
-
* @param name The name of the cookie
|
|
1707
|
-
* @return The value of the cookie, or `null` if the cookie does not exist
|
|
1708
|
-
*/
|
|
1709
|
-
get(name) {
|
|
1710
|
-
return this.#map.get(name) ?? null;
|
|
1711
|
-
}
|
|
1712
|
-
/**
|
|
1713
|
-
* Sets a cookie with the given name and value in the header.
|
|
1714
|
-
*
|
|
1715
|
-
* @param name The name of the cookie
|
|
1716
|
-
* @param value The value of the cookie
|
|
1717
|
-
*/
|
|
1718
|
-
set(name, value) {
|
|
1719
|
-
this.#map.set(name, value);
|
|
1720
|
-
}
|
|
1721
|
-
/**
|
|
1722
|
-
* Removes a cookie with the given name from the header.
|
|
1723
|
-
*
|
|
1724
|
-
* @param name The name of the cookie
|
|
1725
|
-
*/
|
|
1726
|
-
delete(name) {
|
|
1727
|
-
this.#map.delete(name);
|
|
1728
|
-
}
|
|
1729
|
-
/**
|
|
1730
|
-
* True if a cookie with the given name exists in the header.
|
|
1731
|
-
*
|
|
1732
|
-
* @param name The name of the cookie
|
|
1733
|
-
* @return `true` if a cookie with the given name exists in the header
|
|
1734
|
-
*/
|
|
1735
|
-
has(name) {
|
|
1736
|
-
return this.#map.has(name);
|
|
1737
|
-
}
|
|
1738
|
-
/**
|
|
1739
|
-
* Removes all cookies from the header.
|
|
1740
|
-
*/
|
|
1741
|
-
clear() {
|
|
1742
|
-
this.#map.clear();
|
|
1743
|
-
}
|
|
1744
|
-
/**
|
|
1745
|
-
* Returns an iterator of all cookie name and value pairs.
|
|
1746
|
-
*
|
|
1747
|
-
* @return An iterator of `[name, value]` tuples
|
|
1748
|
-
*/
|
|
1749
|
-
entries() {
|
|
1750
|
-
return this.#map.entries();
|
|
1751
|
-
}
|
|
1752
|
-
[Symbol.iterator]() {
|
|
1753
|
-
return this.entries();
|
|
1754
|
-
}
|
|
1755
|
-
/**
|
|
1756
|
-
* Invokes the callback for each cookie name and value pair.
|
|
1757
|
-
*
|
|
1758
|
-
* @param callback The function to call for each pair
|
|
1759
|
-
* @param thisArg The value to use as `this` when calling the callback
|
|
1760
|
-
*/
|
|
1761
|
-
forEach(callback, thisArg) {
|
|
1762
|
-
for (let [name, value] of this) {
|
|
1763
|
-
callback.call(thisArg, name, value, this);
|
|
1764
|
-
}
|
|
1765
|
-
}
|
|
1766
|
-
/**
|
|
1767
|
-
* Returns the string representation of the header value.
|
|
1768
|
-
*
|
|
1769
|
-
* @return The header value as a string
|
|
1770
|
-
*/
|
|
1771
|
-
toString() {
|
|
1772
|
-
let pairs = [];
|
|
1773
|
-
for (let [name, value] of this.#map) {
|
|
1774
|
-
pairs.push(`${name}=${quote(value)}`);
|
|
1775
|
-
}
|
|
1776
|
-
return pairs.join("; ");
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
class IfMatch {
|
|
1781
|
-
tags = [];
|
|
1782
|
-
/**
|
|
1783
|
-
* @param init A string, array of strings, or object to initialize the header
|
|
1784
|
-
*/
|
|
1785
|
-
constructor(init) {
|
|
1786
|
-
if (init) {
|
|
1787
|
-
if (typeof init === "string") {
|
|
1788
|
-
this.tags.push(...init.split(/\s*,\s*/).map(quoteEtag));
|
|
1789
|
-
} else if (Array.isArray(init)) {
|
|
1790
|
-
this.tags.push(...init.map(quoteEtag));
|
|
1791
|
-
} else {
|
|
1792
|
-
this.tags.push(...init.tags.map(quoteEtag));
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
/**
|
|
1797
|
-
* Checks if the header contains the given entity tag.
|
|
1798
|
-
*
|
|
1799
|
-
* Note: This method checks only for exact matches and does not consider wildcards.
|
|
1800
|
-
*
|
|
1801
|
-
* @param tag The entity tag to check for
|
|
1802
|
-
* @return `true` if the tag is present in the header, `false` otherwise
|
|
1803
|
-
*/
|
|
1804
|
-
has(tag) {
|
|
1805
|
-
return this.tags.includes(quoteEtag(tag));
|
|
1806
|
-
}
|
|
1807
|
-
/**
|
|
1808
|
-
* Checks if the precondition passes for the given entity tag.
|
|
1809
|
-
*
|
|
1810
|
-
* This method always returns `true` if the `If-Match` header is not present
|
|
1811
|
-
* since the precondition passes regardless of the entity tag being checked.
|
|
1812
|
-
*
|
|
1813
|
-
* Uses strong comparison as per RFC 9110, meaning weak entity tags (prefixed with `W/`)
|
|
1814
|
-
* will never match.
|
|
1815
|
-
*
|
|
1816
|
-
* @param tag The entity tag to check against
|
|
1817
|
-
* @return `true` if the precondition passes, `false` if it fails (should return 412)
|
|
1818
|
-
*/
|
|
1819
|
-
matches(tag) {
|
|
1820
|
-
if (this.tags.length === 0) {
|
|
1821
|
-
return true;
|
|
1822
|
-
}
|
|
1823
|
-
if (this.tags.includes("*")) {
|
|
1824
|
-
return true;
|
|
1825
|
-
}
|
|
1826
|
-
let normalizedTag = quoteEtag(tag);
|
|
1827
|
-
if (normalizedTag.startsWith("W/")) {
|
|
1828
|
-
return false;
|
|
1829
|
-
}
|
|
1830
|
-
for (let headerTag of this.tags) {
|
|
1831
|
-
if (!headerTag.startsWith("W/") && headerTag === normalizedTag) {
|
|
1832
|
-
return true;
|
|
1833
|
-
}
|
|
1834
|
-
}
|
|
1835
|
-
return false;
|
|
1836
|
-
}
|
|
1837
|
-
/**
|
|
1838
|
-
* Returns the string representation of the header value.
|
|
1839
|
-
*
|
|
1840
|
-
* @return The header value as a string
|
|
1841
|
-
*/
|
|
1842
|
-
toString() {
|
|
1843
|
-
return this.tags.join(", ");
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
|
|
1847
|
-
class IfNoneMatch {
|
|
1848
|
-
tags = [];
|
|
1849
|
-
/**
|
|
1850
|
-
* @param init A string, array of strings, or object to initialize the header
|
|
1851
|
-
*/
|
|
1852
|
-
constructor(init) {
|
|
1853
|
-
if (init) {
|
|
1854
|
-
if (typeof init === "string") {
|
|
1855
|
-
this.tags.push(...init.split(/\s*,\s*/).map(quoteEtag));
|
|
1856
|
-
} else if (Array.isArray(init)) {
|
|
1857
|
-
this.tags.push(...init.map(quoteEtag));
|
|
1858
|
-
} else {
|
|
1859
|
-
this.tags.push(...init.tags.map(quoteEtag));
|
|
1860
|
-
}
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
/**
|
|
1864
|
-
* Checks if the header contains the given entity tag.
|
|
1865
|
-
*
|
|
1866
|
-
* Note: This method checks only for exact matches and does not consider wildcards.
|
|
1867
|
-
*
|
|
1868
|
-
* @param tag The entity tag to check for
|
|
1869
|
-
* @return `true` if the tag is present in the header, `false` otherwise
|
|
1870
|
-
*/
|
|
1871
|
-
has(tag) {
|
|
1872
|
-
return this.tags.includes(quoteEtag(tag));
|
|
1873
|
-
}
|
|
1874
|
-
/**
|
|
1875
|
-
* Checks if this header matches the given entity tag.
|
|
1876
|
-
*
|
|
1877
|
-
* @param tag The entity tag to check for
|
|
1878
|
-
* @return `true` if the tag is present in the header (or the header contains a wildcard), `false` otherwise
|
|
1879
|
-
*/
|
|
1880
|
-
matches(tag) {
|
|
1881
|
-
return this.has(tag) || this.tags.includes("*");
|
|
1882
|
-
}
|
|
1883
|
-
/**
|
|
1884
|
-
* Returns the string representation of the header value.
|
|
1885
|
-
*
|
|
1886
|
-
* @return The header value as a string
|
|
1887
|
-
*/
|
|
1888
|
-
toString() {
|
|
1889
|
-
return this.tags.join(", ");
|
|
1890
|
-
}
|
|
1891
|
-
}
|
|
1892
|
-
|
|
1893
|
-
class IfRange {
|
|
1894
|
-
value = "";
|
|
1895
|
-
/**
|
|
1896
|
-
* @param init A string or Date to initialize the header
|
|
1897
|
-
*/
|
|
1898
|
-
constructor(init) {
|
|
1899
|
-
if (init) {
|
|
1900
|
-
if (typeof init === "string") {
|
|
1901
|
-
this.value = init;
|
|
1902
|
-
} else {
|
|
1903
|
-
this.value = init.toUTCString();
|
|
1904
|
-
}
|
|
1905
|
-
}
|
|
1906
|
-
}
|
|
1907
|
-
/**
|
|
1908
|
-
* Checks if the `If-Range` condition is satisfied for the current resource state.
|
|
1909
|
-
*
|
|
1910
|
-
* This method always returns `true` if the `If-Range` header is not present,
|
|
1911
|
-
* meaning the range request should proceed unconditionally.
|
|
1912
|
-
*
|
|
1913
|
-
* The `If-Range` header can contain either:
|
|
1914
|
-
* - An HTTP date (RFC 7231 IMF-fixdate format)
|
|
1915
|
-
* - An entity tag (ETag)
|
|
1916
|
-
*
|
|
1917
|
-
* When comparing ETags, only strong entity tags are matched as per RFC 7233.
|
|
1918
|
-
* Weak entity tags (prefixed with `W/`) are never considered a match.
|
|
1919
|
-
*
|
|
1920
|
-
* @param resource The current resource state to compare against
|
|
1921
|
-
* @return `true` if the condition is satisfied, `false` otherwise
|
|
1922
|
-
*
|
|
1923
|
-
* @example
|
|
1924
|
-
* ```ts
|
|
1925
|
-
* let ifRange = new IfRange('Wed, 21 Oct 2015 07:28:00 GMT')
|
|
1926
|
-
* ifRange.matches({ lastModified: 1445412480000 }) // true if dates match
|
|
1927
|
-
* ifRange.matches({ lastModified: new Date('2015-10-21T07:28:00Z') }) // true
|
|
1928
|
-
*
|
|
1929
|
-
* let ifRange2 = new IfRange('"abc123"')
|
|
1930
|
-
* ifRange2.matches({ etag: '"abc123"' }) // true
|
|
1931
|
-
* ifRange2.matches({ etag: 'W/"abc123"' }) // false (weak ETag)
|
|
1932
|
-
* ```
|
|
1933
|
-
*/
|
|
1934
|
-
matches(resource) {
|
|
1935
|
-
if (!this.value) {
|
|
1936
|
-
return true;
|
|
1937
|
-
}
|
|
1938
|
-
let dateTimestamp = parseHttpDate(this.value);
|
|
1939
|
-
if (dateTimestamp !== null && resource.lastModified != null) {
|
|
1940
|
-
return removeMilliseconds(dateTimestamp) === removeMilliseconds(resource.lastModified);
|
|
1941
|
-
}
|
|
1942
|
-
if (resource.etag != null) {
|
|
1943
|
-
let normalizedTag = quoteEtag(this.value);
|
|
1944
|
-
let normalizedResourceTag = quoteEtag(resource.etag);
|
|
1945
|
-
if (normalizedTag.startsWith("W/") || normalizedResourceTag.startsWith("W/")) {
|
|
1946
|
-
return false;
|
|
1947
|
-
}
|
|
1948
|
-
return normalizedTag === normalizedResourceTag;
|
|
1949
|
-
}
|
|
1950
|
-
return false;
|
|
1951
|
-
}
|
|
1952
|
-
/**
|
|
1953
|
-
* Returns the string representation of the header value.
|
|
1954
|
-
*
|
|
1955
|
-
* @return The header value as a string
|
|
1956
|
-
*/
|
|
1957
|
-
toString() {
|
|
1958
|
-
return this.value;
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
|
-
|
|
1962
|
-
class Range {
|
|
1963
|
-
unit = "";
|
|
1964
|
-
ranges = [];
|
|
1965
|
-
/**
|
|
1966
|
-
* @param init A string or object to initialize the header
|
|
1967
|
-
*/
|
|
1968
|
-
constructor(init) {
|
|
1969
|
-
if (init) {
|
|
1970
|
-
if (typeof init === "string") {
|
|
1971
|
-
let match = init.match(/^(\w+)=(.+)$/);
|
|
1972
|
-
if (match) {
|
|
1973
|
-
this.unit = match[1];
|
|
1974
|
-
let rangeParts = match[2].split(",");
|
|
1975
|
-
let hasInvalidPart = false;
|
|
1976
|
-
for (let part of rangeParts) {
|
|
1977
|
-
let rangeMatch = part.trim().match(/^(\d*)-(\d*)$/);
|
|
1978
|
-
if (!rangeMatch) {
|
|
1979
|
-
hasInvalidPart = true;
|
|
1980
|
-
continue;
|
|
1981
|
-
}
|
|
1982
|
-
let [, startStr, endStr] = rangeMatch;
|
|
1983
|
-
if (!startStr && !endStr) {
|
|
1984
|
-
hasInvalidPart = true;
|
|
1985
|
-
continue;
|
|
1986
|
-
}
|
|
1987
|
-
let start = startStr ? parseInt(startStr, 10) : void 0;
|
|
1988
|
-
let end = endStr ? parseInt(endStr, 10) : void 0;
|
|
1989
|
-
if (start !== void 0 && end !== void 0 && start > end) {
|
|
1990
|
-
hasInvalidPart = true;
|
|
1991
|
-
continue;
|
|
1992
|
-
}
|
|
1993
|
-
this.ranges.push({ start, end });
|
|
1994
|
-
}
|
|
1995
|
-
if (hasInvalidPart) {
|
|
1996
|
-
this.ranges = [];
|
|
1997
|
-
}
|
|
1998
|
-
}
|
|
1999
|
-
} else {
|
|
2000
|
-
if (init.unit !== void 0)
|
|
2001
|
-
this.unit = init.unit;
|
|
2002
|
-
if (init.ranges !== void 0)
|
|
2003
|
-
this.ranges = init.ranges;
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
/**
|
|
2008
|
-
* Checks if this range can be satisfied for a resource of the given size.
|
|
2009
|
-
*
|
|
2010
|
-
* @param resourceSize The size of the resource in bytes
|
|
2011
|
-
* @return `false` if the range is malformed or all ranges are beyond the resource size
|
|
2012
|
-
*/
|
|
2013
|
-
canSatisfy(resourceSize) {
|
|
2014
|
-
if (!this.unit || this.ranges.length === 0)
|
|
2015
|
-
return false;
|
|
2016
|
-
for (let range of this.ranges) {
|
|
2017
|
-
if (range.start === void 0 && range.end === void 0) {
|
|
2018
|
-
return false;
|
|
2019
|
-
}
|
|
2020
|
-
if (range.start !== void 0 && range.end !== void 0 && range.start > range.end) {
|
|
2021
|
-
return false;
|
|
2022
|
-
}
|
|
2023
|
-
}
|
|
2024
|
-
for (let range of this.ranges) {
|
|
2025
|
-
if (range.start === void 0) {
|
|
2026
|
-
return true;
|
|
2027
|
-
}
|
|
2028
|
-
if (range.start < resourceSize) {
|
|
2029
|
-
return true;
|
|
2030
|
-
}
|
|
2031
|
-
}
|
|
2032
|
-
return false;
|
|
2033
|
-
}
|
|
2034
|
-
/**
|
|
2035
|
-
* Normalizes the ranges for a resource of the given size.
|
|
2036
|
-
* Returns an array of ranges with resolved start and end values.
|
|
2037
|
-
* Returns an empty array if the range cannot be satisfied.
|
|
2038
|
-
*
|
|
2039
|
-
* @param resourceSize The size of the resource in bytes
|
|
2040
|
-
* @return An array of ranges with resolved start and end values
|
|
2041
|
-
*/
|
|
2042
|
-
normalize(resourceSize) {
|
|
2043
|
-
if (!this.canSatisfy(resourceSize)) {
|
|
2044
|
-
return [];
|
|
2045
|
-
}
|
|
2046
|
-
return this.ranges.map((range) => {
|
|
2047
|
-
if (range.start !== void 0 && range.end !== void 0) {
|
|
2048
|
-
return {
|
|
2049
|
-
start: range.start,
|
|
2050
|
-
end: Math.min(range.end, resourceSize - 1)
|
|
2051
|
-
};
|
|
2052
|
-
} else if (range.start !== void 0) {
|
|
2053
|
-
return {
|
|
2054
|
-
start: range.start,
|
|
2055
|
-
end: resourceSize - 1
|
|
2056
|
-
};
|
|
2057
|
-
} else {
|
|
2058
|
-
let suffix = range.end;
|
|
2059
|
-
return {
|
|
2060
|
-
start: Math.max(0, resourceSize - suffix),
|
|
2061
|
-
end: resourceSize - 1
|
|
2062
|
-
};
|
|
2063
|
-
}
|
|
2064
|
-
});
|
|
2065
|
-
}
|
|
2066
|
-
/**
|
|
2067
|
-
* Returns the string representation of the header value.
|
|
2068
|
-
*
|
|
2069
|
-
* @return The header value as a string
|
|
2070
|
-
*/
|
|
2071
|
-
toString() {
|
|
2072
|
-
if (!this.unit || this.ranges.length === 0)
|
|
2073
|
-
return "";
|
|
2074
|
-
let rangeParts = this.ranges.map((range) => {
|
|
2075
|
-
if (range.start !== void 0 && range.end !== void 0) {
|
|
2076
|
-
return `${range.start}-${range.end}`;
|
|
2077
|
-
} else if (range.start !== void 0) {
|
|
2078
|
-
return `${range.start}-`;
|
|
2079
|
-
} else if (range.end !== void 0) {
|
|
2080
|
-
return `-${range.end}`;
|
|
2081
|
-
}
|
|
2082
|
-
return "";
|
|
2083
|
-
});
|
|
2084
|
-
return `${this.unit}=${rangeParts.join(",")}`;
|
|
2085
|
-
}
|
|
2086
|
-
}
|
|
2087
|
-
|
|
2088
|
-
class SetCookie {
|
|
2089
|
-
domain;
|
|
2090
|
-
expires;
|
|
2091
|
-
httpOnly;
|
|
2092
|
-
maxAge;
|
|
2093
|
-
name;
|
|
2094
|
-
partitioned;
|
|
2095
|
-
path;
|
|
2096
|
-
sameSite;
|
|
2097
|
-
secure;
|
|
2098
|
-
value;
|
|
2099
|
-
/**
|
|
2100
|
-
* @param init A string or object to initialize the header
|
|
2101
|
-
*/
|
|
2102
|
-
constructor(init) {
|
|
2103
|
-
if (init) {
|
|
2104
|
-
if (typeof init === "string") {
|
|
2105
|
-
let params = parseParams(init);
|
|
2106
|
-
if (params.length > 0) {
|
|
2107
|
-
this.name = params[0][0];
|
|
2108
|
-
this.value = params[0][1];
|
|
2109
|
-
for (let [key, value] of params.slice(1)) {
|
|
2110
|
-
switch (key.toLowerCase()) {
|
|
2111
|
-
case "domain":
|
|
2112
|
-
this.domain = value;
|
|
2113
|
-
break;
|
|
2114
|
-
case "expires": {
|
|
2115
|
-
if (typeof value === "string") {
|
|
2116
|
-
let date = new Date(value);
|
|
2117
|
-
if (isValidDate(date)) {
|
|
2118
|
-
this.expires = date;
|
|
2119
|
-
}
|
|
2120
|
-
}
|
|
2121
|
-
break;
|
|
2122
|
-
}
|
|
2123
|
-
case "httponly":
|
|
2124
|
-
this.httpOnly = true;
|
|
2125
|
-
break;
|
|
2126
|
-
case "max-age": {
|
|
2127
|
-
if (typeof value === "string") {
|
|
2128
|
-
let v = parseInt(value, 10);
|
|
2129
|
-
if (!isNaN(v))
|
|
2130
|
-
this.maxAge = v;
|
|
2131
|
-
}
|
|
2132
|
-
break;
|
|
2133
|
-
}
|
|
2134
|
-
case "partitioned":
|
|
2135
|
-
this.partitioned = true;
|
|
2136
|
-
break;
|
|
2137
|
-
case "path":
|
|
2138
|
-
this.path = value;
|
|
2139
|
-
break;
|
|
2140
|
-
case "samesite":
|
|
2141
|
-
if (typeof value === "string" && /strict|lax|none/i.test(value)) {
|
|
2142
|
-
this.sameSite = capitalize(value);
|
|
2143
|
-
}
|
|
2144
|
-
break;
|
|
2145
|
-
case "secure":
|
|
2146
|
-
this.secure = true;
|
|
2147
|
-
break;
|
|
2148
|
-
}
|
|
2149
|
-
}
|
|
2150
|
-
}
|
|
2151
|
-
} else {
|
|
2152
|
-
this.domain = init.domain;
|
|
2153
|
-
this.expires = init.expires;
|
|
2154
|
-
this.httpOnly = init.httpOnly;
|
|
2155
|
-
this.maxAge = init.maxAge;
|
|
2156
|
-
this.name = init.name;
|
|
2157
|
-
this.partitioned = init.partitioned;
|
|
2158
|
-
this.path = init.path;
|
|
2159
|
-
this.sameSite = init.sameSite;
|
|
2160
|
-
this.secure = init.secure;
|
|
2161
|
-
this.value = init.value;
|
|
2162
|
-
}
|
|
2163
|
-
}
|
|
2164
|
-
}
|
|
2165
|
-
/**
|
|
2166
|
-
* Returns the string representation of the header value.
|
|
2167
|
-
*
|
|
2168
|
-
* @return The header value as a string
|
|
2169
|
-
*/
|
|
2170
|
-
toString() {
|
|
2171
|
-
if (!this.name) {
|
|
2172
|
-
return "";
|
|
2173
|
-
}
|
|
2174
|
-
let parts = [`${this.name}=${quote(this.value || "")}`];
|
|
2175
|
-
if (this.domain) {
|
|
2176
|
-
parts.push(`Domain=${this.domain}`);
|
|
2177
|
-
}
|
|
2178
|
-
if (this.expires) {
|
|
2179
|
-
parts.push(`Expires=${this.expires.toUTCString()}`);
|
|
2180
|
-
}
|
|
2181
|
-
if (this.httpOnly) {
|
|
2182
|
-
parts.push("HttpOnly");
|
|
2183
|
-
}
|
|
2184
|
-
if (this.maxAge != null) {
|
|
2185
|
-
parts.push(`Max-Age=${this.maxAge}`);
|
|
2186
|
-
}
|
|
2187
|
-
if (this.partitioned) {
|
|
2188
|
-
parts.push("Partitioned");
|
|
2189
|
-
}
|
|
2190
|
-
if (this.path) {
|
|
2191
|
-
parts.push(`Path=${this.path}`);
|
|
2192
|
-
}
|
|
2193
|
-
if (this.sameSite) {
|
|
2194
|
-
parts.push(`SameSite=${this.sameSite}`);
|
|
2195
|
-
}
|
|
2196
|
-
if (this.secure) {
|
|
2197
|
-
parts.push("Secure");
|
|
2198
|
-
}
|
|
2199
|
-
return parts.join("; ");
|
|
2200
|
-
}
|
|
2201
|
-
}
|
|
2202
|
-
|
|
2203
|
-
class Vary {
|
|
2204
|
-
#set;
|
|
2205
|
-
constructor(init) {
|
|
2206
|
-
this.#set = /* @__PURE__ */ new Set();
|
|
2207
|
-
if (init) {
|
|
2208
|
-
if (typeof init === "string") {
|
|
2209
|
-
for (let headerName of init.split(",")) {
|
|
2210
|
-
let trimmed = headerName.trim();
|
|
2211
|
-
if (trimmed) {
|
|
2212
|
-
this.#set.add(trimmed.toLowerCase());
|
|
2213
|
-
}
|
|
2214
|
-
}
|
|
2215
|
-
} else if (Array.isArray(init)) {
|
|
2216
|
-
for (let headerName of init) {
|
|
2217
|
-
let trimmed = headerName.trim();
|
|
2218
|
-
if (trimmed) {
|
|
2219
|
-
this.#set.add(trimmed.toLowerCase());
|
|
2220
|
-
}
|
|
2221
|
-
}
|
|
2222
|
-
} else {
|
|
2223
|
-
for (let headerName of init.headerNames) {
|
|
2224
|
-
let trimmed = headerName.trim();
|
|
2225
|
-
if (trimmed) {
|
|
2226
|
-
this.#set.add(trimmed.toLowerCase());
|
|
2227
|
-
}
|
|
2228
|
-
}
|
|
2229
|
-
}
|
|
2230
|
-
}
|
|
2231
|
-
}
|
|
2232
|
-
/**
|
|
2233
|
-
* An array of the header names (normalized to lowercase).
|
|
2234
|
-
*/
|
|
2235
|
-
get headerNames() {
|
|
2236
|
-
return Array.from(this.#set);
|
|
2237
|
-
}
|
|
2238
|
-
/**
|
|
2239
|
-
* The number of header names in the Vary header.
|
|
2240
|
-
*/
|
|
2241
|
-
get size() {
|
|
2242
|
-
return this.#set.size;
|
|
2243
|
-
}
|
|
2244
|
-
/**
|
|
2245
|
-
* Checks if the Vary header includes the given header name (case-insensitive).
|
|
2246
|
-
* @param headerName The header name to check for.
|
|
2247
|
-
* @returns `true` if the header name is present, `false` otherwise.
|
|
2248
|
-
*/
|
|
2249
|
-
has(headerName) {
|
|
2250
|
-
return this.#set.has(headerName.toLowerCase());
|
|
2251
|
-
}
|
|
2252
|
-
/**
|
|
2253
|
-
* Adds a header name to the Vary header (case-insensitive).
|
|
2254
|
-
* If the header name already exists, this is a no-op.
|
|
2255
|
-
* @param headerName The header name to add.
|
|
2256
|
-
*/
|
|
2257
|
-
add(headerName) {
|
|
2258
|
-
let trimmed = headerName.trim();
|
|
2259
|
-
if (trimmed) {
|
|
2260
|
-
this.#set.add(trimmed.toLowerCase());
|
|
2261
|
-
}
|
|
2262
|
-
}
|
|
2263
|
-
/**
|
|
2264
|
-
* Removes a header name from the Vary header (case-insensitive).
|
|
2265
|
-
* @param headerName The header name to remove.
|
|
2266
|
-
*/
|
|
2267
|
-
delete(headerName) {
|
|
2268
|
-
this.#set.delete(headerName.toLowerCase());
|
|
2269
|
-
}
|
|
2270
|
-
/**
|
|
2271
|
-
* Removes all header names from the Vary header.
|
|
2272
|
-
*/
|
|
2273
|
-
clear() {
|
|
2274
|
-
this.#set.clear();
|
|
2275
|
-
}
|
|
2276
|
-
/**
|
|
2277
|
-
* Calls a callback function for each header name in the Vary header.
|
|
2278
|
-
* @param callback The callback function to call for each header name.
|
|
2279
|
-
* @param thisArg Optional value to use as `this` when executing the callback.
|
|
2280
|
-
*/
|
|
2281
|
-
forEach(callback, thisArg) {
|
|
2282
|
-
for (let headerName of this) {
|
|
2283
|
-
callback.call(thisArg, headerName, this);
|
|
2284
|
-
}
|
|
2285
|
-
}
|
|
2286
|
-
[Symbol.iterator]() {
|
|
2287
|
-
return this.#set.values();
|
|
2288
|
-
}
|
|
2289
|
-
toString() {
|
|
2290
|
-
return Array.from(this.#set).join(", ");
|
|
2291
|
-
}
|
|
2292
|
-
}
|
|
2293
|
-
|
|
2294
|
-
const HeaderWordCasingExceptions = {
|
|
2295
|
-
ct: "CT",
|
|
2296
|
-
etag: "ETag",
|
|
2297
|
-
te: "TE",
|
|
2298
|
-
www: "WWW",
|
|
2299
|
-
x: "X",
|
|
2300
|
-
xss: "XSS"
|
|
2301
|
-
};
|
|
2302
|
-
function canonicalHeaderName(name) {
|
|
2303
|
-
return name.toLowerCase().split("-").map((word) => HeaderWordCasingExceptions[word] || word.charAt(0).toUpperCase() + word.slice(1)).join("-");
|
|
2304
|
-
}
|
|
2305
|
-
|
|
2306
|
-
const CRLF = "\r\n";
|
|
2307
|
-
const AcceptKey = "accept";
|
|
2308
|
-
const AcceptEncodingKey = "accept-encoding";
|
|
2309
|
-
const AcceptLanguageKey = "accept-language";
|
|
2310
|
-
const AcceptRangesKey = "accept-ranges";
|
|
2311
|
-
const AgeKey = "age";
|
|
2312
|
-
const AllowKey = "allow";
|
|
2313
|
-
const CacheControlKey = "cache-control";
|
|
2314
|
-
const ConnectionKey = "connection";
|
|
2315
|
-
const ContentDispositionKey = "content-disposition";
|
|
2316
|
-
const ContentEncodingKey = "content-encoding";
|
|
2317
|
-
const ContentLanguageKey = "content-language";
|
|
2318
|
-
const ContentLengthKey = "content-length";
|
|
2319
|
-
const ContentRangeKey = "content-range";
|
|
2320
|
-
const ContentTypeKey = "content-type";
|
|
2321
|
-
const CookieKey = "cookie";
|
|
2322
|
-
const DateKey = "date";
|
|
2323
|
-
const ETagKey = "etag";
|
|
2324
|
-
const ExpiresKey = "expires";
|
|
2325
|
-
const HostKey = "host";
|
|
2326
|
-
const IfMatchKey = "if-match";
|
|
2327
|
-
const IfModifiedSinceKey = "if-modified-since";
|
|
2328
|
-
const IfNoneMatchKey = "if-none-match";
|
|
2329
|
-
const IfRangeKey = "if-range";
|
|
2330
|
-
const IfUnmodifiedSinceKey = "if-unmodified-since";
|
|
2331
|
-
const LastModifiedKey = "last-modified";
|
|
2332
|
-
const LocationKey = "location";
|
|
2333
|
-
const RangeKey = "range";
|
|
2334
|
-
const RefererKey = "referer";
|
|
2335
|
-
const SetCookieKey = "set-cookie";
|
|
2336
|
-
const VaryKey = "vary";
|
|
2337
|
-
class SuperHeaders extends Headers {
|
|
2338
|
-
#map;
|
|
2339
|
-
#setCookies = [];
|
|
2340
|
-
/**
|
|
2341
|
-
* @param init A string, iterable, object, or `Headers` instance to initialize with
|
|
2342
|
-
*/
|
|
2343
|
-
constructor(init) {
|
|
2344
|
-
super();
|
|
2345
|
-
this.#map = /* @__PURE__ */ new Map();
|
|
2346
|
-
if (init) {
|
|
2347
|
-
if (typeof init === "string") {
|
|
2348
|
-
let lines = init.split(CRLF);
|
|
2349
|
-
for (let line of lines) {
|
|
2350
|
-
let match = line.match(/^([^:]+):(.*)/);
|
|
2351
|
-
if (match) {
|
|
2352
|
-
this.append(match[1].trim(), match[2].trim());
|
|
2353
|
-
}
|
|
2354
|
-
}
|
|
2355
|
-
} else if (isIterable(init)) {
|
|
2356
|
-
for (let [name, value] of init) {
|
|
2357
|
-
this.append(name, value);
|
|
2358
|
-
}
|
|
2359
|
-
} else if (typeof init === "object") {
|
|
2360
|
-
for (let name of Object.getOwnPropertyNames(init)) {
|
|
2361
|
-
let value = init[name];
|
|
2362
|
-
let descriptor = Object.getOwnPropertyDescriptor(SuperHeaders.prototype, name);
|
|
2363
|
-
if (descriptor?.set) {
|
|
2364
|
-
descriptor.set.call(this, value);
|
|
2365
|
-
} else {
|
|
2366
|
-
this.set(name, value.toString());
|
|
2367
|
-
}
|
|
2368
|
-
}
|
|
2369
|
-
}
|
|
2370
|
-
}
|
|
2371
|
-
}
|
|
2372
|
-
/**
|
|
2373
|
-
* Appends a new header value to the existing set of values for a header,
|
|
2374
|
-
* or adds the header if it does not already exist.
|
|
2375
|
-
*
|
|
2376
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/append)
|
|
2377
|
-
*
|
|
2378
|
-
* @param name The name of the header to append to
|
|
2379
|
-
* @param value The value to append
|
|
2380
|
-
*/
|
|
2381
|
-
append(name, value) {
|
|
2382
|
-
let key = name.toLowerCase();
|
|
2383
|
-
if (key === SetCookieKey) {
|
|
2384
|
-
this.#setCookies.push(value);
|
|
2385
|
-
} else {
|
|
2386
|
-
let existingValue = this.#map.get(key);
|
|
2387
|
-
this.#map.set(key, existingValue ? `${existingValue}, ${value}` : value);
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
2390
|
-
/**
|
|
2391
|
-
* Removes a header.
|
|
2392
|
-
*
|
|
2393
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete)
|
|
2394
|
-
*
|
|
2395
|
-
* @param name The name of the header to delete
|
|
2396
|
-
*/
|
|
2397
|
-
delete(name) {
|
|
2398
|
-
let key = name.toLowerCase();
|
|
2399
|
-
if (key === SetCookieKey) {
|
|
2400
|
-
this.#setCookies = [];
|
|
2401
|
-
} else {
|
|
2402
|
-
this.#map.delete(key);
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
/**
|
|
2406
|
-
* Returns a string of all the values for a header, or `null` if the header does not exist.
|
|
2407
|
-
*
|
|
2408
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/get)
|
|
2409
|
-
*
|
|
2410
|
-
* @param name The name of the header to get
|
|
2411
|
-
* @return The header value, or `null` if not found
|
|
2412
|
-
*/
|
|
2413
|
-
get(name) {
|
|
2414
|
-
let key = name.toLowerCase();
|
|
2415
|
-
if (key === SetCookieKey) {
|
|
2416
|
-
return this.getSetCookie().join(", ");
|
|
2417
|
-
} else {
|
|
2418
|
-
let value = this.#map.get(key);
|
|
2419
|
-
if (typeof value === "string") {
|
|
2420
|
-
return value;
|
|
2421
|
-
} else if (value != null) {
|
|
2422
|
-
let str = value.toString();
|
|
2423
|
-
return str === "" ? null : str;
|
|
2424
|
-
} else {
|
|
2425
|
-
return null;
|
|
2426
|
-
}
|
|
2427
|
-
}
|
|
2428
|
-
}
|
|
2429
|
-
/**
|
|
2430
|
-
* Returns an array of all values associated with the `Set-Cookie` header. This is
|
|
2431
|
-
* useful when building headers for a HTTP response since multiple `Set-Cookie` headers
|
|
2432
|
-
* must be sent on separate lines.
|
|
2433
|
-
*
|
|
2434
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/getSetCookie)
|
|
2435
|
-
*
|
|
2436
|
-
* @return An array of `Set-Cookie` header values
|
|
2437
|
-
*/
|
|
2438
|
-
getSetCookie() {
|
|
2439
|
-
return this.#setCookies.map((v) => typeof v === "string" ? v : v.toString());
|
|
2440
|
-
}
|
|
2441
|
-
/**
|
|
2442
|
-
* Returns `true` if the header is present in the list of headers.
|
|
2443
|
-
*
|
|
2444
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/has)
|
|
2445
|
-
*
|
|
2446
|
-
* @param name The name of the header to check
|
|
2447
|
-
* @return `true` if the header is present, `false` otherwise
|
|
2448
|
-
*/
|
|
2449
|
-
has(name) {
|
|
2450
|
-
let key = name.toLowerCase();
|
|
2451
|
-
return key === SetCookieKey ? this.#setCookies.length > 0 : this.get(key) != null;
|
|
2452
|
-
}
|
|
2453
|
-
/**
|
|
2454
|
-
* Sets a new value for the given header. If the header already exists, the new value
|
|
2455
|
-
* will replace the existing value.
|
|
2456
|
-
*
|
|
2457
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/set)
|
|
2458
|
-
*
|
|
2459
|
-
* @param name The name of the header to set
|
|
2460
|
-
* @param value The value to set
|
|
2461
|
-
*/
|
|
2462
|
-
set(name, value) {
|
|
2463
|
-
let key = name.toLowerCase();
|
|
2464
|
-
if (key === SetCookieKey) {
|
|
2465
|
-
this.#setCookies = [value];
|
|
2466
|
-
} else {
|
|
2467
|
-
this.#map.set(key, value);
|
|
2468
|
-
}
|
|
2469
|
-
}
|
|
2470
|
-
/**
|
|
2471
|
-
* Returns an iterator of all header keys (lowercase).
|
|
2472
|
-
*
|
|
2473
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys)
|
|
2474
|
-
*
|
|
2475
|
-
* @return An iterator of header keys
|
|
2476
|
-
*/
|
|
2477
|
-
*keys() {
|
|
2478
|
-
for (let [key] of this)
|
|
2479
|
-
yield key;
|
|
2480
|
-
}
|
|
2481
|
-
/**
|
|
2482
|
-
* Returns an iterator of all header values.
|
|
2483
|
-
*
|
|
2484
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/values)
|
|
2485
|
-
*
|
|
2486
|
-
* @return An iterator of header values
|
|
2487
|
-
*/
|
|
2488
|
-
*values() {
|
|
2489
|
-
for (let [, value] of this)
|
|
2490
|
-
yield value;
|
|
2491
|
-
}
|
|
2492
|
-
/**
|
|
2493
|
-
* Returns an iterator of all header key/value pairs.
|
|
2494
|
-
*
|
|
2495
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries)
|
|
2496
|
-
*
|
|
2497
|
-
* @return An iterator of `[key, value]` tuples
|
|
2498
|
-
*/
|
|
2499
|
-
*entries() {
|
|
2500
|
-
for (let [key] of this.#map) {
|
|
2501
|
-
let str = this.get(key);
|
|
2502
|
-
if (str)
|
|
2503
|
-
yield [key, str];
|
|
2504
|
-
}
|
|
2505
|
-
for (let value of this.getSetCookie()) {
|
|
2506
|
-
yield [SetCookieKey, value];
|
|
2507
|
-
}
|
|
2508
|
-
}
|
|
2509
|
-
[Symbol.iterator]() {
|
|
2510
|
-
return this.entries();
|
|
2511
|
-
}
|
|
2512
|
-
/**
|
|
2513
|
-
* Invokes the `callback` for each header key/value pair.
|
|
2514
|
-
*
|
|
2515
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/forEach)
|
|
2516
|
-
*
|
|
2517
|
-
* @param callback The function to call for each pair
|
|
2518
|
-
* @param thisArg The value to use as `this` when calling the callback
|
|
2519
|
-
*/
|
|
2520
|
-
forEach(callback, thisArg) {
|
|
2521
|
-
for (let [key, value] of this) {
|
|
2522
|
-
callback.call(thisArg, value, key, this);
|
|
2523
|
-
}
|
|
2524
|
-
}
|
|
2525
|
-
/**
|
|
2526
|
-
* Returns a string representation of the headers suitable for use in a HTTP message.
|
|
2527
|
-
*
|
|
2528
|
-
* @return The headers formatted for HTTP
|
|
2529
|
-
*/
|
|
2530
|
-
toString() {
|
|
2531
|
-
let lines = [];
|
|
2532
|
-
for (let [key, value] of this) {
|
|
2533
|
-
lines.push(`${canonicalHeaderName(key)}: ${value}`);
|
|
2534
|
-
}
|
|
2535
|
-
return lines.join(CRLF);
|
|
2536
|
-
}
|
|
2537
|
-
// Header-specific getters and setters
|
|
2538
|
-
/**
|
|
2539
|
-
* The `Accept` header is used by clients to indicate the media types that are acceptable
|
|
2540
|
-
* in the response.
|
|
2541
|
-
*
|
|
2542
|
-
* [MDN `Accept` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept)
|
|
2543
|
-
*
|
|
2544
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2)
|
|
2545
|
-
*/
|
|
2546
|
-
get accept() {
|
|
2547
|
-
return this.#getHeaderValue(AcceptKey, Accept);
|
|
2548
|
-
}
|
|
2549
|
-
set accept(value) {
|
|
2550
|
-
this.#setHeaderValue(AcceptKey, Accept, value);
|
|
2551
|
-
}
|
|
2552
|
-
/**
|
|
2553
|
-
* The `Accept-Encoding` header contains information about the content encodings that the client
|
|
2554
|
-
* is willing to accept in the response.
|
|
2555
|
-
*
|
|
2556
|
-
* [MDN `Accept-Encoding` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding)
|
|
2557
|
-
*
|
|
2558
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.4)
|
|
2559
|
-
*/
|
|
2560
|
-
get acceptEncoding() {
|
|
2561
|
-
return this.#getHeaderValue(AcceptEncodingKey, AcceptEncoding);
|
|
2562
|
-
}
|
|
2563
|
-
set acceptEncoding(value) {
|
|
2564
|
-
this.#setHeaderValue(AcceptEncodingKey, AcceptEncoding, value);
|
|
2565
|
-
}
|
|
2566
|
-
/**
|
|
2567
|
-
* The `Accept-Language` header contains information about preferred natural language for the
|
|
2568
|
-
* response.
|
|
2569
|
-
*
|
|
2570
|
-
* [MDN `Accept-Language` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language)
|
|
2571
|
-
*
|
|
2572
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.5)
|
|
2573
|
-
*/
|
|
2574
|
-
get acceptLanguage() {
|
|
2575
|
-
return this.#getHeaderValue(AcceptLanguageKey, AcceptLanguage);
|
|
2576
|
-
}
|
|
2577
|
-
set acceptLanguage(value) {
|
|
2578
|
-
this.#setHeaderValue(AcceptLanguageKey, AcceptLanguage, value);
|
|
2579
|
-
}
|
|
2580
|
-
/**
|
|
2581
|
-
* The `Accept-Ranges` header indicates the server's acceptance of range requests.
|
|
2582
|
-
*
|
|
2583
|
-
* [MDN `Accept-Ranges` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Ranges)
|
|
2584
|
-
*
|
|
2585
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7233#section-2.3)
|
|
2586
|
-
*/
|
|
2587
|
-
get acceptRanges() {
|
|
2588
|
-
return this.#getStringValue(AcceptRangesKey);
|
|
2589
|
-
}
|
|
2590
|
-
set acceptRanges(value) {
|
|
2591
|
-
this.#setStringValue(AcceptRangesKey, value);
|
|
2592
|
-
}
|
|
2593
|
-
/**
|
|
2594
|
-
* The `Age` header contains the time in seconds an object was in a proxy cache.
|
|
2595
|
-
*
|
|
2596
|
-
* [MDN `Age` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Age)
|
|
2597
|
-
*
|
|
2598
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.1)
|
|
2599
|
-
*/
|
|
2600
|
-
get age() {
|
|
2601
|
-
return this.#getNumberValue(AgeKey);
|
|
2602
|
-
}
|
|
2603
|
-
set age(value) {
|
|
2604
|
-
this.#setNumberValue(AgeKey, value);
|
|
2605
|
-
}
|
|
2606
|
-
/**
|
|
2607
|
-
* The `Allow` header lists the HTTP methods that are supported by the resource.
|
|
2608
|
-
*
|
|
2609
|
-
* [MDN `Allow` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Allow)
|
|
2610
|
-
*
|
|
2611
|
-
* [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.allow)
|
|
2612
|
-
*/
|
|
2613
|
-
get allow() {
|
|
2614
|
-
return this.#getStringValue(AllowKey);
|
|
2615
|
-
}
|
|
2616
|
-
set allow(value) {
|
|
2617
|
-
this.#setStringValue(AllowKey, Array.isArray(value) ? value.join(", ") : value);
|
|
2618
|
-
}
|
|
2619
|
-
/**
|
|
2620
|
-
* The `Cache-Control` header contains directives for caching mechanisms in both requests and responses.
|
|
2621
|
-
*
|
|
2622
|
-
* [MDN `Cache-Control` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control)
|
|
2623
|
-
*
|
|
2624
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.2)
|
|
2625
|
-
*/
|
|
2626
|
-
get cacheControl() {
|
|
2627
|
-
return this.#getHeaderValue(CacheControlKey, CacheControl);
|
|
2628
|
-
}
|
|
2629
|
-
set cacheControl(value) {
|
|
2630
|
-
this.#setHeaderValue(CacheControlKey, CacheControl, value);
|
|
2631
|
-
}
|
|
2632
|
-
/**
|
|
2633
|
-
* The `Connection` header controls whether the network connection stays open after the current
|
|
2634
|
-
* transaction finishes.
|
|
2635
|
-
*
|
|
2636
|
-
* [MDN `Connection` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection)
|
|
2637
|
-
*
|
|
2638
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-6.1)
|
|
2639
|
-
*/
|
|
2640
|
-
get connection() {
|
|
2641
|
-
return this.#getStringValue(ConnectionKey);
|
|
2642
|
-
}
|
|
2643
|
-
set connection(value) {
|
|
2644
|
-
this.#setStringValue(ConnectionKey, value);
|
|
2645
|
-
}
|
|
2646
|
-
/**
|
|
2647
|
-
* The `Content-Disposition` header is a response-type header that describes how the payload is displayed.
|
|
2648
|
-
*
|
|
2649
|
-
* [MDN `Content-Disposition` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
|
|
2650
|
-
*
|
|
2651
|
-
* [RFC 6266](https://datatracker.ietf.org/doc/html/rfc6266)
|
|
2652
|
-
*/
|
|
2653
|
-
get contentDisposition() {
|
|
2654
|
-
return this.#getHeaderValue(ContentDispositionKey, ContentDisposition);
|
|
2655
|
-
}
|
|
2656
|
-
set contentDisposition(value) {
|
|
2657
|
-
this.#setHeaderValue(ContentDispositionKey, ContentDisposition, value);
|
|
2658
|
-
}
|
|
2659
|
-
/**
|
|
2660
|
-
* The `Content-Encoding` header specifies the encoding of the resource.
|
|
2661
|
-
*
|
|
2662
|
-
* Note: If multiple encodings have been used, this value may be a comma-separated list. However, most often this
|
|
2663
|
-
* header will only contain a single value.
|
|
2664
|
-
*
|
|
2665
|
-
* [MDN `Content-Encoding` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding)
|
|
2666
|
-
*
|
|
2667
|
-
* [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.content-encoding)
|
|
2668
|
-
*/
|
|
2669
|
-
get contentEncoding() {
|
|
2670
|
-
return this.#getStringValue(ContentEncodingKey);
|
|
2671
|
-
}
|
|
2672
|
-
set contentEncoding(value) {
|
|
2673
|
-
this.#setStringValue(ContentEncodingKey, Array.isArray(value) ? value.join(", ") : value);
|
|
2674
|
-
}
|
|
2675
|
-
/**
|
|
2676
|
-
* The `Content-Language` header describes the natural language(s) of the intended audience for the response content.
|
|
2677
|
-
*
|
|
2678
|
-
* Note: If the response content is intended for multiple audiences, this value may be a comma-separated list. However,
|
|
2679
|
-
* most often this header will only contain a single value.
|
|
2680
|
-
*
|
|
2681
|
-
* [MDN `Content-Language` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language)
|
|
2682
|
-
*
|
|
2683
|
-
* [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.content-language)
|
|
2684
|
-
*/
|
|
2685
|
-
get contentLanguage() {
|
|
2686
|
-
return this.#getStringValue(ContentLanguageKey);
|
|
2687
|
-
}
|
|
2688
|
-
set contentLanguage(value) {
|
|
2689
|
-
this.#setStringValue(ContentLanguageKey, Array.isArray(value) ? value.join(", ") : value);
|
|
2690
|
-
}
|
|
2691
|
-
/**
|
|
2692
|
-
* The `Content-Length` header indicates the size of the entity-body in bytes.
|
|
2693
|
-
*
|
|
2694
|
-
* [MDN `Content-Length` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length)
|
|
2695
|
-
*
|
|
2696
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2)
|
|
2697
|
-
*/
|
|
2698
|
-
get contentLength() {
|
|
2699
|
-
return this.#getNumberValue(ContentLengthKey);
|
|
2700
|
-
}
|
|
2701
|
-
set contentLength(value) {
|
|
2702
|
-
this.#setNumberValue(ContentLengthKey, value);
|
|
2703
|
-
}
|
|
2704
|
-
/**
|
|
2705
|
-
* The `Content-Range` header indicates where the content of a response body
|
|
2706
|
-
* belongs in relation to a complete resource.
|
|
2707
|
-
*
|
|
2708
|
-
* [MDN `Content-Range` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range)
|
|
2709
|
-
*
|
|
2710
|
-
* [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.content-range)
|
|
2711
|
-
*/
|
|
2712
|
-
get contentRange() {
|
|
2713
|
-
return this.#getHeaderValue(ContentRangeKey, ContentRange);
|
|
2714
|
-
}
|
|
2715
|
-
set contentRange(value) {
|
|
2716
|
-
this.#setHeaderValue(ContentRangeKey, ContentRange, value);
|
|
2717
|
-
}
|
|
2718
|
-
/**
|
|
2719
|
-
* The `Content-Type` header indicates the media type of the resource.
|
|
2720
|
-
*
|
|
2721
|
-
* [MDN `Content-Type` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type)
|
|
2722
|
-
*
|
|
2723
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.1.5)
|
|
2724
|
-
*/
|
|
2725
|
-
get contentType() {
|
|
2726
|
-
return this.#getHeaderValue(ContentTypeKey, ContentType);
|
|
2727
|
-
}
|
|
2728
|
-
set contentType(value) {
|
|
2729
|
-
this.#setHeaderValue(ContentTypeKey, ContentType, value);
|
|
2730
|
-
}
|
|
2731
|
-
/**
|
|
2732
|
-
* The `Cookie` request header contains stored HTTP cookies previously sent by the server with
|
|
2733
|
-
* the `Set-Cookie` header.
|
|
2734
|
-
*
|
|
2735
|
-
* [MDN `Cookie` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie)
|
|
2736
|
-
*
|
|
2737
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc6265#section-5.4)
|
|
2738
|
-
*/
|
|
2739
|
-
get cookie() {
|
|
2740
|
-
return this.#getHeaderValue(CookieKey, Cookie);
|
|
2741
|
-
}
|
|
2742
|
-
set cookie(value) {
|
|
2743
|
-
this.#setHeaderValue(CookieKey, Cookie, value);
|
|
2744
|
-
}
|
|
2745
|
-
/**
|
|
2746
|
-
* The `Date` header contains the date and time at which the message was sent.
|
|
2747
|
-
*
|
|
2748
|
-
* [MDN `Date` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Date)
|
|
2749
|
-
*
|
|
2750
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.2)
|
|
2751
|
-
*/
|
|
2752
|
-
get date() {
|
|
2753
|
-
return this.#getDateValue(DateKey);
|
|
2754
|
-
}
|
|
2755
|
-
set date(value) {
|
|
2756
|
-
this.#setDateValue(DateKey, value);
|
|
2757
|
-
}
|
|
2758
|
-
/**
|
|
2759
|
-
* The `ETag` header provides a unique identifier for the current version of the resource.
|
|
2760
|
-
*
|
|
2761
|
-
* [MDN `ETag` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)
|
|
2762
|
-
*
|
|
2763
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-2.3)
|
|
2764
|
-
*/
|
|
2765
|
-
get etag() {
|
|
2766
|
-
return this.#getStringValue(ETagKey);
|
|
2767
|
-
}
|
|
2768
|
-
set etag(value) {
|
|
2769
|
-
this.#setStringValue(ETagKey, typeof value === "string" ? quoteEtag(value) : value);
|
|
2770
|
-
}
|
|
2771
|
-
/**
|
|
2772
|
-
* The `Expires` header contains the date/time after which the response is considered stale.
|
|
2773
|
-
*
|
|
2774
|
-
* [MDN `Expires` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires)
|
|
2775
|
-
*
|
|
2776
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.3)
|
|
2777
|
-
*/
|
|
2778
|
-
get expires() {
|
|
2779
|
-
return this.#getDateValue(ExpiresKey);
|
|
2780
|
-
}
|
|
2781
|
-
set expires(value) {
|
|
2782
|
-
this.#setDateValue(ExpiresKey, value);
|
|
2783
|
-
}
|
|
2784
|
-
/**
|
|
2785
|
-
* The `Host` header specifies the domain name of the server and (optionally) the TCP port number.
|
|
2786
|
-
*
|
|
2787
|
-
* [MDN `Host` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host)
|
|
2788
|
-
*
|
|
2789
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-5.4)
|
|
2790
|
-
*/
|
|
2791
|
-
get host() {
|
|
2792
|
-
return this.#getStringValue(HostKey);
|
|
2793
|
-
}
|
|
2794
|
-
set host(value) {
|
|
2795
|
-
this.#setStringValue(HostKey, value);
|
|
2796
|
-
}
|
|
2797
|
-
/**
|
|
2798
|
-
* The `If-Modified-Since` header makes a request conditional on the last modification date of the
|
|
2799
|
-
* requested resource.
|
|
2800
|
-
*
|
|
2801
|
-
* [MDN `If-Modified-Since` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since)
|
|
2802
|
-
*
|
|
2803
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.3)
|
|
2804
|
-
*/
|
|
2805
|
-
get ifModifiedSince() {
|
|
2806
|
-
return this.#getDateValue(IfModifiedSinceKey);
|
|
2807
|
-
}
|
|
2808
|
-
set ifModifiedSince(value) {
|
|
2809
|
-
this.#setDateValue(IfModifiedSinceKey, value);
|
|
2810
|
-
}
|
|
2811
|
-
/**
|
|
2812
|
-
* The `If-Match` header makes a request conditional on the presence of a matching ETag.
|
|
2813
|
-
*
|
|
2814
|
-
* [MDN `If-Match` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Match)
|
|
2815
|
-
*
|
|
2816
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.1)
|
|
2817
|
-
*/
|
|
2818
|
-
get ifMatch() {
|
|
2819
|
-
return this.#getHeaderValue(IfMatchKey, IfMatch);
|
|
2820
|
-
}
|
|
2821
|
-
set ifMatch(value) {
|
|
2822
|
-
this.#setHeaderValue(IfMatchKey, IfMatch, value);
|
|
2823
|
-
}
|
|
2824
|
-
/**
|
|
2825
|
-
* The `If-None-Match` header makes a request conditional on the absence of a matching ETag.
|
|
2826
|
-
*
|
|
2827
|
-
* [MDN `If-None-Match` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match)
|
|
2828
|
-
*
|
|
2829
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.2)
|
|
2830
|
-
*/
|
|
2831
|
-
get ifNoneMatch() {
|
|
2832
|
-
return this.#getHeaderValue(IfNoneMatchKey, IfNoneMatch);
|
|
2833
|
-
}
|
|
2834
|
-
set ifNoneMatch(value) {
|
|
2835
|
-
this.#setHeaderValue(IfNoneMatchKey, IfNoneMatch, value);
|
|
2836
|
-
}
|
|
2837
|
-
/**
|
|
2838
|
-
* The `If-Range` header makes a range request conditional on the resource state.
|
|
2839
|
-
* Can contain either an entity tag (ETag) or an HTTP date.
|
|
2840
|
-
*
|
|
2841
|
-
* [MDN `If-Range` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Range)
|
|
2842
|
-
*
|
|
2843
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7233#section-3.2)
|
|
2844
|
-
*/
|
|
2845
|
-
get ifRange() {
|
|
2846
|
-
return this.#getHeaderValue(IfRangeKey, IfRange);
|
|
2847
|
-
}
|
|
2848
|
-
set ifRange(value) {
|
|
2849
|
-
this.#setHeaderValue(IfRangeKey, IfRange, value);
|
|
2850
|
-
}
|
|
2851
|
-
/**
|
|
2852
|
-
* The `If-Unmodified-Since` header makes a request conditional on the last modification date of the
|
|
2853
|
-
* requested resource.
|
|
2854
|
-
*
|
|
2855
|
-
* [MDN `If-Unmodified-Since` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since)
|
|
2856
|
-
*
|
|
2857
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.4)
|
|
2858
|
-
*/
|
|
2859
|
-
get ifUnmodifiedSince() {
|
|
2860
|
-
return this.#getDateValue(IfUnmodifiedSinceKey);
|
|
2861
|
-
}
|
|
2862
|
-
set ifUnmodifiedSince(value) {
|
|
2863
|
-
this.#setDateValue(IfUnmodifiedSinceKey, value);
|
|
2864
|
-
}
|
|
2865
|
-
/**
|
|
2866
|
-
* The `Last-Modified` header contains the date and time at which the resource was last modified.
|
|
2867
|
-
*
|
|
2868
|
-
* [MDN `Last-Modified` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified)
|
|
2869
|
-
*
|
|
2870
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-2.2)
|
|
2871
|
-
*/
|
|
2872
|
-
get lastModified() {
|
|
2873
|
-
return this.#getDateValue(LastModifiedKey);
|
|
2874
|
-
}
|
|
2875
|
-
set lastModified(value) {
|
|
2876
|
-
this.#setDateValue(LastModifiedKey, value);
|
|
2877
|
-
}
|
|
2878
|
-
/**
|
|
2879
|
-
* The `Location` header indicates the URL to redirect to.
|
|
2880
|
-
*
|
|
2881
|
-
* [MDN `Location` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location)
|
|
2882
|
-
*
|
|
2883
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.2)
|
|
2884
|
-
*/
|
|
2885
|
-
get location() {
|
|
2886
|
-
return this.#getStringValue(LocationKey);
|
|
2887
|
-
}
|
|
2888
|
-
set location(value) {
|
|
2889
|
-
this.#setStringValue(LocationKey, value);
|
|
2890
|
-
}
|
|
2891
|
-
/**
|
|
2892
|
-
* The `Range` header indicates the part of a resource that the client wants to receive.
|
|
2893
|
-
*
|
|
2894
|
-
* [MDN `Range` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range)
|
|
2895
|
-
*
|
|
2896
|
-
* [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.range)
|
|
2897
|
-
*/
|
|
2898
|
-
get range() {
|
|
2899
|
-
return this.#getHeaderValue(RangeKey, Range);
|
|
2900
|
-
}
|
|
2901
|
-
set range(value) {
|
|
2902
|
-
this.#setHeaderValue(RangeKey, Range, value);
|
|
2903
|
-
}
|
|
2904
|
-
/**
|
|
2905
|
-
* The `Referer` header contains the address of the previous web page from which a link to the
|
|
2906
|
-
* currently requested page was followed.
|
|
2907
|
-
*
|
|
2908
|
-
* [MDN `Referer` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer)
|
|
2909
|
-
*
|
|
2910
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.5.2)
|
|
2911
|
-
*/
|
|
2912
|
-
get referer() {
|
|
2913
|
-
return this.#getStringValue(RefererKey);
|
|
2914
|
-
}
|
|
2915
|
-
set referer(value) {
|
|
2916
|
-
this.#setStringValue(RefererKey, value);
|
|
2917
|
-
}
|
|
2918
|
-
/**
|
|
2919
|
-
* The `Set-Cookie` header is used to send cookies from the server to the user agent.
|
|
2920
|
-
*
|
|
2921
|
-
* [MDN `Set-Cookie` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie)
|
|
2922
|
-
*
|
|
2923
|
-
* [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc6265#section-4.1)
|
|
2924
|
-
*/
|
|
2925
|
-
get setCookie() {
|
|
2926
|
-
let setCookies = this.#setCookies;
|
|
2927
|
-
for (let i = 0; i < setCookies.length; ++i) {
|
|
2928
|
-
if (typeof setCookies[i] === "string") {
|
|
2929
|
-
setCookies[i] = new SetCookie(setCookies[i]);
|
|
2930
|
-
}
|
|
2931
|
-
}
|
|
2932
|
-
return setCookies;
|
|
2933
|
-
}
|
|
2934
|
-
set setCookie(value) {
|
|
2935
|
-
if (value != null) {
|
|
2936
|
-
this.#setCookies = (Array.isArray(value) ? value : [value]).map((v) => typeof v === "string" ? v : new SetCookie(v));
|
|
2937
|
-
} else {
|
|
2938
|
-
this.#setCookies = [];
|
|
2939
|
-
}
|
|
2940
|
-
}
|
|
2941
|
-
/**
|
|
2942
|
-
* The `Vary` header indicates the set of request headers that determine whether
|
|
2943
|
-
* a cached response can be used rather than requesting a fresh response from the origin server.
|
|
2944
|
-
*
|
|
2945
|
-
* Common values include `Accept-Encoding`, `Accept-Language`, `Accept`, `User-Agent`, etc.
|
|
2946
|
-
*
|
|
2947
|
-
* [MDN `Vary` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary)
|
|
2948
|
-
*
|
|
2949
|
-
* [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.vary)
|
|
2950
|
-
*/
|
|
2951
|
-
get vary() {
|
|
2952
|
-
return this.#getHeaderValue(VaryKey, Vary);
|
|
2953
|
-
}
|
|
2954
|
-
set vary(value) {
|
|
2955
|
-
this.#setHeaderValue(VaryKey, Vary, value);
|
|
2956
|
-
}
|
|
2957
|
-
// Helpers
|
|
2958
|
-
#getHeaderValue(key, ctor) {
|
|
2959
|
-
let value = this.#map.get(key);
|
|
2960
|
-
if (value !== void 0) {
|
|
2961
|
-
if (typeof value === "string") {
|
|
2962
|
-
let obj2 = new ctor(value);
|
|
2963
|
-
this.#map.set(key, obj2);
|
|
2964
|
-
return obj2;
|
|
2965
|
-
} else {
|
|
2966
|
-
return value;
|
|
2967
|
-
}
|
|
2968
|
-
}
|
|
2969
|
-
let obj = new ctor();
|
|
2970
|
-
this.#map.set(key, obj);
|
|
2971
|
-
return obj;
|
|
2972
|
-
}
|
|
2973
|
-
#setHeaderValue(key, ctor, value) {
|
|
2974
|
-
if (value != null) {
|
|
2975
|
-
this.#map.set(key, typeof value === "string" ? value : new ctor(value));
|
|
2976
|
-
} else {
|
|
2977
|
-
this.#map.delete(key);
|
|
2978
|
-
}
|
|
2979
|
-
}
|
|
2980
|
-
#getDateValue(key) {
|
|
2981
|
-
let value = this.#map.get(key);
|
|
2982
|
-
return value === void 0 ? null : new Date(value);
|
|
2983
|
-
}
|
|
2984
|
-
#setDateValue(key, value) {
|
|
2985
|
-
if (value != null) {
|
|
2986
|
-
this.#map.set(key, typeof value === "string" ? value : (typeof value === "number" ? new Date(value) : value).toUTCString());
|
|
2987
|
-
} else {
|
|
2988
|
-
this.#map.delete(key);
|
|
2989
|
-
}
|
|
2990
|
-
}
|
|
2991
|
-
#getNumberValue(key) {
|
|
2992
|
-
let value = this.#map.get(key);
|
|
2993
|
-
return value === void 0 ? null : parseInt(value, 10);
|
|
2994
|
-
}
|
|
2995
|
-
#setNumberValue(key, value) {
|
|
2996
|
-
if (value != null) {
|
|
2997
|
-
this.#map.set(key, typeof value === "string" ? value : value.toString());
|
|
2998
|
-
} else {
|
|
2999
|
-
this.#map.delete(key);
|
|
3000
|
-
}
|
|
3001
|
-
}
|
|
3002
|
-
#getStringValue(key) {
|
|
3003
|
-
let value = this.#map.get(key);
|
|
3004
|
-
return value === void 0 ? null : value;
|
|
3005
|
-
}
|
|
3006
|
-
#setStringValue(key, value) {
|
|
3007
|
-
if (value != null) {
|
|
3008
|
-
this.#map.set(key, value);
|
|
3009
|
-
} else {
|
|
3010
|
-
this.#map.delete(key);
|
|
3011
|
-
}
|
|
3012
|
-
}
|
|
3013
|
-
}
|
|
3014
|
-
|
|
3015
|
-
const HeaderUtilities = {
|
|
3016
|
-
/**
|
|
3017
|
-
* Check if client accepts a specific media type based on Accept header.
|
|
3018
|
-
* @param acceptHeader HTTP Accept header value
|
|
3019
|
-
* @param mediaType Media type to check for acceptance
|
|
3020
|
-
* @returns True if the media type is accepted by the client
|
|
3021
|
-
*/
|
|
3022
|
-
acceptsMediaType(acceptHeader, mediaType) {
|
|
3023
|
-
const accept = this.parseAccept(acceptHeader);
|
|
3024
|
-
return accept ? accept.accepts(mediaType) : false;
|
|
3025
|
-
},
|
|
3026
|
-
/**
|
|
3027
|
-
* Create Cache-Control header value from options.
|
|
3028
|
-
* @param options Cache control directives configuration
|
|
3029
|
-
* @returns Cache-Control header value string
|
|
3030
|
-
*/
|
|
3031
|
-
createCacheControl(options) {
|
|
3032
|
-
const directives = [];
|
|
3033
|
-
if (options.public) {
|
|
3034
|
-
directives.push("public");
|
|
3035
|
-
}
|
|
3036
|
-
if (options.private) {
|
|
3037
|
-
directives.push("private");
|
|
3038
|
-
}
|
|
3039
|
-
if (options.noCache) {
|
|
3040
|
-
directives.push("no-cache");
|
|
3041
|
-
}
|
|
3042
|
-
if (options.noStore) {
|
|
3043
|
-
directives.push("no-store");
|
|
3044
|
-
}
|
|
3045
|
-
if (options.immutable) {
|
|
3046
|
-
directives.push("immutable");
|
|
3047
|
-
}
|
|
3048
|
-
if (options.mustRevalidate) {
|
|
3049
|
-
directives.push("must-revalidate");
|
|
3050
|
-
}
|
|
3051
|
-
if (options.proxyRevalidate) {
|
|
3052
|
-
directives.push("proxy-revalidate");
|
|
3053
|
-
}
|
|
3054
|
-
if (options.maxAge !== void 0) {
|
|
3055
|
-
directives.push(`max-age=${options.maxAge}`);
|
|
3056
|
-
}
|
|
3057
|
-
if (options.sMaxAge !== void 0) {
|
|
3058
|
-
directives.push(`s-maxage=${options.sMaxAge}`);
|
|
3059
|
-
}
|
|
3060
|
-
if (options.minFresh !== void 0) {
|
|
3061
|
-
directives.push(`min-fresh=${options.minFresh}`);
|
|
3062
|
-
}
|
|
3063
|
-
if (options.staleWhileRevalidate !== void 0) {
|
|
3064
|
-
directives.push(`stale-while-revalidate=${options.staleWhileRevalidate}`);
|
|
3065
|
-
}
|
|
3066
|
-
if (options.staleIfError !== void 0) {
|
|
3067
|
-
directives.push(`stale-if-error=${options.staleIfError}`);
|
|
3068
|
-
}
|
|
3069
|
-
return directives.join(", ");
|
|
3070
|
-
},
|
|
3071
|
-
/**
|
|
3072
|
-
* Create common cache control presets with predefined configurations.
|
|
3073
|
-
* @param preset Preset name ('no-cache', 'no-store', 'public', 'private', or 'immutable')
|
|
3074
|
-
* @returns Cache-Control header value string for the preset
|
|
3075
|
-
*/
|
|
3076
|
-
createCacheControlPreset(preset) {
|
|
3077
|
-
const presets = {
|
|
3078
|
-
immutable: { immutable: true, maxAge: 31536e3 },
|
|
3079
|
-
// 1 year
|
|
3080
|
-
"no-cache": { noCache: true },
|
|
3081
|
-
"no-store": { noStore: true },
|
|
3082
|
-
private: { maxAge: 3600, private: true },
|
|
3083
|
-
// 1 hour default
|
|
3084
|
-
public: { maxAge: 3600, public: true }
|
|
3085
|
-
// 1 hour default
|
|
3086
|
-
};
|
|
3087
|
-
return this.createCacheControl(presets[preset]);
|
|
3088
|
-
},
|
|
3089
|
-
/**
|
|
3090
|
-
* Create Content-Disposition header for file downloads with optional filename.
|
|
3091
|
-
* @param options
|
|
3092
|
-
* @param options.filename Filename for the download
|
|
3093
|
-
* @param options.filenameSplat Alternative filename format
|
|
3094
|
-
* @param options.type Disposition type ('inline' or 'attachment')
|
|
3095
|
-
* @returns Content-Disposition header value string
|
|
3096
|
-
*/
|
|
3097
|
-
createContentDisposition(options) {
|
|
3098
|
-
const disposition = new ContentDisposition({
|
|
3099
|
-
type: options.type,
|
|
3100
|
-
...options.filename && { filename: options.filename },
|
|
3101
|
-
...options.filenameSplat && { filenameSplat: options.filenameSplat }
|
|
3102
|
-
});
|
|
3103
|
-
return disposition.toString();
|
|
3104
|
-
},
|
|
3105
|
-
/**
|
|
3106
|
-
* Create Content-Type header value from structured data with optional charset and boundary.
|
|
3107
|
-
* @param options
|
|
3108
|
-
* @param options.boundary Multipart boundary string
|
|
3109
|
-
* @param options.charset Character encoding (e.g., 'utf8')
|
|
3110
|
-
* @param options.mediaType MIME media type (e.g., 'application/json')
|
|
3111
|
-
* @returns Content-Type header value string
|
|
3112
|
-
*/
|
|
3113
|
-
createContentType(options) {
|
|
3114
|
-
const contentType = new ContentType({
|
|
3115
|
-
mediaType: options.mediaType,
|
|
3116
|
-
...options.charset && { charset: options.charset },
|
|
3117
|
-
...options.boundary && { boundary: options.boundary }
|
|
3118
|
-
});
|
|
3119
|
-
return contentType.toString();
|
|
3120
|
-
},
|
|
3121
|
-
/**
|
|
3122
|
-
* Get content type with charset if not already present.
|
|
3123
|
-
* @param contentType Content-Type header value to ensure charset for
|
|
3124
|
-
* @param defaultCharset Default charset to use if not present (default: 'utf8')
|
|
3125
|
-
* @returns Content-Type header value with charset ensured
|
|
3126
|
-
*/
|
|
3127
|
-
ensureCharset(contentType, defaultCharset = "utf8") {
|
|
3128
|
-
const ct = this.parseContentType(contentType);
|
|
3129
|
-
if (!ct) {
|
|
3130
|
-
return contentType;
|
|
3131
|
-
}
|
|
3132
|
-
if (!ct.charset) {
|
|
3133
|
-
ct.charset = defaultCharset;
|
|
3134
|
-
}
|
|
3135
|
-
return ct.toString();
|
|
3136
|
-
},
|
|
3137
|
-
/**
|
|
3138
|
-
* Convert our Headers type to EnhancedHeaders from remix-run/headers.
|
|
3139
|
-
* @param headers Headers in array or object format
|
|
3140
|
-
* @returns SuperHeaders instance with converted header values
|
|
3141
|
-
*/
|
|
3142
|
-
fromHeaders(headers) {
|
|
3143
|
-
const enhanced = new SuperHeaders();
|
|
3144
|
-
if (Array.isArray(headers)) {
|
|
3145
|
-
headers.forEach(([name, value]) => {
|
|
3146
|
-
enhanced.set(name, Array.isArray(value) ? value.join(", ") : String(value));
|
|
3147
|
-
});
|
|
3148
|
-
} else {
|
|
3149
|
-
Object.entries(headers).forEach(([name, value]) => {
|
|
3150
|
-
enhanced.set(name, Array.isArray(value) ? value.join(", ") : String(value));
|
|
3151
|
-
});
|
|
3152
|
-
}
|
|
3153
|
-
return enhanced;
|
|
3154
|
-
},
|
|
3155
|
-
/**
|
|
3156
|
-
* Get preferred media type from Accept header based on quality factors and supported types.
|
|
3157
|
-
* @param acceptHeader HTTP Accept header value
|
|
3158
|
-
* @param supportedTypes Array of supported MIME types to match against
|
|
3159
|
-
* @returns Best matching media type or undefined if no match found
|
|
3160
|
-
*/
|
|
3161
|
-
getPreferredMediaType(acceptHeader, supportedTypes) {
|
|
3162
|
-
const accept = this.parseAccept(acceptHeader);
|
|
3163
|
-
if (!accept) {
|
|
3164
|
-
return void 0;
|
|
3165
|
-
}
|
|
3166
|
-
for (const type of supportedTypes) {
|
|
3167
|
-
if (accept.accepts(type)) {
|
|
3168
|
-
return type;
|
|
3169
|
-
}
|
|
3170
|
-
}
|
|
3171
|
-
return void 0;
|
|
3172
|
-
},
|
|
3173
|
-
/**
|
|
3174
|
-
* Parse Accept header with quality factor support.
|
|
3175
|
-
* @param headerValue HTTP Accept header value to parse
|
|
3176
|
-
* @returns Accept instance or undefined if header is invalid or missing
|
|
3177
|
-
*/
|
|
3178
|
-
parseAccept(headerValue) {
|
|
3179
|
-
if (!headerValue) {
|
|
3180
|
-
return void 0;
|
|
3181
|
-
}
|
|
3182
|
-
try {
|
|
3183
|
-
return new Accept(headerValue);
|
|
3184
|
-
} catch {
|
|
3185
|
-
return void 0;
|
|
3186
|
-
}
|
|
3187
|
-
},
|
|
3188
|
-
/**
|
|
3189
|
-
* Parse Content-Disposition header into structured object.
|
|
3190
|
-
* @param headerValue HTTP Content-Disposition header value to parse
|
|
3191
|
-
* @returns ContentDisposition instance or undefined if header is invalid or missing
|
|
3192
|
-
*/
|
|
3193
|
-
parseContentDisposition(headerValue) {
|
|
3194
|
-
if (!headerValue) {
|
|
3195
|
-
return void 0;
|
|
3196
|
-
}
|
|
3197
|
-
try {
|
|
3198
|
-
return new ContentDisposition(headerValue);
|
|
3199
|
-
} catch {
|
|
3200
|
-
return void 0;
|
|
3201
|
-
}
|
|
3202
|
-
},
|
|
3203
|
-
/**
|
|
3204
|
-
* Parse Content-Type header with structured access to media type, charset, and boundary.
|
|
3205
|
-
* @param headerValue HTTP Content-Type header value to parse
|
|
3206
|
-
* @returns ContentType instance or undefined if header is invalid or missing
|
|
3207
|
-
*/
|
|
3208
|
-
parseContentType(headerValue) {
|
|
3209
|
-
if (!headerValue) {
|
|
3210
|
-
return void 0;
|
|
3211
|
-
}
|
|
3212
|
-
try {
|
|
3213
|
-
return new ContentType(headerValue);
|
|
3214
|
-
} catch {
|
|
3215
|
-
return void 0;
|
|
3216
|
-
}
|
|
3217
|
-
}
|
|
3218
|
-
};
|
|
3219
|
-
|
|
3220
|
-
export { HeaderUtilities as H, createHttpError as c, httpErrorsExports as h };
|