@ph-dev-utils/core
v0.2.0
Published
Filipino developer utilities — peso, government IDs (TIN/SSS/PhilHealth/Pag-IBIG), phone, address (regions/provinces/cities/municipalities), and PH holidays (regular + special, with DOLE pay multipliers).
Maintainers
Readme
@ph-dev-utils/core
Filipino developer utilities for JavaScript / TypeScript — peso formatting, government ID validators (TIN / SSS / PhilHealth / Pag-IBIG), PH phone parsing with network detection, and PSGC region / province lookup.
Need fake test data on top of this? See the sibling @ph-dev-utils/faker.
Install
npm install @ph-dev-utils/coreRequires Node 20+.
Quick start
import {
formatPHP, parsePHP, pesoToWords,
validateTIN, formatTIN,
parseMobile, parseLandline,
findProvince, listRegions,
} from '@ph-dev-utils/core';
formatPHP(1234.5); // '₱1,234.50'
parsePHP('₱1,234.50'); // 1234.5
validateTIN('123-456-789-000'); // true
parseMobile('09171234567'); // { e164: '+639171234567', network: 'Globe', ... }
findProvince('Cebu'); // { code: '0722', name: 'Cebu', region: '07' }API Reference
Peso
formatPHP(value: number, opts?: FormatOptions): string
Format a number as a peso amount with thousands separators.
type FormatOptions = {
decimals?: number; // default: 2
symbol?: 'peso' | 'php' | 'none'; // default: 'peso'
};formatPHP(1234.5); // '₱1,234.50'
formatPHP(1234.5, { decimals: 0 }); // '₱1,235'
formatPHP(1234.5, { symbol: 'php' }); // 'PHP 1,234.50'
formatPHP(1234.5, { symbol: 'none' }); // '1,234.50'
formatPHP(-50); // '-₱50.00'
formatPHP(NaN); // '' (non-finite → empty string)parsePHP(input: string): number | null
Parse a peso-formatted string back to a number. Strips ₱, PHP, whitespace, and commas. Returns null for non-strings, empty strings, or unparseable input.
parsePHP('₱1,234.50'); // 1234.5
parsePHP('PHP 50'); // 50
parsePHP('-1,000'); // -1000
parsePHP('not a number'); // null
parsePHP(''); // nullpesoToWords(value: number): string
Convert a number to its English peso-and-centavos word form. Singular/plural handled ('1 peso' vs '2 pesos').
pesoToWords(1); // 'one peso'
pesoToWords(1234); // 'one thousand two hundred thirty-four pesos'
pesoToWords(1234.56); // 'one thousand two hundred thirty-four pesos and fifty-six centavos'
pesoToWords(-50); // 'negative fifty pesos'
pesoToWords(0); // 'zero pesos'Government ID validators
⚠️ All validators are format-level only. SSS / PhilHealth / Pag-IBIG do not publish official checksum algorithms; unofficial implementations produce confident-but-wrong results in production. This package returns
truefor any input with the correct digit count.
validateTIN(input: string): boolean
BIR TIN: 9 digits (individual) or 12 digits (with 3-digit branch code).
validateTIN('123-456-789'); // true (9-digit individual)
validateTIN('123-456-789-000'); // true (12-digit with branch)
validateTIN('123456789'); // true (digits-only also accepted)
validateTIN('123'); // false
validateTIN('abc-def-ghi'); // falseformatTIN(input: string): string | null
Returns the canonical formatted form, or null if not a valid digit count.
formatTIN('123456789'); // '123-456-789'
formatTIN('123456789000'); // '123-456-789-000'
formatTIN('123'); // nullvalidateSSS(input: string): boolean
SSS number: exactly 10 digits.
validateSSS('12-3456789-0'); // true
validateSSS('1234567890'); // true
validateSSS('123'); // falseformatSSS(input: string): string | null
Formats to XX-XXXXXXX-X, or null if not 10 digits.
formatSSS('1234567890'); // '12-3456789-0'validatePhilHealth(input: string): boolean / formatPhilHealth(input: string): string | null
PhilHealth PIN: exactly 12 digits. Formatted as XX-XXXXXXXXX-X.
validatePhilHealth('123456789012'); // true
formatPhilHealth('123456789012'); // '12-345678901-2'validatePagIBIG(input: string): boolean / formatPagIBIG(input: string): string | null
Pag-IBIG MID: exactly 12 digits. Formatted as XXXX-XXXX-XXXX.
validatePagIBIG('123456789012'); // true
formatPagIBIG('123456789012'); // '1234-5678-9012'Phone
parseMobile(input: string): MobileParse | null
Parse a PH mobile number into a normalized form with network detection. Accepts +63..., 63..., 09..., and 9... forms.
interface MobileParse {
e164: string; // '+63XXXXXXXXXX'
national: string; // '0XXXXXXXXXX'
network: 'Globe' | 'Smart' | 'Sun' | 'DITO' | null;
}parseMobile('09171234567');
// { e164: '+639171234567', national: '09171234567', network: 'Globe' }
parseMobile('+639951234567');
// { e164: '+639951234567', national: '09951234567', network: 'DITO' }
parseMobile('not a phone'); // null
parseMobile('09xxxxxxxxx'); // nullReturns null for non-strings or any input that doesn't normalize to an 11-digit PH mobile starting with 08 (DITO) or 09 (Globe / Smart / Sun / DITO).
parseLandline(input: string): LandlineParse | null
Parse a PH landline number with area code lookup.
interface LandlineParse {
e164: string; // '+63XXXXXXXXXX'
national: string; // '(0X) XXX-XXXX' or '(0XX) XXX-XXXX'
areaCode: string; // '2', '32', '74', etc.
area: string | null; // 'Metro Manila', 'Cebu', etc.
}parseLandline('(02) 8123-4567');
// { e164: '+6328123-4567', national: '(02) 8123-4567', areaCode: '2', area: 'Metro Manila' }
parseLandline('322345678');
// { e164: '+63322345678', national: '(032) 234-5678', areaCode: '32', area: 'Cebu' }
parseLandline('12345'); // nullAddress (PSGC regions + provinces)
Region and province data follows the Philippine Standard Geographic Code at v0.1 granularity (regions + provinces). Cities, municipalities, and barangays are on the v0.2 roadmap.
listRegions(): Region[]
Returns all 17 PH regions.
interface Region {
code: string; // e.g. '04', '13'
name: string; // e.g. 'CALABARZON', 'National Capital Region'
designation: string; // e.g. 'Region IV-A', 'NCR'
}listRegions().length; // 17
listRegions()[0]; // { code: '01', name: 'Ilocos Region', designation: 'Region I' }findRegion(query: string): Region | null
Look up a region by code, name, or designation (case-insensitive).
findRegion('NCR'); // { code: '13', name: 'National Capital Region', ... }
findRegion('04'); // { code: '04', name: 'CALABARZON', ... }
findRegion('calabarzon'); // { code: '04', name: 'CALABARZON', ... }
findRegion('National Capital Region'); // { code: '13', ... }
findRegion('Region IV-A'); // { code: '04', ... }
findRegion('Atlantis'); // nulllistProvinces(regionCode?: string): Province[]
Returns provinces, optionally filtered by region code.
interface Province {
code: string; // 4-digit PSGC code, e.g. '0434'
name: string; // e.g. 'Cavite'
region: string; // parent region code, e.g. '04'
}listProvinces().length; // ~80
listProvinces('04').length; // CALABARZON provinces only
listProvinces('04'); // [{ code: '0420', name: 'Batangas', region: '04' }, ...]findProvince(query: string): Province | null
Look up a province by code or name (case-insensitive).
findProvince('Cebu'); // { code: '0722', name: 'Cebu', region: '07' }
findProvince('0722'); // same
findProvince('cebu'); // same (case-insensitive)
findProvince('Atlantis'); // nullModules table
Direct mapping to the PHP sibling package:
| Capability | JS | PHP |
| --- | --- | --- |
| Format peso | formatPHP(n) | Peso::format($n) |
| Parse peso | parsePHP(s) | Peso::parse($s) |
| Peso to words | pesoToWords(n) | Peso::toWords($n) |
| Validate TIN | validateTIN(s) | Validators\Tin::validate($s) |
| Validate SSS | validateSSS(s) | Validators\Sss::validate($s) |
| Validate PhilHealth | validatePhilHealth(s) | Validators\PhilHealth::validate($s) |
| Validate Pag-IBIG | validatePagIBIG(s) | Validators\PagIbig::validate($s) |
| Parse mobile | parseMobile(s) | Phone::parseMobile($s) |
| Parse landline | parseLandline(s) | Phone::parseLandline($s) |
| List regions | listRegions() | Address::listRegions() |
| Find region | findRegion(q) | Address::findRegion($q) |
| List provinces | listProvinces(code?) | Address::listProvinces($code = null) |
| Find province | findProvince(q) | Address::findProvince($q) |
License
MIT
