balena-request 13.3.2 → 13.3.3

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.
@@ -1,3 +1,39 @@
1
+ - commits:
2
+ - subject: "Tests: add missing @types/temp dependency"
3
+ hash: 2698e0be2a764268831bf2388c82fabeeac542a4
4
+ body: ""
5
+ footer:
6
+ Change-type: patch
7
+ change-type: patch
8
+ author: Pagan Gazzard
9
+ nested: []
10
+ - subject: "Tests: remove bluebird dependency"
11
+ hash: 461710c7c2e7b76e7141ae920e668bf93620e745
12
+ body: ""
13
+ footer:
14
+ Change-type: patch
15
+ change-type: patch
16
+ author: Pagan Gazzard
17
+ nested: []
18
+ - subject: "Tests: remove rindle dependency"
19
+ hash: 27fca4510937b79cf796be5985ff251d0cd33ece
20
+ body: ""
21
+ footer:
22
+ Change-type: patch
23
+ change-type: patch
24
+ author: Pagan Gazzard
25
+ nested: []
26
+ - subject: Update `author` in package.json
27
+ hash: b7d09e73d66a2253b672fabae3b4f1d5c111247d
28
+ body: ""
29
+ footer:
30
+ Change-type: patch
31
+ change-type: patch
32
+ author: Pagan Gazzard
33
+ nested: []
34
+ version: 13.3.3
35
+ title: ""
36
+ date: 2024-12-03T15:16:48.769Z
1
37
  - commits:
2
38
  - subject: Fix always following redirects when followRedirect = false
3
39
  hash: 34db7e138eabfcfcfd822133b391c738d01de323
@@ -9,7 +45,7 @@
9
45
  nested: []
10
46
  version: 13.3.2
11
47
  title: ""
12
- date: 2024-07-12T08:40:03.970Z
48
+ date: 2024-07-12T09:16:13.529Z
13
49
  - commits:
14
50
  - subject: Update balena-auth to 6.0.1
15
51
  hash: 1d3cd469288f2dd0e1ed70a292778b70bd518528
package/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file
4
4
  automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
5
5
  This project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## 13.3.3 - 2024-12-03
8
+
9
+ * Tests: add missing @types/temp dependency [Pagan Gazzard]
10
+ * Tests: remove bluebird dependency [Pagan Gazzard]
11
+ * Tests: remove rindle dependency [Pagan Gazzard]
12
+ * Update `author` in package.json [Pagan Gazzard]
13
+
7
14
  ## 13.3.2 - 2024-07-12
8
15
 
9
16
  * Fix always following redirects when followRedirect = false [Thodoris Greasidis]
package/build/request.js CHANGED
@@ -246,17 +246,8 @@ function getRequest({ auth, debug = false, retries = 0, isBrowser = false, inter
246
246
  return download;
247
247
  }
248
248
  // If status code is an error code, interpret the body of the request as an error.
249
- const chunks = [];
250
- download.on('data', function (chunk) {
251
- chunks.push(chunk);
252
- });
253
- yield new Promise((resolve, reject) => {
254
- download.on('error', reject);
255
- download.on('close', resolve);
256
- download.on('end', resolve);
257
- download.on('done', resolve);
258
- });
259
- const responseError = chunks.join() || 'The request was unsuccessful';
249
+ const data = yield utils.getStreamContents(download);
250
+ const responseError = data || 'The request was unsuccessful';
260
251
  debugRequest(options, download.response);
261
252
  // @ts-expect-error error without request options
262
253
  throw new errors.BalenaRequestError(responseError, download.response.statusCode);
package/build/utils.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type BalenaAuth from 'balena-auth';
2
2
  import type { BalenaRequestOptions, BalenaRequestResponse } from './request';
3
+ import { Readable } from 'stream';
3
4
  /**
4
5
  * @module utils
5
6
  */
@@ -147,3 +148,11 @@ export declare function getBody(response: BalenaRequestResponse, responseFormat?
147
148
  * console.log(response)
148
149
  */
149
150
  export declare function getRequestAsync($fetch?: typeof fetch): (options: BalenaRequestOptions) => Promise<BalenaRequestResponse<any>>;
151
+ /**
152
+ * @summary A function that returns the contents of a stream
153
+ * @function
154
+ * @protected
155
+ *
156
+ * @param {Readable} [stream] - the stream to get the contents of
157
+ */
158
+ export declare function getStreamContents(stream: Readable): Promise<string>;
package/build/utils.js CHANGED
@@ -25,6 +25,7 @@ exports.getResponseLength = getResponseLength;
25
25
  exports.debugRequest = debugRequest;
26
26
  exports.getBody = getBody;
27
27
  exports.getRequestAsync = getRequestAsync;
28
+ exports.getStreamContents = getStreamContents;
28
29
  const tslib_1 = require("tslib");
29
30
  const { fetch: normalFetch, Headers: HeadersPonyfill } =
30
31
  // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -477,3 +478,25 @@ function handleAbortIfNotSupported(signal, response) {
477
478
  function getRequestAsync($fetch = normalFetch) {
478
479
  return (options) => requestAsync($fetch, options);
479
480
  }
481
+ /**
482
+ * @summary A function that returns the contents of a stream
483
+ * @function
484
+ * @protected
485
+ *
486
+ * @param {Readable} [stream] - the stream to get the contents of
487
+ */
488
+ function getStreamContents(stream) {
489
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
490
+ const chunks = [];
491
+ stream.on('data', function (chunk) {
492
+ chunks.push(chunk);
493
+ });
494
+ yield new Promise((resolve, reject) => {
495
+ stream.on('error', reject);
496
+ stream.on('close', resolve);
497
+ stream.on('end', resolve);
498
+ stream.on('done', resolve);
499
+ });
500
+ return chunks.join();
501
+ });
502
+ }
package/lib/request.ts CHANGED
@@ -364,17 +364,8 @@ export function getRequest({
364
364
  }
365
365
 
366
366
  // If status code is an error code, interpret the body of the request as an error.
367
- const chunks: unknown[] = [];
368
- download.on('data', function (chunk: unknown) {
369
- chunks.push(chunk);
370
- });
371
- await new Promise((resolve, reject) => {
372
- download.on('error', reject);
373
- download.on('close', resolve);
374
- download.on('end', resolve);
375
- download.on('done', resolve);
376
- });
377
- const responseError = chunks.join() || 'The request was unsuccessful';
367
+ const data = await utils.getStreamContents(download);
368
+ const responseError = data || 'The request was unsuccessful';
378
369
 
379
370
  debugRequest(options, download.response);
380
371
  // @ts-expect-error error without request options
package/lib/utils.ts CHANGED
@@ -544,3 +544,24 @@ function handleAbortIfNotSupported(
544
544
  export function getRequestAsync($fetch: typeof fetch = normalFetch) {
545
545
  return (options: BalenaRequestOptions) => requestAsync($fetch, options);
546
546
  }
547
+
548
+ /**
549
+ * @summary A function that returns the contents of a stream
550
+ * @function
551
+ * @protected
552
+ *
553
+ * @param {Readable} [stream] - the stream to get the contents of
554
+ */
555
+ export async function getStreamContents(stream: Readable) {
556
+ const chunks: unknown[] = [];
557
+ stream.on('data', function (chunk) {
558
+ chunks.push(chunk);
559
+ });
560
+ await new Promise((resolve, reject) => {
561
+ stream.on('error', reject);
562
+ stream.on('close', resolve);
563
+ stream.on('end', resolve);
564
+ stream.on('done', resolve);
565
+ });
566
+ return chunks.join();
567
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "balena-request",
3
- "version": "13.3.2",
3
+ "version": "13.3.3",
4
4
  "description": "Balena HTTP client",
5
5
  "main": "build/request.js",
6
6
  "types": "build/request.d.ts",
@@ -32,7 +32,7 @@
32
32
  "prepare": "npm run build",
33
33
  "readme": "jsdoc2md --template doc/README.hbs build/request.js build/progress.js build/utils.js > README.md"
34
34
  },
35
- "author": "Juan Cruz Viotti <juanchiviotti@gmail.com>",
35
+ "author": "Balena Ltd. <hello@balena.io>",
36
36
  "license": "Apache-2.0",
37
37
  "devDependencies": {
38
38
  "@balena/lint": "^7.2.0",
@@ -43,10 +43,10 @@
43
43
  "@types/progress-stream": "^2.0.0",
44
44
  "@types/qs": "^6.9.3",
45
45
  "@types/sinon": "^10.0.11",
46
+ "@types/temp": "^0.9.4",
46
47
  "assert": "^2.0.0",
47
48
  "balena-auth": "^6.0.1",
48
49
  "balena-config-karma": "4.0.0",
49
- "bluebird": "^3.7.2",
50
50
  "browserify-zlib": "^0.2.0",
51
51
  "buffer": "^5.7.1",
52
52
  "chai": "^4.3.4",
@@ -57,9 +57,9 @@
57
57
  "mockttp": "^3.8.0",
58
58
  "process": "^0.11.10",
59
59
  "querystring-es3": "^0.2.1",
60
- "rindle": "^1.3.6",
61
60
  "sinon": "^15.0.1",
62
61
  "stream-browserify": "^3.0.0",
62
+ "string-to-stream": "^3.0.1",
63
63
  "temp": "^0.8.4",
64
64
  "timekeeper": "^1.0.0",
65
65
  "ts-node": "^10.9.1",
@@ -82,6 +82,6 @@
82
82
  "balena-auth": "^6.0.1"
83
83
  },
84
84
  "versionist": {
85
- "publishedAt": "2024-07-12T08:40:04.114Z"
85
+ "publishedAt": "2024-12-03T15:16:48.906Z"
86
86
  }
87
87
  }
@@ -1,6 +1,5 @@
1
1
  import { expect } from 'chai';
2
2
  import setup from './setup';
3
- import * as rindle from 'rindle';
4
3
  import * as sinon from 'sinon';
5
4
  import * as mockhttp from 'mockttp';
6
5
  import * as tokens from './tokens.json';
@@ -93,7 +92,7 @@ describe('Request (api key):', function () {
93
92
  expect(stream.response.request.uri.query).to.equal(
94
93
  'apikey=123456789',
95
94
  );
96
- return rindle.extract(stream);
95
+ return utils.getStreamContents(stream);
97
96
  })));
98
97
  });
99
98
 
@@ -141,7 +140,7 @@ describe('Request (api key):', function () {
141
140
  expect(stream.response.request.uri.query).to.equal(
142
141
  'apikey=123456789',
143
142
  );
144
- return rindle.extract(stream);
143
+ return utils.getStreamContents(stream);
145
144
  }));
146
145
 
147
146
  it('should still send an Authorization header', () =>
@@ -157,7 +156,7 @@ describe('Request (api key):', function () {
157
156
  expect(headers.Authorization).to.equal(
158
157
  `Bearer ${johnDoeFixture.token}`,
159
158
  );
160
- return rindle.extract(stream);
159
+ return utils.getStreamContents(stream);
161
160
  }));
162
161
  });
163
162
  });
@@ -191,7 +190,7 @@ describe('Request (api key):', function () {
191
190
  })
192
191
  .then(function (stream) {
193
192
  expect(stream.response.request.uri.query).to.not.exist;
194
- return rindle.extract(stream);
193
+ return utils.getStreamContents(stream);
195
194
  })));
196
195
  }));
197
196
  });
@@ -1,14 +1,13 @@
1
1
  import { expect } from 'chai';
2
2
  import setup from './setup';
3
- import * as Bluebird from 'bluebird';
4
- import * as rindle from 'rindle';
3
+ import * as stringToStream from 'string-to-stream';
5
4
  import * as sinon from 'sinon';
6
5
  import * as mockhttp from 'mockttp';
7
6
  import * as utils from '../build/utils';
8
7
 
9
8
  const mockServer = mockhttp.getLocal();
10
9
 
11
- const { auth, request } = setup();
10
+ const { auth, request, delay } = setup();
12
11
 
13
12
  describe('An interceptor', function () {
14
13
  this.timeout(10000);
@@ -58,7 +57,7 @@ describe('An interceptor', function () {
58
57
  it('should be able to asynchronously change a request before it is sent', function () {
59
58
  request.interceptors[0] = {
60
59
  request(req) {
61
- return Bluebird.delay(100).then(() =>
60
+ return delay(100).then(() =>
62
61
  Object.assign({}, req, { url: mockServer.urlFor('/changed') }),
63
62
  );
64
63
  },
@@ -102,7 +101,7 @@ describe('An interceptor', function () {
102
101
  .stream({
103
102
  url: mockServer.urlFor('/original'),
104
103
  })
105
- .then(rindle.extract)
104
+ .then(utils.getStreamContents)
106
105
  .then(function (data) {
107
106
  const body = JSON.parse(data);
108
107
  expect(body).to.deep.equal({ requested: 'changed' });
@@ -256,7 +255,7 @@ describe('An interceptor', function () {
256
255
  it('should be able to asynchronously change a response before it is returned', function () {
257
256
  request.interceptors[0] = {
258
257
  response(response) {
259
- return Bluebird.delay(100).then(() =>
258
+ return delay(100).then(() =>
260
259
  Object.assign({}, response, { body: { replaced: true } }),
261
260
  );
262
261
  },
@@ -295,7 +294,7 @@ describe('An interceptor', function () {
295
294
  it('should be able to change a stream response before it is returned', function () {
296
295
  request.interceptors[0] = {
297
296
  response() {
298
- return rindle.getStreamFromString('replacement stream');
297
+ return stringToStream('replacement stream');
299
298
  },
300
299
  };
301
300
 
@@ -303,7 +302,7 @@ describe('An interceptor', function () {
303
302
  .stream({
304
303
  url: mockServer.urlFor('/original'),
305
304
  })
306
- .then(rindle.extract)
305
+ .then(utils.getStreamContents)
307
306
  .then((data) => expect(data).to.equal('replacement stream'));
308
307
  });
309
308
  });
@@ -6,13 +6,7 @@ import * as mockhttp from 'mockttp';
6
6
 
7
7
  const mockServer = mockhttp.getLocal();
8
8
 
9
- const { auth, request, getCustomRequest, IS_BROWSER } = setup();
10
-
11
- // Grab setTimeout before we replace it with a fake later, so
12
- // we can still do real waiting in the tests themselves
13
- const unstubbedSetTimeout = setTimeout;
14
- const delay = (delayMs) =>
15
- new Promise((resolve) => unstubbedSetTimeout(resolve, delayMs));
9
+ const { auth, request, getCustomRequest, IS_BROWSER, delay } = setup();
16
10
 
17
11
  class TestFile extends Blob {
18
12
  constructor(blobParts, name, type) {
package/tests/setup.js CHANGED
@@ -27,9 +27,16 @@ const getCustomRequest = function (opts) {
27
27
  return getRequest(opts);
28
28
  };
29
29
 
30
+ // Grab setTimeout before we replace it with a fake later, so
31
+ // we can still do real waiting in the tests themselves
32
+ const unstubbedSetTimeout = setTimeout;
33
+ const delay = (delayMs) =>
34
+ new Promise((resolve) => unstubbedSetTimeout(resolve, delayMs));
35
+
30
36
  export default () => ({
31
37
  IS_BROWSER,
32
38
  auth,
33
39
  request: getCustomRequest(),
34
40
  getCustomRequest,
41
+ delay,
35
42
  });
@@ -1,15 +1,23 @@
1
1
  import { PassThrough } from 'stream';
2
2
  import { expect } from 'chai';
3
3
  import setup from './setup';
4
- import * as Bluebird from 'bluebird';
5
- import * as rindle from 'rindle';
6
4
  import * as zlib from 'browserify-zlib';
7
5
  import * as mockhttp from 'mockttp';
6
+ import * as utils from '../build/utils';
8
7
 
9
8
  const mockServer = mockhttp.getLocal();
10
9
 
11
- const { auth, request } = setup();
12
- const gzip = Bluebird.promisify(zlib.gzip);
10
+ const { auth, request, delay } = setup();
11
+ const gzip = (contents) =>
12
+ new Promise((resolve, reject) =>
13
+ zlib.gzip(contents, (err, res) => {
14
+ if (err) {
15
+ reject(err);
16
+ } else {
17
+ resolve(res);
18
+ }
19
+ }),
20
+ );
13
21
 
14
22
  describe('Request (stream):', function () {
15
23
  beforeEach(() => Promise.all([auth.removeKey(), mockServer.start()]));
@@ -53,7 +61,7 @@ describe('Request (stream):', function () {
53
61
  baseUrl: mockServer.url,
54
62
  url: '/foo',
55
63
  })
56
- .then(rindle.extract)
64
+ .then(utils.getStreamContents)
57
65
  .then((data) => expect(data).to.equal('Lorem ipsum dolor sit amet')));
58
66
 
59
67
  it('should be able to pipe the response after a delay', () =>
@@ -63,13 +71,13 @@ describe('Request (stream):', function () {
63
71
  baseUrl: mockServer.url,
64
72
  url: '/foo',
65
73
  })
66
- .then((stream) => Bluebird.delay(200).return(stream))
74
+ .then((stream) => delay(200).then(() => stream))
67
75
  .then(function (stream) {
68
76
  const pass = new PassThrough();
69
77
  stream.pipe(pass);
70
78
 
71
- return rindle
72
- .extract(pass)
79
+ return utils
80
+ .getStreamContents(pass)
73
81
  .then((data) =>
74
82
  expect(data).to.equal('Lorem ipsum dolor sit amet'),
75
83
  );
@@ -92,7 +100,7 @@ describe('Request (stream):', function () {
92
100
  baseUrl: mockServer.url,
93
101
  url: '/foo',
94
102
  })
95
- .then(rindle.extract)
103
+ .then(utils.getStreamContents)
96
104
  .then((data) => expect(data).to.equal('GET'))));
97
105
  });
98
106
 
@@ -114,7 +122,7 @@ describe('Request (stream):', function () {
114
122
  baseUrl: mockServer.url,
115
123
  url: '/foo',
116
124
  })
117
- .then((stream) => rindle.extract(stream))
125
+ .then((stream) => utils.getStreamContents(stream))
118
126
  .then(function (data) {
119
127
  expect(data).to.equal('Lorem ipsum dolor sit amet');
120
128
  return expect(data.length).to.equal(26);
@@ -147,7 +155,7 @@ describe('Request (stream):', function () {
147
155
  baseUrl: mockServer.url,
148
156
  url: '/foo',
149
157
  })
150
- .then((stream) => rindle.extract(stream))
158
+ .then((stream) => utils.getStreamContents(stream))
151
159
  .then(function (data) {
152
160
  expect(data).to.equal('Lorem ipsum dolor sit amet');
153
161
  return expect(data.length).to.equal(26);
@@ -173,7 +181,7 @@ describe('Request (stream):', function () {
173
181
  baseUrl: mockServer.url,
174
182
  url: '/foo',
175
183
  })
176
- .then((stream) => rindle.extract(stream))
184
+ .then((stream) => utils.getStreamContents(stream))
177
185
  .then(function (data) {
178
186
  expect(data).to.equal('Lorem ipsum dolor sit amet');
179
187
  return expect(data.length).to.equal(26);
@@ -1,6 +1,5 @@
1
1
  import { expect } from 'chai';
2
2
  import setup from './setup';
3
- import * as rindle from 'rindle';
4
3
  import * as sinon from 'sinon';
5
4
  import * as errors from 'balena-errors';
6
5
  import * as mockhttp from 'mockttp';
@@ -307,7 +306,7 @@ describe('Request (token):', function () {
307
306
  expect(headers.Authorization).to.equal(
308
307
  `Bearer ${johnDoeFixture.token}`,
309
308
  );
310
- return rindle.extract(stream);
309
+ return utils.getStreamContents(stream);
311
310
  }));
312
311
  });
313
312
 
@@ -324,7 +323,7 @@ describe('Request (token):', function () {
324
323
  .then(function (stream) {
325
324
  const { headers } = stream.response.request;
326
325
  expect(headers.Authorization).to.not.exist;
327
- return rindle.extract(stream);
326
+ return utils.getStreamContents(stream);
328
327
  }));
329
328
  });
330
329
  });