A flexible, chainable validation rule factory for TypeScript/JavaScript.
- Chainable API for building complex validation rules
- Supports string, number, array, boolean, object, symbol, bigint, null, undefined
- Customizable error messages
- Easy to extend and integrate
- TypeScript support
pnpm add ruler-factory
# or
npm install ruler-factory
# or
yarn add ruler-factory
<script setup lang="ts">
import { ref } from 'vue'
import { rulerFactory } from 'ruler-factory'
const ruler = rulerFactory((validator) => {
return (value) => {
const e = validator(value)
return e ? e.message : true
}
})
const model = ref({
name: '',
email: '',
})
</script>
<template>
<var-form>
<var-input
v-model="model.name"
placeholder="Name"
:rules="ruler().required('Required').min(2, 'Wrong length').done()"
/>
<var-input v-model="model.age" placeholder="Email" :rules="ruler().email('Must be email format').done()" />
</var-form>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { rulerFactory } from 'ruler-factory'
import type { FieldRule } from 'vant'
const ruler = rulerFactory<FieldRule>((validator, params) => ({
validator(value) {
const e = validator(value)
return e ? e.message : true
},
trigger: ['onChange', 'onBlur', 'onSubmit'],
...params,
}))
const model = ref({
name: '',
email: '',
})
</script>
<template>
<van-form>
<van-cell-group inset>
<van-field v-model="model.name" label="Name" placeholder="Name" :rules="ruler().required('Required').done()" />
<van-field
v-model="model.email"
label="Email"
placeholder="Email"
:rules="ruler().email('Must be email format').done()"
/>
</van-cell-group>
</van-form>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { FormItemRule } from 'naive-ui'
import { rulerFactory } from 'ruler-factory'
const ruler = rulerFactory<FormItemRule>((validator, params = {}) => ({
trigger: ['blur', 'change', 'input'],
validator: (_, value) => validator(value),
...params,
}))
const model = ref({
name: '',
age: 20,
})
</script>
<template>
<n-form :model>
<n-form-item path="name" label="Name" :rule="ruler().required('Required').min(2, 'Wrong length').done()">
<n-input v-model:value="model.name" />
</n-form-item>
<n-form-item
path="age"
label="Age"
:rule="ruler().number().required('Required').negative('Must be negative').done()"
>
<n-input-number v-model:value="model.age" />
</n-form-item>
</n-form>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { FormItemRule } from 'element-plus'
import { rulerFactory } from 'ruler-factory'
const ruler = rulerFactory<FormItemRule>((validator, params) => ({
validator(_, value, callback) {
const e = validator(value)
e ? callback(e) : callback()
},
trigger: ['blur', 'change', 'input'],
...params,
}))
const model = ref({
name: '',
email: '',
})
</script>
<template>
<el-form :model>
<el-form-item prop="name" label="Name" :rules="ruler().required('Required').done()">
<el-input v-model="model.name" />
</el-form-item>
<el-form-item prop="email" label="Email" :rules="ruler().email('Must be email format').done()">
<el-input v-model="model.email" />
</el-form-item>
</el-form>
</template>
Take Naive UI
as an example
import { FormItemRule } from 'naive-ui'
import { RulerContext, rulerFactory, RulerFactoryMessage } from 'ruler-factory'
interface RulerExtendedContext {
ip(message: RulerFactoryMessage, params?: FormItemRule): RulerContext<FormItemRule, FormItemRule, this>
}
customRuler().ip('ip format error').done()
const ruler = rulerFactory<FormItemRule, FormItemRule, RulerExtendedContext>(
(validator, params = {}) => ({
trigger: ['blur', 'change', 'input'],
validator: (_, value) => validator(value),
...params,
}),
(ctx) => {
function ip(message: RulerFactoryMessage, params?: FormItemRule) {
ctx.addRule((value) => {
// Implement isString and isIP by yourself
if (!isString(value) || !isIP(value)) {
return new Error(ctx.getMessage(message))
}
}, params)
return ctx
}
return { ip }
},
)
.string(message?, params?)
.number(message?, params?)
.array(message?, params?)
.boolean(message?, params?)
.object(message?, params?)
.symbol(message?, params?)
.bigint(message?, params?)
.null(message?, params?)
.undefined(message?, params?)
.true(message?, params?)
.false(message?, params?)
.required(message)
.min(value, message, params?)
.max(value, message, params?)
.length(value, message, params?)
.regex(regexp, message, params?)
.startsWith(value, message, params?)
.endsWith(value, message, params?)
.includes(value, message, params?)
.uppercase(message, params?)
.lowercase(message, params?)
.email(message, params?)
.number().min(value, message, params?)
.number().max(value, message, params?)
.number().gt(value, message, params?)
.number().gte(value, message, params?)
alias .min.number().lt(value, message, params?)
.number().lte(value, message, params?)
alias .max.number().positive(value, message, params?)
.number().negative(value, message, params?)
.bigint().min(value, message, params?)
.bigint().max(value, message, params?)
.bigint().gt(value, message, params?)
.bigint().gte(value, message, params?)
alias .min.bigint().lt(value, message, params?)
.bigint().lte(value, message, params?)
alias .max.bigint().positive(value, message, params?)
.bigint().negative(value, message, params?)
.array().min(value, message, params?)
.array().max(value, message, params?)
.array().length(value, message, params?)
.array().includes(value, message, params?)
.is(fn, message, params?)
.not(fn, message, params?)
.done()
.addRule(validator)
.trim()
.toLowerCase()
.toUpperCase()
.transform(fn)
MIT