-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import type { FakerCore, LocalizedFakerCore } from './fakerCore'; | ||
|
||
type FakerFunction = (...args: any[]) => unknown; | ||
type FakerModule = Record<string, FakerFunction>; | ||
type FakerModules = Record<string, FakerModule>; | ||
|
||
type FakerFn<C extends FakerCore, P extends unknown[], R> = ( | ||
Check failure on line 7 in src/faker8/bind.ts GitHub Actions / Lint: node-22, ubuntu-latest
Check failure on line 7 in src/faker8/bind.ts GitHub Actions / Lint: node-22, ubuntu-latest
|
||
core: C, | ||
...args: P | ||
) => R; | ||
|
||
type FakerFnFor<C extends FakerCore, F extends FakerFunction> = FakerFn< | ||
Check failure on line 12 in src/faker8/bind.ts GitHub Actions / Lint: node-22, ubuntu-latest
|
||
C, | ||
Parameters<F>, | ||
ReturnType<F> | ||
>; | ||
|
||
type FakerFnModule<C extends FakerCore, M extends FakerModule> = { | ||
Check failure on line 18 in src/faker8/bind.ts GitHub Actions / Lint: node-22, ubuntu-latest
|
||
[K in keyof M]: FakerFnFor<C, M[K]>; | ||
}; | ||
|
||
type FakerFnModules<C extends FakerCore, M extends FakerModules> = { | ||
Check failure on line 22 in src/faker8/bind.ts GitHub Actions / Lint: node-22, ubuntu-latest
|
||
[K in keyof M]: FakerFnModule<C, M[K]>; | ||
}; | ||
|
||
/** | ||
* Binds the given function to the given faker core. | ||
* | ||
* @param fakerCore The faker core to bind the function to. | ||
* @param fn The function to bind. | ||
* | ||
* @example | ||
* const customFunction = bind(fakerCore, arrayElementFn); | ||
* | ||
* @since 8.0.0 | ||
*/ | ||
export function bind<C extends FakerCore, P extends any[], R>( | ||
fakerCore: C, | ||
fn: FakerFn<C, P, R> | ||
): (...args: P) => R { | ||
return (...args: P) => fn(fakerCore.fork() as C, ...args); | ||
} | ||
|
||
/** | ||
* Binds the given module to the given faker core. | ||
* | ||
* @param fakerCore The faker core to bind the module to. | ||
* @param module The module to bind. | ||
* | ||
* @example | ||
* const customModule = bindModule<Datatype>(fakerCore, datatypeFns); | ||
* | ||
* @since 8.0.0 | ||
*/ | ||
export function bindModule<M extends FakerModule>( | ||
fakerCore: FakerCore, | ||
module: FakerFnModule<FakerCore, M> | ||
): M; | ||
export function bindModule<M extends FakerModule>( | ||
fakerCore: LocalizedFakerCore, | ||
module: FakerFnModule<LocalizedFakerCore, M> | ||
): M; | ||
export function bindModule<M extends FakerModule, C extends FakerCore>( | ||
fakerCore: C, | ||
module: FakerFnModule<C, M> | ||
): M { | ||
return Object.fromEntries( | ||
Object.entries(module).map(([key, value]) => { | ||
return [key, bind(fakerCore, value)]; | ||
}) | ||
) as M; | ||
} | ||
|
||
/** | ||
* Binds the given modules to the given faker core. | ||
* | ||
* @param fakerCore The faker core to bind the modules to. | ||
* @param modules The modules to bind. | ||
* | ||
* @example | ||
* const customModules = bindModules<{ datatype: Datatype }>(fakerCore, { datatype: datatypeFns }); | ||
* | ||
* @since 8.0.0 | ||
*/ | ||
export function bindModules<Modules extends FakerModules>( | ||
fakerCore: FakerCore, | ||
modules: FakerFnModules<FakerCore, Modules> | ||
): Modules; | ||
export function bindModules<Modules extends FakerModules>( | ||
fakerCore: LocalizedFakerCore, | ||
modules: FakerFnModules<LocalizedFakerCore, Modules> | ||
): Modules; | ||
export function bindModules< | ||
Modules extends FakerModules, | ||
Core extends FakerCore | ||
>(fakerCore: Core, modules: FakerFnModules<Core, Modules>): Modules { | ||
return Object.fromEntries( | ||
Object.entries(modules).map(([key, value]) => { | ||
return [key, bindModule(fakerCore, value)]; | ||
}) | ||
) as Modules; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// This file is generated by `pnpm run generate:some-script` | ||
|
||
import { bindModule } from '../bind'; | ||
import type { FakerCore } from '../fakerCore'; | ||
import { fakerCore } from '../fakerCore'; | ||
import { fakerNumber, numberFn } from './number'; | ||
|
||
/** | ||
* The functions of the datatype module. | ||
*/ | ||
export const datatypeFns = { | ||
number: numberFn, | ||
}; | ||
|
||
/** | ||
* The datatype module. | ||
*/ | ||
export type Datatype = { | ||
/** | ||
* Returns a single random number in the given range. | ||
* The bounds are inclusive. | ||
* | ||
* @param options Maximum value or options object. | ||
* @param options.min Lower bound for generated number. Defaults to `0`. | ||
* @param options.max Upper bound for generated number. Defaults to `min + 99999`. | ||
* | ||
* @throws When options define `max < min`. | ||
* | ||
* @example | ||
* faker.datatype.number() // 55422 | ||
* faker.datatype.number(100) // 52 | ||
* faker.datatype.number({ min: 1000000 }) // 1031433 | ||
* faker.datatype.number({ max: 100 }) // 42 | ||
* faker.datatype.number({ min: 10, max: 100}) // 36 | ||
* | ||
* @since 8.0.0 | ||
*/ | ||
number: typeof fakerNumber; | ||
}; | ||
|
||
/** | ||
* Creates a new datatype module that is bound to the given faker core. | ||
* | ||
* @param fakerCore The faker core to bind the module to. | ||
*/ | ||
export function bindDatatypeModule(fakerCore: FakerCore): Datatype { | ||
return bindModule<Datatype>(fakerCore, datatypeFns); | ||
} | ||
|
||
// Either | ||
export const fakerDatatype: Datatype = bindDatatypeModule(fakerCore); | ||
// Or | ||
export const fakerDatatype2: Datatype = { number: fakerNumber }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { bind } from '../bind'; | ||
import type { FakerCore } from '../fakerCore'; | ||
import { fakerCore } from '../fakerCore'; | ||
|
||
/** | ||
* Returns a single random number in the given range. | ||
* The bounds are inclusive. | ||
* | ||
* @param fakerCore The faker core to use. | ||
* @param options Maximum value or options object. | ||
* @param options.min Lower bound for generated number. Defaults to `0`. | ||
* @param options.max Upper bound for generated number. Defaults to `min + 99999`. | ||
* | ||
* @throws When options define `max < min`. | ||
* | ||
* @example | ||
* numberFn(fakerCore) // 55422 | ||
* numberFn(fakerCore, { min: 1000000 }) // 1031433 | ||
* numberFn(fakerCore, { max: 100 }) // 42 | ||
* numberFn(fakerCore, { min: 10, max: 100}) // 36 | ||
* | ||
* @since 8.0.0 | ||
*/ | ||
export function numberFn( | ||
fakerCore: FakerCore, | ||
options: { min?: number; max?: number } = {} | ||
): number { | ||
const { min = 0, max = min + 99999 } = options; | ||
return fakerCore.mersenne.next({ min, max }); | ||
} | ||
|
||
// The following part is generated by `pnpm run generate:some-script` | ||
|
||
/** | ||
* Returns a single random number in the given range. | ||
* The bounds are inclusive. | ||
* | ||
* @param options Maximum value or options object. | ||
* @param options.min Lower bound for generated number. Defaults to `0`. | ||
* @param options.max Upper bound for generated number. Defaults to `min + 99999`. | ||
* | ||
* @throws When options define `max < min`. | ||
* | ||
* @example | ||
* fakerNumber() // 55422 | ||
* fakerNumber(100) // 52 | ||
* fakerNumber({ min: 1000000 }) // 1031433 | ||
* fakerNumber({ max: 100 }) // 42 | ||
* fakerNumber({ min: 10, max: 100}) // 36 | ||
* | ||
* @since 8.0.0 | ||
*/ | ||
export const fakerNumber: (options?: { min?: number; max?: number }) => number = | ||
bind(fakerCore, numberFn); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { bindModules } from './bind'; | ||
import type { Datatype } from './datatype'; | ||
import { datatypeFns } from './datatype'; | ||
import type { LocalizedFakerCore } from './fakerCore'; | ||
import type { Forkable } from './forkable'; | ||
import { forkable } from './forkable'; | ||
import type { Helpers } from './helpers'; | ||
import { helpersFns } from './helpers'; | ||
import type { Person } from './person'; | ||
import { personFns } from './person'; | ||
|
||
export const fnsModules = { | ||
datatype: datatypeFns, | ||
helpers: helpersFns, | ||
person: personFns, | ||
}; | ||
|
||
export type FakerModules = { | ||
datatype: Datatype; | ||
helpers: Helpers; | ||
person: Person; | ||
}; | ||
|
||
export type Faker = Forkable<FakerModules>; | ||
|
||
/** | ||
* Creates a new faker instance that is bound to the given faker core. | ||
* | ||
* @param fakerCore The faker core to bind the module to. | ||
*/ | ||
export function bindFaker(fakerCore: LocalizedFakerCore): Faker { | ||
return forkable(fakerCore, (core) => | ||
bindModules<FakerModules>(core, fnsModules) | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import type { LocaleDefinition } from 'src'; | ||
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Build & Unit Test: node-20, ubuntu-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Timezone Test: node-20, ubuntu-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Build & Unit Test: node-18, ubuntu-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Build & Unit Test: node-22, ubuntu-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / TS-Check: node-22, ubuntu-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Build & Unit Test: node-18, macos-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Build & Unit Test: node-20, macos-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Build & Unit Test: node-22, macos-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Codecov: node-22, ubuntu-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Check Code Generation: node-22, ubuntu-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Build & Unit Test: node-18, windows-latest
Check failure on line 1 in src/faker8/fakerCore.ts GitHub Actions / Build & Unit Test: node-22, windows-latest
|
||
import en from '../locales/en'; | ||
import enPerson from '../locales/en/person'; | ||
import type { Mersenne } from './mersenne'; | ||
import { default as newMersenne } from './mersenne'; | ||
|
||
export interface FakerCore { | ||
/** | ||
* @internal | ||
*/ | ||
readonly mersenne: Mersenne; | ||
readonly fork: () => FakerCore; | ||
readonly derive: () => FakerCore; | ||
} | ||
|
||
export interface LocalizedFakerCore extends FakerCore { | ||
readonly definitions: LocaleDefinition; | ||
readonly fork: () => LocalizedFakerCore; | ||
readonly derive: () => LocalizedFakerCore; | ||
} | ||
|
||
export function createFakerCore(mersenne?: Mersenne): FakerCore { | ||
mersenne = mersenne ?? newMersenne(); | ||
return { | ||
mersenne, | ||
fork: () => createFakerCore(mersenne.fork()), | ||
derive: () => createFakerCore(mersenne.derive()), | ||
}; | ||
} | ||
|
||
export function createLocalizedFakerCore( | ||
definitions: Partial<LocaleDefinition>, | ||
mersenne?: Mersenne | ||
): LocalizedFakerCore { | ||
mersenne = mersenne ?? newMersenne(); | ||
return { | ||
mersenne, | ||
definitions: definitions as unknown as LocaleDefinition, | ||
fork: () => createLocalizedFakerCore(definitions, mersenne.fork()), | ||
derive: () => createLocalizedFakerCore(definitions, mersenne.derive()), | ||
}; | ||
} | ||
|
||
const mersenne = newMersenne(); | ||
|
||
export const fakerCore = createFakerCore(mersenne); | ||
export const localizedFakerCore = createLocalizedFakerCore(en, mersenne); | ||
export const personFakerCore = createLocalizedFakerCore( | ||
{ person: enPerson }, | ||
mersenne | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import type { FakerCore } from './fakerCore'; | ||
|
||
export type Forkable<T> = T & { | ||
fork: () => Forkable<T>; | ||
derive: () => Forkable<T>; | ||
}; | ||
|
||
export function forkable<C extends FakerCore, T>( | ||
fakerCore: C, | ||
factory: (fakerCore: C) => T | ||
): Forkable<T> { | ||
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Build & Unit Test: node-20, ubuntu-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Timezone Test: node-20, ubuntu-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Build & Unit Test: node-18, ubuntu-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Build & Unit Test: node-22, ubuntu-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / TS-Check: node-22, ubuntu-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Build & Unit Test: node-18, macos-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Build & Unit Test: node-20, macos-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Build & Unit Test: node-22, macos-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Codecov: node-22, ubuntu-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Check Code Generation: node-22, ubuntu-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Build & Unit Test: node-18, windows-latest
Check failure on line 11 in src/faker8/forkable.ts GitHub Actions / Build & Unit Test: node-22, windows-latest
|
||
const result = factory(fakerCore); | ||
if (typeof result === 'object') { | ||
return { | ||
...result, | ||
fork: () => forkable(fakerCore.fork() as C, factory), | ||
derive: () => forkable(fakerCore.derive() as C, factory), | ||
}; | ||
} else if (typeof result === 'function') { | ||
const fn = result as unknown as Forkable<T>; | ||
fn.fork = () => forkable(fakerCore.fork() as C, factory); | ||
fn.derive = () => forkable(fakerCore.derive() as C, factory); | ||
return fn; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { bind } from '../bind'; | ||
import { numberFn } from '../datatype/number'; | ||
import type { FakerCore } from '../fakerCore'; | ||
import { fakerCore } from '../fakerCore'; | ||
|
||
/** | ||
* Returns a random element from the given array. | ||
* | ||
* @template T The type of the entries to pick from. | ||
* @param fakerCore The faker core to use. | ||
* @param values The array to pick the value from. | ||
* | ||
* @example | ||
* fakerArrayElement(fakerCore, ['cat', 'dog', 'mouse']) // 'dog' | ||
* | ||
* @since 8.0.0 | ||
*/ | ||
export function arrayElementFn<T>(fakerCore: FakerCore, values: T[]): T { | ||
const { length } = values; | ||
const index = numberFn(fakerCore, { min: 0, max: length - 1 }); | ||
return values[index]; | ||
} | ||
|
||
// The following part is generated by `pnpm run generate:some-script` | ||
|
||
/** | ||
* Returns a random element from the given array. | ||
* | ||
* @template T The type of the entries to pick from. | ||
* @param values The array to pick the value from. | ||
* | ||
* @example | ||
* fakerArrayElement(['cat', 'dog', 'mouse']) // 'dog' | ||
* | ||
* @since 8.0.0 | ||
*/ | ||
export const fakerArrayElement: <T>(values: T[]) => T = bind( | ||
fakerCore, | ||
arrayElementFn | ||
); |