/
model.ts
82 lines (70 loc) 路 1.89 KB
/
model.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { faker } from '@faker-js/faker'
import { Builder } from './builder/builder'
import { RelationType } from './contracts'
import type {
DefineFactoryCallback,
DefineStateCallback,
RelationshipMeta,
RelationshipMetaOptions,
} from './contracts'
export class FactoryModel<Model extends Record<string, any>, States extends string | null = null> {
/**
* Store the factory callback
*/
public callback: DefineFactoryCallback<Model>
/**
* Store each state callbacks
*/
public states: Record<string, DefineStateCallback<Model>> = {}
/**
* Store relations metadata
*/
public relations: Record<string, RelationshipMeta> = {}
constructor(callback: DefineFactoryCallback<Model>) {
this.callback = callback
}
private addRelation(name: string, type: RelationType, meta: RelationshipMetaOptions) {
const { tableName } = this.callback({ faker })
this.relations[name] = {
foreignKey: `${tableName}_id`,
localKey: 'id',
...meta,
type,
}
return this
}
/**
* Allows you to define a new state for the factory.
*/
public state<S extends string>(
name: S,
stateCb: DefineStateCallback<Model>
): FactoryModel<Model, Extract<States | S, string>> {
this.states[name] = stateCb
return this
}
/**
* Add hasOne relationship
*/
public hasOne(name: string, meta: RelationshipMetaOptions) {
return this.addRelation(name, RelationType.HasOne, meta)
}
/**
* Add hasMany relationship
*/
public hasMany(name: string, meta: RelationshipMetaOptions) {
return this.addRelation(name, RelationType.HasMany, meta)
}
/**
* Add belongsTo relationship
*/
public belongsTo(name: string, meta: RelationshipMetaOptions) {
return this.addRelation(name, RelationType.BelongsTo, meta)
}
/**
* Returns the Builder
*/
public build(): Builder<typeof this> {
return new Builder(this)
}
}