@d1g1tal/transportr 1.2.2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/transportr.js +1417 -1077
- package/dist/transportr.min.js +2 -2
- package/dist/transportr.min.js.map +4 -4
- package/package.json +6 -6
- package/src/abort-signal.js +175 -0
- package/src/constants.js +50 -0
- package/src/http-media-type.js +2 -0
- package/src/parameter-map.js +221 -0
- package/src/transportr.js +258 -282
- package/src/signal-controller.js +0 -50
package/dist/transportr.js
CHANGED
|
@@ -23,38 +23,6 @@ var Transportr = (() => {
|
|
|
23
23
|
default: () => Transportr
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
// node_modules/@d1g1tal/chrysalis/src/esm/object-type.js
|
|
27
|
-
var _type = (object) => object?.constructor ?? object?.prototype?.constructor ?? globalThis[Object.prototype.toString.call(object).slice(8, -1)] ?? object;
|
|
28
|
-
var object_type_default = _type;
|
|
29
|
-
|
|
30
|
-
// node_modules/@d1g1tal/chrysalis/src/esm/object-is-empty.js
|
|
31
|
-
var _objectIsEmpty = (object) => !!object && Object.keys(object).length === 0 && object.constructor === Object;
|
|
32
|
-
var object_is_empty_default = _objectIsEmpty;
|
|
33
|
-
|
|
34
|
-
// node_modules/@d1g1tal/chrysalis/src/esm/object-merge.js
|
|
35
|
-
var _objectMerge = (...objects) => {
|
|
36
|
-
const target = {};
|
|
37
|
-
for (const source of objects) {
|
|
38
|
-
if (object_type_default(source) != Object)
|
|
39
|
-
return void 0;
|
|
40
|
-
let descriptor, sourceType;
|
|
41
|
-
for (const property of Object.getOwnPropertyNames(source)) {
|
|
42
|
-
descriptor = Object.getOwnPropertyDescriptor(source, property);
|
|
43
|
-
if (descriptor.enumerable) {
|
|
44
|
-
sourceType = object_type_default(source[property]);
|
|
45
|
-
if (sourceType == Object) {
|
|
46
|
-
descriptor.value = object_type_default(target[property]) == Object ? _objectMerge(target[property], source[property]) : { ...source[property] };
|
|
47
|
-
} else if (sourceType == Array) {
|
|
48
|
-
descriptor.value = Array.isArray(target[property]) ? [.../* @__PURE__ */ new Set([...source[property], ...target[property]])] : [...source[property]];
|
|
49
|
-
}
|
|
50
|
-
target[property] = descriptor.value;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return target;
|
|
55
|
-
};
|
|
56
|
-
var object_merge_default = _objectMerge;
|
|
57
|
-
|
|
58
26
|
// node_modules/@d1g1tal/collections/src/set-multi-map.js
|
|
59
27
|
var SetMultiMap = class extends Map {
|
|
60
28
|
/**
|
|
@@ -101,602 +69,176 @@ var Transportr = (() => {
|
|
|
101
69
|
};
|
|
102
70
|
var set_multi_map_default = SetMultiMap;
|
|
103
71
|
|
|
104
|
-
// node_modules/@d1g1tal/
|
|
105
|
-
var
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
let result = "";
|
|
117
|
-
for (const [char, charCode = char.charCodeAt(0)] of string) {
|
|
118
|
-
result += charCode >= 65 && charCode <= 90 ? String.fromCharCode(charCode + 32) : char;
|
|
72
|
+
// node_modules/@d1g1tal/subscribr/node_modules/@d1g1tal/collections/src/set-multi-map.js
|
|
73
|
+
var SetMultiMap2 = class extends Map {
|
|
74
|
+
/**
|
|
75
|
+
* Adds a new element with a specified key and value to the SetMultiMap. If an element with the same key already exists, the value will be added to the underlying {@link Set}.
|
|
76
|
+
*
|
|
77
|
+
* @param {*} key The key to set.
|
|
78
|
+
* @param {*} value The value to add to the SetMultiMap
|
|
79
|
+
* @returns {SetMultiMap} The SetMultiMap with the updated key and value.
|
|
80
|
+
*/
|
|
81
|
+
set(key, value) {
|
|
82
|
+
super.set(key, (super.get(key) ?? /* @__PURE__ */ new Set()).add(value));
|
|
83
|
+
return this;
|
|
119
84
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
var collectAnHTTPQuotedString = (input, position) => {
|
|
123
|
-
let value = "";
|
|
124
|
-
for (let length = input.length, char; ++position < length; ) {
|
|
125
|
-
char = input[position];
|
|
126
|
-
if (char == "\\") {
|
|
127
|
-
value += ++position < length ? input[position] : char;
|
|
128
|
-
} else if (char == '"') {
|
|
129
|
-
break;
|
|
130
|
-
} else {
|
|
131
|
-
value += char;
|
|
132
|
-
}
|
|
85
|
+
[Symbol.toStringTag]() {
|
|
86
|
+
return "SetMultiMap";
|
|
133
87
|
}
|
|
134
|
-
return [value, position];
|
|
135
88
|
};
|
|
136
89
|
|
|
137
|
-
// node_modules/@d1g1tal/
|
|
138
|
-
var
|
|
139
|
-
|
|
140
|
-
#
|
|
90
|
+
// node_modules/@d1g1tal/subscribr/src/context-event-handler.js
|
|
91
|
+
var ContextEventHandler = class {
|
|
92
|
+
#context;
|
|
93
|
+
#eventHandler;
|
|
141
94
|
/**
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* @param {Array<Array<string>>} entries An array of [name, value] tuples.
|
|
95
|
+
* @param {*} context The context to bind to the event handler.
|
|
96
|
+
* @param {function(*): void} eventHandler The event handler to call when the event is published.
|
|
145
97
|
*/
|
|
146
|
-
constructor(
|
|
147
|
-
this.#
|
|
98
|
+
constructor(context, eventHandler) {
|
|
99
|
+
this.#context = context;
|
|
100
|
+
this.#eventHandler = eventHandler;
|
|
148
101
|
}
|
|
149
102
|
/**
|
|
150
|
-
*
|
|
103
|
+
* Call the event handler for the provided event.
|
|
151
104
|
*
|
|
152
|
-
* @
|
|
105
|
+
* @param {Event} event The event to handle
|
|
106
|
+
* @param {*} [data] The value to be passed to the event handler as a parameter.
|
|
153
107
|
*/
|
|
154
|
-
|
|
155
|
-
|
|
108
|
+
handle(event, data) {
|
|
109
|
+
this.#eventHandler.call(this.#context, event, data);
|
|
110
|
+
}
|
|
111
|
+
get [Symbol.toStringTag]() {
|
|
112
|
+
return "ContextEventHandler";
|
|
156
113
|
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// node_modules/@d1g1tal/subscribr/src/subscription.js
|
|
117
|
+
var Subscription = class {
|
|
118
|
+
#eventName;
|
|
119
|
+
#contextEventHandler;
|
|
157
120
|
/**
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
* @param {string} name The name of the media type parameter to retrieve.
|
|
161
|
-
* @returns {string} The media type parameter value.
|
|
121
|
+
* @param {string} eventName The event name.
|
|
122
|
+
* @param {ContextEventHandler} contextEventHandler Then context event handler.
|
|
162
123
|
*/
|
|
163
|
-
|
|
164
|
-
|
|
124
|
+
constructor(eventName, contextEventHandler) {
|
|
125
|
+
this.#eventName = eventName;
|
|
126
|
+
this.#contextEventHandler = contextEventHandler;
|
|
165
127
|
}
|
|
166
128
|
/**
|
|
167
|
-
*
|
|
129
|
+
* Gets the event name for the subscription.
|
|
168
130
|
*
|
|
169
|
-
* @
|
|
170
|
-
* @returns {boolean} true if the media type parameter exists, false otherwise.
|
|
131
|
+
* @returns {string} The event name.
|
|
171
132
|
*/
|
|
172
|
-
|
|
173
|
-
return this.#
|
|
133
|
+
get eventName() {
|
|
134
|
+
return this.#eventName;
|
|
174
135
|
}
|
|
175
136
|
/**
|
|
176
|
-
*
|
|
177
|
-
* If an parameter with the same name already exists, the parameter will be updated.
|
|
137
|
+
* Gets the context event handler.
|
|
178
138
|
*
|
|
179
|
-
* @
|
|
180
|
-
* @param {string} value The media type parameter value.
|
|
181
|
-
* @returns {MediaTypeParameters} This instance.
|
|
139
|
+
* @returns {ContextEventHandler} The context event handler
|
|
182
140
|
*/
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
value = String(value);
|
|
186
|
-
if (!solelyContainsHTTPTokenCodePoints(name)) {
|
|
187
|
-
throw new Error(`Invalid media type parameter name "${name}": only HTTP token code points are valid.`);
|
|
188
|
-
}
|
|
189
|
-
if (!solelyContainsHTTPQuotedStringTokenCodePoints(value)) {
|
|
190
|
-
throw new Error(`Invalid media type parameter value "${value}": only HTTP quoted-string token code points are valid.`);
|
|
191
|
-
}
|
|
192
|
-
this.#map.set(name, value);
|
|
193
|
-
return this;
|
|
141
|
+
get contextEventHandler() {
|
|
142
|
+
return this.#contextEventHandler;
|
|
194
143
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
144
|
+
get [Symbol.toStringTag]() {
|
|
145
|
+
return "Subscription";
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// node_modules/@d1g1tal/subscribr/src/subscribr.js
|
|
150
|
+
var Subscribr = class {
|
|
151
|
+
/** @type {SetMultiMap<string, ContextEventHandler>} */
|
|
152
|
+
#subscribers;
|
|
153
|
+
constructor() {
|
|
154
|
+
this.#subscribers = new SetMultiMap2();
|
|
200
155
|
}
|
|
201
156
|
/**
|
|
202
|
-
*
|
|
157
|
+
* Subscribe to an event
|
|
203
158
|
*
|
|
204
|
-
* @param {string}
|
|
205
|
-
* @
|
|
159
|
+
* @param {string} eventName The event name to subscribe to.
|
|
160
|
+
* @param {function(Event, *): void} eventHandler The event handler to call when the event is published.
|
|
161
|
+
* @param {*} [context] The context to bind to the event handler.
|
|
162
|
+
* @returns {Subscription} An object used to check if the subscription still exists and to unsubscribe from the event.
|
|
206
163
|
*/
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
164
|
+
subscribe(eventName, eventHandler, context = eventHandler) {
|
|
165
|
+
const contextEventHandler = new ContextEventHandler(context, eventHandler);
|
|
166
|
+
this.#subscribers.set(eventName, contextEventHandler);
|
|
167
|
+
return new Subscription(eventName, contextEventHandler);
|
|
210
168
|
}
|
|
211
169
|
/**
|
|
212
|
-
*
|
|
170
|
+
* Unsubscribe from the event
|
|
213
171
|
*
|
|
214
|
-
* @param {
|
|
215
|
-
* @param {
|
|
172
|
+
* @param {Subscription} subscription The subscription to unsubscribe.
|
|
173
|
+
* @param {string} subscription.eventName The event name to subscribe to.
|
|
174
|
+
* @param {ContextEventHandler} subscription.contextEventHandler The event handler to call when the event is published.
|
|
175
|
+
* @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.
|
|
216
176
|
*/
|
|
217
|
-
|
|
218
|
-
this.#
|
|
177
|
+
unsubscribe({ eventName, contextEventHandler }) {
|
|
178
|
+
const contextEventHandlers = this.#subscribers.get(eventName);
|
|
179
|
+
const removed = contextEventHandlers?.delete(contextEventHandler);
|
|
180
|
+
if (removed && contextEventHandlers.size == 0) {
|
|
181
|
+
this.#subscribers.delete(eventName);
|
|
182
|
+
}
|
|
183
|
+
return removed;
|
|
219
184
|
}
|
|
220
185
|
/**
|
|
221
|
-
*
|
|
186
|
+
* Publish an event
|
|
222
187
|
*
|
|
223
|
-
* @
|
|
188
|
+
* @param {string} eventName The name of the event.
|
|
189
|
+
* @param {Event} event The event to be handled.
|
|
190
|
+
* @param {*} [data] The value to be passed to the event handler as a parameter.
|
|
224
191
|
*/
|
|
225
|
-
|
|
226
|
-
|
|
192
|
+
publish(eventName, event = new CustomEvent(eventName), data) {
|
|
193
|
+
if (data == null && !(event instanceof Event)) {
|
|
194
|
+
[data, event] = [event, new CustomEvent(eventName)];
|
|
195
|
+
}
|
|
196
|
+
this.#subscribers.get(eventName)?.forEach((contextEventHandler) => contextEventHandler.handle(event, data));
|
|
227
197
|
}
|
|
228
198
|
/**
|
|
229
|
-
*
|
|
199
|
+
* Check if the event and handler are subscribed.
|
|
230
200
|
*
|
|
231
|
-
* @
|
|
201
|
+
* @param {Subscription} subscription The subscription object.
|
|
202
|
+
* @param {string} subscription.eventName The name of the event to check.
|
|
203
|
+
* @param {ContextEventHandler} subscription.contextEventHandler The event handler to check.
|
|
204
|
+
* @returns {boolean} true if the event name and handler are subscribed, false otherwise.
|
|
232
205
|
*/
|
|
233
|
-
|
|
234
|
-
return this.#
|
|
206
|
+
isSubscribed({ eventName, contextEventHandler }) {
|
|
207
|
+
return this.#subscribers.get(eventName)?.has(contextEventHandler);
|
|
235
208
|
}
|
|
209
|
+
get [Symbol.toStringTag]() {
|
|
210
|
+
return "Subscribr";
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// src/http-error.js
|
|
215
|
+
var HttpError = class extends Error {
|
|
216
|
+
/** @type {ResponseBody} */
|
|
217
|
+
#entity;
|
|
218
|
+
/** @type {ResponseStatus} */
|
|
219
|
+
#responseStatus;
|
|
236
220
|
/**
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
* @
|
|
221
|
+
* @param {string} [message] The error message.
|
|
222
|
+
* @param {HttpErrorOptions} [httpErrorOptions] The http error options.
|
|
223
|
+
* @param {any} [httpErrorOptions.cause] The cause of the error.
|
|
224
|
+
* @param {ResponseStatus} [httpErrorOptions.status] The response status.
|
|
225
|
+
* @param {ResponseBody} [httpErrorOptions.entity] The error entity from the server, if any.
|
|
240
226
|
*/
|
|
241
|
-
|
|
242
|
-
|
|
227
|
+
constructor(message, { cause, status, entity }) {
|
|
228
|
+
super(message, { cause });
|
|
229
|
+
this.#entity = entity;
|
|
230
|
+
this.#responseStatus = status;
|
|
243
231
|
}
|
|
244
232
|
/**
|
|
245
|
-
*
|
|
233
|
+
* It returns the value of the private variable #entity.
|
|
246
234
|
*
|
|
247
|
-
* @returns {
|
|
235
|
+
* @returns {ResponseBody} The entity property of the class.
|
|
248
236
|
*/
|
|
249
|
-
|
|
250
|
-
return this.#
|
|
237
|
+
get entity() {
|
|
238
|
+
return this.#entity;
|
|
251
239
|
}
|
|
252
240
|
/**
|
|
253
|
-
*
|
|
254
|
-
* This method is called by the `String()` function.
|
|
255
|
-
*
|
|
256
|
-
* @example
|
|
257
|
-
* const parameters = new MediaTypeParameters(new Map([['charset', 'utf-8']]));
|
|
258
|
-
* String(parameters); // 'charset=utf-8'
|
|
259
|
-
* parameters.toString(); // 'charset=utf-8'
|
|
260
|
-
* parameters + ''; // 'charset=utf-8'
|
|
261
|
-
* `${parameters}`; // 'charset=utf-8'
|
|
262
|
-
* parameters[Symbol.toStringTag]; // 'MediaTypeParameters'
|
|
263
|
-
* parameters[Symbol.toStringTag](); // 'MediaTypeParameters'
|
|
264
|
-
* Object.prototype.toString.call(parameters); // '[object MediaTypeParameters]'
|
|
265
|
-
* parameters + ''; // 'charset=utf-8'
|
|
266
|
-
* @returns {string} The string representation of the media type parameters.
|
|
267
|
-
*/
|
|
268
|
-
[Symbol.toStringTag]() {
|
|
269
|
-
return "MediaTypeParameters";
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
// node_modules/@d1g1tal/media-type/src/parser.js
|
|
274
|
-
var parse = (input) => {
|
|
275
|
-
input = removeLeadingAndTrailingHTTPWhitespace(input);
|
|
276
|
-
let position = 0;
|
|
277
|
-
let type = "";
|
|
278
|
-
while (position < input.length && input[position] != "/") {
|
|
279
|
-
type += input[position];
|
|
280
|
-
++position;
|
|
281
|
-
}
|
|
282
|
-
if (type.length === 0 || !solelyContainsHTTPTokenCodePoints(type)) {
|
|
283
|
-
return null;
|
|
284
|
-
}
|
|
285
|
-
if (position >= input.length) {
|
|
286
|
-
return null;
|
|
287
|
-
}
|
|
288
|
-
++position;
|
|
289
|
-
let subtype = "";
|
|
290
|
-
while (position < input.length && input[position] != ";") {
|
|
291
|
-
subtype += input[position];
|
|
292
|
-
++position;
|
|
293
|
-
}
|
|
294
|
-
subtype = removeTrailingHTTPWhitespace(subtype);
|
|
295
|
-
if (subtype.length === 0 || !solelyContainsHTTPTokenCodePoints(subtype)) {
|
|
296
|
-
return null;
|
|
297
|
-
}
|
|
298
|
-
const mediaType = {
|
|
299
|
-
type: asciiLowercase(type),
|
|
300
|
-
subtype: asciiLowercase(subtype),
|
|
301
|
-
parameters: /* @__PURE__ */ new Map()
|
|
302
|
-
};
|
|
303
|
-
while (position < input.length) {
|
|
304
|
-
++position;
|
|
305
|
-
while (isHTTPWhitespaceChar(input[position])) {
|
|
306
|
-
++position;
|
|
307
|
-
}
|
|
308
|
-
let parameterName = "";
|
|
309
|
-
while (position < input.length && input[position] != ";" && input[position] != "=") {
|
|
310
|
-
parameterName += input[position];
|
|
311
|
-
++position;
|
|
312
|
-
}
|
|
313
|
-
parameterName = asciiLowercase(parameterName);
|
|
314
|
-
if (position < input.length) {
|
|
315
|
-
if (input[position] == ";") {
|
|
316
|
-
continue;
|
|
317
|
-
}
|
|
318
|
-
++position;
|
|
319
|
-
}
|
|
320
|
-
let parameterValue = null;
|
|
321
|
-
if (input[position] == '"') {
|
|
322
|
-
[parameterValue, position] = collectAnHTTPQuotedString(input, position);
|
|
323
|
-
while (position < input.length && input[position] != ";") {
|
|
324
|
-
++position;
|
|
325
|
-
}
|
|
326
|
-
} else {
|
|
327
|
-
parameterValue = "";
|
|
328
|
-
while (position < input.length && input[position] != ";") {
|
|
329
|
-
parameterValue += input[position];
|
|
330
|
-
++position;
|
|
331
|
-
}
|
|
332
|
-
parameterValue = removeTrailingHTTPWhitespace(parameterValue);
|
|
333
|
-
if (parameterValue === "") {
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
if (parameterName.length > 0 && solelyContainsHTTPTokenCodePoints(parameterName) && solelyContainsHTTPQuotedStringTokenCodePoints(parameterValue) && !mediaType.parameters.has(parameterName)) {
|
|
338
|
-
mediaType.parameters.set(parameterName, parameterValue);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
return mediaType;
|
|
342
|
-
};
|
|
343
|
-
var parser_default = parse;
|
|
344
|
-
|
|
345
|
-
// node_modules/@d1g1tal/media-type/src/serializer.js
|
|
346
|
-
var serialize = (mediaType) => {
|
|
347
|
-
let serialization = `${mediaType.type}/${mediaType.subtype}`;
|
|
348
|
-
if (mediaType.parameters.size === 0) {
|
|
349
|
-
return serialization;
|
|
350
|
-
}
|
|
351
|
-
for (let [name, value] of mediaType.parameters) {
|
|
352
|
-
serialization += `;${name}=`;
|
|
353
|
-
if (!solelyContainsHTTPTokenCodePoints(value) || value.length === 0) {
|
|
354
|
-
value = `"${value.replace(/(["\\])/ug, "\\$1")}"`;
|
|
355
|
-
}
|
|
356
|
-
serialization += value;
|
|
357
|
-
}
|
|
358
|
-
return serialization;
|
|
359
|
-
};
|
|
360
|
-
var serializer_default = serialize;
|
|
361
|
-
|
|
362
|
-
// node_modules/@d1g1tal/media-type/src/media-type.js
|
|
363
|
-
var MediaType = class _MediaType {
|
|
364
|
-
/** @type {string} */
|
|
365
|
-
#type;
|
|
366
|
-
/** @type {string} */
|
|
367
|
-
#subtype;
|
|
368
|
-
/** @type {MediaTypeParameters} */
|
|
369
|
-
#parameters;
|
|
370
|
-
/**
|
|
371
|
-
* Create a new MediaType instance from a string representation.
|
|
372
|
-
*
|
|
373
|
-
* @param {string} mediaType The media type to parse.
|
|
374
|
-
* @param {Object} [parameters] Optional parameters.
|
|
375
|
-
*/
|
|
376
|
-
constructor(mediaType, parameters = {}) {
|
|
377
|
-
const { type, subtype, parameters: parsedParameters } = parser_default(mediaType);
|
|
378
|
-
this.#type = type;
|
|
379
|
-
this.#subtype = subtype;
|
|
380
|
-
this.#parameters = new MediaTypeParameters([...parsedParameters, ...Object.entries(parameters).map(([name, value]) => [asciiLowercase(name), asciiLowercase(value)])]);
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Static factory method for parsing a media type.
|
|
384
|
-
*
|
|
385
|
-
* @param {string} string The media type to parse.
|
|
386
|
-
* @returns {MediaType} The parsed {@link MediaType} object or null if the string could not be parsed.
|
|
387
|
-
*/
|
|
388
|
-
static parse(string) {
|
|
389
|
-
try {
|
|
390
|
-
return new _MediaType(string);
|
|
391
|
-
} catch (e) {
|
|
392
|
-
throw new Error(`Could not parse media type string '${string}'`);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Gets the media type essence (type/subtype).
|
|
397
|
-
*
|
|
398
|
-
* @returns {string} The media type without any parameters
|
|
399
|
-
*/
|
|
400
|
-
get essence() {
|
|
401
|
-
return `${this.#type}/${this.#subtype}`;
|
|
402
|
-
}
|
|
403
|
-
/**
|
|
404
|
-
* Gets the type.
|
|
405
|
-
*
|
|
406
|
-
* @returns {string} The type.
|
|
407
|
-
*/
|
|
408
|
-
get type() {
|
|
409
|
-
return this.#type;
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Sets the type.
|
|
413
|
-
*/
|
|
414
|
-
set type(value) {
|
|
415
|
-
value = asciiLowercase(String(value));
|
|
416
|
-
if (value.length === 0) {
|
|
417
|
-
throw new Error("Invalid type: must be a non-empty string");
|
|
418
|
-
}
|
|
419
|
-
if (!solelyContainsHTTPTokenCodePoints(value)) {
|
|
420
|
-
throw new Error(`Invalid type ${value}: must contain only HTTP token code points`);
|
|
421
|
-
}
|
|
422
|
-
this.#type = value;
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Gets the subtype.
|
|
426
|
-
*
|
|
427
|
-
* @returns {string} The subtype.
|
|
428
|
-
*/
|
|
429
|
-
get subtype() {
|
|
430
|
-
return this.#subtype;
|
|
431
|
-
}
|
|
432
|
-
/**
|
|
433
|
-
* Sets the subtype.
|
|
434
|
-
*/
|
|
435
|
-
set subtype(value) {
|
|
436
|
-
value = asciiLowercase(String(value));
|
|
437
|
-
if (value.length === 0) {
|
|
438
|
-
throw new Error("Invalid subtype: must be a non-empty string");
|
|
439
|
-
}
|
|
440
|
-
if (!solelyContainsHTTPTokenCodePoints(value)) {
|
|
441
|
-
throw new Error(`Invalid subtype ${value}: must contain only HTTP token code points`);
|
|
442
|
-
}
|
|
443
|
-
this.#subtype = value;
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* Gets the parameters.
|
|
447
|
-
*
|
|
448
|
-
* @returns {MediaTypeParameters} The media type parameters.
|
|
449
|
-
*/
|
|
450
|
-
get parameters() {
|
|
451
|
-
return this.#parameters;
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* Gets the serialized version of the media type.
|
|
455
|
-
*
|
|
456
|
-
* @returns {string} The serialized media type.
|
|
457
|
-
*/
|
|
458
|
-
toString() {
|
|
459
|
-
return serializer_default(this);
|
|
460
|
-
}
|
|
461
|
-
/**
|
|
462
|
-
* Determines if this instance is a JavaScript media type.
|
|
463
|
-
*
|
|
464
|
-
* @param {Object} [options] Optional options.
|
|
465
|
-
* @param {boolean} [options.prohibitParameters=false] The option to prohibit parameters when checking if the media type is JavaScript.
|
|
466
|
-
* @returns {boolean} true if this instance represents a JavaScript media type, false otherwise.
|
|
467
|
-
*/
|
|
468
|
-
isJavaScript({ prohibitParameters = false } = {}) {
|
|
469
|
-
switch (this.#type) {
|
|
470
|
-
case "text": {
|
|
471
|
-
switch (this.#subtype) {
|
|
472
|
-
case "ecmascript":
|
|
473
|
-
case "javascript":
|
|
474
|
-
case "javascript1.0":
|
|
475
|
-
case "javascript1.1":
|
|
476
|
-
case "javascript1.2":
|
|
477
|
-
case "javascript1.3":
|
|
478
|
-
case "javascript1.4":
|
|
479
|
-
case "javascript1.5":
|
|
480
|
-
case "jscript":
|
|
481
|
-
case "livescript":
|
|
482
|
-
case "x-ecmascript":
|
|
483
|
-
case "x-javascript":
|
|
484
|
-
return !prohibitParameters || this.#parameters.size === 0;
|
|
485
|
-
default:
|
|
486
|
-
return false;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
case "application": {
|
|
490
|
-
switch (this.#subtype) {
|
|
491
|
-
case "ecmascript":
|
|
492
|
-
case "javascript":
|
|
493
|
-
case "x-ecmascript":
|
|
494
|
-
case "x-javascript":
|
|
495
|
-
return !prohibitParameters || this.#parameters.size === 0;
|
|
496
|
-
default:
|
|
497
|
-
return false;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
default:
|
|
501
|
-
return false;
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
/**
|
|
505
|
-
* Determines if this instance is an XML media type.
|
|
506
|
-
*
|
|
507
|
-
* @returns {boolean} true if this instance represents an XML media type, false otherwise.
|
|
508
|
-
*/
|
|
509
|
-
isXML() {
|
|
510
|
-
return this.#subtype === "xml" && (this.#type === "text" || this.#type === "application") || this.#subtype.endsWith("+xml");
|
|
511
|
-
}
|
|
512
|
-
/**
|
|
513
|
-
* Determines if this instance is an HTML media type.
|
|
514
|
-
*
|
|
515
|
-
* @returns {boolean} true if this instance represents an HTML media type, false otherwise.
|
|
516
|
-
*/
|
|
517
|
-
isHTML() {
|
|
518
|
-
return this.#subtype === "html" && this.#type === "text";
|
|
519
|
-
}
|
|
520
|
-
/**
|
|
521
|
-
* Gets the name of the class.
|
|
522
|
-
*
|
|
523
|
-
* @returns {string} The class name
|
|
524
|
-
*/
|
|
525
|
-
get [Symbol.toStringTag]() {
|
|
526
|
-
return "MediaType";
|
|
527
|
-
}
|
|
528
|
-
};
|
|
529
|
-
|
|
530
|
-
// node_modules/@d1g1tal/subscribr/node_modules/@d1g1tal/collections/src/set-multi-map.js
|
|
531
|
-
var SetMultiMap2 = class extends Map {
|
|
532
|
-
/**
|
|
533
|
-
* Adds a new element with a specified key and value to the SetMultiMap. If an element with the same key already exists, the value will be added to the underlying {@link Set}.
|
|
534
|
-
*
|
|
535
|
-
* @param {*} key The key to set.
|
|
536
|
-
* @param {*} value The value to add to the SetMultiMap
|
|
537
|
-
* @returns {SetMultiMap} The SetMultiMap with the updated key and value.
|
|
538
|
-
*/
|
|
539
|
-
set(key, value) {
|
|
540
|
-
super.set(key, (super.get(key) ?? /* @__PURE__ */ new Set()).add(value));
|
|
541
|
-
return this;
|
|
542
|
-
}
|
|
543
|
-
[Symbol.toStringTag]() {
|
|
544
|
-
return "SetMultiMap";
|
|
545
|
-
}
|
|
546
|
-
};
|
|
547
|
-
|
|
548
|
-
// node_modules/@d1g1tal/subscribr/src/context-event-handler.js
|
|
549
|
-
var ContextEventHandler = class {
|
|
550
|
-
#context;
|
|
551
|
-
#eventHandler;
|
|
552
|
-
/**
|
|
553
|
-
* @param {*} context The context to bind to the event handler.
|
|
554
|
-
* @param {function(*): void} eventHandler The event handler to call when the event is published.
|
|
555
|
-
*/
|
|
556
|
-
constructor(context, eventHandler) {
|
|
557
|
-
this.#context = context;
|
|
558
|
-
this.#eventHandler = eventHandler;
|
|
559
|
-
}
|
|
560
|
-
/**
|
|
561
|
-
* Call the event handler for the provided event.
|
|
562
|
-
*
|
|
563
|
-
* @param {Event} event The event to handle
|
|
564
|
-
* @param {*} [data] The value to be passed to the event handler as a parameter.
|
|
565
|
-
*/
|
|
566
|
-
handle(event, data) {
|
|
567
|
-
this.#eventHandler.call(this.#context, event, data);
|
|
568
|
-
}
|
|
569
|
-
get [Symbol.toStringTag]() {
|
|
570
|
-
return "ContextEventHandler";
|
|
571
|
-
}
|
|
572
|
-
};
|
|
573
|
-
|
|
574
|
-
// node_modules/@d1g1tal/subscribr/src/subscription.js
|
|
575
|
-
var Subscription = class {
|
|
576
|
-
#eventName;
|
|
577
|
-
#contextEventHandler;
|
|
578
|
-
/**
|
|
579
|
-
* @param {string} eventName The event name.
|
|
580
|
-
* @param {ContextEventHandler} contextEventHandler Then context event handler.
|
|
581
|
-
*/
|
|
582
|
-
constructor(eventName, contextEventHandler) {
|
|
583
|
-
this.#eventName = eventName;
|
|
584
|
-
this.#contextEventHandler = contextEventHandler;
|
|
585
|
-
}
|
|
586
|
-
/**
|
|
587
|
-
* Gets the event name for the subscription.
|
|
588
|
-
*
|
|
589
|
-
* @returns {string} The event name.
|
|
590
|
-
*/
|
|
591
|
-
get eventName() {
|
|
592
|
-
return this.#eventName;
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* Gets the context event handler.
|
|
596
|
-
*
|
|
597
|
-
* @returns {ContextEventHandler} The context event handler
|
|
598
|
-
*/
|
|
599
|
-
get contextEventHandler() {
|
|
600
|
-
return this.#contextEventHandler;
|
|
601
|
-
}
|
|
602
|
-
get [Symbol.toStringTag]() {
|
|
603
|
-
return "Subscription";
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
|
-
|
|
607
|
-
// node_modules/@d1g1tal/subscribr/src/subscribr.js
|
|
608
|
-
var Subscribr = class {
|
|
609
|
-
/** @type {SetMultiMap<string, ContextEventHandler>} */
|
|
610
|
-
#subscribers;
|
|
611
|
-
constructor() {
|
|
612
|
-
this.#subscribers = new SetMultiMap2();
|
|
613
|
-
}
|
|
614
|
-
/**
|
|
615
|
-
* Subscribe to an event
|
|
616
|
-
*
|
|
617
|
-
* @param {string} eventName The event name to subscribe to.
|
|
618
|
-
* @param {function(Event, *): void} eventHandler The event handler to call when the event is published.
|
|
619
|
-
* @param {*} [context] The context to bind to the event handler.
|
|
620
|
-
* @returns {Subscription} An object used to check if the subscription still exists and to unsubscribe from the event.
|
|
621
|
-
*/
|
|
622
|
-
subscribe(eventName, eventHandler, context = eventHandler) {
|
|
623
|
-
const contextEventHandler = new ContextEventHandler(context, eventHandler);
|
|
624
|
-
this.#subscribers.set(eventName, contextEventHandler);
|
|
625
|
-
return new Subscription(eventName, contextEventHandler);
|
|
626
|
-
}
|
|
627
|
-
/**
|
|
628
|
-
* Unsubscribe from the event
|
|
629
|
-
*
|
|
630
|
-
* @param {Subscription} subscription The subscription to unsubscribe.
|
|
631
|
-
* @param {string} subscription.eventName The event name to subscribe to.
|
|
632
|
-
* @param {ContextEventHandler} subscription.contextEventHandler The event handler to call when the event is published.
|
|
633
|
-
* @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.
|
|
634
|
-
*/
|
|
635
|
-
unsubscribe({ eventName, contextEventHandler }) {
|
|
636
|
-
const contextEventHandlers = this.#subscribers.get(eventName);
|
|
637
|
-
const removed = contextEventHandlers?.delete(contextEventHandler);
|
|
638
|
-
if (removed && contextEventHandlers.size == 0) {
|
|
639
|
-
this.#subscribers.delete(eventName);
|
|
640
|
-
}
|
|
641
|
-
return removed;
|
|
642
|
-
}
|
|
643
|
-
/**
|
|
644
|
-
* Publish an event
|
|
645
|
-
*
|
|
646
|
-
* @param {string} eventName The name of the event.
|
|
647
|
-
* @param {Event} event The event to be handled.
|
|
648
|
-
* @param {*} [data] The value to be passed to the event handler as a parameter.
|
|
649
|
-
*/
|
|
650
|
-
publish(eventName, event = new CustomEvent(eventName), data) {
|
|
651
|
-
if (data == null && !(event instanceof Event)) {
|
|
652
|
-
[data, event] = [event, new CustomEvent(eventName)];
|
|
653
|
-
}
|
|
654
|
-
this.#subscribers.get(eventName)?.forEach((contextEventHandler) => contextEventHandler.handle(event, data));
|
|
655
|
-
}
|
|
656
|
-
/**
|
|
657
|
-
* Check if the event and handler are subscribed.
|
|
658
|
-
*
|
|
659
|
-
* @param {Subscription} subscription The subscription object.
|
|
660
|
-
* @param {string} subscription.eventName The name of the event to check.
|
|
661
|
-
* @param {ContextEventHandler} subscription.contextEventHandler The event handler to check.
|
|
662
|
-
* @returns {boolean} true if the event name and handler are subscribed, false otherwise.
|
|
663
|
-
*/
|
|
664
|
-
isSubscribed({ eventName, contextEventHandler }) {
|
|
665
|
-
return this.#subscribers.get(eventName)?.has(contextEventHandler);
|
|
666
|
-
}
|
|
667
|
-
get [Symbol.toStringTag]() {
|
|
668
|
-
return "Subscribr";
|
|
669
|
-
}
|
|
670
|
-
};
|
|
671
|
-
|
|
672
|
-
// src/http-error.js
|
|
673
|
-
var HttpError = class extends Error {
|
|
674
|
-
/** @type {ResponseBody} */
|
|
675
|
-
#entity;
|
|
676
|
-
/** @type {ResponseStatus} */
|
|
677
|
-
#responseStatus;
|
|
678
|
-
/**
|
|
679
|
-
* @param {string} [message] The error message.
|
|
680
|
-
* @param {HttpErrorOptions} [httpErrorOptions] The http error options.
|
|
681
|
-
* @param {any} [httpErrorOptions.cause] The cause of the error.
|
|
682
|
-
* @param {ResponseStatus} [httpErrorOptions.status] The response status.
|
|
683
|
-
* @param {ResponseBody} [httpErrorOptions.entity] The error entity from the server, if any.
|
|
684
|
-
*/
|
|
685
|
-
constructor(message, { cause, status, entity }) {
|
|
686
|
-
super(message, { cause });
|
|
687
|
-
this.#entity = entity;
|
|
688
|
-
this.#responseStatus = status;
|
|
689
|
-
}
|
|
690
|
-
/**
|
|
691
|
-
* It returns the value of the private variable #entity.
|
|
692
|
-
*
|
|
693
|
-
* @returns {ResponseBody} The entity property of the class.
|
|
694
|
-
*/
|
|
695
|
-
get entity() {
|
|
696
|
-
return this.#entity;
|
|
697
|
-
}
|
|
698
|
-
/**
|
|
699
|
-
* It returns the status code of the {@link Response}.
|
|
241
|
+
* It returns the status code of the {@link Response}.
|
|
700
242
|
*
|
|
701
243
|
* @returns {number} The status code of the {@link Response}.
|
|
702
244
|
*/
|
|
@@ -783,6 +325,8 @@ var Transportr = (() => {
|
|
|
783
325
|
JSON: "application/json",
|
|
784
326
|
/** JavaScript Object Notation LD Format */
|
|
785
327
|
JSON_LD: "application/ld+json",
|
|
328
|
+
/** JavaScript Object Notation (JSON) Merge Patch */
|
|
329
|
+
JSON_MERGE_PATCH: "application/merge-patch+json",
|
|
786
330
|
/** Musical Instrument Digital Interface (MIDI) */
|
|
787
331
|
MID: "audio/midi",
|
|
788
332
|
/** Musical Instrument Digital Interface (MIDI) */
|
|
@@ -1465,452 +1009,1228 @@ var Transportr = (() => {
|
|
|
1465
1009
|
* Implemented as a misunderstanding of the HTTP specifications. Common because of mistakes in implementations of early HTTP versions. Has exactly the same functionality as standard Connection field.
|
|
1466
1010
|
*
|
|
1467
1011
|
* @example
|
|
1468
|
-
* proxy-connection: keep-alive
|
|
1012
|
+
* proxy-connection: keep-alive
|
|
1013
|
+
*/
|
|
1014
|
+
PROXY_CONNECTION: "proxy-connection",
|
|
1015
|
+
/**
|
|
1016
|
+
* Server-side deep packet insertion of a unique ID identifying customers of Verizon Wireless, also known as "perma-cookie" or "supercookie"
|
|
1017
|
+
*
|
|
1018
|
+
* @example
|
|
1019
|
+
* x-uidh: ...
|
|
1020
|
+
*/
|
|
1021
|
+
X_UIDH: "x-uidh",
|
|
1022
|
+
/**
|
|
1023
|
+
* Used to prevent cross-site request forgery. Alternative header names are: X-CSRFToken and X-XSRF-TOKEN
|
|
1024
|
+
*
|
|
1025
|
+
* @example
|
|
1026
|
+
* x-csrf-token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
|
|
1027
|
+
*/
|
|
1028
|
+
X_CSRF_TOKEN: "x-csrf-token",
|
|
1029
|
+
/**
|
|
1030
|
+
* Specifying which web sites can participate in cross-origin resource sharing
|
|
1031
|
+
*
|
|
1032
|
+
* @example
|
|
1033
|
+
* access-control-allow-origin: *
|
|
1034
|
+
* Provisional
|
|
1035
|
+
*/
|
|
1036
|
+
ACCESS_CONTROL_ALLOW_ORIGIN: "access-control-allow-origin",
|
|
1037
|
+
/**
|
|
1038
|
+
* Specifies which patch document formats this server supports
|
|
1039
|
+
*
|
|
1040
|
+
* @example
|
|
1041
|
+
* accept-patch: text/example,charset=utf-8
|
|
1042
|
+
* Permanent
|
|
1043
|
+
*/
|
|
1044
|
+
ACCEPT_PATCH: "accept-patch",
|
|
1045
|
+
/**
|
|
1046
|
+
* What partial content range types this server supports via byte serving
|
|
1047
|
+
*
|
|
1048
|
+
* @example
|
|
1049
|
+
* accept-ranges: bytes
|
|
1050
|
+
* Permanent
|
|
1051
|
+
*/
|
|
1052
|
+
ACCEPT_RANGES: "accept-ranges",
|
|
1053
|
+
/**
|
|
1054
|
+
* The age the object has been in a proxy cache in seconds
|
|
1055
|
+
*
|
|
1056
|
+
* @example
|
|
1057
|
+
* age: 12
|
|
1058
|
+
* Permanent
|
|
1059
|
+
*/
|
|
1060
|
+
AGE: "age",
|
|
1061
|
+
/**
|
|
1062
|
+
* Valid actions for a specified resource. To be used for a 405 Method not allowed
|
|
1063
|
+
*
|
|
1064
|
+
* @example
|
|
1065
|
+
* allow: GET, HEAD
|
|
1066
|
+
* Permanent
|
|
1067
|
+
*/
|
|
1068
|
+
ALLOW: "allow",
|
|
1069
|
+
/**
|
|
1070
|
+
* Tells all caching mechanisms from server to client whether they may cache this object. It is measured in seconds
|
|
1071
|
+
*
|
|
1072
|
+
* @example
|
|
1073
|
+
* cache-control: max-age=3600
|
|
1074
|
+
* Permanent
|
|
1075
|
+
*/
|
|
1076
|
+
CACHE_CONTROL: "cache-control",
|
|
1077
|
+
/**
|
|
1078
|
+
* Control options for the current connection and list of hop-by-hop response fields
|
|
1079
|
+
*
|
|
1080
|
+
* @example
|
|
1081
|
+
* connection: close
|
|
1082
|
+
* Permanent
|
|
1083
|
+
*/
|
|
1084
|
+
CONNECTION: "connection",
|
|
1085
|
+
/**
|
|
1086
|
+
* An opportunity to raise a "File Download" dialogue box for a known MIME type with binary format or suggest a filename for dynamic content. Quotes are necessary with special characters.
|
|
1087
|
+
*
|
|
1088
|
+
* @example
|
|
1089
|
+
* content-disposition: attachment, filename="fname.ext"
|
|
1090
|
+
* Permanent
|
|
1091
|
+
*/
|
|
1092
|
+
CONTENT_DISPOSITION: "content-disposition",
|
|
1093
|
+
/**
|
|
1094
|
+
* The type of encoding used on the data. See HTTP compression.
|
|
1095
|
+
*
|
|
1096
|
+
* @example
|
|
1097
|
+
* content-encoding: gzip
|
|
1098
|
+
* Permanent
|
|
1099
|
+
*/
|
|
1100
|
+
CONTENT_ENCODING: "content-encoding",
|
|
1101
|
+
/**
|
|
1102
|
+
* The natural language or languages of the intended audience for the enclosed content
|
|
1103
|
+
*
|
|
1104
|
+
* @example
|
|
1105
|
+
* content-language: da
|
|
1106
|
+
* Permanent
|
|
1107
|
+
*/
|
|
1108
|
+
CONTENT_LANGUAGE: "content-language",
|
|
1109
|
+
/**
|
|
1110
|
+
* The length of the response body in octets (8-bit bytes)
|
|
1111
|
+
*
|
|
1112
|
+
* @example
|
|
1113
|
+
* content-length: 348
|
|
1114
|
+
* Permanent
|
|
1115
|
+
*/
|
|
1116
|
+
CONTENT_LENGTH: "content-length",
|
|
1117
|
+
/**
|
|
1118
|
+
* An alternate location for the returned data
|
|
1119
|
+
*
|
|
1120
|
+
* @example
|
|
1121
|
+
* content-location: /index.htm
|
|
1122
|
+
* Permanent
|
|
1123
|
+
*/
|
|
1124
|
+
CONTENT_LOCATION: "content-location",
|
|
1125
|
+
/**
|
|
1126
|
+
* Where in a full body message this partial message belongs
|
|
1127
|
+
*
|
|
1128
|
+
* @example
|
|
1129
|
+
* content-range: bytes 21010-47021/47022
|
|
1130
|
+
* Permanent
|
|
1131
|
+
*/
|
|
1132
|
+
CONTENT_RANGE: "content-range",
|
|
1133
|
+
/**
|
|
1134
|
+
* The MIME type of this content
|
|
1135
|
+
*
|
|
1136
|
+
* @example
|
|
1137
|
+
* content-type: text/html, charset=utf-8
|
|
1138
|
+
* Permanent
|
|
1139
|
+
*/
|
|
1140
|
+
CONTENT_TYPE: "content-type",
|
|
1141
|
+
/**
|
|
1142
|
+
* The date and time that the message was sent (in "HTTP-date" format as defined by RFC 7231)
|
|
1143
|
+
*
|
|
1144
|
+
* @example
|
|
1145
|
+
* date: Tue, 15 Nov 1994 08:12:31 GMT
|
|
1146
|
+
* Permanent
|
|
1147
|
+
*/
|
|
1148
|
+
DATE: "date",
|
|
1149
|
+
/**
|
|
1150
|
+
* An identifier for a specific version of a resource, often a message digest
|
|
1151
|
+
*
|
|
1152
|
+
* @example
|
|
1153
|
+
* etag: "737060cd8c284d8af7ad3082f209582d"
|
|
1154
|
+
* Permanent
|
|
1155
|
+
*/
|
|
1156
|
+
ETAG: "etag",
|
|
1157
|
+
/**
|
|
1158
|
+
* Gives the date/time after which the response is considered stale (in "HTTP-date" format as defined by RFC 7231)
|
|
1159
|
+
*
|
|
1160
|
+
* @example
|
|
1161
|
+
* expires: Thu, 01 Dec 1994 16:00:00 GMT
|
|
1162
|
+
* Permanent
|
|
1163
|
+
*/
|
|
1164
|
+
EXPIRES: "expires",
|
|
1165
|
+
/**
|
|
1166
|
+
* The last modified date for the requested object (in "HTTP-date" format as defined by RFC 7231)
|
|
1167
|
+
*
|
|
1168
|
+
* @example
|
|
1169
|
+
* last-modified: Tue, 15 Nov 1994 12:45:26 GMT
|
|
1170
|
+
* Permanent
|
|
1171
|
+
*/
|
|
1172
|
+
LAST_MODIFIED: "last-modified",
|
|
1173
|
+
/**
|
|
1174
|
+
* Used to express a typed relationship with another resource, where the relation type is defined by RFC 5988
|
|
1175
|
+
*
|
|
1176
|
+
* @example
|
|
1177
|
+
* link: </feed>, rel="alternate"
|
|
1178
|
+
* Permanent
|
|
1179
|
+
*/
|
|
1180
|
+
LINK: "link",
|
|
1181
|
+
/**
|
|
1182
|
+
* Used in redirection, or when a new resource has been created.
|
|
1183
|
+
*
|
|
1184
|
+
* @example
|
|
1185
|
+
* location: http://www.w3.org/pub/WWW/People.html
|
|
1186
|
+
* Permanent
|
|
1187
|
+
*/
|
|
1188
|
+
LOCATION: "location",
|
|
1189
|
+
/**
|
|
1190
|
+
* This field is supposed to set P3P policy, in the form of P3P:CP="your_compact_policy". However, P3P did not take off, most browsers have never fully
|
|
1191
|
+
* implemented it, a lot of websites set this field with fake policy text, that was enough to fool browsers the existence of P3P policy and grant permissions for third party cookies.
|
|
1192
|
+
*
|
|
1193
|
+
* @example
|
|
1194
|
+
* p3p: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
|
|
1195
|
+
* Permanent
|
|
1196
|
+
*/
|
|
1197
|
+
P3P: "p3p",
|
|
1198
|
+
/**
|
|
1199
|
+
* Implementation-specific fields that may have various effects anywhere along the request-response chain.
|
|
1200
|
+
*
|
|
1201
|
+
* @example
|
|
1202
|
+
* pragma: no-cache
|
|
1203
|
+
* Permanent
|
|
1204
|
+
*/
|
|
1205
|
+
PRAGMA: "pragma",
|
|
1206
|
+
/**
|
|
1207
|
+
* Request authentication to access the proxy.
|
|
1208
|
+
*
|
|
1209
|
+
* @example
|
|
1210
|
+
* proxy-authenticate: Basic
|
|
1211
|
+
* Permanent
|
|
1212
|
+
*/
|
|
1213
|
+
PROXY_AUTHENTICATION: "proxy-authenticate",
|
|
1214
|
+
/**
|
|
1215
|
+
* HTTP Public Key Pinning, announces hash of website's authentic TLS certificate
|
|
1216
|
+
*
|
|
1217
|
+
* @example
|
|
1218
|
+
* public-key-pins: max-age=2592000, pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=",
|
|
1219
|
+
* Permanent
|
|
1220
|
+
*/
|
|
1221
|
+
PUBLIC_KEY_PINS: "public-key-pins",
|
|
1222
|
+
/**
|
|
1223
|
+
* If an entity is temporarily unavailable, this instructs the client to try again later. Value could be a specified period of time (in seconds) or a HTTP-date.
|
|
1224
|
+
*
|
|
1225
|
+
* @example
|
|
1226
|
+
* retry-after: 120
|
|
1227
|
+
* retry-after: Fri, 07 Nov 2014 23:59:59 GMT
|
|
1228
|
+
* Permanent
|
|
1229
|
+
*/
|
|
1230
|
+
RETRY_AFTER: "retry-after",
|
|
1231
|
+
/**
|
|
1232
|
+
* A name for the server
|
|
1233
|
+
*
|
|
1234
|
+
* @example
|
|
1235
|
+
* server: Apache/2.4.1 (Unix)
|
|
1236
|
+
* Permanent
|
|
1237
|
+
*/
|
|
1238
|
+
SERVER: "server",
|
|
1239
|
+
/**
|
|
1240
|
+
* An HTTP cookie
|
|
1241
|
+
*
|
|
1242
|
+
* @example
|
|
1243
|
+
* set-cookie: UserID=JohnDoe, Max-Age=3600, Version=1
|
|
1244
|
+
* Permanent
|
|
1245
|
+
*/
|
|
1246
|
+
SET_COOKIE: "set-cookie",
|
|
1247
|
+
/**
|
|
1248
|
+
* CGI header field specifying the status of the HTTP response. Normal HTTP responses use a separate "Status-Line" instead, defined by RFC 7230.
|
|
1249
|
+
*
|
|
1250
|
+
* @example
|
|
1251
|
+
* status: 200 OK
|
|
1469
1252
|
*/
|
|
1470
|
-
|
|
1253
|
+
STATUS: "status",
|
|
1471
1254
|
/**
|
|
1472
|
-
*
|
|
1255
|
+
* A HSTS Policy informing the HTTP client how long to cache the HTTPS only policy and whether this applies to subdomains.
|
|
1473
1256
|
*
|
|
1474
1257
|
* @example
|
|
1475
|
-
*
|
|
1258
|
+
* strict-transport-security: max-age=16070400, includeSubDomains
|
|
1259
|
+
* Permanent
|
|
1476
1260
|
*/
|
|
1477
|
-
|
|
1261
|
+
STRICT_TRANSPORT_SECURITY: "strict-transport-security",
|
|
1478
1262
|
/**
|
|
1479
|
-
*
|
|
1263
|
+
* The Trailer general field value indicates that the given set of header fields is present in the trailer of a message encoded with chunked transfer coding.
|
|
1480
1264
|
*
|
|
1481
1265
|
* @example
|
|
1482
|
-
*
|
|
1266
|
+
* trailer: Max-Forwards
|
|
1267
|
+
* Permanent
|
|
1483
1268
|
*/
|
|
1484
|
-
|
|
1269
|
+
TRAILER: "trailer",
|
|
1485
1270
|
/**
|
|
1486
|
-
*
|
|
1271
|
+
* The form of encoding used to safely transfer the entity to the user. Currently defined methods are: chunked, compress, deflate, gzip, identity.
|
|
1487
1272
|
*
|
|
1488
1273
|
* @example
|
|
1489
|
-
*
|
|
1490
|
-
*
|
|
1274
|
+
* transfer-encoding: chunked
|
|
1275
|
+
* Permanent
|
|
1491
1276
|
*/
|
|
1492
|
-
|
|
1277
|
+
TRANSFER_ENCODING: "transfer-encoding",
|
|
1493
1278
|
/**
|
|
1494
|
-
*
|
|
1279
|
+
* Ask the client to upgrade to another protocol.
|
|
1495
1280
|
*
|
|
1496
1281
|
* @example
|
|
1497
|
-
*
|
|
1282
|
+
* upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
|
|
1498
1283
|
* Permanent
|
|
1499
1284
|
*/
|
|
1500
|
-
|
|
1285
|
+
UPGRADE: "upgrade",
|
|
1501
1286
|
/**
|
|
1502
|
-
*
|
|
1287
|
+
* Tells downstream proxies how to match future request headers to decide whether the cached response can be used rather than requesting a fresh one from the origin server.
|
|
1503
1288
|
*
|
|
1504
1289
|
* @example
|
|
1505
|
-
*
|
|
1290
|
+
* vary: *
|
|
1506
1291
|
* Permanent
|
|
1507
1292
|
*/
|
|
1508
|
-
|
|
1293
|
+
VARY: "vary",
|
|
1509
1294
|
/**
|
|
1510
|
-
*
|
|
1295
|
+
* Informs the client of proxies through which the response was sent.
|
|
1511
1296
|
*
|
|
1512
1297
|
* @example
|
|
1513
|
-
*
|
|
1298
|
+
* via: 1.0 fred, 1.1 example.com (Apache/1.1)
|
|
1514
1299
|
* Permanent
|
|
1515
1300
|
*/
|
|
1516
|
-
|
|
1301
|
+
VIA: "via",
|
|
1517
1302
|
/**
|
|
1518
|
-
*
|
|
1303
|
+
* A general warning about possible problems with the entity body.
|
|
1519
1304
|
*
|
|
1520
1305
|
* @example
|
|
1521
|
-
*
|
|
1306
|
+
* warning: 199 Miscellaneous warning
|
|
1522
1307
|
* Permanent
|
|
1523
1308
|
*/
|
|
1524
|
-
|
|
1309
|
+
WARNING: "warning",
|
|
1525
1310
|
/**
|
|
1526
|
-
*
|
|
1311
|
+
* Indicates the authentication scheme that should be used to access the requested entity.
|
|
1527
1312
|
*
|
|
1528
1313
|
* @example
|
|
1529
|
-
*
|
|
1314
|
+
* www-authenticate: Basic
|
|
1530
1315
|
* Permanent
|
|
1531
1316
|
*/
|
|
1532
|
-
|
|
1317
|
+
WWW_AUTHENTICATE: "www-authenticate",
|
|
1533
1318
|
/**
|
|
1534
|
-
*
|
|
1319
|
+
* Cross-site scripting (XSS) filter
|
|
1535
1320
|
*
|
|
1536
1321
|
* @example
|
|
1537
|
-
*
|
|
1538
|
-
* Permanent
|
|
1322
|
+
* x-xss-protection: 1, mode=block
|
|
1539
1323
|
*/
|
|
1540
|
-
|
|
1324
|
+
X_XSS_PROTECTION: "x-xss-protection",
|
|
1541
1325
|
/**
|
|
1542
|
-
*
|
|
1326
|
+
* The HTTP Content-Security-Policy response header allows web site administrators to control resources the user agent is allowed
|
|
1327
|
+
* to load for a given page. With a few exceptions, policies mostly involve specifying server origins and script endpoints.
|
|
1328
|
+
* This helps guard against cross-site scripting attacks (Cross-site_scripting).
|
|
1543
1329
|
*
|
|
1544
1330
|
* @example
|
|
1545
|
-
* content-
|
|
1546
|
-
* Permanent
|
|
1331
|
+
* content-security-policy: default-src
|
|
1547
1332
|
*/
|
|
1548
|
-
|
|
1333
|
+
CONTENT_SECURITY_POLICY: "content-security-policy",
|
|
1549
1334
|
/**
|
|
1550
|
-
* The
|
|
1335
|
+
* The only defined value, "nosniff", prevents Internet Explorer from MIME-sniffing a response away from the declared content-type. This also applies to Google Chrome, when downloading extensions.
|
|
1551
1336
|
*
|
|
1552
1337
|
* @example
|
|
1553
|
-
* content-
|
|
1554
|
-
* Permanent
|
|
1338
|
+
* x-content-type-options: nosniff
|
|
1555
1339
|
*/
|
|
1556
|
-
|
|
1340
|
+
X_CONTENT_TYPE_OPTIONS: "x-content-type-options",
|
|
1557
1341
|
/**
|
|
1558
|
-
*
|
|
1342
|
+
* specifies the technology (e.g. ASP.NET, PHP, JBoss) supporting the web application (version details are often in X-Runtime, X-Version, or X-AspNet-Version)
|
|
1559
1343
|
*
|
|
1560
1344
|
* @example
|
|
1561
|
-
*
|
|
1562
|
-
* Permanent
|
|
1345
|
+
* x-powered-by: PHP/5.4.0
|
|
1563
1346
|
*/
|
|
1564
|
-
|
|
1347
|
+
X_POWERED_BY: "x-powered-by"
|
|
1348
|
+
};
|
|
1349
|
+
var http_response_headers_default = HttpResponseHeader;
|
|
1350
|
+
|
|
1351
|
+
// src/response-status.js
|
|
1352
|
+
var ResponseStatus = class {
|
|
1353
|
+
/** @type {number} */
|
|
1354
|
+
#code;
|
|
1355
|
+
/** @type {string} */
|
|
1356
|
+
#text;
|
|
1357
|
+
/**
|
|
1358
|
+
*
|
|
1359
|
+
* @param {number} code The status code from the {@link Response}
|
|
1360
|
+
* @param {string} text The status text from the {@link Response}
|
|
1361
|
+
*/
|
|
1362
|
+
constructor(code, text) {
|
|
1363
|
+
this.#code = code;
|
|
1364
|
+
this.#text = text;
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* Returns the status code from the {@link Response}
|
|
1368
|
+
*
|
|
1369
|
+
* @returns {number} The status code.
|
|
1370
|
+
*/
|
|
1371
|
+
get code() {
|
|
1372
|
+
return this.#code;
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* Returns the status text from the {@link Response}.
|
|
1376
|
+
*
|
|
1377
|
+
* @returns {string} The status text.
|
|
1378
|
+
*/
|
|
1379
|
+
get text() {
|
|
1380
|
+
return this.#text;
|
|
1381
|
+
}
|
|
1382
|
+
/**
|
|
1383
|
+
* A String value that is used in the creation of the default string
|
|
1384
|
+
* description of an object. Called by the built-in method {@link Object.prototype.toString}.
|
|
1385
|
+
*
|
|
1386
|
+
* @override
|
|
1387
|
+
* @returns {string} The default string description of this object.
|
|
1388
|
+
*/
|
|
1389
|
+
get [Symbol.toStringTag]() {
|
|
1390
|
+
return "ResponseStatus";
|
|
1391
|
+
}
|
|
1392
|
+
/**
|
|
1393
|
+
* tostring method for the class.
|
|
1394
|
+
*
|
|
1395
|
+
* @override
|
|
1396
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString|Object.prototype.toString}
|
|
1397
|
+
* @returns {string} The status code and status text.
|
|
1398
|
+
*/
|
|
1399
|
+
toString() {
|
|
1400
|
+
return `${this.#code} ${this.#text}`;
|
|
1401
|
+
}
|
|
1402
|
+
};
|
|
1403
|
+
|
|
1404
|
+
// src/parameter-map.js
|
|
1405
|
+
var ParameterMap = class _ParameterMap extends Map {
|
|
1406
|
+
/**
|
|
1407
|
+
* @param {Iterable<[string, *]>|Object} parameters The initial parameters to set.
|
|
1408
|
+
* @returns {ParameterMap<string, *>} The ParameterMap with the updated key and value.
|
|
1409
|
+
*/
|
|
1410
|
+
constructor(parameters = {}) {
|
|
1411
|
+
super();
|
|
1412
|
+
for (const [key, value] of _ParameterMap.#entries(parameters)) {
|
|
1413
|
+
this.append(key, value);
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Adds a new element with a specified key and value to the ParameterMap.
|
|
1418
|
+
* If an element with the same key already exists, the value will be replaced in the underlying {@link Set}.
|
|
1419
|
+
*
|
|
1420
|
+
* @override
|
|
1421
|
+
* @param {string} key The key to set.
|
|
1422
|
+
* @param {*} value The value to add to the ParameterMap
|
|
1423
|
+
* @returns {ParameterMap<string, *>} The ParameterMap with the updated key and value.
|
|
1424
|
+
*/
|
|
1425
|
+
set(key, value) {
|
|
1426
|
+
const array = super.get(key);
|
|
1427
|
+
if (array?.length > 0) {
|
|
1428
|
+
array.length = 0;
|
|
1429
|
+
array[0] = value;
|
|
1430
|
+
} else {
|
|
1431
|
+
super.set(key, [value]);
|
|
1432
|
+
}
|
|
1433
|
+
return this;
|
|
1434
|
+
}
|
|
1435
|
+
/**
|
|
1436
|
+
* Adds all key-value pairs from an iterable or object to the ParameterMap.
|
|
1437
|
+
* If a key already exists, the value will be replaced in the underlying {@link Array}.
|
|
1438
|
+
*
|
|
1439
|
+
* @param {Iterable<[string, *]>|Object} parameters The parameters to set.
|
|
1440
|
+
* @returns {ParameterMap<string, *>} The ParameterMap with the updated key and value.
|
|
1441
|
+
*/
|
|
1442
|
+
setAll(parameters) {
|
|
1443
|
+
for (const [key, value] of _ParameterMap.#entries(parameters)) {
|
|
1444
|
+
this.set(key, value);
|
|
1445
|
+
}
|
|
1446
|
+
return this;
|
|
1447
|
+
}
|
|
1448
|
+
/**
|
|
1449
|
+
* Returns the value associated to the key, or undefined if there is none.
|
|
1450
|
+
* If the key has multiple values, the first value will be returned.
|
|
1451
|
+
* If the key has no values, undefined will be returned.
|
|
1452
|
+
*
|
|
1453
|
+
* @override
|
|
1454
|
+
* @param {string} key The key to get.
|
|
1455
|
+
* @returns {*} The value associated to the key, or undefined if there is none.
|
|
1456
|
+
*/
|
|
1457
|
+
get(key) {
|
|
1458
|
+
return super.get(key)?.[0];
|
|
1459
|
+
}
|
|
1460
|
+
/**
|
|
1461
|
+
* Returns an array of all values associated to the key, or undefined if there are none.
|
|
1462
|
+
*
|
|
1463
|
+
* @param {string} key The key to get.
|
|
1464
|
+
* @returns {Array<*>} An array of all values associated to the key, or undefined if there are none.
|
|
1465
|
+
*/
|
|
1466
|
+
getAll(key) {
|
|
1467
|
+
return super.get(key);
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* Appends a new value to an existing key inside a ParameterMap, or adds the new key if it does not exist.
|
|
1471
|
+
*
|
|
1472
|
+
* @param {string} key The key to append.
|
|
1473
|
+
* @param {*} value The value to append.
|
|
1474
|
+
* @returns {ParameterMap<string, *>} The ParameterMap with the updated key and value to allow chaining.
|
|
1475
|
+
*/
|
|
1476
|
+
append(key, value) {
|
|
1477
|
+
const array = super.get(key);
|
|
1478
|
+
if (array?.length > 0) {
|
|
1479
|
+
array.push(value);
|
|
1480
|
+
} else {
|
|
1481
|
+
super.set(key, [value]);
|
|
1482
|
+
}
|
|
1483
|
+
return this;
|
|
1484
|
+
}
|
|
1485
|
+
/**
|
|
1486
|
+
* Appends all key-value pairs from an iterable or object to the ParameterMap.
|
|
1487
|
+
* If a key already exists, the value will be appended to the underlying {@link Array}.
|
|
1488
|
+
* If a key does not exist, the key and value will be added to the ParameterMap.
|
|
1489
|
+
*
|
|
1490
|
+
* @param {Iterable<[string, *]>|Object} parameters The parameters to append.
|
|
1491
|
+
* @returns {ParameterMap<string, *>} The ParameterMap with the updated key and value.
|
|
1492
|
+
*/
|
|
1493
|
+
appendAll(parameters) {
|
|
1494
|
+
for (const [key, value] of _ParameterMap.#entries(parameters)) {
|
|
1495
|
+
this.append(key, value);
|
|
1496
|
+
}
|
|
1497
|
+
return this;
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Checks if a specific key has a specific value.
|
|
1501
|
+
*
|
|
1502
|
+
* @param {*} value The value to check.
|
|
1503
|
+
* @returns {boolean} True if the key has the value, false otherwise.
|
|
1504
|
+
*/
|
|
1505
|
+
hasValue(value) {
|
|
1506
|
+
for (const array of super.values()) {
|
|
1507
|
+
if (array.includes(value)) {
|
|
1508
|
+
return true;
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
return false;
|
|
1512
|
+
}
|
|
1513
|
+
/**
|
|
1514
|
+
* Removes a specific value from a specific key.
|
|
1515
|
+
*
|
|
1516
|
+
* @param {*} value The value to remove.
|
|
1517
|
+
* @returns {boolean} True if the value was removed, false otherwise.
|
|
1518
|
+
*/
|
|
1519
|
+
deleteValue(value) {
|
|
1520
|
+
for (const array of this.values()) {
|
|
1521
|
+
if (array.includes(value)) {
|
|
1522
|
+
return array.splice(array.indexOf(value), 1).length > 0;
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
return false;
|
|
1526
|
+
}
|
|
1527
|
+
/**
|
|
1528
|
+
* Determines whether the ParameterMap contains anything.
|
|
1529
|
+
*
|
|
1530
|
+
* @returns {boolean} True if the ParameterMap size is greater than 0, false otherwise.
|
|
1531
|
+
*/
|
|
1532
|
+
isEmpty() {
|
|
1533
|
+
return this.size === 0;
|
|
1534
|
+
}
|
|
1535
|
+
/**
|
|
1536
|
+
* Returns an Object that can be serialized to JSON.
|
|
1537
|
+
* If a key has only one value, the value will be a single value.
|
|
1538
|
+
* If a key has multiple values, the value will be an array of values.
|
|
1539
|
+
* If a key has no values, the value will be undefined.
|
|
1540
|
+
*
|
|
1541
|
+
* @override
|
|
1542
|
+
* @returns {Object} The Object to be serialized to JSON.
|
|
1543
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON_behavior}
|
|
1544
|
+
*/
|
|
1545
|
+
toJSON() {
|
|
1546
|
+
const obj = /* @__PURE__ */ Object.create(null);
|
|
1547
|
+
for (const [key, values] of super.entries()) {
|
|
1548
|
+
obj[key] = values.length === 1 ? values[0] : values;
|
|
1549
|
+
}
|
|
1550
|
+
return obj;
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Returns an iterator that yields all key-value pairs in the map as arrays in their insertion order.
|
|
1554
|
+
*
|
|
1555
|
+
* @override
|
|
1556
|
+
* @yields {[string, *]} An iterator for the key-value pairs in the map.
|
|
1557
|
+
*/
|
|
1558
|
+
*entries() {
|
|
1559
|
+
for (const [key, array] of super.entries()) {
|
|
1560
|
+
for (const value of array) {
|
|
1561
|
+
yield [key, value];
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Returns an iterator that yields all key-value pairs in the map as arrays in their insertion order.
|
|
1567
|
+
*
|
|
1568
|
+
* @override
|
|
1569
|
+
* @yields {[string, *]} An iterator for the key-value pairs in the map.
|
|
1570
|
+
*/
|
|
1571
|
+
*[Symbol.iterator]() {
|
|
1572
|
+
yield* this.entries();
|
|
1573
|
+
}
|
|
1574
|
+
/**
|
|
1575
|
+
* Returns an iterable of key, value pairs for every entry in the parameters object.
|
|
1576
|
+
*
|
|
1577
|
+
* @private
|
|
1578
|
+
* @static
|
|
1579
|
+
* @param {Iterable<[string, *]>|Object} parameters The parameters to set.
|
|
1580
|
+
* @returns {Iterable<[string, *]>} An iterable of key, value pairs for every entry in the parameters object.
|
|
1581
|
+
*/
|
|
1582
|
+
static #entries(parameters) {
|
|
1583
|
+
return parameters[Symbol.iterator] ? parameters : Object.entries(parameters);
|
|
1584
|
+
}
|
|
1585
|
+
/**
|
|
1586
|
+
* A String value that is used in the creation of the default string description of an object.
|
|
1587
|
+
* Called by the built-in method {@link Object.prototype.toString}.
|
|
1588
|
+
*
|
|
1589
|
+
* @override
|
|
1590
|
+
* @returns {string} The default string description of this object.
|
|
1591
|
+
*/
|
|
1592
|
+
get [Symbol.toStringTag]() {
|
|
1593
|
+
return "ParameterMap";
|
|
1594
|
+
}
|
|
1595
|
+
};
|
|
1596
|
+
|
|
1597
|
+
// node_modules/@d1g1tal/media-type/src/utils.js
|
|
1598
|
+
var whitespaceCharacters = [" ", " ", "\n", "\r"];
|
|
1599
|
+
var leadingWhitespace = /^[ \t\n\r]+/u;
|
|
1600
|
+
var trailingWhitespace = /[ \t\n\r]+$/u;
|
|
1601
|
+
var httpTokenCodePoints = /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/u;
|
|
1602
|
+
var httpQuotedTokenCodePoints = /^[\t\u0020-\u007E\u0080-\u00FF]*$/u;
|
|
1603
|
+
var removeLeadingAndTrailingHTTPWhitespace = (string) => string.replace(leadingWhitespace, "").replace(trailingWhitespace, "");
|
|
1604
|
+
var removeTrailingHTTPWhitespace = (string) => string.replace(trailingWhitespace, "");
|
|
1605
|
+
var isHTTPWhitespaceChar = (char) => whitespaceCharacters.includes(char);
|
|
1606
|
+
var solelyContainsHTTPTokenCodePoints = (string) => httpTokenCodePoints.test(string);
|
|
1607
|
+
var solelyContainsHTTPQuotedStringTokenCodePoints = (string) => httpQuotedTokenCodePoints.test(string);
|
|
1608
|
+
var asciiLowercase = (string) => {
|
|
1609
|
+
let result = "";
|
|
1610
|
+
for (const [char, charCode = char.charCodeAt(0)] of string) {
|
|
1611
|
+
result += charCode >= 65 && charCode <= 90 ? String.fromCharCode(charCode + 32) : char;
|
|
1612
|
+
}
|
|
1613
|
+
return result;
|
|
1614
|
+
};
|
|
1615
|
+
var collectAnHTTPQuotedString = (input, position) => {
|
|
1616
|
+
let value = "";
|
|
1617
|
+
for (let length = input.length, char; ++position < length; ) {
|
|
1618
|
+
char = input[position];
|
|
1619
|
+
if (char == "\\") {
|
|
1620
|
+
value += ++position < length ? input[position] : char;
|
|
1621
|
+
} else if (char == '"') {
|
|
1622
|
+
break;
|
|
1623
|
+
} else {
|
|
1624
|
+
value += char;
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
return [value, position];
|
|
1628
|
+
};
|
|
1629
|
+
|
|
1630
|
+
// node_modules/@d1g1tal/media-type/src/media-type-parameters.js
|
|
1631
|
+
var MediaTypeParameters = class {
|
|
1632
|
+
/** @type {Map<string, string>} */
|
|
1633
|
+
#map;
|
|
1565
1634
|
/**
|
|
1566
|
-
*
|
|
1635
|
+
* Create a new MediaTypeParameters instance.
|
|
1567
1636
|
*
|
|
1568
|
-
* @
|
|
1569
|
-
* content-length: 348
|
|
1570
|
-
* Permanent
|
|
1637
|
+
* @param {Array<Array<string>>} entries An array of [name, value] tuples.
|
|
1571
1638
|
*/
|
|
1572
|
-
|
|
1639
|
+
constructor(entries) {
|
|
1640
|
+
this.#map = new Map(entries);
|
|
1641
|
+
}
|
|
1573
1642
|
/**
|
|
1574
|
-
*
|
|
1643
|
+
* Gets the number of media type parameters.
|
|
1575
1644
|
*
|
|
1576
|
-
* @
|
|
1577
|
-
* content-location: /index.htm
|
|
1578
|
-
* Permanent
|
|
1645
|
+
* @returns {number} The number of media type parameters
|
|
1579
1646
|
*/
|
|
1580
|
-
|
|
1647
|
+
get size() {
|
|
1648
|
+
return this.#map.size;
|
|
1649
|
+
}
|
|
1581
1650
|
/**
|
|
1582
|
-
*
|
|
1651
|
+
* Gets the media type parameter value for the supplied name.
|
|
1583
1652
|
*
|
|
1584
|
-
* @
|
|
1585
|
-
*
|
|
1586
|
-
* Permanent
|
|
1653
|
+
* @param {string} name The name of the media type parameter to retrieve.
|
|
1654
|
+
* @returns {string} The media type parameter value.
|
|
1587
1655
|
*/
|
|
1588
|
-
|
|
1656
|
+
get(name) {
|
|
1657
|
+
return this.#map.get(asciiLowercase(String(name)));
|
|
1658
|
+
}
|
|
1589
1659
|
/**
|
|
1590
|
-
*
|
|
1660
|
+
* Indicates whether the media type parameter with the specified name exists or not.
|
|
1591
1661
|
*
|
|
1592
|
-
* @
|
|
1593
|
-
*
|
|
1594
|
-
* Permanent
|
|
1662
|
+
* @param {string} name The name of the media type parameter to check.
|
|
1663
|
+
* @returns {boolean} true if the media type parameter exists, false otherwise.
|
|
1595
1664
|
*/
|
|
1596
|
-
|
|
1665
|
+
has(name) {
|
|
1666
|
+
return this.#map.has(asciiLowercase(String(name)));
|
|
1667
|
+
}
|
|
1597
1668
|
/**
|
|
1598
|
-
*
|
|
1669
|
+
* Adds a new media type parameter using the specified name and value to the MediaTypeParameters.
|
|
1670
|
+
* If an parameter with the same name already exists, the parameter will be updated.
|
|
1599
1671
|
*
|
|
1600
|
-
* @
|
|
1601
|
-
*
|
|
1602
|
-
*
|
|
1672
|
+
* @param {string} name The name of the media type parameter to set.
|
|
1673
|
+
* @param {string} value The media type parameter value.
|
|
1674
|
+
* @returns {MediaTypeParameters} This instance.
|
|
1603
1675
|
*/
|
|
1604
|
-
|
|
1676
|
+
set(name, value) {
|
|
1677
|
+
name = asciiLowercase(String(name));
|
|
1678
|
+
value = String(value);
|
|
1679
|
+
if (!solelyContainsHTTPTokenCodePoints(name)) {
|
|
1680
|
+
throw new Error(`Invalid media type parameter name "${name}": only HTTP token code points are valid.`);
|
|
1681
|
+
}
|
|
1682
|
+
if (!solelyContainsHTTPQuotedStringTokenCodePoints(value)) {
|
|
1683
|
+
throw new Error(`Invalid media type parameter value "${value}": only HTTP quoted-string token code points are valid.`);
|
|
1684
|
+
}
|
|
1685
|
+
this.#map.set(name, value);
|
|
1686
|
+
return this;
|
|
1687
|
+
}
|
|
1605
1688
|
/**
|
|
1606
|
-
*
|
|
1607
|
-
*
|
|
1608
|
-
* @example
|
|
1609
|
-
* etag: "737060cd8c284d8af7ad3082f209582d"
|
|
1610
|
-
* Permanent
|
|
1689
|
+
* Clears all the media type parameters.
|
|
1611
1690
|
*/
|
|
1612
|
-
|
|
1691
|
+
clear() {
|
|
1692
|
+
this.#map.clear();
|
|
1693
|
+
}
|
|
1613
1694
|
/**
|
|
1614
|
-
*
|
|
1695
|
+
* Removes the media type parameter using the specified name.
|
|
1615
1696
|
*
|
|
1616
|
-
* @
|
|
1617
|
-
*
|
|
1618
|
-
* Permanent
|
|
1697
|
+
* @param {string} name The name of the media type parameter to delete.
|
|
1698
|
+
* @returns {boolean} true if the parameter existed and has been removed, or false if the parameter does not exist.
|
|
1619
1699
|
*/
|
|
1620
|
-
|
|
1700
|
+
delete(name) {
|
|
1701
|
+
name = asciiLowercase(String(name));
|
|
1702
|
+
return this.#map.delete(name);
|
|
1703
|
+
}
|
|
1621
1704
|
/**
|
|
1622
|
-
*
|
|
1705
|
+
* Executes a provided function once per each name/value pair in the MediaTypeParameters, in insertion order.
|
|
1623
1706
|
*
|
|
1624
|
-
* @
|
|
1625
|
-
*
|
|
1626
|
-
* Permanent
|
|
1707
|
+
* @param {function(string, string): void} callback The function called on each iteration.
|
|
1708
|
+
* @param {*} [thisArg] Optional object when binding 'this' to the callback.
|
|
1627
1709
|
*/
|
|
1628
|
-
|
|
1710
|
+
forEach(callback, thisArg) {
|
|
1711
|
+
this.#map.forEach(callback, thisArg);
|
|
1712
|
+
}
|
|
1629
1713
|
/**
|
|
1630
|
-
*
|
|
1714
|
+
* Returns an iterable of parameter names.
|
|
1631
1715
|
*
|
|
1632
|
-
* @
|
|
1633
|
-
* link: </feed>, rel="alternate"
|
|
1634
|
-
* Permanent
|
|
1716
|
+
* @returns {IterableIterator<string>} The {@link IterableIterator} of media type parameter names.
|
|
1635
1717
|
*/
|
|
1636
|
-
|
|
1718
|
+
keys() {
|
|
1719
|
+
return this.#map.keys();
|
|
1720
|
+
}
|
|
1637
1721
|
/**
|
|
1638
|
-
*
|
|
1722
|
+
* Returns an iterable of parameter values.
|
|
1639
1723
|
*
|
|
1640
|
-
* @
|
|
1641
|
-
* location: http://www.w3.org/pub/WWW/People.html
|
|
1642
|
-
* Permanent
|
|
1724
|
+
* @returns {IterableIterator<string>} The {@link IterableIterator} of media type parameter values.
|
|
1643
1725
|
*/
|
|
1644
|
-
|
|
1726
|
+
values() {
|
|
1727
|
+
return this.#map.values();
|
|
1728
|
+
}
|
|
1645
1729
|
/**
|
|
1646
|
-
*
|
|
1647
|
-
* implemented it, a lot of websites set this field with fake policy text, that was enough to fool browsers the existence of P3P policy and grant permissions for third party cookies.
|
|
1730
|
+
* Returns an iterable of name, value pairs for every parameter entry in the media type parameters.
|
|
1648
1731
|
*
|
|
1649
|
-
* @
|
|
1650
|
-
* p3p: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
|
|
1651
|
-
* Permanent
|
|
1732
|
+
* @returns {IterableIterator<Array<Array<string>>>} The media type parameter entries.
|
|
1652
1733
|
*/
|
|
1653
|
-
|
|
1734
|
+
entries() {
|
|
1735
|
+
return this.#map.entries();
|
|
1736
|
+
}
|
|
1654
1737
|
/**
|
|
1655
|
-
*
|
|
1738
|
+
* A method that returns the default iterator for the {@link MediaTypeParameters}. Called by the semantics of the for-of statement.
|
|
1656
1739
|
*
|
|
1657
|
-
* @
|
|
1658
|
-
* pragma: no-cache
|
|
1659
|
-
* Permanent
|
|
1740
|
+
* @returns {Iterator<string, string, undefined>} The {@link Symbol.iterator} for the media type parameters.
|
|
1660
1741
|
*/
|
|
1661
|
-
|
|
1742
|
+
[Symbol.iterator]() {
|
|
1743
|
+
return this.#map[Symbol.iterator]();
|
|
1744
|
+
}
|
|
1662
1745
|
/**
|
|
1663
|
-
*
|
|
1746
|
+
* Returns a string representation of the media type parameters.
|
|
1747
|
+
* This method is called by the `String()` function.
|
|
1664
1748
|
*
|
|
1665
1749
|
* @example
|
|
1666
|
-
*
|
|
1667
|
-
*
|
|
1750
|
+
* const parameters = new MediaTypeParameters(new Map([['charset', 'utf-8']]));
|
|
1751
|
+
* String(parameters); // 'charset=utf-8'
|
|
1752
|
+
* parameters.toString(); // 'charset=utf-8'
|
|
1753
|
+
* parameters + ''; // 'charset=utf-8'
|
|
1754
|
+
* `${parameters}`; // 'charset=utf-8'
|
|
1755
|
+
* parameters[Symbol.toStringTag]; // 'MediaTypeParameters'
|
|
1756
|
+
* parameters[Symbol.toStringTag](); // 'MediaTypeParameters'
|
|
1757
|
+
* Object.prototype.toString.call(parameters); // '[object MediaTypeParameters]'
|
|
1758
|
+
* parameters + ''; // 'charset=utf-8'
|
|
1759
|
+
* @returns {string} The string representation of the media type parameters.
|
|
1668
1760
|
*/
|
|
1669
|
-
|
|
1761
|
+
[Symbol.toStringTag]() {
|
|
1762
|
+
return "MediaTypeParameters";
|
|
1763
|
+
}
|
|
1764
|
+
};
|
|
1765
|
+
|
|
1766
|
+
// node_modules/@d1g1tal/media-type/src/parser.js
|
|
1767
|
+
var parse = (input) => {
|
|
1768
|
+
input = removeLeadingAndTrailingHTTPWhitespace(input);
|
|
1769
|
+
let position = 0;
|
|
1770
|
+
let type = "";
|
|
1771
|
+
while (position < input.length && input[position] != "/") {
|
|
1772
|
+
type += input[position];
|
|
1773
|
+
++position;
|
|
1774
|
+
}
|
|
1775
|
+
if (type.length === 0 || !solelyContainsHTTPTokenCodePoints(type)) {
|
|
1776
|
+
return null;
|
|
1777
|
+
}
|
|
1778
|
+
if (position >= input.length) {
|
|
1779
|
+
return null;
|
|
1780
|
+
}
|
|
1781
|
+
++position;
|
|
1782
|
+
let subtype = "";
|
|
1783
|
+
while (position < input.length && input[position] != ";") {
|
|
1784
|
+
subtype += input[position];
|
|
1785
|
+
++position;
|
|
1786
|
+
}
|
|
1787
|
+
subtype = removeTrailingHTTPWhitespace(subtype);
|
|
1788
|
+
if (subtype.length === 0 || !solelyContainsHTTPTokenCodePoints(subtype)) {
|
|
1789
|
+
return null;
|
|
1790
|
+
}
|
|
1791
|
+
const mediaType = {
|
|
1792
|
+
type: asciiLowercase(type),
|
|
1793
|
+
subtype: asciiLowercase(subtype),
|
|
1794
|
+
parameters: /* @__PURE__ */ new Map()
|
|
1795
|
+
};
|
|
1796
|
+
while (position < input.length) {
|
|
1797
|
+
++position;
|
|
1798
|
+
while (isHTTPWhitespaceChar(input[position])) {
|
|
1799
|
+
++position;
|
|
1800
|
+
}
|
|
1801
|
+
let parameterName = "";
|
|
1802
|
+
while (position < input.length && input[position] != ";" && input[position] != "=") {
|
|
1803
|
+
parameterName += input[position];
|
|
1804
|
+
++position;
|
|
1805
|
+
}
|
|
1806
|
+
parameterName = asciiLowercase(parameterName);
|
|
1807
|
+
if (position < input.length) {
|
|
1808
|
+
if (input[position] == ";") {
|
|
1809
|
+
continue;
|
|
1810
|
+
}
|
|
1811
|
+
++position;
|
|
1812
|
+
}
|
|
1813
|
+
let parameterValue = null;
|
|
1814
|
+
if (input[position] == '"') {
|
|
1815
|
+
[parameterValue, position] = collectAnHTTPQuotedString(input, position);
|
|
1816
|
+
while (position < input.length && input[position] != ";") {
|
|
1817
|
+
++position;
|
|
1818
|
+
}
|
|
1819
|
+
} else {
|
|
1820
|
+
parameterValue = "";
|
|
1821
|
+
while (position < input.length && input[position] != ";") {
|
|
1822
|
+
parameterValue += input[position];
|
|
1823
|
+
++position;
|
|
1824
|
+
}
|
|
1825
|
+
parameterValue = removeTrailingHTTPWhitespace(parameterValue);
|
|
1826
|
+
if (parameterValue === "") {
|
|
1827
|
+
continue;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
if (parameterName.length > 0 && solelyContainsHTTPTokenCodePoints(parameterName) && solelyContainsHTTPQuotedStringTokenCodePoints(parameterValue) && !mediaType.parameters.has(parameterName)) {
|
|
1831
|
+
mediaType.parameters.set(parameterName, parameterValue);
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
return mediaType;
|
|
1835
|
+
};
|
|
1836
|
+
var parser_default = parse;
|
|
1837
|
+
|
|
1838
|
+
// node_modules/@d1g1tal/media-type/src/serializer.js
|
|
1839
|
+
var serialize = (mediaType) => {
|
|
1840
|
+
let serialization = `${mediaType.type}/${mediaType.subtype}`;
|
|
1841
|
+
if (mediaType.parameters.size === 0) {
|
|
1842
|
+
return serialization;
|
|
1843
|
+
}
|
|
1844
|
+
for (let [name, value] of mediaType.parameters) {
|
|
1845
|
+
serialization += `;${name}=`;
|
|
1846
|
+
if (!solelyContainsHTTPTokenCodePoints(value) || value.length === 0) {
|
|
1847
|
+
value = `"${value.replace(/(["\\])/ug, "\\$1")}"`;
|
|
1848
|
+
}
|
|
1849
|
+
serialization += value;
|
|
1850
|
+
}
|
|
1851
|
+
return serialization;
|
|
1852
|
+
};
|
|
1853
|
+
var serializer_default = serialize;
|
|
1854
|
+
|
|
1855
|
+
// node_modules/@d1g1tal/media-type/src/media-type.js
|
|
1856
|
+
var MediaType = class _MediaType {
|
|
1857
|
+
/** @type {string} */
|
|
1858
|
+
#type;
|
|
1859
|
+
/** @type {string} */
|
|
1860
|
+
#subtype;
|
|
1861
|
+
/** @type {MediaTypeParameters} */
|
|
1862
|
+
#parameters;
|
|
1670
1863
|
/**
|
|
1671
|
-
*
|
|
1864
|
+
* Create a new MediaType instance from a string representation.
|
|
1672
1865
|
*
|
|
1673
|
-
* @
|
|
1674
|
-
*
|
|
1675
|
-
* Permanent
|
|
1866
|
+
* @param {string} mediaType The media type to parse.
|
|
1867
|
+
* @param {Object} [parameters] Optional parameters.
|
|
1676
1868
|
*/
|
|
1677
|
-
|
|
1869
|
+
constructor(mediaType, parameters = {}) {
|
|
1870
|
+
const { type, subtype, parameters: parsedParameters } = parser_default(mediaType);
|
|
1871
|
+
this.#type = type;
|
|
1872
|
+
this.#subtype = subtype;
|
|
1873
|
+
this.#parameters = new MediaTypeParameters([...parsedParameters, ...Object.entries(parameters).map(([name, value]) => [asciiLowercase(name), asciiLowercase(value)])]);
|
|
1874
|
+
}
|
|
1678
1875
|
/**
|
|
1679
|
-
*
|
|
1876
|
+
* Static factory method for parsing a media type.
|
|
1680
1877
|
*
|
|
1681
|
-
* @
|
|
1682
|
-
*
|
|
1683
|
-
* retry-after: Fri, 07 Nov 2014 23:59:59 GMT
|
|
1684
|
-
* Permanent
|
|
1878
|
+
* @param {string} string The media type to parse.
|
|
1879
|
+
* @returns {MediaType} The parsed {@link MediaType} object or null if the string could not be parsed.
|
|
1685
1880
|
*/
|
|
1686
|
-
|
|
1881
|
+
static parse(string) {
|
|
1882
|
+
try {
|
|
1883
|
+
return new _MediaType(string);
|
|
1884
|
+
} catch (e) {
|
|
1885
|
+
throw new Error(`Could not parse media type string '${string}'`);
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1687
1888
|
/**
|
|
1688
|
-
*
|
|
1889
|
+
* Gets the media type essence (type/subtype).
|
|
1689
1890
|
*
|
|
1690
|
-
* @
|
|
1691
|
-
* server: Apache/2.4.1 (Unix)
|
|
1692
|
-
* Permanent
|
|
1891
|
+
* @returns {string} The media type without any parameters
|
|
1693
1892
|
*/
|
|
1694
|
-
|
|
1893
|
+
get essence() {
|
|
1894
|
+
return `${this.#type}/${this.#subtype}`;
|
|
1895
|
+
}
|
|
1695
1896
|
/**
|
|
1696
|
-
*
|
|
1897
|
+
* Gets the type.
|
|
1697
1898
|
*
|
|
1698
|
-
* @
|
|
1699
|
-
* set-cookie: UserID=JohnDoe, Max-Age=3600, Version=1
|
|
1700
|
-
* Permanent
|
|
1899
|
+
* @returns {string} The type.
|
|
1701
1900
|
*/
|
|
1702
|
-
|
|
1901
|
+
get type() {
|
|
1902
|
+
return this.#type;
|
|
1903
|
+
}
|
|
1703
1904
|
/**
|
|
1704
|
-
*
|
|
1705
|
-
*
|
|
1706
|
-
* @example
|
|
1707
|
-
* status: 200 OK
|
|
1905
|
+
* Sets the type.
|
|
1708
1906
|
*/
|
|
1709
|
-
|
|
1907
|
+
set type(value) {
|
|
1908
|
+
value = asciiLowercase(String(value));
|
|
1909
|
+
if (value.length === 0) {
|
|
1910
|
+
throw new Error("Invalid type: must be a non-empty string");
|
|
1911
|
+
}
|
|
1912
|
+
if (!solelyContainsHTTPTokenCodePoints(value)) {
|
|
1913
|
+
throw new Error(`Invalid type ${value}: must contain only HTTP token code points`);
|
|
1914
|
+
}
|
|
1915
|
+
this.#type = value;
|
|
1916
|
+
}
|
|
1710
1917
|
/**
|
|
1711
|
-
*
|
|
1918
|
+
* Gets the subtype.
|
|
1712
1919
|
*
|
|
1713
|
-
* @
|
|
1714
|
-
* strict-transport-security: max-age=16070400, includeSubDomains
|
|
1715
|
-
* Permanent
|
|
1920
|
+
* @returns {string} The subtype.
|
|
1716
1921
|
*/
|
|
1717
|
-
|
|
1922
|
+
get subtype() {
|
|
1923
|
+
return this.#subtype;
|
|
1924
|
+
}
|
|
1718
1925
|
/**
|
|
1719
|
-
*
|
|
1720
|
-
*
|
|
1721
|
-
* @example
|
|
1722
|
-
* trailer: Max-Forwards
|
|
1723
|
-
* Permanent
|
|
1926
|
+
* Sets the subtype.
|
|
1724
1927
|
*/
|
|
1725
|
-
|
|
1928
|
+
set subtype(value) {
|
|
1929
|
+
value = asciiLowercase(String(value));
|
|
1930
|
+
if (value.length === 0) {
|
|
1931
|
+
throw new Error("Invalid subtype: must be a non-empty string");
|
|
1932
|
+
}
|
|
1933
|
+
if (!solelyContainsHTTPTokenCodePoints(value)) {
|
|
1934
|
+
throw new Error(`Invalid subtype ${value}: must contain only HTTP token code points`);
|
|
1935
|
+
}
|
|
1936
|
+
this.#subtype = value;
|
|
1937
|
+
}
|
|
1726
1938
|
/**
|
|
1727
|
-
*
|
|
1939
|
+
* Gets the parameters.
|
|
1728
1940
|
*
|
|
1729
|
-
* @
|
|
1730
|
-
* transfer-encoding: chunked
|
|
1731
|
-
* Permanent
|
|
1941
|
+
* @returns {MediaTypeParameters} The media type parameters.
|
|
1732
1942
|
*/
|
|
1733
|
-
|
|
1943
|
+
get parameters() {
|
|
1944
|
+
return this.#parameters;
|
|
1945
|
+
}
|
|
1734
1946
|
/**
|
|
1735
|
-
*
|
|
1947
|
+
* Gets the serialized version of the media type.
|
|
1736
1948
|
*
|
|
1737
|
-
* @
|
|
1738
|
-
* upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
|
|
1739
|
-
* Permanent
|
|
1949
|
+
* @returns {string} The serialized media type.
|
|
1740
1950
|
*/
|
|
1741
|
-
|
|
1951
|
+
toString() {
|
|
1952
|
+
return serializer_default(this);
|
|
1953
|
+
}
|
|
1742
1954
|
/**
|
|
1743
|
-
*
|
|
1955
|
+
* Determines if this instance is a JavaScript media type.
|
|
1744
1956
|
*
|
|
1745
|
-
* @
|
|
1746
|
-
*
|
|
1747
|
-
*
|
|
1957
|
+
* @param {Object} [options] Optional options.
|
|
1958
|
+
* @param {boolean} [options.prohibitParameters=false] The option to prohibit parameters when checking if the media type is JavaScript.
|
|
1959
|
+
* @returns {boolean} true if this instance represents a JavaScript media type, false otherwise.
|
|
1748
1960
|
*/
|
|
1749
|
-
|
|
1961
|
+
isJavaScript({ prohibitParameters = false } = {}) {
|
|
1962
|
+
switch (this.#type) {
|
|
1963
|
+
case "text": {
|
|
1964
|
+
switch (this.#subtype) {
|
|
1965
|
+
case "ecmascript":
|
|
1966
|
+
case "javascript":
|
|
1967
|
+
case "javascript1.0":
|
|
1968
|
+
case "javascript1.1":
|
|
1969
|
+
case "javascript1.2":
|
|
1970
|
+
case "javascript1.3":
|
|
1971
|
+
case "javascript1.4":
|
|
1972
|
+
case "javascript1.5":
|
|
1973
|
+
case "jscript":
|
|
1974
|
+
case "livescript":
|
|
1975
|
+
case "x-ecmascript":
|
|
1976
|
+
case "x-javascript":
|
|
1977
|
+
return !prohibitParameters || this.#parameters.size === 0;
|
|
1978
|
+
default:
|
|
1979
|
+
return false;
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
case "application": {
|
|
1983
|
+
switch (this.#subtype) {
|
|
1984
|
+
case "ecmascript":
|
|
1985
|
+
case "javascript":
|
|
1986
|
+
case "x-ecmascript":
|
|
1987
|
+
case "x-javascript":
|
|
1988
|
+
return !prohibitParameters || this.#parameters.size === 0;
|
|
1989
|
+
default:
|
|
1990
|
+
return false;
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
default:
|
|
1994
|
+
return false;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1750
1997
|
/**
|
|
1751
|
-
*
|
|
1998
|
+
* Determines if this instance is an XML media type.
|
|
1752
1999
|
*
|
|
1753
|
-
* @
|
|
1754
|
-
* via: 1.0 fred, 1.1 example.com (Apache/1.1)
|
|
1755
|
-
* Permanent
|
|
2000
|
+
* @returns {boolean} true if this instance represents an XML media type, false otherwise.
|
|
1756
2001
|
*/
|
|
1757
|
-
|
|
2002
|
+
isXML() {
|
|
2003
|
+
return this.#subtype === "xml" && (this.#type === "text" || this.#type === "application") || this.#subtype.endsWith("+xml");
|
|
2004
|
+
}
|
|
1758
2005
|
/**
|
|
1759
|
-
*
|
|
2006
|
+
* Determines if this instance is an HTML media type.
|
|
1760
2007
|
*
|
|
1761
|
-
* @
|
|
1762
|
-
* warning: 199 Miscellaneous warning
|
|
1763
|
-
* Permanent
|
|
2008
|
+
* @returns {boolean} true if this instance represents an HTML media type, false otherwise.
|
|
1764
2009
|
*/
|
|
1765
|
-
|
|
2010
|
+
isHTML() {
|
|
2011
|
+
return this.#subtype === "html" && this.#type === "text";
|
|
2012
|
+
}
|
|
1766
2013
|
/**
|
|
1767
|
-
*
|
|
2014
|
+
* Gets the name of the class.
|
|
1768
2015
|
*
|
|
1769
|
-
* @
|
|
1770
|
-
* www-authenticate: Basic
|
|
1771
|
-
* Permanent
|
|
2016
|
+
* @returns {string} The class name
|
|
1772
2017
|
*/
|
|
1773
|
-
|
|
2018
|
+
get [Symbol.toStringTag]() {
|
|
2019
|
+
return "MediaType";
|
|
2020
|
+
}
|
|
2021
|
+
};
|
|
2022
|
+
|
|
2023
|
+
// src/constants.js
|
|
2024
|
+
var defaultCharset = "utf-8";
|
|
2025
|
+
var endsWithSlashRegEx = /\/$/;
|
|
2026
|
+
var mediaTypes = /* @__PURE__ */ new Map([
|
|
2027
|
+
[http_media_type_default.PNG, new MediaType(http_media_type_default.PNG)],
|
|
2028
|
+
[http_media_type_default.TEXT, new MediaType(http_media_type_default.TEXT, { defaultCharset })],
|
|
2029
|
+
[http_media_type_default.JSON, new MediaType(http_media_type_default.JSON, { defaultCharset })],
|
|
2030
|
+
[http_media_type_default.HTML, new MediaType(http_media_type_default.HTML, { defaultCharset })],
|
|
2031
|
+
[http_media_type_default.JAVA_SCRIPT, new MediaType(http_media_type_default.JAVA_SCRIPT, { defaultCharset })],
|
|
2032
|
+
[http_media_type_default.CSS, new MediaType(http_media_type_default.CSS, { defaultCharset })],
|
|
2033
|
+
[http_media_type_default.XML, new MediaType(http_media_type_default.XML, { defaultCharset })],
|
|
2034
|
+
[http_media_type_default.BIN, new MediaType(http_media_type_default.BIN)]
|
|
2035
|
+
]);
|
|
2036
|
+
var RequestEvents = Object.freeze({
|
|
2037
|
+
CONFIGURED: "configured",
|
|
2038
|
+
SUCCESS: "success",
|
|
2039
|
+
ERROR: "error",
|
|
2040
|
+
ABORTED: "aborted",
|
|
2041
|
+
TIMEOUT: "timeout",
|
|
2042
|
+
COMPLETE: "complete",
|
|
2043
|
+
ALL_COMPLETE: "all-complete"
|
|
2044
|
+
});
|
|
2045
|
+
var SignalEvents = Object.freeze({
|
|
2046
|
+
ABORT: "abort",
|
|
2047
|
+
TIMEOUT: "timeout"
|
|
2048
|
+
});
|
|
2049
|
+
var _abortEvent = new CustomEvent(SignalEvents.ABORT, { detail: { cause: new DOMException("The request was aborted", "AbortError") } });
|
|
2050
|
+
var requestBodyMethods = [http_request_methods_default.POST, http_request_methods_default.PUT, http_request_methods_default.PATCH];
|
|
2051
|
+
|
|
2052
|
+
// src/abort-signal.js
|
|
2053
|
+
var NativeAbortSignal = globalThis.AbortSignal;
|
|
2054
|
+
var AbortSignal = class _AbortSignal extends EventTarget {
|
|
2055
|
+
/** @type {AbortController} */
|
|
2056
|
+
#abortController;
|
|
2057
|
+
/** @type {number} */
|
|
2058
|
+
#timeoutId;
|
|
1774
2059
|
/**
|
|
1775
|
-
*
|
|
1776
|
-
*
|
|
1777
|
-
* @example
|
|
1778
|
-
* x-xss-protection: 1, mode=block
|
|
2060
|
+
* @param {AbortSignal} signal The signal to listen to
|
|
1779
2061
|
*/
|
|
1780
|
-
|
|
2062
|
+
constructor(signal) {
|
|
2063
|
+
super();
|
|
2064
|
+
this.#abortController = new AbortController();
|
|
2065
|
+
signal?.addEventListener(SignalEvents.ABORT, (event) => this.#abort(event));
|
|
2066
|
+
}
|
|
1781
2067
|
/**
|
|
1782
|
-
*
|
|
1783
|
-
* to load for a given page. With a few exceptions, policies mostly involve specifying server origins and script endpoints.
|
|
1784
|
-
* This helps guard against cross-site scripting attacks (Cross-site_scripting).
|
|
2068
|
+
* Returns an {@link AbortSignal} instance that is already set as aborted.
|
|
1785
2069
|
*
|
|
1786
|
-
* @
|
|
1787
|
-
*
|
|
2070
|
+
* @static
|
|
2071
|
+
* @returns {AbortSignal} The abort signal
|
|
1788
2072
|
*/
|
|
1789
|
-
|
|
2073
|
+
static abort() {
|
|
2074
|
+
return NativeAbortSignal.abort();
|
|
2075
|
+
}
|
|
1790
2076
|
/**
|
|
1791
|
-
*
|
|
2077
|
+
* Returns an AbortSignal instance that will automatically abort after a specified time.
|
|
1792
2078
|
*
|
|
1793
|
-
* @
|
|
1794
|
-
*
|
|
2079
|
+
* @static
|
|
2080
|
+
* @param {number} time The time in milliseconds to wait before aborting
|
|
2081
|
+
* @returns {AbortSignal} The abort signal
|
|
1795
2082
|
*/
|
|
1796
|
-
|
|
2083
|
+
static timeout(time) {
|
|
2084
|
+
return NativeAbortSignal.timeout(time);
|
|
2085
|
+
}
|
|
1797
2086
|
/**
|
|
1798
|
-
*
|
|
2087
|
+
* The aborted property is a Boolean that indicates whether the request has been aborted (true) or not (false).
|
|
1799
2088
|
*
|
|
1800
|
-
* @
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
var http_response_headers_default = HttpResponseHeader;
|
|
1806
|
-
|
|
1807
|
-
// src/response-status.js
|
|
1808
|
-
var ResponseStatus = class {
|
|
1809
|
-
/** @type {number} */
|
|
1810
|
-
#code;
|
|
1811
|
-
/** @type {string} */
|
|
1812
|
-
#text;
|
|
2089
|
+
* @returns {boolean} Whether the signal was aborted or not
|
|
2090
|
+
*/
|
|
2091
|
+
get aborted() {
|
|
2092
|
+
return this.#abortController.signal.aborted;
|
|
2093
|
+
}
|
|
1813
2094
|
/**
|
|
2095
|
+
* The reason property returns a DOMException object indicating the reason the operation was aborted, or null if the operation is not aborted.
|
|
1814
2096
|
*
|
|
1815
|
-
* @
|
|
1816
|
-
* @param {string} text The status text from the {@link Response}
|
|
2097
|
+
* @returns {DOMException} The reason the signal was aborted
|
|
1817
2098
|
*/
|
|
1818
|
-
|
|
1819
|
-
this.#
|
|
1820
|
-
this.#text = text;
|
|
2099
|
+
get reason() {
|
|
2100
|
+
return this.#abortController.signal.reason;
|
|
1821
2101
|
}
|
|
1822
2102
|
/**
|
|
1823
|
-
*
|
|
2103
|
+
* throws the signal's abort reason if the signal has been aborted; otherwise it does nothing.
|
|
1824
2104
|
*
|
|
1825
|
-
* @returns {
|
|
2105
|
+
* @returns {void}
|
|
1826
2106
|
*/
|
|
1827
|
-
|
|
1828
|
-
|
|
2107
|
+
throwIfAborted() {
|
|
2108
|
+
this.#abortController.signal.throwIfAborted();
|
|
1829
2109
|
}
|
|
1830
2110
|
/**
|
|
1831
|
-
* Returns
|
|
2111
|
+
* Returns an AbortSignal instance that will be aborted when the provided amount of milliseconds have passed.
|
|
2112
|
+
* A value of -1 (which is the default) means there is no timeout.
|
|
2113
|
+
* Note: You can't set this property to a value less than 0.
|
|
1832
2114
|
*
|
|
1833
|
-
* @
|
|
2115
|
+
* @param {number} timeout The timeout in milliseconds
|
|
2116
|
+
* @returns {AbortSignal} The abort signal
|
|
1834
2117
|
*/
|
|
1835
|
-
|
|
1836
|
-
|
|
2118
|
+
withTimeout(timeout) {
|
|
2119
|
+
if (timeout < 0) {
|
|
2120
|
+
throw new RangeError("The timeout cannot be negative");
|
|
2121
|
+
}
|
|
2122
|
+
this.#timeoutId ??= setTimeout(() => this.#abort(_AbortSignal.#generateTimeoutEvent(timeout), true), timeout);
|
|
2123
|
+
return this.#abortController.signal;
|
|
1837
2124
|
}
|
|
1838
2125
|
/**
|
|
1839
|
-
*
|
|
1840
|
-
*
|
|
2126
|
+
* Clears the timeout.
|
|
2127
|
+
* Note: This does not abort the signal, dispatch the timeout event, or reset the timeout.
|
|
1841
2128
|
*
|
|
1842
|
-
* @
|
|
1843
|
-
* @returns {string} The default string description of this object.
|
|
2129
|
+
* @returns {void}
|
|
1844
2130
|
*/
|
|
1845
|
-
|
|
1846
|
-
|
|
2131
|
+
clearTimeout() {
|
|
2132
|
+
clearTimeout(this.#timeoutId);
|
|
1847
2133
|
}
|
|
1848
2134
|
/**
|
|
1849
|
-
*
|
|
2135
|
+
* Adds an event listener for the specified event type.
|
|
1850
2136
|
*
|
|
1851
2137
|
* @override
|
|
1852
|
-
* @
|
|
1853
|
-
* @
|
|
2138
|
+
* @param {string} eventName The name of the event to listen to
|
|
2139
|
+
* @param {EventListener} listener The listener to add
|
|
2140
|
+
* @returns {void}
|
|
1854
2141
|
*/
|
|
1855
|
-
|
|
1856
|
-
|
|
2142
|
+
addEventListener(eventName, listener) {
|
|
2143
|
+
this.#abortController.signal.addEventListener(eventName, listener);
|
|
1857
2144
|
}
|
|
1858
|
-
};
|
|
1859
|
-
|
|
1860
|
-
// src/signal-controller.js
|
|
1861
|
-
var SignalController = class {
|
|
1862
|
-
/** @type {AbortController} */
|
|
1863
|
-
#abortController;
|
|
1864
2145
|
/**
|
|
1865
|
-
*
|
|
2146
|
+
* Dispatches an event to this EventTarget.
|
|
2147
|
+
*
|
|
2148
|
+
* @override
|
|
2149
|
+
* @param {Event} event The event to dispatch
|
|
2150
|
+
* @returns {boolean} Whether the event was dispatched or not
|
|
1866
2151
|
*/
|
|
1867
|
-
|
|
1868
|
-
this.#abortController
|
|
1869
|
-
signal?.addEventListener("abort", () => this.#abortController.abort());
|
|
2152
|
+
dispatchEvent(event) {
|
|
2153
|
+
return this.#abortController.signal.dispatchEvent(event);
|
|
1870
2154
|
}
|
|
1871
2155
|
/**
|
|
1872
|
-
*
|
|
2156
|
+
* Removes an event listener for the specified event type.
|
|
1873
2157
|
*
|
|
1874
|
-
* @
|
|
2158
|
+
* @override
|
|
2159
|
+
* @param {string} eventName The name of the event to listen to
|
|
2160
|
+
* @param {EventListener} listener The listener to remove
|
|
2161
|
+
* @returns {void}
|
|
1875
2162
|
*/
|
|
1876
|
-
|
|
1877
|
-
|
|
2163
|
+
removeEventListener(eventName, listener) {
|
|
2164
|
+
this.#abortController.signal.removeEventListener(eventName, listener);
|
|
1878
2165
|
}
|
|
1879
2166
|
/**
|
|
1880
|
-
* Aborts
|
|
1881
|
-
* This is able to abort fetch requests, data sent using the XMLHttpRequest API, and Web Sockets.
|
|
2167
|
+
* Aborts the signal. This is so naughty. ¯\_(ツ)_/¯
|
|
1882
2168
|
*
|
|
1883
|
-
* @param {
|
|
2169
|
+
* @param {Event} event The event to abort with
|
|
1884
2170
|
* @returns {void}
|
|
1885
2171
|
*/
|
|
1886
|
-
abort(
|
|
1887
|
-
this.#
|
|
2172
|
+
abort(event) {
|
|
2173
|
+
this.#abort(event);
|
|
1888
2174
|
}
|
|
1889
2175
|
/**
|
|
1890
|
-
*
|
|
1891
|
-
* description of an object. Called by the built-in method {@link Object.prototype.toString}.
|
|
2176
|
+
* Aborts the signal.
|
|
1892
2177
|
*
|
|
1893
|
-
* @
|
|
1894
|
-
* @
|
|
2178
|
+
* @private
|
|
2179
|
+
* @param {Event} event The event to abort with
|
|
2180
|
+
* @param {boolean} [dispatchEvent = false] Whether to dispatch the event or not
|
|
2181
|
+
* @returns {void}
|
|
2182
|
+
* @fires SignalEvents.ABORT When the signal is aborted
|
|
2183
|
+
* @fires SignalEvents.TIMEOUT When the signal times out
|
|
2184
|
+
*/
|
|
2185
|
+
#abort(event = _abortEvent, dispatchEvent = false) {
|
|
2186
|
+
clearTimeout(this.#timeoutId);
|
|
2187
|
+
this.#abortController.abort(event.detail?.cause);
|
|
2188
|
+
if (dispatchEvent) {
|
|
2189
|
+
this.#abortController.signal.dispatchEvent(event);
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
/**
|
|
2193
|
+
* Generates a timeout event.
|
|
2194
|
+
*
|
|
2195
|
+
* @private
|
|
2196
|
+
* @static
|
|
2197
|
+
* @param {number} timeout The timeout in milliseconds
|
|
2198
|
+
* @returns {CustomEvent} The timeout event
|
|
1895
2199
|
*/
|
|
1896
|
-
|
|
1897
|
-
return "
|
|
2200
|
+
static #generateTimeoutEvent(timeout) {
|
|
2201
|
+
return new CustomEvent(SignalEvents.TIMEOUT, { detail: { timeout, cause: new DOMException(`The request timed-out after ${timeout / 1e3} seconds`, "TimeoutError") } });
|
|
2202
|
+
}
|
|
2203
|
+
};
|
|
2204
|
+
|
|
2205
|
+
// node_modules/@d1g1tal/chrysalis/src/esm/object-type.js
|
|
2206
|
+
var _type = (object) => object?.constructor ?? object?.prototype?.constructor ?? globalThis[Object.prototype.toString.call(object).slice(8, -1)] ?? object;
|
|
2207
|
+
var object_type_default = _type;
|
|
2208
|
+
|
|
2209
|
+
// node_modules/@d1g1tal/chrysalis/src/esm/object-merge.js
|
|
2210
|
+
var _objectMerge = (...objects) => {
|
|
2211
|
+
const target = {};
|
|
2212
|
+
for (const source of objects) {
|
|
2213
|
+
if (object_type_default(source) != Object)
|
|
2214
|
+
return void 0;
|
|
2215
|
+
let descriptor, sourceType;
|
|
2216
|
+
for (const property of Object.getOwnPropertyNames(source)) {
|
|
2217
|
+
descriptor = Object.getOwnPropertyDescriptor(source, property);
|
|
2218
|
+
if (descriptor.enumerable) {
|
|
2219
|
+
sourceType = object_type_default(source[property]);
|
|
2220
|
+
if (sourceType == Object) {
|
|
2221
|
+
descriptor.value = object_type_default(target[property]) == Object ? _objectMerge(target[property], source[property]) : { ...source[property] };
|
|
2222
|
+
} else if (sourceType == Array) {
|
|
2223
|
+
descriptor.value = Array.isArray(target[property]) ? [.../* @__PURE__ */ new Set([...source[property], ...target[property]])] : [...source[property]];
|
|
2224
|
+
}
|
|
2225
|
+
target[property] = descriptor.value;
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
1898
2228
|
}
|
|
2229
|
+
return target;
|
|
1899
2230
|
};
|
|
2231
|
+
var object_merge_default = _objectMerge;
|
|
1900
2232
|
|
|
1901
2233
|
// src/transportr.js
|
|
1902
|
-
var endsWithSlashRegEx = /\/$/;
|
|
1903
|
-
var charset = "utf-8";
|
|
1904
|
-
var _mediaTypes = /* @__PURE__ */ new Map([
|
|
1905
|
-
[http_media_type_default.PNG, new MediaType(http_media_type_default.PNG)],
|
|
1906
|
-
[http_media_type_default.TEXT, new MediaType(http_media_type_default.TEXT, { charset })],
|
|
1907
|
-
[http_media_type_default.JSON, new MediaType(http_media_type_default.JSON, { charset })],
|
|
1908
|
-
[http_media_type_default.HTML, new MediaType(http_media_type_default.HTML, { charset })],
|
|
1909
|
-
[http_media_type_default.JAVA_SCRIPT, new MediaType(http_media_type_default.JAVA_SCRIPT, { charset })],
|
|
1910
|
-
[http_media_type_default.CSS, new MediaType(http_media_type_default.CSS, { charset })],
|
|
1911
|
-
[http_media_type_default.XML, new MediaType(http_media_type_default.XML, { charset })],
|
|
1912
|
-
[http_media_type_default.BIN, new MediaType(http_media_type_default.BIN)]
|
|
1913
|
-
]);
|
|
1914
2234
|
var _handleText = async (response) => await response.text();
|
|
1915
2235
|
var _handleScript = async (response) => {
|
|
1916
2236
|
const objectURL = URL.createObjectURL(await response.blob());
|
|
@@ -1932,7 +2252,6 @@ var Transportr = (() => {
|
|
|
1932
2252
|
var _handleXml = async (response) => new DOMParser().parseFromString(await response.text(), http_media_type_default.XML);
|
|
1933
2253
|
var _handleHtml = async (response) => new DOMParser().parseFromString(await response.text(), http_media_type_default.HTML);
|
|
1934
2254
|
var _handleHtmlFragment = async (response) => document.createRange().createContextualFragment(await response.text());
|
|
1935
|
-
var _typeConverter = (data) => Object.fromEntries(Array.from(data.keys()).map((key, index, keys, value = data.getAll(key)) => [key, value.length > 1 ? value : value[0]]));
|
|
1936
2255
|
var Transportr = class _Transportr {
|
|
1937
2256
|
/** @type {URL} */
|
|
1938
2257
|
#baseUrl;
|
|
@@ -1942,32 +2261,18 @@ var Transportr = (() => {
|
|
|
1942
2261
|
#subscribr;
|
|
1943
2262
|
/** @type {Subscribr} */
|
|
1944
2263
|
static #globalSubscribr = new Subscribr();
|
|
1945
|
-
/** @type {
|
|
1946
|
-
static #activeRequests =
|
|
1947
|
-
/**
|
|
1948
|
-
* @private
|
|
1949
|
-
* @static
|
|
1950
|
-
* @type {SetMultiMap<ResponseHandler<ResponseBody>, string>}
|
|
1951
|
-
*/
|
|
2264
|
+
/** @type {Set<AbortSignal>} */
|
|
2265
|
+
static #activeRequests = /* @__PURE__ */ new Set();
|
|
2266
|
+
/** @type {SetMultiMap<ResponseHandler<ResponseBody>, string>} */
|
|
1952
2267
|
static #contentTypeHandlers = new set_multi_map_default([
|
|
1953
|
-
[_handleImage,
|
|
1954
|
-
[_handleText,
|
|
1955
|
-
[_handleJson,
|
|
1956
|
-
[_handleHtml,
|
|
1957
|
-
[_handleScript,
|
|
1958
|
-
[_handleCss,
|
|
1959
|
-
[_handleXml,
|
|
1960
|
-
[_handleReadableStream,
|
|
1961
|
-
]);
|
|
1962
|
-
/**
|
|
1963
|
-
* @private
|
|
1964
|
-
* @static
|
|
1965
|
-
* @type {Set<PropertyTypeConverter>}
|
|
1966
|
-
*/
|
|
1967
|
-
static #propertyTypeConverters = /* @__PURE__ */ new Set([
|
|
1968
|
-
[{ property: "body", type: FormData, converter: _typeConverter }],
|
|
1969
|
-
[{ property: "searchParams", type: URLSearchParams, converter: _typeConverter }],
|
|
1970
|
-
[{ property: "headers", type: Headers, converter: Object.fromEntries }]
|
|
2268
|
+
[_handleImage, mediaTypes.get(http_media_type_default.PNG).type],
|
|
2269
|
+
[_handleText, mediaTypes.get(http_media_type_default.TEXT).type],
|
|
2270
|
+
[_handleJson, mediaTypes.get(http_media_type_default.JSON).subtype],
|
|
2271
|
+
[_handleHtml, mediaTypes.get(http_media_type_default.HTML).subtype],
|
|
2272
|
+
[_handleScript, mediaTypes.get(http_media_type_default.JAVA_SCRIPT).subtype],
|
|
2273
|
+
[_handleCss, mediaTypes.get(http_media_type_default.CSS).subtype],
|
|
2274
|
+
[_handleXml, mediaTypes.get(http_media_type_default.XML).subtype],
|
|
2275
|
+
[_handleReadableStream, mediaTypes.get(http_media_type_default.BIN).subtype]
|
|
1971
2276
|
]);
|
|
1972
2277
|
/**
|
|
1973
2278
|
* Create a new Transportr instance with the provided location or origin and context path.
|
|
@@ -1975,65 +2280,14 @@ var Transportr = (() => {
|
|
|
1975
2280
|
* @param {URL|string|RequestOptions} [url=location.origin] The URL for {@link fetch} requests.
|
|
1976
2281
|
* @param {RequestOptions} [options={}] The default {@link RequestOptions} for this instance.
|
|
1977
2282
|
*/
|
|
1978
|
-
constructor(url = location.origin, options = {}) {
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
options = url;
|
|
1982
|
-
url = location.origin;
|
|
1983
|
-
} else if (type != URL) {
|
|
1984
|
-
url = url.startsWith("/") ? new URL(url, location.origin) : new URL(url);
|
|
2283
|
+
constructor(url = globalThis.location.origin, options = {}) {
|
|
2284
|
+
if (object_type_default(url) == Object) {
|
|
2285
|
+
[url, options] = [globalThis.location.origin, url];
|
|
1985
2286
|
}
|
|
1986
|
-
this.#baseUrl = url;
|
|
1987
|
-
this.#options =
|
|
2287
|
+
this.#baseUrl = _Transportr.#getBaseUrl(url);
|
|
2288
|
+
this.#options = _Transportr.#createOptions(options, _Transportr.#defaultRequestOptions);
|
|
1988
2289
|
this.#subscribr = new Subscribr();
|
|
1989
2290
|
}
|
|
1990
|
-
/**
|
|
1991
|
-
* Returns a {@link SignalController} used for aborting requests.
|
|
1992
|
-
*
|
|
1993
|
-
* @static
|
|
1994
|
-
* @param {AbortSignal} [signal] The optional {@link AbortSignal} to used for chaining.
|
|
1995
|
-
* @returns {SignalController} A new {@link SignalController} instance.
|
|
1996
|
-
*/
|
|
1997
|
-
static signalController(signal) {
|
|
1998
|
-
return new SignalController(signal);
|
|
1999
|
-
}
|
|
2000
|
-
/**
|
|
2001
|
-
* Returns a {@link EventRegistration} used for subscribing to global events.
|
|
2002
|
-
*
|
|
2003
|
-
* @static
|
|
2004
|
-
* @param {TransportrEvent} event The event to subscribe to.
|
|
2005
|
-
* @param {function(Event, *): void} handler The event handler.
|
|
2006
|
-
* @param {*} context The context to bind the handler to.
|
|
2007
|
-
* @returns {EventRegistration} A new {@link EventRegistration} instance.
|
|
2008
|
-
*/
|
|
2009
|
-
static register(event, handler, context) {
|
|
2010
|
-
return _Transportr.#globalSubscribr.subscribe(event, handler, context);
|
|
2011
|
-
}
|
|
2012
|
-
/**
|
|
2013
|
-
* Removes a {@link EventRegistration} from the global event handler.
|
|
2014
|
-
*
|
|
2015
|
-
* @static
|
|
2016
|
-
* @param {EventRegistration} eventRegistration The {@link EventRegistration} to remove.
|
|
2017
|
-
* @returns {boolean} True if the {@link EventRegistration} was removed, false otherwise.
|
|
2018
|
-
*/
|
|
2019
|
-
static unregister(eventRegistration) {
|
|
2020
|
-
return _Transportr.#globalSubscribr.unsubscribe(eventRegistration);
|
|
2021
|
-
}
|
|
2022
|
-
/**
|
|
2023
|
-
* Aborts all active requests.
|
|
2024
|
-
* This is useful for when the user navigates away from the current page.
|
|
2025
|
-
* This will also clear the {@link Transportr#activeRequests} array.
|
|
2026
|
-
* This is called automatically when the {@link Transportr#abort} method is called.
|
|
2027
|
-
*
|
|
2028
|
-
* @static
|
|
2029
|
-
* @returns {void}
|
|
2030
|
-
*/
|
|
2031
|
-
static abortAll() {
|
|
2032
|
-
for (const signalController of this.#activeRequests) {
|
|
2033
|
-
signalController.abort();
|
|
2034
|
-
}
|
|
2035
|
-
this.#activeRequests = [];
|
|
2036
|
-
}
|
|
2037
2291
|
/**
|
|
2038
2292
|
* @static
|
|
2039
2293
|
* @constant {Object<string, HttpRequestMethod>}
|
|
@@ -2113,15 +2367,7 @@ var Transportr = (() => {
|
|
|
2113
2367
|
* @static
|
|
2114
2368
|
* @constant {Object<string, TransportrEvent>}
|
|
2115
2369
|
*/
|
|
2116
|
-
static
|
|
2117
|
-
CONFIGURED: "configured",
|
|
2118
|
-
SUCCESS: "success",
|
|
2119
|
-
ERROR: "error",
|
|
2120
|
-
ABORTED: "aborted",
|
|
2121
|
-
TIMEOUT: "timeout",
|
|
2122
|
-
COMPLETE: "complete",
|
|
2123
|
-
ALL_COMPLETE: "all-complete"
|
|
2124
|
-
});
|
|
2370
|
+
static RequestEvents = RequestEvents;
|
|
2125
2371
|
/**
|
|
2126
2372
|
* @private
|
|
2127
2373
|
* @static
|
|
@@ -2131,7 +2377,7 @@ var Transportr = (() => {
|
|
|
2131
2377
|
body: null,
|
|
2132
2378
|
cache: _Transportr.CachingPolicy.NO_STORE,
|
|
2133
2379
|
credentials: _Transportr.CredentialsPolicy.SAME_ORIGIN,
|
|
2134
|
-
headers: { [http_request_headers_default.CONTENT_TYPE]:
|
|
2380
|
+
headers: { [http_request_headers_default.CONTENT_TYPE]: mediaTypes.get(http_media_type_default.JSON).toString(), [http_request_headers_default.ACCEPT]: mediaTypes.get(http_media_type_default.JSON).toString() },
|
|
2135
2381
|
searchParams: {},
|
|
2136
2382
|
integrity: void 0,
|
|
2137
2383
|
keepalive: void 0,
|
|
@@ -2151,9 +2397,54 @@ var Transportr = (() => {
|
|
|
2151
2397
|
* @type {Map<TransportrEvent, ResponseStatus>}
|
|
2152
2398
|
*/
|
|
2153
2399
|
static #eventResponseStatuses = /* @__PURE__ */ new Map([
|
|
2154
|
-
[
|
|
2155
|
-
[
|
|
2400
|
+
[RequestEvents.ABORTED, new ResponseStatus(499, "Aborted")],
|
|
2401
|
+
[RequestEvents.TIMEOUT, new ResponseStatus(504, "Gateway Timeout")]
|
|
2156
2402
|
]);
|
|
2403
|
+
/**
|
|
2404
|
+
* Returns a {@link AbortSignal} used for aborting requests.
|
|
2405
|
+
*
|
|
2406
|
+
* @static
|
|
2407
|
+
* @returns {AbortSignal} A new {@link AbortSignal} instance.
|
|
2408
|
+
*/
|
|
2409
|
+
static abortSignal() {
|
|
2410
|
+
return new AbortSignal();
|
|
2411
|
+
}
|
|
2412
|
+
/**
|
|
2413
|
+
* Returns a {@link EventRegistration} used for subscribing to global events.
|
|
2414
|
+
*
|
|
2415
|
+
* @static
|
|
2416
|
+
* @param {TransportrEvent} event The event to subscribe to.
|
|
2417
|
+
* @param {function(Event, *): void} handler The event handler.
|
|
2418
|
+
* @param {*} context The context to bind the handler to.
|
|
2419
|
+
* @returns {EventRegistration} A new {@link EventRegistration} instance.
|
|
2420
|
+
*/
|
|
2421
|
+
static register(event, handler, context) {
|
|
2422
|
+
return _Transportr.#globalSubscribr.subscribe(event, handler, context);
|
|
2423
|
+
}
|
|
2424
|
+
/**
|
|
2425
|
+
* Removes a {@link EventRegistration} from the global event handler.
|
|
2426
|
+
*
|
|
2427
|
+
* @static
|
|
2428
|
+
* @param {EventRegistration} eventRegistration The {@link EventRegistration} to remove.
|
|
2429
|
+
* @returns {boolean} True if the {@link EventRegistration} was removed, false otherwise.
|
|
2430
|
+
*/
|
|
2431
|
+
static unregister(eventRegistration) {
|
|
2432
|
+
return _Transportr.#globalSubscribr.unsubscribe(eventRegistration);
|
|
2433
|
+
}
|
|
2434
|
+
/**
|
|
2435
|
+
* Aborts all active requests.
|
|
2436
|
+
* This is useful for when the user navigates away from the current page.
|
|
2437
|
+
* This will also clear the {@link Transportr#activeRequests} set.
|
|
2438
|
+
*
|
|
2439
|
+
* @static
|
|
2440
|
+
* @returns {void}
|
|
2441
|
+
*/
|
|
2442
|
+
static abortAll() {
|
|
2443
|
+
for (const abortSignal of this.#activeRequests) {
|
|
2444
|
+
abortSignal.abort(_abortEvent);
|
|
2445
|
+
}
|
|
2446
|
+
this.#activeRequests.clear();
|
|
2447
|
+
}
|
|
2157
2448
|
/**
|
|
2158
2449
|
* It returns the base {@link URL} for the API.
|
|
2159
2450
|
*
|
|
@@ -2252,26 +2543,27 @@ var Transportr = (() => {
|
|
|
2252
2543
|
return this.#request(path, options, { method: http_request_methods_default.HEAD });
|
|
2253
2544
|
}
|
|
2254
2545
|
/**
|
|
2255
|
-
* It
|
|
2546
|
+
* It returns a promise that resolves to the allowed request methods for the given resource path.
|
|
2256
2547
|
*
|
|
2257
2548
|
* @async
|
|
2258
2549
|
* @param {string} [path] The path to the resource.
|
|
2259
2550
|
* @param {RequestOptions} [options] The options for the request.
|
|
2260
|
-
* @returns {Promise<
|
|
2551
|
+
* @returns {Promise<string[]>} A promise that resolves to an array of allowed request methods for this resource.
|
|
2261
2552
|
*/
|
|
2262
2553
|
async options(path, options) {
|
|
2263
|
-
|
|
2554
|
+
const response = await this.#request(path, options, { method: http_request_methods_default.OPTIONS });
|
|
2555
|
+
return response.headers.get("allow").split(",").map((method) => method.trim());
|
|
2264
2556
|
}
|
|
2265
2557
|
/**
|
|
2266
2558
|
* It takes a path and options, and makes a request to the server.
|
|
2267
2559
|
*
|
|
2268
2560
|
* @async
|
|
2269
2561
|
* @param {string} [path] The path to the endpoint you want to hit.
|
|
2270
|
-
* @param {RequestOptions} [
|
|
2562
|
+
* @param {RequestOptions} [userOptions] The options for the request.
|
|
2271
2563
|
* @returns {Promise<ResponseBody>} The return value of the function is the return value of the function that is passed to the `then` method of the promise returned by the `fetch` method.
|
|
2272
2564
|
*/
|
|
2273
|
-
async request(path,
|
|
2274
|
-
return this.#request(path,
|
|
2565
|
+
async request(path, userOptions) {
|
|
2566
|
+
return this.#request(path, userOptions, {}, (response) => response);
|
|
2275
2567
|
}
|
|
2276
2568
|
/**
|
|
2277
2569
|
* It gets a JSON resource from the server.
|
|
@@ -2282,7 +2574,7 @@ var Transportr = (() => {
|
|
|
2282
2574
|
* @returns {Promise<JsonObject>} A promise that resolves to the response body as a JSON object.
|
|
2283
2575
|
*/
|
|
2284
2576
|
async getJson(path, options) {
|
|
2285
|
-
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]:
|
|
2577
|
+
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]: mediaTypes.get(http_media_type_default.JSON).toString() } }, _handleJson);
|
|
2286
2578
|
}
|
|
2287
2579
|
/**
|
|
2288
2580
|
* It gets the XML representation of the resource at the given path.
|
|
@@ -2293,7 +2585,7 @@ var Transportr = (() => {
|
|
|
2293
2585
|
* @returns {Promise<Document>} The result of the function call to #get.
|
|
2294
2586
|
*/
|
|
2295
2587
|
async getXml(path, options) {
|
|
2296
|
-
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]:
|
|
2588
|
+
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]: mediaTypes.get(http_media_type_default.XML).toString() } }, _handleXml);
|
|
2297
2589
|
}
|
|
2298
2590
|
/**
|
|
2299
2591
|
* Get the HTML content of the specified path.
|
|
@@ -2306,7 +2598,7 @@ var Transportr = (() => {
|
|
|
2306
2598
|
* method of the promise returned by the `#get` method.
|
|
2307
2599
|
*/
|
|
2308
2600
|
async getHtml(path, options) {
|
|
2309
|
-
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]:
|
|
2601
|
+
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]: mediaTypes.get(http_media_type_default.HTML).toString() } }, _handleHtml);
|
|
2310
2602
|
}
|
|
2311
2603
|
/**
|
|
2312
2604
|
* It returns a promise that resolves to the HTML fragment at the given path.
|
|
@@ -2318,7 +2610,7 @@ var Transportr = (() => {
|
|
|
2318
2610
|
* @returns {Promise<DocumentFragment>} A promise that resolves to an HTML fragment.
|
|
2319
2611
|
*/
|
|
2320
2612
|
async getHtmlFragment(path, options) {
|
|
2321
|
-
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]:
|
|
2613
|
+
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]: mediaTypes.get(http_media_type_default.HTML).toString() } }, _handleHtmlFragment);
|
|
2322
2614
|
}
|
|
2323
2615
|
/**
|
|
2324
2616
|
* It gets a script from the server, and appends the script to the {@link Document} {@link HTMLHeadElement}
|
|
@@ -2330,7 +2622,7 @@ var Transportr = (() => {
|
|
|
2330
2622
|
* @returns {Promise<void>} A promise that has been resolved.
|
|
2331
2623
|
*/
|
|
2332
2624
|
async getScript(path, options) {
|
|
2333
|
-
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]:
|
|
2625
|
+
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]: mediaTypes.get(http_media_type_default.JAVA_SCRIPT).toString() } }, _handleScript);
|
|
2334
2626
|
}
|
|
2335
2627
|
/**
|
|
2336
2628
|
* Gets a stylesheet from the server, and adds it as a {@link Blob} {@link URL}.
|
|
@@ -2341,7 +2633,7 @@ var Transportr = (() => {
|
|
|
2341
2633
|
* @returns {Promise<void>} A promise that has been resolved.
|
|
2342
2634
|
*/
|
|
2343
2635
|
async getStylesheet(path, options) {
|
|
2344
|
-
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]:
|
|
2636
|
+
return this.#get(path, options, { headers: { [http_request_headers_default.ACCEPT]: mediaTypes.get(http_media_type_default.CSS).toString() } }, _handleCss);
|
|
2345
2637
|
}
|
|
2346
2638
|
/**
|
|
2347
2639
|
* It returns a blob from the specified path.
|
|
@@ -2400,8 +2692,7 @@ var Transportr = (() => {
|
|
|
2400
2692
|
* @returns {Promise<ResponseBody>} The result of the #request method.
|
|
2401
2693
|
*/
|
|
2402
2694
|
async #get(path, userOptions, options, responseHandler) {
|
|
2403
|
-
|
|
2404
|
-
return this.#request(path, userOptions, options, responseHandler);
|
|
2695
|
+
return this.#request(path, userOptions, { ...options, method: http_request_methods_default.GET }, responseHandler);
|
|
2405
2696
|
}
|
|
2406
2697
|
/**
|
|
2407
2698
|
* It takes a path, options, and a response handler, and returns a promise that resolves to the
|
|
@@ -2418,135 +2709,151 @@ var Transportr = (() => {
|
|
|
2418
2709
|
*/
|
|
2419
2710
|
async #request(path, userOptions = {}, options = {}, responseHandler) {
|
|
2420
2711
|
if (object_type_default(path) == Object) {
|
|
2421
|
-
userOptions = path;
|
|
2422
|
-
path = void 0;
|
|
2712
|
+
[path, userOptions] = [void 0, path];
|
|
2423
2713
|
}
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
requestOptions.signal = signalController.signal;
|
|
2429
|
-
if (_Transportr.#needsSerialization(requestOptions.method, requestOptions.headers[http_request_headers_default.CONTENT_TYPE])) {
|
|
2430
|
-
try {
|
|
2431
|
-
requestOptions.body = JSON.stringify(requestOptions.body);
|
|
2432
|
-
} catch (error) {
|
|
2433
|
-
return Promise.reject(new HttpError(url, { cause: error }));
|
|
2434
|
-
}
|
|
2435
|
-
} else if (requestOptions.method == http_request_methods_default.GET && requestOptions.headers[http_request_headers_default.CONTENT_TYPE] != "") {
|
|
2436
|
-
delete requestOptions.headers[http_request_headers_default.CONTENT_TYPE];
|
|
2437
|
-
delete requestOptions.body;
|
|
2714
|
+
try {
|
|
2715
|
+
options = this.#processRequestOptions(userOptions, options);
|
|
2716
|
+
} catch (cause) {
|
|
2717
|
+
return Promise.reject(new HttpError("Unable to process request options", { cause }));
|
|
2438
2718
|
}
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2719
|
+
this.#publish({ name: RequestEvents.CONFIGURED, data: options, global: options.global });
|
|
2720
|
+
const url = _Transportr.#createUrl(this.#baseUrl, path);
|
|
2721
|
+
if (object_type_default(options.signal) != AbortSignal) {
|
|
2722
|
+
options.signal = new AbortSignal(options.signal);
|
|
2723
|
+
}
|
|
2724
|
+
options.signal.addEventListener(SignalEvents.ABORT, (event) => this.#publish({ name: RequestEvents.ABORTED, event, global: options.global }));
|
|
2725
|
+
options.signal.addEventListener(SignalEvents.TIMEOUT, (event) => this.#publish({ name: RequestEvents.TIMEOUT, event, global: options.global }));
|
|
2726
|
+
_Transportr.#activeRequests.add(options.signal);
|
|
2727
|
+
let response, result;
|
|
2443
2728
|
try {
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
response = await fetch(url, requestOptions);
|
|
2729
|
+
response = await fetch(url, new Proxy(options, { get: _Transportr.#requestOptionsProxyHandler(options.timeout) }));
|
|
2730
|
+
if (!responseHandler && response.status != 204 && response.headers.has(http_response_headers_default.CONTENT_TYPE)) {
|
|
2731
|
+
responseHandler = this.#getResponseHandler(response.headers.get(http_response_headers_default.CONTENT_TYPE));
|
|
2732
|
+
}
|
|
2733
|
+
result = await responseHandler?.(response) ?? response;
|
|
2450
2734
|
if (!response.ok) {
|
|
2451
|
-
return Promise.reject(this.#handleError(url, { status: _Transportr.#generateResponseStatusFromError("ResponseError", response), entity:
|
|
2735
|
+
return Promise.reject(this.#handleError(url, { status: _Transportr.#generateResponseStatusFromError("ResponseError", response), entity: result }));
|
|
2452
2736
|
}
|
|
2453
|
-
|
|
2454
|
-
this.#publish(_Transportr.Events.SUCCESS, requestOptions.global, result);
|
|
2737
|
+
this.#publish({ name: RequestEvents.SUCCESS, data: result, global: options.global });
|
|
2455
2738
|
} catch (error) {
|
|
2456
2739
|
return Promise.reject(this.#handleError(url, { cause: error, status: _Transportr.#generateResponseStatusFromError(error.name, response) }));
|
|
2457
2740
|
} finally {
|
|
2458
|
-
clearTimeout(
|
|
2459
|
-
if (!
|
|
2460
|
-
this.#publish(
|
|
2461
|
-
|
|
2462
|
-
if (
|
|
2463
|
-
|
|
2464
|
-
}
|
|
2465
|
-
if (_Transportr.#activeRequests.length === 0) {
|
|
2466
|
-
this.#publish(_Transportr.Events.ALL_COMPLETE, requestOptions.global, response);
|
|
2741
|
+
options.signal.clearTimeout();
|
|
2742
|
+
if (!options.signal.aborted) {
|
|
2743
|
+
this.#publish({ name: RequestEvents.COMPLETE, data: response, global: options.global });
|
|
2744
|
+
_Transportr.#activeRequests.delete(options.signal);
|
|
2745
|
+
if (_Transportr.#activeRequests.size === 0) {
|
|
2746
|
+
this.#publish({ name: RequestEvents.ALL_COMPLETE, global: options.global });
|
|
2467
2747
|
}
|
|
2468
2748
|
}
|
|
2469
2749
|
}
|
|
2470
2750
|
return result;
|
|
2471
2751
|
}
|
|
2472
2752
|
/**
|
|
2473
|
-
*
|
|
2753
|
+
* Creates the options for a {@link Transportr} instance.
|
|
2474
2754
|
*
|
|
2475
2755
|
* @private
|
|
2476
|
-
* @
|
|
2477
|
-
* @param {
|
|
2478
|
-
* @
|
|
2756
|
+
* @static
|
|
2757
|
+
* @param {RequestOptions} userOptions The {@link RequestOptions} to convert.
|
|
2758
|
+
* @param {RequestOptions} options The default {@link RequestOptions}.
|
|
2759
|
+
* @returns {RequestOptions} The converted {@link RequestOptions}.
|
|
2479
2760
|
*/
|
|
2480
|
-
#
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2761
|
+
static #createOptions({ body, headers: userHeaders, searchParams: userSearchParams, ...userOptions }, { headers, searchParams, ...options }) {
|
|
2762
|
+
return object_merge_default(options, userOptions, {
|
|
2763
|
+
body: [FormData, URLSearchParams, Object].includes(object_type_default(body)) ? new ParameterMap(body) : body,
|
|
2764
|
+
headers: _Transportr.#mergeOptions(new Headers(), userHeaders, headers),
|
|
2765
|
+
searchParams: _Transportr.#mergeOptions(new URLSearchParams(), userSearchParams, searchParams)
|
|
2766
|
+
});
|
|
2484
2767
|
}
|
|
2485
2768
|
/**
|
|
2486
|
-
*
|
|
2769
|
+
* Merge the user options and request options into the target.
|
|
2487
2770
|
*
|
|
2488
2771
|
* @private
|
|
2489
|
-
* @
|
|
2490
|
-
* @param {
|
|
2491
|
-
* @param {
|
|
2492
|
-
* @param {
|
|
2493
|
-
* @returns {
|
|
2494
|
-
*/
|
|
2495
|
-
#
|
|
2496
|
-
|
|
2497
|
-
|
|
2772
|
+
* @static
|
|
2773
|
+
* @param {Headers|URLSearchParams|FormData} target The target to merge the options into.
|
|
2774
|
+
* @param {Headers|URLSearchParams|FormData|Object} userOption The user options to merge into the target.
|
|
2775
|
+
* @param {Headers|URLSearchParams|FormData|Object} requestOption The request options to merge into the target.
|
|
2776
|
+
* @returns {Headers|URLSearchParams} The target.
|
|
2777
|
+
*/
|
|
2778
|
+
static #mergeOptions(target, userOption = {}, requestOption = {}) {
|
|
2779
|
+
for (const option of [userOption, requestOption]) {
|
|
2780
|
+
for (const [name, value] of option.entries?.() ?? Object.entries(option)) {
|
|
2781
|
+
target.set(name, value);
|
|
2782
|
+
}
|
|
2498
2783
|
}
|
|
2499
|
-
|
|
2784
|
+
return target;
|
|
2500
2785
|
}
|
|
2501
2786
|
/**
|
|
2502
|
-
*
|
|
2787
|
+
* Merges the user options and request options with the instance options into a new object that is used for the request.
|
|
2503
2788
|
*
|
|
2504
2789
|
* @private
|
|
2505
|
-
* @
|
|
2506
|
-
* @param {
|
|
2507
|
-
* @
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2790
|
+
* @param {RequestOptions} userOptions The user options to merge into the request options.
|
|
2791
|
+
* @param {RequestOptions} options The request options to merge into the user options.
|
|
2792
|
+
* @returns {RequestOptions} The merged options.
|
|
2793
|
+
*/
|
|
2794
|
+
#processRequestOptions({ body: userBody, headers: userHeaders, searchParams: userSearchParams, ...userOptions }, { headers, searchParams, ...options }) {
|
|
2795
|
+
const requestOptions = object_merge_default(this.#options, userOptions, options, {
|
|
2796
|
+
headers: _Transportr.#mergeOptions(new Headers(this.#options.headers), userHeaders, headers),
|
|
2797
|
+
searchParams: _Transportr.#mergeOptions(new URLSearchParams(this.#options.searchParams), userSearchParams, searchParams)
|
|
2798
|
+
});
|
|
2799
|
+
if (requestBodyMethods.includes(requestOptions.method)) {
|
|
2800
|
+
if ([ParameterMap, FormData, URLSearchParams, Object].includes(object_type_default(userBody))) {
|
|
2801
|
+
const contentType = requestOptions.headers.get(http_request_headers_default.CONTENT_TYPE);
|
|
2802
|
+
const mediaType = (mediaTypes.get(contentType) ?? MediaType.parse(contentType))?.subtype;
|
|
2803
|
+
if (mediaType == http_media_type_default.MULTIPART_FORM_DATA) {
|
|
2804
|
+
requestOptions.body = _Transportr.#mergeOptions(new FormData(requestOptions.body), userBody);
|
|
2805
|
+
} else if (mediaType == http_media_type_default.FORM) {
|
|
2806
|
+
requestOptions.body = _Transportr.#mergeOptions(new URLSearchParams(requestOptions.body), userBody);
|
|
2807
|
+
} else if (mediaType.includes("json")) {
|
|
2808
|
+
requestOptions.body = JSON.stringify(_Transportr.#mergeOptions(new ParameterMap(requestOptions.body), userBody));
|
|
2809
|
+
} else {
|
|
2810
|
+
requestOptions.body = _Transportr.#mergeOptions(new ParameterMap(requestOptions.body), userBody);
|
|
2811
|
+
}
|
|
2812
|
+
} else {
|
|
2813
|
+
requestOptions.body = userBody;
|
|
2814
|
+
}
|
|
2815
|
+
} else {
|
|
2816
|
+
requestOptions.headers.delete(http_request_headers_default.CONTENT_TYPE);
|
|
2817
|
+
if (!requestOptions.body?.isEmpty()) {
|
|
2818
|
+
_Transportr.#mergeOptions(requestOptions.searchParams, requestOptions.body);
|
|
2819
|
+
}
|
|
2820
|
+
requestOptions.body = void 0;
|
|
2518
2821
|
}
|
|
2822
|
+
return requestOptions;
|
|
2519
2823
|
}
|
|
2520
2824
|
/**
|
|
2521
|
-
*
|
|
2522
|
-
*
|
|
2825
|
+
* Returns a Proxy of the options object that traps for 'signal' access.
|
|
2826
|
+
* If the signal has not been aborted, then it will return a new signal with a timeout.
|
|
2523
2827
|
*
|
|
2524
2828
|
* @private
|
|
2525
2829
|
* @static
|
|
2526
|
-
* @
|
|
2527
|
-
* @
|
|
2528
|
-
* @param {URL} url The path to the resource you want to access. Used for error handling.
|
|
2529
|
-
* @param {ResponseHandler<ResponseBody>} [handler] The handler to use for processing the response.
|
|
2530
|
-
* @returns {Promise<ResponseBody>} The response is being returned.
|
|
2830
|
+
* @param {number} timeout The timeout in milliseconds before the signal is aborted.
|
|
2831
|
+
* @returns {Proxy<RequestOptions>} A proxy for the options object.
|
|
2531
2832
|
*/
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2833
|
+
static #requestOptionsProxyHandler(timeout) {
|
|
2834
|
+
return (target, property) => {
|
|
2835
|
+
const value = Reflect.get(target, property);
|
|
2836
|
+
return property == "signal" && !value.aborted ? value.withTimeout(timeout) : value;
|
|
2837
|
+
};
|
|
2838
|
+
}
|
|
2839
|
+
/**
|
|
2840
|
+
* It takes a url or a string, and returns a {@link URL} instance.
|
|
2841
|
+
* If the url is a string and starts with a slash, then the origin of the current page is used as the base url.
|
|
2842
|
+
*
|
|
2843
|
+
* @private
|
|
2844
|
+
* @static
|
|
2845
|
+
* @param {URL|string} url The URL to convert to a {@link URL} instance.
|
|
2846
|
+
* @returns {URL} A {@link URL} instance.
|
|
2847
|
+
* @throws {TypeError} If the url is not a string or {@link URL} instance.
|
|
2848
|
+
*/
|
|
2849
|
+
static #getBaseUrl(url) {
|
|
2850
|
+
switch (object_type_default(url)) {
|
|
2851
|
+
case URL:
|
|
2852
|
+
return url;
|
|
2853
|
+
case String:
|
|
2854
|
+
return new URL(url, url.startsWith("/") ? globalThis.location.origin : void 0);
|
|
2855
|
+
default:
|
|
2856
|
+
throw new TypeError("Invalid URL");
|
|
2550
2857
|
}
|
|
2551
2858
|
}
|
|
2552
2859
|
/**
|
|
@@ -2556,48 +2863,81 @@ var Transportr = (() => {
|
|
|
2556
2863
|
* @private
|
|
2557
2864
|
* @static
|
|
2558
2865
|
* @param {URL} url The URL to use as a base.
|
|
2559
|
-
* @param {string} [path] The path to the resource. This
|
|
2560
|
-
* @param {Object<string, string>} [searchParams={}] An object containing the query parameters to be added to the URL.
|
|
2866
|
+
* @param {string} [path] The optional, relative path to the resource. This MUST be a relative path, otherwise, you should create a new {@link Transportr} instance.
|
|
2561
2867
|
* @returns {URL} A new URL object with the pathname and origin of the url parameter, and the path parameter
|
|
2562
2868
|
* appended to the end of the pathname.
|
|
2563
2869
|
*/
|
|
2564
|
-
static #createUrl(url, path
|
|
2565
|
-
|
|
2566
|
-
if (path) {
|
|
2567
|
-
_url = path.startsWith("/") ? new URL(`${url.pathname.replace(endsWithSlashRegEx, "")}${path}`, url.origin) : new URL(path);
|
|
2568
|
-
} else {
|
|
2569
|
-
_url = new URL(url);
|
|
2570
|
-
}
|
|
2571
|
-
Object.entries(searchParams).forEach(([key, value]) => _url.searchParams.append(key, value));
|
|
2572
|
-
return _url;
|
|
2870
|
+
static #createUrl(url, path) {
|
|
2871
|
+
return path ? new URL(`${url.pathname.replace(endsWithSlashRegEx, "")}${path}`, url.origin) : new URL(url);
|
|
2573
2872
|
}
|
|
2574
2873
|
/**
|
|
2575
|
-
*
|
|
2576
|
-
* needs to be serialized.
|
|
2874
|
+
* Generates a ResponseStatus object based on the error name and the response.
|
|
2577
2875
|
*
|
|
2578
2876
|
* @private
|
|
2579
2877
|
* @static
|
|
2580
|
-
* @param {
|
|
2581
|
-
* @param {
|
|
2582
|
-
* @returns {
|
|
2878
|
+
* @param {string} errorName The name of the error.
|
|
2879
|
+
* @param {Response} response The response object returned by the fetch API.
|
|
2880
|
+
* @returns {ResponseStatus} The response status object.
|
|
2881
|
+
*/
|
|
2882
|
+
static #generateResponseStatusFromError(errorName, response) {
|
|
2883
|
+
switch (errorName) {
|
|
2884
|
+
case "AbortError":
|
|
2885
|
+
return _Transportr.#eventResponseStatuses.get(RequestEvents.ABORTED);
|
|
2886
|
+
case "TimeoutError":
|
|
2887
|
+
return _Transportr.#eventResponseStatuses.get(RequestEvents.TIMEOUT);
|
|
2888
|
+
default:
|
|
2889
|
+
return response ? new ResponseStatus(response.status, response.statusText) : new ResponseStatus(500, "Internal Server Error");
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2892
|
+
/**
|
|
2893
|
+
* Handles an error by logging it and throwing it.
|
|
2894
|
+
*
|
|
2895
|
+
* @private
|
|
2896
|
+
* @param {URL} url The path to the resource you want to access.
|
|
2897
|
+
* @param {import('./http-error.js').HttpErrorOptions} options The options for the HttpError.
|
|
2898
|
+
* @returns {HttpError} The HttpError.
|
|
2583
2899
|
*/
|
|
2584
|
-
|
|
2585
|
-
|
|
2900
|
+
#handleError(url, options) {
|
|
2901
|
+
const error = new HttpError(`An error has occurred with your request to: '${url}'`, options);
|
|
2902
|
+
this.#publish({ name: RequestEvents.ERROR, data: error });
|
|
2903
|
+
return error;
|
|
2586
2904
|
}
|
|
2587
2905
|
/**
|
|
2906
|
+
* Publishes an event to the global and instance subscribers.
|
|
2588
2907
|
*
|
|
2589
|
-
* @
|
|
2590
|
-
* @
|
|
2908
|
+
* @private
|
|
2909
|
+
* @param {Object} options The options for the event.
|
|
2910
|
+
* @param {string} options.name The name of the event.
|
|
2911
|
+
* @param {Event} [options.event] The event object.
|
|
2912
|
+
* @param {*} [options.data] The data to pass to the subscribers.
|
|
2913
|
+
* @param {boolean} [options.global=true] Whether or not to publish the event to the global subscribers.
|
|
2914
|
+
* @returns {void}
|
|
2591
2915
|
*/
|
|
2592
|
-
|
|
2593
|
-
if (
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2916
|
+
#publish({ name, event = new CustomEvent(name), data, global = true } = {}) {
|
|
2917
|
+
if (global) {
|
|
2918
|
+
_Transportr.#globalSubscribr.publish(name, event, data);
|
|
2919
|
+
}
|
|
2920
|
+
this.#subscribr.publish(name, event, data);
|
|
2921
|
+
}
|
|
2922
|
+
/**
|
|
2923
|
+
* Returns a response handler for the given content type.
|
|
2924
|
+
*
|
|
2925
|
+
* @private
|
|
2926
|
+
* @param {string} contentType The content type of the response.
|
|
2927
|
+
* @returns {ResponseHandler<ResponseBody>} The response handler.
|
|
2928
|
+
*/
|
|
2929
|
+
#getResponseHandler(contentType) {
|
|
2930
|
+
let handler;
|
|
2931
|
+
const mediaType = MediaType.parse(contentType);
|
|
2932
|
+
if (mediaType) {
|
|
2933
|
+
for (const [responseHandler, contentTypes] of _Transportr.#contentTypeHandlers) {
|
|
2934
|
+
if (contentTypes.has(mediaType.type) || contentTypes.has(mediaType.subtype)) {
|
|
2935
|
+
handler = responseHandler;
|
|
2936
|
+
break;
|
|
2597
2937
|
}
|
|
2598
2938
|
}
|
|
2599
2939
|
}
|
|
2600
|
-
return
|
|
2940
|
+
return handler;
|
|
2601
2941
|
}
|
|
2602
2942
|
/**
|
|
2603
2943
|
* A String value that is used in the creation of the default string
|