xshell 1.3.4 → 1.3.6

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 CHANGED
@@ -1,8 +1,8 @@
1
- import type net from 'node:net';
1
+ import net from 'node:net';
2
2
  import { type Readable } from 'node:stream';
3
3
  import type { Cookie, CookieJar, MemoryCookieStore } from 'tough-cookie';
4
4
  import type { Encoding } from './file.ts';
5
- import { inspect } from './utils.ts';
5
+ import { inspect, type Deferred2, type OnTimeout } from './utils.ts';
6
6
  import { type BasicAuth, type BearerAuth } from './net.common.ts';
7
7
  export * from './net.common.ts';
8
8
  export declare enum MyProxy {
@@ -110,4 +110,25 @@ export declare function request(url: string | URL, options: RequestOptions & {
110
110
  export declare function request(url: string | URL, options: RequestOptions): Promise<string>;
111
111
  /** 发起 http 请求并将响应体作为 json 解析 */
112
112
  export declare function request_json<T = any>(url: string | URL, options?: RequestOptions): Promise<T>;
113
+ export interface ConnectOptions {
114
+ local_port?: number;
115
+ timeout?: number;
116
+ on_timeout?: OnTimeout;
117
+ print?: {
118
+ error: boolean;
119
+ connect: boolean;
120
+ };
121
+ }
122
+ /** 建立 tcp 连接,超时时间为 2 秒 (timeout 选项),返回已连接的 socket
123
+ 连接中遇到的错误会 reject,之后取消监听 error 事件,由调用者 attach 处理
124
+ 连接超时则自动 socket.resetAndDestroy
125
+ - hostname: 要连接到的 ip 或域名
126
+ - port: 要连接的端口
127
+ - options?:
128
+ - local_port?: `随机端口` 使用的本地端口
129
+ - timeout?: `2000` 超时时间
130
+ - print?: 打印连接日志,错误日志
131
+ - error?: `true`
132
+ - connect: `false` */
133
+ export declare function connect(hostname: string, port: number, { local_port, timeout: _timeout, on_timeout, print }?: ConnectOptions): Deferred2<net.Socket>;
113
134
  export declare function get_socket_ip(socket: net.Socket): string;
package/net.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import zlib from 'node:zlib';
2
+ import net from 'node:net';
2
3
  import { buffer as stream_to_buffer, text as stream_to_text } from 'node:stream/consumers';
3
4
  import { pipeline, isReadable } from 'node:stream';
4
5
  import { noop } from "./prototype.js";
5
- import { inspect, assert, delay, map_values, unique, timeout, check, colored, encode, TimeoutError } from "./utils.js";
6
+ import { inspect, assert, delay, map_values, unique, timeout, check, colored, encode, TimeoutError, set_error_message, defer2 } from "./utils.js";
6
7
  import { drop_request_headers } from "./net.common.js";
7
8
  export * from "./net.common.js";
8
9
  export var MyProxy;
@@ -292,6 +293,75 @@ export async function request_json(url, options) {
292
293
  throw error;
293
294
  }
294
295
  }
296
+ /** 建立 tcp 连接,超时时间为 2 秒 (timeout 选项),返回已连接的 socket
297
+ 连接中遇到的错误会 reject,之后取消监听 error 事件,由调用者 attach 处理
298
+ 连接超时则自动 socket.resetAndDestroy
299
+ - hostname: 要连接到的 ip 或域名
300
+ - port: 要连接的端口
301
+ - options?:
302
+ - local_port?: `随机端口` 使用的本地端口
303
+ - timeout?: `2000` 超时时间
304
+ - print?: 打印连接日志,错误日志
305
+ - error?: `true`
306
+ - connect: `false` */
307
+ export function connect(hostname, port, { local_port, timeout: _timeout = 2000, on_timeout, print = { error: true, connect: false } } = {}) {
308
+ let pconnected = defer2();
309
+ let timeouted = false;
310
+ function get_message(message) {
311
+ return `tcp://${hostname}:${port} ${message}`;
312
+ }
313
+ let socket = net.connect({
314
+ host: hostname,
315
+ port,
316
+ localPort: local_port,
317
+ noDelay: true
318
+ }, () => {
319
+ if (pconnected.settled) {
320
+ if (print)
321
+ console.warn(get_message('连接建立了,但是已超时'.yellow));
322
+ socket.resetAndDestroy();
323
+ }
324
+ else {
325
+ clearTimeout(timeout);
326
+ socket.off('error', on_error);
327
+ if (print.connect)
328
+ console.log(get_message('已连接'));
329
+ pconnected.resolve(socket);
330
+ }
331
+ });
332
+ const on_error = (error) => {
333
+ if (pconnected.settled) {
334
+ // 超时后可能会走到这里
335
+ if (timeouted && error.code === 'ERR_SOCKET_CLOSED')
336
+ return;
337
+ // 待观察:不太可能走到这里
338
+ if (print.error)
339
+ console.error(get_message(error.message.red));
340
+ }
341
+ else {
342
+ clearTimeout(timeout);
343
+ pconnected.reject(set_error_message(error, get_message(error.message)));
344
+ }
345
+ };
346
+ socket.once('error', on_error);
347
+ let timeout = setTimeout(async () => {
348
+ // 执行到这里一定没有 settled
349
+ timeouted = true;
350
+ socket.resetAndDestroy();
351
+ if (typeof on_timeout === 'function') {
352
+ pconnected.resolve(null);
353
+ try {
354
+ await on_timeout(new TimeoutError(get_message('超时了')));
355
+ }
356
+ catch (error) {
357
+ pconnected.reject(error);
358
+ }
359
+ }
360
+ else
361
+ pconnected.reject(new TimeoutError(on_timeout || get_message('超时了')));
362
+ }, _timeout);
363
+ return pconnected;
364
+ }
295
365
  export function get_socket_ip(socket) {
296
366
  return socket.remoteAddress.strip_if_start('::ffff:');
297
367
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xshell",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "bin": {
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
@@ -31,10 +31,10 @@ interface BaseOptions {
31
31
  envs?: Record<string, string>;
32
32
  /** 创建子进程时添加 http_proxy, https_proxy, no_proxy 环境变量以启用代理 */
33
33
  proxy?: MyProxy | true;
34
- /** 控制子进程 stdin,默认为 `false` (读空设备),除非传入了 {@link CallOptions.input} 属性
34
+ /** 控制子进程 stdin,默认为 `Boolean(input)` (false 时读空设备),除非传入了 {@link CallOptions.input} 属性
35
35
  - 默认值:
36
36
  - start(): false ('ignore', 空设备)
37
- - (call|launch)(): true (pipe, 作为 child.stdout 可读流)
37
+ - (call|launch)(): false (pipe, 作为 child.stdin)
38
38
  - `true` 设置子进程 stdin 为 'pipe'
39
39
  - `false` 设置子进程 stdin 为 'ignore' (空设备)
40
40
  - `string` 设置子进程 stdin 为某个文件路径 (打开文件,将句柄设置为子进程 stdin) */
@@ -42,8 +42,8 @@ interface BaseOptions {
42
42
  /** 控制子进程 stdout
43
43
  - 默认值:
44
44
  - start(): false ('ignore', 空设备)
45
- - (call|launch)(): true (pipe, 作为 child.stdout 可读流)
46
- - `true` 设置子进程 stdout 为 'pipe' (作为 child.stdout 可读流)
45
+ - (call|launch)(): true (pipe, 作为 child.stdout)
46
+ - `true` 设置子进程 stdout 为 'pipe' (作为 child.stdout)
47
47
  - `false` 设置子进程 stdout 为 'ignore' (空设备)
48
48
  - `string` 设置子进程 stdout 某个文件路径 (打开文件,将句柄设置为子进程 stdout) */
49
49
  stdout?: boolean | string;
package/utils.common.d.ts CHANGED
@@ -63,15 +63,19 @@ export declare function decode(buffer: Uint8Array): string;
63
63
  /** 比较两个 buffer 内容是否相同,第二个可以传入 string 自动编码转换后比较,
64
64
  高频调用时建议提前编码 right 并缓存 */
65
65
  export declare function buffer_equals(left: Uint8Array, right: Uint8Array | string): boolean;
66
+ export type OnTimeout = string | ((error: TimeoutError) => void | Promise<void>);
66
67
  /** 在指定的时间 (milliseconds) 内运行某个任务,超时之后抛出错误或调用 on_timeout
67
68
  - milliseconds: 限时毫秒数
68
69
  - action?: 要等待运行的任务, async function 或 promise
69
- - on_timeout?: 超时后调用的函数
70
- - 若传: 超时时调用会调用 on_timeout,参数为 TimeoutError,然后等待 on_timeout 执行完成
71
- 最后 timeout 函数正常返回 null,如果 on_timeout 报错,同样会 reject
70
+ - on_timeout?: 超时后调用的函数,或者设置错误消息
71
+ - 若传:
72
+ - string: 作为 TimeoutError error message
73
+ - 传 function: 超时时调用会调用 on_timeout,参数为 TimeoutError,然后等待 on_timeout 执行完成
74
+ - on_timeout 函数正常运行: timeout 函数返回 null
75
+ - on_timeout 报错: timeout 函数最终抛出这个错误
72
76
  - 若不传: 直接抛出 TimeoutError
73
77
  - print?: `true` 打印已超时任务的错误 */
74
- export declare function timeout<TReturn>(milliseconds: number, action: Promise<TReturn> | (() => Promise<TReturn>), on_timeout?: (error: TimeoutError) => void | Promise<void>, print?: boolean): Promise<TReturn>;
78
+ export declare function timeout<TReturn>(milliseconds: number, action: Promise<TReturn> | (() => Promise<TReturn>), on_timeout?: OnTimeout, print?: boolean): Deferred2<TReturn>;
75
79
  /** 轮询尝试 action 共 times 次,每次间隔 duration
76
80
  action 返回 trusy 值时认为成功,返回 action 的结果
77
81
  如果次数用尽仍然失败,返回 null */
package/utils.common.js CHANGED
@@ -186,17 +186,20 @@ export function buffer_equals(left, right) {
186
186
  /** 在指定的时间 (milliseconds) 内运行某个任务,超时之后抛出错误或调用 on_timeout
187
187
  - milliseconds: 限时毫秒数
188
188
  - action?: 要等待运行的任务, async function 或 promise
189
- - on_timeout?: 超时后调用的函数
190
- - 若传: 超时时调用会调用 on_timeout,参数为 TimeoutError,然后等待 on_timeout 执行完成
191
- 最后 timeout 函数正常返回 null,如果 on_timeout 报错,同样会 reject
189
+ - on_timeout?: 超时后调用的函数,或者设置错误消息
190
+ - 若传:
191
+ - string: 作为 TimeoutError error message
192
+ - 传 function: 超时时调用会调用 on_timeout,参数为 TimeoutError,然后等待 on_timeout 执行完成
193
+ - on_timeout 函数正常运行: timeout 函数返回 null
194
+ - on_timeout 报错: timeout 函数最终抛出这个错误
192
195
  - 若不传: 直接抛出 TimeoutError
193
196
  - print?: `true` 打印已超时任务的错误 */
194
- export async function timeout(milliseconds, action, on_timeout, print = true) {
195
- const error = new TimeoutError();
197
+ export function timeout(milliseconds, action, on_timeout, print = true) {
198
+ const error = new TimeoutError(typeof on_timeout === 'string' ? on_timeout : undefined);
196
199
  let presult = defer2();
197
200
  let waiting_on_timeout = false;
198
201
  let timeout = setTimeout(async () => {
199
- if (on_timeout) {
202
+ if (typeof on_timeout === 'function')
200
203
  try {
201
204
  waiting_on_timeout = true;
202
205
  await on_timeout(error);
@@ -205,7 +208,6 @@ export async function timeout(milliseconds, action, on_timeout, print = true) {
205
208
  catch (error) {
206
209
  presult.reject(error);
207
210
  }
208
- }
209
211
  else
210
212
  presult.reject(error);
211
213
  }, milliseconds);
package/xlint.js CHANGED
@@ -787,9 +787,6 @@ export const xlint_config = {
787
787
  '@typescript-eslint/dot-notation': 'error',
788
788
  // 必须 throw Error
789
789
  '@typescript-eslint/only-throw-error': 'error',
790
- // ------------ async
791
- // 返回 Promise 的函数一定要标记为 async 函数
792
- '@typescript-eslint/promise-function-async': 'error',
793
790
  // 不要 return await promise, 直接 return promise, 除非外面有 try catch
794
791
  '@typescript-eslint/return-await': 'error',
795
792
  // ------------ 括号