@mikro-orm/core 7.0.0-dev.9 → 7.0.0-dev.90

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 (191) hide show
  1. package/EntityManager.d.ts +77 -48
  2. package/EntityManager.js +288 -225
  3. package/MikroORM.d.ts +40 -31
  4. package/MikroORM.js +98 -137
  5. package/README.md +3 -2
  6. package/cache/FileCacheAdapter.d.ts +1 -1
  7. package/cache/FileCacheAdapter.js +6 -5
  8. package/cache/GeneratedCacheAdapter.d.ts +0 -1
  9. package/cache/GeneratedCacheAdapter.js +0 -2
  10. package/cache/index.d.ts +0 -1
  11. package/cache/index.js +0 -1
  12. package/connections/Connection.d.ts +11 -7
  13. package/connections/Connection.js +16 -14
  14. package/drivers/DatabaseDriver.d.ts +11 -5
  15. package/drivers/DatabaseDriver.js +23 -11
  16. package/drivers/IDatabaseDriver.d.ts +25 -4
  17. package/entity/BaseEntity.d.ts +0 -1
  18. package/entity/BaseEntity.js +0 -3
  19. package/entity/Collection.d.ts +95 -30
  20. package/entity/Collection.js +432 -93
  21. package/entity/EntityAssigner.d.ts +1 -1
  22. package/entity/EntityAssigner.js +17 -9
  23. package/entity/EntityFactory.d.ts +7 -0
  24. package/entity/EntityFactory.js +63 -41
  25. package/entity/EntityHelper.js +26 -12
  26. package/entity/EntityLoader.d.ts +5 -4
  27. package/entity/EntityLoader.js +63 -38
  28. package/entity/EntityRepository.d.ts +1 -1
  29. package/entity/Reference.d.ts +6 -5
  30. package/entity/Reference.js +34 -9
  31. package/entity/WrappedEntity.d.ts +2 -7
  32. package/entity/WrappedEntity.js +2 -7
  33. package/entity/defineEntity.d.ts +568 -0
  34. package/entity/defineEntity.js +529 -0
  35. package/entity/index.d.ts +3 -2
  36. package/entity/index.js +3 -2
  37. package/entity/utils.d.ts +7 -0
  38. package/entity/utils.js +16 -4
  39. package/entity/validators.d.ts +11 -0
  40. package/entity/validators.js +65 -0
  41. package/enums.d.ts +21 -6
  42. package/enums.js +14 -1
  43. package/errors.d.ts +10 -2
  44. package/errors.js +29 -10
  45. package/events/EventManager.d.ts +2 -1
  46. package/events/EventManager.js +19 -11
  47. package/events/EventSubscriber.d.ts +3 -1
  48. package/hydration/Hydrator.js +1 -2
  49. package/hydration/ObjectHydrator.d.ts +4 -4
  50. package/hydration/ObjectHydrator.js +35 -25
  51. package/index.d.ts +2 -2
  52. package/index.js +1 -2
  53. package/logging/DefaultLogger.d.ts +1 -1
  54. package/logging/DefaultLogger.js +1 -0
  55. package/logging/SimpleLogger.d.ts +1 -1
  56. package/logging/index.d.ts +1 -0
  57. package/logging/index.js +1 -0
  58. package/logging/inspect.d.ts +2 -0
  59. package/logging/inspect.js +16 -0
  60. package/metadata/EntitySchema.d.ts +9 -13
  61. package/metadata/EntitySchema.js +44 -26
  62. package/metadata/MetadataDiscovery.d.ts +6 -9
  63. package/metadata/MetadataDiscovery.js +165 -205
  64. package/metadata/MetadataProvider.d.ts +11 -2
  65. package/metadata/MetadataProvider.js +44 -2
  66. package/metadata/MetadataStorage.d.ts +1 -6
  67. package/metadata/MetadataStorage.js +6 -18
  68. package/metadata/MetadataValidator.d.ts +0 -7
  69. package/metadata/MetadataValidator.js +0 -10
  70. package/metadata/discover-entities.d.ts +5 -0
  71. package/metadata/discover-entities.js +40 -0
  72. package/metadata/index.d.ts +1 -1
  73. package/metadata/index.js +1 -1
  74. package/metadata/types.d.ts +480 -0
  75. package/metadata/types.js +1 -0
  76. package/naming-strategy/AbstractNamingStrategy.d.ts +5 -1
  77. package/naming-strategy/AbstractNamingStrategy.js +8 -2
  78. package/naming-strategy/NamingStrategy.d.ts +11 -1
  79. package/not-supported.d.ts +2 -0
  80. package/not-supported.js +4 -0
  81. package/package.json +18 -10
  82. package/platforms/ExceptionConverter.js +1 -1
  83. package/platforms/Platform.d.ts +6 -13
  84. package/platforms/Platform.js +15 -41
  85. package/serialization/EntitySerializer.d.ts +2 -0
  86. package/serialization/EntitySerializer.js +32 -14
  87. package/serialization/EntityTransformer.js +22 -12
  88. package/serialization/SerializationContext.js +16 -13
  89. package/types/ArrayType.d.ts +1 -1
  90. package/types/ArrayType.js +2 -3
  91. package/types/BigIntType.d.ts +8 -6
  92. package/types/BigIntType.js +1 -1
  93. package/types/BlobType.d.ts +0 -1
  94. package/types/BlobType.js +0 -3
  95. package/types/BooleanType.d.ts +2 -1
  96. package/types/BooleanType.js +3 -0
  97. package/types/DecimalType.d.ts +6 -4
  98. package/types/DecimalType.js +3 -3
  99. package/types/DoubleType.js +2 -2
  100. package/types/EnumArrayType.js +1 -2
  101. package/types/JsonType.d.ts +1 -1
  102. package/types/JsonType.js +7 -2
  103. package/types/TinyIntType.js +1 -1
  104. package/types/Type.d.ts +2 -4
  105. package/types/Type.js +3 -3
  106. package/types/Uint8ArrayType.d.ts +0 -1
  107. package/types/Uint8ArrayType.js +1 -4
  108. package/types/index.d.ts +1 -1
  109. package/typings.d.ts +109 -73
  110. package/typings.js +38 -35
  111. package/unit-of-work/ChangeSet.d.ts +0 -3
  112. package/unit-of-work/ChangeSet.js +2 -2
  113. package/unit-of-work/ChangeSetComputer.d.ts +1 -3
  114. package/unit-of-work/ChangeSetComputer.js +11 -9
  115. package/unit-of-work/ChangeSetPersister.d.ts +5 -4
  116. package/unit-of-work/ChangeSetPersister.js +51 -19
  117. package/unit-of-work/UnitOfWork.d.ts +8 -1
  118. package/unit-of-work/UnitOfWork.js +91 -49
  119. package/utils/AbstractSchemaGenerator.d.ts +5 -5
  120. package/utils/AbstractSchemaGenerator.js +11 -9
  121. package/utils/Configuration.d.ts +757 -206
  122. package/utils/Configuration.js +140 -188
  123. package/utils/ConfigurationLoader.d.ts +1 -54
  124. package/utils/ConfigurationLoader.js +1 -352
  125. package/utils/Cursor.d.ts +0 -3
  126. package/utils/Cursor.js +6 -3
  127. package/utils/DataloaderUtils.d.ts +15 -5
  128. package/utils/DataloaderUtils.js +54 -8
  129. package/utils/EntityComparator.d.ts +8 -4
  130. package/utils/EntityComparator.js +52 -17
  131. package/utils/QueryHelper.d.ts +9 -1
  132. package/utils/QueryHelper.js +70 -9
  133. package/utils/RawQueryFragment.d.ts +36 -13
  134. package/utils/RawQueryFragment.js +36 -16
  135. package/utils/TransactionManager.d.ts +65 -0
  136. package/utils/TransactionManager.js +223 -0
  137. package/utils/Utils.d.ts +8 -97
  138. package/utils/Utils.js +82 -302
  139. package/utils/clone.js +2 -3
  140. package/utils/env-vars.d.ts +3 -0
  141. package/utils/env-vars.js +87 -0
  142. package/utils/fs-utils.d.ts +12 -0
  143. package/utils/fs-utils.js +97 -0
  144. package/utils/index.d.ts +2 -1
  145. package/utils/index.js +2 -1
  146. package/utils/upsert-utils.d.ts +7 -2
  147. package/utils/upsert-utils.js +55 -4
  148. package/decorators/Check.d.ts +0 -3
  149. package/decorators/Check.js +0 -13
  150. package/decorators/CreateRequestContext.d.ts +0 -3
  151. package/decorators/CreateRequestContext.js +0 -32
  152. package/decorators/Embeddable.d.ts +0 -8
  153. package/decorators/Embeddable.js +0 -11
  154. package/decorators/Embedded.d.ts +0 -18
  155. package/decorators/Embedded.js +0 -18
  156. package/decorators/Entity.d.ts +0 -18
  157. package/decorators/Entity.js +0 -12
  158. package/decorators/Enum.d.ts +0 -9
  159. package/decorators/Enum.js +0 -16
  160. package/decorators/Filter.d.ts +0 -2
  161. package/decorators/Filter.js +0 -8
  162. package/decorators/Formula.d.ts +0 -4
  163. package/decorators/Formula.js +0 -15
  164. package/decorators/Indexed.d.ts +0 -19
  165. package/decorators/Indexed.js +0 -20
  166. package/decorators/ManyToMany.d.ts +0 -40
  167. package/decorators/ManyToMany.js +0 -14
  168. package/decorators/ManyToOne.d.ts +0 -30
  169. package/decorators/ManyToOne.js +0 -14
  170. package/decorators/OneToMany.d.ts +0 -28
  171. package/decorators/OneToMany.js +0 -17
  172. package/decorators/OneToOne.d.ts +0 -24
  173. package/decorators/OneToOne.js +0 -7
  174. package/decorators/PrimaryKey.d.ts +0 -8
  175. package/decorators/PrimaryKey.js +0 -20
  176. package/decorators/Property.d.ts +0 -250
  177. package/decorators/Property.js +0 -32
  178. package/decorators/Transactional.d.ts +0 -13
  179. package/decorators/Transactional.js +0 -28
  180. package/decorators/hooks.d.ts +0 -16
  181. package/decorators/hooks.js +0 -47
  182. package/decorators/index.d.ts +0 -17
  183. package/decorators/index.js +0 -17
  184. package/entity/ArrayCollection.d.ts +0 -116
  185. package/entity/ArrayCollection.js +0 -402
  186. package/entity/EntityValidator.d.ts +0 -19
  187. package/entity/EntityValidator.js +0 -150
  188. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  189. package/metadata/ReflectMetadataProvider.js +0 -44
  190. package/utils/resolveContextProvider.d.ts +0 -10
  191. package/utils/resolveContextProvider.js +0 -28
@@ -1,7 +1,6 @@
1
- import { inspect } from 'node:util';
2
1
  import { EntityRepository } from '../entity/EntityRepository.js';
3
2
  import { type NamingStrategy } from '../naming-strategy/NamingStrategy.js';
4
- import type { Constructor, EntityProperty, IPrimaryKey, ISchemaGenerator, PopulateOptions, Primary, EntityMetadata, SimpleColumnMeta } from '../typings.js';
3
+ import type { Constructor, EntityMetadata, EntityProperty, IPrimaryKey, ISchemaGenerator, PopulateOptions, Primary, SimpleColumnMeta } from '../typings.js';
5
4
  import { ExceptionConverter } from './ExceptionConverter.js';
6
5
  import type { EntityManager } from '../EntityManager.js';
7
6
  import type { Configuration } from '../utils/Configuration.js';
@@ -30,7 +29,6 @@ export declare abstract class Platform {
30
29
  usesEnumCheckConstraints(): boolean;
31
30
  getSchemaHelper(): unknown;
32
31
  indexForeignKeys(): boolean;
33
- allowsMultiInsert(): boolean;
34
32
  /**
35
33
  * Whether or not the driver supports retuning list of created PKs back when multi-inserting
36
34
  */
@@ -48,11 +46,6 @@ export declare abstract class Platform {
48
46
  * Converts scalar primary key representation to native driver wrapper (e.g. string to mongodb's ObjectId)
49
47
  */
50
48
  denormalizePrimaryKey(data: IPrimaryKey): IPrimaryKey;
51
- /**
52
- * Used when serializing via toObject and toJSON methods, allows to use different PK field name (like `id` instead of `_id`)
53
- */
54
- getSerializedPrimaryKeyField(field: string): string;
55
- usesDifferentSerializedPrimaryKey(): boolean;
56
49
  /**
57
50
  * Returns the SQL specific for the platform to get the current timestamp
58
51
  */
@@ -158,7 +151,7 @@ export declare abstract class Platform {
158
151
  getFullTextIndexExpression(indexName: string, schemaName: string | undefined, tableName: string, columns: SimpleColumnMeta[]): string;
159
152
  convertsJsonAutomatically(): boolean;
160
153
  convertJsonToDatabaseValue(value: unknown, context?: TransformContext): unknown;
161
- convertJsonToJSValue(value: unknown, prop: EntityProperty): unknown;
154
+ convertJsonToJSValue(value: unknown, context?: TransformContext): unknown;
162
155
  convertDateToJSValue(value: string | Date): string;
163
156
  convertIntervalToJSValue(value: string): unknown;
164
157
  convertIntervalToDatabaseValue(value: unknown): unknown;
@@ -175,7 +168,9 @@ export declare abstract class Platform {
175
168
  getExtension<T>(extensionName: string, extensionKey: string, moduleName: string, em: EntityManager): T;
176
169
  getSchemaGenerator(driver: IDatabaseDriver, em?: EntityManager): ISchemaGenerator;
177
170
  processDateProperty(value: unknown): string | number | Date;
178
- quoteIdentifier(id: string, quote?: string): string;
171
+ quoteIdentifier(id: string | {
172
+ toString: () => string;
173
+ }, quote?: string): string;
179
174
  quoteValue(value: any): string;
180
175
  escape(value: any): string;
181
176
  formatQuery(sql: string, params: readonly any[]): string;
@@ -193,7 +188,7 @@ export declare abstract class Platform {
193
188
  getDefaultPrimaryName(tableName: string, columns: string[]): string;
194
189
  supportsCustomPrimaryKeyNames(): boolean;
195
190
  isPopulated<T>(key: string, populate: readonly PopulateOptions<T>[] | boolean): boolean;
196
- shouldHaveColumn<T>(prop: EntityProperty<T>, populate: readonly PopulateOptions<T>[] | boolean, exclude?: string[], includeFormulas?: boolean): boolean;
191
+ shouldHaveColumn<T>(prop: EntityProperty<T>, populate: readonly PopulateOptions<T>[] | boolean, exclude?: string[], includeFormulas?: boolean, ignoreInlineEmbeddables?: boolean): boolean;
197
192
  /**
198
193
  * Currently not supported due to how knex does complex sqlite diffing (always based on current schema)
199
194
  */
@@ -225,6 +220,4 @@ export declare abstract class Platform {
225
220
  * @internal
226
221
  */
227
222
  clone(): this;
228
- /** @ignore */
229
- [inspect.custom](): string;
230
223
  }
@@ -1,10 +1,9 @@
1
- import { inspect } from 'node:util';
2
1
  import { clone } from '../utils/clone.js';
3
2
  import { EntityRepository } from '../entity/EntityRepository.js';
4
3
  import { UnderscoreNamingStrategy } from '../naming-strategy/UnderscoreNamingStrategy.js';
5
4
  import { ExceptionConverter } from './ExceptionConverter.js';
6
- import { ArrayType, BigIntType, BlobType, Uint8ArrayType, BooleanType, CharacterType, DateType, DecimalType, DoubleType, JsonType, SmallIntType, TimeType, TinyIntType, Type, UuidType, StringType, IntegerType, FloatType, DateTimeType, TextType, EnumType, UnknownType, MediumIntType, IntervalType, } from '../types/index.js';
7
- import { parseJsonSafe, Utils } from '../utils/Utils.js';
5
+ import { ArrayType, BigIntType, BlobType, BooleanType, CharacterType, DateTimeType, DateType, DecimalType, DoubleType, EnumType, FloatType, IntegerType, IntervalType, JsonType, MediumIntType, SmallIntType, StringType, TextType, TimeType, TinyIntType, Type, Uint8ArrayType, UnknownType, UuidType, } from '../types/index.js';
6
+ import { parseJsonSafe } from '../utils/Utils.js';
8
7
  import { ReferenceKind } from '../enums.js';
9
8
  import { RawQueryFragment } from '../utils/RawQueryFragment.js';
10
9
  export const JsonProperty = Symbol('JsonProperty');
@@ -48,9 +47,6 @@ export class Platform {
48
47
  indexForeignKeys() {
49
48
  return false;
50
49
  }
51
- allowsMultiInsert() {
52
- return true;
53
- }
54
50
  /**
55
51
  * Whether or not the driver supports retuning list of created PKs back when multi-inserting
56
52
  */
@@ -78,15 +74,6 @@ export class Platform {
78
74
  denormalizePrimaryKey(data) {
79
75
  return data;
80
76
  }
81
- /**
82
- * Used when serializing via toObject and toJSON methods, allows to use different PK field name (like `id` instead of `_id`)
83
- */
84
- getSerializedPrimaryKeyField(field) {
85
- return field;
86
- }
87
- usesDifferentSerializedPrimaryKey() {
88
- return false;
89
- }
90
77
  /**
91
78
  * Returns the SQL specific for the platform to get the current timestamp
92
79
  */
@@ -133,7 +120,7 @@ export class Platform {
133
120
  return true;
134
121
  }
135
122
  isBigIntProperty(prop) {
136
- return prop.columnTypes && prop.columnTypes[0] === 'bigint';
123
+ return prop.columnTypes?.[0] === 'bigint';
137
124
  }
138
125
  getDefaultSchemaName() {
139
126
  return undefined;
@@ -169,7 +156,7 @@ export class Platform {
169
156
  return `text`;
170
157
  }
171
158
  getEnumTypeDeclarationSQL(column) {
172
- if (column.items?.every(item => Utils.isString(item))) {
159
+ if (column.items?.every(item => typeof item === 'string')) {
173
160
  return `enum('${column.items.join("','")}')`;
174
161
  }
175
162
  return this.getTinyIntTypeDeclarationSQL(column);
@@ -269,7 +256,7 @@ export class Platform {
269
256
  getSearchJsonPropertyKey(path, type, aliased, value) {
270
257
  return path.join('.');
271
258
  }
272
- /* v8 ignore next 3 */
259
+ /* v8 ignore next */
273
260
  getJsonIndexDefinition(index) {
274
261
  return index.columnNames;
275
262
  }
@@ -288,11 +275,7 @@ export class Platform {
288
275
  convertJsonToDatabaseValue(value, context) {
289
276
  return JSON.stringify(value);
290
277
  }
291
- convertJsonToJSValue(value, prop) {
292
- const isObjectEmbedded = prop.embedded && prop.object;
293
- if ((this.convertsJsonAutomatically() || isObjectEmbedded) && ['json', 'jsonb', this.getJsonDeclarationSQL()].includes(prop.columnTypes[0])) {
294
- return value;
295
- }
278
+ convertJsonToJSValue(value, context) {
296
279
  return parseJsonSafe(value);
297
280
  }
298
281
  convertDateToJSValue(value) {
@@ -306,7 +289,7 @@ export class Platform {
306
289
  }
307
290
  parseDate(value) {
308
291
  const date = new Date(value);
309
- /* v8 ignore next 3 */
292
+ /* v8 ignore next */
310
293
  if (isNaN(date.getTime())) {
311
294
  return value;
312
295
  }
@@ -336,19 +319,10 @@ export class Platform {
336
319
  if (extension) {
337
320
  return extension;
338
321
  }
339
- /* v8 ignore next 4 */
340
- const module = Utils.tryRequire({
341
- module: moduleName,
342
- warning: `Please install ${moduleName} package.`,
343
- });
344
- /* v8 ignore next 3 */
345
- if (module) {
346
- return this.config.getCachedService(module[extensionName], em);
347
- }
348
- /* v8 ignore next 2 */
349
- throw new Error(`${extensionName} extension not registered.`);
322
+ /* v8 ignore next */
323
+ throw new Error(`${extensionName} extension not registered. Provide it in the ORM config, or use the async \`MikroORM.init()\` method to load extensions automatically.`);
350
324
  }
351
- /* v8 ignore next 3: kept for type inference only */
325
+ /* v8 ignore next: kept for type inference only */
352
326
  getSchemaGenerator(driver, em) {
353
327
  throw new Error(`${driver.constructor.name} does not support SchemaGenerator`);
354
328
  }
@@ -365,7 +339,7 @@ export class Platform {
365
339
  quoteValue(value) {
366
340
  return value;
367
341
  }
368
- /* v8 ignore next 3 */
342
+ /* v8 ignore next */
369
343
  escape(value) {
370
344
  return value;
371
345
  }
@@ -455,7 +429,7 @@ export class Platform {
455
429
  isPopulated(key, populate) {
456
430
  return populate === true || (populate !== false && populate.some(p => p.field === key || p.all));
457
431
  }
458
- shouldHaveColumn(prop, populate, exclude, includeFormulas = true) {
432
+ shouldHaveColumn(prop, populate, exclude, includeFormulas = true, ignoreInlineEmbeddables = true) {
459
433
  if (exclude?.includes(prop.name)) {
460
434
  return false;
461
435
  }
@@ -475,7 +449,7 @@ export class Platform {
475
449
  return true;
476
450
  }
477
451
  if (prop.kind === ReferenceKind.EMBEDDED) {
478
- return !!prop.object;
452
+ return prop.object || ignoreInlineEmbeddables;
479
453
  }
480
454
  return prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner;
481
455
  }
@@ -522,9 +496,9 @@ export class Platform {
522
496
  clone() {
523
497
  return this;
524
498
  }
525
- /* v8 ignore next 4 */
526
499
  /** @ignore */
527
- [inspect.custom]() {
500
+ /* v8 ignore next */
501
+ [Symbol.for('nodejs.util.inspect.custom')]() {
528
502
  return `[${this.constructor.name}]`;
529
503
  }
530
504
  }
@@ -17,6 +17,8 @@ export interface SerializeOptions<T, P extends string = never, E extends string
17
17
  forceObject?: boolean;
18
18
  /** Ignore custom property serializers. */
19
19
  ignoreSerializers?: boolean;
20
+ /** Include properties marked as `hidden`. */
21
+ includeHidden?: boolean;
20
22
  /** Skip properties with `null` value. */
21
23
  skipNull?: boolean;
22
24
  /** Only include properties for a specific group. If a property does not specify any group, it will be included, otherwise only properties with a matching group are included. */
@@ -15,8 +15,8 @@ function isVisible(meta, propName, options) {
15
15
  if (options.exclude?.find(item => item === propName)) {
16
16
  return false;
17
17
  }
18
- const visible = prop && !prop.hidden;
19
- const prefixed = prop && !prop.primary && propName.startsWith('_'); // ignore prefixed properties, if it's not a PK
18
+ const visible = prop && !(prop.hidden && !options.includeHidden);
19
+ const prefixed = prop && !prop.primary && !prop.accessor && propName.startsWith('_'); // ignore prefixed properties, if it's not a PK
20
20
  return visible && !prefixed;
21
21
  }
22
22
  function isPopulated(propName, options) {
@@ -41,13 +41,31 @@ export class EntitySerializer {
41
41
  }
42
42
  const root = wrapped.__serializationContext.root;
43
43
  const ret = {};
44
- const keys = new Set(meta.primaryKeys);
45
- Utils.keys(entity).forEach(prop => keys.add(prop));
44
+ const props = new Set();
45
+ if (meta.serializedPrimaryKey && !meta.compositePK) {
46
+ props.add(meta.serializedPrimaryKey);
47
+ }
48
+ else {
49
+ meta.primaryKeys.forEach(pk => props.add(pk));
50
+ }
51
+ if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
52
+ const entityKeys = new Set(Object.keys(entity));
53
+ for (const prop of meta.props) {
54
+ if (entityKeys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
55
+ props.add(prop.name);
56
+ }
57
+ }
58
+ for (const key of entityKeys) {
59
+ if (!meta.properties[key]) {
60
+ props.add(key);
61
+ }
62
+ }
63
+ }
46
64
  const visited = root.visited.has(entity);
47
65
  if (!visited) {
48
66
  root.visited.add(entity);
49
67
  }
50
- for (const prop of keys) {
68
+ for (const prop of props) {
51
69
  if (!isVisible(meta, prop, options)) {
52
70
  continue;
53
71
  }
@@ -67,7 +85,7 @@ export class EntitySerializer {
67
85
  }
68
86
  const visible = typeof val !== 'undefined' && !(val === null && options.skipNull);
69
87
  if (visible) {
70
- ret[this.propertyName(meta, prop, wrapped.__platform)] = val;
88
+ ret[this.propertyName(meta, prop)] = val;
71
89
  }
72
90
  }
73
91
  if (contextCreated) {
@@ -81,26 +99,26 @@ export class EntitySerializer {
81
99
  if (prop.getterName != null) {
82
100
  const visible = entity[prop.getterName] instanceof Function && isVisible(meta, prop.name, options);
83
101
  if (visible) {
84
- ret[this.propertyName(meta, prop.name, wrapped.__platform)] = this.processProperty(prop.getterName, entity, options);
102
+ ret[this.propertyName(meta, prop.name)] = this.processProperty(prop.getterName, entity, options);
85
103
  }
86
104
  }
87
105
  else {
88
106
  // decorated getters
89
107
  const visible = typeof entity[prop.name] !== 'undefined' && isVisible(meta, prop.name, options);
90
108
  if (visible) {
91
- ret[this.propertyName(meta, prop.name, wrapped.__platform)] = this.processProperty(prop.name, entity, options);
109
+ ret[this.propertyName(meta, prop.name)] = this.processProperty(prop.name, entity, options);
92
110
  }
93
111
  }
94
112
  }
95
113
  return ret;
96
114
  }
97
- static propertyName(meta, prop, platform) {
98
- /* v8 ignore next 3 */
115
+ static propertyName(meta, prop) {
116
+ /* v8 ignore next */
99
117
  if (meta.properties[prop]?.serializedName) {
100
118
  return meta.properties[prop].serializedName;
101
119
  }
102
- if (meta.properties[prop]?.primary && platform) {
103
- return platform.getSerializedPrimaryKeyField(prop);
120
+ if (meta.properties[prop]?.primary && meta.serializedPrimaryKey) {
121
+ return meta.serializedPrimaryKey;
104
122
  }
105
123
  return prop;
106
124
  }
@@ -119,7 +137,7 @@ export class EntitySerializer {
119
137
  }
120
138
  return returnValue;
121
139
  }
122
- /* v8 ignore next 3 */
140
+ /* v8 ignore next */
123
141
  if (!options.ignoreSerializers && serializer) {
124
142
  return serializer(value);
125
143
  }
@@ -132,7 +150,7 @@ export class EntitySerializer {
132
150
  if (Utils.isScalarReference(value)) {
133
151
  return value.unwrap();
134
152
  }
135
- /* v8 ignore next 9 */
153
+ /* v8 ignore next */
136
154
  if (property?.kind === ReferenceKind.EMBEDDED) {
137
155
  if (Array.isArray(value)) {
138
156
  return value.map(item => helper(item).toJSON());
@@ -6,7 +6,7 @@ import { isRaw } from '../utils/RawQueryFragment.js';
6
6
  function isVisible(meta, propName, ignoreFields = []) {
7
7
  const prop = meta.properties[propName];
8
8
  const visible = prop && !prop.hidden;
9
- const prefixed = prop && !prop.primary && propName.startsWith('_'); // ignore prefixed properties, if it's not a PK
9
+ const prefixed = prop && !prop.primary && !prop.accessor && propName.startsWith('_'); // ignore prefixed properties, if it's not a PK
10
10
  return visible && !prefixed && !ignoreFields.includes(propName);
11
11
  }
12
12
  export class EntityTransformer {
@@ -27,22 +27,32 @@ export class EntityTransformer {
27
27
  const root = wrapped.__serializationContext.root;
28
28
  const meta = wrapped.__meta;
29
29
  const ret = {};
30
- const keys = new Set();
30
+ const props = new Set();
31
31
  if (meta.serializedPrimaryKey && !meta.compositePK) {
32
- keys.add(meta.serializedPrimaryKey);
32
+ props.add(meta.serializedPrimaryKey);
33
33
  }
34
34
  else {
35
- meta.primaryKeys.forEach(pk => keys.add(pk));
35
+ meta.primaryKeys.forEach(pk => props.add(pk));
36
36
  }
37
37
  if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
38
- Utils.keys(entity).forEach(prop => keys.add(prop));
38
+ const entityKeys = new Set(Object.keys(entity));
39
+ for (const prop of meta.props) {
40
+ if (entityKeys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
41
+ props.add(prop.name);
42
+ }
43
+ }
44
+ for (const key of entityKeys) {
45
+ if (!meta.properties[key]) {
46
+ props.add(key);
47
+ }
48
+ }
39
49
  }
40
50
  const visited = root.visited.has(entity);
41
51
  const includePrimaryKeys = wrapped.__config.get('serialization').includePrimaryKeys;
42
52
  if (!visited) {
43
53
  root.visited.add(entity);
44
54
  }
45
- for (const prop of keys) {
55
+ for (const prop of props) {
46
56
  const visible = raw ? meta.properties[prop] : isVisible(meta, prop, ignoreFields);
47
57
  if (!visible) {
48
58
  continue;
@@ -67,7 +77,7 @@ export class EntityTransformer {
67
77
  if (typeof val === 'undefined') {
68
78
  continue;
69
79
  }
70
- ret[this.propertyName(meta, prop, wrapped.__platform, raw)] = val;
80
+ ret[this.propertyName(meta, prop, raw)] = val;
71
81
  }
72
82
  if (!wrapped.isInitialized() && wrapped.hasPrimaryKey()) {
73
83
  return ret;
@@ -78,7 +88,7 @@ export class EntityTransformer {
78
88
  const visible = !prop.hidden && entity[prop.getterName] instanceof Function;
79
89
  const populated = root.isMarkedAsPopulated(meta.className, prop.name);
80
90
  if (visible) {
81
- ret[this.propertyName(meta, prop.name, wrapped.__platform, raw)] = this.processProperty(prop.getterName, entity, raw, populated);
91
+ ret[this.propertyName(meta, prop.name, raw)] = this.processProperty(prop.getterName, entity, raw, populated);
82
92
  }
83
93
  }
84
94
  else {
@@ -86,7 +96,7 @@ export class EntityTransformer {
86
96
  const visible = !prop.hidden && typeof entity[prop.name] !== 'undefined';
87
97
  const populated = root.isMarkedAsPopulated(meta.className, prop.name);
88
98
  if (visible) {
89
- ret[this.propertyName(meta, prop.name, wrapped.__platform, raw)] = this.processProperty(prop.name, entity, raw, populated);
99
+ ret[this.propertyName(meta, prop.name, raw)] = this.processProperty(prop.name, entity, raw, populated);
90
100
  }
91
101
  }
92
102
  }
@@ -95,15 +105,15 @@ export class EntityTransformer {
95
105
  }
96
106
  return ret;
97
107
  }
98
- static propertyName(meta, prop, platform, raw) {
108
+ static propertyName(meta, prop, raw) {
99
109
  if (raw) {
100
110
  return prop;
101
111
  }
102
112
  if (meta.properties[prop].serializedName) {
103
113
  return meta.properties[prop].serializedName;
104
114
  }
105
- if (meta.properties[prop].primary && platform) {
106
- return platform.getSerializedPrimaryKeyField(prop);
115
+ if (meta.properties[prop].primary && meta.serializedPrimaryKey) {
116
+ return meta.serializedPrimaryKey;
107
117
  }
108
118
  return prop;
109
119
  }
@@ -36,8 +36,8 @@ export class SerializationContext {
36
36
  }
37
37
  leave(entityName, prop) {
38
38
  const last = this.path.pop();
39
- /* v8 ignore next 3 */
40
- if (!last || last[0] !== entityName || last[1] !== prop) {
39
+ /* v8 ignore next */
40
+ if (last?.[0] !== entityName || last[1] !== prop) {
41
41
  throw new Error(`Trying to leave wrong property: ${entityName}.${prop} instead of ${last?.join('.')}`);
42
42
  }
43
43
  }
@@ -73,18 +73,21 @@ export class SerializationContext {
73
73
  }
74
74
  }
75
75
  isMarkedAsPopulated(entityName, prop) {
76
- let populate = this.populate;
76
+ let populate = this.populate ?? [];
77
77
  for (const segment of this.path) {
78
- if (!populate) {
79
- return false;
80
- }
81
- const exists = populate.find(p => p.field === segment[1]);
82
- if (exists) {
83
- // we need to check for cycles here too, as we could fall into endless loops for bidirectional relations
84
- if (exists.all) {
85
- return !this.path.find(([cls, item]) => entityName === cls && prop === item);
78
+ const hints = populate.filter(p => p.field === segment[1]);
79
+ if (hints.length > 0) {
80
+ const childHints = [];
81
+ for (const hint of hints) {
82
+ // we need to check for cycles here too, as we could fall into endless loops for bidirectional relations
83
+ if (hint.all) {
84
+ return !this.path.find(([cls, item]) => entityName === cls && prop === item);
85
+ }
86
+ if (hint.children) {
87
+ childHints.push(...hint.children);
88
+ }
86
89
  }
87
- populate = exists.children;
90
+ populate = childHints;
88
91
  }
89
92
  }
90
93
  return !!populate?.some(p => p.field === prop);
@@ -95,7 +98,7 @@ export class SerializationContext {
95
98
  }
96
99
  let fields = [...this.fields];
97
100
  for (const segment of this.path) {
98
- /* v8 ignore next 3 */
101
+ /* v8 ignore next */
99
102
  if (fields.length === 0) {
100
103
  return true;
101
104
  }
@@ -1,4 +1,4 @@
1
- import { Type, type TransformContext } from './Type.js';
1
+ import { type TransformContext, Type } from './Type.js';
2
2
  import type { EntityProperty } from '../typings.js';
3
3
  import type { Platform } from '../platforms/Platform.js';
4
4
  export declare class ArrayType<T = string> extends Type<T[] | null, string | null> {
@@ -1,5 +1,4 @@
1
1
  import { Type } from './Type.js';
2
- import { Utils } from '../utils/Utils.js';
3
2
  import { ValidationError } from '../errors.js';
4
3
  export class ArrayType extends Type {
5
4
  toJsValue;
@@ -16,7 +15,7 @@ export class ArrayType extends Type {
16
15
  if (Array.isArray(value)) {
17
16
  return platform.marshallArray(value.map(i => this.toDbValue(i)));
18
17
  }
19
- /* v8 ignore next 3 */
18
+ /* v8 ignore next */
20
19
  if (context?.fromQuery) {
21
20
  return value;
22
21
  }
@@ -26,7 +25,7 @@ export class ArrayType extends Type {
26
25
  if (value == null) {
27
26
  return value;
28
27
  }
29
- if (Utils.isString(value)) {
28
+ if (typeof value === 'string') {
30
29
  value = platform.unmarshallArray(value);
31
30
  }
32
31
  return value.map(i => this.toJsValue(i));
@@ -5,13 +5,15 @@ import type { EntityProperty } from '../typings.js';
5
5
  * This type will automatically convert string values returned from the database to native JS bigints (default)
6
6
  * or numbers (safe only for values up to `Number.MAX_SAFE_INTEGER`), or strings, depending on the `mode`.
7
7
  */
8
- export declare class BigIntType extends Type<string | bigint | number | null | undefined, string | null | undefined> {
9
- mode?: "bigint" | "number" | "string" | undefined;
10
- constructor(mode?: "bigint" | "number" | "string" | undefined);
11
- convertToDatabaseValue(value: string | bigint | null | undefined): string | null | undefined;
12
- convertToJSValue(value: string | bigint | null | undefined): bigint | number | string | null | undefined;
13
- toJSON(value: string | bigint | null | undefined): string | bigint | null | undefined;
8
+ export declare class BigIntType<Mode extends 'bigint' | 'number' | 'string' = 'bigint'> extends Type<JSTypeByMode<Mode> | null | undefined, string | null | undefined> {
9
+ mode?: Mode | undefined;
10
+ constructor(mode?: Mode | undefined);
11
+ convertToDatabaseValue(value: JSTypeByMode<Mode> | null | undefined): string | null | undefined;
12
+ convertToJSValue(value: string | bigint | null | undefined): JSTypeByMode<Mode> | null | undefined;
13
+ toJSON(value: JSTypeByMode<Mode> | null | undefined): JSTypeByMode<Mode> | null | undefined;
14
14
  getColumnType(prop: EntityProperty, platform: Platform): string;
15
15
  compareAsType(): string;
16
16
  compareValues(a: string, b: string): boolean;
17
17
  }
18
+ type JSTypeByMode<Mode extends 'bigint' | 'number' | 'string'> = Mode extends 'bigint' ? bigint : Mode extends 'number' ? number : string;
19
+ export {};
@@ -16,7 +16,7 @@ export class BigIntType extends Type {
16
16
  return '' + value;
17
17
  }
18
18
  convertToJSValue(value) {
19
- /* v8 ignore next 3 */
19
+ /* v8 ignore next */
20
20
  if (value == null) {
21
21
  return value;
22
22
  }
@@ -4,6 +4,5 @@ import type { EntityProperty } from '../typings.js';
4
4
  export declare class BlobType extends Uint8ArrayType {
5
5
  convertToJSValue(value: Buffer): Buffer | null;
6
6
  compareAsType(): string;
7
- ensureComparable(): boolean;
8
7
  getColumnType(prop: EntityProperty, platform: Platform): string;
9
8
  }
package/types/BlobType.js CHANGED
@@ -12,9 +12,6 @@ export class BlobType extends Uint8ArrayType {
12
12
  compareAsType() {
13
13
  return 'Buffer';
14
14
  }
15
- ensureComparable() {
16
- return false;
17
- }
18
15
  getColumnType(prop, platform) {
19
16
  return platform.getBlobDeclarationSQL();
20
17
  }
@@ -1,8 +1,9 @@
1
1
  import { Type } from './Type.js';
2
2
  import type { Platform } from '../platforms/Platform.js';
3
3
  import type { EntityProperty } from '../typings.js';
4
- export declare class BooleanType extends Type<number | null | undefined, number | null | undefined> {
4
+ export declare class BooleanType extends Type<boolean | null | undefined, boolean | null | undefined> {
5
5
  getColumnType(prop: EntityProperty, platform: Platform): string;
6
6
  compareAsType(): string;
7
+ convertToJSValue(value: boolean | null | undefined): boolean | null | undefined;
7
8
  ensureComparable(): boolean;
8
9
  }
@@ -6,6 +6,9 @@ export class BooleanType extends Type {
6
6
  compareAsType() {
7
7
  return 'boolean';
8
8
  }
9
+ convertToJSValue(value) {
10
+ return Boolean(value);
11
+ }
9
12
  ensureComparable() {
10
13
  return false;
11
14
  }
@@ -4,12 +4,14 @@ import type { EntityProperty } from '../typings.js';
4
4
  /**
5
5
  * Type that maps an SQL DECIMAL to a JS string or number.
6
6
  */
7
- export declare class DecimalType extends Type<string | number, string> {
8
- mode?: "number" | "string" | undefined;
9
- constructor(mode?: "number" | "string" | undefined);
10
- convertToJSValue(value: string): number | string;
7
+ export declare class DecimalType<Mode extends 'number' | 'string' = 'string'> extends Type<JSTypeByMode<Mode>, string> {
8
+ mode?: Mode | undefined;
9
+ constructor(mode?: Mode | undefined);
10
+ convertToJSValue(value: string): JSTypeByMode<Mode>;
11
11
  compareValues(a: string, b: string): boolean;
12
12
  private format;
13
13
  getColumnType(prop: EntityProperty, platform: Platform): string;
14
14
  compareAsType(): string;
15
15
  }
16
+ type JSTypeByMode<Mode extends 'number' | 'string'> = Mode extends 'number' ? number : string;
17
+ export {};
@@ -8,18 +8,18 @@ export class DecimalType extends Type {
8
8
  super();
9
9
  this.mode = mode;
10
10
  }
11
- /* v8 ignore next 7 */
11
+ /* v8 ignore next */
12
12
  convertToJSValue(value) {
13
13
  if ((this.mode ?? this.prop?.runtimeType) === 'number') {
14
14
  return +value;
15
15
  }
16
- return value;
16
+ return String(value);
17
17
  }
18
18
  compareValues(a, b) {
19
19
  return this.format(a) === this.format(b);
20
20
  }
21
21
  format(val) {
22
- /* v8 ignore next 3 */
22
+ /* v8 ignore next */
23
23
  if (this.prop?.scale == null) {
24
24
  return +val;
25
25
  }
@@ -3,12 +3,12 @@ import { Type } from './Type.js';
3
3
  * Type that maps an SQL DOUBLE to a JS string or number.
4
4
  */
5
5
  export class DoubleType extends Type {
6
- /* v8 ignore next 7 */
6
+ /* v8 ignore next */
7
7
  convertToJSValue(value) {
8
8
  if (this.prop?.runtimeType === 'number') {
9
9
  return +value;
10
10
  }
11
- return value;
11
+ return String(value);
12
12
  }
13
13
  getColumnType(prop, platform) {
14
14
  return platform.getDoubleDeclarationSQL();
@@ -1,4 +1,3 @@
1
- import { inspect } from 'node:util';
2
1
  import { ArrayType } from './ArrayType.js';
3
2
  import { ValidationError } from '../errors.js';
4
3
  function mapHydrator(items, hydrate) {
@@ -19,7 +18,7 @@ export class EnumArrayType extends ArrayType {
19
18
  if (Array.isArray(value) && Array.isArray(this.items)) {
20
19
  const invalid = value.filter(v => !this.items.includes(v));
21
20
  if (invalid.length > 0) {
22
- throw new ValidationError(`Invalid enum array items provided in ${this.owner}: ${inspect(invalid)}`);
21
+ throw ValidationError.invalidEnumArrayItems(this.owner, invalid);
23
22
  }
24
23
  }
25
24
  return super.convertToDatabaseValue(value, platform, context);