Validate User Input
How to validate user input with custom rules
How to Validate User Input
Validation ensures users provide correct and usable input before template generation.
Basic Validation
Use the validate function in the object form:
const name = await i.text({type: QuestionType.Text,id: 'project.name',message: 'Project name?',desc: 'Enter name',validate: (input) => {Return error string or null for validif (!input) return 'Name is required';return null;}});
name = await i.text({"type": QuestionType.Text,"id": "project.name","message": "Project name?","desc": "Enter name","validate": lambda input: "Name is required" if not input else NoneReturn error string or None for valid})
var name = await i.Text(new TextQuestion{Type = QuestionType.Text,Id = "project.name",Message = "Project name?",Desc = "Enter name",Validate = (input) => string.IsNullOrEmpty(input) ? "Name is required" : nullReturn error string or null for valid});
Validation Patterns
Required Field
const name = await i.text({type: QuestionType.Text,id: 'project.name',message: 'Project name?',desc: 'Enter name',validate: (input) => {if (!input || input.trim() === '') {return 'This field is required';}return null;}});
name = await i.text({"type": QuestionType.Text,"id": "project.name","message": "Project name?","desc": "Enter name","validate": lambda input: "This field is required" if not input or not input.strip() else NoneCheck for empty or whitespace-only input})
var name = await i.Text(new TextQuestion{Type = QuestionType.Text,Id = "project.name",Message = "Project name?",Desc = "Enter name",Validate = (input) => string.IsNullOrWhiteSpace(input) ? "This field is required" : nullCheck for empty or whitespace-only input});
Length Constraints
const username = await i.text({type: QuestionType.Text,id: 'user.name',message: 'Username?',desc: '3-20 characters',validate: (input) => {if (input.length < 3) return 'Minimum 3 characters';Check minimum length firstif (input.length > 20) return 'Maximum 20 characters';Then check maximum lengthreturn null;}});
username = await i.text({"type": QuestionType.Text,"id": "user.name","message": "Username?","desc": "3-20 characters","validate": lambda input: ("Minimum 3 characters" if len(input) < 3 else"Maximum 20 characters" if len(input) > 20 else None)})
var username = await i.Text(new TextQuestion{Type = QuestionType.Text,Id = "user.name",Message = "Username?",Desc = "3-20 characters",Validate = (input) =>{if (input.Length < 3) return "Minimum 3 characters";Check minimum length firstif (input.Length > 20) return "Maximum 20 characters";Then check maximum lengthreturn null;}});
Pattern Matching
const projectName = await i.text({type: QuestionType.Text,id: 'project.name',message: 'Project name?',desc: 'Lowercase, numbers, hyphens only',validate: (input) => {if (!/^[a-z][a-z0-9-]*$/.test(input)) {return 'Use lowercase letters, numbers, and hyphens. Must start with a letter.';}return null;},default: 'my-project'});
import reproject_name = await i.text({"type": QuestionType.Text,"id": "project.name","message": "Project name?","desc": "Lowercase, numbers, hyphens only","validate": lambda input: None if re.match(r'^[a-z][a-z0-9-]*$', input) else "Use lowercase letters, numbers, and hyphens. Must start with a letter.","default": "my-project"})
var projectName = await i.Text(new TextQuestion{Type = QuestionType.Text,Id = "project.name",Message = "Project name?",Desc = "Lowercase, numbers, hyphens only",Validate = (input) => Regex.IsMatch(input, @"^[a-z][a-z0-9-]*$")? null: "Use lowercase letters, numbers, and hyphens. Must start with a letter.",Default = "my-project"});
Email Validation
const email = await i.text({type: QuestionType.Text,id: 'user.email',message: 'Email?',desc: 'Your email address',validate: (input) => {const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;if (!emailRegex.test(input)) {return 'Please enter a valid email address';}return null;}});
import reemail = await i.text({"type": QuestionType.Text,"id": "user.email","message": "Email?","desc": "Your email address","validate": lambda input: None if re.match(r'^[^\s@]+@[^\s@]+\.[^\s@]+$', input) else "Please enter a valid email address"})
var email = await i.Text(new TextQuestion{Type = QuestionType.Text,Id = "user.email",Message = "Email?",Desc = "Your email address",Validate = (input) => Regex.IsMatch(input, @"^[^\s@]+@[^\s@]+\.[^\s@]+$")? null: "Please enter a valid email address"});
URL Validation
const website = await i.text({type: QuestionType.Text,id: 'project.website',message: 'Website URL?',desc: 'Optional website',validate: (input) => {if (!input) return null;Allow empty input (optional field)try {new URL(input);return null;} catch {return 'Please enter a valid URL (including https://)';}}});
from urllib.parse import urlparsewebsite = await i.text({"type": QuestionType.Text,"id": "project.website","message": "Website URL?","desc": "Optional website","validate": lambda input: None if not input else (Allow empty input (optional field)None if urlparse(input).scheme and urlparse(input).netlocelse "Please enter a valid URL (including https://)")})
var website = await i.Text(new TextQuestion{Type = QuestionType.Text,Id = "project.website",Message = "Website URL?",Desc = "Optional website",Validate = (input) =>{if (string.IsNullOrEmpty(input)) return null;Allow empty input (optional field)if (Uri.TryCreate(input, UriKind.Absolute, out _)) return null;return "Please enter a valid URL (including https://)";}});
Number Range
const port = await i.text({type: QuestionType.Text,id: 'server.port',message: 'Port number?',desc: '1024-65535',default: '3000',validate: (input) => {const num = parseInt(input, 10);if (isNaN(num)) return 'Please enter a number';Must be a valid numberif (num < 1024 || num > 65535) return 'Port must be between 1024 and 65535';Check valid port rangereturn null;}});
port = await i.text({"type": QuestionType.Text,"id": "server.port","message": "Port number?","desc": "1024-65535","default": "3000","validate": lambda input: ("Please enter a number" if not input.isdigit() else"Port must be between 1024 and 65535" if not (1024 <= int(input) <= 65535) else None)})
var port = await i.Text(new TextQuestion{Type = QuestionType.Text,Id = "server.port",Message = "Port number?",Desc = "1024-65535",Default = "3000",Validate = (input) =>{if (!int.TryParse(input, out var num)) return "Please enter a number";Must be a valid numberif (num < 1024 || num > 65535) return "Port must be between 1024 and 65535";Check valid port rangereturn null;}});
Password Strength
const password = await i.password({type: QuestionType.Password,id: 'user.password',message: 'Password?',desc: 'Strong password required',validate: (input) => {if (input.length < 8) return 'Minimum 8 characters';Check minimum lengthif (!/[A-Z]/.test(input)) return 'Include an uppercase letter';Require uppercase letterif (!/[a-z]/.test(input)) return 'Include a lowercase letter';Require lowercase letterif (!/[0-9]/.test(input)) return 'Include a number';Require numberif (!/[^A-Za-z0-9]/.test(input)) return 'Include a special character';Require special characterreturn null;}});
import repassword = await i.password({"type": QuestionType.Password,"id": "user.password","message": "Password?","desc": "Strong password required","validate": lambda input: ("Minimum 8 characters" if len(input) < 8 else"Include an uppercase letter" if not re.search(r'[A-Z]', input) elseRequire uppercase letter"Include a lowercase letter" if not re.search(r'[a-z]', input) elseRequire lowercase letter"Include a number" if not re.search(r'[0-9]', input) elseRequire number"Include a special character" if not re.search(r'[^A-Za-z0-9]', input) else NoneRequire special character)})
var password = await i.Password(new PasswordQuestion{Type = QuestionType.Password,Id = "user.password",Message = "Password?",Desc = "Strong password required",Validate = (input) =>{if (input.Length < 8) return "Minimum 8 characters";Check minimum lengthif (!Regex.IsMatch(input, @"[A-Z]")) return "Include an uppercase letter";Require uppercase letterif (!Regex.IsMatch(input, @"[a-z]")) return "Include a lowercase letter";Require lowercase letterif (!Regex.IsMatch(input, @"[0-9]")) return "Include a number";Require numberif (!Regex.IsMatch(input, @"[^A-Za-z0-9]")) return "Include a special character";Require special characterreturn null;}});
Supported Question Types
Validation is only supported on question types that accept text input:
| Question Type | Validation Support |
|---|---|
text | Yes |
password | Yes |
dateSelect | Yes |
select | No |
checkbox | No |
confirm | No |
For select, checkbox, and confirm questions, validation is not needed since users can only choose from predefined options.
Combining Validation with Defaults
const projectName = await i.text({type: QuestionType.Text,id: 'project.name',message: 'Project name?',desc: 'Lowercase, hyphens allowed',default: 'my-project',validate: (input) => {if (!input) return 'Name is required';if (!/^[a-z][a-z0-9-]*$/.test(input)) {return 'Use lowercase letters, numbers, and hyphens. Start with a letter.';}if (input.length > 50) return 'Name too long (max 50 chars)';return null;}});
import reproject_name = await i.text({"type": QuestionType.Text,"id": "project.name","message": "Project name?","desc": "Lowercase, hyphens allowed","default": "my-project","validate": lambda input: ("Name is required" if not input else"Use lowercase letters, numbers, and hyphens. Start with a letter." if not re.match(r'^[a-z][a-z0-9-]*$', input) else"Name too long (max 50 chars)" if len(input) > 50 else None)})
var projectName = await i.Text(new TextQuestion{Type = QuestionType.Text,Id = "project.name",Message = "Project name?",Desc = "Lowercase, hyphens allowed",Default = "my-project",Validate = (input) =>{if (string.IsNullOrEmpty(input)) return "Name is required";if (!Regex.IsMatch(input, @"^[a-z][a-z0-9-]*$"))return "Use lowercase letters, numbers, and hyphens. Start with a letter.";if (input.Length > 50) return "Name too long (max 50 chars)";return null;}});
Related
- IInquirer Reference - Complete API documentation
- Default Values - Setting defaults
- Ask Password - Password questions