# sakti-parser-fa

> Simple TypeScript library for parsing Indonesian government budget Excel files (Sakti FA format).

[![npm version](https://badge.fury.io/js/sakti-parser-fa.svg)](https://www.npmjs.com/package/sakti-parser-fa)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## ✨ Features

- 🌐 **Universal** - Works seamlessly in Node.js and browsers
- 🎯 **Simple API** - Just pass ExcelJS worksheet data  
- 📝 **TypeScript** - Full type definitions included
- 📊 **Multiple formats** - JSON and CSV output
- 🚀 **Zero platform deps** - No file system dependencies
- 🔧 **Lightweight** - Single purpose, minimal footprint

## 📦 Installation

```bash
npm install sakti-parser-fa
```

No additional dependencies needed! ExcelJS is included.

## 🚀 Quick Start

### Node.js

```typescript
import { SaktiParser, SaktiFormatter } from 'sakti-parser-fa';

// Parse Excel file directly with file path
const parser = new SaktiParser();
const result = await parser.parse('budget.xlsx');

// Format output
const formatter = new SaktiFormatter();
const json = formatter.format(result, { format: 'json' });
const csv = formatter.format(result, { format: 'csv' });

console.log('Metadata:', result.metadata);
console.log('Data rows:', result.data.length);
```

### Browser (React/Vue/Vanilla)

```typescript
import { SaktiParser, SaktiFormatter } from 'sakti-parser-fa';

async function parseExcelFile(file: File) {
  // Parse file directly - no ExcelJS needed!
  const parser = new SaktiParser();
  const result = await parser.parse(file);
  
  const formatter = new SaktiFormatter();
  return formatter.format(result, { format: 'json' });
}

// React example
function FileUpload() {
  const handleFile = async (e) => {
    const file = e.target.files[0];
    const parsed = await parseExcelFile(file);
    console.log(JSON.parse(parsed));
  };
  
  return <input type="file" accept=".xlsx" onChange={handleFile} />;
}
```

## 📋 Complete Example

```typescript
import { SaktiParser, SaktiFormatter, type ParseResult } from 'sakti-parser-fa';

async function processBudget(filePath: string) {
  try {
    // 1. Parse SAKTI Excel file directly
    const parser = new SaktiParser();
    const result: ParseResult = await parser.parse(filePath);

    // 2. Access parsed data
    console.log('Ministry:', result.metadata.kementerian_nama);
    console.log('Period:', result.metadata.periode_text);
    console.log('Budget items:', result.data.length);

    // 3. Export as needed
    const formatter = new SaktiFormatter();
    
    // JSON with metadata
    const json = formatter.format(result, { 
      format: 'json', 
      includeMetadata: true 
    });
    
    // CSV without metadata  
    const csv = formatter.format(result, { 
      format: 'csv', 
      includeMetadata: false 
    });

    return { json, csv, result };
  } catch (error) {
    console.error('Failed to process budget file:', error);
    throw error;
  }
}

// Works with File objects too (browser)
async function processBudgetFromFile(file: File) {
  const parser = new SaktiParser();
  return await parser.parse(file);
}

// Works with ArrayBuffer too
async function processBudgetFromBuffer(buffer: ArrayBuffer) {
  const parser = new SaktiParser();
  return await parser.parse(buffer);
}
```

## 📚 API Reference

### `SaktiParser`

Main parser class for processing SAKTI Excel files.

```typescript
class SaktiParser {
  async parse(input: UniversalInput): Promise<ParseResult>
}

type UniversalInput = string | File | ArrayBuffer;
```

**Parameters:**
- `input` - File path (string), File object, or ArrayBuffer

**Returns:** Promise resolving to `ParseResult`

### `SaktiFormatter`

Formats parse results into different output formats.

```typescript
class SaktiFormatter {
  format(result: ParseResult, options?: FormatOptions): string
}

interface FormatOptions {
  format?: 'json' | 'csv';          // Output format (default: 'json')
  includeMetadata?: boolean;        // Include metadata (default: true)
}
```

## 📊 Data Structure

### `ParseResult`

```typescript
interface ParseResult {
  metadata: Metadata;       // Document metadata
  data: ParsedData[];      // Parsed budget data
}
```

### `Metadata`

```typescript
interface Metadata {
  judul: string;                    // Document title
  periode_text: string;             // Period text (e.g., "Januari 2024")
  periode_bulan: number;            // Month number (1-12)
  periode_tahun: number;            // Year
  kementerian_kode: string;         // Ministry code
  kementerian_nama: string;         // Ministry name
  unit_kode: string;                // Unit code
  unit_nama: string;                // Unit name
  satuan_kerja_kode: string;        // Work unit code
  satuan_kerja_nama: string;        // Work unit name
}
```

### `ParsedData`

Hierarchical budget data with up to 11 levels:

```typescript
interface ParsedData {
  _level: number;                   // Current level (1-11)
  _parent: string;                  // Parent reference
  mata_anggaran: string;            // Budget type
  
  // Level 1-11 codes and descriptions
  level_1_kode: string;
  level_1_uraian: string;
  level_2_kode: string;
  level_2_uraian: string;
  // ... up to level_11_kode, level_11_uraian
  
  nilai_rupiah: number;             // Amount in rupiah
  nilai_total: number;              // Total amount
}
```

## 🛠️ Development

```bash
# Clone repository
git clone https://github.com/username/sakti-parser-fa.git
cd sakti-parser-fa

# Install dependencies
npm install

# Build
npm run build

# Test
npm test

# Development mode
npm run dev
```

## 📝 Requirements

- Node.js 18+
- No additional dependencies (ExcelJS included)

## 🤝 Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## 📄 License

MIT License - see the [LICENSE](LICENSE) file for details.

## 🙋‍♂️ Support

- 📖 [Documentation](https://github.com/username/sakti-parser-fa)
- 🐛 [Issues](https://github.com/username/sakti-parser-fa/issues)
- 💬 [Discussions](https://github.com/username/sakti-parser-fa/discussions)

---

**Made with ❤️ for Indonesian government budget transparency**