UNPKG

@freeword/meta

Version:

Meta package for Freeword: exports all core types, constants, and utilities from the src/ directory.

181 lines (163 loc) 9.87 kB
import _ /**/ from 'lodash' // import type { Zcasted, Zsketch, ZodType, ZodArray, ZodTypeAny, ZodPipeline, ZodRawShape, ZodAny, ZodReadonly, ZodEnum, ZodEffects, ZodUnion, ZodTuple, Zchecker, } from '../validation/ZodInternal.js' import { checknameFor, Z } from '../validation/ZodInternal.js' import type { ArrNZ, NotNil, NotUnd } from '../types/TSTools.ts' import * as CO from '../Consts.ts' import { inspectify } from '../utils/UF.ts' // export type { Zcasted, Zsketch, Zobcasted, Zobsketch, ZodType, Zensure, ZodArray, ZodTypeAny, ZodPipeline, ZodString, ZodRawShape, ZodAny, ZodReadonly, ZodEnum, ZodCtx, ZodObject, } from '../validation/ZodInternal.ts' export { Z, zShape, ZodIssueCode, FailedTransform, FailedRefine, } from '../validation/ZodInternal.ts' /* eslint-disable prefer-destructuring */ export function isNotund(val: any): val is NotUnd { return (val !== undefined) } export function isNotnil(val: any): val is NotNil { if (val) { return true } return (! _.isNil(val)) } export const custom = Z.custom // ; const customR = custom // export const notund = custom(isNotund, 'defined or null').describe('any value or null') as ZodType<NotUnd> export const notnil = custom(isNotnil, 'non-nil').describe('any non-absent value') as ZodType<NotNil> export const anything = Z.any().describe('any') export const unk = Z.unknown().describe('non-nil') export const idk = notnil as ZodAny // Primitives export const bool = Z.boolean() export const regexp = Z.instanceof(RegExp) export const jsdate = Z.date() export const num = Z.number() export const safenum = Z.number().min(CO.SAFEINT.min).max(CO.SAFEINT.max) export const str = Z.string() export const anybag = Z.record(str, anything) export const idkbag = Z.record(str, idk) export const unkbag = Z.record(str, unk) export const bareint = Z.number().int() export const safeint = safenum.int() export const bigint = Z.bigint() export const znever = Z.never() // ZMakers // export const arr = Z.array export const bag = Z.record export const jsmap = Z.map export const jsset = Z.set export const jssym = Z.symbol export const lazy = Z.lazy export const literal = Z.literal export const obj = Z.object export const oneof = Z.enum export const tuple = Z.tuple export const typish = Z.instanceof export const union = Z.union export const cases = Z.discriminatedUnion export const preprocess = Z.preprocess export const coerce = Z.coerce export const instance = Z.instanceof export const promise = Z.promise // export const func0args: ZodType<() => any> = custom(_.isFunction, 'should be a 0-arg Function').describe('func0args') as ZodType<() => any> export const func1arg: ZodType<(val: any) => any> = custom(_.isFunction, 'should be a 1-arg Function').describe('func1arg') as ZodType<(val: any) => any> export const funcPassthru: ZodType<<XT>(val: XT) => XT> = custom(_.isFunction, 'should be a passthru Function').describe('funcPassthru') as ZodType<<XT>(val: XT) => XT> export const funcAnyargs: ZodType<(...args: any[]) => any> = custom(_.isFunction, 'should be a Function').describe('funcAnyargs') as ZodType<(...args: any[]) => any> export const func = funcAnyargs // type BagIterFunc = (val: any, key: string, ...args: any[]) => any // seq: number, clxn: Record<string, any>) => any type ArrIterFunc = (val: any, key: number, ...args: any[]) => any // seq: number, clxn: any[]) => any type EitherIterFunc = BagIterFunc | ArrIterFunc export const iterfunc = (custom(_.isFunction, 'should be a (val,key,num,clxn)=>any Function').describe('Collection Function')) as ZodType<EitherIterFunc> // interface Bob { foo: EitherIterFunc } ; const bob: Bob = { foo(val: boolean, key, seq, clxn: Record<number | string, string>): any { return val } } // // export const notund = Z.unknown().nullable().describe('any present-or-null value') // export const notnil = Z.unknown().describe('any non-absent value') // export const notnull = Z.unknown().or(Z.undefined()).describe('unset or non-null') // const demo = obj({ anything, unk, notnull, notnil, notund }) // export type Dicks = Zcasted<typeof demo> // const xx = undefined // const yy: Dicks = { anything: xx, unk: xx, notnull: xx, notnil: xx, notund: xx } // function onUnd(xx1: undefined): Dicks { return { anything: xx, unk: xx, notnull: xx, notnil: xx, notund: xx } } // function noNonNull(xx: NonNull) { return { anything: xx, unk: xx, notnull: xx, notnil: xx, notund: xx } } // function noNonNil(xx: NonNull) { return xx } // function tryit(xx: undefined) { return [noNonNull(xx), noNonNil(xx), noNonNull(xx)]} export function arrNZROCk<NT extends ZodTypeAny>(check: NT): ZodReadonly<ZodArray<NT, 'atleastone'>> { return arr(check).nonempty().readonly() } export function arrROCk<NT extends ZodTypeAny>(check: NT): ZodReadonly<ZodArray<NT>> { return arr(check).readonly() } export function arrNZCk<NT extends ZodTypeAny>(check: NT): ZodArray<NT, 'atleastone'> { return arr(check).nonempty() } export type Zenum<ET extends string = string> = ZodEnum<ArrNZ<ET>> export type Zbag<ZKT extends ZodTypeAny, ZVT extends ZodTypeAny> = ZodType<Record<Zcasted<ZKT> & string, Zcasted<ZVT>>, any, Record<Zsketch<ZKT> & string, Zsketch<ZVT>>> export type PartialZbag<ZKT extends ZodTypeAny, ZVT extends ZodTypeAny> = ZodType<Partial<Record<Zcasted<ZKT> & string, Zcasted<ZVT>>>, any, Partial<Record<Zsketch<ZKT> & string, Zsketch<ZVT>>>> /** * Check that all keys in the bag belong to the keyCK * does not check that the bag covers all keys in the enum, * returned type is Partial<Record<ZKT, ZVT>> */ export function bagWithKeys<ZKT extends ZodTypeAny, ZVT extends ZodTypeAny>(keyCK: ZKT, itemCk: ZVT): Zbag<ZKT, ZVT> { const ck = bag(itemCk).refine((boxenbag) => (_.every(_.keys(boxenbag), (key) => (_.isString(key) && keyCK.check(key))))) return ck as Zbag<ZKT, ZVT> } export function bagWithSomeKeys<ZKT extends ZodTypeAny, ZVT extends ZodTypeAny>(keyCK: ZKT, itemCk: ZVT): PartialZbag<ZKT, ZVT> { return bagWithKeys(keyCK, itemCk) as PartialZbag<ZKT, ZVT> } export function bagWithAllKeys<ZKT extends ZodTypeAny, ZVT extends ZodTypeAny>(keyCK: ZKT, itemCk: ZVT): Zbag<ZKT, ZVT> { return bagWithKeys(keyCK, itemCk) } // /** // * Check that all keys in the bag belong to the keyCK // * and that the bag covers all keys in the enum // * the return type is incorrect, it should be the all-keys bag but is a Partial<Record<ZKT, ZVT>> // */ // export function bagWithAllKeys<ZKT extends ZodTypeAny, ZVT extends ZodTypeAny>(keyCK: ZKT, itemCk: ZVT): Zbag<ZKT, ZVT> { // const ck = bag(itemCk).refine((boxenbag) => (_.every(boxenbag, (_item, key) => (_.isString(key) && keyCK.check(key))))) // return ck as Zbag<ZKT, ZVT> // } function __splitStr<ZT extends ZodTypeAny>(ck: ZT, sep: string | RegExp = /\W+/g): ZodPipeline<ZodEffects<any, string[], string>, ZodArray<ZT>> { return str.transform((val) => _.filter(val.split(sep))).pipe(arr(ck)) } export function splitStr<ZT extends ZodTypeAny>(ck: ZT, sep?: string | RegExp | undefined): ZodUnion<[ZodPipeline<ZodEffects<any, string[], string>, ZodArray<ZT>>, ZodArray<ZT>]> { return union([__splitStr(ck, sep), arr(ck)]) } export function oneOrMany<ZT extends ZodTypeAny>(ck: ZT): ZodEffects<ZodArray<ZT, "many">, ZT["_output"][], unknown> { return preprocess((val) => (_.isArray(val) ? val : [val]), arr(ck), { message: `should be one or many of ${checknameFor(ck)}` }) } /** * due to the difficulty of determining if items have a default value, * you must put .optional() or .default() on the items you want to be optional. * Also, this may not respond to .items or other features of ZodTuple; * but for it to type correctly, we are coercing it to the effective type. */ export function tupleOptionals<TT extends [ZodTypeAny, ...ZodTypeAny[]]>(schemas: TT): ZodTuple<TT, null> { return arr(anything) .transform((vals) => padToLength(vals, schemas.length)) .pipe(tuple(schemas)) as unknown as ZodTuple<TT, null> } function padToLength<ElT>(existing: readonly ElT[], length: number): (ElT | undefined)[] { const extras = (existing.length >= length) ? [] : Array(length - existing.length).fill(undefined) return existing.concat(extras) } type ZNumMakerParams = Parameters<typeof Z.number>[0] export function among(vals: any[], params: ZNumMakerParams = {}) { const valset = new Set(vals) const valstr = vals.map((val) => inspectify(val)).join('|') const message = params.message || `Value should be one of: ${valstr}` return Z.number(params).refine((value) => valset.has(value), { message }) } // const amongR = among export const ZPrims = { bool, str, anybag, idk, regexp, jsdate, znever, num, safenum, bareint, safeint, idkbag, unk, unkbag, notund, notnil, func, func0args, funcAnyargs, } as const satisfies ZodRawShape export const ZMakers = { among, arr, bag, jsmap, jsset, jssym, obj, oneof, tuple, znever, custom, lazy, literal, union, cases, coerce, typish, preprocess, instance, oneOrMany, arrROCk, arrNZCk, arrNZROCk, promise, bagWithKeys, bagWithAllKeys, bagWithSomeKeys, splitStr, tupleOptionals, } as const export type ZMakersT = typeof ZMakers