@ackplus/nest-seeder 1.1.12 โ†’ 1.1.17

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 CHANGED
@@ -1,110 +1,84 @@
1
1
  # @ackplus/nest-seeder
2
2
 
3
- <p align="center">
4
- <a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
5
- </p>
6
-
7
3
  A powerful and flexible database seeding library for NestJS applications with support for factories, data generation using Faker.js, and CLI commands.
8
4
 
9
- ## ๐Ÿ“‹ Table of Contents
10
-
11
- - [Features](#-features)
12
- - [Installation](#-installation)
13
- - [Quick Start](#-quick-start)
14
- - [Configuration](#-configuration)
15
- - [Basic Setup](#basic-setup)
16
- - [Async Configuration](#async-configuration)
17
- - [Creating Seeders](#-creating-seeders)
18
- - [Basic Seeder](#basic-seeder)
19
- - [Using TypeORM](#using-typeorm)
20
- - [Using Mongoose](#using-mongoose)
21
- - [Using Prisma](#using-prisma)
22
- - [Data Factories](#-data-factories)
23
- - [Basic Factory](#basic-factory)
24
- - [Factory with Dependencies](#factory-with-dependencies)
25
- - [Custom Generators](#custom-generators)
26
- - [CLI Usage](#-cli-usage)
27
- - [Setup CLI](#setup-cli)
28
- - [CLI Commands](#cli-commands)
29
- - [Configuration File](#configuration-file)
30
- - [Programmatic Usage](#-programmatic-usage)
31
- - [Advanced Examples](#-advanced-examples)
32
- - [API Reference](#-api-reference)
33
- - [Publishing](#-publishing)
34
-
35
5
  ## โœจ Features
36
6
 
37
- - ๐ŸŽฏ **Type-safe** - Full TypeScript support
38
- - ๐Ÿญ **Factory Pattern** - Generate fake data easily with decorators
39
- - ๐ŸŽฒ **Faker.js Integration** - Built-in support for realistic fake data
40
- - ๐Ÿ”„ **Refresh Mode** - Drop existing data before seeding
7
+ - ๐ŸŒฑ **CLI-Based** - Simple command-line interface, no app code modifications needed
8
+ - ๐Ÿญ **Factory Pattern** - Generate realistic test data with Faker.js
9
+ - ๐Ÿ”„ **Multiple ORMs** - Support for TypeORM, Mongoose, and Prisma
10
+ - ๐Ÿ“ฆ **Batch Operations** - Efficient bulk data insertion
41
11
  - ๐ŸŽฏ **Selective Seeding** - Run specific seeders by name
42
- - ๐Ÿ“ฆ **Multiple ORMs** - Works with TypeORM, Mongoose, Prisma, and more
43
- - ๐Ÿ–ฅ๏ธ **CLI Support** - Run seeders from command line
44
- - โš™๏ธ **Flexible Configuration** - Sync and async configuration options
45
- - ๐Ÿ”— **Dependency Management** - Handle relationships between seeders
12
+ - ๐Ÿ”ฅ **Refresh Mode** - Drop existing data before seeding
13
+ - ๐Ÿงช **Test-Friendly** - Perfect for testing and development
14
+ - ๐Ÿ“ **TypeScript** - Full TypeScript support with type safety
46
15
 
47
16
  ## ๐Ÿ“ฆ Installation
48
17
 
49
18
  ```bash
50
- # Using npm
51
19
  npm install @ackplus/nest-seeder @faker-js/faker
52
-
53
- # Using yarn
54
- yarn add @ackplus/nest-seeder @faker-js/faker
55
-
56
- # Using pnpm
20
+ # or
57
21
  pnpm add @ackplus/nest-seeder @faker-js/faker
22
+ # or
23
+ yarn add @ackplus/nest-seeder @faker-js/faker
58
24
  ```
59
25
 
60
- ### Development Dependencies
26
+ **For TypeScript config files**, also install:
61
27
 
62
28
  ```bash
63
- # If using TypeScript files for seeders (recommended)
64
29
  npm install -D ts-node typescript
65
-
66
- # If using CLI
67
- npm install -D @nestjs/cli
68
30
  ```
69
31
 
70
- ## ๐Ÿš€ Quick Start
32
+ ## ๐Ÿš€ Quick Start (5 Steps)
33
+
34
+ ### Step 1: Create Entity
35
+
36
+ ```typescript
37
+ // src/entities/user.entity.ts
38
+ import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
39
+
40
+ @Entity('users')
41
+ export class User {
42
+ @PrimaryGeneratedColumn()
43
+ id: number;
71
44
 
72
- ### 1. Create a Factory Class
45
+ @Column()
46
+ name: string;
73
47
 
74
- Create a factory class with the `@Factory` decorator to define how to generate fake data:
48
+ @Column({ unique: true })
49
+ email: string;
50
+
51
+ @Column()
52
+ role: string;
53
+ }
54
+ ```
55
+
56
+ ### Step 2: Create Factory
75
57
 
76
58
  ```typescript
77
- // src/database/factories/user.factory.ts
59
+ // src/factories/user.factory.ts
78
60
  import { Factory } from '@ackplus/nest-seeder';
79
61
 
80
62
  export class UserFactory {
63
+ @Factory((faker) => faker.person.fullName())
64
+ name: string;
65
+
81
66
  @Factory((faker) => faker.internet.email())
82
67
  email: string;
83
68
 
84
- @Factory((faker) => faker.person.firstName())
85
- firstName: string;
86
-
87
- @Factory((faker) => faker.person.lastName())
88
- lastName: string;
89
-
90
- @Factory((faker) => faker.internet.password())
91
- password: string;
92
-
93
- @Factory((faker) => faker.datatype.boolean())
94
- isActive: boolean;
69
+ @Factory((faker) => faker.helpers.arrayElement(['admin', 'user', 'guest']))
70
+ role: string;
95
71
  }
96
72
  ```
97
73
 
98
- ### 2. Create a Seeder
99
-
100
- Create a seeder class that implements the `Seeder` interface:
74
+ ### Step 3: Create Seeder
101
75
 
102
76
  ```typescript
103
- // src/database/seeders/user.seeder.ts
77
+ // src/seeders/user.seeder.ts
104
78
  import { Injectable } from '@nestjs/common';
105
79
  import { InjectRepository } from '@nestjs/typeorm';
106
80
  import { Repository } from 'typeorm';
107
- import { Seeder, SeederServiceOptions, DataFactory } from '@ackplus/nest-seeder';
81
+ import { Seeder, DataFactory } from '@ackplus/nest-seeder';
108
82
  import { User } from '../entities/user.entity';
109
83
  import { UserFactory } from '../factories/user.factory';
110
84
 
@@ -115,34 +89,41 @@ export class UserSeeder implements Seeder {
115
89
  private readonly userRepository: Repository<User>,
116
90
  ) {}
117
91
 
118
- async seed(options: SeederServiceOptions): Promise<void> {
119
- // Generate 10 fake users
92
+ async seed(): Promise<void> {
93
+ // Create factory instance
120
94
  const factory = DataFactory.createForClass(UserFactory);
95
+
96
+ // Generate 10 users
121
97
  const users = factory.generate(10);
122
98
 
123
99
  // Save to database
124
100
  await this.userRepository.save(users);
101
+
102
+ console.log('โœ… Seeded 10 users');
125
103
  }
126
104
 
127
- async drop(options: SeederServiceOptions): Promise<void> {
128
- // Clean up - delete all users
105
+ async drop(): Promise<void> {
106
+ // Clear all users
129
107
  await this.userRepository.delete({});
108
+
109
+ console.log('๐Ÿ—‘๏ธ Dropped all users');
130
110
  }
131
111
  }
132
112
  ```
133
113
 
134
- ### 3. Register Seeder Module
114
+ ### Step 4: Create Configuration File
115
+
116
+ Create `seeder.config.ts` in your **project root**:
135
117
 
136
118
  ```typescript
137
- // src/app.module.ts
138
- import { Module } from '@nestjs/common';
119
+ // seeder.config.ts
139
120
  import { TypeOrmModule } from '@nestjs/typeorm';
140
- import { SeederModule } from '@ackplus/nest-seeder';
141
- import { User } from './database/entities/user.entity';
142
- import { UserSeeder } from './database/seeders/user.seeder';
121
+ import { User } from './src/entities/user.entity';
122
+ import { UserSeeder } from './src/seeders/user.seeder';
143
123
 
144
- @Module({
124
+ export default {
145
125
  imports: [
126
+ // Database configuration
146
127
  TypeOrmModule.forRoot({
147
128
  type: 'postgres',
148
129
  host: 'localhost',
@@ -153,244 +134,228 @@ import { UserSeeder } from './database/seeders/user.seeder';
153
134
  entities: [User],
154
135
  synchronize: true,
155
136
  }),
137
+
138
+ // Register repositories
156
139
  TypeOrmModule.forFeature([User]),
157
- SeederModule.register({
158
- seeders: [UserSeeder],
159
- }),
160
140
  ],
161
- })
162
- export class AppModule {}
141
+
142
+ // List seeders (run in order)
143
+ seeders: [UserSeeder],
144
+ };
163
145
  ```
164
146
 
165
- ### 4. Run the Seeder
147
+ ### Step 5: Run Seeder
166
148
 
167
- ```typescript
168
- // src/seed.ts
169
- import { NestFactory } from '@nestjs/core';
170
- import { SeederService } from '@ackplus/nest-seeder';
171
- import { AppModule } from './app.module';
172
-
173
- async function bootstrap() {
174
- const app = await NestFactory.createApplicationContext(AppModule);
175
- const seeder = app.get(SeederService);
176
-
177
- await seeder.run();
178
-
179
- await app.close();
180
- }
149
+ Add script to `package.json`:
181
150
 
182
- bootstrap();
151
+ ```json
152
+ {
153
+ "scripts": {
154
+ "seed": "nest-seed -c seeder.config.ts"
155
+ }
156
+ }
183
157
  ```
184
158
 
185
159
  Run it:
160
+
186
161
  ```bash
187
- ts-node src/seed.ts
162
+ npm run seed
188
163
  ```
189
164
 
190
- ## โš™๏ธ Configuration
165
+ **That's it!** Your database is now seeded! ๐ŸŽ‰
191
166
 
192
- ### Basic Setup
167
+ ## ๐Ÿ–ฅ๏ธ CLI Commands
193
168
 
194
- Register the `SeederModule` with your seeders:
169
+ ### Basic Usage
195
170
 
196
- ```typescript
197
- import { SeederModule } from '@ackplus/nest-seeder';
171
+ ```bash
172
+ # Run all seeders
173
+ nest-seed -c seeder.config.ts
198
174
 
199
- @Module({
200
- imports: [
201
- SeederModule.register({
202
- seeders: [UserSeeder, PostSeeder, CommentSeeder],
203
- imports: [TypeOrmModule.forFeature([User, Post, Comment])],
204
- providers: [/* additional providers */],
205
- }),
206
- ],
207
- })
208
- export class AppModule {}
175
+ # Drop and reseed
176
+ nest-seed -c seeder.config.ts --refresh
177
+
178
+ # Run specific seeder
179
+ nest-seed -c seeder.config.ts --name UserSeeder
180
+
181
+ # Run multiple seeders
182
+ nest-seed -c seeder.config.ts --name UserSeeder ProductSeeder
209
183
  ```
210
184
 
211
- ### Async Configuration
185
+ ### Available Options
212
186
 
213
- For dynamic configuration (e.g., loading from ConfigService):
187
+ | Option | Alias | Description | Default |
188
+ |--------|-------|-------------|---------|
189
+ | `--config` | `-c` | Path to configuration file | (required) |
190
+ | `--refresh` | `-r` | Drop data before seeding | `false` |
191
+ | `--name` | `-n` | Run specific seeder(s) | (all) |
192
+ | `--dummyData` | `-d` | Include dummy data flag | `false` |
193
+ | `--help` | `-h` | Show help | |
214
194
 
215
- #### Using Factory
195
+ ### Package.json Scripts
196
+
197
+ ```json
198
+ {
199
+ "scripts": {
200
+ "seed": "nest-seed -c seeder.config.ts",
201
+ "seed:refresh": "nest-seed -c seeder.config.ts -r",
202
+ "seed:users": "nest-seed -c seeder.config.ts -n UserSeeder",
203
+ "seed:watch": "nodemon --watch src/seeders --ext ts --exec nest-seed -c seeder.config.ts"
204
+ }
205
+ }
206
+ ```
207
+
208
+ ## โš™๏ธ Configuration
209
+
210
+ ### TypeORM Example
216
211
 
217
212
  ```typescript
218
- import { SeederModule } from '@ackplus/nest-seeder';
219
- import { ConfigModule, ConfigService } from '@nestjs/config';
213
+ // seeder.config.ts
214
+ import { TypeOrmModule } from '@nestjs/typeorm';
215
+ import { User, Post, Comment } from './src/entities';
216
+ import { UserSeeder, PostSeeder, CommentSeeder } from './src/seeders';
220
217
 
221
- @Module({
218
+ export default {
222
219
  imports: [
223
- SeederModule.forRootAsync({
224
- imports: [ConfigModule, TypeOrmModule.forFeature([User, Post])],
225
- inject: [UserSeeder, PostSeeder],
226
- useFactory: async (config: ConfigService) => ({
227
- seeders: [UserSeeder, PostSeeder],
228
- refresh: config.get('SEED_REFRESH', false),
229
- dummyData: config.get('SEED_DUMMY_DATA', false),
230
- }),
231
- isGlobal: true,
220
+ TypeOrmModule.forRoot({
221
+ type: 'postgres',
222
+ host: process.env.DB_HOST || 'localhost',
223
+ port: parseInt(process.env.DB_PORT) || 5432,
224
+ username: process.env.DB_USER || 'postgres',
225
+ password: process.env.DB_PASSWORD || 'postgres',
226
+ database: process.env.DB_NAME || 'mydb',
227
+ entities: [User, Post, Comment],
228
+ synchronize: true,
232
229
  }),
230
+ TypeOrmModule.forFeature([User, Post, Comment]),
233
231
  ],
234
- })
235
- export class AppModule {}
232
+ seeders: [UserSeeder, PostSeeder, CommentSeeder],
233
+ };
236
234
  ```
237
235
 
238
- #### Using Class
236
+ ### MongoDB/Mongoose Example
239
237
 
240
238
  ```typescript
241
- import { Injectable } from '@nestjs/common';
242
- import { SeederOptionsFactory, SeederModuleOptions } from '@ackplus/nest-seeder';
243
- import { ConfigService } from '@nestjs/config';
239
+ // seeder.config.ts
240
+ import { MongooseModule } from '@nestjs/mongoose';
241
+ import { User, UserSchema } from './src/schemas/user.schema';
242
+ import { UserSeeder } from './src/seeders/user.seeder';
244
243
 
245
- @Injectable()
246
- export class SeederConfigService implements SeederOptionsFactory {
247
- constructor(private configService: ConfigService) {}
248
-
249
- createSeederOptions(): SeederModuleOptions {
250
- return {
251
- seeders: [UserSeeder, PostSeeder],
252
- refresh: this.configService.get('SEED_REFRESH', false),
253
- };
254
- }
255
- }
244
+ export default {
245
+ imports: [
246
+ MongooseModule.forRoot('mongodb://localhost/mydb'),
247
+ MongooseModule.forFeature([
248
+ { name: User.name, schema: UserSchema }
249
+ ]),
250
+ ],
251
+ seeders: [UserSeeder],
252
+ };
253
+ ```
254
+
255
+ ### SQLite Example
256
+
257
+ ```typescript
258
+ // seeder.config.ts
259
+ import { TypeOrmModule } from '@nestjs/typeorm';
260
+ import { User } from './src/entities/user.entity';
261
+ import { UserSeeder } from './src/seeders/user.seeder';
256
262
 
257
- @Module({
263
+ export default {
258
264
  imports: [
259
- SeederModule.forRootAsync({
260
- imports: [ConfigModule],
261
- useClass: SeederConfigService,
262
- isGlobal: true,
265
+ TypeOrmModule.forRoot({
266
+ type: 'sqlite',
267
+ database: 'database.sqlite',
268
+ entities: [User],
269
+ synchronize: true,
263
270
  }),
271
+ TypeOrmModule.forFeature([User]),
264
272
  ],
265
- })
266
- export class AppModule {}
273
+ seeders: [UserSeeder],
274
+ };
267
275
  ```
268
276
 
269
- ## ๐ŸŒฑ Creating Seeders
270
-
271
- ### Basic Seeder
277
+ ## ๐Ÿญ Factories
272
278
 
273
- Every seeder must implement the `Seeder` interface with `seed()` and `drop()` methods:
279
+ ### Basic Factory
274
280
 
275
281
  ```typescript
276
- import { Injectable } from '@nestjs/common';
277
- import { Seeder, SeederServiceOptions } from '@ackplus/nest-seeder';
282
+ import { Factory } from '@ackplus/nest-seeder';
278
283
 
279
- @Injectable()
280
- export class BasicSeeder implements Seeder {
281
- async seed(options: SeederServiceOptions): Promise<void> {
282
- console.log('Seeding data...');
283
- // Your seeding logic here
284
- }
284
+ export class UserFactory {
285
+ @Factory((faker) => faker.person.fullName())
286
+ name: string;
285
287
 
286
- async drop(options: SeederServiceOptions): Promise<void> {
287
- console.log('Dropping data...');
288
- // Your cleanup logic here
289
- }
288
+ @Factory((faker) => faker.internet.email())
289
+ email: string;
290
+
291
+ @Factory((faker) => faker.datatype.number({ min: 18, max: 80 }))
292
+ age: number;
290
293
  }
291
294
  ```
292
295
 
293
- ### Using TypeORM
296
+ ### Using Factory
294
297
 
295
298
  ```typescript
296
- import { Injectable } from '@nestjs/common';
297
- import { InjectRepository } from '@nestjs/typeorm';
298
- import { Repository } from 'typeorm';
299
- import { Seeder, SeederServiceOptions, DataFactory } from '@ackplus/nest-seeder';
300
- import { User } from '../entities/user.entity';
301
- import { UserFactory } from '../factories/user.factory';
302
-
303
- @Injectable()
304
- export class UserSeeder implements Seeder {
305
- constructor(
306
- @InjectRepository(User)
307
- private readonly userRepository: Repository<User>,
308
- ) {}
299
+ import { DataFactory } from '@ackplus/nest-seeder';
300
+ import { UserFactory } from './user.factory';
309
301
 
310
- async seed(options: SeederServiceOptions): Promise<void> {
311
- const factory = DataFactory.createForClass(UserFactory);
312
-
313
- // Generate different amounts based on options
314
- const count = options.dummyData ? 100 : 10;
315
- const users = factory.generate(count);
302
+ // Create factory
303
+ const factory = DataFactory.createForClass(UserFactory);
316
304
 
317
- // Insert in batches for better performance
318
- const batchSize = 50;
319
- for (let i = 0; i < users.length; i += batchSize) {
320
- const batch = users.slice(i, i + batchSize);
321
- await this.userRepository.save(batch);
322
- }
305
+ // Generate one object
306
+ const user = factory.generate(1)[0];
323
307
 
324
- console.log(`โœ… Seeded ${users.length} users`);
325
- }
308
+ // Generate multiple objects
309
+ const users = factory.generate(10);
326
310
 
327
- async drop(options: SeederServiceOptions): Promise<void> {
328
- await this.userRepository.delete({});
329
- console.log('โœ… Dropped all users');
330
- }
331
- }
311
+ // Generate with overrides
312
+ const admin = factory.generate(1, { role: 'admin' })[0];
332
313
  ```
333
314
 
334
- ### Using Mongoose
315
+ ### Factory with Relationships
335
316
 
336
317
  ```typescript
337
- import { Injectable } from '@nestjs/common';
338
- import { InjectModel } from '@nestjs/mongoose';
339
- import { Model } from 'mongoose';
340
- import { Seeder, SeederServiceOptions, DataFactory } from '@ackplus/nest-seeder';
341
- import { User, UserDocument } from '../schemas/user.schema';
342
- import { UserFactory } from '../factories/user.factory';
343
-
344
- @Injectable()
345
- export class UserSeeder implements Seeder {
346
- constructor(
347
- @InjectModel(User.name)
348
- private userModel: Model<UserDocument>,
349
- ) {}
318
+ import { Factory } from '@ackplus/nest-seeder';
350
319
 
351
- async seed(options: SeederServiceOptions): Promise<void> {
352
- const factory = DataFactory.createForClass(UserFactory);
353
- const users = factory.generate(10);
320
+ export class PostFactory {
321
+ @Factory((faker) => faker.lorem.sentence())
322
+ title: string;
354
323
 
355
- await this.userModel.insertMany(users);
356
- console.log('โœ… Seeded 10 users');
357
- }
324
+ @Factory((faker) => faker.lorem.paragraphs(3))
325
+ content: string;
358
326
 
359
- async drop(options: SeederServiceOptions): Promise<void> {
360
- await this.userModel.deleteMany({});
361
- console.log('โœ… Dropped all users');
362
- }
327
+ // Will be set manually in seeder
328
+ authorId: number;
363
329
  }
364
330
  ```
365
331
 
366
- ### Using Prisma
332
+ ## ๐ŸŒฑ Seeders
333
+
334
+ ### Basic Seeder
367
335
 
368
336
  ```typescript
369
337
  import { Injectable } from '@nestjs/common';
370
- import { Seeder, SeederServiceOptions, DataFactory } from '@ackplus/nest-seeder';
371
- import { PrismaService } from '../prisma.service';
338
+ import { InjectRepository } from '@nestjs/typeorm';
339
+ import { Repository } from 'typeorm';
340
+ import { Seeder, DataFactory } from '@ackplus/nest-seeder';
341
+ import { User } from '../entities/user.entity';
372
342
  import { UserFactory } from '../factories/user.factory';
373
343
 
374
344
  @Injectable()
375
345
  export class UserSeeder implements Seeder {
376
- constructor(private readonly prisma: PrismaService) {}
346
+ constructor(
347
+ @InjectRepository(User)
348
+ private readonly userRepository: Repository<User>,
349
+ ) {}
377
350
 
378
- async seed(options: SeederServiceOptions): Promise<void> {
351
+ async seed(): Promise<void> {
379
352
  const factory = DataFactory.createForClass(UserFactory);
380
353
  const users = factory.generate(10);
381
-
382
- // Use createMany for better performance
383
- await this.prisma.user.createMany({
384
- data: users,
385
- skipDuplicates: true,
386
- });
387
-
388
- console.log('โœ… Seeded 10 users');
354
+ await this.userRepository.save(users);
389
355
  }
390
356
 
391
- async drop(options: SeederServiceOptions): Promise<void> {
392
- await this.prisma.user.deleteMany({});
393
- console.log('โœ… Dropped all users');
357
+ async drop(): Promise<void> {
358
+ await this.userRepository.delete({});
394
359
  }
395
360
  }
396
361
  ```
@@ -401,662 +366,228 @@ export class UserSeeder implements Seeder {
401
366
  import { Injectable } from '@nestjs/common';
402
367
  import { InjectRepository } from '@nestjs/typeorm';
403
368
  import { Repository } from 'typeorm';
404
- import { Seeder, SeederServiceOptions, DataFactory } from '@ackplus/nest-seeder';
405
- import { Post } from '../entities/post.entity';
369
+ import { Seeder, DataFactory } from '@ackplus/nest-seeder';
406
370
  import { User } from '../entities/user.entity';
371
+ import { Post } from '../entities/post.entity';
372
+ import { UserFactory } from '../factories/user.factory';
407
373
  import { PostFactory } from '../factories/post.factory';
408
374
 
409
375
  @Injectable()
410
376
  export class PostSeeder implements Seeder {
411
377
  constructor(
412
- @InjectRepository(Post)
413
- private readonly postRepository: Repository<Post>,
414
378
  @InjectRepository(User)
415
379
  private readonly userRepository: Repository<User>,
380
+ @InjectRepository(Post)
381
+ private readonly postRepository: Repository<Post>,
416
382
  ) {}
417
383
 
418
- async seed(options: SeederServiceOptions): Promise<void> {
384
+ async seed(): Promise<void> {
419
385
  // Get existing users
420
386
  const users = await this.userRepository.find();
421
387
 
422
388
  if (users.length === 0) {
423
- console.warn('โš ๏ธ No users found. Please run UserSeeder first.');
389
+ console.log('โš ๏ธ No users found. Run UserSeeder first.');
424
390
  return;
425
391
  }
426
392
 
427
- const factory = DataFactory.createForClass(PostFactory);
393
+ // Create posts for each user
394
+ const postFactory = DataFactory.createForClass(PostFactory);
428
395
 
429
- // Generate 5 posts per user
430
396
  for (const user of users) {
431
- const posts = factory.generate(5, {
432
- authorId: user.id,
433
- });
397
+ // Generate 3 posts per user
398
+ const posts = postFactory.generate(3).map(post => ({
399
+ ...post,
400
+ author: user,
401
+ }));
402
+
434
403
  await this.postRepository.save(posts);
435
404
  }
436
-
437
- console.log(`โœ… Seeded ${users.length * 5} posts`);
405
+
406
+ console.log(`โœ… Seeded ${users.length * 3} posts`);
438
407
  }
439
408
 
440
- async drop(options: SeederServiceOptions): Promise<void> {
409
+ async drop(): Promise<void> {
441
410
  await this.postRepository.delete({});
442
- console.log('โœ… Dropped all posts');
443
411
  }
444
412
  }
445
413
  ```
446
414
 
447
- ## ๐Ÿญ Data Factories
448
-
449
- ### Basic Factory
450
-
451
- Use the `@Factory` decorator to define how each property should be generated:
452
-
453
- ```typescript
454
- import { Factory } from '@ackplus/nest-seeder';
455
-
456
- export class UserFactory {
457
- @Factory((faker) => faker.internet.email())
458
- email: string;
459
-
460
- @Factory((faker) => faker.person.firstName())
461
- firstName: string;
462
-
463
- @Factory((faker) => faker.person.lastName())
464
- lastName: string;
465
-
466
- @Factory((faker) => faker.internet.password({ length: 10 }))
467
- password: string;
468
-
469
- @Factory((faker) => faker.datatype.boolean())
470
- isActive: boolean;
471
-
472
- @Factory((faker) => faker.date.past())
473
- createdAt: Date;
474
- }
475
- ```
476
-
477
- ### Static Values
478
-
479
- You can also provide static values instead of generators:
480
-
481
- ```typescript
482
- export class AdminFactory {
483
- @Factory('admin')
484
- role: string;
485
-
486
- @Factory(true)
487
- isActive: boolean;
488
-
489
- @Factory((faker) => faker.internet.email())
490
- email: string;
491
- }
492
- ```
493
-
494
- ### Factory with Dependencies
495
-
496
- Use the second parameter to specify dependencies between properties:
415
+ ### Conditional Seeding
497
416
 
498
417
  ```typescript
499
- export class UserFactory {
500
- @Factory((faker) => faker.person.firstName())
501
- firstName: string;
502
-
503
- @Factory((faker) => faker.person.lastName())
504
- lastName: string;
418
+ import { Injectable } from '@nestjs/common';
419
+ import { Seeder, SeederServiceOptions, DataFactory } from '@ackplus/nest-seeder';
505
420
 
506
- // This field depends on firstName and lastName
507
- @Factory((faker, ctx) => {
508
- return `${ctx.firstName}.${ctx.lastName}@example.com`.toLowerCase();
509
- }, ['firstName', 'lastName'])
510
- email: string;
421
+ @Injectable()
422
+ export class UserSeeder implements Seeder {
423
+ async seed(options?: SeederServiceOptions): Promise<void> {
424
+ const factory = DataFactory.createForClass(UserFactory);
425
+
426
+ // Seed more data if dummyData flag is set
427
+ const count = options?.dummyData ? 100 : 10;
428
+ const users = factory.generate(count);
429
+
430
+ await this.userRepository.save(users);
431
+ console.log(`โœ… Seeded ${count} users`);
432
+ }
511
433
 
512
- // This field depends on firstName and lastName
513
- @Factory((faker, ctx) => {
514
- return `${ctx.firstName} ${ctx.lastName}`;
515
- }, ['firstName', 'lastName'])
516
- fullName: string;
434
+ async drop(): Promise<void> {
435
+ await this.userRepository.delete({});
436
+ }
517
437
  }
518
438
  ```
519
439
 
520
- ### Custom Generators
521
-
522
- Create complex data with custom generator functions:
523
-
524
- ```typescript
525
- export class ProductFactory {
526
- @Factory((faker) => faker.commerce.productName())
527
- name: string;
528
-
529
- @Factory((faker) => faker.commerce.productDescription())
530
- description: string;
531
-
532
- @Factory((faker) => parseFloat(faker.commerce.price()))
533
- price: number;
534
-
535
- @Factory((faker) => faker.number.int({ min: 0, max: 1000 }))
536
- stock: number;
537
-
538
- @Factory((faker) => faker.helpers.arrayElement(['electronics', 'clothing', 'food', 'books']))
539
- category: string;
540
-
541
- @Factory((faker) => {
542
- return {
543
- weight: faker.number.float({ min: 0.1, max: 100, precision: 0.1 }),
544
- dimensions: {
545
- width: faker.number.int({ min: 1, max: 100 }),
546
- height: faker.number.int({ min: 1, max: 100 }),
547
- depth: faker.number.int({ min: 1, max: 100 }),
548
- },
549
- };
550
- })
551
- metadata: object;
440
+ Run with dummy data:
552
441
 
553
- @Factory((faker) => faker.helpers.arrayElements(['red', 'blue', 'green', 'yellow'], { min: 1, max: 3 }))
554
- colors: string[];
555
- }
442
+ ```bash
443
+ nest-seed -c seeder.config.ts --dummyData
556
444
  ```
557
445
 
558
- ### Using Factories
446
+ ### MongoDB/Mongoose Seeder
559
447
 
560
448
  ```typescript
561
- import { DataFactory } from '@ackplus/nest-seeder';
562
- import { UserFactory } from './user.factory';
563
-
564
- // Create a factory
565
- const factory = DataFactory.createForClass(UserFactory);
566
-
567
- // Generate single object
568
- const user = factory.generate(1)[0];
569
-
570
- // Generate multiple objects
571
- const users = factory.generate(10);
572
-
573
- // Generate with custom values (override factory defaults)
574
- const admins = factory.generate(5, {
575
- role: 'admin',
576
- isActive: true,
577
- });
578
-
579
- // Mix of factory-generated and custom values
580
- const users = factory.generate(3, {
581
- isActive: true, // Override this field
582
- // Other fields will be generated by factory
583
- });
584
- ```
585
-
586
- ## ๐Ÿ–ฅ๏ธ CLI Usage
587
-
588
- ### Setup CLI
589
-
590
- #### 1. Install CLI dependencies
449
+ import { Injectable } from '@nestjs/common';
450
+ import { InjectModel } from '@nestjs/mongoose';
451
+ import { Model } from 'mongoose';
452
+ import { Seeder, DataFactory } from '@ackplus/nest-seeder';
453
+ import { User } from '../schemas/user.schema';
454
+ import { UserFactory } from '../factories/user.factory';
591
455
 
592
- ```bash
593
- npm install -D ts-node typescript
594
- ```
456
+ @Injectable()
457
+ export class UserSeeder implements Seeder {
458
+ constructor(
459
+ @InjectModel(User.name)
460
+ private readonly userModel: Model<User>,
461
+ ) {}
595
462
 
596
- #### 2. Add CLI script to package.json
463
+ async seed(): Promise<void> {
464
+ const factory = DataFactory.createForClass(UserFactory);
465
+ const users = factory.generate(10);
466
+ await this.userModel.insertMany(users);
467
+ }
597
468
 
598
- ```json
599
- {
600
- "scripts": {
601
- "seed": "nest-seed -c ./src/database/seeder.config.ts",
602
- "seed:refresh": "nest-seed -c ./src/database/seeder.config.ts --refresh",
603
- "seed:user": "nest-seed -c ./src/database/seeder.config.ts --name UserSeeder"
469
+ async drop(): Promise<void> {
470
+ await this.userModel.deleteMany({});
604
471
  }
605
472
  }
606
473
  ```
607
474
 
608
- #### 3. Create a configuration file
609
-
610
- ```typescript
611
- // src/database/seeder.config.ts
612
- import { TypeOrmModule } from '@nestjs/typeorm';
613
- import { User } from './entities/user.entity';
614
- import { Post } from './entities/post.entity';
615
- import { UserSeeder } from './seeders/user.seeder';
616
- import { PostSeeder } from './seeders/post.seeder';
617
-
618
- export default {
619
- imports: [
620
- TypeOrmModule.forRoot({
621
- type: 'postgres',
622
- host: 'localhost',
623
- port: 5432,
624
- username: 'postgres',
625
- password: 'postgres',
626
- database: 'mydb',
627
- entities: [User, Post],
628
- synchronize: true,
629
- }),
630
- TypeOrmModule.forFeature([User, Post]),
631
- ],
632
- seeders: [UserSeeder, PostSeeder],
633
- };
634
- ```
635
-
636
- ### CLI Commands
637
-
638
- #### Run all seeders
639
-
640
- ```bash
641
- npm run seed
642
- # or
643
- nest-seed -c ./src/database/seeder.config.ts
644
- ```
645
-
646
- #### Refresh mode (drop and reseed)
647
-
648
- ```bash
649
- npm run seed:refresh
650
- # or
651
- nest-seed -c ./src/database/seeder.config.ts --refresh
652
- # or short form
653
- nest-seed -c ./src/database/seeder.config.ts -r
654
- ```
655
-
656
- #### Run specific seeder(s)
657
-
658
- ```bash
659
- # Single seeder
660
- nest-seed -c ./src/database/seeder.config.ts --name UserSeeder
661
- # or short form
662
- nest-seed -c ./src/database/seeder.config.ts -n UserSeeder
663
-
664
- # Multiple seeders
665
- nest-seed -c ./src/database/seeder.config.ts -n UserSeeder -n PostSeeder
666
- ```
667
-
668
- #### With dummy data flag
669
-
670
- ```bash
671
- nest-seed -c ./src/database/seeder.config.ts --dummyData
672
- # or short form
673
- nest-seed -c ./src/database/seeder.config.ts -d
674
- ```
675
-
676
- #### Combined options
677
-
678
- ```bash
679
- # Refresh and run specific seeder with dummy data
680
- nest-seed -c ./src/database/seeder.config.ts -r -n UserSeeder -d
681
- ```
682
-
683
- ### CLI Help
684
-
685
- ```bash
686
- nest-seed --help
687
- ```
688
-
689
- Output:
690
- ```
691
- Options:
692
- --help Show help [boolean]
693
- --version Show version number [boolean]
694
- --config, -c Path to seeder configuration file [required]
695
- --refresh, -r Drop all data before seeding [boolean] [default: false]
696
- --name, -n Specific seeder names to run [array]
697
- --dummyData, -d Include dummy data [boolean] [default: false]
698
-
699
- Examples:
700
- nest-seed -c ./seeder.config.ts Run all seeders
701
- nest-seed -c ./seeder.config.ts --refresh Drop and reseed all data
702
- nest-seed -c ./seeder.config.ts --name UserSeeder Run specific seeder
703
- ```
704
-
705
- ### Configuration File
475
+ ## ๐Ÿ”ฅ Advanced Examples
706
476
 
707
- The configuration file should export a default object with the following structure:
477
+ ### Custom Providers in Config
708
478
 
709
479
  ```typescript
710
480
  // seeder.config.ts
711
- import { SeederModuleOptions } from '@ackplus/nest-seeder';
481
+ import { CustomService } from './src/services/custom.service';
712
482
 
713
- const config: SeederModuleOptions = {
714
- // Required: Array of seeder providers
715
- seeders: [UserSeeder, PostSeeder, CommentSeeder],
716
-
717
- // Optional: Modules to import (e.g., TypeORM, Mongoose)
483
+ export default {
718
484
  imports: [
719
485
  TypeOrmModule.forRoot({ /* ... */ }),
720
- TypeOrmModule.forFeature([User, Post, Comment]),
486
+ TypeOrmModule.forFeature([User]),
721
487
  ],
722
-
723
- // Optional: Additional providers
724
- providers: [PrismaService, CustomService],
488
+ seeders: [UserSeeder],
489
+ providers: [CustomService], // Inject custom services
725
490
  };
726
-
727
- export default config;
728
491
  ```
729
492
 
730
- ## ๐Ÿ“ Programmatic Usage
731
-
732
- ### Using Seeder Function
493
+ ### Environment-Based Configuration
733
494
 
734
495
  ```typescript
735
- // src/seed.ts
736
- import { seeder } from '@ackplus/nest-seeder';
737
- import { TypeOrmModule } from '@nestjs/typeorm';
738
- import { User } from './entities/user.entity';
739
- import { UserSeeder } from './seeders/user.seeder';
496
+ // seeder.config.ts
497
+ import * as dotenv from 'dotenv';
498
+ dotenv.config();
499
+
500
+ const isDev = process.env.NODE_ENV === 'development';
740
501
 
741
- seeder({
502
+ export default {
742
503
  imports: [
743
504
  TypeOrmModule.forRoot({
744
505
  type: 'postgres',
745
- host: 'localhost',
746
- port: 5432,
747
- username: 'postgres',
748
- password: 'postgres',
749
- database: 'mydb',
750
- entities: [User],
751
- synchronize: true,
506
+ host: process.env.DB_HOST,
507
+ database: isDev ? 'mydb_dev' : 'mydb_prod',
508
+ synchronize: isDev,
752
509
  }),
753
- TypeOrmModule.forFeature([User]),
510
+ TypeOrmModule.forFeature([User, Post]),
754
511
  ],
755
- }).run({
756
- seeders: [UserSeeder],
757
- });
758
- ```
759
-
760
- Run with CLI arguments:
761
- ```bash
762
- ts-node src/seed.ts --refresh
763
- ts-node src/seed.ts --name UserSeeder
764
- ts-node src/seed.ts -r -n UserSeeder -d
765
- ```
766
-
767
- ### Using SeederService Directly
768
-
769
- ```typescript
770
- import { NestFactory } from '@nestjs/core';
771
- import { SeederService } from '@ackplus/nest-seeder';
772
- import { AppModule } from './app.module';
773
-
774
- async function seed() {
775
- const app = await NestFactory.createApplicationContext(AppModule);
776
- const seeder = app.get(SeederService);
777
-
778
- // Run all seeders
779
- await seeder.run();
780
-
781
- // Or just seed (without drop)
782
- await seeder.seed();
783
-
784
- // Or just drop
785
- await seeder.drop();
786
-
787
- await app.close();
788
- }
789
-
790
- seed();
512
+ seeders: isDev
513
+ ? [UserSeeder, PostSeeder, TestDataSeeder]
514
+ : [UserSeeder, PostSeeder],
515
+ };
791
516
  ```
792
517
 
793
- ## ๐Ÿ”ฅ Advanced Examples
794
-
795
- ### Conditional Seeding
518
+ ### Batch Insert for Performance
796
519
 
797
520
  ```typescript
798
521
  @Injectable()
799
522
  export class UserSeeder implements Seeder {
800
- constructor(
801
- @InjectRepository(User)
802
- private readonly userRepository: Repository<User>,
803
- ) {}
804
-
805
- async seed(options: SeederServiceOptions): Promise<void> {
806
- // Check if data already exists
807
- const count = await this.userRepository.count();
808
- if (count > 0 && !options.refresh) {
809
- console.log('โญ๏ธ Users already exist, skipping...');
810
- return;
811
- }
812
-
523
+ async seed(): Promise<void> {
813
524
  const factory = DataFactory.createForClass(UserFactory);
525
+ const batchSize = 1000;
526
+ const totalRecords = 10000;
814
527
 
815
- // Different amounts based on environment
816
- const count = process.env.NODE_ENV === 'production' ? 10 : 100;
817
- const users = factory.generate(count);
818
-
819
- await this.userRepository.save(users);
820
- console.log(`โœ… Seeded ${users.length} users`);
821
- }
822
-
823
- async drop(options: SeederServiceOptions): Promise<void> {
824
- await this.userRepository.delete({});
825
- }
826
- }
827
- ```
828
-
829
- ### Seeding with External Data
830
-
831
- ```typescript
832
- @Injectable()
833
- export class CountrySeeder implements Seeder {
834
- async seed(options: SeederServiceOptions): Promise<void> {
835
- const countries = [
836
- { code: 'US', name: 'United States' },
837
- { code: 'GB', name: 'United Kingdom' },
838
- { code: 'CA', name: 'Canada' },
839
- // ... more countries
840
- ];
841
-
842
- await this.countryRepository.save(countries);
843
- console.log(`โœ… Seeded ${countries.length} countries`);
844
- }
845
-
846
- async drop(options: SeederServiceOptions): Promise<void> {
847
- await this.countryRepository.delete({});
848
- }
849
- }
850
- ```
851
-
852
- ### Seeding from JSON File
853
-
854
- ```typescript
855
- import * as fs from 'fs';
856
- import * as path from 'path';
857
-
858
- @Injectable()
859
- export class ProductSeeder implements Seeder {
860
- async seed(options: SeederServiceOptions): Promise<void> {
861
- const filePath = path.join(__dirname, '../data/products.json');
862
- const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
863
-
864
- await this.productRepository.save(data);
865
- console.log(`โœ… Seeded ${data.length} products from file`);
866
- }
867
-
868
- async drop(options: SeederServiceOptions): Promise<void> {
869
- await this.productRepository.delete({});
870
- }
871
- }
872
- ```
873
-
874
- ### Transaction Support
875
-
876
- ```typescript
877
- @Injectable()
878
- export class UserSeeder implements Seeder {
879
- constructor(
880
- @InjectRepository(User)
881
- private readonly userRepository: Repository<User>,
882
- private readonly dataSource: DataSource,
883
- ) {}
884
-
885
- async seed(options: SeederServiceOptions): Promise<void> {
886
- const queryRunner = this.dataSource.createQueryRunner();
887
- await queryRunner.connect();
888
- await queryRunner.startTransaction();
889
-
890
- try {
891
- const factory = DataFactory.createForClass(UserFactory);
892
- const users = factory.generate(10);
893
-
894
- await queryRunner.manager.save(users);
895
- await queryRunner.commitTransaction();
896
-
897
- console.log('โœ… Seeded 10 users');
898
- } catch (error) {
899
- await queryRunner.rollbackTransaction();
900
- throw error;
901
- } finally {
902
- await queryRunner.release();
903
- }
904
- }
905
-
906
- async drop(options: SeederServiceOptions): Promise<void> {
907
- await this.userRepository.delete({});
908
- }
909
- }
910
- ```
911
-
912
- ### Multi-tenant Seeding
913
-
914
- ```typescript
915
- @Injectable()
916
- export class TenantSeeder implements Seeder {
917
- constructor(
918
- @InjectRepository(Tenant)
919
- private readonly tenantRepository: Repository<Tenant>,
920
- @InjectRepository(User)
921
- private readonly userRepository: Repository<User>,
922
- ) {}
923
-
924
- async seed(options: SeederServiceOptions): Promise<void> {
925
- const tenantFactory = DataFactory.createForClass(TenantFactory);
926
- const tenants = tenantFactory.generate(5);
927
- const savedTenants = await this.tenantRepository.save(tenants);
928
-
929
- const userFactory = DataFactory.createForClass(UserFactory);
930
-
931
- // Create users for each tenant
932
- for (const tenant of savedTenants) {
933
- const users = userFactory.generate(10, {
934
- tenantId: tenant.id,
935
- });
528
+ for (let i = 0; i < totalRecords; i += batchSize) {
529
+ const users = factory.generate(batchSize);
936
530
  await this.userRepository.save(users);
531
+ console.log(`โœ… Seeded ${Math.min(i + batchSize, totalRecords)}/${totalRecords} users`);
937
532
  }
938
-
939
- console.log('โœ… Seeded 5 tenants with 10 users each');
940
533
  }
941
534
 
942
- async drop(options: SeederServiceOptions): Promise<void> {
535
+ async drop(): Promise<void> {
943
536
  await this.userRepository.delete({});
944
- await this.tenantRepository.delete({});
945
537
  }
946
538
  }
947
539
  ```
948
540
 
949
541
  ## ๐Ÿ“š API Reference
950
542
 
951
- ### SeederModule
952
-
953
- #### `SeederModule.register(options: SeederModuleOptions)`
954
-
955
- Synchronously register the seeder module.
956
-
957
- **Options:**
958
- - `seeders`: Array of seeder providers
959
- - `imports`: Modules to import
960
- - `providers`: Additional providers
961
-
962
- #### `SeederModule.forRootAsync(options: SeederModuleAsyncOptions)`
963
-
964
- Asynchronously register the seeder module.
965
-
966
- **Options:**
967
- - `useFactory`: Factory function for async configuration
968
- - `useClass`: Configuration class implementing `SeederOptionsFactory`
969
- - `useExisting`: Existing provider for configuration
970
- - `imports`: Modules to import
971
- - `inject`: Dependencies to inject
972
- - `isGlobal`: Make module global
973
-
974
- ### Seeder Interface
975
-
976
- ```typescript
977
- interface Seeder {
978
- seed(options: SeederServiceOptions): Promise<any>;
979
- drop(options: SeederServiceOptions): Promise<any>;
980
- }
981
- ```
982
-
983
- ### SeederServiceOptions
543
+ ### DataFactory
984
544
 
985
545
  ```typescript
986
- interface SeederServiceOptions {
987
- name?: string | string[]; // Specific seeders to run
988
- refresh?: boolean; // Drop before seeding
989
- dummyData?: boolean; // Flag for conditional logic
546
+ class DataFactory {
547
+ // Create factory for a class
548
+ static createForClass<T>(factoryClass: new () => T): DataFactory<T>
549
+
550
+ // Generate instances
551
+ generate(count: number, override?: Partial<T>): T[]
990
552
  }
991
553
  ```
992
554
 
993
- ### DataFactory
994
-
995
- #### `DataFactory.createForClass<T>(target: Type<T>): Factory`
996
-
997
- Create a factory for a class with `@Factory` decorators.
998
-
999
- **Returns:** Factory object with `generate()` method
555
+ ### Seeder Interface
1000
556
 
1001
557
  ```typescript
1002
- interface Factory {
1003
- generate(count: number, values?: Record<string, any>): Array<Record<string, any>>;
558
+ interface Seeder {
559
+ // Seed data into database
560
+ seed(options?: SeederServiceOptions): Promise<void>
561
+
562
+ // Drop/clear data from database
563
+ drop(options?: SeederServiceOptions): Promise<void>
1004
564
  }
1005
565
  ```
1006
566
 
1007
567
  ### @Factory Decorator
1008
568
 
1009
569
  ```typescript
1010
- @Factory(
1011
- generator: FactoryValueGenerator | FactoryValue,
1012
- dependsOn?: string[]
1013
- )
1014
- ```
1015
-
1016
- **Parameters:**
1017
- - `generator`: Function `(faker, ctx) => value` or static value
1018
- - `dependsOn`: Array of property names this field depends on
570
+ // Simple factory
571
+ @Factory((faker) => faker.person.fullName())
572
+ name: string;
1019
573
 
1020
- ### SeederService
574
+ // With options
575
+ @Factory((faker) => faker.datatype.number({ min: 1, max: 100 }))
576
+ age: number;
1021
577
 
1022
- #### Methods
1023
-
1024
- - `run()`: Execute seed or drop+seed based on options
1025
- - `seed()`: Run seed method on all seeders
1026
- - `drop()`: Run drop method on all seeders
1027
- - `getSeederToRun()`: Get list of seeders to run based on options
1028
-
1029
- ## ๐Ÿ“ฆ Publishing
1030
-
1031
- This package uses automated GitHub Actions for publishing.
1032
-
1033
- ### Using CLI Script
1034
-
1035
- ```bash
1036
- # Patch version (0.0.1 -> 0.0.2)
1037
- npm run publish:patch
1038
-
1039
- # Minor version (0.0.1 -> 0.1.0)
1040
- npm run publish:minor
1041
-
1042
- # Major version (0.0.1 -> 1.0.0)
1043
- npm run publish:major
578
+ // Array values
579
+ @Factory((faker) => faker.helpers.arrayElement(['admin', 'user']))
580
+ role: string;
1044
581
  ```
1045
582
 
1046
- The script will:
1047
- 1. Update package version
1048
- 2. Create git tag
1049
- 3. Ask to push to remote (triggers GitHub Action)
1050
- 4. Commit version change
1051
-
1052
- ### Manual Publishing
1053
-
1054
- ```bash
1055
- # Create and push a tag
1056
- git tag v1.0.0
1057
- git push origin v1.0.0
583
+ ### SeederServiceOptions
1058
584
 
1059
- # GitHub Action will automatically publish to npm
585
+ ```typescript
586
+ interface SeederServiceOptions {
587
+ refresh?: boolean; // Drop before seeding
588
+ name?: string[]; // Run specific seeders
589
+ dummyData?: boolean; // Custom flag for your logic
590
+ }
1060
591
  ```
1061
592
 
1062
593
  ## ๐Ÿค Contributing
@@ -1075,10 +606,10 @@ This project is licensed under the MIT License.
1075
606
 
1076
607
  ## ๐Ÿ“ฎ Support
1077
608
 
1078
- If you have any questions or need help, please:
1079
- - Open an issue on GitHub
1080
- - Check existing documentation
1081
- - Review examples in the repository
609
+ If you have any questions or need help:
610
+ - Open an issue on [GitHub](https://github.com/ackplus/nest-seeder/issues)
611
+ - Check the [examples](./examples/) directory
612
+ - Review the [Quick Start Guide](./QUICKSTART.md)
1082
613
 
1083
614
  ---
1084
615