Compare commits
2 Commits
fix/sql-na
...
leoric-orm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31294a819b | ||
|
|
9d9b834488 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -30,3 +30,4 @@ config/web_readme.md
|
||||
.tmp/
|
||||
*.sqlite
|
||||
|
||||
run/
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
node_modules/
|
||||
coverage/
|
||||
.tmp/
|
||||
.git/
|
||||
tools/
|
||||
public/
|
||||
test/
|
||||
95
.jshintrc
95
.jshintrc
@@ -1,95 +0,0 @@
|
||||
{
|
||||
// JSHint Default Configuration File (as on JSHint website)
|
||||
// See http://jshint.com/docs/ for more details
|
||||
|
||||
"maxerr" : 50, // {int} Maximum error before stopping
|
||||
|
||||
// Enforcing
|
||||
"bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
|
||||
"camelcase" : false, // true: Identifiers must be in camelCase
|
||||
"curly" : true, // true: Require {} for every new block or scope
|
||||
"eqeqeq" : true, // true: Require triple equals (===) for comparison
|
||||
"forin" : false, // true: Require filtering for..in loops with obj.hasOwnProperty()
|
||||
"immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
|
||||
"indent" : false, // {int} Number of spaces to use for indentation
|
||||
"latedef" : false, // true: Require variables/functions to be defined before being used
|
||||
"newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()`
|
||||
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
|
||||
"noempty" : true, // true: Prohibit use of empty blocks
|
||||
"nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
|
||||
"plusplus" : false, // true: Prohibit use of `++` & `--`
|
||||
"quotmark" : false, // Quotation mark consistency:
|
||||
// false : do nothing (default)
|
||||
// true : ensure whatever is used is consistent
|
||||
// "single" : require single quotes
|
||||
// "double" : require double quotes
|
||||
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
|
||||
"unused" : true, // true: Require all defined variables be used
|
||||
"strict" : true, // true: Requires all functions run in ES5 Strict Mode
|
||||
"trailing" : false, // true: Prohibit trailing whitespaces
|
||||
"maxparams" : false, // {int} Max number of formal params allowed per function
|
||||
"maxdepth" : false, // {int} Max depth of nested blocks (within functions)
|
||||
"maxstatements" : false, // {int} Max number statements per function
|
||||
"maxcomplexity" : false, // {int} Max cyclomatic complexity per function
|
||||
"maxlen" : false, // {int} Max number of characters per line
|
||||
|
||||
// Relaxing
|
||||
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
|
||||
"boss" : true, // true: Tolerate assignments where comparisons would be expected
|
||||
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
|
||||
"eqnull" : false, // true: Tolerate use of `== null`
|
||||
"es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
|
||||
"esnext" : true, // true: Allow ES.next (ES6) syntax (ex: `const`)
|
||||
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
|
||||
// (ex: `for each`, multiple try/catch, function expression…)
|
||||
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
|
||||
"expr" : true, // true: Tolerate `ExpressionStatement` as Programs
|
||||
"funcscope" : false, // true: Tolerate defining variables inside control statements"
|
||||
"globalstrict" : false, // true: Allow global "use strict" (also enables 'strict')
|
||||
"iterator" : false, // true: Tolerate using the `__iterator__` property
|
||||
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
|
||||
"laxbreak" : true, // true: Tolerate possibly unsafe line breakings
|
||||
"laxcomma" : false, // true: Tolerate comma-first style coding
|
||||
"loopfunc" : false, // true: Tolerate functions being defined in loops
|
||||
"multistr" : true, // true: Tolerate multi-line strings
|
||||
"proto" : false, // true: Tolerate using the `__proto__` property
|
||||
"scripturl" : false, // true: Tolerate script-targeted URLs
|
||||
"smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
|
||||
"shadow" : true, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
|
||||
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
|
||||
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
|
||||
"validthis" : true, // true: Tolerate using this in a non-constructor function
|
||||
|
||||
// Environments
|
||||
"browser" : true, // Web Browser (window, document, etc)
|
||||
"couch" : false, // CouchDB
|
||||
"devel" : true, // Development/debugging (alert, confirm, etc)
|
||||
"dojo" : false, // Dojo Toolkit
|
||||
"jquery" : false, // jQuery
|
||||
"mootools" : false, // MooTools
|
||||
"node" : true, // Node.js
|
||||
"nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
|
||||
"prototypejs" : false, // Prototype and Scriptaculous
|
||||
"rhino" : false, // Rhino
|
||||
"worker" : false, // Web Workers
|
||||
"wsh" : false, // Windows Scripting Host
|
||||
"yui" : false, // Yahoo User Interface
|
||||
"noyield" : true, // allow generators without a yield
|
||||
|
||||
// Legacy
|
||||
"nomen" : false, // true: Prohibit dangling `_` in variables
|
||||
"onevar" : false, // true: Allow only one `var` statement per function
|
||||
"passfail" : false, // true: Stop on first error
|
||||
"white" : false, // true: Check against strict whitespace and indentation rules
|
||||
|
||||
// Custom Globals
|
||||
"globals" : { // additional predefined global variables
|
||||
// mocha
|
||||
"describe": true,
|
||||
"it": true,
|
||||
"before": true,
|
||||
"afterEach": true,
|
||||
"beforeEach": true,
|
||||
"after": true
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"notify": false
|
||||
}
|
||||
10
.travis.yml
10
.travis.yml
@@ -1,10 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- '10'
|
||||
- '12'
|
||||
services:
|
||||
- mysql
|
||||
- postgresql
|
||||
script: 'make test-travis-all'
|
||||
after_script:
|
||||
- 'npm i codecov && codecov'
|
||||
21
History.md
21
History.md
@@ -1,24 +1,3 @@
|
||||
3.0.0-rc.44 / 2021-06-11
|
||||
==================
|
||||
|
||||
**features**
|
||||
* [[`a1e8a82`](https://github.com/cnpm/cnpmjs.org/commit/a1e8a8289276275b995d15b3c254fbdbace6dbae)] - feat: impl npm owner hooks (#1645) (killa <<killa123@126.com>>)
|
||||
|
||||
3.0.0-rc.43 / 2021-05-36
|
||||
==================
|
||||
|
||||
**features**
|
||||
* [[`a21aed0`](https://github.com/cnpm/cnpmjs.org/commit/a21aed08c5fe1ea09f4fda157ac3c12bd609781d)] - feat: impl sync to/from backup files (#1612) (killa <<killa123@126.com>>)
|
||||
|
||||
**fixes**
|
||||
* [[`2245dc2`](https://github.com/cnpm/cnpmjs.org/commit/2245dc2967ec070b8bcc618ebfad0cd4cd297fb8)] - feat: impl accelerate request (#1637) (killa <<killa123@126.com>>)
|
||||
|
||||
3.0.0-rc.42 / 2021-04-30
|
||||
==================
|
||||
|
||||
**features**
|
||||
* [[`a21aed0`](https://github.com/cnpm/cnpmjs.org/commit/a21aed08c5fe1ea09f4fda157ac3c12bd609781d)] - feat: impl sync to/from backup files (#1612) (killa <<killa123@126.com>>)
|
||||
|
||||
3.0.0-rc.39 / 2021-01-14
|
||||
==================
|
||||
|
||||
|
||||
6
app/model/README.md
Normal file
6
app/model/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Model
|
||||
|
||||
## Test
|
||||
|
||||
- add `TRUNCATE` script on `test/.setup.js`.
|
||||
- add test case on `test/app/model/*.test.js` for the new model, please follow `test/app/model/user.test.js` example.
|
||||
24
app/model/user.js
Normal file
24
app/model/user.js
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = (app, Model) => {
|
||||
const { STRING, TEXT, BIGINT, BOOLEAN } = Model.DataTypes;
|
||||
|
||||
class User extends Model {}
|
||||
|
||||
User.init({
|
||||
id: { type: BIGINT.UNSIGNED, autoIncrement: true, primaryKey: true },
|
||||
name: { type: STRING(100), allowNull: false },
|
||||
salt: { type: STRING(100), allowNull: false },
|
||||
passwordSha: { type: STRING(100), allowNull: false },
|
||||
ip: { type: STRING(64), allowNull: false },
|
||||
roles: { type: STRING(200), allowNull: false, defaultValue: '[]' },
|
||||
rev: { type: STRING(40), allowNull: false },
|
||||
email: { type: STRING(400), allowNull: false },
|
||||
json: { type: TEXT, allowNull: true },
|
||||
isNpmUser: { type: BOOLEAN, allowNull: false, defaultValue: false, column: 'npm_user' },
|
||||
}, {
|
||||
table: 'user',
|
||||
});
|
||||
|
||||
return User;
|
||||
};
|
||||
@@ -5,8 +5,6 @@ var urllib = require('urllib');
|
||||
var HttpAgent = require('agentkeepalive');
|
||||
var HttpsAgent = require('agentkeepalive').HttpsAgent;
|
||||
var config = require('../config');
|
||||
var url = require('url');
|
||||
var URL = require('url').URL;
|
||||
|
||||
var httpAgent;
|
||||
var httpsAgent;
|
||||
@@ -59,26 +57,5 @@ var client = urllib.create({
|
||||
httpsAgent: httpsAgent
|
||||
});
|
||||
|
||||
var request = urllib.HttpClient.prototype.request;
|
||||
|
||||
function getAccelerateUrl(url) {
|
||||
const urlObj = typeof url === 'string' ? new URL(url) : url;
|
||||
const newHost = config.accelerateHostMap && config.accelerateHostMap[urlObj.host];
|
||||
if (newHost) {
|
||||
urlObj.host = newHost;
|
||||
}
|
||||
return urlObj.toString();
|
||||
}
|
||||
|
||||
client.request = function (requestUrl, options) {
|
||||
const accelerateUrl = getAccelerateUrl(requestUrl);
|
||||
options = Object.assign({}, options, {
|
||||
formatRedirectUrl: function (from, to) {
|
||||
return getAccelerateUrl(url.resolve(from, to));
|
||||
}
|
||||
});
|
||||
return Reflect.apply(request, client, [ accelerateUrl, options ]);
|
||||
};
|
||||
|
||||
module.exports = client;
|
||||
module.exports.USER_AGENT = urllib.USER_AGENT;
|
||||
|
||||
17
config/config.default.js
Normal file
17
config/config.default.js
Normal file
@@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = () => {
|
||||
const { env } = process;
|
||||
|
||||
return {
|
||||
orm: {
|
||||
delegate: 'orm',
|
||||
client: env.CNPMJS_DATABASE_CLIENT || 'mysql',
|
||||
database: env.CNPMJS_DATABASE_NAME || 'cnpmjs_dev',
|
||||
host: env.CNPMJS_DATABASE_HOST || 'localhost',
|
||||
port: env.CNPMJS_DATABASE_PORT || 3306,
|
||||
user: env.CNPMJS_DATABASE_USER || 'root',
|
||||
password: env.CNPMJS_DATABASE_PASSWORD || '',
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -8,7 +8,7 @@ var os = require('os');
|
||||
var utility = require('utility');
|
||||
|
||||
var version = require('../package.json').version;
|
||||
var Nfs = require('fs-cnpm');
|
||||
|
||||
var root = path.dirname(__dirname);
|
||||
var dataDir = path.join(process.env.HOME || root, '.cnpmjs.org');
|
||||
|
||||
@@ -16,11 +16,6 @@ var config = {
|
||||
version: version,
|
||||
dataDir: dataDir,
|
||||
|
||||
// overriding length should alter database table length
|
||||
versionLen: 70, // semver max length
|
||||
nameLen: 214, // name max length
|
||||
tagLen: 70, // tag name max length
|
||||
|
||||
/**
|
||||
* Cluster mode
|
||||
*/
|
||||
@@ -36,9 +31,6 @@ var config = {
|
||||
bindingHost: '127.0.0.1', // only binding on 127.0.0.1 for local access
|
||||
// default is ctx.protocol
|
||||
protocol: '',
|
||||
// When sync package, cnpm not know the access protocol.
|
||||
// So should set manually
|
||||
backupProtocol: 'http',
|
||||
|
||||
// debug mode
|
||||
// if in debug mode, some middleware like limit wont load
|
||||
@@ -125,7 +117,7 @@ var config = {
|
||||
*/
|
||||
|
||||
database: {
|
||||
db: 'cnpmjs',
|
||||
db: 'cnpmjs_test',
|
||||
username: 'root',
|
||||
password: '',
|
||||
|
||||
@@ -167,7 +159,7 @@ var config = {
|
||||
enableNpmAuditsProxy: true,
|
||||
|
||||
// package tarball store in local filesystem by default
|
||||
nfs: new Nfs({
|
||||
nfs: require('fs-cnpm')({
|
||||
dir: path.join(dataDir, 'nfs')
|
||||
}),
|
||||
// if set true, will 302 redirect to `nfs.url(dist.key)`
|
||||
@@ -227,8 +219,6 @@ var config = {
|
||||
// exist: only sync exist modules
|
||||
// all: sync all modules
|
||||
syncModel: 'none', // 'none', 'all', 'exist'
|
||||
// sync package.json/dist-tag.json to sync dir
|
||||
syncBackupFiles: false,
|
||||
|
||||
syncConcurrency: 1,
|
||||
// sync interval, default is 10 minutes
|
||||
@@ -308,37 +298,20 @@ var config = {
|
||||
enable: false,
|
||||
connectOptions: null,
|
||||
},
|
||||
|
||||
// custom format full package list
|
||||
// change `GET /:name` request response body
|
||||
// use on `controllers/registry/list.js`
|
||||
formatCustomFullPackageInfoAndVersions: (ctx, packageInfo) => {
|
||||
return packageInfo;
|
||||
},
|
||||
// custom format one package version
|
||||
// change `GET /:name/:version` request response body
|
||||
// use on `controllers/registry/show.js`
|
||||
formatCustomOnePackageVersion: (ctx, packageVersion) => {
|
||||
return packageVersion;
|
||||
},
|
||||
// registry download accelerate map
|
||||
accelerateHostMap: {},
|
||||
};
|
||||
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
config.enableAbbreviatedMetadata = true;
|
||||
config.customRegistryMiddlewares.push((app) => {
|
||||
config.customRegistryMiddlewares.push(() => {
|
||||
return function* (next) {
|
||||
this.set('x-custom-middleware', 'true');
|
||||
this.set('x-custom-app-models', typeof app.models.query === 'function' ? 'true' : 'false');
|
||||
yield next;
|
||||
};
|
||||
});
|
||||
|
||||
config.customWebMiddlewares.push((app) => {
|
||||
config.customWebMiddlewares.push(() => {
|
||||
return function* (next) {
|
||||
this.set('x-custom-web-middleware', 'true');
|
||||
this.set('x-custom-web-app-models', typeof app.models.query === 'function' ? 'true' : 'false');
|
||||
yield next;
|
||||
};
|
||||
});
|
||||
|
||||
6
config/plugin.js
Normal file
6
config/plugin.js
Normal file
@@ -0,0 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
exports.orm = {
|
||||
enable: true,
|
||||
package: 'egg-orm',
|
||||
};
|
||||
@@ -258,10 +258,6 @@ module.exports = function* list() {
|
||||
info.bugs = pkg.bugs;
|
||||
info.license = pkg.license;
|
||||
|
||||
if (typeof config.formatCustomFullPackageInfoAndVersions === 'function') {
|
||||
info = config.formatCustomFullPackageInfoAndVersions(this, info);
|
||||
}
|
||||
|
||||
debug('show module %s: %s, latest: %s', name, rev, latestMod.version);
|
||||
this.jsonp = info;
|
||||
// use faster etag
|
||||
|
||||
@@ -78,8 +78,8 @@ module.exports = function* save(next) {
|
||||
var versionPackage = pkg.versions[version];
|
||||
var maintainers = versionPackage.maintainers;
|
||||
|
||||
var authorizeType = common.getAuthorizeType(this);
|
||||
if (!maintainers) {
|
||||
var authorizeType = common.getAuthorizeType(this);
|
||||
if (authorizeType === common.AuthorizeType.BEARER) {
|
||||
// With the token mode, pub lib with no maintainers
|
||||
// make the maintainer to be puber
|
||||
@@ -104,19 +104,17 @@ module.exports = function* save(next) {
|
||||
|
||||
// make sure user in auth is in maintainers
|
||||
// should never happened in normal request
|
||||
if (authorizeType !== common.AuthorizeType.BEARER) {
|
||||
var m = maintainers.filter(function (maintainer) {
|
||||
return maintainer.name === username;
|
||||
});
|
||||
if (m.length === 0) {
|
||||
this.status = 403;
|
||||
const error = '[maintainers_error] ' + username + ' does not in maintainer list';
|
||||
this.body = {
|
||||
error,
|
||||
reason: error,
|
||||
};
|
||||
return;
|
||||
}
|
||||
var m = maintainers.filter(function (maintainer) {
|
||||
return maintainer.name === username;
|
||||
});
|
||||
if (m.length === 0) {
|
||||
this.status = 403;
|
||||
const error = '[maintainers_error] ' + username + ' does not in maintainer list';
|
||||
this.body = {
|
||||
error,
|
||||
reason: error,
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: add this info into some table
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
var debug = require('debug')('cnpmjs.org:controllers:registry:package:show');
|
||||
var semver = require('semver');
|
||||
var packageService = require('../../../services/package');
|
||||
var setDownloadURL = require('../../../lib/common').setDownloadURL;
|
||||
var SyncModuleWorker = require('../../sync_module_worker');
|
||||
var config = require('../../../config');
|
||||
|
||||
@@ -16,13 +18,40 @@ var config = require('../../../config');
|
||||
module.exports = function* show() {
|
||||
var name = this.params.name || this.params[0];
|
||||
var tag = this.params.version || this.params[1];
|
||||
var mod = yield packageService.showPackage(name, tag, this);
|
||||
if (tag === '*') {
|
||||
tag = 'latest';
|
||||
}
|
||||
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) {
|
||||
if (typeof config.formatCustomOnePackageVersion === 'function') {
|
||||
mod.package = config.formatCustomOnePackageVersion(this, mod.package);
|
||||
setDownloadURL(mod.package, this);
|
||||
mod.package._cnpm_publish_time = mod.publish_time;
|
||||
mod.package.publish_time = mod.package.publish_time || mod.publish_time;
|
||||
var rs = yield [
|
||||
packageService.listMaintainers(name),
|
||||
packageService.listModuleTags(name),
|
||||
];
|
||||
var maintainers = rs[0];
|
||||
if (maintainers.length > 0) {
|
||||
mod.package.maintainers = maintainers;
|
||||
}
|
||||
|
||||
var tags = rs[1];
|
||||
var distTags = {};
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
var t = tags[i];
|
||||
distTags[t.tag] = t.version;
|
||||
}
|
||||
// show tags for npminstall faster download
|
||||
mod.package['dist-tags'] = distTags;
|
||||
this.jsonp = mod.package;
|
||||
if (config.registryCacheControlHeader) {
|
||||
this.set('cache-control', config.registryCacheControlHeader);
|
||||
@@ -36,7 +65,7 @@ module.exports = function* show() {
|
||||
// if not fond, sync from source registry
|
||||
if (!this.allowSync) {
|
||||
this.status = 404;
|
||||
const error = '[not_exists] version not found: ' + tag;
|
||||
const error = '[not_exists] version not found: ' + version;
|
||||
this.jsonp = {
|
||||
error,
|
||||
reason: error,
|
||||
|
||||
@@ -4,7 +4,6 @@ var debug = require('debug')('cnpmjs.org:controllers:registry:package:update');
|
||||
var packageService = require('../../../services/package');
|
||||
var userService = require('../../../services/user');
|
||||
var config = require('../../../config');
|
||||
var hook = require('../../../services/hook');
|
||||
|
||||
// PUT /:name/-rev/:rev
|
||||
//
|
||||
@@ -159,31 +158,6 @@ function* updateMaintainers() {
|
||||
|
||||
var r = yield packageService.updatePrivateModuleMaintainers(name, usernames);
|
||||
debug('result: %j', r);
|
||||
if (r.add && r.add.length) {
|
||||
const envelope = {
|
||||
event: 'package:owner',
|
||||
name: name,
|
||||
type: 'package',
|
||||
version: null,
|
||||
hookOwner: null,
|
||||
payload: null,
|
||||
change: null,
|
||||
};
|
||||
hook.trigger(envelope);
|
||||
}
|
||||
if (r.remove && r.remove.length) {
|
||||
const envelope = {
|
||||
event: 'package:owner-rm',
|
||||
name: name,
|
||||
type: 'package',
|
||||
version: null,
|
||||
hookOwner: null,
|
||||
payload: null,
|
||||
change: null,
|
||||
};
|
||||
hook.trigger(envelope);
|
||||
}
|
||||
|
||||
|
||||
this.status = 201;
|
||||
this.body = {
|
||||
|
||||
@@ -19,7 +19,6 @@ exports.sync = function* () {
|
||||
var publish = this.query.publish === 'true';
|
||||
var noDep = this.query.nodeps === 'true';
|
||||
var syncUpstreamFirst = this.query.sync_upstream === 'true';
|
||||
var syncFromBackupFile = this.query.sync_from_backup === 'true';
|
||||
if (!config.sourceNpmRegistryIsCNpm) {
|
||||
syncUpstreamFirst = false;
|
||||
}
|
||||
@@ -39,7 +38,6 @@ exports.sync = function* () {
|
||||
publish: publish,
|
||||
noDep: noDep,
|
||||
syncUpstreamFirst: syncUpstreamFirst,
|
||||
syncFromBackupFile: syncFromBackupFile,
|
||||
};
|
||||
|
||||
var logId = yield SyncModuleWorker.sync(name, username, options);
|
||||
|
||||
@@ -8,7 +8,6 @@ var thunkify = require('thunkify-wrap');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var util = require('util');
|
||||
var fs = require('fs');
|
||||
var mzFs = require('mz/fs');
|
||||
var path = require('path');
|
||||
var crypto = require('crypto');
|
||||
var sleep = require('co-sleep');
|
||||
@@ -53,7 +52,6 @@ function SyncModuleWorker(options) {
|
||||
this.concurrency = options.concurrency || 1;
|
||||
this._publish = options.publish === true; // _publish_on_cnpm
|
||||
this.syncUpstreamFirst = options.syncUpstreamFirst;
|
||||
this.syncFromBackupFile = options.syncFromBackupFile;
|
||||
|
||||
this.syncingNames = {};
|
||||
this.nameMap = {};
|
||||
@@ -166,7 +164,6 @@ SyncModuleWorker.prototype.start = function () {
|
||||
}
|
||||
yield arr;
|
||||
that._saveLog();
|
||||
yield that._saveBackupFiles();
|
||||
}).catch(function (err) {
|
||||
logger.error(err);
|
||||
that._saveLog();
|
||||
@@ -325,193 +322,7 @@ SyncModuleWorker.prototype.next = function* (concurrencyId) {
|
||||
yield this.syncByName(concurrencyId, name, registry);
|
||||
};
|
||||
|
||||
// TODO unimplement unpublish
|
||||
SyncModuleWorker.prototype._syncByNameFromBackupFile = function* (concurrencyId, name, retryCount) {
|
||||
const that = this;
|
||||
this.syncingNames[name] = true;
|
||||
|
||||
this.log('----------------- Syncing %s -------------------', name);
|
||||
|
||||
// ignore private scoped package
|
||||
if (common.isPrivateScopedPackage(name)) {
|
||||
this.log('[c#%d] [%s] ignore sync private scoped %j package',
|
||||
concurrencyId, name, config.scopes);
|
||||
yield this._doneOne(concurrencyId, name, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// validate if unpublish
|
||||
const unpublished = yield validateUnpublish(name);
|
||||
if (unpublished) {
|
||||
this.log('[c#%d] [%s] package is unpublished skip sync',
|
||||
concurrencyId, name);
|
||||
yield this._doneOne(concurrencyId, name, true);
|
||||
return;
|
||||
}
|
||||
|
||||
let packageJsons;
|
||||
let tags;
|
||||
try {
|
||||
const packageDir = common.getSyncPackageDir(name);
|
||||
const packageDirFiles = yield nfs.list(packageDir);
|
||||
const packageJsonFileNames = packageDirFiles.filter(fileName => common.isBackupPkgFile(fileName));
|
||||
|
||||
const distTagDir = common.getSyncTagDir(name);
|
||||
const distTagDirFiles = yield nfs.list(distTagDir);
|
||||
const distTagFileNames = distTagDirFiles.filter(fileName => common.isBackupTagFile(fileName));
|
||||
|
||||
const packageJsonRes = yield gather(packageJsonFileNames.map(function* (packageJsonFileName) {
|
||||
const version = common.getVersionFromFileName(packageJsonFileName);
|
||||
return yield readPackage(name, version);
|
||||
}), 5);
|
||||
packageJsons = packageJsonRes.map(({ isError, error, value}) => {
|
||||
if (isError) {
|
||||
error.message = '[sync] read package.json failed: ' + error.message;
|
||||
throw error;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
packageJsons = packageJsons.sort((a, b) => {
|
||||
return a.publish_time - b.publish_time;
|
||||
});
|
||||
|
||||
const tagRes = yield gather(distTagFileNames.map(function* (tagFileName) {
|
||||
const tag = common.getTagNameFromFileName(tagFileName);
|
||||
const version = yield readDistTag(name, tag);
|
||||
return {
|
||||
tag,
|
||||
version,
|
||||
};
|
||||
}));
|
||||
tags = tagRes.map(({ isError, error, value}) => {
|
||||
if (isError) {
|
||||
error.message = '[sync] read dist-tag failed: ' + error.message;
|
||||
throw error;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
} catch (err) {
|
||||
if (retryCount < 3) {
|
||||
this.log('[c#%d] [%s] retry from oss after 3s, err: %s, retryCount: %s',
|
||||
concurrencyId, name, err.stack, retryCount);
|
||||
yield sleep(3000);
|
||||
yield this._syncByNameFromBackupFile(concurrencyId, name, retryCount + 1);
|
||||
return;
|
||||
}
|
||||
this.log('[c#%s] [error] [%s] sync error: %s', concurrencyId, name, err.stack);
|
||||
yield this._doneOne(concurrencyId, name, false);
|
||||
return;
|
||||
}
|
||||
|
||||
const firstPkg = packageJsons[0];
|
||||
const lastPkg = packageJsons[packageJsons.length - 1];
|
||||
|
||||
const times = packageJsons.reduce((times, packageJson) => {
|
||||
times[packageJson.version] = new Date(packageJson.publish_time);
|
||||
return times;
|
||||
}, {
|
||||
modified: new Date(lastPkg.publish_time),
|
||||
created: new Date(firstPkg.publish_time),
|
||||
});
|
||||
const distTags = tags.reduce((distTags, tag) => {
|
||||
distTags[tag.tag] = tag.version;
|
||||
return distTags;
|
||||
}, {});
|
||||
const versions = packageJsons.reduce((versions, packageJson) => {
|
||||
versions[packageJson.version] = packageJson;
|
||||
return versions;
|
||||
}, {});
|
||||
|
||||
const pkg = {
|
||||
name,
|
||||
'dist-tags': distTags,
|
||||
versions: versions,
|
||||
time: times,
|
||||
|
||||
description: lastPkg.description,
|
||||
maintainers: lastPkg.maintainers,
|
||||
author: lastPkg.author,
|
||||
repository: lastPkg.repository,
|
||||
readme: lastPkg.readme,
|
||||
readmeFilename: lastPkg.readmeFilename,
|
||||
homepage: lastPkg.homepage,
|
||||
bugs: lastPkg.bugs,
|
||||
license: lastPkg.license,
|
||||
};
|
||||
|
||||
let syncVersions;
|
||||
try {
|
||||
syncVersions = yield this._sync(name, pkg);
|
||||
} catch (err) {
|
||||
this.log('[c#%s] [error] [%s] sync error: %s', concurrencyId, name, err.stack);
|
||||
yield this._doneOne(concurrencyId, name, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// has new version
|
||||
if (syncVersions.length > 0) {
|
||||
this.updates.push(name);
|
||||
}
|
||||
|
||||
this.log('[c#%d] [%s] synced success, %d versions: %s',
|
||||
concurrencyId, name, syncVersions.length, syncVersions.join(', '));
|
||||
yield this._doneOne(concurrencyId, name, true);
|
||||
|
||||
return syncVersions;
|
||||
|
||||
function* validateUnpublish(name) {
|
||||
const filePath = common.getTarballFilepath(name, '', `unpublish-package.json`);
|
||||
const cdnKey = common.getUnpublishFileKey(name);
|
||||
let unpublishInfo;
|
||||
try {
|
||||
yield nfs.download(cdnKey, filePath);
|
||||
const packageJSONFile = yield mzFs.readFile(filePath, 'utf8');
|
||||
unpublishInfo = JSON.parse(packageJSONFile);
|
||||
} catch (_) {
|
||||
// ...
|
||||
return false;
|
||||
} finally {
|
||||
fs.unlink(filePath, utility.noop);
|
||||
}
|
||||
that.log('[c#%s] get unpublish info', concurrencyId, name);
|
||||
yield that._unpublished(name, unpublishInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
function* readPackage(name, version) {
|
||||
const filePath = common.getTarballFilepath(name, version, `package-${version}.json`);
|
||||
const packageJsonKey = common.getPackageFileCDNKey(name, version);
|
||||
try {
|
||||
yield nfs.download(packageJsonKey, filePath);
|
||||
const packageJSONFile = yield mzFs.readFile(filePath, 'utf8');
|
||||
console.log('file: ', filePath, packageJSONFile);
|
||||
const packageJSON = JSON.parse(packageJSONFile);
|
||||
return packageJSON;
|
||||
} finally {
|
||||
fs.unlink(filePath, utility.noop);
|
||||
}
|
||||
}
|
||||
|
||||
function* readDistTag(name, tag) {
|
||||
const filePath = common.getTarballFilepath(name, '', `tag-${tag}.json`);
|
||||
const packageJsonKey = common.getDistTagCDNKey(name, tag);
|
||||
try {
|
||||
yield nfs.download(packageJsonKey, filePath);
|
||||
const version = yield mzFs.readFile(filePath, 'utf8');
|
||||
return version;
|
||||
} finally {
|
||||
fs.unlink(filePath, utility.noop);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SyncModuleWorker.prototype.syncByName = function* (concurrencyId, name, registry, retryCount) {
|
||||
if (this.syncFromBackupFile) {
|
||||
yield this._syncByNameFromBackupFile(concurrencyId, name, retryCount);
|
||||
return;
|
||||
}
|
||||
|
||||
retryCount = retryCount || 0;
|
||||
var that = this;
|
||||
that.syncingNames[name] = true;
|
||||
@@ -744,39 +555,36 @@ SyncModuleWorker.prototype._unpublished = function* (name, unpublishedInfo) {
|
||||
var r = yield packageService.saveUnpublishedModule(name, unpublishedInfo);
|
||||
this.log(' [%s] save unpublished info: %j to row#%s',
|
||||
name, unpublishedInfo, r.id);
|
||||
if (mods.length) {
|
||||
yield [
|
||||
packageService.removeModulesByName(name),
|
||||
packageService.removeModuleTags(name),
|
||||
];
|
||||
var keys = [];
|
||||
for (var i = 0; i < mods.length; i++) {
|
||||
var row = mods[i];
|
||||
var dist = row.package.dist;
|
||||
var key = dist.key;
|
||||
if (!key) {
|
||||
key = urlparse(dist.tarball).pathname;
|
||||
}
|
||||
key && keys.push(key);
|
||||
if (mods.length === 0) {
|
||||
return;
|
||||
}
|
||||
yield [
|
||||
packageService.removeModulesByName(name),
|
||||
packageService.removeModuleTags(name),
|
||||
];
|
||||
var keys = [];
|
||||
for (var i = 0; i < mods.length; i++) {
|
||||
var row = mods[i];
|
||||
var dist = row.package.dist;
|
||||
var key = dist.key;
|
||||
if (!key) {
|
||||
key = urlparse(dist.tarball).pathname;
|
||||
}
|
||||
|
||||
if (keys.length > 0) {
|
||||
try {
|
||||
yield keys.map(function (key) {
|
||||
return nfs.remove(key);
|
||||
});
|
||||
} catch (err) {
|
||||
// ignore error here
|
||||
this.log(' [%s] delete nfs files: %j error: %s: %s',
|
||||
name, keys, err.name, err.message);
|
||||
}
|
||||
}
|
||||
this.log(' [%s] delete nfs files: %j success', name, keys);
|
||||
key && keys.push(key);
|
||||
}
|
||||
|
||||
if (config.syncBackupFiles) {
|
||||
yield this._saveUnpublishFile(name, unpublishedInfo);
|
||||
if (keys.length > 0) {
|
||||
try {
|
||||
yield keys.map(function (key) {
|
||||
return nfs.remove(key);
|
||||
});
|
||||
} catch (err) {
|
||||
// ignore error here
|
||||
this.log(' [%s] delete nfs files: %j error: %s: %s',
|
||||
name, keys, err.name, err.message);
|
||||
}
|
||||
}
|
||||
this.log(' [%s] delete nfs files: %j success', name, keys);
|
||||
};
|
||||
|
||||
SyncModuleWorker.prototype._sync = function* (name, pkg) {
|
||||
@@ -1715,141 +1523,6 @@ SyncModuleWorker.prototype._syncOneVersion = function *(versionIndex, sourcePack
|
||||
}
|
||||
};
|
||||
|
||||
SyncModuleWorker.prototype._saveBackupFiles = function *() {
|
||||
if (!config.syncBackupFiles) {
|
||||
return;
|
||||
}
|
||||
const pkgNames = Object.keys(this.nameMap);
|
||||
const that = this;
|
||||
yield gather(pkgNames.map(function* (pkgName) {
|
||||
yield that._saveBackupFile(pkgName);
|
||||
}), 5);
|
||||
};
|
||||
|
||||
SyncModuleWorker.prototype._saveBackupFile = function *(pkgName) {
|
||||
const [ mods, tags ] = yield [
|
||||
packageService.listModulesByName(pkgName, [ 'version' ]),
|
||||
packageService.listModuleTags(pkgName),
|
||||
];
|
||||
const that = this;
|
||||
yield gather(mods.map(function* (mod) {
|
||||
yield that._savePackageJsonBackup(pkgName, mod.version);
|
||||
}), 5);
|
||||
yield gather(tags.map(function* (tag) {
|
||||
yield that._saveDistTagBackup(pkgName, tag.tag, tag.version);
|
||||
}), 5);
|
||||
yield this._clearDeletedDistTags(pkgName, tags.map(t => t.tag));
|
||||
};
|
||||
|
||||
SyncModuleWorker.prototype._saveUnpublishFile = function* (pkgName, pkg) {
|
||||
const cdnKey = common.getUnpublishFileKey(pkgName);
|
||||
const filePath = common.getTarballFilepath(pkgName, '', 'unpublish-package.json');
|
||||
this.log('[%s] start save unpublish-package.json', pkgName);
|
||||
const file = JSON.stringify(pkg);
|
||||
yield mzFs.writeFile(filePath, file);
|
||||
|
||||
let shasum = crypto.createHash('sha1');
|
||||
shasum.update(file);
|
||||
shasum = shasum.digest('hex');
|
||||
|
||||
yield nfs.upload(filePath, {
|
||||
key: cdnKey,
|
||||
size: file.length,
|
||||
shasum: shasum,
|
||||
});
|
||||
this.log('[%s:%s] save unpublish package.json backup success', pkgName);
|
||||
};
|
||||
|
||||
SyncModuleWorker.prototype._savePackageJsonBackup = function *(pkgName, version) {
|
||||
const cdnKey = common.getPackageFileCDNKey(pkgName, version);
|
||||
const filePath = common.getTarballFilepath(pkgName, version, `package-${version}.json`);
|
||||
this.log('[%s:%s] start backup package.json', pkgName, version);
|
||||
// If package.json exists no need to sync
|
||||
try {
|
||||
yield nfs.download(cdnKey, filePath);
|
||||
fs.unlink(filePath, utility.noop);
|
||||
this.log('[%s:%s] package.json exits skip backup', pkgName, version);
|
||||
// Download success, no need to sync
|
||||
return;
|
||||
} catch (_) {
|
||||
// ...
|
||||
}
|
||||
// Version is from db, so mod can not be null
|
||||
const mod = yield packageService.showPackage(pkgName, version, {
|
||||
protocol: config.backupProtocol,
|
||||
});
|
||||
|
||||
const file = JSON.stringify(mod.package);
|
||||
yield mzFs.writeFile(filePath, file);
|
||||
|
||||
let shasum = crypto.createHash('sha1');
|
||||
shasum.update(file);
|
||||
shasum = shasum.digest('hex');
|
||||
|
||||
yield nfs.upload(filePath, {
|
||||
key: cdnKey,
|
||||
size: file.length,
|
||||
shasum: shasum,
|
||||
});
|
||||
this.log('[%s:%s] package.json backup success', pkgName, version);
|
||||
};
|
||||
|
||||
SyncModuleWorker.prototype._saveDistTagBackup = function *(pkgName, tag, version) {
|
||||
const cdnKey = common.getDistTagCDNKey(pkgName, tag);
|
||||
const filePath = common.getTarballFilepath(pkgName, '', `tag-${tag}.json`);
|
||||
this.log('[%s:%s] start backup dist-tag.json', pkgName, tag);
|
||||
let oldVersion;
|
||||
try {
|
||||
yield nfs.download(cdnKey, filePath);
|
||||
oldVersion = yield mzFs.readFile(filePath, 'utf8');
|
||||
fs.unlink(filePath, utility.noop);
|
||||
} catch (_) {
|
||||
// ...
|
||||
}
|
||||
this.log('[%s:%s] backup dist tag is %j current dist tag is %j', pkgName, tag, oldVersion, version);
|
||||
if (oldVersion === version) {
|
||||
this.log('[%s:%s] tag equal skip sync', pkgName, tag);
|
||||
return;
|
||||
}
|
||||
this.log('[%s:%s] tag not equal start sync', pkgName, tag);
|
||||
const file = version;
|
||||
yield mzFs.writeFile(filePath, file);
|
||||
|
||||
let shasum = crypto.createHash('sha1');
|
||||
shasum.update(file);
|
||||
shasum = shasum.digest('hex');
|
||||
|
||||
yield nfs.upload(filePath, {
|
||||
key: cdnKey,
|
||||
size: file.length,
|
||||
shasum: shasum,
|
||||
});
|
||||
this.log('[%s:%s] backup dist tag success', pkgName, tag);
|
||||
};
|
||||
|
||||
SyncModuleWorker.prototype._clearDeletedDistTags = function *(pkgName, tagNames) {
|
||||
const syncDir = common.getSyncTagDir(pkgName);
|
||||
const backupDistTagFiless = yield nfs.list(syncDir);
|
||||
const currentTagNames = new Set(tagNames);
|
||||
const shouldDelTags = backupDistTagFiless.filter(tagFileName => {
|
||||
const tagName = common.getTagNameFromFileName(tagFileName);
|
||||
return (
|
||||
// File is an dist-tag file
|
||||
tagName
|
||||
// tag is deleted
|
||||
&& !currentTagNames.has(tagName)
|
||||
);
|
||||
});
|
||||
this.log('[%s] current tags %j backup tags %j should delete tags %j', pkgName, tagNames, backupDistTagFiless, shouldDelTags);
|
||||
const that = this;
|
||||
yield shouldDelTags.map(function* (tagFileName) {
|
||||
const filePath = path.join(syncDir, tagFileName);
|
||||
that.log('[%s] delete tags %s', pkgName, filePath);
|
||||
yield nfs.remove(filePath);
|
||||
});
|
||||
this.log('[%s] delete tags success', pkgName);
|
||||
};
|
||||
|
||||
SyncModuleWorker.sync = function* (name, username, options) {
|
||||
options = options || {};
|
||||
var result = yield logService.create({name: name, username: username});
|
||||
@@ -1861,7 +1534,6 @@ SyncModuleWorker.sync = function* (name, username, options) {
|
||||
noDep: options.noDep,
|
||||
publish: options.publish,
|
||||
syncUpstreamFirst: options.syncUpstreamFirst,
|
||||
syncFromBackupFile: options.syncFromBackupFile,
|
||||
});
|
||||
worker.start();
|
||||
return result.id;
|
||||
|
||||
12
docs/db.sql
12
docs/db.sql
@@ -81,7 +81,7 @@ CREATE TABLE IF NOT EXISTS `module` (
|
||||
`gmt_modified` datetime NOT NULL COMMENT 'modified time',
|
||||
`author` varchar(100) NOT NULL COMMENT 'module author',
|
||||
`name` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
|
||||
`version` varchar(70) NOT NULL COMMENT 'module version',
|
||||
`version` varchar(30) NOT NULL COMMENT 'module version',
|
||||
`description` longtext COMMENT 'module description',
|
||||
`package` longtext CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT 'package.json',
|
||||
`dist_shasum` varchar(100) DEFAULT NULL COMMENT 'module dist SHASUM',
|
||||
@@ -104,7 +104,7 @@ CREATE TABLE IF NOT EXISTS `module` (
|
||||
-- ALTER TABLE `module`
|
||||
-- CHANGE `author` `author` varchar(100) NOT NULL COMMENT 'module author',
|
||||
-- CHANGE `name` `name` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
|
||||
-- CHANGE `version` `version` varchar(70) NOT NULL COMMENT 'module version',
|
||||
-- CHANGE `version` `version` varchar(30) NOT NULL COMMENT 'module version',
|
||||
-- CHANGE `description` `description` longtext COMMENT 'module description',
|
||||
-- CHANGE `package` `package` longtext CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT 'package.json',
|
||||
-- CHANGE `dist_shasum` `dist_shasum` varchar(100) DEFAULT NULL COMMENT 'module dist SHASUM',
|
||||
@@ -117,7 +117,7 @@ CREATE TABLE IF NOT EXISTS `module_abbreviated` (
|
||||
`gmt_create` datetime NOT NULL COMMENT 'create time',
|
||||
`gmt_modified` datetime NOT NULL COMMENT 'modified time',
|
||||
`name` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
|
||||
`version` varchar(70) NOT NULL COMMENT 'module version',
|
||||
`version` varchar(30) NOT NULL COMMENT 'module version',
|
||||
`package` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT 'the abbreviated metadata',
|
||||
`publish_time` bigint(20) unsigned COMMENT 'the publish time',
|
||||
PRIMARY KEY (`id`),
|
||||
@@ -135,7 +135,7 @@ CREATE TABLE IF NOT EXISTS `package_readme` (
|
||||
`gmt_modified` datetime NOT NULL COMMENT 'modified time',
|
||||
`name` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
|
||||
`readme` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT 'the latest version readme',
|
||||
`version` varchar(70) NOT NULL COMMENT 'module version',
|
||||
`version` varchar(30) NOT NULL COMMENT 'module version',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_name` (`name`),
|
||||
KEY `idx_gmt_modified` (`gmt_modified`)
|
||||
@@ -164,8 +164,8 @@ CREATE TABLE IF NOT EXISTS `tag` (
|
||||
`gmt_create` datetime NOT NULL COMMENT 'create time',
|
||||
`gmt_modified` datetime NOT NULL COMMENT 'modified time',
|
||||
`name` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
|
||||
`tag` varchar(70) NOT NULL COMMENT 'tag name',
|
||||
`version` varchar(70) NOT NULL COMMENT 'module version',
|
||||
`tag` varchar(30) NOT NULL COMMENT 'tag name',
|
||||
`version` varchar(30) NOT NULL COMMENT 'module version',
|
||||
`module_id` bigint(20) unsigned NOT NULL COMMENT 'module id',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_name` (`name`, `tag`),
|
||||
|
||||
@@ -229,7 +229,6 @@ var config = {
|
||||
// global hook function: function* (envelope) {}
|
||||
// envelope format please see https://github.com/npm/registry/blob/master/docs/hooks/hooks-payload.md#payload
|
||||
globalHook: null,
|
||||
accelerateHostMap: {},
|
||||
};
|
||||
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
|
||||
12
index.js
12
index.js
@@ -1,5 +1,17 @@
|
||||
/**!
|
||||
* Copyright(c) cnpmjs.org and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
* Authors:
|
||||
* dead_horse <dead_horse@qq.com> (http://deadhorse.me)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var config = require('./config');
|
||||
|
||||
exports.loadConfig = config.loadConfig;
|
||||
|
||||
@@ -26,46 +26,6 @@ exports.getCDNKey = function (name, filename) {
|
||||
return '/' + name + '/-/' + filename;
|
||||
};
|
||||
|
||||
exports.getUnpublishFileKey = function (name) {
|
||||
return `/${name}/sync/unpublish/unpublish-package.json`;
|
||||
};
|
||||
|
||||
exports.getPackageFileCDNKey = function (name, version) {
|
||||
return `/${name}/sync/packages/package-${version}.json`;
|
||||
};
|
||||
|
||||
exports.getDistTagCDNKey = function (name, tag) {
|
||||
return `/${name}/sync/tags/tag-${tag}.json`;
|
||||
};
|
||||
|
||||
exports.getSyncTagDir = function (name) {
|
||||
return `${name}/sync/tags/`;
|
||||
};
|
||||
|
||||
exports.getSyncPackageDir = function (name) {
|
||||
return `${name}/sync/packages/`;
|
||||
};
|
||||
|
||||
const TAG_NAME_REG = /^tag-(.+)\.json$/;
|
||||
exports.getTagNameFromFileName = function (fileName) {
|
||||
const res = fileName.match(TAG_NAME_REG);
|
||||
return res && res[1];
|
||||
};
|
||||
|
||||
exports.isBackupTagFile = function (fileName) {
|
||||
return TAG_NAME_REG.test(fileName);
|
||||
};
|
||||
|
||||
const PACKAGE_NAME_REG = /^package-(.+)\.json$/;
|
||||
exports.getVersionFromFileName = function (fileName) {
|
||||
const res = fileName.match(PACKAGE_NAME_REG);
|
||||
return res && res[1];
|
||||
};
|
||||
|
||||
exports.isBackupPkgFile = function (fileName) {
|
||||
return PACKAGE_NAME_REG.test(fileName);
|
||||
};
|
||||
|
||||
exports.setDownloadURL = function (pkg, ctx, host) {
|
||||
if (pkg.dist) {
|
||||
host = host || config.registryHost || ctx.host;
|
||||
|
||||
@@ -56,12 +56,10 @@
|
||||
// KEY `idx_date` (`date`)
|
||||
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module download total info';
|
||||
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('DownloadTotal', {
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name',
|
||||
},
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
/**!
|
||||
* cnpmjs.org - models/module.js
|
||||
*
|
||||
* Copyright(c) fengmk2 and other contributors.
|
||||
* MIT Licensed
|
||||
*
|
||||
* Authors:
|
||||
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
/*
|
||||
CREATE TABLE IF NOT EXISTS `module` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',
|
||||
@@ -7,7 +21,7 @@ CREATE TABLE IF NOT EXISTS `module` (
|
||||
`gmt_modified` datetime NOT NULL COMMENT 'modified time',
|
||||
`author` varchar(100) NOT NULL COMMENT 'module author',
|
||||
`name` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
|
||||
`version` varchar(70) NOT NULL COMMENT 'module version',
|
||||
`version` varchar(30) NOT NULL COMMENT 'module version',
|
||||
`description` longtext COMMENT 'module description',
|
||||
`package` longtext CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT 'package.json',
|
||||
`dist_shasum` varchar(100) DEFAULT NULL COMMENT 'module dist SHASUM',
|
||||
@@ -21,7 +35,6 @@ CREATE TABLE IF NOT EXISTS `module` (
|
||||
KEY `idx_author` (`author`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module info';
|
||||
*/
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('Module', {
|
||||
@@ -31,12 +44,12 @@ module.exports = function (sequelize, DataTypes) {
|
||||
comment: 'first maintainer name'
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name'
|
||||
},
|
||||
version: {
|
||||
type: DataTypes.STRING(config.versionLen),
|
||||
type: DataTypes.STRING(30),
|
||||
allowNull: false,
|
||||
comment: 'module version'
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ CREATE TABLE IF NOT EXISTS `module_abbreviated` (
|
||||
`gmt_create` datetime NOT NULL COMMENT 'create time',
|
||||
`gmt_modified` datetime NOT NULL COMMENT 'modified time',
|
||||
`name` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
|
||||
`version` varchar(70) NOT NULL COMMENT 'module version',
|
||||
`version` varchar(30) NOT NULL COMMENT 'module version',
|
||||
`package` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT 'the abbreviated metadata',
|
||||
`publish_time` bigint(20) unsigned COMMENT 'the publish time',
|
||||
PRIMARY KEY (`id`),
|
||||
@@ -16,17 +16,15 @@ CREATE TABLE IF NOT EXISTS `module_abbreviated` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module abbreviated info';
|
||||
*/
|
||||
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('ModuleAbbreviated', {
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name'
|
||||
},
|
||||
version: {
|
||||
type: DataTypes.STRING(config.versionLen),
|
||||
type: DataTypes.STRING(30),
|
||||
allowNull: false,
|
||||
comment: 'module version'
|
||||
},
|
||||
|
||||
@@ -19,18 +19,17 @@ CREATE TABLE IF NOT EXISTS `module_deps` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',
|
||||
`gmt_create` datetime NOT NULL COMMENT 'create time',
|
||||
`name` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
|
||||
`deps` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'which module depend on this module',
|
||||
`deps` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'which module depend on this module',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_name_deps` (`name`,`deps`),
|
||||
KEY `idx_name` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module deps';
|
||||
*/
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('ModuleDependency', {
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name',
|
||||
},
|
||||
|
||||
@@ -26,7 +26,6 @@ CREATE TABLE IF NOT EXISTS `module_keyword` (
|
||||
KEY `idx_name` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module keyword';
|
||||
*/
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('ModuleKeyword', {
|
||||
@@ -36,7 +35,7 @@ module.exports = function (sequelize, DataTypes) {
|
||||
comment: 'keyword',
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name',
|
||||
},
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
KEY `idx_name` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module sync log';
|
||||
*/
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('ModuleLog', {
|
||||
@@ -36,7 +35,7 @@ module.exports = function (sequelize, DataTypes) {
|
||||
comment: 'user name'
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name',
|
||||
},
|
||||
|
||||
@@ -25,7 +25,6 @@ CREATE TABLE IF NOT EXISTS `module_maintainer` (
|
||||
KEY `idx_name` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='private module maintainers';
|
||||
*/
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('ModuleMaintainer', {
|
||||
@@ -35,7 +34,7 @@ module.exports = function (sequelize, DataTypes) {
|
||||
comment: 'user name'
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name',
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ CREATE TABLE IF NOT EXISTS `module_star` (
|
||||
KEY `idx_name` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module star';
|
||||
*/
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('ModuleStar', {
|
||||
@@ -35,7 +34,7 @@ module.exports = function (sequelize, DataTypes) {
|
||||
comment: 'user name'
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name',
|
||||
}
|
||||
|
||||
@@ -28,12 +28,11 @@ CREATE TABLE IF NOT EXISTS `module_unpublished` (
|
||||
KEY `idx_gmt_modified` (`gmt_modified`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module unpublished info';
|
||||
*/
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('ModuleUnpublished', {
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name',
|
||||
},
|
||||
|
||||
@@ -25,7 +25,6 @@ CREATE TABLE IF NOT EXISTS `npm_module_maintainer` (
|
||||
KEY `idx_name` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='npm original module maintainers';
|
||||
*/
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('NpmModuleMaintainer', {
|
||||
@@ -35,7 +34,7 @@ module.exports = function (sequelize, DataTypes) {
|
||||
comment: 'user name'
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name',
|
||||
}
|
||||
|
||||
@@ -7,23 +7,22 @@ CREATE TABLE IF NOT EXISTS `package_readme` (
|
||||
`gmt_modified` datetime NOT NULL COMMENT 'modified time',
|
||||
`name` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
|
||||
`readme` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT 'the latest version readme',
|
||||
`version` varchar(70) NOT NULL COMMENT 'module version',
|
||||
`version` varchar(30) NOT NULL COMMENT 'module version',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_name` (`name`),
|
||||
KEY `idx_gmt_modified` (`gmt_modified`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='package latest readme';
|
||||
*/
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('PackageReadme', {
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name'
|
||||
},
|
||||
version: {
|
||||
type: DataTypes.STRING(config.versionLen),
|
||||
type: DataTypes.STRING(30),
|
||||
allowNull: false,
|
||||
comment: 'module latest version'
|
||||
},
|
||||
|
||||
@@ -20,30 +20,29 @@ CREATE TABLE IF NOT EXISTS `tag` (
|
||||
`gmt_create` datetime NOT NULL COMMENT 'create time',
|
||||
`gmt_modified` datetime NOT NULL COMMENT 'modified time',
|
||||
`name` varchar(214) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
|
||||
`tag` varchar(70) NOT NULL COMMENT 'tag name',
|
||||
`version` varchar(70) NOT NULL COMMENT 'module version',
|
||||
`tag` varchar(30) NOT NULL COMMENT 'tag name',
|
||||
`version` varchar(30) NOT NULL COMMENT 'module version',
|
||||
`module_id` bigint(20) unsigned NOT NULL COMMENT 'module id',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_name` (`name`, `tag`),
|
||||
KEY `idx_gmt_modified` (`gmt_modified`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module tag';
|
||||
*/
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('Tag', {
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
allowNull: false,
|
||||
comment: 'module name',
|
||||
},
|
||||
tag: {
|
||||
type: DataTypes.STRING(config.tagLen),
|
||||
type: DataTypes.STRING(30),
|
||||
allowNull: false,
|
||||
comment: 'tag name',
|
||||
},
|
||||
version: {
|
||||
type: DataTypes.STRING(config.versionLen),
|
||||
type: DataTypes.STRING(30),
|
||||
allowNull: false,
|
||||
comment: 'module version',
|
||||
},
|
||||
|
||||
@@ -31,12 +31,11 @@
|
||||
// -- init `total` count
|
||||
// INSERT INTO total(name, gmt_modified) VALUES('total', now())
|
||||
// ON DUPLICATE KEY UPDATE gmt_modified=now();
|
||||
const config = require('../config');
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('Total', {
|
||||
name: {
|
||||
type: DataTypes.STRING(config.nameLen),
|
||||
type: DataTypes.STRING(214),
|
||||
primaryKey: true,
|
||||
comment: 'total name'
|
||||
},
|
||||
|
||||
39
package.json
39
package.json
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "cnpmjs.org",
|
||||
"version": "3.0.0-rc.44",
|
||||
"version": "4.0.0",
|
||||
"description": "Private npm registry and web for Enterprise, base on MySQL and Simple Store Service",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "DEBUG=cnpm* node dispatch.js",
|
||||
"test": "make jshint && make test",
|
||||
"test-local": "make test",
|
||||
"lint": "eslint app config test/app/",
|
||||
"dev": "egg-bin dev",
|
||||
"test": "TESTS=test/app/**/*/user.test.js egg-bin test",
|
||||
"test-model": "TESTS=test/app/model/**/user.test.js egg-bin test",
|
||||
"start": "./bin/nodejsctl start && cp History.md docs/web/history.md",
|
||||
"status": "./bin/nodejsctl status",
|
||||
"stop": "./bin/nodejsctl stop"
|
||||
@@ -15,7 +16,6 @@
|
||||
"cnpmjs.org": "bin/cli.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"agentkeepalive": "^4.0.0",
|
||||
"await-event": "^2.1.0",
|
||||
"bytes": "^2.5.0",
|
||||
"cfork": "^1.6.1",
|
||||
@@ -27,8 +27,10 @@
|
||||
"commander": "^2.11.0",
|
||||
"copy-to": "^2.0.1",
|
||||
"debug": "^3.0.0",
|
||||
"egg": "^2.29.3",
|
||||
"egg-orm": "^1.1.1",
|
||||
"error-formater": "^1.0.3",
|
||||
"fs-cnpm": "^2.1.0",
|
||||
"fs-cnpm": "^1.2.0",
|
||||
"giturl": "^1.0.0",
|
||||
"graceful": "^1.0.1",
|
||||
"gravatar": "^1.6.0",
|
||||
@@ -76,32 +78,21 @@
|
||||
"autod": "*",
|
||||
"chunkstream": "*",
|
||||
"contributors": "*",
|
||||
"intelli-espower-loader": "^1.0.1",
|
||||
"istanbul": "*",
|
||||
"jshint": "*",
|
||||
"mm": "*",
|
||||
"mocha": "3",
|
||||
"node-dev": "*",
|
||||
"pedding": "*",
|
||||
"pg": "5",
|
||||
"pg-hstore": "2",
|
||||
"power-assert": "^1.4.2",
|
||||
"should": "8",
|
||||
"sqlite3": "*",
|
||||
"supertest": "2",
|
||||
"thunk-mocha": "1"
|
||||
"egg-bin": "^4.15.0",
|
||||
"egg-mock": "^4.0.1",
|
||||
"eslint": "^7.21.0",
|
||||
"eslint-config-egg": "^9.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/cnpm/cnpmjs.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/cnpm/cnpmjs.org.git",
|
||||
"web": "https://github.com/cnpm/cnpmjs.org"
|
||||
"url": "git://github.com/cnpm/cnpmjs.org.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/cnpm/cnpmjs.org/issues"
|
||||
},
|
||||
"publishConfig": {
|
||||
"tag": "latest-3"
|
||||
"tag": "latest-4"
|
||||
},
|
||||
"keywords": [
|
||||
"cnpmjs.org",
|
||||
@@ -113,7 +104,7 @@
|
||||
"engines": {
|
||||
"node": ">= 8.0.0"
|
||||
},
|
||||
"author": [
|
||||
"authors": [
|
||||
"fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)",
|
||||
"dead_horse <dead_horse@qq.com> (http://deadhorse.me)"
|
||||
],
|
||||
|
||||
@@ -16,7 +16,6 @@ var block = require('../middleware/block');
|
||||
var auth = require('../middleware/auth');
|
||||
var staticCache = require('../middleware/static');
|
||||
var notFound = require('../middleware/registry_not_found');
|
||||
var models = require('../models');
|
||||
var cors = require('kcors');
|
||||
var proxyToNpm = require('../middleware/proxy_to_npm');
|
||||
var maxrequests = require('koa-maxrequests');
|
||||
@@ -53,7 +52,6 @@ app.use(notFound);
|
||||
app.use(conditional());
|
||||
app.use(etag());
|
||||
|
||||
app.models = models;
|
||||
for (const middleware of config.customRegistryMiddlewares) {
|
||||
app.use(middleware(app));
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ var auth = require('../middleware/auth');
|
||||
var proxyToNpm = require('../middleware/proxy_to_npm');
|
||||
var routes = require('../routes/web');
|
||||
var config = require('../config');
|
||||
var models = require('../models');
|
||||
var jsonp = require('koa-safe-jsonp');
|
||||
var path = require('path');
|
||||
var http = require('http');
|
||||
@@ -43,8 +42,6 @@ if (config.pagemock) {
|
||||
}));
|
||||
}
|
||||
|
||||
// add app.models, let middleware can access models ref
|
||||
app.models = models;
|
||||
for (const mw of config.customWebMiddlewares) {
|
||||
app.use(mw(app));
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var os = require('os');
|
||||
var semver = require('semver');
|
||||
var models = require('../models');
|
||||
var common = require('./common');
|
||||
var libCommon = require('../lib/common');
|
||||
var config = require('../config');
|
||||
var Tag = models.Tag;
|
||||
var User = models.User;
|
||||
@@ -543,23 +541,6 @@ exports.removeModulesByNameAndVersions = function* (name, versions) {
|
||||
// tags
|
||||
|
||||
exports.addModuleTag = function* (name, tag, version) {
|
||||
if (name.length > config.nameLen
|
||||
|| tag.length > config.tagLen
|
||||
|| version.length > config.versionLen) {
|
||||
let errorMsg = 'addModuleTag Error:';
|
||||
if (name.length > config.nameLen) {
|
||||
errorMsg = `${errorMsg} length of name(${name}) > ${config.nameLen}${os.EOL}`;
|
||||
}
|
||||
if (tag.length > config.tagLen) {
|
||||
errorMsg = `${errorMsg} length of tag(${tag}) > ${config.tagLen}${os.EOL}`;
|
||||
}
|
||||
if (version.length > config.versionLen) {
|
||||
errorMsg = `${errorMsg} length of version(${version}) > ${config.versionLen}${os.EOL}`;
|
||||
}
|
||||
console.info('errorMsg: ', errorMsg);
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
|
||||
var mod = yield exports.getModule(name, version);
|
||||
if (!mod) {
|
||||
return null;
|
||||
@@ -884,45 +865,3 @@ exports.saveUnpublishedModule = function* (name, pkg) {
|
||||
exports.getUnpublishedModule = function* (name) {
|
||||
return yield ModuleUnpublished.findByName(name);
|
||||
};
|
||||
|
||||
exports.showPackage = function* (name, tag, ctx) {
|
||||
if (tag === '*') {
|
||||
tag = 'latest';
|
||||
}
|
||||
if (tag === '*') {
|
||||
tag = 'latest';
|
||||
}
|
||||
var version = semver.valid(tag);
|
||||
var range = semver.validRange(tag);
|
||||
var mod;
|
||||
if (version) {
|
||||
mod = yield exports.getModule(name, version);
|
||||
} else if (range) {
|
||||
mod = yield exports.getModuleByRange(name, range);
|
||||
} else {
|
||||
mod = yield exports.getModuleByTag(name, tag);
|
||||
}
|
||||
|
||||
if (mod) {
|
||||
libCommon.setDownloadURL(mod.package, ctx || {});
|
||||
mod.package._cnpm_publish_time = mod.publish_time;
|
||||
mod.package.publish_time = mod.package.publish_time || mod.publish_time;
|
||||
var rs = yield [
|
||||
exports.listMaintainers(name),
|
||||
exports.listModuleTags(name),
|
||||
];
|
||||
var maintainers = rs[0];
|
||||
if (maintainers.length > 0) {
|
||||
mod.package.maintainers = maintainers;
|
||||
}
|
||||
var tags = rs[1];
|
||||
var distTags = {};
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
var t = tags[i];
|
||||
distTags[t.tag] = t.version;
|
||||
}
|
||||
// show tags for npminstall faster download
|
||||
mod.package['dist-tags'] = distTags;
|
||||
return mod;
|
||||
}
|
||||
};
|
||||
|
||||
11
test/.setup.js
Normal file
11
test/.setup.js
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const { app } = require('egg-mock/bootstrap');
|
||||
|
||||
before(async () => {
|
||||
await app.orm.sync();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await app.orm.User.driver.query('TRUNCATE user');
|
||||
});
|
||||
33
test/app/model/user.test.js
Normal file
33
test/app/model/user.test.js
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const { app, assert } = require('egg-mock/bootstrap');
|
||||
|
||||
describe('test/app/model/user.test.js', () => {
|
||||
describe('ctx.orm.User, app.orm.User', () => {
|
||||
it('should work', async () => {
|
||||
const ctx = app.mockContext();
|
||||
assert(ctx.orm.User);
|
||||
assert(app.orm.User);
|
||||
const user = await ctx.orm.User.create({
|
||||
name: 'fengmk2',
|
||||
salt: 'salt',
|
||||
passwordSha: 'password_sha',
|
||||
ip: 'ip',
|
||||
rev: 'rev',
|
||||
email: 'fengmk2@gmail.com',
|
||||
json: '{}',
|
||||
npmUser: '0',
|
||||
});
|
||||
assert(user.id === 1);
|
||||
assert(user.isNpmUser === false);
|
||||
await user.save();
|
||||
assert(user.id);
|
||||
const notExistsUser = await ctx.orm.User.findOne({ name: 'not-exists' });
|
||||
assert(!notExistsUser);
|
||||
const existsUser = await ctx.orm.User.findOne({ name: 'fengmk2' });
|
||||
assert(existsUser.id === user.id);
|
||||
assert(existsUser.name === user.name);
|
||||
assert(existsUser.isNpmUser === false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,40 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const mm = require('mm');
|
||||
const urllib = require('../../common/urllib');
|
||||
const config = require('../../config');
|
||||
|
||||
describe('test/common/urllib.test.js', () => {
|
||||
describe('accelerate request', () => {
|
||||
beforeEach(() => {
|
||||
mm(config, 'accelerateHostMap', {
|
||||
'www.alipay.com': 'www.antgroup.com',
|
||||
'www.google.com': 'www.google.com'
|
||||
});
|
||||
});
|
||||
|
||||
describe('direct', () => {
|
||||
it('should work', function* () {
|
||||
const res = yield urllib.request('https://www.alipay.com', {
|
||||
followRedirect: true,
|
||||
});
|
||||
assert.deepStrictEqual(res.res.requestUrls, [
|
||||
'https://www.antgroup.com/',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('redirect', () => {
|
||||
it('should work', function* () {
|
||||
const res = yield urllib.request('https://google.com', {
|
||||
followRedirect: true,
|
||||
});
|
||||
assert.deepStrictEqual(res.res.requestUrls, [
|
||||
'https://google.com/',
|
||||
'https://www.google.com/',
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -96,20 +96,6 @@ describe('test/controllers/registry/package/dist_tag.test.js', function () {
|
||||
.expect(400, done);
|
||||
});
|
||||
|
||||
it.only('should 400 when set a version of 70+ length', function (done) {
|
||||
const tag = Buffer.alloc(71, 'a').toString();
|
||||
request(app)
|
||||
.put(`/-/package/@cnpmtest/dist_tag_test_module_set/dist-tags/${tag}`)
|
||||
.set('authorization', utils.otherUserAuth)
|
||||
.set('content-type', 'application/json')
|
||||
.send(JSON.stringify(`1.0.1`))
|
||||
.expect({
|
||||
error: '[version_error] @cnpmtest/dist_tag_test_module_set@1.0.1 not exists',
|
||||
reason: '[version_error] @cnpmtest/dist_tag_test_module_set@1.0.1 not exists',
|
||||
})
|
||||
.expect(400, done);
|
||||
});
|
||||
|
||||
it('should 201 set exists tag', function (done) {
|
||||
request(app)
|
||||
.put('/-/package/@cnpmtest/dist_tag_test_module_set/dist-tags/exists')
|
||||
|
||||
@@ -49,7 +49,6 @@ describe('test/controllers/registry/package/list.test.js', () => {
|
||||
var data = res.body;
|
||||
data.name.should.equal('@cnpmtest/testmodule-list-1');
|
||||
assert(res.headers['x-custom-middleware'] === 'true');
|
||||
assert(res.headers['x-custom-app-models'] === 'true');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -230,29 +229,6 @@ describe('test/controllers/registry/package/list.test.js', () => {
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('should config.formatCustomFullPackageInfoAndVersions work', async () => {
|
||||
mm(config, 'formatCustomFullPackageInfoAndVersions', (ctx, info) => {
|
||||
console.log('%s %s, query: %j', ctx.method, ctx.url, ctx.query);
|
||||
info.description = '';
|
||||
info.readme = '';
|
||||
for (const version in info.versions) {
|
||||
const item = info.versions[version];
|
||||
item.description = '';
|
||||
item.readme = '';
|
||||
}
|
||||
return info;
|
||||
});
|
||||
const res = await request(app)
|
||||
.get('/@cnpmtest/testmodule-list-1?a=123123');
|
||||
assert(res.status === 200);
|
||||
assert(res.body.description === '');
|
||||
assert(res.body.readme === '');
|
||||
const firstVersion = Object.keys(res.body.versions)[0];
|
||||
assert(firstVersion);
|
||||
assert(res.body.versions[firstVersion].description === '');
|
||||
assert(res.body.versions[firstVersion].readme === '');
|
||||
});
|
||||
|
||||
describe.skip('unpublished', () => {
|
||||
before(done => {
|
||||
mm(config, 'syncModel', 'all');
|
||||
|
||||
@@ -46,14 +46,14 @@ describe('test/controllers/registry/package/list_by_user.test.js', function () {
|
||||
map['@cnpmtest/list_by_user_module1'].should.be.an.Object();
|
||||
map['@cnpmtest/list_by_user_module1'].should.eql({
|
||||
name: '@cnpmtest/list_by_user_module1',
|
||||
description: 'mk2testmodule version description here',
|
||||
description: '',
|
||||
version: '1.0.1',
|
||||
});
|
||||
|
||||
map['@cnpmtest/list_by_user_module2'].should.be.an.Object();
|
||||
map['@cnpmtest/list_by_user_module2'].should.eql({
|
||||
name: '@cnpmtest/list_by_user_module2',
|
||||
description: 'mk2testmodule version description here',
|
||||
description: '',
|
||||
version: '2.0.0',
|
||||
});
|
||||
})
|
||||
|
||||
@@ -215,21 +215,6 @@ describe('test/controllers/registry/package/save.test.js', function () {
|
||||
.expect(403, done);
|
||||
});
|
||||
|
||||
it('should publish when maintainers dont contain current user in token mode', function* () {
|
||||
var token = yield tokenService.createToken(utils.admin);
|
||||
|
||||
var pkg = utils.getPackage('testmodule-new-4', '0.0.1', utils.admin);
|
||||
pkg.versions['0.0.1'].maintainers[0].name += '-testuser';
|
||||
|
||||
yield request(app)
|
||||
.put('/' + pkg.name)
|
||||
.set('authorization', 'Bearer ' + token.token)
|
||||
.send(pkg)
|
||||
.expect(201);
|
||||
|
||||
yield tokenService.deleteToken(utils.admin, token.token);
|
||||
});
|
||||
|
||||
it('should 400 when attachments missing', function (done) {
|
||||
var pkg = utils.getPackage('testmodule-new-1', '0.0.1', utils.admin);
|
||||
delete pkg._attachments;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var should = require('should');
|
||||
var request = require('supertest');
|
||||
var mm = require('mm');
|
||||
@@ -185,20 +184,6 @@ describe('test/controllers/registry/package/show.test.js', function () {
|
||||
.expect(404, done);
|
||||
});
|
||||
|
||||
it('should config.formatCustomOnePackageVersion work', async () => {
|
||||
mm(config, 'formatCustomOnePackageVersion', (ctx, packageVersion) => {
|
||||
console.log('%s %s, query: %j', ctx.method, ctx.url, ctx.query);
|
||||
packageVersion.description = '';
|
||||
packageVersion.readme = '';
|
||||
return packageVersion;
|
||||
});
|
||||
const res = await request(app)
|
||||
.get('/@cnpmtest/testmodule-show/0.0.1?b=123123');
|
||||
assert(res.status === 200);
|
||||
assert(res.body.description === '');
|
||||
assert(res.body.readme === '');
|
||||
});
|
||||
|
||||
describe('show sync package', function () {
|
||||
before(function (done) {
|
||||
utils.sync('baidu', done);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var should = require('should');
|
||||
var request = require('supertest');
|
||||
var mm = require('mm');
|
||||
@@ -120,13 +119,6 @@ describe('test/controllers/registry/package/update.test.js', function () {
|
||||
});
|
||||
|
||||
it('should add again new maintainers', function (done) {
|
||||
done = pedding(done, 2);
|
||||
mm(config, 'globalHook', function* (envelope) {
|
||||
assert(envelope.name === '@cnpmtest/testmodule-update-1');
|
||||
assert(envelope.type === 'package');
|
||||
assert(envelope.event === 'package:owner');
|
||||
done();
|
||||
});
|
||||
request(app)
|
||||
.put('/@cnpmtest/testmodule-update-1/-rev/1')
|
||||
.send({
|
||||
@@ -179,14 +171,6 @@ describe('test/controllers/registry/package/update.test.js', function () {
|
||||
});
|
||||
|
||||
it('should rm maintainers', function (done) {
|
||||
done = pedding(done, 2);
|
||||
mm(config, 'globalHook', function* (envelope) {
|
||||
assert(envelope.name === '@cnpmtest/testmodule-update-1');
|
||||
assert(envelope.type === 'package');
|
||||
assert(envelope.event === 'package:owner-rm');
|
||||
done();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.put('/@cnpmtest/testmodule-update-1/-rev/1')
|
||||
.send({
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var awaitEvent = require('await-event');
|
||||
var should = require('should');
|
||||
var mm = require('mm');
|
||||
var thunkify = require('thunkify-wrap');
|
||||
var request = require('supertest');
|
||||
var urllib = require('urllib');
|
||||
var urlparse = require('url').parse;
|
||||
var fs = require('mz/fs');
|
||||
var config = require('../../config');
|
||||
var common = require('../../lib/common');
|
||||
var SyncModuleWorker = require('../../controllers/sync_module_worker');
|
||||
var logService = require('../../services/module_log');
|
||||
var packageService = require('../../services/package');
|
||||
@@ -458,353 +455,4 @@ describe('test/controllers/sync_module_worker.test.js', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('save backup files', function () {
|
||||
const pkgName = 'backup-test';
|
||||
|
||||
beforeEach(() => {
|
||||
mm(config, 'syncBackupFiles', true);
|
||||
});
|
||||
|
||||
describe('package not exists', () => {
|
||||
const mockPackageJson = {
|
||||
name: pkgName,
|
||||
version: '1.0.0',
|
||||
description: 'foo',
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mm(packageService, 'listModulesByName', function* () {
|
||||
return [
|
||||
{ name: pkgName, version: '1.0.0' },
|
||||
];
|
||||
});
|
||||
mm(packageService, 'showPackage', function* () {
|
||||
return { package: mockPackageJson };
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function* () {
|
||||
yield config.nfs.remove(common.getPackageFileCDNKey(pkgName, '1.0.0'));
|
||||
});
|
||||
|
||||
it('should upload new file', function* () {
|
||||
var worker = new SyncModuleWorker({
|
||||
name: pkgName,
|
||||
username: 'fengmk2',
|
||||
});
|
||||
yield worker._saveBackupFiles();
|
||||
|
||||
const cdnKey = common.getPackageFileCDNKey(pkgName, '1.0.0');
|
||||
const filePath = '/tmp/tnpm-1.0.0.json';
|
||||
yield config.nfs.download(cdnKey, filePath);
|
||||
const fileContent = yield fs.readFile(filePath, 'utf8');
|
||||
const packageJson = JSON.parse(fileContent);
|
||||
assert.deepStrictEqual(packageJson, mockPackageJson);
|
||||
});
|
||||
});
|
||||
|
||||
describe('new dist tag', () => {
|
||||
beforeEach(() => {
|
||||
mm(packageService, 'listModulesByName', function* () {
|
||||
return [];
|
||||
});
|
||||
mm(packageService, 'listModuleTags', function* () {
|
||||
return [
|
||||
{ tag: 'latest', version: '1.0.0' },
|
||||
];
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function* () {
|
||||
yield config.nfs.remove(common.getDistTagCDNKey(pkgName, 'latest'));
|
||||
});
|
||||
|
||||
it('should create dist-tag file', function* () {
|
||||
var worker = new SyncModuleWorker({
|
||||
name: pkgName,
|
||||
username: 'fengmk2',
|
||||
});
|
||||
yield worker._saveBackupFiles();
|
||||
|
||||
const cdnKey = common.getDistTagCDNKey(pkgName, 'latest');
|
||||
const filePath = '/tmp/tnpm-dist-tag.json';
|
||||
yield config.nfs.download(cdnKey, filePath);
|
||||
const fileContent = yield fs.readFile(filePath, 'utf8');
|
||||
assert(fileContent === '1.0.0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove dist tag', () => {
|
||||
beforeEach(function* () {
|
||||
mm(packageService, 'listModulesByName', function* () {
|
||||
return [];
|
||||
});
|
||||
mm(packageService, 'listModuleTags', function* () {
|
||||
return [];
|
||||
});
|
||||
const cdnKey = common.getDistTagCDNKey(pkgName, 'latest');
|
||||
const filePath = '/tmp/tnpm-dist-tag.json';
|
||||
yield fs.writeFile(filePath, '1.0.0');
|
||||
yield config.nfs.upload(filePath, {
|
||||
key: cdnKey,
|
||||
});
|
||||
});
|
||||
|
||||
it('should delete', function* () {
|
||||
var worker = new SyncModuleWorker({
|
||||
name: pkgName,
|
||||
username: 'fengmk2',
|
||||
});
|
||||
yield worker._saveBackupFiles();
|
||||
|
||||
const cdnKey = common.getDistTagCDNKey(pkgName, 'latest');
|
||||
let err;
|
||||
try {
|
||||
const filePath = '/tmp/tnpm-dist-tag.json';
|
||||
yield config.nfs.download(cdnKey, filePath);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
assert(/ENOENT/.test(err));
|
||||
});
|
||||
});
|
||||
|
||||
describe('update dist tag', () => {
|
||||
beforeEach(function* () {
|
||||
mm(packageService, 'listModulesByName', function* () {
|
||||
return [];
|
||||
});
|
||||
mm(packageService, 'listModuleTags', function* () {
|
||||
return [
|
||||
{ tag: 'latest', version: '1.0.1' },
|
||||
];
|
||||
});
|
||||
const cdnKey = common.getDistTagCDNKey(pkgName, 'latest');
|
||||
const filePath = '/tmp/tnpm-dist-tag.json';
|
||||
yield fs.writeFile(filePath, '1.0.0');
|
||||
yield config.nfs.upload(filePath, {
|
||||
key: cdnKey,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function* () {
|
||||
yield config.nfs.remove(common.getDistTagCDNKey(pkgName, 'latest'));
|
||||
});
|
||||
|
||||
it('should update dist-tag file', function* () {
|
||||
var worker = new SyncModuleWorker({
|
||||
name: pkgName,
|
||||
username: 'fengmk2',
|
||||
});
|
||||
yield worker._saveBackupFiles();
|
||||
|
||||
const cdnKey = common.getDistTagCDNKey(pkgName, 'latest');
|
||||
const filePath = '/tmp/tnpm-dist-tag.json';
|
||||
yield config.nfs.download(cdnKey, filePath);
|
||||
const fileContent = yield fs.readFile(filePath, 'utf8');
|
||||
assert(fileContent === '1.0.1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('package unpublished', () => {
|
||||
it('should sync unpublished info', function* () {
|
||||
var worker = new SyncModuleWorker({
|
||||
name: ['afp'],
|
||||
username: 'fengmk2'
|
||||
});
|
||||
|
||||
worker.start();
|
||||
yield awaitEvent(worker, 'end');
|
||||
|
||||
const cdnKey = common.getUnpublishFileKey('afp');
|
||||
const filePath = '/tmp/unpublish-package.json';
|
||||
yield config.nfs.download(cdnKey, filePath);
|
||||
const fileContent = yield fs.readFile(filePath, 'utf8');
|
||||
assert(fileContent);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sync from backup files', function () {
|
||||
const pkgName = 'sync-from-backup-files';
|
||||
const publishTime100 = Date.now() - 1000 * 60;
|
||||
const publishTime101 = Date.now();
|
||||
|
||||
afterEach(function* () {
|
||||
try {
|
||||
yield config.nfs.remove(common.getDistTagCDNKey(pkgName, 'latest'));
|
||||
yield config.nfs.remove(common.getDistTagCDNKey(pkgName, 'beta'));
|
||||
yield config.nfs.remove(common.getPackageFileCDNKey(pkgName, '1.0.1'));
|
||||
yield config.nfs.remove(common.getPackageFileCDNKey(pkgName, '1.0.0'));
|
||||
} catch (_) {
|
||||
// ...
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(function* () {
|
||||
mm(config, 'syncBackupFiles', true);
|
||||
|
||||
const packageFileCDNKey100 = common.getPackageFileCDNKey(pkgName, '1.0.0');
|
||||
const packageFilePath = '/tmp/tnpm-package.json';
|
||||
yield fs.writeFile(packageFilePath, JSON.stringify({
|
||||
name: pkgName,
|
||||
version: '1.0.0',
|
||||
publish_time: publishTime100,
|
||||
description: 'mock desc',
|
||||
maintainers: [],
|
||||
author: {},
|
||||
repository: {},
|
||||
readme: 'mock readme',
|
||||
readmeFilename: 'README.md',
|
||||
homepage: 'mock home page',
|
||||
bugs: {},
|
||||
license: 'MIT',
|
||||
}));
|
||||
yield config.nfs.upload(packageFilePath, {
|
||||
key: packageFileCDNKey100,
|
||||
});
|
||||
|
||||
const packageFileCDNKey101 = common.getPackageFileCDNKey(pkgName, '1.0.1');
|
||||
yield fs.writeFile(packageFilePath, JSON.stringify({
|
||||
name: pkgName,
|
||||
version: '1.0.1',
|
||||
publish_time: publishTime101,
|
||||
description: 'mock desc 101',
|
||||
maintainers: [],
|
||||
author: {},
|
||||
repository: {},
|
||||
readme: 'mock readme 101',
|
||||
readmeFilename: 'README.md',
|
||||
homepage: 'mock home page 101',
|
||||
bugs: {},
|
||||
license: 'MIT',
|
||||
}));
|
||||
yield config.nfs.upload(packageFilePath, {
|
||||
key: packageFileCDNKey101,
|
||||
});
|
||||
|
||||
const distTagCDNKey = common.getDistTagCDNKey(pkgName, 'latest');
|
||||
const distTagFilePath = '/tmp/tnpm-dist-tag.json';
|
||||
yield fs.writeFile(distTagFilePath, '1.0.0');
|
||||
yield config.nfs.upload(distTagFilePath, {
|
||||
key: distTagCDNKey,
|
||||
});
|
||||
|
||||
const distTagCDNKeyBeta = common.getDistTagCDNKey(pkgName, 'beta');
|
||||
yield fs.writeFile(distTagFilePath, '1.0.1');
|
||||
yield config.nfs.upload(distTagFilePath, {
|
||||
key: distTagCDNKeyBeta,
|
||||
});
|
||||
});
|
||||
|
||||
it('should create pkg', function (done) {
|
||||
var worker = new SyncModuleWorker({
|
||||
name: pkgName,
|
||||
username: 'fengmk2',
|
||||
syncFromBackupFile: true,
|
||||
});
|
||||
var syncPkg;
|
||||
mm(worker, '_sync', function* (name, pkg) {
|
||||
syncPkg = pkg;
|
||||
return [ '1.0.0' ];
|
||||
})
|
||||
worker.start();
|
||||
worker.on('end', function () {
|
||||
assert.deepStrictEqual(worker.successes, [
|
||||
pkgName,
|
||||
]);
|
||||
|
||||
assert.deepStrictEqual(syncPkg, {
|
||||
name: pkgName,
|
||||
'dist-tags': { beta: '1.0.1', latest: '1.0.0' },
|
||||
versions: {
|
||||
'1.0.0': {
|
||||
name: pkgName,
|
||||
version: '1.0.0',
|
||||
publish_time: publishTime100,
|
||||
description: 'mock desc',
|
||||
maintainers: [],
|
||||
author: {},
|
||||
repository: {},
|
||||
readme: 'mock readme',
|
||||
readmeFilename: 'README.md',
|
||||
homepage: 'mock home page',
|
||||
bugs: {},
|
||||
license: 'MIT'
|
||||
},
|
||||
'1.0.1': {
|
||||
name: pkgName,
|
||||
version: '1.0.1',
|
||||
publish_time: publishTime101,
|
||||
description: 'mock desc 101',
|
||||
maintainers: [],
|
||||
author: {},
|
||||
repository: {},
|
||||
readme: 'mock readme 101',
|
||||
readmeFilename: 'README.md',
|
||||
homepage: 'mock home page 101',
|
||||
bugs: {},
|
||||
license: 'MIT'
|
||||
}
|
||||
},
|
||||
time: {
|
||||
modified: new Date(publishTime101),
|
||||
created: new Date(publishTime100),
|
||||
'1.0.0': new Date(publishTime100),
|
||||
'1.0.1': new Date(publishTime101),
|
||||
},
|
||||
description: 'mock desc 101',
|
||||
maintainers: [],
|
||||
author: {},
|
||||
repository: {},
|
||||
readme: 'mock readme 101',
|
||||
readmeFilename: 'README.md',
|
||||
homepage: 'mock home page 101',
|
||||
bugs: {},
|
||||
license: 'MIT'
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('unpublish', () => {
|
||||
before(function* () {
|
||||
const filePath = '/tmp/unpublish-package.json';
|
||||
const cdnKey = common.getUnpublishFileKey('afp');
|
||||
yield fs.writeFile(filePath, JSON.stringify({
|
||||
name: 'xinglie',
|
||||
time: '2017-02-21T13:10:22.892Z',
|
||||
tags: { latest: '0.0.1' },
|
||||
maintainers:[{
|
||||
name: 'xinglie',
|
||||
email: 'kooboy_li@163.com'
|
||||
}],
|
||||
versions:["0.0.1"]
|
||||
}));
|
||||
yield config.nfs.upload(filePath, {
|
||||
key: cdnKey,
|
||||
});
|
||||
});
|
||||
|
||||
it('should unpublished pkg', function* () {
|
||||
const worker = new SyncModuleWorker({
|
||||
name: ['afp'],
|
||||
username: 'fengmk2',
|
||||
syncFromBackupFile: true,
|
||||
});
|
||||
let unpublishPkg;
|
||||
mm(worker, '_unpublished', function(pkg) {
|
||||
unpublishPkg = pkg;
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
worker.start();
|
||||
yield awaitEvent(worker, 'end');
|
||||
|
||||
assert(unpublishPkg === 'afp');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -41,8 +41,8 @@ describe('test/controllers/web/package/search.test.js', function () {
|
||||
.expect(200)
|
||||
.expect({
|
||||
keyword: '@cnpmtest/testmodule-web-search',
|
||||
match: { name: '@cnpmtest/testmodule-web-search', description: 'mk2testmodule version description here' },
|
||||
packages: [ { name: '@cnpmtest/testmodule-web-search', description: 'mk2testmodule version description here' } ],
|
||||
match: { name: '@cnpmtest/testmodule-web-search', description: '' },
|
||||
packages: [ { name: '@cnpmtest/testmodule-web-search', description: '' } ],
|
||||
keywords: []
|
||||
})
|
||||
.expect('content-type', 'application/json; charset=utf-8', done);
|
||||
@@ -52,7 +52,7 @@ describe('test/controllers/web/package/search.test.js', function () {
|
||||
request(app)
|
||||
.get('/browse/keyword/@cnpmtest/testmodule-web-search?type=json&callback=foo')
|
||||
.expect(200)
|
||||
.expect('/**/ typeof foo === \'function\' && foo({"keyword":"@cnpmtest/testmodule-web-search","match":{"name":"@cnpmtest/testmodule-web-search","description":"mk2testmodule version description here"},"packages":[{"name":"@cnpmtest/testmodule-web-search","description":"mk2testmodule version description here"}],"keywords":[]});')
|
||||
.expect('/**/ typeof foo === \'function\' && foo({"keyword":"@cnpmtest/testmodule-web-search","match":{"name":"@cnpmtest/testmodule-web-search","description":""},"packages":[{"name":"@cnpmtest/testmodule-web-search","description":""}],"keywords":[]});')
|
||||
.expect('content-type', 'application/javascript; charset=utf-8', done);
|
||||
});
|
||||
|
||||
@@ -87,8 +87,8 @@ describe('test/controllers/web/package/search.test.js', function () {
|
||||
.expect({
|
||||
keyword: '@cnpmtest/testmodule-web-searc',
|
||||
match: null,
|
||||
packages: [ { name: '@cnpmtest/testmodule-web-search', description: 'mk2testmodule version description here' },
|
||||
{ name: '@cnpmtest/testmodule-web-search_a', description: 'mk2testmodule version description here' }],
|
||||
packages: [ { name: '@cnpmtest/testmodule-web-search', description: '' },
|
||||
{ name: '@cnpmtest/testmodule-web-search_a', description: '' }],
|
||||
keywords: []
|
||||
})
|
||||
.expect('content-type', 'application/json; charset=utf-8', done);
|
||||
@@ -101,7 +101,7 @@ describe('test/controllers/web/package/search.test.js', function () {
|
||||
.expect({
|
||||
keyword: '@cnpmtest/testmodule-web-searc',
|
||||
match: null,
|
||||
packages: [ { name: '@cnpmtest/testmodule-web-search', description: 'mk2testmodule version description here' }],
|
||||
packages: [ { name: '@cnpmtest/testmodule-web-search', description: '' }],
|
||||
keywords: []
|
||||
})
|
||||
.expect('content-type', 'application/json; charset=utf-8', done);
|
||||
|
||||
@@ -82,7 +82,6 @@ describe('controllers/web/user/show.test.js', function () {
|
||||
// he.enclde('fengmk2@gmail.com') ↓
|
||||
assert(res.text.includes('fengmk2@gmail.com'));
|
||||
assert(res.headers['x-custom-web-middleware'] === 'true');
|
||||
assert(res.headers['x-custom-web-app-models'] === 'true');
|
||||
done()
|
||||
});
|
||||
});
|
||||
|
||||
54
test/fixtures/package_and_tgz.json
vendored
54
test/fixtures/package_and_tgz.json
vendored
@@ -1,53 +1 @@
|
||||
{
|
||||
"_id": "mk2testmodule",
|
||||
"name": "mk2testmodule",
|
||||
"description": "mk2testmodule description here",
|
||||
"dist-tags": {
|
||||
"latest": "0.0.1"
|
||||
},
|
||||
"versions": {
|
||||
"0.0.1": {
|
||||
"name": "mk2testmodule",
|
||||
"version": "0.0.1",
|
||||
"description": "mk2testmodule version description here",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"readme": "ERROR: No README data found!",
|
||||
"_id": "mk2testmodule@0.0.1",
|
||||
"dist": {
|
||||
"shasum": "fa475605f88bab9b1127833633ca3ae0a477224c",
|
||||
"tarball": "http://127.0.0.1:7001/mk2testmodule/-/mk2testmodule-0.0.1.tgz"
|
||||
},
|
||||
"_from": ".",
|
||||
"_npmVersion": "1.4.3",
|
||||
"_npmUser": {
|
||||
"name": "fengmk2",
|
||||
"email": "fengmk2@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "fengmk2",
|
||||
"email": "fengmk2@gmail.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "fengmk2",
|
||||
"email": "fengmk2@gmail.com"
|
||||
}
|
||||
],
|
||||
"_attachments": {
|
||||
"mk2testmodule-0.0.1.tgz": {
|
||||
"content_type": "application/octet-stream",
|
||||
"data": "H4sIAAAAAAAAA+2SsWrDMBCGPfspDg2ZinOyEgeylg6Zu2YR8rVRHEtGkkOg5N0jWaFdujVQAv6W4/7/dHcSGqTq5Ccthxyro7emeDCI2KxWkOKmaaaIdc4TouZQ8FqgwI3AdVMgF8ijho9e5DdGH6SLq/y1T74LfMcn4asEYEb2xLbA+q4O5ENv2/FE7CVZZ3JeW5NcrLDiWW3JK6eHcHey2Es9Zdq0dIkfKau50EcjjYpCmpDKSB0s7Nmbc9ZtwVhIBviBlP7Q1O4ZLBZAFx2As3jyOnWTYzhY9zPzpBUZPy2/e39l5bX87wedmZmZeRJuheTX2wAIAAA=",
|
||||
"length": 251
|
||||
}
|
||||
}
|
||||
}
|
||||
{"_id":"mk2testmodule","name":"mk2testmodule","description":"","dist-tags":{"latest":"0.0.1"},"versions":{"0.0.1":{"name":"mk2testmodule","version":"0.0.1","description":"","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"author":"","license":"ISC","readme":"ERROR: No README data found!","_id":"mk2testmodule@0.0.1","dist":{"shasum":"fa475605f88bab9b1127833633ca3ae0a477224c","tarball":"http://127.0.0.1:7001/mk2testmodule/-/mk2testmodule-0.0.1.tgz"},"_from":".","_npmVersion":"1.4.3","_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}]}},"readme":"ERROR: No README data found!","maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_attachments":{"mk2testmodule-0.0.1.tgz":{"content_type":"application/octet-stream","data":"H4sIAAAAAAAAA+2SsWrDMBCGPfspDg2ZinOyEgeylg6Zu2YR8rVRHEtGkkOg5N0jWaFdujVQAv6W4/7/dHcSGqTq5Ccthxyro7emeDCI2KxWkOKmaaaIdc4TouZQ8FqgwI3AdVMgF8ijho9e5DdGH6SLq/y1T74LfMcn4asEYEb2xLbA+q4O5ENv2/FE7CVZZ3JeW5NcrLDiWW3JK6eHcHey2Es9Zdq0dIkfKau50EcjjYpCmpDKSB0s7Nmbc9ZtwVhIBviBlP7Q1O4ZLBZAFx2As3jyOnWTYzhY9zPzpBUZPy2/e39l5bX87wedmZmZeRJuheTX2wAIAAA=","length":251}}}
|
||||
|
||||
@@ -4,9 +4,6 @@ var should = require('should');
|
||||
var sleep = require('co-sleep');
|
||||
var Package = require('../../services/package');
|
||||
var utils = require('../utils');
|
||||
var common = require('../../services/common');
|
||||
const config = require('../../config');
|
||||
const os = require('os');
|
||||
|
||||
describe('test/services/package.test.js', function () {
|
||||
describe('addModuleTag()', function () {
|
||||
@@ -29,15 +26,6 @@ describe('test/services/package.test.js', function () {
|
||||
var tag = yield Package.addModuleTag('not-exists', 'latest', '1.0.0');
|
||||
should.not.exist(tag);
|
||||
});
|
||||
|
||||
it('should return Error when tag length out of range', function* () {
|
||||
const r = yield utils.createModule('test-addModuleTag-module-name', '1.0.0');
|
||||
try {
|
||||
yield Package.addModuleTag(r.name, Buffer.alloc(config.tagLen + 1, 'a'), r.version);
|
||||
} catch (error) {
|
||||
error.message.should.equal(`addModuleTag Error: length of tag(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) > 70${os.EOL}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('getModuleByTag()', function () {
|
||||
@@ -156,7 +144,7 @@ describe('test/services/package.test.js', function () {
|
||||
var alls = yield Package.listAllPublicModuleNames();
|
||||
alls.length.should.above(0);
|
||||
alls.forEach(function (name) {
|
||||
common.isPrivatePackage(name).should.equal(false);
|
||||
name.should.not.containEql('@');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user