xshell 1.0.105 → 1.0.107
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/package.json +11 -11
- package/process.d.ts +2 -2
- package/process.js +4 -6
- package/prototype.browser.d.ts +8 -4
- package/prototype.browser.js +12 -8
- package/prototype.d.ts +8 -4
- package/prototype.js +12 -8
- package/server.d.ts +1 -1
- package/server.js +9 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xshell",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.107",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"bin": {
|
|
@@ -58,9 +58,9 @@
|
|
|
58
58
|
"@babel/traverse": "^7.24.5",
|
|
59
59
|
"@koa/cors": "^5.0.0",
|
|
60
60
|
"@types/ws": "^8.5.10",
|
|
61
|
-
"@typescript-eslint/eslint-plugin": "^7.
|
|
62
|
-
"@typescript-eslint/parser": "^7.
|
|
63
|
-
"@typescript-eslint/utils": "^7.
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "^7.10.0",
|
|
62
|
+
"@typescript-eslint/parser": "^7.10.0",
|
|
63
|
+
"@typescript-eslint/utils": "^7.10.0",
|
|
64
64
|
"@xterm/addon-fit": "^0.10.0",
|
|
65
65
|
"@xterm/addon-web-links": "^0.11.0",
|
|
66
66
|
"@xterm/addon-webgl": "^0.18.0",
|
|
@@ -73,15 +73,15 @@
|
|
|
73
73
|
"cli-table3": "^0.6.5",
|
|
74
74
|
"cli-truncate": "^4.0.0",
|
|
75
75
|
"colors": "^1.4.0",
|
|
76
|
-
"commander": "^12.
|
|
76
|
+
"commander": "^12.1.0",
|
|
77
77
|
"emoji-regex": "^10.3.0",
|
|
78
|
-
"eslint": "^9.
|
|
78
|
+
"eslint": "^9.3.0",
|
|
79
79
|
"eslint-plugin-import": "^2.29.1",
|
|
80
80
|
"eslint-plugin-react": "^7.34.1",
|
|
81
81
|
"gulp-sort": "^2.0.0",
|
|
82
82
|
"hash-string": "^1.0.0",
|
|
83
83
|
"https-proxy-agent": "^7.0.4",
|
|
84
|
-
"i18next": "^23.11.
|
|
84
|
+
"i18next": "^23.11.5",
|
|
85
85
|
"i18next-scanner": "^4.4.0",
|
|
86
86
|
"koa": "^2.15.3",
|
|
87
87
|
"koa-compress": "^5.1.1",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"mime-types": "^2.1.35",
|
|
91
91
|
"ora": "^8.0.1",
|
|
92
92
|
"react": "^18.3.1",
|
|
93
|
-
"react-i18next": "^14.1.
|
|
93
|
+
"react-i18next": "^14.1.2",
|
|
94
94
|
"react-object-model": "^1.2.5",
|
|
95
95
|
"resolve-path": "^1.4.0",
|
|
96
96
|
"strip-ansi": "^7.1.0",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"tslib": "^2.6.2",
|
|
100
100
|
"typescript": "^5.4.5",
|
|
101
101
|
"ua-parser-js": "^2.0.0-beta.2",
|
|
102
|
-
"undici": "^6.
|
|
102
|
+
"undici": "^6.18.1",
|
|
103
103
|
"vinyl": "^3.0.0",
|
|
104
104
|
"vinyl-fs": "^4.0.0",
|
|
105
105
|
"ws": "^8.17.0"
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
"@babel/types": "^7.24.5",
|
|
109
109
|
"@types/ali-oss": "^6.16.11",
|
|
110
110
|
"@types/archiver": "^6.0.2",
|
|
111
|
-
"@types/babel__traverse": "^7.20.
|
|
111
|
+
"@types/babel__traverse": "^7.20.6",
|
|
112
112
|
"@types/byte-size": "^8.1.2",
|
|
113
113
|
"@types/chardet": "^0.8.3",
|
|
114
114
|
"@types/eslint": "^8.56.10",
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"@types/lodash": "^4.17.4",
|
|
120
120
|
"@types/mime-types": "^2.1.4",
|
|
121
121
|
"@types/node": "^20.12.12",
|
|
122
|
-
"@types/react": "^18.3.
|
|
122
|
+
"@types/react": "^18.3.3",
|
|
123
123
|
"@types/through2": "^2.0.41",
|
|
124
124
|
"@types/tough-cookie": "^4.0.5",
|
|
125
125
|
"@types/ua-parser-js": "^0.7.39",
|
package/process.d.ts
CHANGED
|
@@ -135,6 +135,6 @@ export interface TermNodeOptions extends TermOptions {
|
|
|
135
135
|
/** `false` --trace-warnings */
|
|
136
136
|
trace_warnings?: boolean;
|
|
137
137
|
}
|
|
138
|
-
/** 在 term tab 中创建 node.exe 进程
|
|
139
|
-
export declare function term_nodejs(fp_js: string, args?: string[], { title, inspect, tsnode, break: _break, resolve, trace_warnings, ...
|
|
138
|
+
/** 在 term tab 中创建 node.exe 进程 */
|
|
139
|
+
export declare function term_nodejs(fp_js: string, args?: string[], { title, inspect, tsnode, break: _break, resolve, trace_warnings, ...options }?: TermNodeOptions): Promise<ChildProcess>;
|
|
140
140
|
export {};
|
package/process.js
CHANGED
|
@@ -202,15 +202,13 @@ export async function term(exe, args = [], { cwd = process.cwd().fpd, print = tr
|
|
|
202
202
|
envs
|
|
203
203
|
});
|
|
204
204
|
}
|
|
205
|
-
/** 在 term tab 中创建 node.exe 进程
|
|
206
|
-
export async function term_nodejs(fp_js, args = [], { title, inspect, tsnode = false, break: _break, resolve = false, trace_warnings = false, ...
|
|
205
|
+
/** 在 term tab 中创建 node.exe 进程 */
|
|
206
|
+
export async function term_nodejs(fp_js, args = [], { title, inspect, tsnode = false, break: _break, resolve = false, trace_warnings = false, ...options } = {}) {
|
|
207
207
|
return term(exe_nodejs, [
|
|
208
208
|
...trace_warnings ? ['--trace-warnings'] : [],
|
|
209
209
|
...resolve ? ['--experimental-specifier-resolution=node'] : [],
|
|
210
210
|
...title ? [`--title=${title}`] : [],
|
|
211
|
-
...inspect ? [
|
|
212
|
-
_break ? `--inspect-brk=localhost:${inspect}` : `--inspect=localhost:${inspect}`
|
|
213
|
-
] : [],
|
|
211
|
+
...inspect ? [`--inspect${_break ? '-brk' : ''}=localhost:${inspect}`] : [],
|
|
214
212
|
...tsnode ? [
|
|
215
213
|
'--loader=ts-node/esm',
|
|
216
214
|
'--experimental-specifier-resolution=node'
|
|
@@ -219,7 +217,7 @@ export async function term_nodejs(fp_js, args = [], { title, inspect, tsnode = f
|
|
|
219
217
|
...args
|
|
220
218
|
], {
|
|
221
219
|
title,
|
|
222
|
-
...
|
|
220
|
+
...options,
|
|
223
221
|
});
|
|
224
222
|
}
|
|
225
223
|
const short_exe_names = {
|
package/prototype.browser.d.ts
CHANGED
|
@@ -75,10 +75,14 @@ declare global {
|
|
|
75
75
|
text: string;
|
|
76
76
|
};
|
|
77
77
|
space(this: string): string;
|
|
78
|
-
/**
|
|
79
|
-
strip_start(this: string, prefix: string): string;
|
|
80
|
-
/**
|
|
81
|
-
|
|
78
|
+
/** 返回去掉 prefix 开头的字符串,可选 validate = true 确保字符串以 prefix 开头(失败时抛出错误) */
|
|
79
|
+
strip_start(this: string, prefix: string, validate?: boolean): string;
|
|
80
|
+
/** 返回去掉 prefix 开头的字符串,如果没有以 prefix 开头则返回原字符串 */
|
|
81
|
+
strip_if_start(this: string, prefix: string): string;
|
|
82
|
+
/** 返回去掉 suffix 结尾的字符串,可选 validate = true 确保字符串以 suffix 结尾(失败时抛出错误) */
|
|
83
|
+
strip_end(this: string, suffix: string, validate?: boolean): string;
|
|
84
|
+
/** 返回去掉 suffix 结尾的字符串,如果没有以 suffix 结尾则返回原字符串 */
|
|
85
|
+
strip_if_end(this: string, suffix: string): string;
|
|
82
86
|
/** 等价于 .endsWith('/') */
|
|
83
87
|
isdir: boolean;
|
|
84
88
|
/** 以 `/` 分割的路径,可能以 / 结尾 */
|
package/prototype.browser.js
CHANGED
|
@@ -259,17 +259,21 @@ Object.defineProperties(String.prototype, {
|
|
|
259
259
|
text: this.slice(i)
|
|
260
260
|
};
|
|
261
261
|
},
|
|
262
|
-
strip_start(prefix) {
|
|
263
|
-
if (this.startsWith(prefix))
|
|
264
|
-
return this.slice(prefix.length);
|
|
265
|
-
else
|
|
262
|
+
strip_start(prefix, validate) {
|
|
263
|
+
if (validate && !this.startsWith(prefix))
|
|
266
264
|
throw new Error(`字符串没有以前缀 ${prefix} 开头: ${this}`);
|
|
265
|
+
return this.slice(prefix.length);
|
|
267
266
|
},
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
267
|
+
strip_if_start(prefix) {
|
|
268
|
+
return this.startsWith(prefix) ? this.slice(prefix.length) : this;
|
|
269
|
+
},
|
|
270
|
+
strip_end(suffix, validate) {
|
|
271
|
+
if (validate && !this.endsWith(suffix))
|
|
272
272
|
throw new Error(`字符串没有以后缀 ${suffix} 结尾: ${this}`);
|
|
273
|
+
return this.slice(0, -suffix.length);
|
|
274
|
+
},
|
|
275
|
+
strip_if_end(suffix) {
|
|
276
|
+
return this.endsWith(suffix) ? this.slice(0, -suffix.length) : this;
|
|
273
277
|
},
|
|
274
278
|
space() {
|
|
275
279
|
if (!this)
|
package/prototype.d.ts
CHANGED
|
@@ -98,10 +98,14 @@ declare global {
|
|
|
98
98
|
decode_base64(this: string, buffer: true): Buffer;
|
|
99
99
|
decode_base64(this: string, buffer?: boolean): string | Buffer;
|
|
100
100
|
space(this: string): string;
|
|
101
|
-
/**
|
|
102
|
-
strip_start(this: string, prefix: string): string;
|
|
103
|
-
/**
|
|
104
|
-
|
|
101
|
+
/** 返回去掉 prefix 开头的字符串,可选 validate = true 确保字符串以 prefix 开头(失败时抛出错误) */
|
|
102
|
+
strip_start(this: string, prefix: string, validate?: boolean): string;
|
|
103
|
+
/** 返回去掉 prefix 开头的字符串,如果没有以 prefix 开头则返回原字符串 */
|
|
104
|
+
strip_if_start(this: string, prefix: string): string;
|
|
105
|
+
/** 返回去掉 suffix 结尾的字符串,可选 validate = true 确保字符串以 suffix 结尾(失败时抛出错误) */
|
|
106
|
+
strip_end(this: string, suffix: string, validate?: boolean): string;
|
|
107
|
+
/** 返回去掉 suffix 结尾的字符串,如果没有以 suffix 结尾则返回原字符串 */
|
|
108
|
+
strip_if_end(this: string, suffix: string): string;
|
|
105
109
|
/** 等价于 .endsWith('/') */
|
|
106
110
|
isdir: boolean;
|
|
107
111
|
/** 以 `/` 分割的路径,可能以 / 结尾 */
|
package/prototype.js
CHANGED
|
@@ -278,17 +278,21 @@ if (!globalThis.my_prototype_defined) {
|
|
|
278
278
|
strip_ansi() {
|
|
279
279
|
return strip_ansi(this);
|
|
280
280
|
},
|
|
281
|
-
strip_start(prefix) {
|
|
282
|
-
if (this.startsWith(prefix))
|
|
283
|
-
return this.slice(prefix.length);
|
|
284
|
-
else
|
|
281
|
+
strip_start(prefix, validate) {
|
|
282
|
+
if (validate && !this.startsWith(prefix))
|
|
285
283
|
throw new Error(`字符串没有以前缀 ${prefix} 开头: ${this}`);
|
|
284
|
+
return this.slice(prefix.length);
|
|
286
285
|
},
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
286
|
+
strip_if_start(prefix) {
|
|
287
|
+
return this.startsWith(prefix) ? this.slice(prefix.length) : this;
|
|
288
|
+
},
|
|
289
|
+
strip_end(suffix, validate) {
|
|
290
|
+
if (validate && !this.endsWith(suffix))
|
|
291
291
|
throw new Error(`字符串没有以后缀 ${suffix} 结尾: ${this}`);
|
|
292
|
+
return this.slice(0, -suffix.length);
|
|
293
|
+
},
|
|
294
|
+
strip_if_end(suffix) {
|
|
295
|
+
return this.endsWith(suffix) ? this.slice(0, -suffix.length) : this;
|
|
292
296
|
},
|
|
293
297
|
space() {
|
|
294
298
|
if (!this)
|
package/server.d.ts
CHANGED
|
@@ -112,7 +112,7 @@ export declare class Server {
|
|
|
112
112
|
await this.try_send(
|
|
113
113
|
ctx,
|
|
114
114
|
`T:/t/docs${prefix_docs}`,
|
|
115
|
-
(path.endsWith('/') ? `${path}index.html` : path).
|
|
115
|
+
(path.endsWith('/') ? `${path}index.html` : path).strip_start(prefix_docs),
|
|
116
116
|
true
|
|
117
117
|
)
|
|
118
118
|
return
|
package/server.js
CHANGED
|
@@ -110,13 +110,13 @@ export class Server {
|
|
|
110
110
|
// fpd_certs 文件夹下面的每个 .key 对应一个证书及域名
|
|
111
111
|
(await flist(fpd_certs, { print: false, filter: /\.key$/ }))
|
|
112
112
|
.map(async (fname) => {
|
|
113
|
-
let domain = fname.
|
|
113
|
+
let domain = fname.strip_end('.key');
|
|
114
114
|
const [key, cert] = await Promise.all([
|
|
115
115
|
fname,
|
|
116
116
|
`${domain}.crt`,
|
|
117
117
|
].map(async (fname) => fread(`${fpd_certs}${fname}`, { print: false })));
|
|
118
118
|
if (domain.startsWith('star.'))
|
|
119
|
-
domain = `*.${domain.
|
|
119
|
+
domain = `*.${domain.strip_start('star.')}`;
|
|
120
120
|
return [domain, { key, cert }];
|
|
121
121
|
})));
|
|
122
122
|
const default_ctx = lazy_secure_ctxs[this.default_hostnames.find(hostname => hostname in lazy_secure_ctxs)];
|
|
@@ -125,6 +125,7 @@ export class Server {
|
|
|
125
125
|
SNICallback(servername, callback) {
|
|
126
126
|
let lazy_ctx = lazy_secure_ctxs[servername] ||
|
|
127
127
|
lazy_secure_ctxs[servername.replace(/^.*?\./, '*.')] ||
|
|
128
|
+
lazy_secure_ctxs[`*.${servername}`] ||
|
|
128
129
|
default_ctx;
|
|
129
130
|
callback(null, lazy_ctx.ctx ??= createSecureContext(lazy_ctx));
|
|
130
131
|
},
|
|
@@ -247,7 +248,7 @@ export class Server {
|
|
|
247
248
|
// 时间
|
|
248
249
|
`${new Date().to_time_str()} ` +
|
|
249
250
|
// ip(位置)
|
|
250
|
-
(ip || '').limit(
|
|
251
|
+
(ip || '').limit(40) + ' ' +
|
|
251
252
|
// ua
|
|
252
253
|
this.format_ua(headers).limit(56) + ' ' +
|
|
253
254
|
// https/2.0
|
|
@@ -346,7 +347,7 @@ export class Server {
|
|
|
346
347
|
// 时间
|
|
347
348
|
s += `${new Date().to_time_str()} `;
|
|
348
349
|
// ip(位置)
|
|
349
|
-
s += (ip || '').limit(
|
|
350
|
+
s += (ip || '').limit(40) + ' ';
|
|
350
351
|
// ua
|
|
351
352
|
s += this.process_ua(ctx).limit(56) + ' ';
|
|
352
353
|
// https/2.0
|
|
@@ -380,9 +381,8 @@ export class Server {
|
|
|
380
381
|
// query
|
|
381
382
|
if (Object.keys(query).length) {
|
|
382
383
|
let t = inspect(query, { compact: true })
|
|
383
|
-
.replace('[Object: null prototype] ', '')
|
|
384
|
-
|
|
385
|
-
t = t.slice(0, -1);
|
|
384
|
+
.replace('[Object: null prototype] ', '')
|
|
385
|
+
.strip_if_end('\n');
|
|
386
386
|
s += (s + t).width > output_width ? '\n' : ' ';
|
|
387
387
|
s += t;
|
|
388
388
|
}
|
|
@@ -516,7 +516,7 @@ export class Server {
|
|
|
516
516
|
await this.try_send(
|
|
517
517
|
ctx,
|
|
518
518
|
`T:/t/docs${prefix_docs}`,
|
|
519
|
-
(path.endsWith('/') ? `${path}index.html` : path).
|
|
519
|
+
(path.endsWith('/') ? `${path}index.html` : path).strip_start(prefix_docs),
|
|
520
520
|
true
|
|
521
521
|
)
|
|
522
522
|
return
|
|
@@ -556,10 +556,7 @@ export class Server {
|
|
|
556
556
|
const { request, request: { method } } = ctx;
|
|
557
557
|
let { response } = ctx;
|
|
558
558
|
if (!absolute) {
|
|
559
|
-
|
|
560
|
-
fp = fp.slice(root.length);
|
|
561
|
-
if (fp.startsWith('/'))
|
|
562
|
-
fp = fp.slice(1);
|
|
559
|
+
fp = fp.strip_if_start(root).strip_if_start('/');
|
|
563
560
|
const { default: resolve_safely } = await import('resolve-path');
|
|
564
561
|
try {
|
|
565
562
|
fp = resolve_safely(root, fp).fp;
|