"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/config-chain/index.js" (8 Mar 2017, 7208 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 var ProtoList = require('proto-list')
    2   , path = require('path')
    3   , fs = require('fs')
    4   , ini = require('ini')
    5   , EE = require('events').EventEmitter
    6   , url = require('url')
    7   , http = require('http')
    8 
    9 var exports = module.exports = function () {
   10   var args = [].slice.call(arguments)
   11     , conf = new ConfigChain()
   12 
   13   while(args.length) {
   14     var a = args.shift()
   15     if(a) conf.push
   16           ( 'string' === typeof a
   17             ? json(a)
   18             : a )
   19   }
   20 
   21   return conf
   22 }
   23 
   24 //recursively find a file...
   25 
   26 var find = exports.find = function () {
   27   var rel = path.join.apply(null, [].slice.call(arguments))
   28 
   29   function find(start, rel) {
   30     var file = path.join(start, rel)
   31     try {
   32       fs.statSync(file)
   33       return file
   34     } catch (err) {
   35       if(path.dirname(start) !== start) // root
   36         return find(path.dirname(start), rel)
   37     }
   38   }
   39   return find(__dirname, rel)
   40 }
   41 
   42 var parse = exports.parse = function (content, file, type) {
   43   content = '' + content
   44   // if we don't know what it is, try json and fall back to ini
   45   // if we know what it is, then it must be that.
   46   if (!type) {
   47     try { return JSON.parse(content) }
   48     catch (er) { return ini.parse(content) }
   49   } else if (type === 'json') {
   50     if (this.emit) {
   51       try { return JSON.parse(content) }
   52       catch (er) { this.emit('error', er) }
   53     } else {
   54       return JSON.parse(content)
   55     }
   56   } else {
   57     return ini.parse(content)
   58   }
   59 }
   60 
   61 var json = exports.json = function () {
   62   var args = [].slice.call(arguments).filter(function (arg) { return arg != null })
   63   var file = path.join.apply(null, args)
   64   var content
   65   try {
   66     content = fs.readFileSync(file,'utf-8')
   67   } catch (err) {
   68     return
   69   }
   70   return parse(content, file, 'json')
   71 }
   72 
   73 var env = exports.env = function (prefix, env) {
   74   env = env || process.env
   75   var obj = {}
   76   var l = prefix.length
   77   for(var k in env) {
   78     if(k.indexOf(prefix) === 0)
   79       obj[k.substring(l)] = env[k]
   80   }
   81 
   82   return obj
   83 }
   84 
   85 exports.ConfigChain = ConfigChain
   86 function ConfigChain () {
   87   EE.apply(this)
   88   ProtoList.apply(this, arguments)
   89   this._awaiting = 0
   90   this._saving = 0
   91   this.sources = {}
   92 }
   93 
   94 // multi-inheritance-ish
   95 var extras = {
   96   constructor: { value: ConfigChain }
   97 }
   98 Object.keys(EE.prototype).forEach(function (k) {
   99   extras[k] = Object.getOwnPropertyDescriptor(EE.prototype, k)
  100 })
  101 ConfigChain.prototype = Object.create(ProtoList.prototype, extras)
  102 
  103 ConfigChain.prototype.del = function (key, where) {
  104   // if not specified where, then delete from the whole chain, scorched
  105   // earth style
  106   if (where) {
  107     var target = this.sources[where]
  108     target = target && target.data
  109     if (!target) {
  110       return this.emit('error', new Error('not found '+where))
  111     }
  112     delete target[key]
  113   } else {
  114     for (var i = 0, l = this.list.length; i < l; i ++) {
  115       delete this.list[i][key]
  116     }
  117   }
  118   return this
  119 }
  120 
  121 ConfigChain.prototype.set = function (key, value, where) {
  122   var target
  123 
  124   if (where) {
  125     target = this.sources[where]
  126     target = target && target.data
  127     if (!target) {
  128       return this.emit('error', new Error('not found '+where))
  129     }
  130   } else {
  131     target = this.list[0]
  132     if (!target) {
  133       return this.emit('error', new Error('cannot set, no confs!'))
  134     }
  135   }
  136   target[key] = value
  137   return this
  138 }
  139 
  140 ConfigChain.prototype.get = function (key, where) {
  141   if (where) {
  142     where = this.sources[where]
  143     if (where) where = where.data
  144     if (where && Object.hasOwnProperty.call(where, key)) return where[key]
  145     return undefined
  146   }
  147   return this.list[0][key]
  148 }
  149 
  150 ConfigChain.prototype.save = function (where, type, cb) {
  151   if (typeof type === 'function') cb = type, type = null
  152   var target = this.sources[where]
  153   if (!target || !(target.path || target.source) || !target.data) {
  154     // TODO: maybe save() to a url target could be a PUT or something?
  155     // would be easy to swap out with a reddis type thing, too
  156     return this.emit('error', new Error('bad save target: '+where))
  157   }
  158 
  159   if (target.source) {
  160     var pref = target.prefix || ''
  161     Object.keys(target.data).forEach(function (k) {
  162       target.source[pref + k] = target.data[k]
  163     })
  164     return this
  165   }
  166 
  167   var type = type || target.type
  168   var data = target.data
  169   if (target.type === 'json') {
  170     data = JSON.stringify(data)
  171   } else {
  172     data = ini.stringify(data)
  173   }
  174 
  175   this._saving ++
  176   fs.writeFile(target.path, data, 'utf8', function (er) {
  177     this._saving --
  178     if (er) {
  179       if (cb) return cb(er)
  180       else return this.emit('error', er)
  181     }
  182     if (this._saving === 0) {
  183       if (cb) cb()
  184       this.emit('save')
  185     }
  186   }.bind(this))
  187   return this
  188 }
  189 
  190 ConfigChain.prototype.addFile = function (file, type, name) {
  191   name = name || file
  192   var marker = {__source__:name}
  193   this.sources[name] = { path: file, type: type }
  194   this.push(marker)
  195   this._await()
  196   fs.readFile(file, 'utf8', function (er, data) {
  197     if (er) this.emit('error', er)
  198     this.addString(data, file, type, marker)
  199   }.bind(this))
  200   return this
  201 }
  202 
  203 ConfigChain.prototype.addEnv = function (prefix, env, name) {
  204   name = name || 'env'
  205   var data = exports.env(prefix, env)
  206   this.sources[name] = { data: data, source: env, prefix: prefix }
  207   return this.add(data, name)
  208 }
  209 
  210 ConfigChain.prototype.addUrl = function (req, type, name) {
  211   this._await()
  212   var href = url.format(req)
  213   name = name || href
  214   var marker = {__source__:name}
  215   this.sources[name] = { href: href, type: type }
  216   this.push(marker)
  217   http.request(req, function (res) {
  218     var c = []
  219     var ct = res.headers['content-type']
  220     if (!type) {
  221       type = ct.indexOf('json') !== -1 ? 'json'
  222            : ct.indexOf('ini') !== -1 ? 'ini'
  223            : href.match(/\.json$/) ? 'json'
  224            : href.match(/\.ini$/) ? 'ini'
  225            : null
  226       marker.type = type
  227     }
  228 
  229     res.on('data', c.push.bind(c))
  230     .on('end', function () {
  231       this.addString(Buffer.concat(c), href, type, marker)
  232     }.bind(this))
  233     .on('error', this.emit.bind(this, 'error'))
  234 
  235   }.bind(this))
  236   .on('error', this.emit.bind(this, 'error'))
  237   .end()
  238 
  239   return this
  240 }
  241 
  242 ConfigChain.prototype.addString = function (data, file, type, marker) {
  243   data = this.parse(data, file, type)
  244   this.add(data, marker)
  245   return this
  246 }
  247 
  248 ConfigChain.prototype.add = function (data, marker) {
  249   if (marker && typeof marker === 'object') {
  250     var i = this.list.indexOf(marker)
  251     if (i === -1) {
  252       return this.emit('error', new Error('bad marker'))
  253     }
  254     this.splice(i, 1, data)
  255     marker = marker.__source__
  256     this.sources[marker] = this.sources[marker] || {}
  257     this.sources[marker].data = data
  258     // we were waiting for this.  maybe emit 'load'
  259     this._resolve()
  260   } else {
  261     if (typeof marker === 'string') {
  262       this.sources[marker] = this.sources[marker] || {}
  263       this.sources[marker].data = data
  264     }
  265     // trigger the load event if nothing was already going to do so.
  266     this._await()
  267     this.push(data)
  268     process.nextTick(this._resolve.bind(this))
  269   }
  270   return this
  271 }
  272 
  273 ConfigChain.prototype.parse = exports.parse
  274 
  275 ConfigChain.prototype._await = function () {
  276   this._awaiting++
  277 }
  278 
  279 ConfigChain.prototype._resolve = function () {
  280   this._awaiting--
  281   if (this._awaiting === 0) this.emit('load', this)
  282 }