jet-schema
Advanced tools
Comparing version
import jetSchema from './jetSchema'; | ||
export type { TSchemaFnObjArg as TJetSchema, PublicInferType as inferType, } from './jetSchema'; | ||
export { transform } from './util'; | ||
export declare const schema: <T, U extends import("./jetSchema").TSchemaFnObjArg<T> = import("./jetSchema").TSchemaFnObjArg<T>, R extends unknown extends T ? [isOptional?: boolean | undefined, isNullable?: boolean | undefined, defaultVal?: boolean | null | undefined] : undefined extends T ? null extends T ? [isOptional: true, isNullable: true, defaultVal?: boolean | (T & null) | undefined] : [isOptional: true, isNullable?: false | undefined, defaultVal?: boolean | undefined] : null extends T ? [isOptional: false, isNullable?: true | undefined, defaultVal?: true | (T & null) | undefined] : [isOptional?: false | undefined, isNullable?: false | undefined, defaultVal?: true | undefined] = unknown extends T ? [isOptional?: boolean | undefined, isNullable?: boolean | undefined, defaultVal?: boolean | null | undefined] : undefined extends T ? null extends T ? [isOptional: true, isNullable: true, defaultVal?: boolean | (T & null) | undefined] : [isOptional: true, isNullable?: false | undefined, defaultVal?: boolean | undefined] : null extends T ? [isOptional: false, isNullable?: true | undefined, defaultVal?: true | (T & null) | undefined] : [isOptional?: false | undefined, isNullable?: false | undefined, defaultVal?: true | undefined]>(schemaFnObjArg: U, ...rest: R) => import("./jetSchema").ISchema<unknown extends T ? R[0] extends infer T_1 ? T_1 extends R[0] ? T_1 extends true ? (R[1] extends infer T_2 ? T_2 extends R[1] ? T_2 extends true ? NonNullable<Exclude<{ [K_1 in keyof { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
export declare const schema: <T, U extends import("./jetSchema").TSchemaFnObjArg<T> = import("./jetSchema").TSchemaFnObjArg<T>, R extends unknown extends T ? import("./jetSchema").IOptNul | import("./jetSchema").IOptNotNul | import("./jetSchema").INotOptButNul | import("./jetSchema").INotOptOrNul : undefined extends T ? null extends T ? import("./jetSchema").IOptNul : 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 : undefined extends T ? null extends T ? import("./jetSchema").IOptNul : import("./jetSchema").IOptNotNul : null extends T ? import("./jetSchema").INotOptButNul : import("./jetSchema").INotOptOrNul>(schemaFnObjArg: U, schemaOptions?: R | undefined) => import("./jetSchema").ISchema<unknown extends T ? ("optional" extends keyof R ? R[keyof R & "optional"] : false) extends infer T_1 ? T_1 extends ("optional" extends keyof R ? R[keyof R & "optional"] : false) ? T_1 extends true ? (("nullable" extends keyof R ? R[keyof R & "nullable"] : false) extends infer T_2 ? T_2 extends ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) ? T_2 extends true ? NonNullable<Exclude<{ [K_1 in keyof { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
[x: string]: string | number; | ||
@@ -28,3 +28,3 @@ } | (((arg: unknown) => arg is U[K]) | [U[K], (arg: unknown) => arg is U[K]]) : never; } as undefined extends { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
[x: string]: string | number; | ||
} | (((arg: unknown) => arg is U[K]) | [U[K], (arg: unknown) => arg is U[K]]) : never; }[K_2]; }, undefined>> : never : never) | undefined : R[1] extends infer T_2 ? T_2 extends R[1] ? T_2 extends true ? NonNullable<Exclude<{ [K_1 in keyof { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
} | (((arg: unknown) => arg is U[K]) | [U[K], (arg: unknown) => arg is U[K]]) : never; }[K_2]; }, undefined>> : never : never) | undefined : ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) extends infer T_2 ? T_2 extends ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) ? T_2 extends true ? NonNullable<Exclude<{ [K_1 in keyof { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
[x: string]: string | number; | ||
@@ -53,3 +53,3 @@ } | (((arg: unknown) => arg is U[K]) | [U[K], (arg: unknown) => arg is U[K]]) : never; } as undefined extends { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
[x: string]: string | number; | ||
} | (((arg: unknown) => arg is U[K]) | [U[K], (arg: unknown) => arg is U[K]]) : never; }[K_2]; }, undefined>> : never : never : never : never : T, NonNullable<unknown extends T ? R[0] extends infer T_1 ? T_1 extends R[0] ? T_1 extends true ? (R[1] extends infer T_2 ? T_2 extends R[1] ? T_2 extends true ? NonNullable<Exclude<{ [K_1 in keyof { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
} | (((arg: unknown) => arg is U[K]) | [U[K], (arg: unknown) => arg is U[K]]) : never; }[K_2]; }, undefined>> : never : never : never : never : T, NonNullable<unknown extends T ? ("optional" extends keyof R ? R[keyof R & "optional"] : false) extends infer T_1 ? T_1 extends ("optional" extends keyof R ? R[keyof R & "optional"] : false) ? T_1 extends true ? (("nullable" extends keyof R ? R[keyof R & "nullable"] : false) extends infer T_2 ? T_2 extends ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) ? T_2 extends true ? NonNullable<Exclude<{ [K_1 in keyof { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
[x: string]: string | number; | ||
@@ -78,3 +78,3 @@ } | (((arg: unknown) => arg is U[K]) | [U[K], (arg: unknown) => arg is U[K]]) : never; } as undefined extends { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
[x: string]: string | number; | ||
} | (((arg: unknown) => arg is U[K]) | [U[K], (arg: unknown) => arg is U[K]]) : never; }[K_2]; }, undefined>> : never : never) | undefined : R[1] extends infer T_2 ? T_2 extends R[1] ? T_2 extends true ? NonNullable<Exclude<{ [K_1 in keyof { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
} | (((arg: unknown) => arg is U[K]) | [U[K], (arg: unknown) => arg is U[K]]) : never; }[K_2]; }, undefined>> : never : never) | undefined : ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) extends infer T_2 ? T_2 extends ("nullable" extends keyof R ? R[keyof R & "nullable"] : false) ? T_2 extends true ? NonNullable<Exclude<{ [K_1 in keyof { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { | ||
[x: string]: string | number; | ||
@@ -81,0 +81,0 @@ } | (((arg: unknown) => arg is U[K]) | [U[K], (arg: unknown) => arg is U[K]]) : never; } as undefined extends { [K in keyof U]: U[K] extends unknown[] ? U[K][0] : U[K] extends DateConstructor ? Date : U[K] extends import("./util").TFunc ? U[K] extends infer T_3 ? T_3 extends U[K] ? T_3 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends import("./jetSchema").ISchema<unknown, {}> ? U[K]["test"] extends infer T_4 ? T_4 extends U[K]["test"] ? T_4 extends (x: unknown) => x is infer U_1 ? U_1 : never : never : never : U[K] extends string | number ? { |
@@ -37,6 +37,6 @@ import { TFunc } from './util'; | ||
pick: <K extends keyof NT>(prop: K) => (undefined extends NT[K] ? TPickRetVal<NT[K]> | undefined : TPickRetVal<NT[K]>); | ||
_schemaSettings: { | ||
isOptional: boolean; | ||
isNullable: boolean; | ||
defaultVal: boolean | null; | ||
_schemaOptions: { | ||
optional: boolean; | ||
nullable: boolean; | ||
init: boolean | null; | ||
}; | ||
@@ -49,23 +49,2 @@ } | ||
}; | ||
type TSchemaFnArgs<T> = unknown extends T ? [ | ||
isOptional?: boolean, | ||
isNullable?: boolean, | ||
defaultVal?: boolean | null | ||
] : (undefined extends T ? (null extends T ? [ | ||
isOptional: true, | ||
isNullable: true, | ||
defaultVal?: boolean | null | ||
] : [ | ||
isOptional: true, | ||
isNullable?: false, | ||
defaultVal?: boolean | ||
]) : (null extends T ? [ | ||
isOptional: false, | ||
isNullable?: true, | ||
defaultVal?: true | null | ||
] : [ | ||
isOptional?: false, | ||
isNullable?: false, | ||
defaultVal?: true | ||
])); | ||
export type PublicInferType<S> = (S extends ISchema<unknown> ? GetTypePredicate<S['test']> : never); | ||
@@ -76,3 +55,29 @@ type InferTypes<U, isOpt, isNul> = AddNullables<MakeOptIfUndef<InferTypesHelper<U>>, isOpt, isNul>; | ||
}; | ||
declare function jetSchema<M extends TDefaultValsMap<M>>(defaultValuesArr?: M extends [TFunc, unknown][] ? M : never, cloneFnArg?: TFunc, onError?: TOnError): <T, U extends TSchemaFnObjArg<T> = TSchemaFnObjArg<T>, R extends TSchemaFnArgs<T> = TSchemaFnArgs<T>>(schemaFnObjArg: U, ...rest: R) => ISchema<unknown extends T ? InferTypes<U, R[0], R[1]> : T>; | ||
interface IJetOptions<M> { | ||
defaultValuesMap?: M extends [TFunc, unknown][] ? M : never; | ||
cloneFn?: (value: unknown) => unknown; | ||
onError?: TOnError; | ||
} | ||
export interface IOptNul { | ||
optional: true; | ||
nullable: true; | ||
init?: null | boolean; | ||
} | ||
export interface IOptNotNul { | ||
optional: true; | ||
nullable?: false; | ||
init?: boolean; | ||
} | ||
export interface INotOptButNul { | ||
optional?: false; | ||
nullable: true; | ||
init?: null | true; | ||
} | ||
export interface INotOptOrNul { | ||
optional?: false; | ||
nullable?: false; | ||
init?: true; | ||
} | ||
type TSchemaOptions<T> = (unknown extends T ? (IOptNul | IOptNotNul | INotOptButNul | INotOptOrNul) : (undefined extends T ? (null extends T ? IOptNul : IOptNotNul) : (null extends T ? INotOptButNul : INotOptOrNul))); | ||
declare function jetSchema<M extends TDefaultValsMap<M>>(options?: IJetOptions<M>): <T, U extends TSchemaFnObjArg<T> = TSchemaFnObjArg<T>, R extends TSchemaOptions<T> = TSchemaOptions<T>>(schemaFnObjArg: U, schemaOptions?: R) => ISchema<unknown extends T ? InferTypes<U, "optional" extends keyof R ? R["optional"] : false, "nullable" extends keyof R ? R["nullable"] : false> : T>; | ||
export default jetSchema; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const util_1 = require("./util"); | ||
function jetSchema(defaultValuesArr, cloneFnArg, onError) { | ||
const defaultValsMap = new Map(defaultValuesArr), onErrorF = onError !== null && onError !== void 0 ? onError : _defaultOnErr; | ||
let cloneFn; | ||
if (!!cloneFnArg) { | ||
cloneFn = cloneFnArg; | ||
} | ||
else { | ||
cloneFn = (arg) => _clone(arg); | ||
} | ||
return (schemaFnObjArg, ...rest) => { | ||
const [isOptional = false, isNullable = false, defaultVal = true] = rest, ret = _setupDefaultsAndValidators(schemaFnObjArg, cloneFn, defaultValsMap, onErrorF), newFn = _setupNewFn(ret.defaults, ret.validators, cloneFn, onErrorF), testFn = _setupTestFn(ret.validators, isOptional, isNullable, onErrorF); | ||
if (!isOptional && !isNullable && !defaultVal) { | ||
function jetSchema(options) { | ||
const defaultValsMap = new Map(options === null || options === void 0 ? void 0 : options.defaultValuesMap), onErrorF = ((options === null || options === void 0 ? void 0 : options.onError) ? options.onError : _defaultOnErr), cloneFn = ((options === null || options === void 0 ? void 0 : options.cloneFn) ? options.cloneFn : _defaultClone); | ||
return (schemaFnObjArg, schemaOptions) => { | ||
const optionsF = { | ||
optional: !!(schemaOptions === null || schemaOptions === void 0 ? void 0 : schemaOptions.optional), | ||
nullable: !!(schemaOptions === null || schemaOptions === void 0 ? void 0 : schemaOptions.nullable), | ||
init: ((0, util_1.isUndef)(schemaOptions === null || schemaOptions === void 0 ? void 0 : schemaOptions.init) ? true : schemaOptions === null || schemaOptions === void 0 ? void 0 : schemaOptions.init), | ||
}; | ||
if (!optionsF.optional && !optionsF.nullable && !optionsF.init) { | ||
throw new Error('Default value must be the full schema-object if type is neither optional or nullable'); | ||
} | ||
const ret = _setupDefaultsAndValidators(schemaFnObjArg, cloneFn, defaultValsMap, onErrorF), newFn = _setupNewFn(ret.defaults, ret.validators, cloneFn, onErrorF), testFn = _setupTestFn(ret.validators, optionsF.optional, optionsF.nullable, onErrorF); | ||
return { | ||
@@ -30,7 +28,3 @@ new: newFn, | ||
}, | ||
_schemaSettings: { | ||
isOptional, | ||
isNullable, | ||
defaultVal, | ||
}, | ||
_schemaOptions: optionsF, | ||
}; | ||
@@ -53,3 +47,3 @@ }; | ||
else if (_isSchemaObj(setupVal)) { | ||
const childSchema = setupVal, dflt = childSchema._schemaSettings.defaultVal; | ||
const childSchema = setupVal, dflt = childSchema._schemaOptions.init; | ||
if (dflt === true) { | ||
@@ -65,5 +59,5 @@ defaults[key] = () => childSchema.new(); | ||
else if ((0, util_1.isObj)(setupVal)) { | ||
const vals = (0, util_1.getEnumVals)(setupVal); | ||
defaults[key] = () => cloneFn(vals[0]); | ||
validators[key] = (arg) => vals.some(item => item === arg); | ||
const [dflt, vldr] = (0, util_1.processEnum)(setupVal); | ||
defaults[key] = () => cloneFn(dflt); | ||
validators[key] = vldr; | ||
} | ||
@@ -97,3 +91,3 @@ else if ((0, util_1.isFn)(setupVal)) { | ||
function _isSchemaObj(arg) { | ||
return ((0, util_1.isObj)(arg) && '_schemaSettings' in arg); | ||
return ((0, util_1.isObj)(arg) && '_schemaOptions' in arg); | ||
} | ||
@@ -145,3 +139,3 @@ function _setupNewFn(defaultVals, validators, cloneFn, onError) { | ||
} | ||
function _clone(arg) { | ||
function _defaultClone(arg) { | ||
if (arg instanceof Date) { | ||
@@ -148,0 +142,0 @@ return new Date(arg); |
@@ -10,3 +10,3 @@ export type TFunc = (...args: any[]) => any; | ||
export declare function isNonArrObj(arg: unknown): arg is Record<string, unknown>; | ||
export declare function getEnumVals(arg: unknown): unknown[]; | ||
export declare function processEnum(arg: unknown): [unknown, TFunc]; | ||
export declare function isBasicObj(arg: unknown): arg is TBasicObj; | ||
@@ -13,0 +13,0 @@ export declare function isFn(arg: unknown): arg is TFunc; |
@@ -10,3 +10,3 @@ "use strict"; | ||
exports.isNonArrObj = isNonArrObj; | ||
exports.getEnumVals = getEnumVals; | ||
exports.processEnum = processEnum; | ||
exports.isBasicObj = isBasicObj; | ||
@@ -34,18 +34,19 @@ exports.isFn = isFn; | ||
} | ||
function getEnumVals(arg) { | ||
if (isNonArrObj(arg)) { | ||
const resp = Object.keys(arg).reduce((arr, key) => { | ||
if (!arr.includes(key)) { | ||
arr.push(arg[key]); | ||
} | ||
return arr; | ||
}, []); | ||
if (isNum(arg[resp[0]])) { | ||
return resp.map(item => arg[item]); | ||
function processEnum(arg) { | ||
if (!isNonArrObj(arg)) { | ||
throw Error('"getEnumKeys" be an non-array object'); | ||
} | ||
let vals = Object.keys(arg).reduce((arr, key) => { | ||
if (!arr.includes(key)) { | ||
arr.push(arg[key]); | ||
} | ||
else { | ||
return resp; | ||
} | ||
return arr; | ||
}, []); | ||
if (isNum(arg[vals[0]])) { | ||
vals = vals.map(item => arg[item]); | ||
} | ||
throw Error('"getEnumKeys" be an non-array object'); | ||
return [ | ||
vals[0], | ||
arg => vals.some(val => val === arg), | ||
]; | ||
} | ||
@@ -52,0 +53,0 @@ function isBasicObj(arg) { |
{ | ||
"name": "jet-schema", | ||
"version": "1.0.9", | ||
"version": "1.1.0", | ||
"description": "Simple, typescript-first schema validation tool", | ||
@@ -8,3 +8,3 @@ "main": "dist/index.js", | ||
"scripts": { | ||
"test": "vitest", | ||
"test": "NODE_ENV=test vitest", | ||
"test:pg": "ts-node ./test/playground.ts", | ||
@@ -11,0 +11,0 @@ "build": "rm -rf ./dist && tsc -p tsconfig.build.json" |
@@ -69,3 +69,3 @@ # Jet-Schema ✈️ | ||
country: isOptionalStr, | ||
}, true), | ||
}, { optional: true }), | ||
}); | ||
@@ -84,6 +84,6 @@ ``` | ||
`jetSchema()` accepts three optional arguments: | ||
- An array-map `[["val", "function"]]` 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 function in the `jetSchema()` function, you can also pass a 2 length array of the default value and the validator-function when `schema` is called (the next 3 snippets below contain examples). | ||
- The second is a custom clone-function if you don't want to use the built-in function which uses `structuredClone` (I like to use `lodash.cloneDeep`). | ||
- 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. Function must have the format: `(property: string, value?: unknown) => void;` | ||
`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 function in the `jetSchema()` function, you can also pass a 2 length array of the default value and the validator-function when `schema` is called (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. Function must have the format: `(property: string, value?: unknown) => void;` | ||
@@ -94,3 +94,3 @@ > 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`. | ||
// "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) | ||
export const isStr = (arg: unknown): arg is string => typeof param === 'string'; | ||
@@ -108,9 +108,10 @@ export const isOptStr = (arg: unknown): arg is string => arg === undefined || typeof param === 'string'; | ||
export default jetSchema([ | ||
[isNum, 0], | ||
[isStr, ''], | ||
], | ||
'...pass a custom clone-function here...', | ||
'...pass a custom error-handler here...', | ||
); | ||
export default jetLogger({ | ||
defaultValuesMap: [ | ||
[isNum, 0], | ||
[isStr, ''], | ||
], | ||
cloneFn: // pass a custom clone-function here | ||
onError: // pass a custom error-handler here, | ||
}); | ||
``` | ||
@@ -125,7 +126,5 @@ | ||
import { inferType } from 'jet-schema'; | ||
import schema from 'util/schema.ts'; | ||
import { isNum, isStr, isOptionalStr } from 'util/type-checks'; | ||
// **OPTION 1**: Create schema using type | ||
@@ -164,7 +163,17 @@ interface IUser { | ||
### Making schemas optional/nullable <a name="making-schemas-opt-null"></a> | ||
In addition to a schema-object, the `schema()` function accepts 3 additional parameters `isOptional`, `isNullable`, and `default`. These are type-checked against the type supplied to schema (`schema<...Your Type...>()`), so you must supply the correct parameters. So for example, if the schema-type is nullable and optional, then you must enter `true` for the second and third parameters.<br/> | ||
In addition to a schema-object, the `schema` function accepts an additional **options** object parameter. The values here are type-checkd against the generic (`schema<"The Generic">(...)`) that was passed so you must used 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.<nr/> | ||
The third option `default` defines the behavior for nested schemas when initialized from a parent. The value can be a `boolean` or `null`. If `false` the value will not be initialized with the parent, if `null` (the schema must be nullable to do this) the value will be `null`, and if `true` or `undefined` then a full schema object will be created when a parent object is created. The default value for the `default` parameter is `true`. If a nested schema is neither optional or nullable, then `default` must be true. | ||
The third option `init` defines the behavior when a schema is a child-schema and is being initialized from the parent. If a child-schema is optional/nullable, maybe you don't want a nested object and just want it to be null or skipped entirely. If `init` is `null` then `nullable` must be `true`, if `false` then `optional` must be `true`. | ||
```typescript | ||
{ | ||
optional?: boolean; // default "false", must be true if generic is optional | ||
nullable?: boolean; // default "false", must be true if generic is nullable | ||
init?: boolean | null; // default "true", must be undefined, true, or null if generic is not optional. | ||
} | ||
``` | ||
Here's an example of the options in use: | ||
```typescript | ||
// models/User.ts | ||
@@ -184,13 +193,6 @@ | ||
zip: isNumber, | ||
}, true /*(isOptional)*/, true /*(isNullable)*/, /*default*/) // You MUST pass true for "isOptional" and "isNullable" here. | ||
}, { optional: true, nullable: true, init: false }), | ||
}) | ||
const User1 = schema<IUser>({ | ||
id: isNumber, | ||
name: isString, | ||
address: schema({ | ||
street: isString, | ||
zip: isNumber, | ||
}, false, false, false) // **ERROR** since this nested schema is neither optional or nullable, the default cannot be false. | ||
}) | ||
User.new() // => { id: 0, name: '' } | ||
``` | ||
@@ -256,3 +258,3 @@ | ||
street: isString, | ||
}, true, true) | ||
}, { optional: true, nullable: true }), | ||
}) | ||
@@ -276,3 +278,3 @@ | ||
### Recommended Defaults <a name="recommended-defaults"></a> | ||
When calling the `jetSchema` function for this first time, at the very least, I highly recommended you set these default values for each of your basic primitive validator functions, unless of course your application has some other specific need. | ||
When calling the `jetSchema` function for this first time, at the very least, I highly recommend you set these default values for each of your basic primitive validator functions, unless of course your application has some other specific need. | ||
```typescript | ||
@@ -282,8 +284,9 @@ // util/schema.ts | ||
export default jetSchema([ | ||
[isBool, false], | ||
[isStr, ''], | ||
[isNum, 0], | ||
]); | ||
``` | ||
export default jetLogger({ | ||
defaultValuesMap: [ | ||
[isNum, 0], | ||
[isStr, ''], | ||
[isBool, false], | ||
], | ||
}); | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
70744
2.03%491
0.2%283
1.43%