UNPKG

typia

Version:

Superfast runtime validators with only one line

132 lines (123 loc) 4.44 kB
import { Metadata } from "../../../schemas/metadata/Metadata"; import { MetadataArrayType } from "../../../schemas/metadata/MetadataArrayType"; import { MetadataObject } from "../../../schemas/metadata/MetadataObject"; import { MetadataTupleType } from "../../../schemas/metadata/MetadataTupleType"; import { MetadataCollection } from "../../MetadataCollection"; import { MetadataFactory } from "../../MetadataFactory"; import { iterate_metadata_comment_tags } from "./iterate_metadata_comment_tags"; export const iterate_metadata_collection = (errors: MetadataFactory.IError[]) => (collection: MetadataCollection): void => { for (const array of collection.arrays()) if (array.recursive === null) collection.setArrayRecursive( array, isArrayRecursive(new Set())(array)(array.value), ); for (const tuple of collection.tuples()) if (tuple.recursive === null) { const visited: Set<Metadata> = new Set(); collection.setTupleRecursive( tuple, tuple.elements.some(isTupleRecursive(visited)(tuple)), ); } for (const obj of collection.objects()) { iterate_metadata_comment_tags(errors)(obj); if (obj.recursive === null) { const visited: Set<Metadata> = new Set(); collection.setObjectRecursive( obj, obj.properties.some((p) => isObjectRecursive(visited)(obj)(p.value)), ); } } }; const isArrayRecursive = (visited: Set<Metadata>) => (array: MetadataArrayType) => (meta: Metadata): boolean => { if (visited.has(meta)) return false; visited.add(meta); return ( meta.arrays.some( (a) => a.type === array || isArrayRecursive(visited)(array)(a.type.value), ) || meta.aliases.some((alias) => isArrayRecursive(visited)(array)(alias.value), ) || meta.tuples.some( (t) => !t.type.recursive && t.type.elements.some((e) => isArrayRecursive(visited)(array)(e)), ) || meta.maps.some((m) => isArrayRecursive(visited)(array)(m.value)) || meta.sets.some((s) => isArrayRecursive(visited)(array)(s)) || (meta.escaped !== null && isArrayRecursive(visited)(array)(meta.escaped.returns)) || (meta.rest !== null && isArrayRecursive(visited)(array)(meta.rest)) ); }; const isTupleRecursive = (visited: Set<Metadata>) => (tuple: MetadataTupleType) => (meta: Metadata): boolean => { if (visited.has(meta)) return false; visited.add(meta); return ( meta.tuples.some( (t) => t.type === tuple || t.type.elements.some((e) => isTupleRecursive(visited)(tuple)(e)), ) || meta.arrays.some( (a) => !a.type.recursive && isTupleRecursive(visited)(tuple)(a.type.value), ) || meta.maps.some((m) => isTupleRecursive(visited)(tuple)(m.value)) || meta.sets.some((s) => isTupleRecursive(visited)(tuple)(s)) || meta.aliases.some((alias) => isTupleRecursive(visited)(tuple)(alias.value), ) || (meta.escaped !== null && isTupleRecursive(visited)(tuple)(meta.escaped.returns)) || (meta.rest !== null && isTupleRecursive(visited)(tuple)(meta.rest)) ); }; const isObjectRecursive = (visited: Set<Metadata>) => (obj: MetadataObject) => (meta: Metadata): boolean => { if (visited.has(meta)) return false; visited.add(meta); return ( meta.objects.some( (o) => obj === o || o.properties.some((prop) => isObjectRecursive(visited)(obj)(prop.value), ), ) || meta.aliases.some((alias) => isObjectRecursive(visited)(obj)(alias.value), ) || meta.arrays.some( (array) => !array.type.recursive && isObjectRecursive(visited)(obj)(array.type.value), ) || meta.tuples.some( (tuple) => !tuple.type.recursive && tuple.type.elements.some((elem) => isObjectRecursive(visited)(obj)(elem), ), ) || meta.maps.some((map) => isObjectRecursive(visited)(obj)(map.value)) || meta.sets.some((value) => isObjectRecursive(visited)(obj)(value)) || (meta.escaped !== null && isObjectRecursive(visited)(obj)(meta.escaped.returns)) || (meta.rest !== null && isObjectRecursive(visited)(obj)(meta.rest)) ); };