@mikro-orm/core 7.0.0-dev.1 → 7.0.0-dev.11
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.
- package/EntityManager.d.ts +25 -16
- package/EntityManager.js +219 -209
- package/MikroORM.d.ts +7 -6
- package/MikroORM.js +33 -45
- package/cache/CacheAdapter.js +1 -2
- package/cache/FileCacheAdapter.d.ts +1 -1
- package/cache/FileCacheAdapter.js +18 -26
- package/cache/GeneratedCacheAdapter.d.ts +2 -2
- package/cache/GeneratedCacheAdapter.js +1 -5
- package/cache/MemoryCacheAdapter.d.ts +1 -1
- package/cache/MemoryCacheAdapter.js +1 -5
- package/cache/NullCacheAdapter.d.ts +1 -1
- package/cache/NullCacheAdapter.js +1 -5
- package/cache/index.d.ts +5 -5
- package/cache/index.js +5 -21
- package/connections/Connection.d.ts +7 -7
- package/connections/Connection.js +8 -12
- package/connections/index.d.ts +1 -1
- package/connections/index.js +1 -17
- package/decorators/Check.d.ts +2 -2
- package/decorators/Check.js +5 -8
- package/decorators/CreateRequestContext.d.ts +1 -1
- package/decorators/CreateRequestContext.js +13 -14
- package/decorators/Embeddable.d.ts +5 -5
- package/decorators/Embeddable.js +4 -7
- package/decorators/Embedded.d.ts +3 -3
- package/decorators/Embedded.js +10 -12
- package/decorators/Entity.d.ts +6 -6
- package/decorators/Entity.js +5 -9
- package/decorators/Enum.d.ts +3 -3
- package/decorators/Enum.js +7 -10
- package/decorators/Filter.d.ts +1 -1
- package/decorators/Filter.js +3 -6
- package/decorators/Formula.d.ts +2 -3
- package/decorators/Formula.js +7 -10
- package/decorators/Indexed.d.ts +10 -8
- package/decorators/Indexed.js +7 -11
- package/decorators/ManyToMany.d.ts +4 -4
- package/decorators/ManyToMany.js +10 -12
- package/decorators/ManyToOne.d.ts +4 -4
- package/decorators/ManyToOne.js +10 -12
- package/decorators/OneToMany.d.ts +6 -6
- package/decorators/OneToMany.js +11 -14
- package/decorators/OneToOne.d.ts +4 -4
- package/decorators/OneToOne.js +4 -7
- package/decorators/PrimaryKey.d.ts +3 -4
- package/decorators/PrimaryKey.js +10 -13
- package/decorators/Property.d.ts +6 -6
- package/decorators/Property.js +10 -12
- package/decorators/Transactional.d.ts +2 -2
- package/decorators/Transactional.js +7 -10
- package/decorators/hooks.js +23 -35
- package/decorators/index.d.ts +17 -17
- package/decorators/index.js +17 -36
- package/drivers/DatabaseDriver.d.ts +13 -12
- package/drivers/DatabaseDriver.js +60 -64
- package/drivers/IDatabaseDriver.d.ts +16 -13
- package/drivers/IDatabaseDriver.js +1 -4
- package/drivers/index.d.ts +2 -2
- package/drivers/index.js +2 -18
- package/entity/ArrayCollection.d.ts +3 -3
- package/entity/ArrayCollection.js +38 -35
- package/entity/BaseEntity.d.ts +6 -6
- package/entity/BaseEntity.js +17 -21
- package/entity/Collection.d.ts +6 -7
- package/entity/Collection.js +47 -51
- package/entity/EntityAssigner.d.ts +2 -2
- package/entity/EntityAssigner.js +58 -63
- package/entity/EntityFactory.d.ts +3 -3
- package/entity/EntityFactory.js +62 -63
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +44 -45
- package/entity/EntityIdentifier.d.ts +1 -1
- package/entity/EntityIdentifier.js +1 -5
- package/entity/EntityLoader.d.ts +5 -5
- package/entity/EntityLoader.js +106 -98
- package/entity/EntityRepository.d.ts +7 -7
- package/entity/EntityRepository.js +7 -11
- package/entity/EntityValidator.d.ts +1 -1
- package/entity/EntityValidator.js +25 -29
- package/entity/Reference.d.ts +4 -8
- package/entity/Reference.js +35 -42
- package/entity/WrappedEntity.d.ts +12 -12
- package/entity/WrappedEntity.js +23 -27
- package/entity/index.d.ts +13 -13
- package/entity/index.js +13 -29
- package/entity/utils.d.ts +1 -1
- package/entity/utils.js +9 -12
- package/entity/wrap.d.ts +1 -1
- package/entity/wrap.js +2 -6
- package/enums.d.ts +3 -3
- package/enums.js +37 -41
- package/errors.d.ts +1 -1
- package/errors.js +15 -24
- package/events/EventManager.d.ts +3 -3
- package/events/EventManager.js +8 -12
- package/events/EventSubscriber.d.ts +8 -5
- package/events/EventSubscriber.js +1 -2
- package/events/TransactionEventBroadcaster.d.ts +3 -3
- package/events/TransactionEventBroadcaster.js +1 -5
- package/events/index.d.ts +3 -3
- package/events/index.js +3 -19
- package/exceptions.js +18 -39
- package/hydration/Hydrator.d.ts +5 -5
- package/hydration/Hydrator.js +3 -6
- package/hydration/ObjectHydrator.d.ts +3 -3
- package/hydration/ObjectHydrator.js +26 -28
- package/hydration/index.d.ts +2 -2
- package/hydration/index.js +2 -18
- package/index.d.ts +21 -21
- package/index.js +21 -46
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/DefaultLogger.js +9 -13
- package/logging/Logger.d.ts +1 -1
- package/logging/Logger.js +1 -2
- package/logging/SimpleLogger.d.ts +2 -2
- package/logging/SimpleLogger.js +2 -6
- package/logging/colors.js +1 -5
- package/logging/index.d.ts +4 -4
- package/logging/index.js +4 -20
- package/metadata/EntitySchema.d.ts +14 -6
- package/metadata/EntitySchema.js +41 -45
- package/metadata/MetadataDiscovery.d.ts +7 -7
- package/metadata/MetadataDiscovery.js +181 -180
- package/metadata/MetadataProvider.d.ts +2 -2
- package/metadata/MetadataProvider.js +4 -7
- package/metadata/MetadataStorage.d.ts +2 -2
- package/metadata/MetadataStorage.js +15 -19
- package/metadata/MetadataValidator.d.ts +4 -4
- package/metadata/MetadataValidator.js +52 -55
- package/metadata/ReflectMetadataProvider.d.ts +2 -2
- package/metadata/ReflectMetadataProvider.js +8 -12
- package/metadata/index.d.ts +6 -6
- package/metadata/index.js +6 -22
- package/naming-strategy/AbstractNamingStrategy.d.ts +2 -2
- package/naming-strategy/AbstractNamingStrategy.js +4 -8
- package/naming-strategy/EntityCaseNamingStrategy.d.ts +1 -1
- package/naming-strategy/EntityCaseNamingStrategy.js +2 -6
- package/naming-strategy/MongoNamingStrategy.d.ts +1 -1
- package/naming-strategy/MongoNamingStrategy.js +2 -6
- package/naming-strategy/NamingStrategy.d.ts +1 -1
- package/naming-strategy/NamingStrategy.js +1 -2
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +1 -1
- package/naming-strategy/UnderscoreNamingStrategy.js +2 -6
- package/naming-strategy/index.d.ts +5 -5
- package/naming-strategy/index.js +5 -21
- package/package.json +6 -15
- package/platforms/ExceptionConverter.d.ts +2 -2
- package/platforms/ExceptionConverter.js +4 -8
- package/platforms/Platform.d.ts +10 -10
- package/platforms/Platform.js +57 -61
- package/platforms/index.d.ts +2 -2
- package/platforms/index.js +2 -18
- package/serialization/EntitySerializer.d.ts +2 -2
- package/serialization/EntitySerializer.js +36 -41
- package/serialization/EntityTransformer.d.ts +1 -1
- package/serialization/EntityTransformer.js +27 -31
- package/serialization/SerializationContext.d.ts +2 -2
- package/serialization/SerializationContext.js +10 -14
- package/serialization/index.d.ts +3 -3
- package/serialization/index.js +3 -19
- package/types/ArrayType.d.ts +3 -3
- package/types/ArrayType.js +7 -11
- package/types/BigIntType.d.ts +4 -3
- package/types/BigIntType.js +6 -6
- package/types/BlobType.d.ts +3 -3
- package/types/BlobType.js +2 -8
- package/types/BooleanType.d.ts +3 -3
- package/types/BooleanType.js +2 -6
- package/types/CharacterType.d.ts +3 -3
- package/types/CharacterType.js +2 -6
- package/types/DateTimeType.d.ts +3 -3
- package/types/DateTimeType.js +2 -6
- package/types/DateType.d.ts +3 -3
- package/types/DateType.js +2 -6
- package/types/DecimalType.d.ts +3 -3
- package/types/DecimalType.js +4 -7
- package/types/DoubleType.d.ts +3 -3
- package/types/DoubleType.js +3 -6
- package/types/EnumArrayType.d.ts +4 -4
- package/types/EnumArrayType.js +5 -10
- package/types/EnumType.d.ts +3 -3
- package/types/EnumType.js +2 -6
- package/types/FloatType.d.ts +3 -3
- package/types/FloatType.js +2 -6
- package/types/IntegerType.d.ts +3 -3
- package/types/IntegerType.js +2 -6
- package/types/IntervalType.d.ts +3 -3
- package/types/IntervalType.js +2 -6
- package/types/JsonType.d.ts +3 -3
- package/types/JsonType.js +2 -6
- package/types/MediumIntType.d.ts +3 -3
- package/types/MediumIntType.js +2 -6
- package/types/SmallIntType.d.ts +3 -3
- package/types/SmallIntType.js +2 -6
- package/types/StringType.d.ts +3 -3
- package/types/StringType.js +2 -6
- package/types/TextType.d.ts +3 -3
- package/types/TextType.js +2 -6
- package/types/TimeType.d.ts +3 -3
- package/types/TimeType.js +4 -8
- package/types/TinyIntType.d.ts +3 -3
- package/types/TinyIntType.js +3 -6
- package/types/Type.d.ts +2 -2
- package/types/Type.js +5 -9
- package/types/Uint8ArrayType.d.ts +3 -3
- package/types/Uint8ArrayType.js +3 -9
- package/types/UnknownType.d.ts +3 -3
- package/types/UnknownType.js +2 -6
- package/types/UuidType.d.ts +3 -3
- package/types/UuidType.js +2 -6
- package/types/index.d.ts +25 -25
- package/types/index.js +52 -79
- package/typings.d.ts +33 -28
- package/typings.js +37 -38
- package/unit-of-work/ChangeSet.d.ts +1 -1
- package/unit-of-work/ChangeSet.js +13 -17
- package/unit-of-work/ChangeSetComputer.d.ts +8 -7
- package/unit-of-work/ChangeSetComputer.js +26 -30
- package/unit-of-work/ChangeSetPersister.d.ts +7 -6
- package/unit-of-work/ChangeSetPersister.js +51 -48
- package/unit-of-work/CommitOrderCalculator.d.ts +1 -1
- package/unit-of-work/CommitOrderCalculator.js +6 -10
- package/unit-of-work/IdentityMap.d.ts +1 -1
- package/unit-of-work/IdentityMap.js +1 -5
- package/unit-of-work/UnitOfWork.d.ts +8 -7
- package/unit-of-work/UnitOfWork.js +193 -178
- package/unit-of-work/index.d.ts +6 -6
- package/unit-of-work/index.js +6 -22
- package/utils/AbstractSchemaGenerator.d.ts +6 -6
- package/utils/AbstractSchemaGenerator.js +12 -13
- package/utils/Configuration.d.ts +26 -27
- package/utils/Configuration.js +50 -55
- package/utils/ConfigurationLoader.d.ts +9 -8
- package/utils/ConfigurationLoader.js +71 -86
- package/utils/Cursor.d.ts +6 -6
- package/utils/Cursor.js +22 -25
- package/utils/DataloaderUtils.d.ts +4 -4
- package/utils/DataloaderUtils.js +12 -16
- package/utils/EntityComparator.d.ts +2 -2
- package/utils/EntityComparator.js +109 -97
- package/utils/NullHighlighter.d.ts +1 -1
- package/utils/NullHighlighter.js +1 -5
- package/utils/QueryHelper.d.ts +3 -3
- package/utils/QueryHelper.js +47 -51
- package/utils/RawQueryFragment.d.ts +1 -1
- package/utils/RawQueryFragment.js +22 -25
- package/utils/RequestContext.d.ts +2 -2
- package/utils/RequestContext.js +3 -7
- package/utils/TransactionContext.d.ts +1 -1
- package/utils/TransactionContext.js +4 -8
- package/utils/Utils.d.ts +16 -12
- package/utils/Utils.js +96 -95
- package/utils/clone.js +8 -11
- package/utils/index.d.ts +13 -13
- package/utils/index.js +13 -29
- package/utils/resolveContextProvider.d.ts +3 -3
- package/utils/resolveContextProvider.js +9 -12
- package/utils/upsert-utils.d.ts +3 -3
- package/utils/upsert-utils.js +5 -9
- package/index.mjs +0 -199
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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 {
|
|
1
|
+
import { basename, extname } from 'node:path';
|
|
2
|
+
import globby from 'globby';
|
|
3
|
+
import { EntityMetadata, } from '../typings.js';
|
|
4
|
+
import { Utils } from '../utils/Utils.js';
|
|
5
|
+
import { MetadataValidator } from './MetadataValidator.js';
|
|
6
|
+
import { MetadataStorage } from './MetadataStorage.js';
|
|
7
|
+
import { EntitySchema } from './EntitySchema.js';
|
|
8
|
+
import { Cascade, ReferenceKind } from '../enums.js';
|
|
9
|
+
import { MetadataError } from '../errors.js';
|
|
10
|
+
import { ArrayType, BigIntType, BlobType, DateType, DecimalType, DoubleType, EnumArrayType, IntervalType, JsonType, t, Type, Uint8ArrayType, UnknownType, } from '../types/index.js';
|
|
11
|
+
import { colors } from '../logging/colors.js';
|
|
12
|
+
import { raw, RawQueryFragment } from '../utils/RawQueryFragment.js';
|
|
13
|
+
export class MetadataDiscovery {
|
|
20
14
|
metadata;
|
|
21
15
|
platform;
|
|
22
16
|
config;
|
|
@@ -25,7 +19,7 @@ class MetadataDiscovery {
|
|
|
25
19
|
cache;
|
|
26
20
|
logger;
|
|
27
21
|
schemaHelper;
|
|
28
|
-
validator = new
|
|
22
|
+
validator = new MetadataValidator();
|
|
29
23
|
discovered = [];
|
|
30
24
|
constructor(metadata, platform, config) {
|
|
31
25
|
this.metadata = metadata;
|
|
@@ -37,36 +31,40 @@ class MetadataDiscovery {
|
|
|
37
31
|
this.logger = this.config.getLogger();
|
|
38
32
|
this.schemaHelper = this.platform.getSchemaHelper();
|
|
39
33
|
}
|
|
40
|
-
async discover(
|
|
34
|
+
async discover(preferTs = true) {
|
|
41
35
|
const startTime = Date.now();
|
|
42
|
-
this.logger.log('discovery', `ORM entity discovery started, using ${
|
|
43
|
-
await this.findEntities(
|
|
36
|
+
this.logger.log('discovery', `ORM entity discovery started, using ${colors.cyan(this.metadataProvider.constructor.name)}`);
|
|
37
|
+
await this.findEntities(preferTs);
|
|
44
38
|
for (const meta of this.discovered) {
|
|
39
|
+
/* v8 ignore next */
|
|
45
40
|
await this.config.get('discovery').onMetadata?.(meta, this.platform);
|
|
46
41
|
}
|
|
47
42
|
this.processDiscoveredEntities(this.discovered);
|
|
48
43
|
const diff = Date.now() - startTime;
|
|
49
|
-
this.logger.log('discovery', `- entity discovery finished, found ${
|
|
44
|
+
this.logger.log('discovery', `- entity discovery finished, found ${colors.green('' + this.discovered.length)} entities, took ${colors.green(`${diff} ms`)}`);
|
|
50
45
|
const storage = this.mapDiscoveredEntities();
|
|
46
|
+
/* v8 ignore next */
|
|
51
47
|
await this.config.get('discovery').afterDiscovered?.(storage, this.platform);
|
|
52
48
|
return storage;
|
|
53
49
|
}
|
|
54
|
-
discoverSync(
|
|
50
|
+
discoverSync(preferTs = true) {
|
|
55
51
|
const startTime = Date.now();
|
|
56
|
-
this.logger.log('discovery', `ORM entity discovery started, using ${
|
|
57
|
-
this.findEntities(
|
|
52
|
+
this.logger.log('discovery', `ORM entity discovery started, using ${colors.cyan(this.metadataProvider.constructor.name)} in sync mode`);
|
|
53
|
+
this.findEntities(preferTs, true);
|
|
58
54
|
for (const meta of this.discovered) {
|
|
55
|
+
/* v8 ignore next */
|
|
59
56
|
void this.config.get('discovery').onMetadata?.(meta, this.platform);
|
|
60
57
|
}
|
|
61
58
|
this.processDiscoveredEntities(this.discovered);
|
|
62
59
|
const diff = Date.now() - startTime;
|
|
63
|
-
this.logger.log('discovery', `- entity discovery finished, found ${
|
|
60
|
+
this.logger.log('discovery', `- entity discovery finished, found ${colors.green('' + this.discovered.length)} entities, took ${colors.green(`${diff} ms`)}`);
|
|
64
61
|
const storage = this.mapDiscoveredEntities();
|
|
62
|
+
/* v8 ignore next */
|
|
65
63
|
void this.config.get('discovery').afterDiscovered?.(storage, this.platform);
|
|
66
64
|
return storage;
|
|
67
65
|
}
|
|
68
66
|
mapDiscoveredEntities() {
|
|
69
|
-
const discovered = new
|
|
67
|
+
const discovered = new MetadataStorage();
|
|
70
68
|
this.discovered
|
|
71
69
|
.filter(meta => meta.root.name)
|
|
72
70
|
.sort((a, b) => b.root.name.localeCompare(a.root.name))
|
|
@@ -88,7 +86,7 @@ class MetadataDiscovery {
|
|
|
88
86
|
filtered.sort((a, b) => !a.embeddable === !b.embeddable ? 0 : (a.embeddable ? 1 : -1));
|
|
89
87
|
filtered.forEach(meta => this.initSingleTableInheritance(meta, filtered));
|
|
90
88
|
filtered.forEach(meta => this.defineBaseEntityProperties(meta));
|
|
91
|
-
filtered.forEach(meta => this.metadata.set(meta.className,
|
|
89
|
+
filtered.forEach(meta => this.metadata.set(meta.className, EntitySchema.fromMetadata(meta).init().meta));
|
|
92
90
|
filtered.forEach(meta => this.initAutoincrement(meta));
|
|
93
91
|
filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initEmbeddables(meta, prop)));
|
|
94
92
|
filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initFactoryField(meta, prop)));
|
|
@@ -104,7 +102,7 @@ class MetadataDiscovery {
|
|
|
104
102
|
this.inferTypeFromDefault(prop);
|
|
105
103
|
this.initColumnType(prop);
|
|
106
104
|
// change tracking on scalars is used only for "auto" flushMode
|
|
107
|
-
if (this.config.get('flushMode') !== 'auto' && [
|
|
105
|
+
if (this.config.get('flushMode') !== 'auto' && [ReferenceKind.SCALAR, ReferenceKind.EMBEDDED].includes(prop.kind)) {
|
|
108
106
|
prop.trackChanges = false;
|
|
109
107
|
}
|
|
110
108
|
}
|
|
@@ -130,9 +128,9 @@ class MetadataDiscovery {
|
|
|
130
128
|
findEntities(preferTs, sync = false) {
|
|
131
129
|
this.discovered.length = 0;
|
|
132
130
|
const options = this.config.get('discovery');
|
|
133
|
-
const key = (preferTs && this.config.get('preferTs',
|
|
134
|
-
const paths = this.config.get(key).filter(item =>
|
|
135
|
-
const refs = this.config.get(key).filter(item => !
|
|
131
|
+
const key = (preferTs && this.config.get('preferTs', Utils.detectTypeScriptSupport()) && this.config.get('entitiesTs').length > 0) ? 'entitiesTs' : 'entities';
|
|
132
|
+
const paths = this.config.get(key).filter(item => Utils.isString(item));
|
|
133
|
+
const refs = this.config.get(key).filter(item => !Utils.isString(item));
|
|
136
134
|
if (paths.length > 0) {
|
|
137
135
|
if (sync || options.requireEntitiesArray) {
|
|
138
136
|
throw new Error(`[requireEntitiesArray] Explicit list of entities is required, please use the 'entities' option.`);
|
|
@@ -156,17 +154,17 @@ class MetadataDiscovery {
|
|
|
156
154
|
.replace(/\((.*)\)/, '$1'); // unwrap union types
|
|
157
155
|
const missing = [];
|
|
158
156
|
this.discovered.forEach(meta => Object.values(meta.properties).forEach(prop => {
|
|
159
|
-
if (prop.kind ===
|
|
157
|
+
if (prop.kind === ReferenceKind.MANY_TO_MANY && prop.pivotEntity && !this.discovered.find(m => m.className === Utils.className(prop.pivotEntity))) {
|
|
160
158
|
const target = typeof prop.pivotEntity === 'function'
|
|
161
159
|
? prop.pivotEntity()
|
|
162
160
|
: prop.pivotEntity;
|
|
163
161
|
missing.push(target);
|
|
164
162
|
}
|
|
165
|
-
if (prop.kind !==
|
|
163
|
+
if (prop.kind !== ReferenceKind.SCALAR && !unwrap(prop.type).split(/ ?\| ?/).every(type => this.discovered.find(m => m.className === type))) {
|
|
166
164
|
const target = typeof prop.entity === 'function'
|
|
167
165
|
? prop.entity()
|
|
168
166
|
: prop.type;
|
|
169
|
-
missing.push(...
|
|
167
|
+
missing.push(...Utils.asArray(target));
|
|
170
168
|
}
|
|
171
169
|
}));
|
|
172
170
|
if (missing.length > 0) {
|
|
@@ -182,12 +180,12 @@ class MetadataDiscovery {
|
|
|
182
180
|
}
|
|
183
181
|
}
|
|
184
182
|
async discoverDirectories(paths) {
|
|
185
|
-
paths = paths.map(path =>
|
|
186
|
-
const files = await (
|
|
187
|
-
this.logger.log('discovery', `- processing ${
|
|
183
|
+
paths = paths.map(path => Utils.normalizePath(path));
|
|
184
|
+
const files = await globby(paths, { cwd: Utils.normalizePath(this.config.get('baseDir')) });
|
|
185
|
+
this.logger.log('discovery', `- processing ${colors.cyan('' + files.length)} files`);
|
|
188
186
|
const found = [];
|
|
189
187
|
for (const filepath of files) {
|
|
190
|
-
const filename =
|
|
188
|
+
const filename = basename(filepath);
|
|
191
189
|
if (!filename.match(/\.[cm]?[jt]s$/) ||
|
|
192
190
|
filename.endsWith('.js.map') ||
|
|
193
191
|
filename.match(/\.d\.[cm]?ts/) ||
|
|
@@ -197,10 +195,10 @@ class MetadataDiscovery {
|
|
|
197
195
|
continue;
|
|
198
196
|
}
|
|
199
197
|
const name = this.namingStrategy.getClassName(filename);
|
|
200
|
-
const path =
|
|
198
|
+
const path = Utils.normalizePath(this.config.get('baseDir'), filepath);
|
|
201
199
|
const targets = await this.getEntityClassOrSchema(path, name);
|
|
202
200
|
for (const target of targets) {
|
|
203
|
-
if (!(target instanceof Function) && !(target instanceof
|
|
201
|
+
if (!(target instanceof Function) && !(target instanceof EntitySchema)) {
|
|
204
202
|
this.logger.log('discovery', `- ignoring file ${filename}`);
|
|
205
203
|
continue;
|
|
206
204
|
}
|
|
@@ -226,9 +224,10 @@ class MetadataDiscovery {
|
|
|
226
224
|
// discover parents (base entities) automatically
|
|
227
225
|
for (const meta of this.metadata) {
|
|
228
226
|
let parent = meta.extends;
|
|
229
|
-
if (parent instanceof
|
|
227
|
+
if (parent instanceof EntitySchema && !this.metadata.has(parent.meta.className)) {
|
|
230
228
|
this.discoverReferences([parent]);
|
|
231
229
|
}
|
|
230
|
+
/* v8 ignore next 3 */
|
|
232
231
|
if (!meta.class) {
|
|
233
232
|
continue;
|
|
234
233
|
}
|
|
@@ -250,44 +249,44 @@ class MetadataDiscovery {
|
|
|
250
249
|
}
|
|
251
250
|
}
|
|
252
251
|
prepare(entity) {
|
|
253
|
-
|
|
252
|
+
/* v8 ignore next 3 */
|
|
253
|
+
if ('schema' in entity && entity.schema instanceof EntitySchema) {
|
|
254
254
|
return entity.schema;
|
|
255
255
|
}
|
|
256
|
-
if (
|
|
257
|
-
return
|
|
256
|
+
if (EntitySchema.REGISTRY.has(entity)) {
|
|
257
|
+
return EntitySchema.REGISTRY.get(entity);
|
|
258
258
|
}
|
|
259
259
|
return entity;
|
|
260
260
|
}
|
|
261
261
|
getSchema(entity, filepath) {
|
|
262
|
-
if (entity instanceof
|
|
262
|
+
if (entity instanceof EntitySchema) {
|
|
263
263
|
if (filepath) {
|
|
264
264
|
// initialize global metadata for given entity
|
|
265
|
-
|
|
265
|
+
MetadataStorage.getMetadata(entity.meta.className, filepath);
|
|
266
266
|
}
|
|
267
267
|
return entity;
|
|
268
268
|
}
|
|
269
|
-
const path = entity[
|
|
269
|
+
const path = entity[MetadataStorage.PATH_SYMBOL];
|
|
270
270
|
if (path) {
|
|
271
|
-
const meta =
|
|
272
|
-
meta.path =
|
|
271
|
+
const meta = Utils.copy(MetadataStorage.getMetadata(entity.name, path), false);
|
|
272
|
+
meta.path = Utils.relativePath(path, this.config.get('baseDir'));
|
|
273
273
|
this.metadata.set(entity.name, meta);
|
|
274
274
|
}
|
|
275
275
|
const exists = this.metadata.has(entity.name);
|
|
276
276
|
const meta = this.metadata.get(entity.name, true);
|
|
277
277
|
meta.abstract ??= !(exists && meta.name);
|
|
278
|
-
const schema =
|
|
278
|
+
const schema = EntitySchema.fromMetadata(meta);
|
|
279
279
|
schema.setClass(entity);
|
|
280
|
-
schema.meta.useCache = this.metadataProvider.useCache();
|
|
281
280
|
return schema;
|
|
282
281
|
}
|
|
283
282
|
discoverEntity(schema, path) {
|
|
284
|
-
this.logger.log('discovery', `- processing entity ${
|
|
283
|
+
this.logger.log('discovery', `- processing entity ${colors.cyan(schema.meta.className)}${colors.grey(path ? ` (${path})` : '')}`);
|
|
285
284
|
const meta = schema.meta;
|
|
286
|
-
const root =
|
|
287
|
-
schema.meta.path =
|
|
288
|
-
const cache =
|
|
285
|
+
const root = Utils.getRootEntity(this.metadata, meta);
|
|
286
|
+
schema.meta.path = Utils.relativePath(path || meta.path, this.config.get('baseDir'));
|
|
287
|
+
const cache = this.metadataProvider.useCache() && meta.path && this.cache.get(meta.className + extname(meta.path));
|
|
289
288
|
if (cache) {
|
|
290
|
-
this.logger.log('discovery', `- using cached metadata for entity ${
|
|
289
|
+
this.logger.log('discovery', `- using cached metadata for entity ${colors.cyan(meta.className)}`);
|
|
291
290
|
this.metadataProvider.loadFromCache(meta, cache);
|
|
292
291
|
meta.root = root;
|
|
293
292
|
this.discovered.push(meta);
|
|
@@ -309,62 +308,60 @@ class MetadataDiscovery {
|
|
|
309
308
|
this.discovered.push(meta);
|
|
310
309
|
}
|
|
311
310
|
saveToCache(meta) {
|
|
312
|
-
if (!
|
|
311
|
+
if (!this.metadataProvider.useCache()) {
|
|
313
312
|
return;
|
|
314
313
|
}
|
|
315
|
-
const copy =
|
|
316
|
-
copy.props
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
.filter(k => types_1.Type.isMappedType(prop[k]))
|
|
321
|
-
.forEach(k => delete prop[k]);
|
|
322
|
-
});
|
|
323
|
-
copy.props
|
|
324
|
-
.filter(prop => prop.default)
|
|
325
|
-
.forEach(prop => {
|
|
326
|
-
const raw = RawQueryFragment_1.RawQueryFragment.getKnownFragment(prop.default);
|
|
327
|
-
if (raw) {
|
|
328
|
-
prop.defaultRaw ??= this.platform.formatQuery(raw.sql, raw.params);
|
|
329
|
-
delete prop.default;
|
|
314
|
+
const copy = Utils.copy(meta, false);
|
|
315
|
+
for (const prop of copy.props) {
|
|
316
|
+
if (Type.isMappedType(prop.type)) {
|
|
317
|
+
Reflect.deleteProperty(prop, 'type');
|
|
318
|
+
Reflect.deleteProperty(prop, 'customType');
|
|
330
319
|
}
|
|
331
|
-
|
|
320
|
+
if (prop.default) {
|
|
321
|
+
const raw = RawQueryFragment.getKnownFragment(prop.default);
|
|
322
|
+
if (raw) {
|
|
323
|
+
prop.defaultRaw ??= this.platform.formatQuery(raw.sql, raw.params);
|
|
324
|
+
Reflect.deleteProperty(prop, 'default');
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
Reflect.deleteProperty(prop, 'targetMeta');
|
|
328
|
+
}
|
|
332
329
|
[
|
|
333
330
|
'prototype', 'props', 'referencingProperties', 'propertyOrder', 'relations',
|
|
334
331
|
'concurrencyCheckKeys', 'checks',
|
|
335
332
|
].forEach(key => delete copy[key]);
|
|
336
333
|
// base entity without properties might not have path, but nothing to cache there
|
|
337
334
|
if (meta.path) {
|
|
338
|
-
this.cache.set(meta.className +
|
|
335
|
+
this.cache.set(meta.className + extname(meta.path), copy, meta.path);
|
|
339
336
|
}
|
|
340
337
|
}
|
|
341
338
|
initNullability(prop) {
|
|
342
|
-
if (prop.kind ===
|
|
343
|
-
return
|
|
339
|
+
if (prop.kind === ReferenceKind.MANY_TO_ONE) {
|
|
340
|
+
return Utils.defaultValue(prop, 'nullable', prop.optional || prop.cascade.includes(Cascade.REMOVE) || prop.cascade.includes(Cascade.ALL));
|
|
344
341
|
}
|
|
345
|
-
if (prop.kind ===
|
|
346
|
-
return
|
|
342
|
+
if (prop.kind === ReferenceKind.ONE_TO_ONE) {
|
|
343
|
+
return Utils.defaultValue(prop, 'nullable', prop.optional || !prop.owner || prop.cascade.includes(Cascade.REMOVE) || prop.cascade.includes(Cascade.ALL));
|
|
347
344
|
}
|
|
348
|
-
return
|
|
345
|
+
return Utils.defaultValue(prop, 'nullable', prop.optional);
|
|
349
346
|
}
|
|
350
347
|
applyNamingStrategy(meta, prop) {
|
|
351
348
|
if (!prop.fieldNames) {
|
|
352
349
|
this.initFieldName(prop);
|
|
353
350
|
}
|
|
354
|
-
if (prop.kind ===
|
|
351
|
+
if (prop.kind === ReferenceKind.MANY_TO_MANY) {
|
|
355
352
|
this.initManyToManyFields(meta, prop);
|
|
356
353
|
}
|
|
357
|
-
if ([
|
|
354
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
358
355
|
this.initManyToOneFields(prop);
|
|
359
356
|
}
|
|
360
|
-
if (prop.kind ===
|
|
357
|
+
if (prop.kind === ReferenceKind.ONE_TO_MANY) {
|
|
361
358
|
this.initOneToManyFields(prop);
|
|
362
359
|
}
|
|
363
360
|
}
|
|
364
361
|
initOwnColumns(meta) {
|
|
365
362
|
meta.sync();
|
|
366
363
|
for (const prop of meta.props) {
|
|
367
|
-
if (!prop.joinColumns || !prop.columnTypes || prop.ownColumns || ![
|
|
364
|
+
if (!prop.joinColumns || !prop.columnTypes || prop.ownColumns || ![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
368
365
|
continue;
|
|
369
366
|
}
|
|
370
367
|
if (prop.joinColumns.length > 1) {
|
|
@@ -378,15 +375,15 @@ class MetadataDiscovery {
|
|
|
378
375
|
if (prop.joinColumns.length !== prop.columnTypes.length) {
|
|
379
376
|
prop.columnTypes = prop.joinColumns.flatMap(field => {
|
|
380
377
|
const matched = meta.props.find(p => p.fieldNames?.includes(field));
|
|
381
|
-
|
|
382
|
-
|
|
378
|
+
/* v8 ignore next 3 */
|
|
379
|
+
if (!matched) {
|
|
380
|
+
throw MetadataError.fromWrongForeignKey(meta, prop, 'columnTypes');
|
|
383
381
|
}
|
|
384
|
-
|
|
385
|
-
throw errors_1.MetadataError.fromWrongForeignKey(meta, prop, 'columnTypes');
|
|
382
|
+
return matched.columnTypes;
|
|
386
383
|
});
|
|
387
384
|
}
|
|
388
385
|
if (prop.joinColumns.length !== prop.referencedColumnNames.length) {
|
|
389
|
-
throw
|
|
386
|
+
throw MetadataError.fromWrongForeignKey(meta, prop, 'referencedColumnNames');
|
|
390
387
|
}
|
|
391
388
|
}
|
|
392
389
|
}
|
|
@@ -394,13 +391,13 @@ class MetadataDiscovery {
|
|
|
394
391
|
if (prop.fieldNames && prop.fieldNames.length > 0) {
|
|
395
392
|
return;
|
|
396
393
|
}
|
|
397
|
-
if (prop.kind ===
|
|
394
|
+
if (prop.kind === ReferenceKind.SCALAR || prop.kind === ReferenceKind.EMBEDDED) {
|
|
398
395
|
prop.fieldNames = [this.namingStrategy.propertyToColumnName(prop.name, object)];
|
|
399
396
|
}
|
|
400
|
-
else if ([
|
|
397
|
+
else if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
401
398
|
prop.fieldNames = this.initManyToOneFieldName(prop, prop.name);
|
|
402
399
|
}
|
|
403
|
-
else if (prop.kind ===
|
|
400
|
+
else if (prop.kind === ReferenceKind.MANY_TO_MANY && prop.owner) {
|
|
404
401
|
prop.fieldNames = this.initManyToManyFieldName(prop, prop.name);
|
|
405
402
|
}
|
|
406
403
|
}
|
|
@@ -421,11 +418,11 @@ class MetadataDiscovery {
|
|
|
421
418
|
}
|
|
422
419
|
initManyToManyFields(meta, prop) {
|
|
423
420
|
const meta2 = this.metadata.get(prop.type);
|
|
424
|
-
|
|
421
|
+
Utils.defaultValue(prop, 'fixedOrder', !!prop.fixedOrderColumn);
|
|
425
422
|
const pivotMeta = this.metadata.find(prop.pivotEntity);
|
|
426
423
|
const props = Object.values(pivotMeta?.properties ?? {});
|
|
427
424
|
const pks = props.filter(p => p.primary);
|
|
428
|
-
const fks = props.filter(p => p.kind ===
|
|
425
|
+
const fks = props.filter(p => p.kind === ReferenceKind.MANY_TO_ONE);
|
|
429
426
|
if (pivotMeta) {
|
|
430
427
|
pivotMeta.pivotTable = true;
|
|
431
428
|
prop.pivotTable = pivotMeta.tableName;
|
|
@@ -453,14 +450,14 @@ class MetadataDiscovery {
|
|
|
453
450
|
prop.joinColumns = prop2.inverseJoinColumns;
|
|
454
451
|
prop.inverseJoinColumns = prop2.joinColumns;
|
|
455
452
|
}
|
|
456
|
-
prop.referencedColumnNames ??=
|
|
453
|
+
prop.referencedColumnNames ??= Utils.flatten(meta.primaryKeys.map(primaryKey => meta.properties[primaryKey].fieldNames));
|
|
457
454
|
prop.joinColumns ??= prop.referencedColumnNames.map(referencedColumnName => this.namingStrategy.joinKeyColumnName(meta.root.className, referencedColumnName, meta.compositePK));
|
|
458
455
|
prop.inverseJoinColumns ??= this.initManyToOneFieldName(prop, meta2.root.className);
|
|
459
456
|
}
|
|
460
457
|
initManyToOneFields(prop) {
|
|
461
458
|
const meta2 = this.metadata.get(prop.type);
|
|
462
|
-
const fieldNames =
|
|
463
|
-
|
|
459
|
+
const fieldNames = Utils.flatten(meta2.primaryKeys.map(primaryKey => meta2.properties[primaryKey].fieldNames));
|
|
460
|
+
Utils.defaultValue(prop, 'referencedTableName', meta2.collection);
|
|
464
461
|
if (!prop.joinColumns) {
|
|
465
462
|
prop.joinColumns = fieldNames.map(fieldName => this.namingStrategy.joinKeyColumnName(prop.name, fieldName, fieldNames.length > 1));
|
|
466
463
|
}
|
|
@@ -475,7 +472,7 @@ class MetadataDiscovery {
|
|
|
475
472
|
}
|
|
476
473
|
if (!prop.referencedColumnNames) {
|
|
477
474
|
meta2.getPrimaryProps().forEach(pk => this.applyNamingStrategy(meta2, pk));
|
|
478
|
-
prop.referencedColumnNames =
|
|
475
|
+
prop.referencedColumnNames = Utils.flatten(meta2.getPrimaryProps().map(pk => pk.fieldNames));
|
|
479
476
|
}
|
|
480
477
|
}
|
|
481
478
|
processEntity(meta) {
|
|
@@ -483,7 +480,7 @@ class MetadataDiscovery {
|
|
|
483
480
|
meta.primaryKeys = pks.map(prop => prop.name);
|
|
484
481
|
meta.compositePK = pks.length > 1;
|
|
485
482
|
// FK used as PK, we need to cascade
|
|
486
|
-
if (pks.length === 1 && pks[0].kind !==
|
|
483
|
+
if (pks.length === 1 && pks[0].kind !== ReferenceKind.SCALAR) {
|
|
487
484
|
pks[0].deleteRule ??= 'cascade';
|
|
488
485
|
}
|
|
489
486
|
meta.forceConstructor ??= this.shouldForceConstructorUsage(meta);
|
|
@@ -499,7 +496,7 @@ class MetadataDiscovery {
|
|
|
499
496
|
this.initRelation(prop);
|
|
500
497
|
}
|
|
501
498
|
this.initOwnColumns(meta);
|
|
502
|
-
meta.simplePK = pks.length === 1 && pks[0].kind ===
|
|
499
|
+
meta.simplePK = pks.length === 1 && pks[0].kind === ReferenceKind.SCALAR && !pks[0].customType && pks[0].runtimeType !== 'Date';
|
|
503
500
|
meta.serializedPrimaryKey = this.platform.getSerializedPrimaryKeyField(meta.primaryKeys[0]);
|
|
504
501
|
const serializedPKProp = meta.properties[meta.serializedPrimaryKey];
|
|
505
502
|
if (serializedPKProp && meta.serializedPrimaryKey !== meta.primaryKeys[0]) {
|
|
@@ -507,7 +504,7 @@ class MetadataDiscovery {
|
|
|
507
504
|
}
|
|
508
505
|
if (this.platform.usesPivotTable()) {
|
|
509
506
|
return Object.values(meta.properties)
|
|
510
|
-
.filter(prop => prop.kind ===
|
|
507
|
+
.filter(prop => prop.kind === ReferenceKind.MANY_TO_MANY && prop.owner && prop.pivotTable)
|
|
511
508
|
.map(prop => this.definePivotTableEntity(meta, prop));
|
|
512
509
|
}
|
|
513
510
|
return [];
|
|
@@ -515,7 +512,7 @@ class MetadataDiscovery {
|
|
|
515
512
|
findReferencingProperties(meta, metadata) {
|
|
516
513
|
for (const meta2 of metadata) {
|
|
517
514
|
for (const prop2 of meta2.relations) {
|
|
518
|
-
if (prop2.kind !==
|
|
515
|
+
if (prop2.kind !== ReferenceKind.SCALAR && prop2.type === meta.className) {
|
|
519
516
|
meta.referencingProperties.push({ meta: meta2, prop: prop2 });
|
|
520
517
|
}
|
|
521
518
|
}
|
|
@@ -528,23 +525,23 @@ class MetadataDiscovery {
|
|
|
528
525
|
const meta2 = this.metadata.get(prop.type);
|
|
529
526
|
prop[type] = value(meta2.properties)?.name;
|
|
530
527
|
if (prop[type] == null) {
|
|
531
|
-
throw
|
|
528
|
+
throw MetadataError.fromWrongReference(meta, prop, type);
|
|
532
529
|
}
|
|
533
530
|
}
|
|
534
531
|
});
|
|
535
532
|
}
|
|
536
533
|
ensureCorrectFKOrderInPivotEntity(meta, owner) {
|
|
537
534
|
const pks = Object.values(meta.properties).filter(p => p.primary);
|
|
538
|
-
const fks = Object.values(meta.properties).filter(p => p.kind ===
|
|
535
|
+
const fks = Object.values(meta.properties).filter(p => p.kind === ReferenceKind.MANY_TO_ONE);
|
|
539
536
|
let first, second;
|
|
540
537
|
if (pks.length === 2) {
|
|
541
538
|
[first, second] = pks;
|
|
542
539
|
}
|
|
543
540
|
else if (fks.length >= 2) {
|
|
544
541
|
[first, second] = fks;
|
|
542
|
+
/* v8 ignore next 3 */
|
|
545
543
|
}
|
|
546
544
|
else {
|
|
547
|
-
/* istanbul ignore next */
|
|
548
545
|
return [];
|
|
549
546
|
}
|
|
550
547
|
// wrong FK order, first FK needs to point to the owning side
|
|
@@ -565,7 +562,7 @@ class MetadataDiscovery {
|
|
|
565
562
|
prop.inversedBy = inverseName;
|
|
566
563
|
const inverseProp = {
|
|
567
564
|
name: inverseName,
|
|
568
|
-
kind:
|
|
565
|
+
kind: ReferenceKind.MANY_TO_MANY,
|
|
569
566
|
type: meta.className,
|
|
570
567
|
mappedBy: prop.name,
|
|
571
568
|
pivotEntity: prop.pivotEntity,
|
|
@@ -594,7 +591,7 @@ class MetadataDiscovery {
|
|
|
594
591
|
}
|
|
595
592
|
schemaName ??= meta.schema;
|
|
596
593
|
const targetType = prop.targetMeta.className;
|
|
597
|
-
const data = new
|
|
594
|
+
const data = new EntityMetadata({
|
|
598
595
|
name: prop.pivotTable,
|
|
599
596
|
className: prop.pivotTable,
|
|
600
597
|
collection: tableName,
|
|
@@ -628,7 +625,7 @@ class MetadataDiscovery {
|
|
|
628
625
|
const primaryProp = {
|
|
629
626
|
name: pk,
|
|
630
627
|
type: 'number',
|
|
631
|
-
kind:
|
|
628
|
+
kind: ReferenceKind.SCALAR,
|
|
632
629
|
primary: true,
|
|
633
630
|
autoincrement: true,
|
|
634
631
|
unsigned: this.platform.supportsUnsigned(),
|
|
@@ -647,8 +644,8 @@ class MetadataDiscovery {
|
|
|
647
644
|
const ret = {
|
|
648
645
|
name,
|
|
649
646
|
type,
|
|
650
|
-
kind:
|
|
651
|
-
cascade: [
|
|
647
|
+
kind: ReferenceKind.MANY_TO_ONE,
|
|
648
|
+
cascade: [Cascade.ALL],
|
|
652
649
|
fixedOrder: prop.fixedOrder,
|
|
653
650
|
fixedOrderColumn: prop.fixedOrderColumn,
|
|
654
651
|
index: this.platform.indexForeignKeys(),
|
|
@@ -701,7 +698,7 @@ class MetadataDiscovery {
|
|
|
701
698
|
}
|
|
702
699
|
autoWireBidirectionalProperties(meta) {
|
|
703
700
|
Object.values(meta.properties)
|
|
704
|
-
.filter(prop => prop.kind !==
|
|
701
|
+
.filter(prop => prop.kind !== ReferenceKind.SCALAR && !prop.owner && prop.mappedBy)
|
|
705
702
|
.forEach(prop => {
|
|
706
703
|
const meta2 = this.metadata.get(prop.type);
|
|
707
704
|
const prop2 = meta2.properties[prop.mappedBy];
|
|
@@ -711,7 +708,7 @@ class MetadataDiscovery {
|
|
|
711
708
|
});
|
|
712
709
|
}
|
|
713
710
|
defineBaseEntityProperties(meta) {
|
|
714
|
-
const base = meta.extends && this.metadata.get(
|
|
711
|
+
const base = meta.extends && this.metadata.get(Utils.className(meta.extends));
|
|
715
712
|
if (!base || base === meta) { // make sure we do not fall into infinite loop
|
|
716
713
|
return 0;
|
|
717
714
|
}
|
|
@@ -732,15 +729,15 @@ class MetadataDiscovery {
|
|
|
732
729
|
meta.propertyOrder.set(prop.name, (order += 0.01));
|
|
733
730
|
});
|
|
734
731
|
}
|
|
735
|
-
meta.indexes =
|
|
736
|
-
meta.uniques =
|
|
737
|
-
meta.checks =
|
|
732
|
+
meta.indexes = Utils.unique([...base.indexes, ...meta.indexes]);
|
|
733
|
+
meta.uniques = Utils.unique([...base.uniques, ...meta.uniques]);
|
|
734
|
+
meta.checks = Utils.unique([...base.checks, ...meta.checks]);
|
|
738
735
|
const pks = Object.values(meta.properties).filter(p => p.primary).map(p => p.name);
|
|
739
736
|
if (pks.length > 0 && meta.primaryKeys.length === 0) {
|
|
740
737
|
meta.primaryKeys = pks;
|
|
741
738
|
}
|
|
742
|
-
|
|
743
|
-
meta.hooks[type] =
|
|
739
|
+
Utils.keys(base.hooks).forEach(type => {
|
|
740
|
+
meta.hooks[type] = Utils.unique([...base.hooks[type], ...(meta.hooks[type] || [])]);
|
|
744
741
|
});
|
|
745
742
|
if (meta.constructorParams.length === 0 && base.constructorParams.length > 0) {
|
|
746
743
|
meta.constructorParams = [...base.constructorParams];
|
|
@@ -751,7 +748,7 @@ class MetadataDiscovery {
|
|
|
751
748
|
return order;
|
|
752
749
|
}
|
|
753
750
|
initPolyEmbeddables(embeddedProp, discovered, visited = new Set()) {
|
|
754
|
-
if (embeddedProp.kind !==
|
|
751
|
+
if (embeddedProp.kind !== ReferenceKind.EMBEDDED || visited.has(embeddedProp)) {
|
|
755
752
|
return;
|
|
756
753
|
}
|
|
757
754
|
visited.add(embeddedProp);
|
|
@@ -768,6 +765,7 @@ class MetadataDiscovery {
|
|
|
768
765
|
delete prop.default;
|
|
769
766
|
if (properties[prop.name] && properties[prop.name].type !== prop.type) {
|
|
770
767
|
properties[prop.name].type = `${properties[prop.name].type} | ${prop.type}`;
|
|
768
|
+
properties[prop.name].runtimeType = 'any';
|
|
771
769
|
return properties[prop.name];
|
|
772
770
|
}
|
|
773
771
|
return properties[prop.name] = prop;
|
|
@@ -775,7 +773,7 @@ class MetadataDiscovery {
|
|
|
775
773
|
};
|
|
776
774
|
const processExtensions = (meta) => {
|
|
777
775
|
const parent = this.discovered.find(m => {
|
|
778
|
-
return meta.extends &&
|
|
776
|
+
return meta.extends && Utils.className(meta.extends) === m.className;
|
|
779
777
|
});
|
|
780
778
|
if (!parent) {
|
|
781
779
|
return;
|
|
@@ -789,7 +787,7 @@ class MetadataDiscovery {
|
|
|
789
787
|
processExtensions(meta);
|
|
790
788
|
});
|
|
791
789
|
const name = polymorphs.map(t => t.className).sort().join(' | ');
|
|
792
|
-
embeddable = new
|
|
790
|
+
embeddable = new EntityMetadata({
|
|
793
791
|
name,
|
|
794
792
|
className: name,
|
|
795
793
|
embeddable: true,
|
|
@@ -804,13 +802,13 @@ class MetadataDiscovery {
|
|
|
804
802
|
}
|
|
805
803
|
}
|
|
806
804
|
initEmbeddables(meta, embeddedProp, visited = new Set()) {
|
|
807
|
-
if (embeddedProp.kind !==
|
|
805
|
+
if (embeddedProp.kind !== ReferenceKind.EMBEDDED || visited.has(embeddedProp)) {
|
|
808
806
|
return;
|
|
809
807
|
}
|
|
810
808
|
visited.add(embeddedProp);
|
|
811
809
|
const embeddable = this.discovered.find(m => m.name === embeddedProp.type);
|
|
812
810
|
if (!embeddable) {
|
|
813
|
-
throw
|
|
811
|
+
throw MetadataError.fromUnknownEntity(embeddedProp.type, `${meta.className}.${embeddedProp.name}`);
|
|
814
812
|
}
|
|
815
813
|
embeddedProp.embeddable = embeddable.class;
|
|
816
814
|
embeddedProp.embeddedProps = {};
|
|
@@ -831,7 +829,7 @@ class MetadataDiscovery {
|
|
|
831
829
|
const glue = object ? '~' : '_';
|
|
832
830
|
for (const prop of Object.values(embeddable.properties)) {
|
|
833
831
|
const name = (embeddedProp.embeddedPath?.join(glue) ?? embeddedProp.fieldNames[0] + glue) + prop.name;
|
|
834
|
-
meta.properties[name] =
|
|
832
|
+
meta.properties[name] = Utils.copy(prop, false);
|
|
835
833
|
meta.properties[name].name = name;
|
|
836
834
|
meta.properties[name].embedded = [embeddedProp.name, prop.name];
|
|
837
835
|
meta.propertyOrder.set(name, (order += 0.01));
|
|
@@ -870,7 +868,7 @@ class MetadataDiscovery {
|
|
|
870
868
|
path.push(prop.fieldNames[0]);
|
|
871
869
|
meta.properties[name].fieldNames = prop.fieldNames;
|
|
872
870
|
meta.properties[name].embeddedPath = path;
|
|
873
|
-
const fieldName =
|
|
871
|
+
const fieldName = raw(this.platform.getSearchJsonPropertySQL(path.join('->'), prop.runtimeType ?? prop.type, true));
|
|
874
872
|
meta.properties[name].fieldNameRaw = fieldName.sql; // for querying in SQL drivers
|
|
875
873
|
meta.properties[name].persist = false; // only virtual as we store the whole object
|
|
876
874
|
meta.properties[name].userDefined = false; // mark this as a generated/internal property, so we can distinguish from user-defined non-persist properties
|
|
@@ -881,7 +879,7 @@ class MetadataDiscovery {
|
|
|
881
879
|
for (const index of embeddable.indexes) {
|
|
882
880
|
meta.indexes.push({
|
|
883
881
|
...index,
|
|
884
|
-
properties:
|
|
882
|
+
properties: Utils.asArray(index.properties).map(p => {
|
|
885
883
|
return embeddedProp.embeddedProps[p].name;
|
|
886
884
|
}),
|
|
887
885
|
});
|
|
@@ -889,7 +887,7 @@ class MetadataDiscovery {
|
|
|
889
887
|
for (const unique of embeddable.uniques) {
|
|
890
888
|
meta.uniques.push({
|
|
891
889
|
...unique,
|
|
892
|
-
properties:
|
|
890
|
+
properties: Utils.asArray(unique.properties).map(p => {
|
|
893
891
|
return embeddedProp.embeddedProps[p].name;
|
|
894
892
|
}),
|
|
895
893
|
});
|
|
@@ -908,24 +906,26 @@ class MetadataDiscovery {
|
|
|
908
906
|
}
|
|
909
907
|
if (!meta.root.discriminatorMap) {
|
|
910
908
|
meta.root.discriminatorMap = {};
|
|
911
|
-
const children = metadata
|
|
912
|
-
|
|
909
|
+
const children = metadata
|
|
910
|
+
.filter(m => m.root.className === meta.root.className && !m.abstract)
|
|
911
|
+
.sort((a, b) => a.className.localeCompare(b.className));
|
|
912
|
+
for (const m of children) {
|
|
913
913
|
const name = m.discriminatorValue ?? this.namingStrategy.classToTableName(m.className);
|
|
914
914
|
meta.root.discriminatorMap[name] = m.className;
|
|
915
|
-
}
|
|
915
|
+
}
|
|
916
916
|
}
|
|
917
917
|
meta.discriminatorValue = Object.entries(meta.root.discriminatorMap).find(([, className]) => className === meta.className)?.[0];
|
|
918
918
|
if (!meta.root.properties[meta.root.discriminatorColumn]) {
|
|
919
919
|
this.createDiscriminatorProperty(meta.root);
|
|
920
920
|
}
|
|
921
|
-
|
|
922
|
-
|
|
921
|
+
Utils.defaultValue(meta.root.properties[meta.root.discriminatorColumn], 'items', Object.keys(meta.root.discriminatorMap));
|
|
922
|
+
Utils.defaultValue(meta.root.properties[meta.root.discriminatorColumn], 'index', true);
|
|
923
923
|
if (meta.root === meta) {
|
|
924
924
|
return;
|
|
925
925
|
}
|
|
926
926
|
let i = 1;
|
|
927
927
|
Object.values(meta.properties).forEach(prop => {
|
|
928
|
-
const newProp =
|
|
928
|
+
const newProp = { ...prop };
|
|
929
929
|
if (meta.root.properties[prop.name] && meta.root.properties[prop.name].type !== prop.type) {
|
|
930
930
|
const name = newProp.name;
|
|
931
931
|
this.initFieldName(newProp, newProp.object);
|
|
@@ -938,29 +938,30 @@ class MetadataDiscovery {
|
|
|
938
938
|
return;
|
|
939
939
|
}
|
|
940
940
|
if (prop.enum && prop.items && meta.root.properties[prop.name]?.items) {
|
|
941
|
-
newProp.items =
|
|
941
|
+
newProp.items = Utils.unique([...meta.root.properties[prop.name].items, ...prop.items]);
|
|
942
942
|
}
|
|
943
943
|
newProp.nullable = true;
|
|
944
944
|
newProp.inherited = true;
|
|
945
945
|
meta.root.addProperty(newProp);
|
|
946
946
|
});
|
|
947
947
|
meta.collection = meta.root.collection;
|
|
948
|
-
meta.root.indexes =
|
|
949
|
-
meta.root.uniques =
|
|
948
|
+
meta.root.indexes = Utils.unique([...meta.root.indexes, ...meta.indexes]);
|
|
949
|
+
meta.root.uniques = Utils.unique([...meta.root.uniques, ...meta.uniques]);
|
|
950
|
+
meta.root.checks = Utils.unique([...meta.root.checks, ...meta.checks]);
|
|
950
951
|
}
|
|
951
952
|
createDiscriminatorProperty(meta) {
|
|
952
953
|
meta.addProperty({
|
|
953
954
|
name: meta.discriminatorColumn,
|
|
954
955
|
type: 'string',
|
|
955
956
|
enum: true,
|
|
956
|
-
kind:
|
|
957
|
+
kind: ReferenceKind.SCALAR,
|
|
957
958
|
userDefined: false,
|
|
958
959
|
});
|
|
959
960
|
}
|
|
960
961
|
initAutoincrement(meta) {
|
|
961
962
|
const pks = meta.getPrimaryProps();
|
|
962
963
|
if (pks.length === 1 && this.platform.isNumericProperty(pks[0])) {
|
|
963
|
-
/*
|
|
964
|
+
/* v8 ignore next */
|
|
964
965
|
pks[0].autoincrement ??= true;
|
|
965
966
|
}
|
|
966
967
|
}
|
|
@@ -975,7 +976,7 @@ class MetadataDiscovery {
|
|
|
975
976
|
}
|
|
976
977
|
if (this.platform.usesEnumCheckConstraints() && !meta.embeddable) {
|
|
977
978
|
for (const prop of meta.props) {
|
|
978
|
-
if (prop.enum && !prop.nativeEnumName && prop.items?.every(item =>
|
|
979
|
+
if (prop.enum && !prop.nativeEnumName && prop.items?.every(item => Utils.isString(item))) {
|
|
979
980
|
this.initFieldName(prop);
|
|
980
981
|
meta.checks.push({
|
|
981
982
|
name: this.namingStrategy.indexName(meta.tableName, prop.fieldNames, 'check'),
|
|
@@ -1017,7 +1018,7 @@ class MetadataDiscovery {
|
|
|
1017
1018
|
if (typeof prop.defaultRaw !== 'undefined') {
|
|
1018
1019
|
return prop.defaultRaw;
|
|
1019
1020
|
}
|
|
1020
|
-
/*
|
|
1021
|
+
/* v8 ignore next 3 */
|
|
1021
1022
|
if (prop.default != null) {
|
|
1022
1023
|
return '' + this.platform.quoteVersionValue(prop.default, prop);
|
|
1023
1024
|
}
|
|
@@ -1028,7 +1029,7 @@ class MetadataDiscovery {
|
|
|
1028
1029
|
return '1';
|
|
1029
1030
|
}
|
|
1030
1031
|
inferDefaultValue(meta, prop) {
|
|
1031
|
-
/*
|
|
1032
|
+
/* v8 ignore next 3 */
|
|
1032
1033
|
if (!meta.class) {
|
|
1033
1034
|
return;
|
|
1034
1035
|
}
|
|
@@ -1046,8 +1047,8 @@ class MetadataDiscovery {
|
|
|
1046
1047
|
prop.nullable ??= true;
|
|
1047
1048
|
}
|
|
1048
1049
|
// but still use object values for type inference if not explicitly set, e.g. `createdAt = new Date()`
|
|
1049
|
-
if (prop.kind ===
|
|
1050
|
-
prop.type = prop.runtimeType =
|
|
1050
|
+
if (prop.kind === ReferenceKind.SCALAR && prop.type == null && entity1[prop.name] != null) {
|
|
1051
|
+
prop.type = prop.runtimeType = Utils.getObjectType(entity1[prop.name]);
|
|
1051
1052
|
}
|
|
1052
1053
|
}
|
|
1053
1054
|
catch {
|
|
@@ -1059,12 +1060,12 @@ class MetadataDiscovery {
|
|
|
1059
1060
|
return;
|
|
1060
1061
|
}
|
|
1061
1062
|
let val = prop.default;
|
|
1062
|
-
const raw =
|
|
1063
|
+
const raw = RawQueryFragment.getKnownFragment(val);
|
|
1063
1064
|
if (raw) {
|
|
1064
1065
|
prop.defaultRaw = this.platform.formatQuery(raw.sql, raw.params);
|
|
1065
1066
|
return;
|
|
1066
1067
|
}
|
|
1067
|
-
if (prop.customType instanceof
|
|
1068
|
+
if (prop.customType instanceof ArrayType && Array.isArray(prop.default)) {
|
|
1068
1069
|
val = prop.customType.convertToDatabaseValue(prop.default, this.platform);
|
|
1069
1070
|
}
|
|
1070
1071
|
prop.defaultRaw = typeof val === 'string' ? `'${val}'` : '' + val;
|
|
@@ -1100,47 +1101,47 @@ class MetadataDiscovery {
|
|
|
1100
1101
|
}
|
|
1101
1102
|
initCustomType(meta, prop) {
|
|
1102
1103
|
// `prop.type` might be actually instance of custom type class
|
|
1103
|
-
if (
|
|
1104
|
+
if (Type.isMappedType(prop.type) && !prop.customType) {
|
|
1104
1105
|
prop.customType = prop.type;
|
|
1105
1106
|
prop.type = prop.customType.constructor.name;
|
|
1106
1107
|
}
|
|
1107
1108
|
// `prop.type` might also be custom type class (not instance), so `typeof MyType` will give us `function`, not `object`
|
|
1108
|
-
if (typeof prop.type === 'function' &&
|
|
1109
|
+
if (typeof prop.type === 'function' && Type.isMappedType(prop.type.prototype) && !prop.customType) {
|
|
1109
1110
|
prop.customType = new prop.type();
|
|
1110
1111
|
prop.type = prop.customType.constructor.name;
|
|
1111
1112
|
}
|
|
1112
1113
|
if (!prop.customType && ['json', 'jsonb'].includes(prop.type?.toLowerCase())) {
|
|
1113
|
-
prop.customType = new
|
|
1114
|
+
prop.customType = new JsonType();
|
|
1114
1115
|
}
|
|
1115
|
-
if (prop.kind ===
|
|
1116
|
-
prop.customType = new
|
|
1116
|
+
if (prop.kind === ReferenceKind.SCALAR && !prop.customType && prop.columnTypes && ['json', 'jsonb'].includes(prop.columnTypes[0])) {
|
|
1117
|
+
prop.customType = new JsonType();
|
|
1117
1118
|
}
|
|
1118
1119
|
if (!prop.customType && prop.array && prop.items) {
|
|
1119
|
-
prop.customType = new
|
|
1120
|
+
prop.customType = new EnumArrayType(`${meta.className}.${prop.name}`, prop.items);
|
|
1120
1121
|
}
|
|
1121
1122
|
// for number arrays we make sure to convert the items to numbers
|
|
1122
1123
|
if (!prop.customType && prop.type === 'number[]') {
|
|
1123
|
-
prop.customType = new
|
|
1124
|
+
prop.customType = new ArrayType(i => +i);
|
|
1124
1125
|
}
|
|
1125
1126
|
// `string[]` can be returned via ts-morph, while reflect metadata will give us just `array`
|
|
1126
1127
|
if (!prop.customType && (prop.type?.toLowerCase() === 'array' || prop.type?.toString().endsWith('[]'))) {
|
|
1127
|
-
prop.customType = new
|
|
1128
|
+
prop.customType = new ArrayType();
|
|
1128
1129
|
}
|
|
1129
1130
|
if (!prop.customType && prop.type?.toLowerCase() === 'buffer') {
|
|
1130
|
-
prop.customType = new
|
|
1131
|
+
prop.customType = new BlobType();
|
|
1131
1132
|
}
|
|
1132
1133
|
if (!prop.customType && prop.type?.toLowerCase() === 'uint8array') {
|
|
1133
|
-
prop.customType = new
|
|
1134
|
+
prop.customType = new Uint8ArrayType();
|
|
1134
1135
|
}
|
|
1135
1136
|
const mappedType = this.getMappedType(prop);
|
|
1136
1137
|
if (prop.fieldNames?.length === 1 && !prop.customType) {
|
|
1137
|
-
[
|
|
1138
|
+
[BigIntType, DoubleType, DecimalType, IntervalType, DateType]
|
|
1138
1139
|
.filter(type => mappedType instanceof type)
|
|
1139
1140
|
.forEach(type => prop.customType = new type());
|
|
1140
1141
|
}
|
|
1141
1142
|
if (prop.customType && !prop.columnTypes) {
|
|
1142
1143
|
const mappedType = this.getMappedType({ columnTypes: [prop.customType.getColumnType(prop, this.platform)] });
|
|
1143
|
-
if (prop.customType.compareAsType() === 'any' && ![
|
|
1144
|
+
if (prop.customType.compareAsType() === 'any' && ![JsonType].some(t => prop.customType instanceof t)) {
|
|
1144
1145
|
prop.runtimeType ??= mappedType.runtimeType;
|
|
1145
1146
|
}
|
|
1146
1147
|
else {
|
|
@@ -1157,19 +1158,20 @@ class MetadataDiscovery {
|
|
|
1157
1158
|
prop.columnTypes ??= [prop.customType.getColumnType(prop, this.platform)];
|
|
1158
1159
|
prop.hasConvertToJSValueSQL = !!prop.customType.convertToJSValueSQL && prop.customType.convertToJSValueSQL('', this.platform) !== '';
|
|
1159
1160
|
prop.hasConvertToDatabaseValueSQL = !!prop.customType.convertToDatabaseValueSQL && prop.customType.convertToDatabaseValueSQL('', this.platform) !== '';
|
|
1160
|
-
if (prop.customType instanceof
|
|
1161
|
+
if (prop.customType instanceof BigIntType && ['string', 'bigint', 'number'].includes(prop.runtimeType.toLowerCase())) {
|
|
1161
1162
|
prop.customType.mode = prop.runtimeType.toLowerCase();
|
|
1162
1163
|
}
|
|
1163
1164
|
}
|
|
1164
|
-
if (
|
|
1165
|
+
if (Type.isMappedType(prop.customType) && prop.kind === ReferenceKind.SCALAR && !prop.type?.toString().endsWith('[]')) {
|
|
1165
1166
|
prop.type = prop.customType.name;
|
|
1166
1167
|
}
|
|
1167
|
-
if (!prop.customType && [
|
|
1168
|
+
if (!prop.customType && [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind) && this.metadata.get(prop.type).compositePK) {
|
|
1168
1169
|
prop.customTypes = [];
|
|
1169
1170
|
for (const pk of this.metadata.get(prop.type).getPrimaryProps()) {
|
|
1170
1171
|
if (pk.customType) {
|
|
1171
1172
|
prop.customTypes.push(pk.customType);
|
|
1172
1173
|
prop.hasConvertToJSValueSQL ||= !!pk.customType.convertToJSValueSQL && pk.customType.convertToJSValueSQL('', this.platform) !== '';
|
|
1174
|
+
/* v8 ignore next */
|
|
1173
1175
|
prop.hasConvertToDatabaseValueSQL ||= !!pk.customType.convertToDatabaseValueSQL && pk.customType.convertToDatabaseValueSQL('', this.platform) !== '';
|
|
1174
1176
|
}
|
|
1175
1177
|
else {
|
|
@@ -1177,7 +1179,7 @@ class MetadataDiscovery {
|
|
|
1177
1179
|
}
|
|
1178
1180
|
}
|
|
1179
1181
|
}
|
|
1180
|
-
if (prop.kind ===
|
|
1182
|
+
if (prop.kind === ReferenceKind.SCALAR && !(mappedType instanceof UnknownType)) {
|
|
1181
1183
|
if (!prop.columnTypes && prop.nativeEnumName && meta.schema !== this.platform.getDefaultSchemaName() && meta.schema && !prop.nativeEnumName.includes('.')) {
|
|
1182
1184
|
prop.columnTypes = [`${meta.schema}.${prop.nativeEnumName}`];
|
|
1183
1185
|
}
|
|
@@ -1186,19 +1188,19 @@ class MetadataDiscovery {
|
|
|
1186
1188
|
}
|
|
1187
1189
|
// use only custom types provided by user, we don't need to use the ones provided by ORM,
|
|
1188
1190
|
// with exception for ArrayType and JsonType, those two are handled in
|
|
1189
|
-
if (!Object.values(
|
|
1191
|
+
if (!Object.values(t).some(type => type === mappedType.constructor)) {
|
|
1190
1192
|
prop.customType ??= mappedType;
|
|
1191
1193
|
}
|
|
1192
1194
|
}
|
|
1193
1195
|
}
|
|
1194
1196
|
initRelation(prop) {
|
|
1195
|
-
if (prop.kind ===
|
|
1197
|
+
if (prop.kind === ReferenceKind.SCALAR) {
|
|
1196
1198
|
return;
|
|
1197
1199
|
}
|
|
1198
1200
|
const meta2 = this.discovered.find(m => m.className === prop.type);
|
|
1199
1201
|
prop.referencedPKs = meta2.primaryKeys;
|
|
1200
1202
|
prop.targetMeta = meta2;
|
|
1201
|
-
if (!prop.formula && prop.persist === false && [
|
|
1203
|
+
if (!prop.formula && prop.persist === false && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && !prop.embedded) {
|
|
1202
1204
|
prop.formula = a => `${a}.${this.platform.quoteIdentifier(prop.fieldNames[0])}`;
|
|
1203
1205
|
}
|
|
1204
1206
|
}
|
|
@@ -1209,7 +1211,7 @@ class MetadataDiscovery {
|
|
|
1209
1211
|
prop.precision ??= pk.precision;
|
|
1210
1212
|
prop.scale ??= pk.scale;
|
|
1211
1213
|
});
|
|
1212
|
-
if (prop.kind ===
|
|
1214
|
+
if (prop.kind === ReferenceKind.SCALAR && (prop.type == null || prop.type === 'object') && prop.columnTypes?.[0]) {
|
|
1213
1215
|
delete prop.type;
|
|
1214
1216
|
const mappedType = this.getMappedType(prop);
|
|
1215
1217
|
prop.type = mappedType.compareAsType();
|
|
@@ -1217,10 +1219,10 @@ class MetadataDiscovery {
|
|
|
1217
1219
|
if (prop.columnTypes || !this.schemaHelper) {
|
|
1218
1220
|
return;
|
|
1219
1221
|
}
|
|
1220
|
-
if (prop.kind ===
|
|
1222
|
+
if (prop.kind === ReferenceKind.SCALAR) {
|
|
1221
1223
|
const mappedType = this.getMappedType(prop);
|
|
1222
1224
|
const SCALAR_TYPES = ['string', 'number', 'boolean', 'bigint', 'Date', 'Buffer', 'RegExp', 'any', 'unknown'];
|
|
1223
|
-
if (mappedType instanceof
|
|
1225
|
+
if (mappedType instanceof UnknownType
|
|
1224
1226
|
&& !prop.columnTypes
|
|
1225
1227
|
// it could be a runtime type from reflect-metadata
|
|
1226
1228
|
&& !SCALAR_TYPES.includes(prop.type)
|
|
@@ -1234,7 +1236,7 @@ class MetadataDiscovery {
|
|
|
1234
1236
|
}
|
|
1235
1237
|
return;
|
|
1236
1238
|
}
|
|
1237
|
-
if (prop.kind ===
|
|
1239
|
+
if (prop.kind === ReferenceKind.EMBEDDED && prop.object && !prop.columnTypes) {
|
|
1238
1240
|
prop.columnTypes = [this.platform.getJsonDeclarationSQL()];
|
|
1239
1241
|
return;
|
|
1240
1242
|
}
|
|
@@ -1258,13 +1260,13 @@ class MetadataDiscovery {
|
|
|
1258
1260
|
if (prop.customType) {
|
|
1259
1261
|
return prop.customType;
|
|
1260
1262
|
}
|
|
1261
|
-
/*
|
|
1263
|
+
/* v8 ignore next */
|
|
1262
1264
|
let t = prop.columnTypes?.[0] ?? prop.type ?? '';
|
|
1263
1265
|
if (prop.nativeEnumName) {
|
|
1264
1266
|
t = 'enum';
|
|
1265
1267
|
}
|
|
1266
1268
|
else if (prop.enum) {
|
|
1267
|
-
t = prop.items?.every(item =>
|
|
1269
|
+
t = prop.items?.every(item => Utils.isString(item)) ? 'enum' : 'tinyint';
|
|
1268
1270
|
}
|
|
1269
1271
|
if (t === 'Date') {
|
|
1270
1272
|
t = 'datetime';
|
|
@@ -1287,7 +1289,7 @@ class MetadataDiscovery {
|
|
|
1287
1289
|
if (prop.unsigned != null) {
|
|
1288
1290
|
return;
|
|
1289
1291
|
}
|
|
1290
|
-
if ([
|
|
1292
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
1291
1293
|
const meta2 = this.metadata.get(prop.type);
|
|
1292
1294
|
prop.unsigned = meta2.getPrimaryProps().some(pk => {
|
|
1293
1295
|
this.initUnsigned(pk);
|
|
@@ -1299,17 +1301,17 @@ class MetadataDiscovery {
|
|
|
1299
1301
|
}
|
|
1300
1302
|
initIndexes(meta, prop) {
|
|
1301
1303
|
const hasIndex = meta.indexes.some(idx => idx.properties?.length === 1 && idx.properties[0] === prop.name);
|
|
1302
|
-
if (prop.kind ===
|
|
1304
|
+
if (prop.kind === ReferenceKind.MANY_TO_ONE && this.platform.indexForeignKeys() && !hasIndex) {
|
|
1303
1305
|
prop.index ??= true;
|
|
1304
1306
|
}
|
|
1305
1307
|
}
|
|
1306
1308
|
async getEntityClassOrSchema(path, name) {
|
|
1307
|
-
const exports = await
|
|
1309
|
+
const exports = await Utils.dynamicImport(path);
|
|
1308
1310
|
const targets = Object.values(exports)
|
|
1309
|
-
.filter(item => item instanceof
|
|
1311
|
+
.filter(item => item instanceof EntitySchema || (item instanceof Function && MetadataStorage.isKnownEntity(item.name)));
|
|
1310
1312
|
// ignore class implementations that are linked from an EntitySchema
|
|
1311
1313
|
for (const item of targets) {
|
|
1312
|
-
if (item instanceof
|
|
1314
|
+
if (item instanceof EntitySchema) {
|
|
1313
1315
|
targets.forEach((item2, idx) => {
|
|
1314
1316
|
if (item.meta.class === item2) {
|
|
1315
1317
|
targets.splice(idx, 1);
|
|
@@ -1321,18 +1323,17 @@ class MetadataDiscovery {
|
|
|
1321
1323
|
return targets;
|
|
1322
1324
|
}
|
|
1323
1325
|
const target = exports.default ?? exports[name];
|
|
1324
|
-
/*
|
|
1326
|
+
/* v8 ignore next 3 */
|
|
1325
1327
|
if (!target) {
|
|
1326
|
-
throw
|
|
1328
|
+
throw MetadataError.entityNotFound(name, path.replace(this.config.get('baseDir'), '.'));
|
|
1327
1329
|
}
|
|
1328
1330
|
return [target];
|
|
1329
1331
|
}
|
|
1330
1332
|
shouldForceConstructorUsage(meta) {
|
|
1331
1333
|
const forceConstructor = this.config.get('forceEntityConstructor');
|
|
1332
1334
|
if (Array.isArray(forceConstructor)) {
|
|
1333
|
-
return forceConstructor.some(cls =>
|
|
1335
|
+
return forceConstructor.some(cls => Utils.className(cls) === meta.className);
|
|
1334
1336
|
}
|
|
1335
1337
|
return forceConstructor;
|
|
1336
1338
|
}
|
|
1337
1339
|
}
|
|
1338
|
-
exports.MetadataDiscovery = MetadataDiscovery;
|