UNPKG

allume

Version:

A cross-platform package bootloader for javascript.

265 lines (247 loc) 10.7 kB
///////////////////////////////////////////////////////////////////////////////////// // // module 'cc.config.0.2.0/' // ///////////////////////////////////////////////////////////////////////////////////// (function(using, require) { define.parameters = {}; define.parameters.wrapped = true; define.parameters.system = "pkx"; define.parameters.id = "cc.config.0.2.0/"; define.parameters.pkx = { "name": "cc.config", "version": "0.2.0", "title": "Configuration Module", "description": "Library for loading and saving configuration data.", "license": "Apache-2.0", "pkx": { "main": "config.js", "dependencies": [ { "package": "cc.io.file-system.0.2", "optional": true }, { "package": "cc.io.local-storage.0.2", "optional": true }, "cc.io.0.2", "cc.host.0.2", "cc.event.0.2" ] } }; define.parameters.dependencies = [ "pkx", "module", "configuration", "requirer" ]; define.parameters.dependencies[0] = define.parameters.pkx; define.parameters.dependencies.push(define.cache.get("cc.io.file-system.0.2/")); define.parameters.dependencies.push(define.cache.get("cc.io.local-storage.0.2/")); define.parameters.dependencies.push(define.cache.get("cc.io.0.2/")); define.parameters.dependencies.push(define.cache.get("cc.host.0.2/")); define.parameters.dependencies.push(define.cache.get("cc.event.0.2/")); using = define.getUsing(define.parameters.id); require = define.getRequire(define.parameters.id, require); ///////////////////////////////////////////////////////////////////////////////////////////// // // cc.config // // Library for loading and saving configuration data. // // License // Apache License Version 2.0 // // Copyright Nick Verlinden (info@createconform.com) // ///////////////////////////////////////////////////////////////////////////////////////////// function Config(pkx, module, configuration) { var self = this; var host = require("cc.host"); var event = require("cc.event"); var io = require("cc.io"); var fs = require("cc.io.file-system"); var ls = require("cc.io.local-storage"); // // constants // var PROTOCOL_CONFIGURATION = "cfg"; var PATH_CONFIG_DEVICE_LINUX = "/etc/opt/"; var PATH_CONFIG_DEVICE_WINDOWS = typeof process != "undefined"? process.env.ProgramData + "\\" : null; var PATH_CONFIG_DEVICE_MACOS = "/Library/Preferences/"; var PATH_CONFIG_USER_LINUX = typeof process != "undefined"? process.env.HOME + "/.config/" : null; var PATH_CONFIG_USER_WINDOWS = typeof process != "undefined"? process.env.APPDATA + "\\" : null; var PATH_CONFIG_USER_MACOS = typeof process != "undefined"? process.env.HOME + "/Library/Preferences/" : null; this.ERROR_FILE_SIZE_EXEEDS_LIMIT = "config-error-file-size-exeeds-limit"; this.MAX_SIZE = ls && ls.MAX_SIZE? ls.MAX_SIZE : "5242880"; // // private // var volume; var ConfigurationVolume = function(mod, root) { this.err = []; this.name = "Configuration (Local)"; this.protocol = PROTOCOL_CONFIGURATION; this.description = "Contains local module configuration data."; this.size = self.MAX_SIZE; this.state = io.VOLUME_STATE_READY; this.type = io.VOLUME_TYPE_FIXED; this.scope = io.VOLUME_SCOPE_LOCAL; this.class = io.VOLUME_CLASS_PERSISTENT; this.readOnly = false; this.localId = "config"; this.then = null; this.getURI = function(path, ignoreActiveProfile) { return mod.uri.parse(root + (!ignoreActiveProfile? getProfilePath() : "") + (path.indexOf("/") == 0? path.substr(1) : path)); } this.open = function(path, opt_access, create_path, ignoreActiveProfile) { return mod.uri.open(root + (!ignoreActiveProfile? getProfilePath() : "") + (path.indexOf("/") == 0? path.substr(1) : path), opt_access, create_path); }; this.exists = function(path, ignoreActiveProfile) { return mod.uri.exists(root + (!ignoreActiveProfile? getProfilePath() : "") + (path.indexOf("/") == 0? path.substr(1) : path)); }; this.query = function(path, ignoreActiveProfile) { return mod.uri.query(root + (!ignoreActiveProfile? getProfilePath() : "") + (path.indexOf("/") == 0? path.substr(1) : path)); }; this.events = new event.Emitter(this); }; ConfigurationVolume.prototype = io.Volume; var profilePath = ""; function getProfilePath() { if (!profilePath && typeof allume !== "undefined" && allume.config) { profilePath = "pkx/" + allume.config.activeProfile + "/"; } return profilePath; } function mountConfigVolume(resolve, reject) { //mount config volume if not already mounted if (!volume) { tryFileSystem().then(resolve, function(e) { if (e) { reject(new Error(e)); } tryLocalStorage().then(resolve, function(e) { reject(new Error(e || "The runtime does not support saving local configuration.")); }) }); } else { resolve(); } } function tryFileSystem() { return new Promise(function(resolve, reject) { // firstly try file system if (fs && fs.uri) { var path; switch(host.platform) { case host.PLATFORM_MACOS: path = PATH_CONFIG_USER_MACOS; break; case host.PLATFORM_WINDOWS: path = "/" + PATH_CONFIG_USER_WINDOWS; break; } if (host.isPlatformLinuxFamily()) { path = PATH_CONFIG_USER_LINUX; } fs.uri.exists(path).then(function() { volume = new ConfigurationVolume(fs, path); resolve(); }, function(e) { reject(e); }); } else { reject(); } }); } function tryLocalStorage() { return new Promise(function(resolve, reject) { // secondly try local storage if (ls && ls.uri) { volume = new ConfigurationVolume(ls, "ls:///"); resolve(); } else { reject(new Error("The runtime does not support saving local configuraration")); } }); } // // public // this.load = function(path, ignoreActiveProfile) { return new Promise(function(resolve, reject) { function success() { // load file from volume (if not exist, return blanco object) volume.open(path, io.ACCESS_READ, true, ignoreActiveProfile).then(function(stream) { stream.readAsJSON().then(function(obj) { stream.close(); resolve(obj); }, function(e) { stream.close(); reject(e); }); }, reject); } if (!volume) { mountConfigVolume(success, reject); } else { success(); } }); }; this.save = function(obj, path, ignoreActiveProfile) { return new Promise(function(resolve, reject) { function success() { // save file to volume (and create folders) volume.open(path, io.ACCESS_OVERWRITE, true, ignoreActiveProfile).then(function(stream) { var data = JSON.stringify(obj); if (data.length > self.MAX_SIZE) { reject(new Error(self.ERROR_FILE_SIZE_EXEEDS_LIMIT, "The configuration file is too big. There is a size limit of " + self.MAX_SIZE + " bytes per file for storing local configuration data.")); } else { stream.write(data).then(function() { stream.close(); resolve(); }, function(e) { stream.close(); reject(e); }); } }, reject); } if (!path) { reject(new Error(self.ERROR_INVALID_PATH, "There is no path specified to save the config.")); } else if (!volume) { mountConfigVolume(success, reject); } else { success(); } }); }; this.getVolume = function() { //return volume; return new Promise(function(resolve, reject) { function success() { resolve(volume); } if (!volume) { mountConfigVolume(success, reject); } else { success(); } }); }; } var singleton; define(function() { if (!singleton) { singleton = new (Function.prototype.bind.apply(Config, arguments)); } return singleton; }); })(typeof using != "undefined"? using : null, typeof require != "undefined"? require : null);