@nestbolt/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/LICENSE.md +21 -0
- package/README.md +412 -0
- package/dist/base-factory.d.ts +7 -0
- package/dist/base-factory.js +7 -0
- package/dist/base-factory.js.map +1 -0
- package/dist/events/factory.events.d.ts +18 -0
- package/dist/events/factory.events.js +10 -0
- package/dist/events/factory.events.js.map +1 -0
- package/dist/events/index.d.ts +1 -0
- package/dist/events/index.js +6 -0
- package/dist/events/index.js.map +1 -0
- package/dist/exceptions/factory-not-initialized.exception.d.ts +3 -0
- package/dist/exceptions/factory-not-initialized.exception.js +11 -0
- package/dist/exceptions/factory-not-initialized.exception.js.map +1 -0
- package/dist/exceptions/factory-not-registered.exception.d.ts +3 -0
- package/dist/exceptions/factory-not-registered.exception.js +11 -0
- package/dist/exceptions/factory-not-registered.exception.js.map +1 -0
- package/dist/exceptions/index.d.ts +2 -0
- package/dist/exceptions/index.js +8 -0
- package/dist/exceptions/index.js.map +1 -0
- package/dist/factory-builder.d.ts +28 -0
- package/dist/factory-builder.js +108 -0
- package/dist/factory-builder.js.map +1 -0
- package/dist/factory.constants.d.ts +1 -0
- package/dist/factory.constants.js +5 -0
- package/dist/factory.constants.js.map +1 -0
- package/dist/factory.module.d.ts +6 -0
- package/dist/factory.module.js +49 -0
- package/dist/factory.module.js.map +1 -0
- package/dist/factory.service.d.ts +28 -0
- package/dist/factory.service.js +105 -0
- package/dist/factory.service.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/factory-options.interface.d.ts +14 -0
- package/dist/interfaces/factory-options.interface.js +3 -0
- package/dist/interfaces/factory-options.interface.js.map +1 -0
- package/dist/interfaces/index.d.ts +2 -0
- package/dist/interfaces/index.js +3 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/seeder.interface.d.ts +5 -0
- package/dist/interfaces/seeder.interface.js +3 -0
- package/dist/interfaces/seeder.interface.js.map +1 -0
- package/dist/sequence.d.ts +10 -0
- package/dist/sequence.js +26 -0
- package/dist/sequence.js.map +1 -0
- package/package.json +82 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Nestbolt
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<h1 align="center">@nestbolt/factory</h1>
|
|
3
|
+
<p align="center">Model factories and database seeders for NestJS with TypeORM.</p>
|
|
4
|
+
</p>
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="https://www.npmjs.com/package/@nestbolt/factory"><img src="https://img.shields.io/npm/v/@nestbolt/factory.svg?style=flat-square" alt="npm version"></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/@nestbolt/factory"><img src="https://img.shields.io/npm/dt/@nestbolt/factory.svg?style=flat-square" alt="npm downloads"></a>
|
|
9
|
+
<a href="https://github.com/nestbolt/factory/actions"><img src="https://img.shields.io/github/actions/workflow/status/nestbolt/factory/tests.yml?branch=main&style=flat-square&label=tests" alt="tests"></a>
|
|
10
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square" alt="license"></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<hr>
|
|
14
|
+
|
|
15
|
+
This package provides **model factories and database seeders** for [NestJS](https://nestjs.com) that let you generate fake data for any TypeORM entity with a fluent, chainable API.
|
|
16
|
+
|
|
17
|
+
Once installed, using it is as simple as:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
class UserFactory extends BaseFactory<User> {
|
|
21
|
+
get entity() { return User; }
|
|
22
|
+
definition(faker: Faker) {
|
|
23
|
+
return { name: faker.person.fullName(), email: faker.internet.email() };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
await factoryService.use(UserFactory).count(5).state("admin").create();
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Table of Contents
|
|
31
|
+
|
|
32
|
+
- [Installation](#installation)
|
|
33
|
+
- [Quick Start](#quick-start)
|
|
34
|
+
- [Module Configuration](#module-configuration)
|
|
35
|
+
- [Static Configuration (forRoot)](#static-configuration-forroot)
|
|
36
|
+
- [Async Configuration (forRootAsync)](#async-configuration-forrootasync)
|
|
37
|
+
- [Defining Factories](#defining-factories)
|
|
38
|
+
- [Using the Factory Builder](#using-the-factory-builder)
|
|
39
|
+
- [States](#states)
|
|
40
|
+
- [Sequences](#sequences)
|
|
41
|
+
- [Seeders](#seeders)
|
|
42
|
+
- [Events](#events)
|
|
43
|
+
- [Using the Service Directly](#using-the-service-directly)
|
|
44
|
+
- [Configuration Options](#configuration-options)
|
|
45
|
+
- [Testing](#testing)
|
|
46
|
+
- [Changelog](#changelog)
|
|
47
|
+
- [Contributing](#contributing)
|
|
48
|
+
- [Security](#security)
|
|
49
|
+
- [Credits](#credits)
|
|
50
|
+
- [License](#license)
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
Install the package via npm:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm install @nestbolt/factory
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or via yarn:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
yarn add @nestbolt/factory
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Or via pnpm:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pnpm add @nestbolt/factory
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Peer Dependencies
|
|
73
|
+
|
|
74
|
+
This package requires the following peer dependencies, which you likely already have in a NestJS project:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
@nestjs/common ^10.0.0 || ^11.0.0
|
|
78
|
+
@nestjs/core ^10.0.0 || ^11.0.0
|
|
79
|
+
@nestjs/typeorm ^10.0.0 || ^11.0.0
|
|
80
|
+
typeorm ^0.3.0
|
|
81
|
+
reflect-metadata ^0.1.13 || ^0.2.0
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Included
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
@faker-js/faker ^9.0.0 # Bundled — no need to install separately
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Optional
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npm install @nestjs/event-emitter # For seeder lifecycle events
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Quick Start
|
|
97
|
+
|
|
98
|
+
### 1. Define a factory
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { BaseFactory } from "@nestbolt/factory";
|
|
102
|
+
import { Faker } from "@faker-js/faker";
|
|
103
|
+
|
|
104
|
+
export class UserFactory extends BaseFactory<User> {
|
|
105
|
+
get entity() { return User; }
|
|
106
|
+
|
|
107
|
+
definition(faker: Faker): Partial<User> {
|
|
108
|
+
return {
|
|
109
|
+
name: faker.person.fullName(),
|
|
110
|
+
email: faker.internet.email(),
|
|
111
|
+
role: "user",
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
admin(): Partial<User> {
|
|
116
|
+
return { role: "admin" };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 2. Register the module
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { FactoryModule } from "@nestbolt/factory";
|
|
125
|
+
|
|
126
|
+
@Module({
|
|
127
|
+
imports: [
|
|
128
|
+
TypeOrmModule.forRoot({ /* ... */ }),
|
|
129
|
+
FactoryModule.forRoot({
|
|
130
|
+
factories: [UserFactory, PostFactory],
|
|
131
|
+
}),
|
|
132
|
+
],
|
|
133
|
+
})
|
|
134
|
+
export class AppModule {}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 3. Use in your code
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import { FactoryService } from "@nestbolt/factory";
|
|
141
|
+
|
|
142
|
+
@Injectable()
|
|
143
|
+
export class SeedService {
|
|
144
|
+
constructor(private readonly factory: FactoryService) {}
|
|
145
|
+
|
|
146
|
+
async seed() {
|
|
147
|
+
await this.factory.use(UserFactory).count(10).create();
|
|
148
|
+
await this.factory.use(UserFactory).state("admin").create();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Module Configuration
|
|
154
|
+
|
|
155
|
+
The module is registered globally — you only need to import it once.
|
|
156
|
+
|
|
157
|
+
### Static Configuration (forRoot)
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
FactoryModule.forRoot({
|
|
161
|
+
factories: [UserFactory, PostFactory],
|
|
162
|
+
seeders: [DatabaseSeeder],
|
|
163
|
+
seed: 12345, // optional: reproducible faker data
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Async Configuration (forRootAsync)
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
FactoryModule.forRootAsync({
|
|
171
|
+
imports: [ConfigModule],
|
|
172
|
+
inject: [ConfigService],
|
|
173
|
+
useFactory: (config: ConfigService) => ({
|
|
174
|
+
factories: [UserFactory, PostFactory],
|
|
175
|
+
seed: config.get("FAKER_SEED"),
|
|
176
|
+
}),
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Defining Factories
|
|
181
|
+
|
|
182
|
+
Extend `BaseFactory<T>` and implement the `entity` getter and `definition()` method:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
export class PostFactory extends BaseFactory<Post> {
|
|
186
|
+
get entity() { return Post; }
|
|
187
|
+
|
|
188
|
+
definition(faker: Faker): Partial<Post> {
|
|
189
|
+
return {
|
|
190
|
+
title: faker.lorem.sentence(),
|
|
191
|
+
body: faker.lorem.paragraphs(2),
|
|
192
|
+
status: "draft",
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Optional lifecycle hooks
|
|
197
|
+
async afterMake(entity: Post, faker: Faker) {
|
|
198
|
+
// Called after make() — entity is NOT persisted yet
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async afterCreate(entity: Post, faker: Faker) {
|
|
202
|
+
// Called after create() — entity IS persisted
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Using the Factory Builder
|
|
208
|
+
|
|
209
|
+
The `FactoryBuilder` provides a fluent API for generating entities:
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
// Make without persisting
|
|
213
|
+
const user = await factoryService.use(UserFactory).make();
|
|
214
|
+
|
|
215
|
+
// Create and persist to database
|
|
216
|
+
const user = await factoryService.use(UserFactory).create();
|
|
217
|
+
|
|
218
|
+
// Multiple entities
|
|
219
|
+
const users = await factoryService.use(UserFactory).count(10).create();
|
|
220
|
+
|
|
221
|
+
// Always get an array (even for count=1)
|
|
222
|
+
const users = await factoryService.use(UserFactory).createMany();
|
|
223
|
+
const users = await factoryService.use(UserFactory).makeMany();
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
| Method | Returns | Description |
|
|
227
|
+
|--------|---------|-------------|
|
|
228
|
+
| `count(n)` | `this` | Set number of entities to generate |
|
|
229
|
+
| `state(name \| object \| fn)` | `this` | Apply a state (see States) |
|
|
230
|
+
| `override(attrs)` | `this` | Override specific fields (highest priority) |
|
|
231
|
+
| `sequence(field, seq)` | `this` | Apply a sequence to a field |
|
|
232
|
+
| `afterCreating(fn)` | `this` | Callback after persist |
|
|
233
|
+
| `afterMaking(fn)` | `this` | Callback after instantiation |
|
|
234
|
+
| `create()` | `T \| T[]` | Persist and return |
|
|
235
|
+
| `make()` | `T \| T[]` | Instantiate without persisting |
|
|
236
|
+
| `createMany()` | `T[]` | Persist and always return array |
|
|
237
|
+
| `makeMany()` | `T[]` | Instantiate and always return array |
|
|
238
|
+
|
|
239
|
+
**Override priority:** `definition()` → `state()` → `sequence()` → `override()` (highest)
|
|
240
|
+
|
|
241
|
+
## States
|
|
242
|
+
|
|
243
|
+
States let you define named variations of a factory:
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
export class UserFactory extends BaseFactory<User> {
|
|
247
|
+
// ... definition
|
|
248
|
+
|
|
249
|
+
admin(): Partial<User> {
|
|
250
|
+
return { role: "admin" };
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
inactive(): Partial<User> {
|
|
254
|
+
return { active: false };
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Usage
|
|
259
|
+
await factoryService.use(UserFactory).state("admin").create();
|
|
260
|
+
await factoryService.use(UserFactory).state("admin").state("inactive").create();
|
|
261
|
+
|
|
262
|
+
// Object and function states also work
|
|
263
|
+
await factoryService.use(UserFactory).state({ role: "moderator" }).create();
|
|
264
|
+
await factoryService.use(UserFactory).state((faker) => ({ age: faker.number.int({ min: 18, max: 30 }) })).create();
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Sequences
|
|
268
|
+
|
|
269
|
+
Use `Sequence` for auto-incrementing or cycling values:
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
import { Sequence } from "@nestbolt/factory";
|
|
273
|
+
|
|
274
|
+
// Auto-increment
|
|
275
|
+
await factoryService.use(UserFactory)
|
|
276
|
+
.count(3)
|
|
277
|
+
.sequence("email", Sequence.from(i => `user${i}@test.com`))
|
|
278
|
+
.create();
|
|
279
|
+
// → user0@test.com, user1@test.com, user2@test.com
|
|
280
|
+
|
|
281
|
+
// Increment numbers
|
|
282
|
+
Sequence.increment() // 1, 2, 3, ...
|
|
283
|
+
Sequence.increment(100) // 100, 101, 102, ...
|
|
284
|
+
|
|
285
|
+
// Cycle through values
|
|
286
|
+
Sequence.cycle(["draft", "published", "archived"])
|
|
287
|
+
// → draft, published, archived, draft, ...
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Seeders
|
|
291
|
+
|
|
292
|
+
Seeders are classes that populate your database with test data:
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
import { Seeder, FactoryService } from "@nestbolt/factory";
|
|
296
|
+
|
|
297
|
+
export class DatabaseSeeder implements Seeder {
|
|
298
|
+
order = 0; // lower runs first
|
|
299
|
+
|
|
300
|
+
async run(factory: FactoryService): Promise<void> {
|
|
301
|
+
await factory.use(UserFactory).count(10).create();
|
|
302
|
+
await factory.use(UserFactory).state("admin").count(2).create();
|
|
303
|
+
await factory.use(PostFactory).count(20).create();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Register and run seeders:
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
// Register in module
|
|
312
|
+
FactoryModule.forRoot({
|
|
313
|
+
factories: [UserFactory, PostFactory],
|
|
314
|
+
seeders: [DatabaseSeeder],
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// Run all seeders (sorted by order)
|
|
318
|
+
await factoryService.seed();
|
|
319
|
+
|
|
320
|
+
// Run a single seeder
|
|
321
|
+
await factoryService.runSeeder(DatabaseSeeder);
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Events
|
|
325
|
+
|
|
326
|
+
When `@nestjs/event-emitter` is installed, the package emits:
|
|
327
|
+
|
|
328
|
+
| Event | Payload | When |
|
|
329
|
+
|-------|---------|------|
|
|
330
|
+
| `factory.seeder.started` | `{ seederClass }` | Before a seeder runs |
|
|
331
|
+
| `factory.seeder.completed` | `{ seederClass }` | After a seeder completes |
|
|
332
|
+
| `factory.seed.all.started` | `{ seederCount }` | Before `seed()` runs all seeders |
|
|
333
|
+
| `factory.seed.all.completed` | `{ seederCount }` | After `seed()` completes all seeders |
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
import { FACTORY_EVENTS, SeederCompletedEvent } from "@nestbolt/factory";
|
|
337
|
+
import { OnEvent } from "@nestjs/event-emitter";
|
|
338
|
+
|
|
339
|
+
@OnEvent(FACTORY_EVENTS.SEEDER_COMPLETED)
|
|
340
|
+
handleSeederCompleted(event: SeederCompletedEvent) {
|
|
341
|
+
console.log(`Seeder ${event.seederClass} completed`);
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Using the Service Directly
|
|
346
|
+
|
|
347
|
+
Inject `FactoryService` for factory and seeder management:
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
import { FactoryService } from "@nestbolt/factory";
|
|
351
|
+
|
|
352
|
+
@Injectable()
|
|
353
|
+
export class SeedService {
|
|
354
|
+
constructor(private readonly factory: FactoryService) {}
|
|
355
|
+
|
|
356
|
+
async seedDatabase() {
|
|
357
|
+
const users = await this.factory.use(UserFactory).count(10).createMany();
|
|
358
|
+
const faker = this.factory.getFaker();
|
|
359
|
+
await this.factory.seed();
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
| Method | Returns | Description |
|
|
365
|
+
|--------|---------|-------------|
|
|
366
|
+
| `use(FactoryClass)` | `FactoryBuilder<T>` | Get builder for a registered factory |
|
|
367
|
+
| `getFaker()` | `Faker` | Get the configured Faker instance |
|
|
368
|
+
| `seed()` | `Promise<void>` | Run all registered seeders (sorted by order) |
|
|
369
|
+
| `runSeeder(SeederClass)` | `Promise<void>` | Run a single seeder |
|
|
370
|
+
| `getOptions()` | `FactoryModuleOptions` | Get module configuration |
|
|
371
|
+
|
|
372
|
+
## Configuration Options
|
|
373
|
+
|
|
374
|
+
| Option | Type | Default | Description |
|
|
375
|
+
|--------|------|---------|-------------|
|
|
376
|
+
| `factories` | `FactoryClass[]` | `[]` | Factory classes to register |
|
|
377
|
+
| `seeders` | `SeederClass[]` | `[]` | Seeder classes to register |
|
|
378
|
+
| `seed` | `number` | `undefined` | Faker seed for reproducible data |
|
|
379
|
+
|
|
380
|
+
## Testing
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
npm test
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Run tests in watch mode:
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
npm run test:watch
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Generate coverage report:
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
npm run test:cov
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## Changelog
|
|
399
|
+
|
|
400
|
+
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
|
|
401
|
+
|
|
402
|
+
## Contributing
|
|
403
|
+
|
|
404
|
+
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
|
|
405
|
+
|
|
406
|
+
## Security
|
|
407
|
+
|
|
408
|
+
If you discover any security-related issues, please report them via [GitHub Issues](https://github.com/nestbolt/factory/issues) with the **security** label instead of using the public issue tracker.
|
|
409
|
+
|
|
410
|
+
## License
|
|
411
|
+
|
|
412
|
+
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Faker } from "@faker-js/faker";
|
|
2
|
+
export declare abstract class BaseFactory<T> {
|
|
3
|
+
abstract get entity(): new () => T;
|
|
4
|
+
abstract definition(faker: Faker): Partial<T>;
|
|
5
|
+
afterCreate?(entity: T, faker: Faker): Promise<void>;
|
|
6
|
+
afterMake?(entity: T, faker: Faker): Promise<void>;
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-factory.js","sourceRoot":"","sources":["../src/base-factory.ts"],"names":[],"mappings":";;;AAEA,MAAsB,WAAW;CAMhC;AAND,kCAMC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const FACTORY_EVENTS: {
|
|
2
|
+
readonly SEEDER_STARTED: "factory.seeder.started";
|
|
3
|
+
readonly SEEDER_COMPLETED: "factory.seeder.completed";
|
|
4
|
+
readonly SEED_ALL_STARTED: "factory.seed.all.started";
|
|
5
|
+
readonly SEED_ALL_COMPLETED: "factory.seed.all.completed";
|
|
6
|
+
};
|
|
7
|
+
export interface SeederStartedEvent {
|
|
8
|
+
seederClass: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SeederCompletedEvent {
|
|
11
|
+
seederClass: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SeedAllStartedEvent {
|
|
14
|
+
seederCount: number;
|
|
15
|
+
}
|
|
16
|
+
export interface SeedAllCompletedEvent {
|
|
17
|
+
seederCount: number;
|
|
18
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FACTORY_EVENTS = void 0;
|
|
4
|
+
exports.FACTORY_EVENTS = {
|
|
5
|
+
SEEDER_STARTED: "factory.seeder.started",
|
|
6
|
+
SEEDER_COMPLETED: "factory.seeder.completed",
|
|
7
|
+
SEED_ALL_STARTED: "factory.seed.all.started",
|
|
8
|
+
SEED_ALL_COMPLETED: "factory.seed.all.completed",
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=factory.events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.events.js","sourceRoot":"","sources":["../../src/events/factory.events.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG;IAC5B,cAAc,EAAE,wBAAwB;IACxC,gBAAgB,EAAE,0BAA0B;IAC5C,gBAAgB,EAAE,0BAA0B;IAC5C,kBAAkB,EAAE,4BAA4B;CACxC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FACTORY_EVENTS, type SeederStartedEvent, type SeederCompletedEvent, type SeedAllStartedEvent, type SeedAllCompletedEvent, } from "./factory.events";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FACTORY_EVENTS = void 0;
|
|
4
|
+
var factory_events_1 = require("./factory.events");
|
|
5
|
+
Object.defineProperty(exports, "FACTORY_EVENTS", { enumerable: true, get: function () { return factory_events_1.FACTORY_EVENTS; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":";;;AAAA,mDAM0B;AALxB,gHAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FactoryNotInitializedException = void 0;
|
|
4
|
+
class FactoryNotInitializedException extends Error {
|
|
5
|
+
constructor() {
|
|
6
|
+
super("FactoryService has not been initialized. Make sure FactoryModule is imported in your application.");
|
|
7
|
+
this.name = "FactoryNotInitializedException";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.FactoryNotInitializedException = FactoryNotInitializedException;
|
|
11
|
+
//# sourceMappingURL=factory-not-initialized.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory-not-initialized.exception.js","sourceRoot":"","sources":["../../src/exceptions/factory-not-initialized.exception.ts"],"names":[],"mappings":";;;AAAA,MAAa,8BAA+B,SAAQ,KAAK;IACvD;QACE,KAAK,CACH,mGAAmG,CACpG,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC/C,CAAC;CACF;AAPD,wEAOC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FactoryNotRegisteredException = void 0;
|
|
4
|
+
class FactoryNotRegisteredException extends Error {
|
|
5
|
+
constructor(factoryName) {
|
|
6
|
+
super(`Factory "${factoryName}" is not registered. Make sure it is included in the factories array of FactoryModule.forRoot().`);
|
|
7
|
+
this.name = "FactoryNotRegisteredException";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.FactoryNotRegisteredException = FactoryNotRegisteredException;
|
|
11
|
+
//# sourceMappingURL=factory-not-registered.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory-not-registered.exception.js","sourceRoot":"","sources":["../../src/exceptions/factory-not-registered.exception.ts"],"names":[],"mappings":";;;AAAA,MAAa,6BAA8B,SAAQ,KAAK;IACtD,YAAY,WAAmB;QAC7B,KAAK,CACH,YAAY,WAAW,kGAAkG,CAC1H,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAC9C,CAAC;CACF;AAPD,sEAOC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FactoryNotRegisteredException = exports.FactoryNotInitializedException = void 0;
|
|
4
|
+
var factory_not_initialized_exception_1 = require("./factory-not-initialized.exception");
|
|
5
|
+
Object.defineProperty(exports, "FactoryNotInitializedException", { enumerable: true, get: function () { return factory_not_initialized_exception_1.FactoryNotInitializedException; } });
|
|
6
|
+
var factory_not_registered_exception_1 = require("./factory-not-registered.exception");
|
|
7
|
+
Object.defineProperty(exports, "FactoryNotRegisteredException", { enumerable: true, get: function () { return factory_not_registered_exception_1.FactoryNotRegisteredException; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exceptions/index.ts"],"names":[],"mappings":";;;AAAA,yFAAqF;AAA5E,mJAAA,8BAA8B,OAAA;AACvC,uFAAmF;AAA1E,iJAAA,6BAA6B,OAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Faker } from "@faker-js/faker";
|
|
2
|
+
import type { DataSource } from "typeorm";
|
|
3
|
+
import type { BaseFactory } from "./base-factory";
|
|
4
|
+
import type { Sequence } from "./sequence";
|
|
5
|
+
export declare class FactoryBuilder<T> {
|
|
6
|
+
private readonly factory;
|
|
7
|
+
private readonly faker;
|
|
8
|
+
private readonly dataSource;
|
|
9
|
+
private _count;
|
|
10
|
+
private _states;
|
|
11
|
+
private _overrides;
|
|
12
|
+
private _sequences;
|
|
13
|
+
private _afterCreating;
|
|
14
|
+
private _afterMaking;
|
|
15
|
+
constructor(factory: BaseFactory<T>, faker: Faker, dataSource: DataSource | null);
|
|
16
|
+
count(n: number): this;
|
|
17
|
+
state(stateOrOverrides: string | Partial<T> | ((faker: Faker) => Partial<T>)): this;
|
|
18
|
+
override(overrides: Partial<T>): this;
|
|
19
|
+
sequence<K extends keyof T>(field: K, seq: Sequence<T[K]>): this;
|
|
20
|
+
afterCreating(callback: (entity: T, faker: Faker) => Promise<void>): this;
|
|
21
|
+
afterMaking(callback: (entity: T, faker: Faker) => Promise<void>): this;
|
|
22
|
+
make(): Promise<T | T[]>;
|
|
23
|
+
makeMany(): Promise<T[]>;
|
|
24
|
+
create(): Promise<T | T[]>;
|
|
25
|
+
createMany(): Promise<T[]>;
|
|
26
|
+
private buildMany;
|
|
27
|
+
private buildOne;
|
|
28
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FactoryBuilder = void 0;
|
|
4
|
+
class FactoryBuilder {
|
|
5
|
+
constructor(factory, faker, dataSource) {
|
|
6
|
+
this.factory = factory;
|
|
7
|
+
this.faker = faker;
|
|
8
|
+
this.dataSource = dataSource;
|
|
9
|
+
this._count = 1;
|
|
10
|
+
this._states = [];
|
|
11
|
+
this._overrides = {};
|
|
12
|
+
this._sequences = new Map();
|
|
13
|
+
this._afterCreating = [];
|
|
14
|
+
this._afterMaking = [];
|
|
15
|
+
}
|
|
16
|
+
count(n) {
|
|
17
|
+
this._count = n;
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
state(stateOrOverrides) {
|
|
21
|
+
this._states.push(stateOrOverrides);
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
override(overrides) {
|
|
25
|
+
this._overrides = { ...this._overrides, ...overrides };
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
sequence(field, seq) {
|
|
29
|
+
this._sequences.set(field, seq);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
afterCreating(callback) {
|
|
33
|
+
this._afterCreating.push(callback);
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
afterMaking(callback) {
|
|
37
|
+
this._afterMaking.push(callback);
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
async make() {
|
|
41
|
+
const results = await this.buildMany(false);
|
|
42
|
+
return this._count === 1 ? results[0] : results;
|
|
43
|
+
}
|
|
44
|
+
async makeMany() {
|
|
45
|
+
return this.buildMany(false);
|
|
46
|
+
}
|
|
47
|
+
async create() {
|
|
48
|
+
const results = await this.buildMany(true);
|
|
49
|
+
return this._count === 1 ? results[0] : results;
|
|
50
|
+
}
|
|
51
|
+
async createMany() {
|
|
52
|
+
return this.buildMany(true);
|
|
53
|
+
}
|
|
54
|
+
async buildMany(persist) {
|
|
55
|
+
const results = [];
|
|
56
|
+
for (let i = 0; i < this._count; i++) {
|
|
57
|
+
const entity = await this.buildOne(persist);
|
|
58
|
+
results.push(entity);
|
|
59
|
+
}
|
|
60
|
+
return results;
|
|
61
|
+
}
|
|
62
|
+
async buildOne(persist) {
|
|
63
|
+
let attrs = { ...this.factory.definition(this.faker) };
|
|
64
|
+
for (const s of this._states) {
|
|
65
|
+
if (typeof s === "string") {
|
|
66
|
+
const method = this.factory[s];
|
|
67
|
+
if (typeof method === "function") {
|
|
68
|
+
attrs = { ...attrs, ...method.call(this.factory) };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else if (typeof s === "function") {
|
|
72
|
+
attrs = { ...attrs, ...s(this.faker) };
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
attrs = { ...attrs, ...s };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const [field, seq] of this._sequences) {
|
|
79
|
+
attrs[field] = seq.next();
|
|
80
|
+
}
|
|
81
|
+
attrs = { ...attrs, ...this._overrides };
|
|
82
|
+
const EntityClass = this.factory.entity;
|
|
83
|
+
const entity = Object.assign(new EntityClass(), attrs);
|
|
84
|
+
if (this.factory.afterMake) {
|
|
85
|
+
await this.factory.afterMake(entity, this.faker);
|
|
86
|
+
}
|
|
87
|
+
for (const cb of this._afterMaking) {
|
|
88
|
+
await cb(entity, this.faker);
|
|
89
|
+
}
|
|
90
|
+
if (persist) {
|
|
91
|
+
if (!this.dataSource) {
|
|
92
|
+
throw new Error("DataSource is not available. Cannot persist entities without a database connection.");
|
|
93
|
+
}
|
|
94
|
+
const repo = this.dataSource.getRepository(EntityClass);
|
|
95
|
+
const saved = await repo.save(entity);
|
|
96
|
+
Object.assign(entity, saved);
|
|
97
|
+
if (this.factory.afterCreate) {
|
|
98
|
+
await this.factory.afterCreate(entity, this.faker);
|
|
99
|
+
}
|
|
100
|
+
for (const cb of this._afterCreating) {
|
|
101
|
+
await cb(entity, this.faker);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return entity;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.FactoryBuilder = FactoryBuilder;
|
|
108
|
+
//# sourceMappingURL=factory-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory-builder.js","sourceRoot":"","sources":["../src/factory-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const FACTORY_OPTIONS = "FACTORY_OPTIONS";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.constants.js","sourceRoot":"","sources":["../src/factory.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DynamicModule } from "@nestjs/common";
|
|
2
|
+
import type { FactoryModuleOptions, FactoryAsyncOptions } from "./interfaces";
|
|
3
|
+
export declare class FactoryModule {
|
|
4
|
+
static forRoot(options?: FactoryModuleOptions): DynamicModule;
|
|
5
|
+
static forRootAsync(asyncOptions: FactoryAsyncOptions): DynamicModule;
|
|
6
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var FactoryModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.FactoryModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const factory_constants_1 = require("./factory.constants");
|
|
13
|
+
const factory_service_1 = require("./factory.service");
|
|
14
|
+
let FactoryModule = FactoryModule_1 = class FactoryModule {
|
|
15
|
+
static forRoot(options = {}) {
|
|
16
|
+
const providers = [
|
|
17
|
+
{ provide: factory_constants_1.FACTORY_OPTIONS, useValue: options },
|
|
18
|
+
factory_service_1.FactoryService,
|
|
19
|
+
];
|
|
20
|
+
return {
|
|
21
|
+
module: FactoryModule_1,
|
|
22
|
+
global: true,
|
|
23
|
+
providers,
|
|
24
|
+
exports: [factory_service_1.FactoryService, factory_constants_1.FACTORY_OPTIONS],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
static forRootAsync(asyncOptions) {
|
|
28
|
+
const providers = [
|
|
29
|
+
{
|
|
30
|
+
provide: factory_constants_1.FACTORY_OPTIONS,
|
|
31
|
+
useFactory: asyncOptions.useFactory,
|
|
32
|
+
inject: asyncOptions.inject ?? [],
|
|
33
|
+
},
|
|
34
|
+
factory_service_1.FactoryService,
|
|
35
|
+
];
|
|
36
|
+
return {
|
|
37
|
+
module: FactoryModule_1,
|
|
38
|
+
global: true,
|
|
39
|
+
imports: [...(asyncOptions.imports ?? [])],
|
|
40
|
+
providers,
|
|
41
|
+
exports: [factory_service_1.FactoryService, factory_constants_1.FACTORY_OPTIONS],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
exports.FactoryModule = FactoryModule;
|
|
46
|
+
exports.FactoryModule = FactoryModule = FactoryModule_1 = __decorate([
|
|
47
|
+
(0, common_1.Module)({})
|
|
48
|
+
], FactoryModule);
|
|
49
|
+
//# sourceMappingURL=factory.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.module.js","sourceRoot":"","sources":["../src/factory.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAsE;AACtE,2DAAsD;AACtD,uDAAmD;AAI5C,IAAM,aAAa,qBAAnB,MAAM,aAAa;IACxB,MAAM,CAAC,OAAO,CAAC,UAAgC,EAAE;QAC/C,MAAM,SAAS,GAAe;YAC5B,EAAE,OAAO,EAAE,mCAAe,EAAE,QAAQ,EAAE,OAAO,EAAE;YAC/C,gCAAc;SACf,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,eAAa;YACrB,MAAM,EAAE,IAAI;YACZ,SAAS;YACT,OAAO,EAAE,CAAC,gCAAc,EAAE,mCAAe,CAAC;SAC3C,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,YAAiC;QACnD,MAAM,SAAS,GAAe;YAC5B;gBACE,OAAO,EAAE,mCAAe;gBACxB,UAAU,EAAE,YAAY,CAAC,UAAW;gBACpC,MAAM,EAAE,YAAY,CAAC,MAAM,IAAI,EAAE;aAClC;YACD,gCAAc;SACf,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,eAAa;YACrB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YAC1C,SAAS;YACT,OAAO,EAAE,CAAC,gCAAc,EAAE,mCAAe,CAAC;SAC3C,CAAC;IACJ,CAAC;CACF,CAAA;AAjCY,sCAAa;wBAAb,aAAa;IADzB,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,aAAa,CAiCzB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { OnModuleDestroy, OnModuleInit } from "@nestjs/common";
|
|
2
|
+
import { DataSource } from "typeorm";
|
|
3
|
+
import { Faker } from "@faker-js/faker";
|
|
4
|
+
import { FactoryBuilder } from "./factory-builder";
|
|
5
|
+
import type { FactoryModuleOptions, FactoryClass, SeederClass } from "./interfaces";
|
|
6
|
+
interface EventEmitterLike {
|
|
7
|
+
emit(event: string, ...args: any[]): boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class FactoryService implements OnModuleInit, OnModuleDestroy {
|
|
10
|
+
private readonly options;
|
|
11
|
+
private readonly dataSource?;
|
|
12
|
+
private readonly eventEmitter?;
|
|
13
|
+
private static instance;
|
|
14
|
+
private readonly logger;
|
|
15
|
+
private readonly factoryInstances;
|
|
16
|
+
private _faker;
|
|
17
|
+
constructor(options: FactoryModuleOptions, dataSource?: DataSource | undefined, eventEmitter?: EventEmitterLike | undefined);
|
|
18
|
+
onModuleInit(): void;
|
|
19
|
+
onModuleDestroy(): void;
|
|
20
|
+
static getInstance(): FactoryService | null;
|
|
21
|
+
getOptions(): FactoryModuleOptions;
|
|
22
|
+
getFaker(): Faker;
|
|
23
|
+
use<T>(factoryClass: FactoryClass<T>): FactoryBuilder<T>;
|
|
24
|
+
seed(): Promise<void>;
|
|
25
|
+
runSeeder(seederClass: SeederClass): Promise<void>;
|
|
26
|
+
private emit;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var FactoryService_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.FactoryService = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const typeorm_1 = require("typeorm");
|
|
19
|
+
const faker_1 = require("@faker-js/faker");
|
|
20
|
+
const factory_constants_1 = require("./factory.constants");
|
|
21
|
+
const factory_events_1 = require("./events/factory.events");
|
|
22
|
+
const factory_builder_1 = require("./factory-builder");
|
|
23
|
+
const factory_not_registered_exception_1 = require("./exceptions/factory-not-registered.exception");
|
|
24
|
+
let FactoryService = FactoryService_1 = class FactoryService {
|
|
25
|
+
constructor(options, dataSource, eventEmitter) {
|
|
26
|
+
this.options = options;
|
|
27
|
+
this.dataSource = dataSource;
|
|
28
|
+
this.eventEmitter = eventEmitter;
|
|
29
|
+
this.logger = new common_1.Logger(FactoryService_1.name);
|
|
30
|
+
this.factoryInstances = new Map();
|
|
31
|
+
this._faker = faker_1.faker;
|
|
32
|
+
if (options.seed != null) {
|
|
33
|
+
faker_1.faker.seed(options.seed);
|
|
34
|
+
}
|
|
35
|
+
if (options.factories) {
|
|
36
|
+
for (const FactoryClass of options.factories) {
|
|
37
|
+
const instance = new FactoryClass();
|
|
38
|
+
this.factoryInstances.set(FactoryClass.name, instance);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
onModuleInit() {
|
|
43
|
+
FactoryService_1.instance = this;
|
|
44
|
+
this.logger.log("FactoryService initialized");
|
|
45
|
+
}
|
|
46
|
+
onModuleDestroy() {
|
|
47
|
+
if (FactoryService_1.instance === this) {
|
|
48
|
+
FactoryService_1.instance = null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
static getInstance() {
|
|
52
|
+
return FactoryService_1.instance;
|
|
53
|
+
}
|
|
54
|
+
getOptions() {
|
|
55
|
+
return this.options;
|
|
56
|
+
}
|
|
57
|
+
getFaker() {
|
|
58
|
+
return this._faker;
|
|
59
|
+
}
|
|
60
|
+
use(factoryClass) {
|
|
61
|
+
const instance = this.factoryInstances.get(factoryClass.name);
|
|
62
|
+
if (!instance) {
|
|
63
|
+
throw new factory_not_registered_exception_1.FactoryNotRegisteredException(factoryClass.name);
|
|
64
|
+
}
|
|
65
|
+
return new factory_builder_1.FactoryBuilder(instance, this._faker, this.dataSource ?? null);
|
|
66
|
+
}
|
|
67
|
+
async seed() {
|
|
68
|
+
const seeders = this.options.seeders ?? [];
|
|
69
|
+
this.emit(factory_events_1.FACTORY_EVENTS.SEED_ALL_STARTED, { seederCount: seeders.length });
|
|
70
|
+
const sorted = [...seeders].sort((a, b) => {
|
|
71
|
+
const orderA = new a().order ?? 0;
|
|
72
|
+
const orderB = new b().order ?? 0;
|
|
73
|
+
return orderA - orderB;
|
|
74
|
+
});
|
|
75
|
+
for (const SeederClass of sorted) {
|
|
76
|
+
await this.runSeeder(SeederClass);
|
|
77
|
+
}
|
|
78
|
+
this.emit(factory_events_1.FACTORY_EVENTS.SEED_ALL_COMPLETED, { seederCount: seeders.length });
|
|
79
|
+
}
|
|
80
|
+
async runSeeder(seederClass) {
|
|
81
|
+
const seeder = new seederClass();
|
|
82
|
+
const name = seederClass.name;
|
|
83
|
+
this.logger.log(`Running seeder: ${name}`);
|
|
84
|
+
this.emit(factory_events_1.FACTORY_EVENTS.SEEDER_STARTED, { seederClass: name });
|
|
85
|
+
await seeder.run(this);
|
|
86
|
+
this.logger.log(`Completed seeder: ${name}`);
|
|
87
|
+
this.emit(factory_events_1.FACTORY_EVENTS.SEEDER_COMPLETED, { seederClass: name });
|
|
88
|
+
}
|
|
89
|
+
emit(event, payload) {
|
|
90
|
+
if (this.eventEmitter) {
|
|
91
|
+
this.eventEmitter.emit(event, payload);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
exports.FactoryService = FactoryService;
|
|
96
|
+
FactoryService.instance = null;
|
|
97
|
+
exports.FactoryService = FactoryService = FactoryService_1 = __decorate([
|
|
98
|
+
(0, common_1.Injectable)(),
|
|
99
|
+
__param(0, (0, common_1.Inject)(factory_constants_1.FACTORY_OPTIONS)),
|
|
100
|
+
__param(1, (0, common_1.Optional)()),
|
|
101
|
+
__param(2, (0, common_1.Optional)()),
|
|
102
|
+
__param(2, (0, common_1.Inject)("EventEmitter2")),
|
|
103
|
+
__metadata("design:paramtypes", [Object, typeorm_1.DataSource, Object])
|
|
104
|
+
], FactoryService);
|
|
105
|
+
//# sourceMappingURL=factory.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.service.js","sourceRoot":"","sources":["../src/factory.service.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { FactoryModule } from "./factory.module";
|
|
2
|
+
export { FactoryService } from "./factory.service";
|
|
3
|
+
export { BaseFactory } from "./base-factory";
|
|
4
|
+
export { FactoryBuilder } from "./factory-builder";
|
|
5
|
+
export { Sequence } from "./sequence";
|
|
6
|
+
export { FACTORY_OPTIONS } from "./factory.constants";
|
|
7
|
+
export { FACTORY_EVENTS, type SeederStartedEvent, type SeederCompletedEvent, type SeedAllStartedEvent, type SeedAllCompletedEvent, } from "./events";
|
|
8
|
+
export type { FactoryModuleOptions, FactoryAsyncOptions, FactoryClass, SeederClass, Seeder, } from "./interfaces";
|
|
9
|
+
export { FactoryNotInitializedException } from "./exceptions";
|
|
10
|
+
export { FactoryNotRegisteredException } from "./exceptions";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FactoryNotRegisteredException = exports.FactoryNotInitializedException = exports.FACTORY_EVENTS = exports.FACTORY_OPTIONS = exports.Sequence = exports.FactoryBuilder = exports.BaseFactory = exports.FactoryService = exports.FactoryModule = void 0;
|
|
4
|
+
var factory_module_1 = require("./factory.module");
|
|
5
|
+
Object.defineProperty(exports, "FactoryModule", { enumerable: true, get: function () { return factory_module_1.FactoryModule; } });
|
|
6
|
+
var factory_service_1 = require("./factory.service");
|
|
7
|
+
Object.defineProperty(exports, "FactoryService", { enumerable: true, get: function () { return factory_service_1.FactoryService; } });
|
|
8
|
+
var base_factory_1 = require("./base-factory");
|
|
9
|
+
Object.defineProperty(exports, "BaseFactory", { enumerable: true, get: function () { return base_factory_1.BaseFactory; } });
|
|
10
|
+
var factory_builder_1 = require("./factory-builder");
|
|
11
|
+
Object.defineProperty(exports, "FactoryBuilder", { enumerable: true, get: function () { return factory_builder_1.FactoryBuilder; } });
|
|
12
|
+
var sequence_1 = require("./sequence");
|
|
13
|
+
Object.defineProperty(exports, "Sequence", { enumerable: true, get: function () { return sequence_1.Sequence; } });
|
|
14
|
+
var factory_constants_1 = require("./factory.constants");
|
|
15
|
+
Object.defineProperty(exports, "FACTORY_OPTIONS", { enumerable: true, get: function () { return factory_constants_1.FACTORY_OPTIONS; } });
|
|
16
|
+
var events_1 = require("./events");
|
|
17
|
+
Object.defineProperty(exports, "FACTORY_EVENTS", { enumerable: true, get: function () { return events_1.FACTORY_EVENTS; } });
|
|
18
|
+
var exceptions_1 = require("./exceptions");
|
|
19
|
+
Object.defineProperty(exports, "FactoryNotInitializedException", { enumerable: true, get: function () { return exceptions_1.FactoryNotInitializedException; } });
|
|
20
|
+
var exceptions_2 = require("./exceptions");
|
|
21
|
+
Object.defineProperty(exports, "FactoryNotRegisteredException", { enumerable: true, get: function () { return exceptions_2.FactoryNotRegisteredException; } });
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,yDAAsD;AAA7C,oHAAA,eAAe,OAAA;AACxB,mCAMkB;AALhB,wGAAA,cAAc,OAAA;AAahB,2CAA8D;AAArD,4HAAA,8BAA8B,OAAA;AACvC,2CAA6D;AAApD,2HAAA,6BAA6B,OAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BaseFactory } from "../base-factory";
|
|
2
|
+
import type { Seeder } from "./seeder.interface";
|
|
3
|
+
export type FactoryClass<T = any> = new () => BaseFactory<T>;
|
|
4
|
+
export type SeederClass = new () => Seeder;
|
|
5
|
+
export interface FactoryModuleOptions {
|
|
6
|
+
factories?: FactoryClass[];
|
|
7
|
+
seeders?: SeederClass[];
|
|
8
|
+
seed?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface FactoryAsyncOptions {
|
|
11
|
+
imports?: any[];
|
|
12
|
+
inject?: any[];
|
|
13
|
+
useFactory?: (...args: any[]) => Promise<FactoryModuleOptions> | FactoryModuleOptions;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory-options.interface.js","sourceRoot":"","sources":["../../src/interfaces/factory-options.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeder.interface.js","sourceRoot":"","sources":["../../src/interfaces/seeder.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare class Sequence<T = any> {
|
|
2
|
+
private readonly callback;
|
|
3
|
+
private index;
|
|
4
|
+
constructor(callback: (index: number) => T);
|
|
5
|
+
static increment(start?: number): Sequence<number>;
|
|
6
|
+
static cycle<V>(values: V[]): Sequence<V>;
|
|
7
|
+
static from<V>(callback: (index: number) => V): Sequence<V>;
|
|
8
|
+
next(): T;
|
|
9
|
+
reset(): void;
|
|
10
|
+
}
|
package/dist/sequence.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Sequence = void 0;
|
|
4
|
+
class Sequence {
|
|
5
|
+
constructor(callback) {
|
|
6
|
+
this.callback = callback;
|
|
7
|
+
this.index = 0;
|
|
8
|
+
}
|
|
9
|
+
static increment(start = 1) {
|
|
10
|
+
return new Sequence((i) => start + i);
|
|
11
|
+
}
|
|
12
|
+
static cycle(values) {
|
|
13
|
+
return new Sequence((i) => values[i % values.length]);
|
|
14
|
+
}
|
|
15
|
+
static from(callback) {
|
|
16
|
+
return new Sequence(callback);
|
|
17
|
+
}
|
|
18
|
+
next() {
|
|
19
|
+
return this.callback(this.index++);
|
|
20
|
+
}
|
|
21
|
+
reset() {
|
|
22
|
+
this.index = 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.Sequence = Sequence;
|
|
26
|
+
//# sourceMappingURL=sequence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequence.js","sourceRoot":"","sources":["../src/sequence.ts"],"names":[],"mappings":";;;AAAA,MAAa,QAAQ;IAGnB,YAA6B,QAA8B;QAA9B,aAAQ,GAAR,QAAQ,CAAsB;QAFnD,UAAK,GAAG,CAAC,CAAC;IAE4C,CAAC;IAE/D,MAAM,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC;QACxB,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,KAAK,CAAI,MAAW;QACzB,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,IAAI,CAAI,QAA8B;QAC3C,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACjB,CAAC;CACF;AAxBD,4BAwBC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nestbolt/factory",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Model factories and database seeders for NestJS with TypeORM.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"keywords": [
|
|
17
|
+
"nestjs",
|
|
18
|
+
"factory",
|
|
19
|
+
"factories",
|
|
20
|
+
"seeder",
|
|
21
|
+
"database-seeder",
|
|
22
|
+
"faker",
|
|
23
|
+
"test-data",
|
|
24
|
+
"typeorm",
|
|
25
|
+
"model-factory"
|
|
26
|
+
],
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/nestbolt/factory"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20.0.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@faker-js/faker": "^9.0.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
|
40
|
+
"@nestjs/core": "^10.0.0 || ^11.0.0",
|
|
41
|
+
"@nestjs/event-emitter": "^2.0.0 || ^3.0.0",
|
|
42
|
+
"@nestjs/typeorm": "^10.0.0 || ^11.0.0",
|
|
43
|
+
"reflect-metadata": "^0.1.13 || ^0.2.0",
|
|
44
|
+
"typeorm": "^0.3.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependenciesMeta": {
|
|
47
|
+
"@nestjs/event-emitter": {
|
|
48
|
+
"optional": true
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@eslint/js": "^9.0.0",
|
|
53
|
+
"@nestjs/common": "^11.0.0",
|
|
54
|
+
"@nestjs/core": "^11.0.0",
|
|
55
|
+
"@nestjs/testing": "^11.0.0",
|
|
56
|
+
"@nestjs/typeorm": "^11.0.0",
|
|
57
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
58
|
+
"@types/node": "^20.0.0",
|
|
59
|
+
"@vitest/coverage-v8": "^4.1.0",
|
|
60
|
+
"better-sqlite3": "^12.8.0",
|
|
61
|
+
"eslint": "^9.0.0",
|
|
62
|
+
"eslint-config-prettier": "^10.0.0",
|
|
63
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
64
|
+
"prettier": "^3.0.0",
|
|
65
|
+
"reflect-metadata": "^0.2.2",
|
|
66
|
+
"rxjs": "^7.8.0",
|
|
67
|
+
"typeorm": "^0.3.0",
|
|
68
|
+
"typescript": "^5.5.0",
|
|
69
|
+
"typescript-eslint": "^8.0.0",
|
|
70
|
+
"vitest": "^4.1.0"
|
|
71
|
+
},
|
|
72
|
+
"scripts": {
|
|
73
|
+
"build": "tsc -p tsconfig.build.json",
|
|
74
|
+
"test": "vitest run",
|
|
75
|
+
"test:watch": "vitest",
|
|
76
|
+
"test:cov": "vitest run --coverage",
|
|
77
|
+
"test:results": "npx vitest run --coverage 2>&1 | grep -E \"All files|%\" | head -10",
|
|
78
|
+
"lint": "eslint 'src/**/*.ts' 'test/**/*.ts'",
|
|
79
|
+
"lint:fix": "eslint 'src/**/*.ts' 'test/**/*.ts' --fix",
|
|
80
|
+
"format": "prettier --write 'src/**/*.ts' 'test/**/*.ts'"
|
|
81
|
+
}
|
|
82
|
+
}
|