@mikro-orm/entity-generator 7.0.0-dev.24 → 7.0.0-dev.241
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/DefineEntitySourceFile.d.ts +5 -0
- package/DefineEntitySourceFile.js +115 -0
- package/EntityGenerator.d.ts +2 -1
- package/EntityGenerator.js +111 -34
- package/EntitySchemaSourceFile.d.ts +3 -2
- package/EntitySchemaSourceFile.js +47 -36
- package/NativeEnumSourceFile.d.ts +16 -0
- package/NativeEnumSourceFile.js +47 -0
- package/README.md +2 -0
- package/SourceFile.d.ts +8 -1
- package/SourceFile.js +202 -49
- package/package.json +6 -6
- package/tsconfig.build.tsbuildinfo +1 -0
package/SourceFile.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import { Cascade, Config, DecimalType, ReferenceKind, SCALAR_TYPES, UnknownType, Utils, } from '@mikro-orm/core';
|
|
1
|
+
import { Cascade, Config, DecimalType, ReferenceKind, SCALAR_TYPES, UnknownType, Utils, inspect, } from '@mikro-orm/core';
|
|
2
2
|
import { parse, relative } from 'node:path';
|
|
3
|
-
import { inspect } from 'node:util';
|
|
4
3
|
import { POSSIBLE_TYPE_IMPORTS } from './CoreImportsHelper.js';
|
|
5
4
|
/**
|
|
6
5
|
* @see https://github.com/tc39/proposal-regexp-unicode-property-escapes#other-examples
|
|
7
6
|
*/
|
|
8
7
|
export const identifierRegex = /^(?:[$_\p{ID_Start}])(?:[$\u200C\u200D\p{ID_Continue}])*$/u;
|
|
9
|
-
const primitivesAndLibs = [...SCALAR_TYPES, '
|
|
8
|
+
const primitivesAndLibs = [...SCALAR_TYPES, 'unknown', 'object', 'any'];
|
|
10
9
|
export class SourceFile {
|
|
11
10
|
meta;
|
|
12
11
|
namingStrategy;
|
|
13
12
|
platform;
|
|
14
13
|
options;
|
|
15
14
|
coreImports = new Set();
|
|
15
|
+
decoratorImports = new Set();
|
|
16
16
|
entityImports = new Set();
|
|
17
|
+
enumImports = new Map();
|
|
17
18
|
constructor(meta, namingStrategy, platform, options) {
|
|
18
19
|
this.meta = meta;
|
|
19
20
|
this.namingStrategy = namingStrategy;
|
|
@@ -25,24 +26,24 @@ export class SourceFile {
|
|
|
25
26
|
if (this.meta.embeddable || this.meta.collection) {
|
|
26
27
|
if (this.meta.embeddable) {
|
|
27
28
|
const options = this.getEmbeddableDeclOptions();
|
|
28
|
-
ret += `@${this.
|
|
29
|
+
ret += `@${this.referenceDecoratorImport('Embeddable')}(${Utils.hasObjectKeys(options) ? this.serializeObject(options) : ''})\n`;
|
|
29
30
|
}
|
|
30
31
|
else {
|
|
31
32
|
const options = this.getEntityDeclOptions();
|
|
32
|
-
ret += `@${this.
|
|
33
|
+
ret += `@${this.referenceDecoratorImport('Entity')}(${Utils.hasObjectKeys(options) ? this.serializeObject(options) : ''})\n`;
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
for (const index of this.meta.indexes) {
|
|
36
37
|
if (index.properties?.length === 1 && typeof this.meta.properties[index.properties[0]] !== 'undefined') {
|
|
37
38
|
continue;
|
|
38
39
|
}
|
|
39
|
-
ret += `@${this.
|
|
40
|
+
ret += `@${this.referenceDecoratorImport('Index')}(${this.serializeObject(this.getIndexOptions(index))})\n`;
|
|
40
41
|
}
|
|
41
42
|
for (const index of this.meta.uniques) {
|
|
42
43
|
if (index.properties?.length === 1 && typeof this.meta.properties[index.properties[0]] !== 'undefined') {
|
|
43
44
|
continue;
|
|
44
45
|
}
|
|
45
|
-
ret += `@${this.
|
|
46
|
+
ret += `@${this.referenceDecoratorImport('Unique')}(${this.serializeObject(this.getUniqueOptions(index))})\n`;
|
|
46
47
|
}
|
|
47
48
|
let classHead = '';
|
|
48
49
|
if (this.meta.className === this.options.customBaseEntityName) {
|
|
@@ -65,7 +66,10 @@ export class SourceFile {
|
|
|
65
66
|
classBody += definition;
|
|
66
67
|
classBody += '\n';
|
|
67
68
|
if (prop.enum) {
|
|
68
|
-
|
|
69
|
+
const def = this.getEnumClassDefinition(prop, 2);
|
|
70
|
+
if (def.length) {
|
|
71
|
+
enumDefinitions.push(def);
|
|
72
|
+
}
|
|
69
73
|
}
|
|
70
74
|
if (prop.eager) {
|
|
71
75
|
eagerProperties.push(prop);
|
|
@@ -94,6 +98,30 @@ export class SourceFile {
|
|
|
94
98
|
}
|
|
95
99
|
return ret;
|
|
96
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Convert index column options to quoted output format.
|
|
103
|
+
*/
|
|
104
|
+
getColumnOptions(columns) {
|
|
105
|
+
if (!columns?.length) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
return columns.map(col => {
|
|
109
|
+
const colOpt = { name: this.quote(col.name) };
|
|
110
|
+
if (col.sort) {
|
|
111
|
+
colOpt.sort = this.quote(col.sort.toUpperCase());
|
|
112
|
+
}
|
|
113
|
+
if (col.nulls) {
|
|
114
|
+
colOpt.nulls = this.quote(col.nulls.toUpperCase());
|
|
115
|
+
}
|
|
116
|
+
if (col.length != null) {
|
|
117
|
+
colOpt.length = col.length;
|
|
118
|
+
}
|
|
119
|
+
if (col.collation) {
|
|
120
|
+
colOpt.collation = this.quote(col.collation);
|
|
121
|
+
}
|
|
122
|
+
return colOpt;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
97
125
|
getIndexOptions(index, isAtEntityLevel = true) {
|
|
98
126
|
const indexOpt = {};
|
|
99
127
|
if (typeof index.name === 'string') {
|
|
@@ -108,6 +136,30 @@ export class SourceFile {
|
|
|
108
136
|
if (isAtEntityLevel && index.properties) {
|
|
109
137
|
indexOpt.properties = Utils.asArray(index.properties).map(prop => this.quote('' + prop));
|
|
110
138
|
}
|
|
139
|
+
// Index type (e.g., 'fulltext', 'spatial', 'btree', 'hash')
|
|
140
|
+
if (index.type) {
|
|
141
|
+
indexOpt.type = this.quote(index.type);
|
|
142
|
+
}
|
|
143
|
+
// Advanced index options
|
|
144
|
+
const columns = this.getColumnOptions(index.columns);
|
|
145
|
+
if (columns) {
|
|
146
|
+
indexOpt.columns = columns;
|
|
147
|
+
}
|
|
148
|
+
if (index.include) {
|
|
149
|
+
indexOpt.include = Utils.asArray(index.include).map(prop => this.quote('' + prop));
|
|
150
|
+
}
|
|
151
|
+
if (index.fillFactor != null) {
|
|
152
|
+
indexOpt.fillFactor = index.fillFactor;
|
|
153
|
+
}
|
|
154
|
+
if (index.invisible) {
|
|
155
|
+
indexOpt.invisible = true;
|
|
156
|
+
}
|
|
157
|
+
if (index.disabled) {
|
|
158
|
+
indexOpt.disabled = true;
|
|
159
|
+
}
|
|
160
|
+
if (index.clustered) {
|
|
161
|
+
indexOpt.clustered = true;
|
|
162
|
+
}
|
|
111
163
|
return indexOpt;
|
|
112
164
|
}
|
|
113
165
|
getUniqueOptions(index, isAtEntityLevel = true) {
|
|
@@ -127,6 +179,19 @@ export class SourceFile {
|
|
|
127
179
|
if (index.deferMode) {
|
|
128
180
|
uniqueOpt.deferMode = `${this.referenceCoreImport('DeferMode')}.INITIALLY_${index.deferMode.toUpperCase()}`;
|
|
129
181
|
}
|
|
182
|
+
const columns = this.getColumnOptions(index.columns);
|
|
183
|
+
if (columns) {
|
|
184
|
+
uniqueOpt.columns = columns;
|
|
185
|
+
}
|
|
186
|
+
if (index.include) {
|
|
187
|
+
uniqueOpt.include = Utils.asArray(index.include).map(prop => this.quote('' + prop));
|
|
188
|
+
}
|
|
189
|
+
if (index.fillFactor != null) {
|
|
190
|
+
uniqueOpt.fillFactor = index.fillFactor;
|
|
191
|
+
}
|
|
192
|
+
if (index.disabled) {
|
|
193
|
+
uniqueOpt.disabled = true;
|
|
194
|
+
}
|
|
130
195
|
return uniqueOpt;
|
|
131
196
|
}
|
|
132
197
|
generateImports() {
|
|
@@ -141,37 +206,61 @@ export class SourceFile {
|
|
|
141
206
|
return ret;
|
|
142
207
|
}).join(', '))} } from '@mikro-orm/core';`);
|
|
143
208
|
}
|
|
209
|
+
if (this.decoratorImports.size > 0) {
|
|
210
|
+
const type = this.options.decorators;
|
|
211
|
+
imports.add(`import { ${([...this.decoratorImports].sort().map(t => {
|
|
212
|
+
let ret = t;
|
|
213
|
+
if (this.options.coreImportsPrefix) {
|
|
214
|
+
const resolvedIdentifier = `${this.options.coreImportsPrefix}${t}`;
|
|
215
|
+
ret += ` as ${resolvedIdentifier}`;
|
|
216
|
+
}
|
|
217
|
+
return ret;
|
|
218
|
+
}).join(', '))} } from '@mikro-orm/decorators/${type}';`);
|
|
219
|
+
}
|
|
144
220
|
const extension = this.options.esmImport ? '.js' : '';
|
|
145
221
|
const { dir, base } = parse(`${this.options.path ?? '.'}/${this.getBaseName()}`);
|
|
146
222
|
const basePath = relative(dir, this.options.path ?? '.') || '.';
|
|
147
223
|
(this.options.extraImports?.(basePath, base) ?? []).forEach(v => this.entityImports.add(v));
|
|
148
224
|
const entityImports = [...this.entityImports].filter(e => e !== this.meta.className);
|
|
149
|
-
|
|
225
|
+
const importMap = new Map();
|
|
226
|
+
for (const entity of entityImports) {
|
|
150
227
|
const file = this.options.onImport?.(entity, basePath, extension, base) ?? {
|
|
151
228
|
path: `${basePath}/${this.options.fileName(entity)}${extension}`,
|
|
152
229
|
name: entity,
|
|
153
230
|
};
|
|
154
231
|
if (file.path === '') {
|
|
155
232
|
if (file.name === '') {
|
|
156
|
-
|
|
233
|
+
continue;
|
|
157
234
|
}
|
|
158
|
-
|
|
159
|
-
|
|
235
|
+
importMap.set(file.path, `import ${this.quote(file.name)};`);
|
|
236
|
+
continue;
|
|
160
237
|
}
|
|
161
238
|
if (file.name === '') {
|
|
162
|
-
|
|
163
|
-
|
|
239
|
+
importMap.set(file.path, `import * as ${entity} from ${this.quote(file.path)};`);
|
|
240
|
+
continue;
|
|
164
241
|
}
|
|
165
242
|
if (file.name === 'default') {
|
|
166
|
-
|
|
167
|
-
|
|
243
|
+
importMap.set(file.path, `import ${entity} from ${this.quote(file.path)};`);
|
|
244
|
+
continue;
|
|
168
245
|
}
|
|
169
246
|
if (file.name === entity) {
|
|
170
|
-
|
|
171
|
-
|
|
247
|
+
importMap.set(file.path, `import { ${entity} } from ${this.quote(file.path)};`);
|
|
248
|
+
continue;
|
|
172
249
|
}
|
|
173
|
-
|
|
174
|
-
}
|
|
250
|
+
importMap.set(file.path, `import { ${identifierRegex.test(file.name) ? file.name : this.quote(file.name)} as ${entity} } from ${this.quote(file.path)};`);
|
|
251
|
+
}
|
|
252
|
+
if (this.enumImports.size) {
|
|
253
|
+
for (const [name, exports] of this.enumImports.entries()) {
|
|
254
|
+
const file = this.options.onImport?.(name, basePath, extension, base) ?? {
|
|
255
|
+
path: `${basePath}/${this.options.fileName(name)}${extension}`,
|
|
256
|
+
name,
|
|
257
|
+
};
|
|
258
|
+
importMap.set(file.path, `import { ${exports.join(', ')} } from ${this.quote(file.path)};`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
for (const key of [...importMap.keys()].sort()) {
|
|
262
|
+
imports.add(importMap.get(key));
|
|
263
|
+
}
|
|
175
264
|
return Array.from(imports.values()).join('\n');
|
|
176
265
|
}
|
|
177
266
|
getEntityClass(classBody) {
|
|
@@ -181,8 +270,8 @@ export class SourceFile {
|
|
|
181
270
|
}
|
|
182
271
|
ret += `class ${this.meta.className}`;
|
|
183
272
|
if (this.meta.extends) {
|
|
184
|
-
this.entityImports.add(this.meta.extends);
|
|
185
|
-
ret += ` extends ${this.meta.extends}`;
|
|
273
|
+
this.entityImports.add(Utils.className(this.meta.extends));
|
|
274
|
+
ret += ` extends ${Utils.className(this.meta.extends)}`;
|
|
186
275
|
}
|
|
187
276
|
else if (this.options.useCoreBaseEntity) {
|
|
188
277
|
ret += ` extends ${this.referenceCoreImport('BaseEntity')}`;
|
|
@@ -201,6 +290,7 @@ export class SourceFile {
|
|
|
201
290
|
getPropertyDefinition(prop, padLeft) {
|
|
202
291
|
const padding = ' '.repeat(padLeft);
|
|
203
292
|
const propName = identifierRegex.test(prop.name) ? prop.name : this.quote(prop.name);
|
|
293
|
+
const enumMode = this.options.enumMode;
|
|
204
294
|
let hiddenType = '';
|
|
205
295
|
if (prop.hidden) {
|
|
206
296
|
hiddenType += ` & ${this.referenceCoreImport('Hidden')}`;
|
|
@@ -218,7 +308,11 @@ export class SourceFile {
|
|
|
218
308
|
: (() => {
|
|
219
309
|
if (isScalar) {
|
|
220
310
|
if (prop.enum) {
|
|
221
|
-
|
|
311
|
+
const method = enumMode === 'ts-enum' ? 'getEnumClassName' : 'getEnumTypeName';
|
|
312
|
+
if (prop.nativeEnumName) {
|
|
313
|
+
return this.namingStrategy[method](prop.nativeEnumName, undefined, this.meta.schema);
|
|
314
|
+
}
|
|
315
|
+
return this.namingStrategy[method](prop.fieldNames[0], this.meta.collection, this.meta.schema);
|
|
222
316
|
}
|
|
223
317
|
breakdownOfIType = this.breakdownOfIType(prop);
|
|
224
318
|
if (typeof breakdownOfIType !== 'undefined') {
|
|
@@ -253,8 +347,14 @@ export class SourceFile {
|
|
|
253
347
|
return `${padding}${ret};\n`;
|
|
254
348
|
}
|
|
255
349
|
if (prop.enum && typeof prop.default === 'string') {
|
|
350
|
+
if (enumMode === 'union-type') {
|
|
351
|
+
return `${padding}${ret} = ${this.quote(prop.default)};\n`;
|
|
352
|
+
}
|
|
353
|
+
const enumClassName = prop.nativeEnumName
|
|
354
|
+
? this.namingStrategy.getEnumClassName(prop.nativeEnumName, undefined, this.meta.schema)
|
|
355
|
+
: this.namingStrategy.getEnumClassName(prop.fieldNames[0], this.meta.collection, this.meta.schema);
|
|
256
356
|
const enumVal = this.namingStrategy.enumValueToEnumProperty(prop.default, prop.fieldNames[0], this.meta.collection, this.meta.schema);
|
|
257
|
-
return `${padding}${ret} = ${
|
|
357
|
+
return `${padding}${ret} = ${enumClassName}${identifierRegex.test(enumVal) ? `.${enumVal}` : `[${this.quote(enumVal)}]`};\n`;
|
|
258
358
|
}
|
|
259
359
|
if (prop.fieldNames?.length > 1) {
|
|
260
360
|
// TODO: Composite FKs with default values require additions to default/defaultRaw that are not yet supported.
|
|
@@ -270,15 +370,51 @@ export class SourceFile {
|
|
|
270
370
|
return `${padding}${ret} = ${prop.ref ? this.referenceCoreImport('ref') : this.referenceCoreImport('rel')}(${propType}, ${defaultVal});\n`;
|
|
271
371
|
}
|
|
272
372
|
getEnumClassDefinition(prop, padLeft) {
|
|
373
|
+
const enumMode = this.options.enumMode;
|
|
374
|
+
if (prop.nativeEnumName) {
|
|
375
|
+
const imports = [];
|
|
376
|
+
if (enumMode !== 'union-type') {
|
|
377
|
+
imports.push(prop.runtimeType);
|
|
378
|
+
}
|
|
379
|
+
if (!this.options.inferEntityType && enumMode !== 'ts-enum') {
|
|
380
|
+
const enumTypeName = this.namingStrategy.getEnumTypeName(prop.nativeEnumName, undefined, this.meta.schema);
|
|
381
|
+
imports.push(enumTypeName);
|
|
382
|
+
}
|
|
383
|
+
this.enumImports.set(prop.runtimeType, imports);
|
|
384
|
+
return '';
|
|
385
|
+
}
|
|
273
386
|
const enumClassName = this.namingStrategy.getEnumClassName(prop.fieldNames[0], this.meta.collection, this.meta.schema);
|
|
387
|
+
const enumTypeName = this.namingStrategy.getEnumTypeName(prop.fieldNames[0], this.meta.collection, this.meta.schema);
|
|
274
388
|
const padding = ' '.repeat(padLeft);
|
|
275
|
-
let ret = `export enum ${enumClassName} {\n`;
|
|
276
389
|
const enumValues = prop.items;
|
|
390
|
+
if (enumMode === 'union-type') {
|
|
391
|
+
return `export type ${enumTypeName} = ${enumValues.map(item => this.quote(item)).join(' | ')};\n`;
|
|
392
|
+
}
|
|
393
|
+
let ret = '';
|
|
394
|
+
if (enumMode === 'dictionary') {
|
|
395
|
+
ret += `export const ${enumClassName} = {\n`;
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
ret += `export enum ${enumClassName} {\n`;
|
|
399
|
+
}
|
|
277
400
|
for (const enumValue of enumValues) {
|
|
278
401
|
const enumName = this.namingStrategy.enumValueToEnumProperty(enumValue, prop.fieldNames[0], this.meta.collection, this.meta.schema);
|
|
279
|
-
|
|
402
|
+
if (enumMode === 'dictionary') {
|
|
403
|
+
ret += `${padding}${identifierRegex.test(enumName) ? enumName : this.quote(enumName)}: ${this.quote(enumValue)},\n`;
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
ret += `${padding}${identifierRegex.test(enumName) ? enumName : this.quote(enumName)} = ${this.quote(enumValue)},\n`;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (enumMode === 'dictionary') {
|
|
410
|
+
ret += '} as const;\n';
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
ret += '}\n';
|
|
414
|
+
}
|
|
415
|
+
if (enumMode === 'dictionary') {
|
|
416
|
+
ret += `\nexport type ${enumTypeName} = (typeof ${enumClassName})[keyof typeof ${enumClassName}];\n`;
|
|
280
417
|
}
|
|
281
|
-
ret += '}\n';
|
|
282
418
|
return ret;
|
|
283
419
|
}
|
|
284
420
|
serializeObject(options, wordwrap, spaces, level = 0) {
|
|
@@ -308,8 +444,8 @@ export class SourceFile {
|
|
|
308
444
|
}
|
|
309
445
|
getEntityDeclOptions() {
|
|
310
446
|
const options = {};
|
|
311
|
-
if (this.meta.
|
|
312
|
-
options.tableName = this.quote(this.meta.
|
|
447
|
+
if (this.meta.tableName !== this.namingStrategy.classToTableName(this.meta.className)) {
|
|
448
|
+
options.tableName = this.quote(this.meta.tableName);
|
|
313
449
|
}
|
|
314
450
|
if (this.meta.schema && this.meta.schema !== this.platform.getDefaultSchemaName()) {
|
|
315
451
|
options.schema = this.quote(this.meta.schema);
|
|
@@ -318,7 +454,7 @@ export class SourceFile {
|
|
|
318
454
|
options.expression = this.quote(this.meta.expression);
|
|
319
455
|
}
|
|
320
456
|
else if (typeof this.meta.expression === 'function') {
|
|
321
|
-
options.expression =
|
|
457
|
+
options.expression = this.meta.expression.toString();
|
|
322
458
|
}
|
|
323
459
|
if (this.meta.repositoryClass) {
|
|
324
460
|
this.entityImports.add(this.meta.repositoryClass);
|
|
@@ -351,14 +487,14 @@ export class SourceFile {
|
|
|
351
487
|
}
|
|
352
488
|
if (this.meta.discriminatorMap) {
|
|
353
489
|
options.discriminatorMap = Object.fromEntries(Object.entries(this.meta.discriminatorMap)
|
|
354
|
-
.map(([discriminatorValue,
|
|
490
|
+
.map(([discriminatorValue, cls]) => [discriminatorValue, this.quote(Utils.className(cls))]));
|
|
355
491
|
}
|
|
356
492
|
return options;
|
|
357
493
|
}
|
|
358
494
|
getPropertyDecorator(prop, padLeft) {
|
|
359
495
|
const padding = ' '.repeat(padLeft);
|
|
360
496
|
const options = {};
|
|
361
|
-
let decorator = `@${this.
|
|
497
|
+
let decorator = `@${this.referenceDecoratorImport(this.getDecoratorType(prop))}`;
|
|
362
498
|
if (prop.kind === ReferenceKind.MANY_TO_MANY) {
|
|
363
499
|
this.getManyToManyDecoratorOptions(options, prop);
|
|
364
500
|
}
|
|
@@ -379,7 +515,7 @@ export class SourceFile {
|
|
|
379
515
|
decorator = [...indexes.sort(), decorator].map(d => padding + d).join('\n');
|
|
380
516
|
const decoratorArgs = [];
|
|
381
517
|
if (prop.formula) {
|
|
382
|
-
decoratorArgs.push(
|
|
518
|
+
decoratorArgs.push(prop.formula.toString());
|
|
383
519
|
}
|
|
384
520
|
if (Utils.hasObjectKeys(options)) {
|
|
385
521
|
decoratorArgs.push(`${this.serializeObject(options)}`);
|
|
@@ -408,26 +544,26 @@ export class SourceFile {
|
|
|
408
544
|
let propIndexIsNonTrivialIndex = false;
|
|
409
545
|
const nonTrivialIndexes = this.meta.indexes.filter(i => i.properties?.length === 1 && i.properties[0] === prop.name);
|
|
410
546
|
for (const i of nonTrivialIndexes) {
|
|
411
|
-
ret.push(`@${this.
|
|
547
|
+
ret.push(`@${this.referenceDecoratorImport('Index')}(${this.serializeObject(this.getIndexOptions(i, false))})`);
|
|
412
548
|
if (prop.index === i.name) {
|
|
413
549
|
propIndexIsNonTrivialIndex = true;
|
|
414
550
|
delete options.index;
|
|
415
551
|
}
|
|
416
552
|
}
|
|
417
553
|
if (prop.index && !options.index && !propIndexIsNonTrivialIndex) {
|
|
418
|
-
ret.push(`@${this.
|
|
554
|
+
ret.push(`@${this.referenceDecoratorImport('Index')}(${typeof prop.index === 'string' ? `{ name: ${this.quote(prop.index)} }` : ''})`);
|
|
419
555
|
}
|
|
420
556
|
let propIndexIsNonTrivialUnique = false;
|
|
421
557
|
const nonTrivialUnique = this.meta.uniques.filter(i => i.properties?.length === 1 && i.properties[0] === prop.name);
|
|
422
558
|
for (const i of nonTrivialUnique) {
|
|
423
|
-
ret.push(`@${this.
|
|
559
|
+
ret.push(`@${this.referenceDecoratorImport('Unique')}(${this.serializeObject(this.getUniqueOptions(i, false))})`);
|
|
424
560
|
if (prop.unique === i.name) {
|
|
425
561
|
propIndexIsNonTrivialUnique = true;
|
|
426
562
|
delete options.unique;
|
|
427
563
|
}
|
|
428
564
|
}
|
|
429
565
|
if (prop.unique && !options.unique && !propIndexIsNonTrivialUnique) {
|
|
430
|
-
ret.push(`@${this.
|
|
566
|
+
ret.push(`@${this.referenceDecoratorImport('Unique')}(${typeof prop.unique === 'string' ? `{ name: ${this.quote(prop.unique)} }` : ''})`);
|
|
431
567
|
}
|
|
432
568
|
return ret;
|
|
433
569
|
}
|
|
@@ -438,7 +574,7 @@ export class SourceFile {
|
|
|
438
574
|
if (prop.primary && (prop.enum || !(typeof prop.kind === 'undefined' || prop.kind === ReferenceKind.SCALAR))) {
|
|
439
575
|
options.primary = true;
|
|
440
576
|
}
|
|
441
|
-
['persist', 'hydrate'
|
|
577
|
+
['persist', 'hydrate']
|
|
442
578
|
.filter(key => prop[key] === false)
|
|
443
579
|
.forEach(key => options[key] = false);
|
|
444
580
|
['onCreate', 'onUpdate', 'serializer']
|
|
@@ -537,12 +673,23 @@ export class SourceFile {
|
|
|
537
673
|
this.propTypeBreakdowns.set(prop, r);
|
|
538
674
|
return r;
|
|
539
675
|
}
|
|
540
|
-
getScalarPropertyDecoratorOptions(options, prop) {
|
|
676
|
+
getScalarPropertyDecoratorOptions(options, prop, quote = true) {
|
|
541
677
|
if (prop.fieldNames[0] !== this.namingStrategy.propertyToColumnName(prop.name)) {
|
|
542
678
|
options.fieldName = this.quote(prop.fieldNames[0]);
|
|
543
679
|
}
|
|
544
680
|
if (prop.enum) {
|
|
545
|
-
options.
|
|
681
|
+
if (this.options.enumMode === 'union-type') {
|
|
682
|
+
options.items = `[${prop.items.map(item => this.quote(item)).join(', ')}]`;
|
|
683
|
+
}
|
|
684
|
+
else if (prop.nativeEnumName) {
|
|
685
|
+
const enumClassName = this.namingStrategy.getEnumClassName(prop.nativeEnumName, undefined, this.meta.schema);
|
|
686
|
+
options.items = `() => ${enumClassName}`;
|
|
687
|
+
options.nativeEnumName = this.quote(prop.nativeEnumName);
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
const enumClassName = this.namingStrategy.getEnumClassName(prop.fieldNames[0], this.meta.collection, this.meta.schema);
|
|
691
|
+
options.items = `() => ${enumClassName}`;
|
|
692
|
+
}
|
|
546
693
|
}
|
|
547
694
|
// For enum properties, we don't need a column type
|
|
548
695
|
// or the property length or other information in the decorator.
|
|
@@ -571,7 +718,7 @@ export class SourceFile {
|
|
|
571
718
|
return ((useDefault && !hasUsableNullDefault) || (prop.optional && !prop.nullable));
|
|
572
719
|
})() // also when there is the "| Opt" type modifier (because reflect-metadata can't extract the base)
|
|
573
720
|
) {
|
|
574
|
-
options.type = this.quote(prop.type);
|
|
721
|
+
options.type = quote ? this.quote(prop.type) : prop.type;
|
|
575
722
|
}
|
|
576
723
|
}
|
|
577
724
|
const columnTypeFromMappedRuntimeType = mappedRuntimeType.getColumnType({ ...prop, autoincrement: false }, this.platform);
|
|
@@ -598,7 +745,7 @@ export class SourceFile {
|
|
|
598
745
|
assign('length');
|
|
599
746
|
}
|
|
600
747
|
// those are already included in the `columnType` in most cases, and when that option is present, they would be ignored anyway
|
|
601
|
-
/* v8 ignore next
|
|
748
|
+
/* v8 ignore next */
|
|
602
749
|
if (mappedColumnType instanceof DecimalType && !options.columnType) {
|
|
603
750
|
assign('precision');
|
|
604
751
|
assign('scale');
|
|
@@ -632,12 +779,12 @@ export class SourceFile {
|
|
|
632
779
|
options.mappedBy = this.quote(prop.mappedBy);
|
|
633
780
|
return;
|
|
634
781
|
}
|
|
635
|
-
if (prop.pivotTable !== this.namingStrategy.joinTableName(this.meta.collection, prop.type, prop.name)) {
|
|
782
|
+
if (prop.pivotTable !== this.namingStrategy.joinTableName(this.meta.collection, prop.type, prop.name, this.meta.tableName)) {
|
|
636
783
|
options.pivotTable = this.quote(prop.pivotTable);
|
|
637
784
|
}
|
|
638
|
-
if (prop.pivotEntity && prop.pivotEntity !== prop.pivotTable) {
|
|
639
|
-
this.entityImports.add(prop.pivotEntity);
|
|
640
|
-
options.pivotEntity = `() => ${prop.pivotEntity}`;
|
|
785
|
+
if (prop.pivotEntity && Utils.className(prop.pivotEntity) !== prop.pivotTable) {
|
|
786
|
+
this.entityImports.add(Utils.className(prop.pivotEntity));
|
|
787
|
+
options.pivotEntity = `() => ${Utils.className(prop.pivotEntity)}`;
|
|
641
788
|
}
|
|
642
789
|
if (prop.joinColumns.length === 1) {
|
|
643
790
|
options.joinColumn = this.quote(prop.joinColumns[0]);
|
|
@@ -672,7 +819,7 @@ export class SourceFile {
|
|
|
672
819
|
if (prop.array) {
|
|
673
820
|
options.array = true;
|
|
674
821
|
}
|
|
675
|
-
if (prop.object) {
|
|
822
|
+
if (prop.object && !prop.array) {
|
|
676
823
|
options.object = true;
|
|
677
824
|
}
|
|
678
825
|
if (prop.prefix === false || typeof prop.prefix === 'string') {
|
|
@@ -705,10 +852,10 @@ export class SourceFile {
|
|
|
705
852
|
if (prop.ownColumns && prop.ownColumns.length !== prop.fieldNames.length) {
|
|
706
853
|
options.referencedColumnNames = prop.referencedColumnNames.map(fieldName => this.quote(fieldName));
|
|
707
854
|
}
|
|
708
|
-
if (
|
|
855
|
+
if (prop.updateRule) {
|
|
709
856
|
options.updateRule = this.quote(prop.updateRule);
|
|
710
857
|
}
|
|
711
|
-
if (
|
|
858
|
+
if (prop.deleteRule) {
|
|
712
859
|
options.deleteRule = this.quote(prop.deleteRule);
|
|
713
860
|
}
|
|
714
861
|
if (prop.primary) {
|
|
@@ -755,4 +902,10 @@ export class SourceFile {
|
|
|
755
902
|
? `${this.options.coreImportsPrefix}${identifier}`
|
|
756
903
|
: identifier;
|
|
757
904
|
}
|
|
905
|
+
referenceDecoratorImport(identifier) {
|
|
906
|
+
this.decoratorImports.add(identifier);
|
|
907
|
+
return this.options.coreImportsPrefix
|
|
908
|
+
? `${this.options.coreImportsPrefix}${identifier}`
|
|
909
|
+
: identifier;
|
|
910
|
+
}
|
|
758
911
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/entity-generator",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "7.0.0-dev.
|
|
4
|
+
"version": "7.0.0-dev.241",
|
|
5
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.",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./package.json": "./package.json",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
},
|
|
39
39
|
"homepage": "https://mikro-orm.io",
|
|
40
40
|
"engines": {
|
|
41
|
-
"node": ">= 22.
|
|
41
|
+
"node": ">= 22.17.0"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
|
-
"build": "yarn
|
|
44
|
+
"build": "yarn compile && yarn copy",
|
|
45
45
|
"clean": "yarn run -T rimraf ./dist",
|
|
46
46
|
"compile": "yarn run -T tsc -p tsconfig.build.json",
|
|
47
47
|
"copy": "node ../../scripts/copy.mjs"
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@mikro-orm/
|
|
53
|
+
"@mikro-orm/sql": "7.0.0-dev.241"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@mikro-orm/core": "^6.
|
|
56
|
+
"@mikro-orm/core": "^6.6.4"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@mikro-orm/core": "7.0.0-dev.
|
|
59
|
+
"@mikro-orm/core": "7.0.0-dev.241"
|
|
60
60
|
}
|
|
61
61
|
}
|