@13w/miri
Version:
MongoDB patch manager
73 lines • 2.94 kB
JavaScript
import { EventEmitter } from 'node:events';
import { inspect } from 'node:util';
import { createContext, runInContext, SourceTextModule, SyntheticModule } from 'node:vm';
import { CliServiceProvider } from '@mongosh/service-provider-server';
import { ShellInstanceState } from '@mongosh/shell-api';
import { ShellEvaluator } from '@mongosh/shell-evaluator';
import colors from 'colors';
const print = (values, type) => {
const prepare = (object, type = 'print') => {
if (type === 'print') {
return String(object);
}
else {
return inspect(object, { colors: false, customInspect: true, depth: 22 });
}
};
for (const value of values) {
const printable = value.printable ?? value.rawValue;
if (printable === void 0) {
continue;
}
console.log(colors.blue(prepare(printable, value.type ?? type)));
}
};
const __env = Object.fromEntries(Object.entries(process.env)
.filter(([key]) => key.startsWith('MIRI_'))
.map(([key, value]) => [key.substring(5), value]));
export async function evaluateMongo(client, code, filename = '[no file]') {
const context = createContext({ __env });
const bus = new EventEmitter();
// console.log(`Client status! ${(<{ topology: { isConnected: () => boolean } } & MongoClient>client)?.topology?.isConnected() ? '' : 'not'} connected`)
const cliServiceProvider = new CliServiceProvider(client, bus, {
productName: 'MIRI: Migration manager',
productDocsLink: 'https://example.com/',
});
const instanceState = new ShellInstanceState(cliServiceProvider);
instanceState.setCtx(context);
instanceState.setEvaluationListener({
onPrint(values, type) {
return print(values, type);
},
onPrompt() {
throw new Error('Prompt isn\'t supported');
},
onLoad() {
throw new Error('Load isn\'t supported');
},
onExit() {
throw new Error('Exit isn\'t supported');
},
});
const output = await new ShellEvaluator(instanceState)
.customEval(runInContext, `${code};`, context, filename);
return output.rawValue;
}
export async function evaluateJs(code, identifier = '[no file]') {
const context = createContext({ __env, console });
const module = new SourceTextModule(code, { context, identifier });
await module.link(async function linker(specifier, referencingModule) {
return import(specifier).then((module) => {
return new SyntheticModule(['default'], function () {
this.setExport('default', module.default);
}, { context: referencingModule.context });
});
});
await module.evaluate()
.catch((error) => {
error.message += ` # at file ${identifier}`;
throw error;
});
return module.namespace;
}
//# sourceMappingURL=evaluator.js.map