vault/ui/app/forms/v2/form-validators.ts
Vault Automation f0cf2a4b68
UI/v2 forms infrastructure (#14134) (#14694)
* copies v2 form components from POC branch

* fixes issue in form-config-generator when path parameters are not defined

* adds api code-generator for snippet creation

* expands cli and terraform code generators

* updates form-config-generator to return api path from spec

* fixes issue setting field value in v2-form class

* updates form-config types

* updates v2 form and renderer components to conditional render fields

* adds v2 form apply component

* updates v2 form wizard component to support apply step

* add support for field types (text input variants, text area, checkbox, radio, masked input) and add test coverage

* Dynamic field visibility and Select field support

* [POC] Public PKI (mocked) Wizard - revert this before merging

* Revert "[POC] Public PKI (mocked) Wizard - revert this before merging"

This reverts commit 66646f1d7a71d0e67028ebcabcfe33925197ffc9.

* cleanup & address copilot pr comments

* address PR comments

---------

Co-authored-by: Shannon Roberts (Beagin) <beagins@users.noreply.github.com>
Co-authored-by: Jordan Reimer <jordan.reimer@hashicorp.com>
2026-05-13 08:46:34 -07:00

95 lines
2.7 KiB
TypeScript

/**
* Copyright IBM Corp. 2016, 2025
* SPDX-License-Identifier: BUSL-1.1
*/
import type { ValidatorOptions } from './form-validator';
/**
* Built-in validator functions
* All validators return true if valid, false if invalid
*/
export const validators = {
/**
* Required - value must be present
* Rejects: null, undefined, '', [], {}
*/
required: (value: unknown, _options?: ValidatorOptions): boolean => {
if (value === null || value === undefined) return false;
if (typeof value === 'string') return value.trim().length > 0;
if (Array.isArray(value)) return value.length > 0;
if (typeof value === 'object') return Object.keys(value).length > 0;
return true;
},
/**
* Email - validates email format
*/
email: (value: unknown, _options?: ValidatorOptions): boolean => {
if (!value) return true; // Use with 'required' for mandatory emails
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(String(value));
},
/**
* URL - validates URL format
*/
url: (value: unknown, _options?: ValidatorOptions): boolean => {
if (!value) return true;
try {
new URL(String(value));
return true;
} catch {
return false;
}
},
/**
* Pattern - validates against regex pattern
*/
pattern: (value: unknown, { pattern, flags = '' }: ValidatorOptions): boolean => {
if (!value || !pattern) return true;
const regex = typeof pattern === 'string' ? new RegExp(pattern, flags) : pattern;
return regex.test(String(value));
},
/**
* MinLength - validates minimum string length
*/
minLength: (value: unknown, { minLength }: ValidatorOptions): boolean => {
if (minLength === undefined) return true;
if (!value) return false;
return String(value).length >= minLength;
},
/**
* MaxLength - validates maximum string length
*/
maxLength: (value: unknown, { maxLength }: ValidatorOptions): boolean => {
if (maxLength === undefined) return true;
if (!value) return true;
return String(value).length <= maxLength;
},
/**
* Min - validates minimum numeric value
*/
min: (value: unknown, { min }: ValidatorOptions): boolean => {
if (min === undefined) return true;
if (value === null || value === undefined || value === '') return true;
const num = Number(value);
if (isNaN(num)) return false;
return num >= min;
},
/**
* Max - validates maximum numeric value
*/
max: (value: unknown, { max }: ValidatorOptions): boolean => {
if (max === undefined) return true;
if (value === null || value === undefined || value === '') return true;
const num = Number(value);
if (isNaN(num)) return false;
return num <= max;
},
};