From 1dc4a447150c325ab9bb3369e46a855c767e07d7 Mon Sep 17 00:00:00 2001 From: hirsch Date: Tue, 14 Apr 2020 21:44:46 +0200 Subject: [PATCH 1/5] chore: remove unused path lib --- ormconfig.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/ormconfig.js b/ormconfig.js index 5a73c0db..e80507db 100644 --- a/ormconfig.js +++ b/ormconfig.js @@ -1,5 +1,3 @@ -const path = require('path') - module.exports = [ { name: 'sample', From a5cabd9776c71c59d35036f2a4816f9ac63d7d01 Mon Sep 17 00:00:00 2001 From: hirsch Date: Tue, 14 Apr 2020 21:46:14 +0200 Subject: [PATCH 2/5] chore: update logo --- logo.png | Bin 35293 -> 37974 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/logo.png b/logo.png index b13211133d31c0d0dcff347da9b40882e6746695..d238d30d41b58942b94c20ca2d4a2a89ec5074bf 100644 GIT binary patch literal 37974 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

r%!v}*^+@p;qPoZ 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 From c2ce20944779bb26eda3977294f77b558ecda961 Mon Sep 17 00:00:00 2001 From: hirsch Date: Tue, 14 Apr 2020 21:50:08 +0200 Subject: [PATCH 3/5] chore: remove jest config and call prebuild before build --- jest.config.js | 4 ++++ package.json | 18 ++---------------- 2 files changed, 6 insertions(+), 16 deletions(-) create mode 100644 jest.config.js diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..91a2d2c0 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', +}; \ No newline at end of file diff --git a/package.json b/package.json index d266e726..eafda2a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typeorm-seeding", - "version": "1.4.3", + "version": "1.4.4", "description": "🌱 A delightful way to seed test data into your database.", "license": "MIT", "author": "Gery Hirschfeld (https://github.com/hirsch88)", @@ -17,7 +17,7 @@ "prebuild": "rimraf dist", "format": "prettier --write \"src/**/*.ts\"", "lint": "eslint \"src/**/*.ts\" --fix", - "build": "tsc --project ./tsconfig.build.json", + "build": "npm run prebuild && tsc --project ./tsconfig.build.json", "watch": "rollup -cw", "test": "jest", "test:watch": "jest --watch", @@ -67,19 +67,5 @@ }, "resolutions": { "mem": ">=4.0.0" - }, - "jest": { - "moduleFileExtensions": [ - "js", - "json", - "ts" - ], - "rootDir": "src", - "testRegex": ".test.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - }, - "coverageDirectory": "../coverage", - "testEnvironment": "node" } } From 50cb22281e44e638ce7fff64818fd4ae8a9be868 Mon Sep 17 00:00:00 2001 From: hirsch Date: Tue, 14 Apr 2020 21:51:10 +0200 Subject: [PATCH 4/5] feat: enable seeding for testing --- README.md | 107 ++++++++++++++++++++++++----- sample/seeds/create-pets.seed.ts | 2 +- sample/seeds/create-users.seed.ts | 2 +- src/commands/config.command.ts | 17 +++-- src/commands/seed.command.ts | 39 +++++------ src/connection.ts | 108 ++++++++++++++++++------------ src/entity-factory.ts | 30 ++++++--- src/importer.ts | 4 +- src/typeorm-seeding.ts | 40 ++++++++--- src/utils/file.util.ts | 4 +- src/utils/log.util.ts | 10 +++ 11 files changed, 252 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index 091cee14..924c372b 100755 --- a/README.md +++ b/README.md @@ -30,7 +30,8 @@ - [Introduction](#-introduction) - [Installation](#-installation) - [Basic Seeder](#-basic-seeder) -- [Factory API](#-factory-api) +- [Using Entity Factory](#-using-entity-factory) +- [Seeding Data in Testing](#-seeding-data-in-testing) - [Changelog](#-changelog) - [License](#-license) @@ -112,7 +113,7 @@ The seeder can be called by the configured cli command `seed:run`. In this case // create-pets.seed.ts export default class CreatePets implements Seeder { public async run(factory: Factory, connection: Connection): Promise { - await factory(Pet)().seedMany(10) + await factory(Pet)().createMany(10) } } ``` @@ -216,15 +217,15 @@ export default class CreateUsers implements Seeder { } ``` -## ❯ Factory API +## ❯ Using Entity Factory -For all entities we want to seed, we need to define a factory. To do so we give you the awesome [faker](https://github.com/marak/Faker.js/) 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`. +For all entities we want to create, we need to define a factory. To do so we give you the awesome [faker](https://github.com/marak/Faker.js/) 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 | -| --------------- | ----------------------------------------------------------------------------- | -| `Enity` | TypeORM Enity 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 seed it into the database. | +| Types | Description | +| --------------- | ------------------------------------------------------------------------------- | +| `Enity` | TypeORM Enity 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. | ### `define` @@ -268,11 +269,11 @@ map(mapFunction: (entity: Entity) => Promise): EntityFactory { - const pets: Pet[] = await factory(Pet)().seedMany(2) + const pets: Pet[] = await factory(Pet)().createMany(2) const petIds = pets.map((pet: Pet) => pet.Id) await user.pets().attach(petIds) }) - .seedMany(5) + .createMany(5) ``` #### `make` & `makeMany` @@ -294,23 +295,93 @@ await factory(User)().make({ email: 'other@mail.com' }) await factory(User)().makeMany(10, { email: 'other@mail.com' }) ``` -#### `seed` & `seedMany` +#### `create` & `createMany` -seed and seedMany is similar to the make and makeMany method, but at the end the created entity instance gets persisted in the database. +create and createMany 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 enity. ```typescript -seed(overrideParams: EntityProperty = {}): Promise +create(overrideParams: EntityProperty = {}): Promise ``` ```typescript -await factory(User)().seed() -await factory(User)().seedMany(10) +await factory(User)().create() +await factory(User)().createMany(10) // override the email -await factory(User)().seed({ email: 'other@mail.com' }) -await factory(User)().seedMany(10, { email: 'other@mail.com' }) +await factory(User)().create({ email: 'other@mail.com' }) +await factory(User)().createMany(10, { email: 'other@mail.com' }) +``` + +## ❯ Seeding Data in Testing + +The entity factories can also be used in testing. To do so call the `useSeeding` function, which loads all the defined entity factories. + +> Note: Normally Jest parallelizes test runs, which all conect to the same database. This could lead to strange sideeffects. So use the `--runInBand` flag to disable parallelizes runs. + +```typescript +describe("UserService", () => { + beforeAll(async (done) => { + await useRefreshDatabase() + 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 ...', () => { ... }) +}) +``` + +### `useSeeding` + +Loads the defined entity factories. + +```typescript +useSeeding(options: ConfigureOption = {}): Promise +``` + +### `runSeeder` + +Runs the given seeder class. + +```typescript +useSeeding(seed: SeederConstructor): Promise +``` + +### `useRefreshDatabase` + +Connects to the database, drop it and recreates the schema. + +```typescript +useRefreshDatabase(options: ConfigureOption = {}): Promise +``` + +### `tearDownDatabase` + +Closes the open database connection. + +```typescript +tearDownDatabase(): Promise +``` + +### `ConfigureOption` + +```typescript +interface ConfigureOption { + root?: string // path to the orm config file + configName?: string // name of the config file. eg. ormconfig.js + connection?: string // name of the database connection. +} ``` ## ❯ Changelog diff --git a/sample/seeds/create-pets.seed.ts b/sample/seeds/create-pets.seed.ts index 34e83e5e..1cd7b023 100644 --- a/sample/seeds/create-pets.seed.ts +++ b/sample/seeds/create-pets.seed.ts @@ -4,6 +4,6 @@ import { Pet } from '../entities/Pet.entity' export default class CreatePets implements Seeder { public async run(factory: Factory, connection: Connection): Promise { - await factory(Pet)().seed() + await factory(Pet)().create() } } diff --git a/sample/seeds/create-users.seed.ts b/sample/seeds/create-users.seed.ts index b7697bb6..1de35214 100644 --- a/sample/seeds/create-users.seed.ts +++ b/sample/seeds/create-users.seed.ts @@ -3,6 +3,6 @@ import { User } from '../entities/User.entity' export default class CreateUsers implements Seeder { public async run(factory: Factory): Promise { - await factory(User)({ roles: [] }).seedMany(10) + await factory(User)({ roles: [] }).createMany(10) } } diff --git a/src/commands/config.command.ts b/src/commands/config.command.ts index c34163de..2f8d6bd7 100644 --- a/src/commands/config.command.ts +++ b/src/commands/config.command.ts @@ -1,7 +1,7 @@ import * as yargs from 'yargs' import * as chalk from 'chalk' -import { getConnectionOption } from '../typeorm-seeding' import { printError } from '../utils/log.util' +import { configureConnection, getConnectionOptions } from '../connection' export class ConfigCommand implements yargs.CommandModule { command = 'config' @@ -29,15 +29,14 @@ export class ConfigCommand implements yargs.CommandModule { async handler(args: yargs.Arguments) { const log = console.log const pkg = require('../../package.json') - log('🌱 ' + chalk.bold(`TypeORM Seeding v${(pkg as any).version}`)) + log('🌱 ' + chalk.bold(`TypeORM Seeding v${(pkg as any).version}`)) try { - const option = await getConnectionOption( - { - root: args.root as string, - configName: args.configName as string, - }, - args.connection as string, - ) + configureConnection({ + root: args.root as string, + configName: args.configName as string, + connection: args.connection as string, + }) + const option = await getConnectionOptions() log(option) } catch (error) { printError('Could not find the orm config file', error) diff --git a/src/commands/seed.command.ts b/src/commands/seed.command.ts index b24dd6e9..a2669942 100644 --- a/src/commands/seed.command.ts +++ b/src/commands/seed.command.ts @@ -1,11 +1,10 @@ import * as yargs from 'yargs' import * as ora from 'ora' import * as chalk from 'chalk' -import { createConnection } from 'typeorm' -import { setConnection, runSeeder, getConnectionOption, getConnection } from '../typeorm-seeding' import { importSeed } from '../importer' import { loadFiles, importFiles } from '../utils/file.util' -import { ConnectionOptions } from '../connection' +import { runSeeder } from '../typeorm-seeding' +import { configureConnection, getConnectionOptions, ConnectionOptions, createConnection } from '../connection' export class SeedCommand implements yargs.CommandModule { command = 'seed' @@ -35,23 +34,21 @@ export class SeedCommand implements yargs.CommandModule { } async handler(args: yargs.Arguments) { - // Disable logging for the seeders, but keep it alive for our cli const log = console.log - const pkg = require('../../package.json') - log('🌱 ' + chalk.bold(`TypeORM Seeding v${(pkg as any).version}`)) + log('🌱 ' + chalk.bold(`TypeORM Seeding v${(pkg as any).version}`)) const spinner = ora('Loading ormconfig').start() + const configureOption = { + root: args.root as string, + configName: args.configName as string, + connection: args.connection as string, + } // Get TypeORM config file let option: ConnectionOptions try { - option = await getConnectionOption( - { - root: args.root as string, - configName: args.configName as string, - }, - args.connection as string, - ) + configureConnection(configureOption) + option = await getConnectionOptions() spinner.succeed('ORM Config loaded') } catch (error) { panic(spinner, error, 'Could not load the config file!') @@ -59,9 +56,9 @@ export class SeedCommand implements yargs.CommandModule { // Find all factories and seed with help of the config spinner.start('Import Factories') - const factoryFiles = loadFiles(option.factories || ['src/database/factories/**/*{.js,.ts}']) + const factoryFiles = loadFiles(option.factories) try { - importFiles(factoryFiles) + await importFiles(factoryFiles) spinner.succeed('Factories are imported') } catch (error) { panic(spinner, error, 'Could not import factories!') @@ -69,12 +66,13 @@ export class SeedCommand implements yargs.CommandModule { // Show seeds in the console spinner.start('Importing Seeders') - const seedFiles = loadFiles(option.seeds || ['src/database/seeds/**/*{.js,.ts}']) + const seedFiles = loadFiles(option.seeds) let seedFileObjects: any[] = [] try { - seedFileObjects = seedFiles - .map((seedFile) => importSeed(seedFile)) - .filter((seedFileObject) => args.seed === undefined || args.seed === seedFileObject.name) + seedFileObjects = await Promise.all(seedFiles.map((seedFile) => importSeed(seedFile))) + seedFileObjects = seedFileObjects.filter( + (seedFileObject) => args.seed === undefined || args.seed === seedFileObject.name, + ) spinner.succeed('Seeders are imported') } catch (error) { panic(spinner, error, 'Could not import seeders!') @@ -83,8 +81,7 @@ export class SeedCommand implements yargs.CommandModule { // Get database connection and pass it to the seeder spinner.start('Connecting to the database') try { - const connection = await createConnection(option) - setConnection(connection) + await createConnection() spinner.succeed('Database connected') } catch (error) { panic(spinner, error, 'Database connection failed! Check your typeORM config file.') diff --git a/src/connection.ts b/src/connection.ts index 33d3e201..85a68c7c 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -1,8 +1,8 @@ import { - Connection, ConnectionOptionsReader, - createConnection as createTypeORMConnection, + Connection as TypeORMConnection, ConnectionOptions as TypeORMConnectionOptions, + createConnection as TypeORMCreateConnection, } from 'typeorm' import { printError } from './utils/log.util' @@ -11,54 +11,80 @@ interface SeedingOptions { seeds: string[] } -export interface ConnectionOptionArguments { - root: string - configName: string +export declare type ConnectionOptions = TypeORMConnectionOptions & SeedingOptions + +export interface ConfigureOption { + root?: string + configName?: string + connection?: string } -export declare type ConnectionOptions = TypeORMConnectionOptions & SeedingOptions +const KEY = 'TypeORM_Seeding_Connection' -const attachSeedingOptions = (option: ConnectionOptions): ConnectionOptions => { - if (!option.factories) { - const envFactoriesPath = process.env.TYPEORM_SEEDING_FACTORIES - if (envFactoriesPath) { - option.factories = [envFactoriesPath] - } else { - option.factories = ['src/database/factories/**/*{.ts,.js}'] - } - } - if (!option.seeds) { - const envSeedsPath = process.env.TYPEORM_SEEDING_SEEDS - if (envSeedsPath) { - option.seeds = [envSeedsPath] - } else { - option.seeds = ['src/database/seeds/**/*{.ts,.js}'] - } +const defaultConfigureOption: ConfigureOption = { + root: process.cwd(), + configName: '', + connection: '', +} + +if ((global as any)[KEY] === undefined) { + ;(global as any)[KEY] = { + configureOption: defaultConfigureOption, + ormConfig: undefined, + connection: undefined, } - return option } -export const getConnectionOption = async ( - option: ConnectionOptionArguments, - connection: string, -): Promise => { - const reader = new ConnectionOptionsReader(option) - const options = (await reader.all()) as any[] - if (options.length === 1) { - return attachSeedingOptions(options[0]) +export const configureConnection = (option: ConfigureOption = {}) => { + ;(global as any)[KEY].configureOption = { + ...defaultConfigureOption, + ...option, } - if (connection !== undefined && connection !== '') { - const filteredOptions = options.filter((o) => o.name === connection) - if (filteredOptions.length === 1) { - return attachSeedingOptions(options[0]) - } else { - printError('Could not find any connection with the name=', connection) +} + +export const getConnectionOptions = async (): Promise => { + const ormConfig = (global as any)[KEY].ormConfig + if (ormConfig === undefined) { + const configureOption = (global as any)[KEY].configureOption + const connection = configureOption.connection + const reader = new ConnectionOptionsReader({ + root: configureOption.root, + configName: configureOption.configName, + }) + let options = (await reader.all()) as any[] + if (connection !== undefined && connection !== '') { + const filteredOptions = options.filter((o) => o.name === connection) + if (filteredOptions.length === 1) { + options = filteredOptions + } } + if (options.length === 1) { + const option = options[0] + if (!option.factories) { + option.factories = [process.env.TYPEORM_SEEDING_FACTORIES || 'src/database/factories/**/*{.ts,.js}'] + } + if (!option.seeds) { + option.seeds = [process.env.TYPEORM_SEEDING_SEEDS || 'src/database/seeds/**/*{.ts,.js}'] + } + ;(global as any)[KEY].ormConfig = option + return option + } + printError('There are multiple connections please provide a connection name') } - printError('There are multiple connections please provide a connection name') + return ormConfig } -export const createConnection = async (option: ConnectionOptionArguments, name: string): Promise => { - const connectionOption = await getConnectionOption(option, name) - return createTypeORMConnection(connectionOption) +export const createConnection = async (option?: TypeORMConnectionOptions): Promise => { + let connection = (global as any)[KEY].connection + let ormConfig = (global as any)[KEY].ormConfig + + if (option !== undefined) { + ormConfig = option + } + + if (connection === undefined) { + connection = await TypeORMCreateConnection(ormConfig) + ;(global as any)[KEY].connection = connection + } + return connection } diff --git a/src/entity-factory.ts b/src/entity-factory.ts index dffe4990..2badd1d3 100644 --- a/src/entity-factory.ts +++ b/src/entity-factory.ts @@ -1,8 +1,9 @@ import * as Faker from 'faker' -import { Connection, ObjectType } from 'typeorm' +import { ObjectType } from 'typeorm' import { FactoryFunction, EntityProperty } from './types' import { isPromiseLike } from './utils/factory.util' -import { printError } from './utils/log.util' +import { printError, printWarning } from './utils/log.util' +import { getConnectionOptions, createConnection } from './connection' export class EntityFactory { private mapFunction: (entity: Entity) => Promise @@ -35,11 +36,12 @@ export class EntityFactory { } /** - * Seed makes a new entity and does persist it + * Create makes a new entity and does persist it */ - public async seed(overrideParams: EntityProperty = {}): Promise { - const connection: Connection = (global as any).seeder.connection - if (connection) { + public async create(overrideParams: EntityProperty = {}): Promise { + const option = await getConnectionOptions() + const connection = await createConnection(option) + if (connection && connection.isConnected) { const em = connection.createEntityManager() try { const entity = await this.makeEnity(overrideParams, true) @@ -64,14 +66,24 @@ export class EntityFactory { return list } - public async seedMany(amount: number, overrideParams: EntityProperty = {}): Promise { + public async createMany(amount: number, overrideParams: EntityProperty = {}): Promise { const list = [] for (let index = 0; index < amount; index++) { - list[index] = await this.seed(overrideParams) + list[index] = await this.create(overrideParams) } return list } + public async seed(overrideParams: EntityProperty = {}): Promise { + printWarning('The seed() method is deprecated please use the create() method instead') + return this.create(overrideParams) + } + + public async seedMany(amount: number, overrideParams: EntityProperty = {}): Promise { + printWarning('The seedMany() method is deprecated please use the createMany() method instead') + return this.createMany(amount, overrideParams) + } + // ------------------------------------------------------------------------- // Prrivat Helpers // ------------------------------------------------------------------------- @@ -108,7 +120,7 @@ export class EntityFactory { const subEntityFactory = entity[attribute] try { if (isSeeding) { - entity[attribute] = await (subEntityFactory as any).seed() + entity[attribute] = await (subEntityFactory as any).create() } else { entity[attribute] = await (subEntityFactory as any).make() } diff --git a/src/importer.ts b/src/importer.ts index 4c19b3a7..56c6cc9d 100644 --- a/src/importer.ts +++ b/src/importer.ts @@ -1,7 +1,7 @@ import { SeederConstructor, Seeder } from './types' -export const importSeed = (filePath: string): SeederConstructor => { - const seedFileObject: { [key: string]: SeederConstructor } = require(filePath) +export const importSeed = async (filePath: string): Promise => { + const seedFileObject: { [key: string]: SeederConstructor } = await import(filePath) const keys = Object.keys(seedFileObject) return seedFileObject[keys[0]] } diff --git a/src/typeorm-seeding.ts b/src/typeorm-seeding.ts index 66e95cb6..b7d3f65c 100644 --- a/src/typeorm-seeding.ts +++ b/src/typeorm-seeding.ts @@ -1,9 +1,11 @@ import 'reflect-metadata' -import { Connection, ObjectType } from 'typeorm' +import { ObjectType, getConnection, Connection } from 'typeorm' import { EntityFactory } from './entity-factory' import { EntityFactoryDefinition, Factory, FactoryFunction, SeederConstructor, Seeder } from './types' import { getNameOfEntity } from './utils/factory.util' +import { loadFiles, importFiles } from './utils/file.util' +import { ConfigureOption, configureConnection, getConnectionOptions, createConnection } from './connection' // ------------------------------------------------------------------------- // Handy Exports @@ -18,7 +20,6 @@ export { times } from './helpers' // Types & Variables // ------------------------------------------------------------------------- ;(global as any).seeder = { - connection: undefined, entityFactories: new Map>(), } @@ -26,10 +27,6 @@ export { times } from './helpers' // Facade functions // ------------------------------------------------------------------------- -export const setConnection = (connection: Connection) => ((global as any).seeder.connection = connection) - -export const getConnection = () => (global as any).seeder.connection - export const define = (entity: ObjectType, factoryFn: FactoryFunction) => { ;(global as any).seeder.entityFactories.set(getNameOfEntity(entity), { entity, @@ -43,7 +40,34 @@ export const factory: Factory = (entity: ObjectType) => return new EntityFactory(name, entity, entityFactoryObject.factory, context) } -export const runSeeder = async (clazz: SeederConstructor): Promise => { +export const runSeeder = async (clazz: SeederConstructor): Promise => { const seeder: Seeder = new clazz() - return seeder.run(factory, getConnection()) + const connection = await createConnection() + return seeder.run(factory, connection) +} + +// ------------------------------------------------------------------------- +// Facade functions for testing +// ------------------------------------------------------------------------- +export const useRefreshDatabase = async (options: ConfigureOption = {}): Promise => { + configureConnection(options) + const option = await getConnectionOptions() + const connection = await createConnection(option) + if (connection.isConnected) { + await connection.dropDatabase() + await connection.synchronize() + } + return connection +} + +export const tearDownDatabase = async (): Promise => { + const connection = await createConnection() + return connection && connection.isConnected ? connection.close() : undefined +} + +export const useSeeding = async (options: ConfigureOption = {}): Promise => { + configureConnection(options) + const option = await getConnectionOptions() + const factoryFiles = loadFiles(option.factories) + await importFiles(factoryFiles) } diff --git a/src/utils/file.util.ts b/src/utils/file.util.ts index 13a180a2..25dc9150 100644 --- a/src/utils/file.util.ts +++ b/src/utils/file.util.ts @@ -1,7 +1,9 @@ import * as glob from 'glob' import * as path from 'path' -export const importFiles = (filePaths: string[]) => filePaths.forEach(require) +export const importFiles = async (filePaths: string[]) => { + await Promise.all(filePaths.map((filePath) => import(filePath))) +} export const loadFiles = (filePattern: string[]): string[] => { return filePattern diff --git a/src/utils/log.util.ts b/src/utils/log.util.ts index 0849dbf4..b4413b21 100644 --- a/src/utils/log.util.ts +++ b/src/utils/log.util.ts @@ -9,3 +9,13 @@ export const printError = (message: string, error?: any) => { console.error(error) } } + +/** + * Prints the warning to the console + */ +export const printWarning = (message: string, error?: any) => { + console.log('\n🚨 ', chalk.yellow(message)) + if (error) { + console.error(error) + } +} From f3b0f2d99aa9b64ffab4b96151dc5afd4d7f85fe Mon Sep 17 00:00:00 2001 From: hirsch Date: Tue, 14 Apr 2020 22:16:29 +0200 Subject: [PATCH 5/5] docs: update documentation --- README.md | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 924c372b..8c9b83f2 100755 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Isn't it exhausting to create some sample data for your database, well this time is over! -How does it work? Just create a factory for your entities (models) and a seed script. +How does it work? Just create a entity factory for your entities (models) and a seed script. ### Enity @@ -75,9 +75,9 @@ export class Pet { ### Factory -The purpose of a factory is to create new fake entites with generate data. +Then for each entity define a factory. The purpose of a factory is to create new entites with generate data. -> Factories can also be used to generate test data for some unit, integration or e2e tests. +> Note: Factories can also be used to generate data for testing. ```typescript // user.factory.ts @@ -107,7 +107,10 @@ define(Pet, (faker: typeof Faker) => { ### Seeder -The seeder can be called by the configured cli command `seed:run`. In this case it generates 10 pets with a owner (User). + +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:run` must be configured first. Go to [CLI Configuration](#cli-configuration). ```typescript // create-pets.seed.ts @@ -122,7 +125,7 @@ export default class CreatePets implements Seeder { Before using this TypeORM extension please read the [TypeORM Getting Started](https://typeorm.io/#/) documentation. This explains how to setup a TypeORM project. -You can install our extension with `npm` or `yarn`. +After that install the extension with `npm` or `yarn`. ```bash npm i typeorm-seeding @@ -130,7 +133,7 @@ npm i typeorm-seeding yarn add typeorm-seeding ``` -Optional, for `Faker` types +Optional, install the type definitions of the `Faker` library. ```bash npm install -D @types/faker @@ -140,7 +143,7 @@ npm install -D @types/faker To configure the path to your seeds and factories change the TypeORM config file(ormconfig.js or ormconfig.json). -> Default is `src/database/{seeds,factories}/**/*{.ts,.js}` +> The default paths are `src/database/{seeds,factories}/**/*{.ts,.js}` **ormconfig.js** @@ -161,7 +164,7 @@ TYPEORM_SEEDING_SEEDS=src/seeds/**/*{.ts,.js} ### CLI Configuration -Add the following scripts to your `package.json` file. +Add the following scripts to your `package.json` file to configure the seed cli commands. ``` "scripts": { @@ -171,7 +174,9 @@ Add the following scripts to your `package.json` file. } ``` -> Now you are able to execute your seeds with this command `npm run seed:run`. +To execute the seed run `npm run seed:run` in the terminal. + +> Note: More CLI optios are [here](#cli-options) Add the following TypeORM cli commands to the package.json to drop and sync the database. @@ -188,14 +193,16 @@ Add the following TypeORM cli commands to the package.json to drop and sync the | Option | Default | Description | | ---------------------- | --------------- | --------------------------------------------------------------------------- | -| `--seed` or `-s` | null | Option to specify a specific seeder class to run individually. | +| `--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. | ## ❯ Basic Seeder -The seeds files define how much and how the data are connected with each other. The files will be executed alphabetically. +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](https://typeorm.io/#/select-query-builder) or use the [Entity Factory](#-using-entity-factory) + +> Note. The seeder files will be executed alphabetically. ```typescript import { Factory, Seeder } from 'typeorm-seeding' @@ -219,6 +226,8 @@ export default class CreateUsers implements Seeder { ## ❯ Using Entity Factory +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](https://github.com/marak/Faker.js/) 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 | @@ -278,7 +287,7 @@ await factory(User)() #### `make` & `makeMany` -Make and makeMany executes the factory functions and return a new instance of the given enity. The instance is filled with the generated values from the factory function. +Make and makeMany executes the factory functions and return a new instance of the given enity. 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 enity. @@ -297,7 +306,7 @@ await factory(User)().makeMany(10, { email: 'other@mail.com' }) #### `create` & `createMany` -create and createMany is similar to the make and makeMany method, but at the end the created entity instance gets persisted in the database. +the 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 enity. @@ -360,7 +369,7 @@ useSeeding(seed: SeederConstructor): Promise ### `useRefreshDatabase` -Connects to the database, drop it and recreates the schema. +Connects to the database, drops it and recreates the schema. ```typescript useRefreshDatabase(options: ConfigureOption = {}): Promise @@ -378,7 +387,7 @@ tearDownDatabase(): Promise ```typescript interface ConfigureOption { - root?: string // path to the orm config file + 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. }