@microlink/mql 0.13.5 → 0.13.7

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.
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.mql = {}));
5
- })(this, (function (exports) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
+ typeof define === 'function' && define.amd ? define(factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.mql = factory());
5
+ })(this, (function () { 'use strict';
6
6
 
7
7
  function getDefaultExportFromCjs (x) {
8
8
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -33,75 +33,55 @@
33
33
  return a;
34
34
  }
35
35
 
36
- var lightweight$2 = {exports: {}};
37
-
38
- const REGEX_HTTP_PROTOCOL = /^https?:\/\//i;
39
-
40
- var lightweight$1 = url => {
41
- try {
42
- const { href } = new URL(url);
43
- return REGEX_HTTP_PROTOCOL.test(href) && href
44
- } catch (err) {
45
- return false
46
- }
47
- };
36
+ var lightweight$1 = {exports: {}};
48
37
 
49
38
  var dist = {};
50
39
 
51
- function iter(output, nullish, sep, val, key) {
52
- var k, pfx = key ? (key + sep) : key;
53
-
54
- if (val == null) {
55
- if (nullish) output[key] = val;
56
- } else if (typeof val != 'object') {
57
- output[key] = val;
58
- } else if (Array.isArray(val)) {
59
- for (k=0; k < val.length; k++) {
60
- iter(output, nullish, sep, val[k], pfx + k);
61
- }
62
- } else {
63
- for (k in val) {
64
- iter(output, nullish, sep, val[k], pfx + k);
40
+ var hasRequiredDist;
41
+
42
+ function requireDist () {
43
+ if (hasRequiredDist) return dist;
44
+ hasRequiredDist = 1;
45
+ function iter(output, nullish, sep, val, key) {
46
+ var k, pfx = key ? (key + sep) : key;
47
+
48
+ if (val == null) {
49
+ if (nullish) output[key] = val;
50
+ } else if (typeof val != 'object') {
51
+ output[key] = val;
52
+ } else if (Array.isArray(val)) {
53
+ for (k=0; k < val.length; k++) {
54
+ iter(output, nullish, sep, val[k], pfx + k);
55
+ }
56
+ } else {
57
+ for (k in val) {
58
+ iter(output, nullish, sep, val[k], pfx + k);
59
+ }
65
60
  }
66
61
  }
67
- }
68
62
 
69
- function flattie(input, glue, toNull) {
70
- var output = {};
71
- if (typeof input == 'object') {
72
- iter(output, !!toNull, glue || '.', input, '');
63
+ function flattie(input, glue, toNull) {
64
+ var output = {};
65
+ if (typeof input == 'object') {
66
+ iter(output, !!toNull, glue || '.', input, '');
67
+ }
68
+ return output;
73
69
  }
74
- return output;
75
- }
76
70
 
77
- dist.flattie = flattie;
71
+ dist.flattie = flattie;
72
+ return dist;
73
+ }
78
74
 
79
- // eslint-lint-disable-next-line @typescript-eslint/naming-convention
80
75
  class HTTPError extends Error {
76
+ response;
77
+ request;
78
+ options;
81
79
  constructor(response, request, options) {
82
80
  const code = (response.status || response.status === 0) ? response.status : '';
83
81
  const title = response.statusText || '';
84
82
  const status = `${code} ${title}`.trim();
85
83
  const reason = status ? `status code ${status}` : 'an unknown error';
86
- super(`Request failed with ${reason}`);
87
- Object.defineProperty(this, "response", {
88
- enumerable: true,
89
- configurable: true,
90
- writable: true,
91
- value: void 0
92
- });
93
- Object.defineProperty(this, "request", {
94
- enumerable: true,
95
- configurable: true,
96
- writable: true,
97
- value: void 0
98
- });
99
- Object.defineProperty(this, "options", {
100
- enumerable: true,
101
- configurable: true,
102
- writable: true,
103
- value: void 0
104
- });
84
+ super(`Request failed with ${reason}: ${request.method} ${request.url}`);
105
85
  this.name = 'HTTPError';
106
86
  this.response = response;
107
87
  this.request = request;
@@ -110,25 +90,20 @@
110
90
  }
111
91
 
112
92
  class TimeoutError extends Error {
93
+ request;
113
94
  constructor(request) {
114
- super('Request timed out');
115
- Object.defineProperty(this, "request", {
116
- enumerable: true,
117
- configurable: true,
118
- writable: true,
119
- value: void 0
120
- });
95
+ super(`Request timed out: ${request.method} ${request.url}`);
121
96
  this.name = 'TimeoutError';
122
97
  this.request = request;
123
98
  }
124
99
  }
125
100
 
126
101
  // eslint-disable-next-line @typescript-eslint/ban-types
127
- const isObject$1 = (value) => value !== null && typeof value === 'object';
102
+ const isObject = (value) => value !== null && typeof value === 'object';
128
103
 
129
104
  const validateAndMerge = (...sources) => {
130
105
  for (const source of sources) {
131
- if ((!isObject$1(source) || Array.isArray(source)) && source !== undefined) {
106
+ if ((!isObject(source) || Array.isArray(source)) && source !== undefined) {
132
107
  throw new TypeError('The `options` argument must be an object');
133
108
  }
134
109
  }
@@ -148,10 +123,22 @@
148
123
  }
149
124
  return result;
150
125
  };
126
+ function newHookValue(original, incoming, property) {
127
+ return (Object.hasOwn(incoming, property) && incoming[property] === undefined)
128
+ ? []
129
+ : deepMerge(original[property] ?? [], incoming[property] ?? []);
130
+ }
131
+ const mergeHooks = (original = {}, incoming = {}) => ({
132
+ beforeRequest: newHookValue(original, incoming, 'beforeRequest'),
133
+ beforeRetry: newHookValue(original, incoming, 'beforeRetry'),
134
+ afterResponse: newHookValue(original, incoming, 'afterResponse'),
135
+ beforeError: newHookValue(original, incoming, 'beforeError'),
136
+ });
151
137
  // TODO: Make this strongly-typed (no `any`).
152
138
  const deepMerge = (...sources) => {
153
139
  let returnValue = {};
154
140
  let headers = {};
141
+ let hooks = {};
155
142
  for (const source of sources) {
156
143
  if (Array.isArray(source)) {
157
144
  if (!Array.isArray(returnValue)) {
@@ -159,14 +146,18 @@
159
146
  }
160
147
  returnValue = [...returnValue, ...source];
161
148
  }
162
- else if (isObject$1(source)) {
149
+ else if (isObject(source)) {
163
150
  for (let [key, value] of Object.entries(source)) {
164
- if (isObject$1(value) && key in returnValue) {
151
+ if (isObject(value) && key in returnValue) {
165
152
  value = deepMerge(returnValue[key], value);
166
153
  }
167
154
  returnValue = { ...returnValue, [key]: value };
168
155
  }
169
- if (isObject$1(source.headers)) {
156
+ if (isObject(source.hooks)) {
157
+ hooks = mergeHooks(hooks, source.hooks);
158
+ returnValue.hooks = hooks;
159
+ }
160
+ if (isObject(source.headers)) {
170
161
  headers = mergeHeaders(headers, source.headers);
171
162
  returnValue.headers = headers;
172
163
  }
@@ -181,15 +172,24 @@
181
172
  const supportsReadableStream = typeof globalThis.ReadableStream === 'function';
182
173
  const supportsRequest = typeof globalThis.Request === 'function';
183
174
  if (supportsReadableStream && supportsRequest) {
184
- hasContentType = new globalThis.Request('https://empty.invalid', {
185
- body: new globalThis.ReadableStream(),
186
- method: 'POST',
187
- // @ts-expect-error - Types are outdated.
188
- get duplex() {
189
- duplexAccessed = true;
190
- return 'half';
191
- },
192
- }).headers.has('Content-Type');
175
+ try {
176
+ hasContentType = new globalThis.Request('https://empty.invalid', {
177
+ body: new globalThis.ReadableStream(),
178
+ method: 'POST',
179
+ // @ts-expect-error - Types are outdated.
180
+ get duplex() {
181
+ duplexAccessed = true;
182
+ return 'half';
183
+ },
184
+ }).headers.has('Content-Type');
185
+ }
186
+ catch (error) {
187
+ // QQBrowser on iOS throws "unsupported BodyInit type" error (see issue #581)
188
+ if (error instanceof Error && error.message === 'unsupported BodyInit type') {
189
+ return false;
190
+ }
191
+ throw error;
192
+ }
193
193
  }
194
194
  return duplexAccessed && !hasContentType;
195
195
  })();
@@ -205,11 +205,12 @@
205
205
  blob: '*/*',
206
206
  };
207
207
  // The maximum value of a 32bit int (see issue #117)
208
- const maxSafeTimeout = 2147483647;
208
+ const maxSafeTimeout = 2_147_483_647;
209
209
  const stop = Symbol('stop');
210
210
  const kyOptionKeys = {
211
211
  json: true,
212
212
  parseJson: true,
213
+ stringifyJson: true,
213
214
  searchParams: true,
214
215
  prefixUrl: true,
215
216
  retry: true,
@@ -235,6 +236,7 @@
235
236
  window: true,
236
237
  dispatcher: true,
237
238
  duplex: true,
239
+ priority: true,
238
240
  };
239
241
 
240
242
  const normalizeRequestMethod = (input) => requestMethods.includes(input) ? input.toUpperCase() : input;
@@ -266,7 +268,6 @@
266
268
  return {
267
269
  ...defaultRetryOptions,
268
270
  ...retry,
269
- afterStatusCodes: retryAfterStatusCodes,
270
271
  };
271
272
  };
272
273
 
@@ -382,45 +383,18 @@
382
383
  }
383
384
  return result;
384
385
  }
386
+ request;
387
+ abortController;
388
+ _retryCount = 0;
389
+ _input;
390
+ _options;
385
391
  // eslint-disable-next-line complexity
386
392
  constructor(input, options = {}) {
387
- Object.defineProperty(this, "request", {
388
- enumerable: true,
389
- configurable: true,
390
- writable: true,
391
- value: void 0
392
- });
393
- Object.defineProperty(this, "abortController", {
394
- enumerable: true,
395
- configurable: true,
396
- writable: true,
397
- value: void 0
398
- });
399
- Object.defineProperty(this, "_retryCount", {
400
- enumerable: true,
401
- configurable: true,
402
- writable: true,
403
- value: 0
404
- });
405
- Object.defineProperty(this, "_input", {
406
- enumerable: true,
407
- configurable: true,
408
- writable: true,
409
- value: void 0
410
- });
411
- Object.defineProperty(this, "_options", {
412
- enumerable: true,
413
- configurable: true,
414
- writable: true,
415
- value: void 0
416
- });
417
393
  this._input = input;
418
- const isCredentialsSupported = 'credentials' in Request.prototype;
419
394
  this._options = {
420
- credentials: isCredentialsSupported ? this._input.credentials : undefined,
421
395
  ...options,
422
396
  headers: mergeHeaders(this._input.headers, options.headers),
423
- hooks: deepMerge({
397
+ hooks: mergeHooks({
424
398
  beforeRequest: [],
425
399
  beforeRetry: [],
426
400
  beforeError: [],
@@ -431,7 +405,7 @@
431
405
  prefixUrl: String(options.prefixUrl || ''),
432
406
  retry: normalizeRetryOptions(options.retry),
433
407
  throwHttpErrors: options.throwHttpErrors !== false,
434
- timeout: options.timeout ?? 10000,
408
+ timeout: options.timeout ?? 10_000,
435
409
  fetch: options.fetch ?? globalThis.fetch.bind(globalThis),
436
410
  };
437
411
  if (typeof this._input !== 'string' && !(this._input instanceof URL || this._input instanceof globalThis.Request)) {
@@ -448,18 +422,20 @@
448
422
  }
449
423
  if (supportsAbortController) {
450
424
  this.abortController = new globalThis.AbortController();
451
- if (this._options.signal) {
452
- const originalSignal = this._options.signal;
453
- this._options.signal.addEventListener('abort', () => {
454
- this.abortController.abort(originalSignal.reason);
455
- });
456
- }
425
+ const originalSignal = this._options.signal ?? this._input.signal;
426
+ originalSignal?.addEventListener('abort', () => {
427
+ this.abortController.abort(originalSignal.reason);
428
+ });
457
429
  this._options.signal = this.abortController.signal;
458
430
  }
459
431
  if (supportsRequestStreams) {
460
432
  // @ts-expect-error - Types are outdated.
461
433
  this._options.duplex = 'half';
462
434
  }
435
+ if (this._options.json !== undefined) {
436
+ this._options.body = this._options.stringifyJson?.(this._options.json) ?? JSON.stringify(this._options.json);
437
+ this._options.headers.set('content-type', this._options.headers.get('content-type') ?? 'application/json');
438
+ }
463
439
  this.request = new globalThis.Request(this._input, this._options);
464
440
  if (this._options.searchParams) {
465
441
  // eslint-disable-next-line unicorn/prevent-abbreviations
@@ -477,41 +453,38 @@
477
453
  // The spread of `this.request` is required as otherwise it misses the `duplex` option for some reason and throws.
478
454
  this.request = new globalThis.Request(new globalThis.Request(url, { ...this.request }), this._options);
479
455
  }
480
- if (this._options.json !== undefined) {
481
- this._options.body = JSON.stringify(this._options.json);
482
- this.request.headers.set('content-type', this._options.headers.get('content-type') ?? 'application/json');
483
- this.request = new globalThis.Request(this.request, { body: this._options.body });
484
- }
485
456
  }
486
457
  _calculateRetryDelay(error) {
487
458
  this._retryCount++;
488
- if (this._retryCount <= this._options.retry.limit && !(error instanceof TimeoutError)) {
489
- if (error instanceof HTTPError) {
490
- if (!this._options.retry.statusCodes.includes(error.response.status)) {
491
- return 0;
492
- }
493
- const retryAfter = error.response.headers.get('Retry-After');
494
- if (retryAfter && this._options.retry.afterStatusCodes.includes(error.response.status)) {
495
- let after = Number(retryAfter);
496
- if (Number.isNaN(after)) {
497
- after = Date.parse(retryAfter) - Date.now();
498
- }
499
- else {
500
- after *= 1000;
501
- }
502
- if (this._options.retry.maxRetryAfter !== undefined && after > this._options.retry.maxRetryAfter) {
503
- return 0;
504
- }
505
- return after;
459
+ if (this._retryCount > this._options.retry.limit || error instanceof TimeoutError) {
460
+ throw error;
461
+ }
462
+ if (error instanceof HTTPError) {
463
+ if (!this._options.retry.statusCodes.includes(error.response.status)) {
464
+ throw error;
465
+ }
466
+ const retryAfter = error.response.headers.get('Retry-After')
467
+ ?? error.response.headers.get('RateLimit-Reset')
468
+ ?? error.response.headers.get('X-RateLimit-Reset') // GitHub
469
+ ?? error.response.headers.get('X-Rate-Limit-Reset'); // Twitter
470
+ if (retryAfter && this._options.retry.afterStatusCodes.includes(error.response.status)) {
471
+ let after = Number(retryAfter) * 1000;
472
+ if (Number.isNaN(after)) {
473
+ after = Date.parse(retryAfter) - Date.now();
506
474
  }
507
- if (error.response.status === 413) {
508
- return 0;
475
+ else if (after >= Date.parse('2024-01-01')) {
476
+ // A large number is treated as a timestamp (fixed threshold protects against clock skew)
477
+ after -= Date.now();
509
478
  }
479
+ const max = this._options.retry.maxRetryAfter ?? after;
480
+ return after < max ? after : max;
481
+ }
482
+ if (error.response.status === 413) {
483
+ throw error;
510
484
  }
511
- const retryDelay = this._options.retry.delay(this._retryCount);
512
- return Math.min(this._options.retry.backoffLimit, retryDelay);
513
485
  }
514
- return 0;
486
+ const retryDelay = this._options.retry.delay(this._retryCount);
487
+ return Math.min(this._options.retry.backoffLimit, retryDelay);
515
488
  }
516
489
  _decorateResponse(response) {
517
490
  if (this._options.parseJson) {
@@ -525,24 +498,24 @@
525
498
  }
526
499
  catch (error) {
527
500
  const ms = Math.min(this._calculateRetryDelay(error), maxSafeTimeout);
528
- if (ms !== 0 && this._retryCount > 0) {
529
- await delay(ms, { signal: this._options.signal });
530
- for (const hook of this._options.hooks.beforeRetry) {
531
- // eslint-disable-next-line no-await-in-loop
532
- const hookResult = await hook({
533
- request: this.request,
534
- options: this._options,
535
- error: error,
536
- retryCount: this._retryCount,
537
- });
538
- // If `stop` is returned from the hook, the retry process is stopped
539
- if (hookResult === stop) {
540
- return;
541
- }
501
+ if (this._retryCount < 1) {
502
+ throw error;
503
+ }
504
+ await delay(ms, { signal: this._options.signal });
505
+ for (const hook of this._options.hooks.beforeRetry) {
506
+ // eslint-disable-next-line no-await-in-loop
507
+ const hookResult = await hook({
508
+ request: this.request,
509
+ options: this._options,
510
+ error: error,
511
+ retryCount: this._retryCount,
512
+ });
513
+ // If `stop` is returned from the hook, the retry process is stopped
514
+ if (hookResult === stop) {
515
+ return;
542
516
  }
543
- return this._retry(function_);
544
517
  }
545
- throw error;
518
+ return this._retry(function_);
546
519
  }
547
520
  }
548
521
  async _fetch() {
@@ -558,10 +531,13 @@
558
531
  }
559
532
  }
560
533
  const nonRequestOptions = findUnknownOptions(this.request, this._options);
534
+ // Cloning is done here to prepare in advance for retries
535
+ const mainRequest = this.request;
536
+ this.request = mainRequest.clone();
561
537
  if (this._options.timeout === false) {
562
- return this._options.fetch(this.request.clone(), nonRequestOptions);
538
+ return this._options.fetch(mainRequest, nonRequestOptions);
563
539
  }
564
- return timeout(this.request.clone(), nonRequestOptions, this.abortController, this._options);
540
+ return timeout(mainRequest, nonRequestOptions, this.abortController, this._options);
565
541
  }
566
542
  /* istanbul ignore next */
567
543
  _stream(response, onDownloadProgress) {
@@ -616,235 +592,252 @@
616
592
  ky[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, { method }));
617
593
  }
618
594
  ky.create = (newDefaults) => createInstance(validateAndMerge(newDefaults));
619
- ky.extend = (newDefaults) => createInstance(validateAndMerge(defaults, newDefaults));
595
+ ky.extend = (newDefaults) => {
596
+ if (typeof newDefaults === 'function') {
597
+ newDefaults = newDefaults(defaults ?? {});
598
+ }
599
+ return createInstance(validateAndMerge(defaults, newDefaults));
600
+ };
620
601
  ky.stop = stop;
621
602
  return ky;
622
603
  };
623
- const ky$1 = createInstance();
604
+ const ky = createInstance();
624
605
 
625
606
  var distribution = /*#__PURE__*/Object.freeze({
626
607
  __proto__: null,
627
608
  HTTPError: HTTPError,
628
609
  TimeoutError: TimeoutError,
629
- default: ky$1
610
+ default: ky
630
611
  });
631
612
 
632
- var require$$2 = /*@__PURE__*/getAugmentedNamespace(distribution);
633
-
634
- const ENDPOINT = {
635
- FREE: 'https://api.microlink.io/',
636
- PRO: 'https://pro.microlink.io/'
637
- };
638
-
639
- const isObject = input => input !== null && typeof input === 'object';
640
-
641
- const isBuffer = input =>
642
- input != null &&
643
- input.constructor != null &&
644
- typeof input.constructor.isBuffer === 'function' &&
645
- input.constructor.isBuffer(input);
613
+ var require$$1 = /*@__PURE__*/getAugmentedNamespace(distribution);
614
+
615
+ var factory_1;
616
+ var hasRequiredFactory;
617
+
618
+ function requireFactory () {
619
+ if (hasRequiredFactory) return factory_1;
620
+ hasRequiredFactory = 1;
621
+ const ENDPOINT = {
622
+ FREE: 'https://api.microlink.io/',
623
+ PRO: 'https://pro.microlink.io/'
624
+ };
625
+
626
+ const isObject = input => input !== null && typeof input === 'object';
627
+
628
+ const isBuffer = input =>
629
+ input != null &&
630
+ input.constructor != null &&
631
+ typeof input.constructor.isBuffer === 'function' &&
632
+ input.constructor.isBuffer(input);
633
+
634
+ const parseBody = (input, error, url) => {
635
+ try {
636
+ return JSON.parse(input)
637
+ } catch (_) {
638
+ const message = input || error.message;
639
+
640
+ return {
641
+ status: 'error',
642
+ data: { url: message },
643
+ more: 'https://microlink.io/efatalclient',
644
+ code: 'EFATALCLIENT',
645
+ message,
646
+ url
647
+ }
648
+ }
649
+ };
650
+
651
+ const isURL = url => {
652
+ try {
653
+ return /^https?:\/\//i.test(new URL(url).href)
654
+ } catch (_) {
655
+ return false
656
+ }
657
+ };
658
+
659
+ const factory = streamResponseType => ({
660
+ VERSION,
661
+ MicrolinkError,
662
+ got,
663
+ flatten
664
+ }) => {
665
+ const assertUrl = (url = '') => {
666
+ if (!isURL(url)) {
667
+ const message = `The \`url\` as \`${url}\` is not valid. Ensure it has protocol (http or https) and hostname.`;
668
+ throw new MicrolinkError({
669
+ status: 'fail',
670
+ data: { url: message },
671
+ more: 'https://microlink.io/einvalurlclient',
672
+ code: 'EINVALURLCLIENT',
673
+ message,
674
+ url
675
+ })
676
+ }
677
+ };
678
+
679
+ const mapRules = rules => {
680
+ if (!isObject(rules)) return
681
+ const flatRules = flatten(rules);
682
+ return Object.keys(flatRules).reduce((acc, key) => {
683
+ acc[`data.${key}`] = flatRules[key].toString();
684
+ return acc
685
+ }, {})
686
+ };
687
+
688
+ const fetchFromApi = async (apiUrl, opts = {}) => {
689
+ try {
690
+ const response = await got(apiUrl, opts);
691
+ return opts.responseType === streamResponseType
692
+ ? response
693
+ : { ...response.body, response }
694
+ } catch (error) {
695
+ const { response = {} } = error;
696
+ const {
697
+ statusCode,
698
+ body: rawBody,
699
+ headers = {},
700
+ url: uri = apiUrl
701
+ } = response;
702
+ const isBodyBuffer = isBuffer(rawBody);
703
+
704
+ const body =
705
+ isObject(rawBody) && !isBodyBuffer
706
+ ? rawBody
707
+ : parseBody(isBodyBuffer ? rawBody.toString() : rawBody, error, uri);
708
+
709
+ throw new MicrolinkError({
710
+ ...body,
711
+ message: body.message,
712
+ url: uri,
713
+ statusCode,
714
+ headers
715
+ })
716
+ }
717
+ };
718
+
719
+ const getApiUrl = (
720
+ url,
721
+ { data, apiKey, endpoint, retry, cache, ...opts } = {},
722
+ { responseType = 'json', headers: gotHeaders, ...gotOpts } = {}
723
+ ) => {
724
+ const isPro = !!apiKey;
725
+ const apiEndpoint = endpoint || ENDPOINT[isPro ? 'PRO' : 'FREE'];
726
+
727
+ const apiUrl = `${apiEndpoint}?${new URLSearchParams({
728
+ url,
729
+ ...mapRules(data),
730
+ ...flatten(opts)
731
+ }).toString()}`;
732
+
733
+ const headers = isPro
734
+ ? { ...gotHeaders, 'x-api-key': apiKey }
735
+ : { ...gotHeaders };
736
+
737
+ if (opts.stream) {
738
+ responseType = streamResponseType;
739
+ }
740
+ return [apiUrl, { ...gotOpts, responseType, cache, retry, headers }]
741
+ };
742
+
743
+ const createMql = defaultOpts => async (url, opts, gotOpts) => {
744
+ assertUrl(url);
745
+ const [apiUrl, fetchOpts] = getApiUrl(url, opts, {
746
+ ...defaultOpts,
747
+ ...gotOpts
748
+ });
749
+ return fetchFromApi(apiUrl, fetchOpts)
750
+ };
751
+
752
+ const mql = createMql();
753
+ mql.extend = createMql;
754
+ mql.MicrolinkError = MicrolinkError;
755
+ mql.getApiUrl = getApiUrl;
756
+ mql.fetchFromApi = fetchFromApi;
757
+ mql.mapRules = mapRules;
758
+ mql.version = VERSION;
759
+ mql.stream = got.stream;
760
+
761
+ return mql
762
+ };
763
+
764
+ factory_1 = factory;
765
+ return factory_1;
766
+ }
646
767
 
647
- const parseBody = (input, error, url) => {
648
- try {
649
- return JSON.parse(input)
650
- } catch (_) {
651
- const message = input || error.message;
768
+ var hasRequiredLightweight;
652
769
 
653
- return {
654
- status: 'error',
655
- data: { url: message },
656
- more: 'https://microlink.io/efatalclient',
657
- code: 'EFATALCLIENT',
658
- message,
659
- url
660
- }
661
- }
662
- };
770
+ function requireLightweight () {
771
+ if (hasRequiredLightweight) return lightweight$1.exports;
772
+ hasRequiredLightweight = 1;
663
773
 
664
- const factory$1 = streamResponseType => ({
665
- VERSION,
666
- MicrolinkError,
667
- urlHttp,
668
- got,
669
- flatten
670
- }) => {
671
- const assertUrl = (url = '') => {
672
- if (!urlHttp(url)) {
673
- const message = `The \`url\` as \`${url}\` is not valid. Ensure it has protocol (http or https) and hostname.`;
674
- throw new MicrolinkError({
675
- status: 'fail',
676
- data: { url: message },
677
- more: 'https://microlink.io/einvalurlclient',
678
- code: 'EINVALURLCLIENT',
679
- message,
680
- url
681
- })
682
- }
683
- };
684
-
685
- const mapRules = rules => {
686
- if (!isObject(rules)) return
687
- const flatRules = flatten(rules);
688
- return Object.keys(flatRules).reduce((acc, key) => {
689
- acc[`data.${key}`] = flatRules[key].toString();
690
- return acc
691
- }, {})
692
- };
693
-
694
- const fetchFromApi = async (apiUrl, opts = {}) => {
695
- try {
696
- const response = await got(apiUrl, opts);
697
- return opts.responseType === streamResponseType
698
- ? response
699
- : { ...response.body, response }
700
- } catch (error) {
701
- const { response = {} } = error;
702
- const {
703
- statusCode,
704
- body: rawBody,
705
- headers = {},
706
- url: uri = apiUrl
707
- } = response;
708
- const isBodyBuffer = isBuffer(rawBody);
709
-
710
- const body =
711
- isObject(rawBody) && !isBodyBuffer
712
- ? rawBody
713
- : parseBody(isBodyBuffer ? rawBody.toString() : rawBody, error, uri);
714
-
715
- throw new MicrolinkError({
716
- ...body,
717
- message: body.message,
718
- url: uri,
719
- statusCode,
720
- headers
721
- })
722
- }
723
- };
724
-
725
- const getApiUrl = (
726
- url,
727
- { data, apiKey, endpoint, retry, cache, ...opts } = {},
728
- { responseType = 'json', headers: gotHeaders, ...gotOpts } = {}
729
- ) => {
730
- const isPro = !!apiKey;
731
- const apiEndpoint = endpoint || ENDPOINT[isPro ? 'PRO' : 'FREE'];
732
-
733
- const apiUrl = `${apiEndpoint}?${new URLSearchParams({
734
- url,
735
- ...mapRules(data),
736
- ...flatten(opts)
737
- }).toString()}`;
738
-
739
- const headers = isPro
740
- ? { ...gotHeaders, 'x-api-key': apiKey }
741
- : { ...gotHeaders };
742
-
743
- if (opts.stream) {
744
- responseType = streamResponseType;
745
- }
746
- return [apiUrl, { ...gotOpts, responseType, cache, retry, headers }]
747
- };
748
-
749
- const createMql = defaultOpts => async (url, opts, gotOpts) => {
750
- assertUrl(url);
751
- const [apiUrl, fetchOpts] = getApiUrl(url, opts, {
752
- ...defaultOpts,
753
- ...gotOpts
754
- });
755
- return fetchFromApi(apiUrl, fetchOpts)
756
- };
757
-
758
- const mql = createMql();
759
- mql.extend = createMql;
760
- mql.MicrolinkError = MicrolinkError;
761
- mql.getApiUrl = getApiUrl;
762
- mql.fetchFromApi = fetchFromApi;
763
- mql.mapRules = mapRules;
764
- mql.version = VERSION;
765
- mql.stream = got.stream;
766
-
767
- return mql
768
- };
774
+ const { flattie: flatten } = requireDist();
775
+ const { default: ky } = require$$1;
769
776
 
770
- var factory_1 = factory$1;
777
+ const factory = requireFactory()('arrayBuffer');
771
778
 
772
- const urlHttp = lightweight$1;
773
- const { flattie: flatten } = dist;
774
- const { default: ky } = require$$2;
779
+ class MicrolinkError extends Error {
780
+ constructor (props) {
781
+ super();
782
+ this.name = 'MicrolinkError';
783
+ Object.assign(this, props);
784
+ this.description = this.message;
785
+ this.message = this.code
786
+ ? `${this.code}, ${this.description}`
787
+ : this.description;
788
+ }
789
+ }
775
790
 
776
- const factory = factory_1('arrayBuffer');
791
+ const got = async (url, { responseType, ...opts }) => {
792
+ try {
793
+ if (opts.timeout === undefined) opts.timeout = false;
794
+ const response = await ky(url, opts);
795
+ const body = await response[responseType]();
796
+ const { headers, status: statusCode } = response;
797
+ return { url: response.url, body, headers, statusCode }
798
+ } catch (error) {
799
+ if (error.response) {
800
+ const { response } = error;
801
+ error.response = {
802
+ ...response,
803
+ headers: Array.from(response.headers.entries()).reduce(
804
+ (acc, [key, value]) => {
805
+ acc[key] = value;
806
+ return acc
807
+ },
808
+ {}
809
+ ),
810
+ statusCode: response.status,
811
+ body: await response.text()
812
+ };
813
+ }
814
+ throw error
815
+ }
816
+ };
817
+
818
+ got.stream = (...args) => ky(...args).then(res => res.body);
819
+
820
+ const mql = factory({
821
+ MicrolinkError,
822
+ got,
823
+ flatten,
824
+ VERSION: '0.13.7'
825
+ });
777
826
 
778
- class MicrolinkError extends Error {
779
- constructor (props) {
780
- super();
781
- this.name = 'MicrolinkError';
782
- Object.assign(this, props);
783
- this.description = this.message;
784
- this.message = this.code
785
- ? `${this.code}, ${this.description}`
786
- : this.description;
787
- }
827
+ lightweight$1.exports = mql;
828
+ lightweight$1.exports.arrayBuffer = mql.extend({ responseType: 'arrayBuffer' });
829
+ lightweight$1.exports.extend = mql.extend;
830
+ lightweight$1.exports.fetchFromApi = mql.fetchFromApi;
831
+ lightweight$1.exports.getApiUrl = mql.getApiUrl;
832
+ lightweight$1.exports.mapRules = mql.mapRules;
833
+ lightweight$1.exports.MicrolinkError = mql.MicrolinkError;
834
+ lightweight$1.exports.version = mql.version;
835
+ return lightweight$1.exports;
788
836
  }
789
837
 
790
- const got = async (url, { responseType, ...opts }) => {
791
- try {
792
- if (opts.timeout === undefined) opts.timeout = false;
793
- const response = await ky(url, opts);
794
- const body = await response[responseType]();
795
- const { headers, status: statusCode } = response;
796
- return { url: response.url, body, headers, statusCode }
797
- } catch (error) {
798
- if (error.response) {
799
- const { response } = error;
800
- error.response = {
801
- ...response,
802
- headers: Array.from(response.headers.entries()).reduce(
803
- (acc, [key, value]) => {
804
- acc[key] = value;
805
- return acc
806
- },
807
- {}
808
- ),
809
- statusCode: response.status,
810
- body: await response.text()
811
- };
812
- }
813
- throw error
814
- }
815
- };
816
-
817
- got.stream = (...args) => ky(...args).then(res => res.body);
818
-
819
- const mql = factory({
820
- MicrolinkError,
821
- urlHttp,
822
- got,
823
- flatten,
824
- VERSION: '0.13.5'
825
- });
826
-
827
- lightweight$2.exports = mql;
828
- var arrayBuffer = lightweight$2.exports.arrayBuffer = mql.extend({ responseType: 'arrayBuffer' });
829
- var extend = lightweight$2.exports.extend = mql.extend;
830
- var fetchFromApi = lightweight$2.exports.fetchFromApi = mql.fetchFromApi;
831
- var getApiUrl = lightweight$2.exports.getApiUrl = mql.getApiUrl;
832
- var mapRules = lightweight$2.exports.mapRules = mql.mapRules;
833
- var MicrolinkError_1 = lightweight$2.exports.MicrolinkError = mql.MicrolinkError;
834
- var version = lightweight$2.exports.version = mql.version;
835
-
836
- var lightweightExports = lightweight$2.exports;
838
+ var lightweightExports = requireLightweight();
837
839
  var lightweight = /*@__PURE__*/getDefaultExportFromCjs(lightweightExports);
838
840
 
839
- exports.MicrolinkError = MicrolinkError_1;
840
- exports.arrayBuffer = arrayBuffer;
841
- exports.default = lightweight;
842
- exports.extend = extend;
843
- exports.fetchFromApi = fetchFromApi;
844
- exports.getApiUrl = getApiUrl;
845
- exports.mapRules = mapRules;
846
- exports.version = version;
847
-
848
- Object.defineProperty(exports, '__esModule', { value: true });
841
+ return lightweight;
849
842
 
850
843
  }));