@mikro-orm/entity-generator 7.0.0-dev.16 → 7.0.0-dev.161
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 +1 -1
- package/EntityGenerator.js +44 -33
- 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 +3 -2
- package/SourceFile.d.ts +4 -1
- package/SourceFile.js +147 -49
- package/package.json +6 -6
- package/tsconfig.build.tsbuildinfo +1 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { Config, ReferenceKind, types, } from '@mikro-orm/core';
|
|
2
|
+
import { EntitySchemaSourceFile } from './EntitySchemaSourceFile.js';
|
|
3
|
+
export class DefineEntitySourceFile extends EntitySchemaSourceFile {
|
|
4
|
+
generate() {
|
|
5
|
+
const enumDefinitions = [];
|
|
6
|
+
for (const prop of Object.values(this.meta.properties)) {
|
|
7
|
+
if (prop.enum && (typeof prop.kind === 'undefined' || prop.kind === ReferenceKind.SCALAR)) {
|
|
8
|
+
const def = this.getEnumClassDefinition(prop, 2);
|
|
9
|
+
if (def.length) {
|
|
10
|
+
enumDefinitions.push(def);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
let ret = '';
|
|
15
|
+
if (!this.options.inferEntityType) {
|
|
16
|
+
ret += this.generateClassDefinition() + '\n';
|
|
17
|
+
}
|
|
18
|
+
if (enumDefinitions.length) {
|
|
19
|
+
ret += enumDefinitions.join('\n') + '\n';
|
|
20
|
+
}
|
|
21
|
+
const entitySchemaOptions = {};
|
|
22
|
+
if (this.options.inferEntityType) {
|
|
23
|
+
entitySchemaOptions.name = this.quote(this.meta.className);
|
|
24
|
+
if (this.meta.compositePK) {
|
|
25
|
+
entitySchemaOptions.primaryKeys = this.meta.getPrimaryProps().map(p => this.quote(p.name));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
entitySchemaOptions.class = this.meta.className;
|
|
30
|
+
}
|
|
31
|
+
Object.assign(entitySchemaOptions, (this.meta.embeddable ? this.getEmbeddableDeclOptions() : (this.meta.collection ? this.getEntityDeclOptions() : {})));
|
|
32
|
+
const nameSuffix = this.options.inferEntityType ? '' : 'Schema';
|
|
33
|
+
const declLine = `export const ${this.meta.className + nameSuffix} = ${this.referenceCoreImport('defineEntity')}(`;
|
|
34
|
+
ret += declLine;
|
|
35
|
+
if (this.meta.indexes.length > 0) {
|
|
36
|
+
entitySchemaOptions.indexes = this.meta.indexes.map(index => this.getIndexOptions(index));
|
|
37
|
+
}
|
|
38
|
+
if (this.meta.uniques.length > 0) {
|
|
39
|
+
entitySchemaOptions.uniques = this.meta.uniques.map(index => this.getUniqueOptions(index));
|
|
40
|
+
}
|
|
41
|
+
entitySchemaOptions.properties = Object.fromEntries(Object.entries(this.meta.properties).map(([name, prop]) => [name, this.getPropertyBuilder(prop)]));
|
|
42
|
+
// Force top level and properties to be indented, regardless of line length
|
|
43
|
+
entitySchemaOptions[Config] = true;
|
|
44
|
+
entitySchemaOptions.properties[Config] = true;
|
|
45
|
+
ret += this.serializeObject(entitySchemaOptions, declLine.length > 80 ? undefined : 80 - declLine.length, 0);
|
|
46
|
+
ret += ');\n';
|
|
47
|
+
if (this.options.inferEntityType) {
|
|
48
|
+
ret += `\nexport interface I${this.meta.className} extends ${this.referenceCoreImport('InferEntity')}<typeof ${this.meta.className}> {}\n`;
|
|
49
|
+
}
|
|
50
|
+
ret = `${this.generateImports()}\n\n${ret}`;
|
|
51
|
+
return ret;
|
|
52
|
+
}
|
|
53
|
+
getPropertyBuilder(prop) {
|
|
54
|
+
const options = this.getPropertyOptions(prop, false);
|
|
55
|
+
const p = this.referenceCoreImport('p');
|
|
56
|
+
let builder = '';
|
|
57
|
+
switch (prop.kind) {
|
|
58
|
+
case ReferenceKind.ONE_TO_ONE:
|
|
59
|
+
builder += `() => ${p}.oneToOne(${prop.type})`;
|
|
60
|
+
break;
|
|
61
|
+
case ReferenceKind.ONE_TO_MANY:
|
|
62
|
+
builder += `() => ${p}.oneToMany(${prop.type})`;
|
|
63
|
+
break;
|
|
64
|
+
case ReferenceKind.MANY_TO_ONE:
|
|
65
|
+
builder += `() => ${p}.manyToOne(${prop.type})`;
|
|
66
|
+
break;
|
|
67
|
+
case ReferenceKind.MANY_TO_MANY:
|
|
68
|
+
builder += `() => ${p}.manyToMany(${prop.type})`;
|
|
69
|
+
break;
|
|
70
|
+
case ReferenceKind.EMBEDDED:
|
|
71
|
+
builder += `() => ${p}.embedded(${prop.type})`;
|
|
72
|
+
break;
|
|
73
|
+
case ReferenceKind.SCALAR:
|
|
74
|
+
default: {
|
|
75
|
+
if (options.type && !(options.type in types)) {
|
|
76
|
+
builder += `${p}.type(${options.type})`;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
builder += options.type ? `${p}.${options.type}()` : p;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
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',
|
|
87
|
+
]);
|
|
88
|
+
const skipOptions = new Set(['entity', 'kind', 'type', 'items']);
|
|
89
|
+
const spreadOptions = new Set([
|
|
90
|
+
'fieldNames', 'joinColumns', 'inverseJoinColumns', 'referencedColumnNames', 'ownColumns', 'columnTypes',
|
|
91
|
+
'cascade', 'ignoreSchemaChanges', 'customOrder', 'groups', 'where', 'orderBy',
|
|
92
|
+
]);
|
|
93
|
+
const rename = {
|
|
94
|
+
fieldName: 'name',
|
|
95
|
+
};
|
|
96
|
+
for (const key of Object.keys(options)) {
|
|
97
|
+
if (typeof options[key] === 'undefined' || skipOptions.has(key)) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const method = rename[key] ?? key;
|
|
101
|
+
const params = simpleOptions.has(key) && options[key] === true ? '' : options[key];
|
|
102
|
+
builder += `.${method}`;
|
|
103
|
+
if (key === 'enum') {
|
|
104
|
+
builder += `(${options.items})`;
|
|
105
|
+
}
|
|
106
|
+
else if (spreadOptions.has(key) && typeof params === 'string' && params.startsWith('[')) {
|
|
107
|
+
builder += `(${params.slice(1, -1)})`;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
builder += `(${params})`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return builder;
|
|
114
|
+
}
|
|
115
|
+
}
|
package/EntityGenerator.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type GenerateOptions, type MikroORM } from '@mikro-orm/core';
|
|
2
|
-
import { type EntityManager } from '@mikro-orm/
|
|
2
|
+
import { type EntityManager } from '@mikro-orm/sql';
|
|
3
3
|
export declare class EntityGenerator {
|
|
4
4
|
private readonly em;
|
|
5
5
|
private readonly config;
|
package/EntityGenerator.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DatabaseSchema, } from '@mikro-orm/
|
|
1
|
+
import { EntitySchema, ReferenceKind, types, Utils, } from '@mikro-orm/core';
|
|
2
|
+
import { DatabaseSchema, } from '@mikro-orm/sql';
|
|
3
|
+
import { fs } from '@mikro-orm/core/fs-utils';
|
|
3
4
|
import { dirname, join } from 'node:path';
|
|
4
5
|
import { writeFile } from 'node:fs/promises';
|
|
6
|
+
import { DefineEntitySourceFile } from './DefineEntitySourceFile.js';
|
|
5
7
|
import { EntitySchemaSourceFile } from './EntitySchemaSourceFile.js';
|
|
8
|
+
import { NativeEnumSourceFile } from './NativeEnumSourceFile.js';
|
|
6
9
|
import { SourceFile } from './SourceFile.js';
|
|
7
10
|
export class EntityGenerator {
|
|
8
11
|
em;
|
|
@@ -31,29 +34,41 @@ export class EntityGenerator {
|
|
|
31
34
|
const schema = await DatabaseSchema.create(this.connection, this.platform, this.config, undefined, undefined, options.takeTables, options.skipTables);
|
|
32
35
|
const metadata = await this.getEntityMetadata(schema, options);
|
|
33
36
|
const defaultPath = `${this.config.get('baseDir')}/generated-entities`;
|
|
34
|
-
const baseDir =
|
|
37
|
+
const baseDir = fs.normalizePath(options.path ?? defaultPath);
|
|
38
|
+
this.sources.length = 0;
|
|
39
|
+
const map = {
|
|
40
|
+
defineEntity: DefineEntitySourceFile,
|
|
41
|
+
entitySchema: EntitySchemaSourceFile,
|
|
42
|
+
decorators: SourceFile,
|
|
43
|
+
};
|
|
44
|
+
if (options.entityDefinition !== 'decorators') {
|
|
45
|
+
options.scalarTypeInDecorator = true;
|
|
46
|
+
}
|
|
35
47
|
for (const meta of metadata) {
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
this.sources.push(new EntitySchemaSourceFile(meta, this.namingStrategy, this.platform, { ...options, scalarTypeInDecorator: true }));
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
this.sources.push(new SourceFile(meta, this.namingStrategy, this.platform, options));
|
|
42
|
-
}
|
|
48
|
+
if (meta.pivotTable && !options.outputPurePivotTables && !this.referencedEntities.has(meta)) {
|
|
49
|
+
continue;
|
|
43
50
|
}
|
|
51
|
+
this.sources.push(new map[options.entityDefinition](meta, this.namingStrategy, this.platform, options));
|
|
52
|
+
}
|
|
53
|
+
for (const nativeEnum of Object.values(schema.getNativeEnums())) {
|
|
54
|
+
this.sources.push(new NativeEnumSourceFile({}, this.namingStrategy, this.platform, options, nativeEnum));
|
|
44
55
|
}
|
|
56
|
+
const files = this.sources.map(file => [file.getBaseName(), file.generate()]);
|
|
45
57
|
if (options.save) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
fs.ensureDir(baseDir);
|
|
59
|
+
const promises = [];
|
|
60
|
+
for (const [fileName, data] of files) {
|
|
61
|
+
promises.push((async () => {
|
|
62
|
+
const fileDir = dirname(fileName);
|
|
63
|
+
if (fileDir !== '.') {
|
|
64
|
+
fs.ensureDir(join(baseDir, fileDir));
|
|
65
|
+
}
|
|
66
|
+
await writeFile(join(baseDir, fileName), data, { flush: true });
|
|
67
|
+
})());
|
|
68
|
+
}
|
|
69
|
+
await Promise.all(promises);
|
|
55
70
|
}
|
|
56
|
-
return
|
|
71
|
+
return files.map(([, data]) => data);
|
|
57
72
|
}
|
|
58
73
|
async getEntityMetadata(schema, options) {
|
|
59
74
|
const metadata = schema.getTables()
|
|
@@ -200,7 +215,7 @@ export class EntityGenerator {
|
|
|
200
215
|
inverseJoinColumns: meta.relations[1].fieldNames,
|
|
201
216
|
};
|
|
202
217
|
if (outputPurePivotTables || this.referencedEntities.has(meta)) {
|
|
203
|
-
ownerProp.pivotEntity = meta.
|
|
218
|
+
ownerProp.pivotEntity = meta.class;
|
|
204
219
|
}
|
|
205
220
|
if (fixedOrderColumn) {
|
|
206
221
|
ownerProp.fixedOrder = true;
|
|
@@ -264,20 +279,16 @@ export class EntityGenerator {
|
|
|
264
279
|
}
|
|
265
280
|
}
|
|
266
281
|
generateAndAttachCustomBaseEntity(metadata, customBaseEntityName) {
|
|
267
|
-
let
|
|
282
|
+
let base = metadata.find(meta => meta.className === customBaseEntityName);
|
|
283
|
+
if (!base) {
|
|
284
|
+
const schema = new EntitySchema({ className: customBaseEntityName, abstract: true });
|
|
285
|
+
base = schema.init().meta;
|
|
286
|
+
metadata.push(base);
|
|
287
|
+
}
|
|
268
288
|
for (const meta of metadata) {
|
|
269
|
-
if (meta.className
|
|
270
|
-
|
|
271
|
-
continue;
|
|
289
|
+
if (meta.className !== customBaseEntityName) {
|
|
290
|
+
meta.extends ??= base.class;
|
|
272
291
|
}
|
|
273
|
-
meta.extends ??= customBaseEntityName;
|
|
274
|
-
}
|
|
275
|
-
if (!baseClassExists) {
|
|
276
|
-
metadata.push(new EntityMetadata({
|
|
277
|
-
className: customBaseEntityName,
|
|
278
|
-
abstract: true,
|
|
279
|
-
relations: [],
|
|
280
|
-
}));
|
|
281
292
|
}
|
|
282
293
|
}
|
|
283
294
|
castNullDefaultsToUndefined(metadata) {
|
|
@@ -2,7 +2,8 @@ import { type Dictionary, type EntityProperty } from '@mikro-orm/core';
|
|
|
2
2
|
import { SourceFile } from './SourceFile.js';
|
|
3
3
|
export declare class EntitySchemaSourceFile extends SourceFile {
|
|
4
4
|
generate(): string;
|
|
5
|
-
|
|
5
|
+
protected generateClassDefinition(): string;
|
|
6
|
+
protected getPropertyOptions(prop: EntityProperty, quote?: boolean): Dictionary;
|
|
6
7
|
protected getPropertyIndexesOptions(prop: EntityProperty, options: Dictionary): void;
|
|
7
|
-
protected getScalarPropertyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
|
|
8
|
+
protected getScalarPropertyDecoratorOptions(options: Dictionary, prop: EntityProperty, quote?: boolean): void;
|
|
8
9
|
}
|
|
@@ -2,21 +2,56 @@ import { Config, ReferenceKind, } from '@mikro-orm/core';
|
|
|
2
2
|
import { SourceFile } from './SourceFile.js';
|
|
3
3
|
export class EntitySchemaSourceFile extends SourceFile {
|
|
4
4
|
generate() {
|
|
5
|
+
const classDefinition = this.generateClassDefinition();
|
|
6
|
+
const enumDefinitions = [];
|
|
7
|
+
for (const prop of Object.values(this.meta.properties)) {
|
|
8
|
+
if (prop.enum && (typeof prop.kind === 'undefined' || prop.kind === ReferenceKind.SCALAR)) {
|
|
9
|
+
const def = this.getEnumClassDefinition(prop, 2);
|
|
10
|
+
if (def.length) {
|
|
11
|
+
enumDefinitions.push(def);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
let ret = classDefinition;
|
|
16
|
+
if (enumDefinitions.length) {
|
|
17
|
+
ret += '\n' + enumDefinitions.join('\n');
|
|
18
|
+
}
|
|
19
|
+
ret += `\n`;
|
|
20
|
+
const entitySchemaOptions = {
|
|
21
|
+
class: this.meta.className,
|
|
22
|
+
...(this.meta.embeddable ? this.getEmbeddableDeclOptions() : (this.meta.collection ? this.getEntityDeclOptions() : {})),
|
|
23
|
+
};
|
|
24
|
+
const declLine = `export const ${this.meta.className}Schema = new ${this.referenceCoreImport('EntitySchema')}(`;
|
|
25
|
+
ret += declLine;
|
|
26
|
+
if (this.meta.indexes.length > 0) {
|
|
27
|
+
entitySchemaOptions.indexes = this.meta.indexes.map(index => this.getIndexOptions(index));
|
|
28
|
+
}
|
|
29
|
+
if (this.meta.uniques.length > 0) {
|
|
30
|
+
entitySchemaOptions.uniques = this.meta.uniques.map(index => this.getUniqueOptions(index));
|
|
31
|
+
}
|
|
32
|
+
entitySchemaOptions.properties = Object.fromEntries(Object.entries(this.meta.properties).map(([name, prop]) => [name, this.getPropertyOptions(prop)]));
|
|
33
|
+
// Force top level and properties to be indented, regardless of line length
|
|
34
|
+
entitySchemaOptions[Config] = true;
|
|
35
|
+
entitySchemaOptions.properties[Config] = true;
|
|
36
|
+
ret += this.serializeObject(entitySchemaOptions, declLine.length > 80 ? undefined : 80 - declLine.length, 0);
|
|
37
|
+
ret += ');\n';
|
|
38
|
+
ret = `${this.generateImports()}\n\n${ret}`;
|
|
39
|
+
return ret;
|
|
40
|
+
}
|
|
41
|
+
generateClassDefinition() {
|
|
5
42
|
let classBody = '';
|
|
6
|
-
if (this.meta.className === this.options.customBaseEntityName) {
|
|
43
|
+
if (!this.options.customBaseEntityName || this.meta.className === this.options.customBaseEntityName) {
|
|
7
44
|
const defineConfigTypeSettings = {};
|
|
8
45
|
defineConfigTypeSettings.forceObject = this.platform.getConfig().get('serialization').forceObject ?? false;
|
|
9
|
-
|
|
46
|
+
if (defineConfigTypeSettings.forceObject) {
|
|
47
|
+
classBody += `${' '.repeat(2)}[${this.referenceCoreImport('Config')}]?: ${this.referenceCoreImport('DefineConfig')}<${this.serializeObject(defineConfigTypeSettings)}>;\n`;
|
|
48
|
+
}
|
|
10
49
|
}
|
|
11
|
-
const enumDefinitions = [];
|
|
12
50
|
const eagerProperties = [];
|
|
13
51
|
const primaryProps = [];
|
|
14
52
|
const props = [];
|
|
15
53
|
for (const prop of Object.values(this.meta.properties)) {
|
|
16
54
|
props.push(this.getPropertyDefinition(prop, 2));
|
|
17
|
-
if (prop.enum && (typeof prop.kind === 'undefined' || prop.kind === ReferenceKind.SCALAR)) {
|
|
18
|
-
enumDefinitions.push(this.getEnumClassDefinition(prop, 2));
|
|
19
|
-
}
|
|
20
55
|
if (prop.eager) {
|
|
21
56
|
eagerProperties.push(prop);
|
|
22
57
|
}
|
|
@@ -38,33 +73,9 @@ export class EntitySchemaSourceFile extends SourceFile {
|
|
|
38
73
|
classBody += `${' '.repeat(2)}[${this.referenceCoreImport('EagerProps')}]?: ${eagerPropertyNames.join(' | ')};\n`;
|
|
39
74
|
}
|
|
40
75
|
classBody += `${props.join('')}`;
|
|
41
|
-
|
|
42
|
-
if (enumDefinitions.length) {
|
|
43
|
-
ret += '\n' + enumDefinitions.join('\n');
|
|
44
|
-
}
|
|
45
|
-
ret += `\n`;
|
|
46
|
-
const entitySchemaOptions = {
|
|
47
|
-
class: this.meta.className,
|
|
48
|
-
...(this.meta.embeddable ? this.getEmbeddableDeclOptions() : (this.meta.collection ? this.getEntityDeclOptions() : {})),
|
|
49
|
-
};
|
|
50
|
-
const declLine = `export const ${this.meta.className}Schema = new ${this.referenceCoreImport('EntitySchema')}(`;
|
|
51
|
-
ret += declLine;
|
|
52
|
-
if (this.meta.indexes.length > 0) {
|
|
53
|
-
entitySchemaOptions.indexes = this.meta.indexes.map(index => this.getIndexOptions(index));
|
|
54
|
-
}
|
|
55
|
-
if (this.meta.uniques.length > 0) {
|
|
56
|
-
entitySchemaOptions.uniques = this.meta.uniques.map(index => this.getUniqueOptions(index));
|
|
57
|
-
}
|
|
58
|
-
entitySchemaOptions.properties = Object.fromEntries(Object.entries(this.meta.properties).map(([name, prop]) => [name, this.getPropertyOptions(prop)]));
|
|
59
|
-
// Force top level and properties to be indented, regardless of line length
|
|
60
|
-
entitySchemaOptions[Config] = true;
|
|
61
|
-
entitySchemaOptions.properties[Config] = true;
|
|
62
|
-
ret += this.serializeObject(entitySchemaOptions, declLine.length > 80 ? undefined : 80 - declLine.length, 0);
|
|
63
|
-
ret += ');\n';
|
|
64
|
-
ret = `${this.generateImports()}\n\n${ret}`;
|
|
65
|
-
return ret;
|
|
76
|
+
return this.getEntityClass(classBody);
|
|
66
77
|
}
|
|
67
|
-
getPropertyOptions(prop) {
|
|
78
|
+
getPropertyOptions(prop, quote = true) {
|
|
68
79
|
const options = {};
|
|
69
80
|
if (prop.primary) {
|
|
70
81
|
options.primary = true;
|
|
@@ -79,7 +90,7 @@ export class EntitySchemaSourceFile extends SourceFile {
|
|
|
79
90
|
this.getOneToManyDecoratorOptions(options, prop);
|
|
80
91
|
}
|
|
81
92
|
else if (prop.kind === ReferenceKind.SCALAR || typeof prop.kind === 'undefined') {
|
|
82
|
-
this.getScalarPropertyDecoratorOptions(options, prop);
|
|
93
|
+
this.getScalarPropertyDecoratorOptions(options, prop, quote);
|
|
83
94
|
}
|
|
84
95
|
else if (prop.kind === ReferenceKind.EMBEDDED) {
|
|
85
96
|
this.getEmbeddedPropertyDeclarationOptions(options, prop);
|
|
@@ -123,14 +134,14 @@ export class EntitySchemaSourceFile extends SourceFile {
|
|
|
123
134
|
processIndex('index');
|
|
124
135
|
processIndex('unique');
|
|
125
136
|
}
|
|
126
|
-
getScalarPropertyDecoratorOptions(options, prop) {
|
|
137
|
+
getScalarPropertyDecoratorOptions(options, prop, quote = true) {
|
|
127
138
|
if (prop.enum) {
|
|
128
139
|
options.enum = true;
|
|
129
140
|
options.items = `() => ${prop.runtimeType}`;
|
|
130
141
|
}
|
|
131
142
|
else {
|
|
132
|
-
options.type = this.quote(prop.type);
|
|
143
|
+
options.type = quote ? this.quote(prop.type) : prop.type;
|
|
133
144
|
}
|
|
134
|
-
super.getScalarPropertyDecoratorOptions(options, prop);
|
|
145
|
+
super.getScalarPropertyDecoratorOptions(options, prop, quote);
|
|
135
146
|
}
|
|
136
147
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EntityMetadata, GenerateOptions, NamingStrategy, Platform } from '@mikro-orm/core';
|
|
2
|
+
import { SourceFile } from './SourceFile.js';
|
|
3
|
+
export declare class NativeEnumSourceFile extends SourceFile {
|
|
4
|
+
protected readonly nativeEnum: {
|
|
5
|
+
name: string;
|
|
6
|
+
schema?: string;
|
|
7
|
+
items: string[];
|
|
8
|
+
};
|
|
9
|
+
constructor(meta: EntityMetadata, namingStrategy: NamingStrategy, platform: Platform, options: GenerateOptions, nativeEnum: {
|
|
10
|
+
name: string;
|
|
11
|
+
schema?: string;
|
|
12
|
+
items: string[];
|
|
13
|
+
});
|
|
14
|
+
generate(): string;
|
|
15
|
+
getBaseName(extension?: string): string;
|
|
16
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { identifierRegex, SourceFile } from './SourceFile.js';
|
|
2
|
+
export class NativeEnumSourceFile extends SourceFile {
|
|
3
|
+
nativeEnum;
|
|
4
|
+
constructor(meta, namingStrategy, platform, options, nativeEnum) {
|
|
5
|
+
super(meta, namingStrategy, platform, options);
|
|
6
|
+
this.nativeEnum = nativeEnum;
|
|
7
|
+
}
|
|
8
|
+
generate() {
|
|
9
|
+
const enumClassName = this.namingStrategy.getEnumClassName(this.nativeEnum.name, undefined, this.nativeEnum.schema);
|
|
10
|
+
const enumTypeName = this.namingStrategy.getEnumTypeName(this.nativeEnum.name, undefined, this.nativeEnum.schema);
|
|
11
|
+
const padding = ' ';
|
|
12
|
+
const enumMode = this.options.enumMode;
|
|
13
|
+
const enumValues = this.nativeEnum.items;
|
|
14
|
+
if (enumMode === 'union-type') {
|
|
15
|
+
return `export type ${enumTypeName} = ${enumValues.map(item => this.quote(item)).join(' | ')};\n`;
|
|
16
|
+
}
|
|
17
|
+
let ret = '';
|
|
18
|
+
if (enumMode === 'dictionary') {
|
|
19
|
+
ret += `export const ${enumClassName} = {\n`;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
ret += `export enum ${enumClassName} {\n`;
|
|
23
|
+
}
|
|
24
|
+
for (const enumValue of enumValues) {
|
|
25
|
+
const enumName = this.namingStrategy.enumValueToEnumProperty(enumValue, this.nativeEnum.name, '', this.nativeEnum.schema);
|
|
26
|
+
if (enumMode === 'dictionary') {
|
|
27
|
+
ret += `${padding}${identifierRegex.test(enumName) ? enumName : this.quote(enumName)}: ${this.quote(enumValue)},\n`;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
ret += `${padding}${identifierRegex.test(enumName) ? enumName : this.quote(enumName)} = ${this.quote(enumValue)},\n`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (enumMode === 'dictionary') {
|
|
34
|
+
ret += '} as const;\n';
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
ret += '}\n';
|
|
38
|
+
}
|
|
39
|
+
if (enumMode === 'dictionary') {
|
|
40
|
+
ret += `\nexport type ${enumTypeName} = (typeof ${enumClassName})[keyof typeof ${enumClassName}];\n`;
|
|
41
|
+
}
|
|
42
|
+
return ret;
|
|
43
|
+
}
|
|
44
|
+
getBaseName(extension = '.ts') {
|
|
45
|
+
return `${this.options.fileName(this.nativeEnum.name)}${extension}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
package/README.md
CHANGED
|
@@ -11,7 +11,6 @@ TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-or
|
|
|
11
11
|
[](https://discord.gg/w8bjxFHS7X)
|
|
12
12
|
[](https://www.npmjs.com/package/@mikro-orm/core)
|
|
13
13
|
[](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
|
|
14
|
-
[](https://codeclimate.com/github/mikro-orm/mikro-orm/maintainability)
|
|
15
14
|
[](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
|
|
16
15
|
|
|
17
16
|
## 🤔 Unit of What?
|
|
@@ -141,7 +140,7 @@ There is also auto-generated [CHANGELOG.md](CHANGELOG.md) file based on commit m
|
|
|
141
140
|
- [Composite and Foreign Keys as Primary Key](https://mikro-orm.io/docs/composite-keys)
|
|
142
141
|
- [Filters](https://mikro-orm.io/docs/filters)
|
|
143
142
|
- [Using `QueryBuilder`](https://mikro-orm.io/docs/query-builder)
|
|
144
|
-
- [
|
|
143
|
+
- [Populating relations](https://mikro-orm.io/docs/populating-relations)
|
|
145
144
|
- [Property Validation](https://mikro-orm.io/docs/property-validation)
|
|
146
145
|
- [Lifecycle Hooks](https://mikro-orm.io/docs/events#hooks)
|
|
147
146
|
- [Vanilla JS Support](https://mikro-orm.io/docs/usage-with-js)
|
|
@@ -382,6 +381,8 @@ See also the list of contributors who [participated](https://github.com/mikro-or
|
|
|
382
381
|
|
|
383
382
|
Please ⭐️ this repository if this project helped you!
|
|
384
383
|
|
|
384
|
+
> If you'd like to support my open-source work, consider sponsoring me directly at [github.com/sponsors/b4nan](https://github.com/sponsors/b4nan).
|
|
385
|
+
|
|
385
386
|
## 📝 License
|
|
386
387
|
|
|
387
388
|
Copyright © 2018 [Martin Adámek](https://github.com/b4nan).
|
package/SourceFile.d.ts
CHANGED
|
@@ -9,7 +9,9 @@ export declare class SourceFile {
|
|
|
9
9
|
protected readonly platform: Platform;
|
|
10
10
|
protected readonly options: GenerateOptions;
|
|
11
11
|
protected readonly coreImports: Set<string>;
|
|
12
|
+
protected readonly decoratorImports: Set<string>;
|
|
12
13
|
protected readonly entityImports: Set<string>;
|
|
14
|
+
protected readonly enumImports: Map<string, string[]>;
|
|
13
15
|
constructor(meta: EntityMetadata, namingStrategy: NamingStrategy, platform: Platform, options: GenerateOptions);
|
|
14
16
|
generate(): string;
|
|
15
17
|
protected getIndexOptions(index: EntityMetadata['indexes'][number], isAtEntityLevel?: boolean): IndexOptions<Dictionary, string>;
|
|
@@ -30,11 +32,12 @@ export declare class SourceFile {
|
|
|
30
32
|
protected getCommonDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
|
|
31
33
|
private propTypeBreakdowns;
|
|
32
34
|
private breakdownOfIType;
|
|
33
|
-
protected getScalarPropertyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
|
|
35
|
+
protected getScalarPropertyDecoratorOptions(options: Dictionary, prop: EntityProperty, quote?: boolean): void;
|
|
34
36
|
protected getManyToManyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
|
|
35
37
|
protected getOneToManyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
|
|
36
38
|
protected getEmbeddedPropertyDeclarationOptions(options: Dictionary, prop: EntityProperty): void;
|
|
37
39
|
protected getForeignKeyDecoratorOptions(options: OneToOneOptions<any, any>, prop: EntityProperty): void;
|
|
38
40
|
protected getDecoratorType(prop: EntityProperty): string;
|
|
39
41
|
protected referenceCoreImport(identifier: string): string;
|
|
42
|
+
protected referenceDecoratorImport(identifier: string): string;
|
|
40
43
|
}
|