2020-06-08 12:17:56 -04:00
|
|
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
|
|
|
|
|
2022-02-10 22:59:29 -05:00
|
|
|
// ensure each app gets a local version-specific copy, not shared
|
2020-05-29 13:16:38 -04:00
|
|
|
function require_fresh(path) {
|
|
|
|
|
const rpa = require.resolve(path);
|
|
|
|
|
delete require.cache[rpa];
|
|
|
|
|
return require(rpa);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const fs = require('fs');
|
2022-01-13 22:48:34 -05:00
|
|
|
const uglify = require('uglify-js');
|
2020-05-29 13:16:38 -04:00
|
|
|
const moment = require('moment');
|
|
|
|
|
const agent = require('express-useragent');
|
2021-12-27 10:14:21 -05:00
|
|
|
const license = require_fresh('./src/moto/license.js');
|
2020-05-30 20:39:56 -04:00
|
|
|
const version = license.VERSION || "rogue";
|
2020-05-29 13:16:38 -04:00
|
|
|
|
|
|
|
|
const fileCache = {};
|
|
|
|
|
const code_src = {};
|
|
|
|
|
const code = {};
|
|
|
|
|
const mods = {};
|
|
|
|
|
const load = [];
|
2020-06-03 22:39:30 -04:00
|
|
|
const synth = {};
|
2020-06-04 00:15:48 -04:00
|
|
|
const api = {};
|
2020-05-29 13:16:38 -04:00
|
|
|
|
2020-12-13 09:55:30 -05:00
|
|
|
let setupFn;
|
2020-05-30 18:16:40 -04:00
|
|
|
let cacheDir;
|
2020-05-29 13:16:38 -04:00
|
|
|
let startTime;
|
2021-01-26 09:03:02 -05:00
|
|
|
let oversion;
|
2022-02-04 15:31:45 -05:00
|
|
|
let dversion;
|
2020-05-29 13:16:38 -04:00
|
|
|
let lastmod;
|
|
|
|
|
let logger;
|
|
|
|
|
let debug;
|
2020-05-30 18:16:40 -04:00
|
|
|
let http;
|
2020-05-29 13:16:38 -04:00
|
|
|
let util;
|
|
|
|
|
let dir;
|
2020-05-30 18:16:40 -04:00
|
|
|
let log;
|
2020-05-29 13:16:38 -04:00
|
|
|
|
2022-02-10 22:59:29 -05:00
|
|
|
const EventEmitter = require('events');
|
|
|
|
|
class AppEmitter extends EventEmitter {}
|
|
|
|
|
const events = new AppEmitter();
|
|
|
|
|
|
2020-05-29 13:16:38 -04:00
|
|
|
function init(mod) {
|
|
|
|
|
startTime = time();
|
|
|
|
|
lastmod = mod.util.lastmod;
|
|
|
|
|
logger = mod.log;
|
2020-05-30 18:16:40 -04:00
|
|
|
debug = mod.env.debug || mod.meta.debug;
|
|
|
|
|
http = mod.http;
|
2020-05-29 13:16:38 -04:00
|
|
|
util = mod.util;
|
|
|
|
|
dir = mod.dir;
|
2020-05-30 18:16:40 -04:00
|
|
|
log = mod.log;
|
2020-07-05 20:14:52 -04:00
|
|
|
|
2022-02-04 15:31:45 -05:00
|
|
|
dversion = debug ? `_${version}` : version;
|
2020-05-30 18:16:40 -04:00
|
|
|
cacheDir = mod.util.datadir("cache");
|
2020-05-29 13:16:38 -04:00
|
|
|
|
2021-12-29 10:37:17 -05:00
|
|
|
let depcache = {};
|
|
|
|
|
|
2021-12-30 22:59:46 -05:00
|
|
|
function find_deps(path, seen = []) {
|
2021-12-29 10:37:17 -05:00
|
|
|
let cached = depcache[path];
|
|
|
|
|
if (cached) {
|
|
|
|
|
return cached;
|
|
|
|
|
}
|
2021-12-30 22:59:46 -05:00
|
|
|
if (seen.indexOf(path) >= 0) {
|
2022-01-27 12:42:06 -05:00
|
|
|
if (debug > 1) {
|
2021-12-30 22:59:46 -05:00
|
|
|
console.log(`circular dependency at ${path}`, seen);
|
|
|
|
|
}
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
seen.push(path);
|
2021-12-29 16:31:17 -05:00
|
|
|
let deps = [ "main/gapp" ];
|
2021-12-29 10:37:17 -05:00
|
|
|
let lines = fs.readFileSync(`${dir}/src/${path}.js`)
|
|
|
|
|
.toString()
|
|
|
|
|
.split('\n');
|
|
|
|
|
for (let line of lines) {
|
|
|
|
|
let dpos = line.indexOf('// dep:');
|
|
|
|
|
if (dpos >= 0) {
|
|
|
|
|
let dep = line.substring(dpos+7).trim().replace('.','/');
|
|
|
|
|
if (deps.indexOf(dep) < 0) {
|
|
|
|
|
deps.push(dep);
|
|
|
|
|
}
|
2021-12-30 22:59:46 -05:00
|
|
|
let deep = find_deps(dep, seen);
|
2021-12-29 16:31:17 -05:00
|
|
|
deps = deps.filter(p => deep.indexOf(p) < 0);
|
|
|
|
|
// deeper dependencies go first
|
|
|
|
|
deps = [...deep, ...deps];
|
2021-12-29 10:37:17 -05:00
|
|
|
}
|
|
|
|
|
}
|
2021-12-29 16:31:17 -05:00
|
|
|
depcache[path] = deps;
|
|
|
|
|
return deps;
|
2021-12-29 10:37:17 -05:00
|
|
|
}
|
|
|
|
|
|
2021-12-29 08:10:51 -05:00
|
|
|
// process script dependencies, expand paths
|
|
|
|
|
for (let [key,val] of Object.entries(script)) {
|
2021-12-29 10:37:17 -05:00
|
|
|
let nval = val.map(p => p.charAt(0) === '&' ? p.substring(1) : p);
|
|
|
|
|
let modd = false;
|
2021-12-29 08:10:51 -05:00
|
|
|
for (let path of val) {
|
2021-12-29 10:37:17 -05:00
|
|
|
let fc = path.charAt(0);
|
|
|
|
|
if (fc === '@') {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (fc === '&') {
|
|
|
|
|
path = path.substring(1);
|
|
|
|
|
} else {
|
2021-12-29 08:10:51 -05:00
|
|
|
continue;
|
|
|
|
|
}
|
2021-12-29 10:37:17 -05:00
|
|
|
let deps = find_deps(path);
|
|
|
|
|
if (deps) {
|
|
|
|
|
// remove deps already in list
|
|
|
|
|
deps = deps.filter(p => nval.indexOf(p) < 0);
|
|
|
|
|
let ppos = nval.indexOf(path);
|
|
|
|
|
if (ppos < 0) {
|
|
|
|
|
throw `missing ${path} in nval`;
|
2021-12-29 08:10:51 -05:00
|
|
|
}
|
2021-12-29 10:37:17 -05:00
|
|
|
// inject deps
|
|
|
|
|
nval.splice(ppos,0,...deps);
|
|
|
|
|
modd = true;
|
|
|
|
|
}
|
|
|
|
|
// if list is modified, substitute
|
|
|
|
|
if (modd) {
|
2022-01-27 12:42:06 -05:00
|
|
|
if (debug > 1) {
|
2021-12-29 10:37:17 -05:00
|
|
|
console.log({path, val, nval});
|
|
|
|
|
}
|
|
|
|
|
val = nval;
|
2021-12-29 08:10:51 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
script[key] = val.map(p => p.charAt(0) !== '@' ? `src/${p}.js` : p);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-30 18:16:40 -04:00
|
|
|
mod.on.test((req) => {
|
2020-06-12 11:51:02 -04:00
|
|
|
let cookie = cookieValue(req.headers.cookie, "version") || undefined;
|
2020-11-20 09:46:10 -05:00
|
|
|
let vmatch = mod.meta.version || "*";
|
|
|
|
|
if (!Array.isArray(vmatch)) {
|
|
|
|
|
vmatch = [ vmatch ];
|
|
|
|
|
}
|
|
|
|
|
if (vmatch.indexOf("*") >= 0) {
|
|
|
|
|
return true;
|
2020-05-30 18:16:40 -04:00
|
|
|
}
|
2020-11-20 09:46:10 -05:00
|
|
|
return vmatch.indexOf(cookie) >= 0;
|
2020-05-30 18:16:40 -04:00
|
|
|
});
|
2020-05-29 13:16:38 -04:00
|
|
|
|
2020-12-13 09:55:30 -05:00
|
|
|
mod.add(handleSetup);
|
2020-05-29 13:16:38 -04:00
|
|
|
mod.add(handleOptions);
|
|
|
|
|
mod.add(fullpath({
|
2020-05-30 21:26:01 -04:00
|
|
|
"/kiri" : redir("/kiri/", 301),
|
2021-12-16 19:11:52 -05:00
|
|
|
"/mesh" : redir("/mesh/", 301),
|
2020-05-30 21:26:01 -04:00
|
|
|
"/meta" : redir("/meta/", 301),
|
|
|
|
|
"/kiri/index.html" : redir("/kiri/", 301),
|
2021-12-16 19:11:52 -05:00
|
|
|
"/mesh/index.html" : redir("/mesh/", 301),
|
2020-05-30 21:26:01 -04:00
|
|
|
"/meta/index.html" : redir("/meta/", 301)
|
2020-05-29 13:16:38 -04:00
|
|
|
}));
|
2020-05-30 20:39:56 -04:00
|
|
|
mod.add(handleVersion);
|
2020-05-29 13:16:38 -04:00
|
|
|
mod.add(prepath([
|
|
|
|
|
[ "/code/", handleCode ],
|
|
|
|
|
[ "/wasm/", handleWasm ]
|
|
|
|
|
]));
|
|
|
|
|
mod.add(fixedmap("/api/", api));
|
|
|
|
|
if (debug) {
|
|
|
|
|
mod.static("/mod/", "mod");
|
2020-05-30 18:16:40 -04:00
|
|
|
mod.sync("/reload", () => {
|
|
|
|
|
mod.reload();
|
|
|
|
|
return "reload";
|
|
|
|
|
});
|
2020-05-29 13:16:38 -04:00
|
|
|
}
|
2020-05-30 21:26:01 -04:00
|
|
|
mod.add(rewriteHtmlVersion);
|
2021-09-01 13:50:28 -04:00
|
|
|
mod.static("/src/", "src");
|
2020-05-29 13:16:38 -04:00
|
|
|
mod.static("/obj/", "web/obj");
|
2021-12-16 19:11:52 -05:00
|
|
|
mod.static("/font/", "web/font");
|
|
|
|
|
mod.static("/mesh/", "web/mesh");
|
2020-05-29 13:16:38 -04:00
|
|
|
mod.static("/moto/", "web/moto");
|
2020-05-30 21:26:01 -04:00
|
|
|
mod.static("/meta/", "web/meta");
|
2020-05-29 13:16:38 -04:00
|
|
|
mod.static("/kiri/", "web/kiri");
|
|
|
|
|
|
|
|
|
|
// load modules
|
|
|
|
|
lastmod(`${dir}/mod`) && fs.readdirSync(`${dir}/mod`).forEach(dir => {
|
|
|
|
|
const modpath = `mod/${dir}`;
|
|
|
|
|
if (dir.charAt(0) === '.') return;
|
|
|
|
|
const stats = fs.lstatSync(`${mod.dir}/${modpath}`);
|
|
|
|
|
if (!(stats.isDirectory() || stats.isSymbolicLink())) return;
|
|
|
|
|
loadModule(mod, modpath);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// run loads injected by modules
|
|
|
|
|
while (load.length) {
|
|
|
|
|
try {
|
|
|
|
|
load.shift()();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
logger.log({on_load_fail: e});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// runs after module loads / injects
|
|
|
|
|
prepareScripts();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// either add module assets to path or require(init.js)
|
|
|
|
|
function loadModule(mod, dir) {
|
|
|
|
|
if (dir.indexOf('node_modules') >= 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (lastmod(`${mod.dir}/${dir}/.ignore`)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
lastmod(`${mod.dir}/${dir}/init.js`) ?
|
|
|
|
|
initModule(mod, `./${dir}/init.js`, dir) :
|
|
|
|
|
mod.static("/", `${mod.dir}/${dir}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// load module and call returned function with helper object
|
|
|
|
|
function initModule(mod, file, dir) {
|
|
|
|
|
logger.log({module: file});
|
|
|
|
|
require_fresh(file)({
|
2022-02-10 22:59:29 -05:00
|
|
|
// express functions added here show up at "/api/" url root
|
2020-05-29 13:16:38 -04:00
|
|
|
api: api,
|
|
|
|
|
adm: {
|
2021-01-26 09:03:02 -05:00
|
|
|
reload: prepareScripts,
|
|
|
|
|
setver: (ver) => { oversion = ver }
|
2020-05-29 13:16:38 -04:00
|
|
|
},
|
2022-02-10 22:59:29 -05:00
|
|
|
events,
|
2020-05-29 13:16:38 -04:00
|
|
|
const: {
|
|
|
|
|
args: {},
|
2020-06-04 00:31:59 -04:00
|
|
|
meta: mod.meta,
|
2020-05-29 13:16:38 -04:00
|
|
|
debug: debug,
|
|
|
|
|
script: script,
|
|
|
|
|
moddir: dir,
|
|
|
|
|
rootdir: mod.dir,
|
2020-05-30 20:39:56 -04:00
|
|
|
version: version
|
2020-05-29 13:16:38 -04:00
|
|
|
},
|
2020-07-06 18:36:57 -04:00
|
|
|
env: mod.env,
|
2020-05-29 13:16:38 -04:00
|
|
|
pkg: {
|
|
|
|
|
agent,
|
|
|
|
|
moment
|
|
|
|
|
},
|
|
|
|
|
mod: mods,
|
|
|
|
|
util: {
|
|
|
|
|
log: logger.log,
|
|
|
|
|
time: time,
|
|
|
|
|
guid: guid,
|
2020-05-30 18:16:40 -04:00
|
|
|
mkdirs: util.mkdir,
|
2021-03-08 21:57:28 -05:00
|
|
|
isfile: util.isfile,
|
|
|
|
|
confdir: util.confdir,
|
2020-05-30 18:16:40 -04:00
|
|
|
datadir: util.datadir,
|
2020-05-29 13:16:38 -04:00
|
|
|
lastmod: lastmod,
|
|
|
|
|
obj2string: obj2string,
|
|
|
|
|
string2obj: string2obj,
|
|
|
|
|
getCookieValue: cookieValue,
|
2020-05-30 18:16:40 -04:00
|
|
|
logger: log.new
|
2020-05-29 13:16:38 -04:00
|
|
|
},
|
2022-02-17 15:04:36 -05:00
|
|
|
inject: (code, file, opt = {}) => {
|
|
|
|
|
let codelist = script[code];
|
|
|
|
|
if (!codelist) {
|
2020-05-29 13:16:38 -04:00
|
|
|
return logger.log(`inject missing target "${code}"`);
|
|
|
|
|
}
|
2020-11-17 14:18:09 -05:00
|
|
|
const path = `${dir}/${file}`;
|
2020-05-29 13:16:38 -04:00
|
|
|
if (opt.end) {
|
2022-02-17 15:04:36 -05:00
|
|
|
codelist.push(path);
|
2020-05-29 13:16:38 -04:00
|
|
|
} else {
|
2022-02-17 15:04:36 -05:00
|
|
|
let io = Math.max(0, codelist.indexOf('@inject'));
|
|
|
|
|
codelist.splice(io, 0, path);
|
2020-11-17 14:18:09 -05:00
|
|
|
}
|
2020-11-17 15:49:41 -05:00
|
|
|
if (opt.cachever) {
|
|
|
|
|
cachever[path] = opt.cachever;
|
2020-05-29 13:16:38 -04:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
path: {
|
|
|
|
|
any: arg => { mod.add(arg) },
|
|
|
|
|
pre: arg => { mod.add(prepath(arg)) },
|
|
|
|
|
map: arg => { mod.add(fixedmap(arg)) },
|
|
|
|
|
full: arg => { mod.add(fullpath(arg)) },
|
|
|
|
|
static: (root, pre) => {
|
|
|
|
|
mod.static(pre || "/", root);
|
|
|
|
|
},
|
|
|
|
|
code: (endpoint, path) => {
|
|
|
|
|
let fpath = mod.dir + "/" + path;
|
|
|
|
|
if (debug) {
|
|
|
|
|
code[endpoint] = fs.readFileSync(fpath);
|
|
|
|
|
} else {
|
|
|
|
|
code[endpoint] = minify(fpath);
|
|
|
|
|
}
|
|
|
|
|
code_src[endpoint] = {
|
|
|
|
|
endpoint,
|
|
|
|
|
path: path,
|
|
|
|
|
mod: lastmod(fpath)
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
redir: redir,
|
2020-12-13 09:55:30 -05:00
|
|
|
remap: remap,
|
|
|
|
|
setup: fn => { setupFn = fn }
|
2020-05-29 13:16:38 -04:00
|
|
|
},
|
|
|
|
|
handler: {
|
|
|
|
|
addCORS: addCorsHeaders,
|
2020-05-30 18:16:40 -04:00
|
|
|
redirect: http.redirect,
|
|
|
|
|
reply404: http.reply404,
|
2020-05-29 13:16:38 -04:00
|
|
|
reply: quickReply
|
|
|
|
|
},
|
|
|
|
|
ws: {
|
|
|
|
|
register: mod.wss
|
|
|
|
|
},
|
|
|
|
|
onload: (fn) => {
|
|
|
|
|
load.push(fn);
|
|
|
|
|
},
|
|
|
|
|
onexit: (fn) => {
|
|
|
|
|
mod.on.exit(fn);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const script = {
|
|
|
|
|
kiri : [
|
2021-12-29 00:19:22 -05:00
|
|
|
"main/gapp",
|
2021-12-29 10:37:17 -05:00
|
|
|
"moto/license",
|
2021-12-16 19:11:52 -05:00
|
|
|
"main/kiri",
|
2022-02-17 15:04:36 -05:00
|
|
|
"@inject",
|
2020-06-03 22:39:30 -04:00
|
|
|
"ext/three",
|
2021-03-01 22:41:29 -05:00
|
|
|
"ext/three-bgu",
|
2021-10-12 15:53:17 -04:00
|
|
|
"ext/three-svg",
|
2021-08-28 20:35:26 -04:00
|
|
|
"ext/jszip",
|
2021-12-26 22:00:31 -05:00
|
|
|
"ext/clip2",
|
2020-06-03 22:39:30 -04:00
|
|
|
"ext/tween",
|
|
|
|
|
"ext/fsave",
|
2022-01-31 18:20:11 -05:00
|
|
|
// "ext/earcut",
|
2021-02-11 09:23:22 -05:00
|
|
|
"ext/base64",
|
2020-06-03 22:39:30 -04:00
|
|
|
"add/array",
|
|
|
|
|
"add/three",
|
|
|
|
|
"geo/base",
|
|
|
|
|
"geo/point",
|
2020-11-06 10:47:49 -05:00
|
|
|
"geo/points",
|
2020-06-03 22:39:30 -04:00
|
|
|
"geo/slope",
|
|
|
|
|
"geo/line",
|
|
|
|
|
"geo/bounds",
|
|
|
|
|
"geo/polygons",
|
2022-01-31 20:50:19 -05:00
|
|
|
"geo/polygon",
|
2021-09-06 18:10:34 -04:00
|
|
|
"geo/mesh",
|
2021-12-28 16:38:05 -05:00
|
|
|
"data/local",
|
|
|
|
|
"data/index",
|
2020-06-03 22:39:30 -04:00
|
|
|
"moto/ajax",
|
2021-12-28 16:38:05 -05:00
|
|
|
"moto/orbit",
|
2020-06-03 22:39:30 -04:00
|
|
|
"moto/space",
|
2021-12-27 10:14:21 -05:00
|
|
|
"load/3mf",
|
|
|
|
|
"load/obj",
|
|
|
|
|
"load/stl",
|
|
|
|
|
"load/svg",
|
|
|
|
|
"load/url",
|
|
|
|
|
"load/file",
|
2021-12-08 22:09:07 -05:00
|
|
|
"moto/broker",
|
2022-01-24 21:54:50 -05:00
|
|
|
"moto/webui",
|
2022-02-18 18:42:08 -05:00
|
|
|
"kiri/conf",
|
2022-02-17 14:40:51 -05:00
|
|
|
"kiri/consts",
|
|
|
|
|
"kiri/utils",
|
2022-02-19 12:58:17 -05:00
|
|
|
"kiri/stats",
|
2022-02-17 14:40:51 -05:00
|
|
|
"kiri/api",
|
2020-06-05 23:21:53 -04:00
|
|
|
"kiri/ui",
|
2021-10-19 22:23:18 -04:00
|
|
|
"kiri/do",
|
2021-12-28 15:52:28 -05:00
|
|
|
"kiri/pack",
|
2020-06-03 22:39:30 -04:00
|
|
|
"kiri/lang",
|
|
|
|
|
"kiri/lang-en",
|
2022-02-18 11:30:00 -05:00
|
|
|
"kiri/files",
|
2020-06-03 22:39:30 -04:00
|
|
|
"kiri/slice",
|
2020-11-30 22:36:06 -05:00
|
|
|
"kiri/layers",
|
2020-12-14 12:52:08 -05:00
|
|
|
"kiri/client",
|
2021-12-28 16:38:05 -05:00
|
|
|
"kiri-mode/fdm/fill",
|
|
|
|
|
"kiri-mode/fdm/driver",
|
|
|
|
|
"kiri-mode/fdm/client",
|
|
|
|
|
"kiri-mode/sla/driver",
|
|
|
|
|
"kiri-mode/sla/client",
|
|
|
|
|
"kiri-mode/cam/driver",
|
|
|
|
|
"kiri-mode/cam/client",
|
|
|
|
|
"kiri-mode/cam/tool",
|
|
|
|
|
"kiri-mode/cam/animate",
|
|
|
|
|
"kiri-mode/laser/driver",
|
2020-11-30 22:36:06 -05:00
|
|
|
"kiri/stack",
|
2020-11-08 10:55:36 -05:00
|
|
|
"kiri/stacks",
|
2020-06-03 22:39:30 -04:00
|
|
|
"kiri/widget",
|
2022-02-18 13:53:41 -05:00
|
|
|
"kiri/widgets",
|
2022-02-18 18:42:08 -05:00
|
|
|
"kiri/function",
|
2022-02-17 21:52:54 -05:00
|
|
|
"kiri/platform",
|
2022-02-18 13:27:26 -05:00
|
|
|
"kiri/selection",
|
2022-02-18 18:42:08 -05:00
|
|
|
"kiri/settings",
|
2020-06-03 22:39:30 -04:00
|
|
|
"kiri/codec",
|
|
|
|
|
"kiri/main",
|
|
|
|
|
"kiri/init",
|
|
|
|
|
"kiri/export",
|
2021-10-09 10:34:20 -04:00
|
|
|
"kiri/tools",
|
2020-06-04 21:29:40 -04:00
|
|
|
"@devices",
|
|
|
|
|
"@icons"
|
2021-12-26 19:43:48 -05:00
|
|
|
],
|
2021-12-28 15:52:28 -05:00
|
|
|
kiri_work : [
|
2021-12-29 00:19:22 -05:00
|
|
|
"main/gapp",
|
2021-12-29 10:37:17 -05:00
|
|
|
"moto/license",
|
2021-12-16 19:11:52 -05:00
|
|
|
"main/kiri",
|
2022-02-17 15:04:36 -05:00
|
|
|
"@inject",
|
2020-06-03 22:39:30 -04:00
|
|
|
"ext/three",
|
|
|
|
|
"ext/pngjs",
|
2021-02-01 16:39:22 -05:00
|
|
|
"ext/jszip",
|
2020-06-03 22:39:30 -04:00
|
|
|
"ext/clip2",
|
2020-11-06 22:33:56 -05:00
|
|
|
"ext/earcut",
|
2020-06-03 22:39:30 -04:00
|
|
|
"add/array",
|
|
|
|
|
"add/three",
|
|
|
|
|
"add/class",
|
|
|
|
|
"geo/base",
|
2021-07-07 21:09:34 -04:00
|
|
|
"geo/wasm",
|
2022-02-17 00:39:50 -05:00
|
|
|
"geo/paths",
|
2020-06-03 22:39:30 -04:00
|
|
|
"geo/point",
|
2020-11-06 10:47:49 -05:00
|
|
|
"geo/points",
|
2020-06-03 22:39:30 -04:00
|
|
|
"geo/slope",
|
|
|
|
|
"geo/line",
|
|
|
|
|
"geo/bounds",
|
|
|
|
|
"geo/polygons",
|
2022-01-31 20:50:19 -05:00
|
|
|
"geo/polygon",
|
2020-06-03 22:39:30 -04:00
|
|
|
"geo/gyroid",
|
2022-02-16 22:57:12 -05:00
|
|
|
"geo/slicer",
|
2021-09-06 18:10:34 -04:00
|
|
|
"geo/mesh",
|
2021-12-28 15:52:28 -05:00
|
|
|
// "moto/broker",
|
|
|
|
|
"kiri/pack",
|
2022-02-18 12:08:08 -05:00
|
|
|
"kiri/utils",
|
2020-06-03 22:39:30 -04:00
|
|
|
"kiri/slice",
|
2020-11-30 22:36:06 -05:00
|
|
|
"kiri/layers",
|
2021-12-28 16:38:05 -05:00
|
|
|
"kiri-mode/fdm/fill",
|
|
|
|
|
"kiri-mode/fdm/driver",
|
|
|
|
|
"kiri-mode/fdm/slice",
|
|
|
|
|
"kiri-mode/fdm/prepare",
|
|
|
|
|
"kiri-mode/fdm/export",
|
|
|
|
|
"kiri-mode/sla/driver",
|
|
|
|
|
"kiri-mode/sla/slice",
|
|
|
|
|
"kiri-mode/sla/export",
|
|
|
|
|
"kiri-mode/sla/x_cxdlp",
|
|
|
|
|
"kiri-mode/sla/x_photon",
|
2022-01-23 21:15:39 -05:00
|
|
|
"kiri-mode/cam/slicer",
|
2021-12-28 16:38:05 -05:00
|
|
|
"kiri-mode/cam/driver",
|
|
|
|
|
"kiri-mode/cam/ops",
|
|
|
|
|
"kiri-mode/cam/tool",
|
|
|
|
|
"kiri-mode/cam/topo",
|
|
|
|
|
"kiri-mode/cam/slice",
|
|
|
|
|
"kiri-mode/cam/prepare",
|
|
|
|
|
"kiri-mode/cam/export",
|
|
|
|
|
"kiri-mode/cam/animate",
|
|
|
|
|
"kiri-mode/laser/driver",
|
2020-06-03 22:39:30 -04:00
|
|
|
"kiri/widget",
|
|
|
|
|
"kiri/print",
|
2020-06-03 22:59:15 -04:00
|
|
|
"kiri/codec",
|
2020-06-03 22:39:30 -04:00
|
|
|
"kiri/worker"
|
2021-12-26 19:43:48 -05:00
|
|
|
],
|
2021-12-28 15:52:28 -05:00
|
|
|
kiri_pool : [
|
2021-12-29 00:19:22 -05:00
|
|
|
"main/gapp",
|
2021-12-27 10:14:21 -05:00
|
|
|
"moto/license",
|
2021-12-29 10:37:17 -05:00
|
|
|
"main/kiri",
|
2022-02-17 15:04:36 -05:00
|
|
|
"@inject",
|
2021-06-19 22:44:08 -04:00
|
|
|
"ext/clip2",
|
|
|
|
|
"ext/earcut",
|
|
|
|
|
"add/array",
|
|
|
|
|
"add/class",
|
|
|
|
|
"geo/base",
|
2021-07-07 21:09:34 -04:00
|
|
|
"geo/wasm",
|
2021-06-19 22:44:08 -04:00
|
|
|
"geo/point",
|
|
|
|
|
"geo/points",
|
|
|
|
|
"geo/slope",
|
|
|
|
|
"geo/line",
|
|
|
|
|
"geo/bounds",
|
|
|
|
|
"geo/polygons",
|
2022-01-31 20:50:19 -05:00
|
|
|
"geo/polygon",
|
2021-06-19 22:44:08 -04:00
|
|
|
"geo/gyroid",
|
2022-02-16 22:57:12 -05:00
|
|
|
"geo/slicer",
|
2021-12-28 16:38:05 -05:00
|
|
|
"kiri-mode/fdm/driver",
|
|
|
|
|
"kiri-mode/fdm/slice",
|
2022-02-18 12:08:08 -05:00
|
|
|
"kiri/utils",
|
2021-06-19 22:44:08 -04:00
|
|
|
"kiri/slice",
|
|
|
|
|
"kiri/layers",
|
|
|
|
|
"kiri/widget",
|
|
|
|
|
"kiri/codec",
|
|
|
|
|
"kiri/minion"
|
2021-12-26 19:43:48 -05:00
|
|
|
],
|
2020-12-31 23:22:39 -05:00
|
|
|
engine : [
|
2021-12-29 00:19:22 -05:00
|
|
|
"main/gapp",
|
2021-12-27 10:14:21 -05:00
|
|
|
"moto/license",
|
2021-12-29 10:37:17 -05:00
|
|
|
"main/kiri",
|
2022-02-17 15:04:36 -05:00
|
|
|
"@inject",
|
2022-01-31 21:27:39 -05:00
|
|
|
"ext/clip2",
|
2021-12-28 16:38:05 -05:00
|
|
|
"data/local",
|
2020-12-31 23:22:39 -05:00
|
|
|
"ext/three",
|
|
|
|
|
"add/array",
|
|
|
|
|
"add/three",
|
|
|
|
|
"geo/base",
|
|
|
|
|
"geo/point",
|
|
|
|
|
"geo/points",
|
2022-02-18 12:08:08 -05:00
|
|
|
"geo/paths",
|
2020-12-31 23:22:39 -05:00
|
|
|
"geo/slope",
|
|
|
|
|
"geo/line",
|
|
|
|
|
"geo/bounds",
|
|
|
|
|
"geo/polygon",
|
|
|
|
|
"geo/polygons",
|
2021-12-08 22:09:07 -05:00
|
|
|
"moto/broker",
|
2021-12-27 10:14:21 -05:00
|
|
|
"load/obj",
|
|
|
|
|
"load/stl",
|
2020-12-31 23:22:39 -05:00
|
|
|
"kiri/conf",
|
2022-02-18 12:08:08 -05:00
|
|
|
"kiri/utils",
|
2020-12-31 23:22:39 -05:00
|
|
|
"kiri/client",
|
|
|
|
|
"kiri/slice",
|
|
|
|
|
"kiri/layers",
|
|
|
|
|
"kiri/widget",
|
|
|
|
|
"kiri/codec",
|
2021-01-01 11:43:35 -05:00
|
|
|
"kiri/engine"
|
2021-12-26 19:43:48 -05:00
|
|
|
],
|
2021-01-04 20:36:35 -05:00
|
|
|
frame : [
|
2021-12-29 00:19:22 -05:00
|
|
|
"main/gapp",
|
2021-01-04 20:36:35 -05:00
|
|
|
"kiri/frame"
|
2021-12-26 19:43:48 -05:00
|
|
|
],
|
2020-05-30 21:26:01 -04:00
|
|
|
meta : [
|
2021-12-29 00:19:22 -05:00
|
|
|
"main/gapp",
|
2021-12-27 10:14:21 -05:00
|
|
|
"moto/license",
|
2021-12-29 10:37:17 -05:00
|
|
|
"main/meta",
|
2021-12-26 19:43:48 -05:00
|
|
|
],
|
2021-12-16 19:11:52 -05:00
|
|
|
mesh : [
|
2021-12-29 10:37:17 -05:00
|
|
|
"&main/mesh"
|
2021-12-26 19:43:48 -05:00
|
|
|
],
|
|
|
|
|
mesh_work : [
|
2022-01-30 20:24:02 -05:00
|
|
|
"ext/jscad",
|
2021-12-29 10:37:17 -05:00
|
|
|
"&mesh/work"
|
2021-12-27 18:13:11 -05:00
|
|
|
],
|
|
|
|
|
mesh_pool : [
|
2021-12-29 10:37:17 -05:00
|
|
|
"&mesh/pool"
|
2021-12-26 19:43:48 -05:00
|
|
|
]
|
2020-05-29 13:16:38 -04:00
|
|
|
};
|
|
|
|
|
|
2020-11-17 14:18:09 -05:00
|
|
|
// prevent caching of specified modules
|
2020-11-17 15:49:41 -05:00
|
|
|
const cachever = {};
|
2020-11-17 14:18:09 -05:00
|
|
|
|
2020-05-29 13:16:38 -04:00
|
|
|
function promise(resolve, reject) {
|
|
|
|
|
return new Promise(resolve, reject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function rval() {
|
|
|
|
|
return (Math.round(Math.random()*0xffffffff)).toString(36);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function guid() {
|
|
|
|
|
return time().toString(36)+rval()+rval()+rval();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function time() {
|
|
|
|
|
return Date.now();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function obj2string(o) {
|
|
|
|
|
return JSON.stringify(o);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function string2obj(s) {
|
|
|
|
|
return JSON.parse(s);
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-13 09:55:30 -05:00
|
|
|
function handleSetup(req, res, next) {
|
2020-12-13 19:31:35 -05:00
|
|
|
if (setupFn) {
|
|
|
|
|
setupFn(req, res, next);
|
|
|
|
|
} else {
|
|
|
|
|
next();
|
|
|
|
|
}
|
2020-12-13 09:55:30 -05:00
|
|
|
}
|
|
|
|
|
|
2020-05-30 20:39:56 -04:00
|
|
|
function handleVersion(req, res, next) {
|
2022-02-04 15:31:45 -05:00
|
|
|
let vstr = oversion || dversion || version;
|
2021-12-27 20:39:07 -05:00
|
|
|
if (["/kiri/","/mesh/","/meta/"].indexOf(req.app.path) >= 0 && req.url.indexOf(vstr) < 0) {
|
2020-05-30 20:39:56 -04:00
|
|
|
if (req.url.indexOf("?") > 0) {
|
2021-01-26 09:03:02 -05:00
|
|
|
return http.redirect(res, `${req.url},ver:${vstr}`);
|
2020-05-30 20:39:56 -04:00
|
|
|
} else {
|
2021-01-26 09:03:02 -05:00
|
|
|
return http.redirect(res, `${req.url}?ver:${vstr}`);
|
2020-05-30 20:39:56 -04:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-29 13:16:38 -04:00
|
|
|
function handleOptions(req, res, next) {
|
2020-06-02 20:28:48 -04:00
|
|
|
try {
|
|
|
|
|
req.app.ua = agent.parse(req.headers['user-agent'] || '');
|
|
|
|
|
} catch (e) {
|
|
|
|
|
logger.log("ua parse error on : "+req.headers['user-agent']);
|
|
|
|
|
}
|
2020-05-29 13:16:38 -04:00
|
|
|
if (req.method === 'OPTIONS') {
|
|
|
|
|
addCorsHeaders(req, res);
|
|
|
|
|
res.end();
|
|
|
|
|
} else {
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleWasm(req, res, next) {
|
|
|
|
|
let [root, file] = req.app.path.split('/').slice(1);
|
|
|
|
|
let ext = (file || '').split('.')[1];
|
2021-12-16 19:11:52 -05:00
|
|
|
let path = `${dir}/src/wasm/${file}`;
|
2020-05-29 13:16:38 -04:00
|
|
|
let mod = lastmod(path);
|
|
|
|
|
|
|
|
|
|
if (root === 'wasm' && ext === 'wasm' && mod) {
|
|
|
|
|
let imd = ifModifiedDate(req);
|
|
|
|
|
if (imd && mod <= imd) {
|
|
|
|
|
res.writeHead(304, "Not Modified");
|
|
|
|
|
return res.end();
|
|
|
|
|
}
|
|
|
|
|
res.writeHead(200, {
|
|
|
|
|
'Content-Type': 'application/wasm',
|
|
|
|
|
'Cache-Control': 'public, max-age=600',
|
|
|
|
|
'Last-Modified': new Date(mod).toGMTString(),
|
|
|
|
|
});
|
|
|
|
|
res.end(fs.readFileSync(path));
|
|
|
|
|
} else {
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleCode(req, res, next) {
|
|
|
|
|
let key = req.app.path.split('/')[2].split('.')[0],
|
|
|
|
|
ck = code_src[key],
|
|
|
|
|
js = code[key];
|
|
|
|
|
|
|
|
|
|
if (!js) {
|
2020-05-30 18:16:40 -04:00
|
|
|
return http.reply404(req, res);
|
2020-05-29 13:16:38 -04:00
|
|
|
}
|
|
|
|
|
if (ck) {
|
2020-12-11 15:31:22 -05:00
|
|
|
let mpath = `${dir}/${ck.path}`;
|
|
|
|
|
let mod = lastmod(mpath);
|
2020-05-29 13:16:38 -04:00
|
|
|
if (mod > ck.mod) {
|
|
|
|
|
if (debug) {
|
2020-12-11 15:31:22 -05:00
|
|
|
js = code[ck.endpoint] = fs.readFileSync(mpath);
|
2020-05-29 13:16:38 -04:00
|
|
|
} else {
|
2020-12-11 15:31:22 -05:00
|
|
|
js = code[ck.endpoint] = minify(mpath);
|
2020-05-29 13:16:38 -04:00
|
|
|
}
|
|
|
|
|
ck.mod = mod;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addCorsHeaders(req, res);
|
|
|
|
|
serveCode(req, res, {
|
|
|
|
|
code: js,
|
|
|
|
|
mtime: startTime
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function serveCode(req, res, code) {
|
|
|
|
|
if (code.deny) {
|
2020-05-30 18:16:40 -04:00
|
|
|
return http.reply404(req, res);
|
2020-05-29 13:16:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let imd = ifModifiedDate(req);
|
|
|
|
|
if (imd && code.mtime <= imd && !code.nocache) {
|
|
|
|
|
res.writeHead(304, "Not Modified");
|
|
|
|
|
res.end();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let cacheControl = code.nocache ?
|
|
|
|
|
'private, max-age=0' :
|
|
|
|
|
'public, max-age=600';
|
|
|
|
|
|
|
|
|
|
res.writeHead(200, {
|
|
|
|
|
'Content-Type': 'application/javascript',
|
|
|
|
|
'Cache-Control': cacheControl,
|
|
|
|
|
'Last-Modified': new Date(code.mtime).toGMTString(),
|
|
|
|
|
});
|
|
|
|
|
res.end(code.code);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-04 21:29:40 -04:00
|
|
|
function generateIcons() {
|
2021-12-28 16:38:05 -05:00
|
|
|
let root = `${dir}/src/kiri-ico`;
|
2020-06-04 21:29:40 -04:00
|
|
|
let icos = {};
|
|
|
|
|
fs.readdirSync(root).forEach(file => {
|
|
|
|
|
let name = file.split(".")[0] ;
|
|
|
|
|
icos[name] = fs.readFileSync(`${root}/${file}`).toString();
|
|
|
|
|
});
|
|
|
|
|
synth.icons = `self.icons = ${JSON.stringify(icos)};`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function generateDevices() {
|
2021-12-28 16:38:05 -05:00
|
|
|
let root = `${dir}/src/kiri-dev`;
|
2020-06-03 22:39:30 -04:00
|
|
|
let devs = {};
|
|
|
|
|
fs.readdirSync(root).forEach(type => {
|
|
|
|
|
let map = devs[type] = devs[type] || {};
|
|
|
|
|
fs.readdirSync(`${root}/${type}`).forEach(device => {
|
|
|
|
|
map[device] = JSON.parse(fs.readFileSync(`${root}/${type}/${device}`));
|
|
|
|
|
});
|
|
|
|
|
});
|
2020-06-04 21:29:40 -04:00
|
|
|
synth.devices = `self.devices = ${JSON.stringify(devs)};`;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-29 13:16:38 -04:00
|
|
|
function prepareScripts() {
|
2020-06-04 21:29:40 -04:00
|
|
|
generateIcons();
|
|
|
|
|
generateDevices();
|
2021-12-26 19:43:48 -05:00
|
|
|
for (let key of Object.keys(script)) {
|
|
|
|
|
code[key] = concatCode(script[key]);
|
|
|
|
|
}
|
2020-05-29 13:16:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function concatCode(array) {
|
|
|
|
|
let code = [];
|
2020-06-03 22:44:05 -04:00
|
|
|
let direct = array.filter(f => f.charAt(0) !== '@');
|
|
|
|
|
let inject = array.filter(f => f.charAt(0) === '@').map(f => f.substring(1));
|
2020-05-29 13:16:38 -04:00
|
|
|
|
2022-02-17 15:04:36 -05:00
|
|
|
synth.inject = "/* injection point */";
|
|
|
|
|
|
2020-05-29 13:16:38 -04:00
|
|
|
// in debug mode, the script should load dependent
|
|
|
|
|
// scripts instead of serving a complete bundle
|
|
|
|
|
if (debug) {
|
2022-02-04 15:46:55 -05:00
|
|
|
const code = [
|
|
|
|
|
'self.debug=true;',
|
|
|
|
|
'(function() { let load = [ '
|
|
|
|
|
];
|
2020-06-03 22:39:30 -04:00
|
|
|
direct.forEach(file => {
|
2022-02-04 15:31:45 -05:00
|
|
|
const vers = cachever[file] || dversion || version;
|
2020-11-17 14:18:09 -05:00
|
|
|
code.push(`"/${file.replace(/\\/g,'/')}?${vers}",`);
|
2020-05-29 13:16:38 -04:00
|
|
|
});
|
|
|
|
|
code.push([
|
|
|
|
|
']; function load_next() {',
|
|
|
|
|
'let file = load.shift();',
|
|
|
|
|
'if (!file) return;',
|
|
|
|
|
'if (!self.document) { importScripts(file); return load_next() }',
|
|
|
|
|
'let s = document.createElement("script");',
|
|
|
|
|
's.type = "text/javascript";',
|
|
|
|
|
's.src = file;',
|
|
|
|
|
's.onload = load_next;',
|
|
|
|
|
'document.head.appendChild(s);',
|
2022-02-04 15:46:55 -05:00
|
|
|
'} load_next(); })();'
|
2020-05-29 13:16:38 -04:00
|
|
|
].join('\n'));
|
2020-06-03 22:39:30 -04:00
|
|
|
inject.forEach(key => {
|
|
|
|
|
code.push(synth[key]);
|
|
|
|
|
});
|
2020-05-29 13:16:38 -04:00
|
|
|
return code.join('\n');
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-03 22:39:30 -04:00
|
|
|
direct.forEach(file => {
|
2020-05-30 18:16:40 -04:00
|
|
|
let cached = getCachedFile(file, function(path) {
|
|
|
|
|
return minify(`${dir}/${file}`);
|
2020-05-29 13:16:38 -04:00
|
|
|
});
|
|
|
|
|
code.push(cached);
|
|
|
|
|
});
|
|
|
|
|
|
2020-06-03 22:39:30 -04:00
|
|
|
inject.forEach(key => {
|
|
|
|
|
code.push(synth[key]);
|
|
|
|
|
});
|
|
|
|
|
|
2020-05-29 13:16:38 -04:00
|
|
|
return code.join('');
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-30 18:16:40 -04:00
|
|
|
function getCachedFile(file, fn) {
|
|
|
|
|
let filePath = `${dir}/${file}`;
|
|
|
|
|
let cachePath = cacheDir + "/" + file
|
2020-05-29 13:16:38 -04:00
|
|
|
.replace(/\//g,'_')
|
|
|
|
|
.replace(/\\/g,'_')
|
|
|
|
|
.replace(/:/g,'_'),
|
|
|
|
|
cached = fileCache[filePath],
|
|
|
|
|
now = time();
|
|
|
|
|
|
|
|
|
|
if (cached) {
|
|
|
|
|
if (now - cached.lastcheck > 60000) {
|
|
|
|
|
let smod = lastmod(filePath),
|
|
|
|
|
cmod = cached.mtime;
|
|
|
|
|
|
2021-02-14 16:21:51 -05:00
|
|
|
if (!smod) {
|
|
|
|
|
throw "missing source file";
|
|
|
|
|
}
|
|
|
|
|
if (smod > cmod) {
|
|
|
|
|
cached = null;
|
|
|
|
|
} else {
|
|
|
|
|
cached.lastcheck = now;
|
|
|
|
|
}
|
2020-05-29 13:16:38 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!cached) {
|
|
|
|
|
let smod = lastmod(filePath),
|
|
|
|
|
cmod = lastmod(cachePath),
|
|
|
|
|
cacheData;
|
|
|
|
|
|
|
|
|
|
if (cmod >= smod) {
|
|
|
|
|
cacheData = fs.readFileSync(cachePath);
|
|
|
|
|
} else {
|
|
|
|
|
logger.log({update_cache:filePath});
|
|
|
|
|
cacheData = fn(filePath);
|
|
|
|
|
fs.writeFileSync(cachePath, cacheData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cached = {
|
|
|
|
|
data: cacheData,
|
|
|
|
|
mtime: cmod || now,
|
|
|
|
|
lastcheck: now
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
fileCache[filePath] = cached;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cached.data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function minify(path) {
|
|
|
|
|
let code = fs.readFileSync(path);
|
2022-01-13 22:48:34 -05:00
|
|
|
if (path.indexOf("ext/three.js") > 0) {
|
|
|
|
|
return code;
|
|
|
|
|
}
|
2020-05-29 13:16:38 -04:00
|
|
|
let mini = uglify.minify(code.toString());
|
|
|
|
|
if (mini.error) {
|
|
|
|
|
console.trace(mini.error);
|
|
|
|
|
throw mini.error;
|
|
|
|
|
}
|
|
|
|
|
return mini.code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function quickReply(res, code, msg) {
|
|
|
|
|
res.writeHead(code);
|
|
|
|
|
res.end(msg+"\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ifModifiedDate(req) {
|
|
|
|
|
let ims = req.headers['if-modified-since'];
|
|
|
|
|
if (ims) {
|
|
|
|
|
// because sys time has a higher resolution than
|
|
|
|
|
// seconds converted from IMS header. so give it
|
|
|
|
|
// an extra second
|
|
|
|
|
return new Date(ims).getTime() + 1000;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function addCorsHeaders(req, res) {
|
|
|
|
|
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
|
|
|
|
res.setHeader('Access-Control-Allow-Headers', 'X-Moto-Ajax, Content-Type');
|
|
|
|
|
res.setHeader("Access-Control-Allow-Origin", req.headers['origin'] || '*');
|
|
|
|
|
res.setHeader("Allow", "GET,POST,OPTIONS");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dispatch for path prefixs
|
|
|
|
|
function prepath(pre) {
|
|
|
|
|
|
|
|
|
|
function handle(req, res, next) {
|
|
|
|
|
pre.uid = pre.uid || guid();
|
|
|
|
|
req.ppi = req.ppi || {};
|
|
|
|
|
|
|
|
|
|
let path = req.app.path,
|
|
|
|
|
key, fn, i = req.ppi[pre.uid] || 0;
|
|
|
|
|
|
|
|
|
|
while (i < pre.length) {
|
|
|
|
|
key = pre[i][0];
|
|
|
|
|
fn = pre[i++][1];
|
|
|
|
|
if (path.indexOf(key) === 0) {
|
|
|
|
|
return fn(req, res, () => {
|
|
|
|
|
req.ppi[pre.uid] = i;
|
|
|
|
|
handle(req, res, next);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return handle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dispatch full fixed paths
|
|
|
|
|
function fullpath(map) {
|
|
|
|
|
return (req, res, next) => {
|
|
|
|
|
let fn = map[req.app.path];
|
|
|
|
|
if (fn) fn(req, res, next);
|
|
|
|
|
else next();
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dispatch full paths based on a prefix and a function map
|
|
|
|
|
function fixedmap(prefix, map) {
|
|
|
|
|
return (req, res, next) => {
|
|
|
|
|
let path = req.app.path;
|
|
|
|
|
if (path.indexOf(prefix) != 0) return next();
|
|
|
|
|
let fn = map[path.substring(prefix.length)];
|
|
|
|
|
if (fn) fn(req, res, next);
|
|
|
|
|
else next();
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HTTP 307 redirect
|
2020-05-30 20:39:56 -04:00
|
|
|
function redir(path, type) {
|
|
|
|
|
return (req, res, next) => http.redirect(res, path, type);
|
2020-05-29 13:16:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// mangle request path
|
|
|
|
|
function remap(path) {
|
|
|
|
|
return (req, res, next) => {
|
|
|
|
|
req.url = req.app.path = path;
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function cookieValue(cookie,key) {
|
|
|
|
|
if (!cookie) return null;
|
|
|
|
|
key = (key || "key") + "=";
|
|
|
|
|
let kpos = cookie.lastIndexOf(key);
|
|
|
|
|
if (kpos >= 0) {
|
|
|
|
|
return cookie.substring(kpos+key.length).split(';')[0];
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function rewriteHtmlVersion(req, res, next) {
|
2021-12-27 20:39:07 -05:00
|
|
|
if (["/kiri/","/mesh/","/meta/"].indexOf(req.app.path) >= 0) {
|
2020-05-29 13:16:38 -04:00
|
|
|
let real_write = res.write;
|
|
|
|
|
let real_end = res.end;
|
2021-12-28 17:30:15 -05:00
|
|
|
let mlen = '{{version}}'.length;
|
2022-02-04 15:31:45 -05:00
|
|
|
let vstr = dversion || version;
|
2021-12-28 17:30:15 -05:00
|
|
|
if (vstr.length < mlen) {
|
|
|
|
|
vstr = vstr.padStart(mlen,0);
|
|
|
|
|
} else if (vstr.length > mlen) {
|
|
|
|
|
vstr = vstr.substring(0,mlen);
|
|
|
|
|
}
|
2020-05-29 13:16:38 -04:00
|
|
|
res.write = function() {
|
2021-12-28 17:30:15 -05:00
|
|
|
arguments[0] = arguments[0].toString().replace(/{{version}}/g,vstr);
|
2020-05-29 13:16:38 -04:00
|
|
|
real_write.apply(res, arguments);
|
|
|
|
|
};
|
|
|
|
|
res.end = function() {
|
|
|
|
|
if (arguments[0]) {
|
2021-12-28 17:30:15 -05:00
|
|
|
arguments[0] = arguments[0].toString().replace(/{{version}}/g,vstr);
|
2020-05-29 13:16:38 -04:00
|
|
|
}
|
|
|
|
|
real_end.apply(res, arguments);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = init;
|