@mikro-orm/entity-generator 7.0.0-rc.2 → 7.0.0

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.
@@ -28,7 +28,7 @@ export class DefineEntitySourceFile extends EntitySchemaSourceFile {
28
28
  else {
29
29
  entitySchemaOptions.class = this.meta.className;
30
30
  }
31
- Object.assign(entitySchemaOptions, (this.meta.embeddable ? this.getEmbeddableDeclOptions() : (this.meta.collection ? this.getEntityDeclOptions() : {})));
31
+ Object.assign(entitySchemaOptions, this.meta.embeddable ? this.getEmbeddableDeclOptions() : this.meta.collection ? this.getEntityDeclOptions() : {});
32
32
  const nameSuffix = this.options.inferEntityType ? '' : 'Schema';
33
33
  const declLine = `export const ${this.meta.className + nameSuffix} = ${this.referenceCoreImport('defineEntity')}(`;
34
34
  ret += declLine;
@@ -81,14 +81,45 @@ export class DefineEntitySourceFile extends EntitySchemaSourceFile {
81
81
  }
82
82
  }
83
83
  const simpleOptions = new Set([
84
- 'primary', 'ref', 'nullable', 'array', 'object', 'mapToPk', 'hidden', 'concurrencyCheck', 'lazy', 'eager',
85
- 'orphanRemoval', 'version', 'unsigned', 'returning', 'createForeignKeyConstraint', 'fixedOrder', 'owner',
86
- 'getter', 'setter', 'unique', 'index', 'hydrate', 'persist', 'autoincrement',
84
+ 'primary',
85
+ 'ref',
86
+ 'nullable',
87
+ 'array',
88
+ 'object',
89
+ 'mapToPk',
90
+ 'hidden',
91
+ 'concurrencyCheck',
92
+ 'lazy',
93
+ 'eager',
94
+ 'orphanRemoval',
95
+ 'version',
96
+ 'unsigned',
97
+ 'returning',
98
+ 'createForeignKeyConstraint',
99
+ 'fixedOrder',
100
+ 'owner',
101
+ 'getter',
102
+ 'setter',
103
+ 'unique',
104
+ 'index',
105
+ 'hydrate',
106
+ 'persist',
107
+ 'autoincrement',
87
108
  ]);
88
109
  const skipOptions = new Set(['entity', 'kind', 'type', 'items']);
89
110
  const spreadOptions = new Set([
90
- 'fieldNames', 'joinColumns', 'inverseJoinColumns', 'referencedColumnNames', 'ownColumns', 'columnTypes',
91
- 'cascade', 'ignoreSchemaChanges', 'customOrder', 'groups', 'where', 'orderBy',
111
+ 'fieldNames',
112
+ 'joinColumns',
113
+ 'inverseJoinColumns',
114
+ 'referencedColumnNames',
115
+ 'ownColumns',
116
+ 'columnTypes',
117
+ 'cascade',
118
+ 'ignoreSchemaChanges',
119
+ 'customOrder',
120
+ 'groups',
121
+ 'where',
122
+ 'orderBy',
92
123
  ]);
93
124
  const rename = {
94
125
  fieldName: 'name',
@@ -1,15 +1,7 @@
1
1
  import { type GenerateOptions, type MikroORM } from '@mikro-orm/core';
2
2
  import { type EntityManager } from '@mikro-orm/sql';
3
3
  export declare class EntityGenerator {
4
- private readonly em;
5
- private readonly config;
6
- private readonly driver;
7
- private readonly platform;
8
- private readonly helper;
9
- private readonly connection;
10
- private readonly namingStrategy;
11
- private readonly sources;
12
- private readonly referencedEntities;
4
+ #private;
13
5
  constructor(em: EntityManager);
14
6
  static register(orm: MikroORM): void;
15
7
  generate(options?: GenerateOptions): Promise<string[]>;
@@ -8,34 +8,34 @@ import { EntitySchemaSourceFile } from './EntitySchemaSourceFile.js';
8
8
  import { NativeEnumSourceFile } from './NativeEnumSourceFile.js';
9
9
  import { SourceFile } from './SourceFile.js';
10
10
  export class EntityGenerator {
11
- em;
12
- config;
13
- driver;
14
- platform;
15
- helper;
16
- connection;
17
- namingStrategy;
18
- sources = [];
19
- referencedEntities = new WeakSet();
11
+ #config;
12
+ #driver;
13
+ #platform;
14
+ #helper;
15
+ #connection;
16
+ #namingStrategy;
17
+ #sources = [];
18
+ #referencedEntities = new WeakSet();
19
+ #em;
20
20
  constructor(em) {
21
- this.em = em;
22
- this.config = this.em.config;
23
- this.driver = this.em.getDriver();
24
- this.platform = this.driver.getPlatform();
25
- this.helper = this.platform.getSchemaHelper();
26
- this.connection = this.driver.getConnection();
27
- this.namingStrategy = this.config.getNamingStrategy();
21
+ this.#em = em;
22
+ this.#config = this.#em.config;
23
+ this.#driver = this.#em.getDriver();
24
+ this.#platform = this.#driver.getPlatform();
25
+ this.#helper = this.#platform.getSchemaHelper();
26
+ this.#connection = this.#driver.getConnection();
27
+ this.#namingStrategy = this.#config.getNamingStrategy();
28
28
  }
29
29
  static register(orm) {
30
30
  orm.config.registerExtension('@mikro-orm/entity-generator', () => new EntityGenerator(orm.em));
31
31
  }
32
32
  async generate(options = {}) {
33
- options = Utils.mergeConfig({}, this.config.get('entityGenerator'), options);
34
- const schema = await DatabaseSchema.create(this.connection, this.platform, this.config, undefined, undefined, options.takeTables, options.skipTables);
33
+ options = Utils.mergeConfig({}, this.#config.get('entityGenerator'), options);
34
+ const schema = await DatabaseSchema.create(this.#connection, this.#platform, this.#config, undefined, undefined, options.takeTables, options.skipTables);
35
35
  const metadata = await this.getEntityMetadata(schema, options);
36
- const defaultPath = `${this.config.get('baseDir')}/generated-entities`;
36
+ const defaultPath = `${this.#config.get('baseDir')}/generated-entities`;
37
37
  const baseDir = fs.normalizePath(options.path ?? defaultPath);
38
- this.sources.length = 0;
38
+ this.#sources.length = 0;
39
39
  const map = {
40
40
  defineEntity: DefineEntitySourceFile,
41
41
  entitySchema: EntitySchemaSourceFile,
@@ -45,15 +45,15 @@ export class EntityGenerator {
45
45
  options.scalarTypeInDecorator = true;
46
46
  }
47
47
  for (const meta of metadata) {
48
- if (meta.pivotTable && !options.outputPurePivotTables && !this.referencedEntities.has(meta)) {
48
+ if (meta.pivotTable && !options.outputPurePivotTables && !this.#referencedEntities.has(meta)) {
49
49
  continue;
50
50
  }
51
- this.sources.push(new map[options.entityDefinition](meta, this.namingStrategy, this.platform, options));
51
+ this.#sources.push(new map[options.entityDefinition](meta, this.#namingStrategy, this.#platform, options));
52
52
  }
53
53
  for (const nativeEnum of Object.values(schema.getNativeEnums())) {
54
- this.sources.push(new NativeEnumSourceFile({}, this.namingStrategy, this.platform, options, nativeEnum));
54
+ this.#sources.push(new NativeEnumSourceFile({}, this.#namingStrategy, this.#platform, options, nativeEnum));
55
55
  }
56
- const files = this.sources.map(file => [file.getBaseName(), file.generate()]);
56
+ const files = this.#sources.map(file => [file.getBaseName(), file.generate()]);
57
57
  if (options.save) {
58
58
  fs.ensureDir(baseDir);
59
59
  const promises = [];
@@ -71,7 +71,8 @@ export class EntityGenerator {
71
71
  return files.map(([, data]) => data);
72
72
  }
73
73
  async getEntityMetadata(schema, options) {
74
- const metadata = schema.getTables()
74
+ const metadata = schema
75
+ .getTables()
75
76
  .filter(table => !options.schema || table.schema === options.schema)
76
77
  .sort((a, b) => `${a.schema}.${a.name}`.localeCompare(`${b.schema}.${b.name}`))
77
78
  .map(table => {
@@ -83,16 +84,21 @@ export class EntityGenerator {
83
84
  }
84
85
  }
85
86
  }
86
- return table.getEntityDeclaration(this.namingStrategy, this.helper, options.scalarPropertiesForRelations);
87
+ return table.getEntityDeclaration(this.#namingStrategy, this.#helper, options.scalarPropertiesForRelations);
87
88
  });
88
89
  for (const meta of metadata) {
89
90
  for (const prop of meta.relations) {
90
- if (!metadata.some(otherMeta => prop.referencedTableName === otherMeta.collection || prop.referencedTableName === `${otherMeta.schema ?? schema.name}.${otherMeta.collection}`)) {
91
+ if (!metadata.some(otherMeta => prop.referencedTableName === otherMeta.collection ||
92
+ prop.referencedTableName === `${otherMeta.schema ?? schema.name}.${otherMeta.collection}`)) {
91
93
  prop.kind = ReferenceKind.SCALAR;
92
- const mappedTypes = prop.columnTypes.map((t, i) => this.platform.getMappedType(t));
94
+ const mappedTypes = prop.columnTypes.map((t, i) => this.#platform.getMappedType(t));
93
95
  const runtimeTypes = mappedTypes.map(t => t.runtimeType);
94
96
  prop.runtimeType = (runtimeTypes.length === 1 ? runtimeTypes[0] : `[${runtimeTypes.join(', ')}]`);
95
- prop.type = mappedTypes.length === 1 ? (Utils.entries(types).find(([k, v]) => Object.getPrototypeOf(mappedTypes[0]) === v.prototype)?.[0] ?? mappedTypes[0].name) : 'unknown';
97
+ prop.type =
98
+ mappedTypes.length === 1
99
+ ? (Utils.entries(types).find(([k, v]) => Object.getPrototypeOf(mappedTypes[0]) === v.prototype)?.[0] ??
100
+ mappedTypes[0].name)
101
+ : 'unknown';
96
102
  }
97
103
  const meta2 = metadata.find(meta2 => meta2.className === prop.type);
98
104
  const targetPrimaryColumns = meta2?.getPrimaryProps().flatMap(p => p.fieldNames);
@@ -103,15 +109,17 @@ export class EntityGenerator {
103
109
  }
104
110
  }
105
111
  }
106
- await options.onInitialMetadata?.(metadata, this.platform);
112
+ await options.onInitialMetadata?.(metadata, this.#platform);
107
113
  // enforce schema usage in class names only on duplicates
108
114
  const duplicates = Utils.findDuplicates(metadata.map(meta => meta.className));
109
115
  for (const duplicate of duplicates) {
110
116
  for (const meta of metadata.filter(meta => meta.className === duplicate)) {
111
- meta.className = this.namingStrategy.getEntityName(`${meta.schema ?? schema.name}_${meta.className}`);
117
+ meta.className = this.#namingStrategy.getEntityName(`${meta.schema ?? schema.name}_${meta.className}`);
112
118
  for (const relMeta of metadata) {
113
119
  for (const prop of relMeta.relations) {
114
- if (prop.type === duplicate && (prop.referencedTableName === meta.collection || prop.referencedTableName === `${meta.schema ?? schema.name}.${meta.collection}`)) {
120
+ if (prop.type === duplicate &&
121
+ (prop.referencedTableName === meta.collection ||
122
+ prop.referencedTableName === `${meta.schema ?? schema.name}.${meta.collection}`)) {
115
123
  prop.type = meta.className;
116
124
  }
117
125
  }
@@ -132,7 +140,7 @@ export class EntityGenerator {
132
140
  if (options.undefinedDefaults) {
133
141
  this.castNullDefaultsToUndefined(metadata);
134
142
  }
135
- await options.onProcessedMetadata?.(metadata, this.platform);
143
+ await options.onProcessedMetadata?.(metadata, this.#platform);
136
144
  return metadata;
137
145
  }
138
146
  cleanUpReferentialIntegrityRules(metadata) {
@@ -197,12 +205,14 @@ export class EntityGenerator {
197
205
  detectManyToManyRelations(metadata, onlyPurePivotTables, readOnlyPivotTables, outputPurePivotTables) {
198
206
  for (const meta of metadata) {
199
207
  const isReferenced = metadata.some(m => {
200
- return m.tableName !== meta.tableName && m.relations.some(r => {
201
- return r.referencedTableName === meta.tableName && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(r.kind);
202
- });
208
+ return (m.tableName !== meta.tableName &&
209
+ m.relations.some(r => {
210
+ return (r.referencedTableName === meta.tableName &&
211
+ [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(r.kind));
212
+ }));
203
213
  });
204
214
  if (isReferenced) {
205
- this.referencedEntities.add(meta);
215
+ this.#referencedEntities.add(meta);
206
216
  }
207
217
  // Entities with non-composite PKs are never pivot tables. Skip.
208
218
  if (!meta.compositePK) {
@@ -210,8 +220,7 @@ export class EntityGenerator {
210
220
  }
211
221
  // Entities where there are not exactly 2 PK relations that are both ManyToOne are never pivot tables. Skip.
212
222
  const pkRelations = meta.relations.filter(rel => rel.primary);
213
- if (pkRelations.length !== 2 ||
214
- pkRelations.some(rel => rel.kind !== ReferenceKind.MANY_TO_ONE)) {
223
+ if (pkRelations.length !== 2 || pkRelations.some(rel => rel.kind !== ReferenceKind.MANY_TO_ONE)) {
215
224
  continue;
216
225
  }
217
226
  const pkRelationFields = new Set(pkRelations.flatMap(rel => rel.fieldNames));
@@ -227,8 +236,7 @@ export class EntityGenerator {
227
236
  continue;
228
237
  }
229
238
  const pkRelationNames = pkRelations.map(rel => rel.name);
230
- let otherProps = meta.props
231
- .filter(prop => !pkRelationNames.includes(prop.name) &&
239
+ let otherProps = meta.props.filter(prop => !pkRelationNames.includes(prop.name) &&
232
240
  prop.persist !== false && // Skip checking non-persist props
233
241
  prop.fieldNames.some(fieldName => nonPkFields.includes(fieldName)));
234
242
  // Deal with the auto increment column first. That is the column used for fixed ordering, if present.
@@ -255,7 +263,7 @@ export class EntityGenerator {
255
263
  // If this now proven pivot entity has persistent props other than the fixed order column,
256
264
  // output it, by considering it as a referenced one.
257
265
  if (otherProps.length > 0) {
258
- this.referencedEntities.add(meta);
266
+ this.#referencedEntities.add(meta);
259
267
  }
260
268
  }
261
269
  meta.pivotTable = true;
@@ -271,7 +279,7 @@ export class EntityGenerator {
271
279
  }
272
280
  const owner = metadata.find(m => m.className === meta.relations[0].type);
273
281
  const target = metadata.find(m => m.className === meta.relations[1].type);
274
- const name = this.namingStrategy.manyToManyPropertyName(owner.className, target.className, meta.tableName, owner.tableName, meta.schema);
282
+ const name = this.#namingStrategy.manyToManyPropertyName(owner.className, target.className, meta.tableName, owner.tableName, meta.schema);
275
283
  const ownerProp = {
276
284
  name,
277
285
  kind: ReferenceKind.MANY_TO_MANY,
@@ -280,7 +288,7 @@ export class EntityGenerator {
280
288
  joinColumns: meta.relations[0].fieldNames,
281
289
  inverseJoinColumns: meta.relations[1].fieldNames,
282
290
  };
283
- if (outputPurePivotTables || this.referencedEntities.has(meta)) {
291
+ if (outputPurePivotTables || this.#referencedEntities.has(meta)) {
284
292
  ownerProp.pivotEntity = meta.class;
285
293
  }
286
294
  if (fixedOrderColumn) {
@@ -296,7 +304,7 @@ export class EntityGenerator {
296
304
  generateBidirectionalRelations(metadata, includeUnreferencedPurePivotTables) {
297
305
  const filteredMetadata = includeUnreferencedPurePivotTables
298
306
  ? metadata
299
- : metadata.filter(m => !m.pivotTable || this.referencedEntities.has(m));
307
+ : metadata.filter(m => !m.pivotTable || this.#referencedEntities.has(m));
300
308
  for (const meta of filteredMetadata) {
301
309
  for (const prop of meta.relations) {
302
310
  const targetMeta = metadata.find(m => m.className === prop.type);
@@ -327,16 +335,16 @@ export class EntityGenerator {
327
335
  continue;
328
336
  }
329
337
  let i = 1;
330
- const name = newProp.name = this.namingStrategy.inverseSideName(meta.className, prop.name, newProp.kind);
338
+ const name = (newProp.name = this.#namingStrategy.inverseSideName(meta.className, prop.name, newProp.kind));
331
339
  while (targetMeta.properties[newProp.name]) {
332
- newProp.name = name + (i++);
340
+ newProp.name = name + i++;
333
341
  }
334
342
  targetMeta.addProperty(newProp);
335
343
  }
336
344
  }
337
345
  }
338
346
  generateIdentifiedReferences(metadata) {
339
- for (const meta of metadata.filter(m => !m.pivotTable || this.referencedEntities.has(m))) {
347
+ for (const meta of metadata.filter(m => !m.pivotTable || this.#referencedEntities.has(m))) {
340
348
  for (const prop of Object.values(meta.properties)) {
341
349
  if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) || prop.lazy) {
342
350
  prop.ref = true;
@@ -19,7 +19,11 @@ export class EntitySchemaSourceFile extends SourceFile {
19
19
  ret += `\n`;
20
20
  const entitySchemaOptions = {
21
21
  class: this.meta.className,
22
- ...(this.meta.embeddable ? this.getEmbeddableDeclOptions() : (this.meta.collection ? this.getEntityDeclOptions() : {})),
22
+ ...(this.meta.embeddable
23
+ ? this.getEmbeddableDeclOptions()
24
+ : this.meta.collection
25
+ ? this.getEntityDeclOptions()
26
+ : {}),
23
27
  };
24
28
  const declLine = `export const ${this.meta.className}Schema = new ${this.referenceCoreImport('EntitySchema')}(`;
25
29
  ret += declLine;
@@ -72,7 +76,7 @@ export class EntitySchemaSourceFile extends SourceFile {
72
76
  const eagerPropertyNames = eagerProperties.map(prop => `'${prop.name}'`).sort();
73
77
  classBody += `${' '.repeat(2)}[${this.referenceCoreImport('EagerProps')}]?: ${eagerPropertyNames.join(' | ')};\n`;
74
78
  }
75
- classBody += `${props.join('')}`;
79
+ classBody += props.join('');
76
80
  return this.getEntityClass(classBody);
77
81
  }
78
82
  getPropertyOptions(prop, quote = true) {
@@ -122,7 +126,7 @@ export class EntitySchemaSourceFile extends SourceFile {
122
126
  }
123
127
  const defaultName = this.platform.getIndexName(this.meta.collection, prop.fieldNames, type);
124
128
  /* v8 ignore next */
125
- options[type] = (propType === true || defaultName === propType) ? 'true' : this.quote(propType);
129
+ options[type] = propType === true || defaultName === propType ? 'true' : this.quote(propType);
126
130
  const expected = {
127
131
  index: this.platform.indexForeignKeys(),
128
132
  unique: prop.kind === ReferenceKind.ONE_TO_ONE,
@@ -1,11 +1,7 @@
1
1
  import type { EntityMetadata, GenerateOptions, NamingStrategy, Platform } from '@mikro-orm/core';
2
2
  import { SourceFile } from './SourceFile.js';
3
3
  export declare class NativeEnumSourceFile extends SourceFile {
4
- protected readonly nativeEnum: {
5
- name: string;
6
- schema?: string;
7
- items: string[];
8
- };
4
+ private readonly nativeEnum;
9
5
  constructor(meta: EntityMetadata, namingStrategy: NamingStrategy, platform: Platform, options: GenerateOptions, nativeEnum: {
10
6
  name: string;
11
7
  schema?: string;
package/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
  <a href="https://mikro-orm.io"><img src="https://raw.githubusercontent.com/mikro-orm/mikro-orm/master/docs/static/img/logo-readme.svg?sanitize=true" alt="MikroORM" /></a>
3
3
  </h1>
4
4
 
5
- TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL and SQLite (including libSQL) databases.
5
+ TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL, SQLite (including libSQL), MSSQL and Oracle databases.
6
6
 
7
7
  > Heavily inspired by [Doctrine](https://www.doctrine-project.org/) and [Hibernate](https://hibernate.org/).
8
8
 
9
- [![NPM version](https://img.shields.io/npm/v/@mikro-orm/core.svg)](https://www.npmjs.com/package/@mikro-orm/core)
10
- [![NPM dev version](https://img.shields.io/npm/v/@mikro-orm/core/next.svg)](https://www.npmjs.com/package/@mikro-orm/core)
9
+ [![NPM version](https://img.shields.io/npm/v/@mikro-orm/core.svg)](https://npmx.dev/package/@mikro-orm/core)
10
+ [![NPM dev version](https://img.shields.io/npm/v/@mikro-orm/core/next.svg)](https://npmx.dev/package/@mikro-orm/core)
11
11
  [![Chat on discord](https://img.shields.io/discord/1214904142443839538?label=discord&color=blue)](https://discord.gg/w8bjxFHS7X)
12
- [![Downloads](https://img.shields.io/npm/dm/@mikro-orm/core.svg)](https://www.npmjs.com/package/@mikro-orm/core)
12
+ [![Downloads](https://img.shields.io/npm/dm/@mikro-orm/core.svg)](https://npmx.dev/package/@mikro-orm/core)
13
13
  [![Coverage Status](https://img.shields.io/coveralls/mikro-orm/mikro-orm.svg)](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
14
14
  [![Build Status](https://github.com/mikro-orm/mikro-orm/workflows/tests/badge.svg?branch=master)](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
15
15
 
@@ -181,6 +181,7 @@ yarn add @mikro-orm/core @mikro-orm/mysql # for mysql/mariadb
181
181
  yarn add @mikro-orm/core @mikro-orm/mariadb # for mysql/mariadb
182
182
  yarn add @mikro-orm/core @mikro-orm/postgresql # for postgresql
183
183
  yarn add @mikro-orm/core @mikro-orm/mssql # for mssql
184
+ yarn add @mikro-orm/core @mikro-orm/oracledb # for oracle
184
185
  yarn add @mikro-orm/core @mikro-orm/sqlite # for sqlite
185
186
  yarn add @mikro-orm/core @mikro-orm/libsql # for libsql
186
187
  ```
package/SourceFile.d.ts CHANGED
@@ -4,6 +4,7 @@ import { type Dictionary, type EmbeddableOptions, type EntityMetadata, type Enti
4
4
  */
5
5
  export declare const identifierRegex: RegExp;
6
6
  export declare class SourceFile {
7
+ #private;
7
8
  protected readonly meta: EntityMetadata;
8
9
  protected readonly namingStrategy: NamingStrategy;
9
10
  protected readonly platform: Platform;
@@ -34,7 +35,6 @@ export declare class SourceFile {
34
35
  private getPropertyDecorator;
35
36
  protected getPropertyIndexes(prop: EntityProperty, options: Dictionary): string[];
36
37
  protected getCommonDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
37
- private propTypeBreakdowns;
38
38
  private breakdownOfIType;
39
39
  protected getScalarPropertyDecoratorOptions(options: Dictionary, prop: EntityProperty, quote?: boolean): void;
40
40
  protected getManyToManyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;