export class ReadUserDto {
@IsULID()
@ApiProperty({
example: '01J3Z772NCBMD9BETHBMB74HBW',
description: 'User ULID',
})
userId: string;
}
}
DTO's ULID member is string class like this.
@Entity('users', { schema: 'DB' })
export class Users {
@ApiProperty({
example: '01J3Z772NCBMD9BETHBMB74HBW',
description: 'User ULID',
})
@Column('binary', { primary: true, name: 'user_id', length: 16 })
userId: Buffer;
}
But the entity's ULID member is Buffer class.
I want to use ULID as string class in services.
How and where to add type casting layer for solve this problem simply and quiet less duplicate code?
I tried add method convert to entity class in DTO class. But it violates DTO must not have logical method rule. and it happens to uncomportable use mapped-types.
Or tried to use transform decorator with class-validator. but it always returns null... So I found lots of questions, but there's no example recommend code for class-validator before use transform. Only option is use two validation Pipes, but someone says It does not work as you want.
If you don't need to use the Buffer
-typed value on the entity, you could make it also a string
, and specify a transformer:
in the column options, to convert the TS value to/from a raw database type right in the entity class:
class UlidTransformer implements ValueTransformer {
to(value: string): Buffer {
return Buffer.from(value);
}
from(value: Buffer): string {
return value.toString();
}
}
@Entity('users', { schema: 'DB' })
export class Users {
@ApiProperty({
example: '01J3Z772NCBMD9BETHBMB74HBW',
description: 'User ULID',
})
@Column('binary', { primary: true, name: 'user_id', length: 16, transformer: new UlidTransformer() })
userId: string;
Your idea with class-transformer is also possible to implement, but you'd have to manually call the transformation between the DTO and the entity class -- Nest's validation pipe on its own only applies validations & transformations on the controller method inputs.