@microlink/mql 0.10.33 → 0.10.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mql.mjs CHANGED
@@ -1,10 +1,14 @@
1
1
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
2
2
 
3
+ function getDefaultExportFromCjs (x) {
4
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
5
+ }
6
+
3
7
  const URL$1 = globalThis.URL;
4
8
 
5
9
  const REGEX_HTTP_PROTOCOL = /^https?:\/\//i;
6
10
 
7
- var lightweight = url => {
11
+ var lightweight$2 = url => {
8
12
  try {
9
13
  const { href } = new URL$1(url);
10
14
  return REGEX_HTTP_PROTOCOL.test(href) && href
@@ -97,7 +101,7 @@ const factory$1 = ({ VERSION, MicrolinkError, urlHttp, got, flatten }) => {
97
101
  }, {})
98
102
  };
99
103
 
100
- const fetchFromApi = async (apiUrl, opts = {}, retryCount = 0) => {
104
+ const fetchFromApi = async (apiUrl, opts = {}) => {
101
105
  try {
102
106
  const response = await got(apiUrl, opts);
103
107
  return opts.responseType === 'buffer'
@@ -118,10 +122,6 @@ const factory$1 = ({ VERSION, MicrolinkError, urlHttp, got, flatten }) => {
118
122
  ? rawBody
119
123
  : parseBody(isBodyBuffer ? rawBody.toString() : rawBody, err, uri);
120
124
 
121
- if (body.code === 'EFATALCLIENT' && retryCount++ < 2) {
122
- return fetchFromApi(apiUrl, opts, retryCount)
123
- }
124
-
125
125
  throw new MicrolinkError({
126
126
  ...body,
127
127
  message: body.message,
@@ -175,11 +175,7 @@ const factory$1 = ({ VERSION, MicrolinkError, urlHttp, got, flatten }) => {
175
175
 
176
176
  var factory_1 = factory$1;
177
177
 
178
- var kyExports = {};
179
- var ky$1 = {
180
- get exports(){ return kyExports; },
181
- set exports(v){ kyExports = v; },
182
- };
178
+ var ky$1 = {exports: {}};
183
179
 
184
180
  (function (module, exports) {
185
181
  (function (global, factory) {
@@ -193,6 +189,24 @@ var ky$1 = {
193
189
  const status = `${code} ${title}`.trim();
194
190
  const reason = status ? `status code ${status}` : 'an unknown error';
195
191
  super(`Request failed with ${reason}`);
192
+ Object.defineProperty(this, "response", {
193
+ enumerable: true,
194
+ configurable: true,
195
+ writable: true,
196
+ value: void 0
197
+ });
198
+ Object.defineProperty(this, "request", {
199
+ enumerable: true,
200
+ configurable: true,
201
+ writable: true,
202
+ value: void 0
203
+ });
204
+ Object.defineProperty(this, "options", {
205
+ enumerable: true,
206
+ configurable: true,
207
+ writable: true,
208
+ value: void 0
209
+ });
196
210
  this.name = 'HTTPError';
197
211
  this.response = response;
198
212
  this.request = request;
@@ -203,6 +217,12 @@ var ky$1 = {
203
217
  class TimeoutError extends Error {
204
218
  constructor(request) {
205
219
  super('Request timed out');
220
+ Object.defineProperty(this, "request", {
221
+ enumerable: true,
222
+ configurable: true,
223
+ writable: true,
224
+ value: void 0
225
+ });
206
226
  this.name = 'TimeoutError';
207
227
  this.request = request;
208
228
  }
@@ -213,7 +233,7 @@ var ky$1 = {
213
233
 
214
234
  const validateAndMerge = (...sources) => {
215
235
  for (const source of sources) {
216
- if ((!isObject(source) || Array.isArray(source)) && typeof source !== 'undefined') {
236
+ if ((!isObject(source) || Array.isArray(source)) && source !== undefined) {
217
237
  throw new TypeError('The `options` argument must be an object');
218
238
  }
219
239
  }
@@ -260,8 +280,26 @@ var ky$1 = {
260
280
  return returnValue;
261
281
  };
262
282
 
283
+ const supportsRequestStreams = (() => {
284
+ let duplexAccessed = false;
285
+ let hasContentType = false;
286
+ const supportsReadableStream = typeof globalThis.ReadableStream === 'function';
287
+ const supportsRequest = typeof globalThis.Request === 'function';
288
+ if (supportsReadableStream && supportsRequest) {
289
+ hasContentType = new globalThis.Request('https://empty.invalid', {
290
+ body: new globalThis.ReadableStream(),
291
+ method: 'POST',
292
+ // @ts-expect-error - Types are outdated.
293
+ get duplex() {
294
+ duplexAccessed = true;
295
+ return 'half';
296
+ },
297
+ }).headers.has('Content-Type');
298
+ }
299
+ return duplexAccessed && !hasContentType;
300
+ })();
263
301
  const supportsAbortController = typeof globalThis.AbortController === 'function';
264
- const supportsStreams = typeof globalThis.ReadableStream === 'function';
302
+ const supportsResponseStreams = typeof globalThis.ReadableStream === 'function';
265
303
  const supportsFormData = typeof globalThis.FormData === 'function';
266
304
  const requestMethods = ['get', 'post', 'put', 'patch', 'head', 'delete'];
267
305
  const responseTypes = {
@@ -285,6 +323,7 @@ var ky$1 = {
285
323
  statusCodes: retryStatusCodes,
286
324
  afterStatusCodes: retryAfterStatusCodes,
287
325
  maxRetryAfter: Number.POSITIVE_INFINITY,
326
+ backoffLimit: Number.POSITIVE_INFINITY,
288
327
  };
289
328
  const normalizeRetryOptions = (retry = {}) => {
290
329
  if (typeof retry === 'number') {
@@ -307,30 +346,139 @@ var ky$1 = {
307
346
  };
308
347
 
309
348
  // `Promise.race()` workaround (#91)
310
- const timeout = async (request, abortController, options) => new Promise((resolve, reject) => {
311
- const timeoutId = setTimeout(() => {
312
- if (abortController) {
313
- abortController.abort();
349
+ async function timeout(request, abortController, options) {
350
+ return new Promise((resolve, reject) => {
351
+ const timeoutId = setTimeout(() => {
352
+ if (abortController) {
353
+ abortController.abort();
354
+ }
355
+ reject(new TimeoutError(request));
356
+ }, options.timeout);
357
+ void options
358
+ .fetch(request)
359
+ .then(resolve)
360
+ .catch(reject)
361
+ .then(() => {
362
+ clearTimeout(timeoutId);
363
+ });
364
+ });
365
+ }
366
+
367
+ // https://github.com/sindresorhus/delay/tree/ab98ae8dfcb38e1593286c94d934e70d14a4e111
368
+ async function delay(ms, { signal }) {
369
+ return new Promise((resolve, reject) => {
370
+ if (signal) {
371
+ signal.throwIfAborted();
372
+ signal.addEventListener('abort', abortHandler, { once: true });
373
+ }
374
+ function abortHandler() {
375
+ clearTimeout(timeoutId);
376
+ reject(signal.reason);
314
377
  }
315
- reject(new TimeoutError(request));
316
- }, options.timeout);
317
- void options
318
- .fetch(request)
319
- .then(resolve)
320
- .catch(reject)
321
- .then(() => {
322
- clearTimeout(timeoutId);
378
+ const timeoutId = setTimeout(() => {
379
+ signal?.removeEventListener('abort', abortHandler);
380
+ resolve();
381
+ }, ms);
323
382
  });
324
- });
325
- const delay = async (ms) => new Promise(resolve => {
326
- setTimeout(resolve, ms);
327
- });
383
+ }
328
384
 
329
385
  class Ky {
386
+ static create(input, options) {
387
+ const ky = new Ky(input, options);
388
+ const fn = async () => {
389
+ if (typeof ky._options.timeout === 'number' && ky._options.timeout > maxSafeTimeout) {
390
+ throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
391
+ }
392
+ // Delay the fetch so that body method shortcuts can set the Accept header
393
+ await Promise.resolve();
394
+ let response = await ky._fetch();
395
+ for (const hook of ky._options.hooks.afterResponse) {
396
+ // eslint-disable-next-line no-await-in-loop
397
+ const modifiedResponse = await hook(ky.request, ky._options, ky._decorateResponse(response.clone()));
398
+ if (modifiedResponse instanceof globalThis.Response) {
399
+ response = modifiedResponse;
400
+ }
401
+ }
402
+ ky._decorateResponse(response);
403
+ if (!response.ok && ky._options.throwHttpErrors) {
404
+ let error = new HTTPError(response, ky.request, ky._options);
405
+ for (const hook of ky._options.hooks.beforeError) {
406
+ // eslint-disable-next-line no-await-in-loop
407
+ error = await hook(error);
408
+ }
409
+ throw error;
410
+ }
411
+ // If `onDownloadProgress` is passed, it uses the stream API internally
412
+ /* istanbul ignore next */
413
+ if (ky._options.onDownloadProgress) {
414
+ if (typeof ky._options.onDownloadProgress !== 'function') {
415
+ throw new TypeError('The `onDownloadProgress` option must be a function');
416
+ }
417
+ if (!supportsResponseStreams) {
418
+ throw new Error('Streams are not supported in your environment. `ReadableStream` is missing.');
419
+ }
420
+ return ky._stream(response.clone(), ky._options.onDownloadProgress);
421
+ }
422
+ return response;
423
+ };
424
+ const isRetriableMethod = ky._options.retry.methods.includes(ky.request.method.toLowerCase());
425
+ const result = (isRetriableMethod ? ky._retry(fn) : fn());
426
+ for (const [type, mimeType] of Object.entries(responseTypes)) {
427
+ result[type] = async () => {
428
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
429
+ ky.request.headers.set('accept', ky.request.headers.get('accept') || mimeType);
430
+ const awaitedResult = await result;
431
+ const response = awaitedResult.clone();
432
+ if (type === 'json') {
433
+ if (response.status === 204) {
434
+ return '';
435
+ }
436
+ const arrayBuffer = await response.clone().arrayBuffer();
437
+ const responseSize = arrayBuffer.byteLength;
438
+ if (responseSize === 0) {
439
+ return '';
440
+ }
441
+ if (options.parseJson) {
442
+ return options.parseJson(await response.text());
443
+ }
444
+ }
445
+ return response[type]();
446
+ };
447
+ }
448
+ return result;
449
+ }
330
450
  // eslint-disable-next-line complexity
331
451
  constructor(input, options = {}) {
332
- var _a, _b, _c;
333
- this._retryCount = 0;
452
+ Object.defineProperty(this, "request", {
453
+ enumerable: true,
454
+ configurable: true,
455
+ writable: true,
456
+ value: void 0
457
+ });
458
+ Object.defineProperty(this, "abortController", {
459
+ enumerable: true,
460
+ configurable: true,
461
+ writable: true,
462
+ value: void 0
463
+ });
464
+ Object.defineProperty(this, "_retryCount", {
465
+ enumerable: true,
466
+ configurable: true,
467
+ writable: true,
468
+ value: 0
469
+ });
470
+ Object.defineProperty(this, "_input", {
471
+ enumerable: true,
472
+ configurable: true,
473
+ writable: true,
474
+ value: void 0
475
+ });
476
+ Object.defineProperty(this, "_options", {
477
+ enumerable: true,
478
+ configurable: true,
479
+ writable: true,
480
+ value: void 0
481
+ });
334
482
  this._input = input;
335
483
  this._options = {
336
484
  // TODO: credentials can be removed when the spec change is implemented in all browsers. Context: https://www.chromestatus.com/feature/4539473312350208
@@ -343,13 +491,13 @@ var ky$1 = {
343
491
  beforeError: [],
344
492
  afterResponse: [],
345
493
  }, options.hooks),
346
- method: normalizeRequestMethod((_a = options.method) !== null && _a !== void 0 ? _a : this._input.method),
494
+ method: normalizeRequestMethod(options.method ?? this._input.method),
347
495
  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
348
496
  prefixUrl: String(options.prefixUrl || ''),
349
497
  retry: normalizeRetryOptions(options.retry),
350
498
  throwHttpErrors: options.throwHttpErrors !== false,
351
- timeout: typeof options.timeout === 'undefined' ? 10000 : options.timeout,
352
- fetch: (_b = options.fetch) !== null && _b !== void 0 ? _b : globalThis.fetch.bind(globalThis),
499
+ timeout: options.timeout ?? 10000,
500
+ fetch: options.fetch ?? globalThis.fetch.bind(globalThis),
353
501
  };
354
502
  if (typeof this._input !== 'string' && !(this._input instanceof URL || this._input instanceof globalThis.Request)) {
355
503
  throw new TypeError('`input` must be a string, URL, or Request');
@@ -366,12 +514,17 @@ var ky$1 = {
366
514
  if (supportsAbortController) {
367
515
  this.abortController = new globalThis.AbortController();
368
516
  if (this._options.signal) {
517
+ const originalSignal = this._options.signal;
369
518
  this._options.signal.addEventListener('abort', () => {
370
- this.abortController.abort();
519
+ this.abortController.abort(originalSignal.reason);
371
520
  });
372
521
  }
373
522
  this._options.signal = this.abortController.signal;
374
523
  }
524
+ if (supportsRequestStreams) {
525
+ // @ts-expect-error - Types are outdated.
526
+ this._options.duplex = 'half';
527
+ }
375
528
  this.request = new globalThis.Request(this._input, this._options);
376
529
  if (this._options.searchParams) {
377
530
  // eslint-disable-next-line unicorn/prevent-abbreviations
@@ -386,74 +539,15 @@ var ky$1 = {
386
539
  || this._options.body instanceof URLSearchParams) && !(this._options.headers && this._options.headers['content-type'])) {
387
540
  this.request.headers.delete('content-type');
388
541
  }
389
- this.request = new globalThis.Request(new globalThis.Request(url, this.request), this._options);
542
+ // The spread of `this.request` is required as otherwise it misses the `duplex` option for some reason and throws.
543
+ this.request = new globalThis.Request(new globalThis.Request(url, { ...this.request }), this._options);
390
544
  }
391
545
  if (this._options.json !== undefined) {
392
546
  this._options.body = JSON.stringify(this._options.json);
393
- this.request.headers.set('content-type', (_c = this._options.headers.get('content-type')) !== null && _c !== void 0 ? _c : 'application/json');
547
+ this.request.headers.set('content-type', this._options.headers.get('content-type') ?? 'application/json');
394
548
  this.request = new globalThis.Request(this.request, { body: this._options.body });
395
549
  }
396
550
  }
397
- // eslint-disable-next-line @typescript-eslint/promise-function-async
398
- static create(input, options) {
399
- const ky = new Ky(input, options);
400
- const fn = async () => {
401
- if (ky._options.timeout > maxSafeTimeout) {
402
- throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
403
- }
404
- // Delay the fetch so that body method shortcuts can set the Accept header
405
- await Promise.resolve();
406
- let response = await ky._fetch();
407
- for (const hook of ky._options.hooks.afterResponse) {
408
- // eslint-disable-next-line no-await-in-loop
409
- const modifiedResponse = await hook(ky.request, ky._options, ky._decorateResponse(response.clone()));
410
- if (modifiedResponse instanceof globalThis.Response) {
411
- response = modifiedResponse;
412
- }
413
- }
414
- ky._decorateResponse(response);
415
- if (!response.ok && ky._options.throwHttpErrors) {
416
- let error = new HTTPError(response, ky.request, ky._options);
417
- for (const hook of ky._options.hooks.beforeError) {
418
- // eslint-disable-next-line no-await-in-loop
419
- error = await hook(error);
420
- }
421
- throw error;
422
- }
423
- // If `onDownloadProgress` is passed, it uses the stream API internally
424
- /* istanbul ignore next */
425
- if (ky._options.onDownloadProgress) {
426
- if (typeof ky._options.onDownloadProgress !== 'function') {
427
- throw new TypeError('The `onDownloadProgress` option must be a function');
428
- }
429
- if (!supportsStreams) {
430
- throw new Error('Streams are not supported in your environment. `ReadableStream` is missing.');
431
- }
432
- return ky._stream(response.clone(), ky._options.onDownloadProgress);
433
- }
434
- return response;
435
- };
436
- const isRetriableMethod = ky._options.retry.methods.includes(ky.request.method.toLowerCase());
437
- const result = (isRetriableMethod ? ky._retry(fn) : fn());
438
- for (const [type, mimeType] of Object.entries(responseTypes)) {
439
- result[type] = async () => {
440
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
441
- ky.request.headers.set('accept', ky.request.headers.get('accept') || mimeType);
442
- const awaitedResult = await result;
443
- const response = awaitedResult.clone();
444
- if (type === 'json') {
445
- if (response.status === 204) {
446
- return '';
447
- }
448
- if (options.parseJson) {
449
- return options.parseJson(await response.text());
450
- }
451
- }
452
- return response[type]();
453
- };
454
- }
455
- return result;
456
- }
457
551
  _calculateRetryDelay(error) {
458
552
  this._retryCount++;
459
553
  if (this._retryCount < this._options.retry.limit && !(error instanceof TimeoutError)) {
@@ -470,7 +564,7 @@ var ky$1 = {
470
564
  else {
471
565
  after *= 1000;
472
566
  }
473
- if (typeof this._options.retry.maxRetryAfter !== 'undefined' && after > this._options.retry.maxRetryAfter) {
567
+ if (this._options.retry.maxRetryAfter !== undefined && after > this._options.retry.maxRetryAfter) {
474
568
  return 0;
475
569
  }
476
570
  return after;
@@ -480,7 +574,7 @@ var ky$1 = {
480
574
  }
481
575
  }
482
576
  const BACKOFF_FACTOR = 0.3;
483
- return BACKOFF_FACTOR * (2 ** (this._retryCount - 1)) * 1000;
577
+ return Math.min(this._options.retry.backoffLimit, BACKOFF_FACTOR * (2 ** (this._retryCount - 1)) * 1000);
484
578
  }
485
579
  return 0;
486
580
  }
@@ -493,12 +587,11 @@ var ky$1 = {
493
587
  async _retry(fn) {
494
588
  try {
495
589
  return await fn();
496
- // eslint-disable-next-line @typescript-eslint/no-implicit-any-catch
497
590
  }
498
591
  catch (error) {
499
592
  const ms = Math.min(this._calculateRetryDelay(error), maxSafeTimeout);
500
593
  if (ms !== 0 && this._retryCount > 0) {
501
- await delay(ms);
594
+ await delay(ms, { signal: this._options.signal });
502
595
  for (const hook of this._options.hooks.beforeRetry) {
503
596
  // eslint-disable-next-line no-await-in-loop
504
597
  const hookResult = await hook({
@@ -538,6 +631,16 @@ var ky$1 = {
538
631
  _stream(response, onDownloadProgress) {
539
632
  const totalBytes = Number(response.headers.get('content-length')) || 0;
540
633
  let transferredBytes = 0;
634
+ if (response.status === 204) {
635
+ if (onDownloadProgress) {
636
+ onDownloadProgress({ percent: 1, totalBytes, transferredBytes }, new Uint8Array());
637
+ }
638
+ return new globalThis.Response(null, {
639
+ status: response.status,
640
+ statusText: response.statusText,
641
+ headers: response.headers,
642
+ });
643
+ }
541
644
  return new globalThis.Response(new globalThis.ReadableStream({
542
645
  async start(controller) {
543
646
  const reader = response.body.getReader();
@@ -560,7 +663,11 @@ var ky$1 = {
560
663
  }
561
664
  await read();
562
665
  },
563
- }));
666
+ }), {
667
+ status: response.status,
668
+ statusText: response.statusText,
669
+ headers: response.headers,
670
+ });
564
671
  }
565
672
  }
566
673
 
@@ -581,14 +688,16 @@ var ky$1 = {
581
688
 
582
689
  exports.HTTPError = HTTPError;
583
690
  exports.TimeoutError = TimeoutError;
584
- exports["default"] = ky;
691
+ exports.default = ky;
585
692
 
586
693
  Object.defineProperty(exports, '__esModule', { value: true });
587
694
 
588
- }));
589
- } (ky$1, kyExports));
695
+ }));
696
+ } (ky$1, ky$1.exports));
590
697
 
591
- const urlHttp = lightweight;
698
+ var kyExports = ky$1.exports;
699
+
700
+ const urlHttp = lightweight$2;
592
701
  const { flattie: flatten } = dist;
593
702
 
594
703
  const factory = factory_1;
@@ -608,6 +717,7 @@ class MicrolinkError extends Error {
608
717
 
609
718
  const got = async (url, opts) => {
610
719
  try {
720
+ if (opts.retry > 0) opts.retry = opts.retry + 1;
611
721
  if (opts.timeout === undefined) opts.timeout = false;
612
722
  const response = await ky(url, opts);
613
723
  const body = await response.json();
@@ -633,13 +743,15 @@ const got = async (url, opts) => {
633
743
  }
634
744
  };
635
745
 
636
- var browser = factory({
746
+ var lightweight = factory({
637
747
  MicrolinkError,
638
748
  urlHttp,
639
749
  got,
640
750
  flatten,
641
- VERSION: '0.10.33'
751
+ VERSION: '0.10.35'
642
752
  });
643
753
 
644
- export { browser as default };
754
+ var lightweight$1 = /*@__PURE__*/getDefaultExportFromCjs(lightweight);
755
+
756
+ export { lightweight$1 as default };
645
757
  //# sourceMappingURL=mql.mjs.map