@maiyunnet/kebab 9.1.4 → 9.2.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/doc/kebab-rag.md +2237 -437
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/buffer.d.ts +5 -0
- package/lib/buffer.js +13 -0
- package/lib/cookie.d.ts +44 -0
- package/lib/cookie.js +216 -0
- package/lib/core.d.ts +3 -2
- package/lib/core.js +15 -12
- package/lib/dns.d.ts +1 -1
- package/lib/dns.js +4 -6
- package/lib/net/request.d.ts +2 -1
- package/lib/net.d.ts +3 -38
- package/lib/net.js +6 -219
- package/lib/socket.d.ts +4 -3
- package/lib/turnstile.js +2 -2
- package/lib/undici/formdata.d.ts +83 -0
- package/lib/undici/formdata.js +166 -0
- package/lib/undici/request.d.ts +86 -0
- package/lib/undici/request.js +120 -0
- package/lib/undici/response.d.ts +39 -0
- package/lib/undici/response.js +111 -0
- package/lib/undici.d.ts +174 -0
- package/lib/undici.js +595 -0
- package/lib/ws.d.ts +6 -5
- package/lib/ws.js +9 -9
- package/package.json +3 -2
- package/sys/route.js +5 -2
- package/www/example/ctr/middle.js +3 -2
- package/www/example/ctr/test.d.ts +32 -0
- package/www/example/ctr/test.js +526 -4
- package/www/example/route.json +1 -0
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* --- 本文件用来定义每个目录实体地址的常量 ---
|
|
7
7
|
*/
|
|
8
8
|
/** --- 当前系统版本号 --- */
|
|
9
|
-
export const VER = '9.
|
|
9
|
+
export const VER = '9.2.0';
|
|
10
10
|
// --- 服务端用的路径 ---
|
|
11
11
|
const imu = decodeURIComponent(import.meta.url).replace('file://', '').replace(/^\/(\w:)/, '$1');
|
|
12
12
|
/** --- /xxx/xxx --- */
|
package/lib/buffer.d.ts
CHANGED
|
@@ -52,3 +52,8 @@ export declare function getReader(buffer: Buffer): Reader;
|
|
|
52
52
|
* @param size 缓冲区大小
|
|
53
53
|
*/
|
|
54
54
|
export declare function getWriter(size: number): Writer;
|
|
55
|
+
/**
|
|
56
|
+
* --- 从可读流中获取完整的 Buffer ---
|
|
57
|
+
* @param stream 可读流对象
|
|
58
|
+
*/
|
|
59
|
+
export declare function getFull(stream: NodeJS.ReadableStream): Promise<Buffer | null>;
|
package/lib/buffer.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as streamConsumers from 'stream/consumers';
|
|
1
2
|
/** --- 读对象 --- */
|
|
2
3
|
export class Reader {
|
|
3
4
|
_buffer;
|
|
@@ -125,3 +126,15 @@ export function getReader(buffer) {
|
|
|
125
126
|
export function getWriter(size) {
|
|
126
127
|
return new Writer(size);
|
|
127
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* --- 从可读流中获取完整的 Buffer ---
|
|
131
|
+
* @param stream 可读流对象
|
|
132
|
+
*/
|
|
133
|
+
export async function getFull(stream) {
|
|
134
|
+
try {
|
|
135
|
+
return await streamConsumers.buffer(stream);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
package/lib/cookie.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as kebab from '#kebab/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* --- 对 cookie 对象进行操作 ---
|
|
4
|
+
* @param cookie 要操作的对象
|
|
5
|
+
* @param name 名
|
|
6
|
+
* @param value 值
|
|
7
|
+
* @param domain 应用网址,如 .xxx.com
|
|
8
|
+
* @param opt 选项 ttl, path, ssl, httponly
|
|
9
|
+
*/
|
|
10
|
+
export declare function setCookie(cookie: Record<string, ICookie>, name: string, value: string, domain: string, opt?: {
|
|
11
|
+
'ttl'?: number;
|
|
12
|
+
'path'?: string;
|
|
13
|
+
'ssl'?: boolean;
|
|
14
|
+
'httponly'?: boolean;
|
|
15
|
+
}): void;
|
|
16
|
+
/**
|
|
17
|
+
* --- 根据 Set-Cookie 头部转换到 cookie 对象 ---
|
|
18
|
+
* @param cookie cookie 对象
|
|
19
|
+
* @param setCookies 头部的 set-cookie 数组
|
|
20
|
+
* @param uri 请求的 URI 对象
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildCookieObject(cookie: Record<string, ICookie>, setCookies: string[], uri: kebab.IUrlParse): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* --- 对象转换为 Cookie 拼接字符串(会自动筛掉不能发送的 cookie) ---
|
|
25
|
+
* @param cookie cookie 对象
|
|
26
|
+
* @param uri 请求的 URI 对象
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildCookieQuery(cookie: Record<string, ICookie>, uri: kebab.IUrlParse): string;
|
|
29
|
+
/**
|
|
30
|
+
* --- 模拟重启浏览器后的状态 ---
|
|
31
|
+
* @param cookie cookie 对象
|
|
32
|
+
*/
|
|
33
|
+
export declare function resetCookieSession(cookie: Record<string, ICookie>): void;
|
|
34
|
+
/** --- Cookie 对象 --- */
|
|
35
|
+
export interface ICookie {
|
|
36
|
+
'name': string;
|
|
37
|
+
'value': string;
|
|
38
|
+
/** --- 有效期秒级时间戳 --- */
|
|
39
|
+
'exp': number;
|
|
40
|
+
'path': string;
|
|
41
|
+
'domain': string;
|
|
42
|
+
'secure': boolean;
|
|
43
|
+
'httponly': boolean;
|
|
44
|
+
}
|
package/lib/cookie.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import * as lText from '#kebab/lib/text.js';
|
|
2
|
+
import * as lTime from '#kebab/lib/time.js';
|
|
3
|
+
/**
|
|
4
|
+
* --- 对 cookie 对象进行操作 ---
|
|
5
|
+
* @param cookie 要操作的对象
|
|
6
|
+
* @param name 名
|
|
7
|
+
* @param value 值
|
|
8
|
+
* @param domain 应用网址,如 .xxx.com
|
|
9
|
+
* @param opt 选项 ttl, path, ssl, httponly
|
|
10
|
+
*/
|
|
11
|
+
export function setCookie(cookie, name, value, domain, opt = {}) {
|
|
12
|
+
const tim = lTime.stamp();
|
|
13
|
+
const ttl = opt.ttl ?? 0;
|
|
14
|
+
domain = lText.parseHost(domain).hostname;
|
|
15
|
+
const domainN = domain.startsWith('.') ? domain.slice(1) : domain;
|
|
16
|
+
let exp = -1992199400;
|
|
17
|
+
if (ttl) {
|
|
18
|
+
exp = tim + ttl;
|
|
19
|
+
}
|
|
20
|
+
cookie[name + '-' + domainN] = {
|
|
21
|
+
'name': name,
|
|
22
|
+
'value': value,
|
|
23
|
+
'exp': exp,
|
|
24
|
+
'path': opt['path'] ?? '/',
|
|
25
|
+
'domain': domainN,
|
|
26
|
+
'secure': opt['ssl'] ? true : false,
|
|
27
|
+
'httponly': opt['httponly'] ? true : false
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* --- 根据 Set-Cookie 头部转换到 cookie 对象 ---
|
|
32
|
+
* @param cookie cookie 对象
|
|
33
|
+
* @param setCookies 头部的 set-cookie 数组
|
|
34
|
+
* @param uri 请求的 URI 对象
|
|
35
|
+
*/
|
|
36
|
+
export async function buildCookieObject(cookie, setCookies, uri) {
|
|
37
|
+
const tim = lTime.stamp();
|
|
38
|
+
uri.path ??= '/';
|
|
39
|
+
for (const setCookie of setCookies) {
|
|
40
|
+
const cookieTmp = {};
|
|
41
|
+
const list = setCookie.split(';');
|
|
42
|
+
// --- 提取 set-cookie 中的定义信息 ---
|
|
43
|
+
for (let index = 0; index < list.length; ++index) {
|
|
44
|
+
const item = list[index];
|
|
45
|
+
const arr = item.split('=');
|
|
46
|
+
/** --- 提取 key 并修整 --- */
|
|
47
|
+
const key = arr[0].trim();
|
|
48
|
+
if (key === '') {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
/** --- 提取 value --- */
|
|
52
|
+
let val = '';
|
|
53
|
+
if (arr.length > 1) {
|
|
54
|
+
val = item.slice(item.indexOf('=') + 1).trim();
|
|
55
|
+
}
|
|
56
|
+
if (index === 0) {
|
|
57
|
+
// --- 用户定义的信息 ---
|
|
58
|
+
cookieTmp['name'] = key;
|
|
59
|
+
try {
|
|
60
|
+
cookieTmp['value'] = decodeURIComponent(val);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
cookieTmp['value'] = val;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// --- cookie 配置信息,可转小写方便读取 ---
|
|
68
|
+
cookieTmp[key.toLowerCase()] = val;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// --- 获取定义的 domain ---
|
|
72
|
+
let domain = '', domainN = '';
|
|
73
|
+
if (cookieTmp['domain']) {
|
|
74
|
+
cookieTmp['domain'] = lText.parseHost(cookieTmp['domain']).hostname;
|
|
75
|
+
if (!(cookieTmp['domain'].startsWith('.'))) {
|
|
76
|
+
domain = '.' + cookieTmp['domain'];
|
|
77
|
+
domainN = cookieTmp['domain'];
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
domain = cookieTmp['domain'];
|
|
81
|
+
domainN = cookieTmp['domain'].slice(1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
domain = '.' + (uri.hostname ?? '');
|
|
86
|
+
domainN = uri.hostname ?? '';
|
|
87
|
+
}
|
|
88
|
+
// --- 判断有没有设置 domain 的权限 ---
|
|
89
|
+
// --- uri.hostname vs domain(domainN) ---
|
|
90
|
+
// --- ok.xxx.com vs .ok.xxx.com: true ---
|
|
91
|
+
// --- ok.xxx.com vs .xxx.com: true ---
|
|
92
|
+
// --- z.ok.xxx.com vs .xxx.com: true ---
|
|
93
|
+
// --- ok.xxx.com vs .zz.ok.xxx.com: false ---
|
|
94
|
+
if (uri.hostname !== domainN) {
|
|
95
|
+
// --- 设置的域名和当前 host 不相等,如果是 IP、无 . 域名,则直接失败 ---
|
|
96
|
+
if (!lText.isDomain(uri.hostname ?? '')) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const parseDomain = await lText.parseDomain(domainN);
|
|
100
|
+
if (parseDomain.tld === domainN.toLowerCase()) {
|
|
101
|
+
// --- 不能给 tld 设置 cookie ---
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// --- 判断访问路径 (uri['host']) 是不是设置域名 (domain) 的孩子,domain 必须是 uriHost 的同级或者父辈 ---
|
|
105
|
+
if (!((uri.hostname ?? '').endsWith(domain))) {
|
|
106
|
+
// --- false 代表进入了,代表失败 ---
|
|
107
|
+
// --- ok.xxx.com, .xxx.com: true ---
|
|
108
|
+
// --- ok.xxx.com, .ppp.com: false ---
|
|
109
|
+
// --- ok.xxx.com, .p.ok.xxx.com: false ---
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const cookieKey = cookieTmp['name'] + '-' + domainN;
|
|
114
|
+
let exp = -1992199400;
|
|
115
|
+
if (cookieTmp['max-age'] !== undefined) {
|
|
116
|
+
const maxAge = Number(cookieTmp['max-age']);
|
|
117
|
+
if (!(isNaN(maxAge))) {
|
|
118
|
+
if (maxAge <= 0) {
|
|
119
|
+
delete cookie[cookieKey];
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
exp = tim + maxAge;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if ((exp === -1992199400) && cookieTmp['expires']) {
|
|
126
|
+
const expires = lTime.stamp(cookieTmp['expires']);
|
|
127
|
+
if (!(isNaN(expires))) {
|
|
128
|
+
if (expires <= tim) {
|
|
129
|
+
delete cookie[cookieKey];
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
exp = expires;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// --- path ---
|
|
136
|
+
let path = cookieTmp['path'] ?? '';
|
|
137
|
+
if (path === '') {
|
|
138
|
+
const srp = (uri.pathname ?? '').lastIndexOf('/');
|
|
139
|
+
path = (uri.pathname ?? '').slice(0, srp + 1);
|
|
140
|
+
}
|
|
141
|
+
else if (!path.startsWith('/')) {
|
|
142
|
+
path = '/' + path;
|
|
143
|
+
}
|
|
144
|
+
cookie[cookieKey] = {
|
|
145
|
+
'name': cookieTmp['name'],
|
|
146
|
+
'value': cookieTmp['value'],
|
|
147
|
+
'exp': exp,
|
|
148
|
+
'path': path,
|
|
149
|
+
'domain': domainN,
|
|
150
|
+
'secure': cookieTmp['secure'] !== undefined,
|
|
151
|
+
'httponly': cookieTmp['httponly'] !== undefined
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* --- 对象转换为 Cookie 拼接字符串(会自动筛掉不能发送的 cookie) ---
|
|
157
|
+
* @param cookie cookie 对象
|
|
158
|
+
* @param uri 请求的 URI 对象
|
|
159
|
+
*/
|
|
160
|
+
export function buildCookieQuery(cookie, uri) {
|
|
161
|
+
const tim = lTime.stamp();
|
|
162
|
+
let cookieStr = '';
|
|
163
|
+
for (const key in cookie) {
|
|
164
|
+
const item = cookie[key];
|
|
165
|
+
if ((item.exp < tim) && (item.exp !== -1992199400)) {
|
|
166
|
+
delete cookie[key];
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
uri.path ??= '/';
|
|
170
|
+
if (item.secure && (uri.protocol !== 'https:')) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
// --- 判断 path 是否匹配 ---
|
|
174
|
+
if (!uri.path.startsWith(item.path)) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const domain = '.' + item.domain;
|
|
178
|
+
// --- 判断 $uri['host'] 必须是 $domain 的同级或子级 ---
|
|
179
|
+
// --- $uri['host'] vs $domain ---
|
|
180
|
+
// --- ok.xxx.com vs .ok.xxx.com: true ---
|
|
181
|
+
// --- ok.xxx.com vs .xxx.com: true ---
|
|
182
|
+
// --- z.ok.xxx.com vs .xxx.com: true ---
|
|
183
|
+
// --- ok.xxx.com vs .zz.ok.xxx.com: false ---
|
|
184
|
+
if ('.' + (uri.hostname ?? '') !== domain) {
|
|
185
|
+
// --- 域名不相等,那么判断当前域名 host 是不是 domain 的孩子 ---
|
|
186
|
+
if (!(uri.hostname.endsWith(domain))) {
|
|
187
|
+
// --- false 代表进入,被排除了,因为 cookie 的 domain 和当前 host 后半部分,代表不是 domain 的孩子 ---
|
|
188
|
+
// --- ok.xxx.com, .zz.ok.xxx.com: false ---
|
|
189
|
+
// --- pp.ok.xxx.com, .zz.ok.xxx.com: false ---
|
|
190
|
+
// --- q.b.ok.xx.com, .zz.ok.xxx.com: false ---
|
|
191
|
+
// --- z.ok.xxx.com, .xxx.com: true ---
|
|
192
|
+
// --- xx.xxx.com, .ok.xxx.com: false ---
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
cookieStr += item.name + '=' + encodeURIComponent(item.value) + '; ';
|
|
197
|
+
}
|
|
198
|
+
if (cookieStr !== '') {
|
|
199
|
+
return cookieStr.slice(0, -2);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
return '';
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* --- 模拟重启浏览器后的状态 ---
|
|
207
|
+
* @param cookie cookie 对象
|
|
208
|
+
*/
|
|
209
|
+
export function resetCookieSession(cookie) {
|
|
210
|
+
for (const key in cookie) {
|
|
211
|
+
const item = cookie[key];
|
|
212
|
+
if (item.exp === -1992199400000) {
|
|
213
|
+
delete cookie[key];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
package/lib/core.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ import * as http2 from 'http2';
|
|
|
3
3
|
import * as stream from 'stream';
|
|
4
4
|
import * as net from 'net';
|
|
5
5
|
import * as kebab from '#kebab/index.js';
|
|
6
|
-
import * as
|
|
6
|
+
import * as lNetResponse from '#kebab/lib/net/response.js';
|
|
7
|
+
import * as lUndiciResponse from '#kebab/lib/undici/response.js';
|
|
7
8
|
import * as sCtr from '#kebab/sys/ctr.js';
|
|
8
9
|
/** --- 全局参数 --- */
|
|
9
10
|
export declare const globalConfig: kebab.IConfig & {
|
|
@@ -149,7 +150,7 @@ export declare function emptyObject(obj: Record<string, any>, deep?: boolean): v
|
|
|
149
150
|
* @param data 数组
|
|
150
151
|
* @param end 是否关闭写入,默认是,关闭后 passThrough 不能被写入,但仍然可读
|
|
151
152
|
*/
|
|
152
|
-
export declare function passThroughAppend(passThrough: stream.PassThrough, data: Array<stream.Readable |
|
|
153
|
+
export declare function passThroughAppend(passThrough: stream.PassThrough, data: Array<stream.Readable | lNetResponse.Response | lUndiciResponse.Response | string | Buffer>, end?: boolean): Promise<void>;
|
|
153
154
|
/**
|
|
154
155
|
* --- 执行命令行 ---
|
|
155
156
|
* @param command 命令字符串
|
package/lib/core.js
CHANGED
|
@@ -14,9 +14,10 @@ import * as kebab from '#kebab/index.js';
|
|
|
14
14
|
import * as lTime from '#kebab/lib/time.js';
|
|
15
15
|
import * as lFs from '#kebab/lib/fs.js';
|
|
16
16
|
import * as lText from '#kebab/lib/text.js';
|
|
17
|
-
import * as
|
|
17
|
+
import * as lUndici from '#kebab/lib/undici.js';
|
|
18
18
|
import * as lCrypto from '#kebab/lib/crypto.js';
|
|
19
|
-
import * as
|
|
19
|
+
import * as lNetResponse from '#kebab/lib/net/response.js';
|
|
20
|
+
import * as lUndiciResponse from '#kebab/lib/undici/response.js';
|
|
20
21
|
import * as sCtr from '#kebab/sys/ctr.js';
|
|
21
22
|
/** --- 全局参数 --- */
|
|
22
23
|
export const globalConfig = {};
|
|
@@ -396,7 +397,9 @@ export function emptyObject(obj, deep = false) {
|
|
|
396
397
|
*/
|
|
397
398
|
export async function passThroughAppend(passThrough, data, end = true) {
|
|
398
399
|
for (const item of data) {
|
|
399
|
-
if (item instanceof stream.Readable ||
|
|
400
|
+
if (item instanceof stream.Readable ||
|
|
401
|
+
item instanceof lNetResponse.Response ||
|
|
402
|
+
item instanceof lUndiciResponse.Response) {
|
|
400
403
|
const stm = item instanceof stream.Readable ? item : item.getStream();
|
|
401
404
|
if (!stm) {
|
|
402
405
|
continue;
|
|
@@ -463,7 +466,7 @@ export async function sendReload(hosts) {
|
|
|
463
466
|
/** --- 返回成功的 host --- */
|
|
464
467
|
const rtn = [];
|
|
465
468
|
for (const host of hosts) {
|
|
466
|
-
const res = await
|
|
469
|
+
const res = await lUndici.get('http://' + host + ':' + globalConfig.rpcPort.toString() + '/' + lCrypto.aesEncrypt(lText.stringifyJson({
|
|
467
470
|
'action': 'reload',
|
|
468
471
|
'time': time
|
|
469
472
|
}), globalConfig.rpcSecret), {
|
|
@@ -502,7 +505,7 @@ export async function sendRestart(hosts) {
|
|
|
502
505
|
/** --- 返回成功的 host --- */
|
|
503
506
|
const rtn = [];
|
|
504
507
|
for (const host of hosts) {
|
|
505
|
-
const res = await
|
|
508
|
+
const res = await lUndici.get('http://' + host + ':' + globalConfig.rpcPort.toString() + '/' + lCrypto.aesEncrypt(lText.stringifyJson({
|
|
506
509
|
'action': 'restart',
|
|
507
510
|
'time': time
|
|
508
511
|
}), globalConfig.rpcSecret), {
|
|
@@ -535,7 +538,7 @@ export async function sendPm2(name, action = 'restart', hosts) {
|
|
|
535
538
|
/** --- 返回成功的 host --- */
|
|
536
539
|
const rtn = [];
|
|
537
540
|
for (const host of hosts) {
|
|
538
|
-
const res = await
|
|
541
|
+
const res = await lUndici.get('http://' + host + ':' + globalConfig.rpcPort.toString() + '/' + lCrypto.aesEncrypt(lText.stringifyJson({
|
|
539
542
|
'action': 'pm2',
|
|
540
543
|
'time': time,
|
|
541
544
|
'name': name,
|
|
@@ -572,7 +575,7 @@ export async function sendNpm(path, hosts) {
|
|
|
572
575
|
/** --- 返回成功的 host --- */
|
|
573
576
|
const rtn = [];
|
|
574
577
|
for (const host of hosts) {
|
|
575
|
-
const res = await
|
|
578
|
+
const res = await lUndici.get('http://' + host + ':' + globalConfig.rpcPort.toString() + '/' + lCrypto.aesEncrypt(lText.stringifyJson({
|
|
576
579
|
'action': 'npm',
|
|
577
580
|
'time': time,
|
|
578
581
|
'path': path
|
|
@@ -619,7 +622,7 @@ export async function setGlobal(key, data, hosts) {
|
|
|
619
622
|
/** --- 返回成功的 host --- */
|
|
620
623
|
const rtn = [];
|
|
621
624
|
for (const host of hosts) {
|
|
622
|
-
const res = await
|
|
625
|
+
const res = await lUndici.get('http://' + host + ':' + globalConfig.rpcPort.toString() + '/' + lCrypto.aesEncrypt(lText.stringifyJson({
|
|
623
626
|
'action': 'global',
|
|
624
627
|
'time': time
|
|
625
628
|
}), globalConfig.rpcSecret), {
|
|
@@ -660,14 +663,14 @@ export async function updateCode(sourcePath, path, hosts, config = true, strict
|
|
|
660
663
|
/** --- 返回成功的 host --- */
|
|
661
664
|
const rtn = {};
|
|
662
665
|
for (const host of hosts) {
|
|
663
|
-
const fd =
|
|
666
|
+
const fd = lUndici.getFormData();
|
|
664
667
|
if (!await fd.putFile('file', sourcePath)) {
|
|
665
668
|
continue;
|
|
666
669
|
}
|
|
667
670
|
fd.putString('path', path);
|
|
668
671
|
fd.putString('config', config ? '1' : '0');
|
|
669
672
|
fd.putString('strict', strict ? '1' : '0');
|
|
670
|
-
const res = await
|
|
673
|
+
const res = await lUndici.post('http://' + host + ':' + globalConfig.rpcPort.toString() + '/' + lCrypto.aesEncrypt(lText.stringifyJson({
|
|
671
674
|
'action': 'code',
|
|
672
675
|
'time': lTime.stamp()
|
|
673
676
|
}), globalConfig.rpcSecret), fd, {
|
|
@@ -801,7 +804,7 @@ export async function getLog(opt) {
|
|
|
801
804
|
opt.host ??= '127.0.0.1';
|
|
802
805
|
// --- 局域网模式 ---
|
|
803
806
|
const time = lTime.stamp();
|
|
804
|
-
const res = await
|
|
807
|
+
const res = await lUndici.get('http://' + opt.host + ':' + globalConfig.rpcPort.toString() + '/' + lCrypto.aesEncrypt(lText.stringifyJson({
|
|
805
808
|
'action': 'log',
|
|
806
809
|
'time': time,
|
|
807
810
|
'hostname': opt.hostname,
|
|
@@ -837,7 +840,7 @@ export async function ls(opt) {
|
|
|
837
840
|
opt.host ??= '127.0.0.1';
|
|
838
841
|
// --- 局域网模式 ---
|
|
839
842
|
const time = lTime.stamp();
|
|
840
|
-
const res = await
|
|
843
|
+
const res = await lUndici.get('http://' + opt.host + ':' + globalConfig.rpcPort.toString() + '/' + lCrypto.aesEncrypt(lText.stringifyJson({
|
|
841
844
|
'action': 'ls',
|
|
842
845
|
'time': time,
|
|
843
846
|
'path': opt.path,
|
package/lib/dns.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Project: Kebab, User: JianSuoQiYue
|
|
3
3
|
* Date: 2019-6-19
|
|
4
|
-
* Last: 2022-09-12 20:58:07, 2024-2-21 17:55:54, 2025-6-13 19:08:56, 2025-11-19 00:17:56
|
|
4
|
+
* Last: 2022-09-12 20:58:07, 2024-2-21 17:55:54, 2025-6-13 19:08:56, 2025-11-19 00:17:56, 2026-04-17 18:28:54
|
|
5
5
|
*/
|
|
6
6
|
import * as sCtr from '#kebab/sys/ctr.js';
|
|
7
7
|
/**
|
package/lib/dns.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Project: Kebab, User: JianSuoQiYue
|
|
3
3
|
* Date: 2019-6-19
|
|
4
|
-
* Last: 2022-09-12 20:58:07, 2024-2-21 17:55:54, 2025-6-13 19:08:56, 2025-11-19 00:17:56
|
|
4
|
+
* Last: 2022-09-12 20:58:07, 2024-2-21 17:55:54, 2025-6-13 19:08:56, 2025-11-19 00:17:56, 2026-04-17 18:28:54
|
|
5
5
|
*/
|
|
6
6
|
// --- 库和定义 ---
|
|
7
|
-
import * as lNet from '#kebab/lib/net.js';
|
|
8
7
|
import * as lCore from '#kebab/lib/core.js';
|
|
9
8
|
import * as lText from '#kebab/lib/text.js';
|
|
10
9
|
import * as lCrypto from '#kebab/lib/crypto.js';
|
|
11
|
-
import * as
|
|
10
|
+
import * as lUndici from '#kebab/lib/undici.js';
|
|
12
11
|
/**
|
|
13
12
|
* 0.DNSPod:https://www.dnspod.cn/docs/index.html(腾讯云也请使用 DNSPod 的 API)
|
|
14
13
|
* 1.阿里云:https://help.aliyun.com/document_detail/29745.html
|
|
@@ -91,7 +90,7 @@ export class Dns {
|
|
|
91
90
|
const path = data['_path'];
|
|
92
91
|
delete data['_path'];
|
|
93
92
|
// --- 境外服务器请求的话 api 会自动解析到香港服务器 ---
|
|
94
|
-
return
|
|
93
|
+
return lUndici.post('https://dnsapi.cn/' + path, data);
|
|
95
94
|
}
|
|
96
95
|
// --- 阿里云 ---
|
|
97
96
|
case ESERVICE.ALIBABA: {
|
|
@@ -106,10 +105,9 @@ export class Dns {
|
|
|
106
105
|
}, obj));
|
|
107
106
|
const urlRight = lText.queryStringify(getData);
|
|
108
107
|
const signature = lCrypto.hashHmac('sha1', `GET&${encodeURIComponent('/')}&${encodeURIComponent(urlRight)}`, (this._opt.secretKey ?? '') + '&', 'base64');
|
|
109
|
-
return
|
|
108
|
+
return lUndici.get(`https://alidns.aliyuncs.com/?${urlRight}&Signature=${encodeURIComponent(signature)}`); // 境外 api 会自动调度到新加坡服务器
|
|
110
109
|
}
|
|
111
110
|
}
|
|
112
|
-
return new lResponse.Response(null);
|
|
113
111
|
}
|
|
114
112
|
/**
|
|
115
113
|
* --- 获取域名列表 ---
|
package/lib/net/request.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import * as stream from 'stream';
|
|
7
7
|
import * as lNet from '#kebab/lib/net.js';
|
|
8
|
+
import * as lCookie from '#kebab/lib/cookie.js';
|
|
8
9
|
import * as lResponse from './response.js';
|
|
9
10
|
export declare class Request {
|
|
10
11
|
/** --- get 或 post 的数据 --- */
|
|
@@ -81,5 +82,5 @@ export declare class Request {
|
|
|
81
82
|
* --- 发起请求 ---
|
|
82
83
|
* @param cookie
|
|
83
84
|
*/
|
|
84
|
-
request(cookie?: Record<string,
|
|
85
|
+
request(cookie?: Record<string, lCookie.ICookie>): Promise<lResponse.Response>;
|
|
85
86
|
}
|
package/lib/net.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import * as stream from 'stream';
|
|
|
8
8
|
import * as http from 'http';
|
|
9
9
|
import * as http2 from 'http2';
|
|
10
10
|
import * as kebab from '#kebab/index.js';
|
|
11
|
+
import * as lCookie from '#kebab/lib/cookie.js';
|
|
11
12
|
import * as sCtr from '#kebab/sys/ctr.js';
|
|
12
13
|
import * as lFd from './net/formdata.js';
|
|
13
14
|
import * as lRequest from './net/request.js';
|
|
@@ -74,31 +75,6 @@ export declare function fetch(input: string | URL | Request, init?: RequestInit
|
|
|
74
75
|
* @param opt 配置项
|
|
75
76
|
*/
|
|
76
77
|
export declare function request(u: string, data?: Record<string, kebab.Json> | Buffer | string | stream.Readable, opt?: IRequestOptions): Promise<lResponse.Response>;
|
|
77
|
-
/**
|
|
78
|
-
* --- 对 cookie 对象进行操作 ---
|
|
79
|
-
* @param cookie 要操作的对象
|
|
80
|
-
* @param name 名
|
|
81
|
-
* @param value 值
|
|
82
|
-
* @param domain 应用网址,如 .xxx.com
|
|
83
|
-
* @param opt 选项 ttl, path, ssl, httponly
|
|
84
|
-
*/
|
|
85
|
-
export declare function setCookie(cookie: Record<string, ICookie>, name: string, value: string, domain: string, opt?: {
|
|
86
|
-
'ttl'?: number;
|
|
87
|
-
'path'?: string;
|
|
88
|
-
'ssl'?: boolean;
|
|
89
|
-
'httponly'?: boolean;
|
|
90
|
-
}): void;
|
|
91
|
-
/**
|
|
92
|
-
* --- 对象转换为 Cookie 拼接字符串(会自动筛掉不能发送的 cookie) ---
|
|
93
|
-
* @param cookie cookie 对象
|
|
94
|
-
* @param uri 请求的 URI 对象
|
|
95
|
-
*/
|
|
96
|
-
export declare function buildCookieQuery(cookie: Record<string, ICookie>, uri: kebab.IUrlParse): string;
|
|
97
|
-
/**
|
|
98
|
-
* --- 模拟重启浏览器后的状态 ---
|
|
99
|
-
* @param cookie cookie 对象
|
|
100
|
-
*/
|
|
101
|
-
export declare function resetCookieSession(cookie: Record<string, ICookie>): void;
|
|
102
78
|
/**
|
|
103
79
|
* --- 创建 FormData 对象 ---
|
|
104
80
|
*/
|
|
@@ -134,7 +110,7 @@ export declare function rproxy(ctr: sCtr.Ctr, route: Record<string, string>, opt
|
|
|
134
110
|
export interface IRequestOptions {
|
|
135
111
|
'method'?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS';
|
|
136
112
|
'type'?: 'form' | 'json';
|
|
137
|
-
/** ---
|
|
113
|
+
/** --- 秒数,默认 10 秒 --- */
|
|
138
114
|
'timeout'?: number;
|
|
139
115
|
/** --- 追踪 location 次数,0 为不追踪,默认为 0 --- */
|
|
140
116
|
'follow'?: number;
|
|
@@ -156,7 +132,7 @@ export interface IRequestOptions {
|
|
|
156
132
|
/** --- 复用池名,默认为 default --- */
|
|
157
133
|
'reuse'?: string;
|
|
158
134
|
/** --- cookie 托管对象 --- */
|
|
159
|
-
'cookie'?: Record<string, ICookie>;
|
|
135
|
+
'cookie'?: Record<string, lCookie.ICookie>;
|
|
160
136
|
/** --- 若有异常写入文件日志,默认为 true --- */
|
|
161
137
|
'log'?: boolean;
|
|
162
138
|
}
|
|
@@ -202,14 +178,3 @@ export type THttpHeaders = http.IncomingHttpHeaders & {
|
|
|
202
178
|
'http-code'?: number;
|
|
203
179
|
'http-url'?: string;
|
|
204
180
|
};
|
|
205
|
-
/** --- Net Cookie 对象 --- */
|
|
206
|
-
export interface ICookie {
|
|
207
|
-
'name': string;
|
|
208
|
-
'value': string;
|
|
209
|
-
/** --- 有效期秒级时间戳 --- */
|
|
210
|
-
'exp': number;
|
|
211
|
-
'path': string;
|
|
212
|
-
'domain': string;
|
|
213
|
-
'secure': boolean;
|
|
214
|
-
'httponly': boolean;
|
|
215
|
-
}
|