xshell 1.3.29 → 1.3.31

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xshell",
3
- "version": "1.3.29",
3
+ "version": "1.3.31",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -49,16 +49,16 @@
49
49
  ]
50
50
  },
51
51
  "dependencies": {
52
- "@babel/core": "^7.28.5",
53
- "@babel/parser": "^7.28.5",
54
- "@babel/traverse": "^7.28.5",
52
+ "@babel/core": "^7.28.6",
53
+ "@babel/parser": "^7.28.6",
54
+ "@babel/traverse": "^7.28.6",
55
55
  "@koa/cors": "^5.0.0",
56
- "@stylistic/eslint-plugin": "^5.6.1",
56
+ "@stylistic/eslint-plugin": "^5.7.0",
57
57
  "@svgr/webpack": "^8.1.0",
58
58
  "@types/sass-loader": "^8.0.10",
59
- "@typescript-eslint/eslint-plugin": "^8.52.0",
60
- "@typescript-eslint/parser": "^8.52.0",
61
- "@typescript-eslint/utils": "^8.52.0",
59
+ "@typescript-eslint/eslint-plugin": "^8.53.1",
60
+ "@typescript-eslint/parser": "^8.53.1",
61
+ "@typescript-eslint/utils": "^8.53.1",
62
62
  "archiver": "^7.0.1",
63
63
  "chalk": "^5.6.2",
64
64
  "commander": "^14.0.2",
@@ -68,7 +68,7 @@
68
68
  "eslint-plugin-import": "^2.32.0",
69
69
  "eslint-plugin-react": "^7.37.5",
70
70
  "https-proxy-agent": "^7.0.6",
71
- "i18next": "^25.7.3",
71
+ "i18next": "^25.7.4",
72
72
  "i18next-scanner": "^4.6.0",
73
73
  "koa": "^3.1.1",
74
74
  "koa-compress": "^5.1.1",
@@ -76,7 +76,7 @@
76
76
  "mime-types": "^3.0.2",
77
77
  "p-map": "^7.0.4",
78
78
  "react": "^19.2.3",
79
- "react-i18next": "^16.5.1",
79
+ "react-i18next": "^16.5.3",
80
80
  "resolve-path": "^1.4.0",
81
81
  "sass": "^1.97.2",
82
82
  "sass-loader": "^16.0.6",
@@ -89,11 +89,11 @@
89
89
  "typescript": "^5.9.3",
90
90
  "undici": "^7.18.2",
91
91
  "webpack": "^5.104.1",
92
- "webpack-bundle-analyzer": "^5.1.0",
92
+ "webpack-bundle-analyzer": "^5.1.1",
93
93
  "ws": "^8.19.0"
94
94
  },
95
95
  "devDependencies": {
96
- "@babel/types": "^7.28.5",
96
+ "@babel/types": "^7.28.6",
97
97
  "@types/archiver": "^7.0.0",
98
98
  "@types/babel__traverse": "^7.28.0",
99
99
  "@types/eslint": "^9.6.1",
@@ -101,10 +101,10 @@
101
101
  "@types/koa": "^3.0.1",
102
102
  "@types/koa-compress": "^4.0.7",
103
103
  "@types/mime-types": "^3.0.1",
104
- "@types/node": "^25.0.3",
105
- "@types/react": "^19.2.7",
104
+ "@types/node": "^25.0.9",
105
+ "@types/react": "^19.2.8",
106
106
  "@types/tough-cookie": "^4.0.5",
107
- "@types/vscode": "^1.107.0",
107
+ "@types/vscode": "^1.108.1",
108
108
  "@types/webpack-bundle-analyzer": "^4.7.0",
109
109
  "@types/ws": "^8.18.1"
110
110
  }
@@ -179,10 +179,10 @@ declare global {
179
179
  sum<TKey extends keyof T>(this: T[], zero: T[TKey], mapper: TKey): T[TKey];
180
180
  sum<TMapper extends Mapper<T>>(this: T[], zero: ReturnType<TMapper>, mapper: TMapper): ReturnType<TMapper>;
181
181
  sum<TReturn = T>(this: T[], zero: TReturn, mapper?: keyof T | Mapper<T>): TReturn;
182
- /** 查找数组中最大的元素,可传入 mapper 计算出某个值,用作大小比较 */
183
- max(this: T[], mapper?: keyof T | Mapper<T>): T;
184
- /** 查找数组中最小的元素,可传入 mapper 计算出某个值,用作大小比较 */
185
- min(this: T[], mapper?: keyof T | Mapper<T>): T;
182
+ /** 查找数组中最大的元素,可传入 mapper 计算出某个值,用作大小比较,可传 greater 定义大于逻辑 (计算之后的值) */
183
+ max(this: T[], mapper?: keyof T | Mapper<T>, greater?: Greater): T;
184
+ /** 查找数组中最小的元素,可传入 mapper 计算出某个值,用作大小比较,可设置 less 定义小于逻辑 (计算之后的值) */
185
+ min(this: T[], mapper?: keyof T | Mapper<T>, less?: Less): T;
186
186
  /** 去除重复元素(可按 mapper 选择或计算某个值来去重),重复值保留最后出现的那个
187
187
  - mapper?: 可以是 key (string, number, symbol) 或 (obj: any) => any */
188
188
  unique(this: T[], mapper?: keyof T | Mapper<T>): T[];
@@ -232,6 +232,10 @@ export declare const empty: (value: any) => boolean;
232
232
  export declare const is_key_type: IsKeyType;
233
233
  type IsKeyType = (key: any) => key is string | number | symbol;
234
234
  export declare function rethrow(error: Error): void;
235
+ export type Greater<T = any> = (a: T, b: T) => boolean;
236
+ export declare const greater: Greater;
237
+ export type Less = Greater;
238
+ export declare const less: Less;
235
239
  export declare function to_snake_case(str: string): string;
236
240
  export declare function to_space_case(str: string): string;
237
241
  export declare function to_method_property_descriptors(methods: {
@@ -14,6 +14,8 @@ export const is_key_type = ((key) => key_types.includes(typeof key));
14
14
  export function rethrow(error) {
15
15
  throw error;
16
16
  }
17
+ export const greater = (a, b) => a > b;
18
+ export const less = (a, b) => a < b;
17
19
  export function to_snake_case(str) {
18
20
  return str.replace(/([A-Z])/g, '_$1')
19
21
  .toLowerCase()
@@ -532,32 +534,32 @@ if (!globalThis.my_prototype_defined) {
532
534
  mapper ??= ident;
533
535
  return this.reduce((acc, x) => acc + mapper(x), zero);
534
536
  },
535
- max(mapper = ident) {
537
+ max(mapper = ident, _greater = greater) {
536
538
  if (!this.length)
537
539
  return undefined;
538
540
  if (is_key_type(mapper))
539
541
  mapper = select(mapper);
540
542
  let max = mapper(this[0]);
541
543
  let imax = 0;
542
- for (let i = 0; i < this.length; i++) {
544
+ for (let i = 1; i < this.length; i++) {
543
545
  const value = mapper(this[i]);
544
- if (value > max) {
546
+ if (_greater(value, max)) {
545
547
  max = value;
546
548
  imax = i;
547
549
  }
548
550
  }
549
551
  return this[imax];
550
552
  },
551
- min(mapper = ident) {
553
+ min(mapper = ident, _less = less) {
552
554
  if (!this.length)
553
555
  return undefined;
554
556
  if (is_key_type(mapper))
555
557
  mapper = select(mapper);
556
558
  let min = mapper(this[0]);
557
559
  let imin = 0;
558
- for (let i = 0; i < this.length; i++) {
560
+ for (let i = 1; i < this.length; i++) {
559
561
  const value = mapper(this[i]);
560
- if (value < min) {
562
+ if (_less(value, min)) {
561
563
  min = value;
562
564
  imin = i;
563
565
  }
package/server.d.ts CHANGED
@@ -46,6 +46,7 @@ export declare class Server {
46
46
  /** platform_version (1 ~ 8) - 1 作为索引下标 */
47
47
  win10: string[];
48
48
  };
49
+ static ignore_error_codes: Set<string>;
49
50
  app: Koa;
50
51
  handler: ReturnType<Koa['callback']>;
51
52
  /** 启用 http server */
package/server.js CHANGED
@@ -57,6 +57,7 @@ export class Server {
57
57
  'win10 1909',
58
58
  ]
59
59
  };
60
+ static ignore_error_codes = new Set(['ERR_STREAM_PREMATURE_CLOSE', 'EPIPE', 'ECONNRESET']);
60
61
  app;
61
62
  handler;
62
63
  /** 启用 http server */
@@ -260,14 +261,11 @@ export class Server {
260
261
  on_error(error, ctx) {
261
262
  if (!this.print.errors)
262
263
  return;
263
- const code = error?.code;
264
- if (code === 'EPIPE' || code === 'ECONNRESET')
265
- console.log(`${error.code}:`, ctx?.request?.url);
266
- else {
267
- console.error(error);
268
- if (ctx)
269
- console.log('ctx:', ctx);
270
- }
264
+ if (Server.ignore_error_codes.has(error?.code))
265
+ return;
266
+ console.error(error);
267
+ if (ctx)
268
+ console.log('ctx:', ctx);
271
269
  }
272
270
  on_upgrade(request, socket, head) {
273
271
  // url 只有路径部分
@@ -441,12 +439,9 @@ export class Server {
441
439
  const { 'user-agent': user_agent, 'sec-ch-ua': ua, 'sec-ch-ua-mobile': mobile, 'sec-ch-ua-model': _model, 'sec-ch-ua-platform': _platform, 'sec-ch-ua-platform-version': _platform_version } = headers;
442
440
  // --- client hints
443
441
  let model = _model?.slice(1, -1).toLowerCase();
444
- if (model === '22127rk46c')
445
- model = 'redmi k60 pro';
446
- else if (model === '23013rk75c')
447
- model = 'redmi k60';
448
- else if (model === '24129pn74c')
449
- model = 'xiaomi 15';
442
+ const km = known_models[model];
443
+ if (km)
444
+ model = km;
450
445
  const ch_platform = [
451
446
  model,
452
447
  mobile === '?1' ? 'mobile' : '',
@@ -516,12 +511,12 @@ export class Server {
516
511
  if (part0 && part0.startsWith('Mozilla/5.0 (') && part0.endsWith(')')) {
517
512
  // 只取括号中间的
518
513
  ua_platform = part0.slice(13, -1).toLowerCase()
519
- .replace('22127rk46c', 'redmi k60 pro')
520
- .replace('23013rk75c', 'redmi k60')
521
- .replace('24129pn74c', 'xiaomi 15')
522
514
  .replace('macintosh', 'mac')
523
515
  .replace('linux; android', 'android')
524
- .replace(' build/tkq1.220905.001', '');
516
+ .replace(' build/tkq1.220905.001', '')
517
+ .replace(' build/bp2a.250605.031.a3', '');
518
+ for (const k in known_models)
519
+ ua_platform = ua_platform.replace(k, known_models[k]);
525
520
  // 没有多余的信息,屏蔽
526
521
  if (ua_platform === 'windows nt 10.0; win64; x64' && ch_platform.includes('win1'))
527
522
  ua_platform = '';
@@ -822,6 +817,13 @@ export class Server {
822
817
  }
823
818
  export const text_plain = 'text/plain; charset=utf-8';
824
819
  const devtools_trash = '/.well-known/appspecific/com.chrome.devtools.json';
820
+ const known_models = {
821
+ '25128pna1c': 'xiaomi 17 ultra leica',
822
+ '2512bpndac': 'xiaomi 17 ultra',
823
+ '22127rk46c': 'redmi k60 pro',
824
+ '23013rk75c': 'redmi k60',
825
+ '24129pn74c': 'xiaomi 15'
826
+ };
825
827
  function listen_http_server(server, port) {
826
828
  let plisten = defer2();
827
829
  server.once('error', plisten.reject);
package/utils.common.d.ts CHANGED
@@ -82,6 +82,10 @@ export declare function timeout<TReturn>(milliseconds: number, action: Promise<T
82
82
  action 返回 trusy 值时认为成功,返回 action 的结果
83
83
  如果次数用尽仍然失败,返回 null */
84
84
  export declare function poll<TResult>(duration: number, times: number, action: (breaker: () => void) => Promise<TResult>): Promise<TResult>;
85
+ /** 每天在固定时间执行操作
86
+ - hour: 0 - 23 之间的整数,在这个点执行
87
+ - action */
88
+ export declare function schedule_everyday(hour: number, minute: number, action: () => void | Promise<void>): Promise<void>;
85
89
  /** 模糊过滤字符串列表或对象列表,常用于根据用户输入补全或搜索过滤
86
90
  如果有完全匹配关键词的,只返回完全匹配关键词的候选项
87
91
  - query: 查询字符串,要求为全小写
package/utils.common.js CHANGED
@@ -255,6 +255,30 @@ export async function poll(duration, times, action) {
255
255
  }
256
256
  return null;
257
257
  }
258
+ /** 每天在固定时间执行操作
259
+ - hour: 0 - 23 之间的整数,在这个点执行
260
+ - action */
261
+ export async function schedule_everyday(hour, minute, action) {
262
+ const now = Date.now();
263
+ let target = new Date();
264
+ target.setHours(hour, minute, 0, 0);
265
+ // 如果目标时间已过,设定为明天的时间
266
+ if (now > target.getTime())
267
+ target.setDate(target.getDate() + 1);
268
+ // 等时间到
269
+ await delay(target.getTime() - now);
270
+ for (;;) {
271
+ try {
272
+ await action();
273
+ }
274
+ catch (error) {
275
+ // 往上抛没什么意义,打印个日志算了
276
+ console.error(error);
277
+ }
278
+ // 等一天
279
+ await delay(1000 * 60 * 60 * 24);
280
+ }
281
+ }
258
282
  /** 模糊过滤字符串列表或对象列表,常用于根据用户输入补全或搜索过滤
259
283
  如果有完全匹配关键词的,只返回完全匹配关键词的候选项
260
284
  - query: 查询字符串,要求为全小写
package/utils.d.ts CHANGED
@@ -8,10 +8,6 @@ export declare const output_width = 180;
8
8
  export declare const url_width = 52;
9
9
  export declare function set_inspect_options(colors?: boolean): void;
10
10
  export declare function typed_array_to_buffer(view: ArrayBufferView): Buffer<ArrayBufferLike>;
11
- /** 每天在固定时间执行操作
12
- - hour: 0 - 23 之间的整数,在这个点执行
13
- - action */
14
- export declare function schedule_everyday(hour: number, minute: number, action: () => Promise<void>): Promise<void>;
15
11
  export declare function log_line(): void;
16
12
  export declare function sha256(data: string | Uint8Array): string;
17
13
  export declare function sha1(data: string | Uint8Array): string;
package/utils.js CHANGED
@@ -3,7 +3,7 @@ import util from 'node:util';
3
3
  import ncrypto from 'node:crypto';
4
4
  import "./prototype.js";
5
5
  import "./platform.js";
6
- import { assert, decode, defer, delay } from "./utils.common.js";
6
+ import { assert, decode, defer } from "./utils.common.js";
7
7
  export * from "./utils.common.js";
8
8
  /** `180` 输出字符宽度 */
9
9
  export const output_width = 180;
@@ -27,30 +27,6 @@ export function set_inspect_options(colors = true) {
27
27
  export function typed_array_to_buffer(view) {
28
28
  return Buffer.from(view.buffer, view.byteOffset, view.byteLength);
29
29
  }
30
- /** 每天在固定时间执行操作
31
- - hour: 0 - 23 之间的整数,在这个点执行
32
- - action */
33
- export async function schedule_everyday(hour, minute, action) {
34
- const now = Date.now();
35
- let target = new Date();
36
- target.setHours(hour, minute, 0, 0);
37
- // 如果目标时间已过,设定为明天的时间
38
- if (now > target.getTime())
39
- target.setDate(target.getDate() + 1);
40
- // 等时间到
41
- await delay(target.getTime() - now);
42
- for (;;) {
43
- try {
44
- await action();
45
- }
46
- catch (error) {
47
- // 往上抛没什么意义,打印个日志算了
48
- console.error(error);
49
- }
50
- // 等一天
51
- await delay(1000 * 60 * 60 * 24);
52
- }
53
- }
54
30
  export function log_line() {
55
31
  console.log('---');
56
32
  }