@mikro-orm/core 7.0.0-dev.2 → 7.0.0-dev.21
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 +13 -5
- package/EntityManager.js +60 -40
- package/MikroORM.js +2 -2
- package/cache/FileCacheAdapter.js +2 -2
- package/decorators/Check.d.ts +2 -2
- package/decorators/CreateRequestContext.js +4 -1
- package/decorators/Embeddable.d.ts +5 -5
- package/decorators/Embeddable.js +1 -1
- package/decorators/Embedded.d.ts +6 -12
- package/decorators/Entity.d.ts +5 -5
- package/decorators/Entity.js +0 -1
- package/decorators/Enum.d.ts +1 -1
- package/decorators/Formula.d.ts +1 -2
- package/decorators/Indexed.d.ts +9 -7
- package/decorators/Indexed.js +1 -1
- package/decorators/ManyToMany.d.ts +2 -2
- package/decorators/ManyToOne.d.ts +4 -2
- package/decorators/OneToMany.d.ts +4 -4
- package/decorators/OneToOne.d.ts +3 -1
- package/decorators/PrimaryKey.d.ts +2 -3
- package/decorators/Property.d.ts +1 -1
- package/drivers/IDatabaseDriver.d.ts +4 -1
- package/entity/ArrayCollection.d.ts +1 -1
- package/entity/ArrayCollection.js +11 -4
- package/entity/Collection.d.ts +1 -2
- package/entity/Collection.js +14 -9
- package/entity/EntityFactory.js +4 -1
- package/entity/EntityHelper.js +3 -0
- package/entity/EntityLoader.d.ts +3 -2
- package/entity/EntityLoader.js +20 -6
- package/entity/Reference.d.ts +3 -7
- package/enums.d.ts +1 -1
- package/events/EventSubscriber.d.ts +3 -1
- package/exports.d.ts +24 -0
- package/exports.js +23 -0
- package/hydration/ObjectHydrator.js +1 -0
- package/index.d.ts +1 -1
- package/metadata/EntitySchema.d.ts +6 -4
- package/metadata/EntitySchema.js +23 -17
- package/metadata/MetadataDiscovery.js +25 -12
- package/metadata/MetadataValidator.js +4 -3
- package/package.json +7 -6
- package/types/BigIntType.d.ts +1 -0
- package/types/BigIntType.js +3 -0
- package/typings.d.ts +17 -10
- package/typings.js +3 -0
- package/unit-of-work/ChangeSetPersister.js +7 -1
- package/unit-of-work/UnitOfWork.js +25 -9
- package/utils/AbstractSchemaGenerator.js +5 -2
- package/utils/Configuration.d.ts +1 -1
- package/utils/Configuration.js +1 -1
- package/utils/Cursor.d.ts +3 -3
- package/utils/DataloaderUtils.d.ts +1 -1
- package/utils/DataloaderUtils.js +19 -5
- package/utils/EntityComparator.js +65 -49
- package/utils/QueryHelper.js +1 -1
- package/utils/RawQueryFragment.js +6 -1
- package/utils/Utils.d.ts +8 -2
- package/utils/Utils.js +26 -6
package/EntityManager.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { EntityFactory } from './entity/EntityFactory.js';
|
|
|
6
6
|
import { type AssignOptions } from './entity/EntityAssigner.js';
|
|
7
7
|
import { EntityValidator } from './entity/EntityValidator.js';
|
|
8
8
|
import { type EntityRepository } from './entity/EntityRepository.js';
|
|
9
|
-
import { type EntityLoaderOptions } from './entity/EntityLoader.js';
|
|
9
|
+
import { EntityLoader, type EntityLoaderOptions } from './entity/EntityLoader.js';
|
|
10
10
|
import { Reference } from './entity/Reference.js';
|
|
11
11
|
import { UnitOfWork } from './unit-of-work/UnitOfWork.js';
|
|
12
12
|
import type { CountOptions, DeleteOptions, FindAllOptions, FindByCursorOptions, FindOneOptions, FindOneOrFailOptions, FindOptions, GetReferenceOptions, IDatabaseDriver, LockOptions, NativeInsertUpdateOptions, UpdateOptions, UpsertManyOptions, UpsertOptions } from './drivers/IDatabaseDriver.js';
|
|
@@ -171,6 +171,10 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
171
171
|
* });
|
|
172
172
|
* ```
|
|
173
173
|
*
|
|
174
|
+
* The options also support an `includeCount` (true by default) option. If set to false, the `totalCount` is not
|
|
175
|
+
* returned as part of the cursor. This is useful for performance reason, when you don't care about the total number
|
|
176
|
+
* of pages.
|
|
177
|
+
*
|
|
174
178
|
* The `Cursor` object provides the following interface:
|
|
175
179
|
*
|
|
176
180
|
* ```ts
|
|
@@ -180,7 +184,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
180
184
|
* User { ... },
|
|
181
185
|
* User { ... },
|
|
182
186
|
* ],
|
|
183
|
-
* totalCount: 50,
|
|
187
|
+
* totalCount: 50, // not included if `includeCount: false`
|
|
184
188
|
* startCursor: 'WzRd',
|
|
185
189
|
* endCursor: 'WzZd',
|
|
186
190
|
* hasPrevPage: true,
|
|
@@ -188,7 +192,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
188
192
|
* }
|
|
189
193
|
* ```
|
|
190
194
|
*/
|
|
191
|
-
findByCursor<Entity extends object, Hint extends string = never, Fields extends string = '*', Excludes extends string = never>(entityName: EntityName<Entity>, where: FilterQuery<NoInfer<Entity>>, options: FindByCursorOptions<Entity, Hint, Fields, Excludes>): Promise<Cursor<Entity, Hint, Fields, Excludes>>;
|
|
195
|
+
findByCursor<Entity extends object, Hint extends string = never, Fields extends string = '*', Excludes extends string = never, IncludeCount extends boolean = true>(entityName: EntityName<Entity>, where: FilterQuery<NoInfer<Entity>>, options: FindByCursorOptions<Entity, Hint, Fields, Excludes, IncludeCount>): Promise<Cursor<Entity, Hint, Fields, Excludes, IncludeCount>>;
|
|
192
196
|
/**
|
|
193
197
|
* Refreshes the persistent state of an entity from the database, overriding any local changes that have not yet been
|
|
194
198
|
* persisted. Returns the same entity instance (same object reference), but re-hydrated. If the entity is no longer
|
|
@@ -419,7 +423,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
419
423
|
/**
|
|
420
424
|
* Loads specified relations in batch. This will execute one query for each relation, that will populate it on all the specified entities.
|
|
421
425
|
*/
|
|
422
|
-
populate<Entity extends object, Naked extends FromEntityType<UnboxArray<Entity>> = FromEntityType<UnboxArray<Entity>>, Hint extends string = never, Fields extends string = '*', Excludes extends string = never>(entities: Entity, populate: AutoPath<Naked, Hint, PopulatePath.ALL>[] | false, options?: EntityLoaderOptions<Naked, Fields, Excludes>): Promise<Entity extends object[] ? MergeLoaded<ArrayElement<Entity>, Naked, Hint, Fields, Excludes>[] : MergeLoaded<Entity, Naked, Hint, Fields, Excludes>>;
|
|
426
|
+
populate<Entity extends object, Naked extends FromEntityType<UnboxArray<Entity>> = FromEntityType<UnboxArray<Entity>>, Hint extends string = never, Fields extends string = '*', Excludes extends string = never>(entities: Entity, populate: readonly AutoPath<Naked, Hint, PopulatePath.ALL>[] | false, options?: EntityLoaderOptions<Naked, Fields, Excludes>): Promise<Entity extends object[] ? MergeLoaded<ArrayElement<Entity>, Naked, Hint, Fields, Excludes>[] : MergeLoaded<Entity, Naked, Hint, Fields, Excludes>>;
|
|
423
427
|
/**
|
|
424
428
|
* Returns new EntityManager instance with its own identity map
|
|
425
429
|
*/
|
|
@@ -432,6 +436,10 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
432
436
|
* Gets the EntityFactory used by the EntityManager.
|
|
433
437
|
*/
|
|
434
438
|
getEntityFactory(): EntityFactory;
|
|
439
|
+
/**
|
|
440
|
+
* @internal use `em.populate()` as the user facing API, this is exposed only for internal usage
|
|
441
|
+
*/
|
|
442
|
+
getEntityLoader(): EntityLoader;
|
|
435
443
|
/**
|
|
436
444
|
* Gets the Hydrator used by the EntityManager.
|
|
437
445
|
*/
|
|
@@ -488,7 +496,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
488
496
|
* @internal
|
|
489
497
|
*/
|
|
490
498
|
tryCache<T extends object, R>(entityName: string, config: boolean | number | [string, number] | undefined, key: unknown, refresh?: boolean, merge?: boolean): Promise<{
|
|
491
|
-
data?: R;
|
|
499
|
+
data?: R | null;
|
|
492
500
|
key: string;
|
|
493
501
|
} | undefined>;
|
|
494
502
|
/**
|
package/EntityManager.js
CHANGED
|
@@ -149,7 +149,7 @@ export class EntityManager {
|
|
|
149
149
|
options._populateWhere = options.populateWhere ?? this.config.get('populateWhere');
|
|
150
150
|
options.populateWhere = this.createPopulateWhere({ ...where }, options);
|
|
151
151
|
options.populateFilter = await this.getJoinedFilters(meta, { ...where }, options);
|
|
152
|
-
const results = await em.driver.find(entityName, where, { ctx: em.transactionContext, ...options });
|
|
152
|
+
const results = await em.driver.find(entityName, where, { ctx: em.transactionContext, em, ...options });
|
|
153
153
|
if (results.length === 0) {
|
|
154
154
|
await em.storeCache(options.cache, cached, []);
|
|
155
155
|
return [];
|
|
@@ -250,7 +250,7 @@ export class EntityManager {
|
|
|
250
250
|
aliased: type === 'read',
|
|
251
251
|
});
|
|
252
252
|
where = (await this.applyFilters(entityName, where, options.filters ?? {}, type, options));
|
|
253
|
-
where =
|
|
253
|
+
where = this.applyDiscriminatorCondition(entityName, where);
|
|
254
254
|
return where;
|
|
255
255
|
}
|
|
256
256
|
// this method only handles the problem for mongo driver, SQL drivers have their implementation inside QueryBuilder
|
|
@@ -367,7 +367,7 @@ export class EntityManager {
|
|
|
367
367
|
if (!args && filter.cond.length > 0 && filter.args !== false) {
|
|
368
368
|
throw new Error(`No arguments provided for filter '${filter.name}'`);
|
|
369
369
|
}
|
|
370
|
-
cond = await filter.cond(args, type, this, findOptions);
|
|
370
|
+
cond = await filter.cond(args, type, this, findOptions, entityName);
|
|
371
371
|
}
|
|
372
372
|
else {
|
|
373
373
|
cond = filter.cond;
|
|
@@ -433,6 +433,10 @@ export class EntityManager {
|
|
|
433
433
|
* });
|
|
434
434
|
* ```
|
|
435
435
|
*
|
|
436
|
+
* The options also support an `includeCount` (true by default) option. If set to false, the `totalCount` is not
|
|
437
|
+
* returned as part of the cursor. This is useful for performance reason, when you don't care about the total number
|
|
438
|
+
* of pages.
|
|
439
|
+
*
|
|
436
440
|
* The `Cursor` object provides the following interface:
|
|
437
441
|
*
|
|
438
442
|
* ```ts
|
|
@@ -442,7 +446,7 @@ export class EntityManager {
|
|
|
442
446
|
* User { ... },
|
|
443
447
|
* User { ... },
|
|
444
448
|
* ],
|
|
445
|
-
* totalCount: 50,
|
|
449
|
+
* totalCount: 50, // not included if `includeCount: false`
|
|
446
450
|
* startCursor: 'WzRd',
|
|
447
451
|
* endCursor: 'WzZd',
|
|
448
452
|
* hasPrevPage: true,
|
|
@@ -457,7 +461,9 @@ export class EntityManager {
|
|
|
457
461
|
if (Utils.isEmpty(options.orderBy)) {
|
|
458
462
|
throw new Error('Explicit `orderBy` option required');
|
|
459
463
|
}
|
|
460
|
-
const [entities, count] =
|
|
464
|
+
const [entities, count] = options.includeCount !== false
|
|
465
|
+
? await em.findAndCount(entityName, where, options)
|
|
466
|
+
: [await em.find(entityName, where, options)];
|
|
461
467
|
return new Cursor(entities, count, options, this.metadata.get(entityName));
|
|
462
468
|
}
|
|
463
469
|
/**
|
|
@@ -530,14 +536,16 @@ export class EntityManager {
|
|
|
530
536
|
options.populate = await em.preparePopulate(entityName, options);
|
|
531
537
|
const cacheKey = em.cacheKey(entityName, options, 'em.findOne', where);
|
|
532
538
|
const cached = await em.tryCache(entityName, options.cache, cacheKey, options.refresh, true);
|
|
533
|
-
if (cached?.data) {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
539
|
+
if (cached?.data !== undefined) {
|
|
540
|
+
if (cached.data) {
|
|
541
|
+
await em.entityLoader.populate(entityName, [cached.data], options.populate, {
|
|
542
|
+
...options,
|
|
543
|
+
...em.getPopulateWhere(where, options),
|
|
544
|
+
convertCustomTypes: false,
|
|
545
|
+
ignoreLazyScalarProperties: true,
|
|
546
|
+
lookup: false,
|
|
547
|
+
});
|
|
548
|
+
}
|
|
541
549
|
return cached.data;
|
|
542
550
|
}
|
|
543
551
|
options = { ...options };
|
|
@@ -547,6 +555,7 @@ export class EntityManager {
|
|
|
547
555
|
options.populateFilter = await this.getJoinedFilters(meta, { ...where }, options);
|
|
548
556
|
const data = await em.driver.findOne(entityName, where, {
|
|
549
557
|
ctx: em.transactionContext,
|
|
558
|
+
em,
|
|
550
559
|
...options,
|
|
551
560
|
});
|
|
552
561
|
if (!data) {
|
|
@@ -716,8 +725,9 @@ export class EntityManager {
|
|
|
716
725
|
ctx: em.transactionContext,
|
|
717
726
|
convertCustomTypes: true,
|
|
718
727
|
connectionType: 'write',
|
|
728
|
+
schema: options.schema,
|
|
719
729
|
});
|
|
720
|
-
em.getHydrator().hydrate(entity, meta, data2, em.entityFactory, 'full');
|
|
730
|
+
em.getHydrator().hydrate(entity, meta, data2, em.entityFactory, 'full', false, true);
|
|
721
731
|
}
|
|
722
732
|
// recompute the data as there might be some values missing (e.g. those with db column defaults)
|
|
723
733
|
const snapshot = this.comparator.prepareEntity(entity);
|
|
@@ -896,6 +906,7 @@ export class EntityManager {
|
|
|
896
906
|
ctx: em.transactionContext,
|
|
897
907
|
convertCustomTypes: true,
|
|
898
908
|
connectionType: 'write',
|
|
909
|
+
schema: options.schema,
|
|
899
910
|
});
|
|
900
911
|
for (const [entity, cond] of loadPK.entries()) {
|
|
901
912
|
const row = data2.find(row => {
|
|
@@ -911,7 +922,7 @@ export class EntityManager {
|
|
|
911
922
|
if (!row) {
|
|
912
923
|
throw new Error(`Cannot find matching entity for condition ${JSON.stringify(cond)}`);
|
|
913
924
|
}
|
|
914
|
-
em.getHydrator().hydrate(entity, meta, row, em.entityFactory, 'full');
|
|
925
|
+
em.getHydrator().hydrate(entity, meta, row, em.entityFactory, 'full', false, true);
|
|
915
926
|
}
|
|
916
927
|
if (loadPK.size !== data2.length && Array.isArray(uniqueFields)) {
|
|
917
928
|
for (let i = 0; i < allData.length; i++) {
|
|
@@ -1266,7 +1277,7 @@ export class EntityManager {
|
|
|
1266
1277
|
delete options.orderBy;
|
|
1267
1278
|
const cacheKey = em.cacheKey(entityName, options, 'em.count', where);
|
|
1268
1279
|
const cached = await em.tryCache(entityName, options.cache, cacheKey);
|
|
1269
|
-
if (cached?.data) {
|
|
1280
|
+
if (cached?.data !== undefined) {
|
|
1270
1281
|
return cached.data;
|
|
1271
1282
|
}
|
|
1272
1283
|
const count = await em.driver.count(entityName, where, { ctx: em.transactionContext, ...options });
|
|
@@ -1431,6 +1442,9 @@ export class EntityManager {
|
|
|
1431
1442
|
for (const entity of em.unitOfWork.getIdentityMap()) {
|
|
1432
1443
|
fork.unitOfWork.register(entity);
|
|
1433
1444
|
}
|
|
1445
|
+
for (const entity of em.unitOfWork.getPersistStack()) {
|
|
1446
|
+
fork.unitOfWork.persist(entity);
|
|
1447
|
+
}
|
|
1434
1448
|
for (const entity of em.unitOfWork.getOrphanRemoveStack()) {
|
|
1435
1449
|
fork.unitOfWork.getOrphanRemoveStack().add(entity);
|
|
1436
1450
|
}
|
|
@@ -1452,6 +1466,12 @@ export class EntityManager {
|
|
|
1452
1466
|
getEntityFactory() {
|
|
1453
1467
|
return this.getContext().entityFactory;
|
|
1454
1468
|
}
|
|
1469
|
+
/**
|
|
1470
|
+
* @internal use `em.populate()` as the user facing API, this is exposed only for internal usage
|
|
1471
|
+
*/
|
|
1472
|
+
getEntityLoader() {
|
|
1473
|
+
return this.getContext().entityLoader;
|
|
1474
|
+
}
|
|
1455
1475
|
/**
|
|
1456
1476
|
* Gets the Hydrator used by the EntityManager.
|
|
1457
1477
|
*/
|
|
@@ -1695,31 +1715,31 @@ export class EntityManager {
|
|
|
1695
1715
|
const em = this.getContext();
|
|
1696
1716
|
const cacheKey = Array.isArray(config) ? config[0] : JSON.stringify(key);
|
|
1697
1717
|
const cached = await em.resultCache.get(cacheKey);
|
|
1698
|
-
if (cached) {
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
return { key: cacheKey, data };
|
|
1718
|
+
if (!cached) {
|
|
1719
|
+
return { key: cacheKey, data: cached };
|
|
1720
|
+
}
|
|
1721
|
+
let data;
|
|
1722
|
+
if (Array.isArray(cached) && merge) {
|
|
1723
|
+
data = cached.map(item => em.entityFactory.create(entityName, item, {
|
|
1724
|
+
merge: true,
|
|
1725
|
+
convertCustomTypes: true,
|
|
1726
|
+
refresh,
|
|
1727
|
+
recomputeSnapshot: true,
|
|
1728
|
+
}));
|
|
1729
|
+
}
|
|
1730
|
+
else if (Utils.isObject(cached) && merge) {
|
|
1731
|
+
data = em.entityFactory.create(entityName, cached, {
|
|
1732
|
+
merge: true,
|
|
1733
|
+
convertCustomTypes: true,
|
|
1734
|
+
refresh,
|
|
1735
|
+
recomputeSnapshot: true,
|
|
1736
|
+
});
|
|
1737
|
+
}
|
|
1738
|
+
else {
|
|
1739
|
+
data = cached;
|
|
1721
1740
|
}
|
|
1722
|
-
|
|
1741
|
+
await em.unitOfWork.dispatchOnLoadEvent();
|
|
1742
|
+
return { key: cacheKey, data };
|
|
1723
1743
|
}
|
|
1724
1744
|
/**
|
|
1725
1745
|
* @internal
|
package/MikroORM.js
CHANGED
|
@@ -24,7 +24,7 @@ export class MikroORM {
|
|
|
24
24
|
*/
|
|
25
25
|
static async init(options) {
|
|
26
26
|
ConfigurationLoader.registerDotenv(options);
|
|
27
|
-
const coreVersion =
|
|
27
|
+
const coreVersion = ConfigurationLoader.checkPackageVersion();
|
|
28
28
|
const env = await ConfigurationLoader.loadEnvironmentVars();
|
|
29
29
|
if (!options) {
|
|
30
30
|
const configPathFromArg = ConfigurationLoader.configPathsFromArg();
|
|
@@ -35,7 +35,7 @@ export class MikroORM {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
options = Utils.mergeConfig(options, env);
|
|
38
|
-
|
|
38
|
+
ConfigurationLoader.commonJSCompat(options);
|
|
39
39
|
if ('DRIVER' in this && !options.driver) {
|
|
40
40
|
options.driver = this.DRIVER;
|
|
41
41
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { globSync } from 'tinyglobby';
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
3
3
|
import { Utils } from '../utils/Utils.js';
|
|
4
4
|
export class FileCacheAdapter {
|
|
@@ -51,7 +51,7 @@ export class FileCacheAdapter {
|
|
|
51
51
|
*/
|
|
52
52
|
clear() {
|
|
53
53
|
const path = this.path('*');
|
|
54
|
-
const files =
|
|
54
|
+
const files = globSync(path);
|
|
55
55
|
files.forEach(file => unlinkSync(file));
|
|
56
56
|
this.cache = {};
|
|
57
57
|
}
|
package/decorators/Check.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { CheckConstraint } from '../typings.js';
|
|
2
|
-
export declare function Check<T>(options: CheckOptions<T>): (target:
|
|
1
|
+
import type { CheckConstraint, EntityClass } from '../typings.js';
|
|
2
|
+
export declare function Check<T>(options: CheckOptions<T>): (target: T, propertyName?: T extends EntityClass<unknown> ? undefined : keyof T) => any;
|
|
3
3
|
export type CheckOptions<T = any> = CheckConstraint<T>;
|
|
@@ -4,10 +4,13 @@ import { TransactionContext } from '../utils/TransactionContext.js';
|
|
|
4
4
|
export function CreateRequestContext(context, respectExistingContext = false) {
|
|
5
5
|
return function (target, propertyKey, descriptor) {
|
|
6
6
|
const originalMethod = descriptor.value;
|
|
7
|
+
const name = respectExistingContext ? 'EnsureRequestContext' : 'CreateRequestContext';
|
|
8
|
+
if (originalMethod.constructor.name !== 'AsyncFunction') {
|
|
9
|
+
throw new Error(`@${name}() should be use with async functions`);
|
|
10
|
+
}
|
|
7
11
|
descriptor.value = async function (...args) {
|
|
8
12
|
const em = await resolveContextProvider(this, context);
|
|
9
13
|
if (!em) {
|
|
10
|
-
const name = respectExistingContext ? 'EnsureRequestContext' : 'CreateRequestContext';
|
|
11
14
|
throw new Error(`@${name}() decorator can only be applied to methods of classes with \`orm: MikroORM\` property, \`em: EntityManager\` property, or with a callback parameter like \`@${name}(() => orm)\` that returns one of those types. The parameter will contain a reference to current \`this\`. Returning an EntityRepository from it is also supported.`);
|
|
12
15
|
}
|
|
13
16
|
// reuse existing context if available for given respect `contextName`
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { Dictionary } from '../typings.js';
|
|
2
|
-
export declare function Embeddable(options?: EmbeddableOptions):
|
|
3
|
-
export
|
|
4
|
-
discriminatorColumn?: string;
|
|
1
|
+
import type { AnyString, Dictionary, EntityClass } from '../typings.js';
|
|
2
|
+
export declare function Embeddable<T>(options?: EmbeddableOptions<T>): (target: T) => T;
|
|
3
|
+
export interface EmbeddableOptions<T> {
|
|
4
|
+
discriminatorColumn?: (T extends EntityClass<infer P> ? keyof P : string) | AnyString;
|
|
5
5
|
discriminatorMap?: Dictionary<string>;
|
|
6
6
|
discriminatorValue?: number | string;
|
|
7
7
|
abstract?: boolean;
|
|
8
|
-
}
|
|
8
|
+
}
|
package/decorators/Embeddable.js
CHANGED
|
@@ -3,7 +3,7 @@ export function Embeddable(options = {}) {
|
|
|
3
3
|
return function (target) {
|
|
4
4
|
const meta = MetadataStorage.getMetadataFromDecorator(target);
|
|
5
5
|
meta.class = target;
|
|
6
|
-
meta.name =
|
|
6
|
+
meta.name = meta.class.name;
|
|
7
7
|
meta.embeddable = true;
|
|
8
8
|
Object.assign(meta, options);
|
|
9
9
|
return target;
|
package/decorators/Embedded.d.ts
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import type { AnyEntity } from '../typings.js';
|
|
2
|
-
|
|
1
|
+
import type { AnyEntity, EntityName } from '../typings.js';
|
|
2
|
+
import type { PropertyOptions } from './Property.js';
|
|
3
|
+
export declare function Embedded<Owner extends object, Target>(type?: EmbeddedOptions<Owner, Target> | (() => EntityName<Target> | EntityName<Target>[]), options?: EmbeddedOptions<Owner, Target>): (target: AnyEntity, propertyName: string) => any;
|
|
3
4
|
/** With `absolute` the prefix is set at the root of the entity (regardless of the nesting level) */
|
|
4
5
|
export type EmbeddedPrefixMode = 'absolute' | 'relative';
|
|
5
|
-
export
|
|
6
|
-
entity?: string | (() =>
|
|
7
|
-
type?: string;
|
|
6
|
+
export interface EmbeddedOptions<Owner, Target> extends PropertyOptions<Owner> {
|
|
7
|
+
entity?: string | (() => EntityName<Target> | EntityName<Target>[]);
|
|
8
8
|
prefix?: string | boolean;
|
|
9
9
|
prefixMode?: EmbeddedPrefixMode;
|
|
10
|
-
nullable?: boolean;
|
|
11
10
|
object?: boolean;
|
|
12
11
|
array?: boolean;
|
|
13
|
-
|
|
14
|
-
serializer?: (value: any) => any;
|
|
15
|
-
serializedName?: string;
|
|
16
|
-
groups?: string[];
|
|
17
|
-
persist?: boolean;
|
|
18
|
-
};
|
|
12
|
+
}
|
package/decorators/Entity.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { Constructor, Dictionary,
|
|
1
|
+
import type { AnyString, Constructor, Dictionary, EntityClass, ObjectQuery } from '../typings.js';
|
|
2
2
|
import type { FindOptions } from '../drivers/IDatabaseDriver.js';
|
|
3
|
-
export declare function Entity(options?: EntityOptions<
|
|
4
|
-
export type EntityOptions<T> = {
|
|
3
|
+
export declare function Entity<T extends EntityClass<unknown>>(options?: EntityOptions<T>): (target: T) => void;
|
|
4
|
+
export type EntityOptions<T, E = T extends EntityClass<infer P> ? P : T> = {
|
|
5
5
|
tableName?: string;
|
|
6
6
|
schema?: string;
|
|
7
7
|
collection?: string;
|
|
8
|
-
discriminatorColumn?: string;
|
|
8
|
+
discriminatorColumn?: (T extends EntityClass<infer P> ? keyof P : string) | AnyString;
|
|
9
9
|
discriminatorMap?: Dictionary<string>;
|
|
10
10
|
discriminatorValue?: number | string;
|
|
11
11
|
forceConstructor?: boolean;
|
|
@@ -13,6 +13,6 @@ export type EntityOptions<T> = {
|
|
|
13
13
|
abstract?: boolean;
|
|
14
14
|
readonly?: boolean;
|
|
15
15
|
virtual?: boolean;
|
|
16
|
-
expression?: string | ((em: any, where:
|
|
16
|
+
expression?: string | ((em: any, where: ObjectQuery<E>, options: FindOptions<E, any, any, any>) => object);
|
|
17
17
|
repository?: () => Constructor;
|
|
18
18
|
};
|
package/decorators/Entity.js
CHANGED
package/decorators/Enum.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PropertyOptions } from './Property.js';
|
|
2
2
|
import type { AnyEntity, Dictionary } from '../typings.js';
|
|
3
|
-
export declare function Enum<T extends object>(options?: EnumOptions<AnyEntity> | (() => Dictionary)): (target:
|
|
3
|
+
export declare function Enum<T extends object>(options?: EnumOptions<AnyEntity> | (() => Dictionary)): (target: T, propertyName: string) => any;
|
|
4
4
|
export interface EnumOptions<T> extends PropertyOptions<T> {
|
|
5
5
|
items?: (number | string)[] | (() => Dictionary);
|
|
6
6
|
array?: boolean;
|
package/decorators/Formula.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { AnyEntity } from '../typings.js';
|
|
2
1
|
import type { PropertyOptions } from './Property.js';
|
|
3
|
-
export declare function Formula<T extends object>(formula: string | ((alias: string) => string), options?: FormulaOptions<T>): (target:
|
|
2
|
+
export declare function Formula<T extends object>(formula: string | ((alias: string) => string), options?: FormulaOptions<T>): (target: T, propertyName: string) => any;
|
|
4
3
|
export interface FormulaOptions<T> extends PropertyOptions<T> {
|
|
5
4
|
}
|
package/decorators/Indexed.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EntityClass, Dictionary, AutoPath } from '../typings.js';
|
|
2
2
|
import type { DeferMode } from '../enums.js';
|
|
3
|
-
export declare function Index<T>(options?: IndexOptions<T>): (target:
|
|
4
|
-
export declare function Unique<T>(options?: UniqueOptions<T>): (target:
|
|
5
|
-
|
|
3
|
+
export declare function Index<T extends object, H extends string>(options?: IndexOptions<T, H>): (target: T, propertyName?: (T extends EntityClass<unknown> ? undefined : keyof T) | undefined) => any;
|
|
4
|
+
export declare function Unique<T extends object, H extends string>(options?: UniqueOptions<T, H>): (target: T, propertyName?: (T extends EntityClass<unknown> ? undefined : keyof T) | undefined) => any;
|
|
5
|
+
type MaybeArray<T> = T | T[];
|
|
6
|
+
type Properties<T, H extends string> = MaybeArray<AutoPath<T, H>>;
|
|
7
|
+
interface BaseOptions<T, H extends string> {
|
|
6
8
|
name?: string;
|
|
7
|
-
properties?:
|
|
9
|
+
properties?: (T extends EntityClass<infer P> ? Properties<P, H> : Properties<T, H>);
|
|
8
10
|
options?: Dictionary;
|
|
9
11
|
expression?: string;
|
|
10
12
|
}
|
|
11
|
-
export interface UniqueOptions<T> extends BaseOptions<T> {
|
|
13
|
+
export interface UniqueOptions<T, H extends string = string> extends BaseOptions<T, H> {
|
|
12
14
|
deferMode?: DeferMode | `${DeferMode}`;
|
|
13
15
|
}
|
|
14
|
-
export interface IndexOptions<T> extends BaseOptions<T> {
|
|
16
|
+
export interface IndexOptions<T, H extends string = string> extends BaseOptions<T, H> {
|
|
15
17
|
type?: string;
|
|
16
18
|
}
|
|
17
19
|
export {};
|
package/decorators/Indexed.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Utils } from '../utils/Utils.js';
|
|
|
3
3
|
function createDecorator(options, unique) {
|
|
4
4
|
return function (target, propertyName) {
|
|
5
5
|
const meta = MetadataStorage.getMetadataFromDecorator(propertyName ? target.constructor : target);
|
|
6
|
-
options.properties
|
|
6
|
+
options.properties ??= propertyName;
|
|
7
7
|
const key = unique ? 'uniques' : 'indexes';
|
|
8
8
|
meta[key].push(options);
|
|
9
9
|
if (!propertyName) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReferenceOptions } from './Property.js';
|
|
2
|
-
import type { EntityName,
|
|
2
|
+
import type { EntityName, FilterQuery, AnyString } from '../typings.js';
|
|
3
3
|
import { type QueryOrderMap } from '../enums.js';
|
|
4
|
-
export declare function ManyToMany<
|
|
4
|
+
export declare function ManyToMany<Target extends object, Owner extends object>(entity?: ManyToManyOptions<Owner, Target> | string | (() => EntityName<Target>), mappedBy?: (string & keyof Target) | ((e: Target) => any), options?: Partial<ManyToManyOptions<Owner, Target>>): (target: Owner, propertyName: keyof Owner) => any;
|
|
5
5
|
export interface ManyToManyOptions<Owner, Target> extends ReferenceOptions<Owner, Target> {
|
|
6
6
|
/** Set this side as owning. Owning side is where the foreign key is defined. This option is not required if you use `inversedBy` or `mappedBy` to distinguish owning and inverse side. */
|
|
7
7
|
owner?: boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReferenceOptions } from './Property.js';
|
|
2
2
|
import { type DeferMode } from '../enums.js';
|
|
3
|
-
import type {
|
|
4
|
-
export declare function ManyToOne<
|
|
3
|
+
import type { AnyString, EntityName } from '../typings.js';
|
|
4
|
+
export declare function ManyToOne<Target extends object, Owner extends object>(entity?: ManyToOneOptions<Owner, Target> | string | ((e?: any) => EntityName<Target>), options?: Partial<ManyToOneOptions<Owner, Target>>): (target: Owner, propertyName: keyof Owner) => any;
|
|
5
5
|
export interface ManyToOneOptions<Owner, Target> extends ReferenceOptions<Owner, Target> {
|
|
6
6
|
/** Point to the inverse side property name. */
|
|
7
7
|
inversedBy?: (string & keyof Target) | ((e: Target) => any);
|
|
@@ -27,4 +27,6 @@ export interface ManyToOneOptions<Owner, Target> extends ReferenceOptions<Owner,
|
|
|
27
27
|
updateRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
|
|
28
28
|
/** Set the constraint type. Immediate constraints are checked for each statement, while deferred ones are only checked at the end of the transaction. Only for postgres unique constraints. */
|
|
29
29
|
deferMode?: DeferMode | `${DeferMode}`;
|
|
30
|
+
/** Set a custom foreign key constraint name, overriding NamingStrategy.indexName(). */
|
|
31
|
+
foreignKeyName?: string;
|
|
30
32
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ReferenceOptions } from './Property.js';
|
|
2
2
|
import { ReferenceKind, type QueryOrderMap } from '../enums.js';
|
|
3
|
-
import type { EntityName,
|
|
4
|
-
export declare function createOneToDecorator<Target, Owner>(entity: OneToManyOptions<Owner, Target> | string | ((e?: any) => EntityName<Target>), mappedBy: (string & keyof Target) | ((e: Target) => any) | undefined, options: Partial<OneToManyOptions<Owner, Target>>, kind: ReferenceKind): (target:
|
|
5
|
-
export declare function OneToMany<Target, Owner>(entity: string | ((e?: any) => EntityName<Target>), mappedBy: (string & keyof Target) | ((e: Target) => any), options?: Partial<OneToManyOptions<Owner, Target>>): (target:
|
|
6
|
-
export declare function OneToMany<Target, Owner>(options: OneToManyOptions<Owner, Target>): (target:
|
|
3
|
+
import type { EntityName, FilterQuery } from '../typings.js';
|
|
4
|
+
export declare function createOneToDecorator<Target, Owner>(entity: OneToManyOptions<Owner, Target> | string | ((e?: any) => EntityName<Target>), mappedBy: (string & keyof Target) | ((e: Target) => any) | undefined, options: Partial<OneToManyOptions<Owner, Target>>, kind: ReferenceKind): (target: Owner, propertyName: string) => any;
|
|
5
|
+
export declare function OneToMany<Target, Owner>(entity: string | ((e?: any) => EntityName<Target>), mappedBy: (string & keyof Target) | ((e: Target) => any), options?: Partial<OneToManyOptions<Owner, Target>>): (target: Owner, propertyName: string) => void;
|
|
6
|
+
export declare function OneToMany<Target, Owner>(options: OneToManyOptions<Owner, Target>): (target: Owner, propertyName: string) => void;
|
|
7
7
|
export interface OneToManyOptions<Owner, Target> extends ReferenceOptions<Owner, Target> {
|
|
8
8
|
/** Remove the entity when it gets disconnected from the relationship (see {@doclink cascading | Cascading}). */
|
|
9
9
|
orphanRemoval?: boolean;
|
package/decorators/OneToOne.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type DeferMode } from '../enums.js';
|
|
2
2
|
import { type OneToManyOptions } from './OneToMany.js';
|
|
3
3
|
import type { AnyString, EntityName } from '../typings.js';
|
|
4
|
-
export declare function OneToOne<Target, Owner>(entity?: OneToOneOptions<Owner, Target> | string | ((e: Owner) => EntityName<Target>), mappedByOrOptions?: (string & keyof Target) | ((e: Target) => any) | Partial<OneToOneOptions<Owner, Target>>, options?: Partial<OneToOneOptions<Owner, Target>>): (target:
|
|
4
|
+
export declare function OneToOne<Target, Owner>(entity?: OneToOneOptions<Owner, Target> | string | ((e: Owner) => EntityName<Target>), mappedByOrOptions?: (string & keyof Target) | ((e: Target) => any) | Partial<OneToOneOptions<Owner, Target>>, options?: Partial<OneToOneOptions<Owner, Target>>): (target: Owner, propertyName: string) => any;
|
|
5
5
|
export interface OneToOneOptions<Owner, Target> extends Partial<Omit<OneToManyOptions<Owner, Target>, 'orderBy'>> {
|
|
6
6
|
/** Set this side as owning. Owning side is where the foreign key is defined. This option is not required if you use `inversedBy` or `mappedBy` to distinguish owning and inverse side. */
|
|
7
7
|
owner?: boolean;
|
|
@@ -21,4 +21,6 @@ export interface OneToOneOptions<Owner, Target> extends Partial<Omit<OneToManyOp
|
|
|
21
21
|
updateRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
|
|
22
22
|
/** Set the constraint type. Immediate constraints are checked for each statement, while deferred ones are only checked at the end of the transaction. Only for postgres unique constraints. */
|
|
23
23
|
deferMode?: DeferMode | `${DeferMode}`;
|
|
24
|
+
/** Set a custom foreign key constraint name, overriding NamingStrategy.indexName(). */
|
|
25
|
+
foreignKeyName?: string;
|
|
24
26
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { PropertyOptions } from './Property.js';
|
|
2
|
-
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function SerializedPrimaryKey<T extends object>(options?: SerializedPrimaryKeyOptions<T>): (target: AnyEntity, propertyName: string) => any;
|
|
2
|
+
export declare function PrimaryKey<T extends object>(options?: PrimaryKeyOptions<T>): (target: T, propertyName: string) => any;
|
|
3
|
+
export declare function SerializedPrimaryKey<T extends object>(options?: SerializedPrimaryKeyOptions<T>): (target: T, propertyName: string) => any;
|
|
5
4
|
export interface PrimaryKeyOptions<T> extends PropertyOptions<T> {
|
|
6
5
|
}
|
|
7
6
|
export interface SerializedPrimaryKeyOptions<T> extends PropertyOptions<T> {
|
package/decorators/Property.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { EntityName, Constructor, CheckCallback, GeneratedColumnCallback, A
|
|
|
3
3
|
import type { Type, types } from '../types/index.js';
|
|
4
4
|
import type { EntityManager } from '../EntityManager.js';
|
|
5
5
|
import type { SerializeOptions } from '../serialization/EntitySerializer.js';
|
|
6
|
-
export declare function Property<T extends object>(options?: PropertyOptions<T>): (target:
|
|
6
|
+
export declare function Property<T extends object>(options?: PropertyOptions<T>): (target: T, propertyName: string) => any;
|
|
7
7
|
export interface PropertyOptions<Owner> {
|
|
8
8
|
/**
|
|
9
9
|
* Alias for `fieldName`.
|
|
@@ -146,8 +146,11 @@ export interface FindOptions<Entity, Hint extends string = never, Fields extends
|
|
|
146
146
|
hintComments?: string | string[];
|
|
147
147
|
loggerContext?: LogContext;
|
|
148
148
|
logging?: LoggingOptions;
|
|
149
|
+
/** @internal used to apply filters to the auto-joined relations */
|
|
150
|
+
em?: EntityManager;
|
|
149
151
|
}
|
|
150
|
-
export interface FindByCursorOptions<T extends object, P extends string = never, F extends string = '*', E extends string = never> extends Omit<FindOptions<T, P, F, E>, 'limit' | 'offset'> {
|
|
152
|
+
export interface FindByCursorOptions<T extends object, P extends string = never, F extends string = '*', E extends string = never, I extends boolean = true> extends Omit<FindOptions<T, P, F, E>, 'limit' | 'offset'> {
|
|
153
|
+
includeCount?: I;
|
|
151
154
|
}
|
|
152
155
|
export interface FindOneOptions<T extends object, P extends string = never, F extends string = '*', E extends string = never> extends Omit<FindOptions<T, P, F, E>, 'limit' | 'lockMode'> {
|
|
153
156
|
lockMode?: LockMode;
|
|
@@ -14,7 +14,7 @@ export declare class ArrayCollection<T extends object, O extends object> {
|
|
|
14
14
|
getItems(): T[];
|
|
15
15
|
toArray<TT extends T>(): EntityDTO<TT>[];
|
|
16
16
|
toJSON(): EntityDTO<T>[];
|
|
17
|
-
getIdentifiers<U extends IPrimaryKey = Primary<T> & IPrimaryKey>(field?: string): U[];
|
|
17
|
+
getIdentifiers<U extends IPrimaryKey = Primary<T> & IPrimaryKey>(field?: string | string[]): U[];
|
|
18
18
|
add(entity: T | Reference<T> | Iterable<T | Reference<T>>, ...entities: (T | Reference<T>)[]): void;
|
|
19
19
|
/**
|
|
20
20
|
* @internal
|
|
@@ -40,15 +40,22 @@ export class ArrayCollection {
|
|
|
40
40
|
}
|
|
41
41
|
getIdentifiers(field) {
|
|
42
42
|
const items = this.getItems();
|
|
43
|
+
const targetMeta = this.property.targetMeta;
|
|
43
44
|
if (items.length === 0) {
|
|
44
45
|
return [];
|
|
45
46
|
}
|
|
46
|
-
field ??=
|
|
47
|
+
field ??= targetMeta.compositePK ? targetMeta.primaryKeys : targetMeta.serializedPrimaryKey;
|
|
48
|
+
const cb = (i, f) => {
|
|
49
|
+
if (Utils.isEntity(i[f], true)) {
|
|
50
|
+
return wrap(i[f], true).getPrimaryKey();
|
|
51
|
+
}
|
|
52
|
+
return i[f];
|
|
53
|
+
};
|
|
47
54
|
return items.map(i => {
|
|
48
|
-
if (
|
|
49
|
-
return
|
|
55
|
+
if (Array.isArray(field)) {
|
|
56
|
+
return field.map(f => cb(i, f));
|
|
50
57
|
}
|
|
51
|
-
return i
|
|
58
|
+
return cb(i, field);
|
|
52
59
|
});
|
|
53
60
|
}
|
|
54
61
|
add(entity, ...entities) {
|
package/entity/Collection.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { EntityDTO, EntityKey, FilterQuery, Loaded, LoadedCollection, Popul
|
|
|
2
2
|
import { ArrayCollection } from './ArrayCollection.js';
|
|
3
3
|
import { Reference } from './Reference.js';
|
|
4
4
|
import type { Transaction } from '../connections/Connection.js';
|
|
5
|
-
import type {
|
|
5
|
+
import type { CountOptions, FindOptions } from '../drivers/IDatabaseDriver.js';
|
|
6
6
|
import type { EntityLoaderOptions } from './EntityLoader.js';
|
|
7
7
|
export interface MatchingOptions<T extends object, P extends string = never> extends FindOptions<T, P> {
|
|
8
8
|
where?: FilterQuery<T>;
|
|
@@ -12,7 +12,6 @@ export interface MatchingOptions<T extends object, P extends string = never> ext
|
|
|
12
12
|
export declare class Collection<T extends object, O extends object = object> extends ArrayCollection<T, O> {
|
|
13
13
|
private readonly?;
|
|
14
14
|
private _populated?;
|
|
15
|
-
private _em?;
|
|
16
15
|
private _snapshot?;
|
|
17
16
|
constructor(owner: O, items?: T[], initialized?: boolean);
|
|
18
17
|
/**
|