diff options
author | Madeline <46743919+MaddyUnderStars@users.noreply.github.com> | 2022-09-25 18:24:21 +1000 |
---|---|---|
committer | Madeline <46743919+MaddyUnderStars@users.noreply.github.com> | 2022-09-25 23:35:18 +1000 |
commit | 0d23eaba09a4878520bf346af4cead90d76829fc (patch) | |
tree | d930eacceff0b407b44abe55f01d8e3c5dfbfa34 /src/util/schemas/Validator.ts | |
parent | Allow edited_timestamp to passthrough in handleMessage (diff) | |
download | server-0d23eaba09a4878520bf346af4cead90d76829fc.tar.xz |
Refactor to mono-repo + upgrade packages
Diffstat (limited to 'src/util/schemas/Validator.ts')
-rw-r--r-- | src/util/schemas/Validator.ts | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/util/schemas/Validator.ts b/src/util/schemas/Validator.ts new file mode 100644 index 00000000..b71bf6a1 --- /dev/null +++ b/src/util/schemas/Validator.ts @@ -0,0 +1,54 @@ +import Ajv from "ajv"; +import addFormats from "ajv-formats"; +import fs from "fs"; +import path from "path"; + +const SchemaPath = path.join(__dirname, "..", "..", "..", "assets", "schemas.json"); +const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" })); + +export const ajv = new Ajv({ + allErrors: true, + parseDate: true, + allowDate: true, + schemas, + coerceTypes: true, + messages: true, + strict: true, + strictRequired: true +}); + +addFormats(ajv); + +export function validateSchema<G>(schema: string, data: G): G { + const valid = ajv.validate(schema, normalizeBody(data)); + if (!valid) throw ajv.errors; + return data; +} + +// Normalizer is introduced to workaround https://github.com/ajv-validator/ajv/issues/1287 +// this removes null values as ajv doesn't treat them as undefined +// normalizeBody allows to handle circular structures without issues +// taken from https://github.com/serverless/serverless/blob/master/lib/classes/ConfigSchemaHandler/index.js#L30 (MIT license) +export const normalizeBody = (body: any = {}) => { + const normalizedObjectsSet = new WeakSet(); + const normalizeObject = (object: any) => { + if (normalizedObjectsSet.has(object)) return; + normalizedObjectsSet.add(object); + if (Array.isArray(object)) { + for (const [index, value] of object.entries()) { + if (typeof value === "object") normalizeObject(value); + } + } else { + for (const [key, value] of Object.entries(object)) { + if (value == null) { + if (key === "icon" || key === "avatar" || key === "banner" || key === "splash" || key === "discovery_splash") continue; + delete object[key]; + } else if (typeof value === "object") { + normalizeObject(value); + } + } + } + }; + normalizeObject(body); + return body; +}; \ No newline at end of file |