@mikro-orm/core 7.0.0-dev.8 → 7.0.0-dev.80
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 +85 -48
- package/EntityManager.js +300 -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 +17 -8
- package/drivers/IDatabaseDriver.d.ts +27 -5
- package/entity/BaseEntity.d.ts +0 -1
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +98 -30
- package/entity/Collection.js +432 -93
- package/entity/EntityAssigner.d.ts +1 -1
- package/entity/EntityAssigner.js +15 -7
- package/entity/EntityFactory.d.ts +7 -0
- package/entity/EntityFactory.js +64 -41
- package/entity/EntityHelper.js +26 -9
- package/entity/EntityLoader.d.ts +5 -4
- package/entity/EntityLoader.js +73 -40
- package/entity/EntityRepository.d.ts +1 -1
- package/entity/Reference.d.ts +9 -7
- package/entity/Reference.js +33 -6
- package/entity/WrappedEntity.d.ts +2 -4
- package/entity/WrappedEntity.js +1 -5
- package/entity/defineEntity.d.ts +549 -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 +6 -2
- package/errors.js +14 -9
- package/events/EventSubscriber.d.ts +3 -1
- package/hydration/Hydrator.js +1 -2
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +36 -25
- package/index.d.ts +2 -2
- package/index.js +1 -2
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/SimpleLogger.d.ts +1 -1
- package/metadata/EntitySchema.d.ts +9 -13
- package/metadata/EntitySchema.js +44 -26
- package/metadata/MetadataDiscovery.d.ts +6 -9
- package/metadata/MetadataDiscovery.js +167 -206
- 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 +4 -13
- 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 -10
- package/platforms/Platform.js +14 -39
- 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/JsonType.d.ts +1 -1
- package/types/JsonType.js +7 -2
- package/types/TinyIntType.js +1 -1
- package/types/Type.d.ts +2 -1
- package/types/Type.js +1 -1
- package/types/Uint8ArrayType.d.ts +0 -1
- package/types/Uint8ArrayType.js +1 -4
- package/types/index.d.ts +1 -1
- package/typings.d.ts +113 -77
- package/typings.js +41 -35
- 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 +58 -20
- package/unit-of-work/UnitOfWork.d.ts +8 -1
- package/unit-of-work/UnitOfWork.js +115 -57
- package/utils/AbstractSchemaGenerator.d.ts +5 -5
- package/utils/AbstractSchemaGenerator.js +11 -9
- package/utils/Configuration.d.ts +757 -206
- package/utils/Configuration.js +139 -187
- package/utils/ConfigurationLoader.d.ts +1 -54
- package/utils/ConfigurationLoader.js +1 -352
- package/utils/Cursor.d.ts +3 -3
- package/utils/Cursor.js +4 -1
- package/utils/DataloaderUtils.d.ts +15 -5
- package/utils/DataloaderUtils.js +54 -8
- package/utils/EntityComparator.d.ts +8 -4
- package/utils/EntityComparator.js +111 -64
- package/utils/QueryHelper.d.ts +9 -1
- package/utils/QueryHelper.js +70 -9
- package/utils/RawQueryFragment.d.ts +36 -4
- package/utils/RawQueryFragment.js +35 -14
- package/utils/TransactionManager.d.ts +65 -0
- package/utils/TransactionManager.js +223 -0
- package/utils/Utils.d.ts +8 -97
- package/utils/Utils.js +88 -303
- 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 +96 -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
package/platforms/Platform.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { inspect } from 'node:util';
|
|
2
2
|
import { EntityRepository } from '../entity/EntityRepository.js';
|
|
3
3
|
import { type NamingStrategy } from '../naming-strategy/NamingStrategy.js';
|
|
4
|
-
import type { Constructor, EntityProperty, IPrimaryKey, ISchemaGenerator, PopulateOptions, Primary,
|
|
4
|
+
import type { Constructor, EntityMetadata, EntityProperty, IPrimaryKey, ISchemaGenerator, PopulateOptions, Primary, SimpleColumnMeta } from '../typings.js';
|
|
5
5
|
import { ExceptionConverter } from './ExceptionConverter.js';
|
|
6
6
|
import type { EntityManager } from '../EntityManager.js';
|
|
7
7
|
import type { Configuration } from '../utils/Configuration.js';
|
|
@@ -30,7 +30,6 @@ export declare abstract class Platform {
|
|
|
30
30
|
usesEnumCheckConstraints(): boolean;
|
|
31
31
|
getSchemaHelper(): unknown;
|
|
32
32
|
indexForeignKeys(): boolean;
|
|
33
|
-
allowsMultiInsert(): boolean;
|
|
34
33
|
/**
|
|
35
34
|
* Whether or not the driver supports retuning list of created PKs back when multi-inserting
|
|
36
35
|
*/
|
|
@@ -48,11 +47,6 @@ export declare abstract class Platform {
|
|
|
48
47
|
* Converts scalar primary key representation to native driver wrapper (e.g. string to mongodb's ObjectId)
|
|
49
48
|
*/
|
|
50
49
|
denormalizePrimaryKey(data: IPrimaryKey): IPrimaryKey;
|
|
51
|
-
/**
|
|
52
|
-
* Used when serializing via toObject and toJSON methods, allows to use different PK field name (like `id` instead of `_id`)
|
|
53
|
-
*/
|
|
54
|
-
getSerializedPrimaryKeyField(field: string): string;
|
|
55
|
-
usesDifferentSerializedPrimaryKey(): boolean;
|
|
56
50
|
/**
|
|
57
51
|
* Returns the SQL specific for the platform to get the current timestamp
|
|
58
52
|
*/
|
|
@@ -158,7 +152,7 @@ export declare abstract class Platform {
|
|
|
158
152
|
getFullTextIndexExpression(indexName: string, schemaName: string | undefined, tableName: string, columns: SimpleColumnMeta[]): string;
|
|
159
153
|
convertsJsonAutomatically(): boolean;
|
|
160
154
|
convertJsonToDatabaseValue(value: unknown, context?: TransformContext): unknown;
|
|
161
|
-
convertJsonToJSValue(value: unknown,
|
|
155
|
+
convertJsonToJSValue(value: unknown, context?: TransformContext): unknown;
|
|
162
156
|
convertDateToJSValue(value: string | Date): string;
|
|
163
157
|
convertIntervalToJSValue(value: string): unknown;
|
|
164
158
|
convertIntervalToDatabaseValue(value: unknown): unknown;
|
|
@@ -175,7 +169,9 @@ export declare abstract class Platform {
|
|
|
175
169
|
getExtension<T>(extensionName: string, extensionKey: string, moduleName: string, em: EntityManager): T;
|
|
176
170
|
getSchemaGenerator(driver: IDatabaseDriver, em?: EntityManager): ISchemaGenerator;
|
|
177
171
|
processDateProperty(value: unknown): string | number | Date;
|
|
178
|
-
quoteIdentifier(id: string
|
|
172
|
+
quoteIdentifier(id: string | {
|
|
173
|
+
toString: () => string;
|
|
174
|
+
}, quote?: string): string;
|
|
179
175
|
quoteValue(value: any): string;
|
|
180
176
|
escape(value: any): string;
|
|
181
177
|
formatQuery(sql: string, params: readonly any[]): string;
|
|
@@ -193,7 +189,7 @@ export declare abstract class Platform {
|
|
|
193
189
|
getDefaultPrimaryName(tableName: string, columns: string[]): string;
|
|
194
190
|
supportsCustomPrimaryKeyNames(): boolean;
|
|
195
191
|
isPopulated<T>(key: string, populate: readonly PopulateOptions<T>[] | boolean): boolean;
|
|
196
|
-
shouldHaveColumn<T>(prop: EntityProperty<T>, populate: readonly PopulateOptions<T>[] | boolean, exclude?: string[], includeFormulas?: boolean): boolean;
|
|
192
|
+
shouldHaveColumn<T>(prop: EntityProperty<T>, populate: readonly PopulateOptions<T>[] | boolean, exclude?: string[], includeFormulas?: boolean, ignoreInlineEmbeddables?: boolean): boolean;
|
|
197
193
|
/**
|
|
198
194
|
* Currently not supported due to how knex does complex sqlite diffing (always based on current schema)
|
|
199
195
|
*/
|
package/platforms/Platform.js
CHANGED
|
@@ -3,8 +3,8 @@ import { clone } from '../utils/clone.js';
|
|
|
3
3
|
import { EntityRepository } from '../entity/EntityRepository.js';
|
|
4
4
|
import { UnderscoreNamingStrategy } from '../naming-strategy/UnderscoreNamingStrategy.js';
|
|
5
5
|
import { ExceptionConverter } from './ExceptionConverter.js';
|
|
6
|
-
import { ArrayType, BigIntType, BlobType,
|
|
7
|
-
import { parseJsonSafe
|
|
6
|
+
import { ArrayType, BigIntType, BlobType, BooleanType, CharacterType, DateTimeType, DateType, DecimalType, DoubleType, EnumType, FloatType, IntegerType, IntervalType, JsonType, MediumIntType, SmallIntType, StringType, TextType, TimeType, TinyIntType, Type, Uint8ArrayType, UnknownType, UuidType, } from '../types/index.js';
|
|
7
|
+
import { parseJsonSafe } from '../utils/Utils.js';
|
|
8
8
|
import { ReferenceKind } from '../enums.js';
|
|
9
9
|
import { RawQueryFragment } from '../utils/RawQueryFragment.js';
|
|
10
10
|
export const JsonProperty = Symbol('JsonProperty');
|
|
@@ -48,9 +48,6 @@ export class Platform {
|
|
|
48
48
|
indexForeignKeys() {
|
|
49
49
|
return false;
|
|
50
50
|
}
|
|
51
|
-
allowsMultiInsert() {
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
51
|
/**
|
|
55
52
|
* Whether or not the driver supports retuning list of created PKs back when multi-inserting
|
|
56
53
|
*/
|
|
@@ -78,15 +75,6 @@ export class Platform {
|
|
|
78
75
|
denormalizePrimaryKey(data) {
|
|
79
76
|
return data;
|
|
80
77
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Used when serializing via toObject and toJSON methods, allows to use different PK field name (like `id` instead of `_id`)
|
|
83
|
-
*/
|
|
84
|
-
getSerializedPrimaryKeyField(field) {
|
|
85
|
-
return field;
|
|
86
|
-
}
|
|
87
|
-
usesDifferentSerializedPrimaryKey() {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
78
|
/**
|
|
91
79
|
* Returns the SQL specific for the platform to get the current timestamp
|
|
92
80
|
*/
|
|
@@ -133,7 +121,7 @@ export class Platform {
|
|
|
133
121
|
return true;
|
|
134
122
|
}
|
|
135
123
|
isBigIntProperty(prop) {
|
|
136
|
-
return prop.columnTypes
|
|
124
|
+
return prop.columnTypes?.[0] === 'bigint';
|
|
137
125
|
}
|
|
138
126
|
getDefaultSchemaName() {
|
|
139
127
|
return undefined;
|
|
@@ -169,7 +157,7 @@ export class Platform {
|
|
|
169
157
|
return `text`;
|
|
170
158
|
}
|
|
171
159
|
getEnumTypeDeclarationSQL(column) {
|
|
172
|
-
if (column.items?.every(item =>
|
|
160
|
+
if (column.items?.every(item => typeof item === 'string')) {
|
|
173
161
|
return `enum('${column.items.join("','")}')`;
|
|
174
162
|
}
|
|
175
163
|
return this.getTinyIntTypeDeclarationSQL(column);
|
|
@@ -269,7 +257,7 @@ export class Platform {
|
|
|
269
257
|
getSearchJsonPropertyKey(path, type, aliased, value) {
|
|
270
258
|
return path.join('.');
|
|
271
259
|
}
|
|
272
|
-
/* v8 ignore next
|
|
260
|
+
/* v8 ignore next */
|
|
273
261
|
getJsonIndexDefinition(index) {
|
|
274
262
|
return index.columnNames;
|
|
275
263
|
}
|
|
@@ -288,11 +276,7 @@ export class Platform {
|
|
|
288
276
|
convertJsonToDatabaseValue(value, context) {
|
|
289
277
|
return JSON.stringify(value);
|
|
290
278
|
}
|
|
291
|
-
convertJsonToJSValue(value,
|
|
292
|
-
const isObjectEmbedded = prop.embedded && prop.object;
|
|
293
|
-
if ((this.convertsJsonAutomatically() || isObjectEmbedded) && ['json', 'jsonb', this.getJsonDeclarationSQL()].includes(prop.columnTypes[0])) {
|
|
294
|
-
return value;
|
|
295
|
-
}
|
|
279
|
+
convertJsonToJSValue(value, context) {
|
|
296
280
|
return parseJsonSafe(value);
|
|
297
281
|
}
|
|
298
282
|
convertDateToJSValue(value) {
|
|
@@ -306,7 +290,7 @@ export class Platform {
|
|
|
306
290
|
}
|
|
307
291
|
parseDate(value) {
|
|
308
292
|
const date = new Date(value);
|
|
309
|
-
/* v8 ignore next
|
|
293
|
+
/* v8 ignore next */
|
|
310
294
|
if (isNaN(date.getTime())) {
|
|
311
295
|
return value;
|
|
312
296
|
}
|
|
@@ -336,19 +320,10 @@ export class Platform {
|
|
|
336
320
|
if (extension) {
|
|
337
321
|
return extension;
|
|
338
322
|
}
|
|
339
|
-
/* v8 ignore next
|
|
340
|
-
|
|
341
|
-
module: moduleName,
|
|
342
|
-
warning: `Please install ${moduleName} package.`,
|
|
343
|
-
});
|
|
344
|
-
/* v8 ignore next 3 */
|
|
345
|
-
if (module) {
|
|
346
|
-
return this.config.getCachedService(module[extensionName], em);
|
|
347
|
-
}
|
|
348
|
-
/* v8 ignore next 2 */
|
|
349
|
-
throw new Error(`${extensionName} extension not registered.`);
|
|
323
|
+
/* v8 ignore next */
|
|
324
|
+
throw new Error(`${extensionName} extension not registered. Provide it in the ORM config, or use the async \`MikroORM.init()\` method to load extensions automatically.`);
|
|
350
325
|
}
|
|
351
|
-
/* v8 ignore next
|
|
326
|
+
/* v8 ignore next: kept for type inference only */
|
|
352
327
|
getSchemaGenerator(driver, em) {
|
|
353
328
|
throw new Error(`${driver.constructor.name} does not support SchemaGenerator`);
|
|
354
329
|
}
|
|
@@ -365,7 +340,7 @@ export class Platform {
|
|
|
365
340
|
quoteValue(value) {
|
|
366
341
|
return value;
|
|
367
342
|
}
|
|
368
|
-
/* v8 ignore next
|
|
343
|
+
/* v8 ignore next */
|
|
369
344
|
escape(value) {
|
|
370
345
|
return value;
|
|
371
346
|
}
|
|
@@ -455,7 +430,7 @@ export class Platform {
|
|
|
455
430
|
isPopulated(key, populate) {
|
|
456
431
|
return populate === true || (populate !== false && populate.some(p => p.field === key || p.all));
|
|
457
432
|
}
|
|
458
|
-
shouldHaveColumn(prop, populate, exclude, includeFormulas = true) {
|
|
433
|
+
shouldHaveColumn(prop, populate, exclude, includeFormulas = true, ignoreInlineEmbeddables = true) {
|
|
459
434
|
if (exclude?.includes(prop.name)) {
|
|
460
435
|
return false;
|
|
461
436
|
}
|
|
@@ -475,7 +450,7 @@ export class Platform {
|
|
|
475
450
|
return true;
|
|
476
451
|
}
|
|
477
452
|
if (prop.kind === ReferenceKind.EMBEDDED) {
|
|
478
|
-
return
|
|
453
|
+
return prop.object || ignoreInlineEmbeddables;
|
|
479
454
|
}
|
|
480
455
|
return prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner;
|
|
481
456
|
}
|
|
@@ -522,8 +497,8 @@ export class Platform {
|
|
|
522
497
|
clone() {
|
|
523
498
|
return this;
|
|
524
499
|
}
|
|
525
|
-
/* v8 ignore next 4 */
|
|
526
500
|
/** @ignore */
|
|
501
|
+
/* v8 ignore next */
|
|
527
502
|
[inspect.custom]() {
|
|
528
503
|
return `[${this.constructor.name}]`;
|
|
529
504
|
}
|
|
@@ -17,6 +17,8 @@ export interface SerializeOptions<T, P extends string = never, E extends string
|
|
|
17
17
|
forceObject?: boolean;
|
|
18
18
|
/** Ignore custom property serializers. */
|
|
19
19
|
ignoreSerializers?: boolean;
|
|
20
|
+
/** Include properties marked as `hidden`. */
|
|
21
|
+
includeHidden?: boolean;
|
|
20
22
|
/** Skip properties with `null` value. */
|
|
21
23
|
skipNull?: boolean;
|
|
22
24
|
/** Only include properties for a specific group. If a property does not specify any group, it will be included, otherwise only properties with a matching group are included. */
|
|
@@ -15,8 +15,8 @@ function isVisible(meta, propName, options) {
|
|
|
15
15
|
if (options.exclude?.find(item => item === propName)) {
|
|
16
16
|
return false;
|
|
17
17
|
}
|
|
18
|
-
const visible = prop && !prop.hidden;
|
|
19
|
-
const prefixed = prop && !prop.primary && propName.startsWith('_'); // ignore prefixed properties, if it's not a PK
|
|
18
|
+
const visible = prop && !(prop.hidden && !options.includeHidden);
|
|
19
|
+
const prefixed = prop && !prop.primary && !prop.accessor && propName.startsWith('_'); // ignore prefixed properties, if it's not a PK
|
|
20
20
|
return visible && !prefixed;
|
|
21
21
|
}
|
|
22
22
|
function isPopulated(propName, options) {
|
|
@@ -41,13 +41,31 @@ export class EntitySerializer {
|
|
|
41
41
|
}
|
|
42
42
|
const root = wrapped.__serializationContext.root;
|
|
43
43
|
const ret = {};
|
|
44
|
-
const
|
|
45
|
-
|
|
44
|
+
const props = new Set();
|
|
45
|
+
if (meta.serializedPrimaryKey && !meta.compositePK) {
|
|
46
|
+
props.add(meta.serializedPrimaryKey);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
meta.primaryKeys.forEach(pk => props.add(pk));
|
|
50
|
+
}
|
|
51
|
+
if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
|
|
52
|
+
const entityKeys = new Set(Object.keys(entity));
|
|
53
|
+
for (const prop of meta.props) {
|
|
54
|
+
if (entityKeys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
|
|
55
|
+
props.add(prop.name);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const key of entityKeys) {
|
|
59
|
+
if (!meta.properties[key]) {
|
|
60
|
+
props.add(key);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
46
64
|
const visited = root.visited.has(entity);
|
|
47
65
|
if (!visited) {
|
|
48
66
|
root.visited.add(entity);
|
|
49
67
|
}
|
|
50
|
-
for (const prop of
|
|
68
|
+
for (const prop of props) {
|
|
51
69
|
if (!isVisible(meta, prop, options)) {
|
|
52
70
|
continue;
|
|
53
71
|
}
|
|
@@ -67,7 +85,7 @@ export class EntitySerializer {
|
|
|
67
85
|
}
|
|
68
86
|
const visible = typeof val !== 'undefined' && !(val === null && options.skipNull);
|
|
69
87
|
if (visible) {
|
|
70
|
-
ret[this.propertyName(meta, prop
|
|
88
|
+
ret[this.propertyName(meta, prop)] = val;
|
|
71
89
|
}
|
|
72
90
|
}
|
|
73
91
|
if (contextCreated) {
|
|
@@ -81,26 +99,26 @@ export class EntitySerializer {
|
|
|
81
99
|
if (prop.getterName != null) {
|
|
82
100
|
const visible = entity[prop.getterName] instanceof Function && isVisible(meta, prop.name, options);
|
|
83
101
|
if (visible) {
|
|
84
|
-
ret[this.propertyName(meta, prop.name
|
|
102
|
+
ret[this.propertyName(meta, prop.name)] = this.processProperty(prop.getterName, entity, options);
|
|
85
103
|
}
|
|
86
104
|
}
|
|
87
105
|
else {
|
|
88
106
|
// decorated getters
|
|
89
107
|
const visible = typeof entity[prop.name] !== 'undefined' && isVisible(meta, prop.name, options);
|
|
90
108
|
if (visible) {
|
|
91
|
-
ret[this.propertyName(meta, prop.name
|
|
109
|
+
ret[this.propertyName(meta, prop.name)] = this.processProperty(prop.name, entity, options);
|
|
92
110
|
}
|
|
93
111
|
}
|
|
94
112
|
}
|
|
95
113
|
return ret;
|
|
96
114
|
}
|
|
97
|
-
static propertyName(meta, prop
|
|
98
|
-
/* v8 ignore next
|
|
115
|
+
static propertyName(meta, prop) {
|
|
116
|
+
/* v8 ignore next */
|
|
99
117
|
if (meta.properties[prop]?.serializedName) {
|
|
100
118
|
return meta.properties[prop].serializedName;
|
|
101
119
|
}
|
|
102
|
-
if (meta.properties[prop]?.primary &&
|
|
103
|
-
return
|
|
120
|
+
if (meta.properties[prop]?.primary && meta.serializedPrimaryKey) {
|
|
121
|
+
return meta.serializedPrimaryKey;
|
|
104
122
|
}
|
|
105
123
|
return prop;
|
|
106
124
|
}
|
|
@@ -119,7 +137,7 @@ export class EntitySerializer {
|
|
|
119
137
|
}
|
|
120
138
|
return returnValue;
|
|
121
139
|
}
|
|
122
|
-
/* v8 ignore next
|
|
140
|
+
/* v8 ignore next */
|
|
123
141
|
if (!options.ignoreSerializers && serializer) {
|
|
124
142
|
return serializer(value);
|
|
125
143
|
}
|
|
@@ -132,7 +150,7 @@ export class EntitySerializer {
|
|
|
132
150
|
if (Utils.isScalarReference(value)) {
|
|
133
151
|
return value.unwrap();
|
|
134
152
|
}
|
|
135
|
-
/* v8 ignore next
|
|
153
|
+
/* v8 ignore next */
|
|
136
154
|
if (property?.kind === ReferenceKind.EMBEDDED) {
|
|
137
155
|
if (Array.isArray(value)) {
|
|
138
156
|
return value.map(item => helper(item).toJSON());
|
|
@@ -6,7 +6,7 @@ import { isRaw } from '../utils/RawQueryFragment.js';
|
|
|
6
6
|
function isVisible(meta, propName, ignoreFields = []) {
|
|
7
7
|
const prop = meta.properties[propName];
|
|
8
8
|
const visible = prop && !prop.hidden;
|
|
9
|
-
const prefixed = prop && !prop.primary && propName.startsWith('_'); // ignore prefixed properties, if it's not a PK
|
|
9
|
+
const prefixed = prop && !prop.primary && !prop.accessor && propName.startsWith('_'); // ignore prefixed properties, if it's not a PK
|
|
10
10
|
return visible && !prefixed && !ignoreFields.includes(propName);
|
|
11
11
|
}
|
|
12
12
|
export class EntityTransformer {
|
|
@@ -27,22 +27,32 @@ export class EntityTransformer {
|
|
|
27
27
|
const root = wrapped.__serializationContext.root;
|
|
28
28
|
const meta = wrapped.__meta;
|
|
29
29
|
const ret = {};
|
|
30
|
-
const
|
|
30
|
+
const props = new Set();
|
|
31
31
|
if (meta.serializedPrimaryKey && !meta.compositePK) {
|
|
32
|
-
|
|
32
|
+
props.add(meta.serializedPrimaryKey);
|
|
33
33
|
}
|
|
34
34
|
else {
|
|
35
|
-
meta.primaryKeys.forEach(pk =>
|
|
35
|
+
meta.primaryKeys.forEach(pk => props.add(pk));
|
|
36
36
|
}
|
|
37
37
|
if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
|
|
38
|
-
|
|
38
|
+
const entityKeys = new Set(Object.keys(entity));
|
|
39
|
+
for (const prop of meta.props) {
|
|
40
|
+
if (entityKeys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
|
|
41
|
+
props.add(prop.name);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const key of entityKeys) {
|
|
45
|
+
if (!meta.properties[key]) {
|
|
46
|
+
props.add(key);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
39
49
|
}
|
|
40
50
|
const visited = root.visited.has(entity);
|
|
41
51
|
const includePrimaryKeys = wrapped.__config.get('serialization').includePrimaryKeys;
|
|
42
52
|
if (!visited) {
|
|
43
53
|
root.visited.add(entity);
|
|
44
54
|
}
|
|
45
|
-
for (const prop of
|
|
55
|
+
for (const prop of props) {
|
|
46
56
|
const visible = raw ? meta.properties[prop] : isVisible(meta, prop, ignoreFields);
|
|
47
57
|
if (!visible) {
|
|
48
58
|
continue;
|
|
@@ -67,7 +77,7 @@ export class EntityTransformer {
|
|
|
67
77
|
if (typeof val === 'undefined') {
|
|
68
78
|
continue;
|
|
69
79
|
}
|
|
70
|
-
ret[this.propertyName(meta, prop,
|
|
80
|
+
ret[this.propertyName(meta, prop, raw)] = val;
|
|
71
81
|
}
|
|
72
82
|
if (!wrapped.isInitialized() && wrapped.hasPrimaryKey()) {
|
|
73
83
|
return ret;
|
|
@@ -78,7 +88,7 @@ export class EntityTransformer {
|
|
|
78
88
|
const visible = !prop.hidden && entity[prop.getterName] instanceof Function;
|
|
79
89
|
const populated = root.isMarkedAsPopulated(meta.className, prop.name);
|
|
80
90
|
if (visible) {
|
|
81
|
-
ret[this.propertyName(meta, prop.name,
|
|
91
|
+
ret[this.propertyName(meta, prop.name, raw)] = this.processProperty(prop.getterName, entity, raw, populated);
|
|
82
92
|
}
|
|
83
93
|
}
|
|
84
94
|
else {
|
|
@@ -86,7 +96,7 @@ export class EntityTransformer {
|
|
|
86
96
|
const visible = !prop.hidden && typeof entity[prop.name] !== 'undefined';
|
|
87
97
|
const populated = root.isMarkedAsPopulated(meta.className, prop.name);
|
|
88
98
|
if (visible) {
|
|
89
|
-
ret[this.propertyName(meta, prop.name,
|
|
99
|
+
ret[this.propertyName(meta, prop.name, raw)] = this.processProperty(prop.name, entity, raw, populated);
|
|
90
100
|
}
|
|
91
101
|
}
|
|
92
102
|
}
|
|
@@ -95,15 +105,15 @@ export class EntityTransformer {
|
|
|
95
105
|
}
|
|
96
106
|
return ret;
|
|
97
107
|
}
|
|
98
|
-
static propertyName(meta, prop,
|
|
108
|
+
static propertyName(meta, prop, raw) {
|
|
99
109
|
if (raw) {
|
|
100
110
|
return prop;
|
|
101
111
|
}
|
|
102
112
|
if (meta.properties[prop].serializedName) {
|
|
103
113
|
return meta.properties[prop].serializedName;
|
|
104
114
|
}
|
|
105
|
-
if (meta.properties[prop].primary &&
|
|
106
|
-
return
|
|
115
|
+
if (meta.properties[prop].primary && meta.serializedPrimaryKey) {
|
|
116
|
+
return meta.serializedPrimaryKey;
|
|
107
117
|
}
|
|
108
118
|
return prop;
|
|
109
119
|
}
|
|
@@ -36,8 +36,8 @@ export class SerializationContext {
|
|
|
36
36
|
}
|
|
37
37
|
leave(entityName, prop) {
|
|
38
38
|
const last = this.path.pop();
|
|
39
|
-
/* v8 ignore next
|
|
40
|
-
if (
|
|
39
|
+
/* v8 ignore next */
|
|
40
|
+
if (last?.[0] !== entityName || last[1] !== prop) {
|
|
41
41
|
throw new Error(`Trying to leave wrong property: ${entityName}.${prop} instead of ${last?.join('.')}`);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -73,18 +73,21 @@ export class SerializationContext {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
isMarkedAsPopulated(entityName, prop) {
|
|
76
|
-
let populate = this.populate;
|
|
76
|
+
let populate = this.populate ?? [];
|
|
77
77
|
for (const segment of this.path) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
const hints = populate.filter(p => p.field === segment[1]);
|
|
79
|
+
if (hints.length > 0) {
|
|
80
|
+
const childHints = [];
|
|
81
|
+
for (const hint of hints) {
|
|
82
|
+
// we need to check for cycles here too, as we could fall into endless loops for bidirectional relations
|
|
83
|
+
if (hint.all) {
|
|
84
|
+
return !this.path.find(([cls, item]) => entityName === cls && prop === item);
|
|
85
|
+
}
|
|
86
|
+
if (hint.children) {
|
|
87
|
+
childHints.push(...hint.children);
|
|
88
|
+
}
|
|
86
89
|
}
|
|
87
|
-
populate =
|
|
90
|
+
populate = childHints;
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
return !!populate?.some(p => p.field === prop);
|
|
@@ -95,7 +98,7 @@ export class SerializationContext {
|
|
|
95
98
|
}
|
|
96
99
|
let fields = [...this.fields];
|
|
97
100
|
for (const segment of this.path) {
|
|
98
|
-
/* v8 ignore next
|
|
101
|
+
/* v8 ignore next */
|
|
99
102
|
if (fields.length === 0) {
|
|
100
103
|
return true;
|
|
101
104
|
}
|
package/types/ArrayType.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type TransformContext, Type } from './Type.js';
|
|
2
2
|
import type { EntityProperty } from '../typings.js';
|
|
3
3
|
import type { Platform } from '../platforms/Platform.js';
|
|
4
4
|
export declare class ArrayType<T = string> extends Type<T[] | null, string | null> {
|
package/types/ArrayType.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Type } from './Type.js';
|
|
2
|
-
import { Utils } from '../utils/Utils.js';
|
|
3
2
|
import { ValidationError } from '../errors.js';
|
|
4
3
|
export class ArrayType extends Type {
|
|
5
4
|
toJsValue;
|
|
@@ -16,7 +15,7 @@ export class ArrayType extends Type {
|
|
|
16
15
|
if (Array.isArray(value)) {
|
|
17
16
|
return platform.marshallArray(value.map(i => this.toDbValue(i)));
|
|
18
17
|
}
|
|
19
|
-
/* v8 ignore next
|
|
18
|
+
/* v8 ignore next */
|
|
20
19
|
if (context?.fromQuery) {
|
|
21
20
|
return value;
|
|
22
21
|
}
|
|
@@ -26,7 +25,7 @@ export class ArrayType extends Type {
|
|
|
26
25
|
if (value == null) {
|
|
27
26
|
return value;
|
|
28
27
|
}
|
|
29
|
-
if (
|
|
28
|
+
if (typeof value === 'string') {
|
|
30
29
|
value = platform.unmarshallArray(value);
|
|
31
30
|
}
|
|
32
31
|
return value.map(i => this.toJsValue(i));
|
package/types/BigIntType.d.ts
CHANGED
|
@@ -5,13 +5,15 @@ import type { EntityProperty } from '../typings.js';
|
|
|
5
5
|
* This type will automatically convert string values returned from the database to native JS bigints (default)
|
|
6
6
|
* or numbers (safe only for values up to `Number.MAX_SAFE_INTEGER`), or strings, depending on the `mode`.
|
|
7
7
|
*/
|
|
8
|
-
export declare class BigIntType extends
|
|
9
|
-
mode?:
|
|
10
|
-
constructor(mode?:
|
|
11
|
-
convertToDatabaseValue(value:
|
|
12
|
-
convertToJSValue(value: string | bigint | null | undefined):
|
|
13
|
-
toJSON(value:
|
|
8
|
+
export declare class BigIntType<Mode extends 'bigint' | 'number' | 'string' = 'bigint'> extends Type<JSTypeByMode<Mode> | null | undefined, string | null | undefined> {
|
|
9
|
+
mode?: Mode | undefined;
|
|
10
|
+
constructor(mode?: Mode | undefined);
|
|
11
|
+
convertToDatabaseValue(value: JSTypeByMode<Mode> | null | undefined): string | null | undefined;
|
|
12
|
+
convertToJSValue(value: string | bigint | null | undefined): JSTypeByMode<Mode> | null | undefined;
|
|
13
|
+
toJSON(value: JSTypeByMode<Mode> | null | undefined): JSTypeByMode<Mode> | null | undefined;
|
|
14
14
|
getColumnType(prop: EntityProperty, platform: Platform): string;
|
|
15
15
|
compareAsType(): string;
|
|
16
16
|
compareValues(a: string, b: string): boolean;
|
|
17
17
|
}
|
|
18
|
+
type JSTypeByMode<Mode extends 'bigint' | 'number' | 'string'> = Mode extends 'bigint' ? bigint : Mode extends 'number' ? number : string;
|
|
19
|
+
export {};
|
package/types/BigIntType.js
CHANGED
package/types/BlobType.d.ts
CHANGED
|
@@ -4,6 +4,5 @@ import type { EntityProperty } from '../typings.js';
|
|
|
4
4
|
export declare class BlobType extends Uint8ArrayType {
|
|
5
5
|
convertToJSValue(value: Buffer): Buffer | null;
|
|
6
6
|
compareAsType(): string;
|
|
7
|
-
ensureComparable(): boolean;
|
|
8
7
|
getColumnType(prop: EntityProperty, platform: Platform): string;
|
|
9
8
|
}
|
package/types/BlobType.js
CHANGED
package/types/BooleanType.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Type } from './Type.js';
|
|
2
2
|
import type { Platform } from '../platforms/Platform.js';
|
|
3
3
|
import type { EntityProperty } from '../typings.js';
|
|
4
|
-
export declare class BooleanType extends Type<
|
|
4
|
+
export declare class BooleanType extends Type<boolean | null | undefined, boolean | null | undefined> {
|
|
5
5
|
getColumnType(prop: EntityProperty, platform: Platform): string;
|
|
6
6
|
compareAsType(): string;
|
|
7
|
+
convertToJSValue(value: boolean | null | undefined): boolean | null | undefined;
|
|
7
8
|
ensureComparable(): boolean;
|
|
8
9
|
}
|
package/types/BooleanType.js
CHANGED
package/types/DecimalType.d.ts
CHANGED
|
@@ -4,12 +4,14 @@ import type { EntityProperty } from '../typings.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* Type that maps an SQL DECIMAL to a JS string or number.
|
|
6
6
|
*/
|
|
7
|
-
export declare class DecimalType extends
|
|
8
|
-
mode?:
|
|
9
|
-
constructor(mode?:
|
|
10
|
-
convertToJSValue(value: string):
|
|
7
|
+
export declare class DecimalType<Mode extends 'number' | 'string' = 'string'> extends Type<JSTypeByMode<Mode>, string> {
|
|
8
|
+
mode?: Mode | undefined;
|
|
9
|
+
constructor(mode?: Mode | undefined);
|
|
10
|
+
convertToJSValue(value: string): JSTypeByMode<Mode>;
|
|
11
11
|
compareValues(a: string, b: string): boolean;
|
|
12
12
|
private format;
|
|
13
13
|
getColumnType(prop: EntityProperty, platform: Platform): string;
|
|
14
14
|
compareAsType(): string;
|
|
15
15
|
}
|
|
16
|
+
type JSTypeByMode<Mode extends 'number' | 'string'> = Mode extends 'number' ? number : string;
|
|
17
|
+
export {};
|
package/types/DecimalType.js
CHANGED
|
@@ -8,18 +8,18 @@ export class DecimalType extends Type {
|
|
|
8
8
|
super();
|
|
9
9
|
this.mode = mode;
|
|
10
10
|
}
|
|
11
|
-
/* v8 ignore next
|
|
11
|
+
/* v8 ignore next */
|
|
12
12
|
convertToJSValue(value) {
|
|
13
13
|
if ((this.mode ?? this.prop?.runtimeType) === 'number') {
|
|
14
14
|
return +value;
|
|
15
15
|
}
|
|
16
|
-
return value;
|
|
16
|
+
return String(value);
|
|
17
17
|
}
|
|
18
18
|
compareValues(a, b) {
|
|
19
19
|
return this.format(a) === this.format(b);
|
|
20
20
|
}
|
|
21
21
|
format(val) {
|
|
22
|
-
/* v8 ignore next
|
|
22
|
+
/* v8 ignore next */
|
|
23
23
|
if (this.prop?.scale == null) {
|
|
24
24
|
return +val;
|
|
25
25
|
}
|
package/types/DoubleType.js
CHANGED
|
@@ -3,12 +3,12 @@ import { Type } from './Type.js';
|
|
|
3
3
|
* Type that maps an SQL DOUBLE to a JS string or number.
|
|
4
4
|
*/
|
|
5
5
|
export class DoubleType extends Type {
|
|
6
|
-
/* v8 ignore next
|
|
6
|
+
/* v8 ignore next */
|
|
7
7
|
convertToJSValue(value) {
|
|
8
8
|
if (this.prop?.runtimeType === 'number') {
|
|
9
9
|
return +value;
|
|
10
10
|
}
|
|
11
|
-
return value;
|
|
11
|
+
return String(value);
|
|
12
12
|
}
|
|
13
13
|
getColumnType(prop, platform) {
|
|
14
14
|
return platform.getDoubleDeclarationSQL();
|
package/types/JsonType.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare class JsonType extends Type<unknown, string | null> {
|
|
|
5
5
|
convertToDatabaseValue(value: unknown, platform: Platform, context?: TransformContext): string | null;
|
|
6
6
|
convertToJSValueSQL(key: string, platform: Platform): string;
|
|
7
7
|
convertToDatabaseValueSQL(key: string, platform: Platform): string;
|
|
8
|
-
convertToJSValue(value: string | unknown, platform: Platform): unknown;
|
|
8
|
+
convertToJSValue(value: string | unknown, platform: Platform, context?: TransformContext): unknown;
|
|
9
9
|
getColumnType(prop: EntityProperty, platform: Platform): string;
|
|
10
10
|
ensureComparable<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T>): boolean;
|
|
11
11
|
compareAsType(): string;
|
package/types/JsonType.js
CHANGED
|
@@ -12,8 +12,13 @@ export class JsonType extends Type {
|
|
|
12
12
|
convertToDatabaseValueSQL(key, platform) {
|
|
13
13
|
return key + platform.castColumn(this.prop);
|
|
14
14
|
}
|
|
15
|
-
convertToJSValue(value, platform) {
|
|
16
|
-
|
|
15
|
+
convertToJSValue(value, platform, context) {
|
|
16
|
+
const isJsonColumn = ['json', 'jsonb', platform.getJsonDeclarationSQL()].includes(this.prop.columnTypes[0]);
|
|
17
|
+
const isObjectEmbedded = this.prop.embedded && this.prop.object;
|
|
18
|
+
if ((platform.convertsJsonAutomatically() || isObjectEmbedded) && isJsonColumn && !context?.force) {
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
return platform.convertJsonToJSValue(value, context);
|
|
17
22
|
}
|
|
18
23
|
getColumnType(prop, platform) {
|
|
19
24
|
return platform.getJsonDeclarationSQL();
|