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