github.com/kaptinlin/jsonschema@v0.4.6/propertyNames.go (about) 1 package jsonschema 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 // EvaluatePropertyNames checks if every property name in the object conforms to the schema specified by the propertyNames attribute. 9 // According to the JSON Schema Draft 2020-12: 10 // - The "propertyNames" keyword must be a valid JSON Schema. 11 // - If the instance is an object, this keyword validates if every property name in the instance validates against the provided schema. 12 // - The property name that the schema is testing will always be a string. 13 // - Omitting this keyword has the same behavior as an empty schema. 14 // 15 // This method ensures that each property name in the object instance conforms to the constraints defined in the propertyNames schema. 16 // If a property name does not conform, it returns a EvaluationError detailing the issue with that specific property name. 17 // 18 // Reference: https://json-schema.org/draft/2020-12/json-schema-core#name-propertynames 19 func evaluatePropertyNames(schema *Schema, object map[string]interface{}, _ map[string]bool, _ map[int]bool, dynamicScope *DynamicScope) ([]*EvaluationResult, *EvaluationError) { 20 if schema.PropertyNames == nil { 21 // No propertyNames schema defined, equivalent to an empty schema, which means all property names are valid. 22 return nil, nil 23 } 24 25 invalid_properties := []string{} 26 results := []*EvaluationResult{} 27 28 if schema.PropertyNames != nil { 29 for propName := range object { 30 result, _, _ := schema.PropertyNames.evaluate(propName, dynamicScope) 31 32 if result != nil { 33 //nolint:errcheck 34 result.SetEvaluationPath(fmt.Sprintf("/propertyNames/%s", propName)). 35 SetSchemaLocation(schema.GetSchemaLocation(fmt.Sprintf("/propertyNames/%s", propName))). 36 SetInstanceLocation(fmt.Sprintf("/%s", propName)) 37 } 38 39 results = append(results, result) 40 41 if !result.IsValid() { 42 invalid_properties = append(invalid_properties, propName) 43 } 44 } 45 } 46 47 if len(invalid_properties) == 1 { 48 return results, NewEvaluationError("propertyNames", "property_name_mismatch", "Property name {property} does not match the schema", map[string]interface{}{ 49 "property": fmt.Sprintf("'%s'", invalid_properties[0]), 50 }) 51 } else if len(invalid_properties) > 1 { 52 quotedProperties := make([]string, len(invalid_properties)) 53 for i, prop := range invalid_properties { 54 quotedProperties[i] = fmt.Sprintf("'%s'", prop) 55 } 56 return results, NewEvaluationError("propertyNames", "property_names_mismatch", "Property names {properties} do not match the schema", map[string]interface{}{ 57 "properties": strings.Join(quotedProperties, ", "), 58 }) 59 } 60 61 return results, nil 62 }