Skip to content

Schemas libraries

Regle supports the Standard Schema Spec.

This means any Standard Schema compliant RPC library can be used with Regle.

Official list of supported libraries:

sh
pnpm add @regle/schemas
sh
npm install @regle/schemas
sh
yarn add @regle/schemas
sh
bun add @regle/schemas

Usage

Instead of using the core useRegle, use useRegleSchema export from @regle/schemas.

ts
import { 
useRegleSchema
} from '@regle/schemas';
import {
z
} from 'zod';
const {
r$
} =
useRegleSchema
({
name
: '' },
z
.
object
({
name
:
z
.
string
().
min
(1)
}))
ts
import { 
useRegleSchema
} from '@regle/schemas';
import * as
v
from 'valibot';
const {
r$
} =
useRegleSchema
({
name
: '' },
v
.
object
({
name
:
v
.
pipe
(
v
.
string
(),
v
.
minLength
(3))
}))
ts
import { 
useRegleSchema
} from '@regle/schemas';
import {
type
} from 'arktype';
const {
r$
} =
useRegleSchema
({
name
: '' },
type
({
name
: "string > 1"
}))

WARNING

Limitations from the core behaviour

Using schema libraries uses a different mechanism than the core "rules" one. Regle will parse the entire tree instead of doing it per-field. Than means that properties or methods are not available in nested values:

  • $validate (only at root)
  • $pending (only at root)

Computed schema

You can also have a computed schema that can be based on other state values.

WARNING

When doing refinements or transform, Vue can't track what the schema depends on because you're in a function callback.

Same way as withParams from @regle/rules, you can use the withDeps helper to force dependencies on any schema

ts
import { 
useRegleSchema
,
inferSchema
,
withDeps
} from '@regle/schemas';
import {
z
} from 'zod';
import {
ref
,
computed
} from 'vue';
type
Form
= {
firstName
?: string;
lastName
?: string
} const
form
=
ref
<
Form
>({
firstName
: '',
lastName
: '' })
const
schema
=
computed
(() =>
inferSchema
(
form
,
z
.
object
({
firstName
:
z
.
string
(),
/** * Important to keep track of the depency change * Without it, the validator wouldn't run if `firstName` changed */
lastName
:
withDeps
(
z
.
string
().
refine
((
v
) =>
v
!==
form
.
value
.
firstName
, {
message
: "Last name can't be equal to first name",
}), [() =>
form
.
value
.
firstName
]
), })) ); const {
r$
} =
useRegleSchema
(
form
,
schema
);
ts
import { 
useRegleSchema
,
inferSchema
,
withDeps
} from '@regle/schemas';
import * as
v
from 'valibot';
import {
ref
,
computed
} from 'vue';
type
Form
= {
firstName
?: string;
lastName
?: string
} const
form
=
ref
<
Form
>({
firstName
: '',
lastName
: '' })
const
schema
=
computed
(() =>
inferSchema
(
form
,
v
.
object
({
firstName
:
v
.
string
(),
/** * Important to keep track of the depency change * Without it, the validator wouldn't run if `firstName` changed */
lastName
:
withDeps
(
v
.
pipe
(
v
.
string
(),
v
.
check
((
v
) =>
v
!==
form
.
value
.
firstName
, "Last name can't be equal to first name")
), [() =>
form
.
value
.
firstName
]
), })) ) const {
r$
} =
useRegleSchema
(
form
,
schema
);

Type safe output

Similar to the main useRegle composable, r$.$validate also returns a type-safe output using Zod type schema parser.

ts
import { 
useRegleSchema
,
inferSchema
} from '@regle/schemas';
import {
z
} from 'zod';
import {
ref
,
computed
} from 'vue';
type
Form
= {
firstName
?: string;
lastName
?: string
} const
form
=
ref
<
Form
>({
firstName
: '',
lastName
: '' })
const
schema
=
computed
(() =>
inferSchema
(
form
,
z
.
object
({
firstName
:
z
.
string
().
optional
(),
lastName
:
z
.
string
().
min
(1).
refine
(
v
=>
v
!==
form
.
value
.
firstName
, {
message
: "Last name can't be equal to first name"
}), }))) const {
r$
} =
useRegleSchema
(
form
,
schema
);
async function
submit
() {
const {
result
,
data
} = await
r$
.
$validate
();
if (
result
) {
console
.
log
(
data
);
} }
ts
import { 
useRegleSchema
,
inferSchema
} from '@regle/schemas';
import * as
v
from 'valibot';
import {
ref
,
computed
} from 'vue';
type
Form
= {
firstName
?: string;
lastName
?: string
} const
form
=
ref
<
Form
>({
firstName
: '',
lastName
: '' })
const
schema
=
computed
(() => {
return
inferSchema
(
form
,
v
.
object
({
firstName
:
v
.
optional
(
v
.
string
()),
lastName
:
v
.
pipe
(
v
.
string
(),
v
.
minLength
(3),
v
.
check
((
v
) =>
v
!==
form
.
value
.
firstName
, "Last name can't be equal to first name")
) })) }) const {
r$
} =
useRegleSchema
(
form
,
schema
);
async function
submit
() {
const {
result
,
data
} = await
r$
.
$validate
();
if (
result
) {
console
.
log
(
data
);
} }
ts
import { 
useRegleSchema
,
inferSchema
} from '@regle/schemas';
import {
type
} from 'arktype';
import {
ref
,
computed
} from 'vue';
type
Form
= {
firstName
?: string;
lastName
?: string
} const
form
=
ref
<
Form
>({
firstName
: '',
lastName
: '' })
const
schema
=
computed
(() => {
return
inferSchema
(
form
,
type
({
'firstName?': 'string',
lastName
: 'string > 3',
}).
narrow
((
data
,
ctx
) => {
if (
data
.
firstName
!==
data
.
lastName
) {
return true; } return
ctx
.
reject
({
expected
: 'different than firstName',
path
: ['lastName'],
}); })) }) const {
r$
} =
useRegleSchema
(
form
,
schema
);
async function
submit
() {
const {
result
,
data
} = await
r$
.
$validate
();
if (
result
) {
console
.
log
(
data
);
} }

Released under the MIT License. Logo by Johannes Lacourly