Compare commits

..

64 Commits

Author SHA1 Message Date
Jackson Tian
4ce752db58 dont use for-in 2015-12-08 12:09:56 +08:00
Jackson Tian
68a50963f9 improve speed via lodash 2015-12-08 12:09:56 +08:00
Yiyu He
5258569044 Merge pull request #751 from cnpm/greenkeeper-utility-1.6.0
Update utility to version 1.6.0 🚀
2015-12-05 00:26:52 +08:00
greenkeeperio-bot
04d8055d56 chore(package): update utility to version 1.6.0
http://greenkeeper.io/
2015-12-04 17:15:24 +08:00
fengmk2
68b6d54f60 Release 2.5.1 2015-12-02 23:54:28 +08:00
Yiyu He
a950a1e44b Merge pull request #749 from cnpm/greenkeeper-bluebird-3.0.6
bluebird@3.0.6 breaks build 🚨
2015-12-02 11:02:57 +08:00
greenkeeperio-bot
22f5472dbe chore(package): update bluebird to version 3.0.6
http://greenkeeper.io/
2015-12-02 01:06:03 +08:00
Yiyu He
d6d37a623d Merge pull request #744 from cnpm/fix_SequelizeDatabaseError
fix SequelizeDatabaseError
2015-11-27 17:02:59 +08:00
Jackson Tian
757184fbc8 fix SequelizeDatabaseError
SequelizeDatabaseError: ER_BAD_FIELD_ERROR: Unknown column 'NaN' in 'where clause'
2015-11-27 14:46:26 +08:00
Yiyu He
043fa2c32a Merge pull request #741 from cnpm/disable-delete-latest-tag
fix(dist_tag): disable delete latest tag
2015-11-24 22:31:06 +08:00
fengmk2
f94f5ca714 Merge pull request #736 from alsotang/analytics
use isoweek. a week start from monday
2015-11-24 18:48:41 +08:00
fengmk2
788bfc68bc fix(dist_tag): disable delete latest tag 2015-11-24 18:37:44 +08:00
fengmk2
dacc39c1d9 Merge pull request #738 from alsotang/patch-4
count total private pkgs
2015-11-23 23:07:08 +08:00
alsotang
3fb2228031 count total private pkgs 2015-11-23 22:51:38 +08:00
alsotang
4535178fa9 use isoweek. a week start from monday 2015-11-22 16:51:51 +08:00
Yiyu He
42e9e1603f Merge pull request #732 from cnpm/greenkeeper-semver-5.1.0
Update semver to version 5.1.0 🚀
2015-11-20 23:31:44 +08:00
Yiyu He
9a0c3c6c62 Merge pull request #733 from cnpm/greenkeeper-xss-0.2.8
Update xss to version 0.2.8 🚀
2015-11-20 23:31:19 +08:00
greenkeeperio-bot
ba864a62bf chore(package): update xss to version 0.2.8
http://greenkeeper.io/
2015-11-19 11:21:52 +08:00
greenkeeperio-bot
6dbfe18f58 chore(package): update semver to version 5.1.0
http://greenkeeper.io/
2015-11-19 07:18:18 +08:00
fengmk2
d8c65ff1f3 Release 2.5.0 2015-11-17 13:04:56 +08:00
Yiyu He
426990f94e Merge pull request #729 from cnpm/support-sync-deleted-user
feat(sync): sync deleted user
2015-11-17 11:09:30 +08:00
fengmk2
6d57929e89 test: add node v5 2015-11-17 10:24:52 +08:00
fengmk2
2b51171592 feat(sync): sync deleted user 2015-11-17 10:24:24 +08:00
Yiyu He
701c9ffa5f Merge pull request #728 from alsotang/patch-2
Update show.js
2015-11-16 17:26:07 +08:00
alsotang
4260b1c2b6 Update show.js
中文逗号

fix #727
2015-11-16 12:39:39 +08:00
Yiyu He
5e926f658d Merge pull request #725 from cnpm/greenkeeper-bytes-2.2.0
Update bytes to version 2.2.0 🚀
2015-11-14 16:16:22 +08:00
greenkeeperio-bot
78e13bb1d3 chore(package): update bytes to version 2.2.0
http://greenkeeper.io/
2015-11-14 09:44:10 +08:00
Yiyu He
9e5ec3406d Merge pull request #722 from alsotang/gzip_static
gzip static file
2015-11-13 00:24:01 +08:00
Yiyu He
21804d277b Merge pull request #717 from alsotang/no_sync_inner
do not sync inner username
2015-11-13 00:23:45 +08:00
alsotang
95d1a6b35c do not sync inner username 2015-11-12 22:07:33 +08:00
alsotang
78395d48b4 gzip static file 2015-11-12 22:04:45 +08:00
Yiyu He
c6795f201f Merge pull request #721 from cnpm/greenkeeper-bytes-2.1.0
Update bytes to version 2.1.0 🚀
2015-11-11 13:51:52 +08:00
greenkeeperio-bot
8e7a362bc2 chore(package): update bytes to version 2.1.0
http://greenkeeper.io/
2015-11-11 11:11:39 +08:00
Yiyu He
7ff3e9d017 Merge pull request #719 from cnpm/greenkeeper-is-type-of-1.0.0
Update is-type-of to version 1.0.0 🚀
2015-11-09 14:24:34 +08:00
greenkeeperio-bot
902b0bb638 chore(package): update is-type-of to version 1.0.0
http://greenkeeper.io/
2015-11-09 14:21:34 +08:00
Yiyu He
8097352a6c Merge pull request #714 from cnpm/greenkeeper-bluebird-3.0.5
Update bluebird to version 3.0.5 🚀
2015-11-08 23:21:26 +08:00
Yiyu He
ecf902b73e Merge pull request #718 from alsotang/patch-1
Update static.js
2015-11-08 23:14:14 +08:00
alsotang
bb0ace7e23 Update static.js 2015-11-08 18:51:45 +08:00
Yiyu He
d964b11b8c Merge pull request #715 from cnpm/greenkeeper-cfork-1.4.0
Update cfork to version 1.4.0 🚀
2015-11-04 12:07:16 +08:00
greenkeeperio-bot
53fa67f3bf chore(package): update cfork to version 1.4.0
http://greenkeeper.io/
2015-11-04 11:46:28 +08:00
greenkeeperio-bot
adf7ece3e9 chore(package): update bluebird to version 3.0.5
http://greenkeeper.io/
2015-11-01 22:40:59 +08:00
fengmk2
02d5b4d16b Release 2.4.1 2015-10-27 20:50:40 +08:00
Yiyu He
67f8e64140 Merge pull request #703 from cnpm/registry-index-cache
fix: improve registry index page performance with cache
2015-10-27 15:32:52 +08:00
fengmk2
45ceb17238 fix: improve registry index page performance with cache
cache total info in 10s

closes #695
2015-10-27 14:33:30 +08:00
fengmk2
a1ee99618c Merge pull request #701 from cnpm/greenkeeper-koa-mock-1.5.0
Update koa-mock to version 1.5.0 🚀
2015-10-27 14:23:41 +08:00
fengmk2
de854a76f1 Merge pull request #702 from ibigbug/configable-badge-url
Configable badge url
2015-10-27 13:59:04 +08:00
ibigbug
d59ebb44be test case. 2015-10-27 12:27:25 +08:00
yuwei.byw
5a2ac54c73 Use shield offical url prefix. 2015-10-27 11:54:11 +08:00
Yuwei Ba
8fd8bae5aa Configable badge URL prefix. 2015-10-27 11:52:38 +08:00
greenkeeperio-bot
5929b9b1ea chore(package): update koa-mock to version 1.5.0
http://greenkeeper.io/
2015-10-27 11:33:27 +08:00
Yiyu He
aae14f1a6e Merge pull request #697 from cnpm/greenkeeper-semver-5.0.3
Update semver to version 5.0.3 🚀
2015-10-27 00:47:20 +08:00
Yiyu He
96ad637882 Merge pull request #698 from cnpm/greenkeeper-co-4.6.0
Update co to version 4.6.0 🚀
2015-10-27 00:46:49 +08:00
Yiyu He
73aa9129a8 Merge pull request #700 from cnpm/greenkeeper-urllib-2.5.0
Update urllib to version 2.5.0 🚀
2015-10-27 00:46:37 +08:00
greenkeeperio-bot
1c89a6f6f9 chore(package): update urllib to version 2.5.0
http://greenkeeper.io/
2015-10-26 20:15:04 +08:00
greenkeeperio-bot
c2beb96dda chore(package): update co to version 4.6.0
http://greenkeeper.io/
2015-10-24 06:09:06 +08:00
greenkeeperio-bot
4c4fc3fc7f chore(package): update semver to version 5.0.3
http://greenkeeper.io/
2015-10-23 17:10:01 +08:00
fengmk2
82395fdc33 Release 2.4.0 2015-10-21 22:36:45 +08:00
fengmk2
ced4887269 Merge pull request #696 from cnpm/dependents
feat(registry): add package's dependents api
2015-10-21 21:32:39 +08:00
fengmk2
8f96a5a57b feat(registry): add package's dependents api
```
GET /-/package/:name/dependents

{
  "dependents": [ "pkg1", "pkg2" ]
}
```

closes #694
2015-10-21 21:24:59 +08:00
fengmk2
f6e79ff5e7 fix: show package's dependents
closes #694
2015-10-21 21:06:27 +08:00
fengmk2
e932f16424 Merge pull request #690 from cnpm/greenkeeper-bluebird-2.10.2
Update bluebird to version 2.10.2 🚀
2015-10-21 18:44:55 +08:00
fengmk2
622c93c3fe Merge pull request #693 from cnpm/greenkeeper-utility-1.5.0
Update utility to version 1.5.0 🚀
2015-10-21 18:44:28 +08:00
greenkeeperio-bot
ccf3e8a83c chore(package): update utility to version 1.5.0
http://greenkeeper.io/
2015-10-20 21:45:36 +08:00
greenkeeperio-bot
2069b4334c chore(package): update bluebird to version 2.10.2
http://greenkeeper.io/
2015-10-16 21:40:55 +08:00
33 changed files with 379 additions and 111 deletions

View File

@@ -1,9 +1,9 @@
sudo: false
language: node_js
node_js:
- '1'
- '2'
- '4'
- '5'
addons:
- postgresql: '9.3'
script: 'make test-travis-all'

View File

@@ -1,4 +1,48 @@
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
==================
* feat(registry): add package's dependents api
* fix: show package's dependents
* chore(package): update utility to version 1.5.0
* chore(package): update bluebird to version 2.10.2
2.3.1 / 2015-10-15
==================

View File

@@ -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

View File

@@ -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();
};

View File

@@ -0,0 +1,26 @@
/**!
* list package's dependents
*
* Copyright(c) cnpmjs.org and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <m@fengmk2.com> (http://fengmk2.com)
*/
'use strict';
/**
* Module dependencies.
*/
const packageService = require('../../../services/package');
module.exports = function*() {
const name = this.params.name || this.params[0];
const dependents = yield packageService.listDependents(name);
this.body = {
dependents: dependents,
};
};

View File

@@ -1,11 +1,9 @@
/**!
* cnpmjs.org - controllers/registry/package/list_shorts.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';
@@ -19,5 +17,5 @@ var packageService = require('../../../services/package');
// GET /-/short
// List all packages names only
module.exports = function* () {
this.body = yield* packageService.listAllPublicModuleNames();
this.body = yield packageService.listAllPublicModuleNames();
};

View File

@@ -1,11 +1,9 @@
/**!
* cnpmjs.js - controllers/registry/package/show.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';

View File

@@ -42,10 +42,15 @@ exports.list = function* () {
}
var data = yield tasks;
for (var k in data) {
if (data[k].length === 0) {
data[k] = undefined;
var keys = Object.keys(data);
for (var k = 0; k < keys.length; k++) {
var key = keys[k];
// make empty object as undefined
if (data[key].length === 0) {
data[key] = undefined;
}
}
this.body = data;
};

View File

@@ -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;

View File

@@ -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,

View File

@@ -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;
};

View File

@@ -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');

View File

@@ -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);
};

View File

@@ -1,12 +1,10 @@
/**!
* cnpmjs.org - controllers/web/package/show.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.github.com)
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
*/
'use strict';
@@ -179,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',
};
}

View File

@@ -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) {

View File

@@ -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';

View File

@@ -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,
});

View File

@@ -1,10 +1,10 @@
{
"name": "cnpmjs.org",
"version": "2.3.1",
"version": "2.5.1",
"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"
@@ -14,10 +14,10 @@
},
"dependencies": {
"agentkeepalive": "~1.2.0",
"bluebird": "~2.9.7",
"bytes": "~1.0.0",
"cfork": "~1.3.1",
"co": "~4.3.1",
"bluebird": "~3.0.6",
"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,14 +31,15 @@
"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",
"lodash": "^3.10.1",
"markdown-it": "~3.0.6",
"mime": "~1.3.4",
"mini-logger": "~1.0.0",
@@ -46,14 +47,14 @@
"moment": "~2.10.6",
"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.3.0",
"xss": "~0.1.20"
"urllib": "~2.5.0",
"utility": "~1.6.0",
"xss": "~0.2.8"
},
"devDependencies": {
"autod": "*",
@@ -91,7 +92,7 @@
"registry"
],
"engines": {
"node": ">= 1.0.0"
"node": ">= 2.0.0"
},
"author": [
"fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)",

View File

@@ -26,6 +26,7 @@ var listAll = require('../controllers/registry/package/list_all');
var listShorts = require('../controllers/registry/package/list_shorts');
var listSince = require('../controllers/registry/package/list_since');
var listAllVersions = require('../controllers/registry/package/list');
var listDependents = require('../controllers/registry/package/list_dependents');
var getOneVersion = require('../controllers/registry/package/show');
var savePackage = require('../controllers/registry/package/save');
var tag = require('../controllers/registry/package/tag');
@@ -118,6 +119,10 @@ function routes(app) {
app.get('/downloads/range/:range/:name', downloadTotal);
app.get('/downloads/range/:range', downloadTotal);
// GET /-/package/:pkg/dependents
app.get('/-/package/:name/dependents', existsPackage, listDependents);
app.get(/^\/\-\/package\/(@[\w\-\.]+\/[\w\-\.]+)\/dependents$/, existsPackage, listDependents);
// GET /-/package/:pkg/dist-tags -- returns the package's dist-tags
app.get('/-/package/:name/dist-tags', existsPackage, tags.index);
app.get(/^\/\-\/package\/(@[\w\-\.]+\/[\w\-\.]+)\/dist\-tags$/, existsPackage, tags.index);

View File

@@ -1,11 +1,9 @@
/**!
* cnpmjs.org - services/download_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';
@@ -103,7 +101,7 @@ exports.plusModuleTotal = function* (data) {
};
exports.getTotal = function* (start, end) {
return yield* exports.getModuleTotal('__all__', start, end);
return yield exports.getModuleTotal('__all__', start, end);
};
function parseYearMonth(date) {

View File

@@ -50,5 +50,5 @@ exports.append = function* (id, log) {
};
exports.get = function* (id) {
return yield ModuleLog.find(Number(id));
return yield ModuleLog.find(id);
};

View File

@@ -1,11 +1,9 @@
/**!
* cnpmjs.org - services/package.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';
@@ -14,6 +12,8 @@
* Module dependencies.
*/
var _ = require('lodash');
var models = require('../models');
var common = require('./common');
var Tag = models.Tag;
@@ -27,7 +27,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
@@ -222,11 +221,11 @@ exports.listPublicModuleNamesSince = function* (start) {
exports.listAllPublicModuleNames = function* () {
var sql = 'SELECT DISTINCT(name) AS name FROM tag ORDER BY name';
var rows = yield models.query(sql);
return rows.filter(function (row) {
return _.chain(rows).filter(function (row) {
return !common.isPrivatePackage(row.name);
}).map(function (row) {
return row.name;
});
}).value();
};
exports.listModulesByName = function* (moduleName) {
@@ -236,10 +235,10 @@ exports.listModulesByName = function* (moduleName) {
},
order: [ ['id', 'DESC'] ]
});
return mods.map(function (mod) {
return _.chain(mods).map(function (mod) {
parseRow(mod);
return mod;
});
}).value();
};
exports.getModuleLastModified = function* (name) {

View File

@@ -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')

View File

@@ -0,0 +1,54 @@
/**!
* Copyright(c) cnpm and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
*/
'use strict';
/**
* Module dependencies.
*/
const pedding = require('pedding');
const request = require('supertest');
const mm = require('mm');
const app = require('../../../../servers/registry');
const utils = require('../../../utils');
describe('test/controllers/registry/package/list_dependents.test.js', function () {
afterEach(mm.restore);
before(function (done) {
done = pedding(2, done);
const pkg = utils.getPackage('@cnpmtest/testmodule-list-dependents1', '1.0.0', utils.admin);
pkg.versions['1.0.0'].dependencies = {
'@cnpmtest/testmodule-list-dependents2': '~1.0.0',
};
request(app.listen())
.put('/' + pkg.name)
.set('authorization', utils.adminAuth)
.send(pkg)
.expect(201, done);
const pkg2 = utils.getPackage('@cnpmtest/testmodule-list-dependents2', '1.0.0', utils.admin);
request(app.listen())
.put('/' + pkg2.name)
.set('authorization', utils.adminAuth)
.send(pkg2)
.expect(201, done);
});
it('should list package dependents', function (done) {
request(app)
.get('/-/package/@cnpmtest/testmodule-list-dependents2/dependents')
.expect({
dependents: [
'@cnpmtest/testmodule-list-dependents1',
],
})
.expect(200, done);
});
});

View File

@@ -1,11 +1,9 @@
/**!
* cnpmjs.org - test/controllers/registry/package/save.test.js
*
* Copyright(c) cnpmjs.org and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
*/
'use strict';
@@ -22,7 +20,7 @@ var app = require('../../../../servers/registry');
var config = require('../../../../config');
var utils = require('../../../utils');
describe('controllers/registry/package/save.test.js', function () {
describe('test/controllers/registry/package/save.test.js', function () {
afterEach(mm.restore);
describe('no @scoped package', function () {
@@ -288,11 +286,11 @@ describe('controllers/registry/package/save.test.js', function () {
});
it('should save dependents', function* () {
var names = yield* packageService.listDependents('bytetest2');
var names = yield packageService.listDependents('bytetest2');
names.should.length(2);
names.should.eql(['@cnpmtest/testmodule-new-1', '@cnpmtest/testmodule-new-2']);
names = yield* packageService.listDependents('@cnpmtest/testmodule-new-1');
names = yield packageService.listDependents('@cnpmtest/testmodule-new-1');
names.should.length(0);
});
});

View File

@@ -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 () {

View File

@@ -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);
});
});
});
});

View File

@@ -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);
});
});

View File

@@ -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);
});
});

View File

@@ -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,
@@ -60,6 +61,10 @@ module.exports = {
supertest: '~0.13.0',
'test-console': '^0.7.1'
},
dependents: [
'cnpmjs.org',
'koa-project',
],
maintainers: [
{
name: 'fengmk2',

View File

@@ -136,8 +136,8 @@
<div class="pack-dep cols-box-item">
<div class="cols-box-title">
<%
var deps = Object.keys(package.dependencies || {})
var l = deps.length
var deps = Object.keys(package.dependencies || {});
var l = deps.length;
%>
Dependencies<%= ' (' + l + ')' %>
@@ -151,7 +151,7 @@
<a class="pack-dep-name" target="_blank" href="/package/<%= pkg %>"><%= pkg %></a>
<span class="pack-dep-ver"><%= package.dependencies[pkg]%></span>
</li>
<% }) %>
<% }); %>
</ul>
<% } else { %>
None
@@ -160,8 +160,8 @@
<div class="pack-dep cols-box-item">
<div class="cols-box-title">
<%
var deps = Object.keys(package.devDependencies || {})
var l = deps.length
var deps = Object.keys(package.devDependencies || {});
var l = deps.length;
%>
Dev Dependencies<%= ' (' + l + ')' %>
@@ -175,13 +175,36 @@
<a class="pack-dep-name" target="_blank" href="/package/<%= pkg %>"><%= pkg %></a>
<span class="pack-dep-ver"><%= package.devDependencies[pkg]%></span>
</li>
<% }) %>
<% }); %>
</ul>
<% } else { %>
None
<% } %>
</div>
<div class="pack-dep cols-box-item">
<div class="cols-box-title">
<%
var deps = package.dependents;
var l = deps.length;
%>
Dependents<%= ' (' + l + ')' %>
</div>
<% if (l) { %>
<ul>
<%
deps.forEach(function(pkg) {
%>
<li>
<a class="pack-dep-name" target="_blank" href="/package/<%= pkg %>"><%= pkg %></a>
</li>
<% }); %>
</ul>
<% } else { %>
None
<% } %>
</div>
</div>
</div>

View File

@@ -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) { %>

View File

@@ -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">