aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShinigami <[email protected]>2023-09-18 05:52:42 +0200
committerGitHub <[email protected]>2023-09-18 05:52:42 +0200
commitd6a4f8c2ddf9e957e875bc3fab77e496104d1320 (patch)
tree8c87a5d2baf4dfad8d96da7a4823adaf8bd005ee /src
parentf40e217c6275ab555ecbe3ca0046526e44b31263 (diff)
downloadfaker-d6a4f8c2ddf9e957e875bc3fab77e496104d1320.tar.xz
faker-d6a4f8c2ddf9e957e875bc3fab77e496104d1320.zip
feat: split SimpleFaker class from Faker (#2369)
Diffstat (limited to 'src')
-rw-r--r--src/faker.ts192
-rw-r--r--src/index.ts5
-rw-r--r--src/internal/bind-this-to-member-functions.ts15
-rw-r--r--src/modules/datatype/index.ts4
-rw-r--r--src/modules/date/index.ts216
-rw-r--r--src/modules/helpers/index.ts419
-rw-r--r--src/modules/number/index.ts4
-rw-r--r--src/modules/string/index.ts4
-rw-r--r--src/simple-faker.ts220
9 files changed, 569 insertions, 510 deletions
diff --git a/src/faker.ts b/src/faker.ts
index 9161497e..43811f05 100644
--- a/src/faker.ts
+++ b/src/faker.ts
@@ -1,8 +1,6 @@
import type { LocaleDefinition, MetadataDefinition } from './definitions';
import { FakerError } from './errors/faker-error';
import { deprecated } from './internal/deprecated';
-import type { Mersenne } from './internal/mersenne/mersenne';
-import mersenne from './internal/mersenne/mersenne';
import type { LocaleProxy } from './locale-proxy';
import { createLocaleProxy } from './locale-proxy';
import { AirlineModule } from './modules/airline';
@@ -11,7 +9,6 @@ import { ColorModule } from './modules/color';
import { CommerceModule } from './modules/commerce';
import { CompanyModule } from './modules/company';
import { DatabaseModule } from './modules/database';
-import { DatatypeModule } from './modules/datatype';
import { DateModule } from './modules/date';
import { FinanceModule } from './modules/finance';
import { GitModule } from './modules/git';
@@ -23,16 +20,15 @@ import type { LocationModule as AddressModule } from './modules/location';
import { LocationModule } from './modules/location';
import { LoremModule } from './modules/lorem';
import { MusicModule } from './modules/music';
-import { NumberModule } from './modules/number';
import type { PersonModule as NameModule } from './modules/person';
import { PersonModule } from './modules/person';
import { PhoneModule } from './modules/phone';
import { RandomModule } from './modules/random';
import { ScienceModule } from './modules/science';
-import { StringModule } from './modules/string';
import { SystemModule } from './modules/system';
import { VehicleModule } from './modules/vehicle';
import { WordModule } from './modules/word';
+import { SimpleFaker } from './simple-faker';
import { mergeLocales } from './utils/merge-locales';
/**
@@ -60,61 +56,9 @@ import { mergeLocales } from './utils/merge-locales';
*
* customFaker.music.genre(); // throws Error as this data is not available in `es`
*/
-export class Faker {
+export class Faker extends SimpleFaker {
readonly rawDefinitions: LocaleDefinition;
readonly definitions: LocaleProxy;
- private _defaultRefDate: () => Date = () => new Date();
-
- /**
- * Gets a new reference date used to generate relative dates.
- */
- get defaultRefDate(): () => Date {
- return this._defaultRefDate;
- }
-
- /**
- * Sets the `refDate` source to use if no `refDate` date is passed to the date methods.
- *
- * @param dateOrSource The function or the static value used to generate the `refDate` date instance.
- * The function must return a new valid `Date` instance for every call.
- * Defaults to `() => new Date()`.
- *
- * @see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results)
- * @see faker.seed() for reproducible results.
- *
- * @example
- * faker.seed(1234);
- *
- * // Default behavior
- * // faker.setDefaultRefDate();
- * faker.date.past(); // Changes based on the current date/time
- *
- * // Use a static ref date
- * faker.setDefaultRefDate(new Date('2020-01-01'));
- * faker.date.past(); // Reproducible '2019-07-03T08:27:58.118Z'
- *
- * // Use a ref date that changes every time it is used
- * let clock = new Date("2020-01-01").getTime();
- * faker.setDefaultRefDate(() => {
- * clock += 1000; // +1s
- * return new Date(clock);
- * });
- *
- * faker.defaultRefDate() // 2020-01-01T00:00:01Z
- * faker.defaultRefDate() // 2020-01-01T00:00:02Z
- */
- setDefaultRefDate(
- dateOrSource: string | Date | number | (() => Date) = () => new Date()
- ): void {
- if (typeof dateOrSource === 'function') {
- this._defaultRefDate = dateOrSource;
- } else {
- this._defaultRefDate = () => new Date(dateOrSource);
- }
- }
-
- /** @internal */
- private readonly _mersenne: Mersenne = mersenne();
/**
* @deprecated Use the modules specific to the type of data you want to generate instead.
@@ -122,10 +66,6 @@ export class Faker {
// eslint-disable-next-line deprecation/deprecation
readonly random: RandomModule = new RandomModule(this);
- readonly helpers: HelpersModule = new HelpersModule(this);
-
- readonly datatype: DatatypeModule = new DatatypeModule(this);
-
readonly airline: AirlineModule = new AirlineModule(this);
readonly animal: AnimalModule = new AnimalModule(this);
readonly color: ColorModule = new ColorModule(this);
@@ -136,16 +76,15 @@ export class Faker {
readonly finance = new FinanceModule(this);
readonly git: GitModule = new GitModule(this);
readonly hacker: HackerModule = new HackerModule(this);
+ readonly helpers: HelpersModule = new HelpersModule(this);
readonly image: ImageModule = new ImageModule(this);
readonly internet: InternetModule = new InternetModule(this);
readonly location: LocationModule = new LocationModule(this);
readonly lorem: LoremModule = new LoremModule(this);
readonly music: MusicModule = new MusicModule(this);
readonly person: PersonModule = new PersonModule(this);
- readonly number: NumberModule = new NumberModule(this);
readonly phone: PhoneModule = new PhoneModule(this);
readonly science: ScienceModule = new ScienceModule(this);
- readonly string: StringModule = new StringModule(this);
readonly system: SystemModule = new SystemModule(this);
readonly vehicle: VehicleModule = new VehicleModule(this);
readonly word: WordModule = new WordModule(this);
@@ -299,9 +238,12 @@ export class Faker {
localeFallback?: string;
}
) {
+ super();
+
const { locales } = options as {
locales: Record<string, LocaleDefinition>;
};
+
if (locales != null) {
deprecated({
deprecated:
@@ -337,128 +279,6 @@ export class Faker {
}
/**
- * Sets the seed or generates a new one.
- *
- * Please note that generated values are dependent on both the seed and the
- * number of calls that have been made since it was set.
- *
- * This method is intended to allow for consistent values in tests, so you
- * might want to use hardcoded values as the seed.
- *
- * In addition to that it can be used for creating truly random tests
- * (by passing no arguments), that still can be reproduced if needed,
- * by logging the result and explicitly setting it if needed.
- *
- * @param seed The seed to use. Defaults to a random number.
- *
- * @returns The seed that was set.
- *
- * @see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results)
- * @see faker.setDefaultRefDate() when generating relative dates.
- *
- * @example
- * // Consistent values for tests:
- * faker.seed(42)
- * faker.number.int(10); // 4
- * faker.number.int(10); // 8
- *
- * faker.seed(42)
- * faker.number.int(10); // 4
- * faker.number.int(10); // 8
- *
- * // Random but reproducible tests:
- * // Simply log the seed, and if you need to reproduce it, insert the seed here
- * console.log('Running test with seed:', faker.seed());
- */
- seed(seed?: number): number;
- /**
- * Sets the seed array.
- *
- * Please note that generated values are dependent on both the seed and the
- * number of calls that have been made since it was set.
- *
- * This method is intended to allow for consistent values in a tests, so you
- * might want to use hardcoded values as the seed.
- *
- * In addition to that it can be used for creating truly random tests
- * (by passing no arguments), that still can be reproduced if needed,
- * by logging the result and explicitly setting it if needed.
- *
- * @param seedArray The seed array to use.
- *
- * @returns The seed array that was set.
- *
- * @see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results)
- * @see faker.setDefaultRefDate() when generating relative dates.
- *
- * @example
- * // Consistent values for tests:
- * faker.seed([42, 13, 17])
- * faker.number.int(10); // 4
- * faker.number.int(10); // 8
- *
- * faker.seed([42, 13, 17])
- * faker.number.int(10); // 4
- * faker.number.int(10); // 8
- *
- * // Random but reproducible tests:
- * // Simply log the seed, and if you need to reproduce it, insert the seed here
- * console.log('Running test with seed:', faker.seed());
- */
- seed(seedArray: number[]): number[];
- /**
- * Sets the seed or generates a new one.
- *
- * Please note that generated values are dependent on both the seed and the
- * number of calls that have been made since it was set.
- *
- * This method is intended to allow for consistent values in a tests, so you
- * might want to use hardcoded values as the seed.
- *
- * In addition to that it can be used for creating truly random tests
- * (by passing no arguments), that still can be reproduced if needed,
- * by logging the result and explicitly setting it if needed.
- *
- * @param seed The seed or seed array to use.
- *
- * @returns The seed that was set.
- *
- * @see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results)
- * @see faker.setDefaultRefDate() when generating relative dates.
- *
- * @example
- * // Consistent values for tests (using a number):
- * faker.seed(42)
- * faker.number.int(10); // 4
- * faker.number.int(10); // 8
- *
- * faker.seed(42)
- * faker.number.int(10); // 4
- * faker.number.int(10); // 8
- *
- * // Consistent values for tests (using an array):
- * faker.seed([42, 13, 17])
- * faker.number.int(10); // 4
- * faker.number.int(10); // 8
- *
- * faker.seed([42, 13, 17])
- * faker.number.int(10); // 4
- * faker.number.int(10); // 8
- *
- * // Random but reproducible tests:
- * // Simply log the seed, and if you need to reproduce it, insert the seed here
- * console.log('Running test with seed:', faker.seed());
- */
- seed(seed?: number | number[]): number | number[];
- seed(
- seed: number | number[] = Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER)
- ): number | number[] {
- this._mersenne.seed(seed);
-
- return seed;
- }
-
- /**
* Returns an object with metadata about the current locale.
*
* @example
diff --git a/src/index.ts b/src/index.ts
index a1523bc2..000541b7 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -98,11 +98,11 @@ export type { CommerceModule } from './modules/commerce';
export type { CompanyModule } from './modules/company';
export type { DatabaseModule } from './modules/database';
export type { DatatypeModule } from './modules/datatype';
-export type { DateModule } from './modules/date';
+export type { DateModule, SimpleDateModule } from './modules/date';
export type { Currency, FinanceModule } from './modules/finance';
export type { GitModule } from './modules/git';
export type { HackerModule } from './modules/hacker';
-export type { HelpersModule } from './modules/helpers';
+export type { HelpersModule, SimpleHelpersModule } from './modules/helpers';
export type { ImageModule } from './modules/image';
export type { InternetModule } from './modules/internet';
export type {
@@ -128,4 +128,5 @@ export type { StringModule } from './modules/string';
export type { SystemModule } from './modules/system';
export type { VehicleModule } from './modules/vehicle';
export type { WordModule } from './modules/word';
+export { SimpleFaker, simpleFaker } from './simple-faker';
export { mergeLocales } from './utils/merge-locales';
diff --git a/src/internal/bind-this-to-member-functions.ts b/src/internal/bind-this-to-member-functions.ts
index f2a9d3d5..26b7cfe4 100644
--- a/src/internal/bind-this-to-member-functions.ts
+++ b/src/internal/bind-this-to-member-functions.ts
@@ -15,11 +15,14 @@
export function bindThisToMemberFunctions<TClass extends { new (): any }>(
instance: InstanceType<TClass>
): void {
- for (const name of Object.getOwnPropertyNames(
- Object.getPrototypeOf(instance)
- )) {
- if (typeof instance[name] === 'function' && name !== 'constructor') {
- instance[name] = instance[name].bind(instance);
+ let p = Object.getPrototypeOf(instance);
+ do {
+ for (const name of Object.getOwnPropertyNames(p)) {
+ if (typeof instance[name] === 'function' && name !== 'constructor') {
+ instance[name] = instance[name].bind(instance);
+ }
}
- }
+
+ p = Object.getPrototypeOf(p);
+ } while (p !== Object.prototype);
}
diff --git a/src/modules/datatype/index.ts b/src/modules/datatype/index.ts
index ab6998ae..6f735e0e 100644
--- a/src/modules/datatype/index.ts
+++ b/src/modules/datatype/index.ts
@@ -1,4 +1,4 @@
-import type { Faker } from '../..';
+import type { SimpleFaker } from '../..';
import { bindThisToMemberFunctions } from '../../internal/bind-this-to-member-functions';
import { deprecated } from '../../internal/deprecated';
@@ -12,7 +12,7 @@ import { deprecated } from '../../internal/deprecated';
* For a simple random true or false value, use [`boolean()`](https://fakerjs.dev/api/datatype.html#boolean).
*/
export class DatatypeModule {
- constructor(private readonly faker: Faker) {
+ constructor(private readonly faker: SimpleFaker) {
bindThisToMemberFunctions(this);
}
diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts
index 88680ebf..f63ed452 100644
--- a/src/modules/date/index.ts
+++ b/src/modules/date/index.ts
@@ -1,4 +1,4 @@
-import type { Faker } from '../..';
+import type { Faker, SimpleFaker } from '../..';
import type { DateEntryDefinition } from '../../definitions';
import { FakerError } from '../../errors/faker-error';
import { bindThisToMemberFunctions } from '../../internal/bind-this-to-member-functions';
@@ -23,23 +23,8 @@ function toDate(
return date;
}
-/**
- * Module to generate dates.
- *
- * ### Overview
- *
- * To quickly generate a date in the past, use [`recent()`](https://fakerjs.dev/api/date.html#recent) (last day) or [`past()`](https://fakerjs.dev/api/date.html#past) (last year).
- * To quickly generate a date in the future, use [`soon()`](https://fakerjs.dev/api/date.html#soon) (next day) or [`future()`](https://fakerjs.dev/api/date.html#future) (next year).
- * For a realistic birthdate for an adult, use [`birthdate()`](https://fakerjs.dev/api/date.html#birthdate).
- *
- * For more control, any of these methods can be customized with further options, or use [`between()`](https://fakerjs.dev/api/date.html#between) to generate a single date between two dates, or [`betweens()`](https://fakerjs.dev/api/date.html#betweens) for multiple dates.
- *
- * You can generate random localized month and weekday names using [`month()`](https://fakerjs.dev/api/date.html#month) and [`weekday()`](https://fakerjs.dev/api/date.html#weekday).
- *
- * These methods have additional concerns about reproducibility, see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results).
- */
-export class DateModule {
- constructor(private readonly faker: Faker) {
+export class SimpleDateModule {
+ constructor(protected readonly faker: SimpleFaker) {
bindThisToMemberFunctions(this);
}
@@ -827,6 +812,114 @@ export class DateModule {
}
/**
+ * Returns a random birthdate.
+ *
+ * @param options The options to use to generate the birthdate. If no options are set, an age between 18 and 80 (inclusive) is generated.
+ * @param options.min The minimum age or year to generate a birthdate.
+ * @param options.max The maximum age or year to generate a birthdate.
+ * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `now`.
+ * @param options.mode The mode to generate the birthdate. Supported modes are `'age'` and `'year'` .
+ *
+ * There are two modes available `'age'` and `'year'`:
+ * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`).
+ * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`).
+ *
+ * Defaults to `year`.
+ *
+ * @example
+ * faker.date.birthdate() // 1977-07-10T01:37:30.719Z
+ * faker.date.birthdate({ min: 18, max: 65, mode: 'age' }) // 2003-11-02T20:03:20.116Z
+ * faker.date.birthdate({ min: 1900, max: 2000, mode: 'year' }) // 1940-08-20T08:53:07.538Z
+ *
+ * @since 7.0.0
+ */
+ birthdate(
+ options: {
+ /**
+ * The minimum age or year to generate a birthdate.
+ *
+ * @default 18
+ */
+ min?: number;
+ /**
+ * The maximum age or year to generate a birthdate.
+ *
+ * @default 80
+ */
+ max?: number;
+ /**
+ * The mode to generate the birthdate. Supported modes are `'age'` and `'year'` .
+ *
+ * There are two modes available `'age'` and `'year'`:
+ * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`).
+ * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`).
+ *
+ * @default 'year'
+ */
+ mode?: 'age' | 'year';
+ /**
+ * The date to use as reference point for the newly generated date.
+ *
+ * @default faker.defaultRefDate()
+ */
+ refDate?: string | Date | number;
+ } = {}
+ ): Date {
+ if (options.max < options.min) {
+ throw new FakerError(
+ `Max ${options.max} should be larger than or equal to min ${options.min}.`
+ );
+ }
+
+ const mode = options.mode === 'age' ? 'age' : 'year';
+ const refDate = toDate(options.refDate, this.faker.defaultRefDate);
+ const refYear = refDate.getUTCFullYear();
+
+ // If no min or max is specified, generate a random date between (now - 80) years and (now - 18) years respectively
+ // So that people can still be considered as adults in most cases
+
+ // Convert to epoch timestamps
+ let min: number;
+ let max: number;
+ if (mode === 'age') {
+ min = new Date(refDate).setUTCFullYear(refYear - (options.max ?? 80) - 1);
+ max = new Date(refDate).setUTCFullYear(refYear - (options.min ?? 18));
+ } else {
+ // Avoid generating dates the first and last date of the year
+ // to avoid running into other years depending on the timezone.
+ min = new Date(Date.UTC(0, 0, 2)).setUTCFullYear(
+ options.min ?? refYear - 80
+ );
+ max = new Date(Date.UTC(0, 11, 30)).setUTCFullYear(
+ options.max ?? refYear - 18
+ );
+ }
+
+ return new Date(this.faker.number.int({ min, max }));
+ }
+}
+
+/**
+ * Module to generate dates.
+ *
+ * ### Overview
+ *
+ * To quickly generate a date in the past, use [`recent()`](https://fakerjs.dev/api/date.html#recent) (last day) or [`past()`](https://fakerjs.dev/api/date.html#past) (last year).
+ * To quickly generate a date in the future, use [`soon()`](https://fakerjs.dev/api/date.html#soon) (next day) or [`future()`](https://fakerjs.dev/api/date.html#future) (next year).
+ * For a realistic birthdate for an adult, use [`birthdate()`](https://fakerjs.dev/api/date.html#birthdate).
+ *
+ * For more control, any of these methods can be customized with further options, or use [`between()`](https://fakerjs.dev/api/date.html#between) to generate a single date between two dates, or [`betweens()`](https://fakerjs.dev/api/date.html#betweens) for multiple dates.
+ *
+ * You can generate random localized month and weekday names using [`month()`](https://fakerjs.dev/api/date.html#month) and [`weekday()`](https://fakerjs.dev/api/date.html#weekday).
+ *
+ * These methods have additional concerns about reproducibility, see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results).
+ */
+export class DateModule extends SimpleDateModule {
+ constructor(protected readonly faker: Faker) {
+ super(faker);
+ }
+
+ /**
* Returns a random name of a month.
*
* @param options The optional options to use.
@@ -1204,91 +1297,4 @@ export class DateModule {
return this.faker.helpers.arrayElement(source[type]);
}
-
- /**
- * Returns a random birthdate.
- *
- * @param options The options to use to generate the birthdate. If no options are set, an age between 18 and 80 (inclusive) is generated.
- * @param options.min The minimum age or year to generate a birthdate.
- * @param options.max The maximum age or year to generate a birthdate.
- * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `now`.
- * @param options.mode The mode to generate the birthdate. Supported modes are `'age'` and `'year'` .
- *
- * There are two modes available `'age'` and `'year'`:
- * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`).
- * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`).
- *
- * Defaults to `year`.
- *
- * @example
- * faker.date.birthdate() // 1977-07-10T01:37:30.719Z
- * faker.date.birthdate({ min: 18, max: 65, mode: 'age' }) // 2003-11-02T20:03:20.116Z
- * faker.date.birthdate({ min: 1900, max: 2000, mode: 'year' }) // 1940-08-20T08:53:07.538Z
- *
- * @since 7.0.0
- */
- birthdate(
- options: {
- /**
- * The minimum age or year to generate a birthdate.
- *
- * @default 18
- */
- min?: number;
- /**
- * The maximum age or year to generate a birthdate.
- *
- * @default 80
- */
- max?: number;
- /**
- * The mode to generate the birthdate. Supported modes are `'age'` and `'year'` .
- *
- * There are two modes available `'age'` and `'year'`:
- * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`).
- * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`).
- *
- * @default 'year'
- */
- mode?: 'age' | 'year';
- /**
- * The date to use as reference point for the newly generated date.
- *
- * @default faker.defaultRefDate()
- */
- refDate?: string | Date | number;
- } = {}
- ): Date {
- if (options.max < options.min) {
- throw new FakerError(
- `Max ${options.max} should be larger than or equal to min ${options.min}.`
- );
- }
-
- const mode = options.mode === 'age' ? 'age' : 'year';
- const refDate = toDate(options.refDate, this.faker.defaultRefDate);
- const refYear = refDate.getUTCFullYear();
-
- // If no min or max is specified, generate a random date between (now - 80) years and (now - 18) years respectively
- // So that people can still be considered as adults in most cases
-
- // Convert to epoch timestamps
- let min: number;
- let max: number;
- if (mode === 'age') {
- min = new Date(refDate).setUTCFullYear(refYear - (options.max ?? 80) - 1);
- max = new Date(refDate).setUTCFullYear(refYear - (options.min ?? 18));
- } else {
- // Avoid generating dates the first and last date of the year
- // to avoid running into other years depending on the timezone.
- min = new Date(Date.UTC(0, 0, 2)).setUTCFullYear(
- options.min ?? refYear - 80
- );
- max = new Date(Date.UTC(0, 11, 30)).setUTCFullYear(
- options.max ?? refYear - 18
- );
- }
-
- return new Date(this.faker.number.int({ min, max }));
- }
}
diff --git a/src/modules/helpers/index.ts b/src/modules/helpers/index.ts
index 39b42253..3889c572 100644
--- a/src/modules/helpers/index.ts
+++ b/src/modules/helpers/index.ts
@@ -1,4 +1,4 @@
-import type { Faker } from '../..';
+import type { Faker, SimpleFaker } from '../..';
import { FakerError } from '../../errors/faker-error';
import { bindThisToMemberFunctions } from '../../internal/bind-this-to-member-functions';
import { deprecated } from '../../internal/deprecated';
@@ -24,7 +24,7 @@ import * as uniqueExec from './unique';
* @since 8.0.0
*/
function getRepetitionsBasedOnQuantifierParameters(
- faker: Faker,
+ faker: SimpleFaker,
quantifierSymbol: string,
quantifierMin: string,
quantifierMax: string
@@ -94,7 +94,10 @@ function getRepetitionsBasedOnQuantifierParameters(
*
* @since 5.0.0
*/
-function legacyRegexpStringParse(faker: Faker, string: string = ''): string {
+function legacyRegexpStringParse(
+ faker: SimpleFaker,
+ string: string = ''
+): string {
// Deal with range repeat `{min,max}`
const RANGE_REP_REG = /(.)\{(\d+)\,(\d+)\}/;
const REP_REG = /(.)\{(\d+)\}/;
@@ -155,18 +158,7 @@ function legacyRegexpStringParse(faker: Faker, string: string = ''): string {
return string;
}
-/**
- * Module with various helper methods providing basic (seed-dependent) operations useful for implementing faker methods.
- *
- * ### Overview
- *
- * A particularly helpful method is [`arrayElement()`](https://fakerjs.dev/api/helpers.html#arrayelement) which returns a random element from an array. This is useful when adding custom data that Faker doesn't contain.
- *
- * There are alternatives of this method for objects ([`objectKey()`](https://fakerjs.dev/api/helpers.html#objectkey) and [`objectValue()`](https://fakerjs.dev/api/helpers.html#objectvalue)) and enums ([`enumValue()`](https://fakerjs.dev/api/helpers.html#enumvalue)). You can also return multiple elements ([`arrayElements()`](https://fakerjs.dev/api/helpers.html#arrayelements)) or elements according to a weighting ([`weightedArrayElement()`](https://fakerjs.dev/api/helpers.html#weightedarrayelement)).
- *
- * A number of methods can generate strings according to various patterns: [`replaceSymbols()`](https://fakerjs.dev/api/helpers.html#replacesymbols), [`replaceSymbolWithNumber()`](https://fakerjs.dev/api/helpers.html#replacesymbolwithnumber), and [`fromRegExp()`](https://fakerjs.dev/api/helpers.html#fromregexp).
- */
-export class HelpersModule {
+export class SimpleHelpersModule {
/**
* Global store of unique values.
* This means that faker should *never* return duplicate values across all API methods when using `faker.helpers.unique` without passing `options.store`.
@@ -175,7 +167,7 @@ export class HelpersModule {
*/
private readonly uniqueStore: Record<RecordKey, RecordKey> = {};
- constructor(private readonly faker: Faker) {
+ constructor(protected readonly faker: SimpleFaker) {
bindThisToMemberFunctions(this);
}
@@ -1054,6 +1046,212 @@ export class HelpersModule {
}
/**
+ * Helper method that converts the given number or range to a number.
+ *
+ * @param numberOrRange The number or range to convert.
+ * @param numberOrRange.min The minimum value for the range.
+ * @param numberOrRange.max The maximum value for the range.
+ *
+ * @example
+ * faker.helpers.rangeToNumber(1) // 1
+ * faker.helpers.rangeToNumber({ min: 1, max: 10 }) // 5
+ *
+ * @since 8.0.0
+ */
+ rangeToNumber(
+ numberOrRange:
+ | number
+ | {
+ /**
+ * The minimum value for the range.
+ */
+ min: number;
+ /**
+ * The maximum value for the range.
+ */
+ max: number;
+ }
+ ): number {
+ if (typeof numberOrRange === 'number') {
+ return numberOrRange;
+ }
+
+ return this.faker.number.int(numberOrRange);
+ }
+
+ /**
+ * Generates a unique result using the results of the given method.
+ * Used unique entries will be stored internally and filtered from subsequent calls.
+ *
+ * @template TMethod The type of the method to execute.
+ *
+ * @param method The method used to generate the values.
+ * @param args The arguments used to call the method.
+ * @param options The optional options used to configure this method.
+ * @param options.startTime This parameter does nothing.
+ * @param options.maxTime The time in milliseconds this method may take before throwing an error. Defaults to `50`.
+ * @param options.maxRetries The total number of attempts to try before throwing an error. Defaults to `50`.
+ * @param options.currentIterations This parameter does nothing.
+ * @param options.exclude The value or values that should be excluded/skipped. Defaults to `[]`.
+ * @param options.compare The function used to determine whether a value was already returned. Defaults to check the existence of the key.
+ * @param options.store The store of unique entries. Defaults to a global store.
+ *
+ * @see https://github.com/faker-js/faker/issues/1785#issuecomment-1407773744
+ *
+ * @example
+ * faker.helpers.unique(faker.person.firstName) // 'Corbin'
+ *
+ * @since 7.5.0
+ *
+ * @deprecated Please find a dedicated npm package instead, or even create one on your own if you want to.
+ * More info can be found in issue [faker-js/faker #1785](https://github.com/faker-js/faker/issues/1785).
+ */
+ unique<
+ TMethod extends (
+ // TODO @Shinigami92 2023-02-14: This `any` type can be fixed by anyone if they want to.
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ ...parameters: any[]
+ ) => RecordKey,
+ >(
+ method: TMethod,
+ args: Parameters<TMethod> = [] as Parameters<TMethod>,
+ options: {
+ /**
+ * This parameter does nothing.
+ *
+ * @default new Date().getTime()
+ */
+ startTime?: number;
+ /**
+ * The time in milliseconds this method may take before throwing an error.
+ *
+ * @default 50
+ */
+ maxTime?: number;
+ /**
+ * The total number of attempts to try before throwing an error.
+ *
+ * @default 50
+ */
+ maxRetries?: number;
+ /**
+ * This parameter does nothing.
+ *
+ * @default 0
+ */
+ currentIterations?: number;
+ /**
+ * The value or values that should be excluded/skipped.
+ *
+ * @default []
+ */
+ exclude?: RecordKey | RecordKey[];
+ /**
+ * The function used to determine whether a value was already returned.
+ *
+ * Defaults to check the existence of the key.
+ *
+ * @default (obj, key) => (obj[key] === undefined ? -1 : 0)
+ */
+ compare?: (obj: Record<RecordKey, RecordKey>, key: RecordKey) => 0 | -1;
+ /**
+ * The store of unique entries.
+ *
+ * Defaults to a global store.
+ */
+ store?: Record<RecordKey, RecordKey>;
+ } = {}
+ ): ReturnType<TMethod> {
+ deprecated({
+ deprecated: 'faker.helpers.unique',
+ proposed:
+ 'https://github.com/faker-js/faker/issues/1785#issuecomment-1407773744',
+ since: '8.0',
+ until: '9.0',
+ });
+
+ const {
+ maxTime = 50,
+ maxRetries = 50,
+ exclude = [],
+ store = this.uniqueStore,
+ } = options;
+ return uniqueExec.exec(method, args, {
+ ...options,
+ startTime: new Date().getTime(),
+ maxTime,
+ maxRetries,
+ currentIterations: 0,
+ exclude,
+ store,
+ });
+ }
+
+ /**
+ * Generates an array containing values returned by the given method.
+ *
+ * @template TResult The type of elements.
+ *
+ * @param method The method used to generate the values.
+ * @param options The optional options object.
+ * @param options.count The number or range of elements to generate. Defaults to `3`.
+ *
+ * @example
+ * faker.helpers.multiple(faker.person.firstName) // [ 'Aniya', 'Norval', 'Dallin' ]
+ * faker.helpers.multiple(faker.person.firstName, { count: 3 }) // [ 'Santos', 'Lavinia', 'Lavinia' ]
+ *
+ * @since 8.0.0
+ */
+ multiple<TResult>(
+ method: () => TResult,
+ options: {
+ /**
+ * The number or range of elements to generate.
+ *
+ * @default 3
+ */
+ count?:
+ | number
+ | {
+ /**
+ * The minimum value for the range.
+ */
+ min: number;
+ /**
+ * The maximum value for the range.
+ */
+ max: number;
+ };
+ } = {}
+ ): TResult[] {
+ const count = this.rangeToNumber(options.count ?? 3);
+ if (count <= 0) {
+ return [];
+ }
+
+ // TODO @ST-DDT 2022-11-21: Add support for unique option
+
+ return Array.from({ length: count }, method);
+ }
+}
+
+/**
+ * Module with various helper methods providing basic (seed-dependent) operations useful for implementing faker methods.
+ *
+ * ### Overview
+ *
+ * A particularly helpful method is [`arrayElement()`](https://fakerjs.dev/api/helpers.html#arrayelement) which returns a random element from an array. This is useful when adding custom data that Faker doesn't contain.
+ *
+ * There are alternatives of this method for objects ([`objectKey()`](https://fakerjs.dev/api/helpers.html#objectkey) and [`objectValue()`](https://fakerjs.dev/api/helpers.html#objectvalue)) and enums ([`enumValue()`](https://fakerjs.dev/api/helpers.html#enumvalue)). You can also return multiple elements ([`arrayElements()`](https://fakerjs.dev/api/helpers.html#arrayelements)) or elements according to a weighting ([`weightedArrayElement()`](https://fakerjs.dev/api/helpers.html#weightedarrayelement)).
+ *
+ * A number of methods can generate strings according to various patterns: [`replaceSymbols()`](https://fakerjs.dev/api/helpers.html#replacesymbols), [`replaceSymbolWithNumber()`](https://fakerjs.dev/api/helpers.html#replacesymbolwithnumber), and [`fromRegExp()`](https://fakerjs.dev/api/helpers.html#fromregexp).
+ */
+export class HelpersModule extends SimpleHelpersModule {
+ constructor(protected readonly faker: Faker) {
+ super(faker);
+ }
+
+ /**
* Generator for combining faker methods based on a static string input.
*
* Note: We recommend using string template literals instead of `fake()`,
@@ -1277,193 +1475,4 @@ export class HelpersModule {
// return the response recursively until we are done finding all tags
return this.fake(res);
}
-
- /**
- * Helper method that converts the given number or range to a number.
- *
- * @param numberOrRange The number or range to convert.
- * @param numberOrRange.min The minimum value for the range.
- * @param numberOrRange.max The maximum value for the range.
- *
- * @example
- * faker.helpers.rangeToNumber(1) // 1
- * faker.helpers.rangeToNumber({ min: 1, max: 10 }) // 5
- *
- * @since 8.0.0
- */
- rangeToNumber(
- numberOrRange:
- | number
- | {
- /**
- * The minimum value for the range.
- */
- min: number;
- /**
- * The maximum value for the range.
- */
- max: number;
- }
- ): number {
- if (typeof numberOrRange === 'number') {
- return numberOrRange;
- }
-
- return this.faker.number.int(numberOrRange);
- }
-
- /**
- * Generates a unique result using the results of the given method.
- * Used unique entries will be stored internally and filtered from subsequent calls.
- *
- * @template TMethod The type of the method to execute.
- *
- * @param method The method used to generate the values.
- * @param args The arguments used to call the method.
- * @param options The optional options used to configure this method.
- * @param options.startTime This parameter does nothing.
- * @param options.maxTime The time in milliseconds this method may take before throwing an error. Defaults to `50`.
- * @param options.maxRetries The total number of attempts to try before throwing an error. Defaults to `50`.
- * @param options.currentIterations This parameter does nothing.
- * @param options.exclude The value or values that should be excluded/skipped. Defaults to `[]`.
- * @param options.compare The function used to determine whether a value was already returned. Defaults to check the existence of the key.
- * @param options.store The store of unique entries. Defaults to a global store.
- *
- * @see https://github.com/faker-js/faker/issues/1785#issuecomment-1407773744
- *
- * @example
- * faker.helpers.unique(faker.person.firstName) // 'Corbin'
- *
- * @since 7.5.0
- *
- * @deprecated Please find a dedicated npm package instead, or even create one on your own if you want to.
- * More info can be found in issue [faker-js/faker #1785](https://github.com/faker-js/faker/issues/1785).
- */
- unique<
- TMethod extends (
- // TODO @Shinigami92 2023-02-14: This `any` type can be fixed by anyone if they want to.
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- ...parameters: any[]
- ) => RecordKey,
- >(
- method: TMethod,
- args: Parameters<TMethod> = [] as Parameters<TMethod>,
- options: {
- /**
- * This parameter does nothing.
- *
- * @default new Date().getTime()
- */
- startTime?: number;
- /**
- * The time in milliseconds this method may take before throwing an error.
- *
- * @default 50
- */
- maxTime?: number;
- /**
- * The total number of attempts to try before throwing an error.
- *
- * @default 50
- */
- maxRetries?: number;
- /**
- * This parameter does nothing.
- *
- * @default 0
- */
- currentIterations?: number;
- /**
- * The value or values that should be excluded/skipped.
- *
- * @default []
- */
- exclude?: RecordKey | RecordKey[];
- /**
- * The function used to determine whether a value was already returned.
- *
- * Defaults to check the existence of the key.
- *
- * @default (obj, key) => (obj[key] === undefined ? -1 : 0)
- */
- compare?: (obj: Record<RecordKey, RecordKey>, key: RecordKey) => 0 | -1;
- /**
- * The store of unique entries.
- *
- * Defaults to a global store.
- */
- store?: Record<RecordKey, RecordKey>;
- } = {}
- ): ReturnType<TMethod> {
- deprecated({
- deprecated: 'faker.helpers.unique',
- proposed:
- 'https://github.com/faker-js/faker/issues/1785#issuecomment-1407773744',
- since: '8.0',
- until: '9.0',
- });
-
- const {
- maxTime = 50,
- maxRetries = 50,
- exclude = [],
- store = this.uniqueStore,
- } = options;
- return uniqueExec.exec(method, args, {
- ...options,
- startTime: new Date().getTime(),
- maxTime,
- maxRetries,
- currentIterations: 0,
- exclude,
- store,
- });
- }
-
- /**
- * Generates an array containing values returned by the given method.
- *
- * @template TResult The type of elements.
- *
- * @param method The method used to generate the values.
- * @param options The optional options object.
- * @param options.count The number or range of elements to generate. Defaults to `3`.
- *
- * @example
- * faker.helpers.multiple(faker.person.firstName) // [ 'Aniya', 'Norval', 'Dallin' ]
- * faker.helpers.multiple(faker.person.firstName, { count: 3 }) // [ 'Santos', 'Lavinia', 'Lavinia' ]
- *
- * @since 8.0.0
- */
- multiple<TResult>(
- method: () => TResult,
- options: {
- /**
- * The number or range of elements to generate.
- *
- * @default 3
- */
- count?:
- | number
- | {
- /**
- * The minimum value for the range.
- */
- min: number;
- /**
- * The maximum value for the range.
- */
- max: number;
- };
- } = {}
- ): TResult[] {
- const count = this.rangeToNumber(options.count ?? 3);
- if (count <= 0) {
- return [];
- }
-
- // TODO @ST-DDT 2022-11-21: Add support for unique option
-
- return Array.from({ length: count }, method);
- }
}
diff --git a/src/modules/number/index.ts b/src/modules/number/index.ts
index 6e0774e1..a2e64724 100644
--- a/src/modules/number/index.ts
+++ b/src/modules/number/index.ts
@@ -1,4 +1,4 @@
-import type { Faker } from '../..';
+import type { SimpleFaker } from '../..';
import { FakerError } from '../../errors/faker-error';
import { bindThisToMemberFunctions } from '../../internal/bind-this-to-member-functions';
import type { Mersenne } from '../../internal/mersenne/mersenne';
@@ -18,7 +18,7 @@ import type { Mersenne } from '../../internal/mersenne/mersenne';
* - For credit card numbers, use [`faker.finance.creditCardNumber()`](https://fakerjs.dev/api/finance.html#creditcardnumber).
*/
export class NumberModule {
- constructor(private readonly faker: Faker) {
+ constructor(private readonly faker: SimpleFaker) {
bindThisToMemberFunctions(this);
}
diff --git a/src/modules/string/index.ts b/src/modules/string/index.ts
index 536a1c6a..8167ebea 100644
--- a/src/modules/string/index.ts
+++ b/src/modules/string/index.ts
@@ -1,4 +1,4 @@
-import type { Faker } from '../..';
+import type { SimpleFaker } from '../..';
import { FakerError } from '../../errors/faker-error';
import { bindThisToMemberFunctions } from '../../internal/bind-this-to-member-functions';
import type { LiteralUnion } from '../../utils/types';
@@ -103,7 +103,7 @@ const SAMPLE_MAX_LENGTH = 2 ** 20;
* - The [`faker.helpers`](https://fakerjs.dev/api/helpers.html) module includes a number of string related methods.
*/
export class StringModule {
- constructor(private readonly faker: Faker) {
+ constructor(private readonly faker: SimpleFaker) {
bindThisToMemberFunctions(this);
}
diff --git a/src/simple-faker.ts b/src/simple-faker.ts
new file mode 100644
index 00000000..c4ecb8df
--- /dev/null
+++ b/src/simple-faker.ts
@@ -0,0 +1,220 @@
+import type { Mersenne } from './internal/mersenne/mersenne';
+import mersenne from './internal/mersenne/mersenne';
+import { DatatypeModule } from './modules/datatype';
+import { SimpleDateModule } from './modules/date';
+import { SimpleHelpersModule } from './modules/helpers';
+import { NumberModule } from './modules/number';
+import { StringModule } from './modules/string';
+
+/**
+ * This is a simplified Faker class that doesn't need any localized data to generate its output.
+ *
+ * It only includes methods from:
+ * - `datatype`
+ * - `date` (without `month` and `weekday`)
+ * - `helpers` (without `fake`)
+ * - `number`
+ * - `string`
+ *
+ * @example
+ * import { simpleFaker } from '@faker-js/faker';
+ * // const { simpleFaker } = require('@faker-js/faker');
+ *
+ * // simpleFaker.seed(1234);
+ *
+ * simpleFaker.number.int(10); // 4
+ * simpleFaker.string.uuid(); // 'c50e1f5c-86e8-4aa9-888e-168e0a182519'
+ */
+export class SimpleFaker {
+ protected _defaultRefDate: () => Date = () => new Date();
+
+ /**
+ * Gets a new reference date used to generate relative dates.
+ */
+ get defaultRefDate(): () => Date {
+ return this._defaultRefDate;
+ }
+
+ /**
+ * Sets the `refDate` source to use if no `refDate` date is passed to the date methods.
+ *
+ * @param dateOrSource The function or the static value used to generate the `refDate` date instance.
+ * The function must return a new valid `Date` instance for every call.
+ * Defaults to `() => new Date()`.
+ *
+ * @see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results)
+ * @see faker.seed() for reproducible results.
+ *
+ * @example
+ * faker.seed(1234);
+ *
+ * // Default behavior
+ * // faker.setDefaultRefDate();
+ * faker.date.past(); // Changes based on the current date/time
+ *
+ * // Use a static ref date
+ * faker.setDefaultRefDate(new Date('2020-01-01'));
+ * faker.date.past(); // Reproducible '2019-07-03T08:27:58.118Z'
+ *
+ * // Use a ref date that changes every time it is used
+ * let clock = new Date("2020-01-01").getTime();
+ * faker.setDefaultRefDate(() => {
+ * clock += 1000; // +1s
+ * return new Date(clock);
+ * });
+ *
+ * faker.defaultRefDate() // 2020-01-01T00:00:01Z
+ * faker.defaultRefDate() // 2020-01-01T00:00:02Z
+ */
+ setDefaultRefDate(
+ dateOrSource: string | Date | number | (() => Date) = () => new Date()
+ ): void {
+ if (typeof dateOrSource === 'function') {
+ this._defaultRefDate = dateOrSource;
+ } else {
+ this._defaultRefDate = () => new Date(dateOrSource);
+ }
+ }
+
+ /** @internal */
+ private readonly _mersenne: Mersenne = mersenne();
+
+ readonly datatype: DatatypeModule = new DatatypeModule(this);
+ readonly date: SimpleDateModule = new SimpleDateModule(this);
+ readonly helpers: SimpleHelpersModule = new SimpleHelpersModule(this);
+ readonly number: NumberModule = new NumberModule(this);
+ readonly string: StringModule = new StringModule(this);
+
+ /**
+ * Creates a new instance of SimpleFaker.
+ *
+ * In nearly any case you should use the prebuilt `simpleFaker` instances instead of the constructor.
+ */
+ constructor() {
+ // This empty constructor just exists for VitePress docs
+ }
+
+ /**
+ * Sets the seed or generates a new one.
+ *
+ * Please note that generated values are dependent on both the seed and the
+ * number of calls that have been made since it was set.
+ *
+ * This method is intended to allow for consistent values in tests, so you
+ * might want to use hardcoded values as the seed.
+ *
+ * In addition to that it can be used for creating truly random tests
+ * (by passing no arguments), that still can be reproduced if needed,
+ * by logging the result and explicitly setting it if needed.
+ *
+ * @param seed The seed to use. Defaults to a random number.
+ *
+ * @returns The seed that was set.
+ *
+ * @see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results)
+ * @see faker.setDefaultRefDate() when generating relative dates.
+ *
+ * @example
+ * // Consistent values for tests:
+ * faker.seed(42)
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
+ *
+ * faker.seed(42)
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
+ *
+ * // Random but reproducible tests:
+ * // Simply log the seed, and if you need to reproduce it, insert the seed here
+ * console.log('Running test with seed:', faker.seed());
+ */
+ seed(seed?: number): number;
+ /**
+ * Sets the seed array.
+ *
+ * Please note that generated values are dependent on both the seed and the
+ * number of calls that have been made since it was set.
+ *
+ * This method is intended to allow for consistent values in a tests, so you
+ * might want to use hardcoded values as the seed.
+ *
+ * In addition to that it can be used for creating truly random tests
+ * (by passing no arguments), that still can be reproduced if needed,
+ * by logging the result and explicitly setting it if needed.
+ *
+ * @param seedArray The seed array to use.
+ *
+ * @returns The seed array that was set.
+ *
+ * @see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results)
+ * @see faker.setDefaultRefDate() when generating relative dates.
+ *
+ * @example
+ * // Consistent values for tests:
+ * faker.seed([42, 13, 17])
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
+ *
+ * faker.seed([42, 13, 17])
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
+ *
+ * // Random but reproducible tests:
+ * // Simply log the seed, and if you need to reproduce it, insert the seed here
+ * console.log('Running test with seed:', faker.seed());
+ */
+ seed(seedArray: number[]): number[];
+ /**
+ * Sets the seed or generates a new one.
+ *
+ * Please note that generated values are dependent on both the seed and the
+ * number of calls that have been made since it was set.
+ *
+ * This method is intended to allow for consistent values in a tests, so you
+ * might want to use hardcoded values as the seed.
+ *
+ * In addition to that it can be used for creating truly random tests
+ * (by passing no arguments), that still can be reproduced if needed,
+ * by logging the result and explicitly setting it if needed.
+ *
+ * @param seed The seed or seed array to use.
+ *
+ * @returns The seed that was set.
+ *
+ * @see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results)
+ * @see faker.setDefaultRefDate() when generating relative dates.
+ *
+ * @example
+ * // Consistent values for tests (using a number):
+ * faker.seed(42)
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
+ *
+ * faker.seed(42)
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
+ *
+ * // Consistent values for tests (using an array):
+ * faker.seed([42, 13, 17])
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
+ *
+ * faker.seed([42, 13, 17])
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
+ *
+ * // Random but reproducible tests:
+ * // Simply log the seed, and if you need to reproduce it, insert the seed here
+ * console.log('Running test with seed:', faker.seed());
+ */
+ seed(seed?: number | number[]): number | number[];
+ seed(
+ seed: number | number[] = Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER)
+ ): number | number[] {
+ this._mersenne.seed(seed);
+
+ return seed;
+ }
+}
+
+export const simpleFaker = new SimpleFaker();