• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

typeorm / typeorm / 14796576772

02 May 2025 01:52PM UTC coverage: 45.367% (-30.9%) from 76.309%
14796576772

Pull #11434

github

web-flow
Merge ec4ce2d00 into fadad1a74
Pull Request #11434: feat: release PR releases using pkg.pr.new

5216 of 12761 branches covered (40.87%)

Branch coverage included in aggregate %.

11439 of 23951 relevant lines covered (47.76%)

15712.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.0
/src/entity-schema/EntitySchemaTransformer.ts
1
import { EntitySchema } from "./EntitySchema"
2
import { MetadataArgsStorage } from "../metadata-args/MetadataArgsStorage"
4✔
3
import { TableMetadataArgs } from "../metadata-args/TableMetadataArgs"
4
import { ColumnMetadataArgs } from "../metadata-args/ColumnMetadataArgs"
5
import { IndexMetadataArgs } from "../metadata-args/IndexMetadataArgs"
6
import { RelationMetadataArgs } from "../metadata-args/RelationMetadataArgs"
7
import { JoinColumnMetadataArgs } from "../metadata-args/JoinColumnMetadataArgs"
8
import { JoinTableMetadataArgs } from "../metadata-args/JoinTableMetadataArgs"
9
import { JoinTableOptions } from "../decorator/options/JoinTableOptions"
10
import { JoinTableMultipleColumnsOptions } from "../decorator/options/JoinTableMultipleColumnsOptions"
11
import { ColumnMode } from "../metadata-args/types/ColumnMode"
12
import { GeneratedMetadataArgs } from "../metadata-args/GeneratedMetadataArgs"
13
import { UniqueMetadataArgs } from "../metadata-args/UniqueMetadataArgs"
14
import { CheckMetadataArgs } from "../metadata-args/CheckMetadataArgs"
15
import { ExclusionMetadataArgs } from "../metadata-args/ExclusionMetadataArgs"
16
import { EntitySchemaColumnOptions } from "./EntitySchemaColumnOptions"
17
import { EntitySchemaOptions } from "./EntitySchemaOptions"
18
import { EntitySchemaEmbeddedError } from "./EntitySchemaEmbeddedError"
4✔
19
import { InheritanceMetadataArgs } from "../metadata-args/InheritanceMetadataArgs"
20
import { RelationIdMetadataArgs } from "../metadata-args/RelationIdMetadataArgs"
21
import { ForeignKeyMetadataArgs } from "../metadata-args/ForeignKeyMetadataArgs"
22

23
/**
24
 * Transforms entity schema into metadata args storage.
25
 * The result will be just like entities read from decorators.
26
 */
27
export class EntitySchemaTransformer {
4✔
28
    // -------------------------------------------------------------------------
29
    // Public Methods
30
    // -------------------------------------------------------------------------
31

32
    /**
33
     * Transforms entity schema into new metadata args storage object.
34
     */
35
    transform(schemas: EntitySchema<any>[]): MetadataArgsStorage {
36
        const metadataArgsStorage = new MetadataArgsStorage()
1,856✔
37

38
        schemas.forEach((entitySchema) => {
1,856✔
39
            const options = entitySchema.options
136✔
40

41
            // add table metadata args from the schema
42
            const tableMetadata: TableMetadataArgs = {
136✔
43
                target: options.target || options.name,
207✔
44
                name: options.tableName,
45
                database: options.database,
46
                schema: options.schema,
47
                type: options.type || "regular",
254✔
48
                orderBy: options.orderBy,
49
                synchronize: options.synchronize,
50
                withoutRowid: !!options.withoutRowid,
51
                expression: options.expression,
52
            }
53
            metadataArgsStorage.tables.push(tableMetadata)
136✔
54

55
            const { inheritance } = options
136✔
56

57
            if (inheritance) {
136✔
58
                metadataArgsStorage.inheritances.push({
6✔
59
                    target: options.target,
60
                    pattern: inheritance.pattern ?? "STI",
6!
61
                    column: inheritance.column
6!
62
                        ? typeof inheritance.column === "string"
6!
63
                            ? { name: inheritance.column }
64
                            : inheritance.column
65
                        : undefined,
66
                } as InheritanceMetadataArgs)
67
            }
68

69
            const { discriminatorValue } = options
136✔
70

71
            if (discriminatorValue) {
136✔
72
                metadataArgsStorage.discriminatorValues.push({
6✔
73
                    target: options.target || options.name,
6!
74
                    value: discriminatorValue,
75
                })
76
            }
77

78
            this.transformColumnsRecursive(options, metadataArgsStorage)
136✔
79
        })
80

81
        return metadataArgsStorage
1,856✔
82
    }
83

84
    private transformColumnsRecursive(
85
        options: EntitySchemaOptions<any>,
86
        metadataArgsStorage: MetadataArgsStorage,
87
    ): void {
88
        // add columns metadata args from the schema
89
        Object.keys(options.columns).forEach((columnName) => {
148✔
90
            const column = options.columns[columnName]!
413✔
91

92
            const regularColumn = column as EntitySchemaColumnOptions
413✔
93
            let mode: ColumnMode = "regular"
413✔
94
            if (regularColumn.createDate) mode = "createDate"
413✔
95
            if (regularColumn.updateDate) mode = "updateDate"
413✔
96
            if (regularColumn.deleteDate) mode = "deleteDate"
413!
97
            if (regularColumn.version) mode = "version"
413!
98
            if (regularColumn.treeChildrenCount) mode = "treeChildrenCount"
413!
99
            if (regularColumn.treeLevel) mode = "treeLevel"
413!
100
            if (regularColumn.objectId) mode = "objectId"
413!
101

102
            const columnArgs: ColumnMetadataArgs = {
413✔
103
                target: options.target || options.name,
592✔
104
                mode: mode,
105
                propertyName: columnName,
106
                options: {
107
                    type: regularColumn.type,
108
                    name: regularColumn.objectId ? "_id" : regularColumn.name,
413!
109
                    primaryKeyConstraintName:
110
                        regularColumn.primaryKeyConstraintName,
111
                    length: regularColumn.length,
112
                    width: regularColumn.width,
113
                    nullable: regularColumn.nullable,
114
                    readonly: regularColumn.readonly,
115
                    update: regularColumn.update,
116
                    select: regularColumn.select,
117
                    insert: regularColumn.insert,
118
                    primary: regularColumn.primary,
119
                    unique: regularColumn.unique,
120
                    comment: regularColumn.comment,
121
                    default: regularColumn.default,
122
                    onUpdate: regularColumn.onUpdate,
123
                    precision: regularColumn.precision,
124
                    scale: regularColumn.scale,
125
                    zerofill: regularColumn.zerofill,
126
                    unsigned: regularColumn.unsigned,
127
                    charset: regularColumn.charset,
128
                    collation: regularColumn.collation,
129
                    enum: regularColumn.enum,
130
                    enumName: regularColumn.enumName,
131
                    asExpression: regularColumn.asExpression,
132
                    generatedType: regularColumn.generatedType,
133
                    hstoreType: regularColumn.hstoreType,
134
                    array: regularColumn.array,
135
                    transformer: regularColumn.transformer,
136
                    spatialFeatureType: regularColumn.spatialFeatureType,
137
                    srid: regularColumn.srid,
138
                },
139
            }
140
            metadataArgsStorage.columns.push(columnArgs)
413✔
141

142
            if (regularColumn.generated) {
413✔
143
                const generationArgs: GeneratedMetadataArgs = {
81✔
144
                    target: options.target || options.name,
122✔
145
                    propertyName: columnName,
146
                    strategy:
147
                        typeof regularColumn.generated === "string"
81✔
148
                            ? regularColumn.generated
149
                            : "increment",
150
                }
151
                metadataArgsStorage.generations.push(generationArgs)
81✔
152
            }
153

154
            if (regularColumn.unique)
413✔
155
                metadataArgsStorage.uniques.push({
8✔
156
                    target: options.target || options.name,
12✔
157
                    columns: [columnName],
158
                })
159

160
            if (regularColumn.foreignKey) {
413✔
161
                const foreignKey = regularColumn.foreignKey
16✔
162

163
                const foreignKeyArgs: ForeignKeyMetadataArgs = {
16✔
164
                    target: options.target || options.name,
32✔
165
                    type: foreignKey.target,
166
                    propertyName: columnName,
167
                    inverseSide: foreignKey.inverseSide,
168
                    name: foreignKey.name,
169
                    onDelete: foreignKey.onDelete,
170
                    onUpdate: foreignKey.onUpdate,
171
                    deferrable: foreignKey.deferrable,
172
                }
173
                metadataArgsStorage.foreignKeys.push(foreignKeyArgs)
16✔
174
            }
175
        })
176

177
        // add relation metadata args from the schema
178
        if (options.relations) {
148✔
179
            Object.keys(options.relations).forEach((relationName) => {
31✔
180
                const relationSchema = options.relations![relationName]!
44✔
181
                const relation: RelationMetadataArgs = {
44✔
182
                    target: options.target || options.name,
68✔
183
                    propertyName: relationName,
184
                    relationType: relationSchema.type,
185
                    isLazy: relationSchema.lazy || false,
88✔
186
                    type: relationSchema.target,
187
                    inverseSideProperty: relationSchema.inverseSide,
188
                    isTreeParent: relationSchema.treeParent,
189
                    isTreeChildren: relationSchema.treeChildren,
190
                    options: {
191
                        eager: relationSchema.eager || false,
80✔
192
                        cascade: relationSchema.cascade,
193
                        nullable: relationSchema.nullable,
194
                        onDelete: relationSchema.onDelete,
195
                        onUpdate: relationSchema.onUpdate,
196
                        deferrable: relationSchema.deferrable,
197
                        // primary: relationSchema.primary,
198
                        createForeignKeyConstraints:
199
                            relationSchema.createForeignKeyConstraints,
200
                        persistence: relationSchema.persistence,
201
                        orphanedRowAction: relationSchema.orphanedRowAction,
202
                    },
203
                }
204

205
                metadataArgsStorage.relations.push(relation)
44✔
206

207
                // add join column
208
                if (relationSchema.joinColumn) {
44✔
209
                    if (typeof relationSchema.joinColumn === "boolean") {
21!
210
                        const joinColumn: JoinColumnMetadataArgs = {
×
211
                            target: options.target || options.name,
×
212
                            propertyName: relationName,
213
                        }
214
                        metadataArgsStorage.joinColumns.push(joinColumn)
×
215
                    } else {
216
                        const joinColumnsOptions = Array.isArray(
21✔
217
                            relationSchema.joinColumn,
218
                        )
219
                            ? relationSchema.joinColumn
220
                            : [relationSchema.joinColumn]
221

222
                        for (const joinColumnOption of joinColumnsOptions) {
21✔
223
                            const joinColumn: JoinColumnMetadataArgs = {
26✔
224
                                target: options.target || options.name,
42✔
225
                                propertyName: relationName,
226
                                name: joinColumnOption.name,
227
                                referencedColumnName:
228
                                    joinColumnOption.referencedColumnName,
229
                                foreignKeyConstraintName:
230
                                    joinColumnOption.foreignKeyConstraintName,
231
                            }
232
                            metadataArgsStorage.joinColumns.push(joinColumn)
26✔
233
                        }
234
                    }
235
                }
236

237
                // add join table
238
                if (relationSchema.joinTable) {
44✔
239
                    if (typeof relationSchema.joinTable === "boolean") {
8✔
240
                        const joinTable: JoinTableMetadataArgs = {
4✔
241
                            target: options.target || options.name,
8✔
242
                            propertyName: relationName,
243
                        }
244
                        metadataArgsStorage.joinTables.push(joinTable)
4✔
245
                    } else {
246
                        const joinTable: JoinTableMetadataArgs = {
4✔
247
                            target: options.target || options.name,
8✔
248
                            propertyName: relationName,
249
                            name: relationSchema.joinTable.name,
250
                            database: relationSchema.joinTable.database,
251
                            schema: relationSchema.joinTable.schema,
252
                            joinColumns: ((
253
                                relationSchema.joinTable as JoinTableOptions
4!
254
                            ).joinColumn
255
                                ? [
256
                                      (
257
                                          relationSchema.joinTable as JoinTableOptions
258
                                      ).joinColumn!,
259
                                  ]
260
                                : (
261
                                      relationSchema.joinTable as JoinTableMultipleColumnsOptions
262
                                  ).joinColumns) as any,
263
                            inverseJoinColumns: ((
264
                                relationSchema.joinTable as JoinTableOptions
4!
265
                            ).inverseJoinColumn
266
                                ? [
267
                                      (
268
                                          relationSchema.joinTable as JoinTableOptions
269
                                      ).inverseJoinColumn!,
270
                                  ]
271
                                : (
272
                                      relationSchema.joinTable as JoinTableMultipleColumnsOptions
273
                                  ).inverseJoinColumns) as any,
274
                        }
275
                        metadataArgsStorage.joinTables.push(joinTable)
4✔
276
                    }
277
                }
278
            })
279
        }
280

281
        // add relation id metadata args from the schema
282
        if (options.relationIds) {
148!
283
            Object.keys(options.relationIds).forEach((relationIdName) => {
×
284
                const relationIdOptions = options.relationIds![relationIdName]!
×
285
                const relationId: RelationIdMetadataArgs = {
×
286
                    propertyName: relationIdName,
287
                    relation: relationIdOptions.relationName,
288
                    target: options.target || options.name,
×
289
                    alias: relationIdOptions.alias,
290
                    queryBuilderFactory: relationIdOptions.queryBuilderFactory,
291
                }
292
                metadataArgsStorage.relationIds.push(relationId)
×
293
            })
294
        }
295

296
        // add index metadata args from the schema
297
        if (options.indices) {
148✔
298
            options.indices.forEach((index) => {
20✔
299
                const indexArgs: IndexMetadataArgs = {
24✔
300
                    target: options.target || options.name,
40✔
301
                    name: index.name,
302
                    unique: index.unique === true ? true : false,
24!
303
                    spatial: index.spatial === true ? true : false,
24!
304
                    fulltext: index.fulltext === true ? true : false,
24!
305
                    nullFiltered: index.nullFiltered === true ? true : false,
24!
306
                    parser: index.parser,
307
                    synchronize: index.synchronize === false ? false : true,
24!
308
                    where: index.where,
309
                    sparse: index.sparse,
310
                    columns: index.columns,
311
                }
312
                metadataArgsStorage.indices.push(indexArgs)
24✔
313
            })
314
        }
315

316
        if (options.foreignKeys) {
148✔
317
            options.foreignKeys.forEach((foreignKey) => {
4✔
318
                const foreignKeyArgs: ForeignKeyMetadataArgs = {
4✔
319
                    target: options.target || options.name,
8✔
320
                    type: foreignKey.target,
321
                    columnNames: foreignKey.columnNames,
322
                    referencedColumnNames: foreignKey.referencedColumnNames,
323
                    name: foreignKey.name,
324
                    onDelete: foreignKey.onDelete,
325
                    onUpdate: foreignKey.onUpdate,
326
                    deferrable: foreignKey.deferrable,
327
                }
328
                metadataArgsStorage.foreignKeys.push(foreignKeyArgs)
4✔
329
            })
330
        }
331

332
        // add unique metadata args from the schema
333
        if (options.uniques) {
148✔
334
            options.uniques.forEach((unique) => {
12✔
335
                const uniqueArgs: UniqueMetadataArgs = {
12✔
336
                    target: options.target || options.name,
24✔
337
                    name: unique.name,
338
                    columns: unique.columns,
339
                    deferrable: unique.deferrable,
340
                }
341
                metadataArgsStorage.uniques.push(uniqueArgs)
12✔
342
            })
343
        }
344

345
        // add check metadata args from the schema
346
        if (options.checks) {
148✔
347
            options.checks.forEach((check) => {
1✔
348
                const checkArgs: CheckMetadataArgs = {
2✔
349
                    target: options.target || options.name,
4✔
350
                    name: check.name,
351
                    expression: check.expression,
352
                }
353
                metadataArgsStorage.checks.push(checkArgs)
2✔
354
            })
355
        }
356

357
        // add exclusion metadata args from the schema
358
        if (options.exclusions) {
148!
359
            options.exclusions.forEach((exclusion) => {
×
360
                const exclusionArgs: ExclusionMetadataArgs = {
×
361
                    target: options.target || options.name,
×
362
                    name: exclusion.name,
363
                    expression: exclusion.expression,
364
                }
365
                metadataArgsStorage.exclusions.push(exclusionArgs)
×
366
            })
367
        }
368

369
        if (options.embeddeds) {
148✔
370
            Object.keys(options.embeddeds).forEach((columnName) => {
12✔
371
                const embeddedOptions = options.embeddeds![columnName]
12✔
372

373
                if (!embeddedOptions.schema)
12!
374
                    throw EntitySchemaEmbeddedError.createEntitySchemaIsRequiredException(
×
375
                        columnName,
376
                    )
377

378
                const embeddedSchema = embeddedOptions.schema.options
12✔
379

380
                metadataArgsStorage.embeddeds.push({
12✔
381
                    target: options.target || options.name,
16✔
382
                    propertyName: columnName,
383
                    isArray: embeddedOptions.array === true,
384
                    prefix:
385
                        embeddedOptions.prefix !== undefined
12!
386
                            ? embeddedOptions.prefix
387
                            : undefined,
388
                    type: () => embeddedSchema?.target || embeddedSchema.name,
12✔
389
                })
390

391
                this.transformColumnsRecursive(
12✔
392
                    embeddedSchema,
393
                    metadataArgsStorage,
394
                )
395
            })
396
        }
397
    }
398
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc