bajo-extra 0.3.2 → 0.3.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.
@@ -1,35 +1,36 @@
1
1
  import path from 'path'
2
+ import { Readable } from 'node:stream'
2
3
 
3
- async function download (url, opts = {}) {
4
+ async function download (url, opts = {}, extra = {}) {
4
5
  const { fs, getPluginDataDir, importPkg, error, generateId } = this.bajo.helper
5
6
  const { fetch, formatByte, formatPercentage } = this.bajoExtra.helper
6
- const { isFunction } = this.bajo.helper._
7
- if (typeof opts === 'string') opts = { dir: opts }
7
+ const { isFunction, merge } = this.bajo.helper._
8
+ if (typeof opts === 'string') extra = { dir: opts }
8
9
  const increment = await importPkg('add-filename-increment')
9
- if (!opts.dir) {
10
- opts.dir = `${getPluginDataDir('bajoExtra')}/download`
11
- fs.ensureDirSync(opts.dir)
10
+ if (!extra.dir) {
11
+ extra.dir = `${getPluginDataDir('bajoExtra')}/download`
12
+ fs.ensureDirSync(extra.dir)
12
13
  }
13
- const fetchOpts = opts.fetchOpts ?? {}
14
- if (!fs.existsSync(opts.dir)) throw error('Download dir \'%s\' doesn\'t exists', opts.dir)
15
- if (opts.randomFileName) {
14
+ if (!fs.existsSync(extra.dir)) throw error('Download dir \'%s\' doesn\'t exists', extra.dir)
15
+ if (extra.randomFileName) {
16
16
  const ext = path.extname(url)
17
- opts.fileName = `${generateId()}${ext}`
17
+ extra.fileName = `${generateId()}${ext}`
18
18
  }
19
- if (!opts.fileName) opts.fileName = path.basename(url)
20
- const file = path.resolve(increment(`${opts.dir}/${opts.fileName}`, { fs: true }))
19
+ if (!extra.fileName) extra.fileName = path.basename(url)
20
+ const file = path.resolve(increment(`${extra.dir}/${extra.fileName}`, { fs: true }))
21
21
  const writer = fs.createWriteStream(file)
22
- fetchOpts.responseType = 'stream'
23
- const { headers, data } = await fetch(url, fetchOpts, { rawResponse: true })
22
+ const { headers, body, ok, status } = await fetch(url, opts, merge({}, extra, { rawResponse: true }))
23
+ if (!ok) throw error('Getting %s status', status)
24
24
  const total = headers['content-length'] ?? 0
25
+ const data = Readable.fromWeb(body)
25
26
  let length = 0
26
27
  data.on('data', chunk => {
27
28
  length += chunk.length
28
- if (isFunction(opts.progressFn)) opts.progressFn.call(this, length, total)
29
- else if (opts.spin) {
30
- opts.spinText = opts.spinText ?? 'Downloading...'
31
- if (total === 0) opts.spin.setText(`${opts.spinText} %s`, formatByte(length))
32
- else opts.spin.setText(`${opts.spinText} %s of %s (%s)`, formatByte(length), formatByte(total), formatPercentage(length / total))
29
+ if (isFunction(extra.progressFn)) extra.progressFn.call(this, length, total)
30
+ else if (extra.spin) {
31
+ extra.spinText = extra.spinText ?? 'Downloading...'
32
+ if (total === 0) extra.spin.setText(`${extra.spinText} %s`, formatByte(length))
33
+ else extra.spin.setText(`${extra.spinText} %s of %s (%s)`, formatByte(length), formatByte(total), formatPercentage(length / total))
33
34
  }
34
35
  })
35
36
  data.pipe(writer)
@@ -1,25 +1,46 @@
1
- import axios from 'axios'
2
- import http from 'http'
3
- import https from 'https'
1
+ import path from 'path'
2
+ import { fetch, Agent } from 'undici'
4
3
 
5
- async function fetch (url, opts = {}, ext = {}) {
6
- const { getConfig } = this.bajo.helper
7
- const { has, isPlainObject, cloneDeep, isEmpty } = this.bajo.helper._
4
+ async function fetchUrl (url, opts = {}, extra = {}) {
5
+ const { getConfig, isSet, fs } = this.bajo.helper
6
+ const { has, isArray, isPlainObject, isString, cloneDeep, isEmpty, merge } = this.bajo.helper._
8
7
  const cfg = getConfig('bajoExtra')
9
8
  if (isPlainObject(url)) {
10
- ext = cloneDeep(opts)
9
+ extra = cloneDeep(opts)
11
10
  opts = cloneDeep(url)
12
- } else opts.url = url
13
- opts.params = opts.params ?? {}
14
- if (!has(ext, 'cacheBuster')) ext.cacheBuster = true
15
- if (ext.cacheBuster) opts.params[ext.cacheBusterKey ?? '_'] = Date.now()
11
+ url = opts.url
12
+ delete opts.url
13
+ }
14
+ if (opts.method) opts.method = opts.method.toUpperCase()
15
+ if (opts.auth) {
16
+ opts.headers.Authorization = `Basic ${Buffer.from(`${opts.auth.username}:${opts.auth.password}`).toString('base64')}`
17
+ delete opts.auth
18
+ }
19
+ opts.query = merge({}, opts.query, opts.params ?? {})
20
+ delete opts.params
21
+ if (!has(extra, 'cacheBuster')) extra.cacheBuster = true
22
+ if (extra.cacheBuster) opts.query[extra.cacheBusterKey ?? '_'] = Date.now()
16
23
  if (!isEmpty(cfg.fetch.agent)) {
17
- opts.httpAgent = opts.httpAgent ?? new http.Agent(cfg.fetch.agent)
18
- opts.httpsAgent = opts.httpsAgent ?? new https.Agent(cfg.fetch.agent)
24
+ opts.dispatcher = new Agent(cfg.fetch.agent)
25
+ }
26
+ if (opts.body && extra.formData) {
27
+ const formData = new FormData()
28
+ for (const key in opts.body) {
29
+ let fname
30
+ let val = opts.body[key]
31
+ if (!isSet(val)) continue
32
+ if (isString(val) && val.startsWith('file:///')) {
33
+ fname = path.basename(val)
34
+ val = new Blob([fs.readFileSync(val.slice(8))])
35
+ } else if (isPlainObject(val) || isArray(val)) val = JSON.stringify(val)
36
+ if (fname) formData.append(key, val, fname)
37
+ else formData.append(key, val)
38
+ }
39
+ opts.body = formData
19
40
  }
20
- const resp = await axios(opts)
21
- if (ext.rawResponse) return resp
22
- return resp.data
41
+ const resp = await fetch(url, opts)
42
+ if (extra.rawResponse) return resp
43
+ return await resp.json()
23
44
  }
24
45
 
25
- export default fetch
46
+ export default fetchUrl
@@ -7,7 +7,7 @@ async function download ({ path, args }) {
7
7
 
8
8
  let dest
9
9
  try {
10
- dest = await download(url, { spin, spinText })
10
+ dest = await download(url, null, { spin, spinText })
11
11
  } catch (err) {
12
12
  spin.fatal('Error: %s', err.message)
13
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bajo-extra",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Extra package for Bajo Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -27,13 +27,13 @@
27
27
  "homepage": "https://github.com/ardhi/bajo-extra#readme",
28
28
  "dependencies": {
29
29
  "async": "^3.2.4",
30
- "axios": "^1.4.0",
31
30
  "bcrypt": "^5.1.1",
32
31
  "email-addresses": "^5.0.0",
33
32
  "fast-jwt": "^4.0.1",
34
33
  "fast-xml-parser": "^4.3.6",
35
34
  "numbro": "^2.5.0",
36
35
  "performant-array-to-tree": "^1.11.0",
37
- "query-string": "^8.1.0"
36
+ "query-string": "^8.1.0",
37
+ "undici": "^6.16.1"
38
38
  }
39
39
  }