mqtt/core: refactor scriptage

This commit is contained in:
Koushik Dutta
2021-09-27 23:11:08 -07:00
parent 0907a760df
commit 789dfbcc27
3 changed files with 11 additions and 172 deletions

View File

@@ -1,61 +1,6 @@
import ts, { ScriptTarget } from "typescript";
import sdk, { ScryptedDeviceBase } from "@scrypted/sdk";
import vm from "vm";
const { systemManager, deviceManager, mediaManager, endpointManager } = sdk;
function tsCompile(source: string, options: ts.TranspileOptions = null): string {
// Default options -- you could also perform a merge, or use the project tsconfig.json
if (null === options) {
options = {
compilerOptions: {
target: ScriptTarget.ESNext,
module: ts.ModuleKind.CommonJS
}
};
}
return ts.transpileModule(source, options).outputText;
}
import { ScryptedDeviceBase } from "@scrypted/sdk";
import { scryptedEval as scryptedEvalBase } from "../../../common/src/scrypted-eval";
export async function scryptedEval(device: ScryptedDeviceBase, script: string, params: { [name: string]: any }) {
try {
const compiled = tsCompile(script);
const allParams = Object.assign({}, params, {
systemManager,
deviceManager,
endpointManager,
mediaManager,
log: device.log,
console: device.console,
localStorage: device.storage,
device,
});
try {
const f = vm.compileFunction(compiled, Object.keys(allParams), {
filename: 'script.js',
});
try {
return await f(...Object.values(allParams));
}
catch (e) {
device.log.e('Error running script.');
device.console.error(e);
throw e;
}
}
catch (e) {
device.log.e('Error evaluating script.');
device.console.error(e);
throw e;
}
}
catch (e) {
device.log.e('Error compiling script.');
device.console.error(e);
throw e;
}
}
return scryptedEvalBase(device, script, {}, params);
}

View File

@@ -1,3 +1,5 @@
import { createMonacoEvalDefaults } from "../../../common/src/scrypted-eval";
const libs = {
types: require("!!raw-loader!@scrypted/sdk/types.d.ts"),
sdk: require("!!raw-loader!@scrypted/sdk/index.d.ts"),
@@ -6,54 +8,4 @@ const libs = {
util: require("!!raw-loader!./api/util.ts"),
};
function monacoEvalDefaultsFunction(monaco, libs) {
monaco.languages.typescript.typescriptDefaults.setCompilerOptions(
Object.assign(
{},
monaco.languages.typescript.typescriptDefaults.getCompilerOptions(),
{
moduleResolution:
monaco.languages.typescript.ModuleResolutionKind.NodeJs,
}
)
);
const catLibs = Object.values(libs).join('\n');
const catlibsNoExport = Object.keys(libs).filter(lib => lib !== 'sdk')
.map(lib => libs[lib]).map(lib =>
lib.toString().replace(/export /g, '').replace(/import.*?/g, ''))
.join('\n');
monaco.languages.typescript.typescriptDefaults.addExtraLib(`
${catLibs}
declare global {
${catlibsNoExport}
const log: Logger;
const deviceManager: DeviceManager;
const endpointManager: EndpointManager;
const mediaManager: MediaManager;
const systemManager: SystemManager;
const mqtt: MqttClient;
const device: ScryptedDeviceBase & { pathname : string };
}
`,
"node_modules/@types/scrypted__sdk/types.d.ts"
);
monaco.languages.typescript.typescriptDefaults.addExtraLib(
libs['sdk'],
"node_modules/@types/scrypted__sdk/index.d.ts"
);
}
export const monacoEvalDefaults = `(function() {
const libs = ${JSON.stringify(libs)};
return (monaco) => {
(${monacoEvalDefaultsFunction})(monaco, libs);
}
})();
`;
export const monacoEvalDefaults = createMonacoEvalDefaults(libs);

View File

@@ -1,71 +1,13 @@
import ts, { ScriptTarget } from "typescript";
import sdk, { ScryptedDeviceBase } from "@scrypted/sdk";
import vm from "vm";
import { ScryptedDeviceBase } from "@scrypted/sdk";
import { scryptedEval as scryptedEvalBase } from "../../../common/src/scrypted-eval";
const util = require("!!raw-loader!./api/util.ts");
const frigate = require("!!raw-loader!./api/frigate.ts");
const types = require("!!raw-loader!!@scrypted/sdk/types.d.ts");
const libs = {
frigate,
types,
util,
};
const { systemManager, deviceManager, mediaManager, endpointManager } = sdk;
function tsCompile(source: string, options: ts.TranspileOptions = null): string {
// Default options -- you could also perform a merge, or use the project tsconfig.json
if (null === options) {
options = {
compilerOptions: {
target: ScriptTarget.ESNext,
module: ts.ModuleKind.CommonJS
}
};
}
return ts.transpileModule(source, options).outputText;
}
export async function scryptedEval(device: ScryptedDeviceBase, script: string, params: { [name: string]: any }) {
try {
const allScripts = Object.values(libs).join('\n').toString() + script;
const compiled = tsCompile(allScripts);
const allParams = Object.assign({}, params, {
systemManager,
deviceManager,
endpointManager,
mediaManager,
log: device.log,
console: device.console,
localStorage: device.storage,
device,
exports: {},
});
try {
const f = vm.compileFunction(compiled, Object.keys(allParams), {
filename: 'script.js',
});
try {
return await f(...Object.values(allParams));
}
catch (e) {
device.log.e('Error running script.');
device.console.error(e);
throw e;
}
}
catch (e) {
device.log.e('Error evaluating script.');
device.console.error(e);
throw e;
}
}
catch (e) {
device.log.e('Error compiling script.');
device.console.error(e);
throw e;
}
}
return scryptedEvalBase(device, script, libs, params);
}