npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cakkatrok-indonesia-utils

v1.2.0

Published

Utility functions for Indonesian projects: Rupiah, phone number, date, NIK, NPWP, postal code, slug, unique payment amount, masking, and validation.

Readme

cakkatrok-indonesia-utils

npm version npm downloads license: MIT node types dependencies module cli

Utility JavaScript/Node.js tanpa dependency untuk kebutuhan umum aplikasi Indonesia: format Rupiah, nomor HP Indonesia, tanggal Indonesia + weton, slug, nominal transfer unik, NIK, NPWP, kode pos, validasi email, pembersihan teks, title case, dan masking data.

Database kode pos dibundel offline dari dataset MIT pentagonal/Indonesia-Postal-Code dengan 81.248 baris data kelurahan/kecamatan/kota/provinsi.

Instalasi

npm install cakkatrok-indonesia-utils

Requirement: Node.js >=16.

Penggunaan

const {
  formatRupiah,
  parseRupiah,
  normalizePhoneID,
  isValidPhoneID,
  formatPhoneID,
  getProviderID,
  slugifyID,
  formatTanggalID,
  relativeTimeID,
  createUniqueAmount,
  isValidNIK,
  parseNIK,
  isValidNPWP,
  formatNPWP,
  isValidPostalCodeID,
  parsePostalCodeID,
  isValidEmail,
  cleanText,
  titleCaseID,
  maskEmail,
  maskPhoneID,
  maskBankAccountID
} = require('cakkatrok-indonesia-utils');

console.log(formatRupiah(15000));
// Rp15.000

console.log(parseRupiah('Rp15.000,50'));
// 15000.5

console.log(normalizePhoneID('0812-3456-7890'));
// 6281234567890

console.log(isValidPhoneID('0812-3456-7890'));
// true

console.log(formatPhoneID('081234567890'));
// +62 812 3456 7890

console.log(getProviderID('081234567890'));
// Telkomsel

console.log(slugifyID('Produk Lokal Indonesia & UMKM!'));
// produk-lokal-indonesia-dan-umkm

console.log(formatTanggalID('2026-07-08T10:30:00', { includeTime: true }));
// Rabu Legi, 8 Juli 2026 10.30

console.log(relativeTimeID('07 01 2007', '08 03 2026'));
// 19 tahun lebih 2 bulan 1 hari yang lalu

console.log(createUniqueAmount({ amount: 50000, activeAmounts: [50001, 50002] }));
// { baseAmount: 50000, uniqueCode: 3, finalAmount: 50003, formatted: 'Rp50.003' }

console.log(isValidNIK('3201010701070001'));
// true

console.log(parseNIK('3201014701070001'));
// { nik: '3201014701070001', provinceCode: '32', cityCode: '3201', districtCode: '320101', birthDate: '2007-01-07', birthDay: 7, birthMonth: 1, birthYear: 2007, gender: 'female', sequence: '0001' }

console.log(isValidNPWP('12.345.678.9-012.345'));
// true

console.log(formatNPWP('123456789012345'));
// 12.345.678.9-012.345

console.log(isValidPostalCodeID('57557'));
// true

console.log(parsePostalCodeID('57557'));
// { postalCode: '57557', zoneCode: '5', zoneName: 'Jawa Tengah dan DI Yogyakarta', provinces: ['Jawa Tengah'], areas: [...] }

console.log(isValidEmail('[email protected]'));
// true

console.log(cleanText(' halo\n\t dunia '));
// halo dunia

console.log(titleCaseID('cara membuat nasi goreng yang enak'));
// Cara Membuat Nasi Goreng yang Enak

console.log(maskEmail('[email protected]'));
// r****[email protected]

console.log(maskPhoneID('081234567890'));
// +6281*****7890

console.log(maskBankAccountID('1234567890'));
// 123****890

CLI

Jalankan via npx dengan nama package:

npx cakkatrok-indonesia-utils rupiah 15000
npx cakkatrok-indonesia-utils parse-rupiah "Rp15.000"
npx cakkatrok-indonesia-utils phone 081234567890
npx cakkatrok-indonesia-utils provider 081234567890
npx cakkatrok-indonesia-utils slug "Produk Lokal Indonesia & UMKM!"
npx cakkatrok-indonesia-utils date 2026-07-08
npx cakkatrok-indonesia-utils date "07 01 2007"

Jika package sudah terpasang global, command bin-nya adalah indonesia-utils:

npm install -g cakkatrok-indonesia-utils
indonesia-utils rupiah 15000

Perintah yang tersedia:

| Command | Output | | --- | --- | | rupiah <number> | Format angka ke Rupiah | | parse-rupiah <text> | Parse teks Rupiah ke number | | phone <number> | Normalisasi nomor HP ke format 62... | | provider <number> | Deteksi provider dari prefix nomor | | slug <text> | Buat slug bersih | | date [date] | Format tanggal Indonesia |

API

formatRupiah(value, options?)

Format angka ke Rupiah.

formatRupiah(15000); // Rp15.000
formatRupiah(15000, { space: true }); // Rp 15.000
formatRupiah(15000, { withSymbol: false }); // 15.000
formatRupiah(15000.5, { decimal: 2 }); // Rp15.000,50

Options:

{
  symbol: 'Rp',
  withSymbol: true,
  decimal: 0,
  space: false
}

parseRupiah(value)

Parse teks Rupiah ke number.

parseRupiah('Rp15.000'); // 15000
parseRupiah('Rp15.000,50'); // 15000.5
parseRupiah(null); // 0

normalizePhoneID(value, options?)

Normalisasi nomor HP Indonesia ke format kode negara.

normalizePhoneID('0812-3456-7890'); // 6281234567890
normalizePhoneID('+62 812 3456 7890'); // 6281234567890
normalizePhoneID('81234567890'); // 6281234567890
normalizePhoneID('081234567890', { keepPlus: true }); // +6281234567890

Options:

{
  countryCode: '62',
  keepPlus: false
}

isValidPhoneID(value)

Validasi nomor HP Indonesia.

isValidPhoneID('081234567890'); // true
isValidPhoneID('021123456'); // false

formatPhoneID(value, options?)

Format nomor HP untuk ditampilkan.

formatPhoneID('081234567890'); // +62 812 3456 7890
formatPhoneID('081234567890', { international: false }); // 0 812 3456 7890
formatPhoneID('081234567890', { separator: '-' }); // +62-812-3456-7890

Options:

{
  separator: ' ',
  international: true
}

getProviderID(value)

Deteksi provider umum dari prefix nomor HP.

getProviderID('081234567890'); // Telkomsel
getProviderID('089612345678'); // Tri
getProviderID('080000000000'); // Unknown

Provider yang dikenali: Telkomsel, Indosat, XL, Axis, Tri, dan Smartfren.

slugifyID(value, options?)

Buat slug bersih dari teks.

slugifyID('Produk Lokal Indonesia & UMKM!');
// produk-lokal-indonesia-dan-umkm

slugifyID('Halo Dunia', { separator: '_' });
// halo_dunia

Options:

{
  separator: '-',
  lower: true,
  maxLength: 0,
  replacement: {
    '&': ' dan ',
    '+': ' plus ',
    '@': ' at '
  }
}

formatTanggalID(value?, options?)

Format tanggal ke Bahasa Indonesia. Input mendukung Date, timestamp, ISO string, dan format lokal seperti DD MM YYYY, DD-MM-YYYY, atau DD/MM/YYYY.

formatTanggalID('2026-07-08');
// Rabu Legi, 8 Juli 2026

formatTanggalID('07 01 2007');
// Minggu Wage, 7 Januari 2007

formatTanggalID('2026-07-08T10:30:00', { includeTime: true });
// Rabu Legi, 8 Juli 2026 10.30

formatTanggalID('2026-07-08', { dateStyle: 'numeric' });
// Rabu Legi, 08/07/2026

formatTanggalID('2026-07-08', { includeWeton: false });
// Rabu, 8 Juli 2026

Options:

{
  includeDay: true,
  shortMonth: false,
  includeTime: false,
  timeSeparator: '.',
  dateStyle: 'long',
  includeWeton: true
}

relativeTimeID(value, baseValue?)

Buat teks waktu relatif dalam Bahasa Indonesia.

relativeTimeID('2026-07-07T10:30:00', '2026-07-08T10:30:00');
// 1 hari yang lalu

relativeTimeID('08 01 2007', '07 01 2007');
// dalam 1 hari

relativeTimeID('07 01 2007', '08 03 2026');
// 19 tahun lebih 2 bulan 1 hari yang lalu

createUniqueAmount(options)

Buat nominal unik untuk pencocokan transfer manual atau mutasi QRIS.

createUniqueAmount({
  amount: 50000,
  activeAmounts: [50001, 50002]
});

// {
//   baseAmount: 50000,
//   uniqueCode: 3,
//   finalAmount: 50003,
//   formatted: 'Rp50.003'
// }

Options:

{
  amount: 50000,
  min: 1,
  max: 999,
  activeAmounts: [],
  mode: 'add' // atau 'subtract'
}

isValidEmail(value)

Validasi email sederhana.

isValidEmail('[email protected]'); // true
isValidEmail('user@localhost'); // false

isValidNIK(value)

Validasi NIK Indonesia secara praktis: 16 digit, bukan angka berulang, kode wilayah tidak kosong, tanggal lahir valid, dan nomor urut tidak 0000.

isValidNIK('3201010701070001'); // true
isValidNIK('3201014701070001'); // true, perempuan karena tanggal lahir + 40
isValidNIK('3201013201070001'); // false

parseNIK(value)

Parse NIK valid menjadi bagian-bagian dasar. Jika NIK tidak valid, return null.

parseNIK('3201014701070001');

// {
//   nik: '3201014701070001',
//   provinceCode: '32',
//   cityCode: '3201',
//   districtCode: '320101',
//   birthDate: '2007-01-07',
//   birthDay: 7,
//   birthMonth: 1,
//   birthYear: 2007,
//   gender: 'female',
//   sequence: '0001'
// }

Catatan: fungsi ini hanya memecah kode wilayah, tidak mencocokkan kode wilayah ke database nama provinsi/kabupaten/kecamatan.

isValidNPWP(value)

Validasi NPWP 15 digit atau 16 digit. Separator seperti titik dan strip akan diabaikan.

isValidNPWP('12.345.678.9-012.345'); // true
isValidNPWP('1234567890123456'); // true
isValidNPWP('111111111111111'); // false

formatNPWP(value)

Format NPWP 15 digit ke format klasik, atau NPWP 16 digit ke grup 4 digit.

formatNPWP('123456789012345'); // 12.345.678.9-012.345
formatNPWP('1234567890123456'); // 1234 5678 9012 3456

isValidPostalCodeID(value)

Validasi kode pos Indonesia berdasarkan database detail yang dibundel.

isValidPostalCodeID('57557'); // true
isValidPostalCodeID('40123'); // true
isValidPostalCodeID('01234'); // false

parsePostalCodeID(value)

Parse kode pos valid menjadi data daerah detail dari database. Return null jika format kode pos salah atau kode pos tidak tersedia di database.

parsePostalCodeID('57557');

// {
//   postalCode: '57557',
//   zoneCode: '5',
//   zoneName: 'Jawa Tengah dan DI Yogyakarta',
//   provinces: ['Jawa Tengah'],
//   areas: [
//     {
//       postalCode: '57557',
//       village: 'Blimbing',
//       district: 'Gatak',
//       city: 'Sukoharjo',
//       province: 'Jawa Tengah',
//       provinceCode: '33'
//     }
//     // ...13 area lain dengan kode pos yang sama
//   ]
// }

Catatan: satu kode pos bisa dipakai oleh lebih dari satu desa/kelurahan, karena itu detail daerah dikembalikan sebagai array areas.

cleanText(value)

Trim dan normalisasi whitespace.

cleanText(' halo\n\t dunia '); // halo dunia

titleCaseID(value)

Ubah teks menjadi title case dengan beberapa kata sambung tetap lowercase.

titleCaseID('cara membuat nasi goreng yang enak');
// Cara Membuat Nasi Goreng yang Enak

maskEmail(value)

Masking username email.

maskEmail('[email protected]'); // r****[email protected]

maskPhoneID(value)

Masking nomor HP Indonesia.

maskPhoneID('081234567890'); // +6281*****7890

maskBankAccountID(value)

Masking nomor rekening bank dengan menyisakan 3 digit awal dan 3 digit akhir.

maskBankAccountID('1234567890'); // 123****890

TypeScript

Type definition sudah tersedia melalui src/index.d.ts dan otomatis terbaca dari field types di package.json.

import { formatRupiah, type RupiahOptions } from 'cakkatrok-indonesia-utils';

const options: RupiahOptions = { space: true };
const result = formatRupiah(15000, options);

Development

npm test
npm run example

License

MIT