v0.9.0 released — BPJS Module (Kesehatan & Ketenagakerjaan) + Mock Module for deterministic fake Indonesian data. Read changelog
Skip to Content

Mock Generator

Generate structurally valid Indonesian test data for testing and development.

Overview

The Mock module generates fake Indonesian data that passes the library’s own validators:

  • NIK — 16-digit Indonesian national ID
  • Phone — Valid Indonesian mobile numbers with operator prefixes
  • NPWP — Indonesian tax identification numbers
  • Plate — Vehicle license plates (private)
  • Email — Valid email addresses
  • Name — Realistic Indonesian names

Key feature: All generators accept an optional seed for fully deterministic output. Same seed = same data, every time.

Generated data is structurally valid but not real. Do not use for fraudulent purposes.

Features

  • Zero external dependencies (pure algorithms)
  • All generated values pass corresponding validators
  • Deterministic output via optional seed
  • Reuses constants from existing modules
  • Works in Node.js and browser

Installation

npm install @indodev/toolkit

Quick Start

import { generateNIK, generatePhone, generateNPWP, generatePlate, generateEmail, generateName, generateMockPerson, createMockFactory, } from '@indodev/toolkit/mock'; // One-shot generation const nik = generateNIK({ seed: 42 }); // Deterministic NIK const phone = generatePhone({ seed: 42 }); // Deterministic phone const person = generateMockPerson({ seed: 42 }); // Full mock person // Factory for reproducible sequences const factory = createMockFactory(12345); const p1 = factory.generateMockPerson(); const p2 = factory.generateMockPerson(); // p1 and p2 are always the same for the same seed

Determinism

All generator functions accept an optional seed parameter:

// Same seed = same output const nik1 = generateNIK({ seed: 42 }); const nik2 = generateNIK({ seed: 42 }); console.log(nik1 === nik2); // true — always identical

Without a seed, generators use Date.now() as the seed (non-deterministic).

// Without seed — different each time generateNIK(); // Different every call generateNIK(); // Different every call

API Reference

generateNIK(options?)

Generates a structurally valid 16-digit Indonesian NIK.

function generateNIK(options?: NIKMockOptions): string;

Parameters:

NameTypeDefaultDescription
options.gender'M' | 'F'RandomGender for day encoding
options.birthDateDateRandom 1960-2005Birth date to encode
options.provinceCodestringRandom2-digit province code
options.seednumberDate.now()For deterministic output

Returns: 16-digit NIK string

NIK Format: PP KK SS YY MM DD XXXX

  • PP: Province (11-96)
  • KK: Regency (fixed 01)
  • SS: Sub-district (fixed 01)
  • YY: Year (00-30 = 2000s, 31-99 = 1900s)
  • MM: Month (01-12)
  • DD: Day (male: 01-31, female: 41-71 = day+40)
  • XXXX: Serial (fixed 0001)

Examples:

// Random NIK generateNIK(); // '3212012903850001' // Deterministic with seed generateNIK({ seed: 42 }); // Always same output // Specific gender and date generateNIK({ gender: 'F', birthDate: new Date('1990-05-15'), seed: 1 }); // '3201019005550001' (day 15 + 40 = 55 for female) // Specific province generateNIK({ provinceCode: '31', seed: 1 }); // '3101019005550001' (31 = DKI Jakarta)

For female gender with custom birthDate, ensure day ≤ 28 to guarantee valid NIK encoding. Days > 28 may produce invalid day values.


generatePhone(options?)

Generates a valid Indonesian mobile phone number.

function generatePhone(options?: PhoneMockOptions): string;

Parameters:

NameTypeDefaultDescription
options.format'national' | 'international' | 'e164''national'Output format
options.operatorPhoneOperatorRandomMobile operator
options.seednumberDate.now()For deterministic output

Output Formats:

  • national: 08123456789 (11 digits starting with 0)
  • international / e164: +628123456789 (+62 prefix)

Examples:

// Random phone in national format generatePhone(); // '08123456789' // International format generatePhone({ format: 'international', seed: 1 }); // '+628123456789' // Specific operator generatePhone({ operator: 'Telkomsel', seed: 1 }); // '08123456789'

Supported Operators: Telkomsel, XL, Indosat, Axis, Tri, Smartfren


generateNPWP(options?)

Generates a valid Indonesian NPWP (tax identification) number.

function generateNPWP(options?: NPWPMockOptions): string;

Parameters:

NameTypeDefaultDescription
options.format'formatted' | 'raw''raw'Output format
options.seednumberDate.now()For deterministic output

Examples:

// Raw format (15-16 digits) generateNPWP(); // '012345678901234' // Formatted generateNPWP({ format: 'formatted', seed: 1 }); // '01.234.567.8-901.234'

generatePlate(options?)

Generates a valid Indonesian vehicle license plate (private vehicles).

function generatePlate(options?: PlateMockOptions): string;

Parameters:

NameTypeDefaultDescription
options.type'private' | 'public''private'Plate type
options.regionstringRandomSingle letter region code
options.seednumberDate.now()For deterministic output

Format: X 0000 XX (letter + space + 4 digits + space + 2 letters)

Examples:

generatePlate(); // 'B 1234 ABC' generatePlate({ region: 'D', seed: 1 }); // 'D 5678 XY'

Only private plates are supported. Public plates are out of scope.


generateEmail(options?)

Generates a valid Indonesian email address.

function generateEmail(options?: EmailMockOptions): string;

Parameters:

NameTypeDefaultDescription
options.domainstringRandomEmail domain
options.seednumberDate.now()For deterministic output

Examples:

generateEmail(); // 'agus@gmail.com' generateEmail({ domain: 'yahoo.co.id', seed: 1 }); // 'budi@yahoo.co.id' // Same seed produces same email generateEmail({ seed: 42 }); // Always same generateEmail({ seed: 42 }); // Always same

Email uniqueness is NOT guaranteed. Collisions are acceptable and expected.


generateName(options?)

Generates a realistic Indonesian name.

function generateName(options?: NameMockOptions): string;

Parameters:

NameTypeDefaultDescription
options.gender'M' | 'F'RandomGender for name selection
options.parts'first' | 'last' | 'full''full'Which parts to return
options.seednumberDate.now()For deterministic output

Examples:

// Full name generateName(); // 'Budi Santoso' generateName({ gender: 'F' }); // 'Siti Rahayu' // First name only generateName({ parts: 'first', seed: 1 }); // 'Agus' // Last name only generateName({ parts: 'last', seed: 1 }); // 'Santoso'

generateMockPerson(options?)

Generates a complete mock person with consistent data across all fields.

function generateMockPerson(options?: MockPersonOptions): MockPerson;

Parameters:

NameTypeDefaultDescription
options.gender'M' | 'F'RandomGender for all fields
options.seednumberDate.now()For deterministic output

Returns: MockPerson object

interface MockPerson { name: string; // Full name gender: 'M' | 'F'; // Consistent across fields birthDate: string; // ISO 8601: 'YYYY-MM-DD' nik: string; // Passes validateNIK() npwp: string; // Passes validateNPWP() phone: string; // Passes validatePhoneNumber() email: string; // Passes validateEmail() plate: string; // Passes validatePlate() }

Examples:

const person = generateMockPerson({ seed: 42 }); // { // name: 'Agus Santoso', // gender: 'M', // birthDate: '1985-03-15', // nik: '3201018503150001', // npwp: '012345678901234', // phone: '08123456789', // email: 'agus@gmail.com', // plate: 'B 1234 ABC' // } // Female with specific gender const female = generateMockPerson({ gender: 'F', seed: 1 }); // Gender is consistent: NIK encodes female day, name uses female list

createMockFactory(seed)

Creates a factory for generating reproducible sequences of mock data.

function createMockFactory(seed: number): MockFactory;

Parameters:

NameTypeDescription
seednumberSeed for reproducible sequences

Returns: MockFactory instance with all generator methods

Example:

const factory = createMockFactory(12345); const p1 = factory.generateMockPerson(); const p2 = factory.generateMockPerson(); const p3 = factory.generateNIK(); // All deterministic — same seed = same output // Every time you create factory with 12345, you get same sequence

Types

MockGender

type MockGender = 'M' | 'F';

PhoneOperator

type PhoneOperator = 'Telkomsel' | 'XL' | 'Indosat' | 'Axis' | 'Tri' | 'Smartfren';

PhoneFormat

type PhoneFormat = 'national' | 'international' | 'e164';

NPWPFormat

type NPWPFormat = 'formatted' | 'raw';

PlateType

type PlateType = 'private' | 'public';

NameParts

type NameParts = 'first' | 'last' | 'full';

NIKMockOptions

interface NIKMockOptions { gender?: MockGender; birthDate?: Date; provinceCode?: string; seed?: number; }

MockPersonOptions

interface MockPersonOptions { gender?: MockGender; seed?: number; }

MockFactory

interface MockFactory { generateNIK(options?: Omit<NIKMockOptions, 'seed'>): string; generatePhone(options?: Omit<PhoneMockOptions, 'seed'>): string; generateNPWP(options?: Omit<NPWPMockOptions, 'seed'>): string; generatePlate(options?: Omit<PlateMockOptions, 'seed'>): string; generateEmail(options?: Omit<EmailMockOptions, 'seed'>): string; generateName(options?: Omit<NameMockOptions, 'seed'>): string; generateMockPerson(options?: Omit<MockPersonOptions, 'seed'>): MockPerson; }

Validation Guarantee

Every generator is designed so its output passes the corresponding validator:

GeneratorValidator
generateNIK()validateNIK() from @indodev/toolkit/nik
generatePhone()validatePhoneNumber() from @indodev/toolkit/phone
generateNPWP()validateNPWP() from @indodev/toolkit/npwp
generatePlate()validatePlate() from @indodev/toolkit/plate
generateEmail()validateEmail() from @indodev/toolkit/email-validator
const nik = generateNIK({ seed: 42 }); validateNIK(nik); // true — always passes const phone = generatePhone({ seed: 42 }); validatePhoneNumber(phone); // true — always passes
Last updated on