@whitesev/utils 2.11.11 → 2.11.12

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/src/Utils.ts CHANGED
@@ -102,19 +102,25 @@ class Utils {
102
102
  }
103
103
  /**
104
104
  * ajax劫持库,支持xhr和fetch劫持。
105
- * + 来源:https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
106
- * + 作者:cxxjackie
107
- * + 版本:1.4.8
108
- * + 旧版本:1.2.4
109
- * + 文档:https://scriptcat.org/zh-CN/script-show-page/637/
110
- * @param useOldVersion 是否使用旧版本,默认false
105
+ * + 来源: https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
106
+ * + 作者: cxxjackie
107
+ * + 实现方式: Proxy
108
+ * + 版本: `1.4.8`
109
+ * + 文档: https://scriptcat.org/zh-CN/script-show-page/637/
111
110
  */
112
- ajaxHooker = (useOldVersion: boolean = false): UtilsAjaxHookResult => {
113
- if (useOldVersion) {
114
- return AjaxHooker1_2_4();
115
- } else {
116
- return ajaxHooker();
117
- }
111
+ ajaxHooker = (): UtilsAjaxHookResult => {
112
+ return ajaxHooker();
113
+ };
114
+ /**
115
+ * ajax劫持库,支持xhr和fetch劫持。
116
+ * + 来源: https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
117
+ * + 作者: cxxjackie
118
+ * + 实现方式: Object.defineProperty
119
+ * + 版本: `1.2.4`
120
+ * + 文档: https://scriptcat.org/zh-CN/script-show-page/637/
121
+ */
122
+ oldAjaxHooker = (): UtilsAjaxHookResult => {
123
+ return AjaxHooker1_2_4();
118
124
  };
119
125
  /**
120
126
  * 根据坐标点击canvas元素的内部位置
@@ -2207,26 +2213,14 @@ class Utils {
2207
2213
  */
2208
2214
  config?: MutationObserverInit;
2209
2215
  /**
2210
- * 是否主动触发一次
2216
+ * (可选)是否主动触发一次
2211
2217
  */
2212
2218
  immediate?: boolean;
2213
2219
  /**
2214
- * 触发的回调函数
2220
+ * (可选)是否仅触发一次
2221
+ * @default false
2215
2222
  */
2216
- callback: MutationCallback;
2217
- }
2218
- ): MutationObserver;
2219
- mutationObserver(
2220
- target: HTMLElement | Node | NodeList | Document,
2221
- observer_config: {
2222
- /**
2223
- * observer的配置
2224
- */
2225
- config?: MutationObserverInit;
2226
- /**
2227
- * 是否主动触发一次
2228
- */
2229
- immediate?: boolean;
2223
+ once?: boolean;
2230
2224
  /**
2231
2225
  * 触发的回调函数
2232
2226
  */
@@ -2275,6 +2269,7 @@ class Utils {
2275
2269
  characterDataOldValue: void 0 as any as boolean,
2276
2270
  },
2277
2271
  immediate: false,
2272
+ once: false,
2278
2273
  };
2279
2274
  observer_config = that.assign(default_obverser_config, observer_config);
2280
2275
  const windowMutationObserver =
@@ -2282,13 +2277,20 @@ class Utils {
2282
2277
  (this.windowApi.window as any).webkitMutationObserver ||
2283
2278
  (this.windowApi.window as any).MozMutationObserver;
2284
2279
  // 观察者对象
2280
+ const handler = (mutations: MutationRecord[], observer: MutationObserver) => {
2281
+ if (observer_config.once) {
2282
+ // 仅触发一次
2283
+ observer.disconnect();
2284
+ }
2285
+ if (typeof observer_config.callback === "function") {
2286
+ observer_config.callback(mutations, observer);
2287
+ }
2288
+ };
2285
2289
  const mutationObserver = new windowMutationObserver(function (
2286
2290
  mutations: MutationRecord[],
2287
2291
  observer: MutationObserver
2288
2292
  ) {
2289
- if (typeof observer_config.callback === "function") {
2290
- observer_config.callback(mutations, observer);
2291
- }
2293
+ handler(mutations, observer);
2292
2294
  });
2293
2295
 
2294
2296
  if (Array.isArray(target) || target instanceof NodeList) {
@@ -2297,7 +2299,7 @@ class Utils {
2297
2299
  mutationObserver.observe(item, observer_config.config);
2298
2300
  });
2299
2301
  } else if (that.isJQuery(target)) {
2300
- /* 传入的参数是jQuery对象 */
2302
+ // 传入的参数是jQuery对象
2301
2303
  (target as any).each((_: any, item: any) => {
2302
2304
  mutationObserver.observe(item, observer_config.config);
2303
2305
  });
@@ -2305,16 +2307,14 @@ class Utils {
2305
2307
  mutationObserver.observe(target, observer_config.config);
2306
2308
  }
2307
2309
  if (observer_config.immediate) {
2308
- /* 主动触发一次 */
2309
- if (typeof observer_config.callback === "function") {
2310
- observer_config.callback([], mutationObserver);
2311
- }
2310
+ // 主动触发一次
2311
+ handler([], mutationObserver);
2312
2312
  }
2313
2313
  return mutationObserver;
2314
2314
  }
2315
2315
  /**
2316
2316
  * 使用观察器观察元素出现在视图内,出现的话触发回调
2317
- * @param target 目标元素
2317
+ * @param $el 目标元素
2318
2318
  * @param callback 触发的回调
2319
2319
  * @param options 观察器配置
2320
2320
  * @example
@@ -2323,36 +2323,54 @@ class Utils {
2323
2323
  * }))
2324
2324
  */
2325
2325
  mutationVisible(
2326
- target: Element | Element[],
2326
+ $el: Element | Element[],
2327
2327
  callback: (entries: IntersectionObserverEntry[], observer: IntersectionObserver) => void,
2328
- options?: IntersectionObserverInit
2328
+ options?: IntersectionObserverInit & {
2329
+ /** (可选)是否主动触发一次,默认false */
2330
+ immediate?: boolean;
2331
+ /** (可选)是否仅触发一次,默认false */
2332
+ once?: boolean;
2333
+ }
2329
2334
  ) {
2330
2335
  if (typeof IntersectionObserver === "undefined") {
2331
2336
  throw new TypeError("IntersectionObserver is not defined");
2332
2337
  }
2333
- if (target == null) {
2338
+ if ($el == null) {
2334
2339
  throw new TypeError("mutatuinVisible target is null");
2335
2340
  }
2341
+ options = options || {};
2336
2342
  let defaultOptions: IntersectionObserverInit = {
2337
2343
  root: null,
2338
2344
  rootMargin: "0px 0px 0px 0px",
2339
2345
  threshold: [0.01, 0.99],
2340
2346
  };
2341
- defaultOptions = this.assign(defaultOptions, options || {});
2347
+ defaultOptions = this.assign(defaultOptions, options);
2348
+ const handler = (entries: IntersectionObserverEntry[], observer: IntersectionObserver) => {
2349
+ if (options.once) {
2350
+ // 仅触发一次
2351
+ observer.disconnect();
2352
+ }
2353
+ if (typeof callback === "function") {
2354
+ callback(entries, observer);
2355
+ }
2356
+ };
2342
2357
  const intersectionObserver = new IntersectionObserver((entries, observer) => {
2343
2358
  if (entries[0].isIntersecting) {
2344
- if (typeof callback === "function") {
2345
- callback(entries, observer);
2346
- }
2359
+ handler(entries, observer);
2347
2360
  }
2348
2361
  }, defaultOptions);
2349
- if (Array.isArray(target)) {
2350
- target.forEach((item) => {
2351
- intersectionObserver.observe(item);
2362
+ if (Array.isArray($el)) {
2363
+ $el.forEach(($elItem) => {
2364
+ intersectionObserver.observe($elItem);
2352
2365
  });
2353
2366
  } else {
2354
- intersectionObserver.observe(target);
2367
+ intersectionObserver.observe($el);
2368
+ }
2369
+ if (options.immediate) {
2370
+ // 立即触发
2371
+ handler([], intersectionObserver);
2355
2372
  }
2373
+ return intersectionObserver;
2356
2374
  }
2357
2375
  /**
2358
2376
  * 去除全局window下的Utils,返回控制权
@@ -3438,12 +3456,26 @@ class Utils {
3438
3456
  }
3439
3457
  /**
3440
3458
  * 将UrlSearchParams格式的字符串转为对象
3459
+ * @param searhParamsStr 字符串或对象
3460
+ * @example
3461
+ * Utils.searchParamStrToObj("xxx=xx&xx2=xx2")
3462
+ * @example
3463
+ * Utils.searchParamStrToObj(new URLSearchParams({
3464
+ * test1: 1,
3465
+ * test2: 2
3466
+ * }))
3441
3467
  */
3442
- searchParamStrToObj<T>(searhParamsStr?: string | null | undefined): T {
3443
- if (typeof searhParamsStr !== "string") {
3444
- return {} as any as T;
3445
- }
3446
- return Object.fromEntries(new URLSearchParams(searhParamsStr) as any) as T;
3468
+ searchParamStrToObj<T = any>(searhParamsStr?: string | null | undefined | URLSearchParams): T {
3469
+ const params = {};
3470
+ if (searhParamsStr == null) {
3471
+ return params as T;
3472
+ }
3473
+ const urlSearchParams =
3474
+ searhParamsStr instanceof URLSearchParams ? searhParamsStr : new URLSearchParams(searhParamsStr);
3475
+ urlSearchParams.forEach((value, key) => {
3476
+ Reflect.set(params, key, value);
3477
+ });
3478
+ return params as T;
3447
3479
  }
3448
3480
  /**
3449
3481
  * 提供一个封装了 try-catch 的函数,可以执行传入的函数并捕获其可能抛出的错误,并通过传入的错误处理函数进行处理。
@@ -132,8 +132,12 @@ export const ajaxHooker = function () {
132
132
  );
133
133
  }
134
134
  waitForRequestKeys() {
135
+ /**
136
+ * @type {Set<typeof hookInst>}
137
+ */
138
+ const winHookInsts = win.__ajaxHooker.hookInsts;
135
139
  if (!this.request.async) {
136
- win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
140
+ winHookInsts.forEach(({ hookFns, filters }) => {
137
141
  if (this.shouldFilter(filters)) return;
138
142
  hookFns.forEach((fn) => {
139
143
  if (getType(fn) === "[object Function]")
@@ -147,10 +151,10 @@ export const ajaxHooker = function () {
147
151
  }
148
152
  const promises = [];
149
153
  const ignoreKeys = new Set(["type", "async", "response"]);
150
- win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
154
+ winHookInsts.forEach(({ hookFns, filters }) => {
151
155
  if (this.shouldFilter(filters)) return;
152
156
  promises.push(
153
- Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(
157
+ Promise.all(hookFns.map((fn,index) => catchError(fn, this.request, index))).then(
154
158
  () => {
155
159
  const requestKeys = [];
156
160
  for (const key in this.request)
@@ -594,10 +598,54 @@ export const ajaxHooker = function () {
594
598
  });
595
599
  });
596
600
  }
601
+
602
+ /**
603
+ *
604
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeHook"]}
605
+ */
606
+ const removeHook = (fn, onlyRemove = false) => {
607
+ let flag = false;
608
+ for (let index = hookInst.hookFns.length-1; index >=0; index--) {
609
+ const __fn__ = hookInst.hookFns[index];
610
+ if(fn === __fn__){
611
+ hookInst.hookFns.splice(index, 1);
612
+ flag = true;
613
+ if(onlyRemove){
614
+ break;
615
+ }
616
+ }
617
+ }
618
+ return flag;
619
+ }
620
+
621
+ /**
622
+ *
623
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeFilter"]}
624
+ */
625
+ const removeFilter = ()=>{
626
+ if(Array.isArray(hookInst.filters)){
627
+ hookInst.filters.length = 0;
628
+ }else{
629
+ hookInst.filters = [];
630
+ }
631
+ }
632
+
597
633
  return {
598
- hook: (fn) => hookInst.hookFns.push(fn),
634
+ hook: (fn) => {
635
+ hookInst.hookFns.push(fn);
636
+ return {
637
+ remove: () => {
638
+ return removeHook(fn, true);
639
+ }
640
+ }
641
+ },
599
642
  filter: (arr) => {
600
- if (Array.isArray(arr)) hookInst.filters = arr;
643
+ if (Array.isArray(arr)) {
644
+ hookInst.filters = arr;
645
+ }
646
+ return {
647
+ remove: removeFilter
648
+ }
601
649
  },
602
650
  protect: () => {
603
651
  readonly(win, "XMLHttpRequest", winAh.fakeXHR);
@@ -613,5 +661,7 @@ export const ajaxHooker = function () {
613
661
  delete win.__ajaxHooker;
614
662
  }
615
663
  },
664
+ removeHook: removeHook,
665
+ removeFilter: removeFilter
616
666
  };
617
667
  };
@@ -431,19 +431,63 @@ export const AjaxHooker1_2_4 = function () {
431
431
  Object.keys(realXhr).forEach((key) => (fakeXhr[key] = realXhr[key]));
432
432
  fakeXhr.prototype = realXhr.prototype;
433
433
  win.fetch = fakeFetch;
434
- return {
435
- hook: (fn) => hookFns.push(fn),
436
- filter: (arr) => {
437
- filter = Array.isArray(arr) && arr.map(toFilterObj);
438
- },
439
- protect: () => {
440
- readonly(win, "XMLHttpRequest", fakeXhr);
441
- readonly(win, "fetch", fakeFetch);
442
- },
443
- unhook: () => {
444
- writable(win, "XMLHttpRequest", realXhr);
445
- writable(win, "fetch", realFetch);
446
- },
447
- };
434
+
435
+ /**
436
+ *
437
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeHook"]}
438
+ */
439
+ const removeHook = (fn, onlyRemove = false) => {
440
+ let flag = false;
441
+ for (let index = hookFns.length-1; index >=0; index--) {
442
+ const __fn__ = hookFns[index];
443
+ if(fn === __fn__){
444
+ hookFns.splice(index, 1);
445
+ flag = true;
446
+ if(onlyRemove){
447
+ break;
448
+ }
449
+ }
450
+ }
451
+ return flag;
452
+ }
453
+
454
+ /**
455
+ *
456
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeFilter"]}
457
+ */
458
+ const removeFilter = ()=>{
459
+ if(Array.isArray(filter)){
460
+ filter.length = 0;
461
+ }else{
462
+ filter = void 0;
463
+ }
464
+ }
465
+
466
+ return {
467
+ hook: (fn) => {
468
+ hookFns.push(fn);
469
+ return {
470
+ remove: () => {
471
+ return removeHook(fn, true);
472
+ }
473
+ }
474
+ },
475
+ filter: (arr) => {
476
+ filter = Array.isArray(arr) && arr.map(toFilterObj);
477
+ return {
478
+ remove: removeFilter
479
+ }
480
+ },
481
+ protect: () => {
482
+ readonly(win, "XMLHttpRequest", fakeXhr);
483
+ readonly(win, "fetch", fakeFetch);
484
+ },
485
+ unhook: () => {
486
+ writable(win, "XMLHttpRequest", realXhr);
487
+ writable(win, "fetch", realFetch);
488
+ },
489
+ removeHook: removeHook,
490
+ removeFilter: removeFilter
491
+ };
448
492
  })();
449
493
  };
@@ -1052,30 +1052,30 @@ export declare interface HttpxRequestOption {
1052
1052
  */
1053
1053
  data?: string | FormData | object;
1054
1054
  /**
1055
- * 是否自动对data进行处理
1055
+ * 是否自动对`data`进行处理
1056
1056
  *
1057
1057
  * ## 处理以下请求类型
1058
- * + `GET` 自动进行`URLSearchParams`转换
1059
- * + `HEAD` 自动进行`URLSearchParams`转换
1060
- * + `POST` 处理`Content-Type`不为空的情况
1058
+ * + 当请求类型为`GET`,自动进行`URLSearchParams`转换
1059
+ * + 当请求类型为`HEAD`,自动进行`URLSearchParams`转换
1060
+ * + 当请求类型为`POST`,根据下面的`Content-Type`类型来处理(`Content-Type`不为空才会处理)
1061
1061
  *
1062
- * ### `application/json`
1062
+ * ### `POST` => `Content-Type` => `application/json`
1063
1063
  *
1064
- * + `string`: 不做处理
1065
- * + `FormData`: 转为`JSON`并进行`JSON.stringify`处理
1066
- * + `object`: 进行`JSON.stringify`处理
1064
+ * + `data: string`: ignore
1065
+ * + `data: object`: 进行`JSON.stringify`处理
1066
+ * + `data: FormData`: 转为`JSON`并进行`JSON.stringify`处理
1067
1067
  *
1068
- * ### `application/x-www-form-urlencoded`
1068
+ * ### `POST` => `Content-Type` => `application/x-www-form-urlencoded`
1069
1069
  *
1070
- * + `string`: 不做处理
1071
- * + `FormData`: 转为`URLSearchParams`,再转为`string`
1072
- * + `object`: 转为`URLSearchParams`,再转为`string`
1070
+ * + `data: string`: ignore
1071
+ * + `data: object`: 转为`URLSearchParams`,再转为`string`
1072
+ * + `data: FormData`: 转为`URLSearchParams`,再转为`string`
1073
1073
  *
1074
- * ### `multipart/form-data`(上传文件专用)
1074
+ * ### `POST` => `Content-Type` => `multipart/form-data`(上传文件专用)
1075
1075
  *
1076
- * + `string`: 不做处理
1077
- * + `FormData`: 移除`Content-Type`
1078
- * + `object`: 不做处理
1076
+ * + `data: string`: ignore
1077
+ * + `data: object`: ignore
1078
+ * + `data: FormData`: 移除`Content-Type`
1079
1079
  * @default true
1080
1080
  */
1081
1081
  processData?: boolean;
@@ -89,67 +89,103 @@ export declare interface UtilsAjaxHookFilterOptions {
89
89
  /** Utils.ajaxHooker */
90
90
  export declare interface UtilsAjaxHookResult {
91
91
  /**
92
- * 劫持xhr和fetch
93
- *
94
- * 提示:如果多次调用.hook方法,将会多次处理同一个请求
95
- * @example
96
- ajaxHooker.hook(request => {
97
- if (request.url === 'https://www.example.com/') {
98
- request.response = res => {
99
- console.log(res);
100
- res.responseText += 'test';
101
- };
102
- }
103
- });
104
- * @example
105
- // 异步特性无法作用于同步请求,但同步修改仍然有效
106
- // 你可以将以上所有可修改属性赋值为Promise,原请求将被阻塞直至Promise完成(若发生reject,数据将不会被修改)
107
- // 此特性可用于异步劫持。以下是一个异步修改响应数据的例子
108
- ajaxHooker.hook(request => {
109
- request.response = res => {
110
- const responseText = res.responseText; // 注意保存原数据
111
- res.responseText = new Promise(resolve => {
112
- setTimeout(() => {
113
- resolve(responseText + 'test');
114
- }, 3000);
115
- });
116
- };
117
- });
118
-
119
- // 也可以传入async回调函数以实现异步
120
- ajaxHooker.hook(async request => {
121
- request.data = await modifyData(request.data);
122
- request.response = async res => {
123
- res.responseText = await modifyResponse(res.responseText);
124
- };
125
- });
126
- */
92
+ * 劫持xhr和fetch
93
+ *
94
+ * 提示:如果多次调用.hook方法,将会多次处理同一个请求
95
+ * @example
96
+ * ajaxHooker.hook(request => {
97
+ * if (request.url === 'https://www.example.com/') {
98
+ * request.response = res => {
99
+ * console.log(res);
100
+ * res.responseText += 'test';
101
+ * };
102
+ * }
103
+ * });
104
+ * * @example
105
+ * // 异步特性无法作用于同步请求,但同步修改仍然有效
106
+ * // 你可以将以上所有可修改属性赋值为Promise,原请求将被阻塞直至Promise完成(若发生reject,数据将不会被修改)
107
+ * // 此特性可用于异步劫持。以下是一个异步修改响应数据的例子
108
+ * ajaxHooker.hook(request => {
109
+ * request.response = res => {
110
+ * const responseText = res.responseText; // 注意保存原数据
111
+ * res.responseText = new Promise(resolve => {
112
+ * setTimeout(() => {
113
+ * resolve(responseText + 'test');
114
+ * }, 3000);
115
+ * });
116
+ * };
117
+ * });
118
+ * // 也可以传入async回调函数以实现异步
119
+ * ajaxHooker.hook(async request => {
120
+ * request.data = await modifyData(request.data);
121
+ * request.response = async res => {
122
+ * res.responseText = await modifyResponse(res.responseText);
123
+ * };
124
+ * });
125
+ */
127
126
  hook(
128
- callback: (request: UtilsAjaxHookRequestOptions) => void | undefined | null | Promise<void | undefined | null>
129
- ): void;
130
- /**
131
- * 过滤
132
- * @example
133
- // 应于hook方法之前执行,此方法若尽早执行,有助于提升性能。
134
- // 为hook方法设置过滤规则,只有符合规则的请求才会触发hook。过滤规则是一个对象数组,参考下例
135
- ajaxHooker.filter([
136
- {type: 'xhr', url: 'www.example.com', method: 'GET', async: true},
137
- {url: /^http/},
138
- ]);
127
+ callback: (
128
+ /**
129
+ * hook请求的配置
130
+ */
131
+ request: UtilsAjaxHookRequestOptions,
132
+ /**
133
+ * 当前的`callback`的索引下标
134
+ */
135
+ index: number
136
+ ) => void | undefined | null | Promise<void | undefined | null>
137
+ ): {
138
+ /**
139
+ * 该函数是额外添加的,原版仅返回空值
139
140
  */
140
- filter(filterOptions: UtilsAjaxHookFilterOptions[]): void;
141
+ remove: () => boolean;
142
+ };
141
143
  /**
142
- * 阻止xhr和fetch被改写
143
- * @example
144
- // 如果库劫持失败,可能是其他代码对xhr/fetch进行了二次劫持,protect方法会尝试阻止xhr和fetch被改写。应于document-start阶段尽早执行,部分网页下可能引发错误,谨慎使用。
145
- ajaxHooker.protect();
144
+ * 过滤
145
+ *
146
+ * 注意:重复调用`.filter`设置规则会覆盖之前设置的规则
147
+ * @example
148
+ * // 应于hook方法之前执行,此方法若尽早执行,有助于提升性能。
149
+ * // 为hook方法设置过滤规则,只有符合规则的请求才会触发hook。过滤规则是一个对象数组,参考下例
150
+ * ajaxHooker.filter([
151
+ * {type: 'xhr', url: 'www.example.com', method: 'GET', async: true},
152
+ * {url: /^http/},
153
+ * ]);
154
+ */
155
+ filter(filterOptions: UtilsAjaxHookFilterOptions[]): {
156
+ /**
157
+ * 该函数是额外添加的,原版仅返回空值
146
158
  */
159
+ remove: () => void;
160
+ };
161
+ /**
162
+ * 阻止xhr和fetch被改写
163
+ * @example
164
+ * // 如果库劫持失败,可能是其他代码对xhr/fetch进行了二次劫持,protect方法会尝试阻止xhr和fetch被改写。应于document-start阶段尽早执行,部分网页下可能引发错误,谨慎使用。
165
+ * ajaxHooker.protect();
166
+ */
147
167
  protect(): void;
148
168
  /**
149
- * 取消劫持
150
- * @example
151
- // 将xhr和fetch恢复至劫持前的状态,调用此方法后,hook方法不再生效。
152
- ajaxHooker.unhook();
153
- */
169
+ * 取消劫持
170
+ * @example
171
+ * // 将xhr和fetch恢复至劫持前的状态,调用此方法后,hook方法不再生效。
172
+ * ajaxHooker.unhook();
173
+ */
154
174
  unhook(): void;
175
+ /**
176
+ * 移除通过`.hook`添加的函数
177
+ *
178
+ * @description 此函数为额外添加的增强函数
179
+ * @param fn `.hook`添加的函数
180
+ * @param onlyRemove (可选)是否仅移除一个(如果命中的话),默认false
181
+ */
182
+ removeHook(
183
+ fn: (request: UtilsAjaxHookRequestOptions) => void | undefined | null | Promise<void | undefined | null>,
184
+ onlyRemove: boolean
185
+ ): boolean;
186
+ /**
187
+ * 重置通过`.filter`设置的规则
188
+ * @description 此函数为额外添加的增强函数
189
+ */
190
+ removeFilter(): void;
155
191
  }