Skip to content

Commit

Permalink
add dist-tags endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
rlidwka committed May 10, 2015
1 parent 0da30ca commit c09d03b
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 19 deletions.
68 changes: 64 additions & 4 deletions lib/index-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,77 @@ module.exports = function(config, auth, storage) {
}
})

// tagging a package
app.put('/:package/:tag', can('publish'), media('application/json'), function(req, res, next) {
function tag_package_version(req, res, next) {
if (typeof(req.body) !== 'string') return next('route')

var tags = {}
tags[req.params.tag] = req.body
storage.add_tags(req.params.package, tags, function(err) {
storage.merge_tags(req.params.package, tags, function(err) {
if (err) return next(err)
res.status(201)
return next({ ok: 'package tagged' })
})
}

// tagging a package
app.put('/:package/:tag',
can('publish'), media('application/json'), tag_package_version)

app.post('/-/package/:package/dist-tags/:tag',
can('publish'), media('application/json'), tag_package_version)

app.put('/-/package/:package/dist-tags/:tag',
can('publish'), media('application/json'), tag_package_version)

app.delete('/-/package/:package/dist-tags/:tag', can('publish'), function (req, res, next) {
var tags = {}
tags[req.params.tag] = null
storage.merge_tags(req.params.package, tags, function(err) {
if (err) return next(err)
res.status(201)
return next({ ok: 'tag removed' })
})
})

app.get('/-/package/:package/dist-tags', can('access'), function(req, res, next) {
storage.get_package(req.params.package, { req: req }, function(err, info) {
if (err) return next(err)

next(info['dist-tags'])
})
})

app.post('/-/package/:package/dist-tags',
can('publish'), media('application/json'), expect_json,
function(req, res, next) {

storage.merge_tags(req.params.package, req.body, function(err) {
if (err) return next(err)
res.status(201)
return next({ ok: 'tags updated' })
})
})

app.put('/-/package/:package/dist-tags',
can('publish'), media('application/json'), expect_json,
function(req, res, next) {

storage.replace_tags(req.params.package, req.body, function(err) {
if (err) return next(err)
res.status(201)
return next({ ok: 'tags updated' })
})
})

app.delete('/-/package/:package/dist-tags',
can('publish'), media('application/json'),
function(req, res, next) {

storage.replace_tags(req.params.package, {}, function(err) {
if (err) return next(err)
res.status(201)
return next({ ok: 'tags removed' })
})
})

// publishing a package
Expand Down Expand Up @@ -271,7 +331,7 @@ module.exports = function(config, auth, storage) {
}

function add_tags(tags, cb) {
storage.add_tags(name, tags, cb)
storage.merge_tags(name, tags, cb)
}
})

Expand Down
29 changes: 28 additions & 1 deletion lib/local-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,38 @@ Storage.prototype.add_version = function(name, version, metadata, tag, callback)
}, callback)
}

Storage.prototype.add_tags = function(name, tags, callback) {
Storage.prototype.merge_tags = function(name, tags, callback) {
var self = this

self.update_package(name, function updater(data, cb) {
for (var t in tags) {
if (tags[t] === null) {
delete data['dist-tags'][t]
continue
}

if (data.versions[tags[t]] == null) {
return cb( Error[404]("this version doesn't exist") )
}

Utils.tag_version(data, tags[t], t, self.config)
}
cb()
}, callback)
}

Storage.prototype.replace_tags = function(name, tags, callback) {
var self = this

self.update_package(name, function updater(data, cb) {
data['dist-tags'] = {}

for (var t in tags) {
if (tags[t] === null) {
delete data['dist-tags'][t]
continue
}

if (data.versions[tags[t]] == null) {
return cb( Error[404]("this version doesn't exist") )
}
Expand Down
13 changes: 11 additions & 2 deletions lib/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,17 @@ Storage.prototype.add_version = function(name, version, metadata, tag, callback)
//
// Used storages: local (write)
//
Storage.prototype.add_tags = function(name, tag_hash, callback) {
return this.local.add_tags(name, tag_hash, callback)
Storage.prototype.merge_tags = function(name, tag_hash, callback) {
return this.local.merge_tags(name, tag_hash, callback)
}

//
// Tags a package version with a provided tag
//
// Used storages: local (write)
//
Storage.prototype.replace_tags = function(name, tag_hash, callback) {
return this.local.replace_tags(name, tag_hash, callback)
}

//
Expand Down
22 changes: 11 additions & 11 deletions test/functional/fixtures/tags.json
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
{
"name": "testexp_tags",
"name": "__NAME__",
"versions": {
"0.1.0": {
"name": "testexp_tags",
"name": "__NAME__",
"version": "0.1.0",
"dist": {
"shasum": "fake",
"tarball": "http://localhost:55551/testexp_tags/-/blahblah"
"tarball": "http://localhost:55551/__NAME__/-/blahblah"
}
},
"0.1.1alpha": {
"name": "testexp_tags",
"name": "__NAME__",
"version": "0.1.1alpha",
"dist": {
"shasum": "fake",
"tarball": "http://localhost:55551/testexp_tags/-/blahblah"
"tarball": "http://localhost:55551/__NAME__/-/blahblah"
}
},
"0.1.2": {
"name": "testexp_tags",
"name": "__NAME__",
"version": "0.1.2",
"dist": {
"shasum": "fake",
"tarball": "http://localhost:55551/testexp_tags/-/blahblah"
"tarball": "http://localhost:55551/__NAME__/-/blahblah"
}
},
"0.1.3alpha": {
"name": "testexp_tags",
"name": "__NAME__",
"version": "0.1.3alpha",
"dist": {
"shasum": "fake",
"tarball": "http://localhost:55551/testexp_tags/-/blahblah"
"tarball": "http://localhost:55551/__NAME__/-/blahblah"
}
},
"1.1": {
"name": "testexp_tags",
"name": "__NAME__",
"version": "1.1",
"dist": {
"shasum": "fake",
"tarball": "http://localhost:55551/testexp_tags/-/blahblah"
"tarball": "http://localhost:55551/__NAME__/-/blahblah"
}
}
},
Expand Down
123 changes: 122 additions & 1 deletion test/functional/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ module.exports = function() {
describe('tags', function() {
before(function () {
express.get('/testexp_tags', function(req, res) {
res.send(JSON.parse(readfile('fixtures/tags.json')))
var f = readfile('fixtures/tags.json').toString().replace(/__NAME__/g, 'testexp_tags')
res.send(JSON.parse(f))
})
})

Expand All @@ -44,4 +45,124 @@ module.exports = function() {
})
})
})

describe('dist-tags methods', function() {
before(function () {
express.get('/testexp_tags2', function(req, res) {
var f = readfile('fixtures/tags.json').toString().replace(/__NAME__/g, 'testexp_tags2')
res.send(JSON.parse(f))
})
})

// populate cache
before(function () {
return server.get_package('testexp_tags2')
.status(200)
})

beforeEach(function () {
return server.request({
method: 'PUT',
uri: '/-/package/testexp_tags2/dist-tags',
json: {
foo: '0.1.0',
bar: '0.1.1alpha',
baz: '0.1.2',
},
}).status(201).body_ok(/tags updated/)
})

it('fetching tags', function () {
return server.request({
method: 'GET',
uri: '/-/package/testexp_tags2/dist-tags',
}).status(200).then(function (body) {
assert.deepEqual(body,
{ foo: '0.1.0',
bar: '0.1.1alpha',
baz: '0.1.2',
latest: '0.1.3alpha' })
})
})

it('merging tags', function () {
return server.request({
method: 'POST',
uri: '/-/package/testexp_tags2/dist-tags',
json: {
foo: '0.1.2',
quux: '0.1.0',
},
}).status(201).body_ok(/updated/).then(function () {
return server.request({
method: 'GET',
uri: '/-/package/testexp_tags2/dist-tags',
}).status(200).then(function (body) {
assert.deepEqual(body,
{ foo: '0.1.2',
bar: '0.1.1alpha',
baz: '0.1.2',
quux: '0.1.0',
latest: '0.1.3alpha' })
})
})
})

it('replacing tags', function () {
return server.request({
method: 'PUT',
uri: '/-/package/testexp_tags2/dist-tags',
json: {
foo: '0.1.2',
quux: '0.1.0',
},
}).status(201).body_ok(/updated/).then(function () {
return server.request({
method: 'GET',
uri: '/-/package/testexp_tags2/dist-tags',
}).status(200).then(function (body) {
assert.deepEqual(body,
{ foo: '0.1.2',
quux: '0.1.0',
latest: '0.1.3alpha' })
})
})
})

it('adding a tag', function () {
return server.request({
method: 'PUT',
uri: '/-/package/testexp_tags2/dist-tags/foo',
json: '0.1.3alpha',
}).status(201).body_ok(/tagged/).then(function () {
return server.request({
method: 'GET',
uri: '/-/package/testexp_tags2/dist-tags',
}).status(200).then(function (body) {
assert.deepEqual(body,
{ foo: '0.1.3alpha',
bar: '0.1.1alpha',
baz: '0.1.2',
latest: '0.1.3alpha' })
})
})
})

it('removing a tag', function () {
return server.request({
method: 'DELETE',
uri: '/-/package/testexp_tags2/dist-tags/foo',
}).status(201).body_ok(/removed/).then(function () {
return server.request({
method: 'GET',
uri: '/-/package/testexp_tags2/dist-tags',
}).status(200).then(function (body) {
assert.deepEqual(body,
{ bar: '0.1.1alpha',
baz: '0.1.2',
latest: '0.1.3alpha' })
})
})
})
})
}

0 comments on commit c09d03b

Please sign in to comment.