@mikro-orm/entity-generator 7.0.0-dev.33 → 7.0.0-dev.331
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 +146 -0
- package/EntityGenerator.d.ts +3 -10
- package/EntityGenerator.js +161 -76
- package/EntitySchemaSourceFile.d.ts +3 -2
- package/EntitySchemaSourceFile.js +53 -38
- package/NativeEnumSourceFile.d.ts +12 -0
- package/NativeEnumSourceFile.js +47 -0
- package/README.md +7 -4
- package/SourceFile.d.ts +9 -2
- package/SourceFile.js +307 -112
- package/package.json +32 -32
|
@@ -2,21 +2,60 @@ 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
|
|
23
|
+
? this.getEmbeddableDeclOptions()
|
|
24
|
+
: this.meta.collection
|
|
25
|
+
? this.getEntityDeclOptions()
|
|
26
|
+
: {}),
|
|
27
|
+
};
|
|
28
|
+
const declLine = `export const ${this.meta.className}Schema = new ${this.referenceCoreImport('EntitySchema')}(`;
|
|
29
|
+
ret += declLine;
|
|
30
|
+
if (this.meta.indexes.length > 0) {
|
|
31
|
+
entitySchemaOptions.indexes = this.meta.indexes.map(index => this.getIndexOptions(index));
|
|
32
|
+
}
|
|
33
|
+
if (this.meta.uniques.length > 0) {
|
|
34
|
+
entitySchemaOptions.uniques = this.meta.uniques.map(index => this.getUniqueOptions(index));
|
|
35
|
+
}
|
|
36
|
+
entitySchemaOptions.properties = Object.fromEntries(Object.entries(this.meta.properties).map(([name, prop]) => [name, this.getPropertyOptions(prop)]));
|
|
37
|
+
// Force top level and properties to be indented, regardless of line length
|
|
38
|
+
entitySchemaOptions[Config] = true;
|
|
39
|
+
entitySchemaOptions.properties[Config] = true;
|
|
40
|
+
ret += this.serializeObject(entitySchemaOptions, declLine.length > 80 ? undefined : 80 - declLine.length, 0);
|
|
41
|
+
ret += ');\n';
|
|
42
|
+
ret = `${this.generateImports()}\n\n${ret}`;
|
|
43
|
+
return ret;
|
|
44
|
+
}
|
|
45
|
+
generateClassDefinition() {
|
|
5
46
|
let classBody = '';
|
|
6
|
-
if (this.meta.className === this.options.customBaseEntityName) {
|
|
47
|
+
if (!this.options.customBaseEntityName || this.meta.className === this.options.customBaseEntityName) {
|
|
7
48
|
const defineConfigTypeSettings = {};
|
|
8
49
|
defineConfigTypeSettings.forceObject = this.platform.getConfig().get('serialization').forceObject ?? false;
|
|
9
|
-
|
|
50
|
+
if (defineConfigTypeSettings.forceObject) {
|
|
51
|
+
classBody += `${' '.repeat(2)}[${this.referenceCoreImport('Config')}]?: ${this.referenceCoreImport('DefineConfig')}<${this.serializeObject(defineConfigTypeSettings)}>;\n`;
|
|
52
|
+
}
|
|
10
53
|
}
|
|
11
|
-
const enumDefinitions = [];
|
|
12
54
|
const eagerProperties = [];
|
|
13
55
|
const primaryProps = [];
|
|
14
56
|
const props = [];
|
|
15
57
|
for (const prop of Object.values(this.meta.properties)) {
|
|
16
58
|
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
59
|
if (prop.eager) {
|
|
21
60
|
eagerProperties.push(prop);
|
|
22
61
|
}
|
|
@@ -37,34 +76,10 @@ export class EntitySchemaSourceFile extends SourceFile {
|
|
|
37
76
|
const eagerPropertyNames = eagerProperties.map(prop => `'${prop.name}'`).sort();
|
|
38
77
|
classBody += `${' '.repeat(2)}[${this.referenceCoreImport('EagerProps')}]?: ${eagerPropertyNames.join(' | ')};\n`;
|
|
39
78
|
}
|
|
40
|
-
classBody +=
|
|
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;
|
|
79
|
+
classBody += props.join('');
|
|
80
|
+
return this.getEntityClass(classBody);
|
|
66
81
|
}
|
|
67
|
-
getPropertyOptions(prop) {
|
|
82
|
+
getPropertyOptions(prop, quote = true) {
|
|
68
83
|
const options = {};
|
|
69
84
|
if (prop.primary) {
|
|
70
85
|
options.primary = true;
|
|
@@ -79,7 +94,7 @@ export class EntitySchemaSourceFile extends SourceFile {
|
|
|
79
94
|
this.getOneToManyDecoratorOptions(options, prop);
|
|
80
95
|
}
|
|
81
96
|
else if (prop.kind === ReferenceKind.SCALAR || typeof prop.kind === 'undefined') {
|
|
82
|
-
this.getScalarPropertyDecoratorOptions(options, prop);
|
|
97
|
+
this.getScalarPropertyDecoratorOptions(options, prop, quote);
|
|
83
98
|
}
|
|
84
99
|
else if (prop.kind === ReferenceKind.EMBEDDED) {
|
|
85
100
|
this.getEmbeddedPropertyDeclarationOptions(options, prop);
|
|
@@ -111,7 +126,7 @@ export class EntitySchemaSourceFile extends SourceFile {
|
|
|
111
126
|
}
|
|
112
127
|
const defaultName = this.platform.getIndexName(this.meta.collection, prop.fieldNames, type);
|
|
113
128
|
/* v8 ignore next */
|
|
114
|
-
options[type] =
|
|
129
|
+
options[type] = propType === true || defaultName === propType ? 'true' : this.quote(propType);
|
|
115
130
|
const expected = {
|
|
116
131
|
index: this.platform.indexForeignKeys(),
|
|
117
132
|
unique: prop.kind === ReferenceKind.ONE_TO_ONE,
|
|
@@ -123,14 +138,14 @@ export class EntitySchemaSourceFile extends SourceFile {
|
|
|
123
138
|
processIndex('index');
|
|
124
139
|
processIndex('unique');
|
|
125
140
|
}
|
|
126
|
-
getScalarPropertyDecoratorOptions(options, prop) {
|
|
141
|
+
getScalarPropertyDecoratorOptions(options, prop, quote = true) {
|
|
127
142
|
if (prop.enum) {
|
|
128
143
|
options.enum = true;
|
|
129
144
|
options.items = `() => ${prop.runtimeType}`;
|
|
130
145
|
}
|
|
131
146
|
else {
|
|
132
|
-
options.type = this.quote(prop.type);
|
|
147
|
+
options.type = quote ? this.quote(prop.type) : prop.type;
|
|
133
148
|
}
|
|
134
|
-
super.getScalarPropertyDecoratorOptions(options, prop);
|
|
149
|
+
super.getScalarPropertyDecoratorOptions(options, prop, quote);
|
|
135
150
|
}
|
|
136
151
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
private readonly nativeEnum;
|
|
5
|
+
constructor(meta: EntityMetadata, namingStrategy: NamingStrategy, platform: Platform, options: GenerateOptions, nativeEnum: {
|
|
6
|
+
name: string;
|
|
7
|
+
schema?: string;
|
|
8
|
+
items: string[];
|
|
9
|
+
});
|
|
10
|
+
generate(): string;
|
|
11
|
+
getBaseName(extension?: string): string;
|
|
12
|
+
}
|
|
@@ -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
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
<a href="https://mikro-orm.io"><img src="https://raw.githubusercontent.com/mikro-orm/mikro-orm/master/docs/static/img/logo-readme.svg?sanitize=true" alt="MikroORM" /></a>
|
|
3
3
|
</h1>
|
|
4
4
|
|
|
5
|
-
TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL
|
|
5
|
+
TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL, SQLite (including libSQL), MSSQL and Oracle databases.
|
|
6
6
|
|
|
7
7
|
> Heavily inspired by [Doctrine](https://www.doctrine-project.org/) and [Hibernate](https://hibernate.org/).
|
|
8
8
|
|
|
9
|
-
[](https://
|
|
10
|
-
[](https://
|
|
9
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
10
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
11
11
|
[](https://discord.gg/w8bjxFHS7X)
|
|
12
|
-
[](https://
|
|
12
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
13
13
|
[](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
|
|
14
14
|
[](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
|
|
15
15
|
|
|
@@ -181,6 +181,7 @@ yarn add @mikro-orm/core @mikro-orm/mysql # for mysql/mariadb
|
|
|
181
181
|
yarn add @mikro-orm/core @mikro-orm/mariadb # for mysql/mariadb
|
|
182
182
|
yarn add @mikro-orm/core @mikro-orm/postgresql # for postgresql
|
|
183
183
|
yarn add @mikro-orm/core @mikro-orm/mssql # for mssql
|
|
184
|
+
yarn add @mikro-orm/core @mikro-orm/oracledb # for oracle
|
|
184
185
|
yarn add @mikro-orm/core @mikro-orm/sqlite # for sqlite
|
|
185
186
|
yarn add @mikro-orm/core @mikro-orm/libsql # for libsql
|
|
186
187
|
```
|
|
@@ -381,6 +382,8 @@ See also the list of contributors who [participated](https://github.com/mikro-or
|
|
|
381
382
|
|
|
382
383
|
Please ⭐️ this repository if this project helped you!
|
|
383
384
|
|
|
385
|
+
> If you'd like to support my open-source work, consider sponsoring me directly at [github.com/sponsors/b4nan](https://github.com/sponsors/b4nan).
|
|
386
|
+
|
|
384
387
|
## 📝 License
|
|
385
388
|
|
|
386
389
|
Copyright © 2018 [Martin Adámek](https://github.com/b4nan).
|
package/SourceFile.d.ts
CHANGED
|
@@ -4,14 +4,21 @@ import { type Dictionary, type EmbeddableOptions, type EntityMetadata, type Enti
|
|
|
4
4
|
*/
|
|
5
5
|
export declare const identifierRegex: RegExp;
|
|
6
6
|
export declare class SourceFile {
|
|
7
|
+
#private;
|
|
7
8
|
protected readonly meta: EntityMetadata;
|
|
8
9
|
protected readonly namingStrategy: NamingStrategy;
|
|
9
10
|
protected readonly platform: Platform;
|
|
10
11
|
protected readonly options: GenerateOptions;
|
|
11
12
|
protected readonly coreImports: Set<string>;
|
|
13
|
+
protected readonly decoratorImports: Set<string>;
|
|
12
14
|
protected readonly entityImports: Set<string>;
|
|
15
|
+
protected readonly enumImports: Map<string, string[]>;
|
|
13
16
|
constructor(meta: EntityMetadata, namingStrategy: NamingStrategy, platform: Platform, options: GenerateOptions);
|
|
14
17
|
generate(): string;
|
|
18
|
+
/**
|
|
19
|
+
* Convert index column options to quoted output format.
|
|
20
|
+
*/
|
|
21
|
+
private getColumnOptions;
|
|
15
22
|
protected getIndexOptions(index: EntityMetadata['indexes'][number], isAtEntityLevel?: boolean): IndexOptions<Dictionary, string>;
|
|
16
23
|
protected getUniqueOptions(index: EntityMetadata['uniques'][number], isAtEntityLevel?: boolean): UniqueOptions<Dictionary, string>;
|
|
17
24
|
protected generateImports(): string;
|
|
@@ -28,13 +35,13 @@ export declare class SourceFile {
|
|
|
28
35
|
private getPropertyDecorator;
|
|
29
36
|
protected getPropertyIndexes(prop: EntityProperty, options: Dictionary): string[];
|
|
30
37
|
protected getCommonDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
|
|
31
|
-
private propTypeBreakdowns;
|
|
32
38
|
private breakdownOfIType;
|
|
33
|
-
protected getScalarPropertyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
|
|
39
|
+
protected getScalarPropertyDecoratorOptions(options: Dictionary, prop: EntityProperty, quote?: boolean): void;
|
|
34
40
|
protected getManyToManyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
|
|
35
41
|
protected getOneToManyDecoratorOptions(options: Dictionary, prop: EntityProperty): void;
|
|
36
42
|
protected getEmbeddedPropertyDeclarationOptions(options: Dictionary, prop: EntityProperty): void;
|
|
37
43
|
protected getForeignKeyDecoratorOptions(options: OneToOneOptions<any, any>, prop: EntityProperty): void;
|
|
38
44
|
protected getDecoratorType(prop: EntityProperty): string;
|
|
39
45
|
protected referenceCoreImport(identifier: string): string;
|
|
46
|
+
protected referenceDecoratorImport(identifier: string): string;
|
|
40
47
|
}
|