import type { AnySchema } from "../../types" ; import type { SchemaObjCxt } from ".." ; import { _ , str , getProperty , Code , Name } from "../codegen" ; import { escapeFragment , getErrorPath , Type } from "../util" ; import type { JSONType } from "../rules" ; export interface SubschemaContext { schema : AnySchema ; schemaPath : Code ; errSchemaPath : string ; topSchemaRef ? : Code ; errorPath ? : Code ; dataLevel ? : number ; dataTypes ? : JSONType [ ] ; data ? : Name ; parentData ? : Name ; parentDataProperty ? : Code | number ; dataNames ? : Name [ ] ; dataPathArr ? : ( Code | number ) [ ] ; propertyName ? : Name ; jtdDiscriminator ? : string ; jtdMetadata ? : boolean ; compositeRule ? : true ; createErrors ? : boolean ; allErrors ? : boolean ; } export type SubschemaArgs = Partial < { keyword : string ; schemaProp : string | number ; schema : AnySchema ; schemaPath : Code ; errSchemaPath : string ; topSchemaRef : Code ; data : Name | Code ; dataProp : Code | string | number ; dataTypes : JSONType [ ] ; definedProperties : Set < string > ; propertyName : Name ; dataPropType : Type ; jtdDiscriminator : string ; jtdMetadata : boolean ; compositeRule : true ; createErrors : boolean ; allErrors : boolean ; } > ; export function getSubschema ( it , { keyword , schemaProp , schema , schemaPath , errSchemaPath , topSchemaRef } ) { if ( keyword !== undefined && schema !== undefined ) { throw new Error ( 'both "keyword" and "schema" passed, only one allowed' ) ; } if ( keyword !== undefined ) { const sch = it . schema [ keyword ] ; return schemaProp === undefined ? { schema : sch , schemaPath : _ `${ it . schemaPath }${ getProperty ( keyword ) }` , errSchemaPath : `${ it . errSchemaPath }/${ keyword }` , } : { schema : sch [ schemaProp ] , schemaPath : _ `${ it . schemaPath }${ getProperty ( keyword ) }${ getProperty ( schemaProp ) }` , errSchemaPath : `${ it . errSchemaPath }/${ keyword }/${ escapeFragment ( schemaProp ) }` , } ; } if ( schema !== undefined ) { if ( schemaPath === undefined || errSchemaPath === undefined || topSchemaRef === undefined ) { throw new Error ( '"schemaPath", "errSchemaPath" and "topSchemaRef" are required with "schema"' ) ; } return { schema , schemaPath , topSchemaRef , errSchemaPath , } ; } throw new Error ( 'either "keyword" or "schema" must be passed' ) ; } export function extendSubschemaData ( subschema , it , { dataProp , dataPropType : dpType , data , dataTypes , propertyName } ) { if ( data !== undefined && dataProp !== undefined ) { throw new Error ( 'both "data" and "dataProp" passed, only one allowed' ) ; } const { gen } = it ; if ( dataProp !== undefined ) { const { errorPath , dataPathArr , opts } = it ; const nextData = gen . let ( "data" , _ `${ it . data }${ getProperty ( dataProp ) }` , true ) ; dataContextProps ( nextData ) ; subschema . errorPath = str `${ errorPath }${ getErrorPath ( dataProp , dpType , opts . jsPropertySyntax ) }` ; subschema . parentDataProperty = _ `${ dataProp }` ; subschema . dataPathArr = [ ... dataPathArr , subschema . parentDataProperty ] ; } if ( data !== undefined ) { const nextData = data instanceof Name ? data : gen . let ( "data" , data , true ) ; dataContextProps ( nextData ) ; if ( propertyName !== undefined ) subschema . propertyName = propertyName ; } if ( dataTypes ) subschema . dataTypes = dataTypes ; function dataContextProps ( _nextData ) { subschema . data = _nextData ; subschema . dataLevel = it . dataLevel + 1 ; subschema . dataTypes = [ ] ; it . definedProperties = new Set < string > ( ) ; subschema . parentData = it . data ; subschema . dataNames = [ ... it . dataNames , _nextData ] ; } } export function extendSubschemaMode ( subschema , { jtdDiscriminator , jtdMetadata , compositeRule , createErrors , allErrors } ) { if ( compositeRule !== undefined ) subschema . compositeRule = compositeRule ; if ( createErrors !== undefined ) subschema . createErrors = createErrors ; if ( allErrors !== undefined ) subschema . allErrors = allErrors ; subschema . jtdDiscriminator = jtdDiscriminator ; subschema . jtdMetadata = jtdMetadata ; }