import type { IDtoVerify, IDtoMeta, IDtoFuncBase } from "./types" function defineDtoBase(type: string, verify: IDtoVerify) { const dtoFunc = (meta: IDtoMeta) => { return { type, meta, __isDto__: true, } } const dtoVerify = { type, verify, } return { dtoFunc: >(dtoFunc), dtoVerify, } } // ======== Number ============================================================ export const { dtoFunc: DtoNumber, dtoVerify: DtoVerifyNumber } = defineDtoBase< number, { /** 限制最大值 */ max?: number /** 限制最小值 */ min?: number } >("number", (val, dto, meta) => { if (typeof val !== "number") return { isOk: false } if (meta?.max !== undefined && val > meta.max) { return { msg: `out of range: ${val}>${meta?.max}.`, isOk: false, } } if (meta?.min !== undefined && val < meta.min) { return { msg: `out of range: ${val}<${meta?.min}.`, isOk: false, } } return { isOk: true } }) // ======== String ============================================================ export const { dtoFunc: DtoString, dtoVerify: DtoVerifyString } = defineDtoBase< string, { /** 限制最大值,会转换为数字 */ max?: number /** 限制最小值,会转换为数字 */ min?: number /** 限制最大长度 */ maxLength?: number /** 限制最小长度 */ minLength?: number } >("string", (val, dto, meta) => { if (typeof val !== "string") return { isOk: false } if (meta?.max !== undefined && Number.parseFloat(val) > meta.max) { return { msg: `out of range: ${val}>${meta?.max}.`, isOk: false } } if (meta?.min !== undefined && Number.parseFloat(val) < meta.min) { return { msg: `out of range: ${val}<${meta?.min}.`, isOk: false } } if (meta?.maxLength !== undefined && val.length > meta.maxLength) { return { msg: `string length out of range: ${val.length}>${meta?.maxLength}.`, isOk: false, } } if (meta?.minLength !== undefined && val.length < meta.minLength) { return { msg: `string length out of range: ${val.length}<${meta?.minLength}.`, isOk: false, } } return { isOk: true } }) // ======== Boolean ============================================================ export const { dtoFunc: DtoBoolean, dtoVerify: DtoVerifyBoolean } = defineDtoBase( "boolean", (val, dto, meta) => { if (typeof val !== "boolean") return { isOk: false } return { isOk: true } } ) // ======== BigInt ============================================================ export const { dtoFunc: DtoBigInt, dtoVerify: DtoVerifyBigInt } = defineDtoBase< bigint, { /** 限制最大值(bigint 或 number) */ max?: bigint | number /** 限制最小值(bigint 或 number) */ min?: bigint | number } >("bigint", (val, dto, meta) => { if (typeof val !== "bigint") return { isOk: false } if (meta?.max !== undefined) { const maxB = typeof meta.max === "bigint" ? meta.max : BigInt(Math.trunc(meta.max as number)) if (val > maxB) { return { msg: `out of range: ${val}>${maxB}.`, isOk: false } } } if (meta?.min !== undefined) { const minB = typeof meta.min === "bigint" ? meta.min : BigInt(Math.trunc(meta.min as number)) if (val < minB) { return { msg: `out of range: ${val}<${minB}.`, isOk: false } } } return { isOk: true } }) // ======== Date ============================================================= export const { dtoFunc: DtoDate, dtoVerify: DtoVerifyDate } = defineDtoBase< Date, { /** 限制最大时间(Date 或 时间戳 number 毫秒) */ max?: Date | number /** 限制最小时间(Date 或 时间戳 number 毫秒) */ min?: Date | number } >("Date", (val, dto, meta) => { if (!(val instanceof Date)) return { isOk: false } const t = val.getTime() if (Number.isNaN(t)) return { isOk: false, msg: "invalid Date" } if (meta?.max !== undefined) { const maxT = meta.max instanceof Date ? meta.max.getTime() : Number(meta.max) if (!Number.isNaN(maxT) && t > maxT) { return { msg: `out of range: ${t}>${maxT}.`, isOk: false } } } if (meta?.min !== undefined) { const minT = meta.min instanceof Date ? meta.min.getTime() : Number(meta.min) if (!Number.isNaN(minT) && t < minT) { return { msg: `out of range: ${t}<${minT}.`, isOk: false } } } return { isOk: true } }) // ======== Null ============================================================== export const { dtoFunc: DtoNull, dtoVerify: DtoVerifyNull } = defineDtoBase("null", (val, dto, meta) => { if (val !== null) return { isOk: false } return { isOk: true } }) // ======== Any ============================================================== export const { dtoFunc: DtoAny, dtoVerify: DtoVerifyAny } = defineDtoBase("any", (val, dto, meta) => { return { isOk: true } })