Validation

Input validation utilities

The validation utilities help validate user input before sending to the API.

Importing

import { validate } from 'arky-sdk/utils';

Email Validation

validate.email('[email protected]');
// Returns: { valid: true }

validate.email('invalid-email');
// Returns: { valid: false, error: 'Invalid email format' }

Password Validation

validate.password('SecurePass123!');
// Returns: { valid: true }

validate.password('weak');
// Returns: {
//   valid: false,
//   error: 'Password must be at least 8 characters',
//   requirements: {
//     minLength: false,
//     hasUppercase: false,
//     hasLowercase: true,
//     hasNumber: false,
//     hasSpecial: false
//   }
// }

Custom Password Requirements

validate.password('MyPassword123', {
  minLength: 10,
  requireUppercase: true,
  requireLowercase: true,
  requireNumber: true,
  requireSpecial: false
});

Phone Validation

validate.phone('+1234567890');
// Returns: { valid: true, formatted: '+1 234 567 890' }

validate.phone('123-456-7890', 'US');
// Returns: { valid: true, formatted: '+1 (123) 456-7890' }

validate.phone('invalid');
// Returns: { valid: false, error: 'Invalid phone number' }

URL Validation

validate.url('https://example.com');
// Returns: { valid: true }

validate.url('example.com');
// Returns: { valid: true, normalized: 'https://example.com' }

validate.url('not-a-url');
// Returns: { valid: false, error: 'Invalid URL format' }

Slug Validation

validate.slug('my-product-name');
// Returns: { valid: true }

validate.slug('Invalid Slug!');
// Returns: {
//   valid: false,
//   error: 'Slug must contain only lowercase letters, numbers, and hyphens',
//   suggested: 'invalid-slug'
// }

Credit Card Validation

validate.creditCard('4242424242424242');
// Returns: { valid: true, type: 'visa' }

validate.creditCard('5555555555554444');
// Returns: { valid: true, type: 'mastercard' }

validate.creditCard('1234');
// Returns: { valid: false, error: 'Invalid card number' }

Date Validation

validate.date('2024-01-15');
// Returns: { valid: true, date: Date object }

validate.date('2024-01-15', { minDate: new Date() });
// Returns: { valid: false, error: 'Date must be in the future' }

validate.dateRange('2024-01-15', '2024-01-20');
// Returns: { valid: true }

Number Validation

validate.number('42');
// Returns: { valid: true, value: 42 }

validate.number('19.99', { min: 0, max: 100 });
// Returns: { valid: true, value: 19.99 }

validate.number('-5', { min: 0 });
// Returns: { valid: false, error: 'Must be at least 0' }

Required Fields

validate.required('value');
// Returns: { valid: true }

validate.required('');
// Returns: { valid: false, error: 'This field is required' }

validate.required(null);
// Returns: { valid: false, error: 'This field is required' }

Form Validation

Validate Object

const formData = {
  email: '[email protected]',
  password: 'weak',
  phone: '123-456-7890'
};

const schema = {
  email: { type: 'email', required: true },
  password: { type: 'password', required: true },
  phone: { type: 'phone', required: false }
};

const result = validate.form(formData, schema);
// Returns: {
//   valid: false,
//   errors: {
//     password: 'Password must be at least 8 characters'
//   }
// }

React Form Hook

function useFormValidation<T extends Record<string, unknown>>(
  schema: ValidationSchema
) {
  const [errors, setErrors] = useState<Record<string, string>>({});

  const validateField = (name: string, value: unknown) => {
    const fieldSchema = schema[name];
    if (!fieldSchema) return true;

    const result = validate[fieldSchema.type](value, fieldSchema.options);

    if (!result.valid) {
      setErrors(prev => ({ ...prev, [name]: result.error }));
      return false;
    }

    setErrors(prev => {
      const { [name]: _, ...rest } = prev;
      return rest;
    });
    return true;
  };

  const validateForm = (data: T) => {
    const result = validate.form(data, schema);
    setErrors(result.errors || {});
    return result.valid;
  };

  return { errors, validateField, validateForm };
}

// Usage
function RegisterForm() {
  const { errors, validateField, validateForm } = useFormValidation({
    email: { type: 'email', required: true },
    password: { type: 'password', required: true }
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const formData = new FormData(e.target);

    if (validateForm(Object.fromEntries(formData))) {
      // Submit form
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        name="email"
        onBlur={e => validateField('email', e.target.value)}
      />
      {errors.email && <span className="error">{errors.email}</span>}

      <input
        name="password"
        type="password"
        onBlur={e => validateField('password', e.target.value)}
      />
      {errors.password && <span className="error">{errors.password}</span>}

      <button type="submit">Register</button>
    </form>
  );
}

Address Validation

validate.address({
  line1: '123 Main St',
  city: 'New York',
  state: 'NY',
  postalCode: '10001',
  country: 'US'
});
// Returns: { valid: true }

Custom Validators

// Create custom validator
const validateUsername = validate.create({
  pattern: /^[a-z0-9_]{3,20}$/,
  message: 'Username must be 3-20 characters (lowercase, numbers, underscores)'
});

validateUsername('valid_user123');
// Returns: { valid: true }

validateUsername('Invalid User!');
// Returns: { valid: false, error: '...' }
Tip

Validate on the client for immediate feedback, but always validate again on the server for security.