Numbers
NumberBuilder, IntegerBuilder, MoneyBuilder, DateBuilder, and BooleanBuilder
wellformed provides specialized builders for different numeric types, each with appropriate constraints.
NumberBuilder
w.number() creates a floating-point number schema.
w.number() // Any number
w.number().min(0) // >= 0
w.number().max(100) // <= 100
w.number().range(0, 100) // 0 <= n <= 100
w.number().nonNegative() // >= 0 (predicate-based)
w.number().positive() // > 0
w.number().percentage() // 0-100 range
w.number().percentage({ format: "decimal" }) // 0-1 range
w.number().percentage({ allowOver100: true }) // Uncapped
w.number().lte(999999) // Less than or equal
w.number().gte(0.01) // Greater than or equal
w.number().default(0) // Default value transformIntegerBuilder
w.integer() validates that the value is a whole number.
w.integer() // Any integer
w.integer().min(0).max(150) // Range constraint
w.integer().nonNegative() // >= 0
w.integer().positive() // > 0
w.integer().taxYear() // Valid tax year (2020-2100)
w.integer().taxYear({ min: 2023, max: 2025 }) // Custom range
w.integer().default(0) // Default value transformSpecific Integer Types
For interop with the Rust crate, wellformed supports fixed-width integer types:
w.int32() // Signed 32-bit: -2,147,483,648 to 2,147,483,647
w.int64() // Signed 64-bit (limited to JS safe integer range)
w.uint32() // Unsigned 32-bit: 0 to 4,294,967,295
w.uint64() // Unsigned 64-bit (limited to JS safe integer range)Each supports .min(), .max(), .range(), and .default():
w.int32().min(0).max(1000)
w.uint32().range(1, 100)The validator automatically enforces the type's range even without explicit constraints.
MoneyBuilder
w.money() represents monetary amounts as numbers with optional scale.
w.money() // Money amount
w.money().nonNegative() // No negative amounts
w.money().positive() // Must be > 0
w.money().range(0, 1000000) // Amount range
w.money().scale(2) // 2 decimal places (default)
w.money().default(0) // Default valueCurrencyBuilder
w.currency() adds ISO 4217 currency code support:
w.currency() // Any currency
w.currency().code("USD") // US Dollar
w.currency().code("JPY").scale(0) // Yen (0 decimal places)
w.currency().code("BHD").scale(3) // Bahraini Dinar (3 decimal places)
w.currency().nonNegative()
w.currency().positive()
w.currency().range(0, 1000000)DecimalBuilder
w.decimal() provides exact decimal representation with configurable precision and scale:
w.decimal() // Any decimal
w.decimal().precision(10).scale(2) // Up to 10 digits, 2 decimal places
w.decimal().nonNegative()
w.decimal().range(0, 999.99)PercentageBuilder
w.percentage() validates percentage values:
w.percentage() // Decimal format (0-1), default
w.percentage().whole() // Whole number format (0-100)
w.percentage().decimal() // Decimal format (0-1)
w.percentage().allowOver100() // Allow values > 100%
w.percentage().scale(4) // 4 decimal places
w.percentage().default(0)DateBuilder
w.date() validates date values (represented as strings):
w.date() // Any valid date
w.date().format("MM/DD/YYYY") // Expected format
w.date().inRange({ minYear: 2020, maxYear: 2030 })
w.date().inRange({ min: "2024-01-01", max: "2024-12-31" })
w.date().before("2025-01-01")
w.date().after("2020-01-01", { allowEqual: true })
w.date().default("2024-01-01")BooleanBuilder
w.boolean() validates boolean values:
w.boolean() // true or false