xshell 1.3.1 → 1.3.3

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
@@ -218,33 +218,6 @@ export declare function flink(fp_real: string, fp_link: string, { skip_existing,
218
218
  print?: boolean;
219
219
  junction?: boolean;
220
220
  }): Promise<void>;
221
- export interface ZipOptions {
222
- dirname?: string;
223
- print?: {
224
- info: boolean;
225
- files: boolean;
226
- };
227
- }
228
- /** 将文件夹或文件列表压缩为 zip,返回生成的压缩包路径 (fp_zip)
229
- - data:
230
- - fpd_src: 被压缩文件夹路径 (string) 或
231
- - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
232
- - fp_zip: 生成的压缩包路径 (string)
233
- - options?:
234
- - dirname?: `fpd_src.fname` 传入 fpd_src 才生效,修改 zip 中顶层的文件夹的名字(需要以 / 结尾),如 'web/', 为空字符串时去掉顶层文件夹,不要多一个文件夹层级 (flat)
235
- - print?:
236
- - info?: `true` 开始压缩、压缩完成
237
- - files?: `true` 打印压缩文件列表 */
238
- export declare function fzip(data: string | Record<string, string | Uint8Array>, fp_zip: string, options?: ZipOptions): Promise<string>;
239
- /** 将文件夹或文件列表压缩为 zip,返回压缩包数据 (Uint8Array)
240
- - data:
241
- - fpd_src: 被压缩文件夹路径 (string) 或
242
- - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
243
- - options?:
244
- - print?:
245
- - info?: `true` 开始压缩、压缩完成
246
- - files?: `true` 打印压缩文件列表 */
247
- export declare function zip(data: string | Record<string, string | Uint8Array>, options?: ZipOptions): Promise<Buffer>;
248
221
  export interface UnzipOptions {
249
222
  encoding?: Encoding;
250
223
  dryrun?: boolean;
package/file.js CHANGED
@@ -4,7 +4,7 @@ import { t } from "./i18n/instance.js";
4
4
  import { noop, to_json } from "./prototype.js";
5
5
  import { pack, parse } from "./io.common.js";
6
6
  import { path } from "./path.js";
7
- import { check, Lock, WritableMemoryStream, url_width, throttle, decode, strcmp } from "./utils.js";
7
+ import { check, Lock, url_width, throttle, decode, strcmp } from "./utils.js";
8
8
  import { noprint } from "./process.js";
9
9
  export { fsp };
10
10
  export const encodings = ['utf-8', 'gb18030', 'shift-jis', 'utf-16le'];
@@ -481,90 +481,6 @@ export async function flink(fp_real, fp_link, { skip_existing = false, print = t
481
481
  else
482
482
  await fsp.symlink(fp_real, fp_link, is_fpd_real ? 'dir' : 'file');
483
483
  }
484
- /** 将文件夹或文件列表压缩为 zip,返回生成的压缩包路径 (fp_zip)
485
- - data:
486
- - fpd_src: 被压缩文件夹路径 (string) 或
487
- - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
488
- - fp_zip: 生成的压缩包路径 (string)
489
- - options?:
490
- - dirname?: `fpd_src.fname` 传入 fpd_src 才生效,修改 zip 中顶层的文件夹的名字(需要以 / 结尾),如 'web/', 为空字符串时去掉顶层文件夹,不要多一个文件夹层级 (flat)
491
- - print?:
492
- - info?: `true` 开始压缩、压缩完成
493
- - files?: `true` 打印压缩文件列表 */
494
- export async function fzip(data, fp_zip, options) {
495
- return _zip(data, fp_zip, options);
496
- }
497
- /** 将文件夹或文件列表压缩为 zip,返回压缩包数据 (Uint8Array)
498
- - data:
499
- - fpd_src: 被压缩文件夹路径 (string) 或
500
- - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
501
- - options?:
502
- - print?:
503
- - info?: `true` 开始压缩、压缩完成
504
- - files?: `true` 打印压缩文件列表 */
505
- export async function zip(data, options) {
506
- return _zip(data, undefined, options);
507
- }
508
- async function _zip(data, fp_zip, { dirname, print = { files: true, info: true } } = {}) {
509
- let entries;
510
- let fpd_src;
511
- if (typeof data === 'string') {
512
- if (!path.isAbsolute(data) || !data.isdir)
513
- throw new Error('fpd_src 必须是绝对路径且以 / 结尾');
514
- fpd_src = data;
515
- if (dirname === undefined)
516
- dirname = fpd_src.fname;
517
- if (!dirname.isdir)
518
- throw new Error('dirname 需要以 / 结尾');
519
- entries = Object.fromEntries((await flist(fpd_src, noprint))
520
- .map(fp => ([dirname + fp, fpd_src + fp])));
521
- }
522
- else {
523
- check(!dirname, 'dirname 在传入 fpd_src 时才生效');
524
- entries = data;
525
- }
526
- if (print.info)
527
- log_action('开始压缩', fpd_src ? ` ${fpd_src}` : '文件索引', fp_zip ? `${fp_zip}/${dirname || '{entries}'}` : '内存');
528
- const { default: archiver } = await import('archiver');
529
- let archive = archiver('zip');
530
- let ostream = fp_zip ?
531
- fs.createWriteStream(fp_zip, { highWaterMark: 16 * 2 ** 20 /* 16 MB */ })
532
- :
533
- new WritableMemoryStream();
534
- const size = await new Promise(async (resolve, reject) => {
535
- ostream.once('close', () => {
536
- resolve(archive.pointer());
537
- });
538
- ostream.once('error', reject);
539
- archive.once('error', reject);
540
- archive.on('warning', error => {
541
- console.log(error);
542
- });
543
- archive.pipe(ostream);
544
- for (const fp in entries) {
545
- const fdata = entries[fp];
546
- if (fdata instanceof Uint8Array) {
547
- if (print.files)
548
- log_action('压缩', fdata.length.to_fsize_str(), fp);
549
- archive.append(Buffer.isBuffer(fdata) ? fdata : Buffer.from(fdata.buffer), { name: fp });
550
- }
551
- else {
552
- check(fp.isdir === fdata.isdir);
553
- check(path.isAbsolute(fdata));
554
- if (print.files)
555
- log_action('压缩', fdata, fp);
556
- if (fp.isdir)
557
- archive.directory(fdata, fp);
558
- else
559
- archive.file(fdata, { name: fp });
560
- }
561
- }
562
- await archive.finalize();
563
- });
564
- if (print.info)
565
- console.log(`压缩完成,总大小 ${size.to_fsize_str()}`);
566
- return fp_zip || ostream.pbuffer;
567
- }
568
484
  /** 解压 zip 包至文件夹,返回 fpd_out
569
485
  - zip:
570
486
  - 包路径 (string) 或
package/fzip.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ export interface ZipOptions {
2
+ dirname?: string;
3
+ print?: {
4
+ info: boolean;
5
+ files: boolean;
6
+ };
7
+ }
8
+ /** 将文件夹或文件列表压缩为 zip,返回生成的压缩包路径 (fp_zip)
9
+ - data:
10
+ - fpd_src: 被压缩文件夹路径 (string) 或
11
+ - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
12
+ - fp_zip: 生成的压缩包路径 (string)
13
+ - options?:
14
+ - dirname?: `fpd_src.fname` 传入 fpd_src 才生效,修改 zip 中顶层的文件夹的名字(需要以 / 结尾),如 'web/', 为空字符串时去掉顶层文件夹,不要多一个文件夹层级 (flat)
15
+ - print?:
16
+ - info?: `true` 开始压缩、压缩完成
17
+ - files?: `true` 打印压缩文件列表 */
18
+ export declare function fzip(data: string | Record<string, string | Uint8Array>, fp_zip: string, options?: ZipOptions): Promise<string>;
19
+ /** 将文件夹或文件列表压缩为 zip,返回压缩包数据 (Uint8Array)
20
+ - data:
21
+ - fpd_src: 被压缩文件夹路径 (string) 或
22
+ - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
23
+ - options?:
24
+ - dirname?: `fpd_src.fname` 传入 fpd_src 才生效,修改 zip 中顶层的文件夹的名字(需要以 / 结尾),如 'web/', 为空字符串时去掉顶层文件夹,不要多一个文件夹层级 (flat)
25
+ - print?:
26
+ - info?: `true` 开始压缩、压缩完成
27
+ - files?: `true` 打印压缩文件列表 */
28
+ export declare function zip(data: string | Record<string, string | Uint8Array>, options?: ZipOptions): Promise<Buffer>;
package/fzip.js ADDED
@@ -0,0 +1,91 @@
1
+ import fs from 'node:fs';
2
+ import { path } from "./path.js";
3
+ import { flist, log_action } from "./file.js";
4
+ import { noprint } from "./process.js";
5
+ import { WritableMemoryStream, check } from "./utils.js";
6
+ /** 将文件夹或文件列表压缩为 zip,返回生成的压缩包路径 (fp_zip)
7
+ - data:
8
+ - fpd_src: 被压缩文件夹路径 (string) 或
9
+ - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
10
+ - fp_zip: 生成的压缩包路径 (string)
11
+ - options?:
12
+ - dirname?: `fpd_src.fname` 传入 fpd_src 才生效,修改 zip 中顶层的文件夹的名字(需要以 / 结尾),如 'web/', 为空字符串时去掉顶层文件夹,不要多一个文件夹层级 (flat)
13
+ - print?:
14
+ - info?: `true` 开始压缩、压缩完成
15
+ - files?: `true` 打印压缩文件列表 */
16
+ export async function fzip(data, fp_zip, options) {
17
+ return _zip(data, fp_zip, options);
18
+ }
19
+ /** 将文件夹或文件列表压缩为 zip,返回压缩包数据 (Uint8Array)
20
+ - data:
21
+ - fpd_src: 被压缩文件夹路径 (string) 或
22
+ - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
23
+ - options?:
24
+ - dirname?: `fpd_src.fname` 传入 fpd_src 才生效,修改 zip 中顶层的文件夹的名字(需要以 / 结尾),如 'web/', 为空字符串时去掉顶层文件夹,不要多一个文件夹层级 (flat)
25
+ - print?:
26
+ - info?: `true` 开始压缩、压缩完成
27
+ - files?: `true` 打印压缩文件列表 */
28
+ export async function zip(data, options) {
29
+ return _zip(data, undefined, options);
30
+ }
31
+ async function _zip(data, fp_zip, { dirname, print = { files: true, info: true } } = {}) {
32
+ let entries;
33
+ let fpd_src;
34
+ if (typeof data === 'string') {
35
+ if (!path.isAbsolute(data) || !data.isdir)
36
+ throw new Error('fpd_src 必须是绝对路径且以 / 结尾');
37
+ fpd_src = data;
38
+ if (dirname === undefined)
39
+ dirname = fpd_src.fname;
40
+ if (!dirname.isdir)
41
+ throw new Error('dirname 需要以 / 结尾');
42
+ entries = Object.fromEntries((await flist(fpd_src, noprint))
43
+ .map(fp => ([dirname + fp, fpd_src + fp])));
44
+ }
45
+ else {
46
+ check(!dirname, 'dirname 在传入 fpd_src 时才生效');
47
+ entries = data;
48
+ }
49
+ if (print.info)
50
+ log_action('开始压缩', fpd_src ? ` ${fpd_src}` : '文件索引', fp_zip ? `${fp_zip}/${dirname || '{entries}'}` : '内存');
51
+ const { default: archiver } = await import('archiver');
52
+ let archive = archiver('zip');
53
+ let ostream = fp_zip ?
54
+ fs.createWriteStream(fp_zip, { highWaterMark: 16 * 2 ** 20 /* 16 MB */ })
55
+ :
56
+ new WritableMemoryStream();
57
+ const size = await new Promise(async (resolve, reject) => {
58
+ ostream.once('close', () => {
59
+ resolve(archive.pointer());
60
+ });
61
+ ostream.once('error', reject);
62
+ archive.once('error', reject);
63
+ archive.on('warning', error => {
64
+ console.log(error);
65
+ });
66
+ archive.pipe(ostream);
67
+ for (const fp in entries) {
68
+ const fdata = entries[fp];
69
+ if (fdata instanceof Uint8Array) {
70
+ if (print.files)
71
+ log_action('压缩', fdata.length.to_fsize_str(), fp);
72
+ archive.append(Buffer.isBuffer(fdata) ? fdata : Buffer.from(fdata.buffer), { name: fp });
73
+ }
74
+ else {
75
+ check(fp.isdir === fdata.isdir);
76
+ check(path.isAbsolute(fdata));
77
+ if (print.files)
78
+ log_action('压缩', fdata, fp);
79
+ if (fp.isdir)
80
+ archive.directory(fdata, fp);
81
+ else
82
+ archive.file(fdata, { name: fp });
83
+ }
84
+ }
85
+ await archive.finalize();
86
+ });
87
+ if (print.info)
88
+ console.log(`压缩完成,总大小 ${size.to_fsize_str()}`);
89
+ return fp_zip || ostream.pbuffer;
90
+ }
91
+ //# sourceMappingURL=fzip.js.map
package/net.common.d.ts CHANGED
@@ -100,6 +100,8 @@ export interface RemoteOptions {
100
100
  /** 使用者自定义的在 websocket 连接出错时,或者 handlers 出错时的处理
101
101
  用户设置后会覆盖默认的 print 错误功能 */
102
102
  on_error?(error: WebSocketConnectionError | Error, remote: Remote): void;
103
+ /** 使用者自定义的,在重连之前调用的函数,比如可以修改 url,仅连接发起方有效 */
104
+ on_reconnect?(this: Remote): Promise<void>;
103
105
  }
104
106
  /** 通过创建 remote 对象对 websocket rpc 进行抽象
105
107
  使用 remote.call() 进行一元 rpc
@@ -146,10 +148,11 @@ export declare class Remote {
146
148
  error: WebSocketConnectionError | Error;
147
149
  /** 作为 websocket 连接发起方,传入 url
148
150
  作为 websocket 连接接收方,传入 websocket + name */
149
- constructor({ name, url, websocket, funcs, print, verbose, probe, args, on_error, }?: RemoteOptions);
151
+ constructor({ name, url, websocket, funcs, print, verbose, probe, args, on_error, on_reconnect }?: RemoteOptions);
150
152
  /** 统一处理首次连接和连接后的 websocket 错误 */
151
153
  _on_error: (error: WebSocketConnectionError | Error) => void;
152
- reconnect: () => void;
154
+ on_reconnect?: (this: Remote) => Promise<void>;
155
+ reconnect: () => Promise<void>;
153
156
  _on_message: (data: ArrayBuffer) => void;
154
157
  /** 使用者自定义的在 websocket 连接出错时,或者 handlers 出错时的处理
155
158
  用户设置后会覆盖默认的 print 错误功能 */
package/net.common.js CHANGED
@@ -238,12 +238,14 @@ export class Remote {
238
238
  error;
239
239
  /** 作为 websocket 连接发起方,传入 url
240
240
  作为 websocket 连接接收方,传入 websocket + name */
241
- constructor({ name, url, websocket, funcs, print, verbose, probe, args, on_error, } = {}) {
241
+ constructor({ name, url, websocket, funcs, print, verbose, probe, args, on_error, on_reconnect } = {}) {
242
242
  if (name)
243
243
  this.name = name;
244
244
  if (url) {
245
245
  check(!websocket, '构建 Remote 时 url 和 websocket 只能传其中一个');
246
246
  this.url = url;
247
+ if (on_reconnect)
248
+ this.on_reconnect = on_reconnect;
247
249
  }
248
250
  else { // 连接接收方,一定是 nodejs 环境
249
251
  check(websocket, '构建 Remote 时需传入 url 或者 websocket');
@@ -313,8 +315,11 @@ export class Remote {
313
315
  }
314
316
  this.on_error(error, this);
315
317
  };
316
- reconnect = () => {
318
+ on_reconnect;
319
+ reconnect = async () => {
317
320
  this.reconnecting = null;
321
+ if (this.on_reconnect)
322
+ await this.on_reconnect();
318
323
  this.try_connect();
319
324
  };
320
325
  _on_message = (data) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xshell",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "bin": {