+import { basename, extname, isAbsolute, join, resolve } from 'path'
+import { createPrivateKey as createPrivateKey_1, getPublicKey as getPublicKey_1 } from 'pem'
+import { pipeline } from 'stream'
+import { URL } from 'url'
+import { promisify } from 'util'
+
+const objectConverter = (oldObject: any, keyConverter: (e: string) => string, valueConverter: (e: any) => any) => {
+ if (!oldObject || typeof oldObject !== 'object') {
+ return valueConverter(oldObject)
+ }
+
+ if (Array.isArray(oldObject)) {
+ return oldObject.map(e => objectConverter(e, keyConverter, valueConverter))
+ }
+
+ const newObject = {}
+ Object.keys(oldObject).forEach(oldKey => {
+ const newKey = keyConverter(oldKey)
+ newObject[newKey] = objectConverter(oldObject[oldKey], keyConverter, valueConverter)
+ })
+
+ return newObject
+}
+
+function mapToJSON (map: Map<any, any>) {
+ const obj: any = {}
+
+ for (const [ k, v ] of map) {
+ obj[k] = v
+ }
+
+ return obj
+}
+
+// ---------------------------------------------------------------------------
+
+const timeTable = {
+ ms: 1,
+ second: 1000,
+ minute: 60000,
+ hour: 3600000,
+ day: 3600000 * 24,
+ week: 3600000 * 24 * 7,
+ month: 3600000 * 24 * 30
+}
+
+export function parseDurationToMs (duration: number | string): number {
+ if (duration === null) return null
+ if (typeof duration === 'number') return duration
+
+ if (typeof duration === 'string') {
+ const split = duration.match(/^([\d.,]+)\s?(\w+)$/)
+
+ if (split.length === 3) {
+ const len = parseFloat(split[1])
+ let unit = split[2].replace(/s$/i, '').toLowerCase()
+ if (unit === 'm') {
+ unit = 'ms'
+ }
+
+ return (len || 1) * (timeTable[unit] || 0)
+ }
+ }
+
+ throw new Error(`Duration ${duration} could not be properly parsed`)
+}
+
+export function parseBytes (value: string | number): number {
+ if (typeof value === 'number') return value
+
+ const tgm = /^(\d+)\s*TB\s*(\d+)\s*GB\s*(\d+)\s*MB$/
+ const tg = /^(\d+)\s*TB\s*(\d+)\s*GB$/
+ const tm = /^(\d+)\s*TB\s*(\d+)\s*MB$/
+ const gm = /^(\d+)\s*GB\s*(\d+)\s*MB$/
+ const t = /^(\d+)\s*TB$/
+ const g = /^(\d+)\s*GB$/
+ const m = /^(\d+)\s*MB$/
+ const b = /^(\d+)\s*B$/
+ let match
+
+ if (value.match(tgm)) {
+ match = value.match(tgm)
+ return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024 +
+ parseInt(match[2], 10) * 1024 * 1024 * 1024 +
+ parseInt(match[3], 10) * 1024 * 1024
+ } else if (value.match(tg)) {
+ match = value.match(tg)
+ return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024 +
+ parseInt(match[2], 10) * 1024 * 1024 * 1024
+ } else if (value.match(tm)) {
+ match = value.match(tm)
+ return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024 +
+ parseInt(match[2], 10) * 1024 * 1024
+ } else if (value.match(gm)) {
+ match = value.match(gm)
+ return parseInt(match[1], 10) * 1024 * 1024 * 1024 +
+ parseInt(match[2], 10) * 1024 * 1024
+ } else if (value.match(t)) {
+ match = value.match(t)
+ return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024
+ } else if (value.match(g)) {
+ match = value.match(g)
+ return parseInt(match[1], 10) * 1024 * 1024 * 1024
+ } else if (value.match(m)) {
+ match = value.match(m)
+ return parseInt(match[1], 10) * 1024 * 1024
+ } else if (value.match(b)) {
+ match = value.match(b)
+ return parseInt(match[1], 10) * 1024
+ } else {
+ return parseInt(value, 10)
+ }
+}
+
+// ---------------------------------------------------------------------------