regle

repository·main·Indexed 19 days ago

https://github.com/victorgarciaesgi/regle

A headless, model-based form validation library for Vue 3. Regle provides a type-safe, modular approach to validation that mirrors data model structures, featuring async validation, SSR compatibility, and support for Standard Schema specifications including Zod, Valibot, and ArkType. It includes a core library (@regle/core), a rules package (@regle/rules), and an MCP server (@regle/mcp-server) for AI assistant integration.

Tokens
109.8K
Snippets
386
Records
466
Agent score
66%

What's inside regle

  1. Overview of Regle Advanced Patterns

    main

    The regle-advanced skill provides advanced form validation patterns for Regle in Vue 3. It is designed for complex scenarios such as validating arrays of fields, handling asynchronous or server-side errors, managing form variants (discriminated unions), and implementing cross-component scoped validation.

    Requirements:

    • Vue 3.3+
    • TypeScript 5.1+
    • Any agent supporting the Agent Skills spec.
  2. Overview of available Regle Agent Skills

    main

    Regle provides six specialized skills to help AI agents handle different aspects of the library:

    • regle: Core usage including the useRegle composable, validation properties ($invalid, $dirty, $error, $errors, $pending), error display methods (getErrors, flatErrors), and modifiers (autoDirty, lazy, silent, rewardEarly, validationGroups).
    • regle-rules: Validation rules including built-in rules (required, email, minLength), custom rule creation (createRule), rule wrappers (withMessage, withParams, withAsync, withTooltip), and rule operators (and, or, xor, not, pipe, applyIf, assignIf).
    • regle-advanced: Advanced patterns such as collections ($each), async validation, server errors (externalErrors), form resetting ($reset), global configuration (defineRegleConfig), variants (createVariant), scoped validation (useScopedRegle), and merging Regles (mergeRegles).
    • regle-schemas: Schema integration using useRegleSchema with libraries like Zod, Valibot, or ArkType, and support for the Standard Schema spec (useRules, refineRules, InferInput).
    • regle-typescript: TypeScript integration for type-safe output (InferSafeOutput), typing rules (inferRules), and typing component props (InferRegleRoot, RegleFieldStatus).
    • regle-migrate-vuelidate: A migration guide for porting Vuelidate forms (useVuelidate) to Regle (useRegle or useScopedRegle).
  3. What is Regle?

    main

    Regle is a headless form validation library for Vue.js. It provides a type-safe, model-based, and intuitive API designed as an evolution of Vuelidate. Because it is 'headless', it manages the validation logic and state without forcing a specific UI implementation, allowing you to build any interface you need.

    Key features include:

    • Full TypeScript support: Deep type inference and autocompletion.
    • Vue Devtools support: A dedicated extension to debug your validation trees.
    • SSR Ready: Full compatibility with Nuxt and Server-Side Rendering environments.
    • Standard Schema support: Integration with schema libraries like Zod, Valibot, or ArkType to drive your validation logic.
  4. What is the Regle MCP server?

    main

    The Regle MCP (Model Context Protocol) server allows AI assistants to interact with Regle's ecosystem. By integrating this server, your AI assistant can access Regle's documentation and API details to help you write validation rules more effectively.

    Key capabilities provided to the AI assistant include:

    • Creating form validation rules
    • Searching Regle documentation
    • Retrieving precise information on specific rules
    • Creating custom rules
    • Accessing API information for all Regle helpers
  5. Handle discriminated unions with Regle variants

    main

    When a form has fields that depend on a condition or a toggle (discriminated unions), use createVariant to declare the different states and narrowVariant to safely access fields within specific UI blocks. This ensures that fields are only accessible when the current state of the form makes them valid, maintaining both runtime safety and TypeScript accuracy.

    <template>
        <div v-if="narrowVariant(r$, 'type', 'EMAIL')">
          <!-- `email` is a known field only in this block -->
          <input v-model="r$.email.$value" placeholder='Email'/>
          <Errors :errors="r$.email.$errors"/>
        </div>
        
        <div v-else-if="narrowVariant(r$, 'type', 'GITHUB')">
          <!-- `username` is a known field only in this block -->
          <input v-model="r$.username.$value" placeholder='Email'/>
          <Errors :errors="r$.username.$errors"/>
        </div>
    </template>
    
    <script setup lang='ts'>
    import { useRegle, createVariant, narrowVariant } from '@regle/core';
    
    const state = ref<FormState>({})
    
    const {r$} = useRegle(state, () => {
    
      const variant = createVariant(state, 'type', [
        {type: { literal: literal('EMAIL')}, email: { required, email }},
        {type: { literal: literal('GITHUB')}, username: { required }},
        {type: { required }},
      ]);
    
      return {
        firstName: { required },
        ...variant.value,
      };
    })
    </script>
  6. Compare pipe vs and for rule execution

    main

    When deciding how to combine rules, choose between and and pipe based on how you want errors to be reported and how rules should execute:

    Featureandpipe
    ExecutionAll rules run simultaneously.Sequential; later rules only run if earlier ones pass.
    Error ReportingAll errors from all rules are shown at once.Only the first failing rule in the chain reports an error.
    Use CaseWhen you want to show all validation errors immediately.When you want to avoid running complex rules if simple ones fail.
  7. Create custom validation rules

    main

    When built-in rules from @regle/rules are insufficient, you can create custom rules in two ways:

    1. Inline rules: Use a simple function for one-off validation logic.
    2. createRule: Use this function to create reusable rule definitions.

    Custom rules can also support reactive parameters and asynchronous validation.

  8. Use validation groups to group fields

    main

    Validation groups allow you to group specific fields together to track their combined status (e.g., checking if an entire section of a form is valid). You define groups using the validationGroups function in the third argument of useRegle. You can then access the group status via r$.$groups.<groupName>.$invalid, r$.$groups.<groupName>.$errors, etc.

    const { r$ } = useRegle(
      { email: '', user: { firstName: '' } },
      {
        email: { required },
        user: { firstName: { required } },
      },
      {
        validationGroups: (fields) => ({
          group1: [fields.email, fields.user.firstName],
        }),
      }
    );
    
    // Access: r$.$groups.group1.$invalid, r$.$groups.group1.$errors, etc.
  9. Regle vs Tanstack Forms

    main

    Regle is a lightweight, low-boilerplate alternative to Tanstack Forms for Vue developers.

    • Vue Integration: Unlike Tanstack Forms, which carries over much of its React syntax logic, Regle is designed to take full advantage of the Vue Composition API.
    • DOM Dependency: Tanstack Forms relies on DOM components, whereas Regle is headless and does not depend on the DOM.
  10. Use Rule wrappers to customize rules

    main

    Rule wrappers allow you to customize or upgrade your rules by injecting or replacing specific properties like error messages, external parameters, or async behavior. They are imported from @regle/rules and can be applied to individual rules within the useRegle configuration object.

    import { withMessage } from '@regle/rules';
    
    const { r$ } = useRegle({ name: '' }, {
      name: {
        customRule: withMessage((value) => !!value, "Custom Error"),
      }
    });
  11. Replace Nested Component Validation with Scoped Validation

    main

    Regle replaces the Vuelidate concept of 'Nested Component Validation' with Scoped Validation. This allows parents to collect validation states from children using scopes.

    Child Component Setup

    In the child, use useScopedRegle to define validations within a specific scope.

    import { useScopedRegle } from '@regle/core';
    
    // The { namespace: 'foo' } defines the scope name
    const { r$ } = useScopedRegle(state, validations, { namespace: 'foo' });

    Parent Component Setup

    In the parent, use useCollectScope to gather validation results from children matching that scope.

    import { useCollectScope } from '@regle/core';
    
    // Collect all validation states from children using scope 'foo'
    const { r$ } = useCollectScope('foo');
  12. Combine rules with operators

    main

    Regle provides operators to compose complex validation logic by combining multiple rules or applying them conditionally:

    • Logical Operators: and, or, xor, not.
    • Conditional Operators: applyIf (apply rules based on a condition), assignIf (assign rules based on a condition).
    • Composition: pipe (chain rules sequentially).