Skip to content

Commit

Permalink
improve dictionary validation (#520)
Browse files Browse the repository at this point in the history
* improve dictionary validation

* fix

* improve performance

* add undefined check

* rename types

* rename types

* rename
  • Loading branch information
Casheeew authored Jan 20, 2024
1 parent be267e1 commit 0011afe
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 43 deletions.
63 changes: 33 additions & 30 deletions dev/dictionary-validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,33 @@ function readSchema(relativeFileName) {
/**
* @param {import('dev/schema-validate').ValidateMode} mode
* @param {import('jszip')} zip
* @param {string} fileNameFormat
* @param {import('dev/dictionary-validate').Schema} schema
* @param {import('dev/dictionary-validate').SchemasDetails} schemasDetails
*/
async function validateDictionaryBanks(mode, zip, fileNameFormat, schema) {
let jsonSchema;
try {
jsonSchema = createJsonSchema(mode, schema);
} catch (e) {
const e2 = toError(e);
e2.message += `\n(in file ${fileNameFormat})}`;
throw e2;
}
let index = 1;
while (true) {
const fileName = fileNameFormat.replace(/\?/, `${index}`);
async function validateDictionaryBanks(mode, zip, schemasDetails) {
for (const [fileName, file] of Object.entries(zip.files)) {
for (const [fileNameFormat, schema] of schemasDetails) {
if (!fileNameFormat.test(fileName)) { continue; }

const file = zip.files[fileName];
if (!file) { break; }
let jsonSchema;
try {
jsonSchema = createJsonSchema(mode, schema);
} catch (e) {
const e2 = toError(e);
e2.message += `\n(in file ${fileName})}`;
throw e2;
}

const data = parseJson(await file.async('string'));
try {
jsonSchema.validate(data);
} catch (e) {
const e2 = toError(e);
e2.message += `\n(in file ${fileName})}`;
throw e2;
}
const data = parseJson(await file.async('string'));

++index;
try {
jsonSchema.validate(data);
} catch (e) {
const e2 = toError(e);
e2.message += `\n(in file ${fileName})}`;
throw e2;
}
break;
}
}
}

Expand Down Expand Up @@ -98,11 +96,16 @@ export async function validateDictionary(mode, archive, schemas) {
throw e2;
}

await validateDictionaryBanks(mode, archive, 'term_bank_?.json', version === 1 ? schemas.termBankV1 : schemas.termBankV3);
await validateDictionaryBanks(mode, archive, 'term_meta_bank_?.json', schemas.termMetaBankV3);
await validateDictionaryBanks(mode, archive, 'kanji_bank_?.json', version === 1 ? schemas.kanjiBankV1 : schemas.kanjiBankV3);
await validateDictionaryBanks(mode, archive, 'kanji_meta_bank_?.json', schemas.kanjiMetaBankV3);
await validateDictionaryBanks(mode, archive, 'tag_bank_?.json', schemas.tagBankV3);
/** @type {import('dev/dictionary-validate').SchemasDetails} */
const schemasDetails = [
[/^term_bank_(\d+)\.json$/, version === 1 ? schemas.termBankV1 : schemas.termBankV3],
[/^term_meta_bank_(\d+)\.json$/, schemas.termMetaBankV3],
[/^kanji_bank_(\d+)\.json$/, version === 1 ? schemas.kanjiBankV1 : schemas.kanjiBankV3],
[/^kanji_meta_bank_(\d+)\.json$/, schemas.kanjiMetaBankV3],
[/^tag_bank_(\d+)\.json$/, schemas.tagBankV3]
];

await validateDictionaryBanks(mode, archive, schemasDetails);
}

/**
Expand Down
24 changes: 13 additions & 11 deletions ext/js/dictionary/dictionary-importer.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ export class DictionaryImporter {

// Files
/** @type {import('dictionary-importer').QueryDetails} */
const queryDetails = new Map([
const queryDetails = [
['termFiles', /^term_bank_(\d+)\.json$/],
['termMetaFiles', /^term_meta_bank_(\d+)\.json$/],
['kanjiFiles', /^kanji_bank_(\d+)\.json$/],
['kanjiMetaFiles', /^kanji_meta_bank_(\d+)\.json$/],
['tagFiles', /^tag_bank_(\d+)\.json$/]
]);
];
const {termFiles, termMetaFiles, kanjiFiles, kanjiMetaFiles, tagFiles} = Object.fromEntries(this._getArchiveFiles(fileMap, queryDetails));

// Load data
Expand Down Expand Up @@ -692,16 +692,18 @@ export class DictionaryImporter {
_getArchiveFiles(fileMap, queryDetails) {
/** @type {import('dictionary-importer').QueryResult} */
const results = new Map();
for (const [name, value] of fileMap.entries()) {
for (const [fileType, fileNameFormat] of queryDetails.entries()) {
let entries = results.get(fileType);
if (typeof entries === 'undefined') {
entries = [];
results.set(fileType, entries);
}

if (fileNameFormat.test(name)) {
entries.push(value);
for (const [fileType] of queryDetails) {
results.set(fileType, []);
}

for (const [fileName, fileEntry] of fileMap.entries()) {
for (const [fileType, fileNameFormat] of queryDetails) {
if (!fileNameFormat.test(fileName)) { continue; }
const entries = results.get(fileType);

if (typeof entries !== 'undefined') {
entries.push(fileEntry);
break;
}
}
Expand Down
5 changes: 5 additions & 0 deletions types/dev/dictionary-validate.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ export type Schemas = {
termBankV3: Schema;
termMetaBankV3: Schema;
};

/**
* An array of tuples of a regular expression for file types inside a dictionary and its corresponding schema.
*/
export type SchemasDetails = [fileNameFormat: RegExp, schema: unknown][];
4 changes: 2 additions & 2 deletions types/ext/dictionary-importer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ export type ImportRequirementContext = {
export type ArchiveFileMap = Map<string, ZipJS.Entry>;

/**
* A map of file types inside a dictionary and its corresponding regular expressions.
* An array of tuples of a file type inside a dictionary and its corresponding regular expression.
*/
export type QueryDetails = Map<string, RegExp>;
export type QueryDetails = [fileType: string, fileNameFormat: RegExp][];

/**
* A map of file types inside a dictionary and its matching entries.
Expand Down

0 comments on commit 0011afe

Please sign in to comment.