@depup/typeorm-extension 3.9.0-depup.0 → 4.0.0-depup.0
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/README.MD +268 -134
- package/README.md +4 -6
- package/bin/cli.mjs +538 -267
- package/bin/cli.mjs.map +1 -0
- package/changes.json +3 -11
- package/dist/index.d.mts +1456 -0
- package/dist/index.mjs +3123 -2972
- package/dist/index.mjs.map +1 -1
- package/package.json +50 -56
- package/bin/cli.cjs +0 -275
- package/dist/cli/commands/database/create.d.ts +0 -27
- package/dist/cli/commands/database/drop.d.ts +0 -23
- package/dist/cli/commands/database/index.d.ts +0 -2
- package/dist/cli/commands/index.d.ts +0 -2
- package/dist/cli/commands/seed/create.d.ts +0 -21
- package/dist/cli/commands/seed/index.d.ts +0 -2
- package/dist/cli/commands/seed/run.d.ts +0 -24
- package/dist/cli/index.d.ts +0 -2
- package/dist/data-source/find/index.d.ts +0 -2
- package/dist/data-source/find/module.d.ts +0 -3
- package/dist/data-source/find/type.d.ts +0 -22
- package/dist/data-source/index.d.ts +0 -4
- package/dist/data-source/options/index.d.ts +0 -4
- package/dist/data-source/options/module.d.ts +0 -8
- package/dist/data-source/options/singleton.d.ts +0 -4
- package/dist/data-source/options/type.d.ts +0 -26
- package/dist/data-source/options/utils/env.d.ts +0 -4
- package/dist/data-source/options/utils/index.d.ts +0 -2
- package/dist/data-source/options/utils/merge.d.ts +0 -2
- package/dist/data-source/singleton.d.ts +0 -5
- package/dist/data-source/type.d.ts +0 -2
- package/dist/database/driver/cockroachdb.d.ts +0 -4
- package/dist/database/driver/index.d.ts +0 -9
- package/dist/database/driver/mongodb.d.ts +0 -6
- package/dist/database/driver/mssql.d.ts +0 -6
- package/dist/database/driver/mysql.d.ts +0 -7
- package/dist/database/driver/oracle.d.ts +0 -6
- package/dist/database/driver/postgres.d.ts +0 -8
- package/dist/database/driver/sqlite.d.ts +0 -3
- package/dist/database/driver/types.d.ts +0 -20
- package/dist/database/driver/utils/build.d.ts +0 -3
- package/dist/database/driver/utils/character-set.d.ts +0 -2
- package/dist/database/driver/utils/charset.d.ts +0 -2
- package/dist/database/driver/utils/create.d.ts +0 -2
- package/dist/database/driver/utils/index.d.ts +0 -4
- package/dist/database/index.d.ts +0 -3
- package/dist/database/methods/check/index.d.ts +0 -2
- package/dist/database/methods/check/module.d.ts +0 -7
- package/dist/database/methods/check/types.d.ts +0 -51
- package/dist/database/methods/create/index.d.ts +0 -1
- package/dist/database/methods/create/module.d.ts +0 -10
- package/dist/database/methods/drop/index.d.ts +0 -1
- package/dist/database/methods/drop/module.d.ts +0 -10
- package/dist/database/methods/index.d.ts +0 -4
- package/dist/database/methods/type.d.ts +0 -43
- package/dist/database/utils/context.d.ts +0 -3
- package/dist/database/utils/index.d.ts +0 -5
- package/dist/database/utils/migration.d.ts +0 -2
- package/dist/database/utils/query.d.ts +0 -3
- package/dist/database/utils/schema.d.ts +0 -3
- package/dist/database/utils/type.d.ts +0 -32
- package/dist/env/constants.d.ts +0 -68
- package/dist/env/index.d.ts +0 -3
- package/dist/env/module.d.ts +0 -4
- package/dist/env/type.d.ts +0 -36
- package/dist/env/utils.d.ts +0 -3
- package/dist/errors/base.d.ts +0 -2
- package/dist/errors/driver.d.ts +0 -6
- package/dist/errors/index.d.ts +0 -3
- package/dist/errors/options.d.ts +0 -7
- package/dist/helpers/entity/error.d.ts +0 -20
- package/dist/helpers/entity/index.d.ts +0 -5
- package/dist/helpers/entity/join-columns.d.ts +0 -16
- package/dist/helpers/entity/metadata.d.ts +0 -10
- package/dist/helpers/entity/property-names.d.ts +0 -11
- package/dist/helpers/entity/uniqueness.d.ts +0 -28
- package/dist/helpers/index.d.ts +0 -1
- package/dist/index.cjs +0 -3258
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -9
- package/dist/query/index.d.ts +0 -4
- package/dist/query/module.d.ts +0 -5
- package/dist/query/parameter/fields/index.d.ts +0 -2
- package/dist/query/parameter/fields/module.d.ts +0 -25
- package/dist/query/parameter/fields/type.d.ts +0 -6
- package/dist/query/parameter/filters/index.d.ts +0 -2
- package/dist/query/parameter/filters/module.d.ts +0 -35
- package/dist/query/parameter/filters/type.d.ts +0 -12
- package/dist/query/parameter/index.d.ts +0 -5
- package/dist/query/parameter/pagination/index.d.ts +0 -2
- package/dist/query/parameter/pagination/module.d.ts +0 -26
- package/dist/query/parameter/pagination/type.d.ts +0 -3
- package/dist/query/parameter/relations/index.d.ts +0 -2
- package/dist/query/parameter/relations/module.d.ts +0 -27
- package/dist/query/parameter/relations/type.d.ts +0 -8
- package/dist/query/parameter/sort/index.d.ts +0 -2
- package/dist/query/parameter/sort/module.d.ts +0 -26
- package/dist/query/parameter/sort/type.d.ts +0 -6
- package/dist/query/type.d.ts +0 -16
- package/dist/query/utils/alias.d.ts +0 -2
- package/dist/query/utils/index.d.ts +0 -3
- package/dist/query/utils/key.d.ts +0 -1
- package/dist/query/utils/option.d.ts +0 -1
- package/dist/seeder/entity.d.ts +0 -42
- package/dist/seeder/executor.d.ts +0 -24
- package/dist/seeder/factory/index.d.ts +0 -4
- package/dist/seeder/factory/manager.d.ts +0 -8
- package/dist/seeder/factory/module.d.ts +0 -17
- package/dist/seeder/factory/type.d.ts +0 -12
- package/dist/seeder/factory/utils.d.ts +0 -7
- package/dist/seeder/index.d.ts +0 -6
- package/dist/seeder/module.d.ts +0 -5
- package/dist/seeder/type.d.ts +0 -44
- package/dist/seeder/utils/file-path.d.ts +0 -7
- package/dist/seeder/utils/index.d.ts +0 -3
- package/dist/seeder/utils/prepare.d.ts +0 -2
- package/dist/seeder/utils/template.d.ts +0 -1
- package/dist/utils/code-transformation/constants.d.ts +0 -4
- package/dist/utils/code-transformation/index.d.ts +0 -2
- package/dist/utils/code-transformation/module.d.ts +0 -3
- package/dist/utils/entity.d.ts +0 -2
- package/dist/utils/file-path.d.ts +0 -9
- package/dist/utils/file-system.d.ts +0 -1
- package/dist/utils/has-property.d.ts +0 -2
- package/dist/utils/index.d.ts +0 -10
- package/dist/utils/object.d.ts +0 -2
- package/dist/utils/promise.d.ts +0 -1
- package/dist/utils/separator.d.ts +0 -3
- package/dist/utils/slash.d.ts +0 -2
- package/dist/utils/tsconfig/index.d.ts +0 -2
- package/dist/utils/tsconfig/module.d.ts +0 -2
- package/dist/utils/tsconfig/type.d.ts +0 -13
package/README.MD
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/assets/logo.svg" alt="typeorm-extension" width="120">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
<h1 align="center">typeorm-extension</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://badge.fury.io/js/typeorm-extension"><img src="https://badge.fury.io/js/typeorm-extension.svg" alt="npm version"></a>
|
|
9
|
+
<a href="https://codecov.io/gh/Tada5hi/typeorm-extension"><img src="https://codecov.io/gh/Tada5hi/typeorm-extension/branch/master/graph/badge.svg?token=4KNSG8L13V" alt="codecov"></a>
|
|
10
|
+
<a href="https://github.com/Tada5hi/typeorm-extension"><img src="https://github.com/Tada5hi/typeorm-extension/workflows/CI/badge.svg" alt="Master Workflow"></a>
|
|
11
|
+
<a href="https://snyk.io/test/github/Tada5hi/typeorm-extension?targetFile=package.json"><img src="https://snyk.io/test/github/Tada5hi/typeorm-extension/badge.svg?targetFile=package.json" alt="Known Vulnerabilities"></a>
|
|
12
|
+
<a href="https://conventionalcommits.org"><img src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white" alt="Conventional Commits"></a>
|
|
13
|
+
</p>
|
|
8
14
|
|
|
9
15
|
This is a library to
|
|
10
16
|
- `create`, `drop` & `seed` the (default-) database 🔥
|
|
11
17
|
- manage one or many data-source instances 👻
|
|
12
|
-
- parse & apply query parameters (extended **JSON:API** specification & fully typed) to:
|
|
13
|
-
- `filter` (related) resources according to one or more criteria,
|
|
14
|
-
- reduce (related) resource `fields`,
|
|
15
|
-
- `include` related resources,
|
|
16
|
-
- `sort` resources according to one or more criteria,
|
|
17
|
-
- limit the number of resources returned in a response by `page` limit & offset
|
|
18
|
-
|
|
19
|
-
> **Warning**
|
|
20
|
-
> This readme includes the documentation for the upcoming version 3.
|
|
21
|
-
> This is the [link](https://github.com/tada5hi/typeorm-extension/tree/v2) for the v2.
|
|
22
18
|
|
|
23
19
|
**Table of Contents**
|
|
24
20
|
- [Installation](#installation)
|
|
@@ -30,6 +26,8 @@ This is a library to
|
|
|
30
26
|
- [Database](#database)
|
|
31
27
|
- [Create](#create)
|
|
32
28
|
- [Drop](#drop)
|
|
29
|
+
- [Schema Drift](#schema-drift)
|
|
30
|
+
- [Repair Migrations](#repair-migrations)
|
|
33
31
|
- [Instances](#instances)
|
|
34
32
|
- [Single](#single)
|
|
35
33
|
- [Multiple](#multiple)
|
|
@@ -46,9 +44,13 @@ This is a library to
|
|
|
46
44
|
## Installation
|
|
47
45
|
|
|
48
46
|
```bash
|
|
49
|
-
npm install typeorm-extension --save
|
|
47
|
+
npm install typeorm-extension typeorm --save
|
|
50
48
|
```
|
|
51
49
|
|
|
50
|
+
`typeorm` is a peer dependency and is required in the range `^1.1.0`. Seeder factories generate their data
|
|
51
|
+
with a library of your choice, so nothing else is required. The examples below use
|
|
52
|
+
[faker](https://fakerjs.dev/guide/) (`npm install @faker-js/faker`).
|
|
53
|
+
|
|
52
54
|
## Documentation
|
|
53
55
|
|
|
54
56
|
To read the docs, visit [https://typeorm-extension.tada5hi.net](https://typeorm-extension.tada5hi.net)
|
|
@@ -57,64 +59,74 @@ To read the docs, visit [https://typeorm-extension.tada5hi.net](https://typeorm-
|
|
|
57
59
|
|
|
58
60
|
### CLI
|
|
59
61
|
|
|
60
|
-
If you use esm, the executable must be changed from `typeorm-extension` to `typeorm-extension-esm`.
|
|
61
62
|
The following commands are available in the terminal:
|
|
62
|
-
- `typeorm-extension db
|
|
63
|
-
- `typeorm-extension db
|
|
64
|
-
- `typeorm-extension
|
|
65
|
-
- `typeorm-extension seed
|
|
63
|
+
- `typeorm-extension db create` to create the database
|
|
64
|
+
- `typeorm-extension db drop` to drop the database
|
|
65
|
+
- `typeorm-extension db drift` to assert that the database schema matches the entity metadata
|
|
66
|
+
- `typeorm-extension seed run` to seed the database
|
|
67
|
+
- `typeorm-extension seed create` to create a new seeder
|
|
68
|
+
|
|
69
|
+
The legacy colon-form (`db:create`, `db:drop`, `seed:run`, `seed:create`) is still accepted for backwards compatibility.
|
|
66
70
|
|
|
67
|
-
If the application has not yet been built
|
|
71
|
+
If the application has not yet been built and you want to run the CLI against TypeScript sources directly, invoke the ESM bundle with a TypeScript-aware Node loader (e.g. `tsx` or Node's `--experimental-strip-types`):
|
|
68
72
|
|
|
69
73
|
```
|
|
70
74
|
"scripts": {
|
|
71
|
-
"db:create":
|
|
72
|
-
"db:drop":
|
|
73
|
-
"
|
|
74
|
-
"seed:
|
|
75
|
+
"db:create": "tsx ./node_modules/typeorm-extension/bin/cli.mjs db create",
|
|
76
|
+
"db:drop": "tsx ./node_modules/typeorm-extension/bin/cli.mjs db drop",
|
|
77
|
+
"db:drift": "tsx ./node_modules/typeorm-extension/bin/cli.mjs db drift",
|
|
78
|
+
"seed:run": "tsx ./node_modules/typeorm-extension/bin/cli.mjs seed run",
|
|
79
|
+
"seed:create": "tsx ./node_modules/typeorm-extension/bin/cli.mjs seed create"
|
|
75
80
|
}
|
|
76
81
|
```
|
|
77
|
-
To test the application in the context of an esm project, the following adjustments must be made:
|
|
78
|
-
- executable `ts-node` to `ts-node-esm`
|
|
79
|
-
- library path `cli.cjs` to `cli.mjs`
|
|
80
82
|
|
|
81
83
|
Read the [Seeding Configuration](#configuration) section to find out how to specify the path,
|
|
82
84
|
for the seeder- & factory-location.
|
|
83
85
|
|
|
84
86
|
#### CLI Options
|
|
85
87
|
|
|
86
|
-
| Option | Commands
|
|
87
|
-
|
|
88
|
-
| `--root` or `-r` | `db
|
|
89
|
-
| `--
|
|
90
|
-
| `--
|
|
91
|
-
| `--
|
|
92
|
-
| `--
|
|
93
|
-
| `--
|
|
88
|
+
| Option | Commands | Default | Description |
|
|
89
|
+
|-------------------------|---------------------------------------------------|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
90
|
+
| `--root` or `-r` | `db create`, `db drift`, `db drop`, `seed create`, `seed run` | `process.cwd()` | Root directory of the project. |
|
|
91
|
+
| `--tsconfig` or `-tc` | `db create`, `db drift`, `db drop`, `seed run` | `tsconfig.json` | Name (or relative path incl. name) of the tsconfig file. |
|
|
92
|
+
| `--dataSource` or `-d` | `db create`, `db drift`, `db drop`, `seed run` | `data-source` | Name (or relative path incl. name) of the data-source file. |
|
|
93
|
+
| `--synchronize` or `-s` | `db create` | `yes` | Synchronize the database schema after database creation. Options: `yes` or `no`. |
|
|
94
|
+
| `--initialDatabase` | `db create` | `undefined` | Specify the initial database to connect to. This option is only relevant for the `postgres` driver, which must always connect to a database. If no database is provided, the database name will be equal to the connection user name. |
|
|
95
|
+
| `--skipWithoutMigrations` | `db drift` | `false` | Report no drift if the data-source has no migrations registered. |
|
|
96
|
+
| `--name` or `-n` | `seed create` (required), `seed run` (optional) | `undefined` | Name (or relative path incl. name) of the seeder. Required on `seed create`; on `seed run` restricts execution to the matching seeder. |
|
|
97
|
+
| `--timestamp` or `-t` | `seed create` | `Date.now()` | Custom timestamp used in the generated seeder filename. |
|
|
98
|
+
| `--javascript` or `-j` | `seed create` | `false` | Generate a seeder file for JavaScript instead of TypeScript. |
|
|
99
|
+
| `--preserveFilePaths` | `db create`, `db drift`, `db drop`, `seed run` | `false` | This option indicates if file paths should be preserved and treated as if the just-in-time compilation environment is detected. |
|
|
100
|
+
| `--log-level` | `db create`, `db drift`, `db drop`, `seed create`, `seed run` | `info` | Logger verbosity. One of `silent`, `info`, `debug`. |
|
|
94
101
|
|
|
95
102
|
#### CLI Examples
|
|
96
103
|
**`Database Create`**
|
|
97
104
|
```shell
|
|
98
|
-
|
|
105
|
+
tsx ./node_modules/typeorm-extension/bin/cli.mjs db create -d src/data-source.ts
|
|
99
106
|
```
|
|
100
107
|
**`Database Drop`**
|
|
101
108
|
```shell
|
|
102
|
-
|
|
109
|
+
tsx ./node_modules/typeorm-extension/bin/cli.mjs db drop -d src/data-source.ts
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**`Database Drift`**
|
|
113
|
+
```shell
|
|
114
|
+
tsx ./node_modules/typeorm-extension/bin/cli.mjs db drift -d src/data-source.ts
|
|
103
115
|
```
|
|
104
116
|
|
|
105
117
|
**`Seed Run`**
|
|
106
118
|
```shell
|
|
107
|
-
|
|
119
|
+
tsx ./node_modules/typeorm-extension/bin/cli.mjs seed run -d src/data-source.ts
|
|
108
120
|
```
|
|
109
121
|
|
|
110
122
|
**`Seed Run Explicit`**
|
|
111
123
|
```shell
|
|
112
|
-
|
|
124
|
+
tsx ./node_modules/typeorm-extension/bin/cli.mjs seed run -d src/data-source.ts --name src/database/seeds/user.ts
|
|
113
125
|
```
|
|
114
126
|
|
|
115
127
|
**`Seed Create`**
|
|
116
128
|
```shell
|
|
117
|
-
|
|
129
|
+
tsx ./node_modules/typeorm-extension/bin/cli.mjs seed create --name src/database/seeds/user.ts
|
|
118
130
|
```
|
|
119
131
|
|
|
120
132
|
### Database
|
|
@@ -129,7 +141,7 @@ import { createDatabase } from 'typeorm-extension';
|
|
|
129
141
|
|
|
130
142
|
(async () => {
|
|
131
143
|
const options: DataSourceOptions = {
|
|
132
|
-
type: 'better-
|
|
144
|
+
type: 'better-sqlite3',
|
|
133
145
|
database: 'db.sqlite'
|
|
134
146
|
};
|
|
135
147
|
|
|
@@ -201,7 +213,7 @@ import { dropDatabase } from 'typeorm-extension';
|
|
|
201
213
|
|
|
202
214
|
(async () => {
|
|
203
215
|
const options: DataSourceOptions = {
|
|
204
|
-
type: 'better-
|
|
216
|
+
type: 'better-sqlite3',
|
|
205
217
|
database: 'db.sqlite'
|
|
206
218
|
};
|
|
207
219
|
|
|
@@ -252,6 +264,78 @@ To get a better overview and understanding of the
|
|
|
252
264
|
[dropDatabase](https://typeorm-extension.tada5hi.net/guide/database-api-reference.html#dropDatabase)
|
|
253
265
|
function, check out the documentation.
|
|
254
266
|
|
|
267
|
+
#### Schema Drift
|
|
268
|
+
|
|
269
|
+
Compare the database schema against the entity metadata and get back the statements which would reconcile them.
|
|
270
|
+
|
|
271
|
+
Run it right after the migrations to close the blind spot of a project which builds its schema with migrations in
|
|
272
|
+
production but with `synchronize()` in tests: the two descriptions can drift apart silently, and it only surfaces
|
|
273
|
+
when the next generated migration reconciles them.
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
import { assertSchemaMatchesMetadata, getSchemaDrift } from 'typeorm-extension';
|
|
277
|
+
|
|
278
|
+
(async () => {
|
|
279
|
+
const drift = await getSchemaDrift(dataSource);
|
|
280
|
+
if (drift.exists) {
|
|
281
|
+
console.log(drift.up.map((statement) => statement.query));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// ... or let it throw a SchemaDriftError listing the statements
|
|
285
|
+
await assertSchemaMatchesMetadata(dataSource);
|
|
286
|
+
})();
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
The same check is available on the command line as `typeorm-extension db drift`, which exits with code `1` on drift.
|
|
290
|
+
|
|
291
|
+
#### Repair Migrations
|
|
292
|
+
|
|
293
|
+
Renaming a constraint is dialect-asymmetric and easy to get wrong. These helpers read the current state back from the
|
|
294
|
+
database, apply the change only if it is still pending, and return whether they did something. That way a repair migration
|
|
295
|
+
stays resumable (mysql commits DDL regardless of the surrounding transaction) and safe to run against a database which
|
|
296
|
+
never had the drift.
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
300
|
+
import { changeColumnType, renameForeignKey, renameIndex } from 'typeorm-extension';
|
|
301
|
+
|
|
302
|
+
export class RepairSchema1700000000000 implements MigrationInterface {
|
|
303
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
304
|
+
await renameIndex(queryRunner, {
|
|
305
|
+
table: 'auth_events',
|
|
306
|
+
from: 'IDX_auth_events_actor_name',
|
|
307
|
+
to: 'IDX_9f6d1a2b3c4d5e6f70819293',
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
await renameForeignKey(queryRunner, {
|
|
311
|
+
table: 'auth_permissions',
|
|
312
|
+
from: 'FK_auth_permissions_client',
|
|
313
|
+
to: 'FK_1a2b3c4d5e6f708192a3b4c5',
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
await changeColumnType(queryRunner, {
|
|
317
|
+
table: 'auth_permissions',
|
|
318
|
+
column: 'client_id',
|
|
319
|
+
from: { type: 'varchar', length: 36 },
|
|
320
|
+
to: { type: 'varchar', length: 255 },
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
`renameIndex` and `renameForeignKey` support `postgres`, `cockroachdb`, `mysql` and `mariadb` and throw a `DriverError`
|
|
327
|
+
on any other driver. `changeColumnType` and `withForeignKeyChecksDisabled` work everywhere: `changeColumnType` alters
|
|
328
|
+
the column in place (keeping its values) on every relational driver but sqlite, which typeorm handles safely by
|
|
329
|
+
recreating the table.
|
|
330
|
+
|
|
331
|
+
Each helper returns `false` when the change is already applied, which keeps a repair migration resumable. If the
|
|
332
|
+
database is in **neither** the expected nor the desired state it raises a `SchemaAlterationError` instead of returning
|
|
333
|
+
quietly, since a repair migration which repairs nothing would otherwise pass for a successful one. Pass
|
|
334
|
+
`strict: false` per call to opt out.
|
|
335
|
+
|
|
336
|
+
To get a better overview and understanding of these functions, check out the
|
|
337
|
+
[documentation](https://typeorm-extension.tada5hi.net/guide/database-api-reference.html).
|
|
338
|
+
|
|
255
339
|
### Instances
|
|
256
340
|
|
|
257
341
|
#### Single
|
|
@@ -311,7 +395,7 @@ Seeding the database is fairly easy and can be achieved by following the steps b
|
|
|
311
395
|
|
|
312
396
|
Seeder paths are configured as **glob patterns**, making it easy
|
|
313
397
|
to match all the factory/seeder files in your project without configuration effort:
|
|
314
|
-
- use `*` to match anything
|
|
398
|
+
- use `*` to match anything except slashes and hidden files
|
|
315
399
|
- use `**` to match zero or more directories
|
|
316
400
|
- use comma separate values between `{}` to match against a list of options
|
|
317
401
|
|
|
@@ -330,8 +414,14 @@ The following values are assumed by default:
|
|
|
330
414
|
|
|
331
415
|
Note: When seeder paths are configured as **glob patterns**, the paths are resolved and sorted in alphabetical order using filenames. This helps to ensure that the seeders are executed in the correct order.
|
|
332
416
|
|
|
417
|
+
Seeder options can be provided per invocation (`runSeeder(s)` options parameter), on the extended
|
|
418
|
+
data-source options, or via environment variables. Explicit input wins over the data-source options,
|
|
419
|
+
which win over the environment; built-in defaults apply last.
|
|
420
|
+
|
|
333
421
|
It is possible to define that a seeder is only executed once.
|
|
334
|
-
This can either be set globally using the
|
|
422
|
+
This can either be set globally using the `seedTracking` option or locally using the `track` property of a seeder class.
|
|
423
|
+
Executed seeds are recorded in a `seeds` table (a collection for MongoDB);
|
|
424
|
+
the table name can be changed with the `seedTableName` option.
|
|
335
425
|
|
|
336
426
|
`data-source.ts`
|
|
337
427
|
|
|
@@ -340,7 +430,7 @@ import { DataSource, DataSourceOptions } from 'typeorm';
|
|
|
340
430
|
import { SeederOptions } from 'typeorm-extension';
|
|
341
431
|
|
|
342
432
|
const options: DataSourceOptions & SeederOptions = {
|
|
343
|
-
type: 'better-
|
|
433
|
+
type: 'better-sqlite3',
|
|
344
434
|
database: 'db.sqlite',
|
|
345
435
|
|
|
346
436
|
seeds: ['src/database/seeds/**/*{.ts,.js}'],
|
|
@@ -359,7 +449,7 @@ import { runSeeders, SeederOptions } from 'typeorm-extension';
|
|
|
359
449
|
|
|
360
450
|
(async () => {
|
|
361
451
|
const options: DataSourceOptions = {
|
|
362
|
-
type: 'better-
|
|
452
|
+
type: 'better-sqlite3',
|
|
363
453
|
database: 'db.sqlite',
|
|
364
454
|
};
|
|
365
455
|
|
|
@@ -404,27 +494,32 @@ export class User {
|
|
|
404
494
|
To create entities with random data, create a factory for each desired entity.
|
|
405
495
|
The definition of a factory is **optional**.
|
|
406
496
|
|
|
407
|
-
The factory callback
|
|
408
|
-
|
|
497
|
+
The factory callback returns the entity to persist. Pick any data generator you like and import it in the
|
|
498
|
+
factory file. The examples use [faker](https://fakerjs.dev/guide/) (`npm install @faker-js/faker`).
|
|
409
499
|
|
|
410
500
|
**`user.factory.ts`**
|
|
411
501
|
```typescript
|
|
502
|
+
import { faker } from '@faker-js/faker';
|
|
412
503
|
import { setSeederFactory } from 'typeorm-extension';
|
|
413
504
|
import { User } from './user';
|
|
414
505
|
|
|
415
|
-
export default setSeederFactory(User, (
|
|
506
|
+
export default setSeederFactory(User, () => {
|
|
416
507
|
const user = new User();
|
|
417
|
-
user.firstName = faker.
|
|
418
|
-
user.lastName = faker.
|
|
419
|
-
user.email = faker.internet.email(user.firstName, user.lastName);
|
|
508
|
+
user.firstName = faker.person.firstName('male');
|
|
509
|
+
user.lastName = faker.person.lastName('male');
|
|
510
|
+
user.email = faker.internet.email({ firstName: user.firstName, lastName: user.lastName });
|
|
420
511
|
|
|
421
512
|
return user;
|
|
422
513
|
})
|
|
423
514
|
```
|
|
424
515
|
|
|
516
|
+
Since the generator instance belongs to the factory file, locales and reproducible runs are configured
|
|
517
|
+
through the generator's own API, for example `import { fakerDE as faker } from '@faker-js/faker'`
|
|
518
|
+
or `faker.seed(1234)`.
|
|
519
|
+
|
|
425
520
|
#### Seed
|
|
426
|
-
And last but not least, create a seeder. The seeder can be called by the cli command `seed` or in the codebase
|
|
427
|
-
by using the function `runSeeder`.
|
|
521
|
+
And last but not least, create a seeder. The seeder can be called by the cli command `seed:run` or in the codebase
|
|
522
|
+
by using the function `runSeeder` / `runSeeders`.
|
|
428
523
|
A seeder class only requires one method, called `run` and provides the arguments `dataSource` & `factoryManager`.
|
|
429
524
|
|
|
430
525
|
**`user.seeder.ts`**
|
|
@@ -469,6 +564,10 @@ export default class UserSeeder implements Seeder {
|
|
|
469
564
|
}
|
|
470
565
|
```
|
|
471
566
|
|
|
567
|
+
Factories obtained through the `factoryManager` argument are bound to the data source of the
|
|
568
|
+
current seeder run, so `save()` and `saveMany()` persist there. A factory used outside a seeder
|
|
569
|
+
run falls back to the data source registered for the `default` alias.
|
|
570
|
+
|
|
472
571
|
#### Execute
|
|
473
572
|
|
|
474
573
|
Populate the database from the code base:
|
|
@@ -476,11 +575,11 @@ Populate the database from the code base:
|
|
|
476
575
|
```typescript
|
|
477
576
|
import { DataSource, DataSourceOptions } from 'typeorm';
|
|
478
577
|
import { runSeeders, SeederOptions } from 'typeorm-extension';
|
|
479
|
-
import { User } from 'user';
|
|
578
|
+
import { User } from './user';
|
|
480
579
|
|
|
481
580
|
(async () => {
|
|
482
581
|
const options: DataSourceOptions & SeederOptions = {
|
|
483
|
-
type: 'better-
|
|
582
|
+
type: 'better-sqlite3',
|
|
484
583
|
database: 'db.sqlite',
|
|
485
584
|
entities: [User],
|
|
486
585
|
|
|
@@ -500,13 +599,13 @@ Populate the database by explicit definitions from the codebase.
|
|
|
500
599
|
```typescript
|
|
501
600
|
import { DataSource, DataSourceOptions } from 'typeorm';
|
|
502
601
|
import { runSeeders, SeederOptions } from 'typeorm-extension';
|
|
503
|
-
import { User } from 'user';
|
|
504
|
-
import UserSeeder from 'user.seeder';
|
|
505
|
-
import UserFactory from 'user.factory';
|
|
602
|
+
import { User } from './user';
|
|
603
|
+
import UserSeeder from './user.seeder';
|
|
604
|
+
import UserFactory from './user.factory';
|
|
506
605
|
|
|
507
606
|
(async () => {
|
|
508
607
|
const options: DataSourceOptions & SeederOptions = {
|
|
509
|
-
type: 'better-
|
|
608
|
+
type: 'better-sqlite3',
|
|
510
609
|
database: 'db.sqlite',
|
|
511
610
|
entities: [User],
|
|
512
611
|
|
|
@@ -522,20 +621,31 @@ import UserFactory from 'user.factory';
|
|
|
522
621
|
```
|
|
523
622
|
|
|
524
623
|
### Query
|
|
525
|
-
The query submodule enables query parameter (fields, filter, ...) values to be build, parsed & validated.
|
|
526
|
-
Therefore, the [rapiq](https://www.npmjs.com/package/rapiq) library is used under the hood.
|
|
527
624
|
|
|
528
|
-
The query
|
|
529
|
-
|
|
625
|
+
The query submodule (`applyQuery`, `applyFilters`, ...) was removed in v4.
|
|
626
|
+
Its successor is [@rapiq/adapter-typeorm](https://github.com/tada5hi/rapiq/tree/master/packages/adapter-typeorm), the dedicated
|
|
627
|
+
TypeORM adapter of the [rapiq](https://github.com/tada5hi/rapiq) v2 monorepo. The query pipeline is now fully
|
|
628
|
+
**self-contained** in rapiq: decoding the raw URL query string (`@rapiq/codec-url`), typed schema
|
|
629
|
+
validation (`@rapiq/core`) and application onto the `SelectQueryBuilder` (`@rapiq/adapter-typeorm`).
|
|
630
|
+
`typeorm-extension` is no longer involved. On top of the full `applyQuery` use case it adds typed
|
|
631
|
+
schemas, nested `and` / `or` filter compounds, the `contains` operator family and collision-free join aliases.
|
|
632
|
+
|
|
633
|
+
The [monorepo](https://github.com/tada5hi/rapiq) hosts more than the TypeORM adapter: adapters for
|
|
634
|
+
drizzle, prisma, raw SQL and in-memory collections, plus pluggable input parsers (e.g. a MongoDB-style
|
|
635
|
+
filter parser and an expression parser). If rapiq is useful to you, consider giving the repo a ⭐ on GitHub.
|
|
636
|
+
|
|
637
|
+
```bash
|
|
638
|
+
npm install @rapiq/core @rapiq/codec-url @rapiq/adapter-typeorm --save
|
|
639
|
+
```
|
|
530
640
|
|
|
531
|
-
For
|
|
532
|
-
two simple entities with a relation between them are declared to demonstrate the usage of the query utils:
|
|
641
|
+
For demonstration purposes, two simple entities with a relation between them are used:
|
|
533
642
|
|
|
534
643
|
```typescript
|
|
535
644
|
import {
|
|
536
645
|
Entity,
|
|
537
646
|
PrimaryGeneratedColumn,
|
|
538
647
|
Column,
|
|
648
|
+
Index,
|
|
539
649
|
OneToOne,
|
|
540
650
|
JoinColumn
|
|
541
651
|
} from 'typeorm';
|
|
@@ -573,94 +683,118 @@ export class Profile {
|
|
|
573
683
|
}
|
|
574
684
|
```
|
|
575
685
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
but there is also a guide available for [express](https://typeorm-extension.tada5hi.net/guide/query.html).
|
|
686
|
+
Instead of passing loose options per call (as `applyQuery` did), the allowed query features are declared
|
|
687
|
+
once as a typed **schema** and registered alongside a codec:
|
|
579
688
|
|
|
580
689
|
```typescript
|
|
581
|
-
import {
|
|
582
|
-
import
|
|
583
|
-
import {
|
|
584
|
-
|
|
690
|
+
import { SchemaRegistry, defineSchema } from '@rapiq/core';
|
|
691
|
+
import { createURLCodec } from '@rapiq/codec-url';
|
|
692
|
+
import { Profile, User } from './entities';
|
|
693
|
+
|
|
694
|
+
const registry = new SchemaRegistry();
|
|
695
|
+
|
|
696
|
+
registry.add(defineSchema<Profile>({
|
|
697
|
+
name: 'profile',
|
|
698
|
+
fields: { allowed: ['id', 'avatar'] },
|
|
699
|
+
filters: { allowed: ['id'] },
|
|
700
|
+
}));
|
|
701
|
+
|
|
702
|
+
registry.add(defineSchema<User>({
|
|
703
|
+
name: 'user',
|
|
704
|
+
fields: {
|
|
705
|
+
allowed: ['id', 'name', 'email'],
|
|
706
|
+
default: ['id', 'name'],
|
|
707
|
+
},
|
|
708
|
+
filters: { allowed: ['id', 'name', 'profile.id'] },
|
|
709
|
+
relations: { allowed: ['profile'] },
|
|
710
|
+
sort: { allowed: ['id', 'name'], default: { id: 'DESC' } },
|
|
711
|
+
pagination: { maxLimit: 20 },
|
|
712
|
+
schemaMapping: { profile: 'profile' },
|
|
713
|
+
}));
|
|
714
|
+
|
|
715
|
+
export const codec = createURLCodec(registry);
|
|
716
|
+
```
|
|
585
717
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
718
|
+
The codec owns both directions. A client builds the query string with `encode`, from a typed query
|
|
719
|
+
instead of string concatenation (no registry needed on the client):
|
|
720
|
+
|
|
721
|
+
```typescript
|
|
722
|
+
import { defineQuery } from '@rapiq/core';
|
|
723
|
+
import { createURLCodec } from '@rapiq/codec-url';
|
|
724
|
+
import type { User } from './entities';
|
|
725
|
+
|
|
726
|
+
const codec = createURLCodec();
|
|
727
|
+
|
|
728
|
+
const query = defineQuery<User>({
|
|
729
|
+
fields: ['id', 'name'],
|
|
730
|
+
filters: { id: 1 },
|
|
731
|
+
relations: ['profile'],
|
|
732
|
+
pagination: { limit: 10, offset: 0 },
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
const response = await fetch(`/users?${codec.encode(query)}`);
|
|
736
|
+
```
|
|
590
737
|
|
|
591
|
-
|
|
592
|
-
|
|
738
|
+
The request handler then decodes the raw query parameters against the schema and lets the adapter apply
|
|
739
|
+
the result onto the query builder. It is shown here with [express](https://www.npmjs.com/package/express),
|
|
740
|
+
but the flow is framework-agnostic:
|
|
741
|
+
|
|
742
|
+
```typescript
|
|
743
|
+
import { ParseError } from '@rapiq/core';
|
|
744
|
+
import { TypeormAdapter } from '@rapiq/adapter-typeorm';
|
|
745
|
+
import { useDataSource } from 'typeorm-extension';
|
|
746
|
+
import { codec } from './codec';
|
|
747
|
+
import { User } from './entities';
|
|
593
748
|
|
|
594
749
|
/**
|
|
595
750
|
* Get many users.
|
|
596
751
|
*
|
|
597
752
|
* Request example
|
|
598
753
|
* - url: /users?page[limit]=10&page[offset]=0&include=profile&filter[id]=1&fields[user]=id,name
|
|
599
|
-
*
|
|
600
|
-
* Return Example:
|
|
601
|
-
* {
|
|
602
|
-
* data: [
|
|
603
|
-
* {id: 1, name: 'tada5hi', profile: {avatar: 'avatar.jpg', cover: 'cover.jpg'}}
|
|
604
|
-
* ],
|
|
605
|
-
* meta: {
|
|
606
|
-
* total: 1,
|
|
607
|
-
* limit: 20,
|
|
608
|
-
* offset: 0
|
|
609
|
-
* }
|
|
610
|
-
* }
|
|
611
|
-
* @param req
|
|
612
|
-
* @param res
|
|
613
754
|
*/
|
|
614
|
-
|
|
755
|
+
app.get('/users', async (req, res) => {
|
|
756
|
+
let query;
|
|
757
|
+
try {
|
|
758
|
+
query = codec.decode(req.query, { schema: 'user' });
|
|
759
|
+
} catch (e) {
|
|
760
|
+
// e.g. a malformed filter expression
|
|
761
|
+
if (e instanceof ParseError) {
|
|
762
|
+
return res.status(400).json({ error: e.message });
|
|
763
|
+
}
|
|
764
|
+
throw e;
|
|
765
|
+
}
|
|
766
|
+
if (!query) {
|
|
767
|
+
return res.status(400).json({ error: 'Invalid query input.' });
|
|
768
|
+
}
|
|
769
|
+
|
|
615
770
|
const dataSource = await useDataSource();
|
|
616
|
-
const
|
|
617
|
-
const query = repository.createQueryBuilder('user');
|
|
618
|
-
|
|
619
|
-
// -----------------------------------------------------
|
|
620
|
-
|
|
621
|
-
const { pagination } = applyQuery(query, useQuery(req), {
|
|
622
|
-
defaultAlias: 'user',
|
|
623
|
-
fields: {
|
|
624
|
-
// porfile fields can only be included,
|
|
625
|
-
// if the relation 'profile' is included.
|
|
626
|
-
allowed: ['id', 'name', 'profile.id', 'profile.avatar'],
|
|
627
|
-
},
|
|
628
|
-
filters: {
|
|
629
|
-
// porfile.id can only be used as a filter,
|
|
630
|
-
// if the relation 'profile' is included.
|
|
631
|
-
allowed: ['id', 'name', 'profile.id'],
|
|
632
|
-
},
|
|
633
|
-
pagination: {
|
|
634
|
-
// only allow to select 20 items at maximum.
|
|
635
|
-
maxLimit: 20
|
|
636
|
-
},
|
|
637
|
-
relations: {
|
|
638
|
-
allowed: ['profile']
|
|
639
|
-
},
|
|
640
|
-
sort: {
|
|
641
|
-
// profile.id can only be used as sorting key,
|
|
642
|
-
// if the relation 'profile' is included.
|
|
643
|
-
allowed: ['id', 'name', 'profile.id']
|
|
644
|
-
},
|
|
645
|
-
});
|
|
771
|
+
const queryBuilder = dataSource.getRepository(User).createQueryBuilder('user');
|
|
646
772
|
|
|
647
|
-
|
|
773
|
+
const { pagination } = new TypeormAdapter({ queryBuilder }).execute(query);
|
|
648
774
|
|
|
649
|
-
const [entities, total] = await
|
|
775
|
+
const [entities, total] = await queryBuilder.getManyAndCount();
|
|
650
776
|
|
|
651
|
-
|
|
777
|
+
res.json({
|
|
652
778
|
data: entities,
|
|
653
779
|
meta: {
|
|
654
780
|
total,
|
|
655
781
|
...pagination
|
|
656
782
|
}
|
|
657
|
-
};
|
|
783
|
+
});
|
|
658
784
|
});
|
|
659
|
-
|
|
660
|
-
const server = createServer(createNodeDispatcher(router));
|
|
661
|
-
server.listen(80);
|
|
662
785
|
```
|
|
663
786
|
|
|
787
|
+
A production-shaped version with strict schema-violation handling (`throwOnFailure`) is in the
|
|
788
|
+
[Express + TypeORM recipe](https://rapiq.tada5hi.net/guide/recipes/express-typeorm); the client side is covered by the
|
|
789
|
+
[frontend recipe](https://rapiq.tada5hi.net/guide/recipes/frontend).
|
|
790
|
+
|
|
791
|
+
To move over from the removed submodule, follow the migration guide:
|
|
792
|
+
[https://rapiq.tada5hi.net/guide/migration-typeorm-extension](https://rapiq.tada5hi.net/guide/migration-typeorm-extension)
|
|
793
|
+
|
|
794
|
+
> **Note**: This section is kept during the v4 release cycle to route former `applyQuery` users to the
|
|
795
|
+
> successor. With the next major release (v5) it will be removed from the README and docs; the
|
|
796
|
+
> [rapiq documentation](https://rapiq.tada5hi.net) is the canonical reference.
|
|
797
|
+
|
|
664
798
|
## Contributing
|
|
665
799
|
|
|
666
800
|
Before starting to work on a pull request, it is important to review the guidelines for
|
package/README.md
CHANGED
|
@@ -13,19 +13,17 @@ npm install @depup/typeorm-extension
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [typeorm-extension](https://www.npmjs.com/package/typeorm-extension) @
|
|
17
|
-
| Processed | 2026-
|
|
16
|
+
| Original | [typeorm-extension](https://www.npmjs.com/package/typeorm-extension) @ 4.0.0 |
|
|
17
|
+
| Processed | 2026-08-16 |
|
|
18
18
|
| Smoke test | failed |
|
|
19
|
-
| Deps updated |
|
|
19
|
+
| Deps updated | 2 |
|
|
20
20
|
|
|
21
21
|
## Dependency Changes
|
|
22
22
|
|
|
23
23
|
| Dependency | From | To |
|
|
24
24
|
|------------|------|-----|
|
|
25
|
-
| consola | ^3.4.0 | ^3.4.2 |
|
|
26
25
|
| pascal-case | ^3.1.2 | ^4.0.0 |
|
|
27
|
-
|
|
|
28
|
-
| smob | ^1.5.0 | ^1.6.1 |
|
|
26
|
+
| smob | ^1.5.0 | ^1.6.2 |
|
|
29
27
|
|
|
30
28
|
---
|
|
31
29
|
|