Pop-up dictionary browser extension for language learning. Successor to Yomichan. (PERSONAL FORK)
1/*
2 * Copyright (C) 2023-2025 Yomitan Authors
3 * Copyright (C) 2020-2022 Yomichan Authors
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19import Ajv from 'ajv';
20import {readFileSync} from 'fs';
21import {fileURLToPath} from 'url';
22import {JsonSchema} from '../ext/js/data/json-schema.js';
23import {DataError} from './data-error.js';
24import {parseJson} from './json.js';
25
26class JsonSchemaAjv {
27 /**
28 * @param {import('dev/schema-validate').Schema} schema
29 */
30 constructor(schema) {
31 const ajv = new Ajv({
32 meta: false,
33 strictTuples: false,
34 allowUnionTypes: true,
35 });
36 const metaSchemaPath = fileURLToPath(import.meta.resolve('ajv/dist/refs/json-schema-draft-07.json'));
37 /** @type {import('ajv').AnySchemaObject} */
38 const metaSchema = parseJson(readFileSync(metaSchemaPath, {encoding: 'utf8'}));
39 ajv.addMetaSchema(metaSchema);
40 /** @type {import('ajv').ValidateFunction} */
41 this._validate = ajv.compile(/** @type {import('ajv').Schema} */ (schema));
42 }
43
44 /**
45 * @param {unknown} data
46 * @throws {Error}
47 */
48 validate(data) {
49 if (this._validate(data)) { return; }
50 const {errors} = this._validate;
51 const error = new DataError('Schema validation failed');
52 error.data = parseJson(JSON.stringify(errors));
53 throw error;
54 }
55}
56
57/**
58 * Creates a JSON Schema.
59 * @param {import('dev/schema-validate').ValidateMode} mode
60 * @param {import('dev/schema-validate').Schema} schema
61 * @returns {JsonSchema|JsonSchemaAjv}
62 */
63export function createJsonSchema(mode, schema) {
64 switch (mode) {
65 case 'ajv': return new JsonSchemaAjv(schema);
66 default: return new JsonSchema(/** @type {import('ext/json-schema').Schema} */ (schema));
67 }
68}