Skip to content

Commit 0e48220

Browse files
A-312madarche
authored andcommitted
Fire error with 'properties' keyname in schema and 'properties' of convict become '_cvtProperties' (#336)
* Change 'properties' name (reserved word) Update test * Fire error if 'properties' key is used
1 parent 9710356 commit 0e48220

3 files changed

Lines changed: 44 additions & 29 deletions

File tree

packages/convict/lib/convict.js

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ function flatten(obj, useProperties) {
8383
let val = walk(obj, key);
8484
if (typeof val === 'object' && !Array.isArray(val) && val != null) {
8585
if (useProperties) {
86-
if ('properties' in val) {
87-
val = val.properties;
88-
key = key + '.properties';
86+
if ('_cvtProperties' in val) {
87+
val = val._cvtProperties;
88+
key = key + '._cvtProperties';
8989
} else {
9090
entries.push([key, val]);
9191
continue;
@@ -108,7 +108,7 @@ function flatten(obj, useProperties) {
108108
entries.forEach(function(entry) {
109109
let key = entry[0];
110110
if (useProperties) {
111-
key = key.replace(/\.properties/g, '');
111+
key = key.replace(/\._cvtProperties/g, '');
112112
}
113113
const val = entry[1];
114114
flattened[key] = val;
@@ -125,7 +125,7 @@ function validate(instance, schema, strictValidation) {
125125
};
126126

127127
const flatInstance = flatten(instance);
128-
const flatSchema = flatten(schema.properties, true);
128+
const flatSchema = flatten(schema._cvtProperties, true);
129129

130130
Object.keys(flatSchema).forEach(function(name) {
131131
const schemaItem = flatSchema[name];
@@ -202,14 +202,18 @@ const BUILT_INS = BUILT_IN_NAMES.map(function(name) {
202202
});
203203

204204
function normalizeSchema(name, node, props, fullName, env, argv, sensitive) {
205+
if (name === '_cvtProperties') {
206+
throw new Error("'" + fullName + "': '_cvtProperties' is reserved word of convict.");
207+
}
208+
205209
// If the current schema node is not a config property (has no "default"), recursively normalize it.
206210
if (typeof node === 'object' && node !== null && !Array.isArray(node) &&
207211
Object.keys(node).length > 0 && !('default' in node)) {
208212
props[name] = {
209-
properties: {}
213+
_cvtProperties: {}
210214
};
211215
Object.keys(node).forEach(function(k) {
212-
normalizeSchema(k, node[k], props[name].properties, fullName + '.' +
216+
normalizeSchema(k, node[k], props[name]._cvtProperties, fullName + '.' +
213217
k, env, argv, sensitive);
214218
});
215219
return;
@@ -328,9 +332,9 @@ function importArguments(o) {
328332
}
329333

330334
function addDefaultValues(schema, c, instance) {
331-
Object.keys(schema.properties).forEach(function(name) {
332-
let p = schema.properties[name];
333-
if (p.properties) {
335+
Object.keys(schema._cvtProperties).forEach(function(name) {
336+
let p = schema._cvtProperties[name];
337+
if (p._cvtProperties) {
334338
let kids = c[name] || {};
335339
addDefaultValues(p, kids, instance);
336340
c[name] = kids;
@@ -349,7 +353,7 @@ function overlay(from, to, schema) {
349353
to[k] = coerce(k, from[k], schema);
350354
} else {
351355
if (!isObj(to[k])) to[k] = {};
352-
overlay(from[k], to[k], schema.properties[k]);
356+
overlay(from[k], to[k], schema._cvtProperties[k]);
353357
}
354358
});
355359
}
@@ -359,8 +363,8 @@ function traverseSchema(schema, path) {
359363
let o = schema;
360364
while (ar.length > 0) {
361365
let k = ar.shift();
362-
if (o && o.properties && o.properties[k]) {
363-
o = o.properties[k];
366+
if (o && o._cvtProperties && o._cvtProperties[k]) {
367+
o = o._cvtProperties[k];
364368
} else {
365369
o = null;
366370
break;
@@ -510,10 +514,10 @@ let convict = function convict(def, opts) {
510514
* notation to reference nested values
511515
*/
512516
default: function(path) {
513-
// The default value for FOO.BAR.BAZ is stored in `_schema.properties` at:
514-
// FOO.properties.BAR.properties.BAZ.default
515-
path = (path.split('.').join('.properties.')) + '.default';
516-
let o = walk(this._schema.properties, path);
517+
// The default value for FOO.BAR.BAZ is stored in `_schema._cvtProperties` at:
518+
// FOO._cvtProperties.BAR._cvtProperties.BAZ.default
519+
path = (path.split('.').join('._cvtProperties.')) + '.default';
520+
let o = walk(this._schema._cvtProperties, path);
517521
return cloneDeep(o);
518522
},
519523

@@ -661,15 +665,15 @@ let convict = function convict(def, opts) {
661665

662666
// build up current config from definition
663667
rv._schema = {
664-
properties: {}
668+
_cvtProperties: {}
665669
};
666670

667671
rv._env = {};
668672
rv._argv = {};
669673
rv._sensitive = new Set();
670674

671675
Object.keys(rv._def).forEach(function(k) {
672-
normalizeSchema(k, rv._def[k], rv._schema.properties, k, rv._env, rv._argv,
676+
normalizeSchema(k, rv._def[k], rv._schema._cvtProperties, k, rv._env, rv._argv,
673677
rv._sensitive);
674678
});
675679

packages/convict/test/cases/schema-object.schema

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"properties": {
2+
"_cvtProperties": {
33
"shorthand": {
44
"default": "value"
55
},
@@ -39,7 +39,7 @@
3939
"sensitive": false
4040
},
4141
"nested": {
42-
"properties": {
42+
"_cvtProperties": {
4343
"child": {
4444
"default": "ababa"
4545
}

packages/convict/test/schema-tests.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,33 @@ describe('convict schema', function() {
9595
}, null, 2));
9696
});
9797

98+
it('must throw if `_cvtProperties` (reserved keyword) is used', function() {
99+
(function() {
100+
conf = convict({
101+
_cvtProperties: {
102+
format: String,
103+
default: 'DEFAULT'
104+
}
105+
});
106+
}).must.throw();
107+
});
108+
98109
it('must export the schema as JSON', function() {
99110
let res = conf.getSchema();
100111
res.must.eql({
101-
'properties': {
112+
'_cvtProperties': {
102113
'foo': {
103-
'properties': {
114+
'_cvtProperties': {
104115
'bar': {
105116
'default': 7
106117
},
107118
'baz': {
108-
'properties': {
119+
'_cvtProperties': {
109120
'bing': {
110121
'default': 'foo'
111122
},
112123
'name with spaces': {
113-
'properties': {
124+
'_cvtProperties': {
114125
'name_with_underscores': {
115126
'default': true
116127
}
@@ -127,19 +138,19 @@ describe('convict schema', function() {
127138
it('must export the schema as a JSON string', function() {
128139
let res = conf.getSchemaString();
129140
res.must.eql(JSON.stringify({
130-
'properties': {
141+
'_cvtProperties': {
131142
'foo': {
132-
'properties': {
143+
'_cvtProperties': {
133144
'bar': {
134145
'default': 7
135146
},
136147
'baz': {
137-
'properties': {
148+
'_cvtProperties': {
138149
'bing': {
139150
'default': 'foo'
140151
},
141152
'name with spaces': {
142-
'properties': {
153+
'_cvtProperties': {
143154
'name_with_underscores': {
144155
'default': true
145156
}

0 commit comments

Comments
 (0)