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

typeorm / typeorm / 15219332477

23 May 2025 09:13PM UTC coverage: 17.216% (-59.1%) from 76.346%
15219332477

Pull #11332

github

naorpeled
cr comments - move if block
Pull Request #11332: feat: add new undefined and null behavior flags

1603 of 12759 branches covered (12.56%)

Branch coverage included in aggregate %.

0 of 31 new or added lines in 3 files covered. (0.0%)

14132 existing lines in 166 files now uncovered.

4731 of 24033 relevant lines covered (19.69%)

60.22 hits per line

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

38.95
/src/entity-schema/EntitySchemaTransformer.ts
1
import { EntitySchema } from "./EntitySchema"
2
import { MetadataArgsStorage } from "../metadata-args/MetadataArgsStorage"
1✔
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"
1✔
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 {
1✔
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()
43✔
37

38
        schemas.forEach((entitySchema) => {
43✔
39
            const options = entitySchema.options
4✔
40

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

55
            const { inheritance } = options
4✔
56

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

69
            const { discriminatorValue } = options
4✔
70

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

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

81
        return metadataArgsStorage
43✔
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) => {
4✔
90
            const column = options.columns[columnName]!
11✔
91

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

102
            const columnArgs: ColumnMetadataArgs = {
11✔
103
                target: options.target || options.name,
15✔
104
                mode: mode,
105
                propertyName: columnName,
106
                options: {
107
                    type: regularColumn.type,
108
                    name: regularColumn.objectId ? "_id" : regularColumn.name,
11✔
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)
11✔
141

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

154
            if (regularColumn.unique)
11!
UNCOV
155
                metadataArgsStorage.uniques.push({
×
156
                    target: options.target || options.name,
×
157
                    columns: [columnName],
158
                })
159

160
            if (regularColumn.foreignKey) {
11!
UNCOV
161
                const foreignKey = regularColumn.foreignKey
×
162

UNCOV
163
                const foreignKeyArgs: ForeignKeyMetadataArgs = {
×
164
                    target: options.target || options.name,
×
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
                }
UNCOV
173
                metadataArgsStorage.foreignKeys.push(foreignKeyArgs)
×
174
            }
175
        })
176

177
        // add relation metadata args from the schema
178
        if (options.relations) {
4✔
179
            Object.keys(options.relations).forEach((relationName) => {
2✔
180
                const relationSchema = options.relations![relationName]!
2✔
181
                const relation: RelationMetadataArgs = {
2✔
182
                    target: options.target || options.name,
2!
183
                    propertyName: relationName,
184
                    relationType: relationSchema.type,
185
                    isLazy: relationSchema.lazy || false,
4✔
186
                    type: relationSchema.target,
187
                    inverseSideProperty: relationSchema.inverseSide,
188
                    isTreeParent: relationSchema.treeParent,
189
                    isTreeChildren: relationSchema.treeChildren,
190
                    options: {
191
                        eager: relationSchema.eager || false,
3✔
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)
2✔
206

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

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

237
                // add join table
238
                if (relationSchema.joinTable) {
2!
UNCOV
239
                    if (typeof relationSchema.joinTable === "boolean") {
×
UNCOV
240
                        const joinTable: JoinTableMetadataArgs = {
×
241
                            target: options.target || options.name,
×
242
                            propertyName: relationName,
243
                        }
UNCOV
244
                        metadataArgsStorage.joinTables.push(joinTable)
×
245
                    } else {
UNCOV
246
                        const joinTable: JoinTableMetadataArgs = {
×
247
                            target: options.target || options.name,
×
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
×
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
×
265
                            ).inverseJoinColumn
266
                                ? [
267
                                      (
268
                                          relationSchema.joinTable as JoinTableOptions
269
                                      ).inverseJoinColumn!,
270
                                  ]
271
                                : (
272
                                      relationSchema.joinTable as JoinTableMultipleColumnsOptions
273
                                  ).inverseJoinColumns) as any,
274
                        }
UNCOV
275
                        metadataArgsStorage.joinTables.push(joinTable)
×
276
                    }
277
                }
278
            })
279
        }
280

281
        // add relation id metadata args from the schema
282
        if (options.relationIds) {
4!
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) {
4!
UNCOV
298
            options.indices.forEach((index) => {
×
UNCOV
299
                const indexArgs: IndexMetadataArgs = {
×
300
                    target: options.target || options.name,
×
301
                    name: index.name,
302
                    unique: index.unique === true ? true : false,
×
303
                    spatial: index.spatial === true ? true : false,
×
304
                    fulltext: index.fulltext === true ? true : false,
×
305
                    nullFiltered: index.nullFiltered === true ? true : false,
×
306
                    parser: index.parser,
307
                    synchronize: index.synchronize === false ? false : true,
×
308
                    where: index.where,
309
                    sparse: index.sparse,
310
                    columns: index.columns,
311
                }
UNCOV
312
                metadataArgsStorage.indices.push(indexArgs)
×
313
            })
314
        }
315

316
        if (options.foreignKeys) {
4!
UNCOV
317
            options.foreignKeys.forEach((foreignKey) => {
×
UNCOV
318
                const foreignKeyArgs: ForeignKeyMetadataArgs = {
×
319
                    target: options.target || options.name,
×
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
                }
UNCOV
328
                metadataArgsStorage.foreignKeys.push(foreignKeyArgs)
×
329
            })
330
        }
331

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

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

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

369
        if (options.embeddeds) {
4!
UNCOV
370
            Object.keys(options.embeddeds).forEach((columnName) => {
×
UNCOV
371
                const embeddedOptions = options.embeddeds![columnName]
×
372

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

UNCOV
378
                const embeddedSchema = embeddedOptions.schema.options
×
379

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

UNCOV
391
                this.transformColumnsRecursive(
×
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