xshell 1.0.54 → 1.0.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/file.d.ts +13 -6
- package/file.js +30 -12
- package/net.browser.d.ts +4 -2
- package/net.browser.js +10 -9
- package/net.d.ts +5 -4
- package/net.js +10 -10
- package/package.json +11 -11
- package/prototype.browser.d.ts +1 -2
- package/prototype.browser.js +2 -2
- package/prototype.d.ts +0 -1
- package/prototype.js +3 -8
package/file.d.ts
CHANGED
|
@@ -51,15 +51,19 @@ export declare function fread_json<T = any>(fp: string, options?: {
|
|
|
51
51
|
print?: boolean;
|
|
52
52
|
}): Promise<T>;
|
|
53
53
|
/** 写入 data 到 fp 路径所指的文件
|
|
54
|
+
会在因不存在父文件夹导致写入失败时,自动创建父文件夹,并再次尝试写入
|
|
55
|
+
最好预先创建父文件夹,减少文件系统操作,提升性能
|
|
54
56
|
- fp: 目标文件完整路径
|
|
55
57
|
- data: 支持下面几种类型
|
|
56
58
|
- string: 写入文本
|
|
57
59
|
- Uint8Array, Buffer: 写入二进制 buffer
|
|
58
|
-
- any: 通过 JSON.stringify 转为文本后写入文件
|
|
59
|
-
|
|
60
|
+
- any: 通过 JSON.stringify 转为文本后写入文件
|
|
61
|
+
- options?:
|
|
62
|
+
- dir?: 文件夹
|
|
63
|
+
- print?: `true` */
|
|
64
|
+
export declare function fwrite(fp: string | FileHandle, data: string | Uint8Array | any, { dir, print, }?: {
|
|
60
65
|
dir?: string;
|
|
61
66
|
print?: boolean;
|
|
62
|
-
mkdir?: boolean;
|
|
63
67
|
}): Promise<void>;
|
|
64
68
|
export declare function fappend(fp: string, data: string | Uint8Array, { dir, print }?: {
|
|
65
69
|
dir?: string;
|
|
@@ -103,9 +107,11 @@ export declare function ffstat(handle: fsp.FileHandle): Promise<fs.BigIntStats>;
|
|
|
103
107
|
export declare function fdelete(fp: string, { print }?: {
|
|
104
108
|
print?: boolean;
|
|
105
109
|
}): Promise<boolean>;
|
|
106
|
-
/** 复制文件或文件夹
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
/** 复制文件或文件夹
|
|
111
|
+
会在因不存在父文件夹导致复制失败时,自动创建父文件夹,并再次尝试复制
|
|
112
|
+
最好预先创建父文件夹,减少文件系统操作,提升性能
|
|
113
|
+
- fp_src: 源 文件/文件夹 完整路径
|
|
114
|
+
- fp_dst: 目标 文件/文件夹 完整路径
|
|
109
115
|
- options?:
|
|
110
116
|
- print?: `true`
|
|
111
117
|
- overwrite?: `true`
|
|
@@ -117,6 +123,7 @@ export declare function fcopy(fp_src: string, fp_dst: string, { print, overwrite
|
|
|
117
123
|
overwrite?: boolean;
|
|
118
124
|
}): Promise<void>;
|
|
119
125
|
/** 移动文件或文件夹
|
|
126
|
+
相同分区 / 文件系统下使用 rename, 否则 fallback 到复制后删除源文件
|
|
120
127
|
- src: 源 文件/文件夹 完整路径
|
|
121
128
|
- dst: 目标 文件/文件夹 完整路径
|
|
122
129
|
- options?:
|
package/file.js
CHANGED
|
@@ -55,12 +55,17 @@ export async function fread_json(fp, options = {}) {
|
|
|
55
55
|
return JSON.parse(await fread(fp, options));
|
|
56
56
|
}
|
|
57
57
|
/** 写入 data 到 fp 路径所指的文件
|
|
58
|
+
会在因不存在父文件夹导致写入失败时,自动创建父文件夹,并再次尝试写入
|
|
59
|
+
最好预先创建父文件夹,减少文件系统操作,提升性能
|
|
58
60
|
- fp: 目标文件完整路径
|
|
59
61
|
- data: 支持下面几种类型
|
|
60
62
|
- string: 写入文本
|
|
61
63
|
- Uint8Array, Buffer: 写入二进制 buffer
|
|
62
|
-
- any: 通过 JSON.stringify 转为文本后写入文件
|
|
63
|
-
|
|
64
|
+
- any: 通过 JSON.stringify 转为文本后写入文件
|
|
65
|
+
- options?:
|
|
66
|
+
- dir?: 文件夹
|
|
67
|
+
- print?: `true` */
|
|
68
|
+
export async function fwrite(fp, data, { dir, print = true, } = {}) {
|
|
64
69
|
const is_handle = typeof fp === 'object' && fp && 'fd' in fp;
|
|
65
70
|
if (is_handle) {
|
|
66
71
|
if (print)
|
|
@@ -81,10 +86,12 @@ export async function fwrite(fp, data, { dir, print = true, mkdir = false, } = {
|
|
|
81
86
|
await fsp.writeFile(fp, data);
|
|
82
87
|
}
|
|
83
88
|
catch (error) {
|
|
84
|
-
if (
|
|
89
|
+
if (error.code === 'ENOENT' && !is_handle) {
|
|
90
|
+
await fmkdir(fp.fdir, { print: false });
|
|
91
|
+
await fsp.writeFile(fp, data);
|
|
92
|
+
}
|
|
93
|
+
else
|
|
85
94
|
throw error;
|
|
86
|
-
await fmkdir(fp.fdir);
|
|
87
|
-
await fsp.writeFile(fp, data);
|
|
88
95
|
}
|
|
89
96
|
}
|
|
90
97
|
export async function fappend(fp, data, { dir, print = true } = {}) {
|
|
@@ -210,9 +217,11 @@ export async function fdelete(fp, { print = true } = {}) {
|
|
|
210
217
|
throw error;
|
|
211
218
|
}
|
|
212
219
|
}
|
|
213
|
-
/** 复制文件或文件夹
|
|
214
|
-
|
|
215
|
-
|
|
220
|
+
/** 复制文件或文件夹
|
|
221
|
+
会在因不存在父文件夹导致复制失败时,自动创建父文件夹,并再次尝试复制
|
|
222
|
+
最好预先创建父文件夹,减少文件系统操作,提升性能
|
|
223
|
+
- fp_src: 源 文件/文件夹 完整路径
|
|
224
|
+
- fp_dst: 目标 文件/文件夹 完整路径
|
|
216
225
|
- options?:
|
|
217
226
|
- print?: `true`
|
|
218
227
|
- overwrite?: `true`
|
|
@@ -232,12 +241,21 @@ export async function fcopy(fp_src, fp_dst, { print = true, overwrite = true, }
|
|
|
232
241
|
errorOnExist: !overwrite,
|
|
233
242
|
mode: overwrite ? 0 : fs.constants.COPYFILE_EXCL,
|
|
234
243
|
});
|
|
235
|
-
else
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
244
|
+
else
|
|
245
|
+
try {
|
|
246
|
+
await fsp.copyFile(fp_src, fp_dst, overwrite ? 0 : fs.constants.COPYFILE_EXCL);
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
if (error.code === 'ENOENT') {
|
|
250
|
+
await fmkdir(fp_dst.fdir, { print });
|
|
251
|
+
await fsp.copyFile(fp_src, fp_dst, overwrite ? 0 : fs.constants.COPYFILE_EXCL);
|
|
252
|
+
}
|
|
253
|
+
else
|
|
254
|
+
throw error;
|
|
255
|
+
}
|
|
239
256
|
}
|
|
240
257
|
/** 移动文件或文件夹
|
|
258
|
+
相同分区 / 文件系统下使用 rename, 否则 fallback 到复制后删除源文件
|
|
241
259
|
- src: 源 文件/文件夹 完整路径
|
|
242
260
|
- dst: 目标 文件/文件夹 完整路径
|
|
243
261
|
- options?:
|
package/net.browser.d.ts
CHANGED
|
@@ -63,12 +63,14 @@ export declare function request(url: string | URL, options: RequestOptions): Pro
|
|
|
63
63
|
export declare function request_json<T = any>(url: string, options?: RequestOptions): Promise<T>;
|
|
64
64
|
export declare class WebSocketConnectionError extends Error {
|
|
65
65
|
name: string;
|
|
66
|
+
url: string;
|
|
67
|
+
protocols?: string[];
|
|
66
68
|
websocket: WebSocket;
|
|
67
69
|
event: CloseEvent | /* error 事件时的 event,没有 event.error */ Event;
|
|
68
70
|
type: 'close' | 'error';
|
|
69
71
|
code?: number;
|
|
70
72
|
reason?: string;
|
|
71
|
-
constructor(
|
|
73
|
+
constructor(url: string, protocols: string[] | undefined, event: CloseEvent | Event, message?: string);
|
|
72
74
|
}
|
|
73
75
|
/** 连接 websocket url, 设置各种事件监听器。在 open 事件后 resolve, 返回 websocket
|
|
74
76
|
遇到 error 时会创建 WebSocketConnectionError:
|
|
@@ -86,7 +88,7 @@ export declare class WebSocketConnectionError extends Error {
|
|
|
86
88
|
- on_close?: 和 websocket 的 'close' 事件不相同,只在正常关闭 (close code 为 1000) 时才调用,否则都会调用 on_error
|
|
87
89
|
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes */
|
|
88
90
|
export declare function connect_websocket(url: string | URL, { protocols, on_message, on_error, on_close, }: {
|
|
89
|
-
protocols?: string
|
|
91
|
+
protocols?: string[];
|
|
90
92
|
on_message(data: ArrayBuffer | string, websocket: WebSocket): any;
|
|
91
93
|
on_error?(error: WebSocketConnectionError, websocket: WebSocket): any;
|
|
92
94
|
on_close?(event: CloseEvent, websocket: WebSocket): any;
|
package/net.browser.js
CHANGED
|
@@ -147,14 +147,18 @@ let decoder = new TextDecoder();
|
|
|
147
147
|
let encoder = new TextEncoder();
|
|
148
148
|
export class WebSocketConnectionError extends Error {
|
|
149
149
|
name = 'WebSocketConnectionError';
|
|
150
|
+
// 这里不保留 websocket 引用,防止循环引用导致 JSON 序列化失败
|
|
151
|
+
url;
|
|
152
|
+
protocols;
|
|
150
153
|
websocket;
|
|
151
154
|
event;
|
|
152
155
|
type;
|
|
153
156
|
code;
|
|
154
157
|
reason;
|
|
155
|
-
constructor(
|
|
156
|
-
super(`${
|
|
157
|
-
this.
|
|
158
|
+
constructor(url, protocols, event, message) {
|
|
159
|
+
super(`${url}${protocols ? ' ' + protocols.join(', ').bracket() : ''} ${t('连接出错了')}. ${message || ''}`);
|
|
160
|
+
this.url = url;
|
|
161
|
+
this.protocols = protocols;
|
|
158
162
|
this.event = event;
|
|
159
163
|
this.type = event.type;
|
|
160
164
|
if (this.type === 'close') {
|
|
@@ -186,10 +190,7 @@ export async function connect_websocket(url, { protocols, on_message, on_error,
|
|
|
186
190
|
let settled = false;
|
|
187
191
|
websocket.addEventListener('open', event => {
|
|
188
192
|
console.log(websocket.url +
|
|
189
|
-
(
|
|
190
|
-
' ' + (typeof protocols === 'string' ? protocols : protocols.join(', ').bracket('square')).bracket()
|
|
191
|
-
:
|
|
192
|
-
'') +
|
|
193
|
+
(websocket.protocol ? ' ' + websocket.protocol.bracket() : '') +
|
|
193
194
|
t(' 已连接'));
|
|
194
195
|
settled = true;
|
|
195
196
|
resolve(websocket);
|
|
@@ -201,7 +202,7 @@ export async function connect_websocket(url, { protocols, on_message, on_error,
|
|
|
201
202
|
else
|
|
202
203
|
console.log(`${websocket.url} ${t('已正常关闭')}`);
|
|
203
204
|
else { // 异常关闭,认为发生了错误,进行错误处理
|
|
204
|
-
const error = new WebSocketConnectionError(websocket, event, `${t('连接被关闭')}, code: ${event.code}${event.reason ? `, ${t('原因')}: ${event.reason}` : ''}`);
|
|
205
|
+
const error = new WebSocketConnectionError(websocket.url, protocols, event, `${t('连接被关闭')}, code: ${event.code}${event.reason ? `, ${t('原因')}: ${event.reason}` : ''}`);
|
|
205
206
|
if (settled)
|
|
206
207
|
if (on_error)
|
|
207
208
|
on_error(error, websocket);
|
|
@@ -214,7 +215,7 @@ export async function connect_websocket(url, { protocols, on_message, on_error,
|
|
|
214
215
|
}
|
|
215
216
|
});
|
|
216
217
|
websocket.addEventListener('error', event => {
|
|
217
|
-
const error = new WebSocketConnectionError(websocket, event);
|
|
218
|
+
const error = new WebSocketConnectionError(websocket.url, protocols, event);
|
|
218
219
|
// https://blog.insiderattack.net/promises-next-ticks-and-immediates-nodejs-event-loop-part-3-9226cbe7a6aa
|
|
219
220
|
// close 的错误信息比较多,这里延后触发 error 事件,放到微任务队列之后的 timers 队列中
|
|
220
221
|
setTimeout(() => {
|
package/net.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare const cookies: {
|
|
|
25
25
|
init(): Promise<void>;
|
|
26
26
|
get(domain_or_url: string, str?: boolean): Cookie[] | Promise<Cookie[] | string>;
|
|
27
27
|
};
|
|
28
|
-
export { Cookie };
|
|
28
|
+
export type { Cookie };
|
|
29
29
|
export interface BasicAuth {
|
|
30
30
|
type: 'basic';
|
|
31
31
|
username: string;
|
|
@@ -107,7 +107,8 @@ export declare function rpc(func: string, args?: any[], { url, async: _async, ig
|
|
|
107
107
|
}): Promise<any>;
|
|
108
108
|
export declare class WebSocketConnectionError extends Error {
|
|
109
109
|
name: string;
|
|
110
|
-
|
|
110
|
+
url: string;
|
|
111
|
+
protocols?: string[];
|
|
111
112
|
event: CloseEvent | ErrorEvent;
|
|
112
113
|
type: 'close' | 'error';
|
|
113
114
|
address?: string;
|
|
@@ -117,7 +118,7 @@ export declare class WebSocketConnectionError extends Error {
|
|
|
117
118
|
/** close 事件时为 close code, error 事件为 error code */
|
|
118
119
|
code?: string | number;
|
|
119
120
|
reason?: string;
|
|
120
|
-
constructor(
|
|
121
|
+
constructor(url: string, protocols: string[] | undefined, event: CloseEvent | ErrorEvent, message?: string);
|
|
121
122
|
}
|
|
122
123
|
/** 连接 websocket url, 设置各种事件监听器。在 open 事件后 resolve, 返回 websocket
|
|
123
124
|
遇到 error 时会创建 WebSocketConnectionError:
|
|
@@ -137,7 +138,7 @@ export declare class WebSocketConnectionError extends Error {
|
|
|
137
138
|
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes */
|
|
138
139
|
export declare function connect_websocket(url: string | URL, { protocols, max_payload, // 8 GB
|
|
139
140
|
on_message, on_error, on_close }: {
|
|
140
|
-
protocols?: string
|
|
141
|
+
protocols?: string[];
|
|
141
142
|
max_payload?: number;
|
|
142
143
|
on_message(data: ArrayBuffer | string, websocket: WebSocket): any;
|
|
143
144
|
on_error?(error: WebSocketConnectionError, websocket: WebSocket): any;
|
package/net.js
CHANGED
|
@@ -290,7 +290,9 @@ let decoder = new TextDecoder();
|
|
|
290
290
|
let encoder = new TextEncoder();
|
|
291
291
|
export class WebSocketConnectionError extends Error {
|
|
292
292
|
name = 'WebSocketConnectionError';
|
|
293
|
-
websocket
|
|
293
|
+
// 这里不保留 websocket 引用,防止循环引用导致 JSON 序列化失败
|
|
294
|
+
url;
|
|
295
|
+
protocols;
|
|
294
296
|
event;
|
|
295
297
|
type;
|
|
296
298
|
address;
|
|
@@ -300,9 +302,10 @@ export class WebSocketConnectionError extends Error {
|
|
|
300
302
|
/** close 事件时为 close code, error 事件为 error code */
|
|
301
303
|
code;
|
|
302
304
|
reason;
|
|
303
|
-
constructor(
|
|
304
|
-
super(`${
|
|
305
|
-
this.
|
|
305
|
+
constructor(url, protocols, event, message = '') {
|
|
306
|
+
super(`${url}${protocols ? ' ' + protocols.join(', ').bracket() : ''} ${t('连接出错了')}. ${message}`);
|
|
307
|
+
this.url = url;
|
|
308
|
+
this.protocols = protocols;
|
|
306
309
|
this.event = event;
|
|
307
310
|
this.type = event.type;
|
|
308
311
|
if (this.type === 'error') {
|
|
@@ -351,10 +354,7 @@ on_message, on_error, on_close }) {
|
|
|
351
354
|
let settled = false;
|
|
352
355
|
websocket.addEventListener('open', event => {
|
|
353
356
|
console.log(websocket.url +
|
|
354
|
-
(
|
|
355
|
-
' ' + (typeof protocols === 'string' ? protocols : protocols.join(', ').bracket('square')).bracket()
|
|
356
|
-
:
|
|
357
|
-
'') +
|
|
357
|
+
(websocket.protocol ? ' ' + websocket.protocol.bracket() : '') +
|
|
358
358
|
t(' 已连接'));
|
|
359
359
|
settled = true;
|
|
360
360
|
resolve(websocket);
|
|
@@ -372,7 +372,7 @@ on_message, on_error, on_close }) {
|
|
|
372
372
|
console.log(`${websocket.url} ${t('已正常关闭')}`);
|
|
373
373
|
else { // 异常关闭,认为发生了错误,进行错误处理
|
|
374
374
|
assert(settled, t('websocket close 事件时应该已经 settled'));
|
|
375
|
-
const error = new WebSocketConnectionError(websocket, event, `${t('连接被关闭')}, code: ${event.code}${event.reason ? `, ${t('原因')}: ${event.reason}` : ''}`);
|
|
375
|
+
const error = new WebSocketConnectionError(websocket.url, protocols, event, `${t('连接被关闭')}, code: ${event.code}${event.reason ? `, ${t('原因')}: ${event.reason}` : ''}`);
|
|
376
376
|
if (on_error)
|
|
377
377
|
on_error(error, websocket);
|
|
378
378
|
else // 既然用户不传 on_error, 就当 unhandled error 抛出来
|
|
@@ -381,7 +381,7 @@ on_message, on_error, on_close }) {
|
|
|
381
381
|
});
|
|
382
382
|
});
|
|
383
383
|
websocket.addEventListener('error', event => {
|
|
384
|
-
const error = new WebSocketConnectionError(websocket, event, event.error?.message);
|
|
384
|
+
const error = new WebSocketConnectionError(websocket.url, protocols, event, event.error?.message);
|
|
385
385
|
if (settled)
|
|
386
386
|
if (on_error)
|
|
387
387
|
on_error(error, websocket);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xshell",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.56",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"bin": {
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
]
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@babel/core": "^7.22.
|
|
49
|
-
"@babel/parser": "^7.22.
|
|
50
|
-
"@babel/traverse": "^7.22.
|
|
48
|
+
"@babel/core": "^7.22.11",
|
|
49
|
+
"@babel/parser": "^7.22.11",
|
|
50
|
+
"@babel/traverse": "^7.22.11",
|
|
51
51
|
"@koa/cors": "^4.0.0",
|
|
52
52
|
"@types/ws": "^8.5.5",
|
|
53
53
|
"byte-size": "^8.1.1",
|
|
@@ -61,8 +61,8 @@
|
|
|
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.
|
|
65
|
-
"i18next-scanner": "^4.
|
|
64
|
+
"i18next": "^23.4.6",
|
|
65
|
+
"i18next-scanner": "^4.4.0",
|
|
66
66
|
"js-cookie": "^3.0.5",
|
|
67
67
|
"koa": "^2.14.2",
|
|
68
68
|
"koa-compress": "^5.1.1",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"through2": "^4.0.2",
|
|
78
78
|
"tough-cookie": "^4.1.3",
|
|
79
79
|
"tslib": "^2.6.2",
|
|
80
|
-
"typescript": "^5.
|
|
80
|
+
"typescript": "^5.2.2",
|
|
81
81
|
"ua-parser-js": "2.0.0-alpha.2",
|
|
82
82
|
"undici": "^5.23.0",
|
|
83
83
|
"vinyl": "^3.0.0",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"ws": "^8.13.0"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
|
-
"@babel/types": "^7.22.
|
|
88
|
+
"@babel/types": "^7.22.11",
|
|
89
89
|
"@types/babel__traverse": "^7.20.1",
|
|
90
90
|
"@types/byte-size": "^8.1.0",
|
|
91
91
|
"@types/chardet": "^0.8.1",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"@types/koa-compress": "^4.0.3",
|
|
96
96
|
"@types/lodash": "^4.14.197",
|
|
97
97
|
"@types/mime-types": "^2.1.1",
|
|
98
|
-
"@types/node": "^20.5.
|
|
98
|
+
"@types/node": "^20.5.7",
|
|
99
99
|
"@types/react": "^18.2.21",
|
|
100
100
|
"@types/through2": "^2.0.38",
|
|
101
101
|
"@types/tough-cookie": "^4.0.2",
|
|
@@ -104,9 +104,9 @@
|
|
|
104
104
|
"@types/vscode": "^1.81.0",
|
|
105
105
|
"@typescript-eslint/eslint-plugin": "^6.4.1",
|
|
106
106
|
"@typescript-eslint/parser": "^6.4.1",
|
|
107
|
-
"eslint": "^8.
|
|
107
|
+
"eslint": "^8.48.0",
|
|
108
108
|
"eslint-plugin-react": "^7.33.2",
|
|
109
|
-
"eslint-plugin-xlint": "^1.0.
|
|
109
|
+
"eslint-plugin-xlint": "^1.0.8"
|
|
110
110
|
},
|
|
111
111
|
"scripts": {
|
|
112
112
|
"start": "node --title=xshell --inspect=0.0.0.0:8420 ./xshell.js",
|
package/prototype.browser.d.ts
CHANGED
|
@@ -10,8 +10,7 @@ declare global {
|
|
|
10
10
|
truncate(this: string, width: number): string;
|
|
11
11
|
/** pad string to `<width>`
|
|
12
12
|
- character?: `' '`
|
|
13
|
-
- position?: `'right'`
|
|
14
|
-
*/
|
|
13
|
+
- position?: `'right'` */
|
|
15
14
|
pad(this: string, width: number, { character, position }?: {
|
|
16
15
|
character?: string;
|
|
17
16
|
position?: 'left' | 'right';
|
package/prototype.browser.js
CHANGED
|
@@ -149,7 +149,7 @@ Object.defineProperties(String.prototype, {
|
|
|
149
149
|
add_part(last_end);
|
|
150
150
|
// 最后一个 (.*?) 改为贪心匹配,满足 .{suffix} 的需要
|
|
151
151
|
regx_parts = regx_parts.filter(part => part);
|
|
152
|
-
if (regx_parts.
|
|
152
|
+
if (regx_parts[regx_parts.length - 1] === '(.*?)')
|
|
153
153
|
regx_parts[regx_parts.length - 1] = '(.*)';
|
|
154
154
|
const pattern_regx = new RegExp(regx_parts.join(''), flags);
|
|
155
155
|
// --- 根据 pattern_regx 去匹配原有字符串,获取匹配结果,生成 placeholders 词典
|
|
@@ -240,7 +240,7 @@ Object.defineProperties(String.prototype, {
|
|
|
240
240
|
},
|
|
241
241
|
split_lines(delimiter = /\r?\n/) {
|
|
242
242
|
let lines = this.split(delimiter);
|
|
243
|
-
if (lines.
|
|
243
|
+
if (lines[lines.length - 1] === '')
|
|
244
244
|
lines.pop();
|
|
245
245
|
return lines;
|
|
246
246
|
},
|
package/prototype.d.ts
CHANGED
package/prototype.js
CHANGED
|
@@ -147,7 +147,7 @@ if (!globalThis.my_prototype_defined) {
|
|
|
147
147
|
add_part(last_end);
|
|
148
148
|
// 最后一个 (.*?) 改为贪心匹配,满足 .{suffix} 的需要
|
|
149
149
|
regx_parts = regx_parts.filter(part => part);
|
|
150
|
-
if (regx_parts.
|
|
150
|
+
if (regx_parts.at(-1) === '(.*?)')
|
|
151
151
|
regx_parts[regx_parts.length - 1] = '(.*)';
|
|
152
152
|
const pattern_regx = new RegExp(regx_parts.join(''), flags);
|
|
153
153
|
// --- 根据 pattern_regx 去匹配原有字符串,获取匹配结果,生成 placeholders 词典
|
|
@@ -204,7 +204,7 @@ if (!globalThis.my_prototype_defined) {
|
|
|
204
204
|
add_part(last_end);
|
|
205
205
|
// 最后一个 (.*?) 改为贪心匹配,满足 .{suffix} 的需要
|
|
206
206
|
regx_parts = regx_parts.filter(part => part);
|
|
207
|
-
if (regx_parts
|
|
207
|
+
if (regx_parts.at(-1) === '(.*?)')
|
|
208
208
|
regx_parts[regx_parts.length - 1] = '(.*)';
|
|
209
209
|
const pattern_regx = new RegExp(regx_parts.join(''), flags);
|
|
210
210
|
// --- 根据 pattern_regx 去匹配原有字符串,获取匹配结果,生成 placeholders 词典
|
|
@@ -241,7 +241,7 @@ if (!globalThis.my_prototype_defined) {
|
|
|
241
241
|
},
|
|
242
242
|
split_lines(delimiter = /\r?\n/) {
|
|
243
243
|
let lines = this.split(delimiter);
|
|
244
|
-
if (lines.
|
|
244
|
+
if (lines.at(-1) === '')
|
|
245
245
|
lines.pop();
|
|
246
246
|
return lines;
|
|
247
247
|
},
|
|
@@ -408,11 +408,6 @@ if (!globalThis.my_prototype_defined) {
|
|
|
408
408
|
}));
|
|
409
409
|
// ------------------------------------ Array.prototype
|
|
410
410
|
Object.defineProperties(Array.prototype, {
|
|
411
|
-
...to_getter_property_descriptors({
|
|
412
|
-
last() {
|
|
413
|
-
return this[this.length - 1];
|
|
414
|
-
}
|
|
415
|
-
}),
|
|
416
411
|
// --- 文本处理工具方法
|
|
417
412
|
...to_method_property_descriptors({
|
|
418
413
|
log(limit = 10000) {
|