import { mocks } from '@/mocks' import { repeat } from '@/utilities' // eslint-disable-next-line @typescript-eslint/no-explicit-any type Mock = (...args: any[]) => any type MockParams = Parameters type MockReturns = ReturnType // eslint-disable-next-line @typescript-eslint/no-explicit-any type OnlyRequired = Partial extends T ? U : T extends [infer F, ...infer R] ? OnlyRequired : U type MockParamsRequired = OnlyRequired> type CreateArguments, K extends keyof T> = MockParamsRequired extends never[] ? [key: K, args?: MockParams] : [key: K, args: MockParams] type CreateManyArguments, K extends keyof T> = MockParamsRequired extends never[] ? [key: K, count: number, args?: MockParams] : [key: K, count: number, args: MockParams] export class Mocker> { private readonly mockerFunctions: T public constructor(mockerFunctions: T) { this.mockerFunctions = mockerFunctions } public create(...[key, args]: CreateArguments): MockReturns { const mock = this.mockerFunctions[key].bind(this, ...args ?? []) return mock() } public createMany(...[key, count, args]: CreateManyArguments): MockReturns[] { const mock = this.mockerFunctions[key].bind(this, ...args ?? []) return repeat(count, mock) } } export const mocker = new Mocker(mocks) // eslint-disable-next-line @typescript-eslint/no-explicit-any export type MockFunction = (this: typeof mocker, ...args: Args) => T