Compare commits

...

2 Commits

Author SHA1 Message Date
Chen Yangjian
31294a819b fix: model init (#1626) 2021-03-02 10:52:32 +08:00
fengmk2
9d9b834488 feat: use leoric for the ORM solution
https://www.cyj.me/leoric/zh/
2021-03-02 09:49:06 +08:00
13 changed files with 115 additions and 139 deletions

3
.eslintrc Normal file
View File

@@ -0,0 +1,3 @@
{
"extends": "eslint-config-egg"
}

1
.gitignore vendored
View File

@@ -30,3 +30,4 @@ config/web_readme.md
.tmp/
*.sqlite
run/

View File

@@ -1,7 +0,0 @@
node_modules/
coverage/
.tmp/
.git/
tools/
public/
test/

View File

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

View File

@@ -1,3 +0,0 @@
{
"notify": false
}

View File

@@ -1,11 +0,0 @@
sudo: false
language: node_js
node_js:
- '8'
- '10'
services:
- mysql
- postgresql
script: 'make test-travis-all'
after_script:
- 'npm i codecov && codecov'

6
app/model/README.md Normal file
View 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
View 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;
};

17
config/config.default.js Normal file
View 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 || '',
},
};
};

6
config/plugin.js Normal file
View File

@@ -0,0 +1,6 @@
'use strict';
exports.orm = {
enable: true,
package: 'egg-orm',
};

View File

@@ -1,12 +1,13 @@
{
"name": "cnpmjs.org",
"version": "3.0.0-rc.40",
"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,6 +27,8 @@
"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": "^1.2.0",
"giturl": "^1.0.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)"
],

11
test/.setup.js Normal file
View 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');
});

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