@anil-labs/factory 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -0
- package/LICENSE +21 -0
- package/README.md +371 -0
- package/dist/builders/index.d.cts +40 -0
- package/dist/builders/index.d.ts +40 -0
- package/dist/chunks/faker-BOtDMmjd.cjs +1430 -0
- package/dist/chunks/faker-BOtDMmjd.cjs.map +1 -0
- package/dist/chunks/faker-BlEhpR26.mjs +1287 -0
- package/dist/chunks/faker-BlEhpR26.mjs.map +1 -0
- package/dist/chunks/persist-DcARfeC-.cjs +134 -0
- package/dist/chunks/persist-DcARfeC-.cjs.map +1 -0
- package/dist/chunks/persist-ZGX3NWMF.mjs +117 -0
- package/dist/chunks/persist-ZGX3NWMF.mjs.map +1 -0
- package/dist/core/collection.d.cts +41 -0
- package/dist/core/collection.d.ts +41 -0
- package/dist/core/factory.d.cts +115 -0
- package/dist/core/factory.d.ts +115 -0
- package/dist/core/index.d.cts +6 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/registry.d.cts +20 -0
- package/dist/core/registry.d.ts +20 -0
- package/dist/core/sequence.d.cts +36 -0
- package/dist/core/sequence.d.ts +36 -0
- package/dist/core/types.d.cts +47 -0
- package/dist/core/types.d.ts +47 -0
- package/dist/faker/color.d.cts +22 -0
- package/dist/faker/color.d.ts +22 -0
- package/dist/faker/commerce.d.cts +21 -0
- package/dist/faker/commerce.d.ts +21 -0
- package/dist/faker/company.d.cts +20 -0
- package/dist/faker/company.d.ts +20 -0
- package/dist/faker/datatype.d.cts +16 -0
- package/dist/faker/datatype.d.ts +16 -0
- package/dist/faker/date.d.cts +29 -0
- package/dist/faker/date.d.ts +29 -0
- package/dist/faker/faker.d.cts +82 -0
- package/dist/faker/faker.d.ts +82 -0
- package/dist/faker/finance.d.cts +25 -0
- package/dist/faker/finance.d.ts +25 -0
- package/dist/faker/helpers.d.cts +52 -0
- package/dist/faker/helpers.d.ts +52 -0
- package/dist/faker/image.d.cts +22 -0
- package/dist/faker/image.d.ts +22 -0
- package/dist/faker/index.d.cts +21 -0
- package/dist/faker/index.d.ts +21 -0
- package/dist/faker/internet.d.cts +33 -0
- package/dist/faker/internet.d.ts +33 -0
- package/dist/faker/locale.d.cts +26 -0
- package/dist/faker/locale.d.ts +26 -0
- package/dist/faker/location.d.cts +30 -0
- package/dist/faker/location.d.ts +30 -0
- package/dist/faker/lorem.d.cts +26 -0
- package/dist/faker/lorem.d.ts +26 -0
- package/dist/faker/number.d.cts +31 -0
- package/dist/faker/number.d.ts +31 -0
- package/dist/faker/person.d.cts +29 -0
- package/dist/faker/person.d.ts +29 -0
- package/dist/faker/regex.d.cts +19 -0
- package/dist/faker/regex.d.ts +19 -0
- package/dist/faker/string.d.cts +33 -0
- package/dist/faker/string.d.ts +33 -0
- package/dist/faker/system.d.cts +29 -0
- package/dist/faker/system.d.ts +29 -0
- package/dist/faker.cjs +26 -0
- package/dist/faker.mjs +3 -0
- package/dist/index.cjs +635 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +37 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.mjs +596 -0
- package/dist/index.mjs.map +1 -0
- package/dist/locales/en.cjs +351 -0
- package/dist/locales/en.cjs.map +1 -0
- package/dist/locales/en.d.cts +11 -0
- package/dist/locales/en.d.ts +11 -0
- package/dist/locales/en.mjs +350 -0
- package/dist/locales/en.mjs.map +1 -0
- package/dist/locales/types.d.cts +30 -0
- package/dist/locales/types.d.ts +30 -0
- package/dist/persist/console.d.cts +15 -0
- package/dist/persist/console.d.ts +15 -0
- package/dist/persist/http.d.cts +42 -0
- package/dist/persist/http.d.ts +42 -0
- package/dist/persist/index.d.cts +5 -0
- package/dist/persist/index.d.ts +5 -0
- package/dist/persist/memory.d.cts +26 -0
- package/dist/persist/memory.d.ts +26 -0
- package/dist/persist.cjs +5 -0
- package/dist/persist.mjs +2 -0
- package/dist/prng/index.d.cts +5 -0
- package/dist/prng/index.d.ts +5 -0
- package/dist/prng/mulberry32.d.cts +19 -0
- package/dist/prng/mulberry32.d.ts +19 -0
- package/dist/prng/types.d.cts +23 -0
- package/dist/prng/types.d.ts +23 -0
- package/dist/snapshot/index.d.cts +16 -0
- package/dist/snapshot/index.d.ts +16 -0
- package/package.json +136 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { Collection } from './collection';
|
|
2
|
+
import { Sequence, SequenceEntry } from './sequence';
|
|
3
|
+
import { Definition, Hook, Persist, StateValue } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Laravel-inspired model factory for TypeScript. Immutable fluent chain — every
|
|
6
|
+
* method returns a new factory, never mutating the original.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* interface User { id: number; name: string; email: string; active: boolean }
|
|
11
|
+
*
|
|
12
|
+
* const UserFactory = defineFactory<User>(({ seq, faker }) => ({
|
|
13
|
+
* id: seq,
|
|
14
|
+
* name: faker.person.fullName(),
|
|
15
|
+
* email: faker.internet.email(),
|
|
16
|
+
* active: true,
|
|
17
|
+
* }))
|
|
18
|
+
* .state('admin', { role: 'admin' })
|
|
19
|
+
* .state('inactive', { active: false })
|
|
20
|
+
*
|
|
21
|
+
* UserFactory.make() // single User
|
|
22
|
+
* UserFactory.count(5).make() // User[]
|
|
23
|
+
* UserFactory.state('admin').make() // with admin overrides
|
|
24
|
+
* await UserFactory.persist(...).create()
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare class Factory<T extends object> {
|
|
28
|
+
/** @internal */ private readonly definition;
|
|
29
|
+
/** @internal */ private readonly internals;
|
|
30
|
+
/** @internal — use {@link defineFactory} or {@link Factory.define} instead. */
|
|
31
|
+
private constructor();
|
|
32
|
+
/** Create a new factory. Mirrors Laravel's `Factory::new()`. */
|
|
33
|
+
static define<T extends object>(definition: Definition<T>, persist?: Persist<T>): Factory<T>;
|
|
34
|
+
/** Internal: build a copy with a single field replaced. */
|
|
35
|
+
private clone;
|
|
36
|
+
/** Set how many items will be built on the next terminal call. */
|
|
37
|
+
count(n: number): Factory<T>;
|
|
38
|
+
/** Alias of {@link count} — matches Laravel's `->times()`. */
|
|
39
|
+
times(n: number): Factory<T>;
|
|
40
|
+
/** Merge inline overrides into every built item. */
|
|
41
|
+
with(overrides: Partial<T>): Factory<T>;
|
|
42
|
+
/**
|
|
43
|
+
* Register a named state OR activate a previously-registered state.
|
|
44
|
+
*
|
|
45
|
+
* - Two-arg form (`state(name, value)`) **registers** the state.
|
|
46
|
+
* - One-arg form (`state(name)`) **activates** it.
|
|
47
|
+
* - One-arg with a Sequence (`state(seq)`) attaches a sequence as a state.
|
|
48
|
+
*/
|
|
49
|
+
state(arg1: string | Sequence<T>, value?: StateValue<T>): Factory<T>;
|
|
50
|
+
/** Bulk-register multiple states. */
|
|
51
|
+
states(map: Record<string, StateValue<T>>): Factory<T>;
|
|
52
|
+
/** Cycle values through one field across generated items. */
|
|
53
|
+
fieldSequence<K extends keyof T>(field: K, values: readonly T[K][]): Factory<T>;
|
|
54
|
+
/** Attach a sequence of attribute patches. */
|
|
55
|
+
sequence(entries: readonly SequenceEntry<T>[]): Factory<T>;
|
|
56
|
+
/** Attach child records under `key` (one-to-many). */
|
|
57
|
+
has<C extends object>(childFactory: Factory<C>, key: keyof T | string): Factory<T>;
|
|
58
|
+
/**
|
|
59
|
+
* Set a foreign-key field by either resolving from another factory
|
|
60
|
+
* (eager — built once), a plain object (used directly), or a lazy callback
|
|
61
|
+
* (built per-item).
|
|
62
|
+
*/
|
|
63
|
+
for<P extends object>(parent: Factory<P> | P | (() => P), foreignKey: keyof T | string, resolver?: (parent: P) => Partial<T>): Factory<T>;
|
|
64
|
+
/** Attach related records with pivot/intermediate data (many-to-many). */
|
|
65
|
+
hasAttached<C extends object>(childFactory: Factory<C>, key: keyof T | string, pivot?: Record<string, unknown> | ((parent: T, child: C) => Record<string, unknown>)): Factory<T>;
|
|
66
|
+
/** Add models to the recycle pool keyed by `key`. */
|
|
67
|
+
recycle<M extends object>(models: M | readonly M[], key: string): Factory<T>;
|
|
68
|
+
/** Pick a random recycled model from `key`, or undefined. */
|
|
69
|
+
getRecycled(key: string): object | undefined;
|
|
70
|
+
/** Register a hook fired after each item is built. */
|
|
71
|
+
afterMaking(fn: Hook<T>): Factory<T>;
|
|
72
|
+
/** Register a hook fired after each item is persisted via `create()`. */
|
|
73
|
+
afterCreating(fn: Hook<T>): Factory<T>;
|
|
74
|
+
/** Set or replace the persistence callback used by `create()`. */
|
|
75
|
+
persist(fn: Persist<T>): Factory<T>;
|
|
76
|
+
/**
|
|
77
|
+
* Bind this factory to its own private `Faker` instance, seeded as given.
|
|
78
|
+
* Useful when one factory in a suite must be deterministic without
|
|
79
|
+
* affecting the shared default faker.
|
|
80
|
+
*/
|
|
81
|
+
seed(seed: number): Factory<T>;
|
|
82
|
+
/** Set the locale on this factory's faker (creates one if it was shared). */
|
|
83
|
+
locale(name: string): Factory<T>;
|
|
84
|
+
/** Build a single item (ignoring `count`). */
|
|
85
|
+
makeOne(): T;
|
|
86
|
+
/** Build `count` items. */
|
|
87
|
+
makeMany(): T[];
|
|
88
|
+
/**
|
|
89
|
+
* Build — single item when `count === 1`, array otherwise.
|
|
90
|
+
* Use {@link makeOne} / {@link makeMany} when you need a specific shape.
|
|
91
|
+
*/
|
|
92
|
+
make(): T | T[];
|
|
93
|
+
/** Raw attribute objects with the same shape as `make()`. */
|
|
94
|
+
raw(): T | T[];
|
|
95
|
+
/** Build and return as a {@link Collection}. */
|
|
96
|
+
collect(): Collection<T>;
|
|
97
|
+
/**
|
|
98
|
+
* Build and persist via the registered persistence callback.
|
|
99
|
+
* Returns single item when `count === 1`, array otherwise.
|
|
100
|
+
*/
|
|
101
|
+
create(): Promise<T | T[]>;
|
|
102
|
+
/** Always-array variant of {@link create}. */
|
|
103
|
+
createMany(): Promise<T[]>;
|
|
104
|
+
private buildOne;
|
|
105
|
+
private buildMany;
|
|
106
|
+
/**
|
|
107
|
+
* Fire afterMaking hooks for the sync build path (`make`/`makeOne`/`makeMany`/
|
|
108
|
+
* `collect`). Async hooks are kicked off without awaiting — use {@link create}
|
|
109
|
+
* if you need guaranteed sequencing.
|
|
110
|
+
*/
|
|
111
|
+
private fireAfterMakingSync;
|
|
112
|
+
private runHooks;
|
|
113
|
+
}
|
|
114
|
+
/** Functional alias for `Factory.define()`. */
|
|
115
|
+
export declare function defineFactory<T extends object>(definition: Definition<T>, persist?: Persist<T>): Factory<T>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Factory, defineFactory } from './factory';
|
|
2
|
+
export { Sequence, sequence } from './sequence';
|
|
3
|
+
export type { SequenceEntry, SequenceInfo } from './sequence';
|
|
4
|
+
export { Collection } from './collection';
|
|
5
|
+
export { FactoryRegistry } from './registry';
|
|
6
|
+
export type { BuildContext, Definition, Hook, HasAttachedRelation, HasRelation, Persist, StateFn, StateValue, } from './types';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Factory, defineFactory } from './factory';
|
|
2
|
+
export { Sequence, sequence } from './sequence';
|
|
3
|
+
export type { SequenceEntry, SequenceInfo } from './sequence';
|
|
4
|
+
export { Collection } from './collection';
|
|
5
|
+
export { FactoryRegistry } from './registry';
|
|
6
|
+
export type { BuildContext, Definition, Hook, HasAttachedRelation, HasRelation, Persist, StateFn, StateValue, } from './types';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Factory } from './factory';
|
|
2
|
+
/**
|
|
3
|
+
* Process-global registry that lets you look up factories by name.
|
|
4
|
+
* Mirrors how Laravel resolves `UserFactory` from `User::factory()`.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* FactoryRegistry.register('User', UserFactory)
|
|
9
|
+
* const f = FactoryRegistry.resolve<User>('User')
|
|
10
|
+
* f.count(5).make()
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export declare const FactoryRegistry: {
|
|
14
|
+
register<T extends object>(name: string, factory: Factory<T>): void;
|
|
15
|
+
resolve<T extends object>(name: string): Factory<T>;
|
|
16
|
+
has(name: string): boolean;
|
|
17
|
+
unregister(name: string): boolean;
|
|
18
|
+
clear(): void;
|
|
19
|
+
names(): string[];
|
|
20
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Factory } from './factory';
|
|
2
|
+
/**
|
|
3
|
+
* Process-global registry that lets you look up factories by name.
|
|
4
|
+
* Mirrors how Laravel resolves `UserFactory` from `User::factory()`.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* FactoryRegistry.register('User', UserFactory)
|
|
9
|
+
* const f = FactoryRegistry.resolve<User>('User')
|
|
10
|
+
* f.count(5).make()
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export declare const FactoryRegistry: {
|
|
14
|
+
register<T extends object>(name: string, factory: Factory<T>): void;
|
|
15
|
+
resolve<T extends object>(name: string): Factory<T>;
|
|
16
|
+
has(name: string): boolean;
|
|
17
|
+
unregister(name: string): boolean;
|
|
18
|
+
clear(): void;
|
|
19
|
+
names(): string[];
|
|
20
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Info passed to closure-style sequence entries. */
|
|
2
|
+
export interface SequenceInfo {
|
|
3
|
+
/** One-based count (index + 1). */
|
|
4
|
+
readonly count: number;
|
|
5
|
+
/** Zero-based index of this draw. */
|
|
6
|
+
readonly index: number;
|
|
7
|
+
}
|
|
8
|
+
/** An entry is either a literal patch or a function receiving the index info. */
|
|
9
|
+
export type SequenceEntry<T> = Partial<T> | ((info: SequenceInfo) => Partial<T>);
|
|
10
|
+
/**
|
|
11
|
+
* Cycle through a list of attribute patches across generated items.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* factory.sequence([{ role: 'admin' }, { role: 'editor' }]).count(4).make()
|
|
16
|
+
* // → admin, editor, admin, editor
|
|
17
|
+
*
|
|
18
|
+
* factory.sequence([({ index }) => ({ name: `User ${index}` })]).count(3).make()
|
|
19
|
+
* // → User 0, User 1, User 2
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class Sequence<T extends object = object> {
|
|
23
|
+
private cursor;
|
|
24
|
+
private readonly entries;
|
|
25
|
+
constructor(entries: readonly SequenceEntry<T>[]);
|
|
26
|
+
/** Resolve the next patch, cycling when exhausted. */
|
|
27
|
+
next(): Partial<T>;
|
|
28
|
+
/** Reset the cursor to 0. */
|
|
29
|
+
reset(): this;
|
|
30
|
+
/** Current cursor position (zero-based). */
|
|
31
|
+
get currentIndex(): number;
|
|
32
|
+
/** Return a fresh sequence with the same entries but cursor reset. */
|
|
33
|
+
clone(): Sequence<T>;
|
|
34
|
+
}
|
|
35
|
+
/** Functional shorthand for `new Sequence(entries)`. */
|
|
36
|
+
export declare function sequence<T extends object = object>(entries: readonly SequenceEntry<T>[]): Sequence<T>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Info passed to closure-style sequence entries. */
|
|
2
|
+
export interface SequenceInfo {
|
|
3
|
+
/** One-based count (index + 1). */
|
|
4
|
+
readonly count: number;
|
|
5
|
+
/** Zero-based index of this draw. */
|
|
6
|
+
readonly index: number;
|
|
7
|
+
}
|
|
8
|
+
/** An entry is either a literal patch or a function receiving the index info. */
|
|
9
|
+
export type SequenceEntry<T> = Partial<T> | ((info: SequenceInfo) => Partial<T>);
|
|
10
|
+
/**
|
|
11
|
+
* Cycle through a list of attribute patches across generated items.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* factory.sequence([{ role: 'admin' }, { role: 'editor' }]).count(4).make()
|
|
16
|
+
* // → admin, editor, admin, editor
|
|
17
|
+
*
|
|
18
|
+
* factory.sequence([({ index }) => ({ name: `User ${index}` })]).count(3).make()
|
|
19
|
+
* // → User 0, User 1, User 2
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class Sequence<T extends object = object> {
|
|
23
|
+
private cursor;
|
|
24
|
+
private readonly entries;
|
|
25
|
+
constructor(entries: readonly SequenceEntry<T>[]);
|
|
26
|
+
/** Resolve the next patch, cycling when exhausted. */
|
|
27
|
+
next(): Partial<T>;
|
|
28
|
+
/** Reset the cursor to 0. */
|
|
29
|
+
reset(): this;
|
|
30
|
+
/** Current cursor position (zero-based). */
|
|
31
|
+
get currentIndex(): number;
|
|
32
|
+
/** Return a fresh sequence with the same entries but cursor reset. */
|
|
33
|
+
clone(): Sequence<T>;
|
|
34
|
+
}
|
|
35
|
+
/** Functional shorthand for `new Sequence(entries)`. */
|
|
36
|
+
export declare function sequence<T extends object = object>(entries: readonly SequenceEntry<T>[]): Sequence<T>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Faker } from '../faker';
|
|
2
|
+
/** Context passed to definition + state callbacks. */
|
|
3
|
+
export interface BuildContext {
|
|
4
|
+
/** Shared faker instance — already seeded if the factory was. */
|
|
5
|
+
readonly faker: Faker;
|
|
6
|
+
/** One-based item index for this build. */
|
|
7
|
+
readonly seq: number;
|
|
8
|
+
}
|
|
9
|
+
/** Factory definition: returns the base attributes for a single item. */
|
|
10
|
+
export type Definition<T> = (ctx: BuildContext) => T;
|
|
11
|
+
/** State function: returns an attribute patch to merge over the base. */
|
|
12
|
+
export type StateFn<T> = (attrs: T, ctx: BuildContext) => Partial<T>;
|
|
13
|
+
/** State value — either an inline patch or a function returning one. */
|
|
14
|
+
export type StateValue<T> = Partial<T> | StateFn<T>;
|
|
15
|
+
/** Persistence callback used by `create()`. */
|
|
16
|
+
export type Persist<T> = (item: T) => T | Promise<T>;
|
|
17
|
+
/** Lifecycle hook — may be sync or async. */
|
|
18
|
+
export type Hook<T> = (item: T, index: number) => void | Promise<void>;
|
|
19
|
+
/** Relation descriptor for `has()`. */
|
|
20
|
+
export interface HasRelation<P, C> {
|
|
21
|
+
readonly count: number;
|
|
22
|
+
readonly factory: {
|
|
23
|
+
make(): C[];
|
|
24
|
+
} & {
|
|
25
|
+
count(n: number): {
|
|
26
|
+
make(): C[];
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
readonly key: keyof P | string;
|
|
30
|
+
readonly kind: 'has';
|
|
31
|
+
}
|
|
32
|
+
/** Relation descriptor for `hasAttached()`. */
|
|
33
|
+
export interface HasAttachedRelation<P, C> {
|
|
34
|
+
readonly count: number;
|
|
35
|
+
readonly factory: {
|
|
36
|
+
make(): C[];
|
|
37
|
+
} & {
|
|
38
|
+
count(n: number): {
|
|
39
|
+
make(): C[];
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
readonly key: keyof P | string;
|
|
43
|
+
readonly kind: 'hasAttached';
|
|
44
|
+
readonly pivot: Partial<Record<string, unknown>> | ((parent: P, child: C) => Record<string, unknown>);
|
|
45
|
+
}
|
|
46
|
+
/** Pool of recyclable model instances, keyed by an arbitrary string. */
|
|
47
|
+
export type RecyclePool = ReadonlyMap<string, readonly object[]>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Faker } from '../faker';
|
|
2
|
+
/** Context passed to definition + state callbacks. */
|
|
3
|
+
export interface BuildContext {
|
|
4
|
+
/** Shared faker instance — already seeded if the factory was. */
|
|
5
|
+
readonly faker: Faker;
|
|
6
|
+
/** One-based item index for this build. */
|
|
7
|
+
readonly seq: number;
|
|
8
|
+
}
|
|
9
|
+
/** Factory definition: returns the base attributes for a single item. */
|
|
10
|
+
export type Definition<T> = (ctx: BuildContext) => T;
|
|
11
|
+
/** State function: returns an attribute patch to merge over the base. */
|
|
12
|
+
export type StateFn<T> = (attrs: T, ctx: BuildContext) => Partial<T>;
|
|
13
|
+
/** State value — either an inline patch or a function returning one. */
|
|
14
|
+
export type StateValue<T> = Partial<T> | StateFn<T>;
|
|
15
|
+
/** Persistence callback used by `create()`. */
|
|
16
|
+
export type Persist<T> = (item: T) => T | Promise<T>;
|
|
17
|
+
/** Lifecycle hook — may be sync or async. */
|
|
18
|
+
export type Hook<T> = (item: T, index: number) => void | Promise<void>;
|
|
19
|
+
/** Relation descriptor for `has()`. */
|
|
20
|
+
export interface HasRelation<P, C> {
|
|
21
|
+
readonly count: number;
|
|
22
|
+
readonly factory: {
|
|
23
|
+
make(): C[];
|
|
24
|
+
} & {
|
|
25
|
+
count(n: number): {
|
|
26
|
+
make(): C[];
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
readonly key: keyof P | string;
|
|
30
|
+
readonly kind: 'has';
|
|
31
|
+
}
|
|
32
|
+
/** Relation descriptor for `hasAttached()`. */
|
|
33
|
+
export interface HasAttachedRelation<P, C> {
|
|
34
|
+
readonly count: number;
|
|
35
|
+
readonly factory: {
|
|
36
|
+
make(): C[];
|
|
37
|
+
} & {
|
|
38
|
+
count(n: number): {
|
|
39
|
+
make(): C[];
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
readonly key: keyof P | string;
|
|
43
|
+
readonly kind: 'hasAttached';
|
|
44
|
+
readonly pivot: Partial<Record<string, unknown>> | ((parent: P, child: C) => Record<string, unknown>);
|
|
45
|
+
}
|
|
46
|
+
/** Pool of recyclable model instances, keyed by an arbitrary string. */
|
|
47
|
+
export type RecyclePool = ReadonlyMap<string, readonly object[]>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
import { LocaleRef } from './locale';
|
|
3
|
+
/**
|
|
4
|
+
* Color generators.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* faker.color.name() // "amber"
|
|
9
|
+
* faker.color.hex() // "#3f8ad5"
|
|
10
|
+
* faker.color.rgb() // "rgb(63, 138, 213)"
|
|
11
|
+
* faker.color.hsl() // "hsl(217, 64%, 54%)"
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare class Color {
|
|
15
|
+
private readonly rng;
|
|
16
|
+
private readonly locale;
|
|
17
|
+
constructor(rng: Prng, locale: LocaleRef);
|
|
18
|
+
name(): string;
|
|
19
|
+
hex(): string;
|
|
20
|
+
rgb(): string;
|
|
21
|
+
hsl(): string;
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
import { LocaleRef } from './locale';
|
|
3
|
+
/**
|
|
4
|
+
* Color generators.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* faker.color.name() // "amber"
|
|
9
|
+
* faker.color.hex() // "#3f8ad5"
|
|
10
|
+
* faker.color.rgb() // "rgb(63, 138, 213)"
|
|
11
|
+
* faker.color.hsl() // "hsl(217, 64%, 54%)"
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare class Color {
|
|
15
|
+
private readonly rng;
|
|
16
|
+
private readonly locale;
|
|
17
|
+
constructor(rng: Prng, locale: LocaleRef);
|
|
18
|
+
name(): string;
|
|
19
|
+
hex(): string;
|
|
20
|
+
rgb(): string;
|
|
21
|
+
hsl(): string;
|
|
22
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
import { LocaleRef } from './locale';
|
|
3
|
+
/**
|
|
4
|
+
* Commerce generators.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* faker.commerce.productName() // "Bamboo Notebook"
|
|
9
|
+
* faker.commerce.price() // 24.99
|
|
10
|
+
* faker.commerce.department() // "Electronics"
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export declare class Commerce {
|
|
14
|
+
private readonly rng;
|
|
15
|
+
private readonly locale;
|
|
16
|
+
constructor(rng: Prng, locale: LocaleRef);
|
|
17
|
+
productName(): string;
|
|
18
|
+
department(): string;
|
|
19
|
+
price(min?: number, max?: number, decimals?: number): number;
|
|
20
|
+
productDescription(): string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
import { LocaleRef } from './locale';
|
|
3
|
+
/**
|
|
4
|
+
* Commerce generators.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* faker.commerce.productName() // "Bamboo Notebook"
|
|
9
|
+
* faker.commerce.price() // 24.99
|
|
10
|
+
* faker.commerce.department() // "Electronics"
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export declare class Commerce {
|
|
14
|
+
private readonly rng;
|
|
15
|
+
private readonly locale;
|
|
16
|
+
constructor(rng: Prng, locale: LocaleRef);
|
|
17
|
+
productName(): string;
|
|
18
|
+
department(): string;
|
|
19
|
+
price(min?: number, max?: number, decimals?: number): number;
|
|
20
|
+
productDescription(): string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
import { LocaleRef } from './locale';
|
|
3
|
+
/**
|
|
4
|
+
* Company / employment generators.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* faker.company.name() // "Stark Industries"
|
|
9
|
+
* faker.company.jobTitle() // "Frontend Developer"
|
|
10
|
+
* faker.company.buzzPhrase() // "leverage cross-platform synergies"
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export declare class Company {
|
|
14
|
+
private readonly rng;
|
|
15
|
+
private readonly locale;
|
|
16
|
+
constructor(rng: Prng, locale: LocaleRef);
|
|
17
|
+
name(): string;
|
|
18
|
+
jobTitle(): string;
|
|
19
|
+
buzzPhrase(): string;
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
import { LocaleRef } from './locale';
|
|
3
|
+
/**
|
|
4
|
+
* Company / employment generators.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* faker.company.name() // "Stark Industries"
|
|
9
|
+
* faker.company.jobTitle() // "Frontend Developer"
|
|
10
|
+
* faker.company.buzzPhrase() // "leverage cross-platform synergies"
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export declare class Company {
|
|
14
|
+
private readonly rng;
|
|
15
|
+
private readonly locale;
|
|
16
|
+
constructor(rng: Prng, locale: LocaleRef);
|
|
17
|
+
name(): string;
|
|
18
|
+
jobTitle(): string;
|
|
19
|
+
buzzPhrase(): string;
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
/**
|
|
3
|
+
* Primitive datatype generators.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* faker.datatype.boolean() // true or false
|
|
8
|
+
* faker.datatype.boolean(0.8) // true with 80% probability
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare class Datatype {
|
|
12
|
+
private readonly rng;
|
|
13
|
+
constructor(rng: Prng);
|
|
14
|
+
/** Boolean with probability `chance` of `true` (default 0.5). */
|
|
15
|
+
boolean(chance?: number): boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
/**
|
|
3
|
+
* Primitive datatype generators.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* faker.datatype.boolean() // true or false
|
|
8
|
+
* faker.datatype.boolean(0.8) // true with 80% probability
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare class Datatype {
|
|
12
|
+
private readonly rng;
|
|
13
|
+
constructor(rng: Prng);
|
|
14
|
+
/** Boolean with probability `chance` of `true` (default 0.5). */
|
|
15
|
+
boolean(chance?: number): boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
/**
|
|
3
|
+
* Date / time generators.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* faker.date.past() // a Date in the last 365 days
|
|
8
|
+
* faker.date.recent(30) // last 30 days
|
|
9
|
+
* faker.date.future(60) // next 60 days
|
|
10
|
+
* faker.date.between(a, b)
|
|
11
|
+
* faker.date.birthdate({ min: 18, max: 65 })
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare class DateGen {
|
|
15
|
+
private readonly rng;
|
|
16
|
+
constructor(rng: Prng);
|
|
17
|
+
past(days?: number): Date;
|
|
18
|
+
recent(days?: number): Date;
|
|
19
|
+
future(days?: number): Date;
|
|
20
|
+
soon(days?: number): Date;
|
|
21
|
+
between(from: Date, to: Date): Date;
|
|
22
|
+
/** ISO-8601 string of a random recent date. */
|
|
23
|
+
iso(days?: number): string;
|
|
24
|
+
/** A plausible birthdate for someone in `[min, max]` years old. */
|
|
25
|
+
birthdate(opts?: {
|
|
26
|
+
max?: number;
|
|
27
|
+
min?: number;
|
|
28
|
+
}): Date;
|
|
29
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
/**
|
|
3
|
+
* Date / time generators.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* faker.date.past() // a Date in the last 365 days
|
|
8
|
+
* faker.date.recent(30) // last 30 days
|
|
9
|
+
* faker.date.future(60) // next 60 days
|
|
10
|
+
* faker.date.between(a, b)
|
|
11
|
+
* faker.date.birthdate({ min: 18, max: 65 })
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare class DateGen {
|
|
15
|
+
private readonly rng;
|
|
16
|
+
constructor(rng: Prng);
|
|
17
|
+
past(days?: number): Date;
|
|
18
|
+
recent(days?: number): Date;
|
|
19
|
+
future(days?: number): Date;
|
|
20
|
+
soon(days?: number): Date;
|
|
21
|
+
between(from: Date, to: Date): Date;
|
|
22
|
+
/** ISO-8601 string of a random recent date. */
|
|
23
|
+
iso(days?: number): string;
|
|
24
|
+
/** A plausible birthdate for someone in `[min, max]` years old. */
|
|
25
|
+
birthdate(opts?: {
|
|
26
|
+
max?: number;
|
|
27
|
+
min?: number;
|
|
28
|
+
}): Date;
|
|
29
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Prng } from '../prng/types';
|
|
2
|
+
import { Person } from './person';
|
|
3
|
+
import { Internet } from './internet';
|
|
4
|
+
import { Location } from './location';
|
|
5
|
+
import { Lorem } from './lorem';
|
|
6
|
+
import { DateGen } from './date';
|
|
7
|
+
import { NumberGen } from './number';
|
|
8
|
+
import { StringGen } from './string';
|
|
9
|
+
import { Color } from './color';
|
|
10
|
+
import { Company } from './company';
|
|
11
|
+
import { Commerce } from './commerce';
|
|
12
|
+
import { Finance } from './finance';
|
|
13
|
+
import { Image } from './image';
|
|
14
|
+
import { System } from './system';
|
|
15
|
+
import { Datatype } from './datatype';
|
|
16
|
+
import { Helpers } from './helpers';
|
|
17
|
+
/** Options for constructing a `Faker` instance. */
|
|
18
|
+
export interface FakerOptions {
|
|
19
|
+
/** Initial locale name. Defaults to `"en"`. */
|
|
20
|
+
locale?: string;
|
|
21
|
+
/** Initial PRNG seed. If omitted, a time-based seed is used. */
|
|
22
|
+
seed?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Faceted, seedable, locale-aware random-data generator.
|
|
26
|
+
*
|
|
27
|
+
* Every namespace shares the same PRNG and locale reference — `seed()` and
|
|
28
|
+
* `locale()` mutate that shared state in place, so changes propagate without
|
|
29
|
+
* re-constructing modules.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { Faker } from '@anil-labs/factory'
|
|
34
|
+
*
|
|
35
|
+
* const f = new Faker({ seed: 42, locale: 'en' })
|
|
36
|
+
* f.person.fullName() // "Olivia Patel"
|
|
37
|
+
* f.seed(42)
|
|
38
|
+
* f.person.fullName() // "Olivia Patel" — deterministic
|
|
39
|
+
*
|
|
40
|
+
* // Or use the package's default instance:
|
|
41
|
+
* import { faker } from '@anil-labs/factory'
|
|
42
|
+
* faker.seed(1)
|
|
43
|
+
* faker.internet.email()
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare class Faker {
|
|
47
|
+
private readonly rng;
|
|
48
|
+
private readonly localeRef;
|
|
49
|
+
readonly person: Person;
|
|
50
|
+
readonly internet: Internet;
|
|
51
|
+
readonly location: Location;
|
|
52
|
+
readonly lorem: Lorem;
|
|
53
|
+
readonly date: DateGen;
|
|
54
|
+
readonly number: NumberGen;
|
|
55
|
+
readonly string: StringGen;
|
|
56
|
+
readonly color: Color;
|
|
57
|
+
readonly company: Company;
|
|
58
|
+
readonly commerce: Commerce;
|
|
59
|
+
readonly finance: Finance;
|
|
60
|
+
readonly image: Image;
|
|
61
|
+
readonly system: System;
|
|
62
|
+
readonly datatype: Datatype;
|
|
63
|
+
readonly helpers: Helpers;
|
|
64
|
+
constructor(opts?: FakerOptions);
|
|
65
|
+
/** Reseed the underlying PRNG. Subsequent calls are deterministic from here. */
|
|
66
|
+
seed(seed: number): this;
|
|
67
|
+
/** Switch the active locale. Throws if unknown. */
|
|
68
|
+
locale(name: string): this;
|
|
69
|
+
/** Read the current locale identifier (e.g. `"en"`). */
|
|
70
|
+
currentLocale(): string;
|
|
71
|
+
/** Read the current seed (useful for snapshot reproduction). */
|
|
72
|
+
currentSeed(): number;
|
|
73
|
+
/**
|
|
74
|
+
* Build a fresh, independent `Faker` with its own PRNG seeded from this
|
|
75
|
+
* one's current state. Useful when you need to fork a deterministic stream.
|
|
76
|
+
*/
|
|
77
|
+
fork(): Faker;
|
|
78
|
+
/** Access the underlying PRNG. Advanced use only. */
|
|
79
|
+
rawPrng(): Prng;
|
|
80
|
+
}
|
|
81
|
+
/** Default singleton — mutable via `faker.seed()` / `faker.locale()`. */
|
|
82
|
+
export declare const faker: Faker;
|