config 3.3.12 → 4.0.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/async.js +5 -6
- package/lib/config.js +59 -50
- package/package.json +16 -3
- package/parser.js +3 -67
package/async.js
CHANGED
|
@@ -41,12 +41,11 @@ function resolveAsyncConfigs(config) {
|
|
|
41
41
|
var promises = [];
|
|
42
42
|
var resolvers = [];
|
|
43
43
|
(function iterate(prop) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (Object.hasOwnProperty.call(prop, property) && prop[property] != null) {
|
|
47
|
-
propsToSort.push(property);
|
|
48
|
-
}
|
|
44
|
+
if (prop.constructor === String) {
|
|
45
|
+
return;
|
|
49
46
|
}
|
|
47
|
+
|
|
48
|
+
var propsToSort = Object.keys(prop).filter((property) => prop[property] != null);
|
|
50
49
|
propsToSort.sort().forEach(function(property) {
|
|
51
50
|
if (prop[property].constructor === Object) {
|
|
52
51
|
iterate(prop[property]);
|
|
@@ -54,7 +53,7 @@ function resolveAsyncConfigs(config) {
|
|
|
54
53
|
else if (prop[property].constructor === Array) {
|
|
55
54
|
prop[property].forEach(iterate);
|
|
56
55
|
}
|
|
57
|
-
else if (prop[property]
|
|
56
|
+
else if (prop[property].async === asyncSymbol) {
|
|
58
57
|
resolvers.push(prop[property].prepare(config, prop, property));
|
|
59
58
|
promises.push(prop[property]);
|
|
60
59
|
}
|
package/lib/config.js
CHANGED
|
@@ -414,6 +414,29 @@ util.makeImmutable = function(object, property, value) {
|
|
|
414
414
|
// Create a proxy, to capture user updates of configuration options, and throw an exception for awareness, as per:
|
|
415
415
|
// https://github.com/lorenwest/node-config/issues/514
|
|
416
416
|
value = new Proxy(util.makeImmutable(value), {
|
|
417
|
+
get(target, property, receiver) {
|
|
418
|
+
// Config's own defined prototype properties and methods (e.g., `get`, `has`, etc.)
|
|
419
|
+
const ownProps = [
|
|
420
|
+
...Object.getOwnPropertyNames(Config.prototype),
|
|
421
|
+
...Object.getOwnPropertyNames(target),
|
|
422
|
+
]
|
|
423
|
+
|
|
424
|
+
// Bypass proxy receiver for properties directly on the target (e.g., RegExp.prototype.source)
|
|
425
|
+
// or properties that are not functions to prevent errors related to internal object methods.
|
|
426
|
+
if (ownProps.includes(property) || (property in target && typeof target[property] !== 'function')) {
|
|
427
|
+
return Reflect.get(target, property);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Otherwise, use the proxy receiver to handle the property access
|
|
431
|
+
const ref = Reflect.get(target, property, receiver);
|
|
432
|
+
|
|
433
|
+
// Binds the method's `this` context to the target object (e.g., Date.prototype.toISOString)
|
|
434
|
+
// to ensure it behaves correctly when called on the proxy.
|
|
435
|
+
if (typeof ref === 'function') {
|
|
436
|
+
return ref.bind(target);
|
|
437
|
+
}
|
|
438
|
+
return ref;
|
|
439
|
+
},
|
|
417
440
|
set (target, name) {
|
|
418
441
|
const message = (Reflect.has(target, name) ? 'update' : 'add');
|
|
419
442
|
// Notify the user.
|
|
@@ -493,15 +516,14 @@ util.getOption = function(options, optionName, defaultValue) {
|
|
|
493
516
|
* (hostname)-(deployment).EXT
|
|
494
517
|
* local.EXT
|
|
495
518
|
* local-(deployment).EXT
|
|
496
|
-
* runtime.json
|
|
497
519
|
* </pre>
|
|
498
520
|
*
|
|
499
521
|
* <p>
|
|
500
|
-
* EXT can be yml, yaml, coffee, iced, json, cson or js signifying the file type.
|
|
522
|
+
* EXT can be yml, yaml, coffee, iced, json, jsonc, cson or js signifying the file type.
|
|
501
523
|
* yaml (and yml) is in YAML format, coffee is a coffee-script, iced is iced-coffee-script,
|
|
502
|
-
* json is in JSON format,
|
|
503
|
-
* (http://en.wikipedia.org/wiki/.properties), and js is a javascript
|
|
504
|
-
* require()'d with module.exports being the config object.
|
|
524
|
+
* json is in JSON format, jsonc is in JSONC format, cson is in CSON format, properties is
|
|
525
|
+
* in .properties format (http://en.wikipedia.org/wiki/.properties), and js is a javascript
|
|
526
|
+
* executable file that is require()'d with module.exports being the config object.
|
|
505
527
|
* </p>
|
|
506
528
|
*
|
|
507
529
|
* <p>
|
|
@@ -523,11 +545,6 @@ util.getOption = function(options, optionName, defaultValue) {
|
|
|
523
545
|
* </p>
|
|
524
546
|
*
|
|
525
547
|
* <p>
|
|
526
|
-
* The runtime.json file contains configuration changes made at runtime either
|
|
527
|
-
* manually, or by the application setting a configuration value.
|
|
528
|
-
* </p>
|
|
529
|
-
*
|
|
530
|
-
* <p>
|
|
531
548
|
* If the $NODE_APP_INSTANCE environment variable (or --NODE_APP_INSTANCE
|
|
532
549
|
* command line parameter) is set, then files with this appendage will be loaded.
|
|
533
550
|
* See the Multiple Application Instances section of the main documentation page
|
|
@@ -576,9 +593,6 @@ util.loadFileConfigs = function(configDir, options) {
|
|
|
576
593
|
APP_INSTANCE = util.initParam('NODE_APP_INSTANCE');
|
|
577
594
|
CONFIG_SKIP_GITCRYPT = util.initParam('CONFIG_SKIP_GITCRYPT');
|
|
578
595
|
|
|
579
|
-
// This is for backward compatibility
|
|
580
|
-
const runtimeFilename = util.initParam('NODE_CONFIG_RUNTIME_JSON', Path.join(dir , 'runtime.json') );
|
|
581
|
-
|
|
582
596
|
NODE_CONFIG_PARSER = util.initParam('NODE_CONFIG_PARSER');
|
|
583
597
|
if (NODE_CONFIG_PARSER) {
|
|
584
598
|
try {
|
|
@@ -637,12 +651,15 @@ util.loadFileConfigs = function(configDir, options) {
|
|
|
637
651
|
let resolutionIndex = 1;
|
|
638
652
|
const extNames = Parser.getFilesOrder();
|
|
639
653
|
baseNames.forEach(function(baseName) {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
654
|
+
const fileNames = [baseName];
|
|
655
|
+
if (APP_INSTANCE) {
|
|
656
|
+
fileNames.push(baseName + '-' + APP_INSTANCE);
|
|
657
|
+
}
|
|
658
|
+
fileNames.forEach(function(fileName) {
|
|
659
|
+
extNames.forEach(function(extName) {
|
|
660
|
+
allowedFiles[fileName + '.' + extName] = resolutionIndex++;
|
|
661
|
+
});
|
|
662
|
+
})
|
|
646
663
|
});
|
|
647
664
|
|
|
648
665
|
const locatedFiles = util.locateMatchingFiles(dir, allowedFiles);
|
|
@@ -702,10 +719,6 @@ util.loadFileConfigs = function(configDir, options) {
|
|
|
702
719
|
const customEnvVars = util.getCustomEnvVars(dir, extNames);
|
|
703
720
|
util.extendDeep(config, customEnvVars);
|
|
704
721
|
|
|
705
|
-
// Extend the original config with the contents of runtime.json (backwards compatibility)
|
|
706
|
-
const runtimeJson = util.parseFile(runtimeFilename) || {};
|
|
707
|
-
util.extendDeep(config, runtimeJson);
|
|
708
|
-
|
|
709
722
|
util.resolveDeferredConfigs(config);
|
|
710
723
|
|
|
711
724
|
// Return the configuration object
|
|
@@ -725,19 +738,18 @@ util.loadFileConfigs = function(configDir, options) {
|
|
|
725
738
|
*/
|
|
726
739
|
util.locateMatchingFiles = function(configDirs, allowedFiles) {
|
|
727
740
|
return configDirs.split(Path.delimiter)
|
|
741
|
+
.filter(Boolean)
|
|
728
742
|
.reduce(function(files, configDir) {
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
catch(e) {}
|
|
739
|
-
return files;
|
|
743
|
+
configDir = _toAbsolutePath(configDir);
|
|
744
|
+
try {
|
|
745
|
+
FileSystem.readdirSync(configDir)
|
|
746
|
+
.filter(file => allowedFiles[file])
|
|
747
|
+
.forEach(function(file) {
|
|
748
|
+
files.push([allowedFiles[file], Path.join(configDir, file)]);
|
|
749
|
+
});
|
|
740
750
|
}
|
|
751
|
+
catch(e) {}
|
|
752
|
+
return files;
|
|
741
753
|
}, [])
|
|
742
754
|
.sort(function(a, b) { return a[0] - b[0]; })
|
|
743
755
|
.map(function(file) { return file[1]; });
|
|
@@ -748,16 +760,12 @@ util.resolveDeferredConfigs = function (config) {
|
|
|
748
760
|
const deferred = [];
|
|
749
761
|
|
|
750
762
|
function _iterate (prop) {
|
|
763
|
+
if (prop.constructor === String) {
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
751
766
|
|
|
752
767
|
// We put the properties we are going to look it in an array to keep the order predictable
|
|
753
|
-
const propsToSort = [];
|
|
754
|
-
|
|
755
|
-
// First step is to put the properties of interest in an array
|
|
756
|
-
for (const property in prop) {
|
|
757
|
-
if (Object.hasOwnProperty.call(prop, property) && prop[property] != null) {
|
|
758
|
-
propsToSort.push(property);
|
|
759
|
-
}
|
|
760
|
-
}
|
|
768
|
+
const propsToSort = Object.keys(prop).filter((property) => prop[property] != null);
|
|
761
769
|
|
|
762
770
|
// Second step is to iterate of the elements in a predictable (sorted) order
|
|
763
771
|
propsToSort.sort().forEach(function (property) {
|
|
@@ -797,7 +805,7 @@ util.resolveDeferredConfigs = function (config) {
|
|
|
797
805
|
* .js = File to run that has a module.exports containing the config object
|
|
798
806
|
* .coffee = File to run that has a module.exports with coffee-script containing the config object
|
|
799
807
|
* .iced = File to run that has a module.exports with iced-coffee-script containing the config object
|
|
800
|
-
* All other supported file types (yaml, toml, json, cson, hjson, json5, properties, xml)
|
|
808
|
+
* All other supported file types (yaml, toml, json, jsonc, cson, hjson, json5, properties, xml)
|
|
801
809
|
* are parsed with util.parseString.
|
|
802
810
|
*
|
|
803
811
|
* If the file doesn't exist, a null will be returned. If the file can't be
|
|
@@ -872,7 +880,8 @@ util.parseFile = function(fullFilename, options) {
|
|
|
872
880
|
*
|
|
873
881
|
* The format determines the parser to use.
|
|
874
882
|
*
|
|
875
|
-
* json =
|
|
883
|
+
* json = Parsed with a JSON5 parser
|
|
884
|
+
* jsonc = Parsed with a JSON5 parser
|
|
876
885
|
* yaml (or yml) = Parsed with a YAML parser
|
|
877
886
|
* toml = Parsed with a TOML parser
|
|
878
887
|
* cson = Parsed with a CSON parser
|
|
@@ -1277,11 +1286,9 @@ util.diffDeep = function(object1, object2, depth) {
|
|
|
1277
1286
|
* @param depth {integer} An optional depth to prevent recursion. Default: 20.
|
|
1278
1287
|
* @return {object} The altered mergeInto object is returned
|
|
1279
1288
|
*/
|
|
1280
|
-
util.extendDeep = function(mergeInto) {
|
|
1289
|
+
util.extendDeep = function(mergeInto, ...vargs) {
|
|
1281
1290
|
|
|
1282
1291
|
// Initialize
|
|
1283
|
-
const t = this;
|
|
1284
|
-
const vargs = Array.prototype.slice.call(arguments, 1);
|
|
1285
1292
|
let depth = vargs.pop();
|
|
1286
1293
|
if (typeof(depth) != 'number') {
|
|
1287
1294
|
vargs.push(depth);
|
|
@@ -1457,8 +1464,11 @@ util.toObject = function(config) {
|
|
|
1457
1464
|
|
|
1458
1465
|
// Run strictness checks on NODE_ENV and NODE_APP_INSTANCE and throw an error if there's a problem.
|
|
1459
1466
|
util.runStrictnessChecks = function (config) {
|
|
1460
|
-
|
|
1467
|
+
if (util.initParam('SUPPRESS_STRICTNESS_CHECK')) {
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1461
1470
|
|
|
1471
|
+
const sources = config.util.getConfigSources();
|
|
1462
1472
|
const sourceFilenames = sources.map(function (src) {
|
|
1463
1473
|
return Path.basename(src.name);
|
|
1464
1474
|
});
|
|
@@ -1513,8 +1523,7 @@ function _toAbsolutePath (configDir) {
|
|
|
1513
1523
|
// Instantiate and export the configuration
|
|
1514
1524
|
const config = module.exports = new Config();
|
|
1515
1525
|
|
|
1516
|
-
// copy
|
|
1517
|
-
util.stripComments = Parser.stripComments;
|
|
1526
|
+
// copy method to util for backwards compatibility
|
|
1518
1527
|
util.stripYamlComments = Parser.stripYamlComments;
|
|
1519
1528
|
|
|
1520
1529
|
// Produce warnings if the configuration is empty
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "config",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.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>",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"cson": "^3.0.1",
|
|
31
31
|
"hjson": "^1.2.0",
|
|
32
32
|
"js-yaml": "^3.2.2",
|
|
33
|
+
"nyc": "^15.1.0",
|
|
33
34
|
"properties": "~1.2.1",
|
|
34
35
|
"semver": "5.3.0",
|
|
35
36
|
"toml": "^2.0.6",
|
|
@@ -44,9 +45,21 @@
|
|
|
44
45
|
"url": "http://github.com/node-config/node-config.git"
|
|
45
46
|
},
|
|
46
47
|
"engines": {
|
|
47
|
-
"node": ">=
|
|
48
|
+
"node": ">= 20.0.0"
|
|
49
|
+
},
|
|
50
|
+
"nyc": {
|
|
51
|
+
"include": [
|
|
52
|
+
"*.js",
|
|
53
|
+
"lib/**/*.js"
|
|
54
|
+
],
|
|
55
|
+
"extension": [
|
|
56
|
+
".js"
|
|
57
|
+
],
|
|
58
|
+
"report-dir": "./coverage",
|
|
59
|
+
"reporter": "lcov"
|
|
48
60
|
},
|
|
49
61
|
"scripts": {
|
|
50
|
-
"test": "
|
|
62
|
+
"test": "nyc vows test/*.js --spec",
|
|
63
|
+
"vows": "nyc vows"
|
|
51
64
|
}
|
|
52
65
|
}
|
package/parser.js
CHANGED
|
@@ -208,72 +208,6 @@ Parser.propertiesParser = function(filename, content) {
|
|
|
208
208
|
return PPARSER.parse(content, { namespaces: true, variables: true, sections: true });
|
|
209
209
|
};
|
|
210
210
|
|
|
211
|
-
/**
|
|
212
|
-
* Strip all Javascript type comments from the string.
|
|
213
|
-
*
|
|
214
|
-
* The string is usually a file loaded from the O/S, containing
|
|
215
|
-
* newlines and javascript type comments.
|
|
216
|
-
*
|
|
217
|
-
* Thanks to James Padolsey, and all who contributed to this implementation.
|
|
218
|
-
* http://james.padolsey.com/javascript/javascript-comment-removal-revisted/
|
|
219
|
-
*
|
|
220
|
-
* @protected
|
|
221
|
-
* @method stripComments
|
|
222
|
-
* @param fileStr {string} The string to strip comments from
|
|
223
|
-
* @param stringRegex {RegExp} Optional regular expression to match strings that
|
|
224
|
-
* make up the config file
|
|
225
|
-
* @return {string} The string with comments stripped.
|
|
226
|
-
*/
|
|
227
|
-
Parser.stripComments = function(fileStr, stringRegex) {
|
|
228
|
-
stringRegex = stringRegex || /"((?:[^"\\]|\\.)*)"/g;
|
|
229
|
-
|
|
230
|
-
var uid = '_' + +new Date(),
|
|
231
|
-
primitives = [],
|
|
232
|
-
primIndex = 0;
|
|
233
|
-
|
|
234
|
-
return (
|
|
235
|
-
fileStr
|
|
236
|
-
|
|
237
|
-
/* Remove strings */
|
|
238
|
-
.replace(stringRegex, function(match){
|
|
239
|
-
primitives[primIndex] = match;
|
|
240
|
-
return (uid + '') + primIndex++;
|
|
241
|
-
})
|
|
242
|
-
|
|
243
|
-
/* Remove Regexes */
|
|
244
|
-
.replace(/([^\/])(\/(?!\*|\/)(\\\/|.)+?\/[gim]{0,3})/g, function(match, $1, $2){
|
|
245
|
-
primitives[primIndex] = $2;
|
|
246
|
-
return $1 + (uid + '') + primIndex++;
|
|
247
|
-
})
|
|
248
|
-
|
|
249
|
-
/*
|
|
250
|
-
- Remove single-line comments that contain would-be multi-line delimiters
|
|
251
|
-
E.g. // Comment /* <--
|
|
252
|
-
- Remove multi-line comments that contain would be single-line delimiters
|
|
253
|
-
E.g. /* // <--
|
|
254
|
-
*/
|
|
255
|
-
.replace(/\/\/.*?\/?\*.+?(?=\n|\r|$)|\/\*[\s\S]*?\/\/[\s\S]*?\*\//g, '')
|
|
256
|
-
|
|
257
|
-
/*
|
|
258
|
-
Remove single and multi-line comments,
|
|
259
|
-
no consideration of inner-contents
|
|
260
|
-
*/
|
|
261
|
-
.replace(/\/\/.+?(?=\n|\r|$)|\/\*[\s\S]+?\*\//g, '')
|
|
262
|
-
|
|
263
|
-
/*
|
|
264
|
-
Remove multi-line comments that have a replaced ending (string/regex)
|
|
265
|
-
Greedy, so no inner strings/regexes will stop it.
|
|
266
|
-
*/
|
|
267
|
-
.replace(RegExp('\\/\\*[\\s\\S]+' + uid + '\\d+', 'g'), '')
|
|
268
|
-
|
|
269
|
-
/* Bring back strings & regexes */
|
|
270
|
-
.replace(RegExp(uid + '(\\d+)', 'g'), function(match, n){
|
|
271
|
-
return primitives[n];
|
|
272
|
-
})
|
|
273
|
-
);
|
|
274
|
-
|
|
275
|
-
};
|
|
276
|
-
|
|
277
211
|
/**
|
|
278
212
|
* Strip YAML comments from the string
|
|
279
213
|
*
|
|
@@ -313,7 +247,7 @@ Parser.numberParser = function(filename, content) {
|
|
|
313
247
|
return Number.isNaN(numberValue) ? undefined : numberValue;
|
|
314
248
|
};
|
|
315
249
|
|
|
316
|
-
var order = ['js', 'cjs', 'ts', 'json', 'json5', 'hjson', 'toml', 'coffee', 'iced', 'yaml', 'yml', 'cson', 'properties', 'xml',
|
|
250
|
+
var order = ['js', 'cjs', 'mjs', 'ts', 'json', 'jsonc', 'json5', 'hjson', 'toml', 'coffee', 'iced', 'yaml', 'yml', 'cson', 'properties', 'xml',
|
|
317
251
|
'boolean', 'number'];
|
|
318
252
|
var definitions = {
|
|
319
253
|
cjs: Parser.jsParser,
|
|
@@ -323,7 +257,9 @@ var definitions = {
|
|
|
323
257
|
iced: Parser.icedParser,
|
|
324
258
|
js: Parser.jsParser,
|
|
325
259
|
json: Parser.jsonParser,
|
|
260
|
+
jsonc: Parser.jsonParser,
|
|
326
261
|
json5: Parser.json5Parser,
|
|
262
|
+
mjs: Parser.jsParser,
|
|
327
263
|
properties: Parser.propertiesParser,
|
|
328
264
|
toml: Parser.tomlParser,
|
|
329
265
|
ts: Parser.tsParser,
|