fi-pin 0.0.6 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +101 -11
- package/dist/index.d.mts +61 -15
- package/dist/index.d.ts +61 -15
- package/dist/index.js +36 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +29 -33
- package/dist/index.mjs.map +1 -1
- package/package.json +90 -86
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2017 Marko Harjula
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Marko Harjula
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,19 +1,109 @@
|
|
|
1
|
-
|
|
1
|
+
# Finnish Person ID Check
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+

|
|
4
|
+
[](https://codeclimate.com/github/mharj/hetu/maintainability)
|
|
5
|
+
[](https://codeclimate.com/github/mharj/hetu/test_coverage)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This module provides functions to validate Finnish person IDs (Henkilötunnus) and determine the gender based on the ID. A valid Finnish person ID consists of 11 characters in the format `DDMMYYCZZZQ`, where:
|
|
10
|
+
|
|
11
|
+
- `DDMMYY` represents the date of birth.
|
|
12
|
+
- `C` is the century sign ('+' for 1800s, '-' for 1900s, 'A' for 2000s).
|
|
13
|
+
- `ZZZ` is an individual number (odd numbers are males, even numbers are females).
|
|
14
|
+
- `Q` is a checksum character.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
To install the module, run the following command:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install fi-pin
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
or direct import from unpkg (i.e., on a web page):
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import {isValidPersonId, isMale, isFemale} from 'https://unpkg.com/fi-pin@latest/dist/index.mjs';
|
|
10
28
|
```
|
|
11
29
|
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
12
32
|
```typescript
|
|
13
|
-
|
|
33
|
+
const personId = '131052-308T';
|
|
14
34
|
|
|
15
|
-
if (isValidPersonId(
|
|
16
|
-
console.log('male', isMale(
|
|
17
|
-
console.log('female', isFemale(
|
|
35
|
+
if (isValidPersonId(personId)) {
|
|
36
|
+
console.log('male', isMale(personId));
|
|
37
|
+
console.log('female', isFemale(personId));
|
|
18
38
|
}
|
|
39
|
+
|
|
40
|
+
// functions can also be extended with branded types to narrow down the type guard of the personId (as example with zod BRAND)
|
|
41
|
+
if (isValidPersonId<z.BRAND<'PersonID'>>(personId)) {
|
|
42
|
+
// personId is typed as: string & z.BRAND<'PersonID'>
|
|
43
|
+
if (isMale<z.BRAND<'MalePersonID'>>(personId)) {
|
|
44
|
+
// personId is typed as: string & z.BRAND<'PersonID'> & z.BRAND<'MalePersonID'>
|
|
45
|
+
}
|
|
46
|
+
if (isFemale<z.BRAND<'FemalePersonID'>>(personId)) {
|
|
47
|
+
// personId is typed as: string & z.BRAND<'PersonID'> & z.BRAND<'FemalePersonID'>
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Functions
|
|
53
|
+
|
|
54
|
+
### `isValidPersonId<BRAND = string>(personId: string): personId is string & BRAND`
|
|
55
|
+
|
|
56
|
+
Validates if the provided string is a valid Finnish person ID.
|
|
57
|
+
|
|
58
|
+
**Parameters:**
|
|
59
|
+
|
|
60
|
+
- `personId` - The person ID string to validate
|
|
61
|
+
|
|
62
|
+
**Returns:**
|
|
63
|
+
|
|
64
|
+
- `true` if the person ID is valid, `false` otherwise
|
|
65
|
+
|
|
66
|
+
**Example:**
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
isValidPersonId('131052-308T'); // true
|
|
70
|
+
isValidPersonId('131052-3082'); // false
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### `isMale<BRAND = string>(personId: string): personId is string & BRAND`
|
|
74
|
+
|
|
75
|
+
Checks if the provided Finnish person ID belongs to a male.
|
|
76
|
+
|
|
77
|
+
**Parameters:**
|
|
78
|
+
|
|
79
|
+
- `personId` - The Finnish person ID string
|
|
80
|
+
|
|
81
|
+
**Returns:**
|
|
82
|
+
|
|
83
|
+
- `true` if the person ID belongs to a male, `false` otherwise
|
|
84
|
+
|
|
85
|
+
**Example:**
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
isMale('131052-309U'); // true
|
|
89
|
+
isMale('131052-308T'); // false
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### `isFemale<BRAND = string>(personId: string): personId is string & BRAND`
|
|
93
|
+
|
|
94
|
+
Checks if the provided Finnish person ID belongs to a female.
|
|
95
|
+
|
|
96
|
+
**Parameters:**
|
|
97
|
+
|
|
98
|
+
- `personId` - The Finnish person ID string
|
|
99
|
+
|
|
100
|
+
**Returns:**
|
|
101
|
+
|
|
102
|
+
- `true` if the person ID belongs to a female, `false` otherwise
|
|
103
|
+
|
|
104
|
+
**Example:**
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
isFemale('131052-308T'); // true
|
|
108
|
+
isFemale('131052-309U'); // false
|
|
19
109
|
```
|
package/dist/index.d.mts
CHANGED
|
@@ -1,29 +1,75 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @
|
|
4
|
-
* @
|
|
2
|
+
* Parse string to integer
|
|
3
|
+
* @throws TypeError if value is not a number
|
|
4
|
+
* @param {string | undefined} value - string to parse
|
|
5
|
+
* @returns {number} value as number
|
|
6
|
+
* @since v0.0.7
|
|
7
|
+
*/
|
|
8
|
+
declare function parseStringToInt(value: string | undefined): number;
|
|
9
|
+
/**
|
|
10
|
+
* Validate that value is a string
|
|
11
|
+
* @throws TypeError if value is not a string
|
|
12
|
+
* @param {unknown} value - value to validate
|
|
13
|
+
* @returns {string} value as string
|
|
14
|
+
* @since v0.0.7
|
|
15
|
+
*/
|
|
16
|
+
declare function validateString(value: unknown): string;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the checksum character from the checksum index map.
|
|
19
|
+
* @param {number} index The index of the checksum character.
|
|
20
|
+
* @returns {string} The checksum character at the specified index, or undefined if the index is out of bounds.
|
|
21
|
+
* @throws {RangeError} If the index is less than 0 or greater than or equal to checkSumMapLength.
|
|
22
|
+
* @since v0.0.7
|
|
23
|
+
*/
|
|
24
|
+
declare function getCheckSum(index: number): string;
|
|
25
|
+
/**
|
|
26
|
+
* Validates whether a string is a valid Finnish person ID.
|
|
27
|
+
*
|
|
28
|
+
* A valid Finnish person ID consists of 11 characters in the format DDMMYYCZZZQ, where:
|
|
29
|
+
* - DDMMYY represents the date of birth.
|
|
30
|
+
* - C is the century sign ('+' for 1800s, '-' for 1900s, 'A' for 2000s).
|
|
31
|
+
* - ZZZ is an individual number (odd numbers are males, even numbers are females).
|
|
32
|
+
* - Q is a checksum character.
|
|
33
|
+
*
|
|
34
|
+
* The checksum character is calculated based on the first 10 characters.
|
|
35
|
+
* @param {string} personId The person ID string to validate.
|
|
36
|
+
* @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).
|
|
37
|
+
* @returns {boolean} True if the person ID is valid, false otherwise.
|
|
5
38
|
* @example
|
|
6
39
|
* isValidPersonId('131052-308T') // true
|
|
7
40
|
* isValidPersonId('131052-3082') // false
|
|
41
|
+
* const personId = '131052-308T';
|
|
42
|
+
* if (isValidPersonId<z.BRAND<'PersonID'>>(personId)) { // personId type is now: string & z.BRAND<'PersonID'>
|
|
43
|
+
* // personId type is now: string & z.BRAND<'PersonID'>
|
|
44
|
+
* }
|
|
45
|
+
* @since v0.0.1
|
|
8
46
|
*/
|
|
9
|
-
declare function isValidPersonId(personId: string):
|
|
47
|
+
declare function isValidPersonId<BRAND = string>(personId: string): personId is string & BRAND;
|
|
10
48
|
/**
|
|
11
|
-
*
|
|
12
|
-
* @
|
|
13
|
-
* @
|
|
14
|
-
* @returns
|
|
49
|
+
* Checks whether a person ID belongs to a Finnish male.
|
|
50
|
+
* @param {string} personId The Finnish person ID string.
|
|
51
|
+
* @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).
|
|
52
|
+
* @returns {boolean} True if the person ID belongs to a male, false otherwise.
|
|
53
|
+
* @throws {TypeError} If the person ID is not valid.
|
|
15
54
|
* @example
|
|
55
|
+
* isMale('131052-309U') // true
|
|
16
56
|
* isMale('131052-308T') // false
|
|
57
|
+
* isMale<z.BRAND<'PersonIdMale'>>(personId) // if true, personId type is now: string & z.BRAND<'PersonIdMale'>
|
|
58
|
+
* @since v0.0.1
|
|
17
59
|
*/
|
|
18
|
-
declare function isMale(personId: string):
|
|
60
|
+
declare function isMale<BRAND = string>(personId: string): personId is string & BRAND;
|
|
19
61
|
/**
|
|
20
|
-
*
|
|
21
|
-
* @
|
|
22
|
-
* @
|
|
23
|
-
* @returns
|
|
62
|
+
* Checks whether a person ID belongs to a Finnish female.
|
|
63
|
+
* @param {string} personId The Finnish person ID string.
|
|
64
|
+
* @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).
|
|
65
|
+
* @returns {boolean} True if the person ID belongs to a female, false otherwise.
|
|
66
|
+
* @throws {TypeError} If the person ID is not valid.
|
|
24
67
|
* @example
|
|
25
68
|
* isFemale('131052-308T') // true
|
|
69
|
+
* isFemale('131052-309U') // false
|
|
70
|
+
* isFemale<z.BRAND<'PersonIdFemale'>>(personId) // if true, personId type is now: string & z.BRAND<'PersonIdFemale'>
|
|
71
|
+
* @since v0.0.1
|
|
26
72
|
*/
|
|
27
|
-
declare function isFemale(personId: string):
|
|
73
|
+
declare function isFemale<BRAND = string>(personId: string): personId is string & BRAND;
|
|
28
74
|
|
|
29
|
-
export { isFemale, isMale, isValidPersonId };
|
|
75
|
+
export { getCheckSum, isFemale, isMale, isValidPersonId, parseStringToInt, validateString };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,29 +1,75 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @
|
|
4
|
-
* @
|
|
2
|
+
* Parse string to integer
|
|
3
|
+
* @throws TypeError if value is not a number
|
|
4
|
+
* @param {string | undefined} value - string to parse
|
|
5
|
+
* @returns {number} value as number
|
|
6
|
+
* @since v0.0.7
|
|
7
|
+
*/
|
|
8
|
+
declare function parseStringToInt(value: string | undefined): number;
|
|
9
|
+
/**
|
|
10
|
+
* Validate that value is a string
|
|
11
|
+
* @throws TypeError if value is not a string
|
|
12
|
+
* @param {unknown} value - value to validate
|
|
13
|
+
* @returns {string} value as string
|
|
14
|
+
* @since v0.0.7
|
|
15
|
+
*/
|
|
16
|
+
declare function validateString(value: unknown): string;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the checksum character from the checksum index map.
|
|
19
|
+
* @param {number} index The index of the checksum character.
|
|
20
|
+
* @returns {string} The checksum character at the specified index, or undefined if the index is out of bounds.
|
|
21
|
+
* @throws {RangeError} If the index is less than 0 or greater than or equal to checkSumMapLength.
|
|
22
|
+
* @since v0.0.7
|
|
23
|
+
*/
|
|
24
|
+
declare function getCheckSum(index: number): string;
|
|
25
|
+
/**
|
|
26
|
+
* Validates whether a string is a valid Finnish person ID.
|
|
27
|
+
*
|
|
28
|
+
* A valid Finnish person ID consists of 11 characters in the format DDMMYYCZZZQ, where:
|
|
29
|
+
* - DDMMYY represents the date of birth.
|
|
30
|
+
* - C is the century sign ('+' for 1800s, '-' for 1900s, 'A' for 2000s).
|
|
31
|
+
* - ZZZ is an individual number (odd numbers are males, even numbers are females).
|
|
32
|
+
* - Q is a checksum character.
|
|
33
|
+
*
|
|
34
|
+
* The checksum character is calculated based on the first 10 characters.
|
|
35
|
+
* @param {string} personId The person ID string to validate.
|
|
36
|
+
* @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).
|
|
37
|
+
* @returns {boolean} True if the person ID is valid, false otherwise.
|
|
5
38
|
* @example
|
|
6
39
|
* isValidPersonId('131052-308T') // true
|
|
7
40
|
* isValidPersonId('131052-3082') // false
|
|
41
|
+
* const personId = '131052-308T';
|
|
42
|
+
* if (isValidPersonId<z.BRAND<'PersonID'>>(personId)) { // personId type is now: string & z.BRAND<'PersonID'>
|
|
43
|
+
* // personId type is now: string & z.BRAND<'PersonID'>
|
|
44
|
+
* }
|
|
45
|
+
* @since v0.0.1
|
|
8
46
|
*/
|
|
9
|
-
declare function isValidPersonId(personId: string):
|
|
47
|
+
declare function isValidPersonId<BRAND = string>(personId: string): personId is string & BRAND;
|
|
10
48
|
/**
|
|
11
|
-
*
|
|
12
|
-
* @
|
|
13
|
-
* @
|
|
14
|
-
* @returns
|
|
49
|
+
* Checks whether a person ID belongs to a Finnish male.
|
|
50
|
+
* @param {string} personId The Finnish person ID string.
|
|
51
|
+
* @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).
|
|
52
|
+
* @returns {boolean} True if the person ID belongs to a male, false otherwise.
|
|
53
|
+
* @throws {TypeError} If the person ID is not valid.
|
|
15
54
|
* @example
|
|
55
|
+
* isMale('131052-309U') // true
|
|
16
56
|
* isMale('131052-308T') // false
|
|
57
|
+
* isMale<z.BRAND<'PersonIdMale'>>(personId) // if true, personId type is now: string & z.BRAND<'PersonIdMale'>
|
|
58
|
+
* @since v0.0.1
|
|
17
59
|
*/
|
|
18
|
-
declare function isMale(personId: string):
|
|
60
|
+
declare function isMale<BRAND = string>(personId: string): personId is string & BRAND;
|
|
19
61
|
/**
|
|
20
|
-
*
|
|
21
|
-
* @
|
|
22
|
-
* @
|
|
23
|
-
* @returns
|
|
62
|
+
* Checks whether a person ID belongs to a Finnish female.
|
|
63
|
+
* @param {string} personId The Finnish person ID string.
|
|
64
|
+
* @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).
|
|
65
|
+
* @returns {boolean} True if the person ID belongs to a female, false otherwise.
|
|
66
|
+
* @throws {TypeError} If the person ID is not valid.
|
|
24
67
|
* @example
|
|
25
68
|
* isFemale('131052-308T') // true
|
|
69
|
+
* isFemale('131052-309U') // false
|
|
70
|
+
* isFemale<z.BRAND<'PersonIdFemale'>>(personId) // if true, personId type is now: string & z.BRAND<'PersonIdFemale'>
|
|
71
|
+
* @since v0.0.1
|
|
26
72
|
*/
|
|
27
|
-
declare function isFemale(personId: string):
|
|
73
|
+
declare function isFemale<BRAND = string>(personId: string): personId is string & BRAND;
|
|
28
74
|
|
|
29
|
-
export { isFemale, isMale, isValidPersonId };
|
|
75
|
+
export { getCheckSum, isFemale, isMale, isValidPersonId, parseStringToInt, validateString };
|
package/dist/index.js
CHANGED
|
@@ -18,69 +18,68 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
20
|
// src/index.ts
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
getCheckSum: () => getCheckSum,
|
|
23
24
|
isFemale: () => isFemale,
|
|
24
25
|
isMale: () => isMale,
|
|
25
|
-
isValidPersonId: () => isValidPersonId
|
|
26
|
+
isValidPersonId: () => isValidPersonId,
|
|
27
|
+
parseStringToInt: () => parseStringToInt,
|
|
28
|
+
validateString: () => validateString
|
|
26
29
|
});
|
|
27
|
-
module.exports = __toCommonJS(
|
|
28
|
-
var
|
|
29
|
-
|
|
30
|
+
module.exports = __toCommonJS(index_exports);
|
|
31
|
+
var checksumCharacterSet = "0123456789ABCDEFHJKLMNPRSTUVWXY";
|
|
32
|
+
var checkSumMapLength = checksumCharacterSet.length;
|
|
33
|
+
function parseStringToInt(value) {
|
|
30
34
|
if (!value) {
|
|
31
|
-
throw new TypeError("undefined");
|
|
35
|
+
throw new TypeError("Value is undefined");
|
|
32
36
|
}
|
|
33
|
-
const
|
|
34
|
-
if (isNaN(
|
|
35
|
-
throw new TypeError(
|
|
37
|
+
const parsedValue = parseInt(value, 10);
|
|
38
|
+
if (isNaN(parsedValue)) {
|
|
39
|
+
throw new TypeError(`Value is not a number: ${value}`);
|
|
36
40
|
}
|
|
37
|
-
return
|
|
41
|
+
return parsedValue;
|
|
38
42
|
}
|
|
39
|
-
function
|
|
43
|
+
function validateString(value) {
|
|
40
44
|
if (typeof value !== "string") {
|
|
41
|
-
throw new TypeError(`${
|
|
45
|
+
throw new TypeError(`${String(value)} not a string`);
|
|
42
46
|
}
|
|
43
47
|
return value;
|
|
44
48
|
}
|
|
45
|
-
function
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
getString(personId[1]),
|
|
52
|
-
getString(personId[2]),
|
|
53
|
-
getString(personId[3]),
|
|
54
|
-
getString(personId[4]),
|
|
55
|
-
getString(personId[5]),
|
|
56
|
-
getString(personId[6]),
|
|
57
|
-
getString(personId[7]),
|
|
58
|
-
getString(personId[8]),
|
|
59
|
-
getString(personId[9]),
|
|
60
|
-
getString(personId[10])
|
|
61
|
-
];
|
|
49
|
+
function getCheckSum(index) {
|
|
50
|
+
const checkSumChar = checksumCharacterSet[index];
|
|
51
|
+
if (!checkSumChar) {
|
|
52
|
+
throw new RangeError(`Index out of bounds: ${index.toString()} (valid range: 0-${String(checkSumMapLength - 1)})`);
|
|
53
|
+
}
|
|
54
|
+
return checkSumChar;
|
|
62
55
|
}
|
|
63
56
|
function isValidPersonId(personId) {
|
|
64
|
-
if (personId.length !== 11) {
|
|
57
|
+
if (typeof personId !== "string" || personId.length !== 11) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const upperPersonId = personId.toUpperCase();
|
|
61
|
+
try {
|
|
62
|
+
return upperPersonId[10] === getCheckSum(parseStringToInt(upperPersonId.slice(0, 6) + upperPersonId.slice(7, 10)) % checkSumMapLength);
|
|
63
|
+
} catch (_error) {
|
|
65
64
|
return false;
|
|
66
65
|
}
|
|
67
|
-
const d = buildCcValues(personId.toUpperCase());
|
|
68
|
-
return d[10] === buildCheckSum(toInt(d[0] + d[1] + d[2] + d[3] + d[4] + d[5] + d[7] + d[8] + d[9]) % 31);
|
|
69
66
|
}
|
|
70
67
|
function isMale(personId) {
|
|
71
68
|
if (!isValidPersonId(personId)) {
|
|
72
|
-
throw new TypeError(
|
|
69
|
+
throw new TypeError(`${String(personId)} is not valid person id`);
|
|
73
70
|
}
|
|
74
|
-
|
|
75
|
-
return toInt(d[7] + d[8] + d[9]) % 2 === 1;
|
|
71
|
+
return parseStringToInt(personId.slice(7, 10)) % 2 === 1;
|
|
76
72
|
}
|
|
77
73
|
function isFemale(personId) {
|
|
78
74
|
return !isMale(personId);
|
|
79
75
|
}
|
|
80
76
|
// Annotate the CommonJS export names for ESM import in node:
|
|
81
77
|
0 && (module.exports = {
|
|
78
|
+
getCheckSum,
|
|
82
79
|
isFemale,
|
|
83
80
|
isMale,
|
|
84
|
-
isValidPersonId
|
|
81
|
+
isValidPersonId,
|
|
82
|
+
parseStringToInt,
|
|
83
|
+
validateString
|
|
85
84
|
});
|
|
86
85
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const checksumCharacterSet = '0123456789ABCDEFHJKLMNPRSTUVWXY';\nconst checkSumMapLength = checksumCharacterSet.length; // is always 31\n\n/**\n * Parse string to integer\n * @throws TypeError if value is not a number\n * @param {string | undefined} value - string to parse\n * @returns {number} value as number\n * @since v0.0.7\n */\nexport function parseStringToInt(value: string | undefined): number {\n\tif (!value) {\n\t\tthrow new TypeError('Value is undefined');\n\t}\n\tconst parsedValue = parseInt(value, 10);\n\tif (isNaN(parsedValue)) {\n\t\tthrow new TypeError(`Value is not a number: ${value}`);\n\t}\n\treturn parsedValue;\n}\n\n/**\n * Validate that value is a string\n * @throws TypeError if value is not a string\n * @param {unknown} value - value to validate\n * @returns {string} value as string\n * @since v0.0.7\n */\nexport function validateString(value: unknown): string {\n\tif (typeof value !== 'string') {\n\t\tthrow new TypeError(`${String(value)} not a string`);\n\t}\n\treturn value;\n}\n\n/**\n * Returns the checksum character from the checksum index map.\n * @param {number} index The index of the checksum character.\n * @returns {string} The checksum character at the specified index, or undefined if the index is out of bounds.\n * @throws {RangeError} If the index is less than 0 or greater than or equal to checkSumMapLength.\n * @since v0.0.7\n */\nexport function getCheckSum(index: number): string {\n\tconst checkSumChar = checksumCharacterSet[index];\n\tif (!checkSumChar) {\n\t\tthrow new RangeError(`Index out of bounds: ${index.toString()} (valid range: 0-${String(checkSumMapLength - 1)})`);\n\t}\n\treturn checkSumChar;\n}\n\n/**\n * Validates whether a string is a valid Finnish person ID.\n *\n * A valid Finnish person ID consists of 11 characters in the format DDMMYYCZZZQ, where:\n * - DDMMYY represents the date of birth.\n * - C is the century sign ('+' for 1800s, '-' for 1900s, 'A' for 2000s).\n * - ZZZ is an individual number (odd numbers are males, even numbers are females).\n * - Q is a checksum character.\n *\n * The checksum character is calculated based on the first 10 characters.\n * @param {string} personId The person ID string to validate.\n * @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).\n * @returns {boolean} True if the person ID is valid, false otherwise.\n * @example\n * isValidPersonId('131052-308T') // true\n * isValidPersonId('131052-3082') // false\n * const personId = '131052-308T';\n * if (isValidPersonId<z.BRAND<'PersonID'>>(personId)) { // personId type is now: string & z.BRAND<'PersonID'>\n * // personId type is now: string & z.BRAND<'PersonID'>\n * }\n * @since v0.0.1\n */\nexport function isValidPersonId<BRAND = string>(personId: string): personId is string & BRAND {\n\tif (typeof personId !== 'string' || personId.length !== 11) {\n\t\treturn false;\n\t}\n\tconst upperPersonId = personId.toUpperCase();\n\ttry {\n\t\treturn upperPersonId[10] === getCheckSum(parseStringToInt(upperPersonId.slice(0, 6) + upperPersonId.slice(7, 10)) % checkSumMapLength);\n\t} catch (_error) {\n\t\treturn false;\n\t}\n}\n\n/**\n * Checks whether a person ID belongs to a Finnish male.\n * @param {string} personId The Finnish person ID string.\n * @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).\n * @returns {boolean} True if the person ID belongs to a male, false otherwise.\n * @throws {TypeError} If the person ID is not valid.\n * @example\n * isMale('131052-309U') // true\n * isMale('131052-308T') // false\n * isMale<z.BRAND<'PersonIdMale'>>(personId) // if true, personId type is now: string & z.BRAND<'PersonIdMale'>\n * @since v0.0.1\n */\nexport function isMale<BRAND = string>(personId: string): personId is string & BRAND {\n\tif (!isValidPersonId(personId)) {\n\t\tthrow new TypeError(`${String(personId)} is not valid person id`);\n\t}\n\treturn parseStringToInt(personId.slice(7, 10)) % 2 === 1; // check if the individual number is odd\n}\n\n/**\n * Checks whether a person ID belongs to a Finnish female.\n * @param {string} personId The Finnish person ID string.\n * @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).\n * @returns {boolean} True if the person ID belongs to a female, false otherwise.\n * @throws {TypeError} If the person ID is not valid.\n * @example\n * isFemale('131052-308T') // true\n * isFemale('131052-309U') // false\n * isFemale<z.BRAND<'PersonIdFemale'>>(personId) // if true, personId type is now: string & z.BRAND<'PersonIdFemale'>\n * @since v0.0.1\n */\nexport function isFemale<BRAND = string>(personId: string): personId is string & BRAND {\n\treturn !isMale(personId);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAM,uBAAuB;AAC7B,IAAM,oBAAoB,qBAAqB;AASxC,SAAS,iBAAiB,OAAmC;AACnE,MAAI,CAAC,OAAO;AACX,UAAM,IAAI,UAAU,oBAAoB;AAAA,EACzC;AACA,QAAM,cAAc,SAAS,OAAO,EAAE;AACtC,MAAI,MAAM,WAAW,GAAG;AACvB,UAAM,IAAI,UAAU,0BAA0B,KAAK,EAAE;AAAA,EACtD;AACA,SAAO;AACR;AASO,SAAS,eAAe,OAAwB;AACtD,MAAI,OAAO,UAAU,UAAU;AAC9B,UAAM,IAAI,UAAU,GAAG,OAAO,KAAK,CAAC,eAAe;AAAA,EACpD;AACA,SAAO;AACR;AASO,SAAS,YAAY,OAAuB;AAClD,QAAM,eAAe,qBAAqB,KAAK;AAC/C,MAAI,CAAC,cAAc;AAClB,UAAM,IAAI,WAAW,wBAAwB,MAAM,SAAS,CAAC,oBAAoB,OAAO,oBAAoB,CAAC,CAAC,GAAG;AAAA,EAClH;AACA,SAAO;AACR;AAwBO,SAAS,gBAAgC,UAA8C;AAC7F,MAAI,OAAO,aAAa,YAAY,SAAS,WAAW,IAAI;AAC3D,WAAO;AAAA,EACR;AACA,QAAM,gBAAgB,SAAS,YAAY;AAC3C,MAAI;AACH,WAAO,cAAc,EAAE,MAAM,YAAY,iBAAiB,cAAc,MAAM,GAAG,CAAC,IAAI,cAAc,MAAM,GAAG,EAAE,CAAC,IAAI,iBAAiB;AAAA,EACtI,SAAS,QAAQ;AAChB,WAAO;AAAA,EACR;AACD;AAcO,SAAS,OAAuB,UAA8C;AACpF,MAAI,CAAC,gBAAgB,QAAQ,GAAG;AAC/B,UAAM,IAAI,UAAU,GAAG,OAAO,QAAQ,CAAC,yBAAyB;AAAA,EACjE;AACA,SAAO,iBAAiB,SAAS,MAAM,GAAG,EAAE,CAAC,IAAI,MAAM;AACxD;AAcO,SAAS,SAAyB,UAA8C;AACtF,SAAO,CAAC,OAAO,QAAQ;AACxB;","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,59 +1,55 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var checksumCharacterSet = "0123456789ABCDEFHJKLMNPRSTUVWXY";
|
|
3
|
+
var checkSumMapLength = checksumCharacterSet.length;
|
|
4
|
+
function parseStringToInt(value) {
|
|
4
5
|
if (!value) {
|
|
5
|
-
throw new TypeError("undefined");
|
|
6
|
+
throw new TypeError("Value is undefined");
|
|
6
7
|
}
|
|
7
|
-
const
|
|
8
|
-
if (isNaN(
|
|
9
|
-
throw new TypeError(
|
|
8
|
+
const parsedValue = parseInt(value, 10);
|
|
9
|
+
if (isNaN(parsedValue)) {
|
|
10
|
+
throw new TypeError(`Value is not a number: ${value}`);
|
|
10
11
|
}
|
|
11
|
-
return
|
|
12
|
+
return parsedValue;
|
|
12
13
|
}
|
|
13
|
-
function
|
|
14
|
+
function validateString(value) {
|
|
14
15
|
if (typeof value !== "string") {
|
|
15
|
-
throw new TypeError(`${
|
|
16
|
+
throw new TypeError(`${String(value)} not a string`);
|
|
16
17
|
}
|
|
17
18
|
return value;
|
|
18
19
|
}
|
|
19
|
-
function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
getString(personId[1]),
|
|
26
|
-
getString(personId[2]),
|
|
27
|
-
getString(personId[3]),
|
|
28
|
-
getString(personId[4]),
|
|
29
|
-
getString(personId[5]),
|
|
30
|
-
getString(personId[6]),
|
|
31
|
-
getString(personId[7]),
|
|
32
|
-
getString(personId[8]),
|
|
33
|
-
getString(personId[9]),
|
|
34
|
-
getString(personId[10])
|
|
35
|
-
];
|
|
20
|
+
function getCheckSum(index) {
|
|
21
|
+
const checkSumChar = checksumCharacterSet[index];
|
|
22
|
+
if (!checkSumChar) {
|
|
23
|
+
throw new RangeError(`Index out of bounds: ${index.toString()} (valid range: 0-${String(checkSumMapLength - 1)})`);
|
|
24
|
+
}
|
|
25
|
+
return checkSumChar;
|
|
36
26
|
}
|
|
37
27
|
function isValidPersonId(personId) {
|
|
38
|
-
if (personId.length !== 11) {
|
|
28
|
+
if (typeof personId !== "string" || personId.length !== 11) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const upperPersonId = personId.toUpperCase();
|
|
32
|
+
try {
|
|
33
|
+
return upperPersonId[10] === getCheckSum(parseStringToInt(upperPersonId.slice(0, 6) + upperPersonId.slice(7, 10)) % checkSumMapLength);
|
|
34
|
+
} catch (_error) {
|
|
39
35
|
return false;
|
|
40
36
|
}
|
|
41
|
-
const d = buildCcValues(personId.toUpperCase());
|
|
42
|
-
return d[10] === buildCheckSum(toInt(d[0] + d[1] + d[2] + d[3] + d[4] + d[5] + d[7] + d[8] + d[9]) % 31);
|
|
43
37
|
}
|
|
44
38
|
function isMale(personId) {
|
|
45
39
|
if (!isValidPersonId(personId)) {
|
|
46
|
-
throw new TypeError(
|
|
40
|
+
throw new TypeError(`${String(personId)} is not valid person id`);
|
|
47
41
|
}
|
|
48
|
-
|
|
49
|
-
return toInt(d[7] + d[8] + d[9]) % 2 === 1;
|
|
42
|
+
return parseStringToInt(personId.slice(7, 10)) % 2 === 1;
|
|
50
43
|
}
|
|
51
44
|
function isFemale(personId) {
|
|
52
45
|
return !isMale(personId);
|
|
53
46
|
}
|
|
54
47
|
export {
|
|
48
|
+
getCheckSum,
|
|
55
49
|
isFemale,
|
|
56
50
|
isMale,
|
|
57
|
-
isValidPersonId
|
|
51
|
+
isValidPersonId,
|
|
52
|
+
parseStringToInt,
|
|
53
|
+
validateString
|
|
58
54
|
};
|
|
59
55
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const checksumCharacterSet = '0123456789ABCDEFHJKLMNPRSTUVWXY';\nconst checkSumMapLength = checksumCharacterSet.length; // is always 31\n\n/**\n * Parse string to integer\n * @throws TypeError if value is not a number\n * @param {string | undefined} value - string to parse\n * @returns {number} value as number\n * @since v0.0.7\n */\nexport function parseStringToInt(value: string | undefined): number {\n\tif (!value) {\n\t\tthrow new TypeError('Value is undefined');\n\t}\n\tconst parsedValue = parseInt(value, 10);\n\tif (isNaN(parsedValue)) {\n\t\tthrow new TypeError(`Value is not a number: ${value}`);\n\t}\n\treturn parsedValue;\n}\n\n/**\n * Validate that value is a string\n * @throws TypeError if value is not a string\n * @param {unknown} value - value to validate\n * @returns {string} value as string\n * @since v0.0.7\n */\nexport function validateString(value: unknown): string {\n\tif (typeof value !== 'string') {\n\t\tthrow new TypeError(`${String(value)} not a string`);\n\t}\n\treturn value;\n}\n\n/**\n * Returns the checksum character from the checksum index map.\n * @param {number} index The index of the checksum character.\n * @returns {string} The checksum character at the specified index, or undefined if the index is out of bounds.\n * @throws {RangeError} If the index is less than 0 or greater than or equal to checkSumMapLength.\n * @since v0.0.7\n */\nexport function getCheckSum(index: number): string {\n\tconst checkSumChar = checksumCharacterSet[index];\n\tif (!checkSumChar) {\n\t\tthrow new RangeError(`Index out of bounds: ${index.toString()} (valid range: 0-${String(checkSumMapLength - 1)})`);\n\t}\n\treturn checkSumChar;\n}\n\n/**\n * Validates whether a string is a valid Finnish person ID.\n *\n * A valid Finnish person ID consists of 11 characters in the format DDMMYYCZZZQ, where:\n * - DDMMYY represents the date of birth.\n * - C is the century sign ('+' for 1800s, '-' for 1900s, 'A' for 2000s).\n * - ZZZ is an individual number (odd numbers are males, even numbers are females).\n * - Q is a checksum character.\n *\n * The checksum character is calculated based on the first 10 characters.\n * @param {string} personId The person ID string to validate.\n * @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).\n * @returns {boolean} True if the person ID is valid, false otherwise.\n * @example\n * isValidPersonId('131052-308T') // true\n * isValidPersonId('131052-3082') // false\n * const personId = '131052-308T';\n * if (isValidPersonId<z.BRAND<'PersonID'>>(personId)) { // personId type is now: string & z.BRAND<'PersonID'>\n * // personId type is now: string & z.BRAND<'PersonID'>\n * }\n * @since v0.0.1\n */\nexport function isValidPersonId<BRAND = string>(personId: string): personId is string & BRAND {\n\tif (typeof personId !== 'string' || personId.length !== 11) {\n\t\treturn false;\n\t}\n\tconst upperPersonId = personId.toUpperCase();\n\ttry {\n\t\treturn upperPersonId[10] === getCheckSum(parseStringToInt(upperPersonId.slice(0, 6) + upperPersonId.slice(7, 10)) % checkSumMapLength);\n\t} catch (_error) {\n\t\treturn false;\n\t}\n}\n\n/**\n * Checks whether a person ID belongs to a Finnish male.\n * @param {string} personId The Finnish person ID string.\n * @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).\n * @returns {boolean} True if the person ID belongs to a male, false otherwise.\n * @throws {TypeError} If the person ID is not valid.\n * @example\n * isMale('131052-309U') // true\n * isMale('131052-308T') // false\n * isMale<z.BRAND<'PersonIdMale'>>(personId) // if true, personId type is now: string & z.BRAND<'PersonIdMale'>\n * @since v0.0.1\n */\nexport function isMale<BRAND = string>(personId: string): personId is string & BRAND {\n\tif (!isValidPersonId(personId)) {\n\t\tthrow new TypeError(`${String(personId)} is not valid person id`);\n\t}\n\treturn parseStringToInt(personId.slice(7, 10)) % 2 === 1; // check if the individual number is odd\n}\n\n/**\n * Checks whether a person ID belongs to a Finnish female.\n * @param {string} personId The Finnish person ID string.\n * @template BRAND Optional brand type for a more strict type (e.g., use Zod branded type or custom type).\n * @returns {boolean} True if the person ID belongs to a female, false otherwise.\n * @throws {TypeError} If the person ID is not valid.\n * @example\n * isFemale('131052-308T') // true\n * isFemale('131052-309U') // false\n * isFemale<z.BRAND<'PersonIdFemale'>>(personId) // if true, personId type is now: string & z.BRAND<'PersonIdFemale'>\n * @since v0.0.1\n */\nexport function isFemale<BRAND = string>(personId: string): personId is string & BRAND {\n\treturn !isMale(personId);\n}\n"],"mappings":";AAAA,IAAM,uBAAuB;AAC7B,IAAM,oBAAoB,qBAAqB;AASxC,SAAS,iBAAiB,OAAmC;AACnE,MAAI,CAAC,OAAO;AACX,UAAM,IAAI,UAAU,oBAAoB;AAAA,EACzC;AACA,QAAM,cAAc,SAAS,OAAO,EAAE;AACtC,MAAI,MAAM,WAAW,GAAG;AACvB,UAAM,IAAI,UAAU,0BAA0B,KAAK,EAAE;AAAA,EACtD;AACA,SAAO;AACR;AASO,SAAS,eAAe,OAAwB;AACtD,MAAI,OAAO,UAAU,UAAU;AAC9B,UAAM,IAAI,UAAU,GAAG,OAAO,KAAK,CAAC,eAAe;AAAA,EACpD;AACA,SAAO;AACR;AASO,SAAS,YAAY,OAAuB;AAClD,QAAM,eAAe,qBAAqB,KAAK;AAC/C,MAAI,CAAC,cAAc;AAClB,UAAM,IAAI,WAAW,wBAAwB,MAAM,SAAS,CAAC,oBAAoB,OAAO,oBAAoB,CAAC,CAAC,GAAG;AAAA,EAClH;AACA,SAAO;AACR;AAwBO,SAAS,gBAAgC,UAA8C;AAC7F,MAAI,OAAO,aAAa,YAAY,SAAS,WAAW,IAAI;AAC3D,WAAO;AAAA,EACR;AACA,QAAM,gBAAgB,SAAS,YAAY;AAC3C,MAAI;AACH,WAAO,cAAc,EAAE,MAAM,YAAY,iBAAiB,cAAc,MAAM,GAAG,CAAC,IAAI,cAAc,MAAM,GAAG,EAAE,CAAC,IAAI,iBAAiB;AAAA,EACtI,SAAS,QAAQ;AAChB,WAAO;AAAA,EACR;AACD;AAcO,SAAS,OAAuB,UAA8C;AACpF,MAAI,CAAC,gBAAgB,QAAQ,GAAG;AAC/B,UAAM,IAAI,UAAU,GAAG,OAAO,QAAQ,CAAC,yBAAyB;AAAA,EACjE;AACA,SAAO,iBAAiB,SAAS,MAAM,GAAG,EAAE,CAAC,IAAI,MAAM;AACxD;AAcO,SAAS,SAAyB,UAA8C;AACtF,SAAO,CAAC,OAAO,QAAQ;AACxB;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,89 +1,93 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"extension": [
|
|
46
|
-
"ts",
|
|
47
|
-
"js"
|
|
48
|
-
],
|
|
49
|
-
"recursive": true,
|
|
50
|
-
"require": [
|
|
51
|
-
"ts-node/register",
|
|
52
|
-
"source-map-support/register"
|
|
53
|
-
],
|
|
54
|
-
"reporters": [
|
|
55
|
-
"spec",
|
|
56
|
-
"mocha-junit-reporter"
|
|
57
|
-
]
|
|
58
|
-
},
|
|
59
|
-
"keywords": [
|
|
60
|
-
"pin",
|
|
61
|
-
"personid"
|
|
2
|
+
"name": "fi-pin",
|
|
3
|
+
"version": "0.0.9",
|
|
4
|
+
"description": "Finnish Personal Identification Number validate + gender check",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"import": "./dist/index.mjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@cspell/eslint-plugin": "^8.18.0",
|
|
17
|
+
"@eslint/js": "^9.23.0",
|
|
18
|
+
"@stylistic/eslint-plugin": "^4.2.0",
|
|
19
|
+
"@stylistic/eslint-plugin-ts": "^4.2.0",
|
|
20
|
+
"@types/node": "^22.13.14",
|
|
21
|
+
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
|
22
|
+
"@typescript-eslint/parser": "^8.28.0",
|
|
23
|
+
"@vitest/coverage-v8": "^3.0.9",
|
|
24
|
+
"c8": "^10.1.3",
|
|
25
|
+
"eslint": "^9.23.0",
|
|
26
|
+
"eslint-config-prettier": "^10.1.1",
|
|
27
|
+
"eslint-import-resolver-typescript": "^4.2.5",
|
|
28
|
+
"eslint-plugin-import": "^2.31.0",
|
|
29
|
+
"eslint-plugin-jsdoc": "^50.6.9",
|
|
30
|
+
"eslint-plugin-prettier": "^5.2.5",
|
|
31
|
+
"eslint-plugin-sonarjs": "^3.0.2",
|
|
32
|
+
"source-map-support": "^0.5.21",
|
|
33
|
+
"tsup": "^8.4.0",
|
|
34
|
+
"typescript": "^5.8.2",
|
|
35
|
+
"typescript-eslint": "^8.28.0",
|
|
36
|
+
"vite": "^6.2.3",
|
|
37
|
+
"vitest": "^3.0.9",
|
|
38
|
+
"zod": "^3.24.2"
|
|
39
|
+
},
|
|
40
|
+
"mocha": {
|
|
41
|
+
"exit": true,
|
|
42
|
+
"extension": [
|
|
43
|
+
"ts",
|
|
44
|
+
"js"
|
|
62
45
|
],
|
|
63
|
-
"
|
|
64
|
-
|
|
46
|
+
"recursive": true,
|
|
47
|
+
"require": [
|
|
48
|
+
"ts-node/register",
|
|
49
|
+
"source-map-support/register"
|
|
65
50
|
],
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
"
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
51
|
+
"reporters": [
|
|
52
|
+
"spec",
|
|
53
|
+
"mocha-junit-reporter"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"keywords": [
|
|
57
|
+
"pin",
|
|
58
|
+
"personid"
|
|
59
|
+
],
|
|
60
|
+
"files": [
|
|
61
|
+
"dist"
|
|
62
|
+
],
|
|
63
|
+
"nyc": {
|
|
64
|
+
"extension": [
|
|
65
|
+
".ts"
|
|
66
|
+
],
|
|
67
|
+
"include": [
|
|
68
|
+
"src"
|
|
69
|
+
],
|
|
70
|
+
"reporter": [
|
|
71
|
+
"text",
|
|
72
|
+
"lcovonly"
|
|
73
|
+
],
|
|
74
|
+
"all": true
|
|
75
|
+
},
|
|
76
|
+
"repository": {
|
|
77
|
+
"type": "git",
|
|
78
|
+
"url": "git+https://github.com/mharj/hetu.git"
|
|
79
|
+
},
|
|
80
|
+
"author": "mharj",
|
|
81
|
+
"license": "MIT",
|
|
82
|
+
"bugs": {
|
|
83
|
+
"url": "https://github.com/mharj/hetu/issues"
|
|
84
|
+
},
|
|
85
|
+
"homepage": "https://github.com/mharj/hetu#readme",
|
|
86
|
+
"scripts": {
|
|
87
|
+
"build": "tsup src/index.ts --sourcemap --format cjs,esm --dts --clean",
|
|
88
|
+
"test": "vitest test --run --no-isolate --coverage",
|
|
89
|
+
"coverage": "vitest test --run --no-isolate --reporter=dot --coverage --coverage.reporter=lcov",
|
|
90
|
+
"lint": "eslint . --ext .ts",
|
|
91
|
+
"validate": "tsc --noEmit"
|
|
92
|
+
}
|
|
93
|
+
}
|