Elyra
Elyra The coding agent e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Elyra SQL Server MySQL-compatible SQL server in Rust Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine Elyra Sjá SEO & GEO workspace for macOS Elyra DataGrid Server-driven data grid for Laravel
Release notes
Changelog
Elyra

Validation

Commands receive untrusted input from the frontend. elyra::validation adds a Laravel-style validator: check a JSON value against a familiar rule string and get a per-field error bag that surfaces straight to the UI.

In a command

Return [ValidationErrors] and short-circuit with ? — just like Laravel's $request->validate([...]):

use elyra::{command, Ctx, Validator, ValidationErrors};

#[derive(serde::Deserialize, specta::Type)]
struct AccountInput { email: String, age: i64 }

#[command]
async fn create_account(input: AccountInput)
    -> std::result::Result<Account, ValidationErrors>
{
    let data = serde_json::to_value(&input).unwrap_or_default();
    Validator::new(&data)
        .rules(&[
            ("email", "required|email"),
            ("age",   "integer|min:18"),
        ])
        .validate()?;               // -> Err(ValidationErrors) on failure

    Ok(create(input))
}

ValidationErrors serializes to a Laravel-style bag and its Display is that JSON, so returning it as the command error delivers the structure to the frontend.

On the frontend

import { ValidationError, validationErrors } from "@elyra/runtime";

try {
  await api.create_account({ email, age });
} catch (e) {
  if (e instanceof ValidationError) {
    // e.errors: { email: ["…"], age: ["…"] }
    for (const [field, messages] of Object.entries(e.errors)) {
      showFieldError(field, messages[0]);
    }
  }
}

The shell marks these responses with x-elyra-error-kind: validation, so the runtime builds a typed ValidationError — no string sniffing. validationErrors(e) still works and returns the bag (or null) for code that prefers a plain check.

Rules

Pipe-separated, rule:arg for arguments (min:18, in:a,b,c):

Rule Passes when
required present and not null / empty string / empty array
nullable / sometimes (skips the other rules when the field is absent/null)
string a string
integer an integer
numeric any number
boolean true / false
email looks like an email address
url starts with http:// or https://
min:N number ≥ N, or string/array length ≥ N
max:N number ≤ N, or string/array length ≤ N
size:N number == N, or string/array length == N
in:a,b,c value is one of the list
same:field equals another field's value
confirmed <field>_confirmation equals the value

Absent or null fields only fail required — every other rule is skipped for them (Laravel's implicit "sometimes" behaviour), so optional fields validate only when provided. Unknown rules are ignored.

Direct use

Outside a command you can inspect the bag:

let errors = Validator::new(&data).rule("email", "required|email").errors();
if errors.has("email") {
    eprintln!("{}", errors.first("email").unwrap());
}

Related