@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.
Files changed (132) hide show
  1. package/README.MD +268 -134
  2. package/README.md +4 -6
  3. package/bin/cli.mjs +538 -267
  4. package/bin/cli.mjs.map +1 -0
  5. package/changes.json +3 -11
  6. package/dist/index.d.mts +1456 -0
  7. package/dist/index.mjs +3123 -2972
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +50 -56
  10. package/bin/cli.cjs +0 -275
  11. package/dist/cli/commands/database/create.d.ts +0 -27
  12. package/dist/cli/commands/database/drop.d.ts +0 -23
  13. package/dist/cli/commands/database/index.d.ts +0 -2
  14. package/dist/cli/commands/index.d.ts +0 -2
  15. package/dist/cli/commands/seed/create.d.ts +0 -21
  16. package/dist/cli/commands/seed/index.d.ts +0 -2
  17. package/dist/cli/commands/seed/run.d.ts +0 -24
  18. package/dist/cli/index.d.ts +0 -2
  19. package/dist/data-source/find/index.d.ts +0 -2
  20. package/dist/data-source/find/module.d.ts +0 -3
  21. package/dist/data-source/find/type.d.ts +0 -22
  22. package/dist/data-source/index.d.ts +0 -4
  23. package/dist/data-source/options/index.d.ts +0 -4
  24. package/dist/data-source/options/module.d.ts +0 -8
  25. package/dist/data-source/options/singleton.d.ts +0 -4
  26. package/dist/data-source/options/type.d.ts +0 -26
  27. package/dist/data-source/options/utils/env.d.ts +0 -4
  28. package/dist/data-source/options/utils/index.d.ts +0 -2
  29. package/dist/data-source/options/utils/merge.d.ts +0 -2
  30. package/dist/data-source/singleton.d.ts +0 -5
  31. package/dist/data-source/type.d.ts +0 -2
  32. package/dist/database/driver/cockroachdb.d.ts +0 -4
  33. package/dist/database/driver/index.d.ts +0 -9
  34. package/dist/database/driver/mongodb.d.ts +0 -6
  35. package/dist/database/driver/mssql.d.ts +0 -6
  36. package/dist/database/driver/mysql.d.ts +0 -7
  37. package/dist/database/driver/oracle.d.ts +0 -6
  38. package/dist/database/driver/postgres.d.ts +0 -8
  39. package/dist/database/driver/sqlite.d.ts +0 -3
  40. package/dist/database/driver/types.d.ts +0 -20
  41. package/dist/database/driver/utils/build.d.ts +0 -3
  42. package/dist/database/driver/utils/character-set.d.ts +0 -2
  43. package/dist/database/driver/utils/charset.d.ts +0 -2
  44. package/dist/database/driver/utils/create.d.ts +0 -2
  45. package/dist/database/driver/utils/index.d.ts +0 -4
  46. package/dist/database/index.d.ts +0 -3
  47. package/dist/database/methods/check/index.d.ts +0 -2
  48. package/dist/database/methods/check/module.d.ts +0 -7
  49. package/dist/database/methods/check/types.d.ts +0 -51
  50. package/dist/database/methods/create/index.d.ts +0 -1
  51. package/dist/database/methods/create/module.d.ts +0 -10
  52. package/dist/database/methods/drop/index.d.ts +0 -1
  53. package/dist/database/methods/drop/module.d.ts +0 -10
  54. package/dist/database/methods/index.d.ts +0 -4
  55. package/dist/database/methods/type.d.ts +0 -43
  56. package/dist/database/utils/context.d.ts +0 -3
  57. package/dist/database/utils/index.d.ts +0 -5
  58. package/dist/database/utils/migration.d.ts +0 -2
  59. package/dist/database/utils/query.d.ts +0 -3
  60. package/dist/database/utils/schema.d.ts +0 -3
  61. package/dist/database/utils/type.d.ts +0 -32
  62. package/dist/env/constants.d.ts +0 -68
  63. package/dist/env/index.d.ts +0 -3
  64. package/dist/env/module.d.ts +0 -4
  65. package/dist/env/type.d.ts +0 -36
  66. package/dist/env/utils.d.ts +0 -3
  67. package/dist/errors/base.d.ts +0 -2
  68. package/dist/errors/driver.d.ts +0 -6
  69. package/dist/errors/index.d.ts +0 -3
  70. package/dist/errors/options.d.ts +0 -7
  71. package/dist/helpers/entity/error.d.ts +0 -20
  72. package/dist/helpers/entity/index.d.ts +0 -5
  73. package/dist/helpers/entity/join-columns.d.ts +0 -16
  74. package/dist/helpers/entity/metadata.d.ts +0 -10
  75. package/dist/helpers/entity/property-names.d.ts +0 -11
  76. package/dist/helpers/entity/uniqueness.d.ts +0 -28
  77. package/dist/helpers/index.d.ts +0 -1
  78. package/dist/index.cjs +0 -3258
  79. package/dist/index.cjs.map +0 -1
  80. package/dist/index.d.ts +0 -9
  81. package/dist/query/index.d.ts +0 -4
  82. package/dist/query/module.d.ts +0 -5
  83. package/dist/query/parameter/fields/index.d.ts +0 -2
  84. package/dist/query/parameter/fields/module.d.ts +0 -25
  85. package/dist/query/parameter/fields/type.d.ts +0 -6
  86. package/dist/query/parameter/filters/index.d.ts +0 -2
  87. package/dist/query/parameter/filters/module.d.ts +0 -35
  88. package/dist/query/parameter/filters/type.d.ts +0 -12
  89. package/dist/query/parameter/index.d.ts +0 -5
  90. package/dist/query/parameter/pagination/index.d.ts +0 -2
  91. package/dist/query/parameter/pagination/module.d.ts +0 -26
  92. package/dist/query/parameter/pagination/type.d.ts +0 -3
  93. package/dist/query/parameter/relations/index.d.ts +0 -2
  94. package/dist/query/parameter/relations/module.d.ts +0 -27
  95. package/dist/query/parameter/relations/type.d.ts +0 -8
  96. package/dist/query/parameter/sort/index.d.ts +0 -2
  97. package/dist/query/parameter/sort/module.d.ts +0 -26
  98. package/dist/query/parameter/sort/type.d.ts +0 -6
  99. package/dist/query/type.d.ts +0 -16
  100. package/dist/query/utils/alias.d.ts +0 -2
  101. package/dist/query/utils/index.d.ts +0 -3
  102. package/dist/query/utils/key.d.ts +0 -1
  103. package/dist/query/utils/option.d.ts +0 -1
  104. package/dist/seeder/entity.d.ts +0 -42
  105. package/dist/seeder/executor.d.ts +0 -24
  106. package/dist/seeder/factory/index.d.ts +0 -4
  107. package/dist/seeder/factory/manager.d.ts +0 -8
  108. package/dist/seeder/factory/module.d.ts +0 -17
  109. package/dist/seeder/factory/type.d.ts +0 -12
  110. package/dist/seeder/factory/utils.d.ts +0 -7
  111. package/dist/seeder/index.d.ts +0 -6
  112. package/dist/seeder/module.d.ts +0 -5
  113. package/dist/seeder/type.d.ts +0 -44
  114. package/dist/seeder/utils/file-path.d.ts +0 -7
  115. package/dist/seeder/utils/index.d.ts +0 -3
  116. package/dist/seeder/utils/prepare.d.ts +0 -2
  117. package/dist/seeder/utils/template.d.ts +0 -1
  118. package/dist/utils/code-transformation/constants.d.ts +0 -4
  119. package/dist/utils/code-transformation/index.d.ts +0 -2
  120. package/dist/utils/code-transformation/module.d.ts +0 -3
  121. package/dist/utils/entity.d.ts +0 -2
  122. package/dist/utils/file-path.d.ts +0 -9
  123. package/dist/utils/file-system.d.ts +0 -1
  124. package/dist/utils/has-property.d.ts +0 -2
  125. package/dist/utils/index.d.ts +0 -10
  126. package/dist/utils/object.d.ts +0 -2
  127. package/dist/utils/promise.d.ts +0 -1
  128. package/dist/utils/separator.d.ts +0 -3
  129. package/dist/utils/slash.d.ts +0 -2
  130. package/dist/utils/tsconfig/index.d.ts +0 -2
  131. package/dist/utils/tsconfig/module.d.ts +0 -2
  132. package/dist/utils/tsconfig/type.d.ts +0 -13
package/README.MD CHANGED
@@ -1,24 +1,20 @@
1
- # Typeorm Extension 🚀
1
+ <p align="center">
2
+ <img src=".github/assets/logo.svg" alt="typeorm-extension" width="120">
3
+ </p>
2
4
 
3
- [![npm version](https://badge.fury.io/js/typeorm-extension.svg)](https://badge.fury.io/js/typeorm-extension)
4
- [![codecov](https://codecov.io/gh/Tada5hi/typeorm-extension/branch/master/graph/badge.svg?token=4KNSG8L13V)](https://codecov.io/gh/Tada5hi/typeorm-extension)
5
- [![Master Workflow](https://github.com/Tada5hi/typeorm-extension/workflows/CI/badge.svg)](https://github.com/Tada5hi/typeorm-extension)
6
- [![Known Vulnerabilities](https://snyk.io/test/github/Tada5hi/typeorm-extension/badge.svg?targetFile=package.json)](https://snyk.io/test/github/Tada5hi/typeorm-extension?targetFile=package.json)
7
- [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white)](https://conventionalcommits.org)
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:create` to create the database
63
- - `typeorm-extension db:drop` to drop the database
64
- - `typeorm-extension seed:run` seed the database
65
- - `typeorm-extension seed:create` to create a new seeder
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 or is to be tested with ts-node, the commands can be adapted as follows:
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": "ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:create",
72
- "db:drop": "ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:drop",
73
- "seed:run": "ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed:run",
74
- "seed:create": "ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed:create"
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 | Default | Description |
87
- |-------------------------|----------------------------------------------------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
88
- | `--root` or `-r` | `db:create`, `db:drop`, `seed:create` & `seed:run` | `process.cwd()` | Root directory of the project. |
89
- | `--dataSource` or `-d` | `db:create`, `db:drop` & `seed:run` | `data-source` | Name (or relative path incl. name) of the data-source file. |
90
- | `--synchronize` or `-s` | `db:create` | `yes` | Synchronize the database schema after database creation. Options: `yes` or `no`. |
91
- | `--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. |
92
- | `--name` | `seed:create` & `seed:run` | `undefined` | Name (or relative path incl. name) of the seeder. |
93
- | `--preserveFilePaths` | `db:create`, `db:drop`, `seed:create` & `seed:run` | `false` | This option indicates if file paths should be preserved and treated as if the just-in-time compilation environment is detected. |
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
- ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:create -d src/data-source.ts
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
- ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:drop -d src/data-source.ts
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
- ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed:run -d src/data-source.ts
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
- ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed:run -d src/data-source.ts --name src/database/seeds/user.ts
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
- ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed:create --name src/database/seeds/user.ts
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-sqlite',
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-sqlite',
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 expect slashes and hidden files
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 seedTacking option or locally using the track property of a seeder class.
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-sqlite',
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-sqlite',
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 provides an instance of the [faker](https://fakerjs.dev/guide/) library as function argument,
408
- to populate the entity with random data.
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, (faker) => {
506
+ export default setSeederFactory(User, () => {
416
507
  const user = new User();
417
- user.firstName = faker.name.firstName('male');
418
- user.lastName = faker.name.lastName('male');
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-sqlite',
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-sqlite',
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 parameter options (allowed, default, ...) are fully typed 🔥 and depend on the (nested-) properties of the target entity passed to
529
- the typeorm query builder.
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 explanation proposes,
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
- In this example [routup](https://www.npmjs.com/package/routup) and the
577
- plugin [@routup/query](https://www.npmjs.com/package/@routup/query) is used to handle HTTP requests,
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 { createServer } from 'node:http';
582
- import type { Request, Response } from 'routup';
583
- import { createNodeDispatcher, Router } from 'routup';
584
- import { createHandler, useQuery } from '@routup/query';
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
- import {
587
- applyQuery,
588
- useDataSource
589
- } from 'typeorm-extension';
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
- const router = new Router();
592
- router.use(createHandler());
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
- router.get('users', async (req: Request, res: Response) => {
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 repository = dataSource.getRepository(User);
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 query.getManyAndCount();
775
+ const [entities, total] = await queryBuilder.getManyAndCount();
650
776
 
651
- return {
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) @ 3.9.0 |
17
- | Processed | 2026-03-19 |
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 | 4 |
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
- | rapiq | ^0.9.0 | ^1.0.0 |
28
- | smob | ^1.5.0 | ^1.6.1 |
26
+ | smob | ^1.5.0 | ^1.6.2 |
29
27
 
30
28
  ---
31
29