pinoy-kredit-parser 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.MD CHANGED
@@ -1,6 +1,6 @@
1
1
  # pinoy-kredit-parser
2
2
 
3
- A lightweight Node.js library for parsing Philippine credit card statement PDFs into structured transaction data.
3
+ A lightweight, isomorphic library for parsing Philippine credit card statement PDFs into structured transaction data. Works in Node.js, Browsers, and Next.js.
4
4
 
5
5
  Currently supports:
6
6
 
@@ -39,44 +39,50 @@ npm install pinoy-kredit-parser
39
39
  ---
40
40
 
41
41
  ## Usage
42
+ The library automatically detects your environment (Node vs. Browser) to provide the correct parsing engine.
43
+
42
44
  ### Using a file path (Node.js)
43
45
  ```javascript
44
- const { parseKredit, BankType } = require('pinoy-kredit-parser')
46
+ import { parseKredit, BankType } from 'pinoy-kredit-parser';
45
47
 
46
- async function main() {
47
- const transactions = await parseKredit('statement.pdf', {
48
+ const transactions = await parseKredit('./statement.pdf', {
48
49
  bank: BankType.RCBC,
49
- })
50
-
51
- console.log(transactions)
52
- }
53
-
54
- main()
50
+ });
55
51
  ```
56
- ### Using a File object (Browser / modern runtimes)
52
+ ### Browser / Next.js Client Components (File or ArrayBuffer)
57
53
  ```javascript
58
- import { parseKredit, BankType } from 'pinoy-kredit-parser'
59
-
60
- async function handleFile(file) {
61
- const transactions = await parseKredit(file, {
62
- bank: BankType.METROBANK,
63
- })
54
+ import { parseKredit, BankType } from 'pinoy-kredit-parser';
55
+
56
+ const handleUpload = async (event) => {
57
+ const file = event.target.files[0];
58
+ const transactions = await parseKredit(file, {
59
+ bank: BankType.UNIONBANK,
60
+ });
61
+ };
62
+ ```
64
63
 
65
- console.log(transactions)
66
- }
64
+ ### Next.js (App Router / API Routes)
65
+ When using this library in Next.js, you must add it to `serverExternalPackages` in your `next.config.ts` to correctly handle the native PDF rendering binaries.
66
+ ```javascript
67
+ // next.config.ts
68
+ const nextConfig = {
69
+ experimental: {
70
+ serverExternalPackages: ['pinoy-kredit-parser', 'pdf-parse', '@napi-rs/canvas'],
71
+ },
72
+ };
67
73
  ```
68
74
 
69
75
  ---
70
76
 
71
77
  ## Output Format
72
78
 
73
- Each transaction is returned as:
79
+ Transactions are returned in a clean, structured format:
74
80
  ```typescript
75
81
  type KreditTransaction = {
76
- saleDate: string
77
- postDate: string
78
- description: string
79
- amount: number
82
+ saleDate: string; // MM/DD/YY
83
+ postDate: string; // MM/DD/YY
84
+ description: string;
85
+ amount: number; // Positive for purchases, negative for payments/credits
80
86
  }
81
87
  ```
82
88
  Example:
@@ -90,6 +96,12 @@ Example:
90
96
  }
91
97
  ]
92
98
  ```
99
+ ---
100
+ ## Features
101
+ - **Isomorphic:** Shared logic for server-side and client-side parsing.
102
+ - **Zero Global Pollution:** No need for manual DOMMatrix or Canvas polyfills.
103
+ - **Next.js Ready:** Optimized for modern frameworks with automatic environment detection.
104
+ - **Privacy-First:** All parsing happens locally on your machine. No data is ever sent to a server.
93
105
 
94
106
  ---
95
107
 
package/dist/browser.d.ts CHANGED
@@ -4,3 +4,6 @@ type BrowserInput = File | Blob | ArrayBuffer | Uint8Array;
4
4
  export declare const parseKredit: (input: BrowserInput, options: {
5
5
  bank: BankType;
6
6
  }) => Promise<import("./types").KreditTransaction[]>;
7
+ export declare const parseKreditMeta: (input: BrowserInput, options: {
8
+ bank: BankType;
9
+ }) => Promise<import("./types").KreditMeta>;
package/dist/browser.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.parseKredit = void 0;
17
+ exports.parseKreditMeta = exports.parseKredit = void 0;
18
18
  const core_1 = require("./core");
19
19
  __exportStar(require("./types"), exports);
20
20
  const parseKredit = async (input, options) => {
@@ -22,4 +22,9 @@ const parseKredit = async (input, options) => {
22
22
  return (0, core_1.baseParseKredit)(new Uint8Array(data), options);
23
23
  };
24
24
  exports.parseKredit = parseKredit;
25
+ const parseKreditMeta = async (input, options) => {
26
+ const data = input instanceof File || input instanceof Blob ? await input.arrayBuffer() : input;
27
+ return (0, core_1.baseParseMeta)(new Uint8Array(data), options);
28
+ };
29
+ exports.parseKreditMeta = parseKreditMeta;
25
30
  //# sourceMappingURL=browser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iCAAwC;AAGxC,0CAAuB;AAIhB,MAAM,WAAW,GAAG,KAAK,EAAE,KAAmB,EAAE,OAA2B,EAAE,EAAE;IACpF,MAAM,IAAI,GAAG,KAAK,YAAY,IAAI,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;IAE/F,OAAO,IAAA,sBAAe,EAAC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;AACvD,CAAC,CAAA;AAJY,QAAA,WAAW,eAIvB"}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iCAAuD;AAGvD,0CAAuB;AAIhB,MAAM,WAAW,GAAG,KAAK,EAAE,KAAmB,EAAE,OAA2B,EAAE,EAAE;IACpF,MAAM,IAAI,GAAG,KAAK,YAAY,IAAI,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;IAE/F,OAAO,IAAA,sBAAe,EAAC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;AACvD,CAAC,CAAA;AAJY,QAAA,WAAW,eAIvB;AAEM,MAAM,eAAe,GAAG,KAAK,EAAE,KAAmB,EAAE,OAA2B,EAAE,EAAE;IACxF,MAAM,IAAI,GAAG,KAAK,YAAY,IAAI,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;IAE/F,OAAO,IAAA,oBAAa,EAAC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;AACrD,CAAC,CAAA;AAJY,QAAA,eAAe,mBAI3B"}
package/dist/core.d.ts CHANGED
@@ -1,5 +1,9 @@
1
- import { BankType, KreditTransaction } from './types';
1
+ import { BankType, KreditMeta, KreditTransaction } from './types';
2
2
  export declare const baseParseKredit: (data: Buffer | Uint8Array, options: {
3
3
  bank: BankType;
4
4
  CanvasFactory?: any;
5
5
  }) => Promise<KreditTransaction[]>;
6
+ export declare const baseParseMeta: (data: Buffer | Uint8Array, options: {
7
+ bank: BankType;
8
+ CanvasFactory?: any;
9
+ }) => Promise<KreditMeta>;
package/dist/core.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.baseParseKredit = void 0;
3
+ exports.baseParseMeta = exports.baseParseKredit = void 0;
4
4
  const pdf_parse_1 = require("pdf-parse");
5
5
  const types_1 = require("./types");
6
6
  const rcbc_1 = require("./parsers/rcbc");
@@ -24,4 +24,73 @@ const baseParseKredit = async (data, options) => {
24
24
  }
25
25
  };
26
26
  exports.baseParseKredit = baseParseKredit;
27
+ const MONTH_MAP = {
28
+ jan: '01',
29
+ feb: '02',
30
+ mar: '03',
31
+ apr: '04',
32
+ may: '05',
33
+ jun: '06',
34
+ jul: '07',
35
+ aug: '08',
36
+ sep: '09',
37
+ oct: '10',
38
+ nov: '11',
39
+ dec: '12',
40
+ january: '01',
41
+ february: '02',
42
+ march: '03',
43
+ april: '04',
44
+ june: '06',
45
+ july: '07',
46
+ august: '08',
47
+ september: '09',
48
+ october: '10',
49
+ november: '11',
50
+ december: '12',
51
+ };
52
+ const normalizeMetaDate = (raw) => {
53
+ const parts = raw.replace(',', '').trim().split(/\s+/);
54
+ let day, month, year;
55
+ if (/^\d+$/.test(parts[0])) {
56
+ // DD Month YYYY (Metrobank)
57
+ ;
58
+ [day, month, year] = parts;
59
+ }
60
+ else {
61
+ // MMM DD YYYY (RCBC / UnionBank)
62
+ ;
63
+ [month, day, year] = parts;
64
+ }
65
+ const mm = MONTH_MAP[month.toLowerCase()];
66
+ if (!mm)
67
+ throw new Error(`Unknown month in date: ${raw}`);
68
+ return `${mm}/${day.padStart(2, '0')}/${year}`;
69
+ };
70
+ const baseParseMeta = async (data, options) => {
71
+ const parser = new pdf_parse_1.PDFParse({
72
+ data: Buffer.from(data),
73
+ CanvasFactory: options.CanvasFactory,
74
+ });
75
+ const { text } = await parser.getText();
76
+ let raw;
77
+ switch (options.bank) {
78
+ case types_1.BankType.RCBC:
79
+ raw = (0, rcbc_1.parseRCBCMeta)(text);
80
+ break;
81
+ case types_1.BankType.METROBANK:
82
+ raw = (0, metrobank_1.parseMetrobankMeta)(text);
83
+ break;
84
+ case types_1.BankType.UNIONBANK:
85
+ raw = (0, unionbank_1.parseUnionBankMeta)(text);
86
+ break;
87
+ default:
88
+ throw new Error('Unsupported bank type');
89
+ }
90
+ return {
91
+ statementDate: normalizeMetaDate(raw.statementDate),
92
+ dueDate: normalizeMetaDate(raw.dueDate),
93
+ };
94
+ };
95
+ exports.baseParseMeta = baseParseMeta;
27
96
  //# sourceMappingURL=core.js.map
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AACpC,mCAAqD;AACrD,yCAA0C;AAC1C,mDAAoD;AACpD,mDAAoD;AAE7C,MAAM,eAAe,GAAG,KAAK,EAClC,IAAyB,EACzB,OAAgD,EAClB,EAAE;IAChC,MAAM,MAAM,GAAG,IAAI,oBAAQ,CAAC;QAC1B,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACvB,aAAa,EAAE,OAAO,CAAC,aAAa;KACrC,CAAC,CAAA;IAEF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAA;IAEvC,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,gBAAQ,CAAC,IAAI;YAChB,OAAO,IAAA,gBAAS,EAAC,IAAI,CAAC,CAAA;QACxB,KAAK,gBAAQ,CAAC,SAAS;YACrB,OAAO,IAAA,0BAAc,EAAC,IAAI,CAAC,CAAA;QAC7B,KAAK,gBAAQ,CAAC,SAAS;YACrB,OAAO,IAAA,0BAAc,EAAC,IAAI,CAAC,CAAA;QAC7B;YACE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC,CAAA;AArBY,QAAA,eAAe,mBAqB3B"}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
package/dist/node.d.ts CHANGED
@@ -4,3 +4,6 @@ type NodeInput = string | Buffer | Uint8Array;
4
4
  export declare const parseKredit: (input: NodeInput, options: {
5
5
  bank: BankType;
6
6
  }) => Promise<import("./types").KreditTransaction[]>;
7
+ export declare const parseKreditMeta: (input: NodeInput, options: {
8
+ bank: BankType;
9
+ }) => Promise<import("./types").KreditMeta>;
package/dist/node.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.parseKredit = void 0;
17
+ exports.parseKreditMeta = exports.parseKredit = void 0;
18
18
  const node_fs_1 = require("node:fs");
19
19
  const worker_1 = require("pdf-parse/worker");
20
20
  const core_1 = require("./core");
@@ -24,4 +24,9 @@ const parseKredit = async (input, options) => {
24
24
  return (0, core_1.baseParseKredit)(buffer, { ...options, CanvasFactory: worker_1.CanvasFactory });
25
25
  };
26
26
  exports.parseKredit = parseKredit;
27
+ const parseKreditMeta = async (input, options) => {
28
+ const buffer = typeof input === 'string' ? (0, node_fs_1.readFileSync)(input) : input;
29
+ return (0, core_1.baseParseMeta)(buffer, { ...options, CanvasFactory: worker_1.CanvasFactory });
30
+ };
31
+ exports.parseKreditMeta = parseKreditMeta;
27
32
  //# sourceMappingURL=node.js.map
package/dist/node.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,qCAAsC;AACtC,6CAAgD;AAChD,iCAAwC;AAGxC,0CAAuB;AAIhB,MAAM,WAAW,GAAG,KAAK,EAAE,KAAgB,EAAE,OAA2B,EAAE,EAAE;IACjF,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,sBAAY,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAEtE,OAAO,IAAA,sBAAe,EAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,aAAa,EAAb,sBAAa,EAAE,CAAC,CAAA;AAC/D,CAAC,CAAA;AAJY,QAAA,WAAW,eAIvB"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,qCAAsC;AACtC,6CAAgD;AAChD,iCAAuD;AAGvD,0CAAuB;AAIhB,MAAM,WAAW,GAAG,KAAK,EAAE,KAAgB,EAAE,OAA2B,EAAE,EAAE;IACjF,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,sBAAY,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAEtE,OAAO,IAAA,sBAAe,EAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,aAAa,EAAb,sBAAa,EAAE,CAAC,CAAA;AAC/D,CAAC,CAAA;AAJY,QAAA,WAAW,eAIvB;AAEM,MAAM,eAAe,GAAG,KAAK,EAAE,KAAgB,EAAE,OAA2B,EAAE,EAAE;IACrF,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,sBAAY,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAEtE,OAAO,IAAA,oBAAa,EAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,aAAa,EAAb,sBAAa,EAAE,CAAC,CAAA;AAC7D,CAAC,CAAA;AAJY,QAAA,eAAe,mBAI3B"}
@@ -1,2 +1,6 @@
1
1
  import { KreditTransaction } from '../types';
2
2
  export declare const parseMetrobank: (text: string) => KreditTransaction[];
3
+ export declare const parseMetrobankMeta: (text: string) => {
4
+ statementDate: string;
5
+ dueDate: string;
6
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseMetrobank = void 0;
3
+ exports.parseMetrobankMeta = exports.parseMetrobank = void 0;
4
4
  const regex = /^"?(\d{2}\/\d{2})\s+(\d{2}\/\d{2})\s+(.+?)\s+([\d,]+\.\d{2}C?)"?$/;
5
5
  const parseMetrobank = (text) => text
6
6
  .split('\n')
@@ -17,4 +17,12 @@ const parseMetrobank = (text) => text
17
17
  };
18
18
  });
19
19
  exports.parseMetrobank = parseMetrobank;
20
+ const metaRegex = /Statement Date Payment Due Date\n(\d{1,2} \w+ \d{4}) (\d{1,2} \w+ \d{4})/;
21
+ const parseMetrobankMeta = (text) => {
22
+ const m = metaRegex.exec(text);
23
+ if (!m)
24
+ throw new Error('Metrobank: could not extract statement/due dates');
25
+ return { statementDate: m[1], dueDate: m[2] };
26
+ };
27
+ exports.parseMetrobankMeta = parseMetrobankMeta;
20
28
  //# sourceMappingURL=metrobank.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"metrobank.js","sourceRoot":"","sources":["../../src/parsers/metrobank.ts"],"names":[],"mappings":";;;AAEA,MAAM,KAAK,GAAG,mEAAmE,CAAA;AAC1E,MAAM,cAAc,GAAG,CAAC,IAAY,EAAuB,EAAE,CAClE,IAAI;KACD,KAAK,CAAC,IAAI,CAAC;KACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC/B,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;KAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE;IACtD,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IAExC,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAEtE,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE;QAC/B,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;KAClC,CAAA;AACH,CAAC,CAAC,CAAA;AAhBO,QAAA,cAAc,kBAgBrB"}
1
+ {"version":3,"file":"metrobank.js","sourceRoot":"","sources":["../../src/parsers/metrobank.ts"],"names":[],"mappings":";;;AAEA,MAAM,KAAK,GAAG,mEAAmE,CAAA;AAC1E,MAAM,cAAc,GAAG,CAAC,IAAY,EAAuB,EAAE,CAClE,IAAI;KACD,KAAK,CAAC,IAAI,CAAC;KACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC/B,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;KAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE;IACtD,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IAExC,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAEtE,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE;QAC/B,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;KAClC,CAAA;AACH,CAAC,CAAC,CAAA;AAhBO,QAAA,cAAc,kBAgBrB;AAEN,MAAM,SAAS,GAAG,0EAA0E,CAAA;AAErF,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAA8C,EAAE;IAC7F,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IAC3E,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAC/C,CAAC,CAAA;AAJY,QAAA,kBAAkB,sBAI9B"}
@@ -1,2 +1,6 @@
1
1
  import { KreditTransaction } from '../types';
2
2
  export declare const parseRCBC: (text: string) => KreditTransaction[];
3
+ export declare const parseRCBCMeta: (text: string) => {
4
+ statementDate: string;
5
+ dueDate: string;
6
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseRCBC = void 0;
3
+ exports.parseRCBCMeta = exports.parseRCBC = void 0;
4
4
  const regex = /^([\d,]+\.\d{2}-?)\t(\d{2}\/\d{2}\/\d{2}) (\d{2}\/\d{2}\/\d{2}) (.+)$/;
5
5
  const parseRCBC = (text) => text
6
6
  .split('\n')
@@ -17,4 +17,12 @@ const parseRCBC = (text) => text
17
17
  };
18
18
  });
19
19
  exports.parseRCBC = parseRCBC;
20
+ const metaRegex = /([A-Z]{3} \d{2} \d{4})\t([A-Z]{3} \d{2} \d{4})\nPAYMENT DUE DATE\tSTATEMENT DATE/;
21
+ const parseRCBCMeta = (text) => {
22
+ const m = metaRegex.exec(text);
23
+ if (!m)
24
+ throw new Error('RCBC: could not extract statement/due dates');
25
+ return { dueDate: m[1], statementDate: m[2] };
26
+ };
27
+ exports.parseRCBCMeta = parseRCBCMeta;
20
28
  //# sourceMappingURL=rcbc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rcbc.js","sourceRoot":"","sources":["../../src/parsers/rcbc.ts"],"names":[],"mappings":";;;AAEA,MAAM,KAAK,GAAG,uEAAuE,CAAA;AAC9E,MAAM,SAAS,GAAG,CAAC,IAAY,EAAuB,EAAE,CAC7D,IAAI;KACD,KAAK,CAAC,IAAI,CAAC;KACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC/B,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;KAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE;IACtD,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAE5E,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAA;IAEnE,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE;QAC/B,MAAM;KACP,CAAA;AACH,CAAC,CAAC,CAAA;AAhBO,QAAA,SAAS,aAgBhB"}
1
+ {"version":3,"file":"rcbc.js","sourceRoot":"","sources":["../../src/parsers/rcbc.ts"],"names":[],"mappings":";;;AAEA,MAAM,KAAK,GAAG,uEAAuE,CAAA;AAC9E,MAAM,SAAS,GAAG,CAAC,IAAY,EAAuB,EAAE,CAC7D,IAAI;KACD,KAAK,CAAC,IAAI,CAAC;KACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC/B,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;KAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE;IACtD,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAE5E,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAA;IAEnE,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE;QAC/B,MAAM;KACP,CAAA;AACH,CAAC,CAAC,CAAA;AAhBO,QAAA,SAAS,aAgBhB;AAEN,MAAM,SAAS,GAAG,kFAAkF,CAAA;AAE7F,MAAM,aAAa,GAAG,CAAC,IAAY,EAA8C,EAAE;IACxF,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;IACtE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAC/C,CAAC,CAAA;AAJY,QAAA,aAAa,iBAIzB"}
@@ -1,2 +1,6 @@
1
1
  import { KreditTransaction } from '../types';
2
2
  export declare const parseUnionBank: (text: string) => KreditTransaction[];
3
+ export declare const parseUnionBankMeta: (text: string) => {
4
+ statementDate: string;
5
+ dueDate: string;
6
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseUnionBank = void 0;
3
+ exports.parseUnionBankMeta = exports.parseUnionBank = void 0;
4
4
  const regex = /^"?(\d{2}\/\d{2}\/\d{2})\s+(\d{2}\/\d{2}\/\d{2})\s+(.+?)\s+PHP\s+(-?[\d,]+\.\d{2})"?$/;
5
5
  const parseUnionBank = (text) => text
6
6
  .split('\n')
@@ -13,4 +13,14 @@ const parseUnionBank = (text) => text
13
13
  amount: parseFloat(amountStr.replace(/,/g, '')),
14
14
  }));
15
15
  exports.parseUnionBank = parseUnionBank;
16
+ const stmtRegex = /Statement Date\s*:\s*(\w{3} \d{2}, \d{4})/;
17
+ const dueRegex = /Payment Due Date\s*:\s*(\w{3} \d{2}, \d{4})/;
18
+ const parseUnionBankMeta = (text) => {
19
+ const sm = stmtRegex.exec(text);
20
+ const dm = dueRegex.exec(text);
21
+ if (!sm || !dm)
22
+ throw new Error('UnionBank: could not extract statement/due dates');
23
+ return { statementDate: sm[1], dueDate: dm[1] };
24
+ };
25
+ exports.parseUnionBankMeta = parseUnionBankMeta;
16
26
  //# sourceMappingURL=unionbank.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"unionbank.js","sourceRoot":"","sources":["../../src/parsers/unionbank.ts"],"names":[],"mappings":";;;AAEA,MAAM,KAAK,GACT,uFAAuF,CAAA;AAClF,MAAM,cAAc,GAAG,CAAC,IAAY,EAAuB,EAAE,CAClE,IAAI;KACD,KAAK,CAAC,IAAI,CAAC;KACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC/B,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;KAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;IACxD,QAAQ;IACR,QAAQ;IACR,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE;IAC/B,MAAM,EAAE,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;CAChD,CAAC,CAAC,CAAA;AAVM,QAAA,cAAc,kBAUpB"}
1
+ {"version":3,"file":"unionbank.js","sourceRoot":"","sources":["../../src/parsers/unionbank.ts"],"names":[],"mappings":";;;AAEA,MAAM,KAAK,GACT,uFAAuF,CAAA;AAClF,MAAM,cAAc,GAAG,CAAC,IAAY,EAAuB,EAAE,CAClE,IAAI;KACD,KAAK,CAAC,IAAI,CAAC;KACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC/B,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;KAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;IACxD,QAAQ;IACR,QAAQ;IACR,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE;IAC/B,MAAM,EAAE,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;CAChD,CAAC,CAAC,CAAA;AAVM,QAAA,cAAc,kBAUpB;AAEP,MAAM,SAAS,GAAG,2CAA2C,CAAA;AAC7D,MAAM,QAAQ,GAAG,6CAA6C,CAAA;AAEvD,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAA8C,EAAE;IAC7F,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC/B,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IACnF,OAAO,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;AACjD,CAAC,CAAA;AALY,QAAA,kBAAkB,sBAK9B"}
package/dist/types.d.ts CHANGED
@@ -4,6 +4,10 @@ export type KreditTransaction = {
4
4
  description: string;
5
5
  amount: number;
6
6
  };
7
+ export type KreditMeta = {
8
+ statementDate: string;
9
+ dueDate: string;
10
+ };
7
11
  export declare enum BankType {
8
12
  RCBC = "rcbc",
9
13
  METROBANK = "metrobank",
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAOA,IAAY,QAIX;AAJD,WAAY,QAAQ;IAClB,yBAAa,CAAA;IACb,mCAAuB,CAAA;IACvB,mCAAuB,CAAA;AACzB,CAAC,EAJW,QAAQ,wBAAR,QAAQ,QAInB"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAYA,IAAY,QAIX;AAJD,WAAY,QAAQ;IAClB,yBAAa,CAAA;IACb,mCAAuB,CAAA;IACvB,mCAAuB,CAAA;AACzB,CAAC,EAJW,QAAQ,wBAAR,QAAQ,QAInB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinoy-kredit-parser",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "Philippine credit card statement parser",
5
5
  "main": "./dist/node.js",
6
6
  "browser": "./dist/browser.js",
@@ -34,6 +34,8 @@
34
34
  "build": "rm -rf dist && tsc",
35
35
  "format": "prettier --write 'src/**/*.ts'",
36
36
  "format:check": "prettier --check 'src/**/*.ts'",
37
+ "test": "vitest run",
38
+ "test:watch": "vitest",
37
39
  "prepublishOnly": "npm run build"
38
40
  },
39
41
  "keywords": [
@@ -55,6 +57,7 @@
55
57
  "eslint-config-prettier": "^10.1.8",
56
58
  "prettier": "^3.8.1",
57
59
  "ts-node": "^10.9.2",
58
- "typescript": "^5.9.3"
60
+ "typescript": "^5.9.3",
61
+ "vitest": "^4.1.9"
59
62
  }
60
63
  }