Greasy Fork镜像 支持简体中文。

ConfigManager

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

目前為 2022-08-25 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/449583/1085356/ConfigManager.js

  1. /* eslint-disable no-multi-spaces */
  2.  
  3. // ==UserScript==
  4. // @name ConfigManager
  5. // @namespace ConfigManager
  6. // @version 0.4.1
  7. // @description ConfigManager: Manage(Get, set and update) your config with config path simply with a ruleset!
  8. // @author PY-DNG
  9. // @license GPL-v3
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // @grant GM_listValues
  13. // @grant GM_deleteValue
  14. // ==/UserScript==
  15.  
  16. function ConfigManager(Ruleset, storage={}) {
  17. const CM = this;
  18. const _GM_setValue = storage.GM_setValue || GM_setValue || Err('ConfigManager: could not find GM_setValue');
  19. const _GM_getValue = storage.GM_getValue || GM_getValue || Err('ConfigManager: could not find GM_getValue');
  20. const _GM_listValues = storage.GM_listValues || GM_listValues || Err('ConfigManager: could not find GM_listValues');
  21. const _GM_deleteValue = storage.GM_deleteValue || GM_deleteValue || Err('ConfigManager: could not find GM_deleteValue');
  22. const ConfigBase = new Proxy({}, {
  23. get: function(target, property, reciever) {
  24. return _GM_getValue(property);
  25. },
  26. set: function(target, property, value, reciever) {
  27. return (_GM_setValue(property, value), true);
  28. },
  29. has: function(target, property) {
  30. return _GM_listValues().includes(property);
  31. }
  32. });
  33.  
  34. CM.getConfig = getConfig;
  35. CM.setConfig = setConfig;
  36. CM.updateConfig = updateConfig;
  37. CM.updateAllConfigs = updateAllConfigs;
  38. CM.readPath = readPath;
  39. CM.pathExists = pathExists;
  40. CM.mergePath = mergePath;
  41. CM.getBaseName = getBaseName;
  42. CM.Config = new Proxy({}, {
  43. get: function(target, property, reciever) {
  44. return makeProxy(_GM_getValue(property), [property]);
  45.  
  46. function makeProxy(config, path) {
  47. return isObject(config) ? new Proxy(config, {
  48. get: function(target, property, reciever) {
  49. path.push(property);
  50. return makeProxy(target[property], path);
  51. },
  52. set: function(target, property, value, reciever) {
  53. path.push(property);
  54. return (setConfig(path, value), true);
  55. }
  56. }) : config;
  57. }
  58. },
  59. set: function(target, property, value, reciever) {
  60. return (_GM_setValue(property, value), true);
  61. },
  62. has: function(target, property) {
  63. return _GM_listValues().includes(property);
  64. }
  65. });
  66. Object.freeze(CM);
  67.  
  68. // Get config value from path (e.g. 'Users/username/' or ['Users', 12345])
  69. function getConfig(path) {
  70. // Split path
  71. path = arrPath(path);
  72.  
  73. // Init config if need
  74. if (!_GM_listValues().includes(path[0])) {
  75. ConfigBase[path[0]] = Ruleset.defaultValues[path[0]];
  76. }
  77.  
  78. // Get config by path
  79. const target = path.pop();
  80. let config = readPath(ConfigBase, path);
  81. return config[target];
  82. }
  83.  
  84. // Set config value to path
  85. function setConfig(path, value) {
  86. path = arrPath(path);
  87. const target = path.pop();
  88.  
  89. if (path.length > 0) {
  90. const basekey = path.shift();
  91. const baseobj = ConfigBase[basekey];
  92. let config = readPath(baseobj, path);
  93. if (isObject(config)) {
  94. config[target] = value;
  95. ConfigBase[basekey] = baseobj;
  96. } else {
  97. Err('Attempt to set a property to a non-object value')
  98. }
  99. } else {
  100. ConfigBase[target] = value;
  101. }
  102. }
  103.  
  104. function updateConfig(basename) {
  105. let updated = false;
  106.  
  107. // Get updaters and config
  108. const updaters = Ruleset.updaters.hasOwnProperty(basename) ? Ruleset.updaters[basename] : [];
  109. const verKey = Ruleset['version-key'];
  110. const config = getConfig(basename);
  111.  
  112. // Valid check
  113. if (Ruleset.ignores.includes(basename)) {
  114. return false;
  115. }
  116. if (!updaters.length) {
  117. return save();
  118. }
  119.  
  120. // Update
  121. for (let i = (config[verKey] || 0); i < updaters.length; i++) {
  122. const updater = updaters[i];
  123. config = updater(config);
  124. updated = true;
  125. }
  126.  
  127. // Set version and save
  128. return save();
  129.  
  130. function save() {
  131. config[verKey] = updaters.length;
  132. setConfig(basename, config);
  133. return updated;
  134. }
  135. }
  136.  
  137. function updateAllConfigs() {
  138. const keys = _GM_listValues();
  139. keys.forEach((key) => (updateConfig(key)));
  140. }
  141.  
  142. function readPath(obj, path) {
  143. path = arrPath(path);
  144. while (path.length > 0) {
  145. const key = path.shift();
  146. if (isObject(obj) && hasProp(obj, key)) {
  147. obj = obj[key]
  148. } else {
  149. Err('Attempt to read a property that is not exist (reading "' + key + '" in path "' + path + '")')
  150. }
  151. }
  152. return obj;
  153. }
  154.  
  155. function pathExists(obj, path) {
  156. path = arrPath(path);
  157. while (path.length > 0) {
  158. const key = path.shift();
  159. if (isObject(obj) && hasProp(obj, key)) {
  160. obj = obj[key];
  161. } else {
  162. return false;
  163. }
  164. }
  165. return true;
  166. }
  167.  
  168. function mergePath() {
  169. return Array.from(arguments).join('/');
  170. }
  171.  
  172. function getBaseName(path) {
  173. return arrPath(path)[0];
  174. }
  175.  
  176. function getPathWithoutBase(path) {
  177. const p = arrPath(path);
  178. p.shift();
  179. return p;
  180. }
  181.  
  182. function arrPath(strpath) {
  183. return Array.isArray(strpath) ? [...strpath] : strpath.split('/');
  184. }
  185.  
  186. function isObject(obj) {
  187. return typeof obj === 'object' && obj !== null;
  188. }
  189.  
  190. function hasProp(obj, prop) {
  191. return obj === ConfigBase ? prop in obj : obj.hasOwnProperty(prop);
  192. }
  193.  
  194. // type: [Error, TypeError]
  195. function Err(msg, type=0) {
  196. throw new [Error, TypeError][type](msg);
  197. }
  198. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址