Skip to content

Commit

Permalink
Revision 0.32.15 (#774)
Browse files Browse the repository at this point in the history
* Add Additional Guards for Typed Arrays

* Map and Set | Additional Narrow for InstanceObject

* Version
  • Loading branch information
sinclairzx81 committed Mar 1, 2024
1 parent fd1056b commit 3db65cd
Show file tree
Hide file tree
Showing 16 changed files with 377 additions and 138 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sinclair/typebox",
"version": "0.32.14",
"version": "0.32.15",
"description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
"keywords": [
"typescript",
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

export { ValueError, ValueErrorType, ValueErrorIterator } from '../errors/index'
export { TypeCompiler, TypeCheck, type TypeCompilerCodegenOptions, type TypeCompilerLanguageOption, TypeCompilerTypeGuardError, TypeCompilerUnknownTypeError } from './compiler'
export * from './compiler'
4 changes: 2 additions & 2 deletions src/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

export { Errors, ValueError, ValueErrorIterator, ValueErrorType, ValueErrorsUnknownTypeError } from './errors'
export { DefaultErrorFunction, GetErrorFunction, SetErrorFunction, type ErrorFunction, type ErrorFunctionParameter } from './function'
export * from './errors'
export * from './function'
4 changes: 2 additions & 2 deletions src/system/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

export { TypeSystemPolicy } from './policy'
export { TypeSystem, TypeSystemDuplicateFormat, TypeSystemDuplicateTypeKind } from './system'
export * from './policy'
export * from './system'
4 changes: 2 additions & 2 deletions src/value/cast/cast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

import { IsPlainObject, IsArray, IsString, IsNumber, IsNull } from '../guard/index'
import { IsStandardObject, IsArray, IsString, IsNumber, IsNull } from '../guard/index'
import { TypeBoxError } from '../../type/error/index'
import { Kind } from '../../type/symbols/index'
import { Create } from '../create/index'
Expand Down Expand Up @@ -134,7 +134,7 @@ function FromConstructor(schema: TConstructor, references: TSchema[], value: any
}
function FromIntersect(schema: TIntersect, references: TSchema[], value: any): any {
const created = Create(schema, references)
const mapped = IsPlainObject(created) && IsPlainObject(value) ? { ...(created as any), ...value } : value
const mapped = IsStandardObject(created) && IsStandardObject(value) ? { ...(created as any), ...value } : value
return Check(schema, references, mapped) ? mapped : Create(schema, references)
}
function FromNever(schema: TNever, references: TSchema[], value: any): any {
Expand Down
4 changes: 2 additions & 2 deletions src/value/clone/clone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import type { ObjectType, ArrayType, TypedArrayType, ValueType } from '../guard/
// ------------------------------------------------------------------
// ValueGuard
// ------------------------------------------------------------------
import { IsArray, IsDate, IsPlainObject, IsTypedArray, IsValueType } from '../guard/index'
import { IsArray, IsDate, IsStandardObject, IsTypedArray, IsValueType } from '../guard/index'
// ------------------------------------------------------------------
// Clonable
// ------------------------------------------------------------------
Expand All @@ -58,7 +58,7 @@ function ValueType(value: ValueType): any {
export function Clone<T extends unknown>(value: T): T {
if (IsArray(value)) return ArrayType(value)
if (IsDate(value)) return DateType(value)
if (IsPlainObject(value)) return ObjectType(value)
if (IsStandardObject(value)) return ObjectType(value)
if (IsTypedArray(value)) return TypedArrayType(value)
if (IsValueType(value)) return ValueType(value)
throw new Error('ValueClone: Unable to clone value')
Expand Down
6 changes: 3 additions & 3 deletions src/value/delta/delta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

import { IsPlainObject, IsArray, IsTypedArray, IsValueType, IsSymbol, IsUndefined } from '../guard/index'
import { IsStandardObject, IsArray, IsTypedArray, IsValueType, IsSymbol, IsUndefined } from '../guard/index'
import type { ObjectType, ArrayType, TypedArrayType, ValueType } from '../guard/index'
import type { Static } from '../../type/static/index'
import { ValuePointer } from '../pointer/index'
Expand Down Expand Up @@ -90,7 +90,7 @@ function CreateDelete(path: string): Edit {
// Diffing Generators
// ------------------------------------------------------------------
function* ObjectType(path: string, current: ObjectType, next: unknown): IterableIterator<Edit> {
if (!IsPlainObject(next)) return yield CreateUpdate(path, next)
if (!IsStandardObject(next)) return yield CreateUpdate(path, next)
const currentKeys = [...globalThis.Object.keys(current), ...globalThis.Object.getOwnPropertySymbols(current)]
const nextKeys = [...globalThis.Object.keys(next), ...globalThis.Object.getOwnPropertySymbols(next)]
for (const key of currentKeys) {
Expand Down Expand Up @@ -136,7 +136,7 @@ function* ValueType(path: string, current: ValueType, next: unknown): IterableIt
yield CreateUpdate(path, next)
}
function* Visit(path: string, current: unknown, next: unknown): IterableIterator<Edit> {
if (IsPlainObject(current)) return yield* ObjectType(path, current, next)
if (IsStandardObject(current)) return yield* ObjectType(path, current, next)
if (IsArray(current)) return yield* ArrayType(path, current, next)
if (IsTypedArray(current)) return yield* TypedArrayType(path, current, next)
if (IsValueType(current)) return yield* ValueType(path, current, next)
Expand Down
6 changes: 3 additions & 3 deletions src/value/equal/equal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

import { IsPlainObject, IsDate, IsArray, IsTypedArray, IsValueType } from '../guard/index'
import { IsStandardObject, IsDate, IsArray, IsTypedArray, IsValueType } from '../guard/index'
import type { ObjectType, ArrayType, TypedArrayType, ValueType } from '../guard/index'

// ------------------------------------------------------------------
// Equality Checks
// ------------------------------------------------------------------
function ObjectType(left: ObjectType, right: unknown): boolean {
if (!IsPlainObject(right)) return false
if (!IsStandardObject(right)) return false
const leftKeys = [...Object.keys(left), ...Object.getOwnPropertySymbols(left)]
const rightKeys = [...Object.keys(right), ...Object.getOwnPropertySymbols(right)]
if (leftKeys.length !== rightKeys.length) return false
Expand All @@ -58,7 +58,7 @@ function ValueType(left: ValueType, right: unknown): any {
// ------------------------------------------------------------------
/** Returns true if the left value deep-equals the right */
export function Equal<T>(left: T, right: unknown): right is T {
if (IsPlainObject(left)) return ObjectType(left, right)
if (IsStandardObject(left)) return ObjectType(left, right)
if (IsDate(left)) return DateType(left, right)
if (IsTypedArray(left)) return TypedArrayType(left, right)
if (IsArray(left)) return ArrayType(left, right)
Expand Down
83 changes: 71 additions & 12 deletions src/value/guard/guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,35 +57,94 @@ export function IsIterator(value: unknown): value is IterableIterator<any> {
return IsObject(value) && Symbol.iterator in value
}
// --------------------------------------------------------------------------
// Nominal
// Object Instances
// --------------------------------------------------------------------------
/** Returns true if this value is a typed array */
export function IsTypedArray(value: unknown): value is TypedArrayType {
return ArrayBuffer.isView(value)
/** Returns true if this value is not an instance of a class */
export function IsStandardObject(value: unknown): value is ObjectType {
return IsObject(value) && !IsArray(value) && IsFunction(value.constructor) && value.constructor.name === 'Object'
}
/** Returns true if this value is an instance of a class */
export function IsInstanceObject(value: unknown): value is ObjectType {
return IsObject(value) && !IsArray(value) && IsFunction(value.constructor) && value.constructor.name !== 'Object'
}
// --------------------------------------------------------------------------
// JavaScript
// --------------------------------------------------------------------------
/** Returns true if this value is a Promise */
export function IsPromise(value: unknown): value is Promise<unknown> {
return value instanceof Promise
}
/** Returns true if the value is a Uint8Array */
export function IsUint8Array(value: unknown): value is Uint8Array {
return value instanceof Uint8Array
}
/** Returns true if this value is a Date */
export function IsDate(value: unknown): value is Date {
return value instanceof Date && Number.isFinite(value.getTime())
}
/** Returns true if this value is an instance of Map<K, T> */
export function IsMap(value: unknown): value is Map<unknown, unknown> {
return value instanceof globalThis.Map
}
/** Returns true if this value is an instance of Set<T> */
export function IsSet(value: unknown): value is Set<unknown> {
return value instanceof globalThis.Set
}
/** Returns true if this value is RegExp */
export function IsRegExp(value: unknown): value is RegExp {
return value instanceof globalThis.RegExp
}
/** Returns true if this value is a typed array */
export function IsTypedArray(value: unknown): value is TypedArrayType {
return ArrayBuffer.isView(value)
}
/** Returns true if the value is a Int8Array */
export function IsInt8Array(value: unknown): value is Int8Array {
return value instanceof globalThis.Int8Array
}
/** Returns true if the value is a Uint8Array */
export function IsUint8Array(value: unknown): value is Uint8Array {
return value instanceof globalThis.Uint8Array
}
/** Returns true if the value is a Uint8ClampedArray */
export function IsUint8ClampedArray(value: unknown): value is Uint8ClampedArray {
return value instanceof globalThis.Uint8ClampedArray
}
/** Returns true if the value is a Int16Array */
export function IsInt16Array(value: unknown): value is Int16Array {
return value instanceof globalThis.Int16Array
}
/** Returns true if the value is a Uint16Array */
export function IsUint16Array(value: unknown): value is Uint16Array {
return value instanceof globalThis.Uint16Array
}
/** Returns true if the value is a Int32Array */
export function IsInt32Array(value: unknown): value is Int32Array {
return value instanceof globalThis.Int32Array
}
/** Returns true if the value is a Uint32Array */
export function IsUint32Array(value: unknown): value is Uint32Array {
return value instanceof globalThis.Uint32Array
}
/** Returns true if the value is a Float32Array */
export function IsFloat32Array(value: unknown): value is Float32Array {
return value instanceof globalThis.Float32Array
}
/** Returns true if the value is a Float64Array */
export function IsFloat64Array(value: unknown): value is Float64Array {
return value instanceof globalThis.Float64Array
}
/** Returns true if the value is a BigInt64Array */
export function IsBigInt64Array(value: unknown): value is BigInt64Array {
return value instanceof globalThis.BigInt64Array
}
/** Returns true if the value is a BigUint64Array */
export function IsBigUint64Array(value: unknown): value is BigUint64Array {
return value instanceof globalThis.BigUint64Array
}
// --------------------------------------------------------------------------
// Standard
// --------------------------------------------------------------------------
/** Returns true if this value has this property key */
export function HasPropertyKey<K extends PropertyKey>(value: Record<any, unknown>, key: K): value is ObjectType & Record<K, unknown> {
return key in value
}
/** Returns true if this object is not an instance of any other type */
export function IsPlainObject(value: unknown): value is ObjectType {
return IsObject(value) && IsFunction(value.constructor) && value.constructor.name === 'Object'
}
/** Returns true of this value is an object type */
export function IsObject(value: unknown): value is ObjectType {
return value !== null && typeof value === 'object'
Expand Down
4 changes: 2 additions & 2 deletions src/value/hash/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

import { IsArray, IsBoolean, IsBigInt, IsDate, IsNull, IsNumber, IsPlainObject, IsString, IsSymbol, IsUint8Array, IsUndefined } from '../guard/index'
import { IsArray, IsBoolean, IsBigInt, IsDate, IsNull, IsNumber, IsStandardObject, IsString, IsSymbol, IsUint8Array, IsUndefined } from '../guard/index'
import { TypeBoxError } from '../../type/error/index'

// ------------------------------------------------------------------
Expand Down Expand Up @@ -140,7 +140,7 @@ function Visit(value: any) {
if (IsDate(value)) return DateType(value)
if (IsNull(value)) return NullType(value)
if (IsNumber(value)) return NumberType(value)
if (IsPlainObject(value)) return ObjectType(value)
if (IsStandardObject(value)) return ObjectType(value)
if (IsString(value)) return StringType(value)
if (IsSymbol(value)) return SymbolType(value)
if (IsUint8Array(value)) return Uint8ArrayType(value)
Expand Down
61 changes: 18 additions & 43 deletions src/value/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,55 +27,30 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

// ------------------------------------------------------------------
// Value Errors (re-export)
// Errors (re-export)
// ------------------------------------------------------------------
export { ValueError, ValueErrorType, ValueErrorIterator } from '../errors/index'
// ------------------------------------------------------------------
// Value Operators
// Guards
// ------------------------------------------------------------------
export { Cast, ValueCastError } from './cast/index'
export { Check } from './check/index'
export { Clean } from './clean/index'
export { Clone } from './clone/index'
export { Convert } from './convert/index'
export { Create, ValueCreateError } from './create/index'
export { Default } from './default/index'
export { Diff, Patch, Edit, Delete, Insert, Update, ValueDeltaError } from './delta/index'
export { Equal } from './equal/index'
export { Hash, ValueHashError } from './hash/index'
export { Mutate, ValueMutateError, type Mutable } from './mutate/index'
export { ValuePointer } from './pointer/index'
export { TransformDecode, TransformEncode, HasTransform, TransformDecodeCheckError, TransformDecodeError, TransformEncodeCheckError, TransformEncodeError } from './transform/index'
export * from './guard/index'
// ------------------------------------------------------------------
// Value Guards
// Operators
// ------------------------------------------------------------------
export {
ArrayType,
HasPropertyKey,
IsArray,
IsAsyncIterator,
IsBigInt,
IsBoolean,
IsDate,
IsFunction,
IsInteger,
IsIterator,
IsNull,
IsNumber,
IsObject,
IsPlainObject,
IsPromise,
IsString,
IsSymbol,
IsTypedArray,
IsUint8Array,
IsUndefined,
IsValueType,
type ObjectType,
type TypedArrayType,
type ValueType,
} from './guard/index'
export * from './cast/index'
export * from './check/index'
export * from './clean/index'
export * from './clone/index'
export * from './convert/index'
export * from './create/index'
export * from './default/index'
export * from './delta/index'
export * from './equal/index'
export * from './hash/index'
export * from './mutate/index'
export * from './pointer/index'
export * from './transform/index'
// ------------------------------------------------------------------
// Value Namespace
// Namespace
// ------------------------------------------------------------------
export { Value } from './value/index'
10 changes: 5 additions & 5 deletions src/value/mutate/mutate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

import { IsPlainObject, IsArray, IsTypedArray, IsValueType, type TypedArrayType } from '../guard/index'
import { IsStandardObject, IsArray, IsTypedArray, IsValueType, type TypedArrayType } from '../guard/index'
import { ValuePointer } from '../pointer/index'
import { Clone } from '../clone/index'
import { TypeBoxError } from '../../type/error/index'
Expand All @@ -44,7 +44,7 @@ export class ValueMutateError extends TypeBoxError {
// ------------------------------------------------------------------
export type Mutable = { [key: string]: unknown } | unknown[]
function ObjectType(root: Mutable, path: string, current: unknown, next: Record<string, unknown>) {
if (!IsPlainObject(current)) {
if (!IsStandardObject(current)) {
ValuePointer.Set(root, path, Clone(next))
} else {
const currentKeys = Object.keys(current)
Expand Down Expand Up @@ -90,7 +90,7 @@ function ValueType(root: Mutable, path: string, current: unknown, next: unknown)
function Visit(root: Mutable, path: string, current: unknown, next: unknown) {
if (IsArray(next)) return ArrayType(root, path, current, next)
if (IsTypedArray(next)) return TypedArrayType(root, path, current, next)
if (IsPlainObject(next)) return ObjectType(root, path, current, next)
if (IsStandardObject(next)) return ObjectType(root, path, current, next)
if (IsValueType(next)) return ValueType(root, path, current, next)
}
// ------------------------------------------------------------------
Expand All @@ -102,8 +102,8 @@ function IsNonMutableValue(value: unknown): value is Mutable {
function IsMismatchedValue(current: unknown, next: unknown) {
// prettier-ignore
return (
(IsPlainObject(current) && IsArray(next)) ||
(IsArray(current) && IsPlainObject(next))
(IsStandardObject(current) && IsArray(next)) ||
(IsArray(current) && IsStandardObject(next))
)
}
// ------------------------------------------------------------------
Expand Down

0 comments on commit 3db65cd

Please sign in to comment.