@usebruno/js 0.43.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,23 +1,20 @@
1
1
  {
2
2
  "name": "@usebruno/js",
3
- "version": "0.43.0",
3
+ "version": "0.45.0",
4
4
  "license": "MIT",
5
5
  "main": "src/index.js",
6
6
  "files": [
7
7
  "src",
8
8
  "package.json"
9
9
  ],
10
- "peerDependencies": {
11
- "@usebruno/vm2": "^3.9.13"
12
- },
13
10
  "scripts": {
14
11
  "test": "node --experimental-vm-modules $(npx which jest) --testPathIgnorePatterns test.js",
15
12
  "sandbox:bundle-libraries": "node ./src/sandbox/bundle-libraries.js",
16
13
  "prepack": "npm run test"
17
14
  },
18
15
  "dependencies": {
19
- "@usebruno/common": "0.16.0",
20
- "@usebruno/query": "0.1.0",
16
+ "@usebruno/common": "0.18.0",
17
+ "@usebruno/query": "0.2.0",
21
18
  "ajv": "^8.12.0",
22
19
  "ajv-formats": "^2.1.1",
23
20
  "atob": "^2.1.2",
@@ -28,12 +25,11 @@
28
25
  "cheerio": "^1.0.0",
29
26
  "crypto-js": "^4.2.0",
30
27
  "json-query": "^2.2.2",
31
- "jsonwebtoken": "^9.0.2",
28
+ "jsonwebtoken": "^9.0.3",
32
29
  "lodash": "^4.17.21",
33
30
  "moment": "^2.29.4",
34
31
  "nanoid": "3.3.8",
35
- "node-fetch": "2.7.0",
36
- "node-vault": "^0.10.2",
32
+ "node-fetch": "^2.7.0",
37
33
  "path": "^0.12.7",
38
34
  "quickjs-emscripten": "^0.29.2",
39
35
  "tv4": "^1.3.0",
@@ -46,8 +42,5 @@
46
42
  "@rollup/plugin-node-resolve": "^15.0.1",
47
43
  "rollup": "3.29.5",
48
44
  "rollup-plugin-terser": "^7.0.2"
49
- },
50
- "overrides": {
51
- "@postman/tunnel-agent":"0.6.4"
52
45
  }
53
46
  }
package/src/bru.js CHANGED
@@ -2,13 +2,32 @@ const { cloneDeep } = require('lodash');
2
2
  const { uuid } = require('./utils');
3
3
  const xmlFormat = require('xml-formatter');
4
4
  const { interpolate: _interpolate } = require('@usebruno/common');
5
- const { sendRequest } = require('@usebruno/requests').scripting;
5
+ const { sendRequest, createSendRequest } = require('@usebruno/requests').scripting;
6
6
  const { jar: createCookieJar } = require('@usebruno/requests').cookies;
7
7
 
8
8
  const variableNameRegex = /^[\w-.]*$/;
9
9
 
10
10
  class Bru {
11
- constructor(envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName, promptVariables) {
11
+ /**
12
+ * @param {string} runtime - The runtime environment ('quickjs' or 'nodevm')
13
+ * @param {object} envVariables - Environment variables
14
+ * @param {object} runtimeVariables - Runtime variables
15
+ * @param {object} processEnvVars - Process environment variables
16
+ * @param {string} collectionPath - Path to the collection
17
+ * @param {function} historyLogger - History logger function
18
+ * @param {function} setVisualizations - Visualizations setter function
19
+ * @param {object} secretVariables - Secret variables
20
+ * @param {object} collectionVariables - Collection-level variables
21
+ * @param {object} folderVariables - Folder-level variables
22
+ * @param {object} requestVariables - Request-level variables
23
+ * @param {object} globalEnvironmentVariables - Global environment variables
24
+ * @param {object} oauth2CredentialVariables - OAuth2 credential variables
25
+ * @param {object} iterationDetails - Iteration details for runner
26
+ * @param {string} collectionName - Name of the collection
27
+ * @param {object} promptVariables - Prompt variables
28
+ * @param {object} certsAndProxyConfig - Configuration for bru.sendRequest (proxy, certs, TLS)
29
+ */
30
+ constructor(runtime, envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName, promptVariables, certsAndProxyConfig) {
12
31
  this.envVariables = envVariables || {};
13
32
  this.runtimeVariables = runtimeVariables || {};
14
33
  this.promptVariables = promptVariables || {};
@@ -23,11 +42,13 @@ class Bru {
23
42
  this.historyLogger = historyLogger;
24
43
  this.setVisualizations = setVisualizations;
25
44
  this.collectionName = collectionName;
26
- this.sendRequest = sendRequest;
45
+ // Use createSendRequest with config if provided, otherwise use default sendRequest
46
+ this.sendRequest = certsAndProxyConfig ? createSendRequest(certsAndProxyConfig) : sendRequest;
47
+ this.runtime = runtime;
27
48
  this.cookies = {
28
49
  jar: () => {
29
50
  const cookieJar = createCookieJar();
30
-
51
+
31
52
  return {
32
53
  getCookie: (url, cookieName, callback) => {
33
54
  const interpolatedUrl = this.interpolate(url);
@@ -82,7 +103,7 @@ class Bru {
82
103
  iterationData: new IterationDataManager(iterationDetails?.iterationData),
83
104
  iterationIndex: iterationDetails?.iterationIndex,
84
105
  totalIterations: iterationDetails?.totalIterations
85
- };
106
+ };
86
107
 
87
108
  this.utils = {
88
109
  minifyJson: (json) => {
@@ -128,7 +149,6 @@ class Bru {
128
149
  }
129
150
  };
130
151
  }
131
-
132
152
 
133
153
  interpolate = (strOrObj) => {
134
154
  if (!strOrObj) return strOrObj;
@@ -179,7 +199,7 @@ class Bru {
179
199
  if (!key) {
180
200
  throw new Error('Creating a env variable without specifying a name is not allowed.');
181
201
  }
182
-
202
+
183
203
  if (variableNameRegex.test(key) === false) {
184
204
  throw new Error(
185
205
  `Variable name: "${key}" contains invalid characters! Names must only contain alpha-numeric characters, "-", "_", "."`
@@ -242,8 +262,8 @@ class Bru {
242
262
 
243
263
  if (variableNameRegex.test(key) === false) {
244
264
  throw new Error(
245
- `Variable name: "${key}" contains invalid characters!` +
246
- ' Names must only contain alpha-numeric characters, "-", "_", "."'
265
+ `Variable name: "${key}" contains invalid characters!`
266
+ + ' Names must only contain alpha-numeric characters, "-", "_", "."'
247
267
  );
248
268
  }
249
269
 
@@ -251,19 +271,19 @@ class Bru {
251
271
  this.historyLogger({
252
272
  uid: uuid(),
253
273
  type: 'setVar()',
254
- data: { key, value: this.interpolate(value) },
274
+ data: { key, value: value },
255
275
  createdAt: new Date().toISOString()
256
276
  });
257
277
  }
258
278
 
259
- this.runtimeVariables[key] = this.interpolate(value);
279
+ this.runtimeVariables[key] = value;
260
280
  }
261
281
 
262
282
  getVar(key) {
263
283
  if (variableNameRegex.test(key) === false) {
264
284
  throw new Error(
265
- `Variable name: "${key}" contains invalid characters!` +
266
- ' Names must only contain alpha-numeric characters, "-", "_", "."'
285
+ `Variable name: "${key}" contains invalid characters!`
286
+ + ' Names must only contain alpha-numeric characters, "-", "_", "."'
267
287
  );
268
288
  }
269
289
 
@@ -298,12 +318,10 @@ class Bru {
298
318
  this.nextRequest = nextRequest;
299
319
  }
300
320
 
301
-
302
321
  getSecretVar(key) {
303
322
  return this.secretVariables?.[`$secrets.${key}`];
304
323
  }
305
324
 
306
-
307
325
  visualize(type, data) {
308
326
  if (type == 'table') {
309
327
  if (data?.provider == 'ag-grid') {
@@ -332,6 +350,10 @@ class Bru {
332
350
  getCollectionName() {
333
351
  return this.collectionName;
334
352
  }
353
+
354
+ isSafeMode() {
355
+ return this.runtime === 'quickjs';
356
+ }
335
357
  }
336
358
 
337
359
  class IterationDataManager {
@@ -8,7 +8,7 @@ class BrunoRequest {
8
8
  * - req.headers
9
9
  * - req.timeout
10
10
  * - req.body
11
- *
11
+ *
12
12
  * Above shorthands are useful for accessing the request properties directly in the scripts
13
13
  * It must be noted that the user cannot set these properties directly.
14
14
  * They should use the respective setter methods to set these properties.
@@ -22,13 +22,14 @@ class BrunoRequest {
22
22
  this.timeout = req.timeout;
23
23
  this.historyLogger = historyLogger;
24
24
  this.name = req.name;
25
+ this.pathParams = req.pathParams;
25
26
  this.tags = req.tags || [];
26
27
  /**
27
28
  * We automatically parse the JSON body if the content type is JSON
28
29
  * This is to make it easier for the user to access the body directly
29
- *
30
+ *
30
31
  * It must be noted that the request data is always a string and is what gets sent over the network
31
- * If the user wants to access the raw data, they can use getBody({raw: true}) method
32
+ * If the user wants to access the raw data, they can use getBody({raw: true}) method
32
33
  */
33
34
  const isJson = this.hasJSONContentType(this.req.headers);
34
35
  if (isJson) {
@@ -45,9 +46,57 @@ class BrunoRequest {
45
46
  this.req.url = url;
46
47
  }
47
48
 
49
+ getHost() {
50
+ try {
51
+ const url = new URL(this.req.url);
52
+ return url.host;
53
+ } catch (e) {
54
+ return '';
55
+ }
56
+ }
57
+
58
+ getPath() {
59
+ try {
60
+ const url = new URL(this.req.url);
61
+ let pathname = url.pathname;
62
+
63
+ // If path params exist, interpolate them into the pathname
64
+ if (this.req.pathParams && Array.isArray(this.req.pathParams)) {
65
+ pathname = pathname
66
+ .split('/')
67
+ .map((segment) => {
68
+ if (segment.startsWith(':')) {
69
+ const paramName = segment.slice(1);
70
+ const pathParam = this.req.pathParams.find((param) => param.name === paramName);
71
+ if (pathParam && pathParam.value) {
72
+ return pathParam.value;
73
+ }
74
+ }
75
+ return segment;
76
+ })
77
+ .join('/');
78
+ }
79
+
80
+ return pathname;
81
+ } catch (e) {
82
+ return '';
83
+ }
84
+ }
85
+
86
+ getQueryString() {
87
+ try {
88
+ const url = new URL(this.req.url);
89
+ // Return query string without the leading '?'
90
+ return url.search ? url.search.substring(1) : '';
91
+ } catch (e) {
92
+ return '';
93
+ }
94
+ }
95
+
48
96
  getMethod() {
49
97
  return this.req.method;
50
98
  }
99
+
51
100
  getAuthMode() {
52
101
  if (this.req?.oauth2) {
53
102
  return 'oauth2';
@@ -104,7 +153,7 @@ class BrunoRequest {
104
153
 
105
154
  /**
106
155
  * Get the body of the request
107
- *
156
+ *
108
157
  * We automatically parse and return the JSON body if the content type is JSON
109
158
  * If the user wants the raw body, they can pass the raw option as true
110
159
  */
@@ -128,7 +177,7 @@ class BrunoRequest {
128
177
  * Otherwise
129
178
  * - We set the request data as the data itself
130
179
  * - We set the body property as the data itself
131
- *
180
+ *
132
181
  * If the user wants to override this behavior, they can pass the raw option as true
133
182
  */
134
183
  setBody(data, options = {}) {
@@ -140,7 +189,7 @@ class BrunoRequest {
140
189
  createdAt: new Date().toISOString()
141
190
  });
142
191
  }
143
-
192
+
144
193
  if (options.raw) {
145
194
  this.req.data = data;
146
195
  this.body = data;
@@ -170,7 +219,7 @@ class BrunoRequest {
170
219
  this.timeout = timeout;
171
220
  this.req.timeout = timeout;
172
221
  }
173
-
222
+
174
223
  onFail(callback) {
175
224
  if (typeof callback === 'function') {
176
225
  this.req.onFailHandler = callback;
@@ -198,7 +247,6 @@ class BrunoRequest {
198
247
  __isObject(obj) {
199
248
  return obj !== null && typeof obj === 'object';
200
249
  }
201
-
202
250
 
203
251
  disableParsingResponseJson() {
204
252
  this.req.__brunoDisableParsingResponseJson = true;
@@ -212,6 +260,16 @@ class BrunoRequest {
212
260
  return this.req.name;
213
261
  }
214
262
 
263
+ getPathParams() {
264
+ const params = Array.isArray(this.req.pathParams) ? this.req.pathParams : [];
265
+
266
+ return params.map((param) => ({
267
+ name: param.name,
268
+ value: param.value,
269
+ type: param.type
270
+ }));
271
+ }
272
+
215
273
  /**
216
274
  * Get the tags associated with this request
217
275
  * @returns {Array<string>} Array of tag strings
@@ -55,6 +55,20 @@ class BrunoResponse {
55
55
  const clonedData = _.cloneDeep(data);
56
56
  this.res.data = clonedData;
57
57
  this.body = clonedData;
58
+
59
+ // Update dataBuffer to match the modified body
60
+ if (clonedData === null || clonedData === undefined) {
61
+ this.res.dataBuffer = Buffer.from('');
62
+ } else if (typeof clonedData === 'string') {
63
+ this.res.dataBuffer = Buffer.from(clonedData);
64
+ } else {
65
+ // For objects, stringify them
66
+ try {
67
+ this.res.dataBuffer = Buffer.from(JSON.stringify(clonedData));
68
+ } catch (e) {
69
+ this.res.dataBuffer = Buffer.from('');
70
+ }
71
+ }
58
72
  }
59
73
 
60
74
  // TODO: Refactor: dataBuffer size calculation should be handled in a shared utility so it can be passed and reused across the application
@@ -65,7 +79,7 @@ class BrunoResponse {
65
79
 
66
80
  const { data, dataBuffer, headers } = this.res;
67
81
  let bodySize = 0;
68
-
82
+
69
83
  // Use raw received bytes
70
84
  if (Buffer.isBuffer(dataBuffer)) {
71
85
  bodySize = dataBuffer.length;
@@ -94,7 +108,6 @@ class BrunoResponse {
94
108
  const headerSize = Buffer.byteLength(headerLines.join('\r\n'));
95
109
 
96
110
  return { header: headerSize, body: bodySize, total: headerSize + bodySize };
97
-
98
111
  }
99
112
 
100
113
  getDataBuffer() {
@@ -241,7 +241,7 @@ const evaluateRhsOperand = (rhsOperand, operator, context, runtime) => {
241
241
 
242
242
  class AssertRuntime {
243
243
  constructor(props) {
244
- this.runtime = props?.runtime || 'vm2';
244
+ this.runtime = props?.runtime || 'quickjs';
245
245
  }
246
246
 
247
247
  runAssertions(assertions, request, response, envVariables, runtimeVariables, processEnvVars, historyLogger, secretVariables) {
@@ -257,7 +257,9 @@ class AssertRuntime {
257
257
  return [];
258
258
  }
259
259
 
260
+ const certsAndProxyConfig = request?.certsAndProxyConfig;
260
261
  const bru = new Bru(
262
+ this.runtime,
261
263
  envVariables,
262
264
  runtimeVariables,
263
265
  processEnvVars,
@@ -272,7 +274,8 @@ class AssertRuntime {
272
274
  oauth2CredentialVariables,
273
275
  iterationDetails,
274
276
  undefined,
275
- promptVariables
277
+ promptVariables,
278
+ certsAndProxyConfig
276
279
  );
277
280
  const req = new BrunoRequest(request, historyLogger);
278
281
  const res = createResponseParser(response);
@@ -1,45 +1,15 @@
1
- const { NodeVM } = require('@usebruno/vm2');
2
- const path = require('path');
3
- const http = require('http');
4
- const https = require('https');
5
- const stream = require('stream');
6
- const util = require('util');
7
- const zlib = require('zlib');
8
- const url = require('url');
9
- const punycode = require('punycode');
10
- const fs = require('fs');
11
- const { get } = require('lodash');
1
+ const chai = require('chai');
12
2
  const Bru = require('../bru');
13
3
  const BrunoRequest = require('../bruno-request');
14
4
  const BrunoResponse = require('../bruno-response');
15
5
  const { cleanJson } = require('../utils');
16
6
  const { createBruTestResultMethods } = require('../utils/results');
17
7
  const { runScriptInNodeVm } = require('../sandbox/node-vm');
18
-
19
- // Inbuilt Library Support
20
- const ajv = require('ajv');
21
- const addFormats = require('ajv-formats');
22
- const atob = require('atob');
23
- const btoa = require('btoa');
24
- const lodash = require('lodash');
25
- const moment = require('moment');
26
- const uuid = require('uuid');
27
- const nanoid = require('nanoid');
28
- const axios = require('axios');
29
- const fetch = require('node-fetch');
30
- const chai = require('chai');
31
- const CryptoJS = require('crypto-js');
32
- const NodeVault = require('node-vault');
33
- const xml2js = require('xml2js');
34
- const cheerio = require('cheerio');
35
- const tv4 = require('tv4');
36
- const jsonwebtoken = require('jsonwebtoken');
37
8
  const { executeQuickJsVmAsync } = require('../sandbox/quickjs');
38
- const { mixinTypedArrays } = require('../sandbox/mixins/typed-arrays');
39
9
 
40
10
  class ScriptRuntime {
41
11
  constructor(props) {
42
- this.runtime = props?.runtime || 'vm2';
12
+ this.runtime = props?.runtime || 'quickjs';
43
13
  }
44
14
 
45
15
  // This approach is getting out of hand
@@ -61,7 +31,7 @@ class ScriptRuntime {
61
31
  let visualizations = [];
62
32
  let setVisualizations = (data) => {
63
33
  visualizations.push(data);
64
- }
34
+ };
65
35
  const globalEnvironmentVariables = request?.globalEnvironmentVariables || {};
66
36
  const oauth2CredentialVariables = request?.oauth2CredentialVariables || {};
67
37
  const collectionVariables = request?.collectionVariables || {};
@@ -70,27 +40,9 @@ class ScriptRuntime {
70
40
  const promptVariables = request?.promptVariables || {};
71
41
  const iterationDetails = request?.runnerIterationDetails || {};
72
42
  const assertionResults = request?.assertionResults || [];
73
- // TODO please clean this up
74
- const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName, promptVariables);
43
+ const certsAndProxyConfig = request?.certsAndProxyConfig;
44
+ const bru = new Bru(this.runtime, envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName, promptVariables, certsAndProxyConfig);
75
45
  const req = new BrunoRequest(request);
76
- const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false);
77
- const moduleWhitelist = get(scriptingConfig, 'moduleWhitelist', []);
78
- const additionalContextRoots = get(scriptingConfig, 'additionalContextRoots', []);
79
- const additionalContextRootsAbsolute = lodash
80
- .chain(additionalContextRoots)
81
- .map((acr) => (acr.startsWith('/') ? acr : path.join(collectionPath, acr)))
82
- .value();
83
-
84
- const whitelistedModules = {};
85
-
86
- for (let module of moduleWhitelist) {
87
- try {
88
- whitelistedModules[module] = require(module);
89
- } catch (e) {
90
- // Ignore
91
- console.warn(e);
92
- }
93
- }
94
46
 
95
47
  // extend bru with result getter methods
96
48
  const { __brunoTestResults, test } = createBruTestResultMethods(bru, assertionResults, chai);
@@ -104,10 +56,6 @@ class ScriptRuntime {
104
56
  __brunoTestResults: __brunoTestResults
105
57
  };
106
58
 
107
- if (this.runtime === 'vm2') {
108
- mixinTypedArrays(context);
109
- }
110
-
111
59
  if (onConsoleLog && typeof onConsoleLog === 'function') {
112
60
  const customLogger = (type) => {
113
61
  return (...args) => {
@@ -149,70 +97,12 @@ class ScriptRuntime {
149
97
  };
150
98
  }
151
99
 
152
- if (this.runtime === 'quickjs') {
153
- await executeQuickJsVmAsync({
154
- script: script,
155
- context: context,
156
- collectionPath
157
- });
158
-
159
- return {
160
- request,
161
- envVariables: cleanJson(envVariables),
162
- runtimeVariables: cleanJson(runtimeVariables),
163
- visualizations,
164
- persistentEnvVariables: bru.persistentEnvVariables,
165
- globalEnvironmentVariables: cleanJson(globalEnvironmentVariables),
166
- results: cleanJson(__brunoTestResults.getResults()),
167
- nextRequestName: bru.nextRequest,
168
- skipRequest: bru.skipRequest,
169
- stopExecution: bru.stopExecution
170
- };
171
- }
172
-
173
- // default runtime is vm2
174
- const vm = new NodeVM({
175
- sandbox: context,
176
- require: {
177
- context: 'sandbox',
178
- builtin: [ "*" ],
179
- external: true,
180
- root: [collectionPath, ...additionalContextRootsAbsolute],
181
- mock: {
182
- // node libs
183
- path,
184
- stream,
185
- util,
186
- url,
187
- http,
188
- https,
189
- punycode,
190
- zlib,
191
- // 3rd party libs
192
- ajv,
193
- 'ajv-formats': addFormats,
194
- atob,
195
- btoa,
196
- lodash,
197
- moment,
198
- uuid,
199
- nanoid,
200
- axios,
201
- chai,
202
- 'node-fetch': fetch,
203
- 'crypto-js': CryptoJS,
204
- xml2js: xml2js,
205
- jsonwebtoken,
206
- cheerio,
207
- tv4,
208
- ...whitelistedModules,
209
- fs: allowScriptFilesystemAccess ? fs : undefined,
210
- 'node-vault': NodeVault
211
- }
212
- }
100
+ // default runtime is `quickjs`
101
+ await executeQuickJsVmAsync({
102
+ script: script,
103
+ context: context,
104
+ collectionPath
213
105
  });
214
- const asyncVM = vm.run(`module.exports = async () => { ${script} }`, path.join(collectionPath, 'vm.js'));
215
- await asyncVM();
216
106
 
217
107
  return {
218
108
  request,
@@ -246,7 +136,7 @@ class ScriptRuntime {
246
136
  let visualizations = [];
247
137
  let setVisualizations = (data) => {
248
138
  visualizations.push(data);
249
- }
139
+ };
250
140
  const globalEnvironmentVariables = request?.globalEnvironmentVariables || {};
251
141
  const oauth2CredentialVariables = request?.oauth2CredentialVariables || {};
252
142
  const collectionVariables = request?.collectionVariables || {};
@@ -255,27 +145,10 @@ class ScriptRuntime {
255
145
  const promptVariables = request?.promptVariables || {};
256
146
  const iterationDetails = request?.runnerIterationDetails || {};
257
147
  const assertionResults = request?.assertionResults || [];
258
- const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName, promptVariables);
148
+ const certsAndProxyConfig = request?.certsAndProxyConfig;
149
+ const bru = new Bru(this.runtime, envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName, promptVariables, certsAndProxyConfig);
259
150
  const req = new BrunoRequest(request);
260
151
  const res = new BrunoResponse(response);
261
- const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false);
262
- const moduleWhitelist = get(scriptingConfig, 'moduleWhitelist', []);
263
- const additionalContextRoots = get(scriptingConfig, 'additionalContextRoots', []);
264
- const additionalContextRootsAbsolute = lodash
265
- .chain(additionalContextRoots)
266
- .map((acr) => (acr.startsWith('/') ? acr : path.join(collectionPath, acr)))
267
- .value();
268
-
269
- const whitelistedModules = {};
270
-
271
- for (let module of moduleWhitelist) {
272
- try {
273
- whitelistedModules[module] = require(module);
274
- } catch (e) {
275
- // Ignore
276
- console.warn(e);
277
- }
278
- }
279
152
 
280
153
  // extend bru with result getter methods
281
154
  const { __brunoTestResults, test } = createBruTestResultMethods(bru, assertionResults, chai);
@@ -290,10 +163,6 @@ class ScriptRuntime {
290
163
  __brunoTestResults: __brunoTestResults
291
164
  };
292
165
 
293
- if (this.runtime === 'vm2') {
294
- mixinTypedArrays(context);
295
- }
296
-
297
166
  if (onConsoleLog && typeof onConsoleLog === 'function') {
298
167
  const customLogger = (type) => {
299
168
  return (...args) => {
@@ -335,71 +204,13 @@ class ScriptRuntime {
335
204
  };
336
205
  }
337
206
 
338
- if (this.runtime === 'quickjs') {
339
- await executeQuickJsVmAsync({
340
- script: script,
341
- context: context,
342
- collectionPath
343
- });
344
-
345
- return {
346
- response,
347
- envVariables: cleanJson(envVariables),
348
- persistentEnvVariables: cleanJson(bru.persistentEnvVariables),
349
- runtimeVariables: cleanJson(runtimeVariables),
350
- visualizations,
351
- globalEnvironmentVariables: cleanJson(globalEnvironmentVariables),
352
- results: cleanJson(__brunoTestResults.getResults()),
353
- nextRequestName: bru.nextRequest,
354
- skipRequest: bru.skipRequest,
355
- stopExecution: bru.stopExecution
356
- };
357
- }
358
-
359
- // default runtime is vm2
360
- const vm = new NodeVM({
361
- sandbox: context,
362
- require: {
363
- context: 'sandbox',
364
- builtin: [ "*" ],
365
- external: true,
366
- root: [collectionPath, ...additionalContextRootsAbsolute],
367
- mock: {
368
- // node libs
369
- path,
370
- stream,
371
- util,
372
- url,
373
- http,
374
- https,
375
- punycode,
376
- zlib,
377
- // 3rd party libs
378
- ajv,
379
- 'ajv-formats': addFormats,
380
- atob,
381
- btoa,
382
- lodash,
383
- moment,
384
- uuid,
385
- nanoid,
386
- axios,
387
- 'node-fetch': fetch,
388
- 'crypto-js': CryptoJS,
389
- 'xml2js': xml2js,
390
- jsonwebtoken,
391
- cheerio,
392
- tv4,
393
- ...whitelistedModules,
394
- fs: allowScriptFilesystemAccess ? fs : undefined,
395
- 'node-vault': NodeVault
396
- }
397
- }
207
+ // default runtime is `quickjs`
208
+ await executeQuickJsVmAsync({
209
+ script: script,
210
+ context: context,
211
+ collectionPath
398
212
  });
399
213
 
400
- const asyncVM = vm.run(`module.exports = async () => { ${script} }`, path.join(collectionPath, 'vm.js'));
401
- await asyncVM();
402
-
403
214
  return {
404
215
  response,
405
216
  envVariables: cleanJson(envVariables),