@mikro-orm/core 7.0.17 → 7.0.18-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/EntityManager.d.ts +106 -12
  2. package/EntityManager.js +228 -19
  3. package/MikroORM.d.ts +3 -3
  4. package/README.md +2 -1
  5. package/connections/Connection.d.ts +67 -1
  6. package/connections/Connection.js +64 -0
  7. package/drivers/DatabaseDriver.d.ts +1 -0
  8. package/drivers/DatabaseDriver.js +3 -0
  9. package/drivers/IDatabaseDriver.d.ts +50 -7
  10. package/entity/BaseEntity.d.ts +70 -3
  11. package/entity/BaseEntity.js +18 -0
  12. package/entity/Collection.d.ts +6 -3
  13. package/entity/Collection.js +15 -4
  14. package/entity/EntityAssigner.js +8 -0
  15. package/entity/EntityFactory.js +20 -1
  16. package/entity/EntityLoader.d.ts +8 -1
  17. package/entity/EntityLoader.js +41 -16
  18. package/entity/EntityRepository.d.ts +27 -9
  19. package/entity/EntityRepository.js +12 -0
  20. package/entity/Reference.d.ts +42 -1
  21. package/entity/Reference.js +9 -0
  22. package/entity/WrappedEntity.d.ts +2 -2
  23. package/entity/defineEntity.d.ts +92 -17
  24. package/entity/defineEntity.js +17 -6
  25. package/entity/utils.js +4 -5
  26. package/enums.d.ts +8 -1
  27. package/errors.d.ts +2 -0
  28. package/errors.js +4 -0
  29. package/index.d.ts +2 -2
  30. package/index.js +1 -1
  31. package/metadata/EntitySchema.js +3 -0
  32. package/metadata/MetadataDiscovery.d.ts +11 -0
  33. package/metadata/MetadataDiscovery.js +135 -10
  34. package/metadata/MetadataValidator.d.ts +26 -0
  35. package/metadata/MetadataValidator.js +236 -0
  36. package/metadata/Routine.d.ts +74 -0
  37. package/metadata/Routine.js +140 -0
  38. package/metadata/index.d.ts +1 -0
  39. package/metadata/index.js +1 -0
  40. package/metadata/types.d.ts +77 -4
  41. package/naming-strategy/AbstractNamingStrategy.d.ts +1 -1
  42. package/naming-strategy/NamingStrategy.d.ts +1 -1
  43. package/package.json +1 -1
  44. package/platforms/Platform.d.ts +7 -0
  45. package/platforms/Platform.js +15 -1
  46. package/serialization/EntitySerializer.d.ts +18 -6
  47. package/serialization/EntitySerializer.js +31 -4
  48. package/typings.d.ts +389 -18
  49. package/typings.js +21 -4
  50. package/unit-of-work/UnitOfWork.js +11 -3
  51. package/utils/AbstractMigrator.d.ts +26 -3
  52. package/utils/AbstractMigrator.js +264 -15
  53. package/utils/AbstractSchemaGenerator.d.ts +1 -1
  54. package/utils/AbstractSchemaGenerator.js +4 -1
  55. package/utils/Configuration.d.ts +40 -3
  56. package/utils/Configuration.js +46 -0
  57. package/utils/DataloaderUtils.d.ts +10 -1
  58. package/utils/DataloaderUtils.js +78 -0
  59. package/utils/QueryHelper.d.ts +16 -0
  60. package/utils/QueryHelper.js +15 -0
  61. package/utils/TransactionManager.js +2 -0
  62. package/utils/Utils.d.ts +1 -1
  63. package/utils/Utils.js +1 -1
  64. package/utils/fs-utils.d.ts +2 -0
  65. package/utils/fs-utils.js +7 -1
  66. package/utils/index.d.ts +1 -0
  67. package/utils/index.js +1 -0
  68. package/utils/partition-utils.d.ts +17 -0
  69. package/utils/partition-utils.js +79 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.0.17",
3
+ "version": "7.0.18-dev.1",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "keywords": [
6
6
  "data-mapper",
@@ -43,6 +43,8 @@ export declare abstract class Platform {
43
43
  getEnumArrayCheckConstraintExpression(column: string, items: string[]): string | null;
44
44
  /** Whether this platform supports materialized views. */
45
45
  supportsMaterializedViews(): boolean;
46
+ /** Whether this platform supports declarative table partitioning in schema generation. */
47
+ supportsPartitionedTables(): boolean;
46
48
  /** Returns the schema helper instance for this platform, or undefined if not supported. */
47
49
  getSchemaHelper(): unknown;
48
50
  /** Whether the platform automatically creates indexes on foreign key columns. */
@@ -211,6 +213,11 @@ export declare abstract class Platform {
211
213
  getFullTextWhereClause(prop: EntityProperty): string;
212
214
  supportsCreatingFullTextIndex(): boolean;
213
215
  getFullTextIndexExpression(indexName: string, schemaName: string | undefined, tableName: string, columns: SimpleColumnMeta[]): string;
216
+ /**
217
+ * Generates the SQL index hint clause for the given index names.
218
+ * Returns `undefined` when the platform does not support index hints (e.g. PostgreSQL, SQLite).
219
+ */
220
+ formatIndexHint(indexNames: string[]): string | undefined;
214
221
  /** Whether the driver automatically parses JSON columns into JS objects. */
215
222
  convertsJsonAutomatically(): boolean;
216
223
  /** Converts a JS value to its JSON database representation (typically JSON.stringify). */
@@ -2,6 +2,7 @@ import { clone } from '../utils/clone.js';
2
2
  import { EntityRepository } from '../entity/EntityRepository.js';
3
3
  import { UnderscoreNamingStrategy } from '../naming-strategy/UnderscoreNamingStrategy.js';
4
4
  import { ExceptionConverter } from './ExceptionConverter.js';
5
+ import { MetadataError } from '../errors.js';
5
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';
6
7
  import { parseJsonSafe, Utils } from '../utils/Utils.js';
7
8
  import { ReferenceKind } from '../enums.js';
@@ -71,6 +72,10 @@ export class Platform {
71
72
  supportsMaterializedViews() {
72
73
  return false;
73
74
  }
75
+ /** Whether this platform supports declarative table partitioning in schema generation. */
76
+ supportsPartitionedTables() {
77
+ return false;
78
+ }
74
79
  /** Returns the schema helper instance for this platform, or undefined if not supported. */
75
80
  getSchemaHelper() {
76
81
  return undefined;
@@ -436,6 +441,13 @@ export class Platform {
436
441
  getFullTextIndexExpression(indexName, schemaName, tableName, columns) {
437
442
  throw new Error('Full text searching is not supported by this driver.');
438
443
  }
444
+ /**
445
+ * Generates the SQL index hint clause for the given index names.
446
+ * Returns `undefined` when the platform does not support index hints (e.g. PostgreSQL, SQLite).
447
+ */
448
+ formatIndexHint(indexNames) {
449
+ return undefined;
450
+ }
439
451
  /** Whether the driver automatically parses JSON columns into JS objects. */
440
452
  convertsJsonAutomatically() {
441
453
  return true;
@@ -689,7 +701,9 @@ export class Platform {
689
701
  }
690
702
  /** Platform-specific validation of entity metadata. */
691
703
  validateMetadata(meta) {
692
- return;
704
+ if (meta.partitionBy && !this.supportsPartitionedTables()) {
705
+ throw new MetadataError(`Entity ${meta.className} uses partitionBy, but ${this.constructor.name} does not support partitioned tables`);
706
+ }
693
707
  }
694
708
  /**
695
709
  * Generates a custom order by statement given a set of in order values, eg.
@@ -1,21 +1,33 @@
1
- import type { ArrayElement, AutoPath, CleanTypeConfig, ExtractFieldsHint, FromEntityType, SerializeDTO, TypeConfig, UnboxArray } from '../typings.js';
1
+ import type { ArrayElement, AutoPath, CleanTypeConfig, ExtractFieldsHint, FromEntityType, ResolveSerializeFields, SerializeDTO, SerializeFieldsKeepPK, TypeConfig, UnboxArray } from '../typings.js';
2
2
  import { type PopulatePath } from '../enums.js';
3
- /** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, and serialization groups. */
3
+ /** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, fields, and serialization groups. */
4
4
  export declare class EntitySerializer {
5
- /** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, groups, and custom types. */
6
- static serialize<T extends object, P extends string = never, E extends string = never>(entity: T, options?: SerializeOptions<T, P, E>): SerializeDTO<T, P, E>;
5
+ /** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, fields, groups, and custom types. */
6
+ static serialize<T extends object, P extends string = never, E extends string = never, F extends string = never>(entity: T, options?: SerializeOptions<T, P, E, F>): SerializeDTO<T, P, E, never, ResolveSerializeFields<F>, SerializeFieldsKeepPK<F>>;
7
7
  private static propertyName;
8
8
  private static processProperty;
9
9
  private static processCustomType;
10
10
  private static extractChildOptions;
11
+ /**
12
+ * Extracts the nested `fields` whitelist for a child property. A bare parent name (`fields: ['books']`) or a
13
+ * wildcard removes the whitelist on the sub-tree (everything is included), so consumers don't have to repeat
14
+ * every field of the child. Otherwise dot-paths are stripped of the parent prefix and passed down.
15
+ */
16
+ private static extractChildFields;
11
17
  private static processEntity;
12
18
  private static processCollection;
13
19
  }
14
- export interface SerializeOptions<T, P extends string = never, E extends string = never> {
20
+ export interface SerializeOptions<T, P extends string = never, E extends string = never, F extends string = never> {
15
21
  /** Specify which relation should be serialized as populated and which as a FK. */
16
22
  populate?: readonly AutoPath<T, P, `${PopulatePath.ALL}`>[];
17
23
  /** Specify which properties should be omitted. */
18
24
  exclude?: readonly AutoPath<T, E>[];
25
+ /**
26
+ * Whitelist of properties to serialize, supports dot-paths (e.g. `['name', 'books.title']`). When set, only the
27
+ * listed properties end up in the output, including primary keys. A bare property name keeps its entire sub-tree;
28
+ * a dot-path additionally narrows the nested object to the listed sub-keys. `exclude` takes precedence on conflict.
29
+ */
30
+ fields?: readonly AutoPath<T, F, `${PopulatePath.ALL}`>[];
19
31
  /** Enforce unpopulated references to be returned as objects, e.g. `{ author: { id: 1 } }` instead of `{ author: 1 }`. */
20
32
  forceObject?: boolean;
21
33
  /** Ignore custom property serializers. */
@@ -41,4 +53,4 @@ export interface SerializeOptions<T, P extends string = never, E extends string
41
53
  * const dto2 = wrap(user).serialize({ exclude: ['id', 'email'], forceObject: true });
42
54
  * ```
43
55
  */
44
- export declare function serialize<Entity extends object, Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Populate extends string = never, Exclude extends string = never, Config extends TypeConfig = never>(entity: Entity, options?: Config & SerializeOptions<UnboxArray<Entity>, Populate, Exclude>): Naked extends object[] ? SerializeDTO<ArrayElement<Naked>, Populate, Exclude, CleanTypeConfig<Config>>[] : SerializeDTO<Naked, Populate, Exclude, CleanTypeConfig<Config>, ExtractFieldsHint<Entity>>;
56
+ export declare function serialize<Entity extends object, Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Populate extends string = never, Exclude extends string = never, Fields extends string = never, Config extends TypeConfig = never>(entity: Entity, options?: Config & SerializeOptions<UnboxArray<Entity>, Populate, Exclude, Fields>): Naked extends object[] ? SerializeDTO<ArrayElement<Naked>, Populate, Exclude, CleanTypeConfig<Config>, ResolveSerializeFields<Fields, ExtractFieldsHint<Entity>>, SerializeFieldsKeepPK<Fields>>[] : SerializeDTO<Naked, Populate, Exclude, CleanTypeConfig<Config>, ResolveSerializeFields<Fields, ExtractFieldsHint<Entity>>, SerializeFieldsKeepPK<Fields>>;
@@ -4,13 +4,20 @@ import { ReferenceKind } from '../enums.js';
4
4
  import { Reference } from '../entity/Reference.js';
5
5
  import { SerializationContext } from './SerializationContext.js';
6
6
  import { isRaw } from '../utils/RawQueryFragment.js';
7
+ /** Returns true when any entry in `items` is `propName`, the wildcard `*`, or a dot-path under `propName`. */
8
+ function matchesPath(items, propName) {
9
+ return items.some(item => item === propName || item === '*' || item.startsWith(propName + '.'));
10
+ }
7
11
  function isVisible(meta, propName, options) {
8
12
  const prop = meta.properties[propName];
9
13
  if (options.groups && prop?.groups) {
10
14
  return prop.groups.some(g => options.groups.includes(g));
11
15
  }
16
+ if (Array.isArray(options.fields) && options.fields.length > 0 && !matchesPath(options.fields, propName)) {
17
+ return false;
18
+ }
12
19
  if (Array.isArray(options.populate) &&
13
- options.populate?.find(item => item === propName || item.startsWith(propName + '.'))) {
20
+ options.populate.find(item => item === propName || item.startsWith(propName + '.'))) {
14
21
  return true;
15
22
  }
16
23
  if (options.exclude?.find(item => item === propName)) {
@@ -22,7 +29,8 @@ function isVisible(meta, propName, options) {
22
29
  }
23
30
  function isPopulated(propName, options) {
24
31
  if (typeof options.populate !== 'boolean' &&
25
- options.populate?.find(item => item === propName || item.startsWith(propName + '.') || item === '*')) {
32
+ Array.isArray(options.populate) &&
33
+ matchesPath(options.populate, propName)) {
26
34
  return true;
27
35
  }
28
36
  if (typeof options.populate === 'boolean') {
@@ -30,9 +38,9 @@ function isPopulated(propName, options) {
30
38
  }
31
39
  return false;
32
40
  }
33
- /** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, and serialization groups. */
41
+ /** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, fields, and serialization groups. */
34
42
  export class EntitySerializer {
35
- /** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, groups, and custom types. */
43
+ /** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, fields, groups, and custom types. */
36
44
  static serialize(entity, options = {}) {
37
45
  const wrapped = helper(entity);
38
46
  const meta = wrapped.__meta;
@@ -184,8 +192,27 @@ export class EntitySerializer {
184
192
  ? Utils.extractChildElements(options.populate, prop, '*')
185
193
  : options.populate,
186
194
  exclude: Array.isArray(options.exclude) ? Utils.extractChildElements(options.exclude, prop) : options.exclude,
195
+ fields: Array.isArray(options.fields) ? this.extractChildFields(options.fields, prop) : options.fields,
187
196
  };
188
197
  }
198
+ /**
199
+ * Extracts the nested `fields` whitelist for a child property. A bare parent name (`fields: ['books']`) or a
200
+ * wildcard removes the whitelist on the sub-tree (everything is included), so consumers don't have to repeat
201
+ * every field of the child. Otherwise dot-paths are stripped of the parent prefix and passed down.
202
+ */
203
+ static extractChildFields(fields, prop) {
204
+ const out = [];
205
+ const dotPrefix = prop + '.';
206
+ for (const field of fields) {
207
+ if (field === prop || field === '*') {
208
+ return undefined;
209
+ }
210
+ if (field.startsWith(dotPrefix)) {
211
+ out.push(field.substring(dotPrefix.length));
212
+ }
213
+ }
214
+ return out;
215
+ }
189
216
  static processEntity(prop, entity, platform, options) {
190
217
  const child = Reference.unwrapReference(entity[prop.name]);
191
218
  const wrapped = helper(child);