@mikro-orm/core 7.0.4 → 7.0.5-dev.1
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/EntityManager.d.ts +583 -884
- package/EntityManager.js +1895 -1922
- package/MikroORM.d.ts +74 -103
- package/MikroORM.js +179 -178
- package/README.md +1 -1
- package/cache/CacheAdapter.d.ts +36 -36
- package/cache/FileCacheAdapter.d.ts +24 -30
- package/cache/FileCacheAdapter.js +78 -80
- package/cache/GeneratedCacheAdapter.d.ts +20 -18
- package/cache/GeneratedCacheAdapter.js +30 -30
- package/cache/MemoryCacheAdapter.d.ts +20 -18
- package/cache/MemoryCacheAdapter.js +36 -35
- package/cache/NullCacheAdapter.d.ts +16 -16
- package/cache/NullCacheAdapter.js +24 -24
- package/connections/Connection.d.ts +84 -95
- package/connections/Connection.js +168 -165
- package/drivers/DatabaseDriver.d.ts +80 -186
- package/drivers/DatabaseDriver.js +443 -450
- package/drivers/IDatabaseDriver.d.ts +301 -440
- package/entity/BaseEntity.d.ts +83 -120
- package/entity/BaseEntity.js +43 -43
- package/entity/Collection.d.ts +179 -212
- package/entity/Collection.js +721 -727
- package/entity/EntityAssigner.d.ts +77 -88
- package/entity/EntityAssigner.js +230 -231
- package/entity/EntityFactory.d.ts +54 -66
- package/entity/EntityFactory.js +383 -425
- package/entity/EntityHelper.d.ts +22 -34
- package/entity/EntityHelper.js +267 -280
- package/entity/EntityIdentifier.d.ts +4 -4
- package/entity/EntityIdentifier.js +10 -10
- package/entity/EntityLoader.d.ts +72 -98
- package/entity/EntityLoader.js +723 -753
- package/entity/EntityRepository.d.ts +201 -316
- package/entity/EntityRepository.js +213 -213
- package/entity/PolymorphicRef.d.ts +5 -5
- package/entity/PolymorphicRef.js +10 -10
- package/entity/Reference.d.ts +82 -126
- package/entity/Reference.js +274 -278
- package/entity/WrappedEntity.d.ts +72 -115
- package/entity/WrappedEntity.js +166 -168
- package/entity/defineEntity.d.ts +636 -1315
- package/entity/defineEntity.js +518 -527
- package/entity/utils.d.ts +3 -13
- package/entity/utils.js +73 -71
- package/entity/validators.js +43 -43
- package/entity/wrap.js +8 -8
- package/enums.d.ts +253 -258
- package/enums.js +252 -251
- package/errors.d.ts +72 -114
- package/errors.js +253 -350
- package/events/EventManager.d.ts +14 -26
- package/events/EventManager.js +77 -79
- package/events/EventSubscriber.d.ts +29 -29
- package/events/TransactionEventBroadcaster.d.ts +8 -15
- package/events/TransactionEventBroadcaster.js +14 -14
- package/exceptions.d.ts +40 -23
- package/exceptions.js +52 -35
- package/hydration/Hydrator.d.ts +17 -42
- package/hydration/Hydrator.js +43 -43
- package/hydration/ObjectHydrator.d.ts +17 -50
- package/hydration/ObjectHydrator.js +416 -481
- package/index.d.ts +2 -116
- package/index.js +1 -10
- package/logging/DefaultLogger.d.ts +32 -34
- package/logging/DefaultLogger.js +86 -86
- package/logging/Logger.d.ts +41 -41
- package/logging/SimpleLogger.d.ts +11 -13
- package/logging/SimpleLogger.js +22 -22
- package/logging/colors.d.ts +6 -6
- package/logging/colors.js +10 -11
- package/logging/inspect.js +7 -7
- package/metadata/EntitySchema.d.ts +127 -211
- package/metadata/EntitySchema.js +398 -397
- package/metadata/MetadataDiscovery.d.ts +114 -114
- package/metadata/MetadataDiscovery.js +1870 -1951
- package/metadata/MetadataProvider.d.ts +21 -24
- package/metadata/MetadataProvider.js +84 -82
- package/metadata/MetadataStorage.d.ts +32 -38
- package/metadata/MetadataStorage.js +118 -118
- package/metadata/MetadataValidator.d.ts +39 -39
- package/metadata/MetadataValidator.js +338 -381
- package/metadata/discover-entities.d.ts +2 -5
- package/metadata/discover-entities.js +37 -35
- package/metadata/types.d.ts +531 -615
- package/naming-strategy/AbstractNamingStrategy.d.ts +39 -54
- package/naming-strategy/AbstractNamingStrategy.js +85 -90
- package/naming-strategy/EntityCaseNamingStrategy.d.ts +6 -6
- package/naming-strategy/EntityCaseNamingStrategy.js +22 -22
- package/naming-strategy/MongoNamingStrategy.d.ts +6 -6
- package/naming-strategy/MongoNamingStrategy.js +18 -18
- package/naming-strategy/NamingStrategy.d.ts +99 -109
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +7 -7
- package/naming-strategy/UnderscoreNamingStrategy.js +21 -21
- package/not-supported.js +4 -7
- package/package.json +1 -1
- package/platforms/ExceptionConverter.d.ts +1 -1
- package/platforms/ExceptionConverter.js +4 -4
- package/platforms/Platform.d.ts +301 -310
- package/platforms/Platform.js +640 -663
- package/serialization/EntitySerializer.d.ts +26 -49
- package/serialization/EntitySerializer.js +218 -224
- package/serialization/EntityTransformer.d.ts +6 -10
- package/serialization/EntityTransformer.js +217 -219
- package/serialization/SerializationContext.d.ts +23 -27
- package/serialization/SerializationContext.js +105 -105
- package/types/ArrayType.d.ts +8 -8
- package/types/ArrayType.js +33 -33
- package/types/BigIntType.d.ts +10 -17
- package/types/BigIntType.js +37 -37
- package/types/BlobType.d.ts +3 -3
- package/types/BlobType.js +13 -13
- package/types/BooleanType.d.ts +4 -4
- package/types/BooleanType.js +12 -12
- package/types/CharacterType.d.ts +2 -2
- package/types/CharacterType.js +6 -6
- package/types/DateTimeType.d.ts +5 -5
- package/types/DateTimeType.js +15 -15
- package/types/DateType.d.ts +5 -5
- package/types/DateType.js +15 -15
- package/types/DecimalType.d.ts +7 -7
- package/types/DecimalType.js +26 -26
- package/types/DoubleType.d.ts +3 -3
- package/types/DoubleType.js +12 -12
- package/types/EnumArrayType.d.ts +5 -5
- package/types/EnumArrayType.js +24 -24
- package/types/EnumType.d.ts +3 -3
- package/types/EnumType.js +11 -11
- package/types/FloatType.d.ts +3 -3
- package/types/FloatType.js +9 -9
- package/types/IntegerType.d.ts +3 -3
- package/types/IntegerType.js +9 -9
- package/types/IntervalType.d.ts +4 -4
- package/types/IntervalType.js +12 -12
- package/types/JsonType.d.ts +8 -8
- package/types/JsonType.js +32 -32
- package/types/MediumIntType.d.ts +1 -1
- package/types/MediumIntType.js +3 -3
- package/types/SmallIntType.d.ts +3 -3
- package/types/SmallIntType.js +9 -9
- package/types/StringType.d.ts +4 -4
- package/types/StringType.js +12 -12
- package/types/TextType.d.ts +3 -3
- package/types/TextType.js +9 -9
- package/types/TimeType.d.ts +5 -5
- package/types/TimeType.js +17 -17
- package/types/TinyIntType.d.ts +3 -3
- package/types/TinyIntType.js +10 -10
- package/types/Type.d.ts +79 -83
- package/types/Type.js +82 -82
- package/types/Uint8ArrayType.d.ts +4 -4
- package/types/Uint8ArrayType.js +21 -21
- package/types/UnknownType.d.ts +4 -4
- package/types/UnknownType.js +12 -12
- package/types/UuidType.d.ts +5 -5
- package/types/UuidType.js +19 -19
- package/types/index.d.ts +49 -75
- package/types/index.js +26 -52
- package/typings.d.ts +737 -1250
- package/typings.js +231 -244
- package/unit-of-work/ChangeSet.d.ts +26 -26
- package/unit-of-work/ChangeSet.js +56 -56
- package/unit-of-work/ChangeSetComputer.d.ts +12 -12
- package/unit-of-work/ChangeSetComputer.js +170 -178
- package/unit-of-work/ChangeSetPersister.d.ts +44 -63
- package/unit-of-work/ChangeSetPersister.js +421 -442
- package/unit-of-work/CommitOrderCalculator.d.ts +40 -40
- package/unit-of-work/CommitOrderCalculator.js +88 -89
- package/unit-of-work/IdentityMap.d.ts +31 -31
- package/unit-of-work/IdentityMap.js +105 -105
- package/unit-of-work/UnitOfWork.d.ts +141 -181
- package/unit-of-work/UnitOfWork.js +1183 -1200
- package/utils/AbstractMigrator.d.ts +91 -111
- package/utils/AbstractMigrator.js +275 -275
- package/utils/AbstractSchemaGenerator.d.ts +34 -43
- package/utils/AbstractSchemaGenerator.js +122 -121
- package/utils/AsyncContext.d.ts +3 -3
- package/utils/AsyncContext.js +35 -34
- package/utils/Configuration.d.ts +808 -852
- package/utils/Configuration.js +344 -359
- package/utils/Cursor.d.ts +22 -40
- package/utils/Cursor.js +127 -135
- package/utils/DataloaderUtils.d.ts +43 -58
- package/utils/DataloaderUtils.js +198 -203
- package/utils/EntityComparator.d.ts +81 -98
- package/utils/EntityComparator.js +732 -828
- package/utils/NullHighlighter.d.ts +1 -1
- package/utils/NullHighlighter.js +3 -3
- package/utils/QueryHelper.d.ts +51 -79
- package/utils/QueryHelper.js +361 -372
- package/utils/RawQueryFragment.d.ts +34 -50
- package/utils/RawQueryFragment.js +105 -107
- package/utils/RequestContext.d.ts +32 -32
- package/utils/RequestContext.js +53 -52
- package/utils/TransactionContext.d.ts +16 -16
- package/utils/TransactionContext.js +27 -27
- package/utils/TransactionManager.d.ts +58 -58
- package/utils/TransactionManager.js +197 -199
- package/utils/Utils.d.ts +145 -204
- package/utils/Utils.js +812 -812
- package/utils/clone.js +113 -104
- package/utils/env-vars.js +88 -90
- package/utils/fs-utils.d.ts +15 -15
- package/utils/fs-utils.js +181 -180
- package/utils/upsert-utils.d.ts +5 -20
- package/utils/upsert-utils.js +116 -114
package/metadata/EntitySchema.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EntityMetadata } from '../typings.js';
|
|
1
|
+
import { EntityMetadata, } from '../typings.js';
|
|
2
2
|
import { BaseEntity } from '../entity/BaseEntity.js';
|
|
3
3
|
import { Cascade, ReferenceKind } from '../enums.js';
|
|
4
4
|
import { Type } from '../types/Type.js';
|
|
@@ -6,400 +6,401 @@ import { Utils } from '../utils/Utils.js';
|
|
|
6
6
|
import { EnumArrayType } from '../types/EnumArrayType.js';
|
|
7
7
|
/** Class-less entity definition that provides a programmatic API for defining entities without decorators. */
|
|
8
8
|
export class EntitySchema {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
9
|
+
/**
|
|
10
|
+
* When schema links the entity class via `class` option, this registry allows the lookup from opposite side,
|
|
11
|
+
* so we can use the class in `entities` option just like the EntitySchema instance.
|
|
12
|
+
*/
|
|
13
|
+
static REGISTRY = new Map();
|
|
14
|
+
_meta;
|
|
15
|
+
internal = false;
|
|
16
|
+
initialized = false;
|
|
17
|
+
constructor(meta) {
|
|
18
|
+
meta.name = meta.class ? meta.class.name : meta.name;
|
|
19
|
+
if (meta.name) {
|
|
20
|
+
meta.abstract ??= false;
|
|
21
|
+
}
|
|
22
|
+
this._meta = new EntityMetadata({
|
|
23
|
+
className: meta.name,
|
|
24
|
+
...meta,
|
|
25
|
+
});
|
|
26
|
+
this._meta.root ??= this._meta;
|
|
27
|
+
if (meta.class && !meta.internal) {
|
|
28
|
+
EntitySchema.REGISTRY.set(meta.class, this);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Checks if the given value is an EntitySchema instance, using duck-typing
|
|
33
|
+
* as a fallback when `instanceof` fails due to CJS/ESM dual-package hazard
|
|
34
|
+
* (e.g. when using `tsx` or `@swc-node/register` with `"type": "commonjs"` projects).
|
|
35
|
+
*/
|
|
36
|
+
static is(item) {
|
|
37
|
+
if (item instanceof EntitySchema) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return item != null && typeof item === 'object' && item.constructor?.name === 'EntitySchema' && 'meta' in item;
|
|
41
|
+
}
|
|
42
|
+
/** Creates an EntitySchema from existing EntityMetadata (used internally). */
|
|
43
|
+
static fromMetadata(meta) {
|
|
44
|
+
const schema = new EntitySchema({ ...meta, internal: true });
|
|
45
|
+
schema.internal = true;
|
|
46
|
+
return schema;
|
|
47
|
+
}
|
|
48
|
+
/** Adds a scalar property to the entity schema. */
|
|
49
|
+
addProperty(name, type, options = {}) {
|
|
50
|
+
this.renameCompositeOptions(name, options);
|
|
51
|
+
const prop = {
|
|
52
|
+
name,
|
|
53
|
+
kind: ReferenceKind.SCALAR,
|
|
54
|
+
...options,
|
|
55
|
+
...this.normalizeType(options, type),
|
|
56
|
+
};
|
|
57
|
+
if (type && Type.isMappedType(type.prototype)) {
|
|
58
|
+
prop.type = type;
|
|
59
|
+
}
|
|
60
|
+
if (typeof prop.formula === 'string') {
|
|
61
|
+
const formula = prop.formula;
|
|
62
|
+
prop.formula = () => formula;
|
|
63
|
+
}
|
|
64
|
+
if (prop.formula) {
|
|
65
|
+
prop.persist ??= false;
|
|
66
|
+
}
|
|
67
|
+
this._meta.properties[name] = prop;
|
|
68
|
+
}
|
|
69
|
+
/** Adds an enum property to the entity schema. */
|
|
70
|
+
addEnum(name, type, options = {}) {
|
|
71
|
+
if (options.items instanceof Function) {
|
|
72
|
+
options.items = Utils.extractEnumValues(options.items());
|
|
73
|
+
}
|
|
74
|
+
// enum arrays are simple numeric/string arrays, the constraint is enforced in the custom type only
|
|
75
|
+
if (options.array && !options.type) {
|
|
76
|
+
options.type = new EnumArrayType(`${this._meta.className}.${name}`, options.items);
|
|
77
|
+
options.enum = false;
|
|
78
|
+
}
|
|
79
|
+
const prop = { enum: true, ...options };
|
|
80
|
+
if (prop.array) {
|
|
81
|
+
prop.enum = false;
|
|
82
|
+
}
|
|
83
|
+
// force string labels on native enums
|
|
84
|
+
if (prop.nativeEnumName && Array.isArray(prop.items)) {
|
|
85
|
+
prop.items = prop.items.map(val => '' + val);
|
|
86
|
+
}
|
|
87
|
+
this.addProperty(name, this.internal ? type : type || 'enum', prop);
|
|
88
|
+
}
|
|
89
|
+
/** Adds a version property for optimistic locking. */
|
|
90
|
+
addVersion(name, type, options = {}) {
|
|
91
|
+
this.addProperty(name, type, { version: true, ...options });
|
|
92
|
+
}
|
|
93
|
+
/** Adds a primary key property to the entity schema. */
|
|
94
|
+
addPrimaryKey(name, type, options = {}) {
|
|
95
|
+
this.addProperty(name, type, { primary: true, ...options });
|
|
96
|
+
}
|
|
97
|
+
/** Adds a serialized primary key property (e.g. for MongoDB ObjectId). */
|
|
98
|
+
addSerializedPrimaryKey(name, type, options = {}) {
|
|
99
|
+
this._meta.serializedPrimaryKey = name;
|
|
100
|
+
this.addProperty(name, type, { serializedPrimaryKey: true, ...options });
|
|
101
|
+
}
|
|
102
|
+
/** Adds an embedded property to the entity schema. */
|
|
103
|
+
addEmbedded(name, options) {
|
|
104
|
+
this.renameCompositeOptions(name, options);
|
|
105
|
+
Utils.defaultValue(options, 'prefix', true);
|
|
106
|
+
if (options.array) {
|
|
107
|
+
options.object = true; // force object mode for arrays
|
|
108
|
+
}
|
|
109
|
+
this._meta.properties[name] = {
|
|
110
|
+
name,
|
|
111
|
+
kind: ReferenceKind.EMBEDDED,
|
|
112
|
+
...this.normalizeType(options),
|
|
113
|
+
...options,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/** Adds a many-to-one relation to the entity schema. */
|
|
117
|
+
addManyToOne(name, type, options) {
|
|
118
|
+
const prop = this.createProperty(ReferenceKind.MANY_TO_ONE, options);
|
|
119
|
+
prop.owner = true;
|
|
120
|
+
if (prop.joinColumns && !prop.fieldNames) {
|
|
121
|
+
prop.fieldNames = prop.joinColumns;
|
|
122
|
+
}
|
|
123
|
+
if (prop.fieldNames && !prop.joinColumns) {
|
|
124
|
+
prop.joinColumns = prop.fieldNames;
|
|
125
|
+
}
|
|
126
|
+
// By default, the foreign key constraint is created on the relation
|
|
127
|
+
Utils.defaultValue(prop, 'createForeignKeyConstraint', true);
|
|
128
|
+
this.addProperty(name, type, prop);
|
|
129
|
+
}
|
|
130
|
+
/** Adds a many-to-many relation to the entity schema. */
|
|
131
|
+
addManyToMany(name, type, options) {
|
|
132
|
+
options.fixedOrder = options.fixedOrder || !!options.fixedOrderColumn;
|
|
133
|
+
if (!options.owner && !options.mappedBy) {
|
|
134
|
+
options.owner = true;
|
|
135
|
+
}
|
|
136
|
+
if (options.owner) {
|
|
137
|
+
Utils.renameKey(options, 'mappedBy', 'inversedBy');
|
|
138
|
+
// By default, the foreign key constraint is created on the relation
|
|
139
|
+
Utils.defaultValue(options, 'createForeignKeyConstraint', true);
|
|
140
|
+
}
|
|
141
|
+
const prop = this.createProperty(ReferenceKind.MANY_TO_MANY, options);
|
|
142
|
+
this.addProperty(name, type, prop);
|
|
143
|
+
}
|
|
144
|
+
/** Adds a one-to-many relation to the entity schema. */
|
|
145
|
+
addOneToMany(name, type, options) {
|
|
146
|
+
const prop = this.createProperty(ReferenceKind.ONE_TO_MANY, options);
|
|
147
|
+
this.addProperty(name, type, prop);
|
|
148
|
+
}
|
|
149
|
+
/** Adds a one-to-one relation to the entity schema. */
|
|
150
|
+
addOneToOne(name, type, options) {
|
|
151
|
+
const prop = this.createProperty(ReferenceKind.ONE_TO_ONE, options);
|
|
152
|
+
Utils.defaultValue(prop, 'owner', !!prop.inversedBy || !prop.mappedBy);
|
|
153
|
+
Utils.defaultValue(prop, 'unique', prop.owner);
|
|
154
|
+
if (prop.owner) {
|
|
155
|
+
if (options.mappedBy) {
|
|
156
|
+
Utils.renameKey(prop, 'mappedBy', 'inversedBy');
|
|
157
|
+
}
|
|
158
|
+
// By default, the foreign key constraint is created on the relation
|
|
159
|
+
Utils.defaultValue(prop, 'createForeignKeyConstraint', true);
|
|
160
|
+
}
|
|
161
|
+
if (prop.joinColumns && !prop.fieldNames) {
|
|
162
|
+
prop.fieldNames = prop.joinColumns;
|
|
163
|
+
}
|
|
164
|
+
if (prop.fieldNames && !prop.joinColumns) {
|
|
165
|
+
prop.joinColumns = prop.fieldNames;
|
|
166
|
+
}
|
|
167
|
+
this.addProperty(name, type, prop);
|
|
168
|
+
}
|
|
169
|
+
/** Adds an index definition to the entity schema. */
|
|
170
|
+
addIndex(options) {
|
|
171
|
+
this._meta.indexes.push(options);
|
|
172
|
+
}
|
|
173
|
+
/** Adds a unique constraint definition to the entity schema. */
|
|
174
|
+
addUnique(options) {
|
|
175
|
+
this._meta.uniques.push(options);
|
|
176
|
+
}
|
|
177
|
+
/** Sets a custom repository class for this entity. */
|
|
178
|
+
setCustomRepository(repository) {
|
|
179
|
+
this._meta.repository = repository;
|
|
180
|
+
}
|
|
181
|
+
/** Sets the base entity that this schema extends. */
|
|
182
|
+
setExtends(base) {
|
|
183
|
+
this._meta.extends = base;
|
|
184
|
+
}
|
|
185
|
+
/** Sets or replaces the entity class associated with this schema. */
|
|
186
|
+
setClass(cls) {
|
|
187
|
+
const oldClass = this._meta.class;
|
|
188
|
+
const sameClass = this._meta.class === cls;
|
|
189
|
+
this._meta.class = cls;
|
|
190
|
+
this._meta.prototype = cls.prototype;
|
|
191
|
+
this._meta.className = this._meta.name ?? cls.name;
|
|
192
|
+
if (!sameClass || !this._meta.constructorParams) {
|
|
193
|
+
this._meta.constructorParams = Utils.getConstructorParams(cls);
|
|
194
|
+
}
|
|
195
|
+
if (!this.internal) {
|
|
196
|
+
// Remove old class from registry if it's being replaced with a different class
|
|
197
|
+
if (oldClass && oldClass !== cls && EntitySchema.REGISTRY.get(oldClass) === this) {
|
|
198
|
+
EntitySchema.REGISTRY.delete(oldClass);
|
|
199
|
+
}
|
|
200
|
+
EntitySchema.REGISTRY.set(cls, this);
|
|
201
|
+
}
|
|
202
|
+
const base = Object.getPrototypeOf(cls);
|
|
203
|
+
// Only set extends if the parent is NOT the auto-generated class for this same entity.
|
|
204
|
+
// When the user extends the auto-generated class (from defineEntity without a class option)
|
|
205
|
+
// and registers their custom class via setClass, we don't want to discover the
|
|
206
|
+
// auto-generated class as a separate parent entity.
|
|
207
|
+
if (base !== BaseEntity && base.name !== this._meta.className) {
|
|
208
|
+
this._meta.extends ??= base.name ? base : undefined;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/** Returns the underlying EntityMetadata. */
|
|
212
|
+
get meta() {
|
|
213
|
+
return this._meta;
|
|
214
|
+
}
|
|
215
|
+
/** Returns the entity class name. */
|
|
216
|
+
get name() {
|
|
217
|
+
return this._meta.className;
|
|
218
|
+
}
|
|
219
|
+
/** Returns the database table name. */
|
|
220
|
+
get tableName() {
|
|
221
|
+
return this._meta.tableName;
|
|
222
|
+
}
|
|
223
|
+
get class() {
|
|
224
|
+
return this._meta.class;
|
|
225
|
+
}
|
|
226
|
+
get properties() {
|
|
227
|
+
return this._meta.properties;
|
|
228
|
+
}
|
|
229
|
+
new(...params) {
|
|
230
|
+
return new this._meta.class(...params);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* @internal
|
|
234
|
+
*/
|
|
235
|
+
init() {
|
|
236
|
+
if (this.initialized) {
|
|
237
|
+
return this;
|
|
238
|
+
}
|
|
239
|
+
this.setClass(this._meta.class);
|
|
240
|
+
// Abstract TPT entities keep their name because they have their own table
|
|
241
|
+
const isTPT = this._meta.inheritance === 'tpt' || this.isPartOfTPTHierarchy();
|
|
242
|
+
if (this._meta.abstract && !this._meta.discriminatorColumn && !isTPT) {
|
|
243
|
+
delete this._meta.name;
|
|
244
|
+
}
|
|
245
|
+
const tableName = this._meta.collection ?? this._meta.tableName;
|
|
246
|
+
if (tableName?.includes('.') && !this._meta.schema) {
|
|
247
|
+
this._meta.schema = tableName.substring(0, tableName.indexOf('.'));
|
|
248
|
+
this._meta.tableName = tableName.substring(tableName.indexOf('.') + 1);
|
|
249
|
+
}
|
|
250
|
+
this.initProperties();
|
|
251
|
+
this.initPrimaryKeys();
|
|
252
|
+
this._meta.props = Object.values(this._meta.properties);
|
|
253
|
+
this._meta.relations = this._meta.props.filter(prop => typeof prop.kind !== 'undefined' && prop.kind !== ReferenceKind.SCALAR && prop.kind !== ReferenceKind.EMBEDDED);
|
|
254
|
+
this.initialized = true;
|
|
255
|
+
return this;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Check if this entity is part of a TPT hierarchy by walking up the extends chain.
|
|
259
|
+
* This handles mid-level abstract entities (e.g., Animal -> Mammal -> Dog where Mammal is abstract).
|
|
260
|
+
*/
|
|
261
|
+
isPartOfTPTHierarchy() {
|
|
262
|
+
let parent = this._meta.extends;
|
|
263
|
+
while (parent) {
|
|
264
|
+
const parentSchema = EntitySchema.is(parent) ? parent : EntitySchema.REGISTRY.get(parent);
|
|
265
|
+
if (!parentSchema) {
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
if (parentSchema._meta.inheritance === 'tpt') {
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
parent = parentSchema._meta.extends;
|
|
272
|
+
}
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
initProperties() {
|
|
276
|
+
Utils.entries(this._meta.properties).forEach(([name, options]) => {
|
|
277
|
+
if (Type.isMappedType(options.type)) {
|
|
278
|
+
options.type ??= options.type.constructor.name;
|
|
279
|
+
}
|
|
280
|
+
switch (options.kind) {
|
|
281
|
+
case ReferenceKind.ONE_TO_ONE:
|
|
282
|
+
this.addOneToOne(name, options.type, options);
|
|
283
|
+
break;
|
|
284
|
+
case ReferenceKind.ONE_TO_MANY:
|
|
285
|
+
this.addOneToMany(name, options.type, options);
|
|
286
|
+
break;
|
|
287
|
+
case ReferenceKind.MANY_TO_ONE:
|
|
288
|
+
this.addManyToOne(name, options.type, options);
|
|
289
|
+
break;
|
|
290
|
+
case ReferenceKind.MANY_TO_MANY:
|
|
291
|
+
this.addManyToMany(name, options.type, options);
|
|
292
|
+
break;
|
|
293
|
+
case ReferenceKind.EMBEDDED:
|
|
294
|
+
this.addEmbedded(name, options);
|
|
295
|
+
break;
|
|
296
|
+
default:
|
|
297
|
+
if (options.enum) {
|
|
298
|
+
this.addEnum(name, options.type, options);
|
|
299
|
+
}
|
|
300
|
+
else if (options.primary) {
|
|
301
|
+
this.addPrimaryKey(name, options.type, options);
|
|
302
|
+
}
|
|
303
|
+
else if (options.serializedPrimaryKey) {
|
|
304
|
+
this.addSerializedPrimaryKey(name, options.type, options);
|
|
305
|
+
}
|
|
306
|
+
else if (options.version) {
|
|
307
|
+
this.addVersion(name, options.type, options);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
this.addProperty(name, options.type, options);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
initPrimaryKeys() {
|
|
316
|
+
const pks = Object.values(this._meta.properties).filter(prop => prop.primary);
|
|
317
|
+
if (pks.length > 0) {
|
|
318
|
+
this._meta.primaryKeys = pks.map(prop => prop.name);
|
|
319
|
+
this._meta.compositePK = pks.length > 1;
|
|
320
|
+
this._meta.simplePK = !this._meta.compositePK && pks[0].kind === ReferenceKind.SCALAR && !pks[0].customType;
|
|
321
|
+
}
|
|
322
|
+
if (pks.length === 1 && ['number', 'bigint'].includes(pks[0].type)) {
|
|
323
|
+
pks[0].autoincrement ??= true;
|
|
324
|
+
}
|
|
325
|
+
const serializedPrimaryKey = Object.values(this._meta.properties).find(prop => prop.serializedPrimaryKey);
|
|
326
|
+
if (serializedPrimaryKey) {
|
|
327
|
+
this._meta.serializedPrimaryKey = serializedPrimaryKey.name;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
normalizeType(options, type) {
|
|
331
|
+
if ('entity' in options) {
|
|
332
|
+
/* v8 ignore next */
|
|
333
|
+
if (typeof options.entity === 'string') {
|
|
334
|
+
throw new Error(`Relation target needs to be an entity class or EntitySchema instance, string '${options.entity}' given instead for ${this._meta.className}.${options.name}.`);
|
|
335
|
+
}
|
|
336
|
+
else if (options.entity) {
|
|
337
|
+
const tmp = options.entity();
|
|
338
|
+
type = options.type = Array.isArray(tmp)
|
|
339
|
+
? tmp
|
|
340
|
+
.map(t => Utils.className(t))
|
|
341
|
+
.sort()
|
|
342
|
+
.join(' | ')
|
|
343
|
+
: Utils.className(tmp);
|
|
344
|
+
const target = EntitySchema.is(tmp) ? tmp.meta.class : tmp;
|
|
345
|
+
return { type, target };
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (type instanceof Function) {
|
|
349
|
+
type = type.name;
|
|
350
|
+
}
|
|
351
|
+
if (['String', 'Number', 'Boolean', 'Array'].includes(type)) {
|
|
352
|
+
type = type.toLowerCase();
|
|
353
|
+
}
|
|
354
|
+
return { type };
|
|
355
|
+
}
|
|
356
|
+
createProperty(kind, options) {
|
|
357
|
+
return {
|
|
358
|
+
kind,
|
|
359
|
+
cascade: [Cascade.PERSIST],
|
|
360
|
+
...options,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
rename(data, from, to) {
|
|
364
|
+
if (from in data && !(to in data)) {
|
|
365
|
+
// @ts-ignore
|
|
366
|
+
data[to] = [data[from]];
|
|
367
|
+
// @ts-ignore
|
|
368
|
+
delete data[from];
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
renameCompositeOptions(name, options = {}) {
|
|
372
|
+
if (name !== options.name && !options.fieldNames) {
|
|
373
|
+
Utils.renameKey(options, 'name', 'fieldName');
|
|
374
|
+
}
|
|
375
|
+
else if (options.name && (options.fieldNames?.length ?? 0) > 1) {
|
|
376
|
+
delete options.name;
|
|
377
|
+
}
|
|
378
|
+
this.rename(options, 'fieldName', 'fieldNames');
|
|
379
|
+
this.rename(options, 'joinColumn', 'joinColumns');
|
|
380
|
+
this.rename(options, 'inverseJoinColumn', 'inverseJoinColumns');
|
|
381
|
+
this.rename(options, 'referenceColumnName', 'referencedColumnNames');
|
|
382
|
+
this.rename(options, 'columnType', 'columnTypes');
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Adds a lifecycle hook handler to the entity schema.
|
|
386
|
+
* This method allows registering hooks after the entity is defined,
|
|
387
|
+
* which can be useful for avoiding circular type references.
|
|
388
|
+
*
|
|
389
|
+
* @example
|
|
390
|
+
* ```ts
|
|
391
|
+
* export const Article = defineEntity({
|
|
392
|
+
* name: 'Article',
|
|
393
|
+
* properties: { ... },
|
|
394
|
+
* });
|
|
395
|
+
*
|
|
396
|
+
* Article.addHook('beforeCreate', async args => {
|
|
397
|
+
* args.entity.slug = args.entity.title.toLowerCase();
|
|
398
|
+
* });
|
|
399
|
+
* ```
|
|
400
|
+
*/
|
|
401
|
+
addHook(event, handler) {
|
|
402
|
+
this._meta.hooks[event] ??= [];
|
|
403
|
+
this._meta.hooks[event].push(handler);
|
|
404
|
+
return this;
|
|
405
|
+
}
|
|
405
406
|
}
|