UNPKG

@earvinpiamonte/pagasa-tcb-parser

Version:

A TypeScript library for parsing PAGASA weather bulletin PDF files

259 lines (193 loc) 7.07 kB
# `pagasa-tcb-parser` [![npm version](https://img.shields.io/npm/v/@earvinpiamonte/pagasa-tcb-parser.svg)](https://www.npmjs.com/package/@earvinpiamonte/pagasa-tcb-parser) [![Tests](https://github.com/earvinpiamonte/pagasa-tcb-parser/actions/workflows/tests.yml/badge.svg)](https://github.com/earvinpiamonte/pagasa-tcb-parser/actions/workflows/tests.yml) A TypeScript library for parsing [PAGASA](https://www.pagasa.dost.gov.ph/) (Philippine Atmospheric, Geophysical and Astronomical Services Administration) tropical cyclone bulletin (TCB) and advisory (TCA) PDF files. ## Installation ```bash npm i @earvinpiamonte/pagasa-tcb-parser ``` ## Usage ### Basic ```javascript import parseTcbPdf from "@earvinpiamonte/pagasa-tcb-parser"; async function run() { const bulletin = await parseTcbPdf("/path/to/TCB#16_emong.pdf"); console.log(bulletin); } run(); ``` ### Error Handling #### Using async/ await ```javascript import parseTcbPdf from "@earvinpiamonte/pagasa-tcb-parser"; const run = async () => { try { const bulletin = await parseTcbPdf("/path/to/TCB#16_emong.pdf"); console.log(bulletin); } catch (error) { console.error("Failed to parse TCB:", error.message); } }; run(); ``` #### Using Promises with `.then().catch()` ```javascript import parseTcbPdf from "@earvinpiamonte/pagasa-tcb-parser"; parseTcbPdf("/path/to/TCB#16_emong.pdf") .then((bulletin) => { console.log(bulletin); }) .catch((error) => { console.error("Failed to parse TCB:", error.message); }); ``` #### Example fetching and parsing from external source ```javascript import express from "express"; import parseTcbPdf from "@earvinpiamonte/pagasa-tcb-parser"; const app = express(); app.get("/your/api/get-tcb", async (req, res) => { try { const response = await fetch( "https://pubfiles.pagasa.dost.gov.ph/tamss/weather/bulletin/TCB%2316_emong.pdf" ); const buffer = await response.buffer(); const bulletin = await parseTcbPdf(buffer); res.json(bulletin); } catch (error) { res.status(500).json({ error: "Failed to parse TCB" }); } }); ``` > [!NOTE] > `parseTcbPdf` supports both file path (string) and Buffer input. ### Example output The parser returns a structured JavaScript object: <details> <summary>Toggle example code</summary> ```json { "title": "TROPICAL CYCLONE BULLETIN NR. 16", "subtitle": "Tropical Storm EMONG (CO-MAY)", "description": "EMONG WEAKENS INTO A TROPICAL STORM AND IS NOW PASSING CLOSE TO THE BABUYAN ISLANDS", "dateIssued": "July 25, 2025 2:00 PM", "dateIssuedISO": "2025-07-25T06:00:00.000Z", "dateValidUntil": "July 25, 2025 5:00 PM", "dateValidUntilISO": "2025-07-25T09:00:00.000Z", "cyclone": { "name": "EMONG", "internationalName": "CO-MAY", "signals": [ { "level": 1, "regions": { "luzon": [ { "name": "Ilocos Norte", "parts": ["rest"] }, { "name": "Ilocos Sur", "parts": ["northern"], "locals": ["Gregorio del Pilar", "Magsingal" /* ... */] }, { "name": "Abra" }, { "name": "Apayao", "parts": ["rest"] }, { "name": "Kalinga" }, { "name": "Mountain Province" }, { "name": "Cagayan", "parts": ["rest", "mainland"] }, { "name": "Isabela", "parts": ["northern"], "locals": ["Quirino", "Mallig" /* ... */] } ], "visayas": [], "mindanao": [] } }, { "level": 2, "regions": { "luzon": [ /* ... */ ], "visayas": [], "mindanao": [] } } ] } } ``` </details> ### API The package exports a single function that can handle both file paths and buffers: | Function/Method | Parameters | Returns | Description | | -------------------------- | ---------------------------------------------------------- | --------------------- | ------------------------------------------------------------------- | | `parseTcbPdf(input)` | `input`: `string` or `Buffer` | `ParsedTcbPdfPromise` | Parses a PDF from a file path or buffer. | | `.jsonStringified(space?)` | `space?`: `number` or `string` (optional, defaults to `2`) | `Promise<string>` | A chainable method that returns the parsed result as a JSON string. | #### Function Signature ```typescript import { ParsedTcbPdfPromise } from "@earvinpiamonte/pagasa-tcb-parser"; /** * Parses a PAGASA TCB PDF from a file path or Buffer. * Returns a ParsedTcbPdfPromise: a Promise<BulletinData>. */ declare function parseTcbPdf(input: string | Buffer): ParsedTcbPdfPromise; ``` ## Development ### TypeScript Support This package is written in TypeScript and includes type definitions. > **Note:** The package exports the `ParsedTcbPdfPromise` type for advanced typing, which extends `Promise<BulletinData>` with a `.jsonStringified()` method. ```typescript import parseTcbPdf, { ParsedTcbPdfPromise, BulletinData, Regions, Area, CycloneInfo, } from "@earvinpiamonte/pagasa-tcb-parser"; // Option 1: Keep the promise (for chaining .jsonStringified later) const promise: ParsedTcbPdfPromise = parseTcbPdf("/path/to/file.pdf"); const bulletin: BulletinData = await promise; // resolved value const jsonResult: string = await promise.jsonStringified(); // Option 2: Direct await (no need to store promise separately) const bulletin2: BulletinData = await parseTcbPdf("/path/to/another.pdf"); // Access signal data (array) const signalNumberOne = bulletin.cyclone.signals[0]?.level; // number | undefined const firstLuzonArea: Area | undefined = bulletin.cyclone.signals[0]?.regions.luzon[0]; // Find a specific signal level const signalNumberTwo = bulletin.cyclone.signals.find( (signal) => signal.level === 2 ); // Length check if (bulletin.cyclone.signals.length === 0) { // no active signals } ``` ### Testing This project uses [Jest](https://jestjs.io) for testing. #### Prerequisites Make sure you have the dependencies installed: ```bash cd pagasa-tcb-parser/ ``` ```bash npm i ``` #### Running Tests ```bash npm test ``` #### Test Structure The tests are located in the `tests/` directory and include the ff: - **Unit Tests**: `tests/pdf-parser.test.ts` - Tests the core PDF parsing functionality - **Test Data**: `tests/data/` - Contains sample PAGASA TCB PDF files for testing #### Test Data The test suite includes several sample PAGASA TCB PDF files: - `TCB#15_emong.pdf` - `TCB#16_emong.pdf` - `TCB#17_emong.pdf` - `TCB#18_emong.pdf` ### Supported Formats Currently, PAGASA Tropical Cyclone Bulletin PDF files that contain TCWS (Tropical Cyclone Wind Signals) information are supported by this package. ## Maintainer Designed and developed by [Noel Earvin Piamonte](https://earv.in)