UNPKG

object-shape-tester

Version:
55 lines (54 loc) 1.72 kB
import { check } from '@augment-vir/assert'; import { wrapString } from '@augment-vir/common'; import { Kind, Type, TypeRegistry } from '@sinclair/typebox'; import { registerErrorMessage } from '../errors/error-message.js'; import { defineShape } from '../shape/shape.js'; /** * Creates a shape that requires matching the exact value give. * * @category Shape * @example * * ```ts * import {exactShape, checkValidShape} from 'object-shape-tester'; * * const myShape = exactShape('a'); * * checkValidShape('a', myShape); // `true` * checkValidShape('c', myShape); // `false` * * // normally passing a string to a shape will simplify the shape. * checkValidShape('c', defineShape('a')); // `true` * ``` */ export function exactShape(value) { if (check.isSymbol(value)) { return exactSymbolShape(value); } return defineShape(Type.Const(value, { default: value })); } /** * Kind for {@link exactShape}'s type registry entry when the value given to {@link exactShape} is a * symbol. * * @category Internal */ export const exactSymbolKind = 'ExactSymbol'; function exactSymbolShape(value) { if (!TypeRegistry.Has(exactSymbolKind)) { TypeRegistry.Set(exactSymbolKind, (schema, value) => { return value === schema.symbol; }); } registerErrorMessage(exactSymbolKind, ({ schema }) => { const symbolDescription = schema.symbol?.description ? wrapString({ value: schema.symbol.description, wrapper: "'" }) : '<unnamed symbol>'; return `Expected symbol ${symbolDescription}`; }); return defineShape(Type.Unsafe({ [Kind]: exactSymbolKind, symbol: value, default: value, })); }