ConfigManager

ConfigManager: Manage(Get, set and update) your config with config path simply with a ruleset!

Tính đến 15-08-2022. Xem phiên bản mới nhất.

Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta // @require https://update.greasyforks.org/scripts/449583/1081638/ConfigManager.js

/* eslint-disable no-multi-spaces */

// ==UserScript==
// @name               ConfigManager
// @namespace          ConfigManager
// @version            0.1
// @description        ConfigManager: Manage(Get, set and update) your config with config path simply with a ruleset!
// @author             PY-DNG
// @license            GPL-v3
// @grant              GM_setValue
// @grant              GM_getValue
// @grant              GM_listValues
// @grant              GM_deleteValue
// ==/UserScript==

function ConfigManager(Ruleset) {
	const CM = this;
	const ConfigBase = new Proxy({}, {
		get: function(target, property, reciever) {
			return GM_getValue(property);
		},
		set: function(target, property, value, reciever) {
			return (GM_setValue(property, value), true);
		},
		has: function(target, property) {
			return GM_listValues().includes(property);
		}
	});

	CM.getConfig = getConfig;
	CM.setConfig = setConfig;
	CM.updateConfig = updateConfig;
	CM.updateAllConfigs = updateAllConfigs;
	CM.readPath = readPath;
	CM.pathExists = pathExists;
	CM.mergePath = mergePath;
	CM.getBaseName = getBaseName;
	Object.freeze(CM);

	// Get config value from path (e.g. 'Users/username/' or ['Users', 12345])
	function getConfig(path) {
		// Split path
		path = Array.isArray(path) ? path : path.split('/');

		// Init config if need
		if (!GM_listValues().includes(path[0])) {
			ConfigBase[path[0]] = Ruleset.defaultValues[path[0]];
		}

		// Get config by path
		const target = path.pop();
		let config = readPath(ConfigBase, path);
		return config[target];
	}

	// Set config value to path
	function setConfig(path, value) {
		path = Array.isArray(path) ? path : path = path.split('/');
		const target = path.pop();

		if (path.length > 0) {
			const basekey = path.shift();
			const baseobj = ConfigBase[basekey];
			let config = readPath(baseobj, path);
			if (isObject(config)) {
				config[target] = value;
				ConfigBase[basekey] = baseobj;
			} else {
				Err('Attempt to set a property to a non-object value')
			}
		} else {
			ConfigBase[target] = value;
		}
	}

	function updateConfig(path) {
		const basename = getBaseName(path);
		if (!Ruleset.updaters.hasOwnProperty(basename)) {return;}
		const updaters = Ruleset.updaters[basename];
		const verKey = Ruleset['version-key'];
		const config = getConfig(path);
		for (let i = config[verKey]; i < updaters.length; i++) {
			const updater = updaters[i];
			config = updater(config)
		}
		config[verKey] = updaters.length;
		setConfig(path, config);
	}

	function updateAllConfigs() {
		const keys = GM_listValues();
		keys.forEach((key) => (updateConfig(key)));
	}

	function readPath(obj, path) {
		path = [...path];
		while (path.length > 0) {
			const key = path.shift();
			if (isObject(obj) && hasProp(obj, key)) {
				obj = obj[key]
			} else {
				Err('Attempt to read a property that is not exist (reading "' + key + '" in path "' + path + '")')
			}
		}
		return obj;
	}

	function pathExists(obj, path) {
		path = [...path];
		while (path.length > 0) {
			const key = path.shift();
			if (isObject(obj) && hasProp(obj, key)) {
				obj = obj[key]
			} else {
				return false
			}
		}
		return true;
	}

	function mergePath() {
		return Array.from(arguments).join('/')
	}

	function getBaseName(path) {
		return path.split('/')[0];
	}

	function getPathWithoutBase(path) {
		const p = path.split('/');
		p.shift();
		return p;
	}

	function isObject(obj) {
		return typeof obj === 'object' && obj !== null;
	}

	function hasProp(obj, prop) {
		return obj === ConfigBase ? prop in obj : obj.hasOwnProperty(prop);
	}

	// type: [Error, TypeError]
	function Err(msg, type=0) {
		throw new [Error, TypeError][type](msg);
	}
}
长期地址
遇到问题?请前往 GitHub 提 Issues。