.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / table / node_modules / ajv / lib / compile / validate / subschema.ts
1 import type {AnySchema} from "../../types"
2 import type {SchemaObjCxt} from ".."
3 import {_, str, getProperty, Code, Name} from "../codegen"
4 import {escapeFragment, getErrorPath, Type} from "../util"
5 import type {JSONType} from "../rules"
6
7 export interface SubschemaContext {
8   // TODO use Optional? align with SchemCxt property types
9   schema: AnySchema
10   schemaPath: Code
11   errSchemaPath: string
12   topSchemaRef?: Code
13   errorPath?: Code
14   dataLevel?: number
15   dataTypes?: JSONType[]
16   data?: Name
17   parentData?: Name
18   parentDataProperty?: Code | number
19   dataNames?: Name[]
20   dataPathArr?: (Code | number)[]
21   propertyName?: Name
22   jtdDiscriminator?: string
23   jtdMetadata?: boolean
24   compositeRule?: true
25   createErrors?: boolean
26   allErrors?: boolean
27 }
28
29 export type SubschemaArgs = Partial<{
30   keyword: string
31   schemaProp: string | number
32   schema: AnySchema
33   schemaPath: Code
34   errSchemaPath: string
35   topSchemaRef: Code
36   data: Name | Code
37   dataProp: Code | string | number
38   dataTypes: JSONType[]
39   definedProperties: Set<string>
40   propertyName: Name
41   dataPropType: Type
42   jtdDiscriminator: string
43   jtdMetadata: boolean
44   compositeRule: true
45   createErrors: boolean
46   allErrors: boolean
47 }>
48
49 export function getSubschema(
50   it: SchemaObjCxt,
51   {keyword, schemaProp, schema, schemaPath, errSchemaPath, topSchemaRef}: SubschemaArgs
52 ): SubschemaContext {
53   if (keyword !== undefined && schema !== undefined) {
54     throw new Error('both "keyword" and "schema" passed, only one allowed')
55   }
56
57   if (keyword !== undefined) {
58     const sch = it.schema[keyword]
59     return schemaProp === undefined
60       ? {
61           schema: sch,
62           schemaPath: _`${it.schemaPath}${getProperty(keyword)}`,
63           errSchemaPath: `${it.errSchemaPath}/${keyword}`,
64         }
65       : {
66           schema: sch[schemaProp],
67           schemaPath: _`${it.schemaPath}${getProperty(keyword)}${getProperty(schemaProp)}`,
68           errSchemaPath: `${it.errSchemaPath}/${keyword}/${escapeFragment(schemaProp)}`,
69         }
70   }
71
72   if (schema !== undefined) {
73     if (schemaPath === undefined || errSchemaPath === undefined || topSchemaRef === undefined) {
74       throw new Error('"schemaPath", "errSchemaPath" and "topSchemaRef" are required with "schema"')
75     }
76     return {
77       schema,
78       schemaPath,
79       topSchemaRef,
80       errSchemaPath,
81     }
82   }
83
84   throw new Error('either "keyword" or "schema" must be passed')
85 }
86
87 export function extendSubschemaData(
88   subschema: SubschemaContext,
89   it: SchemaObjCxt,
90   {dataProp, dataPropType: dpType, data, dataTypes, propertyName}: SubschemaArgs
91 ): void {
92   if (data !== undefined && dataProp !== undefined) {
93     throw new Error('both "data" and "dataProp" passed, only one allowed')
94   }
95
96   const {gen} = it
97
98   if (dataProp !== undefined) {
99     const {errorPath, dataPathArr, opts} = it
100     const nextData = gen.let("data", _`${it.data}${getProperty(dataProp)}`, true)
101     dataContextProps(nextData)
102     subschema.errorPath = str`${errorPath}${getErrorPath(dataProp, dpType, opts.jsPropertySyntax)}`
103     subschema.parentDataProperty = _`${dataProp}`
104     subschema.dataPathArr = [...dataPathArr, subschema.parentDataProperty]
105   }
106
107   if (data !== undefined) {
108     const nextData = data instanceof Name ? data : gen.let("data", data, true) // replaceable if used once?
109     dataContextProps(nextData)
110     if (propertyName !== undefined) subschema.propertyName = propertyName
111     // TODO something is possibly wrong here with not changing parentDataProperty and not appending dataPathArr
112   }
113
114   if (dataTypes) subschema.dataTypes = dataTypes
115
116   function dataContextProps(_nextData: Name): void {
117     subschema.data = _nextData
118     subschema.dataLevel = it.dataLevel + 1
119     subschema.dataTypes = []
120     it.definedProperties = new Set<string>()
121     subschema.parentData = it.data
122     subschema.dataNames = [...it.dataNames, _nextData]
123   }
124 }
125
126 export function extendSubschemaMode(
127   subschema: SubschemaContext,
128   {jtdDiscriminator, jtdMetadata, compositeRule, createErrors, allErrors}: SubschemaArgs
129 ): void {
130   if (compositeRule !== undefined) subschema.compositeRule = compositeRule
131   if (createErrors !== undefined) subschema.createErrors = createErrors
132   if (allErrors !== undefined) subschema.allErrors = allErrors
133   subschema.jtdDiscriminator = jtdDiscriminator // not inherited
134   subschema.jtdMetadata = jtdMetadata // not inherited
135 }