import type {MaskTokens} from 'maska' // Tokens maska bornant le PREMIER chiffre de chaque champ d'une date/heure. // Objectif : rendre impossible la frappe de valeurs absurdes (ex. 99/99/9999) // dès la saisie. Les impossibilités plus fines (31/02, 29/02 non bissextile, // dépassement min/max) restent du ressort de la validation, en filet de sécurité. const BOUND_TOKENS: MaskTokens = { d: {pattern: /[0-3]/}, // jour : dizaine 0-3 m: {pattern: /[0-1]/}, // mois : dizaine 0-1 h: {pattern: /[0-2]/}, // heure : dizaine 0-2 n: {pattern: /[0-5]/}, // minute : dizaine 0-5 } /** * Construit un masque maska borné à partir d'un gabarit d'affichage * (ex. `JJ/MM/AAAA`, `JJ/MM/AAAA HH:MM`). * * Chaque lettre devient un slot chiffre : le premier chiffre d'un champ est borné * (token dédié), les suivants restent libres (`#`). Les séparateurs sont conservés. * * Le `M` désigne le mois avant les heures, et les minutes après — d'où le suivi de * `seenHour` pour ne pas borner les minutes comme un mois (0-1 au lieu de 0-5). */ export function buildBoundedMask(template: string): {mask: string, tokens: MaskTokens} { let mask = '' let prev = '' let seenHour = false for (const ch of template) { if (!/[A-Za-z]/.test(ch)) { mask += ch // séparateur (/, espace, :) prev = ch continue } const letter = ch.toUpperCase() if (letter === 'H') seenHour = true const isFirstOfField = ch !== prev if (!isFirstOfField) { mask += '#' // unités : chiffre libre } else if (letter === 'J') { mask += 'd' } else if (letter === 'M') { mask += seenHour ? 'n' : 'm' } else if (letter === 'H') { mask += 'h' } else { mask += '#' // année (ou tout autre champ) : libre } prev = ch } return {mask, tokens: BOUND_TOKENS} }