Skip to content

Commit

Permalink
Merge branch 'faker8' into next
Browse files Browse the repository at this point in the history
  • Loading branch information
ST-DDT authored Jun 25, 2024
2 parents 1591a0b + 4818099 commit 779bffc
Show file tree
Hide file tree
Showing 13 changed files with 617 additions and 0 deletions.
102 changes: 102 additions & 0 deletions src/faker8/bind.ts
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;

Check failure on line 3 in src/faker8/bind.ts

View workflow job for this annotation

GitHub Actions / Lint: node-22, ubuntu-latest

Unexpected any. Specify a different type
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

View workflow job for this annotation

GitHub Actions / Lint: node-22, ubuntu-latest

Type Parameter name `C` must have one of the following prefixes: T

Check failure on line 7 in src/faker8/bind.ts

View workflow job for this annotation

GitHub Actions / Lint: node-22, ubuntu-latest

Type Parameter name `P` must have one of the following prefixes: T

Check failure on line 7 in src/faker8/bind.ts

View workflow job for this annotation

GitHub Actions / Lint: node-22, ubuntu-latest

Type Parameter name `R` must have one of the following prefixes: T
core: C,
...args: P
) => R;

type FakerFnFor<C extends FakerCore, F extends FakerFunction> = FakerFn<

Check failure on line 12 in src/faker8/bind.ts

View workflow job for this annotation

GitHub Actions / Lint: node-22, ubuntu-latest

Type Parameter name `C` must have one of the following prefixes: T

Check failure on line 12 in src/faker8/bind.ts

View workflow job for this annotation

GitHub Actions / Lint: node-22, ubuntu-latest

Type Parameter name `F` must have one of the following prefixes: T
C,
Parameters<F>,
ReturnType<F>
>;

type FakerFnModule<C extends FakerCore, M extends FakerModule> = {

Check failure on line 18 in src/faker8/bind.ts

View workflow job for this annotation

GitHub Actions / Lint: node-22, ubuntu-latest

Type Parameter name `C` must have one of the following prefixes: T

Check failure on line 18 in src/faker8/bind.ts

View workflow job for this annotation

GitHub Actions / Lint: node-22, ubuntu-latest

Type Parameter name `M` must have one of the following prefixes: T
[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

View workflow job for this annotation

GitHub Actions / Lint: node-22, ubuntu-latest

Type Parameter name `C` must have one of the following prefixes: T

Check failure on line 22 in src/faker8/bind.ts

View workflow job for this annotation

GitHub Actions / Lint: node-22, ubuntu-latest

Type Parameter name `M` must have one of the following prefixes: T
[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;
}
53 changes: 53 additions & 0 deletions src/faker8/datatype/index.ts
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 };
54 changes: 54 additions & 0 deletions src/faker8/datatype/number.ts
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);
35 changes: 35 additions & 0 deletions src/faker8/faker.ts
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)
);
}
51 changes: 51 additions & 0 deletions src/faker8/fakerCore.ts
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

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-20, ubuntu-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Timezone Test: node-20, ubuntu-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-18, ubuntu-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-22, ubuntu-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / TS-Check: node-22, ubuntu-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-18, macos-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-20, macos-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-22, macos-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Codecov: node-22, ubuntu-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Check Code Generation: node-22, ubuntu-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-18, windows-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-22, windows-latest

Cannot find module 'src' or its corresponding type declarations.

Check failure on line 1 in src/faker8/fakerCore.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-20, windows-latest

Cannot find module 'src' or its corresponding type declarations.
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
);
25 changes: 25 additions & 0 deletions src/faker8/forkable.ts
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

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-20, ubuntu-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Timezone Test: node-20, ubuntu-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-18, ubuntu-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-22, ubuntu-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / TS-Check: node-22, ubuntu-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-18, macos-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-20, macos-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-22, macos-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Codecov: node-22, ubuntu-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Check Code Generation: node-22, ubuntu-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-18, windows-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-22, windows-latest

Function lacks ending return statement and return type does not include 'undefined'.

Check failure on line 11 in src/faker8/forkable.ts

View workflow job for this annotation

GitHub Actions / Build & Unit Test: node-20, windows-latest

Function lacks ending return statement and return type does not include 'undefined'.
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;
}
}
40 changes: 40 additions & 0 deletions src/faker8/helpers/arrayElement.ts
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
);
Loading

0 comments on commit 779bffc

Please sign in to comment.