@mikro-orm/core 7.0.0-dev.9 → 7.0.0-dev.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EntityManager.d.ts +77 -48
- package/EntityManager.js +288 -225
- package/MikroORM.d.ts +40 -31
- package/MikroORM.js +98 -137
- package/README.md +3 -2
- package/cache/FileCacheAdapter.d.ts +1 -1
- package/cache/FileCacheAdapter.js +6 -5
- package/cache/GeneratedCacheAdapter.d.ts +0 -1
- package/cache/GeneratedCacheAdapter.js +0 -2
- package/cache/index.d.ts +0 -1
- package/cache/index.js +0 -1
- package/connections/Connection.d.ts +11 -7
- package/connections/Connection.js +16 -14
- package/drivers/DatabaseDriver.d.ts +11 -5
- package/drivers/DatabaseDriver.js +23 -11
- package/drivers/IDatabaseDriver.d.ts +25 -4
- package/entity/BaseEntity.d.ts +0 -1
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +95 -30
- package/entity/Collection.js +432 -93
- package/entity/EntityAssigner.d.ts +1 -1
- package/entity/EntityAssigner.js +17 -9
- package/entity/EntityFactory.d.ts +7 -0
- package/entity/EntityFactory.js +63 -41
- package/entity/EntityHelper.js +26 -12
- package/entity/EntityLoader.d.ts +5 -4
- package/entity/EntityLoader.js +63 -38
- package/entity/EntityRepository.d.ts +1 -1
- package/entity/Reference.d.ts +6 -5
- package/entity/Reference.js +34 -9
- package/entity/WrappedEntity.d.ts +2 -7
- package/entity/WrappedEntity.js +2 -7
- package/entity/defineEntity.d.ts +568 -0
- package/entity/defineEntity.js +529 -0
- package/entity/index.d.ts +3 -2
- package/entity/index.js +3 -2
- package/entity/utils.d.ts +7 -0
- package/entity/utils.js +16 -4
- package/entity/validators.d.ts +11 -0
- package/entity/validators.js +65 -0
- package/enums.d.ts +21 -6
- package/enums.js +14 -1
- package/errors.d.ts +10 -2
- package/errors.js +29 -10
- package/events/EventManager.d.ts +2 -1
- package/events/EventManager.js +19 -11
- package/events/EventSubscriber.d.ts +3 -1
- package/hydration/Hydrator.js +1 -2
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +35 -25
- package/index.d.ts +2 -2
- package/index.js +1 -2
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/DefaultLogger.js +1 -0
- package/logging/SimpleLogger.d.ts +1 -1
- package/logging/index.d.ts +1 -0
- package/logging/index.js +1 -0
- package/logging/inspect.d.ts +2 -0
- package/logging/inspect.js +16 -0
- package/metadata/EntitySchema.d.ts +9 -13
- package/metadata/EntitySchema.js +44 -26
- package/metadata/MetadataDiscovery.d.ts +6 -9
- package/metadata/MetadataDiscovery.js +165 -205
- package/metadata/MetadataProvider.d.ts +11 -2
- package/metadata/MetadataProvider.js +44 -2
- package/metadata/MetadataStorage.d.ts +1 -6
- package/metadata/MetadataStorage.js +6 -18
- package/metadata/MetadataValidator.d.ts +0 -7
- package/metadata/MetadataValidator.js +0 -10
- package/metadata/discover-entities.d.ts +5 -0
- package/metadata/discover-entities.js +40 -0
- package/metadata/index.d.ts +1 -1
- package/metadata/index.js +1 -1
- package/metadata/types.d.ts +480 -0
- package/metadata/types.js +1 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +5 -1
- package/naming-strategy/AbstractNamingStrategy.js +8 -2
- package/naming-strategy/NamingStrategy.d.ts +11 -1
- package/not-supported.d.ts +2 -0
- package/not-supported.js +4 -0
- package/package.json +18 -10
- package/platforms/ExceptionConverter.js +1 -1
- package/platforms/Platform.d.ts +6 -13
- package/platforms/Platform.js +15 -41
- package/serialization/EntitySerializer.d.ts +2 -0
- package/serialization/EntitySerializer.js +32 -14
- package/serialization/EntityTransformer.js +22 -12
- package/serialization/SerializationContext.js +16 -13
- package/types/ArrayType.d.ts +1 -1
- package/types/ArrayType.js +2 -3
- package/types/BigIntType.d.ts +8 -6
- package/types/BigIntType.js +1 -1
- package/types/BlobType.d.ts +0 -1
- package/types/BlobType.js +0 -3
- package/types/BooleanType.d.ts +2 -1
- package/types/BooleanType.js +3 -0
- package/types/DecimalType.d.ts +6 -4
- package/types/DecimalType.js +3 -3
- package/types/DoubleType.js +2 -2
- package/types/EnumArrayType.js +1 -2
- package/types/JsonType.d.ts +1 -1
- package/types/JsonType.js +7 -2
- package/types/TinyIntType.js +1 -1
- package/types/Type.d.ts +2 -4
- package/types/Type.js +3 -3
- package/types/Uint8ArrayType.d.ts +0 -1
- package/types/Uint8ArrayType.js +1 -4
- package/types/index.d.ts +1 -1
- package/typings.d.ts +109 -73
- package/typings.js +38 -35
- package/unit-of-work/ChangeSet.d.ts +0 -3
- package/unit-of-work/ChangeSet.js +2 -2
- package/unit-of-work/ChangeSetComputer.d.ts +1 -3
- package/unit-of-work/ChangeSetComputer.js +11 -9
- package/unit-of-work/ChangeSetPersister.d.ts +5 -4
- package/unit-of-work/ChangeSetPersister.js +51 -19
- package/unit-of-work/UnitOfWork.d.ts +8 -1
- package/unit-of-work/UnitOfWork.js +91 -49
- package/utils/AbstractSchemaGenerator.d.ts +5 -5
- package/utils/AbstractSchemaGenerator.js +11 -9
- package/utils/Configuration.d.ts +757 -206
- package/utils/Configuration.js +140 -188
- package/utils/ConfigurationLoader.d.ts +1 -54
- package/utils/ConfigurationLoader.js +1 -352
- package/utils/Cursor.d.ts +0 -3
- package/utils/Cursor.js +6 -3
- package/utils/DataloaderUtils.d.ts +15 -5
- package/utils/DataloaderUtils.js +54 -8
- package/utils/EntityComparator.d.ts +8 -4
- package/utils/EntityComparator.js +52 -17
- package/utils/QueryHelper.d.ts +9 -1
- package/utils/QueryHelper.js +70 -9
- package/utils/RawQueryFragment.d.ts +36 -13
- package/utils/RawQueryFragment.js +36 -16
- package/utils/TransactionManager.d.ts +65 -0
- package/utils/TransactionManager.js +223 -0
- package/utils/Utils.d.ts +8 -97
- package/utils/Utils.js +82 -302
- package/utils/clone.js +2 -3
- package/utils/env-vars.d.ts +3 -0
- package/utils/env-vars.js +87 -0
- package/utils/fs-utils.d.ts +12 -0
- package/utils/fs-utils.js +97 -0
- package/utils/index.d.ts +2 -1
- package/utils/index.js +2 -1
- package/utils/upsert-utils.d.ts +7 -2
- package/utils/upsert-utils.js +55 -4
- package/decorators/Check.d.ts +0 -3
- package/decorators/Check.js +0 -13
- package/decorators/CreateRequestContext.d.ts +0 -3
- package/decorators/CreateRequestContext.js +0 -32
- package/decorators/Embeddable.d.ts +0 -8
- package/decorators/Embeddable.js +0 -11
- package/decorators/Embedded.d.ts +0 -18
- package/decorators/Embedded.js +0 -18
- package/decorators/Entity.d.ts +0 -18
- package/decorators/Entity.js +0 -12
- package/decorators/Enum.d.ts +0 -9
- package/decorators/Enum.js +0 -16
- package/decorators/Filter.d.ts +0 -2
- package/decorators/Filter.js +0 -8
- package/decorators/Formula.d.ts +0 -4
- package/decorators/Formula.js +0 -15
- package/decorators/Indexed.d.ts +0 -19
- package/decorators/Indexed.js +0 -20
- package/decorators/ManyToMany.d.ts +0 -40
- package/decorators/ManyToMany.js +0 -14
- package/decorators/ManyToOne.d.ts +0 -30
- package/decorators/ManyToOne.js +0 -14
- package/decorators/OneToMany.d.ts +0 -28
- package/decorators/OneToMany.js +0 -17
- package/decorators/OneToOne.d.ts +0 -24
- package/decorators/OneToOne.js +0 -7
- package/decorators/PrimaryKey.d.ts +0 -8
- package/decorators/PrimaryKey.js +0 -20
- package/decorators/Property.d.ts +0 -250
- package/decorators/Property.js +0 -32
- package/decorators/Transactional.d.ts +0 -13
- package/decorators/Transactional.js +0 -28
- package/decorators/hooks.d.ts +0 -16
- package/decorators/hooks.js +0 -47
- package/decorators/index.d.ts +0 -17
- package/decorators/index.js +0 -17
- package/entity/ArrayCollection.d.ts +0 -116
- package/entity/ArrayCollection.js +0 -402
- package/entity/EntityValidator.d.ts +0 -19
- package/entity/EntityValidator.js +0 -150
- package/metadata/ReflectMetadataProvider.d.ts +0 -8
- package/metadata/ReflectMetadataProvider.js +0 -44
- package/utils/resolveContextProvider.d.ts +0 -10
- package/utils/resolveContextProvider.js +0 -28
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { basename, extname } from 'node:path';
|
|
2
|
-
import globby from 'globby';
|
|
3
1
|
import { EntityMetadata, } from '../typings.js';
|
|
4
2
|
import { Utils } from '../utils/Utils.js';
|
|
5
3
|
import { MetadataValidator } from './MetadataValidator.js';
|
|
@@ -7,7 +5,7 @@ import { MetadataStorage } from './MetadataStorage.js';
|
|
|
7
5
|
import { EntitySchema } from './EntitySchema.js';
|
|
8
6
|
import { Cascade, ReferenceKind } from '../enums.js';
|
|
9
7
|
import { MetadataError } from '../errors.js';
|
|
10
|
-
import {
|
|
8
|
+
import { t, Type } from '../types/index.js';
|
|
11
9
|
import { colors } from '../logging/colors.js';
|
|
12
10
|
import { raw, RawQueryFragment } from '../utils/RawQueryFragment.js';
|
|
13
11
|
export class MetadataDiscovery {
|
|
@@ -16,7 +14,6 @@ export class MetadataDiscovery {
|
|
|
16
14
|
config;
|
|
17
15
|
namingStrategy;
|
|
18
16
|
metadataProvider;
|
|
19
|
-
cache;
|
|
20
17
|
logger;
|
|
21
18
|
schemaHelper;
|
|
22
19
|
validator = new MetadataValidator();
|
|
@@ -27,11 +24,11 @@ export class MetadataDiscovery {
|
|
|
27
24
|
this.config = config;
|
|
28
25
|
this.namingStrategy = this.config.getNamingStrategy();
|
|
29
26
|
this.metadataProvider = this.config.getMetadataProvider();
|
|
30
|
-
this.cache = this.config.getMetadataCacheAdapter();
|
|
31
27
|
this.logger = this.config.getLogger();
|
|
32
28
|
this.schemaHelper = this.platform.getSchemaHelper();
|
|
33
29
|
}
|
|
34
30
|
async discover(preferTs = true) {
|
|
31
|
+
this.discovered.length = 0;
|
|
35
32
|
const startTime = Date.now();
|
|
36
33
|
this.logger.log('discovery', `ORM entity discovery started, using ${colors.cyan(this.metadataProvider.constructor.name)}`);
|
|
37
34
|
await this.findEntities(preferTs);
|
|
@@ -47,10 +44,12 @@ export class MetadataDiscovery {
|
|
|
47
44
|
await this.config.get('discovery').afterDiscovered?.(storage, this.platform);
|
|
48
45
|
return storage;
|
|
49
46
|
}
|
|
50
|
-
discoverSync(
|
|
47
|
+
discoverSync() {
|
|
48
|
+
this.discovered.length = 0;
|
|
51
49
|
const startTime = Date.now();
|
|
52
50
|
this.logger.log('discovery', `ORM entity discovery started, using ${colors.cyan(this.metadataProvider.constructor.name)} in sync mode`);
|
|
53
|
-
this.
|
|
51
|
+
const refs = this.config.get('entities');
|
|
52
|
+
this.discoverReferences(refs);
|
|
54
53
|
for (const meta of this.discovered) {
|
|
55
54
|
/* v8 ignore next */
|
|
56
55
|
void this.config.get('discovery').onMetadata?.(meta, this.platform);
|
|
@@ -63,6 +62,9 @@ export class MetadataDiscovery {
|
|
|
63
62
|
void this.config.get('discovery').afterDiscovered?.(storage, this.platform);
|
|
64
63
|
return storage;
|
|
65
64
|
}
|
|
65
|
+
validateDiscovered(metadata) {
|
|
66
|
+
return this.validator.validateDiscovered(metadata, this.config.get('discovery'));
|
|
67
|
+
}
|
|
66
68
|
mapDiscoveredEntities() {
|
|
67
69
|
const discovered = new MetadataStorage();
|
|
68
70
|
this.discovered
|
|
@@ -74,11 +76,41 @@ export class MetadataDiscovery {
|
|
|
74
76
|
});
|
|
75
77
|
return discovered;
|
|
76
78
|
}
|
|
79
|
+
initAccessors(meta) {
|
|
80
|
+
for (const prop of Object.values(meta.properties)) {
|
|
81
|
+
if (!prop.accessor || meta.properties[prop.accessor]) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const desc = Object.getOwnPropertyDescriptor(meta.prototype, prop.name);
|
|
85
|
+
if (desc?.get || desc?.set) {
|
|
86
|
+
this.initFieldName(prop);
|
|
87
|
+
const accessor = prop.name;
|
|
88
|
+
prop.name = typeof prop.accessor === 'string' ? prop.accessor : prop.name;
|
|
89
|
+
if (prop.accessor === true) {
|
|
90
|
+
prop.getter = prop.setter = true;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
prop.getter = prop.setter = false;
|
|
94
|
+
}
|
|
95
|
+
prop.accessor = accessor;
|
|
96
|
+
prop.serializedName ??= accessor;
|
|
97
|
+
Utils.renameKey(meta.properties, accessor, prop.name);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
const name = prop.name;
|
|
101
|
+
prop.name = prop.accessor;
|
|
102
|
+
this.initFieldName(prop);
|
|
103
|
+
prop.serializedName ??= prop.accessor;
|
|
104
|
+
prop.name = name;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
77
108
|
processDiscoveredEntities(discovered) {
|
|
78
109
|
for (const meta of discovered) {
|
|
79
110
|
let i = 1;
|
|
80
111
|
Object.values(meta.properties).forEach(prop => meta.propertyOrder.set(prop.name, i++));
|
|
81
112
|
Object.values(meta.properties).forEach(prop => this.initPolyEmbeddables(prop, discovered));
|
|
113
|
+
this.initAccessors(meta);
|
|
82
114
|
}
|
|
83
115
|
// ignore base entities (not annotated with @Entity)
|
|
84
116
|
const filtered = discovered.filter(meta => meta.root.name);
|
|
@@ -101,10 +133,6 @@ export class MetadataDiscovery {
|
|
|
101
133
|
this.initDefaultValue(prop);
|
|
102
134
|
this.inferTypeFromDefault(prop);
|
|
103
135
|
this.initColumnType(prop);
|
|
104
|
-
// change tracking on scalars is used only for "auto" flushMode
|
|
105
|
-
if (this.config.get('flushMode') !== 'auto' && [ReferenceKind.SCALAR, ReferenceKind.EMBEDDED].includes(prop.kind)) {
|
|
106
|
-
prop.trackChanges = false;
|
|
107
|
-
}
|
|
108
136
|
}
|
|
109
137
|
}
|
|
110
138
|
filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initIndexes(meta, prop)));
|
|
@@ -114,38 +142,27 @@ export class MetadataDiscovery {
|
|
|
114
142
|
discovered.push(...this.processEntity(meta));
|
|
115
143
|
}
|
|
116
144
|
discovered.forEach(meta => meta.sync(true));
|
|
117
|
-
|
|
118
|
-
// override the path in the options, so we can log it from the CLI in `cache:generate` command
|
|
119
|
-
if (combinedCachePath) {
|
|
120
|
-
this.config.get('metadataCache').combined = combinedCachePath;
|
|
121
|
-
}
|
|
145
|
+
this.metadataProvider.combineCache();
|
|
122
146
|
return discovered.map(meta => {
|
|
123
147
|
meta = this.metadata.get(meta.className);
|
|
124
148
|
meta.sync(true);
|
|
125
149
|
return meta;
|
|
126
150
|
});
|
|
127
151
|
}
|
|
128
|
-
findEntities(preferTs
|
|
129
|
-
this.
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
152
|
+
async findEntities(preferTs) {
|
|
153
|
+
const { entities, entitiesTs, baseDir } = this.config.getAll();
|
|
154
|
+
const targets = (preferTs && entitiesTs.length > 0) ? entitiesTs : entities;
|
|
155
|
+
const processed = [];
|
|
156
|
+
for (const entity of targets) {
|
|
157
|
+
if (typeof entity === 'string') {
|
|
158
|
+
const { discoverEntities } = await import('@mikro-orm/core/file-discovery');
|
|
159
|
+
processed.push(...await discoverEntities(entity, { baseDir }));
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
processed.push(entity);
|
|
137
163
|
}
|
|
138
|
-
return this.discoverDirectories(paths).then(() => {
|
|
139
|
-
this.discoverReferences(refs);
|
|
140
|
-
this.discoverMissingTargets();
|
|
141
|
-
this.validator.validateDiscovered(this.discovered, options);
|
|
142
|
-
return this.discovered;
|
|
143
|
-
});
|
|
144
164
|
}
|
|
145
|
-
this.discoverReferences(
|
|
146
|
-
this.discoverMissingTargets();
|
|
147
|
-
this.validator.validateDiscovered(this.discovered, options);
|
|
148
|
-
return this.discovered;
|
|
165
|
+
return this.discoverReferences(processed);
|
|
149
166
|
}
|
|
150
167
|
discoverMissingTargets() {
|
|
151
168
|
const unwrap = (type) => type
|
|
@@ -173,50 +190,20 @@ export class MetadataDiscovery {
|
|
|
173
190
|
}
|
|
174
191
|
tryDiscoverTargets(targets) {
|
|
175
192
|
for (const target of targets) {
|
|
176
|
-
|
|
177
|
-
|
|
193
|
+
const isDiscoverable = typeof target === 'function' || target instanceof EntitySchema;
|
|
194
|
+
if (isDiscoverable && target.name && !this.metadata.has(target.name)) {
|
|
195
|
+
this.discoverReferences([target], false);
|
|
178
196
|
this.discoverMissingTargets();
|
|
179
197
|
}
|
|
180
198
|
}
|
|
181
199
|
}
|
|
182
|
-
|
|
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`);
|
|
186
|
-
const found = [];
|
|
187
|
-
for (const filepath of files) {
|
|
188
|
-
const filename = basename(filepath);
|
|
189
|
-
if (!filename.match(/\.[cm]?[jt]s$/) ||
|
|
190
|
-
filename.endsWith('.js.map') ||
|
|
191
|
-
filename.match(/\.d\.[cm]?ts/) ||
|
|
192
|
-
filename.startsWith('.') ||
|
|
193
|
-
filename.match(/index\.[cm]?[jt]s$/)) {
|
|
194
|
-
this.logger.log('discovery', `- ignoring file ${filename}`);
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
const name = this.namingStrategy.getClassName(filename);
|
|
198
|
-
const path = Utils.normalizePath(this.config.get('baseDir'), filepath);
|
|
199
|
-
const targets = await this.getEntityClassOrSchema(path, name);
|
|
200
|
-
for (const target of targets) {
|
|
201
|
-
if (!(target instanceof Function) && !(target instanceof EntitySchema)) {
|
|
202
|
-
this.logger.log('discovery', `- ignoring file ${filename}`);
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
const entity = this.prepare(target);
|
|
206
|
-
const schema = this.getSchema(entity, path);
|
|
207
|
-
const meta = schema.init().meta;
|
|
208
|
-
this.metadata.set(meta.className, meta);
|
|
209
|
-
found.push([schema, path]);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
for (const [schema, path] of found) {
|
|
213
|
-
this.discoverEntity(schema, path);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
discoverReferences(refs) {
|
|
200
|
+
discoverReferences(refs, validate = true) {
|
|
217
201
|
const found = [];
|
|
218
202
|
for (const entity of refs) {
|
|
219
|
-
|
|
203
|
+
if (typeof entity === 'string') {
|
|
204
|
+
throw new Error('Folder based discovery requires the async `MikroORM.init()` method.');
|
|
205
|
+
}
|
|
206
|
+
const schema = this.getSchema(entity);
|
|
220
207
|
const meta = schema.init().meta;
|
|
221
208
|
this.metadata.set(meta.className, meta);
|
|
222
209
|
found.push(schema);
|
|
@@ -225,20 +212,27 @@ export class MetadataDiscovery {
|
|
|
225
212
|
for (const meta of this.metadata) {
|
|
226
213
|
let parent = meta.extends;
|
|
227
214
|
if (parent instanceof EntitySchema && !this.metadata.has(parent.meta.className)) {
|
|
228
|
-
this.discoverReferences([parent]);
|
|
215
|
+
this.discoverReferences([parent], false);
|
|
229
216
|
}
|
|
230
|
-
|
|
217
|
+
if (typeof parent === 'function' && parent.name && !this.metadata.has(parent.name)) {
|
|
218
|
+
this.discoverReferences([parent], false);
|
|
219
|
+
}
|
|
220
|
+
/* v8 ignore next */
|
|
231
221
|
if (!meta.class) {
|
|
232
222
|
continue;
|
|
233
223
|
}
|
|
234
224
|
parent = Object.getPrototypeOf(meta.class);
|
|
235
225
|
if (parent.name !== '' && !this.metadata.has(parent.name)) {
|
|
236
|
-
this.discoverReferences([parent]);
|
|
226
|
+
this.discoverReferences([parent], false);
|
|
237
227
|
}
|
|
238
228
|
}
|
|
239
229
|
for (const schema of found) {
|
|
240
230
|
this.discoverEntity(schema);
|
|
241
231
|
}
|
|
232
|
+
this.discoverMissingTargets();
|
|
233
|
+
if (validate) {
|
|
234
|
+
this.validateDiscovered(this.discovered);
|
|
235
|
+
}
|
|
242
236
|
return this.discovered.filter(meta => found.find(m => m.name === meta.className));
|
|
243
237
|
}
|
|
244
238
|
reset(className) {
|
|
@@ -248,23 +242,13 @@ export class MetadataDiscovery {
|
|
|
248
242
|
this.discovered.splice(exists, 1);
|
|
249
243
|
}
|
|
250
244
|
}
|
|
251
|
-
|
|
252
|
-
/* v8 ignore next 3 */
|
|
253
|
-
if ('schema' in entity && entity.schema instanceof EntitySchema) {
|
|
254
|
-
return entity.schema;
|
|
255
|
-
}
|
|
245
|
+
getSchema(entity) {
|
|
256
246
|
if (EntitySchema.REGISTRY.has(entity)) {
|
|
257
|
-
|
|
247
|
+
entity = EntitySchema.REGISTRY.get(entity);
|
|
258
248
|
}
|
|
259
|
-
return entity;
|
|
260
|
-
}
|
|
261
|
-
getSchema(entity, filepath) {
|
|
262
249
|
if (entity instanceof EntitySchema) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
MetadataStorage.getMetadata(entity.meta.className, filepath);
|
|
266
|
-
}
|
|
267
|
-
return entity;
|
|
250
|
+
const meta = Utils.copy(entity.meta, false);
|
|
251
|
+
return EntitySchema.fromMetadata(meta);
|
|
268
252
|
}
|
|
269
253
|
const path = entity[MetadataStorage.PATH_SYMBOL];
|
|
270
254
|
if (path) {
|
|
@@ -279,16 +263,26 @@ export class MetadataDiscovery {
|
|
|
279
263
|
schema.setClass(entity);
|
|
280
264
|
return schema;
|
|
281
265
|
}
|
|
282
|
-
|
|
283
|
-
|
|
266
|
+
getRootEntity(meta) {
|
|
267
|
+
const base = meta.extends && this.metadata.find(Utils.className(meta.extends));
|
|
268
|
+
if (!base || base === meta) { // make sure we do not fall into infinite loop
|
|
269
|
+
return meta;
|
|
270
|
+
}
|
|
271
|
+
const root = this.getRootEntity(base);
|
|
272
|
+
if (root.discriminatorColumn) {
|
|
273
|
+
return root;
|
|
274
|
+
}
|
|
275
|
+
return meta;
|
|
276
|
+
}
|
|
277
|
+
discoverEntity(schema) {
|
|
284
278
|
const meta = schema.meta;
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
const
|
|
279
|
+
const path = meta.path;
|
|
280
|
+
this.logger.log('discovery', `- processing entity ${colors.cyan(meta.className)}${colors.grey(path ? ` (${path})` : '')}`);
|
|
281
|
+
const root = this.getRootEntity(meta);
|
|
282
|
+
schema.meta.path = Utils.relativePath(meta.path, this.config.get('baseDir'));
|
|
283
|
+
const cache = this.metadataProvider.getCachedMetadata(meta, root);
|
|
288
284
|
if (cache) {
|
|
289
285
|
this.logger.log('discovery', `- using cached metadata for entity ${colors.cyan(meta.className)}`);
|
|
290
|
-
this.metadataProvider.loadFromCache(meta, cache);
|
|
291
|
-
meta.root = root;
|
|
292
286
|
this.discovered.push(meta);
|
|
293
287
|
return;
|
|
294
288
|
}
|
|
@@ -297,50 +291,18 @@ export class MetadataDiscovery {
|
|
|
297
291
|
this.inferDefaultValue(meta, prop);
|
|
298
292
|
}
|
|
299
293
|
// if the definition is using EntitySchema we still want it to go through the metadata provider to validate no types are missing
|
|
300
|
-
this.metadataProvider.loadEntityMetadata(meta
|
|
294
|
+
this.metadataProvider.loadEntityMetadata(meta);
|
|
301
295
|
if (!meta.collection && meta.name) {
|
|
302
296
|
const entityName = root.discriminatorColumn ? root.name : meta.name;
|
|
303
297
|
meta.collection = this.namingStrategy.classToTableName(entityName);
|
|
304
298
|
}
|
|
305
|
-
|
|
306
|
-
this.saveToCache(meta);
|
|
299
|
+
this.metadataProvider.saveToCache(meta);
|
|
307
300
|
meta.root = root;
|
|
308
301
|
this.discovered.push(meta);
|
|
309
302
|
}
|
|
310
|
-
saveToCache(meta) {
|
|
311
|
-
if (!this.metadataProvider.useCache()) {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
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');
|
|
319
|
-
}
|
|
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
|
-
}
|
|
329
|
-
[
|
|
330
|
-
'prototype', 'props', 'referencingProperties', 'propertyOrder', 'relations',
|
|
331
|
-
'concurrencyCheckKeys', 'checks',
|
|
332
|
-
].forEach(key => delete copy[key]);
|
|
333
|
-
// base entity without properties might not have path, but nothing to cache there
|
|
334
|
-
if (meta.path) {
|
|
335
|
-
this.cache.set(meta.className + extname(meta.path), copy, meta.path);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
303
|
initNullability(prop) {
|
|
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));
|
|
341
|
-
}
|
|
342
304
|
if (prop.kind === ReferenceKind.ONE_TO_ONE) {
|
|
343
|
-
return Utils.defaultValue(prop, 'nullable', prop.optional || !prop.owner
|
|
305
|
+
return Utils.defaultValue(prop, 'nullable', prop.optional || !prop.owner);
|
|
344
306
|
}
|
|
345
307
|
return Utils.defaultValue(prop, 'nullable', prop.optional);
|
|
346
308
|
}
|
|
@@ -375,7 +337,7 @@ export class MetadataDiscovery {
|
|
|
375
337
|
if (prop.joinColumns.length !== prop.columnTypes.length) {
|
|
376
338
|
prop.columnTypes = prop.joinColumns.flatMap(field => {
|
|
377
339
|
const matched = meta.props.find(p => p.fieldNames?.includes(field));
|
|
378
|
-
/* v8 ignore next
|
|
340
|
+
/* v8 ignore next */
|
|
379
341
|
if (!matched) {
|
|
380
342
|
throw MetadataError.fromWrongForeignKey(meta, prop, 'columnTypes');
|
|
381
343
|
}
|
|
@@ -497,10 +459,9 @@ export class MetadataDiscovery {
|
|
|
497
459
|
}
|
|
498
460
|
this.initOwnColumns(meta);
|
|
499
461
|
meta.simplePK = pks.length === 1 && pks[0].kind === ReferenceKind.SCALAR && !pks[0].customType && pks[0].runtimeType !== 'Date';
|
|
500
|
-
meta.serializedPrimaryKey
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
serializedPKProp.persist = false;
|
|
462
|
+
meta.serializedPrimaryKey ??= meta.props.find(prop => prop.serializedPrimaryKey)?.name;
|
|
463
|
+
if (meta.serializedPrimaryKey && meta.serializedPrimaryKey !== meta.primaryKeys[0]) {
|
|
464
|
+
meta.properties[meta.serializedPrimaryKey].persist ??= false;
|
|
504
465
|
}
|
|
505
466
|
if (this.platform.usesPivotTable()) {
|
|
506
467
|
return Object.values(meta.properties)
|
|
@@ -539,7 +500,7 @@ export class MetadataDiscovery {
|
|
|
539
500
|
}
|
|
540
501
|
else if (fks.length >= 2) {
|
|
541
502
|
[first, second] = fks;
|
|
542
|
-
/* v8 ignore next
|
|
503
|
+
/* v8 ignore next */
|
|
543
504
|
}
|
|
544
505
|
else {
|
|
545
506
|
return [];
|
|
@@ -618,7 +579,7 @@ export class MetadataDiscovery {
|
|
|
618
579
|
}
|
|
619
580
|
data.properties[meta.name + '_owner'] = this.definePivotProperty(prop, meta.name + '_owner', meta.className, targetType + '_inverse', true, meta.className === targetType);
|
|
620
581
|
data.properties[targetType + '_inverse'] = this.definePivotProperty(prop, targetType + '_inverse', targetType, meta.name + '_owner', false, meta.className === targetType);
|
|
621
|
-
return this.metadata.set(data.className, data);
|
|
582
|
+
return this.metadata.set(data.className, EntitySchema.fromMetadata(data).init().meta);
|
|
622
583
|
}
|
|
623
584
|
defineFixedOrderProperty(prop, targetType) {
|
|
624
585
|
const pk = prop.fixedOrderColumn || this.namingStrategy.referenceColumnName();
|
|
@@ -653,6 +614,7 @@ export class MetadataDiscovery {
|
|
|
653
614
|
autoincrement: false,
|
|
654
615
|
updateRule: prop.updateRule,
|
|
655
616
|
deleteRule: prop.deleteRule,
|
|
617
|
+
createForeignKeyConstraint: prop.createForeignKeyConstraint,
|
|
656
618
|
};
|
|
657
619
|
if (selfReferencing && !this.platform.supportsMultipleCascadePaths()) {
|
|
658
620
|
ret.updateRule ??= 'no action';
|
|
@@ -739,12 +701,9 @@ export class MetadataDiscovery {
|
|
|
739
701
|
Utils.keys(base.hooks).forEach(type => {
|
|
740
702
|
meta.hooks[type] = Utils.unique([...base.hooks[type], ...(meta.hooks[type] || [])]);
|
|
741
703
|
});
|
|
742
|
-
if (meta.constructorParams
|
|
704
|
+
if ((meta.constructorParams?.length ?? 0) === 0 && (base.constructorParams?.length ?? 0) > 0) {
|
|
743
705
|
meta.constructorParams = [...base.constructorParams];
|
|
744
706
|
}
|
|
745
|
-
if (meta.toJsonParams.length === 0 && base.toJsonParams.length > 0) {
|
|
746
|
-
meta.toJsonParams = [...base.toJsonParams];
|
|
747
|
-
}
|
|
748
707
|
return order;
|
|
749
708
|
}
|
|
750
709
|
initPolyEmbeddables(embeddedProp, discovered, visited = new Set()) {
|
|
@@ -820,9 +779,16 @@ export class MetadataDiscovery {
|
|
|
820
779
|
}
|
|
821
780
|
return prop.embedded ? isParentObject(meta.properties[prop.embedded[0]]) : false;
|
|
822
781
|
};
|
|
782
|
+
const isParentArray = (prop) => {
|
|
783
|
+
if (prop.array) {
|
|
784
|
+
return true;
|
|
785
|
+
}
|
|
786
|
+
return prop.embedded ? isParentArray(meta.properties[prop.embedded[0]]) : false;
|
|
787
|
+
};
|
|
823
788
|
const rootProperty = getRootProperty(embeddedProp);
|
|
824
789
|
const parentProperty = meta.properties[embeddedProp.embedded?.[0] ?? ''];
|
|
825
790
|
const object = isParentObject(embeddedProp);
|
|
791
|
+
const array = isParentArray(embeddedProp);
|
|
826
792
|
this.initFieldName(embeddedProp, rootProperty !== embeddedProp && object);
|
|
827
793
|
// the prefix of the parent cannot be a boolean; it already passed here
|
|
828
794
|
const prefix = this.getPrefix(embeddedProp, parentProperty);
|
|
@@ -835,7 +801,8 @@ export class MetadataDiscovery {
|
|
|
835
801
|
meta.propertyOrder.set(name, (order += 0.01));
|
|
836
802
|
embeddedProp.embeddedProps[prop.name] = meta.properties[name];
|
|
837
803
|
meta.properties[name].persist ??= embeddedProp.persist;
|
|
838
|
-
|
|
804
|
+
const refInArray = array && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && prop.owner;
|
|
805
|
+
if (embeddedProp.nullable || refInArray) {
|
|
839
806
|
meta.properties[name].nullable = true;
|
|
840
807
|
}
|
|
841
808
|
if (meta.properties[name].fieldNames) {
|
|
@@ -873,6 +840,7 @@ export class MetadataDiscovery {
|
|
|
873
840
|
meta.properties[name].persist = false; // only virtual as we store the whole object
|
|
874
841
|
meta.properties[name].userDefined = false; // mark this as a generated/internal property, so we can distinguish from user-defined non-persist properties
|
|
875
842
|
meta.properties[name].object = true;
|
|
843
|
+
this.initCustomType(meta, meta.properties[name], false, true);
|
|
876
844
|
}
|
|
877
845
|
this.initEmbeddables(meta, meta.properties[name], visited);
|
|
878
846
|
}
|
|
@@ -941,7 +909,7 @@ export class MetadataDiscovery {
|
|
|
941
909
|
newProp.items = Utils.unique([...meta.root.properties[prop.name].items, ...prop.items]);
|
|
942
910
|
}
|
|
943
911
|
newProp.nullable = true;
|
|
944
|
-
newProp.inherited =
|
|
912
|
+
newProp.inherited = !meta.root.properties[prop.name];
|
|
945
913
|
meta.root.addProperty(newProp);
|
|
946
914
|
});
|
|
947
915
|
meta.collection = meta.root.collection;
|
|
@@ -966,7 +934,7 @@ export class MetadataDiscovery {
|
|
|
966
934
|
}
|
|
967
935
|
}
|
|
968
936
|
initCheckConstraints(meta) {
|
|
969
|
-
const map =
|
|
937
|
+
const map = meta.createColumnMappingObject();
|
|
970
938
|
for (const check of meta.checks) {
|
|
971
939
|
const columns = check.property ? meta.properties[check.property].fieldNames : [];
|
|
972
940
|
check.name ??= this.namingStrategy.indexName(meta.tableName, columns, 'check');
|
|
@@ -976,7 +944,7 @@ export class MetadataDiscovery {
|
|
|
976
944
|
}
|
|
977
945
|
if (this.platform.usesEnumCheckConstraints() && !meta.embeddable) {
|
|
978
946
|
for (const prop of meta.props) {
|
|
979
|
-
if (prop.enum && !prop.nativeEnumName && prop.items?.every(item =>
|
|
947
|
+
if (prop.enum && !prop.nativeEnumName && prop.items?.every(item => typeof item === 'string')) {
|
|
980
948
|
this.initFieldName(prop);
|
|
981
949
|
meta.checks.push({
|
|
982
950
|
name: this.namingStrategy.indexName(meta.tableName, prop.fieldNames, 'check'),
|
|
@@ -1001,35 +969,28 @@ export class MetadataDiscovery {
|
|
|
1001
969
|
}
|
|
1002
970
|
return;
|
|
1003
971
|
}
|
|
1004
|
-
const map =
|
|
972
|
+
const map = meta.createColumnMappingObject();
|
|
1005
973
|
if (prop.generated instanceof Function) {
|
|
1006
974
|
prop.generated = prop.generated(map);
|
|
1007
975
|
}
|
|
1008
976
|
}
|
|
1009
|
-
|
|
1010
|
-
return Object.values(meta.properties).reduce((o, prop) => {
|
|
1011
|
-
if (prop.fieldNames) {
|
|
1012
|
-
o[prop.name] = prop.fieldNames[0];
|
|
1013
|
-
}
|
|
1014
|
-
return o;
|
|
1015
|
-
}, {});
|
|
1016
|
-
}
|
|
1017
|
-
getDefaultVersionValue(prop) {
|
|
977
|
+
getDefaultVersionValue(meta, prop) {
|
|
1018
978
|
if (typeof prop.defaultRaw !== 'undefined') {
|
|
1019
979
|
return prop.defaultRaw;
|
|
1020
980
|
}
|
|
1021
|
-
/* v8 ignore next
|
|
981
|
+
/* v8 ignore next */
|
|
1022
982
|
if (prop.default != null) {
|
|
1023
983
|
return '' + this.platform.quoteVersionValue(prop.default, prop);
|
|
1024
984
|
}
|
|
1025
|
-
|
|
985
|
+
this.initCustomType(meta, prop, true);
|
|
986
|
+
const type = prop.customType?.runtimeType ?? prop.runtimeType ?? prop.type;
|
|
987
|
+
if (type === 'Date') {
|
|
1026
988
|
prop.length ??= this.platform.getDefaultVersionLength();
|
|
1027
989
|
return this.platform.getCurrentTimestampSQL(prop.length);
|
|
1028
990
|
}
|
|
1029
991
|
return '1';
|
|
1030
992
|
}
|
|
1031
993
|
inferDefaultValue(meta, prop) {
|
|
1032
|
-
/* v8 ignore next 3 */
|
|
1033
994
|
if (!meta.class) {
|
|
1034
995
|
return;
|
|
1035
996
|
}
|
|
@@ -1065,7 +1026,7 @@ export class MetadataDiscovery {
|
|
|
1065
1026
|
prop.defaultRaw = this.platform.formatQuery(raw.sql, raw.params);
|
|
1066
1027
|
return;
|
|
1067
1028
|
}
|
|
1068
|
-
if (
|
|
1029
|
+
if (Array.isArray(prop.default) && prop.customType) {
|
|
1069
1030
|
val = prop.customType.convertToDatabaseValue(prop.default, this.platform);
|
|
1070
1031
|
}
|
|
1071
1032
|
prop.defaultRaw = typeof val === 'string' ? `'${val}'` : '' + val;
|
|
@@ -1093,13 +1054,13 @@ export class MetadataDiscovery {
|
|
|
1093
1054
|
if (prop.version) {
|
|
1094
1055
|
this.initDefaultValue(prop);
|
|
1095
1056
|
meta.versionProperty = prop.name;
|
|
1096
|
-
prop.defaultRaw = this.getDefaultVersionValue(prop);
|
|
1057
|
+
prop.defaultRaw = this.getDefaultVersionValue(meta, prop);
|
|
1097
1058
|
}
|
|
1098
1059
|
if (prop.concurrencyCheck && !prop.primary) {
|
|
1099
1060
|
meta.concurrencyCheckKeys.add(prop.name);
|
|
1100
1061
|
}
|
|
1101
1062
|
}
|
|
1102
|
-
initCustomType(meta, prop) {
|
|
1063
|
+
initCustomType(meta, prop, simple = false, objectEmbeddable = false) {
|
|
1103
1064
|
// `prop.type` might be actually instance of custom type class
|
|
1104
1065
|
if (Type.isMappedType(prop.type) && !prop.customType) {
|
|
1105
1066
|
prop.customType = prop.type;
|
|
@@ -1107,47 +1068,70 @@ export class MetadataDiscovery {
|
|
|
1107
1068
|
}
|
|
1108
1069
|
// `prop.type` might also be custom type class (not instance), so `typeof MyType` will give us `function`, not `object`
|
|
1109
1070
|
if (typeof prop.type === 'function' && Type.isMappedType(prop.type.prototype) && !prop.customType) {
|
|
1110
|
-
|
|
1111
|
-
|
|
1071
|
+
// if the type is an ORM defined mapped type without `ensureComparable: true`,
|
|
1072
|
+
// we use just the type name, to have more performant hydration code
|
|
1073
|
+
const type = Utils.keys(t).find(type => {
|
|
1074
|
+
return !Type.getType(t[type]).ensureComparable(meta, prop) && prop.type === t[type];
|
|
1075
|
+
});
|
|
1076
|
+
if (type) {
|
|
1077
|
+
prop.type = type === 'datetime' ? 'Date' : type;
|
|
1078
|
+
}
|
|
1079
|
+
else {
|
|
1080
|
+
prop.customType = new prop.type();
|
|
1081
|
+
prop.type = prop.customType.constructor.name;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
if (simple) {
|
|
1085
|
+
return;
|
|
1112
1086
|
}
|
|
1113
1087
|
if (!prop.customType && ['json', 'jsonb'].includes(prop.type?.toLowerCase())) {
|
|
1114
|
-
prop.customType = new
|
|
1088
|
+
prop.customType = new t.json();
|
|
1115
1089
|
}
|
|
1116
1090
|
if (prop.kind === ReferenceKind.SCALAR && !prop.customType && prop.columnTypes && ['json', 'jsonb'].includes(prop.columnTypes[0])) {
|
|
1117
|
-
prop.customType = new
|
|
1091
|
+
prop.customType = new t.json();
|
|
1092
|
+
}
|
|
1093
|
+
if (prop.kind === ReferenceKind.EMBEDDED && !prop.customType && (prop.object || prop.array)) {
|
|
1094
|
+
prop.customType = new t.json();
|
|
1118
1095
|
}
|
|
1119
1096
|
if (!prop.customType && prop.array && prop.items) {
|
|
1120
|
-
prop.customType = new
|
|
1097
|
+
prop.customType = new t.enumArray(`${meta.className}.${prop.name}`, prop.items);
|
|
1098
|
+
}
|
|
1099
|
+
const isArray = prop.type?.toLowerCase() === 'array' || prop.type?.toString().endsWith('[]');
|
|
1100
|
+
if (objectEmbeddable && !prop.customType && isArray) {
|
|
1101
|
+
prop.customType = new t.json();
|
|
1121
1102
|
}
|
|
1122
1103
|
// for number arrays we make sure to convert the items to numbers
|
|
1123
1104
|
if (!prop.customType && prop.type === 'number[]') {
|
|
1124
|
-
prop.customType = new
|
|
1105
|
+
prop.customType = new t.array(i => +i);
|
|
1125
1106
|
}
|
|
1126
1107
|
// `string[]` can be returned via ts-morph, while reflect metadata will give us just `array`
|
|
1127
|
-
if (!prop.customType &&
|
|
1128
|
-
prop.customType = new
|
|
1108
|
+
if (!prop.customType && isArray) {
|
|
1109
|
+
prop.customType = new t.array();
|
|
1129
1110
|
}
|
|
1130
1111
|
if (!prop.customType && prop.type?.toLowerCase() === 'buffer') {
|
|
1131
|
-
prop.customType = new
|
|
1112
|
+
prop.customType = new t.blob();
|
|
1132
1113
|
}
|
|
1133
1114
|
if (!prop.customType && prop.type?.toLowerCase() === 'uint8array') {
|
|
1134
|
-
prop.customType = new
|
|
1115
|
+
prop.customType = new t.uint8array();
|
|
1135
1116
|
}
|
|
1136
1117
|
const mappedType = this.getMappedType(prop);
|
|
1137
1118
|
if (prop.fieldNames?.length === 1 && !prop.customType) {
|
|
1138
|
-
[
|
|
1119
|
+
[t.bigint, t.double, t.decimal, t.interval, t.date]
|
|
1139
1120
|
.filter(type => mappedType instanceof type)
|
|
1140
|
-
.forEach(type => prop.customType = new type());
|
|
1121
|
+
.forEach((type) => prop.customType = new type());
|
|
1141
1122
|
}
|
|
1142
1123
|
if (prop.customType && !prop.columnTypes) {
|
|
1143
1124
|
const mappedType = this.getMappedType({ columnTypes: [prop.customType.getColumnType(prop, this.platform)] });
|
|
1144
|
-
if (prop.customType.compareAsType() === 'any' && ![
|
|
1125
|
+
if (prop.customType.compareAsType() === 'any' && ![t.json].some(t => prop.customType instanceof t)) {
|
|
1145
1126
|
prop.runtimeType ??= mappedType.runtimeType;
|
|
1146
1127
|
}
|
|
1147
1128
|
else {
|
|
1148
1129
|
prop.runtimeType ??= prop.customType.runtimeType;
|
|
1149
1130
|
}
|
|
1150
1131
|
}
|
|
1132
|
+
else if (prop.runtimeType === 'object') {
|
|
1133
|
+
prop.runtimeType = mappedType.runtimeType;
|
|
1134
|
+
}
|
|
1151
1135
|
else {
|
|
1152
1136
|
prop.runtimeType ??= mappedType.runtimeType;
|
|
1153
1137
|
}
|
|
@@ -1158,11 +1142,11 @@ export class MetadataDiscovery {
|
|
|
1158
1142
|
prop.columnTypes ??= [prop.customType.getColumnType(prop, this.platform)];
|
|
1159
1143
|
prop.hasConvertToJSValueSQL = !!prop.customType.convertToJSValueSQL && prop.customType.convertToJSValueSQL('', this.platform) !== '';
|
|
1160
1144
|
prop.hasConvertToDatabaseValueSQL = !!prop.customType.convertToDatabaseValueSQL && prop.customType.convertToDatabaseValueSQL('', this.platform) !== '';
|
|
1161
|
-
if (prop.customType instanceof
|
|
1145
|
+
if (prop.customType instanceof t.bigint && ['string', 'bigint', 'number'].includes(prop.runtimeType.toLowerCase())) {
|
|
1162
1146
|
prop.customType.mode = prop.runtimeType.toLowerCase();
|
|
1163
1147
|
}
|
|
1164
1148
|
}
|
|
1165
|
-
if (Type.isMappedType(prop.customType) && prop.kind === ReferenceKind.SCALAR && !
|
|
1149
|
+
if (Type.isMappedType(prop.customType) && prop.kind === ReferenceKind.SCALAR && !isArray) {
|
|
1166
1150
|
prop.type = prop.customType.name;
|
|
1167
1151
|
}
|
|
1168
1152
|
if (!prop.customType && [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind) && this.metadata.get(prop.type).compositePK) {
|
|
@@ -1179,7 +1163,7 @@ export class MetadataDiscovery {
|
|
|
1179
1163
|
}
|
|
1180
1164
|
}
|
|
1181
1165
|
}
|
|
1182
|
-
if (prop.kind === ReferenceKind.SCALAR && !(mappedType instanceof
|
|
1166
|
+
if (prop.kind === ReferenceKind.SCALAR && !(mappedType instanceof t.unknown)) {
|
|
1183
1167
|
if (!prop.columnTypes && prop.nativeEnumName && meta.schema !== this.platform.getDefaultSchemaName() && meta.schema && !prop.nativeEnumName.includes('.')) {
|
|
1184
1168
|
prop.columnTypes = [`${meta.schema}.${prop.nativeEnumName}`];
|
|
1185
1169
|
}
|
|
@@ -1222,7 +1206,7 @@ export class MetadataDiscovery {
|
|
|
1222
1206
|
if (prop.kind === ReferenceKind.SCALAR) {
|
|
1223
1207
|
const mappedType = this.getMappedType(prop);
|
|
1224
1208
|
const SCALAR_TYPES = ['string', 'number', 'boolean', 'bigint', 'Date', 'Buffer', 'RegExp', 'any', 'unknown'];
|
|
1225
|
-
if (mappedType instanceof
|
|
1209
|
+
if (mappedType instanceof t.unknown
|
|
1226
1210
|
&& !prop.columnTypes
|
|
1227
1211
|
// it could be a runtime type from reflect-metadata
|
|
1228
1212
|
&& !SCALAR_TYPES.includes(prop.type)
|
|
@@ -1266,7 +1250,7 @@ export class MetadataDiscovery {
|
|
|
1266
1250
|
t = 'enum';
|
|
1267
1251
|
}
|
|
1268
1252
|
else if (prop.enum) {
|
|
1269
|
-
t = prop.items?.every(item =>
|
|
1253
|
+
t = prop.items?.every(item => typeof item === 'string') ? 'enum' : 'tinyint';
|
|
1270
1254
|
}
|
|
1271
1255
|
if (t === 'Date') {
|
|
1272
1256
|
t = 'datetime';
|
|
@@ -1305,30 +1289,6 @@ export class MetadataDiscovery {
|
|
|
1305
1289
|
prop.index ??= true;
|
|
1306
1290
|
}
|
|
1307
1291
|
}
|
|
1308
|
-
async getEntityClassOrSchema(path, name) {
|
|
1309
|
-
const exports = await Utils.dynamicImport(path);
|
|
1310
|
-
const targets = Object.values(exports)
|
|
1311
|
-
.filter(item => item instanceof EntitySchema || (item instanceof Function && MetadataStorage.isKnownEntity(item.name)));
|
|
1312
|
-
// ignore class implementations that are linked from an EntitySchema
|
|
1313
|
-
for (const item of targets) {
|
|
1314
|
-
if (item instanceof EntitySchema) {
|
|
1315
|
-
targets.forEach((item2, idx) => {
|
|
1316
|
-
if (item.meta.class === item2) {
|
|
1317
|
-
targets.splice(idx, 1);
|
|
1318
|
-
}
|
|
1319
|
-
});
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
if (targets.length > 0) {
|
|
1323
|
-
return targets;
|
|
1324
|
-
}
|
|
1325
|
-
const target = exports.default ?? exports[name];
|
|
1326
|
-
/* v8 ignore next 3 */
|
|
1327
|
-
if (!target) {
|
|
1328
|
-
throw MetadataError.entityNotFound(name, path.replace(this.config.get('baseDir'), '.'));
|
|
1329
|
-
}
|
|
1330
|
-
return [target];
|
|
1331
|
-
}
|
|
1332
1292
|
shouldForceConstructorUsage(meta) {
|
|
1333
1293
|
const forceConstructor = this.config.get('forceEntityConstructor');
|
|
1334
1294
|
if (Array.isArray(forceConstructor)) {
|