xshell 1.2.35 → 1.2.39

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/file.d.ts CHANGED
@@ -175,8 +175,6 @@ export declare function frename(fp: string, fp_: string, { fpd, print, overwrite
175
175
  }): Promise<void>;
176
176
  export interface FMkdirOptions {
177
177
  print?: boolean;
178
- /** `0o777` A file mode. If a string is passed, it is parsed as an octal integer. */
179
- mode?: string | number;
180
178
  }
181
179
  /**
182
180
  递归创建文件夹,确保 fpd 指向的文件夹存在 Create folders recursively, make sure the folder pointed to by fpd exists
@@ -184,9 +182,8 @@ export interface FMkdirOptions {
184
182
 
185
183
  - fpd: 文件夹完整路径 Folder full path
186
184
  - options?:
187
- - print?: `true`
188
- - mode?: `'0o777'` */
189
- export declare function fmkdir(fpd: string, { print, mode }?: FMkdirOptions): Promise<string>;
185
+ - print?: `true` */
186
+ export declare function fmkdir(fpd: string, { print }?: FMkdirOptions): Promise<string>;
190
187
  /** 创建软链接
191
188
  - fp_real: 现在真实文件/文件夹的路径
192
189
  - fp_link: 目标链接文件/文件夹的路径 */
package/file.js CHANGED
@@ -119,8 +119,10 @@ export async function fwrite(fp, data, { print = true, mtime } = {}) {
119
119
  else
120
120
  throw error;
121
121
  }
122
- if (mtime !== undefined)
123
- await fp.utimes(mtime, mtime);
122
+ if (mtime !== undefined) {
123
+ const mseconds = mtime / 1000;
124
+ await fp.utimes(mseconds, mseconds);
125
+ }
124
126
  return fp;
125
127
  }
126
128
  export async function fpack(fp, data, options) {
@@ -422,9 +424,8 @@ export async function frename(fp, fp_, { fpd, print = true, overwrite = true } =
422
424
 
423
425
  - fpd: 文件夹完整路径 Folder full path
424
426
  - options?:
425
- - print?: `true`
426
- - mode?: `'0o777'` */
427
- export async function fmkdir(fpd, { print = true, mode } = {}) {
427
+ - print?: `true` */
428
+ export async function fmkdir(fpd, { print = true } = {}) {
428
429
  check(path.isAbsolute(fpd), `fpd 必须是绝对路径: ${fpd}`);
429
430
  check(fpd.isdir, `fpd 必须以 / 结尾: ${fpd}`);
430
431
  // 类似 D:/ 这样的根路径,调用 fsp.mkdir 会报错无权限
@@ -438,7 +439,7 @@ export async function fmkdir(fpd, { print = true, mode } = {}) {
438
439
  else
439
440
  throw new Error(t('不存在且无法创建文件夹 {{fpd}}', { fpd }));
440
441
  // Calling fs.promises.mkdir() when path is a directory that exists results in a rejection only when recursive is false.
441
- const fpd_ = (await fsp.mkdir(fpd, { recursive: true, mode }))?.fpd;
442
+ const fpd_ = (await fsp.mkdir(fpd, { recursive: true }))?.fpd;
442
443
  if (fpd_) {
443
444
  if (print)
444
445
  console.log(t('已创建文件夹'), fpd);
package/net.browser.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import './prototype.browser.ts';
2
1
  import { type Message } from './io.browser.ts';
3
2
  import { Lock } from './utils.browser.ts';
4
3
  export interface FullResponse<TBody extends ArrayBuffer | string> {
@@ -208,4 +207,18 @@ export declare class Remote {
208
207
  作为 websocket 连接发起方,不需要传入 websocket
209
208
  作为 websocket 连接接收方,必传 websocket 参数 */
210
209
  call<TReturn = any>(func: string, args?: any[], websocket?: WebSocket): Promise<TReturn>;
210
+ /** 调用对端 remote 中的 func, 开始订阅并接收连续的消息 (订阅流)
211
+ - func: 订阅处理函数
212
+ - on_data: 接收开始订阅后的数据
213
+ - options?:
214
+ - on_error?: 处理开始订阅后的错误
215
+ - websocket?: 作为 websocket 连接接收方,必传 websocket 参数 */
216
+ subscribe<TData, TSubscribed = void>(func: string, on_data: (data: TData) => void, { on_error, websocket }?: RemoteSubscribeOptions): Promise<{
217
+ id: number;
218
+ data: TSubscribed;
219
+ }>;
220
+ }
221
+ export interface RemoteSubscribeOptions {
222
+ on_error?(error: Error): void;
223
+ websocket?: WebSocket;
211
224
  }
package/net.browser.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t } from "./i18n/instance.js";
2
- import "./prototype.browser.js"; // to_time_str()
2
+ import { rethrow } from "./prototype.browser.js"; // to_time_str()
3
3
  import { message_symbol, pack, parse } from "./io.browser.js";
4
4
  import { assert, genid, delay, Lock, timeout, check } from "./utils.browser.js";
5
5
  const drop_request_headers = new Set([
@@ -518,5 +518,43 @@ export class Remote {
518
518
  }
519
519
  });
520
520
  }
521
+ /** 调用对端 remote 中的 func, 开始订阅并接收连续的消息 (订阅流)
522
+ - func: 订阅处理函数
523
+ - on_data: 接收开始订阅后的数据
524
+ - options?:
525
+ - on_error?: 处理开始订阅后的错误
526
+ - websocket?: 作为 websocket 连接接收方,必传 websocket 参数 */
527
+ async subscribe(func, on_data, { on_error = rethrow, websocket } = {}) {
528
+ const id = genid();
529
+ let psubscribed = new Promise((resolve, reject) => {
530
+ let first = true;
531
+ this.handlers.set(id, ({ error, data }) => {
532
+ if (error) {
533
+ if (first) {
534
+ first = false;
535
+ this.handlers.delete(id);
536
+ reject(error);
537
+ }
538
+ else
539
+ on_error(error);
540
+ return;
541
+ }
542
+ if (first) {
543
+ first = false;
544
+ resolve({ id, data: data });
545
+ return;
546
+ }
547
+ on_data(data);
548
+ });
549
+ });
550
+ try {
551
+ await this.send({ id, func }, websocket);
552
+ }
553
+ catch (error) {
554
+ this.handlers.delete(id);
555
+ throw error;
556
+ }
557
+ return psubscribed;
558
+ }
521
559
  }
522
560
  //# sourceMappingURL=net.browser.js.map
package/net.d.ts CHANGED
@@ -2,7 +2,6 @@ import { type Readable } from 'stream';
2
2
  import type { FormData } from 'undici';
3
3
  import type { WebSocket, CloseEvent, ErrorEvent } from 'ws';
4
4
  import type { Cookie, CookieJar, MemoryCookieStore } from 'tough-cookie';
5
- import './prototype.ts';
6
5
  import { type Message } from './io.ts';
7
6
  import type { Encoding } from './file.ts';
8
7
  import { inspect, Lock } from './utils.ts';
@@ -271,6 +270,20 @@ export declare class Remote {
271
270
  作为 websocket 连接发起方,不需要传入 websocket
272
271
  作为 websocket 连接接收方,必传 websocket 参数 */
273
272
  call<TReturn = any>(func: string, args?: any[], websocket?: WebSocket): Promise<TReturn>;
273
+ /** 调用对端 remote 中的 func, 开始订阅并接收连续的消息 (订阅流)
274
+ - func: 订阅处理函数
275
+ - on_data: 接收开始订阅后的数据
276
+ - options?:
277
+ - on_error?: 处理开始订阅后的错误
278
+ - websocket?: 作为 websocket 连接接收方,必传 websocket 参数 */
279
+ subscribe<TData, TSubscribed = void>(func: string, on_data: (data: TData) => void, { on_error, websocket }?: RemoteSubscribeOptions): Promise<{
280
+ id: number;
281
+ data: TSubscribed;
282
+ }>;
283
+ }
284
+ export interface RemoteSubscribeOptions {
285
+ on_error?(error: Error): void;
286
+ websocket?: WebSocket;
274
287
  }
275
288
  /** 为连接到 server 的 client 创建 RemoteClient,以便后续调用 client 中方法 */
276
289
  export declare class RemoteClient {
@@ -285,5 +298,5 @@ export declare class RemoteClient {
285
298
  [inspect.custom](): {
286
299
  remote: string;
287
300
  websocket: string;
288
- } & Omit<this, "call" | "websocket" | typeof import("util").inspect.custom | "remote" | "send">;
301
+ } & Omit<this, "websocket" | typeof import("util").inspect.custom | "remote" | "call" | "send">;
289
302
  }
package/net.js CHANGED
@@ -2,7 +2,7 @@ import zlib from 'zlib';
2
2
  import { buffer as stream_to_buffer, text as stream_to_text } from 'stream/consumers';
3
3
  import { isReadable } from 'stream';
4
4
  import { t } from "./i18n/instance.js";
5
- import "./prototype.js";
5
+ import { rethrow } from "./prototype.js";
6
6
  import { message_symbol, pack, parse } from "./io.js";
7
7
  import { inspect, assert, genid, delay, Lock, pipe_with_error, map_values, unique, timeout, check, colored } from "./utils.js";
8
8
  export const WebSocketConnecting = 0;
@@ -706,6 +706,44 @@ export class Remote {
706
706
  }
707
707
  });
708
708
  }
709
+ /** 调用对端 remote 中的 func, 开始订阅并接收连续的消息 (订阅流)
710
+ - func: 订阅处理函数
711
+ - on_data: 接收开始订阅后的数据
712
+ - options?:
713
+ - on_error?: 处理开始订阅后的错误
714
+ - websocket?: 作为 websocket 连接接收方,必传 websocket 参数 */
715
+ async subscribe(func, on_data, { on_error = rethrow, websocket } = {}) {
716
+ const id = genid();
717
+ let psubscribed = new Promise((resolve, reject) => {
718
+ let first = true;
719
+ this.handlers.set(id, ({ error, data }) => {
720
+ if (error) {
721
+ if (first) {
722
+ first = false;
723
+ this.handlers.delete(id);
724
+ reject(error);
725
+ }
726
+ else
727
+ on_error(error);
728
+ return;
729
+ }
730
+ if (first) {
731
+ first = false;
732
+ resolve({ id, data: data });
733
+ return;
734
+ }
735
+ on_data(data);
736
+ });
737
+ });
738
+ try {
739
+ await this.send({ id, func }, websocket);
740
+ }
741
+ catch (error) {
742
+ this.handlers.delete(id);
743
+ throw error;
744
+ }
745
+ return psubscribed;
746
+ }
709
747
  }
710
748
  /** 为连接到 server 的 client 创建 RemoteClient,以便后续调用 client 中方法 */
711
749
  export class RemoteClient {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xshell",
3
- "version": "1.2.35",
3
+ "version": "1.2.39",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -95,7 +95,7 @@
95
95
  "tslib": "^2.8.1",
96
96
  "typescript": "^5.8.3",
97
97
  "ua-parser-js": "^2.0.3",
98
- "undici": "^7.7.0",
98
+ "undici": "^7.8.0",
99
99
  "vinyl": "^3.0.0",
100
100
  "vinyl-fs": "^4.0.0",
101
101
  "webpack": "^5.99.5",
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
@@ -194,7 +194,7 @@ export interface NodeJsOptions {
194
194
  export interface CallNodeJsOptions extends CallOptions, NodeJsOptions {
195
195
  }
196
196
  /** 调用 node <js> 并等待结果
197
- - js: .js 路径 (相对路径根据 cwd 解析)
197
+ - fp_script: .js/.ts 路径 (相对路径根据 cwd 解析)
198
198
  - args?: `[ ]` 参数列表
199
199
  - options?: {@link CallNodeJsOptions} 继承自 {@link CallOptions} 和 {@link NodeJsOptions}
200
200
  - cwd?: `'T:/'`
@@ -206,7 +206,7 @@ export interface CallNodeJsOptions extends CallOptions, NodeJsOptions {
206
206
  - inspect?: nodejs debugger port, 填 9229 端口 (或者传 true) 可以用临时配置来调试
207
207
  - break?: break at first line
208
208
  - host?: 指定 inspect 监听的 host (默认监听 localhost) */
209
- export declare function call_nodejs(js: string, args?: string[], options?: CallNodeJsOptions): Promise<CallResult<string>>;
209
+ export declare function call_nodejs(fp_script: string, args?: string[], options?: CallNodeJsOptions): Promise<CallResult<string>>;
210
210
  export interface StartNodeJsOptions extends StartOptions, NodeJsOptions {
211
211
  }
212
212
  /** 启动独立的 node.js 进程 (detached),执行某个 js 文件
package/process.js CHANGED
@@ -300,7 +300,7 @@ export async function launch(exe, args, options) {
300
300
  });
301
301
  }
302
302
  /** 调用 node <js> 并等待结果
303
- - js: .js 路径 (相对路径根据 cwd 解析)
303
+ - fp_script: .js/.ts 路径 (相对路径根据 cwd 解析)
304
304
  - args?: `[ ]` 参数列表
305
305
  - options?: {@link CallNodeJsOptions} 继承自 {@link CallOptions} 和 {@link NodeJsOptions}
306
306
  - cwd?: `'T:/'`
@@ -312,8 +312,8 @@ export async function launch(exe, args, options) {
312
312
  - inspect?: nodejs debugger port, 填 9229 端口 (或者传 true) 可以用临时配置来调试
313
313
  - break?: break at first line
314
314
  - host?: 指定 inspect 监听的 host (默认监听 localhost) */
315
- export async function call_nodejs(js, args, options) {
316
- return call(exe_nodejs, get_nodejs_args(js, args, options), options);
315
+ export async function call_nodejs(fp_script, args, options) {
316
+ return call(exe_nodejs, get_nodejs_args(fp_script, args, options), options);
317
317
  }
318
318
  /** 启动独立的 node.js 进程 (detached),执行某个 js 文件
319
319
  - js: .js 路径 (相对路径根据 cwd 解析)
@@ -221,6 +221,7 @@ export declare const not_empty: (value: any) => boolean;
221
221
  export declare const empty: (value: any) => boolean;
222
222
  export declare const is_key_type: IsKeyType;
223
223
  type IsKeyType = (key: any) => key is string | number | symbol;
224
+ export declare function rethrow(error: Error): void;
224
225
  export declare function to_method_property_descriptors(methods: {
225
226
  [name: string]: Function;
226
227
  }): PropertyDescriptorMap;
@@ -10,6 +10,9 @@ export const not_empty = (value) => value !== null && value !== undefined;
10
10
  export const empty = (value) => value === undefined || value === null;
11
11
  const key_types = ['string', 'number', 'symbol'];
12
12
  export const is_key_type = ((key) => key_types.includes(typeof key));
13
+ export function rethrow(error) {
14
+ throw error;
15
+ }
13
16
  export function to_method_property_descriptors(methods) {
14
17
  return Object.fromEntries(Object.entries(methods)
15
18
  .map(([name, value]) => ([name, {
package/prototype.d.ts CHANGED
@@ -251,6 +251,7 @@ export declare const not_empty: (value: any) => boolean;
251
251
  export declare const empty: (value: any) => boolean;
252
252
  export declare const is_key_type: IsKeyType;
253
253
  type IsKeyType = (key: any) => key is string | number | symbol;
254
+ export declare function rethrow(error: Error): void;
254
255
  export declare function to_method_property_descriptors(methods: {
255
256
  [name: string]: Function;
256
257
  }): PropertyDescriptorMap;
package/prototype.js CHANGED
@@ -11,6 +11,9 @@ export const not_empty = (value) => value !== null && value !== undefined;
11
11
  export const empty = (value) => value === undefined || value === null;
12
12
  const key_types = ['string', 'number', 'symbol'];
13
13
  export const is_key_type = ((key) => key_types.includes(typeof key));
14
+ export function rethrow(error) {
15
+ throw error;
16
+ }
14
17
  export function to_method_property_descriptors(methods) {
15
18
  return Object.fromEntries(Object.entries(methods)
16
19
  .map(([name, value]) => ([name, {