@@ -4,7 +4,7 @@ import * as Instance from "@hyperjump/json-schema/instance/experimental";
44import jsonStringify from "json-stringify-deterministic" ;
55
66/**
7- * @import { ErrorHandler, ErrorObject, Json } from "../index.d.ts"
7+ * @import { ErrorHandler, Json } from "../index.d.ts"
88 */
99
1010/**
@@ -16,83 +16,63 @@ import jsonStringify from "json-stringify-deterministic";
1616
1717/** @type {ErrorHandler } */
1818const constAndEnumErrorHandler = async ( normalizedErrors , instance , localization ) => {
19- /** @type { ErrorObject[] } */
20- const errors = [ ] ;
19+ /** @type Set<string> | undefined */
20+ let allowedJson ;
2121
22- /** @type {Constraint[] } */
23- const constraints = [ ] ;
24- let hasFailure = false ;
22+ /** @type string[]> */
23+ const constSchemaLocations = [ ] ;
24+
25+ /** @type string[]> */
26+ const enumSchemaLocations = [ ] ;
27+
28+ /** @type string[]> */
29+ const allSchemaLocations = [ ] ;
2530
2631 for ( const schemaLocation in normalizedErrors [ "https://json-schema.org/keyword/const" ] ) {
27- const passed = normalizedErrors [ "https://json-schema.org/keyword/const" ] [ schemaLocation ] === true ;
28- if ( ! passed ) {
29- hasFailure = true ;
32+ if ( ! normalizedErrors [ "https://json-schema.org/keyword/const" ] [ schemaLocation ] ) {
33+ constSchemaLocations . push ( schemaLocation ) ;
3034 }
35+ allSchemaLocations . push ( schemaLocation ) ;
36+
3137 const keyword = await getSchema ( schemaLocation ) ;
32- constraints . push ( {
33- allowedValues : [ Schema . value ( keyword ) ] ,
34- schemaLocation
35- } ) ;
38+ const keywordJson = new Set ( [ jsonStringify ( /** @type Json */ ( Schema . value ( keyword ) ) ) ] ) ;
39+
40+ allowedJson = allowedJson ?. intersection ( keywordJson ) ?? keywordJson ;
3641 }
3742
3843 for ( const schemaLocation in normalizedErrors [ "https://json-schema.org/keyword/enum" ] ) {
39- const passed = normalizedErrors [ "https://json-schema.org/keyword/enum" ] [ schemaLocation ] === true ;
40- if ( ! passed ) {
41- hasFailure = true ;
44+ if ( ! normalizedErrors [ "https://json-schema.org/keyword/enum" ] [ schemaLocation ] ) {
45+ enumSchemaLocations . push ( schemaLocation ) ;
4246 }
47+ allSchemaLocations . push ( schemaLocation ) ;
48+
4349 const keyword = await getSchema ( schemaLocation ) ;
44- constraints . push ( {
45- allowedValues : Schema . value ( keyword ) ,
46- schemaLocation
47- } ) ;
48- }
50+ const keywordJson = new Set ( /** @type Json[] */ ( Schema . value ( keyword ) ) . map ( ( value ) => jsonStringify ( value ) ) ) ;
4951
50- if ( ! hasFailure || constraints . length === 0 ) {
51- return errors ;
52+ allowedJson = allowedJson ?. intersection ( keywordJson ) ?? keywordJson ;
5253 }
5354
54- let intersectionKeys = new Set ( constraints [ 0 ] . allowedValues . map ( toKey ) ) ;
55- for ( let i = 1 ; i < constraints . length ; i ++ ) {
56- intersectionKeys = intersectionKeys . intersection ( new Set ( constraints [ i ] . allowedValues . map ( toKey ) ) ) ;
55+ if ( constSchemaLocations . length === 0 && enumSchemaLocations . length === 0 ) {
56+ return [ ] ;
5757 }
5858
59- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
60- const intersection = /** @type {Json[] } */ ( [ ...intersectionKeys ] . map ( ( k ) => JSON . parse ( k ) ) ) ;
61-
62- const instanceLocation = Instance . uri ( instance ) ;
63- const intersectionKeysArray = [ ...intersectionKeys ] ;
64- const exactMatch = constraints . find ( ( c ) => {
65- if ( c . allowedValues . length !== intersection . length ) return false ;
66- const constraintKeys = new Set ( c . allowedValues . map ( toKey ) ) ;
67- return intersectionKeysArray . every ( ( k ) => constraintKeys . has ( k ) ) ;
68- } ) ;
69-
70- if ( intersection . length === 0 ) {
71- errors . push ( {
59+ if ( allowedJson ?. size === 0 ) {
60+ return [ {
7261 message : localization . getBooleanSchemaErrorMessage ( ) ,
73- instanceLocation,
74- schemaLocations : constraints . map ( ( c ) => c . schemaLocation )
75- } ) ;
76- } else if ( intersection . length === 1 ) {
77- errors . push ( {
78- message : localization . getConstErrorMessage ( intersection [ 0 ] ) ,
79- instanceLocation,
80- schemaLocations : exactMatch ? [ exactMatch . schemaLocation ] : constraints . map ( ( c ) => c . schemaLocation )
81- } ) ;
62+ instanceLocation : Instance . uri ( instance ) ,
63+ schemaLocations : allSchemaLocations
64+ } ] ;
8265 } else {
83- errors . push ( {
84- message : localization . getEnumErrorMessage ( intersection ) ,
85- instanceLocation,
86- schemaLocations : exactMatch ? [ exactMatch . schemaLocation ] : constraints . map ( ( c ) => c . schemaLocation )
87- } ) ;
66+ /** @type Json[] */
67+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
68+ const allowedValues = [ ...allowedJson ?? [ ] ] . map ( ( json ) => JSON . parse ( json ) ) ;
69+
70+ return [ {
71+ message : localization . getEnumErrorMessage ( allowedValues ) ,
72+ instanceLocation : Instance . uri ( instance ) ,
73+ schemaLocations : constSchemaLocations . length ? constSchemaLocations : enumSchemaLocations
74+ } ] ;
8875 }
89- return errors ;
9076} ;
9177
92- /**
93- * @param {Json } val
94- * @returns {string }
95- */
96- const toKey = ( val ) => jsonStringify ( val ) ;
97-
9878export default constAndEnumErrorHandler ;
0 commit comments