xshell 1.0.58 → 1.0.60

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/.eslintrc.json CHANGED
@@ -51,6 +51,9 @@
51
51
 
52
52
  "xlint/keep-indent": "error",
53
53
 
54
+ // 函数使用 function 来声明而不是 const foo = () => { }
55
+ "xlint/func-style": "error",
56
+
54
57
 
55
58
  "@typescript-eslint/semi": ["error", "never"],
56
59
  "@typescript-eslint/no-extra-semi": "error",
@@ -170,6 +173,14 @@
170
173
 
171
174
  "@typescript-eslint/prefer-includes": "error",
172
175
 
173
- "@typescript-eslint/prefer-regexp-exec": "error"
176
+ "@typescript-eslint/prefer-regexp-exec": "error",
177
+
178
+ // 禁止使用 export default
179
+ "no-restricted-exports": ["error", { "restrictDefaultExports": { "direct": true, "named": true, "defaultFrom": true, "namedFrom": true, "namespaceFrom": true } }],
180
+
181
+ "@typescript-eslint/consistent-type-imports": ["error", { "fixStyle": "inline-type-imports", "disallowTypeAnnotations": false }],
182
+
183
+ // () => { 返回 void 的表达式 }
184
+ "@typescript-eslint/no-confusing-void-expression": "error"
174
185
  }
175
186
  }
package/file.d.ts CHANGED
@@ -5,6 +5,7 @@ import { promises as fsp, default as fs } from 'fs';
5
5
  type FileHandle = fsp.FileHandle & {
6
6
  fp: string;
7
7
  };
8
+ export { fsp };
8
9
  export type Encoding = 'utf-8' | 'gb18030' | 'shift-jis' | 'utf-16le';
9
10
  export declare const encodings: readonly ["utf-8", "gb18030", "shift-jis", "utf-16le"];
10
11
  /** fp 所指向的 文件/ 文件夹 是否存在
@@ -85,8 +86,8 @@ export interface FListOptions {
85
86
  - deep?: `false` 递归遍历 recursively
86
87
  - absolute?: `false` 返回、打印完整路径而不是相对路径,为 false 时返回的 FStats.fp 也会被修改 Return, print full path instead of relative path, FStats.fp returned when false will also be modified
87
88
  - print?: `true`
88
- - filter?: `true` RegExp | (fp: string) => any 注意当 deep = true 时被 filter 过滤掉的目录及目录中的文件不会包含在结果中
89
- Note that when deep = true, directories and files in directories that are filtered out by the filter will not be included in the results
89
+ - filter?: `() => true` RegExp | (fp: string) => any
90
+ 注意当 deep = true 时被 filter 过滤掉的目录及目录中的文件不会包含在结果中
90
91
  - stats?: `false` 启用后返回 FStats 列表
91
92
  Returns the FStats list when enabled */
92
93
  export declare function flist(fpd: string): Promise<string[]>;
@@ -177,4 +178,3 @@ export declare function ftail(fp: string, handler: (lines: string[]) => void | P
177
178
  export declare function freplace(fp: string, pattern: string | RegExp, replacement: string, { print }?: {
178
179
  print?: boolean;
179
180
  }): Promise<void>;
180
- export {};
package/file.js CHANGED
@@ -4,6 +4,7 @@ import { path } from './path.js';
4
4
  import { t } from './i18n/instance.js';
5
5
  import { to_json } from './prototype.js';
6
6
  import { assert, Lock } from './utils.js';
7
+ export { fsp };
7
8
  export const encodings = ['utf-8', 'gb18030', 'shift-jis', 'utf-16le'];
8
9
  /** fp 所指向的 文件/ 文件夹 是否存在
9
10
  Does the file/folder pointed to by fp exist? */
@@ -269,14 +270,14 @@ export async function fmove(fp_src, fp_dst, { overwrite = false, print = true }
269
270
  assert(path.isAbsolute(fp_src) && path.isAbsolute(fp_dst), t('fp_src 和 fp_dst 必须为完整路径'));
270
271
  if (print)
271
272
  console.log(t('移动'), fp_src, '->', fp_dst);
272
- if (!overwrite && fexists(fp_dst))
273
+ if (!overwrite && fexists(fp_dst, { print: false }))
273
274
  throw new Error(`${t('已存在')} ${fp_dst}`);
274
275
  await fmkdir(fp_dst.fdir, { print: false });
275
276
  async function copy_and_delete() {
276
- await fcopy(fp_src, fp_dst, { overwrite, print });
277
- await fdelete(fp_src, { print });
277
+ await fcopy(fp_src, fp_dst, { overwrite, print: false });
278
+ await fdelete(fp_src, { print: false });
278
279
  }
279
- if (fp_src[0] !== fp_dst[0])
280
+ if (fp_src[0] !== fp_dst[0] || overwrite)
280
281
  await copy_and_delete();
281
282
  else
282
283
  try {
@@ -349,9 +350,9 @@ export async function flink(fp_real, fp_link, { junction = false, print = true }
349
350
  const is_fpd_link = fp_link.isdir;
350
351
  assert(is_fpd_real === is_fpd_link, t('fp_real 和 fp_link 必须同为文件路径或文件夹路径'));
351
352
  if (fexists(fp_link))
352
- throw new Error(t('存在同名') + (is_fpd_link ? t('文件夹') : t('文件')) + ': ' + fp_link + t(',无法创建链接'));
353
+ throw new Error(`${t('存在同名')}${is_fpd_link ? t('文件夹') : t('文件')}: ${fp_link}${t(',无法创建链接')}`);
353
354
  if (print)
354
- console.log(t('已将源文件 ') + fp_real + t(' 链接到 ') + fp_link);
355
+ console.log(`${t('已将源文件 ')}${fp_real}${t(' 链接到 ')}${fp_link}`);
355
356
  if (junction)
356
357
  fsp.symlink(fp_real, fp_link, 'junction');
357
358
  else
package/net.js CHANGED
@@ -87,7 +87,7 @@ export async function request(url, { method, queries, headers: _headers, body, t
87
87
  // --- headers, http/2 开始都用小写的 headers
88
88
  let headers = new Headers({
89
89
  'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,ja-JP;q=0.6,ja;q=0.5',
90
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
90
+ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
91
91
  'sec-ch-ua-platform': '"Windows"',
92
92
  'sec-ch-ua-platform-version': '"15.0.0"',
93
93
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xshell",
3
- "version": "1.0.58",
3
+ "version": "1.0.60",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -16,7 +16,7 @@
16
16
  "interactive programming"
17
17
  ],
18
18
  "engines": {
19
- "node": ">=20.6.0",
19
+ "node": ">=20.6.1",
20
20
  "vscode": ">=1.81.0"
21
21
  },
22
22
  "author": "ShenHongFei <shen.hongfei@outlook.com> (https://github.com/ShenHongFei)",
@@ -45,23 +45,23 @@
45
45
  ]
46
46
  },
47
47
  "dependencies": {
48
- "@babel/core": "^7.22.15",
49
- "@babel/parser": "^7.22.15",
50
- "@babel/traverse": "^7.22.15",
48
+ "@babel/core": "^7.23.3",
49
+ "@babel/parser": "^7.23.3",
50
+ "@babel/traverse": "^7.23.3",
51
51
  "@koa/cors": "^4.0.0",
52
- "@types/ws": "^8.5.5",
52
+ "@types/ws": "^8.5.9",
53
53
  "byte-size": "^8.1.1",
54
54
  "chalk": "^5.3.0",
55
- "chardet": "^1.6.0",
55
+ "chardet": "^2.0.0",
56
56
  "cli-table3": "^0.6.3",
57
- "cli-truncate": "^3.1.0",
57
+ "cli-truncate": "^4.0.0",
58
58
  "colors": "^1.4.0",
59
- "commander": "^11.0.0",
60
- "emoji-regex": "^10.2.1",
59
+ "commander": "^11.1.0",
60
+ "emoji-regex": "^10.3.0",
61
61
  "fetch-cookie": "^2.1.0",
62
62
  "gulp-sort": "^2.0.0",
63
63
  "hash-string": "^1.0.0",
64
- "i18next": "^23.4.6",
64
+ "i18next": "^23.6.0",
65
65
  "i18next-scanner": "^4.4.0",
66
66
  "js-cookie": "^3.0.5",
67
67
  "koa": "^2.14.2",
@@ -71,7 +71,7 @@
71
71
  "mime-types": "^2.1.35",
72
72
  "ora": "^7.0.1",
73
73
  "react": "^18.2.0",
74
- "react-i18next": "^13.2.2",
74
+ "react-i18next": "^13.3.1",
75
75
  "resolve-path": "^1.4.0",
76
76
  "strip-ansi": "^7.1.0",
77
77
  "through2": "^4.0.2",
@@ -79,34 +79,34 @@
79
79
  "tslib": "^2.6.2",
80
80
  "typescript": "^5.2.2",
81
81
  "ua-parser-js": "2.0.0-alpha.2",
82
- "undici": "^5.23.0",
82
+ "undici": "^5.27.2",
83
83
  "vinyl": "^3.0.0",
84
84
  "vinyl-fs": "^4.0.0",
85
- "ws": "^8.13.0"
85
+ "ws": "^8.14.2"
86
86
  },
87
87
  "devDependencies": {
88
- "@babel/types": "^7.22.15",
89
- "@types/babel__traverse": "^7.20.1",
90
- "@types/byte-size": "^8.1.0",
91
- "@types/chardet": "^0.8.1",
92
- "@types/gulp-sort": "2.0.1",
93
- "@types/js-cookie": "^3.0.3",
94
- "@types/koa": "^2.13.8",
95
- "@types/koa-compress": "^4.0.3",
96
- "@types/lodash": "^4.14.197",
97
- "@types/mime-types": "^2.1.1",
98
- "@types/node": "^20.5.9",
99
- "@types/react": "^18.2.21",
100
- "@types/through2": "^2.0.38",
101
- "@types/tough-cookie": "^4.0.2",
102
- "@types/ua-parser-js": "^0.7.37",
103
- "@types/vinyl-fs": "^3.0.2",
104
- "@types/vscode": "^1.81.0",
105
- "@typescript-eslint/eslint-plugin": "^6.6.0",
106
- "@typescript-eslint/parser": "^6.6.0",
107
- "eslint": "^8.48.0",
88
+ "@babel/types": "^7.23.3",
89
+ "@types/babel__traverse": "^7.20.4",
90
+ "@types/byte-size": "^8.1.2",
91
+ "@types/chardet": "^0.8.3",
92
+ "@types/gulp-sort": "2.0.4",
93
+ "@types/js-cookie": "^3.0.6",
94
+ "@types/koa": "^2.13.11",
95
+ "@types/koa-compress": "^4.0.6",
96
+ "@types/lodash": "^4.14.201",
97
+ "@types/mime-types": "^2.1.4",
98
+ "@types/node": "^20.9.0",
99
+ "@types/react": "^18.2.37",
100
+ "@types/through2": "^2.0.41",
101
+ "@types/tough-cookie": "^4.0.5",
102
+ "@types/ua-parser-js": "^0.7.39",
103
+ "@types/vinyl-fs": "^3.0.5",
104
+ "@types/vscode": "^1.84.1",
105
+ "@typescript-eslint/eslint-plugin": "^6.10.0",
106
+ "@typescript-eslint/parser": "^6.10.0",
107
+ "eslint": "^8.53.0",
108
108
  "eslint-plugin-react": "^7.33.2",
109
- "eslint-plugin-xlint": "^1.0.8"
109
+ "eslint-plugin-xlint": "^1.0.10"
110
110
  },
111
111
  "scripts": {
112
112
  "start": "node --title=xshell --inspect=0.0.0.0:8420 ./xshell.js",
@@ -1,14 +1,14 @@
1
1
  # 用来修复 `byte_size()` 函数的 ts 类型报错
2
2
 
3
3
  diff --git a/package.json b/package.json
4
- index 4160984ea87736c65ad63d123c7d68cae96dfc1d..f9b14147ceae6c881e7f3829aca6876be317b15f 100644
4
+ index dd8ed66fcb8b1ab93f0a3a015bad95bc31d3b18d..6a3753f42610451163fd7d502a93779fe3dca8db 100644
5
5
  --- a/package.json
6
6
  +++ b/package.json
7
7
  @@ -11,6 +11,7 @@
8
- "githubUsername": "lntel"
8
+ "url": "https://github.com/lntel"
9
9
  }
10
10
  ],
11
11
  + "type": "module",
12
12
  "main": "",
13
13
  "types": "index.d.ts",
14
- "repository": {
14
+ "repository": {
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
@@ -9,8 +9,8 @@ export declare const exe_nodejs: string;
9
9
  interface StartOptions {
10
10
  /** `继承当前工作目录 process.cwd()` 子进程的工作目录 `inherit the cwd` cwd of the child process. */
11
11
  cwd?: string;
12
- /** `process.env` 覆盖/添加到 process.env 的环境变量 overwrite/add to process.env */
13
- env?: Record<string, string>;
12
+ /** `process.env` 覆盖/添加到 process.env 的环境变量 */
13
+ envs?: Record<string, string>;
14
14
  /** `'utf-8'` 子进程输出编码 child output encoding */
15
15
  encoding?: Encoding | 'binary';
16
16
  /** `true` print 选项,支持设置细项 print option (with details) */
@@ -41,13 +41,13 @@ interface StartOptions {
41
41
  - args: `[]` 参数列表 arguments list
42
42
  - options
43
43
  - cwd?: `继承当前工作目录 process.cwd()` 子进程的工作目录 `inherit the cwd` cwd of the child process.
44
- - env?: `process.env` 覆盖/添加到 process.env 的环境变量 overwrite/add to process.env
44
+ - envs?: `process.env` 覆盖/添加到 process.env 的环境变量
45
45
  - encoding?: `'utf-8'` 子进程输出编码 child output encoding
46
46
  - print?: `true` print 选项,支持设置细项 print option (with details)
47
47
  - stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理 when 'ignore' then ignore stdio processing
48
48
  - detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref)
49
49
  */
50
- export declare function start(exe: string, args?: string[], { cwd, encoding, print, stdio, detached, env, window: _window, }?: StartOptions): Promise<ChildProcess>;
50
+ export declare function start(exe: string, args?: string[], { cwd, encoding, print, stdio, detached, envs, window: _window, }?: StartOptions): Promise<ChildProcess>;
51
51
  export declare function start_nodejs(js: string, args?: string[], options?: StartOptions): Promise<ChildProcess>;
52
52
  export interface CallOptions extends StartOptions {
53
53
  throw_code?: boolean;
@@ -67,7 +67,7 @@ export interface CallResult<TOutput extends string | Buffer = string> {
67
67
  - args: `[]` 参数列表 arguments list
68
68
  - options?:
69
69
  - cwd?: `process.cwd()`
70
- - env?: `process.env` 覆盖/添加到 process.env 的环境变量 overwrite/add to process.env
70
+ - envs?: `process.env` 覆盖/添加到 process.env 的环境变量 overwrite/add to process.env
71
71
  - encoding?: `'utf-8'` 子进程输出编码, 设置为 binary 时返回 stdout, stderr 类型为 Buffer; 否则是 string
72
72
  child output encoding. When set to binary, return stdout, stderr is of type Buffer; otherwise it is string
73
73
  - print?: `true` print 选项,支持设置细项 print option (with details)
@@ -80,18 +80,22 @@ export declare function call(exe: string, args?: string[], options?: CallOptions
80
80
  encoding: 'binary';
81
81
  }): Promise<CallResult<Buffer>>;
82
82
  export declare function call(exe: string, args?: string[], options?: CallOptions): Promise<CallResult<string>>;
83
+ export interface CallNodeJsOptions extends CallOptions {
84
+ inspect?: number;
85
+ break?: boolean;
86
+ }
83
87
  /** call node <js> for result
84
88
  - js: .js 路径 (相对路径根据 cwd 解析) path (relative path will resolve based on cwd)
85
89
  - args: `[]` 参数列表 arguments list
86
90
  - options
87
91
  - cwd?: `process.cwd()`
88
- - env?: `process.env` 覆盖/添加到 process.env 的环境变量 overwrite/add to process.env
92
+ - envs?: `process.env` 覆盖/添加到 process.env 的环境变量 overwrite/add to process.env
89
93
  - encoding?: `'utf-8'` 子进程输出编码 child process output encoding
90
94
  - print?: `true` print 选项,支持设置细项 print option (with details)
91
95
  - stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理 when 'ignore' then ignore stdio processing
92
96
  - detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref)
93
97
  - throw_code?: `true` code 不为 0 时是否抛出异常 whether to throw Error when code is not 0 */
94
- export declare function call_nodejs(js: string, args?: string[], options?: CallOptions): Promise<CallResult<string>>;
98
+ export declare function call_nodejs(js: string, args?: string[], { inspect, break: _break, ...options }?: CallNodeJsOptions): Promise<CallResult<string>>;
95
99
  export interface TermOptions {
96
100
  /** `process.cwd()` */
97
101
  cwd?: string;
package/process.js CHANGED
@@ -9,20 +9,20 @@ export const exe_nodejs = process.execPath.fp;
9
9
  - args: `[]` 参数列表 arguments list
10
10
  - options
11
11
  - cwd?: `继承当前工作目录 process.cwd()` 子进程的工作目录 `inherit the cwd` cwd of the child process.
12
- - env?: `process.env` 覆盖/添加到 process.env 的环境变量 overwrite/add to process.env
12
+ - envs?: `process.env` 覆盖/添加到 process.env 的环境变量
13
13
  - encoding?: `'utf-8'` 子进程输出编码 child output encoding
14
14
  - print?: `true` print 选项,支持设置细项 print option (with details)
15
15
  - stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理 when 'ignore' then ignore stdio processing
16
16
  - detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref)
17
17
  */
18
- export async function start(exe, args = [], { cwd, encoding = 'utf-8', print = true, stdio = 'pipe', detached = false, env, window: _window = true, } = {}) {
18
+ export async function start(exe, args = [], { cwd, encoding = 'utf-8', print = true, stdio = 'pipe', detached = false, envs, window: _window = true, } = {}) {
19
19
  const options = {
20
20
  cwd,
21
21
  shell: false,
22
22
  windowsHide: !_window,
23
23
  stdio,
24
- ...env ? {
25
- env: { ...process.env, ...env }
24
+ ...envs ? {
25
+ env: { ...process.env, ...envs }
26
26
  } : {},
27
27
  };
28
28
  if (typeof print === 'boolean')
@@ -169,14 +169,20 @@ export async function call(exe, args = [], options = {}) {
169
169
  - args: `[]` 参数列表 arguments list
170
170
  - options
171
171
  - cwd?: `process.cwd()`
172
- - env?: `process.env` 覆盖/添加到 process.env 的环境变量 overwrite/add to process.env
172
+ - envs?: `process.env` 覆盖/添加到 process.env 的环境变量 overwrite/add to process.env
173
173
  - encoding?: `'utf-8'` 子进程输出编码 child process output encoding
174
174
  - print?: `true` print 选项,支持设置细项 print option (with details)
175
175
  - stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理 when 'ignore' then ignore stdio processing
176
176
  - detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref)
177
177
  - throw_code?: `true` code 不为 0 时是否抛出异常 whether to throw Error when code is not 0 */
178
- export async function call_nodejs(js, args = [], options) {
179
- return call(exe_nodejs, [js, ...args], options);
178
+ export async function call_nodejs(js, args = [], { inspect, break: _break, ...options } = {}) {
179
+ return call(exe_nodejs, [
180
+ ...inspect ? [
181
+ _break ? `--inspect-brk=localhost:${inspect}` : `--inspect=localhost:${inspect}`
182
+ ] : [],
183
+ js,
184
+ ...args
185
+ ], options);
180
186
  }
181
187
  export const exe_winterm = `C:/Users/${userInfo().username}/AppData/Local/Microsoft/WindowsApps/wt.exe`;
182
188
  /** 新建 terminal 窗口执行进程 New Terminal window execution process
package/server.d.ts CHANGED
@@ -68,6 +68,18 @@ export declare class Server {
68
68
  format_ua(headers: IncomingHttpHeaders | IncomingHttp2Headers): string;
69
69
  proxy(ctx: Context, url: string | URL, headers_?: Record<string, string>, redirect?: RequestOptions['redirect']): Promise<void>;
70
70
  static filter_response_headers(headers: Headers): {};
71
+ /** 提供静态文件
72
+ @example
73
+ const prefix_docs = '/zh/'
74
+ if (path.startsWith(prefix_docs)) {
75
+ await this.try_send(
76
+ ctx,
77
+ `T:/t/docs${prefix_docs}`,
78
+ (path.endsWith('/') ? `${path}index.html` : path).slice(prefix_docs.length),
79
+ true
80
+ )
81
+ return
82
+ } */
71
83
  try_send(ctx: Context, fpd_root: string, fp: string, log_404: boolean): Promise<boolean>;
72
84
  /** 将 body 设置为 fp 所指文件的 ReadStream
73
85
  检查 fp 是否合法,设置对应的 content-type,支持缓存,支持分块下载
package/server.js CHANGED
@@ -310,6 +310,18 @@ export class Server {
310
310
  headers_[key] = value;
311
311
  return headers_;
312
312
  }
313
+ /** 提供静态文件
314
+ @example
315
+ const prefix_docs = '/zh/'
316
+ if (path.startsWith(prefix_docs)) {
317
+ await this.try_send(
318
+ ctx,
319
+ `T:/t/docs${prefix_docs}`,
320
+ (path.endsWith('/') ? `${path}index.html` : path).slice(prefix_docs.length),
321
+ true
322
+ )
323
+ return
324
+ } */
313
325
  async try_send(ctx, fpd_root, fp, log_404) {
314
326
  const { request: { _path, path, method }, response, } = ctx;
315
327
  if (response.body !== undefined || response.status !== 404)
@@ -1,5 +1,6 @@
1
1
  export declare const noop: () => void;
2
2
  export declare function assert(assertion: any, message?: string): never | void;
3
+ export declare function log<T>(obj: T): T;
3
4
  /** 生成 0, 1, ..., n - 1 (不包括 n) 的数组,支持传入 generator 函数,通过 index 生成各个元素
4
5
  @example seq(10, i => `item-${i}`) */
5
6
  export declare function seq<T = number>(n: number, generator?: (index: number) => T): T[];
@@ -70,3 +71,4 @@ export declare class Timer {
70
71
  getstr(): string;
71
72
  print(): void;
72
73
  }
74
+ export declare function lowercase_first_letter(str: string): string;
package/utils.browser.js CHANGED
@@ -6,6 +6,10 @@ export function assert(assertion, message) {
6
6
  throw Object.assign(new Error(`断言失败: ${message ? `${message}: ` : ''}${assertion}`), { assertion });
7
7
  }
8
8
  }
9
+ export function log(obj) {
10
+ console.log(obj);
11
+ return obj;
12
+ }
9
13
  /** 生成 0, 1, ..., n - 1 (不包括 n) 的数组,支持传入 generator 函数,通过 index 生成各个元素
10
14
  @example seq(10, i => `item-${i}`) */
11
15
  export function seq(n, generator) {
@@ -193,4 +197,7 @@ export class Timer {
193
197
  console.log(this.getstr());
194
198
  }
195
199
  }
200
+ export function lowercase_first_letter(str) {
201
+ return str[0].toLowerCase() + str.slice(1);
202
+ }
196
203
  //# sourceMappingURL=utils.browser.js.map
package/utils.d.ts CHANGED
@@ -10,6 +10,7 @@ export declare const noop: () => void;
10
10
  export declare const output_width = 230;
11
11
  export declare function set_inspect_options(colors?: boolean): void;
12
12
  export declare function assert(assertion: any, message?: string): never | void;
13
+ export declare function log<T>(obj: T): T;
13
14
  /** 生成 0, 1, ..., n - 1 (不包括 n) 的数组,支持传入 generator 函数,通过 index 生成各个元素
14
15
  @example seq(10, i => `item-${i}`) */
15
16
  export declare function seq<T = number>(n: number, generator?: (index: number) => T): T[];
@@ -92,6 +93,7 @@ export declare class Lock<TResource = void> {
92
93
  }
93
94
  export declare function has_chinese(str: string): boolean;
94
95
  export declare function escape_line_feed(str: string): string;
96
+ export declare function lowercase_first_letter(str: string): string;
95
97
  /** util.inspect(obj)
96
98
  - options
97
99
  - limit?: `10000` 传 0 时不限制
package/utils.js CHANGED
@@ -27,6 +27,10 @@ export function assert(assertion, message) {
27
27
  throw Object.assign(new Error(`断言失败: ${message ? `${message}: ` : ''}${inspect(assertion, { colors: false, compact: true })}`), { assertion });
28
28
  }
29
29
  }
30
+ export function log(obj) {
31
+ console.log(obj);
32
+ return obj;
33
+ }
30
34
  /** 生成 0, 1, ..., n - 1 (不包括 n) 的数组,支持传入 generator 函数,通过 index 生成各个元素
31
35
  @example seq(10, i => `item-${i}`) */
32
36
  export function seq(n, generator) {
@@ -271,6 +275,9 @@ export function has_chinese(str) {
271
275
  export function escape_line_feed(str) {
272
276
  return str.replace(/\n/g, '\\n');
273
277
  }
278
+ export function lowercase_first_letter(str) {
279
+ return str[0].toLowerCase() + str.slice(1);
280
+ }
274
281
  /** util.inspect(obj)
275
282
  - options
276
283
  - limit?: `10000` 传 0 时不限制