-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: (enhancement) Seeds and Scripts (#239)
* init seeds: - Updates types for Profile relation - Adds initial structure for dev/prod seeds * seeds and scripts: - Adds example for users - Adds Readme - Adds Example Script - Adds Script Runner - updates pacakage json - adds scripts for seed:prod and run:script * lint * missing , * pr feedback
- Loading branch information
Showing
12 changed files
with
260 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
nodejs 16.5.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# ENV vars here override .env when running locally | ||
# DATABASE_URL="postgresql://postgres@localhost:5432/<%= name -%>_dev?schema=public" | ||
APP_SECRET=foo | ||
APP_SECRET=foo | ||
APP_ENV=development |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
packages/create-bison-app/template/prisma/SeedsAndScripts.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Seeds and Scripts | ||
|
||
## Seeds | ||
|
||
### Dev VS Prod | ||
|
||
- `yarn db:seed` (DEV) | ||
- `yarn db:seed:prod` (PROD) | ||
|
||
We use `APP_ENV` in the scripts to determine the dataset returned for seeds. | ||
This ENV is set in your .env.local file as well, and can be manually set as an ENV in your deploy environment if needed for other scripts. | ||
|
||
### File Breakdown (Seeds) | ||
|
||
```sh | ||
/seeds | ||
--/model | ||
----/data.ts | ||
----/prismaRunner.ts | ||
----/index.ts | ||
``` | ||
|
||
**data.ts** contains the exported function `seedModelData: ModelCreateInput[]` this function leverages APP_ENV to return the dataset expected for Dev vs Prod. In the case of `users` this returns `initialDevUsers: UserCreateInput[]` or `initalProdUsers: UserCreateInput[]`. | ||
|
||
**prismaRunner.ts** this file contains the Prisma `UPSERT` call for the model. We leverage upsert here so that seeds can potentially be ran more than once as your models and data expand over time. | ||
|
||
**index.ts** export of functions for main seed file | ||
|
||
### Relationships | ||
|
||
In the event your model has a relationship dependency ie. Accounts, Organizations, etc. The prismaRunners are set to return a `Pick<Model, 'id'>` result for you to leverage in future seeds. The dependent runner would expand to take these parameters. | ||
|
||
**User/Organization example:** | ||
|
||
```ts | ||
import {orgSeedData, seedOrganizations } from './seeds/organizations'; | ||
import {userSeedData, seedUsers } from './seeds/users'; | ||
|
||
const [{ id: orgId }] = await seedOrganizations(orgSeedData); | ||
await seedUsers(userSeedData(orgId)); | ||
``` | ||
|
||
```ts | ||
const initialDevUsers = (orgId: string): UserCreateInput[] => [ | ||
{ | ||
email: 'john.doe@echobind.com', | ||
organization: { connect: { id: orgId } }, | ||
// ...other create data | ||
} | ||
] | ||
``` | ||
|
||
## Scripts | ||
|
||
### File Breakdown (Scripts) | ||
|
||
```sh | ||
/scripts | ||
--/run.ts | ||
--/exampleUserScript.ts | ||
``` | ||
|
||
**run.ts** This is the main run file leveraged by `yarn run:script {filename}`. | ||
This script takes a file name to be run via `commander`. These scripts can be ANYTHING. However, in our example, we've leveraged the same `seedUsers` runner to add new employees. | ||
|
||
**exampleUserScript.ts** This is an example script file that can be ran with `yarn run:script exampleUserScript.ts`. This script leverages the same `seedUsers` prisma runner to add a few new employees to the team. |
54 changes: 54 additions & 0 deletions
54
packages/create-bison-app/template/prisma/scripts/exampleUserScript.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { hashPassword } from '../../services/auth'; | ||
import { Role, UserCreateInput } from '../../types'; | ||
|
||
import { seedUsers } from '../seeds/users'; | ||
|
||
// HR: Hey, we've had a few more employees join -- can you create an account for them?! | ||
|
||
const INITIAL_PASSWORD = 'test1234'; | ||
|
||
const main = async () => { | ||
const newEmployees: UserCreateInput[] = [ | ||
{ | ||
profile: { | ||
create: { | ||
firstName: 'Cisco', | ||
lastName: 'Ramon', | ||
}, | ||
}, | ||
email: 'cisco.ramon@speedforce.net', | ||
password: hashPassword(INITIAL_PASSWORD), | ||
roles: [Role.ADMIN], | ||
}, | ||
{ | ||
profile: { | ||
create: { | ||
firstName: 'Caitlin', | ||
lastName: 'Snow', | ||
}, | ||
}, | ||
email: 'caitlin.snow@speedforce.net', | ||
password: hashPassword(INITIAL_PASSWORD), | ||
roles: [Role.ADMIN], | ||
}, | ||
{ | ||
profile: { | ||
create: { | ||
firstName: 'Harrison', | ||
lastName: 'Wells', | ||
}, | ||
}, | ||
email: 'harrison.wells@speedforce.net', | ||
password: hashPassword(INITIAL_PASSWORD), | ||
roles: [Role.ADMIN], | ||
}, | ||
]; | ||
|
||
await seedUsers(newEmployees); | ||
}; | ||
|
||
main() | ||
.catch((e) => console.error(e)) | ||
.finally(async () => { | ||
await prisma.$disconnect(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Command } from 'commander'; | ||
import { spawn } from 'child_process'; | ||
|
||
const program = new Command(); | ||
const run = () => { | ||
program.option('-f, --file <type>', 'filename of script to run'); | ||
|
||
program.parse(process.argv); | ||
|
||
const { file } = program.opts(); | ||
console.log({ file }); | ||
|
||
const child = spawn(`yarn ts-node ${__dirname}/${file}`, { | ||
shell: true, | ||
stdio: 'inherit', | ||
}); | ||
|
||
child.on('exit', function (code) { | ||
process.exit(code); | ||
}); | ||
}; | ||
|
||
run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
// import { UserFactory } from '../tests/factories'; | ||
// import { Role } from '../types'; | ||
// import { prisma } from '../lib/prisma'; | ||
import { userSeedData, seedUsers } from './seeds/users'; | ||
|
||
export async function seed() { | ||
// Add seeds here. You can use factories or raw prisma.create/upsert calls. | ||
console.log('no seeds yet!'); | ||
// await UserFactory.create({ email: 'hello@wee.net' }); | ||
// await UserFactory.create({ roles: [Role.ADMIN] }); | ||
} | ||
const seed = async () => { | ||
console.log('seeding Users...'); | ||
await seedUsers(userSeedData); | ||
}; | ||
|
||
seed() | ||
.catch((e) => console.error(e)) | ||
.finally(() => console.log('Seeding Complete')); |
51 changes: 51 additions & 0 deletions
51
packages/create-bison-app/template/prisma/seeds/users/data.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { hashPassword } from '../../../services/auth'; | ||
import { Role, UserCreateInput } from '../../../types'; | ||
|
||
// ********************************************* | ||
// ** DEVELOPMENT DATA SET | ||
// ********************************************* | ||
|
||
const INITIAL_PASSWORD = 'test1234'; | ||
|
||
const initialDevUsers: UserCreateInput[] = [ | ||
{ | ||
email: 'barry.allen@speedforce.net', | ||
password: hashPassword(INITIAL_PASSWORD), | ||
roles: [Role.ADMIN], | ||
profile: { | ||
create: { | ||
firstName: 'Barry', | ||
lastName: 'Allen', | ||
}, | ||
}, | ||
}, | ||
]; | ||
|
||
// ********************************************* | ||
// ** PRODUCTION DATA SET | ||
// ********************************************* | ||
|
||
const INITIAL_PROD_PASSWORD = 'strong@password'; | ||
|
||
const initialProdUsers: UserCreateInput[] = [ | ||
{ | ||
email: 'apps@echobind.com', | ||
password: hashPassword(INITIAL_PROD_PASSWORD), | ||
roles: [Role.ADMIN], | ||
profile: { | ||
create: { | ||
firstName: 'EB', | ||
lastName: 'Admin', | ||
}, | ||
}, | ||
}, | ||
]; | ||
|
||
// ********************************************* | ||
// ** MAIN DATA EXPORT | ||
// ********************************************* | ||
|
||
const appEnv = process.env.APP_ENV || 'development'; | ||
|
||
export const userSeedData: UserCreateInput[] = | ||
appEnv === 'production' ? initialProdUsers : initialDevUsers; |
2 changes: 2 additions & 0 deletions
2
packages/create-bison-app/template/prisma/seeds/users/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './data'; | ||
export * from './prismaRunner'; |
28 changes: 28 additions & 0 deletions
28
packages/create-bison-app/template/prisma/seeds/users/prismaRunner.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { User, UserCreateInput } from '../../../types'; | ||
import { prisma } from '../../../lib/prisma'; | ||
|
||
type SeedUserResult = Pick<User, 'id' | 'email'>; | ||
|
||
export const seedUsers = async (users: UserCreateInput[]): Promise<SeedUserResult[]> => { | ||
const userPromiseArray = users.map( | ||
async (user): Promise<SeedUserResult> => | ||
prisma.user.upsert({ | ||
where: { | ||
email: user.email, | ||
}, | ||
create: { | ||
email: user.email, | ||
password: user.password, | ||
roles: user.roles, | ||
profile: user.profile, | ||
}, | ||
update: {}, | ||
select: { | ||
id: true, | ||
email: true, | ||
}, | ||
}) | ||
); | ||
|
||
return Promise.all(userPromiseArray); | ||
}; |