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

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 (214) hide show
  1. package/EntityManager.d.ts +114 -63
  2. package/EntityManager.js +385 -310
  3. package/MikroORM.d.ts +44 -35
  4. package/MikroORM.js +109 -143
  5. package/README.md +3 -2
  6. package/cache/FileCacheAdapter.d.ts +1 -1
  7. package/cache/FileCacheAdapter.js +17 -8
  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 +16 -7
  13. package/connections/Connection.js +23 -14
  14. package/drivers/DatabaseDriver.d.ts +25 -16
  15. package/drivers/DatabaseDriver.js +119 -36
  16. package/drivers/IDatabaseDriver.d.ts +125 -23
  17. package/entity/BaseEntity.d.ts +63 -4
  18. package/entity/BaseEntity.js +0 -3
  19. package/entity/Collection.d.ts +102 -31
  20. package/entity/Collection.js +446 -108
  21. package/entity/EntityAssigner.d.ts +1 -1
  22. package/entity/EntityAssigner.js +26 -18
  23. package/entity/EntityFactory.d.ts +13 -1
  24. package/entity/EntityFactory.js +106 -60
  25. package/entity/EntityHelper.d.ts +2 -2
  26. package/entity/EntityHelper.js +65 -20
  27. package/entity/EntityLoader.d.ts +13 -11
  28. package/entity/EntityLoader.js +257 -107
  29. package/entity/EntityRepository.d.ts +28 -8
  30. package/entity/EntityRepository.js +8 -2
  31. package/entity/PolymorphicRef.d.ts +12 -0
  32. package/entity/PolymorphicRef.js +18 -0
  33. package/entity/Reference.d.ts +9 -12
  34. package/entity/Reference.js +34 -9
  35. package/entity/WrappedEntity.d.ts +3 -8
  36. package/entity/WrappedEntity.js +3 -8
  37. package/entity/defineEntity.d.ts +753 -0
  38. package/entity/defineEntity.js +537 -0
  39. package/entity/index.d.ts +4 -2
  40. package/entity/index.js +4 -2
  41. package/entity/utils.d.ts +13 -1
  42. package/entity/utils.js +49 -4
  43. package/entity/validators.d.ts +11 -0
  44. package/entity/validators.js +65 -0
  45. package/enums.d.ts +23 -8
  46. package/enums.js +15 -1
  47. package/errors.d.ts +25 -9
  48. package/errors.js +67 -21
  49. package/events/EventManager.d.ts +2 -1
  50. package/events/EventManager.js +19 -11
  51. package/events/EventSubscriber.d.ts +3 -1
  52. package/hydration/Hydrator.js +1 -2
  53. package/hydration/ObjectHydrator.d.ts +4 -4
  54. package/hydration/ObjectHydrator.js +89 -36
  55. package/index.d.ts +2 -2
  56. package/index.js +1 -2
  57. package/logging/DefaultLogger.d.ts +1 -1
  58. package/logging/DefaultLogger.js +1 -0
  59. package/logging/SimpleLogger.d.ts +1 -1
  60. package/logging/colors.d.ts +1 -1
  61. package/logging/colors.js +7 -6
  62. package/logging/index.d.ts +1 -0
  63. package/logging/index.js +1 -0
  64. package/logging/inspect.d.ts +2 -0
  65. package/logging/inspect.js +11 -0
  66. package/metadata/EntitySchema.d.ts +53 -27
  67. package/metadata/EntitySchema.js +125 -52
  68. package/metadata/MetadataDiscovery.d.ts +64 -10
  69. package/metadata/MetadataDiscovery.js +823 -344
  70. package/metadata/MetadataProvider.d.ts +11 -2
  71. package/metadata/MetadataProvider.js +66 -2
  72. package/metadata/MetadataStorage.d.ts +13 -11
  73. package/metadata/MetadataStorage.js +71 -38
  74. package/metadata/MetadataValidator.d.ts +32 -9
  75. package/metadata/MetadataValidator.js +198 -42
  76. package/metadata/discover-entities.d.ts +5 -0
  77. package/metadata/discover-entities.js +40 -0
  78. package/metadata/index.d.ts +1 -1
  79. package/metadata/index.js +1 -1
  80. package/metadata/types.d.ts +577 -0
  81. package/metadata/types.js +1 -0
  82. package/naming-strategy/AbstractNamingStrategy.d.ts +16 -4
  83. package/naming-strategy/AbstractNamingStrategy.js +20 -2
  84. package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
  85. package/naming-strategy/EntityCaseNamingStrategy.js +6 -5
  86. package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
  87. package/naming-strategy/MongoNamingStrategy.js +6 -6
  88. package/naming-strategy/NamingStrategy.d.ts +28 -4
  89. package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
  90. package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
  91. package/not-supported.d.ts +2 -0
  92. package/not-supported.js +4 -0
  93. package/package.json +22 -11
  94. package/platforms/ExceptionConverter.js +1 -1
  95. package/platforms/Platform.d.ts +14 -16
  96. package/platforms/Platform.js +24 -44
  97. package/serialization/EntitySerializer.d.ts +8 -3
  98. package/serialization/EntitySerializer.js +47 -27
  99. package/serialization/EntityTransformer.js +33 -21
  100. package/serialization/SerializationContext.d.ts +6 -6
  101. package/serialization/SerializationContext.js +16 -13
  102. package/types/ArrayType.d.ts +1 -1
  103. package/types/ArrayType.js +2 -3
  104. package/types/BigIntType.d.ts +9 -6
  105. package/types/BigIntType.js +4 -1
  106. package/types/BlobType.d.ts +0 -1
  107. package/types/BlobType.js +0 -3
  108. package/types/BooleanType.d.ts +2 -1
  109. package/types/BooleanType.js +3 -0
  110. package/types/DecimalType.d.ts +6 -4
  111. package/types/DecimalType.js +3 -3
  112. package/types/DoubleType.js +2 -2
  113. package/types/EnumArrayType.js +1 -2
  114. package/types/JsonType.d.ts +1 -1
  115. package/types/JsonType.js +7 -2
  116. package/types/TinyIntType.js +1 -1
  117. package/types/Type.d.ts +2 -4
  118. package/types/Type.js +3 -3
  119. package/types/Uint8ArrayType.d.ts +0 -1
  120. package/types/Uint8ArrayType.js +1 -4
  121. package/types/index.d.ts +1 -1
  122. package/typings.d.ts +469 -175
  123. package/typings.js +120 -45
  124. package/unit-of-work/ChangeSet.d.ts +4 -6
  125. package/unit-of-work/ChangeSet.js +4 -5
  126. package/unit-of-work/ChangeSetComputer.d.ts +3 -8
  127. package/unit-of-work/ChangeSetComputer.js +44 -21
  128. package/unit-of-work/ChangeSetPersister.d.ts +15 -12
  129. package/unit-of-work/ChangeSetPersister.js +113 -45
  130. package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
  131. package/unit-of-work/CommitOrderCalculator.js +13 -13
  132. package/unit-of-work/IdentityMap.d.ts +12 -0
  133. package/unit-of-work/IdentityMap.js +39 -1
  134. package/unit-of-work/UnitOfWork.d.ts +28 -3
  135. package/unit-of-work/UnitOfWork.js +315 -110
  136. package/utils/AbstractMigrator.d.ts +101 -0
  137. package/utils/AbstractMigrator.js +305 -0
  138. package/utils/AbstractSchemaGenerator.d.ts +5 -5
  139. package/utils/AbstractSchemaGenerator.js +32 -18
  140. package/utils/AsyncContext.d.ts +6 -0
  141. package/utils/AsyncContext.js +42 -0
  142. package/utils/Configuration.d.ts +801 -207
  143. package/utils/Configuration.js +150 -191
  144. package/utils/ConfigurationLoader.d.ts +1 -54
  145. package/utils/ConfigurationLoader.js +1 -352
  146. package/utils/Cursor.d.ts +3 -6
  147. package/utils/Cursor.js +27 -11
  148. package/utils/DataloaderUtils.d.ts +15 -5
  149. package/utils/DataloaderUtils.js +65 -17
  150. package/utils/EntityComparator.d.ts +21 -10
  151. package/utils/EntityComparator.js +243 -106
  152. package/utils/QueryHelper.d.ts +24 -6
  153. package/utils/QueryHelper.js +122 -26
  154. package/utils/RawQueryFragment.d.ts +60 -32
  155. package/utils/RawQueryFragment.js +69 -66
  156. package/utils/RequestContext.js +2 -2
  157. package/utils/TransactionContext.js +2 -2
  158. package/utils/TransactionManager.d.ts +65 -0
  159. package/utils/TransactionManager.js +223 -0
  160. package/utils/Utils.d.ts +15 -122
  161. package/utils/Utils.js +108 -376
  162. package/utils/clone.js +8 -23
  163. package/utils/env-vars.d.ts +7 -0
  164. package/utils/env-vars.js +97 -0
  165. package/utils/fs-utils.d.ts +34 -0
  166. package/utils/fs-utils.js +196 -0
  167. package/utils/index.d.ts +2 -3
  168. package/utils/index.js +2 -3
  169. package/utils/upsert-utils.d.ts +9 -4
  170. package/utils/upsert-utils.js +55 -4
  171. package/decorators/Check.d.ts +0 -3
  172. package/decorators/Check.js +0 -13
  173. package/decorators/CreateRequestContext.d.ts +0 -3
  174. package/decorators/CreateRequestContext.js +0 -32
  175. package/decorators/Embeddable.d.ts +0 -8
  176. package/decorators/Embeddable.js +0 -11
  177. package/decorators/Embedded.d.ts +0 -18
  178. package/decorators/Embedded.js +0 -18
  179. package/decorators/Entity.d.ts +0 -18
  180. package/decorators/Entity.js +0 -13
  181. package/decorators/Enum.d.ts +0 -9
  182. package/decorators/Enum.js +0 -16
  183. package/decorators/Filter.d.ts +0 -2
  184. package/decorators/Filter.js +0 -8
  185. package/decorators/Formula.d.ts +0 -5
  186. package/decorators/Formula.js +0 -15
  187. package/decorators/Indexed.d.ts +0 -17
  188. package/decorators/Indexed.js +0 -20
  189. package/decorators/ManyToMany.d.ts +0 -40
  190. package/decorators/ManyToMany.js +0 -14
  191. package/decorators/ManyToOne.d.ts +0 -30
  192. package/decorators/ManyToOne.js +0 -14
  193. package/decorators/OneToMany.d.ts +0 -28
  194. package/decorators/OneToMany.js +0 -17
  195. package/decorators/OneToOne.d.ts +0 -24
  196. package/decorators/OneToOne.js +0 -7
  197. package/decorators/PrimaryKey.d.ts +0 -9
  198. package/decorators/PrimaryKey.js +0 -20
  199. package/decorators/Property.d.ts +0 -250
  200. package/decorators/Property.js +0 -32
  201. package/decorators/Transactional.d.ts +0 -13
  202. package/decorators/Transactional.js +0 -28
  203. package/decorators/hooks.d.ts +0 -16
  204. package/decorators/hooks.js +0 -47
  205. package/decorators/index.d.ts +0 -17
  206. package/decorators/index.js +0 -17
  207. package/entity/ArrayCollection.d.ts +0 -116
  208. package/entity/ArrayCollection.js +0 -395
  209. package/entity/EntityValidator.d.ts +0 -19
  210. package/entity/EntityValidator.js +0 -150
  211. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  212. package/metadata/ReflectMetadataProvider.js +0 -44
  213. package/utils/resolveContextProvider.d.ts +0 -10
  214. package/utils/resolveContextProvider.js +0 -28
@@ -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,23 +41,41 @@ 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
  }
54
- const cycle = root.visit(meta.className, prop);
72
+ const cycle = root.visit(meta.class, prop);
55
73
  if (cycle && visited) {
56
74
  continue;
57
75
  }
58
76
  const val = this.processProperty(prop, entity, options);
59
77
  if (!cycle) {
60
- root.leave(meta.className, prop);
78
+ root.leave(meta.class, prop);
61
79
  }
62
80
  if (options.skipNull && Utils.isPlainObject(val)) {
63
81
  Utils.dropUndefinedProperties(val, null);
@@ -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());
@@ -141,12 +159,20 @@ export class EntitySerializer {
141
159
  return helper(value).toJSON();
142
160
  }
143
161
  }
144
- const customType = property?.customType;
145
- if (customType) {
146
- return customType.toJSON(value, wrapped.__platform);
162
+ if (property.customType) {
163
+ return this.processCustomType(value, property, wrapped.__platform, options.convertCustomTypes);
147
164
  }
148
165
  return wrapped.__platform.normalizePrimaryKey(value);
149
166
  }
167
+ static processCustomType(value, prop, platform, convertCustomTypes) {
168
+ if (!prop.customType) {
169
+ return value;
170
+ }
171
+ if (convertCustomTypes) {
172
+ return prop.customType.convertToDatabaseValue(value, platform, { mode: 'serialization' });
173
+ }
174
+ return prop.customType.toJSON(value, platform);
175
+ }
150
176
  static extractChildOptions(options, prop) {
151
177
  return {
152
178
  ...options,
@@ -165,10 +191,7 @@ export class EntitySerializer {
165
191
  if (expand) {
166
192
  return this.serialize(child, childOptions);
167
193
  }
168
- let pk = wrapped.getPrimaryKey();
169
- if (prop.customType) {
170
- pk = prop.customType.toJSON(pk, wrapped.__platform);
171
- }
194
+ const pk = this.processCustomType(wrapped.getPrimaryKey(), prop, wrapped.__platform, options.convertCustomTypes);
172
195
  if (options.forceObject || wrapped.__config.get('serialization').forceObject) {
173
196
  return Utils.primaryKeyToObject(meta, pk, visible);
174
197
  }
@@ -192,10 +215,7 @@ export class EntitySerializer {
192
215
  if (populated || !wrapped.__managed) {
193
216
  return this.serialize(item, this.extractChildOptions(options, prop.name));
194
217
  }
195
- let pk = wrapped.getPrimaryKey();
196
- if (prop.customType) {
197
- pk = prop.customType.toJSON(pk, wrapped.__platform);
198
- }
218
+ const pk = this.processCustomType(wrapped.getPrimaryKey(), prop, wrapped.__platform, options.convertCustomTypes);
199
219
  if (options.forceObject || wrapped.__config.get('serialization').forceObject) {
200
220
  return Utils.primaryKeyToObject(wrapped.__meta, pk);
201
221
  }
@@ -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,39 +27,51 @@ 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;
49
59
  }
50
- const populated = root.isMarkedAsPopulated(meta.className, prop);
51
- const partiallyLoaded = root.isPartiallyLoaded(meta.className, prop);
52
- const isPrimary = includePrimaryKeys && meta.properties[prop].primary;
53
- if (!partiallyLoaded && !populated && !isPrimary) {
54
- continue;
60
+ const populated = root.isMarkedAsPopulated(meta.class, prop);
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
+ }
55
67
  }
56
- const cycle = root.visit(meta.className, prop);
68
+ const cycle = root.visit(meta.class, prop);
57
69
  if (cycle && visited) {
58
70
  continue;
59
71
  }
60
72
  const val = EntityTransformer.processProperty(prop, entity, raw, populated);
61
73
  if (!cycle) {
62
- root.leave(meta.className, prop);
74
+ root.leave(meta.class, prop);
63
75
  }
64
76
  if (isRaw(val)) {
65
77
  throw new Error(`Trying to serialize raw SQL fragment: '${val.sql}'`);
@@ -67,7 +79,7 @@ export class EntityTransformer {
67
79
  if (typeof val === 'undefined') {
68
80
  continue;
69
81
  }
70
- ret[this.propertyName(meta, prop, wrapped.__platform, raw)] = val;
82
+ ret[this.propertyName(meta, prop, raw)] = val;
71
83
  }
72
84
  if (!wrapped.isInitialized() && wrapped.hasPrimaryKey()) {
73
85
  return ret;
@@ -76,17 +88,17 @@ export class EntityTransformer {
76
88
  // decorated get methods
77
89
  if (prop.getterName != null) {
78
90
  const visible = !prop.hidden && entity[prop.getterName] instanceof Function;
79
- const populated = root.isMarkedAsPopulated(meta.className, prop.name);
91
+ const populated = root.isMarkedAsPopulated(meta.class, prop.name);
80
92
  if (visible) {
81
- ret[this.propertyName(meta, prop.name, wrapped.__platform, raw)] = this.processProperty(prop.getterName, entity, raw, populated);
93
+ ret[this.propertyName(meta, prop.name, raw)] = this.processProperty(prop.getterName, entity, raw, populated);
82
94
  }
83
95
  }
84
96
  else {
85
97
  // decorated getters
86
98
  const visible = !prop.hidden && typeof entity[prop.name] !== 'undefined';
87
- const populated = root.isMarkedAsPopulated(meta.className, prop.name);
99
+ const populated = root.isMarkedAsPopulated(meta.class, prop.name);
88
100
  if (visible) {
89
- ret[this.propertyName(meta, prop.name, wrapped.__platform, raw)] = this.processProperty(prop.name, entity, raw, populated);
101
+ ret[this.propertyName(meta, prop.name, raw)] = this.processProperty(prop.name, entity, raw, populated);
90
102
  }
91
103
  }
92
104
  }
@@ -95,15 +107,15 @@ export class EntityTransformer {
95
107
  }
96
108
  return ret;
97
109
  }
98
- static propertyName(meta, prop, platform, raw) {
110
+ static propertyName(meta, prop, raw) {
99
111
  if (raw) {
100
112
  return prop;
101
113
  }
102
114
  if (meta.properties[prop].serializedName) {
103
115
  return meta.properties[prop].serializedName;
104
116
  }
105
- if (meta.properties[prop].primary && platform) {
106
- return platform.getSerializedPrimaryKeyField(prop);
117
+ if (meta.properties[prop].primary && meta.serializedPrimaryKey) {
118
+ return meta.serializedPrimaryKey;
107
119
  }
108
120
  return prop;
109
121
  }
@@ -1,4 +1,4 @@
1
- import type { AnyEntity, EntityMetadata, PopulateOptions } from '../typings.js';
1
+ import type { AnyEntity, EntityMetadata, EntityName, PopulateOptions } from '../typings.js';
2
2
  import type { Configuration } from '../utils/Configuration.js';
3
3
  /**
4
4
  * Helper that allows to keep track of where we are currently at when serializing complex entity graph with cycles.
@@ -10,21 +10,21 @@ export declare class SerializationContext<T extends object> {
10
10
  private readonly populate;
11
11
  private readonly fields?;
12
12
  private readonly exclude?;
13
- readonly path: [string, string][];
13
+ readonly path: [EntityName, string][];
14
14
  readonly visited: Set<Partial<any>>;
15
15
  private entities;
16
16
  constructor(config: Configuration, populate?: PopulateOptions<T>[], fields?: Set<string> | undefined, exclude?: string[] | undefined);
17
17
  /**
18
18
  * Returns true when there is a cycle detected.
19
19
  */
20
- visit(entityName: string, prop: string): boolean;
21
- leave<U>(entityName: string, prop: string): void;
20
+ visit(entityName: EntityName, prop: string): boolean;
21
+ leave(entityName: EntityName, prop: string): void;
22
22
  close(): void;
23
23
  /**
24
24
  * When initializing new context, we need to propagate it to the whole entity graph recursively.
25
25
  */
26
26
  static propagate(root: SerializationContext<any>, entity: AnyEntity, isVisible: (meta: EntityMetadata, prop: string) => boolean): void;
27
- isMarkedAsPopulated(entityName: string, prop: string): boolean;
28
- isPartiallyLoaded(entityName: string, prop: string): boolean;
27
+ isMarkedAsPopulated(entityName: EntityName, prop: string): boolean;
28
+ isPartiallyLoaded(entityName: EntityName, prop: string): boolean;
29
29
  private register;
30
30
  }
@@ -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,12 +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
+ compareValues(a: string, b: string): boolean;
16
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
  }
@@ -42,4 +42,7 @@ export class BigIntType extends Type {
42
42
  compareAsType() {
43
43
  return this.mode ?? 'bigint';
44
44
  }
45
+ compareValues(a, b) {
46
+ return String(a) === String(b);
47
+ }
45
48
  }
@@ -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);
@@ -5,7 +5,7 @@ export declare class JsonType extends Type<unknown, string | null> {
5
5
  convertToDatabaseValue(value: unknown, platform: Platform, context?: TransformContext): string | null;
6
6
  convertToJSValueSQL(key: string, platform: Platform): string;
7
7
  convertToDatabaseValueSQL(key: string, platform: Platform): string;
8
- convertToJSValue(value: string | unknown, platform: Platform): unknown;
8
+ convertToJSValue(value: string | unknown, platform: Platform, context?: TransformContext): unknown;
9
9
  getColumnType(prop: EntityProperty, platform: Platform): string;
10
10
  ensureComparable<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T>): boolean;
11
11
  compareAsType(): string;
package/types/JsonType.js CHANGED
@@ -12,8 +12,13 @@ export class JsonType extends Type {
12
12
  convertToDatabaseValueSQL(key, platform) {
13
13
  return key + platform.castColumn(this.prop);
14
14
  }
15
- convertToJSValue(value, platform) {
16
- return platform.convertJsonToJSValue(value, this.prop);
15
+ convertToJSValue(value, platform, context) {
16
+ const isJsonColumn = ['json', 'jsonb', platform.getJsonDeclarationSQL()].includes(this.prop.columnTypes[0]);
17
+ const isObjectEmbedded = this.prop.embedded && this.prop.object;
18
+ if ((platform.convertsJsonAutomatically() || isObjectEmbedded) && isJsonColumn && !context?.force) {
19
+ return value;
20
+ }
21
+ return platform.convertJsonToJSValue(value, context);
17
22
  }
18
23
  getColumnType(prop, platform) {
19
24
  return platform.getJsonDeclarationSQL();
@@ -6,7 +6,7 @@ export class TinyIntType extends Type {
6
6
  compareAsType() {
7
7
  return 'number';
8
8
  }
9
- /* v8 ignore next 3 */
9
+ /* v8 ignore next */
10
10
  ensureComparable() {
11
11
  return false;
12
12
  }
package/types/Type.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { inspect } from 'node:util';
2
1
  import type { Platform } from '../platforms/Platform.js';
3
2
  import type { Constructor, EntityMetadata, EntityProperty } from '../typings.js';
4
3
  export interface TransformContext {
5
4
  fromQuery?: boolean;
5
+ force?: boolean;
6
6
  key?: string;
7
7
  mode?: 'hydration' | 'query' | 'query-data' | 'discovery' | 'serialization';
8
8
  }
@@ -23,7 +23,7 @@ export declare abstract class Type<JSType = string, DBType = JSType> {
23
23
  /**
24
24
  * Converts a value from its database representation to its JS representation of this type.
25
25
  */
26
- convertToJSValue(value: DBType, platform: Platform): JSType;
26
+ convertToJSValue(value: DBType, platform: Platform, context?: TransformContext): JSType;
27
27
  /**
28
28
  * Converts a value from its JS representation to its database representation of this type.
29
29
  */
@@ -78,6 +78,4 @@ export declare abstract class Type<JSType = string, DBType = JSType> {
78
78
  * Checks whether the argument is instance of `Type`.
79
79
  */
80
80
  static isMappedType(data: any): data is Type<any>;
81
- /** @ignore */
82
- [inspect.custom](depth?: number): string;
83
81
  }
package/types/Type.js CHANGED
@@ -1,4 +1,4 @@
1
- import { inspect } from 'node:util';
1
+ import { inspect } from '../logging/inspect.js';
2
2
  export class Type {
3
3
  static types = new Map();
4
4
  platform;
@@ -13,7 +13,7 @@ export class Type {
13
13
  /**
14
14
  * Converts a value from its database representation to its JS representation of this type.
15
15
  */
16
- convertToJSValue(value, platform) {
16
+ convertToJSValue(value, platform, context) {
17
17
  return value;
18
18
  }
19
19
  /**
@@ -65,7 +65,7 @@ export class Type {
65
65
  return !!data?.__mappedType;
66
66
  }
67
67
  /** @ignore */
68
- [inspect.custom](depth = 2) {
68
+ [Symbol.for('nodejs.util.inspect.custom')](depth = 2) {
69
69
  const object = { ...this };
70
70
  const hidden = ['prop', 'platform', 'meta'];
71
71
  hidden.forEach(k => delete object[k]);