xshell 1.1.7 → 1.1.9

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/antd.sass ADDED
@@ -0,0 +1,43 @@
1
+ .ant-modal-root
2
+ // 增加 modal 标题下方空白
3
+ .ant-modal-header
4
+ margin-bottom: 18px
5
+
6
+ .ant-modal-mask
7
+ background-color: unset
8
+
9
+ .ant-modal
10
+ .ant-modal-content
11
+ padding: 20px
12
+
13
+
14
+ @mixin height()
15
+ .ant-table-wrapper
16
+ height: 100%
17
+
18
+ .ant-spin-nested-loading
19
+ height: 100%
20
+
21
+ .ant-spin-container
22
+ height: 100%
23
+ display: flex
24
+ flex-direction: column
25
+
26
+ .ant-table-container
27
+ height: 100%
28
+ display: flex
29
+ flex-direction: column
30
+
31
+ .ant-table-body
32
+ position: relative
33
+ flex: 1
34
+
35
+ table
36
+ position: absolute
37
+ left: 0
38
+ top: 0
39
+ right: 0
40
+ bottom: 0
41
+
42
+ .ant-table
43
+ flex: 1
package/file.js CHANGED
@@ -154,7 +154,10 @@ export async function flist(fpd, options = {}) {
154
154
  return _stats;
155
155
  }
156
156
  if (deep)
157
- return (await Promise.all(fps.map(async (fp) => {
157
+ return (await Promise.all(
158
+ // 顶层文件/文件夹
159
+ fps.map(async (fp) => {
160
+ /** 顶层文件夹的大小 */
158
161
  let fpd_stats;
159
162
  return fp.isdir ?
160
163
  [
@@ -163,7 +166,9 @@ export async function flist(fpd, options = {}) {
163
166
  if (stats) {
164
167
  if (!absolute)
165
168
  fp_or_stats.fp = fp + fp_or_stats.fp;
166
- fpd_stats.size += fp_or_stats.size;
169
+ // 所有顶层文件夹中的文件(不包括文件夹)大小总和加起来作为文件夹大小
170
+ if (!fp_or_stats.fp.isdir)
171
+ fpd_stats.size += fp_or_stats.size;
167
172
  return fp_or_stats;
168
173
  }
169
174
  else
package/i18n/dict.json CHANGED
@@ -382,5 +382,8 @@
382
382
  },
383
383
  "等待 {{duration}} 秒后重试 request (已尝试 {{_count}} 次) …": {
384
384
  "en": "Wait {{duration}} seconds before retrying request (tried {{_count}} times) …"
385
+ },
386
+ "fsend 必须传 absolute 选项, sea 选项, 或 fpd_root 文件夹": {
387
+ "en": "fsend must be passed the absolute option, the sea option, or the fpd_root folder"
385
388
  }
386
389
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xshell",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -57,17 +57,16 @@
57
57
  "@svgr/webpack": "^8.1.0",
58
58
  "@types/sass-loader": "^8.0.9",
59
59
  "@types/ws": "^8.5.13",
60
- "@typescript-eslint/eslint-plugin": "^8.18.0",
61
- "@typescript-eslint/parser": "^8.18.0",
62
- "@typescript-eslint/utils": "^8.18.0",
60
+ "@typescript-eslint/eslint-plugin": "^8.18.1",
61
+ "@typescript-eslint/parser": "^8.18.1",
62
+ "@typescript-eslint/utils": "^8.18.1",
63
63
  "@xterm/addon-fit": "^0.10.0",
64
64
  "@xterm/addon-web-links": "^0.11.0",
65
65
  "@xterm/addon-webgl": "^0.18.0",
66
66
  "@xterm/xterm": "^5.5.0",
67
67
  "ali-oss": "^6.22.0",
68
68
  "archiver": "^7.0.1",
69
- "byte-size": "^9.0.1",
70
- "chalk": "^5.3.0",
69
+ "chalk": "^5.4.0",
71
70
  "chardet": "^2.0.0",
72
71
  "cli-table3": "^0.6.5",
73
72
  "cli-truncate": "^4.0.0",
@@ -81,7 +80,7 @@
81
80
  "gulp-sort": "^2.0.0",
82
81
  "hash-string": "^1.0.0",
83
82
  "https-proxy-agent": "^7.0.6",
84
- "i18next": "^24.1.0",
83
+ "i18next": "^24.2.0",
85
84
  "i18next-scanner": "^4.6.0",
86
85
  "koa": "^2.15.3",
87
86
  "koa-compress": "^5.1.1",
@@ -92,7 +91,7 @@
92
91
  "ora": "^8.1.1",
93
92
  "react": "^19.0.0",
94
93
  "react-i18next": "^15.2.0",
95
- "react-object-model": "^1.2.20",
94
+ "react-object-model": "^1.2.21",
96
95
  "resolve-path": "^1.4.0",
97
96
  "sass": "^1.83.0",
98
97
  "sass-loader": "^16.0.4",
@@ -105,7 +104,7 @@
105
104
  "tslib": "^2.8.1",
106
105
  "typescript": "^5.7.2",
107
106
  "ua-parser-js": "^2.0.0",
108
- "undici": "^7.1.0",
107
+ "undici": "^7.2.0",
109
108
  "vinyl": "^3.0.0",
110
109
  "vinyl-fs": "^4.0.0",
111
110
  "webpack": "^5.97.1",
@@ -117,7 +116,6 @@
117
116
  "@types/ali-oss": "^6.16.11",
118
117
  "@types/archiver": "^6.0.3",
119
118
  "@types/babel__traverse": "^7.20.6",
120
- "@types/byte-size": "^8.1.2",
121
119
  "@types/chardet": "^0.8.3",
122
120
  "@types/eslint": "^9.6.1",
123
121
  "@types/estree": "^1.0.6",
@@ -127,7 +125,7 @@
127
125
  "@types/lodash": "^4.17.13",
128
126
  "@types/mime-types": "^2.1.4",
129
127
  "@types/node": "^22.10.2",
130
- "@types/react": "^19.0.1",
128
+ "@types/react": "^19.0.2",
131
129
  "@types/through2": "^2.0.41",
132
130
  "@types/tough-cookie": "^4.0.5",
133
131
  "@types/ua-parser-js": "^0.7.39",
@@ -137,7 +135,6 @@
137
135
  },
138
136
  "pnpm": {
139
137
  "patchedDependencies": {
140
- "@types/byte-size@8.1.2": "patches/@types__byte-size@8.1.2.patch",
141
138
  "koa@2.15.3": "patches/koa@2.15.3.patch"
142
139
  }
143
140
  }
@@ -60,6 +60,8 @@ declare global {
60
60
  - pattern_placeholder?: `/\{.*?\}/g`
61
61
  */
62
62
  find(this: string, pattern: string, preservations?: string, flags?: string, pattern_placeholder?: RegExp): Record<string, string>;
63
+ /** 查找子串或字符出现的次数 */
64
+ count(this: string, search: string): number;
63
65
  /** - type?: `'single'` */
64
66
  quote(this: string, type?: keyof typeof quotes | 'psh'): string;
65
67
  /** - shape?: `'parenthesis'` */
@@ -134,8 +136,8 @@ declare global {
134
136
  to_formal_str(this: Date, ms?: boolean): string;
135
137
  }
136
138
  interface Number {
137
- /** 12.4 KB (1 KB = 1024 B) */
138
- to_fsize_str(this: number, units?: 'iec' | 'metric'): string;
139
+ /** 12.4 kb (1 kb = 1024 b) */
140
+ to_fsize_str(this: number): string;
139
141
  to_bin_str(this: number): string;
140
142
  /** 转换为 0x???? 这样的十六进制形式
141
143
  - length?: 位数自动对齐到 4 的倍数 */
@@ -146,8 +148,8 @@ declare global {
146
148
  /** 等价于 .at(-1) */
147
149
  last: T;
148
150
  indent(this: string[], width?: number, c?: string): string[];
149
- /** 对数组中所有元素求和 (+), 返回结果 */
150
- sum(this: T[]): T;
151
+ /** 对数组中所有元素求和 (+), 返回结果,可传入 selector 选择某个属性,或者计算出某个值,用作求和 */
152
+ sum<TReturn = T>(this: T[], selector?: keyof T | KeySelector<T>): TReturn;
151
153
  /** 查找数组中最大的元素,可传入 selector 选择某个属性,或者计算出某个值,用作大小比较 */
152
154
  max(this: T[], selector?: keyof T | KeySelector<T>): T;
153
155
  /** 查找数组中最小的元素,可传入 selector 选择某个属性,或者计算出某个值,用作大小比较 */
@@ -169,6 +171,8 @@ declare global {
169
171
  join_lines(append?: boolean): string;
170
172
  }
171
173
  interface BigInt {
174
+ /** 12.4 kb (1 kb = 1024 b) */
175
+ to_fsize_str(this: bigint): string;
172
176
  toJSON(this: bigint): string;
173
177
  }
174
178
  interface Error {
@@ -215,4 +219,5 @@ export declare const brackets: {
215
219
  };
216
220
  export declare function to_json(obj: any, replacer?: any): string;
217
221
  export declare function is_codepoint_fullwidth(codepoint: number): boolean;
222
+ export declare function byte_size(bytes: number | bigint): string;
218
223
  export {};
@@ -1,5 +1,4 @@
1
1
  /** 在浏览器端修改 prototype,需要更加小心 */
2
- import byte_size from 'byte-size';
3
2
  import EmojiRegex from 'emoji-regex';
4
3
  import { t } from "./i18n/instance.js";
5
4
  export const emoji_regex = EmojiRegex();
@@ -224,6 +223,14 @@ Object.defineProperties(String.prototype, {
224
223
  return Object.fromEntries(Object.entries($placeholders)
225
224
  .map(([name, $i]) => [name, matches[$i] || '']));
226
225
  },
226
+ count(search) {
227
+ if (!search)
228
+ throw new Error('count 的 search 不能为空');
229
+ let count = 0;
230
+ for (let i = 0; (i = this.indexOf(search, i)) !== -1; i += search.length)
231
+ count++;
232
+ return count;
233
+ },
227
234
  quote(type = 'single') {
228
235
  if (type === 'psh')
229
236
  return `& ${this.quote()}`;
@@ -418,9 +425,8 @@ function get_time_str(date, hour, ms, splitter) {
418
425
  }
419
426
  // ------------------------------------ Number.prototype
420
427
  Object.defineProperties(Number.prototype, to_method_property_descriptors({
421
- to_fsize_str(units = 'iec') {
422
- const { value, unit } = byte_size(this, { units });
423
- return `${value} ${unit.replace('i', '')}`;
428
+ to_fsize_str() {
429
+ return byte_size(this);
424
430
  },
425
431
  to_bin_str() {
426
432
  return `0b${this.toString(2)}`;
@@ -467,10 +473,17 @@ Object.defineProperties(Array.prototype, {
467
473
  const indent = character.repeat(width);
468
474
  return this.map(line => indent + line);
469
475
  },
470
- sum() {
471
- return this.length
472
- ? this.reduce((acc, x) => acc + x)
473
- : undefined;
476
+ sum(selector) {
477
+ if (!this.length)
478
+ return undefined;
479
+ // 快捷路径
480
+ const first = this[0];
481
+ if ((typeof first === 'number' || typeof first === 'bigint') && !selector)
482
+ return this.reduce((acc, x) => acc + x, first);
483
+ if (is_key_type(selector))
484
+ selector = build_selector(selector);
485
+ selector ??= ident;
486
+ return this.reduce((acc, x) => acc + selector(x), selector(first));
474
487
  },
475
488
  max(selector = ident) {
476
489
  if (!this.length)
@@ -520,6 +533,9 @@ Object.defineProperties(Array.prototype, {
520
533
  })
521
534
  });
522
535
  Object.defineProperties(BigInt.prototype, to_method_property_descriptors({
536
+ to_fsize_str() {
537
+ return byte_size(this);
538
+ },
523
539
  toJSON() {
524
540
  return this.toString();
525
541
  }
@@ -583,4 +599,17 @@ export function is_codepoint_fullwidth(codepoint) {
583
599
  // cjk unified ideographs extension b .. tertiary ideographic plane
584
600
  (0x20000 <= codepoint && codepoint <= 0x3fffd)));
585
601
  }
602
+ const units = ['b', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb', 'zb', 'yb'];
603
+ const bytes_table = units.map((unit, i) => ({
604
+ start: i === 0 ? 0 : 2 ** (i * 10),
605
+ end: 2 ** ((i + 1) * 10),
606
+ unit
607
+ }));
608
+ export function byte_size(bytes) {
609
+ bytes = Number(bytes);
610
+ const sign = bytes < 0 ? '-' : '';
611
+ bytes = Math.abs(bytes);
612
+ const { unit, start } = bytes_table.find(range => bytes >= range.start && bytes < range.end);
613
+ return `${sign}${start === 0 ? bytes : (bytes / start).toFixed()} ${unit}`;
614
+ }
586
615
  //# sourceMappingURL=prototype.browser.js.map
package/prototype.d.ts CHANGED
@@ -59,6 +59,8 @@ declare global {
59
59
  - flags?: `''` 正则匹配选项
60
60
  - pattern_placeholder?: `/\{.*?\}/g` */
61
61
  find(this: string, pattern: string, preservations?: string, flags?: string, pattern_placeholder?: RegExp): Record<string, string>;
62
+ /** 查找子串或字符出现的次数 */
63
+ count(this: string, search: string): number;
62
64
  /** - type?: `'single'` 引号类型 */
63
65
  quote(this: string, type?: keyof typeof quotes | 'psh'): string;
64
66
  /** - type?: `'single'` 引号类型 */
@@ -157,8 +159,8 @@ declare global {
157
159
  to_formal_str(this: Date, ms?: boolean): string;
158
160
  }
159
161
  interface Number {
160
- /** 12.4 KB (1 KB = 1024 B) */
161
- to_fsize_str(this: number, units?: 'iec' | 'metric'): string;
162
+ /** 12.4 kb (1 kb = 1024 b) */
163
+ to_fsize_str(this: number): string;
162
164
  to_bin_str(this: number): string;
163
165
  /** 转换为 0x???? 这样的十六进制形式
164
166
  - length?: 位数自动对齐到 4 的倍数 */
@@ -171,8 +173,8 @@ declare global {
171
173
  log(this: string[], limit?: number): void;
172
174
  indent(this: string[], width?: number, c?: string): string[];
173
175
  indent2to4(this: string[]): string[];
174
- /** 对数组中所有元素求和 (+), 返回结果 */
175
- sum(this: T[]): T;
176
+ /** 对数组中所有元素求和 (+), 返回结果,可传入 selector 选择某个属性,或者计算出某个值,用作求和 */
177
+ sum<TReturn = T>(this: T[], selector?: keyof T | KeySelector<T>): TReturn;
176
178
  /** 查找数组中最大的元素,可传入 selector 选择某个属性,或者计算出某个值,用作大小比较 */
177
179
  max(this: T[], selector?: keyof T | KeySelector<T>): T;
178
180
  /** 查找数组中最小的元素,可传入 selector 选择某个属性,或者计算出某个值,用作大小比较 */
@@ -199,6 +201,8 @@ declare global {
199
201
  join_lines(append?: boolean): string;
200
202
  }
201
203
  interface BigInt {
204
+ /** 12.4 kb (1 kb = 1024 b) */
205
+ to_fsize_str(this: bigint): string;
202
206
  toJSON(this: bigint): string;
203
207
  }
204
208
  interface Error {
@@ -212,9 +216,7 @@ interface SliceOptions {
212
216
  include?: boolean;
213
217
  last?: boolean;
214
218
  }
215
- import chalk from 'chalk';
216
219
  export declare const emoji_regex: RegExp;
217
- export { chalk };
218
220
  export declare const noop: () => void;
219
221
  export declare const ident: <T>(x: T) => T;
220
222
  export declare const build_selector: <TObj>(key: keyof TObj) => (obj: TObj) => TObj[keyof TObj];
@@ -248,3 +250,5 @@ export declare const brackets: {
248
250
  export declare function to_json(obj: any, replacer?: any): string;
249
251
  export declare function to_json_safely(obj: any, replacer?: any): string;
250
252
  export declare function is_codepoint_fullwidth(codepoint: number): boolean;
253
+ export declare function byte_size(bytes: number | bigint): string;
254
+ export {};
package/prototype.js CHANGED
@@ -1,12 +1,9 @@
1
- import byte_size from 'byte-size';
1
+ import util from 'util';
2
2
  import EmojiRegex from 'emoji-regex';
3
+ export const emoji_regex = EmojiRegex();
3
4
  import strip_ansi from 'strip-ansi';
4
- import chalk from 'chalk';
5
5
  import { to_fp, dirname, basename, extname } from "./path.js";
6
6
  import { t } from "./i18n/instance.js";
7
- chalk.level = 2;
8
- export const emoji_regex = EmojiRegex();
9
- export { chalk };
10
7
  export const noop = () => { };
11
8
  export const ident = (x) => x;
12
9
  export const build_selector = (key) => (obj) => obj[key];
@@ -47,7 +44,6 @@ export const brackets = {
47
44
  fat: ['【', '】'],
48
45
  tortoise_shell: ['〔', '〕'],
49
46
  };
50
- const color_map = Object.fromEntries(['red_', 'green_', 'yellow_', 'blue_', 'magenta_', 'cyan_'].map(color => [color, `${color.slice(0, -1)}Bright`]));
51
47
  if (!globalThis.my_prototype_defined) {
52
48
  // ------------------------------------ String.prototype
53
49
  Object.defineProperties(String.prototype, {
@@ -222,6 +218,15 @@ if (!globalThis.my_prototype_defined) {
222
218
  return Object.fromEntries(Object.entries($placeholders)
223
219
  .map(([name, $i]) => [name, matches[$i] || '']));
224
220
  },
221
+ /** 查找子串或字符出现的次数 */
222
+ count(search) {
223
+ if (!search)
224
+ throw new Error('count 的 search 不能为空');
225
+ let count = 0;
226
+ for (let i = 0; (i = this.indexOf(search, i)) !== -1; i += search.length)
227
+ count++;
228
+ return count;
229
+ },
225
230
  quote(type = 'single') {
226
231
  if (type === 'psh')
227
232
  return `& ${this.quote()}`;
@@ -345,17 +350,21 @@ if (!globalThis.my_prototype_defined) {
345
350
  .replace(new RegExp('([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])' + cjk, 'g'), '$1 $2');
346
351
  }
347
352
  }),
348
- // ------------ chalk colors
353
+ // ------------ colors
349
354
  ...Object.fromEntries([
350
355
  'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'grey',
351
356
  'red_', 'green_', 'yellow_', 'blue_', 'magenta_', 'cyan_',
352
357
  'underline',
353
- ].map(color => ([color, {
354
- configurable: true,
355
- get() {
356
- return chalk[color_map[color] || color](this);
357
- }
358
- }]))),
358
+ ].map(color => {
359
+ const style = color.endsWith('_') ? `${color.slice(0, -1)}Bright` : color;
360
+ return [color, {
361
+ configurable: true,
362
+ get() {
363
+ // @ts-ignore
364
+ return util.styleText(style, this, { validateStream: false });
365
+ }
366
+ }];
367
+ })),
359
368
  // ------------ 文件路径操作
360
369
  ...to_getter_property_descriptors({
361
370
  isdir() {
@@ -447,9 +456,8 @@ if (!globalThis.my_prototype_defined) {
447
456
  }
448
457
  // ------------------------------------ Number.prototype
449
458
  Object.defineProperties(Number.prototype, to_method_property_descriptors({
450
- to_fsize_str(units = 'iec') {
451
- const { value, unit } = byte_size(this, { units });
452
- return `${value} ${unit.replace('i', '')}`;
459
+ to_fsize_str() {
460
+ return byte_size(this);
453
461
  },
454
462
  to_bin_str() {
455
463
  return `0b${this.toString(2)}`;
@@ -520,10 +528,17 @@ if (!globalThis.my_prototype_defined) {
520
528
  return this.split_indents()
521
529
  .map(line => ' '.repeat(line.indent * 2) + line.text);
522
530
  },
523
- sum() {
524
- return this.length
525
- ? this.reduce((acc, x) => acc + x)
526
- : undefined;
531
+ sum(selector) {
532
+ if (!this.length)
533
+ return undefined;
534
+ // 快捷路径
535
+ const first = this[0];
536
+ if ((typeof first === 'number' || typeof first === 'bigint') && !selector)
537
+ return this.reduce((acc, x) => acc + x, first);
538
+ if (is_key_type(selector))
539
+ selector = build_selector(selector);
540
+ selector ??= ident;
541
+ return this.reduce((acc, x) => acc + selector(x), selector(first));
527
542
  },
528
543
  max(selector = ident) {
529
544
  if (!this.length)
@@ -573,6 +588,9 @@ if (!globalThis.my_prototype_defined) {
573
588
  })
574
589
  });
575
590
  Object.defineProperties(BigInt.prototype, to_method_property_descriptors({
591
+ to_fsize_str() {
592
+ return byte_size(this);
593
+ },
576
594
  toJSON() {
577
595
  return this.toString();
578
596
  }
@@ -643,4 +661,17 @@ export function is_codepoint_fullwidth(codepoint) {
643
661
  // cjk unified ideographs extension b .. tertiary ideographic plane
644
662
  (0x20000 <= codepoint && codepoint <= 0x3fffd)));
645
663
  }
664
+ const units = ['b', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb', 'zb', 'yb'];
665
+ const bytes_table = units.map((unit, i) => ({
666
+ start: i === 0 ? 0 : 2 ** (i * 10),
667
+ end: 2 ** ((i + 1) * 10),
668
+ unit
669
+ }));
670
+ export function byte_size(bytes) {
671
+ bytes = Number(bytes);
672
+ const sign = bytes < 0 ? '-' : '';
673
+ bytes = Math.abs(bytes);
674
+ const { unit, start } = bytes_table.find(range => bytes >= range.start && bytes < range.end);
675
+ return `${sign}${start === 0 ? bytes : (bytes / start).toFixed()} ${unit}`;
676
+ }
646
677
  //# sourceMappingURL=prototype.js.map
package/server.d.ts CHANGED
@@ -2,7 +2,7 @@ import { type Server as HttpServer, type IncomingHttpHeaders, type IncomingMessa
2
2
  import { type Http2SecureServer, type IncomingHttpHeaders as IncomingHttp2Headers } from 'http2';
3
3
  import type { Duplex } from 'stream';
4
4
  import type { WebSocketServer } from 'ws';
5
- import type { default as Koa, Context, Next } from 'koa';
5
+ import { default as Koa, type Context, type Next } from 'koa';
6
6
  declare module 'koa' {
7
7
  interface Request {
8
8
  /** 经过 decodeURIComponent 后,在路径重写之前的路径 */
@@ -13,7 +13,6 @@ declare module 'koa' {
13
13
  compress: boolean;
14
14
  }
15
15
  }
16
- import type { UAParser } from 'ua-parser-js';
17
16
  import { Remote, type RequestOptions, type RawResponse } from './net.ts';
18
17
  declare module 'http' {
19
18
  interface IncomingMessage {
@@ -34,7 +33,6 @@ export declare class Server {
34
33
  };
35
34
  /** sea 下最后修改时间,用于 http 资源缓存 */
36
35
  last_modified_str?: string;
37
- UAParser: typeof UAParser;
38
36
  js_exts: Set<string>;
39
37
  empty_body_statuses: Set<number>;
40
38
  empty_body_methods: Set<string>;
package/server.js CHANGED
@@ -6,6 +6,12 @@ import fs from 'fs';
6
6
  import { buffer as stream_to_buffer } from 'stream/consumers';
7
7
  import util from 'util';
8
8
  import node_sea from 'node:sea';
9
+ import { default as Koa } from 'koa';
10
+ import KoaCors from '@koa/cors';
11
+ import KoaCompress from 'koa-compress';
12
+ import { UAParser } from 'ua-parser-js';
13
+ import resolve_safely from 'resolve-path';
14
+ import { contentType as get_content_type } from 'mime-types';
9
15
  // --- my libs
10
16
  import { t } from "./i18n/instance.js";
11
17
  import { request as _request, Remote } from "./net.js";
@@ -31,7 +37,6 @@ export class Server {
31
37
  };
32
38
  /** sea 下最后修改时间,用于 http 资源缓存 */
33
39
  last_modified_str;
34
- UAParser;
35
40
  js_exts = new Set(['.js', '.mjs', '.cjs']);
36
41
  empty_body_statuses = new Set([304, 204, 205]);
37
42
  empty_body_methods = new Set(['HEAD', 'OPTIONS']);
@@ -93,14 +98,9 @@ export class Server {
93
98
  }
94
99
  /** start http server and listen */
95
100
  async start() {
96
- const { default: Koa } = await import('koa');
97
- const { default: KoaCors } = await import('@koa/cors');
98
- const { default: KoaCompress } = await import('koa-compress');
99
101
  if (sea)
100
102
  this.last_modified_str = (await fstat(exe_nodejs))
101
103
  .mtime.toUTCString();
102
- const { UAParser } = await import('ua-parser-js');
103
- this.UAParser = UAParser;
104
104
  // --- init koa app
105
105
  let app = new Koa();
106
106
  app.on('error', this.on_error.bind(this));
@@ -442,7 +442,7 @@ export class Server {
442
442
  }
443
443
  format_ua(headers) {
444
444
  const { rtt, 'device-memory': memory } = headers;
445
- const { device, os, browser } = this.UAParser(headers).withClientHints();
445
+ const { device, os, browser } = UAParser(headers).withClientHints();
446
446
  const vendor = device.vendor?.toLowerCase();
447
447
  const model = device.model?.toLowerCase();
448
448
  const osname = os.name?.toLowerCase();
@@ -603,7 +603,6 @@ export class Server {
603
603
  let { response } = ctx;
604
604
  if (!absolute && !_sea) {
605
605
  fp = fp.strip_if_start(fpd_root).strip_if_start('/');
606
- const { default: resolve_safely } = await import('resolve-path');
607
606
  try {
608
607
  fp = resolve_safely(fpd_root, fp).fp;
609
608
  }
@@ -652,7 +651,6 @@ export class Server {
652
651
  if (download)
653
652
  response.set('content-disposition', `attachment; filename="${encodeURIComponent(fp.fname)}"`);
654
653
  if (!response.get('content-type')) {
655
- const { contentType: get_content_type } = await import('mime-types');
656
654
  const { fext } = fp;
657
655
  response.set('content-type', (this.js_exts.has(fext) ? 'text/javascript; chatset=utf-8' : get_content_type(fext))
658
656
  || 'application/octet-stream');
package/storage.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export declare let storage: {
2
+ /** 通过 key 获取字符串类型的值,不存在时返回空字符串 ('') */
3
+ getstr(key: string): string;
4
+ /** 将字符串类型的值保存到 key */
5
+ setstr(key: string, value?: string): void;
6
+ /** 根据 key 获取 JSON 类型的值,不存在时返回通过第二个参数传入的默认值,默认为 null */
7
+ get<TValue = any>(key: string, _default?: TValue): TValue;
8
+ /** 保存 JSON 类型的值到 key */
9
+ set(key: string, value: any): void;
10
+ list(): string[];
11
+ delete(key: string): void;
12
+ };
package/storage.js ADDED
@@ -0,0 +1,28 @@
1
+ export let storage = {
2
+ /** 通过 key 获取字符串类型的值,不存在时返回空字符串 ('') */
3
+ getstr(key) {
4
+ return localStorage.getItem(key) || '';
5
+ },
6
+ /** 将字符串类型的值保存到 key */
7
+ setstr(key, value = '') {
8
+ localStorage.setItem(key, value);
9
+ },
10
+ /** 根据 key 获取 JSON 类型的值,不存在时返回通过第二个参数传入的默认值,默认为 null */
11
+ get(key, _default = null) {
12
+ const strvalue = localStorage.getItem(key);
13
+ return strvalue === null
14
+ ? _default
15
+ : JSON.parse(strvalue);
16
+ },
17
+ /** 保存 JSON 类型的值到 key */
18
+ set(key, value) {
19
+ localStorage.setItem(key, JSON.stringify(value));
20
+ },
21
+ list() {
22
+ return Object.keys(localStorage);
23
+ },
24
+ delete(key) {
25
+ localStorage.removeItem(key);
26
+ }
27
+ };
28
+ //# sourceMappingURL=storage.js.map
@@ -1,14 +0,0 @@
1
- # 用来修复 `byte_size()` 函数的 ts 类型报错
2
-
3
- diff --git a/package.json b/package.json
4
- index dd8ed66fcb8b1ab93f0a3a015bad95bc31d3b18d..6a3753f42610451163fd7d502a93779fe3dca8db 100644
5
- --- a/package.json
6
- +++ b/package.json
7
- @@ -11,6 +11,7 @@
8
- "url": "https://github.com/lntel"
9
- }
10
- ],
11
- + "type": "module",
12
- "main": "",
13
- "types": "index.d.ts",
14
- "repository": {