@whitesev/utils 2.5.7 → 2.5.8

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.
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Main moduleRaid class
3
+ * @link https://scriptcat.org/zh-CN/script-show-page/2628
4
+ */
5
+ export class ModuleRaid {
6
+ /**
7
+ * moduleRaid constructor
8
+ *
9
+ * @example
10
+ * Constructing an instance without any arguments:
11
+ * ```ts
12
+ * const mR = new ModuleRaid()
13
+ * ```
14
+ *
15
+ * Constructing an instance with the optional `opts` object:
16
+ * ```ts
17
+ * const mR = new ModuleRaid({ entrypoint: 'webpackChunk_custom_name' })
18
+ * ```
19
+ *
20
+ * @param opts a object containing options to initialize moduleRaid with
21
+ * - **opts:**
22
+ * - _target_: the window object being searched for
23
+ * - _entrypoint_: the Webpack entrypoint present on the global window object
24
+ * - _debug_: whether debug mode is enabled or not
25
+ * - _strict_: whether strict mode is enabled or not
26
+ */
27
+ constructor(opts: any);
28
+ /**
29
+ * A random generated module ID we use for injecting into Webpack
30
+ */
31
+ moduleID: string;
32
+ /**
33
+ * An array containing different argument injection methods for
34
+ * Webpack (before version 4), and subsequently pulling out methods and modules
35
+ * @internal
36
+ */
37
+ functionArguments: ((number[] | ((_e: any, _t: any, i: any) => void)[])[] | (number[] | string[][] | {
38
+ [x: string]: (_e: any, _t: any, i: any) => void;
39
+ })[])[];
40
+ modules: {};
41
+ constructors: any[];
42
+ get: any;
43
+ /**
44
+ * An array containing different argument injection methods for
45
+ * Webpack (after version 4), and subsequently pulling out methods and modules
46
+ * @internal
47
+ */
48
+ arrayArguments: ((number[] | ((_e: any, _t: any, i: any) => void)[])[] | {}[] | (number[] | string[][] | {
49
+ [x: string]: (_e: any, _t: any, i: any) => void;
50
+ })[])[];
51
+ target: Window & typeof globalThis;
52
+ entrypoint: string;
53
+ debug: boolean;
54
+ strict: boolean;
55
+ /**
56
+ * Debug logging method, outputs to the console when {@link ModuleRaid.debug} is true
57
+ *
58
+ * @param {*} message The message to be logged
59
+ * @internal
60
+ */
61
+ log(message: any): void;
62
+ /**
63
+ * Method to set an alternative getter if we weren't able to extract __webpack_require__
64
+ * from Webpack
65
+ * @internal
66
+ */
67
+ replaceGet(): void;
68
+ /**
69
+ * Method that will try to inject a module into Webpack or get modules
70
+ * depending on it's success it might be more or less brute about it
71
+ * @internal
72
+ */
73
+ fillModules(): void;
74
+ /**
75
+ * Method to hook into `window[this.entrypoint].push` adding a listener for new
76
+ * chunks being pushed into Webpack
77
+ *
78
+ * @example
79
+ * You can listen for newly pushed packages using the `moduleraid:webpack-push` event
80
+ * on `document`
81
+ *
82
+ * ```ts
83
+ * document.addEventListener('moduleraid:webpack-push', (e) => {
84
+ * // e.detail contains the arguments push() was called with
85
+ * console.log(e.detail)
86
+ * })
87
+ * ```
88
+ * @internal
89
+ */
90
+ setupPushEvent(): void;
91
+ /**
92
+ * Method to try autodetecting a Webpack JSONP entrypoint based on common naming
93
+ *
94
+ * If the default entrypoint, or the entrypoint that's passed to the moduleRaid constructor
95
+ * already matches, the method exits early
96
+ *
97
+ * If `options.strict` has been set in the constructor and the initial entrypoint cannot
98
+ * be found, this method will error, demanding a strictly set entrypoint
99
+ * @internal
100
+ */
101
+ detectEntrypoint(): void;
102
+ /**
103
+ * Recursive object-search function for modules
104
+ *
105
+ * @param object the object to search through
106
+ * @param query the query the object keys/values are searched for
107
+ * @returns boolean state of `object` containing `query` somewhere in it
108
+ * @internal
109
+ */
110
+ searchObject(object: any, query: any): boolean;
111
+ /**
112
+ * Method to search through the module object, searching for the fitting content
113
+ * if a string is supplied
114
+ *
115
+ * If query is supplied as a function, everything that returns true when passed
116
+ * to the query function will be returned
117
+ *
118
+ * @example
119
+ * With a string as query argument:
120
+ * ```ts
121
+ * const results = mR.findModule('feature')
122
+ * // => Array of module results
123
+ * ```
124
+ *
125
+ * With a function as query argument:
126
+ * ```ts
127
+ * const results = mR.findModule((module) => { typeof module === 'function' })
128
+ * // => Array of module results
129
+ * ```
130
+ *
131
+ * @param query query to search the module list for
132
+ * @return a list of modules fitting the query
133
+ */
134
+ findModule(query: any): any[];
135
+ /**
136
+ * Method to search through the constructor array, searching for the fitting content
137
+ * if a string is supplied
138
+ *
139
+ * If query is supplied as a function, everything that returns true when passed
140
+ * to the query function will be returned
141
+ *
142
+ * @example
143
+ * With a string as query argument:
144
+ * ```ts
145
+ * const results = mR.findConstructor('feature')
146
+ * // => Array of constructor/module tuples
147
+ * ```
148
+ *
149
+ * With a function as query argument:
150
+ * ```ts
151
+ * const results = mR.findConstructor((constructor) => { constructor.prototype.value !== undefined })
152
+ * // => Array of constructor/module tuples
153
+ * ```
154
+ *
155
+ * Accessing the resulting data:
156
+ * ```ts
157
+ * // With array destructuring (ES6)
158
+ * const [constructor, module] = results[0]
159
+ *
160
+ * // ...or...
161
+ *
162
+ * // regular access
163
+ * const constructor = results[0][0]
164
+ * const module = results[0][1]
165
+ * ```
166
+ *
167
+ * @param query query to search the constructor list for
168
+ * @returns a list of constructor/module tuples fitting the query
169
+ */
170
+ findConstructor(query: any): any[];
171
+ }
@@ -5,12 +5,12 @@ export declare const TryCatch: (...args: any) => {
5
5
  * @param paramDetails 配置
6
6
  * @returns
7
7
  */
8
- config(paramDetails: UtilsTryCatchConfig): any;
8
+ config(paramDetails: UtilsTryCatchConfig): /*elided*/ any;
9
9
  /**
10
10
  * 处理错误
11
11
  * @param handler
12
12
  */
13
- error(handler: ((...args: any[]) => any) | string | Function): any;
13
+ error(handler: ((...args: any[]) => any) | string | Function): /*elided*/ any;
14
14
  /**
15
15
  * 执行传入的函数并捕获其可能抛出的错误,并通过传入的错误处理函数进行处理。
16
16
  * @param callback 待执行函数,可以是 function 或者 string 类型。如果是 string 类型,则会被当做代码进行执行。
@@ -14,6 +14,7 @@ import type { UtilsAjaxHookResult } from "./types/ajaxHooker";
14
14
  import { Vue } from "./Vue";
15
15
  import { type ArgsType, type JSTypeNames, type UtilsOwnObject } from "./types/global";
16
16
  import type { WindowApiOption } from "./types/WindowApi";
17
+ import { ModuleRaid } from "./ModuleRaid";
17
18
  declare class Utils {
18
19
  private windowApi;
19
20
  constructor(option?: WindowApiOption);
@@ -1382,8 +1383,8 @@ declare class Utils {
1382
1383
  * > ()=>{throw new Error('测试错误')}出现错误
1383
1384
  */
1384
1385
  tryCatch: (...args: any) => {
1385
- config(paramDetails: import("./types/TryCatch").UtilsTryCatchConfig): any;
1386
- error(handler: ((...args: any[]) => any) | string | Function): any;
1386
+ config(paramDetails: import("./types/TryCatch").UtilsTryCatchConfig): /*elided*/ any;
1387
+ error(handler: ((...args: any[]) => any) | string | Function): /*elided*/ any;
1387
1388
  run<A extends any[], R>(callback: ((...args: A) => R) | string | Function, __context__?: any): import("./types/TryCatch").UtilsTryCatchType;
1388
1389
  };
1389
1390
  /**
@@ -1815,6 +1816,7 @@ declare class Utils {
1815
1816
  * > "测试"
1816
1817
  */
1817
1818
  Vue: typeof Vue;
1819
+ ModuleRaid: typeof ModuleRaid;
1818
1820
  }
1819
1821
  declare let utils: Utils;
1820
1822
  export { utils as Utils };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whitesev/utils",
3
- "version": "2.5.7",
3
+ "version": "2.5.8",
4
4
  "description": "一个常用的工具库",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
@@ -0,0 +1,397 @@
1
+ // ==UserScript==
2
+ // @name ModuleRaid.js
3
+ // @namespace http://tampermonkey.net/
4
+ // @version 6.2.0
5
+ // @description 检索调用webpackJsonp模块,可指定检索的window
6
+ // @author empyrealtear
7
+ // @license MIT
8
+ // @original-script https://github.com/pixeldesu/moduleRaid
9
+ // ==/UserScript==
10
+
11
+
12
+ /**
13
+ * Main moduleRaid class
14
+ * @link https://scriptcat.org/zh-CN/script-show-page/2628
15
+ */
16
+ export class ModuleRaid {
17
+ /**
18
+ * moduleRaid constructor
19
+ *
20
+ * @example
21
+ * Constructing an instance without any arguments:
22
+ * ```ts
23
+ * const mR = new ModuleRaid()
24
+ * ```
25
+ *
26
+ * Constructing an instance with the optional `opts` object:
27
+ * ```ts
28
+ * const mR = new ModuleRaid({ entrypoint: 'webpackChunk_custom_name' })
29
+ * ```
30
+ *
31
+ * @param opts a object containing options to initialize moduleRaid with
32
+ * - **opts:**
33
+ * - _target_: the window object being searched for
34
+ * - _entrypoint_: the Webpack entrypoint present on the global window object
35
+ * - _debug_: whether debug mode is enabled or not
36
+ * - _strict_: whether strict mode is enabled or not
37
+ */
38
+ constructor(opts) {
39
+ /**
40
+ * A random generated module ID we use for injecting into Webpack
41
+ */
42
+ this.moduleID = Math.random().toString(36).substring(7);
43
+ /**
44
+ * An array containing different argument injection methods for
45
+ * Webpack (before version 4), and subsequently pulling out methods and modules
46
+ * @internal
47
+ */
48
+ this.functionArguments = [
49
+ [
50
+ [0],
51
+ [
52
+ (_e, _t, i) => {
53
+ this.modules = i.c;
54
+ this.constructors = i.m;
55
+ this.get = i;
56
+ },
57
+ ],
58
+ ],
59
+ [
60
+ [1e3],
61
+ {
62
+ [this.moduleID]: (_e, _t, i) => {
63
+ this.modules = i.c;
64
+ this.constructors = i.m;
65
+ this.get = i;
66
+ },
67
+ },
68
+ [[this.moduleID]],
69
+ ],
70
+ ];
71
+ /**
72
+ * An array containing different argument injection methods for
73
+ * Webpack (after version 4), and subsequently pulling out methods and modules
74
+ * @internal
75
+ */
76
+ this.arrayArguments = [
77
+ [
78
+ [this.moduleID],
79
+ {},
80
+ (e) => {
81
+ const mCac = e.m;
82
+ Object.keys(mCac).forEach((mod) => {
83
+ try {
84
+ this.modules[mod] = e(mod);
85
+ }
86
+ catch (err) {
87
+ this.log(`[arrayArguments/1] Failed to require(${mod}) with error:\n${err}\n${err.stack}`);
88
+ }
89
+ });
90
+ this.get = e;
91
+ },
92
+ ],
93
+ this.functionArguments[1],
94
+ ];
95
+ /**
96
+ * Storage for the modules we extracted from Webpack
97
+ */
98
+ this.modules = {};
99
+ /**
100
+ * Storage for the constructors we extracted from Webpack
101
+ */
102
+ this.constructors = [];
103
+ let options = {
104
+ target: window,
105
+ entrypoint: 'webpackJsonp',
106
+ debug: false,
107
+ strict: false,
108
+ };
109
+ if (typeof opts === 'object') {
110
+ options = Object.assign(Object.assign({}, options), opts);
111
+ }
112
+ this.target = options.target
113
+ this.entrypoint = options.entrypoint;
114
+ this.debug = options.debug;
115
+ this.strict = options.strict;
116
+ this.detectEntrypoint();
117
+ this.fillModules();
118
+ this.replaceGet();
119
+ this.setupPushEvent();
120
+ }
121
+ /**
122
+ * Debug logging method, outputs to the console when {@link ModuleRaid.debug} is true
123
+ *
124
+ * @param {*} message The message to be logged
125
+ * @internal
126
+ */
127
+ log(message) {
128
+ if (this.debug) {
129
+ console.warn(`[moduleRaid] ${message}`);
130
+ }
131
+ }
132
+ /**
133
+ * Method to set an alternative getter if we weren't able to extract __webpack_require__
134
+ * from Webpack
135
+ * @internal
136
+ */
137
+ replaceGet() {
138
+ if (this.get === null) {
139
+ this.get = (key) => this.modules[key];
140
+ }
141
+ }
142
+ /**
143
+ * Method that will try to inject a module into Webpack or get modules
144
+ * depending on it's success it might be more or less brute about it
145
+ * @internal
146
+ */
147
+ fillModules() {
148
+ if (typeof this.target[this.entrypoint] === 'function') {
149
+ this.functionArguments.forEach((argument, index) => {
150
+ try {
151
+ if (this.modules && Object.keys(this.modules).length > 0)
152
+ return;
153
+ this.target[this.entrypoint](...argument);
154
+ }
155
+ catch (err) {
156
+ this.log(`moduleRaid.functionArguments[${index}] failed:\n${err}\n${err.stack}`);
157
+ }
158
+ });
159
+ }
160
+ else {
161
+ this.arrayArguments.forEach((argument, index) => {
162
+ try {
163
+ if (this.modules && Object.keys(this.modules).length > 0)
164
+ return;
165
+ this.target[this.entrypoint].push(argument);
166
+ }
167
+ catch (err) {
168
+ this.log(`Pushing moduleRaid.arrayArguments[${index}] into ${this.entrypoint} failed:\n${err}\n${err.stack}`);
169
+ }
170
+ });
171
+ }
172
+ if (this.modules && Object.keys(this.modules).length == 0) {
173
+ let moduleEnd = false;
174
+ let moduleIterator = 0;
175
+ if (typeof this.target[this.entrypoint] != 'function' || !this.target[this.entrypoint]([], [], [moduleIterator])) {
176
+ throw Error('Unknown Webpack structure');
177
+ }
178
+ while (!moduleEnd) {
179
+ try {
180
+ this.modules[moduleIterator] = this.target[this.entrypoint]([], [], [moduleIterator]);
181
+ moduleIterator++;
182
+ }
183
+ catch (err) {
184
+ moduleEnd = true;
185
+ }
186
+ }
187
+ }
188
+ }
189
+ /**
190
+ * Method to hook into `window[this.entrypoint].push` adding a listener for new
191
+ * chunks being pushed into Webpack
192
+ *
193
+ * @example
194
+ * You can listen for newly pushed packages using the `moduleraid:webpack-push` event
195
+ * on `document`
196
+ *
197
+ * ```ts
198
+ * document.addEventListener('moduleraid:webpack-push', (e) => {
199
+ * // e.detail contains the arguments push() was called with
200
+ * console.log(e.detail)
201
+ * })
202
+ * ```
203
+ * @internal
204
+ */
205
+ setupPushEvent() {
206
+ const originalPush = this.target[this.entrypoint].push;
207
+ this.target[this.entrypoint].push = (...args) => {
208
+ const result = Reflect.apply(originalPush, this.target[this.entrypoint], args);
209
+ document.dispatchEvent(new CustomEvent('moduleraid:webpack-push', { detail: args }));
210
+ return result;
211
+ };
212
+ }
213
+ /**
214
+ * Method to try autodetecting a Webpack JSONP entrypoint based on common naming
215
+ *
216
+ * If the default entrypoint, or the entrypoint that's passed to the moduleRaid constructor
217
+ * already matches, the method exits early
218
+ *
219
+ * If `options.strict` has been set in the constructor and the initial entrypoint cannot
220
+ * be found, this method will error, demanding a strictly set entrypoint
221
+ * @internal
222
+ */
223
+ detectEntrypoint() {
224
+ if (this.target[this.entrypoint] != undefined) {
225
+ return;
226
+ }
227
+ if (this.strict) {
228
+ throw Error(`Strict mode is enabled and entrypoint at window.${this.entrypoint} couldn't be found. Please specify the correct one!`);
229
+ }
230
+ let windowObjects = Object.keys(this.target);
231
+ windowObjects = windowObjects
232
+ .filter((object) => object.toLowerCase().includes('chunk') || object.toLowerCase().includes('webpack'))
233
+ .filter((object) => typeof this.target[object] === 'function' || Array.isArray(this.target[object]));
234
+ if (windowObjects.length > 1) {
235
+ throw Error(`Multiple possible endpoints have been detected, please create a new moduleRaid instance with a specific one:\n${windowObjects.join(', ')}`);
236
+ }
237
+ if (windowObjects.length === 0) {
238
+ throw Error('No Webpack JSONP entrypoints could be detected');
239
+ }
240
+ this.log(`Entrypoint has been detected at window.${windowObjects[0]} and set for injection`);
241
+ this.entrypoint = windowObjects[0];
242
+ }
243
+ /**
244
+ * Recursive object-search function for modules
245
+ *
246
+ * @param object the object to search through
247
+ * @param query the query the object keys/values are searched for
248
+ * @returns boolean state of `object` containing `query` somewhere in it
249
+ * @internal
250
+ */
251
+ searchObject(object, query) {
252
+ for (const key in object) {
253
+ const value = object[key];
254
+ const lowerCaseQuery = query.toLowerCase();
255
+ if (typeof value != 'object') {
256
+ const lowerCaseKey = key.toString().toLowerCase();
257
+ if (lowerCaseKey.includes(lowerCaseQuery))
258
+ return true;
259
+ if (typeof value != 'object') {
260
+ const lowerCaseValue = value.toString().toLowerCase();
261
+ if (lowerCaseValue.includes(lowerCaseQuery))
262
+ return true;
263
+ }
264
+ else {
265
+ if (this.searchObject(value, query))
266
+ return true;
267
+ }
268
+ }
269
+ }
270
+ return false;
271
+ }
272
+ /**
273
+ * Method to search through the module object, searching for the fitting content
274
+ * if a string is supplied
275
+ *
276
+ * If query is supplied as a function, everything that returns true when passed
277
+ * to the query function will be returned
278
+ *
279
+ * @example
280
+ * With a string as query argument:
281
+ * ```ts
282
+ * const results = mR.findModule('feature')
283
+ * // => Array of module results
284
+ * ```
285
+ *
286
+ * With a function as query argument:
287
+ * ```ts
288
+ * const results = mR.findModule((module) => { typeof module === 'function' })
289
+ * // => Array of module results
290
+ * ```
291
+ *
292
+ * @param query query to search the module list for
293
+ * @return a list of modules fitting the query
294
+ */
295
+ findModule(query) {
296
+ const results = [];
297
+ const modules = Object.keys(this.modules);
298
+ if (modules.length === 0) {
299
+ throw new Error('There are no modules to search through!');
300
+ }
301
+ modules.forEach((key) => {
302
+ const module = this.modules[key.toString()];
303
+ if (module === undefined)
304
+ return;
305
+ try {
306
+ if (typeof query === 'string') {
307
+ query = query.toLowerCase();
308
+ switch (typeof module) {
309
+ case 'string':
310
+ if (module.toLowerCase().includes(query))
311
+ results.push(module);
312
+ break;
313
+ case 'function':
314
+ if (module.toString().toLowerCase().includes(query))
315
+ results.push(module);
316
+ break;
317
+ case 'object':
318
+ if (this.searchObject(module, query))
319
+ results.push(module);
320
+ break;
321
+ }
322
+ }
323
+ else if (typeof query === 'function') {
324
+ if (query(module))
325
+ results.push(module);
326
+ }
327
+ else {
328
+ throw new TypeError(`findModule can only find via string and function, ${typeof query} was passed`);
329
+ }
330
+ }
331
+ catch (err) {
332
+ this.log(`There was an error while searching through module '${key}':\n${err}\n${err.stack}`);
333
+ }
334
+ });
335
+ return results;
336
+ }
337
+ /**
338
+ * Method to search through the constructor array, searching for the fitting content
339
+ * if a string is supplied
340
+ *
341
+ * If query is supplied as a function, everything that returns true when passed
342
+ * to the query function will be returned
343
+ *
344
+ * @example
345
+ * With a string as query argument:
346
+ * ```ts
347
+ * const results = mR.findConstructor('feature')
348
+ * // => Array of constructor/module tuples
349
+ * ```
350
+ *
351
+ * With a function as query argument:
352
+ * ```ts
353
+ * const results = mR.findConstructor((constructor) => { constructor.prototype.value !== undefined })
354
+ * // => Array of constructor/module tuples
355
+ * ```
356
+ *
357
+ * Accessing the resulting data:
358
+ * ```ts
359
+ * // With array destructuring (ES6)
360
+ * const [constructor, module] = results[0]
361
+ *
362
+ * // ...or...
363
+ *
364
+ * // regular access
365
+ * const constructor = results[0][0]
366
+ * const module = results[0][1]
367
+ * ```
368
+ *
369
+ * @param query query to search the constructor list for
370
+ * @returns a list of constructor/module tuples fitting the query
371
+ */
372
+ findConstructor(query) {
373
+ const results = [];
374
+ const constructors = Object.keys(this.constructors);
375
+ if (constructors.length === 0) {
376
+ throw new Error('There are no constructors to search through!');
377
+ }
378
+ constructors.forEach((key) => {
379
+ const constructor = this.constructors[key];
380
+ try {
381
+ if (typeof query === 'string') {
382
+ query = query.toLowerCase();
383
+ if (constructor.toString().toLowerCase().includes(query))
384
+ results.push([this.constructors[key], this.modules[key]]);
385
+ }
386
+ else if (typeof query === 'function') {
387
+ if (query(constructor))
388
+ results.push([this.constructors[key], this.modules[key]]);
389
+ }
390
+ }
391
+ catch (err) {
392
+ this.log(`There was an error while searching through constructor '${key}':\n${err}\n${err.stack}`);
393
+ }
394
+ });
395
+ return results;
396
+ }
397
+ }
package/src/Utils.ts CHANGED
@@ -22,6 +22,7 @@ import {
22
22
  type UtilsOwnObject,
23
23
  } from "./types/global";
24
24
  import type { WindowApiOption } from "./types/WindowApi";
25
+ import { ModuleRaid } from "./ModuleRaid";
25
26
 
26
27
  class Utils {
27
28
  private windowApi: typeof WindowApi.prototype;
@@ -29,7 +30,7 @@ class Utils {
29
30
  this.windowApi = new WindowApi(option);
30
31
  }
31
32
  /** 版本号 */
32
- version = "2025.1.1";
33
+ version = "2025.1.11";
33
34
 
34
35
  /**
35
36
  * 在页面中增加style元素,如果html节点存在子节点,添加子节点第一个,反之,添加到html节点的子节点最后一个
@@ -5206,6 +5207,7 @@ class Utils {
5206
5207
  * > "测试"
5207
5208
  */
5208
5209
  Vue = Vue;
5210
+ ModuleRaid = ModuleRaid;
5209
5211
  }
5210
5212
 
5211
5213
  let utils = new Utils();