@mikro-orm/core 6.4.7-dev.1 → 7.0.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EntityManager.d.ts +3 -2
- package/EntityManager.js +119 -101
- package/MikroORM.d.ts +8 -8
- package/MikroORM.js +1 -1
- package/README.md +0 -2
- package/connections/Connection.d.ts +3 -7
- package/drivers/DatabaseDriver.js +2 -6
- package/entity/Collection.js +8 -8
- package/entity/Reference.js +5 -5
- package/events/EventManager.js +4 -4
- package/events/TransactionEventBroadcaster.d.ts +1 -5
- package/events/TransactionEventBroadcaster.js +6 -9
- package/index.mjs +2 -0
- package/logging/Logger.d.ts +1 -1
- package/metadata/MetadataDiscovery.js +12 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +1 -1
- package/naming-strategy/NamingStrategy.d.ts +1 -1
- package/package.json +3 -3
- package/platforms/Platform.d.ts +13 -4
- package/platforms/Platform.js +26 -6
- package/serialization/EntitySerializer.js +2 -1
- package/serialization/EntityTransformer.js +2 -1
- package/typings.d.ts +12 -4
- package/typings.js +23 -6
- package/unit-of-work/ChangeSetComputer.d.ts +1 -1
- package/unit-of-work/ChangeSetComputer.js +9 -9
- package/unit-of-work/ChangeSetPersister.d.ts +1 -1
- package/unit-of-work/ChangeSetPersister.js +19 -18
- package/unit-of-work/UnitOfWork.js +1 -1
- package/utils/AbstractSchemaGenerator.js +3 -1
- package/utils/Configuration.d.ts +6 -20
- package/utils/Configuration.js +11 -5
- package/utils/ConfigurationLoader.js +7 -8
- package/utils/DataloaderUtils.d.ts +0 -2
- package/utils/DataloaderUtils.js +0 -10
- package/utils/QueryHelper.js +5 -5
- package/utils/RawQueryFragment.d.ts +2 -0
- package/utils/RawQueryFragment.js +8 -2
- package/utils/Utils.d.ts +1 -1
- package/utils/Utils.js +1 -1
package/typings.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { Transaction } from './connections';
|
|
2
2
|
import { type Cascade, type DeferMode, type EventType, type LoadStrategy, type PopulatePath, type QueryOrderMap, ReferenceKind } from './enums';
|
|
3
|
-
import { type AssignOptions
|
|
3
|
+
import { type AssignOptions } from './entity/EntityAssigner';
|
|
4
|
+
import { type EntityIdentifier } from './entity/EntityIdentifier';
|
|
5
|
+
import { type EntityLoaderOptions } from './entity/EntityLoader';
|
|
6
|
+
import { type Collection } from './entity/Collection';
|
|
7
|
+
import { type EntityFactory } from './entity/EntityFactory';
|
|
8
|
+
import { type EntityRepository } from './entity/EntityRepository';
|
|
9
|
+
import { Reference, type ScalarReference } from './entity/Reference';
|
|
4
10
|
import type { MikroORM } from './MikroORM';
|
|
5
11
|
import type { SerializationContext, SerializeOptions } from './serialization';
|
|
6
12
|
import type { EntitySchema, MetadataStorage } from './metadata';
|
|
7
13
|
import type { Type, types } from './types';
|
|
8
14
|
import type { Platform } from './platforms';
|
|
9
|
-
import type { Configuration } from './utils';
|
|
15
|
+
import type { Configuration, RawQueryFragment } from './utils';
|
|
10
16
|
import type { EntityManager } from './EntityManager';
|
|
11
17
|
import type { EmbeddedPrefixMode } from './decorators/Embedded';
|
|
12
18
|
import type { EventSubscriber } from './events';
|
|
@@ -391,7 +397,7 @@ export declare class EntityMetadata<T = any> {
|
|
|
391
397
|
getPrimaryProp(): EntityProperty<T>;
|
|
392
398
|
get tableName(): string;
|
|
393
399
|
set tableName(name: string);
|
|
394
|
-
sync(initIndexes?: boolean): void;
|
|
400
|
+
sync(initIndexes?: boolean, config?: Configuration): void;
|
|
395
401
|
private initIndexes;
|
|
396
402
|
/** @internal */
|
|
397
403
|
clone(): this;
|
|
@@ -407,7 +413,7 @@ export interface EntityMetadata<T = any> {
|
|
|
407
413
|
schema?: string;
|
|
408
414
|
pivotTable?: boolean;
|
|
409
415
|
virtual?: boolean;
|
|
410
|
-
expression?: string | ((em: any, where: FilterQuery<T>, options: FindOptions<T, any, any, any>) => MaybePromise<object | string>);
|
|
416
|
+
expression?: string | ((em: any, where: FilterQuery<T>, options: FindOptions<T, any, any, any>) => MaybePromise<RawQueryFragment | object | string>);
|
|
411
417
|
discriminatorColumn?: EntityKey<T> | AnyString;
|
|
412
418
|
discriminatorValue?: number | string;
|
|
413
419
|
discriminatorMap?: Dictionary<string>;
|
|
@@ -505,6 +511,7 @@ export interface UpdateSchemaOptions<DatabaseSchema = unknown> {
|
|
|
505
511
|
export interface RefreshDatabaseOptions extends CreateSchemaOptions {
|
|
506
512
|
ensureIndexes?: boolean;
|
|
507
513
|
dropDb?: boolean;
|
|
514
|
+
createSchema?: boolean;
|
|
508
515
|
}
|
|
509
516
|
export interface ISchemaGenerator {
|
|
510
517
|
createSchema(options?: CreateSchemaOptions): Promise<void>;
|
|
@@ -577,6 +584,7 @@ export type MigrationResult = {
|
|
|
577
584
|
diff: MigrationDiff;
|
|
578
585
|
};
|
|
579
586
|
export type MigrationRow = {
|
|
587
|
+
id: number;
|
|
580
588
|
name: string;
|
|
581
589
|
executed_at: Date;
|
|
582
590
|
};
|
package/typings.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EntityMetadata = exports.Config = exports.HiddenProps = exports.EagerProps = exports.OptionalProps = exports.PrimaryKeyProp = exports.EntityRepositoryType = void 0;
|
|
4
4
|
const enums_1 = require("./enums");
|
|
5
|
-
const
|
|
5
|
+
const Reference_1 = require("./entity/Reference");
|
|
6
|
+
const EntityHelper_1 = require("./entity/EntityHelper");
|
|
6
7
|
const Utils_1 = require("./utils/Utils");
|
|
7
8
|
const EntityComparator_1 = require("./utils/EntityComparator");
|
|
8
9
|
exports.EntityRepositoryType = Symbol('EntityRepositoryType');
|
|
@@ -59,7 +60,7 @@ class EntityMetadata {
|
|
|
59
60
|
set tableName(name) {
|
|
60
61
|
this.collection = name;
|
|
61
62
|
}
|
|
62
|
-
sync(initIndexes = false) {
|
|
63
|
+
sync(initIndexes = false, config) {
|
|
63
64
|
this.root ??= this;
|
|
64
65
|
const props = Object.values(this.properties).sort((a, b) => this.propertyOrder.get(a.name) - this.propertyOrder.get(b.name));
|
|
65
66
|
this.props = [...props.filter(p => p.primary), ...props.filter(p => !p.primary)];
|
|
@@ -82,6 +83,22 @@ class EntityMetadata {
|
|
|
82
83
|
this.selfReferencing = this.relations.some(prop => [this.className, this.root.className].includes(prop.targetMeta?.root.className ?? prop.type));
|
|
83
84
|
this.hasUniqueProps = this.uniques.length + this.uniqueProps.length > 0;
|
|
84
85
|
this.virtual = !!this.expression;
|
|
86
|
+
if (config) {
|
|
87
|
+
for (const prop of this.props) {
|
|
88
|
+
if (prop.enum && !prop.nativeEnumName && prop.items?.every(item => Utils_1.Utils.isString(item))) {
|
|
89
|
+
const name = config.getNamingStrategy().indexName(this.tableName, prop.fieldNames, 'check');
|
|
90
|
+
const exists = this.checks.findIndex(check => check.name === name);
|
|
91
|
+
if (exists !== -1) {
|
|
92
|
+
this.checks.splice(exists, 1);
|
|
93
|
+
}
|
|
94
|
+
this.checks.push({
|
|
95
|
+
name,
|
|
96
|
+
property: prop.name,
|
|
97
|
+
expression: `${config.getPlatform().quoteIdentifier(prop.fieldNames[0])} in ('${prop.items.join("', '")}')`,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
85
102
|
this.checks = Utils_1.Utils.removeDuplicates(this.checks);
|
|
86
103
|
this.indexes = Utils_1.Utils.removeDuplicates(this.indexes);
|
|
87
104
|
this.uniques = Utils_1.Utils.removeDuplicates(this.uniques);
|
|
@@ -107,9 +124,9 @@ class EntityMetadata {
|
|
|
107
124
|
set(val) {
|
|
108
125
|
const wrapped = this.__helper;
|
|
109
126
|
const hydrator = wrapped.hydrator;
|
|
110
|
-
const entity =
|
|
111
|
-
const old =
|
|
112
|
-
wrapped.__data[prop.name] =
|
|
127
|
+
const entity = Reference_1.Reference.unwrapReference(val ?? wrapped.__data[prop.name]);
|
|
128
|
+
const old = Reference_1.Reference.unwrapReference(wrapped.__data[prop.name]);
|
|
129
|
+
wrapped.__data[prop.name] = Reference_1.Reference.wrapReference(val, prop);
|
|
113
130
|
// when propagation from inside hydration, we set the FK to the entity data immediately
|
|
114
131
|
if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
|
|
115
132
|
wrapped.__originalEntityData[prop.name] = Utils_1.Utils.getPrimaryKeyValues(val, prop.targetMeta.primaryKeys, true);
|
|
@@ -117,7 +134,7 @@ class EntityMetadata {
|
|
|
117
134
|
else {
|
|
118
135
|
wrapped.__touched = !hydrator.isRunning();
|
|
119
136
|
}
|
|
120
|
-
|
|
137
|
+
EntityHelper_1.EntityHelper.propagate(meta, entity, this, prop, Reference_1.Reference.unwrapReference(val), old);
|
|
121
138
|
},
|
|
122
139
|
enumerable: true,
|
|
123
140
|
configurable: true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ChangeSetComputer = void 0;
|
|
4
|
-
const
|
|
4
|
+
const Utils_1 = require("../utils/Utils");
|
|
5
5
|
const ChangeSet_1 = require("./ChangeSet");
|
|
6
6
|
const entity_1 = require("../entity");
|
|
7
7
|
const enums_1 = require("../enums");
|
|
@@ -48,7 +48,7 @@ class ChangeSetComputer {
|
|
|
48
48
|
for (const prop of meta.relations.filter(prop => prop.persist !== false || prop.userDefined === false)) {
|
|
49
49
|
this.processProperty(changeSet, prop);
|
|
50
50
|
}
|
|
51
|
-
if (changeSet.type === ChangeSet_1.ChangeSetType.UPDATE && !
|
|
51
|
+
if (changeSet.type === ChangeSet_1.ChangeSetType.UPDATE && !Utils_1.Utils.hasObjectKeys(changeSet.payload)) {
|
|
52
52
|
return null;
|
|
53
53
|
}
|
|
54
54
|
// Execute `onCreate` and `onUpdate` on properties recursively, saves `onUpdate` results
|
|
@@ -66,7 +66,7 @@ class ChangeSetComputer {
|
|
|
66
66
|
}
|
|
67
67
|
// Recompute the changeset, we need to merge this as here we ignore relations.
|
|
68
68
|
const diff = this.computePayload(entity, true);
|
|
69
|
-
|
|
69
|
+
Utils_1.Utils.merge(changeSet.payload, diff);
|
|
70
70
|
}
|
|
71
71
|
return changeSet;
|
|
72
72
|
}
|
|
@@ -77,7 +77,7 @@ class ChangeSetComputer {
|
|
|
77
77
|
if (prop.onCreate
|
|
78
78
|
&& type === ChangeSet_1.ChangeSetType.CREATE
|
|
79
79
|
&& (entity[prop.name] == null
|
|
80
|
-
|| (
|
|
80
|
+
|| (Utils_1.Utils.isScalarReference(entity[prop.name]) && entity[prop.name].unwrap() == null))) {
|
|
81
81
|
entity[prop.name] = prop.onCreate(entity, this.em);
|
|
82
82
|
}
|
|
83
83
|
if (prop.onUpdate && type === ChangeSet_1.ChangeSetType.UPDATE) {
|
|
@@ -106,7 +106,7 @@ class ChangeSetComputer {
|
|
|
106
106
|
const comparator = this.comparator.getEntityComparator(entityName);
|
|
107
107
|
const diff = comparator(originalEntityData, data);
|
|
108
108
|
if (ignoreUndefined) {
|
|
109
|
-
|
|
109
|
+
Utils_1.Utils.keys(diff)
|
|
110
110
|
.filter(k => diff[k] === undefined)
|
|
111
111
|
.forEach(k => delete diff[k]);
|
|
112
112
|
}
|
|
@@ -116,11 +116,11 @@ class ChangeSetComputer {
|
|
|
116
116
|
}
|
|
117
117
|
processProperty(changeSet, prop, target) {
|
|
118
118
|
if (!target) {
|
|
119
|
-
const targets =
|
|
119
|
+
const targets = Utils_1.Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
|
|
120
120
|
targets.forEach(([t]) => this.processProperty(changeSet, prop, t));
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
|
-
if (
|
|
123
|
+
if (Utils_1.Utils.isCollection(target)) { // m:n or 1:m
|
|
124
124
|
this.processToMany(prop, changeSet);
|
|
125
125
|
}
|
|
126
126
|
if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
@@ -132,10 +132,10 @@ class ChangeSetComputer {
|
|
|
132
132
|
if (!isToOneOwner || prop.mapToPk) {
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
135
|
-
const targets =
|
|
135
|
+
const targets = Utils_1.Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
|
|
136
136
|
targets.forEach(([target, idx]) => {
|
|
137
137
|
if (!target.__helper.hasPrimaryKey()) {
|
|
138
|
-
|
|
138
|
+
Utils_1.Utils.setPayloadProperty(changeSet.payload, this.metadata.find(changeSet.name), prop, target.__helper.__identifier, idx);
|
|
139
139
|
}
|
|
140
140
|
});
|
|
141
141
|
}
|
|
@@ -2,7 +2,7 @@ import type { MetadataStorage } from '../metadata';
|
|
|
2
2
|
import type { Dictionary, EntityDictionary, EntityMetadata, IHydrator } from '../typings';
|
|
3
3
|
import { type EntityFactory, type EntityValidator } from '../entity';
|
|
4
4
|
import { type ChangeSet } from './ChangeSet';
|
|
5
|
-
import { type Configuration } from '../utils';
|
|
5
|
+
import { type Configuration } from '../utils/Configuration';
|
|
6
6
|
import type { DriverMethodOptions, IDatabaseDriver } from '../drivers';
|
|
7
7
|
export declare class ChangeSetPersister {
|
|
8
8
|
private readonly driver;
|
|
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ChangeSetPersister = void 0;
|
|
4
4
|
const entity_1 = require("../entity");
|
|
5
5
|
const ChangeSet_1 = require("./ChangeSet");
|
|
6
|
-
const
|
|
6
|
+
const RawQueryFragment_1 = require("../utils/RawQueryFragment");
|
|
7
|
+
const Utils_1 = require("../utils/Utils");
|
|
7
8
|
const errors_1 = require("../errors");
|
|
8
9
|
const enums_1 = require("../enums");
|
|
9
10
|
class ChangeSetPersister {
|
|
@@ -59,7 +60,7 @@ class ChangeSetPersister {
|
|
|
59
60
|
}
|
|
60
61
|
const size = this.config.get('batchSize');
|
|
61
62
|
const meta = changeSets[0].meta;
|
|
62
|
-
const pk =
|
|
63
|
+
const pk = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
|
|
63
64
|
for (let i = 0; i < changeSets.length; i += size) {
|
|
64
65
|
const chunk = changeSets.slice(i, i + size);
|
|
65
66
|
const pks = chunk.map(cs => cs.getPrimaryKey());
|
|
@@ -190,7 +191,7 @@ class ChangeSetPersister {
|
|
|
190
191
|
}
|
|
191
192
|
const res = await this.driver.nativeUpdateMany(meta.className, cond, payload, options);
|
|
192
193
|
const map = new Map();
|
|
193
|
-
res.rows?.forEach(item => map.set(
|
|
194
|
+
res.rows?.forEach(item => map.set(Utils_1.Utils.getCompositeKeyHash(item, meta, true, this.platform, true), item));
|
|
194
195
|
for (const changeSet of changeSets) {
|
|
195
196
|
if (res.rows) {
|
|
196
197
|
const row = map.get((0, entity_1.helper)(changeSet.entity).getSerializedPrimaryKey());
|
|
@@ -224,10 +225,10 @@ class ChangeSetPersister {
|
|
|
224
225
|
(0, entity_1.helper)(changeSet.entity).populated();
|
|
225
226
|
meta.relations.forEach(prop => {
|
|
226
227
|
const value = changeSet.entity[prop.name];
|
|
227
|
-
if (
|
|
228
|
+
if (Utils_1.Utils.isEntity(value, true)) {
|
|
228
229
|
value.__helper.populated();
|
|
229
230
|
}
|
|
230
|
-
else if (
|
|
231
|
+
else if (Utils_1.Utils.isCollection(value)) {
|
|
231
232
|
value.populated();
|
|
232
233
|
}
|
|
233
234
|
});
|
|
@@ -253,7 +254,7 @@ class ChangeSetPersister {
|
|
|
253
254
|
// skip entity references as they don't have version values loaded
|
|
254
255
|
changeSets = changeSets.filter(cs => (0, entity_1.helper)(cs.entity).__initialized);
|
|
255
256
|
const $or = changeSets.map(cs => {
|
|
256
|
-
const cond =
|
|
257
|
+
const cond = Utils_1.Utils.getPrimaryKeyCond(cs.originalEntity, meta.primaryKeys.concat(...meta.concurrencyCheckKeys));
|
|
257
258
|
if (meta.versionProperty) {
|
|
258
259
|
// @ts-ignore
|
|
259
260
|
cond[meta.versionProperty] = this.platform.quoteVersionValue(cs.entity[meta.versionProperty], meta.properties[meta.versionProperty]);
|
|
@@ -268,7 +269,7 @@ class ChangeSetPersister {
|
|
|
268
269
|
if (res.length !== changeSets.length) {
|
|
269
270
|
const compare = (a, b, keys) => keys.every(k => a[k] === b[k]);
|
|
270
271
|
const entity = changeSets.find(cs => {
|
|
271
|
-
return !res.some(row => compare(
|
|
272
|
+
return !res.some(row => compare(Utils_1.Utils.getPrimaryKeyCond(cs.entity, primaryKeys), row, primaryKeys));
|
|
272
273
|
}).entity;
|
|
273
274
|
throw errors_1.OptimisticLockError.lockFailed(entity);
|
|
274
275
|
}
|
|
@@ -288,14 +289,14 @@ class ChangeSetPersister {
|
|
|
288
289
|
// do not reload things that already had a runtime value
|
|
289
290
|
meta.props
|
|
290
291
|
.filter(prop => prop.persist !== false && (prop.autoincrement || prop.generated || prop.defaultRaw))
|
|
291
|
-
.filter(prop => (changeSets[0].entity[prop.name] == null && prop.defaultRaw !== 'null') ||
|
|
292
|
+
.filter(prop => (changeSets[0].entity[prop.name] == null && prop.defaultRaw !== 'null') || (0, RawQueryFragment_1.isRaw)(changeSets[0].entity[prop.name]))
|
|
292
293
|
.forEach(prop => reloadProps.push(prop));
|
|
293
294
|
}
|
|
294
295
|
if (changeSets[0].type === ChangeSet_1.ChangeSetType.UPDATE) {
|
|
295
296
|
const returning = new Set();
|
|
296
297
|
changeSets.forEach(cs => {
|
|
297
|
-
|
|
298
|
-
if (
|
|
298
|
+
Utils_1.Utils.keys(cs.payload).forEach(k => {
|
|
299
|
+
if ((0, RawQueryFragment_1.isRaw)(cs.payload[k]) && (0, RawQueryFragment_1.isRaw)(cs.entity[k])) {
|
|
299
300
|
returning.add(meta.properties[k]);
|
|
300
301
|
}
|
|
301
302
|
});
|
|
@@ -312,20 +313,20 @@ class ChangeSetPersister {
|
|
|
312
313
|
return;
|
|
313
314
|
}
|
|
314
315
|
reloadProps.unshift(...meta.getPrimaryProps());
|
|
315
|
-
const pk =
|
|
316
|
+
const pk = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
|
|
316
317
|
const pks = changeSets.map(cs => {
|
|
317
318
|
const val = (0, entity_1.helper)(cs.entity).getPrimaryKey(true);
|
|
318
|
-
if (
|
|
319
|
-
return
|
|
319
|
+
if (Utils_1.Utils.isPlainObject(val)) {
|
|
320
|
+
return Utils_1.Utils.getCompositeKeyValue(val, meta, false, this.platform);
|
|
320
321
|
}
|
|
321
322
|
return val;
|
|
322
323
|
});
|
|
323
324
|
options = this.propagateSchemaFromMetadata(meta, options, {
|
|
324
|
-
fields:
|
|
325
|
+
fields: Utils_1.Utils.unique(reloadProps.map(prop => prop.name)),
|
|
325
326
|
});
|
|
326
327
|
const data = await this.driver.find(meta.className, { [pk]: { $in: pks } }, options);
|
|
327
328
|
const map = new Map();
|
|
328
|
-
data.forEach(item => map.set(
|
|
329
|
+
data.forEach(item => map.set(Utils_1.Utils.getCompositeKeyHash(item, meta, true, this.platform, true), item));
|
|
329
330
|
for (const changeSet of changeSets) {
|
|
330
331
|
const data = map.get((0, entity_1.helper)(changeSet.entity).getSerializedPrimaryKey());
|
|
331
332
|
this.hydrator.hydrate(changeSet.entity, meta, data, this.factory, 'full', false, true);
|
|
@@ -346,10 +347,10 @@ class ChangeSetPersister {
|
|
|
346
347
|
if (prop.name in changeSet.payload) {
|
|
347
348
|
return;
|
|
348
349
|
}
|
|
349
|
-
const values =
|
|
350
|
+
const values = Utils_1.Utils.unwrapProperty(changeSet.payload, meta, prop, true); // for object embeddables
|
|
350
351
|
values.forEach(([value, indexes]) => {
|
|
351
352
|
if (value instanceof entity_1.EntityIdentifier) {
|
|
352
|
-
|
|
353
|
+
Utils_1.Utils.setPayloadProperty(changeSet.payload, meta, prop, value.getValue(), indexes);
|
|
353
354
|
}
|
|
354
355
|
});
|
|
355
356
|
}
|
|
@@ -359,7 +360,7 @@ class ChangeSetPersister {
|
|
|
359
360
|
* We do need to map to the change set payload too, as it will be used in the originalEntityData for new entities.
|
|
360
361
|
*/
|
|
361
362
|
mapReturnedValues(entity, payload, row, meta, upsert = false) {
|
|
362
|
-
if ((!this.usesReturningStatement && !upsert) || !row || !
|
|
363
|
+
if ((!this.usesReturningStatement && !upsert) || !row || !Utils_1.Utils.hasObjectKeys(row)) {
|
|
363
364
|
return;
|
|
364
365
|
}
|
|
365
366
|
const mapped = this.comparator.mapResult(meta.className, row);
|
|
@@ -313,7 +313,7 @@ class UnitOfWork {
|
|
|
313
313
|
if (runInTransaction) {
|
|
314
314
|
await this.em.getConnection('write').transactional(trx => this.persistToDatabase(groups, trx), {
|
|
315
315
|
ctx: oldTx,
|
|
316
|
-
eventBroadcaster: new events_1.TransactionEventBroadcaster(this.em
|
|
316
|
+
eventBroadcaster: new events_1.TransactionEventBroadcaster(this.em),
|
|
317
317
|
});
|
|
318
318
|
}
|
|
319
319
|
else {
|
|
@@ -37,7 +37,9 @@ class AbstractSchemaGenerator {
|
|
|
37
37
|
await this.ensureDatabase();
|
|
38
38
|
await this.dropSchema();
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
if (options?.createSchema !== false) {
|
|
41
|
+
await this.createSchema(options);
|
|
42
|
+
}
|
|
41
43
|
}
|
|
42
44
|
async clearDatabase(options) {
|
|
43
45
|
for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
|
package/utils/Configuration.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { NamingStrategy } from '../naming-strategy';
|
|
|
2
2
|
import { FileCacheAdapter, type SyncCacheAdapter, type CacheAdapter } from '../cache';
|
|
3
3
|
import type { EntityRepository } from '../entity/EntityRepository';
|
|
4
4
|
import type { AnyEntity, Constructor, Dictionary, EntityClass, EntityClassGroup, FilterDef, Highlighter, HydratorConstructor, IHydrator, IMigrationGenerator, IPrimaryKey, MaybePromise, MigrationObject, EntityMetadata, EnsureDatabaseOptions, GenerateOptions, Migration } from '../typings';
|
|
5
|
-
import { ObjectHydrator } from '../hydration';
|
|
5
|
+
import { ObjectHydrator } from '../hydration/ObjectHydrator';
|
|
6
6
|
import { NullHighlighter } from '../utils/NullHighlighter';
|
|
7
7
|
import { type Logger, type LoggerNamespace, type LoggerOptions } from '../logging';
|
|
8
8
|
import type { EntityManager } from '../EntityManager';
|
|
@@ -150,6 +150,7 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
|
|
|
150
150
|
private readonly cache;
|
|
151
151
|
private readonly extensions;
|
|
152
152
|
constructor(options: Options, validate?: boolean);
|
|
153
|
+
getPlatform(): ReturnType<D['getPlatform']>;
|
|
153
154
|
/**
|
|
154
155
|
* Gets specific configuration option. Falls back to specified `defaultValue` if provided.
|
|
155
156
|
*/
|
|
@@ -167,7 +168,7 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
|
|
|
167
168
|
* Gets Logger instance.
|
|
168
169
|
*/
|
|
169
170
|
getLogger(): Logger;
|
|
170
|
-
|
|
171
|
+
getDataloaderType(): DataloaderType;
|
|
171
172
|
/**
|
|
172
173
|
* Gets current client URL (connection string).
|
|
173
174
|
*/
|
|
@@ -231,10 +232,6 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
|
|
|
231
232
|
* Type helper to make it easier to use `mikro-orm.config.js`.
|
|
232
233
|
*/
|
|
233
234
|
export declare function defineConfig<D extends IDatabaseDriver>(options: Options<D>): Options<D, D[typeof EntityManagerType] & EntityManager<IDatabaseDriver<import("..").Connection>>>;
|
|
234
|
-
export interface DynamicPassword {
|
|
235
|
-
password: string;
|
|
236
|
-
expirationChecker?: () => boolean;
|
|
237
|
-
}
|
|
238
235
|
export interface ConnectionOptions {
|
|
239
236
|
dbName?: string;
|
|
240
237
|
schema?: string;
|
|
@@ -243,12 +240,13 @@ export interface ConnectionOptions {
|
|
|
243
240
|
host?: string;
|
|
244
241
|
port?: number;
|
|
245
242
|
user?: string;
|
|
246
|
-
password?: string | (() => MaybePromise<string>
|
|
243
|
+
password?: string | (() => MaybePromise<string>);
|
|
247
244
|
charset?: string;
|
|
248
245
|
collate?: string;
|
|
249
246
|
multipleStatements?: boolean;
|
|
250
247
|
pool?: PoolConfig;
|
|
251
248
|
driverOptions?: Dictionary;
|
|
249
|
+
onCreateConnection?: (connection: unknown) => Promise<void>;
|
|
252
250
|
}
|
|
253
251
|
export type MigrationsOptions = {
|
|
254
252
|
tableName?: string;
|
|
@@ -277,21 +275,9 @@ export interface SeederOptions {
|
|
|
277
275
|
fileName?: (className: string) => string;
|
|
278
276
|
}
|
|
279
277
|
export interface PoolConfig {
|
|
280
|
-
name?: string;
|
|
281
|
-
afterCreate?: Function;
|
|
282
278
|
min?: number;
|
|
283
279
|
max?: number;
|
|
284
|
-
refreshIdle?: boolean;
|
|
285
280
|
idleTimeoutMillis?: number;
|
|
286
|
-
reapIntervalMillis?: number;
|
|
287
|
-
returnToHead?: boolean;
|
|
288
|
-
priorityRange?: number;
|
|
289
|
-
log?: (message: string, logLevel: string) => void;
|
|
290
|
-
propagateCreateError?: boolean;
|
|
291
|
-
createRetryIntervalMillis?: number;
|
|
292
|
-
createTimeoutMillis?: number;
|
|
293
|
-
destroyTimeoutMillis?: number;
|
|
294
|
-
acquireTimeoutMillis?: number;
|
|
295
281
|
}
|
|
296
282
|
export interface MetadataDiscoveryOptions {
|
|
297
283
|
warnWhenNoEntities?: boolean;
|
|
@@ -330,7 +316,7 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
|
|
|
330
316
|
connect: boolean;
|
|
331
317
|
verbose: boolean;
|
|
332
318
|
ignoreUndefinedInQuery?: boolean;
|
|
333
|
-
onQuery: (sql: string, params: unknown[]) => string;
|
|
319
|
+
onQuery: (sql: string, params: readonly unknown[]) => string;
|
|
334
320
|
autoJoinOneToOneOwner: boolean;
|
|
335
321
|
autoJoinRefsForFilters: boolean;
|
|
336
322
|
propagationOnPrototype: boolean;
|
package/utils/Configuration.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.Configuration = void 0;
|
|
|
4
4
|
exports.defineConfig = defineConfig;
|
|
5
5
|
const fs_extra_1 = require("fs-extra");
|
|
6
6
|
const cache_1 = require("../cache");
|
|
7
|
-
const
|
|
7
|
+
const ObjectHydrator_1 = require("../hydration/ObjectHydrator");
|
|
8
8
|
const NullHighlighter_1 = require("../utils/NullHighlighter");
|
|
9
9
|
const logging_1 = require("../logging");
|
|
10
10
|
const Utils_1 = require("../utils/Utils");
|
|
@@ -45,7 +45,7 @@ class Configuration {
|
|
|
45
45
|
findOneOrFailHandler: (entityName, where) => errors_1.NotFoundError.findOneFailed(entityName, where),
|
|
46
46
|
findExactlyOneOrFailHandler: (entityName, where) => errors_1.NotFoundError.findExactlyOneFailed(entityName, where),
|
|
47
47
|
baseDir: process.cwd(),
|
|
48
|
-
hydrator:
|
|
48
|
+
hydrator: ObjectHydrator_1.ObjectHydrator,
|
|
49
49
|
flushMode: enums_1.FlushMode.AUTO,
|
|
50
50
|
loadStrategy: enums_1.LoadStrategy.JOINED,
|
|
51
51
|
dataloader: enums_1.DataloaderType.NONE,
|
|
@@ -167,6 +167,9 @@ class Configuration {
|
|
|
167
167
|
this.init(validate);
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
|
+
getPlatform() {
|
|
171
|
+
return this.platform;
|
|
172
|
+
}
|
|
170
173
|
/**
|
|
171
174
|
* Gets specific configuration option. Falls back to specified `defaultValue` if provided.
|
|
172
175
|
*/
|
|
@@ -198,8 +201,11 @@ class Configuration {
|
|
|
198
201
|
getLogger() {
|
|
199
202
|
return this.logger;
|
|
200
203
|
}
|
|
201
|
-
|
|
202
|
-
|
|
204
|
+
getDataloaderType() {
|
|
205
|
+
if (typeof this.options.dataloader === 'boolean') {
|
|
206
|
+
return this.options.dataloader ? enums_1.DataloaderType.ALL : enums_1.DataloaderType.NONE;
|
|
207
|
+
}
|
|
208
|
+
return this.options.dataloader;
|
|
203
209
|
}
|
|
204
210
|
/**
|
|
205
211
|
* Gets current client URL (connection string).
|
|
@@ -306,7 +312,7 @@ class Configuration {
|
|
|
306
312
|
this.options.metadataCache.enabled = this.getMetadataProvider().useCache();
|
|
307
313
|
}
|
|
308
314
|
if (!this.options.clientUrl) {
|
|
309
|
-
this.options.clientUrl = this.
|
|
315
|
+
this.options.clientUrl = this.platform.getDefaultClientUrl();
|
|
310
316
|
}
|
|
311
317
|
if (!('implicitTransactions' in this.options)) {
|
|
312
318
|
this.options.implicitTransactions = this.platform.usesImplicitTransactions();
|
|
@@ -225,14 +225,13 @@ class ConfigurationLoader {
|
|
|
225
225
|
const ret = {};
|
|
226
226
|
// only to keep some sort of back compatibility with those using env vars only, to support `MIKRO_ORM_TYPE`
|
|
227
227
|
const PLATFORMS = {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
'libsql': { className: 'LibSqlDriver', module: '@mikro-orm/libsql' },
|
|
228
|
+
mongo: { className: 'MongoDriver', module: '@mikro-orm/mongodb' },
|
|
229
|
+
mysql: { className: 'MySqlDriver', module: '@mikro-orm/mysql' },
|
|
230
|
+
mssql: { className: 'MsSqlDriver', module: '@mikro-orm/mssql' },
|
|
231
|
+
mariadb: { className: 'MariaDbDriver', module: '@mikro-orm/mariadb' },
|
|
232
|
+
postgresql: { className: 'PostgreSqlDriver', module: '@mikro-orm/postgresql' },
|
|
233
|
+
sqlite: { className: 'SqliteDriver', module: '@mikro-orm/sqlite' },
|
|
234
|
+
libsql: { className: 'LibSqlDriver', module: '@mikro-orm/libsql' },
|
|
236
235
|
};
|
|
237
236
|
const array = (v) => v.split(',').map(vv => vv.trim());
|
|
238
237
|
const bool = (v) => ['true', 't', '1'].includes(v.toLowerCase());
|
|
@@ -2,7 +2,6 @@ import type { Primary, Ref } from '../typings';
|
|
|
2
2
|
import { Collection, type InitCollectionOptions } from '../entity/Collection';
|
|
3
3
|
import { type EntityManager } from '../EntityManager';
|
|
4
4
|
import type DataLoader from 'dataloader';
|
|
5
|
-
import { DataloaderType } from '../enums';
|
|
6
5
|
import { type LoadReferenceOptions } from '../entity/Reference';
|
|
7
6
|
export declare class DataloaderUtils {
|
|
8
7
|
/**
|
|
@@ -39,5 +38,4 @@ export declare class DataloaderUtils {
|
|
|
39
38
|
* makes one query per entity and maps each input collection to the corresponding result.
|
|
40
39
|
*/
|
|
41
40
|
static getColBatchLoadFn(em: EntityManager): DataLoader.BatchLoadFn<[Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?], any>;
|
|
42
|
-
static getDataloaderType(dataloaderCfg: DataloaderType | boolean): DataloaderType;
|
|
43
41
|
}
|
package/utils/DataloaderUtils.js
CHANGED
|
@@ -182,15 +182,5 @@ class DataloaderUtils {
|
|
|
182
182
|
});
|
|
183
183
|
};
|
|
184
184
|
}
|
|
185
|
-
static getDataloaderType(dataloaderCfg) {
|
|
186
|
-
switch (dataloaderCfg) {
|
|
187
|
-
case true:
|
|
188
|
-
return enums_1.DataloaderType.ALL;
|
|
189
|
-
case false:
|
|
190
|
-
return enums_1.DataloaderType.NONE;
|
|
191
|
-
default:
|
|
192
|
-
return dataloaderCfg;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
185
|
}
|
|
196
186
|
exports.DataloaderUtils = DataloaderUtils;
|
package/utils/QueryHelper.js
CHANGED
|
@@ -74,7 +74,7 @@ class QueryHelper {
|
|
|
74
74
|
if (meta && root) {
|
|
75
75
|
QueryHelper.inlinePrimaryKeyObjects(where, meta, metadata);
|
|
76
76
|
}
|
|
77
|
-
if (
|
|
77
|
+
if (platform.getConfig().get('ignoreUndefinedInQuery') && where && typeof where === 'object') {
|
|
78
78
|
Utils_1.Utils.dropUndefinedProperties(where);
|
|
79
79
|
}
|
|
80
80
|
where = QueryHelper.processParams(where) ?? {};
|
|
@@ -112,15 +112,15 @@ class QueryHelper {
|
|
|
112
112
|
return o;
|
|
113
113
|
}
|
|
114
114
|
// wrap top level operators (except platform allowed operators) with PK
|
|
115
|
-
if (Utils_1.Utils.isOperator(key) && root && meta && !
|
|
115
|
+
if (Utils_1.Utils.isOperator(key) && root && meta && !platform.isAllowedTopLevelOperator(key)) {
|
|
116
116
|
const rootPrimaryKey = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
|
|
117
117
|
o[rootPrimaryKey] = { [key]: QueryHelper.processWhere({ ...options, where: value, root: false }) };
|
|
118
118
|
return o;
|
|
119
119
|
}
|
|
120
|
-
if (prop?.customType && convertCustomTypes && !
|
|
120
|
+
if (prop?.customType && convertCustomTypes && !(0, RawQueryFragment_1.isRaw)(value)) {
|
|
121
121
|
value = QueryHelper.processCustomType(prop, value, platform, undefined, true);
|
|
122
122
|
}
|
|
123
|
-
const isJsonProperty = prop?.customType instanceof JsonType_1.JsonType && Utils_1.Utils.isPlainObject(value) && !
|
|
123
|
+
const isJsonProperty = prop?.customType instanceof JsonType_1.JsonType && Utils_1.Utils.isPlainObject(value) && !(0, RawQueryFragment_1.isRaw)(value) && Object.keys(value)[0] !== '$eq';
|
|
124
124
|
if (isJsonProperty) {
|
|
125
125
|
return this.processJsonCondition(o, value, [prop.fieldNames[0]], platform, aliased);
|
|
126
126
|
}
|
|
@@ -191,7 +191,7 @@ class QueryHelper {
|
|
|
191
191
|
if (Array.isArray(cond) && !(key && Utils_1.Utils.isArrayOperator(key))) {
|
|
192
192
|
return cond.map(v => QueryHelper.processCustomType(prop, v, platform, key, fromQuery));
|
|
193
193
|
}
|
|
194
|
-
if (
|
|
194
|
+
if ((0, RawQueryFragment_1.isRaw)(cond)) {
|
|
195
195
|
return cond;
|
|
196
196
|
}
|
|
197
197
|
return prop.customType.convertToDatabaseValue(cond, platform, { fromQuery, key, mode: 'query' });
|
|
@@ -30,6 +30,8 @@ export declare class RawQueryFragment {
|
|
|
30
30
|
params?: undefined;
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
+
export { RawQueryFragment as Raw };
|
|
34
|
+
export declare function isRaw(value: unknown): value is RawQueryFragment;
|
|
33
35
|
/** @internal */
|
|
34
36
|
export declare const ALIAS_REPLACEMENT = "[::alias::]";
|
|
35
37
|
/** @internal */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ALIAS_REPLACEMENT_RE = exports.ALIAS_REPLACEMENT = exports.RawQueryFragment = void 0;
|
|
3
|
+
exports.ALIAS_REPLACEMENT_RE = exports.ALIAS_REPLACEMENT = exports.Raw = exports.RawQueryFragment = void 0;
|
|
4
|
+
exports.isRaw = isRaw;
|
|
4
5
|
exports.raw = raw;
|
|
5
6
|
exports.sql = sql;
|
|
6
7
|
exports.createSqlFunction = createSqlFunction;
|
|
@@ -102,9 +103,13 @@ class RawQueryFragment {
|
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
105
|
exports.RawQueryFragment = RawQueryFragment;
|
|
106
|
+
exports.Raw = RawQueryFragment;
|
|
105
107
|
Object.defineProperties(RawQueryFragment.prototype, {
|
|
106
108
|
__raw: { value: true, enumerable: false },
|
|
107
109
|
});
|
|
110
|
+
function isRaw(value) {
|
|
111
|
+
return typeof value === 'object' && value !== null && '__raw' in value;
|
|
112
|
+
}
|
|
108
113
|
/** @internal */
|
|
109
114
|
exports.ALIAS_REPLACEMENT = '[::alias::]';
|
|
110
115
|
/** @internal */
|
|
@@ -164,7 +169,8 @@ function raw(sql, params) {
|
|
|
164
169
|
const pairs = Object.entries(params);
|
|
165
170
|
const objectParams = [];
|
|
166
171
|
for (const [key, value] of pairs) {
|
|
167
|
-
sql = sql.replace(
|
|
172
|
+
sql = sql.replace(`:${key}:`, '??');
|
|
173
|
+
sql = sql.replace(`:${key}`, '?');
|
|
168
174
|
objectParams.push(value);
|
|
169
175
|
}
|
|
170
176
|
return new RawQueryFragment(sql, objectParams);
|
package/utils/Utils.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export declare class Utils {
|
|
|
75
75
|
/**
|
|
76
76
|
* Merges all sources into the target recursively. Ignores `undefined` values.
|
|
77
77
|
*/
|
|
78
|
-
static mergeConfig(target:
|
|
78
|
+
static mergeConfig<T>(target: T, ...sources: Dictionary[]): T;
|
|
79
79
|
/**
|
|
80
80
|
* Merges all sources into the target recursively.
|
|
81
81
|
*/
|
package/utils/Utils.js
CHANGED
|
@@ -44,7 +44,7 @@ function compareObjects(a, b) {
|
|
|
44
44
|
if (!a || !b || typeof a !== 'object' || typeof b !== 'object' || !compareConstructors(a, b)) {
|
|
45
45
|
return false;
|
|
46
46
|
}
|
|
47
|
-
if (
|
|
47
|
+
if (a.__raw && b.__raw) {
|
|
48
48
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
49
49
|
return a.sql === b.sql && compareArrays(a.params, b.params);
|
|
50
50
|
}
|