@d1g1tal/transportr 0.0.2
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/LICENSE +21 -0
- package/README.md +2 -0
- package/dist/transportr.js +887 -0
- package/dist/transportr.min.js +4 -0
- package/dist/transportr.min.js.map +7 -0
- package/index.d.ts +5 -0
- package/index.js +5 -0
- package/package.json +70 -0
- package/src/http-media-type.d.ts +149 -0
- package/src/http-media-type.js +150 -0
- package/src/http-request-headers.d.ts +43 -0
- package/src/http-request-headers.js +306 -0
- package/src/http-request-methods.d.ts +12 -0
- package/src/http-request-methods.js +271 -0
- package/src/http-response-headers.d.ts +46 -0
- package/src/http-response-headers.js +344 -0
- package/src/transportr.d.ts +509 -0
- package/src/transportr.js +462 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
import { SetMultiMap } from '@d1g1tal/collections';
|
|
2
|
+
import { _objectMerge } from '@d1g1tal/chrysalis';
|
|
3
|
+
import { MediaType } from '@d1g1tal/media-type';
|
|
4
|
+
import HttpMediaType from './http-media-type.js';
|
|
5
|
+
import HttpRequestHeader from './http-request-headers.js';
|
|
6
|
+
import HttpRequestMethod from './http-request-methods.js';
|
|
7
|
+
import HttpResponseHeader from './http-response-headers.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @template T extends ResponseBody
|
|
11
|
+
* @typedef {function(Response): Promise<T>} ResponseHandler<T>
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** @typedef {Object<string, (boolean|string|number|Array)>} JsonObject */
|
|
15
|
+
/** @typedef {Blob|ArrayBuffer|TypedArray|DataView|FormData|URLSearchParams|string|ReadableStream} RequestBody */
|
|
16
|
+
/** @typedef {Blob|ArrayBuffer|FormData|string|ReadableStream} ResponseBody */
|
|
17
|
+
/** @typedef {'default'|'force-cache'|'no-cache'|'no-store'|'only-if-cached'|'reload'} RequestCache */
|
|
18
|
+
/** @typedef {'include'|'omit'|'same-origin'} RequestCredentials */
|
|
19
|
+
/** @typedef {Headers|Object<string, string>} RequestHeaders */
|
|
20
|
+
/** @typedef {'GET'|'POST'|'PUT'|'PATCH'|'DELETE'|'HEAD'|'OPTIONS'} RequestMethod */
|
|
21
|
+
/** @typedef {'cors'|'navigate'|'no-cors'|'same-origin'} RequestMode */
|
|
22
|
+
/** @typedef {'error'|'follow'|'manual'} RequestRedirect */
|
|
23
|
+
/** @typedef {''|'no-referrer'|'no-referrer-when-downgrade'|'origin'|'origin-when-cross-origin'|'same-origin'|'strict-origin'|'strict-origin-when-cross-origin'|'unsafe-url'} ReferrerPolicy */
|
|
24
|
+
/** @typedef {Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|BigInt64Array|BigUint64Array} TypedArray */
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The options for a {@link Request} object or the second parameter of a {@link fetch} request
|
|
28
|
+
*
|
|
29
|
+
* @typedef {Object} RequestOptions
|
|
30
|
+
* @property {RequestBody} body A RequestInit object or null to set request's body.
|
|
31
|
+
* @property {RequestCache} cache A string indicating how the request will interact with the browser's cache to set request's cache.
|
|
32
|
+
* @property {RequestCredentials} credentials A string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL. Sets request's credentials.
|
|
33
|
+
* @property {RequestHeaders} headers A Headers object, an object literal, or an array of two-item arrays to set request's headers.
|
|
34
|
+
* @property {string} integrity A cryptographic hash of the resource to be fetched by request. Sets request's integrity.
|
|
35
|
+
* @property {boolean} keepalive A boolean to set request's keepalive.
|
|
36
|
+
* @property {RequestMethod} method A string to set request's method.
|
|
37
|
+
* @property {RequestMode} mode A string to indicate whether the request will use CORS, or will be restricted to same-origin URLs. Sets request's mode.
|
|
38
|
+
* @property {RequestRedirect} redirect A string indicating whether request follows redirects, results in an error upon encountering a redirect, or returns the redirect (in an opaque fashion). Sets request's redirect.
|
|
39
|
+
* @property {string} referrer A string whose value is a same-origin URL, "about:client", or the empty string, to set request's referrer.
|
|
40
|
+
* @property {ReferrerPolicy} referrerPolicy A referrer policy to set request's referrerPolicy.
|
|
41
|
+
* @property {AbortSignal} signal An AbortSignal to set request's signal.
|
|
42
|
+
* @property {null} window Can only be null. Used to disassociate request from any Window.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/** @extends Error */
|
|
46
|
+
class HttpError extends Error {}
|
|
47
|
+
|
|
48
|
+
/** @type {RegExp} */
|
|
49
|
+
const endsWithSlashRegEx = /\/$/;
|
|
50
|
+
|
|
51
|
+
/** @type {ResponseHandler<string>} */
|
|
52
|
+
const _handleText = async (response) => await response.text();
|
|
53
|
+
|
|
54
|
+
/** @type {ResponseHandler<JsonObject>} */
|
|
55
|
+
const _handleJson = async (response) => await response.json();
|
|
56
|
+
|
|
57
|
+
/** @type {ResponseHandler<Blob>} */
|
|
58
|
+
const _handleBlob = async (response) => await response.blob();
|
|
59
|
+
|
|
60
|
+
/** @type {ResponseHandler<ArrayBuffer>} */
|
|
61
|
+
const _handleBuffer = async (response) => await response.arrayBuffer();
|
|
62
|
+
|
|
63
|
+
/** @type {ResponseHandler<ReadableStream<Uint8Array>} */
|
|
64
|
+
const _handleReadableStream = async (response) => response.body;
|
|
65
|
+
|
|
66
|
+
/** @type {ResponseHandler<Document>} */
|
|
67
|
+
const _handleXml = async (response) => new DOMParser().parseFromString(await response.text(), Transportr.MediaType.XML.essence);
|
|
68
|
+
|
|
69
|
+
export default class Transportr {
|
|
70
|
+
#baseUrl;
|
|
71
|
+
/**
|
|
72
|
+
* @static
|
|
73
|
+
* @constant {Object<string, MediaType>}
|
|
74
|
+
*/
|
|
75
|
+
static #MediaType = {
|
|
76
|
+
JSON: new MediaType(HttpMediaType.JSON),
|
|
77
|
+
XML: new MediaType(HttpMediaType.XML),
|
|
78
|
+
HTML: new MediaType(HttpMediaType.HTML),
|
|
79
|
+
SCRIPT: new MediaType(HttpMediaType.JAVA_SCRIPT),
|
|
80
|
+
TEXT: new MediaType(HttpMediaType.TEXT),
|
|
81
|
+
CSS: new MediaType(HttpMediaType.CSS),
|
|
82
|
+
WEBP: new MediaType(HttpMediaType.WEBP),
|
|
83
|
+
PNG: new MediaType(HttpMediaType.PNG),
|
|
84
|
+
GIF: new MediaType(HttpMediaType.GIF),
|
|
85
|
+
JPG: new MediaType(HttpMediaType.JPEG),
|
|
86
|
+
OTF: new MediaType(HttpMediaType.OTF),
|
|
87
|
+
WOFF: new MediaType(HttpMediaType.WOFF),
|
|
88
|
+
WOFF2: new MediaType(HttpMediaType.WOFF2),
|
|
89
|
+
TTF: new MediaType(HttpMediaType.TTF),
|
|
90
|
+
PDF: new MediaType(HttpMediaType.PDF)
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* @static
|
|
94
|
+
* @type {SetMultiMap<ResponseHandler<ResponseBody>, string>}
|
|
95
|
+
*/
|
|
96
|
+
static #contentTypeHandlers = new SetMultiMap([
|
|
97
|
+
[_handleJson, Transportr.#MediaType.JSON.subtype],
|
|
98
|
+
[_handleText, Transportr.#MediaType.HTML.subtype],
|
|
99
|
+
[_handleText, Transportr.#MediaType.SCRIPT.subtype],
|
|
100
|
+
[_handleText, Transportr.#MediaType.CSS.subtype],
|
|
101
|
+
[_handleText, Transportr.#MediaType.TEXT.subtype],
|
|
102
|
+
[_handleXml, Transportr.#MediaType.XML.subtype],
|
|
103
|
+
[_handleBlob, Transportr.#MediaType.GIF.subtype],
|
|
104
|
+
[_handleBlob, Transportr.#MediaType.JPG.subtype],
|
|
105
|
+
[_handleBlob, Transportr.#MediaType.PNG.subtype]
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Create a new Transportr instance with the provided location or origin and context path.
|
|
110
|
+
*
|
|
111
|
+
* @param {URL | string} [url = location.origin] The URL for {@link fetch} requests.
|
|
112
|
+
*/
|
|
113
|
+
constructor(url = location.origin) {
|
|
114
|
+
/** @type {URL} */
|
|
115
|
+
this.#baseUrl = url instanceof URL ? url : url.startsWith('/') ? new URL(url, location.origin) : new URL(url);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @static
|
|
120
|
+
* @constant {Object<string, 'GET'|'POST'|'PUT'|'PATCH'|'DELETE'|'HEAD'|'OPTIONS'|'TRACE'|'CONNECT'>}
|
|
121
|
+
*/
|
|
122
|
+
static Method = Object.freeze(HttpRequestMethod);
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @static
|
|
126
|
+
* @constant {Object<string, string>}
|
|
127
|
+
*/
|
|
128
|
+
static MediaType = HttpMediaType;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @static
|
|
132
|
+
* @constant {Object<string, string>}
|
|
133
|
+
*/
|
|
134
|
+
static RequestHeader = HttpRequestHeader;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @static
|
|
138
|
+
* @constant {Object<string, string>}
|
|
139
|
+
*/
|
|
140
|
+
static ResponseHeader = Object.freeze(HttpResponseHeader);
|
|
141
|
+
|
|
142
|
+
static CachingPolicy = {
|
|
143
|
+
DEFAULT: 'default',
|
|
144
|
+
FORCE_CACHE: 'force-cache',
|
|
145
|
+
NO_CACHE: 'no-cache',
|
|
146
|
+
NO_STORE: 'no-store',
|
|
147
|
+
ONLY_IF_CACHED: 'only-if-cached',
|
|
148
|
+
RELOAD: 'reload'
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @static
|
|
153
|
+
* @type {Object<string, string>}
|
|
154
|
+
*/
|
|
155
|
+
static CredentialsPolicy = {
|
|
156
|
+
INCLUDE: 'include',
|
|
157
|
+
OMIT: 'omit',
|
|
158
|
+
SAME_ORIGIN: 'same-origin'
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/** @type {RequestOptions} */
|
|
162
|
+
#defaultRequestOptions = {
|
|
163
|
+
body: null,
|
|
164
|
+
cache: Transportr.CachingPolicy.NO_STORE,
|
|
165
|
+
credentials: 'same-origin',
|
|
166
|
+
headers: {},
|
|
167
|
+
integrity: undefined,
|
|
168
|
+
keepalive: undefined,
|
|
169
|
+
method: undefined,
|
|
170
|
+
mode: 'cors',
|
|
171
|
+
redirect: 'follow',
|
|
172
|
+
referrer: 'about:client',
|
|
173
|
+
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
174
|
+
signal: null,
|
|
175
|
+
window: null
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
*
|
|
180
|
+
* @returns {URL} The base URL used for requests
|
|
181
|
+
*/
|
|
182
|
+
get baseUrl() {
|
|
183
|
+
return this.#baseUrl;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
*
|
|
188
|
+
* @async
|
|
189
|
+
* @param {string} path
|
|
190
|
+
* @param {RequestOptions} [options = {}]
|
|
191
|
+
* @returns {Promise<*>}
|
|
192
|
+
*/
|
|
193
|
+
async get(path, options = {}) {
|
|
194
|
+
return this.#request(path, _objectMerge(options, { method: HttpRequestMethod.GET }));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
*
|
|
199
|
+
* @async
|
|
200
|
+
* @param {string} path
|
|
201
|
+
* @param {Object} body
|
|
202
|
+
* @param {RequestOptions} [options = {}]
|
|
203
|
+
* @returns {Promise<*>}
|
|
204
|
+
*/
|
|
205
|
+
async post(path, body, options = {}) {
|
|
206
|
+
return this.#request(path, _objectMerge(options, { body, method: HttpRequestMethod.POST }));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
*
|
|
211
|
+
* @async
|
|
212
|
+
* @param {string} path
|
|
213
|
+
* @param {RequestOptions} [options = {}]
|
|
214
|
+
* @returns {Promise<*>}
|
|
215
|
+
*/
|
|
216
|
+
async put(path, options = {}) {
|
|
217
|
+
return this.#request(path, _objectMerge(options, { method: HttpRequestMethod.PUT }));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
*
|
|
222
|
+
* @async
|
|
223
|
+
* @param {string} path
|
|
224
|
+
* @param {RequestOptions} [options = {}]
|
|
225
|
+
* @returns {Promise<*>}
|
|
226
|
+
*/
|
|
227
|
+
async patch(path, options = {}) {
|
|
228
|
+
return this.#request(path, _objectMerge(options, { method: HttpRequestMethod.PATCH }));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
*
|
|
233
|
+
* @async
|
|
234
|
+
* @param {string} path
|
|
235
|
+
* @param {RequestOptions} [options = {}]
|
|
236
|
+
* @returns {Promise<*>}
|
|
237
|
+
*/
|
|
238
|
+
async delete(path, options = {}) {
|
|
239
|
+
return this.#request(path, _objectMerge(options, { method: HttpRequestMethod.DELETE }));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
*
|
|
244
|
+
* @async
|
|
245
|
+
* @param {string} path
|
|
246
|
+
* @param {RequestOptions} [options = {}]
|
|
247
|
+
* @returns {Promise<*>}
|
|
248
|
+
*/
|
|
249
|
+
async head(path, options = {}) {
|
|
250
|
+
return this.#request(path, _objectMerge(options, { method: HttpRequestMethod.HEAD }));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
*
|
|
255
|
+
* @async
|
|
256
|
+
* @param {string} path
|
|
257
|
+
* @param {RequestOptions} [options = {}]
|
|
258
|
+
* @returns {Promise<*>}
|
|
259
|
+
*/
|
|
260
|
+
async options(path, options = {}) {
|
|
261
|
+
return this.#request(path, _objectMerge(options, { method: HttpRequestMethod.OPTIONS }));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
*
|
|
266
|
+
* @async
|
|
267
|
+
* @param {string} path
|
|
268
|
+
* @param {RequestOptions} [options = {}]
|
|
269
|
+
* @returns {Promise<*>}
|
|
270
|
+
*/
|
|
271
|
+
async request(path, options = {}) {
|
|
272
|
+
return this.#request(path, options);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
*
|
|
277
|
+
* @async
|
|
278
|
+
* @param {string} path
|
|
279
|
+
* @param {RequestOptions} [options = {}]
|
|
280
|
+
* @returns {Promise<JsonObject>}
|
|
281
|
+
*/
|
|
282
|
+
async getJson(path, options = {}) {
|
|
283
|
+
return this.#get(path, _objectMerge(options, { headers: { [HttpRequestHeader.ACCEPT]: Transportr.MediaType.JSON } }), _handleJson);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
*
|
|
288
|
+
* @async
|
|
289
|
+
* @param {string} path
|
|
290
|
+
* @param {RequestOptions} [options = {}]
|
|
291
|
+
* @returns {Promise<Document>}
|
|
292
|
+
*/
|
|
293
|
+
async getXml(path, options = {}) {
|
|
294
|
+
return new DOMParser().parseFromString(await this.#get(path, _objectMerge(options, { headers: { [HttpRequestHeader.ACCEPT]: Transportr.MediaType.XML } }), _handleBlob), HttpMediaType.XML);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* TODO - Add way to return portion of the retrieved HTML using a selector. Like jQuery.
|
|
299
|
+
*
|
|
300
|
+
* @async
|
|
301
|
+
* @param {string} path
|
|
302
|
+
* @param {RequestOptions} [options = {}]
|
|
303
|
+
* @returns {Promise<string>}
|
|
304
|
+
*/
|
|
305
|
+
async getHtml(path, options = {}) {
|
|
306
|
+
return this.#get(path, _objectMerge(options, { headers: { [HttpRequestHeader.ACCEPT]: HttpMediaType.HTML } }), _handleText);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* TODO - Do I need this? What special handling might this need??
|
|
311
|
+
*
|
|
312
|
+
* @async
|
|
313
|
+
* @param {string} path
|
|
314
|
+
* @param {RequestOptions} [options = {}]
|
|
315
|
+
* @returns {Promise<string>}
|
|
316
|
+
*/
|
|
317
|
+
async getScript(path, options = {}) {
|
|
318
|
+
return this.#get(path, _objectMerge(options, { headers: { [HttpRequestHeader.ACCEPT]: HttpMediaType.JAVA_SCRIPT } }), _handleText);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
*
|
|
323
|
+
* @async
|
|
324
|
+
* @param {string} path
|
|
325
|
+
* @param {RequestOptions} [options = {}]
|
|
326
|
+
* @returns {Promise<Blob>}
|
|
327
|
+
*/
|
|
328
|
+
async getBlob(path, options = {}) {
|
|
329
|
+
return await this.#get(path, _objectMerge(options, { headers: { [HttpRequestHeader.ACCEPT]: HttpMediaType.BIN } }), _handleBlob);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
*
|
|
334
|
+
* @async
|
|
335
|
+
* @param {string} path
|
|
336
|
+
* @param {RequestOptions} [options = {}]
|
|
337
|
+
* @returns {Promise<string>}
|
|
338
|
+
*/
|
|
339
|
+
async getImage(path, options = {}) {
|
|
340
|
+
return URL.createObjectURL(await this.#get(path, _objectMerge(options, { headers: { [HttpRequestHeader.ACCEPT]: 'image/*' } }), _handleBlob));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
*
|
|
345
|
+
* @async
|
|
346
|
+
* @param {string} path
|
|
347
|
+
* @param {RequestOptions} [options = {}]
|
|
348
|
+
* @returns {Promise<ArrayBuffer>}
|
|
349
|
+
*/
|
|
350
|
+
async getBuffer(path, options = {}) {
|
|
351
|
+
return await this.#get(path, _objectMerge(options, { headers: { [HttpRequestHeader.ACCEPT]: HttpMediaType.BIN } }), _handleBuffer);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
*
|
|
356
|
+
* @async
|
|
357
|
+
* @param {string} path
|
|
358
|
+
* @param {RequestOptions} [options = {}]
|
|
359
|
+
* @returns {Promise<ReadableStream<Uint8Array>}
|
|
360
|
+
*/
|
|
361
|
+
async getStream(path, options = {}) {
|
|
362
|
+
return await this.#get(path, _objectMerge(options, { headers: { [HttpRequestHeader.ACCEPT]: HttpMediaType.BIN } }), _handleReadableStream);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
*
|
|
367
|
+
* @param {string} path
|
|
368
|
+
* @param {RequestOptions} options
|
|
369
|
+
* @param {ResponseHandler} responseHandler
|
|
370
|
+
* @returns
|
|
371
|
+
*/
|
|
372
|
+
async #get(path, options, responseHandler) {
|
|
373
|
+
return this.#request(path, _objectMerge(options, { method: Transportr.Method.GET }), responseHandler);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
*
|
|
378
|
+
* @private
|
|
379
|
+
* @async
|
|
380
|
+
* @param {string} path
|
|
381
|
+
* @param {RequestInit} options
|
|
382
|
+
* @param {ResponseHandler<ResponseBody>} [responseHandler]
|
|
383
|
+
* @returns {Promise<ResponseBody|Response>}
|
|
384
|
+
*/
|
|
385
|
+
async #request(path, options, responseHandler) {
|
|
386
|
+
console.debug(`Calling '${path}'`);
|
|
387
|
+
|
|
388
|
+
/** @type {RequestOptions} */
|
|
389
|
+
const requestOptions = _objectMerge(this.#defaultRequestOptions, options);
|
|
390
|
+
const headers = new Headers(requestOptions.headers);
|
|
391
|
+
|
|
392
|
+
if (headers.get(Transportr.RequestHeader.CONTENT_TYPE) == Transportr.MediaType.JSON) {
|
|
393
|
+
requestOptions.body = JSON.stringify(requestOptions.body);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
let response;
|
|
397
|
+
try {
|
|
398
|
+
response = await fetch(Transportr.#createUrl(this.#baseUrl, path, requestOptions.searchParams), requestOptions);
|
|
399
|
+
} catch (error) {
|
|
400
|
+
console.error(error);
|
|
401
|
+
// Need to ensure that the process terminates since an error occurred.
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (!response.ok) {
|
|
406
|
+
throw new HttpError(`An error has occurred with your request: ${response.status} - ${await response.text()}`);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
try {
|
|
410
|
+
return await (responseHandler ? responseHandler(response) : Transportr.#processResponse(response));
|
|
411
|
+
} catch (error) {
|
|
412
|
+
console.error(error);
|
|
413
|
+
// Need to ensure that the process terminates since an error occurred.
|
|
414
|
+
process.exit(1);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
*
|
|
420
|
+
* @private
|
|
421
|
+
* @static
|
|
422
|
+
* @param {URL} url
|
|
423
|
+
* @param {string} path
|
|
424
|
+
* @param {Object} [searchParams = {}]
|
|
425
|
+
* @returns {URL}
|
|
426
|
+
*/
|
|
427
|
+
static #createUrl(url, path, searchParams = {}) {
|
|
428
|
+
url = new URL(`${url.pathname.replace(endsWithSlashRegEx, '')}${path}`, url.origin);
|
|
429
|
+
|
|
430
|
+
for (const [ name, value ] of Object.entries(searchParams)) {
|
|
431
|
+
if (url.searchParams.has(name)) {
|
|
432
|
+
url.searchParams.set(name, value);
|
|
433
|
+
} else {
|
|
434
|
+
url.searchParams.append(name, value);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
return url;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
*
|
|
443
|
+
* @private
|
|
444
|
+
* @static
|
|
445
|
+
* @async
|
|
446
|
+
* @param {Response} response
|
|
447
|
+
* @returns {Promise<ResponseBody|Response>}
|
|
448
|
+
*/
|
|
449
|
+
static async #processResponse(response) {
|
|
450
|
+
const mediaType = new MediaType(response.headers.get(HttpResponseHeader.CONTENT_TYPE));
|
|
451
|
+
|
|
452
|
+
for (const [responseHandler, contentTypes] of Transportr.#contentTypeHandlers.entries()) {
|
|
453
|
+
if (contentTypes.has(mediaType.subtype)) {
|
|
454
|
+
return await responseHandler(response);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
console.warn('Unable to process response. Unknown content-type or no response handler defined.');
|
|
459
|
+
|
|
460
|
+
return response;
|
|
461
|
+
}
|
|
462
|
+
}
|