jj.js 0.12.0 → 0.14.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 +12 -0
- package/jj.js +1 -1
- package/jsconfig.json +2 -2
- package/lib/app.js +4 -1
- package/lib/config.js +6 -1
- package/lib/cookie.js +4 -3
- package/lib/ctx.js +2 -2
- package/lib/loader.js +2 -2
- package/lib/request.js +204 -0
- package/lib/response.js +2 -15
- package/lib/run.js +0 -1
- package/lib/types.js +17 -11
- package/lib/url.js +15 -6
- package/package.json +1 -1
- package/types.js +13 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# v0.14.0 / 2024-03-07
|
|
2
|
+
1. 优化类型文件生成
|
|
3
|
+
2. 修复优化url生成
|
|
4
|
+
3. 自动加载功能,不缓存空文件
|
|
5
|
+
4. 修复优化Resquest类请求方法判断
|
|
6
|
+
5. 默认开启cookie签名机制
|
|
7
|
+
|
|
8
|
+
# v0.13.0 / 2024-02-27
|
|
9
|
+
1. 新增request系统类库
|
|
10
|
+
2. response类isAjax方法迁移到request类
|
|
11
|
+
3. 优化应用端types类型文件生成逻辑,启动服务时生成一次
|
|
12
|
+
|
|
1
13
|
# v0.12.0 / 2024-02-26
|
|
2
14
|
1. 添加依赖`watch`
|
|
3
15
|
|
package/jj.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* jj.js核心库<br/>
|
|
3
|
-
* {App, Cache, Context, Controller, Cookie, Ctx, Db, Logger, Middleware, Model, Pagination, Response, Upload, Url, View, utils, config}
|
|
3
|
+
* {App, Cache, Context, Controller, Cookie, Ctx, Db, Logger, Middleware, Model, Pagination, Request, Response, Upload, Url, View, utils, config}
|
|
4
4
|
* @module core
|
|
5
5
|
* @type {import('./types').Core}
|
|
6
6
|
*/
|
package/jsconfig.json
CHANGED
package/lib/app.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const Koa = require('koa');
|
|
3
|
-
const {app: cfg_app} = require('./config');
|
|
3
|
+
const {app: cfg_app, cookie: cfg_cookie} = require('./config');
|
|
4
4
|
const Logger = require('./logger');
|
|
5
5
|
const Response = require('./response');
|
|
6
6
|
const router = require('./router');
|
|
@@ -54,6 +54,9 @@ class App extends Koa
|
|
|
54
54
|
// router
|
|
55
55
|
this.use(router.routes()).use(router.allowedMethods());
|
|
56
56
|
|
|
57
|
+
// cookie
|
|
58
|
+
cfg_cookie.keys && (this.keys = cfg_app.app_debug ? ['jj.js'] : cfg_cookie.keys);
|
|
59
|
+
|
|
57
60
|
// types
|
|
58
61
|
if(cfg_app.app_debug) {
|
|
59
62
|
const {isFileSync} = require('./utils/fs');
|
package/lib/config.js
CHANGED
|
@@ -49,6 +49,11 @@ const cache = {
|
|
|
49
49
|
clear_time: undefined // (undefined: 清理一次, 0: 关闭自动清理, >0: 为自动清理周期)
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
const cookie = {
|
|
53
|
+
keys: [Math.random().toString(36).slice(-8)], // cookie密钥
|
|
54
|
+
signed: true // 默认开启签名
|
|
55
|
+
}
|
|
56
|
+
|
|
52
57
|
const page = {
|
|
53
58
|
page_key : 'page', // 默认分页标识
|
|
54
59
|
key_origin : 'query', // query 或 params
|
|
@@ -94,6 +99,6 @@ module.exports = {
|
|
|
94
99
|
cache: {...cache, ...base_config.cache},
|
|
95
100
|
page: {...page, ...base_config.page},
|
|
96
101
|
routes: base_config.routes,
|
|
97
|
-
cookie: base_config.cookie,
|
|
102
|
+
cookie: {...cookie, ...base_config.cookie},
|
|
98
103
|
tpl: {...tpl, ...base_config.tpl}
|
|
99
104
|
};
|
package/lib/cookie.js
CHANGED
|
@@ -30,20 +30,21 @@ class Cookie extends Context
|
|
|
30
30
|
if(key === undefined) {
|
|
31
31
|
return this.all();
|
|
32
32
|
}
|
|
33
|
-
return this.ctx.cookies.get(key, options);
|
|
33
|
+
return this.ctx.cookies.get(key, {signed: cfg_cookie.signed, ...options});
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* 删除或清理cookie
|
|
38
38
|
* @public
|
|
39
39
|
* @param {*} [key] - 为空则清理所有cookie
|
|
40
|
+
* @param {import('cookies').GetOption} [options]
|
|
40
41
|
* @returns {this}
|
|
41
42
|
*/
|
|
42
|
-
delete(key) {
|
|
43
|
+
delete(key, options) {
|
|
43
44
|
if(key === undefined) {
|
|
44
45
|
this.clear();
|
|
45
46
|
} else {
|
|
46
|
-
this.ctx.cookies.set(key, '', {maxAge: 0});
|
|
47
|
+
this.ctx.cookies.set(key, '', {...cfg_cookie, ...options, maxAge: 0});
|
|
47
48
|
}
|
|
48
49
|
return this;
|
|
49
50
|
}
|
package/lib/ctx.js
CHANGED
|
@@ -42,8 +42,8 @@ const Ctx = new Proxy(class {}, {
|
|
|
42
42
|
} else {
|
|
43
43
|
_[APP][$prop] = null;
|
|
44
44
|
}
|
|
45
|
-
// lib
|
|
46
|
-
if(['logger', 'pagination', 'response', 'url', 'view'].includes(prop) && _[APP][$prop] && _[APP][$prop].__node && !_[APP][$prop].__node.isClass && $[prop]) {
|
|
45
|
+
// lib内有调用,防止覆盖
|
|
46
|
+
if(['logger', 'pagination', 'request', 'response', 'url', 'view'].includes(prop) && _[APP][$prop] && _[APP][$prop].__node && !_[APP][$prop].__node.isClass && $[prop]) {
|
|
47
47
|
_[APP][$prop] = $[prop];
|
|
48
48
|
}
|
|
49
49
|
}
|
package/lib/loader.js
CHANGED
|
@@ -43,8 +43,8 @@ function loader(dir='./', ...args) {
|
|
|
43
43
|
nodeType[_nodePath] = 'file';
|
|
44
44
|
} else if(isDirSync(_nodePath)) {
|
|
45
45
|
nodeType[_nodePath] = 'dir';
|
|
46
|
-
} else{
|
|
47
|
-
nodeType[_nodePath] = 'none';
|
|
46
|
+
} else {
|
|
47
|
+
// nodeType[_nodePath] = 'none';
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
if(nodeType[_nodePath] == 'file') {
|
package/lib/request.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
const Context = require('./context');
|
|
2
|
+
|
|
3
|
+
class Request extends Context
|
|
4
|
+
{
|
|
5
|
+
/**
|
|
6
|
+
* Initialize a new `Request`
|
|
7
|
+
* @public
|
|
8
|
+
* @param {import('../types').KoaCtx} ctx
|
|
9
|
+
*/
|
|
10
|
+
constructor(ctx) {
|
|
11
|
+
super(ctx);
|
|
12
|
+
/**
|
|
13
|
+
* @type {import('querystring').ParsedUrlQuery}
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
this._get = {...this.ctx.query};
|
|
17
|
+
/**
|
|
18
|
+
* @private
|
|
19
|
+
*/
|
|
20
|
+
this._post = {...this.ctx.request.body};
|
|
21
|
+
/**
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
this._param = {...this.ctx.params};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 智能获取请求数据
|
|
29
|
+
* @param {string} key
|
|
30
|
+
* @param {*} [default_value='']
|
|
31
|
+
* @returns {*}
|
|
32
|
+
*/
|
|
33
|
+
query(key, default_value='') {
|
|
34
|
+
return this.post(key) || this.get(key) || this.param(key) || default_value;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 获取param请求数据
|
|
39
|
+
* @param {string} key
|
|
40
|
+
* @param {*} default_value
|
|
41
|
+
* @returns {*}
|
|
42
|
+
*/
|
|
43
|
+
param(key, default_value='') {
|
|
44
|
+
return this._param[key] || default_value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 获取get请求数据
|
|
49
|
+
* @param {string} key
|
|
50
|
+
* @param {*} default_value
|
|
51
|
+
* @returns {*}
|
|
52
|
+
*/
|
|
53
|
+
get(key, default_value='') {
|
|
54
|
+
return Array.isArray(this._get[key]) ? this._get[key][0] : this._get[key] || default_value;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 获取post请求数据
|
|
59
|
+
* @param {string} key
|
|
60
|
+
* @param {*} default_value
|
|
61
|
+
* @returns {*}
|
|
62
|
+
*/
|
|
63
|
+
post(key, default_value='') {
|
|
64
|
+
return this._post[key] || default_value;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 获取所有请求数据
|
|
70
|
+
* @returns {Object}
|
|
71
|
+
*/
|
|
72
|
+
queryAll() {
|
|
73
|
+
return {...this._param, ...this._get, ...this._post};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 获取所有param数据
|
|
78
|
+
* @returns {Object}
|
|
79
|
+
*/
|
|
80
|
+
paramAll() {
|
|
81
|
+
return this._param;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 获取所有get数据
|
|
86
|
+
* @returns {Object}
|
|
87
|
+
*/
|
|
88
|
+
getAll() {
|
|
89
|
+
return this._get;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 获取所有post数据
|
|
94
|
+
* @returns {Object}
|
|
95
|
+
*/
|
|
96
|
+
postAll() {
|
|
97
|
+
return this._post;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 获取上传file数据
|
|
102
|
+
* @param {string} key
|
|
103
|
+
* @returns {import('formidable').File | import('formidable').File[]}
|
|
104
|
+
*/
|
|
105
|
+
file(key) {
|
|
106
|
+
return this.ctx.request.files[key];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 获取上传file数据
|
|
111
|
+
* @returns {import('formidable').Files}
|
|
112
|
+
*/
|
|
113
|
+
fileAll() {
|
|
114
|
+
return this.ctx.request.files;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 获取请求应用名
|
|
119
|
+
* @returns {string}
|
|
120
|
+
*/
|
|
121
|
+
app() {
|
|
122
|
+
return this.ctx.APP;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 获取请求控制器名
|
|
127
|
+
* @returns {string}
|
|
128
|
+
*/
|
|
129
|
+
controller() {
|
|
130
|
+
return this.ctx.CONTROLLER;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 获取请求方法名
|
|
135
|
+
* @returns {string}
|
|
136
|
+
*/
|
|
137
|
+
action() {
|
|
138
|
+
return this.ctx.ACTION;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* 获取请求url
|
|
143
|
+
* @returns {string}
|
|
144
|
+
*/
|
|
145
|
+
url() {
|
|
146
|
+
return this.ctx.url;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* 获取请求方式
|
|
151
|
+
* @returns {string}
|
|
152
|
+
*/
|
|
153
|
+
method() {
|
|
154
|
+
return this.ctx.method.toLowerCase();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* 判断是否get请求
|
|
159
|
+
* @returns {boolean}
|
|
160
|
+
*/
|
|
161
|
+
isGet() {
|
|
162
|
+
return this.method() == 'get';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* 判断是否post请求
|
|
167
|
+
* @returns {boolean}
|
|
168
|
+
*/
|
|
169
|
+
isPost() {
|
|
170
|
+
return this.method() == 'post';
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 判断是否ajax请求
|
|
175
|
+
* @public
|
|
176
|
+
* @returns {boolean}
|
|
177
|
+
*/
|
|
178
|
+
isAjax() {
|
|
179
|
+
return this.ctx.headers['x-requested-with'] && String(this.ctx.headers['x-requested-with']).toLowerCase() == 'xmlhttprequest'
|
|
180
|
+
|| this.ctx.request.type.toLowerCase() == 'application/json'
|
|
181
|
+
|| this.query('is_ajax')
|
|
182
|
+
? true : false;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* 获取header请求数据
|
|
187
|
+
* @param {string} key
|
|
188
|
+
* @param {*} default_value
|
|
189
|
+
* @returns {*}
|
|
190
|
+
*/
|
|
191
|
+
header(key, default_value='') {
|
|
192
|
+
return this.ctx.headers[key] || default_value;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* 获取所有header请求数据
|
|
197
|
+
* @returns {Object}
|
|
198
|
+
*/
|
|
199
|
+
headerAll() {
|
|
200
|
+
return this.ctx.headers;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
module.exports = Request;
|
package/lib/response.js
CHANGED
|
@@ -72,7 +72,7 @@ class Response extends Context
|
|
|
72
72
|
*/
|
|
73
73
|
jump(msg, url, state=1) {
|
|
74
74
|
const tplData = {state, msg, url, wait: this._wait};
|
|
75
|
-
this.ctx.body = this.isAjax() ? {state, msg, data: url} : this._tpl_jump.replace(/\{\$(\w+)\}/g, (...args) => {
|
|
75
|
+
this.ctx.body = this.$request.isAjax() ? {state, msg, data: url} : this._tpl_jump.replace(/\{\$(\w+)\}/g, (...args) => {
|
|
76
76
|
return tplData[args[1]];
|
|
77
77
|
});
|
|
78
78
|
}
|
|
@@ -99,23 +99,10 @@ class Response extends Context
|
|
|
99
99
|
tplData.msg = escapeHtml(tplData.msg);
|
|
100
100
|
tplData.code = '<span class="line">' + tplData.code.map(str => escapeHtml(str)).join('</span><span class="line">') + '</span>';
|
|
101
101
|
tplData.stack = tplData.stack.map(str => escapeHtml(str)).join('<br>');
|
|
102
|
-
this.ctx.body = this.isAjax() ? {state: 0, msg: tplData.msg} : this._tpl_exception.replace(/\{\$(\w+)\}/g, (...args) => {
|
|
102
|
+
this.ctx.body = this.$request.isAjax() ? {state: 0, msg: tplData.msg} : this._tpl_exception.replace(/\{\$(\w+)\}/g, (...args) => {
|
|
103
103
|
return tplData[args[1]];
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* 判断是否ajax请求
|
|
109
|
-
* @public
|
|
110
|
-
* @returns {boolean}
|
|
111
|
-
*/
|
|
112
|
-
isAjax() {
|
|
113
|
-
return this.ctx.headers['x-requested-with'] && String(this.ctx.headers['x-requested-with']).toLowerCase() == 'xmlhttprequest'
|
|
114
|
-
|| this.ctx.request.type.toLowerCase() == 'application/json'
|
|
115
|
-
|| this.ctx.query.is_ajax
|
|
116
|
-
|| this.ctx.request.body && this.ctx.request.body.is_ajax
|
|
117
|
-
? true : false;
|
|
118
|
-
}
|
|
119
106
|
}
|
|
120
107
|
|
|
121
108
|
module.exports = Response;
|
package/lib/run.js
CHANGED
|
@@ -10,7 +10,6 @@ const storage = require('./storage');
|
|
|
10
10
|
|
|
11
11
|
async function run(ctx, next, control_type=cfg_app.controller_folder) {
|
|
12
12
|
if(cfg_app.app_debug) {
|
|
13
|
-
Logger.http('Request:', ctx.request);
|
|
14
13
|
Logger.http({Router: control_type, APP: ctx.APP, CONTROLLER: ctx.CONTROLLER, ACTION: ctx.ACTION});
|
|
15
14
|
Object.keys(ctx.params).length && Logger.http('Params:', ctx.params);
|
|
16
15
|
Object.keys(ctx.query).length && Logger.http('Get:', ctx.query);
|
package/lib/types.js
CHANGED
|
@@ -21,6 +21,7 @@ function start() {
|
|
|
21
21
|
Object.keys(f).forEach(file => {
|
|
22
22
|
Logger.system("wacth:", file);
|
|
23
23
|
});
|
|
24
|
+
createFile();
|
|
24
25
|
} else if(prev === null) {
|
|
25
26
|
// f is a new file
|
|
26
27
|
if(prevFile.file != f || prevFile.action != "created") {
|
|
@@ -55,18 +56,23 @@ function start() {
|
|
|
55
56
|
* createTypesFile
|
|
56
57
|
*/
|
|
57
58
|
async function createFile(f) {
|
|
58
|
-
if(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
59
|
+
if(f) {
|
|
60
|
+
require.cache[f] && delete(require.cache[f])
|
|
61
|
+
if(f == this._f) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
this._f && require.cache[this._f] && delete(require.cache[this._f]);
|
|
66
|
+
this._f = f;
|
|
67
|
+
|
|
68
|
+
const f_info = f.replace(cfg_app.base_dir + path.sep, '').split(path.sep);
|
|
69
|
+
if(cfg_app.app_multi && f_info[0] && f_info[1] && f_info[0] != cfg_app.common_app && f_info[0] != 'config' && !~f_info[0].indexOf('.')) {
|
|
70
|
+
this._APP = f_info[0];
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
this._APP = cfg_app.default_app;
|
|
69
74
|
}
|
|
75
|
+
|
|
70
76
|
|
|
71
77
|
const ignore = ['node_modules', 'docker', 'package-lock.json', 'types.js', '.git', '.gitignore'];
|
|
72
78
|
ignore.push(path.basename(module.parent.parent.parent.filename));
|
package/lib/url.js
CHANGED
|
@@ -18,19 +18,28 @@ class Url extends Context
|
|
|
18
18
|
* 编译生成url
|
|
19
19
|
* @public
|
|
20
20
|
* @param {string} [url] - 网址,支持智能解析
|
|
21
|
-
* @param {object} [vars] - 网址参数
|
|
22
|
-
* @param {string} [ext] - 网址后缀
|
|
23
|
-
* @param {string} [domain] - 网址域名
|
|
21
|
+
* @param {object|string|boolean} [vars] - 网址参数
|
|
22
|
+
* @param {string|boolean} [ext] - 网址后缀
|
|
23
|
+
* @param {string|boolean} [domain] - 网址域名
|
|
24
24
|
* @returns {string}
|
|
25
|
+
* @example - build(url, vars, ext, domain|true)
|
|
26
|
+
* @example - build(url, ext, domain|true)
|
|
27
|
+
* @example - build(url, domain|true)
|
|
25
28
|
*/
|
|
26
|
-
build(url='', vars, ext='', domain='') {
|
|
27
|
-
if(
|
|
29
|
+
build(url='', vars={}, ext='', domain='') {
|
|
30
|
+
if(typeof vars != 'object') {
|
|
28
31
|
[vars, ext, domain] = [{}, vars, ext];
|
|
29
32
|
}
|
|
33
|
+
if(ext === true || ext.slice(0, 4) == 'http') {
|
|
34
|
+
[ext, domain] = ['', ext];
|
|
35
|
+
}
|
|
36
|
+
if(domain === true) {
|
|
37
|
+
domain = this.ctx.protocol + '://' + this.ctx.host;
|
|
38
|
+
}
|
|
30
39
|
const query = {...vars};
|
|
31
40
|
let urls;
|
|
32
41
|
if(url.slice(0, 1) == ':') {
|
|
33
|
-
url = this.ruleUrl(url.
|
|
42
|
+
url = this.ruleUrl(url.slice(0, 1), query);
|
|
34
43
|
} else if(url.slice(0, 1) != '/' && url.slice(0, 4) != 'http') {
|
|
35
44
|
urls = url.split('/').reverse().map(u => toLine(u));
|
|
36
45
|
if(urls.length < 3) {
|
package/package.json
CHANGED
package/types.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* @typedef {typeof import('./lib/middleware')} Middleware
|
|
11
11
|
* @typedef {typeof import('./lib/model')} Model
|
|
12
12
|
* @typedef {typeof import('./lib/pagination')} Pagination
|
|
13
|
+
* @typedef {typeof import('./lib/request')} Request
|
|
13
14
|
* @typedef {typeof import('./lib/response')} Response
|
|
14
15
|
* @typedef {typeof import('./lib/storage')} Storage
|
|
15
16
|
* @typedef {typeof import('./lib/upload')} Upload
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
* @typedef {typeof import('./lib/middleware').prototype} MiddlewareInstance
|
|
27
28
|
* @typedef {typeof import('./lib/model').prototype} ModelInstance
|
|
28
29
|
* @typedef {typeof import('./lib/pagination').prototype} PaginationInstance
|
|
30
|
+
* @typedef {typeof import('./lib/request').prototype} RequestInstance
|
|
29
31
|
* @typedef {typeof import('./lib/response').prototype} ResponseInstance
|
|
30
32
|
* @typedef {typeof import('./lib/upload').prototype} UploadInstance
|
|
31
33
|
* @typedef {typeof import('./lib/url').prototype} UrlInstance
|
|
@@ -45,6 +47,7 @@
|
|
|
45
47
|
* @property {Middleware} Middleware
|
|
46
48
|
* @property {Model} Model
|
|
47
49
|
* @property {Pagination} Pagination
|
|
50
|
+
* @property {Request} Request
|
|
48
51
|
* @property {Response} Response
|
|
49
52
|
* @property {Upload} Upload
|
|
50
53
|
* @property {Url} Url
|
|
@@ -67,6 +70,7 @@
|
|
|
67
70
|
* @property {MiddlewareInstance} middleware
|
|
68
71
|
* @property {ModelInstance} model
|
|
69
72
|
* @property {PaginationInstance} pagination
|
|
73
|
+
* @property {RequestInstance} request
|
|
70
74
|
* @property {ResponseInstance} response
|
|
71
75
|
* @property {UploadInstance} upload
|
|
72
76
|
* @property {UrlInstance} url
|
|
@@ -86,7 +90,7 @@
|
|
|
86
90
|
* @property {string} [common_app=common] - 公共应用,存放公共模型及逻辑
|
|
87
91
|
* @property {string} [controller_folder=controller] - 控制器目录名
|
|
88
92
|
* @property {string} [static_dir=''] - 静态文件目录,相对于应用根目录,为空时,关闭静态访问
|
|
89
|
-
* @property {
|
|
93
|
+
* @property {import('koa-body').IKoaBodyOptions} [koa_body=null] - koa-body配置参数,为null或空时,关闭koa-body
|
|
90
94
|
* @property {string} [base_dir] - 应用根目录(会自动计算)
|
|
91
95
|
*/
|
|
92
96
|
|
|
@@ -96,7 +100,7 @@
|
|
|
96
100
|
* @property {string} [view_depr='/'] - 模版文件名分割符,'/'代表二级目录
|
|
97
101
|
* @property {string} [view_ext='.htm'] - 模版文件后缀
|
|
98
102
|
* @property {string} [view_engine=art-template] - 默认模版引擎,字符串或引擎类
|
|
99
|
-
* @property {
|
|
103
|
+
* @property {Object} [view_filte={}] - 模版函数
|
|
100
104
|
*/
|
|
101
105
|
|
|
102
106
|
/**
|
|
@@ -112,7 +116,7 @@
|
|
|
112
116
|
*/
|
|
113
117
|
|
|
114
118
|
/**
|
|
115
|
-
* @typedef {
|
|
119
|
+
* @typedef {Object.<string, Object>} DbConfig - 数据库配置
|
|
116
120
|
* @property {DbConfigItem} default - 数据库参数
|
|
117
121
|
*/
|
|
118
122
|
|
|
@@ -123,7 +127,7 @@
|
|
|
123
127
|
*/
|
|
124
128
|
|
|
125
129
|
/**
|
|
126
|
-
* @typedef {
|
|
130
|
+
* @typedef {Object} LogConfig - 日志配置
|
|
127
131
|
* @property {array} [log_level] - 允许输出的日志级别
|
|
128
132
|
* @property {LogHandle} [log_handle] - 日志驱动
|
|
129
133
|
*/
|
|
@@ -167,6 +171,7 @@
|
|
|
167
171
|
|
|
168
172
|
/**
|
|
169
173
|
* @typedef {import('cookies').SetOption} CookieConfig - Cookie配置,一般不用设置
|
|
174
|
+
* @typedef {typeof import('koa').prototype.keys} Keygrip
|
|
170
175
|
*/
|
|
171
176
|
|
|
172
177
|
/**
|
|
@@ -184,7 +189,7 @@
|
|
|
184
189
|
* @property {CacheConfig} [cache]
|
|
185
190
|
* @property {PageConfig} [page]
|
|
186
191
|
* @property {RouteConfig} [routes]
|
|
187
|
-
* @property {CookieConfig} [cookie]
|
|
192
|
+
* @property {CookieConfig & {keys?: String[] | Keygrip | undefined}} [cookie]
|
|
188
193
|
* @property {TplConfig} [tpl]
|
|
189
194
|
*/
|
|
190
195
|
|
|
@@ -283,6 +288,9 @@ class Ctx {
|
|
|
283
288
|
/** @type {(Pagination & PaginationInstance)} */
|
|
284
289
|
$pagination;
|
|
285
290
|
|
|
291
|
+
/** @type {(Request & RequestInstance)} */
|
|
292
|
+
$request;
|
|
293
|
+
|
|
286
294
|
/** @type {(Response & ResponseInstance)} */
|
|
287
295
|
$response;
|
|
288
296
|
|