/** * The mask engine: L1 shape and L3 incremental regex. * * Both layers are pure mechanics. `blocks` lays characters into groups and puts * delimiters between them; `regex` accepts or rejects a prefix. Neither knows * about dates, currencies, phone numbers or any other domain — and there is no * third branch that does. `date`, `time` and `number` are sugar for the resolvers * in `./mask-date.ts`, `./mask-time.ts` and `./mask-number.ts`, expanded by * {@link presetResolver}, so the engine stays domain-free and the built-ins stay * on the same public contract as anything userland writes. * * Pure and dependency-free: every function here is a string transform with no * knowledge of DOM, React or caret positions. Caret mapping lives in * `./caret.ts`, event handling in `../hooks/useMask.ts`. */ import type { Mask, MaskDateOptions, MaskNumberOptions, MaskPattern, MaskPreset, MaskRegexOptions, MaskResolver, MaskTimeOptions } from '@/types'; import { type MatcherCompileResult } from './regex-mask'; /** Outcome of applying an engine pattern to a candidate string. */ export interface MaskResult { /** The masked value, delimiters included. */ value: string; /** The masked value with delimiters stripped. */ raw: string; /** Every block filled — or, for L3, the pattern fully matched. */ completed: boolean; /** * Set when an L3 pattern could not be compiled. The mask degrades to * pass-through; the caller is expected to surface this in development rather * than leave the field silently unmasked. */ unsupportedReason?: string; } /** True when the `mask` prop was given as a resolver function. */ export declare const isMaskResolver: (mask: Mask) => mask is MaskResolver; /** True for an L3 regex pattern. */ export declare const isRegexMask: (mask: MaskPattern | MaskPreset) => mask is MaskRegexOptions; /** True for the `date` sugar. */ export declare const isDateMask: (mask: MaskPattern | MaskPreset) => mask is MaskDateOptions; /** True for the `time` sugar. */ export declare const isTimeMask: (mask: MaskPattern | MaskPreset) => mask is MaskTimeOptions; /** True for the `number` sugar. */ export declare const isNumberMask: (mask: MaskPattern | MaskPreset) => mask is MaskNumberOptions; /** * Expands the `date` / `time` / `number` sugar into the resolver it stands for. * * Returns `null` for anything already in its final form — a resolver, or a * generic engine pattern. `useMask` calls this once per mask run, which is why * the factories are deliberately thin: building one allocates a closure and * nothing else. * * @param mask - Any value accepted by the `mask` prop. */ export declare const presetResolver: (mask: Mask) => MaskResolver | null; /** * Block sizes for a pattern. `date` and `time` derive theirs from their tokens, * which is why they cannot also accept `blocks`. Regex patterns have none — the * pattern is the whole specification — and neither does `number`, whose grouping * is variable-width and applied right-to-left. */ export declare const getMaskBlocks: (mask: MaskPattern | MaskPreset) => readonly number[]; /** Compiles a pattern source, reusing a previous result when there is one. */ export declare const getIncrementalMatcher: (source: string, flags?: string) => MatcherCompileResult; /** * Applies an engine pattern to a candidate string. * * Pure: the same input and pattern always produce the same result, and masking an * already-masked value is a no-op. * * @param input - Candidate value, masked or not. * @param pattern - An L1 `blocks` or L3 `regex` pattern. `date` / `time` are * resolvers; run them through {@link presetResolver} instead. */ export declare const applyMaskPattern: (input: string, pattern: MaskPattern) => MaskResult;