Skip to content

Commit dc920b9

Browse files
committed
getting tehre
1 parent 92eee4c commit dc920b9

File tree

7 files changed

+103
-134
lines changed

7 files changed

+103
-134
lines changed

packages/validator/README.md

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![NPM Version](https://img.shields.io/npm/v/%40obosbbl%2Fvalidation)](https://www.npmjs.com/package/@obosbbl/validation)
44

55

6-
A collection of validation methods for both 🇳🇴 and 🇸🇪 with zero dependencies. Integrates neatly with [Zod](https://github.com/colinhacks/zod).
6+
A collection of validation methods for both 🇳🇴 and 🇸🇪 with zero dependencies.
77

88
## Install
99

@@ -22,37 +22,72 @@ The package has two entrypoints, one for `no` and one for `se`. That allows you
2222

2323
```js
2424
// 🇳🇴 example
25-
import { postalCodeValidator } from '@obosbbl/validation/no';
26-
postalCodeValidator('0000') // => true
25+
import { validateOrganizationNumber } from '@obosbbl/validation/no';
26+
validateOrganizationNumber('937052766') // => true
2727

28-
postalCodeValidator('00000') // => false
28+
validateOrganizationNumber('000') // => false
2929

3030
// 🇸🇪 example
31-
import { postalCodeValidator } from '@obosbbl/validation/no';
32-
postalCodeValidator('00000') // => true
33-
postalCodeValidator('00 000') // => true
31+
import { validateOrganizationNumer } from '@obosbbl/validation/se';
32+
validateOrganizationNumber('5592221054') // => true
3433

35-
postalCodeValidator('000 000') // => false
34+
validateOrganizationNumber('000') // => false
3635
```
3736

38-
## Strictness
37+
## Strictness and formatting characters
38+
39+
The methods are "strict" by default, meaning no formatting characters in the input is allowed.
40+
This is preferrable, for instance when doing server-side validation, where the input is often expected to be a "clean" value.
41+
42+
If you want to allow formatting characters in the input, you can pass `allowFormatting: true` in the options object to the method.
43+
Note that this currently allows any formatting characters, not just the just the "expected" ones for the input type.
3944

40-
By default, the methods allows formatting characters when validating. If you need strict validation, you can pass the `strict` option to the method.
4145

4246
```js
4347
import { validateOrganizationNumber } from '@obosbbl/validation/no';
4448

45-
validateOrganizationNumber('937 052 766') // true;
46-
47-
validateOrganizationNumber('937052766', { strict: true }) // true;
48-
validateOrganizationNumber('937 052 766', { strict: true }) // false;
49+
validateOrganizationNumber('937052766') // true
50+
// formatting characters disallowed by default
51+
validateOrganizationNumber('937 052 766') // false;
52+
// allow formatting characters
53+
validateOrganizationNumber('937 052 766', { allowFormatting: true }) // true;
4954
```
5055

51-
```js
52-
5356
## Methods
5457

5558
* validatePostalCode
5659
* validatePhoneNumber
57-
* supports mobileOnly option
60+
* supports mobileOnly option
5861
* validateOrganizationNumber
62+
* 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.
63+
64+
## Example usage with Zod
65+
66+
```js
67+
import { z } from 'zod';
68+
import { validatePhoneNumber } from '@obosbbl/validation/no';
69+
70+
const mobileOnlySchema = z.object({
71+
name: z.string(),
72+
phoneNumber: z
73+
.string()
74+
.refine(
75+
(val) => validatePhoneNumber(val, { mobileOnly: true }),
76+
'Telefonnummeret er ikke et gyldig mobilnummer',
77+
),
78+
});
79+
80+
const validData = {
81+
name: 'Kari Nordmann',
82+
phoneNumber: '92345678',
83+
};
84+
85+
mobileOnlySchema.parse(validData); // => { name: 'Kari Nordmann', phoneNumber: '92345678' }
86+
87+
const invalidData = {
88+
name: 'Ola Nordmann',
89+
phoneNumber: '22865500',
90+
}
91+
92+
mobileOnlySchema.parse(invalidData); // => throws ZodError
93+
```

packages/validator/package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,5 @@
2323
],
2424
"scripts": {
2525
"build": "bunchee"
26-
},
27-
"devDependencies": {
28-
"zod": "^3.24.1"
2926
}
3027
}

packages/validator/src/no.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export function validatePostalCode(
1515
options: PostalCodeOptions = {},
1616
): boolean {
1717
if (options.allowFormatting) {
18+
// biome-ignore lint/style/noParameterAssign:
1819
value = stripFormatting(value);
1920
}
2021

@@ -44,6 +45,7 @@ export function validatePhoneNumber(
4445
options: PhoneNumberOptions = {},
4546
): boolean {
4647
if (options.allowFormatting) {
48+
// biome-ignore lint/style/noParameterAssign:
4749
value = stripFormatting(value);
4850
}
4951

@@ -72,6 +74,7 @@ export function validateOrganizationNumber(
7274
options: PhoneNumberOptions = {},
7375
): boolean {
7476
if (options.allowFormatting) {
77+
// biome-ignore lint/style/noParameterAssign:
7578
value = stripFormatting(value);
7679
}
7780

packages/validator/src/se.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ export function validatePostalCode(
1515
options: PostalCodeOptions = {},
1616
): boolean {
1717
if (options.allowFormatting) {
18+
// biome-ignore lint/style/noParameterAssign:
1819
value = stripFormatting(value);
1920
}
2021

21-
return /^\d{3} ?\d{2}$/.test(value);
22+
return /^\d{5}$/.test(value);
2223
}
2324

2425
type PhoneNumberOptions = ValidatorOptions & {
@@ -46,6 +47,7 @@ export function validatePhoneNumber(
4647
options: PhoneNumberOptions = {},
4748
): boolean {
4849
if (options.allowFormatting) {
50+
// biome-ignore lint/style/noParameterAssign:
4951
value = stripFormatting(value);
5052
}
5153

@@ -72,8 +74,9 @@ export function validateOrganizationNumber(
7274
value: string,
7375
options: OrganizationNumberOptions = {},
7476
): boolean {
75-
// TODO: Implement proper validation
77+
// TODO: Implement checksum validation. For now it only checks the number of digits.
7678
if (options.allowFormatting) {
79+
// biome-ignore lint/style/noParameterAssign:
7780
value = stripFormatting(value);
7881
}
7982

packages/validator/src/validation.test.ts

Lines changed: 42 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,19 @@ import * as se from './se';
55
describe('no', () => {
66
test.each([
77
['0179', true],
8-
98
['01790', false],
109
['not a number', false],
11-
])('validatePostalCode()', (input, expected) => {
10+
])('validatePostalCode(%s) -> %s', (input, expected) => {
1211
expect(no.validatePostalCode(input)).toBe(expected);
1312
});
1413

1514
test.each([
16-
['22865500', true],
17-
['90000000', true],
18-
['40000000', true],
19-
['22 86 55 00', false],
20-
['000', false],
21-
['000000000', false],
15+
['22865500', true, undefined],
16+
['90000000', true, undefined],
17+
['40000000', true, undefined],
18+
['22 86 55 00', false, undefined],
19+
['000', false, undefined],
20+
['000000000', false, undefined],
2221

2322
// formatting
2423
['22 86 55 00', false, { allowFormatting: false }],
@@ -28,102 +27,65 @@ describe('no', () => {
2827
['22865500', false, { mobileOnly: true }],
2928
['90000000', true, { mobileOnly: true }],
3029
['40000000', true, { mobileOnly: true }],
31-
])('validatePhoneNumber()', (input, expected, options) => {
30+
])('validatePhoneNumber(%s) -> %s', (input, expected, options) => {
3231
expect(no.validatePhoneNumber(input, options)).toBe(expected);
3332
});
3433

3534
test.each([
36-
['937052766', true],
37-
['937 052 766', false],
38-
['435256151', false],
39-
['not a number', false],
40-
['A37 052 766', false],
35+
['937052766', true, undefined],
36+
['937 052 766', false, undefined],
37+
['435256151', false, undefined],
38+
['not a number', false, undefined],
39+
['A37 052 766', false, undefined],
4140

4241
// formatting
4342
['937 052 766', false, { allowFormatting: false }],
4443
['937 052 766', true, { allowFormatting: true }],
45-
])('validateOrganizationNumber()', (input, expected) => {
46-
expect(no.validateOrganizationNumber(input)).toBe(expected);
44+
])('validateOrganizationNumber(%s) -> %s', (input, expected, options) => {
45+
expect(no.validateOrganizationNumber(input, options)).toBe(expected);
4746
});
4847
});
4948

5049
describe('se', () => {
5150
test.each([
52-
['00000', true],
53-
['000 00', true],
51+
['00000', true, undefined],
52+
['000 00', false, undefined],
53+
['not a number', false, undefined],
5454

55-
// strictness
56-
['000 00', false, { strict: true }],
57-
58-
['00', false],
59-
['not a number', false],
60-
])('validatePostalCode()', (input, expected) => {
61-
expect(se.validatePostalCode(input)).toBe(expected);
55+
// formatting
56+
['000 00', false, { allowFormatting: false }],
57+
['000 00', true, { allowFormatting: true }],
58+
])('validatePostalCode(%s) -> %s', (input, expected, options) => {
59+
expect(se.validatePostalCode(input, options)).toBe(expected);
6260
});
6361

6462
test.each([
65-
['22865500', true],
66-
['22 86 55 00', true],
67-
['90000000', true],
68-
['40000000', true],
69-
['000', false],
70-
['000000000', false],
63+
['08123456', true, undefined],
64+
['0812345', false, undefined],
65+
['031123456', true, undefined],
66+
['030312345678', false, undefined],
7167

72-
// strictness
73-
['22 86 55 00', false, { strict: true }],
68+
// formatting
69+
['031-123 45', true, { allowFormatting: true }],
70+
['031-123 45', false, { allowFormatting: false }],
7471

7572
// mobile only
76-
['22 86 55 00', false, { mobileOnly: true }],
77-
['900 00 000', true, { mobileOnly: true }],
78-
['400 00 000', true, { mobileOnly: true }],
79-
])('validatePhoneNumber()', (input, expected, options) => {
73+
['0701234567', true, { mobileOnly: true }],
74+
['031123456', false, { mobileOnly: true }],
75+
])('validatePhoneNumber(%s) -> %s', (input, expected, options) => {
8076
expect(se.validatePhoneNumber(input, options)).toBe(expected);
8177
});
8278

8379
test.each([
84-
['937052766', true],
85-
['937 052 766', true],
80+
['5592221054', true, undefined],
81+
['559222-1054', false, undefined],
82+
['559222105', false, undefined],
83+
['55922210546', false, undefined],
8684

87-
['A37 052 766', false],
88-
['435 256 151', false],
89-
['not a number', false],
90-
])('validateOrganizationNumber()', (input, expected) => {
91-
expect(se.validateOrganizationNumber(input)).toBe(expected);
85+
// formatting
86+
['559222-1054', false, { allowFormatting: false }],
87+
['559222-1054', true, { allowFormatting: true }],
88+
])('validateOrganizationNumber(%s) -> %s', (input, expected, options) => {
89+
expect(se.validateOrganizationNumber(input, options)).toBe(expected);
9290
});
9391
});
94-
95-
// describe('no', () => {
96-
// describe('validatePostalCode', () => {
97-
// test('correctly validates postal codes', () => {
98-
// expect(validatePostalCodeSe('100 26')).toBeTruthy();
99-
// expect(validatePostalCodeSe('10026')).toBeTruthy();
100-
101-
// expect(validatePostalCodeSe('100426')).toBeFalsy();
102-
// expect(validatePostalCodeSe('177')).toBeFalsy();
103-
// expect(validatePostalCodeSe(Number.NaN.toString())).toBeFalsy();
104-
// expect(validatePostalCodeSe('not a number')).toBeFalsy();
105-
// });
106-
// });
107-
108-
// describe('validatePhoneNumber()', () => {
109-
// test('validates phone numbers', () => {
110-
// // should be 8 to 10 digits
111-
// expect(validatePhoneNumberSe('08123456')).toBeTruthy();
112-
// expect(validatePhoneNumberSe('031123456')).toBeTruthy();
113-
// expect(validatePhoneNumberSe('0311234567')).toBeTruthy();
114-
115-
// // too short
116-
// expect(validatePhoneNumberSe('0812345')).toBeFalsy();
117-
// // too long
118-
// expect(validatePhoneNumberSe('0303123456789')).toBeFalsy();
119-
120-
// // cannot start with something other than 0
121-
// expect(validatePhoneNumberSe('12345678')).toBeFalsy();
122-
123-
// // A Swedish mobile number is always 10 digits and starts with 07
124-
// expect(
125-
// validatePhoneNumberSe('0712345678', { mobileOnly: true }),
126-
// ).toBeTruthy();
127-
// });
128-
// });
129-
// });

packages/validator/src/zod.test.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.

pnpm-lock.yaml

Lines changed: 1 addition & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)