mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-08 15:07:33 +00:00
Merge branch 'master' into feat/core/9121-more-vars-epic-ldml
This commit is contained in:
commit
505a45e933
98 changed files with 461 additions and 3347 deletions
|
|
@ -21,9 +21,7 @@
|
|||
"exports": {
|
||||
".": "./build/obj/index.js",
|
||||
"./lib": {
|
||||
"types": "./build/lib/index.d.ts",
|
||||
"import": "./build/lib/index.mjs",
|
||||
"require": "./build/lib/index.cjs"
|
||||
"types": "./build/lib/index.d.ts"
|
||||
},
|
||||
"./obj/*.js": "./build/obj/*.js"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@
|
|||
"exports": {
|
||||
".": "./build/obj/index.js",
|
||||
"./lib": {
|
||||
"import": "./build/lib/index.mjs",
|
||||
"require": "./build/lib/index.cjs"
|
||||
"types": "./build/lib/index.d.ts"
|
||||
},
|
||||
"./obj/*.js": "./build/obj/*.js"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match iOS device widths -->
|
||||
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" /> -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>LMLayer Testing</title>
|
||||
<style type='text/css'>
|
||||
body {padding-left:20px;margin-left:12px; font-family:Tahoma,Helvetica}
|
||||
h1 {color: #800;margin-left:10px;}
|
||||
h2 {color: #008;margin-left:20px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Language-Modeling Layer module testing</h1>
|
||||
<h2><a href="./simple-webworker">A simple basic WebWorker.</a></h2> Designed as a baseline functionality test we can run against various platforms as a first-stage canary of sorts.
|
||||
<h2><a href="./one-stage-embedded-webworker">An embedded WebWorker prototype.</a></h2> A prototype for directly embedding a WebWorker's code within a "master" script.
|
||||
<h2><a href="./two-stage-embedded-webworker">A better embedded WebWorker prototype.</a></h2> A prototype for two-stage compilation of a master/slave main-script/WebWorker pair.
|
||||
<h2><a href="./post-blob-webworker/">Sending code via a Blob URI</a></h2> A prototype for sending code over to a WebWorker via a Blob URI reference.
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
main.js
|
||||
main.js.map
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Compiles the Language Modeling Layer for common use in predictive text and autocorrective applications.
|
||||
# Designed for optimal compatibility with the Keyman Suite.
|
||||
#
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
. "${THIS_SCRIPT%/*}/../../../../resources/build/build-utils.sh"
|
||||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
## END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
display_usage ( ) {
|
||||
echo "build.sh [-clean]"
|
||||
echo
|
||||
echo " -clean to erase pre-existing build products before a re-build"
|
||||
}
|
||||
|
||||
SOURCE="testing/one-stage-embedded-webworker"
|
||||
|
||||
echo "Node.js + dependencies check"
|
||||
npm install --no-optional
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Build environment setup error detected! Please ensure Node.js is installed!"
|
||||
fi
|
||||
|
||||
# A nice, extensible method for -clean operations. Add to this as necessary.
|
||||
clean ( ) {
|
||||
rm -rf "./*.js"
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Failed to erase the prior build."
|
||||
fi
|
||||
}
|
||||
|
||||
# Process command-line arguments
|
||||
while [[ $# -gt 0 ]] ; do
|
||||
key="$1"
|
||||
case $key in
|
||||
-clean)
|
||||
clean
|
||||
;;
|
||||
esac
|
||||
shift # past the processed argument
|
||||
done
|
||||
|
||||
npm run tsc -- -p $SOURCE/tsconfig.json
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Compilation failed."
|
||||
fi
|
||||
|
||||
echo "Typescript compilation successful."
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match phone and tablet device widths -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
|
||||
<!-- Allow KeymanWeb to be saved to the iPhone home screen -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>Embedded WebWorker test</title>
|
||||
|
||||
<!-- Your page CSS -->
|
||||
<style type='text/css'>
|
||||
body {font-family: Tahoma,helvetica;}
|
||||
h3 {font-size: 1em;font-weight:normal;color: darkred; margin-bottom: 4px}
|
||||
.test {font-size: 1.5em; width:80%; min-height:30px; border: 1px solid gray;}
|
||||
#KeymanWebControl {width:50%;min-width:600px;}
|
||||
</style>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body>
|
||||
<h2>LM Layer Testing - One-Stage Embedded WebWorkers</h2>
|
||||
<p>This page serves as a prototype for embedding a WebWorker's code within its "master" script
|
||||
across the TypeScript transpilation boundary.</p>
|
||||
<input type='text' id='txtFeedback' value="No clicks yet." readonly></input> <br>
|
||||
<script>
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = "No clicks yet.";
|
||||
</script>
|
||||
<input type='button' id='btnInput' onclick='canaryWorker.postMessage("Hello.");' value='Message the WebWorker.' />
|
||||
|
||||
<h3><a href="../index.html">Return to testing home page</a></h3>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
// Useful for passing class constructors
|
||||
type Workable<T> = {
|
||||
new (...args: any[]): T;
|
||||
// Requires a static implementation.
|
||||
onmessage(e: any): void;
|
||||
};
|
||||
|
||||
class A {
|
||||
a(x: number, y: number):number {
|
||||
return x + y;
|
||||
}
|
||||
}
|
||||
|
||||
var WorkerGlobals = {
|
||||
counter: 0,
|
||||
a: A
|
||||
}
|
||||
|
||||
class WorkerCore {
|
||||
static WorkerGlobals = WorkerGlobals;
|
||||
//static counter: number;
|
||||
|
||||
static onmessage(e: any) {
|
||||
WorkerGlobals.counter++;
|
||||
|
||||
console.log("Message received from main page: ", e.data);
|
||||
|
||||
// Forces TypeScript to interpret this line as plain JavaScript, as it uses a non-Worker definition.
|
||||
// @ts-ignore
|
||||
postMessage(WorkerGlobals.counter);
|
||||
}
|
||||
}
|
||||
|
||||
function createWorkerFromClasses(globals: object, fn: Workable<object>): Worker {
|
||||
var sep = ";\n";
|
||||
let glb = "var WorkerGlobals = " + JSON.stringify(globals);
|
||||
let wc = "var onmessage = " + fn.onmessage.toString();
|
||||
var blob = new Blob([glb, sep, wc], { type: 'text/javascript' });
|
||||
let url = URL.createObjectURL(blob);
|
||||
|
||||
return new Worker(url);
|
||||
}
|
||||
|
||||
var canaryWorker = createWorkerFromClasses(WorkerGlobals, WorkerCore);
|
||||
|
||||
canaryWorker.onmessage = function(e) {
|
||||
var counter = e.data; // Number of times the WebWorker has been messaged.
|
||||
console.log("Received message from the WebWorker: " + e.data);
|
||||
|
||||
var txtFeedback = <HTMLInputElement>document.getElementById("txtFeedback");
|
||||
txtFeedback.value = counter + " click(s)";
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": false,
|
||||
"module": "none",
|
||||
"outDir": "./",
|
||||
"inlineSources": true,
|
||||
"sourceMap": true,
|
||||
"target": "es5"
|
||||
},
|
||||
"files" : [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
// receive a message and execute its uri
|
||||
onmessage = function (e) {
|
||||
let uri = e.data.uri;
|
||||
importScripts(uri);
|
||||
};
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match phone and tablet device widths -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
|
||||
<!-- Allow KeymanWeb to be saved to the iPhone home screen -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>Blob URI test</title>
|
||||
|
||||
<!-- Your page CSS -->
|
||||
<style type='text/css'>
|
||||
body {font-family: Tahoma,helvetica;}
|
||||
h3 {font-size: 1em;font-weight:normal;color: darkred; margin-bottom: 4px}
|
||||
.test {font-size: 1.5em; width:80%; min-height:30px; border: 1px solid gray;}
|
||||
#KeymanWebControl {width:50%;min-width:600px;}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
if (window.Worker) {
|
||||
var canaryWorker = new Worker('canaryWorker.js');
|
||||
|
||||
canaryWorker.onmessage = function(e) {
|
||||
var message = e.data; // Number of times the WebWorker has been messaged.
|
||||
console.log("Received message from the WebWorker: " + e.data);
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = message;
|
||||
}
|
||||
} else {
|
||||
console.error("WebWorkers are not supported in this browser!");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body>
|
||||
<h2>LM Layer Testing - Sending a function to a WebWorker via a Blob URI test</h2>
|
||||
<p>This page sends a function over to the Worker via a Blob URI, and
|
||||
expects the function to reply back.
|
||||
</p>
|
||||
<input type='text' id='txtFeedback' value="Haven't heard back yet" readonly> <br>
|
||||
<script>
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = "Have not heard back from worker";
|
||||
|
||||
function sendCode () {
|
||||
function payload () {
|
||||
postMessage('Hello, from the blobified code!');
|
||||
}
|
||||
|
||||
// Create an immediately-invoked function expression... to immediately
|
||||
// invoke the code!
|
||||
let iife = ['(', payload.toString(), '())'];
|
||||
let blob = new Blob(iife, { type: 'text/javascript' });
|
||||
let uri = URL.createObjectURL(blob);
|
||||
|
||||
// Go!
|
||||
canaryWorker.postMessage({ uri: uri });
|
||||
}
|
||||
|
||||
</script>
|
||||
<input type='button' id='btnInput' onclick='sendCode()' value='Send the source code!' />
|
||||
|
||||
<h3><a href="../index.html">Return to testing home page</a></h3>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
var counter = 0;
|
||||
|
||||
onmessage = function(e) {
|
||||
counter++;
|
||||
|
||||
console.log("Message received from main page: ", e.data);
|
||||
|
||||
postMessage(counter);
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match phone and tablet device widths -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
|
||||
<!-- Allow KeymanWeb to be saved to the iPhone home screen -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>Basic WebWorker test</title>
|
||||
|
||||
<!-- Your page CSS -->
|
||||
<style type='text/css'>
|
||||
body {font-family: Tahoma,helvetica;}
|
||||
h3 {font-size: 1em;font-weight:normal;color: darkred; margin-bottom: 4px}
|
||||
.test {font-size: 1.5em; width:80%; min-height:30px; border: 1px solid gray;}
|
||||
#KeymanWebControl {width:50%;min-width:600px;}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
if(window.Worker) {
|
||||
var canaryWorker = new Worker('canaryWorker.js');
|
||||
|
||||
canaryWorker.onmessage = function(e) {
|
||||
var counter = e.data; // Number of times the WebWorker has been messaged.
|
||||
console.log("Received message from the WebWorker: " + e.data);
|
||||
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = counter + " click(s)";
|
||||
}
|
||||
} else {
|
||||
console.error("WebWorkers are not supported in this browser!");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body>
|
||||
<h2>LM Layer Testing - basic WebWorker canary</h2>
|
||||
<p>This page uses a simple WebWorker useful for ensuring functionality on various platforms.</p>
|
||||
<input type='text' id='txtFeedback' value="No clicks yet." readonly></input> <br>
|
||||
<script>
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = "No clicks yet.";
|
||||
</script>
|
||||
<input type='button' id='btnInput' onclick='canaryWorker.postMessage("Hello.");' value='Message the WebWorker.' />
|
||||
|
||||
<h3><a href="../index.html">Return to testing home page</a></h3>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
**/*.js
|
||||
**/*.js.map
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Compiles the Language Modeling Layer for common use in predictive text and autocorrective applications.
|
||||
# Designed for optimal compatibility with the Keyman Suite.
|
||||
#
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
. "${THIS_SCRIPT%/*}/../../../../resources/build/build-utils.sh"
|
||||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
## END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
display_usage ( ) {
|
||||
echo "build.sh [-clean]"
|
||||
echo
|
||||
echo " -clean to erase pre-existing build products before a re-build"
|
||||
}
|
||||
|
||||
SOURCE="testing/two-stage-embedded-webworker"
|
||||
|
||||
COMPILED_WORKER="worker.js"
|
||||
EMBEDDED_WORKER="embedded_worker.js"
|
||||
|
||||
echo "Node.js + dependencies check"
|
||||
npm install --no-optional
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Build environment setup error detected! Please ensure Node.js is installed!"
|
||||
fi
|
||||
|
||||
# A nice, extensible method for -clean operations. Add to this as necessary.
|
||||
clean ( ) {
|
||||
rm -rf "./*.js"
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Failed to erase the prior build."
|
||||
fi
|
||||
}
|
||||
|
||||
# Process command-line arguments
|
||||
while [[ $# -gt 0 ]] ; do
|
||||
key="$1"
|
||||
case $key in
|
||||
-clean)
|
||||
clean
|
||||
;;
|
||||
esac
|
||||
shift # past the processed argument
|
||||
done
|
||||
|
||||
npm run tsc -- -p $SOURCE/worker/tsconfig.json
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Worker compilation failed."
|
||||
fi
|
||||
|
||||
rm $EMBEDDED_WORKER &> /dev/null
|
||||
|
||||
echo "var LMLayerWorker = function() {" >> $EMBEDDED_WORKER
|
||||
cat $COMPILED_WORKER >> $EMBEDDED_WORKER
|
||||
echo "" >> $EMBEDDED_WORKER
|
||||
echo "}" >> $EMBEDDED_WORKER
|
||||
|
||||
npm run tsc -- -p $SOURCE/tsconfig.json
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Final compilation failed."
|
||||
fi
|
||||
|
||||
echo "Typescript compilation successful."
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match phone and tablet device widths -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
|
||||
<!-- Allow KeymanWeb to be saved to the iPhone home screen -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>Embedded WebWorker test</title>
|
||||
|
||||
<!-- Your page CSS -->
|
||||
<style type='text/css'>
|
||||
body {font-family: Tahoma,helvetica;}
|
||||
h3 {font-size: 1em;font-weight:normal;color: darkred; margin-bottom: 4px}
|
||||
.test {font-size: 1.5em; width:80%; min-height:30px; border: 1px solid gray;}
|
||||
#KeymanWebControl {width:50%;min-width:600px;}
|
||||
</style>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body>
|
||||
<h2>LM Layer Testing - One-Stage Embedded WebWorkers</h2>
|
||||
<p>This page serves as a prototype for embedding a WebWorker's code within its "master" script
|
||||
across the TypeScript transpilation boundary.</p>
|
||||
<input type='text' id='txtFeedback' value="No clicks yet." readonly></input> <br>
|
||||
<script>
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = "No clicks yet.";
|
||||
</script>
|
||||
<input type='button' id='btnInput' onclick='canaryWorker.postMessage("Hello.");' value='Message the WebWorker.' />
|
||||
|
||||
<h3><a href="../index.html">Return to testing home page</a></h3>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
// Provides the final source for our compiled WebWorker within a wrapping function.
|
||||
/// <reference path="embedded_worker.js" />
|
||||
|
||||
function createWorker(fn: Function): Worker {
|
||||
var str_fn = fn.toString();
|
||||
|
||||
// We now unwrap our WebWorker from its function.
|
||||
var str_lines = str_fn.split("\n");
|
||||
var blob_lines = []
|
||||
|
||||
for(var i=1; i < str_lines.length -1; i++) {
|
||||
blob_lines.push(str_lines[i] + "\n");
|
||||
}
|
||||
// Unwrapping complete.
|
||||
|
||||
var blob = new Blob(blob_lines, { type: 'text/javascript' });
|
||||
let url = URL.createObjectURL(blob);
|
||||
|
||||
return new Worker(url);
|
||||
}
|
||||
|
||||
var canaryWorker = createWorker(LMLayerWorker);
|
||||
|
||||
canaryWorker.onmessage = function(e) {
|
||||
var counter = e.data; // Number of times the WebWorker has been messaged.
|
||||
console.log("Received message from the WebWorker: " + e.data);
|
||||
|
||||
var txtFeedback = <HTMLInputElement>document.getElementById("txtFeedback");
|
||||
txtFeedback.value = counter + " click(s)";
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"module": "none",
|
||||
"outFile": "./main.js",
|
||||
"inlineSources": true,
|
||||
"inlineSourceMap": true,
|
||||
"target": "es5"
|
||||
},
|
||||
"files" : [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
var counter = 0;
|
||||
|
||||
onmessage = function(e) {
|
||||
counter++;
|
||||
|
||||
console.log("Message received from main page: ", e.data);
|
||||
|
||||
postMessage(counter);
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": false,
|
||||
"module": "none",
|
||||
"outFile": "../worker.js",
|
||||
"inlineSources": true,
|
||||
"sourceMap": true,
|
||||
"lib": ["webworker", "es6"],
|
||||
"target": "es5"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Builds hextobin.js
|
||||
#
|
||||
|
||||
# Exit on command failure and when using unset variables:
|
||||
set -eu
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
|
|
@ -22,21 +15,10 @@ cd "$THIS_SCRIPT_PATH"
|
|||
builder_describe "Build hextobin" clean configure build
|
||||
builder_describe_outputs \
|
||||
configure /node_modules \
|
||||
build build/index.js
|
||||
build /common/tools/hextobin/build/index.js
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
if builder_start_action clean; then
|
||||
npm run clean
|
||||
builder_finish_action success clean
|
||||
fi
|
||||
|
||||
if builder_start_action configure; then
|
||||
verify_npm_setup
|
||||
builder_finish_action success configure
|
||||
fi
|
||||
|
||||
if builder_start_action build; then
|
||||
npm run build
|
||||
builder_finish_action success build
|
||||
fi
|
||||
|
||||
builder_run_action clean rm -rf build/ node_modules/
|
||||
builder_run_action configure verify_npm_setup
|
||||
builder_run_action build tsc --build
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env node
|
||||
import * as fs from 'fs';
|
||||
import * as rd from 'readline';
|
||||
import * as program from 'commander';
|
||||
import { Command } from 'commander';
|
||||
import hextobin from './index.js';
|
||||
|
||||
let inputFilename: string = "";
|
||||
let outputFilename: string = "";
|
||||
|
||||
const program = new Command();
|
||||
program
|
||||
.description(
|
||||
`Will convert the input file which is a hex dump to the output file. Hex dump can contain
|
||||
|
|
@ -43,6 +43,4 @@ function exitDueToUsageError(message: string): never {
|
|||
return process.exit(64); // SysExits.EX_USAGE
|
||||
}
|
||||
|
||||
import hextobin from './index';
|
||||
|
||||
hextobin(inputFilename, outputFilename, {silent: false});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"name": "@keymanapp/hextobin",
|
||||
"description": "hextobin conversion tool",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"keyman",
|
||||
"hex",
|
||||
|
|
@ -14,14 +16,6 @@
|
|||
"bin": {
|
||||
"hextobin": "build/hextobin.js"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "tsc -b --clean",
|
||||
"build": "tsc -b"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/keymanapp/keyman.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.7.18"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,9 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"target": "ES2020",
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "node",
|
||||
"rootDir": ".",
|
||||
"outDir": "build/",
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"files": [
|
||||
"index.ts",
|
||||
"hextobin.ts"
|
||||
]
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
"outDir": "build/"
|
||||
},
|
||||
"exclude": ["node_modules"],
|
||||
"files": ["index.ts", "hextobin.ts"]
|
||||
}
|
||||
|
|
|
|||
1
common/tools/sourcemap-path-remapper/src/convert-source-map.d.ts
vendored
Normal file
1
common/tools/sourcemap-path-remapper/src/convert-source-map.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
declare module 'convert-source-map';
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"allowJs": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"declaration": true,
|
||||
"module": "es6",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"sourceRoot": "/common/tools/sourcemap-path-remapper/src",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"outDir": "build/",
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Bundles @keymanapp/keyman-version as a single-file CommonJS module for components
|
||||
* still in need of it.
|
||||
*/
|
||||
|
||||
import esbuild from 'esbuild';
|
||||
|
||||
// Bundles to a compact ESModule
|
||||
esbuild.buildSync({
|
||||
entryPoints: ['build/version.inc.js'],
|
||||
bundle: true,
|
||||
sourcemap: true,
|
||||
//minify: true, // No need to minify a module.
|
||||
//keepNames: true,
|
||||
format: "cjs",
|
||||
// Sets 'common/web' as a root folder for module resolution;
|
||||
// this allows the keyman-version import to resolve.
|
||||
nodePaths: ['..'],
|
||||
outfile: "build/version.inc.cjs",
|
||||
tsconfig: 'tsconfig.json',
|
||||
target: "es5"
|
||||
});
|
||||
|
|
@ -1,11 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Builds the include script for the current Keyman version.
|
||||
#
|
||||
|
||||
# Exit on command failure and when using unset variables:
|
||||
set -eu
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
|
|
@ -13,6 +6,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
|||
## END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
|
||||
|
||||
# This script runs from its own folder
|
||||
cd "$THIS_SCRIPT_PATH"
|
||||
|
|
@ -25,8 +19,7 @@ builder_describe "Build the include script for current Keyman version" \
|
|||
build \
|
||||
"pack build a local .tgz pack for testing" \
|
||||
"publish publish to npm" \
|
||||
test \
|
||||
--dry-run
|
||||
test
|
||||
|
||||
builder_describe_outputs \
|
||||
configure "/node_modules" \
|
||||
|
|
@ -34,21 +27,7 @@ builder_describe_outputs \
|
|||
|
||||
builder_parse "$@"
|
||||
|
||||
|
||||
if builder_start_action configure; then
|
||||
verify_npm_setup
|
||||
builder_finish_action success configure
|
||||
fi
|
||||
|
||||
if builder_start_action clean; then
|
||||
npm run clean
|
||||
rm -f ./version.inc.ts
|
||||
rm -f ./keyman-version.mts
|
||||
rm -rf build
|
||||
builder_finish_action success clean
|
||||
fi
|
||||
|
||||
if builder_start_action build; then
|
||||
function do_build() {
|
||||
# Generate version.inc.ts
|
||||
echo "
|
||||
// Generated by common/web/keyman-version/build.sh
|
||||
|
|
@ -72,22 +51,11 @@ export class KEYMAN_VERSION {
|
|||
export default KEYMAN_VERSION;
|
||||
" > ./version.inc.ts
|
||||
|
||||
tsc -b $builder_verbose
|
||||
# kmlmc (the lexical model compiler) relies on a Node-based import, but after some of the earlier
|
||||
# ES-modularization work, our main output's an ES module. Fortunately, esbuild can provide an easy stopgap.
|
||||
tsc --build $builder_verbose
|
||||
}
|
||||
|
||||
# Generates a CommonJS variant (in case other modules still need it).
|
||||
node ./build-bundler.js
|
||||
|
||||
builder_finish_action success build
|
||||
fi
|
||||
|
||||
if builder_start_action publish; then
|
||||
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
|
||||
builder_publish_to_npm
|
||||
builder_finish_action success publish
|
||||
elif builder_start_action pack; then
|
||||
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
|
||||
builder_publish_to_pack
|
||||
builder_finish_action success pack
|
||||
fi
|
||||
builder_run_action clean rm -rf version.inc.ts keyman-version.mts build/
|
||||
builder_run_action configure verify_npm_setup
|
||||
builder_run_action build do_build
|
||||
builder_run_action publish builder_publish_to_npm
|
||||
builder_run_action pack builder_publish_to_pack
|
||||
|
|
|
|||
|
|
@ -1,26 +1,15 @@
|
|||
{
|
||||
"name": "@keymanapp/keyman-version",
|
||||
"description": "Keyman global version data",
|
||||
"main": "./build/version.inc.cjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./build/version.inc.js",
|
||||
"require": "./build/version.inc.cjs"
|
||||
},
|
||||
"./build/version.inc.cjs": "./build/version.inc.cjs"
|
||||
".": "./build/version.inc.js"
|
||||
},
|
||||
"files": [
|
||||
"/build/"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "echo 'Building @keymanapp/keyman-version' && tsc -b",
|
||||
"clean": "tsc -b --clean",
|
||||
"tsc": "tsc"
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.4.1",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,12 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"allowJs": false,
|
||||
"declaration": true,
|
||||
"module": "es6",
|
||||
"sourceMap": true,
|
||||
"outDir": "./build",
|
||||
"lib": ["es6"],
|
||||
"target": "es5",
|
||||
"downlevelIteration": true,
|
||||
"rootDir": "."
|
||||
},
|
||||
|
||||
"include": [
|
||||
"version.inc.ts"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"module": "none",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,22 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig-base.json",
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
|
||||
// TODO: These override /tsconfig.base.json settings, and so should be removed if possible,
|
||||
// but existing code in web/ breaks some of these settinsg
|
||||
"noImplicitThis": false,
|
||||
"noImplicitReturns": false,
|
||||
"noImplicitAny": false,
|
||||
"strictFunctionTypes": false,
|
||||
"noUnusedLocals": false,
|
||||
|
||||
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"baseUrl": "./",
|
||||
"inlineSources": true,
|
||||
"lib": ["es6", "dom"],
|
||||
"module": "es6",
|
||||
"moduleResolution": "Node16",
|
||||
"outDir": "../build/obj",
|
||||
"rootDir": "./",
|
||||
"sourceMap": true,
|
||||
|
|
|
|||
|
|
@ -64,9 +64,15 @@ export class MarkerParser {
|
|||
public static readonly MAX_MARKER_INDEX = constants.marker_max_index;
|
||||
/** Max count of markers */
|
||||
public static readonly MAX_MARKER_COUNT = constants.marker_max_count;
|
||||
|
||||
private static anyMarkerMatch() : string {
|
||||
const start = (`0000` + (this.MIN_MARKER_INDEX).toString(16)).slice(-4);
|
||||
const end = (`0000` + (this.MAX_MARKER_INDEX).toString(16)).slice(-4);
|
||||
return `${this.SENTINEL}${this.MARKER_CODE}[\\u${start}-\\u${end}]`;
|
||||
}
|
||||
|
||||
/** Expression that matches any marker */
|
||||
public static readonly ANY_MARKER_MATCH =
|
||||
this.SENTINEL + this.MARKER_CODE + `[\\u0001-\\u${this.MAX_MARKER_INDEX.toString(16)}]`;
|
||||
public static readonly ANY_MARKER_MATCH = MarkerParser.anyMarkerMatch();
|
||||
|
||||
/**
|
||||
* Pattern for matching a marker reference, OR the special marker \m{.}
|
||||
|
|
|
|||
|
|
@ -105,16 +105,20 @@ describe('Test of Pattern Parsers', () => {
|
|||
)
|
||||
);
|
||||
// verify the matching behavior of these
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`Q\\m{a}`, markers, true), 'u')
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^Q\\m{a}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`Q\\m{a}`, markers, false)), `Q\\m{a} did not match`);
|
||||
assert.isFalse(new RegExp(MarkerParser.toSentinelString(`Q\\m{a}`, markers, true), 'u')
|
||||
assert.isFalse(new RegExp(MarkerParser.toSentinelString(`^Q\\m{a}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`Q\\m{b}`, markers, false)), `Q\\m{a} should not match Q\\m{b}`);
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`Q\\m{.}`, markers, true), 'u')
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^Q\\m{.}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`Q\\m{a}`, markers, false)), `Q\\m{.} did not match Q\\m{a}`);
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`Q\\m{.}`, markers, true), 'u')
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^Q\\m{.}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`Q\\m{zz}`, markers, false)), `Q\\m{.} did not match Q\\m{zz} (max marker)`);
|
||||
assert.isFalse(new RegExp(MarkerParser.toSentinelString(`Q\\m{.}`, markers, true), 'u')
|
||||
assert.isFalse(new RegExp(MarkerParser.toSentinelString(`^Q\\m{.}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`\\m{a}`, markers, false)), `Q\\m{.} did not match \\m{a}`);
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^\\m{.}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`\\m{a}`, markers, false)), `\\m{.} did not match \\m{a}`);
|
||||
assert.isFalse(new RegExp(MarkerParser.toSentinelString(`^\\m{.}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`\\m{a}\\m{b}`, markers, false)), `\\m{.} did not match \\m{a}\\m{b}`);
|
||||
});
|
||||
it('should match some marker constants', () => {
|
||||
assert.equal(constants.uc_sentinel, KMXFile.UC_SENTINEL);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"outDir": "build/src/",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"module": "es2020",
|
||||
"moduleResolution": "node",
|
||||
"rootDir": ".",
|
||||
"outDir": "build/",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"outDir": "build/src/",
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
"rootDirs": ["./", "../src/"],
|
||||
"outDir": "../build/test",
|
||||
"esModuleInterop": true,
|
||||
"moduleResolution": "node16",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"outDir": "build/src/",
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import 'mocha';
|
||||
import {assert} from 'chai';
|
||||
import x_hextobin from '@keymanapp/hextobin';
|
||||
import hextobin from '@keymanapp/hextobin';
|
||||
import { KMXBuilder } from '@keymanapp/common-types';
|
||||
import {checkMessages, compileKeyboard, compilerTestCallbacks, compilerTestOptions, makePathToFixture} from './helpers/index.js';
|
||||
import { LdmlKeyboardCompiler } from '../src/compiler/compiler.js';
|
||||
|
||||
const hextobin = (x_hextobin as any).default;
|
||||
|
||||
describe('compiler-tests', function() {
|
||||
this.slow(500); // 0.5 sec -- json schema validation takes a while
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import 'mocha';
|
||||
import {assert} from 'chai';
|
||||
import x_hextobin from '@keymanapp/hextobin';
|
||||
import hextobin from '@keymanapp/hextobin';
|
||||
import { KvkFileWriter } from '@keymanapp/common-types';
|
||||
import {checkMessages, compilerTestOptions, compileVisualKeyboard, makePathToFixture} from './helpers/index.js';
|
||||
|
||||
const hextobin = (x_hextobin as any).default;
|
||||
|
||||
describe('visual-keyboard-compiler', function() {
|
||||
this.slow(500); // 0.5 sec -- json schema validation takes a while
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"outDir": "build/src/",
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
"rootDirs": ["./", "../src/"],
|
||||
"outDir": "../build/test",
|
||||
"esModuleInterop": true,
|
||||
"moduleResolution": "node16",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { assert } from "chai";
|
||||
import defaultWordBreaker from './wordbreakers/default-wordbreaker-esm.js';
|
||||
import defaultWordBreaker from '@keymanapp/models-wordbreakers';
|
||||
import {decorateWithJoin} from '../src/join-word-breaker-decorator.js';
|
||||
|
||||
describe('The join word breaker decorator', function () {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { assert } from "chai";
|
||||
import defaultWordBreaker from './wordbreakers/default-wordbreaker-esm.js';
|
||||
import defaultWordBreaker from '@keymanapp/models-wordbreakers';
|
||||
import {decorateWithScriptOverrides} from '../src/script-overrides-decorator.js';
|
||||
|
||||
const THIN_SPACE = "\u2009";
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
"rootDirs": ["./", "../src/"],
|
||||
"outDir": "../build/test",
|
||||
"esModuleInterop": true,
|
||||
"moduleResolution": "node16",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
Wordbreakers ES Module format
|
||||
|
||||
TODO: once we move common/models/wordbreakers to ESM, eliminate this.
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,383 +0,0 @@
|
|||
// TEMP: esm version of /common/models/wordbreakers/default/index.ts
|
||||
|
||||
import { I, WORD_BREAK_PROPERTY, WordBreakProperty } from './data.js';
|
||||
|
||||
|
||||
/**
|
||||
* Word breaker based on Unicode Standard Annex #29, Section 4.1:
|
||||
* Default Word Boundary Specification.
|
||||
*
|
||||
* @see http://unicode.org/reports/tr29/#Word_Boundaries
|
||||
* @see https://github.com/eddieantonio/unicode-default-word-boundary/tree/v12.0.0
|
||||
*/
|
||||
export default function default_(text: string): Span[] {
|
||||
let boundaries = findBoundaries(text);
|
||||
if (boundaries.length == 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// All non-empty strings have at least TWO boundaries: at the start and at the end of
|
||||
// the string.
|
||||
let spans = [];
|
||||
for (let i = 0; i < boundaries.length - 1; i++) {
|
||||
let start = boundaries[i];
|
||||
let end = boundaries[i + 1];
|
||||
let span = new LazySpan(text, start, end);
|
||||
|
||||
if (isNonSpace(span.text)) {
|
||||
spans.push(span);
|
||||
// Preserve a sequence-final space if it exists. Needed to signal "end of word".
|
||||
} else if (i == boundaries.length - 2) { // if "we just checked the final boundary"...
|
||||
// We don't want to return the whitespace itself; the correct token is simply ''.
|
||||
span = new LazySpan(text, end, end);
|
||||
spans.push(span);
|
||||
}
|
||||
}
|
||||
return spans;
|
||||
}
|
||||
|
||||
// Utilities //
|
||||
// type WordBreakProperty = data.WordBreakProperty;
|
||||
// const WordBreakProperty = data.WordBreakProperty;
|
||||
// type I = data.I;
|
||||
// const I = data.I;
|
||||
// const WORD_BREAK_PROPERTY = data.WORD_BREAK_PROPERTY;
|
||||
|
||||
/**
|
||||
* A span that does not cut out the substring until it absolutely has to!
|
||||
*/
|
||||
class LazySpan implements Span {
|
||||
private _source: string;
|
||||
readonly start: number;
|
||||
readonly end: number;
|
||||
constructor(source: string, start: number, end: number) {
|
||||
this._source = source;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
get text(): string {
|
||||
return this._source.substring(this.start, this.end);
|
||||
}
|
||||
|
||||
get length(): number {
|
||||
return this.end - this.start;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when the chunk does not solely consist of whitespace.
|
||||
*
|
||||
* @param chunk a chunk of text. Starts and ends at word boundaries.
|
||||
*/
|
||||
function isNonSpace(chunk: string): boolean {
|
||||
return !Array.from(chunk).map(property).every(wb => (
|
||||
wb === WordBreakProperty.CR ||
|
||||
wb === WordBreakProperty.LF ||
|
||||
wb === WordBreakProperty.Newline ||
|
||||
wb === WordBreakProperty.WSegSpace
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Yields a series of string indices where a word break should
|
||||
* occur. That is, there should be a break BEFORE each string
|
||||
* index yielded by this generator.
|
||||
*
|
||||
* @param text Text to find word boundaries in.
|
||||
*/
|
||||
function findBoundaries(text: string): number[] {
|
||||
// WB1 and WB2: no boundaries if given an empty string.
|
||||
if (text.length === 0) {
|
||||
// There are no boundaries in an empty string!
|
||||
return [];
|
||||
}
|
||||
|
||||
// This algorithm works by maintaining a sliding window of four SCALAR VALUES.
|
||||
//
|
||||
// - Scalar values? JavaScript strings are NOT actually a string of
|
||||
// Unicode code points; some characters are made up of TWO
|
||||
// JavaScript indices. e.g.,
|
||||
// "💩".length === 2;
|
||||
// "💩"[0] === '\uD83D';
|
||||
// "💩"[1] === '\uDCA9';
|
||||
//
|
||||
// These characters that are represented by TWO indices are
|
||||
// called "surrogate pairs". Since we don't want to be in the
|
||||
// "middle" of a character, make sure we're always advancing
|
||||
// by scalar values, and NOT indices. That means, we sometimes
|
||||
// need to advance by TWO indices, not just one.
|
||||
// - Four values? Some rules look at what's to the left of
|
||||
// left, and some look at what's to the right of right. So
|
||||
// keep track of this!
|
||||
|
||||
let boundaries = [];
|
||||
|
||||
let rightPos: number;
|
||||
let lookaheadPos = 0; // lookahead, one scalar value to the right of right.
|
||||
// Before the start of the string is also the start of the string.
|
||||
let lookbehind: WordBreakProperty;
|
||||
let left = WordBreakProperty.sot;
|
||||
let right = WordBreakProperty.sot;
|
||||
let lookahead = wordbreakPropertyAt(0);
|
||||
// Count RIs to make sure we're not splitting emoji flags:
|
||||
let nConsecutiveRegionalIndicators = 0;
|
||||
|
||||
do {
|
||||
// Shift all positions, one scalar value to the right.
|
||||
rightPos = lookaheadPos;
|
||||
lookaheadPos = positionAfter(lookaheadPos);
|
||||
// Shift all properties, one scalar value to the right.
|
||||
[lookbehind, left, right, lookahead] =
|
||||
[left, right, lookahead, wordbreakPropertyAt(lookaheadPos)];
|
||||
|
||||
// Break at the start and end of text, unless the text is empty.
|
||||
// WB1: Break at start of text...
|
||||
if (left === WordBreakProperty.sot) {
|
||||
boundaries.push(rightPos);
|
||||
continue;
|
||||
}
|
||||
// WB2: Break at the end of text...
|
||||
if (right === WordBreakProperty.eot) {
|
||||
boundaries.push(rightPos);
|
||||
break; // Reached the end of the string. We're done!
|
||||
}
|
||||
// WB3: Do not break within CRLF:
|
||||
if (left === WordBreakProperty.CR && right === WordBreakProperty.LF)
|
||||
continue;
|
||||
// WB3b: Otherwise, break after...
|
||||
if (left === WordBreakProperty.Newline ||
|
||||
left === WordBreakProperty.CR ||
|
||||
left === WordBreakProperty.LF) {
|
||||
boundaries.push(rightPos);
|
||||
continue;
|
||||
}
|
||||
// WB3a: ...and before newlines
|
||||
if (right === WordBreakProperty.Newline ||
|
||||
right === WordBreakProperty.CR ||
|
||||
right === WordBreakProperty.LF) {
|
||||
boundaries.push(rightPos);
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: WB3c is not implemented, due to its complex, error-prone
|
||||
// implementation, requiring a ginormous regexp, and the fact that
|
||||
// the only thing it does is prevent big emoji sequences from being
|
||||
// split up, like 🧚🏼♂️
|
||||
// https://www.unicode.org/Public/emoji/12.0/emoji-zwj-sequences.txt
|
||||
|
||||
// WB3d: Keep horizontal whitespace together
|
||||
if (left === WordBreakProperty.WSegSpace && right == WordBreakProperty.WSegSpace)
|
||||
continue;
|
||||
|
||||
// WB4: Ignore format and extend characters
|
||||
// This is to keep grapheme clusters together!
|
||||
// See: Section 6.2: https://unicode.org/reports/tr29/#Grapheme_Cluster_and_Format_Rules
|
||||
// N.B.: The rule about "except after sot, CR, LF, and
|
||||
// Newline" already been by WB1, WB2, WB3a, and WB3b above.
|
||||
while (right === WordBreakProperty.Format ||
|
||||
right === WordBreakProperty.Extend ||
|
||||
right === WordBreakProperty.ZWJ) {
|
||||
// Continue advancing in the string, as if these
|
||||
// characters do not exist. DO NOT update left and
|
||||
// lookbehind however!
|
||||
[rightPos, lookaheadPos] = [lookaheadPos, positionAfter(lookaheadPos)];
|
||||
[right, lookahead] = [lookahead, wordbreakPropertyAt(lookaheadPos)];
|
||||
}
|
||||
// In ignoring the characters in the previous loop, we could
|
||||
// have fallen off the end of the string, so end the loop
|
||||
// prematurely if that happens!
|
||||
if (right === WordBreakProperty.eot) {
|
||||
boundaries.push(rightPos);
|
||||
break;
|
||||
}
|
||||
// WB4 (continued): Lookahead must ALSO ignore these format,
|
||||
// extend, ZWJ characters!
|
||||
while (lookahead === WordBreakProperty.Format ||
|
||||
lookahead === WordBreakProperty.Extend ||
|
||||
lookahead === WordBreakProperty.ZWJ) {
|
||||
// Continue advancing in the string, as if these
|
||||
// characters do not exist. DO NOT update left and right,
|
||||
// however!
|
||||
lookaheadPos = positionAfter(lookaheadPos);
|
||||
lookahead = wordbreakPropertyAt(lookaheadPos);
|
||||
}
|
||||
|
||||
// WB5: Do not break between most letters.
|
||||
if (isAHLetter(left) && isAHLetter(right))
|
||||
continue;
|
||||
// Do not break across certain punctuation
|
||||
// WB6: (Don't break before apostrophes in contractions)
|
||||
if (isAHLetter(left) && isAHLetter(lookahead) &&
|
||||
(right === WordBreakProperty.MidLetter || isMidNumLetQ(right)))
|
||||
continue;
|
||||
// WB7: (Don't break after apostrophes in contractions)
|
||||
if (isAHLetter(lookbehind) && isAHLetter(right) &&
|
||||
(left === WordBreakProperty.MidLetter || isMidNumLetQ(left)))
|
||||
continue;
|
||||
// WB7a
|
||||
if (left === WordBreakProperty.Hebrew_Letter && right === WordBreakProperty.Single_Quote)
|
||||
continue;
|
||||
// WB7b
|
||||
if (left === WordBreakProperty.Hebrew_Letter && right === WordBreakProperty.Double_Quote &&
|
||||
lookahead === WordBreakProperty.Hebrew_Letter)
|
||||
continue;
|
||||
// WB7c
|
||||
if (lookbehind === WordBreakProperty.Hebrew_Letter && left === WordBreakProperty.Double_Quote &&
|
||||
right === WordBreakProperty.Hebrew_Letter)
|
||||
continue;
|
||||
// Do not break within sequences of digits, or digits adjacent to letters.
|
||||
// e.g., "3a" or "A3"
|
||||
// WB8
|
||||
if (left === WordBreakProperty.Numeric && right === WordBreakProperty.Numeric)
|
||||
continue;
|
||||
// WB9
|
||||
if (isAHLetter(left) && right === WordBreakProperty.Numeric)
|
||||
continue;
|
||||
// WB10
|
||||
if (left === WordBreakProperty.Numeric && isAHLetter(right))
|
||||
continue;
|
||||
// Do not break within sequences, such as 3.2, 3,456.789
|
||||
// WB11
|
||||
if (lookbehind === WordBreakProperty.Numeric && right === WordBreakProperty.Numeric &&
|
||||
(left === WordBreakProperty.MidNum || isMidNumLetQ(left)))
|
||||
continue;
|
||||
// WB12
|
||||
if (left === WordBreakProperty.Numeric && lookahead === WordBreakProperty.Numeric &&
|
||||
(right === WordBreakProperty.MidNum || isMidNumLetQ(right)))
|
||||
continue;
|
||||
// WB13: Do not break between Katakana
|
||||
if (left === WordBreakProperty.Katakana && right === WordBreakProperty.Katakana)
|
||||
continue;
|
||||
// Do not break from extenders (e.g., U+202F NARROW NO-BREAK SPACE)
|
||||
// WB13a
|
||||
if ((isAHLetter(left) ||
|
||||
left === WordBreakProperty.Numeric ||
|
||||
left === WordBreakProperty.Katakana ||
|
||||
left === WordBreakProperty.ExtendNumLet) &&
|
||||
right === WordBreakProperty.ExtendNumLet)
|
||||
continue;
|
||||
// WB13b
|
||||
if ((isAHLetter(right) ||
|
||||
right === WordBreakProperty.Numeric ||
|
||||
right === WordBreakProperty.Katakana) && left === WordBreakProperty.ExtendNumLet)
|
||||
continue;
|
||||
|
||||
// WB15 & WB16:
|
||||
// Do not break within emoji flag sequences. That is, do not break between
|
||||
// regional indicator (RI) symbols if there is an odd number of RI
|
||||
// characters before the break point.
|
||||
if (right === WordBreakProperty.Regional_Indicator) {
|
||||
// Emoji flags are actually composed of TWO scalar values, each being a
|
||||
// "regional indicator". These indicators correspond to Latin letters. Put
|
||||
// two of them together, and they spell out an ISO 3166-1-alpha-2 country
|
||||
// code. Since these always come in pairs, NEVER split the pairs! So, if
|
||||
// we happen to be inside the middle of an odd numbered of
|
||||
// Regional_Indicators, DON'T SPLIT IT!
|
||||
nConsecutiveRegionalIndicators += 1;
|
||||
if ((nConsecutiveRegionalIndicators % 2) == 1) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
nConsecutiveRegionalIndicators = 0;
|
||||
}
|
||||
// WB999: Otherwise, break EVERYWHERE (including around ideographs)
|
||||
boundaries.push(rightPos);
|
||||
} while (rightPos < text.length);
|
||||
|
||||
return boundaries;
|
||||
|
||||
///// Internal utility functions /////
|
||||
|
||||
/**
|
||||
* Returns the position of the start of the next scalar value. This jumps
|
||||
* over surrogate pairs.
|
||||
*
|
||||
* If asked for the character AFTER the end of the string, this always
|
||||
* returns the length of the string.
|
||||
*/
|
||||
function positionAfter(pos: number): number {
|
||||
if (pos >= text.length) {
|
||||
return text.length;
|
||||
} else if (isStartOfSurrogatePair(text[pos])) {
|
||||
return pos + 2;
|
||||
}
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the Word_Break property at the given string index.
|
||||
* @param pos position in the text.
|
||||
*/
|
||||
function wordbreakPropertyAt(pos: number) {
|
||||
if (pos < 0) {
|
||||
return WordBreakProperty.sot; // Always "start of string" before the string starts!
|
||||
} else if (pos >= text.length) {
|
||||
return WordBreakProperty.eot; // Always "end of string" after the string ends!
|
||||
} else if (isStartOfSurrogatePair(text[pos])) {
|
||||
// Surrogate pairs the next TWO items from the string!
|
||||
return property(text[pos] + text[pos + 1]);
|
||||
}
|
||||
return property(text[pos]);
|
||||
}
|
||||
|
||||
// Word_Break rule macros
|
||||
// See: https://unicode.org/reports/tr29/#WB_Rule_Macros
|
||||
function isAHLetter(prop: WordBreakProperty): boolean {
|
||||
return prop === WordBreakProperty.ALetter ||
|
||||
prop === WordBreakProperty.Hebrew_Letter;
|
||||
}
|
||||
|
||||
function isMidNumLetQ(prop: WordBreakProperty): boolean {
|
||||
return prop === WordBreakProperty.MidNumLet ||
|
||||
prop === WordBreakProperty.Single_Quote;
|
||||
}
|
||||
}
|
||||
|
||||
function isStartOfSurrogatePair(character: string) {
|
||||
let codeUnit = character.charCodeAt(0);
|
||||
return codeUnit >= 0xD800 && codeUnit <= 0xDBFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Word_Break property value for a character.
|
||||
* Note that
|
||||
* @param character a scalar value
|
||||
*/
|
||||
function property(character: string): WordBreakProperty {
|
||||
// This MUST be a scalar value.
|
||||
// TODO: remove dependence on character.codepointAt()?
|
||||
let codepoint = character.codePointAt(0) as number;
|
||||
return searchForProperty(codepoint, 0, WORD_BREAK_PROPERTY.length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary search for the word break property of a given CODE POINT.
|
||||
*
|
||||
* The auto-generated data.ts master array defines a **character range**
|
||||
* lookup table. If a character's codepoint is equal to or greater than
|
||||
* the I.Start value for an entry and exclusively less than the next entry,
|
||||
* it falls in the first entry's range bucket and is classified accordingly
|
||||
* by this method.
|
||||
*/
|
||||
function searchForProperty(codePoint: number, left: number, right: number): WordBreakProperty {
|
||||
// All items that are not found in the array are assigned the 'Other' property.
|
||||
if (right < left) {
|
||||
return WordBreakProperty.Other;
|
||||
}
|
||||
|
||||
let midpoint = left + ~~((right - left) / 2);
|
||||
let candidate = WORD_BREAK_PROPERTY[midpoint];
|
||||
|
||||
let nextRange = WORD_BREAK_PROPERTY[midpoint + 1];
|
||||
let startOfNextRange = nextRange ? nextRange[I.Start] : Infinity;
|
||||
|
||||
if (codePoint < candidate[I.Start]) {
|
||||
return searchForProperty(codePoint, left, midpoint - 1);
|
||||
} else if (codePoint >= startOfNextRange) {
|
||||
return searchForProperty(codePoint, midpoint + 1, right);
|
||||
}
|
||||
|
||||
// We found it!
|
||||
return candidate[I.Value];
|
||||
}
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
!include ..\Defines.mak
|
||||
|
||||
build: .virtual
|
||||
$(GIT_BASH_FOR_KEYMAN) build.sh --production --test
|
||||
$(GIT_BASH_FOR_KEYMAN) build.sh configure build test installer
|
||||
|
||||
clean: .virtual
|
||||
#TODO: move to build.sh `clean` target
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ isNodeX64() {
|
|||
# [[ $(file -b "$(which node)" | grep x86-64) ]] && echo 1 || echo 0
|
||||
}
|
||||
|
||||
build_addins() {
|
||||
do_build_addins() {
|
||||
local NODEX64=$(isNodeX64)
|
||||
local ARCH=x64
|
||||
local TRAYICON_TARGET=addon.x64.node
|
||||
|
|
@ -29,8 +29,13 @@ build_addins() {
|
|||
echo "TRAYICON_TARGET=$TRAYICON_TARGET"
|
||||
echo "HIDECONSOLE_TARGET=$HIDECONSOLE_TARGET"
|
||||
|
||||
HIDECONSOLE_TARGET="$KEYMAN_ROOT/developer/src/server/src/win32/console/$HIDECONSOLE_TARGET"
|
||||
TRAYICON_TARGET="$KEYMAN_ROOT/developer/src/server/src/win32/trayicon/$TRAYICON_TARGET"
|
||||
local HIDECONSOLE_SRC_TARGET="$KEYMAN_ROOT/developer/src/server/src/win32/console/$HIDECONSOLE_TARGET"
|
||||
local HIDECONSOLE_BIN_TARGET="$KEYMAN_ROOT/developer/src/server/build/src/win32/console/$HIDECONSOLE_TARGET"
|
||||
local TRAYICON_SRC_TARGET="$KEYMAN_ROOT/developer/src/server/src/win32/trayicon/$TRAYICON_TARGET"
|
||||
local TRAYICON_BIN_TARGET="$KEYMAN_ROOT/developer/src/server/build/src/win32/trayicon/$TRAYICON_TARGET"
|
||||
|
||||
mkdir -p "$(dirname "$HIDECONSOLE_BIN_TARGET")"
|
||||
mkdir -p "$(dirname "$TRAYICON_BIN_TARGET")"
|
||||
|
||||
#
|
||||
# Build node-windows-trayicon
|
||||
|
|
@ -39,7 +44,8 @@ build_addins() {
|
|||
pushd "$KEYMAN_ROOT/node_modules/node-windows-trayicon"
|
||||
rm -rf build
|
||||
npx node-gyp clean configure build --arch=$ARCH --silent
|
||||
cp build/Release/addon.node "$TRAYICON_TARGET"
|
||||
cp build/Release/addon.node "$TRAYICON_SRC_TARGET"
|
||||
cp build/Release/addon.node "$TRAYICON_BIN_TARGET"
|
||||
popd
|
||||
|
||||
#
|
||||
|
|
@ -49,7 +55,8 @@ build_addins() {
|
|||
pushd "$KEYMAN_ROOT/node_modules/hetrodo-node-hide-console-window-napi"
|
||||
rm -rf build
|
||||
npx node-gyp clean configure build --arch=$ARCH --silent
|
||||
cp build/Release/node-hide-console-window.node "$HIDECONSOLE_TARGET"
|
||||
cp build/Release/node-hide-console-window.node "$HIDECONSOLE_SRC_TARGET"
|
||||
cp build/Release/node-hide-console-window.node "$HIDECONSOLE_BIN_TARGET"
|
||||
popd
|
||||
|
||||
#
|
||||
|
|
@ -57,10 +64,10 @@ build_addins() {
|
|||
#
|
||||
|
||||
if (( NODEX64 )); then
|
||||
[[ $(isFileX64 "$TRAYICON_TARGET") == 1 ]] || builder_die "$TRAYICON_TARGET should be 64-bit"
|
||||
[[ $(isFileX64 "$HIDECONSOLE_TARGET") == 1 ]] || builder_die "$HIDECONSOLE_TARGET should be 64-bit"
|
||||
[[ $(isFileX64 "$TRAYICON_BIN_TARGET") == 1 ]] || builder_die "$TRAYICON_TARGET should be 64-bit"
|
||||
[[ $(isFileX64 "$HIDECONSOLE_BIN_TARGET") == 1 ]] || builder_die "$HIDECONSOLE_TARGET should be 64-bit"
|
||||
else
|
||||
[[ $(isFileX64 "$TRAYICON_TARGET") == 0 ]] || builder_die "$TRAYICON_TARGET should not be 64-bit"
|
||||
[[ $(isFileX64 "$HIDECONSOLE_TARGET") == 0 ]] || builder_die "$HIDECONSOLE_TARGET should not be 64-bit"
|
||||
[[ $(isFileX64 "$TRAYICON_BIN_TARGET") == 0 ]] || builder_die "$TRAYICON_TARGET should not be 64-bit"
|
||||
[[ $(isFileX64 "$HIDECONSOLE_BIN_TARGET") == 0 ]] || builder_die "$HIDECONSOLE_TARGET should not be 64-bit"
|
||||
fi
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Compiles Keyman Developer Server for deployment
|
||||
#
|
||||
|
||||
# Exit on command failure and when using unset variables:
|
||||
set -eu
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
|
|
@ -16,121 +10,68 @@ EX_USAGE=64
|
|||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
. "$KEYMAN_ROOT/resources/build/jq.inc.sh"
|
||||
|
||||
pushd "$(dirname "$THIS_SCRIPT")"
|
||||
cd "$THIS_SCRIPT_PATH"
|
||||
|
||||
# Build the main script.
|
||||
build () {
|
||||
npm run build || builder_die "Could not build top-level JavaScript file."
|
||||
builder_describe "Build Keyman Developer Server" \
|
||||
@/common/web/keyman-version \
|
||||
@/web \
|
||||
clean \
|
||||
configure \
|
||||
build \
|
||||
test \
|
||||
"installer Prepare for Keyman Developer installer" \
|
||||
"publish Publish to NPM" \
|
||||
":server Keyman Developer Server main program" \
|
||||
":addins Windows addins for GUI integration"
|
||||
|
||||
builder_describe_internal_dependency \
|
||||
publish:server build:server \
|
||||
publish:server build:addins
|
||||
|
||||
builder_describe_outputs \
|
||||
configure:server /node_modules \
|
||||
configure:addins /node_modules \
|
||||
build:server /developer/src/server/build/src/index.js \
|
||||
build:addins /developer/src/server/build/src/win32/trayicon/addon.node
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
function clean_server() {
|
||||
rm -rf "$THIS_SCRIPT_PATH/build"
|
||||
rm -rf "$THIS_SCRIPT_PATH/node_modules"
|
||||
rm -rf "$THIS_SCRIPT_PATH/tsconfig.tsbuildinfo"
|
||||
rm -rf "$THIS_SCRIPT_PATH/src/site/resource"
|
||||
|
||||
# No longer in use, cleanup from previous versions:
|
||||
rm -rf "$THIS_SCRIPT_PATH/dist"
|
||||
}
|
||||
|
||||
display_usage ( ) {
|
||||
echo "Usage: $0 [--production|--watch] [--test|--tdd]"
|
||||
echo " $0 --help"
|
||||
echo
|
||||
echo " --help displays this screen and exits"
|
||||
echo " --production, -p builds production release in /developer/bin/server/"
|
||||
echo " --skip-package-install, -S don't run npm install (not valid with --production)"
|
||||
echo " --test, -t runs unit tests after building"
|
||||
#echo " --watch, -w builds dev server in watch mode"
|
||||
echo " --tdd runs unit tests WITHOUT building"
|
||||
echo " --no-build-addins don't build/copy Win32 addins"
|
||||
echo " --no-build-kmw don't build KeymanWeb"
|
||||
echo " --no-copy-kmw don't copy KeymanWeb"
|
||||
}
|
||||
|
||||
################################ Main script ################################
|
||||
|
||||
run_tests=0
|
||||
production=0
|
||||
build=1
|
||||
install_dependencies=1
|
||||
build_keymanweb=1
|
||||
copy_keymanweb=1
|
||||
build_addins=1
|
||||
|
||||
# Process command-line arguments
|
||||
while [[ $# -gt 0 ]] ; do
|
||||
key="$1"
|
||||
case $key in
|
||||
--help|-h|-?)
|
||||
display_usage
|
||||
exit
|
||||
;;
|
||||
--production|-p)
|
||||
production=1
|
||||
;;
|
||||
--skip-package-install|-S)
|
||||
install_dependencies=0
|
||||
;;
|
||||
--no-build-kmw)
|
||||
build_keymanweb=0
|
||||
;;
|
||||
--no-build-addins)
|
||||
build_addins=0
|
||||
;;
|
||||
--no-copy-kmw)
|
||||
copy_keymanweb=0
|
||||
;;
|
||||
--test)
|
||||
run_tests=1
|
||||
;;
|
||||
--tdd)
|
||||
run_tests=1
|
||||
build=0
|
||||
install_dependencies=0
|
||||
;;
|
||||
*)
|
||||
echo "$0: invalid option: $key"
|
||||
display_usage
|
||||
exit $EX_USAGE
|
||||
esac
|
||||
shift # past the processed argument
|
||||
done
|
||||
|
||||
# ----------------------------------------
|
||||
# Install dependencies
|
||||
# ----------------------------------------
|
||||
|
||||
# Check if Node.JS/npm is installed.
|
||||
type npm >/dev/null ||\
|
||||
builder_die "Build environment setup error detected! Please ensure Node.js is installed!"
|
||||
|
||||
if (( install_dependencies )) ; then
|
||||
function configure_server() {
|
||||
verify_npm_setup
|
||||
# See https://github.com/bubenshchykov/ngrok/issues/254, https://github.com/bubenshchykov/ngrok/pull/255
|
||||
# TODO: this is horrible; is there a way we can avoid this?
|
||||
rm -f "$KEYMAN_ROOT"/node_modules/ngrok/bin/ngrok.exe
|
||||
fi
|
||||
}
|
||||
|
||||
# ----------------------------------------
|
||||
# Rebuild and bundle addins
|
||||
# ----------------------------------------
|
||||
|
||||
if (( build_addins )); then
|
||||
. ./build-addins.inc.sh
|
||||
function build_addins() {
|
||||
# Rebuild and bundle addins
|
||||
source ./build-addins.inc.sh
|
||||
|
||||
# If we have an x64 version of node installed
|
||||
if [[ $(isNodeX64) ]]; then
|
||||
build_addins
|
||||
do_build_addins
|
||||
fi
|
||||
|
||||
# Build with the Keyman Developer x86 version of node
|
||||
PATH="$KEYMAN_ROOT/developer/src/inst/node/dist:$PATH" build_addins
|
||||
fi
|
||||
PATH="$KEYMAN_ROOT/developer/src/inst/node/dist:$PATH" do_build_addins
|
||||
}
|
||||
|
||||
# ----------------------------------------
|
||||
# Build and bundle KeymanWeb
|
||||
# ----------------------------------------
|
||||
|
||||
if (( build_keymanweb )); then
|
||||
pushd "$KEYMAN_ROOT/web/"
|
||||
./build.sh build --debug
|
||||
popd
|
||||
fi
|
||||
|
||||
if (( copy_keymanweb )); then
|
||||
WEB_SRC="$KEYMAN_ROOT/web/build/publish/debug"
|
||||
DST="$(dirname "$THIS_SCRIPT")/src/site/resource"
|
||||
function build_server() {
|
||||
# Copy keymanweb build artifacts
|
||||
local WEB_SRC="$KEYMAN_ROOT/web/build/publish/debug"
|
||||
local DST="$THIS_SCRIPT_PATH/src/site/resource"
|
||||
|
||||
rm -rf "$DST"
|
||||
mkdir -p "$DST/osk"
|
||||
|
|
@ -140,33 +81,26 @@ if (( copy_keymanweb )); then
|
|||
cp -R "$WEB_SRC/ui/"* "$DST/ui/"
|
||||
cp "$KEYMAN_ROOT/web/LICENSE" "$DST/"
|
||||
cp "$KEYMAN_ROOT/web/README.md" "$DST/"
|
||||
fi
|
||||
|
||||
# ----------------------------------------
|
||||
# Build the project
|
||||
# ----------------------------------------
|
||||
# Build server
|
||||
tsc --build
|
||||
|
||||
npm run build || builder_die "Compilation failed."
|
||||
echo "Typescript compilation successful."
|
||||
# Post build
|
||||
mkdir -p "$THIS_SCRIPT_PATH/build/src/site/"
|
||||
mkdir -p "$THIS_SCRIPT_PATH/build/src/win32/"
|
||||
cp -r "$THIS_SCRIPT_PATH/src/site/"** "$THIS_SCRIPT_PATH/build/src/site/"
|
||||
cp -r "$THIS_SCRIPT_PATH/src/win32/"** "$THIS_SCRIPT_PATH/build/src/win32/"
|
||||
|
||||
# ----------------------------------------
|
||||
# Unit tests
|
||||
# ----------------------------------------
|
||||
replaceVersionStrings "$THIS_SCRIPT_PATH/build/src/site/lib/sentry/init.js.in" "$THIS_SCRIPT_PATH/build/src/site/lib/sentry/init.js"
|
||||
rm "$THIS_SCRIPT_PATH/build/src/site/lib/sentry/init.js.in"
|
||||
}
|
||||
|
||||
if (( run_tests )); then
|
||||
npm test || builder_die "Tests failed"
|
||||
fi
|
||||
|
||||
# ----------------------------------------
|
||||
# Deploy to dist/
|
||||
# ----------------------------------------
|
||||
|
||||
if (( production )) ; then
|
||||
function installer_server() {
|
||||
# We need to build in a tmp folder so that npm doesn't get confused by our
|
||||
# monorepo setup, and so we can copy the relevant node_modules in, because
|
||||
# we'll need them in order to build the deployable version.
|
||||
|
||||
PRODBUILDTEMP=`mktemp -d`
|
||||
local PRODBUILDTEMP=`mktemp -d`
|
||||
echo "Preparing in $PRODBUILDTEMP"
|
||||
# Remove @keymanapp devDependencies because they won't install outside the
|
||||
# monorepo context
|
||||
|
|
@ -180,14 +114,35 @@ if (( production )) ; then
|
|||
rm -f node_modules/ngrok/bin/ngrok.exe
|
||||
popd
|
||||
|
||||
# @keymanapp/keyman-version is required in dist now but we need to copy it in manually
|
||||
# @keymanapp/keyman-version is required in build/ now but we need to copy it in manually
|
||||
mkdir -p "$PRODBUILDTEMP/node_modules/@keymanapp/"
|
||||
cp -R "$KEYMAN_ROOT/node_modules/@keymanapp/keyman-version/" "$PRODBUILDTEMP/node_modules/@keymanapp/"
|
||||
|
||||
# We'll build in the $KEYMAN_ROOT/developer/bin/server/ folder
|
||||
rm -rf "$KEYMAN_ROOT/developer/bin/server/"
|
||||
mkdir -p "$KEYMAN_ROOT/developer/bin/server/dist/"
|
||||
cp -R dist/* "$KEYMAN_ROOT/developer/bin/server/dist/"
|
||||
mkdir -p "$KEYMAN_ROOT/developer/bin/server/build/"
|
||||
cp -R build/* "$KEYMAN_ROOT/developer/bin/server/build/"
|
||||
cp -R "$PRODBUILDTEMP"/* "$KEYMAN_ROOT/developer/bin/server/"
|
||||
rm -rf "$PRODBUILDTEMP"
|
||||
fi
|
||||
}
|
||||
|
||||
function test_server() {
|
||||
# eslint .
|
||||
tsc --build test
|
||||
# c8 --reporter=lcov --reporter=text
|
||||
mocha
|
||||
}
|
||||
|
||||
builder_run_action clean:server clean_server
|
||||
builder_run_action configure:server configure_server
|
||||
builder_run_action build:server build_server
|
||||
builder_run_action build:addins build_addins
|
||||
builder_run_action test:server test_server
|
||||
# builder_run_action test:addins # no op
|
||||
builder_run_action installer:server installer_server
|
||||
|
||||
# TODO: consider 'watch'
|
||||
# function watch_server() {
|
||||
# tsc-watch --onSuccess "node --inspect ." --onFailure "node --inspect ."
|
||||
# }
|
||||
# builder_run_action watch:server watch_server
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
{
|
||||
"name": "@keymanapp/developer-server",
|
||||
"description": "Keyman Developer backend server",
|
||||
"main": "dist/index.js",
|
||||
"main": "build/src/index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc -b",
|
||||
"postbuild": "npx gosh ./postbuild.sh",
|
||||
"prod": "node .",
|
||||
"test": "mocha",
|
||||
"watch": "npm run postbuild && tsc-watch --onSuccess \"node --inspect .\" --onFailure \"node --inspect .\""
|
||||
"build": "npx gosh ./build.sh build",
|
||||
"test": "npx gosh ./build.sh test"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -24,13 +22,13 @@
|
|||
"node-windows-trayicon": "keymanapp/node-windows-trayicon#keyman-16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@keymanapp/resources-gosh": "*",
|
||||
"@keymanapp/keyman-version": "*",
|
||||
"@keymanapp/resources-gosh": "*",
|
||||
"@types/chai": "^4.3.0",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^17.0.0",
|
||||
"@types/node": "^20.4.1",
|
||||
"@types/ws": "^8.2.2",
|
||||
"chai": "^4.3.4",
|
||||
"copyfiles": "^2.4.1",
|
||||
|
|
@ -41,6 +39,6 @@
|
|||
},
|
||||
"mocha": {
|
||||
"require": "ts-node/register",
|
||||
"spec": "**/*.test.ts"
|
||||
"spec": "build/**/*.test.js"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# postbuild script run by npm during/after a build
|
||||
#
|
||||
|
||||
# Exit on command failure and when using unset variables:
|
||||
set -eu
|
||||
|
||||
## 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
|
||||
|
||||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
|
||||
LOCAL_ROOT="$(dirname "$THIS_SCRIPT")"
|
||||
|
||||
mkdir -p "$LOCAL_ROOT/dist/site/"
|
||||
mkdir -p "$LOCAL_ROOT/dist/win32/"
|
||||
cp -r "$LOCAL_ROOT/src/site/"** "$LOCAL_ROOT/dist/site/"
|
||||
cp -r "$LOCAL_ROOT/src/win32/"** "$LOCAL_ROOT/dist/win32/"
|
||||
|
||||
replaceVersionStrings "$LOCAL_ROOT/dist/site/lib/sentry/init.js.in" "$LOCAL_ROOT/dist/site/lib/sentry/init.js"
|
||||
rm "$LOCAL_ROOT/dist/site/lib/sentry/init.js.in"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import fs = require('fs');
|
||||
import * as fs from 'fs';
|
||||
|
||||
export class Configuration {
|
||||
public readonly appDataPath: string;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import fs = require('fs');
|
||||
import { configuration } from './config';
|
||||
import * as fs from 'fs';
|
||||
import { configuration } from './config.js';
|
||||
|
||||
export interface DebugObject {
|
||||
id: string;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { extractVersionData } from './version-data';
|
||||
import { extractVersionData } from './version-data.js';
|
||||
// TODO: environment should be just KEYMAN_VERSION
|
||||
|
||||
const KEYMAN_VERSION = require("@keymanapp/keyman-version").KEYMAN_VERSION;
|
||||
import KEYMAN_VERSION from "@keymanapp/keyman-version";
|
||||
export const environment = extractVersionData(KEYMAN_VERSION.VERSION_WITH_TAG);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import chalk = require('chalk');
|
||||
import express = require('express');
|
||||
import { DebugObject, isValidId, simplifyId } from "../../../data";
|
||||
import * as express from 'express';
|
||||
import chalk from 'chalk';
|
||||
import { DebugObject, isValidId, simplifyId } from "../../../data.js";
|
||||
|
||||
export default function apiGet (data: { [id: string]: DebugObject }, req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
let id = req.query['id'] as string;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import express = require('express');
|
||||
import { DebugObject, isValidId, simplifyId } from "../../../data";
|
||||
import fs = require('fs');
|
||||
import crypto = require('crypto');
|
||||
import { configuration } from '../../../config';
|
||||
import chalk = require('chalk');
|
||||
import * as express from 'express';
|
||||
import { DebugObject, isValidId, simplifyId } from "../../../data.js";
|
||||
import * as fs from 'fs';
|
||||
import * as crypto from 'crypto';
|
||||
import { configuration } from '../../../config.js';
|
||||
import chalk from 'chalk';
|
||||
|
||||
// We allow only 12 objects of each type in the cache
|
||||
const MAX_OBJECTS = 12;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import express = require('express');
|
||||
import { DebugObject, isValidId, simplifyId } from "../../../data";
|
||||
import fs = require('fs');
|
||||
import chalk = require('chalk');
|
||||
import * as express from 'express';
|
||||
import { DebugObject, isValidId, simplifyId } from "../../../data.js";
|
||||
import * as fs from 'fs';
|
||||
import chalk from 'chalk';
|
||||
|
||||
export default function apiUnregister<O extends DebugObject> (root:{ [id: string]: O }, req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
let id = req.body['id'];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import chalk = require('chalk');
|
||||
import express = require('express');
|
||||
import { data, DebugFont, simplifyId } from "../../../data";
|
||||
import chalk from 'chalk';
|
||||
import * as express from 'express';
|
||||
import { data, DebugFont, simplifyId } from "../../../data.js";
|
||||
|
||||
export default function apiKeyboardRegister (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
const id = simplifyId(req.body['id']);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import chalk = require('chalk');
|
||||
import express = require('express');
|
||||
import { data, DebugKeyboard } from "../../../data";
|
||||
import chalk from 'chalk';
|
||||
import * as express from 'express';
|
||||
import { data, DebugKeyboard } from "../../../data.js";
|
||||
|
||||
export default function apiKeyboardRegister (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
const keyboard: DebugKeyboard = data.keyboards[req.body['id']];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import chalk = require('chalk');
|
||||
import express = require('express');
|
||||
import { data, DebugPackage } from "../../../data";
|
||||
import chalk from 'chalk';
|
||||
import * as express from 'express';
|
||||
import { data, DebugPackage } from "../../../data.js";
|
||||
|
||||
export default function apiPackageRegister (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
const kmp: DebugPackage = data.packages[req.body['id']];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import express = require('express');
|
||||
import path = require('path');
|
||||
import { data, SiteData } from "../../data";
|
||||
import * as express from 'express';
|
||||
import * as path from 'path';
|
||||
import { data, SiteData } from "../../data.js";
|
||||
|
||||
export default function handleIncKeyboardsCss (req: express.Request, res: express.Response) {
|
||||
let headers = {"Content-Type": "text/css"};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import express = require('express');
|
||||
import { SiteData, data } from "../../data";
|
||||
import * as express from 'express';
|
||||
import { SiteData, data } from "../../data.js";
|
||||
|
||||
export default function handleIncKeyboardsJs (req: express.Request, res: express.Response) {
|
||||
let headers = {"Content-Type": "application/javascript"};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import express = require('express');
|
||||
import { data } from "../../data";
|
||||
import { environment } from '../../environment';
|
||||
import * as express from 'express';
|
||||
import { data } from "../../data.js";
|
||||
import { environment } from '../../environment.js';
|
||||
|
||||
export default function handleIncPackagesJson (req: express.Request, res: express.Response) {
|
||||
const packages = Object.keys(data.packages).map(id => { return { id: id, filename: id+'.kmp', name: data.packages[id].name} });
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
import { environment } from './environment';
|
||||
import { environment } from './environment.js';
|
||||
|
||||
const Sentry = require("@sentry/node");
|
||||
import * as Sentry from '@sentry/node';
|
||||
Sentry.init({
|
||||
dsn: 'https://39b25a09410349a58fe12aaf721565af@o1005580.ingest.sentry.io/5983519', // Keyman Developer
|
||||
environment: environment.versionEnvironment,
|
||||
release: environment.versionGitTag
|
||||
});
|
||||
|
||||
import express = require('express');
|
||||
import ws = require('ws');
|
||||
import os = require('os');
|
||||
import multer = require('multer');
|
||||
import fs = require('fs');
|
||||
import setupRoutes from './routes';
|
||||
import { configuration } from './config';
|
||||
import tray from './tray';
|
||||
import chalk = require('chalk');
|
||||
import express from 'express';
|
||||
import * as ws from 'ws';
|
||||
import * as os from 'os';
|
||||
import multer from 'multer';
|
||||
import * as fs from 'fs';
|
||||
import setupRoutes from './routes.js';
|
||||
import { configuration } from './config.js';
|
||||
import tray from './tray.js';
|
||||
import chalk from 'chalk';
|
||||
|
||||
const options = {
|
||||
ngrokLog: false, // Set this to true if you need to see ngrok logs in the console
|
||||
|
|
@ -58,7 +58,7 @@ const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 102
|
|||
|
||||
/* Websockets */
|
||||
|
||||
const wsServer = new ws.Server({ noServer: true });
|
||||
const wsServer = new ws.WebSocketServer({ noServer: true });
|
||||
wsServer.on('connection', socket => {
|
||||
socket.on('message', (message) => {
|
||||
console.debug('wsServer.socket.onmessage: '+message.toString());
|
||||
|
|
@ -87,7 +87,7 @@ server.on('upgrade', (request, socket, head) => {
|
|||
configuration.ngrokEndpoint = '';
|
||||
|
||||
if(configuration.useNgrok && os.platform() == 'win32' && fs.existsSync(configuration.ngrokBinPath)) {
|
||||
const ngrok = require('ngrok');
|
||||
const ngrok: any = await import('ngrok');
|
||||
(async function() {
|
||||
configuration.ngrokEndpoint = await ngrok.connect({
|
||||
proto: 'http',
|
||||
|
|
|
|||
1
developer/src/server/src/ngrok.d.ts
vendored
Normal file
1
developer/src/server/src/ngrok.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
declare module 'ngrok';
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
import express = require('express');
|
||||
import multer = require('multer');
|
||||
import ws = require('ws');
|
||||
import handleIncKeyboardsJs from './handlers/inc/keyboards-js';
|
||||
import { data, DebugFont, DebugKeyboard, DebugModel, DebugObject, DebugPackage, isValidId } from './data';
|
||||
import apiGet from './handlers/api/debugobject/get';
|
||||
import apiRegister, { apiRegisterFile } from './handlers/api/debugobject/register';
|
||||
import apiKeyboardRegister from './handlers/api/keyboard/register';
|
||||
import apiFontRegister from './handlers/api/font/register';
|
||||
import apiUnregister from './handlers/api/debugobject/unregister';
|
||||
import handleIncPackagesJson from './handlers/inc/packages-json';
|
||||
import apiPackageRegister from './handlers/api/package/register';
|
||||
import handleIncKeyboardsCss from './handlers/inc/keyboards-css';
|
||||
import { Environment } from './version-data';
|
||||
import { configuration } from './config';
|
||||
import chalk = require('chalk');
|
||||
import * as express from 'express';
|
||||
import * as ws from 'ws';
|
||||
import * as multer from 'multer';
|
||||
import handleIncKeyboardsJs from './handlers/inc/keyboards-js.js';
|
||||
import { data, DebugFont, DebugKeyboard, DebugModel, DebugObject, DebugPackage, isValidId } from './data.js';
|
||||
import apiGet from './handlers/api/debugobject/get.js';
|
||||
import apiRegister, { apiRegisterFile } from './handlers/api/debugobject/register.js';
|
||||
import apiKeyboardRegister from './handlers/api/keyboard/register.js';
|
||||
import apiFontRegister from './handlers/api/font/register.js';
|
||||
import apiUnregister from './handlers/api/debugobject/unregister.js';
|
||||
import handleIncPackagesJson from './handlers/inc/packages-json.js';
|
||||
import apiPackageRegister from './handlers/api/package/register.js';
|
||||
import handleIncKeyboardsCss from './handlers/inc/keyboards-css.js';
|
||||
import { Environment } from './version-data.js';
|
||||
import { configuration } from './config.js';
|
||||
import chalk from 'chalk';
|
||||
|
||||
export default function setupRoutes(app: express.Express, upload: multer.Multer, wsServer: ws.Server, environment: Environment ) {
|
||||
export default function setupRoutes(app: express.Express, upload: multer.Multer, wsServer: ws.WebSocketServer, environment: Environment ) {
|
||||
|
||||
/* Middleware - JSON and logging */
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ export default function setupRoutes(app: express.Express, upload: multer.Multer,
|
|||
|
||||
/* All routes */
|
||||
|
||||
app.use('/', express.static('dist/site'));
|
||||
app.use('/', express.static('build/src/site'));
|
||||
|
||||
app.post('/upload', localhostOnly, upload.single('file'), (req, res, next) => {
|
||||
const name = req.file.originalname;
|
||||
|
|
@ -170,7 +170,7 @@ export default function setupRoutes(app: express.Express, upload: multer.Multer,
|
|||
|
||||
/* Utility functions */
|
||||
|
||||
function notifyClients(wsServer: ws.Server, res: express.Request, req: express.Response, next: express.NextFunction) {
|
||||
function notifyClients(wsServer: ws.WebSocketServer, res: express.Request, req: express.Response, next: express.NextFunction) {
|
||||
wsServer.clients.forEach(c => {
|
||||
c.send('refresh', (err) => {
|
||||
if(err) console.error(chalk.red('Websocket send error '+err.message));
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import os = require('os');
|
||||
import * as os from 'os';
|
||||
|
||||
class TrayStub {
|
||||
public start(localPort: number, ngrokAddress: string) {}
|
||||
|
|
@ -9,7 +9,7 @@ class TrayStub {
|
|||
let tray = new TrayStub();
|
||||
|
||||
if(os.platform() == 'win32') {
|
||||
const Win32Tray = require('./win32-tray');
|
||||
const { Win32Tray } = await import('./win32-tray.js');
|
||||
tray = new Win32Tray();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
import path = require("path");
|
||||
import * as path from "path";
|
||||
import * as url from 'url';
|
||||
|
||||
// TODO: this is a Windows-only tray icon. There are a number of
|
||||
// cross-platform solutions but none of them are wonderful. We
|
||||
// should replace this when we find a decent one.
|
||||
|
||||
const WindowsTrayicon = require("./win32/trayicon");
|
||||
const WindowsConsole = require("./win32/console");
|
||||
const open = require("open");
|
||||
import WindowsTrayicon from "./win32/trayicon/index.js";
|
||||
import WindowsConsole from "./win32/console/index.js";
|
||||
import open from 'open';
|
||||
|
||||
module.exports = class Win32Tray {
|
||||
export class Win32Tray {
|
||||
private myTrayApp: any;
|
||||
|
||||
public restart(localPort: number, ngrokAddress: string) {
|
||||
|
|
@ -55,7 +56,7 @@ module.exports = class Win32Tray {
|
|||
|
||||
this.myTrayApp = new WindowsTrayicon({
|
||||
title: "Keyman Developer Server",
|
||||
icon: path.resolve(__dirname, "site", "favicon.ico"),
|
||||
icon: path.resolve(url.fileURLToPath(new URL('.', import.meta.url)), "site", "favicon.ico"),
|
||||
menu: menu
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
declare module "node-hide-console-window" {
|
||||
function hideConsole(): void
|
||||
|
||||
function showConsole(): void
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
const os = require('os');
|
||||
const {showConsole, hideConsole} = require(os.arch() == 'ia32' ? "./node-hide-console-window" : "./node-hide-console-window.x64");
|
||||
|
||||
module.exports = {
|
||||
showConsole,
|
||||
hideConsole
|
||||
}
|
||||
6
developer/src/server/src/win32/console/index.ts
Normal file
6
developer/src/server/src/win32/console/index.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import * as os from 'os';
|
||||
import { createRequire } from 'node:module';
|
||||
const require = createRequire(import.meta.url);
|
||||
const {showConsole, hideConsole} = require(os.arch() == 'ia32' ? "./node-hide-console-window" : "./node-hide-console-window.x64");
|
||||
|
||||
export default { showConsole, hideConsole };
|
||||
|
|
@ -1,8 +1,17 @@
|
|||
const os = require('os');
|
||||
import * as os from 'os';
|
||||
import { createRequire } from 'node:module';
|
||||
const require = createRequire(import.meta.url);
|
||||
const { CTrayIconContainer } = require(os.arch() == 'ia32' ? "./addon" : "./addon.x64");
|
||||
|
||||
class WindowsTrayicon {
|
||||
constructor(options) {
|
||||
__itemCallbacks: any[];
|
||||
__icon: any;
|
||||
__trayTitle: any;
|
||||
__menuItems: any;
|
||||
__nativeTray: any;
|
||||
|
||||
|
||||
constructor(options: any) {
|
||||
this.__itemCallbacks = [];
|
||||
this.__icon = options.icon;
|
||||
this.__trayTitle = options.title || "";
|
||||
|
|
@ -12,7 +21,7 @@ class WindowsTrayicon {
|
|||
for (const item of this.__menuItems) {
|
||||
this.__nativeTray.AddMenuItem(item.id, item.caption);
|
||||
}
|
||||
this.__nativeTray.OnMenuItem((id) => {
|
||||
this.__nativeTray.OnMenuItem((id: any) => {
|
||||
for (const cb of this.__itemCallbacks) {
|
||||
cb(id);
|
||||
}
|
||||
|
|
@ -23,15 +32,15 @@ class WindowsTrayicon {
|
|||
}
|
||||
this.__nativeTray.Start();
|
||||
}
|
||||
item(cb) {
|
||||
item(cb: any) {
|
||||
if ("function" === typeof cb) {
|
||||
this.__itemCallbacks.push(cb);
|
||||
}
|
||||
}
|
||||
balloon(title, text, timeout = 5000) {
|
||||
balloon(title: any, text: any, timeout = 5000) {
|
||||
return new Promise((resolve) => {
|
||||
this.__nativeTray.ShowBalloon(title, text, timeout, () => {
|
||||
resolve();
|
||||
resolve(null);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
|
@ -40,4 +49,4 @@ class WindowsTrayicon {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = WindowsTrayicon;
|
||||
export default WindowsTrayicon;
|
||||
16
developer/src/server/test/tsconfig.json
Normal file
16
developer/src/server/test/tsconfig.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
"rootDirs": ["./", "../src/"],
|
||||
"outDir": "../build/test",
|
||||
"baseUrl": ".",
|
||||
},
|
||||
"include": [
|
||||
"**/*.test.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../" },
|
||||
]
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
import {assert} from 'chai';
|
||||
import 'mocha';
|
||||
|
||||
import { extractVersionData } from './version-data';
|
||||
|
||||
import { extractVersionData } from '../src/version-data.js';
|
||||
|
||||
describe('extractVersionData', function() {
|
||||
it('should parse version strings', function() {
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es2022",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"outDir": "dist/",
|
||||
"outDir": "build/src/",
|
||||
"rootDir": "src/",
|
||||
"baseUrl": ".",
|
||||
|
||||
"declaration": true,
|
||||
"alwaysStrict": true,
|
||||
"noImplicitThis": true,
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
"strictBindCallApply": true,
|
||||
"strictFunctionTypes": true,
|
||||
"noUnusedLocals": true,
|
||||
"allowJs": true,
|
||||
"lib": ["es2022"]
|
||||
},
|
||||
"include": [
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
<key>teamID</key>
|
||||
<string>3YE4W86L3G</string>
|
||||
<key>signingCertificate</key>
|
||||
<string>05473BF50CCD4B78B304656FB4D93FDC7EE7ACD0</string>
|
||||
<string>BB842A0081298BBA6D034C85451750B08FC9EE8A</string>
|
||||
<key>installerSigningCertificate</key>
|
||||
<string>05473BF50CCD4B78B304656FB4D93FDC7EE7ACD0</string>
|
||||
<string>BB842A0081298BBA6D034C85451750B08FC9EE8A</string>
|
||||
<key>provisioningProfiles</key>
|
||||
<dict>
|
||||
<key>Tavultesoft.Keyman</key>
|
||||
|
|
|
|||
165
package-lock.json
generated
165
package-lock.json
generated
|
|
@ -271,16 +271,9 @@
|
|||
"name": "@keymanapp/keyman-version",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.4.1",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
},
|
||||
"common/web/keyman-version/node_modules/@types/node": {
|
||||
"version": "20.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.1.tgz",
|
||||
"integrity": "sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==",
|
||||
"dev": true
|
||||
},
|
||||
"common/web/lm-message-types": {
|
||||
"name": "@keymanapp/lm-message-types",
|
||||
"license": "MIT",
|
||||
|
|
@ -2654,7 +2647,7 @@
|
|||
"@types/express": "^4.17.13",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^17.0.0",
|
||||
"@types/node": "^20.4.1",
|
||||
"@types/ws": "^8.2.2",
|
||||
"chai": "^4.3.4",
|
||||
"copyfiles": "^2.4.1",
|
||||
|
|
@ -2674,9 +2667,10 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"developer/src/server/node_modules/@types/node": {
|
||||
"version": "17.0.45",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"version": "20.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz",
|
||||
"integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==",
|
||||
"dev": true
|
||||
},
|
||||
"developer/src/server/node_modules/busboy": {
|
||||
"version": "1.6.0",
|
||||
|
|
@ -3830,6 +3824,21 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/yargs": {
|
||||
"version": "17.0.26",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.26.tgz",
|
||||
"integrity": "sha512-Y3vDy2X6zw/ZCumcwLpdhM5L7jmyGpmBCTYMHDLqT2IKVMYRRLdv6ZakA+wxhra6Z/3bwhNbNl9bDGXaFU+6rw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/yargs-parser": {
|
||||
"version": "21.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.1.tgz",
|
||||
"integrity": "sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/yauzl": {
|
||||
"version": "2.9.2",
|
||||
"license": "MIT",
|
||||
|
|
@ -4753,6 +4762,7 @@
|
|||
},
|
||||
"node_modules/camelcase": {
|
||||
"version": "5.3.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
|
|
@ -5148,6 +5158,7 @@
|
|||
},
|
||||
"node_modules/decamelize": {
|
||||
"version": "1.2.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
|
|
@ -5884,7 +5895,6 @@
|
|||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.1.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
|
|
@ -9573,6 +9583,7 @@
|
|||
},
|
||||
"node_modules/p-try": {
|
||||
"version": "2.2.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
|
|
@ -9603,6 +9614,7 @@
|
|||
},
|
||||
"node_modules/path-exists": {
|
||||
"version": "4.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
|
|
@ -9930,6 +9942,7 @@
|
|||
},
|
||||
"node_modules/require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/requirejs": {
|
||||
|
|
@ -10170,6 +10183,7 @@
|
|||
},
|
||||
"node_modules/set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"devOptional": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/set-immediate-shim": {
|
||||
|
|
@ -11172,6 +11186,7 @@
|
|||
},
|
||||
"node_modules/which-module": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/which-typed-array": {
|
||||
|
|
@ -11231,7 +11246,6 @@
|
|||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
|
|
@ -11247,7 +11261,6 @@
|
|||
},
|
||||
"node_modules/wrap-ansi/node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
|
|
@ -11255,7 +11268,6 @@
|
|||
},
|
||||
"node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
|
|
@ -11263,7 +11275,6 @@
|
|||
},
|
||||
"node_modules/wrap-ansi/node_modules/string-width": {
|
||||
"version": "4.2.2",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
|
|
@ -11276,7 +11287,6 @@
|
|||
},
|
||||
"node_modules/wrap-ansi/node_modules/strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
|
|
@ -11337,7 +11347,6 @@
|
|||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
|
|
@ -11497,16 +11506,14 @@
|
|||
"@actions/core": "^1.9.1",
|
||||
"@actions/github": "^2.1.0",
|
||||
"typescript": "^4.9.5",
|
||||
"yargs": "^15.1.0"
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^13.7.0",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@types/yargs": "^17.0.26",
|
||||
"semver": "^7.5.2",
|
||||
"ts-node": "^10.9.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/@types/node": {
|
||||
|
|
@ -11516,74 +11523,37 @@
|
|||
},
|
||||
"resources/build/version/node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"license": "MIT",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/cliui": {
|
||||
"version": "6.0.0",
|
||||
"license": "ISC",
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/find-up": {
|
||||
"version": "4.1.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/locate-path": {
|
||||
"version": "5.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-locate": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/p-locate": {
|
||||
"version": "4.1.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-limit": "^2.2.0"
|
||||
},
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"license": "MIT",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
|
|
@ -11595,7 +11565,8 @@
|
|||
},
|
||||
"resources/build/version/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"license": "MIT",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
|
|
@ -11603,51 +11574,29 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/y18n": {
|
||||
"version": "4.0.3",
|
||||
"license": "ISC"
|
||||
},
|
||||
"resources/build/version/node_modules/yargs": {
|
||||
"version": "15.4.1",
|
||||
"license": "MIT",
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"dependencies": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"resources/build/version/node_modules/yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"resources/gosh": {
|
||||
|
|
|
|||
|
|
@ -88,9 +88,7 @@ echo "increment-version.sh: building resources/build/version"
|
|||
pushd "$KEYMAN_ROOT"
|
||||
npm ci
|
||||
|
||||
pushd "$KEYMAN_ROOT/resources/build/version"
|
||||
npm run build:ts
|
||||
popd
|
||||
"$KEYMAN_ROOT/resources/build/version/build.sh"
|
||||
|
||||
echo "increment-version.sh: running resources/build/version"
|
||||
pushd "$KEYMAN_ROOT"
|
||||
|
|
|
|||
1
resources/build/version/.gitignore
vendored
1
resources/build/version/.gitignore
vendored
|
|
@ -47,3 +47,4 @@ coverage
|
|||
# Build output
|
||||
dist
|
||||
lib
|
||||
build
|
||||
|
|
|
|||
24
resources/build/version/build.sh
Executable file
24
resources/build/version/build.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/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
|
||||
|
||||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
|
||||
# This script runs from its own folder
|
||||
cd "$THIS_SCRIPT_PATH"
|
||||
|
||||
################################ Main script ################################
|
||||
|
||||
builder_describe "Build version tooling" clean configure build
|
||||
builder_describe_outputs \
|
||||
configure /resources/build/version/node_modules \
|
||||
build /resources/build/version/build/src/index.js
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
builder_run_action clean rm -rf build/ node_modules/ dist/ lib/
|
||||
builder_run_action configure verify_npm_setup
|
||||
builder_run_action build tsc --build
|
||||
|
|
@ -1,25 +1,24 @@
|
|||
{
|
||||
"description": "Automatically updates HISTORY.md based on pull requests",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.9.1",
|
||||
"@actions/github": "^2.1.0",
|
||||
"typescript": "^4.9.5",
|
||||
"yargs": "^15.1.0"
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"description": "Automatically updates HISTORY.md based on pull requests",
|
||||
"devDependencies": {
|
||||
"@types/node": "^13.7.0",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@types/yargs": "^17.0.26",
|
||||
"semver": "^7.5.2",
|
||||
"ts-node": "^10.9.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0"
|
||||
},
|
||||
"files": [
|
||||
"src"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
"main": "build/src/index.js",
|
||||
"name": "@keymanapp/auto-history-action",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
import { GitHub } from '@actions/github';
|
||||
import { readFileSync, writeFileSync } from 'fs';
|
||||
import { gt } from 'semver';
|
||||
import { reportHistory } from './reportHistory';
|
||||
import { reportHistory } from './reportHistory.js';
|
||||
|
||||
interface PRInformation {
|
||||
title: string;
|
||||
|
|
@ -42,7 +42,8 @@ const splicePullsIntoHistory = async (pulls: PRInformation[]): Promise<{count: n
|
|||
const versionMatch = new RegExp(`^## ${version} ${tier}`, 'i');
|
||||
|
||||
let historyChunks: { heading: string[]; newer: string[]; current: string[]; older: string[] } = {heading:[], newer:[], current:[], older:[]};
|
||||
let state = "heading";
|
||||
type ChunkType = keyof typeof historyChunks;
|
||||
let state: ChunkType = "heading";
|
||||
for(const line of history) {
|
||||
if(line.match(versionMatch)) {
|
||||
// We are in the correct section of history
|
||||
|
|
@ -90,7 +91,7 @@ const splicePullsIntoHistory = async (pulls: PRInformation[]): Promise<{count: n
|
|||
|
||||
let found = false;
|
||||
// Look for the PR in any other chunk -- can be found with merges of master into PR or chained PRs
|
||||
for(const chunk of ['newer','current','older']) {
|
||||
for(const chunk of ['newer','current','older'] as ChunkType[]) {
|
||||
for(const line of historyChunks[chunk]) {
|
||||
if(line.match(pullNumberRe)) {
|
||||
found = true;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
import { info as logInfo } from '@actions/core';
|
||||
import { GitHub } from '@actions/github';
|
||||
|
||||
import { sendCommentToPullRequestAndRelatedIssues, fixupHistory } from './fixupHistory';
|
||||
import { incrementVersion } from './incrementVersion';
|
||||
const yargs = require('yargs');
|
||||
import { sendCommentToPullRequestAndRelatedIssues, fixupHistory } from './fixupHistory.js';
|
||||
import { incrementVersion } from './incrementVersion.js';
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
import { readFileSync } from 'fs';
|
||||
import { reportHistory } from './reportHistory';
|
||||
import { reportHistory } from './reportHistory.js';
|
||||
|
||||
const argv = yargs
|
||||
const argv = await yargs(hideBin(process.argv))
|
||||
.command(['history'], 'Fixes up HISTORY.md with pull request data')
|
||||
.command(['version'], 'Increments the current patch version in VERSION.md')
|
||||
.command(['report-history'], 'Print list of outstanding PRs waiting for the next build')
|
||||
|
|
@ -81,10 +82,10 @@ const main = async (): Promise<void> => {
|
|||
|
||||
if(argv._.includes('report-history')) {
|
||||
let pulls = await reportHistory(octokit, argv.base, argv.force, argv['github-pr'], argv.from, argv.to);
|
||||
let versions = {};
|
||||
let versions: {[index:string]:any} = {};
|
||||
pulls.forEach((item) => {
|
||||
if(typeof item.version == 'string') {
|
||||
if(typeof versions[item.version] == 'undefined') {
|
||||
if(typeof (versions)[item.version] == 'undefined') {
|
||||
versions[item.version] = {data: item.tag_data, pulls: []};
|
||||
}
|
||||
// We want to invert the order of the pulls as we go to
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import { warning as logWarning, info as logInfo } from '@actions/core';
|
|||
|
||||
import { GitHub } from '@actions/github';
|
||||
|
||||
import { findLastHistoryPR, getAssociatedPR} from './graphql/queries';
|
||||
import { spawnChild } from './util/spawnAwait';
|
||||
import { findLastHistoryPR, getAssociatedPR} from './graphql/queries.js';
|
||||
import { spawnChild } from './util/spawnAwait.js';
|
||||
|
||||
const getPullRequestInformation = async (
|
||||
octokit: GitHub, base: string
|
||||
|
|
@ -67,7 +67,7 @@ const getAssociatedPRInformation = async (
|
|||
}
|
||||
}: any = response;
|
||||
|
||||
const node = nodes.find(node => node.state == 'MERGED');
|
||||
const node = nodes.find((node:any) => node.state == 'MERGED');
|
||||
return node ? { title: node.title, number: node.number } : undefined;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "."
|
||||
"rootDir": ".",
|
||||
"outDir": "build/",
|
||||
},
|
||||
"extends": "./tsconfig.production.json",
|
||||
"include": ["./**/*"]
|
||||
"include": ["./**/*.ts"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"alwaysStrict": true,
|
||||
"charset": "utf-8",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"downlevelIteration": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": ["es2017"],
|
||||
"module": "commonjs",
|
||||
"noImplicitAny": false,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"outDir": "lib",
|
||||
"pretty": true,
|
||||
"rootDir": "src",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"target": "es2017"
|
||||
},
|
||||
"files": ["./src/index.ts"]
|
||||
}
|
||||
|
|
@ -1,5 +1,18 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "ES2022",
|
||||
"target": "es2022",
|
||||
"moduleResolution": "node16",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"sourceMap": true,
|
||||
"alwaysStrict": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitAny": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictFunctionTypes": true,
|
||||
"noUnusedLocals": true,
|
||||
|
||||
"rootDir": ".",
|
||||
|
||||
// TODO: move all compiler options here
|
||||
|
|
@ -9,7 +22,9 @@
|
|||
"declarationMap": true,
|
||||
|
||||
"baseUrl": ".",
|
||||
|
||||
"paths": {
|
||||
"@keymanapp/common-types": ["./common/web/types/src/main"],
|
||||
"@keymanapp/input-processor": ["./common/web/input-processor/src"],
|
||||
"@keymanapp/keyboard-processor": ["./common/web/keyboard-processor/src"],
|
||||
"@keymanapp/keyman": ["./web" ],
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
// Lists only CommonJS or 'none' modules; as we move modules from cjs/none to
|
||||
// esm, we should move them from here into tsconfig.esm.json. Eventually, when
|
||||
// we have only ES modules, we'll delete this file.
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./common/predictive-text/testing/one-stage-embedded-webworker/tsconfig.json" },
|
||||
{ "path": "./common/predictive-text/testing/two-stage-embedded-webworker/tsconfig.json" },
|
||||
{ "path": "./common/predictive-text/testing/two-stage-embedded-webworker/worker/tsconfig.json" },
|
||||
|
||||
{ "path": "./developer/src/server/tsconfig.json" },
|
||||
|
||||
{ "path": "./resources/build/version/tsconfig.json" },
|
||||
{ "path": "./resources/build/version/tsconfig.production.json" },
|
||||
// { "path": "./web/bulk_rendering/tsconfig.json" },
|
||||
]
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"extends": "./tsconfig-base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"module": "ES2022",
|
||||
"target": "es2022",
|
||||
"moduleResolution": "Node16",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"sourceMap": true,
|
||||
"alwaysStrict": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitAny": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictFunctionTypes": true,
|
||||
"noUnusedLocals": true,
|
||||
|
||||
"paths": {
|
||||
"@keymanapp/keyman-version": ["./common/web/keyman-version/keyman-version.mts"],
|
||||
"@keymanapp/common-types": ["./common/web/types/src/main"],
|
||||
// "@keymanapp/": ["core/include/ldml/ldml-keyboard-constants"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -1,19 +1,28 @@
|
|||
{
|
||||
// Lists only ES modules; as we move modules from cjs/none to esm, we should
|
||||
// move them from tsconfig.cjs.json to here. Eventually, when we have only ES
|
||||
// modules, we can rename this to tsconfig.json.
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./core/include/ldml/tsconfig.json" },
|
||||
|
||||
//{ "path": "./developer/src/kmc/test/tsconfig.json" },
|
||||
{ "path": "./common/models/templates/tsconfig.json" },
|
||||
{ "path": "./common/models/types/tsconfig.json" },
|
||||
{ "path": "./common/models/wordbreakers/tsconfig.json" },
|
||||
{ "path": "./common/predictive-text/tsconfig.json" },
|
||||
{ "path": "./common/tools/hextobin/" },
|
||||
{ "path": "./common/web/input-processor/tsconfig.json" },
|
||||
{ "path": "./common/web/keyboard-processor/tsconfig.json" },
|
||||
{ "path": "./common/web/keyman-version" },
|
||||
{ "path": "./common/web/lm-message-types/" },
|
||||
{ "path": "./common/web/lm-worker/" },
|
||||
{ "path": "./common/web/recorder/tsconfig.json" },
|
||||
{ "path": "./common/web/sentry-manager/src/tsconfig.json" },
|
||||
{ "path": "./common/web/types/" },
|
||||
{ "path": "./common/web/utils/tsconfig.json" },
|
||||
|
||||
{ "path": "./developer/src/common/web/test-helpers/tsconfig.json" },
|
||||
|
||||
{ "path": "./developer/src/kmc/tsconfig.json" },
|
||||
|
||||
// { "path": "./developer/src/kmc-analyze/test/tsconfig.json" },
|
||||
{ "path": "./developer/src/kmc/test/tsconfig.json" },
|
||||
{ "path": "./developer/src/kmc-analyze/tsconfig.json" },
|
||||
// { "path": "./developer/src/kmc-analyze/test/tsconfig.json" },
|
||||
{ "path": "./developer/src/kmc-kmn/test/tsconfig.json" },
|
||||
{ "path": "./developer/src/kmc-kmn/tsconfig.json" },
|
||||
{ "path": "./developer/src/kmc-keyboard-info/test/tsconfig.json" },
|
||||
|
|
@ -26,25 +35,12 @@
|
|||
{ "path": "./developer/src/kmc-model-info/tsconfig.json" },
|
||||
{ "path": "./developer/src/kmc-package/test/tsconfig.json" },
|
||||
{ "path": "./developer/src/kmc-package/tsconfig.json" },
|
||||
{ "path": "./developer/src/server/tsconfig.json" },
|
||||
|
||||
{ "path": "./common/web/keyman-version" },
|
||||
{ "path": "./common/web/types/" },
|
||||
|
||||
{ "path": "./common/web/input-processor/tsconfig.json" },
|
||||
{ "path": "./common/web/keyboard-processor/tsconfig.json" },
|
||||
{ "path": "./common/web/recorder/tsconfig.json" },
|
||||
{ "path": "./common/web/sentry-manager/src/tsconfig.json" },
|
||||
{ "path": "./common/web/utils/tsconfig.json" },
|
||||
|
||||
{ "path": "./common/models/templates/tsconfig.json" },
|
||||
{ "path": "./common/models/types/tsconfig.json" },
|
||||
{ "path": "./common/models/wordbreakers/tsconfig.json" },
|
||||
{ "path": "./common/predictive-text/tsconfig.json" },
|
||||
{ "path": "./resources/build/version/" },
|
||||
|
||||
{ "path": "./web/src/tsconfig.all.json" },
|
||||
// { "path": "./web/tools/recorder/tsconfig.json" },
|
||||
// { "path": "./web/tools/sourcemap-root/tsconfig.json" },
|
||||
{ "path": "./common/web/lm-message-types/" },
|
||||
{ "path": "./common/web/lm-worker/" },
|
||||
]
|
||||
}
|
||||
|
|
@ -1,15 +1,24 @@
|
|||
{
|
||||
"extends": "../tsconfig-base.json",
|
||||
"extends": "../tsconfig.base.json",
|
||||
|
||||
// TODO: eliminate settings duplicated in ../tsconfig.base.json
|
||||
"compilerOptions": {
|
||||
// Primary settings - the version of ES6 we can target in TS, our downcompile target,
|
||||
// and our module-related settings.
|
||||
"allowSyntheticDefaultImports": true,
|
||||
|
||||
"lib": ["es6"],
|
||||
"module": "es6",
|
||||
"moduleResolution": "Node16",
|
||||
"target": "es5",
|
||||
|
||||
// TODO: These override ../tsconfig.base.json settings, and so should be removed if possible,
|
||||
// but existing code in web/ breaks some of these settinsg
|
||||
"noImplicitThis": false,
|
||||
"noImplicitReturns": false,
|
||||
"noImplicitAny": false,
|
||||
"strictFunctionTypes": false,
|
||||
"noUnusedLocals": false,
|
||||
|
||||
// Other settings - declaration files, sourcemapping, and other miscellaneous bits.
|
||||
"allowJs": false,
|
||||
"declaration": true,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue