Is it possible to 'protect' a property and exclude it from select statements

TypeORM goes well with routing-controllers so you should use it, behind the scenes it uses class-transformer to serialize and deserialize your data. So you can use the @Exclude decorator from that library to prevent certain properties being sent down to the clients.

It also uses the class-validator library to validate the data when specifying it as the type in the controller functions. These are powerful toys. Here is a small example of how you can leverage both:

import { Entity, Column, PrimaryGeneratedColumn, Index, OneToMany } from "typeorm";
import { Exclude, Expose } from "class-transformer";
import { IsNotEmpty, IsEmail, MinLength, MaxLength, Min, Max, IsNumber, IsString } from "class-validator";

@Entity()
export class User extends BaseEntity {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  @IsNotEmpty()
  @IsEmail()
  @Index({ unique: true })
  email: string;

  @Exclude()
  @Column()
  passwordHash: string;

  @Column()
  @IsNotEmpty()
  @IsString()
  firstName: string;

  @Column()
  @IsNotEmpty()
  @IsString()
  lastName: string;

  @Column({ type: 'integer', default: Gender.NotSpecified })
  @IsNumber()
  @Min(1)
  @Max(3)
  gender: Gender;


  @Expose()
  get admin() {
    return this.role == Role.Admin;
  }

  @Expose()
  get stylist() {
    return this.role == Role.Stylist;
  }
}

If you use an another server-side library you can still take advantage of class-transformer and class-validator. You just need to call the validate function manually in your routes, for example for restify you can write:

import {validate } from "class-validator";
import {plainToClass} from "class-transformer";
// ... more code

server.post('/hello', function create(req, res, next) {
   let bodyJSON = parseBodyTheWayYouWant(req.body);
   let post = plainToClass(bodyJSON);
   validate(post)
   return next();
});

You can use delete

Exemple Find All users

async findUsers(){
   const users:User[] = await userRepository.find();

    return users.map(user => { 
        delete user.password;
        delete user.salt;
        return user;
    }) ;
}

Exemple Find User By Id

async findUserById(id){
   const user:User = await userRepository.findOne(id);
   delete user.password;
   return user;
}

I think a more accurate answer would be to set select: false on column options:

@Column({ select: false })
password: string;

And explicitly select the column like this:

const user = await getRepository(User)
    .createQueryBuilder()
    .addSelect('password')
    .getOne()

Tags:

Typeorm