From e0e2d6b3f7c2db1b4d70d51fb1e246bd72fc9c22 Mon Sep 17 00:00:00 2001 From: Alexander Bjerkan Date: Thu, 13 Feb 2025 13:38:50 +0100 Subject: [PATCH] validation: add validateObosMembershipNumber() --- .changeset/cool-planes-exercise.md | 5 ++++ packages/validation/README.md | 6 ++++- packages/validation/src/no.ts | 19 +++++++++++++++ packages/validation/src/se.ts | 3 +++ packages/validation/src/validation.test.ts | 28 ++++++++++++++++++++++ 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 .changeset/cool-planes-exercise.md diff --git a/.changeset/cool-planes-exercise.md b/.changeset/cool-planes-exercise.md new file mode 100644 index 0000000..15c6e80 --- /dev/null +++ b/.changeset/cool-planes-exercise.md @@ -0,0 +1,5 @@ +--- +"@obosbbl/validation": minor +--- + +feat: add method `validateObosMembershipNumber()` to validate if the input value is a valid OBOS membership number. diff --git a/packages/validation/README.md b/packages/validation/README.md index af96695..99e6340 100644 --- a/packages/validation/README.md +++ b/packages/validation/README.md @@ -28,7 +28,7 @@ validateOrganizationNumber('937052766') // => true validateOrganizationNumber('000') // => false // πŸ‡ΈπŸ‡ͺ example -import { validateOrganizationNumer } from '@obosbbl/validation/se'; +import { validateOrganizationNumber } from '@obosbbl/validation/se'; validateOrganizationNumber('5592221054') // => true validateOrganizationNumber('000') // => false @@ -47,8 +47,10 @@ Note that this currently allows any formatting characters, not just the just the import { validateOrganizationNumber } from '@obosbbl/validation/no'; validateOrganizationNumber('937052766') // true + // formatting characters disallowed by default validateOrganizationNumber('937 052 766') // false; + // allow formatting characters validateOrganizationNumber('937 052 766', { allowFormatting: true }) // true; ``` @@ -60,6 +62,8 @@ validateOrganizationNumber('937 052 766', { allowFormatting: true }) // true; * supports mobileOnly option * validateOrganizationNumber * Check digit verification is currently only implemented for Norwegian organization numbers. For Swedish organiation numbers, we only check the length of the input. PRs are welcome to fix this. +* validateObosMembershipNumber + ## Example usage with Zod diff --git a/packages/validation/src/no.ts b/packages/validation/src/no.ts index ccf200c..e4135b7 100644 --- a/packages/validation/src/no.ts +++ b/packages/validation/src/no.ts @@ -84,3 +84,22 @@ export function validateOrganizationNumber( */ return mod11(value, [3, 2, 7, 6, 5, 4, 3, 2]); } + +/** + * Validates that the input value is an OBOS membership number. + * @example + * ``` + * validateObosMembershipNumber('0000000') // => true + * ``` + */ +export function validateObosMembershipNumber( + value: string, + options: PostalCodeOptions = {}, +): boolean { + if (options.allowFormatting) { + // biome-ignore lint/style/noParameterAssign: + value = stripFormatting(value); + } + + return /^\d{7}$/.test(value); +} diff --git a/packages/validation/src/se.ts b/packages/validation/src/se.ts index fdf41d0..1c1313a 100644 --- a/packages/validation/src/se.ts +++ b/packages/validation/src/se.ts @@ -83,3 +83,6 @@ export function validateOrganizationNumber( return /^\d{10}$/.test(value); } + +// just reexport the no method for API feature parity +export { validateObosMembershipNumber } from './no'; diff --git a/packages/validation/src/validation.test.ts b/packages/validation/src/validation.test.ts index 325512d..bf7d7c6 100644 --- a/packages/validation/src/validation.test.ts +++ b/packages/validation/src/validation.test.ts @@ -44,6 +44,20 @@ describe('no', () => { ])('validateOrganizationNumber(%s) -> %s', (input, expected, options) => { expect(no.validateOrganizationNumber(input, options)).toBe(expected); }); + + test.each([ + ['1234567', true, undefined], + // too short + ['123456', false, undefined], + // too long + ['12345678', false, undefined], + + // formatting + ['123 45 67', false, { allowFormatting: false }], + ['123 45 67', true, { allowFormatting: true }], + ])('validateObosMembershipNumber(%s) -> %s', (input, expected, options) => { + expect(no.validateObosMembershipNumber(input, options)).toBe(expected); + }); }); describe('se', () => { @@ -101,4 +115,18 @@ describe('se', () => { ])('validateOrganizationNumber(%s) -> %s', (input, expected, options) => { expect(se.validateOrganizationNumber(input, options)).toBe(expected); }); + + test.each([ + ['1234567', true, undefined], + // too short + ['123456', false, undefined], + // too long + ['12345678', false, undefined], + + // formatting + ['123 45 67', false, { allowFormatting: false }], + ['123 45 67', true, { allowFormatting: true }], + ])('validateObosMembershipNumber(%s) -> %s', (input, expected, options) => { + expect(se.validateObosMembershipNumber(input, options)).toBe(expected); + }); });