# thor-validation **Repository Path**: thor.qin/thor-validation ## Basic Information - **Project Name**: thor-validation - **Description**: JavaScript validation toolkit - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2020-05-16 - **Last Updated**: 2025-07-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # @knno/valid ## Description A TypeScript/JavaScript validation toolkit. ## Installation ``` npm i @knno/valid ``` ## What this validation tool can do? - Validate user-provided data early without putting validation logic in business code - Structured validation rules enable automatic API documentation generation - TypeScript support with type inference - Customizable error messages - Composable and reusable validation rules ## Getting Started ```javascript import {Schema, string} from '@knno/valid'; // 1. Define validation rule const rule = string(min(10), max(100)); // 2. Create validator const schema = new Schema(rule); // 3. Validate data try { schema.validate('Hello World!'); } catch (e) { console.log(e.message); // Handle validation error } ``` ## Major Rule Definitions 1. **need()** ```javascript // input can not be undefined or null let rule = need(); // input can not be undefined or null and it must be a string let rule = need(string()); // must be a number let rule = need(number()) // must be a string or a number let rule = need(union(string(), number())); ... ``` ***need*** rule can only have primitive rule as it's sub rule, all supported sub rules are: ``` object, string, number, array, boolean, date, union ``` 2. **string()** ```javascript // input should be a string, but if input not provide or it is null, it won't be regarded as error. let rule = string(); // must be a string and cannot be null or undefined let rule = need(string()); // string length must at least have 10 characters let rule = string(min(10)); // string length must at most have 100 characters let rule = string(max(100)); // string must match the regular expression let rule = string(match(/^\d+$/)); // string must be a particular value let rule = string(equal('abc')); // verfication successful if all of the following conditions are met let rule = string(min(10), max(100)); // verfication successful if any of the following conditions are met let rule = string(any(equal('abc'), equal('def'), min(10), pattern(/^\d+$/))); ... ``` 3. **number()** ```javascript let rule = number(); // value should great or equal to 10 let rule = number(min(10)); // value should great to 10 let rule = number(more(10)); // value should less or equal to 100 let rule = number(max(100)); // value should less 100 let rule = number(less(100)); let rule = number(range(10, 100)); let rule = number(equal(33)); let rule = number(any(equal(33), equal(44), equal(55))); ``` 4. **boolean()** ```javascript let rule = boolean(); let rule = boolean(equal(true)); ``` 5. **date()** ```javascript let rule = date(); let rule = date(equal('2019-1-1')); let rule = date(begin('2019-1-1')); let rule = date(end('2020-1-1')); let rule = date(before('2020-1-1')); let rule = date(after('2019-1-1')); let rule = date(between('2019-1-1', '2020-1-1')); let rule = date(any(before('2019-1-1', between('2020-3-1', '2020-5-1')))); ``` 6. **object()** ```javascript let rule = object(); let rule = object( prop('name', string()), prop('age', number()), prop('extra', need()), prop('detail', need( object( prop('id', need(number())), prop('account', need(string())) ) )) ); ``` 7. **array()** ```javascript let rule = array(); let rule = array( item(need( union( object( prop('id', need(number())), prop('account', need(string())) ), string() ) )), min(10), max(20) ); ``` 8. **union()** That's means value can be multiple types. ```javascript let rule = union(string(), number()); ... ``` 9. **any() and all()** This two rules can combine a group of sub rules to reach more complex condition check. ```javascript let rule = string(any(min(10), all(pattern(/^A/), min(5)))); ``` 10. **not()** Makes the match condition negated! (can only have one sub rule) ```javascript let rule = string(any(min(10), not(match(/^A/)))); let rule = string(not(any(min(10), match(/^A/)))); let rule = string(not(all(min(10), match(/^A/)))); ``` Above expression means either the string greater or equals to 10 character length or greater or equal to 5 character length and starts with character 'A'. ## Rename Rule Name You can rename any rule name as what your like, this usually can shorten your code: ```javascript import {Schema, string as s, number as n, need as r, object as o, prop as p} from '@knno/valid'; let rule = r(o( p('name', r(s(min(1), max(30)))), p('age', r(n(min(18)))) )); ``` ## Split Definition To make the code clearly, usually you can split a complex definition to several parts: ```javascript let detail = need(object( prop('name', need(string())), prop('account', need(string())), )); let users = need(array( item(detail), min(1), max(1000) )); let rule = need(object( prop('action', need(string())), prop('users', users) )); try { let schema = new Schema(rule); schema.validate({ action: 'show', users: [{ name: 'user 1', account: 'account1' },{ name: 'user 2', account: 'account2' }] }); } catch (e) { console.log(e.message); } ``` ## Specify Custom Message 1. **mismatch()** There have a particular rule ```mismatch()```, it can under the primitive type rule used to specify error message when input type doesn't match the expected type. ```javascript let rule = string(mismatch('There need a string')); ``` 2. **need()** ```javascript let rule = need(object(), 'use custom message'); ``` 3. **Other check rules** Any check rules can accept a string as last parameter as custom message. ```javascript let rule = string(max(20, 'String length cannot be more than 20 characters')); ``` ## Simplified type definition syntax The `define()` function allows creating validation rules with type inference: ```typescript import { define, req, obj, str, num } from '@knno/valid'; // Define both type and validation rules const userType = define(() => req(obj({ name: req(str(min(3))), age: req(num()) })) ); // Use inferred type const user: typeof userType.type = { name: "John", age: 30 }; // Create validator const validator = new Schema(userType.rule); ``` ### Integration with @knno/web Seamless integration with @knno/web framework for API parameter validation: ```typescript import { define, num, obj, str, req } from '@knno/valid'; import { DefaultContext, query, title, result, desc } from '@knno/web'; // Parameter definition const paramsDef = define(() => req(obj({ id: req(num()) })) ); // Request body definition const bodyDef = define(() => req(obj({ field1: req(str(min(3))), field2: req(num()) })) ); @title('Sample API') export default class SampleController { @desc('API description...') @query(paramsDef) @result('None') async post(ctx: DefaultContext): Promise { const params = ctx.getParams(paramsDef); const payload = ctx.body.json(bodyDef); // Use validated parameters... } } ``` See [@knno/web](https://www.npmjs.com/package/@knno/web) **NOTE:** **Usually we don't need to specify any custom message, because the builtin error message will provide more detailed info.** --- That's all If you find any problem please feel free to report to [issues](https://gitee.com/thor.qin/@knno/valid/issues), I would appreciate your contribution.