@microlink/mql 0.11.0-2 → 0.11.0-3

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@microlink/mql",
3
3
  "description": "Microlink Query Language. The official HTTP client to interact with Microlink API for Node.js, browsers & Deno.",
4
4
  "homepage": "https://microlink.io/mql",
5
- "version": "0.11.0-2",
5
+ "version": "0.11.0-3",
6
6
  "types": "index.d.ts",
7
7
  "browser": "src/lightweight.js",
8
8
  "umd:main": "dist/mql.js",
@@ -1,773 +1,2 @@
1
- function getDefaultExportFromCjs (x) {
2
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x.default : x
3
- }
4
-
5
- function getAugmentedNamespace (n) {
6
- if (n.__esModule) return n
7
- const f = n.default
8
- if (typeof f === 'function') {
9
- var a = function a () {
10
- if (this instanceof a) {
11
- return Reflect.construct(f, arguments, this.constructor)
12
- }
13
- return f.apply(this, arguments)
14
- }
15
- a.prototype = f.prototype
16
- } else a = {}
17
- Object.defineProperty(a, '__esModule', { value: true })
18
- Object.keys(n).forEach(function (k) {
19
- const d = Object.getOwnPropertyDescriptor(n, k)
20
- Object.defineProperty(a, k, d.get
21
- ? d
22
- : {
23
- enumerable: true,
24
- get: function () {
25
- return n[k]
26
- }
27
- })
28
- })
29
- return a
30
- }
31
-
32
- const REGEX_HTTP_PROTOCOL = /^https?:\/\//i
33
-
34
- const lightweight = 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
- }
42
-
43
- const dist = {}
44
-
45
- function iter (output, nullish, sep, val, key) {
46
- let k; const 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
- }
60
- }
61
- }
62
-
63
- function flattie (input, glue, toNull) {
64
- const output = {}
65
- if (typeof input === 'object') {
66
- iter(output, !!toNull, glue || '.', input, '')
67
- }
68
- return output
69
- }
70
-
71
- dist.flattie = flattie
72
-
73
- const ENDPOINT = {
74
- FREE: 'https://api.microlink.io/',
75
- PRO: 'https://pro.microlink.io/'
76
- }
77
-
78
- const isObject$1 = input => input !== null && typeof input === 'object'
79
-
80
- const isBuffer = input =>
81
- input != null &&
82
- input.constructor != null &&
83
- typeof input.constructor.isBuffer === 'function' &&
84
- input.constructor.isBuffer(input)
85
-
86
- const parseBody = (input, error, url) => {
87
- try {
88
- return JSON.parse(input)
89
- } catch (_) {
90
- const message = input || error.message
91
-
92
- return {
93
- status: 'error',
94
- data: { url: message },
95
- more: 'https://microlink.io/efatalclient',
96
- code: 'EFATALCLIENT',
97
- message,
98
- url
99
- }
100
- }
101
- }
102
-
103
- const factory$1 = ({ VERSION, MicrolinkError, urlHttp, got, flatten }) => {
104
- const assertUrl = (url = '') => {
105
- if (!urlHttp(url)) {
106
- const message = `The \`url\` as \`${url}\` is not valid. Ensure it has protocol (http or https) and hostname.`
107
- throw new MicrolinkError({
108
- status: 'fail',
109
- data: { url: message },
110
- more: 'https://microlink.io/docs/api/api-parameters/url',
111
- code: 'EINVALURLCLIENT',
112
- message,
113
- url
114
- })
115
- }
116
- }
117
-
118
- const mapRules = rules => {
119
- if (!isObject$1(rules)) return
120
- const flatRules = flatten(rules)
121
- return Object.keys(flatRules).reduce((acc, key) => {
122
- acc[`data.${key}`] = flatRules[key].toString()
123
- return acc
124
- }, {})
125
- }
126
-
127
- const fetchFromApi = async (apiUrl, opts = {}) => {
128
- try {
129
- const response = await got(apiUrl, opts)
130
- return opts.responseType === 'buffer'
131
- ? { body: response.body, response }
132
- : { ...response.body, response }
133
- } catch (err) {
134
- const { response = {} } = err
135
- const {
136
- statusCode,
137
- body: rawBody,
138
- headers = {},
139
- url: uri = apiUrl
140
- } = response
141
- const isBodyBuffer = isBuffer(rawBody)
142
-
143
- const body =
144
- isObject$1(rawBody) && !isBodyBuffer
145
- ? rawBody
146
- : parseBody(isBodyBuffer ? rawBody.toString() : rawBody, err, uri)
147
-
148
- throw new MicrolinkError({
149
- ...body,
150
- message: body.message,
151
- url: uri,
152
- statusCode,
153
- headers
154
- })
155
- }
156
- }
157
-
158
- const getApiUrl = (
159
- url,
160
- { data, apiKey, endpoint, retry, cache, ...opts } = {},
161
- { responseType = 'json', headers: gotHeaders, ...gotOpts } = {}
162
- ) => {
163
- const isPro = !!apiKey
164
- const apiEndpoint = endpoint || ENDPOINT[isPro ? 'PRO' : 'FREE']
165
-
166
- const apiUrl = `${apiEndpoint}?${new URLSearchParams({
167
- url,
168
- ...mapRules(data),
169
- ...flatten(opts)
170
- }).toString()}`
171
-
172
- const headers = isPro
173
- ? { ...gotHeaders, 'x-api-key': apiKey }
174
- : { ...gotHeaders }
175
- return [apiUrl, { ...gotOpts, responseType, cache, retry, headers }]
176
- }
177
-
178
- const createMql = defaultOpts => async (url, opts, gotOpts) => {
179
- assertUrl(url)
180
- const [apiUrl, fetchOpts] = getApiUrl(url, opts, {
181
- ...defaultOpts,
182
- ...gotOpts
183
- })
184
- return fetchFromApi(apiUrl, fetchOpts)
185
- }
186
-
187
- const mql = createMql()
188
- mql.MicrolinkError = MicrolinkError
189
- mql.getApiUrl = getApiUrl
190
- mql.fetchFromApi = fetchFromApi
191
- mql.mapRules = mapRules
192
- mql.version = VERSION
193
- mql.stream = got.stream
194
- mql.buffer = createMql({ responseType: 'buffer' })
195
-
196
- return mql
197
- }
198
-
199
- const factory_1 = factory$1
200
-
201
- // eslint-lint-disable-next-line @typescript-eslint/naming-convention
202
- class HTTPError extends Error {
203
- constructor (response, request, options) {
204
- const code = (response.status || response.status === 0) ? response.status : ''
205
- const title = response.statusText || ''
206
- const status = `${code} ${title}`.trim()
207
- const reason = status ? `status code ${status}` : 'an unknown error'
208
- super(`Request failed with ${reason}`)
209
- Object.defineProperty(this, 'response', {
210
- enumerable: true,
211
- configurable: true,
212
- writable: true,
213
- value: void 0
214
- })
215
- Object.defineProperty(this, 'request', {
216
- enumerable: true,
217
- configurable: true,
218
- writable: true,
219
- value: void 0
220
- })
221
- Object.defineProperty(this, 'options', {
222
- enumerable: true,
223
- configurable: true,
224
- writable: true,
225
- value: void 0
226
- })
227
- this.name = 'HTTPError'
228
- this.response = response
229
- this.request = request
230
- this.options = options
231
- }
232
- }
233
-
234
- class TimeoutError extends Error {
235
- constructor (request) {
236
- super('Request timed out')
237
- Object.defineProperty(this, 'request', {
238
- enumerable: true,
239
- configurable: true,
240
- writable: true,
241
- value: void 0
242
- })
243
- this.name = 'TimeoutError'
244
- this.request = request
245
- }
246
- }
247
-
248
- // eslint-disable-next-line @typescript-eslint/ban-types
249
- const isObject = (value) => value !== null && typeof value === 'object'
250
-
251
- const validateAndMerge = (...sources) => {
252
- for (const source of sources) {
253
- if ((!isObject(source) || Array.isArray(source)) && source !== undefined) {
254
- throw new TypeError('The `options` argument must be an object')
255
- }
256
- }
257
- return deepMerge({}, ...sources)
258
- }
259
- const mergeHeaders = (source1 = {}, source2 = {}) => {
260
- const result = new globalThis.Headers(source1)
261
- const isHeadersInstance = source2 instanceof globalThis.Headers
262
- const source = new globalThis.Headers(source2)
263
- for (const [key, value] of source.entries()) {
264
- if ((isHeadersInstance && value === 'undefined') || value === undefined) {
265
- result.delete(key)
266
- } else {
267
- result.set(key, value)
268
- }
269
- }
270
- return result
271
- }
272
- // TODO: Make this strongly-typed (no `any`).
273
- const deepMerge = (...sources) => {
274
- let returnValue = {}
275
- let headers = {}
276
- for (const source of sources) {
277
- if (Array.isArray(source)) {
278
- if (!Array.isArray(returnValue)) {
279
- returnValue = []
280
- }
281
- returnValue = [...returnValue, ...source]
282
- } else if (isObject(source)) {
283
- for (let [key, value] of Object.entries(source)) {
284
- if (isObject(value) && key in returnValue) {
285
- value = deepMerge(returnValue[key], value)
286
- }
287
- returnValue = { ...returnValue, [key]: value }
288
- }
289
- if (isObject(source.headers)) {
290
- headers = mergeHeaders(headers, source.headers)
291
- returnValue.headers = headers
292
- }
293
- }
294
- }
295
- return returnValue
296
- }
297
-
298
- const supportsRequestStreams = (() => {
299
- let duplexAccessed = false
300
- let hasContentType = false
301
- const supportsReadableStream = typeof globalThis.ReadableStream === 'function'
302
- const supportsRequest = typeof globalThis.Request === 'function'
303
- if (supportsReadableStream && supportsRequest) {
304
- hasContentType = new globalThis.Request('https://empty.invalid', {
305
- body: new globalThis.ReadableStream(),
306
- method: 'POST',
307
- // @ts-expect-error - Types are outdated.
308
- get duplex () {
309
- duplexAccessed = true
310
- return 'half'
311
- }
312
- }).headers.has('Content-Type')
313
- }
314
- return duplexAccessed && !hasContentType
315
- })()
316
- const supportsAbortController = typeof globalThis.AbortController === 'function'
317
- const supportsResponseStreams = typeof globalThis.ReadableStream === 'function'
318
- const supportsFormData = typeof globalThis.FormData === 'function'
319
- const requestMethods = ['get', 'post', 'put', 'patch', 'head', 'delete']
320
- const responseTypes = {
321
- json: 'application/json',
322
- text: 'text/*',
323
- formData: 'multipart/form-data',
324
- arrayBuffer: '*/*',
325
- blob: '*/*'
326
- }
327
- // The maximum value of a 32bit int (see issue #117)
328
- const maxSafeTimeout = 2147483647
329
- const stop = Symbol('stop')
330
-
331
- const normalizeRequestMethod = (input) => requestMethods.includes(input) ? input.toUpperCase() : input
332
- const retryMethods = ['get', 'put', 'head', 'delete', 'options', 'trace']
333
- const retryStatusCodes = [408, 413, 429, 500, 502, 503, 504]
334
- const retryAfterStatusCodes = [413, 429, 503]
335
- const defaultRetryOptions = {
336
- limit: 2,
337
- methods: retryMethods,
338
- statusCodes: retryStatusCodes,
339
- afterStatusCodes: retryAfterStatusCodes,
340
- maxRetryAfter: Number.POSITIVE_INFINITY,
341
- backoffLimit: Number.POSITIVE_INFINITY
342
- }
343
- const normalizeRetryOptions = (retry = {}) => {
344
- if (typeof retry === 'number') {
345
- return {
346
- ...defaultRetryOptions,
347
- limit: retry
348
- }
349
- }
350
- if (retry.methods && !Array.isArray(retry.methods)) {
351
- throw new Error('retry.methods must be an array')
352
- }
353
- if (retry.statusCodes && !Array.isArray(retry.statusCodes)) {
354
- throw new Error('retry.statusCodes must be an array')
355
- }
356
- return {
357
- ...defaultRetryOptions,
358
- ...retry,
359
- afterStatusCodes: retryAfterStatusCodes
360
- }
361
- }
362
-
363
- // `Promise.race()` workaround (#91)
364
- async function timeout (request, abortController, options) {
365
- return new Promise((resolve, reject) => {
366
- const timeoutId = setTimeout(() => {
367
- if (abortController) {
368
- abortController.abort()
369
- }
370
- reject(new TimeoutError(request))
371
- }, options.timeout)
372
- void options
373
- .fetch(request)
374
- .then(resolve)
375
- .catch(reject)
376
- .then(() => {
377
- clearTimeout(timeoutId)
378
- })
379
- })
380
- }
381
-
382
- // https://github.com/sindresorhus/delay/tree/ab98ae8dfcb38e1593286c94d934e70d14a4e111
383
- async function delay (ms, { signal }) {
384
- return new Promise((resolve, reject) => {
385
- if (signal) {
386
- signal.throwIfAborted()
387
- signal.addEventListener('abort', abortHandler, { once: true })
388
- }
389
- function abortHandler () {
390
- clearTimeout(timeoutId)
391
- reject(signal.reason)
392
- }
393
- const timeoutId = setTimeout(() => {
394
- signal?.removeEventListener('abort', abortHandler)
395
- resolve()
396
- }, ms)
397
- })
398
- }
399
-
400
- class Ky {
401
- static create (input, options) {
402
- const ky = new Ky(input, options)
403
- const fn = async () => {
404
- if (typeof ky._options.timeout === 'number' && ky._options.timeout > maxSafeTimeout) {
405
- throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`)
406
- }
407
- // Delay the fetch so that body method shortcuts can set the Accept header
408
- await Promise.resolve()
409
- let response = await ky._fetch()
410
- for (const hook of ky._options.hooks.afterResponse) {
411
- // eslint-disable-next-line no-await-in-loop
412
- const modifiedResponse = await hook(ky.request, ky._options, ky._decorateResponse(response.clone()))
413
- if (modifiedResponse instanceof globalThis.Response) {
414
- response = modifiedResponse
415
- }
416
- }
417
- ky._decorateResponse(response)
418
- if (!response.ok && ky._options.throwHttpErrors) {
419
- let error = new HTTPError(response, ky.request, ky._options)
420
- for (const hook of ky._options.hooks.beforeError) {
421
- // eslint-disable-next-line no-await-in-loop
422
- error = await hook(error)
423
- }
424
- throw error
425
- }
426
- // If `onDownloadProgress` is passed, it uses the stream API internally
427
- /* istanbul ignore next */
428
- if (ky._options.onDownloadProgress) {
429
- if (typeof ky._options.onDownloadProgress !== 'function') {
430
- throw new TypeError('The `onDownloadProgress` option must be a function')
431
- }
432
- if (!supportsResponseStreams) {
433
- throw new Error('Streams are not supported in your environment. `ReadableStream` is missing.')
434
- }
435
- return ky._stream(response.clone(), ky._options.onDownloadProgress)
436
- }
437
- return response
438
- }
439
- const isRetriableMethod = ky._options.retry.methods.includes(ky.request.method.toLowerCase())
440
- const result = (isRetriableMethod ? ky._retry(fn) : fn())
441
- for (const [type, mimeType] of Object.entries(responseTypes)) {
442
- result[type] = async () => {
443
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
444
- ky.request.headers.set('accept', ky.request.headers.get('accept') || mimeType)
445
- const awaitedResult = await result
446
- const response = awaitedResult.clone()
447
- if (type === 'json') {
448
- if (response.status === 204) {
449
- return ''
450
- }
451
- const arrayBuffer = await response.clone().arrayBuffer()
452
- const responseSize = arrayBuffer.byteLength
453
- if (responseSize === 0) {
454
- return ''
455
- }
456
- if (options.parseJson) {
457
- return options.parseJson(await response.text())
458
- }
459
- }
460
- return response[type]()
461
- }
462
- }
463
- return result
464
- }
465
-
466
- // eslint-disable-next-line complexity
467
- constructor (input, options = {}) {
468
- Object.defineProperty(this, 'request', {
469
- enumerable: true,
470
- configurable: true,
471
- writable: true,
472
- value: void 0
473
- })
474
- Object.defineProperty(this, 'abortController', {
475
- enumerable: true,
476
- configurable: true,
477
- writable: true,
478
- value: void 0
479
- })
480
- Object.defineProperty(this, '_retryCount', {
481
- enumerable: true,
482
- configurable: true,
483
- writable: true,
484
- value: 0
485
- })
486
- Object.defineProperty(this, '_input', {
487
- enumerable: true,
488
- configurable: true,
489
- writable: true,
490
- value: void 0
491
- })
492
- Object.defineProperty(this, '_options', {
493
- enumerable: true,
494
- configurable: true,
495
- writable: true,
496
- value: void 0
497
- })
498
- this._input = input
499
- this._options = {
500
- // TODO: credentials can be removed when the spec change is implemented in all browsers. Context: https://www.chromestatus.com/feature/4539473312350208
501
- credentials: this._input.credentials || 'same-origin',
502
- ...options,
503
- headers: mergeHeaders(this._input.headers, options.headers),
504
- hooks: deepMerge({
505
- beforeRequest: [],
506
- beforeRetry: [],
507
- beforeError: [],
508
- afterResponse: []
509
- }, options.hooks),
510
- method: normalizeRequestMethod(options.method ?? this._input.method),
511
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
512
- prefixUrl: String(options.prefixUrl || ''),
513
- retry: normalizeRetryOptions(options.retry),
514
- throwHttpErrors: options.throwHttpErrors !== false,
515
- timeout: options.timeout ?? 10000,
516
- fetch: options.fetch ?? globalThis.fetch.bind(globalThis)
517
- }
518
- if (typeof this._input !== 'string' && !(this._input instanceof URL || this._input instanceof globalThis.Request)) {
519
- throw new TypeError('`input` must be a string, URL, or Request')
520
- }
521
- if (this._options.prefixUrl && typeof this._input === 'string') {
522
- if (this._input.startsWith('/')) {
523
- throw new Error('`input` must not begin with a slash when using `prefixUrl`')
524
- }
525
- if (!this._options.prefixUrl.endsWith('/')) {
526
- this._options.prefixUrl += '/'
527
- }
528
- this._input = this._options.prefixUrl + this._input
529
- }
530
- if (supportsAbortController) {
531
- this.abortController = new globalThis.AbortController()
532
- if (this._options.signal) {
533
- const originalSignal = this._options.signal
534
- this._options.signal.addEventListener('abort', () => {
535
- this.abortController.abort(originalSignal.reason)
536
- })
537
- }
538
- this._options.signal = this.abortController.signal
539
- }
540
- if (supportsRequestStreams) {
541
- // @ts-expect-error - Types are outdated.
542
- this._options.duplex = 'half'
543
- }
544
- this.request = new globalThis.Request(this._input, this._options)
545
- if (this._options.searchParams) {
546
- // eslint-disable-next-line unicorn/prevent-abbreviations
547
- const textSearchParams = typeof this._options.searchParams === 'string'
548
- ? this._options.searchParams.replace(/^\?/, '')
549
- : new URLSearchParams(this._options.searchParams).toString()
550
- // eslint-disable-next-line unicorn/prevent-abbreviations
551
- const searchParams = '?' + textSearchParams
552
- const url = this.request.url.replace(/(?:\?.*?)?(?=#|$)/, searchParams)
553
- // To provide correct form boundary, Content-Type header should be deleted each time when new Request instantiated from another one
554
- if (((supportsFormData && this._options.body instanceof globalThis.FormData) ||
555
- this._options.body instanceof URLSearchParams) && !(this._options.headers && this._options.headers['content-type'])) {
556
- this.request.headers.delete('content-type')
557
- }
558
- // The spread of `this.request` is required as otherwise it misses the `duplex` option for some reason and throws.
559
- this.request = new globalThis.Request(new globalThis.Request(url, { ...this.request }), this._options)
560
- }
561
- if (this._options.json !== undefined) {
562
- this._options.body = JSON.stringify(this._options.json)
563
- this.request.headers.set('content-type', this._options.headers.get('content-type') ?? 'application/json')
564
- this.request = new globalThis.Request(this.request, { body: this._options.body })
565
- }
566
- }
567
-
568
- _calculateRetryDelay (error) {
569
- this._retryCount++
570
- if (this._retryCount < this._options.retry.limit && !(error instanceof TimeoutError)) {
571
- if (error instanceof HTTPError) {
572
- if (!this._options.retry.statusCodes.includes(error.response.status)) {
573
- return 0
574
- }
575
- const retryAfter = error.response.headers.get('Retry-After')
576
- if (retryAfter && this._options.retry.afterStatusCodes.includes(error.response.status)) {
577
- let after = Number(retryAfter)
578
- if (Number.isNaN(after)) {
579
- after = Date.parse(retryAfter) - Date.now()
580
- } else {
581
- after *= 1000
582
- }
583
- if (this._options.retry.maxRetryAfter !== undefined && after > this._options.retry.maxRetryAfter) {
584
- return 0
585
- }
586
- return after
587
- }
588
- if (error.response.status === 413) {
589
- return 0
590
- }
591
- }
592
- const BACKOFF_FACTOR = 0.3
593
- return Math.min(this._options.retry.backoffLimit, BACKOFF_FACTOR * (2 ** (this._retryCount - 1)) * 1000)
594
- }
595
- return 0
596
- }
597
-
598
- _decorateResponse (response) {
599
- if (this._options.parseJson) {
600
- response.json = async () => this._options.parseJson(await response.text())
601
- }
602
- return response
603
- }
604
-
605
- async _retry (fn) {
606
- try {
607
- return await fn()
608
- } catch (error) {
609
- const ms = Math.min(this._calculateRetryDelay(error), maxSafeTimeout)
610
- if (ms !== 0 && this._retryCount > 0) {
611
- await delay(ms, { signal: this._options.signal })
612
- for (const hook of this._options.hooks.beforeRetry) {
613
- // eslint-disable-next-line no-await-in-loop
614
- const hookResult = await hook({
615
- request: this.request,
616
- options: this._options,
617
- error,
618
- retryCount: this._retryCount
619
- })
620
- // If `stop` is returned from the hook, the retry process is stopped
621
- if (hookResult === stop) {
622
- return
623
- }
624
- }
625
- return this._retry(fn)
626
- }
627
- throw error
628
- }
629
- }
630
-
631
- async _fetch () {
632
- for (const hook of this._options.hooks.beforeRequest) {
633
- // eslint-disable-next-line no-await-in-loop
634
- const result = await hook(this.request, this._options)
635
- if (result instanceof Request) {
636
- this.request = result
637
- break
638
- }
639
- if (result instanceof Response) {
640
- return result
641
- }
642
- }
643
- if (this._options.timeout === false) {
644
- return this._options.fetch(this.request.clone())
645
- }
646
- return timeout(this.request.clone(), this.abortController, this._options)
647
- }
648
-
649
- /* istanbul ignore next */
650
- _stream (response, onDownloadProgress) {
651
- const totalBytes = Number(response.headers.get('content-length')) || 0
652
- let transferredBytes = 0
653
- if (response.status === 204) {
654
- if (onDownloadProgress) {
655
- onDownloadProgress({ percent: 1, totalBytes, transferredBytes }, new Uint8Array())
656
- }
657
- return new globalThis.Response(null, {
658
- status: response.status,
659
- statusText: response.statusText,
660
- headers: response.headers
661
- })
662
- }
663
- return new globalThis.Response(new globalThis.ReadableStream({
664
- async start (controller) {
665
- const reader = response.body.getReader()
666
- if (onDownloadProgress) {
667
- onDownloadProgress({ percent: 0, transferredBytes: 0, totalBytes }, new Uint8Array())
668
- }
669
- async function read () {
670
- const { done, value } = await reader.read()
671
- if (done) {
672
- controller.close()
673
- return
674
- }
675
- if (onDownloadProgress) {
676
- transferredBytes += value.byteLength
677
- const percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes
678
- onDownloadProgress({ percent, transferredBytes, totalBytes }, value)
679
- }
680
- controller.enqueue(value)
681
- await read()
682
- }
683
- await read()
684
- }
685
- }), {
686
- status: response.status,
687
- statusText: response.statusText,
688
- headers: response.headers
689
- })
690
- }
691
- }
692
-
693
- /*! MIT License © Sindre Sorhus */
694
- const createInstance = (defaults) => {
695
- // eslint-disable-next-line @typescript-eslint/promise-function-async
696
- const ky = (input, options) => Ky.create(input, validateAndMerge(defaults, options))
697
- for (const method of requestMethods) {
698
- // eslint-disable-next-line @typescript-eslint/promise-function-async
699
- ky[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, { method }))
700
- }
701
- ky.create = (newDefaults) => createInstance(validateAndMerge(newDefaults))
702
- ky.extend = (newDefaults) => createInstance(validateAndMerge(defaults, newDefaults))
703
- ky.stop = stop
704
- return ky
705
- }
706
- const ky$1 = createInstance()
707
-
708
- const distribution = /* #__PURE__ */Object.freeze({
709
- __proto__: null,
710
- HTTPError,
711
- TimeoutError,
712
- default: ky$1
713
- })
714
-
715
- const require$$3 = /* @__PURE__ */getAugmentedNamespace(distribution)
716
-
717
- const urlHttp = lightweight
718
- const { flattie: flatten } = dist
719
-
720
- const factory = factory_1
721
- const { default: ky } = require$$3
722
-
723
- class MicrolinkError extends Error {
724
- constructor (props) {
725
- super()
726
- this.name = 'MicrolinkError'
727
- Object.assign(this, props)
728
- this.description = this.message
729
- this.message = this.code
730
- ? `${this.code}, ${this.description}`
731
- : this.description
732
- }
733
- }
734
-
735
- const got = async (url, opts) => {
736
- try {
737
- if (opts.retry > 0) opts.retry = opts.retry + 1
738
- if (opts.timeout === undefined) opts.timeout = false
739
- const response = await ky(url, opts)
740
- const body = await response.json()
741
- const { headers, status: statusCode } = response
742
- return { url: response.url, body, headers, statusCode }
743
- } catch (err) {
744
- if (err.response) {
745
- const { response } = err
746
- err.response = {
747
- ...response,
748
- headers: Array.from(response.headers.entries()).reduce(
749
- (acc, [key, value]) => {
750
- acc[key] = value
751
- return acc
752
- },
753
- {}
754
- ),
755
- statusCode: response.status,
756
- body: await response.text()
757
- }
758
- }
759
- throw err
760
- }
761
- }
762
-
763
- const lightweight_tpl = factory({
764
- MicrolinkError,
765
- urlHttp,
766
- got,
767
- flatten,
768
- VERSION: '0.11.0-1'
769
- })
770
-
771
- const lightweight_tpl$1 = /* @__PURE__ */getDefaultExportFromCjs(lightweight_tpl)
772
-
773
- export { lightweight_tpl$1 as default }
1
+ function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}function e(t){if(t.__esModule)return t;var e=t.default;if("function"==typeof e){var r=function t(){return this instanceof t?Reflect.construct(e,arguments,this.constructor):e.apply(this,arguments)};r.prototype=e.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(t).forEach((function(e){let s=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(r,e,s.get?s:{enumerable:!0,get:function(){return t[e]}})})),r}const r=/^https?:\/\//i;var s={};function o(t,e,r,s,n){let i;var a=n?n+r:n;if(null==s)e&&(t[n]=s);else if("object"!=typeof s)t[n]=s;else if(Array.isArray(s))for(i=0;i<s.length;i++)o(t,e,r,s[i],a+i);else for(i in s)o(t,e,r,s[i],a+i)}s.flattie=function(t,e,r){let s={};return"object"==typeof t&&o(s,!!r,e||".",t,""),s};const n={FREE:"https://api.microlink.io/",PRO:"https://pro.microlink.io/"},i=t=>null!==t&&"object"==typeof t;var a=({VERSION:t,MicrolinkError:e,urlHttp:r,got:s,flatten:o})=>{const a=t=>{if(!i(t))return;const e=o(t);return Object.keys(e).reduce(((t,r)=>(t[`data.${r}`]=e[r].toString(),t)),{})},u=async(t,r={})=>{try{const e=await s(t,r);return"buffer"===r.responseType?{body:e.body,response:e}:{...e.body,response:e}}catch(r){const{response:s={}}=r,{statusCode:n,body:a,headers:u={},url:l=t}=s,h=null!=(o=a)&&null!=o.constructor&&"function"==typeof o.constructor.isBuffer&&o.constructor.isBuffer(o),c=i(a)&&!h?a:((t,e,r)=>{try{return JSON.parse(t)}catch(s){const o=t||e.message;return{status:"error",data:{url:o},more:"https://microlink.io/efatalclient",code:"EFATALCLIENT",message:o,url:r}}})(h?a.toString():a,r,l);throw new e({...c,message:c.message,url:l,statusCode:n,headers:u})}var o},l=(t,{data:e,apiKey:r,endpoint:s,retry:i,cache:u,...l}={},{responseType:h="json",headers:c,...p}={})=>{const f=!!r;return[`${s||n[f?"PRO":"FREE"]}?${new URLSearchParams({url:t,...a(e),...o(l)}).toString()}`,{...p,responseType:h,cache:u,retry:i,headers:f?{...c,"x-api-key":r}:{...c}}]},h=t=>async(s,o,n)=>{((t="")=>{if(!r(t)){const r=`The \`url\` as \`${t}\` is not valid. Ensure it has protocol (http or https) and hostname.`;throw new e({status:"fail",data:{url:r},more:"https://microlink.io/docs/api/api-parameters/url",code:"EINVALURLCLIENT",message:r,url:t})}})(s);const[i,a]=l(s,o,{...t,...n});return u(i,a)},c=h();return c.MicrolinkError=e,c.getApiUrl=l,c.fetchFromApi=u,c.mapRules=a,c.version=t,c.stream=s.stream,c.buffer=h({responseType:"buffer"}),c};class u extends Error{constructor(t,e,r){const s=`${t.status||0===t.status?t.status:""} ${t.statusText||""}`.trim();super(`Request failed with ${s?`status code ${s}`:"an unknown error"}`),Object.defineProperty(this,"response",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"request",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"options",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.name="HTTPError",this.response=t,this.request=e,this.options=r}}class l extends Error{constructor(t){super("Request timed out"),Object.defineProperty(this,"request",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.name="TimeoutError",this.request=t}}const h=t=>null!==t&&"object"==typeof t,c=(...t)=>{for(const e of t)if((!h(e)||Array.isArray(e))&&void 0!==e)throw new TypeError("The `options` argument must be an object");return f({},...t)},p=(t={},e={})=>{const r=new globalThis.Headers(t),s=e instanceof globalThis.Headers,o=new globalThis.Headers(e);for(const[t,e]of o.entries())s&&"undefined"===e||void 0===e?r.delete(t):r.set(t,e);return r},f=(...t)=>{let e={},r={};for(const s of t)if(Array.isArray(s))Array.isArray(e)||(e=[]),e=[...e,...s];else if(h(s)){for(let[t,r]of Object.entries(s))h(r)&&t in e&&(r=f(e[t],r)),e={...e,[t]:r};h(s.headers)&&(r=p(r,s.headers),e.headers=r)}return e},d=(()=>{let t=!1,e=!1;const r="function"==typeof globalThis.ReadableStream,s="function"==typeof globalThis.Request;return r&&s&&(e=new globalThis.Request("https://empty.invalid",{body:new globalThis.ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type")),t&&!e})(),y="function"==typeof globalThis.AbortController,b="function"==typeof globalThis.ReadableStream,m="function"==typeof globalThis.FormData,_=["get","post","put","patch","head","delete"],w={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},g=2147483647,T=Symbol("stop"),R=t=>_.includes(t)?t.toUpperCase():t,v=[413,429,503],E={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:v,maxRetryAfter:Number.POSITIVE_INFINITY,backoffLimit:Number.POSITIVE_INFINITY},q=(t={})=>{if("number"==typeof t)return{...E,limit:t};if(t.methods&&!Array.isArray(t.methods))throw new Error("retry.methods must be an array");if(t.statusCodes&&!Array.isArray(t.statusCodes))throw new Error("retry.statusCodes must be an array");return{...E,...t,afterStatusCodes:v}};class P{static create(t,e){const r=new P(t,e),s=async()=>{if("number"==typeof r._options.timeout&&r._options.timeout>g)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await Promise.resolve();let t=await r._fetch();for(const e of r._options.hooks.afterResponse){const s=await e(r.request,r._options,r._decorateResponse(t.clone()));s instanceof globalThis.Response&&(t=s)}if(r._decorateResponse(t),!t.ok&&r._options.throwHttpErrors){let e=new u(t,r.request,r._options);for(const t of r._options.hooks.beforeError)e=await t(e);throw e}if(r._options.onDownloadProgress){if("function"!=typeof r._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!b)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return r._stream(t.clone(),r._options.onDownloadProgress)}return t},o=r._options.retry.methods.includes(r.request.method.toLowerCase())?r._retry(s):s();for(const[t,s]of Object.entries(w))o[t]=async()=>{r.request.headers.set("accept",r.request.headers.get("accept")||s);const n=(await o).clone();if("json"===t){if(204===n.status)return"";if(0===(await n.clone().arrayBuffer()).byteLength)return"";if(e.parseJson)return e.parseJson(await n.text())}return n[t]()};return o}constructor(t,e={}){if(Object.defineProperty(this,"request",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"abortController",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_retryCount",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_input",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_options",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this._input=t,this._options={credentials:this._input.credentials||"same-origin",...e,headers:p(this._input.headers,e.headers),hooks:f({beforeRequest:[],beforeRetry:[],beforeError:[],afterResponse:[]},e.hooks),method:R(e.method??this._input.method),prefixUrl:String(e.prefixUrl||""),retry:q(e.retry),throwHttpErrors:!1!==e.throwHttpErrors,timeout:e.timeout??1e4,fetch:e.fetch??globalThis.fetch.bind(globalThis)},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof globalThis.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(y){if(this.abortController=new globalThis.AbortController,this._options.signal){const t=this._options.signal;this._options.signal.addEventListener("abort",(()=>{this.abortController.abort(t.reason)}))}this._options.signal=this.abortController.signal}if(d&&(this._options.duplex="half"),this.request=new globalThis.Request(this._input,this._options),this._options.searchParams){const t="?"+("string"==typeof this._options.searchParams?this._options.searchParams.replace(/^\?/,""):new URLSearchParams(this._options.searchParams).toString()),e=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,t);!(m&&this._options.body instanceof globalThis.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new globalThis.Request(new globalThis.Request(e,{...this.request}),this._options)}void 0!==this._options.json&&(this._options.body=JSON.stringify(this._options.json),this.request.headers.set("content-type",this._options.headers.get("content-type")??"application/json"),this.request=new globalThis.Request(this.request,{body:this._options.body}))}_calculateRetryDelay(t){if(this._retryCount++,this._retryCount<this._options.retry.limit&&!(t instanceof l)){if(t instanceof u){if(!this._options.retry.statusCodes.includes(t.response.status))return 0;const e=t.response.headers.get("Retry-After");if(e&&this._options.retry.afterStatusCodes.includes(t.response.status)){let t=Number(e);return Number.isNaN(t)?t=Date.parse(e)-Date.now():t*=1e3,void 0!==this._options.retry.maxRetryAfter&&t>this._options.retry.maxRetryAfter?0:t}if(413===t.response.status)return 0}const e=.3;return Math.min(this._options.retry.backoffLimit,e*2**(this._retryCount-1)*1e3)}return 0}_decorateResponse(t){return this._options.parseJson&&(t.json=async()=>this._options.parseJson(await t.text())),t}async _retry(t){try{return await t()}catch(e){const r=Math.min(this._calculateRetryDelay(e),g);if(0!==r&&this._retryCount>0){await async function(t,{signal:e}){return new Promise(((r,s)=>{function o(){clearTimeout(n),s(e.reason)}e&&(e.throwIfAborted(),e.addEventListener("abort",o,{once:!0}));const n=setTimeout((()=>{e?.removeEventListener("abort",o),r()}),t)}))}(r,{signal:this._options.signal});for(const t of this._options.hooks.beforeRetry){if(await t({request:this.request,options:this._options,error:e,retryCount:this._retryCount})===T)return}return this._retry(t)}throw e}}async _fetch(){for(const t of this._options.hooks.beforeRequest){const e=await t(this.request,this._options);if(e instanceof Request){this.request=e;break}if(e instanceof Response)return e}return!1===this._options.timeout?this._options.fetch(this.request.clone()):async function(t,e,r){return new Promise(((s,o)=>{const n=setTimeout((()=>{e&&e.abort(),o(new l(t))}),r.timeout);r.fetch(t).then(s).catch(o).then((()=>{clearTimeout(n)}))}))}(this.request.clone(),this.abortController,this._options)}_stream(t,e){const r=Number(t.headers.get("content-length"))||0;let s=0;return 204===t.status?(e&&e({percent:1,totalBytes:r,transferredBytes:s},new Uint8Array),new globalThis.Response(null,{status:t.status,statusText:t.statusText,headers:t.headers})):new globalThis.Response(new globalThis.ReadableStream({async start(o){const n=t.body.getReader();e&&e({percent:0,transferredBytes:0,totalBytes:r},new Uint8Array),await async function t(){const{done:i,value:a}=await n.read();if(i)o.close();else{if(e){s+=a.byteLength;e({percent:0===r?0:s/r,transferredBytes:s,totalBytes:r},a)}o.enqueue(a),await t()}}()}}),{status:t.status,statusText:t.statusText,headers:t.headers})}}
2
+ /*! MIT License © Sindre Sorhus */const j=t=>{const e=(e,r)=>P.create(e,c(t,r));for(const r of _)e[r]=(e,s)=>P.create(e,c(t,s,{method:r}));return e.create=t=>j(c(t)),e.extend=e=>j(c(t,e)),e.stop=T,e},C=j();var O=e(Object.freeze({__proto__:null,HTTPError:u,TimeoutError:l,default:C}));const x=t=>{try{const{href:e}=new URL(t);return r.test(e)&&e}catch(t){return!1}},{flattie:A}=s,S=a,{default:k}=O;class L extends Error{constructor(t){super(),this.name="MicrolinkError",Object.assign(this,t),this.description=this.message,this.message=this.code?`${this.code}, ${this.description}`:this.description}}var N=t(S({MicrolinkError:L,urlHttp:x,got:async(t,e)=>{try{e.retry>0&&(e.retry=e.retry+1),void 0===e.timeout&&(e.timeout=!1);const r=await k(t,e),s=await r.json(),{headers:o,status:n}=r;return{url:r.url,body:s,headers:o,statusCode:n}}catch(t){if(t.response){const{response:e}=t;t.response={...e,headers:Array.from(e.headers.entries()).reduce(((t,[e,r])=>(t[e]=r,t)),{}),statusCode:e.status,body:await e.text()}}throw t}},flatten:A,VERSION:"0.11.0-2"}));export{N as default};
@@ -0,0 +1,55 @@
1
+ 'use strict'
2
+
3
+ const urlHttp = require('url-http/lightweight')
4
+ const { flattie: flatten } = require('flattie')
5
+
6
+ const factory = require('./factory')
7
+ const { default: ky } = require('ky')
8
+
9
+ class MicrolinkError extends Error {
10
+ constructor (props) {
11
+ super()
12
+ this.name = 'MicrolinkError'
13
+ Object.assign(this, props)
14
+ this.description = this.message
15
+ this.message = this.code
16
+ ? `${this.code}, ${this.description}`
17
+ : this.description
18
+ }
19
+ }
20
+
21
+ const got = async (url, opts) => {
22
+ try {
23
+ if (opts.retry > 0) opts.retry = opts.retry + 1
24
+ if (opts.timeout === undefined) opts.timeout = false
25
+ const response = await ky(url, opts)
26
+ const body = await response.json()
27
+ const { headers, status: statusCode } = response
28
+ return { url: response.url, body, headers, statusCode }
29
+ } catch (err) {
30
+ if (err.response) {
31
+ const { response } = err
32
+ err.response = {
33
+ ...response,
34
+ headers: Array.from(response.headers.entries()).reduce(
35
+ (acc, [key, value]) => {
36
+ acc[key] = value
37
+ return acc
38
+ },
39
+ {}
40
+ ),
41
+ statusCode: response.status,
42
+ body: await response.text()
43
+ }
44
+ }
45
+ throw err
46
+ }
47
+ }
48
+
49
+ module.exports = factory({
50
+ MicrolinkError,
51
+ urlHttp,
52
+ got,
53
+ flatten,
54
+ VERSION: require('../package.json').version
55
+ })
package/src/node.mjs CHANGED
@@ -142,7 +142,7 @@ node$1.exports = factory_1({
142
142
  urlHttp: require$$2,
143
143
  got: require$$3.extend({ headers: { 'user-agent': undefined } }),
144
144
  flatten: require$$4.flattie,
145
- VERSION: '0.11.0-1'
145
+ VERSION: '0.11.0-2'
146
146
  });
147
147
 
148
148
  var render = node$1.exports.render = (input, { width = '650px' } = {}) => {