@mikro-orm/entity-generator 7.0.0-dev.1 → 7.0.0-dev.100

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/SourceFile.js CHANGED
@@ -1,21 +1,20 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SourceFile = exports.identifierRegex = void 0;
4
- const core_1 = require("@mikro-orm/core");
5
- const node_path_1 = require("node:path");
6
- const CoreImportsHelper_1 = require("./CoreImportsHelper");
1
+ import { Cascade, Config, DecimalType, ReferenceKind, SCALAR_TYPES, UnknownType, Utils, inspect, } from '@mikro-orm/core';
2
+ import { parse, relative } from 'node:path';
3
+ import { POSSIBLE_TYPE_IMPORTS } from './CoreImportsHelper.js';
7
4
  /**
8
5
  * @see https://github.com/tc39/proposal-regexp-unicode-property-escapes#other-examples
9
6
  */
10
- exports.identifierRegex = /^(?:[$_\p{ID_Start}])(?:[$\u200C\u200D\p{ID_Continue}])*$/u;
11
- const primitivesAndLibs = [...core_1.SCALAR_TYPES, 'bigint', 'Uint8Array', 'unknown', 'object', 'any'];
12
- class SourceFile {
7
+ export const identifierRegex = /^(?:[$_\p{ID_Start}])(?:[$\u200C\u200D\p{ID_Continue}])*$/u;
8
+ const primitivesAndLibs = [...SCALAR_TYPES, 'unknown', 'object', 'any'];
9
+ export class SourceFile {
13
10
  meta;
14
11
  namingStrategy;
15
12
  platform;
16
13
  options;
17
14
  coreImports = new Set();
15
+ decoratorImports = new Set();
18
16
  entityImports = new Set();
17
+ enumImports = new Map();
19
18
  constructor(meta, namingStrategy, platform, options) {
20
19
  this.meta = meta;
21
20
  this.namingStrategy = namingStrategy;
@@ -27,24 +26,24 @@ class SourceFile {
27
26
  if (this.meta.embeddable || this.meta.collection) {
28
27
  if (this.meta.embeddable) {
29
28
  const options = this.getEmbeddableDeclOptions();
30
- ret += `@${this.referenceCoreImport('Embeddable')}(${core_1.Utils.hasObjectKeys(options) ? this.serializeObject(options) : ''})\n`;
29
+ ret += `@${this.referenceDecoratorImport('Embeddable')}(${Utils.hasObjectKeys(options) ? this.serializeObject(options) : ''})\n`;
31
30
  }
32
31
  else {
33
32
  const options = this.getEntityDeclOptions();
34
- ret += `@${this.referenceCoreImport('Entity')}(${core_1.Utils.hasObjectKeys(options) ? this.serializeObject(options) : ''})\n`;
33
+ ret += `@${this.referenceDecoratorImport('Entity')}(${Utils.hasObjectKeys(options) ? this.serializeObject(options) : ''})\n`;
35
34
  }
36
35
  }
37
36
  for (const index of this.meta.indexes) {
38
37
  if (index.properties?.length === 1 && typeof this.meta.properties[index.properties[0]] !== 'undefined') {
39
38
  continue;
40
39
  }
41
- ret += `@${this.referenceCoreImport('Index')}(${this.serializeObject(this.getIndexOptions(index))})\n`;
40
+ ret += `@${this.referenceDecoratorImport('Index')}(${this.serializeObject(this.getIndexOptions(index))})\n`;
42
41
  }
43
42
  for (const index of this.meta.uniques) {
44
43
  if (index.properties?.length === 1 && typeof this.meta.properties[index.properties[0]] !== 'undefined') {
45
44
  continue;
46
45
  }
47
- ret += `@${this.referenceCoreImport('Unique')}(${this.serializeObject(this.getUniqueOptions(index))})\n`;
46
+ ret += `@${this.referenceDecoratorImport('Unique')}(${this.serializeObject(this.getUniqueOptions(index))})\n`;
48
47
  }
49
48
  let classHead = '';
50
49
  if (this.meta.className === this.options.customBaseEntityName) {
@@ -67,7 +66,10 @@ class SourceFile {
67
66
  classBody += definition;
68
67
  classBody += '\n';
69
68
  if (prop.enum) {
70
- enumDefinitions.push(this.getEnumClassDefinition(prop, 2));
69
+ const def = this.getEnumClassDefinition(prop, 2);
70
+ if (def.length) {
71
+ enumDefinitions.push(def);
72
+ }
71
73
  }
72
74
  if (prop.eager) {
73
75
  eagerProperties.push(prop);
@@ -101,11 +103,14 @@ class SourceFile {
101
103
  if (typeof index.name === 'string') {
102
104
  indexOpt.name = this.quote(index.name);
103
105
  }
104
- if (index.expression) {
106
+ if (typeof index.expression === 'string') {
105
107
  indexOpt.expression = this.quote(index.expression);
106
108
  }
109
+ else if (typeof index.expression === 'function') {
110
+ indexOpt.expression = `${index.expression}`.replace(')=>`', ') => `');
111
+ }
107
112
  if (isAtEntityLevel && index.properties) {
108
- indexOpt.properties = core_1.Utils.asArray(index.properties).map(prop => this.quote('' + prop));
113
+ indexOpt.properties = Utils.asArray(index.properties).map(prop => this.quote('' + prop));
109
114
  }
110
115
  return indexOpt;
111
116
  }
@@ -114,11 +119,14 @@ class SourceFile {
114
119
  if (typeof index.name === 'string') {
115
120
  uniqueOpt.name = this.quote(index.name);
116
121
  }
117
- if (index.expression) {
122
+ if (typeof index.expression === 'string') {
118
123
  uniqueOpt.expression = this.quote(index.expression);
119
124
  }
125
+ else if (typeof index.expression === 'function') {
126
+ uniqueOpt.expression = `${index.expression}`.replace(')=>`', ') => `');
127
+ }
120
128
  if (isAtEntityLevel && index.properties) {
121
- uniqueOpt.properties = core_1.Utils.asArray(index.properties).map(prop => this.quote('' + prop));
129
+ uniqueOpt.properties = Utils.asArray(index.properties).map(prop => this.quote('' + prop));
122
130
  }
123
131
  if (index.deferMode) {
124
132
  uniqueOpt.deferMode = `${this.referenceCoreImport('DeferMode')}.INITIALLY_${index.deferMode.toUpperCase()}`;
@@ -129,7 +137,7 @@ class SourceFile {
129
137
  const imports = new Set();
130
138
  if (this.coreImports.size > 0) {
131
139
  imports.add(`import { ${([...this.coreImports].sort().map(t => {
132
- let ret = CoreImportsHelper_1.POSSIBLE_TYPE_IMPORTS.includes(t) ? `type ${t}` : t;
140
+ let ret = POSSIBLE_TYPE_IMPORTS.includes(t) ? `type ${t}` : t;
133
141
  if (this.options.coreImportsPrefix) {
134
142
  const resolvedIdentifier = `${this.options.coreImportsPrefix}${t}`;
135
143
  ret += ` as ${resolvedIdentifier}`;
@@ -137,37 +145,61 @@ class SourceFile {
137
145
  return ret;
138
146
  }).join(', '))} } from '@mikro-orm/core';`);
139
147
  }
148
+ if (this.decoratorImports.size > 0) {
149
+ const type = this.options.decorators;
150
+ imports.add(`import { ${([...this.decoratorImports].sort().map(t => {
151
+ let ret = t;
152
+ if (this.options.coreImportsPrefix) {
153
+ const resolvedIdentifier = `${this.options.coreImportsPrefix}${t}`;
154
+ ret += ` as ${resolvedIdentifier}`;
155
+ }
156
+ return ret;
157
+ }).join(', '))} } from '@mikro-orm/decorators/${type}';`);
158
+ }
140
159
  const extension = this.options.esmImport ? '.js' : '';
141
- const { dir, base } = (0, node_path_1.parse)(`${this.options.path ?? '.'}/${this.getBaseName()}`);
142
- const basePath = (0, node_path_1.relative)(dir, this.options.path ?? '.') || '.';
160
+ const { dir, base } = parse(`${this.options.path ?? '.'}/${this.getBaseName()}`);
161
+ const basePath = relative(dir, this.options.path ?? '.') || '.';
143
162
  (this.options.extraImports?.(basePath, base) ?? []).forEach(v => this.entityImports.add(v));
144
163
  const entityImports = [...this.entityImports].filter(e => e !== this.meta.className);
145
- entityImports.sort().forEach(entity => {
164
+ const importMap = new Map();
165
+ for (const entity of entityImports) {
146
166
  const file = this.options.onImport?.(entity, basePath, extension, base) ?? {
147
167
  path: `${basePath}/${this.options.fileName(entity)}${extension}`,
148
168
  name: entity,
149
169
  };
150
170
  if (file.path === '') {
151
171
  if (file.name === '') {
152
- return;
172
+ continue;
153
173
  }
154
- imports.add(`import ${this.quote(file.name)};`);
155
- return;
174
+ importMap.set(file.path, `import ${this.quote(file.name)};`);
175
+ continue;
156
176
  }
157
177
  if (file.name === '') {
158
- imports.add(`import * as ${entity} from ${this.quote(file.path)};`);
159
- return;
178
+ importMap.set(file.path, `import * as ${entity} from ${this.quote(file.path)};`);
179
+ continue;
160
180
  }
161
181
  if (file.name === 'default') {
162
- imports.add(`import ${entity} from ${this.quote(file.path)};`);
163
- return;
182
+ importMap.set(file.path, `import ${entity} from ${this.quote(file.path)};`);
183
+ continue;
164
184
  }
165
185
  if (file.name === entity) {
166
- imports.add(`import { ${entity} } from ${this.quote(file.path)};`);
167
- return;
186
+ importMap.set(file.path, `import { ${entity} } from ${this.quote(file.path)};`);
187
+ continue;
168
188
  }
169
- imports.add(`import { ${exports.identifierRegex.test(file.name) ? file.name : this.quote(file.name)} as ${entity} } from ${this.quote(file.path)};`);
170
- });
189
+ importMap.set(file.path, `import { ${identifierRegex.test(file.name) ? file.name : this.quote(file.name)} as ${entity} } from ${this.quote(file.path)};`);
190
+ }
191
+ if (this.enumImports.size) {
192
+ for (const [name, exports] of this.enumImports.entries()) {
193
+ const file = this.options.onImport?.(name, basePath, extension, base) ?? {
194
+ path: `${basePath}/${this.options.fileName(name)}${extension}`,
195
+ name,
196
+ };
197
+ importMap.set(file.path, `import { ${exports.join(', ')} } from ${this.quote(file.path)};`);
198
+ }
199
+ }
200
+ for (const key of [...importMap.keys()].sort()) {
201
+ imports.add(importMap.get(key));
202
+ }
171
203
  return Array.from(imports.values()).join('\n');
172
204
  }
173
205
  getEntityClass(classBody) {
@@ -191,20 +223,21 @@ class SourceFile {
191
223
  }
192
224
  quote(val) {
193
225
  const backtick = val.startsWith(`'`) || val.includes('\n');
194
- /* istanbul ignore next */
226
+ /* v8 ignore next */
195
227
  return backtick ? `\`${val.replaceAll('`', '\\``')}\`` : `'${val.replaceAll(`'`, `\\'`)}'`;
196
228
  }
197
229
  getPropertyDefinition(prop, padLeft) {
198
230
  const padding = ' '.repeat(padLeft);
199
- const propName = exports.identifierRegex.test(prop.name) ? prop.name : this.quote(prop.name);
231
+ const propName = identifierRegex.test(prop.name) ? prop.name : this.quote(prop.name);
232
+ const enumMode = this.options.enumMode;
200
233
  let hiddenType = '';
201
234
  if (prop.hidden) {
202
235
  hiddenType += ` & ${this.referenceCoreImport('Hidden')}`;
203
236
  }
204
- if ([core_1.ReferenceKind.ONE_TO_MANY, core_1.ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
237
+ if ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
205
238
  return `${padding}${propName}${hiddenType ? `: ${this.referenceCoreImport('Collection')}<${prop.type}>${hiddenType}` : ''} = new ${this.referenceCoreImport('Collection')}<${prop.type}>(this);\n`;
206
239
  }
207
- const isScalar = typeof prop.kind === 'undefined' || prop.kind === core_1.ReferenceKind.SCALAR;
240
+ const isScalar = typeof prop.kind === 'undefined' || prop.kind === ReferenceKind.SCALAR;
208
241
  let breakdownOfIType;
209
242
  const propType = prop.mapToPk
210
243
  ? (() => {
@@ -214,7 +247,11 @@ class SourceFile {
214
247
  : (() => {
215
248
  if (isScalar) {
216
249
  if (prop.enum) {
217
- return prop.runtimeType;
250
+ const method = enumMode === 'ts-enum' ? 'getEnumClassName' : 'getEnumTypeName';
251
+ if (prop.nativeEnumName) {
252
+ return this.namingStrategy[method](prop.nativeEnumName, undefined, this.meta.schema);
253
+ }
254
+ return this.namingStrategy[method](prop.fieldNames[0], this.meta.collection, this.meta.schema);
218
255
  }
219
256
  breakdownOfIType = this.breakdownOfIType(prop);
220
257
  if (typeof breakdownOfIType !== 'undefined') {
@@ -231,7 +268,7 @@ class SourceFile {
231
268
  const useDefault = hasUsableNullDefault || (!(typeof prop.default === 'undefined' || prop.default === null) && propType !== 'unknown' && typeof breakdownOfIType === 'undefined');
232
269
  const optional = (prop.nullable && (this.options.forceUndefined || prop.optional)) ? '?' : (useDefault ? '' : '!');
233
270
  let ret = `${propName}${optional}: `;
234
- const isArray = prop.array && (prop.kind === core_1.ReferenceKind.EMBEDDED || prop.enum);
271
+ const isArray = prop.array && (prop.kind === ReferenceKind.EMBEDDED || prop.enum);
235
272
  const complexType = isArray ? `${propType}[]` : propType;
236
273
  let wrappedType = prop.ref
237
274
  ? `${this.referenceCoreImport('Ref')}<${complexType}${(isScalar && prop.nullable && !this.options.forceUndefined) ? ' | null' : ''}>`
@@ -249,8 +286,14 @@ class SourceFile {
249
286
  return `${padding}${ret};\n`;
250
287
  }
251
288
  if (prop.enum && typeof prop.default === 'string') {
289
+ if (enumMode === 'union-type') {
290
+ return `${padding}${ret} = ${this.quote(prop.default)};\n`;
291
+ }
292
+ const enumClassName = prop.nativeEnumName
293
+ ? this.namingStrategy.getEnumClassName(prop.nativeEnumName, undefined, this.meta.schema)
294
+ : this.namingStrategy.getEnumClassName(prop.fieldNames[0], this.meta.collection, this.meta.schema);
252
295
  const enumVal = this.namingStrategy.enumValueToEnumProperty(prop.default, prop.fieldNames[0], this.meta.collection, this.meta.schema);
253
- return `${padding}${ret} = ${propType}${exports.identifierRegex.test(enumVal) ? `.${enumVal}` : `[${this.quote(enumVal)}]`};\n`;
296
+ return `${padding}${ret} = ${enumClassName}${identifierRegex.test(enumVal) ? `.${enumVal}` : `[${this.quote(enumVal)}]`};\n`;
254
297
  }
255
298
  if (prop.fieldNames?.length > 1) {
256
299
  // TODO: Composite FKs with default values require additions to default/defaultRaw that are not yet supported.
@@ -266,19 +309,55 @@ class SourceFile {
266
309
  return `${padding}${ret} = ${prop.ref ? this.referenceCoreImport('ref') : this.referenceCoreImport('rel')}(${propType}, ${defaultVal});\n`;
267
310
  }
268
311
  getEnumClassDefinition(prop, padLeft) {
312
+ const enumMode = this.options.enumMode;
313
+ if (prop.nativeEnumName) {
314
+ const imports = [];
315
+ if (enumMode !== 'union-type') {
316
+ imports.push(prop.runtimeType);
317
+ }
318
+ if (!this.options.inferEntityType && enumMode !== 'ts-enum') {
319
+ const enumTypeName = this.namingStrategy.getEnumTypeName(prop.nativeEnumName, undefined, this.meta.schema);
320
+ imports.push(enumTypeName);
321
+ }
322
+ this.enumImports.set(prop.runtimeType, imports);
323
+ return '';
324
+ }
269
325
  const enumClassName = this.namingStrategy.getEnumClassName(prop.fieldNames[0], this.meta.collection, this.meta.schema);
326
+ const enumTypeName = this.namingStrategy.getEnumTypeName(prop.fieldNames[0], this.meta.collection, this.meta.schema);
270
327
  const padding = ' '.repeat(padLeft);
271
- let ret = `export enum ${enumClassName} {\n`;
272
328
  const enumValues = prop.items;
329
+ if (enumMode === 'union-type') {
330
+ return `export type ${enumTypeName} = ${enumValues.map(item => this.quote(item)).join(' | ')};\n`;
331
+ }
332
+ let ret = '';
333
+ if (enumMode === 'dictionary') {
334
+ ret += `export const ${enumClassName} = {\n`;
335
+ }
336
+ else {
337
+ ret += `export enum ${enumClassName} {\n`;
338
+ }
273
339
  for (const enumValue of enumValues) {
274
340
  const enumName = this.namingStrategy.enumValueToEnumProperty(enumValue, prop.fieldNames[0], this.meta.collection, this.meta.schema);
275
- ret += `${padding}${exports.identifierRegex.test(enumName) ? enumName : this.quote(enumName)} = ${this.quote(enumValue)},\n`;
341
+ if (enumMode === 'dictionary') {
342
+ ret += `${padding}${identifierRegex.test(enumName) ? enumName : this.quote(enumName)}: ${this.quote(enumValue)},\n`;
343
+ }
344
+ else {
345
+ ret += `${padding}${identifierRegex.test(enumName) ? enumName : this.quote(enumName)} = ${this.quote(enumValue)},\n`;
346
+ }
347
+ }
348
+ if (enumMode === 'dictionary') {
349
+ ret += '} as const;\n';
350
+ }
351
+ else {
352
+ ret += '}\n';
353
+ }
354
+ if (enumMode === 'dictionary') {
355
+ ret += `\nexport type ${enumTypeName} = (typeof ${enumClassName})[keyof typeof ${enumClassName}];\n`;
276
356
  }
277
- ret += '}\n';
278
357
  return ret;
279
358
  }
280
359
  serializeObject(options, wordwrap, spaces, level = 0) {
281
- if (typeof wordwrap === 'number' && !Object.hasOwn(options, core_1.Config)) {
360
+ if (typeof wordwrap === 'number' && !Object.hasOwn(options, Config)) {
282
361
  const res = this.serializeObject(options, undefined, undefined, level);
283
362
  if (res.length <= wordwrap) {
284
363
  return res;
@@ -292,7 +371,7 @@ class SourceFile {
292
371
  }
293
372
  const entries = Object.entries(options);
294
373
  return `{${doIndent ? `\n${' '.repeat(spaces)}` : ' '}${entries.map(([opt, val]) => {
295
- const key = exports.identifierRegex.test(opt) ? opt : this.quote(opt);
374
+ const key = identifierRegex.test(opt) ? opt : this.quote(opt);
296
375
  return `${doIndent ? ' '.repeat((level * 2) + (spaces + 2)) : ''}${key}: ${this.serializeValue(val, typeof nextWordwrap === 'number' ? nextWordwrap - key.length - 2 /* ': '.length*/ : undefined, doIndent ? spaces : undefined, level + 1)}`;
297
376
  }).join(sep)}${doIndent ? `${entries.length > 0 ? ',\n' : ''}${' '.repeat(spaces + (level * 2))}` : ' '}}`;
298
377
  }
@@ -314,7 +393,7 @@ class SourceFile {
314
393
  options.expression = this.quote(this.meta.expression);
315
394
  }
316
395
  else if (typeof this.meta.expression === 'function') {
317
- options.expression = `${this.meta.expression}`;
396
+ options.expression = this.meta.expression.toString();
318
397
  }
319
398
  if (this.meta.repositoryClass) {
320
399
  this.entityImports.add(this.meta.repositoryClass);
@@ -354,17 +433,17 @@ class SourceFile {
354
433
  getPropertyDecorator(prop, padLeft) {
355
434
  const padding = ' '.repeat(padLeft);
356
435
  const options = {};
357
- let decorator = `@${this.referenceCoreImport(this.getDecoratorType(prop))}`;
358
- if (prop.kind === core_1.ReferenceKind.MANY_TO_MANY) {
436
+ let decorator = `@${this.referenceDecoratorImport(this.getDecoratorType(prop))}`;
437
+ if (prop.kind === ReferenceKind.MANY_TO_MANY) {
359
438
  this.getManyToManyDecoratorOptions(options, prop);
360
439
  }
361
- else if (prop.kind === core_1.ReferenceKind.ONE_TO_MANY) {
440
+ else if (prop.kind === ReferenceKind.ONE_TO_MANY) {
362
441
  this.getOneToManyDecoratorOptions(options, prop);
363
442
  }
364
- else if (prop.kind === core_1.ReferenceKind.SCALAR || typeof prop.kind === 'undefined') {
443
+ else if (prop.kind === ReferenceKind.SCALAR || typeof prop.kind === 'undefined') {
365
444
  this.getScalarPropertyDecoratorOptions(options, prop);
366
445
  }
367
- else if (prop.kind === core_1.ReferenceKind.EMBEDDED) {
446
+ else if (prop.kind === ReferenceKind.EMBEDDED) {
368
447
  this.getEmbeddedPropertyDeclarationOptions(options, prop);
369
448
  }
370
449
  else {
@@ -375,9 +454,9 @@ class SourceFile {
375
454
  decorator = [...indexes.sort(), decorator].map(d => padding + d).join('\n');
376
455
  const decoratorArgs = [];
377
456
  if (prop.formula) {
378
- decoratorArgs.push(`${prop.formula}`);
457
+ decoratorArgs.push(prop.formula.toString());
379
458
  }
380
- if (core_1.Utils.hasObjectKeys(options)) {
459
+ if (Utils.hasObjectKeys(options)) {
381
460
  decoratorArgs.push(`${this.serializeObject(options)}`);
382
461
  }
383
462
  return `${decorator}(${decoratorArgs.join(', ')})\n`;
@@ -392,7 +471,7 @@ class SourceFile {
392
471
  options[type] = (propType === true || defaultName === propType) ? 'true' : this.quote(propType);
393
472
  const expected = {
394
473
  index: this.platform.indexForeignKeys(),
395
- unique: prop.kind === core_1.ReferenceKind.ONE_TO_ONE,
474
+ unique: prop.kind === ReferenceKind.ONE_TO_ONE,
396
475
  };
397
476
  if (expected[type] && options[type] === 'true') {
398
477
  delete options[type];
@@ -404,26 +483,26 @@ class SourceFile {
404
483
  let propIndexIsNonTrivialIndex = false;
405
484
  const nonTrivialIndexes = this.meta.indexes.filter(i => i.properties?.length === 1 && i.properties[0] === prop.name);
406
485
  for (const i of nonTrivialIndexes) {
407
- ret.push(`@${this.referenceCoreImport('Index')}(${this.serializeObject(this.getIndexOptions(i, false))})`);
486
+ ret.push(`@${this.referenceDecoratorImport('Index')}(${this.serializeObject(this.getIndexOptions(i, false))})`);
408
487
  if (prop.index === i.name) {
409
488
  propIndexIsNonTrivialIndex = true;
410
489
  delete options.index;
411
490
  }
412
491
  }
413
492
  if (prop.index && !options.index && !propIndexIsNonTrivialIndex) {
414
- ret.push(`@${this.referenceCoreImport('Index')}(${typeof prop.index === 'string' ? `{ name: ${this.quote(prop.index)} }` : ''})`);
493
+ ret.push(`@${this.referenceDecoratorImport('Index')}(${typeof prop.index === 'string' ? `{ name: ${this.quote(prop.index)} }` : ''})`);
415
494
  }
416
495
  let propIndexIsNonTrivialUnique = false;
417
496
  const nonTrivialUnique = this.meta.uniques.filter(i => i.properties?.length === 1 && i.properties[0] === prop.name);
418
497
  for (const i of nonTrivialUnique) {
419
- ret.push(`@${this.referenceCoreImport('Unique')}(${this.serializeObject(this.getUniqueOptions(i, false))})`);
498
+ ret.push(`@${this.referenceDecoratorImport('Unique')}(${this.serializeObject(this.getUniqueOptions(i, false))})`);
420
499
  if (prop.unique === i.name) {
421
500
  propIndexIsNonTrivialUnique = true;
422
501
  delete options.unique;
423
502
  }
424
503
  }
425
504
  if (prop.unique && !options.unique && !propIndexIsNonTrivialUnique) {
426
- ret.push(`@${this.referenceCoreImport('Unique')}(${typeof prop.unique === 'string' ? `{ name: ${this.quote(prop.unique)} }` : ''})`);
505
+ ret.push(`@${this.referenceDecoratorImport('Unique')}(${typeof prop.unique === 'string' ? `{ name: ${this.quote(prop.unique)} }` : ''})`);
427
506
  }
428
507
  return ret;
429
508
  }
@@ -431,10 +510,10 @@ class SourceFile {
431
510
  if (!prop.mappedBy && (prop.nullable || prop.customTypes?.[0]?.prop?.nullable)) {
432
511
  options.nullable = true;
433
512
  }
434
- if (prop.primary && (prop.enum || !(typeof prop.kind === 'undefined' || prop.kind === core_1.ReferenceKind.SCALAR))) {
513
+ if (prop.primary && (prop.enum || !(typeof prop.kind === 'undefined' || prop.kind === ReferenceKind.SCALAR))) {
435
514
  options.primary = true;
436
515
  }
437
- ['persist', 'hydrate', 'trackChanges']
516
+ ['persist', 'hydrate']
438
517
  .filter(key => prop[key] === false)
439
518
  .forEach(key => options[key] = false);
440
519
  ['onCreate', 'onUpdate', 'serializer']
@@ -449,7 +528,7 @@ class SourceFile {
449
528
  ['hidden', 'version', 'concurrencyCheck', 'eager', 'lazy', 'orphanRemoval']
450
529
  .filter(key => prop[key])
451
530
  .forEach(key => options[key] = true);
452
- if (prop.cascade && (prop.cascade.length !== 1 || prop.cascade[0] !== core_1.Cascade.PERSIST)) {
531
+ if (prop.cascade && (prop.cascade.length !== 1 || prop.cascade[0] !== Cascade.PERSIST)) {
453
532
  options.cascade = `[${prop.cascade.map(value => `${this.referenceCoreImport('Cascade')}.${value.toUpperCase()}`).join(', ')}]`;
454
533
  }
455
534
  if (typeof prop.comment === 'string') {
@@ -461,7 +540,7 @@ class SourceFile {
461
540
  prop.defaultRaw !== (typeof prop.default === 'string' ? this.quote(prop.default) : `${prop.default}`)) {
462
541
  options.defaultRaw = `\`${prop.defaultRaw}\``;
463
542
  }
464
- else if (!(typeof prop.default === 'undefined' || prop.default === null) && (prop.ref || (!prop.enum && (typeof prop.kind === 'undefined' || prop.kind === core_1.ReferenceKind.SCALAR) && (prop.type === 'unknown' || typeof this.breakdownOfIType(prop) !== 'undefined')))) {
543
+ else if (!(typeof prop.default === 'undefined' || prop.default === null) && (prop.ref || (!prop.enum && (typeof prop.kind === 'undefined' || prop.kind === ReferenceKind.SCALAR) && (prop.type === 'unknown' || typeof this.breakdownOfIType(prop) !== 'undefined')))) {
465
544
  options.default = typeof prop.default === 'string' ? this.quote(prop.default) : prop.default;
466
545
  }
467
546
  }
@@ -482,7 +561,7 @@ class SourceFile {
482
561
  return this.propTypeBreakdowns.get(prop);
483
562
  }
484
563
  const mappedDeclaredType = this.platform.getMappedType(prop.type);
485
- const mappedRawType = (prop.customTypes?.[0] ?? ((prop.type !== 'unknown' && mappedDeclaredType instanceof core_1.UnknownType)
564
+ const mappedRawType = (prop.customTypes?.[0] ?? ((prop.type !== 'unknown' && mappedDeclaredType instanceof UnknownType)
486
565
  ? this.platform.getMappedType(prop.columnTypes[0])
487
566
  : mappedDeclaredType));
488
567
  const rawType = mappedRawType.runtimeType;
@@ -533,12 +612,23 @@ class SourceFile {
533
612
  this.propTypeBreakdowns.set(prop, r);
534
613
  return r;
535
614
  }
536
- getScalarPropertyDecoratorOptions(options, prop) {
615
+ getScalarPropertyDecoratorOptions(options, prop, quote = true) {
537
616
  if (prop.fieldNames[0] !== this.namingStrategy.propertyToColumnName(prop.name)) {
538
617
  options.fieldName = this.quote(prop.fieldNames[0]);
539
618
  }
540
619
  if (prop.enum) {
541
- options.items = `() => ${prop.runtimeType}`;
620
+ if (this.options.enumMode === 'union-type') {
621
+ options.items = `[${prop.items.map(item => this.quote(item)).join(', ')}]`;
622
+ }
623
+ else if (prop.nativeEnumName) {
624
+ const enumClassName = this.namingStrategy.getEnumClassName(prop.nativeEnumName, undefined, this.meta.schema);
625
+ options.items = `() => ${enumClassName}`;
626
+ options.nativeEnumName = this.quote(prop.nativeEnumName);
627
+ }
628
+ else {
629
+ const enumClassName = this.namingStrategy.getEnumClassName(prop.fieldNames[0], this.meta.collection, this.meta.schema);
630
+ options.items = `() => ${enumClassName}`;
631
+ }
542
632
  }
543
633
  // For enum properties, we don't need a column type
544
634
  // or the property length or other information in the decorator.
@@ -551,7 +641,7 @@ class SourceFile {
551
641
  ? mappedColumnType
552
642
  : this.platform.getMappedType(prop.runtimeType);
553
643
  const mappedDeclaredType = this.platform.getMappedType(prop.type);
554
- const isTypeStringMissingFromMap = prop.type !== 'unknown' && mappedDeclaredType instanceof core_1.UnknownType;
644
+ const isTypeStringMissingFromMap = prop.type !== 'unknown' && mappedDeclaredType instanceof UnknownType;
555
645
  if (isTypeStringMissingFromMap) {
556
646
  this.entityImports.add(prop.type);
557
647
  options.type = prop.type;
@@ -567,14 +657,14 @@ class SourceFile {
567
657
  return ((useDefault && !hasUsableNullDefault) || (prop.optional && !prop.nullable));
568
658
  })() // also when there is the "| Opt" type modifier (because reflect-metadata can't extract the base)
569
659
  ) {
570
- options.type = this.quote(prop.type);
660
+ options.type = quote ? this.quote(prop.type) : prop.type;
571
661
  }
572
662
  }
573
663
  const columnTypeFromMappedRuntimeType = mappedRuntimeType.getColumnType({ ...prop, autoincrement: false }, this.platform);
574
664
  const columnTypeFromMappedColumnType = mappedColumnType.getColumnType({ ...prop, autoincrement: false }, this.platform);
575
665
  const columnTypeFromMappedDeclaredType = mappedDeclaredType.getColumnType({ ...prop, autoincrement: false }, this.platform);
576
666
  const needsExplicitColumnType = () => {
577
- if (isTypeStringMissingFromMap || [mappedRuntimeType, mappedColumnType, columnTypeFromMappedDeclaredType].some(t => t instanceof core_1.UnknownType)) {
667
+ if (isTypeStringMissingFromMap || [mappedRuntimeType, mappedColumnType, columnTypeFromMappedDeclaredType].some(t => t instanceof UnknownType)) {
578
668
  return true;
579
669
  }
580
670
  if (this.platform.normalizeColumnType(prop.columnTypes[0], prop) !== this.platform.normalizeColumnType(columnTypeFromMappedColumnType, prop)) {
@@ -594,8 +684,8 @@ class SourceFile {
594
684
  assign('length');
595
685
  }
596
686
  // those are already included in the `columnType` in most cases, and when that option is present, they would be ignored anyway
597
- /* istanbul ignore next */
598
- if (mappedColumnType instanceof core_1.DecimalType && !options.columnType) {
687
+ /* v8 ignore next */
688
+ if (mappedColumnType instanceof DecimalType && !options.columnType) {
599
689
  assign('precision');
600
690
  assign('scale');
601
691
  }
@@ -621,6 +711,9 @@ class SourceFile {
621
711
  getManyToManyDecoratorOptions(options, prop) {
622
712
  this.entityImports.add(prop.type);
623
713
  options.entity = `() => ${prop.type}`;
714
+ if (prop.orderBy) {
715
+ options.orderBy = inspect(prop.orderBy);
716
+ }
624
717
  if (prop.mappedBy) {
625
718
  options.mappedBy = this.quote(prop.mappedBy);
626
719
  return;
@@ -655,6 +748,9 @@ class SourceFile {
655
748
  this.entityImports.add(prop.type);
656
749
  options.entity = `() => ${prop.type}`;
657
750
  options.mappedBy = this.quote(prop.mappedBy);
751
+ if (prop.orderBy) {
752
+ options.orderBy = inspect(prop.orderBy);
753
+ }
658
754
  }
659
755
  getEmbeddedPropertyDeclarationOptions(options, prop) {
660
756
  this.entityImports.add(prop.type);
@@ -662,7 +758,7 @@ class SourceFile {
662
758
  if (prop.array) {
663
759
  options.array = true;
664
760
  }
665
- if (prop.object) {
761
+ if (prop.object && !prop.array) {
666
762
  options.object = true;
667
763
  }
668
764
  if (prop.prefix === false || typeof prop.prefix === 'string') {
@@ -713,19 +809,19 @@ class SourceFile {
713
809
  }
714
810
  }
715
811
  getDecoratorType(prop) {
716
- if (prop.kind === core_1.ReferenceKind.ONE_TO_ONE) {
812
+ if (prop.kind === ReferenceKind.ONE_TO_ONE) {
717
813
  return 'OneToOne';
718
814
  }
719
- if (prop.kind === core_1.ReferenceKind.MANY_TO_ONE) {
815
+ if (prop.kind === ReferenceKind.MANY_TO_ONE) {
720
816
  return 'ManyToOne';
721
817
  }
722
- if (prop.kind === core_1.ReferenceKind.ONE_TO_MANY) {
818
+ if (prop.kind === ReferenceKind.ONE_TO_MANY) {
723
819
  return 'OneToMany';
724
820
  }
725
- if (prop.kind === core_1.ReferenceKind.MANY_TO_MANY) {
821
+ if (prop.kind === ReferenceKind.MANY_TO_MANY) {
726
822
  return 'ManyToMany';
727
823
  }
728
- if (prop.kind === core_1.ReferenceKind.EMBEDDED) {
824
+ if (prop.kind === ReferenceKind.EMBEDDED) {
729
825
  return 'Embedded';
730
826
  }
731
827
  if (prop.enum) {
@@ -745,5 +841,10 @@ class SourceFile {
745
841
  ? `${this.options.coreImportsPrefix}${identifier}`
746
842
  : identifier;
747
843
  }
844
+ referenceDecoratorImport(identifier) {
845
+ this.decoratorImports.add(identifier);
846
+ return this.options.coreImportsPrefix
847
+ ? `${this.options.coreImportsPrefix}${identifier}`
848
+ : identifier;
849
+ }
748
850
  }
749
- exports.SourceFile = SourceFile;
package/index.d.ts CHANGED
@@ -2,4 +2,4 @@
2
2
  * @packageDocumentation
3
3
  * @module entity-generator
4
4
  */
5
- export * from './EntityGenerator';
5
+ export * from './EntityGenerator.js';
package/index.js CHANGED
@@ -1,21 +1,5 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
1
  /**
18
2
  * @packageDocumentation
19
3
  * @module entity-generator
20
4
  */
21
- __exportStar(require("./EntityGenerator"), exports);
5
+ export * from './EntityGenerator.js';
package/package.json CHANGED
@@ -1,19 +1,11 @@
1
1
  {
2
2
  "name": "@mikro-orm/entity-generator",
3
- "version": "7.0.0-dev.1",
3
+ "type": "module",
4
+ "version": "7.0.0-dev.100",
4
5
  "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
- "main": "index.js",
6
- "module": "index.mjs",
7
- "typings": "index.d.ts",
8
6
  "exports": {
9
7
  "./package.json": "./package.json",
10
- ".": {
11
- "import": {
12
- "types": "./index.d.ts",
13
- "default": "./index.mjs"
14
- },
15
- "require": "./index.js"
16
- }
8
+ ".": "./index.js"
17
9
  },
18
10
  "repository": {
19
11
  "type": "git",
@@ -46,10 +38,10 @@
46
38
  },
47
39
  "homepage": "https://mikro-orm.io",
48
40
  "engines": {
49
- "node": ">= 22.11.0"
41
+ "node": ">= 22.17.0"
50
42
  },
51
43
  "scripts": {
52
- "build": "yarn clean && yarn compile && yarn copy && yarn run -T gen-esm-wrapper index.js index.mjs",
44
+ "build": "yarn clean && yarn compile && yarn copy",
53
45
  "clean": "yarn run -T rimraf ./dist",
54
46
  "compile": "yarn run -T tsc -p tsconfig.build.json",
55
47
  "copy": "node ../../scripts/copy.mjs"
@@ -58,13 +50,12 @@
58
50
  "access": "public"
59
51
  },
60
52
  "dependencies": {
61
- "@mikro-orm/knex": "7.0.0-dev.1",
62
- "fs-extra": "11.3.0"
53
+ "@mikro-orm/sql": "7.0.0-dev.100"
63
54
  },
64
55
  "devDependencies": {
65
- "@mikro-orm/core": "^6.4.5"
56
+ "@mikro-orm/core": "^6.6.2"
66
57
  },
67
58
  "peerDependencies": {
68
- "@mikro-orm/core": "7.0.0-dev.1"
59
+ "@mikro-orm/core": "7.0.0-dev.100"
69
60
  }
70
61
  }
package/index.mjs DELETED
@@ -1,4 +0,0 @@
1
- import mod from "./index.js";
2
-
3
- export default mod;
4
- export const EntityGenerator = mod.EntityGenerator;