@mikro-orm/entity-generator 6.3.5-dev.2 → 6.3.5-dev.21

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/README.md CHANGED
@@ -143,7 +143,7 @@ There is also auto-generated [CHANGELOG.md](CHANGELOG.md) file based on commit m
143
143
  - [Using `QueryBuilder`](https://mikro-orm.io/docs/query-builder)
144
144
  - [Preloading Deeply Nested Structures via populate](https://mikro-orm.io/docs/nested-populate)
145
145
  - [Property Validation](https://mikro-orm.io/docs/property-validation)
146
- - [Lifecycle Hooks](https://mikro-orm.io/docs/lifecycle-hooks)
146
+ - [Lifecycle Hooks](https://mikro-orm.io/docs/events#hooks)
147
147
  - [Vanilla JS Support](https://mikro-orm.io/docs/usage-with-js)
148
148
  - [Schema Generator](https://mikro-orm.io/docs/schema-generator)
149
149
  - [Entity Generator](https://mikro-orm.io/docs/entity-generator)
@@ -163,6 +163,7 @@ You can find example integrations for some popular frameworks in the [`mikro-orm
163
163
  - [NextJS + MySQL](https://github.com/jonahallibone/mikro-orm-nextjs)
164
164
  - [Accounts.js REST and GraphQL authentication + SQLite](https://github.com/darkbasic/mikro-orm-accounts-example)
165
165
  - [Nest + Shopify + PostgreSQL + GraphQL](https://github.com/Cloudshelf/Shopify_CSConnector)
166
+ - [Elysia.js + libSQL + Bun](https://github.com/mikro-orm/elysia-bun-example-app)
166
167
 
167
168
  ### JavaScript Examples
168
169
 
package/SourceFile.d.ts CHANGED
@@ -12,8 +12,8 @@ export declare class SourceFile {
12
12
  protected readonly entityImports: Set<string>;
13
13
  constructor(meta: EntityMetadata, namingStrategy: NamingStrategy, platform: Platform, options: GenerateOptions);
14
14
  generate(): string;
15
- protected getIndexOptions(index: EntityMetadata['indexes'][number]): IndexOptions<Dictionary>;
16
- protected getUniqueOptions(index: EntityMetadata['uniques'][number]): UniqueOptions<Dictionary>;
15
+ protected getIndexOptions(index: EntityMetadata['indexes'][number], isAtEntityLevel?: boolean): IndexOptions<Dictionary>;
16
+ protected getUniqueOptions(index: EntityMetadata['uniques'][number], isAtEntityLevel?: boolean): UniqueOptions<Dictionary>;
17
17
  protected generateImports(): string;
18
18
  protected getEntityClass(classBody: string): string;
19
19
  getBaseName(extension?: string): string;
@@ -28,6 +28,8 @@ export declare class SourceFile {
28
28
  private getPropertyDecorator;
29
29
  protected getPropertyIndexes(prop: EntityProperty, options: Dictionary): string[];
30
30
  protected getCommonDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
31
+ private propTypeBreakdowns;
32
+ private breakdownOfIType;
31
33
  protected getScalarPropertyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
32
34
  protected getManyToManyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
33
35
  protected getOneToManyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
package/SourceFile.js CHANGED
@@ -34,12 +34,18 @@ class SourceFile {
34
34
  ret += `@${this.referenceCoreImport('Entity')}(${core_1.Utils.hasObjectKeys(options) ? this.serializeObject(options) : ''})\n`;
35
35
  }
36
36
  }
37
- this.meta.indexes.forEach(index => {
37
+ for (const index of this.meta.indexes) {
38
+ if (index.properties?.length === 1 && typeof this.meta.properties[index.properties[0]] !== 'undefined') {
39
+ continue;
40
+ }
38
41
  ret += `@${this.referenceCoreImport('Index')}(${this.serializeObject(this.getIndexOptions(index))})\n`;
39
- });
40
- this.meta.uniques.forEach(index => {
42
+ }
43
+ for (const index of this.meta.uniques) {
44
+ if (index.properties?.length === 1 && typeof this.meta.properties[index.properties[0]] !== 'undefined') {
45
+ continue;
46
+ }
41
47
  ret += `@${this.referenceCoreImport('Unique')}(${this.serializeObject(this.getUniqueOptions(index))})\n`;
42
- });
48
+ }
43
49
  let classHead = '';
44
50
  if (this.meta.className === this.options.customBaseEntityName) {
45
51
  const defineConfigTypeSettings = {};
@@ -90,7 +96,7 @@ class SourceFile {
90
96
  }
91
97
  return ret;
92
98
  }
93
- getIndexOptions(index) {
99
+ getIndexOptions(index, isAtEntityLevel = true) {
94
100
  const indexOpt = {};
95
101
  if (typeof index.name === 'string') {
96
102
  indexOpt.name = this.quote(index.name);
@@ -98,12 +104,12 @@ class SourceFile {
98
104
  if (index.expression) {
99
105
  indexOpt.expression = this.quote(index.expression);
100
106
  }
101
- if (index.properties) {
107
+ if (isAtEntityLevel && index.properties) {
102
108
  indexOpt.properties = core_1.Utils.asArray(index.properties).map(prop => this.quote('' + prop));
103
109
  }
104
110
  return indexOpt;
105
111
  }
106
- getUniqueOptions(index) {
112
+ getUniqueOptions(index, isAtEntityLevel = true) {
107
113
  const uniqueOpt = {};
108
114
  if (typeof index.name === 'string') {
109
115
  uniqueOpt.name = this.quote(index.name);
@@ -111,9 +117,12 @@ class SourceFile {
111
117
  if (index.expression) {
112
118
  uniqueOpt.expression = this.quote(index.expression);
113
119
  }
114
- if (index.properties) {
120
+ if (isAtEntityLevel && index.properties) {
115
121
  uniqueOpt.properties = core_1.Utils.asArray(index.properties).map(prop => this.quote('' + prop));
116
122
  }
123
+ if (index.deferMode) {
124
+ uniqueOpt.deferMode = `${this.referenceCoreImport('DeferMode')}.INITIALLY_${index.deferMode.toUpperCase()}`;
125
+ }
117
126
  return uniqueOpt;
118
127
  }
119
128
  generateImports() {
@@ -206,31 +215,16 @@ class SourceFile {
206
215
  if (prop.enum) {
207
216
  return prop.runtimeType;
208
217
  }
209
- const mappedDeclaredType = this.platform.getMappedType(prop.type);
210
- const mappedRawType = (prop.customTypes?.[0] ?? ((prop.type !== 'unknown' && mappedDeclaredType instanceof core_1.UnknownType)
211
- ? this.platform.getMappedType(prop.columnTypes[0])
212
- : mappedDeclaredType));
213
- const rawType = mappedRawType.runtimeType;
214
- const serializedType = (prop.customType ?? mappedRawType).runtimeType;
215
- // Add non-lib imports where needed.
216
- for (const typeSpec of [prop.runtimeType, rawType, serializedType]) {
217
- const simplePropType = typeSpec.replace(/\[]+$/, '');
218
- if (!primitivesAndLibs.includes(simplePropType)) {
219
- this.entityImports.add(simplePropType);
220
- }
221
- }
222
- if (prop.runtimeType !== rawType || rawType !== serializedType) {
218
+ const breakdownOfIType = this.breakdownOfIType(prop);
219
+ if (typeof breakdownOfIType !== 'undefined') {
223
220
  hasITypeWrapper = true;
224
- if (rawType !== serializedType) {
225
- return `${this.referenceCoreImport('IType')}<${prop.runtimeType}, ${rawType}, ${serializedType}>`;
226
- }
227
- return `${this.referenceCoreImport('IType')}<${prop.runtimeType}, ${rawType}>`;
221
+ return `${this.referenceCoreImport('IType')}<${breakdownOfIType.join(', ')}>`;
228
222
  }
229
223
  return prop.runtimeType;
230
224
  }
231
225
  return prop.type;
232
226
  })();
233
- const useDefault = prop.default != null;
227
+ const useDefault = prop.default != null && (propType !== 'unknown');
234
228
  const optional = prop.nullable ? '?' : (useDefault ? '' : '!');
235
229
  let ret = `${propName}${optional}: ${prop.ref ? `${this.referenceCoreImport('Ref')}<${propType}>` : `${(this.options.esmImport && !isScalar) ? `${this.referenceCoreImport('Rel')}<${propType}>` : propType}`}`;
236
230
  if (prop.array && (prop.kind === core_1.ReferenceKind.EMBEDDED || prop.enum)) {
@@ -240,7 +234,7 @@ class SourceFile {
240
234
  if (useDefault || (prop.optional && !prop.nullable)) {
241
235
  ret += ` & ${this.referenceCoreImport('Opt')}`;
242
236
  }
243
- if (!useDefault || hasITypeWrapper) {
237
+ if (!useDefault || hasITypeWrapper || prop.type === 'unknown') {
244
238
  return `${padding}${ret};\n`;
245
239
  }
246
240
  if (prop.enum && typeof prop.default === 'string') {
@@ -375,16 +369,6 @@ class SourceFile {
375
369
  return `${decorator}(${decoratorArgs.join(', ')})\n`;
376
370
  }
377
371
  getPropertyIndexes(prop, options) {
378
- if (prop.kind === core_1.ReferenceKind.SCALAR) {
379
- const ret = [];
380
- if (prop.index) {
381
- ret.push(`@${this.referenceCoreImport('Index')}(${typeof prop.index === 'string' ? `{ name: ${this.quote(prop.index)} }` : ''})`);
382
- }
383
- if (prop.unique) {
384
- ret.push(`@${this.referenceCoreImport('Unique')}(${typeof prop.unique === 'string' ? `{ name: ${this.quote(prop.unique)} }` : ''})`);
385
- }
386
- return ret;
387
- }
388
372
  const processIndex = (type) => {
389
373
  const propType = prop[type];
390
374
  if (!propType) {
@@ -402,7 +386,32 @@ class SourceFile {
402
386
  };
403
387
  processIndex('index');
404
388
  processIndex('unique');
405
- return [];
389
+ const ret = [];
390
+ let propIndexIsNonTrivialIndex = false;
391
+ const nonTrivialIndexes = this.meta.indexes.filter(i => i.properties?.length === 1 && i.properties[0] === prop.name);
392
+ for (const i of nonTrivialIndexes) {
393
+ ret.push(`@${this.referenceCoreImport('Index')}(${this.serializeObject(this.getIndexOptions(i, false))})`);
394
+ if (prop.index === i.name) {
395
+ propIndexIsNonTrivialIndex = true;
396
+ delete options.index;
397
+ }
398
+ }
399
+ if (prop.index && !options.index && !propIndexIsNonTrivialIndex) {
400
+ ret.push(`@${this.referenceCoreImport('Index')}(${typeof prop.index === 'string' ? `{ name: ${this.quote(prop.index)} }` : ''})`);
401
+ }
402
+ let propIndexIsNonTrivialUnique = false;
403
+ const nonTrivialUnique = this.meta.uniques.filter(i => i.properties?.length === 1 && i.properties[0] === prop.name);
404
+ for (const i of nonTrivialUnique) {
405
+ ret.push(`@${this.referenceCoreImport('Unique')}(${this.serializeObject(this.getUniqueOptions(i, false))})`);
406
+ if (prop.unique === i.name) {
407
+ propIndexIsNonTrivialUnique = true;
408
+ delete options.unique;
409
+ }
410
+ }
411
+ if (prop.unique && !options.unique && !propIndexIsNonTrivialUnique) {
412
+ ret.push(`@${this.referenceCoreImport('Unique')}(${typeof prop.unique === 'string' ? `{ name: ${this.quote(prop.unique)} }` : ''})`);
413
+ }
414
+ return ret;
406
415
  }
407
416
  getCommonDecoratorOptions(options, prop) {
408
417
  if (prop.nullable && !prop.mappedBy) {
@@ -432,26 +441,59 @@ class SourceFile {
432
441
  if (typeof prop.comment === 'string') {
433
442
  options.comment = this.quote(prop.comment);
434
443
  }
435
- if (typeof prop.fieldNames !== 'undefined' && prop.fieldNames.length > 1) {
436
- // TODO: Composite FKs with default values require additions to default/defaultRaw that are not yet supported.
437
- return;
444
+ // TODO: Composite FKs with default values require additions to default/defaultRaw that are not yet supported.
445
+ if (prop.fieldNames?.length <= 1) {
446
+ if (typeof prop.defaultRaw !== 'undefined' && prop.defaultRaw !== 'null' &&
447
+ prop.defaultRaw !== (typeof prop.default === 'string' ? this.quote(prop.default) : `${prop.default}`)) {
448
+ options.defaultRaw = `\`${prop.defaultRaw}\``;
449
+ }
450
+ else if (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')))) {
451
+ options.default = typeof prop.default === 'string' ? this.quote(prop.default) : prop.default;
452
+ }
438
453
  }
439
- if (typeof prop.defaultRaw !== 'undefined' && prop.defaultRaw !== 'null' &&
440
- prop.defaultRaw !== (typeof prop.default === 'string' ? this.quote(prop.default) : `${prop.default}`)) {
441
- options.defaultRaw = `\`${prop.defaultRaw}\``;
442
- }
443
- else if (prop.default != null && (prop.ref || (!prop.enum && (typeof prop.kind === 'undefined' || prop.kind === core_1.ReferenceKind.SCALAR) && (() => {
444
- const mappedDeclaredType = this.platform.getMappedType(prop.type);
445
- const mappedRawType = (prop.customTypes?.[0] ?? ((prop.type !== 'unknown' && mappedDeclaredType instanceof core_1.UnknownType)
446
- ? this.platform.getMappedType(prop.columnTypes[0])
447
- : mappedDeclaredType));
448
- const rawType = mappedRawType.runtimeType;
449
- const serializedType = (prop.customType ?? mappedRawType).runtimeType;
450
- return prop.runtimeType !== rawType || rawType !== serializedType;
451
- })()))) {
452
- options.default = typeof prop.default === 'string' ? this.quote(prop.default) : prop.default;
454
+ if (typeof prop.extra === 'string') {
455
+ options.extra = this.quote(prop.extra);
456
+ }
457
+ if (prop.deferMode) {
458
+ options.deferMode = `${this.referenceCoreImport('DeferMode')}.INITIALLY_${prop.deferMode.toUpperCase()}`;
459
+ }
460
+ if (typeof prop.ignoreSchemaChanges !== 'undefined') {
461
+ options.ignoreSchemaChanges ??= [];
462
+ options.ignoreSchemaChanges.push(...prop.ignoreSchemaChanges.map(v => this.quote(v)));
453
463
  }
454
464
  }
465
+ propTypeBreakdowns = new WeakMap();
466
+ breakdownOfIType(prop) {
467
+ if (this.propTypeBreakdowns.has(prop)) {
468
+ return this.propTypeBreakdowns.get(prop);
469
+ }
470
+ const mappedDeclaredType = this.platform.getMappedType(prop.type);
471
+ const mappedRawType = (prop.customTypes?.[0] ?? ((prop.type !== 'unknown' && mappedDeclaredType instanceof core_1.UnknownType)
472
+ ? this.platform.getMappedType(prop.columnTypes[0])
473
+ : mappedDeclaredType));
474
+ const rawType = mappedRawType.runtimeType;
475
+ const serializedType = (prop.customType ?? mappedRawType).runtimeType;
476
+ // Add non-lib imports where needed.
477
+ for (const typeSpec of [prop.runtimeType, rawType, serializedType]) {
478
+ const simplePropType = typeSpec.replace(/\[]+$/, '');
479
+ if (!primitivesAndLibs.includes(simplePropType)) {
480
+ this.entityImports.add(simplePropType);
481
+ }
482
+ }
483
+ if (prop.runtimeType !== rawType || rawType !== serializedType) {
484
+ if (rawType !== serializedType) {
485
+ const r = [prop.runtimeType, rawType, serializedType];
486
+ this.propTypeBreakdowns.set(prop, r);
487
+ return r;
488
+ }
489
+ const r = [prop.runtimeType, rawType];
490
+ this.propTypeBreakdowns.set(prop, r);
491
+ return r;
492
+ }
493
+ const r = undefined;
494
+ this.propTypeBreakdowns.set(prop, r);
495
+ return r;
496
+ }
455
497
  getScalarPropertyDecoratorOptions(options, prop) {
456
498
  if (prop.fieldNames[0] !== this.namingStrategy.propertyToColumnName(prop.name)) {
457
499
  options.fieldName = this.quote(prop.fieldNames[0]);
@@ -486,11 +528,17 @@ class SourceFile {
486
528
  const columnTypeFromMappedRuntimeType = mappedRuntimeType.getColumnType({ ...prop, autoincrement: false }, this.platform);
487
529
  const columnTypeFromMappedColumnType = mappedColumnType.getColumnType({ ...prop, autoincrement: false }, this.platform);
488
530
  const columnTypeFromMappedDeclaredType = mappedDeclaredType.getColumnType({ ...prop, autoincrement: false }, this.platform);
489
- if (isTypeStringMissingFromMap
490
- || columnTypeFromMappedRuntimeType !== columnTypeFromMappedColumnType
491
- || columnTypeFromMappedDeclaredType !== columnTypeFromMappedColumnType
492
- || [mappedRuntimeType, mappedColumnType, columnTypeFromMappedDeclaredType].some(t => t instanceof core_1.UnknownType)) {
493
- options.columnType = this.quote(columnTypeFromMappedColumnType);
531
+ const needsExplicitColumnType = () => {
532
+ if (isTypeStringMissingFromMap || [mappedRuntimeType, mappedColumnType, columnTypeFromMappedDeclaredType].some(t => t instanceof core_1.UnknownType)) {
533
+ return true;
534
+ }
535
+ if (this.platform.normalizeColumnType(prop.columnTypes[0], prop) !== this.platform.normalizeColumnType(columnTypeFromMappedColumnType, prop)) {
536
+ return prop.columnTypes[0] !== columnTypeFromMappedColumnType;
537
+ }
538
+ return columnTypeFromMappedRuntimeType !== columnTypeFromMappedColumnType || columnTypeFromMappedDeclaredType !== columnTypeFromMappedColumnType;
539
+ };
540
+ if (needsExplicitColumnType()) {
541
+ options.columnType = this.quote(prop.columnTypes[0]);
494
542
  }
495
543
  const assign = (key) => {
496
544
  if (prop[key] != null) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/entity-generator",
3
- "version": "6.3.5-dev.2",
3
+ "version": "6.3.5-dev.21",
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
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -58,13 +58,13 @@
58
58
  "access": "public"
59
59
  },
60
60
  "dependencies": {
61
- "@mikro-orm/knex": "6.3.5-dev.2",
61
+ "@mikro-orm/knex": "6.3.5-dev.21",
62
62
  "fs-extra": "11.2.0"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@mikro-orm/core": "^6.3.4"
66
66
  },
67
67
  "peerDependencies": {
68
- "@mikro-orm/core": "6.3.5-dev.2"
68
+ "@mikro-orm/core": "6.3.5-dev.21"
69
69
  }
70
70
  }