@microlink/function 0.1.1 → 0.1.2
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/README.md +15 -17
- package/dist/microlink-function.js +760 -760
- package/dist/microlink-function.js.map +1 -1
- package/dist/microlink-function.min.js +2 -2
- package/dist/microlink-function.min.js.map +1 -1
- package/package.json +24 -23
- package/src/node.js +1 -1
- package/CHANGELOG.md +0 -19
|
@@ -177,945 +177,945 @@
|
|
|
177
177
|
|
|
178
178
|
var require$$2 = /*@__PURE__*/ getAugmentedNamespace(qss_m)
|
|
179
179
|
|
|
180
|
-
var
|
|
181
|
-
|
|
182
|
-
;(function (module, exports) {
|
|
183
|
-
;(function (global, factory) {
|
|
184
|
-
module.exports = factory()
|
|
185
|
-
})(commonjsGlobal, function () {
|
|
186
|
-
/*! MIT License © Sindre Sorhus */
|
|
180
|
+
var lib = { exports: {} }
|
|
187
181
|
|
|
188
|
-
|
|
189
|
-
const supportsAbortController =
|
|
190
|
-
typeof globalThis.AbortController === 'function'
|
|
191
|
-
const supportsStreams = typeof globalThis.ReadableStream === 'function'
|
|
192
|
-
const supportsFormData = typeof globalThis.FormData === 'function'
|
|
182
|
+
var _nodeResolve_empty = {}
|
|
193
183
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
184
|
+
var _nodeResolve_empty$1 = /*#__PURE__*/ Object.freeze({
|
|
185
|
+
__proto__: null,
|
|
186
|
+
default: _nodeResolve_empty
|
|
187
|
+
})
|
|
198
188
|
|
|
199
|
-
|
|
200
|
-
if (
|
|
201
|
-
(isHeadersInstance && value === 'undefined') ||
|
|
202
|
-
value === undefined
|
|
203
|
-
) {
|
|
204
|
-
result.delete(key)
|
|
205
|
-
} else {
|
|
206
|
-
result.set(key, value)
|
|
207
|
-
}
|
|
208
|
-
}
|
|
189
|
+
var require$$0 = /*@__PURE__*/ getAugmentedNamespace(_nodeResolve_empty$1)
|
|
209
190
|
|
|
210
|
-
|
|
211
|
-
}
|
|
191
|
+
const os = require$$0
|
|
212
192
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
193
|
+
const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/
|
|
194
|
+
const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/
|
|
195
|
+
const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir()
|
|
216
196
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (!Array.isArray(returnValue)) {
|
|
220
|
-
returnValue = []
|
|
221
|
-
}
|
|
197
|
+
var cleanStack$1 = (stack, options) => {
|
|
198
|
+
options = Object.assign({ pretty: false }, options)
|
|
222
199
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
200
|
+
return stack
|
|
201
|
+
.replace(/\\/g, '/')
|
|
202
|
+
.split('\n')
|
|
203
|
+
.filter(line => {
|
|
204
|
+
const pathMatches = line.match(extractPathRegex)
|
|
205
|
+
if (pathMatches === null || !pathMatches[1]) {
|
|
206
|
+
return true
|
|
207
|
+
}
|
|
229
208
|
|
|
230
|
-
|
|
231
|
-
}
|
|
209
|
+
const match = pathMatches[1]
|
|
232
210
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
211
|
+
// Electron
|
|
212
|
+
if (
|
|
213
|
+
match.includes('.app/Contents/Resources/electron.asar') ||
|
|
214
|
+
match.includes('.app/Contents/Resources/default_app.asar')
|
|
215
|
+
) {
|
|
216
|
+
return false
|
|
217
|
+
}
|
|
237
218
|
|
|
238
|
-
|
|
219
|
+
return !pathRegex.test(match)
|
|
220
|
+
})
|
|
221
|
+
.filter(line => line.trim() !== '')
|
|
222
|
+
.map(line => {
|
|
223
|
+
if (options.pretty) {
|
|
224
|
+
return line.replace(extractPathRegex, (m, p1) =>
|
|
225
|
+
m.replace(p1, p1.replace(homeDir, '~'))
|
|
226
|
+
)
|
|
239
227
|
}
|
|
240
228
|
|
|
241
|
-
return
|
|
242
|
-
}
|
|
229
|
+
return line
|
|
230
|
+
})
|
|
231
|
+
.join('\n')
|
|
232
|
+
}
|
|
243
233
|
|
|
244
|
-
|
|
234
|
+
const copyProperty = (to, from, property, ignoreNonConfigurable) => {
|
|
235
|
+
// `Function#length` should reflect the parameters of `to` not `from` since we keep its body.
|
|
236
|
+
// `Function#prototype` is non-writable and non-configurable so can never be modified.
|
|
237
|
+
if (property === 'length' || property === 'prototype') {
|
|
238
|
+
return
|
|
239
|
+
}
|
|
245
240
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
text: 'text/*',
|
|
249
|
-
formData: 'multipart/form-data',
|
|
250
|
-
arrayBuffer: '*/*',
|
|
251
|
-
blob: '*/*'
|
|
252
|
-
}
|
|
241
|
+
const toDescriptor = Object.getOwnPropertyDescriptor(to, property)
|
|
242
|
+
const fromDescriptor = Object.getOwnPropertyDescriptor(from, property)
|
|
253
243
|
|
|
254
|
-
|
|
244
|
+
if (
|
|
245
|
+
!canCopyProperty(toDescriptor, fromDescriptor) &&
|
|
246
|
+
ignoreNonConfigurable
|
|
247
|
+
) {
|
|
248
|
+
return
|
|
249
|
+
}
|
|
255
250
|
|
|
256
|
-
|
|
251
|
+
Object.defineProperty(to, property, fromDescriptor)
|
|
252
|
+
}
|
|
257
253
|
|
|
258
|
-
|
|
254
|
+
// `Object.defineProperty()` throws if the property exists, is not configurable and either:
|
|
255
|
+
// - one its descriptors is changed
|
|
256
|
+
// - it is non-writable and its value is changed
|
|
257
|
+
const canCopyProperty = function (toDescriptor, fromDescriptor) {
|
|
258
|
+
return (
|
|
259
|
+
toDescriptor === undefined ||
|
|
260
|
+
toDescriptor.configurable ||
|
|
261
|
+
(toDescriptor.writable === fromDescriptor.writable &&
|
|
262
|
+
toDescriptor.enumerable === fromDescriptor.enumerable &&
|
|
263
|
+
toDescriptor.configurable === fromDescriptor.configurable &&
|
|
264
|
+
(toDescriptor.writable || toDescriptor.value === fromDescriptor.value))
|
|
265
|
+
)
|
|
266
|
+
}
|
|
259
267
|
|
|
260
|
-
|
|
268
|
+
const changePrototype = (to, from) => {
|
|
269
|
+
const fromPrototype = Object.getPrototypeOf(from)
|
|
270
|
+
if (fromPrototype === Object.getPrototypeOf(to)) {
|
|
271
|
+
return
|
|
272
|
+
}
|
|
261
273
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
// Set the message to the status text, such as Unauthorized,
|
|
265
|
-
// with some fallbacks. This message should never be undefined.
|
|
266
|
-
super(
|
|
267
|
-
response.statusText ||
|
|
268
|
-
String(
|
|
269
|
-
response.status === 0 || response.status
|
|
270
|
-
? response.status
|
|
271
|
-
: 'Unknown response error'
|
|
272
|
-
)
|
|
273
|
-
)
|
|
274
|
-
this.name = 'HTTPError'
|
|
275
|
-
this.response = response
|
|
276
|
-
this.request = request
|
|
277
|
-
this.options = options
|
|
278
|
-
}
|
|
279
|
-
}
|
|
274
|
+
Object.setPrototypeOf(to, fromPrototype)
|
|
275
|
+
}
|
|
280
276
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
super('Request timed out')
|
|
284
|
-
this.name = 'TimeoutError'
|
|
285
|
-
this.request = request
|
|
286
|
-
}
|
|
287
|
-
}
|
|
277
|
+
const wrappedToString = (withName, fromBody) =>
|
|
278
|
+
`/* Wrapped ${withName}*/\n${fromBody}`
|
|
288
279
|
|
|
289
|
-
|
|
280
|
+
const toStringDescriptor = Object.getOwnPropertyDescriptor(
|
|
281
|
+
Function.prototype,
|
|
282
|
+
'toString'
|
|
283
|
+
)
|
|
284
|
+
const toStringName = Object.getOwnPropertyDescriptor(
|
|
285
|
+
Function.prototype.toString,
|
|
286
|
+
'name'
|
|
287
|
+
)
|
|
290
288
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
289
|
+
// We call `from.toString()` early (not lazily) to ensure `from` can be garbage collected.
|
|
290
|
+
// We use `bind()` instead of a closure for the same reason.
|
|
291
|
+
// Calling `from.toString()` early also allows caching it in case `to.toString()` is called several times.
|
|
292
|
+
const changeToString = (to, from, name) => {
|
|
293
|
+
const withName = name === '' ? '' : `with ${name.trim()}() `
|
|
294
|
+
const newToString = wrappedToString.bind(null, withName, from.toString())
|
|
295
|
+
// Ensure `to.toString.toString` is non-enumerable and has the same `same`
|
|
296
|
+
Object.defineProperty(newToString, 'name', toStringName)
|
|
297
|
+
Object.defineProperty(to, 'toString', {
|
|
298
|
+
...toStringDescriptor,
|
|
299
|
+
value: newToString
|
|
300
|
+
})
|
|
301
|
+
}
|
|
298
302
|
|
|
299
|
-
|
|
300
|
-
|
|
303
|
+
const mimicFn$2 = (to, from, { ignoreNonConfigurable = false } = {}) => {
|
|
304
|
+
const { name } = to
|
|
301
305
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
.then(resolve)
|
|
306
|
-
.catch(reject)
|
|
307
|
-
.then(() => {
|
|
308
|
-
clearTimeout(timeoutID)
|
|
309
|
-
})
|
|
310
|
-
/* eslint-enable promise/prefer-await-to-then */
|
|
311
|
-
})
|
|
306
|
+
for (const property of Reflect.ownKeys(from)) {
|
|
307
|
+
copyProperty(to, from, property, ignoreNonConfigurable)
|
|
308
|
+
}
|
|
312
309
|
|
|
313
|
-
|
|
314
|
-
|
|
310
|
+
changePrototype(to, from)
|
|
311
|
+
changeToString(to, from, name)
|
|
315
312
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
methods: retryMethods,
|
|
319
|
-
statusCodes: retryStatusCodes,
|
|
320
|
-
afterStatusCodes: retryAfterStatusCodes
|
|
321
|
-
}
|
|
313
|
+
return to
|
|
314
|
+
}
|
|
322
315
|
|
|
323
|
-
|
|
324
|
-
if (typeof retry === 'number') {
|
|
325
|
-
return {
|
|
326
|
-
...defaultRetryOptions,
|
|
327
|
-
limit: retry
|
|
328
|
-
}
|
|
329
|
-
}
|
|
316
|
+
var mimicFn_1 = mimicFn$2
|
|
330
317
|
|
|
331
|
-
|
|
332
|
-
|
|
318
|
+
var helpers = {
|
|
319
|
+
isFunction: obj => typeof obj === 'function',
|
|
320
|
+
isString: obj => typeof obj === 'string',
|
|
321
|
+
composeErrorMessage: (code, description) => `${code}, ${description}`,
|
|
322
|
+
inherits: (ctor, superCtor) => {
|
|
323
|
+
ctor.super_ = superCtor
|
|
324
|
+
ctor.prototype = Object.create(superCtor.prototype, {
|
|
325
|
+
constructor: {
|
|
326
|
+
value: ctor,
|
|
327
|
+
enumerable: false,
|
|
328
|
+
writable: true,
|
|
329
|
+
configurable: true
|
|
333
330
|
}
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
334
|
|
|
335
|
-
|
|
336
|
-
throw new Error('retry.statusCodes must be an array')
|
|
337
|
-
}
|
|
335
|
+
const { isFunction, composeErrorMessage } = helpers
|
|
338
336
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
...retry,
|
|
342
|
-
afterStatusCodes: retryAfterStatusCodes
|
|
343
|
-
}
|
|
344
|
-
}
|
|
337
|
+
function interfaceObject (error, ...props) {
|
|
338
|
+
Object.assign(error, ...props)
|
|
345
339
|
|
|
346
|
-
|
|
347
|
-
|
|
340
|
+
error.description = isFunction(error.message)
|
|
341
|
+
? error.message(error)
|
|
342
|
+
: error.message
|
|
348
343
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
this._options = {
|
|
354
|
-
// TODO: credentials can be removed when the spec change is implemented in all browsers. Context: https://www.chromestatus.com/feature/4539473312350208
|
|
355
|
-
credentials: this._input.credentials || 'same-origin',
|
|
356
|
-
...options,
|
|
357
|
-
headers: mergeHeaders(this._input.headers, options.headers),
|
|
358
|
-
hooks: deepMerge(
|
|
359
|
-
{
|
|
360
|
-
beforeRequest: [],
|
|
361
|
-
beforeRetry: [],
|
|
362
|
-
afterResponse: []
|
|
363
|
-
},
|
|
364
|
-
options.hooks
|
|
365
|
-
),
|
|
366
|
-
method: normalizeRequestMethod(
|
|
367
|
-
options.method || this._input.method
|
|
368
|
-
),
|
|
369
|
-
prefixUrl: String(options.prefixUrl || ''),
|
|
370
|
-
retry: normalizeRetryOptions(options.retry),
|
|
371
|
-
throwHttpErrors: options.throwHttpErrors !== false,
|
|
372
|
-
timeout:
|
|
373
|
-
typeof options.timeout === 'undefined' ? 10000 : options.timeout,
|
|
374
|
-
fetch: options.fetch || globalThis.fetch.bind(globalThis)
|
|
375
|
-
}
|
|
344
|
+
error.message = error.code
|
|
345
|
+
? composeErrorMessage(error.code, error.description)
|
|
346
|
+
: error.description
|
|
347
|
+
}
|
|
376
348
|
|
|
377
|
-
|
|
378
|
-
typeof this._input !== 'string' &&
|
|
379
|
-
!(
|
|
380
|
-
this._input instanceof URL ||
|
|
381
|
-
this._input instanceof globalThis.Request
|
|
382
|
-
)
|
|
383
|
-
) {
|
|
384
|
-
throw new TypeError('`input` must be a string, URL, or Request')
|
|
385
|
-
}
|
|
349
|
+
var addErrorProps$1 = interfaceObject
|
|
386
350
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
throw new Error(
|
|
390
|
-
'`input` must not begin with a slash when using `prefixUrl`'
|
|
391
|
-
)
|
|
392
|
-
}
|
|
351
|
+
const cleanStack = cleanStack$1
|
|
352
|
+
const mimicFn$1 = mimicFn_1
|
|
393
353
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
}
|
|
354
|
+
const addErrorProps = addErrorProps$1
|
|
355
|
+
const { isString } = helpers
|
|
397
356
|
|
|
398
|
-
|
|
399
|
-
|
|
357
|
+
function createExtendError$1 (ErrorClass, classProps) {
|
|
358
|
+
function ExtendError (props) {
|
|
359
|
+
const error = new ErrorClass()
|
|
360
|
+
const errorProps = isString(props) ? { message: props } : props
|
|
361
|
+
addErrorProps(error, classProps, errorProps)
|
|
400
362
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
this._options.signal.addEventListener('abort', () => {
|
|
405
|
-
this.abortController.abort()
|
|
406
|
-
})
|
|
407
|
-
}
|
|
363
|
+
error.stack = cleanStack(error.stack)
|
|
364
|
+
return error
|
|
365
|
+
}
|
|
408
366
|
|
|
409
|
-
|
|
410
|
-
|
|
367
|
+
ExtendError.prototype = ErrorClass.prototype
|
|
368
|
+
mimicFn$1(ExtendError, ErrorClass)
|
|
411
369
|
|
|
412
|
-
|
|
370
|
+
return ExtendError
|
|
371
|
+
}
|
|
413
372
|
|
|
414
|
-
|
|
415
|
-
const textSearchParams =
|
|
416
|
-
typeof this._options.searchParams === 'string'
|
|
417
|
-
? this._options.searchParams.replace(/^\?/, '')
|
|
418
|
-
: new URLSearchParams(this._options.searchParams).toString()
|
|
419
|
-
const searchParams = '?' + textSearchParams
|
|
420
|
-
const url = this.request.url.replace(
|
|
421
|
-
/(?:\?.*?)?(?=#|$)/,
|
|
422
|
-
searchParams
|
|
423
|
-
)
|
|
373
|
+
var createExtendError_1 = createExtendError$1
|
|
424
374
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
((supportsFormData &&
|
|
428
|
-
this._options.body instanceof globalThis.FormData) ||
|
|
429
|
-
this._options.body instanceof URLSearchParams) &&
|
|
430
|
-
!(this._options.headers && this._options.headers['content-type'])
|
|
431
|
-
) {
|
|
432
|
-
this.request.headers.delete('content-type')
|
|
433
|
-
}
|
|
375
|
+
const { inherits } = helpers
|
|
376
|
+
const mimicFn = mimicFn_1
|
|
434
377
|
|
|
435
|
-
|
|
436
|
-
new globalThis.Request(url, this.request),
|
|
437
|
-
this._options
|
|
438
|
-
)
|
|
439
|
-
}
|
|
378
|
+
const REGEX_CLASS_NAME = /[^0-9a-zA-Z_$]/
|
|
440
379
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
body: this._options.body
|
|
446
|
-
})
|
|
447
|
-
}
|
|
380
|
+
function createError$1 (className) {
|
|
381
|
+
if (typeof className !== 'string') {
|
|
382
|
+
throw new TypeError('Expected className to be a string')
|
|
383
|
+
}
|
|
448
384
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`
|
|
453
|
-
)
|
|
454
|
-
}
|
|
385
|
+
if (REGEX_CLASS_NAME.test(className)) {
|
|
386
|
+
throw new Error('className contains invalid characters')
|
|
387
|
+
}
|
|
455
388
|
|
|
456
|
-
|
|
457
|
-
|
|
389
|
+
function ErrorClass () {
|
|
390
|
+
Object.defineProperty(this, 'name', {
|
|
391
|
+
configurable: true,
|
|
392
|
+
value: className,
|
|
393
|
+
writable: true
|
|
394
|
+
})
|
|
458
395
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
const modifiedResponse = await hook(
|
|
462
|
-
this.request,
|
|
463
|
-
this._options,
|
|
464
|
-
this._decorateResponse(response.clone())
|
|
465
|
-
)
|
|
396
|
+
Error.captureStackTrace(this, this.constructor)
|
|
397
|
+
}
|
|
466
398
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
399
|
+
inherits(ErrorClass, Error)
|
|
400
|
+
mimicFn(ErrorClass, Error)
|
|
401
|
+
return ErrorClass
|
|
402
|
+
}
|
|
471
403
|
|
|
472
|
-
|
|
404
|
+
var createError_1 = createError$1
|
|
473
405
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}
|
|
406
|
+
const createExtendError = createExtendError_1
|
|
407
|
+
const createError = createError_1
|
|
477
408
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
throw new TypeError(
|
|
483
|
-
'The `onDownloadProgress` option must be a function'
|
|
484
|
-
)
|
|
485
|
-
}
|
|
409
|
+
const createErrorClass = ErrorClass => (className, props) => {
|
|
410
|
+
const errorClass = createError(className || ErrorClass.name)
|
|
411
|
+
return createExtendError(errorClass, props)
|
|
412
|
+
}
|
|
486
413
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
414
|
+
lib.exports = createErrorClass(Error)
|
|
415
|
+
lib.exports.type = createErrorClass(TypeError)
|
|
416
|
+
lib.exports.range = createErrorClass(RangeError)
|
|
417
|
+
lib.exports.eval = createErrorClass(EvalError)
|
|
418
|
+
lib.exports.syntax = createErrorClass(SyntaxError)
|
|
419
|
+
lib.exports.reference = createErrorClass(ReferenceError)
|
|
420
|
+
lib.exports.uri = createErrorClass(URIError)
|
|
492
421
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
}
|
|
422
|
+
const ENDPOINT = {
|
|
423
|
+
FREE: 'https://api.microlink.io',
|
|
424
|
+
PRO: 'https://pro.microlink.io'
|
|
425
|
+
}
|
|
498
426
|
|
|
499
|
-
|
|
500
|
-
}
|
|
427
|
+
const isObject = input => input !== null && typeof input === 'object'
|
|
501
428
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
429
|
+
const parseBody = (input, error, url) => {
|
|
430
|
+
try {
|
|
431
|
+
return JSON.parse(input)
|
|
432
|
+
} catch (_) {
|
|
433
|
+
const message = input || error.message
|
|
506
434
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
435
|
+
return {
|
|
436
|
+
status: 'error',
|
|
437
|
+
data: { url: message },
|
|
438
|
+
more: 'https://microlink.io/efatalclient',
|
|
439
|
+
code: 'EFATALCLIENT',
|
|
440
|
+
message,
|
|
441
|
+
url
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
513
445
|
|
|
514
|
-
|
|
446
|
+
const factory$1 = ({
|
|
447
|
+
VERSION,
|
|
448
|
+
MicrolinkError,
|
|
449
|
+
isUrlHttp,
|
|
450
|
+
stringify,
|
|
451
|
+
got,
|
|
452
|
+
flatten
|
|
453
|
+
}) => {
|
|
454
|
+
const assertUrl = (url = '') => {
|
|
455
|
+
if (!isUrlHttp(url)) {
|
|
456
|
+
const message = `The \`url\` as \`${url}\` is not valid. Ensure it has protocol (http or https) and hostname.`
|
|
457
|
+
throw new MicrolinkError({
|
|
458
|
+
status: 'fail',
|
|
459
|
+
data: { url: message },
|
|
460
|
+
more: 'https://microlink.io/docs/api/api-parameters/url',
|
|
461
|
+
code: 'EINVALURLCLIENT',
|
|
462
|
+
message,
|
|
463
|
+
url
|
|
464
|
+
})
|
|
465
|
+
}
|
|
466
|
+
}
|
|
515
467
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
468
|
+
const mapRules = rules => {
|
|
469
|
+
if (!isObject(rules)) return
|
|
470
|
+
const flatRules = flatten(rules)
|
|
471
|
+
return Object.keys(flatRules).reduce(
|
|
472
|
+
(acc, key) => ({ ...acc, [`data.${key}`]: flatRules[key].toString() }),
|
|
473
|
+
{}
|
|
474
|
+
)
|
|
475
|
+
}
|
|
520
476
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
477
|
+
const fetchFromApi = async (apiUrl, opts = {}, retryCount = 0) => {
|
|
478
|
+
try {
|
|
479
|
+
const response = await got(apiUrl, opts)
|
|
480
|
+
return opts.responseType === 'buffer'
|
|
481
|
+
? { body: response.body, response }
|
|
482
|
+
: { ...response.body, response }
|
|
483
|
+
} catch (err) {
|
|
484
|
+
const { response = {} } = err
|
|
485
|
+
const {
|
|
486
|
+
statusCode,
|
|
487
|
+
body: rawBody,
|
|
488
|
+
headers,
|
|
489
|
+
url: uri = apiUrl
|
|
490
|
+
} = response
|
|
491
|
+
const isBuffer = Buffer.isBuffer(rawBody)
|
|
525
492
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
493
|
+
const body =
|
|
494
|
+
isObject(rawBody) && !isBuffer
|
|
495
|
+
? rawBody
|
|
496
|
+
: parseBody(isBuffer ? rawBody.toString() : rawBody, err, uri)
|
|
529
497
|
|
|
530
|
-
|
|
498
|
+
if (body.code === 'EFATALCLIENT' && retryCount++ < 2) {
|
|
499
|
+
return fetchFromApi(apiUrl, opts, retryCount)
|
|
531
500
|
}
|
|
532
501
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
!this._options.retry.statusCodes.includes(error.response.status)
|
|
543
|
-
) {
|
|
544
|
-
return 0
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
const retryAfter = error.response.headers.get('Retry-After')
|
|
548
|
-
if (
|
|
549
|
-
retryAfter &&
|
|
550
|
-
this._options.retry.afterStatusCodes.includes(
|
|
551
|
-
error.response.status
|
|
552
|
-
)
|
|
553
|
-
) {
|
|
554
|
-
let after = Number(retryAfter)
|
|
555
|
-
if (Number.isNaN(after)) {
|
|
556
|
-
after = Date.parse(retryAfter) - Date.now()
|
|
557
|
-
} else {
|
|
558
|
-
after *= 1000
|
|
559
|
-
}
|
|
502
|
+
throw MicrolinkError({
|
|
503
|
+
...body,
|
|
504
|
+
message: body.message,
|
|
505
|
+
url: uri,
|
|
506
|
+
statusCode,
|
|
507
|
+
headers
|
|
508
|
+
})
|
|
509
|
+
}
|
|
510
|
+
}
|
|
560
511
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
512
|
+
const getApiUrl = (
|
|
513
|
+
url,
|
|
514
|
+
{ data, apiKey, endpoint, retry, cache, ...opts } = {},
|
|
515
|
+
{ responseType = 'json', headers: gotHeaders, ...gotOpts } = {}
|
|
516
|
+
) => {
|
|
517
|
+
const isPro = !!apiKey
|
|
518
|
+
const apiEndpoint = endpoint || ENDPOINT[isPro ? 'PRO' : 'FREE']
|
|
567
519
|
|
|
568
|
-
|
|
569
|
-
|
|
520
|
+
const apiUrl = `${apiEndpoint}?${stringify({
|
|
521
|
+
url,
|
|
522
|
+
...mapRules(data),
|
|
523
|
+
...flatten(opts)
|
|
524
|
+
})}`
|
|
570
525
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
526
|
+
const headers = isPro
|
|
527
|
+
? { ...gotHeaders, 'x-api-key': apiKey }
|
|
528
|
+
: { ...gotHeaders }
|
|
529
|
+
return [apiUrl, { ...gotOpts, responseType, cache, retry, headers }]
|
|
530
|
+
}
|
|
575
531
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
532
|
+
const createMql = defaultOpts => async (url, opts, gotOpts) => {
|
|
533
|
+
assertUrl(url)
|
|
534
|
+
const [apiUrl, fetchOpts] = getApiUrl(url, opts, {
|
|
535
|
+
...defaultOpts,
|
|
536
|
+
...gotOpts
|
|
537
|
+
})
|
|
538
|
+
return fetchFromApi(apiUrl, fetchOpts)
|
|
539
|
+
}
|
|
579
540
|
|
|
580
|
-
|
|
581
|
-
|
|
541
|
+
const mql = createMql()
|
|
542
|
+
mql.MicrolinkError = MicrolinkError
|
|
543
|
+
mql.getApiUrl = getApiUrl
|
|
544
|
+
mql.fetchFromApi = fetchFromApi
|
|
545
|
+
mql.mapRules = mapRules
|
|
546
|
+
mql.version = VERSION
|
|
547
|
+
mql.stream = got.stream
|
|
548
|
+
mql.buffer = createMql({ responseType: 'buffer' })
|
|
582
549
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
response.json = async () => {
|
|
586
|
-
return this._options.parseJson(await response.text())
|
|
587
|
-
}
|
|
588
|
-
}
|
|
550
|
+
return mql
|
|
551
|
+
}
|
|
589
552
|
|
|
590
|
-
|
|
591
|
-
}
|
|
553
|
+
var factory_1 = factory$1
|
|
592
554
|
|
|
593
|
-
|
|
594
|
-
try {
|
|
595
|
-
return await fn()
|
|
596
|
-
} catch (error) {
|
|
597
|
-
const ms = Math.min(
|
|
598
|
-
this._calculateRetryDelay(error),
|
|
599
|
-
maxSafeTimeout
|
|
600
|
-
)
|
|
601
|
-
if (ms !== 0 && this._retryCount > 0) {
|
|
602
|
-
await delay(ms)
|
|
555
|
+
var ky$1 = { exports: {} }
|
|
603
556
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
error,
|
|
610
|
-
retryCount: this._retryCount
|
|
611
|
-
})
|
|
557
|
+
;(function (module, exports) {
|
|
558
|
+
;(function (global, factory) {
|
|
559
|
+
module.exports = factory()
|
|
560
|
+
})(commonjsGlobal, function () {
|
|
561
|
+
/*! MIT License © Sindre Sorhus */
|
|
612
562
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
563
|
+
const isObject = value => value !== null && typeof value === 'object'
|
|
564
|
+
const supportsAbortController =
|
|
565
|
+
typeof globalThis.AbortController === 'function'
|
|
566
|
+
const supportsStreams = typeof globalThis.ReadableStream === 'function'
|
|
567
|
+
const supportsFormData = typeof globalThis.FormData === 'function'
|
|
618
568
|
|
|
619
|
-
|
|
620
|
-
|
|
569
|
+
const mergeHeaders = (source1, source2) => {
|
|
570
|
+
const result = new globalThis.Headers(source1 || {})
|
|
571
|
+
const isHeadersInstance = source2 instanceof globalThis.Headers
|
|
572
|
+
const source = new globalThis.Headers(source2 || {})
|
|
621
573
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
574
|
+
for (const [key, value] of source) {
|
|
575
|
+
if (
|
|
576
|
+
(isHeadersInstance && value === 'undefined') ||
|
|
577
|
+
value === undefined
|
|
578
|
+
) {
|
|
579
|
+
result.delete(key)
|
|
580
|
+
} else {
|
|
581
|
+
result.set(key, value)
|
|
625
582
|
}
|
|
626
583
|
}
|
|
627
584
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
// eslint-disable-next-line no-await-in-loop
|
|
631
|
-
const result = await hook(this.request, this._options)
|
|
585
|
+
return result
|
|
586
|
+
}
|
|
632
587
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
588
|
+
const deepMerge = (...sources) => {
|
|
589
|
+
let returnValue = {}
|
|
590
|
+
let headers = {}
|
|
591
|
+
|
|
592
|
+
for (const source of sources) {
|
|
593
|
+
if (Array.isArray(source)) {
|
|
594
|
+
if (!Array.isArray(returnValue)) {
|
|
595
|
+
returnValue = []
|
|
636
596
|
}
|
|
637
597
|
|
|
638
|
-
|
|
639
|
-
|
|
598
|
+
returnValue = [...returnValue, ...source]
|
|
599
|
+
} else if (isObject(source)) {
|
|
600
|
+
for (let [key, value] of Object.entries(source)) {
|
|
601
|
+
if (isObject(value) && key in returnValue) {
|
|
602
|
+
value = deepMerge(returnValue[key], value)
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
returnValue = { ...returnValue, [key]: value }
|
|
640
606
|
}
|
|
641
|
-
}
|
|
642
607
|
|
|
643
|
-
|
|
644
|
-
|
|
608
|
+
if (isObject(source.headers)) {
|
|
609
|
+
headers = mergeHeaders(headers, source.headers)
|
|
610
|
+
}
|
|
645
611
|
}
|
|
646
612
|
|
|
647
|
-
|
|
648
|
-
this.request.clone(),
|
|
649
|
-
this.abortController,
|
|
650
|
-
this._options
|
|
651
|
-
)
|
|
613
|
+
returnValue.headers = headers
|
|
652
614
|
}
|
|
653
615
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
616
|
+
return returnValue
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
const requestMethods = ['get', 'post', 'put', 'patch', 'head', 'delete']
|
|
658
620
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
621
|
+
const responseTypes = {
|
|
622
|
+
json: 'application/json',
|
|
623
|
+
text: 'text/*',
|
|
624
|
+
formData: 'multipart/form-data',
|
|
625
|
+
arrayBuffer: '*/*',
|
|
626
|
+
blob: '*/*'
|
|
627
|
+
}
|
|
663
628
|
|
|
664
|
-
|
|
665
|
-
onDownloadProgress(
|
|
666
|
-
{ percent: 0, transferredBytes: 0, totalBytes },
|
|
667
|
-
new Uint8Array()
|
|
668
|
-
)
|
|
669
|
-
}
|
|
629
|
+
const retryMethods = ['get', 'put', 'head', 'delete', 'options', 'trace']
|
|
670
630
|
|
|
671
|
-
|
|
672
|
-
const { done, value } = await reader.read()
|
|
673
|
-
if (done) {
|
|
674
|
-
controller.close()
|
|
675
|
-
return
|
|
676
|
-
}
|
|
631
|
+
const retryStatusCodes = [408, 413, 429, 500, 502, 503, 504]
|
|
677
632
|
|
|
678
|
-
|
|
679
|
-
transferredBytes += value.byteLength
|
|
680
|
-
const percent =
|
|
681
|
-
totalBytes === 0 ? 0 : transferredBytes / totalBytes
|
|
682
|
-
onDownloadProgress(
|
|
683
|
-
{ percent, transferredBytes, totalBytes },
|
|
684
|
-
value
|
|
685
|
-
)
|
|
686
|
-
}
|
|
633
|
+
const retryAfterStatusCodes = [413, 429, 503]
|
|
687
634
|
|
|
688
|
-
|
|
689
|
-
await read()
|
|
690
|
-
}
|
|
635
|
+
const stop = Symbol('stop')
|
|
691
636
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
637
|
+
class HTTPError extends Error {
|
|
638
|
+
constructor (response, request, options) {
|
|
639
|
+
// Set the message to the status text, such as Unauthorized,
|
|
640
|
+
// with some fallbacks. This message should never be undefined.
|
|
641
|
+
super(
|
|
642
|
+
response.statusText ||
|
|
643
|
+
String(
|
|
644
|
+
response.status === 0 || response.status
|
|
645
|
+
? response.status
|
|
646
|
+
: 'Unknown response error'
|
|
647
|
+
)
|
|
695
648
|
)
|
|
649
|
+
this.name = 'HTTPError'
|
|
650
|
+
this.response = response
|
|
651
|
+
this.request = request
|
|
652
|
+
this.options = options
|
|
696
653
|
}
|
|
697
654
|
}
|
|
698
655
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
) {
|
|
705
|
-
throw new TypeError('The `options` argument must be an object')
|
|
706
|
-
}
|
|
656
|
+
class TimeoutError extends Error {
|
|
657
|
+
constructor (request) {
|
|
658
|
+
super('Request timed out')
|
|
659
|
+
this.name = 'TimeoutError'
|
|
660
|
+
this.request = request
|
|
707
661
|
}
|
|
708
|
-
|
|
709
|
-
return deepMerge({}, ...sources)
|
|
710
662
|
}
|
|
711
663
|
|
|
712
|
-
const
|
|
713
|
-
const ky = (input, options) =>
|
|
714
|
-
new Ky(input, validateAndMerge(defaults, options))
|
|
664
|
+
const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
|
|
715
665
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
666
|
+
// `Promise.race()` workaround (#91)
|
|
667
|
+
const timeout = (request, abortController, options) =>
|
|
668
|
+
new Promise((resolve, reject) => {
|
|
669
|
+
const timeoutID = setTimeout(() => {
|
|
670
|
+
if (abortController) {
|
|
671
|
+
abortController.abort()
|
|
672
|
+
}
|
|
720
673
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
ky.create = newDefaults => createInstance(validateAndMerge(newDefaults))
|
|
724
|
-
ky.extend = newDefaults =>
|
|
725
|
-
createInstance(validateAndMerge(defaults, newDefaults))
|
|
726
|
-
ky.stop = stop
|
|
674
|
+
reject(new TimeoutError(request))
|
|
675
|
+
}, options.timeout)
|
|
727
676
|
|
|
728
|
-
|
|
729
|
-
|
|
677
|
+
/* eslint-disable promise/prefer-await-to-then */
|
|
678
|
+
options
|
|
679
|
+
.fetch(request)
|
|
680
|
+
.then(resolve)
|
|
681
|
+
.catch(reject)
|
|
682
|
+
.then(() => {
|
|
683
|
+
clearTimeout(timeoutID)
|
|
684
|
+
})
|
|
685
|
+
/* eslint-enable promise/prefer-await-to-then */
|
|
686
|
+
})
|
|
730
687
|
|
|
731
|
-
const
|
|
688
|
+
const normalizeRequestMethod = input =>
|
|
689
|
+
requestMethods.includes(input) ? input.toUpperCase() : input
|
|
732
690
|
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
691
|
+
const defaultRetryOptions = {
|
|
692
|
+
limit: 2,
|
|
693
|
+
methods: retryMethods,
|
|
694
|
+
statusCodes: retryStatusCodes,
|
|
695
|
+
afterStatusCodes: retryAfterStatusCodes
|
|
696
|
+
}
|
|
736
697
|
|
|
737
|
-
|
|
698
|
+
const normalizeRetryOptions = (retry = {}) => {
|
|
699
|
+
if (typeof retry === 'number') {
|
|
700
|
+
return {
|
|
701
|
+
...defaultRetryOptions,
|
|
702
|
+
limit: retry
|
|
703
|
+
}
|
|
704
|
+
}
|
|
738
705
|
|
|
739
|
-
|
|
706
|
+
if (retry.methods && !Array.isArray(retry.methods)) {
|
|
707
|
+
throw new Error('retry.methods must be an array')
|
|
708
|
+
}
|
|
740
709
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
})
|
|
710
|
+
if (retry.statusCodes && !Array.isArray(retry.statusCodes)) {
|
|
711
|
+
throw new Error('retry.statusCodes must be an array')
|
|
712
|
+
}
|
|
745
713
|
|
|
746
|
-
|
|
714
|
+
return {
|
|
715
|
+
...defaultRetryOptions,
|
|
716
|
+
...retry,
|
|
717
|
+
afterStatusCodes: retryAfterStatusCodes
|
|
718
|
+
}
|
|
719
|
+
}
|
|
747
720
|
|
|
748
|
-
|
|
721
|
+
// The maximum value of a 32bit int (see issue #117)
|
|
722
|
+
const maxSafeTimeout = 2147483647
|
|
749
723
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
724
|
+
class Ky {
|
|
725
|
+
constructor (input, options = {}) {
|
|
726
|
+
this._retryCount = 0
|
|
727
|
+
this._input = input
|
|
728
|
+
this._options = {
|
|
729
|
+
// TODO: credentials can be removed when the spec change is implemented in all browsers. Context: https://www.chromestatus.com/feature/4539473312350208
|
|
730
|
+
credentials: this._input.credentials || 'same-origin',
|
|
731
|
+
...options,
|
|
732
|
+
headers: mergeHeaders(this._input.headers, options.headers),
|
|
733
|
+
hooks: deepMerge(
|
|
734
|
+
{
|
|
735
|
+
beforeRequest: [],
|
|
736
|
+
beforeRetry: [],
|
|
737
|
+
afterResponse: []
|
|
738
|
+
},
|
|
739
|
+
options.hooks
|
|
740
|
+
),
|
|
741
|
+
method: normalizeRequestMethod(
|
|
742
|
+
options.method || this._input.method
|
|
743
|
+
),
|
|
744
|
+
prefixUrl: String(options.prefixUrl || ''),
|
|
745
|
+
retry: normalizeRetryOptions(options.retry),
|
|
746
|
+
throwHttpErrors: options.throwHttpErrors !== false,
|
|
747
|
+
timeout:
|
|
748
|
+
typeof options.timeout === 'undefined' ? 10000 : options.timeout,
|
|
749
|
+
fetch: options.fetch || globalThis.fetch.bind(globalThis)
|
|
750
|
+
}
|
|
753
751
|
|
|
754
|
-
|
|
755
|
-
|
|
752
|
+
if (
|
|
753
|
+
typeof this._input !== 'string' &&
|
|
754
|
+
!(
|
|
755
|
+
this._input instanceof URL ||
|
|
756
|
+
this._input instanceof globalThis.Request
|
|
757
|
+
)
|
|
758
|
+
) {
|
|
759
|
+
throw new TypeError('`input` must be a string, URL, or Request')
|
|
760
|
+
}
|
|
756
761
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
return true
|
|
764
|
-
}
|
|
762
|
+
if (this._options.prefixUrl && typeof this._input === 'string') {
|
|
763
|
+
if (this._input.startsWith('/')) {
|
|
764
|
+
throw new Error(
|
|
765
|
+
'`input` must not begin with a slash when using `prefixUrl`'
|
|
766
|
+
)
|
|
767
|
+
}
|
|
765
768
|
|
|
766
|
-
|
|
769
|
+
if (!this._options.prefixUrl.endsWith('/')) {
|
|
770
|
+
this._options.prefixUrl += '/'
|
|
771
|
+
}
|
|
767
772
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
match.includes('.app/Contents/Resources/electron.asar') ||
|
|
771
|
-
match.includes('.app/Contents/Resources/default_app.asar')
|
|
772
|
-
) {
|
|
773
|
-
return false
|
|
774
|
-
}
|
|
773
|
+
this._input = this._options.prefixUrl + this._input
|
|
774
|
+
}
|
|
775
775
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
)
|
|
784
|
-
}
|
|
776
|
+
if (supportsAbortController) {
|
|
777
|
+
this.abortController = new globalThis.AbortController()
|
|
778
|
+
if (this._options.signal) {
|
|
779
|
+
this._options.signal.addEventListener('abort', () => {
|
|
780
|
+
this.abortController.abort()
|
|
781
|
+
})
|
|
782
|
+
}
|
|
785
783
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
.join('\n')
|
|
789
|
-
}
|
|
784
|
+
this._options.signal = this.abortController.signal
|
|
785
|
+
}
|
|
790
786
|
|
|
791
|
-
|
|
792
|
-
// `Function#length` should reflect the parameters of `to` not `from` since we keep its body.
|
|
793
|
-
// `Function#prototype` is non-writable and non-configurable so can never be modified.
|
|
794
|
-
if (property === 'length' || property === 'prototype') {
|
|
795
|
-
return
|
|
796
|
-
}
|
|
787
|
+
this.request = new globalThis.Request(this._input, this._options)
|
|
797
788
|
|
|
798
|
-
|
|
799
|
-
|
|
789
|
+
if (this._options.searchParams) {
|
|
790
|
+
const textSearchParams =
|
|
791
|
+
typeof this._options.searchParams === 'string'
|
|
792
|
+
? this._options.searchParams.replace(/^\?/, '')
|
|
793
|
+
: new URLSearchParams(this._options.searchParams).toString()
|
|
794
|
+
const searchParams = '?' + textSearchParams
|
|
795
|
+
const url = this.request.url.replace(
|
|
796
|
+
/(?:\?.*?)?(?=#|$)/,
|
|
797
|
+
searchParams
|
|
798
|
+
)
|
|
800
799
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
800
|
+
// To provide correct form boundary, Content-Type header should be deleted each time when new Request instantiated from another one
|
|
801
|
+
if (
|
|
802
|
+
((supportsFormData &&
|
|
803
|
+
this._options.body instanceof globalThis.FormData) ||
|
|
804
|
+
this._options.body instanceof URLSearchParams) &&
|
|
805
|
+
!(this._options.headers && this._options.headers['content-type'])
|
|
806
|
+
) {
|
|
807
|
+
this.request.headers.delete('content-type')
|
|
808
|
+
}
|
|
807
809
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
+
this.request = new globalThis.Request(
|
|
811
|
+
new globalThis.Request(url, this.request),
|
|
812
|
+
this._options
|
|
813
|
+
)
|
|
814
|
+
}
|
|
810
815
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
(toDescriptor.writable === fromDescriptor.writable &&
|
|
819
|
-
toDescriptor.enumerable === fromDescriptor.enumerable &&
|
|
820
|
-
toDescriptor.configurable === fromDescriptor.configurable &&
|
|
821
|
-
(toDescriptor.writable || toDescriptor.value === fromDescriptor.value))
|
|
822
|
-
)
|
|
823
|
-
}
|
|
816
|
+
if (this._options.json !== undefined) {
|
|
817
|
+
this._options.body = JSON.stringify(this._options.json)
|
|
818
|
+
this.request.headers.set('content-type', 'application/json')
|
|
819
|
+
this.request = new globalThis.Request(this.request, {
|
|
820
|
+
body: this._options.body
|
|
821
|
+
})
|
|
822
|
+
}
|
|
824
823
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
824
|
+
const fn = async () => {
|
|
825
|
+
if (this._options.timeout > maxSafeTimeout) {
|
|
826
|
+
throw new RangeError(
|
|
827
|
+
`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`
|
|
828
|
+
)
|
|
829
|
+
}
|
|
830
830
|
|
|
831
|
-
|
|
832
|
-
|
|
831
|
+
await delay(1)
|
|
832
|
+
let response = await this._fetch()
|
|
833
833
|
|
|
834
|
-
|
|
835
|
-
|
|
834
|
+
for (const hook of this._options.hooks.afterResponse) {
|
|
835
|
+
// eslint-disable-next-line no-await-in-loop
|
|
836
|
+
const modifiedResponse = await hook(
|
|
837
|
+
this.request,
|
|
838
|
+
this._options,
|
|
839
|
+
this._decorateResponse(response.clone())
|
|
840
|
+
)
|
|
836
841
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
const toStringName = Object.getOwnPropertyDescriptor(
|
|
842
|
-
Function.prototype.toString,
|
|
843
|
-
'name'
|
|
844
|
-
)
|
|
842
|
+
if (modifiedResponse instanceof globalThis.Response) {
|
|
843
|
+
response = modifiedResponse
|
|
844
|
+
}
|
|
845
|
+
}
|
|
845
846
|
|
|
846
|
-
|
|
847
|
-
// We use `bind()` instead of a closure for the same reason.
|
|
848
|
-
// Calling `from.toString()` early also allows caching it in case `to.toString()` is called several times.
|
|
849
|
-
const changeToString = (to, from, name) => {
|
|
850
|
-
const withName = name === '' ? '' : `with ${name.trim()}() `
|
|
851
|
-
const newToString = wrappedToString.bind(null, withName, from.toString())
|
|
852
|
-
// Ensure `to.toString.toString` is non-enumerable and has the same `same`
|
|
853
|
-
Object.defineProperty(newToString, 'name', toStringName)
|
|
854
|
-
Object.defineProperty(to, 'toString', {
|
|
855
|
-
...toStringDescriptor,
|
|
856
|
-
value: newToString
|
|
857
|
-
})
|
|
858
|
-
}
|
|
847
|
+
this._decorateResponse(response)
|
|
859
848
|
|
|
860
|
-
|
|
861
|
-
|
|
849
|
+
if (!response.ok && this._options.throwHttpErrors) {
|
|
850
|
+
throw new HTTPError(response, this.request, this._options)
|
|
851
|
+
}
|
|
862
852
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
853
|
+
// If `onDownloadProgress` is passed, it uses the stream API internally
|
|
854
|
+
/* istanbul ignore next */
|
|
855
|
+
if (this._options.onDownloadProgress) {
|
|
856
|
+
if (typeof this._options.onDownloadProgress !== 'function') {
|
|
857
|
+
throw new TypeError(
|
|
858
|
+
'The `onDownloadProgress` option must be a function'
|
|
859
|
+
)
|
|
860
|
+
}
|
|
866
861
|
|
|
867
|
-
|
|
868
|
-
|
|
862
|
+
if (!supportsStreams) {
|
|
863
|
+
throw new Error(
|
|
864
|
+
'Streams are not supported in your environment. `ReadableStream` is missing.'
|
|
865
|
+
)
|
|
866
|
+
}
|
|
869
867
|
|
|
870
|
-
|
|
871
|
-
|
|
868
|
+
return this._stream(
|
|
869
|
+
response.clone(),
|
|
870
|
+
this._options.onDownloadProgress
|
|
871
|
+
)
|
|
872
|
+
}
|
|
872
873
|
|
|
873
|
-
|
|
874
|
+
return response
|
|
875
|
+
}
|
|
874
876
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
inherits: (ctor, superCtor) => {
|
|
880
|
-
ctor.super_ = superCtor
|
|
881
|
-
ctor.prototype = Object.create(superCtor.prototype, {
|
|
882
|
-
constructor: {
|
|
883
|
-
value: ctor,
|
|
884
|
-
enumerable: false,
|
|
885
|
-
writable: true,
|
|
886
|
-
configurable: true
|
|
887
|
-
}
|
|
888
|
-
})
|
|
889
|
-
}
|
|
890
|
-
}
|
|
877
|
+
const isRetriableMethod = this._options.retry.methods.includes(
|
|
878
|
+
this.request.method.toLowerCase()
|
|
879
|
+
)
|
|
880
|
+
const result = isRetriableMethod ? this._retry(fn) : fn()
|
|
891
881
|
|
|
892
|
-
|
|
882
|
+
for (const [type, mimeType] of Object.entries(responseTypes)) {
|
|
883
|
+
result[type] = async () => {
|
|
884
|
+
this.request.headers.set(
|
|
885
|
+
'accept',
|
|
886
|
+
this.request.headers.get('accept') || mimeType
|
|
887
|
+
)
|
|
893
888
|
|
|
894
|
-
|
|
895
|
-
Object.assign(error, ...props)
|
|
889
|
+
const response = (await result).clone()
|
|
896
890
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
891
|
+
if (type === 'json') {
|
|
892
|
+
if (response.status === 204) {
|
|
893
|
+
return ''
|
|
894
|
+
}
|
|
900
895
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
896
|
+
if (options.parseJson) {
|
|
897
|
+
return options.parseJson(await response.text())
|
|
898
|
+
}
|
|
899
|
+
}
|
|
905
900
|
|
|
906
|
-
|
|
901
|
+
return response[type]()
|
|
902
|
+
}
|
|
903
|
+
}
|
|
907
904
|
|
|
908
|
-
|
|
909
|
-
|
|
905
|
+
return result
|
|
906
|
+
}
|
|
910
907
|
|
|
911
|
-
|
|
912
|
-
|
|
908
|
+
_calculateRetryDelay (error) {
|
|
909
|
+
this._retryCount++
|
|
913
910
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
911
|
+
if (
|
|
912
|
+
this._retryCount < this._options.retry.limit &&
|
|
913
|
+
!(error instanceof TimeoutError)
|
|
914
|
+
) {
|
|
915
|
+
if (error instanceof HTTPError) {
|
|
916
|
+
if (
|
|
917
|
+
!this._options.retry.statusCodes.includes(error.response.status)
|
|
918
|
+
) {
|
|
919
|
+
return 0
|
|
920
|
+
}
|
|
919
921
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
922
|
+
const retryAfter = error.response.headers.get('Retry-After')
|
|
923
|
+
if (
|
|
924
|
+
retryAfter &&
|
|
925
|
+
this._options.retry.afterStatusCodes.includes(
|
|
926
|
+
error.response.status
|
|
927
|
+
)
|
|
928
|
+
) {
|
|
929
|
+
let after = Number(retryAfter)
|
|
930
|
+
if (Number.isNaN(after)) {
|
|
931
|
+
after = Date.parse(retryAfter) - Date.now()
|
|
932
|
+
} else {
|
|
933
|
+
after *= 1000
|
|
934
|
+
}
|
|
923
935
|
|
|
924
|
-
|
|
925
|
-
|
|
936
|
+
if (
|
|
937
|
+
typeof this._options.retry.maxRetryAfter !== 'undefined' &&
|
|
938
|
+
after > this._options.retry.maxRetryAfter
|
|
939
|
+
) {
|
|
940
|
+
return 0
|
|
941
|
+
}
|
|
926
942
|
|
|
927
|
-
|
|
928
|
-
|
|
943
|
+
return after
|
|
944
|
+
}
|
|
929
945
|
|
|
930
|
-
|
|
946
|
+
if (error.response.status === 413) {
|
|
947
|
+
return 0
|
|
948
|
+
}
|
|
949
|
+
}
|
|
931
950
|
|
|
932
|
-
|
|
933
|
-
|
|
951
|
+
const BACKOFF_FACTOR = 0.3
|
|
952
|
+
return BACKOFF_FACTOR * 2 ** (this._retryCount - 1) * 1000
|
|
953
|
+
}
|
|
934
954
|
|
|
935
|
-
|
|
955
|
+
return 0
|
|
956
|
+
}
|
|
936
957
|
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
958
|
+
_decorateResponse (response) {
|
|
959
|
+
if (this._options.parseJson) {
|
|
960
|
+
response.json = async () => {
|
|
961
|
+
return this._options.parseJson(await response.text())
|
|
962
|
+
}
|
|
963
|
+
}
|
|
941
964
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
}
|
|
965
|
+
return response
|
|
966
|
+
}
|
|
945
967
|
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
968
|
+
async _retry (fn) {
|
|
969
|
+
try {
|
|
970
|
+
return await fn()
|
|
971
|
+
} catch (error) {
|
|
972
|
+
const ms = Math.min(
|
|
973
|
+
this._calculateRetryDelay(error),
|
|
974
|
+
maxSafeTimeout
|
|
975
|
+
)
|
|
976
|
+
if (ms !== 0 && this._retryCount > 0) {
|
|
977
|
+
await delay(ms)
|
|
952
978
|
|
|
953
|
-
|
|
954
|
-
|
|
979
|
+
for (const hook of this._options.hooks.beforeRetry) {
|
|
980
|
+
// eslint-disable-next-line no-await-in-loop
|
|
981
|
+
const hookResult = await hook({
|
|
982
|
+
request: this.request,
|
|
983
|
+
options: this._options,
|
|
984
|
+
error,
|
|
985
|
+
retryCount: this._retryCount
|
|
986
|
+
})
|
|
955
987
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
988
|
+
// If `stop` is returned from the hook, the retry process is stopped
|
|
989
|
+
if (hookResult === stop) {
|
|
990
|
+
return
|
|
991
|
+
}
|
|
992
|
+
}
|
|
960
993
|
|
|
961
|
-
|
|
994
|
+
return this._retry(fn)
|
|
995
|
+
}
|
|
962
996
|
|
|
963
|
-
|
|
964
|
-
|
|
997
|
+
if (this._options.throwHttpErrors) {
|
|
998
|
+
throw error
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
965
1002
|
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1003
|
+
async _fetch () {
|
|
1004
|
+
for (const hook of this._options.hooks.beforeRequest) {
|
|
1005
|
+
// eslint-disable-next-line no-await-in-loop
|
|
1006
|
+
const result = await hook(this.request, this._options)
|
|
970
1007
|
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
lib.exports.syntax = createErrorClass(SyntaxError)
|
|
976
|
-
lib.exports.reference = createErrorClass(ReferenceError)
|
|
977
|
-
lib.exports.uri = createErrorClass(URIError)
|
|
1008
|
+
if (result instanceof Request) {
|
|
1009
|
+
this.request = result
|
|
1010
|
+
break
|
|
1011
|
+
}
|
|
978
1012
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
1013
|
+
if (result instanceof Response) {
|
|
1014
|
+
return result
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
983
1017
|
|
|
984
|
-
|
|
1018
|
+
if (this._options.timeout === false) {
|
|
1019
|
+
return this._options.fetch(this.request.clone())
|
|
1020
|
+
}
|
|
985
1021
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1022
|
+
return timeout(
|
|
1023
|
+
this.request.clone(),
|
|
1024
|
+
this.abortController,
|
|
1025
|
+
this._options
|
|
1026
|
+
)
|
|
1027
|
+
}
|
|
990
1028
|
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
const message = input || error.message
|
|
1029
|
+
/* istanbul ignore next */
|
|
1030
|
+
_stream (response, onDownloadProgress) {
|
|
1031
|
+
const totalBytes = Number(response.headers.get('content-length')) || 0
|
|
1032
|
+
let transferredBytes = 0
|
|
996
1033
|
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
code: 'EFATAL',
|
|
1002
|
-
message,
|
|
1003
|
-
url
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1034
|
+
return new globalThis.Response(
|
|
1035
|
+
new globalThis.ReadableStream({
|
|
1036
|
+
async start (controller) {
|
|
1037
|
+
const reader = response.body.getReader()
|
|
1007
1038
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
flatten
|
|
1015
|
-
}) => {
|
|
1016
|
-
const assertUrl = (url = '') => {
|
|
1017
|
-
if (!isUrlHttp(url)) {
|
|
1018
|
-
const message = `The \`url\` as \`${url}\` is not valid. Ensure it has protocol (http or https) and hostname.`
|
|
1019
|
-
throw new MicrolinkError({
|
|
1020
|
-
status: 'fail',
|
|
1021
|
-
data: { url: message },
|
|
1022
|
-
more: 'https://microlink.io/docs/api/api-parameters/url',
|
|
1023
|
-
code: 'EINVALURLCLIENT',
|
|
1024
|
-
message,
|
|
1025
|
-
url
|
|
1026
|
-
})
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1039
|
+
if (onDownloadProgress) {
|
|
1040
|
+
onDownloadProgress(
|
|
1041
|
+
{ percent: 0, transferredBytes: 0, totalBytes },
|
|
1042
|
+
new Uint8Array()
|
|
1043
|
+
)
|
|
1044
|
+
}
|
|
1029
1045
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
)
|
|
1037
|
-
}
|
|
1046
|
+
async function read () {
|
|
1047
|
+
const { done, value } = await reader.read()
|
|
1048
|
+
if (done) {
|
|
1049
|
+
controller.close()
|
|
1050
|
+
return
|
|
1051
|
+
}
|
|
1038
1052
|
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
statusCode,
|
|
1049
|
-
body: rawBody,
|
|
1050
|
-
headers,
|
|
1051
|
-
url: uri = apiUrl
|
|
1052
|
-
} = response
|
|
1053
|
+
if (onDownloadProgress) {
|
|
1054
|
+
transferredBytes += value.byteLength
|
|
1055
|
+
const percent =
|
|
1056
|
+
totalBytes === 0 ? 0 : transferredBytes / totalBytes
|
|
1057
|
+
onDownloadProgress(
|
|
1058
|
+
{ percent, transferredBytes, totalBytes },
|
|
1059
|
+
value
|
|
1060
|
+
)
|
|
1061
|
+
}
|
|
1053
1062
|
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
: parseBody(rawBody, err, uri)
|
|
1063
|
+
controller.enqueue(value)
|
|
1064
|
+
await read()
|
|
1065
|
+
}
|
|
1058
1066
|
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
headers
|
|
1065
|
-
})
|
|
1067
|
+
await read()
|
|
1068
|
+
}
|
|
1069
|
+
})
|
|
1070
|
+
)
|
|
1071
|
+
}
|
|
1066
1072
|
}
|
|
1067
|
-
}
|
|
1068
1073
|
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1074
|
+
const validateAndMerge = (...sources) => {
|
|
1075
|
+
for (const source of sources) {
|
|
1076
|
+
if (
|
|
1077
|
+
(!isObject(source) || Array.isArray(source)) &&
|
|
1078
|
+
typeof source !== 'undefined'
|
|
1079
|
+
) {
|
|
1080
|
+
throw new TypeError('The `options` argument must be an object')
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1076
1083
|
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
...mapRules(data),
|
|
1080
|
-
...flatten(pickBy(opts))
|
|
1081
|
-
})}`
|
|
1084
|
+
return deepMerge({}, ...sources)
|
|
1085
|
+
}
|
|
1082
1086
|
|
|
1083
|
-
const
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
return [apiUrl, { ...gotOpts, responseType, cache, retry, headers }]
|
|
1087
|
-
}
|
|
1087
|
+
const createInstance = defaults => {
|
|
1088
|
+
const ky = (input, options) =>
|
|
1089
|
+
new Ky(input, validateAndMerge(defaults, options))
|
|
1088
1090
|
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
...gotOpts
|
|
1094
|
-
})
|
|
1095
|
-
return fetchFromApi(apiUrl, fetchOpts)
|
|
1096
|
-
}
|
|
1091
|
+
for (const method of requestMethods) {
|
|
1092
|
+
ky[method] = (input, options) =>
|
|
1093
|
+
new Ky(input, validateAndMerge(defaults, options, { method }))
|
|
1094
|
+
}
|
|
1097
1095
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
mql.stream = got.stream
|
|
1105
|
-
mql.buffer = createMql({ responseType: 'buffer' })
|
|
1096
|
+
ky.HTTPError = HTTPError
|
|
1097
|
+
ky.TimeoutError = TimeoutError
|
|
1098
|
+
ky.create = newDefaults => createInstance(validateAndMerge(newDefaults))
|
|
1099
|
+
ky.extend = newDefaults =>
|
|
1100
|
+
createInstance(validateAndMerge(defaults, newDefaults))
|
|
1101
|
+
ky.stop = stop
|
|
1106
1102
|
|
|
1107
|
-
|
|
1108
|
-
|
|
1103
|
+
return ky
|
|
1104
|
+
}
|
|
1109
1105
|
|
|
1110
|
-
|
|
1106
|
+
const ky = createInstance()
|
|
1107
|
+
|
|
1108
|
+
return ky
|
|
1109
|
+
})
|
|
1110
|
+
})(ky$1)
|
|
1111
1111
|
|
|
1112
1112
|
const isUrlHttp = lightweight
|
|
1113
1113
|
const { flattie: flatten } = dist
|
|
1114
1114
|
const { encode: stringify } = require$$2
|
|
1115
|
-
const ky = ky$1.exports
|
|
1116
1115
|
const whoops = lib.exports
|
|
1117
1116
|
|
|
1118
1117
|
const factory = factory_1
|
|
1118
|
+
const ky = ky$1.exports
|
|
1119
1119
|
|
|
1120
1120
|
const MicrolinkError = whoops('MicrolinkError')
|
|
1121
1121
|
|
|
@@ -1153,13 +1153,13 @@
|
|
|
1153
1153
|
stringify,
|
|
1154
1154
|
got,
|
|
1155
1155
|
flatten,
|
|
1156
|
-
VERSION: '0.
|
|
1156
|
+
VERSION: '0.10.13'
|
|
1157
1157
|
})
|
|
1158
1158
|
|
|
1159
1159
|
var browser = factory_1$1({
|
|
1160
1160
|
mql: browser$1,
|
|
1161
1161
|
toCompress: code => code.toString(),
|
|
1162
|
-
VERSION: '0.1.
|
|
1162
|
+
VERSION: '0.1.2'
|
|
1163
1163
|
})
|
|
1164
1164
|
|
|
1165
1165
|
return browser
|