Spaces:
Runtime error
Runtime error
File size: 4,366 Bytes
23ac194 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | 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 {
// TODO use Optional? align with SchemCxt property types
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) // replaceable if used once?
dataContextProps(nextData)
if (propertyName !== undefined) subschema.propertyName = propertyName
// TODO something is possibly wrong here with not changing parentDataProperty and not appending dataPathArr
}
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 // not inherited
subschema.jtdMetadata = jtdMetadata // not inherited
}
|