From fa018a8524f9e64006e574052d359fb2038346d5 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sat, 12 Nov 2022 19:41:43 +0100 Subject: [PATCH 1/4] chore: temp --- src/faker8/bind.ts | 89 ++++++++++++++++++++++++++++++ src/faker8/datatype/index.ts | 53 ++++++++++++++++++ src/faker8/datatype/number.ts | 54 ++++++++++++++++++ src/faker8/faker.ts | 35 ++++++++++++ src/faker8/fakerCore.ts | 46 +++++++++++++++ src/faker8/forkable.ts | 25 +++++++++ src/faker8/helpers/arrayElement.ts | 40 ++++++++++++++ src/faker8/helpers/index.ts | 45 +++++++++++++++ src/faker8/index.ts | 17 ++++++ src/faker8/mersenne.ts | 51 +++++++++++++++++ src/faker8/person/firstName.ts | 58 +++++++++++++++++++ src/faker8/person/index.ts | 50 +++++++++++++++++ src/faker8/usage.ts | 30 ++++++++++ 13 files changed, 593 insertions(+) create mode 100644 src/faker8/bind.ts create mode 100644 src/faker8/datatype/index.ts create mode 100644 src/faker8/datatype/number.ts create mode 100644 src/faker8/faker.ts create mode 100644 src/faker8/fakerCore.ts create mode 100644 src/faker8/forkable.ts create mode 100644 src/faker8/helpers/arrayElement.ts create mode 100644 src/faker8/helpers/index.ts create mode 100644 src/faker8/index.ts create mode 100644 src/faker8/mersenne.ts create mode 100644 src/faker8/person/firstName.ts create mode 100644 src/faker8/person/index.ts create mode 100644 src/faker8/usage.ts diff --git a/src/faker8/bind.ts b/src/faker8/bind.ts new file mode 100644 index 00000000000..c9a299ff858 --- /dev/null +++ b/src/faker8/bind.ts @@ -0,0 +1,89 @@ +import type { FakerCore } from './fakerCore'; + +export type FakerFn = ( + core: C, + ...args: P +) => R; + +type FakerFnFor = FakerFn< + C, + Parameters, + ReturnType +>; + +type FakerFnModule = { + [K in keyof M]: FakerFnFor; +}; + +type FakerFnModules< + C extends FakerCore, + M extends Record +> = { + [K in keyof M]: FakerFnModule; +}; + +type FakerFunction = (...args: any[]) => unknown; +export type FakerModule = Record; +export type FakerModules = Record; + +/** + * 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 firstNameFunction = bind(fakerCore, fistNameFn); + * + * @since 8.0.0 + */ +export function bind( + fakerCore: C, + fn: FakerFn +): (...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 nameModule = bindModule(fakerCore, nameFns); + * + * @since 8.0.0 + */ +export function bindModule( + fakerCore: C, + module: FakerFnModule +): 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 nameModule = bindModule(fakerCore, { name: nameFns }); + * + * @since 8.0.0 + */ +export function bindModules< + C extends FakerCore, + M extends Record +>(fakerCore: C, modules: FakerFnModules): M { + return Object.fromEntries( + Object.entries(modules).map(([key, value]) => { + return [key, bindModule(fakerCore, value)]; + }) + ) as M; +} diff --git a/src/faker8/datatype/index.ts b/src/faker8/datatype/index.ts new file mode 100644 index 00000000000..13a8c3f30bc --- /dev/null +++ b/src/faker8/datatype/index.ts @@ -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(fakerCore, datatypeFns); +} + +// Either +export const fakerDatatype: Datatype = bindDatatypeModule(fakerCore); +// Or +export const fakerDatatype2: Datatype = { number: fakerNumber }; diff --git a/src/faker8/datatype/number.ts b/src/faker8/datatype/number.ts new file mode 100644 index 00000000000..a2d1052b607 --- /dev/null +++ b/src/faker8/datatype/number.ts @@ -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 + * faker.datatype.number() // 55422 + * faker.datatype.number({ min: 1000000 }) // 1031433 + * faker.datatype.number({ max: 100 }) // 42 + * faker.datatype.number({ 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 + * 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 + */ +export const fakerNumber: (options?: { min?: number; max?: number }) => number = + bind(fakerCore, numberFn); diff --git a/src/faker8/faker.ts b/src/faker8/faker.ts new file mode 100644 index 00000000000..bfd96301000 --- /dev/null +++ b/src/faker8/faker.ts @@ -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; + +/** + * 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(core, fnsModules) + ); +} diff --git a/src/faker8/fakerCore.ts b/src/faker8/fakerCore.ts new file mode 100644 index 00000000000..a09dfa62a4c --- /dev/null +++ b/src/faker8/fakerCore.ts @@ -0,0 +1,46 @@ +import type { LocaleDefinition } from 'src'; +import en from '../locales/en'; +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: LocaleDefinition, + mersenne?: Mersenne +): LocalizedFakerCore { + mersenne = mersenne ?? newMersenne(); + return { + mersenne, + definitions, + fork: () => createLocalizedFakerCore(definitions, mersenne.fork()), + derive: () => createLocalizedFakerCore(definitions, mersenne.derive()), + }; +} + +const mersenne = newMersenne(); + +export const fakerCore = createFakerCore(mersenne); +export const localizedFakerCore = createLocalizedFakerCore(en, mersenne); diff --git a/src/faker8/forkable.ts b/src/faker8/forkable.ts new file mode 100644 index 00000000000..03f482ef743 --- /dev/null +++ b/src/faker8/forkable.ts @@ -0,0 +1,25 @@ +import type { FakerCore } from './fakerCore'; + +export type Forkable = T & { + fork: () => Forkable; + derive: () => Forkable; +}; + +export function forkable( + fakerCore: C, + factory: (fakerCore: C) => T +): Forkable { + 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; + fn.fork = () => forkable(fakerCore.fork() as C, factory); + fn.derive = () => forkable(fakerCore.derive() as C, factory); + return fn; + } +} diff --git a/src/faker8/helpers/arrayElement.ts b/src/faker8/helpers/arrayElement.ts new file mode 100644 index 00000000000..38bc7391e93 --- /dev/null +++ b/src/faker8/helpers/arrayElement.ts @@ -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(['cat', 'dog', 'mouse']) // 'dog' + * + * @since 8.0.0 + */ +export function arrayElementFn(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: (values: T[]) => T = bind( + fakerCore, + arrayElementFn +); diff --git a/src/faker8/helpers/index.ts b/src/faker8/helpers/index.ts new file mode 100644 index 00000000000..b8246904634 --- /dev/null +++ b/src/faker8/helpers/index.ts @@ -0,0 +1,45 @@ +// This file is generated by `pnpm run generate:some-script` + +import { bindModule } from '../bind'; +import type { FakerCore } from '../fakerCore'; +import { fakerCore } from '../fakerCore'; +import { arrayElementFn, fakerArrayElement } from './arrayElement'; + +/** + * The functions of the helpers module. + */ +export const helpersFns = { + arrayElement: arrayElementFn, +}; + +/** + * The helpers module. + */ +export type Helpers = { + /** + * 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 + */ + arrayElement: (values: T[]) => T; +}; + +/** + * Creates a new helpers module that is bound to the given faker instance. + * + * @param fakerCore The faker instance to bind the module to. + */ +export function bindHelpersModule(fakerCore: FakerCore): Helpers { + return bindModule(fakerCore, helpersFns); +} + +// Either +export const fakerHelpers: Helpers = bindHelpersModule(fakerCore); +// Or +export const fakerHelpers2: Helpers = { arrayElement: fakerArrayElement }; diff --git a/src/faker8/index.ts b/src/faker8/index.ts new file mode 100644 index 00000000000..2a284f743d8 --- /dev/null +++ b/src/faker8/index.ts @@ -0,0 +1,17 @@ +import { fakerDatatype } from './datatype'; +import type { Faker } from './faker'; +import { bindFaker } from './faker'; +import { localizedFakerCore } from './fakerCore'; +import { fakerHelpers } from './helpers'; +import { fakerPerson } from './person'; + +// Either +export const faker: Faker = bindFaker(localizedFakerCore); +// Or +export const faker2: Faker = { + datatype: fakerDatatype, + helpers: fakerHelpers, + person: fakerPerson, + fork: () => bindFaker(localizedFakerCore.fork()), + derive: () => bindFaker(localizedFakerCore.derive()), +}; diff --git a/src/faker8/mersenne.ts b/src/faker8/mersenne.ts new file mode 100644 index 00000000000..eb9d0cbf3a6 --- /dev/null +++ b/src/faker8/mersenne.ts @@ -0,0 +1,51 @@ +import MersenneTwister19937 from 'src/internal/mersenne/twister'; + +export interface Mersenne { + /** + * Generates a random number between `[min, max)`. The result is already floored. + * + * @param options The options to generate a random number. + * @param options.min The minimum number. + * @param options.max The maximum number. + */ + next(options: { max: number; min: number }): number; + + /** + * Sets the seed to use. + * + * @param seed The seed to use. + */ + seed(seed: number | number[]): void; + + fork(): Mersenne; + + derive(): Mersenne; +} + +export default function mersenne(): Mersenne { + const twister = new MersenneTwister19937(); + + twister.initGenrand(Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER)); + + return { + next({ min, max }): number { + return Math.floor(twister.genrandReal2() * (max - min) + min); + }, + + seed(seed: number | number[]): void { + if (typeof seed === 'number') { + twister.initGenrand(seed); + } else if (Array.isArray(seed)) { + twister.initByArray(seed, seed.length); + } + }, + + fork(): Mersenne { + return mersenne(); // TODO + }, + + derive(): Mersenne { + return mersenne(); // TODO + }, + }; +} diff --git a/src/faker8/person/firstName.ts b/src/faker8/person/firstName.ts new file mode 100644 index 00000000000..8a40ac5b4b1 --- /dev/null +++ b/src/faker8/person/firstName.ts @@ -0,0 +1,58 @@ +import type { SexType } from 'src/modules/person'; +import { bind } from '../bind'; +import type { LocalizedFakerCore } from '../fakerCore'; +import { localizedFakerCore } from '../fakerCore'; +import { arrayElementFn } from '../helpers/arrayElement'; + +/** + * Returns a random first name. + * + * @param fakerCore The faker core to use. + * @param sex The optional sex to use. + * Can be either `'female'` or `'male'`. + * + * @see fakerFirstName + * + * @example + * firstNameFn(faker) // 'Antwan' + * firstNameFn(faker, 'female') // 'Victoria' + * firstNameFn(faker, 'male') // 'Tom' + * + * @since 8.0.0 + */ +export function firstNameFn( + fakerCore: LocalizedFakerCore, + sex?: SexType +): string { + // selectDefinitions(...) + const definitions: string[] = sex + ? sex === 'female' + ? fakerCore.definitions.person.female_first_name + : fakerCore.definitions.person.male_first_name + : fakerCore.definitions.person.first_name; + + return arrayElementFn(fakerCore, definitions); +} + +// The following part is generated by `pnpm run generate:some-script` + +/** + * Returns a random first name. + * + * @alias faker.name.firstName + * @alias fakerName.firstName + * + * @param sex The optional sex to use. + * Can be either `'female'` or `'male'`. + * + * @example + * fakerFirstName() // 'Antwan' + * fakerFirstName('female') // 'Victoria' + * fakerFirstName('male') // 'Tom' + * + * @since 8.0.0 + */ +export const fakerFirstName: (sex?: SexType) => string = bind( + localizedFakerCore, + firstNameFn +); diff --git a/src/faker8/person/index.ts b/src/faker8/person/index.ts new file mode 100644 index 00000000000..92059f62984 --- /dev/null +++ b/src/faker8/person/index.ts @@ -0,0 +1,50 @@ +// This file is generated by `pnpm run generate:some-script` + +import { bindModule } from '../bind'; +import type { LocalizedFakerCore } from '../fakerCore'; +import { localizedFakerCore } from '../fakerCore'; +import { fakerFirstName, firstNameFn } from './firstname'; + +/** + * The functions of the person module. + */ +export const personFns = { + firstName: firstNameFn, +}; + +/** + * The person module. + */ +export type Person = Readonly<{ + /** + * Returns a random first name. + * + * @alias faker.name.firstName + * @alias fakerName.firstName + * + * @param sex The optional sex to use. + * Can be either `'female'` or `'male'`. + * + * @example + * fakerFirstName() // 'Antwan' + * fakerFirstName('female') // 'Victoria' + * fakerFirstName('male') // 'Tom' + * + * @since 8.0.0 + */ + firstName: typeof fakerFirstName; +}>; + +/** + * Creates a new person module that is bound to the given faker core. + * + * @param fakerCore The faker core to bind the module to. + */ +export function bindPersonModule(fakerCore: LocalizedFakerCore): Person { + return bindModule(fakerCore, personFns); +} + +// Either +export const fakerPerson: Person = bindPersonModule(localizedFakerCore); +// Or +export const fakerPerson2: Person = { firstName: fakerFirstName }; diff --git a/src/faker8/usage.ts b/src/faker8/usage.ts new file mode 100644 index 00000000000..35cabbb0259 --- /dev/null +++ b/src/faker8/usage.ts @@ -0,0 +1,30 @@ +import { faker } from '.'; +import { bind, bindModules } from './bind'; +import { bindDatatypeModule, datatypeFns } from './datatype'; +import { numberFn } from './datatype/number'; +import { fakerCore } from './fakerCore'; +import { forkable } from './forkable'; +import { helpersFns } from './helpers'; +import { fakerPerson } from './person'; +import { fakerFirstName } from './person/firstname'; + +const firstName = fakerFirstName(); +const firstName2 = fakerPerson.firstName(); +const firstName3 = faker.person.firstName(); +console.log(firstName, firstName2, firstName3); + +faker.fork().fork().person.firstName(); + +const fDataType = forkable(fakerCore, bindDatatypeModule); +fDataType.fork().fork().number(); + +const fNumber = forkable(fakerCore, (core) => bind(core, numberFn)); + +console.log(fNumber.fork().fork()()); + +const subSet = bindModules(fakerCore, { + datatype: datatypeFns, + helpers: helpersFns, +}); + +console.log(subSet.datatype.number()); From 3857407c5ca10e15634947657afde00fef8a8c8b Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sat, 12 Nov 2022 22:39:33 +0100 Subject: [PATCH 2/4] chore: temp --- src/faker8/bind.ts | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/faker8/bind.ts b/src/faker8/bind.ts index c9a299ff858..f064929ad3b 100644 --- a/src/faker8/bind.ts +++ b/src/faker8/bind.ts @@ -1,6 +1,10 @@ import type { FakerCore } from './fakerCore'; -export type FakerFn = ( +type FakerFunction = (...args: any[]) => unknown; +type FakerModule = Record; +type FakerModules = Record; + +type FakerFn = ( core: C, ...args: P ) => R; @@ -15,17 +19,10 @@ type FakerFnModule = { [K in keyof M]: FakerFnFor; }; -type FakerFnModules< - C extends FakerCore, - M extends Record -> = { +type FakerFnModules = { [K in keyof M]: FakerFnModule; }; -type FakerFunction = (...args: any[]) => unknown; -export type FakerModule = Record; -export type FakerModules = Record; - /** * Binds the given function to the given faker core. * @@ -73,14 +70,14 @@ export function bindModule( * @param modules The modules to bind. * * @example - * const nameModule = bindModule(fakerCore, { name: nameFns }); + * const customModules = bindModules(fakerCore, { name: nameFns }); * * @since 8.0.0 */ -export function bindModules< - C extends FakerCore, - M extends Record ->(fakerCore: C, modules: FakerFnModules): M { +export function bindModules( + fakerCore: C, + modules: FakerFnModules +): M { return Object.fromEntries( Object.entries(modules).map(([key, value]) => { return [key, bindModule(fakerCore, value)]; From 0e7e56ab49a13d85e7997d12da2cbb1cdf38be22 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sat, 12 Nov 2022 23:45:51 +0100 Subject: [PATCH 3/4] chore: temp --- src/faker8/bind.ts | 36 +++++++++++++++++++++--------- src/faker8/datatype/index.ts | 2 +- src/faker8/datatype/number.ts | 18 +++++++-------- src/faker8/faker.ts | 2 +- src/faker8/fakerCore.ts | 9 ++++++-- src/faker8/helpers/arrayElement.ts | 2 +- src/faker8/helpers/index.ts | 2 +- src/faker8/person/firstName.ts | 6 ++--- src/faker8/person/index.ts | 2 +- src/faker8/usage.ts | 18 ++++++++++----- 10 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/faker8/bind.ts b/src/faker8/bind.ts index f064929ad3b..4fd2a84cae7 100644 --- a/src/faker8/bind.ts +++ b/src/faker8/bind.ts @@ -1,4 +1,4 @@ -import type { FakerCore } from './fakerCore'; +import type { FakerCore, LocalizedFakerCore } from './fakerCore'; type FakerFunction = (...args: any[]) => unknown; type FakerModule = Record; @@ -30,7 +30,7 @@ type FakerFnModules = { * @param fn The function to bind. * * @example - * const firstNameFunction = bind(fakerCore, fistNameFn); + * const customFunction = bind(fakerCore, arrayElementFn); * * @since 8.0.0 */ @@ -48,11 +48,19 @@ export function bind( * @param module The module to bind. * * @example - * const nameModule = bindModule(fakerCore, nameFns); + * const customModule = bindModule(fakerCore, datatypeFns); * * @since 8.0.0 */ -export function bindModule( +export function bindModule( + fakerCore: FakerCore, + module: FakerFnModule +): M; +export function bindModule( + fakerCore: LocalizedFakerCore, + module: FakerFnModule +): M; +export function bindModule( fakerCore: C, module: FakerFnModule ): M { @@ -70,17 +78,25 @@ export function bindModule( * @param modules The modules to bind. * * @example - * const customModules = bindModules(fakerCore, { name: nameFns }); + * const customModules = bindModules<{ datatype: Datatype }>(fakerCore, { datatype: datatypeFns }); * * @since 8.0.0 */ -export function bindModules( - fakerCore: C, - modules: FakerFnModules -): M { +export function bindModules( + fakerCore: FakerCore, + modules: FakerFnModules +): Modules; +export function bindModules( + fakerCore: LocalizedFakerCore, + modules: FakerFnModules +): Modules; +export function bindModules< + Modules extends FakerModules, + Core extends FakerCore +>(fakerCore: Core, modules: FakerFnModules): Modules { return Object.fromEntries( Object.entries(modules).map(([key, value]) => { return [key, bindModule(fakerCore, value)]; }) - ) as M; + ) as Modules; } diff --git a/src/faker8/datatype/index.ts b/src/faker8/datatype/index.ts index 13a8c3f30bc..c955b558522 100644 --- a/src/faker8/datatype/index.ts +++ b/src/faker8/datatype/index.ts @@ -44,7 +44,7 @@ export type Datatype = { * @param fakerCore The faker core to bind the module to. */ export function bindDatatypeModule(fakerCore: FakerCore): Datatype { - return bindModule(fakerCore, datatypeFns); + return bindModule(fakerCore, datatypeFns); } // Either diff --git a/src/faker8/datatype/number.ts b/src/faker8/datatype/number.ts index a2d1052b607..3d97adb8c6c 100644 --- a/src/faker8/datatype/number.ts +++ b/src/faker8/datatype/number.ts @@ -14,10 +14,10 @@ import { fakerCore } from '../fakerCore'; * @throws When options define `max < min`. * * @example - * faker.datatype.number() // 55422 - * faker.datatype.number({ min: 1000000 }) // 1031433 - * faker.datatype.number({ max: 100 }) // 42 - * faker.datatype.number({ min: 10, max: 100}) // 36 + * numberFn(fakerCore) // 55422 + * numberFn(fakerCore, { min: 1000000 }) // 1031433 + * numberFn(fakerCore, { max: 100 }) // 42 + * numberFn(fakerCore, { min: 10, max: 100}) // 36 * * @since 8.0.0 */ @@ -42,11 +42,11 @@ export function numberFn( * @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 + * fakerNumber() // 55422 + * fakerNumber(100) // 52 + * fakerNumber({ min: 1000000 }) // 1031433 + * fakerNumber({ max: 100 }) // 42 + * fakerNumber({ min: 10, max: 100}) // 36 * * @since 8.0.0 */ diff --git a/src/faker8/faker.ts b/src/faker8/faker.ts index bfd96301000..5ddaeb44d1c 100644 --- a/src/faker8/faker.ts +++ b/src/faker8/faker.ts @@ -30,6 +30,6 @@ export type Faker = Forkable; */ export function bindFaker(fakerCore: LocalizedFakerCore): Faker { return forkable(fakerCore, (core) => - bindModules(core, fnsModules) + bindModules(core, fnsModules) ); } diff --git a/src/faker8/fakerCore.ts b/src/faker8/fakerCore.ts index a09dfa62a4c..b6abe101373 100644 --- a/src/faker8/fakerCore.ts +++ b/src/faker8/fakerCore.ts @@ -1,5 +1,6 @@ import type { LocaleDefinition } from 'src'; import en from '../locales/en'; +import enPerson from '../locales/en/person'; import type { Mersenne } from './mersenne'; import { default as newMersenne } from './mersenne'; @@ -28,13 +29,13 @@ export function createFakerCore(mersenne?: Mersenne): FakerCore { } export function createLocalizedFakerCore( - definitions: LocaleDefinition, + definitions: Partial, mersenne?: Mersenne ): LocalizedFakerCore { mersenne = mersenne ?? newMersenne(); return { mersenne, - definitions, + definitions: definitions as unknown as LocaleDefinition, fork: () => createLocalizedFakerCore(definitions, mersenne.fork()), derive: () => createLocalizedFakerCore(definitions, mersenne.derive()), }; @@ -44,3 +45,7 @@ const mersenne = newMersenne(); export const fakerCore = createFakerCore(mersenne); export const localizedFakerCore = createLocalizedFakerCore(en, mersenne); +export const personFakerCore = createLocalizedFakerCore( + { person: enPerson }, + mersenne +); diff --git a/src/faker8/helpers/arrayElement.ts b/src/faker8/helpers/arrayElement.ts index 38bc7391e93..8d70ca8dbc4 100644 --- a/src/faker8/helpers/arrayElement.ts +++ b/src/faker8/helpers/arrayElement.ts @@ -11,7 +11,7 @@ import { fakerCore } from '../fakerCore'; * @param values The array to pick the value from. * * @example - * fakerArrayElement(['cat', 'dog', 'mouse']) // 'dog' + * fakerArrayElement(fakerCore, ['cat', 'dog', 'mouse']) // 'dog' * * @since 8.0.0 */ diff --git a/src/faker8/helpers/index.ts b/src/faker8/helpers/index.ts index b8246904634..39c89ae8203 100644 --- a/src/faker8/helpers/index.ts +++ b/src/faker8/helpers/index.ts @@ -36,7 +36,7 @@ export type Helpers = { * @param fakerCore The faker instance to bind the module to. */ export function bindHelpersModule(fakerCore: FakerCore): Helpers { - return bindModule(fakerCore, helpersFns); + return bindModule(fakerCore, helpersFns); } // Either diff --git a/src/faker8/person/firstName.ts b/src/faker8/person/firstName.ts index 8a40ac5b4b1..6b2e8f529a1 100644 --- a/src/faker8/person/firstName.ts +++ b/src/faker8/person/firstName.ts @@ -14,9 +14,9 @@ import { arrayElementFn } from '../helpers/arrayElement'; * @see fakerFirstName * * @example - * firstNameFn(faker) // 'Antwan' - * firstNameFn(faker, 'female') // 'Victoria' - * firstNameFn(faker, 'male') // 'Tom' + * firstNameFn(fakerCore) // 'Antwan' + * firstNameFn(fakerCore, 'female') // 'Victoria' + * firstNameFn(fakerCore, 'male') // 'Tom' * * @since 8.0.0 */ diff --git a/src/faker8/person/index.ts b/src/faker8/person/index.ts index 92059f62984..5905554e1a3 100644 --- a/src/faker8/person/index.ts +++ b/src/faker8/person/index.ts @@ -41,7 +41,7 @@ export type Person = Readonly<{ * @param fakerCore The faker core to bind the module to. */ export function bindPersonModule(fakerCore: LocalizedFakerCore): Person { - return bindModule(fakerCore, personFns); + return bindModule(fakerCore, personFns); } // Either diff --git a/src/faker8/usage.ts b/src/faker8/usage.ts index 35cabbb0259..8d328bc97d1 100644 --- a/src/faker8/usage.ts +++ b/src/faker8/usage.ts @@ -1,9 +1,11 @@ import { faker } from '.'; import { bind, bindModules } from './bind'; +import type { Datatype } from './datatype'; import { bindDatatypeModule, datatypeFns } from './datatype'; import { numberFn } from './datatype/number'; import { fakerCore } from './fakerCore'; import { forkable } from './forkable'; +import type { Helpers } from './helpers'; import { helpersFns } from './helpers'; import { fakerPerson } from './person'; import { fakerFirstName } from './person/firstname'; @@ -15,16 +17,20 @@ console.log(firstName, firstName2, firstName3); faker.fork().fork().person.firstName(); +// Custom + const fDataType = forkable(fakerCore, bindDatatypeModule); -fDataType.fork().fork().number(); +console.log(fDataType.fork().fork().number()); const fNumber = forkable(fakerCore, (core) => bind(core, numberFn)); - console.log(fNumber.fork().fork()()); -const subSet = bindModules(fakerCore, { - datatype: datatypeFns, - helpers: helpersFns, -}); +const subSet = bindModules<{ datatype: Datatype; helpers: Helpers }>( + fakerCore, + { + datatype: datatypeFns, + helpers: helpersFns, + } +); console.log(subSet.datatype.number()); From 4818099e1ea54fbf907a894dd7f3b1f2af290463 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Tue, 25 Jun 2024 19:58:59 +0200 Subject: [PATCH 4/4] test --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e22aefafc74..c2f6125b4ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,6 @@ on: push: branches: - next - pull_request: permissions: contents: read # to fetch code (actions/checkout)