Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad0722b57b | ||
|
|
6e11a2c8a7 | ||
|
|
0329cfad61 | ||
|
|
ede8a3ce5f | ||
|
|
cde4f2179e | ||
|
|
374dc17a6b | ||
|
|
626259c379 | ||
|
|
36644bda67 | ||
|
|
236e9e2fb3 | ||
|
|
b551216517 | ||
|
|
c8d9d9f075 | ||
|
|
4d43588b10 | ||
|
|
5f71add418 | ||
|
|
3fcfc6306d | ||
|
|
e78c774dbf | ||
|
|
6a54b1328f | ||
|
|
47c8273b7d | ||
|
|
0f01a4c076 | ||
|
|
17b43e3ae4 | ||
|
|
7fd6b10ddf | ||
|
|
7f16050f9e | ||
|
|
f57d525452 | ||
|
|
f05046b8bd | ||
|
|
a34aa7d72f | ||
|
|
72646ffee2 | ||
|
|
060fc65ffb | ||
|
|
4169ee9c6e | ||
|
|
51f380a800 | ||
|
|
c90062e7a0 | ||
|
|
26007f8318 | ||
|
|
0146ce5c30 | ||
|
|
87518df394 | ||
|
|
e49f5474f6 | ||
|
|
af4401fc62 | ||
|
|
c2d608a5cc | ||
|
|
b91b160b66 | ||
|
|
46a3df95bd | ||
|
|
d08aee047e | ||
|
|
406d8cf9a1 | ||
|
|
e1b9ab6b09 | ||
|
|
71f9014777 | ||
|
|
adca5adff2 | ||
|
|
1857f1d0e5 | ||
|
|
2d56820e8b | ||
|
|
119094b230 | ||
|
|
744b6e1e15 |
@@ -1,11 +1,10 @@
|
||||
sudo: false
|
||||
language: node_js
|
||||
node_js:
|
||||
- '2'
|
||||
- '4'
|
||||
- '5'
|
||||
addons:
|
||||
- postgresql: '9.3'
|
||||
script: 'make test-travis-all'
|
||||
after_script:
|
||||
- "npm i codecov.io && cat ./coverage/coverage.json | ./node_modules/codecov.io/bin/codecov.io.js"
|
||||
- "npm i codecov && codecov"
|
||||
|
||||
2
AUTHORS
2
AUTHORS
@@ -6,4 +6,6 @@ alsotang <alsotang@gmail.com> (https://github.com/alsotang)
|
||||
4simple <wondger@qq.com> (https://github.com/4simple)
|
||||
afc163 <afc163@gmail.com> (https://github.com/afc163)
|
||||
Yuwei Ba <i@xiaoba.me> (https://github.com/ibigbug)
|
||||
dickeylth <dickeylth@gmail.com> (https://github.com/dickeylth)
|
||||
|
||||
|
||||
|
||||
52
History.md
52
History.md
@@ -1,11 +1,61 @@
|
||||
|
||||
2.9.3 / 2016-04-05
|
||||
==================
|
||||
|
||||
* fix: use better diff time to check sync status
|
||||
* Update sequelize to version 3.21.0 🚀
|
||||
* chore(package): update agentkeepalive to version 2.1.0
|
||||
* chore(package): update pg to version 4.5.2
|
||||
|
||||
2.9.2 / 2016-03-29
|
||||
==================
|
||||
|
||||
* fix: override antd for ul & ol list number & icon.
|
||||
|
||||
2.9.1 / 2016-03-29
|
||||
==================
|
||||
|
||||
* refactor: add more ua info on syncer
|
||||
|
||||
2.9.0 / 2016-03-26
|
||||
==================
|
||||
|
||||
* feat: only admin can unpublish
|
||||
* chore(package): update gravatar to version 1.5.0
|
||||
* chore(package): update sequelize to version 3.20.0
|
||||
* fix: fix save download count unqiue constraint error
|
||||
* chore(package): update moment to version 2.12.0
|
||||
|
||||
2.8.1 / 2016-03-07
|
||||
==================
|
||||
|
||||
* fix: only send warning email if no any sync data after 24h
|
||||
* chore(package): update kcors to version 1.1.0
|
||||
* chore(package): update koa to version 1.2.0
|
||||
* chore(package): update urllib to version 2.8.0
|
||||
|
||||
2.8.0 / 2016-02-23
|
||||
==================
|
||||
|
||||
* fix: convert `*` to latest tag
|
||||
* deps: upgrade deps and remove node 2.0.0 support
|
||||
* doc: update sponsors on readme
|
||||
* fix: update copyright year
|
||||
* doc: fix disturl typo
|
||||
* deps: sequelize@3.19.0
|
||||
|
||||
2.7.1 / 2016-02-01
|
||||
==================
|
||||
|
||||
* fix(semver): when have invalid version([#817](https://github.com/cnpm/cnpmjs.org/issues/817))
|
||||
|
||||
2.7.0 / 2016-02-01
|
||||
==================
|
||||
|
||||
* test: fix all test cases
|
||||
* test: fix unpublish
|
||||
* test: add complex range test case
|
||||
* feat: support semver
|
||||
* feat: support semver([#816](https://github.com/cnpm/cnpmjs.org/issues/816))
|
||||
|
||||
2.6.2 / 2016-01-19
|
||||
==================
|
||||
|
||||
31
Makefile
31
Makefile
@@ -3,17 +3,10 @@ REPORTER = spec
|
||||
TIMEOUT = 30000
|
||||
MOCHA_OPTS =
|
||||
DB = sqlite
|
||||
DISTURL = https://npm.taobao.org/mirrors/iojs
|
||||
BIN = iojs
|
||||
|
||||
ifeq ($(findstring io.js, $(shell which node)),)
|
||||
BIN = node
|
||||
DISTURL = https://npm.taobao.org/mirrors/node
|
||||
endif
|
||||
|
||||
install:
|
||||
@npm install --build-from-source --registry=http://registry.npm.taobao.org \
|
||||
--disturl=$(DISTURL)
|
||||
@npm install --build-from-source --registry=https://registry.npm.taobao.org \
|
||||
--disturl=https://npm.taobao.org/mirrors/node
|
||||
|
||||
install-production production:
|
||||
@NODE_ENV=production $(MAKE) install
|
||||
@@ -22,7 +15,7 @@ jshint: install
|
||||
@-node_modules/.bin/jshint ./
|
||||
|
||||
init-database:
|
||||
@$(BIN) test/init_db.js
|
||||
@node test/init_db.js
|
||||
|
||||
init-mysql:
|
||||
@mysql -uroot -e 'DROP DATABASE IF EXISTS cnpmjs_test;'
|
||||
@@ -38,7 +31,7 @@ test: install init-database
|
||||
--timeout $(TIMEOUT) \
|
||||
--require should \
|
||||
--require should-http \
|
||||
--require co-mocha \
|
||||
--require thunk-mocha \
|
||||
--require ./test/init.js \
|
||||
$(MOCHA_OPTS) \
|
||||
$(TESTS)
|
||||
@@ -55,15 +48,15 @@ test-pg: init-pg
|
||||
test-all: test-sqlite test-mysql
|
||||
|
||||
test-cov cov: install init-database
|
||||
@NODE_ENV=test DB=${DB} $(BIN) \
|
||||
node_modules/.bin/istanbul cover --preserve-comments \
|
||||
@NODE_ENV=test DB=${DB} node \
|
||||
node_modules/.bin/istanbul cover \
|
||||
node_modules/.bin/_mocha \
|
||||
-- -u exports \
|
||||
--reporter $(REPORTER) \
|
||||
--timeout $(TIMEOUT) \
|
||||
--require should \
|
||||
--require should-http \
|
||||
--require co-mocha \
|
||||
--require thunk-mocha \
|
||||
--require ./test/init.js \
|
||||
$(MOCHA_OPTS) \
|
||||
$(TESTS)
|
||||
@@ -75,16 +68,16 @@ test-cov-mysql: init-mysql
|
||||
@$(MAKE) test-cov DB=mysql
|
||||
|
||||
test-travis: install init-database
|
||||
@NODE_ENV=test DB=${DB} CNPM_SOURCE_NPM=http://registry.npmjs.com CNPM_SOURCE_NPM_ISCNPM=false \
|
||||
$(BIN) \
|
||||
node_modules/.bin/istanbul cover --preserve-comments \
|
||||
@NODE_ENV=test DB=${DB} CNPM_SOURCE_NPM=https://registry.npmjs.com CNPM_SOURCE_NPM_ISCNPM=false \
|
||||
node \
|
||||
node_modules/.bin/istanbul cover \
|
||||
node_modules/.bin/_mocha \
|
||||
-- -u exports \
|
||||
--reporter dot \
|
||||
--timeout $(TIMEOUT) \
|
||||
--require should \
|
||||
--require should-http \
|
||||
--require co-mocha \
|
||||
--require thunk-mocha \
|
||||
--require ./test/init.js \
|
||||
$(MOCHA_OPTS) \
|
||||
$(TESTS)
|
||||
@@ -103,7 +96,7 @@ test-travis-pg:
|
||||
test-travis-all: test-travis-sqlite test-travis-mysql test-travis-pg
|
||||
|
||||
dev:
|
||||
@NODE_ENV=development $(BIN) node_modules/.bin/node-dev --harmony dispatch.js
|
||||
@NODE_ENV=development node node_modules/.bin/node-dev dispatch.js
|
||||
|
||||
contributors: install
|
||||
@node_modules/.bin/contributors -f plain -o AUTHORS
|
||||
|
||||
@@ -71,7 +71,7 @@ as well as [New features in 2.x](https://github.com/cnpm/cnpmjs.org/wiki/New-fea
|
||||
|
||||
### Dependencies
|
||||
|
||||
* [node](http://nodejs.org) >=0.11.12, use `--harmony`
|
||||
* [node](http://nodejs.org) >= 4.3.1
|
||||
* Databases: only required one type
|
||||
* [sqlite3](https://npm.taobao.org/package/sqlite3) >= 3.0.2, we use `sqlite3` by default
|
||||
* [MySQL](http://dev.mysql.com/downloads/) >= 0.5.0, include `mysqld` and `mysql cli`. I test on `mysql@5.6.16`.
|
||||
@@ -111,7 +111,8 @@ Tips: make sure your code is following the [node-style-guide](https://github.com
|
||||
|
||||
## Sponsors
|
||||
|
||||
- [](http://www.ucloud.cn?sem=sdk-CNPMJS)
|
||||
- [](https://www.aliyun.com?from=cnpmjs.org) (2016.2 - now)
|
||||
- [](http://www.ucloud.cn?sem=sdk-CNPMJS) (2015.3 - 2016.3)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**!
|
||||
/**
|
||||
* Copyright(c) cnpmjs.org and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
|
||||
@@ -107,10 +107,12 @@ defer.setInterval(function* () {
|
||||
try {
|
||||
yield* downloadTotalService.plusModuleTotal({ name: name, date: date, count: count });
|
||||
} catch (err) {
|
||||
err.message += '; name: ' + name + ', count: ' + count + ', date: ' + date;
|
||||
logger.error(err);
|
||||
if (err.name !== 'SequelizeUniqueConstraintError') {
|
||||
err.message += '; name: ' + name + ', count: ' + count + ', date: ' + date;
|
||||
logger.error(err);
|
||||
}
|
||||
// save back to _downloads, try again next time
|
||||
_downloads[name] = (_downloads[name] || 0) + count;
|
||||
}
|
||||
}
|
||||
}, 5000);
|
||||
}, 5000 + Math.ceil(Math.random() * 1000));
|
||||
|
||||
@@ -30,15 +30,18 @@ var config = require('../../../config');
|
||||
module.exports = function* show() {
|
||||
var name = this.params.name || this.params[0];
|
||||
var tag = this.params.version || this.params[1];
|
||||
if (tag === '*') {
|
||||
tag = 'latest';
|
||||
}
|
||||
var version = semver.valid(tag);
|
||||
var range = semver.validRange(tag);
|
||||
var mod;
|
||||
if (version) {
|
||||
mod = yield* packageService.getModule(name, version);
|
||||
mod = yield packageService.getModule(name, version);
|
||||
} else if (range) {
|
||||
mod = yield* packageService.getModuleByRange(name, range);
|
||||
mod = yield packageService.getModuleByRange(name, range);
|
||||
} else {
|
||||
mod = yield* packageService.getModuleByTag(name, tag);
|
||||
mod = yield packageService.getModuleByTag(name, tag);
|
||||
}
|
||||
|
||||
if (mod) {
|
||||
@@ -63,7 +66,7 @@ module.exports = function* show() {
|
||||
}
|
||||
|
||||
// start sync
|
||||
var logId = yield* SyncModuleWorker.sync(name, 'sync-by-install');
|
||||
var logId = yield SyncModuleWorker.sync(name, 'sync-by-install');
|
||||
debug('start sync %s, get log id %s', name, logId);
|
||||
|
||||
this.redirect(config.officialNpmRegistry + this.url);
|
||||
|
||||
@@ -38,7 +38,11 @@ var User = require('../models').User;
|
||||
var os = require('os');
|
||||
|
||||
var USER_AGENT = 'sync.cnpmjs.org/' + config.version +
|
||||
' hostname/' + os.hostname() + ' ' + urllib.USER_AGENT;
|
||||
' hostname/' + os.hostname() +
|
||||
' syncModel/' + config.syncModel +
|
||||
' syncInterval/' + config.syncInterval +
|
||||
' syncConcurrency/' + config.syncConcurrency +
|
||||
' ' + urllib.USER_AGENT;
|
||||
|
||||
function SyncModuleWorker(options) {
|
||||
EventEmitter.call(this);
|
||||
|
||||
@@ -4,10 +4,10 @@ So `cnpm` is meaning: **Company npm**.
|
||||
|
||||
## Registry
|
||||
|
||||
- Our public registry: [r.cnpmjs.org](//r.cnpmjs.org), syncing from [registry.npmjs.org](//registry.npmjs.org)
|
||||
- Our public registry: [r.cnpmjs.org](//r.cnpmjs.org), syncing from [registry.npmjs.org](https://registry.npmjs.org)
|
||||
- [cnpmjs.org](/) version: <span id="app-version"></span>
|
||||
- [Node.js](https://nodejs.org) version: <span id="node-version"></span>
|
||||
- For developers behind the GFW, please visit [the Chinese mirror](https://npm.taobao.org). 中国用户请访问[国内镜像站点](https://npm.taobao.org/)。
|
||||
- For developers in China, please visit [the China mirror](https://npm.taobao.org). 中国用户请访问[国内镜像站点](https://npm.taobao.org/)。
|
||||
|
||||
<div class="ant-table">
|
||||
<table class="downloads">
|
||||
@@ -65,7 +65,7 @@ Default style is `flat-square`.
|
||||
|
||||
### Version
|
||||
|
||||
Badge URL: `http://cnpmjs.org/badge/v/cnpmjs.org.svg` 
|
||||
Badge URL: `https://cnpmjs.org/badge/v/cnpmjs.org.svg` 
|
||||
|
||||
* `<0.1.0 & >=0.0.0`: 
|
||||
* `<1.0.0 & >=0.1.0`: 
|
||||
@@ -73,34 +73,34 @@ Badge URL: `http://cnpmjs.org/badge/v/cnpmjs.org.svg` 
|
||||
Badge URL: `https://cnpmjs.org/badge/d/cnpmjs.org.svg` 
|
||||
|
||||
## Usage
|
||||
|
||||
use our npm client [cnpm](https://github.com/cnpm/cnpm)(More suitable with cnpmjs.org and gzip support), you can get our client through npm:
|
||||
|
||||
```bash
|
||||
$ npm install -g cnpm --registry=http://registry.npm.taobao.org
|
||||
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
|
||||
```
|
||||
|
||||
Or you can alias NPM to use it:
|
||||
|
||||
```bash
|
||||
alias cnpm="npm --registry=http://registry.npm.taobao.org \
|
||||
alias cnpm="npm --registry=https://registry.npm.taobao.org \
|
||||
--cache=$HOME/.npm/.cache/cnpm \
|
||||
--disturl=http://registry.npm.taobao.org/mirrors/node \
|
||||
--disturl=https://npm.taobao.org/mirrors/node \
|
||||
--userconfig=$HOME/.cnpmrc"
|
||||
|
||||
#Or alias it in .bashrc or .zshrc
|
||||
$ echo '\n#alias for cnpm\nalias cnpm="npm --registry=http://registry.npm.taobao.org \
|
||||
$ echo '\n#alias for cnpm\nalias cnpm="npm --registry=https://registry.npm.taobao.org \
|
||||
--cache=$HOME/.npm/.cache/cnpm \
|
||||
--disturl=http://registry.npm.taobao.org/mirrors/node \
|
||||
--disturl=https://npm.taobao.org/mirrors/node \
|
||||
--userconfig=$HOME/.cnpmrc"' >> ~/.zshrc && source ~/.zshrc
|
||||
```
|
||||
|
||||
### install
|
||||
|
||||
Install package from [r.cnpmjs.org](//r.cnpmjs.org). When installing a package or version does not exist, it will try to install from the official registry([registry.npmjs.org](//registry.npmjs.org)), and sync this package to cnpm in the backend.
|
||||
Install package from [r.cnpmjs.org](//r.cnpmjs.org). When installing a package or version does not exist, it will try to install from the official registry([registry.npmjs.org](https://registry.npmjs.org)), and sync this package to cnpm in the backend.
|
||||
|
||||
```bash
|
||||
$ cnpm install [name]
|
||||
@@ -151,4 +151,5 @@ Release [History](/history).
|
||||
|
||||
## Sponsors
|
||||
|
||||
- [](http://www.ucloud.cn?sem=sdk-CNPMJS)
|
||||
- [](https://www.aliyun.com?from=cnpmjs.org) (2016.2 - now)
|
||||
- [](http://www.ucloud.cn?sem=sdk-CNPMJS) (2015.3 - 2016.3)
|
||||
|
||||
24
middleware/unpublishable.js
Normal file
24
middleware/unpublishable.js
Normal file
@@ -0,0 +1,24 @@
|
||||
/**!
|
||||
* cnpmjs.org - middleware/unpublishable.js
|
||||
*
|
||||
* Copyright(c) cnpmjs.org and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
* Authors:
|
||||
* dead_horse <dead_horse@qq.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function *unpublishable(next) {
|
||||
// only admin user can unpublish
|
||||
if (!this.user.isAdmin) {
|
||||
this.status = 403;
|
||||
this.body = {
|
||||
error: 'no_perms',
|
||||
reason: 'Only administrators can unpublish module',
|
||||
};
|
||||
return;
|
||||
}
|
||||
yield next;
|
||||
};
|
||||
@@ -37,7 +37,7 @@ module.exports = {
|
||||
|
||||
query: function* (sql, args) {
|
||||
var options = { replacements: args };
|
||||
var data = yield this.sequelize.query(sql, options).spread();
|
||||
var data = yield this.sequelize.query(sql, options);
|
||||
if (/select /i.test(sql)) {
|
||||
return data[0];
|
||||
}
|
||||
|
||||
@@ -35,7 +35,10 @@ if (username) {
|
||||
|
||||
var models = require('./');
|
||||
|
||||
models.sequelize.sync({ force: force })
|
||||
models.sequelize.sync({
|
||||
force: force,
|
||||
logging: console.log,
|
||||
})
|
||||
.then(function () {
|
||||
models.Total.init(function (err) {
|
||||
if (err) {
|
||||
|
||||
@@ -70,7 +70,7 @@ module.exports = function (sequelize, DataTypes) {
|
||||
});
|
||||
if (row) {
|
||||
row.package = pkg;
|
||||
if (row.isDirty) {
|
||||
if (row.changed()) {
|
||||
row = yield row.save(['package']);
|
||||
}
|
||||
return row;
|
||||
|
||||
@@ -155,7 +155,7 @@ module.exports = function (sequelize, DataTypes) {
|
||||
user.json = data;
|
||||
user.email = data.email || '';
|
||||
user.rev = data._rev || '';
|
||||
if (user.isDirty) {
|
||||
if (user.changed()) {
|
||||
user = yield user.save();
|
||||
}
|
||||
return user;
|
||||
@@ -182,7 +182,7 @@ module.exports = function (sequelize, DataTypes) {
|
||||
user.rev = rev;
|
||||
user.salt = salt;
|
||||
user.password_sha = passwordSha;
|
||||
if (user.isDirty) {
|
||||
if (user.changed()) {
|
||||
user = yield user.save();
|
||||
}
|
||||
return user;
|
||||
|
||||
30
package.json
30
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cnpmjs.org",
|
||||
"version": "2.7.0",
|
||||
"version": "2.9.3",
|
||||
"description": "Private npm registry and web for Enterprise, base on MySQL and Simple Store Service",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -13,26 +13,26 @@
|
||||
"cnpmjs.org": "bin/cli.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"agentkeepalive": "~2.0.3",
|
||||
"bytes": "~2.2.0",
|
||||
"agentkeepalive": "~2.1.0",
|
||||
"bytes": "~2.3.0",
|
||||
"cfork": "~1.4.0",
|
||||
"co": "~4.6.0",
|
||||
"co-defer": "~1.0.0",
|
||||
"co-gather": "~0.0.1",
|
||||
"co-sleep": "~0.0.1",
|
||||
"commander": "~2.6.0",
|
||||
"commander": "~2.9.0",
|
||||
"copy-to": "~2.0.1",
|
||||
"debug": "~2.2.0",
|
||||
"error-formater": "~1.0.3",
|
||||
"fs-cnpm": "~1.2.0",
|
||||
"giturl": "^1.0.0",
|
||||
"graceful": "~1.0.0",
|
||||
"gravatar": "~1.1.0",
|
||||
"gravatar": "~1.5.0",
|
||||
"humanize-ms": "~1.0.1",
|
||||
"humanize-number": "~0.0.2",
|
||||
"is-type-of": "~1.0.0",
|
||||
"kcors": "~1.0.1",
|
||||
"koa": "~1.1.0",
|
||||
"kcors": "~1.1.0",
|
||||
"koa": "~1.2.0",
|
||||
"koa-limit": "~1.0.2",
|
||||
"koa-markdown": "~2.0.1",
|
||||
"koa-middlewares": "~2.1.0",
|
||||
@@ -42,22 +42,21 @@
|
||||
"mime": "~1.3.4",
|
||||
"mini-logger": "~1.1.0",
|
||||
"mkdirp": "~0.5.0",
|
||||
"moment": "~2.11.0",
|
||||
"mysql": "~2.5.4",
|
||||
"moment": "~2.12.0",
|
||||
"mysql": "~2.10.2",
|
||||
"nodemailer": "~1.3.0",
|
||||
"semver": "~5.1.0",
|
||||
"sequelize": "~2.0.1",
|
||||
"sequelize": "~3.21.0",
|
||||
"thunkify-wrap": "~1.0.4",
|
||||
"treekill": "~1.0.0",
|
||||
"tunnel-agent": "^0.4.0",
|
||||
"urllib": "~2.7.0",
|
||||
"urllib": "~2.8.0",
|
||||
"utility": "~1.6.0",
|
||||
"xss": "~0.2.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autod": "*",
|
||||
"chunkstream": "*",
|
||||
"co-mocha": "*",
|
||||
"contributors": "*",
|
||||
"istanbul": "*",
|
||||
"jshint": "*",
|
||||
@@ -65,12 +64,13 @@
|
||||
"mocha": "*",
|
||||
"node-dev": "*",
|
||||
"pedding": "*",
|
||||
"pg": "~4.4.2",
|
||||
"pg": "~4.5.2",
|
||||
"pg-hstore": "~2.3.2",
|
||||
"should": "~7.1.0",
|
||||
"should-http": "*",
|
||||
"sqlite3": "*",
|
||||
"supertest": "*"
|
||||
"supertest": "*",
|
||||
"thunk-mocha": "1"
|
||||
},
|
||||
"homepage": "https://github.com/cnpm/cnpmjs.org",
|
||||
"repository": {
|
||||
@@ -90,7 +90,7 @@
|
||||
"registry"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 2.0.0"
|
||||
"node": ">= 4.3.1"
|
||||
},
|
||||
"author": [
|
||||
"fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)",
|
||||
|
||||
@@ -292,3 +292,6 @@ pre code {
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
ul, ol{
|
||||
list-style: initial;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ var publishable = require('../middleware/publishable');
|
||||
var syncByInstall = require('../middleware/sync_by_install');
|
||||
var editable = require('../middleware/editable');
|
||||
var existsPackage = require('../middleware/exists_package');
|
||||
var unpublishable = require('../middleware/unpublishable');
|
||||
|
||||
var showTotal = require('../controllers/total');
|
||||
|
||||
@@ -94,16 +95,16 @@ function routes(app) {
|
||||
|
||||
// delete tarball and remove one version
|
||||
app.delete(/^\/(@[\w\-\.]+\/[\w\-\.]+)\/download\/(@[\w\-\.]+\/[\w\-\.]+)\/\-rev\/([\w\-\.]+)$/,
|
||||
login, publishable, editable, removeOneVersion);
|
||||
app.delete('/:name/download/:filename/-rev/:rev', login, publishable, editable, removeOneVersion);
|
||||
login, unpublishable, removeOneVersion);
|
||||
app.delete('/:name/download/:filename/-rev/:rev', login, unpublishable, removeOneVersion);
|
||||
|
||||
// update module, unpublish will PUT this
|
||||
app.put(/^\/(@[\w\-\.]+\/[\w\-\.]+)\/\-rev\/([\w\-\.]+)$/, login, publishable, editable, updatePackage);
|
||||
app.put('/:name/-rev/:rev', login, publishable, editable, updatePackage);
|
||||
|
||||
// remove all versions
|
||||
app.delete(/^\/(@[\w\-\.]+\/[\w\-\.]+)\/\-rev\/([\w\-\.]+)$/, login, publishable, editable, removePackage);
|
||||
app.delete('/:name/-rev/:rev', login, publishable, editable, removePackage);
|
||||
app.delete(/^\/(@[\w\-\.]+\/[\w\-\.]+)\/\-rev\/([\w\-\.]+)$/, login, unpublishable, removePackage);
|
||||
app.delete('/:name/-rev/:rev', login, unpublishable, removePackage);
|
||||
|
||||
// try to create a new user
|
||||
// https://registry.npmjs.org/-/user/org.couchdb.user:fengmk2
|
||||
|
||||
@@ -72,7 +72,7 @@ exports.plusModuleTotal = function* (data) {
|
||||
row[field] = utility.toSafeNumber(row[field]);
|
||||
}
|
||||
row[field] += data.count;
|
||||
if (row.isDirty) {
|
||||
if (row.changed()) {
|
||||
yield row.save();
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ exports.plusModuleTotal = function* (data) {
|
||||
row[field] = utility.toSafeNumber(row[field]);
|
||||
}
|
||||
row[field] += data.count;
|
||||
if (row.isDirty) {
|
||||
if (row.changed()) {
|
||||
return yield row.save();
|
||||
}
|
||||
return row;
|
||||
|
||||
@@ -50,5 +50,5 @@ exports.append = function* (id, log) {
|
||||
};
|
||||
|
||||
exports.get = function* (id) {
|
||||
return yield ModuleLog.find(id);
|
||||
return yield ModuleLog.findById(id);
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ function stringifyPackage(pkg) {
|
||||
}
|
||||
|
||||
exports.getModuleById = function* (id) {
|
||||
var row = yield Module.find(Number(id));
|
||||
var row = yield Module.findById(Number(id));
|
||||
parseRow(row);
|
||||
return row;
|
||||
};
|
||||
@@ -75,11 +75,13 @@ exports.getModuleByTag = function* (name, tag) {
|
||||
};
|
||||
|
||||
exports.getModuleByRange = function* (name, range) {
|
||||
var rows = yield* exports.listModulesByName(name);
|
||||
var rows = yield exports.listModulesByName(name);
|
||||
var versionMap = {};
|
||||
var versions = rows.map(function(row) {
|
||||
versionMap[row.version] = row;
|
||||
return row.version;
|
||||
}).filter(function(version) {
|
||||
return semver.valid(version);
|
||||
});
|
||||
|
||||
var version = semver.maxSatisfying(versions, range);
|
||||
@@ -295,7 +297,7 @@ exports.saveModule = function* (mod) {
|
||||
item.dist_size = dist.size;
|
||||
item.description = description;
|
||||
|
||||
if (item.isDirty) {
|
||||
if (item.changed()) {
|
||||
item = yield item.save();
|
||||
}
|
||||
var result = {
|
||||
@@ -327,7 +329,7 @@ exports.saveModule = function* (mod) {
|
||||
};
|
||||
|
||||
exports.updateModulePackage = function* (id, pkg) {
|
||||
var mod = yield Module.find(Number(id));
|
||||
var mod = yield Module.findById(Number(id));
|
||||
if (!mod) {
|
||||
// not exists
|
||||
return null;
|
||||
@@ -380,8 +382,9 @@ exports.updateModuleLastModified = function* (name) {
|
||||
if (!row) {
|
||||
return null;
|
||||
}
|
||||
row.gmt_modified = new Date();
|
||||
return yield row.save(['gmt_modified']);
|
||||
// gmt_modified is readonly, we must use setDataValue
|
||||
row.setDataValue('gmt_modified', new Date());
|
||||
return yield row.save();
|
||||
};
|
||||
|
||||
exports.removeModulesByName = function* (name) {
|
||||
@@ -418,7 +421,7 @@ exports.addModuleTag = function* (name, tag, version) {
|
||||
}
|
||||
row.module_id = mod.id;
|
||||
row.version = version;
|
||||
if (row.isDirty) {
|
||||
if (row.changed()) {
|
||||
return yield row.save();
|
||||
}
|
||||
return row;
|
||||
@@ -594,7 +597,7 @@ exports.addKeyword = function* (data) {
|
||||
item = ModuleKeyword.build(data);
|
||||
}
|
||||
item.description = data.description;
|
||||
if (item.isDirty) {
|
||||
if (item.changed()) {
|
||||
// make sure object will change, otherwise will cause empty sql error
|
||||
// @see https://github.com/cnpm/cnpmjs.org/issues/533
|
||||
return yield item.save();
|
||||
|
||||
@@ -194,9 +194,12 @@ function* checkSyncStatus() {
|
||||
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';
|
||||
var oneDay = 3600000 * 24;
|
||||
var maxTime = Math.max(oneDay, syncInterval * 2);
|
||||
if (diff > maxTime) {
|
||||
var err = new Error('Last sync time is expired in ' + diff + ' ms, lastSyncTime: ' +
|
||||
new Date(lastSyncTime) + ', maxTime: ' + maxTime + ' ms');
|
||||
err.name = 'SyncExpiredError';
|
||||
sendMailToAdmin(err, null, new Date());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@ describe('test/controllers/registry/package/remove.test.js', function () {
|
||||
afterEach(mm.restore);
|
||||
|
||||
before(function (done) {
|
||||
var pkg = utils.getPackage('@cnpmtest/testmodule-remove-1', '1.0.0', utils.admin);
|
||||
var pkg = utils.getPackage('@cnpmtest/testmodule-remove-1', '1.0.0', utils.otherUser);
|
||||
request(app.listen())
|
||||
.put('/' + pkg.name)
|
||||
.set('authorization', utils.adminAuth)
|
||||
.set('authorization', utils.otherUserAuth)
|
||||
.send(pkg)
|
||||
.expect(201, done);
|
||||
});
|
||||
@@ -56,47 +56,13 @@ describe('test/controllers/registry/package/remove.test.js', function () {
|
||||
.expect(404, done);
|
||||
});
|
||||
|
||||
it('should delete 403 when user is not admin on config.enablePrivate = true', function (done) {
|
||||
mm(config, 'enablePrivate', true);
|
||||
it('should delete 403 when user is not admin', function (done) {
|
||||
request(app)
|
||||
.del('/@cnpmtest/testmodule-remove-1/-rev/1')
|
||||
.set('authorization', utils.otherUserAuth)
|
||||
.expect({
|
||||
error: 'no_perms',
|
||||
reason: 'Private mode enable, only admin can publish this module'
|
||||
})
|
||||
.expect(403, done);
|
||||
});
|
||||
|
||||
it('should 400 when scope not exists', function (done) {
|
||||
request(app)
|
||||
.del('/@cnpm-not-exists/testmodule-remove-1/-rev/1')
|
||||
.set('authorization', utils.otherUserAuth)
|
||||
.expect({
|
||||
error: 'invalid scope',
|
||||
reason: 'scope @cnpm-not-exists not match legal scopes: @cnpm, @cnpmtest, @cnpm-test'
|
||||
})
|
||||
.expect(400, done);
|
||||
});
|
||||
|
||||
it('should 403 when delete non scoped package', function (done) {
|
||||
request(app)
|
||||
.del('/testmodule-remove-1/-rev/1')
|
||||
.set('authorization', utils.otherUserAuth)
|
||||
.expect({
|
||||
error: 'no_perms',
|
||||
reason: 'only allow publish with @cnpm, @cnpmtest, @cnpm-test scope(s)'
|
||||
})
|
||||
.expect(403, done);
|
||||
});
|
||||
|
||||
it('should 403 when user not maintainer', function (done) {
|
||||
request(app)
|
||||
.del('/@cnpmtest/testmodule-remove-1/-rev/1')
|
||||
.set('authorization', utils.otherUserAuth)
|
||||
.expect({
|
||||
error: 'forbidden user',
|
||||
reason: 'cnpmjstest101 not authorized to modify @cnpmtest/testmodule-remove-1'
|
||||
reason: 'Only administrators can unpublish module'
|
||||
})
|
||||
.expect(403, done);
|
||||
});
|
||||
|
||||
@@ -27,10 +27,10 @@ describe('controllers/registry/package/remove_version.test.js', function () {
|
||||
|
||||
var lastRev;
|
||||
before(function (done) {
|
||||
var pkg = utils.getPackage('@cnpmtest/testmodule-remove_version-1', '0.0.1', utils.admin);
|
||||
var pkg = utils.getPackage('@cnpmtest/testmodule-remove_version-1', '0.0.1', utils.otherUser);
|
||||
request(app.listen())
|
||||
.put('/' + pkg.name)
|
||||
.set('authorization', utils.adminAuth)
|
||||
.set('authorization', utils.otherUserAuth)
|
||||
.send(pkg)
|
||||
.expect(201, function (err, res) {
|
||||
should.not.exist(err);
|
||||
@@ -78,7 +78,7 @@ describe('controllers/registry/package/remove_version.test.js', function () {
|
||||
.expect(401, done);
|
||||
});
|
||||
|
||||
it('should 403 when auth error', function (done) {
|
||||
it('should 403 when not admin', function (done) {
|
||||
request(app)
|
||||
.del('/@cnpmtest/testmodule-remove_version-1/download/@cnpmtest/testmodule-remove_version-1-0.0.1.tgz/-rev/' + lastRev)
|
||||
.set('authorization', utils.otherUserAuth)
|
||||
@@ -94,10 +94,10 @@ describe('controllers/registry/package/remove_version.test.js', function () {
|
||||
|
||||
describe('mock error', function () {
|
||||
before(function (done) {
|
||||
var pkg = utils.getPackage('@cnpmtest/testmodule-remove_version-1', '0.0.2', utils.admin);
|
||||
var pkg = utils.getPackage('@cnpmtest/testmodule-remove_version-1', '0.0.2', utils.otherUser);
|
||||
request(app.listen())
|
||||
.put('/' + pkg.name)
|
||||
.set('authorization', utils.adminAuth)
|
||||
.set('authorization', utils.otherUserAuth)
|
||||
.send(pkg)
|
||||
.expect(201, done);
|
||||
});
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/**!
|
||||
* cnpmjs.org - test/controllers/registry/package/show.test.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)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
@@ -20,10 +18,10 @@ var mm = require('mm');
|
||||
var app = require('../../../../servers/registry');
|
||||
var utils = require('../../../utils');
|
||||
|
||||
describe('controllers/registry/package/show.test.js', function () {
|
||||
describe('test/controllers/registry/package/show.test.js', function () {
|
||||
afterEach(mm.restore);
|
||||
|
||||
before(function (done) {
|
||||
before(function(done) {
|
||||
var pkg = utils.getPackage('@cnpmtest/testmodule-show', '0.0.1', utils.admin);
|
||||
request(app.listen())
|
||||
.put('/' + pkg.name)
|
||||
@@ -40,6 +38,15 @@ describe('controllers/registry/package/show.test.js', function () {
|
||||
});
|
||||
});
|
||||
|
||||
before(function(done) {
|
||||
var pkg = utils.getPackage('@cnpmtest/testmodule-only-beta', '1.0.0-beta.1', utils.admin);
|
||||
request(app.listen())
|
||||
.put('/' + pkg.name)
|
||||
.set('authorization', utils.adminAuth)
|
||||
.send(pkg)
|
||||
.expect(201, done);
|
||||
});
|
||||
|
||||
it('should return one version', function (done) {
|
||||
request(app.listen())
|
||||
.get('/@cnpmtest/testmodule-show/0.0.1')
|
||||
@@ -92,6 +99,19 @@ describe('controllers/registry/package/show.test.js', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the only beta version', function (done) {
|
||||
request(app.listen())
|
||||
.get('/@cnpmtest/testmodule-only-beta/*')
|
||||
.expect(200, function (err, res) {
|
||||
should.not.exist(err);
|
||||
var data = res.body;
|
||||
data.name.should.equal('@cnpmtest/testmodule-only-beta');
|
||||
data.version.should.equal('1.0.0-beta.1');
|
||||
data.dist.tarball.should.containEql('/@cnpmtest/testmodule-only-beta/download/@cnpmtest/testmodule-only-beta-1.0.0-beta.1.tgz');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should support jsonp', function (done) {
|
||||
request(app.listen())
|
||||
.get('/@cnpmtest/testmodule-show/0.0.1?callback=jsonp')
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/**!
|
||||
* cnpmjs.org - test/services/default_user_service.test.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';
|
||||
@@ -47,7 +45,7 @@ describe('services/default_user_service.test.js', function () {
|
||||
email: 'fengmk2@gmail.com',
|
||||
name: 'cnpmjstest10',
|
||||
html_url: 'http://cnpmjs.org/~cnpmjstest10',
|
||||
avatar_url: 'https://secure.gravatar.com/avatar/95b9d41231617a05ced5604d242c9670?s=50&d=retro',
|
||||
avatar_url: 'https://s.gravatar.com/avatar/95b9d41231617a05ced5604d242c9670?s=50&d=retro',
|
||||
im_url: '',
|
||||
site_admin: true,
|
||||
scopes: ['@cnpm', '@cnpmtest'],
|
||||
@@ -69,7 +67,7 @@ describe('services/default_user_service.test.js', function () {
|
||||
email: 'fengmk2@gmail.com',
|
||||
name: 'cnpmjstest10',
|
||||
html_url: 'http://cnpmjs.org/~cnpmjstest10',
|
||||
avatar_url: 'https://secure.gravatar.com/avatar/95b9d41231617a05ced5604d242c9670?s=50&d=retro',
|
||||
avatar_url: 'https://s.gravatar.com/avatar/95b9d41231617a05ced5604d242c9670?s=50&d=retro',
|
||||
im_url: '',
|
||||
site_admin: true,
|
||||
scopes: ['@cnpm', '@cnpmtest'],
|
||||
@@ -84,7 +82,7 @@ describe('services/default_user_service.test.js', function () {
|
||||
email: 'fengmk2@gmail.com',
|
||||
name: 'cnpmjstest101',
|
||||
html_url: 'http://cnpmjs.org/~cnpmjstest101',
|
||||
avatar_url: 'https://secure.gravatar.com/avatar/95b9d41231617a05ced5604d242c9670?s=50&d=retro',
|
||||
avatar_url: 'https://s.gravatar.com/avatar/95b9d41231617a05ced5604d242c9670?s=50&d=retro',
|
||||
im_url: '',
|
||||
site_admin: false,
|
||||
scopes: ['@cnpm', '@cnpmtest'],
|
||||
@@ -99,7 +97,7 @@ describe('services/default_user_service.test.js', function () {
|
||||
email: 'fengmk2@gmail.com',
|
||||
name: 'Yuan Feng',
|
||||
html_url: 'http://cnpmjs.org/~fengmk2',
|
||||
avatar_url: 'https://secure.gravatar.com/avatar/95b9d41231617a05ced5604d242c9670?s=50&d=retro',
|
||||
avatar_url: 'https://s.gravatar.com/avatar/95b9d41231617a05ced5604d242c9670?s=50&d=retro',
|
||||
im_url: '',
|
||||
site_admin: true,
|
||||
scopes: ['@cnpm', '@cnpmtest'],
|
||||
|
||||
@@ -349,6 +349,16 @@ describe('test/services/package.test.js', function () {
|
||||
mod.name.should.equal('test-getModuleByRange-module-1');
|
||||
mod.version.should.equal('1.1.0');
|
||||
});
|
||||
|
||||
it('should get package with semver range when have invalid version', function* () {
|
||||
yield* createModule('test-getModuleByRange-module-2', '1.0.0');
|
||||
yield* createModule('test-getModuleByRange-module-2', '1.1.0');
|
||||
yield* createModule('test-getModuleByRange-module-2', 'next');
|
||||
var mod = yield* Package.getModuleByRange('test-getModuleByRange-module-2', '1');
|
||||
mod.package.name.should.equal(mod.name);
|
||||
mod.name.should.equal('test-getModuleByRange-module-2');
|
||||
mod.version.should.equal('1.1.0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateModulePackage()', function () {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Copyright 2013 - 2014 © cnpmjs.org
|
||||
Copyright 2013 - 2016 © cnpmjs.org
|
||||
|
|
||||
<a href="/">Home</a>
|
||||
|
|
||||
<script>var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_5757157'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s17.cnzz.com/stat.php%3Fid%3D5757157%26online%3D1%26show%3Dline' type='text/javascript'%3E%3C/script%3E"));</script>
|
||||
<script>var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_5757157'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s17.cnzz.com/stat.php%3Fid%3D5757157%26online%3D1%26show%3Dline' type='text/javascript'%3E%3C/script%3E"));</script>
|
||||
|
||||
Reference in New Issue
Block a user