import type { CodeKeywordDefinition } from "../../types" ; import type { KeywordCxt } from "../../compile/validate" ; import { allSchemaProperties , usePattern } from "../code" ; import { _ , not , Name } from "../../compile/codegen" ; import { alwaysValidSchema , checkStrictMode } from "../../compile/util" ; import { evaluatedPropsToName , Type } from "../../compile/util" ; import { AnySchema } from "../../types" ; const def = { keyword : "patternProperties" , type : "object" , schemaType : "object" , code ( cxt ) { const { gen , schema , data , parentSchema , it } = cxt ; const { opts } = it ; const patterns = allSchemaProperties ( schema ) ; const alwaysValidPatterns = patterns . filter ( ( p ) => alwaysValidSchema ( it , schema [ p ] as AnySchema ) ) ; if ( patterns . length === 0 || ( alwaysValidPatterns . length === patterns . length && ( ! it . opts . unevaluated || it . props === true ) ) ) { return ; } const checkProperties = opts . strictSchema && ! opts . allowMatchingProperties && parentSchema . properties ; const valid = gen . name ( "valid" ) ; if ( it . props !== true && ! ( it . props instanceof Name ) ) { it . props = evaluatedPropsToName ( gen , it . props ) ; } const { props } = it ; validatePatternProperties ( ) ; function validatePatternProperties ( ) { for ( const pat of patterns ) { if ( checkProperties ) checkMatchingProperties ( pat ) ; if ( it . allErrors ) { validateProperties ( pat ) ; } else { gen . var ( valid , true ) ; validateProperties ( pat ) ; gen . if ( valid ) ; } } } function checkMatchingProperties ( pat ) { for ( const prop in checkProperties ) { if ( new RegExp ( pat ) . test ( prop ) ) { checkStrictMode ( it , `property ${ prop } matches pattern ${ pat } (use allowMatchingProperties)` ) ; } } } function validateProperties ( pat ) { gen . forIn ( "key" , data , ( key ) => { gen . if ( _ `${ usePattern ( cxt , pat ) }.test(${ key })` , ( ) => { const alwaysValid = alwaysValidPatterns . includes ( pat ) ; if ( ! alwaysValid ) { cxt . subschema ( { keyword : "patternProperties" , schemaProp : pat , dataProp : key , dataPropType : Type . Str , } , valid ) ; } if ( it . opts . unevaluated && props !== true ) { gen . assign ( _ `${ props }[${ key }]` , true ) ; } else if ( ! alwaysValid && ! it . allErrors ) { gen . if ( not ( valid ) , ( ) => gen . break ( ) ) ; } } ) ; } ) ; } } , } ; export default def ;