From 8d7058b9479318ac9569ad267df521aac14f1eb6 Mon Sep 17 00:00:00 2001 From: dead_horse Date: Sat, 30 Jan 2016 20:42:56 +0800 Subject: [PATCH 1/4] feat: support semver e.x. `/npm/~1.0.0` --- controllers/registry/package/show.js | 4 ++++ routes/registry.js | 4 ++-- services/package.js | 13 +++++++++++ .../controllers/registry/package/show.test.js | 22 +++++++++++++++++++ test/services/package.test.js | 20 +++++++++++++++++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/controllers/registry/package/show.js b/controllers/registry/package/show.js index f1c432425..7f104e9fa 100644 --- a/controllers/registry/package/show.js +++ b/controllers/registry/package/show.js @@ -31,12 +31,16 @@ module.exports = function* show() { var name = this.params.name || this.params[0]; var tag = this.params.version || this.params[1]; var version = semver.valid(tag); + var range = semver.validRange(tag); var mod; if (version) { mod = yield* packageService.getModule(name, version); + } else if (range) { + mod = yield* packageService.getModuleByRange(name, range); } else { mod = yield* packageService.getModuleByTag(name, tag); } + if (mod) { setDownloadURL(mod.package, this); mod.package._cnpm_publish_time = mod.publish_time; diff --git a/routes/registry.js b/routes/registry.js index 46884012c..846210c61 100644 --- a/routes/registry.js +++ b/routes/registry.js @@ -65,9 +65,9 @@ function routes(app) { // module // scope package: params: [$name] - app.get(/^\/(@[\w\-\.]+\/[\w\-\.]+)$/, syncByInstall, listAllVersions); + app.get(/^\/(@[\w\-\.]+\/[^\/]+)$/, syncByInstall, listAllVersions); // scope package: params: [$name, $version] - app.get(/^\/(@[\w\-\.]+\/[\w\-\.]+)\/([\w\.\-]+)$/, syncByInstall, getOneVersion); + app.get(/^\/(@[\w\-\.]+\/[\w\-\.]+)\/([^\/]+)$/, syncByInstall, getOneVersion); app.get('/:name', syncByInstall, listAllVersions); app.get('/:name/:version', syncByInstall, getOneVersion); diff --git a/services/package.js b/services/package.js index 66669de92..3bb555c08 100644 --- a/services/package.js +++ b/services/package.js @@ -12,6 +12,7 @@ * Module dependencies. */ +var semver = require('semver'); var models = require('../models'); var common = require('./common'); var Tag = models.Tag; @@ -73,6 +74,18 @@ exports.getModuleByTag = function* (name, tag) { return yield* exports.getModule(tag.name, tag.version); }; +exports.getModuleByRange = function* (name, range) { + var rows = yield* exports.listModulesByName(name); + var versionMap = {}; + var versions = rows.map(function(row) { + versionMap[row.version] = row; + return row.version; + }); + + var version = semver.maxSatisfying(versions, range); + return versionMap[version]; +}; + exports.getLatestModule = function* (name) { return yield* exports.getModuleByTag(name, 'latest'); }; diff --git a/test/controllers/registry/package/show.test.js b/test/controllers/registry/package/show.test.js index 285346955..589e797dc 100644 --- a/test/controllers/registry/package/show.test.js +++ b/test/controllers/registry/package/show.test.js @@ -16,6 +16,7 @@ var should = require('should'); var request = require('supertest'); +var pedding = require('pedding'); var mm = require('mm'); var app = require('../../../../servers/registry'); var utils = require('../../../utils'); @@ -24,12 +25,20 @@ describe('controllers/registry/package/show.test.js', function () { afterEach(mm.restore); before(function (done) { + done = pedding(done, 2); var pkg = utils.getPackage('@cnpmtest/testmodule-show', '0.0.1', utils.admin); request(app.listen()) .put('/' + pkg.name) .set('authorization', utils.adminAuth) .send(pkg) .expect(201, done); + + pkg = utils.getPackage('@cnpmtest/testmodule-show', '1.1.0', utils.admin); + request(app.listen()) + .put('/' + pkg.name) + .set('authorization', utils.adminAuth) + .send(pkg) + .expect(201, done); }); it('should return one version', function (done) { @@ -45,6 +54,19 @@ describe('controllers/registry/package/show.test.js', function () { }); }); + it('should return max satisfied package with semver range', function (done) { + request(app.listen()) + .get('/@cnpmtest/testmodule-show/^1.0.0') + .expect(200, function (err, res) { + should.not.exist(err); + var data = res.body; + data.name.should.equal('@cnpmtest/testmodule-show'); + data.version.should.equal('1.1.0'); + data.dist.tarball.should.containEql('/@cnpmtest/testmodule-show/download/@cnpmtest/testmodule-show-1.1.0.tgz'); + done(); + }); + }); + it('should support jsonp', function (done) { request(app.listen()) .get('/@cnpmtest/testmodule-show/0.0.1?callback=jsonp') diff --git a/test/services/package.test.js b/test/services/package.test.js index 31dea41e4..545537309 100644 --- a/test/services/package.test.js +++ b/test/services/package.test.js @@ -331,6 +331,26 @@ describe('test/services/package.test.js', function () { }); }); + describe('getModuleByRange()', function() { + it('should get undefined when not match semver range', function* () { + yield* createModule('test-getModuleByRange-module-0', '1.0.0'); + yield* createModule('test-getModuleByRange-module-0', '1.1.0'); + yield* createModule('test-getModuleByRange-module-0', '2.0.0'); + var mod = yield* Package.getModuleByRange('test-getModuleByRange-module-0', '~2.1.0'); + should.not.exist(mod); + }); + + it('should get package with semver range', function* () { + yield* createModule('test-getModuleByRange-module-1', '1.0.0'); + yield* createModule('test-getModuleByRange-module-1', '1.1.0'); + yield* createModule('test-getModuleByRange-module-1', '2.0.0'); + var mod = yield* Package.getModuleByRange('test-getModuleByRange-module-1', '1'); + mod.package.name.should.equal(mod.name); + mod.name.should.equal('test-getModuleByRange-module-1'); + mod.version.should.equal('1.1.0'); + }); + }); + describe('updateModulePackage()', function () { it('should update not exists package return null', function* () { var r = yield* Package.updateModulePackage(101010101, {}); From 4b68eecf53b53b19e900c03ece9a79db7ac6130c Mon Sep 17 00:00:00 2001 From: dead_horse Date: Sat, 30 Jan 2016 23:08:27 +0800 Subject: [PATCH 2/4] test: add complex range test case --- test/controllers/registry/package/show.test.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/controllers/registry/package/show.test.js b/test/controllers/registry/package/show.test.js index 589e797dc..91086bc55 100644 --- a/test/controllers/registry/package/show.test.js +++ b/test/controllers/registry/package/show.test.js @@ -67,6 +67,19 @@ describe('controllers/registry/package/show.test.js', function () { }); }); + it('should return max satisfied package with complex semver range', function (done) { + request(app.listen()) + .get('/@cnpmtest/testmodule-show/>1.2.0 <=2 || 0.0.1') + .expect(200, function (err, res) { + should.not.exist(err); + var data = res.body; + data.name.should.equal('@cnpmtest/testmodule-show'); + data.version.should.equal('0.0.1'); + data.dist.tarball.should.containEql('/@cnpmtest/testmodule-show/download/@cnpmtest/testmodule-show-0.0.1.tgz'); + done(); + }); + }); + it('should support jsonp', function (done) { request(app.listen()) .get('/@cnpmtest/testmodule-show/0.0.1?callback=jsonp') From 9da7c6ccf2d0efd61fa8a1ae1871608e4f045483 Mon Sep 17 00:00:00 2001 From: dead_horse Date: Sun, 31 Jan 2016 00:14:46 +0800 Subject: [PATCH 3/4] test: fix unpublish --- test/controllers/registry/package/list.test.js | 8 ++++---- test/controllers/registry/package/show.test.js | 13 +++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/test/controllers/registry/package/list.test.js b/test/controllers/registry/package/list.test.js index 0f70b9cc1..576d6717c 100644 --- a/test/controllers/registry/package/list.test.js +++ b/test/controllers/registry/package/list.test.js @@ -137,18 +137,18 @@ describe('controllers/registry/package/list.test.js', function () { describe('unpublished', function () { before(function (done) { - utils.sync('tfs', done); + utils.sync('moduletest1', done); }); it('should show unpublished info', function (done) { mm(config, 'syncModel', 'all'); request(app.listen()) - .get('/tfs') + .get('/moduletest1') .expect(404, function (err, res) { should.not.exist(err); var data = res.body; - data.time.unpublished.name.should.equal('fengmk2'); - data.time.unpublished.description.should.equal('tfs'); + data.time.unpublished.name.should.equal('dead_horse'); + data.time.unpublished.description.should.equal('moduletest1'); done(); }); }); diff --git a/test/controllers/registry/package/show.test.js b/test/controllers/registry/package/show.test.js index 91086bc55..6f3145cb0 100644 --- a/test/controllers/registry/package/show.test.js +++ b/test/controllers/registry/package/show.test.js @@ -80,6 +80,19 @@ describe('controllers/registry/package/show.test.js', function () { }); }); + it('should return max satisfied package with *', function (done) { + request(app.listen()) + .get('/@cnpmtest/testmodule-show/*') + .expect(200, function (err, res) { + should.not.exist(err); + var data = res.body; + data.name.should.equal('@cnpmtest/testmodule-show'); + data.version.should.equal('1.1.0'); + data.dist.tarball.should.containEql('/@cnpmtest/testmodule-show/download/@cnpmtest/testmodule-show-1.1.0.tgz'); + done(); + }); + }); + it('should support jsonp', function (done) { request(app.listen()) .get('/@cnpmtest/testmodule-show/0.0.1?callback=jsonp') From 44976f4afa866fb33563e5b15c636d3122bd37d5 Mon Sep 17 00:00:00 2001 From: dead_horse Date: Sun, 31 Jan 2016 02:11:24 +0800 Subject: [PATCH 4/4] test: fix all test cases --- .../controllers/registry/package/list.test.js | 1 - .../controllers/registry/package/show.test.js | 21 +++++++++---------- test/controllers/web/package/show.test.js | 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/test/controllers/registry/package/list.test.js b/test/controllers/registry/package/list.test.js index 576d6717c..230306db3 100644 --- a/test/controllers/registry/package/list.test.js +++ b/test/controllers/registry/package/list.test.js @@ -148,7 +148,6 @@ describe('controllers/registry/package/list.test.js', function () { should.not.exist(err); var data = res.body; data.time.unpublished.name.should.equal('dead_horse'); - data.time.unpublished.description.should.equal('moduletest1'); done(); }); }); diff --git a/test/controllers/registry/package/show.test.js b/test/controllers/registry/package/show.test.js index 6f3145cb0..195e55c9b 100644 --- a/test/controllers/registry/package/show.test.js +++ b/test/controllers/registry/package/show.test.js @@ -16,7 +16,6 @@ var should = require('should'); var request = require('supertest'); -var pedding = require('pedding'); var mm = require('mm'); var app = require('../../../../servers/registry'); var utils = require('../../../utils'); @@ -25,20 +24,20 @@ describe('controllers/registry/package/show.test.js', function () { afterEach(mm.restore); before(function (done) { - done = pedding(done, 2); var pkg = utils.getPackage('@cnpmtest/testmodule-show', '0.0.1', utils.admin); request(app.listen()) .put('/' + pkg.name) .set('authorization', utils.adminAuth) .send(pkg) - .expect(201, done); - - pkg = utils.getPackage('@cnpmtest/testmodule-show', '1.1.0', utils.admin); - request(app.listen()) - .put('/' + pkg.name) - .set('authorization', utils.adminAuth) - .send(pkg) - .expect(201, done); + .expect(201, function(err) { + should.not.exist(err); + pkg = utils.getPackage('@cnpmtest/testmodule-show', '1.1.0', utils.admin); + request(app.listen()) + .put('/' + pkg.name) + .set('authorization', utils.adminAuth) + .send(pkg) + .expect(201, done); + }); }); it('should return one version', function (done) { @@ -107,7 +106,7 @@ describe('controllers/registry/package/show.test.js', function () { should.not.exist(err); var data = res.body; data.name.should.equal('@cnpmtest/testmodule-show'); - data.version.should.equal('0.0.1'); + data.version.should.equal('1.1.0'); done(); }); }); diff --git a/test/controllers/web/package/show.test.js b/test/controllers/web/package/show.test.js index 287e897d7..c3ab21685 100644 --- a/test/controllers/web/package/show.test.js +++ b/test/controllers/web/package/show.test.js @@ -121,7 +121,7 @@ describe('controllers/web/package/show.test.js', function () { it('should display unpublished info', function (done) { mm(config, 'syncModel', 'all'); request(app) - .get('/package/tfs') + .get('/package/moduletest1') .expect(200) .expect(/This package has been unpublished\./, done); });