object-shape-tester
Advanced tools
Comparing version 2.1.0 to 2.2.0
@@ -13,3 +13,5 @@ "use strict"; | ||
isReadonly, | ||
defaultValue: (0, shape_to_default_value_1.shapeToDefaultValue)(shape), | ||
get defaultValue() { | ||
return (0, shape_to_default_value_1.shapeToDefaultValue)(shape); | ||
}, | ||
[shape_specifiers_1.isShapeDefinitionKey]: true, | ||
@@ -16,0 +18,0 @@ }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getShapeSpecifier = exports.matchesSpecifier = exports.specifier = exports.specifierHasSymbol = exports.isUnknownShapeSpecifier = exports.isEnumShapeSpecifier = exports.isExactShapeSpecifier = exports.isAndShapeSpecifier = exports.isOrShapeSpecifier = exports.isIndexedKeysSpecifier = exports.unknownShape = exports.enumShape = exports.exact = exports.and = exports.or = exports.indexedKeys = exports.shapeSpecifiersTypes = exports.isShapeSpecifierKey = exports.isShapeDefinition = exports.isShapeDefinitionKey = void 0; | ||
exports.getShapeSpecifier = exports.matchesSpecifier = exports.specifier = exports.specifierHasSymbol = exports.isUnknownShapeSpecifier = exports.isOrShapeSpecifier = exports.isIndexedKeysSpecifier = exports.isExactShapeSpecifier = exports.isEnumShapeSpecifier = exports.isClassShapeSpecifier = exports.isAndShapeSpecifier = exports.unknownShape = exports.or = exports.indexedKeys = exports.exact = exports.enumShape = exports.classShape = exports.and = exports.isShapeSpecifierKey = exports.shapeSpecifiersTypes = exports.isShapeDefinition = exports.isShapeDefinitionKey = void 0; | ||
const common_1 = require("@augment-vir/common"); | ||
const run_time_assertions_1 = require("run-time-assertions"); | ||
const type_equality_1 = require("./type-equality"); | ||
const andSymbol = Symbol('and'); | ||
const orSymbol = Symbol('or'); | ||
const exactSymbol = Symbol('exact'); | ||
const enumSymbol = Symbol('enum'); | ||
const unknownSymbol = Symbol('unknown'); | ||
const indexedKeysSymbol = Symbol('indexed-keys'); | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Definition | ||
* | ||
* ======================================== | ||
*/ | ||
/** | ||
* This should really be a symbol, but TypeScript freaks out about using names that cannot be named | ||
@@ -22,19 +23,33 @@ * in that case. | ||
exports.isShapeDefinition = isShapeDefinition; | ||
exports.isShapeSpecifierKey = '__vir__shape__specifier__key__do__not__use__in__actual__objects'; | ||
/** | ||
* ======================================== | ||
* | ||
* Specifier Symbols | ||
* | ||
* ======================================== | ||
*/ | ||
const andSymbol = Symbol('and'); | ||
const classSymbol = Symbol('instance'); | ||
const enumSymbol = Symbol('enum'); | ||
const exactSymbol = Symbol('exact'); | ||
const indexedKeysSymbol = Symbol('indexed-keys'); | ||
const orSymbol = Symbol('or'); | ||
const unknownSymbol = Symbol('unknown'); | ||
exports.shapeSpecifiersTypes = [ | ||
andSymbol, | ||
enumSymbol, | ||
exactSymbol, | ||
indexedKeysSymbol, | ||
classSymbol, | ||
orSymbol, | ||
exactSymbol, | ||
enumSymbol, | ||
unknownSymbol, | ||
indexedKeysSymbol, | ||
]; | ||
function indexedKeys(...parts) { | ||
return specifier(parts, indexedKeysSymbol); | ||
} | ||
exports.indexedKeys = indexedKeys; | ||
function or(...parts) { | ||
return specifier(parts, orSymbol); | ||
} | ||
exports.or = or; | ||
exports.isShapeSpecifierKey = '__vir__shape__specifier__key__do__not__use__in__actual__objects'; | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Functions | ||
* | ||
* ======================================== | ||
*/ | ||
function and(...parts) { | ||
@@ -44,2 +59,11 @@ return specifier(parts, andSymbol); | ||
exports.and = and; | ||
/** Define a shape that is an instance of the given class constructor. */ | ||
function classShape(...parts) { | ||
return specifier(parts, classSymbol); | ||
} | ||
exports.classShape = classShape; | ||
function enumShape(...parts) { | ||
return specifier(parts, enumSymbol); | ||
} | ||
exports.enumShape = enumShape; | ||
function exact(...parts) { | ||
@@ -49,6 +73,10 @@ return specifier(parts, exactSymbol); | ||
exports.exact = exact; | ||
function enumShape(...parts) { | ||
return specifier(parts, enumSymbol); | ||
function indexedKeys(...parts) { | ||
return specifier(parts, indexedKeysSymbol); | ||
} | ||
exports.enumShape = enumShape; | ||
exports.indexedKeys = indexedKeys; | ||
function or(...parts) { | ||
return specifier(parts, orSymbol); | ||
} | ||
exports.or = or; | ||
function unknownShape(defaultValue) { | ||
@@ -58,10 +86,9 @@ return specifier([defaultValue], unknownSymbol); | ||
exports.unknownShape = unknownShape; | ||
function isIndexedKeysSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, indexedKeysSymbol); | ||
} | ||
exports.isIndexedKeysSpecifier = isIndexedKeysSpecifier; | ||
function isOrShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, orSymbol); | ||
} | ||
exports.isOrShapeSpecifier = isOrShapeSpecifier; | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Specifier Type Guards | ||
* | ||
* ======================================== | ||
*/ | ||
function isAndShapeSpecifier(maybeSpecifier) { | ||
@@ -71,2 +98,10 @@ return specifierHasSymbol(maybeSpecifier, andSymbol); | ||
exports.isAndShapeSpecifier = isAndShapeSpecifier; | ||
function isClassShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, classSymbol); | ||
} | ||
exports.isClassShapeSpecifier = isClassShapeSpecifier; | ||
function isEnumShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, enumSymbol); | ||
} | ||
exports.isEnumShapeSpecifier = isEnumShapeSpecifier; | ||
function isExactShapeSpecifier(maybeSpecifier) { | ||
@@ -76,6 +111,10 @@ return specifierHasSymbol(maybeSpecifier, exactSymbol); | ||
exports.isExactShapeSpecifier = isExactShapeSpecifier; | ||
function isEnumShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, enumSymbol); | ||
function isIndexedKeysSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, indexedKeysSymbol); | ||
} | ||
exports.isEnumShapeSpecifier = isEnumShapeSpecifier; | ||
exports.isIndexedKeysSpecifier = isIndexedKeysSpecifier; | ||
function isOrShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, orSymbol); | ||
} | ||
exports.isOrShapeSpecifier = isOrShapeSpecifier; | ||
function isUnknownShapeSpecifier(maybeSpecifier) { | ||
@@ -85,2 +124,9 @@ return specifierHasSymbol(maybeSpecifier, unknownSymbol); | ||
exports.isUnknownShapeSpecifier = isUnknownShapeSpecifier; | ||
/** | ||
* ======================================== | ||
* | ||
* Specifier Utilities | ||
* | ||
* ======================================== | ||
*/ | ||
function specifierHasSymbol(maybeSpecifier, symbol) { | ||
@@ -102,3 +148,6 @@ const specifier = getShapeSpecifier(maybeSpecifier); | ||
if (specifier) { | ||
if (isAndShapeSpecifier(specifier)) { | ||
if (isClassShapeSpecifier(specifier)) { | ||
return subject instanceof specifier.parts[0]; | ||
} | ||
else if (isAndShapeSpecifier(specifier)) { | ||
return specifier.parts.every((part) => matchesSpecifier(subject, part)); | ||
@@ -105,0 +154,0 @@ } |
@@ -6,2 +6,3 @@ "use strict"; | ||
const run_time_assertions_1 = require("run-time-assertions"); | ||
const default_value_construction_error_1 = require("../errors/default-value-construction.error"); | ||
const shape_specifiers_1 = require("./shape-specifiers"); | ||
@@ -15,3 +16,12 @@ function shapeToDefaultValue(shape, isReadonly = false) { | ||
if (specifier) { | ||
if ((0, shape_specifiers_1.isOrShapeSpecifier)(specifier) || (0, shape_specifiers_1.isExactShapeSpecifier)(specifier)) { | ||
if ((0, shape_specifiers_1.isClassShapeSpecifier)(specifier)) { | ||
const classConstructor = specifier.parts[0]; | ||
try { | ||
return new classConstructor(); | ||
} | ||
catch (caught) { | ||
throw new default_value_construction_error_1.DefaultValueConstructionError(`Failed to create default value for classShape for class '${classConstructor.name}': ${(0, common_1.extractErrorMessage)(caught)}`); | ||
} | ||
} | ||
else if ((0, shape_specifiers_1.isOrShapeSpecifier)(specifier) || (0, shape_specifiers_1.isExactShapeSpecifier)(specifier)) { | ||
return innerShapeToDefaultValue(specifier.parts[0]); | ||
@@ -35,3 +45,3 @@ } | ||
else { | ||
throw new Error(`found specifier but it matches no expected specifiers: ${String(specifier.specifierType)}`); | ||
throw new default_value_construction_error_1.DefaultValueConstructionError(`found specifier but it matches no expected specifiers: ${String(specifier.specifierType)}`); | ||
} | ||
@@ -38,0 +48,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ShapeMismatchError = void 0; | ||
class ShapeMismatchError extends Error { | ||
class ShapeMismatchError extends TypeError { | ||
constructor() { | ||
@@ -6,0 +6,0 @@ super(...arguments); |
@@ -55,2 +55,5 @@ "use strict"; | ||
} | ||
if ((0, shape_specifiers_1.isClassShapeSpecifier)(shape)) { | ||
return subject instanceof shape.parts[0]; | ||
} | ||
if ((0, common_1.isObject)(subject)) { | ||
@@ -206,3 +209,8 @@ const objectSubject = subject; | ||
}); | ||
const errorMessage = `Failed on key(s): ${failedKeys.join(',')}`; | ||
const errorMessage = `Failed on key(s): ${failedKeys | ||
.map((failedKey) => createKeyString([ | ||
...keys, | ||
failedKey, | ||
])) | ||
.join(',')}`; | ||
throw new shape_mismatch_error_1.ShapeMismatchError(errorMessage); | ||
@@ -209,0 +217,0 @@ } |
@@ -10,5 +10,7 @@ import { isShapeDefinitionKey } from './shape-specifiers'; | ||
isReadonly, | ||
defaultValue: shapeToDefaultValue(shape), | ||
get defaultValue() { | ||
return shapeToDefaultValue(shape); | ||
}, | ||
[isShapeDefinitionKey]: true, | ||
}; | ||
} |
import { getObjectTypedKeys, getObjectTypedValues, isObject, typedArrayIncludes, typedHasProperty, } from '@augment-vir/common'; | ||
import { isRunTimeType } from 'run-time-assertions'; | ||
import { haveEqualTypes } from './type-equality'; | ||
const andSymbol = Symbol('and'); | ||
const orSymbol = Symbol('or'); | ||
const exactSymbol = Symbol('exact'); | ||
const enumSymbol = Symbol('enum'); | ||
const unknownSymbol = Symbol('unknown'); | ||
const indexedKeysSymbol = Symbol('indexed-keys'); | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Definition | ||
* | ||
* ======================================== | ||
*/ | ||
/** | ||
* This should really be a symbol, but TypeScript freaks out about using names that cannot be named | ||
@@ -18,22 +19,39 @@ * in that case. | ||
} | ||
export const isShapeSpecifierKey = '__vir__shape__specifier__key__do__not__use__in__actual__objects'; | ||
/** | ||
* ======================================== | ||
* | ||
* Specifier Symbols | ||
* | ||
* ======================================== | ||
*/ | ||
const andSymbol = Symbol('and'); | ||
const classSymbol = Symbol('instance'); | ||
const enumSymbol = Symbol('enum'); | ||
const exactSymbol = Symbol('exact'); | ||
const indexedKeysSymbol = Symbol('indexed-keys'); | ||
const orSymbol = Symbol('or'); | ||
const unknownSymbol = Symbol('unknown'); | ||
export const shapeSpecifiersTypes = [ | ||
andSymbol, | ||
enumSymbol, | ||
exactSymbol, | ||
indexedKeysSymbol, | ||
classSymbol, | ||
orSymbol, | ||
exactSymbol, | ||
enumSymbol, | ||
unknownSymbol, | ||
indexedKeysSymbol, | ||
]; | ||
export function indexedKeys(...parts) { | ||
return specifier(parts, indexedKeysSymbol); | ||
} | ||
export function or(...parts) { | ||
return specifier(parts, orSymbol); | ||
} | ||
export const isShapeSpecifierKey = '__vir__shape__specifier__key__do__not__use__in__actual__objects'; | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Functions | ||
* | ||
* ======================================== | ||
*/ | ||
export function and(...parts) { | ||
return specifier(parts, andSymbol); | ||
} | ||
export function exact(...parts) { | ||
return specifier(parts, exactSymbol); | ||
/** Define a shape that is an instance of the given class constructor. */ | ||
export function classShape(...parts) { | ||
return specifier(parts, classSymbol); | ||
} | ||
@@ -43,16 +61,26 @@ export function enumShape(...parts) { | ||
} | ||
export function exact(...parts) { | ||
return specifier(parts, exactSymbol); | ||
} | ||
export function indexedKeys(...parts) { | ||
return specifier(parts, indexedKeysSymbol); | ||
} | ||
export function or(...parts) { | ||
return specifier(parts, orSymbol); | ||
} | ||
export function unknownShape(defaultValue) { | ||
return specifier([defaultValue], unknownSymbol); | ||
} | ||
export function isIndexedKeysSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, indexedKeysSymbol); | ||
} | ||
export function isOrShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, orSymbol); | ||
} | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Specifier Type Guards | ||
* | ||
* ======================================== | ||
*/ | ||
export function isAndShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, andSymbol); | ||
} | ||
export function isExactShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, exactSymbol); | ||
export function isClassShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, classSymbol); | ||
} | ||
@@ -62,5 +90,21 @@ export function isEnumShapeSpecifier(maybeSpecifier) { | ||
} | ||
export function isExactShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, exactSymbol); | ||
} | ||
export function isIndexedKeysSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, indexedKeysSymbol); | ||
} | ||
export function isOrShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, orSymbol); | ||
} | ||
export function isUnknownShapeSpecifier(maybeSpecifier) { | ||
return specifierHasSymbol(maybeSpecifier, unknownSymbol); | ||
} | ||
/** | ||
* ======================================== | ||
* | ||
* Specifier Utilities | ||
* | ||
* ======================================== | ||
*/ | ||
export function specifierHasSymbol(maybeSpecifier, symbol) { | ||
@@ -80,3 +124,6 @@ const specifier = getShapeSpecifier(maybeSpecifier); | ||
if (specifier) { | ||
if (isAndShapeSpecifier(specifier)) { | ||
if (isClassShapeSpecifier(specifier)) { | ||
return subject instanceof specifier.parts[0]; | ||
} | ||
else if (isAndShapeSpecifier(specifier)) { | ||
return specifier.parts.every((part) => matchesSpecifier(subject, part)); | ||
@@ -83,0 +130,0 @@ } |
@@ -1,4 +0,5 @@ | ||
import { isObject, mapObjectValues } from '@augment-vir/common'; | ||
import { extractErrorMessage, isObject, mapObjectValues } from '@augment-vir/common'; | ||
import { isRunTimeType } from 'run-time-assertions'; | ||
import { getShapeSpecifier, isAndShapeSpecifier, isEnumShapeSpecifier, isExactShapeSpecifier, isIndexedKeysSpecifier, isOrShapeSpecifier, isShapeDefinition, isUnknownShapeSpecifier, } from './shape-specifiers'; | ||
import { DefaultValueConstructionError } from '../errors/default-value-construction.error'; | ||
import { getShapeSpecifier, isAndShapeSpecifier, isClassShapeSpecifier, isEnumShapeSpecifier, isExactShapeSpecifier, isIndexedKeysSpecifier, isOrShapeSpecifier, isShapeDefinition, isUnknownShapeSpecifier, } from './shape-specifiers'; | ||
export function shapeToDefaultValue(shape, isReadonly = false) { | ||
@@ -10,3 +11,12 @@ return innerShapeToDefaultValue(shape); | ||
if (specifier) { | ||
if (isOrShapeSpecifier(specifier) || isExactShapeSpecifier(specifier)) { | ||
if (isClassShapeSpecifier(specifier)) { | ||
const classConstructor = specifier.parts[0]; | ||
try { | ||
return new classConstructor(); | ||
} | ||
catch (caught) { | ||
throw new DefaultValueConstructionError(`Failed to create default value for classShape for class '${classConstructor.name}': ${extractErrorMessage(caught)}`); | ||
} | ||
} | ||
else if (isOrShapeSpecifier(specifier) || isExactShapeSpecifier(specifier)) { | ||
return innerShapeToDefaultValue(specifier.parts[0]); | ||
@@ -30,3 +40,3 @@ } | ||
else { | ||
throw new Error(`found specifier but it matches no expected specifiers: ${String(specifier.specifierType)}`); | ||
throw new DefaultValueConstructionError(`found specifier but it matches no expected specifiers: ${String(specifier.specifierType)}`); | ||
} | ||
@@ -33,0 +43,0 @@ } |
@@ -1,2 +0,2 @@ | ||
export class ShapeMismatchError extends Error { | ||
export class ShapeMismatchError extends TypeError { | ||
constructor() { | ||
@@ -3,0 +3,0 @@ super(...arguments); |
import { getObjectTypedKeys, isObject, mapObjectValues, } from '@augment-vir/common'; | ||
import { isRunTimeType } from 'run-time-assertions'; | ||
import { getShapeSpecifier, isAndShapeSpecifier, isEnumShapeSpecifier, isExactShapeSpecifier, isIndexedKeysSpecifier, isOrShapeSpecifier, isShapeDefinition, isUnknownShapeSpecifier, matchesSpecifier, } from '../define-shape/shape-specifiers'; | ||
import { getShapeSpecifier, isAndShapeSpecifier, isClassShapeSpecifier, isEnumShapeSpecifier, isExactShapeSpecifier, isIndexedKeysSpecifier, isOrShapeSpecifier, isShapeDefinition, isUnknownShapeSpecifier, matchesSpecifier, } from '../define-shape/shape-specifiers'; | ||
import { ShapeMismatchError } from '../errors/shape-mismatch.error'; | ||
@@ -50,2 +50,5 @@ export function isValidShape(subject, shapeDefinition, options = {}) { | ||
} | ||
if (isClassShapeSpecifier(shape)) { | ||
return subject instanceof shape.parts[0]; | ||
} | ||
if (isObject(subject)) { | ||
@@ -201,3 +204,8 @@ const objectSubject = subject; | ||
}); | ||
const errorMessage = `Failed on key(s): ${failedKeys.join(',')}`; | ||
const errorMessage = `Failed on key(s): ${failedKeys | ||
.map((failedKey) => createKeyString([ | ||
...keys, | ||
failedKey, | ||
])) | ||
.join(',')}`; | ||
throw new ShapeMismatchError(errorMessage); | ||
@@ -204,0 +212,0 @@ } |
import { ArrayElement, AtLeastTuple } from '@augment-vir/common'; | ||
import { LiteralToPrimitive, Primitive, UnionToIntersection, WritableDeep } from 'type-fest'; | ||
declare const andSymbol: unique symbol; | ||
declare const orSymbol: unique symbol; | ||
declare const exactSymbol: unique symbol; | ||
declare const enumSymbol: unique symbol; | ||
declare const unknownSymbol: unique symbol; | ||
declare const indexedKeysSymbol: unique symbol; | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Definition | ||
* | ||
* ======================================== | ||
*/ | ||
/** | ||
* This should really be a symbol, but TypeScript freaks out about using names that cannot be named | ||
@@ -23,6 +24,20 @@ * in that case. | ||
export declare function isShapeDefinition(input: unknown): input is ShapeDefinition<unknown, false>; | ||
/** | ||
* ======================================== | ||
* | ||
* Specifier Symbols | ||
* | ||
* ======================================== | ||
*/ | ||
declare const andSymbol: unique symbol; | ||
declare const classSymbol: unique symbol; | ||
declare const enumSymbol: unique symbol; | ||
declare const exactSymbol: unique symbol; | ||
declare const indexedKeysSymbol: unique symbol; | ||
declare const orSymbol: unique symbol; | ||
declare const unknownSymbol: unique symbol; | ||
export declare const shapeSpecifiersTypes: readonly [typeof andSymbol, typeof enumSymbol, typeof exactSymbol, typeof indexedKeysSymbol, typeof classSymbol, typeof orSymbol, typeof unknownSymbol]; | ||
type BaseParts = AtLeastTuple<unknown, 0>; | ||
export declare const isShapeSpecifierKey: "__vir__shape__specifier__key__do__not__use__in__actual__objects"; | ||
export declare const shapeSpecifiersTypes: readonly [typeof andSymbol, typeof orSymbol, typeof exactSymbol, typeof enumSymbol, typeof unknownSymbol, typeof indexedKeysSymbol]; | ||
type ShapeSpecifierType = ArrayElement<typeof shapeSpecifiersTypes>; | ||
type BaseParts = AtLeastTuple<unknown, 0>; | ||
export type ShapeSpecifier<Parts extends BaseParts, Type extends ShapeSpecifierType> = { | ||
@@ -33,2 +48,14 @@ [isShapeSpecifierKey]: true; | ||
}; | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Types | ||
* | ||
* ======================================== | ||
*/ | ||
export type ShapeAnd<Parts extends AtLeastTuple<unknown, 1>> = ShapeSpecifier<Parts, typeof andSymbol>; | ||
export type AnyConstructor = new (...args: any[]) => any; | ||
export type ShapeClass<Parts extends [AnyConstructor]> = ShapeSpecifier<Parts, typeof classSymbol>; | ||
export type ShapeEnum<Parts extends Readonly<[Record<string, number | string>]>> = ShapeSpecifier<Parts, typeof enumSymbol>; | ||
export type ShapeExact<Parts extends Readonly<AtLeastTuple<unknown, 1>>> = ShapeSpecifier<Parts, typeof exactSymbol>; | ||
export type ShapeIndexedKeys<Parts extends Readonly<[ | ||
@@ -41,13 +68,15 @@ { | ||
export type ShapeOr<Parts extends AtLeastTuple<unknown, 1>> = ShapeSpecifier<Parts, typeof orSymbol>; | ||
export type ShapeAnd<Parts extends AtLeastTuple<unknown, 1>> = ShapeSpecifier<Parts, typeof andSymbol>; | ||
export type ShapeExact<Parts extends Readonly<AtLeastTuple<unknown, 1>>> = ShapeSpecifier<Parts, typeof exactSymbol>; | ||
export type ShapeEnum<Parts extends Readonly<[Record<string, number | string>]>> = ShapeSpecifier<Parts, typeof enumSymbol>; | ||
export type ShapeUnknown<Parts extends Readonly<[unknown]>> = ShapeSpecifier<Parts, typeof unknownSymbol>; | ||
type ExpandParts<Parts extends BaseParts, IsExact extends boolean, IsReadonly extends boolean> = Extract<ArrayElement<Parts>, ShapeDefinition<any, any>> extends never ? SpecifierToRunTimeType<ArrayElement<Parts>, IsExact, IsReadonly> : SpecifierToRunTimeType<Exclude<ArrayElement<Parts>, ShapeDefinition<any, any>>, IsExact, IsReadonly> | Extract<ArrayElement<Parts>, ShapeDefinition<any, any>>['runTimeType']; | ||
export type SpecifierToRunTimeType<PossiblySpecifier, IsExact extends boolean, IsReadonly extends boolean> = PossiblySpecifier extends ShapeSpecifier<infer Parts, infer Type> ? Type extends typeof andSymbol ? MaybeReadonly<IsReadonly, UnionToIntersection<ExpandParts<Parts, IsExact, IsReadonly>>> : Type extends typeof orSymbol ? MaybeReadonly<IsReadonly, ExpandParts<Parts, IsExact, IsReadonly>> : Type extends typeof exactSymbol ? MaybeReadonly<IsReadonly, WritableDeep<ExpandParts<Parts, true, IsReadonly>>> : Type extends typeof enumSymbol ? MaybeReadonly<IsReadonly, WritableDeep<Parts[0][keyof Parts[0]]>> : Type extends typeof indexedKeysSymbol ? Parts[0] extends { | ||
keys: unknown; | ||
values: unknown; | ||
} ? ExpandParts<[Parts[0]['keys']], IsExact, IsReadonly> extends PropertyKey ? MaybeReadonly<IsReadonly, Partial<Record<ExpandParts<[Parts[0]['keys']], IsExact, IsReadonly>, ExpandParts<[Parts[0]['values']], IsExact, IsReadonly>>>> : 'TypeError: indexedKeys keys be a subset of PropertyKey.' : 'TypeError: indexedKeys input is invalid.' : Type extends typeof unknownSymbol ? unknown : 'TypeError: found not match for shape specifier type.' : PossiblySpecifier extends Primitive ? IsExact extends true ? PossiblySpecifier : LiteralToPrimitive<PossiblySpecifier> : PossiblySpecifier extends object ? PossiblySpecifier extends ShapeDefinition<any, any> ? PossiblySpecifier['runTimeType'] : MaybeReadonly<IsReadonly, { | ||
[Prop in keyof PossiblySpecifier]: SpecifierToRunTimeType<PossiblySpecifier[Prop], IsExact, IsReadonly>; | ||
}> : PossiblySpecifier; | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Functions | ||
* | ||
* ======================================== | ||
*/ | ||
export declare function and<Parts extends AtLeastTuple<unknown, 1>>(...parts: Parts): ShapeAnd<Parts>; | ||
/** Define a shape that is an instance of the given class constructor. */ | ||
export declare function classShape<Parts extends [AnyConstructor]>(...parts: Parts): ShapeSpecifier<Parts, typeof classSymbol>; | ||
export declare function enumShape<const Parts extends Readonly<[Record<string, number | string>]>>(...parts: Parts): ShapeEnum<Parts>; | ||
export declare function exact<const Parts extends Readonly<AtLeastTuple<unknown, 1>>>(...parts: Parts): ShapeExact<Parts>; | ||
export declare function indexedKeys<Parts extends Readonly<[ | ||
@@ -60,6 +89,14 @@ { | ||
export declare function or<Parts extends AtLeastTuple<unknown, 1>>(...parts: Parts): ShapeOr<Parts>; | ||
export declare function and<Parts extends AtLeastTuple<unknown, 1>>(...parts: Parts): ShapeAnd<Parts>; | ||
export declare function exact<const Parts extends Readonly<AtLeastTuple<unknown, 1>>>(...parts: Parts): ShapeExact<Parts>; | ||
export declare function enumShape<const Parts extends Readonly<[Record<string, number | string>]>>(...parts: Parts): ShapeEnum<Parts>; | ||
export declare function unknownShape(defaultValue?: unknown): ShapeUnknown<[unknown]>; | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Specifier Type Guards | ||
* | ||
* ======================================== | ||
*/ | ||
export declare function isAndShapeSpecifier(maybeSpecifier: unknown): maybeSpecifier is ShapeAnd<AtLeastTuple<unknown, 1>>; | ||
export declare function isClassShapeSpecifier(maybeSpecifier: unknown): maybeSpecifier is ShapeClass<[AnyConstructor]>; | ||
export declare function isEnumShapeSpecifier(maybeSpecifier: unknown): maybeSpecifier is ShapeEnum<[Record<string, number | string>]>; | ||
export declare function isExactShapeSpecifier(maybeSpecifier: unknown): maybeSpecifier is ShapeExact<[unknown]>; | ||
export declare function isIndexedKeysSpecifier(maybeSpecifier: unknown): maybeSpecifier is ShapeIndexedKeys<Readonly<[ | ||
@@ -72,8 +109,17 @@ { | ||
export declare function isOrShapeSpecifier(maybeSpecifier: unknown): maybeSpecifier is ShapeOr<AtLeastTuple<unknown, 1>>; | ||
export declare function isAndShapeSpecifier(maybeSpecifier: unknown): maybeSpecifier is ShapeAnd<AtLeastTuple<unknown, 1>>; | ||
export declare function isExactShapeSpecifier(maybeSpecifier: unknown): maybeSpecifier is ShapeExact<[unknown]>; | ||
export declare function isEnumShapeSpecifier(maybeSpecifier: unknown): maybeSpecifier is ShapeEnum<[Record<string, number | string>]>; | ||
export declare function isUnknownShapeSpecifier(maybeSpecifier: unknown): maybeSpecifier is ShapeUnknown<[unknown]>; | ||
export declare function specifierHasSymbol(maybeSpecifier: unknown, symbol: ShapeSpecifierType): boolean; | ||
export declare function specifier<Parts extends BaseParts, Type extends ShapeSpecifierType>(parts: Parts, specifierType: Type): ShapeSpecifier<Parts, Type>; | ||
/** | ||
* ======================================== | ||
* | ||
* Shape Value Run Time Type | ||
* | ||
* ======================================== | ||
*/ | ||
type ExpandParts<Parts extends BaseParts, IsExact extends boolean, IsReadonly extends boolean> = Extract<ArrayElement<Parts>, ShapeDefinition<any, any>> extends never ? SpecifierToRunTimeType<ArrayElement<Parts>, IsExact, IsReadonly> : SpecifierToRunTimeType<Exclude<ArrayElement<Parts>, ShapeDefinition<any, any>>, IsExact, IsReadonly> | Extract<ArrayElement<Parts>, ShapeDefinition<any, any>>['runTimeType']; | ||
export type SpecifierToRunTimeType<PossiblySpecifier, IsExact extends boolean, IsReadonly extends boolean> = PossiblySpecifier extends ShapeSpecifier<infer Parts, infer Type> ? Type extends typeof andSymbol ? MaybeReadonly<IsReadonly, UnionToIntersection<ExpandParts<Parts, IsExact, IsReadonly>>> : Type extends typeof classSymbol ? Parts[0] extends AnyConstructor ? MaybeReadonly<IsReadonly, InstanceType<Parts[0]>> : 'TypeError: classShape input must be a constructor.' : Type extends typeof orSymbol ? MaybeReadonly<IsReadonly, ExpandParts<Parts, IsExact, IsReadonly>> : Type extends typeof exactSymbol ? MaybeReadonly<IsReadonly, WritableDeep<ExpandParts<Parts, true, IsReadonly>>> : Type extends typeof enumSymbol ? MaybeReadonly<IsReadonly, WritableDeep<Parts[0][keyof Parts[0]]>> : Type extends typeof indexedKeysSymbol ? Parts[0] extends { | ||
keys: unknown; | ||
values: unknown; | ||
} ? ExpandParts<[Parts[0]['keys']], IsExact, IsReadonly> extends PropertyKey ? MaybeReadonly<IsReadonly, Partial<Record<ExpandParts<[Parts[0]['keys']], IsExact, IsReadonly>, ExpandParts<[Parts[0]['values']], IsExact, IsReadonly>>>> : 'TypeError: indexedKeys keys be a subset of PropertyKey.' : 'TypeError: indexedKeys input is invalid.' : Type extends typeof unknownSymbol ? unknown : 'TypeError: found not match for shape specifier type.' : PossiblySpecifier extends Primitive ? IsExact extends true ? PossiblySpecifier : LiteralToPrimitive<PossiblySpecifier> : PossiblySpecifier extends object ? PossiblySpecifier extends ShapeDefinition<any, any> ? PossiblySpecifier['runTimeType'] : MaybeReadonly<IsReadonly, { | ||
[Prop in keyof PossiblySpecifier]: SpecifierToRunTimeType<PossiblySpecifier[Prop], IsExact, IsReadonly>; | ||
}> : PossiblySpecifier; | ||
type MaybeReadonly<IsReadonly extends boolean, OriginalType> = IsReadonly extends true ? Readonly<OriginalType> : OriginalType; | ||
@@ -83,4 +129,13 @@ export type ShapeToRunTimeType<Shape, IsExact extends boolean, IsReadonly extends boolean> = Shape extends Function ? Shape : Shape extends object ? Shape extends ShapeDefinition<infer InnerShape, any> ? ShapeToRunTimeType<InnerShape, IsExact, IsReadonly> : Shape extends ShapeSpecifier<any, any> ? Shape extends ShapeSpecifier<any, typeof exactSymbol> ? SpecifierToRunTimeType<Shape, true, IsReadonly> : SpecifierToRunTimeType<Shape, IsExact, IsReadonly> : MaybeReadonly<IsReadonly, { | ||
}> : Shape; | ||
/** | ||
* ======================================== | ||
* | ||
* Specifier Utilities | ||
* | ||
* ======================================== | ||
*/ | ||
export declare function specifierHasSymbol(maybeSpecifier: unknown, symbol: ShapeSpecifierType): boolean; | ||
export declare function specifier<Parts extends BaseParts, Type extends ShapeSpecifierType>(parts: Parts, specifierType: Type): ShapeSpecifier<Parts, Type>; | ||
export declare function matchesSpecifier(subject: unknown, shape: unknown, allowExtraKeys?: boolean | undefined): boolean; | ||
export declare function getShapeSpecifier(input: unknown): ShapeSpecifier<BaseParts, ShapeSpecifierType> | undefined; | ||
export {}; |
@@ -1,3 +0,3 @@ | ||
export declare class ShapeMismatchError extends Error { | ||
export declare class ShapeMismatchError extends TypeError { | ||
name: string; | ||
} |
{ | ||
"name": "object-shape-tester", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "Test object properties and value types.", | ||
@@ -39,13 +39,13 @@ "keywords": [], | ||
"dependencies": { | ||
"@augment-vir/common": "^23.0.0", | ||
"type-fest": "^4.9.0" | ||
"@augment-vir/common": "^23.2.0", | ||
"type-fest": "^4.10.2" | ||
}, | ||
"devDependencies": { | ||
"@augment-vir/browser": "^23.0.0", | ||
"@augment-vir/browser-testing": "^23.0.0", | ||
"@augment-vir/node-js": "^23.0.0", | ||
"@augment-vir/browser": "^23.2.0", | ||
"@augment-vir/browser-testing": "^23.2.0", | ||
"@augment-vir/node-js": "^23.2.0", | ||
"@open-wc/testing": "^4.0.0", | ||
"@types/chai": "^4.3.11", | ||
"@types/mocha": "^10.0.6", | ||
"@web/dev-server-esbuild": "^1.0.1", | ||
"@web/dev-server-esbuild": "^1.0.2", | ||
"@web/test-runner": "^0.18.0", | ||
@@ -57,4 +57,4 @@ "@web/test-runner-commands": "^0.9.0", | ||
"cspell": "^8.3.2", | ||
"dependency-cruiser": "^16.0.0", | ||
"esbuild": "^0.19.11", | ||
"dependency-cruiser": "^16.2.0", | ||
"esbuild": "^0.20.0", | ||
"istanbul-smart-text-reporter": "^1.1.3", | ||
@@ -66,9 +66,9 @@ "markdown-code-example-inserter": "^0.3.3", | ||
"prettier-plugin-jsdoc": "^1.3.0", | ||
"prettier-plugin-multiline-arrays": "^3.0.1", | ||
"prettier-plugin-multiline-arrays": "^3.0.3", | ||
"prettier-plugin-organize-imports": "^3.2.4", | ||
"prettier-plugin-packagejson": "^2.4.9", | ||
"prettier-plugin-packagejson": "^2.4.10", | ||
"prettier-plugin-sort-json": "^3.1.0", | ||
"prettier-plugin-toml": "^2.0.1", | ||
"run-time-assertions": "^0.3.0", | ||
"typedoc": "^0.25.7", | ||
"typedoc": "^0.25.8", | ||
"typescript": "^5.3.3", | ||
@@ -75,0 +75,0 @@ "virmator": "^11.3.1", |
69337
29
1331
Updated@augment-vir/common@^23.2.0
Updatedtype-fest@^4.10.2