Skip to content

Commit 537a7dc

Browse files
committed
Refs jdorn#811 - add propertyNames support
1 parent 0443760 commit 537a7dc

File tree

4 files changed

+263
-1
lines changed

4 files changed

+263
-1
lines changed

src/defaults.js

+40
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,46 @@ languages.en = {
145145
*/
146146
error_additional_properties: 'No additional properties allowed, but property {{0}} is set',
147147
/**
148+
* When there is a propertyName that sets a max length and a property name exceeds the max length
149+
* @variables This key takes one variable: The name of the invalid property
150+
*/
151+
error_property_names_exceeds_maxlength: 'Property name {{0}} exceeds maxLength',
152+
/**
153+
* When there is a propertyName that sets an enum and a property name matches none of the possible enum
154+
* @variables This key takes one variable: The name of the invalid property
155+
*/
156+
error_property_names_enum_mismatch: 'Property name {{0}} does not match any enum values',
157+
/**
158+
* When there is a propertyName that sets a pattern and a property name does not match the pattern
159+
* @variables This key takes one variable: The name of the invalid property
160+
*/
161+
error_property_names_pattern_mismatch: 'Property name {{0}} does not match pattern',
162+
/**
163+
* When the propertyName is set to false and there is at least one property
164+
* @variables This key takes one variable: The name of the invalid property
165+
*/
166+
error_property_names_false: 'Property name {{0}} fails when propertyName is false',
167+
/**
168+
* When the propertyName specifies a maxLength that is not a number
169+
* @variables This key takes one variable: The name of the current property
170+
*/
171+
error_property_names_maxlength: 'Property name {{0}} cannot match invalid maxLength',
172+
/**
173+
* When the propertyName specifies an enum that is not an array
174+
* @variables This key takes one variable: The name of the current property
175+
*/
176+
error_property_names_enum: 'Property name {{0}} cannot match invalid enum',
177+
/**
178+
* When the propertyName specifies a pattern that is not a string
179+
* @variables This key takes one variable: The name of the current property
180+
*/
181+
error_property_names_pattern: 'Property name {{0}} cannot match invalid pattern',
182+
/**
183+
* When the propertyName is unsupported
184+
* @variables This key takes one variable: The name of the invalid propertyName
185+
*/
186+
error_property_names_unsupported: 'Unsupported propertyName {{0}}',
187+
/**
148188
* When a dependency is not resolved
149189
* @variables This key takes one variable: The name of the missing property for the dependency
150190
*/

src/editors/object.js

+1
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,7 @@ export class ObjectEditor extends AbstractEditor {
968968
[key]: {}
969969
}
970970
case 'additionalProperties':
971+
case 'propertyNames':
971972
return {
972973
...acc,
973974
[key]: true

src/validator.js

+81
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,87 @@ export class Validator {
375375
}
376376

377377
this._validateObjectSubSchema2 = {
378+
propertyNames (schema, value, path, validatedProperties) {
379+
const errors = []
380+
const keys = Object.keys(value)
381+
let k = null
382+
for (let i = 0; i < keys.length; i++) {
383+
let msg = ''
384+
let truthy = false
385+
k = keys[i]
386+
/* Check property names that don't match */
387+
if (typeof schema.propertyNames === 'boolean') {
388+
console.log(schema.propertyNames ? 'TRUE' : 'FALSE')
389+
console.log('*' + k + '*')
390+
if (schema.propertyNames === true) {
391+
continue
392+
}
393+
errors.push({
394+
path,
395+
property: 'propertyNames',
396+
message: this.translate('error_property_names_false', [k])
397+
})
398+
break
399+
}
400+
truthy = Object.entries(schema.propertyNames).every(([j, prop]) => {
401+
let match = false
402+
let regex = null
403+
switch (j) {
404+
case 'maxLength':
405+
if (typeof prop !== 'number') {
406+
msg = 'error_property_names_maxlength'
407+
break
408+
}
409+
if (k.length > prop) {
410+
msg = 'error_property_names_exceeds_maxlength'
411+
break
412+
}
413+
return true
414+
case 'enum':
415+
if (!Array.isArray(prop)) {
416+
msg = 'error_property_names_enum'
417+
break
418+
}
419+
prop.forEach(p => {
420+
if (p === k) {
421+
match = true
422+
}
423+
})
424+
if (!match) {
425+
msg = 'error_property_names_enum_mismatch'
426+
break
427+
}
428+
return true
429+
case 'pattern':
430+
if (typeof prop !== 'string') {
431+
msg = 'error_property_names_pattern'
432+
break
433+
}
434+
regex = new RegExp(prop)
435+
if (!regex.test(k)) {
436+
msg = 'error_property_names_pattern_mismatch'
437+
break
438+
}
439+
return true
440+
default:
441+
errors.push({
442+
path,
443+
property: 'propertyNames',
444+
message: this.translate('error_property_names_unsupported', [j])
445+
})
446+
return false
447+
}
448+
errors.push({
449+
path,
450+
property: 'propertyNames',
451+
message: this.translate(msg, [k])
452+
})
453+
return false
454+
})
455+
if (!truthy) break
456+
}
457+
return errors
458+
},
378459
additionalProperties (schema, value, path, validatedProperties) {
379460
const errors = []
380461
const keys = Object.keys(value)

tests/fixtures/validation.json

+141-1
Original file line numberDiff line numberDiff line change
@@ -962,5 +962,145 @@
962962
"abc 1999-01-01",
963963
"1999-01-01 abc"
964964
]
965+
},
966+
"property_names_invalid": {
967+
"schema": {
968+
"type": "object",
969+
"properties": {
970+
"abc": { "type": "string" }
971+
},
972+
"propertyNames": {
973+
"unsupported": 10
974+
}
975+
},
976+
"valid": [
977+
],
978+
"invalid": [
979+
{
980+
"abc": "hello"
981+
}
982+
]
983+
},
984+
"property_names_invalid_maxlength": {
985+
"schema": {
986+
"type": "object",
987+
"properties": {
988+
"abc": { "type": "string" }
989+
},
990+
"propertyNames": {
991+
"maxLength": "10"
992+
}
993+
},
994+
"valid": [
995+
],
996+
"invalid": [
997+
{
998+
"abc": "hello"
999+
}
1000+
]
1001+
},
1002+
"property_names_invalid_enum": {
1003+
"schema": {
1004+
"type": "object",
1005+
"properties": {
1006+
"abc": { "type": "string" }
1007+
},
1008+
"propertyNames": {
1009+
"enum": "list"
1010+
}
1011+
},
1012+
"valid": [
1013+
],
1014+
"invalid": [
1015+
{
1016+
"abc": "hello"
1017+
}
1018+
]
1019+
},
1020+
"property_names_invalid_pattern": {
1021+
"schema": {
1022+
"type": "object",
1023+
"properties": {
1024+
"abc": { "type": "string" }
1025+
},
1026+
"propertyNames": {
1027+
"pattern": [
1028+
"abc"
1029+
]
1030+
}
1031+
},
1032+
"valid": [
1033+
],
1034+
"invalid": [
1035+
{
1036+
"abc": "hello"
1037+
}
1038+
]
1039+
},
1040+
"property_names_true": {
1041+
"schema": {
1042+
"type": "object",
1043+
"properties": {
1044+
"abc": { "type": "string" }
1045+
},
1046+
"propertyNames": true
1047+
},
1048+
"valid": [
1049+
{
1050+
},
1051+
{
1052+
"abc": "hello"
1053+
}
1054+
],
1055+
"invalid": [
1056+
]
1057+
},
1058+
"property_names_false": {
1059+
"schema": {
1060+
"type": "object",
1061+
"properties": {
1062+
"abc": { "type": "string" }
1063+
},
1064+
"propertyNames": false
1065+
},
1066+
"valid": [
1067+
{
1068+
}
1069+
],
1070+
"invalid": [
1071+
{
1072+
"abc": "hello"
1073+
}
1074+
]
1075+
},
1076+
"property_names": {
1077+
"schema": {
1078+
"type": "object",
1079+
"propertyNames": {
1080+
"maxLength": 5,
1081+
"pattern": "^[a-z]+",
1082+
"enum": [
1083+
"alpha",
1084+
"bravo",
1085+
"charlie"
1086+
]
1087+
}
1088+
},
1089+
"valid": [
1090+
{
1091+
"alpha": {"type": "string" }
1092+
},
1093+
{
1094+
"bravo": {"type": "string" }
1095+
}
1096+
],
1097+
"invalid": [
1098+
{
1099+
"abc": { "type": "string" }
1100+
},
1101+
{
1102+
"charlie": { "type": "string" }
1103+
}
1104+
]
9651105
}
966-
}
1106+
}

0 commit comments

Comments
 (0)