@yandjin-mikro-orm/core 6.1.4-rc-sti-changes-1

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 (264) hide show
  1. package/EntityManager.d.ts +553 -0
  2. package/EntityManager.js +1736 -0
  3. package/LICENSE +21 -0
  4. package/MikroORM.d.ts +102 -0
  5. package/MikroORM.js +258 -0
  6. package/README.md +383 -0
  7. package/cache/CacheAdapter.d.ts +40 -0
  8. package/cache/CacheAdapter.js +2 -0
  9. package/cache/FileCacheAdapter.d.ts +31 -0
  10. package/cache/FileCacheAdapter.js +90 -0
  11. package/cache/GeneratedCacheAdapter.d.ts +25 -0
  12. package/cache/GeneratedCacheAdapter.js +38 -0
  13. package/cache/MemoryCacheAdapter.d.ts +24 -0
  14. package/cache/MemoryCacheAdapter.js +44 -0
  15. package/cache/NullCacheAdapter.d.ts +19 -0
  16. package/cache/NullCacheAdapter.js +30 -0
  17. package/cache/index.d.ts +5 -0
  18. package/cache/index.js +21 -0
  19. package/connections/Connection.d.ts +85 -0
  20. package/connections/Connection.js +128 -0
  21. package/connections/index.d.ts +1 -0
  22. package/connections/index.js +17 -0
  23. package/decorators/Check.d.ts +3 -0
  24. package/decorators/Check.js +17 -0
  25. package/decorators/CreateRequestContext.d.ts +2 -0
  26. package/decorators/CreateRequestContext.js +31 -0
  27. package/decorators/Embeddable.d.ts +8 -0
  28. package/decorators/Embeddable.js +15 -0
  29. package/decorators/Embedded.d.ts +13 -0
  30. package/decorators/Embedded.js +21 -0
  31. package/decorators/EnsureRequestContext.d.ts +2 -0
  32. package/decorators/EnsureRequestContext.js +26 -0
  33. package/decorators/Entity.d.ts +18 -0
  34. package/decorators/Entity.js +17 -0
  35. package/decorators/Enum.d.ts +9 -0
  36. package/decorators/Enum.js +20 -0
  37. package/decorators/Filter.d.ts +2 -0
  38. package/decorators/Filter.js +12 -0
  39. package/decorators/Formula.d.ts +5 -0
  40. package/decorators/Formula.js +19 -0
  41. package/decorators/Indexed.d.ts +12 -0
  42. package/decorators/Indexed.js +25 -0
  43. package/decorators/ManyToMany.d.ts +21 -0
  44. package/decorators/ManyToMany.js +17 -0
  45. package/decorators/ManyToOne.d.ts +15 -0
  46. package/decorators/ManyToOne.js +17 -0
  47. package/decorators/OneToMany.d.ts +18 -0
  48. package/decorators/OneToMany.js +21 -0
  49. package/decorators/OneToOne.d.ts +12 -0
  50. package/decorators/OneToOne.js +11 -0
  51. package/decorators/PrimaryKey.d.ts +8 -0
  52. package/decorators/PrimaryKey.js +24 -0
  53. package/decorators/Property.d.ts +218 -0
  54. package/decorators/Property.js +35 -0
  55. package/decorators/Subscriber.d.ts +1 -0
  56. package/decorators/Subscriber.js +2 -0
  57. package/decorators/hooks.d.ts +16 -0
  58. package/decorators/hooks.js +60 -0
  59. package/decorators/index.d.ts +17 -0
  60. package/decorators/index.js +36 -0
  61. package/drivers/DatabaseDriver.d.ts +72 -0
  62. package/drivers/DatabaseDriver.js +358 -0
  63. package/drivers/IDatabaseDriver.d.ts +193 -0
  64. package/drivers/IDatabaseDriver.js +4 -0
  65. package/drivers/index.d.ts +2 -0
  66. package/drivers/index.js +18 -0
  67. package/entity/ArrayCollection.d.ts +113 -0
  68. package/entity/ArrayCollection.js +386 -0
  69. package/entity/BaseEntity.d.ts +22 -0
  70. package/entity/BaseEntity.js +47 -0
  71. package/entity/Collection.d.ts +104 -0
  72. package/entity/Collection.js +373 -0
  73. package/entity/EntityAssigner.d.ts +28 -0
  74. package/entity/EntityAssigner.js +226 -0
  75. package/entity/EntityFactory.d.ts +41 -0
  76. package/entity/EntityFactory.js +302 -0
  77. package/entity/EntityHelper.d.ts +29 -0
  78. package/entity/EntityHelper.js +250 -0
  79. package/entity/EntityIdentifier.d.ts +10 -0
  80. package/entity/EntityIdentifier.js +19 -0
  81. package/entity/EntityLoader.d.ts +65 -0
  82. package/entity/EntityLoader.js +579 -0
  83. package/entity/EntityRepository.d.ts +161 -0
  84. package/entity/EntityRepository.js +207 -0
  85. package/entity/EntityValidator.d.ts +19 -0
  86. package/entity/EntityValidator.js +152 -0
  87. package/entity/Reference.d.ts +89 -0
  88. package/entity/Reference.js +242 -0
  89. package/entity/WrappedEntity.d.ts +67 -0
  90. package/entity/WrappedEntity.js +146 -0
  91. package/entity/index.d.ts +13 -0
  92. package/entity/index.js +29 -0
  93. package/entity/wrap.d.ts +15 -0
  94. package/entity/wrap.js +26 -0
  95. package/enums.d.ts +160 -0
  96. package/enums.js +169 -0
  97. package/errors.d.ts +65 -0
  98. package/errors.js +222 -0
  99. package/events/EventManager.d.ts +17 -0
  100. package/events/EventManager.js +77 -0
  101. package/events/EventSubscriber.d.ts +39 -0
  102. package/events/EventSubscriber.js +2 -0
  103. package/events/TransactionEventBroadcaster.d.ts +11 -0
  104. package/events/TransactionEventBroadcaster.js +17 -0
  105. package/events/index.d.ts +3 -0
  106. package/events/index.js +19 -0
  107. package/exceptions.d.ts +104 -0
  108. package/exceptions.js +130 -0
  109. package/hydration/Hydrator.d.ts +23 -0
  110. package/hydration/Hydrator.js +51 -0
  111. package/hydration/ObjectHydrator.d.ts +24 -0
  112. package/hydration/ObjectHydrator.js +332 -0
  113. package/hydration/index.d.ts +2 -0
  114. package/hydration/index.js +18 -0
  115. package/index.d.ts +25 -0
  116. package/index.js +50 -0
  117. package/index.mjs +192 -0
  118. package/logging/DefaultLogger.d.ts +32 -0
  119. package/logging/DefaultLogger.js +90 -0
  120. package/logging/Logger.d.ts +56 -0
  121. package/logging/Logger.js +2 -0
  122. package/logging/SimpleLogger.d.ts +17 -0
  123. package/logging/SimpleLogger.js +31 -0
  124. package/logging/colors.d.ts +9 -0
  125. package/logging/colors.js +20 -0
  126. package/logging/index.d.ts +4 -0
  127. package/logging/index.js +20 -0
  128. package/metadata/EntitySchema.d.ts +74 -0
  129. package/metadata/EntitySchema.js +293 -0
  130. package/metadata/MetadataDiscovery.d.ts +71 -0
  131. package/metadata/MetadataDiscovery.js +1244 -0
  132. package/metadata/MetadataProvider.d.ts +11 -0
  133. package/metadata/MetadataProvider.js +23 -0
  134. package/metadata/MetadataStorage.d.ts +22 -0
  135. package/metadata/MetadataStorage.js +87 -0
  136. package/metadata/MetadataValidator.d.ts +24 -0
  137. package/metadata/MetadataValidator.js +213 -0
  138. package/metadata/ReflectMetadataProvider.d.ts +8 -0
  139. package/metadata/ReflectMetadataProvider.js +48 -0
  140. package/metadata/index.d.ts +6 -0
  141. package/metadata/index.js +22 -0
  142. package/naming-strategy/AbstractNamingStrategy.d.ts +18 -0
  143. package/naming-strategy/AbstractNamingStrategy.js +48 -0
  144. package/naming-strategy/EntityCaseNamingStrategy.d.ts +12 -0
  145. package/naming-strategy/EntityCaseNamingStrategy.js +32 -0
  146. package/naming-strategy/MongoNamingStrategy.d.ts +9 -0
  147. package/naming-strategy/MongoNamingStrategy.js +25 -0
  148. package/naming-strategy/NamingStrategy.d.ts +52 -0
  149. package/naming-strategy/NamingStrategy.js +2 -0
  150. package/naming-strategy/UnderscoreNamingStrategy.d.ts +10 -0
  151. package/naming-strategy/UnderscoreNamingStrategy.js +28 -0
  152. package/naming-strategy/index.d.ts +5 -0
  153. package/naming-strategy/index.js +21 -0
  154. package/package.json +70 -0
  155. package/platforms/ExceptionConverter.d.ts +5 -0
  156. package/platforms/ExceptionConverter.js +11 -0
  157. package/platforms/Platform.d.ts +201 -0
  158. package/platforms/Platform.js +452 -0
  159. package/platforms/index.d.ts +2 -0
  160. package/platforms/index.js +18 -0
  161. package/serialization/EntitySerializer.d.ts +34 -0
  162. package/serialization/EntitySerializer.js +206 -0
  163. package/serialization/EntityTransformer.d.ts +8 -0
  164. package/serialization/EntityTransformer.js +192 -0
  165. package/serialization/SerializationContext.d.ts +30 -0
  166. package/serialization/SerializationContext.js +111 -0
  167. package/serialization/index.d.ts +3 -0
  168. package/serialization/index.js +19 -0
  169. package/types/ArrayType.d.ts +13 -0
  170. package/types/ArrayType.js +47 -0
  171. package/types/BigIntType.d.ts +16 -0
  172. package/types/BigIntType.js +45 -0
  173. package/types/BlobType.d.ts +10 -0
  174. package/types/BlobType.js +27 -0
  175. package/types/BooleanType.d.ts +8 -0
  176. package/types/BooleanType.js +16 -0
  177. package/types/DateTimeType.d.ts +8 -0
  178. package/types/DateTimeType.js +16 -0
  179. package/types/DateType.d.ts +8 -0
  180. package/types/DateType.js +16 -0
  181. package/types/DecimalType.d.ts +11 -0
  182. package/types/DecimalType.js +22 -0
  183. package/types/DoubleType.d.ts +11 -0
  184. package/types/DoubleType.js +22 -0
  185. package/types/EnumArrayType.d.ts +9 -0
  186. package/types/EnumArrayType.js +32 -0
  187. package/types/EnumType.d.ts +8 -0
  188. package/types/EnumType.js +16 -0
  189. package/types/FloatType.d.ts +8 -0
  190. package/types/FloatType.js +16 -0
  191. package/types/IntegerType.d.ts +8 -0
  192. package/types/IntegerType.js +16 -0
  193. package/types/IntervalType.d.ts +8 -0
  194. package/types/IntervalType.js +16 -0
  195. package/types/JsonType.d.ts +13 -0
  196. package/types/JsonType.js +34 -0
  197. package/types/MediumIntType.d.ts +6 -0
  198. package/types/MediumIntType.js +10 -0
  199. package/types/SmallIntType.d.ts +8 -0
  200. package/types/SmallIntType.js +16 -0
  201. package/types/StringType.d.ts +8 -0
  202. package/types/StringType.js +16 -0
  203. package/types/TextType.d.ts +8 -0
  204. package/types/TextType.js +16 -0
  205. package/types/TimeType.d.ts +9 -0
  206. package/types/TimeType.js +23 -0
  207. package/types/TinyIntType.d.ts +8 -0
  208. package/types/TinyIntType.js +16 -0
  209. package/types/Type.d.ts +64 -0
  210. package/types/Type.js +84 -0
  211. package/types/Uint8ArrayType.d.ts +11 -0
  212. package/types/Uint8ArrayType.js +37 -0
  213. package/types/UnknownType.d.ts +7 -0
  214. package/types/UnknownType.js +13 -0
  215. package/types/UuidType.d.ts +7 -0
  216. package/types/UuidType.js +13 -0
  217. package/types/index.d.ts +75 -0
  218. package/types/index.js +77 -0
  219. package/typings.d.ts +767 -0
  220. package/typings.js +198 -0
  221. package/unit-of-work/ChangeSet.d.ts +34 -0
  222. package/unit-of-work/ChangeSet.js +62 -0
  223. package/unit-of-work/ChangeSetComputer.d.ts +26 -0
  224. package/unit-of-work/ChangeSetComputer.js +153 -0
  225. package/unit-of-work/ChangeSetPersister.d.ts +50 -0
  226. package/unit-of-work/ChangeSetPersister.js +361 -0
  227. package/unit-of-work/CommitOrderCalculator.d.ts +62 -0
  228. package/unit-of-work/CommitOrderCalculator.js +113 -0
  229. package/unit-of-work/IdentityMap.d.ts +17 -0
  230. package/unit-of-work/IdentityMap.js +84 -0
  231. package/unit-of-work/UnitOfWork.d.ts +124 -0
  232. package/unit-of-work/UnitOfWork.js +1013 -0
  233. package/unit-of-work/index.d.ts +6 -0
  234. package/unit-of-work/index.js +22 -0
  235. package/utils/AbstractSchemaGenerator.d.ts +38 -0
  236. package/utils/AbstractSchemaGenerator.js +101 -0
  237. package/utils/Configuration.d.ts +390 -0
  238. package/utils/Configuration.js +357 -0
  239. package/utils/ConfigurationLoader.d.ts +29 -0
  240. package/utils/ConfigurationLoader.js +282 -0
  241. package/utils/Cursor.d.ts +77 -0
  242. package/utils/Cursor.js +169 -0
  243. package/utils/DataloaderUtils.d.ts +43 -0
  244. package/utils/DataloaderUtils.js +194 -0
  245. package/utils/EntityComparator.d.ts +73 -0
  246. package/utils/EntityComparator.js +568 -0
  247. package/utils/NullHighlighter.d.ts +4 -0
  248. package/utils/NullHighlighter.js +9 -0
  249. package/utils/QueryHelper.d.ts +28 -0
  250. package/utils/QueryHelper.js +228 -0
  251. package/utils/RawQueryFragment.d.ts +96 -0
  252. package/utils/RawQueryFragment.js +188 -0
  253. package/utils/RequestContext.d.ts +34 -0
  254. package/utils/RequestContext.js +54 -0
  255. package/utils/TransactionContext.d.ts +19 -0
  256. package/utils/TransactionContext.js +34 -0
  257. package/utils/Utils.d.ts +274 -0
  258. package/utils/Utils.js +1073 -0
  259. package/utils/clone.d.ts +6 -0
  260. package/utils/clone.js +127 -0
  261. package/utils/index.d.ts +13 -0
  262. package/utils/index.js +29 -0
  263. package/utils/upsert-utils.d.ts +6 -0
  264. package/utils/upsert-utils.js +33 -0
@@ -0,0 +1,1244 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MetadataDiscovery = void 0;
7
+ const path_1 = require("path");
8
+ const globby_1 = __importDefault(require("globby"));
9
+ const typings_1 = require("../typings");
10
+ const Utils_1 = require("../utils/Utils");
11
+ const MetadataValidator_1 = require("./MetadataValidator");
12
+ const MetadataStorage_1 = require("./MetadataStorage");
13
+ const EntitySchema_1 = require("./EntitySchema");
14
+ const enums_1 = require("../enums");
15
+ const errors_1 = require("../errors");
16
+ const types_1 = require("../types");
17
+ const colors_1 = require("../logging/colors");
18
+ const RawQueryFragment_1 = require("../utils/RawQueryFragment");
19
+ class MetadataDiscovery {
20
+ metadata;
21
+ platform;
22
+ config;
23
+ namingStrategy;
24
+ metadataProvider;
25
+ cache;
26
+ logger;
27
+ schemaHelper;
28
+ validator = new MetadataValidator_1.MetadataValidator();
29
+ discovered = [];
30
+ constructor(metadata, platform, config) {
31
+ this.metadata = metadata;
32
+ this.platform = platform;
33
+ this.config = config;
34
+ this.namingStrategy = this.config.getNamingStrategy();
35
+ this.metadataProvider = this.config.getMetadataProvider();
36
+ this.cache = this.config.getMetadataCacheAdapter();
37
+ this.logger = this.config.getLogger();
38
+ this.schemaHelper = this.platform.getSchemaHelper();
39
+ }
40
+ async discover(preferTsNode = true) {
41
+ const startTime = Date.now();
42
+ this.logger.log('discovery', `ORM entity discovery started, using ${colors_1.colors.cyan(this.metadataProvider.constructor.name)}`);
43
+ await this.findEntities(preferTsNode);
44
+ for (const meta of this.discovered) {
45
+ await this.config.get('discovery').onMetadata?.(meta, this.platform);
46
+ }
47
+ this.processDiscoveredEntities(this.discovered);
48
+ const diff = Date.now() - startTime;
49
+ this.logger.log('discovery', `- entity discovery finished, found ${colors_1.colors.green('' + this.discovered.length)} entities, took ${colors_1.colors.green(`${diff} ms`)}`);
50
+ const storage = this.mapDiscoveredEntities();
51
+ await this.config.get('discovery').afterDiscovered?.(storage, this.platform);
52
+ return storage;
53
+ }
54
+ discoverSync(preferTsNode = true) {
55
+ const startTime = Date.now();
56
+ this.logger.log('discovery', `ORM entity discovery started, using ${colors_1.colors.cyan(this.metadataProvider.constructor.name)} in sync mode`);
57
+ this.findEntities(preferTsNode, true);
58
+ for (const meta of this.discovered) {
59
+ this.config.get('discovery').onMetadata?.(meta, this.platform);
60
+ }
61
+ this.processDiscoveredEntities(this.discovered);
62
+ const diff = Date.now() - startTime;
63
+ this.logger.log('discovery', `- entity discovery finished, found ${colors_1.colors.green('' + this.discovered.length)} entities, took ${colors_1.colors.green(`${diff} ms`)}`);
64
+ const storage = this.mapDiscoveredEntities();
65
+ this.config.get('discovery').afterDiscovered?.(storage, this.platform);
66
+ return storage;
67
+ }
68
+ mapDiscoveredEntities() {
69
+ const discovered = new MetadataStorage_1.MetadataStorage();
70
+ this.discovered
71
+ .filter(meta => meta.root.name)
72
+ .sort((a, b) => b.root.name.localeCompare(a.root.name))
73
+ .forEach(meta => {
74
+ this.platform.validateMetadata(meta);
75
+ discovered.set(meta.className, meta);
76
+ });
77
+ return discovered;
78
+ }
79
+ processDiscoveredEntities(discovered) {
80
+ for (const meta of discovered) {
81
+ let i = 1;
82
+ Object.values(meta.properties).forEach(prop => meta.propertyOrder.set(prop.name, i++));
83
+ Object.values(meta.properties).forEach(prop => this.initPolyEmbeddables(prop, discovered));
84
+ }
85
+ // ignore base entities (not annotated with @Entity)
86
+ const filtered = discovered.filter(meta => meta.root.name);
87
+ // sort so we discover entities first to get around issues with nested embeddables
88
+ filtered.sort((a, b) => !a.embeddable === !b.embeddable ? 0 : (a.embeddable ? 1 : -1));
89
+ filtered.forEach(meta => this.initSingleTableInheritance(meta, filtered));
90
+ filtered.forEach(meta => this.defineBaseEntityProperties(meta));
91
+ filtered.forEach(meta => this.metadata.set(meta.className, EntitySchema_1.EntitySchema.fromMetadata(meta).init().meta));
92
+ filtered.forEach(meta => this.initAutoincrement(meta));
93
+ filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initEmbeddables(meta, prop)));
94
+ filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initFactoryField(meta, prop)));
95
+ filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initFieldName(prop)));
96
+ filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initVersionProperty(meta, prop)));
97
+ filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initCustomType(meta, prop)));
98
+ filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initGeneratedColumn(meta, prop)));
99
+ filtered.forEach(meta => this.initAutoincrement(meta)); // once again after we init custom types
100
+ filtered.forEach(meta => this.initCheckConstraints(meta));
101
+ for (const meta of filtered) {
102
+ for (const prop of Object.values(meta.properties)) {
103
+ this.initDefaultValue(prop);
104
+ this.inferTypeFromDefault(prop);
105
+ this.initColumnType(prop);
106
+ }
107
+ }
108
+ filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initIndexes(prop)));
109
+ filtered.forEach(meta => this.autoWireBidirectionalProperties(meta));
110
+ filtered.forEach(meta => this.findReferencingProperties(meta, filtered));
111
+ filtered.filter(meta => meta.root === meta || !meta.root).forEach(meta => this.setSTIRoot(meta));
112
+ for (const meta of filtered) {
113
+ discovered.push(...this.processEntity(meta));
114
+ }
115
+ discovered.forEach(meta => meta.sync(true));
116
+ const combinedCachePath = this.cache.combine?.();
117
+ // override the path in the options, so we can log it from the CLI in `cache:generate` command
118
+ if (combinedCachePath) {
119
+ this.config.get('metadataCache').combined = combinedCachePath;
120
+ }
121
+ filtered.filter(meta => meta.root === meta || !meta.root).forEach(meta => this.setSTIRoot(meta));
122
+ return discovered.map(meta => this.metadata.get(meta.className));
123
+ }
124
+ findEntities(preferTsNode, sync = false) {
125
+ this.discovered.length = 0;
126
+ const options = this.config.get('discovery');
127
+ const key = (preferTsNode && this.config.get('tsNode', Utils_1.Utils.detectTsNode()) && this.config.get('entitiesTs').length > 0) ? 'entitiesTs' : 'entities';
128
+ const paths = this.config.get(key).filter(item => Utils_1.Utils.isString(item));
129
+ const refs = this.config.get(key).filter(item => !Utils_1.Utils.isString(item));
130
+ if (paths.length > 0) {
131
+ if (sync || options.requireEntitiesArray) {
132
+ throw new Error(`[requireEntitiesArray] Explicit list of entities is required, please use the 'entities' option.`);
133
+ }
134
+ return this.discoverDirectories(paths).then(() => {
135
+ this.discoverReferences(refs);
136
+ this.discoverMissingTargets();
137
+ this.validator.validateDiscovered(this.discovered, options);
138
+ return this.discovered;
139
+ });
140
+ }
141
+ this.discoverReferences(refs);
142
+ this.discoverMissingTargets();
143
+ this.validator.validateDiscovered(this.discovered, options);
144
+ return this.discovered;
145
+ }
146
+ discoverMissingTargets() {
147
+ const unwrap = (type) => type
148
+ .replace(/Array<(.*)>/, '$1') // unwrap array
149
+ .replace(/\[]$/, '') // remove array suffix
150
+ .replace(/\((.*)\)/, '$1'); // unwrap union types
151
+ const missing = [];
152
+ this.discovered.forEach(meta => Object.values(meta.properties).forEach(prop => {
153
+ if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && prop.pivotEntity && !this.discovered.find(m => m.className === Utils_1.Utils.className(prop.pivotEntity))) {
154
+ const target = typeof prop.pivotEntity === 'function'
155
+ ? prop.pivotEntity()
156
+ : prop.pivotEntity;
157
+ missing.push(target);
158
+ }
159
+ if (prop.kind !== enums_1.ReferenceKind.SCALAR && !unwrap(prop.type).split(/ ?\| ?/).every(type => this.discovered.find(m => m.className === type))) {
160
+ const target = typeof prop.entity === 'function'
161
+ ? prop.entity()
162
+ : prop.type;
163
+ missing.push(...Utils_1.Utils.asArray(target));
164
+ }
165
+ }));
166
+ if (missing.length > 0) {
167
+ this.tryDiscoverTargets(missing);
168
+ }
169
+ }
170
+ tryDiscoverTargets(targets) {
171
+ for (const target of targets) {
172
+ if (typeof target === 'function' && target.name && !this.metadata.has(target.name)) {
173
+ this.discoverReferences([target]);
174
+ this.discoverMissingTargets();
175
+ }
176
+ }
177
+ }
178
+ async discoverDirectories(paths) {
179
+ paths = paths.map(path => Utils_1.Utils.normalizePath(path));
180
+ const files = await (0, globby_1.default)(paths, { cwd: Utils_1.Utils.normalizePath(this.config.get('baseDir')) });
181
+ this.logger.log('discovery', `- processing ${colors_1.colors.cyan('' + files.length)} files`);
182
+ const found = [];
183
+ for (const filepath of files) {
184
+ const filename = (0, path_1.basename)(filepath);
185
+ if (!filename.match(/\.[cm]?[jt]s$/) ||
186
+ filename.endsWith('.js.map') ||
187
+ filename.match(/\.d\.[cm]?ts/) ||
188
+ filename.startsWith('.') ||
189
+ filename.match(/index\.[cm]?[jt]s$/)) {
190
+ this.logger.log('discovery', `- ignoring file ${filename}`);
191
+ continue;
192
+ }
193
+ const name = this.namingStrategy.getClassName(filename);
194
+ const path = Utils_1.Utils.normalizePath(this.config.get('baseDir'), filepath);
195
+ const targets = await this.getEntityClassOrSchema(path, name);
196
+ for (const target of targets) {
197
+ if (!(target instanceof Function) && !(target instanceof EntitySchema_1.EntitySchema)) {
198
+ this.logger.log('discovery', `- ignoring file ${filename}`);
199
+ continue;
200
+ }
201
+ this.metadata.set(name, Utils_1.Utils.copy(MetadataStorage_1.MetadataStorage.getMetadata(name, path), false));
202
+ const entity = this.prepare(target);
203
+ const schema = this.getSchema(entity);
204
+ const meta = schema.init().meta;
205
+ this.metadata.set(meta.className, meta);
206
+ found.push([entity, path]);
207
+ }
208
+ }
209
+ for (const [entity, path] of found) {
210
+ this.discoverEntity(entity, path);
211
+ }
212
+ }
213
+ discoverReferences(refs) {
214
+ const found = [];
215
+ for (const entity of refs) {
216
+ const schema = this.getSchema(this.prepare(entity));
217
+ const meta = schema.init().meta;
218
+ this.metadata.set(meta.className, meta);
219
+ found.push(entity);
220
+ }
221
+ for (const entity of found) {
222
+ this.discoverEntity(entity);
223
+ }
224
+ // discover parents (base entities) automatically
225
+ for (const meta of Object.values(this.metadata.getAll())) {
226
+ let parent = meta.extends;
227
+ if (parent instanceof EntitySchema_1.EntitySchema && !this.metadata.has(parent.meta.className)) {
228
+ this.discoverReferences([parent]);
229
+ }
230
+ if (!meta.class) {
231
+ continue;
232
+ }
233
+ parent = Object.getPrototypeOf(meta.class);
234
+ if (parent.name !== '' && !this.metadata.has(parent.name)) {
235
+ this.discoverReferences([parent]);
236
+ }
237
+ }
238
+ return this.discovered.filter(meta => found.find(m => m.name === meta.className));
239
+ }
240
+ prepare(entity) {
241
+ if ('schema' in entity && entity.schema instanceof EntitySchema_1.EntitySchema) {
242
+ return entity.schema;
243
+ }
244
+ return entity;
245
+ }
246
+ getSchema(entity) {
247
+ if (entity instanceof EntitySchema_1.EntitySchema) {
248
+ return entity;
249
+ }
250
+ if (EntitySchema_1.EntitySchema.REGISTRY.has(entity)) {
251
+ return EntitySchema_1.EntitySchema.REGISTRY.get(entity);
252
+ }
253
+ const path = entity.__path;
254
+ if (path) {
255
+ const meta = Utils_1.Utils.copy(MetadataStorage_1.MetadataStorage.getMetadata(entity.name, path), false);
256
+ meta.path = Utils_1.Utils.relativePath(path, this.config.get('baseDir'));
257
+ this.metadata.set(entity.name, meta);
258
+ }
259
+ const exists = this.metadata.has(entity.name);
260
+ const meta = this.metadata.get(entity.name, true);
261
+ meta.abstract ??= !(exists && meta.name);
262
+ const schema = EntitySchema_1.EntitySchema.fromMetadata(meta);
263
+ schema.setClass(entity);
264
+ schema.meta.useCache = this.metadataProvider.useCache();
265
+ return schema;
266
+ }
267
+ discoverEntity(entity, path) {
268
+ entity = this.prepare(entity);
269
+ this.logger.log('discovery', `- processing entity ${colors_1.colors.cyan(entity.name)}${colors_1.colors.grey(path ? ` (${path})` : '')}`);
270
+ const schema = this.getSchema(entity);
271
+ const meta = schema.init().meta;
272
+ const root = Utils_1.Utils.getRootEntity(this.metadata, meta);
273
+ this.metadata.set(meta.className, meta);
274
+ schema.meta.path = Utils_1.Utils.relativePath(path || meta.path, this.config.get('baseDir'));
275
+ const cache = meta.useCache && meta.path && this.cache.get(meta.className + (0, path_1.extname)(meta.path));
276
+ if (cache) {
277
+ this.logger.log('discovery', `- using cached metadata for entity ${colors_1.colors.cyan(meta.className)}`);
278
+ this.metadataProvider.loadFromCache(meta, cache);
279
+ meta.root = root;
280
+ this.discovered.push(meta);
281
+ return;
282
+ }
283
+ // infer default value from property initializer early, as the metatadata provide might use some defaults, e.g. string for reflect-metadata
284
+ Utils_1.Utils.values(meta.properties).forEach(prop => this.inferDefaultValue(meta, prop));
285
+ // if the definition is using EntitySchema we still want it to go through the metadata provider to validate no types are missing
286
+ this.metadataProvider.loadEntityMetadata(meta, meta.className);
287
+ if (!meta.collection && meta.name) {
288
+ const entityName = root.discriminatorColumn ? root.name : meta.name;
289
+ meta.collection = this.namingStrategy.classToTableName(entityName);
290
+ }
291
+ delete meta.root; // to allow caching (as root can contain cycles)
292
+ this.saveToCache(meta);
293
+ meta.root = root;
294
+ this.discovered.push(meta);
295
+ }
296
+ saveToCache(meta) {
297
+ if (!meta.useCache) {
298
+ return;
299
+ }
300
+ const copy = Utils_1.Utils.copy(meta, false);
301
+ copy.props
302
+ .filter(prop => types_1.Type.isMappedType(prop.type))
303
+ .forEach(prop => {
304
+ ['type', 'customType']
305
+ .filter(k => types_1.Type.isMappedType(prop[k]))
306
+ .forEach(k => delete prop[k]);
307
+ });
308
+ copy.props
309
+ .filter(prop => prop.default)
310
+ .forEach(prop => {
311
+ const raw = RawQueryFragment_1.RawQueryFragment.getKnownFragment(prop.default);
312
+ if (raw) {
313
+ prop.defaultRaw ??= this.platform.formatQuery(raw.sql, raw.params);
314
+ delete prop.default;
315
+ }
316
+ });
317
+ [
318
+ 'prototype', 'props', 'referencingProperties', 'propertyOrder', 'relations',
319
+ 'concurrencyCheckKeys', 'checks',
320
+ ].forEach(key => delete copy[key]);
321
+ // base entity without properties might not have path, but nothing to cache there
322
+ if (meta.path) {
323
+ this.cache.set(meta.className + (0, path_1.extname)(meta.path), copy, meta.path);
324
+ }
325
+ }
326
+ initNullability(prop) {
327
+ if (prop.kind === enums_1.ReferenceKind.MANY_TO_ONE) {
328
+ return Utils_1.Utils.defaultValue(prop, 'nullable', prop.optional || prop.cascade.includes(enums_1.Cascade.REMOVE) || prop.cascade.includes(enums_1.Cascade.ALL));
329
+ }
330
+ if (prop.kind === enums_1.ReferenceKind.ONE_TO_ONE) {
331
+ return Utils_1.Utils.defaultValue(prop, 'nullable', prop.optional || !prop.owner || prop.cascade.includes(enums_1.Cascade.REMOVE) || prop.cascade.includes(enums_1.Cascade.ALL));
332
+ }
333
+ return Utils_1.Utils.defaultValue(prop, 'nullable', prop.optional);
334
+ }
335
+ applyNamingStrategy(meta, prop) {
336
+ if (!prop.fieldNames) {
337
+ this.initFieldName(prop);
338
+ }
339
+ if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY) {
340
+ this.initManyToManyFields(meta, prop);
341
+ }
342
+ if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
343
+ this.initManyToOneFields(prop);
344
+ }
345
+ if (prop.kind === enums_1.ReferenceKind.ONE_TO_MANY) {
346
+ this.initOneToManyFields(prop);
347
+ }
348
+ }
349
+ initFieldName(prop, object = false) {
350
+ if (prop.fieldNames && prop.fieldNames.length > 0) {
351
+ return;
352
+ }
353
+ if (prop.kind === enums_1.ReferenceKind.SCALAR || prop.kind === enums_1.ReferenceKind.EMBEDDED) {
354
+ prop.fieldNames = [this.namingStrategy.propertyToColumnName(prop.name, object)];
355
+ }
356
+ else if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
357
+ prop.fieldNames = this.initManyToOneFieldName(prop, prop.name);
358
+ }
359
+ else if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && prop.owner) {
360
+ prop.fieldNames = this.initManyToManyFieldName(prop, prop.name);
361
+ }
362
+ }
363
+ initManyToOneFieldName(prop, name) {
364
+ const meta2 = this.metadata.get(prop.type);
365
+ const ret = [];
366
+ for (const primaryKey of meta2.primaryKeys) {
367
+ this.initFieldName(meta2.properties[primaryKey]);
368
+ for (const fieldName of meta2.properties[primaryKey].fieldNames) {
369
+ ret.push(this.namingStrategy.joinKeyColumnName(name, fieldName, meta2.compositePK));
370
+ }
371
+ }
372
+ return ret;
373
+ }
374
+ initManyToManyFieldName(prop, name) {
375
+ const meta2 = this.metadata.get(prop.type);
376
+ return meta2.primaryKeys.map(() => this.namingStrategy.propertyToColumnName(name));
377
+ }
378
+ initManyToManyFields(meta, prop) {
379
+ const meta2 = this.metadata.get(prop.type);
380
+ Utils_1.Utils.defaultValue(prop, 'fixedOrder', !!prop.fixedOrderColumn);
381
+ const pivotMeta = this.metadata.find(prop.pivotEntity);
382
+ const props = Object.values(pivotMeta?.properties ?? {});
383
+ const pks = props.filter(p => p.primary);
384
+ const fks = props.filter(p => p.kind === enums_1.ReferenceKind.MANY_TO_ONE);
385
+ if (pivotMeta) {
386
+ pivotMeta.pivotTable = true;
387
+ prop.pivotTable = pivotMeta.tableName;
388
+ if (pks.length === 1) {
389
+ prop.fixedOrder = true;
390
+ prop.fixedOrderColumn = pks[0].name;
391
+ }
392
+ }
393
+ if (pivotMeta && (pks.length === 2 || fks.length >= 2)) {
394
+ const owner = prop.mappedBy ? meta2.properties[prop.mappedBy] : prop;
395
+ const [first, second] = this.ensureCorrectFKOrderInPivotEntity(pivotMeta, owner);
396
+ prop.joinColumns = first.fieldNames;
397
+ prop.inverseJoinColumns = second.fieldNames;
398
+ }
399
+ if (!prop.pivotTable && prop.owner && this.platform.usesPivotTable()) {
400
+ prop.pivotTable = this.namingStrategy.joinTableName(meta.tableName, meta2.tableName, prop.name);
401
+ }
402
+ if (prop.mappedBy) {
403
+ const prop2 = meta2.properties[prop.mappedBy];
404
+ this.initManyToManyFields(meta2, prop2);
405
+ prop.pivotTable = prop2.pivotTable;
406
+ prop.pivotEntity = prop2.pivotEntity ?? prop2.pivotTable;
407
+ prop.fixedOrder = prop2.fixedOrder;
408
+ prop.fixedOrderColumn = prop2.fixedOrderColumn;
409
+ prop.joinColumns = prop2.inverseJoinColumns;
410
+ prop.inverseJoinColumns = prop2.joinColumns;
411
+ }
412
+ if (!prop.referencedColumnNames) {
413
+ prop.referencedColumnNames = Utils_1.Utils.flatten(meta.primaryKeys.map(primaryKey => meta.properties[primaryKey].fieldNames));
414
+ }
415
+ if (!prop.joinColumns) {
416
+ prop.joinColumns = prop.referencedColumnNames.map(referencedColumnName => this.namingStrategy.joinKeyColumnName(meta.className, referencedColumnName, meta.compositePK));
417
+ }
418
+ if (!prop.inverseJoinColumns) {
419
+ const meta2 = this.metadata.get(prop.type);
420
+ prop.inverseJoinColumns = this.initManyToOneFieldName(prop, meta2.className);
421
+ }
422
+ }
423
+ initManyToOneFields(prop) {
424
+ const meta2 = this.metadata.get(prop.type);
425
+ const fieldNames = Utils_1.Utils.flatten(meta2.primaryKeys.map(primaryKey => meta2.properties[primaryKey].fieldNames));
426
+ Utils_1.Utils.defaultValue(prop, 'referencedTableName', meta2.collection);
427
+ if (!prop.joinColumns) {
428
+ prop.joinColumns = fieldNames.map(fieldName => this.namingStrategy.joinKeyColumnName(prop.name, fieldName, fieldNames.length > 1));
429
+ }
430
+ if (!prop.referencedColumnNames) {
431
+ prop.referencedColumnNames = fieldNames;
432
+ }
433
+ }
434
+ initOneToManyFields(prop) {
435
+ const meta2 = this.metadata.get(prop.type);
436
+ if (!prop.joinColumns) {
437
+ prop.joinColumns = [this.namingStrategy.joinColumnName(prop.name)];
438
+ }
439
+ if (!prop.referencedColumnNames) {
440
+ meta2.getPrimaryProps().forEach(pk => this.applyNamingStrategy(meta2, pk));
441
+ prop.referencedColumnNames = Utils_1.Utils.flatten(meta2.getPrimaryProps().map(pk => pk.fieldNames));
442
+ }
443
+ }
444
+ processEntity(meta) {
445
+ const pks = Object.values(meta.properties).filter(prop => prop.primary);
446
+ meta.primaryKeys = pks.map(prop => prop.name);
447
+ meta.compositePK = pks.length > 1;
448
+ // FK used as PK, we need to cascade
449
+ if (pks.length === 1 && pks[0].kind !== enums_1.ReferenceKind.SCALAR) {
450
+ pks[0].deleteRule ??= 'cascade';
451
+ }
452
+ meta.forceConstructor = this.shouldForceConstructorUsage(meta);
453
+ this.validator.validateEntityDefinition(this.metadata, meta.className, this.config.get('discovery'));
454
+ for (const prop of Object.values(meta.properties)) {
455
+ this.initNullability(prop);
456
+ this.applyNamingStrategy(meta, prop);
457
+ this.initDefaultValue(prop);
458
+ this.inferTypeFromDefault(prop);
459
+ this.initVersionProperty(meta, prop);
460
+ this.initCustomType(meta, prop);
461
+ this.initColumnType(prop);
462
+ this.initRelation(prop);
463
+ }
464
+ meta.simplePK = pks.length === 1 && pks[0].kind === enums_1.ReferenceKind.SCALAR && !pks[0].customType;
465
+ meta.serializedPrimaryKey = this.platform.getSerializedPrimaryKeyField(meta.primaryKeys[0]);
466
+ const serializedPKProp = meta.properties[meta.serializedPrimaryKey];
467
+ if (serializedPKProp && meta.serializedPrimaryKey !== meta.primaryKeys[0]) {
468
+ serializedPKProp.persist = false;
469
+ }
470
+ if (this.platform.usesPivotTable()) {
471
+ return Object.values(meta.properties)
472
+ .filter(prop => prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && prop.owner && prop.pivotTable)
473
+ .map(prop => this.definePivotTableEntity(meta, prop));
474
+ }
475
+ return [];
476
+ }
477
+ findReferencingProperties(meta, metadata) {
478
+ for (const meta2 of metadata) {
479
+ const prop2 = meta2.relations.find(prop2 => {
480
+ return prop2.kind !== enums_1.ReferenceKind.SCALAR && prop2.type === meta.className;
481
+ });
482
+ if (prop2) {
483
+ meta.referencingProperties.push({ meta: meta2, prop: prop2 });
484
+ }
485
+ }
486
+ }
487
+ initFactoryField(meta, prop) {
488
+ ['mappedBy', 'inversedBy', 'pivotEntity'].forEach(type => {
489
+ const value = prop[type];
490
+ if (value instanceof Function) {
491
+ const meta2 = this.metadata.get(prop.type);
492
+ prop[type] = value(meta2.properties)?.name;
493
+ if (prop[type] == null) {
494
+ throw errors_1.MetadataError.fromWrongReference(meta, prop, type);
495
+ }
496
+ }
497
+ });
498
+ }
499
+ ensureCorrectFKOrderInPivotEntity(meta, owner) {
500
+ const pks = Object.values(meta.properties).filter(p => p.primary);
501
+ const fks = Object.values(meta.properties).filter(p => p.kind === enums_1.ReferenceKind.MANY_TO_ONE);
502
+ let first, second;
503
+ if (pks.length === 2) {
504
+ [first, second] = pks;
505
+ }
506
+ else if (fks.length >= 2) {
507
+ [first, second] = fks;
508
+ }
509
+ else {
510
+ /* istanbul ignore next */
511
+ return [];
512
+ }
513
+ // wrong FK order, first FK needs to point to the owning side
514
+ // (note that we can detect this only if the FKs target different types)
515
+ if (owner.type === first.type && first.type !== second.type) {
516
+ delete meta.properties[first.name];
517
+ meta.removeProperty(first.name, false);
518
+ meta.addProperty(first);
519
+ [first, second] = [second, first];
520
+ }
521
+ return [first, second];
522
+ }
523
+ definePivotTableEntity(meta, prop) {
524
+ const pivotMeta = this.metadata.find(prop.pivotEntity);
525
+ // ensure inverse side exists so we can join it when populating via pivot tables
526
+ if (!prop.inversedBy && prop.targetMeta) {
527
+ const inverseName = `${meta.className}_${prop.name}__inverse`;
528
+ prop.inversedBy = inverseName;
529
+ const inverseProp = {
530
+ name: inverseName,
531
+ kind: enums_1.ReferenceKind.MANY_TO_MANY,
532
+ type: meta.className,
533
+ mappedBy: prop.name,
534
+ pivotEntity: prop.pivotEntity,
535
+ pivotTable: prop.pivotTable,
536
+ persist: false,
537
+ hydrate: false,
538
+ };
539
+ this.applyNamingStrategy(prop.targetMeta, inverseProp);
540
+ this.initCustomType(prop.targetMeta, inverseProp);
541
+ this.initRelation(inverseProp);
542
+ prop.targetMeta.properties[inverseName] = inverseProp;
543
+ }
544
+ if (pivotMeta) {
545
+ this.ensureCorrectFKOrderInPivotEntity(pivotMeta, prop);
546
+ return pivotMeta;
547
+ }
548
+ let tableName = prop.pivotTable;
549
+ let schemaName;
550
+ if (prop.pivotTable.includes('.')) {
551
+ [schemaName, tableName] = prop.pivotTable.split('.');
552
+ }
553
+ schemaName ??= meta.schema;
554
+ const targetType = prop.targetMeta.className;
555
+ const data = new typings_1.EntityMetadata({
556
+ name: prop.pivotTable,
557
+ className: prop.pivotTable,
558
+ collection: tableName,
559
+ schema: schemaName,
560
+ pivotTable: true,
561
+ });
562
+ prop.pivotEntity = data.className;
563
+ if (prop.fixedOrder) {
564
+ const primaryProp = this.defineFixedOrderProperty(prop, targetType);
565
+ data.properties[primaryProp.name] = primaryProp;
566
+ }
567
+ else {
568
+ data.compositePK = true;
569
+ }
570
+ // handle self-referenced m:n with same default field names
571
+ if (meta.name === targetType && prop.joinColumns.every((joinColumn, idx) => joinColumn === prop.inverseJoinColumns[idx])) {
572
+ prop.joinColumns = prop.referencedColumnNames.map(name => this.namingStrategy.joinKeyColumnName(meta.className + '_1', name, meta.compositePK));
573
+ prop.inverseJoinColumns = prop.referencedColumnNames.map(name => this.namingStrategy.joinKeyColumnName(meta.className + '_2', name, meta.compositePK));
574
+ if (prop.inversedBy) {
575
+ const prop2 = this.metadata.get(targetType).properties[prop.inversedBy];
576
+ prop2.inverseJoinColumns = prop.joinColumns;
577
+ prop2.joinColumns = prop.inverseJoinColumns;
578
+ }
579
+ }
580
+ data.properties[meta.name + '_owner'] = this.definePivotProperty(prop, meta.name + '_owner', meta.className, targetType + '_inverse', true);
581
+ data.properties[targetType + '_inverse'] = this.definePivotProperty(prop, targetType + '_inverse', targetType, meta.name + '_owner', false);
582
+ return this.metadata.set(data.className, data);
583
+ }
584
+ defineFixedOrderProperty(prop, targetType) {
585
+ const pk = prop.fixedOrderColumn || this.namingStrategy.referenceColumnName();
586
+ const primaryProp = {
587
+ name: pk,
588
+ type: 'number',
589
+ kind: enums_1.ReferenceKind.SCALAR,
590
+ primary: true,
591
+ autoincrement: true,
592
+ unsigned: this.platform.supportsUnsigned(),
593
+ };
594
+ this.initFieldName(primaryProp);
595
+ this.initColumnType(primaryProp);
596
+ prop.fixedOrderColumn = pk;
597
+ if (prop.inversedBy) {
598
+ const prop2 = this.metadata.get(targetType).properties[prop.inversedBy];
599
+ prop2.fixedOrder = true;
600
+ prop2.fixedOrderColumn = pk;
601
+ }
602
+ return primaryProp;
603
+ }
604
+ definePivotProperty(prop, name, type, inverse, owner) {
605
+ const ret = {
606
+ name,
607
+ type,
608
+ kind: enums_1.ReferenceKind.MANY_TO_ONE,
609
+ cascade: [enums_1.Cascade.ALL],
610
+ fixedOrder: prop.fixedOrder,
611
+ fixedOrderColumn: prop.fixedOrderColumn,
612
+ index: this.platform.indexForeignKeys(),
613
+ primary: !prop.fixedOrder,
614
+ autoincrement: false,
615
+ };
616
+ const meta = this.metadata.get(type);
617
+ ret.targetMeta = meta;
618
+ ret.joinColumns = [];
619
+ ret.inverseJoinColumns = [];
620
+ const schema = meta.schema ?? this.config.get('schema') ?? this.platform.getDefaultSchemaName();
621
+ ret.referencedTableName = schema && schema !== '*' ? schema + '.' + meta.tableName : meta.tableName;
622
+ if (owner) {
623
+ ret.owner = true;
624
+ ret.inversedBy = inverse;
625
+ ret.referencedColumnNames = prop.referencedColumnNames;
626
+ ret.fieldNames = ret.joinColumns = prop.joinColumns;
627
+ ret.inverseJoinColumns = prop.referencedColumnNames;
628
+ meta.primaryKeys.forEach(primaryKey => {
629
+ const prop2 = meta.properties[primaryKey];
630
+ ret.length = prop2.length;
631
+ ret.precision = prop2.precision;
632
+ ret.scale = prop2.scale;
633
+ });
634
+ }
635
+ else {
636
+ ret.owner = false;
637
+ ret.mappedBy = inverse;
638
+ ret.fieldNames = ret.joinColumns = prop.inverseJoinColumns;
639
+ ret.referencedColumnNames = [];
640
+ ret.inverseJoinColumns = [];
641
+ meta.primaryKeys.forEach(primaryKey => {
642
+ const prop2 = meta.properties[primaryKey];
643
+ ret.referencedColumnNames.push(...prop2.fieldNames);
644
+ ret.inverseJoinColumns.push(...prop2.fieldNames);
645
+ ret.length = prop2.length;
646
+ ret.precision = prop2.precision;
647
+ ret.scale = prop2.scale;
648
+ });
649
+ }
650
+ this.initColumnType(ret);
651
+ this.initRelation(ret);
652
+ return ret;
653
+ }
654
+ autoWireBidirectionalProperties(meta) {
655
+ Object.values(meta.properties)
656
+ .filter(prop => prop.kind !== enums_1.ReferenceKind.SCALAR && !prop.owner && prop.mappedBy)
657
+ .forEach(prop => {
658
+ const meta2 = this.metadata.get(prop.type);
659
+ const prop2 = meta2.properties[prop.mappedBy];
660
+ if (prop2 && !prop2.inversedBy) {
661
+ prop2.inversedBy = prop.name;
662
+ }
663
+ });
664
+ }
665
+ defineBaseEntityProperties(meta) {
666
+ const base = meta.extends && this.metadata.get(Utils_1.Utils.className(meta.extends));
667
+ if (!base || base === meta) { // make sure we do not fall into infinite loop
668
+ return 0;
669
+ }
670
+ let order = this.defineBaseEntityProperties(base);
671
+ const ownProps = Object.values(meta.properties);
672
+ const old = ownProps.map(x => x.name);
673
+ meta.properties = {};
674
+ Object.values(base.properties).forEach(prop => {
675
+ if (!prop.inherited) {
676
+ meta.properties[prop.name] = prop;
677
+ }
678
+ });
679
+ ownProps.forEach(prop => meta.properties[prop.name] = prop);
680
+ meta.filters = { ...base.filters, ...meta.filters };
681
+ if (!meta.discriminatorValue) {
682
+ Object.values(base.properties).filter(prop => !old.includes(prop.name)).forEach(prop => {
683
+ meta.properties[prop.name] = { ...prop };
684
+ meta.propertyOrder.set(prop.name, (order += 0.01));
685
+ });
686
+ }
687
+ meta.indexes = Utils_1.Utils.unique([...base.indexes, ...meta.indexes]);
688
+ meta.uniques = Utils_1.Utils.unique([...base.uniques, ...meta.uniques]);
689
+ const pks = Object.values(meta.properties).filter(p => p.primary).map(p => p.name);
690
+ if (pks.length > 0 && meta.primaryKeys.length === 0) {
691
+ meta.primaryKeys = pks;
692
+ }
693
+ Utils_1.Utils.keys(base.hooks).forEach(type => {
694
+ meta.hooks[type] = Utils_1.Utils.unique([...base.hooks[type], ...(meta.hooks[type] || [])]);
695
+ });
696
+ if (meta.constructorParams.length === 0 && base.constructorParams.length > 0) {
697
+ meta.constructorParams = [...base.constructorParams];
698
+ }
699
+ if (meta.toJsonParams.length === 0 && base.toJsonParams.length > 0) {
700
+ meta.toJsonParams = [...base.toJsonParams];
701
+ }
702
+ return order;
703
+ }
704
+ initPolyEmbeddables(embeddedProp, discovered, visited = new Set()) {
705
+ if (embeddedProp.kind !== enums_1.ReferenceKind.EMBEDDED || visited.has(embeddedProp)) {
706
+ return;
707
+ }
708
+ visited.add(embeddedProp);
709
+ const types = embeddedProp.type.split(/ ?\| ?/);
710
+ let embeddable = this.discovered.find(m => m.name === embeddedProp.type);
711
+ const polymorphs = this.discovered.filter(m => types.includes(m.name));
712
+ // create virtual polymorphic entity
713
+ if (!embeddable && polymorphs.length > 0) {
714
+ const properties = {};
715
+ let discriminatorColumn;
716
+ const processExtensions = (meta) => {
717
+ const parent = this.discovered.find(m => {
718
+ return meta.extends && Utils_1.Utils.className(meta.extends) === m.className;
719
+ });
720
+ if (!parent) {
721
+ return;
722
+ }
723
+ discriminatorColumn ??= parent.discriminatorColumn;
724
+ Object.values(parent.properties).forEach(prop => properties[prop.name] = prop);
725
+ processExtensions(parent);
726
+ };
727
+ polymorphs.forEach(meta => {
728
+ Object.values(meta.properties).forEach(prop => properties[prop.name] = prop);
729
+ processExtensions(meta);
730
+ });
731
+ const name = polymorphs.map(t => t.className).sort().join(' | ');
732
+ embeddable = new typings_1.EntityMetadata({
733
+ name,
734
+ className: name,
735
+ embeddable: true,
736
+ abstract: true,
737
+ properties,
738
+ polymorphs,
739
+ discriminatorColumn,
740
+ });
741
+ embeddable.sync();
742
+ discovered.push(embeddable);
743
+ polymorphs.forEach(meta => meta.root = embeddable);
744
+ }
745
+ }
746
+ initEmbeddables(meta, embeddedProp, visited = new Set()) {
747
+ if (embeddedProp.kind !== enums_1.ReferenceKind.EMBEDDED || visited.has(embeddedProp)) {
748
+ return;
749
+ }
750
+ visited.add(embeddedProp);
751
+ const embeddable = this.discovered.find(m => m.name === embeddedProp.type);
752
+ if (!embeddable) {
753
+ throw errors_1.MetadataError.fromUnknownEntity(embeddedProp.type, `${meta.className}.${embeddedProp.name}`);
754
+ }
755
+ embeddedProp.embeddable = embeddable.class;
756
+ embeddedProp.embeddedProps = {};
757
+ let order = meta.propertyOrder.get(embeddedProp.name);
758
+ const getRootProperty = (prop) => prop.embedded ? getRootProperty(meta.properties[prop.embedded[0]]) : prop;
759
+ const isParentObject = (prop) => {
760
+ if (prop.object || prop.array) {
761
+ return true;
762
+ }
763
+ return prop.embedded ? isParentObject(meta.properties[prop.embedded[0]]) : false;
764
+ };
765
+ const rootProperty = getRootProperty(embeddedProp);
766
+ const object = isParentObject(embeddedProp);
767
+ this.initFieldName(embeddedProp, rootProperty !== embeddedProp && object);
768
+ const prefix = embeddedProp.prefix === false ? '' : embeddedProp.prefix === true ? embeddedProp.embeddedPath?.join('_') ?? embeddedProp.fieldNames[0] + '_' : embeddedProp.prefix;
769
+ for (const prop of Object.values(embeddable.properties).filter(p => p.persist !== false)) {
770
+ const name = (embeddedProp.embeddedPath?.join('_') ?? embeddedProp.fieldNames[0] + '_') + prop.name;
771
+ meta.properties[name] = Utils_1.Utils.copy(prop, false);
772
+ meta.properties[name].name = name;
773
+ meta.properties[name].embedded = [embeddedProp.name, prop.name];
774
+ meta.propertyOrder.set(name, (order += 0.01));
775
+ embeddedProp.embeddedProps[prop.name] = meta.properties[name];
776
+ if (embeddedProp.nullable) {
777
+ meta.properties[name].nullable = true;
778
+ }
779
+ if (meta.properties[name].fieldNames) {
780
+ meta.properties[name].fieldNames[0] = prefix + meta.properties[name].fieldNames[0];
781
+ }
782
+ else {
783
+ const name2 = meta.properties[name].name;
784
+ meta.properties[name].name = prefix + prop.name;
785
+ this.initFieldName(meta.properties[name]);
786
+ meta.properties[name].name = name2;
787
+ }
788
+ if (object) {
789
+ embeddedProp.object = true;
790
+ let path = [];
791
+ let tmp = embeddedProp;
792
+ while (tmp.embedded && tmp.object) {
793
+ path.unshift(tmp.embedded[1]);
794
+ tmp = meta.properties[tmp.embedded[0]];
795
+ }
796
+ if (tmp === rootProperty) {
797
+ path.unshift(rootProperty.fieldNames[0]);
798
+ }
799
+ else if (embeddedProp.embeddedPath) {
800
+ path = [...embeddedProp.embeddedPath];
801
+ }
802
+ else {
803
+ path = [embeddedProp.fieldNames[0]];
804
+ }
805
+ this.initFieldName(prop, true);
806
+ path.push(prop.fieldNames[0]);
807
+ meta.properties[name].fieldNames = prop.fieldNames;
808
+ meta.properties[name].embeddedPath = path;
809
+ const fieldName = (0, RawQueryFragment_1.raw)(this.platform.getSearchJsonPropertySQL(path.join('->'), prop.runtimeType ?? prop.type, true));
810
+ meta.properties[name].fieldNameRaw = fieldName.sql; // for querying in SQL drivers
811
+ meta.properties[name].persist = false; // only virtual as we store the whole object
812
+ meta.properties[name].userDefined = false; // mark this as a generated/internal property, so we can distinguish from user-defined non-persist properties
813
+ meta.properties[name].object = true;
814
+ }
815
+ this.initEmbeddables(meta, meta.properties[name], visited);
816
+ }
817
+ for (const index of embeddable.indexes) {
818
+ meta.indexes.push({
819
+ ...index,
820
+ properties: Utils_1.Utils.asArray(index.properties).map(p => {
821
+ return embeddedProp.embeddedProps[p].name;
822
+ }),
823
+ });
824
+ }
825
+ for (const unique of embeddable.uniques) {
826
+ meta.uniques.push({
827
+ ...unique,
828
+ properties: Utils_1.Utils.asArray(unique.properties).map(p => {
829
+ return embeddedProp.embeddedProps[p].name;
830
+ }),
831
+ });
832
+ }
833
+ }
834
+ initSingleTableInheritance(meta, metadata) {
835
+ if (meta.root !== meta && !meta.__processed) {
836
+ meta.root = metadata.find(m => m.className === meta.root.className);
837
+ meta.root.__processed = true;
838
+ if (!meta.root.stiChildren) {
839
+ meta.root.stiChildren = [];
840
+ }
841
+ meta.root.stiChildren.push(meta);
842
+ }
843
+ else {
844
+ delete meta.root.__processed;
845
+ }
846
+ if (!meta.root.discriminatorColumn) {
847
+ return;
848
+ }
849
+ if (!meta.root.discriminatorMap) {
850
+ meta.root.discriminatorMap = {};
851
+ const children = metadata.filter(m => m.root.className === meta.root.className && !m.abstract);
852
+ children.forEach(m => {
853
+ const name = m.discriminatorValue ?? this.namingStrategy.classToTableName(m.className);
854
+ meta.root.discriminatorMap[name] = m.className;
855
+ });
856
+ }
857
+ meta.discriminatorValue = Object.entries(meta.root.discriminatorMap).find(([, className]) => className === meta.className)?.[0];
858
+ if (!meta.root.properties[meta.root.discriminatorColumn]) {
859
+ this.createDiscriminatorProperty(meta.root);
860
+ }
861
+ Utils_1.Utils.defaultValue(meta.root.properties[meta.root.discriminatorColumn], 'items', Object.keys(meta.root.discriminatorMap));
862
+ Utils_1.Utils.defaultValue(meta.root.properties[meta.root.discriminatorColumn], 'index', true);
863
+ if (meta.root === meta) {
864
+ return;
865
+ }
866
+ // Object.values(meta.properties).forEach(prop => {
867
+ // const exists = meta.root.properties[prop.name];
868
+ // prop = Utils.copy(prop, false);
869
+ // prop.nullable = true;
870
+ // if (!exists) {
871
+ // prop.inherited = true;
872
+ // }
873
+ // meta.root.addProperty(prop);
874
+ // });
875
+ meta.collection = meta.root.collection;
876
+ // meta.root.indexes = Utils.unique([...meta.root.indexes, ...meta.indexes]);
877
+ // meta.root.uniques = Utils.unique([...meta.root.uniques, ...meta.uniques]);
878
+ }
879
+ setSTIRoot(metadata) {
880
+ // const stiRoot = metadata.root.stiRoot ?? Utils.copy(metadata.root, false);
881
+ const stiRoot = Object.assign(Object.create(Object.getPrototypeOf(metadata.root)), metadata.root);
882
+ metadata.root.stiRoot = stiRoot;
883
+ const children = metadata.root.stiChildren;
884
+ if (children.length === 0) {
885
+ return;
886
+ }
887
+ for (const child of children) {
888
+ child.stiRoot = stiRoot;
889
+ Object.values(child.properties).forEach((prop) => {
890
+ const exists = stiRoot.properties[prop.name];
891
+ prop = Object.assign(Object.create(Object.getPrototypeOf(prop)), prop);
892
+ prop.nullable = !(prop.name in metadata.root.properties) ? true : prop.nullable ? true : metadata.root.properties[prop.name].nullable;
893
+ // prop.nullable = true;
894
+ if (!exists) {
895
+ prop.inherited = true;
896
+ }
897
+ stiRoot.addProperty(prop);
898
+ });
899
+ stiRoot.indexes = Utils_1.Utils.unique([...stiRoot.indexes, ...child.indexes]);
900
+ stiRoot.uniques = Utils_1.Utils.unique([...stiRoot.uniques, ...child.uniques]);
901
+ }
902
+ }
903
+ createDiscriminatorProperty(meta) {
904
+ meta.addProperty({
905
+ name: meta.discriminatorColumn,
906
+ type: 'string',
907
+ enum: true,
908
+ kind: enums_1.ReferenceKind.SCALAR,
909
+ userDefined: false,
910
+ });
911
+ }
912
+ initAutoincrement(meta) {
913
+ const pks = meta.getPrimaryProps();
914
+ if (pks.length === 1 && this.isNumericProperty(pks[0])) {
915
+ /* istanbul ignore next */
916
+ pks[0].autoincrement ??= true;
917
+ }
918
+ }
919
+ initCheckConstraints(meta) {
920
+ const map = this.createColumnMappingObject(meta);
921
+ for (const check of meta.checks) {
922
+ const columns = check.property ? meta.properties[check.property].fieldNames : [];
923
+ check.name ??= this.namingStrategy.indexName(meta.tableName, columns, 'check');
924
+ if (check.expression instanceof Function) {
925
+ check.expression = check.expression(map);
926
+ }
927
+ }
928
+ }
929
+ initGeneratedColumn(meta, prop) {
930
+ if (!prop.generated && prop.columnTypes) {
931
+ const match = prop.columnTypes[0].match(/(.*) generated always as (.*)/);
932
+ if (match) {
933
+ prop.columnTypes[0] = match[1];
934
+ prop.generated = match[2];
935
+ }
936
+ return;
937
+ }
938
+ const map = this.createColumnMappingObject(meta);
939
+ if (prop.generated instanceof Function) {
940
+ prop.generated = prop.generated(map);
941
+ }
942
+ }
943
+ createColumnMappingObject(meta) {
944
+ return Object.values(meta.properties).reduce((o, prop) => {
945
+ if (prop.fieldNames) {
946
+ o[prop.name] = prop.fieldNames[0];
947
+ }
948
+ return o;
949
+ }, {});
950
+ }
951
+ getDefaultVersionValue(prop) {
952
+ if (typeof prop.defaultRaw !== 'undefined') {
953
+ return prop.defaultRaw;
954
+ }
955
+ /* istanbul ignore next */
956
+ if (prop.default != null) {
957
+ return '' + this.platform.quoteVersionValue(prop.default, prop);
958
+ }
959
+ if (prop.type.toLowerCase() === 'date') {
960
+ prop.length ??= this.platform.getDefaultVersionLength();
961
+ return this.platform.getCurrentTimestampSQL(prop.length);
962
+ }
963
+ return '1';
964
+ }
965
+ inferDefaultValue(meta, prop) {
966
+ /* istanbul ignore next */
967
+ if (!meta.class) {
968
+ return;
969
+ }
970
+ try {
971
+ // try to create two entity instances to detect the value is stable
972
+ const now = Date.now();
973
+ const entity1 = new meta.class();
974
+ const entity2 = new meta.class();
975
+ // we compare the two values by reference, this will discard things like `new Date()` or `Date.now()`
976
+ if (this.config.get('discovery').inferDefaultValues && prop.default === undefined && entity1[prop.name] != null && entity1[prop.name] === entity2[prop.name] && entity1[prop.name] !== now) {
977
+ prop.default ??= entity1[prop.name];
978
+ }
979
+ // if the default value is null, infer nullability
980
+ if (entity1[prop.name] === null) {
981
+ prop.nullable ??= true;
982
+ }
983
+ // but still use object values for type inference if not explicitly set, e.g. `createdAt = new Date()`
984
+ if (prop.kind === enums_1.ReferenceKind.SCALAR && prop.type == null && entity1[prop.name] != null) {
985
+ prop.type = Utils_1.Utils.getObjectType(entity1[prop.name]);
986
+ }
987
+ }
988
+ catch {
989
+ // ignore
990
+ }
991
+ }
992
+ initDefaultValue(prop) {
993
+ if (prop.defaultRaw || !('default' in prop)) {
994
+ return;
995
+ }
996
+ let val = prop.default;
997
+ const raw = RawQueryFragment_1.RawQueryFragment.getKnownFragment(val);
998
+ if (raw) {
999
+ prop.defaultRaw = this.platform.formatQuery(raw.sql, raw.params);
1000
+ return;
1001
+ }
1002
+ if (prop.customType instanceof types_1.ArrayType && Array.isArray(prop.default)) {
1003
+ val = prop.customType.convertToDatabaseValue(prop.default, this.platform);
1004
+ }
1005
+ prop.defaultRaw = typeof val === 'string' ? `'${val}'` : '' + val;
1006
+ }
1007
+ inferTypeFromDefault(prop) {
1008
+ if ((prop.defaultRaw == null && prop.default == null) || prop.type !== 'any') {
1009
+ return;
1010
+ }
1011
+ switch (typeof prop.default) {
1012
+ case 'string':
1013
+ prop.type = prop.runtimeType = 'string';
1014
+ break;
1015
+ case 'number':
1016
+ prop.type = prop.runtimeType = 'number';
1017
+ break;
1018
+ case 'boolean':
1019
+ prop.type = prop.runtimeType = 'boolean';
1020
+ break;
1021
+ }
1022
+ if (prop.defaultRaw?.startsWith('current_timestamp')) {
1023
+ prop.type = prop.runtimeType = 'Date';
1024
+ }
1025
+ }
1026
+ initVersionProperty(meta, prop) {
1027
+ if (prop.version) {
1028
+ this.initDefaultValue(prop);
1029
+ meta.versionProperty = prop.name;
1030
+ prop.defaultRaw = this.getDefaultVersionValue(prop);
1031
+ }
1032
+ if (prop.concurrencyCheck && !prop.primary) {
1033
+ meta.concurrencyCheckKeys.add(prop.name);
1034
+ }
1035
+ }
1036
+ initCustomType(meta, prop) {
1037
+ // `prop.type` might be actually instance of custom type class
1038
+ if (types_1.Type.isMappedType(prop.type) && !prop.customType) {
1039
+ prop.customType = prop.type;
1040
+ prop.type = prop.customType.constructor.name;
1041
+ }
1042
+ // `prop.type` might also be custom type class (not instance), so `typeof MyType` will give us `function`, not `object`
1043
+ if (typeof prop.type === 'function' && types_1.Type.isMappedType(prop.type.prototype) && !prop.customType) {
1044
+ prop.customType = new prop.type();
1045
+ prop.type = prop.customType.constructor.name;
1046
+ }
1047
+ if (!prop.customType && ['json', 'jsonb'].includes(prop.type?.toLowerCase())) {
1048
+ prop.customType = new types_1.JsonType();
1049
+ }
1050
+ if (prop.kind === enums_1.ReferenceKind.SCALAR && !prop.customType && prop.columnTypes && ['json', 'jsonb'].includes(prop.columnTypes[0])) {
1051
+ prop.customType = new types_1.JsonType();
1052
+ }
1053
+ if (!prop.customType && prop.array && prop.items) {
1054
+ prop.customType = new types_1.EnumArrayType(`${meta.className}.${prop.name}`, prop.items);
1055
+ }
1056
+ // for number arrays we make sure to convert the items to numbers
1057
+ if (!prop.customType && prop.type === 'number[]') {
1058
+ prop.customType = new types_1.ArrayType(i => +i);
1059
+ }
1060
+ // `string[]` can be returned via ts-morph, while reflect metadata will give us just `array`
1061
+ if (!prop.customType && (prop.type?.toLowerCase() === 'array' || prop.type?.toString().endsWith('[]'))) {
1062
+ prop.customType = new types_1.ArrayType();
1063
+ }
1064
+ if (!prop.customType && prop.type?.toLowerCase() === 'buffer') {
1065
+ prop.customType = new types_1.BlobType();
1066
+ }
1067
+ if (!prop.customType && prop.type?.toLowerCase() === 'uint8array') {
1068
+ prop.customType = new types_1.Uint8ArrayType();
1069
+ }
1070
+ const mappedType = this.getMappedType(prop);
1071
+ if (prop.fieldNames?.length === 1 && !prop.customType) {
1072
+ [types_1.BigIntType, types_1.DoubleType, types_1.DecimalType, types_1.IntervalType]
1073
+ .filter(type => mappedType instanceof type)
1074
+ .forEach(type => prop.customType = new type());
1075
+ }
1076
+ if (prop.customType && !prop.columnTypes) {
1077
+ const mappedType = this.getMappedType({ columnTypes: [prop.customType.getColumnType(prop, this.platform)] });
1078
+ if (prop.customType.compareAsType() === 'any') {
1079
+ prop.runtimeType ??= mappedType.runtimeType;
1080
+ }
1081
+ else {
1082
+ prop.runtimeType ??= prop.customType.runtimeType;
1083
+ }
1084
+ }
1085
+ else {
1086
+ prop.runtimeType ??= mappedType.runtimeType;
1087
+ }
1088
+ if (prop.customType) {
1089
+ prop.customType.platform = this.platform;
1090
+ prop.customType.meta = meta;
1091
+ prop.customType.prop = prop;
1092
+ prop.columnTypes ??= [prop.customType.getColumnType(prop, this.platform)];
1093
+ prop.hasConvertToJSValueSQL = !!prop.customType.convertToJSValueSQL && prop.customType.convertToJSValueSQL('', this.platform) !== '';
1094
+ prop.hasConvertToDatabaseValueSQL = !!prop.customType.convertToDatabaseValueSQL && prop.customType.convertToDatabaseValueSQL('', this.platform) !== '';
1095
+ if (prop.customType instanceof types_1.BigIntType && ['string', 'bigint', 'number'].includes(prop.runtimeType.toLowerCase())) {
1096
+ prop.customType.mode = prop.runtimeType.toLowerCase();
1097
+ }
1098
+ }
1099
+ if (types_1.Type.isMappedType(prop.customType) && prop.kind === enums_1.ReferenceKind.SCALAR && !prop.type?.toString().endsWith('[]')) {
1100
+ prop.type = prop.customType.name;
1101
+ }
1102
+ if (!prop.customType && [enums_1.ReferenceKind.ONE_TO_ONE, enums_1.ReferenceKind.MANY_TO_ONE].includes(prop.kind) && this.metadata.get(prop.type).compositePK) {
1103
+ prop.customTypes = [];
1104
+ for (const pk of this.metadata.get(prop.type).getPrimaryProps()) {
1105
+ if (pk.customType) {
1106
+ prop.customTypes.push(pk.customType);
1107
+ prop.hasConvertToJSValueSQL ||= !!pk.customType.convertToJSValueSQL && pk.customType.convertToJSValueSQL('', this.platform) !== '';
1108
+ prop.hasConvertToDatabaseValueSQL ||= !!pk.customType.convertToDatabaseValueSQL && pk.customType.convertToDatabaseValueSQL('', this.platform) !== '';
1109
+ }
1110
+ else {
1111
+ prop.customTypes.push(undefined);
1112
+ }
1113
+ }
1114
+ }
1115
+ if (prop.kind === enums_1.ReferenceKind.SCALAR && !(mappedType instanceof types_1.UnknownType)) {
1116
+ prop.columnTypes ??= [mappedType.getColumnType(prop, this.platform)];
1117
+ // use only custom types provided by user, we don't need to use the ones provided by ORM,
1118
+ // with exception for ArrayType and JsonType, those two are handled in
1119
+ if (!Object.values(types_1.t).some(type => type === mappedType.constructor)) {
1120
+ prop.customType ??= mappedType;
1121
+ }
1122
+ }
1123
+ }
1124
+ initRelation(prop) {
1125
+ if (prop.kind === enums_1.ReferenceKind.SCALAR) {
1126
+ return;
1127
+ }
1128
+ const meta2 = this.discovered.find(m => m.className === prop.type);
1129
+ prop.referencedPKs = meta2.primaryKeys;
1130
+ prop.targetMeta = meta2;
1131
+ }
1132
+ initColumnType(prop) {
1133
+ this.initUnsigned(prop);
1134
+ this.metadata.find(prop.type)?.getPrimaryProps().map(pk => {
1135
+ prop.length ??= pk.length;
1136
+ prop.precision ??= pk.precision;
1137
+ prop.scale ??= pk.scale;
1138
+ });
1139
+ if (prop.kind === enums_1.ReferenceKind.SCALAR && (prop.type == null || prop.type === 'object') && prop.columnTypes?.[0]) {
1140
+ delete prop.type;
1141
+ const mappedType = this.getMappedType(prop);
1142
+ prop.type = mappedType.compareAsType();
1143
+ }
1144
+ if (prop.columnTypes || !this.schemaHelper) {
1145
+ return;
1146
+ }
1147
+ if (prop.kind === enums_1.ReferenceKind.SCALAR) {
1148
+ const mappedType = this.getMappedType(prop);
1149
+ prop.columnTypes = [mappedType.getColumnType(prop, this.platform)];
1150
+ return;
1151
+ }
1152
+ if (prop.kind === enums_1.ReferenceKind.EMBEDDED && prop.object && !prop.columnTypes) {
1153
+ prop.columnTypes = [this.platform.getJsonDeclarationSQL()];
1154
+ return;
1155
+ }
1156
+ const targetMeta = this.metadata.get(prop.type);
1157
+ prop.columnTypes = [];
1158
+ for (const pk of targetMeta.getPrimaryProps()) {
1159
+ this.initCustomType(targetMeta, pk);
1160
+ this.initColumnType(pk);
1161
+ const mappedType = this.getMappedType(pk);
1162
+ let columnTypes = pk.columnTypes;
1163
+ if (pk.autoincrement) {
1164
+ columnTypes = [mappedType.getColumnType({ ...pk, autoincrement: false }, this.platform)];
1165
+ }
1166
+ prop.columnTypes.push(...columnTypes);
1167
+ if (!targetMeta.compositePK) {
1168
+ prop.customType = pk.customType;
1169
+ }
1170
+ }
1171
+ }
1172
+ getMappedType(prop) {
1173
+ if (prop.customType) {
1174
+ return prop.customType;
1175
+ }
1176
+ let t = prop.columnTypes?.[0] ?? prop.type;
1177
+ if (prop.nativeEnumName) {
1178
+ t = 'enum';
1179
+ }
1180
+ else if (prop.enum) {
1181
+ t = prop.items?.every(item => Utils_1.Utils.isString(item)) ? 'enum' : 'tinyint';
1182
+ }
1183
+ if (t === 'Date') {
1184
+ t = 'datetime';
1185
+ }
1186
+ return this.platform.getMappedType(t);
1187
+ }
1188
+ initUnsigned(prop) {
1189
+ if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
1190
+ const meta2 = this.metadata.get(prop.type);
1191
+ meta2.primaryKeys.forEach(primaryKey => {
1192
+ const pk = meta2.properties[primaryKey];
1193
+ // if at least one of the target columns is unsigned, we need to mark the property as unsigned
1194
+ prop.unsigned ||= this.platform.supportsUnsigned() && this.isNumericProperty(pk);
1195
+ });
1196
+ return;
1197
+ }
1198
+ prop.unsigned ??= (prop.primary || prop.unsigned) && this.isNumericProperty(prop) && this.platform.supportsUnsigned();
1199
+ }
1200
+ initIndexes(prop) {
1201
+ if (prop.kind === enums_1.ReferenceKind.MANY_TO_ONE && this.platform.indexForeignKeys()) {
1202
+ prop.index ??= true;
1203
+ }
1204
+ }
1205
+ isNumericProperty(prop) {
1206
+ if (prop.customType) {
1207
+ return this.platform.isNumericColumn(prop.customType);
1208
+ }
1209
+ const numericMappedType = prop.columnTypes?.[0] && this.platform.isNumericColumn(this.platform.getMappedType(prop.columnTypes[0]));
1210
+ return numericMappedType || prop.type === 'number' || this.platform.isBigIntProperty(prop);
1211
+ }
1212
+ async getEntityClassOrSchema(path, name) {
1213
+ const exports = await Utils_1.Utils.dynamicImport(path);
1214
+ const targets = Object.values(exports)
1215
+ .filter(item => item instanceof EntitySchema_1.EntitySchema || (item instanceof Function && MetadataStorage_1.MetadataStorage.isKnownEntity(item.name)));
1216
+ // ignore class implementations that are linked from an EntitySchema
1217
+ for (const item of targets) {
1218
+ if (item instanceof EntitySchema_1.EntitySchema) {
1219
+ targets.forEach((item2, idx) => {
1220
+ if (item.meta.class === item2) {
1221
+ targets.splice(idx, 1);
1222
+ }
1223
+ });
1224
+ }
1225
+ }
1226
+ if (targets.length > 0) {
1227
+ return targets;
1228
+ }
1229
+ const target = exports.default ?? exports[name];
1230
+ /* istanbul ignore next */
1231
+ if (!target) {
1232
+ throw errors_1.MetadataError.entityNotFound(name, path.replace(this.config.get('baseDir'), '.'));
1233
+ }
1234
+ return [target];
1235
+ }
1236
+ shouldForceConstructorUsage(meta) {
1237
+ const forceConstructor = this.config.get('forceEntityConstructor');
1238
+ if (Array.isArray(forceConstructor)) {
1239
+ return forceConstructor.some(cls => Utils_1.Utils.className(cls) === meta.className);
1240
+ }
1241
+ return meta.forceConstructor = forceConstructor;
1242
+ }
1243
+ }
1244
+ exports.MetadataDiscovery = MetadataDiscovery;