xshell 1.0.79 → 1.0.80

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
@@ -179,23 +179,26 @@ export interface ZipOptions {
179
179
  files: boolean;
180
180
  };
181
181
  }
182
- /** 将文件夹压缩为 zip
183
- 返回 fp_zip 或压缩包数据
182
+ /** 将文件夹或文件列表压缩为 zip,返回生成的压缩包路径 (fp_zip)
184
183
  - data:
185
- - 被压缩文件夹路径 (fpd_src: string) 或
186
- - 文件索引对象 (entries: Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
187
- - fp_zip?:
188
- - 传压缩包完整路径时压缩到文件, 函数返回值为 Promise<zip 路径>
189
- - 传 undefined 时压缩到内存, 函数返回值为 Promise<zip Uint8Array>
184
+ - fpd_src: 被压缩文件夹路径 (string) 或
185
+ - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
186
+ - fp_zip: 生成的压缩包路径 (string)
190
187
  - options?:
191
188
  - dirname?: `fpd_src.fname` 传入 fpd_src 才生效,修改 zip 中顶层的文件夹的名字(需要以 / 结尾),如 'web/', 为空字符串时去掉顶层文件夹,不要多一个文件夹层级 (flat)
192
189
  - print?:
193
190
  - info?: `true` 开始压缩、压缩完成
194
191
  - files?: `true` 打印压缩文件列表 */
195
- export declare function fzip(entries: Record<string, string | Uint8Array>, fp_zip?: undefined, options?: ZipOptions): Promise<Uint8Array>;
196
- export declare function fzip(entries: Record<string, string | Uint8Array>, fp_zip: string, options?: ZipOptions): Promise<string>;
197
- export declare function fzip(fpd_src: string, fp_zip?: undefined, options?: ZipOptions): Promise<Uint8Array>;
198
- export declare function fzip(fpd_src: string, fp_zip: string, options?: ZipOptions): Promise<string>;
192
+ export declare function fzip(data: string | Record<string, string | Uint8Array>, fp_zip: string, options?: ZipOptions): Promise<string>;
193
+ /** 将文件夹或文件列表压缩为 zip,返回压缩包数据 (Uint8Array)
194
+ - data:
195
+ - fpd_src: 被压缩文件夹路径 (string)
196
+ - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
197
+ - options?:
198
+ - print?:
199
+ - info?: `true` 开始压缩、压缩完成
200
+ - files?: `true` 打印压缩文件列表 */
201
+ export declare function zip(data: string | Record<string, string | Uint8Array>, options?: ZipOptions): Promise<Buffer>;
199
202
  export declare let fwatchers: Record<string, fs.FSWatcher>;
200
203
  /** 跟踪文本文件追加的内容,类似 tail -f */
201
204
  export declare function ftail(fp: string, handler: (lines: string[]) => void | Promise<void>, { print }?: {
package/file.js CHANGED
@@ -362,7 +362,31 @@ export async function flink(fp_real, fp_link, { junction = false, print = true }
362
362
  else
363
363
  fsp.symlink(fp_real, fp_link, is_fpd_real ? 'dir' : 'file');
364
364
  }
365
- export async function fzip(data, fp_zip, { dirname, print = { files: true, info: true } } = {}) {
365
+ /** 将文件夹或文件列表压缩为 zip,返回生成的压缩包路径 (fp_zip)
366
+ - data:
367
+ - fpd_src: 被压缩文件夹路径 (string) 或
368
+ - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
369
+ - fp_zip: 生成的压缩包路径 (string)
370
+ - options?:
371
+ - dirname?: `fpd_src.fname` 传入 fpd_src 才生效,修改 zip 中顶层的文件夹的名字(需要以 / 结尾),如 'web/', 为空字符串时去掉顶层文件夹,不要多一个文件夹层级 (flat)
372
+ - print?:
373
+ - info?: `true` 开始压缩、压缩完成
374
+ - files?: `true` 打印压缩文件列表 */
375
+ export async function fzip(data, fp_zip, options) {
376
+ return _zip(data, fp_zip, options);
377
+ }
378
+ /** 将文件夹或文件列表压缩为 zip,返回压缩包数据 (Uint8Array)
379
+ - data:
380
+ - fpd_src: 被压缩文件夹路径 (string) 或
381
+ - entries: 文件列表 (Record<压缩后相对路径, 原文件绝对路径 (string) | 数据 (Uint8Array)>)
382
+ - options?:
383
+ - print?:
384
+ - info?: `true` 开始压缩、压缩完成
385
+ - files?: `true` 打印压缩文件列表 */
386
+ export async function zip(data, options) {
387
+ return _zip(data, undefined, options);
388
+ }
389
+ async function _zip(data, fp_zip, { dirname, print = { files: true, info: true } } = {}) {
366
390
  let entries;
367
391
  let fpd_src;
368
392
  if (typeof data === 'string') {
@@ -376,12 +400,14 @@ export async function fzip(data, fp_zip, { dirname, print = { files: true, info:
376
400
  entries = Object.fromEntries((await flist(fpd_src, { print: false }))
377
401
  .map(fp => ([dirname + fp, fpd_src + fp])));
378
402
  }
379
- else
403
+ else {
404
+ assert(!dirname, 'dirname 在传入 fpd_src 时才生效');
380
405
  entries = data;
406
+ }
381
407
  if (print.info)
382
408
  console.log(`开始压缩${fpd_src ? ` ${fpd_src}` : '文件索引'} -> ${fp_zip ? `${fp_zip}/${dirname || '{entries}'}` : '内存'}`);
383
409
  const { default: archiver } = await import('archiver');
384
- let archive = archiver('zip', { zlib: { chunkSize: 16 * 2 ** 20 /* 16 MB */ } });
410
+ let archive = archiver('zip');
385
411
  let ostream = fp_zip ?
386
412
  fs.createWriteStream(fp_zip, { highWaterMark: 16 * 2 ** 20 /* 16 MB */ })
387
413
  :
package/net.js CHANGED
@@ -43,15 +43,16 @@ async function request_retry(url, options, timeout, retries = 0, count = 0) {
43
43
  return await undici_request(url, options);
44
44
  }
45
45
  catch (error) {
46
- if (count >= retries ||
47
- error.name !== 'TimeoutError' && !['ECONNRESET', 'ETIMEDOUT', 'ESOCKETTIMEDOUT'].includes(error.cause?.code))
48
- throw error;
49
- else {
46
+ if (count < retries && (error.name === 'AbortError' || error.name === 'TimeoutError')) {
50
47
  const duration = 2 ** count;
51
48
  console.log(`${t('等待 {{duration}} 秒后重试 fetch ({{_count}}) …', { duration, _count: count }).yellow} ${url.toString().blue.underline}`);
52
49
  await delay(1000 * duration);
53
50
  return request_retry(url, options, timeout, retries, count + 1);
54
51
  }
52
+ else if (error.name === 'AbortError' || error.name === 'TimeoutError')
53
+ throw Object.assign(new Error(`request 超时: ${url.toString()}`), { name: 'TimeoutError' });
54
+ else
55
+ throw error;
55
56
  }
56
57
  }
57
58
  export async function request(url, options = {}) {
@@ -118,6 +119,12 @@ export async function request(url, options = {}) {
118
119
  })(),
119
120
  // todo: 强制手动处理重定向,来正确处理 cookie ?
120
121
  maxRedirections: redirect === 'follow' ? 5 : 0,
122
+ // 下面这些 timeout 都不是总的时间,没法用
123
+ // headersTimeout: timeout - 1000,
124
+ // 从收完 headers 开始算
125
+ // bodyTimeout: timeout - 1000,
126
+ // @ts-ignore 没有类型声明,实际可用
127
+ // connectTimeout: timeout - 1000,
121
128
  headers,
122
129
  // --- body
123
130
  body: (() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xshell",
3
- "version": "1.0.79",
3
+ "version": "1.0.80",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -56,7 +56,7 @@ export declare function encode(str: string): Uint8Array;
56
56
  在流式处理 (buffer 可能不完整) 时,应使用独立的 TextDecoder 实例调用 decode(buffer, { stream: true }) */
57
57
  export declare function decode(buffer: Uint8Array): string;
58
58
  /** 字符串字典序比较 */
59
- export declare function strcmp(l: string, r: string): 0 | 1 | -1;
59
+ export declare function strcmp(l: string, r: string): 1 | 0 | -1;
60
60
  /** 比较 1.10.02 这种版本号 */
61
61
  export declare function vercmp(l: string, r: string): number;
62
62
  export declare function get<TReturn = any>(obj: any, keypath: string): TReturn;
package/utils.d.ts CHANGED
@@ -32,7 +32,7 @@ export declare function map_values<TValue, TNewValue>(obj: {
32
32
  /** 映射对象中的 keys, 返回新对象 */
33
33
  export declare function filter_keys<TObj>(obj: TObj, filter: (key: string) => any): TObj;
34
34
  /** 字符串字典序比较 */
35
- export declare function strcmp(l: string, r: string): 0 | 1 | -1;
35
+ export declare function strcmp(l: string, r: string): 1 | 0 | -1;
36
36
  /** 比较 1.10.02 这种版本号 */
37
37
  export declare function vercmp(l: string, r: string): number;
38
38
  export declare function get<TReturn = any>(obj: any, keypath: string): TReturn;