
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
@acore/typeorm-seeding
Advanced tools
A delightful way to seed test data into your database.
Inspired by the awesome framework laravel in PHP and of the repositories from pleerock
Made with ❤️ by Gery Hirschfeld and contributors
Isn't it exhausting to create some sample data for your database, well this time is over!
How does it work? Just create a entity factory for your entities (models) and a seed script.
First create your TypeORM entities.
// user.entity.ts
@Entity()
export class User {
@PrimaryGeneratedColumn('uuid') id: string
@Column({ nullable: true }) name: string
@Column({ type: 'varchar', length: 100, nullable: false }) password: string
@OneToMany((type) => Pet, (pet) => pet.user) pets: Pet[]
@BeforeInsert()
async setPassword(password: string) {
const salt = await bcrypt.genSalt()
this.password = await bcrypt.hash(password || this.password, salt)
}
}
// pet.entity.ts
@Entity()
export class Pet {
@PrimaryGeneratedColumn('uuid') id: string
@Column() name: string
@Column() age: number
@ManyToOne((type) => User, (user) => user.pets)
@JoinColumn({ name: 'user_id' })
user: User
}
Then for each entity define a factory. The purpose of a factory is to create new entites with generate data.
Note: Factories can also be used to generate data for testing.
// user.factory.ts
define(User, (faker: typeof Faker) => {
const gender = faker.datatype.number(1)
const firstName = faker.name.firstName(gender)
const lastName = faker.name.lastName(gender)
const user = new User()
user.name = `${firstName} ${lastName}`
user.password = faker.random.word()
return user
})
// pet.factory.ts
define(Pet, (faker: typeof Faker) => {
const gender = faker.datatype.number(1)
const name = faker.name.firstName(gender)
const pet = new Pet()
pet.name = name
pet.age = faker.datatype.number()
pet.user = factory(User)() as any
return pet
})
And last but not least, create a seeder. The seeder can be called by the configured cli command seed:run. In this case it generates 10 pets with a owner (User).
Note:
seed:runmust be configured first. Go to CLI Configuration.
// create-pets.seed.ts
export default class CreatePets implements Seeder {
public async run(factory: Factory, connection: Connection): Promise<any> {
await factory(Pet)().createMany(10)
}
}
Before using this TypeORM extension please read the TypeORM Getting Started documentation. This explains how to setup a TypeORM project.
After that install the extension with npm or yarn.
npm i typeorm-seeding
# or
yarn add typeorm-seeding
Optional, install the type definitions of the Faker library.
npm install -D @types/faker
To configure the path to your seeds and factories change the TypeORM config file (ormconfig.js or ormconfig.json).
The default paths are
src/database/{seeds,factories}/**/*{.ts,.js}
ormconfig.js
module.exports = {
...
seeds: ['src/seeds/**/*{.ts,.js}'],
factories: ['src/factories/**/*{.ts,.js}'],
}
.env
TYPEORM_SEEDING_FACTORIES=src/factories/**/*{.ts,.js}
TYPEORM_SEEDING_SEEDS=src/seeds/**/*{.ts,.js}
Add the following scripts to your package.json file to configure the seed cli commands.
"scripts": {
"seed:config": "ts-node ./node_modules/typeorm-seeding/dist/cli.js config"
"seed:run": "ts-node ./node_modules/typeorm-seeding/dist/cli.js seed"
...
}
To execute the seed run npm run seed:run in the terminal.
Note: More CLI options are here
Add the following TypeORM cli commands to the package.json to drop and sync the database.
"scripts": {
...
"schema:drop": "ts-node ./node_modules/typeorm/cli.js schema:drop",
"schema:sync": "ts-node ./node_modules/typeorm/cli.js schema:sync",
...
}
| Option | Default | Description |
|---|---|---|
--seed or -s | null | Option to specify a seeder class to run individually. |
--connection or -c | null | Name of the typeorm connection. Required if there are multiple connections. |
--configName or -n | ormconfig.js | Name to the typeorm config file. |
--root or -r | process.cwd() | Path to the typeorm config file. |
A seeder class only contains one method by default run. Within this method, you may insert data into your database. For manually insertion use the Query Builder or use the Entity Factory
Note. The seeder files will be executed alphabetically.
import { Factory, Seeder } from 'typeorm-seeding'
import { Connection } from 'typeorm'
import { User } from '../entities'
export default class CreateUsers implements Seeder {
public async run(factory: Factory, connection: Connection): Promise<any> {
await connection
.createQueryBuilder()
.insert()
.into(User)
.values([
{ firstName: 'Timber', lastName: 'Saw' },
{ firstName: 'Phantom', lastName: 'Lancer' },
])
.execute()
}
}
Of course, manually specifying the attributes for each entity seed is cumbersome. Instead, you can use entity factories to conveniently generate large amounts of database records.
For all entities we want to create, we need to define a factory. To do so we give you the awesome faker library as a parameter into your factory. Then create your "fake" entity and return it. Those factory files should be in the src/database/factories folder and suffixed with .factory like src/database/factories/user.factory.ts.
| Types | Description |
|---|---|
Entity | TypeORM Entity like the user or the pet in the samples. |
Context | Argument to pass some static data into the factory function. |
EntityFactory | This object is used to make new filled entities or create it into the database. |
defineThe define function creates a new entity factory.
define: <Entity, Context>(entity: Entity, factoryFn: FactoryFunction<Entity, Context>) => void;
import Faker from 'faker'
import { define } from 'typeorm-seeding'
import { User } from '../entities'
define(User, (faker: typeof Faker, context: { roles: string[] }) => { ... })
factoryFactory retrieves the defined factory function and returns the EntityFactory to start creating new enities.
factory: (entity: Entity) => (context?: Context) => EntityFactory<Entity, Context>
factory(Pet)()
factory(Pet)({ name: 'Balou' })
mapUse the .map() function to alter the generated value before they get persisted.
map(mapFunction: (entity: Entity) => Promise<Entity>): EntityFactory<Entity, Context>
await factory(User)()
.map(async (user: User) => {
const pets: Pet[] = await factory(Pet)().createMany(2)
const petIds = pets.map((pet: Pet) => pet.Id)
await user.pets().attach(petIds)
})
.createMany(5)
make & makeManyMake and makeMany executes the factory functions and return a new instance of the given entity. The instance is filled with the generated values from the factory function, but not saved in the database.
overrideParams - Override some of the attributes of the entity.
make(overrideParams: EntityProperty<Entity> = {}): Promise<Entity>
await factory(User)().make()
await factory(User)().makeMany(10)
// override the email
await factory(User)().make({ email: 'other@mail.com' })
await factory(User)().makeMany(10, { email: 'other@mail.com' })
create & createManythe create and createMany method is similar to the make and makeMany method, but at the end the created entity instance gets persisted in the database.
overrideParams - Override some of the attributes of the entity.
create(overrideParams: EntityProperty<Entity> = {}): Promise<Entity>
await factory(User)().create()
await factory(User)().createMany(10)
// override the email
await factory(User)().create({ email: 'other@mail.com' })
await factory(User)().createMany(10, { email: 'other@mail.com' })
The entity factories can also be used in testing. To do so call the useSeeding function, which loads all the defined entity factories.
Choose your test database wisley. We suggest to run your test in a sqlite in memory database.
{
"type": "sqlite",
"name": "memory",
"database": ":memory:"
}
However, if the test database is not in memory, than use the --runInBand flag to disable parallelizes runs.
describe("UserService", () => {
let connection: Connection
beforeAll(async (done) => {
connection = await useRefreshDatabase({ connection: 'memory' })
await useSeeding()
const user = await factory(User)().make()
const createdUser = await factory(User)().create()
await runSeeder(CreateUserSeed)
done()
})
afterAll(async (done) => {
await tearDownDatabase()
done()
})
test('Should ...', () => { ... })
})
useSeedingLoads the defined entity factories.
useSeeding(options: ConfigureOption = {}): Promise<void>
runSeederRuns the given seeder class.
runSeeder(seed: SeederConstructor): Promise<void>
useRefreshDatabaseConnects to the database, drops it and recreates the schema.
useRefreshDatabase(options: ConfigureOption = {}): Promise<Connection>
tearDownDatabaseCloses the open database connection.
tearDownDatabase(): Promise<void>
ConfigureOptioninterface ConfigureOption {
root?: string // path to the orm config file. Default = process.cwd()
configName?: string // name of the config file. eg. ormconfig.js
connection?: string // name of the database connection.
}
Please fill free to add your open-source project here. This helps others to better understand the seeding technology.
| Project | Description |
|---|---|
| copa-ch/copa-backend | 🚀 Nest application written in TypeScript for the COPA project. This app manages your tournaments and generates the schedules. |
FAQs
🌱 A delightful way to seed test data into your database.
We found that @acore/typeorm-seeding demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.