You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
3.0 KiB
54 lines
3.0 KiB
|
|
import AJV, {ValidateFunction, JTDSchemaType} from "ajv/dist/jtd";
|
|
|
|
const ajv = new AJV();
|
|
|
|
export type SchemaData<RepresentedT, ReferenceT extends string, ReferencesT extends UntypedReferenceList, DefinitionsT extends ReferencedTypes<ReferencesT>> = {
|
|
value?: RepresentedT,
|
|
schema: JTDSchemaType<RepresentedT, DefinitionsT>,
|
|
key: ReferenceT,
|
|
definition: { [key in ReferenceT]: JTDSchemaType<RepresentedT, DefinitionsT> }
|
|
referenced?: { [key in ReferenceT]: RepresentedT }
|
|
reference: { "ref": ReferenceT },
|
|
validate: ValidateFunction<RepresentedT>
|
|
requiredReferences: ReferencesT
|
|
}
|
|
|
|
export type UntypedReferenceList = SchemaData<any, any, any, any>[]
|
|
|
|
export type Schema<DataT extends SchemaData<any, any, any, any>> = Exclude<DataT["schema"], undefined>
|
|
export type Value<DataT extends SchemaData<any, any, any, any>> = Exclude<DataT["value"], undefined>
|
|
export type Definition<DataT extends SchemaData<any, any, any, any>> = Exclude<DataT["definition"], undefined>
|
|
export type Reference<DataT extends SchemaData<any, any, any, any>> = Exclude<DataT["reference"], undefined>
|
|
export type ReferenceKey<DataT extends SchemaData<any, any, any, any>> = Exclude<DataT["key"], undefined>
|
|
export type Referenced<DataT extends SchemaData<any, any, any, any>> = Exclude<DataT["referenced"], undefined>
|
|
|
|
export type ReferencedSchemaMap<ReferencesT extends UntypedReferenceList> = {
|
|
[Property in keyof ReferencesT as ReferencesT[Property] extends SchemaData<any, any, any, any> ? ReferenceKey<ReferencesT[Property]> : never]: ReferencesT[Property] extends SchemaData<any, any, any, any> ? ReferencesT[Property] : never
|
|
}
|
|
export type ReferencedSchema<ReferencesT extends UntypedReferenceList> = ReferencedSchemaMap<ReferencesT>[keyof ReferencedSchemaMap<ReferencesT>]
|
|
export type ReferencedDefinitions<ReferencesT extends UntypedReferenceList> = {
|
|
[Property in keyof ReferencedSchemaMap<ReferencesT>]?: Definition<ReferencedSchemaMap<ReferencesT>[Property]>
|
|
}
|
|
export type ReferencedTypes<ReferencesT extends UntypedReferenceList> = {
|
|
[Property in keyof ReferencedSchemaMap<ReferencesT>]?: Value<ReferencedSchemaMap<ReferencesT>[Property]>
|
|
}
|
|
|
|
export function schema<
|
|
RepresentedT,
|
|
KeyT extends string,
|
|
ReferencesT extends SchemaData<any, any, any, ReferencedTypes<ReferencesT>>[],
|
|
>({schema, key, references}: { schema: JTDSchemaType<RepresentedT, ReferencedTypes<ReferencesT>>, key: KeyT, references: ReferencesT, typeHint?: RepresentedT|null }): SchemaData<RepresentedT, KeyT, ReferencesT, ReferencedTypes<ReferencesT>> {
|
|
const definition = {[key]: schema} as Definition<SchemaData<RepresentedT, KeyT, ReferencesT, ReferencedTypes<ReferencesT>>>
|
|
const reference = {ref: key}
|
|
const definitions = references.reduce((definitions, reference) => ({...reference.definition, ...definitions}), {} as ReferencedDefinitions<ReferencesT>)
|
|
const validate = ajv.compile<RepresentedT>({ ...schema, definitions })
|
|
return {
|
|
schema,
|
|
key,
|
|
definition,
|
|
reference,
|
|
validate,
|
|
requiredReferences: references
|
|
}
|
|
} |