ofx-data-extractor 1.3.5 → 1.4.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
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/ofx-data-extractor.svg)](https://badge.fury.io/js/ofx-data-extractor) [![MIT License][license-image]][license-url]
4
4
  [![codecov](https://codecov.io/gh/Fabiopf02/ofx-data-extractor/branch/main/graph/badge.svg?token=L4A7E4H8IN)](https://codecov.io/gh/Fabiopf02/ofx-data-extractor)
5
+ [![Release Package](https://github.com/Fabiopf02/ofx-data-extractor/actions/workflows/release.yml/badge.svg)](https://github.com/Fabiopf02/ofx-data-extractor/actions/workflows/release.yml)
5
6
 
6
7
  ## Ofx Data Extractor and Formatter
7
8
  This is a `Node.js` and `Browser` module written in `TypeScript` that provides a utility for extracting data from an `OFX` file. The module can also format some of the data and retrieve specific parts of the file if requested.
@@ -26,6 +27,7 @@ The `Ofx` class provides the following methods:
26
27
  - `config(options: OfxConfig)`: Used for formatting the generated json.`
27
28
  - `getHeaders(): OFXMetaData`: Returns the metadata section of the OFX file as an object.
28
29
  - `getBankTransferList(): Pick<BankTransferList, 'STRTTRN'>`: Returns a list of bank transfer transactions as an object.
30
+ - `getCreditCardTransferList(): Pick<BankTransferList, 'STRTTRN'>`: Returns a list of credit card transactions as an object.
29
31
  - `getTransactionsSummary()`: Object: Returns a summary of transactions for a bank statement as an object.
30
32
  - `getContent(): OfxStructure`: Returns the OFX file content as an object.
31
33
  - `toJson(): OfxResponse`: Returns the entire OFX file content as a JSON object.
@@ -6,5 +6,7 @@ export declare const CREDIT_CARD_SERVICE_START = "<CREDITCARDMSGSRSV1>";
6
6
  export declare const CREDIT_CARD_SERVICE_END = "</CREDITCARDMSGSRSV1>";
7
7
  export declare const START_STATEMENT_TRANSACION = "<STMTTRN>";
8
8
  export declare const FINISH_STATEMENT_TRANSACTION = "</STMTTRN>";
9
+ export declare const QUOTE_PATTERN = "_#_";
10
+ export declare const QUOTE_PATTERN_REGEX: RegExp;
9
11
  export declare const OPENING_TAGS_INITIALLY_IGNORED: string[];
10
12
  export declare const CLOSING_TAGS_INITIALLY_IGNORED: string[];
@@ -1,9 +1,9 @@
1
1
  import type { STRTTRN as STRTTRNType } from '../@types/ofx';
2
2
  import { ExtractorConfig } from '../@types/common';
3
3
  export declare function fixJsonProblems(content: string): string;
4
- export declare function extractFinancialInstitutionTransactionId(fitid: string): string;
5
- export declare function isDateField(field: string): boolean;
6
- export declare function trim(str: string): string;
4
+ export declare const extractFinancialInstitutionTransactionId: (fitid: string) => string;
5
+ export declare const isDateField: (field: string) => boolean;
6
+ export declare const trim: (str: string) => string;
7
7
  export declare function objectStartReplacer(param: string, force?: boolean): string;
8
8
  export declare function objectEndReplacer(param: string, force?: boolean): string;
9
9
  export declare function configFinancialInstitutionTransactionId({ fitId, fitValue, }: Pick<ExtractorConfig, 'fitId'> & {
@@ -21,6 +21,9 @@ export declare function parseTransactions(content: string): {
21
21
  newListText: string;
22
22
  };
23
23
  export declare function getBankStatementTransactionsText(ofxContent: string): {
24
+ newBankStatementTransactions: null;
25
+ oldBankStatementTransactions: null;
26
+ } | {
24
27
  newBankStatementTransactions: string;
25
28
  oldBankStatementTransactions: string;
26
29
  };
@@ -31,6 +34,7 @@ export declare function getCreditCardStatementTransactionsText(ofxContent: strin
31
34
  newCreditCardStatementTransactions: string;
32
35
  oldCreditCardStatementTransactions: string;
33
36
  };
37
+ export declare function extractMetaDataFromXml(data: string[]): string[];
34
38
  export declare function convertMetaDataToObject(stringList: string[], nativeTypes: boolean): {
35
39
  [key: string]: any;
36
40
  };
@@ -1,11 +1,11 @@
1
- // Ofx-data-extractor v1.3.5 Copyright (c) 2024 Fábio Pereira França
2
- const N=/<\/\w+>/g,x=/<\w+>/g,E="<BANKMSGSRSV1>",f="</BANKMSGSRSV1>",d="<CREDITCARDMSGSRSV1>",l="</CREDITCARDMSGSRSV1>",g="<STMTTRN>",c="</STMTTRN>",O=[E,g,d],b=[f,l,c];function M(e){const t=e.slice(0,4),n=e.slice(4,6),r=e.slice(6,8),a=e.slice(8,10),s=e.slice(10,12),i=e.slice(12,14);return{yyyy:t,yy:t.slice(2),y:t,MM:n,M:n,dd:r,d:r,hh:a,h:a,mm:s,m:s,ss:i,s:i}}function R(e,t){const n=M(e);let r=t;for(const[a,s]of Object.entries(n))r=r.replace(a,s);return r}function T(e){return e.replace(/(\\)/g,"\\\\").replace(N,t=>w(t,!0)).replace(x,t=>D(t,!0)).replace(/(},})/g,"}}").replace(/(}")/g,'},"').replace(/(},])/g,"}]").replace(/(,})/g,"}").replace(/({")/g,`{
1
+ // Ofx-data-extractor v1.4.1 Copyright (c) 2024 Fábio Pereira França
2
+ const E=/<\/\w+>/g,x=/<\w+>/g,l="<BANKMSGSRSV1>",f="</BANKMSGSRSV1>",d="<CREDITCARDMSGSRSV1>",g="</CREDITCARDMSGSRSV1>",S="<STMTTRN>",T="</STMTTRN>",N="_#_",M=new RegExp(N,"g"),y=[l,S,d],L=[f,g,T];function b(e){const t=e.slice(0,4),n=e.slice(4,6),r=e.slice(6,8),s=e.slice(8,10),a=e.slice(10,12),i=e.slice(12,14);return{yyyy:t,yy:t.slice(2),y:t,MM:n,M:n,dd:r,d:r,hh:s,h:s,mm:a,m:a,ss:i,s:i}}function _(e,t){const n=b(e);let r=t;for(const[s,a]of Object.entries(n))r=r.replace(s,a);return r}function u(e){return e.replace(/(\\)/g,"\\\\").replace(E,t=>D(t,!0)).replace(x,t=>w(t,!0)).replace(/(},})/g,"}}").replace(/(}")/g,'},"').replace(/(]")/g,'],"').replace(/(},])/g,"}]").replace(/(,})/g,"}").replace(/({")/g,`{
3
3
  "`).replace(/(})/g,`
4
4
  }`).replace(/(",")/g,`",
5
5
  "`).replace(/,\s*}/g,`
6
- }`).replace(/(,",)/,",").slice(0,-1)}function y(e){const t=e.slice(0,12),n=e.slice(12,19),r=e.slice(19),a={date:t,transactionCode:n,protocol:r};return JSON.stringify(a)}function B(e){return e.startsWith("DT")}function _(e){return e.trim()}function D(e,t=!1){return O.includes(e)&&!t?e:e.replace(/[<]/g,`
7
- "`).replace(/[>]/g,'":{')}function w(e,t=!1){return b.includes(e)&&!t?`
8
- ${e}`:"},"}function G({fitId:e,fitValue:t}){return e==="separated"?y(t):`"${t}",`}function k(e){const t=e.search(","),n=e.search(".");return t>n?e.replace(/[.]/g,"").replace(/[,]/g,"."):e.replace(/[,]/g,"")}function F({dateString:e,formatDate:t}){return t?R(e,t):R(e,"y-M-d")}function J(e){let t=e.value.replace(/[{]/g,"").replace(/(},)/g,"");const n=e.field.replace(/['"]/g,"");return n.endsWith("AMT")&&(t=k(t)),B(n)&&(t=F({dateString:t,formatDate:e.formatDate})),n==="FITID"?G({fitId:e.fitId,fitValue:t}):e.nativeTypes&&p(n,t)?`${Number(t)},`:`"${t}",`}function K(e,t){let n=e;const r=n.slice(0,n.indexOf(":")),a=s=>J({field:r,value:s,...t});return e.match(/{(\w|\W)+/)&&(n=n.replace(/({(\w|\W)+)$/,a)),n}function p(e,t){return e.endsWith("ID")||e.endsWith("NUM")?!1:!isNaN(Number(t))}function A(e){const t=e.indexOf(g),n=e.lastIndexOf(c)+c.length,r=e.substring(t,n),a=new RegExp(g,"g"),s=new RegExp(c,"g"),i=`"STRTTRN":[${r.replace(a,"{").replace(s,"},")}]`;return{oldListText:e,newListText:e.replace(r,i)}}function m(e){const t=e.substring(e.indexOf(E),e.indexOf(f)+f.length),n=A(t);return{newBankStatementTransactions:n.newListText,oldBankStatementTransactions:n.oldListText}}function C(e){if(!(e.indexOf(d)>0))return{newCreditCardStatementTransactions:null,oldCreditCardStatementTransactions:null};const n=e.substring(e.indexOf(d),e.indexOf(l)+l.length),r=A(n);return{newCreditCardStatementTransactions:r.newListText,oldCreditCardStatementTransactions:r.oldListText}}function P(e,t){const n={};for(const r of e){const[a,s]=r.split(":"),i=a.replace(`
9
- `,"");n[i]=t&&p(a,s)?Number(s):s}return n}function $(e){return e.reduce((t,n)=>n.TRNTYPE.toLocaleLowerCase().startsWith("deb")?(t.amountOfDebits++,t.debit+=Number(n.TRNAMT.replace("-","")),t):(t.amountOfCredits++,t.credit+=Number(n.TRNAMT),t),{credit:0,debit:0,amountOfCredits:0,amountOfDebits:0})}class z{config;internConfig={};constructor(t){this.config=t,this.internConfig=t}getConfig(){return this.internConfig}sanitizeRow(t){return K(t,this.internConfig)}getPartialJsonData(t){const[n,r]=t.split("<OFX>"),a="<OFX>"+r,{sanitizeRow:s}=this;return a.replace(N,i=>w(i)).replace(x,i=>D(i)).split(`
10
- `).map(_).filter(Boolean).map(s,this).join("")}}function h(e){return e.toString()}async function I(e){return await new Promise((n,r)=>{if(typeof window<"u"&&window.FileReader){const a=new window.FileReader;a.onload=s=>n(s.target.result),a.onerror=s=>r(s.target.error),a.readAsText(e)}else r(new Error("FileReader is not available in this environment."))})}class o{data;dataRead="";constructor(t){this.data=t,t&&(this.dataRead=t)}getData(){return this.dataRead}fromString(t){return new o(t)}fromBuffer(t){return new o(h(t))}async fromBlob(t){return new o(await I(t))}static fromString(t){return new o(t)}static fromBuffer(t){return new o(h(t))}static async fromBlob(t){return new o(await I(t))}}class V{configInstance={}}class L extends V{setConfig(t){this.configInstance=t}getBankTransferList(t){const{newBankStatementTransactions:n}=m(this.configInstance.getPartialJsonData(t));return JSON.parse(`{${T(n)}}`)?.BANKMSGSRSV1?.STMTTRNRS?.STMTRS?.BANKTRANLIST?.STRTTRN}getCreditCardTransferList(t){const{newCreditCardStatementTransactions:n}=C(this.configInstance.getPartialJsonData(t));return n?JSON.parse(`{${T(n)}}`)?.CREDITCARDMSGSRSV1?.CCSTMTTRNRS?.CCSTMTRS?.BANKTRANLIST?.STRTTRN:[]}getTransactionsSummary(t){const n=this.getContent(t),{DTEND:r,DTSTART:a,STRTTRN:s}=n.OFX.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKTRANLIST,i=$(s);return{dateStart:a,dateEnd:r,...i}}getContent(t){const n=this.configInstance.getPartialJsonData(t),{newBankStatementTransactions:r,oldBankStatementTransactions:a}=m(n),{newCreditCardStatementTransactions:s,oldCreditCardStatementTransactions:i}=C(n);let u=n.replace(a,r);return s&&(u=u.replace(i,s)),JSON.parse(`{${T(u)}}`)}}class W{customExtractor;customExtractorInstance;dataReaderInstance=new o("");constructor(t){this.customExtractor=t,this.customExtractorInstance=t||new L,this.config({})}data(t){return this.dataReaderInstance=t,this}config(t){return this.customExtractorInstance.setConfig(new z(t)),this}getHeaders(){const[t]=this.dataReaderInstance.getData().split("<OFX>"),n=t.split(`
11
- `),r=s=>!!s.trim().length,a=n.filter(r);return P(a,!!this.customExtractorInstance.configInstance.getConfig().nativeTypes)}getBankTransferList(){return this.customExtractorInstance.getBankTransferList(this.dataReaderInstance.getData())}getCreditCardTransferList(){return this.customExtractorInstance.getCreditCardTransferList(this.dataReaderInstance.getData())}getTransactionsSummary(){return this.customExtractorInstance.getTransactionsSummary(this.dataReaderInstance.getData())}getContent(){return this.customExtractorInstance.getContent(this.dataReaderInstance.getData())}toJson(){const t=this.getHeaders(),n=this.customExtractorInstance.getContent(this.dataReaderInstance.getData());return{...t,...n}}}class S{extractor;constructor(t,n){this.extractor=new W(new L),this.extractor.data(new o(t)),this.extractor.config(n||{})}static fromBuffer(t){return new S(o.fromBuffer(t).getData())}static async fromBlob(t){const n=await o.fromBlob(t);return new S(n.getData())}config(t){return this.extractor.config(t),this}getHeaders(){return this.extractor.getHeaders()}getBankTransferList(){return this.extractor.getBankTransferList()}getTransactionsSummary(){return this.extractor.getTransactionsSummary()}getContent(){return this.extractor.getContent()}toJson(){return this.extractor.toJson()}}export{W as Extractor,S as Ofx,L as OfxExtractor,o as Reader,I as blobToString,h as bufferToString,T as fixJsonProblems,R as formatDate};
6
+ }`).replace(/(,",)/,",").replace(M,'\\"').slice(0,-1)}const k=e=>JSON.stringify({date:e.slice(0,12),transactionCode:e.slice(12,19),protocol:e.slice(19)}),G=e=>e.startsWith("DT"),p=e=>e.trim();function w(e,t=!1){return y.includes(e)&&!t?e:e.replace(/[<]/g,`
7
+ "`).replace(/[>]/g,'":{')}function D(e,t=!1){return L.includes(e)&&!t?`
8
+ ${e}`:"},"}function F({fitId:e,fitValue:t}){return e==="separated"?k(t):`"${t}",`}function J(e){return e.search(",")>e.search(".")?e.replace(/[.]/g,"").replace(/[,]/g,"."):e.replace(/[,]/g,"")}function P({dateString:e,formatDate:t="y-M-d"}){return _(e,t)}function K(e){let t=e.value.replace(/[{]/g,"").replace(/(},)/g,"").replace(/["]/g,N);const n=e.field.replace(/['"]/g,"");return n.endsWith("AMT")&&(t=J(t)),G(n)&&(t=P({dateString:t,formatDate:e.formatDate})),n==="FITID"?F({fitId:e.fitId,fitValue:t}):e.nativeTypes&&A(n,t)?`${Number(t)},`:`"${t}",`}function X(e,t){let n=e;return e.match(/{(\w|\W)+/)&&(n=n.replace(/({(\w|\W)+)$/,r=>K({field:n.slice(0,n.indexOf(":")),value:r,...t}))),n}function A(e,t){return e.endsWith("ID")||e.endsWith("NUM")?!1:!isNaN(Number(t))}function O(e){const t=e.indexOf(S),n=e.lastIndexOf(T)+T.length,r=e.substring(t,n),s=new RegExp(S,"g"),a=new RegExp(T,"g"),i=`"STRTTRN":[${r.replace(s,"{").replace(a,"},")}]`;return{oldListText:e,newListText:e.replace(r,i)}}function m(e){if(!(e.indexOf(l)>0))return{newBankStatementTransactions:null,oldBankStatementTransactions:null};const n=O(e.substring(e.indexOf(l),e.indexOf(f)+f.length));return{newBankStatementTransactions:n.newListText,oldBankStatementTransactions:n.oldListText}}function C(e){if(!(e.indexOf(d)>0))return{newCreditCardStatementTransactions:null,oldCreditCardStatementTransactions:null};const n=e.substring(e.indexOf(d),e.indexOf(g)+g.length),r=O(n);return{newCreditCardStatementTransactions:r.newListText,oldCreditCardStatementTransactions:r.oldListText}}function $(e){const t=[];for(const n of e)t.push(...n.replace("<?xml"," ").replace("<?OFX"," ").replace("?>"," ").split(" ").filter(Boolean).map(p).map(r=>r.replace("=",":").replace(/["]/g,"")));return t}function V(e,t){const n={};e.join("").search("<?")>-1&&(e=$(e));for(const r of e){const[s,a]=r.split(":"),i=s.replace(`
9
+ `,"").toUpperCase();n[i]=t&&A(s,a)?Number(a):a}return n}function z(e){return e.reduce((t,n)=>{const r=Math.abs(+n.TRNAMT);return n.TRNTYPE.toLocaleLowerCase().startsWith("deb")?(t.amountOfDebits++,t.debit+=r,t):(t.amountOfCredits++,t.credit+=r,t)},{credit:0,debit:0,amountOfCredits:0,amountOfDebits:0})}class W{config;internConfig={};constructor(t){this.config=t,this.internConfig=t}getConfig(){return this.internConfig}sanitizeRow(t){return X(t,this.internConfig)}getPartialJsonData(t){const[n,r]=t.split("<OFX>"),s="<OFX>"+r,{sanitizeRow:a}=this;return s.replace(E,i=>D(i)).replace(x,i=>w(i)).split(`
10
+ `).map(p).filter(Boolean).map(a,this).join("")}}function h(e){return e.toString()}async function I(e){return await new Promise((n,r)=>{if(typeof window<"u"&&window.FileReader){const s=new window.FileReader;s.onload=a=>n(a.target.result),s.onerror=a=>r(a.target.error),s.readAsText(e)}else r(new Error("FileReader is not available in this environment."))})}class o{data;dataRead="";constructor(t){this.data=t,t&&(this.dataRead=t)}getData(){return this.dataRead}fromString(t){return new o(t)}fromBuffer(t){return new o(h(t))}async fromBlob(t){return new o(await I(t))}static fromString(t){return new o(t)}static fromBuffer(t){return new o(h(t))}static async fromBlob(t){return new o(await I(t))}}class j{configInstance={}}class B extends j{setConfig(t){this.configInstance=t}getBankTransferList(t){const{newBankStatementTransactions:n}=m(this.configInstance.getPartialJsonData(t));return n?JSON.parse(`{${u(n)}}`)?.BANKMSGSRSV1?.STMTTRNRS?.STMTRS?.BANKTRANLIST?.STRTTRN:[]}getCreditCardTransferList(t){const{newCreditCardStatementTransactions:n}=C(this.configInstance.getPartialJsonData(t));return n?JSON.parse(`{${u(n)}}`)?.CREDITCARDMSGSRSV1?.CCSTMTTRNRS?.CCSTMTRS?.BANKTRANLIST?.STRTTRN:[]}getTransactionsSummary(t){const n=this.getContent(t),{DTEND:r,DTSTART:s,STRTTRN:a}=n.OFX.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKTRANLIST,i=z(a);return{dateStart:s,dateEnd:r,...i}}getContent(t){const n=this.configInstance.getPartialJsonData(t),{newBankStatementTransactions:r,oldBankStatementTransactions:s}=m(n),{newCreditCardStatementTransactions:a,oldCreditCardStatementTransactions:i}=C(n);let c=n;return r&&(c=c.replace(s,r)),a&&(c=c.replace(i,a)),JSON.parse(`{${u(c)}}`)}}class H{customExtractor;customExtractorInstance;dataReaderInstance=new o("");constructor(t){this.customExtractor=t,this.customExtractorInstance=t||new B,this.config({})}data(t){return this.dataReaderInstance=t,this}config(t){return this.customExtractorInstance.setConfig(new W(t)),this}getHeaders(){const[t]=this.dataReaderInstance.getData().split("<OFX>");return V(t.split(`
11
+ `).filter(n=>!!n.trim().length),!!this.customExtractorInstance.configInstance.getConfig().nativeTypes)}getBankTransferList(){return this.customExtractorInstance.getBankTransferList(this.dataReaderInstance.getData())}getCreditCardTransferList(){return this.customExtractorInstance.getCreditCardTransferList(this.dataReaderInstance.getData())}getTransactionsSummary(){return this.customExtractorInstance.getTransactionsSummary(this.dataReaderInstance.getData())}getContent(){return this.customExtractorInstance.getContent(this.dataReaderInstance.getData())}toJson(){const t=this.getHeaders(),n=this.customExtractorInstance.getContent(this.dataReaderInstance.getData());return{...t,...n}}}class R{extractor;constructor(t,n){this.extractor=new H(new B),this.extractor.data(new o(t)),this.extractor.config(n||{})}static fromBuffer(t){return new R(o.fromBuffer(t).getData())}static async fromBlob(t){const n=await o.fromBlob(t);return new R(n.getData())}config(t){return this.extractor.config(t),this}getHeaders(){return this.extractor.getHeaders()}getBankTransferList(){return this.extractor.getBankTransferList()}getCreditCardTransferList(){return this.extractor.getCreditCardTransferList()}getTransactionsSummary(){return this.extractor.getTransactionsSummary()}getContent(){return this.extractor.getContent()}toJson(){return this.extractor.toJson()}}export{H as Extractor,R as Ofx,B as OfxExtractor,o as Reader,I as blobToString,h as bufferToString,u as fixJsonProblems,_ as formatDate};
@@ -9,6 +9,7 @@ export declare class Ofx {
9
9
  config(config: OfxConfig): this;
10
10
  getHeaders(): MetaData;
11
11
  getBankTransferList(): STRTTRN[];
12
+ getCreditCardTransferList(): STRTTRN[];
12
13
  getTransactionsSummary(): import("../@types/common").TransactionsSummary;
13
14
  getContent(): OfxStructure;
14
15
  toJson(): OfxResponse;
@@ -1,11 +1,11 @@
1
- // Ofx-data-extractor v1.3.5 Copyright (c) 2024 Fábio Pereira França
2
- (function(o,u){typeof exports=="object"&&typeof module<"u"?u(exports):typeof define=="function"&&define.amd?define(["exports"],u):(o=typeof globalThis<"u"?globalThis:o||self,u(o.ofx={}))})(this,function(o){"use strict";const u=/<\/\w+>/g,x=/<\w+>/g,E="<BANKMSGSRSV1>",l="</BANKMSGSRSV1>",g="<CREDITCARDMSGSRSV1>",S="</CREDITCARDMSGSRSV1>",m="<STMTTRN>",f="</STMTTRN>",y=[E,m,g],M=[l,S,f];function B(e){const t=e.slice(0,4),n=e.slice(4,6),r=e.slice(6,8),a=e.slice(8,10),s=e.slice(10,12),i=e.slice(12,14);return{yyyy:t,yy:t.slice(2),y:t,MM:n,M:n,dd:r,d:r,hh:a,h:a,mm:s,m:s,ss:i,s:i}}function R(e,t){const n=B(e);let r=t;for(const[a,s]of Object.entries(n))r=r.replace(a,s);return r}function T(e){return e.replace(/(\\)/g,"\\\\").replace(u,t=>w(t,!0)).replace(x,t=>D(t,!0)).replace(/(},})/g,"}}").replace(/(}")/g,'},"').replace(/(},])/g,"}]").replace(/(,})/g,"}").replace(/({")/g,`{
1
+ // Ofx-data-extractor v1.4.1 Copyright (c) 2024 Fábio Pereira França
2
+ (function(o,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(o=typeof globalThis<"u"?globalThis:o||self,f(o.ofx={}))})(this,function(o){"use strict";const f=/<\/\w+>/g,x=/<\w+>/g,g="<BANKMSGSRSV1>",S="</BANKMSGSRSV1>",m="<CREDITCARDMSGSRSV1>",R="</CREDITCARDMSGSRSV1>",C="<STMTTRN>",T="</STMTTRN>",N="_#_",L=new RegExp(N,"g"),_=[g,C,m],k=[S,R,T];function G(e){const t=e.slice(0,4),n=e.slice(4,6),r=e.slice(6,8),s=e.slice(8,10),a=e.slice(10,12),i=e.slice(12,14);return{yyyy:t,yy:t.slice(2),y:t,MM:n,M:n,dd:r,d:r,hh:s,h:s,mm:a,m:a,ss:i,s:i}}function p(e,t){const n=G(e);let r=t;for(const[s,a]of Object.entries(n))r=r.replace(s,a);return r}function l(e){return e.replace(/(\\)/g,"\\\\").replace(f,t=>O(t,!0)).replace(x,t=>D(t,!0)).replace(/(},})/g,"}}").replace(/(}")/g,'},"').replace(/(]")/g,'],"').replace(/(},])/g,"}]").replace(/(,})/g,"}").replace(/({")/g,`{
3
3
  "`).replace(/(})/g,`
4
4
  }`).replace(/(",")/g,`",
5
5
  "`).replace(/,\s*}/g,`
6
- }`).replace(/(,",)/,",").slice(0,-1)}function _(e){const t=e.slice(0,12),n=e.slice(12,19),r=e.slice(19),a={date:t,transactionCode:n,protocol:r};return JSON.stringify(a)}function G(e){return e.startsWith("DT")}function k(e){return e.trim()}function D(e,t=!1){return y.includes(e)&&!t?e:e.replace(/[<]/g,`
7
- "`).replace(/[>]/g,'":{')}function w(e,t=!1){return M.includes(e)&&!t?`
8
- ${e}`:"},"}function J({fitId:e,fitValue:t}){return e==="separated"?_(t):`"${t}",`}function F(e){const t=e.search(","),n=e.search(".");return t>n?e.replace(/[.]/g,"").replace(/[,]/g,"."):e.replace(/[,]/g,"")}function P({dateString:e,formatDate:t}){return t?R(e,t):R(e,"y-M-d")}function K(e){let t=e.value.replace(/[{]/g,"").replace(/(},)/g,"");const n=e.field.replace(/['"]/g,"");return n.endsWith("AMT")&&(t=F(t)),G(n)&&(t=P({dateString:t,formatDate:e.formatDate})),n==="FITID"?J({fitId:e.fitId,fitValue:t}):e.nativeTypes&&p(n,t)?`${Number(t)},`:`"${t}",`}function $(e,t){let n=e;const r=n.slice(0,n.indexOf(":")),a=s=>K({field:r,value:s,...t});return e.match(/{(\w|\W)+/)&&(n=n.replace(/({(\w|\W)+)$/,a)),n}function p(e,t){return e.endsWith("ID")||e.endsWith("NUM")?!1:!isNaN(Number(t))}function b(e){const t=e.indexOf(m),n=e.lastIndexOf(f)+f.length,r=e.substring(t,n),a=new RegExp(m,"g"),s=new RegExp(f,"g"),i=`"STRTTRN":[${r.replace(a,"{").replace(s,"},")}]`;return{oldListText:e,newListText:e.replace(r,i)}}function A(e){const t=e.substring(e.indexOf(E),e.indexOf(l)+l.length),n=b(t);return{newBankStatementTransactions:n.newListText,oldBankStatementTransactions:n.oldListText}}function O(e){if(!(e.indexOf(g)>0))return{newCreditCardStatementTransactions:null,oldCreditCardStatementTransactions:null};const n=e.substring(e.indexOf(g),e.indexOf(S)+S.length),r=b(n);return{newCreditCardStatementTransactions:r.newListText,oldCreditCardStatementTransactions:r.oldListText}}function j(e,t){const n={};for(const r of e){const[a,s]=r.split(":"),i=a.replace(`
9
- `,"");n[i]=t&&p(a,s)?Number(s):s}return n}function z(e){return e.reduce((t,n)=>n.TRNTYPE.toLocaleLowerCase().startsWith("deb")?(t.amountOfDebits++,t.debit+=Number(n.TRNAMT.replace("-","")),t):(t.amountOfCredits++,t.credit+=Number(n.TRNAMT),t),{credit:0,debit:0,amountOfCredits:0,amountOfDebits:0})}class V{config;internConfig={};constructor(t){this.config=t,this.internConfig=t}getConfig(){return this.internConfig}sanitizeRow(t){return $(t,this.internConfig)}getPartialJsonData(t){const[n,r]=t.split("<OFX>"),a="<OFX>"+r,{sanitizeRow:s}=this;return a.replace(u,i=>w(i)).replace(x,i=>D(i)).split(`
10
- `).map(k).filter(Boolean).map(s,this).join("")}}function C(e){return e.toString()}async function h(e){return await new Promise((n,r)=>{if(typeof window<"u"&&window.FileReader){const a=new window.FileReader;a.onload=s=>n(s.target.result),a.onerror=s=>r(s.target.error),a.readAsText(e)}else r(new Error("FileReader is not available in this environment."))})}class c{data;dataRead="";constructor(t){this.data=t,t&&(this.dataRead=t)}getData(){return this.dataRead}fromString(t){return new c(t)}fromBuffer(t){return new c(C(t))}async fromBlob(t){return new c(await h(t))}static fromString(t){return new c(t)}static fromBuffer(t){return new c(C(t))}static async fromBlob(t){return new c(await h(t))}}class W{configInstance={}}class I extends W{setConfig(t){this.configInstance=t}getBankTransferList(t){const{newBankStatementTransactions:n}=A(this.configInstance.getPartialJsonData(t));return JSON.parse(`{${T(n)}}`)?.BANKMSGSRSV1?.STMTTRNRS?.STMTRS?.BANKTRANLIST?.STRTTRN}getCreditCardTransferList(t){const{newCreditCardStatementTransactions:n}=O(this.configInstance.getPartialJsonData(t));return n?JSON.parse(`{${T(n)}}`)?.CREDITCARDMSGSRSV1?.CCSTMTTRNRS?.CCSTMTRS?.BANKTRANLIST?.STRTTRN:[]}getTransactionsSummary(t){const n=this.getContent(t),{DTEND:r,DTSTART:a,STRTTRN:s}=n.OFX.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKTRANLIST,i=z(s);return{dateStart:a,dateEnd:r,...i}}getContent(t){const n=this.configInstance.getPartialJsonData(t),{newBankStatementTransactions:r,oldBankStatementTransactions:a}=A(n),{newCreditCardStatementTransactions:s,oldCreditCardStatementTransactions:i}=O(n);let N=n.replace(a,r);return s&&(N=N.replace(i,s)),JSON.parse(`{${T(N)}}`)}}class L{customExtractor;customExtractorInstance;dataReaderInstance=new c("");constructor(t){this.customExtractor=t,this.customExtractorInstance=t||new I,this.config({})}data(t){return this.dataReaderInstance=t,this}config(t){return this.customExtractorInstance.setConfig(new V(t)),this}getHeaders(){const[t]=this.dataReaderInstance.getData().split("<OFX>"),n=t.split(`
11
- `),r=s=>!!s.trim().length,a=n.filter(r);return j(a,!!this.customExtractorInstance.configInstance.getConfig().nativeTypes)}getBankTransferList(){return this.customExtractorInstance.getBankTransferList(this.dataReaderInstance.getData())}getCreditCardTransferList(){return this.customExtractorInstance.getCreditCardTransferList(this.dataReaderInstance.getData())}getTransactionsSummary(){return this.customExtractorInstance.getTransactionsSummary(this.dataReaderInstance.getData())}getContent(){return this.customExtractorInstance.getContent(this.dataReaderInstance.getData())}toJson(){const t=this.getHeaders(),n=this.customExtractorInstance.getContent(this.dataReaderInstance.getData());return{...t,...n}}}class d{extractor;constructor(t,n){this.extractor=new L(new I),this.extractor.data(new c(t)),this.extractor.config(n||{})}static fromBuffer(t){return new d(c.fromBuffer(t).getData())}static async fromBlob(t){const n=await c.fromBlob(t);return new d(n.getData())}config(t){return this.extractor.config(t),this}getHeaders(){return this.extractor.getHeaders()}getBankTransferList(){return this.extractor.getBankTransferList()}getTransactionsSummary(){return this.extractor.getTransactionsSummary()}getContent(){return this.extractor.getContent()}toJson(){return this.extractor.toJson()}}o.Extractor=L,o.Ofx=d,o.OfxExtractor=I,o.Reader=c,o.blobToString=h,o.bufferToString=C,o.fixJsonProblems=T,o.formatDate=R});
6
+ }`).replace(/(,",)/,",").replace(L,'\\"').slice(0,-1)}const F=e=>JSON.stringify({date:e.slice(0,12),transactionCode:e.slice(12,19),protocol:e.slice(19)}),J=e=>e.startsWith("DT"),w=e=>e.trim();function D(e,t=!1){return _.includes(e)&&!t?e:e.replace(/[<]/g,`
7
+ "`).replace(/[>]/g,'":{')}function O(e,t=!1){return k.includes(e)&&!t?`
8
+ ${e}`:"},"}function P({fitId:e,fitValue:t}){return e==="separated"?F(t):`"${t}",`}function K(e){return e.search(",")>e.search(".")?e.replace(/[.]/g,"").replace(/[,]/g,"."):e.replace(/[,]/g,"")}function X({dateString:e,formatDate:t="y-M-d"}){return p(e,t)}function $(e){let t=e.value.replace(/[{]/g,"").replace(/(},)/g,"").replace(/["]/g,N);const n=e.field.replace(/['"]/g,"");return n.endsWith("AMT")&&(t=K(t)),J(n)&&(t=X({dateString:t,formatDate:e.formatDate})),n==="FITID"?P({fitId:e.fitId,fitValue:t}):e.nativeTypes&&A(n,t)?`${Number(t)},`:`"${t}",`}function V(e,t){let n=e;return e.match(/{(\w|\W)+/)&&(n=n.replace(/({(\w|\W)+)$/,r=>$({field:n.slice(0,n.indexOf(":")),value:r,...t}))),n}function A(e,t){return e.endsWith("ID")||e.endsWith("NUM")?!1:!isNaN(Number(t))}function B(e){const t=e.indexOf(C),n=e.lastIndexOf(T)+T.length,r=e.substring(t,n),s=new RegExp(C,"g"),a=new RegExp(T,"g"),i=`"STRTTRN":[${r.replace(s,"{").replace(a,"},")}]`;return{oldListText:e,newListText:e.replace(r,i)}}function b(e){if(!(e.indexOf(g)>0))return{newBankStatementTransactions:null,oldBankStatementTransactions:null};const n=B(e.substring(e.indexOf(g),e.indexOf(S)+S.length));return{newBankStatementTransactions:n.newListText,oldBankStatementTransactions:n.oldListText}}function y(e){if(!(e.indexOf(m)>0))return{newCreditCardStatementTransactions:null,oldCreditCardStatementTransactions:null};const n=e.substring(e.indexOf(m),e.indexOf(R)+R.length),r=B(n);return{newCreditCardStatementTransactions:r.newListText,oldCreditCardStatementTransactions:r.oldListText}}function j(e){const t=[];for(const n of e)t.push(...n.replace("<?xml"," ").replace("<?OFX"," ").replace("?>"," ").split(" ").filter(Boolean).map(w).map(r=>r.replace("=",":").replace(/["]/g,"")));return t}function z(e,t){const n={};e.join("").search("<?")>-1&&(e=j(e));for(const r of e){const[s,a]=r.split(":"),i=s.replace(`
9
+ `,"").toUpperCase();n[i]=t&&A(s,a)?Number(a):a}return n}function W(e){return e.reduce((t,n)=>{const r=Math.abs(+n.TRNAMT);return n.TRNTYPE.toLocaleLowerCase().startsWith("deb")?(t.amountOfDebits++,t.debit+=r,t):(t.amountOfCredits++,t.credit+=r,t)},{credit:0,debit:0,amountOfCredits:0,amountOfDebits:0})}class H{config;internConfig={};constructor(t){this.config=t,this.internConfig=t}getConfig(){return this.internConfig}sanitizeRow(t){return V(t,this.internConfig)}getPartialJsonData(t){const[n,r]=t.split("<OFX>"),s="<OFX>"+r,{sanitizeRow:a}=this;return s.replace(f,i=>O(i)).replace(x,i=>D(i)).split(`
10
+ `).map(w).filter(Boolean).map(a,this).join("")}}function h(e){return e.toString()}async function E(e){return await new Promise((n,r)=>{if(typeof window<"u"&&window.FileReader){const s=new window.FileReader;s.onload=a=>n(a.target.result),s.onerror=a=>r(a.target.error),s.readAsText(e)}else r(new Error("FileReader is not available in this environment."))})}class c{data;dataRead="";constructor(t){this.data=t,t&&(this.dataRead=t)}getData(){return this.dataRead}fromString(t){return new c(t)}fromBuffer(t){return new c(h(t))}async fromBlob(t){return new c(await E(t))}static fromString(t){return new c(t)}static fromBuffer(t){return new c(h(t))}static async fromBlob(t){return new c(await E(t))}}class U{configInstance={}}class I extends U{setConfig(t){this.configInstance=t}getBankTransferList(t){const{newBankStatementTransactions:n}=b(this.configInstance.getPartialJsonData(t));return n?JSON.parse(`{${l(n)}}`)?.BANKMSGSRSV1?.STMTTRNRS?.STMTRS?.BANKTRANLIST?.STRTTRN:[]}getCreditCardTransferList(t){const{newCreditCardStatementTransactions:n}=y(this.configInstance.getPartialJsonData(t));return n?JSON.parse(`{${l(n)}}`)?.CREDITCARDMSGSRSV1?.CCSTMTTRNRS?.CCSTMTRS?.BANKTRANLIST?.STRTTRN:[]}getTransactionsSummary(t){const n=this.getContent(t),{DTEND:r,DTSTART:s,STRTTRN:a}=n.OFX.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKTRANLIST,i=W(a);return{dateStart:s,dateEnd:r,...i}}getContent(t){const n=this.configInstance.getPartialJsonData(t),{newBankStatementTransactions:r,oldBankStatementTransactions:s}=b(n),{newCreditCardStatementTransactions:a,oldCreditCardStatementTransactions:i}=y(n);let u=n;return r&&(u=u.replace(s,r)),a&&(u=u.replace(i,a)),JSON.parse(`{${l(u)}}`)}}class M{customExtractor;customExtractorInstance;dataReaderInstance=new c("");constructor(t){this.customExtractor=t,this.customExtractorInstance=t||new I,this.config({})}data(t){return this.dataReaderInstance=t,this}config(t){return this.customExtractorInstance.setConfig(new H(t)),this}getHeaders(){const[t]=this.dataReaderInstance.getData().split("<OFX>");return z(t.split(`
11
+ `).filter(n=>!!n.trim().length),!!this.customExtractorInstance.configInstance.getConfig().nativeTypes)}getBankTransferList(){return this.customExtractorInstance.getBankTransferList(this.dataReaderInstance.getData())}getCreditCardTransferList(){return this.customExtractorInstance.getCreditCardTransferList(this.dataReaderInstance.getData())}getTransactionsSummary(){return this.customExtractorInstance.getTransactionsSummary(this.dataReaderInstance.getData())}getContent(){return this.customExtractorInstance.getContent(this.dataReaderInstance.getData())}toJson(){const t=this.getHeaders(),n=this.customExtractorInstance.getContent(this.dataReaderInstance.getData());return{...t,...n}}}class d{extractor;constructor(t,n){this.extractor=new M(new I),this.extractor.data(new c(t)),this.extractor.config(n||{})}static fromBuffer(t){return new d(c.fromBuffer(t).getData())}static async fromBlob(t){const n=await c.fromBlob(t);return new d(n.getData())}config(t){return this.extractor.config(t),this}getHeaders(){return this.extractor.getHeaders()}getBankTransferList(){return this.extractor.getBankTransferList()}getCreditCardTransferList(){return this.extractor.getCreditCardTransferList()}getTransactionsSummary(){return this.extractor.getTransactionsSummary()}getContent(){return this.extractor.getContent()}toJson(){return this.extractor.toJson()}}o.Extractor=M,o.Ofx=d,o.OfxExtractor=I,o.Reader=c,o.blobToString=E,o.bufferToString=h,o.fixJsonProblems=l,o.formatDate=p});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ofx-data-extractor",
3
- "version": "1.3.5",
3
+ "version": "1.4.1",
4
4
  "keywords": [
5
5
  "ofx",
6
6
  "financial",