| [81bc7da] | 1 | 'use strict';
|
|---|
| 2 | var fs = require('fs')
|
|---|
| 3 | var ini = require('ini')
|
|---|
| 4 | var path = require('path')
|
|---|
| 5 | var stripJsonComments = require('strip-json-comments')
|
|---|
| 6 |
|
|---|
| 7 | var parse = exports.parse = function (content) {
|
|---|
| 8 |
|
|---|
| 9 | //if it ends in .json or starts with { then it must be json.
|
|---|
| 10 | //must be done this way, because ini accepts everything.
|
|---|
| 11 | //can't just try and parse it and let it throw if it's not ini.
|
|---|
| 12 | //everything is ini. even json with a syntax error.
|
|---|
| 13 |
|
|---|
| 14 | if(/^\s*{/.test(content))
|
|---|
| 15 | return JSON.parse(stripJsonComments(content))
|
|---|
| 16 | return ini.parse(content)
|
|---|
| 17 |
|
|---|
| 18 | }
|
|---|
| 19 |
|
|---|
| 20 | var file = exports.file = function () {
|
|---|
| 21 | var args = [].slice.call(arguments).filter(function (arg) { return arg != null })
|
|---|
| 22 |
|
|---|
| 23 | //path.join breaks if it's a not a string, so just skip this.
|
|---|
| 24 | for(var i in args)
|
|---|
| 25 | if('string' !== typeof args[i])
|
|---|
| 26 | return
|
|---|
| 27 |
|
|---|
| 28 | var file = path.join.apply(null, args)
|
|---|
| 29 | var content
|
|---|
| 30 | try {
|
|---|
| 31 | return fs.readFileSync(file,'utf-8')
|
|---|
| 32 | } catch (err) {
|
|---|
| 33 | return
|
|---|
| 34 | }
|
|---|
| 35 | }
|
|---|
| 36 |
|
|---|
| 37 | var json = exports.json = function () {
|
|---|
| 38 | var content = file.apply(null, arguments)
|
|---|
| 39 | return content ? parse(content) : null
|
|---|
| 40 | }
|
|---|
| 41 |
|
|---|
| 42 | var env = exports.env = function (prefix, env) {
|
|---|
| 43 | env = env || process.env
|
|---|
| 44 | var obj = {}
|
|---|
| 45 | var l = prefix.length
|
|---|
| 46 | for(var k in env) {
|
|---|
| 47 | if(k.toLowerCase().indexOf(prefix.toLowerCase()) === 0) {
|
|---|
| 48 |
|
|---|
| 49 | var keypath = k.substring(l).split('__')
|
|---|
| 50 |
|
|---|
| 51 | // Trim empty strings from keypath array
|
|---|
| 52 | var _emptyStringIndex
|
|---|
| 53 | while ((_emptyStringIndex=keypath.indexOf('')) > -1) {
|
|---|
| 54 | keypath.splice(_emptyStringIndex, 1)
|
|---|
| 55 | }
|
|---|
| 56 |
|
|---|
| 57 | var cursor = obj
|
|---|
| 58 | keypath.forEach(function _buildSubObj(_subkey,i){
|
|---|
| 59 |
|
|---|
| 60 | // (check for _subkey first so we ignore empty strings)
|
|---|
| 61 | // (check for cursor to avoid assignment to primitive objects)
|
|---|
| 62 | if (!_subkey || typeof cursor !== 'object')
|
|---|
| 63 | return
|
|---|
| 64 |
|
|---|
| 65 | // If this is the last key, just stuff the value in there
|
|---|
| 66 | // Assigns actual value from env variable to final key
|
|---|
| 67 | // (unless it's just an empty string- in that case use the last valid key)
|
|---|
| 68 | if (i === keypath.length-1)
|
|---|
| 69 | cursor[_subkey] = env[k]
|
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 | // Build sub-object if nothing already exists at the keypath
|
|---|
| 73 | if (cursor[_subkey] === undefined)
|
|---|
| 74 | cursor[_subkey] = {}
|
|---|
| 75 |
|
|---|
| 76 | // Increment cursor used to track the object at the current depth
|
|---|
| 77 | cursor = cursor[_subkey]
|
|---|
| 78 |
|
|---|
| 79 | })
|
|---|
| 80 |
|
|---|
| 81 | }
|
|---|
| 82 |
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 | return obj
|
|---|
| 86 | }
|
|---|
| 87 |
|
|---|
| 88 | var find = exports.find = function () {
|
|---|
| 89 | var rel = path.join.apply(null, [].slice.call(arguments))
|
|---|
| 90 |
|
|---|
| 91 | function find(start, rel) {
|
|---|
| 92 | var file = path.join(start, rel)
|
|---|
| 93 | try {
|
|---|
| 94 | fs.statSync(file)
|
|---|
| 95 | return file
|
|---|
| 96 | } catch (err) {
|
|---|
| 97 | if(path.dirname(start) !== start) // root
|
|---|
| 98 | return find(path.dirname(start), rel)
|
|---|
| 99 | }
|
|---|
| 100 | }
|
|---|
| 101 | return find(process.cwd(), rel)
|
|---|
| 102 | }
|
|---|
| 103 |
|
|---|
| 104 |
|
|---|