🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

mt940js

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mt940js - npm Package Compare versions

Comparing version
1.3.0
to
1.3.1
cli

Sorry, the diff of this file is not supported yet

+45
class Field86StructureParser {
static buildTagRe(details) {
const prefix = details.charAt();
// check first symbol is known separator
let tagRe;
if (!prefix) {
return;
} else if (prefix === '/') { // assume /XXX/ fields
tagRe = '\\/[0-9A-Z]{2,4}\\/';
} else if ('>?'.includes(prefix)) { // assume >DD fields
tagRe = `\\${prefix}\\d{2}`;
} else return; // known separator not found
return {
detect: new RegExp(`^${tagRe}`), // line must begin with a tag
match: new RegExp(`(${tagRe})(.*?)(?=(${tagRe})|$)`, 'g'), // matcher
// item: new RegExp(`^(${tagRe})(.*)`),
strip: new RegExp(`\\${prefix}`, 'g'),
};
}
/**
* Detects if field 86 is structured and attempts to parse it
*/
static parse(details) {
details = details.replace(/\n/g, '').trim();
const rule = Field86StructureParser.buildTagRe(details);
if (!rule) return;
if (!rule.detect.test(details)) return; // string must start with tag
const parsedStruc = {};
let match = rule.match.exec(details);
while (match) {
const subTag = match[1].replace(rule.strip, '');
parsedStruc[subTag] = match[2];
match = rule.match.exec(details);
}
return parsedStruc;
}
}
module.exports = Field86StructureParser;

Sorry, the diff of this file is not supported yet

+2
-1

@@ -19,4 +19,5 @@ {

"no-console": "off",
"no-trailing-spaces": ["error"]
"no-trailing-spaces": ["error"],
"indent": ["error", 2]
}
}

@@ -11,4 +11,9 @@ mt940-js changelog

2019-01-29 v1.2.2
2019-01-31 v1.3.1
------------------
+ no86structure param to skip 86 tag structure detection
* minor fixes and refactorings
2019-01-29 v1.3.0
------------------
+ experimental messageBlocks detection and partial parsing '{1:...}'

@@ -15,0 +20,0 @@

+12
-12

@@ -20,15 +20,15 @@ const fs = require('fs');

switch (arg) {
case '--help':
case '-h':
banner();
case '--help':
case '-h':
banner();
process.exit(1);
break;
default:
try {
fs.accessSync(arg);
files.push(arg);
} catch (e) {
console.error(`Cannot access file: ${arg}`);
process.exit(1);
break;
default:
try {
fs.accessSync(arg);
files.push(arg);
} catch (e) {
console.error(`Cannot access file: ${arg}`);
process.exit(1);
}
}
}

@@ -35,0 +35,0 @@ });

@@ -8,2 +8,3 @@ /**

const helperModels = require('./helperModels');
const Field86Structure = require('./field86structure');

@@ -60,3 +61,11 @@ /**

class Parser {
constructor () {
/**
* Constructor, params are given as object fields { no86Structure: true }
* @constructor
* @param {boolean} no86Structure - don't parse 86 field structure
*/
constructor ({ no86Structure } = {}) {
this.params = {
no86Structure,
};
this.postParseMiddlewareStack = [];

@@ -171,3 +180,3 @@ }

!hasMessageBlocks && i instanceof Tags.TagTransactionReferenceNumber) {
groups.push(curGroup = []); // Statement starting tag -> start new group
groups.push(curGroup = []); // Statement starting tag -> start new group
}

@@ -317,5 +326,7 @@ curGroup.push(i);

}
for (let t of statement.transactions) {
let structuredDetails = this._detectDetailStructure(t);
if (structuredDetails) t.structuredDetails = structuredDetails;
if (!this.params.no86Structure) {
for (let t of statement.transactions) {
let structuredDetails = Field86Structure.parse(t.details);
if (structuredDetails) t.structuredDetails = structuredDetails;
}
}

@@ -336,44 +347,6 @@ if (withTags) { statement.tags = group } // preserve tags

/**
* Detects if field 86 is structured and attempts to parse it
* @private
*/
_detectDetailStructure(transaction) {
const details = transaction.details.replace(/\n/g, '').trim();
const prefix = details.charAt();
// check first symbol is known separator
let tagRe;
if (!prefix) return;
else if (prefix === '/') { // assume /XXX/ fields
tagRe = '\\/[0-9A-Z]{2,4}\\/';
} else if ('>?'.includes(prefix)) { // assume >DD fields
tagRe = `\\${prefix}\\d{2}`;
} else return; // known separator not found
const rule = {
detect: new RegExp(`^${tagRe}`),
split: new RegExp(`(?=${tagRe})`),
item: new RegExp(`^(${tagRe})(.*)`),
};
const stripPrefixRe = new RegExp(`\\${prefix}`, 'g');
if (!rule.detect.test(details)) return; // string must start with tag
const matches = details.split(rule.split);
if (matches.length > 0 && matches[0].length === 0) matches.shift(); // remove empty match at start
if (matches.length === 0) return; // no matches found
const parsedStruc = matches
.map(m => m.match(rule.item)) // supposed to match groups 1 and 2
.map(m => [ m[1].replace(stripPrefixRe, ''), m[2] ]) // remove prefix symbols from tag
.reduce((struc, m) => Object.assign(struc, { [m[0]]: m[1] }), {});
return parsedStruc;
}
/**
* parses message blocks
* @private
*/
_parseMessageBlockFields(messageId, value) {
_parseMessageBlockFields(messageId, value) { //eslint-disable-line no-unused-vars
// TODO somethings like:

@@ -380,0 +353,0 @@ // messageBlockFactory.createTag(messageId, value)

{
"name": "mt940js",
"version": "1.3.0",
"version": "1.3.1",
"description": "javascript mt940 bank statement parser",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -100,3 +100,3 @@ # SWIFT MT940 bank statement format JS parser

The parser attempts to detect if field 86 contains tags like these and, if yes, adds `structuredDetails` attribute to a statement line. Tag digits are not interpreted as they are not standardized among different banks.
The parser attempts to detect if field 86 contains tags like these and, if yes, adds `structuredDetails` attribute to a statement line. Tag digits are not interpreted as they are not standardized among different banks. Parsing 86 structure can be force disabled by passing `{ no86Structure: true }` to the constructor.

@@ -137,2 +137,3 @@ ```javascript

- pre parsing middlewares
- parsing structure of block messages

@@ -139,0 +140,0 @@ ## Author

@@ -18,2 +18,13 @@ const assert = require('chai').assert;

const DUMMY_STATEMENT_LINES_WITH_STRUCTURE = [
':20:B4E08MS9D00A0009',
':21:X',
':25:123456789',
':28C:123/1',
':60F:C140507EUR0,00',
':61:1405070507C500,00NTRFNONREF//AUXREF',
':86:?20some?21data',
':62F:C140508EUR500,00',
];
const DUMMY_STATEMENT_LINES_61_64_65 = [

@@ -264,2 +275,21 @@ ':20:B4E08MS9D00A0009',

it('statement with structured 86', () => {
let parser = new Parser();
let result = parser.parse(DUMMY_STATEMENT_LINES_WITH_STRUCTURE.join('\n'));
assert.equal(result.length, 1);
const exp = expectedStatement();
exp.transactions[0].details = '?20some?21data';
exp.transactions[0].structuredDetails = {
'20': 'some',
'21': 'data',
};
assert.deepEqual(result[0], exp);
parser = new Parser({ no86Structure: true });
result = parser.parse(DUMMY_STATEMENT_LINES_WITH_STRUCTURE.join('\n'));
delete exp.transactions[0].structuredDetails;
assert.deepEqual(result[0], exp);
});
it('statement with fields 64, 65, long 61 and statement comment', () => {

@@ -266,0 +296,0 @@ const parser = new Parser();

@@ -1,15 +0,9 @@

const assert = require('chai').assert;
const Parser = require('../lib/parser');
const parser = new Parser();
const assert = require('chai').assert;
const Field86Parser = require('../lib/field86structure');
function run(details) {
const transaction = {
details: details
};
const structure = parser._detectDetailStructure(transaction);
// console.log(structure);
return structure;
return Field86Parser.parse(details);
}
describe('Parser::_detectDetailStructure', () => {
describe('Field86Structure', () => {
it('Detects no structure', () => {

@@ -68,2 +62,22 @@ assert.isUndefined(run('some arbitrary text'));

it('complex detect', () => {
const tag = [
' /XXXX//100924006010 XXXXXXXXXXXXX XXXXXXXX XXXXXX AB (PUBL)',
' /ORDP/XX XXXXXX XXXXX XXXX N.A.25 XXXX XXXXX, CANARY WHARF',
' /REMI/UBERWEISUNG OUR REF: 03MT181024144353',
'YOUR REF: P6363103 240 1 M CA O/XXXXGB2L',
'/ACC/INST/XXXXGB2L /6231400604',
'BIC:XXXXGB2L',
].join('');
const parsed = run(tag);
console.log(parsed);
assert.deepEqual(parsed, {
'XXXX': '/100924006010 XXXXXXXXXXXXX XXXXXXXX XXXXXX AB (PUBL) ',
'ORDP': 'XX XXXXXX XXXXX XXXX N.A.25 XXXX XXXXX, CANARY WHARF ',
'REMI': 'UBERWEISUNG OUR REF: 03MT181024144353YOUR REF: P6363103 240 1 M CA O/XXXXGB2L',
'ACC': 'INST/XXXXGB2L /6231400604BIC:XXXXGB2L'
});
});
});