@mikro-orm/core 7.0.0-dev.1 → 7.0.0-dev.100

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 (281) hide show
  1. package/EntityManager.d.ts +96 -58
  2. package/EntityManager.js +465 -395
  3. package/MikroORM.d.ts +45 -35
  4. package/MikroORM.js +109 -160
  5. package/README.md +3 -2
  6. package/cache/CacheAdapter.js +1 -2
  7. package/cache/FileCacheAdapter.d.ts +2 -2
  8. package/cache/FileCacheAdapter.js +20 -27
  9. package/cache/GeneratedCacheAdapter.d.ts +2 -3
  10. package/cache/GeneratedCacheAdapter.js +1 -7
  11. package/cache/MemoryCacheAdapter.d.ts +1 -1
  12. package/cache/MemoryCacheAdapter.js +1 -5
  13. package/cache/NullCacheAdapter.d.ts +1 -1
  14. package/cache/NullCacheAdapter.js +1 -5
  15. package/cache/index.d.ts +4 -5
  16. package/cache/index.js +4 -21
  17. package/connections/Connection.d.ts +22 -14
  18. package/connections/Connection.js +27 -23
  19. package/connections/index.d.ts +1 -1
  20. package/connections/index.js +1 -17
  21. package/drivers/DatabaseDriver.d.ts +25 -15
  22. package/drivers/DatabaseDriver.js +77 -64
  23. package/drivers/IDatabaseDriver.d.ts +40 -16
  24. package/drivers/IDatabaseDriver.js +1 -4
  25. package/drivers/index.d.ts +2 -2
  26. package/drivers/index.js +2 -18
  27. package/entity/BaseEntity.d.ts +6 -7
  28. package/entity/BaseEntity.js +16 -23
  29. package/entity/Collection.d.ts +98 -34
  30. package/entity/Collection.js +466 -131
  31. package/entity/EntityAssigner.d.ts +3 -3
  32. package/entity/EntityAssigner.js +67 -64
  33. package/entity/EntityFactory.d.ts +10 -3
  34. package/entity/EntityFactory.js +112 -91
  35. package/entity/EntityHelper.d.ts +2 -2
  36. package/entity/EntityHelper.js +66 -53
  37. package/entity/EntityIdentifier.d.ts +1 -1
  38. package/entity/EntityIdentifier.js +1 -5
  39. package/entity/EntityLoader.d.ts +8 -7
  40. package/entity/EntityLoader.js +161 -128
  41. package/entity/EntityRepository.d.ts +8 -8
  42. package/entity/EntityRepository.js +7 -11
  43. package/entity/Reference.d.ts +10 -13
  44. package/entity/Reference.js +64 -46
  45. package/entity/WrappedEntity.d.ts +12 -17
  46. package/entity/WrappedEntity.js +22 -31
  47. package/entity/defineEntity.d.ts +568 -0
  48. package/entity/defineEntity.js +529 -0
  49. package/entity/index.d.ts +14 -13
  50. package/entity/index.js +14 -29
  51. package/entity/utils.d.ts +8 -1
  52. package/entity/utils.js +22 -13
  53. package/entity/validators.d.ts +11 -0
  54. package/entity/validators.js +65 -0
  55. package/entity/wrap.d.ts +1 -1
  56. package/entity/wrap.js +2 -6
  57. package/enums.d.ts +24 -9
  58. package/enums.js +50 -41
  59. package/errors.d.ts +11 -3
  60. package/errors.js +42 -32
  61. package/events/EventManager.d.ts +5 -4
  62. package/events/EventManager.js +26 -22
  63. package/events/EventSubscriber.d.ts +8 -5
  64. package/events/EventSubscriber.js +1 -2
  65. package/events/TransactionEventBroadcaster.d.ts +3 -3
  66. package/events/TransactionEventBroadcaster.js +1 -5
  67. package/events/index.d.ts +3 -3
  68. package/events/index.js +3 -19
  69. package/exceptions.js +18 -39
  70. package/hydration/Hydrator.d.ts +5 -5
  71. package/hydration/Hydrator.js +2 -6
  72. package/hydration/ObjectHydrator.d.ts +7 -7
  73. package/hydration/ObjectHydrator.js +58 -50
  74. package/hydration/index.d.ts +2 -2
  75. package/hydration/index.js +2 -18
  76. package/index.d.ts +21 -21
  77. package/index.js +20 -46
  78. package/logging/DefaultLogger.d.ts +2 -2
  79. package/logging/DefaultLogger.js +10 -13
  80. package/logging/Logger.d.ts +1 -1
  81. package/logging/Logger.js +1 -2
  82. package/logging/SimpleLogger.d.ts +3 -3
  83. package/logging/SimpleLogger.js +2 -6
  84. package/logging/colors.js +1 -5
  85. package/logging/index.d.ts +5 -4
  86. package/logging/index.js +5 -20
  87. package/logging/inspect.d.ts +2 -0
  88. package/logging/inspect.js +16 -0
  89. package/metadata/EntitySchema.d.ts +14 -10
  90. package/metadata/EntitySchema.js +78 -64
  91. package/metadata/MetadataDiscovery.d.ts +11 -14
  92. package/metadata/MetadataDiscovery.js +278 -317
  93. package/metadata/MetadataProvider.d.ts +13 -4
  94. package/metadata/MetadataProvider.js +47 -8
  95. package/metadata/MetadataStorage.d.ts +2 -7
  96. package/metadata/MetadataStorage.js +19 -35
  97. package/metadata/MetadataValidator.d.ts +3 -10
  98. package/metadata/MetadataValidator.js +51 -64
  99. package/metadata/discover-entities.d.ts +5 -0
  100. package/metadata/discover-entities.js +40 -0
  101. package/metadata/index.d.ts +6 -6
  102. package/metadata/index.js +6 -22
  103. package/metadata/types.d.ts +480 -0
  104. package/metadata/types.js +1 -0
  105. package/naming-strategy/AbstractNamingStrategy.d.ts +7 -3
  106. package/naming-strategy/AbstractNamingStrategy.js +11 -9
  107. package/naming-strategy/EntityCaseNamingStrategy.d.ts +1 -1
  108. package/naming-strategy/EntityCaseNamingStrategy.js +2 -6
  109. package/naming-strategy/MongoNamingStrategy.d.ts +1 -1
  110. package/naming-strategy/MongoNamingStrategy.js +2 -6
  111. package/naming-strategy/NamingStrategy.d.ts +12 -2
  112. package/naming-strategy/NamingStrategy.js +1 -2
  113. package/naming-strategy/UnderscoreNamingStrategy.d.ts +1 -1
  114. package/naming-strategy/UnderscoreNamingStrategy.js +2 -6
  115. package/naming-strategy/index.d.ts +5 -5
  116. package/naming-strategy/index.js +5 -21
  117. package/not-supported.d.ts +2 -0
  118. package/not-supported.js +4 -0
  119. package/package.json +19 -20
  120. package/platforms/ExceptionConverter.d.ts +2 -2
  121. package/platforms/ExceptionConverter.js +4 -8
  122. package/platforms/Platform.d.ts +15 -22
  123. package/platforms/Platform.js +58 -88
  124. package/platforms/index.d.ts +2 -2
  125. package/platforms/index.js +2 -18
  126. package/serialization/EntitySerializer.d.ts +4 -2
  127. package/serialization/EntitySerializer.js +64 -51
  128. package/serialization/EntityTransformer.d.ts +1 -1
  129. package/serialization/EntityTransformer.js +48 -42
  130. package/serialization/SerializationContext.d.ts +2 -2
  131. package/serialization/SerializationContext.js +24 -25
  132. package/serialization/index.d.ts +3 -3
  133. package/serialization/index.js +3 -19
  134. package/types/ArrayType.d.ts +3 -3
  135. package/types/ArrayType.js +6 -11
  136. package/types/BigIntType.d.ts +12 -9
  137. package/types/BigIntType.js +6 -6
  138. package/types/BlobType.d.ts +3 -4
  139. package/types/BlobType.js +2 -11
  140. package/types/BooleanType.d.ts +5 -4
  141. package/types/BooleanType.js +5 -6
  142. package/types/CharacterType.d.ts +3 -3
  143. package/types/CharacterType.js +2 -6
  144. package/types/DateTimeType.d.ts +3 -3
  145. package/types/DateTimeType.js +2 -6
  146. package/types/DateType.d.ts +3 -3
  147. package/types/DateType.js +2 -6
  148. package/types/DecimalType.d.ts +9 -7
  149. package/types/DecimalType.js +5 -8
  150. package/types/DoubleType.d.ts +3 -3
  151. package/types/DoubleType.js +4 -7
  152. package/types/EnumArrayType.d.ts +4 -4
  153. package/types/EnumArrayType.js +4 -10
  154. package/types/EnumType.d.ts +3 -3
  155. package/types/EnumType.js +2 -6
  156. package/types/FloatType.d.ts +3 -3
  157. package/types/FloatType.js +2 -6
  158. package/types/IntegerType.d.ts +3 -3
  159. package/types/IntegerType.js +2 -6
  160. package/types/IntervalType.d.ts +3 -3
  161. package/types/IntervalType.js +2 -6
  162. package/types/JsonType.d.ts +4 -4
  163. package/types/JsonType.js +9 -8
  164. package/types/MediumIntType.d.ts +3 -3
  165. package/types/MediumIntType.js +2 -6
  166. package/types/SmallIntType.d.ts +3 -3
  167. package/types/SmallIntType.js +2 -6
  168. package/types/StringType.d.ts +3 -3
  169. package/types/StringType.js +2 -6
  170. package/types/TextType.d.ts +3 -3
  171. package/types/TextType.js +2 -6
  172. package/types/TimeType.d.ts +3 -3
  173. package/types/TimeType.js +4 -8
  174. package/types/TinyIntType.d.ts +3 -3
  175. package/types/TinyIntType.js +3 -6
  176. package/types/Type.d.ts +4 -6
  177. package/types/Type.js +6 -10
  178. package/types/Uint8ArrayType.d.ts +3 -4
  179. package/types/Uint8ArrayType.js +3 -12
  180. package/types/UnknownType.d.ts +3 -3
  181. package/types/UnknownType.js +2 -6
  182. package/types/UuidType.d.ts +3 -3
  183. package/types/UuidType.js +2 -6
  184. package/types/index.d.ts +25 -25
  185. package/types/index.js +52 -79
  186. package/typings.d.ts +134 -93
  187. package/typings.js +67 -65
  188. package/unit-of-work/ChangeSet.d.ts +1 -4
  189. package/unit-of-work/ChangeSet.js +13 -17
  190. package/unit-of-work/ChangeSetComputer.d.ts +8 -9
  191. package/unit-of-work/ChangeSetComputer.js +36 -38
  192. package/unit-of-work/ChangeSetPersister.d.ts +11 -9
  193. package/unit-of-work/ChangeSetPersister.js +100 -65
  194. package/unit-of-work/CommitOrderCalculator.d.ts +1 -1
  195. package/unit-of-work/CommitOrderCalculator.js +6 -10
  196. package/unit-of-work/IdentityMap.d.ts +1 -1
  197. package/unit-of-work/IdentityMap.js +1 -5
  198. package/unit-of-work/UnitOfWork.d.ts +16 -8
  199. package/unit-of-work/UnitOfWork.js +266 -209
  200. package/unit-of-work/index.d.ts +6 -6
  201. package/unit-of-work/index.js +6 -22
  202. package/utils/AbstractSchemaGenerator.d.ts +11 -11
  203. package/utils/AbstractSchemaGenerator.js +21 -20
  204. package/utils/Configuration.d.ts +774 -224
  205. package/utils/Configuration.js +166 -216
  206. package/utils/ConfigurationLoader.d.ts +1 -53
  207. package/utils/ConfigurationLoader.js +1 -367
  208. package/utils/Cursor.d.ts +6 -9
  209. package/utils/Cursor.js +25 -25
  210. package/utils/DataloaderUtils.d.ts +18 -8
  211. package/utils/DataloaderUtils.js +63 -21
  212. package/utils/EntityComparator.d.ts +9 -5
  213. package/utils/EntityComparator.js +155 -108
  214. package/utils/NullHighlighter.d.ts +1 -1
  215. package/utils/NullHighlighter.js +1 -5
  216. package/utils/QueryHelper.d.ts +12 -4
  217. package/utils/QueryHelper.js +110 -53
  218. package/utils/RawQueryFragment.d.ts +37 -14
  219. package/utils/RawQueryFragment.js +50 -33
  220. package/utils/RequestContext.d.ts +2 -2
  221. package/utils/RequestContext.js +3 -7
  222. package/utils/TransactionContext.d.ts +1 -1
  223. package/utils/TransactionContext.js +4 -8
  224. package/utils/TransactionManager.d.ts +65 -0
  225. package/utils/TransactionManager.js +223 -0
  226. package/utils/Utils.d.ts +16 -100
  227. package/utils/Utils.js +114 -332
  228. package/utils/clone.js +7 -11
  229. package/utils/env-vars.d.ts +3 -0
  230. package/utils/env-vars.js +87 -0
  231. package/utils/fs-utils.d.ts +12 -0
  232. package/utils/fs-utils.js +97 -0
  233. package/utils/index.d.ts +14 -13
  234. package/utils/index.js +14 -29
  235. package/utils/upsert-utils.d.ts +8 -3
  236. package/utils/upsert-utils.js +57 -10
  237. package/decorators/Check.d.ts +0 -3
  238. package/decorators/Check.js +0 -16
  239. package/decorators/CreateRequestContext.d.ts +0 -3
  240. package/decorators/CreateRequestContext.js +0 -33
  241. package/decorators/Embeddable.d.ts +0 -8
  242. package/decorators/Embeddable.js +0 -14
  243. package/decorators/Embedded.d.ts +0 -18
  244. package/decorators/Embedded.js +0 -20
  245. package/decorators/Entity.d.ts +0 -18
  246. package/decorators/Entity.js +0 -16
  247. package/decorators/Enum.d.ts +0 -9
  248. package/decorators/Enum.js +0 -19
  249. package/decorators/Filter.d.ts +0 -2
  250. package/decorators/Filter.js +0 -11
  251. package/decorators/Formula.d.ts +0 -5
  252. package/decorators/Formula.js +0 -18
  253. package/decorators/Indexed.d.ts +0 -17
  254. package/decorators/Indexed.js +0 -24
  255. package/decorators/ManyToMany.d.ts +0 -40
  256. package/decorators/ManyToMany.js +0 -16
  257. package/decorators/ManyToOne.d.ts +0 -30
  258. package/decorators/ManyToOne.js +0 -16
  259. package/decorators/OneToMany.d.ts +0 -28
  260. package/decorators/OneToMany.js +0 -20
  261. package/decorators/OneToOne.d.ts +0 -24
  262. package/decorators/OneToOne.js +0 -10
  263. package/decorators/PrimaryKey.d.ts +0 -9
  264. package/decorators/PrimaryKey.js +0 -23
  265. package/decorators/Property.d.ts +0 -250
  266. package/decorators/Property.js +0 -34
  267. package/decorators/Transactional.d.ts +0 -13
  268. package/decorators/Transactional.js +0 -31
  269. package/decorators/hooks.d.ts +0 -16
  270. package/decorators/hooks.js +0 -59
  271. package/decorators/index.d.ts +0 -17
  272. package/decorators/index.js +0 -36
  273. package/entity/ArrayCollection.d.ts +0 -116
  274. package/entity/ArrayCollection.js +0 -399
  275. package/entity/EntityValidator.d.ts +0 -19
  276. package/entity/EntityValidator.js +0 -154
  277. package/index.mjs +0 -199
  278. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  279. package/metadata/ReflectMetadataProvider.js +0 -48
  280. package/utils/resolveContextProvider.d.ts +0 -10
  281. package/utils/resolveContextProvider.js +0 -31
@@ -1,23 +1,21 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QueryHelper = void 0;
4
- const Reference_1 = require("../entity/Reference");
5
- const Utils_1 = require("./Utils");
6
- const enums_1 = require("../enums");
7
- const JsonType_1 = require("../types/JsonType");
8
- const wrap_1 = require("../entity/wrap");
9
- const RawQueryFragment_1 = require("./RawQueryFragment");
10
- class QueryHelper {
1
+ import { Reference } from '../entity/Reference.js';
2
+ import { Utils } from './Utils.js';
3
+ import { ARRAY_OPERATORS, GroupOperator, JSON_KEY_OPERATORS, ReferenceKind } from '../enums.js';
4
+ import { JsonType } from '../types/JsonType.js';
5
+ import { helper } from '../entity/wrap.js';
6
+ import { isRaw, RawQueryFragment } from './RawQueryFragment.js';
7
+ /** @internal */
8
+ export class QueryHelper {
11
9
  static SUPPORTED_OPERATORS = ['>', '<', '<=', '>=', '!', '!='];
12
10
  static processParams(params) {
13
- if (Reference_1.Reference.isReference(params)) {
11
+ if (Reference.isReference(params)) {
14
12
  params = params.unwrap();
15
13
  }
16
- if (Utils_1.Utils.isEntity(params)) {
17
- if ((0, wrap_1.helper)(params).__meta.compositePK) {
18
- return (0, wrap_1.helper)(params).__primaryKeys;
14
+ if (Utils.isEntity(params)) {
15
+ if (helper(params).__meta.compositePK) {
16
+ return helper(params).__primaryKeys;
19
17
  }
20
- return (0, wrap_1.helper)(params).getPrimaryKey();
18
+ return helper(params).getPrimaryKey();
21
19
  }
22
20
  if (params === undefined) {
23
21
  return null;
@@ -25,34 +23,75 @@ class QueryHelper {
25
23
  if (Array.isArray(params)) {
26
24
  return params.map(item => QueryHelper.processParams(item));
27
25
  }
28
- if (Utils_1.Utils.isPlainObject(params)) {
26
+ if (Utils.isPlainObject(params)) {
29
27
  QueryHelper.processObjectParams(params);
30
28
  }
31
29
  return params;
32
30
  }
33
31
  static processObjectParams(params = {}) {
34
- Utils_1.Utils.keys(params).forEach(k => {
32
+ Utils.keys(params).forEach(k => {
35
33
  params[k] = QueryHelper.processParams(params[k]);
36
34
  });
37
35
  return params;
38
36
  }
37
+ /**
38
+ * converts `{ account: { $or: [ [Object], [Object] ] } }`
39
+ * to `{ $or: [ { account: [Object] }, { account: [Object] } ] }`
40
+ */
41
+ static liftGroupOperators(where, meta, metadata, key) {
42
+ if (!Utils.isPlainObject(where)) {
43
+ return undefined;
44
+ }
45
+ const keys = Object.keys(where);
46
+ const groupOperator = keys.find(k => {
47
+ return k in GroupOperator && Array.isArray(where[k]) && where[k].every(cond => {
48
+ return Utils.isPlainObject(cond) && Object.keys(cond).every(k2 => {
49
+ if (Utils.isOperator(k2, false)) {
50
+ if (k2 === '$not') {
51
+ return Object.keys(cond[k2]).every(k3 => meta.primaryKeys.includes(k3));
52
+ }
53
+ return true;
54
+ }
55
+ return meta.primaryKeys.includes(k2);
56
+ });
57
+ });
58
+ });
59
+ if (groupOperator) {
60
+ return groupOperator;
61
+ }
62
+ for (const k of keys) {
63
+ const value = where[k];
64
+ const prop = meta.properties[k];
65
+ if (!prop || ![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
66
+ continue;
67
+ }
68
+ const op = this.liftGroupOperators(value, prop.targetMeta, metadata, k);
69
+ if (op) {
70
+ delete where[k];
71
+ where[op] = value[op].map((v) => {
72
+ return { [k]: v };
73
+ });
74
+ }
75
+ }
76
+ return undefined;
77
+ }
39
78
  static inlinePrimaryKeyObjects(where, meta, metadata, key) {
40
79
  if (Array.isArray(where)) {
41
80
  where.forEach((item, i) => {
42
81
  if (this.inlinePrimaryKeyObjects(item, meta, metadata, key)) {
43
- where[i] = Utils_1.Utils.getPrimaryKeyValues(item, meta.primaryKeys, false);
82
+ where[i] = Utils.getPrimaryKeyValues(item, meta, false);
44
83
  }
45
84
  });
46
85
  }
47
- if (!Utils_1.Utils.isPlainObject(where) || (key && meta.properties[key]?.customType instanceof JsonType_1.JsonType)) {
86
+ if (!Utils.isPlainObject(where) || (key && meta.properties[key]?.customType instanceof JsonType)) {
48
87
  return false;
49
88
  }
50
- if (meta.primaryKeys.every(pk => pk in where) && Utils_1.Utils.getObjectKeysSize(where) === meta.primaryKeys.length) {
51
- return !!key && !enums_1.GroupOperator[key] && Object.keys(where).every(k => !Utils_1.Utils.isPlainObject(where[k]) || Object.keys(where[k]).every(v => {
52
- if (Utils_1.Utils.isOperator(v, false)) {
53
- return false;
89
+ if (meta.primaryKeys.every(pk => pk in where) && Utils.getObjectKeysSize(where) === meta.primaryKeys.length) {
90
+ return !!key && !GroupOperator[key] && key !== '$not' && Object.keys(where).every(k => !Utils.isPlainObject(where[k]) || Object.keys(where[k]).every(v => {
91
+ if (Utils.isOperator(v, false)) {
92
+ return true;
54
93
  }
55
- if (meta.properties[k].primary && [enums_1.ReferenceKind.ONE_TO_ONE, enums_1.ReferenceKind.MANY_TO_ONE].includes(meta.properties[k].kind)) {
94
+ if (meta.properties[k].primary && [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(meta.properties[k].kind)) {
56
95
  return this.inlinePrimaryKeyObjects(where[k], meta.properties[k].targetMeta, metadata, v);
57
96
  }
58
97
  return true;
@@ -61,7 +100,7 @@ class QueryHelper {
61
100
  Object.keys(where).forEach(k => {
62
101
  const meta2 = metadata.find(meta.properties[k]?.type) || meta;
63
102
  if (this.inlinePrimaryKeyObjects(where[k], meta2, metadata, k)) {
64
- where[k] = Utils_1.Utils.getPrimaryKeyValues(where[k], meta2.primaryKeys, true);
103
+ where[k] = Utils.getPrimaryKeyValues(where[k], meta2, true);
65
104
  }
66
105
  });
67
106
  return false;
@@ -72,30 +111,31 @@ class QueryHelper {
72
111
  const meta = metadata.find(entityName);
73
112
  // inline PK-only objects in M:N queries, so we don't join the target entity when not needed
74
113
  if (meta && root) {
114
+ QueryHelper.liftGroupOperators(where, meta, metadata);
75
115
  QueryHelper.inlinePrimaryKeyObjects(where, meta, metadata);
76
116
  }
77
117
  if (platform.getConfig().get('ignoreUndefinedInQuery') && where && typeof where === 'object') {
78
- Utils_1.Utils.dropUndefinedProperties(where);
118
+ Utils.dropUndefinedProperties(where);
79
119
  }
80
120
  where = QueryHelper.processParams(where) ?? {};
81
- /* istanbul ignore next */
82
- if (!root && Utils_1.Utils.isPrimaryKey(where)) {
121
+ /* v8 ignore next */
122
+ if (!root && Utils.isPrimaryKey(where)) {
83
123
  return where;
84
124
  }
85
- if (meta && Utils_1.Utils.isPrimaryKey(where, meta.compositePK)) {
86
- where = { [Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys)]: where };
125
+ if (meta && Utils.isPrimaryKey(where, meta.compositePK)) {
126
+ where = { [Utils.getPrimaryKeyHash(meta.primaryKeys)]: where };
87
127
  }
88
128
  if (Array.isArray(where) && root) {
89
- const rootPrimaryKey = meta ? Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys) : entityName;
129
+ const rootPrimaryKey = meta ? Utils.getPrimaryKeyHash(meta.primaryKeys) : entityName;
90
130
  let cond = { [rootPrimaryKey]: { $in: where } };
91
131
  // @ts-ignore
92
132
  // detect tuple comparison, use `$or` in case the number of constituents don't match
93
- if (meta && !where.every(c => Utils_1.Utils.isPrimaryKey(c) || (Array.isArray(c) && c.length === meta.primaryKeys.length && c.every(i => Utils_1.Utils.isPrimaryKey(i))))) {
133
+ if (meta && !where.every(c => Utils.isPrimaryKey(c) || (Array.isArray(c) && c.length === meta.primaryKeys.length && c.every(i => Utils.isPrimaryKey(i))))) {
94
134
  cond = { $or: where };
95
135
  }
96
136
  return QueryHelper.processWhere({ ...options, where: cond, root: false });
97
137
  }
98
- if (!Utils_1.Utils.isPlainObject(where)) {
138
+ if (!Utils.isPlainObject(where)) {
99
139
  return where;
100
140
  }
101
141
  return Object.keys(where).reduce((o, key) => {
@@ -103,34 +143,34 @@ class QueryHelper {
103
143
  const prop = this.findProperty(key, options);
104
144
  const keys = prop?.joinColumns?.length ?? 0;
105
145
  const composite = keys > 1;
106
- if (Array.isArray(value) && value.length === 0 && RawQueryFragment_1.RawQueryFragment.isKnownFragment(key)) {
146
+ if (Array.isArray(value) && value.length === 0 && RawQueryFragment.isKnownFragment(key)) {
107
147
  o[key] = value;
108
148
  return o;
109
149
  }
110
- if (key in enums_1.GroupOperator) {
150
+ if (key in GroupOperator) {
111
151
  o[key] = value.map((sub) => QueryHelper.processWhere({ ...options, where: sub, root }));
112
152
  return o;
113
153
  }
114
154
  // wrap top level operators (except platform allowed operators) with PK
115
- if (Utils_1.Utils.isOperator(key) && root && meta && !platform.isAllowedTopLevelOperator(key)) {
116
- const rootPrimaryKey = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
155
+ if (Utils.isOperator(key) && root && meta && !platform.isAllowedTopLevelOperator(key)) {
156
+ const rootPrimaryKey = Utils.getPrimaryKeyHash(meta.primaryKeys);
117
157
  o[rootPrimaryKey] = { [key]: QueryHelper.processWhere({ ...options, where: value, root: false }) };
118
158
  return o;
119
159
  }
120
- if (prop?.customType && convertCustomTypes && !(0, RawQueryFragment_1.isRaw)(value)) {
160
+ if (prop?.customType && convertCustomTypes && !isRaw(value)) {
121
161
  value = QueryHelper.processCustomType(prop, value, platform, undefined, true);
122
162
  }
123
- const isJsonProperty = prop?.customType instanceof JsonType_1.JsonType && Utils_1.Utils.isPlainObject(value) && !(0, RawQueryFragment_1.isRaw)(value) && Object.keys(value)[0] !== '$eq';
124
- if (isJsonProperty) {
163
+ const isJsonProperty = prop?.customType instanceof JsonType && Utils.isPlainObject(value) && !isRaw(value) && Object.keys(value)[0] !== '$eq';
164
+ if (isJsonProperty && prop?.kind !== ReferenceKind.EMBEDDED) {
125
165
  return this.processJsonCondition(o, value, [prop.fieldNames[0]], platform, aliased);
126
166
  }
127
- if (Array.isArray(value) && !Utils_1.Utils.isOperator(key) && !QueryHelper.isSupportedOperator(key) && !key.includes('?') && options.type !== 'orderBy') {
167
+ if (Array.isArray(value) && !Utils.isOperator(key) && !QueryHelper.isSupportedOperator(key) && !key.includes('?') && options.type !== 'orderBy') {
128
168
  // comparing single composite key - use $eq instead of $in
129
169
  const op = composite && !value.every(v => Array.isArray(v)) ? '$eq' : '$in';
130
170
  o[key] = { [op]: value };
131
171
  return o;
132
172
  }
133
- if (Utils_1.Utils.isPlainObject(value)) {
173
+ if (Utils.isPlainObject(value)) {
134
174
  o[key] = QueryHelper.processWhere({
135
175
  ...options,
136
176
  where: value,
@@ -152,7 +192,7 @@ class QueryHelper {
152
192
  if (Array.isArray(options)) {
153
193
  options.forEach(filter => opts[filter] = true);
154
194
  }
155
- else if (Utils_1.Utils.isPlainObject(options)) {
195
+ else if (Utils.isPlainObject(options)) {
156
196
  Object.keys(options).forEach(filter => opts[filter] = options[filter]);
157
197
  }
158
198
  return Object.keys(filters)
@@ -162,6 +202,24 @@ class QueryHelper {
162
202
  return filters[f];
163
203
  });
164
204
  }
205
+ static mergePropertyFilters(propFilters, options) {
206
+ if (!options || !propFilters || options === true || propFilters === true) {
207
+ return options ?? propFilters;
208
+ }
209
+ if (Array.isArray(propFilters)) {
210
+ propFilters = propFilters.reduce((o, item) => {
211
+ o[item] = true;
212
+ return o;
213
+ }, {});
214
+ }
215
+ if (Array.isArray(options)) {
216
+ options = options.reduce((o, item) => {
217
+ o[item] = true;
218
+ return o;
219
+ }, {});
220
+ }
221
+ return Utils.mergeConfig({}, propFilters, options);
222
+ }
165
223
  static isFilterActive(entityName, filterName, filter, options) {
166
224
  if (filter.entity && !filter.entity.includes(entityName)) {
167
225
  return false;
@@ -172,9 +230,9 @@ class QueryHelper {
172
230
  return filter.default || filterName in options;
173
231
  }
174
232
  static processCustomType(prop, cond, platform, key, fromQuery) {
175
- if (Utils_1.Utils.isPlainObject(cond)) {
176
- return Utils_1.Utils.keys(cond).reduce((o, k) => {
177
- if (Utils_1.Utils.isOperator(k, true) || prop.referencedPKs?.includes(k)) {
233
+ if (Utils.isPlainObject(cond)) {
234
+ return Utils.keys(cond).reduce((o, k) => {
235
+ if (Utils.isOperator(k, true) || prop.referencedPKs?.includes(k)) {
178
236
  o[k] = QueryHelper.processCustomType(prop, cond[k], platform, k, fromQuery);
179
237
  }
180
238
  else {
@@ -183,15 +241,15 @@ class QueryHelper {
183
241
  return o;
184
242
  }, {});
185
243
  }
186
- if (key && Utils_1.Utils.isJsonKeyOperator(key)) {
244
+ if (key && JSON_KEY_OPERATORS.includes(key)) {
187
245
  return Array.isArray(cond)
188
246
  ? platform.marshallArray(cond)
189
247
  : cond;
190
248
  }
191
- if (Array.isArray(cond) && !(key && Utils_1.Utils.isArrayOperator(key))) {
249
+ if (Array.isArray(cond) && !(key && ARRAY_OPERATORS.includes(key))) {
192
250
  return cond.map(v => QueryHelper.processCustomType(prop, v, platform, key, fromQuery));
193
251
  }
194
- if ((0, RawQueryFragment_1.isRaw)(cond)) {
252
+ if (isRaw(cond)) {
195
253
  return cond;
196
254
  }
197
255
  return prop.customType.convertToDatabaseValue(cond, platform, { fromQuery, key, mode: 'query' });
@@ -200,8 +258,8 @@ class QueryHelper {
200
258
  return !!QueryHelper.SUPPORTED_OPERATORS.find(op => key === op);
201
259
  }
202
260
  static processJsonCondition(o, value, path, platform, alias) {
203
- if (Utils_1.Utils.isPlainObject(value) && !Object.keys(value).some(k => Utils_1.Utils.isOperator(k))) {
204
- Utils_1.Utils.keys(value).forEach(k => {
261
+ if (Utils.isPlainObject(value) && !Object.keys(value).some(k => Utils.isOperator(k))) {
262
+ Utils.keys(value).forEach(k => {
205
263
  this.processJsonCondition(o, value[k], [...path, k], platform, alias);
206
264
  });
207
265
  return o;
@@ -219,7 +277,7 @@ class QueryHelper {
219
277
  if (Array.isArray(value)) {
220
278
  return typeof value[0];
221
279
  }
222
- if (Utils_1.Utils.isPlainObject(value) && Object.keys(value).every(k => Utils_1.Utils.isOperator(k))) {
280
+ if (Utils.isPlainObject(value) && Object.keys(value).every(k => Utils.isOperator(k))) {
223
281
  return this.getValueType(Object.values(value)[0]);
224
282
  }
225
283
  return typeof value;
@@ -233,4 +291,3 @@ class QueryHelper {
233
291
  return meta?.properties[propName];
234
292
  }
235
293
  }
236
- exports.QueryHelper = QueryHelper;
@@ -1,5 +1,4 @@
1
- import { inspect } from 'node:util';
2
- import type { AnyString, Dictionary, EntityKey } from '../typings';
1
+ import type { AnyString, Dictionary, EntityKey } from '../typings.js';
3
2
  export declare class RawQueryFragment {
4
3
  #private;
5
4
  readonly sql: string;
@@ -10,8 +9,6 @@ export declare class RawQueryFragment {
10
9
  valueOf(): string;
11
10
  toJSON(): string;
12
11
  toString(): string;
13
- /** @internal */
14
- assign(): void;
15
12
  clone(): RawQueryFragment;
16
13
  static run<T>(cb: (...args: any[]) => Promise<T>): Promise<T>;
17
14
  /**
@@ -21,14 +18,6 @@ export declare class RawQueryFragment {
21
18
  static isKnownFragment(key: string | RawQueryFragment): boolean;
22
19
  static getKnownFragment(key: string | RawQueryFragment, cleanup?: boolean): RawQueryFragment | undefined;
23
20
  static remove(key: string): void;
24
- /** @ignore */
25
- [inspect.custom](): {
26
- sql: string;
27
- params: unknown[];
28
- } | {
29
- sql: string;
30
- params?: undefined;
31
- };
32
21
  }
33
22
  export { RawQueryFragment as Raw };
34
23
  export declare function isRaw(value: unknown): value is RawQueryFragment;
@@ -72,8 +61,26 @@ export declare const ALIAS_REPLACEMENT_RE = "\\[::alias::\\]";
72
61
  * ```ts
73
62
  * @Filter({ name: 'long', cond: () => ({ [raw('length(perex)')]: { $gt: 10000 } }) })
74
63
  * ```
64
+ *
65
+ * The `raw` helper can be used within indexes and uniques to write database-agnostic SQL expressions. In that case, you can use `'??'` to tag your database identifiers (table name, column names, index name, ...) inside your expression, and pass those identifiers as a second parameter to the `raw` helper. Internally, those will automatically be quoted according to the database in use:
66
+ *
67
+ * ```ts
68
+ * // On postgres, will produce: create index "index custom_idx_on_name" on "library.author" ("country")
69
+ * // On mysql, will produce: create index `index custom_idx_on_name` on `library.author` (`country`)
70
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => raw(`create index ?? on ?? (??)`, ['custom_idx_on_name', table, columns.name]) })
71
+ * @Entity({ schema: 'library' })
72
+ * export class Author { ... }
73
+ * ```
74
+ *
75
+ * You can also use the `quote` tag function to write database-agnostic SQL expressions. The end-result is the same as using the `raw` function regarding database identifiers quoting, only to have a more elegant expression syntax:
76
+ *
77
+ * ```ts
78
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => quote`create index ${'custom_idx_on_name'} on ${table} (${columns.name})` })
79
+ * @Entity({ schema: 'library' })
80
+ * export class Author { ... }
81
+ * ```
75
82
  */
76
- export declare function raw<T extends object = any, R = any>(sql: EntityKey<T> | EntityKey<T>[] | AnyString | ((alias: string) => string) | RawQueryFragment, params?: readonly unknown[] | Dictionary<unknown>): R;
83
+ export declare function raw<T extends object = any, R = any>(sql: EntityKey<T> | EntityKey<T>[] | AnyString | ((alias: string) => string) | RawQueryFragment, params?: readonly unknown[] | Dictionary<unknown>): NoInfer<R>;
77
84
  /**
78
85
  * Alternative to the `raw()` helper allowing to use it as a tagged template function for the simple cases.
79
86
  *
@@ -90,9 +97,25 @@ export declare function raw<T extends object = any, R = any>(sql: EntityKey<T> |
90
97
  */
91
98
  export declare function sql(sql: readonly string[], ...values: unknown[]): any;
92
99
  export declare namespace sql {
93
- var ref: <T extends object>(...keys: string[]) => RawQueryFragment;
100
+ var ref: <T extends object>(...keys: string[]) => NoInfer<RawQueryFragment>;
94
101
  var now: (length?: number) => string;
95
102
  var lower: <T extends object>(key: string | ((alias: string) => string)) => string;
96
103
  var upper: <T extends object>(key: string | ((alias: string) => string)) => string;
97
104
  }
98
105
  export declare function createSqlFunction<T extends object, R = string>(func: string, key: string | ((alias: string) => string)): R;
106
+ /**
107
+ * Tag function providing quoting of db identifiers (table name, columns names, index names, ...).
108
+ *
109
+ * Within the template literal on which the tag function is applied, all placeholders are considered to be database identifiers, and will thus be quoted as so according to the database in use.
110
+ *
111
+ * ```ts
112
+ * // On postgres, will produce: create index "index custom_idx_on_name" on "library.author" ("name")
113
+ * // On mysql, will produce: create index `index custom_idx_on_name` on `library.author` (`name`)
114
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => quote`create index ${'custom_idx_on_name'} on ${table} (${columns.name})` })
115
+ * @Entity({ schema: 'library' })
116
+ * export class Author { ... }
117
+ * ```
118
+ */
119
+ export declare function quote(expParts: readonly string[], ...values: (string | {
120
+ toString(): string;
121
+ })[]): any;
@@ -1,21 +1,12 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ALIAS_REPLACEMENT_RE = exports.ALIAS_REPLACEMENT = exports.Raw = exports.RawQueryFragment = void 0;
4
- exports.isRaw = isRaw;
5
- exports.raw = raw;
6
- exports.sql = sql;
7
- exports.createSqlFunction = createSqlFunction;
8
- const node_async_hooks_1 = require("node:async_hooks");
9
- const node_util_1 = require("node:util");
10
- const Utils_1 = require("./Utils");
11
- class RawQueryFragment {
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { Utils } from './Utils.js';
3
+ export class RawQueryFragment {
12
4
  sql;
13
5
  params;
14
6
  static #rawQueryCache = new Map();
15
- static #storage = new node_async_hooks_1.AsyncLocalStorage();
7
+ static #storage = new AsyncLocalStorage();
16
8
  static #index = 0n;
17
9
  static cloneRegistry;
18
- #assigned = false;
19
10
  #used = 0;
20
11
  #key;
21
12
  constructor(sql, params = []) {
@@ -24,7 +15,7 @@ class RawQueryFragment {
24
15
  this.#key = `[raw]: ${this.sql} (#${RawQueryFragment.#index++})`;
25
16
  }
26
17
  as(alias) {
27
- return new RawQueryFragment(`${this.sql} as ${alias}`, this.params);
18
+ return new RawQueryFragment(`${this.sql} as ??`, [...this.params, alias]);
28
19
  }
29
20
  valueOf() {
30
21
  throw new Error(`Trying to modify raw SQL fragment: '${this.sql}'`);
@@ -37,13 +28,6 @@ class RawQueryFragment {
37
28
  this.#used++;
38
29
  return this.#key;
39
30
  }
40
- /** @internal */
41
- assign() {
42
- if (this.#assigned) {
43
- throw new Error(`Cannot reassign already used RawQueryFragment: '${this.sql}'`);
44
- }
45
- this.#assigned = true;
46
- }
47
31
  clone() {
48
32
  RawQueryFragment.cloneRegistry?.add(this.#key);
49
33
  return new RawQueryFragment(this.sql, this.params);
@@ -93,27 +77,26 @@ class RawQueryFragment {
93
77
  }
94
78
  }
95
79
  }
96
- /* istanbul ignore next */
97
80
  /** @ignore */
98
- [node_util_1.inspect.custom]() {
81
+ /* v8 ignore next */
82
+ [Symbol.for('nodejs.util.inspect.custom')]() {
99
83
  if (this.params) {
100
84
  return { sql: this.sql, params: this.params };
101
85
  }
102
86
  return { sql: this.sql };
103
87
  }
104
88
  }
105
- exports.RawQueryFragment = RawQueryFragment;
106
- exports.Raw = RawQueryFragment;
89
+ export { RawQueryFragment as Raw };
107
90
  Object.defineProperties(RawQueryFragment.prototype, {
108
91
  __raw: { value: true, enumerable: false },
109
92
  });
110
- function isRaw(value) {
93
+ export function isRaw(value) {
111
94
  return typeof value === 'object' && value !== null && '__raw' in value;
112
95
  }
113
96
  /** @internal */
114
- exports.ALIAS_REPLACEMENT = '[::alias::]';
97
+ export const ALIAS_REPLACEMENT = '[::alias::]';
115
98
  /** @internal */
116
- exports.ALIAS_REPLACEMENT_RE = '\\[::alias::\\]';
99
+ export const ALIAS_REPLACEMENT_RE = '\\[::alias::\\]';
117
100
  /**
118
101
  * Creates raw SQL query fragment that can be assigned to a property or part of a filter. This fragment is represented
119
102
  * by `RawQueryFragment` class instance that can be serialized to a string, so it can be used both as an object value
@@ -150,20 +133,38 @@ exports.ALIAS_REPLACEMENT_RE = '\\[::alias::\\]';
150
133
  * ```ts
151
134
  * @Filter({ name: 'long', cond: () => ({ [raw('length(perex)')]: { $gt: 10000 } }) })
152
135
  * ```
136
+ *
137
+ * The `raw` helper can be used within indexes and uniques to write database-agnostic SQL expressions. In that case, you can use `'??'` to tag your database identifiers (table name, column names, index name, ...) inside your expression, and pass those identifiers as a second parameter to the `raw` helper. Internally, those will automatically be quoted according to the database in use:
138
+ *
139
+ * ```ts
140
+ * // On postgres, will produce: create index "index custom_idx_on_name" on "library.author" ("country")
141
+ * // On mysql, will produce: create index `index custom_idx_on_name` on `library.author` (`country`)
142
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => raw(`create index ?? on ?? (??)`, ['custom_idx_on_name', table, columns.name]) })
143
+ * @Entity({ schema: 'library' })
144
+ * export class Author { ... }
145
+ * ```
146
+ *
147
+ * You can also use the `quote` tag function to write database-agnostic SQL expressions. The end-result is the same as using the `raw` function regarding database identifiers quoting, only to have a more elegant expression syntax:
148
+ *
149
+ * ```ts
150
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => quote`create index ${'custom_idx_on_name'} on ${table} (${columns.name})` })
151
+ * @Entity({ schema: 'library' })
152
+ * export class Author { ... }
153
+ * ```
153
154
  */
154
- function raw(sql, params) {
155
+ export function raw(sql, params) {
155
156
  if (sql instanceof RawQueryFragment) {
156
157
  return sql;
157
158
  }
158
159
  if (sql instanceof Function) {
159
- sql = sql(exports.ALIAS_REPLACEMENT);
160
+ sql = sql(ALIAS_REPLACEMENT);
160
161
  }
161
162
  if (sql === '??' && Array.isArray(params)) {
162
163
  return new RawQueryFragment(sql, params);
163
164
  }
164
165
  if (Array.isArray(sql)) {
165
166
  // for composite FK we return just a simple string
166
- return Utils_1.Utils.getPrimaryKeyHash(sql);
167
+ return Utils.getPrimaryKeyHash(sql);
167
168
  }
168
169
  if (typeof params === 'object' && !Array.isArray(params)) {
169
170
  const pairs = Object.entries(params);
@@ -191,14 +192,14 @@ function raw(sql, params) {
191
192
  * await em.find(User, { [sql`(select 1 = 1)`]: [] });
192
193
  * ```
193
194
  */
194
- function sql(sql, ...values) {
195
+ export function sql(sql, ...values) {
195
196
  return raw(sql.reduce((query, queryPart, i) => {
196
197
  const valueExists = i < values.length;
197
198
  const text = query + queryPart;
198
199
  return valueExists ? text + '?' : text;
199
200
  }, ''), values);
200
201
  }
201
- function createSqlFunction(func, key) {
202
+ export function createSqlFunction(func, key) {
202
203
  if (typeof key === 'string') {
203
204
  return raw(`${func}(${key})`);
204
205
  }
@@ -208,3 +209,19 @@ sql.ref = (...keys) => raw('??', [keys.join('.')]);
208
209
  sql.now = (length) => raw('current_timestamp' + (length == null ? '' : `(${length})`));
209
210
  sql.lower = (key) => createSqlFunction('lower', key);
210
211
  sql.upper = (key) => createSqlFunction('upper', key);
212
+ /**
213
+ * Tag function providing quoting of db identifiers (table name, columns names, index names, ...).
214
+ *
215
+ * Within the template literal on which the tag function is applied, all placeholders are considered to be database identifiers, and will thus be quoted as so according to the database in use.
216
+ *
217
+ * ```ts
218
+ * // On postgres, will produce: create index "index custom_idx_on_name" on "library.author" ("name")
219
+ * // On mysql, will produce: create index `index custom_idx_on_name` on `library.author` (`name`)
220
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => quote`create index ${'custom_idx_on_name'} on ${table} (${columns.name})` })
221
+ * @Entity({ schema: 'library' })
222
+ * export class Author { ... }
223
+ * ```
224
+ */
225
+ export function quote(expParts, ...values) {
226
+ return raw(expParts.join('??'), values);
227
+ }
@@ -1,5 +1,5 @@
1
- import type { EntityManager } from '../EntityManager';
2
- import { type LoggingOptions } from '../logging/Logger';
1
+ import type { EntityManager } from '../EntityManager.js';
2
+ import { type LoggingOptions } from '../logging/Logger.js';
3
3
  /**
4
4
  * Uses `AsyncLocalStorage` to create async context that holds the current EM fork.
5
5
  */
@@ -1,13 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RequestContext = void 0;
4
- const node_async_hooks_1 = require("node:async_hooks");
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
5
2
  /**
6
3
  * Uses `AsyncLocalStorage` to create async context that holds the current EM fork.
7
4
  */
8
- class RequestContext {
5
+ export class RequestContext {
9
6
  map;
10
- static storage = new node_async_hooks_1.AsyncLocalStorage();
7
+ static storage = new AsyncLocalStorage();
11
8
  static counter = 1;
12
9
  id = RequestContext.counter++;
13
10
  constructor(map) {
@@ -61,4 +58,3 @@ class RequestContext {
61
58
  return new RequestContext(forks);
62
59
  }
63
60
  }
64
- exports.RequestContext = RequestContext;
@@ -1,4 +1,4 @@
1
- import type { EntityManager } from '../EntityManager';
1
+ import type { EntityManager } from '../EntityManager.js';
2
2
  export declare class TransactionContext {
3
3
  readonly em: EntityManager;
4
4
  private static storage;
@@ -1,10 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TransactionContext = void 0;
4
- const node_async_hooks_1 = require("node:async_hooks");
5
- class TransactionContext {
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ export class TransactionContext {
6
3
  em;
7
- static storage = new node_async_hooks_1.AsyncLocalStorage();
4
+ static storage = new AsyncLocalStorage();
8
5
  id;
9
6
  constructor(em) {
10
7
  this.em = em;
@@ -26,9 +23,8 @@ class TransactionContext {
26
23
  /**
27
24
  * Returns current EntityManager (if available).
28
25
  */
29
- static getEntityManager(name = /* istanbul ignore next */ 'default') {
26
+ static getEntityManager(name = 'default') {
30
27
  const context = TransactionContext.currentTransactionContext();
31
28
  return context?.em.name === name ? context.em : undefined;
32
29
  }
33
30
  }
34
- exports.TransactionContext = TransactionContext;