@maiyunnet/kebab 7.3.0 → 7.4.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 +4 -2
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/s3.d.ts +6 -1
- package/lib/s3.js +16 -21
- package/lib/sql.d.ts +4 -1
- package/lib/sql.js +13 -2
- package/package.json +1 -1
- package/sys/mod.d.ts +2 -0
- package/sys/mod.js +3 -3
- package/www/example/ctr/test.js +6 -0
package/README.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
<p align="center"><img src="./doc/icon.png" width="64" height="64" alt="Kebab"></p>
|
|
2
2
|
<p align="center">
|
|
3
|
-
<a href="https://github.com/maiyun/kebab/blob/
|
|
3
|
+
<a href="https://github.com/maiyun/kebab/blob/main/LICENSE">
|
|
4
4
|
<img alt="License" src="https://img.shields.io/github/license/maiyun/kebab?color=blue" />
|
|
5
5
|
</a>
|
|
6
|
+
<a href="https://www.npmjs.com/package/@maiyunnet/kebab">
|
|
7
|
+
<img alt="NPM stable version" src="https://img.shields.io/npm/v/@maiyunnet/kebab?color=brightgreen&logo=npm" />
|
|
8
|
+
</a>
|
|
6
9
|
<a href="https://github.com/maiyun/kebab/releases">
|
|
7
10
|
<img alt="GitHub releases" src="https://img.shields.io/github/v/release/maiyun/kebab?color=brightgreen&logo=github" />
|
|
8
|
-
<img alt="GitHub pre-releases" src="https://img.shields.io/github/v/release/maiyun/kebab?color=yellow&logo=github&include_prereleases" />
|
|
9
11
|
</a>
|
|
10
12
|
<a href="https://github.com/maiyun/kebab/issues">
|
|
11
13
|
<img alt="GitHub issues" src="https://img.shields.io/github/issues/maiyun/kebab?color=blue&logo=github" />
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* --- 本文件用来定义每个目录实体地址的常量 ---
|
|
7
7
|
*/
|
|
8
8
|
/** --- 当前系统版本号 --- */
|
|
9
|
-
export const VER = '7.
|
|
9
|
+
export const VER = '7.4.0';
|
|
10
10
|
// --- 服务端用的路径 ---
|
|
11
11
|
const imu = decodeURIComponent(import.meta.url).replace('file://', '').replace(/^\/(\w:)/, '$1');
|
|
12
12
|
/** --- /xxx/xxx --- */
|
package/lib/s3.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Project: Kebab, User: Tang Rukun, JianSuoQiYue
|
|
3
3
|
* Date: 2024-2-18 18:32:45
|
|
4
|
-
* Last: 2024-2-18 18:32:47, 2024-3-16 16:42:27, 2024-5-31 21:36:26, 2024-7-8 00:28:42, 2024-7-19 11:32:43, 2025-6-10 21:45:34
|
|
4
|
+
* Last: 2024-2-18 18:32:47, 2024-3-16 16:42:27, 2024-5-31 21:36:26, 2024-7-8 00:28:42, 2024-7-19 11:32:43, 2025-6-10 21:45:34, 2025-12-5 23:42:59
|
|
5
5
|
*/
|
|
6
6
|
import * as s3 from '@aws-sdk/client-s3';
|
|
7
7
|
import * as stream from 'stream';
|
|
@@ -79,6 +79,11 @@ export declare class S3 {
|
|
|
79
79
|
* @param bucket bucket 名
|
|
80
80
|
*/
|
|
81
81
|
headObject(key: string, bucket?: string): Promise<s3.HeadObjectCommandOutput | false>;
|
|
82
|
+
/**
|
|
83
|
+
* --- 销毁连接,释放资源 ---
|
|
84
|
+
* --- 一般会自动垃圾回收,但高频接口也可主动调用 ---
|
|
85
|
+
*/
|
|
86
|
+
destroy(): void;
|
|
82
87
|
}
|
|
83
88
|
/**
|
|
84
89
|
* --- 创建一个对象存储对象 ---
|
package/lib/s3.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Project: Kebab, User: Tang Rukun, JianSuoQiYue
|
|
3
3
|
* Date: 2024-2-18 18:32:45
|
|
4
|
-
* Last: 2024-2-18 18:32:47, 2024-3-16 16:42:27, 2024-5-31 21:36:26, 2024-7-8 00:28:42, 2024-7-19 11:32:43, 2025-6-10 21:45:34
|
|
4
|
+
* Last: 2024-2-18 18:32:47, 2024-3-16 16:42:27, 2024-5-31 21:36:26, 2024-7-8 00:28:42, 2024-7-19 11:32:43, 2025-6-10 21:45:34, 2025-12-5 23:42:59
|
|
5
5
|
*/
|
|
6
6
|
// --- 库和定义 ---
|
|
7
7
|
import * as s3 from '@aws-sdk/client-s3';
|
|
8
8
|
import * as ls from '@aws-sdk/lib-storage';
|
|
9
9
|
import * as lCore from '#kebab/lib/core.js';
|
|
10
10
|
import * as lText from '#kebab/lib/text.js';
|
|
11
|
-
/** --- s3 的连接对象 --- */
|
|
12
|
-
const links = [];
|
|
13
11
|
/**
|
|
14
12
|
* --- s3 文档:https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/ ---
|
|
15
13
|
*/
|
|
@@ -52,12 +50,6 @@ export class S3 {
|
|
|
52
50
|
endpoint = undefined;
|
|
53
51
|
}
|
|
54
52
|
}
|
|
55
|
-
const token = `${opt.service}-${account}-${secretId}-${region}`;
|
|
56
|
-
const link = links.find((item) => item.token === token);
|
|
57
|
-
if (link) {
|
|
58
|
-
this._link = link.link;
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
53
|
this._link = new s3.S3Client({
|
|
62
54
|
'region': region,
|
|
63
55
|
'credentials': {
|
|
@@ -66,10 +58,6 @@ export class S3 {
|
|
|
66
58
|
},
|
|
67
59
|
'endpoint': endpoint,
|
|
68
60
|
});
|
|
69
|
-
links.push({
|
|
70
|
-
'token': token,
|
|
71
|
-
'link': this._link,
|
|
72
|
-
});
|
|
73
61
|
}
|
|
74
62
|
/**
|
|
75
63
|
* --- 修改预定义 bucket ---
|
|
@@ -105,14 +93,14 @@ export class S3 {
|
|
|
105
93
|
'Body': content,
|
|
106
94
|
'ContentLength': length,
|
|
107
95
|
'ContentType': type,
|
|
108
|
-
'ContentDisposition': disposition
|
|
96
|
+
'ContentDisposition': disposition,
|
|
109
97
|
}
|
|
110
98
|
});
|
|
111
99
|
const res = await upload.done();
|
|
112
100
|
return (res.Location && res.Bucket && res.Key) ? res : false;
|
|
113
101
|
}
|
|
114
102
|
catch (e) {
|
|
115
|
-
lCore.log(this._ctr, '[S3][putObject] ' + lText.stringifyJson(e.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
103
|
+
lCore.log(this._ctr, '[LIB][S3][putObject] ' + lText.stringifyJson(e.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
116
104
|
return false;
|
|
117
105
|
}
|
|
118
106
|
}
|
|
@@ -131,8 +119,8 @@ export class S3 {
|
|
|
131
119
|
const r = await this._link.send(go);
|
|
132
120
|
return r.Body;
|
|
133
121
|
}
|
|
134
|
-
catch {
|
|
135
|
-
|
|
122
|
+
catch (e) {
|
|
123
|
+
lCore.log(this._ctr, '[LIB][S3][getObject] ' + lText.stringifyJson(e.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
136
124
|
return false;
|
|
137
125
|
}
|
|
138
126
|
}
|
|
@@ -150,8 +138,8 @@ export class S3 {
|
|
|
150
138
|
await this._link.send(doc);
|
|
151
139
|
return true;
|
|
152
140
|
}
|
|
153
|
-
catch {
|
|
154
|
-
|
|
141
|
+
catch (e) {
|
|
142
|
+
lCore.log(this._ctr, '[LIB][S3][deleteObject] ' + lText.stringifyJson(e.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
155
143
|
return false;
|
|
156
144
|
}
|
|
157
145
|
}
|
|
@@ -172,7 +160,7 @@ export class S3 {
|
|
|
172
160
|
return true;
|
|
173
161
|
}
|
|
174
162
|
catch (e) {
|
|
175
|
-
lCore.log(this._ctr, '[S3][deleteObjects] ' + lText.stringifyJson(e.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
163
|
+
lCore.log(this._ctr, '[LIB][S3][deleteObjects] ' + lText.stringifyJson(e.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
176
164
|
return false;
|
|
177
165
|
}
|
|
178
166
|
}
|
|
@@ -191,11 +179,18 @@ export class S3 {
|
|
|
191
179
|
}
|
|
192
180
|
catch (e) {
|
|
193
181
|
if (e.$metadata?.httpStatusCode !== 404) {
|
|
194
|
-
lCore.log(this._ctr, '[S3][headObject] ' + lText.stringifyJson(e.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
182
|
+
lCore.log(this._ctr, '[LIB][S3][headObject] ' + lText.stringifyJson(e.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
195
183
|
}
|
|
196
184
|
return false;
|
|
197
185
|
}
|
|
198
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* --- 销毁连接,释放资源 ---
|
|
189
|
+
* --- 一般会自动垃圾回收,但高频接口也可主动调用 ---
|
|
190
|
+
*/
|
|
191
|
+
destroy() {
|
|
192
|
+
this._link.destroy();
|
|
193
|
+
}
|
|
199
194
|
}
|
|
200
195
|
/**
|
|
201
196
|
* --- 创建一个对象存储对象 ---
|
package/lib/sql.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ export declare class Sql {
|
|
|
25
25
|
private readonly _alias;
|
|
26
26
|
/** --- PostgreSQL 占位符计数器 --- */
|
|
27
27
|
private _placeholderCounter;
|
|
28
|
+
/** --- 是否忽略错误 --- */
|
|
29
|
+
private _ignore;
|
|
28
30
|
constructor(opt: {
|
|
29
31
|
'service': ESERVICE;
|
|
30
32
|
'ctr'?: ctr.Ctr;
|
|
@@ -35,8 +37,9 @@ export declare class Sql {
|
|
|
35
37
|
/**
|
|
36
38
|
* --- 插入数据前导 ---
|
|
37
39
|
* @param table 表名
|
|
40
|
+
* @param ignore 是否忽略错误(MySQL: INSERT IGNORE, PGSQL: ON CONFLICT DO NOTHING)
|
|
38
41
|
*/
|
|
39
|
-
insert(table: string): this;
|
|
42
|
+
insert(table: string, ignore?: boolean): this;
|
|
40
43
|
/**
|
|
41
44
|
* --- 实际插入数据的数据 ---
|
|
42
45
|
* @param cs [] 数据列或字段列
|
package/lib/sql.js
CHANGED
|
@@ -25,6 +25,8 @@ export class Sql {
|
|
|
25
25
|
_alias = [];
|
|
26
26
|
/** --- PostgreSQL 占位符计数器 --- */
|
|
27
27
|
_placeholderCounter = 1;
|
|
28
|
+
/** --- 是否忽略错误 --- */
|
|
29
|
+
_ignore = false;
|
|
28
30
|
// --- 实例化 ---
|
|
29
31
|
constructor(opt) {
|
|
30
32
|
this._ctr = opt.ctr;
|
|
@@ -41,12 +43,18 @@ export class Sql {
|
|
|
41
43
|
/**
|
|
42
44
|
* --- 插入数据前导 ---
|
|
43
45
|
* @param table 表名
|
|
46
|
+
* @param ignore 是否忽略错误(MySQL: INSERT IGNORE, PGSQL: ON CONFLICT DO NOTHING)
|
|
44
47
|
*/
|
|
45
|
-
insert(table) {
|
|
48
|
+
insert(table, ignore = false) {
|
|
46
49
|
this._data = [];
|
|
47
50
|
this._placeholderCounter = 1;
|
|
48
51
|
this._alias.length = 0;
|
|
49
|
-
|
|
52
|
+
this._ignore = ignore;
|
|
53
|
+
let sql = 'INSERT ';
|
|
54
|
+
if (ignore && this._service === ESERVICE.MYSQL) {
|
|
55
|
+
sql += 'IGNORE ';
|
|
56
|
+
}
|
|
57
|
+
sql += 'INTO ' + this.field(table, this._pre);
|
|
50
58
|
this._sql = [sql];
|
|
51
59
|
return this;
|
|
52
60
|
}
|
|
@@ -99,6 +107,9 @@ export class Sql {
|
|
|
99
107
|
sql = sql.slice(0, -2) + ') VALUES (' + values.slice(0, -2) + ')';
|
|
100
108
|
}
|
|
101
109
|
this._sql.push(sql);
|
|
110
|
+
if (this._ignore && this._service === ESERVICE.PGSQL) {
|
|
111
|
+
this._sql.push(' ON CONFLICT DO NOTHING');
|
|
112
|
+
}
|
|
102
113
|
return this;
|
|
103
114
|
}
|
|
104
115
|
/**
|
package/package.json
CHANGED
package/sys/mod.d.ts
CHANGED
|
@@ -97,6 +97,7 @@ export default class Mod {
|
|
|
97
97
|
'pre'?: string;
|
|
98
98
|
'ctr'?: sCtr.Ctr;
|
|
99
99
|
'index'?: string;
|
|
100
|
+
'ignore'?: boolean;
|
|
100
101
|
}): Promise<boolean | null | false>;
|
|
101
102
|
/**
|
|
102
103
|
* --- 获取添加一个序列的模拟 SQL ---
|
|
@@ -109,6 +110,7 @@ export default class Mod {
|
|
|
109
110
|
'pre'?: string;
|
|
110
111
|
'ctr'?: sCtr.Ctr;
|
|
111
112
|
'index'?: string;
|
|
113
|
+
'ignore'?: boolean;
|
|
112
114
|
}): string;
|
|
113
115
|
/**
|
|
114
116
|
* --- 根据条件移除条目 ---
|
package/sys/mod.js
CHANGED
|
@@ -130,7 +130,7 @@ export default class Mod {
|
|
|
130
130
|
});
|
|
131
131
|
if (!vs) {
|
|
132
132
|
// --- 单行 ---
|
|
133
|
-
sq.insert(this._$table + (opt.index ? ('_' + opt.index) : ''));
|
|
133
|
+
sq.insert(this._$table + (opt.index ? ('_' + opt.index) : ''), opt.ignore);
|
|
134
134
|
sq.values(cs);
|
|
135
135
|
const r = await db.execute(sq.getSql(), sq.getData());
|
|
136
136
|
if (r.packet === null) {
|
|
@@ -150,7 +150,7 @@ export default class Mod {
|
|
|
150
150
|
/** --- 总批次数量 --- */
|
|
151
151
|
const batch = Math.ceil(vs.length / line);
|
|
152
152
|
for (let i = 0; i < batch; ++i) {
|
|
153
|
-
sq.insert(this._$table + (opt.index ? ('_' + opt.index) : ''));
|
|
153
|
+
sq.insert(this._$table + (opt.index ? ('_' + opt.index) : ''), opt.ignore);
|
|
154
154
|
sq.values(cs, vs.slice(i * line, (i + 1) * line));
|
|
155
155
|
const r = await db.execute(sq.getSql(), sq.getData());
|
|
156
156
|
if (r.packet === null) {
|
|
@@ -177,7 +177,7 @@ export default class Mod {
|
|
|
177
177
|
'ctr': opt.ctr,
|
|
178
178
|
'pre': opt.pre ?? this._$pre,
|
|
179
179
|
});
|
|
180
|
-
sq.insert(this._$table + (opt.index ? ('_' + opt.index) : '')).values(cs, vs);
|
|
180
|
+
sq.insert(this._$table + (opt.index ? ('_' + opt.index) : ''), opt.ignore).values(cs, vs);
|
|
181
181
|
return sq.format();
|
|
182
182
|
}
|
|
183
183
|
/**
|
package/www/example/ctr/test.js
CHANGED
|
@@ -2365,6 +2365,12 @@ Result:<pre id="result">Nothing.</pre>`);
|
|
|
2365
2365
|
echo.push(`<pre>sql.insert('user').values(['name', 'age'], ['Ah', '16']);</pre>
|
|
2366
2366
|
<b>getSql() :</b> ${s}<br>
|
|
2367
2367
|
<b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
|
|
2368
|
+
<b>format() :</b> ${sql.format(s, sd)}<hr>`);
|
|
2369
|
+
s = sql.insert('user', true).values(['name', 'age'], ['Ah', '16']).getSql();
|
|
2370
|
+
sd = sql.getData();
|
|
2371
|
+
echo.push(`<pre>sql.insert('user', true).values(['name', 'age'], ['Ah', '16']);</pre>
|
|
2372
|
+
<b>getSql() :</b> ${s}<br>
|
|
2373
|
+
<b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
|
|
2368
2374
|
<b>format() :</b> ${sql.format(s, sd)}<hr>`);
|
|
2369
2375
|
s = sql.insert('user').values({ 'name': 'Bob', 'age': '24' }).getSql();
|
|
2370
2376
|
sd = sql.getData();
|