JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 18
  • Score
    100M100P100Q26140F
  • License MIT

Universal TypeScript library for parsing Indonesian government budget Excel files (Sakti FA) - works in both browser and Node.js

Package Exports

  • sakti-parser-fa
  • sakti-parser-fa/browser
  • sakti-parser-fa/core
  • sakti-parser-fa/node

Readme

Sakti Parser FA

npm version License: MIT TypeScript

Universal TypeScript library untuk mem-parsing file Excel Laporan Ketersediaan Dana (FA) dari sistem Sakti Kementerian Keuangan RI. Bekerja di browser dan Node.js.

โœจ Fitur Utama

  • ๐ŸŒ Universal - Bekerja di browser dan server
  • ๐Ÿ—๏ธ Parsing Hierarki - Struktur anggaran 11 level sesuai Sakti
  • ๐Ÿ“Š Multi Format - Object, JSON, dan CSV output
  • โœ… Validasi Data - Otomatis cleaning dan validasi
  • ๐Ÿ”’ Type Safety - Full TypeScript support
  • ๐Ÿ‡ฎ๐Ÿ‡ฉ Bahasa Indonesia - Parsing tanggal dan format lokal
  • โšก Performance - Optimized untuk file besar

๐Ÿ“ฆ Instalasi

npm install sakti-parser-fa

๐Ÿš€ Quick Start

Browser (React.js)

import React, { useState } from 'react';
import { SaktiParser } from 'sakti-parser-fa/browser';

function ExcelUploader() {
  const [result, setResult] = useState(null);
  const [loading, setLoading] = useState(false);

  const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;

    setLoading(true);
    try {
      const parser = new SaktiParser({
        outputFormat: 'object'
      });
      
      const parseResult = await parser.parseStructuredData(file);
      setResult(parseResult);
    } catch (error) {
      console.error('Error parsing file:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <input 
        type="file" 
        accept=".xlsx" 
        onChange={handleFileUpload}
        disabled={loading}
      />
      
      {loading && <p>Processing...</p>}
      
      {result && (
        <div>
          <h3>๐Ÿ“‹ Metadata</h3>
          <p>Judul: {result.metadata.judul}</p>
          <p>Periode: {result.metadata.periode_text}</p>
          <p>Kementerian: {result.metadata.kementerian_nama}</p>
          
          <h3>๐Ÿ“Š Data</h3>
          <p>Total items: {result.data.length}</p>
          
          {/* Show first 5 items */}
          {result.data.slice(0, 5).map((item, index) => (
            <div key={index} style={{ marginLeft: item._level * 20 }}>
              <strong>Level {item._level}:</strong> {item.uraian}
              <br />
              <small>Budget: Rp {item.pagu.toLocaleString('id-ID')}</small>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

export default ExcelUploader;

Server (Express.js)

import express from 'express';
import multer from 'multer';
import { SaktiParser } from 'sakti-parser-fa/node';

const app = express();
const upload = multer({ dest: 'uploads/' });

// Parse Excel file endpoint
app.post('/api/parse-excel', upload.single('excelFile'), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ error: 'No file uploaded' });
    }

    const parser = new SaktiParser({
      outputFormat: 'json'
    });

    // Parse the uploaded file
    const result = await parser.parseStructuredData(req.file.path);
    
    // Return parsed data
    res.json({
      success: true,
      metadata: result.metadata,
      dataCount: result.data.length,
      data: result.data
    });

  } catch (error) {
    console.error('Parsing error:', error);
    res.status(500).json({ 
      error: 'Failed to parse Excel file',
      message: error.message 
    });
  }
});

// Get summary endpoint
app.post('/api/parse-summary', upload.single('excelFile'), async (req, res) => {
  try {
    const parser = new SaktiParser();
    const result = await parser.parseStructuredData(req.file.path);
    
    // Calculate summary
    const summary = {
      metadata: result.metadata,
      totalItems: result.data.length,
      totalBudget: result.data
        .filter(item => item._level === 11)
        .reduce((sum, item) => sum + item.pagu, 0),
      levelBreakdown: {}
    };
    
    // Count items by level
    result.data.forEach(item => {
      summary.levelBreakdown[item._level] = 
        (summary.levelBreakdown[item._level] || 0) + 1;
    });
    
    res.json(summary);
    
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

๐Ÿ“‹ Data Structure

Input: Excel FA File

File Excel dengan struktur:

  • Baris 1: Judul laporan
  • Baris 3: Periode (contoh: "Periode Juli 2025")
  • Baris 4-6: Metadata kementerian, unit, satuan kerja
  • Baris 10+: Data anggaran hierarki (11 level)

Output: Structured Data

interface ParseResult {
  metadata: {
    judul: string;
    periode_text: string;
    periode_bulan: number;        // 1-12
    periode_tahun: number;        // 2025
    kementerian_kode: string;     // "145"
    kementerian_nama: string;     // "KEMENTERIAN KEUANGAN"
    unit_kode: string;            // "06"
    unit_nama: string;            // "SEKRETARIAT JENDERAL"
    satuan_kerja_kode: string;    // "123456"
    satuan_kerja_nama: string;    // "BIRO KEUANGAN"
  };
  data: Array<{
    _level: number;               // 1-11 (hierarchy level)
    _parent: string;              // Parent mata anggaran
    mata_anggaran: string;        // Full budget code
    kode: string;                 // Item code
    uraian: string;               // Description
    pagu: number;                 // Budget amount (Rupiah)
    pagu_terkunci: number;        // Locked budget
    realisasi_sebelum: number;    // Previous realization
    realisasi_periode: number;    // Current period realization
    realisasi_kumulatif: number;  // Total realization
    realisasi_persen: number;     // Realization percentage (0.0-1.0)
    sisa_anggaran: number;        // Remaining budget
  }>;
}

๐Ÿ”ง Configuration Options

const parser = new SaktiParser({
  // Output format
  outputFormat: 'object' | 'json' | 'csv',
  
  // CSV options
  csvOptions: {
    delimiter: ';',          // Column separator
    header: true,            // Include header row
    quoted: true             // Quote all fields
  },
  
  // JSON options
  jsonOptions: {
    flat: true              // Flat array vs nested object
  }
});

๐Ÿ’ก Advanced Usage

Universal Parser (Auto-detect Environment)

import { UniversalSaktiParser } from 'sakti-parser-fa';

const parser = new UniversalSaktiParser();

// Works in Node.js
const result1 = await parser.parse('./file.xlsx');

// Works in browser
const result2 = await parser.parse(fileObject);

// Works everywhere
const result3 = await parser.parse(worksheetData);

Multiple Output Formats

// Get different formats
const objectResult = await parser.parseAndFormat(input); // Default: object
const jsonResult = await parser.parseAndFormat(input, { outputFormat: 'json' });
const csvResult = await parser.parseAndFormat(input, { outputFormat: 'csv' });

Custom CSV Export

const parser = new SaktiParser({
  outputFormat: 'csv',
  csvOptions: {
    delimiter: ';',
    header: true,
    quoted: true
  }
});

const result = await parser.parseAndFormat('file.xlsx');
// result.content.data contains CSV string

๐Ÿ“Š Bundle Sizes

  • Core: 36KB (pure parsing logic)
  • Browser: 43KB (includes File handling)
  • Node.js: 42KB (includes file reading)
  • Universal: 41KB (auto-detection)

All bundles are gzipped and include TypeScript definitions.

๐ŸŒ Browser Support

  • Modern Browsers: Chrome 80+, Firefox 75+, Safari 13+, Edge 80+
  • Mobile: iOS Safari 13+, Chrome Android 80+
  • Bundle: ES2020 modules with tree-shaking support

๐Ÿ“ Examples

๐Ÿงช Testing

npm test              # Run all tests
npm run test:coverage # Run with coverage
npm run test:watch    # Watch mode

Test Coverage: 85%+ with 88 test cases across all platforms.

๐Ÿ“„ License

MIT License - see LICENSE file.

๐Ÿท๏ธ Keywords

sakti kementerian-keuangan anggaran excel-parser typescript universal browser nodejs indonesia government budget hierarchical-data


Dibuat dengan โค๏ธ untuk komunitas developer Indonesia

๐Ÿ“– Documentation โ€ข ๐Ÿ’ก Examples โ€ข ๐Ÿ› Issues โ€ข ๐Ÿ’ฌ Discussions