diff --git a/bundles/org.openhab.automation.jsscripting/pom.xml b/bundles/org.openhab.automation.jsscripting/pom.xml index fd2259ec8..8a69afe50 100644 --- a/bundles/org.openhab.automation.jsscripting/pom.xml +++ b/bundles/org.openhab.automation.jsscripting/pom.xml @@ -22,7 +22,7 @@ !jdk.internal.reflect.*, !jdk.vm.ci.services - 22.3.0 + 22.0.0.2 6.2.1 ${project.version} openhab@2.1.0 @@ -135,11 +135,7 @@ js ${graal.version} - - com.ibm.icu - icu4j - 69.1 - + diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index f810e2375..a4c27008a 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -210,7 +210,10 @@ public class OpenhabGraalJSScriptEngine delegate.getBindings(ScriptContext.ENGINE_SCOPE).put(REQUIRE_WRAPPER_NAME, wrapRequireFn); // Injections into the JS runtime delegate.put("require", wrapRequireFn.apply((Function) delegate.get("require"))); - jsRuntimeFeatures.getFeatures().forEach((key, obj) -> delegate.put(key, obj)); + jsRuntimeFeatures.getFeatures().forEach((key, obj) -> { + LOGGER.debug("Injecting {} into the JS runtime...", key); + delegate.put(key, obj); + }); initialized = true; diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js index 88d31c686..a39854783 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js @@ -1,189 +1,189 @@ // ThreadsafeTimers is injected into the JS runtime (function (global) { - 'use strict'; + 'use strict'; - // Append the script file name OR rule UID depending on which is available - const defaultIdentifier = "org.openhab.automation.script" + (globalThis["javax.script.filename"] ? ".file." + globalThis["javax.script.filename"].replace(/^.*[\\\/]/, '') : globalThis["ruleUID"] ? ".ui." + globalThis["ruleUID"] : ""); - const System = Java.type('java.lang.System'); - const formatRegExp = /%[sdj%]/g; - // Pass the defaultIdentifier to ThreadsafeTimers to enable naming of scheduled jobs - ThreadsafeTimers.setIdentifier(defaultIdentifier); + // Append the script file name OR rule UID depending on which is available + const defaultIdentifier = 'org.openhab.automation.script' + (globalThis['javax.script.filename'] ? '.file.' + globalThis['javax.script.filename'].replace(/^.*[\\\/]/, '') : globalThis.ruleUID ? '.ui.' + globalThis.ruleUID : ''); + const System = Java.type('java.lang.System'); + const formatRegExp = /%[sdj%]/g; + // Pass the defaultIdentifier to ThreadsafeTimers to enable naming of scheduled jobs + ThreadsafeTimers.setIdentifier(defaultIdentifier); - function createLogger(name = defaultIdentifier) { - return Java.type("org.slf4j.LoggerFactory").getLogger(name); + function createLogger (name = defaultIdentifier) { + return Java.type('org.slf4j.LoggerFactory').getLogger(name); + } + + // User configurable + let log = createLogger(); + + function stringify (value) { + try { + if (Java.isJavaObject(value)) { + return value.toString(); + } else { + // special cases + if (value === undefined) { + return 'undefined'; + } + if (typeof value === 'function') { + return '[Function]'; + } + if (value instanceof RegExp) { + return value.toString(); + } + // fallback to JSON + return JSON.stringify(value, null, 2); + } + } catch (e) { + return '[Circular: ' + e + ']'; + } + } + + function format (f) { + if (typeof f !== 'string') { + const objects = []; + for (let index = 0; index < arguments.length; index++) { + objects.push(stringify(arguments[index])); + } + return objects.join(' '); } - // User configurable - let log = createLogger(); + if (arguments.length === 1) return f; - function stringify(value) { - try { - if (Java.isJavaObject(value)) { - return value.toString(); - } else { - // special cases - if (value === undefined) { - return "undefined" - } - if (typeof value === 'function') { - return "[Function]" - } - if (value instanceof RegExp) { - return value.toString(); - } - // fallback to JSON - return JSON.stringify(value, null, 2); - } - } catch (e) { - return '[Circular: ' + e + ']'; - } + let i = 1; + const args = arguments; + const len = args.length; + let str = String(f).replace(formatRegExp, function (x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + // falls through + default: + return x; + } + }); + for (let x = args[i]; i < len; x = args[++i]) { + if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) { + str += ' ' + x; + } else { + str += ' ' + stringify(x); + } } + return str; + } - function format(f) { - if (typeof f !== 'string') { - var objects = []; - for (var index = 0; index < arguments.length; index++) { - objects.push(stringify(arguments[index])); - } - return objects.join(' '); + const counters = {}; + const timers = {}; + + // Polyfills for common NodeJS functions + + const console = { + assert: function (expression, message) { + if (!expression) { + log.error(message); + } + }, + + count: function (label) { + let counter; + + if (label) { + if (counters.hasOwnProperty(label)) { + counter = counters[label]; + } else { + counter = 0; } - if (arguments.length === 1) return f; + // update + counters[label] = ++counter; + log.debug(format.apply(null, [label + ':', counter])); + } + }, - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function (x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - // falls through - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) { - str += ' ' + x; - } else { - str += ' ' + stringify(x); - } + debug: function () { + log.debug(format.apply(null, arguments)); + }, + + info: function () { + log.info(format.apply(null, arguments)); + }, + + log: function () { + log.info(format.apply(null, arguments)); + }, + + warn: function () { + log.warn(format.apply(null, arguments)); + }, + + error: function () { + log.error(format.apply(null, arguments)); + }, + + trace: function (e) { + if (Java.isJavaObject(e)) { + log.trace(e.getLocalizedMessage(), e); + } else { + if (e.stack) { + log.trace(e.stack); + } else { + if (e.message) { + log.trace(format.apply(null, [(e.name || 'Error') + ':', e.message])); + } else { + log.trace((e.name || 'Error')); + } } - return str; + } + }, + + time: function (label) { + if (label) { + timers[label] = System.currentTimeMillis(); + } + }, + + timeEnd: function (label) { + if (label) { + const now = System.currentTimeMillis(); + if (timers.hasOwnProperty(label)) { + log.info(format.apply(null, [label + ':', (now - timers[label]) + 'ms'])); + delete timers[label]; + } else { + log.info(format.apply(null, [label + ':', ''])); + } + } + }, + + // Allow user customizable logging names + // Be aware that a log4j2 required a logger defined for the logger name, otherwise messages won't be logged! + set loggerName (name) { + log = createLogger(name); + this._loggerName = name; + ThreadsafeTimers.setIdentifier(name); + }, + + get loggerName () { + return this._loggerName || defaultIdentifier; } + }; - const counters = {}; - const timers = {}; + // Polyfill common NodeJS functions onto the global object + globalThis.console = console; + globalThis.setTimeout = ThreadsafeTimers.setTimeout; + globalThis.clearTimeout = ThreadsafeTimers.clearTimeout; + globalThis.setInterval = ThreadsafeTimers.setInterval; + globalThis.clearInterval = ThreadsafeTimers.clearInterval; - // Polyfills for common NodeJS functions - - const console = { - 'assert': function (expression, message) { - if (!expression) { - log.error(message); - } - }, - - count: function (label) { - let counter; - - if (label) { - if (counters.hasOwnProperty(label)) { - counter = counters[label]; - } else { - counter = 0; - } - - // update - counters[label] = ++counter; - log.debug(format.apply(null, [label + ':', counter])); - } - }, - - debug: function () { - log.debug(format.apply(null, arguments)); - }, - - info: function () { - log.info(format.apply(null, arguments)); - }, - - log: function () { - log.info(format.apply(null, arguments)); - }, - - warn: function () { - log.warn(format.apply(null, arguments)); - }, - - error: function () { - log.error(format.apply(null, arguments)); - }, - - trace: function (e) { - if (Java.isJavaObject(e)) { - log.trace(e.getLocalizedMessage(), e); - } else { - if (e.stack) { - log.trace(e.stack); - } else { - if (e.message) { - log.trace(format.apply(null, [(e.name || 'Error') + ':', e.message])); - } else { - log.trace((e.name || 'Error')); - } - } - } - }, - - time: function (label) { - if (label) { - timers[label] = System.currentTimeMillis(); - } - }, - - timeEnd: function (label) { - if (label) { - const now = System.currentTimeMillis(); - if (timers.hasOwnProperty(label)) { - log.info(format.apply(null, [label + ':', (now - timers[label]) + 'ms'])); - delete timers[label]; - } else { - log.info(format.apply(null, [label + ':', ''])); - } - } - }, - - // Allow user customizable logging names - // Be aware that a log4j2 required a logger defined for the logger name, otherwise messages won't be logged! - set loggerName(name) { - log = createLogger(name); - this._loggerName = name; - ThreadsafeTimers.setIdentifier(name); - }, - - get loggerName() { - return this._loggerName || defaultIdentifier; - } - }; - - // Polyfill common NodeJS functions onto the global object - globalThis.console = console; - globalThis.setTimeout = ThreadsafeTimers.setTimeout; - globalThis.clearTimeout = ThreadsafeTimers.clearTimeout; - globalThis.setInterval = ThreadsafeTimers.setInterval; - globalThis.clearInterval = ThreadsafeTimers.clearInterval; - - // Support legacy NodeJS libraries - globalThis.global = globalThis; - globalThis.process = { env: { NODE_ENV: '' } }; + // Support legacy NodeJS libraries + globalThis.global = globalThis; + globalThis.process = { env: { NODE_ENV: '' } }; })(this);