jj.js 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +17 -92
- package/jj.js +3 -3
- package/lib/app.js +16 -0
- package/lib/config.js +4 -4
- package/lib/context.js +5 -1
- package/lib/ctx.js +39 -41
- package/lib/db.js +33 -37
- package/lib/logger.js +11 -1
- package/lib/middleware.js +2 -2
- package/lib/model.js +5 -9
- package/lib/pagination.js +3 -3
- package/lib/response.js +1 -1
- package/lib/run.js +30 -26
- package/lib/storage.js +5 -0
- package/lib/tpl/types.js +22 -0
- package/lib/types.js +215 -265
- package/lib/upload.js +2 -2
- package/lib/utils/fs.js +53 -62
- package/lib/utils/utils.js +1 -1
- package/lib/view.js +4 -3
- package/package.json +4 -1
- package/types.js +308 -0
package/lib/model.js
CHANGED
|
@@ -2,9 +2,9 @@ const Context = require('./context');
|
|
|
2
2
|
const {toLine} = require('./utils/str');
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @typedef {import('
|
|
6
|
-
* @typedef {import('
|
|
7
|
-
* @typedef {import('
|
|
5
|
+
* @typedef {import('../types').OkPacket} OkPacket
|
|
6
|
+
* @typedef {import('../types').RowData} RowData
|
|
7
|
+
* @typedef {import('../types').ListData} ListData
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -15,7 +15,7 @@ class Model extends Context
|
|
|
15
15
|
/**
|
|
16
16
|
* Initialize a new `Model`
|
|
17
17
|
* @public
|
|
18
|
-
* @param {import('
|
|
18
|
+
* @param {import('../types').KoaCtx} ctx
|
|
19
19
|
*/
|
|
20
20
|
constructor(ctx) {
|
|
21
21
|
super(ctx);
|
|
@@ -32,7 +32,6 @@ class Model extends Context
|
|
|
32
32
|
* @returns {Promise<OkPacket>}
|
|
33
33
|
*/
|
|
34
34
|
async add(data) {
|
|
35
|
-
// @ts-ignore
|
|
36
35
|
return await this.db.allowField().insert(data);
|
|
37
36
|
}
|
|
38
37
|
|
|
@@ -49,7 +48,6 @@ class Model extends Context
|
|
|
49
48
|
condition[this.pk] = data[this.pk];
|
|
50
49
|
delete data[this.pk];
|
|
51
50
|
}
|
|
52
|
-
// @ts-ignore
|
|
53
51
|
return await this.db.allowField().update(data, condition);
|
|
54
52
|
}
|
|
55
53
|
|
|
@@ -64,7 +62,6 @@ class Model extends Context
|
|
|
64
62
|
* @returns {Promise<OkPacket>}
|
|
65
63
|
*/
|
|
66
64
|
async del(condition) {
|
|
67
|
-
// @ts-ignore
|
|
68
65
|
return await this.db.delete(condition);
|
|
69
66
|
}
|
|
70
67
|
|
|
@@ -85,13 +82,12 @@ class Model extends Context
|
|
|
85
82
|
* @returns {Promise<(ListData)>}
|
|
86
83
|
*/
|
|
87
84
|
async all(condition) {
|
|
88
|
-
// @ts-ignore
|
|
89
85
|
return await this.db.select(condition);
|
|
90
86
|
}
|
|
91
87
|
|
|
92
88
|
/**
|
|
93
89
|
* 数据库实例
|
|
94
|
-
* @type {
|
|
90
|
+
* @type {import('../types').DbInstance}
|
|
95
91
|
*/
|
|
96
92
|
get db() {
|
|
97
93
|
if(!this._db){
|
package/lib/pagination.js
CHANGED
|
@@ -9,7 +9,7 @@ class Pagination extends Context
|
|
|
9
9
|
/**
|
|
10
10
|
* Initialize a new `Pagination`
|
|
11
11
|
* @public
|
|
12
|
-
* @param {import('
|
|
12
|
+
* @param {import('../types').KoaCtx} ctx
|
|
13
13
|
*/
|
|
14
14
|
constructor(ctx) {
|
|
15
15
|
super(ctx);
|
|
@@ -23,12 +23,12 @@ class Pagination extends Context
|
|
|
23
23
|
/**
|
|
24
24
|
* 分页配置
|
|
25
25
|
* @public
|
|
26
|
-
* @param {import('
|
|
26
|
+
* @param {import('../types').PageConfig} [options]
|
|
27
27
|
* @returns {this}
|
|
28
28
|
*/
|
|
29
29
|
init(options) {
|
|
30
30
|
/**
|
|
31
|
-
* @type {import('
|
|
31
|
+
* @type {import('../types').PageConfig}
|
|
32
32
|
* @private
|
|
33
33
|
*/
|
|
34
34
|
this.options = {...cfg_page, ...options};
|
package/lib/response.js
CHANGED
package/lib/run.js
CHANGED
|
@@ -1,39 +1,43 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const loader = require('./loader');
|
|
3
|
-
const {readFile} = require('
|
|
3
|
+
const {readFile} = require('fs').promises;
|
|
4
4
|
const {toHump} = require('./utils/str');
|
|
5
|
-
const
|
|
5
|
+
const config = require('./config');
|
|
6
|
+
const {app: cfg_app, view: cfg_view} = config;
|
|
6
7
|
const compose = require('koa-compose');
|
|
7
8
|
const Logger = require('./logger');
|
|
9
|
+
const storage = require('./storage');
|
|
8
10
|
|
|
9
11
|
async function run(ctx, next, control_type=cfg_app.controller_folder) {
|
|
10
12
|
if(cfg_app.app_debug) {
|
|
11
|
-
Logger.
|
|
12
|
-
Logger.
|
|
13
|
-
Object.keys(ctx.params).length && Logger.
|
|
14
|
-
Object.keys(ctx.query).length && Logger.
|
|
15
|
-
Object.keys(ctx.request.body || {}).length && Logger.
|
|
13
|
+
Logger.http('Request:', ctx.request);
|
|
14
|
+
Logger.http({Router: control_type, APP: ctx.APP, CONTROLLER: ctx.CONTROLLER, ACTION: ctx.ACTION});
|
|
15
|
+
Object.keys(ctx.params).length && Logger.http('Params:', ctx.params);
|
|
16
|
+
Object.keys(ctx.query).length && Logger.http('Get:', ctx.query);
|
|
17
|
+
Object.keys(ctx.request.body || {}).length && Logger.http('Post:', ctx.request.body);
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
// 设置store
|
|
21
|
+
const store = storage.getStore();
|
|
22
|
+
store.APP = ctx.APP;
|
|
23
|
+
store.CONTROLLER = ctx.CONTROLLER;
|
|
24
|
+
store.ACTION = ctx.ACTION;
|
|
25
|
+
store.COMMON = cfg_app.common_app;
|
|
18
26
|
// 设置根加载器
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
ctx._.config.log = log;
|
|
27
|
-
ctx._.config.cache = cache;
|
|
28
|
-
ctx._.config.cookie = cookie;
|
|
29
|
-
ctx._.config.tpl = tpl;
|
|
27
|
+
store.$ = loader('./', ctx);
|
|
28
|
+
store._ = loader(cfg_app.base_dir, ctx);
|
|
29
|
+
// 配置特殊处理
|
|
30
|
+
store._.config === undefined && (store._.config = {});
|
|
31
|
+
Object.entries(config).forEach(([key, value]) => {
|
|
32
|
+
store._.config[key] = value;
|
|
33
|
+
});
|
|
30
34
|
|
|
31
35
|
// 应用、控制器、方法名字验证
|
|
32
36
|
if(~ctx.APP.indexOf('.') || ~ctx.CONTROLLER.indexOf('.') || ~ctx.ACTION.indexOf('.')) {
|
|
33
37
|
throw new Error(`RunError: 应用、控制器或方法名字不合法!`);
|
|
34
38
|
}
|
|
35
39
|
|
|
36
|
-
if(ctx.APP[0] == '_' || ctx.APP[0] == '$' || !
|
|
40
|
+
if(ctx.APP[0] == '_' || ctx.APP[0] == '$' || !store._[ctx.APP]) {
|
|
37
41
|
if(cfg_app.app_debug) {
|
|
38
42
|
throw new Error(`RunError: 应用:${ctx.APP}不存在!`);
|
|
39
43
|
} else {
|
|
@@ -41,7 +45,7 @@ async function run(ctx, next, control_type=cfg_app.controller_folder) {
|
|
|
41
45
|
}
|
|
42
46
|
}
|
|
43
47
|
|
|
44
|
-
if(!
|
|
48
|
+
if(!store._[ctx.APP][control_type]) {
|
|
45
49
|
if(cfg_app.app_debug) {
|
|
46
50
|
throw new Error(`RunError: 目录:${ctx.APP}/${control_type}不存在!`);
|
|
47
51
|
} else {
|
|
@@ -51,7 +55,7 @@ async function run(ctx, next, control_type=cfg_app.controller_folder) {
|
|
|
51
55
|
|
|
52
56
|
// 模版文件内容直接输出
|
|
53
57
|
if(control_type == cfg_view.view_folder) {
|
|
54
|
-
const content = await readFile(path.join(
|
|
58
|
+
const content = await readFile(path.join(cfg_app.base_dir, `${ctx.APP}/${control_type}`, ctx.CONTROLLER + cfg_view.view_depr + ctx.ACTION + cfg_view.view_ext));
|
|
55
59
|
if(!content) {
|
|
56
60
|
throw new Error(`RunError: 模板文件:${ctx.APP}/${control_type}/${ctx.CONTROLLER + cfg_view.view_depr + ctx.ACTION + cfg_view.view_ext}不存在!`);
|
|
57
61
|
}
|
|
@@ -60,7 +64,7 @@ async function run(ctx, next, control_type=cfg_app.controller_folder) {
|
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
// 控制器
|
|
63
|
-
const Controller =
|
|
67
|
+
const Controller = store._[ctx.APP][control_type][ctx.CONTROLLER] || store._[ctx.APP][control_type]['_empty'];
|
|
64
68
|
|
|
65
69
|
if(ctx.CONTROLLER[0] == '_' || ctx.CONTROLLER[0] == '$' || typeof Controller != 'function') {
|
|
66
70
|
if(cfg_app.app_debug) {
|
|
@@ -73,7 +77,7 @@ async function run(ctx, next, control_type=cfg_app.controller_folder) {
|
|
|
73
77
|
// 控制器实例
|
|
74
78
|
const $controller = new Controller(ctx, next);
|
|
75
79
|
const humpAction = toHump(ctx.ACTION);
|
|
76
|
-
const action = typeof $controller[humpAction] == 'function' ? humpAction : '
|
|
80
|
+
const action = typeof $controller[humpAction] == 'function' ? humpAction : '_empty';
|
|
77
81
|
|
|
78
82
|
if(ctx.ACTION[0] == '_' || ctx.ACTION[0] == '$' || typeof $controller[action] != 'function') {
|
|
79
83
|
if(cfg_app.app_debug) {
|
|
@@ -96,13 +100,13 @@ async function run(ctx, next, control_type=cfg_app.controller_folder) {
|
|
|
96
100
|
}
|
|
97
101
|
return stack.concat(async (ctx, next) => {
|
|
98
102
|
const [METHOD = action, MIDDLEWARE = ctx.CONTROLLER, APP = ctx.APP] = middle.middleware.split('/').reverse();
|
|
99
|
-
if(!
|
|
103
|
+
if(!store._[APP]) {
|
|
100
104
|
throw new Error(`RunError: 中间件应用:${APP}不存在!`);
|
|
101
105
|
}
|
|
102
|
-
if(!
|
|
106
|
+
if(!store._[APP]['middleware']) {
|
|
103
107
|
throw new Error(`RunError: 中间件目录:${APP}/middleware不存在!`);
|
|
104
108
|
}
|
|
105
|
-
const Middleware =
|
|
109
|
+
const Middleware = store._[APP]['middleware'][MIDDLEWARE];
|
|
106
110
|
if(!Middleware || typeof Middleware != 'function') {
|
|
107
111
|
throw new Error(`RunError: 中间件文件:${APP}/middleware/${MIDDLEWARE}不存在!`);
|
|
108
112
|
}
|
package/lib/storage.js
ADDED
package/lib/tpl/types.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module.exports = `/**
|
|
2
|
+
* @type {typeof import('jj.js/types')}
|
|
3
|
+
*/
|
|
4
|
+
const JJCtx = require('jj.js').Ctx;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('jj.js/types').Config} JJConfig
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
__TYPES__
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @class Ctx
|
|
14
|
+
*/
|
|
15
|
+
class Ctx extends JJCtx {
|
|
16
|
+
__PROPERTY__
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @module types
|
|
21
|
+
*/
|
|
22
|
+
module.exports = Ctx;`;
|