xshell 1.1.19 → 1.1.21
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/apps.d.ts +0 -41
- package/apps.js +0 -74
- package/builder.js +15 -4
- package/file.d.ts +2 -1
- package/file.js +28 -2
- package/git.d.ts +2 -2
- package/git.js +3 -3
- package/net.browser.js +1 -1
- package/net.js +1 -1
- package/package.json +2 -4
- package/path.d.ts +2 -2
- package/process.d.ts +66 -49
- package/process.js +93 -112
- package/server.js +4 -5
- package/utils.browser.d.ts +2 -1
- package/utils.browser.js +2 -1
- package/utils.d.ts +2 -1
- package/utils.js +2 -1
package/apps.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { Readable } from 'stream';
|
|
2
|
-
import type OSS from 'ali-oss';
|
|
3
1
|
import { type CallOptions } from './process.ts';
|
|
4
2
|
export declare let npm: {
|
|
5
3
|
bin: string;
|
|
@@ -17,42 +15,3 @@ export declare let npm: {
|
|
|
17
15
|
break?: boolean;
|
|
18
16
|
}): Promise<void>;
|
|
19
17
|
};
|
|
20
|
-
/** 使用 tsc 编译项目
|
|
21
|
-
- fpd: 项目目录
|
|
22
|
-
- options?:
|
|
23
|
-
- tsconfig?: `'<dir>/tsconfig.json'`
|
|
24
|
-
- typecheck?: `false` 是否只进行 typecheck, (使用 call_node 执行而非 term) */
|
|
25
|
-
export declare function tsc(fpd: string, { tsconfig, typecheck, }?: {
|
|
26
|
-
tsconfig?: string;
|
|
27
|
-
typecheck?: boolean;
|
|
28
|
-
}): Promise<import("./process.ts").CallResult<string>>;
|
|
29
|
-
export declare let oss: {
|
|
30
|
-
client: OSS;
|
|
31
|
-
bucket: string;
|
|
32
|
-
region: string;
|
|
33
|
-
fpd_cdn: string;
|
|
34
|
-
fpd_oss: string;
|
|
35
|
-
init({ bucket, region, fpd_cdn, fpd_oss, access_id, access_key }: {
|
|
36
|
-
bucket: string;
|
|
37
|
-
region: string;
|
|
38
|
-
fpd_cdn: string;
|
|
39
|
-
fpd_oss: string;
|
|
40
|
-
access_id: string;
|
|
41
|
-
access_key: string;
|
|
42
|
-
}): Promise<void>;
|
|
43
|
-
/** 上传文件到 oss,返回文件 url
|
|
44
|
-
- fp: 上传到 oss 的路径, 如 assets/web.latest.zip
|
|
45
|
-
- data: 文件 (Uint8Array) | 本地文件完整路径 (string) | ReadableStream
|
|
46
|
-
- options?:
|
|
47
|
-
- private?: `false` 设置为私有,需要通过 URL 签名参数访问
|
|
48
|
-
- print?: `true` 打印消息
|
|
49
|
-
- cdn?: `false` false 时返回 oss 链接,true 时返回 cdn 链接
|
|
50
|
-
- copy?: `false` 是否复制到剪贴板 */
|
|
51
|
-
upload(fp_remote: string, data: Uint8Array | string | Readable, { private: _private, print, cdn, }?: {
|
|
52
|
-
private?: boolean;
|
|
53
|
-
print?: boolean;
|
|
54
|
-
cdn?: boolean;
|
|
55
|
-
}): Promise<string>;
|
|
56
|
-
/** 获取经过签名后可访问的 url */
|
|
57
|
-
get_url(fp: string): Promise<string>;
|
|
58
|
-
};
|
package/apps.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import util from 'util';
|
|
2
2
|
import { call_nodejs, platform, username } from "./process.js";
|
|
3
|
-
import { check } from "./utils.js";
|
|
4
|
-
import { path } from "./path.js";
|
|
5
3
|
export let npm = {
|
|
6
4
|
bin: platform == 'win32' ? `C:/Users/${username}/AppData/Roaming/npm/node_modules/pnpm/bin/pnpm.cjs` : '/usr/bin/pnpm',
|
|
7
5
|
async call(cwd, bin, args, options) {
|
|
@@ -23,76 +21,4 @@ export let npm = {
|
|
|
23
21
|
await this.call(cwd, this.bin, args);
|
|
24
22
|
},
|
|
25
23
|
};
|
|
26
|
-
/** 使用 tsc 编译项目
|
|
27
|
-
- fpd: 项目目录
|
|
28
|
-
- options?:
|
|
29
|
-
- tsconfig?: `'<dir>/tsconfig.json'`
|
|
30
|
-
- typecheck?: `false` 是否只进行 typecheck, (使用 call_node 执行而非 term) */
|
|
31
|
-
export async function tsc(fpd, { tsconfig = './tsconfig.json', typecheck = false, } = {}) {
|
|
32
|
-
return call_nodejs(`${fpd}/node_modules/typescript/bin/tsc`, [
|
|
33
|
-
'--project', tsconfig,
|
|
34
|
-
...typecheck ? ['--noEmit'] : []
|
|
35
|
-
], {
|
|
36
|
-
cwd: fpd,
|
|
37
|
-
print: { command: false, code: false, stdout: true, stderr: true }
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
export let oss = {
|
|
41
|
-
client: null,
|
|
42
|
-
bucket: null,
|
|
43
|
-
region: null,
|
|
44
|
-
fpd_cdn: null,
|
|
45
|
-
fpd_oss: null,
|
|
46
|
-
async init({ bucket, region, fpd_cdn, fpd_oss, access_id, access_key }) {
|
|
47
|
-
if (this.client)
|
|
48
|
-
return;
|
|
49
|
-
const OSS = (await import('ali-oss')).default;
|
|
50
|
-
this.bucket = bucket;
|
|
51
|
-
this.region = region;
|
|
52
|
-
this.fpd_cdn = fpd_cdn;
|
|
53
|
-
this.fpd_oss = fpd_oss;
|
|
54
|
-
this.client = new OSS({
|
|
55
|
-
accessKeyId: access_id,
|
|
56
|
-
accessKeySecret: access_key,
|
|
57
|
-
region: this.region,
|
|
58
|
-
bucket: this.bucket,
|
|
59
|
-
secure: true
|
|
60
|
-
});
|
|
61
|
-
},
|
|
62
|
-
/** 上传文件到 oss,返回文件 url
|
|
63
|
-
- fp: 上传到 oss 的路径, 如 assets/web.latest.zip
|
|
64
|
-
- data: 文件 (Uint8Array) | 本地文件完整路径 (string) | ReadableStream
|
|
65
|
-
- options?:
|
|
66
|
-
- private?: `false` 设置为私有,需要通过 URL 签名参数访问
|
|
67
|
-
- print?: `true` 打印消息
|
|
68
|
-
- cdn?: `false` false 时返回 oss 链接,true 时返回 cdn 链接
|
|
69
|
-
- copy?: `false` 是否复制到剪贴板 */
|
|
70
|
-
async upload(fp_remote, data, { private: _private = false, print = true, cdn = false, } = {}) {
|
|
71
|
-
check(this.client, 'OSS 应该已经初始化了');
|
|
72
|
-
check(!fp_remote.startsWith('/'), 'fp 不能以 / 开头');
|
|
73
|
-
check(!fp_remote.isdir, '不能使用 oss.upload 上传文件夹,请使用 oss.upload_dir');
|
|
74
|
-
if (typeof data === 'string')
|
|
75
|
-
check(path.isAbsolute(data), 'oss.upload 传入 data 参数类型为 string 时,必须为本地文件完整路径');
|
|
76
|
-
if (data instanceof Uint8Array && !Buffer.isBuffer(data))
|
|
77
|
-
data = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
78
|
-
await this.client.put(fp_remote, data);
|
|
79
|
-
let url;
|
|
80
|
-
if (_private) {
|
|
81
|
-
await this.client.putACL(fp_remote, 'private');
|
|
82
|
-
url = await this.get_url(fp_remote);
|
|
83
|
-
}
|
|
84
|
-
else
|
|
85
|
-
url = new URL(`${cdn ? this.fpd_cdn : this.fpd_oss}${fp_remote}`).toString();
|
|
86
|
-
if (print)
|
|
87
|
-
console.log(`已上传到 oss${_private ? ' (私有)' : ''}:`, url);
|
|
88
|
-
return url;
|
|
89
|
-
},
|
|
90
|
-
/** 获取经过签名后可访问的 url */
|
|
91
|
-
async get_url(fp) {
|
|
92
|
-
check(this.client, 'OSS 应该已经初始化了');
|
|
93
|
-
const url = new URL(this.client.signatureUrl(fp, { expires: /* 十年 */ 3600 * 24 * 365 * 10 }));
|
|
94
|
-
const url_ = `${this.fpd_cdn}${url.pathname.slice(1)}${url.search}`;
|
|
95
|
-
return url_;
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
24
|
//# sourceMappingURL=apps.js.map
|
package/builder.js
CHANGED
|
@@ -386,10 +386,21 @@ export class Bundler {
|
|
|
386
386
|
...target === 'nodejs' ? [
|
|
387
387
|
/Can't resolve '(bufferutil|utf-8-validate)'/,
|
|
388
388
|
// 打包 ali-oss 时可能的报错
|
|
389
|
-
(warning) =>
|
|
390
|
-
(warning
|
|
391
|
-
|
|
392
|
-
|
|
389
|
+
(warning) => {
|
|
390
|
+
if (!warning)
|
|
391
|
+
return false;
|
|
392
|
+
const { message, module } = warning;
|
|
393
|
+
if (!message)
|
|
394
|
+
return false;
|
|
395
|
+
const fp = module?.context?.fp || '';
|
|
396
|
+
if (message.includes('the request of a dependency is an expression'))
|
|
397
|
+
return fp.endsWith('any-promise') ||
|
|
398
|
+
fp.includes('/@sqltools/base-driver/');
|
|
399
|
+
else if (message.includes('require function is used in a way in which dependencies cannot be statically extracted'))
|
|
400
|
+
return fp.includes('/vscode-languageserver-types/');
|
|
401
|
+
else
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
393
404
|
] : [],
|
|
394
405
|
],
|
|
395
406
|
performance: {
|
package/file.d.ts
CHANGED
|
@@ -84,6 +84,7 @@ export interface FListOptions {
|
|
|
84
84
|
absolute?: boolean;
|
|
85
85
|
print?: boolean;
|
|
86
86
|
stats?: boolean;
|
|
87
|
+
best_effort?: boolean;
|
|
87
88
|
}
|
|
88
89
|
/**
|
|
89
90
|
- fpd: 文件夹完整路径 absolute path of directory
|
|
@@ -94,7 +95,7 @@ export interface FListOptions {
|
|
|
94
95
|
- filter?: `() => true` RegExp | (fp: string) => any
|
|
95
96
|
注意当 deep = true 时被 filter 过滤掉的目录及目录中的文件不会包含在结果中
|
|
96
97
|
- stats?: `false` 启用后返回 FStats 列表
|
|
97
|
-
|
|
98
|
+
- best_effort?: `false` 启用后,当遇到 stat 软链接文件不存在等错误时,会返回一个 fake_time FStats 文件,而不是抛出错误 */
|
|
98
99
|
export declare function flist(fpd: string): Promise<string[]>;
|
|
99
100
|
export declare function flist(fpd: string, options?: FListOptions & {
|
|
100
101
|
stats: true;
|
package/file.js
CHANGED
|
@@ -119,8 +119,25 @@ export async function fappend(fp, data, { print = true } = {}) {
|
|
|
119
119
|
throw error;
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
+
const fake_time = new Date(0);
|
|
123
|
+
const fake_stats = {
|
|
124
|
+
fp: '',
|
|
125
|
+
size: 0n,
|
|
126
|
+
atimeNs: 0n,
|
|
127
|
+
mtimeNs: 0n,
|
|
128
|
+
ctimeNs: 0n,
|
|
129
|
+
birthtimeNs: 0n,
|
|
130
|
+
atimeMs: 0n,
|
|
131
|
+
mtimeMs: 0n,
|
|
132
|
+
ctimeMs: 0n,
|
|
133
|
+
birthtimeMs: 0n,
|
|
134
|
+
mtime: fake_time,
|
|
135
|
+
atime: fake_time,
|
|
136
|
+
ctime: fake_time,
|
|
137
|
+
birthtime: fake_time,
|
|
138
|
+
};
|
|
122
139
|
export async function flist(fpd, options = {}) {
|
|
123
|
-
const { filter, deep = false, absolute = false, print = true, stats = false } = options;
|
|
140
|
+
const { filter, deep = false, absolute = false, print = true, stats = false, best_effort = false } = options;
|
|
124
141
|
check(path.isAbsolute(fpd), t("flist: 参数 fpd: '{{fpd}}' 必须是绝对路径", { fpd }));
|
|
125
142
|
check(fpd.isdir, t("flist: 参数 fpd: '{{fpd}}' 必须以 / 结尾", { fpd }));
|
|
126
143
|
if (!path.isAbsolute(fpd))
|
|
@@ -148,7 +165,16 @@ export async function flist(fpd, options = {}) {
|
|
|
148
165
|
fps.push(fp);
|
|
149
166
|
}
|
|
150
167
|
async function _fstat(fp) {
|
|
151
|
-
let _stats
|
|
168
|
+
let _stats;
|
|
169
|
+
try {
|
|
170
|
+
_stats = await fstat(absolute ? fp : fpd + fp);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (best_effort)
|
|
174
|
+
_stats = { ...fake_stats };
|
|
175
|
+
else
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
152
178
|
if (!absolute)
|
|
153
179
|
_stats.fp = fp;
|
|
154
180
|
return _stats;
|
package/git.d.ts
CHANGED
|
@@ -5,10 +5,10 @@ export declare class Git {
|
|
|
5
5
|
constructor(cwd: string);
|
|
6
6
|
static init(cwd: string, print?: boolean): Promise<Git>;
|
|
7
7
|
static clone(repo: string, fpd: string, shallow?: boolean | string): Promise<Git>;
|
|
8
|
-
call(args?: any[], { color, print,
|
|
8
|
+
call(args?: any[], { color, print, on_stderr, throw_code, }?: {
|
|
9
9
|
color?: boolean;
|
|
10
10
|
print?: CallOptions['print'];
|
|
11
|
-
|
|
11
|
+
on_stderr?: CallOptions['on_stderr'];
|
|
12
12
|
throw_code?: CallOptions['throw_code'];
|
|
13
13
|
}): Promise<import("./process.ts").CallResult<string>>;
|
|
14
14
|
get_branch(): Promise<string>;
|
package/git.js
CHANGED
|
@@ -23,7 +23,7 @@ export class Git {
|
|
|
23
23
|
]);
|
|
24
24
|
return git;
|
|
25
25
|
}
|
|
26
|
-
async call(args = [], { color = true, print,
|
|
26
|
+
async call(args = [], { color = true, print, on_stderr, throw_code, } = {}) {
|
|
27
27
|
return call(Git.exe, [
|
|
28
28
|
...color ? [] : [
|
|
29
29
|
'-c', 'color.status=false',
|
|
@@ -35,8 +35,8 @@ export class Git {
|
|
|
35
35
|
], {
|
|
36
36
|
cwd: this.cwd,
|
|
37
37
|
print,
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
throw_code,
|
|
39
|
+
on_stderr
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
async get_branch() {
|
package/net.browser.js
CHANGED
package/net.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xshell",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"bin": {
|
|
@@ -64,7 +64,6 @@
|
|
|
64
64
|
"@xterm/addon-web-links": "^0.11.0",
|
|
65
65
|
"@xterm/addon-webgl": "^0.18.0",
|
|
66
66
|
"@xterm/xterm": "^5.5.0",
|
|
67
|
-
"ali-oss": "^6.22.0",
|
|
68
67
|
"archiver": "^7.0.1",
|
|
69
68
|
"chalk": "^5.4.1",
|
|
70
69
|
"chardet": "^2.0.0",
|
|
@@ -90,7 +89,7 @@
|
|
|
90
89
|
"mime-types": "^2.1.35",
|
|
91
90
|
"ora": "^8.1.1",
|
|
92
91
|
"react": "^19.0.0",
|
|
93
|
-
"react-i18next": "^15.
|
|
92
|
+
"react-i18next": "^15.3.0",
|
|
94
93
|
"react-object-model": "^1.2.21",
|
|
95
94
|
"resolve-path": "^1.4.0",
|
|
96
95
|
"sass": "^1.83.0",
|
|
@@ -113,7 +112,6 @@
|
|
|
113
112
|
},
|
|
114
113
|
"devDependencies": {
|
|
115
114
|
"@babel/types": "^7.26.3",
|
|
116
|
-
"@types/ali-oss": "^6.16.11",
|
|
117
115
|
"@types/archiver": "^6.0.3",
|
|
118
116
|
"@types/babel__traverse": "^7.20.6",
|
|
119
117
|
"@types/chardet": "^0.8.3",
|
package/path.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ export declare function extname(path: string): string;
|
|
|
54
54
|
/** `/` */
|
|
55
55
|
export declare const sep = "/";
|
|
56
56
|
/** The platform-specific file delimiter. ';' or ':'. */
|
|
57
|
-
export declare const delimiter: "
|
|
57
|
+
export declare const delimiter: ";" | ":";
|
|
58
58
|
/** Returns an object from a path string - the opposite of format().
|
|
59
59
|
@param path path to evaluate.
|
|
60
60
|
@throws {TypeError} if `path` is not a string. */
|
|
@@ -81,7 +81,7 @@ export declare let path: {
|
|
|
81
81
|
basename: typeof basename;
|
|
82
82
|
extname: typeof extname;
|
|
83
83
|
sep: string;
|
|
84
|
-
delimiter: "
|
|
84
|
+
delimiter: ";" | ":";
|
|
85
85
|
parse: typeof parse;
|
|
86
86
|
format: typeof format;
|
|
87
87
|
toNamespacedPath: typeof toNamespacedPath;
|
package/process.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { InspectOptions } from 'util';
|
|
2
2
|
import { type ChildProcess } from 'child_process';
|
|
3
3
|
import './prototype.ts';
|
|
4
|
-
import type
|
|
4
|
+
import { type Encoding } from './file.ts';
|
|
5
5
|
import type { MyProxy } from './net.ts';
|
|
6
6
|
export declare const sea: boolean;
|
|
7
7
|
export declare const exe_nodejs: string;
|
|
@@ -18,7 +18,6 @@ export declare const print_no_command: {
|
|
|
18
18
|
readonly stderr: true;
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
|
-
type StdioType = 'pipe' | 'ignore' | 'inherit' | number;
|
|
22
21
|
export interface FullPrintOptions {
|
|
23
22
|
stdout: boolean;
|
|
24
23
|
stderr: boolean;
|
|
@@ -32,13 +31,25 @@ interface BaseOptions {
|
|
|
32
31
|
envs?: Record<string, string>;
|
|
33
32
|
/** 创建子进程时添加 http_proxy, https_proxy, no_proxy 环境变量以启用代理 */
|
|
34
33
|
proxy?: MyProxy | true;
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
/** 控制子进程 stdin,默认为 `false` (读空设备),除非传入了 {@link CallOptions.input} 属性
|
|
35
|
+
- 默认值:
|
|
36
|
+
- start(): false ('ignore', 空设备)
|
|
37
|
+
- (call|launch)(): true (pipe, 作为 child.stdout 可读流)
|
|
38
|
+
- `true` 设置子进程 stdin 为 'pipe'
|
|
39
|
+
- `false` 设置子进程 stdin 为 'ignore' (空设备)
|
|
40
|
+
- `string` 设置子进程 stdin 为某个文件路径 (打开文件,将句柄设置为子进程 stdin) */
|
|
41
|
+
stdin?: boolean | string;
|
|
42
|
+
/** 控制子进程 stdout
|
|
43
|
+
- 默认值:
|
|
44
|
+
- start(): false ('ignore', 空设备)
|
|
45
|
+
- (call|launch)(): true (pipe, 作为 child.stdout 可读流)
|
|
46
|
+
- `true` 设置子进程 stdout 为 'pipe' (作为 child.stdout 可读流)
|
|
47
|
+
- `false` 设置子进程 stdout 为 'ignore' (空设备)
|
|
48
|
+
- `string` 设置子进程 stdout 某个文件路径 (打开文件,将句柄设置为子进程 stdout) */
|
|
49
|
+
stdout?: boolean | string;
|
|
50
|
+
/** 控制子进程 stderr,默认为 `stdout` 的值,用法同 {@link BaseOptions.stdout} */
|
|
51
|
+
stderr?: boolean | string;
|
|
52
|
+
/** 默认为 false,不显示窗口,会设置 UV_PROCESS_WINDOWS_HIDE
|
|
42
53
|
然后设置启动进程的参数 CREATE_NO_WINDOW, 和 SW_HIDE
|
|
43
54
|
D:/0/libuv/src/win/process.c
|
|
44
55
|
CREATE_NO_WINDOW:
|
|
@@ -55,12 +66,6 @@ interface BaseOptions {
|
|
|
55
66
|
export interface StartOptions extends BaseOptions {
|
|
56
67
|
/** `true` 是否打印启动命令行 */
|
|
57
68
|
print?: boolean;
|
|
58
|
-
/** 使用文件作为标准输入 */
|
|
59
|
-
fp_stdin?: string;
|
|
60
|
-
/** 使用文件作为标准输出 */
|
|
61
|
-
fp_stdout?: string;
|
|
62
|
-
/** 使用文件作为标准错误 */
|
|
63
|
-
fp_stderr?: string;
|
|
64
69
|
}
|
|
65
70
|
export declare function get_command(exe: string, args?: string[]): string;
|
|
66
71
|
export interface SubProcess<TOutput extends string | Buffer = string> extends ChildProcess {
|
|
@@ -72,48 +77,44 @@ export interface SubProcess<TOutput extends string | Buffer = string> extends Ch
|
|
|
72
77
|
args: string[];
|
|
73
78
|
/** 启动命令 */
|
|
74
79
|
command: string;
|
|
75
|
-
/** 调用 call 的 Promise
|
|
76
|
-
presult
|
|
80
|
+
/** 调用 call 的 Promise 结果,只有通过 launch 启动的进程有 */
|
|
81
|
+
presult?: Promise<CallResult<TOutput>>;
|
|
77
82
|
/** 是否还在运行 */
|
|
78
83
|
get running(): boolean;
|
|
79
84
|
/** 是否已结束,等价于 !running */
|
|
80
85
|
get finished(): boolean;
|
|
81
86
|
}
|
|
82
|
-
/** 启动独立 (detached) 的进程,不受当前 node.js
|
|
83
|
-
使用 windowsHide 选项避免创建命令行窗口
|
|
87
|
+
/** 使用 exe 启动独立 (detached) 的进程,不受当前 node.js 进程退出的影响,可重定向 stdio 到文件(默认直接忽略)
|
|
84
88
|
- exe: .exe 路径或文件名 (建议使用完整路径,跳过 path 搜索,性能更高)
|
|
85
89
|
- args?: `[ ]` 参数列表
|
|
86
|
-
- options?:
|
|
87
|
-
- cwd
|
|
90
|
+
- options?: {@link StartOptions} 继承自 {@link BaseOptions}
|
|
91
|
+
- cwd?: `'T:/'`
|
|
88
92
|
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量,传 null 时可以取消设置该变量
|
|
89
|
-
-
|
|
93
|
+
- proxy?: 创建子进程时添加 http_proxy, https_proxy, no_proxy 环境变量以启用代理
|
|
90
94
|
- print?: `true` 是否打印启动命令行
|
|
91
|
-
-
|
|
92
|
-
|
|
93
|
-
-
|
|
94
|
-
|
|
95
|
+
- stdin?: 控制子进程 stdin,默认为 `false` ('ignore', 读空设备)
|
|
96
|
+
可传入 string,设置子进程 stdin 为某个文件路径 (打开文件,将句柄设置为子进程 stdin)
|
|
97
|
+
- stdout?: 控制子进程 stdout,默认为 `false` ('ignore', 写空设备)
|
|
98
|
+
可传入 string,设置子进程 stdout 某个文件路径 (打开文件,将句柄设置为子进程 stdout)
|
|
99
|
+
- stderr?: 控制子进程 stderr,默认为 `stdout` 的值,用法同 stdout
|
|
100
|
+
- window?: 默认为 false,不显示窗口,设置启动进程的参数 CREATE_NO_WINDOW, 和 SW_HIDE
|
|
101
|
+
- title?: 由创建进程的调用者设置的,用于区分、识别、记忆的可选名称 */
|
|
95
102
|
export declare function start(exe: string, args?: string[], options?: StartOptions): Promise<SubProcess>;
|
|
96
103
|
export interface CallOptions extends BaseOptions {
|
|
97
104
|
/** `true` print 选项,支持设置细项 */
|
|
98
|
-
print?: boolean | FullPrintOptions
|
|
105
|
+
print?: boolean | Partial<FullPrintOptions>;
|
|
99
106
|
/** `true` code 不为 0 时是否抛出异常 */
|
|
100
107
|
throw_code?: boolean;
|
|
101
|
-
/** `'utf-8'`
|
|
108
|
+
/** `'utf-8'` 子进程输出编码,不传 'binary' 则 stdout, stderr 为 string 流 */
|
|
102
109
|
encoding?: 'binary' | Encoding;
|
|
103
|
-
/**
|
|
104
|
-
stdio?: 'pipe' | 'ignore' | [StdioType, StdioType, StdioType];
|
|
105
|
-
/** `false` 子进程是否可能会读取 stdin
|
|
106
|
-
设置为 true 时会设置子进程 stdin 为 'pipe', 否则为 'ignore' */
|
|
107
|
-
stdin?: boolean;
|
|
108
|
-
/** 启动子进程之后写入到子进程 stdin 中的内容,写完后关闭子进程 stdin */
|
|
110
|
+
/** 启动子进程之后写入到子进程 stdin 中的内容,写完后就关闭子进程 stdin,通知子进程处理 */
|
|
109
111
|
input?: string;
|
|
110
|
-
/** 实时处理 stdout 和 stderr 的每个 chunk,启用后子进程输出不会自动 print */
|
|
111
|
-
printers?: {
|
|
112
|
-
stdout?: (chunk: string) => void;
|
|
113
|
-
stderr?: (chunk: string) => void;
|
|
114
|
-
};
|
|
115
112
|
/** 可以传入回调函数及时获取通过 start 创建的子进程,便于执行 kill、获得 pid 等操作 */
|
|
116
|
-
on_child
|
|
113
|
+
on_child?(child: SubProcess): void;
|
|
114
|
+
/** 实时处理 stdout 的每个 chunk,设置后子进程输出不会自动 print,且 CallResult 中 stdout 属性为 '' */
|
|
115
|
+
on_stdout?(chunk: string): void;
|
|
116
|
+
/** 实时处理 stderr 的每个 chunk,设置后子进程输出不会自动 print,且 CallResult 中 stderr 属性为 '' */
|
|
117
|
+
on_stderr?(chunk: string): void;
|
|
117
118
|
}
|
|
118
119
|
export interface CallResult<TOutput extends string | Buffer = string> {
|
|
119
120
|
pid: number;
|
|
@@ -142,18 +143,34 @@ export declare class CallError<TOutput extends string | Buffer = string> extends
|
|
|
142
143
|
[inspect.custom](depth: number, options: InspectOptions, inspect: Function): string;
|
|
143
144
|
}
|
|
144
145
|
/** 调用 exe 启动子进程,等待并获取返回结果,错误时抛出 CallError
|
|
145
|
-
- exe:
|
|
146
|
-
- args
|
|
147
|
-
- options?:
|
|
148
|
-
- cwd
|
|
149
|
-
- print?: `true` print 选项,支持设置细项
|
|
146
|
+
- exe: exe 路径或文件名 (建议使用路径,跳过 path 搜索,性能更高)
|
|
147
|
+
- args?: `[ ]` 参数列表
|
|
148
|
+
- options?: {@link CallOptions} 继承自 {@link BaseOptions}
|
|
149
|
+
- cwd?: `'T:/'`
|
|
150
|
+
- print?: `true` print 选项,支持设置细项 {@link FullPrintOptions}
|
|
151
|
+
- command?: `true` 打印启动命令行
|
|
152
|
+
- code?: `true` 打印进程执行成功的消息 (进程 ... 正常结束)
|
|
153
|
+
- stdout?: `true` 打印 stdout
|
|
154
|
+
- stderr?: `true` 打印 stderr
|
|
150
155
|
- throw_code?: `true` code 不为 0 时是否抛出异常
|
|
151
156
|
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量,传 null 时可以取消设置该变量
|
|
152
|
-
-
|
|
153
|
-
- printers?: 实时处理 stdout 和 stderr 的每个 chunk,启用后子进程输出不会自动 print,且对应的 stdout, stderr 为空
|
|
154
|
-
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理
|
|
157
|
+
- proxy?: 创建子进程时添加 http_proxy, https_proxy, no_proxy 环境变量以启用代理
|
|
155
158
|
- input?: string, 启动子进程之后写入到子进程 stdin 中的内容,写完后关闭子进程 stdin
|
|
156
|
-
-
|
|
159
|
+
- stdin?: 控制子进程 stdin,默认为 `false` (读空设备),除非传入了 {@link CallOptions.input} 属性
|
|
160
|
+
- `true` 设置子进程 stdin 为 'pipe'
|
|
161
|
+
- `false` 设置子进程 stdin 为 'ignore' (空设备)
|
|
162
|
+
- `string` 设置子进程 stdin 为某个文件路径 (打开文件,将句柄设置为子进程 stdin)
|
|
163
|
+
- stdout?: 控制子进程 stdout,默认为 `true` (pipe, 作为 child.stdout 可读流)
|
|
164
|
+
- `true` 设置子进程 stdout 为 'pipe' (作为 child.stdout 可读流)
|
|
165
|
+
- `false` 设置子进程 stdout 为 'ignore' (空设备)
|
|
166
|
+
- `string` 设置子进程 stdout 某个文件路径 (打开文件,将句柄设置为子进程 stdout)
|
|
167
|
+
- stderr?: 控制子进程 stderr,用法同 {@link BaseOptions.stdout}
|
|
168
|
+
- window?: 默认为 false,不显示窗口,设置启动进程的参数 CREATE_NO_WINDOW, 和 SW_HIDE
|
|
169
|
+
- title?: 由创建进程的调用者设置的,用于区分、识别、记忆的可选名称
|
|
170
|
+
- encoding?: `'utf-8'` 子进程输出编码, 设置为 binary 时返回 stdout, stderr 类型为 Buffer; 否则是 string
|
|
171
|
+
- on_child?: 可以传入回调函数及时获取通过 spawn 创建的子进程,便于执行 kill、获得 pid 等操作
|
|
172
|
+
- on_stdout?: 实时处理 stdout 的每个 chunk,设置后子进程输出不会自动 print,且 CallResult 中 stdout 属性为 ''
|
|
173
|
+
- on_stderr?: 实时处理 stderr 的每个 chunk,设置后子进程输出不会自动 print,且 CallResult 中 stderr 属性为 '' */
|
|
157
174
|
export declare function call(exe: string, args: string[], options: CallOptions & {
|
|
158
175
|
encoding: 'binary';
|
|
159
176
|
}): Promise<CallResult<Buffer>>;
|
package/process.js
CHANGED
|
@@ -2,6 +2,7 @@ import { spawn } from 'child_process';
|
|
|
2
2
|
import os from 'os';
|
|
3
3
|
import node_sea from 'node:sea';
|
|
4
4
|
import "./prototype.js";
|
|
5
|
+
import { fopen } from "./file.js";
|
|
5
6
|
import { inspect, DecoderStream, filter_values, check, colored, timeout } from "./utils.js";
|
|
6
7
|
export const sea = node_sea.isSea();
|
|
7
8
|
export const exe_nodejs = process.execPath.fp;
|
|
@@ -15,13 +16,9 @@ export function get_command(exe, args) {
|
|
|
15
16
|
? ` ${args.map(arg => arg.quote_if_space()).join(' ')}`
|
|
16
17
|
: '');
|
|
17
18
|
}
|
|
18
|
-
async function prepare_spawn(detached, exe, args, { cwd, window: _window, envs,
|
|
19
|
+
async function prepare_spawn(detached, exe, args, { cwd, window: _window = false, envs,
|
|
19
20
|
// @ts-ignore
|
|
20
|
-
input,
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
stdin, fp_stdin, fp_stdout, fp_stderr, print = true, proxy,
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
stdio }) {
|
|
21
|
+
input, stdin = Boolean(input), stdout = !detached, stderr = stdout, print = true, proxy, }) {
|
|
25
22
|
// --- 处理 proxy, envs
|
|
26
23
|
if (proxy === true) {
|
|
27
24
|
const { MyProxy } = await import("./net.js");
|
|
@@ -38,53 +35,41 @@ stdio }) {
|
|
|
38
35
|
} : {},
|
|
39
36
|
...envs
|
|
40
37
|
});
|
|
41
|
-
// --- 处理 stdio
|
|
42
|
-
if (
|
|
43
|
-
|
|
38
|
+
// --- 处理 stdio: 将 stdio 中的 true, false, string 转换为对应的 node.js stdio 值
|
|
39
|
+
if (detached)
|
|
40
|
+
check([stdin, stdout, stderr].every(io => io !== true), '调用 start 启动 detached 进程时 stdio 不能为 true (pipe)');
|
|
44
41
|
let opened_handles = [];
|
|
45
42
|
async function close_all_handles() {
|
|
46
43
|
await Promise.all(opened_handles.map(async (handle) => handle.close()));
|
|
47
44
|
}
|
|
48
|
-
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
stdio = ['ignore', 'ignore', 'ignore'];
|
|
56
|
-
else
|
|
57
|
-
stdio = [
|
|
58
|
-
// 当子进程 stdin 为 'ignore' 时,python 会报错 [WinError 6] 句柄无效,cmd / powershell 都会立即结束退出
|
|
59
|
-
(stdin || input) ? 'pipe' : 'ignore',
|
|
60
|
-
'pipe',
|
|
61
|
-
'pipe'
|
|
62
|
-
];
|
|
63
|
-
if (fp_stdin || fp_stdout || fp_stderr) {
|
|
64
|
-
const { fopen } = await import("./file.js");
|
|
65
|
-
async function open(fp, flags) {
|
|
66
|
-
try {
|
|
67
|
-
const handle = await fopen(fp, flags);
|
|
68
|
-
opened_handles.push(handle);
|
|
69
|
-
return handle.fd;
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
await close_all_handles();
|
|
73
|
-
throw error;
|
|
74
|
-
}
|
|
45
|
+
async function resolve_stdio(io, flags) {
|
|
46
|
+
if (io === true)
|
|
47
|
+
return 'pipe';
|
|
48
|
+
else if (typeof io === 'string') {
|
|
49
|
+
const handle = await fopen(io, flags);
|
|
50
|
+
opened_handles.push(handle);
|
|
51
|
+
return handle.fd;
|
|
75
52
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (fp_stdout)
|
|
79
|
-
stdio[1] = await open(fp_stdout, 'w');
|
|
80
|
-
if (fp_stderr)
|
|
81
|
-
stdio[2] = fp_stderr === fp_stdout
|
|
82
|
-
? stdio[1]
|
|
83
|
-
: await open(fp_stderr, 'w');
|
|
53
|
+
else
|
|
54
|
+
return 'ignore';
|
|
84
55
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
56
|
+
let pstdout;
|
|
57
|
+
let stdio;
|
|
58
|
+
try {
|
|
59
|
+
stdio = await Promise.all([
|
|
60
|
+
resolve_stdio(stdin, 'r'),
|
|
61
|
+
(pstdout = resolve_stdio(stdout, 'w')),
|
|
62
|
+
// 若 stderr 和 stdout 相同,则复用其 fd
|
|
63
|
+
stderr === stdout && typeof stderr === 'string'
|
|
64
|
+
? pstdout
|
|
65
|
+
: resolve_stdio(stderr, 'w')
|
|
66
|
+
]);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
await close_all_handles();
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
// --- 处理 print
|
|
88
73
|
if (typeof print === 'boolean')
|
|
89
74
|
print = {
|
|
90
75
|
command: print,
|
|
@@ -92,17 +77,23 @@ stdio }) {
|
|
|
92
77
|
stdout: print,
|
|
93
78
|
stderr: print
|
|
94
79
|
};
|
|
80
|
+
print = {
|
|
81
|
+
command: print.command ?? true,
|
|
82
|
+
code: print.code ?? true,
|
|
83
|
+
stdout: stdout && (print.stdout ?? true),
|
|
84
|
+
stderr: stderr && (print.stderr ?? true)
|
|
85
|
+
};
|
|
95
86
|
const command = get_command(exe, args);
|
|
96
87
|
if (print.command)
|
|
97
88
|
console.log(command.blue);
|
|
98
89
|
return {
|
|
99
|
-
|
|
90
|
+
// 已经转为了完整的 FullPrintOptions
|
|
91
|
+
print: print,
|
|
100
92
|
command,
|
|
101
93
|
spawn_options: {
|
|
102
94
|
cwd,
|
|
103
95
|
shell: false,
|
|
104
|
-
|
|
105
|
-
windowsHide: _window ?? Boolean(!detached || fp_stdout),
|
|
96
|
+
windowsHide: !_window,
|
|
106
97
|
detached,
|
|
107
98
|
stdio,
|
|
108
99
|
...envs_ ? { env: envs_ } : {}
|
|
@@ -142,19 +133,21 @@ function to_subprocess(child, { title, exe, args, command, }) {
|
|
|
142
133
|
});
|
|
143
134
|
return child;
|
|
144
135
|
}
|
|
145
|
-
/** 启动独立 (detached) 的进程,不受当前 node.js
|
|
146
|
-
使用 windowsHide 选项避免创建命令行窗口
|
|
136
|
+
/** 使用 exe 启动独立 (detached) 的进程,不受当前 node.js 进程退出的影响,可重定向 stdio 到文件(默认直接忽略)
|
|
147
137
|
- exe: .exe 路径或文件名 (建议使用完整路径,跳过 path 搜索,性能更高)
|
|
148
138
|
- args?: `[ ]` 参数列表
|
|
149
|
-
- options?:
|
|
150
|
-
- cwd
|
|
139
|
+
- options?: {@link StartOptions} 继承自 {@link BaseOptions}
|
|
140
|
+
- cwd?: `'T:/'`
|
|
151
141
|
- envs?: `process.env` 覆盖/添加到 process.env 的环境变量,传 null 时可以取消设置该变量
|
|
152
|
-
-
|
|
142
|
+
- proxy?: 创建子进程时添加 http_proxy, https_proxy, no_proxy 环境变量以启用代理
|
|
153
143
|
- print?: `true` 是否打印启动命令行
|
|
154
|
-
-
|
|
155
|
-
|
|
156
|
-
-
|
|
157
|
-
|
|
144
|
+
- stdin?: 控制子进程 stdin,默认为 `false` ('ignore', 读空设备)
|
|
145
|
+
可传入 string,设置子进程 stdin 为某个文件路径 (打开文件,将句柄设置为子进程 stdin)
|
|
146
|
+
- stdout?: 控制子进程 stdout,默认为 `false` ('ignore', 写空设备)
|
|
147
|
+
可传入 string,设置子进程 stdout 某个文件路径 (打开文件,将句柄设置为子进程 stdout)
|
|
148
|
+
- stderr?: 控制子进程 stderr,默认为 `stdout` 的值,用法同 stdout
|
|
149
|
+
- window?: 默认为 false,不显示窗口,设置启动进程的参数 CREATE_NO_WINDOW, 和 SW_HIDE
|
|
150
|
+
- title?: 由创建进程的调用者设置的,用于区分、识别、记忆的可选名称 */
|
|
158
151
|
export async function start(exe, args = [], options = {}) {
|
|
159
152
|
const { spawn_options, close_all_handles, command } = await prepare_spawn(true, exe, args, options);
|
|
160
153
|
try {
|
|
@@ -205,7 +198,7 @@ export async function call(exe, args = [], options = {}) {
|
|
|
205
198
|
await close_all_handles();
|
|
206
199
|
}
|
|
207
200
|
const { stdio } = spawn_options;
|
|
208
|
-
const { encoding = 'utf-8', throw_code = true, input,
|
|
201
|
+
const { encoding = 'utf-8', throw_code = true, input, on_stdout, on_stderr, on_child } = options;
|
|
209
202
|
// 防止 child spawn 失败时 crash nodejs 进程
|
|
210
203
|
child.on('error', error => {
|
|
211
204
|
console.error(error);
|
|
@@ -216,39 +209,37 @@ export async function call(exe, args = [], options = {}) {
|
|
|
216
209
|
child.stdin.end(input);
|
|
217
210
|
}
|
|
218
211
|
// --- 收集进程输出
|
|
212
|
+
const piped_stdout = stdio[1] === 'pipe';
|
|
213
|
+
const piped_stderr = stdio[2] === 'pipe';
|
|
219
214
|
let stdouts = [];
|
|
220
215
|
let stderrs = [];
|
|
221
|
-
if (
|
|
222
|
-
if (encoding === 'utf-8')
|
|
223
|
-
child.stdout.setEncoding(
|
|
216
|
+
if (piped_stdout) {
|
|
217
|
+
if (encoding === 'utf-8' || encoding === 'utf-16le')
|
|
218
|
+
child.stdout.setEncoding(encoding);
|
|
224
219
|
else if (encoding !== 'binary')
|
|
225
220
|
child.stdout = child.stdout.pipe(new DecoderStream(encoding));
|
|
226
|
-
child.stdout.on('data',
|
|
227
|
-
?
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
stdouts.push(chunk);
|
|
235
|
-
});
|
|
221
|
+
child.stdout.on('data', on_stdout || (print.stdout
|
|
222
|
+
? (chunk) => {
|
|
223
|
+
stdouts.push(chunk);
|
|
224
|
+
process.stdout.write(chunk);
|
|
225
|
+
}
|
|
226
|
+
: (chunk) => {
|
|
227
|
+
stdouts.push(chunk);
|
|
228
|
+
}));
|
|
236
229
|
}
|
|
237
|
-
if (
|
|
238
|
-
if (encoding === 'utf-8')
|
|
239
|
-
child.stderr.setEncoding(
|
|
230
|
+
if (piped_stderr) {
|
|
231
|
+
if (encoding === 'utf-8' || encoding === 'utf-16le')
|
|
232
|
+
child.stderr.setEncoding(encoding);
|
|
240
233
|
else if (encoding !== 'binary')
|
|
241
234
|
child.stderr = child.stderr.pipe(new DecoderStream(encoding));
|
|
242
|
-
child.stderr.on('data',
|
|
243
|
-
?
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
stderrs.push(chunk);
|
|
251
|
-
});
|
|
235
|
+
child.stderr.on('data', on_stderr || (print.stderr
|
|
236
|
+
? (chunk) => {
|
|
237
|
+
stderrs.push(chunk);
|
|
238
|
+
process.stderr.write(chunk);
|
|
239
|
+
}
|
|
240
|
+
: (chunk) => {
|
|
241
|
+
stderrs.push(chunk);
|
|
242
|
+
}));
|
|
252
243
|
}
|
|
253
244
|
on_child?.(child);
|
|
254
245
|
let code, signal;
|
|
@@ -279,19 +270,14 @@ export async function call(exe, args = [], options = {}) {
|
|
|
279
270
|
child,
|
|
280
271
|
print,
|
|
281
272
|
[inspect.custom]() {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
'print',
|
|
291
|
-
...print.stdout ? ['stdout'] : [],
|
|
292
|
-
...print.stderr ? ['stderr'] : [],
|
|
293
|
-
]
|
|
294
|
-
});
|
|
273
|
+
const { stdout, stderr, command, print, code, signal } = this;
|
|
274
|
+
return {
|
|
275
|
+
...!print.command ? { command } : {},
|
|
276
|
+
...piped_stdout && !print.stdout ? { stdout } : {},
|
|
277
|
+
...piped_stderr && !print.stderr ? { stderr } : {},
|
|
278
|
+
...code ? { code } : {},
|
|
279
|
+
...signal ? { signal } : {},
|
|
280
|
+
};
|
|
295
281
|
}
|
|
296
282
|
};
|
|
297
283
|
if (throw_code && code)
|
|
@@ -299,20 +285,15 @@ export async function call(exe, args = [], options = {}) {
|
|
|
299
285
|
return result;
|
|
300
286
|
}
|
|
301
287
|
export async function launch(exe, args, options) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
310
|
-
catch (error) {
|
|
311
|
-
reject(error);
|
|
312
|
-
}
|
|
288
|
+
return new Promise(resolve => {
|
|
289
|
+
const presult = call(exe, args, {
|
|
290
|
+
on_child(child) {
|
|
291
|
+
child.presult = presult;
|
|
292
|
+
resolve(child);
|
|
293
|
+
},
|
|
294
|
+
...options,
|
|
295
|
+
});
|
|
313
296
|
});
|
|
314
|
-
ps.presult = presult;
|
|
315
|
-
return ps;
|
|
316
297
|
}
|
|
317
298
|
/** 调用 node <js> 并等待结果
|
|
318
299
|
- js: .js 路径 (相对路径根据 cwd 解析)
|
package/server.js
CHANGED
|
@@ -14,7 +14,7 @@ import { contentType as get_content_type } from 'mime-types';
|
|
|
14
14
|
// --- my libs
|
|
15
15
|
import { t } from "./i18n/instance.js";
|
|
16
16
|
import { request as _request, Remote } from "./net.js";
|
|
17
|
-
import { inspect, check, range_to_numbers, encode, filter_keys, filter_values, consume_stream } from "./utils.js";
|
|
17
|
+
import { inspect, check, range_to_numbers, encode, filter_keys, filter_values, consume_stream, colored } from "./utils.js";
|
|
18
18
|
import { flist, fread, fstat } from "./file.js";
|
|
19
19
|
import { exe_nodejs, sea } from "./process.js";
|
|
20
20
|
// ------------ my server
|
|
@@ -281,7 +281,7 @@ export class Server {
|
|
|
281
281
|
// 时间
|
|
282
282
|
`${this.log_date ? new Date().to_str() : new Date().to_time_str()} ` +
|
|
283
283
|
// wss://
|
|
284
|
-
|
|
284
|
+
`ws${socket.encrypted ? 's' : ''}://`.yellow +
|
|
285
285
|
// host
|
|
286
286
|
host +
|
|
287
287
|
// path
|
|
@@ -386,15 +386,14 @@ export class Server {
|
|
|
386
386
|
let { method } = request;
|
|
387
387
|
if (Server.logger_ignore_fexts.has(path.fext))
|
|
388
388
|
return;
|
|
389
|
-
let s = '';
|
|
390
389
|
// 时间
|
|
391
|
-
s
|
|
390
|
+
let s = `${this.log_date ? new Date().to_str() : new Date().to_time_str()} `;
|
|
392
391
|
// method
|
|
393
392
|
method = method.toLowerCase();
|
|
394
393
|
if (method !== 'get')
|
|
395
394
|
s += `${method.yellow} `;
|
|
396
395
|
// http, https, http2, websocket
|
|
397
|
-
s += `${http_version === '2.0'
|
|
396
|
+
s += colored(`${protocol}://`, 'magenta', http_version === '2.0');
|
|
398
397
|
// host
|
|
399
398
|
s += host;
|
|
400
399
|
// path
|
package/utils.browser.d.ts
CHANGED
|
@@ -24,7 +24,8 @@ export declare function delay(milliseconds: number, { signal }?: {
|
|
|
24
24
|
export declare class TimeoutError extends Error {
|
|
25
25
|
name: "TimeoutError";
|
|
26
26
|
}
|
|
27
|
-
/** 在指定的时间 (milliseconds)
|
|
27
|
+
/** 在指定的时间 (milliseconds) 内运行某个任务,超时之后抛出错误或调用 on_timeout
|
|
28
|
+
- milliseconds: 限时毫秒数
|
|
28
29
|
- action?: 要等待运行的任务, async function 或 promise
|
|
29
30
|
- on_timeout?: 超时后调用的函数
|
|
30
31
|
- 如果传入了 on_timeout 参数: 调用 on_timeout,然后 timeout 函数正常返回 null
|
package/utils.browser.js
CHANGED
|
@@ -76,7 +76,8 @@ export async function delay(milliseconds, { signal } = {}) {
|
|
|
76
76
|
export class TimeoutError extends Error {
|
|
77
77
|
name = 'TimeoutError';
|
|
78
78
|
}
|
|
79
|
-
/** 在指定的时间 (milliseconds)
|
|
79
|
+
/** 在指定的时间 (milliseconds) 内运行某个任务,超时之后抛出错误或调用 on_timeout
|
|
80
|
+
- milliseconds: 限时毫秒数
|
|
80
81
|
- action?: 要等待运行的任务, async function 或 promise
|
|
81
82
|
- on_timeout?: 超时后调用的函数
|
|
82
83
|
- 如果传入了 on_timeout 参数: 调用 on_timeout,然后 timeout 函数正常返回 null
|
package/utils.d.ts
CHANGED
|
@@ -90,7 +90,8 @@ export declare function delay(milliseconds: number, options?: TimerOptions): Pro
|
|
|
90
90
|
export declare class TimeoutError extends Error {
|
|
91
91
|
name: "TimeoutError";
|
|
92
92
|
}
|
|
93
|
-
/** 在指定的时间 (milliseconds)
|
|
93
|
+
/** 在指定的时间 (milliseconds) 内运行某个任务,超时之后抛出错误或调用 on_timeout
|
|
94
|
+
- milliseconds: 限时毫秒数
|
|
94
95
|
- action?: 要等待运行的任务, async function 或 promise
|
|
95
96
|
- on_timeout?: 超时后调用的函数
|
|
96
97
|
- 如果传入了 on_timeout 参数: 调用 on_timeout,然后 timeout 函数正常返回 null
|
package/utils.js
CHANGED
|
@@ -280,7 +280,8 @@ export async function delay(milliseconds, options) {
|
|
|
280
280
|
export class TimeoutError extends Error {
|
|
281
281
|
name = 'TimeoutError';
|
|
282
282
|
}
|
|
283
|
-
/** 在指定的时间 (milliseconds)
|
|
283
|
+
/** 在指定的时间 (milliseconds) 内运行某个任务,超时之后抛出错误或调用 on_timeout
|
|
284
|
+
- milliseconds: 限时毫秒数
|
|
284
285
|
- action?: 要等待运行的任务, async function 或 promise
|
|
285
286
|
- on_timeout?: 超时后调用的函数
|
|
286
287
|
- 如果传入了 on_timeout 参数: 调用 on_timeout,然后 timeout 函数正常返回 null
|