UNPKG

@sinclair/typebox

Version:

Json Schema Type Builder with Static Type Resolution for TypeScript

74 lines (73 loc) 2.75 kB
import { SetUnionMany, SetIntersectMany } from '../sets/index.mjs'; // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsIntersect, IsUnion, IsTuple, IsArray, IsObject, IsRecord } from '../guard/kind.mjs'; // prettier-ignore function FromRest(types) { const result = []; for (const L of types) result.push(KeyOfPropertyKeys(L)); return result; } // prettier-ignore function FromIntersect(types) { const propertyKeysArray = FromRest(types); const propertyKeys = SetUnionMany(propertyKeysArray); return propertyKeys; } // prettier-ignore function FromUnion(types) { const propertyKeysArray = FromRest(types); const propertyKeys = SetIntersectMany(propertyKeysArray); return propertyKeys; } // prettier-ignore function FromTuple(types) { return types.map((_, indexer) => indexer.toString()); } // prettier-ignore function FromArray(_) { return (['[number]']); } // prettier-ignore function FromProperties(T) { return (globalThis.Object.getOwnPropertyNames(T)); } // ------------------------------------------------------------------ // FromPatternProperties // ------------------------------------------------------------------ // prettier-ignore function FromPatternProperties(patternProperties) { if (!includePatternProperties) return []; const patternPropertyKeys = globalThis.Object.getOwnPropertyNames(patternProperties); return patternPropertyKeys.map(key => { return (key[0] === '^' && key[key.length - 1] === '$') ? key.slice(1, key.length - 1) : key; }); } /** Returns a tuple of PropertyKeys derived from the given TSchema. */ // prettier-ignore export function KeyOfPropertyKeys(type) { return (IsIntersect(type) ? FromIntersect(type.allOf) : IsUnion(type) ? FromUnion(type.anyOf) : IsTuple(type) ? FromTuple(type.items ?? []) : IsArray(type) ? FromArray(type.items) : IsObject(type) ? FromProperties(type.properties) : IsRecord(type) ? FromPatternProperties(type.patternProperties) : []); } // ---------------------------------------------------------------- // KeyOfPattern // ---------------------------------------------------------------- let includePatternProperties = false; /** Returns a regular expression pattern derived from the given TSchema */ export function KeyOfPattern(schema) { includePatternProperties = true; const keys = KeyOfPropertyKeys(schema); includePatternProperties = false; const pattern = keys.map((key) => `(${key})`); return `^(${pattern.join('|')})$`; }