@depup/typeorm-extension 3.9.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 (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.MD +674 -0
  3. package/README.md +34 -0
  4. package/bin/cli.cjs +275 -0
  5. package/bin/cli.mjs +273 -0
  6. package/changes.json +22 -0
  7. package/dist/cli/commands/database/create.d.ts +27 -0
  8. package/dist/cli/commands/database/drop.d.ts +23 -0
  9. package/dist/cli/commands/database/index.d.ts +2 -0
  10. package/dist/cli/commands/index.d.ts +2 -0
  11. package/dist/cli/commands/seed/create.d.ts +21 -0
  12. package/dist/cli/commands/seed/index.d.ts +2 -0
  13. package/dist/cli/commands/seed/run.d.ts +24 -0
  14. package/dist/cli/index.d.ts +2 -0
  15. package/dist/data-source/find/index.d.ts +2 -0
  16. package/dist/data-source/find/module.d.ts +3 -0
  17. package/dist/data-source/find/type.d.ts +22 -0
  18. package/dist/data-source/index.d.ts +4 -0
  19. package/dist/data-source/options/index.d.ts +4 -0
  20. package/dist/data-source/options/module.d.ts +8 -0
  21. package/dist/data-source/options/singleton.d.ts +4 -0
  22. package/dist/data-source/options/type.d.ts +26 -0
  23. package/dist/data-source/options/utils/env.d.ts +4 -0
  24. package/dist/data-source/options/utils/index.d.ts +2 -0
  25. package/dist/data-source/options/utils/merge.d.ts +2 -0
  26. package/dist/data-source/singleton.d.ts +5 -0
  27. package/dist/data-source/type.d.ts +2 -0
  28. package/dist/database/driver/cockroachdb.d.ts +4 -0
  29. package/dist/database/driver/index.d.ts +9 -0
  30. package/dist/database/driver/mongodb.d.ts +6 -0
  31. package/dist/database/driver/mssql.d.ts +6 -0
  32. package/dist/database/driver/mysql.d.ts +7 -0
  33. package/dist/database/driver/oracle.d.ts +6 -0
  34. package/dist/database/driver/postgres.d.ts +8 -0
  35. package/dist/database/driver/sqlite.d.ts +3 -0
  36. package/dist/database/driver/types.d.ts +20 -0
  37. package/dist/database/driver/utils/build.d.ts +3 -0
  38. package/dist/database/driver/utils/character-set.d.ts +2 -0
  39. package/dist/database/driver/utils/charset.d.ts +2 -0
  40. package/dist/database/driver/utils/create.d.ts +2 -0
  41. package/dist/database/driver/utils/index.d.ts +4 -0
  42. package/dist/database/index.d.ts +3 -0
  43. package/dist/database/methods/check/index.d.ts +2 -0
  44. package/dist/database/methods/check/module.d.ts +7 -0
  45. package/dist/database/methods/check/types.d.ts +51 -0
  46. package/dist/database/methods/create/index.d.ts +1 -0
  47. package/dist/database/methods/create/module.d.ts +10 -0
  48. package/dist/database/methods/drop/index.d.ts +1 -0
  49. package/dist/database/methods/drop/module.d.ts +10 -0
  50. package/dist/database/methods/index.d.ts +4 -0
  51. package/dist/database/methods/type.d.ts +43 -0
  52. package/dist/database/utils/context.d.ts +3 -0
  53. package/dist/database/utils/index.d.ts +5 -0
  54. package/dist/database/utils/migration.d.ts +2 -0
  55. package/dist/database/utils/query.d.ts +3 -0
  56. package/dist/database/utils/schema.d.ts +3 -0
  57. package/dist/database/utils/type.d.ts +32 -0
  58. package/dist/env/constants.d.ts +68 -0
  59. package/dist/env/index.d.ts +3 -0
  60. package/dist/env/module.d.ts +4 -0
  61. package/dist/env/type.d.ts +36 -0
  62. package/dist/env/utils.d.ts +3 -0
  63. package/dist/errors/base.d.ts +2 -0
  64. package/dist/errors/driver.d.ts +6 -0
  65. package/dist/errors/index.d.ts +3 -0
  66. package/dist/errors/options.d.ts +7 -0
  67. package/dist/helpers/entity/error.d.ts +20 -0
  68. package/dist/helpers/entity/index.d.ts +5 -0
  69. package/dist/helpers/entity/join-columns.d.ts +16 -0
  70. package/dist/helpers/entity/metadata.d.ts +10 -0
  71. package/dist/helpers/entity/property-names.d.ts +11 -0
  72. package/dist/helpers/entity/uniqueness.d.ts +28 -0
  73. package/dist/helpers/index.d.ts +1 -0
  74. package/dist/index.cjs +3258 -0
  75. package/dist/index.cjs.map +1 -0
  76. package/dist/index.d.ts +9 -0
  77. package/dist/index.mjs +3136 -0
  78. package/dist/index.mjs.map +1 -0
  79. package/dist/query/index.d.ts +4 -0
  80. package/dist/query/module.d.ts +5 -0
  81. package/dist/query/parameter/fields/index.d.ts +2 -0
  82. package/dist/query/parameter/fields/module.d.ts +25 -0
  83. package/dist/query/parameter/fields/type.d.ts +6 -0
  84. package/dist/query/parameter/filters/index.d.ts +2 -0
  85. package/dist/query/parameter/filters/module.d.ts +35 -0
  86. package/dist/query/parameter/filters/type.d.ts +12 -0
  87. package/dist/query/parameter/index.d.ts +5 -0
  88. package/dist/query/parameter/pagination/index.d.ts +2 -0
  89. package/dist/query/parameter/pagination/module.d.ts +26 -0
  90. package/dist/query/parameter/pagination/type.d.ts +3 -0
  91. package/dist/query/parameter/relations/index.d.ts +2 -0
  92. package/dist/query/parameter/relations/module.d.ts +27 -0
  93. package/dist/query/parameter/relations/type.d.ts +8 -0
  94. package/dist/query/parameter/sort/index.d.ts +2 -0
  95. package/dist/query/parameter/sort/module.d.ts +26 -0
  96. package/dist/query/parameter/sort/type.d.ts +6 -0
  97. package/dist/query/type.d.ts +16 -0
  98. package/dist/query/utils/alias.d.ts +2 -0
  99. package/dist/query/utils/index.d.ts +3 -0
  100. package/dist/query/utils/key.d.ts +1 -0
  101. package/dist/query/utils/option.d.ts +1 -0
  102. package/dist/seeder/entity.d.ts +42 -0
  103. package/dist/seeder/executor.d.ts +24 -0
  104. package/dist/seeder/factory/index.d.ts +4 -0
  105. package/dist/seeder/factory/manager.d.ts +8 -0
  106. package/dist/seeder/factory/module.d.ts +17 -0
  107. package/dist/seeder/factory/type.d.ts +12 -0
  108. package/dist/seeder/factory/utils.d.ts +7 -0
  109. package/dist/seeder/index.d.ts +6 -0
  110. package/dist/seeder/module.d.ts +5 -0
  111. package/dist/seeder/type.d.ts +44 -0
  112. package/dist/seeder/utils/file-path.d.ts +7 -0
  113. package/dist/seeder/utils/index.d.ts +3 -0
  114. package/dist/seeder/utils/prepare.d.ts +2 -0
  115. package/dist/seeder/utils/template.d.ts +1 -0
  116. package/dist/utils/code-transformation/constants.d.ts +4 -0
  117. package/dist/utils/code-transformation/index.d.ts +2 -0
  118. package/dist/utils/code-transformation/module.d.ts +3 -0
  119. package/dist/utils/entity.d.ts +2 -0
  120. package/dist/utils/file-path.d.ts +9 -0
  121. package/dist/utils/file-system.d.ts +1 -0
  122. package/dist/utils/has-property.d.ts +2 -0
  123. package/dist/utils/index.d.ts +10 -0
  124. package/dist/utils/object.d.ts +2 -0
  125. package/dist/utils/promise.d.ts +1 -0
  126. package/dist/utils/separator.d.ts +3 -0
  127. package/dist/utils/slash.d.ts +2 -0
  128. package/dist/utils/tsconfig/index.d.ts +2 -0
  129. package/dist/utils/tsconfig/module.d.ts +2 -0
  130. package/dist/utils/tsconfig/type.d.ts +13 -0
  131. package/package.json +134 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021-2024 Peter Placzek
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,674 @@
1
+ # Typeorm Extension 🚀
2
+
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)
8
+
9
+ This is a library to
10
+ - `create`, `drop` & `seed` the (default-) database 🔥
11
+ - 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
+
23
+ **Table of Contents**
24
+ - [Installation](#installation)
25
+ - [Documentation](#documentation)
26
+ - [Usage](#usage)
27
+ - [CLI](#cli)
28
+ - [Options](#cli-options)
29
+ - [Examples](#cli-examples)
30
+ - [Database](#database)
31
+ - [Create](#create)
32
+ - [Drop](#drop)
33
+ - [Instances](#instances)
34
+ - [Single](#single)
35
+ - [Multiple](#multiple)
36
+ - [Seeding](#seeding)
37
+ - [Configuration](#configuration)
38
+ - [Entity](#entity)
39
+ - [Factory](#factory)
40
+ - [Seed](#seed)
41
+ - [Execute](#execute)
42
+ - [Query](#query)
43
+ - [Contributing](#contributing)
44
+ - [License](#license)
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ npm install typeorm-extension --save
50
+ ```
51
+
52
+ ## Documentation
53
+
54
+ To read the docs, visit [https://typeorm-extension.tada5hi.net](https://typeorm-extension.tada5hi.net)
55
+
56
+ ## Usage
57
+
58
+ ### CLI
59
+
60
+ If you use esm, the executable must be changed from `typeorm-extension` to `typeorm-extension-esm`.
61
+ 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
66
+
67
+ If the application has not yet been built or is to be tested with ts-node, the commands can be adapted as follows:
68
+
69
+ ```
70
+ "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
+ }
76
+ ```
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
+
81
+ Read the [Seeding Configuration](#configuration) section to find out how to specify the path,
82
+ for the seeder- & factory-location.
83
+
84
+ #### CLI Options
85
+
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. |
94
+
95
+ #### CLI Examples
96
+ **`Database Create`**
97
+ ```shell
98
+ ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:create -d src/data-source.ts
99
+ ```
100
+ **`Database Drop`**
101
+ ```shell
102
+ ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:drop -d src/data-source.ts
103
+ ```
104
+
105
+ **`Seed Run`**
106
+ ```shell
107
+ ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed:run -d src/data-source.ts
108
+ ```
109
+
110
+ **`Seed Run Explicit`**
111
+ ```shell
112
+ ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed:run -d src/data-source.ts --name src/database/seeds/user.ts
113
+ ```
114
+
115
+ **`Seed Create`**
116
+ ```shell
117
+ ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed:create --name src/database/seeds/user.ts
118
+ ```
119
+
120
+ ### Database
121
+ An alternative to the CLI variant, is to `create` the database in the code base during the runtime of the application.
122
+ Therefore, provide the `DataSourceOptions` for the DataSource manually, or let it be created automatically:
123
+
124
+ #### Create
125
+ **`Example #1`**
126
+ ```typescript
127
+ import { DataSource, DataSourceOptions } from 'typeorm';
128
+ import { createDatabase } from 'typeorm-extension';
129
+
130
+ (async () => {
131
+ const options: DataSourceOptions = {
132
+ type: 'better-sqlite',
133
+ database: 'db.sqlite'
134
+ };
135
+
136
+ // Create the database with specification of the DataSource options
137
+ await createDatabase({
138
+ options
139
+ });
140
+
141
+ const dataSource = new DataSource(options);
142
+ await dataSource.initialize();
143
+ // do something with the DataSource
144
+ })();
145
+ ```
146
+
147
+ **`Example #2`**
148
+ ```typescript
149
+ import {
150
+ buildDataSourceOptions,
151
+ createDatabase
152
+ } from 'typeorm-extension';
153
+
154
+ (async () => {
155
+ const options = await buildDataSourceOptions();
156
+
157
+ // modify options
158
+
159
+ // Create the database with specification of the DataSource options
160
+ await createDatabase({
161
+ options
162
+ });
163
+
164
+ const dataSource = new DataSource(options);
165
+ await dataSource.initialize();
166
+ // do something with the DataSource
167
+ })();
168
+ ```
169
+
170
+ **`Example #3`**
171
+
172
+ It is also possible to let the library automatically search for the data-source under the hood.
173
+ Therefore, it will search by default for a `data-source.{ts,js}` file in the following directories:
174
+ - `{src,dist}/db/`
175
+ - `{src,dist}/database`
176
+ - `{src,dist}`
177
+
178
+ ```typescript
179
+ import { createDatabase } from 'typeorm-extension';
180
+
181
+ (async () => {
182
+ // Create the database without specifying it manually
183
+ await createDatabase();
184
+ })();
185
+ ```
186
+
187
+
188
+ To get a better overview and understanding of the
189
+ [createDatabase](https://typeorm-extension.tada5hi.net/guide/database-api-reference.html#createdatabase)
190
+ function, check out the documentation.
191
+
192
+ #### Drop
193
+
194
+ **`Example #1`**
195
+ ```typescript
196
+ import {
197
+ DataSource,
198
+ DataSourceOptions
199
+ } from 'typeorm';
200
+ import { dropDatabase } from 'typeorm-extension';
201
+
202
+ (async () => {
203
+ const options: DataSourceOptions = {
204
+ type: 'better-sqlite',
205
+ database: 'db.sqlite'
206
+ };
207
+
208
+ // Drop the database with specification of the DataSource options
209
+ await dropDatabase({
210
+ options
211
+ });
212
+ })();
213
+ ```
214
+
215
+ **`Example #2`**
216
+ ```typescript
217
+ import {
218
+ buildDataSourceOptions,
219
+ dropDatabase
220
+ } from 'typeorm-extension';
221
+
222
+ (async () => {
223
+ const options = await buildDataSourceOptions();
224
+
225
+ // modify options
226
+
227
+ // Drop the database with specification of the DataSource options
228
+ await dropDatabase({
229
+ options
230
+ });
231
+ })();
232
+ ```
233
+
234
+ **`Example #3`**
235
+
236
+ It is also possible to let the library automatically search for the data-source under the hood.
237
+ Therefore, it will search by default for a `data-source.{ts,js}` file in the following directories:
238
+ - `{src,dist}/db/`
239
+ - `{src,dist}/database`
240
+ - `{src,dist}`
241
+
242
+ ```typescript
243
+ import { dropDatabase } from 'typeorm-extension';
244
+
245
+ (async () => {
246
+ // Drop the database without specifying it manually
247
+ await dropDatabase();
248
+ })();
249
+ ```
250
+
251
+ To get a better overview and understanding of the
252
+ [dropDatabase](https://typeorm-extension.tada5hi.net/guide/database-api-reference.html#dropDatabase)
253
+ function, check out the documentation.
254
+
255
+ ### Instances
256
+
257
+ #### Single
258
+
259
+ The default DataSource instance can be acquired, by not providing any alias at all or using the key `default`.
260
+ If no DataSource instance or DataSourceOptions object is deposited initially the method will attempt to locate and load
261
+ the DataSource file and initialize itself from there.
262
+
263
+ ```typescript
264
+ import { useDataSource } from 'typeorm-extension';
265
+
266
+ (async () => {
267
+ const dataSource : DataSource = await useDataSource();
268
+ })();
269
+ ```
270
+
271
+ Reference(s):
272
+ - [setDataSource](https://typeorm-extension.tada5hi.net/guide/datasource-api-reference.html#setdatasource)
273
+ - [useDataSource](https://typeorm-extension.tada5hi.net/guide/datasource-api-reference.html#usedatasource)
274
+
275
+ #### Multiple
276
+
277
+ It is also possible to manage multiple DataSource instances.
278
+ Therefore, each additional DataSource must be registered under a different alias.
279
+ This can be done by either setting the DataSource instance or the DataSourceOptions object for the given alias.
280
+
281
+ ```typescript
282
+ import { DataSource, DataSourceOptions } from 'typeorm';
283
+ import { setDataSource, useDataSource } from 'typeorm-extension';
284
+
285
+ (async () => {
286
+ const secondDataSourceOptions : DataSourceOptions = {
287
+ // ...
288
+ };
289
+
290
+ const dataSource = new DataSource(secondDataSourceOptions);
291
+ setDataSource(dataSource, 'second');
292
+
293
+ const instance : DataSource = await useDataSource('second');
294
+ })();
295
+ ```
296
+
297
+ Reference(s):
298
+ - [setDataSource](https://typeorm-extension.tada5hi.net/guide/datasource-api-reference.html#setdatasource)
299
+ - [setDataSourceOptions](https://typeorm-extension.tada5hi.net/guide/datasource-api-reference.html#setdatasourceoptions)
300
+
301
+ ### Seeding
302
+
303
+ Seeding the database is fairly easy and can be achieved by following the steps below:
304
+ - `Configuration`: Specify the seed and factory location by path or object.
305
+ - `Entity`: Define one or more entities.
306
+ - `Factory` (optional): Define a factory for each entity for which data should be automatically generated.
307
+ - `Seed`: Define one or more seed classes to populate the database with an initial data set or generated data by a factory.
308
+ - `Execute`: Run the seeder(s) with the CLI or in the code base.
309
+
310
+ #### Configuration
311
+
312
+ Seeder paths are configured as **glob patterns**, making it easy
313
+ to match all the factory/seeder files in your project without configuration effort:
314
+ - use `*` to match anything expect slashes and hidden files
315
+ - use `**` to match zero or more directories
316
+ - use comma separate values between `{}` to match against a list of options
317
+
318
+ Check out the [glob](https://www.npmjs.com/package/glob) documentation for other supported pattern features.
319
+ It is important to use the posix/unix path separator (/) because
320
+ the Windows path separator (\\) is used to match paths with literal global pattern characters.
321
+
322
+ The seeder- & factory-location, can be specified via:
323
+ - `environment` variable(s)
324
+ - extended `data-source.ts` file
325
+ - `runSeeder(s)` method options parameter, in case of a direct code base usage
326
+
327
+ The following values are assumed by default:
328
+ - factory path: `src/database/factories/**/*{.ts,.js}`
329
+ - seed path: `src/database/seeds/**/*{.ts,.js}`
330
+
331
+ 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
+
333
+ 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.
335
+
336
+ `data-source.ts`
337
+
338
+ ```typescript
339
+ import { DataSource, DataSourceOptions } from 'typeorm';
340
+ import { SeederOptions } from 'typeorm-extension';
341
+
342
+ const options: DataSourceOptions & SeederOptions = {
343
+ type: 'better-sqlite',
344
+ database: 'db.sqlite',
345
+
346
+ seeds: ['src/database/seeds/**/*{.ts,.js}'],
347
+ seedTracking: false,
348
+ factories: ['src/database/factories/**/*{.ts,.js}'],
349
+ };
350
+
351
+ export const dataSource = new DataSource(options);
352
+ ```
353
+
354
+ `runSeeder(s)`
355
+
356
+ ```typescript
357
+ import { DataSource, DataSourceOptions } from 'typeorm';
358
+ import { runSeeders, SeederOptions } from 'typeorm-extension';
359
+
360
+ (async () => {
361
+ const options: DataSourceOptions = {
362
+ type: 'better-sqlite',
363
+ database: 'db.sqlite',
364
+ };
365
+
366
+ const dataSource = new DataSource(options);
367
+ await dataSource.initialize();
368
+
369
+ runSeeders(dataSource, {
370
+ seeds: ['src/database/seeds/**/*{.ts,.js}'],
371
+ factories: ['src/database/factories/**/*{.ts,.js}']
372
+ });
373
+ })();
374
+ ```
375
+
376
+ #### Entity
377
+ To get started, define one or more entities.
378
+
379
+ **`user.ts`**
380
+ ```typescript
381
+ import {
382
+ Entity,
383
+ PrimaryGeneratedColumn,
384
+ Column
385
+ } from 'typeorm';
386
+
387
+ @Entity()
388
+ export class User {
389
+ @PrimaryGeneratedColumn()
390
+ id: number
391
+
392
+ @Column()
393
+ firstName: string
394
+
395
+ @Column()
396
+ lastName: string
397
+
398
+ @Column()
399
+ email: string
400
+ }
401
+ ```
402
+
403
+ #### Factory
404
+ To create entities with random data, create a factory for each desired entity.
405
+ The definition of a factory is **optional**.
406
+
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.
409
+
410
+ **`user.factory.ts`**
411
+ ```typescript
412
+ import { setSeederFactory } from 'typeorm-extension';
413
+ import { User } from './user';
414
+
415
+ export default setSeederFactory(User, (faker) => {
416
+ 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);
420
+
421
+ return user;
422
+ })
423
+ ```
424
+
425
+ #### 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`.
428
+ A seeder class only requires one method, called `run` and provides the arguments `dataSource` & `factoryManager`.
429
+
430
+ **`user.seeder.ts`**
431
+
432
+ A seeder class must implement the [Seeder](https://typeorm-extension.tada5hi.net/guide/seeding-api-reference.html) interface, and could look like this:
433
+
434
+ ```typescript
435
+ import { Seeder, SeederFactoryManager } from 'typeorm-extension';
436
+ import { DataSource } from 'typeorm';
437
+ import { User } from './user';
438
+
439
+ export default class UserSeeder implements Seeder {
440
+ /**
441
+ * Track seeder execution.
442
+ *
443
+ * Default: false
444
+ */
445
+ track = false;
446
+
447
+ public async run(
448
+ dataSource: DataSource,
449
+ factoryManager: SeederFactoryManager
450
+ ): Promise<any> {
451
+ const repository = dataSource.getRepository(User);
452
+ await repository.insert([
453
+ {
454
+ firstName: 'Caleb',
455
+ lastName: 'Barrows',
456
+ email: 'caleb.barrows@gmail.com'
457
+ }
458
+ ]);
459
+
460
+ // ---------------------------------------------------
461
+
462
+ const userFactory = await factoryManager.get(User);
463
+ // save 1 factory generated entity, to the database
464
+ await userFactory.save();
465
+
466
+ // save 5 factory generated entities, to the database
467
+ await userFactory.saveMany(5);
468
+ }
469
+ }
470
+ ```
471
+
472
+ #### Execute
473
+
474
+ Populate the database from the code base:
475
+
476
+ ```typescript
477
+ import { DataSource, DataSourceOptions } from 'typeorm';
478
+ import { runSeeders, SeederOptions } from 'typeorm-extension';
479
+ import { User } from 'user';
480
+
481
+ (async () => {
482
+ const options: DataSourceOptions & SeederOptions = {
483
+ type: 'better-sqlite',
484
+ database: 'db.sqlite',
485
+ entities: [User],
486
+
487
+ seeds: ['./*.seeder.ts'],
488
+ factories: ['./*.factory.ts']
489
+ };
490
+
491
+ const dataSource = new DataSource(options);
492
+ await dataSource.initialize();
493
+
494
+ await runSeeders(dataSource);
495
+ })();
496
+ ```
497
+
498
+ Populate the database by explicit definitions from the codebase.
499
+
500
+ ```typescript
501
+ import { DataSource, DataSourceOptions } from 'typeorm';
502
+ import { runSeeders, SeederOptions } from 'typeorm-extension';
503
+ import { User } from 'user';
504
+ import UserSeeder from 'user.seeder';
505
+ import UserFactory from 'user.factory';
506
+
507
+ (async () => {
508
+ const options: DataSourceOptions & SeederOptions = {
509
+ type: 'better-sqlite',
510
+ database: 'db.sqlite',
511
+ entities: [User],
512
+
513
+ seeds: [UserSeeder],
514
+ factories: [UserFactory]
515
+ };
516
+
517
+ const dataSource = new DataSource(options);
518
+ await dataSource.initialize();
519
+
520
+ await runSeeders(dataSource);
521
+ })();
522
+ ```
523
+
524
+ ### 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
+
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.
530
+
531
+ For explanation proposes,
532
+ two simple entities with a relation between them are declared to demonstrate the usage of the query utils:
533
+
534
+ ```typescript
535
+ import {
536
+ Entity,
537
+ PrimaryGeneratedColumn,
538
+ Column,
539
+ OneToOne,
540
+ JoinColumn
541
+ } from 'typeorm';
542
+
543
+ @Entity()
544
+ export class User {
545
+ @PrimaryGeneratedColumn({unsigned: true})
546
+ id: number;
547
+
548
+ @Column({type: 'varchar', length: 30})
549
+ @Index({unique: true})
550
+ name: string;
551
+
552
+ @Column({type: 'varchar', length: 255, default: null, nullable: true})
553
+ email: string;
554
+
555
+ @OneToOne(() => Profile)
556
+ profile: Profile;
557
+ }
558
+
559
+ @Entity()
560
+ export class Profile {
561
+ @PrimaryGeneratedColumn({unsigned: true})
562
+ id: number;
563
+
564
+ @Column({type: 'varchar', length: 255, default: null, nullable: true})
565
+ avatar: string;
566
+
567
+ @Column({type: 'varchar', length: 255, default: null, nullable: true})
568
+ cover: string;
569
+
570
+ @OneToOne(() => User)
571
+ @JoinColumn()
572
+ user: User;
573
+ }
574
+ ```
575
+
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).
579
+
580
+ ```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';
585
+
586
+ import {
587
+ applyQuery,
588
+ useDataSource
589
+ } from 'typeorm-extension';
590
+
591
+ const router = new Router();
592
+ router.use(createHandler());
593
+
594
+ /**
595
+ * Get many users.
596
+ *
597
+ * Request example
598
+ * - 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
+ */
614
+ router.get('users', async (req: Request, res: Response) => {
615
+ 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
+ });
646
+
647
+ // -----------------------------------------------------
648
+
649
+ const [entities, total] = await query.getManyAndCount();
650
+
651
+ return {
652
+ data: entities,
653
+ meta: {
654
+ total,
655
+ ...pagination
656
+ }
657
+ };
658
+ });
659
+
660
+ const server = createServer(createNodeDispatcher(router));
661
+ server.listen(80);
662
+ ```
663
+
664
+ ## Contributing
665
+
666
+ Before starting to work on a pull request, it is important to review the guidelines for
667
+ [contributing](./CONTRIBUTING.md) and the [code of conduct](./CODE_OF_CONDUCT.md).
668
+ These guidelines will help to ensure that contributions are made effectively and are accepted.
669
+
670
+ ## License
671
+
672
+ Made with 💚
673
+
674
+ Published under [MIT License](./LICENSE).