UNPKG

@interaktiv/mibuilder-core

Version:

Core libraries to interact with MiBuilder projects.

316 lines (267 loc) 8.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Config = void 0; var _types = require("@interaktiv/types"); var _mibuilderError = require("../mibuilder-error"); var _configGroup = require("./config-group"); const INVALID_PATH_REGEX = /[["?<>|\]]+/; const MIBUILDER_CONFIG_FILE_NAME = 'mibuilder-config.json'; const CONFIG_GROUP = { APP: 'app', TEMPLATE: 'template', CLI: 'cli', API: 'api', ANDROID: 'android', MATCH: 'match', FLINT: 'flint' }; const configNames = (0, _types.definiteValuesOf)(CONFIG_GROUP); const isValidGroup = group => configNames.includes(group); /** * Tests whether a path is in the correct format; the value doesn't include the * characters "[", "]", "?", "<", ">", "?", "|" * * @param {String} value The path as a string. * @return {Boolean} Returns true if path is valid */ const validatePathDoesNotContainInvalidChars = value => INVALID_PATH_REGEX.test(value) === false; /** * The files where mibuilder config values are stored for projects and the * global space. * * The configs are saved in different groups {@link CONFIG_GROUP} * * *Note:* It is not recommended to instantiate this object directly when * resolving config values. Instead use {@link ConfigAggregator} * * TODO: Update example * ```javascript * ``` */ class Config extends _configGroup.ConfigGroup { /** * Returns the default file name for a config file. * * **See** {@link MIBUILDER_CONFIG_FILE_NAME} * * @return {String} The file name of the config file */ static getFileName() { return MIBUILDER_CONFIG_FILE_NAME; } /** * Gets default options. * * @param {Boolean} [isGlobal=true] Make the config global. * @param {String} filename Override the default file. {@link Config.getFileName} * @return {Object} The default options */ // eslint-disable-next-line default-param-last static getDefaultOptions(isGlobal = true, filename) { return _configGroup.ConfigGroup.getOptions(CONFIG_GROUP.CLI, filename || Config.getFileName(), isGlobal); } /** * Constructor * * **Do not directly construct instances of this class -- use {@link Aliases.create} instead.** * * @param {Object} [options] The options for the class instance */ constructor(options) { super(options || Config.getDefaultOptions(true)); } /** * Initializer for supported config types. */ async init() { if (!Config.allowedGroups) Config.allowedGroups = configNames; if (!Config.allowedProperties) { Config.allowedProperties = [{ group: 'app', key: 'workspace', input: { validator: validatePathDoesNotContainInvalidChars, failedMessage: 'Specify a valid file path' } }, { group: 'template', key: 'sshPrivateKeyPath', input: { validator: validatePathDoesNotContainInvalidChars, failedMessage: 'Specify a valid file path' } }, { group: 'template', key: 'sshPublicKeyPath', input: { validator: validatePathDoesNotContainInvalidChars, failedMessage: 'Specify a valid file path' } }, // TODO: Add input.validator for web url or file path { group: 'template', key: 'remoteOrigin' }, // TODO: Add input.validator for web url { group: 'api', key: 'getContentEndpoint' }, { group: 'android', key: 'googlePlayJsonKeyPath', input: { validator: validatePathDoesNotContainInvalidChars, failedMessage: 'Specify a valid file path' } }, // TODO: Add input.validator for web url { group: 'match', key: 'gitUrl' }, // TODO: Add input.validator for web url { group: 'flint', key: 'gitUrl' }]; } await super.init(); } /** * Returns an object representing the supported allowed groups. * * @return {Object} the allowed groups */ static getAllowedGroups() { if (!Config.allowedGroups) { throw new _mibuilderError.MiBuilderError('Config meta information has not been initialized.', undefined, ['Use Config.create()']); } return Config.allowedGroups; } static getAllowedProperties() { if (!Config.allowedProperties) { throw new _mibuilderError.MiBuilderError('Config meta information has not been initialized.', undefined, ['Use Config.create()']); } return Config.allowedProperties; } static getKeyAndGroupFromPath(path) { if ((0, _types.isString)(path) === false) return { group: CONFIG_GROUP.CLI, key: null }; const parts = path.split('.'); if (parts.length === 1) return { group: CONFIG_GROUP.CLI, key: parts[0] }; return { group: parts[0], key: parts[1] }; } /** * Don't use kit's set to prevent nested object save. * Used internally by {@link ConfigStore} * * @param {Object} contents The contents of the group * @param {String} key The key in the contents * @param {*} value The value for the key */ setMethod(contents, key, value) { contents[key] = value; } /** * Get an alias from a key and group. Shorthand for * `Alias.create({}).get(path)`. Returns the promise resolved when the * alias is created. * * @param {Boolean} isGlobal True for a global config. False for a local config. * @param {String} path The path to the config. */ static async fetch(isGlobal, path) { const { group, key } = Config.getKeyAndGroupFromPath(path); if (isValidGroup(group) === false) { throw new _mibuilderError.MiBuilderError('You have specified an invalid config group in which to save your values. Please verify that you are specifying a valid config group', 'InvalidConfigGroup'); } const config = await Config.create(Config.getDefaultOptions(isGlobal)); return config.getInGroup(key, group); } /** * The value of a supported config property. * * @param {Boolean} isGlobal True for a global config. False for a local config. * @param {String} path The name of the property to set. * @param {Boolean} value The property value. * @return {*} The value */ static async update(isGlobal, path, value) { const { group, key } = Config.getKeyAndGroupFromPath(path); if (isValidGroup(group) === false) { throw new _mibuilderError.MiBuilderError('You have specified an invalid config group in which to save your values. Please verify that you are specifying a valid config group', 'InvalidConfigGroup'); } const config = await Config.create(Config.getDefaultOptions(isGlobal)); config.setInGroup(key, value, group); return config.write(); } /** * Clear all the configured properties both local and global. */ static async clear() { const globalConfig = await Config.create(Config.getDefaultOptions(true)); globalConfig.clear(); await globalConfig.write(); const localConfig = await Config.create(Config.getDefaultOptions(false)); localConfig.clear(); await localConfig.write(); } /** * Writes Config properties. * * @param {Object} newContents The new Config value to persist * @return {Object} The current config */ async write(newContents) { if (newContents != null) { this.setContentsFromObject(newContents); } await super.write(); return this.getContents(); } /** * Sets a value for a property. * * **Throws** *{@link MiBuilderError}{ name: 'InvalidConfigValue' }* If the input validator fails. * * @param {String} path The property path to set. * @param {*} value The value of the property. * @return {Object} The config content */ set(path, value) { const { group, key } = Config.getKeyAndGroupFromPath(path); if (isValidGroup(group) === false) { throw new _mibuilderError.MiBuilderError('You have specified an invalid config group in which to save your values. Please verify that you are specifying a valid config group', 'InvalidConfigGroup'); } const property = Config.allowedProperties.find(prop => prop.group === group && prop.key === key); if (property == null) { throw new _mibuilderError.MiBuilderError(`Unknown config name "${key}"`, 'UnknownConfigKey'); } if (property.input && property.input.validator(value) === false) { throw new _mibuilderError.MiBuilderError(`Invalid config value. ${property.input.failedMessage}`, 'InvalidConfigValue'); } this.setInGroup(property.key, value, property.group); return this.getContents(); } } /** * Different groups of configs. */ exports.Config = Config; Config.Group = CONFIG_GROUP;