mirror of
https://github.com/gnh1201/welsonjs.git
synced 2026-04-18 18:18:42 +00:00
Implement MCP JSON-RPC handling and related I/O fixes: mcploader now handles initialize, tools/list and tools/call (implements add_both_numbers) and returns JSON-RPC responses; stdio-server.send serializes object messages before writing; console logging on WScript now writes muted messages to StdErr; bump jsonrpc2 version to 0.1.7 and reformat extract(). These changes enable proper MCP capability negotiation, tool discovery and invocation over stdio.
903 lines
28 KiB
JavaScript
903 lines
28 KiB
JavaScript
// app.js
|
|
// Copyright 2019-2025, Namhyeon Go <gnh1201@catswords.re.kr> and the WelsonJS contributors.
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// https://github.com/gnh1201/welsonjs
|
|
|
|
// Bootstrap code for running a javascript app in windows. Run as:
|
|
// cscript.js app.js <appname> <app arguments> ...
|
|
//
|
|
"use strict";
|
|
|
|
var exit = function(status) {
|
|
console.error("Exit", status, "caused");
|
|
|
|
if (typeof WScript !== "undefined") {
|
|
WScript.Quit(status);
|
|
return;
|
|
} else if (typeof window !== "undefined") {
|
|
window.close();
|
|
return;
|
|
}
|
|
|
|
// to exit completely
|
|
throw new Error("Exit " + status + " caused");
|
|
};
|
|
|
|
var console = {
|
|
_timers: {},
|
|
_counters: {},
|
|
_messages: [],
|
|
_join: function(args, sep) {
|
|
args = args || [];
|
|
sep = sep || ' ';
|
|
var res = '';
|
|
for (var i = args.length - 1; i > -1; i--) {
|
|
res = (i ? sep : '') + args[i] + res;
|
|
}
|
|
return res;
|
|
},
|
|
_muted: (function() {
|
|
try {
|
|
if (typeof WScript !== "undefined")
|
|
return WScript.Arguments.Named.Exists("quiet");
|
|
} catch (e) { /* ignore */ }
|
|
|
|
return false;
|
|
})(),
|
|
_echoCallback: function(params, type) {
|
|
if (this._muted) return;
|
|
|
|
if (typeof WScript !== "undefined") {
|
|
if (this._muted) {
|
|
WScript.StdErr.WriteLine("[*] " + params.message);
|
|
return;
|
|
}
|
|
WScript.StdOut.WriteLine("[*] " + params.message);
|
|
}
|
|
},
|
|
_echo: function(args, type) {
|
|
var messages = [];
|
|
var params = {
|
|
type: type,
|
|
scope: [],
|
|
message: '',
|
|
datetime: new Date().toISOString()
|
|
};
|
|
|
|
var argl = args.length;
|
|
for (var i = 0; i < argl; i++) {
|
|
switch (typeof args[i]) {
|
|
case "string":
|
|
messages.push(args[i]);
|
|
break;
|
|
|
|
case "number":
|
|
case "boolean":
|
|
messages.push(String(args[i]));
|
|
break;
|
|
|
|
case "object":
|
|
if ("message" in args[i]) {
|
|
messages.push(args[i].message);
|
|
for (var k in args[i]) {
|
|
params[k] = args[i][k];
|
|
}
|
|
} else {
|
|
messages.push("[object Object]");
|
|
}
|
|
break;
|
|
|
|
case "unknown":
|
|
messages.push("[unknown]");
|
|
break;
|
|
}
|
|
}
|
|
|
|
params.message = messages.join(' ');
|
|
if (typeof type !== "undefined") {
|
|
params.message = type + ": " + params.message;
|
|
}
|
|
this._echoCallback(params);
|
|
this._messages.push(params.message);
|
|
|
|
if (params.scope.length > 0) {
|
|
this._echoCallback(params, type);
|
|
}
|
|
},
|
|
assert: function(assertion) {
|
|
if (arguments.length > 1 && assertion === arguments[0]) {
|
|
if(!assertion) {
|
|
this.error("Assertion failed:", this._join(arguments.slice(1)));
|
|
}
|
|
}
|
|
},
|
|
clear: function() {
|
|
this._messages = [];
|
|
},
|
|
log: function() {
|
|
this._echo(arguments);
|
|
},
|
|
error: function() {
|
|
this._echo(arguments, "error");
|
|
},
|
|
info: function() {
|
|
this._echo(arguments, "info");
|
|
},
|
|
warn: function() {
|
|
this._echo(arguments, "warn");
|
|
},
|
|
debug: function() {
|
|
this._echo(arguments, "debug");
|
|
},
|
|
trace: function() {
|
|
try {
|
|
var callee = arguments.callee.caller.caller;
|
|
throw new TraceError("DEBUG", "", callee);
|
|
} catch (e) {
|
|
this.debug(e.message);
|
|
}
|
|
},
|
|
time: function(label) {
|
|
label = label || "default";
|
|
if (!(label in this._timers)) {
|
|
this._timers[label] = new Date();
|
|
}
|
|
},
|
|
timeLog: function(label, end) {
|
|
label = label || "default";
|
|
if (label in this._timers) {
|
|
console.debug(label + ":", ((new Date()).getTime() - this._timers[label].getTime()) + "ms", (end ? " - timer ended" : ""));
|
|
}
|
|
},
|
|
timeEnd: function(label) {
|
|
label = label || "default";
|
|
if (label in this._timers) {
|
|
this.timeLog();
|
|
delete this._timers[label];
|
|
}
|
|
},
|
|
count: function(label) {
|
|
label = label || "default";
|
|
if (!(label in this._counters)) {
|
|
this._counters[label] = 1;
|
|
}
|
|
},
|
|
countReset: function(label) {
|
|
label = label || "default";
|
|
if (label in this._counters) {
|
|
this.timeLog();
|
|
delete this._counters[label];
|
|
}
|
|
}
|
|
};
|
|
|
|
function TraceError(severity, message, callee) {
|
|
var MAX_DEPTH = 20;
|
|
|
|
var SEVERITY_MAP = {
|
|
"": "ERROR",
|
|
"LOG": "INFO",
|
|
"INFO": "INFO",
|
|
"WARN": "WARN",
|
|
"WARNING": "WARN",
|
|
"ERROR": "ERROR",
|
|
"ERR": "ERROR",
|
|
"CRITICAL": "ERROR",
|
|
"FATAL": "ERROR",
|
|
"DEBUG": "DEBUG"
|
|
};
|
|
|
|
var CONSOLE_METHOD_MAP = {
|
|
"ERROR": "error",
|
|
"WARN": "warn",
|
|
"INFO": "info",
|
|
"DEBUG": "debug"
|
|
};
|
|
|
|
function fnName(fn) {
|
|
return fn ? (fn.__name__ || fn.name || "(anonymous)") : "(null)";
|
|
}
|
|
|
|
function normSeverity(s) {
|
|
s = (s == null) ? "" : String(s);
|
|
s = s.toUpperCase();
|
|
return SEVERITY_MAP[s] || (s || "ERROR");
|
|
}
|
|
|
|
function callersOf(startFn) {
|
|
var out = [];
|
|
var f = startFn;
|
|
var i = 0;
|
|
|
|
while (f && i < MAX_DEPTH) {
|
|
out[out.length] = fnName(f);
|
|
try {
|
|
f = f.caller;
|
|
} catch (e) {
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function pickConsoleFn(sev) {
|
|
if (typeof console === "undefined" || !console)
|
|
return null;
|
|
|
|
var methodName = CONSOLE_METHOD_MAP[sev] || "log";
|
|
var fn = console[methodName] || console.log;
|
|
|
|
if (!fn)
|
|
return null;
|
|
|
|
return (function (fns) {
|
|
var i;
|
|
|
|
return function (s) {
|
|
for (i = 0; i < fns.length; i++) {
|
|
try {
|
|
fns[i](s);
|
|
return;
|
|
} catch (e) {
|
|
// try next
|
|
}
|
|
}
|
|
};
|
|
})([
|
|
function (s) { fn.call(console, s); }, // 1) severity-specific console
|
|
function (s) { console.log(s); }, // 2) generic console.log
|
|
function (s) { WScript.StdOut.WriteLine(s); } // 3) WSH fallback
|
|
]);
|
|
}
|
|
|
|
function buildMessage(name, sev, msg, chain) {
|
|
var s = name + " [" + sev + "]";
|
|
if (msg) s += ": " + msg;
|
|
if (chain) s += "\r\n" + chain;
|
|
return s;
|
|
}
|
|
|
|
this.name = "TraceException";
|
|
this.severity = normSeverity(severity);
|
|
this.message = message || "";
|
|
this.description = this.message; // IE friendly
|
|
this.callee = callee || null;
|
|
|
|
this.callers = callersOf(this.callee);
|
|
this.callChain = this.callers.length ? this.callers.join("\r\n <- ") : "";
|
|
|
|
this.fullMessage = buildMessage(this.name, this.severity, this.message, this.callChain);
|
|
this.toString = function () {
|
|
return this.fullMessage;
|
|
};
|
|
|
|
this._logFn = pickConsoleFn(this.severity);
|
|
|
|
this.log = function () {
|
|
if (this._logFn)
|
|
this._logFn(this.fullMessage);
|
|
};
|
|
|
|
this.log();
|
|
}
|
|
TraceError.prototype = new Error;
|
|
|
|
if (typeof CreateObject === "undefined") {
|
|
var CreateObject = function(progId, serverName, callback) {
|
|
var progIds = (progId instanceof Array ? progId : [progId]);
|
|
|
|
for (var i = 0; i < progIds.length; i++) {
|
|
try {
|
|
var obj = CreateObject.make(progIds[i], serverName);
|
|
if (typeof callback === "function") {
|
|
callback(obj, progIds[i]);
|
|
}
|
|
return obj;
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
};
|
|
}
|
|
};
|
|
CreateObject.make = function(p, s) {
|
|
if (typeof WScript !== "undefined") {
|
|
if ("CreateObject" in WScript) {
|
|
return WScript.CreateObject(p, s);
|
|
} else {
|
|
console.warn("(Chakra) The standalone engine does not supported. Please use the built-in engine.");
|
|
console.warn("(Chakra) hint:", "cscript //NoLogo //E:{1b7cd997-e5ff-4932-a7a6-2a9e636da385} app.js <filename> <...arguments>");
|
|
throw new Error("Could not find a loader");
|
|
}
|
|
} else if (typeof ActiveXObject !== "undefined") {
|
|
return new ActiveXObject(p);
|
|
} else {
|
|
throw new Error("Could not find a loader");
|
|
}
|
|
};
|
|
}
|
|
|
|
if (typeof UseObject === "undefined") {
|
|
var UseObject = function(progId, callback, dispose, fallback) {
|
|
if (typeof callback !== "function") {
|
|
return null;
|
|
}
|
|
|
|
if (typeof dispose !== "function") {
|
|
dispose = function(obj) {
|
|
try {
|
|
obj.Close();
|
|
} catch (e) { /* ignore */ }
|
|
};
|
|
}
|
|
|
|
var obj = CreateObject(progId);
|
|
try {
|
|
return callback(obj);
|
|
} catch (e) {
|
|
return (typeof fallback === "function" ?
|
|
fallback(obj, e) : null);
|
|
} finally {
|
|
dispose(obj);
|
|
obj = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @FN {string} The name of the file.
|
|
*/
|
|
function __evalFile__(FN) {
|
|
try {
|
|
return eval(require._load(FN));
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @f {Function} a function object
|
|
* @name {string} a name of the exported function
|
|
*/
|
|
function __export__(f, name) {
|
|
if (typeof f !== "function")
|
|
return f;
|
|
|
|
name = (name == null) ? "" : String(name);
|
|
|
|
if (!name)
|
|
name = "(exported)";
|
|
|
|
try {
|
|
f.__name__ = name;
|
|
} catch (e) {}
|
|
|
|
try {
|
|
f.name = name;
|
|
} catch (e) {}
|
|
|
|
var wrapped = function () {
|
|
try {
|
|
return f.apply(this, arguments);
|
|
} catch (e) {
|
|
if (typeof TraceError === "function") {
|
|
throw new TraceError(
|
|
"ERROR",
|
|
(e && (e.message || e.description)) ? (e.message || e.description) : "error",
|
|
arguments.callee
|
|
);
|
|
}
|
|
}
|
|
};
|
|
|
|
wrapped.__name__ = name;
|
|
wrapped.__target__ = f;
|
|
|
|
return wrapped;
|
|
}
|
|
|
|
/**
|
|
* @FN {string} The name of the file.
|
|
*/
|
|
function require(pathname) {
|
|
var cache = require._cache = require._cache || {};
|
|
var suffix = (function(pos, s) {
|
|
return pos < 0 ? '.' : s.substring(pos);
|
|
})(pathname.lastIndexOf('.'), pathname);
|
|
var FN = pathname;
|
|
|
|
if ('.js$.jse$.coffee$.ls$.ts$.re$.res$.enc$'.indexOf(suffix + '$') < 0) FN += ".js";
|
|
if (cache[FN]) return cache[FN];
|
|
|
|
var T = null;
|
|
var sep = '://', pos = FN.indexOf(sep);
|
|
if (pos > -1) {
|
|
var scheme = FN.substring(0, pos);
|
|
|
|
// request a script from a remote server
|
|
if (["http", "https"].indexOf(scheme) > -1) {
|
|
require._addScriptProvider(function(url) {
|
|
try {
|
|
return require("lib/http").get(url);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
// request a script from LLM based AI services
|
|
if (["ai"].indexOf(scheme) > -1) {
|
|
require._addScriptProvider(function(url) {
|
|
try {
|
|
var text = url.substring(pos + sep.length);
|
|
return require("lib/language-inference-engine")
|
|
.create()
|
|
.setProvider("openai")
|
|
.inference(text, 0)
|
|
.join(' ')
|
|
;
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
// if exists the custom script providers
|
|
if (require._scriptProviders.length > 0) {
|
|
var i = 0;
|
|
while (T == null && i < require._scriptProviders.length) {
|
|
try {
|
|
T = require._scriptProviders[i](FN) || null;
|
|
break;
|
|
} catch (e) {
|
|
T = null;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
} else {
|
|
// load script from a local server
|
|
var _filename = (function(fs, path) {
|
|
var filepaths = [
|
|
FN, // default
|
|
path.join(pathname, "index.js"), // default
|
|
path.join(FN + '.enc'), // default (encrypted)
|
|
path.join(pathname, 'index.js.enc'), // default (encrypted)
|
|
path.join("Scripts", FN), // NuGet
|
|
path.join("Scripts", pathname, "index.js"), // NuGet
|
|
path.join("bower_components", FN), // Bower
|
|
path.join("bower_components", pathname, "index.js"), // Bower
|
|
path.join("node_modules", FN), // NPM
|
|
path.join("node_modules", pathname, "index.js"), // NPM
|
|
];
|
|
var filename = filepaths[0];
|
|
|
|
var i = 0;
|
|
while (!fs.existsSync(filename) && i < filepaths.length) {
|
|
filename = filepaths[i];
|
|
i++;
|
|
}
|
|
|
|
return filename;
|
|
})({
|
|
existsSync: function(filename) {
|
|
return UseObject("Scripting.FileSystemObject", function(fso) {
|
|
return fso.FileExists(require._getCurrentScriptDirectory() + "\\" + filename);
|
|
});
|
|
}
|
|
}, {
|
|
join: function() {
|
|
var result = arguments[0];
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
result += "\\" + arguments[i];
|
|
}
|
|
return result;
|
|
}
|
|
});
|
|
var _dirname = (function(dirname) {
|
|
var currentScriptDirectory = require._getCurrentScriptDirectory();
|
|
return dirname.length > 0 ? currentScriptDirectory + "\\" + dirname : currentScriptDirectory;
|
|
})(require._getDirName(_filename));
|
|
T = require._load(_filename);
|
|
|
|
// check the suffix again
|
|
suffix = (function(pos, s) {
|
|
return pos < 0 ? '.' : s.substring(pos);
|
|
})(_filename.lastIndexOf('.'), _filename);
|
|
}
|
|
|
|
// transpile
|
|
switch (suffix) {
|
|
case '.coffee': // CoffeeScript 2
|
|
T = require._msie9("app/assets/js/coffeescript-legacy-2.7.0.min", [T], function(p, w, d, l) {
|
|
return w.CoffeeScript.compile(p[0], {
|
|
"header": true,
|
|
"sourceMap": false,
|
|
"bare": true
|
|
});
|
|
});
|
|
break;
|
|
|
|
case ".ls": // LiveScript
|
|
T = require._msie9("app/assets/js/livescript-1.6.1.min", [T, "app/assets/ls/prelude.ls"], function(p, w, d, l) {
|
|
return w.require("livescript").compile(require._load(p[1]) + "\n\n" + p[0], {
|
|
"header": true,
|
|
"bare": true
|
|
});
|
|
});
|
|
break;
|
|
|
|
case ".ts": // TypeScript
|
|
T = require._modernie("app/assets/js/typescript-4.9.4", [T], function(p, w, d, l) {
|
|
return w.ts.transpile(p[0]);
|
|
});
|
|
break;
|
|
|
|
case ".re": // Rescript (aka. BuckleScript, ReasonML)
|
|
case ".res":
|
|
T = require._modernie("app/assets/js/rescript-compiler-10.1.2", [T], function(p, w, d, l) {
|
|
var compiler = w.rescript_compiler.make();
|
|
var result = compiler.rescript.compile(p[0]);
|
|
return result.js_code;
|
|
});
|
|
break;
|
|
|
|
case ".enc": // encrypted script (require WelsonJS.Toolkit)
|
|
T = (function(data, o) {
|
|
try {
|
|
var s = '', i = 0, k = 6;
|
|
while (i < k && (s.length == 0 || s.length > 16)) {
|
|
if (i > 0) {
|
|
console.error("Invalid key length");
|
|
}
|
|
s = o.Prompt("This file has been encrypted. Please enter the password:");
|
|
i++;
|
|
}
|
|
if (i == k) return '';
|
|
return o.DecryptString(s, data);
|
|
} catch (e) {
|
|
console.error("Failed to load the encrypted data:", e.message);
|
|
return '';
|
|
}
|
|
})(T, CreateObject("WelsonJS.Toolkit"));
|
|
break;
|
|
}
|
|
|
|
// compile
|
|
T = "(function(global){var module=new require.__Module__();return(function(exports,require,module,__filename,__dirname){"
|
|
+ '"use strict";'
|
|
+ T
|
|
+ "\n\nreturn module.exports})(module.exports,global.require,module,_filename,_dirname)})(require._global);\n\n////@ sourceURL="
|
|
+ FN
|
|
;
|
|
|
|
// execute
|
|
try {
|
|
cache[FN] = eval(T);
|
|
} catch (e) {
|
|
console.error("PARSE ERROR!", e.number + ",", e.description + ",", "FN=" + FN);
|
|
}
|
|
|
|
// print VERSIONINFO and AUTHOR
|
|
if (typeof cache[FN] === "object") {
|
|
if ("VERSIONINFO" in cache[FN]) {
|
|
if ("AUTHOR" in cache[FN]) {
|
|
console.log(cache[FN].VERSIONINFO + " by " + cache[FN].AUTHOR);
|
|
} else {
|
|
console.log(cache[FN].VERSIONINFO);
|
|
}
|
|
}
|
|
}
|
|
|
|
return cache[FN];
|
|
}
|
|
require.__Module__ = function() {
|
|
this.exports = {};
|
|
};
|
|
require._global = this;
|
|
require._getDirName = function(path) {
|
|
var pos = Math.max.apply(null, [path.lastIndexOf("\\"), path.lastIndexOf("/")]);
|
|
return (pos > -1 ? path.substring(0, pos) : "");
|
|
};
|
|
require._getCurrentScriptDirectory = function() {
|
|
try {
|
|
if (typeof WScript !== "undefined") {
|
|
if ("ScriptFullName" in WScript) {
|
|
return require._getDirName(WScript.ScriptFullName);
|
|
} else {
|
|
throw new Error("No detected an absolute path.");
|
|
}
|
|
} else if (typeof document !== "undefined") {
|
|
return require._getDirName(document.location.pathname);
|
|
} else {
|
|
throw new Error("No detected an absolute path.");
|
|
}
|
|
} catch (e) {
|
|
console.warn(e.message, "Use the relative path.");
|
|
}
|
|
|
|
return ".";
|
|
};
|
|
require._load = function(FN) {
|
|
// if empty
|
|
if (FN == '') return '';
|
|
|
|
// get filename
|
|
var _filename = require._getCurrentScriptDirectory() + "\\" + FN;
|
|
|
|
// load script file
|
|
// use ADODB.Stream instead of Scripting.FileSystemObject, because of supporting UTF-8 (Unicode)
|
|
var objStream = CreateObject("ADODB.Stream");
|
|
var T = null;
|
|
try {
|
|
objStream.charSet = "utf-8";
|
|
objStream.open();
|
|
objStream.loadFromFile(_filename);
|
|
T = objStream.readText();
|
|
objStream.close();
|
|
} catch (e) {
|
|
console.error("LOAD ERROR!", e.number + ",", e.description + ",", "FN=" + FN);
|
|
return;
|
|
}
|
|
|
|
return T;
|
|
};
|
|
require._msie9 = function(FN, params, callback) {
|
|
if (typeof FN !== "string" || FN == null) FN = '';
|
|
else if (FN.substring(FN.length - 3) !== '.js') FN += ".js";
|
|
|
|
var exports = null;
|
|
try {
|
|
var T = require._load("app/assets/js/core-js-3.26.1.minified.js")
|
|
+ "\n\n" + require._load("app/assets/js/html5shiv-printshiv-3.7.3.min.js")
|
|
+ "\n\n" + require._load("app/assets/js/modernizr-2.8.3.min.js")
|
|
+ "\n\n" + require._load(FN);
|
|
var htmlfile = CreateObject("htmlfile");
|
|
htmlfile.write('<meta http-equiv="X-UA-Compatible" content="IE=9">');
|
|
htmlfile.write('<script type="text/javascript">//<!--<![CDATA[\n' + T + '\n//]]>--></script>');
|
|
if (typeof callback === "function") {
|
|
var loadScript = function(FN) {
|
|
if (FN.indexOf('://') > -1) {
|
|
htmlfile.write('<script type="text/javascript" src="' + FN + '"></script>');
|
|
} else {
|
|
htmlfile.write('<script type="text/javascript">//<!--<![CDATA[\n' + require._load(FN) + '\n//]]>--></script>');
|
|
}
|
|
};
|
|
//console.log(htmlfile.parentWindow.navigator.userAgent);
|
|
exports = callback(params, htmlfile.parentWindow, htmlfile.parentWindow.document, loadScript);
|
|
}
|
|
htmlfile.close();
|
|
} catch (e) {
|
|
console.error("LOAD ERROR!", e.number + ",", e.description + ",", "FN=" + FN);
|
|
}
|
|
|
|
return exports;
|
|
};
|
|
require._modernie = function(FN, params, callback) {
|
|
if (typeof FN !== "string" || FN == null) FN = '';
|
|
else if (FN.substring(FN.length - 3) !== '.js') FN += ".js";
|
|
|
|
var exports = null;
|
|
try {
|
|
var ua = '', T = '', htmlfile = CreateObject("htmlfile");
|
|
|
|
htmlfile.write('<meta http-equiv="X-UA-Compatible" content="IE=edge">');
|
|
htmlfile.write('<script type="text/javascript">//<!--<![CDATA[\n\nfunction __getUserAgent(){return window.navigator.userAgent}\n\n//]]>--></script>');
|
|
ua = htmlfile.parentWindow.__getUserAgent();
|
|
|
|
if (ua.indexOf('Trident/ ')) {
|
|
T = require._load("app/assets/js/core-js-3.26.1.minified.js")
|
|
+ "\n\n" + require._load("app/assets/js/modernizr-2.8.3.min.js")
|
|
+ "\n\n" + require._load("app/assets/js/babel-standalone-7.20.6.min.js")
|
|
+ "\n\n" + require._load(FN);
|
|
} else {
|
|
T = require._load("app/assets/js/core-js-3.26.1.minified.js")
|
|
+ "\n\n" + require._load("app/assets/js/html5shiv-printshiv-3.7.3.min.js")
|
|
+ "\n\n" + require._load("app/assets/js/modernizr-2.8.3.min.js")
|
|
+ "\n\n" + require._load(FN);
|
|
}
|
|
htmlfile.write('<script type="text/javascript">//<!--<![CDATA[\n' + T + '\n//]]>--></script>');
|
|
|
|
if (typeof callback === "function") {
|
|
var loadScript = function(src) {
|
|
if (src.indexOf('://') > -1) {
|
|
htmlfile.write('<script type="text/javascript" src="' + src + '"></script>');
|
|
} else {
|
|
htmlfile.write('<script type="text/javascript">//<!--<![CDATA[\n' + require._load(src) + '\n//]]>--></script>');
|
|
}
|
|
};
|
|
//console.log(htmlfile.parentWindow.navigator.userAgent);
|
|
exports = callback(params, htmlfile.parentWindow, htmlfile.parentWindow.document, loadScript);
|
|
}
|
|
htmlfile.close();
|
|
} catch (e) {
|
|
console.error("LOAD ERROR!", e.number + ",", e.description + ",", "FN=" + FN);
|
|
}
|
|
|
|
return exports;
|
|
};
|
|
require._scriptProviders = [];
|
|
require._addScriptProvider = function(f) {
|
|
if (typeof f === "function") {
|
|
require._scriptProviders.push(f);
|
|
} else {
|
|
console.error("This is not an function");
|
|
}
|
|
};
|
|
|
|
// Load script, and call app.main()
|
|
function initializeConsole() {
|
|
if (typeof WScript === "undefined") {
|
|
console.error("This is not a console application");
|
|
return;
|
|
}
|
|
|
|
var args = (function(acc, length) {
|
|
for (var i = 0; i < length; i++)
|
|
acc.push(WScript.arguments(i));
|
|
return acc;
|
|
})([], WScript.arguments.length);
|
|
|
|
if (args.length > 0) {
|
|
var name = args.shift();
|
|
var app = require(name);
|
|
if (app) {
|
|
if (app.main) {
|
|
var status = app.main.call(this, args);
|
|
if (typeof status !== "undefined") {
|
|
exit(status);
|
|
}
|
|
} else {
|
|
console.error("Error, missing main entry point in", name);
|
|
}
|
|
} else {
|
|
console.error("Error, cannot find", name);
|
|
}
|
|
}
|
|
}
|
|
|
|
function initializeWindow(name, args, w, h) {
|
|
if (typeof window === "undefined") {
|
|
console.error("This is not a GUI application");
|
|
return;
|
|
}
|
|
var app = require(name);
|
|
|
|
// set default size of window
|
|
if (typeof w !== "undefined" && typeof h !== "undefined") {
|
|
window.resizeTo(w, h);
|
|
}
|
|
|
|
// load the application
|
|
if (app) {
|
|
if (app.main) {
|
|
var status = app.main.call(app, args);
|
|
if (status > 0) {
|
|
exit(status);
|
|
}
|
|
} else {
|
|
console.error("Missing main entry point in", name + ".js");
|
|
return;
|
|
}
|
|
} else {
|
|
console.error("Could not find", name + ".js");
|
|
return;
|
|
}
|
|
}
|
|
|
|
function dispatchServiceEvent(name, eventType, w_args, argl) {
|
|
var app = require(name);
|
|
var args = (function(acc, length) {
|
|
for (var i = 0; i < argl; i++)
|
|
acc.push(w_args(i));
|
|
return acc;
|
|
})([], argl);
|
|
|
|
if (app) {
|
|
var bind = function(eventType) {
|
|
var event_callback_name = "on" + eventType;
|
|
|
|
if (event_callback_name in app && typeof app[event_callback_name] === "function")
|
|
return app[event_callback_name];
|
|
|
|
return null;
|
|
};
|
|
|
|
return (function(action) {
|
|
if (eventType in action) {
|
|
try {
|
|
return (function(f) {
|
|
return (typeof f !== "function" ? null : f(args));
|
|
})(action[eventType]);
|
|
} catch (e) {
|
|
console.error("Exception:", e.message);
|
|
}
|
|
}
|
|
})({
|
|
start: bind("ServiceStart"),
|
|
stop: bind("ServiceStop"),
|
|
elapsedTime: bind("ServiceElapsedTime"),
|
|
screenNextTemplate: bind("ScreenNextTemplate"),
|
|
screenTemplateMatched: bind("ScreenTemplateMatched"),
|
|
fileCreated: bind("FileCreated"),
|
|
networkConnected: bind("NetworkConnected"),
|
|
registryModified: bind("RegistryModified"),
|
|
avScanResult: bind("AvScanResult")
|
|
});
|
|
} else {
|
|
console.error("Could not find", name + ".js");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Date.prototype.toISOString() polyfill for MSScriptControl.ScriptControl
|
|
if (!Date.prototype.toISOString) {
|
|
Date.prototype.toISOString = function() {
|
|
var pad = function(number) {
|
|
return number < 10 ? ('0' + number) : number;
|
|
};
|
|
return this.getUTCFullYear() +
|
|
'-' + pad(this.getUTCMonth() + 1) +
|
|
'-' + pad(this.getUTCDate()) +
|
|
'T' + pad(this.getUTCHours()) +
|
|
':' + pad(this.getUTCMinutes()) +
|
|
':' + pad(this.getUTCSeconds()) +
|
|
'.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) +
|
|
'Z';
|
|
};
|
|
}
|
|
|
|
// JSON 2
|
|
if (typeof JSON === "undefined") {
|
|
__evalFile__("app/assets/js/json2.js");
|
|
}
|
|
|
|
// core-js (polyfills)
|
|
require("app/assets/js/core-js-3.49.0.wsh");
|
|
|
|
// Squel.js SQL query string builder for Javascript
|
|
var squel = require("app/assets/js/squel-basic-5.13.0-afa1cb5.wsh");
|
|
|
|
// JavaScript YAML parser and dumper.
|
|
var yaml = require("app/assets/js/js-yaml-4.1.0.wsh");
|
|
|
|
// is.js Micro check library
|
|
var is = require("app/assets/js/is-0.9.0.min");
|
|
|
|
// Intl (ECMA-402) polyfill
|
|
//var Intl = require("app/assets/js/Intl-1.2.5-e93b114.min");
|
|
//console.log(new Intl.NumberFormat().format(1234567890.123456));
|
|
|
|
// numbers.js - Advanced Mathematics Library for Node.js and JavaScript
|
|
var numbers = require("app/assets/js/numbers-0.7.0.wsh");
|
|
|
|
// linq.js - LINQ for JavaScript
|
|
var Enumerable = require("app/assets/js/linq-4.0.2.wsh")._default;
|
|
|
|
// PEG.js: Parser generator for JavaScript
|
|
var PEG = require("app/assets/js/peg-0.10.0");
|
|
|
|
// Dive into entrypoint
|
|
function __main__() {
|
|
console.log("");
|
|
console.log(" __ __ _ _ ____ ");
|
|
console.log(" \\ \\ / /__| |___ ___ _ __ | / ___| ");
|
|
console.log(" \\ \\ /\\ / / _ \\ / __|/ _ \\| '_ \\ _ | \\___ \\ ");
|
|
console.log(" \\ V V / __/ \\__ \\ (_) | | | | |_| |___) |");
|
|
console.log(" \\_/\\_/ \\___|_|___/\\___/|_| |_|\\___/|____/ ");
|
|
console.log("");
|
|
console.log(" WelsonJS - Build a Windows app on the Windows built-in JavaScript engine");
|
|
console.log(" C-2021-000237 (cros.or.kr), 10.5281/zenodo.11382385 (doi.org), 2023-A0562 (oss.kr), Codename Macadamia");
|
|
console.log(" This software is distributed as open source under the GPL 3.0 or MS-RL licenses.");
|
|
console.log(" Please support this project: https://github.com/sponsors/gnh1201");
|
|
console.log(" Source code available: https://github.com/gnh1201/welsonjs");
|
|
console.log("");
|
|
|
|
if (typeof window === "undefined") {
|
|
initializeConsole();
|
|
} else {
|
|
console.log("welcome");
|
|
}
|
|
}
|
|
|
|
__main__();
|