jet-schema
Advanced tools
Comparing version 1.1.5 to 1.2.0
import jetSchema from './jetSchema'; | ||
export type { TSchemaFnObjArg as TJetSchema, PublicInferType as inferType, } from './jetSchema'; | ||
export { transform, setDefault } from './util'; | ||
export declare const schema: <T, U extends Required<{ [K in keyof T]: T[K] extends string | number ? import("./util").TEnum | import("./util").IValidatorFn<T[K]> : T[K] extends Date ? DateConstructor | import("./util").IValidatorFn<T[K]> : ((NonNullable<T[K]> extends infer T_1 ? { [K_1 in keyof T_1]: NonNullable<T[K]>[K_1]; } : never) extends (string extends keyof NonNullable<T[K]> ? never : { | ||
export declare const schema: <T, U extends Required<{ [K in keyof T]: T[K] extends string | number ? import("./util").TEnum | import("./util").IValidatorFnOrObj<T[K]> : T[K] extends Date ? DateConstructor | import("./util").IValidatorFnOrObj<T[K]> : ((NonNullable<T[K]> extends infer T_1 ? { [K_1 in keyof T_1]: NonNullable<T[K]>[K_1]; } : never) extends (string extends keyof NonNullable<T[K]> ? never : { | ||
[key: string]: string | number | boolean | (string extends keyof NonNullable<T[K]> ? never : any); | ||
}) ? true : false) extends true ? import("./jetSchema").ISchema<T[K]> : import("./util").IValidatorFn<T[K]>; }> = Required<{ [K in keyof T]: T[K] extends string | number ? import("./util").TEnum | import("./util").IValidatorFn<T[K]> : T[K] extends Date ? DateConstructor | import("./util").IValidatorFn<T[K]> : ((NonNullable<T[K]> extends infer T_1 ? { [K_1 in keyof T_1]: NonNullable<T[K]>[K_1]; } : never) extends (string extends keyof NonNullable<T[K]> ? never : { | ||
}) ? true : false) extends true ? import("./jetSchema").ISchema<T[K]> : import("./util").IValidatorFnOrObj<T[K]>; }> = Required<{ [K in keyof T]: T[K] extends string | number ? import("./util").TEnum | import("./util").IValidatorFnOrObj<T[K]> : T[K] extends Date ? DateConstructor | import("./util").IValidatorFnOrObj<T[K]> : ((NonNullable<T[K]> extends infer T_1 ? { [K_1 in keyof T_1]: NonNullable<T[K]>[K_1]; } : never) extends (string extends keyof NonNullable<T[K]> ? never : { | ||
[key: string]: string | number | boolean | (string extends keyof NonNullable<T[K]> ? never : any); | ||
}) ? true : false) extends true ? import("./jetSchema").ISchema<T[K]> : import("./util").IValidatorFn<T[K]>; }>, R extends unknown extends T ? import("./jetSchema").IOptNul | import("./jetSchema").IOptNotNul | import("./jetSchema").INotOptButNul | import("./jetSchema").INotOptOrNul | import("./jetSchema").INullish : undefined extends T ? null extends T ? import("./jetSchema").IOptNul | import("./jetSchema").INullish : import("./jetSchema").IOptNotNul : null extends T ? import("./jetSchema").INotOptButNul : import("./jetSchema").INotOptOrNul = unknown extends T ? import("./jetSchema").IOptNul | import("./jetSchema").IOptNotNul | import("./jetSchema").INotOptButNul | import("./jetSchema").INotOptOrNul | import("./jetSchema").INullish : undefined extends T ? null extends T ? import("./jetSchema").IOptNul | import("./jetSchema").INullish : import("./jetSchema").IOptNotNul : null extends T ? import("./jetSchema").INotOptButNul : import("./jetSchema").INotOptOrNul>(schemaFnObjArg: U, ...options: unknown extends T ? [] | [R] : undefined extends T ? [R] : null extends T ? [R] : [] | [R]) => unknown extends T ? import("./jetSchema").ISchema<"nullish" extends keyof R ? NonNullable<Exclude<{ [K_3 in keyof { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }]-?: (x: undefined extends { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3] ? Partial<Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>> : Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>) => void; }[keyof U] extends (x: infer I) => void ? I extends infer U_1 ? { [K_4 in keyof U_1]: U_1[K_4]; } : never : never, undefined>> | null | undefined : ("optional" extends keyof R ? R[keyof R & "optional"] : false) extends infer T_2 ? T_2 extends ("optional" extends keyof R ? R[keyof R & "optional"] : false) ? T_2 extends true ? (("nullable" extends keyof R ? R[keyof R & "nullable"] : false) extends infer T_3 ? T_3 extends ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) ? T_3 extends true ? NonNullable<Exclude<{ [K_3 in keyof { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }]-?: (x: undefined extends { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3] ? Partial<Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>> : Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>) => void; }[keyof U] extends (x: infer I) => void ? I extends infer U_1 ? { [K_4 in keyof U_1]: U_1[K_4]; } : never : never, undefined>> | null : NonNullable<Exclude<{ [K_3 in keyof { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }]-?: (x: undefined extends { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3] ? Partial<Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>> : Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>) => void; }[keyof U] extends (x: infer I) => void ? I extends infer U_1 ? { [K_4 in keyof U_1]: U_1[K_4]; } : never : never, undefined>> : never : never) | undefined : ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) extends infer T_3 ? T_3 extends ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) ? T_3 extends true ? NonNullable<Exclude<{ [K_3 in keyof { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }]-?: (x: undefined extends { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3] ? Partial<Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>> : Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>) => void; }[keyof U] extends (x: infer I) => void ? I extends infer U_1 ? { [K_4 in keyof U_1]: U_1[K_4]; } : never : never, undefined>> | null : NonNullable<Exclude<{ [K_3 in keyof { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }]-?: (x: undefined extends { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3] ? Partial<Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>> : Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFn<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>) => void; }[keyof U] extends (x: infer I) => void ? I extends infer U_1 ? { [K_4 in keyof U_1]: U_1[K_4]; } : never : never, undefined>> : never : never : never : never> : import("./jetSchema").ISchema<T>; | ||
}) ? true : false) extends true ? import("./jetSchema").ISchema<T[K]> : import("./util").IValidatorFnOrObj<T[K]>; }>, R extends unknown extends T ? import("./jetSchema").IOptNul | import("./jetSchema").IOptNotNul | import("./jetSchema").INotOptButNul | import("./jetSchema").INotOptOrNul | import("./jetSchema").INullish : undefined extends T ? null extends T ? import("./jetSchema").IOptNul | import("./jetSchema").INullish : import("./jetSchema").IOptNotNul : null extends T ? import("./jetSchema").INotOptButNul : import("./jetSchema").INotOptOrNul = unknown extends T ? import("./jetSchema").IOptNul | import("./jetSchema").IOptNotNul | import("./jetSchema").INotOptButNul | import("./jetSchema").INotOptOrNul | import("./jetSchema").INullish : undefined extends T ? null extends T ? import("./jetSchema").IOptNul | import("./jetSchema").INullish : import("./jetSchema").IOptNotNul : null extends T ? import("./jetSchema").INotOptButNul : import("./jetSchema").INotOptOrNul>(schemaFnObjArg: U, ...options: unknown extends T ? [] | [R] : undefined extends T ? [R] : null extends T ? [R] : [] | [R]) => unknown extends T ? import("./jetSchema").ISchema<"nullish" extends keyof R ? NonNullable<Exclude<{ [K_3 in keyof { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }]-?: (x: undefined extends { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3] ? Partial<Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>> : Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>) => void; }[keyof U] extends (x: infer I) => void ? I extends infer U_1 ? { [K_4 in keyof U_1]: U_1[K_4]; } : never : never, undefined>> | null | undefined : ("optional" extends keyof R ? R[keyof R & "optional"] : false) extends infer T_2 ? T_2 extends ("optional" extends keyof R ? R[keyof R & "optional"] : false) ? T_2 extends true ? (("nullable" extends keyof R ? R[keyof R & "nullable"] : false) extends infer T_3 ? T_3 extends ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) ? T_3 extends true ? NonNullable<Exclude<{ [K_3 in keyof { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }]-?: (x: undefined extends { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3] ? Partial<Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>> : Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>) => void; }[keyof U] extends (x: infer I) => void ? I extends infer U_1 ? { [K_4 in keyof U_1]: U_1[K_4]; } : never : never, undefined>> | null : NonNullable<Exclude<{ [K_3 in keyof { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }]-?: (x: undefined extends { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3] ? Partial<Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>> : Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>) => void; }[keyof U] extends (x: infer I) => void ? I extends infer U_1 ? { [K_4 in keyof U_1]: U_1[K_4]; } : never : never, undefined>> : never : never) | undefined : ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) extends infer T_3 ? T_3 extends ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) ? T_3 extends true ? NonNullable<Exclude<{ [K_3 in keyof { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }]-?: (x: undefined extends { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3] ? Partial<Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>> : Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>) => void; }[keyof U] extends (x: infer I) => void ? I extends infer U_1 ? { [K_4 in keyof U_1]: U_1[K_4]; } : never : never, undefined>> | null : NonNullable<Exclude<{ [K_3 in keyof { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }]-?: (x: undefined extends { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3] ? Partial<Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>> : Record<K_3, { [K_2 in keyof U]: U[K_2] extends DateConstructor ? Date : U[K_2] extends import("./util").IValidatorFnOrObj<infer X> ? X : U[K_2] extends import("./jetSchema").ISchema<infer X_1> ? X_1 : U[K_2] extends unknown[] ? never : U[K_2] extends import("./util").TEnum ? U[K_2][keyof U[K_2]] : never; }[K_3]>) => void; }[keyof U] extends (x: infer I) => void ? I extends infer U_1 ? { [K_4 in keyof U_1]: U_1[K_4]; } : never : never, undefined>> : never : never : never : never> : import("./jetSchema").ISchema<T>; | ||
export default jetSchema; |
@@ -6,9 +6,6 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.schema = exports.setDefault = exports.transform = void 0; | ||
exports.schema = void 0; | ||
const jetSchema_1 = __importDefault(require("./jetSchema")); | ||
var util_1 = require("./util"); | ||
Object.defineProperty(exports, "transform", { enumerable: true, get: function () { return util_1.transform; } }); | ||
Object.defineProperty(exports, "setDefault", { enumerable: true, get: function () { return util_1.setDefault; } }); | ||
exports.schema = (0, jetSchema_1.default)(); | ||
exports.default = jetSchema_1.default; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
import { TFunc, IValidatorFn, TEnum } from './util'; | ||
import { TFunc, IValidatorFnOrObj, TEnum, IValidatorObj, TValidatorFn } from './util'; | ||
type TStaticObj<Prop> = string extends keyof Prop ? never : { | ||
@@ -14,8 +14,2 @@ [key: string]: string | number | boolean | TStaticObj<Prop>; | ||
type TOnError = (property: string, value?: unknown, origMessage?: string, schemaId?: string) => void; | ||
type TDefaultValsMap<T> = { | ||
[K in keyof T]: { | ||
0: ((arg: unknown) => arg is unknown); | ||
1: 0 extends keyof T[K] ? GetTypePredicate<T[K][0]> : never; | ||
}; | ||
}; | ||
type TPickRetVal<T, NnT = NonNullable<T>> = { | ||
@@ -42,9 +36,18 @@ test: (arg: unknown) => arg is T; | ||
export type TSchemaFnObjArg<T> = Required<{ | ||
[K in keyof T]: (T[K] extends (string | number) ? (IValidatorFn<T[K]> | TEnum) : T[K] extends Date ? (DateConstructor | IValidatorFn<T[K]>) : IsStaticObj<T[K]> extends true ? ISchema<T[K]> : IValidatorFn<T[K]>); | ||
[K in keyof T]: (T[K] extends (string | number) ? (IValidatorFnOrObj<T[K]> | TEnum) : T[K] extends Date ? (DateConstructor | IValidatorFnOrObj<T[K]>) : IsStaticObj<T[K]> extends true ? ISchema<T[K]> : IValidatorFnOrObj<T[K]>); | ||
}>; | ||
interface IJetOptions<M> { | ||
defaultValuesMap?: M extends [TFunc, unknown][] ? M : never; | ||
globals?: M extends IValidatorObj<unknown>[] ? M : never; | ||
cloneFn?: (value: unknown) => unknown; | ||
onError?: TOnError; | ||
} | ||
type TGlobalsArr<M> = { | ||
[K in keyof M]: { | ||
fn: TValidatorFn<unknown>; | ||
} & ('fn' extends keyof M[K] ? { | ||
default?: GetTypePredicate<M[K]['fn']>; | ||
transform?: TFunc; | ||
onError?: IValidatorObj<unknown>['onError']; | ||
} : never); | ||
}; | ||
type TSchemaOptions<T> = (unknown extends T ? (IOptNul | IOptNotNul | INotOptButNul | INotOptOrNul | INullish) : (undefined extends T ? (null extends T ? (IOptNul | INullish) : IOptNotNul) : (null extends T ? INotOptButNul : INotOptOrNul))); | ||
@@ -60,3 +63,3 @@ type TSchemaOptionsHelper<T, R> = (unknown extends T ? ([] | [R]) : undefined extends T ? [R] : null extends T ? [R] : ([] | [R])); | ||
type InferTypesHelper<U> = { | ||
[K in keyof U]: (U[K] extends DateConstructor ? Date : U[K] extends IValidatorFn<infer X> ? X : U[K] extends ISchema<infer X> ? X : U[K] extends unknown[] ? never : U[K] extends TEnum ? U[K][keyof U[K]] : never); | ||
[K in keyof U]: (U[K] extends DateConstructor ? Date : U[K] extends IValidatorFnOrObj<infer X> ? X : U[K] extends ISchema<infer X> ? X : U[K] extends unknown[] ? never : U[K] extends TEnum ? U[K][keyof U[K]] : never); | ||
}; | ||
@@ -95,3 +98,3 @@ export interface IOptNul { | ||
} | ||
declare function jetSchema<M extends TDefaultValsMap<M>>(options?: IJetOptions<M>): <T, U extends TSchemaFnObjArg<T> = Required<{ [K in keyof T]: T[K] extends string | number ? TEnum | IValidatorFn<T[K]> : T[K] extends Date ? DateConstructor | IValidatorFn<T[K]> : IsStaticObj<T[K], NonNullable<T[K]>> extends true ? ISchema<T[K]> : IValidatorFn<T[K]>; }>, R extends TSchemaOptions<T> = TSchemaOptions<T>>(schemaFnObjArg: U, ...options: TSchemaOptionsHelper<T, R>) => unknown extends T ? ISchema<InferTypes<U, R>> : ISchema<T>; | ||
declare function jetSchema<M extends TGlobalsArr<M>>(options?: IJetOptions<M>): <T, U extends TSchemaFnObjArg<T> = Required<{ [K in keyof T]: T[K] extends string | number ? TEnum | IValidatorFnOrObj<T[K]> : T[K] extends Date ? DateConstructor | IValidatorFnOrObj<T[K]> : IsStaticObj<T[K], NonNullable<T[K]>> extends true ? ISchema<T[K]> : IValidatorFnOrObj<T[K]>; }>, R extends TSchemaOptions<T> = TSchemaOptions<T>>(schemaFnObjArg: U, ...options: TSchemaOptionsHelper<T, R>) => unknown extends T ? ISchema<InferTypes<U, R>> : ISchema<T>; | ||
export default jetSchema; |
"use strict"; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -12,5 +23,9 @@ const util_1 = require("./util"); | ||
ParseNotAnObj: 'schema.parse failed: value must be an object.', | ||
NewFn: 'Failed in the "new" function', | ||
TestFn: 'Failed in the "test" function', | ||
ParseFn: 'Failed in the "parse" function', | ||
}; | ||
function jetSchema(options) { | ||
const defaultValsMap = new Map(options === null || options === void 0 ? void 0 : options.defaultValuesMap), cloneFn = ((options === null || options === void 0 ? void 0 : options.cloneFn) ? options.cloneFn : _defaultClone), onError = ((options === null || options === void 0 ? void 0 : options.onError) ? _wrapCustomError(options.onError) : _defaultOnErr); | ||
var _a; | ||
const globalsMap = _setupGlobalsMap((_a = options === null || options === void 0 ? void 0 : options.globals) !== null && _a !== void 0 ? _a : []), cloneFn = ((options === null || options === void 0 ? void 0 : options.cloneFn) ? options.cloneFn : _defaultClone), onError = ((options === null || options === void 0 ? void 0 : options.onError) ? _wrapCustomError(options.onError) : _defaultOnErr); | ||
return (schemaFnObjArg, ...options) => { | ||
@@ -26,3 +41,3 @@ const [schemaOptions] = options; | ||
} | ||
const ret = _setupDefaultsAndValidators(schemaFnObjArg, cloneFn, defaultValsMap, onErrorF), newFn = _setupNewFn(ret.defaults, ret.validators, cloneFn, onErrorF), testFn = _setupTestFn(ret.validators, optionsF.optional, optionsF.nullable, onErrorF), parseFn = _setupParseFn(ret.validators, cloneFn, onErrorF); | ||
const ret = _setupAllVldtrsHolder(schemaFnObjArg, cloneFn, globalsMap, onErrorF, optionsF.id), newFn = _setupNewFn(ret.allVldtrsHolder, cloneFn, onErrorF), testFn = _setupTestFn(ret.allVldtrsHolder, optionsF.optional, optionsF.nullable, onErrorF), parseFn = _setupParseFn(ret.allVldtrsHolder, cloneFn, onErrorF); | ||
return { | ||
@@ -32,7 +47,7 @@ new: newFn, | ||
pick: (p) => { | ||
const prop = schemaFnObjArg[p]; | ||
const prop = schemaFnObjArg[p], key = p; | ||
if (!!prop) { | ||
return Object.assign({ default: ret.defaults[p], test: ret.validators[p] }, (_isSchemaObj(prop) ? { | ||
return Object.assign({ default: ret.allVldtrsHolder[key].default, test: ret.allVldtrsHolder[key].fn }, (_isSchemaObj(prop) ? { | ||
pick: prop.pick, | ||
new: ret.childSchemaNewFns[p], | ||
new: ret.childSchemaNewFns[key], | ||
schema: () => (Object.assign({}, prop)), | ||
@@ -47,54 +62,96 @@ } : {})); | ||
} | ||
function _setupDefaultsAndValidators(schemaArgObj, cloneFn, defaultValsMap, onError) { | ||
const defaults = {}, childSchemaNewFns = {}, validators = {}; | ||
function _setupAllVldtrsHolder(schemaArgObj, cloneFn, globalsMap, onError, schemaId = '') { | ||
const allVldtrsHolder = {}, childSchemaNewFns = {}; | ||
for (const key in schemaArgObj) { | ||
const schemaArgProp = schemaArgObj[key]; | ||
allVldtrsHolder[key] = { | ||
fn: (arg) => false, | ||
default: () => false, | ||
}; | ||
if (schemaArgProp === Date) { | ||
defaults[key] = () => new Date(); | ||
validators[key] = util_1.isDate; | ||
allVldtrsHolder[key] = { | ||
fn: (0, util_1.transform)((arg) => new Date(arg), util_1.isDate), | ||
default: () => new Date(), | ||
}; | ||
} | ||
else if ((typeof schemaArgProp === 'function') || | ||
_isValidatorObj(schemaArgProp)) { | ||
let vdlrFn, defaultVal, hasLocalDefault = false, hasLocalTransform = false; | ||
if (_isValidatorObj(schemaArgProp)) { | ||
const localObj = schemaArgProp; | ||
vdlrFn = localObj.fn; | ||
if ('default' in localObj) { | ||
defaultVal = localObj.default; | ||
hasLocalDefault = true; | ||
} | ||
if (!!localObj.transform) { | ||
vdlrFn = (0, util_1.transform)(localObj.transform, vdlrFn); | ||
hasLocalTransform = true; | ||
} | ||
if (!!localObj.onError) { | ||
let customErr = localObj.onError; | ||
if (!!schemaId) { | ||
customErr = _wrapErrorWithSchemaId(customErr, schemaId); | ||
} | ||
allVldtrsHolder[key].onError = customErr; | ||
} | ||
} | ||
else { | ||
vdlrFn = schemaArgProp; | ||
} | ||
const globalsObj = globalsMap.get(vdlrFn); | ||
if (!!globalsObj) { | ||
if (!hasLocalDefault && 'default' in globalsObj) { | ||
defaultVal = globalsObj.default; | ||
} | ||
if (!hasLocalTransform && globalsObj.transform) { | ||
vdlrFn = (0, util_1.transform)(globalsObj.transform, vdlrFn); | ||
} | ||
if (!!globalsObj.onError) { | ||
let customErr = globalsObj.onError; | ||
if (!!schemaId) { | ||
customErr = _wrapErrorWithSchemaId(customErr, schemaId); | ||
} | ||
allVldtrsHolder[key].onError = customErr; | ||
} | ||
} | ||
if (!(0, util_1.isUndef)(defaultVal)) { | ||
const defaultF = cloneFn(defaultVal); | ||
allVldtrsHolder[key].default = () => defaultF; | ||
} | ||
else { | ||
allVldtrsHolder[key].default = () => undefined; | ||
} | ||
allVldtrsHolder[key].fn = vdlrFn; | ||
} | ||
else if (_isSchemaObj(schemaArgProp)) { | ||
const childSchema = schemaArgProp, dflt = childSchema._schemaOptions.init; | ||
if (dflt === true) { | ||
defaults[key] = () => childSchema.new(); | ||
allVldtrsHolder[key].default = () => childSchema.new(); | ||
} | ||
else if (dflt === null) { | ||
defaults[key] = () => null; | ||
allVldtrsHolder[key].default = () => null; | ||
} | ||
else { | ||
defaults[key] = () => undefined; | ||
allVldtrsHolder[key].default = () => undefined; | ||
} | ||
childSchemaNewFns[key] = () => childSchema.new(); | ||
validators[key] = childSchema.test; | ||
allVldtrsHolder[key].fn = childSchema.test; | ||
} | ||
else if ((0, util_1.isEnum)(schemaArgProp)) { | ||
const [dflt, vldr] = (0, util_1.processEnum)(schemaArgProp); | ||
defaults[key] = () => cloneFn(dflt); | ||
validators[key] = vldr; | ||
allVldtrsHolder[key].default = () => cloneFn(dflt); | ||
allVldtrsHolder[key].fn = vldr; | ||
} | ||
else if (typeof schemaArgProp === 'function') { | ||
let vdlrFn = schemaArgProp; | ||
let dflt; | ||
if (!!vdlrFn.origVldtr) { | ||
dflt = vdlrFn.defaultVal; | ||
vdlrFn = vdlrFn.origVldtr; | ||
} | ||
else if (defaultValsMap.has(vdlrFn)) { | ||
dflt = defaultValsMap.get(vdlrFn); | ||
} | ||
if (!(0, util_1.isUndef)(dflt)) { | ||
const defaultF = cloneFn(dflt); | ||
defaults[key] = () => defaultF; | ||
} | ||
else { | ||
defaults[key] = () => undefined; | ||
} | ||
validators[key] = vdlrFn; | ||
} | ||
else { | ||
onError(key, '', Errors.Validator); | ||
} | ||
const vldr = validators[key], dfltVal = defaults[key](); | ||
const vldr = allVldtrsHolder[key].fn, dfltVal = allVldtrsHolder[key].default(); | ||
if (!vldr(dfltVal)) { | ||
onError(key, dfltVal, Errors.Default); | ||
if (!!allVldtrsHolder[key].onError) { | ||
allVldtrsHolder[key].onError(key, dfltVal, Errors.Default); | ||
} | ||
else { | ||
onError(key, dfltVal, Errors.Default); | ||
} | ||
} | ||
@@ -104,4 +161,3 @@ } | ||
childSchemaNewFns, | ||
defaults, | ||
validators, | ||
allVldtrsHolder, | ||
}; | ||
@@ -112,16 +168,19 @@ } | ||
} | ||
function _setupNewFn(defaultVals, validators, cloneFn, onError) { | ||
function _isValidatorObj(arg) { | ||
return ((0, util_1.isObj)(arg) && ('fn' in arg) && typeof arg.fn === 'function'); | ||
} | ||
function _setupNewFn(allVldtrsHolder, cloneFn, onError) { | ||
return (partial = {}) => { | ||
const retVal = {}; | ||
for (const dflt in defaultVals) { | ||
const val = defaultVals[dflt](); | ||
for (const key in allVldtrsHolder) { | ||
const val = allVldtrsHolder[key].default(); | ||
if (val !== undefined) { | ||
retVal[dflt] = val; | ||
retVal[key] = val; | ||
} | ||
} | ||
for (const key in partial) { | ||
if (!defaultVals[key]) { | ||
if (!allVldtrsHolder[key]) { | ||
continue; | ||
} | ||
const testFn = validators[key]; | ||
const testFn = allVldtrsHolder[key].fn; | ||
let val = partial[key]; | ||
@@ -132,3 +191,8 @@ if (testFn(val, ((transVal) => val = transVal))) { | ||
else { | ||
onError(key, val); | ||
if (!!allVldtrsHolder[key].onError) { | ||
allVldtrsHolder[key].onError(key, val, Errors.NewFn); | ||
} | ||
else { | ||
onError(key, val, Errors.NewFn); | ||
} | ||
retVal[key] = '**ERROR**'; | ||
@@ -140,3 +204,3 @@ } | ||
} | ||
function _setupTestFn(validators, isOptional, isNullable, onError) { | ||
function _setupTestFn(allVldtrsHolder, isOptional, isNullable, onError) { | ||
return (arg) => { | ||
@@ -165,7 +229,12 @@ if ((0, util_1.isUndef)(arg)) { | ||
} | ||
for (const key in validators) { | ||
const testFn = validators[key]; | ||
for (const key in allVldtrsHolder) { | ||
const testFn = allVldtrsHolder[key].fn; | ||
let val = arg[key]; | ||
if (!testFn(val, ((transVal) => val = transVal))) { | ||
onError(key, val); | ||
if (!!allVldtrsHolder[key].onError) { | ||
allVldtrsHolder[key].onError(key, val, Errors.TestFn); | ||
} | ||
else { | ||
onError(key, val, Errors.TestFn); | ||
} | ||
return false; | ||
@@ -180,3 +249,3 @@ } | ||
} | ||
function _setupParseFn(validators, cloneFn, onError) { | ||
function _setupParseFn(allVldtrsHolder, cloneFn, onError) { | ||
return (arg) => { | ||
@@ -188,7 +257,12 @@ const retVal = {}; | ||
} | ||
for (const key in validators) { | ||
const testFn = validators[key]; | ||
for (const key in allVldtrsHolder) { | ||
const testFn = allVldtrsHolder[key].fn; | ||
let val = arg[key]; | ||
if (!testFn(val, ((transVal) => val = transVal))) { | ||
onError(key, val); | ||
if (!!allVldtrsHolder[key].onError) { | ||
allVldtrsHolder[key].onError(key, val, Errors.ParseFn); | ||
} | ||
else { | ||
onError(key, val, Errors.ParseFn); | ||
} | ||
retVal[key] = '**ERROR**'; | ||
@@ -203,2 +277,10 @@ } | ||
} | ||
function _setupGlobalsMap(globalsArr) { | ||
const map = new Map(); | ||
for (const obj of globalsArr) { | ||
const { fn } = obj, rest = __rest(obj, ["fn"]); | ||
map.set(fn, rest); | ||
} | ||
return map; | ||
} | ||
function _processOptions(options) { | ||
@@ -205,0 +287,0 @@ let base = { init: true }; |
export type TFunc = (...args: any[]) => any; | ||
export type TBasicObj = Record<string, unknown>; | ||
export type TEnum = Record<string, string | number>; | ||
export interface IValidatorFn<T> { | ||
(arg: unknown, cb?: ((transformedVal: T) => void)): arg is T; | ||
defaultVal?: T; | ||
origVldtr?: IValidatorFn<T>; | ||
export type TValidatorFn<T> = (arg: unknown, cb?: ((transformedVal: T) => void)) => arg is T; | ||
export interface IValidatorObj<T> { | ||
fn: TValidatorFn<T>; | ||
default?: T; | ||
transform?: TFunc; | ||
onError?: (property: string, value?: unknown, moreDetails?: string, schemaId?: string) => void; | ||
} | ||
export type IValidatorFnOrObj<T> = TValidatorFn<T> | IValidatorObj<T>; | ||
export declare function isUndef(param: unknown): param is undefined; | ||
@@ -18,5 +21,3 @@ export declare function isNum(param: unknown): param is number; | ||
export declare function isBasicObj(arg: unknown): arg is TBasicObj; | ||
export declare const isDate: IValidatorFn<Date>; | ||
export declare function isValidDate(val: unknown): val is Date; | ||
export declare function transform<T>(transFn: TFunc, vldt: ((arg: unknown) => arg is T)): IValidatorFn<T>; | ||
export declare function setDefault<T>(vldtr: IValidatorFn<T>, defaultVal: T): IValidatorFn<T>; | ||
export declare const isDate: (val: unknown) => val is Date; | ||
export declare function transform<T>(transFn: TFunc, vldt: ((arg: unknown) => arg is T)): TValidatorFn<T>; |
@@ -13,5 +13,3 @@ "use strict"; | ||
exports.isBasicObj = isBasicObj; | ||
exports.isValidDate = isValidDate; | ||
exports.transform = transform; | ||
exports.setDefault = setDefault; | ||
function isUndef(param) { | ||
@@ -84,9 +82,6 @@ return param === undefined; | ||
} | ||
exports.isDate = transform((arg) => { | ||
return new Date(arg); | ||
}, isValidDate); | ||
function isValidDate(val) { | ||
return ((isStr(val) || isNum(val) || (val instanceof Date)) && | ||
!isNaN(new Date(val).getTime())); | ||
} | ||
const isDate = (val) => { | ||
return (val instanceof Date) && !isNaN(new Date(val).getTime()); | ||
}; | ||
exports.isDate = isDate; | ||
function transform(transFn, vldt) { | ||
@@ -101,8 +96,2 @@ return (arg, cb) => { | ||
} | ||
function setDefault(vldtr, defaultVal) { | ||
const clone = (arg) => false; | ||
clone.defaultVal = defaultVal; | ||
clone.origVldtr = vldtr; | ||
return clone; | ||
} | ||
//# sourceMappingURL=util.js.map |
{ | ||
"name": "jet-schema", | ||
"version": "1.1.5", | ||
"version": "1.2.0", | ||
"description": "Simple, typescript-first schema validation tool", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
131
README.md
@@ -13,3 +13,2 @@ # Jet-Schema ✈️ | ||
- [Making schemas optional/nullable](#making-schemas-opt-null) | ||
- [Transforming values with "transform"](#transforming-values-with-transform) | ||
- [Combining Schemas](#combining-schemas) | ||
@@ -25,6 +24,6 @@ - [TypeScript Caveats](#typescript-caveats) | ||
## Introduction <a name="introduction"></a> | ||
Most schema validation libraries have fancy functions for validating objects and their properties, but the problem is I usually already have a lot of my own custom validation logic specific for each of my applications (i.e. functions to check primitive-types, regexes for validating strings etc). The only thing that was making me use schema-validation libraries was trying to validate an object. So I thought, why not figure out a way to integrate my all the functions I had already written with something that can validate them against object properties? Well **jet-schema** does just that :) | ||
Most schema validation libraries have fancy functions for validating objects and their properties, but the problem is I already have a lot of my own custom validation functions specific for each of my applications that I also like to copy-n-paste a lot and modify as needed (i.e. functions to check primitive-types, regexes for validating strings etc). The only thing that was making me use schema-validation libraries was trying to validate an object. So I thought, why not figure out a way to integrate my all the functions I had already written with something that can validate them against object properties? Well **jet-schema** does just that :) | ||
<br/> | ||
If you want a library that includes all kinds of special functions for validating things other than objects, **jet-schema** is probably not for you. However, the vast majority of projects I've worked on have involved implementing lots of type-checking functions specific to the needs of that project. For example, maybe the email format that's built into the library is different than the one your application needs. Instead of of having to dig into the library's features to validate using your custom method, with **jet-schema** you can just pass your method. | ||
If you want a library that includes all kinds of special functions for validating things other than objects, **jet-schema** is probably not for you. However, the vast majority of projects I've worked on have involved implementing lots of type-checking functions specific to the needs of that project. For example, maybe the email format that's built into the library is different than the one your application needs. Instead of of having to dig into the library's features to run validations specific to your needs, with **jet-schema** you can just pass your method. | ||
<br/> | ||
@@ -37,8 +36,7 @@ | ||
- TypeScript first! | ||
- Quick, terse, simple, easy-to-use (you can probably learn every feature in like 30 minutes). | ||
- Quick, terse, simple, easy-to-use (this library only exports 2 functions and 2 types). | ||
- Much smaller and less complex than most schema-validation libraries. | ||
- Typesafety works both ways, you can either force a schema structure using a pre-defined type OR you can infer a type from a schema. | ||
- `new`, `test`, `parse` functions provided automatically on every new schema. | ||
- Provides a `transform` wrapper function to modify values before validating them. | ||
- Default values can be set globally on initial setup or with the `setDefault` wrapper. | ||
- Setting defaults and transforming values can be set globally on initial setup or at the schema-level. | ||
- Works client-side or server-side. | ||
@@ -53,3 +51,2 @@ - Enums can be used for validation. | ||
```typescript | ||
import { setDefault, transform } from 'jet-schema'; | ||
import schema from 'utils/schema'; | ||
@@ -74,4 +71,4 @@ import { isRelKey, isString, isNumber, isOptionalStr } from 'utils/validators'; | ||
name: isString, | ||
email: setDefault(isEmail, 'x@x.com'), | ||
age: transform(Number, isNumber), | ||
email: { fn: isEmail, default: 'x@x.com' }, | ||
age: { fn: isNumber, transform: Number }, | ||
created: Date, | ||
@@ -92,18 +89,30 @@ address: schema<IUser['address']>({ | ||
Note that at the heart of `jet-schema` are **validator-functions**. Since functions are objects in javascript, and objects are pass by reference, `jet-schema` will map certain settings to validator-functions by using the functions themselves as a reference. This is what enables you to pass your existing validator-functions to your schema without have to deal with the library's features everytime. | ||
> npm install -s jet-schema | ||
After installation, you need to configure the `schema` function by importing and calling the `jetSchema()` function. | ||
After installation, you need to configure the `schema` function by importing and calling `jetSchema()`. | ||
<br/> | ||
`jetSchema()` accepts an optional settings object with 3 three options: | ||
- `defaultValuesMap`: An `[["val", "function"]]`nested array specifying which default value should be used for which validator-function: you should use this option for frequently used validator-function/default-value combinations where you don't want to set a default value every time. Upon initialization, the validator-functions will check their defaults. If a value is not optional and you do not supply a default value, then an error will be thrown when the schema is initialized. If you don't set a default value for a validator-function in `jetSchema()`, you can also call `setDefault` when setting up the schema (the next 3 snippets below contain examples). | ||
- `cloneFn`: A custom clone-function if you don't want to use the built-in function which uses `structuredClone` (I like to use `lodash.cloneDeep`). | ||
- `onError`: If a validator-function fails then an error is thrown. You can override this behavior by passing a custom error handling function as the third argument. This feature is really useful for testing when you may want to return an error string instead of throw an error. | ||
`jetSchema()` accepts an optional settings object with 3 three properties: | ||
- `globals?`: An array of **validator-objects**, which set certain default settings for specific validator-functions. You should use this option for frequently used validator-function/default/transform combinations where you don't want to set a default value or transform-function every time. Upon initialization, the validator-functions will check their defaults. If a value is not optional and you do not supply a default value, then an error will occur when the schema is initialized. If you don't set a default value for a validator-function in `jetSchema()`, you can also do so when setting up an individual schema (the next 3 snippets below contain examples).<br/> | ||
The format for a **validator-object** is: | ||
```typescript | ||
{ | ||
fn: <T>(arg: unknown) => arg is T; // a validator-function | ||
default?: T; // the value to use for the validator-function | ||
transform?: (arg: unknown) => T; // modify the value before calling the validator-function | ||
onError?: (property: string, value?: unknown, moreDetails?: string, schemaId?: string) => void; // Custom error message for the function | ||
} | ||
``` | ||
- `cloneFn?`: A custom clone-function if you don't want to use the built-in function which uses `structuredClone` (I like to use `lodash.cloneDeep`). | ||
- `onError?`: A global error handler. By default, if a validator-function fails then an error is thrown. You can override this behavior by passing a custom error handling function as the third argument. This feature is really useful for testing when you may want to return an error string instead of throw an error. | ||
- Format: `(property: string, value?: unknown, origMessage?: string, schemaId?: string) => void;`. | ||
> When setting up **jet-schema** for the first time, usually what I do is create two files under my `util/` folder: `schema.ts` and `validators.ts`. In `schema.ts` I'll import and call the `jet-schema` function then apply any frequently used validator-function/default-value combinations I have and a clone-function. If you don't want to go through this step, you can import the `schema` function directly from `jet-schema`. | ||
When setting up **jet-schema** for the first time, usually what I do is create two files under my `util/` folder: `schema.ts` and `validators.ts`. In `schema.ts` I'll import and call the `jet-schema` function then apply any globals and a custom clone-function. If you don't want to go through this step, you can import the `schema` function directly from `jet-schema`. | ||
```typescript | ||
// "util/validators.ts" | ||
// As mentioned in the intro, you can copy some validators from here (https://github.com/seanpmaxwell/ts-validators/blob/master/src/validators.ts) | ||
// As mentioned in the intro, you can copy some predefined validators from here (https://github.com/seanpmaxwell/ts-validators/blob/master/src/validators.ts) | ||
export const isStr = (arg: unknown): arg is string => typeof param === 'string'; | ||
@@ -122,8 +131,8 @@ export const isOptStr = (arg: unknown): arg is string => arg === undefined || typeof param === 'string'; | ||
export default jetLogger({ | ||
defaultValuesMap: [ | ||
[isNum, 0], | ||
[isStr, ''], | ||
globals: [ | ||
{ fn: isNum, default: 0 }, | ||
{ fn: isStr, default: '' }, | ||
], | ||
cloneFn: // pass a custom clone-function here | ||
onError: // pass a custom error-handler here, | ||
cloneFn: () => ... // pass a custom clone-function here if you want | ||
onError: () => ... // pass a custom error-handler here if you want, | ||
}); | ||
@@ -134,5 +143,5 @@ ``` | ||
Now that we have our `schema` function setup, let's make a schema. Simply import the `schema` function from `util/schema.ts` and then your existing validator-functions and pass them as the value to each property in the `schema` function. If you want to set a default value at the schema level instead of at the global level in the `jetSchema` function, you can import the `setDefault` function from `jet-schema` and pass it the validator-function and the default value to go with it. Note that setting a default does not modify the validator function in any way. If a property is required then a default must be set for it (either globally or in `setDefault`) or else `new` won't know what to use as a value if the partial doesn't contain it.<br/> | ||
Now that we have our `schema` function setup, let's make a schema. Simply import the `schema` function from `util/schema.ts` and your existing validator-functions, then pass them as the value to each property in the `schema` function or use a validator-object. The format for a validator-object is the same both locally and globally (see above). All local-settings will for a validator-function will overwrite the global ones. Remember that if a property is required then a default must be set for its validator-function (locally or globally) or else `new` won't know what to use as a value when passing a partial.<br/> | ||
For handling the overall schema's type, there are two ways to go about this, enforcing a schema from a type or infering a type from a schema. I'll show you an example of doing it both ways. | ||
For handling an individual schema's type, there are two ways to go about this, enforcing a schema from a type or infering a type from a schema. I'll show you an example of doing it both ways. | ||
@@ -143,3 +152,3 @@ > Personally, I like to create an interface first cause I feel like interfaces are great way to document your data-types; however, I created `inferType` because I know some people prefer to setup their schemas first and infer their types from that. | ||
// "models/User.ts" | ||
import { inferType, setDefault } from 'jet-schema'; | ||
import { inferType } from 'jet-schema'; | ||
import schema from 'util/schema.ts'; | ||
@@ -158,3 +167,3 @@ import { isNum, isStr, isOptionalStr } from 'util/validators.ts'; | ||
name: isStr, | ||
email: setDefault(isEmail, ''), | ||
email: { fn: isEmail, default: '' }, | ||
nickName: isOptionalStr, | ||
@@ -167,3 +176,3 @@ }) | ||
name: isStr, | ||
email: setDefault(isEmail, ''), | ||
email: { fn: isEmail, default: '' }, | ||
nickName: isOptionalStr, | ||
@@ -178,20 +187,5 @@ }) | ||
- `pick` allows you to select any property and returns an object with the `test` and `default` functions. | ||
- `parse` is like a combination of `new` and `test`. It accepts an `unknown` value which is not optional, validates the properties but returns a new instance (while removing an extra ones) instead of a type-predicate. If you have an incoming unknown value (i.e. an api call) and you want to validate the properties and return a new instance while removing any possible extra ones, use `parse`. Note: only objects will pass the `parse` function, even if a schema is nullish, `null/undefined` values will not pass. | ||
- `parse` is like a combination of `new` and `test`. It accepts an `unknown` value which is not optional, validates the properties but returns a new instance (while removing an extra ones) instead of a type-predicate. If you have an incoming unknown value (i.e. an api call) and you want to validate the properties and return a new cleaned instance, use `parse`. Note: only objects will pass the `parse` function, even if a schema is nullish, `null/undefined` values will not pass. | ||
### Child (aka nested) schemas <a name="child-schemas"></a> | ||
- If an object property is a mapped-type, then it must be initialized with the `schema` function. | ||
- Just like with the parent schemas, you can also call `new`, `test`, `pick`, `parse` in addition to `default`. The value returned from `default` could be different from `new` if the schema is optional/nullable and the default value is `null` or `undefined`. | ||
- There is one extra function `schema()` that you can call when using `pick` on a child-schema. This can be handy if you need to export a child-schema from one parent-schema to another: | ||
```typescript | ||
interface IUserAlt { | ||
id: number; | ||
address: IUser['address']; | ||
} | ||
const UserAlt = schema<IUserAlt>({ | ||
id: isNumber, | ||
address: User.pick('address').schema(), | ||
}); | ||
``` | ||
### Making schemas optional/nullable <a name="making-schemas-opt-null"></a> | ||
@@ -213,5 +207,4 @@ In addition to a schema-object, the `schema` function accepts an additional **options** object parameter. The values here are type-checked against the generic (`schema<"The Generic">(...)`) that was passed so you must use the correct values. If your generic is optional/nullable then your are required to pass the object so at runtime the correct values are parsed. | ||
You can also set the optional `id` field, if you need a unique identifier for your schema for whatever reason. If you set this option then it be added to the default error message. This can be useful if you have to debug a bunch of schemas at once (that's pretty much all I use it for). | ||
You can also set the optional `id` field, if you need a unique identifier for your schema for whatever reason. If you set this option then it will be added to the default error message. This can be useful if you have to debug a bunch of schemas at once (that's pretty much all I use it for). | ||
Here's an example of the options in use: | ||
@@ -241,14 +234,32 @@ | ||
### Transforming values with `transform()` <a name="transforming-values-with-transform"></a> | ||
If you want to modify a value before it passes through a validator-function, you can import the `transform` function and wrap your validator function with it. `transform` accepts a transforming-function and a validator-function and returns a new validator-function (type-predicate is preserved) which will transform the value before testing it. When calling `new`, `test`, or `parse`, `transform` will modify the original object. | ||
<br/> | ||
If you want to access the transformed value yourself for whatever reason, you can pass a callback as the second argument to the returned validator-function and `transform` will supply the modified value to it. I've found `transform` can be useful for other parts of my application where I need to modify a value before validating it and then access the transformed value. | ||
### Child (aka nested) schemas <a name="child-schemas"></a> | ||
- If an object property is a mapped-type, then it must be initialized with the `schema` function. | ||
- Just like with the parent schemas, you can also call `new`, `test`, `pick`, `parse` in addition to `default`. Note: the value returned from `default` could be different from `new` if the schema is optional/nullable and the default value is `null` or `undefined`. | ||
- There is one extra function `schema()` that you can call when using `pick` on a child-schema. This can be handy if you need to export a child-schema from one parent-schema to another: | ||
```typescript | ||
import { transform } from 'jet-schema'; | ||
interface IUser { | ||
id: number; | ||
address?: { street: string, city: string }; | ||
} | ||
const modifyAndTest = transform(JSON.parse, isNumberArray); | ||
let val = '[1,2,3,5]'; | ||
console.log(modifyAndTest(val, transVal => val = transVal)); // => true | ||
console.log(val); // => [1,2,3,5] this is number array not a string | ||
const User = schema<IUser>({ | ||
id: isNumber, | ||
address: schema<IUser['address']>({ | ||
street: isStr, | ||
city: isString | ||
}, { optional: true, init: false }), | ||
}); | ||
User.pick('address').default() // => undefined because we said "init: false" | ||
User.pick('address').new() // { street: '', city: '' } | ||
interface IUserAlt { | ||
id: number; | ||
address?: IUser['address']; | ||
} | ||
const UserAlt = schema<IUserAlt>({ | ||
id: isNumber, | ||
address: User.pick('address').schema(), | ||
}); | ||
``` | ||
@@ -295,3 +306,3 @@ | ||
**Child schemas**<br/> | ||
As mentioned, if a property in a parent is mapped-object type (it as a defined set of keys), then you need to call `schema` again for the nested object. If you don't use a generic on the child-schema, typescript will still make sure all the required properties are there; however, because of structural-typing the child could have additional properties. It is highly-recommended that you pass a generic to your child-objects so additional properties don't get added. | ||
As mentioned, if a property in a parent is mapped-object type (it has a defined set of keys), then you need to call `schema` again for the nested object. If you don't use a generic on the child-schema, typescript will still make sure all the required properties are there; however, because of structural-typing the child could have additional properties. It is highly-recommended that you pass a generic to your child-objects so additional properties don't get added. | ||
```typescript | ||
@@ -316,3 +327,3 @@ interface IUser { | ||
- When passing the `Date` constructor, `jet-schema` sets the type to be a `Date` object and automatically converts all valid date values (i.e. `string/number`, maybe a `Date` object got stringified in an API call) to a `Date` object. The default value will be a `Date` object with the current datetime. | ||
- You can also use an enum as a validator. The default value will be the first value in the enum object and validation will make sure it is an enum value. | ||
- You can also use an enum as a validator. The default value will be the first value in the enum object and validation will make sure it is value of that enum. | ||
<br> | ||
@@ -357,8 +368,8 @@ | ||
export default jetLogger({ | ||
defaultValuesMap: [ | ||
[isNum, 0], | ||
[isStr, ''], | ||
[isBool, false], | ||
globals: [ | ||
{ fn: isNum, default: 0 }, | ||
{ fn: isStr, default: '' }, | ||
{ fn: isBool, default: false }, | ||
], | ||
}); | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
69626
615
359