wip: code cleanup, added axios, nanoid shims for quickjs vm

This commit is contained in:
lohxt1 2024-08-16 22:24:21 +05:30
parent a42689a717
commit e81029f28b
6 changed files with 163 additions and 127 deletions

View File

@ -8,6 +8,7 @@ const { newQuickJSWASMModule, memoizePromiseFactory } = require('quickjs-emscrip
// execute `npm run build:isolated-vm:inbuilt-modules` if the below file doesn't exist
const getBundledCode = require('../../bundle-browser-rollup');
const addSleepShimToContext = require('./shims/sleep');
let QuickJSSyncContext;
const loader = memoizePromiseFactory(() => newQuickJSWASMModule());
@ -33,17 +34,6 @@ const executeQuickJsVm = ({ script: externalScript, context: externalContext, sc
req && addBrunoRequestShimToContext(vm, req);
res && addBrunoResponseShimToContext(vm, res);
////////////////////////////////////////////////////////////////////////////////
const logHandle = vm.newFunction('log', (...args) => {
const nativeArgs = args.map(vm.dump);
console.log(...nativeArgs);
});
vm.setProp(vm.global, 'log', logHandle);
logHandle.dispose();
////////////////////////////////////////////////////////////////////////////////
const templateLiteralText = `\`${externalScript}\`;`;
const jsExpressionText = `${externalScript};`;
@ -81,15 +71,15 @@ const executeQuickJsVmAsync = async ({
const vm = module.newContext();
const bundledCode = getBundledCode?.toString() || '';
let bundledScript = `
(${bundledCode})()
`;
bundledScript += `
globalThis.require = (module) => {
return globalThis.requireObject[module];
}
`;
vm.evalCode(
`
(${bundledCode})()
globalThis.require = (module) => {
return globalThis.requireObject[module];
}
`
);
const { bru, req, res, test, __brunoTestResults, console: consoleFn } = externalContext;
@ -97,72 +87,13 @@ const executeQuickJsVmAsync = async ({
req && addBrunoRequestShimToContext(vm, req);
res && addBrunoResponseShimToContext(vm, res);
consoleFn && addConsoleShimToContext(vm, consoleFn);
addSleepShimToContext(vm);
// await addLibraryShimsToContext(context);
await addLibraryShimsToContext(vm);
test && __brunoTestResults && addTestShimToContext(vm, __brunoTestResults);
bundledScript += `
globalThis.expect = require('chai').expect;
globalThis.assert = require('chai').assert;
globalThis.__brunoTestResults = {
addResult: globalThis.__bruno__addResult,
getResults: globalThis.__bruno__getResults,
}
globalThis.DummyChaiAssertionError = class DummyChaiAssertionError extends Error {
constructor(message, props, ssf) {
super(message);
this.name = "AssertionError";
Object.assign(this, props);
}
}
globalThis.Test = (__brunoTestResults) => async (description, callback) => {
try {
await callback();
__brunoTestResults.addResult({ description, status: "pass" });
} catch (error) {
if (error instanceof DummyChaiAssertionError) {
const { message, actual, expected } = error;
__brunoTestResults.addResult({
description,
status: "fail",
error: message,
actual,
expected,
});
} else {
globalThis.__bruno__addResult({
description,
status: "fail",
error: error.message || "An unexpected error occurred.",
});
}
}
};
globalThis.test = Test(__brunoTestResults);
`;
////////////////////////////////////////////////////////////////////////////////
const sleep = vm.newFunction('sleep', (timer) => {
const t = vm.getString(timer);
const promise = vm.newPromise();
setTimeout(() => {
promise.resolve(vm.newString('slept'));
}, t);
promise.settled.then(vm.runtime.executePendingJobs);
return promise.handle;
});
sleep.consume((handle) => vm.setProp(vm.global, 'sleep', handle));
////////////////////////////////////////////////////////////////////////////////
const script = `
${bundledScript}
(async () => {
const setTimeout = async(fn, timer) => {
v = await sleep(timer);

View File

@ -0,0 +1,72 @@
const axios = require('axios');
const { cleanJson } = require('../../../../utils');
const { marshallToVm } = require('../../utils');
const methods = ['get', 'post', 'put', 'patch', 'delete'];
const addAxiosShimToContext = async (vm) => {
methods?.forEach((method) => {
const axiosHandle = vm.newFunction(method, (...args) => {
const nativeArgs = args.map(vm.dump);
const promise = vm.newPromise();
axios[method](...nativeArgs)
.then((response) => {
const { status, headers, data } = response || {};
promise.resolve(marshallToVm(cleanJson({ status, headers, data }), vm));
})
.catch((err) => {
promise.resolve(
marshallToVm(
cleanJson({
message: err.message
}),
vm
)
);
});
promise.settled.then(vm.runtime.executePendingJobs);
return promise.handle;
});
axiosHandle.consume((handle) => vm.setProp(vm.global, `__bruno__axios__${method}`, handle));
});
const axiosHandle = vm.newFunction('axios', (...args) => {
const nativeArgs = args.map(vm.dump);
const promise = vm.newPromise();
axios(...nativeArgs)
.then((response) => {
const { status, headers, data } = response || {};
promise.resolve(marshallToVm(cleanJson({ status, headers, data }), vm));
})
.catch((err) => {
promise.resolve(
marshallToVm(
cleanJson({
message: err.message
}),
vm
)
);
});
promise.settled.then(vm.runtime.executePendingJobs);
return promise.handle;
});
axiosHandle.consume((handle) => vm.setProp(vm.global, `__bruno__axios`, handle));
vm.evalCode(
`
globalThis.axios = __bruno__axios;
${methods
?.map((method) => {
return `globalThis.axios.${method} = __bruno__axios__${method};`;
})
?.join('\n')}
globalThis.requireObject = {
...globalThis.requireObject,
axios: globalThis.axios,
}
`
);
};
module.exports = addAxiosShimToContext;

View File

@ -1,7 +1,9 @@
const addAxiosShimToContext = require('./axios');
const addNanoidShimToContext = require('./nanoid');
const addLibraryShimsToContext = async (context) => {
await addNanoidShimToContext(context);
const addLibraryShimsToContext = async (vm) => {
await addNanoidShimToContext(vm);
await addAxiosShimToContext(vm);
};
module.exports = addLibraryShimsToContext;

View File

@ -1,5 +1,24 @@
const { nanoid } = require('nanoid');
const { marshallToVm } = require('../../utils');
const addNanoidShimToContext = async (context) => {};
const addNanoidShimToContext = async (vm) => {
let _nanoid = vm.newFunction('nanoid', function () {
let v = nanoid();
console.log(v);
return marshallToVm(v, vm);
});
vm.setProp(vm.global, '__bruno__nanoid', _nanoid);
_nanoid.dispose();
vm.evalCode(
`
globalThis.nanoid = {};
globalThis.nanoid.nanoid = globalThis.__bruno__nanoid;
globalThis.requireObject = {
...globalThis.requireObject,
'nanoid': globalThis.nanoid
}
`
);
};
module.exports = addNanoidShimToContext;

View File

@ -0,0 +1,14 @@
const addSleepShimToContext = (vm) => {
const sleepHandle = vm.newFunction('sleep', (timer) => {
const t = vm.getString(timer);
const promise = vm.newPromise();
setTimeout(() => {
promise.resolve(vm.newString('slept'));
}, t);
promise.settled.then(vm.runtime.executePendingJobs);
return promise.handle;
});
sleepHandle.consume((handle) => vm.setProp(vm.global, 'sleep', handle));
};
module.exports = addSleepShimToContext;

View File

@ -13,53 +13,51 @@ const addBruShimToContext = (vm, __brunoTestResults) => {
vm.setProp(vm.global, '__bruno__getResults', getResults);
getResults.dispose();
// vm.evalCode(
// `
// globalThis.expect = require('chai').expect;
// globalThis.assert = require('chai').assert;
vm.evalCode(
`
globalThis.expect = require('chai').expect;
globalThis.assert = require('chai').assert;
// globalThis.__brunoTestResults = {
// addResult: globalThis.addResult,
// getResults: globalThis.getResults,
// }
globalThis.__brunoTestResults = {
addResult: globalThis.__bruno__addResult,
getResults: globalThis.__bruno__getResults,
}
// globalThis.DummyChaiAssertionError = class DummyChaiAssertionError extends Error {
// constructor(message, props, ssf) {
// super(message);
// this.name = "AssertionError";
// Object.assign(this, props);
// }
// }
globalThis.DummyChaiAssertionError = class DummyChaiAssertionError extends Error {
constructor(message, props, ssf) {
super(message);
this.name = "AssertionError";
Object.assign(this, props);
}
}
// globalThis.Test = (__brunoTestResults) => async (description, callback) => {
// try {
// await callback();
// __brunoTestResults.addResult({ description, status: "pass" });
// } catch (error) {
// if (error instanceof DummyChaiAssertionError) {
// const { message, actual, expected } = error;
// __brunoTestResults.addResult({
// description,
// status: "fail",
// error: message,
// actual,
// expected,
// });
// } else {
// __brunoTestResults.addResult({
// description,
// status: "fail",
// error: error.message || "An unexpected error occurred.",
// });
// }
// console.log(error);
// }
// };
// let foobar = 'foobar3000';
// log("from test shim");
// globalThis.test = Test(__brunoTestResults);
// `
// );
globalThis.Test = (__brunoTestResults) => async (description, callback) => {
try {
await callback();
__brunoTestResults.__bruno__addResult({ description, status: "pass" });
} catch (error) {
if (error instanceof DummyChaiAssertionError) {
const { message, actual, expected } = error;
__brunoTestResults.addResult({
description,
status: "fail",
error: message,
actual,
expected,
});
} else {
globalThis.__bruno__addResult({
description,
status: "fail",
error: error.message || "An unexpected error occurred.",
});
}
}
};
globalThis.test = Test(__brunoTestResults);
`
);
};
module.exports = addBruShimToContext;