Skip to content

Commit

Permalink
Add jsdocs to the helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
gcampax committed Oct 1, 2019
1 parent 04a43f4 commit 0d57bfd
Show file tree
Hide file tree
Showing 8 changed files with 340 additions and 21 deletions.
2 changes: 2 additions & 0 deletions lib/base_client.js
Expand Up @@ -16,6 +16,8 @@ const Mixins = require('./mixins.json');
*
* Accessing the Thingpedia API from Almond occurs in a platform-specific manner,
* through clients that extend this class.
*
* @interface
*/
class BaseClient {
/**
Expand Down
2 changes: 2 additions & 0 deletions lib/config_delegate.js
Expand Up @@ -15,6 +15,8 @@
*
* This class exists mostly for documentation, it's not actually used
* because JS does not have interfaces or multiple inheritance.
*
* @interface
*/
class ConfigDelegate {
/**
Expand Down
135 changes: 135 additions & 0 deletions lib/helpers/http.js
Expand Up @@ -159,10 +159,145 @@ function httpDownloadStream(url, method, data, options) {
return httpRequestStream(url, method, data, options, false, true);
}

/**
* HTTP Helpers.
*
* @namespace
* @alias module:Helpers.Http
*/
module.exports = {
/**
* Perform a buffered HTTP request with a custom method.
*
* @param {string} url - the URL to POST to
* @param {string} method - the HTTP method to use
* @param {string|null} data - the content of the request body; you can pass `null` for an empty body
* @param {Object} [options] - request options
* @param {string} [options.dataContentType] - the value of the `Content-Type` request header
* @param {string} [options.auth] - the value of `Authorization` header
* @param {string} [options.accept] - the value of `Accept` header
* @param {BaseDevice} [options.useOAuth2] - if set, the `Authorization` header will be computed for the passed
* device based on the OAuth 2.0 standard; using this option also enables
* automatic refresh token handling (if the refresh token exists); this
* option is ignored if `auth` is also set
* @param {string} [options.authMethod=Bearer] - set this to override the prefix of the `Authorization` header;
* this option is ignored unless `useOAuth2` is set
* @param {string} [options.user-agent] - set the `User-Agent` header; if unset a default user agent is used
* @param {Object.<string,string>} [options.extraHeaders] - other request headers to set
* @param {boolean} [options.ignoreErrors=false] - set to `true` to ignore errors (HTTP statuses 300 and higher)
* @param {boolean} [options.followRedirects=true] - set to `false` to disable automatic handling of HTTP redirects (status 301, 302 and 303)
* @param {boolean} [options.raw=false] - return the binary response body instead of converting to a string
* @return {string|Array} either the string response body, or a tuple with {@link Buffer} and content type.
* @function
* @async
*/
request: httpRequest,

/**
* Perform a buffered HTTP GET.
*
* If `options.raw` is set, returns a tuple of the response (as a `Buffer`) and the `Content-Type` header.
* Otherwise, it returns the response body as a string.
* If the HTTP request fails (returns a status code greater or equal to 300), the promise is rejected.
* The resulting `Error` object will have a `code` property containing the actual HTTP status code.
* If the HTTP status code is a redirect (between 300 and 399 inclusive), the `redirect` property
* on the error will contain the value of the `Location` header.
*
* @param {string} url - the URL to retrieve
* @param {Object} [options] - request options
* @param {string} [options.auth] - the value of `Authorization` header
* @param {string} [options.accept] - the value of `Accept` header
* @param {BaseDevice} [options.useOAuth2] - if set, the `Authorization` header will be computed for the passed
* device based on the OAuth 2.0 standard; using this option also enables
* automatic refresh token handling (if the refresh token exists); this
* option is ignored if `auth` is also set
* @param {string} [options.authMethod=Bearer] - set this to override the prefix of the `Authorization` header;
* this option is ignored unless `useOAuth2` is set
* @param {string} [options.user-agent] - set the `User-Agent` header; if unset a default user agent is used
* @param {Object.<string,string>} [options.extraHeaders] - other request headers to set
* @param {boolean} [options.ignoreErrors=false] - set to `true` to ignore errors (HTTP statuses 300 and higher)
* @param {boolean} [options.followRedirects=true] - set to `false` to disable automatic handling of HTTP redirects (status 301, 302 and 303)
* @param {boolean} [options.raw=false] - return the binary response body instead of converting to a string
* @return {string|Array} either the string response body, or a tuple with {@link Buffer} and content type.
* @async
*/
get(url, options) { return httpRequest(url, 'GET', null, options); },

/**
* Perform a buffered HTTP POST.
*
* @param {string} url - the URL to POST to
* @param {string|null} data - the content of the request body; you can pass `null` for an empty body
* @param {Object} [options] - request options
* @param {string} [options.dataContentType] - the value of the `Content-Type` request header
* @param {string} [options.auth] - the value of `Authorization` header
* @param {string} [options.accept] - the value of `Accept` header
* @param {BaseDevice} [options.useOAuth2] - if set, the `Authorization` header will be computed for the passed
* device based on the OAuth 2.0 standard; using this option also enables
* automatic refresh token handling (if the refresh token exists); this
* option is ignored if `auth` is also set
* @param {string} [options.authMethod=Bearer] - set this to override the prefix of the `Authorization` header;
* this option is ignored unless `useOAuth2` is set
* @param {string} [options.user-agent] - set the `User-Agent` header; if unset a default user agent is used
* @param {Object.<string,string>} [options.extraHeaders] - other request headers to set
* @param {boolean} [options.ignoreErrors=false] - set to `true` to ignore errors (HTTP statuses 300 and higher)
* @param {boolean} [options.followRedirects=true] - set to `false` to disable automatic handling of HTTP redirects (status 301, 302 and 303)
* @param {boolean} [options.raw=false] - return the binary response body instead of converting to a string
* @return {string|Array} either the string response body, or a tuple with {@link Buffer} and content type.
* @async
*/
post(url, data, options) { return httpRequest(url, 'POST', data, options); },

/**
* Perform a stream HTTP POST request.
*
* The response will be buffered as with {@link module:Helpers.Http.post}.
*
* @param {string} url - the URL to POST to
* @param {string|null} data - the content of the request body; you can pass `null` for an empty body
* @param {Object} [options] - request options
* @param {string} [options.dataContentType] - the value of the `Content-Type` request header
* @param {string} [options.auth] - the value of `Authorization` header
* @param {string} [options.accept] - the value of `Accept` header
* @param {BaseDevice} [options.useOAuth2] - if set, the `Authorization` header will be computed for the passed
* device based on the OAuth 2.0 standard; using this option also enables
* automatic refresh token handling (if the refresh token exists); this
* option is ignored if `auth` is also set
* @param {string} [options.authMethod=Bearer] - set this to override the prefix of the `Authorization` header;
* this option is ignored unless `useOAuth2` is set
* @param {string} [options.user-agent] - set the `User-Agent` header; if unset a default user agent is used
* @param {Object.<string,string>} [options.extraHeaders] - other request headers to set
* @param {boolean} [options.ignoreErrors=false] - set to `true` to ignore errors (HTTP statuses 300 and higher)
* @param {boolean} [options.followRedirects=true] - set to `false` to disable automatic handling of HTTP redirects (status 301, 302 and 303)
* @param {boolean} [options.raw=false] - return the binary response body instead of converting to a string
* @return {string|Array} either the string response body, or a tuple with {@link Buffer} and content type.
* @async
*/
postStream(url, data, options) { return httpUploadStream(url, 'POST', data, options); },

/**
* Perform a streaming GET request.
*
*
* The result is the [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
* from the underlying nodejs HTTP API. The result is also a `stream.Readable` and can be used as such.
*
* @param {string} url - the URL to retrieve
* @param {Object} [options] - request options
* @param {string} [options.auth] - the value of `Authorization` header
* @param {string} [options.accept] - the value of `Accept` header
* @param {BaseDevice} [options.useOAuth2] - if set, the `Authorization` header will be computed for the passed
* device based on the OAuth 2.0 standard; using this option also enables
* automatic refresh token handling (if the refresh token exists); this
* option is ignored if `auth` is also set
* @param {string} [options.authMethod=Bearer] - set this to override the prefix of the `Authorization` header;
* this option is ignored unless `useOAuth2` is set
* @param {string} [options.user-agent] - set the `User-Agent` header; if unset a default user agent is used
* @param {Object.<string,string>} [options.extraHeaders] - other request headers to set
* @param {boolean} [options.ignoreErrors=false] - set to `true` to ignore errors (HTTP statuses 300 and higher)
* @param {boolean} [options.followRedirects=true] - set to `false` to disable automatic handling of HTTP redirects (status 301, 302 and 303)
* @return {http.IncomingMessage} the server response
* @async
*/
getStream(url, options) { return httpDownloadStream(url, 'GET', null, options); },
};
85 changes: 74 additions & 11 deletions lib/helpers/object_set.js
Expand Up @@ -11,42 +11,98 @@

const events = require('events');

// The abstract interface that all ObjectSets must conform to
//
// Some ObjectSets are read-only, in which case the mutator methods will fail
class ObjectSet extends events.EventEmitter {
// events: object-added(object), object-removed(object)

/**
* The abstract interface that all ObjectSets must conform to.
*
* @memberof! module:Helpers.ObjectSet
*/
class Base extends events.EventEmitter {
/**
* Notifies that an object was to this set.
*
* @event module:Helpers.ObjectSet.Base#object-added
* @param {Object} object - the added object
*/
/**
* Notifies that an object was removed from this set.
*
* @event module:Helpers.ObjectSet.Base#object-removed
* @param {Object} object - the just-removed object
*/

/**
* @protected
*/
constructor() {
super();
this.setMaxListeners(Infinity);
}

/**
* Report the addition of an object.
*
* @param {Object} o - the added object
* @fires module:Helpers.ObjectSet.Base#object-added
* @protected
*/
objectAdded(o) {
this.emit('object-added', o);
}

/**
* Report the removal of an object.
*
* @param {Object} o - the removed object
* @fires module:Helpers.ObjectSet.Base#object-removed
* @protected
*/
objectRemoved(o) {
this.emit('object-removed', o);
}

/* istanbul ignore next */
/**
* List all objects currently in the set.
*
* @return {Object[]} - the objects in the set
* @abstract
*/
values() {
throw new Error('Not Implemented');
}

/* istanbul ignore next */
start() {
/**
* Start this object set.
*
* This should be called for ObjectSets whose content
* changes dynamically.
* @abstract
*/
async start() {
throw new Error('Not Implemented');
}

/* istanbul ignore next */
stop() {
/**
* Stop this object set.
*
* This should be called for ObjectSets whose content
* changes dynamically.
* @abstract
*/
async stop() {
throw new Error('Not Implemented');
}
}

class SimpleObjectSet extends ObjectSet {
/**
* A simple implementation of {@link module:Helpers.ObjectSet.Base} backed by a {@link Map}.
*
* @extends module:Helpers.ObjectSet.Base
* @memberof! module:Helpers.ObjectSet
*/
class Simple extends Base {
constructor() {
super();

Expand Down Expand Up @@ -132,7 +188,14 @@ class SimpleObjectSet extends ObjectSet {
}
}

/**
* ObjectSet is an abstract set data structure that can be monitored for additions
* and removal.
*
* @namespace
* @alias module:Helpers.ObjectSet
*/
module.exports = {
Simple: SimpleObjectSet,
Base: ObjectSet
Simple,
Base
};
31 changes: 28 additions & 3 deletions lib/helpers/polling.js
Expand Up @@ -11,7 +11,29 @@

const stream = require('stream');

module.exports = class PollingStream extends stream.Readable {
/**
* Callback called when polling.
*
* The callback should poll the underlying API and return the current results.
*
* @callback module:Helpers~PollCallback
* @return {Object[]} the current list of results
*/

/**
* A stream.Readable implementation that emits new values at specific interval.
*
* @extends stream.Readable
* @alias module:Helpers.PollingStream
*/
class PollingStream extends stream.Readable {
/**
* Construct a new polling stream.
*
* @param {TriggerStateBinder} state - a state binder object
* @param {number} interval - polling interval, in milliseconds
* @param {module:Helpers~PollCallback} callback - function to call every poll interval
*/
constructor(state, interval, callback) {
super({ objectMode: true });

Expand All @@ -22,6 +44,9 @@ module.exports = class PollingStream extends stream.Readable {
this._destroyed = false;
}

/**
* Destroy the current stream (stop polling).
*/
destroy() {
if (this._timeout === null)
return;
Expand Down Expand Up @@ -65,5 +90,5 @@ module.exports = class PollingStream extends stream.Readable {
if (this._timeout === null)
this._nextTimeout();
}
};

}
module.exports = PollingStream;

0 comments on commit 0d57bfd

Please sign in to comment.