jj.js 0.18.0 → 0.20.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/README.md +243 -173
- package/jj.js +14 -14
- package/lib/app.js +53 -15
- package/lib/cache.js +96 -30
- package/lib/config.js +21 -6
- package/lib/context.js +18 -22
- package/lib/controller.js +36 -5
- package/lib/cookie.js +11 -15
- package/lib/ctx.js +28 -28
- package/lib/db/mongodb.js +564 -0
- package/lib/db/mysql.js +294 -0
- package/lib/db/sql.js +116 -0
- package/lib/db/sqlite.js +292 -0
- package/lib/db.js +261 -331
- package/lib/loader.js +79 -44
- package/lib/logger.js +124 -126
- package/lib/middleware.js +39 -6
- package/lib/model.js +23 -9
- package/lib/{run.js → mvc.js} +29 -22
- package/lib/pagination.js +68 -14
- package/lib/request.js +6 -3
- package/lib/response.js +70 -6
- package/lib/router.js +4 -3
- package/lib/types.js +363 -196
- package/lib/upload.js +15 -15
- package/lib/url.js +10 -2
- package/lib/utils/error.js +9 -5
- package/lib/utils/utils.js +2 -0
- package/lib/utils/validate.js +13 -0
- package/lib/view.js +54 -8
- package/logo.png +0 -0
- package/package.json +10 -3
- package/types.js +181 -84
- package/CHANGELOG.md +0 -53
- package/jsdoc.conf.js +0 -17
package/lib/app.js
CHANGED
|
@@ -1,42 +1,79 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const Koa = require('koa');
|
|
3
3
|
const {app: cfg_app, cookie: cfg_cookie} = require('./config');
|
|
4
|
+
const loader = require('./loader');
|
|
4
5
|
const Logger = require('./logger');
|
|
5
6
|
const Response = require('./response');
|
|
6
7
|
const router = require('./router');
|
|
8
|
+
const mvc = require('./mvc');
|
|
7
9
|
const storage = require('./storage');
|
|
8
10
|
const pjson = require('../package.json');
|
|
9
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {import('../types').AppOptions} AppOptions
|
|
14
|
+
* @typedef {import('../types').KoaMiddleware} KoaMiddleware
|
|
15
|
+
*/
|
|
16
|
+
|
|
10
17
|
/**
|
|
11
18
|
* @extends Koa
|
|
12
19
|
*/
|
|
13
20
|
class App extends Koa
|
|
14
21
|
{
|
|
15
22
|
/**
|
|
16
|
-
* @
|
|
17
|
-
* @param {...any} args - listen(port, ip, callback(err){})
|
|
23
|
+
* @param {AppOptions|KoaMiddleware|KoaMiddleware[]} [options] Application options
|
|
18
24
|
*/
|
|
19
|
-
|
|
25
|
+
constructor(options) {
|
|
26
|
+
if(typeof options == 'function') {
|
|
27
|
+
options = {
|
|
28
|
+
middleware: [options]
|
|
29
|
+
};
|
|
30
|
+
} else if(Array.isArray(options)) {
|
|
31
|
+
options = {
|
|
32
|
+
middleware: options
|
|
33
|
+
};
|
|
34
|
+
} else if(options && options.middleware && !Array.isArray(options.middleware)) {
|
|
35
|
+
options.middleware = [options.middleware]
|
|
36
|
+
}
|
|
37
|
+
super(options);
|
|
38
|
+
this._init(options);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {AppOptions} [options] - Application options
|
|
43
|
+
*/
|
|
44
|
+
_init(options) {
|
|
20
45
|
// storage
|
|
21
46
|
this.use(async (ctx, next) => {
|
|
22
|
-
|
|
47
|
+
ctx.APP_TIME = Date.now();
|
|
48
|
+
ctx.APP_VERSION = pjson.version;
|
|
49
|
+
await storage.run({
|
|
50
|
+
$: loader(__dirname, ctx),
|
|
51
|
+
_: loader(cfg_app.base_dir, ctx)
|
|
52
|
+
}, async() => {
|
|
23
53
|
await next();
|
|
24
54
|
});
|
|
25
55
|
});
|
|
26
56
|
|
|
57
|
+
// options.middleware
|
|
58
|
+
options && Array.isArray(options.middleware) && options.middleware.forEach(middleware => {
|
|
59
|
+
this.use(middleware);
|
|
60
|
+
});
|
|
61
|
+
|
|
27
62
|
// exception
|
|
28
63
|
this.use(async (ctx, next) => {
|
|
29
|
-
ctx.APP_TIME = Date.now();
|
|
30
|
-
ctx.APP_VERSION = pjson.version;
|
|
31
|
-
|
|
32
64
|
try {
|
|
33
65
|
await next();
|
|
34
66
|
} catch (err) {
|
|
35
|
-
|
|
67
|
+
const errorMessage = err instanceof Error ? (err.stack || '') : String(err);
|
|
68
|
+
errorMessage.split("\n").forEach(line => {
|
|
69
|
+
Logger.error(line);
|
|
70
|
+
});
|
|
36
71
|
if(cfg_app.app_debug) {
|
|
37
|
-
new Response(ctx).exception(err);
|
|
72
|
+
new Response(ctx).exception(err instanceof Error ? err : new Error(errorMessage));
|
|
38
73
|
} else {
|
|
39
|
-
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
const errorStatus = typeof err === 'object' && err && (err.statusCode || err.status) || 500;
|
|
76
|
+
ctx.response.status = errorStatus;
|
|
40
77
|
ctx.body = 'Internal Server Error';
|
|
41
78
|
}
|
|
42
79
|
}
|
|
@@ -54,18 +91,19 @@ class App extends Koa
|
|
|
54
91
|
// router
|
|
55
92
|
this.use(router.routes()).use(router.allowedMethods());
|
|
56
93
|
|
|
94
|
+
// mvc
|
|
95
|
+
this.use(mvc);
|
|
96
|
+
|
|
57
97
|
// cookie
|
|
58
98
|
cfg_cookie.keys && (this.keys = cfg_app.app_debug ? ['jj.js'] : cfg_cookie.keys);
|
|
59
99
|
|
|
60
|
-
// types
|
|
100
|
+
// create types
|
|
61
101
|
if(cfg_app.app_debug) {
|
|
62
102
|
const {isFileSync} = require('./utils/fs');
|
|
63
103
|
const jsconfigFile = path.join(cfg_app.base_dir, 'jsconfig.json');
|
|
64
|
-
isFileSync(jsconfigFile)
|
|
104
|
+
if(!isFileSync(jsconfigFile)) Logger.warning('jsconfig.json not found!');
|
|
105
|
+
require('./types').watch();
|
|
65
106
|
}
|
|
66
|
-
|
|
67
|
-
// server
|
|
68
|
-
return super.listen(...args);
|
|
69
107
|
}
|
|
70
108
|
}
|
|
71
109
|
|
package/lib/cache.js
CHANGED
|
@@ -2,22 +2,35 @@ const {cache: cfg_cache} = require('./config');
|
|
|
2
2
|
|
|
3
3
|
class Cache
|
|
4
4
|
{
|
|
5
|
+
static cache = new Map();
|
|
6
|
+
static timer = null;
|
|
7
|
+
|
|
5
8
|
/**
|
|
6
9
|
* Creat a new `Cache` class
|
|
7
10
|
* @public
|
|
11
|
+
* @param {Map.<any, any>} [store] - 缓存存储实例
|
|
8
12
|
*/
|
|
9
|
-
constructor() {
|
|
13
|
+
constructor(store) {
|
|
10
14
|
if(new.target) {
|
|
11
15
|
// @ts-ignore
|
|
12
|
-
class ChildCache extends this.constructor {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
|
|
16
|
+
class ChildCache extends this.constructor {
|
|
17
|
+
static cache = store || Cache.cache;
|
|
18
|
+
}
|
|
19
|
+
// 只有独立 cache 时才声明独立的 timer
|
|
20
|
+
if(store) {
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
ChildCache.timer = null;
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
ChildCache.setIntervalTime(cfg_cache.clear_time);
|
|
25
|
+
}
|
|
17
26
|
return ChildCache;
|
|
18
27
|
}
|
|
19
28
|
}
|
|
20
29
|
|
|
30
|
+
static {
|
|
31
|
+
this.setIntervalTime(cfg_cache.clear_time);
|
|
32
|
+
}
|
|
33
|
+
|
|
21
34
|
/**
|
|
22
35
|
* 获取缓存
|
|
23
36
|
* @public
|
|
@@ -29,9 +42,9 @@ class Cache
|
|
|
29
42
|
if(key === undefined) {
|
|
30
43
|
return this.cache;
|
|
31
44
|
}
|
|
32
|
-
const
|
|
33
|
-
if(
|
|
34
|
-
return
|
|
45
|
+
const item = this.cache.get(key);
|
|
46
|
+
if(item && item.time > this.time()) {
|
|
47
|
+
return item.data;
|
|
35
48
|
} else {
|
|
36
49
|
this.delete(key);
|
|
37
50
|
return undefined;
|
|
@@ -48,8 +61,7 @@ class Cache
|
|
|
48
61
|
*/
|
|
49
62
|
static set(key, data, cache_time) {
|
|
50
63
|
cache_time || (cache_time = cfg_cache.cache_time || 60 * 60 * 24 * 365 * 10);
|
|
51
|
-
|
|
52
|
-
this.cache[key] = {data: data, time: cache_time + now_time};
|
|
64
|
+
this.cache.set(key, {data: data, time: cache_time + this.time()});
|
|
53
65
|
}
|
|
54
66
|
|
|
55
67
|
/**
|
|
@@ -60,11 +72,69 @@ class Cache
|
|
|
60
72
|
*/
|
|
61
73
|
static delete(key) {
|
|
62
74
|
if(key) {
|
|
63
|
-
|
|
75
|
+
this.cache.delete(key);
|
|
64
76
|
} else {
|
|
65
77
|
// @ts-ignore
|
|
66
|
-
this.cache =
|
|
78
|
+
this.cache = new Map();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 检查缓存是否存在
|
|
84
|
+
* @public
|
|
85
|
+
* @static
|
|
86
|
+
* @param {string} key - 缓存键
|
|
87
|
+
* @returns {boolean}
|
|
88
|
+
*/
|
|
89
|
+
static has(key) {
|
|
90
|
+
const item = this.cache.get(key);
|
|
91
|
+
if(item && item.time > this.time()) {
|
|
92
|
+
return true;
|
|
93
|
+
} else if(item) {
|
|
94
|
+
// 已过期,删除
|
|
95
|
+
this.delete(key);
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 获取有效缓存数量(过滤已过期)
|
|
102
|
+
* @public
|
|
103
|
+
* @static
|
|
104
|
+
* @returns {number}
|
|
105
|
+
*/
|
|
106
|
+
static size() {
|
|
107
|
+
let count = 0;
|
|
108
|
+
const now_time = this.time();
|
|
109
|
+
for(let [key, item] of this.cache) {
|
|
110
|
+
if(item.time > now_time) {
|
|
111
|
+
count++;
|
|
112
|
+
} else {
|
|
113
|
+
// 自动清理过期缓存
|
|
114
|
+
this.delete(key);
|
|
115
|
+
}
|
|
67
116
|
}
|
|
117
|
+
return count;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 获取所有有效缓存的键(过滤已过期)
|
|
122
|
+
* @public
|
|
123
|
+
* @static
|
|
124
|
+
* @returns {string[]}
|
|
125
|
+
*/
|
|
126
|
+
static keys() {
|
|
127
|
+
const keys = [];
|
|
128
|
+
const now_time = this.time();
|
|
129
|
+
for(let [key, item] of this.cache) {
|
|
130
|
+
if(item.time > now_time) {
|
|
131
|
+
keys.push(key);
|
|
132
|
+
} else {
|
|
133
|
+
// 自动清理过期缓存
|
|
134
|
+
this.delete(key);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return keys;
|
|
68
138
|
}
|
|
69
139
|
|
|
70
140
|
/**
|
|
@@ -79,8 +149,8 @@ class Cache
|
|
|
79
149
|
// @ts-ignore
|
|
80
150
|
this.timer = setInterval(() => {
|
|
81
151
|
const now_time = this.time();
|
|
82
|
-
for(let key
|
|
83
|
-
|
|
152
|
+
for(let [key, item] of this.cache) {
|
|
153
|
+
item.time < now_time && this.delete(key);
|
|
84
154
|
}
|
|
85
155
|
}, time * 1000);
|
|
86
156
|
} else {
|
|
@@ -90,6 +160,17 @@ class Cache
|
|
|
90
160
|
}
|
|
91
161
|
}
|
|
92
162
|
|
|
163
|
+
/**
|
|
164
|
+
* 设置缓存存储实例
|
|
165
|
+
* @public
|
|
166
|
+
* @static
|
|
167
|
+
* @param {Map.<any, any>} [store] - 缓存存储实例
|
|
168
|
+
*/
|
|
169
|
+
static setStore(store) {
|
|
170
|
+
this.cache = store || new Map();
|
|
171
|
+
this.setIntervalTime(cfg_cache.clear_time);
|
|
172
|
+
}
|
|
173
|
+
|
|
93
174
|
/**
|
|
94
175
|
* 获取当前时间戳
|
|
95
176
|
* @public
|
|
@@ -101,19 +182,4 @@ class Cache
|
|
|
101
182
|
}
|
|
102
183
|
}
|
|
103
184
|
|
|
104
|
-
/**
|
|
105
|
-
* 缓存store
|
|
106
|
-
*/
|
|
107
|
-
// @ts-ignore
|
|
108
|
-
Cache.cache = {};
|
|
109
|
-
/**
|
|
110
|
-
* 缓存自动清理定时器
|
|
111
|
-
*/
|
|
112
|
-
// @ts-ignore
|
|
113
|
-
Cache.timer = null;
|
|
114
|
-
/**
|
|
115
|
-
* 开启缓存自动清理
|
|
116
|
-
*/
|
|
117
|
-
Cache.setIntervalTime(cfg_cache.clear_time);
|
|
118
|
-
|
|
119
185
|
module.exports = Cache;
|
package/lib/config.js
CHANGED
|
@@ -3,7 +3,7 @@ const loader = require('./loader');
|
|
|
3
3
|
const {format} = require('./utils/date');
|
|
4
4
|
|
|
5
5
|
const app = {
|
|
6
|
-
app_debug:
|
|
6
|
+
app_debug: false, // 调试模式
|
|
7
7
|
app_multi: false, // 是否开启多应用
|
|
8
8
|
|
|
9
9
|
default_app: 'app', // 默认应用
|
|
@@ -34,19 +34,34 @@ const db = {
|
|
|
34
34
|
user : 'root', // 数据库用户名
|
|
35
35
|
password : '', // 数据库密码
|
|
36
36
|
port : '', // 数据库连接端口
|
|
37
|
-
charset : '
|
|
37
|
+
charset : 'utf8mb4', // 数据库编码默认采用utf8mb4
|
|
38
38
|
prefix : 'jj_' // 数据库表前缀
|
|
39
|
-
}
|
|
39
|
+
},
|
|
40
|
+
sqlite: {
|
|
41
|
+
type : 'sqlite', // 数据库类型
|
|
42
|
+
database : ':memory:', // 数据库文件绝对地址,支持:memory:内存数据库
|
|
43
|
+
prefix : 'jj_' // 数据库表前缀
|
|
44
|
+
},
|
|
45
|
+
mongodb: {
|
|
46
|
+
type : 'mongodb', // 数据库类型
|
|
47
|
+
host : '127.0.0.1', // 服务器地址
|
|
48
|
+
database : 'jj', // 数据库名
|
|
49
|
+
user : 'root', // 数据库用户名
|
|
50
|
+
password : '', // 数据库密码
|
|
51
|
+
port : 27017, // 数据库连接端口
|
|
52
|
+
prefix : 'jj_' // 数据库表前缀
|
|
53
|
+
},
|
|
40
54
|
}
|
|
41
55
|
|
|
42
56
|
const log = {
|
|
43
57
|
log_level: ['system', 'error'], // [system, error, warning, info, debug, http, sql]
|
|
58
|
+
// @ts-ignore
|
|
44
59
|
log_handle: function(level, ...args) {console.log(`[${format('YY-mm-dd HH:ii:ss')}] [${level}]`, ...args.map(msg => typeof msg == 'object' ? JSON.stringify(msg) : String(msg)));}
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
const cache = {
|
|
48
63
|
cache_time: 60 * 60 * 24, // 默认缓存时间(1天),为空或false则为10年
|
|
49
|
-
clear_time: undefined // (undefined: 清理一次, 0: 关闭自动清理, >0: 为自动清理周期
|
|
64
|
+
clear_time: undefined // (undefined: 清理一次, 0: 关闭自动清理, >0: 为自动清理周期
|
|
50
65
|
}
|
|
51
66
|
|
|
52
67
|
const cookie = {
|
|
@@ -83,8 +98,8 @@ const tpl = {
|
|
|
83
98
|
jump: require('./tpl/jump'),
|
|
84
99
|
exception: require('./tpl/exception')
|
|
85
100
|
}
|
|
86
|
-
|
|
87
|
-
const base_dir =
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
const base_dir = require.main.path;
|
|
88
103
|
const base_config = loader(path.join(base_dir, './config'));
|
|
89
104
|
|
|
90
105
|
/**
|
package/lib/context.js
CHANGED
|
@@ -1,23 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
{
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
this.ctx = ctx;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
1
|
+
const Ctx = require('./ctx');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @extends Ctx
|
|
5
|
+
*/
|
|
6
|
+
class Context extends Ctx
|
|
7
|
+
{
|
|
8
|
+
/**
|
|
9
|
+
* Initialize a new `Context`
|
|
10
|
+
* @public
|
|
11
|
+
* @param {import('../types').KoaCtx} ctx
|
|
12
|
+
*/
|
|
13
|
+
constructor(ctx) {
|
|
14
|
+
super();
|
|
15
|
+
this.ctx = ctx;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
23
19
|
module.exports = Context;
|
package/lib/controller.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const Middleware = require('./middleware');
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('../types').ViewInstance} ViewInstance
|
|
5
|
+
*/
|
|
6
|
+
|
|
3
7
|
/**
|
|
4
8
|
* @extends Middleware
|
|
5
9
|
*/
|
|
@@ -13,7 +17,7 @@ class Controller extends Middleware
|
|
|
13
17
|
* @returns {this}
|
|
14
18
|
*/
|
|
15
19
|
$assign(name, value) {
|
|
16
|
-
this
|
|
20
|
+
this._$view.assign(name, value);
|
|
17
21
|
return this;
|
|
18
22
|
}
|
|
19
23
|
|
|
@@ -24,7 +28,7 @@ class Controller extends Middleware
|
|
|
24
28
|
* @returns {object}
|
|
25
29
|
*/
|
|
26
30
|
$data(name) {
|
|
27
|
-
return this
|
|
31
|
+
return this._$view.data(name);
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
/**
|
|
@@ -33,7 +37,7 @@ class Controller extends Middleware
|
|
|
33
37
|
* @param {string} [template]
|
|
34
38
|
*/
|
|
35
39
|
async $load(template) {
|
|
36
|
-
const content = await this
|
|
40
|
+
const content = await this._$view.load(template);
|
|
37
41
|
this.$show(content);
|
|
38
42
|
}
|
|
39
43
|
|
|
@@ -43,7 +47,7 @@ class Controller extends Middleware
|
|
|
43
47
|
* @param {string} content
|
|
44
48
|
*/
|
|
45
49
|
async $render(content) {
|
|
46
|
-
const html = await this
|
|
50
|
+
const html = await this._$view.render(content);
|
|
47
51
|
this.$show(html);
|
|
48
52
|
}
|
|
49
53
|
|
|
@@ -53,9 +57,36 @@ class Controller extends Middleware
|
|
|
53
57
|
* @param {string} [template]
|
|
54
58
|
*/
|
|
55
59
|
async $fetch(template) {
|
|
56
|
-
const content = await this
|
|
60
|
+
const content = await this._$view.fetch(template);
|
|
57
61
|
this.$show(content);
|
|
58
62
|
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @type {ViewInstance} View实例
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
__view = null;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @type {ViewInstance} View实例
|
|
73
|
+
*/
|
|
74
|
+
get _$view() {
|
|
75
|
+
if(this.__view === null) {
|
|
76
|
+
if(this.$view && this.$view.__ISCLASS__) {
|
|
77
|
+
this.__view = this.$view;
|
|
78
|
+
} else if(this.$ && this.$.view) {
|
|
79
|
+
this.__view = this.$.view;
|
|
80
|
+
} else {
|
|
81
|
+
this.__view = new (require('./view'))(this.ctx);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return this.__view;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
set _$view(view) {
|
|
88
|
+
this.__view = view;
|
|
89
|
+
}
|
|
59
90
|
}
|
|
60
91
|
|
|
61
92
|
module.exports = Controller;
|
package/lib/cookie.js
CHANGED
|
@@ -22,39 +22,35 @@ class Cookie extends Context
|
|
|
22
22
|
/**
|
|
23
23
|
* 获取cookie
|
|
24
24
|
* @public
|
|
25
|
-
* @param {string}
|
|
25
|
+
* @param {string} key - cookie键名
|
|
26
26
|
* @param {import('cookies').GetOption} [options]
|
|
27
|
-
* @returns {
|
|
27
|
+
* @returns {any}
|
|
28
28
|
*/
|
|
29
29
|
get(key, options) {
|
|
30
|
-
|
|
31
|
-
return this.all();
|
|
32
|
-
}
|
|
33
|
-
return this.ctx.cookies.get(key, {signed: cfg_cookie.signed, ...options});
|
|
30
|
+
return this.ctx.cookies.get(key, {signed: cfg_cookie.signed ? true : false, ...options});
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
/**
|
|
37
|
-
*
|
|
34
|
+
* 删除cookie
|
|
38
35
|
* @public
|
|
39
|
-
* @param {
|
|
36
|
+
* @param {string} key - cookie键名
|
|
40
37
|
* @param {import('cookies').GetOption} [options]
|
|
41
38
|
* @returns {this}
|
|
42
39
|
*/
|
|
43
40
|
delete(key, options) {
|
|
44
|
-
|
|
45
|
-
this.clear();
|
|
46
|
-
} else {
|
|
47
|
-
this.ctx.cookies.set(key, '', {...cfg_cookie, ...options, maxAge: 0});
|
|
48
|
-
}
|
|
41
|
+
this.ctx.cookies.set(key, null, {...cfg_cookie, ...options, maxAge: 0});
|
|
49
42
|
return this;
|
|
50
43
|
}
|
|
51
44
|
|
|
52
45
|
/**
|
|
53
46
|
* 获取所有cookie
|
|
54
47
|
* @public
|
|
55
|
-
* @returns {
|
|
48
|
+
* @returns {Object.<string, string>}
|
|
56
49
|
*/
|
|
57
50
|
all() {
|
|
51
|
+
/**
|
|
52
|
+
* @type {Object.<string, string>}
|
|
53
|
+
*/
|
|
58
54
|
const cookies = {};
|
|
59
55
|
this.keys().forEach(key => cookies[key] = this.get(key));
|
|
60
56
|
return cookies;
|
|
@@ -73,7 +69,7 @@ class Cookie extends Context
|
|
|
73
69
|
/**
|
|
74
70
|
* 获取所有cookie key
|
|
75
71
|
* @public
|
|
76
|
-
* @returns {
|
|
72
|
+
* @returns {Array.<string>}
|
|
77
73
|
*/
|
|
78
74
|
keys() {
|
|
79
75
|
const cookie_header = this.ctx.request.headers.cookie || '';
|
package/lib/ctx.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
const storage = require('./storage');
|
|
3
|
+
// 允许$访问的系统类库
|
|
4
|
+
const libs = ['ctx', 'context', 'cache', 'cookie', 'db', 'logger', 'middleware', 'model', 'pagination', 'request', 'response', 'upload', 'url', 'view', 'utils', 'config'];
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
|
-
* 开发jj.js
|
|
7
|
+
* 开发jj.js库本身时,需改为import('../types')
|
|
8
|
+
* type {typeof import('../types')}
|
|
6
9
|
* @type {typeof import('../../../types')}
|
|
7
10
|
*/
|
|
8
|
-
const Ctx = new Proxy(class {}, {
|
|
11
|
+
const Ctx = new Proxy(class Ctx {}, {
|
|
9
12
|
construct() {
|
|
10
13
|
return new Proxy({__proto__: arguments[2].prototype}, {
|
|
11
14
|
get: (target, $prop, receiver) => {
|
|
12
|
-
if($prop in target || typeof $prop == 'symbol' || $prop == 'inspect') {
|
|
15
|
+
if($prop in target || typeof $prop == 'symbol' || $prop == 'inspect' || $prop == 'ctx' || $prop == '$next') {
|
|
13
16
|
return Reflect.get(target, $prop, receiver);
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
const store = storage.getStore();
|
|
17
|
-
const $ = store.$;
|
|
18
|
-
const _ = store._;
|
|
19
20
|
if($prop == '$' || $prop == '_') {
|
|
20
21
|
return store[$prop];
|
|
21
22
|
}
|
|
@@ -23,33 +24,32 @@ const Ctx = new Proxy(class {}, {
|
|
|
23
24
|
return undefined;
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
const {$, _, APP, COMMON} = store;
|
|
26
28
|
const prop = $prop.slice(1);
|
|
27
|
-
const APP = store.APP;
|
|
28
|
-
const COMMON = store.COMMON;
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
} else if(_[APP][prop]) {
|
|
39
|
-
_[APP][$prop] = _[APP][prop];
|
|
40
|
-
} else if(_[COMMON] && _[COMMON][prop]) {
|
|
41
|
-
_[APP][$prop] = _[COMMON][prop];
|
|
42
|
-
} else {
|
|
43
|
-
_[APP][$prop] = null;
|
|
44
|
-
}
|
|
45
|
-
// lib内有调用,防止覆盖
|
|
46
|
-
if(['logger', 'pagination', 'request', 'response', 'url', 'view'].includes(prop) && _[APP][$prop] && _[APP][$prop].__node && !_[APP][$prop].__node.isClass && $[prop]) {
|
|
47
|
-
_[APP][$prop] = $[prop];
|
|
48
|
-
}
|
|
30
|
+
if(!_[APP]) {
|
|
31
|
+
return libs.includes(prop) ? $[prop] : undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if(!_[APP][prop] && !(_[COMMON] && _[COMMON][prop]) && !libs.includes(prop)) {
|
|
35
|
+
return undefined;
|
|
49
36
|
}
|
|
50
37
|
|
|
51
|
-
|
|
52
|
-
|
|
38
|
+
return _[APP][$prop] = new Proxy(function() {}, {
|
|
39
|
+
construct(target, args, newTarget) {
|
|
40
|
+
const node = _[APP][prop] && _[APP][prop].__ISCLASS__ && _[APP][prop]
|
|
41
|
+
|| _[COMMON] && _[COMMON][prop].__ISCLASS__ && _[COMMON][prop]
|
|
42
|
+
|| libs.includes(prop) && $[prop].__ISCLASS__ && $[prop]
|
|
43
|
+
|| undefined;
|
|
44
|
+
return node ? Reflect.construct(node, args, newTarget) : undefined;
|
|
45
|
+
},
|
|
46
|
+
get: (...args) => {
|
|
47
|
+
return res = _[APP][prop] && _[APP][prop][args[1]]
|
|
48
|
+
|| _[COMMON] && _[COMMON][prop][args[1]]
|
|
49
|
+
|| libs.includes(prop) && $[prop][args[1]]
|
|
50
|
+
|| undefined;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
53
|
}
|
|
54
54
|
});
|
|
55
55
|
}
|