@mikro-orm/core 7.0.0-dev.5 → 7.0.0-dev.50
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 +81 -27
- package/EntityManager.js +287 -175
- package/MikroORM.d.ts +6 -6
- package/MikroORM.js +31 -74
- package/README.md +3 -2
- package/cache/FileCacheAdapter.d.ts +2 -1
- package/cache/FileCacheAdapter.js +6 -4
- package/connections/Connection.d.ts +9 -5
- package/connections/Connection.js +16 -13
- package/decorators/Embedded.d.ts +5 -11
- package/decorators/Entity.d.ts +18 -3
- package/decorators/Indexed.d.ts +2 -2
- package/decorators/ManyToMany.d.ts +2 -0
- package/decorators/ManyToOne.d.ts +4 -0
- package/decorators/OneToOne.d.ts +4 -0
- package/decorators/Property.d.ts +53 -9
- package/decorators/Transactional.d.ts +1 -0
- package/decorators/Transactional.js +3 -3
- package/decorators/index.d.ts +1 -1
- package/drivers/DatabaseDriver.d.ts +10 -5
- package/drivers/DatabaseDriver.js +4 -4
- package/drivers/IDatabaseDriver.d.ts +28 -4
- package/entity/ArrayCollection.d.ts +6 -4
- package/entity/ArrayCollection.js +26 -9
- package/entity/BaseEntity.d.ts +0 -1
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +3 -4
- package/entity/Collection.js +37 -17
- package/entity/EntityAssigner.d.ts +1 -1
- package/entity/EntityAssigner.js +9 -1
- package/entity/EntityFactory.d.ts +7 -0
- package/entity/EntityFactory.js +29 -11
- package/entity/EntityHelper.js +25 -8
- package/entity/EntityLoader.d.ts +5 -4
- package/entity/EntityLoader.js +69 -36
- package/entity/EntityRepository.d.ts +1 -1
- package/entity/EntityValidator.js +1 -1
- package/entity/Reference.d.ts +9 -7
- package/entity/Reference.js +30 -3
- package/entity/WrappedEntity.d.ts +0 -2
- package/entity/WrappedEntity.js +1 -5
- package/entity/defineEntity.d.ts +555 -0
- package/entity/defineEntity.js +529 -0
- package/entity/index.d.ts +2 -0
- package/entity/index.js +2 -0
- package/entity/utils.d.ts +7 -0
- package/entity/utils.js +15 -3
- package/enums.d.ts +16 -3
- package/enums.js +13 -0
- package/errors.d.ts +6 -1
- package/errors.js +14 -4
- package/events/EventSubscriber.d.ts +3 -1
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +35 -24
- package/index.d.ts +2 -1
- package/index.js +1 -1
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/SimpleLogger.d.ts +1 -1
- package/metadata/EntitySchema.d.ts +8 -4
- package/metadata/EntitySchema.js +39 -19
- package/metadata/MetadataDiscovery.d.ts +4 -4
- package/metadata/MetadataDiscovery.js +139 -122
- package/metadata/MetadataStorage.js +1 -1
- package/metadata/MetadataValidator.js +4 -3
- package/naming-strategy/AbstractNamingStrategy.d.ts +5 -1
- package/naming-strategy/AbstractNamingStrategy.js +7 -1
- package/naming-strategy/NamingStrategy.d.ts +11 -1
- package/package.json +5 -5
- package/platforms/Platform.d.ts +5 -3
- package/platforms/Platform.js +4 -8
- package/serialization/EntitySerializer.d.ts +2 -0
- package/serialization/EntitySerializer.js +23 -5
- package/serialization/EntityTransformer.js +16 -6
- package/serialization/SerializationContext.js +14 -11
- package/types/BigIntType.d.ts +9 -6
- package/types/BigIntType.js +3 -0
- package/types/BooleanType.d.ts +1 -1
- package/types/DecimalType.d.ts +6 -4
- package/types/DecimalType.js +1 -1
- package/types/DoubleType.js +1 -1
- package/types/JsonType.d.ts +1 -1
- package/types/JsonType.js +7 -2
- package/types/Type.d.ts +2 -1
- package/types/Type.js +1 -1
- package/types/index.d.ts +1 -1
- package/typings.d.ts +89 -49
- package/typings.js +31 -31
- package/unit-of-work/ChangeSetComputer.js +8 -3
- package/unit-of-work/ChangeSetPersister.d.ts +4 -2
- package/unit-of-work/ChangeSetPersister.js +37 -16
- package/unit-of-work/UnitOfWork.d.ts +8 -1
- package/unit-of-work/UnitOfWork.js +110 -53
- package/utils/AbstractSchemaGenerator.js +3 -1
- package/utils/Configuration.d.ts +29 -16
- package/utils/Configuration.js +17 -18
- package/utils/ConfigurationLoader.d.ts +9 -22
- package/utils/ConfigurationLoader.js +49 -72
- package/utils/Cursor.d.ts +3 -3
- package/utils/Cursor.js +3 -0
- package/utils/DataloaderUtils.d.ts +7 -2
- package/utils/DataloaderUtils.js +38 -7
- package/utils/EntityComparator.d.ts +6 -2
- package/utils/EntityComparator.js +104 -58
- package/utils/QueryHelper.d.ts +9 -1
- package/utils/QueryHelper.js +66 -5
- package/utils/RawQueryFragment.d.ts +36 -4
- package/utils/RawQueryFragment.js +34 -13
- package/utils/TransactionManager.d.ts +65 -0
- package/utils/TransactionManager.js +223 -0
- package/utils/Utils.d.ts +13 -11
- package/utils/Utils.js +82 -55
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/upsert-utils.d.ts +7 -2
- package/utils/upsert-utils.js +52 -1
|
@@ -28,6 +28,12 @@ export declare class UnitOfWork {
|
|
|
28
28
|
private working;
|
|
29
29
|
constructor(em: EntityManager);
|
|
30
30
|
merge<T extends object>(entity: T, visited?: Set<AnyEntity>): void;
|
|
31
|
+
/**
|
|
32
|
+
* Entity data can wary in its shape, e.g. we might get a deep relation graph with joined strategy, but for diffing,
|
|
33
|
+
* we need to normalize the shape, so relation values are only raw FKs. This method handles that.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
normalizeEntityData<T extends object>(meta: EntityMetadata<T>, data: EntityData<T>): void;
|
|
31
37
|
/**
|
|
32
38
|
* @internal
|
|
33
39
|
*/
|
|
@@ -39,7 +45,7 @@ export declare class UnitOfWork {
|
|
|
39
45
|
/**
|
|
40
46
|
* Returns entity from the identity map. For composite keys, you need to pass an array of PKs in the same order as they are defined in `meta.primaryKeys`.
|
|
41
47
|
*/
|
|
42
|
-
getById<T extends object>(entityName: string, id: Primary<T> | Primary<T>[], schema?: string): T | undefined;
|
|
48
|
+
getById<T extends object>(entityName: string, id: Primary<T> | Primary<T>[], schema?: string, convertCustomTypes?: boolean): T | undefined;
|
|
43
49
|
tryGetById<T extends object>(entityName: string, where: FilterQuery<T>, schema?: string, strict?: boolean): T | null;
|
|
44
50
|
/**
|
|
45
51
|
* Returns map of all managed entities.
|
|
@@ -103,6 +109,7 @@ export declare class UnitOfWork {
|
|
|
103
109
|
private commitDeleteChangeSets;
|
|
104
110
|
private commitExtraUpdates;
|
|
105
111
|
private commitCollectionUpdates;
|
|
112
|
+
private filterCollectionUpdates;
|
|
106
113
|
/**
|
|
107
114
|
* Orders change sets so FK constrains are maintained, ensures stable order (needed for node < 11)
|
|
108
115
|
*/
|
|
@@ -43,7 +43,7 @@ export class UnitOfWork {
|
|
|
43
43
|
this.eventManager = this.em.getEventManager();
|
|
44
44
|
this.comparator = this.em.getComparator();
|
|
45
45
|
this.changeSetComputer = new ChangeSetComputer(this.em.getValidator(), this.collectionUpdates, this.metadata, this.platform, this.em.config, this.em);
|
|
46
|
-
this.changeSetPersister = new ChangeSetPersister(this.em.getDriver(), this.metadata, this.em.config.getHydrator(this.metadata), this.em.getEntityFactory(), this.em.getValidator(), this.em.config);
|
|
46
|
+
this.changeSetPersister = new ChangeSetPersister(this.em.getDriver(), this.metadata, this.em.config.getHydrator(this.metadata), this.em.getEntityFactory(), this.em.getValidator(), this.em.config, this.em);
|
|
47
47
|
}
|
|
48
48
|
merge(entity, visited) {
|
|
49
49
|
const wrapped = helper(entity);
|
|
@@ -61,10 +61,43 @@ export class UnitOfWork {
|
|
|
61
61
|
// as there can be some entity with already changed state that is not yet flushed
|
|
62
62
|
if (wrapped.__initialized && (!visited || !wrapped.__originalEntityData)) {
|
|
63
63
|
wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
|
|
64
|
-
wrapped.__touched = false;
|
|
65
64
|
}
|
|
66
65
|
this.cascade(entity, Cascade.MERGE, visited ?? new Set());
|
|
67
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Entity data can wary in its shape, e.g. we might get a deep relation graph with joined strategy, but for diffing,
|
|
69
|
+
* we need to normalize the shape, so relation values are only raw FKs. This method handles that.
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
normalizeEntityData(meta, data) {
|
|
73
|
+
const forceUndefined = this.em.config.get('forceUndefined');
|
|
74
|
+
for (const key of Utils.keys(data)) {
|
|
75
|
+
const prop = meta.properties[key];
|
|
76
|
+
if (!prop) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
|
|
80
|
+
data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
|
|
81
|
+
}
|
|
82
|
+
else if (prop.kind === ReferenceKind.EMBEDDED && !prop.object && Utils.isPlainObject(data[prop.name])) {
|
|
83
|
+
for (const p of prop.targetMeta.props) {
|
|
84
|
+
/* v8 ignore next */
|
|
85
|
+
const prefix = prop.prefix === false ? '' : prop.prefix === true ? prop.name + '_' : prop.prefix;
|
|
86
|
+
data[prefix + p.name] = data[prop.name][p.name];
|
|
87
|
+
}
|
|
88
|
+
data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
|
|
89
|
+
}
|
|
90
|
+
if (prop.hydrate === false && prop.customType?.ensureComparable(meta, prop)) {
|
|
91
|
+
const converted = prop.customType.convertToJSValue(data[key], this.platform, { key, mode: 'hydration', force: true });
|
|
92
|
+
data[key] = prop.customType.convertToDatabaseValue(converted, this.platform, { key, mode: 'hydration' });
|
|
93
|
+
}
|
|
94
|
+
if (forceUndefined) {
|
|
95
|
+
if (data[key] === null) {
|
|
96
|
+
data[key] = undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
68
101
|
/**
|
|
69
102
|
* @internal
|
|
70
103
|
*/
|
|
@@ -82,31 +115,14 @@ export class UnitOfWork {
|
|
|
82
115
|
wrapped.__em ??= this.em;
|
|
83
116
|
wrapped.__managed = true;
|
|
84
117
|
if (data && (options?.refresh || !wrapped.__originalEntityData)) {
|
|
118
|
+
this.normalizeEntityData(wrapped.__meta, data);
|
|
85
119
|
for (const key of Utils.keys(data)) {
|
|
86
120
|
const prop = wrapped.__meta.properties[key];
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
wrapped.__loadedProperties.add(key);
|
|
91
|
-
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
|
|
92
|
-
data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta.primaryKeys, true);
|
|
93
|
-
}
|
|
94
|
-
else if (prop.kind === ReferenceKind.EMBEDDED && !prop.object && Utils.isPlainObject(data[prop.name])) {
|
|
95
|
-
for (const p of prop.targetMeta.props) {
|
|
96
|
-
/* v8 ignore next */
|
|
97
|
-
const prefix = prop.prefix === false ? '' : prop.prefix === true ? prop.name + '_' : prop.prefix;
|
|
98
|
-
data[prefix + p.name] = data[prop.name][p.name];
|
|
99
|
-
}
|
|
100
|
-
data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta.primaryKeys, true);
|
|
101
|
-
}
|
|
102
|
-
if (forceUndefined) {
|
|
103
|
-
if (data[key] === null) {
|
|
104
|
-
data[key] = undefined;
|
|
105
|
-
}
|
|
121
|
+
if (prop) {
|
|
122
|
+
wrapped.__loadedProperties.add(key);
|
|
106
123
|
}
|
|
107
124
|
}
|
|
108
125
|
wrapped.__originalEntityData = data;
|
|
109
|
-
wrapped.__touched = false;
|
|
110
126
|
}
|
|
111
127
|
return entity;
|
|
112
128
|
}
|
|
@@ -125,7 +141,7 @@ export class UnitOfWork {
|
|
|
125
141
|
/**
|
|
126
142
|
* Returns entity from the identity map. For composite keys, you need to pass an array of PKs in the same order as they are defined in `meta.primaryKeys`.
|
|
127
143
|
*/
|
|
128
|
-
getById(entityName, id, schema) {
|
|
144
|
+
getById(entityName, id, schema, convertCustomTypes) {
|
|
129
145
|
if (id == null || (Array.isArray(id) && id.length === 0)) {
|
|
130
146
|
return undefined;
|
|
131
147
|
}
|
|
@@ -135,7 +151,16 @@ export class UnitOfWork {
|
|
|
135
151
|
hash = '' + id;
|
|
136
152
|
}
|
|
137
153
|
else {
|
|
138
|
-
|
|
154
|
+
let keys = Array.isArray(id) ? Utils.flatten(id) : [id];
|
|
155
|
+
keys = meta.getPrimaryProps(true).map((p, i) => {
|
|
156
|
+
if (!convertCustomTypes && p.customType) {
|
|
157
|
+
return p.customType.convertToDatabaseValue(keys[i], this.platform, {
|
|
158
|
+
key: p.name,
|
|
159
|
+
mode: 'hydration',
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return keys[i];
|
|
163
|
+
});
|
|
139
164
|
hash = Utils.getPrimaryKeyHash(keys);
|
|
140
165
|
}
|
|
141
166
|
schema ??= meta.schema ?? this.em.config.getSchema();
|
|
@@ -185,10 +210,8 @@ export class UnitOfWork {
|
|
|
185
210
|
if (this.queuedActions.has(meta.className) || this.queuedActions.has(meta.root.className)) {
|
|
186
211
|
return true;
|
|
187
212
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return true;
|
|
191
|
-
}
|
|
213
|
+
if (meta.discriminatorMap && Object.values(meta.discriminatorMap).some(v => this.queuedActions.has(v))) {
|
|
214
|
+
return true;
|
|
192
215
|
}
|
|
193
216
|
return false;
|
|
194
217
|
}
|
|
@@ -209,7 +232,6 @@ export class UnitOfWork {
|
|
|
209
232
|
this.changeSets.set(entity, cs);
|
|
210
233
|
this.persistStack.delete(entity);
|
|
211
234
|
wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
|
|
212
|
-
wrapped.__touched = false;
|
|
213
235
|
}
|
|
214
236
|
recomputeSingleChangeSet(entity) {
|
|
215
237
|
const changeSet = this.changeSets.get(entity);
|
|
@@ -220,7 +242,6 @@ export class UnitOfWork {
|
|
|
220
242
|
if (cs && !this.checkUniqueProps(cs)) {
|
|
221
243
|
Object.assign(changeSet.payload, cs.payload);
|
|
222
244
|
helper(entity).__originalEntityData = this.comparator.prepareEntity(entity);
|
|
223
|
-
helper(entity).__touched = false;
|
|
224
245
|
}
|
|
225
246
|
}
|
|
226
247
|
persist(entity, visited, options = {}) {
|
|
@@ -303,6 +324,7 @@ export class UnitOfWork {
|
|
|
303
324
|
cs.entity.__helper.__processing = true;
|
|
304
325
|
}
|
|
305
326
|
await this.eventManager.dispatchEvent(EventType.onFlush, { em: this.em, uow: this });
|
|
327
|
+
this.filterCollectionUpdates();
|
|
306
328
|
// nothing to do, do not start transaction
|
|
307
329
|
if (this.changeSets.size === 0 && this.collectionUpdates.size === 0 && this.extraUpdates.size === 0) {
|
|
308
330
|
return void (await this.eventManager.dispatchEvent(EventType.afterFlush, { em: this.em, uow: this }));
|
|
@@ -311,9 +333,11 @@ export class UnitOfWork {
|
|
|
311
333
|
const platform = this.em.getPlatform();
|
|
312
334
|
const runInTransaction = !this.em.isInTransaction() && platform.supportsTransactions() && this.em.config.get('implicitTransactions');
|
|
313
335
|
if (runInTransaction) {
|
|
336
|
+
const loggerContext = Utils.merge({ id: this.em._id }, this.em.getLoggerContext({ disableContextResolution: true }));
|
|
314
337
|
await this.em.getConnection('write').transactional(trx => this.persistToDatabase(groups, trx), {
|
|
315
338
|
ctx: oldTx,
|
|
316
339
|
eventBroadcaster: new TransactionEventBroadcaster(this.em),
|
|
340
|
+
loggerContext,
|
|
317
341
|
});
|
|
318
342
|
}
|
|
319
343
|
else {
|
|
@@ -369,7 +393,6 @@ export class UnitOfWork {
|
|
|
369
393
|
}
|
|
370
394
|
delete wrapped.__identifier;
|
|
371
395
|
delete wrapped.__originalEntityData;
|
|
372
|
-
wrapped.__touched = false;
|
|
373
396
|
wrapped.__managed = false;
|
|
374
397
|
}
|
|
375
398
|
computeChangeSets() {
|
|
@@ -379,14 +402,14 @@ export class UnitOfWork {
|
|
|
379
402
|
this.cascade(entity, Cascade.REMOVE, visited);
|
|
380
403
|
}
|
|
381
404
|
visited.clear();
|
|
382
|
-
for (const entity of this.persistStack) {
|
|
383
|
-
this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
|
|
384
|
-
}
|
|
385
405
|
for (const entity of this.identityMap) {
|
|
386
406
|
if (!this.removeStack.has(entity) && !this.persistStack.has(entity) && !this.orphanRemoveStack.has(entity)) {
|
|
387
407
|
this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
|
|
388
408
|
}
|
|
389
409
|
}
|
|
410
|
+
for (const entity of this.persistStack) {
|
|
411
|
+
this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
|
|
412
|
+
}
|
|
390
413
|
visited.clear();
|
|
391
414
|
for (const entity of this.persistStack) {
|
|
392
415
|
this.findNewEntities(entity, visited);
|
|
@@ -542,13 +565,22 @@ export class UnitOfWork {
|
|
|
542
565
|
if (!wrapped || wrapped.__identifier || wrapped.hasPrimaryKey()) {
|
|
543
566
|
return;
|
|
544
567
|
}
|
|
545
|
-
const
|
|
546
|
-
|
|
547
|
-
|
|
568
|
+
const pks = wrapped.__meta.getPrimaryProps();
|
|
569
|
+
const idents = [];
|
|
570
|
+
for (const pk of pks) {
|
|
571
|
+
if (pk.kind === ReferenceKind.SCALAR) {
|
|
572
|
+
idents.push(new EntityIdentifier(entity[pk.name]));
|
|
573
|
+
}
|
|
574
|
+
else if (entity[pk.name]) {
|
|
575
|
+
this.initIdentifier(entity[pk.name]);
|
|
576
|
+
idents.push(helper(entity[pk.name])?.__identifier);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
if (pks.length === 1) {
|
|
580
|
+
wrapped.__identifier = idents[0];
|
|
548
581
|
}
|
|
549
|
-
else
|
|
550
|
-
|
|
551
|
-
wrapped.__identifier = helper(entity[pk.name])?.__identifier;
|
|
582
|
+
else {
|
|
583
|
+
wrapped.__identifier = idents;
|
|
552
584
|
}
|
|
553
585
|
}
|
|
554
586
|
processReference(parent, prop, kind, visited, processed, idx) {
|
|
@@ -600,8 +632,15 @@ export class UnitOfWork {
|
|
|
600
632
|
const diff = this.comparator.diffEntities(changeSet.name, copy, current);
|
|
601
633
|
Object.assign(changeSet.payload, diff);
|
|
602
634
|
const wrapped = helper(changeSet.entity);
|
|
603
|
-
if (wrapped.__identifier
|
|
604
|
-
|
|
635
|
+
if (wrapped.__identifier) {
|
|
636
|
+
const idents = Utils.asArray(wrapped.__identifier);
|
|
637
|
+
let i = 0;
|
|
638
|
+
for (const pk of wrapped.__meta.primaryKeys) {
|
|
639
|
+
if (diff[pk]) {
|
|
640
|
+
idents[i].setValue(diff[pk]);
|
|
641
|
+
}
|
|
642
|
+
i++;
|
|
643
|
+
}
|
|
605
644
|
}
|
|
606
645
|
}
|
|
607
646
|
postCommitCleanup() {
|
|
@@ -825,9 +864,16 @@ export class UnitOfWork {
|
|
|
825
864
|
}
|
|
826
865
|
await this.changeSetPersister.executeUpdates(changeSets, batched, { ctx });
|
|
827
866
|
for (const changeSet of changeSets) {
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
867
|
+
const wrapped = helper(changeSet.entity);
|
|
868
|
+
wrapped.__originalEntityData = this.comparator.prepareEntity(changeSet.entity);
|
|
869
|
+
if (!wrapped.__initialized) {
|
|
870
|
+
for (const prop of changeSet.meta.relations) {
|
|
871
|
+
if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind) && changeSet.entity[prop.name] == null) {
|
|
872
|
+
changeSet.entity[prop.name] = Collection.create(changeSet.entity, prop.name, undefined, wrapped.isInitialized());
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
wrapped.__initialized = true;
|
|
876
|
+
}
|
|
831
877
|
await this.runHooks(EventType.afterUpdate, changeSet);
|
|
832
878
|
}
|
|
833
879
|
}
|
|
@@ -870,23 +916,34 @@ export class UnitOfWork {
|
|
|
870
916
|
}
|
|
871
917
|
}
|
|
872
918
|
async commitCollectionUpdates(ctx) {
|
|
873
|
-
|
|
919
|
+
this.filterCollectionUpdates();
|
|
920
|
+
const loggerContext = Utils.merge({ id: this.em._id }, this.em.getLoggerContext({ disableContextResolution: true }));
|
|
921
|
+
await this.em.getDriver().syncCollections(this.collectionUpdates, {
|
|
922
|
+
ctx,
|
|
923
|
+
schema: this.em.schema,
|
|
924
|
+
loggerContext,
|
|
925
|
+
});
|
|
926
|
+
for (const coll of this.collectionUpdates) {
|
|
927
|
+
coll.takeSnapshot();
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
filterCollectionUpdates() {
|
|
874
931
|
for (const coll of this.collectionUpdates) {
|
|
932
|
+
let skip = true;
|
|
875
933
|
if (coll.property.owner || coll.getItems(false).filter(item => !item.__helper.__initialized).length > 0) {
|
|
876
934
|
if (this.platform.usesPivotTable()) {
|
|
877
|
-
|
|
935
|
+
skip = false;
|
|
878
936
|
}
|
|
879
937
|
}
|
|
880
938
|
else if (coll.property.kind === ReferenceKind.ONE_TO_MANY && coll.getSnapshot() === undefined) {
|
|
881
|
-
|
|
939
|
+
skip = false;
|
|
882
940
|
}
|
|
883
941
|
else if (coll.property.kind === ReferenceKind.MANY_TO_MANY && !coll.property.owner) {
|
|
884
|
-
|
|
942
|
+
skip = false;
|
|
943
|
+
}
|
|
944
|
+
if (skip) {
|
|
945
|
+
this.collectionUpdates.delete(coll);
|
|
885
946
|
}
|
|
886
|
-
}
|
|
887
|
-
await this.em.getDriver().syncCollections(collectionUpdates, { ctx, schema: this.em.schema });
|
|
888
|
-
for (const coll of this.collectionUpdates) {
|
|
889
|
-
coll.takeSnapshot();
|
|
890
947
|
}
|
|
891
948
|
}
|
|
892
949
|
/**
|
|
@@ -42,7 +42,9 @@ export class AbstractSchemaGenerator {
|
|
|
42
42
|
for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
|
|
43
43
|
await this.driver.nativeDelete(meta.className, {}, options);
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
if (options?.clearIdentityMap ?? true) {
|
|
46
|
+
this.clearIdentityMap();
|
|
47
|
+
}
|
|
46
48
|
}
|
|
47
49
|
clearIdentityMap() {
|
|
48
50
|
/* v8 ignore next 3 */
|
package/utils/Configuration.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { NamingStrategy } from '../naming-strategy/NamingStrategy.js';
|
|
|
2
2
|
import { FileCacheAdapter } from '../cache/FileCacheAdapter.js';
|
|
3
3
|
import { type SyncCacheAdapter, type CacheAdapter } from '../cache/CacheAdapter.js';
|
|
4
4
|
import type { EntityRepository } from '../entity/EntityRepository.js';
|
|
5
|
-
import type { AnyEntity, Constructor, Dictionary, EntityClass,
|
|
5
|
+
import type { AnyEntity, Constructor, Dictionary, EntityClass, FilterDef, Highlighter, HydratorConstructor, IHydrator, IMigrationGenerator, IPrimaryKey, MaybePromise, MigrationObject, EntityMetadata, EnsureDatabaseOptions, GenerateOptions, Migration } from '../typings.js';
|
|
6
6
|
import { ObjectHydrator } from '../hydration/ObjectHydrator.js';
|
|
7
7
|
import { NullHighlighter } from '../utils/NullHighlighter.js';
|
|
8
8
|
import { type Logger, type LoggerNamespace, type LoggerOptions } from '../logging/Logger.js';
|
|
@@ -54,14 +54,14 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
|
|
|
54
54
|
baseDir: string;
|
|
55
55
|
hydrator: typeof ObjectHydrator;
|
|
56
56
|
flushMode: FlushMode.AUTO;
|
|
57
|
-
loadStrategy: LoadStrategy.
|
|
57
|
+
loadStrategy: LoadStrategy.BALANCED;
|
|
58
58
|
dataloader: DataloaderType.NONE;
|
|
59
59
|
populateWhere: PopulateHint.ALL;
|
|
60
|
-
connect: true;
|
|
61
60
|
ignoreUndefinedInQuery: false;
|
|
62
61
|
onQuery: (sql: string) => string;
|
|
63
62
|
autoJoinOneToOneOwner: true;
|
|
64
63
|
autoJoinRefsForFilters: true;
|
|
64
|
+
filtersOnRelations: true;
|
|
65
65
|
propagationOnPrototype: true;
|
|
66
66
|
populateAfterFlush: true;
|
|
67
67
|
serialization: {
|
|
@@ -78,9 +78,11 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
|
|
|
78
78
|
upsertManaged: true;
|
|
79
79
|
forceEntityConstructor: false;
|
|
80
80
|
forceUndefined: false;
|
|
81
|
+
processOnCreateHooksEarly: false;
|
|
81
82
|
ensureDatabase: true;
|
|
82
83
|
ensureIndexes: false;
|
|
83
84
|
batchSize: number;
|
|
85
|
+
hashAlgorithm: "md5";
|
|
84
86
|
debug: false;
|
|
85
87
|
ignoreDeprecations: false;
|
|
86
88
|
verbose: false;
|
|
@@ -103,17 +105,21 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
|
|
|
103
105
|
disableForeignKeys: false;
|
|
104
106
|
createForeignKeyConstraints: true;
|
|
105
107
|
ignoreSchema: never[];
|
|
108
|
+
skipTables: never[];
|
|
109
|
+
skipColumns: {};
|
|
106
110
|
};
|
|
107
111
|
embeddables: {
|
|
108
|
-
prefixMode: "
|
|
112
|
+
prefixMode: "relative";
|
|
109
113
|
};
|
|
110
114
|
entityGenerator: {
|
|
111
115
|
forceUndefined: true;
|
|
112
116
|
undefinedDefaults: false;
|
|
113
|
-
bidirectionalRelations: false;
|
|
114
|
-
identifiedReferences: false;
|
|
115
117
|
scalarTypeInDecorator: false;
|
|
118
|
+
bidirectionalRelations: true;
|
|
119
|
+
identifiedReferences: true;
|
|
116
120
|
scalarPropertiesForRelations: "never";
|
|
121
|
+
entityDefinition: "defineEntity";
|
|
122
|
+
enumMode: "dictionary";
|
|
117
123
|
fileName: (className: string) => string;
|
|
118
124
|
onlyPurePivotTables: false;
|
|
119
125
|
outputPurePivotTables: false;
|
|
@@ -170,10 +176,6 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
|
|
|
170
176
|
*/
|
|
171
177
|
getLogger(): Logger;
|
|
172
178
|
getDataloaderType(): DataloaderType;
|
|
173
|
-
/**
|
|
174
|
-
* Gets current client URL (connection string).
|
|
175
|
-
*/
|
|
176
|
-
getClientUrl(hidePassword?: boolean): string;
|
|
177
179
|
getSchema(skipDefaultSchema?: boolean): string | undefined;
|
|
178
180
|
/**
|
|
179
181
|
* Gets current database driver instance.
|
|
@@ -232,7 +234,7 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
|
|
|
232
234
|
/**
|
|
233
235
|
* Type helper to make it easier to use `mikro-orm.config.js`.
|
|
234
236
|
*/
|
|
235
|
-
export declare function defineConfig<D extends IDatabaseDriver>(options: Options<D>): Options<D,
|
|
237
|
+
export declare function defineConfig<D extends IDatabaseDriver = IDatabaseDriver, EM extends EntityManager<D> = EntityManager<D>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: Options<D, EM, Entities>): Options<D, EM, Entities>;
|
|
236
238
|
export interface ConnectionOptions {
|
|
237
239
|
dbName?: string;
|
|
238
240
|
schema?: string;
|
|
@@ -294,10 +296,11 @@ export interface MetadataDiscoveryOptions {
|
|
|
294
296
|
onMetadata?: (meta: EntityMetadata, platform: Platform) => MaybePromise<void>;
|
|
295
297
|
afterDiscovered?: (storage: MetadataStorage, platform: Platform) => MaybePromise<void>;
|
|
296
298
|
tsConfigPath?: string;
|
|
299
|
+
skipSyncDiscovery?: boolean;
|
|
297
300
|
}
|
|
298
301
|
export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM extends EntityManager = EntityManager> extends ConnectionOptions {
|
|
299
|
-
entities: (string | EntityClass<AnyEntity> |
|
|
300
|
-
entitiesTs: (string | EntityClass<AnyEntity> |
|
|
302
|
+
entities: (string | EntityClass<AnyEntity> | EntitySchema)[];
|
|
303
|
+
entitiesTs: (string | EntityClass<AnyEntity> | EntitySchema)[];
|
|
301
304
|
extensions: {
|
|
302
305
|
register: (orm: MikroORM) => void;
|
|
303
306
|
}[];
|
|
@@ -314,12 +317,12 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
|
|
|
314
317
|
};
|
|
315
318
|
implicitTransactions?: boolean;
|
|
316
319
|
disableTransactions?: boolean;
|
|
317
|
-
connect: boolean;
|
|
318
320
|
verbose: boolean;
|
|
319
321
|
ignoreUndefinedInQuery?: boolean;
|
|
320
322
|
onQuery: (sql: string, params: readonly unknown[]) => string;
|
|
321
323
|
autoJoinOneToOneOwner: boolean;
|
|
322
324
|
autoJoinRefsForFilters: boolean;
|
|
325
|
+
filtersOnRelations: boolean;
|
|
323
326
|
propagationOnPrototype: boolean;
|
|
324
327
|
populateAfterFlush: boolean;
|
|
325
328
|
serialization: {
|
|
@@ -332,6 +335,11 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
|
|
|
332
335
|
upsertManaged: boolean;
|
|
333
336
|
forceEntityConstructor: boolean | (Constructor<AnyEntity> | string)[];
|
|
334
337
|
forceUndefined: boolean;
|
|
338
|
+
/**
|
|
339
|
+
* Property `onCreate` hooks are normally executed during `flush` operation.
|
|
340
|
+
* With this option, they will be processed early inside `em.create()` method.
|
|
341
|
+
*/
|
|
342
|
+
processOnCreateHooksEarly: boolean;
|
|
335
343
|
forceUtcTimezone?: boolean;
|
|
336
344
|
timezone?: string;
|
|
337
345
|
ensureDatabase: boolean | EnsureDatabaseOptions;
|
|
@@ -340,7 +348,7 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
|
|
|
340
348
|
useBatchUpdates?: boolean;
|
|
341
349
|
batchSize: number;
|
|
342
350
|
hydrator: HydratorConstructor;
|
|
343
|
-
loadStrategy: LoadStrategy |
|
|
351
|
+
loadStrategy: LoadStrategy | `${LoadStrategy}`;
|
|
344
352
|
dataloader: DataloaderType | boolean;
|
|
345
353
|
populateWhere?: PopulateHint | `${PopulateHint}`;
|
|
346
354
|
flushMode: FlushMode | 'commit' | 'auto' | 'always';
|
|
@@ -374,6 +382,8 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
|
|
|
374
382
|
disableForeignKeys?: boolean;
|
|
375
383
|
createForeignKeyConstraints?: boolean;
|
|
376
384
|
ignoreSchema?: string[];
|
|
385
|
+
skipTables?: (string | RegExp)[];
|
|
386
|
+
skipColumns?: Dictionary<(string | RegExp)[]>;
|
|
377
387
|
managementDbName?: string;
|
|
378
388
|
};
|
|
379
389
|
embeddables: {
|
|
@@ -403,5 +413,8 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
|
|
|
403
413
|
seeder: SeederOptions;
|
|
404
414
|
preferReadReplicas: boolean;
|
|
405
415
|
dynamicImportProvider: (id: string) => Promise<unknown>;
|
|
416
|
+
hashAlgorithm: 'md5' | 'sha256';
|
|
417
|
+
}
|
|
418
|
+
export interface Options<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = D[typeof EntityManagerType] & EntityManager, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> extends Pick<MikroORMOptions<D, EM>, Exclude<keyof MikroORMOptions, keyof typeof Configuration.DEFAULTS>>, Partial<MikroORMOptions<D, EM>> {
|
|
419
|
+
entities?: Entities;
|
|
406
420
|
}
|
|
407
|
-
export type Options<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = D[typeof EntityManagerType] & EntityManager> = Pick<MikroORMOptions<D, EM>, Exclude<keyof MikroORMOptions<D, EM>, keyof typeof Configuration.DEFAULTS>> & Partial<MikroORMOptions<D, EM>>;
|
package/utils/Configuration.js
CHANGED
|
@@ -44,14 +44,14 @@ export class Configuration {
|
|
|
44
44
|
baseDir: process.cwd(),
|
|
45
45
|
hydrator: ObjectHydrator,
|
|
46
46
|
flushMode: FlushMode.AUTO,
|
|
47
|
-
loadStrategy: LoadStrategy.
|
|
47
|
+
loadStrategy: LoadStrategy.BALANCED,
|
|
48
48
|
dataloader: DataloaderType.NONE,
|
|
49
49
|
populateWhere: PopulateHint.ALL,
|
|
50
|
-
connect: true,
|
|
51
50
|
ignoreUndefinedInQuery: false,
|
|
52
51
|
onQuery: sql => sql,
|
|
53
52
|
autoJoinOneToOneOwner: true,
|
|
54
53
|
autoJoinRefsForFilters: true,
|
|
54
|
+
filtersOnRelations: true,
|
|
55
55
|
propagationOnPrototype: true,
|
|
56
56
|
populateAfterFlush: true,
|
|
57
57
|
serialization: {
|
|
@@ -68,9 +68,11 @@ export class Configuration {
|
|
|
68
68
|
upsertManaged: true,
|
|
69
69
|
forceEntityConstructor: false,
|
|
70
70
|
forceUndefined: false,
|
|
71
|
+
processOnCreateHooksEarly: false,
|
|
71
72
|
ensureDatabase: true,
|
|
72
73
|
ensureIndexes: false,
|
|
73
74
|
batchSize: 300,
|
|
75
|
+
hashAlgorithm: 'md5',
|
|
74
76
|
debug: false,
|
|
75
77
|
ignoreDeprecations: false,
|
|
76
78
|
verbose: false,
|
|
@@ -93,17 +95,21 @@ export class Configuration {
|
|
|
93
95
|
disableForeignKeys: false,
|
|
94
96
|
createForeignKeyConstraints: true,
|
|
95
97
|
ignoreSchema: [],
|
|
98
|
+
skipTables: [],
|
|
99
|
+
skipColumns: {},
|
|
96
100
|
},
|
|
97
101
|
embeddables: {
|
|
98
|
-
prefixMode: '
|
|
102
|
+
prefixMode: 'relative',
|
|
99
103
|
},
|
|
100
104
|
entityGenerator: {
|
|
101
105
|
forceUndefined: true,
|
|
102
106
|
undefinedDefaults: false,
|
|
103
|
-
bidirectionalRelations: false,
|
|
104
|
-
identifiedReferences: false,
|
|
105
107
|
scalarTypeInDecorator: false,
|
|
108
|
+
bidirectionalRelations: true,
|
|
109
|
+
identifiedReferences: true,
|
|
106
110
|
scalarPropertiesForRelations: 'never',
|
|
111
|
+
entityDefinition: 'defineEntity',
|
|
112
|
+
enumMode: 'dictionary',
|
|
107
113
|
fileName: (className) => className,
|
|
108
114
|
onlyPurePivotTables: false,
|
|
109
115
|
outputPurePivotTables: false,
|
|
@@ -144,7 +150,6 @@ export class Configuration {
|
|
|
144
150
|
}
|
|
145
151
|
this.options = Utils.mergeConfig({}, Configuration.DEFAULTS, options);
|
|
146
152
|
this.options.baseDir = Utils.absolutePath(this.options.baseDir);
|
|
147
|
-
this.options.preferTs ??= options.preferTs;
|
|
148
153
|
if (validate) {
|
|
149
154
|
this.validateOptions();
|
|
150
155
|
}
|
|
@@ -204,15 +209,6 @@ export class Configuration {
|
|
|
204
209
|
}
|
|
205
210
|
return this.options.dataloader;
|
|
206
211
|
}
|
|
207
|
-
/**
|
|
208
|
-
* Gets current client URL (connection string).
|
|
209
|
-
*/
|
|
210
|
-
getClientUrl(hidePassword = false) {
|
|
211
|
-
if (hidePassword) {
|
|
212
|
-
return this.options.clientUrl.replace(/\/\/([^:]+):(.+)@/, '//$1:*****@');
|
|
213
|
-
}
|
|
214
|
-
return this.options.clientUrl;
|
|
215
|
-
}
|
|
216
212
|
getSchema(skipDefaultSchema = false) {
|
|
217
213
|
if (skipDefaultSchema && this.options.schema === this.platform.getDefaultSchemaName()) {
|
|
218
214
|
return undefined;
|
|
@@ -268,7 +264,7 @@ export class Configuration {
|
|
|
268
264
|
* Gets instance of metadata CacheAdapter. (cached)
|
|
269
265
|
*/
|
|
270
266
|
getMetadataCacheAdapter() {
|
|
271
|
-
return this.getCachedService(this.options.metadataCache.adapter, this.options.metadataCache.options, this.options.baseDir, this.options.metadataCache.pretty);
|
|
267
|
+
return this.getCachedService(this.options.metadataCache.adapter, this.options.metadataCache.options, this.options.baseDir, this.options.metadataCache.pretty, this.options.hashAlgorithm);
|
|
272
268
|
}
|
|
273
269
|
/**
|
|
274
270
|
* Gets instance of CacheAdapter for result cache. (cached)
|
|
@@ -315,13 +311,13 @@ export class Configuration {
|
|
|
315
311
|
this.options.implicitTransactions = this.platform.usesImplicitTransactions();
|
|
316
312
|
}
|
|
317
313
|
try {
|
|
318
|
-
const url = new URL(this.
|
|
314
|
+
const url = new URL(this.options.clientUrl);
|
|
319
315
|
if (url.pathname) {
|
|
320
316
|
this.options.dbName = this.get('dbName', decodeURIComponent(url.pathname).substring(1));
|
|
321
317
|
}
|
|
322
318
|
}
|
|
323
319
|
catch {
|
|
324
|
-
const url = this.
|
|
320
|
+
const url = this.options.clientUrl.match(/:\/\/.*\/([^?]+)/);
|
|
325
321
|
if (url) {
|
|
326
322
|
this.options.dbName = this.get('dbName', decodeURIComponent(url[1]));
|
|
327
323
|
}
|
|
@@ -338,6 +334,9 @@ export class Configuration {
|
|
|
338
334
|
Object.keys(this.options.filters).forEach(key => {
|
|
339
335
|
this.options.filters[key].default ??= true;
|
|
340
336
|
});
|
|
337
|
+
if (!this.options.filtersOnRelations) {
|
|
338
|
+
this.options.autoJoinRefsForFilters ??= false;
|
|
339
|
+
}
|
|
341
340
|
this.options.subscribers = Utils.unique(this.options.subscribers).map(subscriber => {
|
|
342
341
|
return subscriber.constructor.name === 'Function' ? new subscriber() : subscriber;
|
|
343
342
|
});
|
|
@@ -13,42 +13,29 @@ export declare class ConfigurationLoader {
|
|
|
13
13
|
* @param paths Array of possible paths for a configuration file. Files will be checked in order, and the first existing one will be used. Defaults to the output of {@link ConfigurationLoader.getConfigPaths}.
|
|
14
14
|
* @param options Additional options to augment the final configuration with.
|
|
15
15
|
*/
|
|
16
|
-
static getConfiguration<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = EntityManager>(contextName
|
|
17
|
-
/**
|
|
18
|
-
* Gets the default config from the default paths
|
|
19
|
-
*
|
|
20
|
-
* @deprecated Prefer to explicitly set the `contextName` at the first argument. This signature is available for backwards compatibility, and may be removed in v7.
|
|
21
|
-
*/
|
|
22
|
-
static getConfiguration<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = EntityManager>(): Promise<Configuration<D, EM>>;
|
|
23
|
-
/**
|
|
24
|
-
* Gets default configuration out of the default paths, and possibly from `process.argv`
|
|
25
|
-
*
|
|
26
|
-
* @param validate Whether to validate the final configuration.
|
|
27
|
-
* @param options Additional options to augment the final configuration with (just before validation).
|
|
28
|
-
*
|
|
29
|
-
* @deprecated Use the other overloads of this method. This signature will be removed in v7.
|
|
30
|
-
*/
|
|
31
|
-
static getConfiguration<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = EntityManager>(validate: boolean, options?: Partial<Options>): Promise<Configuration<D, EM>>;
|
|
16
|
+
static getConfiguration<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = EntityManager>(contextName?: string, paths?: string[], options?: Partial<Options>): Promise<Configuration<D, EM>>;
|
|
32
17
|
static getConfigFile(paths: string[]): Promise<[string, unknown] | []>;
|
|
33
18
|
static getPackageConfig(basePath?: string): Dictionary;
|
|
34
19
|
static getSettings(): Settings;
|
|
35
|
-
static configPathsFromArg(): string[] | undefined;
|
|
36
20
|
static getConfigPaths(): string[];
|
|
37
21
|
static isESM(): boolean;
|
|
38
|
-
|
|
39
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Tries to register TS support in the following order: swc, tsx, jiti, tsimp
|
|
24
|
+
* Use `MIKRO_ORM_CLI_TS_LOADER` env var to set the loader explicitly.
|
|
25
|
+
* This method is used only in CLI context.
|
|
26
|
+
*/
|
|
27
|
+
static registerTypeScriptSupport(configPath?: string, tsLoader?: 'swc' | 'tsx' | 'jiti' | 'tsimp' | 'auto'): Promise<boolean>;
|
|
28
|
+
static registerDotenv<D extends IDatabaseDriver>(options: Options<D>): void;
|
|
40
29
|
static loadEnvironmentVars<D extends IDatabaseDriver>(): Promise<Partial<Options<D>>>;
|
|
41
30
|
static loadEnvironmentVarsSync<D extends IDatabaseDriver>(): Partial<Options<D>>;
|
|
42
31
|
static getORMPackages(): Set<string>;
|
|
43
|
-
/** @internal */
|
|
44
|
-
static commonJSCompat(options: Partial<Options>): void;
|
|
45
32
|
static getORMPackageVersion(name: string): string | undefined;
|
|
46
33
|
static checkPackageVersion(): string;
|
|
47
34
|
}
|
|
48
35
|
export interface Settings {
|
|
49
|
-
alwaysAllowTs?: boolean;
|
|
50
36
|
verbose?: boolean;
|
|
51
37
|
preferTs?: boolean;
|
|
38
|
+
tsLoader?: 'swc' | 'tsx' | 'jiti' | 'tsimp' | 'auto';
|
|
52
39
|
tsConfigPath?: string;
|
|
53
40
|
configPaths?: string[];
|
|
54
41
|
}
|