Merge pull request #9038 from keymanapp/refactor/developer/kmc-kmn-call-into-kmc-kmw

refactor(developer): kmc-kmn now builds .js when needed 🗜
This commit is contained in:
Marc Durdin 2023-06-20 17:12:08 +10:00 • committed by GitHub
commit fa38e30e2f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 259 additions and 634 deletions

View file

@ -99,8 +99,9 @@ export enum CompilerErrorNamespace {
*/
Analyzer = 0x6000,
/**
* kmc-kmw errors between 0x7000…0x7FFF; note that some errors generated by
* kmc-kmw are from kmc-kmn namespace for legacy reasons
* kmc-kmn/kmw-compiler errors between 0x7000…0x7FFF; note that some errors
* generated by kmc-kmn/kmw-compiler are from kmc-kmn namespace for legacy
* reasons
*/
KmwCompiler = 0x7000,
};

View file

@ -29,8 +29,7 @@ builder_describe \
test \
":kmcmplib=src/kmcmplib Compiler - .kmn compiler" \
":kmc-analyze=src/kmc-analyze Compiler - Analysis Tools" \
":kmc-kmn=src/kmc-kmn Compiler - .kmn wrapper Keyboard Module" \
":kmc-kmw=src/kmc-kmw Compiler - .kmn Javascript Keyboard Module" \
":kmc-kmn=src/kmc-kmn Compiler - .kmn to .kmx and .js Keyboard Module" \
":kmc-ldml=src/kmc-ldml Compiler - LDML Keyboard Module" \
":kmc-model=src/kmc-model Compiler - Lexical Model Module" \
":kmc-model-info=src/kmc-model-info Compiler - .model_info Module" \

View file

@ -19,7 +19,6 @@ export async function getOskFromKmnFile(callbacks: CompilerCallbacks, filename:
let result = kmnCompiler.runCompiler(filename, filename + '.tmp', {
shouldAddCompilerVersion: false,
saveDebug: false,
target: 'js'
});
if(!result) {

View file

@ -8,6 +8,7 @@ module.exports = {
extends: ["../../../common/web/eslint/eslintNoNodeImports.js"],
}
],
ignorePatterns: ["test/fixtures/*"],
rules: {
"prefer-const": "off", // TODO: enable this once infrastructure is in place and cleanup the problem cases
},

View file

@ -27,7 +27,8 @@
"url": "https://github.com/keymanapp/keyman/issues"
},
"dependencies": {
"@keymanapp/keyman-version": "*"
"@keymanapp/keyman-version": "*",
"@keymanapp/kmc-kmn": "*"
},
"devDependencies": {
"@types/chai": "^4.1.7",
@ -61,6 +62,7 @@
"exclude-after-remap": true,
"exclude": [
"src/import/",
"src/kmw-compiler",
"test/"
]
},

View file

@ -10,15 +10,25 @@ import { UnicodeSetParser, UnicodeSet, Osk } from '@keymanapp/common-types';
import { CompilerCallbacks, CompilerEvent, CompilerOptions, KeymanFileTypes, KvkFileWriter, KvksFileReader } from '@keymanapp/common-types';
import loadWasmHost from '../import/kmcmplib/wasm-host.js';
import { CompilerMessages, mapErrorFromKmcmplib } from './messages.js';
import { WriteCompiledKeyboard } from '../kmw-compiler/write-compiled-keyboard.js';
export interface CompilerResultFile {
filename: string;
data: Uint8Array;
};
export const COMPILETARGETS_KMX = 0x01;
export const COMPILETARGETS_JS = 0x02;
export const COMPILETARGETS__MASK = 0x03;
export interface CompilerResultMetadata {
/**
* A bitmask, consisting of COMPILETARGETS_KMX and/or COMPILETARGETS_JS
*/
targets: number;
kvksFilename?: string;
displayMapFilename?: string;
displayMap?: Osk.PuaMap;
};
export interface CompilerResult {
@ -29,7 +39,6 @@ export interface CompilerResult {
};
export interface KmnCompilerOptions extends CompilerOptions {
target?: 'kmx' | 'js';
};
const baseOptions: KmnCompilerOptions = {
@ -37,7 +46,6 @@ const baseOptions: KmnCompilerOptions = {
saveDebug: true,
compilerWarningsAsErrors: false,
warnDeprecatedCode: true,
target: 'kmx'
};
/**
@ -163,7 +171,7 @@ export class KmnCompiler implements UnicodeSetParser {
loadFile: this.loadFileCallback
};
let result: CompilerResult = {data:{}};
let result: CompilerResult = {data:{targets:0}};
let wasm_interface = new this.Module.CompilerInterface();
let wasm_options = new this.Module.CompilerOptions();
let wasm_result = null;
@ -172,26 +180,60 @@ export class KmnCompiler implements UnicodeSetParser {
wasm_options.compilerWarningsAsErrors = options.compilerWarningsAsErrors;
wasm_options.warnDeprecatedCode = options.warnDeprecatedCode;
wasm_options.shouldAddCompilerVersion = options.shouldAddCompilerVersion;
wasm_options.target = options.target == 'js' ? 1 : 0; // TODO CKF_KEYMANWEB : CKF_KEYMAN;
wasm_options.target = 0; // CKF_KEYMAN; TODO use COMPILETARGETS_KMX
wasm_interface.callbacksKey = this.callbackID; // key of object on globalThis
wasm_result = this.Module.kmcmp_compile(infile, wasm_options, wasm_interface);
if(!wasm_result.result) {
return null;
}
if(wasm_result.targets & COMPILETARGETS_KMX) {
result.kmx = {
filename: outfile,
data: new Uint8Array(this.Module.HEAP8.buffer, wasm_result.kmx, wasm_result.kmxSize)
};
}
//
// Visual Keyboard transform
//
result.data.kvksFilename = wasm_result.kvksFilename;
result.data.displayMapFilename = wasm_result.displayMapFilename;
result.data.displayMap = null;
if(wasm_result.displayMapFilename) {
result.data.displayMap = this.loadDisplayMapping(infile, result.data.displayMapFilename)
}
if(result.data.kvksFilename) {
result.kvk = this.runKvkCompiler(result.data.kvksFilename, infile, outfile, result.data.displayMapFilename);
result.kvk = this.runKvkCompiler(result.data.kvksFilename, infile, outfile, result.data.displayMap);
if(!result.kvk) {
return null;
}
}
result.kmx = {
filename: outfile,
data: new Uint8Array(this.Module.HEAP8.buffer, wasm_result.kmx, wasm_result.kmxSize)
};
//
// KeymanWeb compiler
//
if(wasm_result.targets & COMPILETARGETS_JS) {
wasm_options.target = 1; // CKF_KEYMANWEB TODO use COMPILETARGETS_JS
wasm_result = this.Module.kmcmp_compile(infile, wasm_options, wasm_interface);
if(!wasm_result.result) {
return null;
}
let web_kmx = {
filename: outfile,
data: new Uint8Array(this.Module.HEAP8.buffer, wasm_result.kmx, wasm_result.kmxSize)
};
result.js = this.runWebCompiler(infile, outfile, web_kmx.data, result.kvk?.data, result.data.displayMap, options);
if(!result.js) {
return null;
}
}
return result;
} catch(e) {
@ -208,7 +250,27 @@ export class KmnCompiler implements UnicodeSetParser {
}
}
private runKvkCompiler(kvksFilename: string, kmnFilename: string, kmxFilename: string, displayMapFilename?: string) {
private runWebCompiler(
kmnFilename: string,
kmxFilename: string,
web_kmx: Uint8Array,
kvk: Uint8Array,
displayMap: Osk.PuaMap,
options: CompilerOptions
): CompilerResultFile {
const data = WriteCompiledKeyboard(this.callbacks, kmnFilename, web_kmx, kvk, displayMap, options.saveDebug);
if(!data) {
return null;
}
return {
filename: this.callbacks.path.join(this.callbacks.path.dirname(kmxFilename),
this.callbacks.path.basename(kmnFilename, KeymanFileTypes.Source.KeymanKeyboard) + KeymanFileTypes.Binary.WebKeyboard),
data: new TextEncoder().encode(data)
};
}
private runKvkCompiler(kvksFilename: string, kmnFilename: string, kmxFilename: string, displayMap?: Osk.PuaMap) {
// The compiler detected a .kvks file, which needs to be captured
let reader = new KvksFileReader();
kvksFilename = this.callbacks.resolveFilename(kmnFilename, kvksFilename);
@ -227,23 +289,9 @@ export class KmnCompiler implements UnicodeSetParser {
this.callbacks.reportMessage(CompilerMessages.Warn_InvalidVkeyInKvksFile({filename, invalidVkey}));
}
if(displayMapFilename) {
if(displayMap) {
// Remap using the osk-char-use-rewriter
let mapping: any;
displayMapFilename = this.callbacks.resolveFilename(kmnFilename, displayMapFilename);
try {
// Expected file format: displaymap.schema.json
// TODO: verify with schema
let data = this.callbacks.loadFile(displayMapFilename);
mapping = JSON.parse(new TextDecoder().decode(data));
} catch(e) {
this.callbacks.reportMessage(CompilerMessages.Error_InvalidDisplayMapFile({filename, e}));
return null;
}
let pua = Osk.parseMapping(mapping);
Osk.remapVisualKeyboard(vk, pua);
Osk.remapVisualKeyboard(vk, displayMap);
}
let writer = new KvkFileWriter();
@ -254,6 +302,24 @@ export class KmnCompiler implements UnicodeSetParser {
};
}
private loadDisplayMapping(kmnFilename:string, displayMapFilename: string): Osk.PuaMap {
// Remap using the osk-char-use-rewriter
let mapping: any;
displayMapFilename = this.callbacks.resolveFilename(kmnFilename, displayMapFilename);
try {
// Expected file format: displaymap.schema.json
// TODO: verify with schema
let data = this.callbacks.loadFile(displayMapFilename);
mapping = JSON.parse(new TextDecoder().decode(data));
} catch(e) {
this.callbacks.reportMessage(CompilerMessages.Error_InvalidDisplayMapFile({filename: displayMapFilename, e}));
return null;
}
return Osk.parseMapping(mapping);
}
/**
*
* @param pattern UnicodeSet pattern such as `[a-z]`

View file

@ -1,4 +1,4 @@
import { TSentinelRecord, GetSuppChar, ExpandSentinel, incxstr, xstrlen, xstrlen_printing } from "../util/util.js";
import { TSentinelRecord, GetSuppChar, ExpandSentinel, incxstr, xstrlen, xstrlen_printing } from "./util.js";
import { KMX } from "@keymanapp/common-types";
import { callbacks, FMnemonic, FTabStop, IsKeyboardVersion10OrLater, IsKeyboardVersion14OrLater, nl, options } from "./compiler-globals.js";

View file

@ -1,4 +1,4 @@
import { KmnCompilerMessages } from "@keymanapp/kmc-kmn";
import { KmnCompilerMessages } from "../compiler/messages.js";
import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m } from "@keymanapp/common-types";
const Namespace = CompilerErrorNamespace.KmwCompiler;
@ -12,10 +12,10 @@ export class KmwCompilerMessages extends KmnCompilerMessages {
// Note: for legacy reasons, KMWCompilerMessages extends from
// KMNCompilerMessages as they share the same error codes. This can be a
// little confusing because kmcmplib still builds its own error message
// strings, not kmc-kmn, whereas the kmc-kmw messages are defined here.
// However, as the kmc-kmw module may be going away at some point, it's
// probably not worth the splitting of all KMW-specific error messages out of
// the KmnCompilerMessages space.
// strings, not kmc-kmn, whereas the kmw messages are defined here. However,
// as the kmw module may be going away at some point, it's probably not worth
// the splitting of all KMW-specific error messages out of the
// KmnCompilerMessages space.
static Error_InvalidBegin = () => m(this.ERROR_InvalidBegin,
`A "begin unicode" statement is required to compile a KeymanWeb keyboard`);
@ -40,7 +40,8 @@ export class KmwCompilerMessages extends KmnCompilerMessages {
static Error_NotSupportedInKeymanWebOutput = (o:{code:string}) => m(this.ERROR_NotSupportedInKeymanWebOutput,
`Statement ${o.code} is not currently supported in output`);
// Following messages are kmc-kmw only, so use KmwCompiler error namespace
// Following messages are kmw-compiler only, so use KmwCompiler error namespace
static Error_NotAnyRequiresVersion14 = () => m(this.ERROR_NotAnyRequiresVersion14,
`Statement notany in context() match requires version 14.0+ of KeymanWeb`);
static ERROR_NotAnyRequiresVersion14 = SevError | 0x0001;

View file

@ -1,4 +1,4 @@
import { KMX, TouchLayout, TouchLayoutFileReader, TouchLayoutFileWriter } from "@keymanapp/common-types";
import { KMX, Osk, TouchLayout, TouchLayoutFileReader, TouchLayoutFileWriter } from "@keymanapp/common-types";
import { callbacks, IsKeyboardVersion14OrLater, IsKeyboardVersion15OrLater } from "./compiler-globals.js";
import { JavaScript_Key, VKeyNames } from "./javascript-strings.js";
@ -191,7 +191,7 @@ function TransformSpecialKeys14(FDebug: boolean, sLayoutFile: string): string {
return sLayoutFile;
}
export function ValidateLayoutFile(fk: KMX.KEYBOARD, FDebug: boolean, sLayoutFile: string, sVKDictionary: string): VLFOutput { // I4060 // I4139
export function ValidateLayoutFile(fk: KMX.KEYBOARD, FDebug: boolean, sLayoutFile: string, sVKDictionary: string, displayMap: Osk.PuaMap): VLFOutput { // I4060 // I4139
/*
var
@ -265,6 +265,11 @@ var
}
}
// Transform the layout keys with displayMap
if(displayMap) {
Osk.remapTouchLayout(data, displayMap);
}
// If not debugging, then this strips out formatting for a big saving in file size
// This also normalises any values such as Pad or Width which should be strings
let writer = new TouchLayoutFileWriter({formatted: FDebug});

View file

@ -1,5 +1,5 @@
import { KMX, CompilerOptions, CompilerCallbacks, KvkFileReader, KvksFileReader, VisualKeyboard, KeymanFileTypes } from "@keymanapp/common-types";
import { ExpandSentinel, incxstr, xstrlen } from "../util/util.js";
import { KMX, CompilerOptions, CompilerCallbacks, KvkFileReader, VisualKeyboard, KmxFileReader, Osk } from "@keymanapp/common-types";
import { ExpandSentinel, incxstr, xstrlen } from "./util.js";
import { options, nl, FTabStop, setupGlobals, IsKeyboardVersion10OrLater, callbacks } from "./compiler-globals.js";
import { JavaScript_ContextMatch, JavaScript_KeyAsString, JavaScript_Name, JavaScript_OutputString, JavaScript_Rules, JavaScript_Shift, JavaScript_ShiftAsString, JavaScript_Store, zeroPadHex } from './javascript-strings.js';
import { KmwCompilerMessages } from "./messages.js";
@ -35,11 +35,14 @@ export function RequotedString(s: string, RequoteSingleQuotes: boolean = false):
return s;
}
export function WriteCompiledKeyboard(callbacks: CompilerCallbacks, kmnfile: string, kmxfile: string, name: string, keyboard: KMX.KEYBOARD, FDebug: boolean = false): string {
export function WriteCompiledKeyboard(callbacks: CompilerCallbacks, kmnfile: string, keyboardData: Uint8Array, kvkData: Uint8Array, displayMap: Osk.PuaMap, FDebug: boolean = false): string {
let opts: CompilerOptions = {
shouldAddCompilerVersion: false,
saveDebug: FDebug
};
const reader = new KmxFileReader();
const keyboard: KMX.KEYBOARD = reader.read(keyboardData);
setupGlobals(callbacks, opts, FDebug?' ':'', FDebug?'\r\n':'', keyboard, kmnfile);
// let fgp: GROUP;
@ -55,7 +58,7 @@ export function WriteCompiledKeyboard(callbacks: CompilerCallbacks, kmnfile: str
sEmbedJS: string = "", sEmbedCSS: string = "";
let sVisualKeyboard: string = "", sFullName: string = "";
let sBegin_NewContext: string = "", sBegin_PostKeystroke: string = "";
let sLayoutFile: string = "", sVKDictionary: string;
let sLayoutFile: string = "", sVKDictionary: string = "";
let linecomment: string; // I3438
// let HasRules: boolean;
let sModifierBitmask: string;
@ -108,7 +111,7 @@ export function WriteCompiledKeyboard(callbacks: CompilerCallbacks, kmnfile: str
}
}
const sName = 'Keyboard_'+name; //TODO: verify --> GetKeymanWebCompiledNameFromFileName(FInFile);
const sName = 'Keyboard_'+getKeymanWebCompiledNameFromFileName(kmnfile);
if (sHelpFile != '') {
sHelp = '';
@ -174,7 +177,7 @@ export function WriteCompiledKeyboard(callbacks: CompilerCallbacks, kmnfile: str
if (sLayoutFile != '') { // I3483
let path = callbacks.resolveFilename(kmnfile, sLayoutFile);
let result = ValidateLayoutFile(keyboard, options.saveDebug, path, sVKDictionary);
let result = ValidateLayoutFile(keyboard, options.saveDebug, path, sVKDictionary, displayMap);
if(!result.result) {
sLayoutFile = '';
callbacks.reportMessage(KmwCompilerMessages.Error_TouchLayoutFileInvalid());
@ -192,43 +195,8 @@ export function WriteCompiledKeyboard(callbacks: CompilerCallbacks, kmnfile: str
if (sVisualKeyboard != '') {
// TODO: stop reusing sVisualKeyboard for both filename and content
let path = callbacks.resolveFilename(kmnfile, sVisualKeyboard);
let kvk: VisualKeyboard.VisualKeyboard;
if(KeymanFileTypes.filenameIs(path, KeymanFileTypes.Source.VisualKeyboard)) {
let reader = new KvksFileReader();
let source = reader.read(callbacks.loadFile(path));
reader.validate(source, callbacks.loadSchema("kvks")); // TODO: handle exceptions
kvk = reader.transform(source);
// TODO: log errors
}
else {
// Note: very old keyboard sources may still have .kvk as an xml
// file, but we'll treat that as an error rather than silently
// falling back to KvksFileReader
let reader = new KvkFileReader();
kvk = reader.read(callbacks.loadFile(path));
}
// TODO: support &displayMap:
/*if(keyboard.extra.displayMapFilename) {
// Remap using the osk-char-use-rewriter
let mapping: any;
displayMapFilename = this.callbacks.resolveFilename(kmnFilename, displayMapFilename);
try {
let data = this.callbacks.loadFile(displayMapFilename);
mapping = JSON.parse(new TextDecoder().decode(data));
} catch(e) {
// TODO: this.callbacks.reportMessage(CompilerMessages.Error_InvalidDisplayMapFile({filename, e}));
return null;
}
let pua = Osk.parseMapping(mapping);
Osk.remapVisualKeyboard(vk, pua);
}*/
let reader = new KvkFileReader();
let kvk: VisualKeyboard.VisualKeyboard = reader.read(kvkData);
let result = VisualKeyboardFromFile(kvk, options.saveDebug);
if(!result.result) {
// TODO: error
@ -679,3 +647,35 @@ export function FormatModifierAsBitflags(FBitMask: number): string {
}
return result;
}
function cleanKeyboardID(name: string): string {
name = name.toLowerCase();
if(name.length == 0) {
return name;
}
if(name[0].match(/\d/)) {
name = '_' + name;
}
let result = '';
for(let i = 0; i < name.length; i++) {
if(!name[i].match(/[a-z0-9_]/)) {
result += '_';
} else {
result += name[i];
}
}
return result;
}
function getKeymanWebCompiledNameFromFileName(filename: string): string {
let m = /([^/\\]+)$/.exec(filename);
if(!m) {
return null;
}
m = /^(.+?)(\.[^.]+)?$/.exec(m[1]);
if(!m) {
return null;
}
return cleanKeyboardID(m[1]);
}

View file

@ -1,3 +1,4 @@
export { KmnCompilerMessages, CompilerMessages } from './compiler/messages.js';
export { KmnCompiler } from './compiler/compiler.js';
export { KmnCompilerMessages, CompilerMessages } from './compiler/messages.js';
export { KmwCompilerMessages } from './kmw-compiler/messages.js';

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -2,13 +2,12 @@ import { dirname } from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers';
import { KmnCompiler } from '@keymanapp/kmc-kmn';
import { KMX, KmxFileReader } from '@keymanapp/common-types';
import { WriteCompiledKeyboard } from '../src/compiler/write-compiled-keyboard.js';
import { KmnCompiler } from '../../src/compiler/compiler.js';
import { WriteCompiledKeyboard } from '../../src/kmw-compiler/write-compiled-keyboard.js';
import { extractTouchLayout } from './util.js';
const __dirname = dirname(fileURLToPath(import.meta.url)).replace(/\\/g, '/');
const fixturesDir = __dirname + '/../../test/fixtures/';
const fixturesDir = __dirname + '/../../../test/fixtures/kmw/';
const fixtureName = fixturesDir + 'khmer_angkor.js';
const infile = fixturesDir + 'khmer_angkor.kmn';
const outfile = fixturesDir + 'khmer_angkor.kmx'; // intermediate outfile
@ -26,10 +25,10 @@ if(!await kmnCompiler.init(callbacks)) {
process.exit(1);
}
let result = kmnCompiler.runCompiler(infile, outfile, {
shouldAddCompilerVersion: false,
saveDebug: true, // TODO: we should probably use passed debug flag
target: 'js'
});
if(!result) {
@ -37,10 +36,7 @@ if(!result) {
process.exit(1);
}
const reader = new KmxFileReader();
const keyboard: KMX.KEYBOARD = reader.read(result.kmx.data);
const js = WriteCompiledKeyboard(callbacks, infile, outfile, 'khmer_angkor', keyboard, true);
const js = WriteCompiledKeyboard(callbacks, infile, result.kmx.data, result.kvk.data, null, true);
callbacks.printMessages();

View file

@ -1,17 +1,16 @@
import 'mocha';
import { assert } from 'chai';
// import sinonChai from 'sinon-chai';
import { WriteCompiledKeyboard } from '../src/compiler/write-compiled-keyboard.js';
import { WriteCompiledKeyboard } from '../../src/kmw-compiler/write-compiled-keyboard.js';
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers';
import { KmnCompiler } from '@keymanapp/kmc-kmn';
import { KMX, KmxFileReader } from '@keymanapp/common-types';
import { KmnCompiler } from '../../src/compiler/compiler.js';
import { extractTouchLayout } from './util.js';
const __dirname = dirname(fileURLToPath(import.meta.url)).replace(/\\/g, '/');
const fixturesDir = __dirname + '/../../test/fixtures/';
const fixturesDir = __dirname + '/../../../test/fixtures/kmw/';
//const baselineDir = __dirname + '/../../../../../common/test/keyboards/baseline/';
// chai.use(sinonChai);
@ -42,15 +41,11 @@ describe('Compiler class', function() {
let result = kmnCompiler.runCompiler(infile, outfile, {
shouldAddCompilerVersion: false,
saveDebug: true, // TODO: we should probably use passed debug flag
target: 'js'
});
assert.isNotNull(result);
const reader = new KmxFileReader();
const keyboard: KMX.KEYBOARD = reader.read(result.kmx.data);
const js = WriteCompiledKeyboard(callbacks, infile, outfile, 'khmer_angkor', keyboard, true);
const js = WriteCompiledKeyboard(callbacks, infile, result.kmx?.data, result.kvk?.data, null, true);
const fjs = fs.readFileSync(fixtureName, 'utf8');

View file

@ -78,8 +78,8 @@ describe('Compiler class', function() {
it('should compile a keyboard with visual keyboard', async function() {
const compiler = new KmnCompiler();
const callbacks = new TestCompilerCallbacks();
assert(await compiler.init(callbacks));
assert(compiler.verifyInitialized());
assert.isTrue(await compiler.init(callbacks));
assert.isTrue(compiler.verifyInitialized());
const fixtureDir = keyboardsDir + 'caps_lock_layer_3620/'
const infile = fixtureDir + 'source/caps_lock_layer_3620.kmn';
@ -89,10 +89,10 @@ describe('Compiler class', function() {
const resultingKmxfile = __dirname + '/caps_lock_layer_3620.kmx';
const resultingKvkfile = __dirname + '/caps_lock_layer_3620.kvk';
assert(compiler.run(infile, resultingKmxfile, {saveDebug: true, shouldAddCompilerVersion: false}));
assert.isTrue(compiler.run(infile, resultingKmxfile, {saveDebug: true, shouldAddCompilerVersion: false}));
assert(fs.existsSync(resultingKmxfile));
assert(fs.existsSync(resultingKvkfile));
assert.isTrue(fs.existsSync(resultingKmxfile));
assert.isTrue(fs.existsSync(resultingKvkfile));
const kmxData = fs.readFileSync(resultingKmxfile);
const kmxFixtureData = fs.readFileSync(kmxFixture);

View file

@ -14,7 +14,8 @@
},
"include": [
"**/test-*.ts",
"./helpers/index.ts"
"./helpers/index.ts",
"./kmw/util.ts"
],
"references": [
{ "path": "../../../../common/web/keyman-version/tsconfig.esm.json" },

View file

@ -1,15 +0,0 @@
module.exports = {
parserOptions: {
project: ["./tsconfig.json", "./test/tsconfig.json"],
},
ignorePatterns: ["test/fixtures/**/*"],
overrides: [
{
files:"src/**/*.ts",
extends: ["../../../common/web/eslint/eslintNoNodeImports.js"],
}
],
rules: {
"prefer-const": "off", // TODO: enable this once infrastructure is in place and cleanup the problem cases
},
};

View file

@ -1,39 +0,0 @@
#
# Keyman Developer - kmc KMW Keyboard Compiler Makefile
#
!include ..\Defines.mak
# We do configure here because parent Makefile calls this first; other
# kmc and kmc-* makefiles don't do it
build: configure .virtual
$(GIT_BASH_FOR_KEYMAN) build.sh build
configure: .virtual
$(GIT_BASH_FOR_KEYMAN) build.sh configure
clean: .virtual
$(GIT_BASH_FOR_KEYMAN) build.sh clean
test: .virtual
$(GIT_BASH_FOR_KEYMAN) build.sh test
# build.sh bundle must be run from shell as it requires a temp folder to be
# passed in. See inst/download.in.mak for instantiation.
publish: .virtual
$(GIT_BASH_FOR_KEYMAN) build.sh publish
signcode:
@rem nothing to do
wrap-symbols:
@rem nothing to do
test-manifest:
@rem nothing to do
install:
@rem nothing to do
!include ..\Target.mak

View file

@ -1 +0,0 @@
# kmc-kmw

View file

@ -1,72 +0,0 @@
#!/usr/bin/env bash
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/build-utils.sh"
## END STANDARD BUILD SCRIPT INCLUDE
cd "$THIS_SCRIPT_PATH"
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
builder_describe "Build Keyman kmc KMW Keyboard Compiler module" \
"@/common/web/types" \
"@/developer/src/kmc-kmn" \
"configure" \
"build" \
"clean" \
"test" \
"pack build a local .tgz pack for testing" \
"publish publish to npm" \
"--dry-run,-n don't actually publish, just dry run"
builder_describe_outputs \
configure /node_modules \
build build/src/main.js
builder_parse "$@"
#-------------------------------------------------------------------------------------------------------------------
function copy_schema() {
# We need the schema file at runtime and bundled, so always copy it for all
# actions except `clean` and `configure`
mkdir -p "$THIS_SCRIPT_PATH/build/src/"
cp "$KEYMAN_ROOT/common/schemas/keyman-touch-layout/keyman-touch-layout.spec.json" "$THIS_SCRIPT_PATH/build/src/"
cp "$KEYMAN_ROOT/common/schemas/kvks/kvks.schema.json" "$THIS_SCRIPT_PATH/build/src/"
}
function do_build() {
copy_schema
tsc --build
}
function do_test() {
copy_schema
eslint .
cd test
tsc --build
cd ..
# TODO: add c8 for coverage
mocha
}
function do_publish() {
copy_schema
builder_publish_to_npm
}
function do_pack() {
copy_schema
builder_publish_to_pack
}
#-------------------------------------------------------------------------------------------------------------------
builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo
builder_run_action configure verify_npm_setup
builder_run_action build do_build
builder_run_action test do_test
builder_run_action pack do_pack
builder_run_action publish do_publish

View file

@ -1,57 +0,0 @@
{
"name": "@keymanapp/kmc-kmw",
"description": "Keyman Developer KMW keyboard compiler",
"keywords": [
"keyboard",
"keyman",
"ldml",
"unicode"
],
"type": "module",
"exports": {
".": "./build/src/main.js"
},
"scripts": {
"build": "gosh ./build.sh build",
"test": "gosh ./build.sh test",
"prepublishOnly": "npm run build"
},
"author": "Marc Durdin <marc@keyman.com> (https://github.com/mcdurdin)",
"license": "MIT",
"bugs": {
"url": "https://github.com/keymanapp/keyman/issues"
},
"dependencies": {
"@keymanapp/common-types": "*",
"@keymanapp/keyman-version": "*",
"@keymanapp/kmc-kmn": "*",
"ajv": "^8.11.0",
"restructure": "git+https://github.com/keymanapp/dependency-restructure.git#7a188a1e26f8f36a175d95b67ffece8702363dfc",
"semver": "^7.3.7",
"xml2js": "git+https://github.com/keymanapp/dependency-node-xml2js#535fe732dc408d697e0f847c944cc45f0baf0829"
},
"devDependencies": {
"@types/chai": "^4.1.7",
"@types/mocha": "^5.2.7",
"@types/node": "^10.14.6",
"@types/semver": "^7.3.12",
"@types/xml2js": "^0.4.5",
"c8": "^7.12.0",
"chai": "^4.3.4",
"chalk": "^2.4.2",
"mocha": "^8.4.0",
"ts-node": "^9.1.1",
"typescript": "^4.9.5",
"@keymanapp/resources-gosh": "*"
},
"mocha": {
"spec": "build/test/**/test-*.js",
"require": [
"source-map-support/register"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
}
}

View file

@ -1,2 +0,0 @@
export { WriteCompiledKeyboard } from './compiler/write-compiled-keyboard.js';

View file

@ -1,7 +0,0 @@
Keyman kmn kmw Keyboard Compiler Tests
======================================
Test
----
../build.sh test

View file

@ -1,26 +0,0 @@
{
"extends": "../../kmc/tsconfig.kmc-base.json",
"compilerOptions": {
"rootDir": ".",
"rootDirs": ["./", "../src/"],
"outDir": "../build/test",
"baseUrl": ".",
"allowSyntheticDefaultImports": true, // for chai
"paths": {
"@keymanapp/common-types": ["../../../../common/web/types/src/main"],
"@keymanapp/developer-test-helpers": ["../../common/web/test-helpers/index"],
"@keymanapp/kmc-kmn": ["../../kmc-kmn/src/main"],
},
},
"include": [
"**/test-*.ts",
"util.ts"
],
"references": [
{ "path": "../../../../common/web/types/" },
{ "path": "../../kmc-kmn/" },
{ "path": "../../common/web/test-helpers/" },
{ "path": "../" }
]
}

View file

@ -1,22 +0,0 @@
{
"extends": "../../../tsconfig.esm-base.json",
"compilerOptions": {
"outDir": "build/src/",
"rootDir": "src/",
"baseUrl": ".",
"paths": {
"@keymanapp/common-types": ["../../../common/web/types/src/main"],
"@keymanapp/kmc-kmn": ["../kmc-kmn/src/main"],
},
},
"include": [
"src/**/*.ts"
],
"references": [
{ "path": "../../../common/web/types/" },
{ "path": "../kmc-kmn/" },
{ "path": "../../../core/include/ldml/"},
]
}

View file

@ -22,7 +22,6 @@ builder_describe "Build Keyman Keyboard Compiler kmc" \
"@/common/web/types" \
"@/developer/src/kmc-analyze" \
"@/developer/src/kmc-kmn" \
"@/developer/src/kmc-kmw" \
"@/developer/src/kmc-ldml" \
"@/developer/src/kmc-model" \
"@/developer/src/kmc-model-info" \
@ -116,7 +115,6 @@ readonly PACKAGES=(
core/include/ldml
developer/src/kmc-analyze
developer/src/kmc-kmn
developer/src/kmc-kmw
developer/src/kmc-ldml
developer/src/kmc-model
developer/src/kmc-model-info

View file

@ -41,7 +41,6 @@
"@keymanapp/common-types": "*",
"@keymanapp/kmc-analyze": "*",
"@keymanapp/kmc-kmn": "*",
"@keymanapp/kmc-kmw": "*",
"@keymanapp/kmc-ldml": "*",
"@keymanapp/kmc-model": "*",
"@keymanapp/kmc-model-info": "*",

View file

@ -9,7 +9,6 @@
"@keymanapp/common-types": [ "../../../common/web/types/src/main" ],
"@keymanapp/kmc-analyze": [ "../kmc-analyze/src/index" ],
"@keymanapp/kmc-kmn": [ "../kmc-kmn/src/main" ],
"@keymanapp/kmc-kmw": [ "../kmc-kmw/src/main" ],
"@keymanapp/kmc-ldml": [ "../kmc-ldml/src/main" ],
"@keymanapp/kmc-model": [ "../kmc-model/src/main" ],
"@keymanapp/kmc-model-info": [ "../kmc-model-info/src/model-info-compiler" ],
@ -24,7 +23,6 @@
{ "path": "../../../common/web/types" },
{ "path": "../kmc-analyze" },
{ "path": "../kmc-kmn" },
{ "path": "../kmc-kmw" },
{ "path": "../kmc-ldml" },
{ "path": "../kmc-model" },
{ "path": "../kmc-model-info" },

View file

@ -18,6 +18,7 @@
/* Compile target */
// TODO: deprecate these
#define CKF_KEYMAN 0
#define CKF_KEYMANWEB 1
@ -29,9 +30,14 @@ struct KMCMP_COMPILER_OPTIONS {
int target; // CKF_KEYMAN, CKF_KEYMANWEB
};
#define COMPILETARGETS_KMX 0x01
#define COMPILETARGETS_JS 0x02
#define COMPILETARGETS__MASK 0x03
struct KMCMP_COMPILER_RESULT {
void* kmx;
size_t kmxSize;
int targets; /// COMPILETARGETS__MASK = COMPILETARGETS_KMX | COMPILETARGETS_JS
std::string kvksFilename;
std::string displayMapFilename;
};

View file

@ -42,6 +42,7 @@ bool CompileKeyboardBuffer(KMX_BYTE* infile, int sz, PFILE_KEYBOARD fk)
fk->dpDeadKeyArray = NULL;
fk->cxVKDictionary = 0; // I3438
fk->dpVKDictionary = NULL; // I3438
fk->extra->targets = COMPILETARGETS_KMX;
fk->extra->kvksFilename = u"";
fk->extra->displayMapFilename = u"";
/* fk->szMessage[0] = 0;

View file

@ -96,6 +96,7 @@
#include <xstring.h>
#include <codecvt>
#include <locale>
#include <string>
#include "UnreachableRules.h"
#include "CheckForDuplicates.h"
@ -140,6 +141,7 @@ KMX_BOOL IsSameToken(PKMX_WCHAR *p, KMX_WCHAR const * token);
KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, int offset, int IsUnicode);
PKMX_WCHAR GetDelimitedString(PKMX_WCHAR *p, KMX_WCHAR const * Delimiters, KMX_WORD Flags);
KMX_DWORD GetXString(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_WCHAR const * token, PKMX_WCHAR output, int max, int offset, PKMX_WCHAR *newp, int isVKey, int isUnicode);
int GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store);
int GetGroupNum(PFILE_KEYBOARD fk, PKMX_WCHAR p);
@ -1064,6 +1066,7 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE
case TSS_TARGETS: // I4504
VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyTargets);
fk->extra->targets = GetCompileTargetsFromTargetsStore(sp->dpString);
break;
case TSS_WINDOWSLANGUAGES:
@ -1135,7 +1138,7 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE
case TSS_DISPLAYMAP:
// This store is allowed in older versions of Keyman, as it is a
// compile-time only feature. Implemented only in kmc-kmn/kmc-kmw, not in
// compile-time only feature. Implemented only in kmc-kmn, not in
// the legacy compilers.
fk->extra->displayMapFilename = sp->dpString;
break;
@ -1146,6 +1149,45 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE
return CERR_None;
}
int GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store) {
// Compile to .kmx
const std::vector<std::u16string> KMXKeymanTargets{
u"windows", u"macosx", u"linux", u"desktop"
};
// Compile to .js
const std::vector<std::u16string> KMWKeymanTargets{
u"web", u"iphone", u"ipad", u"androidphone", u"androidtablet",
u"mobile", u"tablet"
};
const std::u16string AnyTarget = u"any";
int result = 0;
auto p = new KMX_WCHAR[u16len(store)+1];
u16cpy(p, store);
KMX_WCHAR* ctx;
auto token = u16tok(p, u" ", &ctx);
while(token) {
if(AnyTarget == token) {
result |= COMPILETARGETS_KMX | COMPILETARGETS_JS;
}
for(auto p: KMXKeymanTargets) {
if(p == token) result |= COMPILETARGETS_KMX;
}
for(auto p: KMWKeymanTargets) {
if(p == token) result |= COMPILETARGETS_JS;
}
token = u16tok(nullptr, u" ", &ctx);
// Future: consider warnings on invalid compile targets?
}
delete[] p;
return result;
}
KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString) { // I4140
/* version format \d+(\.\d+)* e.g. 9.0.3, 1.0, 1.2.3.4, 6.2.1.4.6.4, blank is not allowed */

View file

@ -103,6 +103,8 @@ EXTERN bool kmcmp_CompileKeyboard(
result.kmx = data;
result.kmxSize = dataSize;
// TODO: can we eliminate this intermediate structure?
result.targets = fk.extra->targets;
result.kvksFilename = string_from_u16string(fk.extra->kvksFilename); // convert to UTF8
result.displayMapFilename = string_from_u16string(fk.extra->displayMapFilename); // convert to UTF8

View file

@ -55,17 +55,20 @@ struct WASM_COMPILER_RESULT {
int kmxSize;
// Following are compiler side-channel data, required for
// follow-on transform
int targets; /* COMPILETARGETS_KMX | COMPILETARGETS_JS */
std::string kvksFilename;
std::string displayMapFilename;
// TODO: additional data to be passed back
};
WASM_COMPILER_RESULT kmcmp_wasm_compile(std::string pszInfile, const KMCMP_COMPILER_OPTIONS options, const WASM_COMPILER_INTERFACE intf) {
WASM_COMPILER_RESULT r = {false};
WASM_COMPILER_RESULT r;
KMCMP_COMPILER_RESULT kr;
r.result = false;
r.kmx = 0;
r.kmxSize = 0;
r.targets = 0;
r.kvksFilename = "";
r.displayMapFilename = "";
@ -84,6 +87,7 @@ WASM_COMPILER_RESULT kmcmp_wasm_compile(std::string pszInfile, const KMCMP_COMPI
r.kmxSize = (int) kr.kmxSize;
r.kvksFilename = kr.kvksFilename;
r.displayMapFilename = kr.displayMapFilename;
r.targets = kr.targets;
}
return r;
@ -110,6 +114,7 @@ EMSCRIPTEN_BINDINGS(compiler_interface) {
.property("result", &WASM_COMPILER_RESULT::result)
.property("kmx", &WASM_COMPILER_RESULT::kmx)
.property("kmxSize", &WASM_COMPILER_RESULT::kmxSize)
.property("targets", &WASM_COMPILER_RESULT::targets)
.property("kvksFilename", &WASM_COMPILER_RESULT::kvksFilename)
.property("displayMapFilename", &WASM_COMPILER_RESULT::displayMapFilename)
;

View file

@ -123,6 +123,7 @@ typedef FILE_VKDICTIONARY *PFILE_VKDICTIONARY;
* Extra metadata for API consumers
*/
struct FILE_KEYBOARD_EXTRA {
int targets;
std::string kmnFilename; // utf-8
std::u16string kvksFilename; // utf-16, original TSS_VISUALKEYBOARD value
std::u16string displayMapFilename; // utf-16, original TSS_DISPLAY_MAP value

View file

@ -224,7 +224,7 @@ int u16ncmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) {
return 0;
}
KMX_WCHAR * u16tok(KMX_WCHAR *p, KMX_WCHAR ch, KMX_WCHAR **ctx) {
KMX_WCHAR * u16tok(KMX_WCHAR *p, const KMX_WCHAR ch, KMX_WCHAR **ctx) {
if (!p) {
p = *ctx;
if (!p) return NULL;
@ -246,7 +246,7 @@ KMX_WCHAR * u16tok(KMX_WCHAR *p, KMX_WCHAR ch, KMX_WCHAR **ctx) {
return p;
}
KMX_WCHAR * u16tok(KMX_WCHAR* p, KMX_WCHAR* delim, KMX_WCHAR** ctx) {
KMX_WCHAR * u16tok(KMX_WCHAR* p, const KMX_WCHAR* delim, KMX_WCHAR** ctx) {
if (!p) {
p = *ctx;
if (!p) return NULL;

View file

@ -26,8 +26,8 @@ const KMX_WCHAR * u16cpy(KMX_WCHAR *dst, const KMX_WCHAR *src);
const KMX_WCHAR * u16rchr(const KMX_WCHAR *p, KMX_WCHAR ch) ;
const KMX_WCHAR * u16chr(const KMX_WCHAR *p, KMX_WCHAR ch) ;
const KMX_WCHAR * u16ncat(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max);
KMX_WCHAR * u16tok(KMX_WCHAR *p, KMX_WCHAR ch, KMX_WCHAR **ctx) ;
KMX_WCHAR * u16tok(KMX_WCHAR* p, KMX_WCHAR* ch, KMX_WCHAR** ctx) ;
KMX_WCHAR * u16tok(KMX_WCHAR *p, const KMX_WCHAR ch, KMX_WCHAR **ctx) ;
KMX_WCHAR * u16tok(KMX_WCHAR* p, const KMX_WCHAR* ch, KMX_WCHAR** ctx) ;
long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) ;
double u16tof( KMX_WCHAR* str);

View file

@ -23,6 +23,7 @@
void setup();
void test_kmcmp_CompileKeyboard(char *kmn_file);
void test_GetCompileTargetsFromTargetsStore();
int main(int argc, char *argv[]) {
if(argc < 1) {
@ -33,6 +34,8 @@ int main(int argc, char *argv[]) {
setup();
test_kmcmp_CompileKeyboard(argv[1]);
test_GetCompileTargetsFromTargetsStore();
return 0;
}
@ -65,4 +68,17 @@ void test_kmcmp_CompileKeyboard(char *kmn_file) {
assert(error_vec[0] == CERR_CannotReadInfile);
unlink(kmn_file);
}
}
extern int GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store);
void test_GetCompileTargetsFromTargetsStore() {
assert(GetCompileTargetsFromTargetsStore(u"any") == (COMPILETARGETS_KMX | COMPILETARGETS_JS));
assert(GetCompileTargetsFromTargetsStore(u"windows") == COMPILETARGETS_KMX);
assert(GetCompileTargetsFromTargetsStore(u"desktop") == COMPILETARGETS_KMX);
assert(GetCompileTargetsFromTargetsStore(u"mobile") == COMPILETARGETS_JS);
assert(GetCompileTargetsFromTargetsStore(u"web") == COMPILETARGETS_JS);
assert(GetCompileTargetsFromTargetsStore(u"desktop mobile") == (COMPILETARGETS_KMX | COMPILETARGETS_JS));
assert(GetCompileTargetsFromTargetsStore(u"desktop tablet") == (COMPILETARGETS_KMX | COMPILETARGETS_JS));
assert(GetCompileTargetsFromTargetsStore(u"foo bar baz") == 0);
}

272
package-lock.json generated
View file

@ -12,7 +12,6 @@
"developer/src/common/web/test-helpers",
"developer/src/kmc-analyze",
"developer/src/kmc-kmn",
"developer/src/kmc-kmw",
"developer/src/kmc-ldml",
"developer/src/kmc-model",
"developer/src/kmc-model-info",
@ -644,7 +643,6 @@
"@keymanapp/keyman-version": "*",
"@keymanapp/kmc-analyze": "*",
"@keymanapp/kmc-kmn": "*",
"@keymanapp/kmc-kmw": "*",
"@keymanapp/kmc-ldml": "*",
"@keymanapp/kmc-model": "*",
"@keymanapp/kmc-model-info": "*",
@ -681,6 +679,7 @@
"commander": "^10.0.0"
},
"devDependencies": {
"@keymanapp/resources-gosh": "*",
"@types/chai": "^4.1.7",
"@types/mocha": "^5.2.7",
"@types/node": "^10.14.6",
@ -935,7 +934,8 @@
"name": "@keymanapp/kmc-kmn",
"license": "MIT",
"dependencies": {
"@keymanapp/keyman-version": "*"
"@keymanapp/keyman-version": "*",
"@keymanapp/kmc-kmn": "*"
},
"devDependencies": {
"@keymanapp/developer-test-helpers": "*",
@ -1271,268 +1271,6 @@
"node": ">=0.3.1"
}
},
"developer/src/kmc-kmw": {
"name": "@keymanapp/kmc-kmw",
"license": "MIT",
"dependencies": {
"@keymanapp/common-types": "*",
"@keymanapp/keyman-version": "*",
"@keymanapp/kmc-kmn": "*",
"ajv": "^8.11.0",
"restructure": "git+https://github.com/keymanapp/dependency-restructure.git#7a188a1e26f8f36a175d95b67ffece8702363dfc",
"semver": "^7.3.7",
"xml2js": "git+https://github.com/keymanapp/dependency-node-xml2js#535fe732dc408d697e0f847c944cc45f0baf0829"
},
"devDependencies": {
"@types/chai": "^4.1.7",
"@types/mocha": "^5.2.7",
"@types/node": "^10.14.6",
"@types/semver": "^7.3.12",
"@types/xml2js": "^0.4.5",
"c8": "^7.12.0",
"chai": "^4.3.4",
"chalk": "^2.4.2",
"mocha": "^8.4.0",
"ts-node": "^9.1.1",
"typescript": "^4.9.5"
}
},
"developer/src/kmc-kmw/node_modules/@types/mocha": {
"version": "5.2.7",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
"integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
"dev": true
},
"developer/src/kmc-kmw/node_modules/@types/node": {
"version": "10.17.60",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
"integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==",
"dev": true
},
"developer/src/kmc-kmw/node_modules/ajv": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"developer/src/kmc-kmw/node_modules/ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"dependencies": {
"color-convert": "^1.9.0"
},
"engines": {
"node": ">=4"
}
},
"developer/src/kmc-kmw/node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"engines": {
"node": ">=4"
}
},
"developer/src/kmc-kmw/node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"dependencies": {
"color-name": "1.1.3"
}
},
"developer/src/kmc-kmw/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
"developer/src/kmc-kmw/node_modules/js-yaml": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
"integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
"dev": true,
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"developer/src/kmc-kmw/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"developer/src/kmc-kmw/node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"developer/src/kmc-kmw/node_modules/mocha": {
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz",
"integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==",
"dev": true,
"dependencies": {
"@ungap/promise-all-settled": "1.1.2",
"ansi-colors": "4.1.1",
"browser-stdout": "1.3.1",
"chokidar": "3.5.1",
"debug": "4.3.1",
"diff": "5.0.0",
"escape-string-regexp": "4.0.0",
"find-up": "5.0.0",
"glob": "7.1.6",
"growl": "1.10.5",
"he": "1.2.0",
"js-yaml": "4.0.0",
"log-symbols": "4.0.0",
"minimatch": "3.0.4",
"ms": "2.1.3",
"nanoid": "3.1.20",
"serialize-javascript": "5.0.1",
"strip-json-comments": "3.1.1",
"supports-color": "8.1.1",
"which": "2.0.2",
"wide-align": "1.1.3",
"workerpool": "6.1.0",
"yargs": "16.2.0",
"yargs-parser": "20.2.4",
"yargs-unparser": "2.0.0"
},
"bin": {
"_mocha": "bin/_mocha",
"mocha": "bin/mocha"
},
"engines": {
"node": ">= 10.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mochajs"
}
},
"developer/src/kmc-kmw/node_modules/mocha/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"developer/src/kmc-kmw/node_modules/mocha/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"developer/src/kmc-kmw/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
"developer/src/kmc-kmw/node_modules/restructure": {
"version": "3.0.0",
"resolved": "git+ssh://git@github.com/keymanapp/dependency-restructure.git#7a188a1e26f8f36a175d95b67ffece8702363dfc",
"integrity": "sha512-TxgE+TFgblOfmvJyv9TCzABfDo4nvNHeYD0+awQ5UoE/KhSuENJ1Uhc1rtegx8SbmvI3nqXFaHgnVATNcCOhXw==",
"license": "MIT"
},
"developer/src/kmc-kmw/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"developer/src/kmc-kmw/node_modules/supports-color/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"developer/src/kmc-kmw/node_modules/ts-node": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz",
"integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==",
"dev": true,
"dependencies": {
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"source-map-support": "^0.5.17",
"yn": "3.1.1"
},
"bin": {
"ts-node": "dist/bin.js",
"ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js"
},
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"typescript": ">=2.7"
}
},
"developer/src/kmc-kmw/node_modules/ts-node/node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true,
"engines": {
"node": ">=0.3.1"
}
},
"developer/src/kmc-ldml": {
"name": "@keymanapp/kmc-ldml",
"license": "MIT",
@ -2829,10 +2567,6 @@
"resolved": "developer/src/kmc-kmn",
"link": true
},
"node_modules/@keymanapp/kmc-kmw": {
"resolved": "developer/src/kmc-kmw",
"link": true
},
"node_modules/@keymanapp/kmc-ldml": {
"resolved": "developer/src/kmc-ldml",
"link": true

View file

@ -22,7 +22,6 @@
"developer/src/common/web/test-helpers",
"developer/src/kmc-analyze",
"developer/src/kmc-kmn",
"developer/src/kmc-kmw",
"developer/src/kmc-ldml",
"developer/src/kmc-model",
"developer/src/kmc-model-info",

View file

@ -16,8 +16,6 @@
{ "path": "./developer/src/kmc-analyze/tsconfig.json" },
{ "path": "./developer/src/kmc-kmn/test/tsconfig.json" },
{ "path": "./developer/src/kmc-kmn/tsconfig.json" },
{ "path": "./developer/src/kmc-kmw/test/tsconfig.json" },
{ "path": "./developer/src/kmc-kmw/tsconfig.json" },
{ "path": "./developer/src/kmc-ldml/test/tsconfig.json" },
{ "path": "./developer/src/kmc-ldml/tsconfig.json" },
{ "path": "./developer/src/kmc-model/test/tsconfig.json" },