| 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: SchemaObjCxt,
|
| {keyword, schemaProp, schema, schemaPath, errSchemaPath, topSchemaRef}: SubschemaArgs
|
| ): SubschemaContext {
|
| 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: SubschemaContext,
|
| it: SchemaObjCxt,
|
| {dataProp, dataPropType: dpType, data, dataTypes, propertyName}: SubschemaArgs
|
| ): void {
|
| 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: Name): void {
|
| 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: SubschemaContext,
|
| {jtdDiscriminator, jtdMetadata, compositeRule, createErrors, allErrors}: SubschemaArgs
|
| ): void {
|
| if (compositeRule !== undefined) subschema.compositeRule = compositeRule
|
| if (createErrors !== undefined) subschema.createErrors = createErrors
|
| if (allErrors !== undefined) subschema.allErrors = allErrors
|
| subschema.jtdDiscriminator = jtdDiscriminator
|
| subschema.jtdMetadata = jtdMetadata
|
| }
|
|
|