/**
* The base class for entities such as Job, Process Graph, Service etc.
*
* @abstract
*/
class BaseEntity {
/**
* Creates an instance of this object.
*
* @param {Connection} connection - A Connection object representing an established connection to an openEO back-end.
* @param {Array.<string|Array.<string>>} properties - A mapping from the API property names to the JS client property names (usually to convert between snake_case and camelCase), e.g. `["id", "title", ["process_graph", "processGraph"]]`
*/
constructor(connection, properties = []) {
/**
* @protected
* @type {Connection}
*/
this.connection = connection;
/**
* @protected
* @type {object.<string, string>}
*/
this.apiToClientNames = {};
/**
* @protected
* @type {object.<string, string>}
*/
this.clientToApiNames = {};
/**
* @protected
* @type {number}
*/
this.lastRefreshTime = 0;
/**
* Additional (non-standardized) properties received from the API.
*
* @protected
* @type {object.<string, *>}
*/
this.extra = {};
for(let i in properties) {
let backend, client;
if (Array.isArray(properties[i])) {
backend = properties[i][0];
client = properties[i][1];
}
else {
backend = properties[i];
client = properties[i];
}
this.apiToClientNames[backend] = client;
this.clientToApiNames[client] = backend;
}
}
/**
* Returns a JSON serializable representation of the data that is API compliant.
*
* @returns {object.<string, *>}
*/
toJSON() {
let obj = {};
for(let key in this.clientToApiNames) {
let apiKey = this.clientToApiNames[key];
if (typeof this[key] !== 'undefined') {
obj[apiKey] = this[key];
}
}
return Object.assign(obj, this.extra);
}
/**
* Converts the data from an API response into data suitable for our JS client models.
*
* @param {object.<string, *>} metadata - JSON object originating from an API response.
* @returns {BaseEntity} Returns the object itself.
*/
setAll(metadata) {
for(let name in metadata) {
if (typeof this.apiToClientNames[name] === 'undefined') {
this.extra[name] = metadata[name];
}
else {
this[this.apiToClientNames[name]] = metadata[name];
}
}
this.lastRefreshTime = Date.now();
return this;
}
/**
* Returns the age of the data in seconds.
*
* @returns {number} Age of the data in seconds as integer.
*/
getDataAge() {
return (Date.now() - this.lastRefreshTime) / 1000;
}
/**
* Returns all data in the model.
*
* @returns {object.<string, *>}
*/
getAll() {
let obj = {};
for(let backend in this.apiToClientNames) {
let client = this.apiToClientNames[backend];
if (typeof this[client] !== 'undefined') {
obj[client] = this[client];
}
}
return Object.assign(obj, this.extra);
}
/**
* Get a value from the additional data that is not part of the core model, i.e. from proprietary extensions.
*
* @param {string} name - Name of the property.
* @returns {*} The value, which could be of any type.
*/
get(name) {
return typeof this.extra[name] !== 'undefined' ? this.extra[name] : null;
}
/**
* Converts the object to a valid objects for API requests.
*
* @param {object.<string, *>} parameters
* @returns {object.<string, *>}
* @protected
*/
_convertToRequest(parameters) {
let request = {};
for(let key in parameters) {
if (typeof this.clientToApiNames[key] === 'undefined') {
request[key] = parameters[key];
}
else {
request[this.clientToApiNames[key]] = parameters[key];
}
}
return request;
}
/**
* Checks whether a features is supported by the API.
*
* @param {string} feature
* @returns {boolean}
* @protected
* @see Capabilities#hasFeature
*/
_supports(feature) {
return this.connection.capabilities().hasFeature(feature);
}
}
module.exports = BaseEntity;