Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

balena-request

balena-io-modules30.2kApache-2.014.1.5TypeScript support: included

Balena HTTP client

balena, request, http

readme

balena-request

Balena HTTP client.

npm version dependencies Build Status Build status ![Gitter](https://badges.gitter.im/Join Chat.svg)

Role

The intention of this module is to provide an exclusive client to make HTTP requests to the balena servers.

THIS MODULE IS LOW LEVEL AND IS NOT MEANT TO BE USED BY END USERS DIRECTLY.

Unless you know what you're doing, use the balena SDK instead.

Installation

Install balena-request by running:

$ npm install --save balena-request

Documentation

The module returns a factory function that you use to get an instance of the auth module.

It accepts the following params:

Param Type Description
options Object options
options.auth Object An instantiated balena-auth instance
options.debug boolean when set to true will log the request details in case of error.
options.isBrowser boolean set to true if the runtime is the browser.
options.interceptors Array<Interceptor> An initial array of interceptors

Example

var request = require('balena-request')({
    auth: auth,
    debug: false,
    isBrowser: false
})

request~getRequest(options)

Kind: inner method of request
Summary: Creates a new balena-request instance.

Param Type
options object
options.auth object
options.debug boolean
options.retries number
options.isBrowser boolean
options.interceptors array

getRequest~interceptors : Array.<Interceptor>

The current array of interceptors to use. Interceptors intercept requests made by calls to .stream() and .send() (some of which are made internally) and are executed in the order they appear in this array for requests, and in the reverse order for responses.

Kind: inner constant of getRequest
Summary: Array of interceptor
Access: public
Example

request.interceptors.push(
    requestError: (error) ->
        console.log(error)
        throw error
)

getRequest~send(options) ⇒ Promise.<Object>

This function automatically handles authorization with balena.

The module scans your environment for a saved session token. Alternatively, you may pass the apiKey option. Otherwise, the request is made anonymously.

Requests can be aborted using an AbortController (with a polyfill like https://www.npmjs.com/package/abortcontroller-polyfill if necessary). This is not well supported everywhere yet, is on a best-efforts basis, and should not be relied upon.

Kind: inner method of getRequest
Summary: Perform an HTTP request to balena
Returns: Promise.<Object> - response
Access: public

Param Type Default Description
options Object | options
[options.method] String 'GET' method
options.url String | relative url
[options.apiKey] String | api key
[options.responseFormat] String | explicit expected response format, can be one of 'blob', 'json', 'text', 'none'. Defaults to sniffing the content-type
[options.signal] AbortSignal | a signal from an AbortController
[options.body] * | body
[options.timeout] number | body

Example

request.send
    method: 'GET'
    baseUrl: 'https://api.balena-cloud.com'
    url: '/foo'
.get('body')

Example

request.send
    method: 'POST'
    baseUrl: 'https://api.balena-cloud.com'
    url: '/bar'
    data:
        hello: 'world'
.get('body')

getRequest~stream(options) ⇒ Promise.<NodeJS.ReadableStream>

This function emits a progress event, passing an object with the following properties:

  • Number percent: from 0 to 100.
  • Number total: total bytes to be transmitted.
  • Number received: number of bytes transmitted.
  • Number eta: estimated remaining time, in seconds.

The stream may also contain the following custom properties:

  • String .mime: Equals the value of the Content-Type HTTP header.

See request.send() for an explanation on how this function handles authentication, and details on how to abort requests.

Kind: inner method of getRequest
Summary: Stream an HTTP response from balena.
Returns: Promise.<NodeJS.ReadableStream> - response
Access: public

Param Type Default Description
options Object | options
[options.method] String 'GET' method
options.url String | relative url
[options.body] * | body

Example

request.stream
    method: 'GET'
    baseUrl: 'https://img.balena-cloud.com'
    url: '/download/foo'
.then (stream) ->
    stream.on 'progress', (state) ->
        console.log(state)

    stream.pipe(fs.createWriteStream('/opt/download'))

getRequest~refreshToken(options) ⇒ Promise.<String>

This function automatically refreshes the authentication token.

Kind: inner method of getRequest
Summary: Refresh token on user request
Returns: Promise.<String> - token - new token
Access: public

Param Type Description
options object
options.baseUrl String relative url

Example

request.refreshToken
    baseUrl: 'https://api.balena-cloud.com'

request~Interceptor : object

An interceptor implements some set of the four interception hook callbacks. To continue processing, each function should return a value or a promise that successfully resolves to a value.

To halt processing, each function should throw an error or return a promise that rejects with an error.

Kind: inner typedef of request
Properties

Name Type Description
[request] function Callback invoked before requests are made. Called with the request options, should return (or resolve to) new request options, or throw/reject.
[response] function Callback invoked before responses are returned. Called with the response, should return (or resolve to) a new response, or throw/reject.
[requestError] function Callback invoked if an error happens before a request. Called with the error itself, caused by a preceeding request interceptor rejecting/throwing an error for the request, or a failing in preflight token validation. Should return (or resolve to) new request options, or throw/reject.
[responseError] function Callback invoked if an error happens in the response. Called with the error itself, caused by a preceeding response interceptor rejecting/throwing an error for the request, a network error, or an error response from the server. Should return (or resolve to) a new response, or throw/reject.

Support

If you're having any problem, please raise an issue on GitHub and the balena team will be happy to help.

Tests

Run the test suite by doing:

$ npm test

Contribute

Before submitting a PR, please make sure that you include tests, and that coffeelint runs without any warning:

$ gulp lint

License

The project is licensed under the Apache 2.0 license.

changelog

Change Log

All notable changes to this project will be documented in this file automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY! This project adheres to Semantic Versioning.

14.1.5 - 2025-05-29

  • Remove no longer needed timekeeper dev dependency [Thodoris Greasidis]

14.1.4 - 2025-05-29

  • Update dependency buffer to v6 [balena-renovate[bot]]

14.1.3 - 2025-05-28

  • Abstract the timeout implementation [Thodoris Greasidis]

14.1.2 - 2025-05-27

  • Simplify the event emitting logic in the stream() method [Thodoris Greasidis]

14.1.1 - 2025-05-27

  • Update dependency temp to ^0.9.0 [balena-renovate[bot]]

14.1.0 - 2025-05-27

  • Add test for stream() progress events [Thodoris Greasidis]
  • tests/stream: Remove redundant response length checks [Thodoris Greasidis]
  • Convert the stream tests to async await [Thodoris Greasidis]
  • Add typing for the progress event on the result of the stream() method [Thodoris Greasidis]

14.0.8 - 2025-05-26

  • Drop fetch-ponyfill in favor of native fetch & node-fetch for streaming downloads [Thodoris Greasidis]
  • Deprecate the isBrowser parameter [Thodoris Greasidis]

14.0.7 - 2025-05-26

  • Drop @balena/node-web-streams [Otavio Jacobi]

14.0.6 - 2025-05-23

  • Clear created setTimeout [Otavio Jacobi]

14.0.5 - 2025-04-11

  • Update dependency sinon to v19 [balena-renovate[bot]]

14.0.4 - 2025-04-10

  • Update dependency @balena/lint to v8 [balena-renovate[bot]]

14.0.3 - 2025-04-09

  • Update dependency mocha to v11 [balena-renovate[bot]]

14.0.2 - 2025-03-19

  • Update dependency balena-config-karma to v4.0.2 [balena-renovate[bot]]

14.0.1 - 2024-12-05

  • Avoid requiring some node dependencies using the package.json browser field [Thodoris Greasidis]

14.0.0 - 2024-12-04

  • Switch tsconfig module to Node16 [Pagan Gazzard]
  • Update form-data-encoder to 4.x and formdata-node to 6.x [Pagan Gazzard]
  • Update tsconfig target to es2017 [Pagan Gazzard]
  • Set type to commonjs in package.json [Pagan Gazzard]

13.3.4 - 2024-12-04

  • Tests: Convert to typescript [Pagan Gazzard]

13.3.3 - 2024-12-03

  • Tests: add missing @types/temp dependency [Pagan Gazzard]
  • Tests: remove bluebird dependency [Pagan Gazzard]
  • Tests: remove rindle dependency [Pagan Gazzard]
  • Update author in package.json [Pagan Gazzard]

13.3.2 - 2024-07-12

  • Fix always following redirects when followRedirect = false [Thodoris Greasidis]

13.3.1 - 2024-02-23

  • Update balena-auth to 6.0.1 [Thodoris Greasidis]

13.3.0 - 2024-02-13

  • Increase TOKEN_REFRESH_INTERVAL from 1 hours to 1 day [Otávio Jacobi]

13.2.1 - 2024-02-13

  • fix: throw BalenaExpiredToken only when token is really expired [Otávio Jacobi]

13.2.0 - 2023-11-01

  • Include the response headers in BalenaRequestErrors [Thodoris Greasidis]
  • Stop using require-npm4-to-publish [Thodoris Greasidis]

13.1.0 - 2023-10-30

  • Add multi part request support when File-like is present [Otávio Jacobi]
  • Update @balena/lint to 7.2.0 Update @balena/lint from 5.4.1 to 7.2.0 [Otávio Jacobi]

13.0.1 - 2023-10-18

  • Update @balena/lint to 7.2.0 Update @balena/lint from 5.4.1 to 7.2.0 [Otávio Jacobi]

13.0.0 - 2023-10-11

  • Drop support for node 14 & 16 [Otávio Jacobi]

12.0.4 - 2023-08-23

  • Refactor the interceptors to stop using .reduce() [Thodoris Greasidis]

12.0.3 - 2023-08-09

  • Avoid deep imports from balena-auth [Thodoris Greasidis]
  • Update balena-auth to 5.1.0 [Thodoris Greasidis]

12.0.2 - 2023-07-25

  • Make url a normal dependency [Thodoris Greasidis]

12.0.1 - 2023-07-24

  • Update balena-auth to 5.0.0 [Thodoris Greasidis]

12.0.0 - 2023-07-14

  • Update TypeScript to 5.1.6 [Thodoris Greasidis]
  • Update mockttp to v3.8.0 [Thodoris Greasidis]
  • Drop support for node < 14 [Thodoris Greasidis]
  • Add querystring-es3 polyfill to fix browser tests [Thodoris Greasidis]
  • tsconfig: Enable skipLibCheck to avoid mockttp nested dependency errors [Thodoris Greasidis]
  • Update TypeScript to 4.9.5 [Thodoris Greasidis]
  • patch: Update flowzone.yml [Kyle Harding]

11.5.10 - 2022-11-02

  • Update balena-errors to v4.7.3 [JSReds]

11.5.9 - 2022-09-26

  • Delete redundant .resinci.yml [Thodoris Greasidis]

11.5.8 - 2022-09-22

  • Fix overriding the whole webpack resolve section of karma tests [Thodoris Greasidis]

11.5.7 - 2022-09-22

  • Replace balenaCI with flowzone [Thodoris Greasidis]
  • Fix tests in node 18 [Thodoris Greasidis]
  • Specify the supported node engines in the package.json [Thodoris Greasidis]

v11.5.6

(2022-09-22)

  • Fix the typings to properly mark the auth parameter as optional [Thodoris Greasidis]
  • Update TypeScript to 4.8.3 [Thodoris Greasidis]

v11.5.5

(2022-04-06)

  • Fix extracting the response error from object response bodies [Thodoris Greasidis]

v11.5.4

(2022-04-06)

  • Drop explicit karma-chrome-launcher devDependency [Thodoris Greasidis]

v11.5.3

(2022-04-05)

  • Use response error as response message if there is one [Matthew Yarmolinsky]

v11.5.2

(2022-04-04)

  • Drop circle.yml [Thodoris Greasidis]

v11.5.1

(2022-04-04)

  • Drop mochainon & bump karma [Thodoris Greasidis]

v11.5.0

(2021-11-28)

  • Convert tests to JavaScript and drop coffeescript [Thodoris Greasidis]
  • Fix the jsdoc generation [Thodoris Greasidis]
  • Convert to typescript and publish typings [Thodoris Greasidis]

v11.4.2

(2021-09-20)

  • Allow overriding the default zlib flush setting [Kyle Harding]

v11.4.1

(2021-08-27)

  • Allow more lenient gzip decompression [Kyle Harding]

v11.4.0

(2021-03-12)

  • Update fetch-ponyfill to v7 [Thodoris Greasidis]

v11.3.0

(2021-03-12)

  • Switch to the versioned token refresh endpoint [Thodoris Greasidis]

v11.2.1

(2021-03-12)

  • Prevent token refresh when no base url is provided [Thodoris Greasidis]

v11.2.0

(2020-11-12)

  • Update balena-auth from 4.0.0 to 4.1.0 [josecoelho]

v11.1.1

(2020-08-13)

  • Stop refreshing the token on absolute urls [Thodoris Greasidis]

v11.1.0

(2020-07-16)

  • Add lazy loading for most modules [Pagan Gazzard]

v11.0.4

(2020-07-14)

  • Fix body overwriting on nodejs [Pagan Gazzard]

v11.0.3

(2020-07-13)

  • Add .versionbot/CHANGELOG.yml for nested changelogs [Pagan Gazzard]

v11.0.2

(2020-07-06)

  • Fix tslib dependency [Pagan Gazzard]

v11.0.1

(2020-07-03)

  • Fix passing baseUrl to refreshToken if the request uses an absolute url [Pagan Gazzard]

v11.0.0

(2020-07-03)

  • Change the browser request timeout error to be consistent with node [Thodoris Greasidis]
  • Bump balena-config-karma & convert karma.conf.coffee to js [Thodoris Greasidis]
  • Switch to a named export [Pagan Gazzard]
  • Update fetch-ponyfill to 6.x [Pagan Gazzard]
  • Remove rindle dependency [Pagan Gazzard]
  • Update balena-auth to 4.x [Pagan Gazzard]
  • Drop support for nodejs < 10 [Pagan Gazzard]
  • Switch to returning native promises [Pagan Gazzard]
  • Convert to type checked javascript [Pagan Gazzard]

v10.0.9

(2020-04-20)

  • Use native check in favour of isEmpty [Pagan Gazzard]
  • Use Object.assign to emulate lodash/defaults [Pagan Gazzard]
  • Switch to native includes [Pagan Gazzard]
  • Remove lodash noop usage [Pagan Gazzard]
  • Switch to native Object.assign [Pagan Gazzard]

10.0.8 - 2020-03-02

  • Remove lodash/parseint [Pagan Gazzard]

10.0.7 - 2020-02-13

  • Use @balena/node-web-streams instead of a GitHub branch [Thodoris Greasidis]

10.0.6 - 2020-02-13

  • Add the build directory to the .gitignore [Thodoris Greasidis]

10.0.5 - 2020-02-13

  • Update github target [Pagan Gazzard]

10.0.4 - 2020-01-21

  • Update dependencies [Pagan Gazzard]

10.0.3 - 2020-01-15

  • Increase the default timeout from 30s to 59s [Pagan Gazzard]
  • Use a prepare script to build on install via git and remove built files [Pagan Gazzard]

10.0.2 - 2019-04-12

  • Fix invalid balena-auth peer dependency [Thodoris Greasidis]

10.0.1 - 2018-11-13

  • Update to new fetch-readablestream that properly supports abort() [Tim Perry]

v10.0.0 - 2018-10-18

  • Rename everything 'resin' to 'balena' [Tim Perry]

v9.3.5 - 2018-09-17

  • Use resinCI for publishing to npm [Thodoris Greasidis]

v9.3.4 - 2018-09-14

  • Stream: Fix Edge bug that causes sending wrong request headers [Thodoris Greasidis]

v9.3.3 - 2018-09-14

  • Chore: Add headless Chrome parameters to work on ResinCi [Thodoris Greasidis]

v9.3.2 - 2018-08-17

  • Add method to do the token refresh #120 [amdomanska]

v9.3.1 - 2018-07-09

  • Ensure request errors whilst streaming are passed on #119 [Tim Perry]
  • Handle errors in aborted requests to avoid uncaught exception warnings #119 [Tim Perry]

v9.3.0 - 2018-07-05

  • Fake Abort in environments with Node streams #118 [Tim Perry]
  • Fake Abort in environments with cancellable response bodies #118 [Tim Perry]
  • Support Abort signals where natively available #118 [Tim Perry]

v9.2.0 - 2018-07-02

  • Add support for streaming in the browser #116 [Tim Perry]

v9.1.0 - 2018-06-12

  • Return the whole body when having a non-object error property #114 [Thodoris Greasidis]

v9.0.3 - 2018-04-25

  • Update jsdoc-to-markdown to fix #110 #112 [Tim Perry]

v9.0.2 - 2017-11-22

  • Set up circleci npm autopublishing #109 [Tim Perry]

v9.0.1 - 2017-11-01

  • Reformat changelog to add versionbot #108 [Tim Perry]

v9.0.0 - 2017-10-31

  • Using resin-auth instead of resin-token

v8.6.0 - 2017-10-05

  • Allow requests to be sent without a token using sendToken: false, even if one exists

v8.5.0 - 2017-07-07

Changed

  • Added the new responseFormat option to send to define the explicit response body format
  • Added proxy support tests

Fixed

  • Fix bug with token error handling when code is minified

v8.4.0 - 2017-04-10

  • Stopped trying to resolve the token if none is provided
  • Updated rindle so that bluebird and lodash can be deduped
  • Removed unused resin-token import, so that it's possible to use the module with api keys without installing resin-token

v8.3.1 - 2017-04-03

  • Peer depend on resin-token 4.0.0

v8.3.0 - 2017-02-23

  • Include request config in errors from failed requests
  • Don't add accept-encoding in browsers by default (since it doesn't work)

v8.2.0 - 2017-02-20

  • Added request interception support.

v8.1.0 - 2017-01-06

Changed

  • Internal refactoring of mocking the fetch requests. New getRequest._setFetch method added.

v8.0.1 - 2017-01-04

Changed

  • Breaking: Resin-Token must now be injected, rather than being built internally
  • Fixed bug where no timeouts were set
  • Timeouts now abort underlying requests (in Node only)

8.0.0 (yanked due to major issues)

v7.0.0 - 2017-01-02

Changed

  • Breaking: Timeouts in requests now use the Bluebird implementation. This changes how errors are thrown slightly: a Promise.TimeoutError is now thrown instead of a raw Error, with the message "operation timed out" instead of "timeout".
  • Fetch is now provided internally (by Fetch-ponyfill), so isomorphic-fetch is no longer required in downstream applications.

v6.2.0 - 2016-12-13

Changed

  • Include 'duration' in debug output, if enabled
  • Added a 'retries' option you can pass to send(), to set the number of times to retry failing requests, or to getRequest directly to set the default number of retries.

v6.1.1 - 2016-12-13

Changed

  • Fixed: in specific environments (like Chrome 54) Response.body is a getter that is impossible to overwrite. As a result it's always the original instance of the ReadableStream. We now clone the response object before assigning the parsed body.

v6.1.0 - 2016-12-13

Changed

  • Lazy-load the dependencies that are not used by the browser code.

v6.0.1 - 2016-11-24

Changed

  • Added the missing qs dependency.

v6.0.0 - 2016-11-20

Changed

  • Breaking! Switch to factory pattern in order to make it work with the new resin-token
  • Fix the apikey query param name

v5.0.0 - 2016-09-15

Changed

  • Updated resin-token to v2.4.3
  • Run tests in the browser
  • Updated node versions to be run on Travis and AppVeyor
  • Breaking! Take API Key as a query option
  • Breaking! Decouple resin-request from resin-settings-client

v4.1.2 - 2016-03-17

Changed

  • Ensure query strings are not encoded when passing an api_key.

v4.1.1 - 2016-03-14

Changed

  • Prevent passing an undefined api_key query string.

v4.1.0 - 2016-03-13

Added

  • Add API key support via RESIN_API_KEY.

v4.0.7 - 2016-03-09

Changed

  • Upgrade dependencies.
  • Fix README example indentation.

v4.0.6 - 2016-03-09

Changed

  • Remove token if its expired.

v4.0.5 - 2016-03-03

Changed

  • Throw ResinExpiredToken if there is a saved token but its expired.

v4.0.4 - 2016-02-18

Added

  • Show debug information when passing DEBUG=true.

Changed

  • Only set a timeout default on non-streaming HTTP requests.

v4.0.3 - 2016-02-17

Changed

  • Set a default timeout of 30 seconds.

v4.0.2 - 2016-02-12

Changed

  • Support baseUrl option.

v4.0.1 - 2016-01-24

Changed

  • Add statusCode property to ResinRequestError instances.

v4.0.0 - 2016-01-20

Removed

  • Remove custom stream .length property.

3.0.0 (yanked due to major issues)

v2.4.3 - 2016-01-20

Changed

  • Make sure we send an Accept-Encoding header on streaming requests.
  • Only disable gzip on streaming requests.
  • Enable strictSSL by default.
  • Change license to Apache 2.0.
  • Fix X-Transfer-Length header not being interpreted correctly.

v2.4.2 - 2016-01-08

Changed

  • Fix X-Transfer-Length decompression bug.

v2.4.1 - 2015-11-23

Changed

  • Fix compressed/uncompressed data piping bug.

v2.4.0 - 2015-11-17

Added

  • Fallback to X-Transfer-Length if no Content-Length.

v2.3.2 - 2015-09-07

Changed

  • Upgrade resin-settings-client to v3.0.0.

v2.3.1 - 2015-08-26

Changed

  • Translate percent to percentage in progress event.

v2.3.0 - 2015-08-25

Added

  • Implement stream custom .mime property.

Changed

  • Document stream custom .length property.

v2.2.5 - 2015-08-24

Changed

  • Use response Content-Length to determine stream length.

v2.2.4 - 2015-08-24

Changed

  • Fix random error when piping a stream.

v2.2.3 - 2015-08-07

Changed

  • Fix unit tests in Appveyor.
  • Upgrade resin-token to v2.4.1.

v2.2.2 - 2015-07-27

Changed

  • Prevent Authorization header from being undefined, which resulted on an exception in `request@2.53.0`.

v2.2.1 - 2015-07-17

Changed

  • Use tokenRefreshInterval setting instead of tokenValidityTime, to decide if it's time to refresh the token.

v2.2.0 - 2015-07-17

Added

  • Add eta property to progress state.
  • Refresh session token at an interval.

v2.1.0 - 2015-06-29

Added

  • Reject request.stream() with the request body if response status code doesn't determine a success.

Changed

  • Upgrade resin-token, which now stops validating a token with the server.

v2.0.0 - 2015-06-18

Added

  • JSDoc documentation.
  • License to every source files.
  • Implement request.stream().

Changed

  • Support promises.
  • Improved README documentation.
  • Rename request() to send().

v1.3.0 - 2015-06-12

Changed

  • Move onProgress callback to options object.

v1.2.5 - 2015-05-18

Changed

  • Upgrade Resin Settings Client to v1.0.1, which defaults remoteUrl to api.resin.io.

v1.2.4 - 2015-05-07

Changed

  • Fix pipe issue.

v1.2.3 - 2015-04-21

Changed

  • Print node-request progress state on DEBUG.

Added

  • Configure Hound CI correctly.

v1.2.2 - 2015-03-20

Added

  • Print request method on DEBUG.

v1.2.1 - 2015-03-20

Added

  • Improve error logging support.
  • Implement DEBUG flag.

v1.2.0 - 2015-03-19

Changed

v1.1.0 - 2015-03-18

Removed

  • options.token option is now obsolete, as the token is fetched automatically with resin-token.