Skip to content

Commit

Permalink
Merge pull request #640 from postmanlabs/feat/block-globals-in-execution
Browse files Browse the repository at this point in the history
Allow blocking globals in specific executions
  • Loading branch information
codenirvana authored Mar 13, 2024
2 parents cc7fb82 + d60ea9f commit c7732f7
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
unreleased:
new features:
- GH-640 Added option to allow blocking globals in specific executions

2.1.0:
date: 2024-02-28
new features:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ An asynchronous script will require an explicit call of a global function `__exi
```javascript
myscope.set('setTimeout', global.setTimeout); // inject setTimeout

// note the 2nd parameter is set to `true` for async
myscope.exec('setTimeout(function () { __exitscope(null); }, 1000)', true, function (err) {
// note the 2nd parameter is set to `{ async: true }`
myscope.exec('setTimeout(function () { __exitscope(null); }, 1000)', { async: true }, function (err) {
err ? console.error(err.stack || err) : console.log('execution complete');
});
```
Expand Down
20 changes: 14 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,25 @@ class Uniscope {
* Executes a string within a protected Uniscope of controlled set of globals.
*
* @param {String} code A string representing a JavaScript expression, statement, or sequence of statements
* @param {Boolean} [async=false] When set to true, callback will be called when `__exitscope` is triggered
* @param {Object} [options] An object of options for the exec
* @param {Boolean} [options.async=false] When set to true, callback will be called when `__exitscope` is triggered
* @param {String[]} [options.block] Specify a set of global variables that will not be allowed to trickle in
* @param {Function} callback Callback function to be called at the end of execution
*/
exec (code, async, callback) {
exec (code, options, callback) {
// allow polymorphic parameter to enable async functions
// and validate the primary code parameter
if (async && !callback) {
callback = async;
async = false;
if (options && !callback) {
callback = options;
options = {};
}

if (typeof options === 'boolean') {
options = { async: options };
}

const async = Boolean(options && options.async);

if (!util.isFunction(callback)) { throw new Error(ERROR_CALLBACK_MISSING); }
if (!util.isString(code)) { return callback(new TypeError(ERROR_CODE_MUST_BE_STRING)); }

Expand Down Expand Up @@ -233,7 +241,7 @@ class Uniscope {
});

// based on Uniscope configuration, the globals that we block are specifically set to undefined
util.forEach(blocked, (key) => {
util.forEach(blocked.concat(options.block || []), (key) => {
let position = globals.indexOf(key);

(position === -1) && (position = globals.length);
Expand Down
33 changes: 33 additions & 0 deletions test/unit/scope-exec.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,37 @@ describe('scope module exec', function () {
expect(d).to.equal(4);
`, done);
});

it('should allow blocking globals in specific executions', function (done) {
scope.set('myGlobal', 'my_global');

scope.set('blockedExecution', function () {
scope.exec(`
expect(myGlobal).to.equal(undefined);
unblockedExecution(); // call execution from inside the blocked scope
try {
Function('return myGlobal')();
throw new Error('myGlobal is not blocked');
} catch (e) {
expect(e).to.be.an('error');
expect(e.message).to.equal('myGlobal is not defined');
}
`, { block: ['myGlobal'] }, function (err) {
expect(err, 'error in blockedExecution').to.be.undefined;
});
});

scope.set('unblockedExecution', function () {
scope.exec(`
expect(myGlobal).to.equal('my_global');
`, function (err) {
expect(err, 'error in unblockedExecution').to.be.undefined;
});
});

scope.exec(`
blockedExecution();
unblockedExecution();
`, done);
});
});

0 comments on commit c7732f7

Please sign in to comment.