@twin.org/web 0.0.2-next.8 → 0.0.3-next.1

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.
Files changed (66) hide show
  1. package/dist/es/errors/fetchError.js +27 -0
  2. package/dist/es/errors/fetchError.js.map +1 -0
  3. package/dist/es/index.js +20 -0
  4. package/dist/es/index.js.map +1 -0
  5. package/dist/es/models/IFetchOptions.js +2 -0
  6. package/dist/es/models/IFetchOptions.js.map +1 -0
  7. package/dist/es/models/IHttpHeaders.js +4 -0
  8. package/dist/es/models/IHttpHeaders.js.map +1 -0
  9. package/dist/es/models/IJwk.js +2 -0
  10. package/dist/es/models/IJwk.js.map +1 -0
  11. package/dist/es/models/IJwtHeader.js +2 -0
  12. package/dist/es/models/IJwtHeader.js.map +1 -0
  13. package/dist/es/models/IJwtPayload.js +2 -0
  14. package/dist/es/models/IJwtPayload.js.map +1 -0
  15. package/dist/es/models/headerTypes.js +41 -0
  16. package/dist/es/models/headerTypes.js.map +1 -0
  17. package/dist/es/models/httpMethod.js +18 -0
  18. package/dist/es/models/httpMethod.js.map +1 -0
  19. package/dist/es/models/httpStatusCode.js +257 -0
  20. package/dist/es/models/httpStatusCode.js.map +1 -0
  21. package/dist/es/models/jwkCryptoKey.js +4 -0
  22. package/dist/es/models/jwkCryptoKey.js.map +1 -0
  23. package/dist/es/models/mimeTypes.js +101 -0
  24. package/dist/es/models/mimeTypes.js.map +1 -0
  25. package/dist/es/utils/fetchHelper.js +271 -0
  26. package/dist/es/utils/fetchHelper.js.map +1 -0
  27. package/dist/es/utils/headerHelper.js +34 -0
  28. package/dist/es/utils/headerHelper.js.map +1 -0
  29. package/dist/es/utils/jwk.js +99 -0
  30. package/dist/es/utils/jwk.js.map +1 -0
  31. package/dist/es/utils/jws.js +58 -0
  32. package/dist/es/utils/jws.js.map +1 -0
  33. package/dist/es/utils/jwt.js +243 -0
  34. package/dist/es/utils/jwt.js.map +1 -0
  35. package/dist/es/utils/mimeTypeHelper.js +144 -0
  36. package/dist/es/utils/mimeTypeHelper.js.map +1 -0
  37. package/dist/types/errors/fetchError.d.ts +1 -1
  38. package/dist/types/index.d.ts +17 -16
  39. package/dist/types/models/IFetchOptions.d.ts +1 -1
  40. package/dist/types/models/IJwk.d.ts +1 -2
  41. package/dist/types/models/IJwtHeader.d.ts +1 -2
  42. package/dist/types/models/IJwtPayload.d.ts +1 -2
  43. package/dist/types/utils/fetchHelper.d.ts +6 -2
  44. package/dist/types/utils/headerHelper.d.ts +17 -0
  45. package/dist/types/utils/jwk.d.ts +10 -4
  46. package/dist/types/utils/jws.d.ts +5 -1
  47. package/dist/types/utils/jwt.d.ts +7 -3
  48. package/docs/changelog.md +311 -0
  49. package/docs/reference/classes/FetchHelper.md +10 -2
  50. package/docs/reference/classes/HeaderHelper.md +57 -0
  51. package/docs/reference/classes/Jwk.md +27 -7
  52. package/docs/reference/classes/Jws.md +8 -0
  53. package/docs/reference/classes/Jwt.md +30 -22
  54. package/docs/reference/classes/MimeTypeHelper.md +5 -5
  55. package/docs/reference/index.md +4 -3
  56. package/docs/reference/type-aliases/IJwk.md +5 -0
  57. package/docs/reference/type-aliases/IJwtHeader.md +5 -0
  58. package/docs/reference/type-aliases/IJwtPayload.md +5 -0
  59. package/locales/.validate-ignore +1 -0
  60. package/locales/en.json +3 -2
  61. package/package.json +25 -12
  62. package/dist/cjs/index.cjs +0 -1269
  63. package/dist/esm/index.mjs +0 -1258
  64. package/docs/reference/interfaces/IJwk.md +0 -7
  65. package/docs/reference/interfaces/IJwtHeader.md +0 -13
  66. package/docs/reference/interfaces/IJwtPayload.md +0 -13
@@ -1,1258 +0,0 @@
1
- import { BaseError, StringHelper, Guards, Is, AsyncCache, ObjectHelper, GeneralError, Converter, JsonHelper } from '@twin.org/core';
2
- import { Ed25519, Sha256 } from '@twin.org/crypto';
3
- import { importJWK, CompactSign, flattenedVerify, SignJWT, jwtVerify } from 'jose';
4
-
5
- // Copyright 2024 IOTA Stiftung.
6
- // SPDX-License-Identifier: Apache-2.0.
7
- /**
8
- * Class to represent errors from fetch.
9
- */
10
- class FetchError extends BaseError {
11
- /**
12
- * Runtime name for the class.
13
- */
14
- static CLASS_NAME = "FetchError";
15
- /**
16
- * Create a new instance of FetchError.
17
- * @param source The source of the error.
18
- * @param message The message as a code.
19
- * @param httpStatus The http status code.
20
- * @param properties Any additional information for the error.
21
- * @param cause The cause of the error if we have wrapped another error.
22
- */
23
- constructor(source, message, httpStatus, properties, cause) {
24
- super(FetchError.CLASS_NAME, source, message, {
25
- httpStatus,
26
- ...properties
27
- }, cause);
28
- }
29
- }
30
-
31
- // Copyright 2024 IOTA Stiftung.
32
- // SPDX-License-Identifier: Apache-2.0.
33
- /**
34
- * Common http header types.
35
- */
36
- // eslint-disable-next-line @typescript-eslint/naming-convention
37
- const HeaderTypes = {
38
- /**
39
- * Content Type.
40
- */
41
- ContentType: "content-type",
42
- /**
43
- * Content Length.
44
- */
45
- ContentLength: "content-length",
46
- /**
47
- * Content Disposition.
48
- */
49
- ContentDisposition: "content-disposition",
50
- /**
51
- * Accept.
52
- */
53
- Accept: "accept",
54
- /**
55
- * Authorization.
56
- */
57
- Authorization: "authorization",
58
- /**
59
- * Cookie.
60
- */
61
- Cookie: "cookie",
62
- /**
63
- * Set Cookie.
64
- */
65
- SetCookie: "set-cookie",
66
- /**
67
- * Location
68
- */
69
- Location: "location"
70
- };
71
-
72
- // Copyright 2024 IOTA Stiftung.
73
- // SPDX-License-Identifier: Apache-2.0.
74
- /**
75
- * The names of the HTTP Methods.
76
- */
77
- // eslint-disable-next-line @typescript-eslint/naming-convention
78
- const HttpMethod = {
79
- GET: "GET",
80
- POST: "POST",
81
- PUT: "PUT",
82
- PATCH: "PATCH",
83
- DELETE: "DELETE",
84
- OPTIONS: "OPTIONS",
85
- HEAD: "HEAD",
86
- CONNECT: "CONNECT",
87
- TRACE: "TRACE"
88
- };
89
-
90
- // Copyright 2024 IOTA Stiftung.
91
- // SPDX-License-Identifier: Apache-2.0.
92
- /**
93
- * Standard HTTP status codes.
94
- */
95
- // eslint-disable-next-line @typescript-eslint/naming-convention
96
- const HttpStatusCode = {
97
- /**
98
- * Continue status code.
99
- */
100
- continue: 100,
101
- /**
102
- * Switching Protocols status code.
103
- */
104
- switchingProtocols: 101,
105
- /**
106
- * Processing status code.
107
- */
108
- processing: 102,
109
- /**
110
- * Early Hints status code.
111
- */
112
- earlyHints: 103,
113
- /**
114
- * OK status code.
115
- */
116
- ok: 200,
117
- /**
118
- * Created status code.
119
- */
120
- created: 201,
121
- /**
122
- * Accepted status code.
123
- */
124
- accepted: 202,
125
- /**
126
- * Non-Authoritative Information status code.
127
- */
128
- nonAuthoritativeInformation: 203,
129
- /**
130
- * No Content status code.
131
- */
132
- noContent: 204,
133
- /**
134
- * Reset Content status code.
135
- */
136
- resetContent: 205,
137
- /**
138
- * Partial Content status code.
139
- */
140
- partialContent: 206,
141
- /**
142
- * Multi-Status status code.
143
- */
144
- multiStatus: 207,
145
- /**
146
- * Already Reported status code.
147
- */
148
- alreadyReported: 208,
149
- /**
150
- * IM Used status code.
151
- */
152
- imUsed: 226,
153
- /**
154
- * Multiple Choices status code.
155
- */
156
- multipleChoices: 300,
157
- /**
158
- * Moved Permanently status code.
159
- */
160
- movedPermanently: 301,
161
- /**
162
- * Found status code.
163
- */
164
- found: 302,
165
- /**
166
- * See Other status code.
167
- */
168
- seeOther: 303,
169
- /**
170
- * Not Modified status code.
171
- */
172
- notModified: 304,
173
- /**
174
- * Use Proxy status code.
175
- */
176
- useProxy: 305,
177
- /**
178
- * Temporary Redirect status code.
179
- */
180
- temporaryRedirect: 307,
181
- /**
182
- * Permanent Redirect status code.
183
- */
184
- permanentRedirect: 308,
185
- /**
186
- * Bad Request status code.
187
- */
188
- badRequest: 400,
189
- /**
190
- * Unauthorized status code.
191
- */
192
- unauthorized: 401,
193
- /**
194
- * Payment Required status code.
195
- */
196
- paymentRequired: 402,
197
- /**
198
- * Forbidden status code.
199
- */
200
- forbidden: 403,
201
- /**
202
- * Not Found status code.
203
- */
204
- notFound: 404,
205
- /**
206
- * Method Not Allowed status code.
207
- */
208
- methodNotAllowed: 405,
209
- /**
210
- * Not Acceptable status code.
211
- */
212
- notAcceptable: 406,
213
- /**
214
- * Proxy Authentication Required status code.
215
- */
216
- proxyAuthenticationRequired: 407,
217
- /**
218
- * Request Timeout status code.
219
- */
220
- requestTimeout: 408,
221
- /**
222
- * Conflict status code.
223
- */
224
- conflict: 409,
225
- /**
226
- * Gone status code.
227
- */
228
- gone: 410,
229
- /**
230
- * Length Required status code.
231
- */
232
- lengthRequired: 411,
233
- /**
234
- * Precondition Failed status code.
235
- */
236
- preconditionFailed: 412,
237
- /**
238
- * Payload Too Large status code.
239
- */
240
- payloadTooLarge: 413,
241
- /**
242
- * URI Too Long status code.
243
- */
244
- uriTooLong: 414,
245
- /**
246
- * Unsupported Media Type status code.
247
- */
248
- unsupportedMediaType: 415,
249
- /**
250
- * Range Not Satisfiable status code.
251
- */
252
- rangeNotSatisfiable: 416,
253
- /**
254
- * Expectation Failed status code.
255
- */
256
- expectationFailed: 417,
257
- /**
258
- * I'm a Teapot status code.
259
- */
260
- imATeapot: 418,
261
- /**
262
- * Misdirected Request status code.
263
- */
264
- misdirectedRequest: 421,
265
- /**
266
- * Unprocessable Entity status code.
267
- */
268
- unprocessableEntity: 422,
269
- /**
270
- * Locked status code.
271
- */
272
- locked: 423,
273
- /**
274
- * Failed Dependency status code.
275
- */
276
- failedDependency: 424,
277
- /**
278
- * Too Early status code.
279
- */
280
- tooEarly: 425,
281
- /**
282
- * Upgrade Required status code.
283
- */
284
- upgradeRequired: 426,
285
- /**
286
- * Precondition Required status code.
287
- */
288
- preconditionRequired: 428,
289
- /**
290
- * Too Many Requests status code.
291
- */
292
- tooManyRequests: 429,
293
- /**
294
- * Request Header Fields Too Large status code.
295
- */
296
- requestHeaderFieldsTooLarge: 431,
297
- /**
298
- * Unavailable For Legal Reasons status code.
299
- */
300
- unavailableForLegalReasons: 451,
301
- /**
302
- * Internal Server Error status code.
303
- */
304
- internalServerError: 500,
305
- /**
306
- * Not Implemented status code.
307
- */
308
- notImplemented: 501,
309
- /**
310
- * Bad Gateway status code.
311
- */
312
- badGateway: 502,
313
- /**
314
- * Service Unavailable status code.
315
- */
316
- serviceUnavailable: 503,
317
- /**
318
- * Gateway Timeout status code.
319
- */
320
- gatewayTimeout: 504,
321
- /**
322
- * HTTP Version Not Supported status code.
323
- */
324
- httpVersionNotSupported: 505,
325
- /**
326
- * Variant Also Negotiates status code.
327
- */
328
- variantAlsoNegotiates: 506,
329
- /**
330
- * Insufficient Storage status code.
331
- */
332
- insufficientStorage: 507,
333
- /**
334
- * Loop Detected status code.
335
- */
336
- loopDetected: 508,
337
- /**
338
- * Not Extended status code.
339
- */
340
- notExtended: 510,
341
- /**
342
- * Network Authentication Required status code.
343
- */
344
- networkAuthenticationRequired: 511
345
- };
346
-
347
- // Copyright 2024 IOTA Stiftung.
348
- // SPDX-License-Identifier: Apache-2.0.
349
- /**
350
- * Common mime types.
351
- */
352
- // eslint-disable-next-line @typescript-eslint/naming-convention
353
- const MimeTypes = {
354
- /**
355
- * Plaint Text - text/plain
356
- */
357
- PlainText: "text/plain",
358
- /**
359
- * HTML - text/html
360
- */
361
- Html: "text/html",
362
- /**
363
- * Javascript - text/javascript
364
- */
365
- Javascript: "text/javascript",
366
- /**
367
- * JSON - application/json
368
- */
369
- Json: "application/json",
370
- /**
371
- * JSON-LD - application/ld+json
372
- */
373
- JsonLd: "application/ld+json",
374
- /**
375
- * JWT - application/jwt
376
- */
377
- Jwt: "application/jwt",
378
- /**
379
- * XML - application/xml
380
- */
381
- Xml: "application/xml",
382
- /**
383
- * Application Octet Stream, arbitrary binary - application/octet-stream
384
- */
385
- OctetStream: "application/octet-stream",
386
- /**
387
- * Application GZIP - application/gzip
388
- */
389
- Gzip: "application/gzip",
390
- /**
391
- * Application deflate - application/zlib
392
- */
393
- Zlib: "application/zlib",
394
- /**
395
- * Application BZIP2 - application/x-bzip2
396
- */
397
- Bzip2: "application/x-bzip2",
398
- /**
399
- * Application ZIP - application/zip
400
- */
401
- Zip: "application/zip",
402
- /**
403
- * Application PDF - application/pdf
404
- */
405
- Pdf: "application/pdf",
406
- /**
407
- * Image GIF - image/gif
408
- */
409
- Gif: "image/gif",
410
- /**
411
- * Image BMP - image/bmp
412
- */
413
- Bmp: "image/bmp",
414
- /**
415
- * Image JPEG - image/jpeg
416
- */
417
- Jpeg: "image/jpeg",
418
- /**
419
- * Image PNG - image/png
420
- */
421
- Png: "image/png",
422
- /**
423
- * Image Tiff - image/tiff
424
- */
425
- Tiff: "image/tiff",
426
- /**
427
- * Image SVG - image/svg+xml
428
- */
429
- Svg: "image/svg+xml",
430
- /**
431
- * Image WEBP - image/webp
432
- */
433
- WebP: "image/webp",
434
- /**
435
- * Video MP4 - video/mp4
436
- */
437
- Mp4: "video/mp4",
438
- /**
439
- * Audio/Video MPEG - video/mpeg
440
- */
441
- Mpeg: "video/mpeg",
442
- /**
443
- * Video WEBM - video/webm
444
- */
445
- Webm: "video/webm"
446
- };
447
-
448
- // Copyright 2024 IOTA Stiftung.
449
- // SPDX-License-Identifier: Apache-2.0.
450
- /**
451
- * Class to helper with fetch operations.
452
- */
453
- class FetchHelper {
454
- /**
455
- * Runtime name for the class.
456
- * @internal
457
- */
458
- static _CLASS_NAME = "FetchHelper";
459
- /**
460
- * Prefix to use for cache entries.
461
- * @internal
462
- */
463
- static _CACHE_PREFIX = "fetch_";
464
- /**
465
- * Runtime name for the class.
466
- * @internal
467
- */
468
- static _CLASS_NAME_CAMEL_CASE = StringHelper.camelCase("FetchHelper");
469
- /**
470
- * Perform a fetch request.
471
- * @param source The source for the request.
472
- * @param url The url for the request.
473
- * @param method The http method.
474
- * @param body Request to send to the endpoint.
475
- * @param options Options for sending the requests.
476
- * @returns The response.
477
- */
478
- static async fetch(source, url, method, body, options) {
479
- Guards.string(FetchHelper._CLASS_NAME, "source", source);
480
- Guards.string(FetchHelper._CLASS_NAME, "url", url);
481
- Guards.arrayOneOf(FetchHelper._CLASS_NAME, "method", method, Object.values(HttpMethod));
482
- if (!Is.undefined(body) && !Is.uint8Array(body)) {
483
- Guards.string(FetchHelper._CLASS_NAME, "body", body);
484
- }
485
- if (!Is.undefined(options)) {
486
- Guards.object(FetchHelper._CLASS_NAME, "options", options);
487
- if (!Is.undefined(options.headers)) {
488
- Guards.object(FetchHelper._CLASS_NAME, "options.headers", options.headers);
489
- }
490
- if (!Is.undefined(options.timeoutMs)) {
491
- Guards.integer(FetchHelper._CLASS_NAME, "options.timeoutMs", options.timeoutMs);
492
- }
493
- if (!Is.undefined(options.includeCredentials)) {
494
- Guards.boolean(FetchHelper._CLASS_NAME, "options.includeCredentials", options.includeCredentials);
495
- }
496
- if (!Is.undefined(options.retryCount)) {
497
- Guards.integer(FetchHelper._CLASS_NAME, "options.retryCount", options.retryCount);
498
- }
499
- if (!Is.undefined(options.retryDelayMs)) {
500
- Guards.integer(FetchHelper._CLASS_NAME, "options.retryDelayMs", options.retryDelayMs);
501
- }
502
- }
503
- let controller;
504
- let timerId;
505
- const retryCount = options?.retryCount ?? 1;
506
- const baseDelayMilliseconds = options?.retryDelayMs ?? 3000;
507
- let lastError;
508
- let attempt;
509
- for (attempt = 0; attempt < retryCount; attempt++) {
510
- if (attempt > 0) {
511
- const exponentialBackoffDelay = baseDelayMilliseconds * Math.pow(2, attempt - 1);
512
- await new Promise(resolve => globalThis.setTimeout(resolve, exponentialBackoffDelay));
513
- }
514
- if (options?.timeoutMs !== undefined) {
515
- controller = new AbortController();
516
- timerId = globalThis.setTimeout(() => {
517
- if (controller) {
518
- controller.abort();
519
- }
520
- }, options?.timeoutMs);
521
- }
522
- let finalBody;
523
- if (method === HttpMethod.POST || method === HttpMethod.PUT) {
524
- if (Is.string(body)) {
525
- finalBody = body;
526
- }
527
- else if (Is.uint8Array(body)) {
528
- finalBody = new Uint8Array(body);
529
- }
530
- }
531
- try {
532
- const requestOptions = {
533
- method,
534
- headers: options?.headers,
535
- body: finalBody,
536
- signal: controller ? controller.signal : undefined
537
- };
538
- if (Is.boolean(options?.includeCredentials)) {
539
- requestOptions.credentials = "include";
540
- }
541
- const response = await fetch(url, requestOptions);
542
- if (!response.ok && retryCount > 1) {
543
- lastError = new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.general`, response.status ?? HttpStatusCode.internalServerError, {
544
- url,
545
- statusText: response.statusText
546
- });
547
- }
548
- else {
549
- return response;
550
- }
551
- }
552
- catch (err) {
553
- const isErr = Is.object(err);
554
- if (isErr && Is.stringValue(err.message) && err.message.includes("Failed to fetch")) {
555
- lastError = new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.connectivity`, HttpStatusCode.serviceUnavailable, {
556
- url
557
- }, err);
558
- }
559
- else {
560
- const isAbort = isErr && err.name === "AbortError";
561
- const props = { url };
562
- let httpStatus = HttpStatusCode.internalServerError;
563
- if (isAbort) {
564
- httpStatus = HttpStatusCode.requestTimeout;
565
- }
566
- else if (isErr && "httpStatus" in err) {
567
- httpStatus = err.httpStatus;
568
- }
569
- if (isErr && "statusText" in err) {
570
- props.statusText = err.statusText;
571
- }
572
- lastError = new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.${isAbort ? "timeout" : "general"}`, httpStatus, props, err);
573
- }
574
- }
575
- finally {
576
- if (timerId) {
577
- globalThis.clearTimeout(timerId);
578
- }
579
- }
580
- }
581
- if (retryCount > 1 && attempt === retryCount) {
582
- // False positive as FetchError is derived from Error
583
- // eslint-disable-next-line @typescript-eslint/only-throw-error
584
- throw new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.retryLimitExceeded`, HttpStatusCode.internalServerError, { url }, lastError);
585
- }
586
- throw lastError;
587
- }
588
- /**
589
- * Perform a request in json format.
590
- * @param source The source for the request.
591
- * @param url The url for the request.
592
- * @param method The http method.
593
- * @param requestData Request to send to the endpoint.
594
- * @param options Options for sending the requests.
595
- * @returns The response.
596
- */
597
- static async fetchJson(source, url, method, requestData, options) {
598
- if (Is.integer(options?.cacheTtlMs) && options.cacheTtlMs >= 0) {
599
- // The cache option is set, so call the same method again but without
600
- // the cache option to get the result and cache it.
601
- const cacheResponse = AsyncCache.exec(`${FetchHelper._CACHE_PREFIX}${url}`, options.cacheTtlMs, async () => FetchHelper.fetchJson(source, url, method, requestData, ObjectHelper.omit(options, ["cacheTtlMs"])));
602
- // If the return value is a promise return it, otherwise continue
603
- // with the regular processing.
604
- if (Is.promise(cacheResponse)) {
605
- return cacheResponse;
606
- }
607
- }
608
- options ??= {};
609
- options.headers ??= {};
610
- if (Is.undefined(options.headers[HeaderTypes.ContentType]) &&
611
- (method === HttpMethod.POST || method === HttpMethod.PUT || method === HttpMethod.PATCH)) {
612
- options.headers[HeaderTypes.ContentType] = MimeTypes.Json;
613
- }
614
- const response = await FetchHelper.fetch(source, url, method, requestData ? JSON.stringify(requestData) : undefined, options);
615
- if (response.ok) {
616
- if (response.status === HttpStatusCode.noContent) {
617
- return {};
618
- }
619
- try {
620
- return (await response.json());
621
- }
622
- catch (err) {
623
- // False positive as FetchError is derived from Error
624
- // eslint-disable-next-line @typescript-eslint/only-throw-error
625
- throw new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.decodingJSON`, HttpStatusCode.badRequest, { url }, err);
626
- }
627
- }
628
- const errorResponseData = await response.json();
629
- const errorResponse = BaseError.fromError(errorResponseData);
630
- const isErrorEmpty = BaseError.isEmpty(errorResponse);
631
- // False positive as FetchError is derived from Error
632
- // eslint-disable-next-line @typescript-eslint/only-throw-error
633
- throw new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.failureStatusText`, response.status, {
634
- statusText: response.statusText,
635
- url,
636
- data: isErrorEmpty ? errorResponseData : undefined
637
- }, isErrorEmpty ? undefined : errorResponse);
638
- }
639
- /**
640
- * Perform a request for binary data.
641
- * @param source The source for the request.
642
- * @param url The url for the request.
643
- * @param method The http method.
644
- * @param requestData Request to send to the endpoint.
645
- * @param options Options for sending the requests.
646
- * @returns The response.
647
- */
648
- static async fetchBinary(source, url, method, requestData, options) {
649
- if (Is.integer(options?.cacheTtlMs) && options.cacheTtlMs >= 0) {
650
- // The cache option is set, so call the same method again but without
651
- // the cache option to get the result and cache it.
652
- const cacheResponse = AsyncCache.exec(`${FetchHelper._CACHE_PREFIX}${url}`, options.cacheTtlMs * 1000, async () => FetchHelper.fetchBinary(source, url, method, requestData, ObjectHelper.omit(options, ["cacheTtlMs"])));
653
- // If the return value is a promise return it, otherwise continue
654
- // with the regular processing.
655
- if (Is.promise(cacheResponse)) {
656
- return cacheResponse;
657
- }
658
- }
659
- options ??= {};
660
- options.headers ??= {};
661
- if (Is.undefined(options.headers[HeaderTypes.ContentType])) {
662
- options.headers[HeaderTypes.ContentType] = MimeTypes.OctetStream;
663
- }
664
- const response = await this.fetch(source, url, method, requestData, options);
665
- if (response.ok) {
666
- if (method === HttpMethod.GET) {
667
- if (response.status === HttpStatusCode.noContent) {
668
- return new Uint8Array();
669
- }
670
- return new Uint8Array(await response.arrayBuffer());
671
- }
672
- try {
673
- return (await response.json());
674
- }
675
- catch (err) {
676
- // False positive as FetchError is derived from Error
677
- // eslint-disable-next-line @typescript-eslint/only-throw-error
678
- throw new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.decodingJSON`, HttpStatusCode.badRequest, { url }, err);
679
- }
680
- }
681
- const errorResponseData = await response.json();
682
- const errorResponse = BaseError.fromError(errorResponseData);
683
- const isErrorEmpty = BaseError.isEmpty(errorResponse);
684
- // False positive as FetchError is derived from Error
685
- // eslint-disable-next-line @typescript-eslint/only-throw-error
686
- throw new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.failureStatusText`, response.status, {
687
- statusText: response.statusText,
688
- url,
689
- data: isErrorEmpty ? errorResponseData : undefined
690
- }, isErrorEmpty ? undefined : errorResponse);
691
- }
692
- /**
693
- * Clears the cache.
694
- */
695
- static clearCache() {
696
- AsyncCache.clearCache(FetchHelper._CACHE_PREFIX);
697
- }
698
- /**
699
- * Get a cache entry.
700
- * @param url The url for the request.
701
- * @returns The cache entry if it exists.
702
- */
703
- static async getCacheEntry(url) {
704
- return AsyncCache.get(`${FetchHelper._CACHE_PREFIX}${url}`);
705
- }
706
- /**
707
- * Set a cache entry.
708
- * @param url The url for the request.
709
- * @param value The value to cache.
710
- * @returns The cache entry if it exists.
711
- */
712
- static async setCacheEntry(url, value) {
713
- AsyncCache.set(`${FetchHelper._CACHE_PREFIX}${url}`, value);
714
- }
715
- /**
716
- * Remove a cache entry.
717
- * @param url The url for the request.
718
- */
719
- static removeCacheEntry(url) {
720
- AsyncCache.remove(`${FetchHelper._CACHE_PREFIX}${url}`);
721
- }
722
- }
723
-
724
- // Copyright 2024 IOTA Stiftung.
725
- // SPDX-License-Identifier: Apache-2.0.
726
- /**
727
- * Class to handle JSON Web Keys.
728
- */
729
- class Jwk {
730
- /**
731
- * Runtime name for the class.
732
- * @internal
733
- */
734
- static _CLASS_NAME = "Jwk";
735
- /**
736
- * Convert the JWK to a crypto key.
737
- * @param jwk The JWK to convert.
738
- * @param alg The alg to be used, defaults to jwk.alg.
739
- * @returns The crypto key.
740
- */
741
- static async toCryptoKey(jwk, alg) {
742
- Guards.object(Jwk._CLASS_NAME, "jwk", jwk);
743
- try {
744
- return importJWK(jwk, alg);
745
- }
746
- catch (err) {
747
- throw new GeneralError(Jwk._CLASS_NAME, "jwkImportFailed", undefined, err);
748
- }
749
- }
750
- /**
751
- * Convert the Ed25519 private key to a crypto key.
752
- * @param privateKey The private key to use.
753
- * @returns The crypto key.
754
- */
755
- static async fromEd25519Private(privateKey) {
756
- Guards.uint8Array(Jwk._CLASS_NAME, "privateKey", privateKey);
757
- const publicKey = Ed25519.publicKeyFromPrivateKey(privateKey);
758
- const jwk = {
759
- kty: "OKP",
760
- use: "enc",
761
- alg: "EdDSA",
762
- crv: "Ed25519",
763
- x: Converter.bytesToBase64Url(publicKey),
764
- d: Converter.bytesToBase64Url(privateKey)
765
- };
766
- return jwk;
767
- }
768
- /**
769
- * Convert the Ed25519 public key to a crypto key.
770
- * @param publicKey The private key to use.
771
- * @returns The crypto key.
772
- */
773
- static async fromEd25519Public(publicKey) {
774
- Guards.uint8Array(Jwk._CLASS_NAME, "publicKey", publicKey);
775
- const jwk = {
776
- kty: "OKP",
777
- use: "sig",
778
- alg: "EdDSA",
779
- crv: "Ed25519",
780
- x: Converter.bytesToBase64Url(publicKey)
781
- };
782
- return jwk;
783
- }
784
- /**
785
- * Convert the JWK to raw keys.
786
- * @param jwk The JWK to convert to raw.
787
- * @returns The crypto key.
788
- */
789
- static async toRaw(jwk) {
790
- Guards.object(Jwk._CLASS_NAME, "jwk", jwk);
791
- let publicKey;
792
- let privateKey;
793
- if (Is.stringBase64Url(jwk.x)) {
794
- publicKey = Converter.base64UrlToBytes(jwk.x);
795
- }
796
- if (Is.stringBase64Url(jwk.d)) {
797
- privateKey = Converter.base64UrlToBytes(jwk.d);
798
- }
799
- return {
800
- publicKey,
801
- privateKey
802
- };
803
- }
804
- /**
805
- * Generate a KID for the JWK.
806
- * @param jwk The JWK to generate a KID for.
807
- * @returns The KID.
808
- */
809
- static async generateKid(jwk) {
810
- Guards.object(Jwk._CLASS_NAME, "jwk", jwk);
811
- const kidProps = ObjectHelper.pick(jwk, ["crv", "kty", "x"]);
812
- const canonicalJson = JsonHelper.canonicalize(kidProps);
813
- const hash = Sha256.sum256(Converter.utf8ToBytes(canonicalJson));
814
- return Converter.bytesToBase64Url(hash);
815
- }
816
- }
817
-
818
- // Copyright 2024 IOTA Stiftung.
819
- // SPDX-License-Identifier: Apache-2.0.
820
- /**
821
- * Class to handle JSON Web Signatures.
822
- */
823
- class Jws {
824
- /**
825
- * Runtime name for the class.
826
- * @internal
827
- */
828
- static _CLASS_NAME = "Jws";
829
- /**
830
- * Create a signature.
831
- * @param privateKey The private key to use.
832
- * @param hash The hash to sign.
833
- * @param algOverride An optional algorithm override.
834
- * @returns The signature.
835
- */
836
- static async create(privateKey, hash, algOverride) {
837
- Guards.defined(Jws._CLASS_NAME, "privateKey", privateKey);
838
- Guards.uint8Array(Jws._CLASS_NAME, "hash", hash);
839
- try {
840
- const jws = await new CompactSign(hash)
841
- .setProtectedHeader({
842
- alg: algOverride ?? (Is.uint8Array(privateKey) ? "EdDSA" : privateKey.algorithm.name),
843
- b64: false,
844
- crit: ["b64"]
845
- })
846
- .sign(privateKey);
847
- return jws;
848
- }
849
- catch (err) {
850
- throw new GeneralError(Jws._CLASS_NAME, "createFailed", undefined, err);
851
- }
852
- }
853
- /**
854
- * Verify a signature.
855
- * @param jws The signature to verify.
856
- * @param publicKey The public key to verify the signature with.
857
- * @param hash The hash to verify.
858
- * @returns True if the signature was verified.
859
- */
860
- static async verify(jws, publicKey, hash) {
861
- Guards.stringValue(Jws._CLASS_NAME, "jws", jws);
862
- Guards.defined(Jws._CLASS_NAME, "publicKey", publicKey);
863
- Guards.uint8Array(Jws._CLASS_NAME, "hash", hash);
864
- try {
865
- const jwsParts = jws.split(".");
866
- await flattenedVerify({ protected: jwsParts[0], payload: hash, signature: jwsParts[2] }, publicKey);
867
- return true;
868
- }
869
- catch (err) {
870
- throw new GeneralError(Jws._CLASS_NAME, "verifyFailed", undefined, err);
871
- }
872
- }
873
- }
874
-
875
- // Copyright 2024 IOTA Stiftung.
876
- // SPDX-License-Identifier: Apache-2.0.
877
- /**
878
- * Class to handle JSON Web Tokens.
879
- */
880
- class Jwt {
881
- /**
882
- * Runtime name for the class.
883
- * @internal
884
- */
885
- static _CLASS_NAME = "Jwt";
886
- /**
887
- * Encode a token.
888
- * @param header The header to encode.
889
- * @param payload The payload to encode.
890
- * @param key The key for signing the token, can be omitted if a signer is provided.
891
- * @returns The encoded token.
892
- */
893
- static async encode(header, payload, key) {
894
- Guards.object(Jwt._CLASS_NAME, "header", header);
895
- Guards.object(Jwt._CLASS_NAME, "payload", payload);
896
- Guards.defined(Jwt._CLASS_NAME, "key", key);
897
- return Jwt.internalEncode(header, payload, key);
898
- }
899
- /**
900
- * Encode a token.
901
- * @param header The header to encode.
902
- * @param payload The payload to encode.
903
- * @param signer Custom signer method.
904
- * @returns The encoded token.
905
- */
906
- static async encodeWithSigner(header, payload, signer) {
907
- Guards.object(Jwt._CLASS_NAME, "header", header);
908
- Guards.stringValue(Jwt._CLASS_NAME, "header.alg", header.alg);
909
- Guards.object(Jwt._CLASS_NAME, "payload", payload);
910
- Guards.function(Jwt._CLASS_NAME, "signer", signer);
911
- return Jwt.internalEncode(header, payload, undefined, signer);
912
- }
913
- /**
914
- * Decode a token.
915
- * @param token The token to decode.
916
- * @returns The decoded payload.
917
- */
918
- static async decode(token) {
919
- Guards.stringValue(Jwt._CLASS_NAME, "token", token);
920
- let header;
921
- let payload;
922
- let signature;
923
- const segments = token.split(".");
924
- if (segments.length > 0) {
925
- try {
926
- const bytesHeader = Converter.base64UrlToBytes(segments[0]);
927
- header = JSON.parse(Converter.bytesToUtf8(bytesHeader));
928
- }
929
- catch { }
930
- }
931
- if (segments.length > 1) {
932
- try {
933
- const bytesPayload = Converter.base64UrlToBytes(segments[1]);
934
- payload = JSON.parse(Converter.bytesToUtf8(bytesPayload));
935
- }
936
- catch { }
937
- }
938
- if (segments.length > 2) {
939
- signature = Converter.base64UrlToBytes(segments[2]);
940
- }
941
- return {
942
- header,
943
- payload,
944
- signature
945
- };
946
- }
947
- /**
948
- * Verify a token.
949
- * @param token The token to verify.
950
- * @param key The key for verifying the token
951
- * @returns The decoded payload.
952
- */
953
- static async verify(token, key) {
954
- Guards.stringValue(Jwt._CLASS_NAME, "token", token);
955
- Guards.defined(Jwt._CLASS_NAME, "key", key);
956
- return Jwt.verifySignature(token, key);
957
- }
958
- /**
959
- * Verify a token.
960
- * @param token The token to verify.
961
- * @param verifier Custom verification method.
962
- * @returns The decoded payload.
963
- */
964
- static async verifyWithVerifier(token, verifier) {
965
- Guards.stringValue(Jwt._CLASS_NAME, "token", token);
966
- Guards.function(Jwt._CLASS_NAME, "verifier", verifier);
967
- return Jwt.verifySignature(token, undefined, verifier);
968
- }
969
- /**
970
- * Verify a token by parts.
971
- * @param token The token to verify.
972
- * @param key The key for verifying the token, if not provided no verification occurs.
973
- * @param verifier Custom verification method.
974
- * @returns True if the parts are verified.
975
- */
976
- static async verifySignature(token, key, verifier) {
977
- Guards.stringValue(Jwt._CLASS_NAME, "token", token);
978
- const hasKey = Is.notEmpty(key);
979
- const hasVerifier = Is.notEmpty(verifier);
980
- if (!hasKey && !hasVerifier) {
981
- throw new GeneralError(Jwt._CLASS_NAME, "noKeyOrVerifier");
982
- }
983
- verifier ??= async (t, k) => Jwt.defaultVerifier(t, k);
984
- return verifier(token, key);
985
- }
986
- /**
987
- * The default signer for the JWT.
988
- * @param header The header to sign.
989
- * @param payload The payload to sign.
990
- * @param key The optional key to sign with.
991
- * @returns The signature.
992
- */
993
- static async defaultSigner(header, payload, key) {
994
- Guards.object(Jwt._CLASS_NAME, "header", header);
995
- Guards.object(Jwt._CLASS_NAME, "payload", payload);
996
- Guards.defined(Jwt._CLASS_NAME, "key", key);
997
- const signer = new SignJWT(payload);
998
- signer.setProtectedHeader(header);
999
- let finalKey = key;
1000
- if (header.alg === "EdDSA" && Is.uint8Array(key)) {
1001
- // Jose does not support Ed25519 keys in raw format, so we need to convert it to PKCS8.
1002
- finalKey = await Ed25519.privateKeyToPkcs8(key);
1003
- }
1004
- return signer.sign(finalKey);
1005
- }
1006
- /**
1007
- * The default verifier for the JWT.
1008
- * @param token The token to verify.
1009
- * @param key The key to verify with.
1010
- * @returns The header and payload if verification successful.
1011
- */
1012
- static async defaultVerifier(token, key) {
1013
- Guards.stringValue(Jwt._CLASS_NAME, "token", token);
1014
- Guards.defined(Jwt._CLASS_NAME, "key", key);
1015
- try {
1016
- const result = await jwtVerify(token, key);
1017
- return {
1018
- header: result.protectedHeader,
1019
- payload: result.payload
1020
- };
1021
- }
1022
- catch (err) {
1023
- throw new GeneralError(Jwt._CLASS_NAME, "verifyFailed", undefined, err);
1024
- }
1025
- }
1026
- /**
1027
- * Create bytes for signing from header and payload.
1028
- * @param header The header.
1029
- * @param payload The payload.
1030
- * @returns The bytes to sign.
1031
- */
1032
- static toSigningBytes(header, payload) {
1033
- Guards.object(Jwt._CLASS_NAME, "header", header);
1034
- Guards.object(Jwt._CLASS_NAME, "payload", payload);
1035
- const segments = [];
1036
- const headerBytes = Converter.utf8ToBytes(JSON.stringify(header));
1037
- segments.push(Converter.bytesToBase64Url(headerBytes));
1038
- const payloadBytes = Converter.utf8ToBytes(JSON.stringify(payload));
1039
- segments.push(Converter.bytesToBase64Url(payloadBytes));
1040
- return Converter.utf8ToBytes(segments.join("."));
1041
- }
1042
- /**
1043
- * Create header and payload from signing bytes.
1044
- * @param signingBytes The signing bytes from a token.
1045
- * @returns The header and payload.
1046
- * @throws If the signing bytes are invalid
1047
- */
1048
- static fromSigningBytes(signingBytes) {
1049
- Guards.uint8Array(Jwt._CLASS_NAME, "signingBytes", signingBytes);
1050
- const segments = Converter.bytesToUtf8(signingBytes).split(".");
1051
- if (segments.length !== 2) {
1052
- throw new GeneralError(Jwt._CLASS_NAME, "invalidSigningBytes");
1053
- }
1054
- const headerBytes = Converter.base64UrlToBytes(segments[0]);
1055
- const payloadBytes = Converter.base64UrlToBytes(segments[1]);
1056
- return {
1057
- header: ObjectHelper.fromBytes(headerBytes),
1058
- payload: ObjectHelper.fromBytes(payloadBytes)
1059
- };
1060
- }
1061
- /**
1062
- * Convert signed bytes and signature bytes to token.
1063
- * @param signingBytes The signed bytes.
1064
- * @param signature The signature.
1065
- * @returns The token.
1066
- */
1067
- static tokenFromBytes(signingBytes, signature) {
1068
- Guards.uint8Array(Jwt._CLASS_NAME, "signingBytes", signingBytes);
1069
- Guards.uint8Array(Jwt._CLASS_NAME, "signature", signature);
1070
- const signedBytesUtf8 = Converter.bytesToUtf8(signingBytes);
1071
- const signatureBase64 = Converter.bytesToBase64Url(signature);
1072
- return `${signedBytesUtf8}.${signatureBase64}`;
1073
- }
1074
- /**
1075
- * Convert the token to signing bytes and signature bytes.
1076
- * @param token The token to convert to bytes.
1077
- * @returns The decoded bytes.
1078
- * @throws If the token is invalid.
1079
- */
1080
- static tokenToBytes(token) {
1081
- Guards.stringValue(Jwt._CLASS_NAME, "token", token);
1082
- const segments = token.split(".");
1083
- if (segments.length !== 3) {
1084
- throw new GeneralError(Jwt._CLASS_NAME, "invalidTokenParts");
1085
- }
1086
- const signingBytes = Converter.utf8ToBytes(`${segments[0]}.${segments[1]}`);
1087
- const signature = Converter.base64UrlToBytes(segments[2]);
1088
- return {
1089
- signingBytes,
1090
- signature
1091
- };
1092
- }
1093
- /**
1094
- * Encode a token.
1095
- * @param header The header to encode.
1096
- * @param payload The payload to encode.
1097
- * @param key The key for signing the token, can be omitted if a signer is provided.
1098
- * @param signer Custom signer method.
1099
- * @returns The encoded token.
1100
- * @internal
1101
- */
1102
- static async internalEncode(header, payload, key, signer) {
1103
- const hasKey = Is.notEmpty(key);
1104
- const hasSigner = Is.notEmpty(signer);
1105
- if (!hasKey && !hasSigner) {
1106
- throw new GeneralError(Jwt._CLASS_NAME, "noKeyOrSigner");
1107
- }
1108
- signer ??= async (h, p, k) => Jwt.defaultSigner(h, p, k);
1109
- if (Is.undefined(header.typ)) {
1110
- header.typ = "JWT";
1111
- }
1112
- return signer(header, payload, key);
1113
- }
1114
- }
1115
-
1116
- // Copyright 2024 IOTA Stiftung.
1117
- // SPDX-License-Identifier: Apache-2.0.
1118
- /**
1119
- * Class to help with mime types.
1120
- */
1121
- class MimeTypeHelper {
1122
- /**
1123
- * Detect the mime type from a byte array.
1124
- * @param data The data to test.
1125
- * @returns The mime type if detected.
1126
- */
1127
- static async detect(data) {
1128
- if (!Is.uint8Array(data) || data.length === 0) {
1129
- return undefined;
1130
- }
1131
- // Image
1132
- if (MimeTypeHelper.checkBytes(data, [0x47, 0x49, 0x46])) {
1133
- return MimeTypes.Gif;
1134
- }
1135
- if (MimeTypeHelper.checkBytes(data, [0x42, 0x4d])) {
1136
- return MimeTypes.Bmp;
1137
- }
1138
- if (MimeTypeHelper.checkBytes(data, [0xff, 0xd8, 0xff])) {
1139
- return MimeTypes.Jpeg;
1140
- }
1141
- if (MimeTypeHelper.checkBytes(data, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) {
1142
- return MimeTypes.Png;
1143
- }
1144
- if (MimeTypeHelper.checkBytes(data, [0x49, 0x49, 0x2a, 0x00]) ||
1145
- MimeTypeHelper.checkBytes(data, [0x4d, 0x4d, 0x00, 0x2a])) {
1146
- return MimeTypes.Tiff;
1147
- }
1148
- // Compression
1149
- if (MimeTypeHelper.checkBytes(data, [0x1f, 0x8b, 0x8])) {
1150
- return MimeTypes.Gzip;
1151
- }
1152
- if (MimeTypeHelper.checkBytes(data, [0x78, 0x01]) ||
1153
- MimeTypeHelper.checkBytes(data, [0x78, 0x9c]) ||
1154
- MimeTypeHelper.checkBytes(data, [0x78, 0xda])) {
1155
- return MimeTypes.Zlib;
1156
- }
1157
- if (MimeTypeHelper.checkBytes(data, [0x42, 0x5a, 0x68])) {
1158
- return MimeTypes.Bzip2;
1159
- }
1160
- if (MimeTypeHelper.checkBytes(data, [0x50, 0x4b, 0x3, 0x4])) {
1161
- return MimeTypes.Zip;
1162
- }
1163
- // Documents
1164
- if (MimeTypeHelper.checkText(data, ["%PDF"])) {
1165
- return MimeTypes.Pdf;
1166
- }
1167
- // Lookup svg before xml, as svg are xml files as well
1168
- const asText = Converter.bytesToUtf8(data);
1169
- if (asText.includes("<svg")) {
1170
- return MimeTypes.Svg;
1171
- }
1172
- if (MimeTypeHelper.checkText(data, ["<?xml ", "<message"])) {
1173
- return MimeTypes.Xml;
1174
- }
1175
- if (MimeTypeHelper.checkBytes(data, [0xef, 0xbb, 0xbf]) &&
1176
- MimeTypeHelper.checkText(data, ["<?xml "], 3)) {
1177
- // UTF-8-BOM
1178
- return MimeTypes.Xml;
1179
- }
1180
- if (StringHelper.isUtf8(data)) {
1181
- try {
1182
- JSON.parse(new TextDecoder().decode(data));
1183
- return MimeTypes.Json;
1184
- }
1185
- catch {
1186
- return MimeTypes.PlainText;
1187
- }
1188
- }
1189
- }
1190
- /**
1191
- * Return the default extension for a mime type.
1192
- * @param mimeType The mimetype to get the extension for.
1193
- * @returns The extension for the mime type.
1194
- */
1195
- static defaultExtension(mimeType) {
1196
- if (!Is.stringValue(mimeType)) {
1197
- return undefined;
1198
- }
1199
- const lookup = {
1200
- [MimeTypes.PlainText]: "txt",
1201
- [MimeTypes.Html]: "html",
1202
- [MimeTypes.Javascript]: "js",
1203
- [MimeTypes.Json]: "json",
1204
- [MimeTypes.JsonLd]: "jsonld",
1205
- [MimeTypes.Jwt]: "jwt",
1206
- [MimeTypes.Xml]: "xml",
1207
- [MimeTypes.OctetStream]: "bin",
1208
- [MimeTypes.Gzip]: "gzip",
1209
- [MimeTypes.Zlib]: "zlib",
1210
- [MimeTypes.Bzip2]: "bz2",
1211
- [MimeTypes.Zip]: "zip",
1212
- [MimeTypes.Pdf]: "pdf",
1213
- [MimeTypes.Gif]: "gif",
1214
- [MimeTypes.Bmp]: "bmp",
1215
- [MimeTypes.Jpeg]: "jpeg",
1216
- [MimeTypes.Png]: "png",
1217
- [MimeTypes.Tiff]: "tif",
1218
- [MimeTypes.Svg]: "svg",
1219
- [MimeTypes.WebP]: "webp",
1220
- [MimeTypes.Mp4]: "mp4",
1221
- [MimeTypes.Mpeg]: "mpg",
1222
- [MimeTypes.Webm]: "webm"
1223
- };
1224
- return lookup[mimeType];
1225
- }
1226
- /**
1227
- * Check if the bytes match.
1228
- * @param data The data to look at.
1229
- * @param bytes The bytes to try and match.
1230
- * @param startOffset Start offset in the data.
1231
- * @returns True if the bytes match.
1232
- * @internal
1233
- */
1234
- static checkBytes(data, bytes, startOffset = 0) {
1235
- if (data.length - startOffset < bytes.length) {
1236
- return false;
1237
- }
1238
- for (let i = 0; i < bytes.length; i++) {
1239
- if (data[i + startOffset] !== bytes[i]) {
1240
- return false;
1241
- }
1242
- }
1243
- return true;
1244
- }
1245
- /**
1246
- * Check if the text matches.
1247
- * @param data The data to look at.
1248
- * @param texts The text to try and match.
1249
- * @param startOffset Start offset in the data.
1250
- * @returns True if the bytes match.
1251
- * @internal
1252
- */
1253
- static checkText(data, texts, startOffset = 0) {
1254
- return texts.some(text => MimeTypeHelper.checkBytes(data, Array.from(Converter.utf8ToBytes(text)), startOffset));
1255
- }
1256
- }
1257
-
1258
- export { FetchError, FetchHelper, HeaderTypes, HttpMethod, HttpStatusCode, Jwk, Jws, Jwt, MimeTypeHelper, MimeTypes };