forked from PreMiD/Presences
-
Notifications
You must be signed in to change notification settings - Fork 0
/
schemaValidator.ts
126 lines (110 loc) · 3.56 KB
/
schemaValidator.ts
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import "source-map-support/register";
import * as fs from "fs";
import { blue, green, red, yellow } from "chalk";
import axios from "axios";
import { validate } from "jsonschema";
const latestMetadataSchema = "https://schemas.premid.app/metadata/1.3",
stats = {
validated: 0,
validatedWithWarnings: 0,
failedToValidate: 0
},
validated = (service: string): void => {
console.log(green(`✔ ${service}`));
stats.validated++;
},
validatedWithWarnings = (service: string, warning: string): void => {
console.log(yellow(`✔ ${service} (${warning})`));
stats.validatedWithWarnings++;
},
failedToValidate = (service: string, errors: string[]): void => {
console.log(
red(`✘ ${service}\n${errors.map((e) => ` -> ${e}`).join("\n")}`)
);
stats.failedToValidate++;
},
loadMetadata = (path: string): Metadata =>
JSON.parse(fs.readFileSync(path, "utf-8")),
changedFiles = fs
.readFileSync("./file_changes.txt", "utf-8")
.trim()
.split("\n"),
metaFiles = changedFiles.filter((f: string) => f.endsWith("metadata.json"));
(async (): Promise<void> => {
console.log(blue("Getting latest schema..."));
const schema = (await axios.get(latestMetadataSchema)).data;
console.log(
blue("Beginning validation of " + metaFiles.length + " presences...")
);
for (const metaFile of metaFiles) {
const meta = loadMetadata(metaFile),
service = meta.service,
result = validate(meta, schema),
validLangs = (await axios.get("https://api.premid.app/v2/langFile/list"))
.data,
invalidLangs: string[] = [];
Object.keys(meta.description).forEach((lang) => {
const index = validLangs.findIndex((l: string) => l == lang);
if (index == -1) invalidLangs.push(lang);
});
if (result.valid && !invalidLangs.length) {
if (meta.schema && meta.schema !== latestMetadataSchema) {
validatedWithWarnings(service, "Using out of date schema");
} else {
validated(service);
}
} else {
const errors: string[] = [];
for (const error of result.errors)
errors.push(`${error.message} @ ${error.property}`);
for (const invalidLang of invalidLangs)
errors.push(
`"${invalidLang}" is not a valid language! Valid languages can be found here: https://api.premid.app/v2/langFile/list`
);
failedToValidate(service, errors);
}
}
console.log();
console.log(blue("Statistics:"));
console.log(
green(`${stats.validated} fully validated\n`) +
yellow(`${stats.validatedWithWarnings} validated, but with warnings\n`) +
red(`${stats.failedToValidate} failed to validate`)
);
console.log();
if (stats.failedToValidate > 0) {
console.log(red("One or more services failed to validate."));
process.exit(-1);
}
if (stats.validatedWithWarnings > 0) {
console.log(yellow("One or more services validated, but with warnings."));
}
})();
interface Metadata {
schema: string;
author: { name: string; id: string };
contributors?: Array<{ name: string; id: string }>;
service: string;
description: Record<string, string>;
url: string;
version: string;
logo: string;
thumbnail: string;
color: string;
tags: string | Array<string>;
category: string;
iframe?: boolean;
regExp?: RegExp;
iframeRegExp?: RegExp;
button?: boolean;
warning?: boolean;
settings?: Array<{
id: string;
title: string;
icon: string;
if?: Record<string, string>;
placeholder?: string;
value?: string | number | boolean;
values?: Array<string | number | boolean>;
}>;
}