UNPKG

d2

Version:

Javascript library for DHIS2

151 lines (140 loc) 4.8 kB
import Api from '../api/Api' import { isString, isArray } from '../lib/check' /** * @private * @description * Represents a namespace in the dataStore that can be used to be used to interact with * the remote API. * * @property {Array} keys an array of the loaded keys. * @property {String} namespace name of this namespace as on the server. * * @memberof module:datastore */ class BaseStoreNamespace { /** * @param {string} namespace - the name of the namespace this represents. * @param {string[]} keys - preloaded keys for this namespace. * @param {module:api.Api} api - the api implementation, used for testing. * @param {string} endPoint - the relative API-endpoint, one of ['dataStore, userDataStore']. */ constructor(namespace, keys, api = Api.getApi(), endPoint) { if (!isString(namespace)) { throw new Error( 'BaseStoreNamespace must be called with a string to identify the Namespace' ) } if (!isString(endPoint)) { throw new Error( 'BaseStoreNamespace must be called with an endPoint' ) } if (this.constructor === BaseStoreNamespace) { throw new Error("Can't instantiate abstract class!") } this.api = api /** * The name of the namespace * @type {string} */ this.namespace = namespace /** * an array of the loaded keys. * @type {string[]} */ this.keys = keys || [] this.endPoint = endPoint } /** * Get the keys for this namespace. * * @returns {Promise} - The internal list of keys for current namespace. */ getKeys() { return this.api .get([this.endPoint, this.namespace].join('/')) .then(response => { if (response && isArray(response)) { this.keys = response return response } return Promise.reject( new Error( 'The requested namespace has no keys or does not exist.' ) ) }) } /** * Retrieves the value of given key in current namespace. * * @param key - key to retrieve. * @returns {Promise} - The value of the given key. */ get(key) { return this.api.get([this.endPoint, this.namespace, key].join('/')) } /** * Sets the value of given key to given value. * * This will also create a new namespace on the API-end if it does not exist. * If the key exists <a href='#update'> update</a> will be called, unless <code>overrideUpdate</code> equals * true. * * @param key - key in this namespace to set. * @param value - JSON-value to be set. * @param [overrideUpdate=false] - If true a post-request is sent even if key exists. * @param [encrypt=false] - If the value should be encrypted on the server. * @returns {Promise} - the response body from the {@link module:api.Api#get API}. */ set(key, value, overrideUpdate = false, encrypt = false) { if (!overrideUpdate && this.keys.includes(key)) { return this.update(key, value) } const queryParams = encrypt === true ? '?encrypt=true' : '' return this.api .post( [this.endPoint, this.namespace, key + queryParams].join('/'), value ) .then(resp => { this.keys = [...this.keys, key] return resp }) } /** * Deletes given key from the API. * @param {string} key - key to delete. * @returns {Promise} - the response body from the {@link module:api.Api#get API}. */ delete(key) { if (!isString(key)) { return Promise.reject( new Error(`Expected key to be string, but got ${typeof key}`) ) } return this.api .delete([this.endPoint, this.namespace, key].join('/')) .then(resp => { this.keys = this.keys.filter(elem => elem !== key) return resp }) } /** * Updates a key with given value. * @param key - key to update. * @param value - value to update to. * @returns {Promise} - the response body from the {@link module:api.Api#get API}. */ update(key, value) { return this.api.update( [this.endPoint, this.namespace, key].join('/'), value, false, { headers: { 'Content-Type': 'application/json' }, } ) } } export default BaseStoreNamespace