diff --git a/src/errors/errors.ts b/src/errors/errors.ts index 8bf7302b3..20198717e 100644 --- a/src/errors/errors.ts +++ b/src/errors/errors.ts @@ -26,11 +26,46 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -import { IsArray, IsUint8Array, IsDate, IsPromise, IsFunction, IsAsyncIterator, IsIterator, IsBoolean, IsNumber, IsBigInt, IsString, IsSymbol, IsInteger, IsNull, IsUndefined } from '../value/guard/guard' -import { TypeSystemPolicy, TypeSystemErrorFunction } from '../system/system' -import { Deref } from '../value/deref/deref' -import { Hash } from '../value/hash/hash' -import * as Types from '../type/index' +import { IsArray, IsUint8Array, IsDate, IsPromise, IsFunction, IsAsyncIterator, IsIterator, IsBoolean, IsNumber, IsBigInt, IsString, IsSymbol, IsInteger, IsNull, IsUndefined } from '../value/guard/index' +import { TypeSystemPolicy, TypeSystemErrorFunction } from '../system/index' +import { KeyOfStringResolvePattern } from '../type/keyof/index' +import { TypeRegistry, FormatRegistry } from '../type/registry/index' +import { ExtendsUndefinedCheck } from '../type/extends/extends-undefined' +import { Deref } from '../value/deref/index' +import { Hash } from '../value/hash/index' +import { Kind } from '../type/symbols/index' + +import type { TSchema } from '../type/schema/index' +import type { TAsyncIterator } from '../type/async-iterator/index' +import type { TAny } from '../type/any/index' +import type { TArray } from '../type/array/index' +import type { TBigInt } from '../type/bigint/index' +import type { TBoolean } from '../type/boolean/index' +import type { TDate } from '../type/date/index' +import type { TConstructor } from '../type/constructor/index' +import type { TFunction } from '../type/function/index' +import type { TInteger } from '../type/integer/index' +import type { TIntersect } from '../type/intersect/index' +import type { TIterator } from '../type/iterator/index' +import type { TLiteral } from '../type/literal/index' +import { Never, type TNever } from '../type/never/index' +import type { TNot } from '../type/not/index' +import type { TNull } from '../type/null/index' +import type { TNumber } from '../type/number/index' +import type { TObject } from '../type/object/index' +import type { TPromise } from '../type/promise/index' +import type { TRecord } from '../type/record/index' +import type { TRef } from '../type/ref/index' +import type { TTemplateLiteral } from '../type/template-literal/index' +import type { TThis } from '../type/recursive/index' +import type { TTuple } from '../type/tuple/index' +import type { TUnion } from '../type/union/index' +import type { TUnknown } from '../type/unknown/index' +import type { TString } from '../type/string/index' +import type { TSymbol } from '../type/symbol/index' +import type { TUndefined } from '../type/undefined/index' +import type { TUint8Array } from '../type/uint8array/index' +import type { TVoid } from '../type/void/index' // -------------------------------------------------------------------------- // ValueErrorType @@ -105,7 +140,7 @@ export enum ValueErrorType { // -------------------------------------------------------------------------- export interface ValueError { type: ValueErrorType - schema: Types.TSchema + schema: TSchema path: string value: unknown message: string @@ -114,7 +149,7 @@ export interface ValueError { // ValueErrors // -------------------------------------------------------------------------- export class ValueErrorsUnknownTypeError extends Error { - constructor(public readonly schema: Types.TSchema) { + constructor(public readonly schema: TSchema) { super('Unknown type') } } @@ -147,14 +182,14 @@ export class ValueErrorIterator { // -------------------------------------------------------------------------- // Create // -------------------------------------------------------------------------- -function Create(type: ValueErrorType, schema: Types.TSchema, path: string, value: unknown): ValueError { +function Create(type: ValueErrorType, schema: TSchema, path: string, value: unknown): ValueError { return { type, schema, path, value, message: TypeSystemErrorFunction.Get()(schema, type) } } // -------------------------------------------------------------------------- // Types // -------------------------------------------------------------------------- -function* TAny(schema: Types.TAny, references: Types.TSchema[], path: string, value: any): IterableIterator {} -function* TArray(schema: Types.TArray, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TAny(schema: TAny, references: TSchema[], path: string, value: any): IterableIterator {} +function* TArray(schema: TArray, references: TSchema[], path: string, value: any): IterableIterator { if (!IsArray(value)) { return yield Create(ValueErrorType.Array, schema, path, value) } @@ -175,7 +210,7 @@ function* TArray(schema: Types.TArray, references: Types.TSchema[], path: string if (!(IsDefined(schema.contains) || IsDefined(schema.minContains) || IsDefined(schema.maxContains))) { return } - const containsSchema = IsDefined(schema.contains) ? schema.contains : Types.Type.Never() + const containsSchema = IsDefined(schema.contains) ? schema.contains : Never() const containsCount = value.reduce((acc: number, value, index) => (Visit(containsSchema, references, `${path}${index}`, value).next().done === true ? acc + 1 : acc), 0) if (containsCount === 0) { yield Create(ValueErrorType.ArrayContains, schema, path, value) @@ -187,10 +222,10 @@ function* TArray(schema: Types.TArray, references: Types.TSchema[], path: string yield Create(ValueErrorType.ArrayMaxContains, schema, path, value) } } -function* TAsyncIterator(schema: Types.TAsyncIterator, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TAsyncIterator(schema: TAsyncIterator, references: TSchema[], path: string, value: any): IterableIterator { if (!IsAsyncIterator(value)) yield Create(ValueErrorType.AsyncIterator, schema, path, value) } -function* TBigInt(schema: Types.TBigInt, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TBigInt(schema: TBigInt, references: TSchema[], path: string, value: any): IterableIterator { if (!IsBigInt(value)) return yield Create(ValueErrorType.BigInt, schema, path, value) if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { yield Create(ValueErrorType.BigIntExclusiveMaximum, schema, path, value) @@ -208,13 +243,13 @@ function* TBigInt(schema: Types.TBigInt, references: Types.TSchema[], path: stri yield Create(ValueErrorType.BigIntMultipleOf, schema, path, value) } } -function* TBoolean(schema: Types.TBoolean, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TBoolean(schema: TBoolean, references: TSchema[], path: string, value: any): IterableIterator { if (!IsBoolean(value)) yield Create(ValueErrorType.Boolean, schema, path, value) } -function* TConstructor(schema: Types.TConstructor, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TConstructor(schema: TConstructor, references: TSchema[], path: string, value: any): IterableIterator { yield* Visit(schema.returns, references, path, value.prototype) } -function* TDate(schema: Types.TDate, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TDate(schema: TDate, references: TSchema[], path: string, value: any): IterableIterator { if (!IsDate(value)) return yield Create(ValueErrorType.Date, schema, path, value) if (IsDefined(schema.exclusiveMaximumTimestamp) && !(value.getTime() < schema.exclusiveMaximumTimestamp)) { yield Create(ValueErrorType.DateExclusiveMaximumTimestamp, schema, path, value) @@ -232,10 +267,10 @@ function* TDate(schema: Types.TDate, references: Types.TSchema[], path: string, yield Create(ValueErrorType.DateMultipleOfTimestamp, schema, path, value) } } -function* TFunction(schema: Types.TFunction, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TFunction(schema: TFunction, references: TSchema[], path: string, value: any): IterableIterator { if (!IsFunction(value)) yield Create(ValueErrorType.Function, schema, path, value) } -function* TInteger(schema: Types.TInteger, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TInteger(schema: TInteger, references: TSchema[], path: string, value: any): IterableIterator { if (!IsInteger(value)) return yield Create(ValueErrorType.Integer, schema, path, value) if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { yield Create(ValueErrorType.IntegerExclusiveMaximum, schema, path, value) @@ -253,7 +288,7 @@ function* TInteger(schema: Types.TInteger, references: Types.TSchema[], path: st yield Create(ValueErrorType.IntegerMultipleOf, schema, path, value) } } -function* TIntersect(schema: Types.TIntersect, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TIntersect(schema: TIntersect, references: TSchema[], path: string, value: any): IterableIterator { for (const inner of schema.allOf) { const next = Visit(inner, references, path, value).next() if (!next.done) { @@ -262,7 +297,7 @@ function* TIntersect(schema: Types.TIntersect, references: Types.TSchema[], path } } if (schema.unevaluatedProperties === false) { - const keyCheck = new RegExp(Types.KeyOfStringResolvePattern(schema)) + const keyCheck = new RegExp(KeyOfStringResolvePattern(schema)) for (const valueKey of Object.getOwnPropertyNames(value)) { if (!keyCheck.test(valueKey)) { yield Create(ValueErrorType.IntersectUnevaluatedProperties, schema, `${path}/${valueKey}`, value) @@ -270,7 +305,7 @@ function* TIntersect(schema: Types.TIntersect, references: Types.TSchema[], path } } if (typeof schema.unevaluatedProperties === 'object') { - const keyCheck = new RegExp(Types.KeyOfStringResolvePattern(schema)) + const keyCheck = new RegExp(KeyOfStringResolvePattern(schema)) for (const valueKey of Object.getOwnPropertyNames(value)) { if (!keyCheck.test(valueKey)) { const next = Visit(schema.unevaluatedProperties, references, `${path}/${valueKey}`, value[valueKey]).next() @@ -279,22 +314,22 @@ function* TIntersect(schema: Types.TIntersect, references: Types.TSchema[], path } } } -function* TIterator(schema: Types.TIterator, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TIterator(schema: TIterator, references: TSchema[], path: string, value: any): IterableIterator { if (!IsIterator(value)) yield Create(ValueErrorType.Iterator, schema, path, value) } -function* TLiteral(schema: Types.TLiteral, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TLiteral(schema: TLiteral, references: TSchema[], path: string, value: any): IterableIterator { if (!(value === schema.const)) yield Create(ValueErrorType.Literal, schema, path, value) } -function* TNever(schema: Types.TNever, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TNever(schema: TNever, references: TSchema[], path: string, value: any): IterableIterator { yield Create(ValueErrorType.Never, schema, path, value) } -function* TNot(schema: Types.TNot, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TNot(schema: TNot, references: TSchema[], path: string, value: any): IterableIterator { if (Visit(schema.not, references, path, value).next().done === true) yield Create(ValueErrorType.Not, schema, path, value) } -function* TNull(schema: Types.TNull, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TNull(schema: TNull, references: TSchema[], path: string, value: any): IterableIterator { if (!IsNull(value)) yield Create(ValueErrorType.Null, schema, path, value) } -function* TNumber(schema: Types.TNumber, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TNumber(schema: TNumber, references: TSchema[], path: string, value: any): IterableIterator { if (!TypeSystemPolicy.IsNumberLike(value)) return yield Create(ValueErrorType.Number, schema, path, value) if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { yield Create(ValueErrorType.NumberExclusiveMaximum, schema, path, value) @@ -312,7 +347,7 @@ function* TNumber(schema: Types.TNumber, references: Types.TSchema[], path: stri yield Create(ValueErrorType.NumberMultipleOf, schema, path, value) } } -function* TObject(schema: Types.TObject, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TObject(schema: TObject, references: TSchema[], path: string, value: any): IterableIterator { if (!TypeSystemPolicy.IsObjectLike(value)) return yield Create(ValueErrorType.Object, schema, path, value) if (IsDefined(schema.minProperties) && !(Object.getOwnPropertyNames(value).length >= schema.minProperties)) { yield Create(ValueErrorType.ObjectMinProperties, schema, path, value) @@ -337,14 +372,14 @@ function* TObject(schema: Types.TObject, references: Types.TSchema[], path: stri if (typeof schema.additionalProperties === 'object') { for (const valueKey of unknownKeys) { if (knownKeys.includes(valueKey)) continue - yield* Visit(schema.additionalProperties as Types.TSchema, references, `${path}/${EscapeKey(valueKey)}`, value[valueKey]) + yield* Visit(schema.additionalProperties as TSchema, references, `${path}/${EscapeKey(valueKey)}`, value[valueKey]) } } for (const knownKey of knownKeys) { const property = schema.properties[knownKey] if (schema.required && schema.required.includes(knownKey)) { yield* Visit(property, references, `${path}/${EscapeKey(knownKey)}`, value[knownKey]) - if (Types.ExtendsUndefinedCheck(schema) && !(knownKey in value)) { + if (ExtendsUndefinedCheck(schema) && !(knownKey in value)) { yield Create(ValueErrorType.ObjectRequiredProperty, property, `${path}/${EscapeKey(knownKey)}`, undefined) } } else { @@ -354,10 +389,10 @@ function* TObject(schema: Types.TObject, references: Types.TSchema[], path: stri } } } -function* TPromise(schema: Types.TPromise, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TPromise(schema: TPromise, references: TSchema[], path: string, value: any): IterableIterator { if (!IsPromise(value)) yield Create(ValueErrorType.Promise, schema, path, value) } -function* TRecord(schema: Types.TRecord, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TRecord(schema: TRecord, references: TSchema[], path: string, value: any): IterableIterator { if (!TypeSystemPolicy.IsRecordLike(value)) return yield Create(ValueErrorType.Object, schema, path, value) if (IsDefined(schema.minProperties) && !(Object.getOwnPropertyNames(value).length >= schema.minProperties)) { yield Create(ValueErrorType.ObjectMinProperties, schema, path, value) @@ -372,7 +407,7 @@ function* TRecord(schema: Types.TRecord, references: Types.TSchema[], path: stri } if (typeof schema.additionalProperties === 'object') { for (const [propertyKey, propertyValue] of Object.entries(value)) { - if (!regex.test(propertyKey)) yield* Visit(schema.additionalProperties as Types.TSchema, references, `${path}/${EscapeKey(propertyKey)}`, propertyValue) + if (!regex.test(propertyKey)) yield* Visit(schema.additionalProperties as TSchema, references, `${path}/${EscapeKey(propertyKey)}`, propertyValue) } } if (schema.additionalProperties === false) { @@ -382,10 +417,10 @@ function* TRecord(schema: Types.TRecord, references: Types.TSchema[], path: stri } } } -function* TRef(schema: Types.TRef, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TRef(schema: TRef, references: TSchema[], path: string, value: any): IterableIterator { yield* Visit(Deref(schema, references), references, path, value) } -function* TString(schema: Types.TString, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TString(schema: TString, references: TSchema[], path: string, value: any): IterableIterator { if (!IsString(value)) return yield Create(ValueErrorType.String, schema, path, value) if (IsDefined(schema.minLength) && !(value.length >= schema.minLength)) { yield Create(ValueErrorType.StringMinLength, schema, path, value) @@ -400,30 +435,30 @@ function* TString(schema: Types.TString, references: Types.TSchema[], path: stri } } if (IsString(schema.format)) { - if (!Types.FormatRegistry.Has(schema.format)) { + if (!FormatRegistry.Has(schema.format)) { yield Create(ValueErrorType.StringFormatUnknown, schema, path, value) } else { - const format = Types.FormatRegistry.Get(schema.format)! + const format = FormatRegistry.Get(schema.format)! if (!format(value)) { yield Create(ValueErrorType.StringFormat, schema, path, value) } } } } -function* TSymbol(schema: Types.TSymbol, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TSymbol(schema: TSymbol, references: TSchema[], path: string, value: any): IterableIterator { if (!IsSymbol(value)) yield Create(ValueErrorType.Symbol, schema, path, value) } -function* TTemplateLiteral(schema: Types.TTemplateLiteral, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TTemplateLiteral(schema: TTemplateLiteral, references: TSchema[], path: string, value: any): IterableIterator { if (!IsString(value)) return yield Create(ValueErrorType.String, schema, path, value) const regex = new RegExp(schema.pattern) if (!regex.test(value)) { yield Create(ValueErrorType.StringPattern, schema, path, value) } } -function* TThis(schema: Types.TThis, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TThis(schema: TThis, references: TSchema[], path: string, value: any): IterableIterator { yield* Visit(Deref(schema, references), references, path, value) } -function* TTuple(schema: Types.TTuple, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TTuple(schema: TTuple, references: TSchema[], path: string, value: any): IterableIterator { if (!IsArray(value)) return yield Create(ValueErrorType.Tuple, schema, path, value) if (schema.items === undefined && !(value.length === 0)) { return yield Create(ValueErrorType.TupleLength, schema, path, value) @@ -438,10 +473,10 @@ function* TTuple(schema: Types.TTuple, references: Types.TSchema[], path: yield* Visit(schema.items[i], references, `${path}/${i}`, value[i]) } } -function* TUndefined(schema: Types.TUndefined, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TUndefined(schema: TUndefined, references: TSchema[], path: string, value: any): IterableIterator { if (!IsUndefined(value)) yield Create(ValueErrorType.Undefined, schema, path, value) } -function* TUnion(schema: Types.TUnion, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TUnion(schema: TUnion, references: TSchema[], path: string, value: any): IterableIterator { let count = 0 for (const subschema of schema.anyOf) { const errors = [...Visit(subschema, references, path, value)] @@ -452,7 +487,7 @@ function* TUnion(schema: Types.TUnion, references: Types.TSchema[], path: string yield Create(ValueErrorType.Union, schema, path, value) } } -function* TUint8Array(schema: Types.TUint8Array, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TUint8Array(schema: TUint8Array, references: TSchema[], path: string, value: any): IterableIterator { if (!IsUint8Array(value)) return yield Create(ValueErrorType.Uint8Array, schema, path, value) if (IsDefined(schema.maxByteLength) && !(value.length <= schema.maxByteLength)) { yield Create(ValueErrorType.Uint8ArrayMaxByteLength, schema, path, value) @@ -461,18 +496,18 @@ function* TUint8Array(schema: Types.TUint8Array, references: Types.TSchema[], pa yield Create(ValueErrorType.Uint8ArrayMinByteLength, schema, path, value) } } -function* TUnknown(schema: Types.TUnknown, references: Types.TSchema[], path: string, value: any): IterableIterator {} -function* TVoid(schema: Types.TVoid, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* TUnknown(schema: TUnknown, references: TSchema[], path: string, value: any): IterableIterator {} +function* TVoid(schema: TVoid, references: TSchema[], path: string, value: any): IterableIterator { if (!TypeSystemPolicy.IsVoidLike(value)) yield Create(ValueErrorType.Void, schema, path, value) } -function* TKind(schema: Types.TSchema, references: Types.TSchema[], path: string, value: any): IterableIterator { - const check = Types.TypeRegistry.Get(schema[Types.Kind])! +function* TKind(schema: TSchema, references: TSchema[], path: string, value: any): IterableIterator { + const check = TypeRegistry.Get(schema[Kind])! if (!check(schema, value)) yield Create(ValueErrorType.Kind, schema, path, value) } -function* Visit(schema: T, references: Types.TSchema[], path: string, value: any): IterableIterator { +function* Visit(schema: T, references: TSchema[], path: string, value: any): IterableIterator { const references_ = IsDefined(schema.$id) ? [...references, schema] : references const schema_ = schema as any - switch (schema_[Types.Kind]) { + switch (schema_[Kind]) { case 'Any': return yield* TAny(schema_, references_, path, value) case 'Array': @@ -534,14 +569,14 @@ function* Visit(schema: T, references: Types.TSchema[], case 'Void': return yield* TVoid(schema_, references_, path, value) default: - if (!Types.TypeRegistry.Has(schema_[Types.Kind])) throw new ValueErrorsUnknownTypeError(schema) + if (!TypeRegistry.Has(schema_[Kind])) throw new ValueErrorsUnknownTypeError(schema) return yield* TKind(schema_, references_, path, value) } } /** Returns an iterator for each error in this value. */ -export function Errors(schema: T, references: Types.TSchema[], value: unknown): ValueErrorIterator +export function Errors(schema: T, references: TSchema[], value: unknown): ValueErrorIterator /** Returns an iterator for each error in this value. */ -export function Errors(schema: T, value: unknown): ValueErrorIterator +export function Errors(schema: T, value: unknown): ValueErrorIterator /** Returns an iterator for each error in this value. */ export function Errors(...args: any[]) { const iterator = args.length === 3 ? Visit(args[0], args[1], '', args[2]) : Visit(args[0], [], '', args[1]) diff --git a/src/value/check/check.ts b/src/value/check/check.ts index d3bbd5124..96ae115b7 100644 --- a/src/value/check/check.ts +++ b/src/value/check/check.ts @@ -54,7 +54,7 @@ import type { TNot } from '../../type/not/index' import type { TNull } from '../../type/null/index' import type { TNumber } from '../../type/number/index' import type { TObject } from '../../type/object/index' -import type { TPromise } from '../..//type/promise/index' +import type { TPromise } from '../../type/promise/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TTemplateLiteral, TTemplateLiteralKind } from '../../type/template-literal/index' diff --git a/src/value/create/create.ts b/src/value/create/create.ts index 4893a1063..fd573e75c 100644 --- a/src/value/create/create.ts +++ b/src/value/create/create.ts @@ -26,9 +26,9 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -import { HasPropertyKey, IsString } from '../guard/guard' -import { Check } from '../check/check' -import { Deref } from '../deref/deref' +import { HasPropertyKey, IsString } from '../guard/index' +import { Check } from '../check/index' +import { Deref } from '../deref/index' import { TemplateLiteralParseExact, IsTemplateLiteralFinite, TemplateLiteralGenerate } from '../../type/template-literal/index' import { PatternStringExact, PatternNumberExact } from '../../type/patterns/index' import { TypeRegistry } from '../../type/registry/index' @@ -52,7 +52,7 @@ import type { TNot } from '../../type/not/index' import type { TNull } from '../../type/null/index' import type { TNumber } from '../../type/number/index' import type { TObject } from '../../type/object/index' -import type { TPromise } from '../..//type/promise/index' +import type { TPromise } from '../../type/promise/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TTemplateLiteral } from '../../type/template-literal/index'