File size: 3,086 Bytes
d76f93d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { ValidationError } from "../utils/apiErrors";
import { CreateBookRequest, Genre } from "../models/Book";

const minStrLength = 2;
const maxStrLength = 100;
const maxPages = 10000;

export class BookValidator {
  static validate(body: Partial<CreateBookRequest>): void {
    this.validateAuthor(body.author);
    this.validateTitle(body.title);
    this.validatePages(body.pages);
    this.validateYear(body.year);
    this.validateGenre(body.genre);
  }

  static validateForUpdate(body: Partial<CreateBookRequest>): void {
    if (body.author !== undefined) {
      this.validateAuthor(body.author);
    }
    if (body.title !== undefined) {
      this.validateTitle(body.title);
    }
    if (body.pages !== undefined) {
      this.validatePages(body.pages);
    }
    if (body.year !== undefined) {
      this.validateYear(body.year);
    }
    if (body.genre !== undefined) {
      this.validateGenre(body.genre);
    }
  }

  private static validateAuthor(author: string | undefined): void {
    if (!author || author.trim().length === 0) {
      throw new ValidationError("Author is required");
    }

    if (author.trim().length < minStrLength) {
      throw new ValidationError(`Author must be at least ${minStrLength} characters`);
    }

    if (author.length > maxStrLength) {
      throw new ValidationError(`Author must be at most ${maxStrLength} characters`);
    }
  }

  private static validateTitle(title: string | undefined): void {
    if (!title || title.trim().length === 0) {
      throw new ValidationError("Title is required");
    }

    if (title.trim().length < minStrLength) {
      throw new ValidationError(`Title must be at least ${minStrLength} characters`);
    }

    if (title.length > maxStrLength) {
      throw new ValidationError(`Title must be at most ${maxStrLength} characters`);
    }
  }

  private static validatePages(pages: number | undefined): void {
    if (pages === undefined || pages === null) {
      throw new ValidationError("Pages is required");
    }

    if (!Number.isInteger(pages)) {
      throw new ValidationError("Pages must be an integer");
    }

    if (pages < 1) {
      throw new ValidationError("Pages must be at least 1");
    }

    if (pages > maxPages) {
      throw new ValidationError(`Pages must be at most ${maxPages}`);
    }
  }

  private static validateYear(year: number | undefined): void {
    if (year === undefined || year === null) {
      throw new ValidationError("Year is required");
    }

    if (!Number.isInteger(year)) {
      throw new ValidationError("Year must be an integer");
    }

    const currentYear = new Date().getFullYear();
    if (year > currentYear) {
      throw new ValidationError(`Year cannot be greater than ${currentYear}`);
    }
  }

  private static validateGenre(genre: string | undefined): void {
    if (!genre) {
      throw new ValidationError("Genre is required");
    }

    if (!Object.values(Genre).includes(genre as Genre)) {
      throw new ValidationError(
        `Genre must be one of: ${Object.values(Genre).join(", ")}`
      );
    }
  }
}