Repository navigation
v5.1.0
A feature release with one addition: RUT_PATTERN, the shapes validate() accepts, exported as regular-expression strings for schemas and database constraints, where code cannot run. Nothing existing changes: every function behaves exactly as in 5.0.1, and the Modulo 11 algorithm is unchanged.
Why
A RUT rule usually has to live in more than one place: the API schema, a database column, a backend written in another language. validate() cannot run in any of them, so the shape gets retyped there as a hand-written regex, and hand-written RUT regexes drift. They let leading zeros through, accept 9-digit bodies, or match non-ASCII digits through \d. RUT_PATTERN gives those places the exact shape rule the library enforces, and a test suite keeps the two from ever disagreeing.
Do I need to change anything?
No. This release only adds an export. If you don't import RUT_PATTERN, your bundle does not grow: it is a plain object that bundlers drop when unused.
Added
-
RUT_PATTERN— the accepted shapes as plain regular-expression strings, for a JSON Schema or OpenAPIpattern, a zod/valibotregex, or a databaseCHECKconstraint.import { RUT_PATTERN, validate } from 'rut.ts' RUT_PATTERN.any // '^([1-9][0-9]{6,7}-?[0-9kK]|[1-9][0-9]?[.][0-9]{3}[.][0-9]{3}-[0-9kK])$' RUT_PATTERN.compact // '^[1-9][0-9]{6,7}[0-9kK]$' 123456785 RUT_PATTERN.hyphen // '^[1-9][0-9]{6,7}-[0-9kK]$' 12345678-5 RUT_PATTERN.dotted // '^[1-9][0-9]?[.][0-9]{3}[.][0-9]{3}-[0-9kK]$' 12.345.678-5 // zod: the pattern documents the shape, the refinement does the real check const rut = z .string() .trim() .regex(new RegExp(RUT_PATTERN.hyphen)) .refine((value) => validate(value))
- Safe to paste. The strings are anchored, flagless and backslash-free, so they need no escaping in JSON, YAML or SQL, and they carry the no-leading-zero and 7–8 digit rules themselves.
- They cannot drift from the validator. For inputs up to the 64-char cap,
isRutLike(s) === new RegExp(RUT_PATTERN.any).test(s.trim()), and an accepted input matches exactly one ofcompact/hyphen/dotted. A test suite pins this. - Part of the frozen contract. The four strings are public API, byte for byte.
What a pattern does not do:
- It checks shape only, never the verifier digit. About ten in eleven strings that match are not real RUTs, so always run
validate()wherever code can run. anyandcompactmatch any 9-digit number, a phone number included. Preferhyphenordottedin API schemas.- Other engines read anchors differently. In Python use
re.fullmatch(withre.search,$also matches before a trailing newline; the same goes for Perl), and in Ruby replace^/$with\A/\z, because there they match at every line.
Changed
- Docs: the 7–8 digit body range is stated as part of the frozen contract. The README and
llms.txtnow say explicitly that the body must be1.000.000–99.999.999, and that a shorter body is rejected even when its verifier is correct (validate('999999-K')→false,calculateVerifier('999999')throws). Historical RUNs below one million are deliberately out of scope. No behavior change: this documents what the library already does.
Unchanged
- Every existing function.
validate(),isValidRut(),isRutLike(),format(),clean()and the rest behave exactly as in5.0.1.validate()does not use the exported strings. - The body floor stays at 7 digits. No option to accept shorter bodies was added:
validate()remains flag-free exceptstrict. - What you ship if you don't use it. A bundle that imports only
validateorformatis byte-for-byte the same size as before. Importing everything adds about 85 bytes gzipped.
Internal
RUT_PATTERNequivalence suite (40 tests): the exact strings, an exhaustive check of every string up to 9 characters over a reduced alphabet (2.4 million), a property test over mutated RUTs, and the documented limits. It fails if either the patterns or the validator change on their own.- Contract tests pin the body range (25 tests). The existing "too short" cases also carried a wrong verifier, so nothing in the unit suites proved that
validate(),isRutLike(),isValidRut()orcalculateVerifier()reject a body for being too short. The new cases use a correct Modulo 11 digit below the floor (999999-K,999.999-K,100000-4,1000-6,1-9) and check the exact boundaries (999999/1000000/99999999/100000000). - Test suite: 613 tests across 17 suites.
Full notes: CHANGELOG.md