xshell 1.0.69 → 1.0.71
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 +8 -4
- package/apps.js +10 -6
- package/git.d.ts +3 -3
- package/git.js +4 -4
- package/net.js +2 -1
- package/package.json +17 -17
- package/repl.js +1 -0
- package/server.d.ts +7 -1
- package/server.js +24 -7
- package/utils.browser.d.ts +1 -1
- package/utils.browser.js +1 -1
- package/utils.d.ts +1 -1
- package/utils.js +1 -1
package/apps.d.ts
CHANGED
|
@@ -31,11 +31,13 @@ export declare let oss: {
|
|
|
31
31
|
client: OSS;
|
|
32
32
|
bucket: string;
|
|
33
33
|
region: string;
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
fpd_cdn: string;
|
|
35
|
+
fpd_oss: string;
|
|
36
|
+
init({ bucket, region, fpd_cdn, fpd_oss, access_id, access_key }: {
|
|
36
37
|
bucket: string;
|
|
37
38
|
region: string;
|
|
38
|
-
|
|
39
|
+
fpd_cdn: string;
|
|
40
|
+
fpd_oss: string;
|
|
39
41
|
access_id: string;
|
|
40
42
|
access_key: string;
|
|
41
43
|
}): Promise<void>;
|
|
@@ -44,10 +46,12 @@ export declare let oss: {
|
|
|
44
46
|
- data: 文件 (Uint8Array) | 本地文件完整路径 (string) | ReadableStream
|
|
45
47
|
- options?:
|
|
46
48
|
- private?: `false` 设置为私有,需要通过 URL 签名参数访问
|
|
49
|
+
- cdn?: `false` false 时返回 oss 链接,true 时返回 cdn 链接
|
|
47
50
|
- print?: `true` 打印消息 */
|
|
48
|
-
upload(fp: string, data: Uint8Array | string | Readable, { private: _private, print, }?: {
|
|
51
|
+
upload(fp: string, data: Uint8Array | string | Readable, { private: _private, print, cdn, }?: {
|
|
49
52
|
private?: boolean;
|
|
50
53
|
print?: boolean;
|
|
54
|
+
cdn?: boolean;
|
|
51
55
|
}): Promise<string>;
|
|
52
56
|
/** 获取经过签名后可访问的 url */
|
|
53
57
|
get_url(fp: string): Promise<string>;
|
package/apps.js
CHANGED
|
@@ -41,14 +41,16 @@ export let oss = {
|
|
|
41
41
|
client: null,
|
|
42
42
|
bucket: null,
|
|
43
43
|
region: null,
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
fpd_cdn: null,
|
|
45
|
+
fpd_oss: null,
|
|
46
|
+
async init({ bucket, region, fpd_cdn, fpd_oss, access_id, access_key }) {
|
|
46
47
|
if (this.client)
|
|
47
48
|
return;
|
|
48
49
|
const OSS = (await import('ali-oss')).default;
|
|
49
50
|
this.bucket = bucket;
|
|
50
51
|
this.region = region;
|
|
51
|
-
this.
|
|
52
|
+
this.fpd_cdn = fpd_cdn;
|
|
53
|
+
this.fpd_oss = fpd_oss;
|
|
52
54
|
this.client = new OSS({
|
|
53
55
|
accessKeyId: access_id,
|
|
54
56
|
accessKeySecret: access_key,
|
|
@@ -62,9 +64,11 @@ export let oss = {
|
|
|
62
64
|
- data: 文件 (Uint8Array) | 本地文件完整路径 (string) | ReadableStream
|
|
63
65
|
- options?:
|
|
64
66
|
- private?: `false` 设置为私有,需要通过 URL 签名参数访问
|
|
67
|
+
- cdn?: `false` false 时返回 oss 链接,true 时返回 cdn 链接
|
|
65
68
|
- print?: `true` 打印消息 */
|
|
66
|
-
async upload(fp, data, { private: _private = false, print = true, } = {}) {
|
|
69
|
+
async upload(fp, data, { private: _private = false, print = true, cdn = false, } = {}) {
|
|
67
70
|
assert(this.client, 'OSS 应该已经初始化了');
|
|
71
|
+
assert(!fp.startsWith('/'), 'fp 不能以 / 开头');
|
|
68
72
|
assert(!fp.isdir, '不能使用 oss.upload 上传文件夹,请使用 oss.upload_dir');
|
|
69
73
|
if (typeof data === 'string')
|
|
70
74
|
assert(data[1] === ':' && path.isAbsolute(data), 'oss.upload 传入 data 参数类型为 string 时,必须为本地文件完整路径');
|
|
@@ -77,7 +81,7 @@ export let oss = {
|
|
|
77
81
|
url = await this.get_url(fp);
|
|
78
82
|
}
|
|
79
83
|
else
|
|
80
|
-
url = new URL(this.
|
|
84
|
+
url = new URL(`${cdn ? this.fpd_cdn : this.fpd_oss}${fp}`).toString();
|
|
81
85
|
if (print)
|
|
82
86
|
console.log(`已上传到 OSS${_private ? ' (私有)' : ''}:`, url);
|
|
83
87
|
return url;
|
|
@@ -86,7 +90,7 @@ export let oss = {
|
|
|
86
90
|
async get_url(fp) {
|
|
87
91
|
assert(this.client, 'OSS 应该已经初始化了');
|
|
88
92
|
const url = new URL(this.client.signatureUrl(fp, { expires: /* 十年 */ 3600 * 24 * 365 * 10 }));
|
|
89
|
-
const url_ = `${this.
|
|
93
|
+
const url_ = `${this.fpd_cdn}${url.pathname.slice(1)}${url.search}`;
|
|
90
94
|
return url_;
|
|
91
95
|
}
|
|
92
96
|
};
|
package/git.d.ts
CHANGED
|
@@ -14,12 +14,12 @@ export declare class Git {
|
|
|
14
14
|
get_branches(print?: boolean): Promise<string[]>;
|
|
15
15
|
has_branch(branch: string): Promise<boolean>;
|
|
16
16
|
/** - last?: `4` */
|
|
17
|
-
log({
|
|
18
|
-
|
|
17
|
+
log({ n, graph, format, }?: {
|
|
18
|
+
n?: number;
|
|
19
19
|
graph?: boolean;
|
|
20
20
|
format?: string;
|
|
21
21
|
}): Promise<import("./process.js").CallResult<string>>;
|
|
22
|
-
get_last_commits(
|
|
22
|
+
get_last_commits(n?: number): Promise<{
|
|
23
23
|
time: Date;
|
|
24
24
|
commiter: string;
|
|
25
25
|
hash: string;
|
package/git.js
CHANGED
|
@@ -52,19 +52,19 @@ export class Git {
|
|
|
52
52
|
.includes(branch);
|
|
53
53
|
}
|
|
54
54
|
/** - last?: `4` */
|
|
55
|
-
async log({
|
|
55
|
+
async log({ n = 4, graph = false, format, } = {}) {
|
|
56
56
|
if (!graph && !format)
|
|
57
57
|
// 多行 commit message 会被 join 在一起,用空格隔开
|
|
58
58
|
format = ['ct', 'cn', 'H', 's'].map(x => `%${x}`).join('%x00');
|
|
59
59
|
return this.call([
|
|
60
60
|
'log',
|
|
61
61
|
...graph ? ['--graph'] : [],
|
|
62
|
-
`-${
|
|
62
|
+
`-${n}`,
|
|
63
63
|
...format ? [`--pretty=format:${format}`] : [],
|
|
64
64
|
], { color: !format, print: !format });
|
|
65
65
|
}
|
|
66
|
-
async get_last_commits(
|
|
67
|
-
const { stdout } = await this.log({
|
|
66
|
+
async get_last_commits(n = 100) {
|
|
67
|
+
const { stdout } = await this.log({ n });
|
|
68
68
|
return stdout.split_lines()
|
|
69
69
|
.map(line => {
|
|
70
70
|
const [unixtime, commiter, hash, message] = line.split('\x00');
|
package/net.js
CHANGED
|
@@ -346,7 +346,8 @@ on_message, on_error, on_close }) {
|
|
|
346
346
|
const { WebSocket } = await import('ws');
|
|
347
347
|
let websocket = new WebSocket(url, protocols, {
|
|
348
348
|
maxPayload: max_payload,
|
|
349
|
-
skipUTF8Validation: true
|
|
349
|
+
skipUTF8Validation: true,
|
|
350
|
+
allowSynchronousEvents: true,
|
|
350
351
|
});
|
|
351
352
|
// https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543
|
|
352
353
|
websocket.binaryType = 'arraybuffer';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xshell",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.71",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"bin": {
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
]
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@babel/core": "^7.23.
|
|
49
|
-
"@babel/parser": "^7.23.
|
|
50
|
-
"@babel/traverse": "^7.23.
|
|
51
|
-
"@koa/cors": "^
|
|
48
|
+
"@babel/core": "^7.23.6",
|
|
49
|
+
"@babel/parser": "^7.23.6",
|
|
50
|
+
"@babel/traverse": "^7.23.6",
|
|
51
|
+
"@koa/cors": "^5.0.0",
|
|
52
52
|
"@types/ws": "^8.5.10",
|
|
53
53
|
"ali-oss": "^6.18.1",
|
|
54
54
|
"archiver": "^6.0.1",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"fetch-cookie": "^2.1.0",
|
|
64
64
|
"gulp-sort": "^2.0.0",
|
|
65
65
|
"hash-string": "^1.0.0",
|
|
66
|
-
"i18next": "^23.7.
|
|
66
|
+
"i18next": "^23.7.9",
|
|
67
67
|
"i18next-scanner": "^4.4.0",
|
|
68
68
|
"js-cookie": "^3.0.5",
|
|
69
69
|
"koa": "^2.14.2",
|
|
@@ -74,25 +74,25 @@
|
|
|
74
74
|
"ora": "^7.0.1",
|
|
75
75
|
"react": "^18.2.0",
|
|
76
76
|
"react-i18next": "^13.5.0",
|
|
77
|
-
"react-object-model": "^1.2.
|
|
77
|
+
"react-object-model": "^1.2.1",
|
|
78
78
|
"resolve-path": "^1.4.0",
|
|
79
79
|
"strip-ansi": "^7.1.0",
|
|
80
80
|
"through2": "^4.0.2",
|
|
81
81
|
"tough-cookie": "^4.1.3",
|
|
82
82
|
"tslib": "^2.6.2",
|
|
83
|
-
"typescript": "^5.3.
|
|
83
|
+
"typescript": "^5.3.3",
|
|
84
84
|
"ua-parser-js": "2.0.0-alpha.2",
|
|
85
|
-
"undici": "^
|
|
85
|
+
"undici": "^6.0.1",
|
|
86
86
|
"vinyl": "^3.0.0",
|
|
87
87
|
"vinyl-fs": "^4.0.0",
|
|
88
|
-
"ws": "^8.
|
|
88
|
+
"ws": "^8.15.1",
|
|
89
89
|
"xterm": "^5.3.0",
|
|
90
90
|
"xterm-addon-fit": "^0.8.0",
|
|
91
91
|
"xterm-addon-web-links": "^0.9.0",
|
|
92
92
|
"xterm-addon-webgl": "^0.16.0"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@babel/types": "^7.23.
|
|
95
|
+
"@babel/types": "^7.23.6",
|
|
96
96
|
"@types/ali-oss": "^6.16.11",
|
|
97
97
|
"@types/archiver": "^6.0.2",
|
|
98
98
|
"@types/babel__traverse": "^7.20.4",
|
|
@@ -104,18 +104,18 @@
|
|
|
104
104
|
"@types/koa-compress": "^4.0.6",
|
|
105
105
|
"@types/lodash": "^4.14.202",
|
|
106
106
|
"@types/mime-types": "^2.1.4",
|
|
107
|
-
"@types/node": "^20.10.
|
|
108
|
-
"@types/react": "^18.2.
|
|
107
|
+
"@types/node": "^20.10.4",
|
|
108
|
+
"@types/react": "^18.2.45",
|
|
109
109
|
"@types/through2": "^2.0.41",
|
|
110
110
|
"@types/tough-cookie": "^4.0.5",
|
|
111
111
|
"@types/ua-parser-js": "^0.7.39",
|
|
112
112
|
"@types/vinyl-fs": "^3.0.5",
|
|
113
|
-
"@types/vscode": "^1.
|
|
114
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
115
|
-
"@typescript-eslint/parser": "^6.
|
|
113
|
+
"@types/vscode": "^1.85.0",
|
|
114
|
+
"@typescript-eslint/eslint-plugin": "^6.14.0",
|
|
115
|
+
"@typescript-eslint/parser": "^6.14.0",
|
|
116
116
|
"eslint": "^8.55.0",
|
|
117
117
|
"eslint-plugin-react": "^7.33.2",
|
|
118
|
-
"eslint-plugin-xlint": "^1.0.
|
|
118
|
+
"eslint-plugin-xlint": "^1.0.11"
|
|
119
119
|
},
|
|
120
120
|
"scripts": {
|
|
121
121
|
"start": "node --title=xshell --inspect=0.0.0.0:8420 ./xshell.js",
|
package/repl.js
CHANGED
package/server.d.ts
CHANGED
|
@@ -35,6 +35,10 @@ export declare class Server {
|
|
|
35
35
|
js_exts: Set<string>;
|
|
36
36
|
app: Koa;
|
|
37
37
|
handler: ReturnType<Koa['callback']>;
|
|
38
|
+
/** 启用 http server */
|
|
39
|
+
http: boolean;
|
|
40
|
+
/** 启用 http2 server */
|
|
41
|
+
http2: boolean;
|
|
38
42
|
http_port: number;
|
|
39
43
|
http2_port: number;
|
|
40
44
|
/** http2 server 证书文件夹路径,设置后才会启用 http2 server */
|
|
@@ -55,8 +59,10 @@ export declare class Server {
|
|
|
55
59
|
stdout_write: Function;
|
|
56
60
|
stderr_write: Function;
|
|
57
61
|
encoder: TextEncoder;
|
|
58
|
-
constructor({ name, http_port, http2_port, fpd_certs, default_hostnames, remote, funcs, stdio_subscribable, }: {
|
|
62
|
+
constructor({ name, http, http2, http_port, http2_port, fpd_certs, default_hostnames, remote, funcs, stdio_subscribable, }: {
|
|
59
63
|
name: string;
|
|
64
|
+
http?: boolean;
|
|
65
|
+
http2?: boolean;
|
|
60
66
|
http_port?: number;
|
|
61
67
|
http2_port?: number;
|
|
62
68
|
fpd_certs?: string;
|
package/server.js
CHANGED
|
@@ -26,6 +26,10 @@ export class Server {
|
|
|
26
26
|
js_exts = new Set(['.js', '.mjs', '.cjs']);
|
|
27
27
|
app;
|
|
28
28
|
handler;
|
|
29
|
+
/** 启用 http server */
|
|
30
|
+
http = false;
|
|
31
|
+
/** 启用 http2 server */
|
|
32
|
+
http2 = false;
|
|
29
33
|
http_port = 80;
|
|
30
34
|
http2_port = 443;
|
|
31
35
|
/** http2 server 证书文件夹路径,设置后才会启用 http2 server */
|
|
@@ -44,8 +48,13 @@ export class Server {
|
|
|
44
48
|
stdout_write;
|
|
45
49
|
stderr_write;
|
|
46
50
|
encoder = new TextEncoder();
|
|
47
|
-
constructor({ name, http_port, http2_port, fpd_certs, default_hostnames, remote, funcs, stdio_subscribable, }) {
|
|
51
|
+
constructor({ name, http, http2, http_port, http2_port, fpd_certs, default_hostnames, remote, funcs, stdio_subscribable, }) {
|
|
48
52
|
this.name = name;
|
|
53
|
+
if (http)
|
|
54
|
+
this.http = http;
|
|
55
|
+
if (http2)
|
|
56
|
+
this.http2 = http2;
|
|
57
|
+
assert(this.http || this.http2, 'http 和 http2 至少启用一个');
|
|
49
58
|
if (http_port !== undefined)
|
|
50
59
|
this.http_port = http_port;
|
|
51
60
|
if (http2_port !== undefined)
|
|
@@ -86,14 +95,18 @@ export class Server {
|
|
|
86
95
|
},
|
|
87
96
|
threshold: 512
|
|
88
97
|
}));
|
|
89
|
-
app.use(KoaCors({
|
|
98
|
+
app.use(KoaCors({
|
|
99
|
+
credentials: true,
|
|
100
|
+
origin: (ctx) => ctx.request.get('origin') || '*'
|
|
101
|
+
}));
|
|
90
102
|
await this.init_app(app);
|
|
91
103
|
app.use(this._router.bind(this));
|
|
92
104
|
this.app = app;
|
|
93
105
|
this.handler = this.app.callback();
|
|
94
106
|
this.http_server = http_create_server(this.handler);
|
|
95
|
-
const {
|
|
96
|
-
if (
|
|
107
|
+
const { http, http2 } = this;
|
|
108
|
+
if (http2) {
|
|
109
|
+
const { fpd_certs } = this;
|
|
97
110
|
let lazy_secure_ctxs = Object.fromEntries(await Promise.all(
|
|
98
111
|
// fpd_certs 文件夹下面的每个 .key 对应一个证书及域名
|
|
99
112
|
(await flist(fpd_certs, { print: false, filter: /\.key$/ }))
|
|
@@ -121,6 +134,7 @@ export class Server {
|
|
|
121
134
|
noServer: true,
|
|
122
135
|
skipUTF8Validation: true,
|
|
123
136
|
perMessageDeflate: true,
|
|
137
|
+
allowSynchronousEvents: true,
|
|
124
138
|
maxPayload: 2 ** 30 // 1 GB
|
|
125
139
|
});
|
|
126
140
|
this.websocket_server.on('connection', (ws, request) => {
|
|
@@ -192,16 +206,19 @@ export class Server {
|
|
|
192
206
|
}
|
|
193
207
|
}
|
|
194
208
|
await Promise.all([
|
|
195
|
-
new Promise(resolve => {
|
|
209
|
+
http && new Promise(resolve => {
|
|
196
210
|
this.http_server.listen(this.http_port, resolve);
|
|
197
211
|
}),
|
|
198
|
-
|
|
212
|
+
http2 && new Promise(resolve => {
|
|
199
213
|
this.http2_server.listen(this.http2_port, resolve);
|
|
200
214
|
}),
|
|
201
215
|
]);
|
|
202
216
|
console.log(t('{{name}} 启动成功,正在监听 {{ports}} 端口', {
|
|
203
217
|
name: this.name,
|
|
204
|
-
ports:
|
|
218
|
+
ports: [
|
|
219
|
+
...http ? [this.http_port] : [],
|
|
220
|
+
...http2 ? [this.http2_port] : []
|
|
221
|
+
].join(', ')
|
|
205
222
|
}));
|
|
206
223
|
}
|
|
207
224
|
stop() {
|
package/utils.browser.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export declare class Lock<TResource = void> {
|
|
|
51
51
|
}
|
|
52
52
|
export declare function pause(milliseconds?: number): Promise<void>;
|
|
53
53
|
/** 字符串字典序比较 */
|
|
54
|
-
export declare function strcmp(l: string, r: string):
|
|
54
|
+
export declare function strcmp(l: string, r: string): 0 | 1 | -1;
|
|
55
55
|
/** 比较 1.10.02 这种版本号 */
|
|
56
56
|
export declare function vercmp(l: string, r: string): number;
|
|
57
57
|
export declare function get<TReturn = any>(obj: any, keypath: string): TReturn;
|
package/utils.browser.js
CHANGED
|
@@ -181,7 +181,7 @@ export function delta2str(delta) {
|
|
|
181
181
|
// [1, 1000) ms
|
|
182
182
|
if (delta < 1000)
|
|
183
183
|
return `${delta.toFixed(0)} ms`;
|
|
184
|
-
// 1.
|
|
184
|
+
// 1.1 s
|
|
185
185
|
if (1000 <= delta && delta < 1000 * 60)
|
|
186
186
|
return `${(delta / 1000).toFixed(1)} s`;
|
|
187
187
|
// 1 min 12 s [1 min 0s, 60 min)
|
package/utils.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare function unique<T>(iterable: T[] | Iterable<T>, selector?: string
|
|
|
22
22
|
/** 排序对象中 key 的顺序,返回新的对象 */
|
|
23
23
|
export declare function sort_keys<T>(obj: T): T;
|
|
24
24
|
/** 字符串字典序比较 */
|
|
25
|
-
export declare function strcmp(l: string, r: string):
|
|
25
|
+
export declare function strcmp(l: string, r: string): 0 | 1 | -1;
|
|
26
26
|
/** 比较 1.10.02 这种版本号 */
|
|
27
27
|
export declare function vercmp(l: string, r: string): number;
|
|
28
28
|
export declare function get<TReturn = any>(obj: any, keypath: string): TReturn;
|
package/utils.js
CHANGED
|
@@ -144,7 +144,7 @@ export function delta2str(delta) {
|
|
|
144
144
|
// [1, 1000) ms
|
|
145
145
|
if (delta < 1000)
|
|
146
146
|
return `${delta.toFixed(0)} ms`;
|
|
147
|
-
// 1.
|
|
147
|
+
// 1.1 s
|
|
148
148
|
if (1000 <= delta && delta < 1000 * 60)
|
|
149
149
|
return `${(delta / 1000).toFixed(1)} s`;
|
|
150
150
|
// 1 min 12 s [1 min 0s, 60 min)
|