From 95a598da62f8a59eb48f7fa67b463fb2ae018c37 Mon Sep 17 00:00:00 2001 From: jay23606 <4602056+jay23606@users.noreply.github.com> Date: Tue, 27 Oct 2026 04:55:43 -0400 Subject: [PATCH 1/2] Add Romanian postal code validator --- CHANGELOG.md | 4 ++++ README.md | 9 ++++++--- src/index.ts | 2 ++ src/postal-code.ts | 14 ++++++++++++++ test/postal-code.test.ts | 11 +++++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 src/postal-code.ts create mode 100644 test/postal-code.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 405263e..f9202c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project are documented here. The format follows [Kee ## [Unreleased] +### Added + +- `validatePostalCode` / `isValidPostalCode` for six-digit Romanian postal code format validation + ## [0.1.0] - 2026-10-27 ### Added diff --git a/README.md b/README.md index 086d9e7..e0b62ee 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Try it in your browser

-Validate and decode Romanian identifiers (**CNP**, **CUI/CIF** and **IBAN**) with error messages you can show directly to users. Zero dependencies, fully typed, runs in Node and in the browser. +Validate and decode Romanian identifiers (**CNP**, **CUI/CIF**, **IBAN** and postal codes) with error messages you can show directly to users. Zero dependencies, fully typed, runs in Node and in the browser. ```bash npm install validro @@ -60,7 +60,7 @@ type ValidationResult = | { valid: false; error: string; data: null }; ``` -Only need true or false? Use `isValidCnp`, `isValidCui` and `isValidIbanRo`. +Only need true or false? Use `isValidCnp`, `isValidCui`, `isValidIbanRo` and `isValidPostalCode`. ## API @@ -69,7 +69,8 @@ Only need true or false? Use `isValidCnp`, `isValidCui` and `isValidIbanRo`. | `validateCnp(cnp, now?)` | `ValidationResult`; `now` sets the date used to reject future birth dates | | `validateCui(cui)` | `ValidationResult` | | `validateIbanRo(iban)` | `ValidationResult` | -| `isValidCnp`, `isValidCui`, `isValidIbanRo` | `boolean` | +| `validatePostalCode(postalCode)` | `ValidationResult`; exactly 6 digits | +| `isValidCnp`, `isValidCui`, `isValidIbanRo`, `isValidPostalCode` | `boolean` | | `cnpControlDigit(first12)` | the CNP control digit | | `cuiControlDigit(body)` | the CUI control digit | | `ibanChecksumOk(iban)` | mod-97 check, works for any country | @@ -109,3 +110,5 @@ Ideas and bugs are welcome in [issues](https://github.com/Robert-GeorgeDev/Valid ## License [MIT](LICENSE) + + diff --git a/src/index.ts b/src/index.ts index 64c5499..6758db9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,5 +4,7 @@ export { validateCui, isValidCui, cuiControlDigit } from "./cui.js"; export type { CuiInfo } from "./cui.js"; export { validateIbanRo, isValidIbanRo, ibanChecksumOk } from "./iban.js"; export type { IbanInfo } from "./iban.js"; +export { validatePostalCode, isValidPostalCode } from "./postal-code.js"; +export type { PostalCodeInfo } from "./postal-code.js"; export { CNP_COUNTIES } from "./counties.js"; export type { ValidationResult } from "./result.js"; diff --git a/src/postal-code.ts b/src/postal-code.ts new file mode 100644 index 0000000..fc9d4b1 --- /dev/null +++ b/src/postal-code.ts @@ -0,0 +1,14 @@ +import { fail, ok, type ValidationResult } from "./result.js"; + +export interface PostalCodeInfo { + postalCode: string; +} + +/** Validates the six-digit format of a Romanian postal code. */ +export function validatePostalCode(input: string): ValidationResult { + if (typeof input !== "string") return fail("Codul poștal trebuie să fie un șir de caractere"); + if (!/^\d{6}$/.test(input)) return fail("Codul poștal trebuie să conțină exact 6 cifre"); + return ok({ postalCode: input }); +} + +export const isValidPostalCode = (input: string): boolean => validatePostalCode(input).valid; diff --git a/test/postal-code.test.ts b/test/postal-code.test.ts new file mode 100644 index 0000000..120e604 --- /dev/null +++ b/test/postal-code.test.ts @@ -0,0 +1,11 @@ +import { describe, expect, it } from "vitest"; +import { isValidPostalCode, validatePostalCode } from "../src/postal-code.js"; + +describe("Romanian postal code", () => { + it("accepts exactly six digits and rejects other formats", () => { + expect(validatePostalCode("010101")).toEqual({ valid: true, error: null, data: { postalCode: "010101" } }); + expect(isValidPostalCode("12345")).toBe(false); + expect(isValidPostalCode("1234567")).toBe(false); + expect(isValidPostalCode("12345a")).toBe(false); + }); +}); From ddb0ff0d1c5210a752d7869dc810c788975dfbd1 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 27 Oct 2026 09:06:20 +0000 Subject: [PATCH 2/2] fix: ignore spaces in postal codes, like the other validators Follow-up to #12: cleans the input before checking, adds tests and lists postal codes in the README table. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LqqTowH2NxGHN3urqpLyyY --- README.md | 5 ++--- src/postal-code.ts | 9 +++++---- test/postal-code.test.ts | 8 ++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e0b62ee..570411b 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Only need true or false? Use `isValidCnp`, `isValidCui`, `isValidIbanRo` and `is | CNP | 13 digits, sex and century digit, real calendar date including leap years, not in the future, county code (01–52, 70), sequence not 000, control digit (key `279146358279`) | | CUI / CIF | optional `RO` prefix, 2–10 digits, no leading zero, control digit (key `753217532`) | | IBAN (RO) | 24 characters: `RO`, 2 check digits, 4-letter bank code, 16 alphanumerics, ISO 13616 mod-97 | +| Postal code | exactly 6 digits | Spaces, dots and dashes in the input are ignored. @@ -102,7 +103,7 @@ All examples in this repository are fictitious: sample CNPs use birth dates in t - [ ] Romanian licence plates - [ ] Phone numbers, normalized to `+40` -- [ ] Postal codes +- [x] Postal codes - [ ] Python port Ideas and bugs are welcome in [issues](https://github.com/Robert-GeorgeDev/ValidRO/issues). See [CONTRIBUTING.md](CONTRIBUTING.md) to get started. @@ -110,5 +111,3 @@ Ideas and bugs are welcome in [issues](https://github.com/Robert-GeorgeDev/Valid ## License [MIT](LICENSE) - - diff --git a/src/postal-code.ts b/src/postal-code.ts index fc9d4b1..b46ec52 100644 --- a/src/postal-code.ts +++ b/src/postal-code.ts @@ -1,14 +1,15 @@ -import { fail, ok, type ValidationResult } from "./result.js"; +import { clean, fail, ok, type ValidationResult } from "./result.js"; export interface PostalCodeInfo { postalCode: string; } -/** Validates the six-digit format of a Romanian postal code. */ +/** Validates the six-digit format of a Romanian postal code. Spaces, dots and dashes are ignored. */ export function validatePostalCode(input: string): ValidationResult { if (typeof input !== "string") return fail("Codul poștal trebuie să fie un șir de caractere"); - if (!/^\d{6}$/.test(input)) return fail("Codul poștal trebuie să conțină exact 6 cifre"); - return ok({ postalCode: input }); + const postalCode = clean(input); + if (!/^\d{6}$/.test(postalCode)) return fail("Codul poștal trebuie să conțină exact 6 cifre"); + return ok({ postalCode }); } export const isValidPostalCode = (input: string): boolean => validatePostalCode(input).valid; diff --git a/test/postal-code.test.ts b/test/postal-code.test.ts index 120e604..5a5d9bd 100644 --- a/test/postal-code.test.ts +++ b/test/postal-code.test.ts @@ -8,4 +8,12 @@ describe("Romanian postal code", () => { expect(isValidPostalCode("1234567")).toBe(false); expect(isValidPostalCode("12345a")).toBe(false); }); + + it("ignores spaces, like the other validators", () => { + expect(validatePostalCode(" 010 101 ").data).toEqual({ postalCode: "010101" }); + }); + + it("explains what is wrong", () => { + expect(validatePostalCode("1234").error).toContain("exact 6 cifre"); + }); });