Validation & Parsing
Validate user input, parse notation into structured options, and convert between formats. All functions on this page are exported from @randsum/roller.
Validation
Section titled “Validation”isDiceNotation(value)
Section titled “isDiceNotation(value)”Type guard that returns true if the string is valid dice notation. Use this for quick checks before passing input to roll().
import { isDiceNotation } from '@randsum/roller'
isDiceNotation('4d6L') // true — typed as DiceNotationisDiceNotation('2d6+3') // trueisDiceNotation('hello') // falseisDiceNotation('4dX') // false — non-numeric sidesvalidateNotation(notation)
Section titled “validateNotation(notation)”Returns a detailed result object with either the parsed structure or an error:
import { validateNotation } from '@randsum/roller'
const valid = validateNotation('4d6L')// { valid: true, notation: ['4d6L'], options: [{ sides: 6, quantity: 4, ... }] }
const invalid = validateNotation('4dX')// { valid: false, error: { message: '...', argument: '4dX' } }Use this instead of isDiceNotation() when you need to show error messages to the user.
suggestNotationFix(notation)
Section titled “suggestNotationFix(notation)”Suggests a corrected version of invalid notation. Returns undefined if no suggestion is available.
import { suggestNotationFix } from '@randsum/roller'
suggestNotationFix('d6') // '1d6' — missing quantitysuggestNotationFix('4 d 6') // '4d6' — extra whitespacesuggestNotationFix('46') // '4d6' — missing 'd' separatorsuggestNotationFix('xyz') // undefined — no suggestionCombine with validateNotation() for a complete user-facing validation flow:
import { validateNotation, suggestNotationFix } from '@randsum/roller'
function validateUserInput(input: string) {const result = validateNotation(input)if (result.valid) return { ok: true, notation: result.notation }
const suggestion = suggestNotationFix(input)return { ok: false, error: result.error, suggestion // may be undefined}}notation(value)
Section titled “notation(value)”Assert that a string is valid notation or throw NotationParseError. Returns the input narrowed to the DiceNotation type. The thrown error includes a suggestion property when a fix can be inferred.
import { notation } from '@randsum/roller'
const n = notation('4d6L') // returns '4d6L' as DiceNotationnotation('bad') // throws NotationParseErrorParsing
Section titled “Parsing”notationToOptions(notation)
Section titled “notationToOptions(notation)”Parse a notation string into an array of ParsedNotationOptions objects — one per dice group in the expression:
import { isDiceNotation, notationToOptions } from '@randsum/roller'
if (isDiceNotation('4d6R{1}L+2')) {const options = notationToOptions('4d6R{1}L+2')// [// {// sides: 6,// quantity: 4,// modifiers: {// reroll: { exact: [1] },// drop: { lowest: 1 },// plus: 2// }// }// ]}Transformation
Section titled “Transformation”optionsToNotation(options)
Section titled “optionsToNotation(options)”Convert a RollOptions object back into a notation string:
import { optionsToNotation } from '@randsum/roller'
optionsToNotation({ sides: 6, quantity: 4, modifiers: { drop: { lowest: 1 } } })// '4d6L'optionsToDescription(options)
Section titled “optionsToDescription(options)”Generate a human-readable description of the roll. Returns an array of description strings:
import { optionsToDescription } from '@randsum/roller'
optionsToDescription({ sides: 6, quantity: 4, modifiers: { drop: { lowest: 1 } } })// ['Roll 4 6-sided dice', 'Drop lowest']modifiersToNotation(modifiers) / modifiersToDescription(modifiers)
Section titled “modifiersToNotation(modifiers) / modifiersToDescription(modifiers)”Convert just the modifier portion. modifiersToNotation returns a single string; modifiersToDescription returns an array of description strings:
import { modifiersToNotation, modifiersToDescription } from '@randsum/roller'
modifiersToNotation({ drop: { lowest: 1 }, plus: 3 })// 'L+3'
modifiersToDescription({ drop: { lowest: 1 }, plus: 3 })// ['Drop lowest', 'Add 3']Tokenization
Section titled “Tokenization”tokenize(notation)
Section titled “tokenize(notation)”Parse a notation string into typed tokens for syntax highlighting or UI display. Each token includes its position, type, and a human-readable description.
import { tokenize } from '@randsum/roller'
const tokens = tokenize('4d6L+2')// [// { text: '4d6', key: 'xDN', category: 'Core', start: 0, end: 3, description: '4 six-sided dice' },// { text: 'L', key: 'L', category: 'Filter', start: 3, end: 4, description: 'Drop lowest 1' },// { text: '+2', key: '+', category: 'Scale', start: 4, end: 6, description: 'Plus 2' }// ]Each token conforms to the Token interface:
interface Token { readonly text: string // the matched substring from the input readonly key: string // notation pattern key (e.g. 'xDN', 'L', 'R{..}') readonly category: TokenCategory readonly start: number // start index (inclusive) readonly end: number // end index (exclusive) readonly description: string // human-readable description}TokenCategory is ModifierCategory | 'unknown', where ModifierCategory is one of:
'Core' | 'Special' | 'Order' | 'Clamp' | 'Map' | 'Filter' | 'Substitute' | 'Generate' | 'Accumulate' | 'Scale' | 'Reinterpret' | 'Dispatch'
Tokens that do not match any known pattern have category: 'unknown'.
Common validation issues
Section titled “Common validation issues”| Input | Valid? | Issue |
|---|---|---|
'4dX' | No | Non-numeric sides |
'roll(4d6)' | No | Unsupported wrapper syntax |
'd6' | No | Missing quantity — suggestNotationFix returns '1d6' |
' 4d6' | Yes | Leading/trailing whitespace is trimmed automatically |
'4d6l' | Yes | Lowercase modifiers are accepted |
'4d6L' | Yes | Standard drop-lowest |
If isDiceNotation() returns false for input that looks valid, call suggestNotationFix() to see if the library can auto-correct the issue.