data-faker-plus 0.0.1
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/README.md +584 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.esm.js +1 -0
- package/dist/index.umd.js +1 -0
- package/dist/types/common/ClassDecoratorStateManager.d.ts +47 -0
- package/dist/types/common/ClassDecoratorValidator.d.ts +28 -0
- package/dist/types/common/DecoratorValidator.d.ts +14 -0
- package/dist/types/common/PropertyDecoraotrValidator.d.ts +30 -0
- package/dist/types/constants/DataFakerConstants.d.ts +2 -0
- package/dist/types/constants/DecoratorConstants.d.ts +5 -0
- package/dist/types/constants/MetaDataConstants.d.ts +4 -0
- package/dist/types/core/DataFaker.d.ts +43 -0
- package/dist/types/core/DataFieldDecoratorFactory.d.ts +38 -0
- package/dist/types/core/DataModel.d.ts +39 -0
- package/dist/types/core/DataModelDecoratorFactory.d.ts +48 -0
- package/dist/types/core/DecoratorInfo.d.ts +37 -0
- package/dist/types/core/LocaleParser.d.ts +16 -0
- package/dist/types/core/ModelManager.d.ts +53 -0
- package/dist/types/core/ModelParser.d.ts +62 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/types/decorator.d.ts +70 -0
- package/dist/types/types/faker.d.ts +238 -0
- package/dist/types/types/index.d.ts +2 -0
- package/dist/types/types/index.ts +2 -0
- package/dist/types/utils/IdUtils.d.ts +13 -0
- package/dist/types/utils/ObjectUtils.d.ts +9 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
# Data Faker
|
|
2
|
+
|
|
3
|
+
注意下面的仅仅是演示案例,具体详情请参见
|
|
4
|
+
[DataFaker 国外官网](https://df-docs-9vlztj5ob-bloom-lmh.vercel.app/)
|
|
5
|
+
[DataFaker 国内官网](https://ootjp8xe3-datafaker-9j23z0sk.maozi.io/)
|
|
6
|
+
|
|
7
|
+
## 起步
|
|
8
|
+
|
|
9
|
+
### 介绍
|
|
10
|
+
|
|
11
|
+
`DataFaker` 是一个数据生成器,底层依赖 `faker.js`,并在之上扩展了模板语法,能够帮助你快速生成各类的数据,包括引用数据和递归数据,满足你在不同场景下各类数据的生成需求。它特别适用于以下场景:
|
|
12
|
+
|
|
13
|
+
- 前端开发中的模拟数据
|
|
14
|
+
- 单元测试和集成测试
|
|
15
|
+
- API 接口原型设计
|
|
16
|
+
- 数据库样本数据生成
|
|
17
|
+
- 演示和教学用例
|
|
18
|
+
|
|
19
|
+
[致敬 faker.js](https://faker.nodejs.cn/guide/)
|
|
20
|
+
|
|
21
|
+
### 特性
|
|
22
|
+
|
|
23
|
+
- 无侵入:`DataFaker` 对`faker.js`只做增强不做修改,你仍然可以像以前那样使用 `faker.js`
|
|
24
|
+
- 模板化:`DataFaker`以模板的方式来定义数据结构,就像定义数据库表结构那样
|
|
25
|
+
- 面向模型:`DataFaker`将模板封装为了模型,以模型为基本单元,提供了模型复用机制,让你的数据模板可在多处复用
|
|
26
|
+
- 上下文机制:`DataFaker`采用上下文机制保持数据之间的关联性
|
|
27
|
+
- 多语言:`DataFaker`底层依托`faker.js`,其同样也支持 `70` 多种语言环境
|
|
28
|
+
- 多数据源:`DataFaker` 借助了 `faker.js` 的底层数据库,能够生成涵盖动物、书本等 `26` 类数据
|
|
29
|
+
- 可配置:`DataFaker` 支持个性化配置方式
|
|
30
|
+
|
|
31
|
+
## 基本使用
|
|
32
|
+
|
|
33
|
+
`DataFaker`使用起来十分的简单,你只需要:
|
|
34
|
+
|
|
35
|
+
1. 定义数据模型
|
|
36
|
+
2. 生成数据
|
|
37
|
+
|
|
38
|
+
### 定义模型-defineModel
|
|
39
|
+
|
|
40
|
+
`defineModel`方法用于定义数据模型,它接受两个参数:
|
|
41
|
+
|
|
42
|
+
- 模型名称
|
|
43
|
+
- 数据模板
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// 定义模型
|
|
47
|
+
const userModel = defineModel('user', {
|
|
48
|
+
id: 'string.uuid',
|
|
49
|
+
name: 'person.fullName',
|
|
50
|
+
age: ['number.int', { min: 18, max: 30 }],
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 生成数据-fakeData
|
|
55
|
+
|
|
56
|
+
使用`fakeData`函数并传入数据模型就能生成模型模板对象的数据,如下所示:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// 生成数据
|
|
60
|
+
const data = fakeData(userModel);
|
|
61
|
+
console.log(data);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
生成的数据如下:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"id": "5bdfc8e5-3b33-4560-b4ca-8b32b0150661",
|
|
69
|
+
"name": "Malcolm Simonis",
|
|
70
|
+
"age": 18
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 核心概念
|
|
75
|
+
|
|
76
|
+
### 模板语法
|
|
77
|
+
|
|
78
|
+
`DataFaker`通过模板来定义数据结构,就像定义一个数据库表那样,每一个数据结构就是一个`schema`。
|
|
79
|
+
|
|
80
|
+
```ts {15-20}
|
|
81
|
+
const addressModel = defineModel('address', {
|
|
82
|
+
country: 'location.country',
|
|
83
|
+
city: 'location.city',
|
|
84
|
+
});
|
|
85
|
+
const userModel = defineModel('user', {
|
|
86
|
+
id: 'number.int',
|
|
87
|
+
firstName: 'person.firstName',
|
|
88
|
+
secondeName: 'person.lastName',
|
|
89
|
+
age: ['number.int', { min: 18, max: 65 }],
|
|
90
|
+
hobby: ['helpers.arrayElements', ['篮球', '足球', '乒乓球', '羽毛球']],
|
|
91
|
+
email: ctx => {
|
|
92
|
+
return faker.internet.email({ firstName: ctx.firstName, lastName: ctx.secondeName });
|
|
93
|
+
},
|
|
94
|
+
address: addressModel,
|
|
95
|
+
children: {
|
|
96
|
+
// 引用自身,此时必须使用模型别名'user'而不能使用userModel
|
|
97
|
+
refModel: 'user',
|
|
98
|
+
// 控制自引用递归深度
|
|
99
|
+
deep: 3,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
const userDatas = fakeData(userModel);
|
|
103
|
+
console.dir(userDatas, { depth: Infinity });
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 模型复用
|
|
107
|
+
|
|
108
|
+
使用`cloneModel`函数我们能够克隆一个模型,其需要提供两个参数
|
|
109
|
+
|
|
110
|
+
- 参数 【1】:克隆的新的模型别名
|
|
111
|
+
- 参数 【2】:要克隆的模型对象
|
|
112
|
+
|
|
113
|
+
比如我们以`userModel`模型为原型,克隆出了一个学生模型,并将其别名命名为`studentModel`
|
|
114
|
+
|
|
115
|
+
```ts {2,17-19}
|
|
116
|
+
// 用户模型
|
|
117
|
+
const userModel = defineModel('user', {
|
|
118
|
+
id: 'number.int',
|
|
119
|
+
firstName: 'person.firstName',
|
|
120
|
+
secondName: 'person.lastName',
|
|
121
|
+
age: ['number.int', { min: 18, max: 65 }],
|
|
122
|
+
email: ctx => {
|
|
123
|
+
return faker.internet.email({ firstName: ctx.firstName, lastName: ctx.secondName });
|
|
124
|
+
},
|
|
125
|
+
children: {
|
|
126
|
+
refModel: 'user',
|
|
127
|
+
// 控制自引用递归深度
|
|
128
|
+
deep: 1,
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
// 克隆学生模型
|
|
132
|
+
const studentModel = cloneModel('student', userModel);
|
|
133
|
+
const studentDatas = fakeData(studentModel);
|
|
134
|
+
console.dir(studentDatas, { depth: Infinity });
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
生成数据如下:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"id": 6584695714108738,
|
|
142
|
+
"firstName": "Jane",
|
|
143
|
+
"secondName": "Wisoky",
|
|
144
|
+
"age": 21,
|
|
145
|
+
"children": {
|
|
146
|
+
"id": 390307445727788,
|
|
147
|
+
"firstName": "Addie",
|
|
148
|
+
"secondName": "Koch",
|
|
149
|
+
"age": 62,
|
|
150
|
+
"children": {
|
|
151
|
+
"id": 6872368248204444,
|
|
152
|
+
"firstName": "Alexandra",
|
|
153
|
+
"secondName": "Powlowski",
|
|
154
|
+
"age": 29,
|
|
155
|
+
"children": null,
|
|
156
|
+
"email": "Alexandra.Powlowski16@hotmail.com"
|
|
157
|
+
},
|
|
158
|
+
"email": "Addie_Koch@hotmail.com"
|
|
159
|
+
},
|
|
160
|
+
"email": "Jane_Wisoky27@gmail.com"
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 钩子函数
|
|
165
|
+
|
|
166
|
+
钩子函数就是在数据生成前后或数据生成中执行的函数,它能让你在数据生成前后或数据生成中操作数据项和模板,改变数据生成方式,`DataFaker`提供了四类钩子函数:
|
|
167
|
+
|
|
168
|
+
- 数据生成前操作模板-`beforeAllCbs`
|
|
169
|
+
- 数据生成后操作数据-`afterAllCbs`
|
|
170
|
+
- 数据项生成前设置模板-`beforeEachCbs`
|
|
171
|
+
- 数据项生成后操作数据-`afterEachCbs`
|
|
172
|
+
|
|
173
|
+
> 比如我希望为所有引用数据添加 id`属性
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const addressModel = defineModel('address', {
|
|
177
|
+
country: 'location.country',
|
|
178
|
+
city: 'location.city',
|
|
179
|
+
children: {
|
|
180
|
+
refModel: 'address',
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
// 用户模型
|
|
184
|
+
const userModel = defineModel('user', {
|
|
185
|
+
firstName: 'person.firstName',
|
|
186
|
+
secondName: 'person.lastName',
|
|
187
|
+
age: ['number.int', { min: 18, max: 65 }],
|
|
188
|
+
address: { refModel: 'address', count: 1 },
|
|
189
|
+
});
|
|
190
|
+
const userDatas = fakeData(userModel, {
|
|
191
|
+
hooks: {
|
|
192
|
+
afterEachCbs: ctx => {
|
|
193
|
+
if (ctx.type === 'object' && ctx.value) {
|
|
194
|
+
// 对所有引用类型添加id
|
|
195
|
+
ctx.value['id'] = faker.string.uuid();
|
|
196
|
+
}
|
|
197
|
+
return ctx;
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
console.dir(userDatas, { depth: Infinity });
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
生成数据如下:
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
{
|
|
208
|
+
firstName: 'Ernest',
|
|
209
|
+
secondName: 'Ritchie',
|
|
210
|
+
age: 42,
|
|
211
|
+
address: {
|
|
212
|
+
country: 'Sint Maarten',
|
|
213
|
+
city: 'Joeborough',
|
|
214
|
+
children: {
|
|
215
|
+
country: 'Sudan',
|
|
216
|
+
city: 'Watsicashire',
|
|
217
|
+
children: null,
|
|
218
|
+
id: '6b9dd2aa-26a2-4072-95af-6c63eddd6dc0'
|
|
219
|
+
},
|
|
220
|
+
id: '945e2165-2119-45ee-bd52-b0c0df8a73b1'
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 引用数据和自引用
|
|
226
|
+
|
|
227
|
+
`DataFaker`支持引用数据和生成自引用递归数据
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
const addressModel = defineModel('address', {
|
|
231
|
+
country: 'location.country',
|
|
232
|
+
city: 'location.city',
|
|
233
|
+
children: {
|
|
234
|
+
refModel: 'address',
|
|
235
|
+
count: 2,
|
|
236
|
+
deep: 1,
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
// 用户模型
|
|
240
|
+
const userModel = defineModel('user', {
|
|
241
|
+
firstName: 'person.firstName',
|
|
242
|
+
secondName: 'person.lastName',
|
|
243
|
+
age: ['number.int', { min: 18, max: 65 }],
|
|
244
|
+
address: { refModel: 'address', count: 2 },
|
|
245
|
+
children: {
|
|
246
|
+
refModel: 'user',
|
|
247
|
+
deep: 2,
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
const userDatas = fakeData(userModel);
|
|
251
|
+
console.dir(userDatas, { depth: Infinity });
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
生成数据如下:
|
|
255
|
+
|
|
256
|
+
```json
|
|
257
|
+
{
|
|
258
|
+
"firstName": "Lydia",
|
|
259
|
+
"secondName": "Adams",
|
|
260
|
+
"age": 41,
|
|
261
|
+
"address": [
|
|
262
|
+
// 第一个address数据
|
|
263
|
+
{
|
|
264
|
+
"country": "Democratic Republic of the Congo",
|
|
265
|
+
"city": "Elisefurt",
|
|
266
|
+
// 递归1层
|
|
267
|
+
"children": [
|
|
268
|
+
{
|
|
269
|
+
"country": "Nauru",
|
|
270
|
+
"city": "Randalltown"
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"country": "Afghanistan",
|
|
274
|
+
"city": "Commerce City"
|
|
275
|
+
}
|
|
276
|
+
]
|
|
277
|
+
},
|
|
278
|
+
// 第二个address数据
|
|
279
|
+
{
|
|
280
|
+
"country": "Ecuador",
|
|
281
|
+
"city": "Hamillworth",
|
|
282
|
+
"children": [
|
|
283
|
+
{
|
|
284
|
+
"country": "Reunion",
|
|
285
|
+
"city": "West Greysonland"
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"country": "Italy",
|
|
289
|
+
"city": "Hempstead"
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
],
|
|
294
|
+
// 第一层children
|
|
295
|
+
"children": {
|
|
296
|
+
"firstName": "Lisette",
|
|
297
|
+
"secondName": "Gutmann",
|
|
298
|
+
"age": 29,
|
|
299
|
+
"address": [
|
|
300
|
+
{
|
|
301
|
+
"country": "Syrian Arab Republic",
|
|
302
|
+
"city": "Leuschkefield",
|
|
303
|
+
"children": [
|
|
304
|
+
{
|
|
305
|
+
"country": "Austria",
|
|
306
|
+
"city": "Hammesstad"
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"country": "Barbados",
|
|
310
|
+
"city": "West Elodyfort"
|
|
311
|
+
}
|
|
312
|
+
]
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
"country": "Colombia",
|
|
316
|
+
"city": "Fort Anastasia",
|
|
317
|
+
"children": [
|
|
318
|
+
{
|
|
319
|
+
"country": "Czechia",
|
|
320
|
+
"city": "Hyattfort"
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"country": "Zambia",
|
|
324
|
+
"city": "West Stefanieborough"
|
|
325
|
+
}
|
|
326
|
+
]
|
|
327
|
+
}
|
|
328
|
+
],
|
|
329
|
+
// 第二层children
|
|
330
|
+
"children": {
|
|
331
|
+
"firstName": "Rex",
|
|
332
|
+
"secondName": "Farrell",
|
|
333
|
+
"age": 22,
|
|
334
|
+
"address": [
|
|
335
|
+
{
|
|
336
|
+
"country": "El Salvador",
|
|
337
|
+
"city": "Montyshire",
|
|
338
|
+
"children": [
|
|
339
|
+
{
|
|
340
|
+
"country": "Bangladesh",
|
|
341
|
+
"city": "Port Prince"
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"country": "Svalbard & Jan Mayen Islands",
|
|
345
|
+
"city": "South Siennacester"
|
|
346
|
+
}
|
|
347
|
+
]
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
"country": "Panama",
|
|
351
|
+
"city": "Monterey Park",
|
|
352
|
+
"children": [
|
|
353
|
+
{
|
|
354
|
+
"country": "Vietnam",
|
|
355
|
+
"city": "South Scotworth"
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"country": "Mozambique",
|
|
359
|
+
"city": "Matildeside"
|
|
360
|
+
}
|
|
361
|
+
]
|
|
362
|
+
}
|
|
363
|
+
]
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## 装饰器语法
|
|
370
|
+
|
|
371
|
+
### 基本使用
|
|
372
|
+
|
|
373
|
+
`DataFaker`为了更好的支持`ts`,引入了装饰器语法,装饰器语法本质上就是`defineModel`的语法糖,它设计的初衷就是为了保持现有类和模型的共通性。
|
|
374
|
+
比如现在项目中本来就有`User`和`Address`两个类作为 ts 类型
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
class Address {
|
|
378
|
+
declare city: string;
|
|
379
|
+
declare children: Address[];
|
|
380
|
+
}
|
|
381
|
+
// 用户类
|
|
382
|
+
class User {
|
|
383
|
+
declare id: string;
|
|
384
|
+
declare firstName: string;
|
|
385
|
+
declare secondName: string;
|
|
386
|
+
declare age: number;
|
|
387
|
+
declare email: string;
|
|
388
|
+
declare address: Address;
|
|
389
|
+
declare children: User[];
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
为了将这两个类利用起来,而不是重新使用`defineModel`来定义数据模型,我们可以使用装饰器语法来将现有的类型类定义为`User`和`Address`数据模型。
|
|
394
|
+
|
|
395
|
+
- 使用`@DataModel`装饰器定义数据模型,它接受一个模型别名作为参数
|
|
396
|
+
- 使用`@DataField`装饰器来定义字段,与[模板语法](/模板语法)中定义字段是一致的
|
|
397
|
+
|
|
398
|
+
如下所示:
|
|
399
|
+
|
|
400
|
+
```ts
|
|
401
|
+
@DataModel('address')
|
|
402
|
+
class Address {
|
|
403
|
+
@DataField('location.city')
|
|
404
|
+
declare city: string;
|
|
405
|
+
@DataField({ refModel: 'address', count: 1, deep: 1 })
|
|
406
|
+
declare children: Address[];
|
|
407
|
+
}
|
|
408
|
+
@DataModel('user')
|
|
409
|
+
class User {
|
|
410
|
+
@DataField('string.uuid')
|
|
411
|
+
declare id: string;
|
|
412
|
+
@DataField('person.firstName')
|
|
413
|
+
declare firstName: string;
|
|
414
|
+
@DataField('person.lastName')
|
|
415
|
+
declare secondName: string;
|
|
416
|
+
@DataField(['number.int', { min: 18, max: 65 }])
|
|
417
|
+
declare age: number;
|
|
418
|
+
@DataField(ctx => {
|
|
419
|
+
return faker.internet.email({ firstName: ctx.firstName, lastName: ctx.secondName });
|
|
420
|
+
})
|
|
421
|
+
declare email: string;
|
|
422
|
+
@DataField({ refModel: 'address', count: 1 })
|
|
423
|
+
declare address: Address;
|
|
424
|
+
@DataField({ refModel: 'user', deep: 1, count: 1 })
|
|
425
|
+
declare children: User[];
|
|
426
|
+
}
|
|
427
|
+
const userDatas = fakeData('user', 2);
|
|
428
|
+
console.dir(userDatas, { depth: Infinity });
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
数据生成结果如下:
|
|
432
|
+
|
|
433
|
+
```ts
|
|
434
|
+
[
|
|
435
|
+
{
|
|
436
|
+
id: 'b8e8ade6-5f37-43d9-b512-4ba0395e5975',
|
|
437
|
+
firstName: 'Cecile',
|
|
438
|
+
secondName: 'MacGyver',
|
|
439
|
+
age: 24,
|
|
440
|
+
address: { city: 'Leviland', children: { city: 'North Georgianna' } },
|
|
441
|
+
children: {
|
|
442
|
+
id: 'f29ea63b-ac69-4832-9586-b82b17f2d40b',
|
|
443
|
+
firstName: 'Floyd',
|
|
444
|
+
secondName: 'Flatley',
|
|
445
|
+
age: 57,
|
|
446
|
+
address: { city: 'Lake Anissa', children: { city: 'North Beverlyshire' } },
|
|
447
|
+
email: 'Floyd.Flatley@hotmail.com',
|
|
448
|
+
},
|
|
449
|
+
email: 'Cecile_MacGyver34@yahoo.com',
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
id: '3647b033-470d-40f3-adf9-836df66f7eef',
|
|
453
|
+
firstName: 'Evangeline',
|
|
454
|
+
secondName: 'Kerluke',
|
|
455
|
+
age: 23,
|
|
456
|
+
address: { city: 'Raynorland', children: { city: 'West Rosetta' } },
|
|
457
|
+
children: {
|
|
458
|
+
id: '350c4642-761f-4b36-a6cf-5b1bcf35edcb',
|
|
459
|
+
firstName: 'Aurelio',
|
|
460
|
+
secondName: 'Kuvalis',
|
|
461
|
+
age: 64,
|
|
462
|
+
address: { city: 'Florence-Graham', children: { city: 'New Brock' } },
|
|
463
|
+
email: 'Aurelio_Kuvalis61@yahoo.com',
|
|
464
|
+
},
|
|
465
|
+
email: 'Evangeline.Kerluke@yahoo.com',
|
|
466
|
+
},
|
|
467
|
+
];
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### 基于原生基础的数据模型继承
|
|
471
|
+
|
|
472
|
+
装饰器语法可以更加方便的实现模型继承,只需要像原生继承那样,无需做任何改动,如下所示,`User` 类从 `Person` 类的数据模型中继承了 `email` 和 `children` 字段:
|
|
473
|
+
|
|
474
|
+
```ts
|
|
475
|
+
@DataModel('person')
|
|
476
|
+
class Person {
|
|
477
|
+
@DataField(ctx => {
|
|
478
|
+
return faker.internet.email({ firstName: ctx.firstName, lastName: ctx.secondName });
|
|
479
|
+
})
|
|
480
|
+
declare email: string;
|
|
481
|
+
@DataField({ refModel: 'user', deep: 1, count: 1 })
|
|
482
|
+
declare children: User[];
|
|
483
|
+
}
|
|
484
|
+
@DataModel('user')
|
|
485
|
+
class User extends Person {
|
|
486
|
+
@DataField('string.uuid')
|
|
487
|
+
declare id: string;
|
|
488
|
+
@DataField('person.firstName')
|
|
489
|
+
declare firstName: string;
|
|
490
|
+
@DataField('person.lastName')
|
|
491
|
+
declare secondName: string;
|
|
492
|
+
@DataField(['number.int', { min: 18, max: 65 }])
|
|
493
|
+
declare age: number;
|
|
494
|
+
}
|
|
495
|
+
const userDatas = fakeData('user', 2);
|
|
496
|
+
console.dir(userDatas, { depth: Infinity });
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
生成数据如下:
|
|
500
|
+
|
|
501
|
+
```ts
|
|
502
|
+
[
|
|
503
|
+
{
|
|
504
|
+
children: {
|
|
505
|
+
id: '01beb5dd-d2f8-4602-a4f6-4304d49b1532',
|
|
506
|
+
firstName: 'Anjali',
|
|
507
|
+
secondName: 'Murphy',
|
|
508
|
+
age: 51,
|
|
509
|
+
email: 'Anjali.Murphy@hotmail.com',
|
|
510
|
+
},
|
|
511
|
+
id: '041980c6-164a-4fad-81a2-65a3f9c64359',
|
|
512
|
+
firstName: 'Kristy',
|
|
513
|
+
secondName: 'Ledner',
|
|
514
|
+
age: 62,
|
|
515
|
+
email: 'Kristy_Ledner30@yahoo.com',
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
children: {
|
|
519
|
+
id: '2df47ecb-186e-4d9b-a417-4b62dd4906d0',
|
|
520
|
+
firstName: 'Jody',
|
|
521
|
+
secondName: 'Schmeler',
|
|
522
|
+
age: 18,
|
|
523
|
+
email: 'Jody_Schmeler@hotmail.com',
|
|
524
|
+
},
|
|
525
|
+
id: '26450cf7-f190-44dc-ab1b-6ff0faf8e74b',
|
|
526
|
+
firstName: 'Nathanial',
|
|
527
|
+
secondName: 'Schaden',
|
|
528
|
+
age: 19,
|
|
529
|
+
email: 'Nathanial.Schaden96@gmail.com',
|
|
530
|
+
},
|
|
531
|
+
];
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
## 多种配置方式
|
|
535
|
+
|
|
536
|
+
### 全局配置
|
|
537
|
+
|
|
538
|
+
下面演示全局定义数据生成钩子函数
|
|
539
|
+
|
|
540
|
+
```ts
|
|
541
|
+
// 全局定义beforeAllCbs回调函数
|
|
542
|
+
DataFaker.setHooks({
|
|
543
|
+
beforeAllCbs: schema => {
|
|
544
|
+
console.log(schema);
|
|
545
|
+
return schema;
|
|
546
|
+
},
|
|
547
|
+
});
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### 模板中配置
|
|
551
|
+
|
|
552
|
+
下面演示模板中定义引用类型生成数量
|
|
553
|
+
|
|
554
|
+
```ts
|
|
555
|
+
const userModel = defineModel('user', {
|
|
556
|
+
firstName: 'person.firstName',
|
|
557
|
+
secondName: 'person.lastName',
|
|
558
|
+
age: ['number.int', { min: 18, max: 65 }],
|
|
559
|
+
address: { refModel: 'address', count: 2 },
|
|
560
|
+
});
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### 运行时配置
|
|
564
|
+
|
|
565
|
+
下面展示运行时配置引用数据生成方式
|
|
566
|
+
|
|
567
|
+
```ts
|
|
568
|
+
const userDatas = fakeData(userModel, {
|
|
569
|
+
refRules: {
|
|
570
|
+
// address引用数据生成一个,然后其address.childern自引用数据生成一个
|
|
571
|
+
address: {
|
|
572
|
+
[COUNT]: 1,
|
|
573
|
+
children: {
|
|
574
|
+
[COUNT]: 1,
|
|
575
|
+
},
|
|
576
|
+
},
|
|
577
|
+
// 自引用递归深度为1,且只生成一个,address引用属性同上
|
|
578
|
+
children: {
|
|
579
|
+
[DEEP]: 1,
|
|
580
|
+
[COUNT]: 1,
|
|
581
|
+
},
|
|
582
|
+
},
|
|
583
|
+
});
|
|
584
|
+
```
|