@maiyunnet/kebab 2.0.6 → 2.0.8
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/index.d.ts +11 -1
- package/index.js +13 -1
- package/lib/buffer.d.ts +25 -0
- package/lib/buffer.js +30 -5
- package/lib/captcha.d.ts +15 -0
- package/lib/captcha.js +20 -0
- package/lib/consistent.d.ts +51 -0
- package/lib/consistent.js +59 -0
- package/lib/core.d.ts +134 -0
- package/lib/core.js +176 -0
- package/lib/crypto.d.ts +75 -6
- package/lib/crypto.js +206 -38
- package/lib/db.d.ts +104 -0
- package/lib/db.js +126 -0
- package/lib/dns.d.ts +51 -0
- package/lib/dns.js +54 -2
- package/lib/fs.d.ts +100 -0
- package/lib/fs.js +118 -0
- package/lib/jwt.d.ts +43 -0
- package/lib/jwt.js +45 -0
- package/lib/kv.d.ts +362 -0
- package/lib/kv.js +377 -0
- package/lib/lan.d.ts +6 -0
- package/lib/lan.js +7 -0
- package/lib/net/formdata.d.ts +38 -0
- package/lib/net/formdata.js +43 -0
- package/lib/net/request.d.ts +62 -0
- package/lib/net/request.js +57 -0
- package/lib/net/response.d.ts +21 -0
- package/lib/net/response.js +16 -0
- package/lib/net.d.ts +86 -0
- package/lib/net.js +140 -0
- package/lib/s3.d.ts +52 -0
- package/lib/s3.js +51 -0
- package/lib/scan.d.ts +52 -0
- package/lib/scan.js +84 -0
- package/lib/session.d.ts +31 -0
- package/lib/session.js +52 -1
- package/lib/sql.d.ts +176 -0
- package/lib/sql.js +287 -2
- package/lib/ssh/sftp.d.ts +106 -0
- package/lib/ssh/sftp.js +106 -0
- package/lib/ssh/shell.d.ts +37 -0
- package/lib/ssh/shell.js +31 -0
- package/lib/ssh.d.ts +32 -0
- package/lib/ssh.js +32 -0
- package/lib/text.d.ts +131 -0
- package/lib/text.js +188 -0
- package/lib/time.d.ts +53 -0
- package/lib/time.js +55 -0
- package/lib/ws.d.ts +68 -0
- package/lib/ws.js +74 -0
- package/lib/zip.d.ts +53 -0
- package/lib/zip.js +73 -0
- package/lib/zlib.d.ts +76 -0
- package/lib/zlib.js +78 -0
- package/main.d.ts +6 -1
- package/main.js +11 -1
- package/package.json +2 -2
- package/sys/child.js +104 -0
- package/sys/cmd.js +28 -0
- package/sys/ctr.d.ts +166 -0
- package/sys/ctr.js +177 -0
- package/sys/master.js +63 -0
- package/sys/mod.d.ts +266 -0
- package/sys/mod.js +335 -0
- package/sys/route.d.ts +34 -0
- package/sys/route.js +164 -0
- package/www/example/ctr/test.d.ts +3 -0
- package/www/example/ctr/test.js +63 -1
- package/www/example/mod/test.js +14 -0
- package/www/example/mod/testdata.js +9 -0
- package/www/example/ws/test.js +1 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/details.md +0 -82
- package/.VSCodeCounter/2025-02-14_14-46-44/diff-details.md +0 -15
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.csv +0 -2
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.md +0 -19
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.txt +0 -22
- package/.VSCodeCounter/2025-02-14_14-46-44/results.csv +0 -69
- package/.VSCodeCounter/2025-02-14_14-46-44/results.json +0 -1
- package/.VSCodeCounter/2025-02-14_14-46-44/results.md +0 -48
- package/.VSCodeCounter/2025-02-14_14-46-44/results.txt +0 -118
- package/.vscode/tasks.json +0 -15
package/lib/scan.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
4
|
+
* Date: 2022-09-24 15:23:25
|
|
5
|
+
* Last: 2022-09-24 15:23:25, 2022-9-26 12:37:01, 2022-12-29 00:11:16
|
|
6
|
+
*/
|
|
2
7
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
8
|
if (k2 === undefined) k2 = k;
|
|
4
9
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -37,6 +42,20 @@ exports.Scan = void 0;
|
|
|
37
42
|
exports.get = get;
|
|
38
43
|
exports.scanned = scanned;
|
|
39
44
|
exports.setData = setData;
|
|
45
|
+
/*
|
|
46
|
+
CREATE TABLE IF NOT EXISTS `scan` (
|
|
47
|
+
`id` bigint NOT NULL AUTO_INCREMENT,
|
|
48
|
+
`token` char (32) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
|
49
|
+
`data` text NOT NULL,
|
|
50
|
+
`time_update` bigint NOT NULL,
|
|
51
|
+
`time_add` bigint NOT NULL,
|
|
52
|
+
`time_exp` bigint NOT NULL,
|
|
53
|
+
PRIMARY KEY (`id`),
|
|
54
|
+
UNIQUE KEY `token` (`token`) USING btree
|
|
55
|
+
KEY `time_update` (`time_update`),
|
|
56
|
+
KEY `time_exp` (`time_exp`)
|
|
57
|
+
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
|
58
|
+
*/
|
|
40
59
|
const lCore = __importStar(require("../lib/core"));
|
|
41
60
|
const lDb = __importStar(require("../lib/db"));
|
|
42
61
|
const lKv = __importStar(require("../lib/kv"));
|
|
@@ -46,9 +65,12 @@ const lText = __importStar(require("../lib/text"));
|
|
|
46
65
|
class Scan {
|
|
47
66
|
constructor(link, token, opt = {}) {
|
|
48
67
|
this._sql = null;
|
|
68
|
+
/** --- 表名或者 kv 里 key 的前缀 --- */
|
|
49
69
|
this._name = 'scan';
|
|
50
70
|
this._token = null;
|
|
71
|
+
/** --- 有效期,默认 5 分钟 --- */
|
|
51
72
|
this._ttl = 60 * 5;
|
|
73
|
+
/** --- 二维码剩余有效时间 --- */
|
|
52
74
|
this._timeLeft = null;
|
|
53
75
|
if (opt.ttl !== undefined) {
|
|
54
76
|
this._ttl = opt.ttl;
|
|
@@ -64,26 +86,35 @@ class Scan {
|
|
|
64
86
|
this._token = token;
|
|
65
87
|
}
|
|
66
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* --- 生成二维码处的轮询,检查是否被扫码、被录入数据 ---
|
|
91
|
+
* @returns -3 系统错误 -2 token 不存在或已过期 -1 无操作, 0 已扫码, 其他返回为存的数据并结束轮询
|
|
92
|
+
*/
|
|
67
93
|
async poll() {
|
|
68
94
|
if (!this._token) {
|
|
69
95
|
return -3;
|
|
70
96
|
}
|
|
71
97
|
const time = lTime.stamp();
|
|
72
98
|
if (this._link instanceof lDb.Pool) {
|
|
99
|
+
// --- Db ---
|
|
73
100
|
this._sql.select('*', this._name).where([
|
|
74
101
|
{ 'token': this._token },
|
|
75
102
|
['time_exp', '>', time]
|
|
76
103
|
]);
|
|
77
104
|
const r = await this._link.query(this._sql.getSql(), this._sql.getData());
|
|
78
105
|
if (r.error) {
|
|
106
|
+
// --- 出错 ---
|
|
79
107
|
return -3;
|
|
80
108
|
}
|
|
81
109
|
const data = r.rows?.[0];
|
|
82
110
|
if (!data) {
|
|
111
|
+
// --- 不存在或过期 ---
|
|
83
112
|
return -2;
|
|
84
113
|
}
|
|
114
|
+
// --- 存在,判断是否被扫码,以及是否被写入数据 ---
|
|
85
115
|
this._timeLeft = data['time_exp'] - time;
|
|
86
116
|
if (data['data'] !== '') {
|
|
117
|
+
// --- 已经写入数据了,删除数据库条目并返回写入的数据内容 ---
|
|
87
118
|
this._sql.delete(this._name).where({
|
|
88
119
|
'id': data['id']
|
|
89
120
|
});
|
|
@@ -91,15 +122,19 @@ class Scan {
|
|
|
91
122
|
return r === false ? -3 : r;
|
|
92
123
|
}
|
|
93
124
|
else if (data['time_update'] > 0) {
|
|
125
|
+
// --- 已被扫描 ---
|
|
94
126
|
return 0;
|
|
95
127
|
}
|
|
96
128
|
else {
|
|
129
|
+
// --- 未扫描 ---
|
|
97
130
|
return -1;
|
|
98
131
|
}
|
|
99
132
|
}
|
|
100
133
|
else {
|
|
134
|
+
// --- Kv ---
|
|
101
135
|
const data = await this._link.getJson('scan-' + this._name + '_' + this._token);
|
|
102
136
|
if (data === null) {
|
|
137
|
+
// --- 不存在或过期 ---
|
|
103
138
|
return -2;
|
|
104
139
|
}
|
|
105
140
|
const ttl = await this._link.ttl('scan-' + this._name + '_' + this._token);
|
|
@@ -108,17 +143,23 @@ class Scan {
|
|
|
108
143
|
}
|
|
109
144
|
this._timeLeft = ttl;
|
|
110
145
|
if (data['data'] !== null) {
|
|
146
|
+
// --- 已经写入数据了,删除数据库条目并返回写入的数据内容 ---
|
|
111
147
|
await this._link.del('scan-' + this._name + '_' + this._token);
|
|
112
148
|
return data;
|
|
113
149
|
}
|
|
114
150
|
else if (data['time_update'] > 0) {
|
|
151
|
+
// --- 已被扫描 ---
|
|
115
152
|
return 0;
|
|
116
153
|
}
|
|
117
154
|
else {
|
|
155
|
+
// --- 未扫描 ---
|
|
118
156
|
return -1;
|
|
119
157
|
}
|
|
120
158
|
}
|
|
121
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* --- 创建 token,直接应用到本类 ---
|
|
162
|
+
*/
|
|
122
163
|
async createToken() {
|
|
123
164
|
await this._gc();
|
|
124
165
|
const time = lTime.stamp();
|
|
@@ -129,6 +170,7 @@ class Scan {
|
|
|
129
170
|
}
|
|
130
171
|
this._token = lCore.random(32, lCore.RANDOM_LUN);
|
|
131
172
|
if (this._link instanceof lDb.Pool) {
|
|
173
|
+
// --- Db ---
|
|
132
174
|
this._sql.insert(this._name).values({
|
|
133
175
|
'token': this._token,
|
|
134
176
|
'data': '',
|
|
@@ -147,6 +189,7 @@ class Scan {
|
|
|
147
189
|
}
|
|
148
190
|
}
|
|
149
191
|
else {
|
|
192
|
+
// --- Kv ---
|
|
150
193
|
if (await this._link.set('scan-' + this._name + '_' + this._token, {
|
|
151
194
|
'time_update': 0,
|
|
152
195
|
'data': null
|
|
@@ -158,18 +201,34 @@ class Scan {
|
|
|
158
201
|
}
|
|
159
202
|
return true;
|
|
160
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* --- 获取当前 token ---
|
|
206
|
+
*/
|
|
161
207
|
getToken() {
|
|
162
208
|
return this._token;
|
|
163
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* --- 设置有效期,设置后的新 token 被创建有效 ---
|
|
212
|
+
* @param ttl
|
|
213
|
+
*/
|
|
164
214
|
setTTL(ttl) {
|
|
165
215
|
this._ttl = ttl;
|
|
166
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* --- 获取设置的有效期 ---
|
|
219
|
+
*/
|
|
167
220
|
getTTL() {
|
|
168
221
|
return this._ttl;
|
|
169
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* --- 获取当前 token 可扫剩余有效期 ---
|
|
225
|
+
*/
|
|
170
226
|
getTimeLeft() {
|
|
171
227
|
return this._timeLeft;
|
|
172
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* --- 根据情况清空 Db 状态下的 scan 表垃圾数据 ---
|
|
231
|
+
*/
|
|
173
232
|
async _gc() {
|
|
174
233
|
if (this._link instanceof lKv.Pool) {
|
|
175
234
|
return;
|
|
@@ -184,6 +243,12 @@ class Scan {
|
|
|
184
243
|
}
|
|
185
244
|
}
|
|
186
245
|
exports.Scan = Scan;
|
|
246
|
+
/**
|
|
247
|
+
* -- 创建 Scan 对象 ---
|
|
248
|
+
* @param link
|
|
249
|
+
* @param token Token
|
|
250
|
+
* @param opt
|
|
251
|
+
*/
|
|
187
252
|
async function get(link, token, opt = {}) {
|
|
188
253
|
const scan = new Scan(link, token, opt);
|
|
189
254
|
if (!token) {
|
|
@@ -191,10 +256,17 @@ async function get(link, token, opt = {}) {
|
|
|
191
256
|
}
|
|
192
257
|
return scan;
|
|
193
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* --- 对 token 执行访问操作,通常用户扫码后展示的网页所调用,代表已扫码 ---
|
|
261
|
+
* @param link
|
|
262
|
+
* @patam token 必填
|
|
263
|
+
* @param opt
|
|
264
|
+
*/
|
|
194
265
|
async function scanned(link, token, opt = {}) {
|
|
195
266
|
const time = lTime.stamp();
|
|
196
267
|
const name = opt.name ?? 'scan';
|
|
197
268
|
if (link instanceof lDb.Pool) {
|
|
269
|
+
// --- Db ---
|
|
198
270
|
const sql = lSql.get(opt.sqlPre);
|
|
199
271
|
sql.update(name, {
|
|
200
272
|
'time_update': time
|
|
@@ -214,11 +286,13 @@ async function scanned(link, token, opt = {}) {
|
|
|
214
286
|
}
|
|
215
287
|
}
|
|
216
288
|
else {
|
|
289
|
+
// --- Kv ---
|
|
217
290
|
const ldata = await link.getJson('scan-' + name + '_' + token);
|
|
218
291
|
if (ldata === null) {
|
|
219
292
|
return false;
|
|
220
293
|
}
|
|
221
294
|
if (ldata['time_update'] > 0) {
|
|
295
|
+
// --- 已经被扫码过了 ---
|
|
222
296
|
return false;
|
|
223
297
|
}
|
|
224
298
|
ldata['time_update'] = time;
|
|
@@ -230,6 +304,13 @@ async function scanned(link, token, opt = {}) {
|
|
|
230
304
|
}
|
|
231
305
|
return false;
|
|
232
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* --- 将数据写入 token,通常在客户的逻辑下去写,服务器会 poll 到 ---
|
|
309
|
+
* @param link
|
|
310
|
+
* @param token
|
|
311
|
+
* @param data
|
|
312
|
+
* @param opt
|
|
313
|
+
*/
|
|
233
314
|
async function setData(link, token, data, opt = {}) {
|
|
234
315
|
if (typeof data === 'number' && Number.isInteger(data)) {
|
|
235
316
|
if (data >= -3 && data <= 1) {
|
|
@@ -239,6 +320,7 @@ async function setData(link, token, data, opt = {}) {
|
|
|
239
320
|
const time = lTime.stamp();
|
|
240
321
|
const name = opt.name ?? 'scan';
|
|
241
322
|
if (link instanceof lDb.Pool) {
|
|
323
|
+
// --- Db ---
|
|
242
324
|
const sql = lSql.get(opt.sqlPre);
|
|
243
325
|
sql.update(name, {
|
|
244
326
|
'data': lText.stringifyJson(data)
|
|
@@ -258,11 +340,13 @@ async function setData(link, token, data, opt = {}) {
|
|
|
258
340
|
}
|
|
259
341
|
}
|
|
260
342
|
else {
|
|
343
|
+
// --- Kv ---
|
|
261
344
|
const ldata = await link.getJson('scan-' + name + '_' + token);
|
|
262
345
|
if (ldata === null) {
|
|
263
346
|
return false;
|
|
264
347
|
}
|
|
265
348
|
if (ldata['time_update'] === 0) {
|
|
349
|
+
// --- 还未被扫码,无法操作 ---
|
|
266
350
|
return false;
|
|
267
351
|
}
|
|
268
352
|
const ttl = await link.ttl('scan-' + name + '_' + token);
|
package/lib/session.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
3
|
+
* Date: 2019-6-5 22:01:40
|
|
4
|
+
* Last: 2020-3-30 00:11:15, 2022-12-29 00:10:28, 2023-5-24 18:59:27
|
|
5
|
+
*/
|
|
1
6
|
import * as db from '../lib/db';
|
|
2
7
|
import * as kv from '../lib/kv';
|
|
3
8
|
import * as ctr from '../sys/ctr';
|
|
@@ -8,15 +13,41 @@ export interface IOptions {
|
|
|
8
13
|
'sqlPre'?: string;
|
|
9
14
|
}
|
|
10
15
|
export declare class Session {
|
|
16
|
+
/** --- 数据库操作对象 --- */
|
|
11
17
|
private _link;
|
|
18
|
+
/** --- Sql 对象 --- */
|
|
12
19
|
private _sql;
|
|
20
|
+
/** --- session 在前端或 Kv 中储存的名前缀 --- */
|
|
13
21
|
private _name;
|
|
22
|
+
/** --- 当前 Session 的 token --- */
|
|
14
23
|
private _token;
|
|
24
|
+
/** --- Session 有效期 --- */
|
|
15
25
|
private _ttl;
|
|
26
|
+
/** --- ctr 对象 --- */
|
|
16
27
|
private _ctr;
|
|
28
|
+
/**
|
|
29
|
+
* --- 初始化函数,相当于 construct ---
|
|
30
|
+
* @param ctr 模型实例
|
|
31
|
+
* @param link Kv 或 Db 实例
|
|
32
|
+
* @param auth 设为 true 则优先从头 Authorization 或 post _auth 值读取 token
|
|
33
|
+
* @param opt 选项
|
|
34
|
+
*/
|
|
17
35
|
init(ctr: ctr.Ctr, link: db.Pool | kv.Pool, auth?: boolean, opt?: IOptions): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* --- 获取当前的 token 值 ---
|
|
38
|
+
*/
|
|
18
39
|
getToken(): string;
|
|
40
|
+
/**
|
|
41
|
+
* --- 获取当前的 cookie 的 name 值 ---
|
|
42
|
+
*/
|
|
19
43
|
getName(): string;
|
|
44
|
+
/**
|
|
45
|
+
* --- 页面整体结束时,要写入到 Kv 或 数据库 ---
|
|
46
|
+
*/
|
|
20
47
|
update(): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* --- 根据情况清空 Db 状态下的 session 表垃圾数据 ---
|
|
50
|
+
* --- 仅能在 Db 模式执行,非 Db 模式则等于没运行 ---
|
|
51
|
+
*/
|
|
21
52
|
private _gc;
|
|
22
53
|
}
|
package/lib/session.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
4
|
+
* Date: 2019-6-5 22:01:40
|
|
5
|
+
* Last: 2020-3-30 00:11:15, 2022-12-29 00:10:28, 2023-5-24 18:59:27
|
|
6
|
+
*/
|
|
2
7
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
8
|
if (k2 === undefined) k2 = k;
|
|
4
9
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -34,6 +39,20 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
39
|
})();
|
|
35
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
41
|
exports.Session = void 0;
|
|
42
|
+
/*
|
|
43
|
+
* --- Mysql ---
|
|
44
|
+
CREATE TABLE `session` (
|
|
45
|
+
`id` bigint NOT NULL AUTO_INCREMENT,
|
|
46
|
+
`token` char(16) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
|
47
|
+
`data` text NOT NULL,
|
|
48
|
+
`time_update` bigint NOT NULL,
|
|
49
|
+
`time_add` bigint NOT NULL,
|
|
50
|
+
PRIMARY KEY (`id`),
|
|
51
|
+
UNIQUE KEY `token` (`token`),
|
|
52
|
+
KEY `time_update` (`time_update`)
|
|
53
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
|
54
|
+
*/
|
|
55
|
+
// --- 库和定义 ---
|
|
37
56
|
const core = __importStar(require("../lib/core"));
|
|
38
57
|
const time = __importStar(require("../lib/time"));
|
|
39
58
|
const db = __importStar(require("../lib/db"));
|
|
@@ -42,9 +61,18 @@ const sql = __importStar(require("../lib/sql"));
|
|
|
42
61
|
const text = __importStar(require("../lib/text"));
|
|
43
62
|
class Session {
|
|
44
63
|
constructor() {
|
|
64
|
+
/** --- 当前 Session 的 token --- */
|
|
45
65
|
this._token = '';
|
|
66
|
+
/** --- Session 有效期 --- */
|
|
46
67
|
this._ttl = 0;
|
|
47
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* --- 初始化函数,相当于 construct ---
|
|
71
|
+
* @param ctr 模型实例
|
|
72
|
+
* @param link Kv 或 Db 实例
|
|
73
|
+
* @param auth 设为 true 则优先从头 Authorization 或 post _auth 值读取 token
|
|
74
|
+
* @param opt 选项
|
|
75
|
+
*/
|
|
48
76
|
async init(ctr, link, auth = false, opt = {}) {
|
|
49
77
|
const config = ctr.getPrototype('_config');
|
|
50
78
|
const ssl = opt.ssl ?? config.session.ssl;
|
|
@@ -66,12 +94,16 @@ class Session {
|
|
|
66
94
|
this._link = link;
|
|
67
95
|
if (link instanceof db.Pool) {
|
|
68
96
|
this._sql = sql.get(pre ? pre : ctr);
|
|
69
|
-
await this._gc();
|
|
97
|
+
await this._gc(); // --- 执行 gc ---
|
|
70
98
|
}
|
|
99
|
+
// --- 初始化 Session 数组 ---
|
|
71
100
|
let session = {};
|
|
72
101
|
let needInsert = false;
|
|
102
|
+
// --- 有 token 则查看 token 的信息是否存在
|
|
73
103
|
if (this._token !== '') {
|
|
104
|
+
// --- 如果启用了内存加速则在内存找 ---
|
|
74
105
|
if (this._link instanceof kv.Pool) {
|
|
106
|
+
// --- Kv ---
|
|
75
107
|
let data;
|
|
76
108
|
if ((data = await this._link.getJson(this._name + '_' + this._token)) === null) {
|
|
77
109
|
needInsert = true;
|
|
@@ -81,6 +113,7 @@ class Session {
|
|
|
81
113
|
}
|
|
82
114
|
}
|
|
83
115
|
else {
|
|
116
|
+
// --- 数据库 ---
|
|
84
117
|
this._sql.select('*', 'session').where([
|
|
85
118
|
['time_update', '>=', tim - this._ttl],
|
|
86
119
|
{ 'token': this._token }
|
|
@@ -96,8 +129,13 @@ class Session {
|
|
|
96
129
|
ctr.setPrototype('_session', session);
|
|
97
130
|
}
|
|
98
131
|
else {
|
|
132
|
+
// --- 全新的机子 ---
|
|
99
133
|
needInsert = true;
|
|
100
134
|
}
|
|
135
|
+
// --- 本来就该添加个新 Session ---
|
|
136
|
+
// --- 内存和数据库里没找到的也该添加个新 Session ---
|
|
137
|
+
// --- 数据库的 Session 已经过期加新 Session ---
|
|
138
|
+
// --- 如果不存在不允许加新则返回错误 ---
|
|
101
139
|
if (needInsert) {
|
|
102
140
|
if (this._link instanceof kv.Pool) {
|
|
103
141
|
let count = 0;
|
|
@@ -141,12 +179,21 @@ class Session {
|
|
|
141
179
|
});
|
|
142
180
|
return true;
|
|
143
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* --- 获取当前的 token 值 ---
|
|
184
|
+
*/
|
|
144
185
|
getToken() {
|
|
145
186
|
return this._token;
|
|
146
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* --- 获取当前的 cookie 的 name 值 ---
|
|
190
|
+
*/
|
|
147
191
|
getName() {
|
|
148
192
|
return this._name;
|
|
149
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* --- 页面整体结束时,要写入到 Kv 或 数据库 ---
|
|
196
|
+
*/
|
|
150
197
|
async update() {
|
|
151
198
|
if (this._link instanceof kv.Pool) {
|
|
152
199
|
await this._link.set(this._name + '_' + this._token, this._ctr.getPrototype('_session'), this._ttl);
|
|
@@ -161,6 +208,10 @@ class Session {
|
|
|
161
208
|
await this._link.execute(this._sql.getSql(), this._sql.getData());
|
|
162
209
|
}
|
|
163
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* --- 根据情况清空 Db 状态下的 session 表垃圾数据 ---
|
|
213
|
+
* --- 仅能在 Db 模式执行,非 Db 模式则等于没运行 ---
|
|
214
|
+
*/
|
|
164
215
|
async _gc() {
|
|
165
216
|
if (!(this._link instanceof db.Pool)) {
|
|
166
217
|
return;
|
package/lib/sql.d.ts
CHANGED
|
@@ -1,55 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
3
|
+
* Date: 2019-5-27 20:18:50
|
|
4
|
+
* Last: 2020-3-29 19:37:25, 2022-07-24 22:38:11, 2023-5-24 18:49:18, 2023-6-13 22:20:21, 2023-12-11 13:58:54, 2023-12-14 13:14:40, 2023-12-21 00:04:40, 2024-4-11 19:29:29, 2024-9-2 17:15:28
|
|
5
|
+
*/
|
|
1
6
|
import * as ctr from '../sys/ctr';
|
|
2
7
|
import * as types from '../types';
|
|
3
8
|
export declare class Sql {
|
|
9
|
+
/** --- 前置 --- */
|
|
4
10
|
private readonly _pre;
|
|
11
|
+
/** --- 预拼装 Sql 数组 --- */
|
|
5
12
|
private _sql;
|
|
13
|
+
/** --- 所有 data 数据 --- */
|
|
6
14
|
private _data;
|
|
7
15
|
constructor(pre?: string, opt?: {
|
|
8
16
|
'data'?: types.DbValue[];
|
|
9
17
|
'sql'?: string[];
|
|
10
18
|
});
|
|
19
|
+
/**
|
|
20
|
+
* --- 插入数据前导 ---
|
|
21
|
+
* @param table 表名
|
|
22
|
+
*/
|
|
11
23
|
insert(table: string): this;
|
|
24
|
+
/**
|
|
25
|
+
* --- 替换已经存在的唯一索引数据,不存在则插入 ---
|
|
26
|
+
* @param table 表名
|
|
27
|
+
*/
|
|
12
28
|
replace(table: string): this;
|
|
29
|
+
/**
|
|
30
|
+
* --- 实际插入数据的数据 ---
|
|
31
|
+
* @param cs [] 数据列或字段列
|
|
32
|
+
* @param vs [] | [][] 数据
|
|
33
|
+
*/
|
|
13
34
|
values(cs: string[] | Record<string, types.DbValue>, vs?: types.DbValue[] | types.DbValue[][]): this;
|
|
35
|
+
/**
|
|
36
|
+
* --- 不存在则插入,衔接在 insert 之后 ---
|
|
37
|
+
* @param table 表名
|
|
38
|
+
* @param insert {'xx': 'xx', 'xx': 'xx'}
|
|
39
|
+
* @param where [{'xx': 'xx', 'xx': 'xx'}], {'xx': 'xx'}
|
|
40
|
+
*/
|
|
14
41
|
notExists(table: string, insert: Record<string, types.DbValue>, where: string | types.Json): this;
|
|
42
|
+
/**
|
|
43
|
+
* --- 当不能 insert 时,update(仅能配合 insert 方法用) ---
|
|
44
|
+
* @param s 更新数据
|
|
45
|
+
*/
|
|
15
46
|
duplicate(s: types.Json): this;
|
|
47
|
+
/**
|
|
48
|
+
* --- '*', 'xx' ---
|
|
49
|
+
* @param c 字段字符串或字段数组
|
|
50
|
+
* @param f 表,允许多张表
|
|
51
|
+
*/
|
|
16
52
|
select(c: string | Array<string | Array<string | string[]>>, f: string | string[]): this;
|
|
53
|
+
/**
|
|
54
|
+
* --- UPDATE SQL 方法 ---
|
|
55
|
+
* @param f 表名
|
|
56
|
+
* @param s 设定 update 的值
|
|
57
|
+
*/
|
|
17
58
|
update(f: string, s: types.Json): this;
|
|
18
59
|
private _updateSub;
|
|
60
|
+
/**
|
|
61
|
+
* --- 'xx' ---
|
|
62
|
+
* @param f 表名
|
|
63
|
+
*/
|
|
19
64
|
delete(f: string): this;
|
|
65
|
+
/**
|
|
66
|
+
* --- 联查另一个 sql 对象 ---
|
|
67
|
+
* @param sql sql 对象
|
|
68
|
+
* @param type 类型
|
|
69
|
+
*/
|
|
20
70
|
union(lsql: Sql, type?: string): this;
|
|
71
|
+
/**
|
|
72
|
+
* --- 所有联查另一个 sql 对象 ---
|
|
73
|
+
* @param sql sql 对象
|
|
74
|
+
*/
|
|
21
75
|
unionAll(lsql: Sql): this;
|
|
76
|
+
/**
|
|
77
|
+
* --- join 方法 ---
|
|
78
|
+
* @param f 表名
|
|
79
|
+
* @param s ON 信息
|
|
80
|
+
* @param type 类型
|
|
81
|
+
* @param suf 表后缀
|
|
82
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
83
|
+
*/
|
|
22
84
|
join(f: string, s?: types.Json, type?: string, suf?: string, pre?: string): this;
|
|
85
|
+
/**
|
|
86
|
+
* --- left join 方法 ---
|
|
87
|
+
* @param f 表名
|
|
88
|
+
* @param s ON 信息
|
|
89
|
+
* @param suf 表后缀
|
|
90
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
91
|
+
*/
|
|
23
92
|
leftJoin(f: string, s?: types.Json, suf?: string, pre?: string): this;
|
|
93
|
+
/**
|
|
94
|
+
* --- right join 方法 ---
|
|
95
|
+
* @param f 表名
|
|
96
|
+
* @param s ON 信息
|
|
97
|
+
* @param suf 表后缀
|
|
98
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
99
|
+
*/
|
|
24
100
|
rightJoin(f: string, s?: types.Json, suf?: string, pre?: string): this;
|
|
101
|
+
/**
|
|
102
|
+
* --- inner join 方法 ---
|
|
103
|
+
* @param f 表名
|
|
104
|
+
* @param s ON 信息
|
|
105
|
+
* @param suf 表后缀
|
|
106
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
107
|
+
*/
|
|
25
108
|
innerJoin(f: string, s?: types.Json, suf?: string, pre?: string): this;
|
|
109
|
+
/**
|
|
110
|
+
* --- full join 方法 ---
|
|
111
|
+
* @param f 表名
|
|
112
|
+
* @param s ON 信息
|
|
113
|
+
* @param suf 表后缀
|
|
114
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
115
|
+
*/
|
|
26
116
|
fullJoin(f: string, s?: types.Json, suf?: string, pre?: string): this;
|
|
117
|
+
/**
|
|
118
|
+
* --- cross join 方法 ---
|
|
119
|
+
* @param f 表名
|
|
120
|
+
* @param s ON 信息
|
|
121
|
+
* @param suf 表后缀
|
|
122
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
123
|
+
*/
|
|
27
124
|
crossJoin(f: string, s?: types.Json, suf?: string, pre?: string): this;
|
|
125
|
+
/**
|
|
126
|
+
* --- having 后置筛选器,用法类似 where ---
|
|
127
|
+
*/
|
|
28
128
|
having(s?: string | types.Json): this;
|
|
129
|
+
/** --- where 的 data 的开始处和结束处 --- */
|
|
29
130
|
private _whereDataPosition;
|
|
131
|
+
/**
|
|
132
|
+
* --- 筛选器 ---
|
|
133
|
+
* --- 1. 'city': 'bj', 'type': '2' ---
|
|
134
|
+
* --- 2. ['type', '>', '1'] ---
|
|
135
|
+
* --- 3. ['type', 'in', ['1', '2']] ---
|
|
136
|
+
* --- 4. 'type': ['1', '2'] ---
|
|
137
|
+
* --- 5. '$or': [{'city': 'bj'}, {'city': 'sh'}, [['age', '>', '10']]], 'type': '2' ---
|
|
138
|
+
* --- 6. 'city_in': column('city_out') ---
|
|
139
|
+
* --- 7. ['JSON_CONTAINS(`uid`, ?)', ['hello']] ---
|
|
140
|
+
* @param s 筛选数据
|
|
141
|
+
*/
|
|
30
142
|
where(s: string | types.Json): this;
|
|
31
143
|
private _whereSub;
|
|
144
|
+
/**
|
|
145
|
+
* --- ORDER BY ---
|
|
146
|
+
* @param c 字段字符串或数组
|
|
147
|
+
* @param d 排序规则
|
|
148
|
+
*/
|
|
32
149
|
by(c: string | Array<string | string[]>, d?: 'DESC' | 'ASC'): this;
|
|
150
|
+
/**
|
|
151
|
+
* --- GROUP BY ---
|
|
152
|
+
* @param c 字段字符串或数组
|
|
153
|
+
*/
|
|
33
154
|
group(c: string | string[]): this;
|
|
155
|
+
/**
|
|
156
|
+
* --- LIMIT ---
|
|
157
|
+
* @param a 起始
|
|
158
|
+
* @param b 长度
|
|
159
|
+
*/
|
|
34
160
|
limit(a: number, b?: number): this;
|
|
161
|
+
/**
|
|
162
|
+
* --- 追加消极锁,通常不建议使用 ---
|
|
163
|
+
*/
|
|
35
164
|
lock(): this;
|
|
165
|
+
/**
|
|
166
|
+
* --- 创建一个本对象的一个新的 sql 对象拷贝 ---
|
|
167
|
+
* @param f 可为空,可设置新对象的 table 名变化
|
|
168
|
+
*/
|
|
36
169
|
copy(f?: string | string[], opt?: {
|
|
37
170
|
'where'?: string | types.Json;
|
|
38
171
|
}): Sql;
|
|
172
|
+
/**
|
|
173
|
+
* --- 获取 sql 语句 ---
|
|
174
|
+
*/
|
|
39
175
|
getSql(): string;
|
|
176
|
+
/**
|
|
177
|
+
* --- 获取全部 data ---
|
|
178
|
+
*/
|
|
40
179
|
getData(): types.DbValue[];
|
|
180
|
+
/**
|
|
181
|
+
* --- 获取定义的 pre ---
|
|
182
|
+
*/
|
|
41
183
|
getPre(): string;
|
|
184
|
+
/**
|
|
185
|
+
* --- 获取带 data 的 sql 语句 ---
|
|
186
|
+
* @param sql
|
|
187
|
+
* @param data
|
|
188
|
+
*/
|
|
42
189
|
format(sql?: string, data?: types.DbValue[]): string;
|
|
190
|
+
/**
|
|
191
|
+
* --- 在 sql 最后追加字符串 ---
|
|
192
|
+
* @param sql
|
|
193
|
+
*/
|
|
43
194
|
append(sql: string): this;
|
|
195
|
+
/**
|
|
196
|
+
* --- 对字段进行包裹 ---
|
|
197
|
+
* @param str
|
|
198
|
+
* @param pre 表前缀,仅请在 field 表名时倒入前缀
|
|
199
|
+
* @param suf 表后缀,仅请在 field 表名时倒入后缀,前面加 # 代表要强制 AS
|
|
200
|
+
*/
|
|
44
201
|
field(str: string | number | Array<string | string[]>, pre?: string, suf?: string): string;
|
|
202
|
+
/**
|
|
203
|
+
* --- 判断传入值是否是 field,还是别的对象 ---
|
|
204
|
+
* @param str
|
|
205
|
+
*/
|
|
45
206
|
private _isField;
|
|
46
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* --- 创建 sql 对象 ---
|
|
210
|
+
* @param ctrPre ctr 对象或 pre 表前缀
|
|
211
|
+
* @param opt 参数
|
|
212
|
+
*/
|
|
47
213
|
export declare function get(ctrPre?: ctr.Ctr | string, opt?: {
|
|
48
214
|
'data'?: types.DbValue[];
|
|
49
215
|
'sql'?: string[];
|
|
50
216
|
}): Sql;
|
|
217
|
+
/**
|
|
218
|
+
* --- 返回代入后的完整 SQL 字符串 ---
|
|
219
|
+
* @param sql SQL 字符串
|
|
220
|
+
* @param data DATA 数据
|
|
221
|
+
*/
|
|
51
222
|
export declare function format(sql: string, data: types.DbValue[]): string;
|
|
223
|
+
/**
|
|
224
|
+
* --- 将数组兑换为组合的对象(Array/Object mix) ---
|
|
225
|
+
* @param arr 要转换的数组
|
|
226
|
+
*/
|
|
52
227
|
export declare function aoMix(arr: types.Json): Record<string, string | number | types.Json>;
|
|
228
|
+
/** --- 创建字段对象 --- */
|
|
53
229
|
export declare function column(field: string): {
|
|
54
230
|
'type': 'column';
|
|
55
231
|
'token': string;
|