Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@globocom/backstage-functions-sandbox

Package Overview
Dependencies
Maintainers
12
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@globocom/backstage-functions-sandbox - npm Package Compare versions

Comparing version 0.5.3 to 0.6.0-next.0

docs/desenho_functions_sandbox.excalidraw

1

index.js
module.exports = require('./lib/Sandbox');
module.exports.executeFunctionInSandbox = require('./lib/ForkSandbox').executeFunctionInSandbox;
module.exports.PrefixLog = require('./lib/PrefixLog');
module.exports.MemoryStream = require('./lib/MemoryStream');

@@ -67,5 +67,6 @@ const vm = require('vm');

this.config = config || {};
this.activeTimers = []
}
createEmptyContext(backstageOptions, prefix = null, extraEnv = null, console = null) {
createEmptyContext(backstageOptions, prefix = null, extraEnv = null, console = null, objsList={}) {
const exports = {};

@@ -98,3 +99,12 @@

this.context.Buffer = Buffer;
this.context.setTimeout = setTimeout;
this.context.setTimeout = (func, delay) => {
const timeoutId = setTimeout(func, delay);
objsList.timerList.push(timeoutId)
return timeoutId
}
this.context.setInterval = (func, interval) => {
const intervalId = setInterval(func, interval);
objsList.intervalList.push(intervalId)
return intervalId
}
this.context.clearTimeout = clearTimeout;

@@ -120,3 +130,4 @@ this.context.exports = exports;

const script = new vm.Script(text, { filename, displayErrors: false, lineOffset: -1 });
const context = this.createEmptyContext({}, prefix || filename, null, console);
let objsCounter = { intervalList: [], timerList: []}
const context = this.createEmptyContext({}, prefix || filename, null, console, objsCounter);
script.runInContext(context, { timeout: this.syncTimeout });

@@ -143,2 +154,17 @@ } catch (e) {

hasPendingObjects(objsList) {
return (objsList.timerList.length > 0) || (objsList.intervalList.length > 0);
}
finishPendingObjects(objsList) {
if (!objsList) return;
if (objsList.timerList) {
objsList.timerList.forEach((timeoutId) => clearTimeout(timeoutId));
}
if (objsList.intervalList) {
objsList.intervalList.forEach((intervalId) => clearInterval(intervalId));
}
}
runScript(script, req, { prefix, env, console, span } = {}) {

@@ -166,2 +192,3 @@ return new Promise((accept, reject) => {

const sandboxRes = new Response({ callback });
let objsList = { intervalList: [], timerList: []}
const context = this.createEmptyContext({

@@ -171,6 +198,7 @@ request: sandboxReq,

span,
}, prefix, env, console);
}, prefix, env, console, objsList);
const vmDomain = domain.create();
vmDomain.on('error', (err) => {
this.finishPendingObjects(objsList)
callback(err);

@@ -180,2 +208,3 @@ });

vmDomain.run(() => {
const result = script.runInContext(context, {

@@ -190,2 +219,3 @@ timeout: this.syncTimeout,

.then((body) => {
this.finishPendingObjects(objsList)
sandboxRes.send(body);

@@ -196,3 +226,5 @@ })

});
return
}
this.finishPendingObjects(objsList)
});

@@ -199,0 +231,0 @@ });

3

package.json
{
"name": "@globocom/backstage-functions-sandbox",
"version": "0.5.3",
"version": "0.6.0-next.0",
"description": "Sandbox for Backstage functions",

@@ -30,2 +30,3 @@ "main": "index.js",

"dependencies": {
"node-fetch": "^2.5.0",
"once": "^1.4.0",

@@ -32,0 +33,0 @@ "stack-trace": "^0.0.9"

@@ -35,2 +35,3 @@ [![Build Status](https://travis-ci.org/globocom/functions-sandbox.png?branch=master)](https://travis-ci.org/globocom/functions-sandbox)

// express.Request compatible

@@ -50,2 +51,46 @@ const req = {

## Example of usage (with child_process)
```javascript
const { executeFunctionInSandbox } = require('backstage-functions-sandbox/lib/ForkSandbox');
const myCode = `
async function main(req, res) {
const result = req.body.x * req.body.y;
const name = Backstage.env.MY_VAR;
// you could call await here
return { name, result };
}
`;
const req = {
headers: {},
query: {},
body: { x: 10, y: 10}
};
const taskId = `${namespace}/${id}-${Date.now()}`; //or can be any uniq id
executeFunctionInSandbox(taskId, {
env: {
MY_VAR: 'TRUE', // environment variable will be available on Backstage.env.MY_VAR
},
globalModules: [ 'path' ], // put all available modules that will allow to import
asyncTimeout: 10000,
syncTimeout: 300,
preCode: code, // not required to compile using sandbox.Compilecode
req,
namespace: "foo",
functionName: "bar",
options,
})
/* can return result using callback or using async await */
.then(result => {
console.log(result)
})
.catch(err => {
console.log(err)
})
```
## Configuration

@@ -52,0 +97,0 @@

@@ -69,3 +69,3 @@ const expect = require('chai').expect;

it('should return context with setTimeout', () => {
expect(context.setTimeout).to.equal(setTimeout);
expect(context.setTimeout).to.exist;
});

@@ -141,3 +141,3 @@

expect(result.error).to.be.eql('SyntaxError: Unexpected token }');
expect(result.error).to.be.eql('SyntaxError: Unexpected token \'}\'');
expect(result.stack).to.be.eql('');

@@ -301,26 +301,2 @@ });

describe('when code has an error in anonymous function', () => {
it('should resolve promise as rejected', (done) => {
const filename = 'test.js';
const code = `
function main(req, res) {
setTimeout(() => {
throw new Error('An error');
}, 10);
}
`;
const script = testSandbox.compileCode(filename, code);
testSandbox
.runScript(script, {})
.then(() => {
done(new Error('It is expected an error'));
}, (error) => {
expect(error.message).to.be.eql('An error');
done();
})
.catch(err => done(err));
});
});
describe('when code has an not declared variable', () => {

@@ -327,0 +303,0 @@ it('should resolve promise as rejected by "strict mode"', (done) => {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc