How to write a Data Seeder Helper in NestJS 9+ with Typeorm 0.3+
Published: 2023-05-16 04:52:14

I have been looking for different solutions that can help how to seed data inside database using a helper function without using any third part package.


After struggling with different methods and solutions then I come up with this solutions. It works fine without any third part package.

Let's dive deep into code
Assuming you generated your application with NestJS CLI 9 

Your App module will look like below
`app.module.ts`
```
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: ['dist/**/*.entity{.ts,.js}'],
      synchronize: true,
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

Then create a seeder helper function like this below, Feel free to add more data as you want.
`seed-data.ts`
```
import { DataSource, In } from 'typeorm';
import { Permission } from '../../modules/permissions/entities/permission.entity';
import { Role } from '../../modules/permissions/entities/role.entity';
import { Auth } from '../../modules/users/entities/auth.entity';
import { PERMISSIONS_LIST } from './data/permissions.seeders';
import { ROLE_LIST } from './data/roles.seeders';

export async function seedData(dataSource: DataSource): Promise<void> {

  const permissionRepository = dataSource.getRepository(Permission);
  const roleRepository = dataSource.getRepository(Role);

  const permissionsList = PERMISSIONS_LIST;
  for (const permission of permissionsList) {
    let _permission = permissionRepository.create(
      permission as unknown as Permission,
    );
    await permissionRepository.save(_permission);
  }

  const rolesList = ROLE_LIST;
  for (const role of rolesList) {
    let _permissions = await permissionRepository.findBy({
      id: In(role.permissions),
    });
    let _roleItem = {
      name: role.name,
      guard: role.guard,
      code: role.code,
    };
    let _role = roleRepository.create({
      ..._roleItem,
      permissions: _permissions,
    });
    await roleRepository.save(_role);
  }
}

```
Note that ROLE_LIST and PERMISSION_LIST are sample data in an array format like
`data.ts`
```
import { GuardType } from "src/modules/permissions/entities/guard-type.enum";

export const ROLE_LIST = [
  {
    name: "admin",
    guard: GuardType.ADMIN,
    code: "admin",
    permissions: [1, 2]
  },
  {
    name: "user",
    guard: GuardType.USER,
    code: "user",
    permissions: [2]
  },
  {
    name: "test",
    guard: GuardType.TEST,
    code: "test",
    permissions: [2]
  }
];
```

Then write a helper function to boostrap your app using NestFactory function like below
`seed.helper.ts`
```
import { DataSource } from 'typeorm';
import { seedData } from './seed-data';
import { AppModule } from '../../app.module';
import { NestFactory } from '@nestjs/core';

async function runSeeder() {
  const app = await NestFactory.create(AppModule);
  const dataSource = app.get(DataSource);
  await seedData(dataSource);
  await app.close();
}
runSeeder();
```

Then final add the command to package.json file so that you can execute a runSeeder function inside package.json.
`package.json`
```
"scripts": {
    "build": "nest build",
    ...
    "data:sync": "ts-node -r tsconfig-paths/register ./src/seeders/seed.helper.ts"
```

Now everything is now set just run `npm run data:sync` now data should be populated in the database.

Feel free to leave a comment in this post below.