rename lib -> utils

This commit is contained in:
Kalle (Sendou)
2021-03-08 17:48:05 +02:00
parent ebb7da7d48
commit dff31cdfc7
153 changed files with 183 additions and 187 deletions

48
utils/validators/build.ts Normal file
View File

@@ -0,0 +1,48 @@
import { isAbilityArray } from "utils/lists/abilities";
import { clothingGear, headGear, shoesGear } from "utils/lists/gear";
import { weaponsWithHero } from "utils/lists/weaponsWithHero";
import * as z from "zod";
import { abilityEnum, hasNoDuplicates } from "./common";
export const TITLE_CHARACTER_LIMIT = 100;
export const DESCRIPTION_CHARACTER_LIMIT = 1000;
export const buildSchema = z.object({
weapon: z.string().refine((val) => weaponsWithHero.includes(val as any)),
title: z.string().max(TITLE_CHARACTER_LIMIT).optional().nullable(),
description: z
.string()
.max(DESCRIPTION_CHARACTER_LIMIT)
.optional()
.nullable(),
modes: z
.array(z.enum(["TW", "SZ", "TC", "RM", "CB"]))
.min(1)
.max(5)
.refine(hasNoDuplicates),
headAbilities: z
.array(abilityEnum)
.refine((arr) => isAbilityArray(arr, "HEAD")),
clothingAbilities: z
.array(abilityEnum)
.refine((arr) => isAbilityArray(arr, "CLOTHING")),
shoesAbilities: z
.array(abilityEnum)
.refine((arr) => isAbilityArray(arr, "SHOES")),
headGear: z
.string()
.refine((val) => !val || headGear.includes(val as any))
.optional()
.nullable(),
clothingGear: z
.string()
.refine((val) => !val || clothingGear.includes(val as any))
.optional()
.nullable(),
shoesGear: z
.string()
.refine((val) => !val || shoesGear.includes(val as any))
.optional()
.nullable(),
id: z.number().optional(),
});

View File

@@ -0,0 +1,32 @@
import * as z from "zod";
export const hasNoDuplicates = (arr: any[]) => new Set(arr).size === arr.length;
export const abilityEnum = z.enum([
"ISM",
"ISS",
"REC",
"RSU",
"SSU",
"SCU",
"SS",
"SPU",
"QR",
"QSJ",
"BRU",
"RES",
"BDU",
"MPU",
"OG",
"LDE",
"T",
"CB",
"NS",
"H",
"TI",
"RP",
"AD",
"SJ",
"OS",
"DR",
]);

View File

@@ -0,0 +1,48 @@
import { weapons } from "utils/lists/weapons";
import * as z from "zod";
import { abilityEnum } from "./common";
const playerSchema = z.object({
principal_id: z.string(),
name: z.string().min(1).max(10),
weapon: z.string().refine((val) => weapons.includes(val as any)),
main_abilities: z.array(abilityEnum),
sub_abilities: z.array(z.array(abilityEnum)),
kills: z.number().int().min(0).max(50),
assists: z.number().int().min(0).max(50),
deaths: z.number().int().min(0).max(50),
specials: z.number().int().min(0).max(50),
paint: z.number().int().min(0).max(10000),
gear: z.array(z.string()),
});
const teamInfoSchema = z.object({
score: z.number().int().min(0).max(100),
players: z.array(playerSchema),
});
export const detailedMapSchema = z.array(
z.object({
stage: z.string(),
mode: z.enum(["SZ", "TC", "RM", "CB"]),
duration: z.number().int().min(15).max(500),
winners: teamInfoSchema,
losers: teamInfoSchema,
date: z.string().refine((val) => {
const d = new Date(Number(val));
const timestamp = d.getTime();
if (Number.isNaN(timestamp)) {
return false;
}
const nd = new Date();
nd.setMonth(-6);
if (d.getTime() < nd.getTime()) {
return false;
}
return true;
}),
})
);

View File

@@ -0,0 +1,9 @@
import * as z from "zod";
export const FA_POST_CONTENT_LIMIT = 2000;
export const freeAgentPostSchema = z.object({
playstyles: z.array(z.enum(["FRONTLINE", "MIDLINE", "BACKLINE"])).min(1),
canVC: z.enum(["YES", "NO", "MAYBE"]),
content: z.string().max(FA_POST_CONTENT_LIMIT),
});

View File

@@ -0,0 +1,58 @@
import { countries } from "countries-list";
import { weaponsWithHero } from "utils/lists/weaponsWithHero";
import * as z from "zod";
import { hasNoDuplicates } from "./common";
export const PROFILE_CHARACTER_LIMIT = 7000;
const profileRootSchema = z.object({
bio: z.string().max(PROFILE_CHARACTER_LIMIT).optional().nullable(),
country: z
.string()
.refine((val) => !val || Object.keys(countries).includes(val))
.optional()
.nullable(),
customUrlPath: z
.string()
.max(32)
.refine(
(val) => !val || isCustomUrl(val),
"Name in the custom URL can't only contain numbers"
)
.optional()
.nullable(),
twitchName: z.string().max(25).optional().nullable(),
twitterName: z.string().max(15).optional().nullable(),
youtubeId: z.string().optional().nullable(),
weaponPool: z
.array(z.string())
.max(5)
.refine((arr) => arr.every((val) => weaponsWithHero.includes(val as any)))
.refine(hasNoDuplicates),
});
export const profileSchemaFrontend = profileRootSchema.extend({
sensMotion: z.string(),
sensStick: z.string(),
});
export const profileSchemaBackend = profileRootSchema.extend({
sensMotion: z
.number()
.min(-5)
.max(5)
.refine((val) => (val * 10) % 5 === 0)
.optional()
.nullable(),
sensStick: z
.number()
.min(-50)
.max(50)
.refine((val) => (val * 10) % 5 === 0)
.optional()
.nullable(),
});
export function isCustomUrl(identifier: string) {
return isNaN(Number(identifier));
}

View File

@@ -0,0 +1,51 @@
import * as z from "zod";
// https://stackoverflow.com/a/3809435
const urlRegex = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$/;
export const salmonRunRecordSchema = z.object({
rotationId: z.number(), // check on db level
goldenEggCount: z.number().min(10).max(300),
category: z.enum([
"TOTAL",
"TOTAL_NO_NIGHT",
"PRINCESS",
"NT_NORMAL",
"HT_NORMAL",
"LT_NORMAL",
"NT_RUSH",
"HT_RUSH",
"NT_FOG",
"HT_FOG",
"LT_FOG",
"NT_GOLDIE",
"HT_GOLDIE",
"NT_GRILLERS",
"HT_GRILLERS",
"NT_MOTHERSHIP",
"HT_MOTHERSHIP",
"LT_MOTHERSHIP",
"LT_COHOCK",
]),
userIds: z.array(z.number()),
links: z
.string()
.refine((val) => {
const lines = linesFromTextareaValue(val);
if (lines.length === 0 || lines.length > 4) {
return false;
}
return true;
}, "Include 1-4 links")
.refine((val) => {
return linesFromTextareaValue(val).every((link) => urlRegex.test(link));
}, "One of the links is invalid"),
});
function linesFromTextareaValue(value: string) {
return value
.trim()
.split("\n")
.filter((val) => val !== "");
}

View File

@@ -0,0 +1,15 @@
import * as z from "zod";
export const SUGGESTION_DESCRIPTION_LIMIT = 500;
const suggestionRootSchema = z.object({
description: z.string().max(SUGGESTION_DESCRIPTION_LIMIT),
});
export const suggestionFullSchema = suggestionRootSchema.extend({
suggestedId: z.number().int(),
tier: z.number().int().min(1).max(3),
region: z.enum(["NA", "EU"]),
});
export const resuggestionSchema = suggestionRootSchema;

14
utils/validators/team.ts Normal file
View File

@@ -0,0 +1,14 @@
import * as z from "zod";
export const TEAM_BIO_CHARACTER_LIMIT = 7000;
export const TEAM_RECRUITING_POST_CHARACTER_LIMIT = 2000;
export const teamSchema = z.object({
twitterName: z.string().max(15).optional().nullable(),
bio: z.string().max(TEAM_BIO_CHARACTER_LIMIT).optional().nullable(),
recruitingPost: z
.string()
.max(TEAM_RECRUITING_POST_CHARACTER_LIMIT)
.optional()
.nullable(),
});

View File

@@ -0,0 +1,7 @@
import * as z from "zod";
export const vouchSchema = z.object({
vouchedId: z.number().int(),
tier: z.number().int().min(1).max(3),
region: z.enum(["NA", "EU"]),
});