feat(developer): add first steps for validating

This commit is contained in:
Sabine 2025-05-12 18:29:34 +02:00
parent b2413a9d76
commit ae0b032b96
4 changed files with 14 additions and 35 deletions

View file

@ -36,7 +36,7 @@ export class ConverterMessages {
// from SRL
static ERROR_SchemaValidationError = SevError | 0x0011;
static Error_SchemaValidationError = (o:{instancePath:string, keyword:string, message: string, params: string}) => m(this.ERROR_SchemaValidationError,
`Error validating Keylayout XML file: ${def(o.instancePath)}: ${def(o.keyword)}: ${def(o.message)} ${def(o.params)}`);
`!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Error validating Keylayout XML file: ${def(o.instancePath)}: ${def(o.keyword)}: ${def(o.message)} ${def(o.params)}`);
}

View file

@ -1,6 +1,8 @@
/*
* Keyman is 2025 copyright (C) SIL International. MIT License.
*
* Created by S. Schmitt on 2025-05-12
*
* Read macOS/Ukelele .keylayout files
*
*/
@ -10,32 +12,13 @@ import { XMLParser } from 'fast-xml-parser';
import { util } from '@keymanapp/common-types';
import { KeylayoutToKmnConverter } from './keylayout-to-kmn-converter.js';
import { ConverterMessages } from '../converter-messages.js';
import { SchemaValidators } from '@keymanapp/common-types';
import boxXmlArray = util.boxXmlArray;
export class KeylayoutFileReader {
constructor(private callbacks: CompilerCallbacks /*,private options: CompilerOptions*/) { };
/**
* @returns true if valid, false if invalid
*/
public validate(source: any): boolean {
if(!SchemaValidators.default.keylayout(source)) {
console.log("SchemaValidators.default.keylayout).errors ",(<any>SchemaValidators.default.keylayout).errors);
for (const err of (<any>SchemaValidators.default.keylayout).errors) {
this.callbacks.reportMessage(ConverterMessages.Error_SchemaValidationError({
instancePath: err.instancePath,
keyword: err.keyword,
message: err.message || 'Unknown AJV Error', // docs say 'message' is optional if 'messages:false' in options
params: Object.entries(err.params || {}).sort().map(([k,v])=>`${k}="${v}"`).join(' '),
}));
}
return false;
}
return true;
}
/**
* @brief member function to box single-entry objects into arrays
@ -67,8 +50,6 @@ export class KeylayoutFileReader {
*/
public read(inputFilename: string): Object {
let xmlFile;
let jsonObj = [];
const options = {
ignoreAttributes: false,
@ -77,16 +58,16 @@ export class KeylayoutFileReader {
};
try {
xmlFile = this.callbacks.fs.readFileSync(this.callbacks.path.join(process.cwd(), KeylayoutToKmnConverter.TEST_SUBFOLDER, KeylayoutToKmnConverter.DATA_SUBFOLDER, this.callbacks.path.basename(inputFilename)), 'utf8');
const xmlFile = this.callbacks.fs.readFileSync(this.callbacks.path.join(process.cwd(), KeylayoutToKmnConverter.TEST_SUBFOLDER, KeylayoutToKmnConverter.DATA_SUBFOLDER, this.callbacks.path.basename(inputFilename)), 'utf8');
const parser = new XMLParser(options);
jsonObj = parser.parse(xmlFile); // get plain Object
const jsonObj = parser.parse(xmlFile); // get plain Object
this.boxArray(jsonObj.keyboard); // jsonObj now contains arrays; no single fields
return jsonObj;
}
catch (err) {
this.callbacks.reportMessage(ConverterMessages.Error_FileNotFound({ inputFilename }));
return null;
}
return jsonObj;
}
}

View file

@ -56,20 +56,18 @@ export class KeylayoutToKmnConverter {
const jsonO: object = KeylayoutReader.read(inputFilename);
// just to check if it works: validate file with stevens schema file -------------------------------------------------
// to check if it works: validate file with stevens schema file -------------------------------------------------
console.log("stop ",);
console.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I will validate ",inputFilename, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
try {
// validate the object tree against the .xsd schema
if (!KeylayoutReader.validate(jsonO)) {
//if (KeylayoutReader.validate(jsonO)) {
return null;
}
} catch (e) {
this.callbacks.reportMessage(ConverterMessages.Error_InvalidFile({ errorText: e.toString() }));
return null;
}
// just to check if it works: validate file with stevens schema file -------------------------------------------------
// to check if it works: validate file with stevens schema file -------------------------------------------------
if (!jsonO) {

View file

@ -140,7 +140,7 @@ export class KmnFileWriter {
const output_character = new TextDecoder().decode(unique_data_Rules[k].output);
const output_character_unicode = util.convertToUnicodeCodePoint(output_character);
// if we are about to print a unicode codepoint instead of a single character we need to check if it is a control character
// if we are about to print a unicode codepoint instead of a single character we need to check if it is a control character and add a warning
if ((output_character_unicode.length > 1)
&& (Number("0x" + output_character_unicode.substring(2, output_character_unicode.length)) < KeylayoutToKmnConverter.MAX_CTRL_CHARACTER)) {
if (warn_text[2] == "")
@ -181,7 +181,7 @@ export class KmnFileWriter {
const output_character = new TextDecoder().decode(unique_data_Rules[k].output);
const output_character_unicode = util.convertToUnicodeCodePoint(output_character);
// if we are about to print a unicode codepoint instead of a single character we need to check if it is a control character
// if we are about to print a unicode codepoint instead of a single character we need to check if it is a control character and add a warning
if ((output_character_unicode.length > 1)
&& (Number("0x" + output_character_unicode.substring(2, output_character_unicode.length)) < KeylayoutToKmnConverter.MAX_CTRL_CHARACTER)) {
if (warn_text[2] == "")
@ -241,7 +241,7 @@ export class KmnFileWriter {
const output_character = new TextDecoder().decode(unique_data_Rules[k].output);
const output_character_unicode = util.convertToUnicodeCodePoint(output_character);
// if we are about to print a unicode codepoint instead of a single character we need to check if a control character is to be used
// if we are about to print a unicode codepoint instead of a single character we need to check if it is a control character and add a warning
if ((output_character_unicode.length > 1)
&& (Number("0x" + output_character_unicode.substring(2, output_character_unicode.length)) < KeylayoutToKmnConverter.MAX_CTRL_CHARACTER)) {
if (warn_text[2] == "")
@ -319,8 +319,8 @@ export class KmnFileWriter {
}
/**
* @brief member function to review rules for acceptable modifiers, duplicate or ambiguous rules and return an array containing possible warnings
* definition of comparisons e.g. 1-1, 2-4, 6-6
* @brief member function to review rules for acceptable modifiers, duplicate or ambiguous rules and return an array containing possible warnings.
* Definition of comparisons e.g. 1-1, 2-4, 6-6
* see https://docs.google.com/document/d/12J3NGO6RxIthCpZDTR8FYSRjiMgXJDLwPY2z9xqKzJ0/edit?tab=t.0#heading=h.pcz8rjyrl5ug
* @param rule : Rule[] - an array of all rules
* @param index the index of a rule in array[rule]