@regle/mcp-server 1.19.0 β 1.19.2
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 +10 -10
- package/package.json +1 -1
package/dist/regle-mcp-server.js
CHANGED
|
@@ -139,21 +139,21 @@ var docs_data_default = {
|
|
|
139
139
|
"title": "Built-in rules",
|
|
140
140
|
"category": "rules",
|
|
141
141
|
"path": "core-concepts/rules/built-in-rules.md",
|
|
142
|
-
"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## `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## `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 { r$ } = useRegle({ aliment: 'Fish' }, {\n aliment: {\n oneOf: oneOf(['Fish', 'Meat', 'Bone'])\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
|
+
"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## `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## `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```"
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
"id": "core-concepts-rules-index",
|
|
146
146
|
"title": "Rules",
|
|
147
147
|
"category": "rules",
|
|
148
148
|
"path": "core-concepts/rules/index.md",
|
|
149
|
-
"content": "# Rules\n\nRules are the core
|
|
149
|
+
"content": "# Rules\n\nRules are the core building block of Regle (and also its name).\n\nA rule takes a value (and optional parameters) as input and returns a validation result as output.\n\nThe **result** can be either:\n\n- A `boolean`\n- An object containing at least `{ $valid: boolean }` (allowing you to attach [metadata](/advanced-usage/rule-metadata))\n\n## Reusable rules with `createRule`\n\nThe recommended way to write rules in Regle is with `createRule`. It provides a structured definition that includes the validator logic, an error message, and optional configuration β all in one place.\n\n```ts\nimport { createRule, type Maybe } from '@regle/core';\nimport { isFilled } from '@regle/rules';\n\nexport const mustBe = createRule({\n validator(value: Maybe<string>, expected: string) {\n if (isFilled(value)) {\n return value === expected;\n }\n return true;\n },\n message: ({ $params: [expected] }) => `The value must be '${expected}'`,\n});\n\n// Rule can now accept reactive parameters\nconst expected = ref('foo');\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n mustBe: mustBe(expected),\n // or\n mustBe: mustBe(() => expected.value),\n },\n});\n```\n\nRules created with `createRule` can accept reactive parameters, return custom metadata, run async logic, and more.\n\n:::tip\nHead to the [Reusable rules](/core-concepts/rules/reusable-rules) page for the full guide on `createRule`, including parameters, reactivity, async rules, and metadata.\n:::\n\n## Inline rules\n\nFor quick, one-off validations, you can write rules directly as inline functions. The function receives the current field value as its first argument.\n\nSimple rule:\n\n```ts\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n simpleRule: (value) => value === 'regle',\n },\n})\n```\n\nAsync rule:\n\n```ts\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n asyncRule: async (value) => await someAsyncCall(),\n },\n})\n```\n\nRule with metadata:\n\n```ts\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n metadataRule: (value) => ({\n $valid: value === 'regle',\n foo: 'bar',\n }),\n },\n})\n```\n\n## Adding error messages\n\nAny rule β inline or reusable β can be wrapped with the `withMessage` helper to associate an error message with it.\n\n```ts\nimport { withMessage } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n foo: withMessage((value: Maybe<string>) => value === 'foo', \"Value must be 'foo'\"),\n },\n})\n```\n\n:::tip\nLearn more about `withMessage` and other wrappers in the [Rule wrappers](/core-concepts/rules/rule-wrappers) section.\n:::\n\n## Handling `optional` and `required` rules\n\nIn Regle (borrowed from Vuelidate), all rules are **optional by default**. This means a rule will only run when the field has a value.\n\nThe only exceptions are:\n\n- `required`\n- `checked`\n- `literal`\n\nThis separation keeps the validation logic clean: you define *how* a field should be validated independently from *whether* it's mandatory.\n\nWhen writing custom rules, follow the same convention by checking if the value is filled before validating:\n\n```ts\nimport { isFilled } from '@regle/rules';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: {\n mustBeFoo: (value) => {\n return isFilled(value) && value === 'foo';\n },\n },\n})\n```"
|
|
150
150
|
},
|
|
151
151
|
{
|
|
152
152
|
"id": "core-concepts-rules-reusable-rules",
|
|
153
153
|
"title": "Reusable rules",
|
|
154
154
|
"category": "rules",
|
|
155
155
|
"path": "core-concepts/rules/reusable-rules.md",
|
|
156
|
-
"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### 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='form.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
|
+
"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 undereadble 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='form.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```"
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
"id": "core-concepts-rules-rule-wrappers",
|
|
@@ -841,7 +841,7 @@ var docs_data_default = {
|
|
|
841
841
|
"optional": true
|
|
842
842
|
}
|
|
843
843
|
],
|
|
844
|
-
"returnType": "TRulesDelc",
|
|
844
|
+
"returnType": "MapRulesToUnsafeRules<TRulesDelc>",
|
|
845
845
|
"example": "import { required, email, minLength, assignIf } from '@regle/rules';\n\nconst condition = ref(false);\n\nconst { r$ } = useRegle(ref({ name: '', email: '' }), {\n name: assignIf(condition, { required, minLength: minLength(4) }),\n email: { email },\n});",
|
|
846
846
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/rules-operators#assignif Documentation" }
|
|
847
847
|
},
|
|
@@ -851,11 +851,11 @@ var docs_data_default = {
|
|
|
851
851
|
"description": "Checks if at least one key is filled in the object.",
|
|
852
852
|
"parameters": [{
|
|
853
853
|
"name": "keys",
|
|
854
|
-
"type": "MaybeRefOrGetter<(NoInfer<keyof T> & string)[]>",
|
|
854
|
+
"type": "MaybeRefOrGetter<readonly (NoInfer<keyof T> & string)[]>",
|
|
855
855
|
"description": "",
|
|
856
856
|
"optional": true
|
|
857
857
|
}],
|
|
858
|
-
"returnType": "RegleRuleDefinition<\"atLeastOne\", T, [keys?: (NoInfer<keyof T> & string)[]], false, boolean, false, T, boolean>",
|
|
858
|
+
"returnType": "RegleRuleDefinition<\"atLeastOne\", T, [keys?: readonly (NoInfer<keyof T> & string)[]], false, boolean, false, T, boolean>",
|
|
859
859
|
"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});",
|
|
860
860
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#atleastone Documentation" }
|
|
861
861
|
},
|
|
@@ -1360,7 +1360,7 @@ var docs_data_default = {
|
|
|
1360
1360
|
"description": "- The TypeScript enum to validate against",
|
|
1361
1361
|
"optional": false
|
|
1362
1362
|
}],
|
|
1363
|
-
"returnType": "RegleRuleDefinition<\n 'nativeEnum',\n
|
|
1363
|
+
"returnType": "RegleRuleDefinition<\n 'nativeEnum',\n T[keyof T],\n [enumLike: T],\n false,\n boolean,\n MaybeInput<T[keyof T]>,\n string | number\n>",
|
|
1364
1364
|
"example": "import { nativeEnum } from '@regle/rules';\n\nenum Foo {\n Bar, Baz\n}\n\nconst { r$ } = useRegle({ type: '' }, {\n type: { nativeEnum: nativeEnum(Foo) },\n})",
|
|
1365
1365
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#nativeenum Documentation" }
|
|
1366
1366
|
},
|
|
@@ -1407,11 +1407,11 @@ var docs_data_default = {
|
|
|
1407
1407
|
"description": "Allow only one of the values from a fixed Array of possible entries.",
|
|
1408
1408
|
"parameters": [{
|
|
1409
1409
|
"name": "options",
|
|
1410
|
-
"type": "
|
|
1410
|
+
"type": "TEnum",
|
|
1411
1411
|
"description": "- Array of allowed values",
|
|
1412
1412
|
"optional": false
|
|
1413
1413
|
}],
|
|
1414
|
-
"returnType": "RegleRuleDefinition<\"oneOf\",
|
|
1414
|
+
"returnType": "RegleRuleDefinition<\"oneOf\", TEnum[keyof TEnum], [options: TEnum[keyof TEnum]], false, boolean, TEnum[keyof TEnum], string | number, boolean>",
|
|
1415
1415
|
"example": "import { oneOf } from '@regle/rules';\n\nconst { r$ } = useRegle({ aliment: 'Fish' }, {\n aliment: {\n oneOf: oneOf(['Fish', 'Meat', 'Bone'])\n },\n})",
|
|
1416
1416
|
"tags": { "see": "://reglejs.dev/core-concepts/rules/built-in-rules#oneof Documentation" }
|
|
1417
1417
|
},
|
|
@@ -1955,7 +1955,7 @@ function searchApi(query) {
|
|
|
1955
1955
|
return results;
|
|
1956
1956
|
}
|
|
1957
1957
|
|
|
1958
|
-
var version = "1.19.
|
|
1958
|
+
var version = "1.19.2";
|
|
1959
1959
|
|
|
1960
1960
|
let posthogClient = null;
|
|
1961
1961
|
posthogClient = new PostHog("phc_kqgJoylCpKkGkkRGxb4MyN2mViehoQcUFEGwVkk4l8E", {
|