xshell 1.1.13 → 1.1.14

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/builder.d.ts CHANGED
@@ -140,7 +140,9 @@ export declare class Bundler {
140
140
  build(print?: boolean): Promise<void>;
141
141
  close(): Promise<void>;
142
142
  build_all(print?: boolean): Promise<void>;
143
+ /** 打包构建 js, 构建 html, 复制依赖文件 */
143
144
  build_all_and_close(print?: boolean): Promise<void>;
145
+ /** 仅打包构建 js, 不复制依赖 */
144
146
  build_and_close(print?: boolean): Promise<void>;
145
147
  build_htmls(print?: {
146
148
  info: boolean;
package/builder.js CHANGED
@@ -489,6 +489,7 @@ export class Bundler {
489
489
  this.target === 'web' && this.htmls && this.build_htmls({ info: print, files: false })
490
490
  ]);
491
491
  }
492
+ /** 打包构建 js, 构建 html, 复制依赖文件 */
492
493
  async build_all_and_close(print = true) {
493
494
  await Promise.all([
494
495
  this.build_and_close(print),
@@ -496,6 +497,7 @@ export class Bundler {
496
497
  this.target === 'web' && this.htmls && this.build_htmls({ info: print, files: false })
497
498
  ]);
498
499
  }
500
+ /** 仅打包构建 js, 不复制依赖 */
499
501
  async build_and_close(print = true) {
500
502
  await this.build(print);
501
503
  await this.close();
package/net.browser.d.ts CHANGED
@@ -66,7 +66,7 @@ export declare function request(url: string | URL, options: RequestOptions): Pro
66
66
  /** 发起 http 请求并将响应体作为 json 解析 */
67
67
  export declare function request_json<T = any>(url: string, options?: RequestOptions): Promise<T>;
68
68
  export declare class WebSocketConnectionError extends Error {
69
- name: string;
69
+ name: "WebSocketConnectionError";
70
70
  url: string;
71
71
  protocols?: string[];
72
72
  websocket: WebSocket;
package/net.d.ts CHANGED
@@ -71,6 +71,13 @@ export interface RequestError extends Error {
71
71
  response?: FullResponse<string>;
72
72
  [inspect.custom]: Function;
73
73
  }
74
+ export interface StatusCodeError {
75
+ status: number;
76
+ }
77
+ export declare class StatusCodeError extends Error {
78
+ name: "StatusCodeError";
79
+ constructor(status: number, url: string);
80
+ }
74
81
  /**
75
82
  - url: 必须是完整 url
76
83
  - options?:
@@ -91,7 +98,7 @@ export interface RequestError extends Error {
91
98
  - encoding?: `根据网页 content-type: charset=gb18030 提取 || 'utf-8'` 传入 'binary' 时返回 Buffer
92
99
  (只对非 raw 的请求起作用)
93
100
  - retries?: `false` 可以传入 true (默认 2 次) 或 重试次数
94
- - timeout?: `5 * 1000` 超时后会抛出 error.name 为 'TimeoutError' 的 error, 可以传入 0 来禁用超时
101
+ - timeout?: `5 * 1000` 超时后会抛出 error.name 为 'TimeoutError' 的 error (但类型不是 utils.ts 中的 TimeoutError), 可以传入 0 来禁用超时
95
102
  - auth?: BasicAuth | BearerAuth
96
103
  - cookies?: 需要额外添加到请求的 cookies, 默认情况下携带了 MemoryCookieStore 中保存的之前 http 响应中的 cookies
97
104
  - raw?: `false` 传入后返回整个 response (RawResponse),body 为 Readable
@@ -112,20 +119,8 @@ export declare function request(url: string | URL, options: RequestOptions & {
112
119
  export declare function request(url: string | URL, options: RequestOptions): Promise<string>;
113
120
  /** 发起 http 请求并将响应体作为 json 解析 */
114
121
  export declare function request_json<T = any>(url: string | URL, options?: RequestOptions): Promise<T>;
115
- /** post json to http://localhost:8421/api/rpc
116
- - func: function name
117
- - args?: argument array
118
- - options?:
119
- - ignore?: `false` wait for execution but do not serialize result to response
120
- - async?: `false` do not wait for exec
121
- */
122
- export declare function rpc(func: string, args?: any[], { url, async: _async, ignore }?: {
123
- url?: string;
124
- async?: boolean;
125
- ignore?: boolean;
126
- }): Promise<any>;
127
122
  export declare class WebSocketConnectionError extends Error {
128
- name: string;
123
+ name: "WebSocketConnectionError";
129
124
  url: string;
130
125
  protocols?: string[];
131
126
  event: CloseEvent | ErrorEvent;
package/net.js CHANGED
@@ -3,7 +3,7 @@ import { buffer as stream_to_buffer, text as stream_to_text } from 'stream/consu
3
3
  import { isReadable } from 'stream';
4
4
  import { t } from "./i18n/instance.js";
5
5
  import "./prototype.js";
6
- import { inspect, concat, assert, genid, delay, Lock, encode, decode, pipe_with_error, map_values, unique, timeout, check } from "./utils.js";
6
+ import { inspect, concat, assert, genid, delay, Lock, encode, decode, pipe_with_error, map_values, unique, timeout, check, colored } from "./utils.js";
7
7
  export const WebSocketConnecting = 0;
8
8
  export const WebSocketOpen = 1;
9
9
  export const WebSocketClosing = 2;
@@ -57,16 +57,27 @@ async function request_retry(url, options, _timeout, retries = 0, count = 0, pri
57
57
  if (count < retries) {
58
58
  const duration = 2 ** count;
59
59
  if (print.retry)
60
- console.log(`${t('等待 {{duration}} 秒后重试 request (已尝试 {{_count}} 次) …', { duration, _count: count + 1 }).yellow} ${url.toString().blue.underline}`);
60
+ console.log(`${`等待 ${duration} 秒后重试请求 (已尝试 ${count + 1} ) ··`.yellow} ${url.toString().blue.underline}`);
61
61
  await delay(1000 * duration);
62
62
  return request_retry(url, options, _timeout, retries, count + 1, print);
63
63
  }
64
- else
65
- throw Object.assign(new Error(`request 超时: ${url.toString()}`), { name: 'TimeoutError' });
64
+ else {
65
+ const seconds = _timeout / 1000;
66
+ throw Object.assign(new Error(`请求超过 ${seconds.toFixed(seconds < 1 ? 1 : 0)} 秒等待时间: ${url.toString()}`), { name: 'TimeoutError' });
67
+ }
66
68
  else
67
69
  throw error;
68
70
  }
69
71
  }
72
+ export class StatusCodeError extends Error {
73
+ name = 'StatusCodeError';
74
+ constructor(status, url) {
75
+ super(`状态码 ${status}: ${url}`);
76
+ Object.defineProperties(this, {
77
+ status: { value: status }
78
+ });
79
+ }
80
+ }
70
81
  export async function request(url, options = {}) {
71
82
  let { default: undici, ProxyAgent: UndiciProxyAgent, FormData } = await import('undici');
72
83
  UndiciProxyAgent ??= undici.ProxyAgent;
@@ -117,11 +128,11 @@ export async function request(url, options = {}) {
117
128
  headers.cookie = request_cookies.map(cookie => cookie.cookieString())
118
129
  .join('; ');
119
130
  if (_headers) {
120
- assert(Object.getPrototypeOf(_headers)?.constructor.name !== 'Headers');
131
+ check(Object.getPrototypeOf(_headers)?.constructor.name !== 'Headers');
121
132
  for (const key in _headers)
122
133
  // 可能在 http/2 的 response 中会有这样开头的保留 headers, 在透传时忽略比较好
123
134
  if (!key.startsWith(':') && !key.startsWith('sec-') && !drop_request_headers.has(key)) {
124
- assert(key === key.toLowerCase(), t('传入 request 的 headers 参数中 key 应该都是小写的,实际为 {{key}}', { key }));
135
+ check(key === key.toLowerCase(), `传入 request 的 headers 参数中 key 应该都是小写的,实际为 ${key}`);
125
136
  headers[key] = _headers[key];
126
137
  }
127
138
  }
@@ -142,9 +153,7 @@ export async function request(url, options = {}) {
142
153
  return dispatcher;
143
154
  })();
144
155
  })(),
145
- // todo: 强制手动处理重定向,来正确处理 cookie ?
146
- maxRedirections: redirect === 'follow' ? 5 : 0,
147
- // 下面这些 timeout 都不是总的时间,没法用
156
+ // 下面这些 timeout 都不是总的时间
148
157
  headersTimeout: timeout,
149
158
  // 从收完 headers 开始算
150
159
  bodyTimeout: timeout,
@@ -214,7 +223,7 @@ export async function request(url, options = {}) {
214
223
  body = pipe_with_error(_body, zlib.createBrotliDecompress());
215
224
  break;
216
225
  default:
217
- throw new Error(t('不支持 content-encoding: {{encoding}} 的 http 请求', { encoding: content_encoding.quote() }));
226
+ throw new Error(`不支持 content-encoding: ${content_encoding.quote()} 的 http 请求`);
218
227
  }
219
228
  }
220
229
  response = {
@@ -223,85 +232,49 @@ export async function request(url, options = {}) {
223
232
  body
224
233
  };
225
234
  if (!((200 <= status && status <= 299) || status === 304 || (redirect === 'manual' && 300 <= status && status < 400)))
226
- throw Object.assign(new Error(t('状态码 {{status}}, 非 2xx: {{url}}', { status: response.status, url })), { name: 'StatusCodeError' });
235
+ throw new StatusCodeError(status, url.toString());
227
236
  }
228
237
  catch (error) {
229
- ;
230
- error.url = url;
231
- error.options = options;
232
- if (response)
233
- error.response = {
234
- status: response.status,
235
- headers: response.headers,
236
- body: await stream_to_text(response.body),
237
- };
238
- error[inspect.custom] = (depth, options, inspect) => {
239
- const { colors } = options;
240
- let _method = method || 'GET';
241
- if (colors)
242
- _method = _method.red;
243
- let _url = urlstr;
244
- if (colors)
245
- _url = _url.blue.underline;
246
- let s = '\n' +
247
- `${_method} ${_url}\n`;
248
- if (queries && Object.keys(queries).length) {
249
- let _query = t('请求参数:');
250
- if (colors)
251
- _query = _query.yellow;
252
- s += _query + '\n' +
253
- inspect(queries, options) + '\n';
254
- }
255
- if (body !== undefined) {
256
- let _body = t('请求体:');
257
- if (colors)
258
- _body = _body.yellow;
259
- s += _body + '\n' +
260
- inspect(body, options) + '\n';
261
- }
262
- if (error.name === 'StatusCodeError') {
263
- let _status = t('响应状态码:');
264
- if (colors)
265
- _status = _status.yellow;
266
- let _code = String(response.status);
267
- if (colors)
268
- _code = _code.red;
269
- s += _status + ' ' + _code + '\n';
270
- }
271
- else if (error.name === 'TimeoutError') {
272
- let _timeout = t('超过等待时间:');
273
- if (colors)
274
- _timeout = _timeout.red;
275
- s += `${_timeout} ${timeout} ms\n`;
276
- }
277
- if (response) {
278
- let _headers = t('响应头:');
279
- if (colors)
280
- _headers = _headers.yellow;
281
- s += _headers + '\n';
282
- for (const key in response.headers) {
283
- const value = response.headers[key];
284
- s += `${key}: ${value}\n`;
238
+ response ??= error.response;
239
+ throw Object.defineProperties(error, {
240
+ url: { value: url },
241
+ options: { value: options },
242
+ ...response ? {
243
+ response: {
244
+ value: {
245
+ status: response.status,
246
+ headers: response.headers,
247
+ body: await stream_to_text(response.body),
248
+ }
285
249
  }
286
- if (error.response.body) {
287
- let _body = t('响应体:');
288
- if (colors)
289
- _body = _body.yellow;
290
- s += _body + '\n' +
291
- error.response.body + '\n';
250
+ } : {},
251
+ [inspect.custom]: {
252
+ value(depth, options, inspect) {
253
+ const { colors } = options;
254
+ const c = (str, color) => colored(str, color, colors);
255
+ let s = '\n' +
256
+ `${c(method || 'GET', 'red')} ${c(c(urlstr, 'blue'), 'underline')}\n`;
257
+ if (queries && Object.keys(queries).length)
258
+ s += c('请求参数:\n', 'yellow') +
259
+ inspect(queries, options).ensure_end();
260
+ if (body !== undefined)
261
+ s += c('请求体:\n', 'yellow') +
262
+ inspect(body, options).ensure_end();
263
+ if (response) {
264
+ s += c('响应头:\n', 'yellow');
265
+ for (const key in response.headers) {
266
+ const value = response.headers[key];
267
+ s += `${key}: ${value}\n`;
268
+ }
269
+ if (error.response.body)
270
+ s += c('响应体:\n', 'yellow') +
271
+ error.response.body.toString().ensure_end();
272
+ }
273
+ s += inspect(error, { ...options, customInspect: false });
274
+ return s;
292
275
  }
293
276
  }
294
- let _stack = t('调用栈:');
295
- if (colors)
296
- _stack = _stack.yellow;
297
- s += _stack + '\n';
298
- if (error.cause)
299
- s += inspect(error.cause, options) + '\n';
300
- s += error.stack + '\n' +
301
- '\n';
302
- return s;
303
- };
304
- throw error;
277
+ });
305
278
  }
306
279
  if (raw)
307
280
  return response;
@@ -337,26 +310,6 @@ export async function request_json(url, options) {
337
310
  throw error;
338
311
  }
339
312
  }
340
- // ------------------------------------ rpc client
341
- /** post json to http://localhost:8421/api/rpc
342
- - func: function name
343
- - args?: argument array
344
- - options?:
345
- - ignore?: `false` wait for execution but do not serialize result to response
346
- - async?: `false` do not wait for exec
347
- */
348
- export async function rpc(func, args, { url = 'http://localhost:8421/api/rpc', async: _async = false, ignore = false } = {}) {
349
- if (!func)
350
- throw new Error('rpc argument error: no func');
351
- return request_json(url, {
352
- body: {
353
- func,
354
- args,
355
- async: _async,
356
- ignore,
357
- }
358
- });
359
- }
360
313
  export class WebSocketConnectionError extends Error {
361
314
  name = 'WebSocketConnectionError';
362
315
  // 这里不保留 websocket 引用,防止循环引用导致 JSON 序列化失败
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xshell",
3
- "version": "1.1.13",
3
+ "version": "1.1.14",
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
@@ -1,8 +1,8 @@
1
+ import type { InspectOptions } from 'util';
1
2
  import { type ChildProcess } from 'child_process';
2
3
  import './prototype.ts';
3
4
  import type { Encoding } from './file.ts';
4
5
  import type { MyProxy } from './net.ts';
5
- import { inspect } from './utils.ts';
6
6
  export declare const sea: boolean;
7
7
  export declare const exe_nodejs: string;
8
8
  export declare const platform: NodeJS.Platform;
@@ -103,8 +103,7 @@ export interface CallResult<TOutput extends string | Buffer = string> {
103
103
  child: ChildProcess;
104
104
  print: FullPrintOptions;
105
105
  }
106
- export declare class CallError<TOutput extends string | Buffer = string> extends Error {
107
- name: string;
106
+ export interface CallError<TOutput extends string | Buffer = string> extends Error {
108
107
  pid: number;
109
108
  stdout: TOutput;
110
109
  stderr: TOutput;
@@ -113,8 +112,11 @@ export declare class CallError<TOutput extends string | Buffer = string> extends
113
112
  command: string;
114
113
  child: ChildProcess;
115
114
  print: FullPrintOptions;
115
+ }
116
+ export declare class CallError<TOutput extends string | Buffer = string> extends Error {
117
+ name: "CallError";
116
118
  constructor({ message, pid, stdout, stderr, code, signal, command, child, print }: CallResult<TOutput>);
117
- [inspect.custom](): string;
119
+ [inspect.custom](depth: number, options: InspectOptions, inspect: Function): string;
118
120
  }
119
121
  /** 调用可执行文件,获取返回结果,错误时抛出 CallError
120
122
  - exe: .exe 路径或文件名 (建议使用路径,跳过 path 搜索,性能更高)
package/process.js CHANGED
@@ -2,14 +2,14 @@ import { spawn } from 'child_process';
2
2
  import os from 'os';
3
3
  import node_sea from 'node:sea';
4
4
  import "./prototype.js";
5
- import { inspect, DecoderStream, filter_values, check } from "./utils.js";
5
+ import { inspect, DecoderStream, filter_values, check, colored } from "./utils.js";
6
6
  export const sea = node_sea.isSea();
7
7
  export const exe_nodejs = process.execPath.fp;
8
8
  export const platform = os.platform();
9
9
  export const username = os.userInfo().username;
10
10
  export const noprint = { print: false };
11
11
  export const print_no_command = { print: { command: false, code: false, stdout: true, stderr: true } };
12
- async function prepare_spawn(detached, exe, args, { cwd, window: _window = true, envs,
12
+ async function prepare_spawn(detached, exe, args, { cwd, window: _window, envs,
13
13
  // @ts-ignore
14
14
  input, fp_stdin, fp_stdout, fp_stderr, print = true, proxy,
15
15
  // @ts-ignore
@@ -94,7 +94,7 @@ stdio }) {
94
94
  cwd,
95
95
  shell: false,
96
96
  // processhacker 在 windowsHide 为 true 时不显示窗口
97
- windowsHide: !_window,
97
+ windowsHide: _window ?? Boolean(!detached || fp_stdout),
98
98
  detached,
99
99
  stdio,
100
100
  ...envs_ ? { env: envs_ } : {}
@@ -128,29 +128,29 @@ export async function start(exe, args = [], options = {}) {
128
128
  }
129
129
  export class CallError extends Error {
130
130
  name = 'CallError';
131
- pid;
132
- stdout;
133
- stderr;
134
- code;
135
- signal;
136
- command;
137
- child;
138
- print;
139
131
  constructor({ message, pid, stdout, stderr, code, signal, command, child, print }) {
140
132
  super(message);
141
- this.pid = pid;
142
- this.stdout = stdout;
143
- this.stderr = stderr;
144
- this.code = code;
145
- this.signal = signal;
146
- this.command = command;
147
- this.child = child;
148
- this.print = print;
133
+ // defineProperty 默认 enumerable: false,不会在 inspect 中显示
134
+ Object.defineProperties(this, {
135
+ pid: { value: pid },
136
+ stdout: { value: stdout },
137
+ stderr: { value: stderr },
138
+ code: { value: code },
139
+ signal: { value: signal },
140
+ command: { value: command },
141
+ child: { value: child },
142
+ print: { value: print }
143
+ });
149
144
  }
150
- [inspect.custom]() {
151
- return (!this.print.stdout && this.stdout ? `标准输出:\n${this.stdout}\n` : '') +
152
- (!this.print.stderr && this.stderr ? `标准错误:\n${this.stderr}\n` : '') +
153
- this.stack;
145
+ [inspect.custom](depth, options, inspect) {
146
+ const { colors } = options;
147
+ return (!this.print.stdout && this.stdout
148
+ ? `${colored('标准输出:\n', 'yellow', colors)}${this.stdout.toString().ensure_end()}`
149
+ : '') +
150
+ (!this.print.stderr && this.stderr
151
+ ? `${colored('标准错误:\n', 'yellow', colors)}${this.stderr.toString().ensure_end()}`
152
+ : '') +
153
+ inspect(this, { ...options, customInspect: false });
154
154
  }
155
155
  }
156
156
  export async function call(exe, args = [], options = {}) {
@@ -92,6 +92,10 @@ declare global {
92
92
  strip_end(this: string, suffix: string, validate?: boolean): string;
93
93
  /** 返回去掉 suffix 结尾的字符串,如果没有以 suffix 结尾则返回原字符串 */
94
94
  strip_if_end(this: string, suffix: string): string;
95
+ /** 确保字符串以 prefix 开头,否则在头部追加 prefix */
96
+ ensure_start(this: string, prefix: string): string;
97
+ /** 确保字符串以 suffix (默认 '\n') 结尾,否则在尾部追加 suffix */
98
+ ensure_end(this: string, suffix?: string): string;
95
99
  /** 从 search 字符串出现的位置开始截取到最后
96
100
  - options?:
97
101
  - include?: `false` 传 true 时包括 search 部分
@@ -287,6 +287,12 @@ Object.defineProperties(String.prototype, {
287
287
  strip_if_end(suffix) {
288
288
  return this.endsWith(suffix) ? this.slice(0, -suffix.length) : this;
289
289
  },
290
+ ensure_start(prefix) {
291
+ return this.startsWith(prefix) ? this : prefix + this;
292
+ },
293
+ ensure_end(suffix = '\n') {
294
+ return this.endsWith(suffix) ? this : this + suffix;
295
+ },
290
296
  slice_from(search, { include = false, last = false } = {}) {
291
297
  const i = last ? this.lastIndexOf(search) : this.indexOf(search);
292
298
  if (i === -1)
package/prototype.d.ts CHANGED
@@ -114,6 +114,10 @@ declare global {
114
114
  strip_end(this: string, suffix: string, validate?: boolean): string;
115
115
  /** 返回去掉 suffix 结尾的字符串,如果没有以 suffix 结尾则返回原字符串 */
116
116
  strip_if_end(this: string, suffix: string): string;
117
+ /** 确保字符串以 prefix 开头,否则在头部追加 prefix */
118
+ ensure_start(this: string, prefix: string): string;
119
+ /** 确保字符串以 suffix (默认 '\n') 结尾,否则在尾部追加 suffix */
120
+ ensure_end(this: string, suffix?: string): string;
117
121
  /** 从 search 字符串出现的位置开始截取到最后
118
122
  - options?:
119
123
  - include?: `false` 传 true 时包括 search 部分
package/prototype.js CHANGED
@@ -309,6 +309,12 @@ if (!globalThis.my_prototype_defined) {
309
309
  strip_if_end(suffix) {
310
310
  return this.endsWith(suffix) ? this.slice(0, -suffix.length) : this;
311
311
  },
312
+ ensure_start(prefix) {
313
+ return this.startsWith(prefix) ? this : prefix + this;
314
+ },
315
+ ensure_end(suffix = '\n') {
316
+ return this.endsWith(suffix) ? this : this + suffix;
317
+ },
312
318
  slice_from(search, { include = false, last = false } = {}) {
313
319
  const i = last ? this.lastIndexOf(search) : this.indexOf(search);
314
320
  if (i === -1)
@@ -344,6 +350,9 @@ if (!globalThis.my_prototype_defined) {
344
350
  .replace(new RegExp(cjk + '([~!;:,\\.\\?\u2026])([A-Za-z0-9])', 'g'), '$1$2 $3')
345
351
  .replace(new RegExp(cjk + '([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])', 'g'), '$1 $2')
346
352
  .replace(new RegExp('([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])' + cjk, 'g'), '$1 $2');
353
+ },
354
+ to_backslash() {
355
+ return this.replaceAll('/', '\\');
347
356
  }
348
357
  }),
349
358
  // ------------ colors
@@ -404,11 +413,6 @@ if (!globalThis.my_prototype_defined) {
404
413
  ? ''
405
414
  : fname.slice(index + 1);
406
415
  }
407
- }),
408
- ...to_method_property_descriptors({
409
- to_backslash() {
410
- return this.replaceAll('/', '\\');
411
- }
412
416
  })
413
417
  });
414
418
  // ------------------------------------ Date.prototype
@@ -22,7 +22,7 @@ export declare function delay(milliseconds: number, { signal }?: {
22
22
  signal?: AbortSignal;
23
23
  }): Promise<void>;
24
24
  export declare class TimeoutError extends Error {
25
- constructor(message?: string, options?: ErrorOptions);
25
+ name: "TimeoutError";
26
26
  }
27
27
  /** 在指定的时间 (milliseconds) 内运行某个任务,超时之后
28
28
  - 如果传入了 on_timeout 参数: 调用 on_timeout,返回 null
@@ -79,11 +79,13 @@ export declare function encode(str: string): Uint8Array<ArrayBufferLike>;
79
79
  在流式处理 (buffer 可能不完整) 时,应使用独立的 TextDecoder 实例调用 decode(buffer, { stream: true }) */
80
80
  export declare function decode(buffer: Uint8Array): string;
81
81
  /** 字符串字典序比较 */
82
- export declare function strcmp(l: string, r: string): 0 | 1 | -1;
82
+ export declare function strcmp(l: string, r: string): 1 | 0 | -1;
83
83
  /** 比较 1.10.02 这种版本号
84
84
  - l, r: 两个版本号字符串
85
85
  - loose?: 宽松模式,允许两个版本号格式(位数)不一致 */
86
86
  export declare function vercmp(l: string, r: string, loose?: boolean): number;
87
+ /** 过滤符合 pattern 的行 */
88
+ export declare function grep(str: string, pattern: string | RegExp): string;
87
89
  /** 模糊过滤字符串列表或对象列表,常用于根据用户输入补全或搜索过滤
88
90
  - query: 查询字符串,要求为全小写
89
91
  - list: 要过滤的列表
package/utils.browser.js CHANGED
@@ -74,10 +74,7 @@ export async function delay(milliseconds, { signal } = {}) {
74
74
  });
75
75
  }
76
76
  export class TimeoutError extends Error {
77
- constructor(message, options) {
78
- super(message, options);
79
- this.name = this.constructor.name;
80
- }
77
+ name = 'TimeoutError';
81
78
  }
82
79
  /** 在指定的时间 (milliseconds) 内运行某个任务,超时之后
83
80
  - 如果传入了 on_timeout 参数: 调用 on_timeout,返回 null
@@ -262,6 +259,14 @@ export function vercmp(l, r, loose = false) {
262
259
  // loose 下按短的优先,否则应该一样,为 0
263
260
  return lparts.length - rparts.length;
264
261
  }
262
+ /** 过滤符合 pattern 的行 */
263
+ export function grep(str, pattern) {
264
+ return str.split_lines()
265
+ .filter(typeof pattern === 'string'
266
+ ? line => line.includes(pattern)
267
+ : line => pattern.test(line))
268
+ .join_lines();
269
+ }
265
270
  /** 模糊过滤字符串列表或对象列表,常用于根据用户输入补全或搜索过滤
266
271
  - query: 查询字符串,要求为全小写
267
272
  - list: 要过滤的列表
package/utils.d.ts CHANGED
@@ -40,11 +40,13 @@ export declare function filter_values<TObj extends Record<string, any>>(obj: TOb
40
40
  /** 忽略对象中的 keys, 返回新对象 */
41
41
  export declare function omit<TObj>(obj: TObj, omit_keys: string[]): TObj;
42
42
  /** 字符串字典序比较 */
43
- export declare function strcmp(l: string, r: string): 0 | 1 | -1;
43
+ export declare function strcmp(l: string, r: string): 1 | 0 | -1;
44
44
  /** 比较 1.10.02 这种版本号
45
45
  - l, r: 两个版本号字符串
46
46
  - loose?: 宽松模式,允许两个版本号格式(位数)不一致 */
47
47
  export declare function vercmp(l: string, r: string, loose?: boolean): number;
48
+ /** 过滤符合 pattern 的行 */
49
+ export declare function grep(str: string, pattern: string | RegExp): string;
48
50
  /** 模糊过滤字符串列表或对象列表,常用于根据用户输入补全或搜索过滤
49
51
  - query: 查询字符串,要求为全小写
50
52
  - list: 要过滤的列表
@@ -86,7 +88,7 @@ export declare class Timer {
86
88
  export declare function log_line(): void;
87
89
  export declare function delay(milliseconds: number, options?: TimerOptions): Promise<void>;
88
90
  export declare class TimeoutError extends Error {
89
- constructor(message?: string, options?: ErrorOptions);
91
+ name: "TimeoutError";
90
92
  }
91
93
  /** 在指定的时间 (milliseconds) 内运行某个任务,超时之后
92
94
  - 如果传入了 on_timeout 参数: 调用 on_timeout,返回 null
@@ -152,8 +154,11 @@ export declare function inspect(obj: any, options?: util.InspectOptions & {
152
154
  limit?: number;
153
155
  omit?: string[];
154
156
  }): string;
157
+ /** 根据 enabled 选项返回有 / 无颜色的字符串 (str) */
158
+ export declare function colored(str: string, color: string, enabled?: boolean): any;
155
159
  export declare namespace inspect {
156
160
  const custom: typeof util.inspect.custom;
161
+ const defaultOptions: util.InspectOptions;
157
162
  }
158
163
  /** npm map-stream
159
164
  filter will reemit the data if cb(err,pass) pass is truthy
package/utils.js CHANGED
@@ -132,6 +132,14 @@ export function vercmp(l, r, loose = false) {
132
132
  // loose 下按短的优先,否则应该一样,为 0
133
133
  return lparts.length - rparts.length;
134
134
  }
135
+ /** 过滤符合 pattern 的行 */
136
+ export function grep(str, pattern) {
137
+ return str.split_lines()
138
+ .filter(typeof pattern === 'string'
139
+ ? line => line.includes(pattern)
140
+ : line => pattern.test(line))
141
+ .join_lines();
142
+ }
135
143
  /** 模糊过滤字符串列表或对象列表,常用于根据用户输入补全或搜索过滤
136
144
  - query: 查询字符串,要求为全小写
137
145
  - list: 要过滤的列表
@@ -270,10 +278,7 @@ export async function delay(milliseconds, options) {
270
278
  return timers.setTimeout(milliseconds, undefined, options);
271
279
  }
272
280
  export class TimeoutError extends Error {
273
- constructor(message, options) {
274
- super(message, options);
275
- this.name = this.constructor.name;
276
- }
281
+ name = 'TimeoutError';
277
282
  }
278
283
  /** 在指定的时间 (milliseconds) 内运行某个任务,超时之后
279
284
  - 如果传入了 on_timeout 参数: 调用 on_timeout,返回 null
@@ -449,8 +454,13 @@ export function inspect(obj, options = {}) {
449
454
  else
450
455
  return text;
451
456
  }
457
+ /** 根据 enabled 选项返回有 / 无颜色的字符串 (str) */
458
+ export function colored(str, color, enabled = inspect.defaultOptions.colors) {
459
+ return enabled ? str[color] : str;
460
+ }
452
461
  (function (inspect) {
453
462
  inspect.custom = util.inspect.custom;
463
+ inspect.defaultOptions = util.inspect.defaultOptions;
454
464
  })(inspect || (inspect = {}));
455
465
  // ------------------------------------ stream
456
466
  /** npm map-stream