@usebruno/js 0.23.0 → 0.25.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 +7 -5
- package/src/bru.js +11 -0
- package/src/bruno-response.js +9 -0
- package/src/runtime/assert-runtime.js +8 -0
- package/src/runtime/script-runtime.js +28 -6
- package/src/runtime/test-runtime.js +61 -1
- package/src/sandbox/bundle-libraries.js +1 -1
- package/src/sandbox/quickjs/index.js +0 -8
- package/src/sandbox/quickjs/shims/bru.js +85 -0
- package/src/utils.js +6 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usebruno/js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -16,25 +16,27 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@usebruno/common": "0.3.0",
|
|
19
|
+
"@usebruno/crypto-js": "^3.1.9",
|
|
19
20
|
"@usebruno/query": "0.1.0",
|
|
20
21
|
"ajv": "^8.12.0",
|
|
21
22
|
"ajv-formats": "^2.1.1",
|
|
22
23
|
"atob": "^2.1.2",
|
|
23
|
-
"axios": "1.7.
|
|
24
|
+
"axios": "1.7.7",
|
|
24
25
|
"btoa": "^1.2.1",
|
|
25
26
|
"chai": "^4.3.7",
|
|
26
27
|
"chai-string": "^1.5.0",
|
|
28
|
+
"cheerio": "^1.0.0",
|
|
27
29
|
"crypto-js": "^4.1.1",
|
|
28
|
-
"crypto-js-3.1.9-1": "npm:crypto-js@^3.1.9-1",
|
|
29
30
|
"json-query": "^2.2.2",
|
|
30
31
|
"lodash": "^4.17.21",
|
|
31
32
|
"moment": "^2.29.4",
|
|
32
|
-
"nanoid": "3.3.
|
|
33
|
+
"nanoid": "3.3.8",
|
|
33
34
|
"node-fetch": "2.7.0",
|
|
34
35
|
"node-vault": "^0.10.2",
|
|
35
36
|
"path": "^0.12.7",
|
|
36
37
|
"quickjs-emscripten": "^0.29.2",
|
|
37
|
-
"uuid": "^9.0.0"
|
|
38
|
+
"uuid": "^9.0.0",
|
|
39
|
+
"xml2js": "^0.6.2"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
40
42
|
"@rollup/plugin-commonjs": "^23.0.2",
|
package/src/bru.js
CHANGED
|
@@ -17,6 +17,17 @@ class Bru {
|
|
|
17
17
|
this.collectionPath = collectionPath;
|
|
18
18
|
this.historyLogger = historyLogger;
|
|
19
19
|
this.setVisualizations = setVisualizations;
|
|
20
|
+
this.runner = {
|
|
21
|
+
skipRequest: () => {
|
|
22
|
+
this.skipRequest = true;
|
|
23
|
+
},
|
|
24
|
+
stopExecution: () => {
|
|
25
|
+
this.stopExecution = true;
|
|
26
|
+
},
|
|
27
|
+
setNextRequest: (nextRequest) => {
|
|
28
|
+
this.nextRequest = nextRequest;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
20
31
|
}
|
|
21
32
|
|
|
22
33
|
_interpolate = (str) => {
|
package/src/bruno-response.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const { get } = require('@usebruno/query');
|
|
2
|
+
|
|
1
3
|
class BrunoResponse {
|
|
2
4
|
constructor(res) {
|
|
3
5
|
this.res = res;
|
|
@@ -6,6 +8,13 @@ class BrunoResponse {
|
|
|
6
8
|
this.headers = res ? res.headers : null;
|
|
7
9
|
this.body = res ? res.data : null;
|
|
8
10
|
this.responseTime = res ? res.responseTime : null;
|
|
11
|
+
|
|
12
|
+
// Make the instance callable
|
|
13
|
+
const callable = (...args) => get(this.body, ...args);
|
|
14
|
+
Object.setPrototypeOf(callable, this.constructor.prototype);
|
|
15
|
+
Object.assign(callable, this);
|
|
16
|
+
|
|
17
|
+
return callable;
|
|
9
18
|
}
|
|
10
19
|
|
|
11
20
|
getStatus() {
|
|
@@ -58,6 +58,7 @@ chai.use(function (chai, utils) {
|
|
|
58
58
|
* endsWith : ends with
|
|
59
59
|
* between : between
|
|
60
60
|
* isEmpty : is empty
|
|
61
|
+
* isNotEmpty : is not empty
|
|
61
62
|
* isNull : is null
|
|
62
63
|
* isUndefined : is undefined
|
|
63
64
|
* isDefined : is defined
|
|
@@ -95,6 +96,7 @@ const parseAssertionOperator = (str = '') => {
|
|
|
95
96
|
'endsWith',
|
|
96
97
|
'between',
|
|
97
98
|
'isEmpty',
|
|
99
|
+
'isNotEmpty',
|
|
98
100
|
'isNull',
|
|
99
101
|
'isUndefined',
|
|
100
102
|
'isDefined',
|
|
@@ -109,6 +111,7 @@ const parseAssertionOperator = (str = '') => {
|
|
|
109
111
|
|
|
110
112
|
const unaryOperators = [
|
|
111
113
|
'isEmpty',
|
|
114
|
+
'isNotEmpty',
|
|
112
115
|
'isNull',
|
|
113
116
|
'isUndefined',
|
|
114
117
|
'isDefined',
|
|
@@ -147,6 +150,7 @@ const parseAssertionOperator = (str = '') => {
|
|
|
147
150
|
const isUnaryOperator = (operator) => {
|
|
148
151
|
const unaryOperators = [
|
|
149
152
|
'isEmpty',
|
|
153
|
+
'isNotEmpty',
|
|
150
154
|
'isNull',
|
|
151
155
|
'isUndefined',
|
|
152
156
|
'isDefined',
|
|
@@ -348,6 +352,9 @@ class AssertRuntime {
|
|
|
348
352
|
case 'isEmpty':
|
|
349
353
|
expect(lhs).to.be.empty;
|
|
350
354
|
break;
|
|
355
|
+
case 'isNotEmpty':
|
|
356
|
+
expect(lhs).to.not.be.empty;
|
|
357
|
+
break;
|
|
351
358
|
case 'isNull':
|
|
352
359
|
expect(lhs).to.be.null;
|
|
353
360
|
break;
|
|
@@ -412,6 +419,7 @@ class AssertRuntime {
|
|
|
412
419
|
createdAt: new Date().toISOString()
|
|
413
420
|
});
|
|
414
421
|
}
|
|
422
|
+
request.assertionResults = assertionResults;
|
|
415
423
|
|
|
416
424
|
return assertionResults;
|
|
417
425
|
}
|
|
@@ -28,6 +28,8 @@ const fetch = require('node-fetch');
|
|
|
28
28
|
const chai = require('chai');
|
|
29
29
|
const CryptoJS = require('crypto-js');
|
|
30
30
|
const NodeVault = require('node-vault');
|
|
31
|
+
const xml2js = require('xml2js');
|
|
32
|
+
const cheerio = require('cheerio');
|
|
31
33
|
const { executeQuickJsVmAsync } = require('../sandbox/quickjs');
|
|
32
34
|
|
|
33
35
|
class ScriptRuntime {
|
|
@@ -47,7 +49,8 @@ class ScriptRuntime {
|
|
|
47
49
|
processEnvVars,
|
|
48
50
|
scriptingConfig,
|
|
49
51
|
historyLogger,
|
|
50
|
-
secretVariables
|
|
52
|
+
secretVariables,
|
|
53
|
+
runRequestByItemPathname
|
|
51
54
|
) {
|
|
52
55
|
let visualizations = [];
|
|
53
56
|
let setVisualizations = (data) => {
|
|
@@ -98,6 +101,10 @@ class ScriptRuntime {
|
|
|
98
101
|
};
|
|
99
102
|
}
|
|
100
103
|
|
|
104
|
+
if(runRequestByItemPathname) {
|
|
105
|
+
context.bru.runRequest = runRequestByItemPathname;
|
|
106
|
+
}
|
|
107
|
+
|
|
101
108
|
if (this.runtime === 'quickjs') {
|
|
102
109
|
await executeQuickJsVmAsync({
|
|
103
110
|
script: script,
|
|
@@ -111,7 +118,9 @@ class ScriptRuntime {
|
|
|
111
118
|
runtimeVariables: cleanJson(runtimeVariables),
|
|
112
119
|
visualizations,
|
|
113
120
|
globalEnvironmentVariables: cleanJson(globalEnvironmentVariables),
|
|
114
|
-
nextRequestName: bru.nextRequest
|
|
121
|
+
nextRequestName: bru.nextRequest,
|
|
122
|
+
skipRequest: bru.skipRequest,
|
|
123
|
+
stopExecution: bru.stopExecution
|
|
115
124
|
};
|
|
116
125
|
}
|
|
117
126
|
|
|
@@ -145,6 +154,8 @@ class ScriptRuntime {
|
|
|
145
154
|
chai,
|
|
146
155
|
'node-fetch': fetch,
|
|
147
156
|
'crypto-js': CryptoJS,
|
|
157
|
+
'xml2js': xml2js,
|
|
158
|
+
cheerio,
|
|
148
159
|
...whitelistedModules,
|
|
149
160
|
fs: allowScriptFilesystemAccess ? fs : undefined,
|
|
150
161
|
'node-vault': NodeVault
|
|
@@ -160,7 +171,9 @@ class ScriptRuntime {
|
|
|
160
171
|
runtimeVariables: cleanJson(runtimeVariables),
|
|
161
172
|
visualizations,
|
|
162
173
|
globalEnvironmentVariables: cleanJson(globalEnvironmentVariables),
|
|
163
|
-
nextRequestName: bru.nextRequest
|
|
174
|
+
nextRequestName: bru.nextRequest,
|
|
175
|
+
skipRequest: bru.skipRequest,
|
|
176
|
+
stopExecution: bru.stopExecution
|
|
164
177
|
};
|
|
165
178
|
}
|
|
166
179
|
|
|
@@ -175,7 +188,8 @@ class ScriptRuntime {
|
|
|
175
188
|
processEnvVars,
|
|
176
189
|
scriptingConfig,
|
|
177
190
|
historyLogger,
|
|
178
|
-
secretVariables
|
|
191
|
+
secretVariables,
|
|
192
|
+
runRequestByItemPathname
|
|
179
193
|
) {
|
|
180
194
|
let visualizations = [];
|
|
181
195
|
let setVisualizations = (data) => {
|
|
@@ -223,6 +237,10 @@ class ScriptRuntime {
|
|
|
223
237
|
};
|
|
224
238
|
}
|
|
225
239
|
|
|
240
|
+
if(runRequestByItemPathname) {
|
|
241
|
+
context.bru.runRequest = runRequestByItemPathname;
|
|
242
|
+
}
|
|
243
|
+
|
|
226
244
|
if (this.runtime === 'quickjs') {
|
|
227
245
|
await executeQuickJsVmAsync({
|
|
228
246
|
script: script,
|
|
@@ -236,7 +254,9 @@ class ScriptRuntime {
|
|
|
236
254
|
runtimeVariables: cleanJson(runtimeVariables),
|
|
237
255
|
visualizations,
|
|
238
256
|
globalEnvironmentVariables: cleanJson(globalEnvironmentVariables),
|
|
239
|
-
nextRequestName: bru.nextRequest
|
|
257
|
+
nextRequestName: bru.nextRequest,
|
|
258
|
+
skipRequest: bru.skipRequest,
|
|
259
|
+
stopExecution: bru.stopExecution
|
|
240
260
|
};
|
|
241
261
|
}
|
|
242
262
|
|
|
@@ -285,7 +305,9 @@ class ScriptRuntime {
|
|
|
285
305
|
runtimeVariables: cleanJson(runtimeVariables),
|
|
286
306
|
visualizations,
|
|
287
307
|
globalEnvironmentVariables: cleanJson(globalEnvironmentVariables),
|
|
288
|
-
nextRequestName: bru.nextRequest
|
|
308
|
+
nextRequestName: bru.nextRequest,
|
|
309
|
+
skipRequest: bru.skipRequest,
|
|
310
|
+
stopExecution: bru.stopExecution
|
|
289
311
|
};
|
|
290
312
|
}
|
|
291
313
|
}
|
|
@@ -30,8 +30,29 @@ const axios = require('axios');
|
|
|
30
30
|
const fetch = require('node-fetch');
|
|
31
31
|
const CryptoJS = require('crypto-js');
|
|
32
32
|
const NodeVault = require('node-vault');
|
|
33
|
+
const xml2js = require('xml2js');
|
|
34
|
+
const cheerio = require('cheerio');
|
|
33
35
|
const { executeQuickJsVmAsync } = require('../sandbox/quickjs');
|
|
34
36
|
|
|
37
|
+
const getResultsSummary = (results) => {
|
|
38
|
+
const summary = {
|
|
39
|
+
total: results.length,
|
|
40
|
+
passed: 0,
|
|
41
|
+
failed: 0,
|
|
42
|
+
skipped: 0,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
results.forEach((r) => {
|
|
46
|
+
const passed = r.status === "pass";
|
|
47
|
+
if (passed) summary.passed += 1;
|
|
48
|
+
else if (r.status === "fail") summary.failed += 1;
|
|
49
|
+
else summary.skipped += 1;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return summary;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
35
56
|
class TestRuntime {
|
|
36
57
|
constructor(props) {
|
|
37
58
|
this.runtime = props?.runtime || 'vm2';
|
|
@@ -48,12 +69,14 @@ class TestRuntime {
|
|
|
48
69
|
processEnvVars,
|
|
49
70
|
scriptingConfig,
|
|
50
71
|
historyLogger,
|
|
51
|
-
secretVariables
|
|
72
|
+
secretVariables,
|
|
73
|
+
runRequestByItemPathname
|
|
52
74
|
) {
|
|
53
75
|
const globalEnvironmentVariables = request?.globalEnvironmentVariables || {};
|
|
54
76
|
const collectionVariables = request?.collectionVariables || {};
|
|
55
77
|
const folderVariables = request?.folderVariables || {};
|
|
56
78
|
const requestVariables = request?.requestVariables || {};
|
|
79
|
+
const assertionResults = request?.assertionResults || [];
|
|
57
80
|
const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, historyLogger, undefined, secretVariables, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables);
|
|
58
81
|
const req = new BrunoRequest(request, historyLogger);
|
|
59
82
|
const res = new BrunoResponse(response);
|
|
@@ -77,6 +100,7 @@ class TestRuntime {
|
|
|
77
100
|
}
|
|
78
101
|
|
|
79
102
|
const __brunoTestResults = new TestResults();
|
|
103
|
+
|
|
80
104
|
const test = Test(__brunoTestResults, chai);
|
|
81
105
|
|
|
82
106
|
if (!testsFile || !testsFile.length) {
|
|
@@ -90,6 +114,36 @@ class TestRuntime {
|
|
|
90
114
|
};
|
|
91
115
|
}
|
|
92
116
|
|
|
117
|
+
bru.getTestResults = async () => {
|
|
118
|
+
let results = await __brunoTestResults.getResults();
|
|
119
|
+
const summary = getResultsSummary(results);
|
|
120
|
+
return {
|
|
121
|
+
summary,
|
|
122
|
+
results: results?.map?.(r => ({
|
|
123
|
+
status: r?.status,
|
|
124
|
+
description: r?.description,
|
|
125
|
+
expected: r?.expected,
|
|
126
|
+
actual: r?.actual,
|
|
127
|
+
error: r?.error
|
|
128
|
+
}))
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
bru.getAssertionResults = async () => {
|
|
132
|
+
let results = assertionResults;
|
|
133
|
+
const summary = getResultsSummary(results);
|
|
134
|
+
return {
|
|
135
|
+
summary,
|
|
136
|
+
results: results?.map?.(r => ({
|
|
137
|
+
status: r?.status,
|
|
138
|
+
lhsExpr: r?.lhsExpr,
|
|
139
|
+
rhsExpr: r?.rhsExpr,
|
|
140
|
+
operator: r?.operator,
|
|
141
|
+
rhsOperand: r?.rhsOperand,
|
|
142
|
+
error: r?.error
|
|
143
|
+
}))
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
93
147
|
const context = {
|
|
94
148
|
test,
|
|
95
149
|
bru,
|
|
@@ -115,6 +169,10 @@ class TestRuntime {
|
|
|
115
169
|
};
|
|
116
170
|
}
|
|
117
171
|
|
|
172
|
+
if(runRequestByItemPathname) {
|
|
173
|
+
context.bru.runRequest = runRequestByItemPathname;
|
|
174
|
+
}
|
|
175
|
+
|
|
118
176
|
if (this.runtime === 'quickjs') {
|
|
119
177
|
await executeQuickJsVmAsync({
|
|
120
178
|
script: testsFile,
|
|
@@ -151,6 +209,8 @@ class TestRuntime {
|
|
|
151
209
|
chai,
|
|
152
210
|
'node-fetch': fetch,
|
|
153
211
|
'crypto-js': CryptoJS,
|
|
212
|
+
'xml2js': xml2js,
|
|
213
|
+
cheerio,
|
|
154
214
|
...whitelistedModules,
|
|
155
215
|
fs: allowScriptFilesystemAccess ? fs : undefined,
|
|
156
216
|
'node-vault': NodeVault
|
|
@@ -11,7 +11,7 @@ const bundleLibraries = async () => {
|
|
|
11
11
|
import moment from "moment";
|
|
12
12
|
import btoa from "btoa";
|
|
13
13
|
import atob from "atob";
|
|
14
|
-
import * as CryptoJS from "crypto-js
|
|
14
|
+
import * as CryptoJS from "@usebruno/crypto-js";
|
|
15
15
|
globalThis.expect = expect;
|
|
16
16
|
globalThis.assert = assert;
|
|
17
17
|
globalThis.moment = moment;
|
|
@@ -22,12 +22,6 @@ const toNumber = (value) => {
|
|
|
22
22
|
return Number.isInteger(num) ? parseInt(value, 10) : parseFloat(value);
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
const removeQuotes = (str) => {
|
|
26
|
-
if ((str.startsWith('"') && str.endsWith('"')) || (str.startsWith("'") && str.endsWith("'"))) {
|
|
27
|
-
return str.slice(1, -1);
|
|
28
|
-
}
|
|
29
|
-
return str;
|
|
30
|
-
};
|
|
31
25
|
|
|
32
26
|
const executeQuickJsVm = ({ script: externalScript, context: externalContext, scriptType = 'template-literal' }) => {
|
|
33
27
|
if (!externalScript?.length || typeof externalScript !== 'string') {
|
|
@@ -44,7 +38,6 @@ const executeQuickJsVm = ({ script: externalScript, context: externalContext, sc
|
|
|
44
38
|
if (externalScript === 'null') return null;
|
|
45
39
|
if (externalScript === 'undefined') return undefined;
|
|
46
40
|
|
|
47
|
-
externalScript = removeQuotes(externalScript);
|
|
48
41
|
|
|
49
42
|
const vm = QuickJSSyncContext;
|
|
50
43
|
|
|
@@ -94,7 +87,6 @@ const executeQuickJsVmAsync = async ({ script: externalScript, context: external
|
|
|
94
87
|
if (externalScript === 'null') return null;
|
|
95
88
|
if (externalScript === 'undefined') return undefined;
|
|
96
89
|
|
|
97
|
-
externalScript = removeQuotes(externalScript);
|
|
98
90
|
|
|
99
91
|
try {
|
|
100
92
|
const module = await newQuickJSWASMModule();
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
const { cleanJson } = require('../../../utils');
|
|
1
2
|
const { marshallToVm } = require('../utils');
|
|
2
3
|
|
|
3
4
|
const addBruShimToContext = (vm, bru) => {
|
|
4
5
|
const bruObject = vm.newObject();
|
|
6
|
+
const bruRunnerObject = vm.newObject();
|
|
5
7
|
|
|
6
8
|
let cwd = vm.newFunction('cwd', function () {
|
|
7
9
|
return marshallToVm(bru.cwd(), vm);
|
|
@@ -93,6 +95,24 @@ const addBruShimToContext = (vm, bru) => {
|
|
|
93
95
|
vm.setProp(bruObject, 'setNextRequest', setNextRequest);
|
|
94
96
|
setNextRequest.dispose();
|
|
95
97
|
|
|
98
|
+
let runnerSkipRequest = vm.newFunction('skipRequest', function () {
|
|
99
|
+
bru?.runner?.skipRequest();
|
|
100
|
+
});
|
|
101
|
+
vm.setProp(bruRunnerObject, 'skipRequest', runnerSkipRequest);
|
|
102
|
+
runnerSkipRequest.dispose();
|
|
103
|
+
|
|
104
|
+
let runnerStopExecution = vm.newFunction('stopExecution', function () {
|
|
105
|
+
bru?.runner?.stopExecution();
|
|
106
|
+
});
|
|
107
|
+
vm.setProp(bruRunnerObject, 'stopExecution', runnerStopExecution);
|
|
108
|
+
runnerStopExecution.dispose();
|
|
109
|
+
|
|
110
|
+
let runnerSetNextRequest = vm.newFunction('setNextRequest', function (nextRequest) {
|
|
111
|
+
bru?.runner?.setNextRequest(vm.dump(nextRequest));
|
|
112
|
+
});
|
|
113
|
+
vm.setProp(bruRunnerObject, 'setNextRequest', runnerSetNextRequest);
|
|
114
|
+
runnerSetNextRequest.dispose();
|
|
115
|
+
|
|
96
116
|
let visualize = vm.newFunction('visualize', function (type, data) {
|
|
97
117
|
bru.visualize(vm.dump(type), vm.dump(data));
|
|
98
118
|
});
|
|
@@ -123,6 +143,70 @@ const addBruShimToContext = (vm, bru) => {
|
|
|
123
143
|
vm.setProp(bruObject, 'getCollectionVar', getCollectionVar);
|
|
124
144
|
getCollectionVar.dispose();
|
|
125
145
|
|
|
146
|
+
let getTestResults = vm.newFunction('getTestResults', () => {
|
|
147
|
+
const promise = vm.newPromise();
|
|
148
|
+
bru.getTestResults()
|
|
149
|
+
.then((results) => {
|
|
150
|
+
promise.resolve(marshallToVm(cleanJson(results), vm));
|
|
151
|
+
})
|
|
152
|
+
.catch((err) => {
|
|
153
|
+
promise.resolve(
|
|
154
|
+
marshallToVm(
|
|
155
|
+
cleanJson({
|
|
156
|
+
message: err.message
|
|
157
|
+
}),
|
|
158
|
+
vm
|
|
159
|
+
)
|
|
160
|
+
);
|
|
161
|
+
});
|
|
162
|
+
promise.settled.then(vm.runtime.executePendingJobs);
|
|
163
|
+
return promise.handle;
|
|
164
|
+
});
|
|
165
|
+
getTestResults.consume((handle) => vm.setProp(bruObject, 'getTestResults', handle));
|
|
166
|
+
|
|
167
|
+
let getAssertionResults = vm.newFunction('getAssertionResults', () => {
|
|
168
|
+
const promise = vm.newPromise();
|
|
169
|
+
bru.getAssertionResults()
|
|
170
|
+
.then((results) => {
|
|
171
|
+
promise.resolve(marshallToVm(cleanJson(results), vm));
|
|
172
|
+
})
|
|
173
|
+
.catch((err) => {
|
|
174
|
+
promise.resolve(
|
|
175
|
+
marshallToVm(
|
|
176
|
+
cleanJson({
|
|
177
|
+
message: err.message
|
|
178
|
+
}),
|
|
179
|
+
vm
|
|
180
|
+
)
|
|
181
|
+
);
|
|
182
|
+
});
|
|
183
|
+
promise.settled.then(vm.runtime.executePendingJobs);
|
|
184
|
+
return promise.handle;
|
|
185
|
+
});
|
|
186
|
+
getAssertionResults.consume((handle) => vm.setProp(bruObject, 'getAssertionResults', handle));
|
|
187
|
+
|
|
188
|
+
let runRequestHandle = vm.newFunction('runRequest', (args) => {
|
|
189
|
+
const promise = vm.newPromise();
|
|
190
|
+
bru.runRequest(vm.dump(args))
|
|
191
|
+
.then((response) => {
|
|
192
|
+
const { status, headers, data, dataBuffer, size } = response || {};
|
|
193
|
+
promise.resolve(marshallToVm(cleanJson({ status, headers, data, dataBuffer, size }), vm));
|
|
194
|
+
})
|
|
195
|
+
.catch((err) => {
|
|
196
|
+
promise.resolve(
|
|
197
|
+
marshallToVm(
|
|
198
|
+
cleanJson({
|
|
199
|
+
message: err.message
|
|
200
|
+
}),
|
|
201
|
+
vm
|
|
202
|
+
)
|
|
203
|
+
);
|
|
204
|
+
});
|
|
205
|
+
promise.settled.then(vm.runtime.executePendingJobs);
|
|
206
|
+
return promise.handle;
|
|
207
|
+
});
|
|
208
|
+
runRequestHandle.consume((handle) => vm.setProp(bruObject, 'runRequest', handle));
|
|
209
|
+
|
|
126
210
|
const sleep = vm.newFunction('sleep', (timer) => {
|
|
127
211
|
const t = vm.getString(timer);
|
|
128
212
|
const promise = vm.newPromise();
|
|
@@ -134,6 +218,7 @@ const addBruShimToContext = (vm, bru) => {
|
|
|
134
218
|
});
|
|
135
219
|
sleep.consume((handle) => vm.setProp(bruObject, 'sleep', handle));
|
|
136
220
|
|
|
221
|
+
vm.setProp(bruObject, 'runner', bruRunnerObject);
|
|
137
222
|
vm.setProp(vm.global, 'bru', bruObject);
|
|
138
223
|
bruObject.dispose();
|
|
139
224
|
};
|
package/src/utils.js
CHANGED
|
@@ -19,8 +19,8 @@ const JS_KEYWORDS = `
|
|
|
19
19
|
* ```js
|
|
20
20
|
* res.data.pets.map(pet => pet.name.toUpperCase())
|
|
21
21
|
*
|
|
22
|
-
* function(
|
|
23
|
-
* const { res, pet } =
|
|
22
|
+
* function(__bruno__functionInnerContext) {
|
|
23
|
+
* const { res, pet } = __bruno__functionInnerContext;
|
|
24
24
|
* return res.data.pets.map(pet => pet.name.toUpperCase())
|
|
25
25
|
* }
|
|
26
26
|
* ```
|
|
@@ -46,9 +46,11 @@ const compileJsExpression = (expr) => {
|
|
|
46
46
|
globals: globals.map((name) => ` ${name} = ${name} ?? globalThis.${name};`).join('')
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
// param name that is unlikely to show up as a var in an expression
|
|
50
|
+
const param = `__bruno__functionInnerContext`;
|
|
51
|
+
const body = `let { ${code.vars} } = ${param}; ${code.globals}; return ${expr}`;
|
|
50
52
|
|
|
51
|
-
return new Function(
|
|
53
|
+
return new Function(param, body);
|
|
52
54
|
};
|
|
53
55
|
|
|
54
56
|
const internalExpressionCache = new Map();
|
|
@@ -84,14 +86,6 @@ const evaluateJsTemplateLiteral = (templateLiteral, context) => {
|
|
|
84
86
|
return undefined;
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
if (templateLiteral.startsWith('"') && templateLiteral.endsWith('"')) {
|
|
88
|
-
return templateLiteral.slice(1, -1);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (templateLiteral.startsWith("'") && templateLiteral.endsWith("'")) {
|
|
92
|
-
return templateLiteral.slice(1, -1);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
89
|
if (!isNaN(templateLiteral)) {
|
|
96
90
|
const number = Number(templateLiteral);
|
|
97
91
|
// Check if the number is too high. Too high number might get altered, see #1000
|