@usebruno/js 0.11.0 → 0.13.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 +1 -1
- package/src/bru.js +39 -1
- package/src/bruno-request.js +20 -1
- package/src/runtime/assert-runtime.js +30 -4
- package/src/runtime/script-runtime.js +39 -9
- package/src/runtime/test-runtime.js +24 -5
- package/src/runtime/vars-runtime.js +43 -6
- package/src/utils.js +12 -1
package/package.json
CHANGED
package/src/bru.js
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
const Handlebars = require('handlebars');
|
|
2
2
|
const { cloneDeep } = require('lodash');
|
|
3
|
+
const { uuid } = require('./utils');
|
|
3
4
|
|
|
4
5
|
const variableNameRegex = /^[\w-.]*$/;
|
|
5
6
|
|
|
6
7
|
class Bru {
|
|
7
|
-
constructor(
|
|
8
|
+
constructor(
|
|
9
|
+
envVariables,
|
|
10
|
+
collectionVariables,
|
|
11
|
+
processEnvVars,
|
|
12
|
+
collectionPath,
|
|
13
|
+
historyLogger,
|
|
14
|
+
setHtmlVisualizationString,
|
|
15
|
+
secretVariables
|
|
16
|
+
) {
|
|
8
17
|
this.envVariables = envVariables;
|
|
9
18
|
this.collectionVariables = collectionVariables;
|
|
10
19
|
this.processEnvVars = cloneDeep(processEnvVars || {});
|
|
20
|
+
this.secretVariables = cloneDeep(secretVariables || {});
|
|
11
21
|
this.collectionPath = collectionPath;
|
|
22
|
+
this.historyLogger = historyLogger;
|
|
23
|
+
this.setHtmlVisualizationString = setHtmlVisualizationString;
|
|
12
24
|
}
|
|
13
25
|
|
|
14
26
|
_interpolateEnvVar = (str) => {
|
|
@@ -48,6 +60,15 @@ class Bru {
|
|
|
48
60
|
throw new Error('Creating a env variable without specifying a name is not allowed.');
|
|
49
61
|
}
|
|
50
62
|
|
|
63
|
+
if (this.historyLogger) {
|
|
64
|
+
this.historyLogger({
|
|
65
|
+
uid: uuid(),
|
|
66
|
+
type: 'setEnvVar()',
|
|
67
|
+
data: { key, value },
|
|
68
|
+
createdAt: new Date().toISOString()
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
51
72
|
this.envVariables[key] = value;
|
|
52
73
|
}
|
|
53
74
|
|
|
@@ -63,6 +84,15 @@ class Bru {
|
|
|
63
84
|
);
|
|
64
85
|
}
|
|
65
86
|
|
|
87
|
+
if (this.historyLogger) {
|
|
88
|
+
this.historyLogger({
|
|
89
|
+
uid: uuid(),
|
|
90
|
+
type: 'setVar()',
|
|
91
|
+
data: { key, value },
|
|
92
|
+
createdAt: new Date().toISOString()
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
66
96
|
this.collectionVariables[key] = value;
|
|
67
97
|
}
|
|
68
98
|
|
|
@@ -80,6 +110,14 @@ class Bru {
|
|
|
80
110
|
setNextRequest(nextRequest) {
|
|
81
111
|
this.nextRequest = nextRequest;
|
|
82
112
|
}
|
|
113
|
+
|
|
114
|
+
visualize(htmlString) {
|
|
115
|
+
this.setHtmlVisualizationString(htmlString);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
getSecretVar(key) {
|
|
119
|
+
return this.secretVariables?.[`$secrets.${key}`];
|
|
120
|
+
}
|
|
83
121
|
}
|
|
84
122
|
|
|
85
123
|
module.exports = Bru;
|
package/src/bruno-request.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
const { uuid } = require('./utils');
|
|
2
|
+
|
|
1
3
|
class BrunoRequest {
|
|
2
|
-
constructor(req) {
|
|
4
|
+
constructor(req, historyLogger) {
|
|
3
5
|
this.req = req;
|
|
4
6
|
this.url = req.url;
|
|
5
7
|
this.method = req.method;
|
|
6
8
|
this.headers = req.headers;
|
|
7
9
|
this.body = req.data;
|
|
8
10
|
this.timeout = req.timeout;
|
|
11
|
+
this.historyLogger = historyLogger;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
getUrl() {
|
|
@@ -53,6 +56,14 @@ class BrunoRequest {
|
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
setHeader(name, value) {
|
|
59
|
+
if (this.historyLogger) {
|
|
60
|
+
this.historyLogger({
|
|
61
|
+
uid: uuid(),
|
|
62
|
+
type: 'setHeader()',
|
|
63
|
+
data: { name, value },
|
|
64
|
+
createdAt: new Date().toISOString()
|
|
65
|
+
});
|
|
66
|
+
}
|
|
56
67
|
this.req.headers[name] = value;
|
|
57
68
|
}
|
|
58
69
|
|
|
@@ -61,6 +72,14 @@ class BrunoRequest {
|
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
setBody(data) {
|
|
75
|
+
if (this.historyLogger) {
|
|
76
|
+
this.historyLogger({
|
|
77
|
+
uid: uuid(),
|
|
78
|
+
type: 'setBody()',
|
|
79
|
+
data: { body: data },
|
|
80
|
+
createdAt: new Date().toISOString()
|
|
81
|
+
});
|
|
82
|
+
}
|
|
64
83
|
this.req.data = data;
|
|
65
84
|
}
|
|
66
85
|
|
|
@@ -3,7 +3,7 @@ const chai = require('chai');
|
|
|
3
3
|
const { nanoid } = require('nanoid');
|
|
4
4
|
const Bru = require('../bru');
|
|
5
5
|
const BrunoRequest = require('../bruno-request');
|
|
6
|
-
const { evaluateJsTemplateLiteral, evaluateJsExpression, createResponseParser } = require('../utils');
|
|
6
|
+
const { evaluateJsTemplateLiteral, evaluateJsExpression, createResponseParser, uuid } = require('../utils');
|
|
7
7
|
const { interpolateString } = require('../interpolate-string');
|
|
8
8
|
|
|
9
9
|
const { expect } = chai;
|
|
@@ -199,14 +199,31 @@ const evaluateRhsOperand = (rhsOperand, operator, context) => {
|
|
|
199
199
|
};
|
|
200
200
|
|
|
201
201
|
class AssertRuntime {
|
|
202
|
-
runAssertions(
|
|
202
|
+
runAssertions(
|
|
203
|
+
assertions,
|
|
204
|
+
request,
|
|
205
|
+
response,
|
|
206
|
+
envVariables,
|
|
207
|
+
collectionVariables,
|
|
208
|
+
collectionPath,
|
|
209
|
+
historyLogger,
|
|
210
|
+
secretVariables
|
|
211
|
+
) {
|
|
203
212
|
const enabledAssertions = _.filter(assertions, (a) => a.enabled);
|
|
204
213
|
if (!enabledAssertions.length) {
|
|
205
214
|
return [];
|
|
206
215
|
}
|
|
207
216
|
|
|
208
|
-
const bru = new Bru(
|
|
209
|
-
|
|
217
|
+
const bru = new Bru(
|
|
218
|
+
envVariables,
|
|
219
|
+
collectionVariables,
|
|
220
|
+
undefined, // processEnvVars,
|
|
221
|
+
undefined, // collectionPath,
|
|
222
|
+
undefined, // historyLogger,
|
|
223
|
+
undefined, // setHtmlVisualizationString,
|
|
224
|
+
secretVariables
|
|
225
|
+
);
|
|
226
|
+
const req = new BrunoRequest(request, historyLogger);
|
|
210
227
|
const res = createResponseParser(response);
|
|
211
228
|
|
|
212
229
|
const bruContext = {
|
|
@@ -339,6 +356,15 @@ class AssertRuntime {
|
|
|
339
356
|
}
|
|
340
357
|
}
|
|
341
358
|
|
|
359
|
+
if (historyLogger) {
|
|
360
|
+
historyLogger({
|
|
361
|
+
uid: uuid(),
|
|
362
|
+
type: 'network',
|
|
363
|
+
assertions: assertionResults,
|
|
364
|
+
createdAt: new Date().toISOString()
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
|
|
342
368
|
return assertionResults;
|
|
343
369
|
}
|
|
344
370
|
}
|
|
@@ -27,7 +27,7 @@ const axios = require('axios');
|
|
|
27
27
|
const fetch = require('node-fetch');
|
|
28
28
|
const chai = require('chai');
|
|
29
29
|
const CryptoJS = require('crypto-js');
|
|
30
|
-
const
|
|
30
|
+
const NodeSecrets = require('node-vault');
|
|
31
31
|
|
|
32
32
|
class ScriptRuntime {
|
|
33
33
|
constructor() {}
|
|
@@ -42,10 +42,24 @@ class ScriptRuntime {
|
|
|
42
42
|
collectionPath,
|
|
43
43
|
onConsoleLog,
|
|
44
44
|
processEnvVars,
|
|
45
|
-
scriptingConfig
|
|
45
|
+
scriptingConfig,
|
|
46
|
+
historyLogger,
|
|
47
|
+
secretVariables
|
|
46
48
|
) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
let htmlVisualizationString;
|
|
50
|
+
let setHtmlVisualizationString = (htmlString) => {
|
|
51
|
+
htmlVisualizationString = htmlString;
|
|
52
|
+
};
|
|
53
|
+
const bru = new Bru(
|
|
54
|
+
envVariables,
|
|
55
|
+
collectionVariables,
|
|
56
|
+
processEnvVars,
|
|
57
|
+
collectionPath,
|
|
58
|
+
historyLogger,
|
|
59
|
+
setHtmlVisualizationString,
|
|
60
|
+
secretVariables
|
|
61
|
+
);
|
|
62
|
+
const req = new BrunoRequest(request, historyLogger);
|
|
49
63
|
const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false);
|
|
50
64
|
const moduleWhitelist = get(scriptingConfig, 'moduleWhitelist', []);
|
|
51
65
|
const additionalContextRoots = get(scriptingConfig, 'additionalContextRoots', []);
|
|
@@ -116,7 +130,7 @@ class ScriptRuntime {
|
|
|
116
130
|
'crypto-js': CryptoJS,
|
|
117
131
|
...whitelistedModules,
|
|
118
132
|
fs: allowScriptFilesystemAccess ? fs : undefined,
|
|
119
|
-
'node-vault':
|
|
133
|
+
'node-vault': NodeSecrets
|
|
120
134
|
}
|
|
121
135
|
}
|
|
122
136
|
});
|
|
@@ -126,6 +140,7 @@ class ScriptRuntime {
|
|
|
126
140
|
request,
|
|
127
141
|
envVariables: cleanJson(envVariables),
|
|
128
142
|
collectionVariables: cleanJson(collectionVariables),
|
|
143
|
+
htmlVisualizationString,
|
|
129
144
|
nextRequestName: bru.nextRequest
|
|
130
145
|
};
|
|
131
146
|
}
|
|
@@ -139,10 +154,24 @@ class ScriptRuntime {
|
|
|
139
154
|
collectionPath,
|
|
140
155
|
onConsoleLog,
|
|
141
156
|
processEnvVars,
|
|
142
|
-
scriptingConfig
|
|
157
|
+
scriptingConfig,
|
|
158
|
+
historyLogger,
|
|
159
|
+
secretVariables
|
|
143
160
|
) {
|
|
144
|
-
|
|
145
|
-
|
|
161
|
+
let htmlVisualizationString;
|
|
162
|
+
let setHtmlVisualizationString = (htmlString) => {
|
|
163
|
+
htmlVisualizationString = htmlString;
|
|
164
|
+
};
|
|
165
|
+
const bru = new Bru(
|
|
166
|
+
envVariables,
|
|
167
|
+
collectionVariables,
|
|
168
|
+
processEnvVars,
|
|
169
|
+
collectionPath,
|
|
170
|
+
historyLogger,
|
|
171
|
+
setHtmlVisualizationString,
|
|
172
|
+
secretVariables
|
|
173
|
+
);
|
|
174
|
+
const req = new BrunoRequest(request, historyLogger);
|
|
146
175
|
const res = new BrunoResponse(response);
|
|
147
176
|
const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false);
|
|
148
177
|
const moduleWhitelist = get(scriptingConfig, 'moduleWhitelist', []);
|
|
@@ -208,7 +237,7 @@ class ScriptRuntime {
|
|
|
208
237
|
'crypto-js': CryptoJS,
|
|
209
238
|
...whitelistedModules,
|
|
210
239
|
fs: allowScriptFilesystemAccess ? fs : undefined,
|
|
211
|
-
'node-vault':
|
|
240
|
+
'node-vault': NodeSecrets
|
|
212
241
|
}
|
|
213
242
|
}
|
|
214
243
|
});
|
|
@@ -220,6 +249,7 @@ class ScriptRuntime {
|
|
|
220
249
|
response,
|
|
221
250
|
envVariables: cleanJson(envVariables),
|
|
222
251
|
collectionVariables: cleanJson(collectionVariables),
|
|
252
|
+
htmlVisualizationString,
|
|
223
253
|
nextRequestName: bru.nextRequest
|
|
224
254
|
};
|
|
225
255
|
}
|
|
@@ -29,7 +29,7 @@ const nanoid = require('nanoid');
|
|
|
29
29
|
const axios = require('axios');
|
|
30
30
|
const fetch = require('node-fetch');
|
|
31
31
|
const CryptoJS = require('crypto-js');
|
|
32
|
-
const
|
|
32
|
+
const NodeSecrets = require('node-vault');
|
|
33
33
|
|
|
34
34
|
class TestRuntime {
|
|
35
35
|
constructor() {}
|
|
@@ -43,10 +43,20 @@ class TestRuntime {
|
|
|
43
43
|
collectionPath,
|
|
44
44
|
onConsoleLog,
|
|
45
45
|
processEnvVars,
|
|
46
|
-
scriptingConfig
|
|
46
|
+
scriptingConfig,
|
|
47
|
+
historyLogger,
|
|
48
|
+
secretVariables
|
|
47
49
|
) {
|
|
48
|
-
const bru = new Bru(
|
|
49
|
-
|
|
50
|
+
const bru = new Bru(
|
|
51
|
+
envVariables,
|
|
52
|
+
collectionVariables,
|
|
53
|
+
processEnvVars,
|
|
54
|
+
collectionPath,
|
|
55
|
+
historyLogger,
|
|
56
|
+
undefined, // setHtmlVisualizationString
|
|
57
|
+
secretVariables
|
|
58
|
+
);
|
|
59
|
+
const req = new BrunoRequest(request, historyLogger);
|
|
50
60
|
const res = new BrunoResponse(response);
|
|
51
61
|
const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false);
|
|
52
62
|
const moduleWhitelist = get(scriptingConfig, 'moduleWhitelist', []);
|
|
@@ -134,7 +144,7 @@ class TestRuntime {
|
|
|
134
144
|
'crypto-js': CryptoJS,
|
|
135
145
|
...whitelistedModules,
|
|
136
146
|
fs: allowScriptFilesystemAccess ? fs : undefined,
|
|
137
|
-
'node-vault':
|
|
147
|
+
'node-vault': NodeSecrets
|
|
138
148
|
}
|
|
139
149
|
}
|
|
140
150
|
});
|
|
@@ -142,6 +152,15 @@ class TestRuntime {
|
|
|
142
152
|
const asyncVM = vm.run(`module.exports = async () => { ${testsFile}}`, path.join(collectionPath, 'vm.js'));
|
|
143
153
|
await asyncVM();
|
|
144
154
|
|
|
155
|
+
if (historyLogger) {
|
|
156
|
+
historyLogger({
|
|
157
|
+
uid: uuid.v4(),
|
|
158
|
+
type: 'network',
|
|
159
|
+
tests: cleanJson(__brunoTestResults.getResults()),
|
|
160
|
+
createdAt: new Date().toISOString()
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
145
164
|
return {
|
|
146
165
|
request,
|
|
147
166
|
envVariables: cleanJson(envVariables),
|
|
@@ -4,14 +4,31 @@ const BrunoRequest = require('../bruno-request');
|
|
|
4
4
|
const { evaluateJsTemplateLiteral, evaluateJsExpression, createResponseParser } = require('../utils');
|
|
5
5
|
|
|
6
6
|
class VarsRuntime {
|
|
7
|
-
runPreRequestVars(
|
|
7
|
+
runPreRequestVars(
|
|
8
|
+
vars,
|
|
9
|
+
request,
|
|
10
|
+
envVariables,
|
|
11
|
+
collectionVariables,
|
|
12
|
+
collectionPath,
|
|
13
|
+
processEnvVars,
|
|
14
|
+
historyLogger,
|
|
15
|
+
secretVars = {}
|
|
16
|
+
) {
|
|
8
17
|
const enabledVars = _.filter(vars, (v) => v.enabled);
|
|
9
18
|
if (!enabledVars.length) {
|
|
10
19
|
return;
|
|
11
20
|
}
|
|
12
21
|
|
|
13
|
-
const bru = new Bru(
|
|
14
|
-
|
|
22
|
+
const bru = new Bru(
|
|
23
|
+
envVariables,
|
|
24
|
+
collectionVariables,
|
|
25
|
+
processEnvVars,
|
|
26
|
+
null,
|
|
27
|
+
historyLogger,
|
|
28
|
+
undefined, // setHtmlVisualizationString
|
|
29
|
+
secretVars
|
|
30
|
+
);
|
|
31
|
+
const req = new BrunoRequest(request, historyLogger);
|
|
15
32
|
|
|
16
33
|
const bruContext = {
|
|
17
34
|
bru,
|
|
@@ -21,6 +38,7 @@ class VarsRuntime {
|
|
|
21
38
|
const context = {
|
|
22
39
|
...envVariables,
|
|
23
40
|
...collectionVariables,
|
|
41
|
+
...secretVars,
|
|
24
42
|
...bruContext
|
|
25
43
|
};
|
|
26
44
|
|
|
@@ -34,14 +52,32 @@ class VarsRuntime {
|
|
|
34
52
|
};
|
|
35
53
|
}
|
|
36
54
|
|
|
37
|
-
runPostResponseVars(
|
|
55
|
+
runPostResponseVars(
|
|
56
|
+
vars,
|
|
57
|
+
request,
|
|
58
|
+
response,
|
|
59
|
+
envVariables,
|
|
60
|
+
collectionVariables,
|
|
61
|
+
collectionPath,
|
|
62
|
+
processEnvVars,
|
|
63
|
+
historyLogger,
|
|
64
|
+
secretVars = {}
|
|
65
|
+
) {
|
|
38
66
|
const enabledVars = _.filter(vars, (v) => v.enabled);
|
|
39
67
|
if (!enabledVars.length) {
|
|
40
68
|
return;
|
|
41
69
|
}
|
|
42
70
|
|
|
43
|
-
const bru = new Bru(
|
|
44
|
-
|
|
71
|
+
const bru = new Bru(
|
|
72
|
+
envVariables,
|
|
73
|
+
collectionVariables,
|
|
74
|
+
processEnvVars,
|
|
75
|
+
null,
|
|
76
|
+
historyLogger,
|
|
77
|
+
undefined, // setHtmlVisualizationString
|
|
78
|
+
secretVars
|
|
79
|
+
);
|
|
80
|
+
const req = new BrunoRequest(request, historyLogger);
|
|
45
81
|
const res = createResponseParser(response);
|
|
46
82
|
|
|
47
83
|
const bruContext = {
|
|
@@ -53,6 +89,7 @@ class VarsRuntime {
|
|
|
53
89
|
const context = {
|
|
54
90
|
...envVariables,
|
|
55
91
|
...collectionVariables,
|
|
92
|
+
...secretVars,
|
|
56
93
|
...bruContext
|
|
57
94
|
};
|
|
58
95
|
|
package/src/utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const jsonQuery = require('json-query');
|
|
2
2
|
const { get } = require('@usebruno/query');
|
|
3
|
+
const { customAlphabet } = require('nanoid');
|
|
3
4
|
|
|
4
5
|
const JS_KEYWORDS = `
|
|
5
6
|
break case catch class const continue debugger default delete do
|
|
@@ -142,10 +143,20 @@ const cleanJson = (data) => {
|
|
|
142
143
|
}
|
|
143
144
|
};
|
|
144
145
|
|
|
146
|
+
// a customized version of nanoid without using _ and -
|
|
147
|
+
const uuid = () => {
|
|
148
|
+
// https://github.com/ai/nanoid/blob/main/url-alphabet/index.js
|
|
149
|
+
const urlAlphabet = 'useandom26T198340PX75pxJACKVERYMINDBUSHWOLFGQZbfghjklqvwyzrict';
|
|
150
|
+
const customNanoId = customAlphabet(urlAlphabet, 21);
|
|
151
|
+
|
|
152
|
+
return customNanoId();
|
|
153
|
+
};
|
|
154
|
+
|
|
145
155
|
module.exports = {
|
|
146
156
|
evaluateJsExpression,
|
|
147
157
|
evaluateJsTemplateLiteral,
|
|
148
158
|
createResponseParser,
|
|
149
159
|
internalExpressionCache,
|
|
150
|
-
cleanJson
|
|
160
|
+
cleanJson,
|
|
161
|
+
uuid
|
|
151
162
|
};
|