git ssb

3+

cel / ssb-npm-registry



Commit 78ce860110b5885bd27979420dc921a600384376

Support dep

cel committed on 10/11/2017, 8:38:37 AM
Parent: ac1aa941c3eaf67a2cb8143995195708ae9e8bf3

Files changed

index.jschanged
package-lock.jsonchanged
package.jsonchanged
index.jsView
@@ -3,8 +3,12 @@
33 var path = require('path')
44 var fs = require('fs')
55 var crypto = require('crypto')
66 var pkg = require('./package')
7+var semver = require('semver')
8+var toPull = require('stream-to-pull-stream')
9+var proc = require('child_process')
10+var pull = require('pull-stream')
711
812 function pullOnce(data) {
913 var ended
1014 return function (abort, cb) {
@@ -39,8 +43,20 @@
3943 }
4044 }
4145 }
4246
47+function once(cb) {
48+ var done
49+ return function (err, result) {
50+ if (done) {
51+ if (err) console.trace(err)
52+ } else {
53+ done = true
54+ cb(err, result)
55+ }
56+ }
57+}
58+
4359 function pkgLockToRegistryPkgs(pkgLock, wsPort) {
4460 // convert a package-lock.json file into data for serving as an npm registry
4561 var hasNonBlobUrl = false
4662 var blobUrlRegex = new RegExp('^http://localhost:' + wsPort + '/blobs/get/&')
@@ -208,12 +224,25 @@
208224 })
209225 })(0)
210226 }
211227
228+SsbNpmRegistryServer.prototype.getBlob = function (id, cb) {
229+ var blobs = this.sbot.blobs
230+ blobs.size(id, function (err, size) {
231+ if (typeof size === 'number') cb(null, blobs.get(id))
232+ else blobs.want(id, function (err, got) {
233+ if (err) cb(err)
234+ else if (!got) cb('missing blob ' + id)
235+ else cb(null, blobs.get(id))
236+ })
237+ })
238+}
239+
212240 SsbNpmRegistryServer.prototype.blobDist = function (id) {
213241 var m = /^&([^.]+)\.([a-z0-9]+)$/.exec(id)
214242 if (!m) throw new Error('bad blob id: ' + id)
215243 return {
244+ ssbBlobId: id,
216245 integrity: m[2] + '-' + m[1],
217246 tarball: 'http://localhost:' + this.wsPort + '/blobs/get/' + id
218247 }
219248 }
@@ -327,9 +356,9 @@
327356 this.blobsToPush = []
328357 }
329358
330359 Req.prototype.serve = function () {
331- // console.log(this.req.method, this.req.url, this.req.socket.remoteAddress.replace(/^::ffff:/, ''))
360+ console.log(this.req.method, this.req.url, this.req.socket.remoteAddress.replace(/^::ffff:/, ''))
332361 var pathname = this.req.url.replace(/\?.*/, '')
333362 var m
334363 if (pathname === '/') return this.serveHome()
335364 if (pathname === '/bootstrap') return this.serveBootstrap()
@@ -413,8 +442,10 @@
413442 var self = this
414443 var parts = pathname.split('/')
415444 var pkgName = parts.shift()
416445 if (parts[0] === '-rev') return this.respondError(501, 'Unpublish is not supported')
446+ var spec = parts.shift()
447+ try { spec = decodeURIComponent(spec) } finally {}
417448 if (parts.length > 0) return this.respondError(404)
418449 if (self.req.method === 'PUT') return self.publishPkg(pkgName)
419450 var obj = {
420451 _id: pkgName,
@@ -424,10 +455,9 @@
424455 }
425456 var oldest, newest
426457 var getMention = self.server.getMentions({$prefix: 'npm:' + pkgName + ':'})
427458 getMention(null, function next(err, mention) {
428- if (err === true) return self.respond(200, obj)
429- if (err) return self.respondError(500, err.stack || err)
459+ if (err) return done(err === true ? null : err)
430460 var data = decodeName(mention.name)
431461 if (!data.version) return
432462 if (data.distTag) obj['dist-tags'][data.distTag] = data.version
433463 obj.versions[data.version] = {
@@ -437,8 +467,27 @@
437467 dist: self.server.blobDist(mention.link)
438468 }
439469 getMention(null, next)
440470 })
471+ function done(err) {
472+ if (err) return self.respondError(500, err.stack || err)
473+ if (spec) {
474+ var version = obj['dist-tags'][spec]
475+ || semver.maxSatisfying(Object.keys(obj.versions), spec)
476+ obj = obj.versions[version]
477+ if (!obj) return self.respondError(404, 'version not found: ' + spec)
478+ }
479+ // get dependency info, for dep(1)
480+ self.getPackageJsonFromTarballBlob(obj.dist.ssbBlobId, function (err, pkg) {
481+ if (err) return self.respondError(500, err.stack || err)
482+ if (pkg) {
483+ pkg.dist = obj.dist
484+ if (!pkg.author) pkg.author = obj.author
485+ obj = pkg
486+ }
487+ self.respond(200, obj)
488+ })
489+ }
441490 }
442491
443492 Req.prototype.servePrebuild = function (name) {
444493 var self = this
@@ -586,4 +635,27 @@
586635 console.log(msgs.map(function (msg) { return msg.key }).join('\n'))
587636 })
588637 })
589638 }
639+
640+Req.prototype.getPackageJsonFromTarballBlob = function (id, cb) {
641+ var self = this
642+ self.server.getBlob(id, function (err, readBlob) {
643+ if (err) return cb(err)
644+ cb = once(cb)
645+ var tar = proc.spawn('tar', ['-zxO', 'package/package.json'], {
646+ stdio: ['pipe', 'pipe', 'ignore']
647+ })
648+ tar.on('error', cb)
649+ tar.on('exit', function (code) {
650+ if (code) return cb(new Error('tar error: ' + code))
651+ })
652+ pull(readBlob, toPull(tar.stdin))
653+ pull(toPull(tar.stdout), pull.collect(function (err, bufs) {
654+ if (err) return cb(err)
655+ var pkg
656+ try { pkg = JSON.parse(Buffer.concat(bufs)) }
657+ catch(e) { return cb(e) }
658+ cb(null, pkg)
659+ }))
660+ })
661+}
package-lock.jsonView
@@ -1,5 +1,28 @@
11 {
22 "name": "ssb-npm-registry",
33 "version": "1.2.0",
4- "lockfileVersion": 1
4+ "lockfileVersion": 1,
5+ "requires": true,
6+ "dependencies": {
7+ "looper": {
8+ "version": "3.0.0",
9+ "resolved": "http://localhost:8989/blobs/get/&UKhTvWst16euOATlhckl4mr/zcz+aByyUJO11lMf+Jc=.sha256"
10+ },
11+ "pull-stream": {
12+ "version": "3.6.1",
13+ "resolved": "http://localhost:8989/blobs/get/&xEhoJll+9Z5EYr7s7MUgCbBhdF1nekcqnIdIKV4z2SU=.sha256"
14+ },
15+ "semver": {
16+ "version": "http://localhost:8989/blobs/get/&g9RJddYB3N4kZLtt5wGzYfSbu50VykRSS7J7Ca2xWNQ=.sha256",
17+ "integrity": "sha1-4FnAnYVx8FQII3M0M1BdOi8AsY4="
18+ },
19+ "stream-to-pull-stream": {
20+ "version": "1.7.2",
21+ "resolved": "http://localhost:8989/blobs/get/&djTfFg53BMgWrMVaCSww1ok8fAriwNnz0bsoj/MaZcI=.sha256",
22+ "requires": {
23+ "looper": "3.0.0",
24+ "pull-stream": "3.6.1"
25+ }
26+ }
27+ }
528 }
package.jsonView
@@ -7,6 +7,10 @@
77 "main": "index.js",
88 "repository": {
99 "type": "git",
1010 "url": "ssb://#ssb-npm-registry"
11+ },
12+ "dependencies": {
13+ "semver": "^5.4.1",
14+ "stream-to-pull-stream": "^1.7.2"
1115 }
1216 }

Built with git-ssb-web