Mari's guided journal software.
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

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
}
}