All files / common/dtos MemberDTO.mjs

73.68% Statements 14/19
75% Branches 3/4
50% Functions 4/8
76.47% Lines 13/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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              12x               29x                                       12x               8x           8x           8x           8x                   8x             8x     8x 8x 8x                 8x                
import { z } from "zod";
import { isAlpha } from "class-validator";
 
// https://stackoverflow.com/questions/76354177/how-to-infer-zod-type-in-jsdoc-without-typescript
/**
 * @typedef { z.infer<typeof MemberDTOSchema> } MemberDTOSchemaType
 */
export const MemberDTOSchema = z.object(
{
    name: z
        .string()
        .trim()
        .min(1)
        .max(50)
        .refine(
            name => name.split(' ').every(word => isAlpha(word) || word.length === 0),
            { message: "Name must only contain letters and spaces!" }
        ),
 
    adminNumber: z
        .string()
        .toUpperCase()
        .regex(
            /^\d{7}[A-Z]$/,
            { message: "Invalid admin number format. It should consist of 7 digits followed by 1 uppercase letter (e.g., 2304806I)." }
        ),
 
    gymPrograms: z
        .array(z.string())
        .default([])
        .transform(programs => new Set(programs))
        .transform(programs => Array.from(programs))
        .transform(programs => programs.map(program => program.toLowerCase()))
});
 
export const MemberUpdateDTOSchema = MemberDTOSchema.partial();
 
export class MemberDTO
{
  /**
   * @type { string } // Technically, this is supposed to be a bigint, but JS doesn't serialize it well...
   * @public
   */
  id;
 
  /**
   * @type { string }
   * @public
   */
  name;
 
  /**
   * @type { string }
   * @public
   */
  adminNumber;
 
  /**
   * @type { string[] }
   * @public
   */
  gymPrograms;
 
  /**
   * @param { bigint } id
   * @param { string } name
   * @param { string } adminNumber
   * @param { string[] } gymPrograms
   */
  constructor({ id, name, adminNumber, gymPrograms })
  {
    Iif (id !== undefined)
    {
        this.id = `${id}`;
    }
 
    else
    {
        delete this.id;
    }
 
    this.name = name;
    this.adminNumber = adminNumber;
    this.gymPrograms = gymPrograms;
  }
 
  /**
   * @param { MemberDTOSchemaType } schema
   * @returns { MemberDTO }
   */
  static fromSchema(schema)
  {
      return new MemberDTO(
      {
          id: undefined,
          name: schema.name,
          adminNumber: schema.adminNumber,
          gymPrograms: schema.gymPrograms
      });
  }
}