@microlink/mql 0.10.32 → 0.10.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md CHANGED
File without changes
package/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  <div align="center">
2
- <img src="https://cdn.microlink.io/banner/mql.png" alt="microlink logo">
2
+ <img src="https://github.com/microlinkhq/cdn/raw/master/dist/banner/mql.png#gh-light-mode-only" alt="microlink logo">
3
+ <img src="https://github.com/microlinkhq/cdn/raw/master/dist/banner/mql-dark.png#gh-dark-mode-only" alt="microlink logo">
3
4
  </div>
4
5
 
5
6
  ###### [Documentation](https://microlink.io/mql) | [CLI](https://github.com/microlinkhq/cli) | [Playground](https://mql.microlink.io) | [Chat](https://microlink.io/chat)
package/dist/mql.js CHANGED
@@ -6,6 +6,10 @@
6
6
 
7
7
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
8
8
 
9
+ function getDefaultExportFromCjs (x) {
10
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
11
+ }
12
+
9
13
  const URL$1 = globalThis.URL;
10
14
 
11
15
  const REGEX_HTTP_PROTOCOL = /^https?:\/\//i;
@@ -79,14 +83,7 @@
79
83
  }
80
84
  };
81
85
 
82
- const factory$1 = ({
83
- VERSION,
84
- MicrolinkError,
85
- urlHttp,
86
- stringify,
87
- got,
88
- flatten
89
- }) => {
86
+ const factory$1 = ({ VERSION, MicrolinkError, urlHttp, got, flatten }) => {
90
87
  const assertUrl = (url = '') => {
91
88
  if (!urlHttp(url)) {
92
89
  const message = `The \`url\` as \`${url}\` is not valid. Ensure it has protocol (http or https) and hostname.`;
@@ -110,7 +107,7 @@
110
107
  }, {})
111
108
  };
112
109
 
113
- const fetchFromApi = async (apiUrl, opts = {}, retryCount = 0) => {
110
+ const fetchFromApi = async (apiUrl, opts = {}) => {
114
111
  try {
115
112
  const response = await got(apiUrl, opts);
116
113
  return opts.responseType === 'buffer'
@@ -131,10 +128,6 @@
131
128
  ? rawBody
132
129
  : parseBody(isBodyBuffer ? rawBody.toString() : rawBody, err, uri);
133
130
 
134
- if (body.code === 'EFATALCLIENT' && retryCount++ < 2) {
135
- return fetchFromApi(apiUrl, opts, retryCount)
136
- }
137
-
138
131
  throw new MicrolinkError({
139
132
  ...body,
140
133
  message: body.message,
@@ -188,11 +181,7 @@
188
181
 
189
182
  var factory_1 = factory$1;
190
183
 
191
- var kyExports = {};
192
- var ky$1 = {
193
- get exports(){ return kyExports; },
194
- set exports(v){ kyExports = v; },
195
- };
184
+ var ky$1 = {exports: {}};
196
185
 
197
186
  (function (module, exports) {
198
187
  (function (global, factory) {
@@ -206,6 +195,24 @@
206
195
  const status = `${code} ${title}`.trim();
207
196
  const reason = status ? `status code ${status}` : 'an unknown error';
208
197
  super(`Request failed with ${reason}`);
198
+ Object.defineProperty(this, "response", {
199
+ enumerable: true,
200
+ configurable: true,
201
+ writable: true,
202
+ value: void 0
203
+ });
204
+ Object.defineProperty(this, "request", {
205
+ enumerable: true,
206
+ configurable: true,
207
+ writable: true,
208
+ value: void 0
209
+ });
210
+ Object.defineProperty(this, "options", {
211
+ enumerable: true,
212
+ configurable: true,
213
+ writable: true,
214
+ value: void 0
215
+ });
209
216
  this.name = 'HTTPError';
210
217
  this.response = response;
211
218
  this.request = request;
@@ -216,6 +223,12 @@
216
223
  class TimeoutError extends Error {
217
224
  constructor(request) {
218
225
  super('Request timed out');
226
+ Object.defineProperty(this, "request", {
227
+ enumerable: true,
228
+ configurable: true,
229
+ writable: true,
230
+ value: void 0
231
+ });
219
232
  this.name = 'TimeoutError';
220
233
  this.request = request;
221
234
  }
@@ -226,7 +239,7 @@
226
239
 
227
240
  const validateAndMerge = (...sources) => {
228
241
  for (const source of sources) {
229
- if ((!isObject(source) || Array.isArray(source)) && typeof source !== 'undefined') {
242
+ if ((!isObject(source) || Array.isArray(source)) && source !== undefined) {
230
243
  throw new TypeError('The `options` argument must be an object');
231
244
  }
232
245
  }
@@ -273,8 +286,26 @@
273
286
  return returnValue;
274
287
  };
275
288
 
289
+ const supportsRequestStreams = (() => {
290
+ let duplexAccessed = false;
291
+ let hasContentType = false;
292
+ const supportsReadableStream = typeof globalThis.ReadableStream === 'function';
293
+ const supportsRequest = typeof globalThis.Request === 'function';
294
+ if (supportsReadableStream && supportsRequest) {
295
+ hasContentType = new globalThis.Request('https://empty.invalid', {
296
+ body: new globalThis.ReadableStream(),
297
+ method: 'POST',
298
+ // @ts-expect-error - Types are outdated.
299
+ get duplex() {
300
+ duplexAccessed = true;
301
+ return 'half';
302
+ },
303
+ }).headers.has('Content-Type');
304
+ }
305
+ return duplexAccessed && !hasContentType;
306
+ })();
276
307
  const supportsAbortController = typeof globalThis.AbortController === 'function';
277
- const supportsStreams = typeof globalThis.ReadableStream === 'function';
308
+ const supportsResponseStreams = typeof globalThis.ReadableStream === 'function';
278
309
  const supportsFormData = typeof globalThis.FormData === 'function';
279
310
  const requestMethods = ['get', 'post', 'put', 'patch', 'head', 'delete'];
280
311
  const responseTypes = {
@@ -298,6 +329,7 @@
298
329
  statusCodes: retryStatusCodes,
299
330
  afterStatusCodes: retryAfterStatusCodes,
300
331
  maxRetryAfter: Number.POSITIVE_INFINITY,
332
+ backoffLimit: Number.POSITIVE_INFINITY,
301
333
  };
302
334
  const normalizeRetryOptions = (retry = {}) => {
303
335
  if (typeof retry === 'number') {
@@ -320,30 +352,139 @@
320
352
  };
321
353
 
322
354
  // `Promise.race()` workaround (#91)
323
- const timeout = async (request, abortController, options) => new Promise((resolve, reject) => {
324
- const timeoutId = setTimeout(() => {
325
- if (abortController) {
326
- abortController.abort();
355
+ async function timeout(request, abortController, options) {
356
+ return new Promise((resolve, reject) => {
357
+ const timeoutId = setTimeout(() => {
358
+ if (abortController) {
359
+ abortController.abort();
360
+ }
361
+ reject(new TimeoutError(request));
362
+ }, options.timeout);
363
+ void options
364
+ .fetch(request)
365
+ .then(resolve)
366
+ .catch(reject)
367
+ .then(() => {
368
+ clearTimeout(timeoutId);
369
+ });
370
+ });
371
+ }
372
+
373
+ // https://github.com/sindresorhus/delay/tree/ab98ae8dfcb38e1593286c94d934e70d14a4e111
374
+ async function delay(ms, { signal }) {
375
+ return new Promise((resolve, reject) => {
376
+ if (signal) {
377
+ signal.throwIfAborted();
378
+ signal.addEventListener('abort', abortHandler, { once: true });
379
+ }
380
+ function abortHandler() {
381
+ clearTimeout(timeoutId);
382
+ reject(signal.reason);
327
383
  }
328
- reject(new TimeoutError(request));
329
- }, options.timeout);
330
- void options
331
- .fetch(request)
332
- .then(resolve)
333
- .catch(reject)
334
- .then(() => {
335
- clearTimeout(timeoutId);
384
+ const timeoutId = setTimeout(() => {
385
+ signal?.removeEventListener('abort', abortHandler);
386
+ resolve();
387
+ }, ms);
336
388
  });
337
- });
338
- const delay = async (ms) => new Promise(resolve => {
339
- setTimeout(resolve, ms);
340
- });
389
+ }
341
390
 
342
391
  class Ky {
392
+ static create(input, options) {
393
+ const ky = new Ky(input, options);
394
+ const fn = async () => {
395
+ if (typeof ky._options.timeout === 'number' && ky._options.timeout > maxSafeTimeout) {
396
+ throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
397
+ }
398
+ // Delay the fetch so that body method shortcuts can set the Accept header
399
+ await Promise.resolve();
400
+ let response = await ky._fetch();
401
+ for (const hook of ky._options.hooks.afterResponse) {
402
+ // eslint-disable-next-line no-await-in-loop
403
+ const modifiedResponse = await hook(ky.request, ky._options, ky._decorateResponse(response.clone()));
404
+ if (modifiedResponse instanceof globalThis.Response) {
405
+ response = modifiedResponse;
406
+ }
407
+ }
408
+ ky._decorateResponse(response);
409
+ if (!response.ok && ky._options.throwHttpErrors) {
410
+ let error = new HTTPError(response, ky.request, ky._options);
411
+ for (const hook of ky._options.hooks.beforeError) {
412
+ // eslint-disable-next-line no-await-in-loop
413
+ error = await hook(error);
414
+ }
415
+ throw error;
416
+ }
417
+ // If `onDownloadProgress` is passed, it uses the stream API internally
418
+ /* istanbul ignore next */
419
+ if (ky._options.onDownloadProgress) {
420
+ if (typeof ky._options.onDownloadProgress !== 'function') {
421
+ throw new TypeError('The `onDownloadProgress` option must be a function');
422
+ }
423
+ if (!supportsResponseStreams) {
424
+ throw new Error('Streams are not supported in your environment. `ReadableStream` is missing.');
425
+ }
426
+ return ky._stream(response.clone(), ky._options.onDownloadProgress);
427
+ }
428
+ return response;
429
+ };
430
+ const isRetriableMethod = ky._options.retry.methods.includes(ky.request.method.toLowerCase());
431
+ const result = (isRetriableMethod ? ky._retry(fn) : fn());
432
+ for (const [type, mimeType] of Object.entries(responseTypes)) {
433
+ result[type] = async () => {
434
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
435
+ ky.request.headers.set('accept', ky.request.headers.get('accept') || mimeType);
436
+ const awaitedResult = await result;
437
+ const response = awaitedResult.clone();
438
+ if (type === 'json') {
439
+ if (response.status === 204) {
440
+ return '';
441
+ }
442
+ const arrayBuffer = await response.clone().arrayBuffer();
443
+ const responseSize = arrayBuffer.byteLength;
444
+ if (responseSize === 0) {
445
+ return '';
446
+ }
447
+ if (options.parseJson) {
448
+ return options.parseJson(await response.text());
449
+ }
450
+ }
451
+ return response[type]();
452
+ };
453
+ }
454
+ return result;
455
+ }
343
456
  // eslint-disable-next-line complexity
344
457
  constructor(input, options = {}) {
345
- var _a, _b, _c;
346
- this._retryCount = 0;
458
+ Object.defineProperty(this, "request", {
459
+ enumerable: true,
460
+ configurable: true,
461
+ writable: true,
462
+ value: void 0
463
+ });
464
+ Object.defineProperty(this, "abortController", {
465
+ enumerable: true,
466
+ configurable: true,
467
+ writable: true,
468
+ value: void 0
469
+ });
470
+ Object.defineProperty(this, "_retryCount", {
471
+ enumerable: true,
472
+ configurable: true,
473
+ writable: true,
474
+ value: 0
475
+ });
476
+ Object.defineProperty(this, "_input", {
477
+ enumerable: true,
478
+ configurable: true,
479
+ writable: true,
480
+ value: void 0
481
+ });
482
+ Object.defineProperty(this, "_options", {
483
+ enumerable: true,
484
+ configurable: true,
485
+ writable: true,
486
+ value: void 0
487
+ });
347
488
  this._input = input;
348
489
  this._options = {
349
490
  // TODO: credentials can be removed when the spec change is implemented in all browsers. Context: https://www.chromestatus.com/feature/4539473312350208
@@ -356,13 +497,13 @@
356
497
  beforeError: [],
357
498
  afterResponse: [],
358
499
  }, options.hooks),
359
- method: normalizeRequestMethod((_a = options.method) !== null && _a !== void 0 ? _a : this._input.method),
500
+ method: normalizeRequestMethod(options.method ?? this._input.method),
360
501
  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
361
502
  prefixUrl: String(options.prefixUrl || ''),
362
503
  retry: normalizeRetryOptions(options.retry),
363
504
  throwHttpErrors: options.throwHttpErrors !== false,
364
- timeout: typeof options.timeout === 'undefined' ? 10000 : options.timeout,
365
- fetch: (_b = options.fetch) !== null && _b !== void 0 ? _b : globalThis.fetch.bind(globalThis),
505
+ timeout: options.timeout ?? 10000,
506
+ fetch: options.fetch ?? globalThis.fetch.bind(globalThis),
366
507
  };
367
508
  if (typeof this._input !== 'string' && !(this._input instanceof URL || this._input instanceof globalThis.Request)) {
368
509
  throw new TypeError('`input` must be a string, URL, or Request');
@@ -379,12 +520,17 @@
379
520
  if (supportsAbortController) {
380
521
  this.abortController = new globalThis.AbortController();
381
522
  if (this._options.signal) {
523
+ const originalSignal = this._options.signal;
382
524
  this._options.signal.addEventListener('abort', () => {
383
- this.abortController.abort();
525
+ this.abortController.abort(originalSignal.reason);
384
526
  });
385
527
  }
386
528
  this._options.signal = this.abortController.signal;
387
529
  }
530
+ if (supportsRequestStreams) {
531
+ // @ts-expect-error - Types are outdated.
532
+ this._options.duplex = 'half';
533
+ }
388
534
  this.request = new globalThis.Request(this._input, this._options);
389
535
  if (this._options.searchParams) {
390
536
  // eslint-disable-next-line unicorn/prevent-abbreviations
@@ -399,74 +545,15 @@
399
545
  || this._options.body instanceof URLSearchParams) && !(this._options.headers && this._options.headers['content-type'])) {
400
546
  this.request.headers.delete('content-type');
401
547
  }
402
- this.request = new globalThis.Request(new globalThis.Request(url, this.request), this._options);
548
+ // The spread of `this.request` is required as otherwise it misses the `duplex` option for some reason and throws.
549
+ this.request = new globalThis.Request(new globalThis.Request(url, { ...this.request }), this._options);
403
550
  }
404
551
  if (this._options.json !== undefined) {
405
552
  this._options.body = JSON.stringify(this._options.json);
406
- this.request.headers.set('content-type', (_c = this._options.headers.get('content-type')) !== null && _c !== void 0 ? _c : 'application/json');
553
+ this.request.headers.set('content-type', this._options.headers.get('content-type') ?? 'application/json');
407
554
  this.request = new globalThis.Request(this.request, { body: this._options.body });
408
555
  }
409
556
  }
410
- // eslint-disable-next-line @typescript-eslint/promise-function-async
411
- static create(input, options) {
412
- const ky = new Ky(input, options);
413
- const fn = async () => {
414
- if (ky._options.timeout > maxSafeTimeout) {
415
- throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
416
- }
417
- // Delay the fetch so that body method shortcuts can set the Accept header
418
- await Promise.resolve();
419
- let response = await ky._fetch();
420
- for (const hook of ky._options.hooks.afterResponse) {
421
- // eslint-disable-next-line no-await-in-loop
422
- const modifiedResponse = await hook(ky.request, ky._options, ky._decorateResponse(response.clone()));
423
- if (modifiedResponse instanceof globalThis.Response) {
424
- response = modifiedResponse;
425
- }
426
- }
427
- ky._decorateResponse(response);
428
- if (!response.ok && ky._options.throwHttpErrors) {
429
- let error = new HTTPError(response, ky.request, ky._options);
430
- for (const hook of ky._options.hooks.beforeError) {
431
- // eslint-disable-next-line no-await-in-loop
432
- error = await hook(error);
433
- }
434
- throw error;
435
- }
436
- // If `onDownloadProgress` is passed, it uses the stream API internally
437
- /* istanbul ignore next */
438
- if (ky._options.onDownloadProgress) {
439
- if (typeof ky._options.onDownloadProgress !== 'function') {
440
- throw new TypeError('The `onDownloadProgress` option must be a function');
441
- }
442
- if (!supportsStreams) {
443
- throw new Error('Streams are not supported in your environment. `ReadableStream` is missing.');
444
- }
445
- return ky._stream(response.clone(), ky._options.onDownloadProgress);
446
- }
447
- return response;
448
- };
449
- const isRetriableMethod = ky._options.retry.methods.includes(ky.request.method.toLowerCase());
450
- const result = (isRetriableMethod ? ky._retry(fn) : fn());
451
- for (const [type, mimeType] of Object.entries(responseTypes)) {
452
- result[type] = async () => {
453
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
454
- ky.request.headers.set('accept', ky.request.headers.get('accept') || mimeType);
455
- const awaitedResult = await result;
456
- const response = awaitedResult.clone();
457
- if (type === 'json') {
458
- if (response.status === 204) {
459
- return '';
460
- }
461
- if (options.parseJson) {
462
- return options.parseJson(await response.text());
463
- }
464
- }
465
- return response[type]();
466
- };
467
- }
468
- return result;
469
- }
470
557
  _calculateRetryDelay(error) {
471
558
  this._retryCount++;
472
559
  if (this._retryCount < this._options.retry.limit && !(error instanceof TimeoutError)) {
@@ -483,7 +570,7 @@
483
570
  else {
484
571
  after *= 1000;
485
572
  }
486
- if (typeof this._options.retry.maxRetryAfter !== 'undefined' && after > this._options.retry.maxRetryAfter) {
573
+ if (this._options.retry.maxRetryAfter !== undefined && after > this._options.retry.maxRetryAfter) {
487
574
  return 0;
488
575
  }
489
576
  return after;
@@ -493,7 +580,7 @@
493
580
  }
494
581
  }
495
582
  const BACKOFF_FACTOR = 0.3;
496
- return BACKOFF_FACTOR * (2 ** (this._retryCount - 1)) * 1000;
583
+ return Math.min(this._options.retry.backoffLimit, BACKOFF_FACTOR * (2 ** (this._retryCount - 1)) * 1000);
497
584
  }
498
585
  return 0;
499
586
  }
@@ -506,12 +593,11 @@
506
593
  async _retry(fn) {
507
594
  try {
508
595
  return await fn();
509
- // eslint-disable-next-line @typescript-eslint/no-implicit-any-catch
510
596
  }
511
597
  catch (error) {
512
598
  const ms = Math.min(this._calculateRetryDelay(error), maxSafeTimeout);
513
599
  if (ms !== 0 && this._retryCount > 0) {
514
- await delay(ms);
600
+ await delay(ms, { signal: this._options.signal });
515
601
  for (const hook of this._options.hooks.beforeRetry) {
516
602
  // eslint-disable-next-line no-await-in-loop
517
603
  const hookResult = await hook({
@@ -551,6 +637,16 @@
551
637
  _stream(response, onDownloadProgress) {
552
638
  const totalBytes = Number(response.headers.get('content-length')) || 0;
553
639
  let transferredBytes = 0;
640
+ if (response.status === 204) {
641
+ if (onDownloadProgress) {
642
+ onDownloadProgress({ percent: 1, totalBytes, transferredBytes }, new Uint8Array());
643
+ }
644
+ return new globalThis.Response(null, {
645
+ status: response.status,
646
+ statusText: response.statusText,
647
+ headers: response.headers,
648
+ });
649
+ }
554
650
  return new globalThis.Response(new globalThis.ReadableStream({
555
651
  async start(controller) {
556
652
  const reader = response.body.getReader();
@@ -573,7 +669,11 @@
573
669
  }
574
670
  await read();
575
671
  },
576
- }));
672
+ }), {
673
+ status: response.status,
674
+ statusText: response.statusText,
675
+ headers: response.headers,
676
+ });
577
677
  }
578
678
  }
579
679
 
@@ -594,12 +694,14 @@
594
694
 
595
695
  exports.HTTPError = HTTPError;
596
696
  exports.TimeoutError = TimeoutError;
597
- exports["default"] = ky;
697
+ exports.default = ky;
598
698
 
599
699
  Object.defineProperty(exports, '__esModule', { value: true });
600
700
 
601
- }));
602
- } (ky$1, kyExports));
701
+ }));
702
+ } (ky$1, ky$1.exports));
703
+
704
+ var kyExports = ky$1.exports;
603
705
 
604
706
  const urlHttp = lightweight;
605
707
  const { flattie: flatten } = dist;
@@ -621,6 +723,7 @@
621
723
 
622
724
  const got = async (url, opts) => {
623
725
  try {
726
+ if (opts.retry > 0) opts.retry = opts.retry + 1;
624
727
  if (opts.timeout === undefined) opts.timeout = false;
625
728
  const response = await ky(url, opts);
626
729
  const body = await response.json();
@@ -651,10 +754,12 @@
651
754
  urlHttp,
652
755
  got,
653
756
  flatten,
654
- VERSION: '0.10.32'
757
+ VERSION: '0.10.34'
655
758
  });
656
759
 
657
- return browser;
760
+ var browser$1 = /*@__PURE__*/getDefaultExportFromCjs(browser);
761
+
762
+ return browser$1;
658
763
 
659
764
  }));
660
765
  //# sourceMappingURL=mql.js.map