@d1g1tal/transportr 1.2.1 → 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 +1462 -1114
- 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 +305 -318
- 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) */
|
|
@@ -1462,455 +1006,1231 @@ var Transportr = (() => {
|
|
|
1462
1006
|
// src/http-response-headers.js
|
|
1463
1007
|
var HttpResponseHeader = {
|
|
1464
1008
|
/**
|
|
1465
|
-
* 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.
|
|
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.
|
|
1010
|
+
*
|
|
1011
|
+
* @example
|
|
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
|
|
1466
1241
|
*
|
|
1467
1242
|
* @example
|
|
1468
|
-
*
|
|
1243
|
+
* set-cookie: UserID=JohnDoe, Max-Age=3600, Version=1
|
|
1244
|
+
* Permanent
|
|
1469
1245
|
*/
|
|
1470
|
-
|
|
1246
|
+
SET_COOKIE: "set-cookie",
|
|
1471
1247
|
/**
|
|
1472
|
-
*
|
|
1248
|
+
* CGI header field specifying the status of the HTTP response. Normal HTTP responses use a separate "Status-Line" instead, defined by RFC 7230.
|
|
1473
1249
|
*
|
|
1474
1250
|
* @example
|
|
1475
|
-
*
|
|
1251
|
+
* status: 200 OK
|
|
1476
1252
|
*/
|
|
1477
|
-
|
|
1253
|
+
STATUS: "status",
|
|
1478
1254
|
/**
|
|
1479
|
-
*
|
|
1255
|
+
* A HSTS Policy informing the HTTP client how long to cache the HTTPS only policy and whether this applies to subdomains.
|
|
1480
1256
|
*
|
|
1481
1257
|
* @example
|
|
1482
|
-
*
|
|
1258
|
+
* strict-transport-security: max-age=16070400, includeSubDomains
|
|
1259
|
+
* Permanent
|
|
1483
1260
|
*/
|
|
1484
|
-
|
|
1261
|
+
STRICT_TRANSPORT_SECURITY: "strict-transport-security",
|
|
1485
1262
|
/**
|
|
1486
|
-
*
|
|
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.
|
|
1487
1264
|
*
|
|
1488
1265
|
* @example
|
|
1489
|
-
*
|
|
1490
|
-
*
|
|
1266
|
+
* trailer: Max-Forwards
|
|
1267
|
+
* Permanent
|
|
1491
1268
|
*/
|
|
1492
|
-
|
|
1269
|
+
TRAILER: "trailer",
|
|
1493
1270
|
/**
|
|
1494
|
-
*
|
|
1271
|
+
* The form of encoding used to safely transfer the entity to the user. Currently defined methods are: chunked, compress, deflate, gzip, identity.
|
|
1495
1272
|
*
|
|
1496
1273
|
* @example
|
|
1497
|
-
*
|
|
1274
|
+
* transfer-encoding: chunked
|
|
1498
1275
|
* Permanent
|
|
1499
1276
|
*/
|
|
1500
|
-
|
|
1277
|
+
TRANSFER_ENCODING: "transfer-encoding",
|
|
1501
1278
|
/**
|
|
1502
|
-
*
|
|
1279
|
+
* Ask the client to upgrade to another protocol.
|
|
1503
1280
|
*
|
|
1504
1281
|
* @example
|
|
1505
|
-
*
|
|
1282
|
+
* upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
|
|
1506
1283
|
* Permanent
|
|
1507
1284
|
*/
|
|
1508
|
-
|
|
1285
|
+
UPGRADE: "upgrade",
|
|
1509
1286
|
/**
|
|
1510
|
-
*
|
|
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.
|
|
1511
1288
|
*
|
|
1512
1289
|
* @example
|
|
1513
|
-
*
|
|
1290
|
+
* vary: *
|
|
1514
1291
|
* Permanent
|
|
1515
1292
|
*/
|
|
1516
|
-
|
|
1293
|
+
VARY: "vary",
|
|
1517
1294
|
/**
|
|
1518
|
-
*
|
|
1295
|
+
* Informs the client of proxies through which the response was sent.
|
|
1519
1296
|
*
|
|
1520
1297
|
* @example
|
|
1521
|
-
*
|
|
1298
|
+
* via: 1.0 fred, 1.1 example.com (Apache/1.1)
|
|
1522
1299
|
* Permanent
|
|
1523
1300
|
*/
|
|
1524
|
-
|
|
1301
|
+
VIA: "via",
|
|
1525
1302
|
/**
|
|
1526
|
-
*
|
|
1303
|
+
* A general warning about possible problems with the entity body.
|
|
1527
1304
|
*
|
|
1528
1305
|
* @example
|
|
1529
|
-
*
|
|
1306
|
+
* warning: 199 Miscellaneous warning
|
|
1530
1307
|
* Permanent
|
|
1531
1308
|
*/
|
|
1532
|
-
|
|
1309
|
+
WARNING: "warning",
|
|
1533
1310
|
/**
|
|
1534
|
-
*
|
|
1311
|
+
* Indicates the authentication scheme that should be used to access the requested entity.
|
|
1535
1312
|
*
|
|
1536
1313
|
* @example
|
|
1537
|
-
*
|
|
1314
|
+
* www-authenticate: Basic
|
|
1538
1315
|
* Permanent
|
|
1539
1316
|
*/
|
|
1540
|
-
|
|
1317
|
+
WWW_AUTHENTICATE: "www-authenticate",
|
|
1541
1318
|
/**
|
|
1542
|
-
*
|
|
1319
|
+
* Cross-site scripting (XSS) filter
|
|
1543
1320
|
*
|
|
1544
1321
|
* @example
|
|
1545
|
-
*
|
|
1546
|
-
* Permanent
|
|
1322
|
+
* x-xss-protection: 1, mode=block
|
|
1547
1323
|
*/
|
|
1548
|
-
|
|
1324
|
+
X_XSS_PROTECTION: "x-xss-protection",
|
|
1549
1325
|
/**
|
|
1550
|
-
* The
|
|
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).
|
|
1551
1329
|
*
|
|
1552
1330
|
* @example
|
|
1553
|
-
* content-
|
|
1554
|
-
* Permanent
|
|
1331
|
+
* content-security-policy: default-src
|
|
1555
1332
|
*/
|
|
1556
|
-
|
|
1333
|
+
CONTENT_SECURITY_POLICY: "content-security-policy",
|
|
1557
1334
|
/**
|
|
1558
|
-
* 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.
|
|
1559
1336
|
*
|
|
1560
1337
|
* @example
|
|
1561
|
-
* content-
|
|
1562
|
-
* Permanent
|
|
1338
|
+
* x-content-type-options: nosniff
|
|
1563
1339
|
*/
|
|
1564
|
-
|
|
1340
|
+
X_CONTENT_TYPE_OPTIONS: "x-content-type-options",
|
|
1565
1341
|
/**
|
|
1566
|
-
*
|
|
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)
|
|
1567
1343
|
*
|
|
1568
1344
|
* @example
|
|
1569
|
-
*
|
|
1570
|
-
* Permanent
|
|
1345
|
+
* x-powered-by: PHP/5.4.0
|
|
1571
1346
|
*/
|
|
1572
|
-
|
|
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;
|
|
1573
1634
|
/**
|
|
1574
|
-
*
|
|
1635
|
+
* Create a new MediaTypeParameters instance.
|
|
1575
1636
|
*
|
|
1576
|
-
* @
|
|
1577
|
-
* content-location: /index.htm
|
|
1578
|
-
* Permanent
|
|
1637
|
+
* @param {Array<Array<string>>} entries An array of [name, value] tuples.
|
|
1579
1638
|
*/
|
|
1580
|
-
|
|
1639
|
+
constructor(entries) {
|
|
1640
|
+
this.#map = new Map(entries);
|
|
1641
|
+
}
|
|
1581
1642
|
/**
|
|
1582
|
-
*
|
|
1643
|
+
* Gets the number of media type parameters.
|
|
1583
1644
|
*
|
|
1584
|
-
* @
|
|
1585
|
-
* content-range: bytes 21010-47021/47022
|
|
1586
|
-
* Permanent
|
|
1645
|
+
* @returns {number} The number of media type parameters
|
|
1587
1646
|
*/
|
|
1588
|
-
|
|
1647
|
+
get size() {
|
|
1648
|
+
return this.#map.size;
|
|
1649
|
+
}
|
|
1589
1650
|
/**
|
|
1590
|
-
*
|
|
1651
|
+
* Gets the media type parameter value for the supplied name.
|
|
1591
1652
|
*
|
|
1592
|
-
* @
|
|
1593
|
-
*
|
|
1594
|
-
* Permanent
|
|
1653
|
+
* @param {string} name The name of the media type parameter to retrieve.
|
|
1654
|
+
* @returns {string} The media type parameter value.
|
|
1595
1655
|
*/
|
|
1596
|
-
|
|
1656
|
+
get(name) {
|
|
1657
|
+
return this.#map.get(asciiLowercase(String(name)));
|
|
1658
|
+
}
|
|
1597
1659
|
/**
|
|
1598
|
-
*
|
|
1660
|
+
* Indicates whether the media type parameter with the specified name exists or not.
|
|
1599
1661
|
*
|
|
1600
|
-
* @
|
|
1601
|
-
*
|
|
1602
|
-
* 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.
|
|
1603
1664
|
*/
|
|
1604
|
-
|
|
1665
|
+
has(name) {
|
|
1666
|
+
return this.#map.has(asciiLowercase(String(name)));
|
|
1667
|
+
}
|
|
1605
1668
|
/**
|
|
1606
|
-
*
|
|
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.
|
|
1607
1671
|
*
|
|
1608
|
-
* @
|
|
1609
|
-
*
|
|
1610
|
-
*
|
|
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.
|
|
1611
1675
|
*/
|
|
1612
|
-
|
|
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
|
+
}
|
|
1613
1688
|
/**
|
|
1614
|
-
*
|
|
1615
|
-
*
|
|
1616
|
-
* @example
|
|
1617
|
-
* expires: Thu, 01 Dec 1994 16:00:00 GMT
|
|
1618
|
-
* Permanent
|
|
1689
|
+
* Clears all the media type parameters.
|
|
1619
1690
|
*/
|
|
1620
|
-
|
|
1691
|
+
clear() {
|
|
1692
|
+
this.#map.clear();
|
|
1693
|
+
}
|
|
1621
1694
|
/**
|
|
1622
|
-
*
|
|
1695
|
+
* Removes the media type parameter using the specified name.
|
|
1623
1696
|
*
|
|
1624
|
-
* @
|
|
1625
|
-
*
|
|
1626
|
-
* 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.
|
|
1627
1699
|
*/
|
|
1628
|
-
|
|
1700
|
+
delete(name) {
|
|
1701
|
+
name = asciiLowercase(String(name));
|
|
1702
|
+
return this.#map.delete(name);
|
|
1703
|
+
}
|
|
1629
1704
|
/**
|
|
1630
|
-
*
|
|
1705
|
+
* Executes a provided function once per each name/value pair in the MediaTypeParameters, in insertion order.
|
|
1631
1706
|
*
|
|
1632
|
-
* @
|
|
1633
|
-
*
|
|
1634
|
-
* 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.
|
|
1635
1709
|
*/
|
|
1636
|
-
|
|
1710
|
+
forEach(callback, thisArg) {
|
|
1711
|
+
this.#map.forEach(callback, thisArg);
|
|
1712
|
+
}
|
|
1637
1713
|
/**
|
|
1638
|
-
*
|
|
1714
|
+
* Returns an iterable of parameter names.
|
|
1639
1715
|
*
|
|
1640
|
-
* @
|
|
1641
|
-
* location: http://www.w3.org/pub/WWW/People.html
|
|
1642
|
-
* Permanent
|
|
1716
|
+
* @returns {IterableIterator<string>} The {@link IterableIterator} of media type parameter names.
|
|
1643
1717
|
*/
|
|
1644
|
-
|
|
1718
|
+
keys() {
|
|
1719
|
+
return this.#map.keys();
|
|
1720
|
+
}
|
|
1645
1721
|
/**
|
|
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.
|
|
1722
|
+
* Returns an iterable of parameter values.
|
|
1648
1723
|
*
|
|
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
|
|
1724
|
+
* @returns {IterableIterator<string>} The {@link IterableIterator} of media type parameter values.
|
|
1652
1725
|
*/
|
|
1653
|
-
|
|
1726
|
+
values() {
|
|
1727
|
+
return this.#map.values();
|
|
1728
|
+
}
|
|
1654
1729
|
/**
|
|
1655
|
-
*
|
|
1730
|
+
* Returns an iterable of name, value pairs for every parameter entry in the media type parameters.
|
|
1656
1731
|
*
|
|
1657
|
-
* @
|
|
1658
|
-
* pragma: no-cache
|
|
1659
|
-
* Permanent
|
|
1732
|
+
* @returns {IterableIterator<Array<Array<string>>>} The media type parameter entries.
|
|
1660
1733
|
*/
|
|
1661
|
-
|
|
1734
|
+
entries() {
|
|
1735
|
+
return this.#map.entries();
|
|
1736
|
+
}
|
|
1662
1737
|
/**
|
|
1663
|
-
*
|
|
1738
|
+
* A method that returns the default iterator for the {@link MediaTypeParameters}. Called by the semantics of the for-of statement.
|
|
1664
1739
|
*
|
|
1665
|
-
* @
|
|
1666
|
-
* proxy-authenticate: Basic
|
|
1667
|
-
* Permanent
|
|
1740
|
+
* @returns {Iterator<string, string, undefined>} The {@link Symbol.iterator} for the media type parameters.
|
|
1668
1741
|
*/
|
|
1669
|
-
|
|
1742
|
+
[Symbol.iterator]() {
|
|
1743
|
+
return this.#map[Symbol.iterator]();
|
|
1744
|
+
}
|
|
1670
1745
|
/**
|
|
1671
|
-
*
|
|
1746
|
+
* Returns a string representation of the media type parameters.
|
|
1747
|
+
* This method is called by the `String()` function.
|
|
1672
1748
|
*
|
|
1673
1749
|
* @example
|
|
1674
|
-
*
|
|
1675
|
-
*
|
|
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.
|
|
1676
1760
|
*/
|
|
1677
|
-
|
|
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;
|
|
1678
1863
|
/**
|
|
1679
|
-
*
|
|
1864
|
+
* Create a new MediaType instance from a string representation.
|
|
1680
1865
|
*
|
|
1681
|
-
* @
|
|
1682
|
-
*
|
|
1683
|
-
* retry-after: Fri, 07 Nov 2014 23:59:59 GMT
|
|
1684
|
-
* Permanent
|
|
1866
|
+
* @param {string} mediaType The media type to parse.
|
|
1867
|
+
* @param {Object} [parameters] Optional parameters.
|
|
1685
1868
|
*/
|
|
1686
|
-
|
|
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
|
+
}
|
|
1687
1875
|
/**
|
|
1688
|
-
*
|
|
1876
|
+
* Static factory method for parsing a media type.
|
|
1689
1877
|
*
|
|
1690
|
-
* @
|
|
1691
|
-
*
|
|
1692
|
-
* 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.
|
|
1693
1880
|
*/
|
|
1694
|
-
|
|
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
|
+
}
|
|
1695
1888
|
/**
|
|
1696
|
-
*
|
|
1889
|
+
* Gets the media type essence (type/subtype).
|
|
1697
1890
|
*
|
|
1698
|
-
* @
|
|
1699
|
-
* set-cookie: UserID=JohnDoe, Max-Age=3600, Version=1
|
|
1700
|
-
* Permanent
|
|
1891
|
+
* @returns {string} The media type without any parameters
|
|
1701
1892
|
*/
|
|
1702
|
-
|
|
1893
|
+
get essence() {
|
|
1894
|
+
return `${this.#type}/${this.#subtype}`;
|
|
1895
|
+
}
|
|
1703
1896
|
/**
|
|
1704
|
-
*
|
|
1897
|
+
* Gets the type.
|
|
1705
1898
|
*
|
|
1706
|
-
* @
|
|
1707
|
-
* status: 200 OK
|
|
1899
|
+
* @returns {string} The type.
|
|
1708
1900
|
*/
|
|
1709
|
-
|
|
1901
|
+
get type() {
|
|
1902
|
+
return this.#type;
|
|
1903
|
+
}
|
|
1710
1904
|
/**
|
|
1711
|
-
*
|
|
1712
|
-
*
|
|
1713
|
-
* @example
|
|
1714
|
-
* strict-transport-security: max-age=16070400, includeSubDomains
|
|
1715
|
-
* Permanent
|
|
1905
|
+
* Sets the type.
|
|
1716
1906
|
*/
|
|
1717
|
-
|
|
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
|
+
}
|
|
1718
1917
|
/**
|
|
1719
|
-
*
|
|
1918
|
+
* Gets the subtype.
|
|
1720
1919
|
*
|
|
1721
|
-
* @
|
|
1722
|
-
* trailer: Max-Forwards
|
|
1723
|
-
* Permanent
|
|
1920
|
+
* @returns {string} The subtype.
|
|
1724
1921
|
*/
|
|
1725
|
-
|
|
1922
|
+
get subtype() {
|
|
1923
|
+
return this.#subtype;
|
|
1924
|
+
}
|
|
1726
1925
|
/**
|
|
1727
|
-
*
|
|
1728
|
-
*
|
|
1729
|
-
* @example
|
|
1730
|
-
* transfer-encoding: chunked
|
|
1731
|
-
* Permanent
|
|
1926
|
+
* Sets the subtype.
|
|
1732
1927
|
*/
|
|
1733
|
-
|
|
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
|
+
}
|
|
1734
1938
|
/**
|
|
1735
|
-
*
|
|
1939
|
+
* Gets the parameters.
|
|
1736
1940
|
*
|
|
1737
|
-
* @
|
|
1738
|
-
* upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
|
|
1739
|
-
* Permanent
|
|
1941
|
+
* @returns {MediaTypeParameters} The media type parameters.
|
|
1740
1942
|
*/
|
|
1741
|
-
|
|
1943
|
+
get parameters() {
|
|
1944
|
+
return this.#parameters;
|
|
1945
|
+
}
|
|
1742
1946
|
/**
|
|
1743
|
-
*
|
|
1947
|
+
* Gets the serialized version of the media type.
|
|
1744
1948
|
*
|
|
1745
|
-
* @
|
|
1746
|
-
* vary: *
|
|
1747
|
-
* Permanent
|
|
1949
|
+
* @returns {string} The serialized media type.
|
|
1748
1950
|
*/
|
|
1749
|
-
|
|
1951
|
+
toString() {
|
|
1952
|
+
return serializer_default(this);
|
|
1953
|
+
}
|
|
1750
1954
|
/**
|
|
1751
|
-
*
|
|
1955
|
+
* Determines if this instance is a JavaScript media type.
|
|
1752
1956
|
*
|
|
1753
|
-
* @
|
|
1754
|
-
*
|
|
1755
|
-
*
|
|
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.
|
|
1756
1960
|
*/
|
|
1757
|
-
|
|
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
|
+
}
|
|
1758
1997
|
/**
|
|
1759
|
-
*
|
|
1998
|
+
* Determines if this instance is an XML media type.
|
|
1760
1999
|
*
|
|
1761
|
-
* @
|
|
1762
|
-
* warning: 199 Miscellaneous warning
|
|
1763
|
-
* Permanent
|
|
2000
|
+
* @returns {boolean} true if this instance represents an XML media type, false otherwise.
|
|
1764
2001
|
*/
|
|
1765
|
-
|
|
2002
|
+
isXML() {
|
|
2003
|
+
return this.#subtype === "xml" && (this.#type === "text" || this.#type === "application") || this.#subtype.endsWith("+xml");
|
|
2004
|
+
}
|
|
1766
2005
|
/**
|
|
1767
|
-
*
|
|
2006
|
+
* Determines if this instance is an HTML media type.
|
|
1768
2007
|
*
|
|
1769
|
-
* @
|
|
1770
|
-
* www-authenticate: Basic
|
|
1771
|
-
* Permanent
|
|
2008
|
+
* @returns {boolean} true if this instance represents an HTML media type, false otherwise.
|
|
1772
2009
|
*/
|
|
1773
|
-
|
|
2010
|
+
isHTML() {
|
|
2011
|
+
return this.#subtype === "html" && this.#type === "text";
|
|
2012
|
+
}
|
|
1774
2013
|
/**
|
|
1775
|
-
*
|
|
2014
|
+
* Gets the name of the class.
|
|
1776
2015
|
*
|
|
1777
|
-
* @
|
|
1778
|
-
* x-xss-protection: 1, mode=block
|
|
2016
|
+
* @returns {string} The class name
|
|
1779
2017
|
*/
|
|
1780
|
-
|
|
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;
|
|
1781
2059
|
/**
|
|
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).
|
|
1785
|
-
*
|
|
1786
|
-
* @example
|
|
1787
|
-
* content-security-policy: default-src
|
|
2060
|
+
* @param {AbortSignal} signal The signal to listen to
|
|
1788
2061
|
*/
|
|
1789
|
-
|
|
2062
|
+
constructor(signal) {
|
|
2063
|
+
super();
|
|
2064
|
+
this.#abortController = new AbortController();
|
|
2065
|
+
signal?.addEventListener(SignalEvents.ABORT, (event) => this.#abort(event));
|
|
2066
|
+
}
|
|
1790
2067
|
/**
|
|
1791
|
-
*
|
|
2068
|
+
* Returns an {@link AbortSignal} instance that is already set as aborted.
|
|
1792
2069
|
*
|
|
1793
|
-
* @
|
|
1794
|
-
*
|
|
2070
|
+
* @static
|
|
2071
|
+
* @returns {AbortSignal} The abort signal
|
|
1795
2072
|
*/
|
|
1796
|
-
|
|
2073
|
+
static abort() {
|
|
2074
|
+
return NativeAbortSignal.abort();
|
|
2075
|
+
}
|
|
1797
2076
|
/**
|
|
1798
|
-
*
|
|
2077
|
+
* Returns an AbortSignal instance that will automatically abort after a specified time.
|
|
1799
2078
|
*
|
|
1800
|
-
* @
|
|
1801
|
-
*
|
|
2079
|
+
* @static
|
|
2080
|
+
* @param {number} time The time in milliseconds to wait before aborting
|
|
2081
|
+
* @returns {AbortSignal} The abort signal
|
|
1802
2082
|
*/
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
// src/response-status.js
|
|
1808
|
-
var ResponseStatus = class {
|
|
1809
|
-
/** @type {number} */
|
|
1810
|
-
#code;
|
|
1811
|
-
/** @type {string} */
|
|
1812
|
-
#text;
|
|
2083
|
+
static timeout(time) {
|
|
2084
|
+
return NativeAbortSignal.timeout(time);
|
|
2085
|
+
}
|
|
1813
2086
|
/**
|
|
2087
|
+
* The aborted property is a Boolean that indicates whether the request has been aborted (true) or not (false).
|
|
1814
2088
|
*
|
|
1815
|
-
* @
|
|
1816
|
-
* @param {string} text The status text from the {@link Response}
|
|
2089
|
+
* @returns {boolean} Whether the signal was aborted or not
|
|
1817
2090
|
*/
|
|
1818
|
-
|
|
1819
|
-
this.#
|
|
1820
|
-
this.#text = text;
|
|
2091
|
+
get aborted() {
|
|
2092
|
+
return this.#abortController.signal.aborted;
|
|
1821
2093
|
}
|
|
1822
2094
|
/**
|
|
1823
|
-
*
|
|
2095
|
+
* The reason property returns a DOMException object indicating the reason the operation was aborted, or null if the operation is not aborted.
|
|
1824
2096
|
*
|
|
1825
|
-
* @returns {
|
|
2097
|
+
* @returns {DOMException} The reason the signal was aborted
|
|
1826
2098
|
*/
|
|
1827
|
-
get
|
|
1828
|
-
return this.#
|
|
2099
|
+
get reason() {
|
|
2100
|
+
return this.#abortController.signal.reason;
|
|
1829
2101
|
}
|
|
1830
2102
|
/**
|
|
1831
|
-
*
|
|
2103
|
+
* throws the signal's abort reason if the signal has been aborted; otherwise it does nothing.
|
|
1832
2104
|
*
|
|
1833
|
-
* @returns {
|
|
2105
|
+
* @returns {void}
|
|
1834
2106
|
*/
|
|
1835
|
-
|
|
1836
|
-
|
|
2107
|
+
throwIfAborted() {
|
|
2108
|
+
this.#abortController.signal.throwIfAborted();
|
|
1837
2109
|
}
|
|
1838
2110
|
/**
|
|
1839
|
-
*
|
|
1840
|
-
*
|
|
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.
|
|
1841
2114
|
*
|
|
1842
|
-
* @
|
|
1843
|
-
* @returns {
|
|
2115
|
+
* @param {number} timeout The timeout in milliseconds
|
|
2116
|
+
* @returns {AbortSignal} The abort signal
|
|
1844
2117
|
*/
|
|
1845
|
-
|
|
1846
|
-
|
|
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;
|
|
1847
2124
|
}
|
|
1848
2125
|
/**
|
|
1849
|
-
*
|
|
2126
|
+
* Clears the timeout.
|
|
2127
|
+
* Note: This does not abort the signal, dispatch the timeout event, or reset the timeout.
|
|
2128
|
+
*
|
|
2129
|
+
* @returns {void}
|
|
2130
|
+
*/
|
|
2131
|
+
clearTimeout() {
|
|
2132
|
+
clearTimeout(this.#timeoutId);
|
|
2133
|
+
}
|
|
2134
|
+
/**
|
|
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
|
*
|
|
@@ -2187,8 +2478,8 @@ var Transportr = (() => {
|
|
|
2187
2478
|
* the specified options, where the method is GET.
|
|
2188
2479
|
*
|
|
2189
2480
|
* @async
|
|
2190
|
-
* @param {string} path
|
|
2191
|
-
* @param {RequestOptions} [options]
|
|
2481
|
+
* @param {string} [path] The path to the resource you want to get.
|
|
2482
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2192
2483
|
* @returns {Promise<ResponseBody>} A promise that resolves to the response of the request.
|
|
2193
2484
|
*/
|
|
2194
2485
|
async get(path, options) {
|
|
@@ -2198,9 +2489,9 @@ var Transportr = (() => {
|
|
|
2198
2489
|
* This function makes a POST request to the given path with the given body and options.
|
|
2199
2490
|
*
|
|
2200
2491
|
* @async
|
|
2201
|
-
* @param {string} path
|
|
2202
|
-
* @param {RequestBody} body
|
|
2203
|
-
* @param {RequestOptions} [options]
|
|
2492
|
+
* @param {string} [path] The path to the endpoint you want to call.
|
|
2493
|
+
* @param {RequestBody} body The body of the request.
|
|
2494
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2204
2495
|
* @returns {Promise<ResponseBody>} A promise that resolves to the response body.
|
|
2205
2496
|
*/
|
|
2206
2497
|
async post(path, body, options) {
|
|
@@ -2211,8 +2502,8 @@ var Transportr = (() => {
|
|
|
2211
2502
|
* the specified options, where the method is PUT.
|
|
2212
2503
|
*
|
|
2213
2504
|
* @async
|
|
2214
|
-
* @param {string} path
|
|
2215
|
-
* @param {RequestOptions} [options]
|
|
2505
|
+
* @param {string} [path] The path to the endpoint you want to call.
|
|
2506
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2216
2507
|
* @returns {Promise<ResponseBody>} The return value of the #request method.
|
|
2217
2508
|
*/
|
|
2218
2509
|
async put(path, options) {
|
|
@@ -2222,8 +2513,8 @@ var Transportr = (() => {
|
|
|
2222
2513
|
* It takes a path and options, and returns a request with the method set to PATCH.
|
|
2223
2514
|
*
|
|
2224
2515
|
* @async
|
|
2225
|
-
* @param {string} path
|
|
2226
|
-
* @param {RequestOptions} [options]
|
|
2516
|
+
* @param {string} [path] The path to the endpoint you want to hit.
|
|
2517
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2227
2518
|
* @returns {Promise<ResponseBody>} A promise that resolves to the response of the request.
|
|
2228
2519
|
*/
|
|
2229
2520
|
async patch(path, options) {
|
|
@@ -2233,8 +2524,8 @@ var Transportr = (() => {
|
|
|
2233
2524
|
* It takes a path and options, and returns a request with the method set to DELETE.
|
|
2234
2525
|
*
|
|
2235
2526
|
* @async
|
|
2236
|
-
* @param {string} path
|
|
2237
|
-
* @param {RequestOptions} [options]
|
|
2527
|
+
* @param {string} [path] The path to the resource you want to access.
|
|
2528
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2238
2529
|
* @returns {Promise<ResponseBody>} The result of the request.
|
|
2239
2530
|
*/
|
|
2240
2531
|
async delete(path, options) {
|
|
@@ -2244,111 +2535,112 @@ var Transportr = (() => {
|
|
|
2244
2535
|
* Returns the response headers of a request to the given path.
|
|
2245
2536
|
*
|
|
2246
2537
|
* @async
|
|
2247
|
-
* @param {string} path
|
|
2248
|
-
* @param {RequestOptions} [options]
|
|
2538
|
+
* @param {string} [path] The path to the resource you want to access.
|
|
2539
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2249
2540
|
* @returns {Promise<ResponseBody>} A promise that resolves to the response object.
|
|
2250
2541
|
*/
|
|
2251
2542
|
async head(path, options) {
|
|
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
|
-
* @param {string} path
|
|
2259
|
-
* @param {RequestOptions} [options]
|
|
2260
|
-
* @returns {Promise<
|
|
2549
|
+
* @param {string} [path] The path to the resource.
|
|
2550
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
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
|
-
* @param {string} path
|
|
2270
|
-
* @param {RequestOptions} [
|
|
2561
|
+
* @param {string} [path] The path to the endpoint you want to hit.
|
|
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.
|
|
2278
2570
|
*
|
|
2279
2571
|
* @async
|
|
2280
|
-
* @param {string} path
|
|
2281
|
-
* @param {RequestOptions} [options]
|
|
2572
|
+
* @param {string} [path] The path to the resource.
|
|
2573
|
+
* @param {RequestOptions} [options] The options object to pass to the request.
|
|
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.
|
|
2289
2581
|
*
|
|
2290
2582
|
* @async
|
|
2291
|
-
* @param {string} path
|
|
2292
|
-
* @param {RequestOptions} [options]
|
|
2583
|
+
* @param {string} [path] The path to the resource you want to get.
|
|
2584
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
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.
|
|
2300
2592
|
*
|
|
2301
2593
|
* @todo Add way to return portion of the retrieved HTML using a selector. Like jQuery.
|
|
2302
2594
|
* @async
|
|
2303
|
-
* @param {string} path
|
|
2304
|
-
* @param {RequestOptions} [options]
|
|
2595
|
+
* @param {string} [path] The path to the resource.
|
|
2596
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2305
2597
|
* @returns {Promise<Document>} The return value of the function is the return value of the function passed to the `then`
|
|
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.
|
|
2313
2605
|
*
|
|
2314
|
-
* @todo
|
|
2606
|
+
* @todo Add way to return portion of the retrieved HTML using a selector. Like jQuery.
|
|
2315
2607
|
* @async
|
|
2316
|
-
* @param {string} path
|
|
2317
|
-
* @param {RequestOptions} [options]
|
|
2608
|
+
* @param {string} [path] The path to the resource.
|
|
2609
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
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}
|
|
2325
2617
|
* CORS is enabled by default.
|
|
2326
2618
|
*
|
|
2327
2619
|
* @async
|
|
2328
|
-
* @param {string} path
|
|
2329
|
-
* @param {RequestOptions} [options]
|
|
2620
|
+
* @param {string} [path] The path to the script.
|
|
2621
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
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}.
|
|
2337
2629
|
*
|
|
2338
2630
|
* @async
|
|
2339
|
-
* @param {string} path
|
|
2340
|
-
* @param {RequestOptions} [options]
|
|
2631
|
+
* @param {string} [path] The path to the stylesheet.
|
|
2632
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
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.
|
|
2348
2640
|
*
|
|
2349
2641
|
* @async
|
|
2350
|
-
* @param {string} path
|
|
2351
|
-
* @param {RequestOptions} [options]
|
|
2642
|
+
* @param {string} [path] The path to the resource.
|
|
2643
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2352
2644
|
* @returns {Promise<Blob>} A promise that resolves to a blob.
|
|
2353
2645
|
*/
|
|
2354
2646
|
async getBlob(path, options) {
|
|
@@ -2358,8 +2650,8 @@ var Transportr = (() => {
|
|
|
2358
2650
|
* It returns a promise that resolves to an object URL.
|
|
2359
2651
|
*
|
|
2360
2652
|
* @async
|
|
2361
|
-
* @param {string} path
|
|
2362
|
-
* @param {RequestOptions} [options]
|
|
2653
|
+
* @param {string|RequestOptions} [path] The path to the resource.
|
|
2654
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2363
2655
|
* @returns {Promise<string>} A promise that resolves to an object URL.
|
|
2364
2656
|
*/
|
|
2365
2657
|
async getImage(path, options) {
|
|
@@ -2369,8 +2661,8 @@ var Transportr = (() => {
|
|
|
2369
2661
|
* It gets a buffer from the specified path
|
|
2370
2662
|
*
|
|
2371
2663
|
* @async
|
|
2372
|
-
* @param {string} path
|
|
2373
|
-
* @param {RequestOptions} [options]
|
|
2664
|
+
* @param {string} [path] The path to the resource.
|
|
2665
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2374
2666
|
* @returns {Promise<ArrayBuffer>} A promise that resolves to a buffer.
|
|
2375
2667
|
*/
|
|
2376
2668
|
async getBuffer(path, options) {
|
|
@@ -2380,8 +2672,8 @@ var Transportr = (() => {
|
|
|
2380
2672
|
* It returns a readable stream of the response body from the specified path.
|
|
2381
2673
|
*
|
|
2382
2674
|
* @async
|
|
2383
|
-
* @param {string} path
|
|
2384
|
-
* @param {RequestOptions} [options]
|
|
2675
|
+
* @param {string} [path] The path to the resource.
|
|
2676
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2385
2677
|
* @returns {Promise<ReadableStream<Uint8Array>>} A readable stream.
|
|
2386
2678
|
*/
|
|
2387
2679
|
async getStream(path, options) {
|
|
@@ -2393,14 +2685,14 @@ var Transportr = (() => {
|
|
|
2393
2685
|
*
|
|
2394
2686
|
* @private
|
|
2395
2687
|
* @async
|
|
2396
|
-
* @param {string} path
|
|
2397
|
-
* @param {RequestOptions} [userOptions]
|
|
2398
|
-
* @param {RequestOptions} [options]
|
|
2399
|
-
* @param {ResponseHandler<ResponseBody>} [responseHandler]
|
|
2688
|
+
* @param {string} [path] The path to the endpoint you want to call.
|
|
2689
|
+
* @param {RequestOptions} [userOptions] The options passed to the public function to use for the request.
|
|
2690
|
+
* @param {RequestOptions} [options] The options for the request.
|
|
2691
|
+
* @param {ResponseHandler<ResponseBody>} [responseHandler] A function that will be called with the response object.
|
|
2400
2692
|
* @returns {Promise<ResponseBody>} The result of the #request method.
|
|
2401
2693
|
*/
|
|
2402
2694
|
async #get(path, userOptions, options, responseHandler) {
|
|
2403
|
-
return this.#request(path, userOptions, options, responseHandler);
|
|
2695
|
+
return this.#request(path, userOptions, { ...options, method: http_request_methods_default.GET }, responseHandler);
|
|
2404
2696
|
}
|
|
2405
2697
|
/**
|
|
2406
2698
|
* It takes a path, options, and a response handler, and returns a promise that resolves to the
|
|
@@ -2408,90 +2700,175 @@ var Transportr = (() => {
|
|
|
2408
2700
|
*
|
|
2409
2701
|
* @private
|
|
2410
2702
|
* @async
|
|
2411
|
-
* @param {string} path
|
|
2412
|
-
* @param {RequestOptions} [userOptions={}]
|
|
2413
|
-
* @param {RequestOptions} [options={}]
|
|
2414
|
-
* @param {ResponseHandler<ResponseBody>} [responseHandler]
|
|
2703
|
+
* @param {string} [path] The path to the resource you want to access.
|
|
2704
|
+
* @param {RequestOptions} [userOptions={}] The options passed to the public function to use for the request.
|
|
2705
|
+
* @param {RequestOptions} [options={}] The options to use for the request.
|
|
2706
|
+
* @param {ResponseHandler<ResponseBody>} [responseHandler] A function that will be called with the response body as a parameter. This
|
|
2415
2707
|
* is useful if you want to do something with the response body before returning it.
|
|
2416
2708
|
* @returns {Promise<ResponseBody>} The response from the API call.
|
|
2417
2709
|
*/
|
|
2418
2710
|
async #request(path, userOptions = {}, options = {}, responseHandler) {
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
requestOptions.body = JSON.stringify(requestOptions.body);
|
|
2427
|
-
} catch (error) {
|
|
2428
|
-
return Promise.reject(new HttpError(url, { cause: error }));
|
|
2429
|
-
}
|
|
2430
|
-
} else if (requestOptions.method == http_request_methods_default.GET && requestOptions.headers[http_request_headers_default.CONTENT_TYPE] != "") {
|
|
2431
|
-
delete requestOptions.headers[http_request_headers_default.CONTENT_TYPE];
|
|
2432
|
-
delete requestOptions.body;
|
|
2711
|
+
if (object_type_default(path) == Object) {
|
|
2712
|
+
[path, userOptions] = [void 0, path];
|
|
2713
|
+
}
|
|
2714
|
+
try {
|
|
2715
|
+
options = this.#processRequestOptions(userOptions, options);
|
|
2716
|
+
} catch (cause) {
|
|
2717
|
+
return Promise.reject(new HttpError("Unable to process request options", { cause }));
|
|
2433
2718
|
}
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
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;
|
|
2438
2728
|
try {
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
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;
|
|
2445
2734
|
if (!response.ok) {
|
|
2446
|
-
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 }));
|
|
2447
2736
|
}
|
|
2448
|
-
|
|
2449
|
-
this.#publish(_Transportr.Events.SUCCESS, requestOptions.global, result);
|
|
2737
|
+
this.#publish({ name: RequestEvents.SUCCESS, data: result, global: options.global });
|
|
2450
2738
|
} catch (error) {
|
|
2451
2739
|
return Promise.reject(this.#handleError(url, { cause: error, status: _Transportr.#generateResponseStatusFromError(error.name, response) }));
|
|
2452
2740
|
} finally {
|
|
2453
|
-
clearTimeout(
|
|
2454
|
-
if (!
|
|
2455
|
-
this.#publish(
|
|
2456
|
-
|
|
2457
|
-
if (
|
|
2458
|
-
|
|
2459
|
-
}
|
|
2460
|
-
if (_Transportr.#activeRequests.length === 0) {
|
|
2461
|
-
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 });
|
|
2462
2747
|
}
|
|
2463
2748
|
}
|
|
2464
2749
|
}
|
|
2465
2750
|
return result;
|
|
2466
2751
|
}
|
|
2467
2752
|
/**
|
|
2468
|
-
*
|
|
2753
|
+
* Creates the options for a {@link Transportr} instance.
|
|
2469
2754
|
*
|
|
2470
2755
|
* @private
|
|
2471
|
-
* @
|
|
2472
|
-
* @param {
|
|
2473
|
-
* @
|
|
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}.
|
|
2474
2760
|
*/
|
|
2475
|
-
#
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
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
|
+
});
|
|
2479
2767
|
}
|
|
2480
2768
|
/**
|
|
2481
|
-
*
|
|
2769
|
+
* Merge the user options and request options into the target.
|
|
2482
2770
|
*
|
|
2483
2771
|
* @private
|
|
2484
|
-
* @
|
|
2485
|
-
* @param {
|
|
2486
|
-
* @param {
|
|
2487
|
-
* @param {
|
|
2488
|
-
* @returns {
|
|
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
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
return target;
|
|
2785
|
+
}
|
|
2786
|
+
/**
|
|
2787
|
+
* Merges the user options and request options with the instance options into a new object that is used for the request.
|
|
2788
|
+
*
|
|
2789
|
+
* @private
|
|
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;
|
|
2821
|
+
}
|
|
2822
|
+
return requestOptions;
|
|
2823
|
+
}
|
|
2824
|
+
/**
|
|
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.
|
|
2827
|
+
*
|
|
2828
|
+
* @private
|
|
2829
|
+
* @static
|
|
2830
|
+
* @param {number} timeout The timeout in milliseconds before the signal is aborted.
|
|
2831
|
+
* @returns {Proxy<RequestOptions>} A proxy for the options object.
|
|
2489
2832
|
*/
|
|
2490
|
-
#
|
|
2491
|
-
|
|
2492
|
-
|
|
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");
|
|
2493
2857
|
}
|
|
2494
|
-
|
|
2858
|
+
}
|
|
2859
|
+
/**
|
|
2860
|
+
* It takes a URL, a path, and a set of search parameters, and returns a new URL with the path and
|
|
2861
|
+
* search parameters applied.
|
|
2862
|
+
*
|
|
2863
|
+
* @private
|
|
2864
|
+
* @static
|
|
2865
|
+
* @param {URL} url The URL to use as a base.
|
|
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.
|
|
2867
|
+
* @returns {URL} A new URL object with the pathname and origin of the url parameter, and the path parameter
|
|
2868
|
+
* appended to the end of the pathname.
|
|
2869
|
+
*/
|
|
2870
|
+
static #createUrl(url, path) {
|
|
2871
|
+
return path ? new URL(`${url.pathname.replace(endsWithSlashRegEx, "")}${path}`, url.origin) : new URL(url);
|
|
2495
2872
|
}
|
|
2496
2873
|
/**
|
|
2497
2874
|
* Generates a ResponseStatus object based on the error name and the response.
|
|
@@ -2505,91 +2882,62 @@ var Transportr = (() => {
|
|
|
2505
2882
|
static #generateResponseStatusFromError(errorName, response) {
|
|
2506
2883
|
switch (errorName) {
|
|
2507
2884
|
case "AbortError":
|
|
2508
|
-
return _Transportr.#eventResponseStatuses.get(
|
|
2885
|
+
return _Transportr.#eventResponseStatuses.get(RequestEvents.ABORTED);
|
|
2509
2886
|
case "TimeoutError":
|
|
2510
|
-
return _Transportr.#eventResponseStatuses.get(
|
|
2887
|
+
return _Transportr.#eventResponseStatuses.get(RequestEvents.TIMEOUT);
|
|
2511
2888
|
default:
|
|
2512
2889
|
return response ? new ResponseStatus(response.status, response.statusText) : new ResponseStatus(500, "Internal Server Error");
|
|
2513
2890
|
}
|
|
2514
2891
|
}
|
|
2515
2892
|
/**
|
|
2516
|
-
*
|
|
2517
|
-
* based on the response's content type
|
|
2893
|
+
* Handles an error by logging it and throwing it.
|
|
2518
2894
|
*
|
|
2519
2895
|
* @private
|
|
2520
|
-
* @
|
|
2521
|
-
* @
|
|
2522
|
-
* @
|
|
2523
|
-
* @param {URL} url - The path to the resource you want to access. Used for error handling.
|
|
2524
|
-
* @param {ResponseHandler<ResponseBody>} [handler] - The handler to use for processing the response.
|
|
2525
|
-
* @returns {Promise<ResponseBody>} The response is being returned.
|
|
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.
|
|
2526
2899
|
*/
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
mediaType = MediaType.parse(response.headers.get(http_response_headers_default.CONTENT_TYPE));
|
|
2532
|
-
if (mediaType) {
|
|
2533
|
-
for (const [responseHandler, contentTypes] of _Transportr.#contentTypeHandlers) {
|
|
2534
|
-
if (contentTypes.has(mediaType.type) || contentTypes.has(mediaType.subtype)) {
|
|
2535
|
-
handler = responseHandler;
|
|
2536
|
-
break;
|
|
2537
|
-
}
|
|
2538
|
-
}
|
|
2539
|
-
}
|
|
2540
|
-
}
|
|
2541
|
-
return (handler ?? _handleText)(response);
|
|
2542
|
-
} catch (error) {
|
|
2543
|
-
console.error("Unable to process response.", error, response);
|
|
2544
|
-
return Promise.reject(this.#handleError(url, { cause: error }));
|
|
2545
|
-
}
|
|
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;
|
|
2546
2904
|
}
|
|
2547
2905
|
/**
|
|
2548
|
-
*
|
|
2549
|
-
* search parameters applied.
|
|
2906
|
+
* Publishes an event to the global and instance subscribers.
|
|
2550
2907
|
*
|
|
2551
2908
|
* @private
|
|
2552
|
-
* @
|
|
2553
|
-
* @param {
|
|
2554
|
-
* @param {
|
|
2555
|
-
* @param {
|
|
2556
|
-
* @
|
|
2557
|
-
*
|
|
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}
|
|
2558
2915
|
*/
|
|
2559
|
-
|
|
2560
|
-
if (
|
|
2561
|
-
|
|
2916
|
+
#publish({ name, event = new CustomEvent(name), data, global = true } = {}) {
|
|
2917
|
+
if (global) {
|
|
2918
|
+
_Transportr.#globalSubscribr.publish(name, event, data);
|
|
2562
2919
|
}
|
|
2563
|
-
|
|
2564
|
-
return url;
|
|
2920
|
+
this.#subscribr.publish(name, event, data);
|
|
2565
2921
|
}
|
|
2566
2922
|
/**
|
|
2567
|
-
*
|
|
2568
|
-
* needs to be serialized.
|
|
2923
|
+
* Returns a response handler for the given content type.
|
|
2569
2924
|
*
|
|
2570
2925
|
* @private
|
|
2571
|
-
* @
|
|
2572
|
-
* @
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
* @returns {RequestOptions} The options to use for the request.
|
|
2583
|
-
*/
|
|
2584
|
-
static #convertRequestOptions(options) {
|
|
2585
|
-
if (!object_is_empty_default(options)) {
|
|
2586
|
-
for (const [{ property, type, converter }, option = options[property]] of _Transportr.#propertyTypeConverters) {
|
|
2587
|
-
if (option instanceof type) {
|
|
2588
|
-
options[property] = converter(option);
|
|
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;
|
|
2589
2937
|
}
|
|
2590
2938
|
}
|
|
2591
2939
|
}
|
|
2592
|
-
return
|
|
2940
|
+
return handler;
|
|
2593
2941
|
}
|
|
2594
2942
|
/**
|
|
2595
2943
|
* A String value that is used in the creation of the default string
|