npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ekwo-ai/journal-report

v0.8.0

Published

Reads a journal report or a general ledger detail saved as CSV — date, journal number, account code, debit, credit — with the chart of accounts and the contacts exported beside it, into plain objects in TypeScript: amounts as decimal strings, and what doe

Readme

@ekwo-ai/journal-report

Reads a journal report, or a general ledger detail, saved as CSV — the report a cloud ledger prints of every journal it posted, one row per line with the number of its journal — into plain objects, in TypeScript, with no dependencies. Beside it, the chart of accounts and the contacts, which the same ledger exports as CSV directly.

import { readJournalReport } from '@ekwo-ai/journal-report';

const books = readJournalReport([report, chart, contacts], { dateOrder: 'dmy' });

books.entries;    // [{ number: '102', journal: 'Receivable Invoice', date: '2025-01-15', lines: […] }, …]
books.accounts;   // [{ code: '090', name: 'Business Bank Account', type: 'Bank' }, …]
books.violations; // a journal that does not balance

The files

The report (required). Such a service exports its reports as a spreadsheet, not as CSV: open it and save it as CSV. A report is laid out for a person, so:

  • the header is the first row that names a Date, an Account Code, a Debit and a Credit — the title rows above it are passed over;
  • a line is a row whose date cell holds a date; the rows that head a group, total it, or give an opening or closing balance are passed over;
  • lines are gathered into entries by their journal number (Journal ID, Journal Number, Journal #), which the report has to carry: add the column in the report's column picker before exporting it, with the account code. A report without it is refused by name — there would be no way to put its lines back into entries.

Optional columns: Source (kept as the journal of the entry), Account, Description, Narration, Reference, Contact.

  • A date written in digits — 03/04/2026 — is read in the order the caller names (dateOrder: 'dmy' | 'mdy' | 'ymd') and refused without one: the order follows the region of the organisation, and the file does not say it. A date in ISO or with its month in letters (3 Apr 2026) needs none.
  • An amount is read as a spreadsheet displays it. In a comma-separated file the decimal mark is a point and a comma only groups thousands, three digits at a time (1,234.50). In a file separated by a semicolon or a tab the decimal mark is the one mark the number carries, and thousands are grouped by a space only. A negative is a minus or brackets. Anything else is refused.

The chart of accounts (optional): *Code, *Name, *Type, the rest ignored. Codes are kept as text: 090 stays 090.

The contacts (optional): *ContactName, AccountNumber, EmailAddress, TaxNumber, CompanyNumber; the country only when it is written as a two-letter code.

What it returns

The shape declared in src/types.ts, which is, field for field, the shape every reader of an accounting export in this repository declares for itself. A report says no currency: it prints the organisation's and does not name it. Amounts are decimal strings, never negative. What does not add up comes back in violations; what is not a report is thrown as a BooksFileError with a code.

It knows no chart of accounts: in Ekwo OS the correspondence is made by ekwo import journal-report <files…> --date-order dmy.

Sources

This reader was written against the reports of Xero, read on 22 September 2026 from its help centre:

ekwo import xero <files…> is the same as ekwo import journal-report.

What those pages do not state — the exact text of the title and total rows — is why the reader finds the header by its columns and a line by its date, rather than by position. The fixtures under test/fixtures/ are written by hand from those pages and hold no real data.

MIT.