nik-id 1.0.0

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.
@@ -0,0 +1,81 @@
1
+ import { NIKResult } from './types.js';
2
+
3
+ /**
4
+ * Modul parsing NIK (Nomor Induk Kependudukan).
5
+ *
6
+ * Menyediakan fungsi {@link parseNIK} yang memvalidasi dan mengekstrak
7
+ * semua komponen dari NIK: kode wilayah (provinsi, kabupaten/kota, kecamatan),
8
+ * tanggal lahir, jenis kelamin, dan nomor urut registrasi.
9
+ *
10
+ * Kode wilayah yang dikembalikan menggunakan format **Kemendagri** (bukan BPS).
11
+ * Untuk resolve ke nama wilayah, gunakan package `kode-wilayah-id` dengan
12
+ * fungsi `getProvinceByKemendagriCode()`, `getRegencyByKemendagriCode()`, dll.
13
+ *
14
+ * @module parse
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { parseNIK } from 'nik-id/parse';
19
+ *
20
+ * const result = parseNIK("3204076508850001");
21
+ * if (result.valid) {
22
+ * console.log(result.provinceCode); // "32"
23
+ * console.log(result.regencyCode); // "3204"
24
+ * console.log(result.districtCode); // "320407"
25
+ * console.log(result.gender); // "F"
26
+ * console.log(result.birthDate); // Date: 1985-08-25
27
+ * console.log(result.sequenceNumber); // "0001"
28
+ * }
29
+ * ```
30
+ */
31
+
32
+ /**
33
+ * Parse NIK menjadi komponen-komponennya.
34
+ *
35
+ * Fungsi ini pertama memvalidasi NIK menggunakan {@link validateNIK},
36
+ * kemudian mengekstrak setiap komponen ke dalam object {@link NIKResult}.
37
+ *
38
+ * Komponen yang diekstrak:
39
+ * - **provinceCode** — kode provinsi Kemendagri (2 digit)
40
+ * - **regencyCode** — kode kabupaten/kota Kemendagri (4 digit)
41
+ * - **districtCode** — kode kecamatan Kemendagri (6 digit)
42
+ * - **birthDate** — tanggal lahir sebagai `Date` object
43
+ * - **gender** — jenis kelamin (`"M"` atau `"F"`)
44
+ * - **sequenceNumber** — nomor urut registrasi (4 digit)
45
+ *
46
+ * @param nik - String NIK 16 digit yang akan di-parse
47
+ * @returns {@link NIKResult} — discriminated union yang bisa di-narrow
48
+ * menggunakan `result.valid`
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const result = parseNIK("3204076508850001");
53
+ * if (result.valid) {
54
+ * // result bertipe NIKValid — semua field tersedia
55
+ * console.log(result.provinceCode); // "32"
56
+ * console.log(result.regencyCode); // "3204"
57
+ * console.log(result.districtCode); // "320407"
58
+ * console.log(result.birthDate); // Date: 1985-08-25
59
+ * console.log(result.gender); // "F"
60
+ * console.log(result.sequenceNumber); // "0001"
61
+ * } else {
62
+ * // result bertipe NIKInvalid — ada error
63
+ * console.log(result.error); // "NIK harus 16 digit"
64
+ * }
65
+ * ```
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * // Integrasi dengan kode-wilayah-id
70
+ * import { getProvinceByKemendagriCode } from 'kode-wilayah-id';
71
+ *
72
+ * const result = parseNIK("3204076508850001");
73
+ * if (result.valid) {
74
+ * const prov = getProvinceByKemendagriCode(result.provinceCode);
75
+ * console.log(prov?.name); // "JAWA BARAT"
76
+ * }
77
+ * ```
78
+ */
79
+ declare function parseNIK(nik: string): NIKResult;
80
+
81
+ export { parseNIK };
package/dist/parse.js ADDED
@@ -0,0 +1,84 @@
1
+ // src/utils.ts
2
+ function disambiguateYear(yy) {
3
+ const currentYY = (/* @__PURE__ */ new Date()).getFullYear() % 100;
4
+ return yy > currentYY ? 1900 + yy : 2e3 + yy;
5
+ }
6
+
7
+ // src/validate.ts
8
+ var MIN_PROVINCE_CODE = 11;
9
+ var MAX_PROVINCE_CODE = 97;
10
+ var NIK_LENGTH = 16;
11
+ var DIGITS_ONLY_PATTERN = /^\d{16}$/;
12
+ function isValidCalendarDate(year, month, day) {
13
+ const date = new Date(year, month - 1, day);
14
+ return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
15
+ }
16
+ function validateNIK(nik) {
17
+ if (typeof nik !== "string") {
18
+ return { valid: false, error: "NIK harus berupa string" };
19
+ }
20
+ if (nik.length !== NIK_LENGTH) {
21
+ return { valid: false, error: "NIK harus 16 digit" };
22
+ }
23
+ if (!DIGITS_ONLY_PATTERN.test(nik)) {
24
+ return { valid: false, error: "NIK hanya boleh berisi angka" };
25
+ }
26
+ const provinceCode = Number.parseInt(nik.substring(0, 2), 10);
27
+ if (provinceCode < MIN_PROVINCE_CODE || provinceCode > MAX_PROVINCE_CODE) {
28
+ return { valid: false, error: "Kode provinsi tidak valid" };
29
+ }
30
+ const dd = Number.parseInt(nik.substring(6, 8), 10);
31
+ const mm = Number.parseInt(nik.substring(8, 10), 10);
32
+ const yy = Number.parseInt(nik.substring(10, 12), 10);
33
+ const isValidMaleDD = dd >= 1 && dd <= 31;
34
+ const isValidFemaleDD = dd >= 41 && dd <= 71;
35
+ if (!isValidMaleDD && !isValidFemaleDD) {
36
+ return { valid: false, error: "Tanggal lahir tidak valid" };
37
+ }
38
+ if (mm < 1 || mm > 12) {
39
+ return { valid: false, error: "Tanggal lahir tidak valid" };
40
+ }
41
+ const actualDay = isValidFemaleDD ? dd - 40 : dd;
42
+ const fullYear = disambiguateYear(yy);
43
+ if (!isValidCalendarDate(fullYear, mm, actualDay)) {
44
+ return { valid: false, error: "Tanggal lahir tidak valid" };
45
+ }
46
+ const seq = nik.substring(12, 16);
47
+ if (seq === "0000") {
48
+ return { valid: false, error: "Nomor urut tidak valid" };
49
+ }
50
+ return { valid: true };
51
+ }
52
+
53
+ // src/parse.ts
54
+ function parseNIK(nik) {
55
+ const validation = validateNIK(nik);
56
+ if (!validation.valid) {
57
+ return { valid: false, error: validation.error };
58
+ }
59
+ const provinceCode = nik.substring(0, 2);
60
+ const regencyCode = nik.substring(0, 4);
61
+ const districtCode = nik.substring(0, 6);
62
+ const dd = Number.parseInt(nik.substring(6, 8), 10);
63
+ const mm = Number.parseInt(nik.substring(8, 10), 10);
64
+ const yy = Number.parseInt(nik.substring(10, 12), 10);
65
+ const isFemale = dd > 40;
66
+ const actualDay = isFemale ? dd - 40 : dd;
67
+ const gender = isFemale ? "F" : "M";
68
+ const fullYear = disambiguateYear(yy);
69
+ const birthDate = new Date(fullYear, mm - 1, actualDay);
70
+ const sequenceNumber = nik.substring(12, 16);
71
+ return {
72
+ valid: true,
73
+ nik,
74
+ provinceCode,
75
+ regencyCode,
76
+ districtCode,
77
+ birthDate,
78
+ gender,
79
+ sequenceNumber
80
+ };
81
+ }
82
+ export {
83
+ parseNIK
84
+ };
package/dist/types.cjs ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Definisi tipe data untuk parsing dan validasi NIK (Nomor Induk Kependudukan).
3
+ *
4
+ * NIK adalah nomor identitas penduduk Indonesia yang terdiri dari 16 digit:
5
+ * - Digit 1-2: kode provinsi (format Kemendagri)
6
+ * - Digit 3-4: kode kabupaten/kota (format Kemendagri)
7
+ * - Digit 5-6: kode kecamatan (format Kemendagri)
8
+ * - Digit 7-12: tanggal lahir (DDMMYY, perempuan DD+40)
9
+ * - Digit 13-16: nomor urut registrasi
10
+ *
11
+ * Semua kode wilayah menggunakan format **Kemendagri** (bukan BPS).
12
+ * Kalau butuh resolve ke nama wilayah, bisa pakai package `kode-wilayah-id`
13
+ * dengan fungsi `getProvinceByKemendagriCode()`, `getRegencyByKemendagriCode()`, dll.
14
+ *
15
+ * @module types
16
+ */
17
+ /**
18
+ * Hasil parsing NIK yang valid — berisi semua komponen NIK yang sudah diekstrak.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const result = parseNIK("3204076508850001");
23
+ * if (result.valid) {
24
+ * console.log(result.provinceCode); // "32"
25
+ * console.log(result.regencyCode); // "3204"
26
+ * console.log(result.districtCode); // "320407"
27
+ * console.log(result.gender); // "F"
28
+ * console.log(result.birthDate); // Date: 1985-08-25
29
+ * console.log(result.sequenceNumber); // "0001"
30
+ * }
31
+ * ```
32
+ */
33
+ interface NIKValid {
34
+ /** Selalu `true` — gunakan untuk narrowing discriminated union */
35
+ valid: true;
36
+ /** NIK asli yang di-parse (16 digit) */
37
+ nik: string;
38
+ /**
39
+ * Kode provinsi Kemendagri (2 digit).
40
+ * Contoh: `"32"` untuk Jawa Barat, `"11"` untuk Aceh.
41
+ *
42
+ * Bisa dipakai dengan `kode-wilayah-id`:
43
+ * ```typescript
44
+ * import { getProvinceByKemendagriCode } from 'kode-wilayah-id';
45
+ * const prov = getProvinceByKemendagriCode(result.provinceCode);
46
+ * ```
47
+ */
48
+ provinceCode: string;
49
+ /**
50
+ * Kode kabupaten/kota Kemendagri (4 digit).
51
+ * Contoh: `"3204"` untuk Kab. Bandung.
52
+ */
53
+ regencyCode: string;
54
+ /**
55
+ * Kode kecamatan Kemendagri (6 digit).
56
+ * Contoh: `"320407"` untuk Kec. Nagreg.
57
+ */
58
+ districtCode: string;
59
+ /**
60
+ * Tanggal lahir yang sudah di-parse menjadi object `Date`.
61
+ * Tahun 2 digit disambiguasi: `YY > tahunSekarang` → 1900+YY, else 2000+YY.
62
+ */
63
+ birthDate: Date;
64
+ /** Jenis kelamin: `"M"` (laki-laki) atau `"F"` (perempuan) */
65
+ gender: "M" | "F";
66
+ /** Nomor urut registrasi di kecamatan (4 digit, `"0001"`–`"9999"`) */
67
+ sequenceNumber: string;
68
+ }
69
+ /**
70
+ * Hasil parsing NIK yang tidak valid — berisi pesan error.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const result = parseNIK("123");
75
+ * if (!result.valid) {
76
+ * console.log(result.error); // "NIK harus 16 digit"
77
+ * }
78
+ * ```
79
+ */
80
+ interface NIKInvalid {
81
+ /** Selalu `false` — gunakan untuk narrowing discriminated union */
82
+ valid: false;
83
+ /** Pesan error dalam bahasa Indonesia yang menjelaskan kenapa NIK tidak valid */
84
+ error: string;
85
+ }
86
+ /**
87
+ * Discriminated union hasil parsing NIK.
88
+ *
89
+ * Gunakan `result.valid` untuk narrowing:
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const result = parseNIK(input);
94
+ * if (result.valid) {
95
+ * // result bertipe NIKValid — semua field tersedia
96
+ * console.log(result.gender);
97
+ * } else {
98
+ * // result bertipe NIKInvalid — ada error
99
+ * console.log(result.error);
100
+ * }
101
+ * ```
102
+ */
103
+ type NIKResult = NIKValid | NIKInvalid;
104
+ /**
105
+ * Hasil validasi NIK yang valid.
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const result = validateNIK("3204076508850001");
110
+ * if (result.valid) {
111
+ * console.log("NIK valid!");
112
+ * }
113
+ * ```
114
+ */
115
+ interface ValidationValid {
116
+ /** Selalu `true` */
117
+ valid: true;
118
+ }
119
+ /**
120
+ * Hasil validasi NIK yang tidak valid.
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * const result = validateNIK("123");
125
+ * if (!result.valid) {
126
+ * console.log(result.error); // "NIK harus 16 digit"
127
+ * }
128
+ * ```
129
+ */
130
+ interface ValidationInvalid {
131
+ /** Selalu `false` */
132
+ valid: false;
133
+ /** Pesan error dalam bahasa Indonesia */
134
+ error: string;
135
+ }
136
+ /**
137
+ * Discriminated union hasil validasi NIK.
138
+ *
139
+ * Lebih ringan dari {@link NIKResult} — cuma cek valid/tidak tanpa parsing.
140
+ */
141
+ type ValidationResult = ValidationValid | ValidationInvalid;
142
+ /**
143
+ * Opsi untuk men-generate NIK.
144
+ *
145
+ * Semua field opsional — yang tidak diisi akan di-random.
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * // Full random
150
+ * generateNIK();
151
+ *
152
+ * // Perempuan lahir 25 Agustus 1985
153
+ * generateNIK({ gender: "F", birthDate: new Date("1985-08-25") });
154
+ *
155
+ * // Wilayah spesifik (Kec. Nagreg, Kab. Bandung, Jawa Barat)
156
+ * generateNIK({ provinceCode: "32", regencyCode: "3204", districtCode: "320407" });
157
+ * ```
158
+ */
159
+ interface GenerateOptions {
160
+ /**
161
+ * Kode provinsi Kemendagri (2 digit).
162
+ * Kalau diisi, `regencyCode` juga harus diisi.
163
+ */
164
+ provinceCode?: string;
165
+ /**
166
+ * Kode kabupaten/kota Kemendagri (4 digit).
167
+ * Kalau diisi, `provinceCode` harus match (2 digit pertama sama).
168
+ */
169
+ regencyCode?: string;
170
+ /**
171
+ * Kode kecamatan Kemendagri (6 digit).
172
+ * Kalau diisi, `regencyCode` harus match (4 digit pertama sama).
173
+ */
174
+ districtCode?: string;
175
+ /** Jenis kelamin: `"M"` (laki-laki) atau `"F"` (perempuan) */
176
+ gender?: "M" | "F";
177
+ /**
178
+ * Tanggal lahir. Kalau tidak diisi, di-random antara 1950-2005.
179
+ */
180
+ birthDate?: Date;
181
+ }
182
+
183
+ export type { GenerateOptions, NIKInvalid, NIKResult, NIKValid, ValidationInvalid, ValidationResult, ValidationValid };
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Definisi tipe data untuk parsing dan validasi NIK (Nomor Induk Kependudukan).
3
+ *
4
+ * NIK adalah nomor identitas penduduk Indonesia yang terdiri dari 16 digit:
5
+ * - Digit 1-2: kode provinsi (format Kemendagri)
6
+ * - Digit 3-4: kode kabupaten/kota (format Kemendagri)
7
+ * - Digit 5-6: kode kecamatan (format Kemendagri)
8
+ * - Digit 7-12: tanggal lahir (DDMMYY, perempuan DD+40)
9
+ * - Digit 13-16: nomor urut registrasi
10
+ *
11
+ * Semua kode wilayah menggunakan format **Kemendagri** (bukan BPS).
12
+ * Kalau butuh resolve ke nama wilayah, bisa pakai package `kode-wilayah-id`
13
+ * dengan fungsi `getProvinceByKemendagriCode()`, `getRegencyByKemendagriCode()`, dll.
14
+ *
15
+ * @module types
16
+ */
17
+ /**
18
+ * Hasil parsing NIK yang valid — berisi semua komponen NIK yang sudah diekstrak.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const result = parseNIK("3204076508850001");
23
+ * if (result.valid) {
24
+ * console.log(result.provinceCode); // "32"
25
+ * console.log(result.regencyCode); // "3204"
26
+ * console.log(result.districtCode); // "320407"
27
+ * console.log(result.gender); // "F"
28
+ * console.log(result.birthDate); // Date: 1985-08-25
29
+ * console.log(result.sequenceNumber); // "0001"
30
+ * }
31
+ * ```
32
+ */
33
+ interface NIKValid {
34
+ /** Selalu `true` — gunakan untuk narrowing discriminated union */
35
+ valid: true;
36
+ /** NIK asli yang di-parse (16 digit) */
37
+ nik: string;
38
+ /**
39
+ * Kode provinsi Kemendagri (2 digit).
40
+ * Contoh: `"32"` untuk Jawa Barat, `"11"` untuk Aceh.
41
+ *
42
+ * Bisa dipakai dengan `kode-wilayah-id`:
43
+ * ```typescript
44
+ * import { getProvinceByKemendagriCode } from 'kode-wilayah-id';
45
+ * const prov = getProvinceByKemendagriCode(result.provinceCode);
46
+ * ```
47
+ */
48
+ provinceCode: string;
49
+ /**
50
+ * Kode kabupaten/kota Kemendagri (4 digit).
51
+ * Contoh: `"3204"` untuk Kab. Bandung.
52
+ */
53
+ regencyCode: string;
54
+ /**
55
+ * Kode kecamatan Kemendagri (6 digit).
56
+ * Contoh: `"320407"` untuk Kec. Nagreg.
57
+ */
58
+ districtCode: string;
59
+ /**
60
+ * Tanggal lahir yang sudah di-parse menjadi object `Date`.
61
+ * Tahun 2 digit disambiguasi: `YY > tahunSekarang` → 1900+YY, else 2000+YY.
62
+ */
63
+ birthDate: Date;
64
+ /** Jenis kelamin: `"M"` (laki-laki) atau `"F"` (perempuan) */
65
+ gender: "M" | "F";
66
+ /** Nomor urut registrasi di kecamatan (4 digit, `"0001"`–`"9999"`) */
67
+ sequenceNumber: string;
68
+ }
69
+ /**
70
+ * Hasil parsing NIK yang tidak valid — berisi pesan error.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const result = parseNIK("123");
75
+ * if (!result.valid) {
76
+ * console.log(result.error); // "NIK harus 16 digit"
77
+ * }
78
+ * ```
79
+ */
80
+ interface NIKInvalid {
81
+ /** Selalu `false` — gunakan untuk narrowing discriminated union */
82
+ valid: false;
83
+ /** Pesan error dalam bahasa Indonesia yang menjelaskan kenapa NIK tidak valid */
84
+ error: string;
85
+ }
86
+ /**
87
+ * Discriminated union hasil parsing NIK.
88
+ *
89
+ * Gunakan `result.valid` untuk narrowing:
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const result = parseNIK(input);
94
+ * if (result.valid) {
95
+ * // result bertipe NIKValid — semua field tersedia
96
+ * console.log(result.gender);
97
+ * } else {
98
+ * // result bertipe NIKInvalid — ada error
99
+ * console.log(result.error);
100
+ * }
101
+ * ```
102
+ */
103
+ type NIKResult = NIKValid | NIKInvalid;
104
+ /**
105
+ * Hasil validasi NIK yang valid.
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const result = validateNIK("3204076508850001");
110
+ * if (result.valid) {
111
+ * console.log("NIK valid!");
112
+ * }
113
+ * ```
114
+ */
115
+ interface ValidationValid {
116
+ /** Selalu `true` */
117
+ valid: true;
118
+ }
119
+ /**
120
+ * Hasil validasi NIK yang tidak valid.
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * const result = validateNIK("123");
125
+ * if (!result.valid) {
126
+ * console.log(result.error); // "NIK harus 16 digit"
127
+ * }
128
+ * ```
129
+ */
130
+ interface ValidationInvalid {
131
+ /** Selalu `false` */
132
+ valid: false;
133
+ /** Pesan error dalam bahasa Indonesia */
134
+ error: string;
135
+ }
136
+ /**
137
+ * Discriminated union hasil validasi NIK.
138
+ *
139
+ * Lebih ringan dari {@link NIKResult} — cuma cek valid/tidak tanpa parsing.
140
+ */
141
+ type ValidationResult = ValidationValid | ValidationInvalid;
142
+ /**
143
+ * Opsi untuk men-generate NIK.
144
+ *
145
+ * Semua field opsional — yang tidak diisi akan di-random.
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * // Full random
150
+ * generateNIK();
151
+ *
152
+ * // Perempuan lahir 25 Agustus 1985
153
+ * generateNIK({ gender: "F", birthDate: new Date("1985-08-25") });
154
+ *
155
+ * // Wilayah spesifik (Kec. Nagreg, Kab. Bandung, Jawa Barat)
156
+ * generateNIK({ provinceCode: "32", regencyCode: "3204", districtCode: "320407" });
157
+ * ```
158
+ */
159
+ interface GenerateOptions {
160
+ /**
161
+ * Kode provinsi Kemendagri (2 digit).
162
+ * Kalau diisi, `regencyCode` juga harus diisi.
163
+ */
164
+ provinceCode?: string;
165
+ /**
166
+ * Kode kabupaten/kota Kemendagri (4 digit).
167
+ * Kalau diisi, `provinceCode` harus match (2 digit pertama sama).
168
+ */
169
+ regencyCode?: string;
170
+ /**
171
+ * Kode kecamatan Kemendagri (6 digit).
172
+ * Kalau diisi, `regencyCode` harus match (4 digit pertama sama).
173
+ */
174
+ districtCode?: string;
175
+ /** Jenis kelamin: `"M"` (laki-laki) atau `"F"` (perempuan) */
176
+ gender?: "M" | "F";
177
+ /**
178
+ * Tanggal lahir. Kalau tidak diisi, di-random antara 1950-2005.
179
+ */
180
+ birthDate?: Date;
181
+ }
182
+
183
+ export type { GenerateOptions, NIKInvalid, NIKResult, NIKValid, ValidationInvalid, ValidationResult, ValidationValid };
package/dist/types.js ADDED
File without changes
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/validate.ts
21
+ var validate_exports = {};
22
+ __export(validate_exports, {
23
+ validateNIK: () => validateNIK
24
+ });
25
+ module.exports = __toCommonJS(validate_exports);
26
+
27
+ // src/utils.ts
28
+ function disambiguateYear(yy) {
29
+ const currentYY = (/* @__PURE__ */ new Date()).getFullYear() % 100;
30
+ return yy > currentYY ? 1900 + yy : 2e3 + yy;
31
+ }
32
+
33
+ // src/validate.ts
34
+ var MIN_PROVINCE_CODE = 11;
35
+ var MAX_PROVINCE_CODE = 97;
36
+ var NIK_LENGTH = 16;
37
+ var DIGITS_ONLY_PATTERN = /^\d{16}$/;
38
+ function isValidCalendarDate(year, month, day) {
39
+ const date = new Date(year, month - 1, day);
40
+ return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
41
+ }
42
+ function validateNIK(nik) {
43
+ if (typeof nik !== "string") {
44
+ return { valid: false, error: "NIK harus berupa string" };
45
+ }
46
+ if (nik.length !== NIK_LENGTH) {
47
+ return { valid: false, error: "NIK harus 16 digit" };
48
+ }
49
+ if (!DIGITS_ONLY_PATTERN.test(nik)) {
50
+ return { valid: false, error: "NIK hanya boleh berisi angka" };
51
+ }
52
+ const provinceCode = Number.parseInt(nik.substring(0, 2), 10);
53
+ if (provinceCode < MIN_PROVINCE_CODE || provinceCode > MAX_PROVINCE_CODE) {
54
+ return { valid: false, error: "Kode provinsi tidak valid" };
55
+ }
56
+ const dd = Number.parseInt(nik.substring(6, 8), 10);
57
+ const mm = Number.parseInt(nik.substring(8, 10), 10);
58
+ const yy = Number.parseInt(nik.substring(10, 12), 10);
59
+ const isValidMaleDD = dd >= 1 && dd <= 31;
60
+ const isValidFemaleDD = dd >= 41 && dd <= 71;
61
+ if (!isValidMaleDD && !isValidFemaleDD) {
62
+ return { valid: false, error: "Tanggal lahir tidak valid" };
63
+ }
64
+ if (mm < 1 || mm > 12) {
65
+ return { valid: false, error: "Tanggal lahir tidak valid" };
66
+ }
67
+ const actualDay = isValidFemaleDD ? dd - 40 : dd;
68
+ const fullYear = disambiguateYear(yy);
69
+ if (!isValidCalendarDate(fullYear, mm, actualDay)) {
70
+ return { valid: false, error: "Tanggal lahir tidak valid" };
71
+ }
72
+ const seq = nik.substring(12, 16);
73
+ if (seq === "0000") {
74
+ return { valid: false, error: "Nomor urut tidak valid" };
75
+ }
76
+ return { valid: true };
77
+ }
78
+ // Annotate the CommonJS export names for ESM import in node:
79
+ 0 && (module.exports = {
80
+ validateNIK
81
+ });