aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/serve.js97
-rw-r--r--package-lock.json184
-rw-r--r--package.json3
3 files changed, 267 insertions, 17 deletions
diff --git a/lib/serve.js b/lib/serve.js
index 0c1ede8..abf15c3 100644
--- a/lib/serve.js
+++ b/lib/serve.js
@@ -21,6 +21,7 @@ var htime = require('human-time')
var ph = require('pull-hyperscript')
var emojis = require('emoji-named-characters')
var jpeg = require('jpeg-autorotate')
+var unzip = require('unzip')
module.exports = Serve
@@ -335,6 +336,7 @@ Serve.prototype.path = function (url) {
case '/npm-prebuilds': return this.npmPrebuilds(m[2])
case '/npm-readme': return this.npmReadme(m[2])
case '/markdown': return this.markdown(m[2])
+ case '/zip': return this.zip(m[2])
}
return this.respond(404, 'Not found')
}
@@ -2202,6 +2204,101 @@ Serve.prototype.markdown = function (url) {
)
}
+Serve.prototype.zip = function (url) {
+ var self = this
+ var parts = url.split('/').slice(1)
+ var id = decodeURIComponent(parts.shift())
+ var filename = parts.join('/')
+ var blobs = self.app.sbot.blobs
+ var etag = id + filename
+ var index = filename === '' || /\/$/.test(filename)
+ var indexFilename = index && (filename + 'index.html')
+ if (filename === '/' || /\/\/$/.test(filename)) {
+ // force directory listing if path ends in //
+ filename = filename.replace(/\/$/, '')
+ indexFilename = false
+ }
+ var files = index && []
+ if (self.req.headers['if-none-match'] === etag) return self.respond(304)
+ blobs.size(id, function (err, size) {
+ if (size == null) return askWantBlobsForm([id])
+ if (err) {
+ if (/^invalid/.test(err.message)) return self.respond(400, err.message)
+ else return self.respond(500, err.message || err)
+ }
+ var parseUnzip = unzip.Parse()
+ var gotEntry = false
+ parseUnzip.on('entry', function (entry) {
+ if (index) {
+ if (!gotEntry) {
+ if (entry.path === indexFilename) {
+ gotEntry = true
+ return serveFile(entry)
+ } else if (entry.path.substr(0, filename.length) === filename) {
+ files.push({path: entry.path, type: entry.type, props: entry.props})
+ }
+ }
+ } else {
+ if (!gotEntry && entry.path === filename) {
+ gotEntry = true
+ // if (false && entry.type === 'Directory') return serveDirectory(entry)
+ return serveFile(entry)
+ }
+ }
+ entry.autodrain()
+ })
+ parseUnzip.on('close', function () {
+ if (gotEntry) return
+ if (!index) return self.respond(404, 'Entry not found')
+ pull(
+ ph('section', {}, [
+ ph('h3', [
+ ph('a', {href: self.app.render.toUrl('/links/' + id)}, id.substr(0, 8) + '…'),
+ ' ',
+ ph('a', {href: self.app.render.toUrl('/zip/' + encodeURIComponent(id) + '/' + filename)}, filename || '/'),
+ ]),
+ pull(
+ pull.values(files),
+ pull.map(function (file) {
+ var path = '/zip/' + encodeURIComponent(id) + '/' + file.path
+ return ph('li', [
+ ph('a', {href: self.app.render.toUrl(path)}, file.path)
+ ])
+ })
+ )
+ ]),
+ self.wrapPage(id + filename),
+ self.respondSink(200)
+ )
+ gotEntry = true // so that the handler on error event does not run
+ })
+ parseUnzip.on('error', function (err) {
+ if (!gotEntry) return self.respond(400, err.message)
+ })
+ var size
+ function serveFile(entry) {
+ size = entry.size
+ pull(
+ toPull.source(entry),
+ ident(gotType),
+ self.respondSink()
+ )
+ }
+ pull(
+ self.app.getBlob(id),
+ toPull(parseUnzip)
+ )
+ function gotType(type) {
+ type = type && mime.lookup(type)
+ if (type) self.res.setHeader('Content-Type', type)
+ if (size) self.res.setHeader('Content-Length', size)
+ self.res.setHeader('Cache-Control', 'public, max-age=315360000')
+ self.res.setHeader('etag', etag)
+ self.res.writeHead(200)
+ }
+ })
+}
+
// wrap a binary source and render it or turn into an embed
Serve.prototype.wrapBinary = function (opts) {
var self = this
diff --git a/package-lock.json b/package-lock.json
index ae79d80..0f5d62f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -30,6 +30,15 @@
"resolved": "http://localhost:8989/blobs/get/&tix85Coqflfg1RbOQ/x6cq0E1Rry5rDhGiIHyRdM+8s=.sha256",
"integrity": "sha256-tix85Coqflfg1RbOQ/x6cq0E1Rry5rDhGiIHyRdM+8s="
},
+ "binary": {
+ "version": "0.3.0",
+ "resolved": "http://localhost:8989/blobs/get/&lAvJtA+yqHWHbjyhvj0Fp6QZiB5CAcdsg/+7BVaLaQk=.sha256",
+ "integrity": "sha256-lAvJtA+yqHWHbjyhvj0Fp6QZiB5CAcdsg/+7BVaLaQk=",
+ "requires": {
+ "buffers": "0.1.1",
+ "chainsaw": "0.1.0"
+ }
+ },
"brace-expansion": {
"version": "http://localhost:8989/blobs/get/&fdjQQT88BvLg9ynhFsffO5ZCC04SoSTrnmmGGWWxcPo=.sha256",
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
@@ -42,6 +51,11 @@
"version": "http://localhost:8989/blobs/get/&u3cvbnn1mLUZCBFO3qRNABW3op1sgtwIK2UCQ/RIYGY=.sha256",
"integrity": "sha1-QUGcrvdpdVkp3VGJZ9PuwKYmJ3E="
},
+ "buffers": {
+ "version": "0.1.1",
+ "resolved": "http://localhost:8989/blobs/get/&+N5Jxg5GcAUYLZaHtdh3dbvOxjhaxjIgt3QTJ0Qd620=.sha256",
+ "integrity": "sha256-+N5Jxg5GcAUYLZaHtdh3dbvOxjhaxjIgt3QTJ0Qd620="
+ },
"builtin-modules": {
"version": "http://localhost:8989/blobs/get/&54lxeCToaIJpwkHCA9n2Fc8VKG1iF9dN78fzlbDaXxE=.sha256",
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
@@ -60,6 +74,14 @@
"resolved": "http://localhost:8989/blobs/get/&mjv2gAClOLf1jZaoHspyZ5ZbBYFn6imQeCwXDtp1kvU=.sha256",
"integrity": "sha256-mjv2gAClOLf1jZaoHspyZ5ZbBYFn6imQeCwXDtp1kvU="
},
+ "chainsaw": {
+ "version": "0.1.0",
+ "resolved": "http://localhost:8989/blobs/get/&AVhqaqHRF0rgev9pgi0B4HBP4w8jrCIiHJuAS6uXbPs=.sha256",
+ "integrity": "sha256-AVhqaqHRF0rgev9pgi0B4HBP4w8jrCIiHJuAS6uXbPs=",
+ "requires": {
+ "traverse": "0.3.9"
+ }
+ },
"chloride": {
"version": "2.2.7",
"resolved": "http://localhost:8989/blobs/get/&/ahFOC6wlOMnO1HdAIAcuY6NQ9AkKjmR1Os/xnts6N8=.sha256",
@@ -216,6 +238,27 @@
"version": "http://localhost:8989/blobs/get/&noDLhxMSWqU9+BopYm97gfJqm+HNQYQLPM3K5NUuj5w=.sha256",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
+ "fstream": {
+ "version": "0.1.31",
+ "resolved": "http://localhost:8989/blobs/get/&MgatCTGF+duNaFmT4+Nyh0UEi9rjNltsqSTLdeLCKwE=.sha256",
+ "integrity": "sha256-MgatCTGF+duNaFmT4+Nyh0UEi9rjNltsqSTLdeLCKwE=",
+ "requires": {
+ "graceful-fs": "3.0.11",
+ "inherits": "2.0.3",
+ "mkdirp": "0.5.1",
+ "rimraf": "2.6.2"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "3.0.11",
+ "resolved": "http://localhost:8989/blobs/get/&WtP5g2DDTtr9aihenL4LdIICzr9RtKdKV9qRCFH1JQM=.sha256",
+ "integrity": "sha256-WtP5g2DDTtr9aihenL4LdIICzr9RtKdKV9qRCFH1JQM=",
+ "requires": {
+ "natives": "1.1.0"
+ }
+ }
+ }
+ },
"get-caller-file": {
"version": "1.0.2",
"resolved": "http://localhost:8989/blobs/get/&FMgvATYUUtPunnh52Q5mgZVX2OhKaewPbHxlxlYwSac=.sha256",
@@ -437,6 +480,27 @@
"yallist": "http://localhost:8989/blobs/get/&x7MQhNNSXhcxS0bCjljOts2PEKn/km2vSDA5dvissLI=.sha256"
}
},
+ "match-stream": {
+ "version": "0.0.2",
+ "resolved": "http://localhost:8989/blobs/get/&8ifmMRW33QbZzSrMY/n26MvE9tZtdgdmHG2P8iAx9/w=.sha256",
+ "integrity": "sha256-8ifmMRW33QbZzSrMY/n26MvE9tZtdgdmHG2P8iAx9/w=",
+ "requires": {
+ "buffers": "0.1.1",
+ "readable-stream": "1.0.34"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "http://localhost:8989/blobs/get/&0QEMlyAUePLZCW/tXOEhdYfVI4R19FBv4JyHzdW8VqY=.sha256",
+ "requires": {
+ "core-util-is": "http://localhost:8989/blobs/get/&pKRNq2V57ePgat5Y0m+P1kLq4JFT/VnGCPy3lRpJk5g=.sha256",
+ "inherits": "2.0.3",
+ "isarray": "http://localhost:8989/blobs/get/&PoREAgaWgArtkqCdTFJgKtx2FAo5tsjpT+fInPcKnwo=.sha256",
+ "string_decoder": "http://localhost:8989/blobs/get/&Pm5v/q/mFX6yJ4qQmvwLhFI0sTRG3KipUYwrebnCIIY=.sha256"
+ }
+ }
+ }
+ },
"mem": {
"version": "1.1.0",
"resolved": "http://localhost:8989/blobs/get/&JPEeBd7nMfhv4111AT1r8bKQHDHp5jbjOlgYO63qN5I=.sha256",
@@ -527,6 +591,11 @@
"integrity": "sha256-dF6wPKUaGRuuJwIvKGrSOSZpzkskLzu2eXPH9iZqSKs=",
"optional": true
},
+ "natives": {
+ "version": "1.1.0",
+ "resolved": "http://localhost:8989/blobs/get/&Xc7wzjsjGc4j8E08ehRgLsKR8ETg+IRu5fMxRHJryZA=.sha256",
+ "integrity": "sha256-Xc7wzjsjGc4j8E08ehRgLsKR8ETg+IRu5fMxRHJryZA="
+ },
"node-gyp-build": {
"version": "3.2.2",
"resolved": "http://localhost:8989/blobs/get/&4FlrrtCACsITHl9W+Fo8zZxpVDu6KPKVlqzJERNerJo=.sha256",
@@ -597,6 +666,11 @@
"mem": "1.1.0"
}
},
+ "over": {
+ "version": "0.0.5",
+ "resolved": "http://localhost:8989/blobs/get/&2SFVsXLBCq9u2cfVbIv27fccQ+MOAk5V8HAOWGbFwK4=.sha256",
+ "integrity": "sha256-2SFVsXLBCq9u2cfVbIv27fccQ+MOAk5V8HAOWGbFwK4="
+ },
"p-finally": {
"version": "1.0.0",
"resolved": "http://localhost:8989/blobs/get/&7/2E4J4TMFQqhKJD8fTaIacA1Fm4N2HqyhYHDrH7iEE=.sha256",
@@ -699,8 +773,8 @@
"integrity": "sha256-+uVE8RHNwJIJa68sQGICGbxnCTCOdLLhSt/Pb4NmgL0="
},
"pull-defer": {
- "version": "0.2.2",
- "resolved": "http://localhost:8989/blobs/get/&mDI2o/JC9yvFOVbeAhDN+hwTm7cK+dBwISYO49EMY24=.sha256"
+ "version": "http://localhost:8989/blobs/get/&mDI2o/JC9yvFOVbeAhDN+hwTm7cK+dBwISYO49EMY24=.sha256",
+ "integrity": "sha1-CIew/7MK8ypW2+z6csFnInHwexM="
},
"pull-git-packidx-parser": {
"version": "http://localhost:8989/blobs/get/&ou0MPQZabBgzrHDu54jzLU3Sc6Rf5a/lost0whPQUJ0=.sha256",
@@ -777,8 +851,8 @@
}
},
"pull-many": {
- "version": "1.0.8",
- "resolved": "http://localhost:8989/blobs/get/&wBHfPheBEjwjjkNoeM5mWtU/tYDs8+xnt5w6C1+EK3g=.sha256",
+ "version": "http://localhost:8989/blobs/get/&wBHfPheBEjwjjkNoeM5mWtU/tYDs8+xnt5w6C1+EK3g=.sha256",
+ "integrity": "sha1-Pa3ZttFWxUVyG9qNAAPdjqoGKT4=",
"requires": {
"pull-stream": "3.6.1"
}
@@ -840,6 +914,29 @@
"ws": "1.1.4"
}
},
+ "pullstream": {
+ "version": "0.4.1",
+ "resolved": "http://localhost:8989/blobs/get/&dU4CcxT0bjZmQhlL7P9dpSxkrrm+K5JOy8/1SDVpwSs=.sha256",
+ "integrity": "sha256-dU4CcxT0bjZmQhlL7P9dpSxkrrm+K5JOy8/1SDVpwSs=",
+ "requires": {
+ "over": "0.0.5",
+ "readable-stream": "1.0.34",
+ "setimmediate": "1.0.5",
+ "slice-stream": "1.0.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "http://localhost:8989/blobs/get/&0QEMlyAUePLZCW/tXOEhdYfVI4R19FBv4JyHzdW8VqY=.sha256",
+ "requires": {
+ "core-util-is": "http://localhost:8989/blobs/get/&pKRNq2V57ePgat5Y0m+P1kLq4JFT/VnGCPy3lRpJk5g=.sha256",
+ "inherits": "2.0.3",
+ "isarray": "http://localhost:8989/blobs/get/&PoREAgaWgArtkqCdTFJgKtx2FAo5tsjpT+fInPcKnwo=.sha256",
+ "string_decoder": "http://localhost:8989/blobs/get/&Pm5v/q/mFX6yJ4qQmvwLhFI0sTRG3KipUYwrebnCIIY=.sha256"
+ }
+ }
+ }
+ },
"rc": {
"version": "1.2.1",
"resolved": "http://localhost:8989/blobs/get/&XPry2asXmpIfJLFtlg5hZmO2uM0QlZd5nCr/AJBOLek=.sha256",
@@ -895,6 +992,14 @@
"resolved": "http://localhost:8989/blobs/get/&Y6ct0k73eVjQG88nl6Ll/lfhxdEVefvRvci3hMiZmcM=.sha256",
"integrity": "sha256-Y6ct0k73eVjQG88nl6Ll/lfhxdEVefvRvci3hMiZmcM="
},
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "http://localhost:8989/blobs/get/&5u4iUQN5Nebmc0+RrO4XpcxAXxAREHuP7ND3+WhZKd4=.sha256",
+ "integrity": "sha256-5u4iUQN5Nebmc0+RrO4XpcxAXxAREHuP7ND3+WhZKd4=",
+ "requires": {
+ "glob": "http://localhost:8989/blobs/get/&zz0+R6Ewi1Ev1wfx31k3N8tWkHnQS/l14fxI3mpintE=.sha256"
+ }
+ },
"safe-buffer": {
"version": "5.1.1",
"resolved": "http://localhost:8989/blobs/get/&DBRHICIwyQWmEc+9TG2DT/zR9Zja3LyNW+dIJuXjsXE=.sha256",
@@ -925,6 +1030,11 @@
"version": "http://localhost:8989/blobs/get/&2TSu59ueCdoJ6HckdDMV/+iIEwqm4E+73srJhfauaT0=.sha256",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
+ "setimmediate": {
+ "version": "1.0.5",
+ "resolved": "http://localhost:8989/blobs/get/&XLn8ImmDZO1CwC1qo9xQ/+r6aEUq6EaZZy49/XSSLJ4=.sha256",
+ "integrity": "sha256-XLn8ImmDZO1CwC1qo9xQ/+r6aEUq6EaZZy49/XSSLJ4="
+ },
"sha.js": {
"version": "2.4.5",
"resolved": "http://localhost:8989/blobs/get/&JxjiN22oEOlVmJQn3aII8ykRlfimM2Ph+URrf/2KZhs=.sha256",
@@ -948,6 +1058,26 @@
"version": "http://localhost:8989/blobs/get/&2JAO0FDbn45cJ1KdQ8Al0Lu7FnN8oZnYa9UP3Ixb0tg=.sha256",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
},
+ "slice-stream": {
+ "version": "1.0.0",
+ "resolved": "http://localhost:8989/blobs/get/&vZJmJejF0Cfij1r3a/BjIvBStHkzidwIh8n5j5k63Us=.sha256",
+ "integrity": "sha256-vZJmJejF0Cfij1r3a/BjIvBStHkzidwIh8n5j5k63Us=",
+ "requires": {
+ "readable-stream": "1.0.34"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "http://localhost:8989/blobs/get/&0QEMlyAUePLZCW/tXOEhdYfVI4R19FBv4JyHzdW8VqY=.sha256",
+ "requires": {
+ "core-util-is": "http://localhost:8989/blobs/get/&pKRNq2V57ePgat5Y0m+P1kLq4JFT/VnGCPy3lRpJk5g=.sha256",
+ "inherits": "2.0.3",
+ "isarray": "http://localhost:8989/blobs/get/&PoREAgaWgArtkqCdTFJgKtx2FAo5tsjpT+fInPcKnwo=.sha256",
+ "string_decoder": "http://localhost:8989/blobs/get/&Pm5v/q/mFX6yJ4qQmvwLhFI0sTRG3KipUYwrebnCIIY=.sha256"
+ }
+ }
+ }
+ },
"smart-buffer": {
"version": "1.1.15",
"resolved": "http://localhost:8989/blobs/get/&WkLju39M7S7Fo0ag0wBPhdAHagB2f32gvxvGhsfZgfc=.sha256",
@@ -1054,11 +1184,11 @@
}
},
"ssb-contact": {
- "version": "1.2.0",
- "resolved": "http://localhost:8989/blobs/get/&V4bNrv533a7pKfPxw7Ok92hNWBN+eCbyybmi8cGMzrM=.sha256",
+ "version": "http://localhost:8989/blobs/get/&V4bNrv533a7pKfPxw7Ok92hNWBN+eCbyybmi8cGMzrM=.sha256",
+ "integrity": "sha1-lGp4PIQOWRbVEsRTiJYQlwWQzWw=",
"requires": {
- "pull-defer": "0.2.2",
- "pull-many": "1.0.8",
+ "pull-defer": "http://localhost:8989/blobs/get/&mDI2o/JC9yvFOVbeAhDN+hwTm7cK+dBwISYO49EMY24=.sha256",
+ "pull-many": "http://localhost:8989/blobs/get/&wBHfPheBEjwjjkNoeM5mWtU/tYDs8+xnt5w6C1+EK3g=.sha256",
"pull-stream": "3.6.1"
}
},
@@ -1076,14 +1206,6 @@
"version": "http://localhost:8989/blobs/get/&5yyYBZpB4w+X6kW42KMh43Xz9KP3XW79mYOj40/CHA4=.sha256",
"integrity": "sha1-Fg4kETeCqcpegGByqnpl58hl2/I="
},
- "ssb-mentions": {
- "version": "http://localhost:8989/blobs/get/&GKwsJ3ykvOXc24wyNuWBdmnCFpQ+Ltd9ggjoOuOF/Pg=.sha256",
- "integrity": "sha1-en5LsSk2uHwNcjeC+b1ZMfuFef4=",
- "requires": {
- "ssb-marked": "http://localhost:8989/blobs/get/&5yyYBZpB4w+X6kW42KMh43Xz9KP3XW79mYOj40/CHA4=.sha256",
- "ssb-ref": "http://localhost:8989/blobs/get/&wLimOD3785KVj7kBIAbjN6GH8EMhKRkcZSPrEMhdhks=.sha256"
- }
- },
"ssb-ref": {
"version": "http://localhost:8989/blobs/get/&wLimOD3785KVj7kBIAbjN6GH8EMhKRkcZSPrEMhdhks=.sha256",
"integrity": "sha1-XU7/xUXsD/1/wVuieCmmQLiir7o=",
@@ -1176,6 +1298,11 @@
"resolved": "http://localhost:8989/blobs/get/&2+Rf668b9yZcJXMyQrwOesOLYy22qOGfA0GvR3BCWJk=.sha256",
"integrity": "sha256-2+Rf668b9yZcJXMyQrwOesOLYy22qOGfA0GvR3BCWJk="
},
+ "traverse": {
+ "version": "0.3.9",
+ "resolved": "http://localhost:8989/blobs/get/&eBP2sa38eIi/Jilni5wRnDaHQPA0jLlcxH4Fex4WCUI=.sha256",
+ "integrity": "sha256-eBP2sa38eIi/Jilni5wRnDaHQPA0jLlcxH4Fex4WCUI="
+ },
"tweetnacl": {
"version": "0.14.5",
"resolved": "http://localhost:8989/blobs/get/&bOoz1nqb2D+L0lBlXHiiyJ6pErzGvpHI5lgHzmnP39Y=.sha256",
@@ -1194,6 +1321,31 @@
"resolved": "http://localhost:8989/blobs/get/&x9CnHOGgcWXdpCT6uvXvsVHIbcTZ12GYkjEOgXE31BQ=.sha256",
"integrity": "sha256-x9CnHOGgcWXdpCT6uvXvsVHIbcTZ12GYkjEOgXE31BQ="
},
+ "unzip": {
+ "version": "0.1.11",
+ "resolved": "http://localhost:8989/blobs/get/&lUPDF4rcMYrDcMNc3I0oVd9vWMwOqoEHf7ycdfWAjOo=.sha256",
+ "integrity": "sha256-lUPDF4rcMYrDcMNc3I0oVd9vWMwOqoEHf7ycdfWAjOo=",
+ "requires": {
+ "binary": "0.3.0",
+ "fstream": "0.1.31",
+ "match-stream": "0.0.2",
+ "pullstream": "0.4.1",
+ "readable-stream": "1.0.34",
+ "setimmediate": "1.0.5"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "http://localhost:8989/blobs/get/&0QEMlyAUePLZCW/tXOEhdYfVI4R19FBv4JyHzdW8VqY=.sha256",
+ "requires": {
+ "core-util-is": "http://localhost:8989/blobs/get/&pKRNq2V57ePgat5Y0m+P1kLq4JFT/VnGCPy3lRpJk5g=.sha256",
+ "inherits": "2.0.3",
+ "isarray": "http://localhost:8989/blobs/get/&PoREAgaWgArtkqCdTFJgKtx2FAo5tsjpT+fInPcKnwo=.sha256",
+ "string_decoder": "http://localhost:8989/blobs/get/&Pm5v/q/mFX6yJ4qQmvwLhFI0sTRG3KipUYwrebnCIIY=.sha256"
+ }
+ }
+ }
+ },
"validate-npm-package-license": {
"version": "http://localhost:8989/blobs/get/&FZFTRu/blzraNxOJt63Ut68JKa3cpNPwb1RBvaWZBW4=.sha256",
"integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
diff --git a/package.json b/package.json
index 76417ae..d4f48d7 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,8 @@
"ssb-marked": "^0.7.1",
"ssb-mentions": "http://localhost:8989/blobs/get/&GjuxknqKwJqHznKueFNCyIh52v1woz5PB41vqmoHfyM=.sha256",
"ssb-sort": "^1.0.0",
- "stream-to-pull-stream": "^1.7.2"
+ "stream-to-pull-stream": "^1.7.2",
+ "unzip": "^0.1.11"
},
"scripts": {
"start": "ssb-client ."