@@ -47,6 +47,15 @@ export function jsonSchemaLinter(options?: JSONValidationOptions) {
4747 } ;
4848}
4949
50+ // all the error types that apply to a specific key or value
51+ const positionalErrors = [
52+ "NoAdditionalPropertiesError" ,
53+ "RequiredPropertyError" ,
54+ "InvalidPropertyNameError" ,
55+ "ForbiddenPropertyError" ,
56+ "UndefinedValueError" ,
57+ ] ;
58+
5059export class JSONValidation {
5160 private schema : Draft | null = null ;
5261
@@ -117,37 +126,52 @@ export class JSONValidation {
117126 if ( ! errors . length ) return [ ] ;
118127 // reduce() because we want to filter out errors that don't have a pointer
119128 return errors . reduce ( ( acc , error ) => {
120- const errorPath = getErrorPath ( error ) ;
121- const pointer = json . pointers . get ( errorPath ) as JSONPointerData ;
122-
123- if ( pointer ) {
124- // if the error is a property error, use the key position
125- const isKeyError =
126- error . name === "NoAdditionalPropertiesError" ||
127- error . name === "RequiredPropertyError" ;
129+ const pushRoot = ( ) => {
128130 const errorString = this . rewriteError ( error ) ;
129131 acc . push ( {
130- from : isKeyError ? pointer . keyFrom : pointer . valueFrom ,
131- to : isKeyError ? pointer . keyTo : pointer . valueTo ,
132- // TODO: create a domnode and replace `` with <code></code>
133- // renderMessage: () => error.message,
132+ from : 0 ,
133+ to : 0 ,
134134 message : errorString ,
135+ severity : "error" ,
136+ source : this . schemaTitle ,
135137 renderMessage : ( ) => {
136138 const dom = el ( "div" , { } ) ;
137139 dom . innerHTML = errorString ;
138140 return dom ;
139141 } ,
140- severity : "error" ,
141- source : this . schemaTitle ,
142- } ) ;
143- } else {
144- acc . push ( {
145- from : 0 ,
146- to : 0 ,
147- message : this . rewriteError ( error ) ,
148- severity : "error" ,
149- source : this . schemaTitle ,
150142 } ) ;
143+ } ;
144+ const errorPath = getErrorPath ( error ) ;
145+ const pointer = json . pointers . get ( errorPath ) as JSONPointerData ;
146+ if (
147+ error . name === "MaxPropertiesError" ??
148+ error . name === "MinPropertiesError"
149+ ) {
150+ pushRoot ( ) ;
151+ }
152+ if ( pointer ) {
153+ // if the error is a property error, use the key position
154+ const isKeyError = positionalErrors . includes ( error . name ) ;
155+ const errorString = this . rewriteError ( error ) ;
156+ const from = isKeyError ? pointer . keyFrom : pointer . valueFrom ;
157+ const to = isKeyError ? pointer . keyTo : pointer . valueTo ;
158+ // skip error if no from/to value is found
159+ if ( to !== undefined && from !== undefined ) {
160+ acc . push ( {
161+ from,
162+ to,
163+ // TODO: create a domnode and replace `` with <code></code>
164+ // renderMessage: () => error.message,
165+ message : errorString ,
166+ renderMessage : ( ) => {
167+ const dom = el ( "div" , { } ) ;
168+ dom . innerHTML = errorString ;
169+ return dom ;
170+ } ,
171+ severity : "error" ,
172+ source : this . schemaTitle ,
173+ } ) ;
174+ }
151175 }
152176 return acc ;
153177 } , [ ] as Diagnostic [ ] ) ;
0 commit comments