resources/datapoint.js
/* eslint
valid-typeof: 'off'
*/
/**
* Check if override flag is valid.
* @param {Datapoint} dpt - Datapoint object.
* @param {boolean} override - Override flag.
*/
function checkPermissionsOverride(dpt, override) {
const ovr = override || false;
if (dpt.body.permissions && !ovr) {
return false;
}
return true;
}
/**
* Datapoints contain any type of data produced by an action.
*/
class Datapoint {
/**
* Datapoints contain any type of data produced by an action.
* @param {string} type - What kind of Datapoint is this?
* @param {*} format - What type of value does this Datapoint store?
*/
constructor(type, format) {
// Initialize the body property
const body = {};
Object.defineProperty(body, 'body', {
enumerable: false,
configurable: false,
writable: false
});
/**
* Declare empty JSON as body to store values
*/
this.body = body;
this.body.type = null;
this.body.format = null;
this.body.content = {
value: null,
title: null
};
this.body.parent = null;
this.body.permissions = null;
// Add type (if provided)
if (type) this.setType(type);
// Add format (if provided)
if (format) this.setFormat(format);
}
// Getters ====================================
/**
* The data stored in a Datapoint.
*/
get data() {
return this.body;
}
/**
* The data type for the Datapoint's value.
*/
get format() {
return this.body.format;
}
/**
* The type of Datapoint.
*/
get type() {
return this.body.type;
}
/**
* The content of the Datapoint.
*/
get content() {
return this.body.content;
}
/**
* The parent of this Datapoint.
*/
get parent() {
return this.body.parent;
}
/**
* Permissions associated with this Datapoint.
*/
get permissions() {
return this.body.permissions;
}
// Setters ====================================
/**
* Set the type of the Datapoint.
* @param {string} type - What kind of Datapoint is this?
*/
setType(type) {
if (typeof type === 'string') {
this.body.type = type;
return this;
}
const typeErr = 'Type must be a valid string';
throw Error(typeErr);
}
/**
* Set the format of the Datapoint.
* @param {string} format - What type of value does this Datapoint hold?
*/
setFormat(format) {
if (typeof format === 'string') {
this.body.format = format;
return this;
}
const typeErr = 'Type must be a valid string representing a type (string, number)';
throw Error(typeErr);
}
/**
* Set the content of a datapoint.
* @param {*} content - The value of the Datapoint. If object, must have 'value' field.
*/
setContent(content) {
// Make sure we have an object with a value field
let contentObj = {};
if (typeof content == 'object') {
if (!content.value) {
const fmtError = 'Must provide object with value';
throw TypeError(fmtError);
}
contentObj = Object.assign(contentObj, content);
} else {
contentObj.value = content;
}
// Check format
if (!this.body.format) {
const fmtError = 'Datapoint does not have a format specified.';
throw Error(fmtError);
} else if (typeof contentObj.value != this.body.format) {
const fmtError = `Value type must match format: ${this.body.format}`;
throw TypeError(fmtError);
}
// Assign to datapoint
this.body.content = Object.assign(this.body.content, contentObj);
return this;
}
/**
* Set the parent field.
* @param {*} parent - The parent of this process.
*/
setParent(parent) {
this.body.parent = parent;
return this;
}
/**
* Set custom permissions.
* @param {*} perms - Custom permissions object.
* @param {boolean} override - Set as true to override existing permissions.
*/
setCustomPermissions(perms, override) {
if (!checkPermissionsOverride(this, override)) throw Error('This datapoint already has permissions. Override option not specified.');
this.body.permissions = perms;
return this;
}
/**
* Assign permissions using standard format: GET, PUT, and DELETE.
* @param {object} perms - Permissions JSON. Must have GET, PUT, or DELETE fields.
* @param {boolean} override - Set as true to override existing permissions
*/
setPermissions(perms, override) {
if (!checkPermissionsOverride(this, override)) throw Error('This datapoint already has permissions. Override option not specified.');
if ((typeof perms != 'object') && (!perms.GET && !perms.PUT && !perms.DELETE)) {
throw Error('Permissions have GET, PUT, and DELETE fields.');
}
// Add the permission
if (this.body.permissions && typeof this.body.permissions == 'object') {
console.log(this.body.permissions);
this.body.permissions = Object.assign(this.body.permissions, perms);
} else {
this.body.permissions = perms;
}
return this;
}
/**
* Add a new permission.
* @param {string} type - GET, PUT, or DELETE
* @param {*} perm - Who shoudld receive the permission?
*/
addPermission(type, perm) {
if (['GET', 'PUT', 'DELETE'].indexOf(type) < 0) {
throw Error('Permission must be of type GET, PUT, or DELETE. Otherwise, use setCustomPermissions');
}
// If body doesnt have a permissions object, initialize it
if (!this.body.permissions || typeof this.body.permissions != 'object') {
this.body.permissions = {
GET: [],
PUT: [],
DELETE: []
};
}
this.body.permissions[type].push(perm);
return this;
}
/**
* Check for missing fields and generate a JSON object of the datapoint.
*/
generate() {
const myBody = this.body;
['type', 'format', 'content', 'parent'].forEach((fieldName) => {
if (!myBody[fieldName]) {
throw Error(`Missing a field: ${fieldName}`);
}
});
return this.body;
}
/**
* Convert the datapoint to a string.
*/
toString() {
return JSON.stringify(this.data);
}
}
module.exports = Datapoint;