Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * @typedef {Object} PatchOptions
- * @property {boolean} [block] - If true, prevents the original function from being called.
- * @property {any} [value] - The value to return instead of the original function result.
- */
- /**
- * @callback PatchCallback
- * @param {Array<any>} args - The arguments passed to the function.
- * @param {Function} original - The original function being patched.
- * @returns {PatchOptions}
- */
- /**
- * @typedef {Object} ReturnedPatch
- * @property {function} original - The original function before patching.
- * @property {function} restore - Restores the original function.
- */
- /**
- * Monkey-patches a function with a Proxy in a given context.
- *
- * @param {string} name - The name of the function.
- * @param {boolean} isConstructor - Whether the target is a constructor.
- * @param {PatchCallback} callback
- * @param {Object} [context=window] - The context in which the function exists.
- * @returns {ReturnedPatch}
- * @example
- * const patch = patchFunction('open', false, (args, original) => {
- * console.log(`XMLHttpRequest.open called with URL: ${args[1]}`);
- * return { block: true };
- * }, XMLHttpRequest.prototype);
- */
- export function patchFunction(name, isConstructor, callback, context = window) {
- if (!context || typeof context[name] !== 'function') {
- throw new Error(
- `Function or constructor ${name} not found in the specified context.`
- );
- }
- const original = context[name];
- context[name] = new Proxy(original, {
- [isConstructor ? 'construct' : 'apply'](target, thisArg, argList) {
- const options = callback?.(argList, original);
- let result;
- if (!options?.block) {
- result = isConstructor
- ? Reflect.construct(target, argList)
- : Reflect.apply(target, thisArg, argList);
- }
- return options && 'value' in options ? options.value : result;
- }
- });
- return {
- original,
- restore() {
- context[name] = original;
- }
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment