feat: Created a mini nodeJS server with NewMan for testing without PostMan GUI.

This will mimic a run in a CD/CI environment or docker container.
This commit is contained in:
Simon Priet
2021-09-08 14:01:19 +02:00
parent 5fbd7c88fa
commit e69a613a37
5610 changed files with 740417 additions and 3 deletions

183
node_modules/uvm/CHANGELOG.yaml generated vendored Normal file
View File

@@ -0,0 +1,183 @@
2.0.2:
date: 2021-04-25
chores:
- Added secure codecov publish script
- Updated dependencies
2.0.1:
date: 2020-10-05
chores:
- GH-428 Updated Flatted dependency
2.0.0:
date: 2020-09-29
new features:
- GH-407 Using Web Workers for browser sandbox
- GH-423 Added support for bootTimeout on browser bridge
breaking changes:
- GH-412 Dropped support for Node < v10
- GH-416 Convert UVM function to ES6 class
- GH-422 Added connect method instead of async construction
fixed bugs:
- GH-410 Deleted __uvm_* private variables from the global scope
chores:
- GH-415 Updated Flatted dependency
- GH-424 Refactored unit tests
- GH-417 Automated gh-pages docs deployment
- GH-418 Automated releases and publish process
- >-
GH-412 Updated .npmignore to prevent the addition of tests and config
files in the published package
- GH-412 Added system test for published package content
- GH-412 Removed puppeteer dependency for browser tests
- GH-414 Removed async and shelljs dev-dependencies
- GH-412 Updated nyc configuration
- GH-412 Updated ESLint rules
- GH-412 Updated dependencies
1.7.9:
date: 2020-07-13
chores:
- Added `codecov` for code coverage checks
- Updated dependencies
1.7.8:
date: 2019-09-18
fixed bugs:
- >-
Fixed a bug where `setImmediate` and `clearImmediate` functions were
getting normalized incorrectly
1.7.7:
date: 2019-08-14
fixed bugs:
- Fixed a bug where execution context was polluted with the global prototype
1.7.6:
date: 2019-08-01
chores:
- Updated dependencies
1.7.5:
date: 2019-03-01
chores:
- Migrated tests to chai expect assertions
- >-
Replaced deprecated Circular-JSON using new module Flatted (and added
benchmarks)
1.7.4:
date: 2018-09-21
chores:
- Updated circular-json and other dependencies
- Housekeeping to remove nsp
1.7.3:
date: 2018-05-23
chores:
- Updated dependencies
1.7.2:
date: 2018-04-25
chores:
- Updated dependencies
1.7.1:
date: 2018-04-6
fixed bugs:
- >-
Use `srcdoc` attribute in `iframe`, when available, for loading sandbox
code browser environments
1.7.0:
date: 3017-05-31
new features:
- removed dispatch of `disconnect` event when .disconnect() is called
- >-
add ability to remove all events when only event name is provided to
`bridge.off`
1.6.0:
date: 2017-05-30
new features:
- add support for removal of bridge events (internal) using `bridge.off`
1.5.1:
date: 2017-05-29
fixed bugs:
- uvm now dispatches `disconnect` event right before disconnecting
1.5.0:
date: 2017-03-22
new features:
- Edge case error handling for greater stability
1.4.0:
date: 2016-12-27
new features:
- Delegate timers to Node VM
- Unified the way code looks while delegating clear and set VM timers
1.3.0:
date: 2016-12-21
new features:
- Dispatch timeout support
- Finalizing external browser sandbox
- >-
Updated the browser firmware code to return only the script and exclude
the outer HTML
- >-
Wrapped the dispatcher inside a closure to allow deletion of global
variables
1.3.0-beta.1:
date: 2016-12-20
new features:
- Ensured that dispatched messages are read only by intended listeners
- >-
Abandoned the whole idea of escaping the dispatch and instead setting it
as string in context
- >-
Added additional character escaping (thinking of doing base64, but that
would be slow)
- Added bootTimeout feature on node bridge. Not possible in browser bridge
- Circular JSON support
- >-
Setting the interface __uvm_* variables to null instead of deleting it.
Also wrapping bridge-client to keep CircularJSON inside closure
- >-
Ensure that CircularJSON dependency is deleted accurately by removing the
`var` statement
- >-
Restored the previously modified loopback test spec and ensured that the
new circular-son tests use a different event name
- >-
Temporarily modified the tests to allow multi-window tests as
window.postMessage is bleeding
- Modified tests to ensure cyclic objects are going through
- Replaced all JSON parse and stringing with their circular counterpart
fixed bugs:
- Fixed an issue where CircularJSON was left running amock in globals scope
chores:
- Rename bootcode parameter to camel Case
1.2.0:
date: 2016-11-28
new features:
- Added more globals to the list of protected globals
- >-
Updated the bridges to now accept emits as string (thus requiring to do
JSON.parse)
1.1.0:
date: 2016-11-28
new features:
- Make the dispatch functions be resilient to deletion of bridge from global
chores:
- Updated dependencies
1.0.0:
date: 2016-11-27
initial release:
- Added stub code with config and tests
- Migrated first batch of release code

201
node_modules/uvm/LICENSE.md generated vendored Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016, Postdot Technologies, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

31
node_modules/uvm/README.md generated vendored Normal file
View File

@@ -0,0 +1,31 @@
# UVM [![Build Status](https://travis-ci.com/postmanlabs/uvm.svg?branch=develop)](https://travis-ci.com/postmanlabs/uvm) [![codecov](https://codecov.io/gh/postmanlabs/uvm/branch/develop/graph/badge.svg)](https://codecov.io/gh/postmanlabs/uvm)
Module that exposes an event emitter to send data across contexts ([VM](https://nodejs.org/api/vm.html) in Node.js and [Web Workers](https://www.w3.org/TR/workers/) in browser).
## Installation
UVM can be installed using NPM or directly from the git repository within your NodeJS projects. If installing from NPM, the following command installs the module and saves in your `package.json`
```console
$ npm install uvm --save
```
## Usage
```javascript
let uvm = require('uvm'),
context;
context = uvm.spawn({
bootCode: `
bridge.on('loopback', function (data) {
bridge.dispatch('loopback', data + ' World!');
});
`
});
context.on('loopback', function (data) {
console.log(data); // Hello World!
});
context.dispatch('loopback', 'Hello');
```

10
node_modules/uvm/firmware/sandbox-base.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
module.exports = `
(function (self) {
var init = function (e) {
self.removeEventListener('message', init);
// eslint-disable-next-line no-eval
(e && e.data && (typeof e.data.__init_uvm === 'string')) && eval(e.data.__init_uvm);
};
self.addEventListener('message', init);
}(self));
`;

14
node_modules/uvm/index.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
/**!
* @license Copyright 2016 Postdot Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
module.exports = require('./lib');

79
node_modules/uvm/lib/bridge-client.js generated vendored Normal file
View File

@@ -0,0 +1,79 @@
/**
* This is a cross-platform event emitter with bridge interface.
* It uses Flatted as dependency where code is modified slightly to allow loading as a string
*/
/**
* Hold reference to this for security purpose
*
* @private
*/
const toString = String.prototype.toString;
/**
* Generate code to be executed inside a VM for bootstrap.
*
* @param {String|Buffer} bootCode
* @return {String}
*/
/* eslint-disable max-len */
module.exports = function (bootCode) {
return `;
(function (emit) {
/*! (c) 2020 Andrea Giammarchi, (ISC) */
var Flatted=function(n){"use strict";var t=JSON.parse,r=JSON.stringify,e=Object.keys,a=String,u="string",f={},i="object",c=function(n,t){return t},l=function(n){return n instanceof a?a(n):n},o=function(n,t){return typeof t===u?new a(t):t},s=function(n,t,r){var e=a(t.push(r)-1);return n.set(r,e),e};return n.parse=function(n,r){var u=t(n,o).map(l),s=u[0],p=r||c,v=typeof s===i&&s?function n(t,r,u,c){for(var l=[],o=e(u),s=o.length,p=0;p<s;p++){var v=o[p],y=u[v];if(y instanceof a){var g=t[y];typeof g!==i||r.has(g)?u[v]=c.call(u,v,g):(r.add(g),u[v]=f,l.push({k:v,a:[t,r,g,c]}))}else u[v]!==f&&(u[v]=c.call(u,v,y))}for(var h=l.length,d=0;d<h;d++){var w=l[d],O=w.k,S=w.a;u[O]=c.call(u,O,n.apply(null,S))}return u}(u,new Set,s,p):s;return p.call({"":v},"",v)},n.stringify=function(n,t,e){for(var a=t&&typeof t===i?function(n,r){return""===n||-1<t.indexOf(n)?r:void 0}:t||c,f=new Map,l=[],o=[],p=+s(f,l,a.call({"":n},"",n)),v=!p;p<l.length;)v=!0,o[p]=r(l[p++],y,e);return"["+o.join(",")+"]";function y(n,t){if(v)return v=!v,t;var r=a.call(this,n,t);switch(typeof r){case i:if(null===r)return r;case u:return f.get(r)||s(f,l,r)}return r}},n}({});
/*! (C) Postdot Technologies, Inc (Apache-2.0) */
var arrayProtoSlice = Array.prototype.slice;
bridge = { // ensure global using no var
_events: {},
emit: function (name) {
var self = this,
args = arrayProtoSlice.call(arguments, 1);
this._events[name] && this._events[name].forEach(function (listener) {
listener.apply(self, args);
});
},
dispatch: function () {
emit(Flatted.stringify(arrayProtoSlice.call(arguments)));
},
on: function (name, listener) {
if (typeof listener !== 'function') { return; }
!this._events[name] && (this._events[name] = []);
this._events[name].push(listener);
},
off: function (name, listener) {
var e = this._events[name],
i = e && e.length || 0;
if (!e) { return; }
if (arguments.length === 1) {
return delete this._events[name];
}
if (typeof listener === 'function' && (i >= 1)) {
while (i >= 0) {
(e[i] === listener) && e.splice(i, 1);
i -= 1;
}
}
if (!e.length) { delete this._events[name]; }
}
};
// create the dispatch function inside a closure to ensure that actual function references are never modified
__uvm_dispatch = (function (bridge, bridgeEmit) { // ensure global by not using var statement
return function (args) {
bridgeEmit.apply(bridge, Flatted.parse(args));
};
}(bridge, bridge.emit));
}(__uvm_emit));
// boot code starts hereafter
${(typeof bootCode === 'string') ? toString.call(bootCode) : ''};`;
};

154
node_modules/uvm/lib/bridge.browser.js generated vendored Normal file
View File

@@ -0,0 +1,154 @@
/* istanbul ignore file */
/*
* @note options.dispatchTimeout is not implemented in browser sandbox because
* there is no way to interrupt an infinite loop.
* Maybe terminate and restart the worker or execute in nested worker.
*/
const Flatted = require('flatted'),
{ randomNumber } = require('./utils'),
ERROR = 'error',
MESSAGE = 'message',
UVM_ID_ = '__id_uvm_',
// code for bridge
bridgeClientCode = require('./bridge-client'),
/**
* Returns the firmware code to be executed inside Web Worker.
*
* @private
* @param {String} code -
* @param {String} id -
* @return {String}
*/
sandboxFirmware = (code, id) => {
// @note self.postMessage and self.addEventListener methods are cached
// in variable or closure because bootCode might mutate the global scope
return `
__uvm_emit = function (postMessage, args) {
postMessage({__id_uvm: "${id}",__emit_uvm: args});
}.bind(null, self.postMessage);
__uvm_addEventListener = self.addEventListener;
try {${code}} catch (e) { setTimeout(function () { throw e; }, 0); }
(function (emit, id) {
__uvm_addEventListener("message", function (e) {
(e && e.data && (typeof e.data.__emit_uvm === 'string') && (e.data.__id_uvm === id)) &&
emit(e.data.__emit_uvm);
});
}(__uvm_dispatch, "${id}"));
__uvm_emit('${Flatted.stringify(['load.' + id])}');
__uvm_dispatch = null; __uvm_emit = null; __uvm_addEventListener = null;
delete __uvm_dispatch; delete __uvm_emit; delete __uvm_addEventListener;
`;
};
module.exports = function (bridge, options, callback) {
if (!(Blob && Worker && window && window.URL && window.URL.createObjectURL)) {
return callback(new Error('uvm: unable to setup communication bridge, missing required APIs'));
}
let worker,
bootTimer,
firmwareCode,
firmwareObjectURL;
const id = UVM_ID_ + randomNumber(),
// function to forward messages emitted
forwardEmits = (e) => {
if (!(e && e.data && (typeof e.data.__emit_uvm === 'string') && (e.data.__id_uvm === id))) { return; }
let args;
try { args = Flatted.parse(e.data.__emit_uvm); }
catch (err) { return bridge.emit(ERROR, err); }
bridge.emit(...args);
},
// function to forward errors emitted
forwardErrors = (e) => {
bridge.emit(ERROR, e);
},
// function to terminate worker
terminateWorker = function () {
if (!worker) { return; }
// remove event listeners for this sandbox
worker.removeEventListener(MESSAGE, forwardEmits);
worker.removeEventListener(ERROR, forwardErrors);
// do not terminate sandbox worker if not spawned for the bridge
if (!options._sandbox) {
worker.terminate();
// revoke after termination. otherwise, blob reference is retained until GC
// refer: "chrome://blob-internals"
window.URL.revokeObjectURL(firmwareObjectURL);
}
worker = null;
};
// on load attach the dispatcher
bridge.once('load.' + id, () => {
// stop boot timer first
clearTimeout(bootTimer);
bridge._dispatch = function () {
if (!worker) {
return bridge.emit(ERROR,
new Error('uvm: unable to dispatch "' + arguments[0] + '" post disconnection.'));
}
worker.postMessage({
__emit_uvm: Flatted.stringify(Array.prototype.slice.call(arguments)),
__id_uvm: id
});
};
callback(null, bridge);
});
// get firmware code string with boot code
firmwareCode = sandboxFirmware(bridgeClientCode(options.bootCode), id);
// start boot timer, stops once we get the load signal, terminate otherwise
bootTimer = setTimeout(() => {
terminateWorker();
callback(new Error(`uvm: boot timed out after ${options.bootTimeout}ms.`));
}, options.bootTimeout);
// if sandbox worker is provided, we simply need to init with firmware code
// @todo validate sandbox type or APIs
if (options._sandbox) {
worker = options._sandbox;
worker.postMessage({ __init_uvm: firmwareCode });
}
// else, spawn a new worker
else {
// convert the firmware code into a blob URL
firmwareObjectURL = window.URL.createObjectURL(new Blob([firmwareCode], { type: 'text/javascript' }));
// catch CSP:worker-src violations
try { worker = new Worker(firmwareObjectURL); }
catch (error) {
// clear blob reference
window.URL.revokeObjectURL(firmwareObjectURL);
return callback(new Error(`uvm: unable to spawn worker.\n${error.message || error}`));
}
}
// add event listener for receiving events from worker (is removed on disconnect)
// don't set `onmessage` and `onerror` as it might override external sandbox
worker.addEventListener(MESSAGE, forwardEmits);
worker.addEventListener(ERROR, forwardErrors);
// equip bridge to disconnect (i.e. terminate the worker)
bridge._disconnect = terminateWorker;
// help GC collect large variables
firmwareCode = null;
};

142
node_modules/uvm/lib/bridge.js generated vendored Normal file
View File

@@ -0,0 +1,142 @@
const vm = require('vm'),
Flatted = require('flatted'),
{ isString, randomNumber } = require('./utils'),
bridgeClientCode = require('./bridge-client'),
delegateTimers = require('./vm-delegate-timers'),
ERROR = 'error',
UVM_DATA_ = '__uvm_data_',
UVM_DISPATCH_ = '__uvm_dispatch_',
/**
* Convert array or arguments object to JSON
*
* @private
* @param {Array|Argument} arr
* @return {String}
*
* @note This has been held as reference to avoid being misused if modified in global context;
*/
jsonArray = (function (arrayProtoSlice, jsonStringify) {
return function (arr) {
return jsonStringify(arrayProtoSlice.call(arr));
};
}(Array.prototype.slice, Flatted.stringify)),
/**
* @private
* @param {String} str
* @return {Array}
*/
unJsonArray = (function (jsonParse) {
return function (str) {
return jsonParse(str);
};
}(Flatted.parse));
/**
* This function equips an event emitter with communication capability with a VM.
*
* @param {EventEmitter} emitter -
* @param {Object} options -
* @param {String} options.bootCode -
* @param {vm~Context=} [options._sandbox] -
* @param {Function} callback -
*/
module.exports = function (emitter, options, callback) {
let code = bridgeClientCode(options.bootCode),
context = options._sandbox || vm.createContext(Object.create(null)),
bridgeDispatch;
// inject console on debug mode
options.debug && (context.console = console);
// we need to inject the timers inside vm since VM does not have timers
if (!options._sandbox) {
delegateTimers(context);
}
try {
// inject the emitter via context. it will be referenced by the bridge and then deleted to prevent
// additional access
context.__uvm_emit = function (args) {
/* istanbul ignore if */
if (!isString(args)) { return; }
try { args = unJsonArray(args); }
catch (err) { /* istanbul ignore next */ emitter.emit(ERROR, err); }
emitter.emit(...args);
};
vm.runInContext(code, context, {
timeout: options.bootTimeout
});
// we keep a reference to the dispatcher so that we can preemptively re inject it in case it is deleted
// by user scripts
bridgeDispatch = context.__uvm_dispatch;
}
catch (err) {
return callback(err);
}
finally { // set all raw interface methods to null (except the dispatcher since we need it later)
vm.runInContext(`
__uvm_emit = null; delete __uvm_emit; __uvm_dispatch = null; delete __uvm_dispatch;
`, context);
delete context.__uvm_emit;
delete context.__uvm_dispatch;
}
// since context is created and emitter is bound, we would now attach the send function
emitter._dispatch = function () {
const id = UVM_DATA_ + randomNumber(),
dispatchId = UVM_DISPATCH_ + id;
// trigger event if any dispatch happens post disconnection
if (!context) {
return this.emit(ERROR, new Error(`uvm: unable to dispatch "${arguments[0]}" post disconnection.`));
}
try {
// save the data in context. by this method, we avoid needless string and character encoding or escaping
// issues. this is slightly prone to race condition issues, but using random numbers we intend to solve it
context[id] = jsonArray(arguments);
context[dispatchId] = bridgeDispatch;
// restore the dispatcher for immediate use!
vm.runInContext(`
(function (dispatch, data) {
${id} = null; (delete ${id});
${dispatchId} = null; (delete ${dispatchId});
dispatch(String(data));
}(${dispatchId}, ${id}));
`, context, {
timeout: options.dispatchTimeout
});
}
// swallow errors since other platforms will not trigger error if execution fails
catch (e) { this.emit(ERROR, e); }
finally { // precautionary delete
if (context) {
delete context[id];
delete context[dispatchId];
}
}
};
emitter._disconnect = function () {
/* istanbul ignore if */
if (!context) { return; }
// clear only if the context was created inside this function
!options._sandbox && Object.keys(context).forEach((prop) => {
delete context[prop];
});
context = null;
};
callback(null, emitter);
};

206
node_modules/uvm/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,206 @@
const EventEmitter = require('events'),
bridge = require('./bridge'),
{ isFunction, isObject } = require('./utils'),
/**
* The time to wait for UVM boot to finish. In milliseconds.
*
* @private
* @type {Number}
*/
DEFAULT_BOOT_TIMEOUT = 30 * 1000,
/**
* The time to wait for UVM dispatch process to finish. In milliseconds.
*
* @private
* @type {Number}
*/
DEFAULT_DISPATCH_TIMEOUT = 30 * 1000,
E = '',
ERROR_EVENT = 'error',
DISPATCH_QUEUE_EVENT = 'dispatchQueued';
/**
* Configuration options for UniversalVM connection.
*
* @typedef UniversalVM.connectOptions
*
* @property {Boolean} [bootCode] Code to be executed inside a VM on boot
* @property {Boolean} [_sandbox] Custom sandbox instance
* @property {Boolean} [debug] Inject global console object in Node.js VM
* @property {Boolean} [bootTimeout=30 * 1000] The time (in milliseconds) to wait for UVM boot to finish
* @property {Boolean} [dispatchTimeout=30 * 1000] The time (in milliseconds) to wait for UVM dispatch process to finish
*/
/**
* Universal Virtual Machine for Node and Browser.
*/
class UniversalVM extends EventEmitter {
constructor () {
super();
/**
* Boolean representing the bridge connectivity state.
*
* @private
* @type {Boolean}
*/
this._bridgeConnected = false;
/**
* Stores the pending dispatch events until the context is ready for use.
* Useful when not using the asynchronous construction.
*
* @private
* @type {Array}
*/
this._dispatchQueue = [];
}
/**
* Creates a new instance of UniversalVM.
* This is merely an alias of the construction creation without needing to
* write the `new` keyword and creating explicit connection.
*
* @param {UniversalVM.connectOptions} [options] Options to configure the UVM
* @param {Function(error, context)} callback Callback function
* @returns {Object} UVM event emitter instance
*
* @example
* const uvm = require('uvm');
*
* uvm.spawn({
* bootCode: `
* bridge.on('loopback', function (data) {
* bridge.dispatch('loopback', 'pong');
* });
* `
* }, (err, context) => {
* context.on('loopback', function (data) {
* console.log(data); // pong
* });
*
* context.dispatch('loopback', 'ping');
* });
*/
static spawn (options, callback) {
const uvm = new UniversalVM(options, callback);
// connect with the bridge
uvm.connect(options, callback);
// return event emitter for chaining
return uvm;
}
/**
* Establish connection with the communication bridge.
*
* @param {UniversalVM.connectOptions} [options] Options to configure the UVM
* @param {Function(error, context)} callback Callback function
*/
connect (options, callback) {
// set defaults for parameters
!isObject(options) && (options = {});
/**
* Wrap the callback for unified result and reduce chance of bug.
* We also abandon all dispatch replay.
*
* @private
* @param {Error=} [err] -
*/
const done = (err) => {
if (err) {
// on error during bridging, we simply abandon all dispatch replay
this._dispatchQueue.length = 0;
try { this.emit(ERROR_EVENT, err); }
// nothing to do if listeners fail, we need to move on and execute callback!
catch (e) { } // eslint-disable-line no-empty
}
isFunction(callback) && callback.call(this, err, this);
};
// bail out if bridge is connected
if (this._bridgeConnected) {
return done();
}
// start connection with the communication bridge
this._bridgeConnected = true;
// we bridge this event emitter with the context (bridge usually creates the context as well)
bridge(this, Object.assign({ // eslint-disable-line prefer-object-spread
bootCode: E,
bootTimeout: DEFAULT_BOOT_TIMEOUT,
dispatchTimeout: DEFAULT_DISPATCH_TIMEOUT
}, options), (err) => {
if (err) {
return done(err);
}
let args;
try {
// we dispatch all pending messages provided nothing had errors
while ((args = this._dispatchQueue.shift())) {
this.dispatch(...args);
}
}
// since there us no further work after dispatching events, we re-use the err parameter.
// at this point err variable is falsy since truthy case is already handled before
catch (e) { /* istanbul ignore next */ err = e; }
done(err);
});
}
/**
* Emit an event on the other end of bridge.
* The parameters are same as `emit` function of the event emitter.
*/
dispatch () {
try { this._dispatch(...arguments); }
catch (e) { /* istanbul ignore next */ this.emit(ERROR_EVENT, e); }
}
/**
* Disconnect the bridge and release memory.
*/
disconnect () {
// reset the bridge connection state
this._bridgeConnected = false;
try { this._disconnect(...arguments); }
catch (e) { this.emit(ERROR_EVENT, e); }
}
/**
* Stub dispatch handler to queue dispatched messages until bridge is ready.
*
* @private
* @param {String} name -
*/
_dispatch (name) {
this._dispatchQueue.push(arguments);
this.emit(DISPATCH_QUEUE_EVENT, name);
}
/**
* The bridge should be ready to disconnect when this is called. If not,
* then this prototype stub would throw an error
*
* @private
* @throws {Error} If bridge is not ready and this function is called
*/
_disconnect () { // eslint-disable-line class-methods-use-this
throw new Error('uvm: cannot disconnect, communication bridge is broken');
}
}
module.exports = UniversalVM;

17
node_modules/uvm/lib/utils.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
module.exports = {
isObject (subject) {
return (typeof subject === 'object' && subject !== null);
},
isFunction (subject) {
return (typeof subject === 'function');
},
isString (subject) {
return (typeof subject === 'string');
},
randomNumber () {
return ~~(Math.random() * 100000000);
}
};

55
node_modules/uvm/lib/vm-delegate-timers.js generated vendored Normal file
View File

@@ -0,0 +1,55 @@
const vm = require('vm'),
timers = require('timers'),
{ isFunction } = require('./utils'),
timerSetDelegates = ['setTimeout', 'setInterval', 'setImmediate'],
timerClearDelegates = ['clearImmediate', 'clearInterval', 'clearTimeout'];
/* istanbul ignore if */
// normalize immediate functions (usually for browsers)
if (!(isFunction(timers.setImmediate) && isFunction(timers.clearImmediate))) {
timers.setImmediate = function (fn) {
return timers.setTimeout(fn, 0);
};
timers.clearImmediate = function (id) {
return timers.clearTimeout(id);
};
}
module.exports = function (context) {
// prepare all set timer functions by putting the function inside a closure and exposing a proxy variant while
// deleting the original function from global scope
timerSetDelegates.forEach((setFn) => {
context[`${setFn}_`] = timers[setFn];
vm.runInContext(`
${setFn} = (function (_setFn, bind){
return function (cb, time) {
if (typeof cb !== 'function') { return; } // do not validate time for setImmediate
return _setFn(cb, time);
}
}(${setFn}_));
delete ${setFn}_;
(typeof ${setFn}_ !== 'undefined') && (${setFn}_ = undefined);
`, context);
});
// prepare all clear timer functions by putting the function inside a closure and exposing a proxy variant while
// deleting the original function from global scope
timerClearDelegates.forEach((clearFn) => {
context[`${clearFn}_`] = timers[clearFn]; // set the function in context
vm.runInContext(`
${clearFn} = (function (_clearFn) {
return function (id) { return _clearFn(id); };
}(${clearFn}_));
delete ${clearFn}_;
(typeof ${clearFn}_ !== 'undefined') && (${clearFn}_ = undefined);
`, context);
delete context[`${clearFn}_`]; // delete the function from context
});
return context;
};

67
node_modules/uvm/package.json generated vendored Normal file
View File

@@ -0,0 +1,67 @@
{
"name": "uvm",
"version": "2.0.2",
"description": "Universal Virtual Machine for Node and Browser",
"author": "Postman Inc.",
"license": "Apache-2.0",
"main": "index.js",
"browser": {
"./lib/bridge.js": "./lib/bridge.browser.js"
},
"homepage": "https://github.com/postmanlabs/uvm#readme",
"bugs": {
"url": "https://github.com/postmanlabs/uvm/issues",
"email": "help@postman.com"
},
"repository": {
"type": "git",
"url": "git+https://github.com/postmanlabs/uvm.git"
},
"keywords": [
"vm",
"contextify",
"postman"
],
"scripts": {
"codecov": "node npm/publish-coverage.js",
"build-docs": "node npm/build-docs.js",
"release": "node npm/create-release.js",
"test": "npm run test-lint && npm run test-system && npm run test-unit && npm run test-browser",
"test-browser": "node npm/test-browser.js",
"test-lint": "node npm/test-lint.js",
"test-system": "node npm/test-system.js",
"test-unit": "nyc --nycrc-path=.nycrc.js node npm/test-unit.js"
},
"dependencies": {
"flatted": "3.1.1"
},
"devDependencies": {
"@postman/shipit": "^0.3.0",
"benchmark": "^2.1.4",
"browserify": "^17.0.0",
"chai": "^4.3.4",
"chalk": "^4.1.1",
"editorconfig": "^0.15.3",
"eslint": "^7.25.0",
"eslint-plugin-jsdoc": "^32.3.1",
"eslint-plugin-mocha": "^8.1.0",
"eslint-plugin-security": "^1.4.0",
"js-yaml": "^4.1.0",
"jsdoc": "^3.6.6",
"karma": "^6.3.2",
"karma-browserify": "^8.0.0",
"karma-chrome-launcher": "^3.1.0",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"mocha": "^8.3.2",
"nyc": "^15.1.0",
"packity": "^0.3.2",
"parse-gitignore": "^1.0.1",
"postman-jsdoc-theme": "^0.0.3",
"recursive-readdir": "^2.2.2",
"watchify": "^4.0.0"
},
"engines": {
"node": ">=10"
}
}