Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

Commit 70653ad

Browse files
author
Alan Shaw
committed
refactor: use ky
License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>
1 parent b58c489 commit 70653ad

16 files changed

+228
-300
lines changed

package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
"browser": {
1818
"glob": false,
1919
"fs": false,
20-
"stream": "readable-stream",
21-
"./src/lib/configure.js": "./src/lib/configure.browser.js",
22-
"./src/lib/querystring.js": "./src/lib/querystring.browser.js"
20+
"stream": "readable-stream"
2321
},
2422
"repository": "github:ipfs/js-ipfs-http-client",
2523
"scripts": {
@@ -64,13 +62,14 @@
6462
"just-kebab-case": "^1.1.0",
6563
"just-map-keys": "^1.1.0",
6664
"kind-of": "^6.0.2",
65+
"ky": "^0.11.2",
66+
"ky-universal": "^0.2.2",
6767
"lru-cache": "^5.1.1",
6868
"multiaddr": "^6.0.6",
6969
"multibase": "~0.6.0",
7070
"multicodec": "~0.5.1",
7171
"multihashes": "~0.4.14",
7272
"ndjson": "github:hugomrdias/ndjson#feat/readable-stream3",
73-
"node-fetch": "^2.6.0",
7473
"once": "^1.4.0",
7574
"peer-id": "~0.12.2",
7675
"peer-info": "~0.15.1",

src/lib/configure.browser.js

Lines changed: 0 additions & 45 deletions
This file was deleted.

src/lib/configure.js

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
'use strict'
2+
/* eslint-env browser */
23

3-
const { Headers } = require('node-fetch')
4+
const ky = require('ky-universal')
5+
const { isBrowser, isWebWorker } = require('ipfs-utils/src/env')
46
const { toUri } = require('./multiaddr')
5-
const pkg = require('../../package.json')
7+
const errorHandler = require('./error-handler')
68

79
// Set default configuration and call create function with them
810
module.exports = create => config => {
@@ -16,28 +18,46 @@ module.exports = create => config => {
1618
config = { ...config }
1719
}
1820

19-
config.fetch = config.fetch || require('./fetch').fetch
20-
2121
if (config.protocol || config.host || config.port) {
2222
const port = config.port ? `:${config.port}` : ''
2323
config.apiAddr = `${config.protocol || 'http'}://${config.host || 'localhost'}${port}`
2424
}
2525

26-
config.apiAddr = (config.apiAddr || 'http://localhost:5001').toString()
27-
config.apiAddr = config.apiAddr.startsWith('/')
28-
? toUri(config.apiAddr)
29-
: config.apiAddr
26+
config.apiAddr = (config.apiAddr || getDefaultApiAddr(config)).toString()
27+
config.apiAddr = config.apiAddr.startsWith('/') ? toUri(config.apiAddr) : config.apiAddr
3028
config.apiPath = config.apiPath || config['api-path'] || '/api/v0'
3129

32-
if (config.apiPath.endsWith('/')) {
33-
config.apiPath = config.apiPath.slice(0, -1)
34-
}
30+
return create({
31+
// TODO configure ky to use config.fetch when this is released:
32+
// https://github.com/sindresorhus/ky/pull/153
33+
ky: ky.extend({
34+
prefixUrl: config.apiAddr + config.apiPath,
35+
timeout: config.timeout || 60 * 1000,
36+
headers: config.headers,
37+
hooks: {
38+
afterResponse: [errorHandler]
39+
}
40+
})
41+
})
42+
}
43+
44+
function getDefaultApiAddr ({ protocol, host, port }) {
45+
if (isBrowser || isWebWorker) {
46+
if (!protocol && !host && !port) { // Use current origin
47+
return ''
48+
}
49+
50+
if (!protocol) {
51+
protocol = location.protocol.startsWith('http')
52+
? location.protocol.split(':')[0]
53+
: 'http'
54+
}
3555

36-
config.headers = new Headers(config.headers)
56+
host = host || location.hostname
57+
port = port || location.port
3758

38-
if (!config.headers.has('User-Agent')) {
39-
config.headers.append('User-Agent', `${pkg.name}/${pkg.version}`)
59+
return `${protocol}://${host}${port ? ':' + port : ''}`
4060
}
4161

42-
return create(config)
62+
return `${protocol || 'http'}://${host || 'localhost'}:${port || 5001}`
4363
}

src/lib/error-handler.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict'
2+
3+
const { HTTPError } = require('ky-universal')
4+
const log = require('debug')('ipfs-http-client:lib:error-handler')
5+
6+
function isJsonResponse (res) {
7+
return (res.headers.get('Content-Type') || '').startsWith('application/json')
8+
}
9+
10+
module.exports = async function errorHandler (response) {
11+
if (response.ok) return
12+
13+
let msg
14+
15+
try {
16+
if (isJsonResponse(response)) {
17+
const data = await response.json()
18+
log(data)
19+
msg = data.Message || data.message
20+
} else {
21+
msg = await response.text()
22+
}
23+
} catch (err) {
24+
log('Failed to parse error response', err)
25+
// Failed to extract/parse error message from response
26+
throw new HTTPError(response)
27+
}
28+
29+
if (!msg) throw new HTTPError(response)
30+
throw Object.assign(new Error(msg), { status: response.status })
31+
}

src/lib/fetch.js

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/lib/querystring.browser.js

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/lib/querystring.js

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/lib/stream-to-iterable.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict'
2+
3+
module.exports = function toIterable (body) {
4+
// Node.js stream
5+
if (body[Symbol.asyncIterator]) return body
6+
7+
// Browser ReadableStream
8+
if (body.getReader) {
9+
return (async function * () {
10+
const reader = body.getReader()
11+
12+
try {
13+
while (true) {
14+
const { done, value } = await reader.read()
15+
if (done) return
16+
yield value
17+
}
18+
} finally {
19+
reader.releaseLock()
20+
}
21+
})()
22+
}
23+
24+
throw new Error('unknown stream')
25+
}

src/pubsub/ls.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
'use strict'
22

33
const configure = require('../lib/configure')
4-
const { ok } = require('../lib/fetch')
5-
const { objectToQuery } = require('../lib/querystring')
64

7-
module.exports = configure(({ fetch, apiAddr, apiPath, headers }) => {
5+
module.exports = configure(({ ky }) => {
86
return async (options) => {
97
options = options || {}
108

11-
const qs = objectToQuery(options.qs)
12-
const url = `${apiAddr}${apiPath}/pubsub/ls${qs}`
13-
const res = await ok(fetch(url, {
9+
const { Strings } = await ky.get('pubsub/ls', {
10+
timeout: options.timeout,
1411
signal: options.signal,
15-
headers: options.headers || headers
16-
}))
17-
const data = await res.json()
18-
return data.Strings || []
12+
headers: options.headers,
13+
searchParams: options.searchParams
14+
}).json()
15+
16+
return Strings || []
1917
}
2018
})

src/pubsub/peers.js

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
'use strict'
22

3-
const { objectToQuery } = require('../lib/querystring')
43
const configure = require('../lib/configure')
5-
const { ok } = require('../lib/fetch')
64

7-
module.exports = configure(({ fetch, apiAddr, apiPath, headers }) => {
5+
module.exports = configure(({ ky }) => {
86
return async (topic, options) => {
97
if (!options && typeof topic === 'object') {
108
options = topic
@@ -13,17 +11,16 @@ module.exports = configure(({ fetch, apiAddr, apiPath, headers }) => {
1311

1412
options = options || {}
1513

16-
const qs = objectToQuery({
17-
arg: topic,
18-
...(options.qs || {})
19-
})
14+
const searchParams = new URLSearchParams(options.searchParams)
15+
searchParams.set('arg', topic)
2016

21-
const url = `${apiAddr}${apiPath}/pubsub/peers${qs}`
22-
const res = await ok(fetch(url, {
17+
const { Strings } = await ky.get('pubsub/peers', {
18+
timeout: options.timeout,
2319
signal: options.signal,
24-
headers: options.headers || headers
25-
}))
26-
const data = await res.json()
27-
return data.Strings || []
20+
headers: options.headers,
21+
searchParams
22+
}).json()
23+
24+
return Strings || []
2825
}
2926
})

0 commit comments

Comments
 (0)