xshell 1.0.202 → 1.0.203
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/net.d.ts +8 -1
- package/net.js +10 -6
- package/package.json +2 -2
- package/path.d.ts +2 -2
- package/process.d.ts +80 -93
- package/process.js +178 -210
- package/utils.browser.d.ts +1 -1
- package/utils.d.ts +1 -1
package/net.d.ts
CHANGED
|
@@ -54,6 +54,10 @@ export interface RequestOptions {
|
|
|
54
54
|
cookies?: Record<string, string>;
|
|
55
55
|
redirect?: 'follow' | 'manual';
|
|
56
56
|
decode?: boolean;
|
|
57
|
+
print?: {
|
|
58
|
+
retry: boolean;
|
|
59
|
+
timeout: boolean;
|
|
60
|
+
};
|
|
57
61
|
}
|
|
58
62
|
export interface RequestFullOptions extends RequestOptions {
|
|
59
63
|
full: true;
|
|
@@ -92,7 +96,10 @@ export interface RequestError extends Error {
|
|
|
92
96
|
- cookies?: 需要额外添加到请求的 cookies, 默认情况下携带了 MemoryCookieStore 中保存的之前 http 响应中的 cookies
|
|
93
97
|
- raw?: `false` 传入后返回整个 response (RawResponse),body 为 Readable
|
|
94
98
|
- full?: `false` 传入后返回整个 response (FullResponse),body 根据 encoding 对应为 string 或 Buffer
|
|
95
|
-
- decode?: 根据 content-encoding: br 等解码压缩后的 response.body
|
|
99
|
+
- decode?: 根据 content-encoding: br 等解码压缩后的 response.body
|
|
100
|
+
- print?:
|
|
101
|
+
- retry: `true` 是否打印 "等待 1 秒后重试 request" 提示信息
|
|
102
|
+
- timeout: `true` 是否打印最后一次超时重试失败时的错误 */
|
|
96
103
|
export declare function request(url: string | URL): Promise<string>;
|
|
97
104
|
export declare function request(url: string | URL, options: RequestRawOptions): Promise<RawResponse>;
|
|
98
105
|
export declare function request(url: string | URL, options: RequestFullOptions & {
|
package/net.js
CHANGED
|
@@ -38,7 +38,7 @@ const drop_request_headers = new Set([
|
|
|
38
38
|
'upgrade',
|
|
39
39
|
]);
|
|
40
40
|
let agents = {};
|
|
41
|
-
async function request_retry(url, options, _timeout, retries = 0, count = 0) {
|
|
41
|
+
async function request_retry(url, options, _timeout, retries = 0, count = 0, print) {
|
|
42
42
|
let { default: undici, request: undici_request } = await import('undici');
|
|
43
43
|
undici_request ??= undici.request;
|
|
44
44
|
try {
|
|
@@ -46,7 +46,7 @@ async function request_retry(url, options, _timeout, retries = 0, count = 0) {
|
|
|
46
46
|
// 设置给 undici 设置 timeout, signal 不一定管用,还是得自己兜底
|
|
47
47
|
options.signal = AbortSignal.timeout(_timeout);
|
|
48
48
|
return await timeout(_timeout + 300, // 为 undici 兜底
|
|
49
|
-
async () => undici.request(url, options), undefined, count >= retries // 只打印最后一次超时的错误,避免太多冗余输出
|
|
49
|
+
async () => undici.request(url, options), undefined, print.timeout && count >= retries // 只打印最后一次超时的错误,避免太多冗余输出
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
else
|
|
@@ -56,9 +56,10 @@ async function request_retry(url, options, _timeout, retries = 0, count = 0) {
|
|
|
56
56
|
if (error.name === 'TimeoutError')
|
|
57
57
|
if (count < retries) {
|
|
58
58
|
const duration = 2 ** count;
|
|
59
|
-
|
|
59
|
+
if (print.retry)
|
|
60
|
+
console.log(`${t('等待 {{duration}} 秒后重试 request (已尝试 {{_count}} 次) …', { duration, _count: count + 1 }).yellow} ${url.toString().blue.underline}`);
|
|
60
61
|
await delay(1000 * duration);
|
|
61
|
-
return request_retry(url, options, _timeout, retries, count + 1);
|
|
62
|
+
return request_retry(url, options, _timeout, retries, count + 1, print);
|
|
62
63
|
}
|
|
63
64
|
else
|
|
64
65
|
throw Object.assign(new Error(`request 超时: ${url.toString()}`), { name: 'TimeoutError' });
|
|
@@ -72,7 +73,10 @@ export async function request(url, options = {}) {
|
|
|
72
73
|
FormData ??= undici.FormData;
|
|
73
74
|
const { Cookie } = await import('tough-cookie');
|
|
74
75
|
await cookies.init();
|
|
75
|
-
const { queries, headers: _headers, body, type = 'application/json', timeout = 5 * 1000, auth, cookies: _cookies, raw = false, full = false, redirect = 'follow', decode = true,
|
|
76
|
+
const { queries, headers: _headers, body, type = 'application/json', timeout = 5 * 1000, auth, cookies: _cookies, raw = false, full = false, redirect = 'follow', decode = true, print = {
|
|
77
|
+
timeout: true,
|
|
78
|
+
retry: true
|
|
79
|
+
} } = options;
|
|
76
80
|
let { method, retries, encoding, proxy, } = options;
|
|
77
81
|
url = new URL(url);
|
|
78
82
|
if (queries)
|
|
@@ -179,7 +183,7 @@ export async function request(url, options = {}) {
|
|
|
179
183
|
};
|
|
180
184
|
let response;
|
|
181
185
|
try {
|
|
182
|
-
const { statusCode: status, headers: _headers, body: _body } = await request_retry(url, undici_options, timeout, retries);
|
|
186
|
+
const { statusCode: status, headers: _headers, body: _body } = await request_retry(url, undici_options, timeout, retries, 0, print);
|
|
183
187
|
// 处理 cookie,自动保存到 cookie jar
|
|
184
188
|
let _cookies = _headers['set-cookie'] || [];
|
|
185
189
|
if (typeof _cookies === 'string')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xshell",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.203",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"bin": {
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"tslib": "^2.8.1",
|
|
106
106
|
"typescript": "^5.7.2",
|
|
107
107
|
"ua-parser-js": "^2.0.0",
|
|
108
|
-
"undici": "^7.0.0
|
|
108
|
+
"undici": "^7.0.0",
|
|
109
109
|
"vinyl": "^3.0.0",
|
|
110
110
|
"vinyl-fs": "^4.0.0",
|
|
111
111
|
"webpack": "^5.96.1",
|
package/path.d.ts
CHANGED
|
@@ -55,7 +55,7 @@ export declare function extname(path: string): string;
|
|
|
55
55
|
/** `/` */
|
|
56
56
|
export declare const sep = "/";
|
|
57
57
|
/** The platform-specific file delimiter. ';' or ':'. */
|
|
58
|
-
export declare const delimiter: "
|
|
58
|
+
export declare const delimiter: ";" | ":";
|
|
59
59
|
/** Returns an object from a path string - the opposite of format().
|
|
60
60
|
@param path path to evaluate.
|
|
61
61
|
@throws {TypeError} if `path` is not a string. */
|
|
@@ -83,7 +83,7 @@ export declare let path: {
|
|
|
83
83
|
basename: typeof basename;
|
|
84
84
|
extname: typeof extname;
|
|
85
85
|
sep: string;
|
|
86
|
-
delimiter: "
|
|
86
|
+
delimiter: ";" | ":";
|
|
87
87
|
parse: typeof parse;
|
|
88
88
|
format: typeof format;
|
|
89
89
|
toNamespacedPath: typeof toNamespacedPath;
|
package/process.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { type ChildProcess } from 'child_process';
|
|
|
2
2
|
import './prototype.ts';
|
|
3
3
|
import type { Encoding } from './file.ts';
|
|
4
4
|
import type { MyProxy } from './net.ts';
|
|
5
|
-
import { inspect } from './utils.ts';
|
|
6
5
|
export declare const exe_nodejs: string;
|
|
7
6
|
export declare const platform: NodeJS.Platform;
|
|
8
7
|
export declare const username: string;
|
|
@@ -18,35 +17,25 @@ export declare const print_no_command: {
|
|
|
18
17
|
};
|
|
19
18
|
};
|
|
20
19
|
type StdioType = 'pipe' | 'ignore' | 'inherit' | number;
|
|
21
|
-
interface
|
|
22
|
-
|
|
20
|
+
export interface FullPrintOptions {
|
|
21
|
+
stdout: boolean;
|
|
22
|
+
stderr: boolean;
|
|
23
|
+
command: boolean;
|
|
24
|
+
/** 进程执行成功的消息 */
|
|
25
|
+
code: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface BaseOptions {
|
|
23
28
|
cwd?: string;
|
|
24
29
|
/** `process.env` 覆盖/添加到 process.env 的环境变量 */
|
|
25
30
|
envs?: Record<string, string>;
|
|
26
31
|
/** 创建子进程时添加 http_proxy, https_proxy, no_proxy 环境变量以启用代理 */
|
|
27
32
|
proxy?: MyProxy | true;
|
|
28
|
-
/** `'utf-8'` 子进程输出编码 child output encoding */
|
|
29
|
-
encoding?: Encoding | 'binary';
|
|
30
|
-
/** `true` print 选项,支持设置细项 print option (with details) */
|
|
31
|
-
print?: boolean | {
|
|
32
|
-
stdout: boolean;
|
|
33
|
-
stderr: boolean;
|
|
34
|
-
command: boolean;
|
|
35
|
-
/** 进程执行成功的消息 */
|
|
36
|
-
code: boolean;
|
|
37
|
-
};
|
|
38
|
-
/** `'pipe'` 设置为 'ignore' 时忽略 stdio 处理 */
|
|
39
|
-
stdio?: 'pipe' | 'ignore' | [StdioType, StdioType, StdioType];
|
|
40
|
-
/** 启动子进程之后写入到子进程 stdin 中的内容,写完后关闭子进程 stdin (pty 不关闭) */
|
|
41
|
-
input?: string;
|
|
42
33
|
/** 使用文件作为标准输入 */
|
|
43
34
|
fp_stdin?: string;
|
|
44
35
|
/** 使用文件作为标准输出 */
|
|
45
36
|
fp_stdout?: string;
|
|
46
37
|
/** 使用文件作为标准错误 */
|
|
47
38
|
fp_stderr?: string;
|
|
48
|
-
/** `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref) */
|
|
49
|
-
detached?: boolean;
|
|
50
39
|
/** 为 true 时会设置 UV_PROCESS_WINDOWS_HIDE
|
|
51
40
|
然后设置启动进程的参数 CREATE_NO_WINDOW, 和 SW_HIDE
|
|
52
41
|
D:/0/libuv/src/win/process.c
|
|
@@ -59,29 +48,47 @@ interface StartOptions {
|
|
|
59
48
|
具体有什么用还不清楚 */
|
|
60
49
|
window?: boolean;
|
|
61
50
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
51
|
+
export interface StartOptions extends BaseOptions {
|
|
52
|
+
/** `true` 是否打印启动命令行 */
|
|
53
|
+
print?: boolean;
|
|
54
|
+
/** 使用文件作为标准输入 */
|
|
55
|
+
fp_stdin?: string;
|
|
56
|
+
/** 使用文件作为标准输出 */
|
|
57
|
+
fp_stdout?: string;
|
|
58
|
+
/** 使用文件作为标准错误 */
|
|
59
|
+
fp_stderr?: string;
|
|
60
|
+
}
|
|
61
|
+
/** 启动独立的进程,不受当前 node.js 进程退出的影响
|
|
62
|
+
- exe: .exe 路径或文件名 (建议使用完整路径,跳过 path 搜索,性能更高)
|
|
63
|
+
- args?: `[ ]` 参数列表
|
|
64
|
+
- options?:
|
|
65
|
+
- cwd?
|
|
67
66
|
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量,传 null 时可以取消设置该变量
|
|
68
|
-
- encoding?: `'utf-8'` 子进程输出编码
|
|
69
|
-
- print?: `true`
|
|
70
|
-
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
67
|
+
- encoding?: `'utf-8'` 子进程输出编码
|
|
68
|
+
- print?: `true` 是否打印启动命令行
|
|
69
|
+
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
71
70
|
- input?: string, 启动子进程之后写入到子进程 stdin 中的内容,写完后关闭子进程 stdin (pty 不关闭)
|
|
72
|
-
- fp_stdin?: 使用文件作为标准输入,设置 stdio
|
|
73
|
-
- fp_stdout?: 使用文件作为标准输出,设置 stdio
|
|
74
|
-
- fp_stderr?: 使用文件作为标准错误,设置 stdio
|
|
75
|
-
- detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref) */
|
|
71
|
+
- fp_stdin?: 使用文件作为标准输入,设置 stdio 中对应的值
|
|
72
|
+
- fp_stdout?: 使用文件作为标准输出,设置 stdio 中对应的值
|
|
73
|
+
- fp_stderr?: 使用文件作为标准错误,设置 stdio 中对应的值 */
|
|
76
74
|
export declare function start(exe: string, args?: string[], options?: StartOptions): Promise<ChildProcess>;
|
|
77
|
-
export
|
|
78
|
-
|
|
75
|
+
export interface CallOptions extends BaseOptions {
|
|
76
|
+
/** `true` print 选项,支持设置细项 */
|
|
77
|
+
print?: boolean | FullPrintOptions;
|
|
78
|
+
/** `true` code 不为 0 时是否抛出异常 */
|
|
79
79
|
throw_code?: boolean;
|
|
80
|
+
/** `'utf-8'` 子进程输出编码 */
|
|
81
|
+
encoding?: 'binary' | Encoding;
|
|
82
|
+
/** `'pipe'` 设置为 'ignore' 时忽略 stdio 处理 */
|
|
83
|
+
stdio?: 'pipe' | 'ignore' | [StdioType, StdioType, StdioType];
|
|
84
|
+
/** 启动子进程之后写入到子进程 stdin 中的内容,写完后关闭子进程 stdin */
|
|
80
85
|
input?: string;
|
|
86
|
+
/** 实时处理 stdout 和 stderr 的每个 chunk,启用后子进程输出不会自动 print */
|
|
81
87
|
printers?: {
|
|
82
88
|
stdout?: (chunk: string) => void;
|
|
83
89
|
stderr?: (chunk: string) => void;
|
|
84
90
|
};
|
|
91
|
+
/** 可以传入回调函数及时获取通过 start 创建的子进程,便于执行 kill、获得 pid 等操作 */
|
|
85
92
|
on_child?: (child: ChildProcess) => void;
|
|
86
93
|
}
|
|
87
94
|
export interface CallResult<TOutput extends string | Buffer = string> {
|
|
@@ -91,83 +98,63 @@ export interface CallResult<TOutput extends string | Buffer = string> {
|
|
|
91
98
|
code: number | null;
|
|
92
99
|
signal: NodeJS.Signals | null;
|
|
93
100
|
child: ChildProcess;
|
|
94
|
-
[inspect.custom](): string;
|
|
95
101
|
}
|
|
96
|
-
export interface CallError {
|
|
102
|
+
export interface CallError<TOutput extends string | Buffer = string> {
|
|
97
103
|
result: {
|
|
98
104
|
pid: number;
|
|
99
|
-
stdout:
|
|
100
|
-
stderr:
|
|
105
|
+
stdout: TOutput;
|
|
106
|
+
stderr: TOutput;
|
|
101
107
|
code: number;
|
|
102
|
-
signal:
|
|
108
|
+
signal: NodeJS.Signals;
|
|
103
109
|
child: ChildProcess;
|
|
104
110
|
};
|
|
105
111
|
}
|
|
106
|
-
/**
|
|
107
|
-
- exe: .exe 路径或文件名 (建议使用路径,跳过 path 搜索,性能更高)
|
|
108
|
-
- args: `[]` 参数列表
|
|
112
|
+
/** 调用可执行文件,获取返回结果
|
|
113
|
+
- exe: .exe 路径或文件名 (建议使用路径,跳过 path 搜索,性能更高)
|
|
114
|
+
- args: `[ ]` 参数列表
|
|
109
115
|
- options?:
|
|
110
|
-
- cwd
|
|
116
|
+
- cwd?
|
|
111
117
|
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量,传 null 时可以取消设置该变量
|
|
112
118
|
- encoding?: `'utf-8'` 子进程输出编码, 设置为 binary 时返回 stdout, stderr 类型为 Buffer; 否则是 string
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
-
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
- throw_code?: `true` code 不为 0 时是否抛出异常 whether to throw Error when code is not 0
|
|
120
|
-
- on_child: 可以传入回调函数及时获取通过 start 创建的子进程,便于执行 kill、获得 pid 等操作 */
|
|
121
|
-
export declare function call(exe: string, args?: string[]): Promise<CallResult<string>>;
|
|
122
|
-
export declare function call(exe: string, args?: string[], options?: CallOptions & {
|
|
123
|
-
encoding: 'binary';
|
|
124
|
-
}): Promise<CallResult<Buffer>>;
|
|
119
|
+
- print?: `true` print 选项,支持设置细项
|
|
120
|
+
- printers?: 实时处理 stdout 和 stderr 的每个 chunk,启用后子进程输出不会自动 print,且对应的 stdout, stderr 为空
|
|
121
|
+
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
122
|
+
- input?: string, 启动子进程之后写入到子进程 stdin 中的内容,写完后关闭子进程 stdin
|
|
123
|
+
- throw_code?: `true` code 不为 0 时是否抛出异常
|
|
124
|
+
- on_child?: 可以传入回调函数及时获取通过 start 创建的子进程,便于执行 kill、获得 pid 等操作 */
|
|
125
125
|
export declare function call(exe: string, args?: string[], options?: CallOptions): Promise<CallResult<string>>;
|
|
126
126
|
export interface CallNodeJsOptions extends CallOptions {
|
|
127
|
-
inspect?: number;
|
|
127
|
+
inspect?: number | true;
|
|
128
128
|
break?: boolean;
|
|
129
129
|
}
|
|
130
|
-
/**
|
|
131
|
-
- js: .js 路径 (相对路径根据 cwd 解析)
|
|
132
|
-
- args
|
|
133
|
-
- options
|
|
134
|
-
- cwd?: `
|
|
135
|
-
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量
|
|
136
|
-
- encoding?: `'utf-8'` 子进程输出编码
|
|
137
|
-
- print?: `true` print 选项,支持设置细项
|
|
138
|
-
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
139
|
-
- detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref)
|
|
130
|
+
/** 调用 node <js> 并等待结果
|
|
131
|
+
- js: .js 路径 (相对路径根据 cwd 解析)
|
|
132
|
+
- args?: `[ ]` 参数列表
|
|
133
|
+
- options?:
|
|
134
|
+
- cwd?: `'T:/'`
|
|
135
|
+
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量
|
|
136
|
+
- encoding?: `'utf-8'` 子进程输出编码
|
|
137
|
+
- print?: `true` print 选项,支持设置细项
|
|
138
|
+
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
140
139
|
- throw_code?: `true` code 不为 0 时是否抛出异常
|
|
141
|
-
- inspect?: nodejs debugger port
|
|
140
|
+
- inspect?: nodejs debugger port, 填 9229 端口 (或者传 true) 可以用临时配置来调试
|
|
142
141
|
- break?: break at first line */
|
|
143
142
|
export declare function call_nodejs(js: string, args?: string[], { inspect, break: _break, ...options }?: CallNodeJsOptions): Promise<CallResult<string>>;
|
|
144
|
-
export interface
|
|
145
|
-
|
|
146
|
-
cwd?: string;
|
|
147
|
-
/** `true` 打印参数 */
|
|
148
|
-
print?: boolean;
|
|
149
|
-
title?: string;
|
|
150
|
-
/** `process.env` 覆盖/添加到 process.env 的环境变量 */
|
|
151
|
-
envs?: Record<string, string>;
|
|
152
|
-
}
|
|
153
|
-
export declare const exe_winterm: string;
|
|
154
|
-
/** 新建 terminal 窗口执行进程 New Terminal window execution process
|
|
155
|
-
- exe: exe 文件路径 exe file path
|
|
156
|
-
- args: 调用参数 call parameter
|
|
157
|
-
- options?: WinTermOptions */
|
|
158
|
-
export declare function term(exe: string, args?: string[], { cwd, print, title, envs }?: TermOptions): Promise<ChildProcess>;
|
|
159
|
-
export interface TermNodeOptions extends TermOptions {
|
|
160
|
-
/** nodejs debugger port */
|
|
161
|
-
inspect?: number;
|
|
162
|
-
/** break at first line */
|
|
143
|
+
export interface StartNodeJsOptions extends StartOptions {
|
|
144
|
+
inspect?: number | true;
|
|
163
145
|
break?: boolean;
|
|
164
|
-
/** 使用 ts-node 直接运行 use ts-node to run directly */
|
|
165
|
-
tsnode?: boolean;
|
|
166
|
-
/** `false` --experimental-specifier-resolution=node */
|
|
167
|
-
resolve?: boolean;
|
|
168
|
-
/** `false` --trace-warnings */
|
|
169
|
-
trace_warnings?: boolean;
|
|
170
146
|
}
|
|
171
|
-
/**
|
|
172
|
-
|
|
147
|
+
/** 启动 node <js>
|
|
148
|
+
- js: .js 路径 (相对路径根据 cwd 解析)
|
|
149
|
+
- args: `[]` 参数列表
|
|
150
|
+
- options
|
|
151
|
+
- cwd?: `'T:/'`
|
|
152
|
+
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量
|
|
153
|
+
- encoding?: `'utf-8'` 子进程输出编码
|
|
154
|
+
- print?: `true` print 选项,支持设置细项
|
|
155
|
+
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
156
|
+
- detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref)
|
|
157
|
+
- inspect?: nodejs debugger port, 填 9229 端口 (或者传 true) 可以用临时配置来调试
|
|
158
|
+
- break?: break at first line */
|
|
159
|
+
export declare function start_nodejs(js: string, args?: string[], { inspect, break: _break, ...options }?: StartNodeJsOptions): Promise<ChildProcess>;
|
|
173
160
|
export {};
|
package/process.js
CHANGED
|
@@ -1,42 +1,50 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import os from 'os';
|
|
3
|
-
import { t } from "./i18n/instance.js";
|
|
4
3
|
import "./prototype.js";
|
|
5
|
-
import { inspect, DecoderStream, filter_values,
|
|
4
|
+
import { inspect, DecoderStream, filter_values, check } from "./utils.js";
|
|
6
5
|
export const exe_nodejs = process.execPath.fp;
|
|
7
6
|
export const platform = os.platform();
|
|
8
7
|
export const username = os.userInfo().username;
|
|
9
8
|
export const noprint = { print: false };
|
|
10
9
|
export const print_no_command = { print: { command: false, code: false, stdout: true, stderr: true } };
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- encoding?: `'utf-8'` 子进程输出编码 child output encoding
|
|
18
|
-
- print?: `true` print 选项,支持设置细项 print option (with details)
|
|
19
|
-
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理 when 'ignore' then ignore stdio processing
|
|
20
|
-
- input?: string, 启动子进程之后写入到子进程 stdin 中的内容,写完后关闭子进程 stdin (pty 不关闭)
|
|
21
|
-
- fp_stdin?: 使用文件作为标准输入,设置 stdio 中选项为对应的值
|
|
22
|
-
- fp_stdout?: 使用文件作为标准输出,设置 stdio 中选项为对应的值
|
|
23
|
-
- fp_stderr?: 使用文件作为标准错误,设置 stdio 中选项为对应的值
|
|
24
|
-
- detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref) */
|
|
25
|
-
export async function start(exe, args = [], options = {}) {
|
|
26
|
-
const { cwd, encoding = 'utf-8', detached = false, window: _window = true, envs, input, fp_stdin, fp_stdout, fp_stderr } = options;
|
|
27
|
-
let { print = true, stdio = detached ? 'ignore' : 'pipe', proxy } = options;
|
|
10
|
+
async function prepare_spawn(detached, exe, args, { cwd, window: _window = true, envs,
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
input, fp_stdin, fp_stdout, fp_stderr, print = true, proxy,
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
stdio }) {
|
|
15
|
+
// --- 处理 proxy, envs
|
|
28
16
|
if (proxy === true) {
|
|
29
17
|
const { MyProxy } = await import("./net.js");
|
|
30
18
|
proxy = MyProxy.socks5;
|
|
31
19
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
20
|
+
let envs_;
|
|
21
|
+
if (envs || proxy)
|
|
22
|
+
envs_ = filter_values({
|
|
23
|
+
...process.env,
|
|
24
|
+
...proxy ? {
|
|
25
|
+
http_proxy: proxy,
|
|
26
|
+
https_proxy: proxy,
|
|
27
|
+
no_proxy: '127.0.0.1,::1,localhost,192.168.0.0/20,192.168.100.0/24'
|
|
28
|
+
} : {},
|
|
29
|
+
...envs
|
|
30
|
+
});
|
|
31
|
+
// --- 处理 stdio
|
|
32
|
+
if (input && fp_stdin)
|
|
33
|
+
throw new Error('input 和 fp_stdin 不能同时设置');
|
|
36
34
|
let opened_handles = [];
|
|
37
35
|
async function close_all_handles() {
|
|
38
36
|
await Promise.all(opened_handles.map(async (handle) => handle.close()));
|
|
39
37
|
}
|
|
38
|
+
if (Array.isArray(stdio)) {
|
|
39
|
+
if (input)
|
|
40
|
+
check(stdio[0] === 'pipe', '传入 input 时 stdio[0] 应该是 pipe');
|
|
41
|
+
}
|
|
42
|
+
else if (typeof stdio === 'string')
|
|
43
|
+
stdio = [stdio, stdio, stdio];
|
|
44
|
+
else if (detached)
|
|
45
|
+
stdio = ['ignore', 'ignore', 'ignore'];
|
|
46
|
+
else
|
|
47
|
+
stdio = [input ? 'pipe' : 'ignore', 'pipe', 'pipe'];
|
|
40
48
|
if (fp_stdin || fp_stdout || fp_stderr) {
|
|
41
49
|
const { fopen } = await import("./file.js");
|
|
42
50
|
async function open(fp, flags) {
|
|
@@ -59,168 +67,145 @@ export async function start(exe, args = [], options = {}) {
|
|
|
59
67
|
? stdio[1]
|
|
60
68
|
: await open(fp_stderr, 'w');
|
|
61
69
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
shell: false,
|
|
65
|
-
windowsHide: !_window,
|
|
66
|
-
detached,
|
|
67
|
-
stdio,
|
|
68
|
-
...envs || proxy ? {
|
|
69
|
-
env: filter_values({
|
|
70
|
-
...process.env,
|
|
71
|
-
...proxy ? {
|
|
72
|
-
http_proxy: proxy,
|
|
73
|
-
https_proxy: proxy,
|
|
74
|
-
no_proxy: '127.0.0.1,::1,localhost,192.168.0.0/20,192.168.100.0/24'
|
|
75
|
-
} : {},
|
|
76
|
-
...envs
|
|
77
|
-
})
|
|
78
|
-
} : {},
|
|
79
|
-
};
|
|
70
|
+
if (detached)
|
|
71
|
+
check(stdio.every((x) => x === 'ignore' || typeof x === 'number'), '调用 start 时 stdio 只能是 fd 或者 ignore');
|
|
80
72
|
if (typeof print === 'boolean')
|
|
81
73
|
print = {
|
|
82
|
-
stdout: print,
|
|
83
|
-
stderr: print,
|
|
84
74
|
command: print,
|
|
85
75
|
code: print,
|
|
76
|
+
stdout: print,
|
|
77
|
+
stderr: print
|
|
86
78
|
};
|
|
79
|
+
let command;
|
|
87
80
|
if (print.command)
|
|
88
|
-
console.log((
|
|
89
|
-
(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
'')).blue);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
81
|
+
console.log((command =
|
|
82
|
+
(short_exe_names[exe] || exe.quote_if_space()) +
|
|
83
|
+
(args.length
|
|
84
|
+
? ' ' + args
|
|
85
|
+
.map(arg => arg.quote_if_space())
|
|
86
|
+
.join(' ')
|
|
87
|
+
: '')).blue);
|
|
88
|
+
return {
|
|
89
|
+
print,
|
|
90
|
+
command,
|
|
91
|
+
spawn_options: {
|
|
92
|
+
cwd,
|
|
93
|
+
shell: false,
|
|
94
|
+
// processhacker 在 windowsHide 为 true 时不显示窗口
|
|
95
|
+
windowsHide: !_window,
|
|
96
|
+
detached,
|
|
97
|
+
stdio,
|
|
98
|
+
...envs_ ? { env: envs_ } : {}
|
|
99
|
+
},
|
|
100
|
+
close_all_handles: opened_handles.length ? close_all_handles : undefined
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** 启动独立的进程,不受当前 node.js 进程退出的影响
|
|
104
|
+
- exe: .exe 路径或文件名 (建议使用完整路径,跳过 path 搜索,性能更高)
|
|
105
|
+
- args?: `[ ]` 参数列表
|
|
106
|
+
- options?:
|
|
107
|
+
- cwd?
|
|
108
|
+
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量,传 null 时可以取消设置该变量
|
|
109
|
+
- encoding?: `'utf-8'` 子进程输出编码
|
|
110
|
+
- print?: `true` 是否打印启动命令行
|
|
111
|
+
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
112
|
+
- input?: string, 启动子进程之后写入到子进程 stdin 中的内容,写完后关闭子进程 stdin (pty 不关闭)
|
|
113
|
+
- fp_stdin?: 使用文件作为标准输入,设置 stdio 中对应的值
|
|
114
|
+
- fp_stdout?: 使用文件作为标准输出,设置 stdio 中对应的值
|
|
115
|
+
- fp_stderr?: 使用文件作为标准错误,设置 stdio 中对应的值 */
|
|
116
|
+
export async function start(exe, args = [], options = {}) {
|
|
117
|
+
const { spawn_options, close_all_handles } = await prepare_spawn(true, exe, args, options);
|
|
118
|
+
try {
|
|
119
|
+
let child = spawn(exe, args, spawn_options);
|
|
120
|
+
child.unref();
|
|
121
|
+
return child;
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
if (close_all_handles)
|
|
125
|
+
await close_all_handles();
|
|
106
126
|
}
|
|
127
|
+
}
|
|
128
|
+
export async function call(exe, args = [], options = {}) {
|
|
129
|
+
const { print, command, spawn_options, close_all_handles } = await prepare_spawn(false, exe, args, options);
|
|
107
130
|
let child;
|
|
108
131
|
try {
|
|
109
|
-
child = spawn(exe, args,
|
|
132
|
+
child = spawn(exe, args, spawn_options);
|
|
110
133
|
}
|
|
111
|
-
|
|
112
|
-
if (
|
|
134
|
+
finally {
|
|
135
|
+
if (close_all_handles)
|
|
113
136
|
await close_all_handles();
|
|
114
|
-
throw error;
|
|
115
137
|
}
|
|
138
|
+
const { stdio } = spawn_options;
|
|
139
|
+
const { encoding = 'utf-8', input, on_child, printers, throw_code } = options;
|
|
116
140
|
// 防止 child spawn 失败时 crash nodejs 进程
|
|
117
141
|
child.on('error', error => {
|
|
118
142
|
console.error(error);
|
|
119
143
|
});
|
|
120
|
-
if (stdio[0] === 'pipe')
|
|
121
|
-
child.stdin.setDefaultEncoding('
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (encoding === 'utf-8')
|
|
125
|
-
child.stdout.setEncoding('utf-8');
|
|
126
|
-
else
|
|
127
|
-
child.stdout = child.stdout.pipe(new DecoderStream(encoding));
|
|
128
|
-
if (print.stdout)
|
|
129
|
-
child.stdout.pipe(process.stdout, { end: false });
|
|
130
|
-
}
|
|
131
|
-
if (stdio[2] === 'pipe') {
|
|
132
|
-
if (encoding === 'utf-8')
|
|
133
|
-
child.stderr.setEncoding('utf-8');
|
|
134
|
-
else
|
|
135
|
-
child.stderr = child.stderr.pipe(new DecoderStream(encoding));
|
|
136
|
-
if (print.stderr)
|
|
137
|
-
child.stderr.pipe(process.stderr, { end: false });
|
|
138
|
-
}
|
|
144
|
+
if (stdio[0] === 'pipe') {
|
|
145
|
+
child.stdin.setDefaultEncoding('utf-8');
|
|
146
|
+
if (input)
|
|
147
|
+
child.stdin.end(input);
|
|
139
148
|
}
|
|
140
|
-
|
|
141
|
-
child.stdin.end(input);
|
|
142
|
-
if (opened_handles.length)
|
|
143
|
-
await close_all_handles();
|
|
144
|
-
return child;
|
|
145
|
-
}
|
|
146
|
-
export async function start_nodejs(js, args = [], options) {
|
|
147
|
-
return start(exe_nodejs, ['--enable-source-maps', js, ...args], options);
|
|
148
|
-
}
|
|
149
|
-
export async function call(exe, args = [], options = {}) {
|
|
150
|
-
const { encoding = 'utf-8', throw_code = true, printers, on_child } = options;
|
|
151
|
-
let { stdio = 'pipe', print = true } = options;
|
|
152
|
-
if (typeof print === 'boolean')
|
|
153
|
-
print = {
|
|
154
|
-
command: print,
|
|
155
|
-
stdout: print,
|
|
156
|
-
stderr: print,
|
|
157
|
-
code: print,
|
|
158
|
-
};
|
|
159
|
-
if (typeof stdio === 'string')
|
|
160
|
-
stdio = [stdio, stdio, stdio];
|
|
161
|
-
const cmd = (short_exe_names[exe] || exe.quote_if_space()) +
|
|
162
|
-
(args.length ? (' ' + args.map(arg => arg.quote_if_space())
|
|
163
|
-
.join(' '))
|
|
164
|
-
:
|
|
165
|
-
'');
|
|
166
|
-
if (print.command)
|
|
167
|
-
console.log(cmd.blue);
|
|
168
|
-
let child = await start(exe, args, {
|
|
169
|
-
...options,
|
|
170
|
-
print: false,
|
|
171
|
-
});
|
|
172
|
-
on_child?.(child);
|
|
173
|
-
// --- collect output
|
|
149
|
+
// --- 收集进程输出
|
|
174
150
|
let stdouts = [];
|
|
175
151
|
let stderrs = [];
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
(async () => {
|
|
186
|
-
if (stdio[1] === 'pipe')
|
|
187
|
-
for await (const chunk of child.stdout) {
|
|
188
|
-
if (encoding !== 'binary' && print.stdout)
|
|
189
|
-
if (printers?.stdout)
|
|
190
|
-
printers.stdout(chunk);
|
|
191
|
-
else
|
|
192
|
-
process.stdout.write(chunk);
|
|
152
|
+
if (stdio[1] === 'pipe') {
|
|
153
|
+
if (encoding === 'utf-8')
|
|
154
|
+
child.stdout.setEncoding('utf-8');
|
|
155
|
+
else if (encoding !== 'binary')
|
|
156
|
+
child.stdout = child.stdout.pipe(new DecoderStream(encoding));
|
|
157
|
+
child.stdout.on('data', printers?.stdout
|
|
158
|
+
? printers.stdout
|
|
159
|
+
: print.stdout
|
|
160
|
+
? (chunk) => {
|
|
193
161
|
stdouts.push(chunk);
|
|
162
|
+
process.stdout.write(chunk);
|
|
194
163
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
164
|
+
: (chunk) => {
|
|
165
|
+
stdouts.push(chunk);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (stdio[2] === 'pipe') {
|
|
169
|
+
if (encoding === 'utf-8')
|
|
170
|
+
child.stderr.setEncoding('utf-8');
|
|
171
|
+
else if (encoding !== 'binary')
|
|
172
|
+
child.stderr = child.stderr.pipe(new DecoderStream(encoding));
|
|
173
|
+
child.stderr.on('data', printers?.stderr
|
|
174
|
+
? printers.stderr
|
|
175
|
+
: print.stderr
|
|
176
|
+
? (chunk) => {
|
|
204
177
|
stderrs.push(chunk);
|
|
178
|
+
process.stderr.write(chunk);
|
|
205
179
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
180
|
+
: (chunk) => {
|
|
181
|
+
stderrs.push(chunk);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
on_child?.(child);
|
|
185
|
+
let code, signal;
|
|
186
|
+
await new Promise(resolve => {
|
|
187
|
+
child.once('close', (_code, _signal) => {
|
|
188
|
+
code = _code;
|
|
189
|
+
signal = _signal;
|
|
190
|
+
resolve();
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
let message;
|
|
194
|
+
const code_error = throw_code && (code || signal);
|
|
195
|
+
if (print.code || code_error) {
|
|
196
|
+
message = `进程 ${command} ` + (code
|
|
197
|
+
? `${throw_code ? '异常' : ''}结束,退出码: ${code}${signal ? `,信号: ${signal}` : ''}`
|
|
198
|
+
: '正常结束');
|
|
199
|
+
console.log(message[code_error ? 'red' : 'blue']);
|
|
200
|
+
}
|
|
214
201
|
const result = {
|
|
215
202
|
pid: child.pid,
|
|
216
|
-
stdout: encoding === 'binary'
|
|
217
|
-
Buffer.concat(stdouts)
|
|
218
|
-
:
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
:
|
|
223
|
-
stderrs.join(''),
|
|
203
|
+
stdout: encoding === 'binary'
|
|
204
|
+
? Buffer.concat(stdouts)
|
|
205
|
+
: stdouts.join(''),
|
|
206
|
+
stderr: encoding === 'binary'
|
|
207
|
+
? Buffer.concat(stderrs)
|
|
208
|
+
: stderrs.join(''),
|
|
224
209
|
code,
|
|
225
210
|
signal,
|
|
226
211
|
child,
|
|
@@ -228,71 +213,54 @@ export async function call(exe, args = [], options = {}) {
|
|
|
228
213
|
return inspect(this, { omit: ['child'] });
|
|
229
214
|
}
|
|
230
215
|
};
|
|
231
|
-
if (
|
|
232
|
-
|
|
216
|
+
if (code_error) {
|
|
217
|
+
let error = new Error(message);
|
|
218
|
+
error.result = result;
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
233
221
|
return result;
|
|
234
222
|
}
|
|
235
|
-
/**
|
|
236
|
-
- js: .js 路径 (相对路径根据 cwd 解析)
|
|
237
|
-
- args
|
|
238
|
-
- options
|
|
239
|
-
- cwd?: `
|
|
240
|
-
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量
|
|
241
|
-
- encoding?: `'utf-8'` 子进程输出编码
|
|
242
|
-
- print?: `true` print 选项,支持设置细项
|
|
243
|
-
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
244
|
-
- detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref)
|
|
223
|
+
/** 调用 node <js> 并等待结果
|
|
224
|
+
- js: .js 路径 (相对路径根据 cwd 解析)
|
|
225
|
+
- args?: `[ ]` 参数列表
|
|
226
|
+
- options?:
|
|
227
|
+
- cwd?: `'T:/'`
|
|
228
|
+
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量
|
|
229
|
+
- encoding?: `'utf-8'` 子进程输出编码
|
|
230
|
+
- print?: `true` print 选项,支持设置细项
|
|
231
|
+
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
245
232
|
- throw_code?: `true` code 不为 0 时是否抛出异常
|
|
246
|
-
- inspect?: nodejs debugger port
|
|
233
|
+
- inspect?: nodejs debugger port, 填 9229 端口 (或者传 true) 可以用临时配置来调试
|
|
247
234
|
- break?: break at first line */
|
|
248
235
|
export async function call_nodejs(js, args = [], { inspect, break: _break, ...options } = {}) {
|
|
249
236
|
return call(exe_nodejs, [
|
|
250
237
|
'--enable-source-maps',
|
|
251
|
-
...inspect ? [`--inspect${_break ? '-brk' : ''}=localhost:${inspect}`] : [],
|
|
238
|
+
...inspect ? [`--inspect${_break ? '-brk' : ''}=localhost:${inspect === true ? 9229 : inspect}`] : [],
|
|
252
239
|
js,
|
|
253
240
|
...args
|
|
254
241
|
], options);
|
|
255
242
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
-
|
|
259
|
-
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
detached: true,
|
|
271
|
-
cwd,
|
|
272
|
-
envs
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
/** 在 term tab 中创建 node.exe 进程 */
|
|
276
|
-
export async function term_nodejs(fp_js, args = [], { title, inspect, tsnode = false, break: _break, resolve = false, trace_warnings, ...options } = {}) {
|
|
277
|
-
return term(exe_nodejs, [
|
|
243
|
+
/** 启动 node <js>
|
|
244
|
+
- js: .js 路径 (相对路径根据 cwd 解析)
|
|
245
|
+
- args: `[]` 参数列表
|
|
246
|
+
- options
|
|
247
|
+
- cwd?: `'T:/'`
|
|
248
|
+
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量
|
|
249
|
+
- encoding?: `'utf-8'` 子进程输出编码
|
|
250
|
+
- print?: `true` print 选项,支持设置细项
|
|
251
|
+
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
252
|
+
- detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref)
|
|
253
|
+
- inspect?: nodejs debugger port, 填 9229 端口 (或者传 true) 可以用临时配置来调试
|
|
254
|
+
- break?: break at first line */
|
|
255
|
+
export async function start_nodejs(js, args = [], { inspect, break: _break, ...options } = {}) {
|
|
256
|
+
return start(exe_nodejs, [
|
|
278
257
|
'--enable-source-maps',
|
|
279
|
-
...
|
|
280
|
-
|
|
281
|
-
...title ? [`--title=${title}`] : [],
|
|
282
|
-
...inspect ? [`--inspect${_break ? '-brk' : ''}=localhost:${inspect}`] : [],
|
|
283
|
-
...tsnode ? [
|
|
284
|
-
'--loader=ts-node/esm',
|
|
285
|
-
'--experimental-specifier-resolution=node'
|
|
286
|
-
] : [],
|
|
287
|
-
fp_js,
|
|
258
|
+
...inspect ? [`--inspect${_break ? '-brk' : ''}=localhost:${inspect === true ? 9229 : inspect}`] : [],
|
|
259
|
+
js,
|
|
288
260
|
...args
|
|
289
|
-
],
|
|
290
|
-
title,
|
|
291
|
-
...options,
|
|
292
|
-
});
|
|
261
|
+
], options);
|
|
293
262
|
}
|
|
294
263
|
const short_exe_names = {
|
|
295
|
-
[exe_winterm]: 'term',
|
|
296
264
|
[exe_nodejs]: 'node',
|
|
297
265
|
};
|
|
298
266
|
//# sourceMappingURL=process.js.map
|
package/utils.browser.d.ts
CHANGED
|
@@ -81,7 +81,7 @@ export declare function encode(str: string): Uint8Array<ArrayBufferLike>;
|
|
|
81
81
|
在流式处理 (buffer 可能不完整) 时,应使用独立的 TextDecoder 实例调用 decode(buffer, { stream: true }) */
|
|
82
82
|
export declare function decode(buffer: Uint8Array): string;
|
|
83
83
|
/** 字符串字典序比较 */
|
|
84
|
-
export declare function strcmp(l: string, r: string):
|
|
84
|
+
export declare function strcmp(l: string, r: string): 1 | 0 | -1;
|
|
85
85
|
/** 比较 1.10.02 这种版本号
|
|
86
86
|
- l, r: 两个版本号字符串
|
|
87
87
|
- loose?: 宽松模式,允许两个版本号格式(位数)不一致 */
|
package/utils.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ export declare function filter_values<TObj extends Record<string, any>>(obj: TOb
|
|
|
44
44
|
/** 忽略对象中的 keys, 返回新对象 */
|
|
45
45
|
export declare function omit<TObj>(obj: TObj, omit_keys: string[]): TObj;
|
|
46
46
|
/** 字符串字典序比较 */
|
|
47
|
-
export declare function strcmp(l: string, r: string):
|
|
47
|
+
export declare function strcmp(l: string, r: string): 1 | 0 | -1;
|
|
48
48
|
/** 比较 1.10.02 这种版本号
|
|
49
49
|
- l, r: 两个版本号字符串
|
|
50
50
|
- loose?: 宽松模式,允许两个版本号格式(位数)不一致 */
|