config 1.20.3 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/History.md CHANGED
@@ -1,3 +1,30 @@
1
+ 1.24.0 / 2016-11-02
2
+ ===================
3
+
4
+ * Prevent accidental publish to private repository
5
+
6
+ 1.23.0 / 2016-11-02
7
+ ===================
8
+
9
+ * Re-publishing because npmjs didn't see 1.22
10
+
11
+ 1.22.0 / 2016-10-25
12
+ ===================
13
+
14
+ * original/previous value for deferredConfig @simon-scherzinger
15
+ * util.loadFileConfigs: support optional source dir @wmertens
16
+ * Adding raw wrapper to prevent object modification in config @patrickpilch
17
+
18
+ 1.21.0 / 2016-06-01
19
+ ===================
20
+
21
+ * Added XML configuration @tusharmath
22
+
23
+ 1.20.4 / 2016-05-23
24
+ ===================
25
+
26
+ * Fixed a regression with extending prototype methods @tahoemph
27
+
1
28
  1.20.3 / 2016-05-18
2
29
  ===================
3
30
 
package/README.md CHANGED
@@ -123,7 +123,7 @@ Articles
123
123
 
124
124
  Contributors
125
125
  ------------
126
- <table id="contributors"><tr><td><img src=https://avatars.githubusercontent.com/u/373538?v=3><a href="https://github.com/lorenwest">lorenwest</a></td><td><img src=https://avatars.githubusercontent.com/u/25829?v=3><a href="https://github.com/markstos">markstos</a></td><td><img src=https://avatars.githubusercontent.com/u/447151?v=3><a href="https://github.com/elliotttf">elliotttf</a></td><td><img src=https://avatars.githubusercontent.com/u/66902?v=3><a href="https://github.com/leachiM2k">leachiM2k</a></td><td><img src=https://avatars.githubusercontent.com/u/791137?v=3><a href="https://github.com/josx">josx</a></td><td><img src=https://avatars.githubusercontent.com/u/133277?v=3><a href="https://github.com/enyo">enyo</a></td></tr><tr><td><img src=https://avatars.githubusercontent.com/u/1077378?v=3><a href="https://github.com/arthanzel">arthanzel</a></td><td><img src=https://avatars.githubusercontent.com/u/355800?v=3><a href="https://github.com/diversario">diversario</a></td><td><img src=https://avatars.githubusercontent.com/u/1656140?v=3><a href="https://github.com/eheikes">eheikes</a></td><td><img src=https://avatars.githubusercontent.com/u/138707?v=3><a href="https://github.com/th507">th507</a></td><td><img src=https://avatars.githubusercontent.com/u/842998?v=3><a href="https://github.com/nsabovic">nsabovic</a></td><td><img src=https://avatars.githubusercontent.com/u/506460?v=3><a href="https://github.com/Osterjour">Osterjour</a></td></tr><tr><td><img src=https://avatars.githubusercontent.com/u/175627?v=3><a href="https://github.com/axelhzf">axelhzf</a></td><td><img src=https://avatars.githubusercontent.com/u/7782055?v=3><a href="https://github.com/benkroeger">benkroeger</a></td><td><img src=https://avatars.githubusercontent.com/u/1246875?v=3><a href="https://github.com/jaylynch">jaylynch</a></td><td><img src=https://avatars.githubusercontent.com/u/145742?v=3><a href="https://github.com/jberrisch">jberrisch</a></td><td><img src=https://avatars.githubusercontent.com/u/1918551?v=3><a href="https://github.com/nitzan-shaked">nitzan-shaked</a></td><td><img src=https://avatars.githubusercontent.com/u/3058150?v=3><a href="https://github.com/Alaneor">Alaneor</a></td></tr><tr><td><img src=https://avatars.githubusercontent.com/u/498929?v=3><a href="https://github.com/roncli">roncli</a></td><td><img src=https://avatars.githubusercontent.com/u/1355559?v=3><a href="https://github.com/superoven">superoven</a></td><td><img src=https://avatars.githubusercontent.com/u/4425455?v=3><a href="https://github.com/ncuillery">ncuillery</a></td><td><img src=https://avatars.githubusercontent.com/u/125062?v=3><a href="https://github.com/keis">keis</a></td><td><img src=https://avatars.githubusercontent.com/u/16861?v=3><a href="https://github.com/abh">abh</a></td><td><img src=https://avatars.githubusercontent.com/u/57770?v=3><a href="https://github.com/bertrandom">bertrandom</a></td></tr><tr><td><img src=https://avatars.githubusercontent.com/u/959858?v=3><a href="https://github.com/laktak">laktak</a></td><td><img src=https://avatars.githubusercontent.com/u/157303?v=3><a href="https://github.com/cmcculloh">cmcculloh</a></td><td><img src=https://avatars.githubusercontent.com/u/270632?v=3><a href="https://github.com/thetalecrafter">thetalecrafter</a></td><td><img src=https://avatars.githubusercontent.com/u/28898?v=3><a href="https://github.com/DMajrekar">DMajrekar</a></td><td><img src=https://avatars.githubusercontent.com/u/5358976?v=3><a href="https://github.com/dsimidzija">dsimidzija</a></td><td><img src=https://avatars.githubusercontent.com/u/535667?v=3><a href="https://github.com/jasonhansel">jasonhansel</a></td></tr></table>
126
+ <table id="contributors"><tr><td><img src=https://avatars.githubusercontent.com/u/373538?v=3><a href="https://github.com/lorenwest">lorenwest</a></td><td><img src=https://avatars.githubusercontent.com/u/25829?v=3><a href="https://github.com/markstos">markstos</a></td><td><img src=https://avatars.githubusercontent.com/u/447151?v=3><a href="https://github.com/elliotttf">elliotttf</a></td><td><img src=https://avatars.githubusercontent.com/u/66902?v=3><a href="https://github.com/leachiM2k">leachiM2k</a></td><td><img src=https://avatars.githubusercontent.com/u/791137?v=3><a href="https://github.com/josx">josx</a></td><td><img src=https://avatars.githubusercontent.com/u/133277?v=3><a href="https://github.com/enyo">enyo</a></td></tr><tr><td><img src=https://avatars.githubusercontent.com/u/2675698?v=3><a href="https://github.com/rundef">rundef</a></td><td><img src=https://avatars.githubusercontent.com/u/1077378?v=3><a href="https://github.com/arthanzel">arthanzel</a></td><td><img src=https://avatars.githubusercontent.com/u/1656140?v=3><a href="https://github.com/eheikes">eheikes</a></td><td><img src=https://avatars.githubusercontent.com/u/355800?v=3><a href="https://github.com/diversario">diversario</a></td><td><img src=https://avatars.githubusercontent.com/u/138707?v=3><a href="https://github.com/th507">th507</a></td><td><img src=https://avatars.githubusercontent.com/u/842998?v=3><a href="https://github.com/nsabovic">nsabovic</a></td></tr><tr><td><img src=https://avatars.githubusercontent.com/u/506460?v=3><a href="https://github.com/Osterjour">Osterjour</a></td><td><img src=https://avatars.githubusercontent.com/u/175627?v=3><a href="https://github.com/axelhzf">axelhzf</a></td><td><img src=https://avatars.githubusercontent.com/u/7782055?v=3><a href="https://github.com/benkroeger">benkroeger</a></td><td><img src=https://avatars.githubusercontent.com/u/1246875?v=3><a href="https://github.com/jaylynch">jaylynch</a></td><td><img src=https://avatars.githubusercontent.com/u/145742?v=3><a href="https://github.com/jberrisch">jberrisch</a></td><td><img src=https://avatars.githubusercontent.com/u/1918551?v=3><a href="https://github.com/nitzan-shaked">nitzan-shaked</a></td></tr><tr><td><img src=https://avatars.githubusercontent.com/u/3058150?v=3><a href="https://github.com/Alaneor">Alaneor</a></td><td><img src=https://avatars.githubusercontent.com/u/498929?v=3><a href="https://github.com/roncli">roncli</a></td><td><img src=https://avatars.githubusercontent.com/u/1355559?v=3><a href="https://github.com/superoven">superoven</a></td><td><img src=https://avatars.githubusercontent.com/u/4425455?v=3><a href="https://github.com/ncuillery">ncuillery</a></td><td><img src=https://avatars.githubusercontent.com/u/125062?v=3><a href="https://github.com/keis">keis</a></td><td><img src=https://avatars.githubusercontent.com/u/16861?v=3><a href="https://github.com/abh">abh</a></td></tr><tr><td><img src=https://avatars.githubusercontent.com/u/57770?v=3><a href="https://github.com/bertrandom">bertrandom</a></td><td><img src=https://avatars.githubusercontent.com/u/959858?v=3><a href="https://github.com/laktak">laktak</a></td><td><img src=https://avatars.githubusercontent.com/u/157303?v=3><a href="https://github.com/cmcculloh">cmcculloh</a></td><td><img src=https://avatars.githubusercontent.com/u/270632?v=3><a href="https://github.com/thetalecrafter">thetalecrafter</a></td><td><img src=https://avatars.githubusercontent.com/u/28898?v=3><a href="https://github.com/DMajrekar">DMajrekar</a></td><td><img src=https://avatars.githubusercontent.com/u/5358976?v=3><a href="https://github.com/dsimidzija">dsimidzija</a></td></tr></table>
127
127
 
128
128
  License
129
129
  -------
package/defer.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // Create a deferredConfig prototype so that we can check for it when reviewing the configs later.
2
2
  function DeferredConfig () {
3
3
  }
4
- DeferredConfig.prototype.resolve = function (config) {};
4
+ DeferredConfig.prototype.resolve = function (config, original) {};
5
5
 
6
6
  // Accept a function that we'll use to resolve this value later and return a 'deferred' configuration value to resolve it later.
7
7
  function deferConfig (func) {
package/lib/config.js CHANGED
@@ -13,8 +13,10 @@ var Yaml = null, // External libraries are lazy-loaded
13
13
  JSON5 = null,
14
14
  TOML = null,
15
15
  HJSON = null,
16
+ XML = null,
16
17
  deferConfig = require('../defer').deferConfig,
17
18
  DeferredConfig = require('../defer').DeferredConfig,
19
+ RawConfig = require('../raw').RawConfig,
18
20
  Utils = require('util'),
19
21
  Path = require('path'),
20
22
  FileSystem = require('fs');
@@ -186,6 +188,10 @@ Config.prototype.get = function(property) {
186
188
  checkMutability = false;
187
189
  }
188
190
 
191
+ if (value instanceof RawConfig) {
192
+ value = value.resolve();
193
+ }
194
+
189
195
  // Return the value
190
196
  return value;
191
197
  };
@@ -531,16 +537,18 @@ util.makeImmutable = function(object, property, value) {
531
537
  for (var i = 0; i < properties.length; i++) {
532
538
  var propertyName = properties[i],
533
539
  value = object[propertyName];
540
+
541
+ if (!(value instanceof RawConfig)) {
542
+ Object.defineProperty(object, propertyName, {
543
+ value: value,
544
+ writable : false,
545
+ configurable: false
546
+ });
534
547
 
535
- Object.defineProperty(object, propertyName, {
536
- value: value,
537
- writable : false,
538
- configurable: false
539
- });
540
-
541
- // Call recursively if an object.
542
- if (util.isObject(value)) {
543
- util.makeImmutable(value);
548
+ // Call recursively if an object.
549
+ if (util.isObject(value)) {
550
+ util.makeImmutable(value);
551
+ }
544
552
  }
545
553
  }
546
554
 
@@ -624,7 +632,7 @@ util.getConfigSources = function() {
624
632
  * @method loadFileConfigs
625
633
  * @return config {Object} The configuration object
626
634
  */
627
- util.loadFileConfigs = function() {
635
+ util.loadFileConfigs = function(configDir) {
628
636
 
629
637
  // Initialize
630
638
  var t = this,
@@ -632,7 +640,7 @@ util.loadFileConfigs = function() {
632
640
 
633
641
  // Initialize parameters from command line, environment, or default
634
642
  NODE_ENV = util.initParam('NODE_ENV', 'development');
635
- CONFIG_DIR = util.initParam('NODE_CONFIG_DIR', Path.join( process.cwd(), 'config') );
643
+ CONFIG_DIR = configDir || util.initParam('NODE_CONFIG_DIR', Path.join( process.cwd(), 'config') );
636
644
  if (CONFIG_DIR.indexOf('.') === 0) {
637
645
  CONFIG_DIR = Path.join(process.cwd() , CONFIG_DIR);
638
646
  }
@@ -677,7 +685,7 @@ util.loadFileConfigs = function() {
677
685
 
678
686
  baseNames.push('local', 'local-' + NODE_ENV);
679
687
 
680
- var extNames = ['js', 'json', 'json5', 'hjson', 'toml', 'coffee', 'iced', 'yaml', 'yml', 'cson', 'properties'];
688
+ var extNames = ['js', 'json', 'json5', 'hjson', 'toml', 'coffee', 'iced', 'yaml', 'yml', 'cson', 'properties', 'xml'];
681
689
  baseNames.forEach(function(baseName) {
682
690
  extNames.forEach(function(extName) {
683
691
 
@@ -700,42 +708,45 @@ util.loadFileConfigs = function() {
700
708
  });
701
709
 
702
710
  // Override configurations from the $NODE_CONFIG environment variable
703
- var envConfig = {};
704
- if (process.env.NODE_CONFIG) {
705
- try {
706
- envConfig = JSON.parse(process.env.NODE_CONFIG);
707
- } catch(e) {
708
- console.error('The $NODE_CONFIG environment variable is malformed JSON');
711
+ // NODE_CONFIG only applies to the base config
712
+ if (!configDir) {
713
+ var envConfig = {};
714
+ if (process.env.NODE_CONFIG) {
715
+ try {
716
+ envConfig = JSON.parse(process.env.NODE_CONFIG);
717
+ } catch(e) {
718
+ console.error('The $NODE_CONFIG environment variable is malformed JSON');
719
+ }
720
+ util.extendDeep(config, envConfig);
721
+ configSources.push({
722
+ name: "$NODE_CONFIG",
723
+ parsed: envConfig,
724
+ });
709
725
  }
710
- util.extendDeep(config, envConfig);
711
- configSources.push({
712
- name: "$NODE_CONFIG",
713
- parsed: envConfig,
714
- });
715
- }
716
726
 
717
- // Override configurations from the --NODE_CONFIG command line
718
- var cmdLineConfig = util.getCmdLineArg('NODE_CONFIG');
719
- if (cmdLineConfig) {
720
- try {
721
- cmdLineConfig = JSON.parse(cmdLineConfig);
722
- } catch(e) {
723
- console.error('The --NODE_CONFIG={json} command line argument is malformed JSON');
727
+ // Override configurations from the --NODE_CONFIG command line
728
+ var cmdLineConfig = util.getCmdLineArg('NODE_CONFIG');
729
+ if (cmdLineConfig) {
730
+ try {
731
+ cmdLineConfig = JSON.parse(cmdLineConfig);
732
+ } catch(e) {
733
+ console.error('The --NODE_CONFIG={json} command line argument is malformed JSON');
734
+ }
735
+ util.extendDeep(config, cmdLineConfig);
736
+ configSources.push({
737
+ name: "--NODE_CONFIG argument",
738
+ parsed: cmdLineConfig,
739
+ });
724
740
  }
725
- util.extendDeep(config, cmdLineConfig);
726
- configSources.push({
727
- name: "--NODE_CONFIG argument",
728
- parsed: cmdLineConfig,
729
- });
741
+
742
+ // Place the mixed NODE_CONFIG into the environment
743
+ env['NODE_CONFIG'] = JSON.stringify(util.extendDeep(envConfig, cmdLineConfig, {}));
730
744
  }
731
745
 
732
746
  // Override with environment variables if there is a custom-environment-variables.EXT mapping file
733
747
  var customEnvVars = util.getCustomEnvVars(CONFIG_DIR, extNames);
734
748
  util.extendDeep(config, customEnvVars);
735
749
 
736
- // Place the mixed NODE_CONFIG into the environment
737
- env['NODE_CONFIG'] = JSON.stringify(util.extendDeep(envConfig, cmdLineConfig, {}));
738
-
739
750
  // Extend the original config with the contents of runtime.json (backwards compatibility)
740
751
  var runtimeJson = util.parseFile(RUNTIME_JSON_FILENAME) || {};
741
752
  util.extendDeep(config, runtimeJson);
@@ -773,7 +784,7 @@ util.resolveDeferredConfigs = function (config) {
773
784
  }
774
785
  } else {
775
786
  if (prop[property] instanceof DeferredConfig ) {
776
- prop[property]= prop[property].resolve.call(completeConfig,completeConfig)
787
+ prop[property]= prop[property].resolve.call(completeConfig,completeConfig, prop[property]._original);
777
788
  }
778
789
  else {
779
790
  // Nothing to do. Keep the property how it is.
@@ -796,7 +807,7 @@ util.resolveDeferredConfigs = function (config) {
796
807
  * .js = File to run that has a module.exports containing the config object
797
808
  * .coffee = File to run that has a module.exports with coffee-script containing the config object
798
809
  * .iced = File to run that has a module.exports with iced-coffee-script containing the config object
799
- * All other supported file types (yaml, toml, json, cson, hjson, json5, properties)
810
+ * All other supported file types (yaml, toml, json, cson, hjson, json5, properties, xml)
800
811
  * are parsed with util.parseString.
801
812
  *
802
813
  * If the file doesn't exist, a null will be returned. If the file can't be
@@ -911,6 +922,7 @@ util.parseFile = function(fullFilename) {
911
922
  * hjson = Parsed with a HJSON parser
912
923
  * json5 = Parsed with a JSON5 parser
913
924
  * properties = Parsed with the 'properties' node package
925
+ * xml = Parsed with a XML parser
914
926
  *
915
927
  * If the file doesn't exist, a null will be returned. If the file can't be
916
928
  * parsed, an exception will be thrown.
@@ -1016,6 +1028,18 @@ util.parseString = function (content, format) {
1016
1028
  PPARSER = require('properties');
1017
1029
  }
1018
1030
  configObject = PPARSER.parse(content, { namespaces: true, variables: true, sections: true });
1031
+ } else if (format === 'xml') {
1032
+
1033
+ if (!XML) {
1034
+ XML = require('x2js');
1035
+ }
1036
+
1037
+ var x2js = new XML();
1038
+ configObject = x2js.xml2js(content);
1039
+ var rootKeys = Object.keys(configObject);
1040
+ if(rootKeys.length == 1) {
1041
+ configObject = configObject[rootKeys[0]];
1042
+ }
1019
1043
  }
1020
1044
 
1021
1045
  return configObject;
@@ -1041,6 +1065,9 @@ util.parseString = function (content, format) {
1041
1065
  * @return toObject
1042
1066
  */
1043
1067
  util.attachProtoDeep = function(toObject, depth) {
1068
+ if (toObject instanceof RawConfig) {
1069
+ return toObject;
1070
+ }
1044
1071
 
1045
1072
  // Recursion detection
1046
1073
  var t = this;
@@ -1402,8 +1429,14 @@ util.extendDeep = function(mergeInto) {
1402
1429
  // Cycle through each element of the object to merge from
1403
1430
  for (var prop in mergeFrom) {
1404
1431
 
1405
- // Extend recursively if both elements are objects and target is not really a deferred function
1432
+ // save original value in deferred elements
1433
+ var fromIsDeferredFunc = mergeFrom[prop] instanceof DeferredConfig;
1406
1434
  var isDeferredFunc = mergeInto[prop] instanceof DeferredConfig;
1435
+
1436
+ if (fromIsDeferredFunc && mergeInto.hasOwnProperty(prop)) {
1437
+ mergeFrom[prop]._original = isDeferredFunc ? mergeInto[prop]._original : mergeInto[prop];
1438
+ }
1439
+ // Extend recursively if both elements are objects and target is not really a deferred function
1407
1440
  if (mergeFrom[prop] instanceof Date) {
1408
1441
  mergeInto[prop] = mergeFrom[prop];
1409
1442
  } else if (util.isObject(mergeInto[prop]) && util.isObject(mergeFrom[prop]) && !isDeferredFunc) {
@@ -1416,11 +1449,10 @@ util.extendDeep = function(mergeInto) {
1416
1449
  }
1417
1450
 
1418
1451
  // Copy property descriptor otherwise, preserving accessors
1419
- else {
1420
- var descriptor = Object.getOwnPropertyDescriptor(Object(mergeFrom), prop);
1421
- if (descriptor) {
1422
- Object.defineProperty(mergeInto, prop, descriptor);
1423
- }
1452
+ else if (Object.getOwnPropertyDescriptor(Object(mergeFrom), prop)){
1453
+ Object.defineProperty(mergeInto, prop, Object.getOwnPropertyDescriptor(Object(mergeFrom), prop));
1454
+ } else {
1455
+ mergeInto[prop] = mergeFrom[prop];
1424
1456
  }
1425
1457
  }
1426
1458
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "config",
3
- "version": "1.20.3",
3
+ "version": "1.24.0",
4
4
  "main": "./lib/config.js",
5
5
  "description": "Configuration control for production node deployments",
6
6
  "author": "Loren West <open_source@lorenwest.com>",
@@ -28,7 +28,9 @@
28
28
  "js-yaml": "^3.2.2",
29
29
  "properties": "~1.2.1",
30
30
  "toml": "^2.0.6",
31
- "vows": ">=0.8.1"
31
+ "underscore": "^1.8.3",
32
+ "vows": ">=0.8.1",
33
+ "x2js": "^2.0.1"
32
34
  },
33
35
  "repository": {
34
36
  "type": "git",
package/raw.js ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * This is meant to wrap configuration objects that should be left as is,
3
+ * meaning that the object or its protoype will not be modified in any way
4
+ */
5
+ function RawConfig () {
6
+ }
7
+
8
+ function raw(rawObj) {
9
+ var obj = Object.create(RawConfig.prototype);
10
+ obj.resolve = function () { return rawObj; }
11
+ return obj;
12
+ }
13
+
14
+ module.exports.RawConfig = RawConfig;
15
+ module.exports.raw = raw;