@mikro-orm/core 7.0.0-rc.1 → 7.0.0-rc.3

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.
Files changed (76) hide show
  1. package/EntityManager.d.ts +3 -2
  2. package/EntityManager.js +107 -43
  3. package/MikroORM.js +4 -4
  4. package/cache/FileCacheAdapter.js +1 -3
  5. package/connections/Connection.js +16 -3
  6. package/drivers/DatabaseDriver.js +26 -8
  7. package/drivers/IDatabaseDriver.d.ts +49 -1
  8. package/entity/BaseEntity.d.ts +3 -3
  9. package/entity/Collection.js +43 -17
  10. package/entity/EntityAssigner.js +23 -11
  11. package/entity/EntityFactory.js +36 -13
  12. package/entity/EntityHelper.js +27 -18
  13. package/entity/EntityLoader.d.ts +6 -6
  14. package/entity/EntityLoader.js +55 -22
  15. package/entity/EntityRepository.d.ts +1 -1
  16. package/entity/Reference.d.ts +1 -1
  17. package/entity/Reference.js +37 -8
  18. package/entity/WrappedEntity.d.ts +3 -3
  19. package/entity/WrappedEntity.js +5 -1
  20. package/entity/defineEntity.d.ts +202 -58
  21. package/entity/defineEntity.js +20 -24
  22. package/entity/utils.js +28 -26
  23. package/entity/validators.js +2 -1
  24. package/enums.js +12 -17
  25. package/errors.js +18 -8
  26. package/events/EventManager.js +1 -1
  27. package/exceptions.js +7 -2
  28. package/hydration/ObjectHydrator.js +27 -13
  29. package/index.d.ts +2 -2
  30. package/index.js +1 -1
  31. package/logging/DefaultLogger.js +3 -5
  32. package/logging/colors.js +3 -6
  33. package/metadata/EntitySchema.d.ts +2 -2
  34. package/metadata/EntitySchema.js +12 -2
  35. package/metadata/MetadataDiscovery.js +107 -48
  36. package/metadata/MetadataProvider.js +26 -1
  37. package/metadata/MetadataStorage.js +2 -4
  38. package/metadata/MetadataValidator.js +20 -5
  39. package/metadata/types.d.ts +2 -2
  40. package/naming-strategy/AbstractNamingStrategy.js +5 -2
  41. package/not-supported.js +5 -1
  42. package/package.json +40 -37
  43. package/platforms/Platform.d.ts +4 -1
  44. package/platforms/Platform.js +50 -24
  45. package/serialization/EntitySerializer.d.ts +3 -3
  46. package/serialization/EntitySerializer.js +7 -3
  47. package/serialization/EntityTransformer.js +6 -4
  48. package/serialization/SerializationContext.js +1 -1
  49. package/typings.d.ts +73 -33
  50. package/typings.js +11 -9
  51. package/unit-of-work/ChangeSet.js +4 -4
  52. package/unit-of-work/ChangeSetComputer.js +8 -6
  53. package/unit-of-work/ChangeSetPersister.js +15 -10
  54. package/unit-of-work/CommitOrderCalculator.js +4 -2
  55. package/unit-of-work/UnitOfWork.d.ts +7 -1
  56. package/unit-of-work/UnitOfWork.js +51 -22
  57. package/utils/AbstractMigrator.d.ts +101 -0
  58. package/utils/AbstractMigrator.js +303 -0
  59. package/utils/AbstractSchemaGenerator.js +2 -1
  60. package/utils/AsyncContext.js +1 -1
  61. package/utils/Configuration.d.ts +3 -1
  62. package/utils/Configuration.js +8 -4
  63. package/utils/Cursor.js +4 -2
  64. package/utils/DataloaderUtils.js +15 -12
  65. package/utils/EntityComparator.js +51 -43
  66. package/utils/QueryHelper.js +38 -26
  67. package/utils/RawQueryFragment.js +3 -2
  68. package/utils/TransactionManager.js +2 -1
  69. package/utils/Utils.d.ts +1 -1
  70. package/utils/Utils.js +36 -30
  71. package/utils/env-vars.js +6 -5
  72. package/utils/fs-utils.d.ts +1 -0
  73. package/utils/fs-utils.js +6 -5
  74. package/utils/index.d.ts +0 -2
  75. package/utils/index.js +0 -2
  76. package/utils/upsert-utils.js +6 -3
package/package.json CHANGED
@@ -1,53 +1,56 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "type": "module",
4
- "version": "7.0.0-rc.1",
3
+ "version": "7.0.0-rc.3",
5
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.",
6
- "exports": {
7
- "./package.json": "./package.json",
8
- ".": "./index.js",
9
- "./file-discovery": {
10
- "node": "./metadata/discover-entities.js",
11
- "browser": "./not-supported.js"
12
- },
13
- "./fs-utils": {
14
- "node": "./utils/fs-utils.js",
15
- "browser": "./not-supported.js"
16
- }
17
- },
18
- "repository": {
19
- "type": "git",
20
- "url": "git+ssh://git@github.com/mikro-orm/mikro-orm.git"
21
- },
22
- "funding": "https://github.com/sponsors/b4nan",
23
5
  "keywords": [
24
- "orm",
6
+ "data-mapper",
7
+ "ddd",
8
+ "entity",
9
+ "identity-map",
10
+ "javascript",
11
+ "js",
12
+ "mariadb",
13
+ "mikro-orm",
25
14
  "mongo",
26
15
  "mongodb",
27
16
  "mysql",
28
- "mariadb",
17
+ "orm",
29
18
  "postgresql",
30
19
  "sqlite",
31
20
  "sqlite3",
32
21
  "ts",
33
22
  "typescript",
34
- "js",
35
- "javascript",
36
- "entity",
37
- "ddd",
38
- "mikro-orm",
39
- "unit-of-work",
40
- "data-mapper",
41
- "identity-map"
23
+ "unit-of-work"
42
24
  ],
43
- "author": "Martin Adámek",
44
- "license": "MIT",
25
+ "homepage": "https://mikro-orm.io",
45
26
  "bugs": {
46
27
  "url": "https://github.com/mikro-orm/mikro-orm/issues"
47
28
  },
48
- "homepage": "https://mikro-orm.io",
49
- "engines": {
50
- "node": ">= 22.17.0"
29
+ "license": "MIT",
30
+ "author": "Martin Adámek",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+ssh://git@github.com/mikro-orm/mikro-orm.git"
34
+ },
35
+ "funding": "https://github.com/sponsors/b4nan",
36
+ "type": "module",
37
+ "exports": {
38
+ "./package.json": "./package.json",
39
+ ".": "./index.js",
40
+ "./file-discovery": {
41
+ "node": "./metadata/discover-entities.js",
42
+ "browser": "./not-supported.js"
43
+ },
44
+ "./fs-utils": {
45
+ "node": "./utils/fs-utils.js",
46
+ "browser": "./not-supported.js"
47
+ },
48
+ "./migrations": "./utils/AbstractMigrator.js",
49
+ "./schema": "./utils/AbstractSchemaGenerator.js",
50
+ "./dataloader": "./utils/DataloaderUtils.js"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
51
54
  },
52
55
  "scripts": {
53
56
  "build": "yarn compile && yarn copy",
@@ -55,9 +58,6 @@
55
58
  "compile": "yarn run -T tsc -p tsconfig.build.json",
56
59
  "copy": "node ../../scripts/copy.mjs"
57
60
  },
58
- "publishConfig": {
59
- "access": "public"
60
- },
61
61
  "peerDependencies": {
62
62
  "dataloader": "2.2.3"
63
63
  },
@@ -65,5 +65,8 @@
65
65
  "dataloader": {
66
66
  "optional": true
67
67
  }
68
+ },
69
+ "engines": {
70
+ "node": ">= 22.17.0"
68
71
  }
69
72
  }
@@ -66,7 +66,9 @@ export declare abstract class Platform {
66
66
  $flags?: string;
67
67
  };
68
68
  isAllowedTopLevelOperator(operator: string): boolean;
69
- quoteVersionValue(value: Date | number, prop: EntityProperty): Date | string | number;
69
+ convertVersionValue(value: Date | number, prop: EntityProperty): Date | string | number | {
70
+ $in: (string | number)[];
71
+ };
70
72
  getDefaultVersionLength(): number;
71
73
  allowsComparingTuples(): boolean;
72
74
  isBigIntProperty(prop: EntityProperty): boolean;
@@ -138,6 +140,7 @@ export declare abstract class Platform {
138
140
  getDefaultMappedType(type: string): Type<unknown>;
139
141
  supportsMultipleCascadePaths(): boolean;
140
142
  supportsMultipleStatements(): boolean;
143
+ supportsUnionWhere(): boolean;
141
144
  getArrayDeclarationSQL(): string;
142
145
  marshallArray(values: string[]): string;
143
146
  unmarshallArray(value: string): string[];
@@ -113,7 +113,7 @@ export class Platform {
113
113
  isAllowedTopLevelOperator(operator) {
114
114
  return operator === '$not';
115
115
  }
116
- quoteVersionValue(value, prop) {
116
+ convertVersionValue(value, prop) {
117
117
  return value;
118
118
  }
119
119
  getDefaultVersionLength() {
@@ -198,35 +198,58 @@ export class Platform {
198
198
  }
199
199
  switch (this.extractSimpleType(type)) {
200
200
  case 'character':
201
- case 'char': return Type.getType(CharacterType);
201
+ case 'char':
202
+ return Type.getType(CharacterType);
202
203
  case 'string':
203
- case 'varchar': return Type.getType(StringType);
204
- case 'interval': return Type.getType(IntervalType);
205
- case 'text': return Type.getType(TextType);
204
+ case 'varchar':
205
+ return Type.getType(StringType);
206
+ case 'interval':
207
+ return Type.getType(IntervalType);
208
+ case 'text':
209
+ return Type.getType(TextType);
206
210
  case 'int':
207
- case 'number': return Type.getType(IntegerType);
208
- case 'bigint': return Type.getType(BigIntType);
209
- case 'smallint': return Type.getType(SmallIntType);
210
- case 'tinyint': return Type.getType(TinyIntType);
211
- case 'mediumint': return Type.getType(MediumIntType);
212
- case 'float': return Type.getType(FloatType);
213
- case 'double': return Type.getType(DoubleType);
214
- case 'integer': return Type.getType(IntegerType);
211
+ case 'number':
212
+ return Type.getType(IntegerType);
213
+ case 'bigint':
214
+ return Type.getType(BigIntType);
215
+ case 'smallint':
216
+ return Type.getType(SmallIntType);
217
+ case 'tinyint':
218
+ return Type.getType(TinyIntType);
219
+ case 'mediumint':
220
+ return Type.getType(MediumIntType);
221
+ case 'float':
222
+ return Type.getType(FloatType);
223
+ case 'double':
224
+ return Type.getType(DoubleType);
225
+ case 'integer':
226
+ return Type.getType(IntegerType);
215
227
  case 'decimal':
216
- case 'numeric': return Type.getType(DecimalType);
217
- case 'boolean': return Type.getType(BooleanType);
228
+ case 'numeric':
229
+ return Type.getType(DecimalType);
230
+ case 'boolean':
231
+ return Type.getType(BooleanType);
218
232
  case 'blob':
219
- case 'buffer': return Type.getType(BlobType);
220
- case 'uint8array': return Type.getType(Uint8ArrayType);
221
- case 'uuid': return Type.getType(UuidType);
222
- case 'date': return Type.getType(DateType);
233
+ case 'buffer':
234
+ return Type.getType(BlobType);
235
+ case 'uint8array':
236
+ return Type.getType(Uint8ArrayType);
237
+ case 'uuid':
238
+ return Type.getType(UuidType);
239
+ case 'date':
240
+ return Type.getType(DateType);
223
241
  case 'datetime':
224
- case 'timestamp': return Type.getType(DateTimeType);
225
- case 'time': return Type.getType(TimeType);
242
+ case 'timestamp':
243
+ return Type.getType(DateTimeType);
244
+ case 'time':
245
+ return Type.getType(TimeType);
226
246
  case 'object':
227
- case 'json': return Type.getType(JsonType);
228
- case 'enum': return Type.getType(EnumType);
229
- default: return Type.getType(UnknownType);
247
+ case 'json':
248
+ return Type.getType(JsonType);
249
+ case 'enum':
250
+ return Type.getType(EnumType);
251
+ default:
252
+ return Type.getType(UnknownType);
230
253
  }
231
254
  }
232
255
  supportsMultipleCascadePaths() {
@@ -235,6 +258,9 @@ export class Platform {
235
258
  supportsMultipleStatements() {
236
259
  return this.config.get('multipleStatements');
237
260
  }
261
+ supportsUnionWhere() {
262
+ return false;
263
+ }
238
264
  getArrayDeclarationSQL() {
239
265
  return 'text';
240
266
  }
@@ -1,7 +1,7 @@
1
- import type { ArrayElement, AutoPath, CleanTypeConfig, EntityDTO, FromEntityType, Loaded, TypeConfig, UnboxArray } from '../typings.js';
1
+ import type { ArrayElement, AutoPath, CleanTypeConfig, SerializeDTO, FromEntityType, TypeConfig, UnboxArray } from '../typings.js';
2
2
  import { type PopulatePath } from '../enums.js';
3
3
  export declare class EntitySerializer {
4
- static serialize<T extends object, P extends string = never, E extends string = never>(entity: T, options?: SerializeOptions<T, P, E>): EntityDTO<Loaded<T, P>>;
4
+ static serialize<T extends object, P extends string = never, E extends string = never>(entity: T, options?: SerializeOptions<T, P, E>): SerializeDTO<T, P, E>;
5
5
  private static propertyName;
6
6
  private static processProperty;
7
7
  private static processCustomType;
@@ -39,4 +39,4 @@ export interface SerializeOptions<T, P extends string = never, E extends string
39
39
  * const dto2 = wrap(user).serialize({ exclude: ['id', 'email'], forceObject: true });
40
40
  * ```
41
41
  */
42
- export declare function serialize<Entity extends object, Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Populate extends string = never, Exclude extends string = never, Config extends TypeConfig = never>(entity: Entity, options?: Config & SerializeOptions<UnboxArray<Entity>, Populate, Exclude>): Naked extends object[] ? EntityDTO<Loaded<ArrayElement<Naked>, Populate>, CleanTypeConfig<Config>>[] : EntityDTO<Loaded<Naked, Populate>, CleanTypeConfig<Config>>;
42
+ export declare function serialize<Entity extends object, Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Populate extends string = never, Exclude extends string = never, Config extends TypeConfig = never>(entity: Entity, options?: Config & SerializeOptions<UnboxArray<Entity>, Populate, Exclude>): Naked extends object[] ? SerializeDTO<ArrayElement<Naked>, Populate, Exclude, CleanTypeConfig<Config>>[] : SerializeDTO<Naked, Populate, Exclude, CleanTypeConfig<Config>>;
@@ -9,7 +9,8 @@ function isVisible(meta, propName, options) {
9
9
  if (options.groups && prop?.groups) {
10
10
  return prop.groups.some(g => options.groups.includes(g));
11
11
  }
12
- if (Array.isArray(options.populate) && options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')) {
12
+ if (Array.isArray(options.populate) &&
13
+ options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')) {
13
14
  return true;
14
15
  }
15
16
  if (options.exclude?.find(item => item === propName)) {
@@ -20,7 +21,8 @@ function isVisible(meta, propName, options) {
20
21
  return visible && !prefixed;
21
22
  }
22
23
  function isPopulated(propName, options) {
23
- if (typeof options.populate !== 'boolean' && options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')) {
24
+ if (typeof options.populate !== 'boolean' &&
25
+ options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')) {
24
26
  return true;
25
27
  }
26
28
  if (typeof options.populate === 'boolean') {
@@ -176,7 +178,9 @@ export class EntitySerializer {
176
178
  static extractChildOptions(options, prop) {
177
179
  return {
178
180
  ...options,
179
- populate: Array.isArray(options.populate) ? Utils.extractChildElements(options.populate, prop, '*') : options.populate,
181
+ populate: Array.isArray(options.populate)
182
+ ? Utils.extractChildElements(options.populate, prop, '*')
183
+ : options.populate,
180
184
  exclude: Array.isArray(options.exclude) ? Utils.extractChildElements(options.exclude, prop) : options.exclude,
181
185
  };
182
186
  }
@@ -58,10 +58,12 @@ export class EntityTransformer {
58
58
  continue;
59
59
  }
60
60
  const populated = root.isMarkedAsPopulated(meta.class, prop);
61
- const partiallyLoaded = root.isPartiallyLoaded(meta.class, prop);
62
- const isPrimary = includePrimaryKeys && meta.properties[prop].primary;
63
- if (!partiallyLoaded && !populated && !isPrimary) {
64
- continue;
61
+ if (!raw) {
62
+ const partiallyLoaded = root.isPartiallyLoaded(meta.class, prop);
63
+ const isPrimary = includePrimaryKeys && meta.properties[prop].primary;
64
+ if (!partiallyLoaded && !populated && !isPrimary) {
65
+ continue;
66
+ }
65
67
  }
66
68
  const cycle = root.visit(meta.class, prop);
67
69
  if (cycle && visited) {
@@ -104,7 +104,7 @@ export class SerializationContext {
104
104
  }
105
105
  fields = fields
106
106
  .filter(field => field.startsWith(`${segment[1]}.`) || field === '*')
107
- .map(field => field === '*' ? field : field.substring(segment[1].length + 1));
107
+ .map(field => (field === '*' ? field : field.substring(segment[1].length + 1)));
108
108
  }
109
109
  return fields.some(p => p === prop || p === '*');
110
110
  }
package/typings.d.ts CHANGED
@@ -36,11 +36,11 @@ export type Compute<T> = {
36
36
  [K in keyof T]: T[K];
37
37
  } & {};
38
38
  type InternalKeys = 'EntityRepositoryType' | 'PrimaryKeyProp' | 'OptionalProps' | 'EagerProps' | 'HiddenProps' | '__selectedType' | '__loadedType';
39
- export type CleanKeys<T, K extends keyof T, B extends boolean = false> = (T[K] & {}) extends Function ? never : K extends symbol | InternalKeys ? never : B extends true ? (T[K] & {}) extends Scalar ? never : K : K;
39
+ export type CleanKeys<T, K extends keyof T, B extends boolean = false> = T[K] & {} extends Function ? never : K extends symbol | InternalKeys ? never : B extends true ? T[K] & {} extends Scalar ? never : K : K;
40
40
  export type FunctionKeys<T, K extends keyof T> = T[K] extends Function ? K : never;
41
41
  export type Cast<T, R> = T extends R ? T : R;
42
- export type IsUnknown<T> = T extends unknown ? unknown extends T ? true : never : never;
43
- export type IsAny<T> = 0 extends (1 & T) ? true : false;
42
+ export type IsUnknown<T> = T extends unknown ? (unknown extends T ? true : never) : never;
43
+ export type IsAny<T> = 0 extends 1 & T ? true : false;
44
44
  export type IsNever<T, True = true, False = false> = [T] extends [never] ? True : False;
45
45
  export type MaybePromise<T> = T | Promise<T>;
46
46
  /**
@@ -98,9 +98,9 @@ type LoadableShape = CollectionShape | ReferenceShape | readonly any[];
98
98
  export type UnionKeys<T> = T extends any ? keyof T : never;
99
99
  export type UnionPropertyType<T, K extends PropertyKey> = T extends any ? (K extends keyof T ? T[K] : never) : never;
100
100
  type IsUnion<T, U = T> = T extends any ? ([U] extends [T] ? false : true) : false;
101
- export type MergeUnion<T> = [T] extends [object] ? (T extends Scalar ? T : IsUnion<T> extends true ? {
101
+ export type MergeUnion<T> = [T] extends [object] ? T extends Scalar ? T : IsUnion<T> extends true ? {
102
102
  [K in UnionKeys<T>]: UnionPropertyType<T, K>;
103
- } : T) : T;
103
+ } : T : T;
104
104
  export type DeepPartial<T> = T & {
105
105
  [P in keyof T]?: T[P] extends (infer U)[] ? DeepPartial<U>[] : T[P] extends Readonly<infer U>[] ? Readonly<DeepPartial<U>>[] : DeepPartial<T[P]>;
106
106
  };
@@ -110,6 +110,10 @@ export declare const OptionalProps: unique symbol;
110
110
  export declare const EagerProps: unique symbol;
111
111
  export declare const HiddenProps: unique symbol;
112
112
  export declare const Config: unique symbol;
113
+ export declare const EntityName: unique symbol;
114
+ export type InferEntityName<T> = T extends {
115
+ [EntityName]?: infer Name;
116
+ } ? (Name extends string ? Name : never) : never;
113
117
  export type Opt<T = unknown> = T & Opt.Brand;
114
118
  export declare namespace Opt {
115
119
  const __optional: unique symbol;
@@ -169,11 +173,11 @@ export type Primary<T> = IsAny<T> extends true ? any : T extends {
169
173
  /** @internal */
170
174
  export type PrimaryProperty<T> = T extends {
171
175
  [PrimaryKeyProp]?: infer PK;
172
- } ? (PK extends keyof T ? PK : (PK extends any[] ? PK[number] : never)) : T extends {
176
+ } ? PK extends keyof T ? PK : PK extends any[] ? PK[number] : never : T extends {
173
177
  _id?: any;
174
- } ? (T extends {
178
+ } ? T extends {
175
179
  id?: any;
176
- } ? 'id' | '_id' : '_id') : T extends {
180
+ } ? 'id' | '_id' : '_id' : T extends {
177
181
  id?: any;
178
182
  } ? 'id' : T extends {
179
183
  uuid?: any;
@@ -233,7 +237,7 @@ type ExpandQueryMerged<T> = [T] extends [object] ? [T] extends [Scalar] ? never
233
237
  export type FilterObject<T> = {
234
238
  -readonly [K in EntityKey<T>]?: ExpandQuery<ExpandProperty<FilterObjectProp<T, K>>> | ExpandQueryMerged<ExpandProperty<FilterObjectProp<T, K>>> | FilterValue<ExpandProperty<FilterObjectProp<T, K>>> | null;
235
239
  };
236
- export type ExpandQuery<T> = T extends object ? T extends Scalar ? never : FilterQuery<T> : FilterValue<T>;
240
+ export type ExpandQuery<T> = T extends object ? (T extends Scalar ? never : FilterQuery<T>) : FilterValue<T>;
237
241
  export type EntityProps<T> = {
238
242
  -readonly [K in EntityKey<T>]?: T[K];
239
243
  };
@@ -243,7 +247,7 @@ export interface IWrappedEntity<Entity extends object> {
243
247
  isInitialized(): boolean;
244
248
  isManaged(): boolean;
245
249
  populated(populated?: boolean): void;
246
- populate<Hint extends string = never>(populate: readonly AutoPath<Entity, Hint, PopulatePath.ALL>[] | false, options?: EntityLoaderOptions<Entity>): Promise<Loaded<Entity, Hint>>;
250
+ populate<Hint extends string = never, Fields extends string = never>(populate: readonly AutoPath<Entity, Hint, PopulatePath.ALL>[] | false, options?: EntityLoaderOptions<Entity, Fields>): Promise<Loaded<Entity, Hint>>;
247
251
  init<Hint extends string = never, Fields extends string = '*', Exclude extends string = never>(options?: FindOneOptions<Entity, Hint, Fields, Exclude>): Promise<Loaded<Entity, Hint, Fields, Exclude> | null>;
248
252
  toReference(): Ref<Entity> & LoadedReference<Loaded<Entity, AddEager<Entity>>>;
249
253
  toObject(): EntityDTO<Entity>;
@@ -251,7 +255,7 @@ export interface IWrappedEntity<Entity extends object> {
251
255
  toObject<Ignored extends EntityKey<Entity>>(ignoreFields: Ignored[]): Omit<EntityDTO<Entity>, Ignored>;
252
256
  toJSON(...args: any[]): EntityDTO<Entity>;
253
257
  toPOJO(): EntityDTO<Entity>;
254
- serialize<Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Hint extends string = never, Exclude extends string = never>(options?: SerializeOptions<Naked, Hint, Exclude>): EntityDTO<Loaded<Naked, Hint>>;
258
+ serialize<Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Hint extends string = never, Exclude extends string = never>(options?: SerializeOptions<Naked, Hint, Exclude>): SerializeDTO<Naked, Hint, Exclude>;
255
259
  setSerializationContext<Hint extends string = never, Fields extends string = '*', Exclude extends string = never>(options: LoadHint<Entity, Hint, Fields, Exclude>): void;
256
260
  assign<Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Convert extends boolean = false, Data extends EntityData<Naked, Convert> | Partial<EntityDTO<Naked>> = EntityData<Naked, Convert> | Partial<EntityDTO<Naked>>>(data: Data & IsSubset<EntityData<Naked, Convert>, Data>, options?: AssignOptions<Convert>): MergeSelected<Entity, Naked, keyof Data & string>;
257
261
  getSchema(): string | undefined;
@@ -320,11 +324,11 @@ type NonArrayObject = object & {
320
324
  export type EntityDataProp<T, C extends boolean> = T extends Date ? string | Date : T extends Scalar ? T : T extends ScalarReference<infer U> ? EntityDataProp<U, C> : T extends {
321
325
  __runtime?: infer Runtime;
322
326
  __raw?: infer Raw;
323
- } ? (C extends true ? Raw : Runtime) : T extends ReferenceShape<infer U> ? EntityDataNested<U, C> : T extends CollectionShape<infer U> ? U | U[] | EntityDataNested<U & object, C> | EntityDataNested<U & object, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
327
+ } ? C extends true ? Raw : Runtime : T extends ReferenceShape<infer U> ? EntityDataNested<U, C> : T extends CollectionShape<infer U> ? U | U[] | EntityDataNested<U & object, C> | EntityDataNested<U & object, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
324
328
  export type RequiredEntityDataProp<T, O, C extends boolean> = T extends Date ? string | Date : Exclude<T, null> extends RequiredNullable.Brand ? T | null : T extends Scalar ? T : T extends ScalarReference<infer U> ? RequiredEntityDataProp<U, O, C> : T extends {
325
329
  __runtime?: infer Runtime;
326
330
  __raw?: infer Raw;
327
- } ? (C extends true ? Raw : Runtime) : T extends ReferenceShape<infer U> ? RequiredEntityDataNested<U, O, C> : T extends CollectionShape<infer U> ? U | U[] | RequiredEntityDataNested<U & object, O, C> | RequiredEntityDataNested<U & object, O, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : U[] | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
331
+ } ? C extends true ? Raw : Runtime : T extends ReferenceShape<infer U> ? RequiredEntityDataNested<U, O, C> : T extends CollectionShape<infer U> ? U | U[] | RequiredEntityDataNested<U & object, O, C> | RequiredEntityDataNested<U & object, O, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : U[] | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
328
332
  export type EntityDataNested<T, C extends boolean = false> = T extends undefined ? never : T extends any[] ? Readonly<T> : EntityData<T, C> | ExpandEntityProp<T, C>;
329
333
  type UnwrapScalarRef<T> = T extends ScalarReference<infer U> ? U : T;
330
334
  type EntityDataItem<T, C extends boolean> = C extends false ? UnwrapScalarRef<T> | EntityDataProp<T, C> | Raw | null : EntityDataProp<T, C> | Raw | null;
@@ -364,9 +368,9 @@ export type Rel<T> = T;
364
368
  /** Alias for `ScalarReference` (see {@apilink Ref}). */
365
369
  export type ScalarRef<T> = ScalarReference<T>;
366
370
  /** Alias for `Reference<T> & { id: number }` (see {@apilink Ref}). */
367
- export type EntityRef<T extends object> = true extends IsUnknown<PrimaryProperty<T>> ? Reference<T> : IsAny<T> extends true ? Reference<T> : ({
371
+ export type EntityRef<T extends object> = true extends IsUnknown<PrimaryProperty<T>> ? Reference<T> : IsAny<T> extends true ? Reference<T> : {
368
372
  [K in PrimaryProperty<T> & keyof T]: T[K];
369
- } & Reference<T>);
373
+ } & Reference<T>;
370
374
  /**
371
375
  * Ref type represents a `Reference` instance, and adds the primary keys to its prototype automatically, so you can do
372
376
  * `ref.id` instead of `ref.unwrap().id`. It resolves to either `ScalarRef` or `EntityRef`, based on the type argument.
@@ -380,14 +384,15 @@ type ExtractHiddenProps<T> = (T extends {
380
384
  type ExcludeHidden<T, K extends keyof T> = K extends ExtractHiddenProps<T> ? never : K;
381
385
  type ExtractConfig<T> = T extends {
382
386
  [Config]?: infer K;
383
- } ? (K & TypeConfig) : TypeConfig;
387
+ } ? K & TypeConfig : TypeConfig;
384
388
  type PreferExplicitConfig<E, I> = IsNever<E, I, E>;
385
389
  type PrimaryOrObject<T, U, C extends TypeConfig> = PreferExplicitConfig<C, ExtractConfig<T>>['forceObject'] extends true ? {
386
390
  [K in PrimaryProperty<U> & keyof U]: U[K];
387
391
  } : Primary<U>;
388
- export type EntityDTOProp<E, T, C extends TypeConfig = never> = T extends Scalar ? T : T extends ScalarReference<infer U> ? U : T extends {
392
+ type DTOWrapper<T, C extends TypeConfig, Flat extends boolean> = Flat extends true ? EntityDTOFlat<T, C> : EntityDTO<T, C>;
393
+ export type EntityDTOProp<E, T, C extends TypeConfig = never, Flat extends boolean = false> = T extends Scalar ? T : T extends ScalarReference<infer U> ? U : T extends {
389
394
  __serialized?: infer U;
390
- } ? (IsUnknown<U> extends false ? U : T) : T extends LoadedReferenceShape<infer U> ? EntityDTO<U, C> : T extends ReferenceShape<infer U> ? PrimaryOrObject<E, U, C> : T extends LoadedCollectionShape<infer U> ? EntityDTO<U & object, C>[] : T extends CollectionShape<infer U> ? PrimaryOrObject<E, U & object, C>[] : T extends readonly (infer U)[] ? U extends Scalar ? T : EntityDTOProp<E, U, C>[] : T extends Relation<T> ? EntityDTO<T, C> : T;
395
+ } ? IsUnknown<U> extends false ? U : T : T extends LoadedReferenceShape<infer U> ? DTOWrapper<U, C, Flat> : T extends ReferenceShape<infer U> ? PrimaryOrObject<E, U, C> : T extends LoadedCollectionShape<infer U> ? DTOWrapper<U & object, C, Flat>[] : T extends CollectionShape<infer U> ? PrimaryOrObject<E, U & object, C>[] : T extends readonly (infer U)[] ? U extends Scalar ? T : EntityDTOProp<E, U, C, Flat>[] : T extends Relation<T> ? DTOWrapper<T, C, Flat> : T;
391
396
  type UnwrapLoadedEntity<T> = T extends {
392
397
  [__loadedType]?: infer U;
393
398
  } ? NonNullable<U> : T;
@@ -400,6 +405,27 @@ export type EntityDTO<T, C extends TypeConfig = never> = {
400
405
  } & {
401
406
  [K in keyof T as DTOOptionalKeys<T, K>]?: EntityDTOProp<T, T[K], C> | AddOptional<T[K]>;
402
407
  };
408
+ /**
409
+ * @internal
410
+ * 1-pass variant of EntityDTO — ~2x cheaper to resolve but all keys are required
411
+ * (optional keys use `| undefined` in value type instead of `?` modifier).
412
+ * Use only for internal type computations (output types), never as a user-facing
413
+ * function parameter type where generic assignability checks are needed.
414
+ */
415
+ export type EntityDTOFlat<T, C extends TypeConfig = never> = {
416
+ [K in keyof T as ExcludeHidden<T, K> & CleanKeys<T, K>]: EntityDTOProp<T, T[K], C, true> | AddOptional<T[K]>;
417
+ };
418
+ /**
419
+ * @internal
420
+ * Single-pass fused type that combines Loaded + EntityDTO into one mapped type.
421
+ * ~40x faster than `EntityDTO<Loaded<T, H>>` for populated entities.
422
+ */
423
+ type SerializeTopHints<H extends string> = H extends `${infer Top}.${string}` ? Top : H;
424
+ type SerializeSubHints<K extends string, H extends string> = H extends `${K}.${infer Rest}` ? Rest : never;
425
+ type SerializePropValue<T, K extends keyof T, H extends string, C extends TypeConfig = never> = K & string extends SerializeTopHints<H> ? NonNullable<T[K]> extends CollectionShape<infer U> ? SerializeDTO<U & object, SerializeSubHints<K & string, H>, never, C>[] : SerializeDTO<ExpandProperty<T[K]>, SerializeSubHints<K & string, H>, never, C> | Extract<T[K], null | undefined> : EntityDTOProp<T, T[K], C>;
426
+ export type SerializeDTO<T, H extends string = never, E extends string = never, C extends TypeConfig = never> = string extends H ? EntityDTOFlat<T, C> : {
427
+ [K in keyof T as ExcludeHidden<T, K> & CleanKeys<T, K> & (IsNever<E> extends true ? K : Exclude<K, E>)]: SerializePropValue<T, K, H, C> | Extract<T[K], null | undefined>;
428
+ };
403
429
  type TargetKeys<T> = T extends EntityClass<infer P> ? keyof P : keyof T;
404
430
  type PropertyName<T> = IsUnknown<T> extends false ? TargetKeys<T> : string;
405
431
  export type FormulaTable = {
@@ -792,7 +818,7 @@ export interface GenerateOptions {
792
818
  export interface IEntityGenerator {
793
819
  generate(options?: GenerateOptions): Promise<string[]>;
794
820
  }
795
- export type UmzugMigration = {
821
+ export type MigrationInfo = {
796
822
  name: string;
797
823
  path?: string;
798
824
  };
@@ -812,6 +838,14 @@ export type MigrationRow = {
812
838
  name: string;
813
839
  executed_at: Date;
814
840
  };
841
+ /**
842
+ * @internal
843
+ */
844
+ export interface IMigrationRunner {
845
+ run(migration: Migration, method: 'up' | 'down'): Promise<void>;
846
+ setMasterMigration(trx: Transaction): void;
847
+ unsetMasterMigration(): void;
848
+ }
815
849
  /**
816
850
  * @internal
817
851
  */
@@ -852,23 +886,23 @@ export interface IMigrator {
852
886
  /**
853
887
  * Returns list of pending (not yet executed) migrations found in the migration directory.
854
888
  */
855
- getPending(): Promise<UmzugMigration[]>;
889
+ getPending(): Promise<MigrationInfo[]>;
856
890
  /**
857
891
  * Executes specified migrations. Without parameter it will migrate up to the latest version.
858
892
  */
859
- up(options?: string | string[] | MigrateOptions): Promise<UmzugMigration[]>;
893
+ up(options?: string | string[] | MigrateOptions): Promise<MigrationInfo[]>;
860
894
  /**
861
895
  * Executes down migrations to the given point. Without parameter it will migrate one version down.
862
896
  */
863
- down(options?: string | string[] | MigrateOptions): Promise<UmzugMigration[]>;
897
+ down(options?: string | string[] | Omit<MigrateOptions, 'from'>): Promise<MigrationInfo[]>;
864
898
  /**
865
899
  * Registers event handler.
866
900
  */
867
- on(event: MigratorEvent, listener: (event: UmzugMigration) => MaybePromise<void>): IMigrator;
901
+ on(event: MigratorEvent, listener: (event: MigrationInfo) => MaybePromise<void>): IMigrator;
868
902
  /**
869
903
  * Removes event handler.
870
904
  */
871
- off(event: MigratorEvent, listener: (event: UmzugMigration) => MaybePromise<void>): IMigrator;
905
+ off(event: MigratorEvent, listener: (event: MigrationInfo) => MaybePromise<void>): IMigrator;
872
906
  /**
873
907
  * @internal
874
908
  */
@@ -896,6 +930,10 @@ export interface IMigrationGenerator {
896
930
  export interface Migration {
897
931
  up(): Promise<void> | void;
898
932
  down(): Promise<void> | void;
933
+ isTransactional(): boolean;
934
+ reset(): void;
935
+ setTransactionContext(ctx: Transaction): void;
936
+ getQueries?(): any[];
899
937
  }
900
938
  export interface MigrationObject {
901
939
  name: string;
@@ -937,7 +975,7 @@ type ExtractStringKeys<T> = {
937
975
  * Simplified to just check `T extends object` since ExtractType handles the unwrapping.
938
976
  */
939
977
  type StringKeys<T, E extends string = never> = T extends object ? ExtractStringKeys<ExtractType<T>> | E : never;
940
- type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ? ExtractType<T[K]> : (K extends E ? keyof T : never);
978
+ type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ? ExtractType<T[K]> : K extends E ? keyof T : never;
941
979
  type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
942
980
  type RelationKeys<T> = T extends object ? {
943
981
  [K in keyof T]-?: CleanKeys<T, K, true>;
@@ -947,12 +985,12 @@ export type UnboxArray<T> = T extends any[] ? ArrayElement<T> : T;
947
985
  export type ArrayElement<ArrayType extends unknown[]> = ArrayType extends (infer ElementType)[] ? ElementType : never;
948
986
  export type ExpandProperty<T> = T extends ReferenceShape<infer U> ? NonNullable<U> : T extends CollectionShape<infer U> ? NonNullable<U> : T extends (infer U)[] ? NonNullable<U> : NonNullable<T>;
949
987
  type LoadedLoadable<T, E extends object> = T extends CollectionShape ? LoadedCollection<E> : T extends ScalarReference<infer U> ? LoadedScalarReference<U> : T extends ReferenceShape ? T & LoadedReference<E> : T extends Scalar ? T : T extends (infer U)[] ? U extends Scalar ? T : E[] : E;
950
- type IsTrue<T> = IsNever<T> extends true ? false : T extends boolean ? T extends true ? true : false : false;
951
- type StringLiteral<T> = T extends string ? string extends T ? never : T : never;
952
- type Prefix<T, K> = K extends `${infer S}.${string}` ? S : (K extends '*' ? keyof T : K);
988
+ type IsTrue<T> = IsNever<T> extends true ? false : T extends boolean ? (T extends true ? true : false) : false;
989
+ type StringLiteral<T> = T extends string ? (string extends T ? never : T) : never;
990
+ type Prefix<T, K> = K extends `${infer S}.${string}` ? S : K extends '*' ? keyof T : K;
953
991
  type IsPrefixedExclude<T, K extends keyof T, E extends string> = K extends E ? never : K;
954
- export type IsPrefixed<T, K extends keyof T, L extends string, E extends string = never> = IsNever<E> extends false ? IsPrefixedExclude<T, K, E> : K extends symbol ? never : IsTrue<L> extends true ? (T[K] & {} extends LoadableShape ? K : never) : IsNever<StringLiteral<L>> extends true ? never : L extends '*' ? K : K extends Prefix<T, L> ? K : K extends PrimaryProperty<T> ? K : never;
955
- type Suffix<Key, Hint extends string, All = true | '*'> = Hint extends `${infer Pref}.${infer Suf}` ? (Pref extends Key ? Suf : never) : Hint extends All ? Hint : never;
992
+ export type IsPrefixed<T, K extends keyof T, L extends string, E extends string = never> = IsNever<E> extends false ? IsPrefixedExclude<T, K, E> : K extends symbol ? never : IsTrue<L> extends true ? T[K] & {} extends LoadableShape ? K : never : IsNever<StringLiteral<L>> extends true ? never : '*' extends L ? K : K extends Prefix<T, L> ? K : K extends PrimaryProperty<T> ? K : never;
993
+ type Suffix<Key, Hint extends string, All = true | '*'> = Hint extends `${infer Pref}.${infer Suf}` ? Pref extends Key ? Suf : never : Hint extends All ? Hint : never;
956
994
  export type IsSubset<T, U> = keyof U extends keyof T ? {} : string extends keyof U ? {} : {
957
995
  [K in keyof U as K extends keyof T ? never : CleanKeys<U, K>]: never;
958
996
  };
@@ -981,9 +1019,7 @@ type LoadedProp<T, L extends string = never, F extends string = '*', E extends s
981
1019
  export type AddEager<T> = ExtractEagerProps<T> & string;
982
1020
  export type ExpandHint<T, L extends string> = L | AddEager<T>;
983
1021
  export type Selected<T, L extends string = never, F extends string = '*'> = {
984
- [K in keyof T as IsPrefixed<T, K, L | F | AddEager<T>>]: LoadedProp<NonNullable<T[K]>, Suffix<K, L, true>, Suffix<K, F, true>> | AddOptional<T[K]>;
985
- } & {
986
- [K in keyof T as FunctionKeys<T, K>]: T[K];
1022
+ [K in keyof T as IsPrefixed<T, K, L | F | AddEager<T>> | FunctionKeys<T, K>]: T[K] extends Function ? T[K] : NonNullable<T[K]> extends Scalar ? T[K] : LoadedProp<NonNullable<T[K]>, Suffix<K, L, true>, Suffix<K, F, true>> | AddOptional<T[K]>;
987
1023
  } & {
988
1024
  [__selectedType]?: T;
989
1025
  };
@@ -1056,6 +1092,10 @@ export interface ISeedManager {
1056
1092
  export interface Seeder<T extends Dictionary = Dictionary> {
1057
1093
  run(em: EntityManager, context?: T): void | Promise<void>;
1058
1094
  }
1095
+ export interface SeederObject {
1096
+ name: string;
1097
+ class: Constructor<Seeder>;
1098
+ }
1059
1099
  export type ConnectionType = 'read' | 'write';
1060
1100
  export type MetadataProcessor = (metadata: EntityMetadata[], platform: Platform) => MaybePromise<void>;
1061
1101
  export type MaybeReturnType<T> = T extends (...args: any[]) => infer R ? R : T;
package/typings.js CHANGED
@@ -11,6 +11,8 @@ export const OptionalProps = Symbol('OptionalProps');
11
11
  export const EagerProps = Symbol('EagerProps');
12
12
  export const HiddenProps = Symbol('HiddenProps');
13
13
  export const Config = Symbol('Config');
14
+ // eslint-disable-next-line @typescript-eslint/no-redeclare
15
+ export const EntityName = Symbol('EntityName');
14
16
  export class EntityMetadata {
15
17
  static counter = 0;
16
18
  _id = 1000 * EntityMetadata.counter++; // keep the id >= 1000 to allow computing cache keys by simple addition
@@ -29,11 +31,9 @@ export class EntityMetadata {
29
31
  Object.assign(this, meta);
30
32
  const name = meta.className ?? meta.name;
31
33
  if (!this.class && name) {
32
- const Class = this.extends === BaseEntity
33
- ? ({ [name]: class extends BaseEntity {
34
- } })[name]
35
- : ({ [name]: class {
36
- } })[name];
34
+ const Class = this.extends === BaseEntity ? { [name]: class extends BaseEntity {
35
+ } }[name] : { [name]: class {
36
+ } }[name];
37
37
  this.class = Class;
38
38
  }
39
39
  }
@@ -106,9 +106,7 @@ export class EntityMetadata {
106
106
  */
107
107
  createSchemaColumnMappingObject() {
108
108
  // For TPT entities, only include properties that belong to this entity's table
109
- const props = this.inheritanceType === 'tpt' && this.ownProps
110
- ? this.ownProps
111
- : Object.values(this.properties);
109
+ const props = this.inheritanceType === 'tpt' && this.ownProps ? this.ownProps : Object.values(this.properties);
112
110
  return props.reduce((o, prop) => {
113
111
  if (prop.fieldNames) {
114
112
  o[prop.name] = prop.fieldNames[0];
@@ -206,7 +204,11 @@ export class EntityMetadata {
206
204
  const hydrator = wrapped.hydrator;
207
205
  const entity = Reference.unwrapReference(val ?? wrapped.__data[prop.name]);
208
206
  const old = Reference.unwrapReference(wrapped.__data[prop.name]);
209
- if (old && old !== entity && prop.kind === ReferenceKind.MANY_TO_ONE && prop.inversedBy && old[prop.inversedBy]) {
207
+ if (old &&
208
+ old !== entity &&
209
+ prop.kind === ReferenceKind.MANY_TO_ONE &&
210
+ prop.inversedBy &&
211
+ old[prop.inversedBy]) {
210
212
  old[prop.inversedBy].removeWithoutPropagation(this);
211
213
  }
212
214
  wrapped.__data[prop.name] = Reference.wrapReference(val, prop);
@@ -27,10 +27,10 @@ export class ChangeSet {
27
27
  else {
28
28
  this.primaryKey = this.originalEntity[this.meta.primaryKeys[0]];
29
29
  }
30
- if (!this.meta.compositePK
31
- && this.meta.getPrimaryProp().targetMeta?.compositePK
32
- && typeof this.primaryKey === 'object'
33
- && this.primaryKey !== null) {
30
+ if (!this.meta.compositePK &&
31
+ this.meta.getPrimaryProp().targetMeta?.compositePK &&
32
+ typeof this.primaryKey === 'object' &&
33
+ this.primaryKey !== null) {
34
34
  this.primaryKey = this.meta.getPrimaryProp().targetMeta.primaryKeys.map(childPK => {
35
35
  return this.primaryKey[childPK];
36
36
  });