112 lines
3.5 KiB
TypeScript
112 lines
3.5 KiB
TypeScript
import * as path from "path";
|
|
import {remote} from "electron";
|
|
import * as electron from "electron";
|
|
import * as os from "os";
|
|
|
|
const Module = require("module");
|
|
|
|
interface ModuleOverride {
|
|
name?: string,
|
|
test: string | RegExp | ((request: string) => boolean);
|
|
callback: (this: string, request: string, parent?: NodeJS.Module) => any;
|
|
}
|
|
const overrides: ModuleOverride[] = [];
|
|
|
|
function proxied_load(request: string, parent?: NodeJS.Module) {
|
|
for(const override of overrides) {
|
|
let test_satisfied = false;
|
|
if(typeof override.test === "string") {
|
|
test_satisfied = override.test === request;
|
|
} else if(typeof override.test === "function") {
|
|
test_satisfied = override.test(request);
|
|
} else if(typeof override === "object") {
|
|
if(override.test instanceof RegExp)
|
|
test_satisfied = !!request.match(override.test);
|
|
}
|
|
|
|
if(test_satisfied) {
|
|
//console.log("Using override %s for %s", override.name || "unnamed", request);
|
|
return override.callback.apply(this, arguments);
|
|
}
|
|
}
|
|
//console.log("No override found for %s", request);
|
|
return proxied_load.original_load.apply(this, arguments);
|
|
}
|
|
|
|
function shared_backend_loader(request: string) {
|
|
if(!request.startsWith("tc-backend/")) throw "invalid target";
|
|
const target = request.substr(11);
|
|
|
|
return require(path.join(backend_root, target));
|
|
}
|
|
|
|
namespace proxied_load {
|
|
export let original_load: typeof Module.require;
|
|
}
|
|
|
|
let backend_root: string;
|
|
export function initialize(backend_root_: string) {
|
|
backend_root = backend_root_;
|
|
|
|
proxied_load.original_load = Module._load;
|
|
Module._load = proxied_load;
|
|
|
|
window["backend-loader"] = {
|
|
require: shared_backend_loader
|
|
};
|
|
}
|
|
|
|
|
|
overrides.push({
|
|
name: "tc-loader",
|
|
test: "tc-loader",
|
|
callback: () => window["loader"]
|
|
});
|
|
|
|
overrides.push({
|
|
name: "native loader",
|
|
test: /^tc-native\/[a-zA-Z_-]+$/,
|
|
callback: request => {
|
|
const name = request.substr(10);
|
|
|
|
const file_mapping = {
|
|
connection: "teaclient_connection.node",
|
|
ppt: "teaclient_ppt.node",
|
|
dns: "teaclient_dns.node"
|
|
};
|
|
|
|
if(typeof file_mapping[name] !== "string")
|
|
throw "unknown native module";
|
|
|
|
const app_path = (remote || electron).app.getAppPath();
|
|
let target_path;
|
|
if(app_path.endsWith(".asar")) {
|
|
target_path = path.join(path.dirname(app_path), "natives", file_mapping[name]);
|
|
} else {
|
|
/* from source code */
|
|
target_path = path.join(app_path, "native", "build", os.platform() + "_" + os.arch(), file_mapping[name]);
|
|
}
|
|
return require(target_path);
|
|
}
|
|
});
|
|
|
|
overrides.push({
|
|
name: "shared loader",
|
|
test: /^tc-shared\/.*/,
|
|
callback: request => {
|
|
const webpack_path = path.dirname("shared/js/" + request.substr(10)); //FIXME: Get the prefix from a variable!
|
|
const loader = require("tc-loader");
|
|
|
|
const mapping = loader.module_mapping().find(e => e.application === "client-app"); //FIXME: Variable name!
|
|
if(!mapping) throw "missing mapping";
|
|
|
|
const entries = mapping.modules.filter(e => e.context === webpack_path);
|
|
if(!entries.length) throw "unknown target path";
|
|
|
|
const basename = path.basename(request, path.extname(request));
|
|
const entry = entries.find(e => path.basename(e.resource, path.extname(e.resource)) === basename);
|
|
if(!entry) throw "unknown import";
|
|
|
|
return window["shared-require"](entry.id);
|
|
}
|
|
}); |