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

@ingram-tech/coda

v0.1.0

Published

TypeScript parser for Belgian CODA (Coded statement of account) bank files

Readme

@ingram-tech/coda

TypeScript parser for CODA (Coded statement of account) bank files. CODA is the Belgian standard (maintained by Febelfin) for electronic bank-to-customer account statements, used by all Belgian banks and widely supported across Europe.

Parses CODA v2.x files into fully typed objects. Returns null on invalid input instead of throwing.

Installation

npm install @ingram-tech/coda

Usage

import { parseCoda } from "@ingram-tech/coda";
import { readFileSync } from "node:fs";

const content = readFileSync("statement.cod", "utf-8");
const file = parseCoda(content);

if (file) {
    for (const stmt of file.statements) {
        console.log(`Account: ${stmt.account.number} (${stmt.account.currency})`);
        console.log(`Holder: ${stmt.accountHolderName}`);
        console.log(`Old balance: ${stmt.oldBalance.amount}`);
        console.log(`New balance: ${stmt.newBalance?.amount}`);

        for (const m of stmt.movements) {
            console.log(`  ${m.amount > 0 ? "+" : ""}${m.amount} ${m.counterpartyName ?? ""}`);
            console.log(`    ${m.communication}`);

            if (m.structuredCommunicationType === 101) {
                // Belgian structured payment reference (+++xxx/xxxx/xxxxx+++)
                const ref = m.communication;
                console.log(`    Ref: +++${ref.slice(0, 3)}/${ref.slice(3, 7)}/${ref.slice(7)}+++`);
            }
        }

        for (const msg of stmt.freeCommunications) {
            console.log(`  Message: ${msg}`);
        }
    }
}

Design

  • Single function, null return -- parseCoda(content) returns a CodaFile or null. No exceptions for malformed input.
  • Signed amounts -- Balances and movements are signed numbers: positive for credit, negative for debit. No separate sign field to check.
  • Faithful extraction -- Fields are extracted at their standard-defined positions. Communications are concatenated across record parts (2.1 + 2.2 + 2.3 for movements, 3.1 + 3.2 + 3.3 for information records) and right-trimmed.
  • No deep structured communication parsing -- The communicationType and structuredCommunicationType fields tell you the format; the communication field gives you the raw content. Type 101/102 Belgian structured references come through as 12-digit strings ready for mod-97 validation. More exotic types (127 SEPA direct debit, 105 FX details, etc.) are left as raw strings for the caller to parse.
  • Flat movement model -- Each record 2.1 becomes a CodaMovement, with fields from 2.2 and 2.3 merged in. Information records (3.x) are attached as an information[] array on the preceding movement.

Parsed fields

The parser extracts all fields defined in the CODA v2.8 standard:

  • Header (record 0): creation date, bank ID, duplicate flag, file reference, addressee name, BIC, company ID, separate application code, MT940 references, version
  • Old balance (record 1): account number (Belgian BBAN, foreign BBAN, Belgian IBAN, or foreign IBAN), currency, country code, paper/CODA statement sequence numbers, account holder name, account description, opening balance (signed amount + date)
  • Movements (records 2.1 / 2.2 / 2.3):
    • 2.1: sequence/detail numbers, bank reference, signed amount, value date, entry date, 8-digit transaction code (type/family/transaction/category), communication (structured or free), globalisation code
    • 2.2: customer reference, counterparty BIC, R-transaction type and reason, SEPA CategoryPurpose and Purpose codes
    • 2.3: counterparty account number and currency, counterparty name, communication continuation
  • Information (records 3.1 / 3.2 / 3.3): sequence/detail numbers, bank reference, transaction code, communication (structured or free), linked to parent movement
  • New balance (record 8): closing balance (signed amount + date)
  • Free communications (record 4): free-text messages, grouped by sequence number
  • Trailer (record 9): debit and credit movement totals

API reference

parseCoda(content: string): CodaFile | null

Parse a CODA file. Returns null if the input is empty, doesn't start with a record 0, or cannot be parsed. Handles both \n and \r\n line endings. Multiple statements in a single file (delimited by record 0 boundaries) are supported.

Types

CodaFile

| Field | Type | Description | |-------|------|-------------| | statements | CodaStatement[] | One or more bank statements |

CodaStatement

| Field | Type | Description | |-------|------|-------------| | creationDate | Date | File creation date | | bankId | number | Bank identification number | | isDuplicate | boolean | Whether this is a duplicate file | | fileReference | string? | File reference assigned by the bank | | addressee | string | Name of the addressee | | bic | string? | BIC of the bank holding the account | | companyId | string? | Belgian company identification number | | separateApplication | string | Separate application code (5 positions) | | transactionReference | string? | MT940 transaction reference (tag 20) | | relatedReference | string? | MT940 related reference (tag 21) | | version | number | CODA standard version | | account | CodaAccount | Account details | | paperStatementSequence | number | Paper statement sequence number | | codaStatementSequence | number | CODA statement sequence number | | accountHolderName | string? | Name of the account holder | | accountDescription | string? | Account description | | oldBalance | CodaBalance | Opening balance | | newBalance | CodaBalance? | Closing balance (absent in empty files) | | movements | CodaMovement[] | Transaction movements | | freeCommunications | string[] | Free communication texts | | totalDebit | number | Sum of debit movement amounts from trailer | | totalCredit | number | Sum of credit movement amounts from trailer |

CodaAccount

| Field | Type | Description | |-------|------|-------------| | structure | "belgian-bban" \| "foreign-bban" \| "belgian-iban" \| "foreign-iban" | Account number format | | number | string | Account number (BBAN or IBAN) | | currency | string? | ISO currency code | | countryCode | string? | ISO country code (Belgian BBAN only) |

CodaBalance

| Field | Type | Description | |-------|------|-------------| | amount | number | Signed amount (positive = credit, negative = debit) | | date | Date | Balance date |

CodaMovement

| Field | Type | Description | |-------|------|-------------| | sequenceNumber | number | Continuous sequence number | | detailNumber | number | Detail number within sequence | | bankReference | string | Bank reference (informative) | | amount | number | Signed amount | | valueDate | Date? | Value date | | entryDate | Date | Entry/booking date | | transactionCode | CodaTransactionCode | 8-digit transaction code | | communication | string | Full communication text | | communicationType | "structured" \| "unstructured" | Communication format | | structuredCommunicationType | number? | 3-digit type (e.g. 101, 127) | | paperStatementSequence | number | Paper statement sequence | | globalisationCode | number? | Globalisation hierarchy level (1-9) | | customerReference | string? | Customer reference | | counterpartyBic | string? | Counterparty's bank BIC | | rTransactionType | number? | R-transaction type (1-5) | | rTransactionReason | string? | ISO reason return code | | categoryPurpose | string? | SEPA CategoryPurpose | | purpose | string? | SEPA Purpose | | counterpartyAccountNumber | string? | Counterparty account number | | counterpartyAccountCurrency | string? | Counterparty account currency | | counterpartyName | string? | Counterparty name | | information | CodaInformation[] | Linked information records |

CodaTransactionCode

| Field | Type | Description | |-------|------|-------------| | type | number | Type (0=simple, 1=customer total, 2=bank total, 5/6/7/8/9=details, 3=with detail) | | family | number | Family (01-39 domestic/SEPA, 41-79 foreign, 80-89 other) | | transaction | number | Transaction within family | | category | number | Category (000=net amount, others for cost breakdowns) |

CodaInformation

| Field | Type | Description | |-------|------|-------------| | sequenceNumber | number | Matches parent movement | | detailNumber | number | Detail number | | bankReference | string | Bank reference | | transactionCode | CodaTransactionCode | Transaction code | | communication | string | Full communication text | | communicationType | "structured" \| "unstructured" | Communication format | | structuredCommunicationType | number? | 3-digit type code |

Development

npm test          # run tests in watch mode
npm run test:run  # run tests once
npm run lint      # eslint
npm run format    # prettier
npm run build     # build to dist/
npm run ci        # type-check + lint + test + build

License

MIT