@mikro-orm/core 6.3.10-dev.8 → 6.3.10
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.js +2 -1
- package/MikroORM.d.ts +2 -2
- package/MikroORM.js +4 -1
- package/decorators/CreateRequestContext.js +4 -6
- package/entity/EntityLoader.d.ts +1 -0
- package/entity/EntityLoader.js +18 -9
- package/hydration/ObjectHydrator.js +7 -2
- package/metadata/MetadataDiscovery.js +5 -1
- package/package.json +2 -2
- package/typings.d.ts +1 -1
- package/unit-of-work/ChangeSetComputer.js +3 -5
- package/unit-of-work/ChangeSetPersister.js +4 -3
- package/utils/Utils.d.ts +0 -1
- package/utils/Utils.js +4 -0
package/EntityManager.js
CHANGED
|
@@ -1538,11 +1538,12 @@ class EntityManager {
|
|
|
1538
1538
|
// we need to prune the `populate` hint from to-one relations, as partially loading them does not require their population, we want just the FK
|
|
1539
1539
|
const pruneToOneRelations = (meta, fields) => {
|
|
1540
1540
|
const ret = [];
|
|
1541
|
-
for (
|
|
1541
|
+
for (let field of fields) {
|
|
1542
1542
|
if (field === enums_1.PopulatePath.ALL || field.startsWith(`${enums_1.PopulatePath.ALL}.`)) {
|
|
1543
1543
|
ret.push(...meta.props.filter(prop => prop.lazy || [enums_1.ReferenceKind.SCALAR, enums_1.ReferenceKind.EMBEDDED].includes(prop.kind)).map(prop => prop.name));
|
|
1544
1544
|
continue;
|
|
1545
1545
|
}
|
|
1546
|
+
field = field.split(':')[0];
|
|
1546
1547
|
if (!field.includes('.') && ![enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(meta.properties[field].kind)) {
|
|
1547
1548
|
ret.push(field);
|
|
1548
1549
|
continue;
|
package/MikroORM.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EntityManagerType, IDatabaseDriver } from './drivers';
|
|
2
|
-
import { MetadataStorage } from './metadata';
|
|
2
|
+
import { MetadataStorage, type EntitySchema } from './metadata';
|
|
3
3
|
import { Configuration, type Options } from './utils';
|
|
4
4
|
import type { EntityManager } from './EntityManager';
|
|
5
5
|
import type { Constructor, EntityMetadata, EntityName, IEntityGenerator, IMigrator, ISeedManager } from './typings';
|
|
@@ -66,7 +66,7 @@ export declare class MikroORM<D extends IDatabaseDriver = IDatabaseDriver, EM ex
|
|
|
66
66
|
/**
|
|
67
67
|
* Allows dynamically discovering new entity by reference, handy for testing schema diffing.
|
|
68
68
|
*/
|
|
69
|
-
discoverEntity(entities:
|
|
69
|
+
discoverEntity<T extends Constructor | EntitySchema>(entities: T | T[]): void;
|
|
70
70
|
/**
|
|
71
71
|
* Gets the SchemaGenerator.
|
|
72
72
|
*/
|
package/MikroORM.js
CHANGED
|
@@ -192,7 +192,10 @@ class MikroORM {
|
|
|
192
192
|
const options = this.config.get('discovery');
|
|
193
193
|
new metadata_1.MetadataValidator().validateDiscovered([...Object.values(this.metadata.getAll()), ...tmp], options);
|
|
194
194
|
const metadata = this.discovery.processDiscoveredEntities(tmp);
|
|
195
|
-
metadata.forEach(meta =>
|
|
195
|
+
metadata.forEach(meta => {
|
|
196
|
+
this.metadata.set(meta.className, meta);
|
|
197
|
+
meta.root = this.metadata.get(meta.root.className);
|
|
198
|
+
});
|
|
196
199
|
this.metadata.decorate(this.em);
|
|
197
200
|
}
|
|
198
201
|
/**
|
|
@@ -11,15 +11,9 @@ function CreateRequestContext(getContext, respectExistingContext = false) {
|
|
|
11
11
|
return function (target, propertyKey, descriptor) {
|
|
12
12
|
const originalMethod = descriptor.value;
|
|
13
13
|
descriptor.value = async function (...args) {
|
|
14
|
-
// reuse existing context if available
|
|
15
|
-
if (respectExistingContext && RequestContext_1.RequestContext.currentRequestContext()) {
|
|
16
|
-
return originalMethod.apply(this, args);
|
|
17
|
-
}
|
|
18
|
-
// If we are inside explicit transaction context, we need to create another tx context.
|
|
19
14
|
// Otherwise, the outer tx context would be preferred.
|
|
20
15
|
const txContext = TransactionContext_1.TransactionContext.currentTransactionContext();
|
|
21
16
|
const provider = txContext ? TransactionContext_1.TransactionContext : RequestContext_1.RequestContext;
|
|
22
|
-
/* istanbul ignore next */
|
|
23
17
|
let orm;
|
|
24
18
|
let em;
|
|
25
19
|
if (typeof getContext === 'function') {
|
|
@@ -35,6 +29,10 @@ function CreateRequestContext(getContext, respectExistingContext = false) {
|
|
|
35
29
|
em = await this.em;
|
|
36
30
|
}
|
|
37
31
|
const create = async (em) => {
|
|
32
|
+
// reuse existing context if available for given respect `contextName`
|
|
33
|
+
if (respectExistingContext && RequestContext_1.RequestContext.getEntityManager(em.name)) {
|
|
34
|
+
return originalMethod.apply(this, args);
|
|
35
|
+
}
|
|
38
36
|
if (txContext) {
|
|
39
37
|
em = em.fork({ useContext: true });
|
|
40
38
|
}
|
package/entity/EntityLoader.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ export declare class EntityLoader {
|
|
|
42
42
|
* preload everything in one call (this will update already existing references in IM)
|
|
43
43
|
*/
|
|
44
44
|
private populateMany;
|
|
45
|
+
private populateScalar;
|
|
45
46
|
private initializeCollections;
|
|
46
47
|
private initializeOneToMany;
|
|
47
48
|
private initializeManyToMany;
|
package/entity/EntityLoader.js
CHANGED
|
@@ -118,20 +118,18 @@ class EntityLoader {
|
|
|
118
118
|
const [field, ref] = populate.field.split(':', 2);
|
|
119
119
|
const meta = this.metadata.find(entityName);
|
|
120
120
|
const prop = meta.properties[field];
|
|
121
|
+
if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && prop.owner && !this.driver.getPlatform().usesPivotTable()) {
|
|
122
|
+
const filtered = entities.filter(e => !e[prop.name]?.isInitialized());
|
|
123
|
+
if (filtered.length > 0) {
|
|
124
|
+
await this.populateScalar(meta, filtered, options, prop);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
121
127
|
if (prop.kind === enums_1.ReferenceKind.SCALAR && prop.lazy) {
|
|
122
128
|
const filtered = entities.filter(e => options.refresh || (prop.ref ? !e[prop.name]?.isInitialized() : e[prop.name] === undefined));
|
|
123
129
|
if (options.ignoreLazyScalarProperties || filtered.length === 0) {
|
|
124
130
|
return entities;
|
|
125
131
|
}
|
|
126
|
-
|
|
127
|
-
const ids = Utils_1.Utils.unique(filtered.map(e => Utils_1.Utils.getPrimaryKeyValues(e, meta.primaryKeys, true)));
|
|
128
|
-
const where = this.mergePrimaryCondition(ids, pk, options, meta, this.metadata, this.driver.getPlatform());
|
|
129
|
-
const { filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging } = options;
|
|
130
|
-
await this.em.find(meta.className, where, {
|
|
131
|
-
filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging,
|
|
132
|
-
fields: [prop.name],
|
|
133
|
-
populate: [],
|
|
134
|
-
});
|
|
132
|
+
await this.populateScalar(meta, filtered, options, prop);
|
|
135
133
|
return entities;
|
|
136
134
|
}
|
|
137
135
|
if (prop.kind === enums_1.ReferenceKind.EMBEDDED) {
|
|
@@ -149,6 +147,17 @@ class EntityLoader {
|
|
|
149
147
|
this.initializeCollections(filtered, prop, field, data, innerOrderBy.length > 0);
|
|
150
148
|
return data;
|
|
151
149
|
}
|
|
150
|
+
async populateScalar(meta, filtered, options, prop) {
|
|
151
|
+
const pk = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
|
|
152
|
+
const ids = Utils_1.Utils.unique(filtered.map(e => Utils_1.Utils.getPrimaryKeyValues(e, meta.primaryKeys, true)));
|
|
153
|
+
const where = this.mergePrimaryCondition(ids, pk, options, meta, this.metadata, this.driver.getPlatform());
|
|
154
|
+
const { filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging } = options;
|
|
155
|
+
await this.em.find(meta.className, where, {
|
|
156
|
+
filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging,
|
|
157
|
+
fields: [prop.name],
|
|
158
|
+
populate: [],
|
|
159
|
+
});
|
|
160
|
+
}
|
|
152
161
|
initializeCollections(filtered, prop, field, children, customOrder) {
|
|
153
162
|
if (prop.kind === enums_1.ReferenceKind.ONE_TO_MANY) {
|
|
154
163
|
this.initializeOneToMany(filtered, children, prop, field);
|
|
@@ -165,9 +165,14 @@ class ObjectHydrator extends Hydrator_1.Hydrator {
|
|
|
165
165
|
ret.push(` }`);
|
|
166
166
|
ret.push(` } else if (!entity${entityKey} && data${dataKey} instanceof Collection) {`);
|
|
167
167
|
ret.push(` entity${entityKey} = data${dataKey};`);
|
|
168
|
+
if (!this.platform.usesPivotTable() && prop.owner && prop.kind === enums_1.ReferenceKind.MANY_TO_MANY) {
|
|
169
|
+
ret.push(` } else if (!entity${entityKey} && Array.isArray(data${dataKey})) {`);
|
|
170
|
+
const items = this.platform.usesPivotTable() || !prop.owner ? 'undefined' : '[]';
|
|
171
|
+
ret.push(` const coll = Collection.create(entity, '${prop.name}', ${items}, !!data${dataKey} || newEntity);`);
|
|
172
|
+
ret.push(` coll.setDirty(false);`);
|
|
173
|
+
}
|
|
168
174
|
ret.push(` } else if (!entity${entityKey}) {`);
|
|
169
|
-
const
|
|
170
|
-
ret.push(` const coll = Collection.create(entity, '${prop.name}', ${items}, !!data${dataKey} || newEntity);`);
|
|
175
|
+
ret.push(` const coll = Collection.create(entity, '${prop.name}', undefined, newEntity);`);
|
|
171
176
|
ret.push(` coll.setDirty(false);`);
|
|
172
177
|
ret.push(` }`);
|
|
173
178
|
return ret;
|
|
@@ -121,7 +121,11 @@ class MetadataDiscovery {
|
|
|
121
121
|
if (combinedCachePath) {
|
|
122
122
|
this.config.get('metadataCache').combined = combinedCachePath;
|
|
123
123
|
}
|
|
124
|
-
return discovered.map(meta =>
|
|
124
|
+
return discovered.map(meta => {
|
|
125
|
+
meta = this.metadata.get(meta.className);
|
|
126
|
+
meta.sync(true);
|
|
127
|
+
return meta;
|
|
128
|
+
});
|
|
125
129
|
}
|
|
126
130
|
findEntities(preferTsNode, sync = false) {
|
|
127
131
|
this.discovered.length = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "6.3.10
|
|
3
|
+
"version": "6.3.10",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"esprima": "4.0.1",
|
|
65
65
|
"fs-extra": "11.2.0",
|
|
66
66
|
"globby": "11.1.0",
|
|
67
|
-
"mikro-orm": "6.3.10
|
|
67
|
+
"mikro-orm": "6.3.10",
|
|
68
68
|
"reflect-metadata": "0.2.2"
|
|
69
69
|
}
|
|
70
70
|
}
|
package/typings.d.ts
CHANGED
|
@@ -683,7 +683,7 @@ export type AutoPath<O, P extends string | boolean, E extends string = never, D
|
|
|
683
683
|
export type UnboxArray<T> = T extends any[] ? ArrayElement<T> : T;
|
|
684
684
|
export type ArrayElement<ArrayType extends unknown[]> = ArrayType extends (infer ElementType)[] ? ElementType : never;
|
|
685
685
|
export type ExpandProperty<T> = T extends Reference<infer U> ? NonNullable<U> : T extends Collection<infer U, any> ? NonNullable<U> : T extends (infer U)[] ? NonNullable<U> : NonNullable<T>;
|
|
686
|
-
type LoadedLoadable<T, E extends object> = T extends Collection<any, any> ? LoadedCollection<E> : T extends Reference<any> ? LoadedReference<E> : T extends ScalarReference<infer U> ? LoadedScalarReference<U> : T extends Scalar | any[] ? T : E;
|
|
686
|
+
type LoadedLoadable<T, E extends object> = T extends Collection<any, any> ? LoadedCollection<E> : T extends Reference<any> ? T & LoadedReference<E> : T extends ScalarReference<infer U> ? LoadedScalarReference<U> : T extends Scalar | any[] ? T : E;
|
|
687
687
|
type IsTrue<T> = IsNever<T> extends true ? false : T extends boolean ? T extends true ? true : false : false;
|
|
688
688
|
type StringLiteral<T> = T extends string ? string extends T ? never : T : never;
|
|
689
689
|
type Prefix<T, K> = K extends `${infer S}.${string}` ? S : (K extends '*' ? keyof T : K);
|
|
@@ -141,14 +141,12 @@ class ChangeSetComputer {
|
|
|
141
141
|
}
|
|
142
142
|
processToMany(prop, changeSet) {
|
|
143
143
|
const target = changeSet.entity[prop.name];
|
|
144
|
-
if (!target.isDirty()) {
|
|
144
|
+
if (!target.isDirty() && changeSet.type !== ChangeSet_1.ChangeSetType.CREATE) {
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
147
|
this.collectionUpdates.add(target);
|
|
148
|
-
if (prop.owner
|
|
149
|
-
|
|
150
|
-
changeSet.payload[prop.name] = target.getItems(false).map((item) => item.__helper.__identifier ?? item.__helper.getPrimaryKey());
|
|
151
|
-
}
|
|
148
|
+
if (prop.owner && !this.platform.usesPivotTable()) {
|
|
149
|
+
changeSet.payload[prop.name] = target.getItems(false).map((item) => item.__helper.__identifier ?? item.__helper.getPrimaryKey());
|
|
152
150
|
}
|
|
153
151
|
}
|
|
154
152
|
}
|
|
@@ -185,12 +185,13 @@ class ChangeSetPersister {
|
|
|
185
185
|
this.checkConcurrencyKeys(meta, changeSet, cond[idx]);
|
|
186
186
|
});
|
|
187
187
|
const res = await this.driver.nativeUpdateMany(meta.className, cond, changeSets.map(cs => cs.payload), options);
|
|
188
|
-
|
|
188
|
+
for (const changeSet of changeSets) {
|
|
189
189
|
if (res.rows) {
|
|
190
|
-
|
|
190
|
+
const row = res.rows.find(row => utils_1.Utils.equals(utils_1.Utils.extractPK(row, meta), changeSet.getPrimaryKey()));
|
|
191
|
+
this.mapReturnedValues(changeSet.entity, changeSet.payload, row, meta);
|
|
191
192
|
}
|
|
192
193
|
changeSet.persisted = true;
|
|
193
|
-
}
|
|
194
|
+
}
|
|
194
195
|
}
|
|
195
196
|
mapPrimaryKey(meta, value, changeSet) {
|
|
196
197
|
const prop = meta.properties[meta.primaryKeys[0]];
|
package/utils/Utils.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type GlobbyOptions } from 'globby';
|
|
2
|
-
import { type URL } from 'node:url';
|
|
3
2
|
import type { Dictionary, EntityData, EntityDictionary, EntityKey, EntityMetadata, EntityName, EntityProperty, IMetadataStorage, Primary } from '../typings';
|
|
4
3
|
import type { Collection } from '../entity/Collection';
|
|
5
4
|
import type { Platform } from '../platforms';
|
package/utils/Utils.js
CHANGED
|
@@ -881,6 +881,10 @@ class Utils {
|
|
|
881
881
|
catch {
|
|
882
882
|
// ignore
|
|
883
883
|
}
|
|
884
|
+
// For some reason, ".ts" files do not work with "file://" URLs on Windows.
|
|
885
|
+
if (id.endsWith('.ts')) {
|
|
886
|
+
id = (0, node_url_1.fileURLToPath)(id);
|
|
887
|
+
}
|
|
884
888
|
}
|
|
885
889
|
/* istanbul ignore next */
|
|
886
890
|
return this.dynamicImportProvider(id);
|