@mikro-orm/core 7.0.0-dev.3 → 7.0.0-dev.4

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 CHANGED
@@ -367,7 +367,7 @@ export class EntityManager {
367
367
  if (!args && filter.cond.length > 0 && filter.args !== false) {
368
368
  throw new Error(`No arguments provided for filter '${filter.name}'`);
369
369
  }
370
- cond = await filter.cond(args, type, this, findOptions);
370
+ cond = await filter.cond(args, type, this, findOptions, entityName);
371
371
  }
372
372
  else {
373
373
  cond = filter.cond;
@@ -717,7 +717,7 @@ export class EntityManager {
717
717
  convertCustomTypes: true,
718
718
  connectionType: 'write',
719
719
  });
720
- em.getHydrator().hydrate(entity, meta, data2, em.entityFactory, 'full');
720
+ em.getHydrator().hydrate(entity, meta, data2, em.entityFactory, 'full', false, true);
721
721
  }
722
722
  // recompute the data as there might be some values missing (e.g. those with db column defaults)
723
723
  const snapshot = this.comparator.prepareEntity(entity);
@@ -911,7 +911,7 @@ export class EntityManager {
911
911
  if (!row) {
912
912
  throw new Error(`Cannot find matching entity for condition ${JSON.stringify(cond)}`);
913
913
  }
914
- em.getHydrator().hydrate(entity, meta, row, em.entityFactory, 'full');
914
+ em.getHydrator().hydrate(entity, meta, row, em.entityFactory, 'full', false, true);
915
915
  }
916
916
  if (loadPK.size !== data2.length && Array.isArray(uniqueFields)) {
917
917
  for (let i = 0; i < allData.length; i++) {
@@ -1,11 +1,11 @@
1
- import type { Constructor, Dictionary, FilterQuery } from '../typings.js';
1
+ import type { AnyString, Constructor, Dictionary, EntityClass, FilterQuery } from '../typings.js';
2
2
  import type { FindOptions } from '../drivers/IDatabaseDriver.js';
3
- export declare function Entity(options?: EntityOptions<any>): <T>(target: T & Dictionary) => T & Dictionary;
3
+ export declare function Entity<T extends EntityClass<unknown>>(options?: EntityOptions<T>): (target: T) => void;
4
4
  export type EntityOptions<T> = {
5
5
  tableName?: string;
6
6
  schema?: string;
7
7
  collection?: string;
8
- discriminatorColumn?: string;
8
+ discriminatorColumn?: (T extends EntityClass<infer P> ? keyof P : string) | AnyString;
9
9
  discriminatorMap?: Dictionary<string>;
10
10
  discriminatorValue?: number | string;
11
11
  forceConstructor?: boolean;
@@ -8,6 +8,5 @@ export function Entity(options = {}) {
8
8
  if (!options.abstract || meta.discriminatorColumn) {
9
9
  meta.name = target.name;
10
10
  }
11
- return target;
12
11
  };
13
12
  }
@@ -1,17 +1,19 @@
1
- import type { AnyEntity, Dictionary } from '../typings.js';
1
+ import type { EntityClass, Dictionary, AutoPath } from '../typings.js';
2
2
  import type { DeferMode } from '../enums.js';
3
- export declare function Index<T>(options?: IndexOptions<T>): (target: AnyEntity, propertyName?: string) => any;
4
- export declare function Unique<T>(options?: UniqueOptions<T>): (target: AnyEntity, propertyName?: string) => any;
5
- interface BaseOptions<T> {
3
+ export declare function Index<T extends object, H extends string>(options?: IndexOptions<T, H>): (target: T, propertyName?: (T extends EntityClass<unknown> ? undefined : keyof T) | undefined) => any;
4
+ export declare function Unique<T extends object, H extends string>(options?: UniqueOptions<T, H>): (target: T, propertyName?: (T extends EntityClass<unknown> ? undefined : keyof T) | undefined) => any;
5
+ type MaybeArray<T> = T | T[];
6
+ type Properties<T, H extends string> = MaybeArray<AutoPath<T, H>>;
7
+ interface BaseOptions<T, H extends string> {
6
8
  name?: string;
7
- properties?: keyof T | (keyof T)[];
9
+ properties?: (T extends EntityClass<infer P> ? Properties<P, H> : Properties<T, H>);
8
10
  options?: Dictionary;
9
11
  expression?: string;
10
12
  }
11
- export interface UniqueOptions<T> extends BaseOptions<T> {
13
+ export interface UniqueOptions<T, H extends string = string> extends BaseOptions<T, H> {
12
14
  deferMode?: DeferMode | `${DeferMode}`;
13
15
  }
14
- export interface IndexOptions<T> extends BaseOptions<T> {
16
+ export interface IndexOptions<T, H extends string = string> extends BaseOptions<T, H> {
15
17
  type?: string;
16
18
  }
17
19
  export {};
@@ -3,7 +3,7 @@ import { Utils } from '../utils/Utils.js';
3
3
  function createDecorator(options, unique) {
4
4
  return function (target, propertyName) {
5
5
  const meta = MetadataStorage.getMetadataFromDecorator(propertyName ? target.constructor : target);
6
- options.properties = options.properties || propertyName;
6
+ options.properties ??= propertyName;
7
7
  const key = unique ? 'uniques' : 'indexes';
8
8
  meta[key].push(options);
9
9
  if (!propertyName) {
@@ -86,7 +86,9 @@ export class EntityFactory {
86
86
  }
87
87
  if (options.merge && wrapped.hasPrimaryKey()) {
88
88
  this.unitOfWork.register(entity, data, {
89
- refresh: options.refresh && options.initialized,
89
+ // Always refresh to ensure the payload is in correct shape for joined strategy. When loading nested relations,
90
+ // they will be created early without `Type.ensureComparable` being properly handled, resulting in extra updates.
91
+ refresh: options.initialized,
90
92
  newEntity: options.newEntity,
91
93
  loaded: options.initialized,
92
94
  });
package/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * @packageDocumentation
3
3
  * @module core
4
4
  */
5
- export { Constructor, ConnectionType, Dictionary, PrimaryKeyProp, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, EntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, EntityMetadata, QBFilterQuery, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, EntityRepositoryType, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, MigrationDiff, GenerateOptions, FilterObject, IEntityGenerator, ISeedManager, EntityClassGroup, OptionalProps, EagerProps, HiddenProps, RequiredEntityData, CheckCallback, SimpleColumnMeta, Rel, Ref, ScalarRef, EntityRef, ISchemaGenerator, UmzugMigration, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, FilterKey, Opt, EntityType, FromEntityType, Selected, IsSubset, NoInfer, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, Hidden, FilterValue, MergeLoaded, MergeSelected, Config, DefineConfig, TypeConfig, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, } from './typings.js';
5
+ export { Constructor, ConnectionType, Dictionary, PrimaryKeyProp, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, EntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, EntityMetadata, QBFilterQuery, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, EntityRepositoryType, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, MigrationDiff, GenerateOptions, FilterObject, IEntityGenerator, ISeedManager, EntityClassGroup, OptionalProps, EagerProps, HiddenProps, RequiredEntityData, CheckCallback, SimpleColumnMeta, Rel, Ref, ScalarRef, EntityRef, ISchemaGenerator, UmzugMigration, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, Opt, EntityType, FromEntityType, Selected, IsSubset, NoInfer, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, Hidden, FilterValue, MergeLoaded, MergeSelected, Config, DefineConfig, TypeConfig, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, } from './typings.js';
6
6
  export * from './enums.js';
7
7
  export * from './errors.js';
8
8
  export * from './exceptions.js';
@@ -68,8 +68,8 @@ export declare class EntitySchema<Entity = any, Base = never> {
68
68
  addManyToMany<Target = AnyEntity>(name: EntityKey<Entity>, type: TypeType, options: ManyToManyOptions<Entity, Target>): void;
69
69
  addOneToMany<Target = AnyEntity>(name: EntityKey<Entity>, type: TypeType, options: OneToManyOptions<Entity, Target>): void;
70
70
  addOneToOne<Target = AnyEntity>(name: EntityKey<Entity>, type: TypeType, options: OneToOneOptions<Entity, Target>): void;
71
- addIndex(options: IndexOptions<Entity>): void;
72
- addUnique(options: UniqueOptions<Entity>): void;
71
+ addIndex<Key extends string>(options: IndexOptions<Entity, Key>): void;
72
+ addUnique<Key extends string>(options: UniqueOptions<Entity, Key>): void;
73
73
  setCustomRepository(repository: () => Constructor): void;
74
74
  setExtends(base: string | EntitySchema): void;
75
75
  setClass(proto: EntityClass<Entity>): void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
3
  "type": "module",
4
- "version": "7.0.0-dev.3",
4
+ "version": "7.0.0-dev.4",
5
5
  "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.",
6
6
  "exports": {
7
7
  "./package.json": "./package.json",
@@ -55,7 +55,7 @@
55
55
  "dotenv": "16.4.7",
56
56
  "esprima": "4.0.1",
57
57
  "globby": "11.1.0",
58
- "mikro-orm": "7.0.0-dev.3",
58
+ "mikro-orm": "7.0.0-dev.4",
59
59
  "reflect-metadata": "0.2.2"
60
60
  }
61
61
  }
package/typings.d.ts CHANGED
@@ -28,6 +28,7 @@ export type EntityKey<T = unknown, B extends boolean = false> = string & {
28
28
  [K in keyof T]-?: CleanKeys<T, K, B> extends never ? never : K;
29
29
  }[keyof T];
30
30
  export type EntityValue<T> = T[EntityKey<T>];
31
+ export type EntityDataValue<T> = EntityData<T>[EntityKey<T>];
31
32
  export type FilterKey<T> = keyof FilterQuery<T>;
32
33
  export type AsyncFunction<R = any, T = Dictionary> = (args: T) => Promise<T>;
33
34
  export type Compute<T> = {
@@ -240,7 +241,7 @@ type IsOptional<T, K extends keyof T, I> = T[K] extends Collection<any, any> ? t
240
241
  type RequiredKeys<T, K extends keyof T, I> = IsOptional<T, K, I> extends false ? CleanKeys<T, K> : never;
241
242
  type OptionalKeys<T, K extends keyof T, I> = IsOptional<T, K, I> extends false ? never : CleanKeys<T, K>;
242
243
  export type EntityData<T, C extends boolean = false> = {
243
- [K in EntityKey<T>]?: EntityDataItem<T[K], C>;
244
+ [K in EntityKey<T>]?: EntityDataItem<T[K] & {}, C>;
244
245
  };
245
246
  export type RequiredEntityData<T, I = never, C extends boolean = false> = {
246
247
  [K in keyof T as RequiredKeys<T, K, I>]: T[K] | RequiredEntityDataProp<T[K], T, C> | Primary<T[K]>;
@@ -292,7 +293,8 @@ export type EntityDTO<T, C extends TypeConfig = never> = {
292
293
  } & {
293
294
  [K in keyof T as DTOOptionalKeys<T, K>]?: EntityDTOProp<T, T[K], C> | AddOptional<T[K]>;
294
295
  };
295
- export type CheckCallback<T> = (columns: Record<keyof T, string>) => string;
296
+ type CheckKey<T> = IsUnknown<T> extends false ? keyof T : string;
297
+ export type CheckCallback<T> = (columns: Record<CheckKey<T>, string>) => string;
296
298
  export type GeneratedColumnCallback<T> = (columns: Record<keyof T, string>) => string;
297
299
  export interface CheckConstraint<T = any> {
298
300
  name?: string;
@@ -681,7 +683,7 @@ export interface MigrationObject {
681
683
  }
682
684
  export type FilterDef = {
683
685
  name: string;
684
- cond: Dictionary | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions<any, any, any, any> | FindOneOptions<any, any, any, any>) => Dictionary | Promise<Dictionary>);
686
+ cond: Dictionary | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions<any, any, any, any> | FindOneOptions<any, any, any, any>, entityName?: EntityName<any>) => Dictionary | Promise<Dictionary>);
685
687
  default?: boolean;
686
688
  entity?: string[];
687
689
  args?: boolean;
@@ -884,7 +884,7 @@ export class UnitOfWork {
884
884
  collectionUpdates.push(coll);
885
885
  }
886
886
  }
887
- await this.em.getDriver().syncCollections(collectionUpdates, { ctx });
887
+ await this.em.getDriver().syncCollections(collectionUpdates, { ctx, schema: this.em.schema });
888
888
  for (const coll of this.collectionUpdates) {
889
889
  coll.takeSnapshot();
890
890
  }
@@ -32,7 +32,7 @@ export class AbstractSchemaGenerator {
32
32
  }
33
33
  else {
34
34
  await this.ensureDatabase();
35
- await this.dropSchema();
35
+ await this.dropSchema(options);
36
36
  }
37
37
  if (options?.createSchema !== false) {
38
38
  await this.createSchema(options);
@@ -103,7 +103,10 @@ export class AbstractSchemaGenerator {
103
103
  }
104
104
  return calc.sort()
105
105
  .map(cls => this.metadata.find(cls))
106
- .filter(meta => schema ? [schema, '*'].includes(meta.schema) : meta.schema !== '*');
106
+ .filter(meta => {
107
+ const targetSchema = meta.schema ?? this.config.get('schema', this.platform.getDefaultSchemaName());
108
+ return schema ? [schema, '*'].includes(targetSchema) : meta.schema !== '*';
109
+ });
107
110
  }
108
111
  notImplemented() {
109
112
  throw new Error(`This method is not supported by ${this.driver.constructor.name} driver`);
@@ -74,7 +74,7 @@ export class EntityComparator {
74
74
  lines.push(` if (entity${this.wrap(pk)} != null && (entity${this.wrap(pk)}.__entity || entity${this.wrap(pk)}.__reference)) {`);
75
75
  lines.push(` const pk = entity${this.wrap(pk)}.__helper.getPrimaryKey();`);
76
76
  if (meta.properties[pk].targetMeta.compositePK) {
77
- lines.push(` if (typeof pk === 'object') {`);
77
+ lines.push(` if (typeof pk === 'object' && pk != null) {`);
78
78
  lines.push(` return [`);
79
79
  for (const childPK of meta.properties[pk].targetMeta.primaryKeys) {
80
80
  lines.push(` pk${this.wrap(childPK)},`);
@@ -17,7 +17,12 @@ export class RawQueryFragment {
17
17
  this.#key = `[raw]: ${this.sql} (#${RawQueryFragment.#index++})`;
18
18
  }
19
19
  as(alias) {
20
- return new RawQueryFragment(`${this.sql} as ${alias}`, this.params);
20
+ // TODO: to be removed in v7
21
+ /* istanbul ignore next */
22
+ if (alias.startsWith('`') || alias.startsWith('"')) {
23
+ return new RawQueryFragment(`${this.sql} as ${alias}`, this.params);
24
+ }
25
+ return new RawQueryFragment(`${this.sql} as ??`, [...this.params, alias]);
21
26
  }
22
27
  valueOf() {
23
28
  throw new Error(`Trying to modify raw SQL fragment: '${this.sql}'`);