Last active
October 14, 2022 16:58
-
-
Save daliborgogic/7cce7023e7d1f3d9ff0f8a630e765aab to your computer and use it in GitHub Desktop.
Checks for a valid postcode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"scripts": { | |
"test": "vitest" | |
}, | |
"devDependencies": { | |
"vitest": "^0.24.3" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { expect, test } from 'vitest' | |
import { isGBPostcode, isPostcode } from '../src/uses/usePostcode.js' | |
test('is GB', () => { | |
expect(isGBPostcode('SW1W 0NY')).toBe(true) | |
expect(isGBPostcode('PO16 7GZ')).toBe(true) | |
expect(isGBPostcode('GU16 7HF')).toBe(true) | |
expect(isGBPostcode('L1 8JQ')).toBe(true) | |
expect(isGBPostcode('L1 8JQ$')).toBe(false) | |
}) | |
test('is DE', () => { | |
expect(isPostcode('DE', '84419')).toBe(true) | |
}) | |
test('is AT', () => { | |
expect(isPostcode('AT', '1010')).toBe(true) | |
expect(isPostcode('AT', '1423')).toBe(true) | |
expect(isPostcode('AT', '5020')).toBe(true) | |
}) | |
test('is Ireland', () => { | |
expect(isPostcode('IE', 'A65 F4E2')).toBe(true) | |
expect(isPostcode('IE', 'D02 AF30')).toBe(true) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const normalizePostcode = postcode => postcode.toUpperCase().trim().replace(/\s/g, '') | |
export const isGBPostcode = postcode => { | |
// Permitted letters depend upon their position in the postcode. | |
// https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation. | |
const ALPHA1 = '[abcdefghijklmnoprstuwyz]' // Character 1. | |
const ALPHA2 = '[abcdefghklmnopqrstuvwxy]' // Character 2. | |
const ALPHA3 = '[abcdefghjkpstuw]' // Character 3 == ABCDEFGHJKPSTUW. | |
const ALPHA4 = '[abehmnprvwxy]' // Character 4 == ABEHMNPRVWXY. | |
const ALPHA5 = '[abdefghjlnpqrstuwxyz]' // Character 5 != CIKMOV. | |
const pcexp = [] | |
// Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA. | |
pcexp[0] = `^(${ALPHA1}{1}${ALPHA2}{0,1}[0-9]{1,2})([0-9]{1}${ALPHA5}{2})$` | |
// Expression for postcodes: ANA NAA. | |
pcexp[1] = `^(${ALPHA1}{1}[0-9]{1}${ALPHA3}{1})([0-9]{1}${ALPHA5}{2})$` | |
// Expression for postcodes: AANA NAA. | |
pcexp[2] = `^(${ALPHA1}{1}${ALPHA2}[0-9]{1}${ALPHA4})([0-9]{1}${ALPHA5}{2})$` | |
// Exception for the special postcode GIR 0AA. | |
pcexp[3] = '^(gir)(0aa)$' | |
// Standard BFPO numbers. | |
pcexp[4] = '/^(bfpo)([0-9]{1,4})$/' | |
// c/o BFPO numbers. | |
pcexp[5] = '/^(bfpo)(c/o[0-9]{1,3})$/' | |
// Load up the string to check, converting into lowercase and removing spaces. | |
postcode = postcode.toLowerCase().replace(/\s/g, '') | |
// Assume we are not going to find a valid postcode. | |
let valid = false | |
// Check the string against the six types of postcodes. | |
for (const el of pcexp) { | |
if (postcode.match(el)) { | |
valid = true | |
break | |
} | |
} | |
return valid | |
} | |
export const isPostcode = (country, postcode) => { | |
// Assume we are not going to find a valid postcode. | |
let valid = true | |
if (postcode.replace(/^[\s\-A-Za-z0-9]+$/, '').trim().length > 0) { | |
return false; | |
} | |
switch (country) { | |
case 'AT': | |
valid = /^([0-9]{4})$/.test(postcode) | |
break | |
case 'BA': | |
valid = /^([7-8]{1})([0-9]{4})$/.test(postcode) | |
break | |
case 'BE': | |
valid = /^([0-9]{4})$/i.test(postcode) | |
break | |
case 'BR': | |
valid = /^([0-9]{5})([-])?([0-9]{3})$/.test(postcode) | |
break | |
case 'CH': | |
valid = /^([0-9]{4})$/i.test(postcode) | |
break | |
case 'DE': | |
valid = /^([0]{1}[1-9]{1}|[1-9]{1}[0-9]{1})[0-9]{3}$/.test(postcode) | |
break | |
case 'ES': | |
case 'FR': | |
case 'IT': | |
valid = /^([0-9]{5})$/i.test(postcode) | |
break | |
case 'GB': | |
valid = isGBPostcode(postcode) | |
break | |
case 'HU': | |
valid = /^([0-9]{4})$/i.test(postcode) | |
break | |
case 'IE': | |
valid = /([AC-FHKNPRTV-Y]\d{2}|D6W)[0-9AC-FHKNPRTV-Y]{4}/.test(normalizePostcode(postcode)) | |
break | |
case 'IN': | |
valid = /^[1-9]{1}[0-9]{2}\s{0,1}[0-9]{3}$/.test(postcode) | |
break | |
case 'JP': | |
valid = /^([0-9]{3})([-]?)([0-9]{4})$/.test(postcode) | |
break | |
case 'PT': | |
valid = /^([0-9]{4})([-])([0-9]{3})$/.test(postcode) | |
break | |
case 'PR': | |
case 'US': | |
valid = /^([0-9]{5})(-[0-9]{4})?$/i.test(postcode) | |
break | |
case 'CA': | |
// CA Postal codes cannot contain D,F,I,O,Q,U and cannot start with W or Z. https://en.wikipedia.org/wiki/Postal_codes_in_Canada#Number_of_possible_postal_codes. | |
valid = /^([ABCEGHJKLMNPRSTVXY]d[ABCEGHJKLMNPRSTVWXYZ])([ ])?(d[ABCEGHJKLMNPRSTVWXYZ]d)$/i.test(postcode) | |
break | |
case 'PL': | |
valid = /^([0-9]{2})([-])([0-9]{3})$/.test(postcode) | |
break | |
case 'CZ': | |
case 'SK': | |
valid = /^([0-9]{3})(s?)([0-9]{2})$/.test(postcode) | |
break | |
case 'NL': | |
valid = /^([1-9][0-9]{3})(s?)(?!SA|SD|SS)[A-Z]{2}$/i.test(postcode) | |
break | |
case 'SI': | |
valid = /^([1-9][0-9]{3})$/.test(postcode) | |
break | |
case 'LI': | |
valid = /^(94[8-9][0-9])$/.test(postcode) | |
break | |
default: | |
valid = true | |
break | |
} | |
return valid | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment