|
|
|
@ -3,7 +3,18 @@ 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>> = { |
|
|
|
|
interface BaseSchemaData<RepresentedT, ReferenceT extends string> { |
|
|
|
|
value?: RepresentedT, |
|
|
|
|
schema: unknown, |
|
|
|
|
key: ReferenceT, |
|
|
|
|
definition: { [key in ReferenceT]: unknown } |
|
|
|
|
referenced?: { [key in ReferenceT]: RepresentedT } |
|
|
|
|
reference: { "ref": ReferenceT }, |
|
|
|
|
validate: ValidateFunction<RepresentedT> |
|
|
|
|
requiredReferences: AnyReferenceList |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export interface SchemaData<RepresentedT, ReferenceT extends string, ReferencesT extends AnyReferenceList, DefinitionsT extends ReferencedTypes<ReferencesT>> extends BaseSchemaData<RepresentedT, ReferenceT> { |
|
|
|
|
value?: RepresentedT, |
|
|
|
|
schema: JTDSchemaType<RepresentedT, DefinitionsT>, |
|
|
|
|
key: ReferenceT, |
|
|
|
@ -14,35 +25,38 @@ export type SchemaData<RepresentedT, ReferenceT extends string, ReferencesT exte |
|
|
|
|
requiredReferences: ReferencesT |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export type UntypedReferenceList = SchemaData<any, any, any, any>[] |
|
|
|
|
export type AnySchemaData = BaseSchemaData<unknown, string> |
|
|
|
|
export type AnySchemaDataFor<RepresentedT> = BaseSchemaData<RepresentedT, string> |
|
|
|
|
export type AnyReferenceList = AnySchemaData[] |
|
|
|
|
export type AnyDefinitions = Record<string, unknown> |
|
|
|
|
|
|
|
|
|
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 Schema<DataT extends AnySchemaData> = Exclude<DataT["schema"], undefined> |
|
|
|
|
export type Value<DataT extends AnySchemaData> = Exclude<DataT["value"], undefined> |
|
|
|
|
export type Definition<DataT extends AnySchemaData> = Exclude<DataT["definition"], undefined> |
|
|
|
|
export type Reference<DataT extends AnySchemaData> = Exclude<DataT["reference"], undefined> |
|
|
|
|
export type ReferenceKey<DataT extends AnySchemaData> = Exclude<DataT["key"], undefined> |
|
|
|
|
export type Referenced<DataT extends AnySchemaData> = 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 ReferencedSchemaMap<ReferencesT extends AnyReferenceList> = { |
|
|
|
|
[Property in keyof ReferencesT as ReferencesT[Property] extends AnySchemaData ? ReferenceKey<ReferencesT[Property]> : never]: ReferencesT[Property] extends AnySchemaData ? ReferencesT[Property] : never |
|
|
|
|
} |
|
|
|
|
export type ReferencedSchema<ReferencesT extends UntypedReferenceList> = ReferencedSchemaMap<ReferencesT>[keyof ReferencedSchemaMap<ReferencesT>] |
|
|
|
|
export type ReferencedDefinitions<ReferencesT extends UntypedReferenceList> = { |
|
|
|
|
export type ReferencedSchema<ReferencesT extends AnyReferenceList> = ReferencedSchemaMap<ReferencesT>[keyof ReferencedSchemaMap<ReferencesT>] |
|
|
|
|
export type ReferencedDefinitions<ReferencesT extends AnyReferenceList> = { |
|
|
|
|
[Property in keyof ReferencedSchemaMap<ReferencesT>]?: Definition<ReferencedSchemaMap<ReferencesT>[Property]> |
|
|
|
|
} |
|
|
|
|
export type ReferencedTypes<ReferencesT extends UntypedReferenceList> = { |
|
|
|
|
export type ReferencedTypes<ReferencesT extends AnyReferenceList> = { |
|
|
|
|
[Property in keyof ReferencedSchemaMap<ReferencesT>]?: Value<ReferencedSchemaMap<ReferencesT>[Property]> |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export function schema< |
|
|
|
|
RepresentedT, |
|
|
|
|
KeyT extends string, |
|
|
|
|
ReferencesT extends SchemaData<any, any, any, ReferencedTypes<ReferencesT>>[], |
|
|
|
|
ReferencesT extends AnySchemaData[], |
|
|
|
|
>({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 }) |
|
|
|
|
const definitions = references.reduce<AnyDefinitions>((definitions, reference) => ({...reference.definition, ...definitions}), definition) |
|
|
|
|
const validate = ajv.compile<RepresentedT>({ ...reference, definitions }) |
|
|
|
|
return { |
|
|
|
|
schema, |
|
|
|
|
key, |
|
|
|
|