From 9921a8f70b07e9df3f0573c6256e534311509804 Mon Sep 17 00:00:00 2001 From: Braden MacDonald <mail@bradenm.com> Date: Sat, 30 Dec 2023 18:52:46 -0800 Subject: [PATCH 1/4] fix parsing bug where SGML has _some_ closing tags present --- ofx.js | 3 +- test/data/example2.ofx | 310 +++++++++++++++++++++++++++++++++++++++++ test/parse.js | 19 +++ 3 files changed, 331 insertions(+), 1 deletion(-) create mode 100644 test/data/example2.ofx diff --git a/ofx.js b/ofx.js index 705baf5..dfc2870 100644 --- a/ofx.js +++ b/ofx.js @@ -5,8 +5,9 @@ function sgml2Xml(sgml) { .replace(/>\s+</g, '><') // remove whitespace inbetween tag close/open .replace(/\s+</g, '<') // remove whitespace before a close tag .replace(/>\s+/g, '>') // remove whitespace after a close tag + .replace(/<([A-Za-z0-9_]+)>([^<]+)<\/\1>/g, '<\$1>\$2') // remove closing tags if present. Example: <FOO>bar</FOO> becomes <FOO>bar for consistency, fixed in last step below. .replace(/<([A-Z0-9_]*)+\.+([A-Z0-9_]*)>([^<]+)/g, '<\$1\$2>\$3' ) - .replace(/<(\w+?)>([^<]+)/g, '<\$1>\$2</\$1>'); + .replace(/<(\w+?)>([^<]+)/g, '<\$1>\$2</\$1>'); // Add closing tag wherever they seem to be missing: <FOO>bar becomes <FOO>bar</FOO> } /** diff --git a/test/data/example2.ofx b/test/data/example2.ofx new file mode 100644 index 0000000..1fac492 --- /dev/null +++ b/test/data/example2.ofx @@ -0,0 +1,310 @@ +OFXHEADER:100 +DATA:OFXSGML +VERSION:102 +SECURITY:NONE +ENCODING:USASCII +CHARSET:1252 +COMPRESSION:NONE +OLDFILEUID:NONE +NEWFILEUID:NONE +<OFX> +<SIGNONMSGSRSV1> +<SONRS> +<STATUS> +<CODE>0 +<SEVERITY>INFO +</STATUS> +<DTSERVER>******* +<LANGUAGE>FRA +<DTPROFUP>****** +<DTACCTUP>****** +</SONRS> +</SIGNONMSGSRSV1> +<BANKMSGSRSV1> +<STMTTRNRS> +<TRNUID>****** +<STATUS> +<CODE>0 +<SEVERITY>INFO +</STATUS> +<STMTRS> +<CURDEF>EUR +<BANKACCTFROM> +<BANKID>*****</BANKID> +<BRANCHID>*****</BRANCHID> +<ACCTID>*****</ACCTID> +<ACCTTYPE>CHECKING</ACCTTYPE> +</BANKACCTFROM> +<BANKTRANLIST> +<DTSTART>**** +<DTEND>**** +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>**** +<TRNAMT>-45.54 +<FITID>****** +<CHECKNUM>***** +<NAME>FRAIS DE TUTELLE +<MEMO>******* +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>****** +<TRNAMT>-90.00 +<FITID>***** +<CHECKNUM>**** +<NAME>ACHAT PRODUITS HYGIENE +<MEMO>****** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>**** +<TRNAMT>-78.73 +<FITID>***** +<CHECKNUM>***** +<NAME>APIVIA COURTAGE +<MEMO>******** +</STMTTRN> +<STMTTRN> +<TRNTYPE>CREDIT +<DTPOSTED>***** +<TRNAMT>+721.01 +<FITID>***** +<CHECKNUM>***** +<NAME>EURO VIR CARSAT LANGUEDOC ROUSSI +<MEMO>****** +</STMTTRN> +<STMTTRN> +<TRNTYPE>CREDIT +<DTPOSTED>**** +<TRNAMT>+130.83 +<FITID>****** +<CHECKNUM>***** +<NAME>EURO VIR CARSAT TI LR PREST +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>CREDIT +<DTPOSTED>***** +<TRNAMT>+247.28 +<FITID>**** +<CHECKNUM>****** +<NAME>EURO VIR CAF GARD +<MEMO>****** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>**** +<TRNAMT>-37.00 +<FITID>***** +<CHECKNUM>***** +<NAME>DIRECTION GENERALE DES +<MEMO>****** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>**** +<TRNAMT>-122.00 +<FITID>**** +<CHECKNUM>***** +<NAME>CHEQUE +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>*** +<TRNAMT>-448.00 +<FITID>**** +<CHECKNUM>*** +<NAME>DIRECTION GENERALE DES +<MEMO>**** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>*** +<TRNAMT>-2199.50 +<FITID>**** +<CHECKNUM>***** +<NAME>EHPAD 092023 +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>**** +<TRNAMT>-3.00 +<FITID>**** +<CHECKNUM>**** +<NAME>COTISATIONS BANCAIRES +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>***** +<TRNAMT>-21.41 +<FITID>***** +<CHECKNUM>*** +<NAME>DDFIP GARD +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>*** +<TRNAMT>-44.50 +<FITID>**** +<CHECKNUM>**** +<NAME>COTISATIONS BANCAIRES +<MEMO>**** +</STMTTRN> +<STMTTRN> +<TRNTYPE>CREDIT +<DTPOSTED>**** +<TRNAMT>+23947.61 +<FITID>**** +<CHECKNUM>**** +<NAME>VIR +<MEMO>**** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>**** +<TRNAMT>-45.54 +<FITID>**** +<CHECKNUM>**** +<NAME>FRAIS DE TUTELLE +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>**** +<TRNAMT>-122.00 +<FITID>**** +<CHECKNUM>***** +<NAME>CHEQUE +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>***** +<TRNAMT>-78.73 +<FITID>***** +<CHECKNUM>**** +<NAME>APIVIA COURTAGE +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>CREDIT +<DTPOSTED>**** +<TRNAMT>+721.01 +<FITID>***** +<CHECKNUM>**** +<NAME>EURO VIR CARSAT LANGUEDOC ROUSSI +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>CREDIT +<DTPOSTED>***** +<TRNAMT>+130.83 +<FITID>**** +<CHECKNUM>***** +<NAME>EURO VIR CARSAT TI LR PREST +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>CREDIT +<DTPOSTED>***** +<TRNAMT>+242.28 +<FITID>***** +<CHECKNUM>***** +<NAME>EURO VIR CAF GARD +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>**** +<TRNAMT>-3.00 +<FITID>**** +<CHECKNUM>***** +<NAME>COTISATIONS BANCAIRES +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>**** +<TRNAMT>-2267.65 +<FITID>**** +<CHECKNUM>**** +<NAME>**** +<MEMO>**** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>***** +<TRNAMT>-78.73 +<FITID>**** +<CHECKNUM>**** +<NAME>**** +<MEMO>**** +</STMTTRN> +<STMTTRN> +<TRNTYPE>CREDIT +<DTPOSTED>*** +<TRNAMT>+637.88 +<FITID>**** +<CHECKNUM>**** +<NAME>EURO VIR CARSAT LANGUEDOC ROUSSI +<MEMO>EURO **** +</STMTTRN> +<STMTTRN> +<TRNTYPE>CREDIT +<DTPOSTED>**** +<TRNAMT>+130.83 +<FITID>**** +<CHECKNUM>**** +<NAME>EURO VIR CARSAT TI LR PREST +<MEMO>**** +</STMTTRN> +<STMTTRN> +<TRNTYPE>CREDIT +<DTPOSTED>*** +<TRNAMT>+242.28 +<FITID>**** +<CHECKNUM>***** +<NAME>EURO VIR CAF GARD +<MEMO>***** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>*** +<TRNAMT>-45.54 +<FITID>**** +<CHECKNUM>**** +<NAME>FRAIS DE TUTELLE +<MEMO>**** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>**** +<TRNAMT>-3.00 +<FITID>*** +<CHECKNUM>**** +<NAME>COTISATIONS BANCAIRES +<MEMO>**** +</STMTTRN> +<STMTTRN> +<TRNTYPE>DEBIT +<DTPOSTED>*** +<TRNAMT>-122.00 +<FITID>*** +<CHECKNUM>**** +<NAME>SNC L ESCALE 30ST PRIVAT DES +<MEMO>***** +</STMTTRN> +</BANKTRANLIST> +<LEDGERBAL> +<BALAMT>+23757.44 +<DTASOF>**** +</LEDGERBAL> +</STMTRS> +</STMTTRNRS> +</BANKMSGSRSV1> +</OFX> \ No newline at end of file diff --git a/test/parse.js b/test/parse.js index 5750b51..f4e928f 100644 --- a/test/parse.js +++ b/test/parse.js @@ -23,6 +23,25 @@ test('parse', t => { }); }); +test('parse 2', t => { + const file = fs.readFileSync(__dirname + '/data/example2.ofx', 'utf8'); + ofx.parse(file).then(data => { + // headers + t.equal(data.header.OFXHEADER, '100'); + t.equal(data.header.ENCODING, 'USASCII'); + + var transactions = data.OFX.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKTRANLIST.STMTTRN; + t.equal(transactions.length, 29); + t.equal(transactions[0].TRNAMT, "-45.54"); + + var status = data.OFX.SIGNONMSGSRSV1.SONRS.STATUS; + t.equal(status.CODE, '0'); + t.equal(status.SEVERITY, 'INFO'); + + t.end(); + }); +}); + test('parse XML', t => { const file = fs.readFileSync(__dirname + '/data/example-xml.qfx', 'utf8'); ofx.parse(file).then(data => { From dbde009d6a1506b6c8b51726664c34d34e5b9523 Mon Sep 17 00:00:00 2001 From: Braden MacDonald <mail@bradenm.com> Date: Sat, 30 Dec 2023 18:52:56 -0800 Subject: [PATCH 2/4] Version bump: xml2js --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dd16e2b..6c9f2fc 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "tape": "^4.6.3" }, "dependencies": { - "xml2js": "^0.4.19" + "xml2js": "^0.6.2" }, "main": "./ofx.js", "directories": {}, From 17d53428dd01bbb0fd35f0d7f8f4a422fcb2de59 Mon Sep 17 00:00:00 2001 From: Braden MacDonald <mail@bradenm.com> Date: Sat, 30 Dec 2023 18:59:55 -0800 Subject: [PATCH 3/4] Run tests using GitHub Actions, not CircleCI --- .circleci/config.yml | 14 -------------- .github/workflows/ci-test.yml | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 14 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/workflows/ci-test.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index c2dd773..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2 -jobs: - build: - docker: - - image: node:7.4.0 - working_directory: ~/ofx-js - steps: - - checkout - - run: - name: Install Dependencies - command: npm install - - run: - name: NPM Test - command: npm test diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml new file mode 100644 index 0000000..06c952c --- /dev/null +++ b/.github/workflows/ci-test.yml @@ -0,0 +1,20 @@ +name: Run tests (Node.js) + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: ['14.x', '16.x', '18.x'] + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test From 868468e64023141e141a45ada69e9aba0d953468 Mon Sep 17 00:00:00 2001 From: Braden MacDonald <mail@bradenm.com> Date: Sat, 30 Dec 2023 19:05:29 -0800 Subject: [PATCH 4/4] Version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6c9f2fc..e5ecf91 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ofx-js", "description": "Parse OFX files using pure JavaScript.", - "version": "0.1.1", + "version": "0.2.0", "homepage": "https://github.com/bradenmacdonald/ofx-js", "contributors": [ {