Prisma2 Fixtures Loader (adapted from typeorm-fixtures-cli)
npm install @getbigger-io/prisma-fixtures-cli


Relying on faker.js, prisma-fixtures-cli allows you to create a ton of fixtures/fake data for use while developing
or testing your project. It gives you a few essential tools to make it very easy to collect complex data with constraints in a readable and easy to edit
way, so that everyone on your team can tweak the fixtures if needed.
This package has been adapted from TypeORM Fixtures CLI thanks to its
author RobinCK.
- Install
- Development Setup
- Example
- Creating Fixtures
- Fixture Ranges
- Fixture Reference
- Fixture Lists
- Handling Relations
- Advanced Guide
- Parameters
- Faker Data
- EJS templating
- Load Processor
- Samples
- Usage
#### NPM
``bash`
npm install @getbigger-io/prisma-fixtures-cli --save-dev
#### Yarn
`bash`
yarn add @getbigger-io/prisma-fixtures-cli --dev
`bashinstall dependencies
npm install
Example
fixtures/Comment.yml`yaml
entity: comment
items:
comment{1..10}:
fullName: '{{name.firstName}} {{name.lastName}}'
email: '{{internet.email}}'
text: '{{lorem.paragraphs}}'
post: '@post*'
`Note: Your entity must be named the same as you call it in the prisma client e.g:
client....
fixtures/Post.yml`yaml
entity: post
connectedFields: ['user'] # Use this to connect the user when creating the post
items:
post1:
title: '{{name.title}}'
description: '{{lorem.paragraphs}}'
user: '@user($current)'
post2:
title: '{{name.title}}'
description: '{{lorem.paragraphs}}'
user: '@user($current)'
`fixtures/User.yml`yaml
entity: User
connectedFields: ['profile'] # Use this to connect the user when creating the post
items:
user1:
firstName: '{{name.firstName}}'
lastName: '{{name.lastName}}'
email: '{{internet.email}}'
profile: '@profile1'
user2:
firstName: '{{name.firstName}}'
lastName: '{{name.lastName}}'
email: '{{internet.email}}'
profile: '@profile2'
`fixtures/Profile.yml`yaml
entity: profile
items:
profile1:
aboutMe: <%= ['about string', 'about string 2', 'about string 3'].join(", ") %>
skype: skype-account>
language: english
profile2:
aboutMe: <%= ['about string', 'about string 2', 'about string 3'].join(", ") %>
skype: skype-account
language: english
`Creating Fixtures
The most basic functionality of this library is to turn flat yaml files into objects
`yaml
entity: user
items:
user0:
username: bob
fullname: Bob
birthDate: 1980-10-10
email: bob@example.org
favoriteNumber: 42 user1:
username: alice
fullname: Alice
birthDate: 1978-07-12
email: alice@example.org
favoriteNumber: 27
`$3
The first step is to let create many copies of an object for you to remove duplication from the yaml file.
You can do that by defining a range in the fixture name:
`yaml
entity: user
items:
user{1..10}:
username: bob
fullname: Bob
birthDate: 1980-10-10
email: bob@example.org
favoriteNumber: 42
`Now it will collect ten users, with IDs user1 to user10. Pretty good but we only have 10 bobs with the same name, username and email, which is not so fancy yet.
$3
You can also specify a reference to a previously created list of fixtures:
`yaml
entity: post
connectedFields: ['user'] # Use this to connect the user when creating the post
items:
post1:
title: 'Post title'
description: 'Post description'
user: '@user1'
`$3
You can also specify a list of values instead of a range:
`yaml
entity: post
connectedFields: ['user']
items:
post{1..10}:
title: 'Post title'
description: 'Post description'
user: '@user($current)'
`In the case of a range (e.g. user{1..10}),
($current) will return 1 for user1, 2 for user2 etc.The current iteration can be used as a string value:
`yaml
entity: post
items:
post{1..10}:
title: 'Post($current)'
description: 'Post description'
`Post($current) will return Post1 for post1, Post2 for post2 etc.You can mutate this output by using basic math operators:
`yaml
entity: post
items:
post{1..10}:
title: 'Post($current*100)'
description: 'Post description'
`Post($current*100) will return Post100 for post1, Post200 for post2 etc.Handling Relations
`yaml
entity: user
items:
user1:
# ...entity: group
connectedFields: ['owner', 'members']
items:
group1:
name: '<{names.admin}>'
owner: '@user1'
members:
- '@user2'
- '@user3'
`If you want to create ten users and ten groups and have each user own one group, you can use
($current) which is replaced with the current ID of each iteration when using fixture ranges:`yaml
entity: user
items:
user1:
# ...entity: group
connectedFields: ['owner', 'members']
items:
group{1..10}:
name: 'name'
owner: '@user($current)'
members:
- '@user2'
- '@user3'
`If you would like a random user instead of a fixed one, you can define a reference with a wildcard:
`yaml
entity: user
items:
user1:
# ...entity: group
connectedFields: ['owner', 'members']
items:
group{1..10}:
name: 'name'
owner: '@user*'
members:
- '@user2'
- '@user3'
`or
`yaml
entity: user
items:
user1:
# ...entity: group
connectedFields: ['owner', 'members']
items:
group{1..10}:
name: 'name'
owner: '@user{1..2}' # @user1 or @user2
members:
- '@user2'
- '@user3'
`Advanced Guide
$3
You can set global parameters that will be inserted everywhere those values are used to help with readability. For example:
`yaml
entity: group
connectedFields: ['owner', 'members']
parameters:
names:
admin: Admin
items:
group1:
name: '<{names.admin}>' # <--- set Admin
owner: '@user1'
members:
- '@user2'
- '@user3'
`$3
This library integrates with the faker.js library. Using {{foo}} you can call Faker data providers to collect random data.
Let's turn our static bob user into a randomized entry:
`yaml
entity: user
items:
user{1..10}:
username: '{{internet.userName}}'
fullname: '{{name.firstName}} {{name.lastName}}'
birthDate: '{{date.past}}'
email: '{{internet.email}}'
favoriteNumber: '{{random.number}}'
`$3
This library integrates with the EJS
`yaml
entity: Profile
items:
profile1:
aboutMe: <%= ['about string', 'about string 2', 'about string 3'].join(", ") %>
skype: skype-account>
language: english
`$3
Processors allow you to process objects before and/or after they are persisted. Processors must implement the:
IProcessor`typescript
import { IProcessor } from '@getbigger-io/prisma-fixtures-cli';
`Here is an example:
processor/UserProcessor.ts`typescript
import { IProcessor } from '@getbigger-io/prisma-fixtures-cli';
import { User } from '@prisma/client';export default class UserProcessor implements IProcessor {
preProcess(name: string, object: any): any {
return { ...object, firstName: 'foo' };
}
}
`fixture config
fixtures/user.yml`yaml
entity: user
processor: ../processor/UserProcessor
items:
user1:
firstName: '{{name.firstName}}'
lastName: '{{name.lastName}}'
email: '{{internet.email}}'
`Usage
`
Usage: fixtures [options] Fixtures folder/file pathOptions:
-v, --version output the version number
--require A list of additional modules. e.g. ts-node/register
-d --debug Enable debug
--databaseUrl Overrides the DATABASE_URL env variable
-h, --help output usage information
--no-color Disable color
`##### Require multiple additional modules
If you're using multiple modules at once (e.g. ts-node and tsconfig-paths)
you have the ability to require these modules with multiple require flags. For example:
`
fixtures ./fixtures --require=ts-node/register --require=tsconfig-paths/register --databaseUrl=file:./mydb.sqlite
`$3
Although @getbigger-io/prisma-fixtures-cli is intended to use as a CLI, you can still load
fixtures via APIs in your program.
For example, the below code snippet will load all fixtures exist in
./fixtures directory:`typescript
import * as path from 'path';
import { Builder, fixturesIterator, Loader, Parser, Resolver } from '@getbigger-io/prisma-fixtures-cli';const loadFixtures = async (fixturesPath: string) => {
let connection;
try {
connection = await PrismaClient();
await connection.$connect();
const loader = new Loader();
loader.load(path.resolve(fixturesPath));
const resolver = new Resolver();
const fixtures = resolver.resolve(loader.fixtureConfigs);
const builder = new Builder(connection, new Parser());
for (const fixture of fixturesIterator(fixtures)) {
const entity = await builder.build(fixture);
// use the entity if you need it
}
} catch (err) {
throw err;
} finally {
if (connection) {
await connection.$disconnect();
}
}
};
loadFixtures('./fixtures')
.then(() => {
console.log('Fixtures are successfully loaded.');
})
.catch(err => console.log(err));
``This project exists thanks to all the people who contribute. [Contribute].
MIT © Nicolas MACHEREY