@regle/mcp-server 1.21.1 → 1.21.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/regle-mcp-server.js +98 -98
- package/package.json +4 -4
package/dist/regle-mcp-server.js
CHANGED
|
@@ -26,7 +26,7 @@ const rawData = {
|
|
|
26
26
|
"title": "markStatic",
|
|
27
27
|
"category": "advanced-usage",
|
|
28
28
|
"path": "advanced-usage/immutable-constructors.md",
|
|
29
|
-
"content": "# Handling immutable constructors\n\nRegle works by tracking changes in the state and updating the validation rules accordingly.\n\nThis works great for objects and arrays, but not for immutable constructors (like `Decimal` from `decimal.js` or `Moment` from `moment.js`, etc...).\n\nThis constructors will be interpreted as regular objects and their properties treated as nested fields.\n\n## Default Usage\n\nTo handle these cases, you can use the `markStatic` helper to mark the value as static and treat the constructor as a regular raw Field.\n\n```vue\n<template>\n <input :value=\"r$.decimal.$value?.toString()\" @input=\"handleDecimalInput\" />\n</template>\n\n```\n\n## Schema Usage\n\nWhen using Regle with `@regle/schemas`, you will have to also declare the static constructor in the schema.\n\n```ts\nimport { markStatic
|
|
29
|
+
"content": "# Handling immutable constructors\n\nRegle works by tracking changes in the state and updating the validation rules accordingly.\n\nThis works great for objects and arrays, but not for immutable constructors (like `Decimal` from `decimal.js` or `Moment` from `moment.js`, etc...).\n\nThis constructors will be interpreted as regular objects and their properties treated as nested fields.\n\n## Default Usage\n\nTo handle these cases, you can use the `markStatic` helper to mark the value as static and treat the constructor as a regular raw Field.\n\n```vue\n<template>\n <input :value=\"r$.decimal.$value?.toString()\" @input=\"handleDecimalInput\" />\n</template>\n\n```\n\n## Schema Usage\n\nWhen using Regle with `@regle/schemas`, you will have to also declare the static constructor in the schema.\n\n```ts\nimport { markStatic } from '@regle/core'\nimport { useRegleSchema } from '@regle/schemas'\nimport { z } from 'zod'\n\nconst StaticDecimal = markStatic(Decimal)\n\nconst schema = z.object({\n decimal: z.instanceof(StaticDecimal).refine((value) => value.toNumber() > 10),\n})\n\nconst { r$ } = useRegleSchema({ decimal: new StaticDecimal(0) }, schema)\n\n```\n\n## `isStatic` helper\n\nYou can use the `isStatic` helper to check if a value is a static value.\n\n```ts\nimport { isStatic } from '@regle/core';\n\nconst result = isStatic(r$.$value.decimal); // true\n```\n\n## `UnwrapStatic` type helper\n\nYou can use the `UnwrapStatic` type to unwrap a static value.\n\n```ts\nimport { type UnwrapStatic } from '@regle/core';\n\ntype value = UnwrapStatic<typeof r$.$value.decimal>; // Decimal\n```\n\n## `isRegleStatic` type helper\n\nYou can use the `isRegleStatic` type helper to check if a value is a static value.\n\n```ts\nimport { type isRegleStatic } from '@regle/core';\n\ntype isStatic = isRegleStatic<typeof state.decimal>; // true\n```"
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
"id": "advanced-usage-merge-regles",
|
|
@@ -47,7 +47,7 @@ const rawData = {
|
|
|
47
47
|
"title": "Scoped validation",
|
|
48
48
|
"category": "advanced-usage",
|
|
49
49
|
"path": "advanced-usage/scoped-validation.md",
|
|
50
|
-
"content": "# Scoped validation\n\nScoped validation in Regle is made to port Vuelidate's `nested component validation`.\n\nProblems with Vuelidate's approach:\n - Performances\n - Not declarative\n - Usage (too magic for the user)\n - Type safety\n - Restricted to DOM\n - Have to play with `$scope` and `$stopPropagation` to avoid unwanted behaviour\n\nRegle's solution solves all
|
|
50
|
+
"content": "# Scoped validation\n\nScoped validation in Regle is made to port Vuelidate's `nested component validation`.\n\nProblems with Vuelidate's approach:\n - Performances\n - Not declarative\n - Usage (too magic for the user)\n - Type safety\n - Restricted to DOM\n - Have to play with `$scope` and `$stopPropagation` to avoid unwanted behaviour\n\nRegle's solution solves all these problems\n\n## Collecting validation with `useCollectScope` and `useScopedRegle`\n\n### `useScopedRegle`\n\n`useScopedRegle` is a clone of `useRegle`, but with the difference that every time it's used and updated, its state will be collected by the same scope created using `createScopedUseRegle`.\n\nEvery time it's called, a instance will be added for `useCollectScope` to collect.\n\nIt can be called multiple times at any place, not only on components, as it's not restricted by DOM.\n\n### `useCollectScope`\n\nThis composable allow you to retrieve every Regle instances created using the sibling composable `useScopedRegle`.\n\nChildren properties like `$value` and `$errors` will not be objects, and are converted into arrays instead.\n\nYou will also have access to every validation properties like `$error`, `$invalid` etc...\n\n:::code-group\n\n```vue [Parent.vue]\n<template>\n <div>\n <Child1 />\n </div>\n\n <Child2 />\n\n Collected errors: <pre>{{ r$.$errors }}</pre>\n</template>\n\n```\n\n```vue [Child1.vue]\n<template>\n <input v-model=\"r$.$value.firstName\" placeholder=\"Type your firstname\" />\n <ul>\n <li v-for=\"error of r$.$errors.firstName\" :key=\"error\">\n {{ error }}\n </li>\n </ul>\n</template>\n\n```\n\n```vue [Child2.vue]\n<template>\n <input v-model=\"r$.$value.email\" placeholder=\"Type your email\" />\n <ul>\n <li v-for=\"error of r$.$errors.email\" :key=\"error\">\n {{ error }}\n </li>\n </ul>\n</template>\n\n```\n:::\n\nResult:\n\n## Multiple scopes\n\nIf you want to create your own separated scope, you can use `createScopedUseRegle` helper method.\n\nIt's advised to change the name of this composable to avoid conflicts or issues.\n\n```ts [scoped-config.ts]\nimport { createScopedUseRegle } from '@regle/core';\n\nexport const { useScopedRegle, useCollectScope } = createScopedUseRegle();\nexport const { \n useScopedRegle: useContactsRegle, \n useCollectScope: useCollectContacts \n} = createScopedUseRegle();\n```\n\n## Namespaces inside scopes\n\nEach scope can collect a specific namespace. Giving a namespace name will collect only the children with the same namespace name.\n\nThe namespace can be reactive, so it will update every time it changes.\n\nIn this example, only the components using the same scope and namespace will be collected.\n\n:::code-group\n```vue [Parent.vue]\n\n```\n\n```vue [Child1.vue]\n<template>\n <input v-model=\"r$.$value.firstName\" placeholder=\"Type your firstname\" />\n <ul>\n <li v-for=\"error of r$.$errors.firstName\" :key=\"error\">\n {{ error }}\n </li>\n </ul>\n</template>\n\n```\n\n```vue [Child2.vue]\n<template>\n <input v-model=\"r$.$value.email\" placeholder=\"Type your email\" />\n <ul>\n <li v-for=\"error of r$.$errors.email\" :key=\"error\">\n {{ error }}\n </li>\n </ul>\n</template>\n\n```\n\nYou can also collect multiple namespaces at once by passing an array of namespace names to the `useCollectScope` function.\n\n```ts\nconst { r$ } = useCollectScope(['contacts', 'persons']);\n```\n:::\n\n## Inject global config\n\nIf you have a global config already registered, simply pass it as a parameter to your `createScopedUseRegle` function.\n\n```ts twoslash [scoped-config.ts]\nimport { createScopedUseRegle, defineRegleConfig } from '@regle/core';\nimport { required, withMessage } from '@regle/rules';\n\nconst { useRegle } = defineRegleConfig({\n rules: () => ({\n custom: withMessage(required, 'Custom error'),\n }),\n});\n\nexport const { useScopedRegle, useCollectScope } = createScopedUseRegle({customUseRegle: useRegle});\n\nconst {r$} = useScopedRegle({name: ''}, {\n name: {\n cus\n\n }\n})\n\n```\n\n## Custom store for instances\n\nBy default collected instances are stored in a local ref. \n\nYou can provide your own store ref.\n\n```ts\nimport { createScopedUseRegle, type ScopedInstancesRecordLike } from '@regle/core';\n\n// Having a default \nconst myCustomStore = ref<ScopedInstancesRecordLike>({});\n\nconst { useScopedRegle, useCollectScope } = createScopedUseRegle({customStore: myCustomStore});\n```\n\n## Collect instances in a Record\n\nBy default collected instances are stored in a readonly array.\n\nIf you want to store your nested instances in a record it's possible with the `asRecord` option.\n\nThis will **require** every nested `useScopeRegle` to provide a parameter `id`.\n\n:::code-group\n\n```ts [scoped-config.ts]\nimport { createScopedUseRegle } from '@regle/core';\n\nexport const { \n useScopedRegle: useScopedRegleItem, \n useCollectScope: useCollectScopeRecord \n} = createScopedUseRegle({ asRecord: true });\n```\n```vue [Parent.vue]\n\n```\n\n```vue [Child1.vue]\n<template>\n <input v-model=\"r$.$value.firstName\" placeholder=\"Type your firstname\" />\n <ul>\n <li v-for=\"error of r$.$errors.firstName\" :key=\"error\">\n {{ error }}\n </li>\n </ul>\n</template>\n\n```\n\n```vue [Child2.vue]\n<template>\n <input v-model=\"r$.$value.email\" placeholder=\"Type your email\" />\n <ul>\n <li v-for=\"error of r$.$errors.email\" :key=\"error\">\n {{ error }}\n </li>\n </ul>\n</template>\n\n```\n:::\n\n## Manually dispose or register a scope entry\n\n`useScopedRegle` also returns two methods: `dispose` and `register`.\n\nYou can then programmatically handle if your component is collected from inside.\n\n```vue\n\n```\n\n## Manual typing\n\n:::warning\nUse with care, only if you're 100% sure of what return type your collected types will have.\n\nThe order of the collected values can change depending on if they added/deleted.\nThis is here for convenience but not advised.\n:::\n\n```ts twoslash\nimport { useCollectScope } from '@regle/core';\n\nconst { r$ } = useCollectScope<[{ foo: string }]>();\n\nconst { valid, data } = await r$.$validate();\n\n```\n\n## Testing\n\nIf you write unit test for a component using scoped validation, you may encounter problems with the tests failing.\n\nTo solve this, mount your component with the `attachTo` option set to the document element.\n\n```ts\nimport { mount } from '@vue/test-utils';\nimport ComponentUsingCollectScope from './ComponentUsingCollectScope.vue';\n\nconst wrapper = mount(ComponentUsingCollectScope, {\n attachTo: document.documentElement,\n});\n```"
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
"id": "advanced-usage-self-validation",
|
|
@@ -61,7 +61,7 @@ const rawData = {
|
|
|
61
61
|
"title": "Variants",
|
|
62
62
|
"category": "advanced-usage",
|
|
63
63
|
"path": "advanced-usage/variants.md",
|
|
64
|
-
"content": "# Variants or discriminated unions\n\nYour form may not be linear, and have multiple fields that depends on a condition or a toggle.\nIt can be complex and become a mess when trying to organise your types around it.\n\nRegle variants offer a way to simply declare and use this discriminated unions, while keeping all fields correctly types and also runtime safe.\n\n## `createVariant`\n\nThe first
|
|
64
|
+
"content": "# Variants or discriminated unions\n\nYour form may not be linear, and have multiple fields that depends on a condition or a toggle.\nIt can be complex and become a mess when trying to organise your types around it.\n\nRegle variants offer a way to simply declare and use this discriminated unions, while keeping all fields correctly types and also runtime safe.\n\n## `createVariant`\n\nThe first step to Regle variants is to have a type that includes a discriminated variant.\n\n```ts twoslash include form-types\ntype FormStateLoginType = \n| {type: 'EMAIL', email: string} \n| {type: 'GITHUB', username: string} \n| {type?: undefined}\n\ntype FormState = {\n firstName?: string;\n lastName?: string;\n} & FormStateLoginType\n```\n\nHere your state can have two possible outcomes, but with classic rules it's hard to handle fields statuses as they can always be undefined.\n\nThe solution to this is to first declare your variant-related rules inside `createVariant` like this:\n\n```ts twoslash include main\nimport {ref} from 'vue';\n\n// ---cut---\nimport { useRegle, createVariant} from '@regle/core';\nimport { literal, required, email } from '@regle/rules';\n\nconst state = ref<FormState>({})\n\n// ⚠️ Use getter syntax for your rules () => {} or a computed one\nconst {r$} = useRegle(state, () => {\n /** \n * Here you create you rules variations, see each member as a `OR` \n * `type` here is the discriminant\n * \n * Depending of the value of `type`, Regle will apply the corresponding rules.\n */\n const variant = createVariant(state, 'type', [\n {type: { literal: literal('EMAIL')}, email: { required, email }},\n {type: { literal: literal('GITHUB')}, username: { required }},\n {type: { required }},\n ]);\n\n return {\n firstName: {required},\n // Don't forget to return the computed rules\n ...variant.value,\n };\n})\n```\n\n## `narrowVariant`\n\nIn your form, you'll need to use type narrowing to access your field status somehow. \n\nFor this you'll have to discriminate the `$fields` depending on value. As the status uses deeply nested properties, this will not be possible with a standard guard `if (value === \"EMAIL\")`.\n\nIn your template or script, you can use Regle's `narrowVariant` helper to narrow the fields to the value.\n\nLet's take the previous example again:\n\n```vue twoslash\n<template>\n <input v-model=\"r$.firstName.$value\" placeholder='First name'/>\n <Errors :errors=\"r$.firstName.$errors\"/>\n\n <select v-model=\"r$.type.$value\">\n <option disabled value=\"\">Account type</option>\n <option value=\"EMAIL\">Email</option>\n <option value=\"GITHUB\">Github</option>\n </select>\n\n <div v-if=\"narrowVariant(r$, 'type', 'EMAIL')\">\n <!-- `email` is now a known field in this block -->\n <input v-model=\"r$.email.$value\" placeholder='Email'/>\n <Errors :errors=\"r$.email.$errors\"/>\n </div>\n \n <div v-else-if=\"narrowVariant(r$, 'type', 'GITHUB')\">\n <!-- `username` is now a known field in this block -->\n <input v-model=\"r$.username.$value\" placeholder='Username'/>\n <Errors :errors=\"r$.username.$errors\"/>\n \n </div>\n\n</template>\n\n```\n\nResult:\n\n### Nested variants\n\nAll the above also works for nested variants\n\n```ts twoslash include nested-types\ntype FormState = {\n firstName?: string;\n lastName?: string;\n login: \n | {type: 'EMAIL', email: string} \n | {type: 'GITHUB', username: string} \n | {type?: undefined}\n}\n\n```\n\n:::warning\nThe first argument of `createVariant` needs to be reactive. For nested values, use getter syntax.\n:::\n\n```ts twoslash include nested-regle\nimport {ref, defineComponent} from 'vue';\n\nconst Errors = defineComponent({});\n\n// ---cut---\nimport { useRegle, createVariant} from '@regle/core';\nimport { literal, required, email } from '@regle/rules';\n\nconst state = ref<FormState>({\n firstName: '',\n login: {}\n})\n\nconst {r$} = useRegle(state, () => {\n\n const loginVariant = createVariant(() => state.value.login, 'type', [\n {type: { literal: literal('EMAIL')}, email: { required, email }},\n {type: { literal: literal('GITHUB')}, username: { required }},\n {type: { required}},\n ]);\n\n return {\n firstName: {required},\n login: loginVariant.value\n };\n})\n```\n\nIn the component:\n\n```vue twoslash\n<template>\n <input v-model=\"r$.firstName.$value\" placeholder='First name'/>\n <Errors :errors=\"r$.firstName.$errors\"/>\n\n <select v-model=\"r$.login.type.$value\">\n <option disabled value=\"\">Account type</option>\n <option value=\"EMAIL\">Email</option>\n <option value=\"GITHUB\">Github</option>\n </select>\n\n <div v-if=\"narrowVariant(r$.login, 'type', 'EMAIL')\">\n <!-- `email` is now a known field in this block -->\n <input v-model=\"r$.login.email.$value\" placeholder='Email'/>\n <Errors :errors=\"r$.login.email.$errors\"/>\n </div>\n \n <div v-else-if=\"narrowVariant(r$.login, 'type', 'GITHUB')\">\n <!-- `username` is now a known field in this block -->\n <input v-model=\"r$.login.username.$value\" placeholder='Username'/>\n <Errors :errors=\"r$.login.username.$errors\"/>\n </div>\n\n</template>\n\n```\n\n## `variantToRef`\n\nA use case is also to have a narrowed **Ref** ready to be used and isn't tied to a block scope. Like in the root of a script setup component where you're sure only one variant is possible.\n\nHaving a `variantToRef` helper prevents you from creating custom `computed` methods, which would make you lose the `v-model` compatibilities of the `.$value`.\n\nThe **ref** will be reactive and already typed as the variant you defined, while still needing to be checked for nullish.\n\n:::code-group\n```vue twoslash [Github.vue]\n<template>\n <div v-if=\"githubVariant$\">\n <input v-model=\"githubVariant$.username.$value\" placeholder='Username'/>\n <Errors :errors=\"githubVariant$.username.$errors\"/>\n </div>\n</template>\n\n```\n\n```ts twoslash [form.store.ts]\nimport {ref} from 'vue';\nimport { defineStore, skipHydrate} from 'pinia';\nimport { useRegle, createVariant} from '@regle/core';\nimport { literal, required, email } from '@regle/rules';\n\nexport const useFormStore = defineStore('form', () => {\n \n const state = ref<FormState>({});\n\n const {r$} = useRegle(state, () => {\n \n const variant = createVariant(state, 'type', [\n {type: { literal: literal('EMAIL')}, email: { required, email }},\n {type: { literal: literal('GITHUB')}, username: { required }},\n {type: { required}},\n ]);\n\n return {\n firstName: {required},\n ...variant.value,\n };\n })\n\n return {\n r$: skipHydrate(r$),\n }\n})\n```\n\n:::\n\n### `unsafeAssertion` option\n\nWhen using `variantToRef` in a component it happens that the assertion is done by the parent component, which means you know the variant assertion will always be valid in the entire component.\n\nFor this case you can pass an option to assert that the variant is always defined.\n\n```ts\nimport { variantToRef } from '@regle/core';\n\nconst variant$ = variantToRef(r$, 'type', 'EMAIL', { unsafeAssertion: true });\n\n```"
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
"id": "cheat-sheet",
|
|
@@ -89,7 +89,7 @@ const rawData = {
|
|
|
89
89
|
"title": "Server errors",
|
|
90
90
|
"category": "common-usage",
|
|
91
91
|
"path": "common-usage/external-errors.md",
|
|
92
|
-
"content": "# External errors\n\nRegle handles only client side errors. But some validation may need to be submitted to a server and returned to the client.\n\nTo handle this, you can use the `externalErrors` modifier.\n\nIt matches the structure of your form, but you can also use dot path to define the errors.\n\n## Basic usage\n\n```ts\nimport { type RegleExternalErrorTree, useRegle } from '@regle/core'\n\nconst form = reactive({\n email: '',\n name: {\n pseudo: '',\n },\n})\n\nconst externalErrors = ref<RegleExternalErrorTree<typeof form>>({});\n\nconst { r$ } = useRegle(\n form,\n {\n email: { required },\n name: { pseudo: { required } },\n },\n {\n externalErrors,\n }\n);\n\nasync function submit() {\n const {valid} = await r$.$validate();\n\n if (valid) {\n r$.$setExternalErrors({\n email: [\"Email already exists\"],\n name: {\n pseudo: [\"Pseudo already exists\"]\n },\n })\n }\n}\n```\n\nResult:\n\n:::warning\n\nIf you're working with collections and server-only validations, you'll have to at least specify an empty `$each` object in the client rules to tell Regle that the array is to be treated as a collection\n\n```ts\nconst { r$ } = useRegle({collection: []}, {\n collection: {\n $each: {}\n },\n}, { externalErrors })\n\n```\n\n:::\n\n## Dot path errors\n\n`externalErrors` can also be used to handle dot path errors. \n\nIt can be handy for some backend frameworks that return errors with dot path.\n\n```ts\nimport { useRegle } from '@regle/core';\n\nconst form = reactive({\n email: '',\n name: {\n pseudo: '',\n },\n collection: [{name: ''}]\n})\n\nconst externalErrors = ref<Record<string, string[]>>({});\n\nconst { r$ } = useRegle(form, {}, { externalErrors })\n\nasync function submit() {\n const {valid} = await r$.$validate();\n\n if (valid) {\n r$.$setExternalErrors({\n email: [\"Email already exists\"],\n \"name.pseudo\": [\"Pseudo already exists\"],\n \"collection.0.name\": [\"Name already exists\"]\n })\n }\n}\n``` \n\n## Without the `externalErrors` option\n\n`r$.$setExternalErrors` also works when you don't provide the `externalErrors` option.\nRegle stores those errors internally.\n\n```ts\nconst form = reactive({\n email: '',\n name: {\n pseudo: '',\n },\n})\n\nconst { r$ } = useRegle(form, {\n email: { required },\n name: { pseudo: { required } },\n})\n\nasync function submit() {\n const { valid } = await r$.$validate();\n\n if (!valid) return;\n\n r$.$setExternalErrors({\n email: ['Email already exists'],\n 'name.pseudo': ['Pseudo already exists'],\n });\n}\n```\n\n## Clearing errors\n\nBy default, when you set the external errors, Regle will keep them until the form is validated or modified again.\n\nThis
|
|
92
|
+
"content": "# External errors\n\nRegle handles only client side errors. But some validation may need to be submitted to a server and returned to the client.\n\nTo handle this, you can use the `externalErrors` modifier.\n\nIt matches the structure of your form, but you can also use dot path to define the errors.\n\n## Basic usage\n\n```ts\nimport { type RegleExternalErrorTree, useRegle } from '@regle/core'\n\nconst form = reactive({\n email: '',\n name: {\n pseudo: '',\n },\n})\n\nconst externalErrors = ref<RegleExternalErrorTree<typeof form>>({});\n\nconst { r$ } = useRegle(\n form,\n {\n email: { required },\n name: { pseudo: { required } },\n },\n {\n externalErrors,\n }\n);\n\nasync function submit() {\n const {valid} = await r$.$validate();\n\n if (valid) {\n r$.$setExternalErrors({\n email: [\"Email already exists\"],\n name: {\n pseudo: [\"Pseudo already exists\"]\n },\n })\n }\n}\n```\n\nResult:\n\n:::warning\n\nIf you're working with collections and server-only validations, you'll have to at least specify an empty `$each` object in the client rules to tell Regle that the array is to be treated as a collection\n\n```ts\nconst { r$ } = useRegle({collection: []}, {\n collection: {\n $each: {}\n },\n}, { externalErrors })\n\n```\n\n:::\n\n## Dot path errors\n\n`externalErrors` can also be used to handle dot path errors. \n\nIt can be handy for some backend frameworks that return errors with dot path.\n\n```ts\nimport { useRegle } from '@regle/core';\n\nconst form = reactive({\n email: '',\n name: {\n pseudo: '',\n },\n collection: [{name: ''}]\n})\n\nconst externalErrors = ref<Record<string, string[]>>({});\n\nconst { r$ } = useRegle(form, {}, { externalErrors })\n\nasync function submit() {\n const {valid} = await r$.$validate();\n\n if (valid) {\n r$.$setExternalErrors({\n email: [\"Email already exists\"],\n \"name.pseudo\": [\"Pseudo already exists\"],\n \"collection.0.name\": [\"Name already exists\"]\n })\n }\n}\n``` \n\n## Without the `externalErrors` option\n\n`r$.$setExternalErrors` also works when you don't provide the `externalErrors` option.\nRegle stores those errors internally.\n\n```ts\nconst form = reactive({\n email: '',\n name: {\n pseudo: '',\n },\n})\n\nconst { r$ } = useRegle(form, {\n email: { required },\n name: { pseudo: { required } },\n})\n\nasync function submit() {\n const { valid } = await r$.$validate();\n\n if (!valid) return;\n\n r$.$setExternalErrors({\n email: ['Email already exists'],\n 'name.pseudo': ['Pseudo already exists'],\n });\n}\n```\n\n## Clearing errors\n\nBy default, when you set the external errors, Regle will keep them until the form is validated or modified again.\n\nThis behavior can be modified with these options:\n\n### `clearExternalErrors`\n\n```ts\nr$.$reset({ clearExternalErrors: false });\n```\n\n### `clearExternalErrorsOnValidate`\n\n```ts\nimport { useRegle } from '@regle/core';\n\nconst { r$ } = useRegle(form, {}, { \n externalErrors, \n clearExternalErrorsOnValidate: true \n})\n```\n\n### `clearExternalErrorsOnChange`\n\n```ts\nimport { useRegle } from '@regle/core';\n\nconst { r$ } = useRegle(form, {}, { \n externalErrors, \n clearExternalErrorsOnChange: false \n})\n```\n\n### `$clearExternalErrors()`\n\nYou can also clear the errors manually by calling the `$clearExternalErrors` method.\n\n```ts\nr$.$clearExternalErrors();\n```"
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
95
|
"id": "common-usage-reset-form",
|
|
@@ -131,14 +131,14 @@ const rawData = {
|
|
|
131
131
|
"title": "Modifiers",
|
|
132
132
|
"category": "core-concepts",
|
|
133
133
|
"path": "core-concepts/modifiers.md",
|
|
134
|
-
"content": "# Modifiers\n\nModifiers allow you to control the behavior and settings of validation rules in your application. They can be applied globally to all fields or customized per field.\n\n## Deep modifiers\n\nDeep modifiers are specified as the third argument of the `useRegle` composable. They apply recursively to all fields within your state.\n\n```ts\nconst { r$ } = useRegle({}, {}, {\n /* modifiers */\n})\n```\n\n### `autoDirty`\n\n__Type__: `boolean`\n\n__Default__: `true`\n\nAutomatically set the dirty set without the need of `$value` or `$touch`.\n\n### `immediateDirty`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\nSet the dirty state to true when the form is initialized.\n\n### `disabled`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\nTemporarily pauses Regle reactivity and validation computation.\n\nWhen `disabled` is `true`, state changes still happen, but validation status does not update until you enable it again.\n\n```ts\nimport { ref } from 'vue';\nimport { useRegle } from '@regle/core';\nimport { required } from '@regle/rules';\n\nconst disabled = ref(false);\n\nconst { r$ } = useRegle(\n { name: '' },\n { name: { required } },\n { disabled }\n);\n\ndisabled.value = true;\nr$.$value.name = 'John'; // value updates, validation is paused\n\ndisabled.value = false; // validation reactivity resumes\n```\n\n### `silent`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\nRegle Automatically tracks changes in the state for all nested rules. If set to `true`, you must manually call `$touch` or `$validate` to display errors.\n\n### `lazy`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\nUsage:\n\nWhen set to false, tells the rules to be called on init, otherwise they are lazy and only called when the field is dirty.\n\n### `externalErrors`\n\n__Type__: `RegleExternalErrorTree<State>` \n\nPass an object, matching your error state, that holds external validation errors. These can be from a backend validations or something else.\n\nCheck the [External errors](/common-usage/external-errors) section for more details.\n\n### `rewardEarly`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\n__Side effect__: disable `$autoDirty` when `true`.\n\nEnables the `reward-early-punish-late` mode of Regle. This mode will not set fields as invalid once they are valid, unless manually triggered by `$validate` method.\n\nThis
|
|
134
|
+
"content": "# Modifiers\n\nModifiers allow you to control the behavior and settings of validation rules in your application. They can be applied globally to all fields or customized per field.\n\n## Deep modifiers\n\nDeep modifiers are specified as the third argument of the `useRegle` composable. They apply recursively to all fields within your state.\n\n```ts\nconst { r$ } = useRegle({}, {}, {\n /* modifiers */\n})\n```\n\n### `autoDirty`\n\n__Type__: `boolean`\n\n__Default__: `true`\n\nAutomatically set the dirty set without the need of `$value` or `$touch`.\n\n### `immediateDirty`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\nSet the dirty state to true when the form is initialized.\n\n### `disabled`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\nTemporarily pauses Regle reactivity and validation computation.\n\nWhen `disabled` is `true`, state changes still happen, but validation status does not update until you enable it again.\n\n```ts\nimport { ref } from 'vue';\nimport { useRegle } from '@regle/core';\nimport { required } from '@regle/rules';\n\nconst disabled = ref(false);\n\nconst { r$ } = useRegle(\n { name: '' },\n { name: { required } },\n { disabled }\n);\n\ndisabled.value = true;\nr$.$value.name = 'John'; // value updates, validation is paused\n\ndisabled.value = false; // validation reactivity resumes\n```\n\n### `silent`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\nRegle Automatically tracks changes in the state for all nested rules. If set to `true`, you must manually call `$touch` or `$validate` to display errors.\n\n### `lazy`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\nUsage:\n\nWhen set to false, tells the rules to be called on init, otherwise they are lazy and only called when the field is dirty.\n\n### `externalErrors`\n\n__Type__: `RegleExternalErrorTree<State>` \n\nPass an object, matching your error state, that holds external validation errors. These can be from a backend validations or something else.\n\nCheck the [External errors](/common-usage/external-errors) section for more details.\n\n### `rewardEarly`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\n__Side effect__: disable `$autoDirty` when `true`.\n\nEnables the `reward-early-punish-late` mode of Regle. This mode will not set fields as invalid once they are valid, unless manually triggered by `$validate` method.\n\nThis has no effect when `autoDirty` is set to `true` (the default). Set `autoDirty: false` for `rewardEarly` to take effect.\n\n### `clearExternalErrorsOnChange`\n\n__Type__: `boolean`\n\n__Default__: `true`\n\nThis mode is similar to `rewardEarly`, but only applies to external errors.\nSetting it to `false` will keep the server errors until `$clearExternalErrors` is called.\n\n### `clearExternalErrorsOnValidate`\n\n__Type__: `boolean`\n\n__Default__: `false`\n\nThis mode is similar to `clearExternalErrorsOnChange`, but for the `$validate` and `$validateSync` methods.\nSetting it to `false` will keep the server errors until `$clearExternalErrors` is called manually, or the `externalErrors` is set again.\n\n### `validationGroups`\n\n__Type__: `(fields) => Record<string, (RegleFieldStatus |RegleCollectionStatus)[]>`\n\nValidation groups let you merge field properties under one, to better handle validation status.\n\nYou will have access to your declared groups in the `r$.$groups` object.\n\n```ts twoslash\n\nimport { ref } from 'vue';\n// ---cut---\nimport { useRegle } from '@regle/core';\nimport { required } from '@regle/rules';\n\nconst { r$ } = useRegle({ email: '', user: { firstName: '' } }, {\n email: { required },\n user: {\n firstName: { required },\n }\n}, {\n validationGroups: (fields) => ({\n group1: [fields.email, fields.user.firstName]\n })\n})\n\nr$.$groups.group1.\n\n```\n<br><br><br><br>\n\n## Per-field modifiers\n\nPer-field modifiers allow to customize more precisely which behavior you want for each field.\n\n```ts twoslash\n\nimport { useRegle } from '@regle/core';\n// ---cut---\nconst { r$ } = useRegle({ name: '' }, {\n name: { $ }\n\n})\n```\n\n<br><br>\n\n`$autoDirty` `$lazy`, `$silent`, `$immediateDirty` and `$rewardEarly` work the same as the deep modifiers.\n\n### `$debounce`\nType: `number` (ms)\n\nThis let you declare the number of milliseconds the rule needs to wait before executing. Useful for async or heavy computations.\n\n:::tip\nAll async rules have a default debounce of `200ms`, you can disable or modify this setting with `$debounce`\n:::\n\n### `$isEdited`\nType: `(currentValue: MaybeInput<TValue>, initialValue: MaybeInput<TValue>, defaultHandlerFn: (currentValue: unknown, initialValue: unknown) => boolean) => boolean`\n\nOverride the default `$edited` property handler. Useful to handle custom comparisons for complex object types.\n\n:::warning\nIt's highly recommended to use this modifier with the [`markStatic`](/advanced-usage/immutable-constructors) helper to handle immutable constructors.\n:::\n\n```ts\nimport { markStatic, useRegle } from '@regle/core';\nimport { Decimal } from 'decimal.js';\nimport { required } from '@regle/rules';\n\nconst { r$ } = useRegle({ decimal: markStatic(new Decimal(1)) }, {\n decimal: {\n required,\n $isEdited(currentValue, initialValue, defaultHandlerFn) {\n if (currentValue != null && initialValue != null) {\n return currentValue.toNearest(0.01).toString() !== initialValue.toNearest(0.01).toString();\n }\n // fallback to the default handler\n return defaultHandlerFn(currentValue, initialValue);\n },\n },\n})\n```\n\n## Array specific modifiers\n\nThis modifiers are only impacting Array collections.\n\n```ts\nconst { r$ } = useRegle({ collection: [] }, {\n collection: { /** Deep modifiers */ }\n})\n```\n\n### `$deepCompare`\nType: `boolean`\n\nDefault: `false`\n\nAllow deep compare of array children to compute the `$edited` property.\n\nIt's disabled by default for performance reasons."
|
|
135
135
|
},
|
|
136
136
|
{
|
|
137
137
|
"id": "core-concepts-rules-built-in-rules",
|
|
138
138
|
"title": "Built-in rules",
|
|
139
139
|
"category": "rules",
|
|
140
140
|
"path": "core-concepts/rules/built-in-rules.md",
|
|
141
|
-
"content": "# Built-in rules\n\nAll built-in rules are available through the `@regle/rules` package.\n\nDon't forget to install it if you haven't:\n\n::: code-group\n\n```sh [pnpm]\npnpm add @regle/rules\n```\n\n```sh [npm]\nnpm install @regle/rules\n```\n\n```sh [yarn]\nyarn add @regle/rules\n```\n\n```sh [bun]\nbun add @regle/rules\n```\n\n:::\n\n:::tip\nEvery built-in rule will check if the value of the field is set before checking if it's valid.\n\nThis allow to have rules even if the field is not required.\n:::\n\n## `alpha`\n\n_**Params**_\n - `allowSymbols?: MaybeRefOrGetter<boolean>`\n\nAllows only alphabetic characters.\n\n```ts\nimport { alpha } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: { \n alpha,\n // or\n alpha: alpha({ allowSymbols: true }),\n },\n})\n```\n\n## `alphaNum`\n\n_**Params**_\n - `allowSymbols?: MaybeRefOrGetter<boolean>`\n\nAllows only alphanumeric characters.\n\n```ts\nimport { useRegle } from '@regle/core';\nimport { alphaNum } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: { \n alphaNum,\n // or\n alphaNum: alphaNum({ allowSymbols: true }),\n },\n});\n```\n\n## `atLeastOne`\n\n_**Params**_\n - `keys?: MaybeRefOrGetter<string[]>` - Optional list of keys to check. If not provided, checks if the object has at least one filled property.\n\n_**Works with**_\n - `Record | object`\n\nChecks if at least one key is filled in the object. Useful for object-level validation with `$self`.\n\n```ts\nimport { atLeastOne } from '@regle/rules';\n\nconst { r$ } = useRegle({ user: { firstName: '', lastName: '' } }, {\n user: {\n $self: {\n // Check if any property is filled\n atLeastOne,\n // or check specific keys\n atLeastOne: atLeastOne(['firstName', 'lastName']),\n },\n },\n})\n```\n\n## `between`\n\n_**Params**_\n - `min: Ref<number> | number | () => number`\n - `max: Ref<number> | number | () => number`\n - `options?: {allowEqual?: boolean}`\n\nChecks if a number is in specified bounds. `min` and `max` are both inclusive.\n\n```ts\nimport { between } from '@regle/rules';\n\nconst maxCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n between: between(1, 6),\n between: between(1, maxCount, {allowEqual: false}),\n between: between(() => maxCount.value, 10)\n },\n})\n```\n\n## `boolean`\n\nRequires a value to be a native boolean type. Mainly used for typing.\n\n```ts\nimport {type InferInput} from '@regle/core';\nimport { boolean } from '@regle/rules';\n\nconst rules = {\n checkbox: { boolean },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `checked`\n\nRequires a boolean value to be `true`. This is useful for checkbox inputs.\n\n### Note\n\nThis rule does not need `required` to be set, it will assert the value is set.\n\n```ts\nimport { checked } from '@regle/rules';\n\nconst { r$ } = useRegle({ confirm: false }, {\n confirm: { checked },\n})\n```\n\n## `contains`\n\n_**Params**_\n- `contain: Ref<string> | string | () => string`\n\nChecks if the string contains the specified substring.\n\n```ts\nimport { contains } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestLib: '' }, {\n bestLib: {\n contains: contains('regle')\n },\n})\n```\n\n## `containsSpecialCharacter`\n\n_**Params**_\n- `minCharactersCount?: Ref<number> | number | () => number`\n\nRequires a string to contain at least a number of special characters.\n\n```ts\nimport { containsSpecialCharacter } from '@regle/rules';\n\nconst { r$ } = useRegle({ password: '' }, {\n password: {\n containsSpecialCharacter,\n // or with a custom minimum\n containsSpecialCharacter: containsSpecialCharacter(2),\n },\n})\n```\n\n## `containsUppercase`\n\n_**Params**_\n- `minUppercaseCount?: Ref<number> | number | () => number`\n\nRequires a string to contain at least a number of uppercase letters.\n\n```ts\nimport { containsUppercase } from '@regle/rules';\n\nconst { r$ } = useRegle({ password: '' }, {\n password: {\n containsUppercase,\n // or with a custom minimum\n containsUppercase: containsUppercase(2),\n },\n})\n```\n\n## `date`\n\nRequires a value to be a native Date constructor. Mainly used for typing.\n\n```ts\nimport {type InferInput} from '@regle/core';\nimport { date } from '@regle/rules';\n\nconst rules = {\n birthday: { date },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `dateAfter`\n_**Params**_\n - `after: Ref<string | Date> | string | Date | () => string | Date`\n - `options?: {allowEqual?: boolean}`\n\nChecks if the date is after the given parameter.\n\n```ts\nimport { dateAfter } from '@regle/rules';\n\nconst today = ref(new Date());\n\nconst { r$ } = useRegle({ birthday: null as Date | null }, {\n birthday: {\n dateAfter: dateAfter(today),\n // or\n dateAfter: dateAfter(today, { allowEqual: false }),\n },\n})\n```\n\n## `dateBefore`\n_**Params**_\n - `before: Ref<string | Date> | string | Date | () => string | Date`\n - `options?: {allowEqual?: boolean}`\n\nChecks if the date is before the given parameter.\n\n```ts\nimport { dateBefore } from '@regle/rules';\n\nconst today = ref(new Date());\n\nconst { r$ } = useRegle({ birthday: null as Date | null }, {\n birthday: {\n dateBefore: dateBefore(today),\n // or\n dateBefore: dateBefore(today, { allowEqual: false }),\n },\n})\n```\n\n## `dateBetween`\n\n_**Params**_\n - `before: Ref<string | Date> | string | Date | () => string | Date`\n - `after: Ref<string | Date> | string | Date | () => string | Date`\n - `options?: {allowEqual?: boolean}`\n\nChecks if the date falls between the specified bounds.\n\n```ts\nimport { dateBetween } from '@regle/rules';\n\nconst before = ref(new Date());\nconst after = ref(new Date(2030, 3, 1));\n\nconst { r$ } = useRegle({ birthday: null as Date | null }, {\n birthday: {\n dateBetween: dateBetween(before, after),\n // or\n dateBetween: dateBetween(before, after, { allowEqual: false }),\n },\n})\n```\n\n## `decimal`\n\nAllows positive and negative decimal numbers.\n\n```ts\nimport { decimal } from '@regle/rules';\n\nconst { r$ } = useRegle({ price: 0 }, {\n price: { decimal },\n})\n```\n\n## `domain`\n\nValidates domain names only (for example `example.com` or `sub.example.com`).\n\n```ts\nimport { domain } from '@regle/rules';\n\nconst { r$ } = useRegle({ siteDomain: '' }, {\n siteDomain: { domain },\n})\n```\n\n## `email`\n\nValidates email addresses. Always verify on the server to ensure the address is real and not already in use.\n\n```ts\nimport { email } from '@regle/rules';\n\nconst { r$ } = useRegle({ email: '' }, {\n email: { email },\n})\n```\n\n## `emoji`\n\nValidates emojis.\n\n```ts\nimport { emoji } from '@regle/rules';\n\nconst { r$ } = useRegle({ emoji: '' }, {\n emoji: { emoji },\n})\n```\n\n## `endsWith`\n\n_**Params**_\n- `end: Ref<string> | string | () => string`\n\nChecks if the string ends with the specified substring.\n\n```ts\nimport { endsWith } from '@regle/rules';\n\nconst { r$ } = useRegle({ firstName: '' }, {\n firstName: { endsWith: endsWith('foo') },\n})\n```\n\n## `exactDigits`\n_**Params**_\n - `count: Ref<number> | number | () => number`\n\nRequires the input value to have a strict specified number of digits.\n\n```ts\nimport { exactDigits } from '@regle/rules';\n\nconst exactValue = ref(6);\n\nconst { r$ } = useRegle({ digits: '' }, {\n digits: {\n exactDigits: exactDigits(6),\n // or with ref\n exactDigits: exactDigits(exactValue),\n // or with getter\n exactDigits: exactDigits(() => exactValue.value)\n },\n})\n```\n\n## `exactLength`\n\n_**Params**_\n - `count: Ref<number> | number | () => number`\n\nRequires the input value to have a strict specified length, inclusive. Works with arrays, objects and strings.\n\n```ts\nimport { exactLength } from '@regle/rules';\n\nconst exactValue = ref(6);\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n exactLength: exactLength(6),\n exactLength: exactLength(exactValue),\n exactLength: exactLength(() => exactValue.value)\n },\n})\n```\n\n## `exactValue`\n\n_**Params**_\n - `count: Ref<number> | number | () => number`\n\nRequires a field to have a strict numeric value.\n\n```ts\nimport { exactValue } from '@regle/rules';\n\nconst exactCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n exactValue: exactValue(6),\n exactValue: exactValue(exactCount),\n exactValue: exactValue(() => exactCount.value)\n },\n})\n```\n\n## `file`\n\nRequires a value to be a native File constructor. Mainly used for typing.\n\n```ts\nimport { file } from '@regle/rules';\n\nconst rules = {\n file: { file },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `fileType`\n\nRequires a value to be a file with a specific type.\n\n```ts\nimport { fileType } from '@regle/rules';\n\nconst { r$ } = useRegle({ file: null as File | null }, {\n file: { fileType: fileType(['image/png', 'image/jpeg']) },\n})\n```\n\n## `hexadecimal`\n\nValidates hexadecimal values.\n\n```ts\nimport { hexadecimal } from '@regle/rules';\n\nconst { r$ } = useRegle({ hexadecimal: '' }, {\n hexadecimal: { hexadecimal },\n})\n```\n\n## `hostname`\n\nValidates hostnames.\n\n```ts\nimport { hostname } from '@regle/rules';\n\nconst { r$ } = useRegle({ siteHost: '' }, {\n siteHost: { hostname },\n})\n```\n\n## `httpUrl`\n\n_**Params**_\n- `options?: {protocol?: RegExp}`\n\nValidates HTTP URLs.\n\n```ts\nimport { httpUrl } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestUrl: '' }, {\n bestUrl: { httpUrl },\n // or with custom protocol validation\n bestUrl: { httpUrl: httpUrl({ protocol: /^https$/ }) },\n})\n```\n\n## `integer`\n\nAllows only integers (positive and negative).\n\n```ts\nimport { integer } from '@regle/rules';\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: { integer },\n})\n```\n\n## `ipv4Address`\n\nValidates IPv4 addresses in dotted decimal notation *127.0.0.1*.\n\n```ts\nimport { ipv4Address } from '@regle/rules';\n\nconst { r$ } = useRegle({ address: '' }, {\n address: { ipv4Address },\n})\n```\n\n## `literal`\n\nValidates literal values.\n\n### Note\n\nThis rule does not need `required` to be set, it will assert the value is set.\n\n```ts\nimport { literal } from '@regle/rules';\n\nconst { r$ } = useRegle({ value: '' }, {\n value: { literal: literal('foo') },\n})\n```\n\n## `lowercase`\n\nValidates lowercase strings.\n\n```ts\nimport { lowercase } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: { lowercase },\n})\n```\n\n## `macAddress`\n\n_**Params**_\n - `separator?: string | Ref<string> | () => string`\n\nValidates MAC addresses. Call as a function to specify a custom separator (e.g., ':' or an empty string for 00ff1122334455).\n\n```ts\nimport { useRegle } from '@regle/core';\nimport { macAddress } from '@regle/rules';\n\nconst { r$ } = useRegle({ address: '' }, {\n address: {\n macAddress,\n // or\n macAddress: macAddress('-')\n },\n});\n```\n\n## `maxFileSize`\n\nRequires a value to be a file with a maximum size.\n\n```ts\nimport { maxFileSize } from '@regle/rules';\n\nconst { r$ } = useRegle({ file: null as File | null }, {\n file: { maxFileSize: maxFileSize(10_000_000) }, // 10 MB\n})\n```\n\n## `maxLength`\n\n_**Params**_\n - `max: Ref<number> | number | () => number`\n - `options?: {allowEqual?: boolean}`\n\n_**Works with**_\n - `Array | Record | string | number`\n\nRequires the input value to have a maximum specified length, inclusive. Works with arrays, objects and strings.\n\n```ts\nimport { maxLength } from '@regle/rules';\n\nconst maxValue = ref(6);\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n maxLength: maxLength(6),\n maxLength: maxLength(maxValue),\n maxLength: maxLength(() => maxValue.value)\n },\n})\n```\n\n## `maxValue`\n\n_**Params**_\n - `min: Ref<number> | number | () => number`\n - `options?: {allowEqual?: boolean}`\n\n Requires a field to have a specified maximum numeric value.\n\n```ts\nimport { maxValue } from '@regle/rules';\n\nconst maxCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n maxValue: maxValue(6),\n maxValue: maxValue(maxCount, {allowEqual: false}),\n maxValue: maxValue(() => maxCount.value)\n },\n})\n```\n\n## `minFileSize`\n\nRequires a value to be a file with a minimum size.\n\n```ts\nimport { minFileSize } from '@regle/rules';\n\nconst { r$ } = useRegle({ file: null as File | null }, {\n file: { minFileSize: minFileSize(1_000_000) }, // 1 MB\n})\n```\n\n## `minLength`\n\n_**Params**_\n - `min: Ref<number> | number | () => number`\n - `options?: {allowEqual?: boolean}`\n\n_**Works with**_\n - `Array | Record | string | number`\n\nRequires the input value to have a minimum specified length, inclusive. Works with arrays, objects and strings.\n\n```ts\nimport { minLength } from '@regle/rules';\n\nconst minValue = ref(6);\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n minLength: minLength(6),\n minLength: minLength(minValue),\n minLength: minLength(() => minValue.value)\n },\n})\n```\n\n## `minValue`\n\n_**Params**_\n - `min: Ref<number> | number | () => number`\n - `options?: {allowEqual?: boolean}`\n\n_**Works with**_\n - `number`\n\nRequires a field to have a specified minimum numeric value.\n\n```ts\nimport { minValue } from '@regle/rules';\n\nconst minCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n minValue: minValue(6),\n minValue: minValue(minCount, {allowEqual: false}),\n minValue: minValue(() => minCount.value)\n },\n})\n```\n\n## `nativeEnum`\n\nValidate against a native Typescript enum value. Similar to Zod's `nativeEnum`\n\n```ts\nimport { nativeEnum } from '@regle/rules';\n\nenum Foo {\n Bar, Baz\n}\n\nconst { r$ } = useRegle({ type: '' }, {\n type: { nativeEnum: nativeEnum(Foo) },\n})\n```\n\n## `number`\n\nRequires a value to be a native number type. Mainly used for typing.\n\n```ts\nimport { number } from '@regle/rules';\n\nconst rules = {\n count: { number },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `numeric`\n\nAllows only numeric values (including numeric strings).\n\n```ts\nimport { numeric } from '@regle/rules';\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: { numeric },\n})\n```\n\n## `oneOf`\n\nAllow only one of the values from a fixed Array of possible entries.\n\n_**Params**_\n - `options: MaybeRefOrGetter<Array<string | number>>`\n\n```ts\nimport { oneOf } from '@regle/rules';\n\nconst foodEnum = {\n Fish: 'Fish',\n Meat: 'Meat',\n Bone: 'Bone',\n} as const;\n\nconst { r$ } = useRegle({ aliment: 'Fish' }, {\n aliment: {\n oneOf: oneOf(['Fish', 'Meat', 'Bone']),\n // or\n oneOf: oneOf(foodEnum),\n },\n})\n```\n\n## `regex`\n\n_**Params**_\n- `regexps: MaybeRefOrGetter<RegExp | RegExp[]>`\n\nChecks if the value matches one or more regular expressions.\n\n```ts\nimport { regex } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n regex: regex(/^foo/),\n regex: regex([/^bar/, /baz$/]),\n },\n})\n```\n\n## `required`\n\nRequires non-empty data. Checks for empty arrays and strings containing only whitespaces.\n\n```ts\nimport {required} from '@regle/rules';\n\nconst {r$} = useRegle({name: ''}, {\n name: {required},\n})\n```\n\n## `requiredIf`\n\n_**Params**_\n - `condition: Ref<unknown> | unknown | () => unknown` - the property to base the `required` validator on.\n\nRequires non-empty data, only if provided data property, ref, or a function resolves to `true`.\n\n```ts\nimport { requiredIf } from '@regle/rules';\n\nconst form = ref({ name: '', condition: false });\n\nconst conditionRef = ref(false);\n\nconst { r$ } = useRegle(form, {\n name: {\n required: requiredIf(() => form.value.condition),\n required: requiredIf(conditionRef),\n },\n})\n```\n\n## `requiredUnless`\n\n_**Params**_\n - `condition: Ref<unknown> | unknown | () => unknown` - the property to base the `required` validator on.\n\nRequires non-empty data, only if provided data property, ref, or a function resolves to `false`.\n\n```ts\nimport { requiredUnless } from '@regle/rules';\n\nconst form = ref({ name: '', condition: false });\n\nconst conditionRef = ref(false);\n\nconst { r$ } = useRegle(form, {\n name: {\n required: requiredUnless(() => form.value.condition),\n required: requiredUnless(conditionRef)\n },\n})\n```\n\n## `sameAs`\n\n_**Params**_\n * `target: unknown`\n\nChecks if the value matches the specified property or ref.\n\n```ts\nimport { sameAs } from '@regle/rules';\n\nconst form = ref({\n password: '',\n confirmPassword: '',\n});\n\nconst { r$ } = useRegle(form, {\n confirmPassword: {\n sameAs: sameAs(() => form.value.password),\n }\n})\n```\n\n## `startsWith`\n\n_**Params**_\n- `start: Ref<string> | string | () => string`\n\nChecks if the string starts with the specified substring.\n\n```ts\nimport { startsWith } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestLib: '' }, {\n bestLib: {\n startsWith: startsWith('regle')\n },\n})\n```\n\n## `string`\n\nRequires a value to be a native string type. Mainly used for typing\n\n```ts\nimport {type InferInput} from '@regle/core';\nimport { string } from '@regle/rules';\n\nconst rules = {\n firstName: { string },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `type`\n\nDefine the input type of a rule. No runtime validation. \nOverride any input type set by other rules.\n\n```ts\nimport {type InferInput} from '@regle/core';\nimport { type } from '@regle/rules';\n\nconst rules = {\n firstName: { type: type<string>() },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `uppercase`\n\nValidates uppercase strings.\n\n```ts\nimport { uppercase } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: { uppercase },\n})\n```\n\n## `url`\n\n_**Params**_\n- `options?: {protocol?: RegExp}`\n\nValidates URLs.\n\n```ts\nimport { url } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestUrl: '' }, {\n bestUrl: { url },\n // or with custom protocol validation\n bestUrl: { url: url({ protocol: /^https?$/ }) },\n})\n```"
|
|
141
|
+
"content": "# Built-in rules\n\nAll built-in rules are available through the `@regle/rules` package.\n\nDon't forget to install it if you haven't:\n\n::: code-group\n\n```sh [pnpm]\npnpm add @regle/rules\n```\n\n```sh [npm]\nnpm install @regle/rules\n```\n\n```sh [yarn]\nyarn add @regle/rules\n```\n\n```sh [bun]\nbun add @regle/rules\n```\n\n:::\n\n:::tip\nEvery built-in rule will check if the value of the field is set before checking if it's valid.\n\nThis allow to have rules even if the field is not required.\n:::\n\n## `alpha`\n\n_**Params**_\n - `allowSymbols?: MaybeRefOrGetter<boolean>`\n\nAllows only alphabetic characters.\n\n```ts\nimport { alpha } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: { \n alpha,\n // or\n alpha: alpha({ allowSymbols: true }),\n },\n})\n```\n\n## `alphaNum`\n\n_**Params**_\n - `allowSymbols?: MaybeRefOrGetter<boolean>`\n\nAllows only alphanumeric characters.\n\n```ts\nimport { useRegle } from '@regle/core';\nimport { alphaNum } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: { \n alphaNum,\n // or\n alphaNum: alphaNum({ allowSymbols: true }),\n },\n});\n```\n\n## `atLeastOne`\n\n_**Params**_\n - `keys?: MaybeRefOrGetter<string[]>` - Optional list of keys to check. If not provided, checks if the object has at least one filled property.\n\n_**Works with**_\n - `Record | object`\n\nChecks if at least one key is filled in the object. Useful for object-level validation with `$self`.\n\n```ts\nimport { atLeastOne } from '@regle/rules';\n\nconst { r$ } = useRegle({ user: { firstName: '', lastName: '' } }, {\n user: {\n $self: {\n // Check if any property is filled\n atLeastOne,\n // or check specific keys\n atLeastOne: atLeastOne(['firstName', 'lastName']),\n },\n },\n})\n```\n\n## `between`\n\n_**Params**_\n - `min: Ref<number> | number | () => number`\n - `max: Ref<number> | number | () => number`\n - `options?: {allowEqual?: boolean}`\n\nChecks if a number is in specified bounds. `min` and `max` are both inclusive.\n\n```ts\nimport { between } from '@regle/rules';\n\nconst maxCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n between: between(1, 6),\n between: between(1, maxCount, {allowEqual: false}),\n between: between(() => maxCount.value, 10)\n },\n})\n```\n\n## `boolean`\n\nRequires a value to be a native boolean type. Mainly used for typing.\n\n```ts\nimport {type InferInput} from '@regle/core';\nimport { boolean } from '@regle/rules';\n\nconst rules = {\n checkbox: { boolean },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `checked`\n\nRequires a boolean value to be `true`. This is useful for checkbox inputs.\n\n### Note\n\nThis rule does not need `required` to be set, it will assert the value is set.\n\n```ts\nimport { checked } from '@regle/rules';\n\nconst { r$ } = useRegle({ confirm: false }, {\n confirm: { checked },\n})\n```\n\n## `contains`\n\n_**Params**_\n- `contain: Ref<string> | string | () => string`\n\nChecks if the string contains the specified substring.\n\n```ts\nimport { contains } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestLib: '' }, {\n bestLib: {\n contains: contains('regle')\n },\n})\n```\n\n## `containsSpecialCharacter`\n\n_**Params**_\n- `minCharactersCount?: Ref<number> | number | () => number`\n\nRequires a string to contain at least a number of special characters.\n\n```ts\nimport { containsSpecialCharacter } from '@regle/rules';\n\nconst { r$ } = useRegle({ password: '' }, {\n password: {\n containsSpecialCharacter,\n // or with a custom minimum\n containsSpecialCharacter: containsSpecialCharacter(2),\n },\n})\n```\n\n## `containsUppercase`\n\n_**Params**_\n- `minUppercaseCount?: Ref<number> | number | () => number`\n\nRequires a string to contain at least a number of uppercase letters.\n\n```ts\nimport { containsUppercase } from '@regle/rules';\n\nconst { r$ } = useRegle({ password: '' }, {\n password: {\n containsUppercase,\n // or with a custom minimum\n containsUppercase: containsUppercase(2),\n },\n})\n```\n\n## `date`\n\nRequires a value to be a native Date constructor. Mainly used for typing.\n\n```ts\nimport {type InferInput} from '@regle/core';\nimport { date } from '@regle/rules';\n\nconst rules = {\n birthday: { date },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `dateAfter`\n_**Params**_\n - `after: Ref<string | Date> | string | Date | () => string | Date`\n - `options?: {allowEqual?: boolean}`\n\nChecks if the date is after the given parameter.\n\n```ts\nimport { dateAfter } from '@regle/rules';\n\nconst today = ref(new Date());\n\nconst { r$ } = useRegle({ birthday: null as Date | null }, {\n birthday: {\n dateAfter: dateAfter(today),\n // or\n dateAfter: dateAfter(today, { allowEqual: false }),\n },\n})\n```\n\n## `dateBefore`\n_**Params**_\n - `before: Ref<string | Date> | string | Date | () => string | Date`\n - `options?: {allowEqual?: boolean}`\n\nChecks if the date is before the given parameter.\n\n```ts\nimport { dateBefore } from '@regle/rules';\n\nconst today = ref(new Date());\n\nconst { r$ } = useRegle({ birthday: null as Date | null }, {\n birthday: {\n dateBefore: dateBefore(today),\n // or\n dateBefore: dateBefore(today, { allowEqual: false }),\n },\n})\n```\n\n## `dateBetween`\n\n_**Params**_\n - `before: Ref<string | Date> | string | Date | () => string | Date`\n - `after: Ref<string | Date> | string | Date | () => string | Date`\n - `options?: {allowEqual?: boolean}`\n\nChecks if the date falls between the specified bounds.\n\n```ts\nimport { dateBetween } from '@regle/rules';\n\nconst before = ref(new Date());\nconst after = ref(new Date(2030, 3, 1));\n\nconst { r$ } = useRegle({ birthday: null as Date | null }, {\n birthday: {\n dateBetween: dateBetween(before, after),\n // or\n dateBetween: dateBetween(before, after, { allowEqual: false }),\n },\n})\n```\n\n## `decimal`\n\nAllows positive and negative decimal numbers.\n\n```ts\nimport { decimal } from '@regle/rules';\n\nconst { r$ } = useRegle({ price: 0 }, {\n price: { decimal },\n})\n```\n\n## `domain`\n\nValidates domain names only (for example `example.com` or `sub.example.com`).\n\n```ts\nimport { domain } from '@regle/rules';\n\nconst { r$ } = useRegle({ siteDomain: '' }, {\n siteDomain: { domain },\n})\n```\n\n## `email`\n\nValidates email addresses. Always verify on the server to ensure the address is real and not already in use.\n\n```ts\nimport { email } from '@regle/rules';\n\nconst { r$ } = useRegle({ email: '' }, {\n email: { email },\n})\n```\n\n## `emoji`\n\nValidates emojis.\n\n```ts\nimport { emoji } from '@regle/rules';\n\nconst { r$ } = useRegle({ emoji: '' }, {\n emoji: { emoji },\n})\n```\n\n## `endsWith`\n\n_**Params**_\n- `end: Ref<string> | string | () => string`\n\nChecks if the string ends with the specified substring.\n\n```ts\nimport { endsWith } from '@regle/rules';\n\nconst { r$ } = useRegle({ firstName: '' }, {\n firstName: { endsWith: endsWith('foo') },\n})\n```\n\n## `exactDigits`\n_**Params**_\n - `count: Ref<number> | number | () => number`\n\nRequires the input value to have a strict specified number of digits.\n\n```ts\nimport { exactDigits } from '@regle/rules';\n\nconst exactValue = ref(6);\n\nconst { r$ } = useRegle({ digits: '' }, {\n digits: {\n exactDigits: exactDigits(6),\n // or with ref\n exactDigits: exactDigits(exactValue),\n // or with getter\n exactDigits: exactDigits(() => exactValue.value)\n },\n})\n```\n\n## `exactLength`\n\n_**Params**_\n - `count: Ref<number> | number | () => number`\n\nRequires the input value to have a strict specified length, inclusive. Works with arrays, objects and strings.\n\n```ts\nimport { exactLength } from '@regle/rules';\n\nconst exactValue = ref(6);\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n exactLength: exactLength(6),\n exactLength: exactLength(exactValue),\n exactLength: exactLength(() => exactValue.value)\n },\n})\n```\n\n## `exactValue`\n\n_**Params**_\n - `count: Ref<number> | number | () => number`\n\nRequires a field to have a strict numeric value.\n\n```ts\nimport { exactValue } from '@regle/rules';\n\nconst exactCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n exactValue: exactValue(6),\n exactValue: exactValue(exactCount),\n exactValue: exactValue(() => exactCount.value)\n },\n})\n```\n\n## `file`\n\nRequires a value to be a native File constructor. Mainly used for typing.\n\n```ts\nimport { file } from '@regle/rules';\n\nconst rules = {\n file: { file },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `fileType`\n\nRequires a value to be a file with a specific type.\n\n```ts\nimport { fileType } from '@regle/rules';\n\nconst { r$ } = useRegle({ file: null as File | null }, {\n file: { fileType: fileType(['image/png', 'image/jpeg']) },\n})\n```\n\n## `hexadecimal`\n\nValidates hexadecimal values.\n\n```ts\nimport { hexadecimal } from '@regle/rules';\n\nconst { r$ } = useRegle({ hexadecimal: '' }, {\n hexadecimal: { hexadecimal },\n})\n```\n\n## `hostname`\n\nValidates hostnames.\n\n```ts\nimport { hostname } from '@regle/rules';\n\nconst { r$ } = useRegle({ siteHost: '' }, {\n siteHost: { hostname },\n})\n```\n\n## `httpUrl`\n\n_**Params**_\n- `options?: {protocol?: RegExp}`\n\nValidates HTTP URLs.\n\n```ts\nimport { httpUrl } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestUrl: '' }, {\n bestUrl: { httpUrl },\n // or with custom protocol validation\n bestUrl: { httpUrl: httpUrl({ protocol: /^https$/ }) },\n})\n```\n\n## `integer`\n\nAllows only integers (positive and negative).\n\n```ts\nimport { integer } from '@regle/rules';\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: { integer },\n})\n```\n\n## `ipv4Address`\n\nValidates IPv4 addresses in dotted decimal notation *127.0.0.1*.\n\n```ts\nimport { ipv4Address } from '@regle/rules';\n\nconst { r$ } = useRegle({ address: '' }, {\n address: { ipv4Address },\n})\n```\n\n<Ipv4AddressDemo />\n\n## `literal`\n\nValidates literal values.\n\n### Note\n\nThis rule does not need `required` to be set, it will assert the value is set.\n\n```ts\nimport { literal } from '@regle/rules';\n\nconst { r$ } = useRegle({ value: '' }, {\n value: { literal: literal('foo') },\n})\n```\n\n## `lowercase`\n\nValidates lowercase strings.\n\n```ts\nimport { lowercase } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: { lowercase },\n})\n```\n\n## `macAddress`\n\n_**Params**_\n - `separator?: string | Ref<string> | () => string`\n\nValidates MAC addresses. Call as a function to specify a custom separator (e.g., ':' or an empty string for 00ff1122334455).\n\n```ts\nimport { useRegle } from '@regle/core';\nimport { macAddress } from '@regle/rules';\n\nconst { r$ } = useRegle({ address: '' }, {\n address: {\n macAddress,\n // or\n macAddress: macAddress('-')\n },\n});\n```\n\n## `maxFileSize`\n\nRequires a value to be a file with a maximum size.\n\n```ts\nimport { maxFileSize } from '@regle/rules';\n\nconst { r$ } = useRegle({ file: null as File | null }, {\n file: { maxFileSize: maxFileSize(10_000_000) }, // 10 MB\n})\n```\n\n## `maxLength`\n\n_**Params**_\n - `max: Ref<number> | number | () => number`\n - `options?: {allowEqual?: boolean}`\n\n_**Works with**_\n - `Array | Record | string | number`\n\nRequires the input value to have a maximum specified length, inclusive. Works with arrays, objects and strings.\n\n```ts\nimport { maxLength } from '@regle/rules';\n\nconst maxValue = ref(6);\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n maxLength: maxLength(6),\n maxLength: maxLength(maxValue),\n maxLength: maxLength(() => maxValue.value)\n },\n})\n```\n\n## `maxValue`\n\n_**Params**_\n - `min: Ref<number> | number | () => number`\n - `options?: {allowEqual?: boolean}`\n\n Requires a field to have a specified maximum numeric value.\n\n```ts\nimport { maxValue } from '@regle/rules';\n\nconst maxCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n maxValue: maxValue(6),\n maxValue: maxValue(maxCount, {allowEqual: false}),\n maxValue: maxValue(() => maxCount.value)\n },\n})\n```\n\n## `minFileSize`\n\nRequires a value to be a file with a minimum size.\n\n```ts\nimport { minFileSize } from '@regle/rules';\n\nconst { r$ } = useRegle({ file: null as File | null }, {\n file: { minFileSize: minFileSize(1_000_000) }, // 1 MB\n})\n```\n\n## `minLength`\n\n_**Params**_\n - `min: Ref<number> | number | () => number`\n - `options?: {allowEqual?: boolean}`\n\n_**Works with**_\n - `Array | Record | string | number`\n\nRequires the input value to have a minimum specified length, inclusive. Works with arrays, objects and strings.\n\n```ts\nimport { minLength } from '@regle/rules';\n\nconst minValue = ref(6);\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n minLength: minLength(6),\n minLength: minLength(minValue),\n minLength: minLength(() => minValue.value)\n },\n})\n```\n\n## `minValue`\n\n_**Params**_\n - `min: Ref<number> | number | () => number`\n - `options?: {allowEqual?: boolean}`\n\n_**Works with**_\n - `number`\n\nRequires a field to have a specified minimum numeric value.\n\n```ts\nimport { minValue } from '@regle/rules';\n\nconst minCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n minValue: minValue(6),\n minValue: minValue(minCount, {allowEqual: false}),\n minValue: minValue(() => minCount.value)\n },\n})\n```\n\n## `nativeEnum`\n\nValidate against a native Typescript enum value. Similar to Zod's `nativeEnum`\n\n```ts\nimport { nativeEnum } from '@regle/rules';\n\nenum Foo {\n Bar, Baz\n}\n\nconst { r$ } = useRegle({ type: '' }, {\n type: { nativeEnum: nativeEnum(Foo) },\n})\n```\n\n## `number`\n\nRequires a value to be a native number type. Mainly used for typing.\n\n```ts\nimport { number } from '@regle/rules';\n\nconst rules = {\n count: { number },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `numeric`\n\nAllows only numeric values (including numeric strings).\n\n```ts\nimport { numeric } from '@regle/rules';\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: { numeric },\n})\n```\n\n## `oneOf`\n\nAllow only one of the values from a fixed Array of possible entries.\n\n_**Params**_\n - `options: MaybeRefOrGetter<Array<string | number>>`\n\n```ts\nimport { oneOf } from '@regle/rules';\n\nconst foodEnum = {\n Fish: 'Fish',\n Meat: 'Meat',\n Bone: 'Bone',\n} as const;\n\nconst { r$ } = useRegle({ aliment: 'Fish' }, {\n aliment: {\n oneOf: oneOf(['Fish', 'Meat', 'Bone']),\n // or\n oneOf: oneOf(foodEnum),\n },\n})\n```\n\n## `regex`\n\n_**Params**_\n- `regexps: MaybeRefOrGetter<RegExp | RegExp[]>`\n\nChecks if the value matches one or more regular expressions.\n\n```ts\nimport { regex } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n regex: regex(/^foo/),\n regex: regex([/^bar/, /baz$/]),\n },\n})\n```\n\n## `required`\n\nRequires non-empty data. Checks for empty arrays and strings containing only whitespaces.\n\n```ts\nimport {required} from '@regle/rules';\n\nconst {r$} = useRegle({name: ''}, {\n name: {required},\n})\n```\n\n## `requiredIf`\n\n_**Params**_\n - `condition: Ref<unknown> | unknown | () => unknown` - the property to base the `required` validator on.\n\nRequires non-empty data, only if provided data property, ref, or a function resolves to `true`.\n\n```ts\nimport { requiredIf } from '@regle/rules';\n\nconst form = ref({ name: '', condition: false });\n\nconst conditionRef = ref(false);\n\nconst { r$ } = useRegle(form, {\n name: {\n required: requiredIf(() => form.value.condition),\n required: requiredIf(conditionRef),\n },\n})\n```\n\n## `requiredUnless`\n\n_**Params**_\n - `condition: Ref<unknown> | unknown | () => unknown` - the property to base the `required` validator on.\n\nRequires non-empty data, only if provided data property, ref, or a function resolves to `false`.\n\n```ts\nimport { requiredUnless } from '@regle/rules';\n\nconst form = ref({ name: '', condition: false });\n\nconst conditionRef = ref(false);\n\nconst { r$ } = useRegle(form, {\n name: {\n required: requiredUnless(() => form.value.condition),\n required: requiredUnless(conditionRef)\n },\n})\n```\n\n## `sameAs`\n\n_**Params**_\n * `target: unknown`\n\nChecks if the value matches the specified property or ref.\n\n```ts\nimport { sameAs } from '@regle/rules';\n\nconst form = ref({\n password: '',\n confirmPassword: '',\n});\n\nconst { r$ } = useRegle(form, {\n confirmPassword: {\n sameAs: sameAs(() => form.value.password),\n }\n})\n```\n\n## `startsWith`\n\n_**Params**_\n- `start: Ref<string> | string | () => string`\n\nChecks if the string starts with the specified substring.\n\n```ts\nimport { startsWith } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestLib: '' }, {\n bestLib: {\n startsWith: startsWith('regle')\n },\n})\n```\n\n## `string`\n\nRequires a value to be a native string type. Mainly used for typing\n\n```ts\nimport {type InferInput} from '@regle/core';\nimport { string } from '@regle/rules';\n\nconst rules = {\n firstName: { string },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `type`\n\nDefine the input type of a rule. No runtime validation. \nOverride any input type set by other rules.\n\n```ts\nimport {type InferInput} from '@regle/core';\nimport { type } from '@regle/rules';\n\nconst rules = {\n firstName: { type: type<string>() },\n}\n\nconst state = ref<InferInput<typeof rules>>({});\n```\n\n## `uppercase`\n\nValidates uppercase strings.\n\n```ts\nimport { uppercase } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: { uppercase },\n})\n```\n\n## `url`\n\n_**Params**_\n- `options?: {protocol?: RegExp}`\n\nValidates URLs.\n\n```ts\nimport { url } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestUrl: '' }, {\n bestUrl: { url },\n // or with custom protocol validation\n bestUrl: { url: url({ protocol: /^https?$/ }) },\n})\n```"
|
|
142
142
|
},
|
|
143
143
|
{
|
|
144
144
|
"id": "core-concepts-rules-index",
|
|
@@ -152,14 +152,14 @@ const rawData = {
|
|
|
152
152
|
"title": "Reusable rules",
|
|
153
153
|
"category": "rules",
|
|
154
154
|
"path": "core-concepts/rules/reusable-rules.md",
|
|
155
|
-
"content": "# Reusable rules\n\n## `createRule`\n\nTo create reusable rules, it’s recommended to use `createRule`. This utility simplifies defining the rule’s type, parameters, active state as well as track reactive dependencies automatically.\n\nExample: Recreating a simple `required` rule\n\n```ts\nimport { createRule } from '@regle/core';\nimport { isFilled } from '@regle/rules';\n\nexport const required = createRule({\n validator: (value: unknown) => {\n return isFilled(value);\n },\n message: 'This field is required',\n});\n```\n\n## Available options:\n\n### `validator`\n_**Type**_: `(value, ...params?) => boolean | {$valid: boolean, [x: string]: any}`\n\n*required*\n\nThe `validator` function determines whether the field is valid. You can write it in the same way as an inline rule.\n\n### `message`\n_**Type**_: `string | string[] | (metadata) => (string | string[])`\n\n*required*\n\nThis will define what error message you assign to your rule. It can be a string or a function receiving the value, params and metadata as parameters.\n\n### `type` \n_**Type**_: `string`\n\n*optional*\n\nSpecifies the type of validator. This is useful when multiple rules share the same target, such as `required` and `requiredIf`.\n\n### `active`\n_**Type**_: `boolean | (metadata) => boolean`\n\n*optional*\n\nDefines the `$active` state of the rule, indicating whether the rule is currently being validated. This can be computed dynamically.\nFor more details, see [Parameters and active mode](#parameters-and-active-mode).\n\n### `async`\n_**Type**_: `boolean`\n\n*optional*\n\nIf your validator function is not written with `async await` syntax, you can enforce the rule to be async with this parameter.\n\n### `tooltip`\n_**Type**_: `string | string[] | (metadata) => (string | string[])`\n\n*optional*\n\nUse `tooltip` to display non-error-related messages for your field. These tooltips are aggregated and made accessible via `xxx.$tooltips`. This is useful for providing additional information or guidance.\n\n## Reactive parameters\n\nWith `createRule` you can easily define a rule that will depend on external reactive parameters.\n\n### Declaration\n\nWhen declaring your validator, **Regle** will detect that your rule requires parameters and transform it into a function declaration:\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\n\nexport const myValidator = createRule({\n validator: (value: Maybe<string>, arg: number) => {\n return true;\n },\n message: ({ $params: [arg] }) => {\n return 'This field is invalid';\n }\n});\n```\n\nThe parameters detection also works with optional and spread parameters\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\n\nexport const myValidator = createRule({\n validator: (value: Maybe<string>, optionalArg?: number, otherOptional?: string) => {\n return true;\n },\n message: ({ $params: [optionalArg, otherOptional] }) => {\n return 'This field is invalid';\n }\n});\n\nconst {r$} = useRegle({foo: ''}, {\n foo: {\n // Can be used inline if first parameter is optional\n myValidator,\n // or\n myValidator: myValidator(5),\n // or\n myValidator: myValidator(5, 'foo')
|
|
155
|
+
"content": "# Reusable rules\n\n## `createRule`\n\nTo create reusable rules, it’s recommended to use `createRule`. This utility simplifies defining the rule’s type, parameters, active state as well as track reactive dependencies automatically.\n\nExample: Recreating a simple `required` rule\n\n```ts\nimport { createRule } from '@regle/core';\nimport { isFilled } from '@regle/rules';\n\nexport const required = createRule({\n validator: (value: unknown) => {\n return isFilled(value);\n },\n message: 'This field is required',\n});\n```\n\n## Available options:\n\n### `validator`\n_**Type**_: `(value, ...params?) => boolean | {$valid: boolean, [x: string]: any}`\n\n*required*\n\nThe `validator` function determines whether the field is valid. You can write it in the same way as an inline rule.\n\n### `message`\n_**Type**_: `string | string[] | (metadata) => (string | string[])`\n\n*required*\n\nThis will define what error message you assign to your rule. It can be a string or a function receiving the value, params and metadata as parameters.\n\n### `type` \n_**Type**_: `string`\n\n*optional*\n\nSpecifies the type of validator. This is useful when multiple rules share the same target, such as `required` and `requiredIf`.\n\n### `active`\n_**Type**_: `boolean | (metadata) => boolean`\n\n*optional*\n\nDefines the `$active` state of the rule, indicating whether the rule is currently being validated. This can be computed dynamically.\nFor more details, see [Parameters and active mode](#parameters-and-active-mode).\n\n### `async`\n_**Type**_: `boolean`\n\n*optional*\n\nIf your validator function is not written with `async await` syntax, you can enforce the rule to be async with this parameter.\n\n### `tooltip`\n_**Type**_: `string | string[] | (metadata) => (string | string[])`\n\n*optional*\n\nUse `tooltip` to display non-error-related messages for your field. These tooltips are aggregated and made accessible via `xxx.$tooltips`. This is useful for providing additional information or guidance.\n\n## Reactive parameters\n\nWith `createRule` you can easily define a rule that will depend on external reactive parameters.\n\n### Declaration\n\nWhen declaring your validator, **Regle** will detect that your rule requires parameters and transform it into a function declaration:\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\n\nexport const myValidator = createRule({\n validator: (value: Maybe<string>, arg: number) => {\n return true;\n },\n message: ({ $params: [arg] }) => {\n return 'This field is invalid';\n }\n});\n```\n\nThe parameters detection also works with optional and spread parameters\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\n\nexport const myValidator = createRule({\n validator: (value: Maybe<string>, optionalArg?: number, otherOptional?: string) => {\n return true;\n },\n message: ({ $params: [optionalArg, otherOptional] }) => {\n return 'This field is invalid';\n }\n});\n\nconst {r$} = useRegle({foo: ''}, {\n foo: {\n // Can be used inline if first parameter is optional\n myValidator,\n // or\n myValidator: myValidator(5),\n // or\n myValidator: myValidator(5, 'foo'),\n }\n})\n```\n\n:::warning\n\nWhile adding spread parameters `...anyOtherArg` is supported, keep in mind that it will receive every parameters, even the ones injected by a parent modifier like `applyIf`, `and`, `or` etc..\n\nSo it's not advised to use it\n:::\n\n### Reactivity\n\nThe real advantage of using `createRule` is that it automatically registers parameters as reactive dependencies. This means your rule works seamlessly with plain values, refs, or getter functions.\n\n```ts\nconst max = ref(5);\n\nuseRegle({name: ''},{\n name: {\n // Plain value\n rule1: myValidator(5),\n // Ref\n rule2: myValidator(max),\n // Getter value\n rule3: myValidator(() => max.value)\n }\n})\n```\n\n:::warning\nIf you pass a raw value as a parameter, it will only be reactive if all your rules are declared as a computed or a getter function\n\n```ts\nconst state = ref({name: ''})\nconst max = ref(5);\n\n// ❌ Not reactive\nuseRegle(state, {\n name: {\n maxLength: maxLength(max.value),\n ...(max.value === 3 && {\n required,\n })\n }\n})\n\n// ✅ Reactive\nuseRegle(state, () => ({\n name: {\n maxLength: maxLength(max.value),\n ...(max.value === 3 && {\n required,\n })\n }\n}))\n\n// ✅ Reactive\nconst rules = computed(() => ({\n name: {\n maxLength: maxLength(max.value),\n ...(max.value === 3 && {\n required,\n })\n }\n}))\nuseRegle(state, rules);\n\n```\n:::\n\n### Default values\n\nYou can set default value directly in the rule declaration. Be sure to type it correctly.\n\nThere will be difference in implementation if you want to access the parameter value in the message factory function as a function scope is unreadable from outside its scope.\n\nYou'll have to return explicitly the default value in the validator function, and declare the parameter as metadata.\n\n```ts\nexport const myValidator = createRule({\n validator: (value: Maybe<number>, arg: number = 0) => {\n return {\n $valid: value === arg,\n arg,\n };\n },\n message: ({ arg }) => `The value must be ${arg}`,\n});\n```\n\n### Active property\n\nThe `active` property option is a field that will provide the rule an `on/off` behaviour.\n\nSome rules have conditional validation properties, such as `requiredIf` or any rule using `applyIf`.\nThis property allows you to declare the active state of the rule.\n\nIt will then be exposed in the `$active` rule property and be used to reflect the validation to your user.\n\n```ts\nimport { createRule, useRegle } from '@regle/core';\n\nconst myConditionalRule = createRule({\n validator(value: unknown, param: string) {\n // Params like `condition` will always be unwrapped here\n // no need to check if it's a value, a ref or a getter function\n if (param === \"Yes\") {\n return isFilled(value);\n }\n return true;\n },\n active({ $params: [condition] }) {\n return condition === 'Yes';\n },\n});\n```\n\nUsage in a component:\n\n```vue\n\n<template>\n <label>\n Name <span v-if=\"r$.name.$rules.myConditionalRule.$active\">(required)</span>\n </label>\n</template>\n\n```\n\n### Recreating `requiredIf` rule\n\n::: code-group\n\n```vue [Form.vue]\n\n<template>\n <div>\n <input v-model=\"condition\" type='checkbox'/>\n <label>The field is required</label>\n </div>\n\n <div>\n <!-- Here we can use $active to know if the rule is enabled -->\n <input \n v-model='r$.$value.name'\n :placeholder='`Type your name${r$.name.$rules.required.$active ? \"*\": \"\"}`'\n />\n\n <button type=\"button\" @click=\"r$.$reset({toInitialState: true})\">Reset</button>\n </div>\n\n <ul v-if=\"r$.$errors.name.length\">\n <li v-for=\"error of r$.$errors.name\" :key='error'>\n {{ error }}\n </li>\n </ul>\n</template>\n```\n:::\n\nResult: \n\n## Async rules\n\nAsync rules are useful for server-side validations or computationally expensive local checks. They update the `$pending` state whenever invoked.\n\n```vue [App.vue]\n<template>\n <div class=\"demo-container\">\n <div>\n <input\n v-model=\"form.email\"\n :class=\"{ pending: r$.email.$pending }\"\n placeholder=\"Type your email\"\n />\n\n <button type=\"button\" @click=\"r$.$reset({toInitialState: true})\">Reset</button>\n <button type=\"button\" @click=\"r$.$validate()\">Submit</button>\n </div>\n\n <span v-if=\"r$.email.$pending\"> Checking... </span>\n \n <ul v-if=\"r$.$errors.email.length\">\n <li v-for=\"error of r$.$errors.email\" :key=\"error\">\n {{ error }}\n </li>\n </ul>\n </div>\n</template>\n\n```\n\n## Metadata\n\nLike in inline rules, you can return any data from your validator function as long as it returns an object containing at least `$valid: boolean`.\n\nIt can be useful for returning computed data from the validator, or in async function to process api result, or api errors.\n\n```ts twoslash {8}\nimport { createRule } from '@regle/core';\n\nexport const example = createRule({\n validator: (value) => {\n if (value === 'regle') {\n return {\n $valid: false,\n foo: 'bar'\n }\n }\n return true;\n },\n message({foo}) {\n\n return 'Error example';\n },\n});\n```"
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
"id": "core-concepts-rules-rule-wrappers",
|
|
159
159
|
"title": "Rule wrappers",
|
|
160
160
|
"category": "rules",
|
|
161
161
|
"path": "core-concepts/rules/rule-wrappers.md",
|
|
162
|
-
"content": "# Rule wrappers\n\nRule wrappers let you customize or upgrade your rules by injecting or replacing some properties.\n\n## Built-in wrappers\n\n### `withMessage`\n\nThe withMessage wrapper lets you associate an error message with a rule. Pass your rule as the first argument and the error message as the second.\n\n``` ts twoslash {5-13}\n\nimport { useRegle, type InlineRuleDeclaration, type Maybe, type MaybeInput } from '@regle/core';\n// ---cut---\nimport { withMessage } from '@regle/rules';\n\nconst customRuleInlineWithMetaData = ((value: Maybe<string>) => ({\n $valid: value === 'regle',\n foo: 'bar' as const\n})) satisfies InlineRuleDeclaration;\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n // Inline functions can be also written... inline\n customRule1: withMessage((value: MaybeInput<string>) => !!value, \"Custom Error\"),\n customRule2: withMessage(customRuleInlineWithMetaData, \"Custom Error\"),\n\n // You can also access the current value and metadata with a getter function\n customRule3: withMessage(\n customRuleInlineWithMetaData, \n ({ $value, foo }) => `Custom Error: ${$value} ${foo}`\n\n ), \n }\n})\n```\n\nEvery error can be accessed in the `r$` object. In either `$errors` (if the field is dirty) or `$silentErrors` properties.\n\nIn this case:\n\n- `r$.$errors.name`\n- `r$.name.$errors`\n\n### `withParams`\n\nThe withParams wrapper allows your rule to depend on external parameters, such as a reactive property in your component or store.\n\nBy default, useRegle observes changes automatically when rules are defined using getter functions or computed properties.\n\n```ts\n/** Non reactive rules */\nuseRegle({}, { /* rules */})\n```\n\n⬇️\n\n```ts\nuseRegle({}, () => ({ /* rules */ }))\n// or\nconst rules = computed(() => ({/* rules */ }))\n\nuseRegle({}, rules)\n```\n\nHowever, sometimes dependencies cannot be tracked automatically, use `withParams` to manually define them:\n\n``` ts twoslash {7-9}\n\nimport { useRegle } from '@regle/core';\nimport { ref } from 'vue';\n// ---cut---\nimport { withParams } from '@regle/rules';\n\nconst base = ref('foo');\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n customRule: withParams((value, param) => value === param, [base]),\n // or\n customRule: withParams((value, param) => value === param, [() => base.value]),\n }\n})\n```\n\n### `withAsync`\n\n`withAsync` works like `withParams`, but is specifically designed for async rules that depend on external values.\n\n``` ts\nimport { withAsync } from '@regle/rules';\n\nconst base = ref('foo');\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n customRule: withAsync(async (value, param) => {\n await someAsyncCall(param)\n }, [base])\n }\n})\n```\n\n### `withTooltip`\n\nThe `withTooltip` wrapper allows you to display additional messages for your field that aren’t necessarily errors. \n\nTooltips are aggregated and accessible via `xxx.$tooltips`.\n\n## Chaining wrappers\n\nYou can combine multiple wrappers to create more powerful and flexible rules while keeping everything typed correctly.\n\n```ts twoslash {9-14}\n\nimport { useRegle } from '@regle/core';\nimport { ref } from 'vue';\nconst someAsyncCall = async (param: string) => await Promise.resolve(true);\n// ---cut---\nimport { withAsync, withMessage } from '@regle/rules';\n\nconst base = ref(1);\n\nconst { r$ } = useRegle({ name: '' },\n {\n name: {\n customRule: withMessage(\n withAsync(\n async (value, param) => await someAsyncCall(param),\n [base]\n ),\n ({$value, $params: [param] }) => `Custom error: ${$value} != ${param}`\n \n ),\n },\n }\n);\n```"
|
|
162
|
+
"content": "# Rule wrappers\n\nRule wrappers let you customize or upgrade your rules by injecting or replacing some properties.\n\n## Built-in wrappers\n\n### `withMessage`\n\nThe withMessage wrapper lets you associate an error message with a rule. Pass your rule as the first argument and the error message as the second.\n\n``` ts twoslash {5-13}\n\nimport { useRegle, type InlineRuleDeclaration, type Maybe, type MaybeInput } from '@regle/core';\n// ---cut---\nimport { withMessage } from '@regle/rules';\n\nconst customRuleInlineWithMetaData = ((value: Maybe<string>) => ({\n $valid: value === 'regle',\n foo: 'bar' as const\n})) satisfies InlineRuleDeclaration;\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n // Inline functions can be also written... inline\n customRule1: withMessage((value: MaybeInput<string>) => !!value, \"Custom Error\"),\n customRule2: withMessage(customRuleInlineWithMetaData, \"Custom Error\"),\n\n // You can also access the current value and metadata with a getter function\n customRule3: withMessage(\n customRuleInlineWithMetaData, \n ({ $value, foo }) => `Custom Error: ${$value} ${foo}`\n\n ), \n }\n})\n```\n\nEvery error can be accessed in the `r$` object. In either `$errors` (if the field is dirty) or `$silentErrors` properties.\n\nIn this case:\n\n- `r$.$errors.name`\n- `r$.name.$errors`\n\n### `withParams`\n\nThe withParams wrapper allows your rule to depend on external parameters, such as a reactive property in your component or store.\n\nBy default, useRegle observes changes automatically when rules are defined using getter functions or computed properties.\n\n```ts\n/** Non reactive rules */\nuseRegle({}, { /* rules */})\n```\n\n⬇️\n\n```ts\nuseRegle({}, () => ({ /* rules */ }))\n// or\nconst rules = computed(() => ({/* rules */ }))\n\nuseRegle({}, rules)\n```\n\nHowever, sometimes dependencies cannot be tracked automatically, use `withParams` to manually define them:\n\n``` ts twoslash {7-9}\n\nimport { useRegle } from '@regle/core';\nimport { ref } from 'vue';\n// ---cut---\nimport { withParams } from '@regle/rules';\n\nconst base = ref('foo');\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n customRule: withParams((value, param) => value === param, [base]),\n // or\n customRule: withParams((value, param) => value === param, [() => base.value]),\n }\n})\n```\n\n### `withAsync`\n\n`withAsync` works like `withParams`, but is specifically designed for async rules that depend on external values.\n\n``` ts\nimport { withAsync } from '@regle/rules';\n\nconst base = ref('foo');\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n customRule: withAsync(async (value, param) => {\n await someAsyncCall(param)\n }, [base])\n }\n})\n```\n\n### `withTooltip`\n\nThe `withTooltip` wrapper allows you to display additional messages for your field that aren’t necessarily errors. \n\nTooltips are aggregated and accessible via `xxx.$tooltips`.\n\n```ts\nimport { withTooltip } from '@regle/rules';\n\nconst { r$ } = useRegle({ password: '' }, {\n password: {\n strong: withTooltip(\n (value) => !!value && value.length >= 8,\n 'Password should be at least 8 characters'\n ),\n }\n})\n\n// Access tooltips in template: r$.password.$tooltips\n```\n\n## Chaining wrappers\n\nYou can combine multiple wrappers to create more powerful and flexible rules while keeping everything typed correctly.\n\n```ts twoslash {9-14}\n\nimport { useRegle } from '@regle/core';\nimport { ref } from 'vue';\nconst someAsyncCall = async (param: string) => await Promise.resolve(true);\n// ---cut---\nimport { withAsync, withMessage } from '@regle/rules';\n\nconst base = ref(1);\n\nconst { r$ } = useRegle({ name: '' },\n {\n name: {\n customRule: withMessage(\n withAsync(\n async (value, param) => await someAsyncCall(param),\n [base]\n ),\n ({$value, $params: [param] }) => `Custom error: ${$value} != ${param}`\n \n ),\n },\n }\n);\n```"
|
|
163
163
|
},
|
|
164
164
|
{
|
|
165
165
|
"id": "core-concepts-rules-rules-operators",
|
|
@@ -180,21 +180,21 @@ const rawData = {
|
|
|
180
180
|
"title": "Validations helpers",
|
|
181
181
|
"category": "rules",
|
|
182
182
|
"path": "core-concepts/rules/validations-helpers.md",
|
|
183
|
-
"content": "# Validations helpers\n\nWhen writing custom rules, some checks or validations can become tedious, especially when handling values that might be null, undefined, or unset. It's also a best practice to verify whether a field is \"filled\" before proceeding with validation.\n\nTo simplify this process, Regle provides a set of utility functions to assist in creating custom rules.\n\nThese utilities can be accessed via:\n\n```ts\nimport { isFilled, isEmpty, getSize, ... } from '@regle/rules';\n```\n\n## Runtime and Type guards\n\n### `isFilled`\n\n_**Params**_\n - `value: unknown`\n - `considerEmptyArrayInvalid = true`\n\nThis is almost a must have for optional fields. It checks if any value you provided is defined (including arrays and objects).\nYou can base your validator result on this.\n\n`isFilled` also acts as a type guard.\n\nBy default, it considers empty array as `false`. You can override this behaviour with the `considerEmptyArrayInvalid`\n\n```ts\nimport { createRule } from '@regle/core';\nimport { isFilled } from '@regle/rules';\n\nconst rule = createRule({\n validator(value: unknown) {\n if (isFilled(value)) {\n return check(value);\n }\n return true;\n },\n message: 'Error'\n})\n```\n\n### `isEmpty`\n\n_**Params**_\n - `value: unknown`\n - `considerEmptyArrayInvalid = true`\n\nThis is the inverse of `isFilled`. It will check if the value is in any way empty (including arrays and objects)\n\n`isEmpty` also acts as a type guard.\n\nBy default, it considers empty array as `true`. You can override this behaviour with the `considerEmptyArrayInvalid`\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isEmpty } from '@regle/rules';\n\nconst rule = createRule({\n validator(value: Maybe<string>) {\n if (isEmpty(value)) {\n return true;\n }\n return check(value);\n },\n message: 'Error'\n})\n```\n\n### `isNumber`\n\nThis is a type guard that will check if the passed value is a real `Number`.\nThis also returns false for `NaN`, so this is better than `typeof value === \"number\"`.\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled, isNumber } from '@regle/rules';\n\nconst rule = createRule({\n validator(value: Maybe<number | string>) {\n if (isFilled(value) && isNumber(value)) {\n return checkNumber(value);\n }\n return true;\n },\n message: 'Error'\n})\n```\n\n### `isDate`\n\nThis is a useful helper that can check if the provided value is a Date, it is used internally for `date` rules.\nThis can also check strings.\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled, isDate } from '@regle/rules';\n\nconst rule = createRule({\n validator(value: Maybe<string | Date>) {\n if (isFilled(value) && isDate(value)) {\n return checkDate(value);\n }\n return true;\n },\n message: 'Error'\n})\n```\n\n## Operations utils\n\n### `getSize`\n\nThis helper will return the length of any data type you pass.\nIt works with strings, arrays, objects and numbers.\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled, getSize } from '@regle/rules';\n\nconst rule = createRule({\n validator(value: Maybe<string | Array<number>>) {\n if (isFilled(value)) {\n return getSize(value) > 6;\n }\n return true;\n },\n message: 'Error'\n})\n```\n\n### `matchRegex`\n\nThis utility can take multiple regular expressions as arguments. It checks the input's validity and tests it against the provided regex patterns.\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled, matchRegex } from '@regle/rules';\n\nconst regex = createRule({\n validator(value: Maybe<string>, regexps: RegExp[]) {\n if (isFilled(value)) {\n return matchRegex(value, ...regexps);\n }\n return true;\n },\n message: 'Error'\n})\n```\n\n## Coerce utils\n\n### `toNumber`\n\nThis utility converts any string (or number) into a number using the `Number` constructor.\n\n:::warning\nThis helper returns `NaN` if the input cannot be coerced, which is technically still a number.\n\nIt can be safe to also check for `isNaN` additionally.\n:::\n\n### `toDate`\n\nThis utility will coerce any string, number or Date value into a Date using the `Date` constructor
|
|
183
|
+
"content": "# Validations helpers\n\nWhen writing custom rules, some checks or validations can become tedious, especially when handling values that might be null, undefined, or unset. It's also a best practice to verify whether a field is \"filled\" before proceeding with validation.\n\nTo simplify this process, Regle provides a set of utility functions to assist in creating custom rules.\n\nThese utilities can be accessed via:\n\n```ts\nimport { isFilled, isEmpty, getSize, ... } from '@regle/rules';\n```\n\n## Runtime and Type guards\n\n### `isFilled`\n\n_**Params**_\n - `value: unknown`\n - `considerEmptyArrayInvalid = true`\n\nThis is almost a must have for optional fields. It checks if any value you provided is defined (including arrays and objects).\nYou can base your validator result on this.\n\n`isFilled` also acts as a type guard.\n\nBy default, it considers empty array as `false`. You can override this behaviour with the `considerEmptyArrayInvalid`\n\n```ts\nimport { createRule } from '@regle/core';\nimport { isFilled } from '@regle/rules';\n\nconst rule = createRule({\n validator(value: unknown) {\n if (isFilled(value)) {\n return check(value);\n }\n return true;\n },\n message: 'Error'\n})\n```\n\n### `isEmpty`\n\n_**Params**_\n - `value: unknown`\n - `considerEmptyArrayInvalid = true`\n\nThis is the inverse of `isFilled`. It will check if the value is in any way empty (including arrays and objects)\n\n`isEmpty` also acts as a type guard.\n\nBy default, it considers empty array as `true`. You can override this behaviour with the `considerEmptyArrayInvalid`\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isEmpty } from '@regle/rules';\n\nconst rule = createRule({\n validator(value: Maybe<string>) {\n if (isEmpty(value)) {\n return true;\n }\n return check(value);\n },\n message: 'Error'\n})\n```\n\n### `isNumber`\n\nThis is a type guard that will check if the passed value is a real `Number`.\nThis also returns false for `NaN`, so this is better than `typeof value === \"number\"`.\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled, isNumber } from '@regle/rules';\n\nconst rule = createRule({\n validator(value: Maybe<number | string>) {\n if (isFilled(value) && isNumber(value)) {\n return checkNumber(value);\n }\n return true;\n },\n message: 'Error'\n})\n```\n\n### `isDate`\n\nThis is a useful helper that can check if the provided value is a Date, it is used internally for `date` rules.\nThis can also check strings.\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled, isDate } from '@regle/rules';\n\nconst rule = createRule({\n validator(value: Maybe<string | Date>) {\n if (isFilled(value) && isDate(value)) {\n return checkDate(value);\n }\n return true;\n },\n message: 'Error'\n})\n```\n\n## Operations utils\n\n### `getSize`\n\nThis helper will return the length of any data type you pass.\nIt works with strings, arrays, objects and numbers.\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled, getSize } from '@regle/rules';\n\nconst rule = createRule({\n validator(value: Maybe<string | Array<number>>) {\n if (isFilled(value)) {\n return getSize(value) > 6;\n }\n return true;\n },\n message: 'Error'\n})\n```\n\n### `matchRegex`\n\nThis utility can take multiple regular expressions as arguments. It checks the input's validity and tests it against the provided regex patterns.\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled, matchRegex } from '@regle/rules';\n\nconst regex = createRule({\n validator(value: Maybe<string>, regexps: RegExp[]) {\n if (isFilled(value)) {\n return matchRegex(value, ...regexps);\n }\n return true;\n },\n message: 'Error'\n})\n```\n\n## Coerce utils\n\n### `toNumber`\n\nThis utility converts any string (or number) into a number using the `Number` constructor.\n\n:::warning\nThis helper returns `NaN` if the input cannot be coerced, which is technically still a number.\n\nIt can be safe to also check for `isNaN` additionally.\n:::\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled, toNumber } from '@regle/rules';\n\nconst minValue = createRule({\n validator(value: Maybe<string | number>, min: number) {\n if (isFilled(value)) {\n const num = toNumber(value);\n return !isNaN(num) && num >= min;\n }\n return true;\n },\n message: ({ $params: [min] }) => `Value must be at least ${min}`,\n});\n```\n\n### `toDate`\n\nThis utility will coerce any string, number or Date value into a Date using the `Date` constructor.\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled, toDate } from '@regle/rules';\n\nconst afterToday = createRule({\n validator(value: Maybe<string | Date>) {\n if (isFilled(value)) {\n const date = toDate(value);\n return date > new Date();\n }\n return true;\n },\n message: 'Date must be in the future',\n});\n```"
|
|
184
184
|
},
|
|
185
185
|
{
|
|
186
186
|
"id": "core-concepts-validation-properties",
|
|
187
187
|
"title": "Validation properties",
|
|
188
188
|
"category": "core-concepts",
|
|
189
189
|
"path": "core-concepts/validation-properties.md",
|
|
190
|
-
"content": "# Validation properties\n\nValidation properties are computed values or methods available for every nested rule status, including `r$` and `regle`.\n\nLet's take a look at a simple example to explain the different properties.\n\n``` vue twoslash\n\n```\n<br/>\n\n## Computed properties for fields\n\n### `$invalid` \n- Type: `readonly boolean`\n\nIndicates whether the field is invalid. It becomes `true` if any associated rules return `false`.\n\n### `$correct` \n- Type: `readonly boolean`\n \nThis is not the opposite of `$invalid`. Correct is meant to display UI validation report. \nThis will be `true` only if:\n- The field have at least one active rule\n- Is dirty and not empty\n- Passes validation\n\n### `$dirty` \n- Type: `readonly boolean`\n \nIndicates whether a field has been validated or interacted with by the user at least once. It's typically used to determine if a message should be displayed to the user. You can change this flag manually using the `$touch` and `$reset` methods. The `$dirty` flag is considered true if the current model has been touched or if all its children are dirty. \n\n### `$anyDirty` \n- Type: `readonly boolean`\n\nSimilar to `$dirty`, with one exception. The `$anyDirty` flag is considered true if given model was touched or any of its children are `$anyDirty` which means at least one descendant is `$dirty`.\n\n### `$edited` \n- Type: `readonly boolean`\n \nIndicates whether a field has been touched and if the value is different than the initial one.\n\n### `$anyEdited` \n- Type: `readonly boolean`\n\nSimilar to `$edited`, with one exception. The $anyEdited flag is considered true if given model was edited or any of its children are $anyEdited which means at least one descendant is `$edited`.\n\n### `$value` \n- Type: `TValue` (The current property value type)\n\nA reference to the original validated model. It can be used to bind your form with `v-model`.\n\n### `$silentValue` \n- Type: `TValue` (The current property value type)\n\n`$value` variant that will not \"touch\" the field and update the value silently, running only the rules, so you can easily swap values without impacting user interaction.\n\n### `$initialValue` \n- Type: `TValue` \n\nInitial value of the field. This value will be set to the current `$value` when using `$reset`.\n\n### `$originalValue` \n- Type: `TValue` \n\nOriginal value of the field. This value is the unmutated state that was passed to the form when it was initialized. This value will not be mutated when using `$reset`.\n\n \n### `$pending` \n- Type: `readonly boolean`\n\nIndicates if any async rule for the field is currently running. Always `false` for synchronous rules.\n\n### `$ready` \n- Type: `readonly boolean`\n\nIndicates whether the field is ready for submission. Equivalent to `!$invalid && !$pending`.\n\n### `$error` \n- Type: `readonly boolean`\n\nConvenience flag to easily decide if a message should be displayed. Equivalent to `$dirty && !$pending && $invalid`.\n\n### `$errors` \n- Type: `readonly string[]`\n\nCollection of all the error messages, collected for all children properties and nested forms. Only contains errors from properties where $dirty equals `true`.\n\n### `$silentErrors` \n- Type: `readonly string[]`\n\nCollection of all the error messages, collected for all children properties.\n\n### `$issues` \n- Type: `RegleFieldIssue[]`\n\nCollect all metadata of validators (errors, messages etc). Only contains metadata from properties where $dirty equals true.\n\n### `$name` \n- Type: `readonly string`\n\nReturn the current key name of the field.\n\n## Common methods for fields\n\n### `$validate` \n- Type: `(forceValues?: TState) => Promise<false | SafeOutput<TState>>`\n\nSets all properties as dirty, triggering all rules. \nIt returns a promise that will either resolve to `false` or a Headless copy of your form state. Values that had the `required` rule will be transformed into a non-nullable value (type only).\n\n#### `forceValues` parameter\n\nThe first argument is optional and can be used to assign a new state before validating. It's equivalent to use `r$.$value = x` and `r$.$validate();`.\n\n### `$validateSync` \n- Type: `(forceValues?: TState) => boolean`\n\nValidates the form synchronously without waiting for async rules. This method:\n- Does **NOT** wait for async validation results (async rules are skipped and assumed valid)\n- Returns a `boolean` directly instead of a `Promise`\n\nUse this when you need immediate validation feedback without side effects, such as for real-time UI feedback or form gating logic.\n\n```ts\n// Basic usage\nconst isValid = r$.$validateSync();\n\n// Field-level validation\nconst isEmailValid = r$.email.$validateSync();\n\n// Use with form submission gating\nfunction handleSubmit() {\n if (r$.$validateSync()) {\n // Proceed with submission\n }\n}\n```\n\n:::warning\nSince `$validateSync` skips async rules, use `$validate()` when you need to ensure all validations (including async) have passed before submission.\n:::\n\n### `$extractDirtyFields` \n- Type: `(filterNullishValues = true) => DeepPartial<TState>`\n\nWill return a copy of your state with only the fields that are dirty.\nBy default it will filter out nullish values or objects, but you can override it with the first parameter `$extractDirtyFields(false)`.\n\n### `$touch` \n- Type: `() => void`\n\nMarks the field and all nested properties as `$dirty`.\n\n### `$reset` \n- Type: `(options?: ResetOptions) => void`\n\nReset the validation status to a pristine state while keeping the current state.\nThe current state is treated as the new initial state.\n\n:::tip\nFor more information about the `$reset` method, check the [
|
|
190
|
+
"content": "# Validation properties\n\nValidation properties are computed values or methods available for every nested rule status, including `r$` and `regle`.\n\nLet's take a look at a simple example to explain the different properties.\n\n``` vue twoslash\n\n```\n<br/>\n\n## Computed properties for fields\n\n### `$invalid` \n- Type: `readonly boolean`\n\nIndicates whether the field is invalid. It becomes `true` if any associated rules return `false`.\n\n### `$correct` \n- Type: `readonly boolean`\n \nThis is not the opposite of `$invalid`. Correct is meant to display UI validation report. \nThis will be `true` only if:\n- The field have at least one active rule\n- Is dirty and not empty\n- Passes validation\n\n### `$dirty` \n- Type: `readonly boolean`\n \nIndicates whether a field has been validated or interacted with by the user at least once. It's typically used to determine if a message should be displayed to the user. You can change this flag manually using the `$touch` and `$reset` methods. The `$dirty` flag is considered true if the current model has been touched or if all its children are dirty. \n\n### `$anyDirty` \n- Type: `readonly boolean`\n\nSimilar to `$dirty`, with one exception. The `$anyDirty` flag is considered true if given model was touched or any of its children are `$anyDirty` which means at least one descendant is `$dirty`.\n\n### `$edited` \n- Type: `readonly boolean`\n \nIndicates whether a field has been touched and if the value is different than the initial one.\n\n### `$anyEdited` \n- Type: `readonly boolean`\n\nSimilar to `$edited`, with one exception. The $anyEdited flag is considered true if given model was edited or any of its children are $anyEdited which means at least one descendant is `$edited`.\n\n### `$value` \n- Type: `TValue` (The current property value type)\n\nA reference to the original validated model. It can be used to bind your form with `v-model`.\n\n### `$silentValue` \n- Type: `TValue` (The current property value type)\n\n`$value` variant that will not \"touch\" the field and update the value silently, running only the rules, so you can easily swap values without impacting user interaction.\n\n### `$initialValue` \n- Type: `TValue` \n\nInitial value of the field. This value will be set to the current `$value` when using `$reset`.\n\n### `$originalValue` \n- Type: `TValue` \n\nOriginal value of the field. This value is the unmutated state that was passed to the form when it was initialized. This value will not be mutated when using `$reset`.\n\n \n### `$pending` \n- Type: `readonly boolean`\n\nIndicates if any async rule for the field is currently running. Always `false` for synchronous rules.\n\n### `$ready` \n- Type: `readonly boolean`\n\nIndicates whether the field is ready for submission. Equivalent to `!$invalid && !$pending`.\n\n### `$error` \n- Type: `readonly boolean`\n\nConvenience flag to easily decide if a message should be displayed. Equivalent to `$dirty && !$pending && $invalid`.\n\n### `$errors` \n- Type: `readonly string[]`\n\nCollection of all the error messages, collected for all children properties and nested forms. Only contains errors from properties where $dirty equals `true`.\n\n### `$silentErrors` \n- Type: `readonly string[]`\n\nCollection of all the error messages, collected for all children properties.\n\n### `$issues` \n- Type: `RegleFieldIssue[]`\n\nCollect all metadata of validators (errors, messages etc). Only contains metadata from properties where $dirty equals true.\n\n### `$name` \n- Type: `readonly string`\n\nReturn the current key name of the field.\n\n## Common methods for fields\n\n### `$validate` \n- Type: `(forceValues?: TState) => Promise<false | SafeOutput<TState>>`\n\nSets all properties as dirty, triggering all rules. \nIt returns a promise that will either resolve to `false` or a Headless copy of your form state. Values that had the `required` rule will be transformed into a non-nullable value (type only).\n\n#### `forceValues` parameter\n\nThe first argument is optional and can be used to assign a new state before validating. It's equivalent to use `r$.$value = x` and `r$.$validate();`.\n\n### `$validateSync` \n- Type: `(forceValues?: TState) => boolean`\n\nValidates the form synchronously without waiting for async rules. This method:\n- Does **NOT** wait for async validation results (async rules are skipped and assumed valid)\n- Returns a `boolean` directly instead of a `Promise`\n\nUse this when you need immediate validation feedback without side effects, such as for real-time UI feedback or form gating logic.\n\n```ts\n// Basic usage\nconst isValid = r$.$validateSync();\n\n// Field-level validation\nconst isEmailValid = r$.email.$validateSync();\n\n// Use with form submission gating\nfunction handleSubmit() {\n if (r$.$validateSync()) {\n // Proceed with submission\n }\n}\n```\n\n:::warning\nSince `$validateSync` skips async rules, use `$validate()` when you need to ensure all validations (including async) have passed before submission.\n:::\n\n### `$extractDirtyFields` \n- Type: `(filterNullishValues = true) => DeepPartial<TState>`\n\nWill return a copy of your state with only the fields that are dirty.\nBy default it will filter out nullish values or objects, but you can override it with the first parameter `$extractDirtyFields(false)`.\n\n### `$touch` \n- Type: `() => void`\n\nMarks the field and all nested properties as `$dirty`.\n\n### `$reset` \n- Type: `(options?: ResetOptions) => void`\n\nReset the validation status to a pristine state while keeping the current state.\nThe current state is treated as the new initial state.\n\n:::tip\nFor more information about the `$reset` method, check the [resetting forms section](/common-usage/reset-form)\n:::\n\n### `$clearExternalErrors` \n- Type: `() => void`\n\nClears the `$externalErrors` state back to an empty object.\n\n### `$setExternalErrors`\n- Type: `(errors: RegleExternalErrorTree<TState> | Record<string, string[]>) => void`\n\nSets external errors from either a nested object or dot-path keys.\nThis method is available on the root `r$`, and works with or without passing the `externalErrors` option to `useRegle`.\n\n```ts\nr$.$setExternalErrors({\n email: ['Email already exists'],\n 'user.firstName': ['First name already exists'],\n});\n```\n\n### `$addRules`\n- Type: `(rules: RegleRuleDecl) => void`\n\nAdds runtime rules to the current field status.\nThis is useful when a child component receives a `RegleFieldStatus` and needs to attach its own field-specific validation rules.\n\n:::warning\nThis is convenient for children components to add rules to their parent field status, but you will lose a bit of type safety.\n:::\n\n```ts\nconst { r$ } = useRegle(form, {\n password: {},\n});\n\nr$.password.$addRules({\n required,\n minLength: minLength(8),\n});\n```\n\n### `addRules` (deprecated)\n- Type: `(rules: RegleRuleDecl) => void`\n\n:::warning Deprecated\nUse `$addRules` instead. This alias will be removed in a future version.\n:::\n\n## Specific properties for fields\n\n### `$rules` \n- Type: `Record<string, RegleRuleStatus>`\n\nThis is reactive tree containing all the declared rules of your field.\nTo know more about the rule properties check the [rules properties section](/core-concepts/rules/rules-properties)\n\n \n### `$silentIssues` \n- Type: `RegleFieldIssue[]`\n\nCollect all metadata of validators (errors, messages etc).\n \n\n## Specific properties for nested objects\n\n### `$fields` \n- Type: `Record<string, RegleStatus | RegleFieldStatus | RegleCollectionStatus>`\n\nThis represents all the children of your object. You can access any nested child at any depth to get the relevant data you need for your form.\n\n### `$self`\n- Type: `RegleFieldStatus`\nRepresents the status of the object itself. You can have validation rules on the object like `required`, this field represents the isolated status of the object.\n\n## Specific properties for collections\n\nCheck documentation for [collections here](/common-usage/collections)\n\n### `$each`\n- Type: `Array<string, RegleStatus>`\n\nThis will store the status of every item in your collection. Each item will be a field you can access, or map on it to display your elements.\n\n### `$self` \n- Type: `RegleFieldStatus`\nRepresents the status of the collection itself. You can have validation rules on the array like `minLength`, this field represents the isolated status of the collection."
|
|
191
191
|
},
|
|
192
192
|
{
|
|
193
193
|
"id": "examples-advanced",
|
|
194
194
|
"title": "Advanced demo",
|
|
195
195
|
"category": "examples",
|
|
196
196
|
"path": "examples/advanced.md",
|
|
197
|
-
"content": "# Advanced demo\n\nYou can play with the code of this example in the stackblitz sandbox.\n\nDon't
|
|
197
|
+
"content": "# Advanced demo\n\nYou can play with the code of this example in the stackblitz sandbox.\n\nDon't forget to install the `Vue` extension in the online IDE.\n\n<a target='_blank' href=\"https://stackblitz.com/~/github.com/victorgarciaesgi/regle-examples/tree/main/examples/advanced-example?file=examples/advanced-example/src/App.vue&configPath=examples/advanced-example\">\n <img\n alt=\"Open in StackBlitz\"\n src=\"https://developer.stackblitz.com/img/open_in_stackblitz.svg\"\n />\n</a>\n\n<iframe style='width: 100%; height: 700px' src=\"https://stackblitz.com/github/victorgarciaesgi/regle-examples/tree/main/examples/advanced-example?embed=1&file=src%2FApp.vue&theme=dark&view=preview\" title=\"Sandbox editor\" sandbox=\"allow-modals allow-forms allow-popups allow-scripts allow-same-origin\"></iframe>"
|
|
198
198
|
},
|
|
199
199
|
{
|
|
200
200
|
"id": "examples-collections",
|
|
@@ -222,7 +222,7 @@ const rawData = {
|
|
|
222
222
|
"title": "index",
|
|
223
223
|
"category": "examples",
|
|
224
224
|
"path": "examples/index.md",
|
|
225
|
-
"content": "#
|
|
225
|
+
"content": "# Examples\n\n## Playground\n\nYou can try Regle in the [Regle Playground](https://play.reglejs.dev).\n\n## Simple Validation Example\n\nSee a minimal usage of Regle's validation logic: \n[Simple Validation Example](./simple.md)\n\n## Advanced Example\n\nAdvanced validation patterns and techniques: \n[Advanced Example](./advanced.md)\n\n## Collections Example\n\nWorking with arrays and collections in your forms: \n[Collections Example](./collections.md)\n\n## Server Validation Example\n\nHandling server-side validation and external errors: \n[Server Validation Example](./server-validation.md)\n\n## Conditional Rules Example\n\nApplying validation rules conditionally based on form state: \n[Conditional Rules Example](./conditional-rules.md)\n\n## Custom Rules Example\n\nDefine and use your own custom validation rules: \n[Custom Rules Example](./custom-rules.md)\n\n## Required Indicators Example\n\nDisplay required field indicators in your forms: \n[Required Indicators Example](./required-indicators.md)"
|
|
226
226
|
},
|
|
227
227
|
{
|
|
228
228
|
"id": "examples-required-indicators",
|
|
@@ -243,7 +243,7 @@ const rawData = {
|
|
|
243
243
|
"title": "Simple demo",
|
|
244
244
|
"category": "examples",
|
|
245
245
|
"path": "examples/simple.md",
|
|
246
|
-
"content": "# Simple demo\n\nYou can play with the code of this example in the stackblitz sandbox.\n\nDon't
|
|
246
|
+
"content": "# Simple demo\n\nYou can play with the code of this example in the stackblitz sandbox.\n\nDon't forget to install the `Vue` extension in the online IDE.\n\n<a target='_blank' href=\"https://stackblitz.com/~/github.com/victorgarciaesgi/regle-examples/tree/main/examples/simple-example?file=examples/simple-example/src/App.vue&configPath=examples/simple-example\">\n <img\n alt=\"Open in StackBlitz\"\n src=\"https://developer.stackblitz.com/img/open_in_stackblitz.svg\"\n />\n</a>\n\n<iframe style='width: 100%; height: 700px' src=\"https://stackblitz.com/github/victorgarciaesgi/regle-examples/tree/main/examples/simple-example?embed=1&file=src%2FApp.vue&theme=dark&view=preview\" title=\"Sandbox editor\" sandbox=\"allow-modals allow-forms allow-popups allow-scripts allow-same-origin\"></iframe>"
|
|
247
247
|
},
|
|
248
248
|
{
|
|
249
249
|
"id": "integrations-agent-skills",
|
|
@@ -257,7 +257,7 @@ const rawData = {
|
|
|
257
257
|
"title": "Regle MCP server",
|
|
258
258
|
"category": "integrations",
|
|
259
259
|
"path": "integrations/mcp-server.md",
|
|
260
|
-
"content": "# MCP Server\n\n[MCP (Model Context Protocol)](https://modelcontextprotocol.io/) is an open standard that enables AI assistants to interact with external tools and data sources. \n\nRegle offers an MCP server that can be used to get documentation and autocomplete in your favorite AI assistant editor. This allows your AI assistant to understand Regle's API and help you write validation rules more effectively.\n\nThe MCP server provides the following features:\n\n- Create form validation rules\n- Search documentation\n- Get precise information on any rule\n- Create custom rules\n- API information on every Regle helper\n\n## Cursor\n\n<a href=\"https://cursor.com/en-US/install-mcp?name=regle&config=eyJjb21tYW5kIjoibnB4IEByZWdsZS9tY3Atc2VydmVyIn0%3D\">\n <div class=\"light-only\">\n <img src=\"https://cursor.com/deeplink/mcp-install-dark.svg\" alt=\"Install MCP Server\" />\n </div>\n <div class=\"dark-only\">\n <img src=\"https://cursor.com/deeplink/mcp-install-light.svg\" alt=\"Install MCP Server\" />\n </div>\n</a>\n\nOr add to your `.cursor/mcp.json`\n```json\n{\n \"mcpServers\": {\n \"regle\": {\n \"command\": \"npx\",\n \"args\": [\"@regle/mcp-server\"]\n }\n }\n}\n```\n\n## Claude Code\n\nFor Claude Code, run the following command:\n\n```bash\nclaude mcp add-json regle --scope project '{\"command\":\"npx\",\"args\":[\"-y\",\"@regle/mcp-server\"]}'\n```"
|
|
260
|
+
"content": "# MCP Server\n\n[MCP (Model Context Protocol)](https://modelcontextprotocol.io/) is an open standard that enables AI assistants to interact with external tools and data sources. \n\nRegle offers an MCP server that can be used to get documentation and autocomplete in your favorite AI assistant editor. This allows your AI assistant to understand Regle's API and help you write validation rules more effectively.\n\nThe MCP server provides the following features:\n\n- Create form validation rules\n- Search documentation\n- Get precise information on any rule\n- Create custom rules\n- API information on every Regle helper\n\n## Cursor\n\n<a href=\"https://cursor.com/en-US/install-mcp?name=regle&config=eyJjb21tYW5kIjoibnB4IEByZWdsZS9tY3Atc2VydmVyIn0%3D\">\n <div class=\"light-only\">\n <img src=\"https://cursor.com/deeplink/mcp-install-dark.svg\" alt=\"Install MCP Server\" />\n </div>\n <div class=\"dark-only\">\n <img src=\"https://cursor.com/deeplink/mcp-install-light.svg\" alt=\"Install MCP Server\" />\n </div>\n</a>\n\nOr add to your `.cursor/mcp.json`\n```json\n{\n \"mcpServers\": {\n \"regle\": {\n \"command\": \"npx\",\n \"args\": [\"@regle/mcp-server\"]\n }\n }\n}\n```\n\n## Claude Code\n\nFor Claude Code, run the following command:\n\n```bash\nclaude mcp add-json regle --scope project '{\"command\":\"npx\",\"args\":[\"-y\",\"@regle/mcp-server\"]}'\n```\n\n## Claude Desktop\n\nFor Claude Desktop, add the following to your `claude_desktop_config.json`:\n\n```json\n{\n \"mcpServers\": {\n \"regle\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@regle/mcp-server\"]\n }\n }\n}\n```"
|
|
261
261
|
},
|
|
262
262
|
{
|
|
263
263
|
"id": "integrations-nuxt",
|
|
@@ -271,14 +271,14 @@ const rawData = {
|
|
|
271
271
|
"title": "Schemas libraries",
|
|
272
272
|
"category": "integrations",
|
|
273
273
|
"path": "integrations/schemas-libraries.md",
|
|
274
|
-
"content": "# Schemas libraries (Zod, Valibot, ...)\n\nRegle supports the [Standard Schema Spec](https://standardschema.dev/).\n\nThis means any Standard Schema compliant RPC library can be used with Regle.\n\nOfficial list of supported libraries:\n\n- Zod [docs](https://zod.dev/) <span data-title=\"zod\"></span> `3.24+`. \n- Valibot [docs](https://valibot.dev/) <span data-title=\"valibot\"></span> `1+`.\n- ArkType [docs](https://arktype.io/) <span data-title=\"arktype\"></span> `2+`\n- Any library following the [Standard Schema Spec](https://standardschema.dev/) \n\n::: code-group\n```sh [pnpm]\npnpm add @regle/schemas\n```\n\n```sh [npm]\nnpm install @regle/schemas\n```\n\n```sh [yarn]\nyarn add @regle/schemas\n```\n\n```sh [bun]\nbun add @regle/schemas\n```\n:::\n\n## Usage\n\nInstead of using the core `useRegle`, use `useRegleSchema` export from `@regle/schemas`.\n\n:::code-group\n```ts [Zod]\nimport { useRegleSchema } from '@regle/schemas';\nimport { z } from 'zod';\n\nconst { r$ } = useRegleSchema({ name: '' }, z.object({\n name: z.string().min(1)\n}))\n```\n\n```ts [Valibot]\nimport { useRegleSchema } from '@regle/schemas';\nimport * as v from 'valibot';\n\nconst { r$ } = useRegleSchema({ name: '' }, v.object({\n name: v.pipe(v.string(), v.minLength(3))\n}))\n```\n\n```ts [ArkType]\nimport { useRegleSchema } from '@regle/schemas';\nimport { type } from 'arktype';\n\nconst { r$ } = useRegleSchema({ name: '' }, type({\n name: \"string > 1\"\n}))\n```\n\n:::\n\n:::warning\nLimitations from the core behaviour\n\nUsing schema libraries uses a different mechanism than the core \"rules\" one. Regle will parse the entire tree instead of doing it per-field.
|
|
274
|
+
"content": "# Schemas libraries (Zod, Valibot, ...)\n\nRegle supports the [Standard Schema Spec](https://standardschema.dev/).\n\nThis means any Standard Schema compliant RPC library can be used with Regle.\n\nOfficial list of supported libraries:\n\n- Zod [docs](https://zod.dev/) <span data-title=\"zod\"></span> `3.24+`. \n- Valibot [docs](https://valibot.dev/) <span data-title=\"valibot\"></span> `1+`.\n- ArkType [docs](https://arktype.io/) <span data-title=\"arktype\"></span> `2+`\n- Any library following the [Standard Schema Spec](https://standardschema.dev/) \n\n::: code-group\n```sh [pnpm]\npnpm add @regle/schemas\n```\n\n```sh [npm]\nnpm install @regle/schemas\n```\n\n```sh [yarn]\nyarn add @regle/schemas\n```\n\n```sh [bun]\nbun add @regle/schemas\n```\n:::\n\n## Usage\n\nInstead of using the core `useRegle`, use `useRegleSchema` export from `@regle/schemas`.\n\n:::code-group\n```ts [Zod]\nimport { useRegleSchema } from '@regle/schemas';\nimport { z } from 'zod';\n\nconst { r$ } = useRegleSchema({ name: '' }, z.object({\n name: z.string().min(1)\n}))\n```\n\n```ts [Valibot]\nimport { useRegleSchema } from '@regle/schemas';\nimport * as v from 'valibot';\n\nconst { r$ } = useRegleSchema({ name: '' }, v.object({\n name: v.pipe(v.string(), v.minLength(3))\n}))\n```\n\n```ts [ArkType]\nimport { useRegleSchema } from '@regle/schemas';\nimport { type } from 'arktype';\n\nconst { r$ } = useRegleSchema({ name: '' }, type({\n name: \"string > 1\"\n}))\n```\n\n:::\n\n:::warning\nLimitations from the core behaviour\n\nUsing schema libraries uses a different mechanism than the core \"rules\" one. Regle will parse the entire tree instead of doing it per-field. That means that properties or methods are not available in nested values:\n\n- `$validate` (only at root)\n- `$pending` (only at root)\n\nOne other limitation is you won't have access to any children `$rules`, so checking if a field is required with `xx.$rules.required.active` is not possible with schemas.\n:::\n\n## Computed schema\n\nYou can also have a computed schema that can be based on other state values.\n\n:::warning\nWhen doing refinements or transform, Vue can't track what the schema depends on because you're in a function callback. \n\nSame way as `withParams` from `@regle/rules`, you can use the `withDeps` helper to force dependencies on any schema\n:::\n\n:::code-group\n\n```ts [Zod]\nimport { useRegleSchema, inferSchema, withDeps } from '@regle/schemas';\nimport { z } from 'zod';\nimport { ref, computed } from 'vue';\n\ntype Form = {\n firstName?: string;\n lastName?: string\n}\n\nconst form = ref<Form>({ firstName: '', lastName: '' })\n\nconst schema = computed(() =>\n inferSchema(form, z.object({\n firstName: z.string(),\n /** \n * Important to keep track of the dependency change\n * Without it, the validator wouldn't run if `firstName` changed\n */\n lastName: withDeps(\n z.string().refine((v) => v !== form.value.firstName, {\n message: \"Last name can't be equal to first name\",\n }),\n [() => form.value.firstName]\n ),\n }))\n);\n\nconst { r$ } = useRegleSchema(form, schema);\n\n```\n```ts [Valibot]\nimport { useRegleSchema, inferSchema, withDeps} from '@regle/schemas';\nimport * as v from 'valibot';\nimport { ref, computed } from 'vue';\n\ntype Form = {\n firstName?: string;\n lastName?: string\n}\n\nconst form = ref<Form>({ firstName: '', lastName: '' })\n\nconst schema = computed(() => \n inferSchema(form, v.object({\n firstName: v.string(),\n /** \n * Important to keep track of the dependency change\n * Without it, the validator wouldn't run if `firstName` changed\n */\n lastName: withDeps(\n v.pipe(\n v.string(),\n v.check((v) => v !== form.value.firstName, \"Last name can't be equal to first name\")\n ),\n [() => form.value.firstName]\n ),\n }))\n)\n\nconst { r$ } = useRegleSchema(form, schema);\n\n```\n\n:::\n\n## `syncState`\n\nBy default, Regle doesn't allow any transforms on the state. \n\nModifiers like `default`, `catch` or `transform` will not impact the validation.\n\nIf you want to allow the schema to update your form state you can use the `syncState` option. \nThe state will only be patched is the parse is successful.\n\n```ts\ntype RegleSchemaBehaviourOptions = {\n syncState?: {\n /**\n * Applies every transform on every update to the state\n */\n onUpdate?: boolean;\n /**\n * Applies every transform only when calling `$validate`\n */\n onValidate?: boolean;\n };\n};\n```\n\nUsage:\n\n```vue\n\n```\n\n## Type safe output\n\nSimilar to the main `useRegle` composable, `r$.$validate` also returns a type-safe output using Zod type schema parser.\n\n:::code-group\n```ts [Zod]\nimport { useRegleSchema, inferSchema } from '@regle/schemas';\nimport { z } from 'zod';\nimport { ref, computed } from 'vue';\n\ntype Form = {\n firstName?: string;\n lastName?: string\n}\n\nconst form = ref<Form>({ firstName: '', lastName: '' })\n\nconst schema = computed(() => inferSchema(form, z.object({\n firstName: z.string().optional(),\n lastName: z.string().min(1).refine(v => v !== form.value.firstName, {\n message: \"Last name can't be equal to first name\"\n }),\n})))\n\nconst { r$ } = useRegleSchema(form, schema);\n\nasync function submit() {\n const { valid, data } = await r$.$validate();\n if (valid) {\n console.log(data);\n }\n}\n\n```\n\n```ts [Valibot]\nimport { useRegleSchema, inferSchema } from '@regle/schemas';\nimport * as v from 'valibot';\nimport { ref, computed } from 'vue';\n\ntype Form = {\n firstName?: string;\n lastName?: string\n}\n\nconst form = ref<Form>({ firstName: '', lastName: '' })\n\nconst schema = computed(() => {\n return inferSchema(form, v.object({\n firstName: v.optional(v.string()),\n lastName: v.pipe(\n v.string(),\n v.minLength(3),\n v.check((v) => v !== form.value.firstName, \"Last name can't be equal to first name\")\n )\n }))\n})\n\nconst { r$ } = useRegleSchema(form, schema);\n\nasync function submit() {\n const { valid, data } = await r$.$validate();\n if (valid) {\n console.log(data);\n }\n}\n\n```\n\n```ts [ArkType]\nimport { useRegleSchema, inferSchema } from '@regle/schemas';\nimport { type } from 'arktype';\nimport { ref, computed } from 'vue';\n\ntype Form = {\n firstName?: string;\n lastName?: string\n}\n\nconst form = ref<Form>({ firstName: '', lastName: '' })\n\nconst schema = computed(() => {\n return inferSchema(form, type({\n 'firstName?': 'string',\n lastName: 'string > 3',\n }).narrow((data, ctx) => {\n if (data.firstName !== data.lastName) {\n return true;\n }\n return ctx.reject({\n expected: 'different than firstName',\n path: ['lastName'],\n });\n }))\n})\n\nconst { r$ } = useRegleSchema(form, schema);\n\nasync function submit() {\n const { valid, data } = await r$.$validate();\n if (valid) {\n console.log(data);\n }\n}\n```\n:::"
|
|
275
275
|
},
|
|
276
276
|
{
|
|
277
277
|
"id": "introduction-comparisons",
|
|
278
278
|
"title": "Comparison with other form libraries",
|
|
279
279
|
"category": "introduction",
|
|
280
280
|
"path": "introduction/comparisons.md",
|
|
281
|
-
"content": "# Comparison with other form libraries\n\n## Vuelidate\n\nRegle is successor of Vuelidate. As a long-time user of Vuelidate, I was inspired to create Regle after the project was discontinued.\n\nBoth libraries share a similar API and developer experience (DX), including:\n- Data-based validation\n- Unified reactivity\n- Simple declaration\n\nRegle builds upon these features and adds several improvements:\n- 100% type safety\n- Autocomplete\n- Zod/Valibot support (with more integrations planned)\n- Global config\n- Improved API in some areas, such as rules declaration, `$each`, `validationGroups`, `$validate`\n\n## VeeValidate\n\nRegle is a good VeeValidate alternative.\n\nVeeValidate is primarily focused on being component-centric. It now also offers Composition API helpers.\n\nIts API is less declarative compared to Regle, making it challenging to handle large forms or manage form state within a Pinia store.\n\nWhile VeeValidate supports typed schemas using libraries like Zod, Yup, or Valibot, this comes at the cost of losing some of VeeValidate's native features. In contrast, when using Zod with Regle, you retain all the features available in the default @regle/rules, ensuring a consistent developer experience.\n\n## Tanstack Forms\n\nI love Tanstack products and what
|
|
281
|
+
"content": "# Comparison with other form libraries\n\n## Vuelidate\n\nRegle is successor of Vuelidate. As a long-time user of Vuelidate, I was inspired to create Regle after the project was discontinued.\n\nBoth libraries share a similar API and developer experience (DX), including:\n- Data-based validation\n- Unified reactivity\n- Simple declaration\n\nRegle builds upon these features and adds several improvements:\n- 100% type safety\n- Autocomplete\n- Zod/Valibot support (with more integrations planned)\n- Global config\n- Improved API in some areas, such as rules declaration, `$each`, `validationGroups`, `$validate`\n\n## VeeValidate\n\nRegle is a good VeeValidate alternative.\n\nVeeValidate is primarily focused on being component-centric. It now also offers Composition API helpers.\n\nIts API is less declarative compared to Regle, making it challenging to handle large forms or manage form state within a Pinia store.\n\nWhile VeeValidate supports typed schemas using libraries like Zod, Yup, or Valibot, this comes at the cost of losing some of VeeValidate's native features. In contrast, when using Zod with Regle, you retain all the features available in the default @regle/rules, ensuring a consistent developer experience.\n\n## Tanstack Forms\n\nI love Tanstack products and what they're doing is so great for the JS community, especially making their tools framework agnostic.\n\nAs for Tanstack Forms, I feel the API for Vue keeps too much syntax logic from the React counterpart. \nIt doesn't take advantage of the Vue composition API enough.\n\nTanstack forms also relies on DOM components, Regle doesn't.\n\nRegle is a more lightweight and less boilerplate alternative to Tanstack Forms.\n\nYou can compare the [Regle playground](https://play.reglejs.dev) and the [Tanstack Forms Vue playground](https://tanstack.com/form/latest/docs/framework/vue/examples/simple?panel=code) to see that Regle is much more readable and uses way less code to do the same thing.\n\n## Formkit & VueForms\n\nFormkit and VueForms are centered around DOM components.\nRegle is headless and data-driven, so you can work with your state anywhere you want.\n\nWorking exclusively with a data-driven model enables stronger type safety and a better developer experience.\n\nRegle is an alternative to Formkit and VueForms if you don't want the UI and validation to be tied.\n\n## Formwerk\n\nFrom Formwerk website: `[Formwerk] is ideal for those building internal UI design systems or UI libraries intended for other developers.`.\nThe focus is not on validation, but on building a scalable UI around the form fields, so it differs completely in usage.\nFormwerk also offers the same feature to validate forms using Standard Schema Spec (Zod, Valibot, Arktype)"
|
|
282
282
|
},
|
|
283
283
|
{
|
|
284
284
|
"id": "introduction-devtools",
|
|
@@ -292,7 +292,7 @@ const rawData = {
|
|
|
292
292
|
"title": "Introduction",
|
|
293
293
|
"category": "introduction",
|
|
294
294
|
"path": "introduction/index.md",
|
|
295
|
-
"content": "# Introduction\n\n## What is Regle?\n\nIf you've ever built
|
|
295
|
+
"content": "# Introduction\n\n## What is Regle?\n\nIf you've ever built forms and wrote repetitive validation logic, struggling with complex error states, or losing type safety along the way, Regle is the perfect solution.\n\nRegle is a type-safe, headless form validation library that lets you write validation rules that mirror your data structure. Think of it as the perfect evolution of Vuelidate, but with modern TypeScript support and a more intuitive API.\n\n## Why Choose Regle?\n\n- **🔒 Type Safe**: Full TypeScript inference means autocomplete everywhere and catch errors at compile time\n- **🌳 Model-Based**: Your validation tree matches your data model—no mental gymnastics required \n- **🔌 Headless**: Works with any UI framework, CSS library, or design system\n- **🔍 Devtools**: Built-in Vue devtools extension for easy debugging and testing.\n- **📦 Modular**: Use built-in rules or create custom ones that fit your exact needs\n- **⚡ Performance**: Efficient reactivity system that only updates what changed\n- **🛠 Developer Experience**: If you've used Vuelidate, you'll feel right at home\n\n## Basic example\n\nHere's a real form that you can copy and use right away:\n\nFrom `r$`, you can build any UI you want. The validation logic is completely separate from your presentation layer.\n\n**Live Result:**\n\n## What's Next?\n\nReady to dive deeper? Here's your learning path:\n\n1. **[Installation](/introduction/installation)** - Get Regle set up in your project\n2. **[Core Concepts](/core-concepts/)** - Understand how `useRegle` works\n3. **[Built-in Rules](/core-concepts/rules/built-in-rules)** - Explore all available validation rules\n4. **[Examples](/examples/simple)** - See Regle in action with real-world scenarios\n\n:::tip Coming from Vuelidate?\nRegle's API is intentionally similar to Vuelidate's. Check out our [comparison guide](/introduction/comparisons#vuelidate) to see what's changed and what's stayed the same.\n:::"
|
|
296
296
|
},
|
|
297
297
|
{
|
|
298
298
|
"id": "introduction-installation",
|
|
@@ -306,14 +306,14 @@ const rawData = {
|
|
|
306
306
|
"title": "Migrate from Vuelidate",
|
|
307
307
|
"category": "introduction",
|
|
308
308
|
"path": "introduction/migrate-from-vuelidate.md",
|
|
309
|
-
"content": "# Migrate from Vuelidate\n\nMigrating from Vuelidate is really simple. Regle API is similar to Vuelidate's one on purpose, so the mental model stays the same.\n\nRegle type safety will ensure you make no mistakes while making the migration.\n\n## Imports\n\n```ts\nimport { useVuelidate } from '@vuelidate/core'; // [!code --]\nimport { required } from '@vuelidate/validators'; // [!code --]\nimport { useRegle } from '@regle/core'; // [!code ++]\nimport { required } from '@regle/rules'; // [!code ++]\n```\n\n```ts\nconst v$ = useVuelidate(rules, state, options); // [!code --]\nconst { r$ } = useRegle(state, rules, options); // [!code ++]\n```\n\n## Helpers\n\n```ts\nimport { helpers } from '@vuelidate/validators'; // [!code --]\nimport { withMessage, withParams, withAsync, isEmpty, ... } from '@regle/rules'; // [!code ++]\n```\n\nHelpers which have been renamed:\n\n- `req` -> `isFilled`\n- `len` -> `getSize`\n- `regex` -> `matchRegex`\n- `forEach` -> Deleted, you can use `$each` directly.\n- `unwrap` -> use `toValue` from [Vue](https://vuejs.org/api/reactivity-utilities#tovalue)\n - Parameters are automatically unwrapped when using `createRule`\n\n## Displaying errors\n\nVuelidate:\n```vue\n<template> \n <p \n v-for=\"error of v$.name.$errors\"\n :key=\"error.$uid\" \n >\n {{error.$message}}\n </p>\n</template>\n```\n\nRegle: \n```vue\n<template>\n <p\n v-for=\"(error, index) of r$.$errors.name\"\n :key=\"index\"\n >\n {{ error }} \n </p>\n</template>\n```\n\n### `withMessage`\n\nOrder of parameters are swapped\n\n```ts\nconst rule = helpers.withMessage('This field cannot be empty', required) // [!code --]\nconst rule = withMessage(required, 'This field cannot be empty') // [!code ++]\n```\n\n### `withParams`\n\nYou can create rules with parameters with [createRule](/core-concepts/rules/reusable-rules#createrule) helper\n\n```ts\nconst contains = (param) => // [!code --]\n helpers.withParams( // [!code --]\n { type: 'contains', value: param }, // [!code --]\n (value) => !helpers.req(value) || value.includes(param) // [!code --]\n ) // [!code --]\n\nconst contains = createRule({ // [!code ++]\n validator(value: Maybe<string>, param: Maybe<string>) { // [!code ++]\n return isEmpty(value) || value.includes(param); // [!code ++]\n }, // [!code ++]\n message: ({$params: [param]}) => `Value must contain ${param}
|
|
309
|
+
"content": "# Migrate from Vuelidate\n\nMigrating from Vuelidate is really simple. Regle API is similar to Vuelidate's one on purpose, so the mental model stays the same.\n\nRegle type safety will ensure you make no mistakes while making the migration.\n\n## Imports\n\n```ts\nimport { useVuelidate } from '@vuelidate/core'; // [!code --]\nimport { required } from '@vuelidate/validators'; // [!code --]\nimport { useRegle } from '@regle/core'; // [!code ++]\nimport { required } from '@regle/rules'; // [!code ++]\n```\n\n```ts\nconst v$ = useVuelidate(rules, state, options); // [!code --]\nconst { r$ } = useRegle(state, rules, options); // [!code ++]\n```\n\n## Helpers\n\n```ts\nimport { helpers } from '@vuelidate/validators'; // [!code --]\nimport { withMessage, withParams, withAsync, isEmpty, ... } from '@regle/rules'; // [!code ++]\n```\n\nHelpers which have been renamed:\n\n- `req` -> `isFilled`\n- `len` -> `getSize`\n- `regex` -> `matchRegex`\n- `forEach` -> Deleted, you can use `$each` directly.\n- `unwrap` -> use `toValue` from [Vue](https://vuejs.org/api/reactivity-utilities#tovalue)\n - Parameters are automatically unwrapped when using `createRule`\n\n## Displaying errors\n\nVuelidate:\n```vue\n<template> \n <p \n v-for=\"error of v$.name.$errors\"\n :key=\"error.$uid\" \n >\n {{error.$message}}\n </p>\n</template>\n```\n\nRegle: \n```vue\n<template>\n <p\n v-for=\"(error, index) of r$.$errors.name\"\n :key=\"index\"\n >\n {{ error }} \n </p>\n</template>\n```\n\n### `withMessage`\n\nOrder of parameters are swapped\n\n```ts\nconst rule = helpers.withMessage('This field cannot be empty', required) // [!code --]\nconst rule = withMessage(required, 'This field cannot be empty') // [!code ++]\n```\n\n### `withParams`\n\nYou can create rules with parameters with [createRule](/core-concepts/rules/reusable-rules#createrule) helper\n\n```ts\nconst contains = (param) => // [!code --]\n helpers.withParams( // [!code --]\n { type: 'contains', value: param }, // [!code --]\n (value) => !helpers.req(value) || value.includes(param) // [!code --]\n ) // [!code --]\n\nconst contains = createRule({ // [!code ++]\n validator(value: Maybe<string>, param: Maybe<string>) { // [!code ++]\n return isEmpty(value) || value.includes(param); // [!code ++]\n }, // [!code ++]\n message: ({$params: [param]}) => `Value must contain ${param}`, // [!code ++]\n}) // [!code ++]\n```\n\n## Properties\n\nSome properties have been renamed\n\n- `$model` -> `$value`\n- `$response` -> `$metadata` [Using metadata from rules](/advanced-usage/rule-metadata#using-metadata-from-rules)\n- `$externalResults` -> `$externalErrors`\n\n### Accessing nested fields\n\n```ts\nv$.nested.child.$error // [!code --]\nr$.nested.child.$error // [!code ++]\n```\n\n## Collections\n\nSee [docs for validating arrays](/common-usage/collections)\n\n```ts\nconst v$ = useVuelidate({ // [!code --]\n collection: { // [!code --]\n $each: helpers.forEach({ // [!code --]\n name: { // [!code --]\n required // [!code --]\n } // [!code --]\n }) // [!code --]\n } // [!code --]\n}, {collection: [{name: ''}]}) // [!code --]\nconst { r$ } = useRegle({ collection: [{name: ''}]}, { // [!code ++]\n collection: {// [!code ++]\n $each: {// [!code ++]\n name: {// [!code ++]\n required// [!code ++]\n }// [!code ++]\n }// [!code ++]\n }// [!code ++]\n})// [!code ++]\n```\n\n## Methods\n\nSee [docs for type safe output](/typescript/type-safe-output)\n\n```ts\nconst result = await v$.$validate(); // [!code --]\nconst { valid, data } = await r$.$validate(); // [!code ++]\n```\n\n## Custom messages\n\nIf you used to declare this kind of helper methods with Vuelidate:\n\n```ts\nimport {helpers, required, numeric, minLength} from '@vuelidate/validators';\n\nexport const requiredValidator = helpers.withMessage(\n 'This field is required.',\n required\n);\nexport const numericValidator = helpers.withMessage(\n 'Please enter a valid value.',\n numeric\n);\n\nexport const minLengthValidator = (value) =>\n helpers.withMessage(\n ({ $model, $params }) =>\n `Please enter a value greater than or equal to ${$params.max}.`,\n minLength(value)\n );\n```\n\nYou can remove it and configure it with [global config](/advanced-usage/global-config#replace-built-in-rules-messages).\n\n:::tip\nIf you use Nuxt <span data-title=\"nuxt\"></span>, check the [Nuxt module documentation](/integrations/nuxt) for even easier error message sharing.\n:::\n\n```ts\nimport { defineRegleConfig } from '@regle/core';\nimport { withMessage, minLength, required, numeric } from '@regle/rules';\n\nconst { useRegle: useCustomRegle } = defineRegleConfig({\n rules: () => ({\n required: withMessage(required, 'This field is required.'),\n numeric: withMessage(numeric, 'Please enter a valid value.'),\n minLength: withMessage(minLength, ({ $value, $params: [max] }) => {\n return `Minimum length is ${max}. Current length: ${$value?.length}`;\n })\n })\n})\n\nconst { r$ } = useCustomRegle({ name: '' }, {\n name: {\n required,\n numeric,\n minLength: minLength(6)\n }\n})\n```\n\n## Nested component validation\n\n__**Nested component**__ validation is replaced by __**Scoped validation**__.\n\nSee [docs for scoped validation](/advanced-usage/scoped-validation) for more details\n\n```ts\n// [scoped-config.ts]\nimport { useScopedRegle, useCollectScope, useRegle } from '@regle/core'; // [!code ++]\n\n// Parent.vue\nconst v$ = useVuelidate(); // [!code --]\nconst v$ = useVuelidate({}, {}, {$scope: 'foo'}); // [!code --]\n\nconst { r$ } = useCollectScope(); // [!code ++]\nconst { r$ } = useCollectScope('foo'); // [!code ++]\n\n// Child.vue\n\nconst v$ = useVuelidate(validations, state); // [!code --]\nconst v$ = useVuelidate(validations, state, { $scope: false }); // [!code --]\nconst v$ = useVuelidate(validations, state, { $scope: 'foo' }); // [!code --]\nconst v$ = useVuelidate(validations, state, { $stopPropagation: true }); // [!code --]\n\nconst { r$ } = useScopedRegle(state, validations); // [!code ++]\nconst { r$ } = useRegle(state, validations); // [!code ++]\nconst { r$ } = useScopedRegle(state, validations, {namespace: 'foo'}); // [!code ++]\nconst { r$ } = useScopedRegle(state, validations); // [!code ++]\n```\n\n## Validation groups\n\n```ts\nconst rules = { // [!code --]\n number: { isEven },// [!code --]\n nested: {// [!code --]\n word: { required: v => !!v }// [!code --]\n },// [!code --]\n $validationGroups: {// [!code --]\n firstGroup: ['number', 'nested.word']// [!code --]\n }// [!code --]\n}// [!code --]\nconst v$ = useVuelidate(rules, ...);// [!code --]\n\nconst { r$ } = useRegle(..., { // [!code ++]\n number: {isEven},// [!code ++]\n nested: {// [!code ++]\n word: { required: v => !!v }// [!code ++]\n }// [!code ++]\n}, {// [!code ++]\n validationGroups: (fields) => ({// [!code ++]\n firstGroup: [fields.number, fields.nested.word]// [!code ++]\n })// [!code ++]\n})// [!code ++]\nr$.$groups.firstGroup// [!code ++]\n```"
|
|
310
310
|
},
|
|
311
311
|
{
|
|
312
312
|
"id": "troubleshooting-reactivity",
|
|
313
313
|
"title": "Reactivity caveats",
|
|
314
314
|
"category": "troubleshooting",
|
|
315
315
|
"path": "troubleshooting/reactivity.md",
|
|
316
|
-
"content": "# Reactivity caveats\n\n## Tracking Dependencies\n\nWhen using `useRegle` with a getter function or a computed property, Regle automatically tracks dependencies. However, sometimes dependencies cannot be tracked automatically. In such cases, you can either use the `withParams` wrapper to manually define dependencies or use the `createRule` function which automatically tracks dependencies for you.\n\nTo illustrate the issue, consider the following example:\n\n```ts\nimport { ref, computed } from 'vue';\nimport { withMessage } from '@regle/rules';\nimport { type Maybe, type RegleComputedRules } from '@regle/core';\n\nconst condition = ref(false)\n\nconst weight = (greeting: string) => {\n return withMessage((value: Maybe<number>) => {\n return !!value && value > 1 && condition.value === true\n }, `Weight must be greater than 1, ${greeting}`)\n}\n\nconst rules = computed(() => {\n return {\n items: {\n $each: (item) => ({\n weight: {\n weight: weight('Hello World')\n }\n })\n }\n } satisfies RegleComputedRules<typeof form>\n})\n```\n\nIn the above example, the `weight` rule depends on the `condition` ref, which is not tracked by Regle because it is inside a function and Vue cannot collect the reference. To fix this, you can either use the `withParams` wrapper or use the `createRule` function which automatically tracks dependencies for you.\n\n```ts\nimport { ref } from 'vue';\nimport { withParams, withMessage } from '@regle/rules';\nimport { createRule, type Maybe } from '@regle/core';\n\nconst condition = ref(false)\n\n// Usage with `withParams`\nconst weight1 = (greeting: string) => {\n return withMessage(\n withParams((value: Maybe<number>) => {\n return !!value && value > 1 && condition.value === true\n }, [condition]),\n `Weight must be greater than 1, ${greeting}`\n )\n}\n\n// Usage with `createRule`\nconst weight2 = createRule({\n validator(value: Maybe<number>, greeting: string, condition: boolean) {\n return !!value && value > 1 && condition === true\n },\n\n message: ({ $params: [greeting] }) => {\n return `Weight must be greater than 1, ${greeting}`\n }\n})\n```\n\nNow the `condition` ref is tracked by Regle and the rule will be re-evaluated whenever the `condition` ref changes.\n\n## Pinia hydration issues\n\nIf you use `store.$dispose()` or Nuxt in SSR mode, you may encounter this error:\n\n```\nUncaught TypeError: 'set' on proxy: trap returned falsish for property 'xxx'\n```\n\nThis is because Pinia tries to hydrate the stateful property `r$`.\nTo avoid this, you can use [skipHydrate](https://pinia.vuejs.org/api/pinia/functions/skipHydrate.html#skipHydrate-)\n\n```ts [pinia.store.ts]\nimport { skipHydrate } from 'pinia';\n\nexport const usePiniaStore = defineStore('pinia-store', () => {\n const {r$} = useRegle(/** */)\n\n return { r$: skipHydrate(r$) };\n});\n```\n\n:::info\nIf you are using Nuxt, you can use the `@regle/nuxt` module that will automatically skip the hydration of the `r$` property.\n:::"
|
|
316
|
+
"content": "# Reactivity caveats\n\n## Tracking Dependencies\n\nWhen using `useRegle` with a getter function or a computed property, Regle automatically tracks dependencies. However, sometimes dependencies cannot be tracked automatically. In such cases, you can either use the `withParams` wrapper to manually define dependencies or use the `createRule` function which automatically tracks dependencies for you.\n\nTo illustrate the issue, consider the following example:\n\n```ts\nimport { ref, computed } from 'vue';\nimport { withMessage } from '@regle/rules';\nimport { useRegle, type Maybe, type RegleComputedRules } from '@regle/core';\n\nconst form = ref({ items: [{ weight: 0 }] });\nconst condition = ref(false)\n\nconst weight = (greeting: string) => {\n return withMessage((value: Maybe<number>) => {\n return !!value && value > 1 && condition.value === true\n }, `Weight must be greater than 1, ${greeting}`)\n}\n\nconst rules = computed(() => {\n return {\n items: {\n $each: (item) => ({\n weight: {\n weight: weight('Hello World')\n }\n })\n }\n } satisfies RegleComputedRules<typeof form>\n})\n```\n\nIn the above example, the `weight` rule depends on the `condition` ref, which is not tracked by Regle because it is inside a function and Vue cannot collect the reference. To fix this, you can either use the `withParams` wrapper or use the `createRule` function which automatically tracks dependencies for you.\n\n```ts\nimport { ref } from 'vue';\nimport { withParams, withMessage } from '@regle/rules';\nimport { createRule, type Maybe } from '@regle/core';\n\nconst condition = ref(false)\n\n// Usage with `withParams`\nconst weight1 = (greeting: string) => {\n return withMessage(\n withParams((value: Maybe<number>) => {\n return !!value && value > 1 && condition.value === true\n }, [condition]),\n `Weight must be greater than 1, ${greeting}`\n )\n}\n\n// Usage with `createRule`\nconst weight2 = createRule({\n validator(value: Maybe<number>, greeting: string, condition: boolean) {\n return !!value && value > 1 && condition === true\n },\n\n message: ({ $params: [greeting] }) => {\n return `Weight must be greater than 1, ${greeting}`\n }\n})\n```\n\nNow the `condition` ref is tracked by Regle and the rule will be re-evaluated whenever the `condition` ref changes.\n\n## Pinia hydration issues\n\nIf you use `store.$dispose()` or Nuxt in SSR mode, you may encounter this error:\n\n```\nUncaught TypeError: 'set' on proxy: trap returned falsish for property 'xxx'\n```\n\nThis is because Pinia tries to hydrate the stateful property `r$`.\nTo avoid this, you can use [skipHydrate](https://pinia.vuejs.org/api/pinia/functions/skipHydrate.html#skipHydrate-)\n\n```ts [pinia.store.ts]\nimport { skipHydrate } from 'pinia';\n\nexport const usePiniaStore = defineStore('pinia-store', () => {\n const {r$} = useRegle(/** */)\n\n return { r$: skipHydrate(r$) };\n});\n```\n\n:::info\nIf you are using Nuxt, you can use the `@regle/nuxt` module that will automatically skip the hydration of the `r$` property.\n:::"
|
|
317
317
|
},
|
|
318
318
|
{
|
|
319
319
|
"id": "typescript-type-safe-output",
|
|
@@ -359,7 +359,7 @@ const rawData = {
|
|
|
359
359
|
"description": "Create a scoped validation system for collecting and validating multiple form instances.\nUseful for dynamic forms, multi-step wizards, or component-based form architectures.",
|
|
360
360
|
"parameters": [{
|
|
361
361
|
"name": "options",
|
|
362
|
-
"type": "CreateScopedUseRegleOptions<TCustomRegle, TAsRecord>",
|
|
362
|
+
"type": "CreateScopedUseRegleOptions<TCustomRegle, TAsRecord> | undefined",
|
|
363
363
|
"description": "- Configuration options",
|
|
364
364
|
"optional": true
|
|
365
365
|
}],
|
|
@@ -515,12 +515,12 @@ const rawData = {
|
|
|
515
515
|
"description": "Type helper to provide autocomplete and type-checking for your form rules.\nIt returns the rules without any processing - useful with computed rules.",
|
|
516
516
|
"parameters": [{
|
|
517
517
|
"name": "state",
|
|
518
|
-
"type": "TState | DeepReactiveState<TState>",
|
|
518
|
+
"type": "Maybe<TState> | DeepReactiveState<TState>",
|
|
519
519
|
"description": "- The state reference",
|
|
520
520
|
"optional": false
|
|
521
521
|
}, {
|
|
522
522
|
"name": "rulesFactory",
|
|
523
|
-
"type": "Unwrap<TState> extends PrimitiveTypes ? TDecl : Unwrap<TState> extends Record<string, any> ? TRules : {}",
|
|
523
|
+
"type": "Unwrap<TState> extends MaybeInput<PrimitiveTypes> ? TDecl : Unwrap<TState> extends Record<string, any> ? TRules : {}",
|
|
524
524
|
"description": "",
|
|
525
525
|
"optional": false
|
|
526
526
|
}],
|
|
@@ -576,7 +576,7 @@ const rawData = {
|
|
|
576
576
|
"optional": false
|
|
577
577
|
}, {
|
|
578
578
|
"name": "_scoped",
|
|
579
|
-
"type": "TScoped",
|
|
579
|
+
"type": "TScoped | undefined",
|
|
580
580
|
"description": "- Internal flag for scoped validation (default: false)",
|
|
581
581
|
"optional": true
|
|
582
582
|
}],
|
|
@@ -591,7 +591,7 @@ const rawData = {
|
|
|
591
591
|
"parameters": [
|
|
592
592
|
{
|
|
593
593
|
"name": "root",
|
|
594
|
-
"type": "TRoot",
|
|
594
|
+
"type": "TRoot | undefined",
|
|
595
595
|
"description": "- The Regle status object",
|
|
596
596
|
"optional": false
|
|
597
597
|
},
|
|
@@ -660,7 +660,7 @@ const rawData = {
|
|
|
660
660
|
"description": "Composable to collect and merge all Regle instances created with the default `useScopedRegle` within the same scope.\nReturns a merged `r$` object allowing validation across multiple components simultaneously.\n\nChildren properties like `$value` and `$errors` are converted to arrays instead of objects.\nYou have access to all validation properties like `$error`, `$invalid`, `$validate()`, etc.",
|
|
661
661
|
"parameters": [{
|
|
662
662
|
"name": "namespace",
|
|
663
|
-
"type": "MaybeRefOrGetter<string | string[]>",
|
|
663
|
+
"type": "MaybeRefOrGetter<string | string[]> | undefined",
|
|
664
664
|
"description": "- Optional namespace or array of namespaces to filter which scoped instances to collect",
|
|
665
665
|
"optional": true
|
|
666
666
|
}],
|
|
@@ -674,7 +674,7 @@ const rawData = {
|
|
|
674
674
|
"description": "`useRegle` serves as the foundation for validation logic.\nIt transforms your data and validation rules into a powerful, reactive validation system.",
|
|
675
675
|
"parameters": [{
|
|
676
676
|
"name": "params",
|
|
677
|
-
"type": "[state: TState | DeepReactiveState<TState>, rulesFactory: Unwrap<TState> extends PrimitiveTypes ? MaybeRefOrGetter
|
|
677
|
+
"type": "[state: Maybe<TState> | DeepReactiveState<TState>, rulesFactory: Unwrap<TState> extends MaybeInput<PrimitiveTypes> ? MaybeRefOrGetter<...> : Unwrap<...> extends Record<...> ? MaybeComputedOrGetter<......",
|
|
678
678
|
"description": "",
|
|
679
679
|
"optional": false
|
|
680
680
|
}],
|
|
@@ -687,7 +687,7 @@ const rawData = {
|
|
|
687
687
|
"kind": "function",
|
|
688
688
|
"description": "",
|
|
689
689
|
"parameters": [],
|
|
690
|
-
"returnType": "Ref<$InternalRegleStatusType, $InternalRegleStatusType>",
|
|
690
|
+
"returnType": "Ref<$InternalRegleStatusType | undefined, $InternalRegleStatusType | undefined>",
|
|
691
691
|
"example": "",
|
|
692
692
|
"tags": { "internal": "This is the internal function that creates the root storage for the Regle instance.\nThis allows shared logic between all `useRegle` like composables" }
|
|
693
693
|
},
|
|
@@ -702,7 +702,7 @@ const rawData = {
|
|
|
702
702
|
"optional": false
|
|
703
703
|
}, {
|
|
704
704
|
"name": "options",
|
|
705
|
-
"type": "useRulesFnOptions<TRules, TValidationGroups, TState>",
|
|
705
|
+
"type": "useRulesFnOptions<TRules, TValidationGroups, TState> | undefined",
|
|
706
706
|
"description": "",
|
|
707
707
|
"optional": true
|
|
708
708
|
}],
|
|
@@ -712,11 +712,11 @@ const rawData = {
|
|
|
712
712
|
},
|
|
713
713
|
{
|
|
714
714
|
"name": "useScopedRegle",
|
|
715
|
-
"kind": "
|
|
715
|
+
"kind": "const",
|
|
716
716
|
"description": "Clone of `useRegle` that automatically registers its instance for collection by `useCollectScope`.\nEvery time it's called, a new instance is added for the parent scope to collect.\n\nCan be called multiple times anywhere in your app - not restricted to components or DOM.\nWhen the component is unmounted or scope is disposed, the instance is automatically unregistered.",
|
|
717
717
|
"parameters": [{
|
|
718
718
|
"name": "params",
|
|
719
|
-
"type": "[state: TState | DeepReactiveState<TState>, rulesFactory: Unwrap<TState> extends PrimitiveTypes ? MaybeRefOrGetter
|
|
719
|
+
"type": "[state: Maybe<TState> | DeepReactiveState<TState>, rulesFactory: Unwrap<TState> extends MaybeInput<PrimitiveTypes> ? MaybeRefOrGetter<...> : Unwrap<...> extends Record<...> ? MaybeComputedOrGetter<......",
|
|
720
720
|
"description": "",
|
|
721
721
|
"optional": false
|
|
722
722
|
}],
|
|
@@ -766,11 +766,11 @@ const rawData = {
|
|
|
766
766
|
"description": "Allows only alphabetic characters.",
|
|
767
767
|
"parameters": [{
|
|
768
768
|
"name": "params",
|
|
769
|
-
"type": "[options?: MaybeRefOrGetter<CommonAlphaOptions
|
|
769
|
+
"type": "[options?: MaybeRefOrGetter<Maybe<CommonAlphaOptions | undefined>>]",
|
|
770
770
|
"description": "",
|
|
771
771
|
"optional": false
|
|
772
772
|
}],
|
|
773
|
-
"returnType": "RegleRuleDefinition<\"alpha\", string, [options?: CommonAlphaOptions], false, boolean, string
|
|
773
|
+
"returnType": "RegleRuleDefinition<\"alpha\", string, [options?: CommonAlphaOptions | undefined], false, boolean, MaybeInput<string>, string, false>",
|
|
774
774
|
"example": "import { alpha } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n alpha,\n // or with symbols allowed\n alpha: alpha({ allowSymbols: true }),\n },\n})",
|
|
775
775
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#alpha Documentation" }
|
|
776
776
|
},
|
|
@@ -780,11 +780,11 @@ const rawData = {
|
|
|
780
780
|
"description": "Allows only alphanumeric characters.",
|
|
781
781
|
"parameters": [{
|
|
782
782
|
"name": "params",
|
|
783
|
-
"type": "[options?: MaybeRefOrGetter<CommonAlphaOptions
|
|
783
|
+
"type": "[options?: MaybeRefOrGetter<Maybe<CommonAlphaOptions | undefined>>]",
|
|
784
784
|
"description": "",
|
|
785
785
|
"optional": false
|
|
786
786
|
}],
|
|
787
|
-
"returnType": "RegleRuleDefinition<\"alphaNum\", string | number, [options?: CommonAlphaOptions], false, boolean, string
|
|
787
|
+
"returnType": "RegleRuleDefinition<\"alphaNum\", string | number, [options?: CommonAlphaOptions | undefined], false, boolean, MaybeInput<string>, string | number, false>",
|
|
788
788
|
"example": "import { alphaNum } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n alphaNum,\n // or with symbols allowed\n alphaNum: alphaNum({ allowSymbols: true }),\n },\n})",
|
|
789
789
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#alphanum Documentation" }
|
|
790
790
|
},
|
|
@@ -809,7 +809,7 @@ const rawData = {
|
|
|
809
809
|
"parameters": [
|
|
810
810
|
{
|
|
811
811
|
"name": "_condition",
|
|
812
|
-
"type": "MaybeRefOrGetter<boolean
|
|
812
|
+
"type": "MaybeRefOrGetter<Maybe<boolean>>",
|
|
813
813
|
"description": "- The condition to check (ref, getter, or value)",
|
|
814
814
|
"optional": false
|
|
815
815
|
},
|
|
@@ -821,7 +821,7 @@ const rawData = {
|
|
|
821
821
|
},
|
|
822
822
|
{
|
|
823
823
|
"name": "options",
|
|
824
|
-
"type": "ApplyIfOptions",
|
|
824
|
+
"type": "ApplyIfOptions | undefined",
|
|
825
825
|
"description": "",
|
|
826
826
|
"optional": true
|
|
827
827
|
}
|
|
@@ -837,7 +837,7 @@ const rawData = {
|
|
|
837
837
|
"parameters": [
|
|
838
838
|
{
|
|
839
839
|
"name": "_condition",
|
|
840
|
-
"type": "MaybeRefOrGetter<boolean
|
|
840
|
+
"type": "MaybeRefOrGetter<Maybe<boolean>>",
|
|
841
841
|
"description": "- The condition to check (ref, getter, or value)",
|
|
842
842
|
"optional": false
|
|
843
843
|
},
|
|
@@ -849,7 +849,7 @@ const rawData = {
|
|
|
849
849
|
},
|
|
850
850
|
{
|
|
851
851
|
"name": "otherwiseRules",
|
|
852
|
-
"type": "MaybeRefOrGetter<TRulesDelc>",
|
|
852
|
+
"type": "MaybeRefOrGetter<TRulesDelc> | undefined",
|
|
853
853
|
"description": "",
|
|
854
854
|
"optional": true
|
|
855
855
|
}
|
|
@@ -864,11 +864,11 @@ const rawData = {
|
|
|
864
864
|
"description": "Checks if at least one key is filled in the object.",
|
|
865
865
|
"parameters": [{
|
|
866
866
|
"name": "keys",
|
|
867
|
-
"type": "MaybeRefOrGetter<readonly (NoInfer<keyof T> & string)[]>",
|
|
867
|
+
"type": "MaybeRefOrGetter<readonly (NoInfer<keyof T> & string)[] | undefined>",
|
|
868
868
|
"description": "",
|
|
869
869
|
"optional": true
|
|
870
870
|
}],
|
|
871
|
-
"returnType": "RegleRuleDefinition<\"atLeastOne\", T, [keys?: readonly (NoInfer<keyof T> & string)[]], false, boolean, false, T, boolean>",
|
|
871
|
+
"returnType": "RegleRuleDefinition<\"atLeastOne\", T, [keys?: readonly (NoInfer<keyof T> & string)[] | undefined], false, boolean, false, T, boolean>",
|
|
872
872
|
"example": "import { atLeastOne } from '@regle/rules';\n\nconst { r$ } = useRegle({ user: { firstName: '', lastName: '' } }, {\n user: {\n atLeastOne,\n // or\n atLeastOne: atLeastOne(['firstName', 'lastName'])\n // or\n atLeastOne: atLeastOne<{ firstName: string; lastName: string }>(['firstName', 'lastName'])\n },\n});",
|
|
873
873
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#atleastone Documentation" }
|
|
874
874
|
},
|
|
@@ -878,11 +878,11 @@ const rawData = {
|
|
|
878
878
|
"description": "Checks if a number is in specified bounds. `min` and `max` are both inclusive by default.",
|
|
879
879
|
"parameters": [{
|
|
880
880
|
"name": "params",
|
|
881
|
-
"type": "[min: MaybeRefOrGetter<number
|
|
881
|
+
"type": "[min: MaybeRefOrGetter<Maybe<number>>, max: MaybeRefOrGetter<Maybe<number>>, options?: MaybeRefOrGetter<Maybe<CommonComparisonOptions | undefined>>]",
|
|
882
882
|
"description": "",
|
|
883
883
|
"optional": false
|
|
884
884
|
}],
|
|
885
|
-
"returnType": "RegleRuleDefinition<\"between\", number, [min: number, max: number, options?: CommonComparisonOptions], false, boolean, number
|
|
885
|
+
"returnType": "RegleRuleDefinition<\"between\", number, [min: number, max: number, options?: CommonComparisonOptions | undefined], false, boolean, MaybeInput<number>, number, false>",
|
|
886
886
|
"example": "import { between } from '@regle/rules';\n\nconst maxCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n between: between(1, 6),\n // or with reactive max\n between: between(1, maxCount, { allowEqual: false }),\n // or with getter\n between: between(() => maxCount.value, 10)\n },\n})",
|
|
887
887
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#between Documentation" }
|
|
888
888
|
},
|
|
@@ -910,11 +910,11 @@ const rawData = {
|
|
|
910
910
|
"description": "Checks if the string contains the specified substring.",
|
|
911
911
|
"parameters": [{
|
|
912
912
|
"name": "params",
|
|
913
|
-
"type": "[part: MaybeRefOrGetter<string
|
|
913
|
+
"type": "[part: MaybeRefOrGetter<Maybe<MaybeInput<string>>>]",
|
|
914
914
|
"description": "",
|
|
915
915
|
"optional": false
|
|
916
916
|
}],
|
|
917
|
-
"returnType": "RegleRuleDefinition<\"contains\", string, [part: string], false, boolean, string
|
|
917
|
+
"returnType": "RegleRuleDefinition<\"contains\", string, [part: MaybeInput<string>], false, boolean, MaybeInput<string>, string, false>",
|
|
918
918
|
"example": "import { contains } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestLib: '' }, {\n bestLib: {\n contains: contains('regle')\n },\n})",
|
|
919
919
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#contains Documentation" }
|
|
920
920
|
},
|
|
@@ -924,11 +924,11 @@ const rawData = {
|
|
|
924
924
|
"description": "Requires a string field to contain at least a given number of special characters.",
|
|
925
925
|
"parameters": [{
|
|
926
926
|
"name": "params",
|
|
927
|
-
"type": "[minCharactersCount?: MaybeRefOrGetter<number
|
|
927
|
+
"type": "[minCharactersCount?: MaybeRefOrGetter<Maybe<number | undefined>>]",
|
|
928
928
|
"description": "",
|
|
929
929
|
"optional": false
|
|
930
930
|
}],
|
|
931
|
-
"returnType": "RegleRuleDefinition<\"containsSpecialCharacter\", string, [minCharactersCount?: number], false, { $valid: boolean; minCharactersCount: number; }, string, string, false>",
|
|
931
|
+
"returnType": "RegleRuleDefinition<\"containsSpecialCharacter\", string, [minCharactersCount?: number | undefined], false, { $valid: boolean; minCharactersCount: number; }, string, string, false>",
|
|
932
932
|
"example": "import { useRegle, containsSpecialCharacter } from '@regle/rules';\n\nconst { r$ } = useRegle({ password: '' }, {\n password: {\n containsSpecialCharacter,\n // or with a minimum number of special characters\n containsSpecialCharacter: containsSpecialCharacter(2)\n }\n})",
|
|
933
933
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#containsSpecialCharacter Documentation" }
|
|
934
934
|
},
|
|
@@ -938,11 +938,11 @@ const rawData = {
|
|
|
938
938
|
"description": "Requires a string field to contain at least a given number of uppercase letters.",
|
|
939
939
|
"parameters": [{
|
|
940
940
|
"name": "params",
|
|
941
|
-
"type": "[minUppercaseCount?: MaybeRefOrGetter<number
|
|
941
|
+
"type": "[minUppercaseCount?: MaybeRefOrGetter<Maybe<number | undefined>>]",
|
|
942
942
|
"description": "",
|
|
943
943
|
"optional": false
|
|
944
944
|
}],
|
|
945
|
-
"returnType": "RegleRuleDefinition<\"containsUppercase\", string, [minUppercaseCount?: number], false, { $valid: boolean; minUppercaseCount: number; }, string, string, false>",
|
|
945
|
+
"returnType": "RegleRuleDefinition<\"containsUppercase\", string, [minUppercaseCount?: number | undefined], false, { $valid: boolean; minUppercaseCount: number; }, string, string, false>",
|
|
946
946
|
"example": "import { useRegle, containsUppercase } from '@regle/rules';\n\nconst { r$ } = useRegle({ password: '' }, {\n password: { containsUppercase },\n // or with a minimum number of uppercase letters\n password: { containsUppercase: containsUppercase(2) }\n})",
|
|
947
947
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#containsUppercase Documentation" }
|
|
948
948
|
},
|
|
@@ -961,11 +961,11 @@ const rawData = {
|
|
|
961
961
|
"description": "Checks if the date is after the given parameter.",
|
|
962
962
|
"parameters": [{
|
|
963
963
|
"name": "params",
|
|
964
|
-
"type": "[after: MaybeRefOrGetter<string | Date
|
|
964
|
+
"type": "[after: MaybeRefOrGetter<Maybe<MaybeInput<string | Date>>>, options?: MaybeRefOrGetter<Maybe<CommonComparisonOptions | undefined>>]",
|
|
965
965
|
"description": "",
|
|
966
966
|
"optional": false
|
|
967
967
|
}],
|
|
968
|
-
"returnType": "RegleRuleDefinition<\"dateAfter\", string | Date, [after: string | Date
|
|
968
|
+
"returnType": "RegleRuleDefinition<\"dateAfter\", string | Date, [after: MaybeInput<string | Date>, options?: CommonComparisonOptions | undefined], false, true | { ...; } | { ...; }, MaybeInput<...>, string | Date, fa...",
|
|
969
969
|
"example": "import { dateAfter } from '@regle/rules';\n\nconst { r$ } = useRegle({ birthday: null as Date | null }, {\n birthday: {\n dateAfter: dateAfter(new Date()),\n // or with options\n dateAfter: dateAfter(new Date(), { allowEqual: false }),\n },\n})",
|
|
970
970
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#dateafter Documentation" }
|
|
971
971
|
},
|
|
@@ -975,11 +975,11 @@ const rawData = {
|
|
|
975
975
|
"description": "Checks if the date is before the given parameter.",
|
|
976
976
|
"parameters": [{
|
|
977
977
|
"name": "params",
|
|
978
|
-
"type": "[before: MaybeRefOrGetter<string | Date
|
|
978
|
+
"type": "[before: MaybeRefOrGetter<Maybe<MaybeInput<string | Date>>>, options?: MaybeRefOrGetter<Maybe<CommonComparisonOptions | undefined>>]",
|
|
979
979
|
"description": "",
|
|
980
980
|
"optional": false
|
|
981
981
|
}],
|
|
982
|
-
"returnType": "RegleRuleDefinition<\"dateBefore\", string | Date, [before: string | Date
|
|
982
|
+
"returnType": "RegleRuleDefinition<\"dateBefore\", string | Date, [before: MaybeInput<string | Date>, options?: CommonComparisonOptions | undefined], false, true | { ...; } | { ...; }, MaybeInput<...>, string | Date, ...",
|
|
983
983
|
"example": "import { dateBefore } from '@regle/rules';\n\nconst { r$ } = useRegle({ birthday: null as Date | null }, {\n birthday: {\n dateBefore: dateBefore(new Date()),\n // or with options\n dateBefore: dateBefore(new Date(), { allowEqual: false }),\n },\n})",
|
|
984
984
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#datebefore Documentation" }
|
|
985
985
|
},
|
|
@@ -989,11 +989,11 @@ const rawData = {
|
|
|
989
989
|
"description": "Checks if the date falls between the specified bounds.",
|
|
990
990
|
"parameters": [{
|
|
991
991
|
"name": "params",
|
|
992
|
-
"type": "[before: MaybeRefOrGetter<string | Date
|
|
992
|
+
"type": "[before: MaybeRefOrGetter<Maybe<MaybeInput<string | Date>>>, after: MaybeRefOrGetter<Maybe<MaybeInput<string | Date>>>, options?: MaybeRefOrGetter<...>]",
|
|
993
993
|
"description": "",
|
|
994
994
|
"optional": false
|
|
995
995
|
}],
|
|
996
|
-
"returnType": "RegleRuleDefinition<\"dateBetween\", string | Date, [before: string | Date
|
|
996
|
+
"returnType": "RegleRuleDefinition<\"dateBetween\", string | Date, [before: MaybeInput<string | Date>, after: MaybeInput<string | Date>, options?: CommonComparisonOptions | undefined], ... 4 more ..., false>",
|
|
997
997
|
"example": "import { dateBetween } from '@regle/rules';\n\nconst { r$ } = useRegle({ birthday: null as Date | null }, {\n birthday: {\n dateBetween: dateBetween(new Date(), new Date(2030, 3, 1)),\n // or with options\n dateBetween: dateBetween(new Date(), new Date(2030, 3, 1), { allowEqual: false }),\n },\n})",
|
|
998
998
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#datebetween Documentation" }
|
|
999
999
|
},
|
|
@@ -1039,11 +1039,11 @@ const rawData = {
|
|
|
1039
1039
|
"description": "Checks if the string ends with the specified substring.",
|
|
1040
1040
|
"parameters": [{
|
|
1041
1041
|
"name": "params",
|
|
1042
|
-
"type": "[part: MaybeRefOrGetter<string
|
|
1042
|
+
"type": "[part: MaybeRefOrGetter<Maybe<MaybeInput<string>>>]",
|
|
1043
1043
|
"description": "",
|
|
1044
1044
|
"optional": false
|
|
1045
1045
|
}],
|
|
1046
|
-
"returnType": "RegleRuleDefinition<\"endsWith\", string, [part: string], false, boolean, string
|
|
1046
|
+
"returnType": "RegleRuleDefinition<\"endsWith\", string, [part: MaybeInput<string>], false, boolean, MaybeInput<string>, string, false>",
|
|
1047
1047
|
"example": "import { endsWith } from '@regle/rules';\n\nconst { r$ } = useRegle({ firstName: '' }, {\n firstName: { endsWith: endsWith('foo') },\n})",
|
|
1048
1048
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#endswith Documentation" }
|
|
1049
1049
|
},
|
|
@@ -1053,7 +1053,7 @@ const rawData = {
|
|
|
1053
1053
|
"description": "Requires the input value to have a strict specified length. Works with arrays, objects and strings.",
|
|
1054
1054
|
"parameters": [{
|
|
1055
1055
|
"name": "params",
|
|
1056
|
-
"type": "[count: MaybeRefOrGetter<number
|
|
1056
|
+
"type": "[count: MaybeRefOrGetter<Maybe<number>>]",
|
|
1057
1057
|
"description": "",
|
|
1058
1058
|
"optional": false
|
|
1059
1059
|
}],
|
|
@@ -1067,7 +1067,7 @@ const rawData = {
|
|
|
1067
1067
|
"description": "Requires the input value to have a strict specified length. Works with arrays, objects and strings.",
|
|
1068
1068
|
"parameters": [{
|
|
1069
1069
|
"name": "params",
|
|
1070
|
-
"type": "[count: MaybeRefOrGetter<number
|
|
1070
|
+
"type": "[count: MaybeRefOrGetter<Maybe<number>>]",
|
|
1071
1071
|
"description": "",
|
|
1072
1072
|
"optional": false
|
|
1073
1073
|
}],
|
|
@@ -1081,11 +1081,11 @@ const rawData = {
|
|
|
1081
1081
|
"description": "Requires a field to have a strict numeric value.",
|
|
1082
1082
|
"parameters": [{
|
|
1083
1083
|
"name": "params",
|
|
1084
|
-
"type": "[count: MaybeRefOrGetter<number
|
|
1084
|
+
"type": "[count: MaybeRefOrGetter<Maybe<number>>]",
|
|
1085
1085
|
"description": "",
|
|
1086
1086
|
"optional": false
|
|
1087
1087
|
}],
|
|
1088
|
-
"returnType": "RegleRuleDefinition<\"exactValue\", number, [count: number], false, boolean, number
|
|
1088
|
+
"returnType": "RegleRuleDefinition<\"exactValue\", number, [count: number], false, boolean, MaybeInput<number>, number, false>",
|
|
1089
1089
|
"example": "import { exactValue } from '@regle/rules';\n\nconst exactCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n exactValue: exactValue(6),\n // or with reactive value\n exactValue: exactValue(exactCount),\n // or with getter\n exactValue: exactValue(() => exactCount.value)\n },\n})",
|
|
1090
1090
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#exactvalue Documentation" }
|
|
1091
1091
|
},
|
|
@@ -1104,7 +1104,7 @@ const rawData = {
|
|
|
1104
1104
|
"description": "Requires a value to be a file with a specific type.",
|
|
1105
1105
|
"parameters": [{
|
|
1106
1106
|
"name": "params",
|
|
1107
|
-
"type": "[accept: MaybeRefOrGetter<readonly string[]
|
|
1107
|
+
"type": "[accept: MaybeRefOrGetter<Maybe<readonly string[]>>]",
|
|
1108
1108
|
"description": "",
|
|
1109
1109
|
"optional": false
|
|
1110
1110
|
}],
|
|
@@ -1150,11 +1150,11 @@ const rawData = {
|
|
|
1150
1150
|
"description": "Validates HTTP URLs.",
|
|
1151
1151
|
"parameters": [{
|
|
1152
1152
|
"name": "params",
|
|
1153
|
-
"type": "[options?: MaybeRefOrGetter<UrlOptions
|
|
1153
|
+
"type": "[options?: MaybeRefOrGetter<Maybe<UrlOptions | undefined>>]",
|
|
1154
1154
|
"description": "",
|
|
1155
1155
|
"optional": false
|
|
1156
1156
|
}],
|
|
1157
|
-
"returnType": "RegleRuleDefinition<\"httpUrl\", string, [options?: UrlOptions], false, boolean, unknown, string, false>",
|
|
1157
|
+
"returnType": "RegleRuleDefinition<\"httpUrl\", string, [options?: UrlOptions | undefined], false, boolean, unknown, string, false>",
|
|
1158
1158
|
"example": "import { httpUrl } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestUrl: '' }, {\n bestUrl: { httpUrl },\n // or to force https protocol\n bestUrl: { httpUrl: httpUrl({ protocol: /^https$/ }) },\n})",
|
|
1159
1159
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#httpurl Documentation" }
|
|
1160
1160
|
},
|
|
@@ -1289,11 +1289,11 @@ const rawData = {
|
|
|
1289
1289
|
"description": "Validates MAC addresses. Call as a function to specify a custom separator (e.g., `':'` or an empty string for `00ff1122334455`).",
|
|
1290
1290
|
"parameters": [{
|
|
1291
1291
|
"name": "params",
|
|
1292
|
-
"type": "[separator?: MaybeRefOrGetter<string
|
|
1292
|
+
"type": "[separator?: MaybeRefOrGetter<Maybe<string | undefined>>]",
|
|
1293
1293
|
"description": "",
|
|
1294
1294
|
"optional": false
|
|
1295
1295
|
}],
|
|
1296
|
-
"returnType": "RegleRuleDefinition<\"macAddress\", string, [separator?: string], false, boolean, string
|
|
1296
|
+
"returnType": "RegleRuleDefinition<\"macAddress\", string, [separator?: string | undefined], false, boolean, MaybeInput<string>, string, false>",
|
|
1297
1297
|
"example": "import { macAddress } from '@regle/rules';\n\nconst { r$ } = useRegle({ address: '' }, {\n address: {\n macAddress,\n // or with custom separator\n macAddress: macAddress('-')\n },\n})",
|
|
1298
1298
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#macaddress Documentation" }
|
|
1299
1299
|
},
|
|
@@ -1303,7 +1303,7 @@ const rawData = {
|
|
|
1303
1303
|
"description": "Tests a value against one or more regular expressions.\nReturns `true` if the value is empty or matches **all** provided patterns.",
|
|
1304
1304
|
"parameters": [{
|
|
1305
1305
|
"name": "_value",
|
|
1306
|
-
"type": "string | number",
|
|
1306
|
+
"type": "string | number | null | undefined",
|
|
1307
1307
|
"description": "- The value to test",
|
|
1308
1308
|
"optional": false
|
|
1309
1309
|
}, {
|
|
@@ -1322,7 +1322,7 @@ const rawData = {
|
|
|
1322
1322
|
"description": "Requires a value to be a file with a maximum size.",
|
|
1323
1323
|
"parameters": [{
|
|
1324
1324
|
"name": "params",
|
|
1325
|
-
"type": "[maxSize: MaybeRefOrGetter<number
|
|
1325
|
+
"type": "[maxSize: MaybeRefOrGetter<Maybe<number>>]",
|
|
1326
1326
|
"description": "",
|
|
1327
1327
|
"optional": false
|
|
1328
1328
|
}],
|
|
@@ -1336,11 +1336,11 @@ const rawData = {
|
|
|
1336
1336
|
"description": "Requires the input value to have a maximum specified length, inclusive. Works with arrays, objects and strings.",
|
|
1337
1337
|
"parameters": [{
|
|
1338
1338
|
"name": "params",
|
|
1339
|
-
"type": "[max: MaybeRefOrGetter<number
|
|
1339
|
+
"type": "[max: MaybeRefOrGetter<Maybe<number>>, options?: MaybeRefOrGetter<Maybe<CommonComparisonOptions | undefined>>]",
|
|
1340
1340
|
"description": "",
|
|
1341
1341
|
"optional": false
|
|
1342
1342
|
}],
|
|
1343
|
-
"returnType": "RegleRuleDefinition<\"maxLength\", string | any[] | Record<PropertyKey, any>, [max: number, options?: CommonComparisonOptions], false, boolean, unknown, string |
|
|
1343
|
+
"returnType": "RegleRuleDefinition<\"maxLength\", string | any[] | Record<PropertyKey, any>, [max: number, options?: CommonComparisonOptions | undefined], false, boolean, unknown, string | ... 1 more ... | Record<...>...",
|
|
1344
1344
|
"example": "import { maxLength } from '@regle/rules';\n\nconst maxValue = ref(6);\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n maxLength: maxLength(6),\n // or with reactive value\n maxLength: maxLength(maxValue),\n // or with getter\n maxLength: maxLength(() => maxValue.value)\n },\n})",
|
|
1345
1345
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#maxlength Documentation" }
|
|
1346
1346
|
},
|
|
@@ -1350,11 +1350,11 @@ const rawData = {
|
|
|
1350
1350
|
"description": "Requires a field to have a specified maximum numeric value.",
|
|
1351
1351
|
"parameters": [{
|
|
1352
1352
|
"name": "params",
|
|
1353
|
-
"type": "[max: MaybeRefOrGetter<string | number
|
|
1353
|
+
"type": "[max: MaybeRefOrGetter<Maybe<string | number>>, options?: MaybeRefOrGetter<Maybe<CommonComparisonOptions | undefined>>]",
|
|
1354
1354
|
"description": "",
|
|
1355
1355
|
"optional": false
|
|
1356
1356
|
}],
|
|
1357
|
-
"returnType": "RegleRuleDefinition<\"maxValue\", string | number, [max: string | number, options?: CommonComparisonOptions], false, boolean, string | number
|
|
1357
|
+
"returnType": "RegleRuleDefinition<\"maxValue\", string | number, [max: string | number, options?: CommonComparisonOptions | undefined], false, boolean, MaybeInput<string | number>, string | number, false>",
|
|
1358
1358
|
"example": "import { maxValue } from '@regle/rules';\n\nconst maxCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n maxValue: maxValue(6),\n // or with options\n maxValue: maxValue(maxCount, { allowEqual: false }),\n // or with getter\n maxValue: maxValue(() => maxCount.value)\n },\n})",
|
|
1359
1359
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#maxvalue Documentation" }
|
|
1360
1360
|
},
|
|
@@ -1364,11 +1364,11 @@ const rawData = {
|
|
|
1364
1364
|
"description": "Requires a value to be a file with a minimum size.",
|
|
1365
1365
|
"parameters": [{
|
|
1366
1366
|
"name": "params",
|
|
1367
|
-
"type": "[minSize: MaybeRefOrGetter<number
|
|
1367
|
+
"type": "[minSize: MaybeRefOrGetter<Maybe<number>>]",
|
|
1368
1368
|
"description": "",
|
|
1369
1369
|
"optional": false
|
|
1370
1370
|
}],
|
|
1371
|
-
"returnType": "RegleRuleDefinition<\"minFileSize\", File, [minSize: number], false, true | { $valid: boolean; fileSize: number; }, File
|
|
1371
|
+
"returnType": "RegleRuleDefinition<\"minFileSize\", File, [minSize: number], false, true | { $valid: boolean; fileSize: number; }, MaybeInput<File>, File, false>",
|
|
1372
1372
|
"example": "import { type InferInput } from '@regle/core';\nimport { minFileSize } from '@regle/rules';\n\nconst {r$} = useRegle({ file: null as File | null }, {\n file: { minFileSize: minFileSize(1_000_000) }, // 1 MB\n})",
|
|
1373
1373
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#minfilesize Documentation" }
|
|
1374
1374
|
},
|
|
@@ -1378,11 +1378,11 @@ const rawData = {
|
|
|
1378
1378
|
"description": "Requires the input value to have a minimum specified length, inclusive. Works with arrays, objects and strings.",
|
|
1379
1379
|
"parameters": [{
|
|
1380
1380
|
"name": "params",
|
|
1381
|
-
"type": "[min: MaybeRefOrGetter<number
|
|
1381
|
+
"type": "[min: MaybeRefOrGetter<Maybe<number>>, options?: MaybeRefOrGetter<Maybe<CommonComparisonOptions | undefined>>]",
|
|
1382
1382
|
"description": "",
|
|
1383
1383
|
"optional": false
|
|
1384
1384
|
}],
|
|
1385
|
-
"returnType": "RegleRuleDefinition<\"minLength\", string | any[] | Record<PropertyKey, any>, [min: number, options?: CommonComparisonOptions], false, boolean,
|
|
1385
|
+
"returnType": "RegleRuleDefinition<\"minLength\", string | any[] | Record<PropertyKey, any>, [min: number, options?: CommonComparisonOptions | undefined], false, boolean, MaybeInput<...>, string | ... 1 more ... | Rec...",
|
|
1386
1386
|
"example": "import { minLength } from '@regle/rules';\n\nconst minValue = ref(6);\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n minLength: minLength(6),\n // or with reactive value\n minLength: minLength(minValue),\n // or with getter\n minLength: minLength(() => minValue.value)\n },\n})",
|
|
1387
1387
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#minlength Documentation" }
|
|
1388
1388
|
},
|
|
@@ -1392,11 +1392,11 @@ const rawData = {
|
|
|
1392
1392
|
"description": "Requires a field to have a specified minimum numeric value.",
|
|
1393
1393
|
"parameters": [{
|
|
1394
1394
|
"name": "params",
|
|
1395
|
-
"type": "[min: MaybeRefOrGetter<string | number
|
|
1395
|
+
"type": "[min: MaybeRefOrGetter<Maybe<string | number>>, options?: MaybeRefOrGetter<Maybe<CommonComparisonOptions | undefined>>]",
|
|
1396
1396
|
"description": "",
|
|
1397
1397
|
"optional": false
|
|
1398
1398
|
}],
|
|
1399
|
-
"returnType": "RegleRuleDefinition<\"minValue\", string | number, [min: string | number, options?: CommonComparisonOptions], false, boolean, string | number
|
|
1399
|
+
"returnType": "RegleRuleDefinition<\"minValue\", string | number, [min: string | number, options?: CommonComparisonOptions | undefined], false, boolean, MaybeInput<string | number>, string | number, false>",
|
|
1400
1400
|
"example": "import { minValue } from '@regle/rules';\n\nconst minCount = ref(6);\n\nconst { r$ } = useRegle({ count: 0 }, {\n count: {\n minValue: minValue(6),\n // or with options\n minValue: minValue(minCount, { allowEqual: false }),\n // or with getter\n minValue: minValue(() => minCount.value)\n },\n})",
|
|
1401
1401
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#minvalue Documentation" }
|
|
1402
1402
|
},
|
|
@@ -1425,7 +1425,7 @@ const rawData = {
|
|
|
1425
1425
|
"optional": false
|
|
1426
1426
|
}, {
|
|
1427
1427
|
"name": "message",
|
|
1428
|
-
"type": "RegleRuleDefinitionWithMetadataProcessor<TValue, RegleRuleMetadataConsumer<TValue, TParams, TMetadata>, string | string[]>",
|
|
1428
|
+
"type": "RegleRuleDefinitionWithMetadataProcessor<TValue, RegleRuleMetadataConsumer<TValue, TParams, TMetadata>, string | string[]> | undefined",
|
|
1429
1429
|
"description": "- Optional custom error message",
|
|
1430
1430
|
"optional": true
|
|
1431
1431
|
}],
|
|
@@ -1461,7 +1461,7 @@ const rawData = {
|
|
|
1461
1461
|
"description": "- Array of allowed values",
|
|
1462
1462
|
"optional": false
|
|
1463
1463
|
}],
|
|
1464
|
-
"returnType": "RegleRuleDefinition<\"oneOf\", TEnum[keyof TEnum], [options: TEnum], false, boolean, TEnum[keyof TEnum]
|
|
1464
|
+
"returnType": "RegleRuleDefinition<\"oneOf\", TEnum[keyof TEnum], [options: TEnum], false, boolean, MaybeInput<TEnum[keyof TEnum]>, string | number, boolean>",
|
|
1465
1465
|
"example": "import { oneOf } from '@regle/rules';\n\nconst { r$ } = useRegle({ aliment: 'Fish' }, {\n aliment: {\n oneOf: oneOf(['Fish', 'Meat', 'Bone'])\n },\n})",
|
|
1466
1466
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#oneof Documentation" }
|
|
1467
1467
|
},
|
|
@@ -1499,11 +1499,11 @@ const rawData = {
|
|
|
1499
1499
|
"description": "Checks if the value matches one or more regular expressions.",
|
|
1500
1500
|
"parameters": [{
|
|
1501
1501
|
"name": "params",
|
|
1502
|
-
"type": "[regexp: MaybeRefOrGetter<RegExp | readonly RegExp[]
|
|
1502
|
+
"type": "[regexp: MaybeRefOrGetter<Maybe<RegExp | readonly RegExp[]>>]",
|
|
1503
1503
|
"description": "",
|
|
1504
1504
|
"optional": false
|
|
1505
1505
|
}],
|
|
1506
|
-
"returnType": "RegleRuleDefinition<\"regex\", string | number, [regexp: RegExp | readonly RegExp[]], false, boolean, string | number
|
|
1506
|
+
"returnType": "RegleRuleDefinition<\"regex\", string | number, [regexp: RegExp | readonly RegExp[]], false, boolean, MaybeInput<string | number>, string | number, false>",
|
|
1507
1507
|
"example": "import { regex } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n regex: regex(/^foo/),\n // or with multiple patterns\n regex: regex([/^bar/, /baz$/]),\n },\n})",
|
|
1508
1508
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#regex Documentation" }
|
|
1509
1509
|
},
|
|
@@ -1522,7 +1522,7 @@ const rawData = {
|
|
|
1522
1522
|
"description": "Requires non-empty data, only if provided data property, ref, or a function resolves to `true`.",
|
|
1523
1523
|
"parameters": [{
|
|
1524
1524
|
"name": "params",
|
|
1525
|
-
"type": "[condition: MaybeRefOrGetter<boolean
|
|
1525
|
+
"type": "[condition: MaybeRefOrGetter<Maybe<boolean>>]",
|
|
1526
1526
|
"description": "",
|
|
1527
1527
|
"optional": false
|
|
1528
1528
|
}],
|
|
@@ -1536,7 +1536,7 @@ const rawData = {
|
|
|
1536
1536
|
"description": "Requires non-empty data, only if provided data property, ref, or a function resolves to `false`.",
|
|
1537
1537
|
"parameters": [{
|
|
1538
1538
|
"name": "params",
|
|
1539
|
-
"type": "[condition: MaybeRefOrGetter<boolean
|
|
1539
|
+
"type": "[condition: MaybeRefOrGetter<Maybe<boolean>>]",
|
|
1540
1540
|
"description": "",
|
|
1541
1541
|
"optional": false
|
|
1542
1542
|
}],
|
|
@@ -1555,11 +1555,11 @@ const rawData = {
|
|
|
1555
1555
|
"optional": false
|
|
1556
1556
|
}, {
|
|
1557
1557
|
"name": "otherName",
|
|
1558
|
-
"type": "MaybeRefOrGetter<string>",
|
|
1558
|
+
"type": "MaybeRefOrGetter<string> | undefined",
|
|
1559
1559
|
"description": "- Optional name for the other field (used in error message)",
|
|
1560
1560
|
"optional": true
|
|
1561
1561
|
}],
|
|
1562
|
-
"returnType": "RegleRuleDefinition<\"sameAs\", TTarget, [target: TTarget, otherName?: string], false, boolean, TTarget extends infer M ? M : TTarget
|
|
1562
|
+
"returnType": "RegleRuleDefinition<\"sameAs\", TTarget, [target: TTarget, otherName?: string | undefined], false, boolean, TTarget extends MaybeInput<infer M> ? M : MaybeInput<TTarget>, unknown, false>",
|
|
1563
1563
|
"example": "import { sameAs } from '@regle/rules';\n\nconst form = ref({\n password: '',\n confirmPassword: '',\n});\n\nconst { r$ } = useRegle(form, {\n confirmPassword: {\n sameAs: sameAs(() => form.value.password),\n }\n})",
|
|
1564
1564
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#sameas Documentation" }
|
|
1565
1565
|
},
|
|
@@ -1569,11 +1569,11 @@ const rawData = {
|
|
|
1569
1569
|
"description": "Checks if the string starts with the specified substring.",
|
|
1570
1570
|
"parameters": [{
|
|
1571
1571
|
"name": "params",
|
|
1572
|
-
"type": "[part: MaybeRefOrGetter<string
|
|
1572
|
+
"type": "[part: MaybeRefOrGetter<Maybe<MaybeInput<string>>>]",
|
|
1573
1573
|
"description": "",
|
|
1574
1574
|
"optional": false
|
|
1575
1575
|
}],
|
|
1576
|
-
"returnType": "RegleRuleDefinition<\"startsWith\", string, [part: string], false, boolean, string
|
|
1576
|
+
"returnType": "RegleRuleDefinition<\"startsWith\", string, [part: MaybeInput<string>], false, boolean, MaybeInput<string>, string, false>",
|
|
1577
1577
|
"example": "import { startsWith } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestLib: '' }, {\n bestLib: {\n startsWith: startsWith('regle')\n },\n})",
|
|
1578
1578
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#startswith Documentation" }
|
|
1579
1579
|
},
|
|
@@ -1592,7 +1592,7 @@ const rawData = {
|
|
|
1592
1592
|
"description": "Coerces any string, number, or Date value into a `Date` using the `Date` constructor.",
|
|
1593
1593
|
"parameters": [{
|
|
1594
1594
|
"name": "argument",
|
|
1595
|
-
"type": "string | number | Date",
|
|
1595
|
+
"type": "string | number | Date | null | undefined",
|
|
1596
1596
|
"description": "- The value to convert to a Date",
|
|
1597
1597
|
"optional": false
|
|
1598
1598
|
}],
|
|
@@ -1638,11 +1638,11 @@ const rawData = {
|
|
|
1638
1638
|
"description": "Validates URLs.",
|
|
1639
1639
|
"parameters": [{
|
|
1640
1640
|
"name": "params",
|
|
1641
|
-
"type": "[options?: MaybeRefOrGetter<UrlOptions
|
|
1641
|
+
"type": "[options?: MaybeRefOrGetter<Maybe<UrlOptions | undefined>>]",
|
|
1642
1642
|
"description": "",
|
|
1643
1643
|
"optional": false
|
|
1644
1644
|
}],
|
|
1645
|
-
"returnType": "RegleRuleDefinition<\"url\", string, [options?: UrlOptions], false, boolean, unknown, string, false>",
|
|
1645
|
+
"returnType": "RegleRuleDefinition<\"url\", string, [options?: UrlOptions | undefined], false, boolean, unknown, string, false>",
|
|
1646
1646
|
"example": "import { url } from '@regle/rules';\n\nconst { r$ } = useRegle({ bestUrl: '' }, {\n bestUrl: { url },\n // or with custom protocol validation\n bestUrl: { url: url({ protocol: /^https?$/ }) },\n})",
|
|
1647
1647
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#url Documentation" }
|
|
1648
1648
|
},
|
|
@@ -1657,7 +1657,7 @@ const rawData = {
|
|
|
1657
1657
|
"optional": false
|
|
1658
1658
|
}, {
|
|
1659
1659
|
"name": "depsArray",
|
|
1660
|
-
"type": "[...TParams]",
|
|
1660
|
+
"type": "[...TParams] | undefined",
|
|
1661
1661
|
"description": "- Array of reactive dependencies (refs or getters)",
|
|
1662
1662
|
"optional": true
|
|
1663
1663
|
}],
|
|
@@ -1744,7 +1744,7 @@ const rawData = {
|
|
|
1744
1744
|
"description": "Create a scoped validation system for schema-based validation.\nSimilar to `createScopedUseRegle` but for use with Standard Schema libraries.",
|
|
1745
1745
|
"parameters": [{
|
|
1746
1746
|
"name": "options",
|
|
1747
|
-
"type": "CreateScopedUseRegleSchemaOptions<TCustomRegle, TAsRecord>",
|
|
1747
|
+
"type": "CreateScopedUseRegleSchemaOptions<TCustomRegle, TAsRecord> | undefined",
|
|
1748
1748
|
"description": "- Configuration options",
|
|
1749
1749
|
"optional": true
|
|
1750
1750
|
}],
|
|
@@ -1786,7 +1786,7 @@ const rawData = {
|
|
|
1786
1786
|
"description": "",
|
|
1787
1787
|
"parameters": [{
|
|
1788
1788
|
"name": "namespace",
|
|
1789
|
-
"type": "MaybeRefOrGetter<string | string[]>",
|
|
1789
|
+
"type": "MaybeRefOrGetter<string | string[]> | undefined",
|
|
1790
1790
|
"description": "",
|
|
1791
1791
|
"optional": true
|
|
1792
1792
|
}],
|
|
@@ -1800,11 +1800,11 @@ const rawData = {
|
|
|
1800
1800
|
"description": "`useRegleSchema` enables validation using Standard Schema compatible libraries\nlike Zod, Valibot, or ArkType.",
|
|
1801
1801
|
"parameters": [{
|
|
1802
1802
|
"name": "params",
|
|
1803
|
-
"type": "[state: MaybeRef<DeepPartial<NoInferLegacy<TState>>> | DeepReactiveState<DeepPartial<NoInferLegacy<TState>>>, rulesFactory: MaybeRef<...>, options
|
|
1803
|
+
"type": "[state: MaybeRef<DeepPartial<NoInferLegacy<TState>>> | DeepReactiveState<DeepPartial<NoInferLegacy<TState>>>, rulesFactory: MaybeRef<...>, options?: useRegleSchemaFnOptions<...> | undefined]",
|
|
1804
1804
|
"description": "",
|
|
1805
1805
|
"optional": false
|
|
1806
1806
|
}],
|
|
1807
|
-
"returnType": "NonNullable<TState> extends PrimitiveTypes ? { r$: Raw<Omit<RegleCommonStatus<PrimitiveTypes & TState & {}, Record<string, any>>, \"$pending\" | ... 3 more ... | \"$originalValue\"> & { ...; } & {
|
|
1807
|
+
"returnType": "NonNullable<TState> extends PrimitiveTypes ? { r$: Raw<Omit<RegleCommonStatus<PrimitiveTypes & TState & {}, Record<string, any>>, \"$pending\" | ... 3 more ... | \"$originalValue\"> & { ...; } & {} & { .....",
|
|
1808
1808
|
"example": "import { useRegleSchema } from '@regle/schemas';\nimport * as v from 'valibot';\n\n// With Valibot\nconst { r$ } = useRegleSchema(\n { name: '', email: '' },\n v.object({\n name: v.pipe(v.string(), v.minLength(3)),\n email: v.pipe(v.string(), v.email())\n })\n);\n\n// With Zod\nimport { z } from 'zod';\n\nconst { r$ } = useRegleSchema(\n { name: '' },\n z.object({\n name: z.string().min(3)\n })\n);\n\n// Access validation state\nr$.$valid // Whether all validations pass\nr$.$value // The current form values\nr$.name.$errors // Errors for the name field",
|
|
1809
1809
|
"tags": { "see": "://reglejs.dev/integrations/schemas-libraries Documentation" }
|
|
1810
1810
|
},
|
|
@@ -1814,11 +1814,11 @@ const rawData = {
|
|
|
1814
1814
|
"description": "",
|
|
1815
1815
|
"parameters": [{
|
|
1816
1816
|
"name": "params",
|
|
1817
|
-
"type": "[state: MaybeRef<DeepPartial<NoInferLegacy<TState>>> | DeepReactiveState<DeepPartial<NoInferLegacy<TState>>>, rulesFactory: MaybeRef<...>, options
|
|
1817
|
+
"type": "[state: MaybeRef<DeepPartial<NoInferLegacy<TState>>> | DeepReactiveState<DeepPartial<NoInferLegacy<TState>>>, rulesFactory: MaybeRef<...>, options?: useRegleSchemaFnOptions<...> | undefined]",
|
|
1818
1818
|
"description": "",
|
|
1819
1819
|
"optional": false
|
|
1820
1820
|
}],
|
|
1821
|
-
"returnType": "NonNullable<TState> extends PrimitiveTypes ? { r$: Raw<Omit<RegleCommonStatus<PrimitiveTypes & TState & {}, Record<string, any>>, \"$pending\" | ... 3 more ... | \"$originalValue\"> & { ...; } & {
|
|
1821
|
+
"returnType": "NonNullable<TState> extends PrimitiveTypes ? { r$: Raw<Omit<RegleCommonStatus<PrimitiveTypes & TState & {}, Record<string, any>>, \"$pending\" | ... 3 more ... | \"$originalValue\"> & { ...; } & {} & { .....",
|
|
1822
1822
|
"example": "",
|
|
1823
1823
|
"tags": {}
|
|
1824
1824
|
},
|
|
@@ -2002,7 +2002,7 @@ function searchApi(query) {
|
|
|
2002
2002
|
});
|
|
2003
2003
|
return results;
|
|
2004
2004
|
}
|
|
2005
|
-
var version = "1.21.
|
|
2005
|
+
var version = "1.21.5";
|
|
2006
2006
|
let posthogClient = null;
|
|
2007
2007
|
posthogClient = new PostHog("phc_kqgJoylCpKkGkkRGxb4MyN2mViehoQcUFEGwVkk4l8E", {
|
|
2008
2008
|
host: "https://eu.i.posthog.com",
|