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