aboutsummaryrefslogtreecommitdiff
path: root/src/shared/settings/Search.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/settings/Search.ts')
-rw-r--r--src/shared/settings/Search.ts68
1 files changed, 25 insertions, 43 deletions
diff --git a/src/shared/settings/Search.ts b/src/shared/settings/Search.ts
index 4580236..bdbe4a8 100644
--- a/src/shared/settings/Search.ts
+++ b/src/shared/settings/Search.ts
@@ -1,3 +1,22 @@
+import Validator from './Validator';
+
+const Schema = {
+ type: 'object',
+ properties: {
+ default: { type: 'string' },
+ engines: {
+ type: 'object',
+ propertyNames: {
+ pattern: '^[A-Za-z_][A-Za-z0-9_]+$',
+ },
+ patternProperties: {
+ '.*': { type: 'string' },
+ },
+ },
+ },
+ required: ['default'],
+};
+
type Entries = { [name: string]: string };
export type SearchJSON = {
@@ -12,19 +31,10 @@ export default class Search {
) {
}
- static fromJSON(json: any): Search {
- let defaultEngine = Search.getStringField(json, 'default');
- let engines = Search.getObjectField(json, 'engines');
+ static fromJSON(json: unknown): Search {
+ let obj = new Validator<SearchJSON>(Schema).validate(json);
- for (let [name, url] of Object.entries(engines)) {
- if ((/\s/).test(name)) {
- throw new TypeError(
- `While space in the search engine not allowed: "${name}"`);
- }
- if (typeof url !== 'string') {
- throw new TypeError(
- `Invalid type of value in filed "engines": ${JSON.stringify(json)}`);
- }
+ for (let [name, url] of Object.entries(obj.engines)) {
let matches = url.match(/{}/g);
if (matches === null) {
throw new TypeError(`No {}-placeholders in URL of "${name}"`);
@@ -32,15 +42,11 @@ export default class Search {
throw new TypeError(`Multiple {}-placeholders in URL of "${name}"`);
}
}
-
- if (!Object.keys(engines).includes(defaultEngine)) {
- throw new TypeError(`Default engine "${defaultEngine}" not found`);
+ if (!Object.keys(obj.engines).includes(obj.default)) {
+ throw new TypeError(`Default engine "${obj.default}" not found`);
}
- return new Search(
- json.default as string,
- json.engines,
- );
+ return new Search(obj.default, obj.engines);
}
toJSON(): SearchJSON {
@@ -49,28 +55,4 @@ export default class Search {
engines: this.engines,
};
}
-
- private static getStringField(json: any, name: string): string {
- if (!Object.prototype.hasOwnProperty.call(json, name)) {
- throw new TypeError(
- `missing field "${name}" on search: ${JSON.stringify(json)}`);
- }
- if (typeof json[name] !== 'string') {
- throw new TypeError(
- `invalid type of filed "${name}" on search: ${JSON.stringify(json)}`);
- }
- return json[name];
- }
-
- private static getObjectField(json: any, name: string): Object {
- if (!Object.prototype.hasOwnProperty.call(json, name)) {
- throw new TypeError(
- `missing field "${name}" on search: ${JSON.stringify(json)}`);
- }
- if (typeof json[name] !== 'object' || json[name] === null) {
- throw new TypeError(
- `invalid type of filed "${name}" on search: ${JSON.stringify(json)}`);
- }
- return json[name];
- }
}