Skip to content
This repository was archived by the owner on Sep 28, 2021. It is now read-only.

Commit a22900a

Browse files
vasco-santosPedroMiguelSS
and
PedroMiguelSS
committed
chore: convert to async await syntax (#28)
BREAKING CHANGE: All places in the API that used callbacks are now replaced with async/await Co-authored-by: PedroMiguelSS <[email protected]>
1 parent 5f9e3e3 commit a22900a

File tree

3 files changed

+118
-143
lines changed

3 files changed

+118
-143
lines changed

package.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
},
3232
"homepage": "https://github.com./ipfs/js-ipfs-http-response#readme",
3333
"dependencies": {
34-
"async": "^2.6.1",
3534
"cids": "~0.7.1",
3635
"debug": "^4.1.1",
3736
"file-type": "^8.0.0",
@@ -40,8 +39,8 @@
4039
"ipfs-unixfs": "~0.1.16",
4140
"mime-types": "^2.1.21",
4241
"multihashes": "~0.4.14",
43-
"promisify-es6": "^1.0.3",
44-
"stream-to-blob": "^1.0.1"
42+
"p-try-each": "^1.0.1",
43+
"stream-to-blob": "^2.0.0"
4544
},
4645
"devDependencies": {
4746
"aegir": "^18.0.3",

src/index.js

+75-84
Original file line numberDiff line numberDiff line change
@@ -19,103 +19,94 @@ const header = (status = 200, statusText = 'OK', headers = {}) => ({
1919
headers
2020
})
2121

22-
const response = (ipfsNode, ipfsPath) => {
22+
const response = async (ipfsNode, ipfsPath) => {
2323
// handle hash resolve error (simple hash, test for directory now)
24-
const handleResolveError = (node, path, error) => {
24+
const handleResolveError = async (node, path, error) => {
2525
if (error) {
2626
const errorString = error.toString()
2727

28-
return new Promise((resolve, reject) => {
29-
// switch case with true feels so wrong.
30-
switch (true) {
31-
case (errorString.includes('dag node is a directory')):
32-
resolver.directory(node, path, error.cid)
33-
.then((content) => {
34-
// dir render
35-
if (typeof content === 'string') {
36-
resolve(new Response(content, header(200, 'OK', { 'Content-Type': 'text/html' })))
37-
}
38-
39-
// redirect to dir entry point (index)
40-
resolve(Response.redirect(pathUtils.joinURLParts(path, content[0].Name)))
41-
})
42-
.catch((error) => {
43-
log(error)
44-
resolve(new Response(errorString, header(500, error.toString())))
45-
})
46-
break
47-
case errorString.startsWith('Error: no link named'):
48-
resolve(new Response(errorString, header(404, errorString)))
49-
break
50-
case errorString.startsWith('Error: multihash length inconsistent'):
51-
case errorString.startsWith('Error: Non-base58 character'):
52-
resolve(new Response(errorString, header(400, errorString)))
53-
break
54-
default:
55-
log(error)
56-
resolve(new Response(errorString, header(500, errorString)))
28+
if (errorString.includes('dag node is a directory')) {
29+
try {
30+
const content = await resolver.directory(node, path, error.cid)
31+
// dir render
32+
if (typeof content === 'string') {
33+
return new Response(content, header(200, 'OK', { 'Content-Type': 'text/html' }))
34+
}
35+
36+
// redirect to dir entry point (index)
37+
return Response.redirect(pathUtils.joinURLParts(path, content[0].Name))
38+
} catch (error) {
39+
log(error)
40+
return new Response(errorString, header(500, error.toString()))
5741
}
58-
})
42+
}
43+
44+
if (errorString.startsWith('Error: no link named')) {
45+
return new Response(errorString, header(404, errorString))
46+
}
47+
48+
if (errorString.startsWith('Error: multihash length inconsistent') || errorString.startsWith('Error: Non-base58 character')) {
49+
return new Response(errorString, header(400, errorString))
50+
}
51+
52+
log(error)
53+
return new Response(errorString, header(500, errorString))
5954
}
6055
}
6156

62-
return new Promise((resolve, reject) => {
63-
// remove trailing slash for files if needed
64-
if (ipfsPath.endsWith('/')) {
65-
resolve(Response.redirect(pathUtils.removeTrailingSlash(ipfsPath)))
66-
}
57+
// remove trailing slash for files if needed
58+
if (ipfsPath.endsWith('/')) {
59+
return Response.redirect(pathUtils.removeTrailingSlash(ipfsPath))
60+
}
6761

68-
resolver.cid(ipfsNode, ipfsPath)
69-
.then((resolvedData) => {
70-
const readableStream = ipfsNode.catReadableStream(resolvedData.cid)
71-
const responseStream = new stream.PassThrough({ highWaterMark: 1 })
72-
readableStream.pipe(responseStream)
62+
try {
63+
const resolvedData = await resolver.cid(ipfsNode, ipfsPath)
7364

74-
readableStream.once('error', (error) => {
75-
if (error) {
76-
log(error)
77-
resolve(new Response(error.toString(), header(500, 'Error fetching the file')))
78-
}
79-
})
80-
81-
// return only after first chunk being checked
82-
let contentTypeDetected = false
83-
readableStream.on('data', (chunk) => {
84-
// check mime on first chunk
85-
if (contentTypeDetected) {
86-
return
87-
}
65+
const readableStream = ipfsNode.catReadableStream(resolvedData.cid)
66+
const responseStream = new stream.PassThrough({ highWaterMark: 1 })
67+
readableStream.pipe(responseStream)
8868

89-
contentTypeDetected = true
90-
// return Response with mime type
91-
const contentType = detectContentType(ipfsPath, chunk)
92-
93-
if (typeof Blob === 'undefined') {
94-
if (contentType) {
95-
resolve(new Response(responseStream, header(200, 'OK', { 'Content-Type': contentType })))
96-
} else {
97-
resolve(new Response(responseStream, header()))
98-
}
99-
} else {
100-
toBlob(responseStream, (err, blob) => {
101-
if (err) {
102-
resolve(new Response(err.toString(), header(500, 'Error fetching the file')))
103-
}
104-
105-
if (contentType) {
106-
resolve(new Response(blob, header(200, 'OK', { 'Content-Type': contentType })))
107-
} else {
108-
resolve(new Response(blob, header()))
109-
}
110-
})
111-
}
112-
})
69+
return new Promise((resolve, reject) => {
70+
readableStream.once('error', (error) => {
71+
if (error) {
72+
log(error)
73+
return resolve(new Response(error.toString(), header(500, 'Error fetching the file')))
74+
}
11375
})
114-
.catch((error) => {
115-
log(error)
116-
resolve(handleResolveError(ipfsNode, ipfsPath, error))
76+
77+
// return only after first chunk being checked
78+
let contentTypeDetected = false
79+
readableStream.on('data', async (chunk) => {
80+
// check mime on first chunk
81+
if (contentTypeDetected) {
82+
return
83+
}
84+
85+
contentTypeDetected = true
86+
// return Response with mime type
87+
const contentType = detectContentType(ipfsPath, chunk)
88+
89+
if (typeof Blob === 'undefined') {
90+
return contentType
91+
? resolve(new Response(responseStream, header(200, 'OK', { 'Content-Type': contentType })))
92+
: resolve(new Response(responseStream, header()))
93+
}
94+
95+
try {
96+
const blob = await toBlob(responseStream)
97+
98+
return contentType
99+
? resolve(new Response(blob, header(200, 'OK', { 'Content-Type': contentType })))
100+
: resolve(new Response(blob, header()))
101+
} catch (err) {
102+
return resolve(new Response(err.toString(), header(500, 'Error fetching the file')))
103+
}
117104
})
118-
})
105+
})
106+
} catch (error) {
107+
log(error)
108+
return handleResolveError(ipfsNode, ipfsPath, error)
109+
}
119110
}
120111

121112
module.exports = {

src/resolver.js

+41-56
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
'use strict'
22

3+
const pTryEach = require('p-try-each')
34
const mh = require('multihashes')
4-
const promisify = require('promisify-es6')
55
const CID = require('cids')
66
const debug = require('debug')
7-
const tryEach = require('async/tryEach')
8-
const waterfall = require('async/waterfall')
97
const log = debug('jsipfs:http:response:resolver')
108
log.error = debug('jsipfs:http:response:resolver:error')
119
const dirView = require('./dir-view')
@@ -16,74 +14,61 @@ const INDEX_HTML_FILES = [
1614
'index.shtml'
1715
]
1816

19-
const findIndexFile = (ipfs, path, callback) => {
20-
return tryEach(INDEX_HTML_FILES.map(file => {
21-
return (cb) => {
22-
waterfall([
23-
(cb) => ipfs.files.stat(`${path}/${file}`, cb),
24-
(stats, cb) => cb(null, {
25-
name: file,
26-
cid: new CID(stats.hash)
27-
})
28-
], cb)
17+
const findIndexFile = (ipfs, path) => {
18+
return pTryEach(INDEX_HTML_FILES.map(file => {
19+
return async () => {
20+
const stats = await ipfs.files.stat(`${path}/${file}`)
21+
22+
return {
23+
name: file,
24+
cid: new CID(stats.hash)
25+
}
2926
}
30-
}), callback)
27+
}))
3128
}
3229

33-
const directory = promisify((ipfs, path, cid, callback) => {
30+
const directory = async (ipfs, path, cid) => {
3431
// Test if it is a Website
35-
findIndexFile(ipfs, path, (err, res) => {
36-
if (err) {
37-
if (err.message.includes('does not exist')) {
38-
// not a website, just show a directory listing
39-
return ipfs.dag.get(cid, (err, result) => {
40-
if (err) {
41-
return callback(err)
42-
}
43-
44-
return callback(null, dirView.render(path, result.value.Links))
45-
})
46-
}
32+
try {
33+
const res = await findIndexFile(ipfs, path)
4734

48-
return callback(err)
35+
return [{ Name: res.name }]
36+
} catch (err) {
37+
if (err.message.includes('does not exist')) {
38+
// not a website, just show a directory listing
39+
const result = await ipfs.dag.get(cid)
40+
41+
return dirView.render(path, result.value.Links)
4942
}
5043

51-
callback(err, [{
52-
Name: res.name
53-
}])
54-
})
55-
})
44+
throw err
45+
}
46+
}
5647

57-
const cid = promisify((ipfs, path, callback) => {
58-
ipfs.files.stat(path, (err, stats) => {
59-
if (err) {
60-
return callback(err)
61-
}
48+
const cid = async (ipfs, path) => {
49+
const stats = await ipfs.files.stat(path)
6250

63-
const cid = new CID(stats.hash)
51+
const cid = new CID(stats.hash)
6452

65-
if (stats.type.includes('directory')) {
66-
const err = new Error('This dag node is a directory')
67-
err.cid = cid
68-
err.fileName = stats.name
69-
err.dagDirType = stats.type
53+
if (stats.type.includes('directory')) {
54+
const err = new Error('This dag node is a directory')
55+
err.cid = cid
56+
err.fileName = stats.name
57+
err.dagDirType = stats.type
7058

71-
return callback(err)
72-
}
59+
throw err
60+
}
7361

74-
callback(err, {
75-
cid
76-
})
77-
})
78-
})
62+
return { cid }
63+
}
7964

80-
const multihash = promisify((ipfs, path, callback) => {
65+
const multihash = async (ipfs, path) => {
8166
// deprecated, use 'cid' instead
8267
// (left for backward-compatibility)
83-
cid(ipfs, path)
84-
.then((result) => { callback(null, { multihash: mh.toB58String(result.cid.multihash) }) })
85-
.catch((err) => { callback(err) })
86-
})
68+
const result = await cid(ipfs, path)
69+
70+
return { multihash: mh.toB58String(result.cid.multihash) }
71+
}
8772

8873
module.exports = {
8974
directory: directory,

0 commit comments

Comments
 (0)