@interaktiv/mibuilder-core
Version:
Core libraries to interact with MiBuilder projects.
292 lines (241 loc) • 7.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ConfigGroup = void 0;
var _types = require("@interaktiv/types");
var _mibuilderError = require("../mibuilder-error");
var _configFile = require("./config-file");
/**
* A config file that stores config values in groups. e.g. to store different
* config values for different commands, without having manually manipulate the
* config.
*
* **Note:** All config methods are overwritten to use the {@link ConfigGroup.setDefaultGroup}.
*
* ```
* class MyPluginConfig extends ConfigGroup<ConfigGroup.Options> {
* public static getFileName(): string {
* return 'myPluginConfigFilename.json';
* }
* }
* const myConfig = await MyPluginConfig.create(ConfigGroup.getOptions('all'));
*
* myConfig.setDefaultGroup('myCommand'); // Can be set in your command's init.
*
* myConfig.set('mykey', 'myvalue'); // Sets 'myKey' for the 'myCommand' group.
*
* myConfig.setInGroup('myKey', 'myvalue', 'all'); // Manually set in another group.
*
* await myConfig.write();
* ```
*/
class ConfigGroup extends _configFile.ConfigFile {
constructor(...args) {
super(...args);
this.defaultGroup = 'default';
}
/**
* Initialize the asynchronous dependencies.
*/
async init() {
await super.init();
this.setDefaultGroup(this.options.defaultGroup);
}
/**
* Get ConfigGroup specific options, such as the default group.
*
* @param {String} defaultGroup The default group to use when creating the
* config.
* @param {String} filename The filename of the config file. Uses the static {@link getFileName} by default.
* @param {Boolean} [isGlobal=true] Make the config global
* @return {Object} options
*/
static getOptions(defaultGroup, filename, isGlobal = true) {
const options = _configFile.ConfigFile.getDefaultOptions(isGlobal, filename);
const configGroupOptions = {
defaultGroup
};
Object.assign(configGroupOptions, options);
return configGroupOptions;
}
/**
* Sets the default group for all {@link BaseConfigStore} methods to use.
*
* **Throws** *{@link MiBuilderError}{ name: 'MissingGroupName' }* The group parameter is null or undefined.
*
* @param {String} group The group
*/
setDefaultGroup(group) {
if ((0, _types.isNil)(group)) {
throw new _mibuilderError.MiBuilderError('null or undefined group', 'MissingGroupName');
}
this.defaultGroup = group;
}
/**
* Set a group of entries in a bulk save. Returns The new properties that
* were saved.
*
* @param {Object} newEntries An object representing the props to set.
* @param {String} group The group the property belongs to.
*/
async updateValues(newEntries, group) {
// Make sure the contents are loaded
await this.read();
Object.entries(newEntries).forEach(([key, val]) => this.setInGroup(key, val, group || this.defaultGroup));
await this.write();
return newEntries;
}
/**
* Set a value on a group. Returns the promise resolved when the value is set.
*
* @param {String} key The key.
* @param {*} value The value.
* @param {String} group The group.
*/
async updateValue(key, value, group) {
// Make sure the content is loaded
await this.read();
this.setInGroup(key, value, group || this.defaultGroup); // Then save it
await this.write();
}
/**
* Gets an array of key value pairs.
*
* @return {[String,*][]} The key value pairs
*/
entries() {
const group = this.getGroup();
if (group) {
return (0, _types.definiteEntriesOf)(group);
}
return [];
}
/**
* Returns a specified element from ConfigGroup. Returns the associated value.
*
* @param {String} key The key
* @return {Object} The value for the group
*/
get(key) {
return this.getInGroup(key);
}
/**
* Returns a boolean if an element with the specified key exists in the
* default group.
*
* @param {string} key The key
* @return {Boolean} Returns true if the key exists in the default group
*/
has(key) {
const group = this.getGroup();
return !!group && super.has(this.defaultGroup) && !!group[key];
}
/**
* Returns an array of the keys from the default group.
*
* @return {String[]} The keys of the default group
*/
keys() {
return Object.keys(this.getGroup(this.defaultGroup) || {});
}
/**
* Returns an array of the values from the default group.
*
* @return {*[]} The values of the default group
*/
values() {
return (0, _types.definiteValuesOf)(this.getGroup(this.defaultGroup) || {});
}
/**
* Add or updates an element with the specified key in the default group.
*
* @param {String} key The key
* @param {*} value The value
* @return {Object} The content of the group
*/
set(key, value) {
return this.setInGroup(key, value, this.defaultGroup);
}
/**
* Removes an element with the specified key from the default group. Returns
* `true` if the item was deleted.
*
* @param {String} key The key
* @return {Boolean} Returns true if the item was deleted
*/
unset(key) {
const groupContents = this.getGroup(this.defaultGroup);
if (groupContents) {
delete groupContents[key];
return true;
}
return false;
}
/**
* Remove all key value pairs from the default group.
*/
clear() {
delete this.getContents()[this.defaultGroup];
}
/**
* Get all config contents for a group.
*
* @param {string} [group='default'] The group.
* @return {String} The group
*/
getGroup(group = this.defaultGroup) {
return (0, _types.getJsonMap)(this.getContents(), group) || undefined;
}
/**
* Returns the value associated to the key and group, or undefined if there
* is none.
*
* @param {String} key The key
* @param {String} group The group. Defaults to the default group
* @return {Object} The contents of the group
*/
getInGroup(key, group) {
const groupContents = this.getGroup(group);
if (groupContents) return groupContents[key];
return undefined;
}
/**
* Convert the config object to a json object.
*
* @return {Object} The contents as a json object
*/
toObject() {
return this.getContents();
}
/**
* Convert an object to a {@link ConfigContents} and set it as the config
* contents.
*
* @param {object} obj The object
*/
setContentsFromObject(obj) {
const contents = new Map((0, _types.definiteEntriesOf)(obj));
Array.from(contents.entries()).filter(([, groupContents]) => !!groupContents).forEach(([groupKey, groupContents]) => {
(0, _types.definiteEntriesOf)(groupContents).forEach(([contentKey, contentValue]) => {
this.setInGroup(contentKey, contentValue, groupKey);
});
});
}
/**
* Sets the value for the key and group in the config object.
*
* @param {String} key The key
* @param {*} value The value
* @param {String} group The group. Uses the default group if not specified
* @return {Object} The content of the group
*/
setInGroup(key, value, group) {
const inGroup = group || this.defaultGroup; // Init group if group not found
if (super.has(inGroup) === false) super.set(inGroup, {});
const content = this.getGroup(inGroup) || {};
this.setMethod(content, key, value);
return content;
}
}
exports.ConfigGroup = ConfigGroup;