@mikro-orm/core 7.0.2-dev.12 → 7.0.2-dev.14
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 +4 -0
- package/EntityManager.js +4 -0
- package/MikroORM.d.ts +2 -0
- package/MikroORM.js +2 -0
- package/cache/CacheAdapter.d.ts +2 -0
- package/cache/GeneratedCacheAdapter.d.ts +1 -0
- package/cache/GeneratedCacheAdapter.js +1 -0
- package/cache/MemoryCacheAdapter.d.ts +1 -0
- package/cache/MemoryCacheAdapter.js +1 -0
- package/cache/NullCacheAdapter.d.ts +1 -0
- package/cache/NullCacheAdapter.js +1 -0
- package/connections/Connection.d.ts +13 -0
- package/connections/Connection.js +9 -0
- package/drivers/DatabaseDriver.d.ts +12 -0
- package/drivers/DatabaseDriver.js +12 -0
- package/drivers/IDatabaseDriver.d.ts +44 -0
- package/drivers/IDatabaseDriver.js +1 -0
- package/entity/BaseEntity.d.ts +11 -0
- package/entity/BaseEntity.js +11 -0
- package/entity/Collection.d.ts +26 -0
- package/entity/Collection.js +15 -0
- package/entity/EntityAssigner.d.ts +3 -0
- package/entity/EntityAssigner.js +2 -0
- package/entity/EntityFactory.d.ts +16 -0
- package/entity/EntityFactory.js +6 -0
- package/entity/EntityLoader.d.ts +19 -0
- package/entity/EntityLoader.js +2 -0
- package/entity/EntityRepository.d.ts +2 -0
- package/entity/EntityRepository.js +2 -0
- package/entity/Reference.d.ts +20 -0
- package/entity/Reference.js +16 -0
- package/entity/WrappedEntity.d.ts +20 -0
- package/entity/WrappedEntity.js +21 -1
- package/entity/defineEntity.d.ts +10 -0
- package/entity/defineEntity.js +1 -0
- package/enums.d.ts +132 -0
- package/enums.js +132 -0
- package/errors.d.ts +6 -0
- package/errors.js +6 -0
- package/events/EventManager.d.ts +5 -0
- package/events/EventManager.js +5 -0
- package/events/EventSubscriber.d.ts +4 -0
- package/events/TransactionEventBroadcaster.d.ts +2 -0
- package/events/TransactionEventBroadcaster.js +2 -0
- package/hydration/Hydrator.d.ts +2 -0
- package/hydration/Hydrator.js +2 -0
- package/hydration/ObjectHydrator.d.ts +1 -0
- package/hydration/ObjectHydrator.js +1 -0
- package/logging/DefaultLogger.d.ts +3 -0
- package/logging/DefaultLogger.js +3 -0
- package/logging/Logger.d.ts +5 -0
- package/metadata/EntitySchema.d.ts +22 -0
- package/metadata/EntitySchema.js +20 -0
- package/metadata/MetadataDiscovery.d.ts +4 -0
- package/metadata/MetadataDiscovery.js +4 -0
- package/metadata/MetadataProvider.d.ts +8 -0
- package/metadata/MetadataProvider.js +8 -0
- package/metadata/MetadataStorage.d.ts +14 -0
- package/metadata/MetadataStorage.js +13 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +1 -0
- package/naming-strategy/AbstractNamingStrategy.js +1 -0
- package/naming-strategy/MongoNamingStrategy.d.ts +1 -0
- package/naming-strategy/MongoNamingStrategy.js +1 -0
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +1 -0
- package/naming-strategy/UnderscoreNamingStrategy.js +1 -0
- package/package.json +1 -1
- package/platforms/ExceptionConverter.d.ts +1 -0
- package/platforms/ExceptionConverter.js +1 -0
- package/platforms/Platform.d.ts +65 -0
- package/platforms/Platform.js +65 -0
- package/serialization/EntitySerializer.d.ts +2 -0
- package/serialization/EntitySerializer.js +2 -0
- package/serialization/EntityTransformer.d.ts +2 -0
- package/serialization/EntityTransformer.js +2 -0
- package/serialization/SerializationContext.d.ts +5 -0
- package/serialization/SerializationContext.js +5 -0
- package/types/ArrayType.d.ts +1 -0
- package/types/ArrayType.js +1 -0
- package/types/BlobType.d.ts +1 -0
- package/types/BlobType.js +1 -0
- package/types/BooleanType.d.ts +1 -0
- package/types/BooleanType.js +1 -0
- package/types/CharacterType.d.ts +1 -0
- package/types/CharacterType.js +1 -0
- package/types/DateTimeType.d.ts +1 -0
- package/types/DateTimeType.js +1 -0
- package/types/DateType.d.ts +1 -0
- package/types/DateType.js +1 -0
- package/types/EnumArrayType.d.ts +1 -0
- package/types/EnumArrayType.js +1 -0
- package/types/EnumType.d.ts +1 -0
- package/types/EnumType.js +1 -0
- package/types/FloatType.d.ts +1 -0
- package/types/FloatType.js +1 -0
- package/types/IntegerType.d.ts +1 -0
- package/types/IntegerType.js +1 -0
- package/types/IntervalType.d.ts +1 -0
- package/types/IntervalType.js +1 -0
- package/types/JsonType.d.ts +1 -0
- package/types/JsonType.js +1 -0
- package/types/MediumIntType.d.ts +1 -0
- package/types/MediumIntType.js +1 -0
- package/types/SmallIntType.d.ts +1 -0
- package/types/SmallIntType.js +1 -0
- package/types/StringType.d.ts +1 -0
- package/types/StringType.js +1 -0
- package/types/TextType.d.ts +1 -0
- package/types/TextType.js +1 -0
- package/types/TimeType.d.ts +1 -0
- package/types/TimeType.js +1 -0
- package/types/TinyIntType.d.ts +1 -0
- package/types/TinyIntType.js +1 -0
- package/types/Type.d.ts +3 -0
- package/types/Type.js +1 -0
- package/types/Uint8ArrayType.d.ts +1 -0
- package/types/Uint8ArrayType.js +1 -0
- package/types/UnknownType.d.ts +1 -0
- package/types/UnknownType.js +1 -0
- package/types/UuidType.d.ts +1 -0
- package/types/UuidType.js +1 -0
- package/types/index.d.ts +2 -0
- package/types/index.js +2 -0
- package/typings.d.ts +177 -0
- package/typings.js +11 -0
- package/unit-of-work/ChangeSet.d.ts +4 -0
- package/unit-of-work/ChangeSet.js +4 -0
- package/unit-of-work/ChangeSetComputer.d.ts +2 -0
- package/unit-of-work/ChangeSetComputer.js +2 -0
- package/unit-of-work/ChangeSetPersister.d.ts +4 -0
- package/unit-of-work/ChangeSetPersister.js +4 -0
- package/unit-of-work/IdentityMap.d.ts +7 -0
- package/unit-of-work/IdentityMap.js +7 -0
- package/unit-of-work/UnitOfWork.d.ts +15 -0
- package/unit-of-work/UnitOfWork.js +15 -0
- package/utils/Configuration.d.ts +8 -0
- package/utils/Configuration.js +8 -0
- package/utils/EntityComparator.d.ts +2 -0
- package/utils/EntityComparator.js +2 -0
- package/utils/NullHighlighter.d.ts +1 -0
- package/utils/NullHighlighter.js +1 -0
- package/utils/RawQueryFragment.d.ts +10 -0
- package/utils/RawQueryFragment.js +9 -0
- package/utils/RequestContext.d.ts +1 -0
- package/utils/TransactionContext.d.ts +1 -0
- package/utils/TransactionContext.js +1 -0
- package/utils/Utils.d.ts +6 -0
- package/utils/Utils.js +7 -1
package/entity/BaseEntity.js
CHANGED
|
@@ -2,37 +2,48 @@ import { Reference } from './Reference.js';
|
|
|
2
2
|
import { EntityAssigner } from './EntityAssigner.js';
|
|
3
3
|
import { EntitySerializer } from '../serialization/EntitySerializer.js';
|
|
4
4
|
import { helper } from './wrap.js';
|
|
5
|
+
/** Base class for entities providing convenience methods like `assign()`, `toObject()`, and `populate()`. */
|
|
5
6
|
export class BaseEntity {
|
|
7
|
+
/** Returns whether the entity has been fully loaded from the database. */
|
|
6
8
|
isInitialized() {
|
|
7
9
|
return helper(this).__initialized;
|
|
8
10
|
}
|
|
11
|
+
/** Marks the entity as populated or not for serialization purposes. */
|
|
9
12
|
populated(populated = true) {
|
|
10
13
|
helper(this).populated(populated);
|
|
11
14
|
}
|
|
15
|
+
/** Loads the specified relations on this entity. */
|
|
12
16
|
async populate(populate, options = {}) {
|
|
13
17
|
return helper(this).populate(populate, options);
|
|
14
18
|
}
|
|
19
|
+
/** Returns a Reference wrapper for this entity. */
|
|
15
20
|
toReference() {
|
|
16
21
|
return Reference.create(this);
|
|
17
22
|
}
|
|
18
23
|
toObject(ignoreFields) {
|
|
19
24
|
return helper(this).toObject(ignoreFields);
|
|
20
25
|
}
|
|
26
|
+
/** Converts the entity to a plain object, including all properties regardless of serialization rules. */
|
|
21
27
|
toPOJO() {
|
|
22
28
|
return helper(this).toPOJO();
|
|
23
29
|
}
|
|
30
|
+
/** Serializes the entity with control over which relations and fields to include or exclude. */
|
|
24
31
|
serialize(options) {
|
|
25
32
|
return EntitySerializer.serialize(this, options);
|
|
26
33
|
}
|
|
34
|
+
/** Assigns the given data to this entity, updating its properties and relations. */
|
|
27
35
|
assign(data, options = {}) {
|
|
28
36
|
return EntityAssigner.assign(this, data, options);
|
|
29
37
|
}
|
|
38
|
+
/** Initializes (refreshes) the entity by reloading it from the database. Returns null if not found. */
|
|
30
39
|
init(options) {
|
|
31
40
|
return helper(this).init(options);
|
|
32
41
|
}
|
|
42
|
+
/** Returns the database schema this entity belongs to. */
|
|
33
43
|
getSchema() {
|
|
34
44
|
return helper(this).getSchema();
|
|
35
45
|
}
|
|
46
|
+
/** Sets the database schema for this entity. */
|
|
36
47
|
setSchema(schema) {
|
|
37
48
|
helper(this).setSchema(schema);
|
|
38
49
|
}
|
package/entity/Collection.d.ts
CHANGED
|
@@ -3,11 +3,16 @@ import { Reference } from './Reference.js';
|
|
|
3
3
|
import type { Transaction } from '../connections/Connection.js';
|
|
4
4
|
import type { CountOptions, FindOptions } from '../drivers/IDatabaseDriver.js';
|
|
5
5
|
import type { EntityLoaderOptions } from './EntityLoader.js';
|
|
6
|
+
/** Options for the `Collection.matching()` method to query a subset of collection items from the database. */
|
|
6
7
|
export interface MatchingOptions<T extends object, P extends string = never> extends FindOptions<T, P> {
|
|
8
|
+
/** Additional filtering conditions for the query. */
|
|
7
9
|
where?: FilterQuery<T>;
|
|
10
|
+
/** Whether to store the matched items in the collection (makes it read-only). */
|
|
8
11
|
store?: boolean;
|
|
12
|
+
/** Transaction context for the query. */
|
|
9
13
|
ctx?: Transaction;
|
|
10
14
|
}
|
|
15
|
+
/** Represents a to-many relation (1:m or m:n) as an iterable, managed collection of entities. */
|
|
11
16
|
export declare class Collection<T extends object, O extends object = object> {
|
|
12
17
|
#private;
|
|
13
18
|
readonly owner: O;
|
|
@@ -32,12 +37,15 @@ export declare class Collection<T extends object, O extends object = object> {
|
|
|
32
37
|
* The value is cached (unless you use the `where` option), use `refresh: true` to force reload it.
|
|
33
38
|
*/
|
|
34
39
|
loadCount(options?: LoadCountOptions<T> | boolean): Promise<number>;
|
|
40
|
+
/** Queries a subset of the collection items from the database with custom filtering, ordering, and pagination. */
|
|
35
41
|
matching<TT extends T, P extends string = never>(options: MatchingOptions<T, P>): Promise<Loaded<TT, P>[]>;
|
|
36
42
|
/**
|
|
37
43
|
* Returns the items (the collection must be initialized)
|
|
38
44
|
*/
|
|
39
45
|
getItems(check?: boolean): T[];
|
|
46
|
+
/** Serializes the collection items to plain JSON objects. Returns an empty array if not initialized. */
|
|
40
47
|
toJSON<TT extends T>(): EntityDTO<TT>[];
|
|
48
|
+
/** Adds one or more items to the collection, propagating the change to the inverse side. Returns the number of items added. */
|
|
41
49
|
add<TT extends T>(entity: TT | Reference<TT> | Iterable<TT | Reference<TT>>, ...entities: (TT | Reference<TT>)[]): number;
|
|
42
50
|
/**
|
|
43
51
|
* Remove specified item(s) from the collection. Note that removing item from collection does not necessarily imply deleting the target entity,
|
|
@@ -46,11 +54,17 @@ export declare class Collection<T extends object, O extends object = object> {
|
|
|
46
54
|
* which tells the ORM we don't want orphaned entities to exist, so we know those should be removed.
|
|
47
55
|
*/
|
|
48
56
|
remove<TT extends T>(entity: TT | Reference<TT> | Iterable<TT | Reference<TT>> | ((item: TT) => boolean), ...entities: (TT | Reference<TT>)[]): number;
|
|
57
|
+
/** Checks whether the collection contains the given item. */
|
|
49
58
|
contains<TT extends T>(item: TT | Reference<TT>, check?: boolean): boolean;
|
|
59
|
+
/** Returns the number of items in the collection. Throws if the collection is not initialized. */
|
|
50
60
|
count(): number;
|
|
61
|
+
/** Returns true if the collection has no items. Throws if the collection is not initialized. */
|
|
51
62
|
isEmpty(): boolean;
|
|
63
|
+
/** Returns whether this collection should be included in serialization based on its populated state. */
|
|
52
64
|
shouldPopulate(populated?: boolean): boolean;
|
|
65
|
+
/** Marks the collection as populated or not for serialization purposes. */
|
|
53
66
|
populated(populated?: boolean | undefined): void;
|
|
67
|
+
/** Initializes the collection by loading its items from the database. */
|
|
54
68
|
init<TT extends T, P extends string = never>(options?: InitCollectionOptions<TT, P>): Promise<LoadedCollection<Loaded<TT, P>>>;
|
|
55
69
|
private getEntityManager;
|
|
56
70
|
private createCondition;
|
|
@@ -63,12 +77,15 @@ export declare class Collection<T extends object, O extends object = object> {
|
|
|
63
77
|
private reorderItems;
|
|
64
78
|
private cancelOrphanRemoval;
|
|
65
79
|
private validateModification;
|
|
80
|
+
/** Converts all items in the collection to plain DTO objects. */
|
|
66
81
|
toArray<TT extends T>(): EntityDTO<TT>[];
|
|
82
|
+
/** Returns the primary key values (or a specific field) of all items in the collection. */
|
|
67
83
|
getIdentifiers<U extends IPrimaryKey = Primary<T> & IPrimaryKey>(field?: string | string[]): U[];
|
|
68
84
|
/**
|
|
69
85
|
* @internal
|
|
70
86
|
*/
|
|
71
87
|
addWithoutPropagation(entity: T): void;
|
|
88
|
+
/** Replaces all items in the collection with the given items. */
|
|
72
89
|
set(items: Iterable<T | Reference<T>>): void;
|
|
73
90
|
private compare;
|
|
74
91
|
/**
|
|
@@ -129,8 +146,10 @@ export declare class Collection<T extends object, O extends object = object> {
|
|
|
129
146
|
* If there are more items with the same key, only the first one will be present.
|
|
130
147
|
*/
|
|
131
148
|
indexBy<K1 extends keyof T, K2 extends keyof T = never>(key: K1, valueKey: K2): Record<T[K1] & PropertyKey, T[K2]>;
|
|
149
|
+
/** Returns whether the collection has been initialized. Pass `fully = true` to also check that all items are initialized. */
|
|
132
150
|
isInitialized(fully?: boolean): boolean;
|
|
133
151
|
isDirty(): boolean;
|
|
152
|
+
/** Returns whether the collection was partially loaded (propagation is disabled for partial collections). */
|
|
134
153
|
isPartial(): boolean;
|
|
135
154
|
setDirty(dirty?: boolean): void;
|
|
136
155
|
get length(): number;
|
|
@@ -157,12 +176,19 @@ export declare class Collection<T extends object, O extends object = object> {
|
|
|
157
176
|
protected shouldPropagateToCollection(collection: Collection<O, T>, method: 'add' | 'remove' | 'takeSnapshot'): boolean;
|
|
158
177
|
protected incrementCount(value: number): void;
|
|
159
178
|
}
|
|
179
|
+
/** Options for initializing a collection via `init()` or `load()`. */
|
|
160
180
|
export interface InitCollectionOptions<T, P extends string = never, F extends string = '*', E extends string = never> extends EntityLoaderOptions<T, F, E> {
|
|
181
|
+
/** Whether to use the dataloader for batching collection loads. */
|
|
161
182
|
dataloader?: boolean;
|
|
183
|
+
/** Relations to populate on the loaded items. */
|
|
162
184
|
populate?: Populate<T, P>;
|
|
185
|
+
/** Populate only references (without loading full entities). Works only with M:N collections that use pivot table. */
|
|
163
186
|
ref?: boolean;
|
|
164
187
|
}
|
|
188
|
+
/** Options for the `Collection.loadCount()` method. */
|
|
165
189
|
export interface LoadCountOptions<T extends object> extends CountOptions<T, '*'> {
|
|
190
|
+
/** Whether to reload the count from the database even if it is already cached. */
|
|
166
191
|
refresh?: boolean;
|
|
192
|
+
/** Additional filtering conditions for the count query. */
|
|
167
193
|
where?: FilterQuery<T>;
|
|
168
194
|
}
|
package/entity/Collection.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Reference } from './Reference.js';
|
|
|
5
5
|
import { helper, wrap } from './wrap.js';
|
|
6
6
|
import { QueryHelper } from '../utils/QueryHelper.js';
|
|
7
7
|
import { inspect } from '../logging/inspect.js';
|
|
8
|
+
/** Represents a to-many relation (1:m or m:n) as an iterable, managed collection of entities. */
|
|
8
9
|
export class Collection {
|
|
9
10
|
owner;
|
|
10
11
|
#items = new Set();
|
|
@@ -91,6 +92,7 @@ export class Collection {
|
|
|
91
92
|
}
|
|
92
93
|
return count;
|
|
93
94
|
}
|
|
95
|
+
/** Queries a subset of the collection items from the database with custom filtering, ordering, and pagination. */
|
|
94
96
|
async matching(options) {
|
|
95
97
|
const em = this.getEntityManager();
|
|
96
98
|
const { where, ctx, ...opts } = options;
|
|
@@ -128,12 +130,14 @@ export class Collection {
|
|
|
128
130
|
}
|
|
129
131
|
return [...this.#items];
|
|
130
132
|
}
|
|
133
|
+
/** Serializes the collection items to plain JSON objects. Returns an empty array if not initialized. */
|
|
131
134
|
toJSON() {
|
|
132
135
|
if (!this.isInitialized()) {
|
|
133
136
|
return [];
|
|
134
137
|
}
|
|
135
138
|
return this.toArray();
|
|
136
139
|
}
|
|
140
|
+
/** Adds one or more items to the collection, propagating the change to the inverse side. Returns the number of items added. */
|
|
137
141
|
add(entity, ...entities) {
|
|
138
142
|
entities = Utils.asArray(entity).concat(entities);
|
|
139
143
|
const unwrapped = entities.map(i => Reference.unwrapReference(i));
|
|
@@ -203,6 +207,7 @@ export class Collection {
|
|
|
203
207
|
}
|
|
204
208
|
return removed;
|
|
205
209
|
}
|
|
210
|
+
/** Checks whether the collection contains the given item. */
|
|
206
211
|
contains(item, check = true) {
|
|
207
212
|
if (check) {
|
|
208
213
|
this.checkInitialized();
|
|
@@ -210,14 +215,17 @@ export class Collection {
|
|
|
210
215
|
const entity = Reference.unwrapReference(item);
|
|
211
216
|
return this.#items.has(entity);
|
|
212
217
|
}
|
|
218
|
+
/** Returns the number of items in the collection. Throws if the collection is not initialized. */
|
|
213
219
|
count() {
|
|
214
220
|
this.checkInitialized();
|
|
215
221
|
return this.#items.size;
|
|
216
222
|
}
|
|
223
|
+
/** Returns true if the collection has no items. Throws if the collection is not initialized. */
|
|
217
224
|
isEmpty() {
|
|
218
225
|
this.checkInitialized();
|
|
219
226
|
return this.count() === 0;
|
|
220
227
|
}
|
|
228
|
+
/** Returns whether this collection should be included in serialization based on its populated state. */
|
|
221
229
|
shouldPopulate(populated) {
|
|
222
230
|
if (!this.isInitialized(true)) {
|
|
223
231
|
return false;
|
|
@@ -227,9 +235,11 @@ export class Collection {
|
|
|
227
235
|
}
|
|
228
236
|
return !!populated;
|
|
229
237
|
}
|
|
238
|
+
/** Marks the collection as populated or not for serialization purposes. */
|
|
230
239
|
populated(populated = true) {
|
|
231
240
|
this.#populated = populated;
|
|
232
241
|
}
|
|
242
|
+
/** Initializes the collection by loading its items from the database. */
|
|
233
243
|
async init(options = {}) {
|
|
234
244
|
if (this.#dirty) {
|
|
235
245
|
const items = [...this.#items];
|
|
@@ -377,12 +387,14 @@ export class Collection {
|
|
|
377
387
|
throw ValidationError.cannotModifyInverseCollection(this.owner, this.property);
|
|
378
388
|
}
|
|
379
389
|
}
|
|
390
|
+
/** Converts all items in the collection to plain DTO objects. */
|
|
380
391
|
toArray() {
|
|
381
392
|
if (this.#items.size === 0) {
|
|
382
393
|
return [];
|
|
383
394
|
}
|
|
384
395
|
return this.map(item => wrap(item).toJSON());
|
|
385
396
|
}
|
|
397
|
+
/** Returns the primary key values (or a specific field) of all items in the collection. */
|
|
386
398
|
getIdentifiers(field) {
|
|
387
399
|
const items = this.getItems();
|
|
388
400
|
const targetMeta = this.property.targetMeta;
|
|
@@ -416,6 +428,7 @@ export class Collection {
|
|
|
416
428
|
this.#dirty = true;
|
|
417
429
|
}
|
|
418
430
|
}
|
|
431
|
+
/** Replaces all items in the collection with the given items. */
|
|
419
432
|
set(items) {
|
|
420
433
|
if (!this.#initialized) {
|
|
421
434
|
this.#initialized = true;
|
|
@@ -571,6 +584,7 @@ export class Collection {
|
|
|
571
584
|
return obj;
|
|
572
585
|
}, {});
|
|
573
586
|
}
|
|
587
|
+
/** Returns whether the collection has been initialized. Pass `fully = true` to also check that all items are initialized. */
|
|
574
588
|
isInitialized(fully = false) {
|
|
575
589
|
if (!this.#initialized || !fully) {
|
|
576
590
|
return this.#initialized;
|
|
@@ -585,6 +599,7 @@ export class Collection {
|
|
|
585
599
|
isDirty() {
|
|
586
600
|
return this.#dirty;
|
|
587
601
|
}
|
|
602
|
+
/** Returns whether the collection was partially loaded (propagation is disabled for partial collections). */
|
|
588
603
|
isPartial() {
|
|
589
604
|
return this.#partial;
|
|
590
605
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { EntityManager } from '../EntityManager.js';
|
|
2
2
|
import type { EntityData, EntityDTO, EntityProperty, FromEntityType, IsSubset, MergeSelected } from '../typings.js';
|
|
3
|
+
/** Handles assigning data to entities, resolving relations, and propagating changes. */
|
|
3
4
|
export declare class EntityAssigner {
|
|
5
|
+
/** Assigns the given data to the entity, resolving relations and handling custom types. */
|
|
4
6
|
static assign<Entity extends object, Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Convert extends boolean = false, Data extends EntityData<Naked, Convert> | Partial<EntityDTO<Naked>> = EntityData<Naked, Convert> | Partial<EntityDTO<Naked>>>(entity: Entity, data: Data & IsSubset<EntityData<Naked, Convert>, Data>, options?: AssignOptions<Convert>): MergeSelected<Entity, Naked, keyof Data & string>;
|
|
5
7
|
private static assignProperty;
|
|
6
8
|
/**
|
|
@@ -16,6 +18,7 @@ export declare class EntityAssigner {
|
|
|
16
18
|
private static createCollectionItem;
|
|
17
19
|
}
|
|
18
20
|
export declare const assign: typeof EntityAssigner.assign;
|
|
21
|
+
/** Options controlling how data is assigned to an entity via `assign()`. */
|
|
19
22
|
export interface AssignOptions<Convert extends boolean> {
|
|
20
23
|
/**
|
|
21
24
|
* Allows disabling processing of nested relations. When disabled, an object payload in place of a relation always
|
package/entity/EntityAssigner.js
CHANGED
|
@@ -6,7 +6,9 @@ import { validateProperty } from './validators.js';
|
|
|
6
6
|
import { helper, wrap } from './wrap.js';
|
|
7
7
|
import { EntityHelper } from './EntityHelper.js';
|
|
8
8
|
import { ValidationError } from '../errors.js';
|
|
9
|
+
/** Handles assigning data to entities, resolving relations, and propagating changes. */
|
|
9
10
|
export class EntityAssigner {
|
|
11
|
+
/** Assigns the given data to the entity, resolving relations and handling custom types. */
|
|
10
12
|
static assign(entity, data, options = {}) {
|
|
11
13
|
let opts = options;
|
|
12
14
|
if (opts.visited?.has(entity)) {
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
import type { EntityData, EntityMetadata, EntityName, New, Primary } from '../typings.js';
|
|
2
2
|
import type { EntityManager } from '../EntityManager.js';
|
|
3
3
|
import type { EntityComparator } from '../utils/EntityComparator.js';
|
|
4
|
+
/** @internal Options for creating and merging entities via the EntityFactory. */
|
|
4
5
|
export interface FactoryOptions {
|
|
6
|
+
/** Whether the entity should be marked as initialized. */
|
|
5
7
|
initialized?: boolean;
|
|
8
|
+
/** Whether the entity is being newly created (uses constructor). */
|
|
6
9
|
newEntity?: boolean;
|
|
7
10
|
/**
|
|
8
11
|
* Property `onCreate` hooks are normally executed during `flush` operation.
|
|
9
12
|
* With this option, they will be processed early inside `em.create()` method.
|
|
10
13
|
*/
|
|
11
14
|
processOnCreateHooksEarly?: boolean;
|
|
15
|
+
/** Whether to merge the entity into the identity map. */
|
|
12
16
|
merge?: boolean;
|
|
17
|
+
/** Whether to refresh an already loaded entity with new data. */
|
|
13
18
|
refresh?: boolean;
|
|
19
|
+
/** Whether to convert custom types during hydration. */
|
|
14
20
|
convertCustomTypes?: boolean;
|
|
21
|
+
/** Whether to recompute the entity snapshot after creation. */
|
|
15
22
|
recomputeSnapshot?: boolean;
|
|
23
|
+
/** Schema from FindOptions, overrides default schema. */
|
|
16
24
|
schema?: string;
|
|
25
|
+
/** Parent entity schema for nested entity creation. */
|
|
17
26
|
parentSchema?: string;
|
|
27
|
+
/** Whether to normalize accessors to the correct property names (normally handled via result mapper). */
|
|
18
28
|
normalizeAccessors?: boolean;
|
|
19
29
|
/**
|
|
20
30
|
* Property name to use for identity map lookup instead of the primary key.
|
|
@@ -22,13 +32,19 @@ export interface FactoryOptions {
|
|
|
22
32
|
*/
|
|
23
33
|
key?: string;
|
|
24
34
|
}
|
|
35
|
+
/** @internal Factory responsible for creating, merging, and hydrating entity instances. */
|
|
25
36
|
export declare class EntityFactory {
|
|
26
37
|
#private;
|
|
27
38
|
constructor(em: EntityManager);
|
|
39
|
+
/** Creates a new entity instance or returns an existing one from the identity map, hydrating it with the provided data. */
|
|
28
40
|
create<T extends object, P extends string = string>(entityName: EntityName<T>, data: EntityData<T>, options?: FactoryOptions): New<T, P>;
|
|
41
|
+
/** Merges new data into an existing entity, preserving user-modified properties. */
|
|
29
42
|
mergeData<T extends object>(meta: EntityMetadata<T>, entity: T, data: EntityData<T>, options?: FactoryOptions): void;
|
|
43
|
+
/** Creates or retrieves an uninitialized entity reference by its primary key or alternate key. */
|
|
30
44
|
createReference<T extends object>(entityName: EntityName<T>, id: Primary<T> | Primary<T>[] | Record<string, Primary<T>>, options?: Pick<FactoryOptions, 'merge' | 'convertCustomTypes' | 'schema' | 'key'>): T;
|
|
45
|
+
/** Creates an embeddable entity instance from the provided data. */
|
|
31
46
|
createEmbeddable<T extends object>(entityName: EntityName<T>, data: EntityData<T>, options?: Pick<FactoryOptions, 'newEntity' | 'convertCustomTypes'>): T;
|
|
47
|
+
/** Returns the EntityComparator instance used for diffing entities. */
|
|
32
48
|
getComparator(): EntityComparator;
|
|
33
49
|
private createEntity;
|
|
34
50
|
private assignDefaultValues;
|
package/entity/EntityFactory.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Reference } from './Reference.js';
|
|
|
5
5
|
import { helper } from './wrap.js';
|
|
6
6
|
import { EntityHelper } from './EntityHelper.js';
|
|
7
7
|
import { JsonType } from '../types/JsonType.js';
|
|
8
|
+
/** @internal Factory responsible for creating, merging, and hydrating entity instances. */
|
|
8
9
|
export class EntityFactory {
|
|
9
10
|
#driver;
|
|
10
11
|
#platform;
|
|
@@ -24,6 +25,7 @@ export class EntityFactory {
|
|
|
24
25
|
this.#eventManager = this.#em.getEventManager();
|
|
25
26
|
this.#comparator = this.#em.getComparator();
|
|
26
27
|
}
|
|
28
|
+
/** Creates a new entity instance or returns an existing one from the identity map, hydrating it with the provided data. */
|
|
27
29
|
create(entityName, data, options = {}) {
|
|
28
30
|
data = Reference.unwrapReference(data);
|
|
29
31
|
options.initialized ??= true;
|
|
@@ -108,6 +110,7 @@ export class EntityFactory {
|
|
|
108
110
|
wrapped.__processing = false;
|
|
109
111
|
return entity;
|
|
110
112
|
}
|
|
113
|
+
/** Merges new data into an existing entity, preserving user-modified properties. */
|
|
111
114
|
mergeData(meta, entity, data, options = {}) {
|
|
112
115
|
// merge unchanged properties automatically
|
|
113
116
|
data = QueryHelper.processParams(data);
|
|
@@ -181,6 +184,7 @@ export class EntityFactory {
|
|
|
181
184
|
});
|
|
182
185
|
this.unitOfWork.normalizeEntityData(meta, originalEntityData);
|
|
183
186
|
}
|
|
187
|
+
/** Creates or retrieves an uninitialized entity reference by its primary key or alternate key. */
|
|
184
188
|
createReference(entityName, id, options = {}) {
|
|
185
189
|
options.convertCustomTypes ??= true;
|
|
186
190
|
const meta = this.#metadata.get(entityName);
|
|
@@ -218,12 +222,14 @@ export class EntityFactory {
|
|
|
218
222
|
}
|
|
219
223
|
return this.create(entityName, id, { ...options, initialized: false });
|
|
220
224
|
}
|
|
225
|
+
/** Creates an embeddable entity instance from the provided data. */
|
|
221
226
|
createEmbeddable(entityName, data, options = {}) {
|
|
222
227
|
data = { ...data };
|
|
223
228
|
const meta = this.#metadata.get(entityName);
|
|
224
229
|
const meta2 = this.processDiscriminatorColumn(meta, data);
|
|
225
230
|
return this.createEntity(data, meta2, options);
|
|
226
231
|
}
|
|
232
|
+
/** Returns the EntityComparator instance used for diffing entities. */
|
|
227
233
|
getComparator() {
|
|
228
234
|
return this.#comparator;
|
|
229
235
|
}
|
package/entity/EntityLoader.d.ts
CHANGED
|
@@ -3,24 +3,42 @@ import type { EntityManager } from '../EntityManager.js';
|
|
|
3
3
|
import { LoadStrategy, type LockMode, type PopulateHint, PopulatePath, type QueryOrderMap } from '../enums.js';
|
|
4
4
|
import type { FilterOptions } from '../drivers/IDatabaseDriver.js';
|
|
5
5
|
import type { LoggingOptions } from '../logging/Logger.js';
|
|
6
|
+
/** Options for controlling how relations are loaded by the EntityLoader. */
|
|
6
7
|
export interface EntityLoaderOptions<Entity, Fields extends string = PopulatePath.ALL, Excludes extends string = never> {
|
|
8
|
+
/** Select specific fields to load (partial loading). */
|
|
7
9
|
fields?: readonly AutoPath<Entity, Fields, `${PopulatePath.ALL}`>[];
|
|
10
|
+
/** Fields to exclude from loading. */
|
|
8
11
|
exclude?: readonly AutoPath<Entity, Excludes>[];
|
|
12
|
+
/** Additional filtering conditions applied to populated relations. */
|
|
9
13
|
where?: FilterQuery<Entity>;
|
|
14
|
+
/** Controls how `where` conditions are applied to populated relations. */
|
|
10
15
|
populateWhere?: PopulateHint | `${PopulateHint}`;
|
|
16
|
+
/** Ordering for populated relations. */
|
|
11
17
|
orderBy?: QueryOrderMap<Entity> | QueryOrderMap<Entity>[];
|
|
18
|
+
/** Whether to reload already loaded entities. */
|
|
12
19
|
refresh?: boolean;
|
|
20
|
+
/** Whether to validate the populate hint against the entity metadata. */
|
|
13
21
|
validate?: boolean;
|
|
22
|
+
/** Whether to look up eager-loaded relationships automatically. */
|
|
14
23
|
lookup?: boolean;
|
|
24
|
+
/** Whether to convert custom types during hydration. */
|
|
15
25
|
convertCustomTypes?: boolean;
|
|
26
|
+
/** Whether to skip loading lazy scalar properties. */
|
|
16
27
|
ignoreLazyScalarProperties?: boolean;
|
|
28
|
+
/** Filter options to apply when loading relations. */
|
|
17
29
|
filters?: FilterOptions;
|
|
30
|
+
/** Loading strategy to use (select-in, joined, or balanced). */
|
|
18
31
|
strategy?: LoadStrategy | `${LoadStrategy}`;
|
|
32
|
+
/** Lock mode for the query (pessimistic locking). */
|
|
19
33
|
lockMode?: Exclude<LockMode, LockMode.OPTIMISTIC>;
|
|
34
|
+
/** Database schema override. */
|
|
20
35
|
schema?: string;
|
|
36
|
+
/** Connection type (read or write replica). */
|
|
21
37
|
connectionType?: ConnectionType;
|
|
38
|
+
/** Logging options for the query. */
|
|
22
39
|
logging?: LoggingOptions;
|
|
23
40
|
}
|
|
41
|
+
/** Responsible for batch-loading entity relations using either select-in or joined loading strategies. */
|
|
24
42
|
export declare class EntityLoader {
|
|
25
43
|
#private;
|
|
26
44
|
constructor(em: EntityManager);
|
|
@@ -29,6 +47,7 @@ export declare class EntityLoader {
|
|
|
29
47
|
* This will execute one query for each relation, that will populate it on all the specified entities.
|
|
30
48
|
*/
|
|
31
49
|
populate<Entity extends object, Fields extends string = PopulatePath.ALL>(entityName: EntityName<Entity>, entities: Entity[], populate: PopulateOptions<Entity>[] | boolean, options: EntityLoaderOptions<Entity, Fields>): Promise<void>;
|
|
50
|
+
/** Normalizes populate hints into a structured array of PopulateOptions, expanding dot paths and eager relations. */
|
|
32
51
|
normalizePopulate<Entity>(entityName: EntityName<Entity>, populate: (PopulateOptions<Entity> | boolean)[] | PopulateOptions<Entity> | boolean, strategy?: LoadStrategy, lookup?: boolean, exclude?: string[]): PopulateOptions<Entity>[];
|
|
33
52
|
private setSerializationContext;
|
|
34
53
|
/**
|
package/entity/EntityLoader.js
CHANGED
|
@@ -6,6 +6,7 @@ import { Reference } from './Reference.js';
|
|
|
6
6
|
import { helper } from './wrap.js';
|
|
7
7
|
import { expandDotPaths } from './utils.js';
|
|
8
8
|
import { Raw } from '../utils/RawQueryFragment.js';
|
|
9
|
+
/** Responsible for batch-loading entity relations using either select-in or joined loading strategies. */
|
|
9
10
|
export class EntityLoader {
|
|
10
11
|
#metadata;
|
|
11
12
|
#driver;
|
|
@@ -56,6 +57,7 @@ export class EntityLoader {
|
|
|
56
57
|
visited.delete(entity);
|
|
57
58
|
}
|
|
58
59
|
}
|
|
60
|
+
/** Normalizes populate hints into a structured array of PopulateOptions, expanding dot paths and eager relations. */
|
|
59
61
|
normalizePopulate(entityName, populate, strategy, lookup = true, exclude) {
|
|
60
62
|
const meta = this.#metadata.find(entityName);
|
|
61
63
|
let normalized = Utils.asArray(populate).map(field => {
|
|
@@ -5,6 +5,7 @@ import type { EntityData, EntityName, Primary, Loaded, FilterQuery, EntityDictio
|
|
|
5
5
|
import type { CountOptions, DeleteOptions, FindAllOptions, FindByCursorOptions, FindOneOptions, FindOneOrFailOptions, FindOptions, GetReferenceOptions, NativeInsertUpdateOptions, StreamOptions, UpdateOptions, UpsertManyOptions, UpsertOptions } from '../drivers/IDatabaseDriver.js';
|
|
6
6
|
import type { EntityLoaderOptions } from './EntityLoader.js';
|
|
7
7
|
import type { Cursor } from '../utils/Cursor.js';
|
|
8
|
+
/** Repository class providing a type-safe API for querying and persisting a specific entity type. */
|
|
8
9
|
export declare class EntityRepository<Entity extends object> {
|
|
9
10
|
protected readonly em: EntityManager;
|
|
10
11
|
protected readonly entityName: EntityName<Entity>;
|
|
@@ -198,6 +199,7 @@ export declare class EntityRepository<Entity extends object> {
|
|
|
198
199
|
* Returns total number of entities matching your `where` query.
|
|
199
200
|
*/
|
|
200
201
|
count<Hint extends string = never>(where?: FilterQuery<Entity>, options?: CountOptions<Entity, Hint>): Promise<number>;
|
|
202
|
+
/** Returns the entity class name associated with this repository. */
|
|
201
203
|
getEntityName(): string;
|
|
202
204
|
/**
|
|
203
205
|
* Returns the underlying EntityManager instance
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ValidationError } from '../errors.js';
|
|
2
2
|
import { Utils } from '../utils/Utils.js';
|
|
3
|
+
/** Repository class providing a type-safe API for querying and persisting a specific entity type. */
|
|
3
4
|
export class EntityRepository {
|
|
4
5
|
em;
|
|
5
6
|
entityName;
|
|
@@ -193,6 +194,7 @@ export class EntityRepository {
|
|
|
193
194
|
async count(where = {}, options = {}) {
|
|
194
195
|
return this.getEntityManager().count(this.entityName, where, options);
|
|
195
196
|
}
|
|
197
|
+
/** Returns the entity class name associated with this repository. */
|
|
196
198
|
getEntityName() {
|
|
197
199
|
return Utils.className(this.entityName);
|
|
198
200
|
}
|
package/entity/Reference.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import type { AddEager, AddOptional, Dictionary, EntityClass, EntityKey, EntityProperty, Loaded, LoadedReference, Primary, Ref } from '../typings.js';
|
|
2
2
|
import type { FindOneOptions, FindOneOrFailOptions } from '../drivers/IDatabaseDriver.js';
|
|
3
|
+
/** Wrapper around an entity that provides lazy loading capabilities and identity-preserving reference semantics. */
|
|
3
4
|
export declare class Reference<T extends object> {
|
|
4
5
|
private entity;
|
|
5
6
|
private property?;
|
|
6
7
|
constructor(entity: T);
|
|
8
|
+
/** Creates a Reference wrapper for the given entity, preserving identity if one already exists. */
|
|
7
9
|
static create<T extends object>(entity: T | Ref<T>): Ref<T>;
|
|
10
|
+
/** Creates a Reference wrapper for an entity identified by its primary key, wrapped in a Ref. */
|
|
8
11
|
static createFromPK<T extends object>(entityType: EntityClass<T>, pk: Primary<T>, options?: {
|
|
9
12
|
schema?: string;
|
|
10
13
|
}): Ref<T>;
|
|
14
|
+
/** Creates an uninitialized entity reference by primary key without wrapping it in a Reference. */
|
|
11
15
|
static createNakedFromPK<T extends object>(entityType: EntityClass<T>, pk: Primary<T>, options?: {
|
|
12
16
|
schema?: string;
|
|
13
17
|
}): T;
|
|
@@ -35,14 +39,22 @@ export declare class Reference<T extends object> {
|
|
|
35
39
|
*/
|
|
36
40
|
loadOrFail<TT extends T, P extends string = never, F extends string = '*', E extends string = never>(options?: LoadReferenceOrFailOptions<TT, P, F, E>): Promise<Loaded<TT, P, F, E>>;
|
|
37
41
|
private set;
|
|
42
|
+
/** Returns the underlying entity without checking initialization state. */
|
|
38
43
|
unwrap(): T;
|
|
44
|
+
/** Returns the underlying entity, throwing an error if the reference is not initialized. */
|
|
39
45
|
getEntity(): T;
|
|
46
|
+
/** Returns the value of a property on the underlying entity. Throws if the reference is not initialized. */
|
|
40
47
|
getProperty<K extends keyof T>(prop: K): T[K];
|
|
48
|
+
/** Loads the entity if needed, then returns the value of the specified property. */
|
|
41
49
|
loadProperty<TT extends T, P extends string = never, K extends keyof TT = keyof TT>(prop: K, options?: LoadReferenceOrFailOptions<TT, P>): Promise<Loaded<TT, P>[K]>;
|
|
50
|
+
/** Returns whether the underlying entity has been fully loaded from the database. */
|
|
42
51
|
isInitialized(): boolean;
|
|
52
|
+
/** Marks the underlying entity as populated or not for serialization purposes. */
|
|
43
53
|
populated(populated?: boolean): void;
|
|
54
|
+
/** Serializes the underlying entity to a plain JSON object. */
|
|
44
55
|
toJSON(...args: any[]): Dictionary;
|
|
45
56
|
}
|
|
57
|
+
/** Wrapper for lazy scalar properties that provides on-demand loading from the database. */
|
|
46
58
|
export declare class ScalarReference<Value> {
|
|
47
59
|
#private;
|
|
48
60
|
private value?;
|
|
@@ -58,15 +70,23 @@ export declare class ScalarReference<Value> {
|
|
|
58
70
|
* Returns the entity or throws an error just like `em.findOneOrFail()` (and respects the same config options).
|
|
59
71
|
*/
|
|
60
72
|
loadOrFail(options?: Omit<LoadReferenceOrFailOptions<any, any>, 'populate' | 'fields' | 'exclude'>): Promise<Value>;
|
|
73
|
+
/** Sets the scalar value and marks the reference as initialized. */
|
|
61
74
|
set(value: Value): void;
|
|
75
|
+
/** Binds this scalar reference to a specific entity and property for lazy loading support. */
|
|
62
76
|
bind<Entity extends object>(entity: Entity, property: EntityKey<Entity>): void;
|
|
77
|
+
/** Returns the current scalar value, or undefined if not yet loaded. */
|
|
63
78
|
unwrap(): Value | undefined;
|
|
79
|
+
/** Returns whether the scalar value has been loaded. */
|
|
64
80
|
isInitialized(): boolean;
|
|
65
81
|
}
|
|
82
|
+
/** Options for `Reference.load()` to control how the referenced entity is loaded. */
|
|
66
83
|
export interface LoadReferenceOptions<T extends object, P extends string = never, F extends string = '*', E extends string = never> extends FindOneOptions<T, P, F, E> {
|
|
84
|
+
/** Whether to use the dataloader for batching reference loads. */
|
|
67
85
|
dataloader?: boolean;
|
|
68
86
|
}
|
|
87
|
+
/** Options for `Reference.loadOrFail()` which throws when the entity is not found. */
|
|
69
88
|
export interface LoadReferenceOrFailOptions<T extends object, P extends string = never, F extends string = '*', E extends string = never> extends FindOneOrFailOptions<T, P, F, E> {
|
|
89
|
+
/** Whether to use the dataloader for batching reference loads. */
|
|
70
90
|
dataloader?: boolean;
|
|
71
91
|
}
|
|
72
92
|
/**
|
package/entity/Reference.js
CHANGED
|
@@ -4,6 +4,7 @@ import { Utils } from '../utils/Utils.js';
|
|
|
4
4
|
import { QueryHelper } from '../utils/QueryHelper.js';
|
|
5
5
|
import { NotFoundError } from '../errors.js';
|
|
6
6
|
import { inspect } from '../logging/inspect.js';
|
|
7
|
+
/** Wrapper around an entity that provides lazy loading capabilities and identity-preserving reference semantics. */
|
|
7
8
|
export class Reference {
|
|
8
9
|
entity;
|
|
9
10
|
property;
|
|
@@ -26,6 +27,7 @@ export class Reference {
|
|
|
26
27
|
});
|
|
27
28
|
}
|
|
28
29
|
}
|
|
30
|
+
/** Creates a Reference wrapper for the given entity, preserving identity if one already exists. */
|
|
29
31
|
static create(entity) {
|
|
30
32
|
const unwrapped = Reference.unwrapReference(entity);
|
|
31
33
|
const ref = helper(entity).toReference();
|
|
@@ -34,10 +36,12 @@ export class Reference {
|
|
|
34
36
|
}
|
|
35
37
|
return ref;
|
|
36
38
|
}
|
|
39
|
+
/** Creates a Reference wrapper for an entity identified by its primary key, wrapped in a Ref. */
|
|
37
40
|
static createFromPK(entityType, pk, options) {
|
|
38
41
|
const ref = this.createNakedFromPK(entityType, pk, options);
|
|
39
42
|
return helper(ref)?.toReference() ?? ref;
|
|
40
43
|
}
|
|
44
|
+
/** Creates an uninitialized entity reference by primary key without wrapping it in a Reference. */
|
|
41
45
|
static createNakedFromPK(entityType, pk, options) {
|
|
42
46
|
const factory = entityType.prototype.__factory;
|
|
43
47
|
if (!factory) {
|
|
@@ -121,28 +125,35 @@ export class Reference {
|
|
|
121
125
|
this.entity = Reference.unwrapReference(entity);
|
|
122
126
|
delete helper(this.entity).__reference;
|
|
123
127
|
}
|
|
128
|
+
/** Returns the underlying entity without checking initialization state. */
|
|
124
129
|
unwrap() {
|
|
125
130
|
return this.entity;
|
|
126
131
|
}
|
|
132
|
+
/** Returns the underlying entity, throwing an error if the reference is not initialized. */
|
|
127
133
|
getEntity() {
|
|
128
134
|
if (!this.isInitialized()) {
|
|
129
135
|
throw new Error(`Reference<${helper(this.entity).__meta.name}> ${helper(this.entity).getPrimaryKey()} not initialized`);
|
|
130
136
|
}
|
|
131
137
|
return this.entity;
|
|
132
138
|
}
|
|
139
|
+
/** Returns the value of a property on the underlying entity. Throws if the reference is not initialized. */
|
|
133
140
|
getProperty(prop) {
|
|
134
141
|
return this.getEntity()[prop];
|
|
135
142
|
}
|
|
143
|
+
/** Loads the entity if needed, then returns the value of the specified property. */
|
|
136
144
|
async loadProperty(prop, options) {
|
|
137
145
|
await this.loadOrFail(options);
|
|
138
146
|
return this.getEntity()[prop];
|
|
139
147
|
}
|
|
148
|
+
/** Returns whether the underlying entity has been fully loaded from the database. */
|
|
140
149
|
isInitialized() {
|
|
141
150
|
return helper(this.entity).__initialized;
|
|
142
151
|
}
|
|
152
|
+
/** Marks the underlying entity as populated or not for serialization purposes. */
|
|
143
153
|
populated(populated) {
|
|
144
154
|
helper(this.entity).populated(populated);
|
|
145
155
|
}
|
|
156
|
+
/** Serializes the underlying entity to a plain JSON object. */
|
|
146
157
|
toJSON(...args) {
|
|
147
158
|
return wrap(this.entity).toJSON(...args);
|
|
148
159
|
}
|
|
@@ -160,6 +171,7 @@ export class Reference {
|
|
|
160
171
|
return ret === '[Object]' ? `[${name}]` : name + ' ' + ret;
|
|
161
172
|
}
|
|
162
173
|
}
|
|
174
|
+
/** Wrapper for lazy scalar properties that provides on-demand loading from the database. */
|
|
163
175
|
export class ScalarReference {
|
|
164
176
|
value;
|
|
165
177
|
entity;
|
|
@@ -197,18 +209,22 @@ export class ScalarReference {
|
|
|
197
209
|
}
|
|
198
210
|
return ret;
|
|
199
211
|
}
|
|
212
|
+
/** Sets the scalar value and marks the reference as initialized. */
|
|
200
213
|
set(value) {
|
|
201
214
|
this.value = value;
|
|
202
215
|
this.#initialized = true;
|
|
203
216
|
}
|
|
217
|
+
/** Binds this scalar reference to a specific entity and property for lazy loading support. */
|
|
204
218
|
bind(entity, property) {
|
|
205
219
|
this.entity = entity;
|
|
206
220
|
this.#property = property;
|
|
207
221
|
Object.defineProperty(this, 'entity', { enumerable: false, value: entity });
|
|
208
222
|
}
|
|
223
|
+
/** Returns the current scalar value, or undefined if not yet loaded. */
|
|
209
224
|
unwrap() {
|
|
210
225
|
return this.value;
|
|
211
226
|
}
|
|
227
|
+
/** Returns whether the scalar value has been loaded. */
|
|
212
228
|
isInitialized() {
|
|
213
229
|
return this.#initialized;
|
|
214
230
|
}
|