xshell 1.0.131 → 1.0.133

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
@@ -1,6 +1,46 @@
1
1
  import Webpack from 'webpack';
2
2
  import { Lock } from './utils.js';
3
+ /** target web 时的 npm 包依赖管理
4
+ 有 productions 但无 devs 时,大部分情况是相同配置,因此在 dev 模式下会用 productions
5
+ 也可以手动设置 [ ] 禁用 fallback */
6
+ export interface Dependency {
7
+ /** 项目隐含的子依赖 */
8
+ dependencies?: string[];
9
+ /** 开发环境依赖的 .js 文件 */
10
+ devs?: string[];
11
+ /** 生产环境依赖的 .js 文件 */
12
+ productions?: string[];
13
+ /** 需要直接复制到输出目录的资源 */
14
+ assets?: {
15
+ productions: string[];
16
+ devs?: string[];
17
+ };
18
+ /** .map 代码映射 */
19
+ maps?: {
20
+ productions?: string[];
21
+ devs?: string[];
22
+ };
23
+ }
24
+ type DependencyId = 'react' | 'react-dom' | 'lodash' | 'jquery' | 'xterm' | 'swiper' | 'dayjs' | 'antd' | 'antd-icons' | 'vscode-oniguruma' | 'antd-plots' | 'gridstack' | 'quill' | 'monaco';
25
+ export interface HtmlBuildOptions {
26
+ title: string;
27
+ device_viewport?: boolean;
28
+ /** 也会在 copy_files 中一并被复制 */
29
+ fp_icon?: string;
30
+ dependencies?: DependencyId[];
31
+ fp_manifest?: string;
32
+ /** 额外需要加载的脚本 */
33
+ scripts?: {
34
+ /** 在 index.js 之前加载 */
35
+ before?: string[];
36
+ /** 在 index.js 之后加载 */
37
+ after?: string[];
38
+ };
39
+ heads?: string[];
40
+ notice?: boolean;
41
+ }
3
42
  export interface BundlerOptions {
43
+ dependencies?: DependencyId[];
4
44
  source_map?: boolean;
5
45
  production?: boolean;
6
46
  external_dayjs?: boolean;
@@ -19,12 +59,26 @@ export interface BundlerOptions {
19
59
  license?: {
20
60
  ignores?: string[];
21
61
  };
62
+ assets?: {
63
+ productions?: string[];
64
+ devs?: string[];
65
+ };
66
+ htmls?: Record<string, HtmlBuildOptions>;
22
67
  }
23
68
  export declare class Bundler {
24
69
  name: string;
25
70
  fpd_root: string;
26
- config: Webpack.Configuration;
71
+ production: boolean;
72
+ fpd_out: string;
73
+ source_map: boolean;
74
+ dependencies: DependencyId[];
27
75
  analyzer: boolean;
76
+ config: Webpack.Configuration;
77
+ htmls?: Record<string, HtmlBuildOptions>;
78
+ assets?: {
79
+ productions?: string[];
80
+ devs?: string[];
81
+ };
28
82
  license?: {
29
83
  ignores?: string[];
30
84
  };
@@ -41,6 +95,9 @@ export declare class Bundler {
41
95
  - globals?: 全局变量定义
42
96
  - external_dayjs?: `false` 配置 dayjs 为 external 来配合 antd 使用, 减小一点体积
43
97
  - externals?: 配置外部模块
98
+ - htmls?: 配置要生成的 html, 比如 { 'index.html', { title: '文件', ... } }
99
+ - assets?: 项目中需要直接复制到输出目录的资源,有 productions 但无 devs 时 (是同一套),
100
+ 在 dev 模式下会用 productions 中的资源,如果不需要 productions 资源, devs 可以设置为 [ ]
44
101
  - commonjs2?: `false` 打包为 commonjs2 (.cjs) 的文件
45
102
  - single_chunk?: `true` 输出为单个文件,将依赖也打包到其中,不要生成多个 chunk
46
103
  - dynamic_import?: `true` 对于 await import('...') 要不要打包外部模块到输出文件中
@@ -53,15 +110,40 @@ export declare class Bundler {
53
110
  - production?: `true` webpack mode 设置为 'production'
54
111
  - sass?: 传入 sass 实例避免 webpack 重复加载 .cjs 版本
55
112
  - license?: 使用 license-webpack-plugin 构建 ThirdPartyNotice.txt */
56
- constructor(name: string, target: 'web' | 'nodejs', fpd_root: string, fpd_out: string, fpdt_cache: string, entry: Record<string, string>, { source_map, globals, external_dayjs, externals, commonjs2, single_chunk, dynamic_import, resolve_alias, assets_stats, analyzer, dts, exclude_modules, cache_version, production, sass, license, }?: BundlerOptions);
57
- /** 获取构建时 git 仓库的最新提交、分支信息 */
58
- get_git_info(version?: string): Promise<{
59
- version: string;
60
- branch: string;
61
- time: string;
62
- commit: string;
63
- }>;
113
+ constructor(name: string, target: 'web' | 'nodejs', fpd_root: string, fpd_out: string, fpdt_cache: string, entry: Record<string, string>, { source_map, globals, external_dayjs, externals, htmls, assets, commonjs2, single_chunk, dynamic_import, resolve_alias, assets_stats, analyzer, dts, exclude_modules, cache_version, production, sass, dependencies, license, }?: BundlerOptions);
64
114
  build(print?: boolean): Promise<void>;
65
115
  close(): Promise<void>;
66
116
  build_and_close(print?: boolean): Promise<void>;
117
+ build_htmls(print?: {
118
+ info: boolean;
119
+ files: boolean;
120
+ }): Promise<void>;
121
+ resolve_dependencies(dependency_ids?: DependencyId[], resolveds?: Set<DependencyId>): Set<DependencyId>;
122
+ /** 解析依赖的文件
123
+ - dependencies: 依赖 id
124
+ - assets: false 时只包括在 script 标签加载的文件; true 时包括 assets, maps 等 */
125
+ resolve_dependency_files(_dependencies: DependencyId[], assets: boolean, { production, source_map }?: {
126
+ production?: boolean;
127
+ source_map?: boolean;
128
+ }): string[];
129
+ copy_files({ dependencies, production, assets, fpd_root, fpd_out, print }?: {
130
+ dependencies?: DependencyId[];
131
+ production?: boolean;
132
+ assets?: {
133
+ productions?: string[];
134
+ devs?: string[];
135
+ };
136
+ fpd_root?: string;
137
+ fpd_out?: string;
138
+ print?: {
139
+ info: boolean;
140
+ files: boolean;
141
+ };
142
+ }): Promise<void>;
143
+ /** 为空时返回空数组 */
144
+ resolve_config(config: {
145
+ productions?: string[];
146
+ devs?: string[];
147
+ }, production: boolean): string[];
67
148
  }
149
+ export {};
package/builder.js CHANGED
@@ -1,12 +1,107 @@
1
1
  import { fileURLToPath } from 'url';
2
2
  import Webpack from 'webpack';
3
- import { Lock, Timer, filter_values } from './utils.js';
4
- import { Git } from './git.js';
3
+ import { noprint } from './process.js';
4
+ import { Lock, Timer, assert, filter_values, not_empty } from './utils.js';
5
+ import { fcopy, fmkdir, fwrite } from './file.js';
6
+ import { path } from './path.js';
7
+ const monaco_files = [
8
+ 'loader.js',
9
+ 'editor/editor.main.js',
10
+ 'editor/editor.main.css',
11
+ 'editor/editor.main.nls.js',
12
+ 'editor/editor.main.nls.zh-cn.js',
13
+ 'base/common/worker/simpleWorker.nls.js',
14
+ 'base/worker/workerMain.js',
15
+ 'base/browser/ui/codicons/codicon/codicon.ttf',
16
+ ...['python', 'javascript', 'typescript', 'css', 'html', 'cpp', 'sql', 'scss', 'shell'].map(language => `basic-languages/${language}/${language}.js`),
17
+ ];
18
+ const dependencies = {
19
+ react: {
20
+ productions: ['react/umd/react.production.min.js'],
21
+ devs: ['react/umd/react.development.js'],
22
+ },
23
+ 'react-dom': {
24
+ dependencies: ['react'],
25
+ productions: ['react-dom/umd/react-dom.production.min.js'],
26
+ devs: ['react-dom/umd/react-dom.development.js'],
27
+ },
28
+ lodash: {
29
+ productions: ['lodash/lodash.min.js'],
30
+ devs: ['lodash/lodash.js'],
31
+ },
32
+ jquery: {
33
+ productions: ['jquery/dist/jquery.min.js']
34
+ },
35
+ xterm: {
36
+ productions: ['@xterm/xterm/lib/xterm.js'],
37
+ maps: {
38
+ productions: ['@xterm/xterm/lib/xterm.js.map'],
39
+ }
40
+ },
41
+ swiper: {
42
+ productions: ['swiper/swiper-bundle.min.js']
43
+ },
44
+ dayjs: {
45
+ productions: ['dayjs/dayjs.min.js'],
46
+ },
47
+ antd: {
48
+ dependencies: ['dayjs', 'react', 'react-dom'],
49
+ productions: ['antd/dist/antd.min.js'],
50
+ devs: ['antd/dist/antd.js'],
51
+ maps: {
52
+ productions: ['antd/dist/antd.min.js.map'],
53
+ devs: ['antd/dist/antd.js.map'],
54
+ }
55
+ },
56
+ 'antd-icons': {
57
+ dependencies: ['antd'],
58
+ productions: ['@ant-design/icons/dist/index.umd.min.js'],
59
+ devs: ['@ant-design/icons/dist/index.umd.js']
60
+ },
61
+ 'vscode-oniguruma': {
62
+ assets: {
63
+ productions: ['vscode-oniguruma/release/onig.wasm']
64
+ }
65
+ },
66
+ 'antd-plots': {
67
+ productions: ['@ant-design/plots/dist/plots.min.js'],
68
+ maps: {
69
+ productions: ['@ant-design/plots/dist/plots.min.js.map']
70
+ }
71
+ },
72
+ gridstack: {
73
+ productions: ['gridstack/dist/gridstack-all.js'],
74
+ maps: {
75
+ productions: ['gridstack/dist/gridstack-all.js.map']
76
+ }
77
+ },
78
+ quill: {
79
+ productions: ['react-quill/dist/react-quill.js']
80
+ },
81
+ monaco: {
82
+ assets: {
83
+ productions: monaco_files.map(fp => `monaco-editor/min/vs/${fp}`),
84
+ devs: monaco_files.map(fp => `monaco-editor/dev/vs/${fp}`)
85
+ },
86
+ maps: {
87
+ productions: monaco_files.filter(fp => fp.endsWith('.js') && !fp.startsWith('basic-languages/') && !fp.startsWith('language/'))
88
+ .map(fp => `monaco-editor/min-maps/vs/${fp}.map`),
89
+ devs: monaco_files.filter(fp => fp.endsWith('.js') && !fp.startsWith('basic-languages/') && !fp.startsWith('language/'))
90
+ .map(fp => `monaco-editor/dev/vs/${fp}.map`),
91
+ }
92
+ }
93
+ };
5
94
  export class Bundler {
6
95
  name;
7
96
  fpd_root;
8
- config;
97
+ production;
98
+ fpd_out;
99
+ source_map;
100
+ dependencies = [];
9
101
  analyzer;
102
+ config;
103
+ htmls;
104
+ assets;
10
105
  license;
11
106
  lcompiler;
12
107
  /** 通过 webpack 从入口文件打包所有依赖生成单个 index.{mjs,cjs} 文件
@@ -21,6 +116,9 @@ export class Bundler {
21
116
  - globals?: 全局变量定义
22
117
  - external_dayjs?: `false` 配置 dayjs 为 external 来配合 antd 使用, 减小一点体积
23
118
  - externals?: 配置外部模块
119
+ - htmls?: 配置要生成的 html, 比如 { 'index.html', { title: '文件', ... } }
120
+ - assets?: 项目中需要直接复制到输出目录的资源,有 productions 但无 devs 时 (是同一套),
121
+ 在 dev 模式下会用 productions 中的资源,如果不需要 productions 资源, devs 可以设置为 [ ]
24
122
  - commonjs2?: `false` 打包为 commonjs2 (.cjs) 的文件
25
123
  - single_chunk?: `true` 输出为单个文件,将依赖也打包到其中,不要生成多个 chunk
26
124
  - dynamic_import?: `true` 对于 await import('...') 要不要打包外部模块到输出文件中
@@ -33,9 +131,19 @@ export class Bundler {
33
131
  - production?: `true` webpack mode 设置为 'production'
34
132
  - sass?: 传入 sass 实例避免 webpack 重复加载 .cjs 版本
35
133
  - license?: 使用 license-webpack-plugin 构建 ThirdPartyNotice.txt */
36
- constructor(name, target, fpd_root, fpd_out, fpdt_cache, entry, { source_map = true, globals, external_dayjs = false, externals, commonjs2 = false, single_chunk = true, dynamic_import = true, resolve_alias, assets_stats = true, analyzer = false, dts = false, exclude_modules, cache_version, production = true, sass, license, } = {}) {
134
+ constructor(name, target, fpd_root, fpd_out, fpdt_cache, entry, { source_map = true, globals, external_dayjs = false, externals, htmls, assets, commonjs2 = false, single_chunk = true, dynamic_import = true, resolve_alias, assets_stats = true, analyzer = false, dts = false, exclude_modules, cache_version, production = true, sass, dependencies, license, } = {}) {
37
135
  this.name = name;
38
136
  this.analyzer = analyzer;
137
+ this.production = production;
138
+ this.fpd_root = fpd_root;
139
+ this.fpd_out = fpd_out;
140
+ this.source_map = source_map;
141
+ this.htmls = htmls;
142
+ this.assets = assets;
143
+ if (dependencies) {
144
+ assert(target === 'web');
145
+ this.dependencies = dependencies;
146
+ }
39
147
  this.license = license;
40
148
  // let smp = new SpeedMeasurePlugin()
41
149
  // const config: Webpack.Configuration = smp.wrap({
@@ -262,21 +370,6 @@ export class Bundler {
262
370
  }
263
371
  };
264
372
  }
265
- /** 获取构建时 git 仓库的最新提交、分支信息 */
266
- async get_git_info(version) {
267
- let git = new Git(this.fpd_root);
268
- const branch = await git.get_branch();
269
- const { hash, time } = (await git.get_last_commits(1))[0];
270
- version ||= branch;
271
- const timestr = time.to_formal_str();
272
- const commit = hash.slice(0, 6);
273
- return {
274
- version: version,
275
- branch,
276
- time: timestr,
277
- commit
278
- };
279
- }
280
373
  async build(print = true) {
281
374
  let timer = new Timer();
282
375
  if (!this.lcompiler) {
@@ -346,5 +439,84 @@ export class Bundler {
346
439
  await this.build(print);
347
440
  await this.close();
348
441
  }
442
+ async build_htmls(print = { info: true, files: false }) {
443
+ await Promise.all(Object.entries(this.htmls).map(async ([fp_html, { device_viewport: device_width = false, fp_icon, fp_manifest, dependencies: _dependencies = this.dependencies, title, scripts, notice = false, heads, }]) => {
444
+ const html = '<!doctype html>\n' +
445
+ '<html>\n' +
446
+ ' <head>\n' +
447
+ ` <title>${title}</title>\n` +
448
+ " <meta charset='utf-8' />\n" +
449
+ (heads ? heads.map(head => ` ${head}`).join_lines() : '') +
450
+ (device_width ? " <meta name='viewport' content='width=device-width, initial-scale=1.0' />\n" : '') +
451
+ (fp_icon ? ` <link rel='icon' href='${fp_icon}' />\n` : '') +
452
+ (fp_manifest ? ` <link rel='manifest' href='${fp_manifest}' />\n` : '') +
453
+ this.resolve_dependency_files(_dependencies, false, { production: this.production }).map(fp => ` <script src='/vendors/${fp}' defer></script>`).join_lines() +
454
+ (scripts?.before ? scripts.before.map(fp => ` <script src='${fp}' defer></script>`).join_lines() : '') +
455
+ " <script src='./index.js' type='module'></script>\n" +
456
+ (scripts?.after ? scripts.after.map(fp => ` <script src='${fp}' defer></script>`).join_lines() : '') +
457
+ ' </head>\n' +
458
+ ' <body>\n' +
459
+ " <div class='root'>\n" +
460
+ (notice ?
461
+ ' <h2>正在加载 ··· (最多需要十秒钟)</h2>\n' +
462
+ ' <h2>如果一直停留在此页面请按 f12 或右键 > 检查,打开开发者工具查看底部控制台报错,并尝试更换浏览器或将浏览器更新到最新版本,同时检查网络连接情况</h2>\n'
463
+ : '') +
464
+ ' </div>\n' +
465
+ ' </body>\n' +
466
+ '</html>\n';
467
+ await fwrite(`${this.fpd_out}${fp_html}`, html, noprint);
468
+ if (print.files)
469
+ console.log(`已构建 ${fp_html}`);
470
+ }));
471
+ if (print.info)
472
+ console.log('htmls 已构建完成');
473
+ }
474
+ resolve_dependencies(dependency_ids = this.dependencies, resolveds = new Set()) {
475
+ dependency_ids.forEach(id => {
476
+ if (!resolveds.has(id)) {
477
+ const dependency_ids_ = dependencies[id].dependencies;
478
+ if (dependency_ids_)
479
+ this.resolve_dependencies(dependency_ids_, resolveds);
480
+ resolveds.add(id);
481
+ }
482
+ });
483
+ return resolveds;
484
+ }
485
+ /** 解析依赖的文件
486
+ - dependencies: 依赖 id
487
+ - assets: false 时只包括在 script 标签加载的文件; true 时包括 assets, maps 等 */
488
+ resolve_dependency_files(_dependencies, assets, { production = this.production, source_map = this.source_map } = {}) {
489
+ return this.resolve_dependencies(_dependencies).map(id => {
490
+ const dependency = dependencies[id];
491
+ const { assets: _assets, maps } = dependency;
492
+ return [
493
+ ...assets ? this.resolve_config(_assets, production) : [],
494
+ ...assets && source_map ? this.resolve_config(maps, production) : [],
495
+ ...this.resolve_config(dependency, production)
496
+ ];
497
+ }).flat();
498
+ }
499
+ async copy_files({ dependencies = this.dependencies, production = this.production, assets = this.assets, fpd_root = this.fpd_root, fpd_out = this.fpd_out, print = { info: true, files: false } } = {}) {
500
+ if (print.info)
501
+ console.log(`复制项目文件及依赖到输出目录`);
502
+ if (dependencies)
503
+ await fmkdir(`${fpd_out}vendors/`, { print: false });
504
+ await Promise.all([
505
+ ...this.resolve_dependency_files(dependencies, true, { production })
506
+ .map(async (fp) => fcopy(`${fpd_root}node_modules/${fp}`, `${fpd_out}vendors/${fp}`, { print: print.files })),
507
+ ...this.resolve_config(assets, production)
508
+ .map(async (fp) => fcopy(`${fpd_root}${fp}`, `${fpd_out}${fp}`, { print: print.files })),
509
+ ...this.htmls ? Object.entries(this.htmls).map(async ([fp_html, { fp_icon, fp_manifest, scripts }]) => Promise.all([fp_icon, fp_manifest, ...(scripts?.before || []), ...(scripts?.after || [])]
510
+ .filter(not_empty)
511
+ .map(fp => fcopy(path.resolve(`${fpd_root}${fp_html}`.fdir, fp), path.resolve(`${fpd_out}${fp_html}`.fdir, fp), { print: print.files })))) : []
512
+ ]);
513
+ }
514
+ /** 为空时返回空数组 */
515
+ resolve_config(config, production) {
516
+ return config
517
+ ? (production ? config.productions : config.devs || config.productions) ||
518
+ []
519
+ : [];
520
+ }
349
521
  }
350
522
  //# sourceMappingURL=builder.js.map
package/file.d.ts CHANGED
@@ -42,6 +42,7 @@ export declare function fread(fp: string, { dir, encoding, print }?: {
42
42
  encoding?: Encoding;
43
43
  print?: boolean;
44
44
  }): Promise<string>;
45
+ /** 读取文件,划分为行,并去掉最后一个 \n 之后的 '' */
45
46
  export declare function fread_lines(fp: string, options?: {
46
47
  dir?: string;
47
48
  encoding?: Encoding;
package/file.js CHANGED
@@ -49,6 +49,7 @@ export async function fread(fp, { dir, encoding = 'utf-8', print = true } = {})
49
49
  .decode(await fsp.readFile(fp));
50
50
  }
51
51
  }
52
+ /** 读取文件,划分为行,并去掉最后一个 \n 之后的 '' */
52
53
  export async function fread_lines(fp, options = {}) {
53
54
  return (await fread(fp, options))
54
55
  .split_lines();
package/git.d.ts CHANGED
@@ -5,9 +5,10 @@ export declare class Git {
5
5
  constructor(cwd: string);
6
6
  static init(cwd: string, print?: boolean): Promise<Git>;
7
7
  static clone(repo: string, fpd: string): Promise<void>;
8
- call(args?: any[], { color, print }?: {
8
+ call(args?: any[], { color, print, printers }?: {
9
9
  color?: boolean;
10
10
  print?: CallOptions['print'];
11
+ printers?: CallOptions['printers'];
11
12
  }): Promise<import("./process.js").CallResult<string>>;
12
13
  get_branch(): Promise<string>;
13
14
  /** - print: `true` */
@@ -33,4 +34,20 @@ export declare class Git {
33
34
  checkout(branch?: 'main'): Promise<void>;
34
35
  checkout(branch?: string): Promise<void>;
35
36
  _checkout(branch?: string): Promise<void>;
37
+ get_version_info(version?: string): Promise<{
38
+ version: string;
39
+ branch: string;
40
+ time: string;
41
+ hash: string;
42
+ commiter: string;
43
+ message: string;
44
+ }>;
45
+ }
46
+ export interface GitVersionInfo {
47
+ version: string;
48
+ branch: string;
49
+ time: string;
50
+ hash: string;
51
+ commiter: string;
52
+ message: string;
36
53
  }
package/git.js CHANGED
@@ -1,4 +1,4 @@
1
- import { call } from './process.js';
1
+ import { call, print_no_command } from './process.js';
2
2
  import { fread, fmkdir } from './file.js';
3
3
  export class Git {
4
4
  static exe = 'git';
@@ -15,7 +15,7 @@ export class Git {
15
15
  await fmkdir(fpd);
16
16
  await new this(fpd).call(['clone', repo, '.']);
17
17
  }
18
- async call(args = [], { color = true, print } = {}) {
18
+ async call(args = [], { color = true, print, printers } = {}) {
19
19
  return call(Git.exe, [
20
20
  ...color ? [] : [
21
21
  '-c', 'color.status=false',
@@ -26,6 +26,7 @@ export class Git {
26
26
  ], {
27
27
  cwd: this.cwd,
28
28
  print,
29
+ printers
29
30
  });
30
31
  }
31
32
  async get_branch() {
@@ -93,32 +94,26 @@ export class Git {
93
94
  await this._checkout(branch);
94
95
  else {
95
96
  console.log(`创建分支 ${branch}`);
96
- await this.call(['checkout', '-b', branch], { print: { command: false, code: false, stdout: true, stderr: true } });
97
+ await this.call(['checkout', '-b', branch], print_no_command);
97
98
  }
98
99
  }
99
100
  }
100
101
  async _checkout(branch) {
101
- try {
102
- const { stdout, stderr } = await this.call(['checkout', branch], { print: false });
103
- if (stdout)
104
- console.log(stdout.trimEnd());
105
- console.log(/Already on '.*'\n/.test(stderr) ?
106
- `已经在 ${branch} 分支了`
107
- : /Switched to branch '.*'/.test(stderr) ?
108
- `已切换到 ${branch} 分支`
109
- :
110
- stderr.trimEnd());
111
- }
112
- catch (error) {
113
- if (error.result) {
114
- const { stdout, stderr } = error.result;
115
- if (stdout)
116
- console.log(stdout);
117
- if (stderr)
118
- console.log(stderr);
119
- }
120
- throw error;
121
- }
102
+ await this.call(['checkout', branch], print_no_command);
103
+ }
104
+ async get_version_info(version) {
105
+ const branch = await this.get_branch();
106
+ const { hash, time, commiter, message } = (await this.get_last_commits(1))[0];
107
+ version ||= branch;
108
+ const timestr = time.to_formal_str();
109
+ return {
110
+ version,
111
+ branch,
112
+ time: timestr,
113
+ hash: hash.slice(0, 6),
114
+ commiter,
115
+ message
116
+ };
122
117
  }
123
118
  }
124
119
  //# sourceMappingURL=git.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xshell",
3
- "version": "1.0.131",
3
+ "version": "1.0.133",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -56,9 +56,9 @@
56
56
  "@svgr/webpack": "^8.1.0",
57
57
  "@types/sass-loader": "^8.0.8",
58
58
  "@types/ws": "^8.5.10",
59
- "@typescript-eslint/eslint-plugin": "^7.13.0",
60
- "@typescript-eslint/parser": "^7.13.0",
61
- "@typescript-eslint/utils": "^7.13.0",
59
+ "@typescript-eslint/eslint-plugin": "^7.13.1",
60
+ "@typescript-eslint/parser": "^7.13.1",
61
+ "@typescript-eslint/utils": "^7.13.1",
62
62
  "@xterm/addon-fit": "^0.10.0",
63
63
  "@xterm/addon-web-links": "^0.11.0",
64
64
  "@xterm/addon-webgl": "^0.18.0",
@@ -74,14 +74,14 @@
74
74
  "commander": "^12.1.0",
75
75
  "css-loader": "^7.1.2",
76
76
  "emoji-regex": "^10.3.0",
77
- "eslint": "^9.4.0",
77
+ "eslint": "^9.5.0",
78
78
  "eslint-plugin-import": "^2.29.1",
79
- "eslint-plugin-react": "^7.34.2",
79
+ "eslint-plugin-react": "^7.34.3",
80
80
  "gulp-sort": "^2.0.0",
81
81
  "hash-string": "^1.0.0",
82
82
  "https-proxy-agent": "^7.0.4",
83
83
  "i18next": "^23.11.5",
84
- "i18next-scanner": "^4.4.0",
84
+ "i18next-scanner": "^4.5.0",
85
85
  "koa": "^2.15.3",
86
86
  "koa-compress": "^5.1.1",
87
87
  "license-webpack-plugin": "^4.0.2",
@@ -93,7 +93,7 @@
93
93
  "react-i18next": "^14.1.2",
94
94
  "react-object-model": "^1.2.6",
95
95
  "resolve-path": "^1.4.0",
96
- "sass": "^1.77.5",
96
+ "sass": "^1.77.6",
97
97
  "sass-loader": "^14.2.1",
98
98
  "source-map-loader": "^5.0.0",
99
99
  "strip-ansi": "^7.1.0",
@@ -104,12 +104,12 @@
104
104
  "tslib": "^2.6.3",
105
105
  "typescript": "^5.4.5",
106
106
  "ua-parser-js": "^2.0.0-beta.3",
107
- "undici": "^6.18.2",
107
+ "undici": "^6.19.2",
108
108
  "vinyl": "^3.0.0",
109
109
  "vinyl-fs": "^4.0.0",
110
- "webpack": "^5.92.0",
110
+ "webpack": "^5.92.1",
111
111
  "webpack-bundle-analyzer": "^4.10.2",
112
- "ws": "^8.17.0"
112
+ "ws": "^8.17.1"
113
113
  },
114
114
  "devDependencies": {
115
115
  "@babel/types": "^7.24.7",
@@ -125,7 +125,7 @@
125
125
  "@types/koa-compress": "^4.0.6",
126
126
  "@types/lodash": "^4.17.5",
127
127
  "@types/mime-types": "^2.1.4",
128
- "@types/node": "^20.14.2",
128
+ "@types/node": "^20.14.6",
129
129
  "@types/react": "^18.3.3",
130
130
  "@types/through2": "^2.0.41",
131
131
  "@types/tough-cookie": "^4.0.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;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
1
+ if (!Promise.withResolvers)
2
+ Promise.withResolvers = function PromiseWithResolvers() {
3
+ let resolve, reject;
4
+ let promise = new Promise((_resolve, _reject) => {
5
+ resolve = _resolve;
6
+ reject = _reject;
7
+ });
8
+ return { promise, resolve, reject };
9
+ };
10
+ if (!Array.prototype.toReversed)
11
+ Object.defineProperty(Array.prototype, 'toReversed', {
12
+ configurable: true,
13
+ writable: true,
14
+ enumerable: false,
15
+ value: function toReversed() {
16
+ return [...this].reverse();
17
+ }
18
+ });
19
+ if (!Array.prototype.toSpliced)
20
+ Object.defineProperty(Array.prototype, 'toSpliced', {
21
+ configurable: true,
22
+ writable: true,
23
+ enumerable: false,
24
+ value: function toSpliced(...args) {
25
+ const copy = [...this];
26
+ copy.splice(...args);
27
+ return copy;
28
+ }
29
+ });
30
+ if (!Array.prototype.at)
31
+ Object.defineProperty(Array.prototype, 'at', {
32
+ configurable: true,
33
+ writable: true,
34
+ enumerable: false,
35
+ value: function at(index) {
36
+ return index >= 0 ? this[index] : this[index + this.length];
37
+ }
38
+ });
39
+ export {};
40
+ //# sourceMappingURL=polyfill.browser.js.map
package/process.d.ts CHANGED
@@ -11,6 +11,14 @@ export declare const username: string;
11
11
  export declare const noprint: {
12
12
  readonly print: false;
13
13
  };
14
+ export declare const print_no_command: {
15
+ readonly print: {
16
+ readonly command: false;
17
+ readonly code: false;
18
+ readonly stdout: true;
19
+ readonly stderr: true;
20
+ };
21
+ };
14
22
  interface StartOptions {
15
23
  /** `继承当前工作目录 process.cwd()` 子进程的工作目录 `inherit the cwd` cwd of the child process. */
16
24
  cwd?: string;
@@ -57,6 +65,10 @@ export declare function start_nodejs(js: string, args?: string[], options?: Star
57
65
  export interface CallOptions extends StartOptions {
58
66
  throw_code?: boolean;
59
67
  input?: string;
68
+ printers?: {
69
+ stdout?: (chunk: string) => void;
70
+ stderr?: (chunk: string) => void;
71
+ };
60
72
  }
61
73
  export interface CallResult<TOutput extends string | Buffer = string> {
62
74
  pid: number;
@@ -109,7 +121,9 @@ export interface CallNodeJsOptions extends CallOptions {
109
121
  - print?: `true` print 选项,支持设置细项 print option (with details)
110
122
  - stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理 when 'ignore' then ignore stdio processing
111
123
  - detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref)
112
- - throw_code?: `true` code 不为 0 时是否抛出异常 whether to throw Error when code is not 0 */
124
+ - throw_code?: `true` code 不为 0 时是否抛出异常
125
+ - inspect?: nodejs debugger port
126
+ - break?: break at first line */
113
127
  export declare function call_nodejs(js: string, args?: string[], { inspect, break: _break, ...options }?: CallNodeJsOptions): Promise<CallResult<string>>;
114
128
  export interface TermOptions {
115
129
  /** `process.cwd()` */
package/process.js CHANGED
@@ -7,6 +7,7 @@ export const exe_nodejs = process.execPath.fp;
7
7
  export const platform = os.platform();
8
8
  export const username = os.userInfo().username;
9
9
  export const noprint = { print: false };
10
+ export const print_no_command = { print: { command: false, code: false, stdout: true, stderr: true } };
10
11
  /** start process
11
12
  - exe: .exe 路径或文件名 (建议使用完整路径,跳过 path 搜索,性能更高) path or filename (full path is recommanded to skip path searching for better perf)
12
13
  - args: `[]` 参数列表 arguments list
@@ -86,7 +87,7 @@ export async function start_nodejs(js, args = [], options) {
86
87
  return start(exe_nodejs, [js, ...args], options);
87
88
  }
88
89
  export async function call(exe, args = [], options = {}) {
89
- const { encoding = 'utf-8', throw_code = true, input, } = options;
90
+ const { encoding = 'utf-8', throw_code = true, input, printers } = options;
90
91
  let { stdio = 'pipe', print = true } = options;
91
92
  if (typeof print === 'boolean')
92
93
  print = {
@@ -126,7 +127,10 @@ export async function call(exe, args = [], options = {}) {
126
127
  if (stdio[1] === 'pipe')
127
128
  for await (const chunk of child.stdout) {
128
129
  if (encoding !== 'binary' && print.stdout)
129
- process.stdout.write(chunk);
130
+ if (printers?.stdout)
131
+ printers.stdout(chunk);
132
+ else
133
+ process.stdout.write(chunk);
130
134
  stdouts.push(chunk);
131
135
  }
132
136
  })(),
@@ -134,7 +138,10 @@ export async function call(exe, args = [], options = {}) {
134
138
  if (stdio[2] === 'pipe')
135
139
  for await (const chunk of child.stderr) {
136
140
  if (encoding !== 'binary' && print.stderr)
137
- process.stderr.write(chunk);
141
+ if (printers?.stderr)
142
+ printers.stderr(chunk);
143
+ else
144
+ process.stderr.write(chunk);
138
145
  stderrs.push(chunk);
139
146
  }
140
147
  })()
@@ -176,7 +183,9 @@ export async function call(exe, args = [], options = {}) {
176
183
  - print?: `true` print 选项,支持设置细项 print option (with details)
177
184
  - stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理 when 'ignore' then ignore stdio processing
178
185
  - detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref)
179
- - throw_code?: `true` code 不为 0 时是否抛出异常 whether to throw Error when code is not 0 */
186
+ - throw_code?: `true` code 不为 0 时是否抛出异常
187
+ - inspect?: nodejs debugger port
188
+ - break?: break at first line */
180
189
  export async function call_nodejs(js, args = [], { inspect, break: _break, ...options } = {}) {
181
190
  return call(exe_nodejs, [
182
191
  ...inspect ? [`--inspect${_break ? '-brk' : ''}=localhost:${inspect}`] : [],
@@ -53,6 +53,8 @@ declare global {
53
53
  }
54
54
  ```
55
55
 
56
+ 为空时返回 { }
57
+
56
58
  - preservations?: `''` 保留的正则表达式字符
57
59
  - flags?: `''` 正则匹配选项
58
60
  - pattern_placeholder?: `/\{.*?\}/g`
@@ -147,6 +149,9 @@ declare global {
147
149
  interface Error {
148
150
  toJSON(this: Error): string;
149
151
  }
152
+ interface Set<T> {
153
+ map<TResult>(mapfn: (value: T, index: number) => TResult): TResult[];
154
+ }
150
155
  }
151
156
  export declare const emoji_regex: RegExp;
152
157
  export declare function to_method_property_descriptors(methods: {
@@ -454,6 +454,11 @@ Object.defineProperties(Error.prototype, to_method_property_descriptors({
454
454
  .map(name => [name, this[name]]));
455
455
  }
456
456
  }));
457
+ Object.defineProperties(Set.prototype, to_method_property_descriptors({
458
+ map(mapfn) {
459
+ return Array.from(this, mapfn);
460
+ }
461
+ }));
457
462
  export function to_json(obj, replacer) {
458
463
  return JSON.stringify(obj, replacer, 4) + '\n';
459
464
  }
package/prototype.d.ts CHANGED
@@ -54,6 +54,8 @@ declare global {
54
54
  }
55
55
  ```
56
56
 
57
+ 为空时返回 { }
58
+
57
59
  - preservations?: `''` 保留的正则表达式字符
58
60
  - flags?: `''` 正则匹配选项
59
61
  - pattern_placeholder?: `/\{.*?\}/g` */
@@ -178,6 +180,9 @@ declare global {
178
180
  interface Error {
179
181
  toJSON(this: Error): string;
180
182
  }
183
+ interface Set<T> {
184
+ map<TResult>(mapfn: (value: T, index: number) => TResult): TResult[];
185
+ }
181
186
  }
182
187
  import chalk from 'chalk';
183
188
  export declare const emoji_regex: RegExp;
package/prototype.js CHANGED
@@ -507,6 +507,11 @@ if (!globalThis.my_prototype_defined) {
507
507
  .map(name => [name, this[name]]));
508
508
  }
509
509
  }));
510
+ Object.defineProperties(Set.prototype, to_method_property_descriptors({
511
+ map(mapfn) {
512
+ return Array.from(this, mapfn);
513
+ }
514
+ }));
510
515
  }
511
516
  export function to_json(obj, replacer) {
512
517
  return JSON.stringify(obj, replacer, 4) + '\n';
@@ -3,6 +3,9 @@ export declare const noop: () => void;
3
3
  export declare const not_empty: (value: any) => boolean;
4
4
  export declare function assert(assertion: any, message?: string): never | void;
5
5
  export declare function log<T>(obj: T): T;
6
+ /** 数组或 iterable 去重(可按 selector 去重),重复值保留最后出现的那个
7
+ - selector?: 可以是 key (string) 或 (obj: any) => any */
8
+ export declare function unique<TObj>(iterable: TObj[] | Iterable<TObj>, selector?: string | ((obj: TObj) => any)): TObj[];
6
9
  /** 生成 0, 1, ..., n - 1 (不包括 n) 的数组,支持传入 generator 函数,通过 index 生成各个元素
7
10
  @example seq(10, i => `item-${i}`) */
8
11
  export declare function seq<T = number>(n: number, generator?: (index: number) => T): T[];
package/utils.browser.js CHANGED
@@ -12,6 +12,17 @@ export function log(obj) {
12
12
  console.log(obj);
13
13
  return obj;
14
14
  }
15
+ /** 数组或 iterable 去重(可按 selector 去重),重复值保留最后出现的那个
16
+ - selector?: 可以是 key (string) 或 (obj: any) => any */
17
+ export function unique(iterable, selector) {
18
+ if (!selector)
19
+ return [...new Set(iterable)];
20
+ let map = new Map();
21
+ const is_str_selector = typeof selector === 'string';
22
+ for (const x of iterable)
23
+ map.set(is_str_selector ? x[selector] : selector(x), x);
24
+ return [...map.values()];
25
+ }
15
26
  /** 生成 0, 1, ..., n - 1 (不包括 n) 的数组,支持传入 generator 函数,通过 index 生成各个元素
16
27
  @example seq(10, i => `item-${i}`) */
17
28
  export function seq(n, generator) {
@@ -216,12 +227,16 @@ export function concat(arrays) {
216
227
  export function delta2str(delta) {
217
228
  if (delta < 1)
218
229
  return '0 ms';
219
- // [1, 1000) ms
220
- if (delta < 1000)
230
+ // [1, 100) ms
231
+ if (delta < 100)
221
232
  return `${delta.toFixed(0)} ms`;
222
- // 1.1 s
223
- if (1000 <= delta && delta < 1000 * 60)
233
+ // [100, 1000) ms
234
+ // 0.8 s
235
+ if (delta <= 950)
224
236
  return `${(delta / 1000).toFixed(1)} s`;
237
+ // 3 s
238
+ if (delta < 1000 * 60)
239
+ return `${(delta / 1000).toFixed()} s`;
225
240
  // 1 min 12 s [1 min 0s, 60 min)
226
241
  const seconds = Math.trunc(delta / 1000);
227
242
  if (seconds < 60 * 60)
package/utils.js CHANGED
@@ -150,12 +150,16 @@ export function typed_array_to_buffer(view) {
150
150
  export function delta2str(delta) {
151
151
  if (delta < 1)
152
152
  return '0 ms';
153
- // [1, 1000) ms
154
- if (delta < 1000)
153
+ // [1, 100) ms
154
+ if (delta < 100)
155
155
  return `${delta.toFixed(0)} ms`;
156
- // 1.1 s
157
- if (1000 <= delta && delta < 1000 * 60)
156
+ // [100, 1000) ms
157
+ // 0.8 s
158
+ if (delta <= 950)
158
159
  return `${(delta / 1000).toFixed(1)} s`;
160
+ // 3 s
161
+ if (delta < 1000 * 60)
162
+ return `${(delta / 1000).toFixed()} s`;
159
163
  // 1 min 12 s [1 min 0s, 60 min)
160
164
  const seconds = Math.trunc(delta / 1000);
161
165
  if (seconds < 60 * 60)