Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extend returning format of getDateOfBirth #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 66 additions & 66 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
{
"name": "pesel-utils",
"version": "1.0.4",
"description": "Bunch of utilities useful when working with PESEL numbers",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"files": [
"dist/index.js",
"dist/index.esm.js",
"dist/index.d.ts"
],
"author": "Antoni Kepinski <a@kepinski.me> (https://kepinski.me)",
"bugs": {
"url": "https://github.com/xxczaki/pesel-utils/issues"
},
"scripts": {
"prebuild": "del-cli dist",
"esm": "tsc --module esnext && cpy dist/index.js dist --rename index.esm.js",
"cjs": "tsc --module commonjs",
"build": "npm run esm && npm run cjs",
"test": "npm run build && xo && ava",
"prepublishOnly": "npm run build"
},
"engines": {
"node": ">=8"
},
"license": "MIT",
"repository": "xxczaki/pesel-utils",
"homepage": "https://github.com/xxczaki/pesel-utils",
"devDependencies": {
"@akepinski/tsconfig": "0.0.2",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0",
"ava": "^2.4.0",
"browser-env": "^3.2.6",
"cpy-cli": "^2.0.0",
"del-cli": "^3.0.0",
"eslint-config-xo-typescript": "^0.15.0",
"ts-node": "^8.4.1",
"typescript": "^3.6.3",
"xo": "*"
},
"sideEffects": false,
"ava": {
"babel": false,
"compileEnhancements": false,
"extensions": [
"ts"
],
"require": [
"ts-node/register"
]
},
"xo": {
"extends": "xo-typescript",
"envs": [
"browser"
],
"extensions": [
"ts"
],
"rules": {
"no-mixed-operators": "off",
"ava/no-ignored-test-files": "off"
}
}
"name": "pesel-utils",
"version": "1.0.4",
"description": "Bunch of utilities useful when working with PESEL numbers",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"files": [
"dist/index.js",
"dist/index.esm.js",
"dist/index.d.ts"
],
"author": "Antoni Kepinski <a@kepinski.me> (https://kepinski.me)",
"bugs": {
"url": "https://github.com/xxczaki/pesel-utils/issues"
},
"scripts": {
"prebuild": "del-cli dist",
"esm": "tsc --module esnext && cpy dist/index.js dist --rename index.esm.js",
"cjs": "tsc --module commonjs",
"build": "npm run esm && npm run cjs",
"test": "npm run build && xo && ava",
"prepublishOnly": "npm run build"
},
"engines": {
"node": ">=8"
},
"license": "MIT",
"repository": "xxczaki/pesel-utils",
"homepage": "https://github.com/xxczaki/pesel-utils",
"devDependencies": {
"@akepinski/tsconfig": "0.0.2",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0",
"ava": "^2.4.0",
"browser-env": "^3.2.6",
"cpy-cli": "^2.0.0",
"del-cli": "^3.0.0",
"eslint-config-xo-typescript": "^0.15.0",
"ts-node": "^8.4.1",
"typescript": "^3.6.3",
"xo": "*"
},
"sideEffects": false,
"ava": {
"babel": false,
"compileEnhancements": false,
"extensions": [
"ts"
],
"require": [
"ts-node/register"
]
},
"xo": {
"extends": "xo-typescript",
"envs": [
"browser"
],
"extensions": [
"ts"
],
"rules": {
"no-mixed-operators": "off",
"ava/no-ignored-test-files": "off"
}
}
}
53 changes: 42 additions & 11 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,55 @@

> Bunch of utilities useful when working with PESEL numbers

[![Build Status](https://travis-ci.org/xxczaki/pesel-utils.svg?branch=master)](https://travis-ci.org/xxczaki/pesel-utils)
[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo)
[![Build Status](https://travis-ci.org/xxczaki/pesel-utils.svg?branch=master)](https://travis-ci.org/xxczaki/pesel-utils)
[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo)
[![install size](https://packagephobia.now.sh/badge?p=pesel-utils)](https://packagephobia.now.sh/result?p=pesel-utils)

## Highlights

- Simple API
- 0 dependencies
- Zero dependencies
- Well tested
- Uses 4-step PESEL validation (lenght + year + month + checksum)
- Uses 4-step PESEL validation (length + year + month + checksum)
- Written in TypeScript

## Install

```
$ npm install pesel-utils
npm install pesel-utils
```

or

```
yarn add pesel-utils
```

## Usage

Add utils to your project

```js
const {isValidPesel, checkGender, getDateOfBirth} = require('pesel-utils');
const { isValidPesel, checkGender, getDateOfBirth } = require("pesel-utils");
```

or

isValidPesel('371340514609'); //=> false
checkGender('69021818876'); //=> 'male'
getDateOfBirth('75040373939'); //=> '1975/04/03'
```js
import { checkGender, getDateOfBirth, isValidPesel } from "pesel-utils";
```

then

```js
isValidPesel("371340514609"); // => false
checkGender("69021818876"); // => 'male'

getDateOfBirth("75040373939"); // => '1975/04/03'
// You can also specify a separator
getDateOfBirth("75040373939", "-"); // => '1975-04-03'
// or get it as array
getDateOfBirth("75040373939", null); // => ['1975', '04', '03']
```

## API
Expand All @@ -52,16 +75,24 @@ Type: `string`

PESEL you want to check.

### getDateOfBirth(pesel)
### getDateOfBirth(pesel, separator?)

Returns a `string` with date of birth, extracted from PESEL in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format by default.

Returns a `string` with date of birth, extracted from PESEL (in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format).
You can specify custom separator or get it as array (just set `null`).

##### pesel

Type: `string`

PESEL you want to check.

##### separator

Type: `string`

Default is `/`. If you want to get Array, set it to `null`.

## License

MIT © [Antoni Kepinski](https://kepinski.me)
79 changes: 42 additions & 37 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,46 @@
'use strict';

/**
* @param {string} pesel PESEL you want to check.
* @return {boolean} Whether the provided PESEL is valid or not.
*/
* @param {string} pesel - PESEL you want to check.
* @return {boolean} Whether the provided PESEL is valid or not.
*/
const isValidPesel = (pesel: string): boolean => {
// Basic validation
if (pesel.length !== 11) {
// Basic validation.
if (!/^[0-9]{11}$/u.test(pesel)) {
return false;
}

const arr = pesel.split('').map(e => Number(e));

const year = Number(`${arr[0]}${arr[1]}`);
const month = Number(`${arr[2]}${arr[3]}`);
const monthWithCentury = Number(pesel.substring(2, 4));

// Year validation
if (year <= 0o0 || year > 99) {
// Century is encoded in month: https://en.wikipedia.org/wiki/PESEL.
if (!monthWithCentury || monthWithCentury % 20 > 12) {
return false;
}

// Month validation
if (month <= 0o0 || month > 72) {
// Validate day.
const day = Number(pesel.substring(4, 6));
if (!day || day < 1 || day > 31) {
return false;
}

const validate = ((9 * arr[0]) + (7 * arr[1]) + (3 * arr[2]) + arr[3] + (9 * arr[4]) + (7 * arr[5]) + (3 * arr[6]) + arr[7] + (9 * arr[8]) + (7 * arr[9]));
const lastDigit = Number(validate.toString().split('').pop());
const times = [1, 3, 7, 9];
const digits: number[] = `${pesel}`
.split('')
.map(digit => Number.parseInt(digit, 10));

// Checksum check
if (lastDigit === arr[10]) {
return true;
}
const [dig11] = digits.splice(-1);

return false;
const control = digits.reduce((previousValue, currentValue, index) =>
previousValue + currentValue * times[index % 4] as number
) % 10;

return 10 - (control === 0 ? 10 : control) === dig11;
};

/**
* @param {string} pesel PESEL you want to check.
* @return {('male'|'female')} Gender (`male` or `female`).
*/
* @param {string} pesel - PESEL you want to check.
* @return {('male'|'female')} Gender (`male` or `female`).
*/
const checkGender = (pesel: string): 'male' | 'female' => {
const arr = pesel.split('').map(e => Number(e));
const arr = pesel.split('').map(Number);

const genderIdentifier = arr[9];

Expand All @@ -53,11 +52,15 @@ const checkGender = (pesel: string): 'male' | 'female' => {
};

/**
* @param {string} pesel PESEL you want to check.
* @return {string} Date of birth, extracted from PESEL (in ISO 8601 format).
*/
const getDateOfBirth = (pesel: string): string => {
const arr = pesel.split('').map(e => Number(e));
* @param {string} pesel - PESEL you want to check.
* @param {string} separator - default is `/`. If you want to get Array, set it to `null`.
* @return {string | array} Date of birth, extracted from PESEL in ISO 8601 format by default, also you can add custom separator. If separator is `null` it returns Array.
*/
const getDateOfBirth = (
pesel: string,
separator: string | null = '/',
): string | string[] => {
const arr = pesel.split('').map(Number);

const year = `${arr[0]}${arr[1]}`;
const month = Number(`${arr[2]}${arr[3]}`);
Expand Down Expand Up @@ -91,11 +94,13 @@ const getDateOfBirth = (pesel: string): string => {
formattedMonth = month - 60;
}

return `${firstDigitsofTheYear}${year}/${formattedMonth < 10 ? `0${formattedMonth}` : formattedMonth}/${day}`;
};
const birthDate: string[] = [
`${firstDigitsofTheYear}${year}`,
`${formattedMonth < 10 ? `0${formattedMonth}` : formattedMonth}`,
`${day}`,
];

export {
isValidPesel,
checkGender,
getDateOfBirth
return separator ? birthDate.join(separator) : birthDate;
};

export {isValidPesel, checkGender, getDateOfBirth};
9 changes: 9 additions & 0 deletions test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ test('get date of birth (21st century)', t => {
test('get date of birth (22nd century)', t => {
t.is(getDateOfBirth('00440345653'), '2100/04/03');
});

test('get date of birth (23rd century)', t => {
t.is(getDateOfBirth('00640345653'), '2200/04/03');
});

test('get date of birth (21st century) with custom separator', t => {
t.is(getDateOfBirth('13240376213', '-'), '2013/04/03');
});

test('get date of birth (22nd century) as array', t => {
t.is(getDateOfBirth('00440345653', null), ['2100', '04', '03']);
});
Loading