Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17f47732a0 | ||
|
|
3a46b97544 | ||
|
|
44976f4afa | ||
|
|
9da7c6ccf2 | ||
|
|
4b68eecf53 | ||
|
|
8d7058b947 | ||
|
|
933ae69d0b | ||
|
|
1af36f0a7a | ||
|
|
f4e9de5094 | ||
|
|
2ccaf404ab | ||
|
|
44c79c7646 | ||
|
|
a845d3f74d | ||
|
|
730113424c | ||
|
|
658be3004f | ||
|
|
214d0ad5c3 | ||
|
|
ca70c8a06d | ||
|
|
1c680367a7 | ||
|
|
3bd43d5ba9 | ||
|
|
0965f8f8e5 | ||
|
|
005eb603ae | ||
|
|
65a9303dff | ||
|
|
3bc6b625ec | ||
|
|
2b0dc6d17f | ||
|
|
842d790dcb | ||
|
|
20eac48349 | ||
|
|
efb80e8c33 | ||
|
|
35fbc651cd | ||
|
|
e55779ffa7 | ||
|
|
878176ea9c | ||
|
|
e3a2eab000 | ||
|
|
7478846754 | ||
|
|
8b244e6c26 | ||
|
|
19217de010 | ||
|
|
93a57b5dae | ||
|
|
defb447f29 | ||
|
|
93b73de164 | ||
|
|
ffc6124c0e | ||
|
|
ab40a992c2 | ||
|
|
5258569044 | ||
|
|
04d8055d56 | ||
|
|
68b6d54f60 | ||
|
|
a950a1e44b | ||
|
|
22f5472dbe | ||
|
|
d6d37a623d | ||
|
|
757184fbc8 | ||
|
|
043fa2c32a | ||
|
|
f94f5ca714 | ||
|
|
788bfc68bc | ||
|
|
dacc39c1d9 | ||
|
|
3fb2228031 | ||
|
|
4535178fa9 | ||
|
|
42e9e1603f | ||
|
|
9a0c3c6c62 | ||
|
|
ba864a62bf | ||
|
|
6dbfe18f58 | ||
|
|
d8c65ff1f3 | ||
|
|
426990f94e | ||
|
|
6d57929e89 | ||
|
|
2b51171592 | ||
|
|
701c9ffa5f | ||
|
|
4260b1c2b6 | ||
|
|
5e926f658d | ||
|
|
78e13bb1d3 | ||
|
|
9e5ec3406d | ||
|
|
21804d277b | ||
|
|
95d1a6b35c | ||
|
|
78395d48b4 | ||
|
|
c6795f201f | ||
|
|
8e7a362bc2 | ||
|
|
7ff3e9d017 | ||
|
|
902b0bb638 | ||
|
|
8097352a6c | ||
|
|
ecf902b73e | ||
|
|
bb0ace7e23 | ||
|
|
d964b11b8c | ||
|
|
53fa67f3bf | ||
|
|
adf7ece3e9 | ||
|
|
02d5b4d16b | ||
|
|
67f8e64140 | ||
|
|
45ceb17238 | ||
|
|
a1ee99618c | ||
|
|
de854a76f1 | ||
|
|
d59ebb44be | ||
|
|
5a2ac54c73 | ||
|
|
8fd8bae5aa | ||
|
|
5929b9b1ea | ||
|
|
aae14f1a6e | ||
|
|
96ad637882 | ||
|
|
73aa9129a8 | ||
|
|
1c89a6f6f9 | ||
|
|
c2beb96dda | ||
|
|
4c4fc3fc7f |
@@ -3,6 +3,7 @@ language: node_js
|
||||
node_js:
|
||||
- '2'
|
||||
- '4'
|
||||
- '5'
|
||||
addons:
|
||||
- postgresql: '9.3'
|
||||
script: 'make test-travis-all'
|
||||
|
||||
77
History.md
77
History.md
@@ -1,4 +1,75 @@
|
||||
|
||||
2.7.0 / 2016-02-01
|
||||
==================
|
||||
|
||||
* test: fix all test cases
|
||||
* test: fix unpublish
|
||||
* test: add complex range test case
|
||||
* feat: support semver
|
||||
|
||||
2.6.2 / 2016-01-19
|
||||
==================
|
||||
|
||||
* feat: list & show support jsonp
|
||||
* chore(package): update urllib to version 2.7.0
|
||||
* Delete install.md
|
||||
|
||||
2.6.1 / 2016-01-12
|
||||
==================
|
||||
|
||||
* fix: source registry is not cnpm, ignore check status
|
||||
|
||||
2.6.0 / 2016-01-12
|
||||
==================
|
||||
|
||||
* feat(sync): monitor sync status
|
||||
* chore(package): update agentkeepalive to version 2.0.3
|
||||
* fix SequelizeDatabaseError: ER_NO_SUCH_TABLE: Table 'qnpm.total' doesn't exist\nreproduce this bug:\nthe first startup of cnpmjs.org
|
||||
* chore(package): update moment to version 2.11.0
|
||||
* chore(package): update xss to version 0.2.10
|
||||
* chore(package): update pg-hstore to version 2.3.2
|
||||
* chore(package): update mini-logger to version 1.1.0
|
||||
* chore(package): update urllib to version 2.6.0
|
||||
* fix: row.package will json parse error
|
||||
* remove bluebird
|
||||
* chore(package): update utility to version 1.6.0
|
||||
|
||||
2.5.1 / 2015-12-02
|
||||
==================
|
||||
|
||||
* chore(package): update bluebird to version 3.0.6
|
||||
* fix: SequelizeDatabaseError
|
||||
* fix(dist_tag): disable delete latest tag
|
||||
* feat: count total private pkgs
|
||||
* fix: use isoweek. a week start from monday
|
||||
* chore(package): update xss to version 0.2.8
|
||||
* chore(package): update semver to version 5.1.0
|
||||
|
||||
2.5.0 / 2015-11-17
|
||||
==================
|
||||
|
||||
* test: add node v5
|
||||
* feat(sync): sync deleted user
|
||||
* Update show.js
|
||||
* chore(package): update bytes to version 2.2.0
|
||||
* do not sync inner username
|
||||
* gzip static file
|
||||
* chore(package): update bytes to version 2.1.0
|
||||
* chore(package): update is-type-of to version 1.0.0
|
||||
* Update static.js
|
||||
* chore(package): update cfork to version 1.4.0
|
||||
* chore(package): update bluebird to version 3.0.5
|
||||
|
||||
2.4.1 / 2015-10-27
|
||||
==================
|
||||
|
||||
* fix: improve registry index page performance with cache
|
||||
* Configable badge URL prefix.
|
||||
* chore(package): update koa-mock to version 1.5.0
|
||||
* chore(package): update urllib to version 2.5.0
|
||||
* chore(package): update co to version 4.6.0
|
||||
* chore(package): update semver to version 5.0.3
|
||||
|
||||
2.4.0 / 2015-10-21
|
||||
==================
|
||||
|
||||
@@ -23,7 +94,7 @@
|
||||
* Add mock data.
|
||||
* refactor: add more sync log
|
||||
* Fix sidebar overflow.
|
||||
* Merge pull request #680 from ibigbug/ant-design
|
||||
* Merge pull request [#680](https://github.com/cnpm/cnpmjs.org/issues/680) from ibigbug/ant-design
|
||||
* Clean code.
|
||||
* Indent.
|
||||
* chore(package): update debug to version 2.2.0
|
||||
@@ -120,10 +191,10 @@
|
||||
|
||||
* feat: support always-auth
|
||||
* fix mysql select args = [] bug
|
||||
* fix #597 sequelize raw query.
|
||||
* fix [#597](https://github.com/cnpm/cnpmjs.org/issues/597) sequelize raw query.
|
||||
* fix(markdown): hotfix markdown-it cpu problem
|
||||
* feat: upgrade to co4
|
||||
* use kcors fixes #594
|
||||
* use kcors fixes [#594](https://github.com/cnpm/cnpmjs.org/issues/594)
|
||||
|
||||
2.0.0-rc.13 / 2015-02-04
|
||||
==================
|
||||
|
||||
2
Makefile
2
Makefile
@@ -112,7 +112,7 @@ autod: install
|
||||
@node_modules/.bin/autod -w \
|
||||
--prefix "~" \
|
||||
--exclude public,view,docs,backup,coverage \
|
||||
--dep bluebird,mysql \
|
||||
--dep mysql \
|
||||
--keep should,supertest,should-http,chunkstream,mm,pedding
|
||||
@$(MAKE) install
|
||||
|
||||
|
||||
@@ -83,9 +83,10 @@ function start(options) {
|
||||
debug('save config %s to %s', configJSON, configfile);
|
||||
|
||||
// if sqlite db file not exists, init first
|
||||
initDatabase();
|
||||
initDatabase(function() {
|
||||
require('../dispatch');
|
||||
});
|
||||
|
||||
require('../dispatch');
|
||||
fs.writeFileSync(path.join(dataDir, 'pid'), process.pid + '');
|
||||
}
|
||||
|
||||
@@ -105,7 +106,7 @@ function stop(options) {
|
||||
}
|
||||
}
|
||||
|
||||
function initDatabase() {
|
||||
function initDatabase(callback) {
|
||||
var models = require('../models');
|
||||
|
||||
models.sequelize.sync({ force: false })
|
||||
@@ -117,6 +118,7 @@ function initDatabase() {
|
||||
throw err;
|
||||
} else {
|
||||
console.log('[models/init_script.js] `sqlite` sequelize sync and init success');
|
||||
callback();
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
@@ -174,12 +174,12 @@ var config = {
|
||||
// cnpm wont directly sync from this one
|
||||
// but sometimes will request it for some package infomations
|
||||
// please don't change it if not necessary
|
||||
officialNpmRegistry: 'https://registry.npmjs.org',
|
||||
officialNpmRegistry: 'https://registry.npmjs.com',
|
||||
|
||||
// sync source, upstream registry
|
||||
// If you want to directly sync from official npm's registry
|
||||
// please drop them an email first
|
||||
sourceNpmRegistry: 'http://registry.npm.taobao.org',
|
||||
sourceNpmRegistry: 'https://registry.npm.taobao.org',
|
||||
|
||||
// upstream registry is base on cnpm/cnpmjs.org or not
|
||||
// if your upstream is official npm registry, please turn it off
|
||||
@@ -210,6 +210,7 @@ var config = {
|
||||
syncDevDependencies: false,
|
||||
|
||||
// badge subject on http://shields.io/
|
||||
badgePrefixURL: 'https://img.shields.io/badge',
|
||||
badgeSubject: 'cnpm',
|
||||
|
||||
// custom user service, @see https://github.com/cnpm/cnpmjs.org/wiki/Use-Your-Own-User-Authorization
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/**!
|
||||
* cnpmjs.org - controllers/registry/package/dist_tag.js
|
||||
*
|
||||
* Copyright(c) fengmk2 and other contributors.
|
||||
* Copyright(c) cnpm and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
* Authors:
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
@@ -25,7 +23,7 @@ function ok() {
|
||||
// GET /-/package/:pkg/dist-tags -- returns the package's dist-tags
|
||||
exports.index = function* () {
|
||||
var name = this.params.name || this.params[0];
|
||||
var rows = yield* packageService.listModuleTags(name);
|
||||
var rows = yield packageService.listModuleTags(name);
|
||||
var tags = {};
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var row = rows[i];
|
||||
@@ -79,6 +77,14 @@ exports.set = function* () {
|
||||
exports.destroy = function* () {
|
||||
var name = this.params.name || this.params[0];
|
||||
var tag = this.params.tag || this.params[1];
|
||||
if (tag === 'latest') {
|
||||
this.status = 400;
|
||||
this.body = {
|
||||
error: 'dist_tag_error',
|
||||
reason: 'Can\'t not delete latest tag',
|
||||
};
|
||||
return;
|
||||
}
|
||||
yield packageService.removeModuleTagsByNames(name, tag);
|
||||
this.body = ok();
|
||||
};
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/**!
|
||||
* cnpmjs.org - controllers/registry/package/list.js
|
||||
*
|
||||
* Copyright(c) fengmk2 and other contributors.
|
||||
/**
|
||||
* Copyright(c) cnpm and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
* Authors:
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
@@ -130,6 +128,10 @@ module.exports = function* list() {
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var row = rows[i];
|
||||
var pkg = row.package;
|
||||
// pkg is string ... ignore it
|
||||
if (typeof pkg === 'string') {
|
||||
continue;
|
||||
}
|
||||
common.setDownloadURL(pkg, this);
|
||||
pkg._cnpm_publish_time = row.publish_time;
|
||||
versions[pkg.version] = pkg;
|
||||
@@ -196,5 +198,5 @@ module.exports = function* list() {
|
||||
info.license = pkg.license;
|
||||
|
||||
debug('show module %s: %s, latest: %s', orginalName, rev, latestMod.version);
|
||||
this.body = info;
|
||||
this.jsonp = info;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
@@ -44,14 +48,14 @@ module.exports = function* show() {
|
||||
if (maintainers.length > 0) {
|
||||
mod.package.maintainers = maintainers;
|
||||
}
|
||||
this.body = mod.package;
|
||||
this.jsonp = mod.package;
|
||||
return;
|
||||
}
|
||||
|
||||
// if not fond, sync from source registry
|
||||
if (!this.allowSync) {
|
||||
this.status = 404;
|
||||
this.body = {
|
||||
this.jsonp = {
|
||||
error: 'not exist',
|
||||
reason: 'version not found: ' + version
|
||||
};
|
||||
|
||||
@@ -60,8 +60,13 @@ exports.sync = function* () {
|
||||
};
|
||||
|
||||
exports.getSyncLog = function* (next) {
|
||||
var logId = this.params.id || this.params[1];
|
||||
var logId = Number(this.params.id || this.params[1]);
|
||||
var offset = Number(this.query.offset) || 0;
|
||||
|
||||
if (!logId) { // NaN
|
||||
this.status = 404;
|
||||
return;
|
||||
}
|
||||
var row = yield* Log.get(logId);
|
||||
if (!row) {
|
||||
return yield* next;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var debug = require('debug')('cnpmjs.org:proxy:sync_module_worker');
|
||||
var debug = require('debug')('cnpmjs.org:sync_module_worker');
|
||||
var co = require('co');
|
||||
var gather = require('co-gather');
|
||||
var defer = require('co-defer');
|
||||
@@ -383,11 +383,21 @@ function* _listStarUsers(modName) {
|
||||
}
|
||||
|
||||
function* _saveNpmUser(username) {
|
||||
var user = yield* npmSerivce.getUser(username);
|
||||
var user = yield npmSerivce.getUser(username);
|
||||
if (!user) {
|
||||
return;
|
||||
var existsUser = yield User.findByName(username);
|
||||
if (existsUser && existsUser.isNpmUser) {
|
||||
// delete it
|
||||
yield User.destroy({
|
||||
where: {
|
||||
name: username,
|
||||
}
|
||||
});
|
||||
return { exists: true, deleted: true, isNpmUser: true };
|
||||
}
|
||||
return { exists: false };
|
||||
}
|
||||
yield* User.saveNpmUser(user);
|
||||
yield User.saveNpmUser(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -677,7 +687,7 @@ SyncModuleWorker.prototype._sync = function* (name, pkg) {
|
||||
that.log(' [%s] %d versions: %j need to deleted',
|
||||
name, deletedVersionNames.length, deletedVersionNames);
|
||||
try {
|
||||
yield* packageService.removeModulesByNameAndVersions(name, deletedVersionNames);
|
||||
yield packageService.removeModulesByNameAndVersions(name, deletedVersionNames);
|
||||
} catch (err) {
|
||||
that.log(' [%s] delete error, %s: %s', name, err.name, err.message);
|
||||
}
|
||||
@@ -1049,7 +1059,7 @@ SyncModuleWorker.prototype._syncOneVersion = function *(versionIndex, sourcePack
|
||||
|
||||
SyncModuleWorker.sync = function* (name, username, options) {
|
||||
options = options || {};
|
||||
var result = yield* logService.create({name: name, username: username});
|
||||
var result = yield logService.create({name: name, username: username});
|
||||
var worker = new SyncModuleWorker({
|
||||
logId: result.id,
|
||||
type: options.type,
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/**!
|
||||
* cnpmjs.org - controllers/total.js
|
||||
*
|
||||
* Copyright(c) cnpmjs.org and other contributors.
|
||||
* Copyright(c) cnpm and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
* Authors:
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
|
||||
* dead_horse <dead_horse@qq.com> (http://deadhorse.me)
|
||||
*/
|
||||
|
||||
@@ -15,17 +13,24 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Total = require('../services/total');
|
||||
var version = require('../package.json').version;
|
||||
var config = require('../config');
|
||||
var getDownloadTotal = require('./utils').getDownloadTotal;
|
||||
const Total = require('../services/total');
|
||||
const version = require('../package.json').version;
|
||||
const config = require('../config');
|
||||
const getDownloadTotal = require('./utils').getDownloadTotal;
|
||||
|
||||
var startTime = '' + Date.now();
|
||||
const startTime = '' + Date.now();
|
||||
let cache = null;
|
||||
|
||||
module.exports = function* showTotal() {
|
||||
var r = yield [Total.get(), getDownloadTotal()];
|
||||
var total = r[0];
|
||||
var download = r[1];
|
||||
if (cache && Date.now() - cache.cache_time < 10000) {
|
||||
// cache 10 seconds
|
||||
this.body = cache;
|
||||
return;
|
||||
}
|
||||
|
||||
const r = yield [Total.get(), getDownloadTotal()];
|
||||
const total = r[0];
|
||||
const download = r[1];
|
||||
|
||||
total.download = download;
|
||||
total.db_name = 'registry';
|
||||
@@ -35,5 +40,8 @@ module.exports = function* showTotal() {
|
||||
total.donate = 'https://www.gittip.com/fengmk2';
|
||||
total.sync_model = config.syncModel;
|
||||
|
||||
cache = total;
|
||||
total.cache_time = Date.now();
|
||||
|
||||
this.body = total;
|
||||
};
|
||||
|
||||
@@ -56,11 +56,11 @@ exports.getDownloadTotal = function* (name) {
|
||||
var end = moment();
|
||||
var start = end.clone().subtract(1, 'months').startOf('month');
|
||||
var lastday = end.clone().subtract(1, 'days').format('YYYY-MM-DD');
|
||||
var lastweekStart = end.clone().subtract(1, 'weeks').startOf('week');
|
||||
var lastweekEnd = lastweekStart.clone().endOf('week').format('YYYY-MM-DD');
|
||||
var lastweekStart = end.clone().subtract(1, 'weeks').startOf('isoweek');
|
||||
var lastweekEnd = lastweekStart.clone().endOf('isoweek').format('YYYY-MM-DD');
|
||||
var lastmonthEnd = start.clone().endOf('month').format('YYYY-MM-DD');
|
||||
var thismonthStart = end.clone().startOf('month').format('YYYY-MM-DD');
|
||||
var thisweekStart = end.clone().startOf('week').format('YYYY-MM-DD');
|
||||
var thisweekStart = end.clone().startOf('isoweek').format('YYYY-MM-DD');
|
||||
start = start.format('YYYY-MM-DD');
|
||||
end = end.format('YYYY-MM-DD');
|
||||
lastweekStart = lastweekStart.format('YYYY-MM-DD');
|
||||
|
||||
@@ -46,7 +46,7 @@ exports.version = function* () {
|
||||
}
|
||||
version = version.replace(/\-/g, '--');
|
||||
var style = this.query.style || 'flat-square';
|
||||
var url = util.format('https://dn-img-shields-io.qbox.me/badge/%s-%s-%s.svg?style=%s',
|
||||
var url = util.format(config.badgePrefixURL + '/%s-%s-%s.svg?style=%s',
|
||||
utility.encodeURIComponent(subject), version, color, utility.encodeURIComponent(style));
|
||||
this.redirect(url);
|
||||
};
|
||||
@@ -56,7 +56,7 @@ exports.downloads = function* () {
|
||||
var name = this.params[0];
|
||||
var count = yield DownloadTotal.getTotalByName(name);
|
||||
var style = this.query.style || 'flat-square';
|
||||
var url = util.format('https://dn-img-shields-io.qbox.me/badge/downloads-%s-brightgreen.svg?style=%s',
|
||||
var url = util.format(config.badgePrefixURL + '/downloads-%s-brightgreen.svg?style=%s',
|
||||
count, utility.encodeURIComponent(style));
|
||||
this.redirect(url);
|
||||
};
|
||||
|
||||
@@ -177,7 +177,7 @@ module.exports = function* show(next) {
|
||||
pkg.engines[k] = {
|
||||
version: engine,
|
||||
title: k + ': ' + engine,
|
||||
badgeURL: 'https://dn-img-shields-io.qbox.me/badge/' + encodeURIComponent(k) +
|
||||
badgeURL: config.badgePrefixURL + '/' + encodeURIComponent(k) +
|
||||
'-' + encodeURIComponent(engine) + '-' + color + '.svg?style=flat-square',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ module.exports = function* showUser(next) {
|
||||
var data = {
|
||||
name: name,
|
||||
email: user.email,
|
||||
json: user.json || {}
|
||||
json: user.json || {},
|
||||
isNpmUser: user.isNpmUser,
|
||||
};
|
||||
|
||||
if (data.json.login) {
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
# Install & Get Started
|
||||
|
||||
## Deps
|
||||
|
||||
* MySQL Server: http://db4free.net/
|
||||
* qiniu CDN: http://www.qiniu.com/
|
||||
* redis session: https://garantiadata.com Support 24MB free spaces.
|
||||
* node: >=0.10.21
|
||||
|
||||
## Clone
|
||||
|
||||
```bash
|
||||
$ git clone git://github.com/fengmk2/cnpmjs.org.git $HOME/cnpmjs.org
|
||||
$ cd $HOME/cnpmjs.org
|
||||
```
|
||||
|
||||
## Create your `config.js`
|
||||
|
||||
```bash
|
||||
$ vim config/config.js
|
||||
```
|
||||
|
||||
`config.js` content sample:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
debug: false,
|
||||
enableCluster: true, // enable cluster mode
|
||||
logdir: 'your application log dir',
|
||||
mysqlServers: [
|
||||
{
|
||||
host: 'your mysql host',
|
||||
port: 3306,
|
||||
user: 'yourname',
|
||||
password: 'your password'
|
||||
}
|
||||
],
|
||||
mysqlDatabase: 'cnpmjs',
|
||||
redis: {
|
||||
host: 'your redist host',
|
||||
port: 6379,
|
||||
},
|
||||
qn: {
|
||||
accessKey: "your qiniu appkey",
|
||||
secretKey: "your secret key",
|
||||
bucket: "foobucket",
|
||||
domain: "http://foobucket.u.qiniudn.com"
|
||||
},
|
||||
nfs: null, // you can set a nfs to replace qiniu cdn
|
||||
enablePrivate: true, // enable private mode, only admin can publish, other use just can sync package from source npm
|
||||
admins: {
|
||||
admin: 'admin@cnpmjs.org',
|
||||
},
|
||||
syncModel: 'exist', //`all` sync all packages, `exist` only update exist packages, `none` do nothing
|
||||
};
|
||||
```
|
||||
|
||||
## Create MySQL Database and Tables
|
||||
|
||||
```bash
|
||||
$ mysql -u yourname -p
|
||||
|
||||
mysql> use cnpmjs;
|
||||
mysql> source docs/db.sql
|
||||
```
|
||||
|
||||
## Use your own CDN
|
||||
If you wan to use your own CDN instead of qiniu. Just look at `common/qnfs.js` and implement the interface like it, then pass it by set `config.nfs`.
|
||||
|
||||
## npm install
|
||||
|
||||
```bash
|
||||
$ npm install
|
||||
```
|
||||
|
||||
## start
|
||||
|
||||
```bash
|
||||
$ ./bin/nodejsctl start
|
||||
|
||||
Starting cnpmjs.org ...
|
||||
Start nodejs success. PID=27175
|
||||
```
|
||||
|
||||
## open registry and web
|
||||
|
||||
```bash
|
||||
# registry
|
||||
$ open http://localhost:7001
|
||||
# web
|
||||
$ open http://localhost:7002
|
||||
```
|
||||
|
||||
## use cnpm cli with your own registry
|
||||
You do not need to write another command line tool with your own registry,
|
||||
just alias [cnpm](http://github.com/fengmk2/cnpm), then you can get a npm client for you own registry.
|
||||
|
||||
```
|
||||
# install cnpm first
|
||||
npm install -g cnpm
|
||||
|
||||
# then alias lnpm to cnpm, but change config to your own registry
|
||||
alias lnpm='cnpm --registry=http://localhost:7001\
|
||||
--registryweb=http://localhost:7002\
|
||||
--cache=$HOME/.npm/.cache/lnpm\
|
||||
--disturl=http://cnpmjs.org/dist\
|
||||
--userconfig=$HOME/.lnpmrc'
|
||||
|
||||
#or put this in .zshrc or .bashrc
|
||||
echo "#lnpm alias\nalias lnpm='cnpm --registry=http://localhost:7001\
|
||||
--registryweb=http://localhost:7002\
|
||||
--cache=$HOME/.npm/.cache/lnpm\
|
||||
--disturl=http://cnpmjs.org/dist\
|
||||
--userconfig=$HOME/.lnpmrc'" >> $HOME/.zshrc && source $HOME/.zshrc
|
||||
```
|
||||
@@ -1,11 +1,9 @@
|
||||
/**!
|
||||
* cnpmjs.org - middleware/exists_package.js
|
||||
*
|
||||
* Copyright(c) fengmk2 and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
* Authors:
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -23,7 +23,8 @@ var staticDir = path.join(path.dirname(__dirname), 'public');
|
||||
module.exports = middlewares.staticCache(staticDir, {
|
||||
buffer: config.debug ? false : true,
|
||||
maxAge: config.debug ? 0 : 60 * 60 * 24 * 7,
|
||||
alas: {
|
||||
alias: {
|
||||
'/favicon.ico': '/favicon.png'
|
||||
}
|
||||
},
|
||||
gzip: config.enableCompress,
|
||||
});
|
||||
|
||||
31
package.json
31
package.json
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "cnpmjs.org",
|
||||
"version": "2.4.0",
|
||||
"version": "2.7.0",
|
||||
"description": "Private npm registry and web for Enterprise, base on MySQL and Simple Store Service",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "make install && make jshint && make test",
|
||||
"test": "make jshint && make test",
|
||||
"start": "./bin/nodejsctl start && cp History.md docs/web/history.md",
|
||||
"status": "./bin/nodejsctl status",
|
||||
"stop": "./bin/nodejsctl stop"
|
||||
@@ -13,11 +13,10 @@
|
||||
"cnpmjs.org": "bin/cli.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"agentkeepalive": "~1.2.0",
|
||||
"bluebird": "~2.10.2",
|
||||
"bytes": "~1.0.0",
|
||||
"cfork": "~1.3.1",
|
||||
"co": "~4.3.1",
|
||||
"agentkeepalive": "~2.0.3",
|
||||
"bytes": "~2.2.0",
|
||||
"cfork": "~1.4.0",
|
||||
"co": "~4.6.0",
|
||||
"co-defer": "~1.0.0",
|
||||
"co-gather": "~0.0.1",
|
||||
"co-sleep": "~0.0.1",
|
||||
@@ -31,29 +30,29 @@
|
||||
"gravatar": "~1.1.0",
|
||||
"humanize-ms": "~1.0.1",
|
||||
"humanize-number": "~0.0.2",
|
||||
"is-type-of": "~0.3.1",
|
||||
"is-type-of": "~1.0.0",
|
||||
"kcors": "~1.0.1",
|
||||
"koa": "~1.1.0",
|
||||
"koa-limit": "~1.0.2",
|
||||
"koa-markdown": "~2.0.1",
|
||||
"koa-middlewares": "~2.1.0",
|
||||
"koa-mock": "~1.1.4",
|
||||
"koa-mock": "~1.5.0",
|
||||
"koa-safe-jsonp": "~0.3.0",
|
||||
"markdown-it": "~3.0.6",
|
||||
"mime": "~1.3.4",
|
||||
"mini-logger": "~1.0.0",
|
||||
"mini-logger": "~1.1.0",
|
||||
"mkdirp": "~0.5.0",
|
||||
"moment": "~2.10.6",
|
||||
"moment": "~2.11.0",
|
||||
"mysql": "~2.5.4",
|
||||
"nodemailer": "~1.3.0",
|
||||
"semver": "~4.2.0",
|
||||
"semver": "~5.1.0",
|
||||
"sequelize": "~2.0.1",
|
||||
"thunkify-wrap": "~1.0.4",
|
||||
"treekill": "~1.0.0",
|
||||
"tunnel-agent": "^0.4.0",
|
||||
"urllib": "~2.2.2",
|
||||
"utility": "~1.5.0",
|
||||
"xss": "~0.1.20"
|
||||
"urllib": "~2.7.0",
|
||||
"utility": "~1.6.0",
|
||||
"xss": "~0.2.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autod": "*",
|
||||
@@ -67,7 +66,7 @@
|
||||
"node-dev": "*",
|
||||
"pedding": "*",
|
||||
"pg": "~4.4.2",
|
||||
"pg-hstore": "~2.3.1",
|
||||
"pg-hstore": "~2.3.2",
|
||||
"should": "~7.1.0",
|
||||
"should-http": "*",
|
||||
"sqlite3": "*",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
global.Promise = require('bluebird');
|
||||
var koa = require('koa');
|
||||
var app = module.exports = koa();
|
||||
var http = require('http');
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
global.Promise = require('bluebird');
|
||||
var opensearch = require('../middleware/opensearch');
|
||||
var notFound = require('../middleware/web_not_found');
|
||||
var staticCache = require('../middleware/static');
|
||||
|
||||
@@ -50,5 +50,5 @@ exports.append = function* (id, log) {
|
||||
};
|
||||
|
||||
exports.get = function* (id) {
|
||||
return yield ModuleLog.find(Number(id));
|
||||
return yield ModuleLog.find(id);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**!
|
||||
/**
|
||||
* Copyright(c) cnpm and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
@@ -12,6 +12,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var semver = require('semver');
|
||||
var models = require('../models');
|
||||
var common = require('./common');
|
||||
var Tag = models.Tag;
|
||||
@@ -25,7 +26,6 @@ var ModuleUnpublished = models.ModuleUnpublished;
|
||||
var NpmModuleMaintainer = models.NpmModuleMaintainer;
|
||||
|
||||
// module
|
||||
|
||||
var _parseRow = function (row) {
|
||||
if (row.package.indexOf('%7B%22') === 0) {
|
||||
// now store package will encodeURIComponent() after JSON.stringify
|
||||
@@ -74,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');
|
||||
};
|
||||
@@ -234,10 +246,11 @@ exports.listModulesByName = function* (moduleName) {
|
||||
},
|
||||
order: [ ['id', 'DESC'] ]
|
||||
});
|
||||
return mods.map(function (mod) {
|
||||
|
||||
for (var mod of mods) {
|
||||
parseRow(mod);
|
||||
return mod;
|
||||
});
|
||||
}
|
||||
return mods;
|
||||
};
|
||||
|
||||
exports.getModuleLastModified = function* (name) {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/**!
|
||||
* cnpmjs.org - services/total.js
|
||||
*
|
||||
* Copyright(c) fengmk2 and other contributors.
|
||||
/**
|
||||
* Copyright(c) cnpm and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
* Authors:
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/**!
|
||||
* cnpmjs.org - sync/index.js
|
||||
*
|
||||
* Copyright(c) cnpmjs.org and other contributors.
|
||||
/**
|
||||
* Copyright(c) cnpm and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
* Authors:
|
||||
* dead_horse <dead_horse@qq.com> (http://deadhorse.me)
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
@@ -14,7 +13,6 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
global.Promise = require('bluebird');
|
||||
var debug = require('debug')('cnpmjs.org:sync:index');
|
||||
var co = require('co');
|
||||
var ms = require('humanize-ms');
|
||||
@@ -49,7 +47,8 @@ function onerror(err) {
|
||||
|
||||
//set sync_status = 0 at first
|
||||
co(function* () {
|
||||
yield* totalService.updateSyncStatus(0);
|
||||
yield totalService.updateSyncStatus(0);
|
||||
yield checkSyncStatus();
|
||||
}).catch(onerror);
|
||||
|
||||
var syncInterval = ms(config.syncInterval);
|
||||
@@ -68,7 +67,7 @@ var syncFn = co.wrap(function* () {
|
||||
var data;
|
||||
var error;
|
||||
try {
|
||||
data = yield* sync();
|
||||
data = yield sync();
|
||||
} catch (err) {
|
||||
error = err;
|
||||
error.message += ' (sync package error)';
|
||||
@@ -80,6 +79,9 @@ var syncFn = co.wrap(function* () {
|
||||
}
|
||||
syncing = false;
|
||||
}
|
||||
|
||||
// check last_sync_time and last_exist_sync_time
|
||||
yield checkSyncStatus();
|
||||
});
|
||||
|
||||
if (sync) {
|
||||
@@ -104,7 +106,7 @@ var syncPopularFn = co.wrap(function* syncPopular() {
|
||||
var data;
|
||||
var error;
|
||||
try {
|
||||
data = yield* startSyncPopular();
|
||||
data = yield startSyncPopular();
|
||||
} catch (err) {
|
||||
error = err;
|
||||
error.message += ' (sync package error)';
|
||||
@@ -174,3 +176,27 @@ function sendMailToAdmin(err, result, syncTime) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function* checkSyncStatus() {
|
||||
// if source registry not cnpm, ignore it. e.g.: cnpmjs.org source registry is npmjs.org
|
||||
if (!config.sourceNpmRegistryIsCNpm) {
|
||||
return;
|
||||
}
|
||||
var total = yield totalService.getTotalInfo();
|
||||
var lastSyncTime;
|
||||
if (config.syncModel === 'all') {
|
||||
lastSyncTime = total.last_sync_time;
|
||||
} else if (config.syncModel === 'exist') {
|
||||
lastSyncTime = total.last_exist_sync_time;
|
||||
}
|
||||
debug('checkSyncStatus start, lastSyncTime: %s, syncInterval: %s', lastSyncTime, syncInterval);
|
||||
if (!lastSyncTime) {
|
||||
return;
|
||||
}
|
||||
var diff = Date.now() - lastSyncTime;
|
||||
if (diff > syncInterval * 2) {
|
||||
var err = new Error('Last sync time is expired in ' + diff + ' ms, lastSyncTime: ' + new Date(lastSyncTime));
|
||||
err.name = 'SyncExpriedError';
|
||||
sendMailToAdmin(err, null, new Date());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,6 +170,18 @@ describe('controllers/registry/package/dist_tag.test.js', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should not destroy latest tag', function(done) {
|
||||
request(app.listen())
|
||||
.delete('/-/package/@cnpmtest/dist_tag_test_module_destroy/dist-tags/latest')
|
||||
.set('authorization', utils.otherUserAuth)
|
||||
.set('content-type', 'application/json')
|
||||
.expect({
|
||||
error: 'dist_tag_error',
|
||||
reason: 'Can\'t not delete latest tag',
|
||||
})
|
||||
.expect(400, done);
|
||||
});
|
||||
|
||||
it('should 404 destroy not exists tag', function (done) {
|
||||
request(app.listen())
|
||||
.delete('/-/package/@cnpmtest/dist_tag_test_module_destroy/dist-tags/not-exists')
|
||||
|
||||
@@ -89,6 +89,13 @@ describe('controllers/registry/package/list.test.js', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should support jsonp', function (done) {
|
||||
request(app.listen())
|
||||
.get('/@cnpmtest/testmodule-list-1?callback=jsonp')
|
||||
.expect(/jsonp\(\{/)
|
||||
.expect(200, done);
|
||||
});
|
||||
|
||||
it('should 404 when package not exists', function (done) {
|
||||
request(app.listen())
|
||||
.get('/@cnpmtest/not-exists-package')
|
||||
@@ -130,18 +137,17 @@ 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');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,7 +29,15 @@ describe('controllers/registry/package/show.test.js', function () {
|
||||
.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) {
|
||||
@@ -45,6 +53,52 @@ 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 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 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')
|
||||
.expect(/jsonp\(\{/)
|
||||
.expect(200, done);
|
||||
});
|
||||
|
||||
it('should return latest tag', function (done) {
|
||||
request(app.listen())
|
||||
.get('/@cnpmtest/testmodule-show/latest')
|
||||
@@ -52,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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -123,6 +123,12 @@ describe('controllers/sync.test.js', function () {
|
||||
.get('/sync/pedding/log/123123123')
|
||||
.expect(404, done);
|
||||
});
|
||||
|
||||
it('should 404 when log id not number', function (done) {
|
||||
request(webApp.listen())
|
||||
.get('/sync/pedding/log/info.php')
|
||||
.expect(404, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('scope package', function () {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/**!
|
||||
* cnpmjs.org - test/controllers/sync_module_worker.test.js
|
||||
*
|
||||
* Copyright(c) cnpmjs.org and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
@@ -14,6 +12,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var should = require('should');
|
||||
var mm = require('mm');
|
||||
var thunkify = require('thunkify-wrap');
|
||||
var request = require('supertest');
|
||||
@@ -24,6 +23,7 @@ var logService = require('../../services/module_log');
|
||||
var packageService = require('../../services/package');
|
||||
var utils = require('../utils');
|
||||
var app = require('../../servers/registry');
|
||||
var User = require('../../models').User;
|
||||
|
||||
describe('test/controllers/sync_module_worker.test.js', function () {
|
||||
afterEach(mm.restore);
|
||||
@@ -299,5 +299,64 @@ describe('test/controllers/sync_module_worker.test.js', function () {
|
||||
var end = thunkify.event(worker, 'end');
|
||||
yield end();
|
||||
});
|
||||
|
||||
describe('sync deleted user', function() {
|
||||
before(function*() {
|
||||
var user = {
|
||||
name: 'notexistsuserscnpmtest',
|
||||
email: 'notexistsuserscnpmtest@gmail.com',
|
||||
};
|
||||
yield User.saveNpmUser(user);
|
||||
|
||||
var user = {
|
||||
name: 'existsuserscnpmtest',
|
||||
email: 'existsuserscnpmtest@gmail.com',
|
||||
password_sha: '0',
|
||||
salt: '0',
|
||||
ip: '127.0.0.1',
|
||||
};
|
||||
yield User.add(user);
|
||||
});
|
||||
|
||||
it('should not delete when cnpm user exists', function*() {
|
||||
var worker = new SyncModuleWorker({
|
||||
type: 'user',
|
||||
name: 'existsuserscnpmtest',
|
||||
username: 'fengmk2',
|
||||
});
|
||||
worker.start();
|
||||
var end = thunkify.event(worker, 'end');
|
||||
yield end();
|
||||
var user = yield User.findByName('existsuserscnpmtest');
|
||||
should.exists(user);
|
||||
user.name.should.equal('existsuserscnpmtest');
|
||||
});
|
||||
|
||||
it('should delete when user exists', function*() {
|
||||
var worker = new SyncModuleWorker({
|
||||
type: 'user',
|
||||
name: 'notexistsuserscnpmtest',
|
||||
username: 'fengmk2',
|
||||
});
|
||||
worker.start();
|
||||
var end = thunkify.event(worker, 'end');
|
||||
yield end();
|
||||
var user = yield User.findByName('notexistsuserscnpmtest');
|
||||
should.not.exists(user);
|
||||
});
|
||||
|
||||
it('should not delete when user not exists', function*() {
|
||||
var worker = new SyncModuleWorker({
|
||||
type: 'user',
|
||||
name: 'notexistsuserscnpmtest',
|
||||
username: 'fengmk2',
|
||||
});
|
||||
worker.start();
|
||||
var end = thunkify.event(worker, 'end');
|
||||
yield end();
|
||||
var user = yield User.findByName('notexistsuserscnpmtest');
|
||||
should.not.exists(user);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ var should = require('should');
|
||||
var request = require('supertest');
|
||||
var app = require('../../servers/registry');
|
||||
|
||||
describe('controllers/total.test.js', function () {
|
||||
describe('test/controllers/total.test.js', function () {
|
||||
describe('GET / in registry', function () {
|
||||
it('should return total info', function (done) {
|
||||
request(app.listen())
|
||||
@@ -29,7 +29,14 @@ describe('controllers/total.test.js', function () {
|
||||
res.body.db_name.should.equal('registry');
|
||||
res.body.store_engine.should.be.a.String;
|
||||
res.body.node_version.should.equal(process.version);
|
||||
done();
|
||||
res.body.cache_time.should.be.a.Number;
|
||||
// request again should get cache total info
|
||||
request(app.listen())
|
||||
.get('/')
|
||||
.expect(function(res2) {
|
||||
res2.body.cache_time.should.equal(res.body.cache_time);
|
||||
})
|
||||
.expect(200, done);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ var mm = require('mm');
|
||||
var app = require('../../../servers/web');
|
||||
var registry = require('../../../servers/registry');
|
||||
var utils = require('../../utils');
|
||||
var config = require('../../../config')
|
||||
|
||||
describe('controllers/web/badge.test.js', function () {
|
||||
afterEach(mm.restore);
|
||||
@@ -35,7 +36,7 @@ describe('controllers/web/badge.test.js', function () {
|
||||
should.not.exists(err);
|
||||
request(app)
|
||||
.get('/badge/v/@cnpmtest/badge-test-module.svg?style=flat-square')
|
||||
.expect('Location', 'https://dn-img-shields-io.qbox.me/badge/cnpm-1.0.1-blue.svg?style=flat-square')
|
||||
.expect('Location', config.badgePrefixURL + '/cnpm-1.0.1-blue.svg?style=flat-square')
|
||||
.expect(302, done);
|
||||
});
|
||||
});
|
||||
@@ -50,7 +51,7 @@ describe('controllers/web/badge.test.js', function () {
|
||||
should.not.exists(err);
|
||||
request(app)
|
||||
.get('/badge/v/@cnpmtest/badge-test-module.svg?style=flat-square&tag=v2')
|
||||
.expect('Location', 'https://dn-img-shields-io.qbox.me/badge/cnpm-2.0.1-blue.svg?style=flat-square')
|
||||
.expect('Location', config.badgePrefixURL + '/cnpm-2.0.1-blue.svg?style=flat-square')
|
||||
.expect(302, done);
|
||||
});
|
||||
});
|
||||
@@ -65,7 +66,7 @@ describe('controllers/web/badge.test.js', function () {
|
||||
should.not.exists(err);
|
||||
request(app)
|
||||
.get('/badge/v/@cnpmtest/badge-test-module.svg?style=flat-square&tag=v3&subject=ant-design')
|
||||
.expect('Location', 'https://dn-img-shields-io.qbox.me/badge/ant--design-3.0.1-blue.svg?style=flat-square')
|
||||
.expect('Location', config.badgePrefixURL + '/ant--design-3.0.1-blue.svg?style=flat-square')
|
||||
.expect(302, done);
|
||||
});
|
||||
});
|
||||
@@ -80,7 +81,7 @@ describe('controllers/web/badge.test.js', function () {
|
||||
should.not.exists(err);
|
||||
request(app)
|
||||
.get('/badge/v/@cnpmtest/badge-test-module.svg?style=flat-square')
|
||||
.expect('Location', 'https://dn-img-shields-io.qbox.me/badge/cnpm-1.0.0--beta1-blue.svg?style=flat-square')
|
||||
.expect('Location', config.badgePrefixURL + '/cnpm-1.0.0--beta1-blue.svg?style=flat-square')
|
||||
.expect(302, done);
|
||||
});
|
||||
});
|
||||
@@ -95,7 +96,7 @@ describe('controllers/web/badge.test.js', function () {
|
||||
should.not.exists(err);
|
||||
request(app)
|
||||
.get('/badge/v/@cnpmtest/badge-test-module.svg?style=flat-square')
|
||||
.expect('Location', 'https://dn-img-shields-io.qbox.me/badge/cnpm-0.1.0-green.svg?style=flat-square')
|
||||
.expect('Location', config.badgePrefixURL + '/cnpm-0.1.0-green.svg?style=flat-square')
|
||||
.expect(302, done);
|
||||
});
|
||||
});
|
||||
@@ -110,7 +111,7 @@ describe('controllers/web/badge.test.js', function () {
|
||||
should.not.exists(err);
|
||||
request(app)
|
||||
.get('/badge/v/@cnpmtest/badge-test-module.svg?style=flat-square')
|
||||
.expect('Location', 'https://dn-img-shields-io.qbox.me/badge/cnpm-0.0.0-red.svg?style=flat-square')
|
||||
.expect('Location', config.badgePrefixURL + '/cnpm-0.0.0-red.svg?style=flat-square')
|
||||
.expect(302, done);
|
||||
});
|
||||
});
|
||||
@@ -118,7 +119,7 @@ describe('controllers/web/badge.test.js', function () {
|
||||
it('should show invalid when package not exists', function (done) {
|
||||
request(app)
|
||||
.get('/badge/v/@cnpmtest/badge-test-module-not-exists.svg?style=flat')
|
||||
.expect('Location', 'https://dn-img-shields-io.qbox.me/badge/cnpm-invalid-lightgrey.svg?style=flat')
|
||||
.expect('Location', config.badgePrefixURL + '/cnpm-invalid-lightgrey.svg?style=flat')
|
||||
.expect(302, done);
|
||||
});
|
||||
});
|
||||
@@ -134,7 +135,7 @@ describe('controllers/web/badge.test.js', function () {
|
||||
should.not.exists(err);
|
||||
request(app)
|
||||
.get('/badge/d/@cnpmtest/badge-download-module.svg?style=flat-square')
|
||||
.expect('Location', 'https://dn-img-shields-io.qbox.me/badge/downloads-0-brightgreen.svg?style=flat-square')
|
||||
.expect('Location', config.badgePrefixURL + '/downloads-0-brightgreen.svg?style=flat-square')
|
||||
.expect(302, done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var config = require('../../../../config')
|
||||
module.exports = {
|
||||
title: 'Package - koa',
|
||||
package: {
|
||||
@@ -9,7 +10,7 @@ module.exports = {
|
||||
node: {
|
||||
version: '>= 0.11.13',
|
||||
title: 'node: >=0.11.13',
|
||||
badgeURL: 'https://dn-img-shields-io.qbox.me/badge/node-%3E%3D%200.11.13-red.svg?style=flat-square',
|
||||
badgeURL: config.badgePrefixURL + '/badge/node-%3E%3D%200.11.13-red.svg?style=flat-square',
|
||||
}
|
||||
},
|
||||
_publish_on_cnpm: false,
|
||||
|
||||
@@ -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, {});
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
var packages = scopes[scope];
|
||||
%>
|
||||
<h1>
|
||||
Private packages in <%= scope %>
|
||||
Private packages in <%= scope %>(total: <%= packages.length %>)
|
||||
</h1>
|
||||
<hr />
|
||||
<% if (!packages.length) { %>
|
||||
|
||||
@@ -20,8 +20,9 @@
|
||||
<small>(<%= user.json.fullname %>)</small>
|
||||
<% } %>
|
||||
|
||||
|
||||
<small>[<a href="/sync/user:<%= user.name %>" target="_blank">SYNC</a> profile]</small>
|
||||
<% if (user.isNpmUser) { %>
|
||||
<small>[<a href="/sync/user:<%= user.name %>" target="_blank">SYNC</a> profile]</small>
|
||||
<% } %>
|
||||
</h2>
|
||||
<div class="ant-table">
|
||||
<table class="downloads">
|
||||
|
||||
Reference in New Issue
Block a user