@jorgebodega/typeorm-seeding 2.0.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -0
- package/LICENSE +21 -0
- package/README.md +374 -0
- package/dist/package.json +81 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +19 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/commands/config.command.d.ts +19 -0
- package/dist/src/commands/config.command.js +70 -0
- package/dist/src/commands/config.command.js.map +1 -0
- package/dist/src/commands/seed.command.d.ts +22 -0
- package/dist/src/commands/seed.command.js +105 -0
- package/dist/src/commands/seed.command.js.map +1 -0
- package/dist/src/connection/ConnectionConfigurationManager.d.ts +9 -0
- package/dist/src/connection/ConnectionConfigurationManager.js +24 -0
- package/dist/src/connection/ConnectionConfigurationManager.js.map +1 -0
- package/dist/src/connection/configureConnection.d.ts +2 -0
- package/dist/src/connection/configureConnection.js +9 -0
- package/dist/src/connection/configureConnection.js.map +1 -0
- package/dist/src/connection/fetchConnection.d.ts +2 -0
- package/dist/src/connection/fetchConnection.js +22 -0
- package/dist/src/connection/fetchConnection.js.map +1 -0
- package/dist/src/connection/getConnectionOptions.d.ts +2 -0
- package/dist/src/connection/getConnectionOptions.js +22 -0
- package/dist/src/connection/getConnectionOptions.js.map +1 -0
- package/dist/src/connection/index.d.ts +3 -0
- package/dist/src/connection/index.js +7 -0
- package/dist/src/connection/index.js.map +1 -0
- package/dist/src/errors/EntityNotDefinedError.d.ts +3 -0
- package/dist/src/errors/EntityNotDefinedError.js +10 -0
- package/dist/src/errors/EntityNotDefinedError.js.map +1 -0
- package/dist/src/errors/FactoryImportationError.d.ts +3 -0
- package/dist/src/errors/FactoryImportationError.js +10 -0
- package/dist/src/errors/FactoryImportationError.js.map +1 -0
- package/dist/src/errors/FactoryNotDefinedError.d.ts +3 -0
- package/dist/src/errors/FactoryNotDefinedError.js +10 -0
- package/dist/src/errors/FactoryNotDefinedError.js.map +1 -0
- package/dist/src/errors/SeederImportationError.d.ts +3 -0
- package/dist/src/errors/SeederImportationError.js +10 -0
- package/dist/src/errors/SeederImportationError.js.map +1 -0
- package/dist/src/facade.d.ts +12 -0
- package/dist/src/facade.js +30 -0
- package/dist/src/facade.js.map +1 -0
- package/dist/src/factoriesMap.d.ts +5 -0
- package/dist/src/factoriesMap.js +23 -0
- package/dist/src/factoriesMap.js.map +1 -0
- package/dist/src/factory.d.ts +32 -0
- package/dist/src/factory.js +90 -0
- package/dist/src/factory.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +12 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/runSeeder.d.ts +2 -0
- package/dist/src/runSeeder.js +11 -0
- package/dist/src/runSeeder.js.map +1 -0
- package/dist/src/seeder.d.ts +5 -0
- package/dist/src/seeder.js +7 -0
- package/dist/src/seeder.js.map +1 -0
- package/dist/src/types.d.ts +28 -0
- package/dist/src/types.js +3 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/useFactories.d.ts +3 -0
- package/dist/src/useFactories.js +44 -0
- package/dist/src/useFactories.js.map +1 -0
- package/dist/src/useSeeders.d.ts +4 -0
- package/dist/src/useSeeders.js +54 -0
- package/dist/src/useSeeders.js.map +1 -0
- package/dist/src/utils/fileHandling.d.ts +1 -0
- package/dist/src/utils/fileHandling.js +10 -0
- package/dist/src/utils/fileHandling.js.map +1 -0
- package/dist/src/utils/getNameOfEntity.d.ts +2 -0
- package/dist/src/utils/getNameOfEntity.js +12 -0
- package/dist/src/utils/getNameOfEntity.js.map +1 -0
- package/dist/src/utils/isPromiseLike.d.ts +1 -0
- package/dist/src/utils/isPromiseLike.js +6 -0
- package/dist/src/utils/isPromiseLike.js.map +1 -0
- package/package.json +81 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# [2.0.0-next.2](https://github.com/jorgebodega/typeorm-seeding/compare/v2.0.0-next.1...v2.0.0-next.2) (2021-12-13)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* npmignore not working properly ([2d1d898](https://github.com/jorgebodega/typeorm-seeding/commit/2d1d8986351ec647f88df7f3a72c37b149826fa3))
|
|
7
|
+
|
|
8
|
+
# [2.0.0-next.1](https://github.com/jorgebodega/typeorm-seeding/compare/v1.6.2...v2.0.0-next.1) (2021-12-12)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
* :construction_worker: ci: Add changes to how semantic-release work ([c4c34dd](https://github.com/jorgebodega/typeorm-seeding/commit/c4c34dd55882a445992882398c5da74459322a77))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* add save options to create and createMany ([ca88005](https://github.com/jorgebodega/typeorm-seeding/commit/ca88005775d0aa37d1668d458ad17d260b192499))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### BREAKING CHANGES
|
|
20
|
+
|
|
21
|
+
* just to enforce new major version
|
|
22
|
+
|
|
23
|
+
# [2.0.0-next.1](https://github.com/jorgebodega/typeorm-seeding/compare/v1.6.2...v2.0.0-next.1) (2021-12-12)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
* :construction_worker: ci: Add changes to how semantic-release work ([c4c34dd](https://github.com/jorgebodega/typeorm-seeding/commit/c4c34dd55882a445992882398c5da74459322a77))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Features
|
|
30
|
+
|
|
31
|
+
* add save options to create and createMany ([ca88005](https://github.com/jorgebodega/typeorm-seeding/commit/ca88005775d0aa37d1668d458ad17d260b192499))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### BREAKING CHANGES
|
|
35
|
+
|
|
36
|
+
* just to enforce new major version
|
|
37
|
+
|
|
38
|
+
# [2.0.0-next.1](https://github.com/jorgebodega/typeorm-seeding/compare/v1.6.2...v2.0.0-next.1) (2021-12-12)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
* :construction_worker: ci: Add changes to how semantic-release work ([c4c34dd](https://github.com/jorgebodega/typeorm-seeding/commit/c4c34dd55882a445992882398c5da74459322a77))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
### Features
|
|
45
|
+
|
|
46
|
+
* add save options to create and createMany ([ca88005](https://github.com/jorgebodega/typeorm-seeding/commit/ca88005775d0aa37d1668d458ad17d260b192499))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
### BREAKING CHANGES
|
|
50
|
+
|
|
51
|
+
* just to enforce new major version
|
|
52
|
+
|
|
53
|
+
# [2.0.0-next.1](https://github.com/jorgebodega/typeorm-seeding/compare/v1.6.2...v2.0.0-next.1) (2021-12-12)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
* :construction_worker: ci: Add changes to how semantic-release work ([c4c34dd](https://github.com/jorgebodega/typeorm-seeding/commit/c4c34dd55882a445992882398c5da74459322a77))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### Features
|
|
60
|
+
|
|
61
|
+
* add save options to create and createMany ([ca88005](https://github.com/jorgebodega/typeorm-seeding/commit/ca88005775d0aa37d1668d458ad17d260b192499))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### BREAKING CHANGES
|
|
65
|
+
|
|
66
|
+
* just to enforce new major version
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018 w3tecch
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./logo.png" alt="logo" width="160" />
|
|
3
|
+
</p>
|
|
4
|
+
<h1 align="center" style="text-align: center;">TypeORM Seeding</h1>
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
7
|
+
<img alt="NPM" src="https://img.shields.io/npm/l/@jorgebodega/typeorm-seeding?style=for-the-badge">
|
|
8
|
+
<a href="https://www.npmjs.com/package/@jorgebodega/typeorm-seeding">
|
|
9
|
+
<img alt="NPM latest version" src="https://img.shields.io/npm/v/@jorgebodega/typeorm-seeding/latest?style=for-the-badge">
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/@jorgebodega/typeorm-seeding/v/next">
|
|
12
|
+
<img alt="NPM next version" src="https://img.shields.io/npm/v/@jorgebodega/typeorm-seeding/next?style=for-the-badge">
|
|
13
|
+
</a>
|
|
14
|
+
<a href="https://github.com/semantic-release/semantic-release">
|
|
15
|
+
<img src="https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release&style=for-the-badge" alt="Semantic release" />
|
|
16
|
+
</a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<p align="center">
|
|
20
|
+
<a href='https://coveralls.io/github/jorgebodega/typeorm-seeding'>
|
|
21
|
+
<img alt="Coveralls master branch" src="https://img.shields.io/coveralls/github/jorgebodega/typeorm-seeding/master?style=for-the-badge">
|
|
22
|
+
</a>
|
|
23
|
+
<a href='https://coveralls.io/github/jorgebodega/typeorm-seeding?branch=next'>
|
|
24
|
+
<img alt="Coveralls next branch" src="https://img.shields.io/coveralls/github/jorgebodega/typeorm-seeding/next?style=for-the-badge&label=coverage%40next">
|
|
25
|
+
</a>
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
<p align="center">
|
|
29
|
+
<img alt="Checks for master branch" src="https://img.shields.io/github/checks-status/jorgebodega/typeorm-seeding/master?style=for-the-badge">
|
|
30
|
+
<a href='https://coveralls.io/github/jorgebodega/typeorm-seeding'>
|
|
31
|
+
<img alt="Checks for next branch" src="https://img.shields.io/github/checks-status/jorgebodega/typeorm-seeding/next?label=checks%40next&style=for-the-badge">
|
|
32
|
+
</a>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<b>A delightful way to seed test data into your database.</b></br>
|
|
37
|
+
<span>Inspired by the awesome framework <a href="https://laravel.com/">laravel</a> in PHP and of the repositories from <a href="https://github.com/pleerock">pleerock</a></span></br>
|
|
38
|
+
<sub>Made with ❤️ by <a href="https://github.com/hirsch88">Gery Hirschfeld</a>, <a href="https://github.com/jorgebodega">Jorge Bodega</a> and <a href="https://github.com/w3tecch/typeorm-seeding/graphs/contributors">contributors</a></sub>
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<br />
|
|
42
|
+
|
|
43
|
+
## ❯ Table of contents
|
|
44
|
+
|
|
45
|
+
- [Installation](#-installation)
|
|
46
|
+
- [Introduction](#-introduction)
|
|
47
|
+
- [Basic Seeder](#-basic-seeder)
|
|
48
|
+
- [Using Entity Factory](#-using-entity-factory)
|
|
49
|
+
- [Seeding Data in Testing](#-seeding-data-in-testing)
|
|
50
|
+
|
|
51
|
+
## ❯ Installation
|
|
52
|
+
|
|
53
|
+
Before using this TypeORM extension please read the [TypeORM Getting Started](https://typeorm.io/#/) documentation. This explains how to setup a TypeORM project.
|
|
54
|
+
|
|
55
|
+
After that install the extension with `npm` or `yarn`. Add development flag if you are not using seeders nor factories in production code.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm i [-D] @jorgebodega/typeorm-seeding
|
|
59
|
+
yarn add [-D] @jorgebodega/typeorm-seeding
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Optional, install the type definitions of the `Faker` library.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm install -D @types/faker
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Configuration
|
|
69
|
+
|
|
70
|
+
To configure the path to your seeds and factories change the TypeORM config file or use environment variables like TypeORM. If both are used the environment variables will be prioritized.
|
|
71
|
+
|
|
72
|
+
**ormconfig.js**
|
|
73
|
+
|
|
74
|
+
```JavaScript
|
|
75
|
+
module.exports = {
|
|
76
|
+
...
|
|
77
|
+
seeds: ['src/seeds/**/*{.ts,.js}'],
|
|
78
|
+
factories: ['src/factories/**/*{.ts,.js}'],
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**.env**
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
TYPEORM_SEEDING_FACTORIES=src/factories/**/*{.ts,.js}
|
|
86
|
+
TYPEORM_SEEDING_SEEDS=src/seeds/**/*{.ts,.js}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### CLI Configuration
|
|
90
|
+
|
|
91
|
+
Add the following scripts to your `package.json` file to configure the seed cli commands.
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
"scripts": {
|
|
95
|
+
"seed:config": "typeorm-seeding config",
|
|
96
|
+
"seed:run": "typeorm-seeding seed",
|
|
97
|
+
...
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### CLI Options
|
|
102
|
+
|
|
103
|
+
| Option | Default | Description |
|
|
104
|
+
| ---------------------- | --------------------- | ---------------------------------------------------------------------------- |
|
|
105
|
+
| `--seed` or `-s` | null | Option to specify a seeder class to run individually. (Only on seed command) |
|
|
106
|
+
| `--connection` or `-c` | TypeORM default value | Name of the TypeORM connection. Required if there are multiple connections. |
|
|
107
|
+
| `--configName` or `-n` | TypeORM default value | Name to the TypeORM config file. |
|
|
108
|
+
| `--root` or `-r` | TypeORM default value | Path to the TypeORM config file. |
|
|
109
|
+
|
|
110
|
+
## ❯ Introduction
|
|
111
|
+
|
|
112
|
+
Isn't it exhausting to create some sample data for your database, well this time is over!
|
|
113
|
+
|
|
114
|
+
How does it work? Just create a entity factory for your entities (models) and a seed script.
|
|
115
|
+
|
|
116
|
+
### Entity
|
|
117
|
+
|
|
118
|
+
First create your TypeORM entities.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// user.entity.ts
|
|
122
|
+
@Entity()
|
|
123
|
+
export class User {
|
|
124
|
+
@PrimaryGeneratedColumn('uuid') id: string
|
|
125
|
+
@Column({ nullable: true }) name: string
|
|
126
|
+
@Column({ type: 'varchar', length: 100, nullable: false }) password: string
|
|
127
|
+
@OneToMany((type) => Pet, (pet) => pet.user) pets: Pet[]
|
|
128
|
+
|
|
129
|
+
@BeforeInsert()
|
|
130
|
+
async setPassword(password: string) {
|
|
131
|
+
const salt = await bcrypt.genSalt()
|
|
132
|
+
this.password = await bcrypt.hash(password || this.password, salt)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// pet.entity.ts
|
|
137
|
+
@Entity()
|
|
138
|
+
export class Pet {
|
|
139
|
+
@PrimaryGeneratedColumn('uuid') id: string
|
|
140
|
+
@Column() name: string
|
|
141
|
+
@Column() age: number
|
|
142
|
+
@ManyToOne((type) => User, (user) => user.pets)
|
|
143
|
+
@JoinColumn({ name: 'user_id' })
|
|
144
|
+
user: User
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Factory
|
|
149
|
+
|
|
150
|
+
Then for each entity define a factory. The purpose of a factory is to create new entites with generate data.
|
|
151
|
+
|
|
152
|
+
> Note: Factories can also be used to generate data for testing.
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// user.factory.ts
|
|
156
|
+
define(User, (faker: typeof Faker) => {
|
|
157
|
+
const gender = faker.datatype.number(1)
|
|
158
|
+
const firstName = faker.name.firstName(gender)
|
|
159
|
+
const lastName = faker.name.lastName(gender)
|
|
160
|
+
|
|
161
|
+
const user = new User()
|
|
162
|
+
user.name = `${firstName} ${lastName}`
|
|
163
|
+
user.password = faker.random.word()
|
|
164
|
+
return user
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
// pet.factory.ts
|
|
168
|
+
define(Pet, (faker: typeof Faker) => {
|
|
169
|
+
const gender = faker.datatype.number(1)
|
|
170
|
+
const name = faker.name.firstName(gender)
|
|
171
|
+
|
|
172
|
+
const pet = new Pet()
|
|
173
|
+
pet.name = name
|
|
174
|
+
pet.age = faker.datatype.number()
|
|
175
|
+
pet.user = factory(User)() as any
|
|
176
|
+
return pet
|
|
177
|
+
})
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Seeder
|
|
181
|
+
|
|
182
|
+
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).
|
|
183
|
+
|
|
184
|
+
> Note: `seed:run` must be configured first. Go to [CLI Configuration](#cli-configuration).
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
// create-pets.seed.ts
|
|
188
|
+
export default class CreatePets implements Seeder {
|
|
189
|
+
public async run(factory: Factory, connection: Connection): Promise<any> {
|
|
190
|
+
await factory(Pet)().createMany(10)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Until [this issue](https://github.com/w3tecch/typeorm-seeding/issues/119) is closed, seeder files must not contain any other export statement besides the one that exports the seeder class.
|
|
196
|
+
|
|
197
|
+
## ❯ Basic Seeder
|
|
198
|
+
|
|
199
|
+
A seeder class only use `run` method. 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)
|
|
200
|
+
|
|
201
|
+
> Note. The seeder files will be executed alphabetically.
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
export default class CreateUsers implements Seeder {
|
|
205
|
+
public async run(factory: EntityFactory, connection: Connection): Promise<any> {
|
|
206
|
+
await connection
|
|
207
|
+
.createQueryBuilder()
|
|
208
|
+
.insert()
|
|
209
|
+
.into(User)
|
|
210
|
+
.values([
|
|
211
|
+
{ firstName: 'Timber', lastName: 'Saw' },
|
|
212
|
+
{ firstName: 'Phantom', lastName: 'Lancer' },
|
|
213
|
+
])
|
|
214
|
+
.execute()
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## ❯ Using Entity Factory
|
|
220
|
+
|
|
221
|
+
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.
|
|
222
|
+
|
|
223
|
+
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`.
|
|
224
|
+
|
|
225
|
+
| Types | Description |
|
|
226
|
+
| --------------- | ------------------------------------------------------------------------------- |
|
|
227
|
+
| `Entity` | TypeORM Entity like the user or the pet in the samples. |
|
|
228
|
+
| `Context` | Argument to pass some static data into the factory function. |
|
|
229
|
+
| `EntityFactory` | This object is used to make new filled entities or create it into the database. |
|
|
230
|
+
|
|
231
|
+
### `define`
|
|
232
|
+
|
|
233
|
+
The define function creates a new entity factory.
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
define: <Entity, Context>(entity: Entity, factoryFn: FactoryFunction<Entity, Context>) => void;
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
define(User, (faker: typeof Faker, context: { roles: string[] }) => {
|
|
241
|
+
const user = new User()
|
|
242
|
+
...
|
|
243
|
+
return user
|
|
244
|
+
})
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### `factory`
|
|
248
|
+
|
|
249
|
+
Factory retrieves the defined factory function and returns the EntityFactory to start creating new enities.
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
factory: (entity: Entity) => (context?: Context) => Factory<Entity, Context>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
factory(Pet)()
|
|
257
|
+
factory(Pet)({ name: 'Balou' })
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Factory
|
|
261
|
+
|
|
262
|
+
#### `map`
|
|
263
|
+
|
|
264
|
+
Use the `.map()` function to alter the generated value before they get processed.
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
map(mapFunction: (entity: Entity) => Promise<Entity>): Factory<Entity, Context>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
await factory(User)()
|
|
272
|
+
.map(async (user: User) => {
|
|
273
|
+
const pets: Pet[] = await factory(Pet)().createMany(2)
|
|
274
|
+
const petIds = pets.map((pet: Pet) => pet.Id)
|
|
275
|
+
await user.pets().attach(petIds)
|
|
276
|
+
return user
|
|
277
|
+
})
|
|
278
|
+
.createMany(5)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### `make` & `makeMany`
|
|
282
|
+
|
|
283
|
+
Make 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.
|
|
284
|
+
|
|
285
|
+
- **overrideParams** - Override some of the attributes of the entity.
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
make(overrideParams: Partial<Entity> = {}): Promise<Entity>
|
|
289
|
+
makeMany(amount: number, overrideParams: Partial<Entity> = {}): Promise<Entity>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
await factory(User)().make()
|
|
294
|
+
await factory(User)().makeMany(10)
|
|
295
|
+
|
|
296
|
+
// override the email
|
|
297
|
+
await factory(User)().make({ email: 'other@mail.com' })
|
|
298
|
+
await factory(User)().makeMany(10, { email: 'other@mail.com' })
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### `create` & `createMany`
|
|
302
|
+
|
|
303
|
+
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 using TypeORM entity manager.
|
|
304
|
+
|
|
305
|
+
- **overrideParams** - Override some of the attributes of the entity.
|
|
306
|
+
- **saveOptions** - [Save options](https://github.com/typeorm/typeorm/blob/master/src/repository/SaveOptions.ts) from TypeORM
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
create(overrideParams: Partial<Entity> = {}, saveOptions?: SaveOptions): Promise<Entity>
|
|
310
|
+
createMany(amount: number, overrideParams: Partial<Entity> = {}, saveOptions?: SaveOptions): Promise<Entity>
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
await factory(User)().create()
|
|
315
|
+
await factory(User)().createMany(10)
|
|
316
|
+
|
|
317
|
+
// override the email
|
|
318
|
+
await factory(User)().create({ email: 'other@mail.com' })
|
|
319
|
+
await factory(User)().createMany(10, { email: 'other@mail.com' })
|
|
320
|
+
|
|
321
|
+
// using save options
|
|
322
|
+
await factory(User)().create({ email: 'other@mail.com' }, { listeners: false })
|
|
323
|
+
await factory(User)().createMany(10, { email: 'other@mail.com' }, { listeners: false })
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
#### Execution order
|
|
327
|
+
|
|
328
|
+
As the order of execution can be complex, you can check it here:
|
|
329
|
+
|
|
330
|
+
1. **Context**: The context is used when the entity is being created
|
|
331
|
+
2. **Map function**: Map function alters the already existing entity.
|
|
332
|
+
3. **Override params**: Alters the already existing entity.
|
|
333
|
+
4. **Promises**: If some attribute is a promise, the promise will be resolved before the entity is created.
|
|
334
|
+
5. **Factories**: If some attribute is a factory, the factory will be executed with `make`/`create` like the previous one.
|
|
335
|
+
|
|
336
|
+
## ❯ Seeding Data in Testing
|
|
337
|
+
|
|
338
|
+
The entity factories can also be used in testing. To do so call the `useFactories` or `useSeeders` function.
|
|
339
|
+
|
|
340
|
+
### `useFactories`
|
|
341
|
+
|
|
342
|
+
Loads the defined entity factories.
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
useFactories(options?: Partial<ConnectionConfiguration>): Promise<void>
|
|
346
|
+
useFactories(seeders?: string[], options?: Partial<ConnectionConfiguration>): Promise<void>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### `useSeeders`
|
|
350
|
+
|
|
351
|
+
Loads the seeders, and could execute them.
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
useSeeders(executeSeeders?: boolean, options?: Partial<ConnectionConfiguration>): Promise<Seeder[]>
|
|
355
|
+
useSeeders(executeSeeders?: boolean, seeders?: string[], options?: Partial<ConnectionConfiguration>): Promise<Seeder[]>
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### `runSeeder`
|
|
359
|
+
|
|
360
|
+
Runs the given seeder class.
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
runSeeder(seeder: Seeder): Promise<void>
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### `ConnectionConfiguration`
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
interface ConnectionConfiguration {
|
|
370
|
+
root?: string // path to the orm config file. Default = process.cwd()
|
|
371
|
+
configName?: string // name of the config file. eg. ormconfig.js
|
|
372
|
+
connection = 'default' // name of the database connection.
|
|
373
|
+
}
|
|
374
|
+
```
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jorgebodega/typeorm-seeding",
|
|
3
|
+
"version": "2.0.0-next.2",
|
|
4
|
+
"description": "🌱 A delightful way to seed test data into your database.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Gery Hirschfeld <gery.hirschfeld@w3tec.ch> (https://github.com/hirsch88)",
|
|
7
|
+
"contributors": [
|
|
8
|
+
"Jorge Bodega <jorge.bodega.f@gmail.com> (https://github.com/jorgebodega)"
|
|
9
|
+
],
|
|
10
|
+
"main": "dist/index.js",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"bin": {
|
|
13
|
+
"typeorm-seeding": "dist/cli.js"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/jorgebodega/typeorm-seeding.git"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc --project ./tsconfig.build.json",
|
|
21
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
22
|
+
"format:ci": "prettier --check \"src/**/*.ts\" \"sample/**/*.ts\"",
|
|
23
|
+
"lint": "eslint \"src/**/*.ts\" \"sample/**/*.ts\" --fix",
|
|
24
|
+
"lint:ci": "eslint \"src/**/*.ts\" \"sample/**/*.ts\"",
|
|
25
|
+
"prebuild": "rimraf dist",
|
|
26
|
+
"prepack": "yarn build",
|
|
27
|
+
"schema:drop": "ts-node ./node_modules/typeorm/cli.js schema:drop",
|
|
28
|
+
"schema:log": "ts-node ./node_modules/typeorm/cli.js schema:log",
|
|
29
|
+
"schema:sync": "ts-node ./node_modules/typeorm/cli.js schema:sync",
|
|
30
|
+
"seed:run": "ts-node ./src/cli.ts seed",
|
|
31
|
+
"seed:config": "ts-node ./src/cli.ts config",
|
|
32
|
+
"test": "jest",
|
|
33
|
+
"test:cov": "jest --coverage --silent",
|
|
34
|
+
"test:watch": "jest --watch",
|
|
35
|
+
"typecheck": "tsc --noEmit"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@semantic-release/changelog": "^6.0.1",
|
|
39
|
+
"@semantic-release/git": "^10.0.1",
|
|
40
|
+
"@tsconfig/node16": "^1.0.2",
|
|
41
|
+
"@types/bcryptjs": "^2.4.2",
|
|
42
|
+
"@types/chalk": "^2.2.0",
|
|
43
|
+
"@types/faker": "^5.5.9",
|
|
44
|
+
"@types/glob": "^7.2.0",
|
|
45
|
+
"@types/jest": "^27.0.3",
|
|
46
|
+
"@types/node": "^16.11.12",
|
|
47
|
+
"@types/yargs": "^17.0.7",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^5.6.0",
|
|
49
|
+
"@typescript-eslint/parser": "^5.6.0",
|
|
50
|
+
"bcryptjs": "^2.4.3",
|
|
51
|
+
"eslint": "^8.4.1",
|
|
52
|
+
"eslint-config-prettier": "^8.3.0",
|
|
53
|
+
"eslint-plugin-import": "^2.25.3",
|
|
54
|
+
"jest": "^27.4.3",
|
|
55
|
+
"prettier": "^2.5.1",
|
|
56
|
+
"semantic-release": "^18.0.1",
|
|
57
|
+
"sqlite3": "^5.0.2",
|
|
58
|
+
"ts-jest": "^27.1.1",
|
|
59
|
+
"ts-node": "^10.4.0",
|
|
60
|
+
"typeorm": "^0.2.41",
|
|
61
|
+
"typescript": "^4.5.3"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"chalk": "^4.1.2",
|
|
65
|
+
"faker": "^5.5.3",
|
|
66
|
+
"glob": "^7.2.0",
|
|
67
|
+
"ora": "^5.4.1",
|
|
68
|
+
"reflect-metadata": "^0.1.13",
|
|
69
|
+
"rimraf": "^3.0.2",
|
|
70
|
+
"yargs": "^17.3.0"
|
|
71
|
+
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"typeorm": "^0.2.41"
|
|
74
|
+
},
|
|
75
|
+
"resolutions": {
|
|
76
|
+
"mem": ">=4.0.0"
|
|
77
|
+
},
|
|
78
|
+
"engines": {
|
|
79
|
+
"node": ">=14"
|
|
80
|
+
}
|
|
81
|
+
}
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
/* istanbul ignore file */
|
|
6
|
+
require("reflect-metadata");
|
|
7
|
+
const yargs = (0, tslib_1.__importStar)(require("yargs"));
|
|
8
|
+
const seed_command_1 = require("./commands/seed.command");
|
|
9
|
+
const config_command_1 = require("./commands/config.command");
|
|
10
|
+
yargs
|
|
11
|
+
.usage('Usage: $0 <command> [options]')
|
|
12
|
+
.command(new config_command_1.ConfigCommand())
|
|
13
|
+
.command(new seed_command_1.SeedCommand())
|
|
14
|
+
.recommendCommands()
|
|
15
|
+
.demandCommand(1)
|
|
16
|
+
.strict()
|
|
17
|
+
.help('h')
|
|
18
|
+
.alias('h', 'help').argv;
|
|
19
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";;;;AACA,0BAA0B;AAC1B,4BAAyB;AACzB,0DAA8B;AAC9B,0DAAqD;AACrD,8DAAyD;AAEzD,KAAK;KACF,KAAK,CAAC,+BAA+B,CAAC;KACtC,OAAO,CAAC,IAAI,8BAAa,EAAE,CAAC;KAC5B,OAAO,CAAC,IAAI,0BAAW,EAAE,CAAC;KAC1B,iBAAiB,EAAE;KACnB,aAAa,CAAC,CAAC,CAAC;KAChB,MAAM,EAAE;KACR,IAAI,CAAC,GAAG,CAAC;KACT,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,IAAI,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Argv, Arguments, CommandModule } from 'yargs';
|
|
2
|
+
interface ConfigCommandArguments extends Arguments {
|
|
3
|
+
root?: string;
|
|
4
|
+
configName?: string;
|
|
5
|
+
connection?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class ConfigCommand implements CommandModule {
|
|
8
|
+
command: string;
|
|
9
|
+
describe: string;
|
|
10
|
+
builder(args: Argv): Argv<{
|
|
11
|
+
n: string | undefined;
|
|
12
|
+
} & {
|
|
13
|
+
c: string;
|
|
14
|
+
} & {
|
|
15
|
+
r: string | undefined;
|
|
16
|
+
}>;
|
|
17
|
+
handler(args: ConfigCommandArguments): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.ConfigCommand = void 0;
|
|
23
|
+
const yargs_1 = require("yargs");
|
|
24
|
+
const chalk_1 = require("chalk");
|
|
25
|
+
const connection_1 = require("../connection");
|
|
26
|
+
class ConfigCommand {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.command = 'config';
|
|
29
|
+
this.describe = 'Show the TypeORM config';
|
|
30
|
+
}
|
|
31
|
+
builder(args) {
|
|
32
|
+
return args
|
|
33
|
+
.option('n', {
|
|
34
|
+
alias: 'configName',
|
|
35
|
+
type: 'string',
|
|
36
|
+
describe: 'Name of the typeorm config file (json or js).',
|
|
37
|
+
})
|
|
38
|
+
.option('c', {
|
|
39
|
+
alias: 'connection',
|
|
40
|
+
type: 'string',
|
|
41
|
+
default: 'default',
|
|
42
|
+
describe: 'Name of the typeorm connection',
|
|
43
|
+
})
|
|
44
|
+
.option('r', {
|
|
45
|
+
alias: 'root',
|
|
46
|
+
type: 'string',
|
|
47
|
+
describe: 'Path to your typeorm config file',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async handler(args) {
|
|
51
|
+
const { default: pkg } = await Promise.resolve().then(() => __importStar(require('../../package.json')));
|
|
52
|
+
console.log('🌱 ' + (0, chalk_1.bold)(`TypeORM Seeding v${pkg.version}`));
|
|
53
|
+
try {
|
|
54
|
+
(0, connection_1.configureConnection)({
|
|
55
|
+
root: args.root,
|
|
56
|
+
configName: args.configName,
|
|
57
|
+
connection: args.connection,
|
|
58
|
+
});
|
|
59
|
+
const options = await (0, connection_1.getConnectionOptions)();
|
|
60
|
+
console.log(options);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.log('\n❌ ', (0, chalk_1.red)('Could not find the orm config file'));
|
|
64
|
+
console.error(error);
|
|
65
|
+
(0, yargs_1.exit)(1, error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.ConfigCommand = ConfigCommand;
|
|
70
|
+
//# sourceMappingURL=config.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.command.js","sourceRoot":"","sources":["../../../src/commands/config.command.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,iCAA4D;AAC5D,iCAAiC;AACjC,8CAAyE;AAQzE,MAAa,aAAa;IAA1B;QACE,YAAO,GAAG,QAAQ,CAAA;QAClB,aAAQ,GAAG,yBAAyB,CAAA;IAuCtC,CAAC;IArCC,OAAO,CAAC,IAAU;QAChB,OAAO,IAAI;aACR,MAAM,CAAC,GAAG,EAAE;YACX,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,+CAA+C;SAC1D,CAAC;aACD,MAAM,CAAC,GAAG,EAAE;YACX,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,SAAS;YAClB,QAAQ,EAAE,gCAAgC;SAC3C,CAAC;aACD,MAAM,CAAC,GAAG,EAAE;YACX,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,kCAAkC;SAC7C,CAAC,CAAA;IACN,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAA4B;QACxC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,wDAAa,oBAAoB,GAAC,CAAA;QAC3D,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,IAAA,YAAI,EAAC,oBAAoB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QAC7D,IAAI;YACF,IAAA,gCAAmB,EAAC;gBAClB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,UAAU,EAAE,IAAI,CAAC,UAAU;aAC5B,CAAC,CAAA;YACF,MAAM,OAAO,GAAG,MAAM,IAAA,iCAAoB,GAAE,CAAA;YAC5C,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;SACrB;QAAC,OAAO,KAAU,EAAE;YACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAA,WAAG,EAAC,oCAAoC,CAAC,CAAC,CAAA;YAC9D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YACpB,IAAA,YAAI,EAAC,CAAC,EAAE,KAAc,CAAC,CAAA;SACxB;IACH,CAAC;CACF;AAzCD,sCAyCC"}
|