mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-07 16:44:27 +01:00
feat: testing quickjs sanbox
This commit is contained in:
parent
81d660afd7
commit
8eac761583
@ -57,6 +57,9 @@ npm run build:graphql-docs
|
|||||||
npm run build:bruno-query
|
npm run build:bruno-query
|
||||||
npm run build:bruno-common
|
npm run build:bruno-common
|
||||||
|
|
||||||
|
# bundle js sandbox libraries
|
||||||
|
npm run sandbox:bundle-libraries --workspace=packages/bruno-js
|
||||||
|
|
||||||
# run next app (terminal 1)
|
# run next app (terminal 1)
|
||||||
npm run dev:web
|
npm run dev:web
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ const getEnvVars = (environment = {}) => {
|
|||||||
|
|
||||||
const getJsSandboxRuntime = (collection) => {
|
const getJsSandboxRuntime = (collection) => {
|
||||||
const securityConfig = get(collection, 'securityConfig', {});
|
const securityConfig = get(collection, 'securityConfig', {});
|
||||||
return securityConfig.jsSandboxMode === 'safe' ? 'isolated-vm' : 'vm2';
|
return securityConfig.jsSandboxMode === 'safe' ? 'quickjs' : 'vm2';
|
||||||
};
|
};
|
||||||
|
|
||||||
const protocolRegex = /^([-+\w]{1,25})(:?\/\/|:)/;
|
const protocolRegex = /^([-+\w]{1,25})(:?\/\/|:)/;
|
||||||
|
2
packages/bruno-js/.gitignore
vendored
2
packages/bruno-js/.gitignore
vendored
@ -1 +1 @@
|
|||||||
src/bundle-browser-rollup.js
|
src/sandbox/bundle-browser-rollup.js
|
@ -12,11 +12,10 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest --testPathIgnorePatterns test.js",
|
"test": "jest --testPathIgnorePatterns test.js",
|
||||||
"postinstall": "npm run isolated-vm:install && npm run isolated-vm:bundle-libraries",
|
"sandbox:bundle-libraries": "node ./src/sandbox/bundle-libraries.js",
|
||||||
"isolated-vm:install": "cd ./node_modules/isolated-vm && npm install",
|
"isolated-vm:install": "cd ./node_modules/isolated-vm && npm install",
|
||||||
"isolated-vm:prebuild:dev": "node ./scripts/prebuild-isolated-vm-for-dev.js",
|
"isolated-vm:prebuild:dev": "node ./scripts/prebuild-isolated-vm-for-dev.js",
|
||||||
"isolated-vm:prebuild:prod": "node ./scripts/prebuild-isolated-vm-for-prod-builds.js",
|
"isolated-vm:prebuild:prod": "node ./scripts/prebuild-isolated-vm-for-prod-builds.js"
|
||||||
"isolated-vm:bundle-libraries": "node ./src/sandbox/isolatedvm/utils/bundle-libraries.js"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@usebruno/common": "0.1.0",
|
"@usebruno/common": "0.1.0",
|
||||||
|
@ -31,6 +31,7 @@ const fetch = require('node-fetch');
|
|||||||
const CryptoJS = require('crypto-js');
|
const CryptoJS = require('crypto-js');
|
||||||
const NodeVault = require('node-vault');
|
const NodeVault = require('node-vault');
|
||||||
const { executeInIsolatedVMAsync } = require('../sandbox/isolatedvm');
|
const { executeInIsolatedVMAsync } = require('../sandbox/isolatedvm');
|
||||||
|
const { executeQuickJsVmAsync } = require('../sandbox/quickjs');
|
||||||
|
|
||||||
class TestRuntime {
|
class TestRuntime {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -115,16 +116,12 @@ class TestRuntime {
|
|||||||
modules: {},
|
modules: {},
|
||||||
scriptType: 'jsScript'
|
scriptType: 'jsScript'
|
||||||
});
|
});
|
||||||
|
} else if(this.runtime === 'quickjs') {
|
||||||
return {
|
await executeQuickJsVmAsync({
|
||||||
request,
|
script: testsFile,
|
||||||
envVariables: cleanJson(envVariables),
|
context: context
|
||||||
runtimeVariables: cleanJson(runtimeVariables),
|
});
|
||||||
results: cleanJson(__brunoTestResults.getResults()),
|
} else {
|
||||||
nextRequestName: bru.nextRequest
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// default runtime is vm2
|
// default runtime is vm2
|
||||||
const vm = new NodeVM({
|
const vm = new NodeVM({
|
||||||
sandbox: context,
|
sandbox: context,
|
||||||
@ -163,6 +160,7 @@ class TestRuntime {
|
|||||||
});
|
});
|
||||||
const asyncVM = vm.run(`module.exports = async () => { ${testsFile}}`, path.join(collectionPath, 'vm.js'));
|
const asyncVM = vm.run(`module.exports = async () => { ${testsFile}}`, path.join(collectionPath, 'vm.js'));
|
||||||
await asyncVM();
|
await asyncVM();
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
request,
|
request,
|
||||||
|
@ -54,7 +54,7 @@ const bundleLibraries = async () => {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
file: './src/bundle-browser-rollup.js',
|
file: './src/sandbox/bundle-browser-rollup.js',
|
||||||
format: 'iife',
|
format: 'iife',
|
||||||
name: 'MyBundle'
|
name: 'MyBundle'
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ const bundleLibraries = async () => {
|
|||||||
const bundle = await rollup.rollup(config.input);
|
const bundle = await rollup.rollup(config.input);
|
||||||
const { output } = await bundle.generate(config.output);
|
const { output } = await bundle.generate(config.output);
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
'./src/bundle-browser-rollup.js',
|
'./src/sandbox/bundle-browser-rollup.js',
|
||||||
`
|
`
|
||||||
const getBundledCode = () => {
|
const getBundledCode = () => {
|
||||||
return function(){
|
return function(){
|
@ -1,167 +0,0 @@
|
|||||||
const ivm = require('isolated-vm');
|
|
||||||
const addBruShimToContext = require('./shims/bru');
|
|
||||||
const addBrunoRequestShimToContext = require('./shims/bruno-request');
|
|
||||||
const addConsoleShimToContext = require('./shims/console');
|
|
||||||
const addBrunoResponseShimToContext = require('./shims/bruno-response');
|
|
||||||
const addTestShimToContext = require('./shims/test');
|
|
||||||
const addLibraryShimsToContext = require('./shims/lib');
|
|
||||||
|
|
||||||
// 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');
|
|
||||||
|
|
||||||
const toNumber = (value) => {
|
|
||||||
const num = Number(value);
|
|
||||||
return Number.isInteger(num) ? parseInt(value, 10) : parseFloat(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const executeInIsolatedVMStrict = ({ script: externalScript, context: externalContext, scriptType = 'script' }) => {
|
|
||||||
if (!isNaN(Number(externalScript))) {
|
|
||||||
return Number(externalScript);
|
|
||||||
}
|
|
||||||
let result;
|
|
||||||
const isolate = new ivm.Isolate();
|
|
||||||
try {
|
|
||||||
const context = isolate.createContextSync();
|
|
||||||
context.global.setSync('global', context.global.derefInto());
|
|
||||||
|
|
||||||
const { bru, req, res } = externalContext;
|
|
||||||
|
|
||||||
context.evalSync(`
|
|
||||||
let bru = {};
|
|
||||||
let req = {};
|
|
||||||
let res = {};
|
|
||||||
`);
|
|
||||||
|
|
||||||
bru && addBruShimToContext(context, bru);
|
|
||||||
req && addBrunoRequestShimToContext(context, req);
|
|
||||||
res && addBrunoResponseShimToContext(context, res);
|
|
||||||
|
|
||||||
context.global.setSync('setResult', function (arg) {
|
|
||||||
result = arg;
|
|
||||||
});
|
|
||||||
|
|
||||||
const templateLiteralText = `
|
|
||||||
let value = \`${externalScript}\`;
|
|
||||||
setResult(value);
|
|
||||||
`;
|
|
||||||
|
|
||||||
const jsExpressionText = `
|
|
||||||
let value = ${externalScript};
|
|
||||||
setResult(value);
|
|
||||||
`;
|
|
||||||
|
|
||||||
let scriptText = scriptType === 'template-literal' ? templateLiteralText : jsExpressionText;
|
|
||||||
|
|
||||||
const script = isolate.compileScriptSync(scriptText);
|
|
||||||
script.runSync(context);
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error executing the script!', error);
|
|
||||||
}
|
|
||||||
isolate.dispose();
|
|
||||||
};
|
|
||||||
|
|
||||||
const executeInIsolatedVMAsync = async ({
|
|
||||||
script: externalScript,
|
|
||||||
context: externalContext,
|
|
||||||
modules = {},
|
|
||||||
scriptType = 'script'
|
|
||||||
}) => {
|
|
||||||
if (!isNaN(Number(externalScript))) {
|
|
||||||
return toNumber(externalScript);
|
|
||||||
}
|
|
||||||
let result;
|
|
||||||
const isolate = new ivm.Isolate();
|
|
||||||
try {
|
|
||||||
const context = await isolate.createContext();
|
|
||||||
await context.global.set('global', context.global.derefInto());
|
|
||||||
|
|
||||||
context.evalSync(`
|
|
||||||
let bru = {};
|
|
||||||
let req = {};
|
|
||||||
let res = {};
|
|
||||||
let console = {};
|
|
||||||
global.requireObject = {};
|
|
||||||
`);
|
|
||||||
|
|
||||||
context.global.setSync('log', function (...args) {
|
|
||||||
console.debug(...args);
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
const bundledCode = getBundledCode?.toString() || '';
|
|
||||||
await context.eval(`(${bundledCode})()`);
|
|
||||||
} catch (err) {
|
|
||||||
console.debug('Error bundling libraries', err);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { bru, req, res, test, __brunoTestResults, console: consoleFn } = externalContext;
|
|
||||||
|
|
||||||
bru && addBruShimToContext(context, bru);
|
|
||||||
req && addBrunoRequestShimToContext(context, req);
|
|
||||||
res && addBrunoResponseShimToContext(context, res);
|
|
||||||
consoleFn && addConsoleShimToContext(context, consoleFn);
|
|
||||||
addSleepShimToContext(context);
|
|
||||||
|
|
||||||
await context.eval(
|
|
||||||
`
|
|
||||||
global.require = (module) => {
|
|
||||||
return global.requireObject[module];
|
|
||||||
}
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
await addLibraryShimsToContext(context);
|
|
||||||
|
|
||||||
test && __brunoTestResults && (await addTestShimToContext(context, __brunoTestResults));
|
|
||||||
|
|
||||||
context.global.setSync('setResult', function (arg) {
|
|
||||||
result = arg;
|
|
||||||
});
|
|
||||||
|
|
||||||
const jsScriptText = `
|
|
||||||
new Promise(async (resolve, reject) => {
|
|
||||||
// modify the setTimeout function with the shim to work-around the callback-function clone issues
|
|
||||||
setTimeout = global.setTimeout;
|
|
||||||
console?.debug && console.debug('isolated-vm:execution-start:');
|
|
||||||
try {
|
|
||||||
${externalScript}
|
|
||||||
} catch (error) {
|
|
||||||
console?.debug && console.debug('isolated-vm:execution-end:with-error', error?.message);
|
|
||||||
}
|
|
||||||
console?.debug && console.debug('isolated-vm:execution-end:');
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
`;
|
|
||||||
|
|
||||||
const templateLiteralText = `
|
|
||||||
let value = \`${externalScript}\`;
|
|
||||||
setResult(value);
|
|
||||||
`;
|
|
||||||
|
|
||||||
const jsExpressionText = `
|
|
||||||
let value = ${externalScript};
|
|
||||||
setResult(value);
|
|
||||||
`;
|
|
||||||
|
|
||||||
let scriptText =
|
|
||||||
scriptType === 'template-literal'
|
|
||||||
? templateLiteralText
|
|
||||||
: scriptType === 'expression'
|
|
||||||
? jsExpressionText
|
|
||||||
: jsScriptText;
|
|
||||||
|
|
||||||
const script = await isolate.compileScript(scriptText);
|
|
||||||
await script.run(context);
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error executing the script!', error);
|
|
||||||
}
|
|
||||||
isolate.dispose();
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
executeInIsolatedVMStrict,
|
|
||||||
executeInIsolatedVMAsync
|
|
||||||
};
|
|
@ -1,59 +0,0 @@
|
|||||||
const addBruShimToContext = (context, bru) => {
|
|
||||||
context.global.setSync('cwd', function () {
|
|
||||||
return bru.cwd();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getEnvName', function () {
|
|
||||||
return bru.getEnvName();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getProcessEnv', function (key) {
|
|
||||||
return bru.getProcessEnv(key);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getEnvVar', function (key) {
|
|
||||||
return bru.getEnvVar(key);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('setEnvVar', function (key, value) {
|
|
||||||
bru.setEnvVar(key, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('setVar', function (key, value) {
|
|
||||||
bru.setVar(key, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getVar', function (key) {
|
|
||||||
return bru.getVar(key);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('setNextRequest', function (nextRequest) {
|
|
||||||
bru.setNextRequest(nextRequest);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('visualize', function (htmlString) {
|
|
||||||
bru.visualize(htmlString);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getSecretVar', function (key) {
|
|
||||||
return bru.getSecretVar(key);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.evalSync(`
|
|
||||||
bru = {
|
|
||||||
...bru || {},
|
|
||||||
cwd: global.cwd,
|
|
||||||
getEnvName: global.getEnvName,
|
|
||||||
getProcessEnv: global.getProcessEnv,
|
|
||||||
getEnvVar: global.getEnvVar,
|
|
||||||
setEnvVar: global.setEnvVar,
|
|
||||||
setVar: global.setVar,
|
|
||||||
getVar: global.getVar,
|
|
||||||
setNextRequest: global.setNextRequest,
|
|
||||||
visualize: global.visualize,
|
|
||||||
getSecretVar: global.getSecretVar
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addBruShimToContext;
|
|
@ -1,79 +0,0 @@
|
|||||||
const addBrunoRequestShimToContext = (context, req) => {
|
|
||||||
context.global.setSync('getUrl', function () {
|
|
||||||
return req.getUrl();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('setUrl', function (url) {
|
|
||||||
req.setUrl(url);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getMethod', function () {
|
|
||||||
return req.getMethod();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getAuthMode', function () {
|
|
||||||
return req.getAuthMode();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('setMethod', function (method) {
|
|
||||||
req.setMethod(method);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getHeaders', function () {
|
|
||||||
return req.getHeaders();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('setHeaders', function (headers) {
|
|
||||||
req.setHeaders(headers);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getHeader', function (name) {
|
|
||||||
return req.getHeader(name);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('setHeader', function (name, value) {
|
|
||||||
req.setHeader(name, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getBody', function () {
|
|
||||||
return req.getBody();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('setBody', function (data) {
|
|
||||||
req.setBody(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('setMaxRedirects', function (maxRedirects) {
|
|
||||||
req.setMaxRedirects(maxRedirects);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getTimeout', function () {
|
|
||||||
return req.getTimeout();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('setTimeout', function (timeout) {
|
|
||||||
req.setTimeout(timeout);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.evalSync(`
|
|
||||||
req = {
|
|
||||||
...req || {},
|
|
||||||
getUrl: global.getUrl,
|
|
||||||
setUrl: global.setUrl,
|
|
||||||
getMethod: global.getMethod,
|
|
||||||
getAuthMode: global.getAuthMode,
|
|
||||||
setMethod: global.setMethod,
|
|
||||||
getHeaders: global.getHeaders,
|
|
||||||
setHeaders: global.setHeaders,
|
|
||||||
getHeader: global.getHeader,
|
|
||||||
setHeader: global.setHeader,
|
|
||||||
getBody: global.getBody,
|
|
||||||
setBody: global.setBody,
|
|
||||||
setMaxRedirects: global.setMaxRedirects,
|
|
||||||
getTimeout: global.getTimeout,
|
|
||||||
setTimeout: global.setTimeout
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addBrunoRequestShimToContext;
|
|
@ -1,46 +0,0 @@
|
|||||||
const ivm = require('isolated-vm');
|
|
||||||
|
|
||||||
const addBrunoResponseShimToContext = (context, res) => {
|
|
||||||
context.global.setSync('status', new ivm.ExternalCopy(res?.status).copyInto());
|
|
||||||
context.global.setSync('headers', new ivm.ExternalCopy(res?.headers).copyInto());
|
|
||||||
context.global.setSync('body', new ivm.ExternalCopy(res?.body).copyInto());
|
|
||||||
context.global.setSync('responseTime', new ivm.ExternalCopy(res?.responseTime).copyInto());
|
|
||||||
|
|
||||||
context.global.setSync('getStatus', function () {
|
|
||||||
return res?.getStatus();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getHeader', function (name) {
|
|
||||||
return res?.getHeader(name);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getHeaders', function () {
|
|
||||||
return res?.getHeaders();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getBody', function () {
|
|
||||||
return res?.getBody();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getResponseTime', function () {
|
|
||||||
return res?.getResponseTime();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.evalSync(`
|
|
||||||
res = {
|
|
||||||
...res || {},
|
|
||||||
status: global.status,
|
|
||||||
statusText: global.statusText,
|
|
||||||
headers: global.headers,
|
|
||||||
body: global.body,
|
|
||||||
responseTime: global.responseTime,
|
|
||||||
getStatus: global.getStatus,
|
|
||||||
getHeader: global.getHeader,
|
|
||||||
getHeaders: global.getHeaders,
|
|
||||||
getBody: global.getBody,
|
|
||||||
getResponseTime: global.getResponseTime
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addBrunoResponseShimToContext;
|
|
@ -1,39 +0,0 @@
|
|||||||
const addConsoleShimToContext = (context, console) => {
|
|
||||||
context.global.setSync('log', function (...args) {
|
|
||||||
console?.log && console.log(...args);
|
|
||||||
return args;
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('debug', function (...args) {
|
|
||||||
console?.debug && console.debug(...args);
|
|
||||||
return args;
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('info', function (...args) {
|
|
||||||
console?.info && console.info(...args);
|
|
||||||
return args;
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('warn', function (...args) {
|
|
||||||
console?.warn && console.warn(...args);
|
|
||||||
return args;
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('error', function (...args) {
|
|
||||||
console?.error && console.error(...args);
|
|
||||||
return args;
|
|
||||||
});
|
|
||||||
|
|
||||||
context.evalSync(`
|
|
||||||
console = {
|
|
||||||
...console || {},
|
|
||||||
log: global.log,
|
|
||||||
debug: global.debug,
|
|
||||||
info: global.info,
|
|
||||||
warn: global.warn,
|
|
||||||
error: global.error
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addConsoleShimToContext;
|
|
@ -1,57 +0,0 @@
|
|||||||
const axios = require('axios');
|
|
||||||
const ivm = require('isolated-vm');
|
|
||||||
const { cleanJson } = require('../../../../utils');
|
|
||||||
|
|
||||||
const addAxiosShimToContext = async (context) => {
|
|
||||||
await context.evalClosure(
|
|
||||||
`
|
|
||||||
globalThis.axios = (...args) => $0.applySyncPromise(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
${['get', 'post', 'put', 'patch', 'delete']
|
|
||||||
?.map(
|
|
||||||
(method, idx) =>
|
|
||||||
`globalThis.axios.${method} = (...args) => $${
|
|
||||||
idx + 1
|
|
||||||
}.applySyncPromise(undefined, args?.map(arg=>JSON.stringify(arg)))`
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
globalThis.requireObject = {
|
|
||||||
...globalThis.requireObject,
|
|
||||||
axios: globalThis.axios,
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
[
|
|
||||||
async (...argStrings) => {
|
|
||||||
console.log(argStrings);
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
const res = await axios(...args)
|
|
||||||
.then((response) => {
|
|
||||||
return cleanJson(response?.data);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return {
|
|
||||||
message: err.message
|
|
||||||
// response: cleanJson(err.response)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return new ivm.ExternalCopy(res).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
...['get', 'post', 'put', 'patch', 'delete']?.map((method) => async (...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
const res = await axios[method](...args)
|
|
||||||
.then((response) => {
|
|
||||||
return cleanJson(response?.data);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return {
|
|
||||||
message: err.message
|
|
||||||
// response: cleanJson(err.response)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return new ivm.ExternalCopy(res).copyInto({ release: true });
|
|
||||||
})
|
|
||||||
],
|
|
||||||
{ arguments: { reference: true } }
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addAxiosShimToContext;
|
|
@ -1,121 +0,0 @@
|
|||||||
const axios = require('axios');
|
|
||||||
const ivm = require('isolated-vm');
|
|
||||||
const { cleanJson } = require('../../../../utils');
|
|
||||||
|
|
||||||
const addAxiosShimToContext = async (context) => {
|
|
||||||
await context.evalClosure(
|
|
||||||
`
|
|
||||||
globalThis.axios = (...args) => $0.applySyncPromise(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.axios.get = (...args) => $1.applySyncPromise(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.axios.post = (...args) => $2.applySyncPromise(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.axios.put = (...args) => $3.applySyncPromise(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.axios.delete = (...args) => $4.applySyncPromise(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.axios.patch = (...args) => $5.applySyncPromise(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.requireObject = {
|
|
||||||
...globalThis.requireObject,
|
|
||||||
axios: globalThis.axios,
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
[
|
|
||||||
async (...argStrings) => {
|
|
||||||
console.log(argStrings);
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
const res = await axios(...args)
|
|
||||||
.then((response) => {
|
|
||||||
const { status, headers, data } = response || {};
|
|
||||||
return cleanJson({ status, headers, data });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return {
|
|
||||||
message: err.message
|
|
||||||
// response: cleanJson(err.response)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return new ivm.ExternalCopy(res).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
async (...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
const res = await axios
|
|
||||||
.get(...args)
|
|
||||||
.then((response) => {
|
|
||||||
const { status, headers, data } = response || {};
|
|
||||||
return cleanJson({ status, headers, data });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return {
|
|
||||||
message: err.message
|
|
||||||
// response: cleanJson(err.response)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return new ivm.ExternalCopy(res).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
async (...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
const res = await axios
|
|
||||||
.post(...args)
|
|
||||||
.then((response) => {
|
|
||||||
const { status, headers, data } = response || {};
|
|
||||||
return cleanJson({ status, headers, data });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return {
|
|
||||||
message: err.message
|
|
||||||
// response: cleanJson(err.response)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return new ivm.ExternalCopy(res).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
async (...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
const res = await axios
|
|
||||||
.put(...args)
|
|
||||||
.then((response) => {
|
|
||||||
const { status, headers, data } = response || {};
|
|
||||||
return cleanJson({ status, headers, data });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return {
|
|
||||||
message: err.message
|
|
||||||
// response: cleanJson(err.response)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return new ivm.ExternalCopy(res).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
async (...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
const res = await axios
|
|
||||||
.delete(...args)
|
|
||||||
.then((response) => {
|
|
||||||
const { status, headers, data } = response || {};
|
|
||||||
return cleanJson({ status, headers, data });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return {
|
|
||||||
message: err.message
|
|
||||||
// response: cleanJson(err.response)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return new ivm.ExternalCopy(res).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
async (...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
const res = await axios
|
|
||||||
.patch(...args)
|
|
||||||
.then((response) => {
|
|
||||||
const { status, headers, data } = response || {};
|
|
||||||
return cleanJson({ status, headers, data });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return {
|
|
||||||
message: err.message
|
|
||||||
// response: cleanJson(err.response)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return new ivm.ExternalCopy(res).copyInto({ release: true });
|
|
||||||
}
|
|
||||||
],
|
|
||||||
{ arguments: { reference: true } }
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addAxiosShimToContext;
|
|
@ -1,11 +0,0 @@
|
|||||||
const addAxiosShimToContext = require('./axios');
|
|
||||||
const addNanoidShimToContext = require('./nanoid');
|
|
||||||
const addUuidShimToContext = require('./uuid');
|
|
||||||
|
|
||||||
const addLibraryShimsToContext = async (context) => {
|
|
||||||
await addAxiosShimToContext(context);
|
|
||||||
await addNanoidShimToContext(context);
|
|
||||||
await addUuidShimToContext(context);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addLibraryShimsToContext;
|
|
@ -1,23 +0,0 @@
|
|||||||
const ivm = require('isolated-vm');
|
|
||||||
const { nanoid } = require('nanoid');
|
|
||||||
|
|
||||||
const addNanoidShimToContext = async (context) => {
|
|
||||||
await context.evalClosure(
|
|
||||||
`
|
|
||||||
globalThis.nanoid = {};
|
|
||||||
globalThis.nanoid.nanoid = () => $0.applySync(undefined);
|
|
||||||
globalThis.requireObject = {
|
|
||||||
...globalThis.requireObject,
|
|
||||||
nanoid: globalThis.nanoid
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
[
|
|
||||||
() => {
|
|
||||||
return new ivm.ExternalCopy(nanoid()).copyInto({ release: true });
|
|
||||||
}
|
|
||||||
],
|
|
||||||
{ arguments: { reference: true } }
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addNanoidShimToContext;
|
|
@ -1,39 +0,0 @@
|
|||||||
const ivm = require('isolated-vm');
|
|
||||||
const uuid = require('uuid');
|
|
||||||
const { MAX, NIL } = uuid;
|
|
||||||
|
|
||||||
const addUuidShimToContext = async (context) => {
|
|
||||||
await context.evalClosure(
|
|
||||||
`
|
|
||||||
globalThis.uuid = {};
|
|
||||||
globalThis.uuid.MAX = $0;
|
|
||||||
globalThis.uuid.NIL = $1;
|
|
||||||
${['version', 'parse', 'stringify', 'v1', 'v1ToV6', 'v3', 'v4', 'v5', 'v6', 'v6ToV1', 'v7', 'validate']
|
|
||||||
?.map(
|
|
||||||
(fn, idx) =>
|
|
||||||
`globalThis.uuid.${fn} = (...args) => $${
|
|
||||||
idx + 2
|
|
||||||
}.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));`
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
globalThis.requireObject = {
|
|
||||||
...globalThis.requireObject,
|
|
||||||
uuid: globalThis.uuid,
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
[
|
|
||||||
new ivm.ExternalCopy(MAX).copyInto({ release: true }),
|
|
||||||
new ivm.ExternalCopy(NIL).copyInto({ release: true }),
|
|
||||||
...['version', 'parse', 'stringify', 'v1', 'v1ToV6', 'v3', 'v4', 'v5', 'v6', 'v6ToV1', 'v7', 'validate']?.map(
|
|
||||||
(fn) =>
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(uuid[fn](...args)).copyInto({ release: true });
|
|
||||||
}
|
|
||||||
)
|
|
||||||
],
|
|
||||||
{ arguments: { reference: true } }
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addUuidShimToContext;
|
|
@ -1,83 +0,0 @@
|
|||||||
const ivm = require('isolated-vm');
|
|
||||||
const { MAX, NIL, parse, stringify, v1, v1ToV6, v3, v4, v5, v6, v6ToV1, v7, validate, version } = require('uuid');
|
|
||||||
|
|
||||||
const addUuidShimToContext = async (context) => {
|
|
||||||
await context.evalClosure(
|
|
||||||
`
|
|
||||||
globalThis.uuid = {};
|
|
||||||
globalThis.uuid.MAX = $0;
|
|
||||||
globalThis.uuid.NIL = $1;
|
|
||||||
globalThis.uuid.version = (...args) => $2.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.parse = (...args) => $3.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.stringify = (...args) => $4.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.v1 = (...args) => $5.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.v1ToV6 = (...args) => $6.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.v3 = (...args) => $7.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.v4 = (...args) => $8.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.v5 = (...args) => $9.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.v6 = (...args) => $10.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.v6ToV1 = (...args) => $11.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.v7 = (...args) => $12.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.uuid.validate = (...args) => $13.applySync(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
globalThis.requireObject = {
|
|
||||||
...globalThis.requireObject,
|
|
||||||
uuid: globalThis.uuid,
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
[
|
|
||||||
new ivm.ExternalCopy(MAX).copyInto({ release: true }),
|
|
||||||
new ivm.ExternalCopy(NIL).copyInto({ release: true }),
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(version(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(parse(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(stringify(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(v1(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(v1ToV6(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(v3(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(v4(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(v5(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(v6(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(v6ToV1(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(v7(...args)).copyInto({ release: true });
|
|
||||||
},
|
|
||||||
(...argStrings) => {
|
|
||||||
let args = argStrings?.map((arg) => JSON.parse(arg));
|
|
||||||
return new ivm.ExternalCopy(validate(...args)).copyInto({ release: true });
|
|
||||||
}
|
|
||||||
],
|
|
||||||
{ arguments: { reference: true } }
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addUuidShimToContext;
|
|
@ -1,32 +0,0 @@
|
|||||||
const ivm = require('isolated-vm');
|
|
||||||
const addSleepShimToContext = (context, console) => {
|
|
||||||
context.evalClosureSync(
|
|
||||||
`
|
|
||||||
global.sleep = (...args) => $0.applySyncPromise(undefined, args?.map(arg=>JSON.stringify(arg)));
|
|
||||||
`,
|
|
||||||
[
|
|
||||||
async (...argStrings) => {
|
|
||||||
await new Promise((resolve) => {
|
|
||||||
const timer = Number(argStrings?.[0]);
|
|
||||||
if (!Number.isInteger(timer) || timer < 0) {
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve();
|
|
||||||
}, timer);
|
|
||||||
});
|
|
||||||
return new ivm.ExternalCopy('done').copyInto({ release: true });
|
|
||||||
}
|
|
||||||
],
|
|
||||||
{ arguments: { reference: true } }
|
|
||||||
);
|
|
||||||
|
|
||||||
context.evalSync(`
|
|
||||||
global.setTimeout = async (fn, timer) => {
|
|
||||||
await sleep(timer);
|
|
||||||
await fn.apply();
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addSleepShimToContext;
|
|
@ -1,57 +0,0 @@
|
|||||||
const addTestShimToContext = async (context, __brunoTestResults) => {
|
|
||||||
context.global.setSync('addResult', function (v) {
|
|
||||||
__brunoTestResults.addResult(v);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.global.setSync('getResults', function () {
|
|
||||||
return __brunoTestResults.getResults();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.evalSync(`
|
|
||||||
global.expect = require('chai').expect;
|
|
||||||
global.assert = require('chai').assert;
|
|
||||||
|
|
||||||
global.__brunoTestResults = {
|
|
||||||
addResult: global.addResult,
|
|
||||||
getResults: global.getResults,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
global.DummyChaiAssertionError = class DummyChaiAssertionError extends Error {
|
|
||||||
constructor(message, props, ssf) {
|
|
||||||
super(message);
|
|
||||||
this.name = "AssertionError";
|
|
||||||
Object.assign(this, props);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
global.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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
global.test = Test(__brunoTestResults);
|
|
||||||
`);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addTestShimToContext;
|
|
@ -1,20 +1,13 @@
|
|||||||
const ivm = require('isolated-vm');
|
const ivm = require('isolated-vm');
|
||||||
const addBruShimToContext = require('./shims/bru');
|
const addBruShimToContext = require('./shims/bru');
|
||||||
const addQuickBruShimToContext = require('./shims/bru-quick');
|
|
||||||
|
|
||||||
const addBrunoRequestShimToContext = require('./shims/bruno-request');
|
const addBrunoRequestShimToContext = require('./shims/bruno-request');
|
||||||
const addQuickBrunoRequestShimToContext = require('./shims/bruno-request-quick');
|
|
||||||
|
|
||||||
const addBrunoResponseShimToContext = require('./shims/bruno-response');
|
|
||||||
const addQuickBrunoResponseShimToContext = require('./shims/bruno-response-quick');
|
|
||||||
|
|
||||||
const addConsoleShimToContext = require('./shims/console');
|
const addConsoleShimToContext = require('./shims/console');
|
||||||
const addTestShimToContext = require('./shims/test-quick');
|
const addBrunoResponseShimToContext = require('./shims/bruno-response');
|
||||||
|
const addTestShimToContext = require('./shims/test');
|
||||||
const addLibraryShimsToContext = require('./shims/lib');
|
const addLibraryShimsToContext = require('./shims/lib');
|
||||||
const { getQuickJS, newQuickJSAsyncWASMModule } = require('quickjs-emscripten');
|
|
||||||
|
|
||||||
// execute `npm run build:isolated-vm:inbuilt-modules` if the below file doesn't exist
|
// execute `npm run build:isolated-vm:inbuilt-modules` if the below file doesn't exist
|
||||||
const getBundledCode = require('../../bundle-browser-rollup');
|
const getBundledCode = require('../bundle-browser-rollup');
|
||||||
const addSleepShimToContext = require('./shims/sleep');
|
const addSleepShimToContext = require('./shims/sleep');
|
||||||
|
|
||||||
const toNumber = (value) => {
|
const toNumber = (value) => {
|
||||||
@ -79,151 +72,93 @@ const executeInIsolatedVMAsync = async ({
|
|||||||
return toNumber(externalScript);
|
return toNumber(externalScript);
|
||||||
}
|
}
|
||||||
let result;
|
let result;
|
||||||
|
const isolate = new ivm.Isolate();
|
||||||
try {
|
try {
|
||||||
// const QuickJS = await getQuickJS()
|
const context = await isolate.createContext();
|
||||||
// const vm = QuickJS.newContext();
|
await context.global.set('global', context.global.derefInto());
|
||||||
|
|
||||||
const module = await newQuickJSAsyncWASMModule()
|
context.evalSync(`
|
||||||
const runtime = module.newRuntime()
|
let bru = {};
|
||||||
const vm = runtime.newContext()
|
let req = {};
|
||||||
// context.evalSync(`
|
let res = {};
|
||||||
// let bru = {};
|
|
||||||
// let req = {};
|
|
||||||
// let res = {};
|
|
||||||
// let console = {};
|
|
||||||
// global.requireObject = {};
|
|
||||||
// `);
|
|
||||||
|
|
||||||
const bundledCode = getBundledCode?.toString() || '';
|
|
||||||
let bundledScript = `(${bundledCode})()`;
|
|
||||||
|
|
||||||
bundledScript += `
|
|
||||||
globalThis.require = (module) => {
|
|
||||||
return globalThis.requireObject[module];
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
bundledScript += `
|
|
||||||
let bru = {
|
|
||||||
cwd: __bruno__cwd,
|
|
||||||
getEnvName: __bruno__getEnvName,
|
|
||||||
getProcessEnv: __bruno__getProcessEnv,
|
|
||||||
getEnvVar: __bruno__getEnvVar,
|
|
||||||
setEnvVar: __bruno__setEnvVar,
|
|
||||||
getVar: __bruno__getVar,
|
|
||||||
setVar: __bruno__setVar,
|
|
||||||
setNextRequest: __bruno__setNextRequest,
|
|
||||||
visualize: __bruno__visualize,
|
|
||||||
getSecretVar: __bruno__getSecretVar
|
|
||||||
};
|
|
||||||
let req = {
|
|
||||||
url: __bruno__req__url,
|
|
||||||
method: __bruno__req__method,
|
|
||||||
headers: __bruno__req__headers,
|
|
||||||
body: __bruno__req__body,
|
|
||||||
timeout: __bruno__req__timeout,
|
|
||||||
getUrl: __bruno__req__getUrl,
|
|
||||||
setUrl: __bruno__req__setUrl,
|
|
||||||
getMethod: __bruno__req__getMethod,
|
|
||||||
getAuthMode: __bruno__req__getAuthMode,
|
|
||||||
setMethod: __bruno__req__setMethod,
|
|
||||||
getHeaders: __bruno__req__getHeaders,
|
|
||||||
setHeaders: __bruno__req__setHeaders,
|
|
||||||
getHeader: __bruno__req__getHeader,
|
|
||||||
setHeader: __bruno__req__setHeader
|
|
||||||
getBody: __bruno__req__getBody,
|
|
||||||
setBody: __bruno__req__setBody,
|
|
||||||
setMaxRedirects: __bruno__req__setMaxRedirects,
|
|
||||||
getTimeout: __bruno__req__getTimeout,
|
|
||||||
setTimeout: __bruno__req__setTimeout
|
|
||||||
};
|
|
||||||
let res = {
|
|
||||||
status: __bruno__res__status,
|
|
||||||
headers: __bruno__res__headers,
|
|
||||||
body: __bruno__res__body,
|
|
||||||
responseTime: __bruno__res__responseTime,
|
|
||||||
getStatus: __bruno__res__getStatus,
|
|
||||||
getHeader: __bruno__res__getHeader,
|
|
||||||
getHeaders: __bruno__res__getHeaders,
|
|
||||||
getBody: __bruno__res__getBody,
|
|
||||||
getResponseTime: __bruno__res__getResponseTime
|
|
||||||
};
|
|
||||||
let console = {};
|
let console = {};
|
||||||
`;
|
global.requireObject = {};
|
||||||
|
`);
|
||||||
|
|
||||||
|
context.global.setSync('log', function (...args) {
|
||||||
|
console.debug(...args);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const bundledCode = getBundledCode?.toString() || '';
|
||||||
|
await context.eval(`(${bundledCode})()`);
|
||||||
|
} catch (err) {
|
||||||
|
console.debug('Error bundling libraries', err);
|
||||||
|
}
|
||||||
|
|
||||||
const { bru, req, res, test, __brunoTestResults, console: consoleFn } = externalContext;
|
const { bru, req, res, test, __brunoTestResults, console: consoleFn } = externalContext;
|
||||||
|
|
||||||
bru && addQuickBruShimToContext(vm, bru);
|
bru && addBruShimToContext(context, bru);
|
||||||
req && addQuickBrunoRequestShimToContext(vm, req);
|
req && addBrunoRequestShimToContext(context, req);
|
||||||
res && addQuickBrunoResponseShimToContext(vm, res);
|
res && addBrunoResponseShimToContext(context, res);
|
||||||
// consoleFn && addConsoleShimToContext(context, consoleFn);
|
consoleFn && addConsoleShimToContext(context, consoleFn);
|
||||||
// addSleepShimToContext(context);
|
addSleepShimToContext(context);
|
||||||
|
|
||||||
// await addLibraryShimsToContext(context);
|
await context.eval(
|
||||||
|
`
|
||||||
test && __brunoTestResults && addTestShimToContext(vm, __brunoTestResults);
|
global.require = (module) => {
|
||||||
|
return global.requireObject[module];
|
||||||
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 {
|
await addLibraryShimsToContext(context);
|
||||||
constructor(message, props, ssf) {
|
|
||||||
super(message);
|
|
||||||
this.name = "AssertionError";
|
|
||||||
Object.assign(this, props);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
globalThis.Test = (__brunoTestResults) => (description, callback) => {
|
test && __brunoTestResults && (await addTestShimToContext(context, __brunoTestResults));
|
||||||
|
|
||||||
|
context.global.setSync('setResult', function (arg) {
|
||||||
|
result = arg;
|
||||||
|
});
|
||||||
|
|
||||||
|
const jsScriptText = `
|
||||||
|
new Promise(async (resolve, reject) => {
|
||||||
|
// modify the setTimeout function with the shim to work-around the callback-function clone issues
|
||||||
|
setTimeout = global.setTimeout;
|
||||||
|
console?.debug && console.debug('isolated-vm:execution-start:');
|
||||||
try {
|
try {
|
||||||
callback();
|
${externalScript}
|
||||||
__brunoTestResults.addResult({ description, status: "pass" });
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof DummyChaiAssertionError) {
|
console?.debug && console.debug('isolated-vm:execution-end:with-error', error?.message);
|
||||||
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.",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// console.log(error);
|
console?.debug && console.debug('isolated-vm:execution-end:');
|
||||||
}
|
resolve();
|
||||||
};
|
});
|
||||||
|
|
||||||
globalThis.test = Test(__brunoTestResults);
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
bundledScript += externalScript;
|
const templateLiteralText = `
|
||||||
|
let value = \`${externalScript}\`;
|
||||||
|
setResult(value);
|
||||||
|
`;
|
||||||
|
|
||||||
const result = await vm.evalCodeAsync(bundledScript);
|
const jsExpressionText = `
|
||||||
console.log('Result:', result);
|
let value = ${externalScript};
|
||||||
if (result.error) {
|
setResult(value);
|
||||||
console.log("Execution failed:", vm.dump(result.error))
|
`;
|
||||||
result.error.dispose()
|
|
||||||
} else {
|
let scriptText =
|
||||||
console.log("Success:", vm.dump(result.value))
|
scriptType === 'template-literal'
|
||||||
result.value.dispose();
|
? templateLiteralText
|
||||||
}
|
: scriptType === 'expression'
|
||||||
vm.dispose();
|
? jsExpressionText
|
||||||
|
: jsScriptText;
|
||||||
|
|
||||||
|
const script = await isolate.compileScript(scriptText);
|
||||||
|
await script.run(context);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error executing the script!', error);
|
console.error('Error executing the script!', error);
|
||||||
}
|
}
|
||||||
|
isolate.dispose();
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
const { marshallToVm } = require('../utils');
|
|
||||||
|
|
||||||
const addBrunoRequestShimToContext = (vm, req) => {
|
|
||||||
const url = marshallToVm(req.getUrl(), vm);
|
|
||||||
const method = marshallToVm(req.getMethod(), vm);
|
|
||||||
const headers = marshallToVm(req.getHeaders(), vm);
|
|
||||||
const body = marshallToVm(req.getBody(), vm);
|
|
||||||
const timeout = marshallToVm(req.getTimeout(), vm);
|
|
||||||
|
|
||||||
vm.setProp(vm.global, '__bruno__requrl', url);
|
|
||||||
vm.setProp(vm.global, '__bruno__reqmethod', method);
|
|
||||||
vm.setProp(vm.global, '__bruno__reqheaders', headers);
|
|
||||||
vm.setProp(vm.global, '__bruno__reqbody', body);
|
|
||||||
vm.setProp(vm.global, '__bruno__reqtimeout', timeout);
|
|
||||||
|
|
||||||
url.dispose();
|
|
||||||
method.dispose();
|
|
||||||
headers.dispose();
|
|
||||||
body.dispose();
|
|
||||||
timeout.dispose();
|
|
||||||
|
|
||||||
// let getUrl = vm.newFunction('__bruno__req__getUrl', function () {
|
|
||||||
// return marshallToVm(req.getUrl(), vm);
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'getUrl', getUrl);
|
|
||||||
// getUrl.dispose();
|
|
||||||
|
|
||||||
// let setUrl = vm.newFunction('__bruno__req__setUrl', function (url) {
|
|
||||||
// req.setUrl(vm.dump(url));
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'setUrl', setUrl);
|
|
||||||
// setUrl.dispose();
|
|
||||||
|
|
||||||
// let getMethod = vm.newFunction('__bruno__req__getMethod', function () {
|
|
||||||
// return marshallToVm(req.getMethod(), vm);
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'getMethod', getMethod);
|
|
||||||
// getMethod.dispose();
|
|
||||||
|
|
||||||
// let getAuthMode = vm.newFunction('__bruno__req__getAuthMode', function () {
|
|
||||||
// return marshallToVm(req.getAuthMode(), vm);
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'getAuthMode', getAuthMode);
|
|
||||||
// getAuthMode.dispose();
|
|
||||||
|
|
||||||
// let setMethod = vm.newFunction('__bruno__req__setMethod', function (method) {
|
|
||||||
// req.setMethod(vm.dump(method));
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'setMethod', setMethod);
|
|
||||||
// setMethod.dispose();
|
|
||||||
|
|
||||||
// let getHeaders = vm.newFunction('__bruno__req__getHeaders', function () {
|
|
||||||
// return marshallToVm(req.getHeaders(), vm);
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'getHeaders', getHeaders);
|
|
||||||
// getHeaders.dispose();
|
|
||||||
|
|
||||||
// let setHeaders = vm.newFunction('__bruno__req__setHeaders', function (headers) {
|
|
||||||
// req.setHeaders(vm.dump(headers));
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'setHeaders', setHeaders);
|
|
||||||
// setHeaders.dispose();
|
|
||||||
|
|
||||||
// let getHeader = vm.newFunction('__bruno__req__getHeader', function (name) {
|
|
||||||
// return marshallToVm(req.getHeader(vm.dump(name)), vm);
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'getHeader', getHeader);
|
|
||||||
// getHeader.dispose();
|
|
||||||
|
|
||||||
// let setHeader = vm.newFunction('__bruno__req__setHeader', function (name, value) {
|
|
||||||
// req.setHeader(vm.dump(name), vm.dump(value));
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'setHeader', setHeader);
|
|
||||||
// setHeader.dispose();
|
|
||||||
|
|
||||||
// let getBody = vm.newFunction('__bruno__req__getBody', function () {
|
|
||||||
// return marshallToVm(req.getBody(), vm);
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'getBody', getBody);
|
|
||||||
// getBody.dispose();
|
|
||||||
|
|
||||||
// let setBody = vm.newFunction('__bruno__req__setBody', function (data) {
|
|
||||||
// req.setBody(vm.dump(data));
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'setBody', setBody);
|
|
||||||
// setBody.dispose();
|
|
||||||
|
|
||||||
// let setMaxRedirects = vm.newFunction('__bruno__req__setMaxRedirects', function (maxRedirects) {
|
|
||||||
// req.setMaxRedirects(vm.dump(maxRedirects));
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'setMaxRedirects', setMaxRedirects);
|
|
||||||
// setMaxRedirects.dispose();
|
|
||||||
|
|
||||||
// let getTimeout = vm.newFunction('__bruno__req__getTimeout', function () {
|
|
||||||
// return marshallToVm(req.getTimeout(), vm);
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'getTimeout', getTimeout);
|
|
||||||
// getTimeout.dispose();
|
|
||||||
|
|
||||||
// let setTimeout = vm.newFunction('__bruno__req__setTimeout', function (timeout) {
|
|
||||||
// req.setTimeout(vm.dump(timeout));
|
|
||||||
// });
|
|
||||||
// vm.setProp(vm.global, 'setTimeout', setTimeout);
|
|
||||||
// setTimeout.dispose();
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = addBrunoRequestShimToContext;
|
|
@ -1,84 +0,0 @@
|
|||||||
const rollup = require('rollup');
|
|
||||||
const { nodeResolve } = require('@rollup/plugin-node-resolve');
|
|
||||||
const commonjs = require('@rollup/plugin-commonjs');
|
|
||||||
const fs = require('fs');
|
|
||||||
const { terser } = require('rollup-plugin-terser');
|
|
||||||
|
|
||||||
const bundleLibraries = async () => {
|
|
||||||
const codeScript = `
|
|
||||||
import { expect, assert } from 'chai';
|
|
||||||
import { Buffer } from "buffer";
|
|
||||||
import moment from "moment";
|
|
||||||
import btoa from "btoa";
|
|
||||||
import atob from "atob";
|
|
||||||
globalThis.expect = expect;
|
|
||||||
globalThis.assert = assert;
|
|
||||||
globalThis.moment = moment;
|
|
||||||
globalThis.btoa = btoa;
|
|
||||||
globalThis.atob = atob;
|
|
||||||
globalThis.Buffer = Buffer;
|
|
||||||
globalThis.requireObject = {
|
|
||||||
'chai': { expect, assert },
|
|
||||||
'moment': moment,
|
|
||||||
'buffer': { Buffer },
|
|
||||||
'btoa': btoa,
|
|
||||||
'atob': atob,
|
|
||||||
};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
input: {
|
|
||||||
input: 'inline-code',
|
|
||||||
plugins: [
|
|
||||||
{
|
|
||||||
name: 'inline-code-plugin',
|
|
||||||
resolveId(id) {
|
|
||||||
if (id === 'inline-code') {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
load(id) {
|
|
||||||
if (id === 'inline-code') {
|
|
||||||
return codeScript;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
nodeResolve({
|
|
||||||
preferBuiltins: false,
|
|
||||||
browser: false
|
|
||||||
}),
|
|
||||||
commonjs(),
|
|
||||||
terser()
|
|
||||||
]
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
file: './src/bundle-browser-rollup.js',
|
|
||||||
format: 'iife',
|
|
||||||
name: 'MyBundle'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const bundle = await rollup.rollup(config.input);
|
|
||||||
const { output } = await bundle.generate(config.output);
|
|
||||||
fs.writeFileSync(
|
|
||||||
'./src/bundle-browser-rollup.js',
|
|
||||||
`
|
|
||||||
const getBundledCode = () => {
|
|
||||||
return function(){
|
|
||||||
${output?.map((o) => o.code).join('\n')}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
module.exports = getBundledCode;
|
|
||||||
`
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error while bundling:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bundleLibraries();
|
|
||||||
|
|
||||||
module.exports = bundleLibraries;
|
|
203
packages/bruno-js/src/sandbox/quickjs/index.js
Normal file
203
packages/bruno-js/src/sandbox/quickjs/index.js
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
const ivm = require('isolated-vm');
|
||||||
|
const addBruShimToContext = require('./shims/bru');
|
||||||
|
const addBrunoRequestShimToContext = require('./shims/bruno-request');
|
||||||
|
const addBrunoResponseShimToContext = require('./shims/bruno-response');
|
||||||
|
const addTestShimToContext = require('./shims/test');
|
||||||
|
const { newQuickJSAsyncWASMModule } = require('quickjs-emscripten');
|
||||||
|
|
||||||
|
// execute `npm run build:isolated-vm:inbuilt-modules` if the below file doesn't exist
|
||||||
|
const getBundledCode = require('../bundle-browser-rollup');
|
||||||
|
|
||||||
|
const toNumber = (value) => {
|
||||||
|
const num = Number(value);
|
||||||
|
return Number.isInteger(num) ? parseInt(value, 10) : parseFloat(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const executeQuickJsVm = ({ script: externalScript, context: externalContext }) => {
|
||||||
|
if (!isNaN(Number(externalScript))) {
|
||||||
|
return Number(externalScript);
|
||||||
|
}
|
||||||
|
let result;
|
||||||
|
const isolate = new ivm.Isolate();
|
||||||
|
try {
|
||||||
|
const context = isolate.createContextSync();
|
||||||
|
context.global.setSync('global', context.global.derefInto());
|
||||||
|
|
||||||
|
const { bru, req, res } = externalContext;
|
||||||
|
|
||||||
|
context.evalSync(`
|
||||||
|
let bru = {};
|
||||||
|
let req = {};
|
||||||
|
let res = {};
|
||||||
|
`);
|
||||||
|
|
||||||
|
bru && addBruShimToContext(context, bru);
|
||||||
|
req && addBrunoRequestShimToContext(context, req);
|
||||||
|
res && addBrunoResponseShimToContext(context, res);
|
||||||
|
|
||||||
|
context.global.setSync('setResult', function (arg) {
|
||||||
|
result = arg;
|
||||||
|
});
|
||||||
|
|
||||||
|
const templateLiteralText = `
|
||||||
|
let value = \`${externalScript}\`;
|
||||||
|
setResult(value);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const jsExpressionText = `
|
||||||
|
let value = ${externalScript};
|
||||||
|
setResult(value);
|
||||||
|
`;
|
||||||
|
|
||||||
|
let scriptText = scriptType === 'template-literal' ? templateLiteralText : jsExpressionText;
|
||||||
|
|
||||||
|
const script = isolate.compileScriptSync(scriptText);
|
||||||
|
script.runSync(context);
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error executing the script!', error);
|
||||||
|
}
|
||||||
|
isolate.dispose();
|
||||||
|
};
|
||||||
|
|
||||||
|
const executeQuickJsVmAsync = async ({
|
||||||
|
script: externalScript,
|
||||||
|
context: externalContext
|
||||||
|
}) => {
|
||||||
|
if (!isNaN(Number(externalScript))) {
|
||||||
|
return toNumber(externalScript);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const module = await newQuickJSAsyncWASMModule()
|
||||||
|
const runtime = module.newRuntime()
|
||||||
|
const vm = runtime.newContext()
|
||||||
|
|
||||||
|
const bundledCode = getBundledCode?.toString() || '';
|
||||||
|
let bundledScript = `(${bundledCode})()`;
|
||||||
|
|
||||||
|
bundledScript += `
|
||||||
|
globalThis.require = (module) => {
|
||||||
|
return globalThis.requireObject[module];
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
bundledScript += `
|
||||||
|
let bru = {
|
||||||
|
cwd: __bruno__cwd,
|
||||||
|
getEnvName: __bruno__getEnvName,
|
||||||
|
getProcessEnv: __bruno__getProcessEnv,
|
||||||
|
getEnvVar: __bruno__getEnvVar,
|
||||||
|
setEnvVar: __bruno__setEnvVar,
|
||||||
|
getVar: __bruno__getVar,
|
||||||
|
setVar: __bruno__setVar,
|
||||||
|
setNextRequest: __bruno__setNextRequest,
|
||||||
|
visualize: __bruno__visualize,
|
||||||
|
getSecretVar: __bruno__getSecretVar
|
||||||
|
};
|
||||||
|
let req = {
|
||||||
|
url: __bruno__req__url,
|
||||||
|
method: __bruno__req__method,
|
||||||
|
headers: __bruno__req__headers,
|
||||||
|
body: __bruno__req__body,
|
||||||
|
timeout: __bruno__req__timeout,
|
||||||
|
getUrl: __bruno__req__getUrl,
|
||||||
|
setUrl: __bruno__req__setUrl,
|
||||||
|
getMethod: __bruno__req__getMethod,
|
||||||
|
setMethod: __bruno__req__setMethod,
|
||||||
|
getAuthMode: __bruno__req__getAuthMode,
|
||||||
|
getHeaders: __bruno__req__getHeaders,
|
||||||
|
setHeaders: __bruno__req__setHeaders,
|
||||||
|
getHeader: __bruno__req__getHeader,
|
||||||
|
setHeader: __bruno__req__setHeader,
|
||||||
|
getBody: __bruno__req__getBody,
|
||||||
|
setBody: __bruno__req__setBody,
|
||||||
|
setMaxRedirects: __bruno__req__setMaxRedirects,
|
||||||
|
getTimeout: __bruno__req__getTimeout,
|
||||||
|
setTimeout: __bruno__req__setTimeout
|
||||||
|
};
|
||||||
|
let res = {
|
||||||
|
status: globalThis.__bruno__res__status,
|
||||||
|
headers: globalThis.__bruno__res__headers,
|
||||||
|
body: globalThis.__bruno__res__body,
|
||||||
|
responseTime: globalThis.__bruno__res__responseTime,
|
||||||
|
getStatus: globalThis.__bruno__res__getStatus,
|
||||||
|
getHeader: globalThis.__bruno__res__getHeader,
|
||||||
|
getHeaders: globalThis.__bruno__res__getHeaders,
|
||||||
|
getBody: globalThis.__bruno__res__getBody,
|
||||||
|
getResponseTime: globalThis.__bruno__res__getResponseTime
|
||||||
|
};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const { bru, req, res, test, __brunoTestResults, console: consoleFn } = externalContext;
|
||||||
|
|
||||||
|
bru && addBruShimToContext(vm, bru);
|
||||||
|
req && addBrunoRequestShimToContext(vm, req);
|
||||||
|
res && addBrunoResponseShimToContext(vm, res);
|
||||||
|
|
||||||
|
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) => (description, callback) => {
|
||||||
|
try {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
globalThis.test = Test(__brunoTestResults);
|
||||||
|
`;
|
||||||
|
|
||||||
|
bundledScript += externalScript;
|
||||||
|
|
||||||
|
const result = await vm.evalCodeAsync(bundledScript);
|
||||||
|
if (result.error) {
|
||||||
|
console.log("Execution failed:", vm.dump(result.error))
|
||||||
|
result.error.dispose()
|
||||||
|
} else {
|
||||||
|
result.value.dispose();
|
||||||
|
}
|
||||||
|
vm.dispose();
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error executing the script!', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
executeQuickJsVm,
|
||||||
|
executeQuickJsVmAsync
|
||||||
|
};
|
107
packages/bruno-js/src/sandbox/quickjs/shims/bruno-request.js
Normal file
107
packages/bruno-js/src/sandbox/quickjs/shims/bruno-request.js
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
const { marshallToVm } = require('../utils');
|
||||||
|
|
||||||
|
const addBrunoRequestShimToContext = (vm, req) => {
|
||||||
|
const url = marshallToVm(req.getUrl(), vm);
|
||||||
|
const method = marshallToVm(req.getMethod(), vm);
|
||||||
|
const headers = marshallToVm(req.getHeaders(), vm);
|
||||||
|
const body = marshallToVm(req.getBody(), vm);
|
||||||
|
const timeout = marshallToVm(req.getTimeout(), vm);
|
||||||
|
|
||||||
|
vm.setProp(vm.global, '__bruno__req__url', url);
|
||||||
|
vm.setProp(vm.global, '__bruno__req__method', method);
|
||||||
|
vm.setProp(vm.global, '__bruno__req__headers', headers);
|
||||||
|
vm.setProp(vm.global, '__bruno__req__body', body);
|
||||||
|
vm.setProp(vm.global, '__bruno__req__timeout', timeout);
|
||||||
|
|
||||||
|
url.dispose();
|
||||||
|
method.dispose();
|
||||||
|
headers.dispose();
|
||||||
|
body.dispose();
|
||||||
|
timeout.dispose();
|
||||||
|
|
||||||
|
let getUrl = vm.newFunction('getUrl', function () {
|
||||||
|
return marshallToVm(req.getUrl(), vm);
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__getUrl', getUrl);
|
||||||
|
getUrl.dispose();
|
||||||
|
|
||||||
|
let setUrl = vm.newFunction('setUrl', function (url) {
|
||||||
|
req.setUrl(vm.dump(url));
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__setUrl', setUrl);
|
||||||
|
setUrl.dispose();
|
||||||
|
|
||||||
|
let getMethod = vm.newFunction('getMethod', function () {
|
||||||
|
return marshallToVm(req.getMethod(), vm);
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__getMethod', getMethod);
|
||||||
|
getMethod.dispose();
|
||||||
|
|
||||||
|
let getAuthMode = vm.newFunction('getAuthMode', function () {
|
||||||
|
return marshallToVm(req.getAuthMode(), vm);
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__getAuthMode', getAuthMode);
|
||||||
|
getAuthMode.dispose();
|
||||||
|
|
||||||
|
let setMethod = vm.newFunction('setMethod', function (method) {
|
||||||
|
req.setMethod(vm.dump(method));
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__setMethod', setMethod);
|
||||||
|
setMethod.dispose();
|
||||||
|
|
||||||
|
let getHeaders = vm.newFunction('getHeaders', function () {
|
||||||
|
return marshallToVm(req.getHeaders(), vm);
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__getHeaders', getHeaders);
|
||||||
|
getHeaders.dispose();
|
||||||
|
|
||||||
|
let setHeaders = vm.newFunction('setHeaders', function (headers) {
|
||||||
|
req.setHeaders(vm.dump(headers));
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__setHeaders', setHeaders);
|
||||||
|
setHeaders.dispose();
|
||||||
|
|
||||||
|
let getHeader = vm.newFunction('getHeader', function (name) {
|
||||||
|
return marshallToVm(req.getHeader(vm.dump(name)), vm);
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__getHeader', getHeader);
|
||||||
|
getHeader.dispose();
|
||||||
|
|
||||||
|
let setHeader = vm.newFunction('setHeader', function (name, value) {
|
||||||
|
req.setHeader(vm.dump(name), vm.dump(value));
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__setHeader', setHeader);
|
||||||
|
setHeader.dispose();
|
||||||
|
|
||||||
|
let getBody = vm.newFunction('getBody', function () {
|
||||||
|
return marshallToVm(req.getBody(), vm);
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__getBody', getBody);
|
||||||
|
getBody.dispose();
|
||||||
|
|
||||||
|
let setBody = vm.newFunction('setBody', function (data) {
|
||||||
|
req.setBody(vm.dump(data));
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__setBody', setBody);
|
||||||
|
setBody.dispose();
|
||||||
|
|
||||||
|
let setMaxRedirects = vm.newFunction('setMaxRedirects', function (maxRedirects) {
|
||||||
|
req.setMaxRedirects(vm.dump(maxRedirects));
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__setMaxRedirects', setMaxRedirects);
|
||||||
|
setMaxRedirects.dispose();
|
||||||
|
|
||||||
|
let getTimeout = vm.newFunction('getTimeout', function () {
|
||||||
|
return marshallToVm(req.getTimeout(), vm);
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__getTimeout', getTimeout);
|
||||||
|
getTimeout.dispose();
|
||||||
|
|
||||||
|
let setTimeout = vm.newFunction('setTimeout', function (timeout) {
|
||||||
|
req.setTimeout(vm.dump(timeout));
|
||||||
|
});
|
||||||
|
vm.setProp(vm.global, '__bruno__req__setTimeout', setTimeout);
|
||||||
|
setTimeout.dispose();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = addBrunoRequestShimToContext;
|
@ -3,6 +3,10 @@ const marshallToVm = (value, vm) => {
|
|||||||
return vm.undefined;
|
return vm.undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value === null) {
|
||||||
|
return vm.null;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
return vm.newString(value);
|
return vm.newString(value);
|
||||||
} else if (typeof value === "number") {
|
} else if (typeof value === "number") {
|
||||||
@ -13,13 +17,13 @@ const marshallToVm = (value, vm) => {
|
|||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
const arr = vm.newArray();
|
const arr = vm.newArray();
|
||||||
for (let i = 0; i < value.length; i++) {
|
for (let i = 0; i < value.length; i++) {
|
||||||
vm.setElement(arr, i, marshallToVm(value[i]));
|
vm.setProp(arr, i, marshallToVm(value[i], vm));
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
} else {
|
} else {
|
||||||
const obj = vm.newObject();
|
const obj = vm.newObject();
|
||||||
for (const key in value) {
|
for (const key in value) {
|
||||||
vm.setProp(obj, key, marshallToVm(value[key]));
|
vm.setProp(obj, key, marshallToVm(value[key], vm));
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
@ -5,28 +5,7 @@ meta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get {
|
get {
|
||||||
url: https://testbench-sanity.usebruno.com/ping
|
url: {{host}}/ping
|
||||||
body: none
|
body: none
|
||||||
auth: none
|
auth: none
|
||||||
}
|
}
|
||||||
|
|
||||||
script:pre-request {
|
|
||||||
// const moment = require("moment");
|
|
||||||
// function a() {
|
|
||||||
// return moment().format("hh:mm");
|
|
||||||
// return test;
|
|
||||||
// }
|
|
||||||
// a();
|
|
||||||
}
|
|
||||||
|
|
||||||
tests {
|
|
||||||
test("should get var in scripts", function() {
|
|
||||||
expect("bruno-test-87267").to.equal("bruno-test-87267");
|
|
||||||
});
|
|
||||||
// const moment = require("moment");
|
|
||||||
// function a() {
|
|
||||||
// return moment().format("hh:mm");
|
|
||||||
// return test;
|
|
||||||
// }
|
|
||||||
// a();
|
|
||||||
}
|
|
||||||
|
@ -10,7 +10,6 @@ get {
|
|||||||
auth: none
|
auth: none
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
assert {
|
assert {
|
||||||
res.status: eq 200
|
res.status: eq 200
|
||||||
res.body: eq pong
|
res.body: eq pong
|
||||||
|
Loading…
Reference in New Issue
Block a user