@@ -39,12 +39,12 @@ import {
39
39
SET_SCHEMA ,
40
40
SET_UISCHEMA ,
41
41
SET_VALIDATION_MODE ,
42
+ UPDATE_CORE ,
42
43
UPDATE_DATA ,
43
44
UPDATE_ERRORS ,
44
- UPDATE_CORE ,
45
45
UpdateCoreAction
46
46
} from '../actions' ;
47
- import { createAjv , Reducer } from '../util' ;
47
+ import { pathsAreEqual , createAjv , pathStartsWith , Reducer } from '../util' ;
48
48
import { JsonSchema , UISchemaElement } from '../models' ;
49
49
50
50
export const validate = ( validator : ValidateFunction | undefined , data : any ) : ErrorObject [ ] => {
@@ -184,7 +184,7 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
184
184
state . ajv !== thisAjv ||
185
185
state . errors !== errors ||
186
186
state . validator !== validator ||
187
- state . validationMode !== validationMode
187
+ state . validationMode !== validationMode ;
188
188
return stateChanged
189
189
? {
190
190
...state ,
@@ -230,7 +230,8 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
230
230
case UPDATE_DATA : {
231
231
if ( action . path === undefined || action . path === null ) {
232
232
return state ;
233
- } else if ( action . path === '' ) {
233
+ }
234
+ if ( action . path . length === 0 ) {
234
235
// empty path is ok
235
236
const result = action . updater ( cloneDeep ( state . data ) ) ;
236
237
const errors = validate ( state . validator , result ) ;
@@ -317,32 +318,29 @@ export const getControlPath = (error: ErrorObject) => {
317
318
return dataPath . replace ( / \/ / g, '.' ) . substr ( 1 ) ;
318
319
}
319
320
// dataPath was renamed to instancePath in AJV v8
320
- var controlPath : string = error . instancePath ;
321
+ const controlPath = error . instancePath
322
+ . replace ( / ^ \/ / , '' ) // remove leading slash
323
+ . split ( '/' ) ; // convert to string[]
321
324
322
- // change '/' chars to '.'
323
- controlPath = controlPath . replace ( / \/ / g, '.' ) ;
324
-
325
325
const invalidProperty = getInvalidProperty ( error ) ;
326
- if ( invalidProperty !== undefined && ! controlPath . endsWith ( invalidProperty ) ) {
327
- controlPath = ` ${ controlPath } . ${ invalidProperty } ` ;
326
+ if ( invalidProperty !== undefined && controlPath . at ( - 1 ) !== invalidProperty ) {
327
+ controlPath . push ( invalidProperty ) ;
328
328
}
329
-
330
- // remove '.' chars at the beginning of paths
331
- controlPath = controlPath . replace ( / ^ ./ , '' ) ;
329
+
332
330
return controlPath ;
333
- }
331
+ } ;
334
332
335
333
export const errorsAt = (
336
- instancePath : string ,
334
+ instancePath : string [ ] ,
337
335
schema : JsonSchema ,
338
- matchPath : ( path : string ) => boolean
336
+ matchPath : ( path : string [ ] ) => boolean
339
337
) => ( errors : ErrorObject [ ] ) : ErrorObject [ ] => {
340
338
// Get data paths of oneOf and anyOf errors to later determine whether an error occurred inside a subschema of oneOf or anyOf.
341
339
const combinatorPaths = filter (
342
340
errors ,
343
341
error => error . keyword === 'oneOf' || error . keyword === 'anyOf'
344
342
) . map ( error => getControlPath ( error ) ) ;
345
-
343
+
346
344
return filter ( errors , error => {
347
345
// Filter errors that match any keyword that we don't want to show in the UI
348
346
if ( filteredErrorKeywords . indexOf ( error . keyword ) !== - 1 ) {
@@ -360,8 +358,8 @@ export const errorsAt = (
360
358
// because the parent schema can never match the property schema (e.g. for 'required' checks).
361
359
const parentSchema : JsonSchema | undefined = error . parentSchema ;
362
360
if ( result && ! isObjectSchema ( parentSchema )
363
- && combinatorPaths . findIndex ( p => instancePath . startsWith ( p ) ) !== - 1 ) {
364
- result = result && isEqual ( parentSchema , schema ) ;
361
+ && combinatorPaths . some ( combinatorPath => pathStartsWith ( instancePath , combinatorPath ) ) ) {
362
+ result = isEqual ( parentSchema , schema ) ;
365
363
}
366
364
return result ;
367
365
} ) ;
@@ -372,7 +370,7 @@ export const errorsAt = (
372
370
*/
373
371
const isObjectSchema = ( schema ?: JsonSchema ) : boolean => {
374
372
return schema ?. type === 'object' || ! ! schema ?. properties ;
375
- }
373
+ } ;
376
374
377
375
/**
378
376
* The error-type of an AJV error is defined by its `keyword` property.
@@ -388,13 +386,16 @@ const isObjectSchema = (schema?: JsonSchema): boolean => {
388
386
const filteredErrorKeywords = [ 'additionalProperties' , 'allOf' , 'anyOf' , 'oneOf' ] ;
389
387
390
388
const getErrorsAt = (
391
- instancePath : string ,
389
+ instancePath : string [ ] ,
392
390
schema : JsonSchema ,
393
- matchPath : ( path : string ) => boolean
391
+ matchPath : ( path : string [ ] ) => boolean
394
392
) => ( state : JsonFormsCore ) : ErrorObject [ ] =>
395
- errorsAt ( instancePath , schema , matchPath ) ( state . validationMode === 'ValidateAndHide' ? [ ] : state . errors ) ;
393
+ errorsAt ( instancePath , schema , matchPath ) (
394
+ state . validationMode === 'ValidateAndHide' ? [ ] : state . errors
395
+ ) ;
396
+
397
+ export const errorAt = ( instancePath : string [ ] , schema : JsonSchema ) =>
398
+ getErrorsAt ( instancePath , schema , path => pathsAreEqual ( path , instancePath ) ) ;
396
399
397
- export const errorAt = ( instancePath : string , schema : JsonSchema ) =>
398
- getErrorsAt ( instancePath , schema , path => path === instancePath ) ;
399
- export const subErrorsAt = ( instancePath : string , schema : JsonSchema ) =>
400
- getErrorsAt ( instancePath , schema , path => path . startsWith ( instancePath ) ) ;
400
+ export const subErrorsAt = ( instancePath : string [ ] , schema : JsonSchema ) =>
401
+ getErrorsAt ( instancePath , schema , path => pathStartsWith ( path , instancePath ) ) ;
0 commit comments