From e8fb54c19a0ed957d7bf042bd75191b298d76b3a Mon Sep 17 00:00:00 2001 From: PalmDevs Date: Tue, 3 Jun 2025 16:08:37 +0700 Subject: [PATCH] fix(lib/patcher): import types properly --- lib/patcher/src/_internal.ts | 52 ++++++-- lib/patcher/src/hooks/after.ts | 34 ++++-- lib/patcher/src/hooks/before.ts | 29 +++-- lib/patcher/src/hooks/instead.ts | 44 +++++-- lib/patcher/src/types.ts | 197 ++++++++++++++++++++----------- 5 files changed, 252 insertions(+), 104 deletions(-) diff --git a/lib/patcher/src/_internal.ts b/lib/patcher/src/_internal.ts index 045ea74..530abb1 100644 --- a/lib/patcher/src/_internal.ts +++ b/lib/patcher/src/_internal.ts @@ -1,4 +1,16 @@ -export interface FunctionProxyState { +import type { + AbstractNewable, + AfterHook, + BeforeHook, + Callable, + FiniteDomain, + InsteadHook, + UnknownFunction, +} from './types' + +export interface FunctionProxyState< + T extends UnknownFunction = UnknownFunction, +> { readonly proxy: T readonly target: T } @@ -53,7 +65,11 @@ export const patchedFunctionProxyHandler = { args = applyHooks(state.before, args) const { instead } = state - let result: ReturnType = Reflect.apply(instead === undefined ? state.target : instead.proxy, receiver, args) + let result: ReturnType = Reflect.apply( + instead === undefined ? state.target : instead.proxy, + receiver, + args, + ) result = applyHooks(state.after, result) @@ -77,30 +93,44 @@ export const patchedFunctionProxyHandler = { return result }, - defineProperty: (state, key, descriptor) => Reflect.defineProperty(state.target, key, descriptor), + defineProperty: (state, key, descriptor) => + Reflect.defineProperty(state.target, key, descriptor), deleteProperty: (state, key) => Reflect.deleteProperty(state.target, key), - get: (state, key, receiver: unknown) => Reflect.get(state.target, key, receiver), - getOwnPropertyDescriptor: (state, key) => Reflect.getOwnPropertyDescriptor(state.target, key), + get: (state, key, receiver: unknown) => + Reflect.get(state.target, key, receiver), + getOwnPropertyDescriptor: (state, key) => + Reflect.getOwnPropertyDescriptor(state.target, key), getPrototypeOf: state => Reflect.getPrototypeOf(state.target), has: (state, key) => Reflect.has(state.target, key), isExtensible: state => Reflect.isExtensible(state.target), ownKeys: state => Reflect.ownKeys(state.target), preventExtensions: state => Reflect.preventExtensions(state.target), - set: (state, key, value: unknown, receiver: unknown) => Reflect.set(state.target, key, value, receiver), - setPrototypeOf: (state, prototype) => Reflect.setPrototypeOf(state.target, prototype), + set: (state, key, value: unknown, receiver: unknown) => + Reflect.set(state.target, key, value, receiver), + setPrototypeOf: (state, prototype) => + Reflect.setPrototypeOf(state.target, prototype), } as const satisfies Required> interface PatchedFunctionProxyStateMap extends WeakMap { readonly delete: (key: UnknownFunction) => boolean - readonly get: (key: K) => PatchedFunctionProxyState | undefined + readonly get: ( + key: K, + ) => PatchedFunctionProxyState | undefined readonly has: (key: UnknownFunction) => boolean - readonly set: (key: K, value: PatchedFunctionProxyState) => this + readonly set: ( + key: K, + value: PatchedFunctionProxyState, + ) => this } /** proxy -> state */ -export const patchedFunctionProxyStates: PatchedFunctionProxyStateMap = new WeakMap() +export const patchedFunctionProxyStates: PatchedFunctionProxyStateMap = + new WeakMap() -export function createPatchedFunctionProxy( +export function createPatchedFunctionProxy< + Key extends PropertyKey, + Value extends UnknownFunction, +>( target: Value, parent: Record, key: FiniteDomain, diff --git a/lib/patcher/src/hooks/after.ts b/lib/patcher/src/hooks/after.ts index ceb6c1d..56338a6 100644 --- a/lib/patcher/src/hooks/after.ts +++ b/lib/patcher/src/hooks/after.ts @@ -1,11 +1,18 @@ import { + createPatchedFunctionProxy, type HookNode, type PatchedFunctionProxyState, - createPatchedFunctionProxy, patchedFunctionProxyStates, unproxy, } from '../_internal' +import type { + AfterHook, + BeforeHook, + FiniteDomain, + UnknownFunction, +} from '../types' + function unpatchAfter( state: PatchedFunctionProxyState, hookNode: HookNode>, @@ -19,7 +26,8 @@ function unpatchAfter( if (prev === undefined) { state.after = next if (next === undefined) { - if (state.before === undefined && state.instead === undefined) unproxy(state) + if (state.before === undefined && state.instead === undefined) + unproxy(state) return } } else { @@ -31,7 +39,10 @@ function unpatchAfter( hookNode.next = undefined } -export function after, Key extends PropertyKey>( +export function after< + Parent extends Record, + Key extends PropertyKey, +>( parent: Parent, key: FiniteDomain, hook: AfterHook, @@ -48,21 +59,28 @@ export function after( if (state !== undefined && state.parent === parent && state.key === key) { const head = state.after hookNode = { - unpatched: false, hook, - prev: undefined, next: head, + prev: undefined, + unpatched: false, } if (head !== undefined) head.prev = hookNode state.after = hookNode } else { hookNode = { - unpatched: false, hook, - prev: undefined, next: undefined, + prev: undefined, + unpatched: false, } - state = createPatchedFunctionProxy(target, parent, key, undefined, undefined, hookNode) + state = createPatchedFunctionProxy( + target, + parent, + key, + undefined, + undefined, + hookNode, + ) } return unpatchAfter.bind(undefined, state, hookNode) diff --git a/lib/patcher/src/hooks/before.ts b/lib/patcher/src/hooks/before.ts index 0c8fb5f..5e5525f 100644 --- a/lib/patcher/src/hooks/before.ts +++ b/lib/patcher/src/hooks/before.ts @@ -1,11 +1,13 @@ import { + createPatchedFunctionProxy, type HookNode, type PatchedFunctionProxyState, - createPatchedFunctionProxy, patchedFunctionProxyStates, unproxy, } from '../_internal' +import type { BeforeHook, FiniteDomain, UnknownFunction } from '../types' + function unpatchBefore( state: PatchedFunctionProxyState, hookNode: HookNode>, @@ -19,7 +21,8 @@ function unpatchBefore( if (prev === undefined) { state.before = next if (next === undefined) { - if (state.instead === undefined && state.after === undefined) unproxy(state) + if (state.instead === undefined && state.after === undefined) + unproxy(state) return } } else { @@ -31,7 +34,10 @@ function unpatchBefore( hookNode.next = undefined } -export function before, Key extends PropertyKey>( +export function before< + Parent extends Record, + Key extends PropertyKey, +>( parent: Parent, key: FiniteDomain, hook: BeforeHook, @@ -48,21 +54,28 @@ export function before( if (state !== undefined && state.parent === parent && state.key === key) { const head = state.before hookNode = { - unpatched: false, hook, - prev: undefined, next: head, + prev: undefined, + unpatched: false, } if (head !== undefined) head.prev = hookNode state.before = hookNode } else { hookNode = { - unpatched: false, hook, - prev: undefined, next: undefined, + prev: undefined, + unpatched: false, } - state = createPatchedFunctionProxy(target, parent, key, hookNode, undefined, undefined) + state = createPatchedFunctionProxy( + target, + parent, + key, + hookNode, + undefined, + undefined, + ) } return unpatchBefore.bind(undefined, state, hookNode) diff --git a/lib/patcher/src/hooks/instead.ts b/lib/patcher/src/hooks/instead.ts index 94f7547..36bdc4c 100644 --- a/lib/patcher/src/hooks/instead.ts +++ b/lib/patcher/src/hooks/instead.ts @@ -1,18 +1,33 @@ import { + createPatchedFunctionProxy, type FunctionProxyState, type InsteadHookNode, type PatchedFunctionProxyState, - createPatchedFunctionProxy, patchedFunctionProxyHandler, patchedFunctionProxyStates, unproxy, } from '../_internal' +import type { + AbstractNewable, + Callable, + FiniteDomain, + InsteadHook, + UnknownFunction, +} from '../types' + const insteadHookProxyHandler = { ...patchedFunctionProxyHandler, - apply(hookNode: InsteadHookNode, receiver: ThisParameterType, args: Parameters) { + apply( + hookNode: InsteadHookNode, + receiver: ThisParameterType, + args: Parameters, + ) { const { next } = hookNode - return Reflect.apply(hookNode.hook, receiver, [args, next === undefined ? hookNode.target : next.proxy]) + return Reflect.apply(hookNode.hook, receiver, [ + args, + next === undefined ? hookNode.target : next.proxy, + ]) }, construct>( hookNode: InsteadHookNode, @@ -20,7 +35,11 @@ const insteadHookProxyHandler = { ctor: AbstractNewable, ) { const { next } = hookNode - return Reflect.construct(hookNode.hook, [args, next === undefined ? hookNode.target : next.proxy], ctor) + return Reflect.construct( + hookNode.hook, + [args, next === undefined ? hookNode.target : next.proxy], + ctor, + ) }, } as const satisfies Required> @@ -36,7 +55,8 @@ function unpatchInstead( if (prev === undefined) { state.instead = next if (next === undefined) { - if (state.before === undefined && state.after === undefined) unproxy(state) + if (state.before === undefined && state.after === undefined) + unproxy(state) return } } else { @@ -48,7 +68,10 @@ function unpatchInstead( hookNode.next = undefined } -export function instead, Key extends PropertyKey>( +export function instead< + Parent extends Record, + Key extends PropertyKey, +>( parent: Parent, key: FiniteDomain, hook: InsteadHook, @@ -78,7 +101,14 @@ export function instead( state.instead = hookNode } else { hookNode.next = undefined - state = createPatchedFunctionProxy(target, parent, key, undefined, hookNode, undefined) + state = createPatchedFunctionProxy( + target, + parent, + key, + undefined, + hookNode, + undefined, + ) } return unpatchInstead.bind(undefined, state, hookNode) diff --git a/lib/patcher/src/types.ts b/lib/patcher/src/types.ts index 56708a9..78f75e7 100644 --- a/lib/patcher/src/types.ts +++ b/lib/patcher/src/types.ts @@ -1,4 +1,4 @@ -type FiniteDomain = unknown extends ( +export type FiniteDomain = unknown extends ( Key extends unknown ? object extends Record ? unknown @@ -8,69 +8,84 @@ type FiniteDomain = unknown extends ( ? never : Key -type UnknownFunction = Callable | AbstractNewable +export type UnknownFunction = Callable | AbstractNewable -type Callable = ( - this: This, - ...args: Args -) => Return +export type Callable< + This = never, + Args extends readonly unknown[] = never, + Return = unknown, +> = (this: This, ...args: Args) => Return -type AbstractNewable = abstract new (...args: Args) => Return +export type AbstractNewable< + Args extends readonly unknown[] = never, + Return = unknown, +> = abstract new (...args: Args) => Return -type ConcreteNewable = new (...args: Args) => Return +export type ConcreteNewable< + Args extends readonly unknown[] = never, + Return = unknown, +> = new (...args: Args) => Return -type UnionToIntersection = (Union extends unknown ? (arg: Union) => unknown : never) extends ( - arg: infer Intersection, -) => unknown +export type UnionToIntersection = ( + Union extends unknown + ? (arg: Union) => unknown + : never +) extends (arg: infer Intersection) => unknown ? Intersection & Union : never -type BeforeHook = OverloadUnion extends infer U - ? 0 extends 1 & U - ? (args: any) => any - : UnionToIntersection< - U extends Callable - ? (args: Args) => Args - : U extends ConcreteNewable - ? (args: Args) => Args - : never - > - : never +export type BeforeHook = + OverloadUnion extends infer U + ? 0 extends 1 & U + ? (args: any) => any + : UnionToIntersection< + U extends Callable + ? (args: Args) => Args + : U extends ConcreteNewable + ? (args: Args) => Args + : never + > + : never -type InsteadHook = OverloadUnion extends infer U - ? 0 extends 1 & U - ? - | ((this: any, args: any[], originalFunction: T) => any) - | (abstract new ( - args: any[], - originalFunction: T, - ) => any) - : UnionToIntersection< - U extends Callable - ? (this: This, args: Args, originalFunction: T) => Return - : U extends ConcreteNewable - ? abstract new ( - args: Args, - originalFunction: T, - ) => Return - : never - > - : never +export type InsteadHook = + OverloadUnion extends infer U + ? 0 extends 1 & U + ? + | ((this: any, args: any[], originalFunction: T) => any) + | (abstract new ( + args: any[], + originalFunction: T, + ) => any) + : UnionToIntersection< + U extends Callable + ? (this: This, args: Args, originalFunction: T) => Return + : U extends ConcreteNewable + ? abstract new ( + args: Args, + originalFunction: T, + ) => Return + : never + > + : never -type AfterHook = OverloadUnion extends infer U - ? 0 extends 1 & U - ? (result: any) => any - : UnionToIntersection< - U extends Callable - ? (result: Return) => Return - : U extends ConcreteNewable - ? (result: Return) => Return - : never - > - : never +export type AfterHook = + OverloadUnion extends infer U + ? 0 extends 1 & U + ? (result: any) => any + : UnionToIntersection< + U extends Callable + ? (result: Return) => Return + : U extends ConcreteNewable + ? (result: Return) => Return + : never + > + : never /** @see {@link https://github.com/microsoft/TypeScript/issues/32164#issuecomment-1146737709} */ -type OverloadUnion> = 0 extends 1 & Overload +export type OverloadUnion< + Overload extends UnknownFunction, + PartialOverload = OmitOverloads, +> = 0 extends 1 & Overload ? any : Overload extends Callable ? Overload extends AbstractNewable @@ -80,14 +95,22 @@ type OverloadUnion, ConcreteNewable > - : OverloadUnionCallable> + : OverloadUnionCallable< + Overload, + PartialOverload, + Callable + > : Overload extends AbstractNewable - ? OverloadUnionNewable> + ? OverloadUnionNewable< + Overload, + PartialOverload, + ConcreteNewable + > : never -type OmitOverloads = { [Key in keyof T]: T[Key] } +export type OmitOverloads = { [Key in keyof T]: T[Key] } -type OverloadUnionCallableNewable< +export type OverloadUnionCallableNewable< Overload extends Callable & AbstractNewable, PartialOverload, CurrentCallable extends Callable, @@ -101,7 +124,7 @@ type OverloadUnionCallableNewable< | CurrentCallable | CurrentNewable -type OverloadUnionCallableNewableInner< +export type OverloadUnionCallableNewableInner< Overload extends Callable & AbstractNewable, PartialOverload, PreviousOverload extends Callable & ConcreteNewable, @@ -110,8 +133,10 @@ type OverloadUnionCallableNewableInner< : Overload extends Callable ? Overload extends AbstractNewable ? // Detects infinite recursion caused by generic overloads. - Callable & ConcreteNewable extends PreviousOverload - ? PreviousOverload extends Callable & ConcreteNewable + Callable & + ConcreteNewable extends PreviousOverload + ? PreviousOverload extends Callable & + ConcreteNewable ? any : OverloadUnionCallableNewable< Overload, @@ -128,11 +153,19 @@ type OverloadUnionCallableNewableInner< : never : never -type OverloadUnionCallable = - | OverloadUnionCallableInner +export type OverloadUnionCallable< + Overload extends Callable, + PartialOverload, + CurrentCallable extends Callable, +> = + | OverloadUnionCallableInner< + CurrentCallable & Overload, + CurrentCallable & PartialOverload, + CurrentCallable + > | CurrentCallable -type OverloadUnionCallableInner< +export type OverloadUnionCallableInner< Overload extends Callable, PartialOverload, PreviousOverload extends Callable, @@ -143,15 +176,31 @@ type OverloadUnionCallableInner< Callable extends PreviousOverload ? PreviousOverload extends Callable ? any - : OverloadUnionCallable> - : OverloadUnionCallable> + : OverloadUnionCallable< + Overload, + PartialOverload, + Callable + > + : OverloadUnionCallable< + Overload, + PartialOverload, + Callable + > : never -type OverloadUnionNewable = - | OverloadUnionNewableInner +export type OverloadUnionNewable< + Overload extends AbstractNewable, + PartialOverload, + CurrentNewable extends ConcreteNewable, +> = + | OverloadUnionNewableInner< + CurrentNewable & Overload, + CurrentNewable & PartialOverload, + CurrentNewable + > | CurrentNewable -type OverloadUnionNewableInner< +export type OverloadUnionNewableInner< Overload extends AbstractNewable, PartialOverload, PreviousOverload extends ConcreteNewable, @@ -162,6 +211,14 @@ type OverloadUnionNewableInner< ConcreteNewable extends PreviousOverload ? PartialOverload extends ConcreteNewable ? any - : OverloadUnionNewable> - : OverloadUnionNewable> + : OverloadUnionNewable< + Overload, + PartialOverload, + ConcreteNewable + > + : OverloadUnionNewable< + Overload, + PartialOverload, + ConcreteNewable + > : never