nik-parser-indonesia 1.0.1 → 1.0.2
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/dist/data/data_wilayah.json +465834 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +23 -0
- package/dist/src/NikParser.d.ts +6 -0
- package/dist/src/NikParser.js +68 -0
- package/dist/src/types.d.ts +26 -0
- package/dist/src/types.js +3 -0
- package/index.ts +7 -0
- package/package.json +7 -4
- package/src/NikParser.ts +73 -0
- package/src/types.ts +28 -0
- package/tsconfig.json +15 -0
- package/index.js +0 -10
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.parse = void 0;
|
|
18
|
+
// index.ts
|
|
19
|
+
const NikParser_1 = require("./src/NikParser");
|
|
20
|
+
const parserInstance = new NikParser_1.NikParser();
|
|
21
|
+
const parse = (nik) => parserInstance.parse(nik);
|
|
22
|
+
exports.parse = parse;
|
|
23
|
+
__exportStar(require("./src/types"), exports); // Ekspor tipe datanya juga agar bisa dipakai client
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.NikParser = void 0;
|
|
7
|
+
// Gunakan import statis di bagian paling atas file
|
|
8
|
+
const data_wilayah_json_1 = __importDefault(require("../data/data_wilayah.json"));
|
|
9
|
+
class NikParser {
|
|
10
|
+
dataWilayah;
|
|
11
|
+
constructor() {
|
|
12
|
+
// Sangat bersih! Tidak perlu try-catch lagi untuk load file,
|
|
13
|
+
// karena jika file JSON hilang atau salah path, compiler TS akan langsung error saat build.
|
|
14
|
+
this.dataWilayah = data_wilayah_json_1.default;
|
|
15
|
+
}
|
|
16
|
+
parse(nik) {
|
|
17
|
+
// Validation Guard
|
|
18
|
+
if (!nik || typeof nik !== 'string') {
|
|
19
|
+
return { isValid: false, error: "NIK harus berupa string", biodata: null, wilayah: null };
|
|
20
|
+
}
|
|
21
|
+
const cleanNik = nik.trim();
|
|
22
|
+
if (cleanNik.length !== 16 || isNaN(Number(cleanNik))) {
|
|
23
|
+
return { isValid: false, error: "NIK harus berjumlah 16 digit angka", biodata: null, wilayah: null };
|
|
24
|
+
}
|
|
25
|
+
// 1. Parsing Tanggal Lahir & Jenis Kelamin
|
|
26
|
+
let tanggal = parseInt(cleanNik.substring(6, 8), 10);
|
|
27
|
+
const bulan = cleanNik.substring(8, 10);
|
|
28
|
+
const tahun = cleanNik.substring(10, 12);
|
|
29
|
+
let jenis_kelamin = "Pria";
|
|
30
|
+
if (tanggal > 40) {
|
|
31
|
+
jenis_kelamin = "Wanita";
|
|
32
|
+
tanggal = tanggal - 40;
|
|
33
|
+
}
|
|
34
|
+
const padTanggal = String(tanggal).padStart(2, '0');
|
|
35
|
+
const tahunPenuh = parseInt(tahun, 10) > 26 ? `19${tahun}` : `20${tahun}`;
|
|
36
|
+
const tanggal_lahir = `${padTanggal}-${bulan}-${tahunPenuh}`;
|
|
37
|
+
// 2. Parsing Wilayah Domisili
|
|
38
|
+
const kodeProv = cleanNik.substring(0, 2);
|
|
39
|
+
const kodeKab = `${kodeProv}.${cleanNik.substring(2, 4)}`;
|
|
40
|
+
const kodeKec = `${kodeKab}.${cleanNik.substring(4, 6)}`;
|
|
41
|
+
// Cari Provinsi
|
|
42
|
+
const provinsi = this.dataWilayah.find(p => p.code === kodeProv);
|
|
43
|
+
if (!provinsi)
|
|
44
|
+
return { isValid: false, error: "Kode Provinsi tidak terdaftar", biodata: null, wilayah: null };
|
|
45
|
+
// Cari Kabupaten/Kota
|
|
46
|
+
const kabupaten = provinsi.kabupaten?.find(k => k.code === kodeKab);
|
|
47
|
+
if (!kabupaten)
|
|
48
|
+
return { isValid: false, error: "Kode Kabupaten/Kota tidak terdaftar", biodata: null, wilayah: null };
|
|
49
|
+
// Cari Kecamatan
|
|
50
|
+
const kecamatan = kabupaten.kecamatan?.find(kec => kec.code === kodeKec);
|
|
51
|
+
if (!kecamatan)
|
|
52
|
+
return { isValid: false, error: "Kode Kecamatan tidak terdaftar", biodata: null, wilayah: null };
|
|
53
|
+
return {
|
|
54
|
+
isValid: true,
|
|
55
|
+
error: null,
|
|
56
|
+
biodata: {
|
|
57
|
+
jenis_kelamin,
|
|
58
|
+
tanggal_lahir
|
|
59
|
+
},
|
|
60
|
+
wilayah: {
|
|
61
|
+
provinsi: provinsi.name,
|
|
62
|
+
kabupaten: kabupaten.name,
|
|
63
|
+
kecamatan: kecamatan.name
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.NikParser = NikParser;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface Biodata {
|
|
2
|
+
jenis_kelamin: "Pria" | "Wanita";
|
|
3
|
+
tanggal_lahir: string;
|
|
4
|
+
}
|
|
5
|
+
export interface Wilayah {
|
|
6
|
+
provinsi: string;
|
|
7
|
+
kabupaten: string;
|
|
8
|
+
kecamatan: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ParseResult {
|
|
11
|
+
isValid: boolean;
|
|
12
|
+
error: string | null;
|
|
13
|
+
biodata: Biodata | null;
|
|
14
|
+
wilayah: Wilayah | null;
|
|
15
|
+
}
|
|
16
|
+
export interface RegionNode {
|
|
17
|
+
code: string;
|
|
18
|
+
name: string;
|
|
19
|
+
kabupaten?: RegionNode[];
|
|
20
|
+
kecamatan?: RegionNode[];
|
|
21
|
+
desa?: Array<{
|
|
22
|
+
code: string;
|
|
23
|
+
name: string;
|
|
24
|
+
type: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
package/index.ts
ADDED
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nik-parser-indonesia",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Library untuk melakukan parsing NIK (No Induk Kependudukan) Indonesia untuk mendapatkan info daerah, jenis kelamin, dan tanggal lahir.",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
6
7
|
"scripts": {
|
|
7
|
-
"
|
|
8
|
+
"build": "tsc"
|
|
8
9
|
},
|
|
9
10
|
"keywords": [
|
|
10
11
|
"nik",
|
|
@@ -16,5 +17,7 @@
|
|
|
16
17
|
],
|
|
17
18
|
"author": "Zealish",
|
|
18
19
|
"license": "MIT",
|
|
19
|
-
"
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"typescript": "^5.0.0"
|
|
22
|
+
}
|
|
20
23
|
}
|
package/src/NikParser.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ParseResult, RegionNode } from './types';
|
|
2
|
+
|
|
3
|
+
// Gunakan import statis di bagian paling atas file
|
|
4
|
+
import dataWilayahJson from '../data/data_wilayah.json';
|
|
5
|
+
|
|
6
|
+
export class NikParser {
|
|
7
|
+
private dataWilayah: RegionNode[];
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
// Sangat bersih! Tidak perlu try-catch lagi untuk load file,
|
|
11
|
+
// karena jika file JSON hilang atau salah path, compiler TS akan langsung error saat build.
|
|
12
|
+
this.dataWilayah = dataWilayahJson as RegionNode[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public parse(nik: string): ParseResult {
|
|
16
|
+
// Validation Guard
|
|
17
|
+
if (!nik || typeof nik !== 'string') {
|
|
18
|
+
return { isValid: false, error: "NIK harus berupa string", biodata: null, wilayah: null };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const cleanNik = nik.trim();
|
|
22
|
+
if (cleanNik.length !== 16 || isNaN(Number(cleanNik))) {
|
|
23
|
+
return { isValid: false, error: "NIK harus berjumlah 16 digit angka", biodata: null, wilayah: null };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 1. Parsing Tanggal Lahir & Jenis Kelamin
|
|
27
|
+
let tanggal = parseInt(cleanNik.substring(6, 8), 10);
|
|
28
|
+
const bulan = cleanNik.substring(8, 10);
|
|
29
|
+
const tahun = cleanNik.substring(10, 12);
|
|
30
|
+
|
|
31
|
+
let jenis_kelamin: "Pria" | "Wanita" = "Pria";
|
|
32
|
+
|
|
33
|
+
if (tanggal > 40) {
|
|
34
|
+
jenis_kelamin = "Wanita";
|
|
35
|
+
tanggal = tanggal - 40;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const padTanggal = String(tanggal).padStart(2, '0');
|
|
39
|
+
const tahunPenuh = parseInt(tahun, 10) > 26 ? `19${tahun}` : `20${tahun}`;
|
|
40
|
+
const tanggal_lahir = `${padTanggal}-${bulan}-${tahunPenuh}`;
|
|
41
|
+
|
|
42
|
+
// 2. Parsing Wilayah Domisili
|
|
43
|
+
const kodeProv = cleanNik.substring(0, 2);
|
|
44
|
+
const kodeKab = `${kodeProv}.${cleanNik.substring(2, 4)}`;
|
|
45
|
+
const kodeKec = `${kodeKab}.${cleanNik.substring(4, 6)}`;
|
|
46
|
+
|
|
47
|
+
// Cari Provinsi
|
|
48
|
+
const provinsi = this.dataWilayah.find(p => p.code === kodeProv);
|
|
49
|
+
if (!provinsi) return { isValid: false, error: "Kode Provinsi tidak terdaftar", biodata: null, wilayah: null };
|
|
50
|
+
|
|
51
|
+
// Cari Kabupaten/Kota
|
|
52
|
+
const kabupaten = provinsi.kabupaten?.find(k => k.code === kodeKab);
|
|
53
|
+
if (!kabupaten) return { isValid: false, error: "Kode Kabupaten/Kota tidak terdaftar", biodata: null, wilayah: null };
|
|
54
|
+
|
|
55
|
+
// Cari Kecamatan
|
|
56
|
+
const kecamatan = kabupaten.kecamatan?.find(kec => kec.code === kodeKec);
|
|
57
|
+
if (!kecamatan) return { isValid: false, error: "Kode Kecamatan tidak terdaftar", biodata: null, wilayah: null };
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
isValid: true,
|
|
61
|
+
error: null,
|
|
62
|
+
biodata: {
|
|
63
|
+
jenis_kelamin,
|
|
64
|
+
tanggal_lahir
|
|
65
|
+
},
|
|
66
|
+
wilayah: {
|
|
67
|
+
provinsi: provinsi.name,
|
|
68
|
+
kabupaten: kabupaten.name,
|
|
69
|
+
kecamatan: kecamatan.name
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
|
|
3
|
+
export interface Biodata {
|
|
4
|
+
jenis_kelamin: "Pria" | "Wanita";
|
|
5
|
+
tanggal_lahir: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface Wilayah {
|
|
9
|
+
provinsi: string;
|
|
10
|
+
kabupaten: string;
|
|
11
|
+
kecamatan: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ParseResult {
|
|
15
|
+
isValid: boolean;
|
|
16
|
+
error: string | null;
|
|
17
|
+
biodata: Biodata | null;
|
|
18
|
+
wilayah: Wilayah | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Interface untuk data JSON internal
|
|
22
|
+
export interface RegionNode {
|
|
23
|
+
code: string;
|
|
24
|
+
name: string;
|
|
25
|
+
kabupaten?: RegionNode[];
|
|
26
|
+
kecamatan?: RegionNode[];
|
|
27
|
+
desa?: Array<{ code: string; name: string; type: string }>;
|
|
28
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "CommonJS",
|
|
5
|
+
"lib": ["ES2022"],
|
|
6
|
+
"declaration": true, // Pembuat file .d.ts untuk suggestion otomatis
|
|
7
|
+
"outDir": "./dist", // Semua hasil compile masuk ke folder dist
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true // Mengizinkan TS membaca file JSON langsung
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*", "index.ts"]
|
|
15
|
+
}
|
package/index.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// index.js
|
|
2
|
-
const NikParser = require("./src/NikParser");
|
|
3
|
-
|
|
4
|
-
// Buat instance secara internal sekali saja (Singleton pattern)
|
|
5
|
-
const parserInstance = new NikParser();
|
|
6
|
-
|
|
7
|
-
// Ekspor fungsi parser langsung
|
|
8
|
-
module.exports = {
|
|
9
|
-
parse: (nik) => parserInstance.parse(nik),
|
|
10
|
-
};
|