-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathindex.ts
More file actions
271 lines (248 loc) · 6.38 KB
/
index.ts
File metadata and controls
271 lines (248 loc) · 6.38 KB
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
/**
* @example
*
* This is an example of how to use the functions in this package.
*
* ```ts
* import {
* mykadValidator,
* mykadAge,
* mykadAge,
* mykadDOB,
* mykadState,
* mykadGender,
* readMyKadNum, } from '@razmans/mykad';
*
* const myKadNumber = 'your-mykad-number-here';
* const validate = mykadValidator(myKadNumber); // Example: true/false
* const age=mykadAge(myKadNumber); // Example: 30
* const dob=mykadDOB(myKadNumber); // Example: '1994-02-03'
* const state=mykadState(myKadNumber); // Example: 'WP Kuala Lumpur'
* const gender=mykadGender(myKadNumber);// Example: 'F' or 'M'
*
* or
* const { isValid, age, dob, state, gender } = readMyKadNum(myKadNumber)
```
*/
/**
* Read MyKad Number
* @module readMyKadNum
* @param mykad MyKad number
* @returns Object with details of the MyKad number
*/
/** Read MyKad number and return all details */
export function readMyKadNum(mykad: string): { [key: string]: any } {
// valid
if (mykadValidator(mykad)) {
return {
isValid: true,
age: mykadAge(mykad),
dob: mykadDOB(mykad),
state: mykadState(mykad),
gender: mykadGender(mykad)
};
}
// invalid
return {
isValid: false,
age: 0,
dob: 'MYKAD INVALID',
state: 'MYKAD INVALID',
gender: 'MYKAD INVALID'
};
}
/**
* MyKad Validator
* @module mykadValidator
* @param mykad MyKad number
* @returns Boolean value
*/
/** Validate MyKad number */
export function mykadValidator(mykad: string): boolean {
const regex = /^[0-9]{6}-[0-9]{2}-[0-9]{4}$/;
return regex.test(mykad);
}
/**
* MyKad Age Checker
* @module mykadAge
* @param mykad MyKad number
* @returns Age of the person
*/
/** Determine a person's age based on MyKad number */
export function mykadAge(mykad: string): number {
if (!mykadValidator(mykad)) {
return 0;
}
const year = parseInt(mykad.substring(0, 2));
const currentYear = new Date().getFullYear() % 100;
if (year > currentYear) {
return currentYear + 100 - year;
} else {
return currentYear - year;
}
}
/**
* MyKad Details Checker
* @module mykadDOB
* @param mykad MyKad number
* @returns String date in the format of YYYY-MM-DD
*/
/** Determine a person's date of birth based on MyKad number */
export function mykadDOB(mykad: string): string {
if (!mykadValidator(mykad)) {
return 'MYKAD INVALID';
}
function getYear(mykad: string) {
return parseInt(mykad.substring(0, 2));
}
function getMonth(mykad: string): string {
return mykad.substring(2, 4).padStart(2, '0');
}
function getDay(mykad: string): string {
return mykad.substring(4, 6).padStart(2, "0");
}
function isValidDayAndMonth(month: string, day: string): boolean {
const MaxDayOfMonth = {
'01': 31,
'02': 29,
'03': 31,
'04': 30,
'05': 31,
'06': 30,
'07': 31,
'08': 31,
'09': 30,
'10': 31,
'11': 30,
'12': 31
}
const isValidDay = (1 <= parseInt(day) && parseInt(day) <= 31)
const isValidMonth = (1 <= parseInt(month) && parseInt(month) <= 12)
const isDayCorrectInMonth = day <= MaxDayOfMonth[month];
// Actually, lack of LeapYear check
// e.g. 2025-02-29 INVALID
return [isValidDay, isValidMonth, isDayCorrectInMonth].every(condition => condition === true);
}
const year = getYear(mykad) // e.g. 84
const month = getMonth(mykad) // e.g '08'
const day = getDay(mykad) // e.g. 30'
// invalid
if (!isValidDayAndMonth(month, day)) return "MYKAD INVALID";
// valid day & month
const currentYear = new Date().getFullYear() % 100;
const adjustedYear = year > currentYear ? year + 1900 : year + 2000; // assume everyone < 100 years old
return `${adjustedYear}-${month}-${day}`;
}
/**
* MyKad Gender Checker
* @module mykadGender
* @param mykad MyKad number
* @returns Gender string 'F' or 'M'
*/
/** Determine a person's gender based on MyKad number */
export function mykadGender(mykad: string): string {
if (!mykadValidator(mykad)) {
return 'MYKAD INVALID';
}
return parseInt(mykad.split('-')[2]) % 2 === 0 ? 'F' : 'M';
}
/**
* MyKad State Checker
* @module mykadState
* @param mykad MyKad number
* @returns String of the state
*/
/** Determine a person's state based on MyKad number */
export function mykadState(mykad: string): string {
if (!mykadValidator(mykad)) {
return 'MYKAD INVALID';
}
const stateCode = parseInt(mykad.split('-')[1]);
const state = {
1: State.Johor,
2: State.Kedah,
3: State.Kelantan,
4: State.Melaka,
5: State.NegeriSembilan,
6: State.Pahang,
7: State.PulauPinang,
8: State.Perak,
9: State.Perlis,
10: State.Selangor,
11: State.Terengganu,
12: State.Sabah,
13: State.Sarawak,
14: State.WPKualaLumpur,
15: State.WPLabuan,
16: State.WPPutrajaya,
21: State.Johor,
22: State.Johor,
23: State.Johor,
24: State.Johor,
25: State.Kedah,
26: State.Kedah,
27: State.Kedah,
28: State.Kelantan,
29: State.Kelantan,
30: State.Melaka,
31: State.NegeriSembilan,
32: State.Pahang,
33: State.Pahang,
34: State.PulauPinang,
35: State.PulauPinang,
36: State.Perak,
37: State.Perak,
38: State.Perak,
39: State.Perak,
40: State.Perlis,
41: State.Selangor,
42: State.Selangor,
43: State.Selangor,
44: State.Selangor,
45: State.Terengganu,
46: State.Terengganu,
47: State.Sabah,
48: State.Sabah,
49: State.Sabah,
50: State.Sarawak,
51: State.Sarawak,
52: State.Sarawak,
53: State.Sarawak,
54: State.WPKualaLumpur,
55: State.WPKualaLumpur,
56: State.WPKualaLumpur,
57: State.WPKualaLumpur,
58: State.WPLabuan,
59: State.NegeriSembilan
};
return state[stateCode as keyof typeof state] || State.NotInMalaysia;
}
/**
* @module State
* @example
* ```ts
* import { State } from '@razmans/mykad';
*
* const state = State.Johor; // Example: 'Johor'
* ```
* Enum for States in Malaysia
* */
export enum State {
Johor = 'Johor',
Kedah = 'Kedah',
Kelantan = 'Kelantan',
Melaka = 'Melaka',
NegeriSembilan = 'Negeri Sembilan',
Pahang = 'Pahang',
PulauPinang = 'Pulau Pinang',
Perak = 'Perak',
Perlis = 'Perlis',
Selangor = 'Selangor',
Terengganu = 'Terengganu',
Sabah = 'Sabah',
Sarawak = 'Sarawak',
WPKualaLumpur = 'WP Kuala Lumpur',
WPLabuan = 'WP Labuan',
WPPutrajaya = 'WP Putrajaya',
NotInMalaysia = 'Not in Malaysia'
}