@usebruno/js 0.42.2 → 0.44.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 +4 -7
- package/src/bru.js +10 -11
- package/src/bruno-request.js +8 -8
- package/src/bruno-response.js +1 -2
- package/src/runtime/assert-runtime.js +5 -2
- package/src/runtime/script-runtime.js +18 -206
- package/src/runtime/test-runtime.js +12 -106
- package/src/runtime/vars-runtime.js +3 -2
- package/src/sandbox/node-vm/index.js +85 -34
- package/src/sandbox/node-vm/index.spec.js +252 -0
- package/src/sandbox/quickjs/index.js +2 -2
- package/src/sandbox/quickjs/shims/bru.js +3 -3
- package/src/sandbox/quickjs/shims/lib/crypto-utils.js +7 -9
- package/src/sandbox/quickjs/shims/lib/crypto-utils.spec.js +6 -6
- package/src/sandbox/quickjs/shims/lib/utils.js +1 -1
- package/src/utils/results.js +4 -4
- package/src/utils.js +6 -6
package/package.json
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usebruno/js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.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.
|
|
20
|
-
"@usebruno/query": "0.
|
|
16
|
+
"@usebruno/common": "0.17.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,7 +25,7 @@
|
|
|
28
25
|
"cheerio": "^1.0.0",
|
|
29
26
|
"crypto-js": "^4.2.0",
|
|
30
27
|
"json-query": "^2.2.2",
|
|
31
|
-
"jsonwebtoken": "^9.0.
|
|
28
|
+
"jsonwebtoken": "^9.0.3",
|
|
32
29
|
"lodash": "^4.17.21",
|
|
33
30
|
"moment": "^2.29.4",
|
|
34
31
|
"nanoid": "3.3.8",
|
package/src/bru.js
CHANGED
|
@@ -8,9 +8,10 @@ const { jar: createCookieJar } = require('@usebruno/requests').cookies;
|
|
|
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) {
|
|
11
|
+
constructor(envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName, promptVariables) {
|
|
12
12
|
this.envVariables = envVariables || {};
|
|
13
13
|
this.runtimeVariables = runtimeVariables || {};
|
|
14
|
+
this.promptVariables = promptVariables || {};
|
|
14
15
|
this.processEnvVars = cloneDeep(processEnvVars || {});
|
|
15
16
|
this.secretVariables = cloneDeep(secretVariables || {});
|
|
16
17
|
this.collectionVariables = collectionVariables || {};
|
|
@@ -26,7 +27,7 @@ class Bru {
|
|
|
26
27
|
this.cookies = {
|
|
27
28
|
jar: () => {
|
|
28
29
|
const cookieJar = createCookieJar();
|
|
29
|
-
|
|
30
|
+
|
|
30
31
|
return {
|
|
31
32
|
getCookie: (url, cookieName, callback) => {
|
|
32
33
|
const interpolatedUrl = this.interpolate(url);
|
|
@@ -81,7 +82,7 @@ class Bru {
|
|
|
81
82
|
iterationData: new IterationDataManager(iterationDetails?.iterationData),
|
|
82
83
|
iterationIndex: iterationDetails?.iterationIndex,
|
|
83
84
|
totalIterations: iterationDetails?.totalIterations
|
|
84
|
-
};
|
|
85
|
+
};
|
|
85
86
|
|
|
86
87
|
this.utils = {
|
|
87
88
|
minifyJson: (json) => {
|
|
@@ -127,7 +128,6 @@ class Bru {
|
|
|
127
128
|
}
|
|
128
129
|
};
|
|
129
130
|
}
|
|
130
|
-
|
|
131
131
|
|
|
132
132
|
interpolate = (strOrObj) => {
|
|
133
133
|
if (!strOrObj) return strOrObj;
|
|
@@ -142,6 +142,7 @@ class Bru {
|
|
|
142
142
|
...this.requestVariables,
|
|
143
143
|
...this.oauth2CredentialVariables,
|
|
144
144
|
...this.runtimeVariables,
|
|
145
|
+
...this.promptVariables,
|
|
145
146
|
process: {
|
|
146
147
|
env: {
|
|
147
148
|
...this.processEnvVars
|
|
@@ -177,7 +178,7 @@ class Bru {
|
|
|
177
178
|
if (!key) {
|
|
178
179
|
throw new Error('Creating a env variable without specifying a name is not allowed.');
|
|
179
180
|
}
|
|
180
|
-
|
|
181
|
+
|
|
181
182
|
if (variableNameRegex.test(key) === false) {
|
|
182
183
|
throw new Error(
|
|
183
184
|
`Variable name: "${key}" contains invalid characters! Names must only contain alpha-numeric characters, "-", "_", "."`
|
|
@@ -240,8 +241,8 @@ class Bru {
|
|
|
240
241
|
|
|
241
242
|
if (variableNameRegex.test(key) === false) {
|
|
242
243
|
throw new Error(
|
|
243
|
-
`Variable name: "${key}" contains invalid characters!`
|
|
244
|
-
|
|
244
|
+
`Variable name: "${key}" contains invalid characters!`
|
|
245
|
+
+ ' Names must only contain alpha-numeric characters, "-", "_", "."'
|
|
245
246
|
);
|
|
246
247
|
}
|
|
247
248
|
|
|
@@ -260,8 +261,8 @@ class Bru {
|
|
|
260
261
|
getVar(key) {
|
|
261
262
|
if (variableNameRegex.test(key) === false) {
|
|
262
263
|
throw new Error(
|
|
263
|
-
`Variable name: "${key}" contains invalid characters!`
|
|
264
|
-
|
|
264
|
+
`Variable name: "${key}" contains invalid characters!`
|
|
265
|
+
+ ' Names must only contain alpha-numeric characters, "-", "_", "."'
|
|
265
266
|
);
|
|
266
267
|
}
|
|
267
268
|
|
|
@@ -296,12 +297,10 @@ class Bru {
|
|
|
296
297
|
this.nextRequest = nextRequest;
|
|
297
298
|
}
|
|
298
299
|
|
|
299
|
-
|
|
300
300
|
getSecretVar(key) {
|
|
301
301
|
return this.secretVariables?.[`$secrets.${key}`];
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
|
|
305
304
|
visualize(type, data) {
|
|
306
305
|
if (type == 'table') {
|
|
307
306
|
if (data?.provider == 'ag-grid') {
|
package/src/bruno-request.js
CHANGED
|
@@ -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.
|
|
@@ -26,9 +26,9 @@ class BrunoRequest {
|
|
|
26
26
|
/**
|
|
27
27
|
* We automatically parse the JSON body if the content type is JSON
|
|
28
28
|
* This is to make it easier for the user to access the body directly
|
|
29
|
-
*
|
|
29
|
+
*
|
|
30
30
|
* 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
|
|
31
|
+
* If the user wants to access the raw data, they can use getBody({raw: true}) method
|
|
32
32
|
*/
|
|
33
33
|
const isJson = this.hasJSONContentType(this.req.headers);
|
|
34
34
|
if (isJson) {
|
|
@@ -48,6 +48,7 @@ class BrunoRequest {
|
|
|
48
48
|
getMethod() {
|
|
49
49
|
return this.req.method;
|
|
50
50
|
}
|
|
51
|
+
|
|
51
52
|
getAuthMode() {
|
|
52
53
|
if (this.req?.oauth2) {
|
|
53
54
|
return 'oauth2';
|
|
@@ -104,7 +105,7 @@ class BrunoRequest {
|
|
|
104
105
|
|
|
105
106
|
/**
|
|
106
107
|
* Get the body of the request
|
|
107
|
-
*
|
|
108
|
+
*
|
|
108
109
|
* We automatically parse and return the JSON body if the content type is JSON
|
|
109
110
|
* If the user wants the raw body, they can pass the raw option as true
|
|
110
111
|
*/
|
|
@@ -128,7 +129,7 @@ class BrunoRequest {
|
|
|
128
129
|
* Otherwise
|
|
129
130
|
* - We set the request data as the data itself
|
|
130
131
|
* - We set the body property as the data itself
|
|
131
|
-
*
|
|
132
|
+
*
|
|
132
133
|
* If the user wants to override this behavior, they can pass the raw option as true
|
|
133
134
|
*/
|
|
134
135
|
setBody(data, options = {}) {
|
|
@@ -140,7 +141,7 @@ class BrunoRequest {
|
|
|
140
141
|
createdAt: new Date().toISOString()
|
|
141
142
|
});
|
|
142
143
|
}
|
|
143
|
-
|
|
144
|
+
|
|
144
145
|
if (options.raw) {
|
|
145
146
|
this.req.data = data;
|
|
146
147
|
this.body = data;
|
|
@@ -170,7 +171,7 @@ class BrunoRequest {
|
|
|
170
171
|
this.timeout = timeout;
|
|
171
172
|
this.req.timeout = timeout;
|
|
172
173
|
}
|
|
173
|
-
|
|
174
|
+
|
|
174
175
|
onFail(callback) {
|
|
175
176
|
if (typeof callback === 'function') {
|
|
176
177
|
this.req.onFailHandler = callback;
|
|
@@ -198,7 +199,6 @@ class BrunoRequest {
|
|
|
198
199
|
__isObject(obj) {
|
|
199
200
|
return obj !== null && typeof obj === 'object';
|
|
200
201
|
}
|
|
201
|
-
|
|
202
202
|
|
|
203
203
|
disableParsingResponseJson() {
|
|
204
204
|
this.req.__brunoDisableParsingResponseJson = true;
|
package/src/bruno-response.js
CHANGED
|
@@ -65,7 +65,7 @@ class BrunoResponse {
|
|
|
65
65
|
|
|
66
66
|
const { data, dataBuffer, headers } = this.res;
|
|
67
67
|
let bodySize = 0;
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
// Use raw received bytes
|
|
70
70
|
if (Buffer.isBuffer(dataBuffer)) {
|
|
71
71
|
bodySize = dataBuffer.length;
|
|
@@ -94,7 +94,6 @@ class BrunoResponse {
|
|
|
94
94
|
const headerSize = Buffer.byteLength(headerLines.join('\r\n'));
|
|
95
95
|
|
|
96
96
|
return { header: headerSize, body: bodySize, total: headerSize + bodySize };
|
|
97
|
-
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
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 || '
|
|
244
|
+
this.runtime = props?.runtime || 'quickjs';
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
runAssertions(assertions, request, response, envVariables, runtimeVariables, processEnvVars, historyLogger, secretVariables) {
|
|
@@ -250,6 +250,7 @@ class AssertRuntime {
|
|
|
250
250
|
const collectionVariables = request?.collectionVariables || {};
|
|
251
251
|
const folderVariables = request?.folderVariables || {};
|
|
252
252
|
const requestVariables = request?.requestVariables || {};
|
|
253
|
+
const promptVariables = request?.promptVariables || {};
|
|
253
254
|
const iterationDetails = request?.runnerIterationDetails || {};
|
|
254
255
|
const enabledAssertions = _.filter(assertions, (a) => a.enabled);
|
|
255
256
|
if (!enabledAssertions.length) {
|
|
@@ -269,7 +270,9 @@ class AssertRuntime {
|
|
|
269
270
|
requestVariables,
|
|
270
271
|
globalEnvironmentVariables,
|
|
271
272
|
oauth2CredentialVariables,
|
|
272
|
-
iterationDetails
|
|
273
|
+
iterationDetails,
|
|
274
|
+
undefined,
|
|
275
|
+
promptVariables
|
|
273
276
|
);
|
|
274
277
|
const req = new BrunoRequest(request, historyLogger);
|
|
275
278
|
const res = createResponseParser(response);
|
|
@@ -1,45 +1,15 @@
|
|
|
1
|
-
const
|
|
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 || '
|
|
12
|
+
this.runtime = props?.runtime || 'quickjs';
|
|
43
13
|
}
|
|
44
14
|
|
|
45
15
|
// This approach is getting out of hand
|
|
@@ -61,35 +31,18 @@ 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 || {};
|
|
68
38
|
const folderVariables = request?.folderVariables || {};
|
|
69
39
|
const requestVariables = request?.requestVariables || {};
|
|
40
|
+
const promptVariables = request?.promptVariables || {};
|
|
70
41
|
const iterationDetails = request?.runnerIterationDetails || {};
|
|
71
42
|
const assertionResults = request?.assertionResults || [];
|
|
72
43
|
// TODO please clean this up
|
|
73
|
-
const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName);
|
|
44
|
+
const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName, promptVariables);
|
|
74
45
|
const req = new BrunoRequest(request);
|
|
75
|
-
const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false);
|
|
76
|
-
const moduleWhitelist = get(scriptingConfig, 'moduleWhitelist', []);
|
|
77
|
-
const additionalContextRoots = get(scriptingConfig, 'additionalContextRoots', []);
|
|
78
|
-
const additionalContextRootsAbsolute = lodash
|
|
79
|
-
.chain(additionalContextRoots)
|
|
80
|
-
.map((acr) => (acr.startsWith('/') ? acr : path.join(collectionPath, acr)))
|
|
81
|
-
.value();
|
|
82
|
-
|
|
83
|
-
const whitelistedModules = {};
|
|
84
|
-
|
|
85
|
-
for (let module of moduleWhitelist) {
|
|
86
|
-
try {
|
|
87
|
-
whitelistedModules[module] = require(module);
|
|
88
|
-
} catch (e) {
|
|
89
|
-
// Ignore
|
|
90
|
-
console.warn(e);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
46
|
|
|
94
47
|
// extend bru with result getter methods
|
|
95
48
|
const { __brunoTestResults, test } = createBruTestResultMethods(bru, assertionResults, chai);
|
|
@@ -103,10 +56,6 @@ class ScriptRuntime {
|
|
|
103
56
|
__brunoTestResults: __brunoTestResults
|
|
104
57
|
};
|
|
105
58
|
|
|
106
|
-
if (this.runtime === 'vm2') {
|
|
107
|
-
mixinTypedArrays(context);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
59
|
if (onConsoleLog && typeof onConsoleLog === 'function') {
|
|
111
60
|
const customLogger = (type) => {
|
|
112
61
|
return (...args) => {
|
|
@@ -148,70 +97,12 @@ class ScriptRuntime {
|
|
|
148
97
|
};
|
|
149
98
|
}
|
|
150
99
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
return {
|
|
159
|
-
request,
|
|
160
|
-
envVariables: cleanJson(envVariables),
|
|
161
|
-
runtimeVariables: cleanJson(runtimeVariables),
|
|
162
|
-
visualizations,
|
|
163
|
-
persistentEnvVariables: bru.persistentEnvVariables,
|
|
164
|
-
globalEnvironmentVariables: cleanJson(globalEnvironmentVariables),
|
|
165
|
-
results: cleanJson(__brunoTestResults.getResults()),
|
|
166
|
-
nextRequestName: bru.nextRequest,
|
|
167
|
-
skipRequest: bru.skipRequest,
|
|
168
|
-
stopExecution: bru.stopExecution
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// default runtime is vm2
|
|
173
|
-
const vm = new NodeVM({
|
|
174
|
-
sandbox: context,
|
|
175
|
-
require: {
|
|
176
|
-
context: 'sandbox',
|
|
177
|
-
builtin: [ "*" ],
|
|
178
|
-
external: true,
|
|
179
|
-
root: [collectionPath, ...additionalContextRootsAbsolute],
|
|
180
|
-
mock: {
|
|
181
|
-
// node libs
|
|
182
|
-
path,
|
|
183
|
-
stream,
|
|
184
|
-
util,
|
|
185
|
-
url,
|
|
186
|
-
http,
|
|
187
|
-
https,
|
|
188
|
-
punycode,
|
|
189
|
-
zlib,
|
|
190
|
-
// 3rd party libs
|
|
191
|
-
ajv,
|
|
192
|
-
'ajv-formats': addFormats,
|
|
193
|
-
atob,
|
|
194
|
-
btoa,
|
|
195
|
-
lodash,
|
|
196
|
-
moment,
|
|
197
|
-
uuid,
|
|
198
|
-
nanoid,
|
|
199
|
-
axios,
|
|
200
|
-
chai,
|
|
201
|
-
'node-fetch': fetch,
|
|
202
|
-
'crypto-js': CryptoJS,
|
|
203
|
-
xml2js: xml2js,
|
|
204
|
-
jsonwebtoken,
|
|
205
|
-
cheerio,
|
|
206
|
-
tv4,
|
|
207
|
-
...whitelistedModules,
|
|
208
|
-
fs: allowScriptFilesystemAccess ? fs : undefined,
|
|
209
|
-
'node-vault': NodeVault
|
|
210
|
-
}
|
|
211
|
-
}
|
|
100
|
+
// default runtime is `quickjs`
|
|
101
|
+
await executeQuickJsVmAsync({
|
|
102
|
+
script: script,
|
|
103
|
+
context: context,
|
|
104
|
+
collectionPath
|
|
212
105
|
});
|
|
213
|
-
const asyncVM = vm.run(`module.exports = async () => { ${script} }`, path.join(collectionPath, 'vm.js'));
|
|
214
|
-
await asyncVM();
|
|
215
106
|
|
|
216
107
|
return {
|
|
217
108
|
request,
|
|
@@ -245,35 +136,18 @@ class ScriptRuntime {
|
|
|
245
136
|
let visualizations = [];
|
|
246
137
|
let setVisualizations = (data) => {
|
|
247
138
|
visualizations.push(data);
|
|
248
|
-
}
|
|
139
|
+
};
|
|
249
140
|
const globalEnvironmentVariables = request?.globalEnvironmentVariables || {};
|
|
250
141
|
const oauth2CredentialVariables = request?.oauth2CredentialVariables || {};
|
|
251
142
|
const collectionVariables = request?.collectionVariables || {};
|
|
252
143
|
const folderVariables = request?.folderVariables || {};
|
|
253
144
|
const requestVariables = request?.requestVariables || {};
|
|
145
|
+
const promptVariables = request?.promptVariables || {};
|
|
254
146
|
const iterationDetails = request?.runnerIterationDetails || {};
|
|
255
147
|
const assertionResults = request?.assertionResults || [];
|
|
256
|
-
const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName);
|
|
148
|
+
const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, setVisualizations, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables, oauth2CredentialVariables, iterationDetails, collectionName, promptVariables);
|
|
257
149
|
const req = new BrunoRequest(request);
|
|
258
150
|
const res = new BrunoResponse(response);
|
|
259
|
-
const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false);
|
|
260
|
-
const moduleWhitelist = get(scriptingConfig, 'moduleWhitelist', []);
|
|
261
|
-
const additionalContextRoots = get(scriptingConfig, 'additionalContextRoots', []);
|
|
262
|
-
const additionalContextRootsAbsolute = lodash
|
|
263
|
-
.chain(additionalContextRoots)
|
|
264
|
-
.map((acr) => (acr.startsWith('/') ? acr : path.join(collectionPath, acr)))
|
|
265
|
-
.value();
|
|
266
|
-
|
|
267
|
-
const whitelistedModules = {};
|
|
268
|
-
|
|
269
|
-
for (let module of moduleWhitelist) {
|
|
270
|
-
try {
|
|
271
|
-
whitelistedModules[module] = require(module);
|
|
272
|
-
} catch (e) {
|
|
273
|
-
// Ignore
|
|
274
|
-
console.warn(e);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
151
|
|
|
278
152
|
// extend bru with result getter methods
|
|
279
153
|
const { __brunoTestResults, test } = createBruTestResultMethods(bru, assertionResults, chai);
|
|
@@ -288,10 +162,6 @@ class ScriptRuntime {
|
|
|
288
162
|
__brunoTestResults: __brunoTestResults
|
|
289
163
|
};
|
|
290
164
|
|
|
291
|
-
if (this.runtime === 'vm2') {
|
|
292
|
-
mixinTypedArrays(context);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
165
|
if (onConsoleLog && typeof onConsoleLog === 'function') {
|
|
296
166
|
const customLogger = (type) => {
|
|
297
167
|
return (...args) => {
|
|
@@ -333,71 +203,13 @@ class ScriptRuntime {
|
|
|
333
203
|
};
|
|
334
204
|
}
|
|
335
205
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
return {
|
|
344
|
-
response,
|
|
345
|
-
envVariables: cleanJson(envVariables),
|
|
346
|
-
persistentEnvVariables: cleanJson(bru.persistentEnvVariables),
|
|
347
|
-
runtimeVariables: cleanJson(runtimeVariables),
|
|
348
|
-
visualizations,
|
|
349
|
-
globalEnvironmentVariables: cleanJson(globalEnvironmentVariables),
|
|
350
|
-
results: cleanJson(__brunoTestResults.getResults()),
|
|
351
|
-
nextRequestName: bru.nextRequest,
|
|
352
|
-
skipRequest: bru.skipRequest,
|
|
353
|
-
stopExecution: bru.stopExecution
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// default runtime is vm2
|
|
358
|
-
const vm = new NodeVM({
|
|
359
|
-
sandbox: context,
|
|
360
|
-
require: {
|
|
361
|
-
context: 'sandbox',
|
|
362
|
-
builtin: [ "*" ],
|
|
363
|
-
external: true,
|
|
364
|
-
root: [collectionPath, ...additionalContextRootsAbsolute],
|
|
365
|
-
mock: {
|
|
366
|
-
// node libs
|
|
367
|
-
path,
|
|
368
|
-
stream,
|
|
369
|
-
util,
|
|
370
|
-
url,
|
|
371
|
-
http,
|
|
372
|
-
https,
|
|
373
|
-
punycode,
|
|
374
|
-
zlib,
|
|
375
|
-
// 3rd party libs
|
|
376
|
-
ajv,
|
|
377
|
-
'ajv-formats': addFormats,
|
|
378
|
-
atob,
|
|
379
|
-
btoa,
|
|
380
|
-
lodash,
|
|
381
|
-
moment,
|
|
382
|
-
uuid,
|
|
383
|
-
nanoid,
|
|
384
|
-
axios,
|
|
385
|
-
'node-fetch': fetch,
|
|
386
|
-
'crypto-js': CryptoJS,
|
|
387
|
-
'xml2js': xml2js,
|
|
388
|
-
jsonwebtoken,
|
|
389
|
-
cheerio,
|
|
390
|
-
tv4,
|
|
391
|
-
...whitelistedModules,
|
|
392
|
-
fs: allowScriptFilesystemAccess ? fs : undefined,
|
|
393
|
-
'node-vault': NodeVault
|
|
394
|
-
}
|
|
395
|
-
}
|
|
206
|
+
// default runtime is `quickjs`
|
|
207
|
+
await executeQuickJsVmAsync({
|
|
208
|
+
script: script,
|
|
209
|
+
context: context,
|
|
210
|
+
collectionPath
|
|
396
211
|
});
|
|
397
212
|
|
|
398
|
-
const asyncVM = vm.run(`module.exports = async () => { ${script} }`, path.join(collectionPath, 'vm.js'));
|
|
399
|
-
await asyncVM();
|
|
400
|
-
|
|
401
213
|
return {
|
|
402
214
|
response,
|
|
403
215
|
envVariables: cleanJson(envVariables),
|