@usebruno/js 0.35.0 → 0.36.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,6 +1,6 @@
1
1
  {
2
2
  "name": "@usebruno/js",
3
- "version": "0.35.0",
3
+ "version": "0.36.0",
4
4
  "license": "MIT",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -16,7 +16,7 @@
16
16
  "prepack": "npm run test"
17
17
  },
18
18
  "dependencies": {
19
- "@usebruno/common": "0.9.0",
19
+ "@usebruno/common": "0.10.0",
20
20
  "@usebruno/crypto-js": "^3.1.9",
21
21
  "@usebruno/query": "0.1.0",
22
22
  "ajv": "^8.12.0",
package/src/bru.js CHANGED
@@ -2,6 +2,7 @@ const { cloneDeep } = require('lodash');
2
2
  const { uuid } = require('./utils');
3
3
  const { interpolate: _interpolate } = require('@usebruno/common');
4
4
  const { sendRequest } = require('@usebruno/requests').scripting;
5
+ const { jar: createCookieJar } = require('@usebruno/common').cookies;
5
6
 
6
7
  const variableNameRegex = /^[\w-.]*$/;
7
8
 
@@ -21,6 +22,50 @@ class Bru {
21
22
  this.setVisualizations = setVisualizations;
22
23
  this.collectionName = collectionName;
23
24
  this.sendRequest = sendRequest;
25
+
26
+ this.cookies = {
27
+ jar: () => {
28
+ const cookieJar = createCookieJar();
29
+
30
+ return {
31
+ getCookie: (url, cookieName, callback) => {
32
+ const interpolatedUrl = this.interpolate(url);
33
+ return cookieJar.getCookie(interpolatedUrl, cookieName, callback);
34
+ },
35
+
36
+ getCookies: (url, callback) => {
37
+ const interpolatedUrl = this.interpolate(url);
38
+ return cookieJar.getCookies(interpolatedUrl, callback);
39
+ },
40
+
41
+ setCookie: (url, nameOrCookieObj, valueOrCallback, maybeCallback) => {
42
+ const interpolatedUrl = this.interpolate(url);
43
+ return cookieJar.setCookie(interpolatedUrl, nameOrCookieObj, valueOrCallback, maybeCallback);
44
+ },
45
+
46
+ setCookies: (url, cookiesArray, callback) => {
47
+ const interpolatedUrl = this.interpolate(url);
48
+ return cookieJar.setCookies(interpolatedUrl, cookiesArray, callback);
49
+ },
50
+
51
+ // Clear entire cookie jar
52
+ clear: (callback) => {
53
+ return cookieJar.clear(callback);
54
+ },
55
+
56
+ // Delete cookies for a specific URL/domain
57
+ deleteCookies: (url, callback) => {
58
+ const interpolatedUrl = this.interpolate(url);
59
+ return cookieJar.deleteCookies(interpolatedUrl, callback);
60
+ },
61
+
62
+ deleteCookie: (url, cookieName, callback) => {
63
+ const interpolatedUrl = this.interpolate(url);
64
+ return cookieJar.deleteCookie(interpolatedUrl, cookieName, callback);
65
+ }
66
+ };
67
+ }
68
+ };
24
69
  this.runner = {
25
70
  skipRequest: () => {
26
71
  this.skipRequest = true;
@@ -9,6 +9,7 @@ class BrunoResponse {
9
9
  this.headers = res ? res.headers : null;
10
10
  this.body = res ? res.data : null;
11
11
  this.responseTime = res ? res.responseTime : null;
12
+ this.url = res?.request ? res.request.protocol + '//' + res.request.host + res.request.path : null;
12
13
 
13
14
  // Make the instance callable
14
15
  const callable = (...args) => get(this.body, ...args);
@@ -42,6 +43,10 @@ class BrunoResponse {
42
43
  return this.res ? this.res.responseTime : null;
43
44
  }
44
45
 
46
+ getUrl() {
47
+ return this.res ? this.url : null;
48
+ }
49
+
45
50
  setBody(data) {
46
51
  if (!this.res) {
47
52
  return;
@@ -173,6 +173,9 @@ const addBruShimToContext = (vm, bru) => {
173
173
  vm.setProp(bruRunnerIterationDataObject, 'stringify', runnerStringifyIterationData);
174
174
  runnerStringifyIterationData.dispose();
175
175
 
176
+ vm.setProp(bruRunnerObject, 'iterationData', bruRunnerIterationDataObject);
177
+ bruRunnerIterationDataObject.dispose();
178
+
176
179
  let visualize = vm.newFunction('visualize', function (type, data) {
177
180
  bru.visualize(vm.dump(type), vm.dump(data));
178
181
  });
@@ -300,8 +303,139 @@ const addBruShimToContext = (vm, bru) => {
300
303
  });
301
304
  sleep.consume((handle) => vm.setProp(bruObject, 'sleep', handle));
302
305
 
303
- vm.setProp(bruRunnerObject, 'iterationData', bruRunnerIterationDataObject);
306
+ let bruCookiesObject = vm.newObject();
307
+
308
+ const _jarFn = vm.newFunction('_jar', () => {
309
+ const nativeJar = bru.cookies.jar();
310
+ const jarObj = vm.newObject();
311
+
312
+ const _getCookieFn = vm.newFunction('_getCookie', (url, cookieName) => {
313
+ const promise = vm.newPromise();
314
+ nativeJar.getCookie(vm.dump(url), vm.dump(cookieName), (err, cookie) => {
315
+ if (err) {
316
+ promise.reject(marshallToVm(cleanJson(err), vm));
317
+ } else {
318
+ promise.resolve(marshallToVm(cleanCircularJson(cookie), vm));
319
+ }
320
+ });
321
+ promise.settled.then(vm.runtime.executePendingJobs);
322
+ return promise.handle;
323
+ });
324
+ _getCookieFn.consume((handle) => vm.setProp(jarObj, '_getCookie', handle));
325
+
326
+ const _getCookiesFn = vm.newFunction('_getCookies', (url) => {
327
+ const promise = vm.newPromise();
328
+ nativeJar.getCookies(vm.dump(url), (err, cookies) => {
329
+ if (err) {
330
+ promise.reject(marshallToVm(cleanJson(err), vm));
331
+ } else {
332
+ promise.resolve(marshallToVm(cleanCircularJson(cookies), vm));
333
+ }
334
+ });
335
+ promise.settled.then(vm.runtime.executePendingJobs);
336
+ return promise.handle;
337
+ });
338
+ _getCookiesFn.consume((handle) => vm.setProp(jarObj, '_getCookies', handle));
339
+
340
+ const _setCookieFn = vm.newFunction('_setCookie', (url, nameOrCookieObj, value) => {
341
+ const promise = vm.newPromise();
342
+ const dumpedUrl = vm.dump(url);
343
+ const dumpedNameOrObj = vm.dump(nameOrCookieObj);
344
+
345
+ // Check if the second argument is an object (cookie object case)
346
+ if (typeof dumpedNameOrObj === 'object' && dumpedNameOrObj !== null) {
347
+ // Cookie object case: setCookie(url, cookieObject, callback)
348
+ nativeJar.setCookie(dumpedUrl, dumpedNameOrObj, (err) => {
349
+ if (err) {
350
+ promise.reject(marshallToVm(cleanJson(err), vm));
351
+ } else {
352
+ promise.resolve(vm.undefined);
353
+ }
354
+ });
355
+ } else {
356
+ // Name/value case: setCookie(url, name, value, callback)
357
+ const dumpedValue = value ? vm.dump(value) : '';
358
+ nativeJar.setCookie(dumpedUrl, dumpedNameOrObj, dumpedValue, (err) => {
359
+ if (err) {
360
+ promise.reject(marshallToVm(cleanJson(err), vm));
361
+ } else {
362
+ promise.resolve(vm.undefined);
363
+ }
364
+ });
365
+ }
366
+
367
+ promise.settled.then(vm.runtime.executePendingJobs);
368
+ return promise.handle;
369
+ });
370
+ _setCookieFn.consume((handle) => vm.setProp(jarObj, '_setCookie', handle));
371
+
372
+ const _setCookiesFn = vm.newFunction('_setCookies', (url, cookiesArray) => {
373
+ const promise = vm.newPromise();
374
+
375
+ nativeJar.setCookies(vm.dump(url), vm.dump(cookiesArray), (err) => {
376
+ if (err) {
377
+ promise.reject(marshallToVm(cleanJson(err), vm));
378
+ } else {
379
+ promise.resolve(vm.undefined);
380
+ }
381
+ });
382
+ promise.settled.then(vm.runtime.executePendingJobs);
383
+ return promise.handle;
384
+ });
385
+ _setCookiesFn.consume((handle) => vm.setProp(jarObj, '_setCookies', handle));
386
+
387
+ const _clearFn = vm.newFunction('_clear', () => {
388
+ const promise = vm.newPromise();
389
+ nativeJar.clear((err) => {
390
+ if (err) {
391
+ promise.reject(marshallToVm(cleanJson(err), vm));
392
+ } else {
393
+ promise.resolve(vm.undefined);
394
+ }
395
+ });
396
+ promise.settled.then(vm.runtime.executePendingJobs);
397
+ return promise.handle;
398
+ });
399
+ _clearFn.consume((handle) => vm.setProp(jarObj, '_clear', handle));
400
+
401
+ const _deleteCookiesFn = vm.newFunction('_deleteCookies', (url) => {
402
+ const promise = vm.newPromise();
403
+ nativeJar.deleteCookies(vm.dump(url), (err) => {
404
+ if (err) {
405
+ promise.reject(marshallToVm(cleanJson(err), vm));
406
+ } else {
407
+ promise.resolve(vm.undefined);
408
+ }
409
+ });
410
+ promise.settled.then(vm.runtime.executePendingJobs);
411
+ return promise.handle;
412
+ });
413
+ _deleteCookiesFn.consume((handle) => vm.setProp(jarObj, '_deleteCookies', handle));
414
+
415
+ const _deleteCookieFn = vm.newFunction('_deleteCookie', (url, cookieName) => {
416
+ const promise = vm.newPromise();
417
+ nativeJar.deleteCookie(vm.dump(url), vm.dump(cookieName), (err) => {
418
+ if (err) {
419
+ promise.reject(marshallToVm(cleanJson(err), vm));
420
+ } else {
421
+ promise.resolve(vm.undefined);
422
+ }
423
+ });
424
+ promise.settled.then(vm.runtime.executePendingJobs);
425
+ return promise.handle;
426
+ });
427
+ _deleteCookieFn.consume((handle) => vm.setProp(jarObj, '_deleteCookie', handle));
428
+
429
+ return jarObj;
430
+ });
431
+ _jarFn.consume((handle) => vm.setProp(bruCookiesObject, '_jar', handle));
432
+
433
+ vm.setProp(bruObject, 'cookies', bruCookiesObject);
434
+ bruCookiesObject.dispose();
435
+
304
436
  vm.setProp(bruObject, 'runner', bruRunnerObject);
437
+ bruRunnerObject.dispose();
438
+
305
439
  vm.setProp(vm.global, 'bru', bruObject);
306
440
  bruObject.dispose();
307
441
 
@@ -325,7 +459,41 @@ const addBruShimToContext = (vm, bru) => {
325
459
  return Promise.reject(err);
326
460
  }
327
461
  }
328
- }
462
+ };
463
+
464
+ globalThis.bru.cookies.jar = () => {
465
+ const _jar = globalThis.bru.cookies._jar();
466
+
467
+ const callWithCallback = async (promiseFn, callback) => {
468
+ if (!callback) return await promiseFn();
469
+ try {
470
+ const result = await promiseFn();
471
+ try { await callback(null, result); } catch(cbErr) { return Promise.reject(cbErr); }
472
+ } catch(err) {
473
+ try { await callback(err, null); } catch(cbErr) { return Promise.reject(cbErr); }
474
+ }
475
+ };
476
+
477
+ return {
478
+ getCookie: (url, name, cb) => callWithCallback(() => _jar._getCookie(url, name), cb),
479
+ getCookies: (url, cb) => callWithCallback(() => _jar._getCookies(url), cb),
480
+ setCookie: (url, nameOrCookieObj, valueOrCallback, maybeCallback) => {
481
+ if (typeof nameOrCookieObj === 'object' && nameOrCookieObj !== null) {
482
+ const callback = typeof valueOrCallback === 'function' ? valueOrCallback : undefined;
483
+ return callWithCallback(() => _jar._setCookie(url, nameOrCookieObj), callback);
484
+ } else {
485
+ const value = typeof valueOrCallback === 'string' ? valueOrCallback : '';
486
+ const callback = typeof maybeCallback === 'function' ? maybeCallback :
487
+ (typeof valueOrCallback === 'function' ? valueOrCallback : undefined);
488
+ return callWithCallback(() => _jar._setCookie(url, nameOrCookieObj, value), callback);
489
+ }
490
+ },
491
+ setCookies: (url, cookiesArray, cb) => callWithCallback(() => _jar._setCookies(url, cookiesArray), cb),
492
+ clear: (cb) => callWithCallback(() => _jar._clear(), cb),
493
+ deleteCookies: (url, cb) => callWithCallback(() => _jar._deleteCookies(url), cb),
494
+ deleteCookie: (url, name, cb) => callWithCallback(() => _jar._deleteCookie(url, name), cb)
495
+ };
496
+ };
329
497
  `);
330
498
  };
331
499
 
@@ -10,17 +10,20 @@ const addBrunoResponseShimToContext = (vm, res) => {
10
10
  const headers = marshallToVm(res?.headers, vm);
11
11
  const body = marshallToVm(res?.body, vm);
12
12
  const responseTime = marshallToVm(res?.responseTime, vm);
13
+ const url = marshallToVm(res?.url, vm);
13
14
 
14
15
  vm.setProp(resFn, 'status', status);
15
16
  vm.setProp(resFn, 'statusText', statusText);
16
17
  vm.setProp(resFn, 'headers', headers);
17
18
  vm.setProp(resFn, 'body', body);
18
19
  vm.setProp(resFn, 'responseTime', responseTime);
20
+ vm.setProp(resFn, 'url', url);
19
21
 
20
22
  status.dispose();
21
23
  headers.dispose();
22
24
  body.dispose();
23
25
  responseTime.dispose();
26
+ url.dispose();
24
27
  statusText.dispose();
25
28
 
26
29
  let getStatusText = vm.newFunction('getStatusText', function () {
@@ -59,6 +62,12 @@ const addBrunoResponseShimToContext = (vm, res) => {
59
62
  vm.setProp(resFn, 'getResponseTime', getResponseTime);
60
63
  getResponseTime.dispose();
61
64
 
65
+ let getUrl = vm.newFunction('getUrl', function () {
66
+ return marshallToVm(res.getUrl(), vm);
67
+ });
68
+ vm.setProp(resFn, 'getUrl', getUrl);
69
+ getUrl.dispose();
70
+
62
71
  let setBody = vm.newFunction('setBody', function (data) {
63
72
  res.setBody(vm.dump(data));
64
73
  });
package/src/utils.js CHANGED
@@ -118,6 +118,7 @@ const createResponseParser = (response = {}) => {
118
118
  res.headers = response.headers;
119
119
  res.body = response.data;
120
120
  res.responseTime = response.responseTime;
121
+ res.url = response.request ? response.request.protocol + '//' + response.request.host + response.request.path : null;
121
122
 
122
123
  res.jq = (expr) => {
123
124
  const output = jsonQuery(expr, { data: response.data });