@@ -3,37 +3,87 @@ import * as Schema from "@hyperjump/browser";
33import * as Instance from "@hyperjump/json-schema/instance/experimental" ;
44
55/**
6- * @import { ErrorHandler, ErrorObject } from "../index.d.ts"
6+ * @import { ErrorHandler } from "../index.d.ts"
7+ * @import { JsonNode } from "@hyperjump/json-schema/instance/experimental"
78 */
89
910/** @type ErrorHandler */
1011const requiredErrorHandler = async ( normalizedErrors , instance , localization ) => {
11- /** @type ErrorObject[] */
12- const errors = [ ] ;
12+ /** @type {Set<string> } */
13+ const allMissingRequired = new Set ( ) ;
14+ const allSchemaLocations = [ ] ;
1315
1416 for ( const schemaLocation in normalizedErrors [ "https://json-schema.org/keyword/required" ] ) {
1517 if ( normalizedErrors [ "https://json-schema.org/keyword/required" ] [ schemaLocation ] ) {
1618 continue ;
1719 }
1820
21+ allSchemaLocations . push ( schemaLocation ) ;
1922 const keyword = await getSchema ( schemaLocation ) ;
2023 const required = /** @type string[] */ ( Schema . value ( keyword ) ) ;
2124
22- const missingRequired = [ ] ;
23- for ( const propertyName of required ) {
25+ addMissingProperties ( required , instance , allMissingRequired ) ;
26+ }
27+
28+ for ( const schemaLocation in normalizedErrors [ "https://json-schema.org/keyword/dependentRequired" ] ) {
29+ if ( normalizedErrors [ "https://json-schema.org/keyword/dependentRequired" ] [ schemaLocation ] ) {
30+ continue ;
31+ }
32+
33+ allSchemaLocations . push ( schemaLocation ) ;
34+ const keyword = await getSchema ( schemaLocation ) ;
35+
36+ for await ( const [ propertyName , dependencyNode ] of Schema . entries ( keyword ) ) {
2437 if ( ! Instance . has ( propertyName , instance ) ) {
25- missingRequired . push ( propertyName ) ;
38+ continue ;
2639 }
40+
41+ const requiredProperties = /** @type string[] */ ( Schema . value ( dependencyNode ) ) ;
42+ addMissingProperties ( requiredProperties , instance , allMissingRequired ) ;
43+ }
44+ }
45+
46+ for ( const schemaLocation in normalizedErrors [ "https://json-schema.org/keyword/draft-04/dependencies" ] ) {
47+ if ( typeof normalizedErrors [ "https://json-schema.org/keyword/draft-04/dependencies" ] [ schemaLocation ] === "boolean" ) {
48+ continue ;
2749 }
2850
29- errors . push ( {
30- message : localization . getRequiredErrorMessage ( missingRequired ) ,
31- instanceLocation : Instance . uri ( instance ) ,
32- schemaLocations : [ schemaLocation ]
33- } ) ;
51+ const keyword = await getSchema ( schemaLocation ) ;
52+
53+ let hasArrayFormDependencies = false ;
54+ for await ( const [ propertyName , dependency ] of Schema . entries ( keyword ) ) {
55+ if ( ! Instance . has ( propertyName , instance ) || Schema . typeOf ( dependency ) !== "array" ) {
56+ continue ;
57+ }
58+
59+ hasArrayFormDependencies = true ;
60+ const dependencyArray = /** @type {string[] } */ ( Schema . value ( dependency ) ) ;
61+ addMissingProperties ( dependencyArray , instance , allMissingRequired ) ;
62+ }
63+
64+ if ( hasArrayFormDependencies ) {
65+ allSchemaLocations . push ( schemaLocation ) ;
66+ }
3467 }
3568
36- return errors ;
69+ if ( allMissingRequired . size === 0 ) {
70+ return [ ] ;
71+ }
72+
73+ return [ {
74+ message : localization . getRequiredErrorMessage ( [ ...allMissingRequired ] ) ,
75+ instanceLocation : Instance . uri ( instance ) ,
76+ schemaLocations : /** @type {string[] } */ ( [ ...allSchemaLocations ] )
77+ } ] ;
78+ } ;
79+
80+ /** @type (requiredProperties: string[], instance: JsonNode, missingSet: Set<string>) => void */
81+ const addMissingProperties = ( requiredProperties , instance , missingSet ) => {
82+ for ( const propertyName of requiredProperties ) {
83+ if ( ! Instance . has ( propertyName , instance ) ) {
84+ missingSet . add ( propertyName ) ;
85+ }
86+ }
3787} ;
3888
3989export default requiredErrorHandler ;
0 commit comments