@@ -47,6 +47,15 @@ export function jsonSchemaLinter(options?: JSONValidationOptions) {
47
47
} ;
48
48
}
49
49
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
+
50
59
export class JSONValidation {
51
60
private schema : Draft | null = null ;
52
61
@@ -117,37 +126,52 @@ export class JSONValidation {
117
126
if ( ! errors . length ) return [ ] ;
118
127
// reduce() because we want to filter out errors that don't have a pointer
119
128
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 = ( ) => {
128
130
const errorString = this . rewriteError ( error ) ;
129
131
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 ,
134
134
message : errorString ,
135
+ severity : "error" ,
136
+ source : this . schemaTitle ,
135
137
renderMessage : ( ) => {
136
138
const dom = el ( "div" , { } ) ;
137
139
dom . innerHTML = errorString ;
138
140
return dom ;
139
141
} ,
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 ,
150
142
} ) ;
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
+ }
151
175
}
152
176
return acc ;
153
177
} , [ ] as Diagnostic [ ] ) ;
0 commit comments