Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate type validators to zod #218

Open
nicholaschiang opened this issue May 18, 2021 · 3 comments
Open

Migrate type validators to zod #218

nicholaschiang opened this issue May 18, 2021 · 3 comments
Labels
backlog Low priority implementation changes p4 Low priority tasks type:migration Migrating code or resources

Comments

@nicholaschiang
Copy link
Member

Instead of declaring a type and then declaring the JSON validator for that type separately, I should use a library like zod to only do it once (and then have a single source of truth instead of duplicating code and creating more possibilities for bugs).

@nicholaschiang nicholaschiang added p4 Low priority tasks backlog Low priority implementation changes type:migration Migrating code or resources labels May 18, 2021
@nicholaschiang
Copy link
Member Author

See the validators in lib/model, for example, in lib/model/user.ts:

export interface UserInterface extends AccountInterface {
  age?: number;
  orgs: string[];
  zooms: ZoomUser[];
  availability: Availability;
  mentoring: Subjects;
  tutoring: Subjects;
  langs: string[];
  parents: string[];
  verifications: Verification[];
  visible: boolean;
  featured: Aspect[];
  roles: Role[];
  tags: UserTag[];
  reference: string;
  timezone: string;
  token?: string;
  hash?: string;
}

export function isUserJSON(json: unknown): json is UserJSON {
  if (!isAccountJSON(json)) return false;
  if (!isJSON(json)) return false;
  if (json.age && typeof json.age !== 'number') return false;
  if (!isStringArray(json.orgs)) return false;
  if (!isArray(json.zooms, isZoomUserJSON)) return false;
  if (!isAvailabilityJSON(json.availability)) return false;
  if (!isSubjects(json.mentoring)) return false;
  if (!isSubjects(json.tutoring)) return false;
  if (!isStringArray(json.langs)) return false;
  if (!isStringArray(json.parents)) return false;
  if (!isArray(json.verifications, isVerificationJSON)) return false;
  if (typeof json.visible !== 'boolean') return false;
  if (!isArray(json.featured, isAspect)) return false;
  if (!isArray(json.roles, isRole)) return false;
  if (!isArray(json.tags, isUserTag)) return false;
  if (typeof json.reference !== 'string') return false;
  if (typeof json.timezone !== 'string') return false;
  if (json.token && typeof json.token !== 'string') return false;
  if (json.hash && typeof json.hash !== 'string') return false;
  return true;
}

All of that ☝️ could have been written once using a zod type validator.

@nicholaschiang
Copy link
Member Author

Also, zod is nicer because it throws the specific validation error instead of simply returning false (like the above validator function). That way, the client knows exactly why it got a 400 - Invalid Request Body API error and how to fix it.

@jasonappah
Copy link

I'd love to take this issue! Is there anything else I should be aware of before working on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog Low priority implementation changes p4 Low priority tasks type:migration Migrating code or resources
Projects
None yet
Development

No branches or pull requests

2 participants