@ekwo-ai/camt053 0.4.0
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/LICENSE +21 -0
- package/README.md +240 -0
- package/dist/decimal.d.ts +20 -0
- package/dist/decimal.d.ts.map +1 -0
- package/dist/decimal.js +46 -0
- package/dist/decimal.js.map +1 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +454 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +210 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/xml.d.ts +40 -0
- package/dist/xml.d.ts.map +1 -0
- package/dist/xml.js +274 -0
- package/dist/xml.js.map +1 -0
- package/package.json +56 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a statement is once it has been read: an account, two balances and
|
|
3
|
+
* lines. The shape is declared here and imported from nowhere — it names no
|
|
4
|
+
* table, no ledger and no country, so anything that keeps books can take it.
|
|
5
|
+
*
|
|
6
|
+
* Every amount is a **decimal string**, signed from the account holder's side:
|
|
7
|
+
* money in is positive, money out is negative, an overdrawn balance is
|
|
8
|
+
* negative. No figure of a statement passes through a `number`.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* How an account is identified. ISO 20022 gives a choice and so does this
|
|
12
|
+
* type: an IBAN (ISO 13616) **or** anything else — a domestic account number,
|
|
13
|
+
* a routing number and an account, whatever the bank's country uses. Half the
|
|
14
|
+
* world has no IBAN, and a reader that only returned one would read half the
|
|
15
|
+
* statements.
|
|
16
|
+
*/
|
|
17
|
+
export type AccountIdentifier = {
|
|
18
|
+
kind: 'iban';
|
|
19
|
+
/** As written, without spaces, upper case. */
|
|
20
|
+
value: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'other';
|
|
23
|
+
/** `Othr/Id`, as written. */
|
|
24
|
+
value: string;
|
|
25
|
+
/** `SchmeNm/Cd` (an ISO external code such as `BBAN`) or `SchmeNm/Prtry`. */
|
|
26
|
+
scheme: string | null;
|
|
27
|
+
/** `Othr/Issr`, who assigned it. */
|
|
28
|
+
issuer: string | null;
|
|
29
|
+
};
|
|
30
|
+
export interface StatementAccount {
|
|
31
|
+
identifier: AccountIdentifier;
|
|
32
|
+
/** `Acct/Ccy`. Null when the bank does not say; the balances still do. */
|
|
33
|
+
currency: string | null;
|
|
34
|
+
name: string | null;
|
|
35
|
+
ownerName: string | null;
|
|
36
|
+
/** BIC of the institution servicing the account, when given. */
|
|
37
|
+
servicerBic: string | null;
|
|
38
|
+
}
|
|
39
|
+
export interface StatementBalance {
|
|
40
|
+
/**
|
|
41
|
+
* `Tp/CdOrPrtry/Cd` — `OPBD` opening booked, `CLBD` closing booked, `PRCD`
|
|
42
|
+
* previous closing, `ITBD` interim, `CLAV` closing available… — or the
|
|
43
|
+
* proprietary label when the bank uses one.
|
|
44
|
+
*/
|
|
45
|
+
type: string;
|
|
46
|
+
/** Signed: a debit balance is negative. */
|
|
47
|
+
amount: string;
|
|
48
|
+
currency: string;
|
|
49
|
+
/** The day, `YYYY-MM-DD`, as the bank wrote it — no timezone is applied. */
|
|
50
|
+
date: string | null;
|
|
51
|
+
}
|
|
52
|
+
export interface StructuredReference {
|
|
53
|
+
/** `CdtrRefInf/Ref`: the creditor reference itself. */
|
|
54
|
+
reference: string;
|
|
55
|
+
/** `CdtrRefInf/Tp/CdOrPrtry/Cd`, usually `SCOR`; or the proprietary label. */
|
|
56
|
+
type: string | null;
|
|
57
|
+
/** `CdtrRefInf/Tp/Issr`: who defined the reference — `ISO` for an RF one. */
|
|
58
|
+
issuer: string | null;
|
|
59
|
+
}
|
|
60
|
+
export interface Remittance {
|
|
61
|
+
/** Every `RmtInf/Ustrd`, in order. Free text: what a person typed. */
|
|
62
|
+
unstructured: string[];
|
|
63
|
+
/** Every `RmtInf/Strd/CdtrRefInf` that carries a reference, in order. */
|
|
64
|
+
structured: StructuredReference[];
|
|
65
|
+
}
|
|
66
|
+
export interface Counterparty {
|
|
67
|
+
name: string | null;
|
|
68
|
+
account: AccountIdentifier | null;
|
|
69
|
+
/** BIC of the counterparty's bank, when given. */
|
|
70
|
+
agentBic: string | null;
|
|
71
|
+
/** The ultimate debtor or creditor behind the counterparty, when named. */
|
|
72
|
+
ultimateName: string | null;
|
|
73
|
+
}
|
|
74
|
+
export interface BankTransactionCode {
|
|
75
|
+
/** ISO 20022 external code set: domain, family, sub-family. */
|
|
76
|
+
domain: string | null;
|
|
77
|
+
family: string | null;
|
|
78
|
+
subFamily: string | null;
|
|
79
|
+
/** The bank's own code, and who issued the code list. */
|
|
80
|
+
proprietary: string | null;
|
|
81
|
+
proprietaryIssuer: string | null;
|
|
82
|
+
}
|
|
83
|
+
export interface StatementLine {
|
|
84
|
+
/** Position among the statement's lines, from 1. */
|
|
85
|
+
index: number;
|
|
86
|
+
/** Position of the `Ntry` this line comes from, from 1. */
|
|
87
|
+
entry: number;
|
|
88
|
+
/**
|
|
89
|
+
* When the entry was a batch split into its transactions: which one this is,
|
|
90
|
+
* from 1, and out of how many. Both null when the line is the whole entry.
|
|
91
|
+
*/
|
|
92
|
+
detail: number | null;
|
|
93
|
+
detailCount: number | null;
|
|
94
|
+
/**
|
|
95
|
+
* `BOOK`, `PDNG`, `INFO`, `FUTR`, or the proprietary label. Only booked
|
|
96
|
+
* entries move the balance, and only they are counted in the balance check.
|
|
97
|
+
*/
|
|
98
|
+
status: string;
|
|
99
|
+
booked: boolean;
|
|
100
|
+
/** `RvslInd`: this entry reverses an earlier one. */
|
|
101
|
+
reversal: boolean;
|
|
102
|
+
/** `BookgDt`, `YYYY-MM-DD`. Falls back to nothing: a missing date is reported. */
|
|
103
|
+
bookingDate: string | null;
|
|
104
|
+
/** `ValDt`, `YYYY-MM-DD`. */
|
|
105
|
+
valueDate: string | null;
|
|
106
|
+
/** Signed: positive is money in. Null when the file's figure is unreadable. */
|
|
107
|
+
amount: string | null;
|
|
108
|
+
currency: string | null;
|
|
109
|
+
/** Signed amount of the whole entry when this line is one part of it. */
|
|
110
|
+
entryAmount: string | null;
|
|
111
|
+
/**
|
|
112
|
+
* The bank's own reference for this movement: the transaction's
|
|
113
|
+
* `Refs/AcctSvcrRef`, else the entry's `AcctSvcrRef`. Unique per movement at
|
|
114
|
+
* a given bank when present — and optional in the schema, so it may be null.
|
|
115
|
+
*/
|
|
116
|
+
bankReference: string | null;
|
|
117
|
+
/** `NtryRef`: unique within the statement, by the message definition. */
|
|
118
|
+
entryReference: string | null;
|
|
119
|
+
/** As written — including the placeholder `NOTPROVIDED` when the bank writes it. */
|
|
120
|
+
endToEndId: string | null;
|
|
121
|
+
transactionId: string | null;
|
|
122
|
+
instructionId: string | null;
|
|
123
|
+
paymentInformationId: string | null;
|
|
124
|
+
mandateId: string | null;
|
|
125
|
+
counterparty: Counterparty | null;
|
|
126
|
+
remittance: Remittance;
|
|
127
|
+
bankTransactionCode: BankTransactionCode | null;
|
|
128
|
+
/** `RtrInf/Rsn`: why a payment came back — ISO code or proprietary label. */
|
|
129
|
+
returnReason: string | null;
|
|
130
|
+
/**
|
|
131
|
+
* `AmtDtls/InstdAmt`: what was ordered, in the currency it was ordered in,
|
|
132
|
+
* unsigned as the file writes it. The line's `amount` stays what moved on
|
|
133
|
+
* the account; nothing is converted here.
|
|
134
|
+
*/
|
|
135
|
+
instructedAmount: {
|
|
136
|
+
amount: string;
|
|
137
|
+
currency: string;
|
|
138
|
+
} | null;
|
|
139
|
+
/** `AmtDtls/…/CcyXchg/XchgRate`, as written. */
|
|
140
|
+
exchangeRate: string | null;
|
|
141
|
+
/** `AddtlTxInf`, else `AddtlNtryInf`. */
|
|
142
|
+
additionalInformation: string | null;
|
|
143
|
+
}
|
|
144
|
+
export interface Statement {
|
|
145
|
+
/** `Stmt/Id`. */
|
|
146
|
+
id: string;
|
|
147
|
+
electronicSequenceNumber: string | null;
|
|
148
|
+
legalSequenceNumber: string | null;
|
|
149
|
+
/** `CreDtTm`, as written. */
|
|
150
|
+
createdAt: string | null;
|
|
151
|
+
/** `FrToDt`, by day. */
|
|
152
|
+
period: {
|
|
153
|
+
from: string | null;
|
|
154
|
+
to: string | null;
|
|
155
|
+
} | null;
|
|
156
|
+
/** `StmtPgntn`, from version 03 on: a statement delivered in several files. */
|
|
157
|
+
page: {
|
|
158
|
+
number: string;
|
|
159
|
+
last: boolean;
|
|
160
|
+
} | null;
|
|
161
|
+
account: StatementAccount;
|
|
162
|
+
/** `OPBD`, else `PRCD`. */
|
|
163
|
+
openingBalance: StatementBalance | null;
|
|
164
|
+
/** `CLBD`. */
|
|
165
|
+
closingBalance: StatementBalance | null;
|
|
166
|
+
/** Every `Bal`, in file order, including the two above. */
|
|
167
|
+
balances: StatementBalance[];
|
|
168
|
+
lines: StatementLine[];
|
|
169
|
+
/**
|
|
170
|
+
* Opening balance plus booked entries equals closing balance: true, false,
|
|
171
|
+
* or null when it could not be checked (a balance missing, a figure
|
|
172
|
+
* unreadable, an entry in another currency). False is reported as
|
|
173
|
+
* `balance_mismatch` and **never corrected**.
|
|
174
|
+
*/
|
|
175
|
+
balanced: boolean | null;
|
|
176
|
+
}
|
|
177
|
+
export interface Violation {
|
|
178
|
+
/** A stable token, for a caller that branches on it. */
|
|
179
|
+
code: ViolationCode;
|
|
180
|
+
/** What is wrong, in a sentence. */
|
|
181
|
+
message: string;
|
|
182
|
+
/** Which statement of the file, from 1. */
|
|
183
|
+
statement: number;
|
|
184
|
+
/** Which line of that statement (`StatementLine.index`), where there is one. */
|
|
185
|
+
line?: number;
|
|
186
|
+
}
|
|
187
|
+
export type ViolationCode = 'version_not_verified' | 'balance_mismatch' | 'opening_balance_missing' | 'closing_balance_missing' | 'balance_currency_mismatch' | 'foreign_currency_entry' | 'invalid_amount' | 'invalid_direction' | 'invalid_date' | 'booking_date_missing' | 'invalid_iban' | 'duplicate_bank_reference' | 'duplicate_entry_reference' | 'batch_not_split' | 'batch_count_mismatch';
|
|
188
|
+
export interface StatementFile {
|
|
189
|
+
/** The namespace of the document element: the version that was read. */
|
|
190
|
+
namespace: string;
|
|
191
|
+
/** `02`, `08`… — the last part of the message identifier. */
|
|
192
|
+
version: string;
|
|
193
|
+
/** Whether this package's tests hold that version against its schema. */
|
|
194
|
+
versionVerified: boolean;
|
|
195
|
+
/** `GrpHdr/MsgId`. */
|
|
196
|
+
messageId: string | null;
|
|
197
|
+
/** `GrpHdr/CreDtTm`, as written. */
|
|
198
|
+
createdAt: string | null;
|
|
199
|
+
statements: Statement[];
|
|
200
|
+
violations: Violation[];
|
|
201
|
+
}
|
|
202
|
+
export interface ReadOptions {
|
|
203
|
+
/** Refuse a larger file unread. Default 32 MiB. */
|
|
204
|
+
maxBytes?: number;
|
|
205
|
+
/** Refuse deeper nesting. Default 64; the deepest path of the schema is under 20. */
|
|
206
|
+
maxDepth?: number;
|
|
207
|
+
/** Refuse more elements. Default 2,000,000. */
|
|
208
|
+
maxElements?: number;
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a statement is once it has been read: an account, two balances and
|
|
3
|
+
* lines. The shape is declared here and imported from nowhere — it names no
|
|
4
|
+
* table, no ledger and no country, so anything that keeps books can take it.
|
|
5
|
+
*
|
|
6
|
+
* Every amount is a **decimal string**, signed from the account holder's side:
|
|
7
|
+
* money in is positive, money out is negative, an overdrawn balance is
|
|
8
|
+
* negative. No figure of a statement passes through a `number`.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
package/dist/xml.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A strict, small XML reader, written here because a statement comes from
|
|
3
|
+
* outside and this package depends on nothing.
|
|
4
|
+
*
|
|
5
|
+
* It reads the XML a bank writes and refuses the XML an attacker writes:
|
|
6
|
+
*
|
|
7
|
+
* - **no DOCTYPE at all**, so no internal subset, no entity declaration, no
|
|
8
|
+
* external entity, no parameter entity — the billion-laughs family and the
|
|
9
|
+
* XXE family both start with `<!DOCTYPE` and both stop there;
|
|
10
|
+
* - the five predefined entities and numeric character references, and any
|
|
11
|
+
* other `&name;` is an error rather than an empty string;
|
|
12
|
+
* - a size limit applied before anything is read, a depth limit and an element
|
|
13
|
+
* limit applied while reading, and no recursion: nesting costs heap the
|
|
14
|
+
* limits bound, never stack;
|
|
15
|
+
* - UTF-8 only, decoded fatally: a byte that is not UTF-8 is an error and not a
|
|
16
|
+
* replacement character in somebody's name;
|
|
17
|
+
* - namespaces resolved, because a bank may write `<Document xmlns="…">` or
|
|
18
|
+
* `<ns2:Document xmlns:ns2="…">` and both are the same statement.
|
|
19
|
+
*
|
|
20
|
+
* It is not a general XML parser and says so: element and attribute names are
|
|
21
|
+
* ASCII (every ISO 20022 name is), and nothing is validated against a schema.
|
|
22
|
+
*/
|
|
23
|
+
export interface XmlElement {
|
|
24
|
+
/** Local name, without prefix. */
|
|
25
|
+
name: string;
|
|
26
|
+
/** Namespace URI, `''` when the element is in none. */
|
|
27
|
+
namespace: string;
|
|
28
|
+
/** Attributes by the name they were written under; `xmlns` ones left out. */
|
|
29
|
+
attributes: Record<string, string>;
|
|
30
|
+
children: XmlElement[];
|
|
31
|
+
/** The element's own character data, concatenated; children's is theirs. */
|
|
32
|
+
text: string;
|
|
33
|
+
}
|
|
34
|
+
export interface XmlLimits {
|
|
35
|
+
maxBytes: number;
|
|
36
|
+
maxDepth: number;
|
|
37
|
+
maxElements: number;
|
|
38
|
+
}
|
|
39
|
+
export declare function parseXml(input: string | Uint8Array, limits: XmlLimits): XmlElement;
|
|
40
|
+
//# sourceMappingURL=xml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../src/xml.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAwID,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,MAAM,EAAE,SAAS,GAAG,UAAU,CAsKlF"}
|
package/dist/xml.js
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { StatementFileError } from './errors.js';
|
|
2
|
+
const NAME = /[A-Za-z_][A-Za-z0-9_.-]*(?::[A-Za-z_][A-Za-z0-9_.-]*)?/y;
|
|
3
|
+
const ATTRIBUTE = /\s+([A-Za-z_][A-Za-z0-9_.-]*(?::[A-Za-z_][A-Za-z0-9_.-]*)?)\s*=\s*(?:"([^<"]*)"|'([^<']*)')/y;
|
|
4
|
+
const DECLARATION = /^<\?xml\s+version\s*=\s*(?:"1\.[0-9]+"|'1\.[0-9]+')(?:\s+encoding\s*=\s*(?:"([A-Za-z][A-Za-z0-9._-]*)"|'([A-Za-z][A-Za-z0-9._-]*)'))?(?:\s+standalone\s*=\s*(?:"(?:yes|no)"|'(?:yes|no)'))?\s*\?>/;
|
|
5
|
+
const REFERENCE = /&(?:#x([0-9a-fA-F]+)|#([0-9]+)|([A-Za-z_][A-Za-z0-9_.-]*));/g;
|
|
6
|
+
const PREDEFINED = {
|
|
7
|
+
lt: '<',
|
|
8
|
+
gt: '>',
|
|
9
|
+
amp: '&',
|
|
10
|
+
quot: '"',
|
|
11
|
+
apos: "'",
|
|
12
|
+
};
|
|
13
|
+
const XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
14
|
+
function malformed(what, at) {
|
|
15
|
+
return new StatementFileError('malformed_xml', `${what} (at character ${at})`);
|
|
16
|
+
}
|
|
17
|
+
/** XML 1.0 `Char`, by code point. */
|
|
18
|
+
function isXmlChar(code) {
|
|
19
|
+
return (code === 0x9 ||
|
|
20
|
+
code === 0xa ||
|
|
21
|
+
code === 0xd ||
|
|
22
|
+
(code >= 0x20 && code <= 0xd7ff) ||
|
|
23
|
+
(code >= 0xe000 && code <= 0xfffd) ||
|
|
24
|
+
(code >= 0x10000 && code <= 0x10ffff));
|
|
25
|
+
}
|
|
26
|
+
/** The first code unit XML does not allow in a document, or -1. */
|
|
27
|
+
function firstForbiddenCharacter(source) {
|
|
28
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
29
|
+
const code = source.charCodeAt(index);
|
|
30
|
+
if (code >= 0x20 && code < 0xfffe)
|
|
31
|
+
continue;
|
|
32
|
+
if (code === 0x9 || code === 0xa || code === 0xd)
|
|
33
|
+
continue;
|
|
34
|
+
return index;
|
|
35
|
+
}
|
|
36
|
+
return -1;
|
|
37
|
+
}
|
|
38
|
+
function decodeReferences(raw, at) {
|
|
39
|
+
if (!raw.includes('&'))
|
|
40
|
+
return raw;
|
|
41
|
+
let out = '';
|
|
42
|
+
let last = 0;
|
|
43
|
+
for (const match of raw.matchAll(REFERENCE)) {
|
|
44
|
+
const index = match.index;
|
|
45
|
+
const between = raw.slice(last, index);
|
|
46
|
+
if (between.includes('&'))
|
|
47
|
+
throw malformed('a bare "&"', at + last + between.indexOf('&'));
|
|
48
|
+
out += between;
|
|
49
|
+
if (match[3] !== undefined) {
|
|
50
|
+
const value = PREDEFINED[match[3]];
|
|
51
|
+
if (value === undefined) {
|
|
52
|
+
throw new StatementFileError('undefined_entity', `entity &${match[3]}; is not one of the five XML predefines, and this reader declares no other (at character ${at + index})`);
|
|
53
|
+
}
|
|
54
|
+
out += value;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const code = match[1] !== undefined ? parseInt(match[1], 16) : parseInt(match[2], 10);
|
|
58
|
+
if (!isXmlChar(code)) {
|
|
59
|
+
throw malformed(`character reference ${match[0]} is not an XML character`, at + index);
|
|
60
|
+
}
|
|
61
|
+
out += String.fromCodePoint(code);
|
|
62
|
+
}
|
|
63
|
+
last = index + match[0].length;
|
|
64
|
+
}
|
|
65
|
+
const rest = raw.slice(last);
|
|
66
|
+
if (rest.includes('&'))
|
|
67
|
+
throw malformed('a bare "&"', at + last + rest.indexOf('&'));
|
|
68
|
+
return out + rest;
|
|
69
|
+
}
|
|
70
|
+
function decode(input, limits) {
|
|
71
|
+
if (typeof input === 'string') {
|
|
72
|
+
// A string has no bytes to count; its length is the closest honest bound,
|
|
73
|
+
// and UTF-8 never encodes a code unit in less than one byte.
|
|
74
|
+
if (input.length > limits.maxBytes) {
|
|
75
|
+
throw new StatementFileError('too_large', `the file is ${input.length} characters, over the limit of ${limits.maxBytes}`);
|
|
76
|
+
}
|
|
77
|
+
return input.charCodeAt(0) === 0xfeff ? input.slice(1) : input;
|
|
78
|
+
}
|
|
79
|
+
if (input.byteLength > limits.maxBytes) {
|
|
80
|
+
throw new StatementFileError('too_large', `the file is ${input.byteLength} bytes, over the limit of ${limits.maxBytes}`);
|
|
81
|
+
}
|
|
82
|
+
const first = input[0];
|
|
83
|
+
const second = input[1];
|
|
84
|
+
if ((first === 0xfe && second === 0xff) || (first === 0xff && second === 0xfe)) {
|
|
85
|
+
throw new StatementFileError('unsupported_encoding', 'the file is UTF-16; this reader takes UTF-8');
|
|
86
|
+
}
|
|
87
|
+
let text;
|
|
88
|
+
try {
|
|
89
|
+
text = new TextDecoder('utf-8', { fatal: true }).decode(input);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
throw new StatementFileError('unsupported_encoding', 'the file is not valid UTF-8; decode it first and pass the string');
|
|
93
|
+
}
|
|
94
|
+
const declaration = DECLARATION.exec(text);
|
|
95
|
+
const encoding = declaration?.[1] ?? declaration?.[2];
|
|
96
|
+
if (encoding !== undefined && !/^utf-?8$/i.test(encoding)) {
|
|
97
|
+
throw new StatementFileError('unsupported_encoding', `the file declares encoding ${encoding}; this reader takes UTF-8 — decode it first and pass the string`);
|
|
98
|
+
}
|
|
99
|
+
return text;
|
|
100
|
+
}
|
|
101
|
+
function isSpace(character) {
|
|
102
|
+
return character === ' ' || character === '\n' || character === '\t';
|
|
103
|
+
}
|
|
104
|
+
export function parseXml(input, limits) {
|
|
105
|
+
const source = decode(input, limits).replace(/\r\n?/g, '\n');
|
|
106
|
+
const forbidden = firstForbiddenCharacter(source);
|
|
107
|
+
if (forbidden !== -1)
|
|
108
|
+
throw malformed('a control character XML does not allow', forbidden);
|
|
109
|
+
let at = 0;
|
|
110
|
+
const declaration = DECLARATION.exec(source);
|
|
111
|
+
if (declaration)
|
|
112
|
+
at = declaration[0].length;
|
|
113
|
+
const rootScope = new Map([['xml', XML_NAMESPACE]]);
|
|
114
|
+
const stack = [];
|
|
115
|
+
let root;
|
|
116
|
+
let elements = 0;
|
|
117
|
+
const addText = (raw, where, literal) => {
|
|
118
|
+
const top = stack[stack.length - 1];
|
|
119
|
+
if (top === undefined) {
|
|
120
|
+
if (raw.trim() !== '')
|
|
121
|
+
throw malformed('text outside the document element', where);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
top.text.push(literal ? raw : decodeReferences(raw, where));
|
|
125
|
+
};
|
|
126
|
+
while (at < source.length) {
|
|
127
|
+
const lt = source.indexOf('<', at);
|
|
128
|
+
if (lt === -1) {
|
|
129
|
+
addText(source.slice(at), at, false);
|
|
130
|
+
at = source.length;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
if (lt > at)
|
|
134
|
+
addText(source.slice(at, lt), at, false);
|
|
135
|
+
at = lt;
|
|
136
|
+
if (source.startsWith('<!--', at)) {
|
|
137
|
+
const end = source.indexOf('-->', at + 4);
|
|
138
|
+
if (end === -1)
|
|
139
|
+
throw malformed('a comment that never ends', at);
|
|
140
|
+
at = end + 3;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (source.startsWith('<![CDATA[', at)) {
|
|
144
|
+
if (stack.length === 0)
|
|
145
|
+
throw malformed('a CDATA section outside the document element', at);
|
|
146
|
+
const end = source.indexOf(']]>', at + 9);
|
|
147
|
+
if (end === -1)
|
|
148
|
+
throw malformed('a CDATA section that never ends', at);
|
|
149
|
+
addText(source.slice(at + 9, end), at, true);
|
|
150
|
+
at = end + 3;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (source.startsWith('<!DOCTYPE', at)) {
|
|
154
|
+
throw new StatementFileError('doctype_forbidden', 'the file carries a DOCTYPE; a statement needs none, and entity declarations are refused unread');
|
|
155
|
+
}
|
|
156
|
+
if (source.startsWith('<!', at))
|
|
157
|
+
throw malformed('a markup declaration', at);
|
|
158
|
+
if (source.startsWith('<?', at)) {
|
|
159
|
+
const end = source.indexOf('?>', at + 2);
|
|
160
|
+
if (end === -1)
|
|
161
|
+
throw malformed('a processing instruction that never ends', at);
|
|
162
|
+
if (/^<\?xml[\s?]/i.test(source.slice(at, at + 6))) {
|
|
163
|
+
throw malformed('an XML declaration anywhere but the first character', at);
|
|
164
|
+
}
|
|
165
|
+
at = end + 2;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (source.startsWith('</', at)) {
|
|
169
|
+
NAME.lastIndex = at + 2;
|
|
170
|
+
const name = NAME.exec(source);
|
|
171
|
+
if (!name)
|
|
172
|
+
throw malformed('a closing tag without a name', at);
|
|
173
|
+
let end = NAME.lastIndex;
|
|
174
|
+
while (isSpace(source[end]))
|
|
175
|
+
end += 1;
|
|
176
|
+
if (source[end] !== '>')
|
|
177
|
+
throw malformed('a closing tag that never ends', at);
|
|
178
|
+
const open = stack.pop();
|
|
179
|
+
if (open === undefined || open.qualifiedName !== name[0]) {
|
|
180
|
+
throw malformed(`</${name[0]}> closes ${open ? `<${open.qualifiedName}>` : 'nothing'}`, at);
|
|
181
|
+
}
|
|
182
|
+
open.element.text = open.text.join('');
|
|
183
|
+
at = end + 1;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
// An opening tag.
|
|
187
|
+
NAME.lastIndex = at + 1;
|
|
188
|
+
const name = NAME.exec(source);
|
|
189
|
+
if (!name)
|
|
190
|
+
throw malformed('a "<" that opens nothing', at);
|
|
191
|
+
if (root !== undefined && stack.length === 0) {
|
|
192
|
+
throw malformed('a second document element', at);
|
|
193
|
+
}
|
|
194
|
+
elements += 1;
|
|
195
|
+
if (elements > limits.maxElements) {
|
|
196
|
+
throw new StatementFileError('too_many_elements', `the file holds more than ${limits.maxElements} elements`);
|
|
197
|
+
}
|
|
198
|
+
if (stack.length >= limits.maxDepth) {
|
|
199
|
+
throw new StatementFileError('too_deep', `elements are nested deeper than ${limits.maxDepth}`);
|
|
200
|
+
}
|
|
201
|
+
let cursor = NAME.lastIndex;
|
|
202
|
+
const written = [];
|
|
203
|
+
for (;;) {
|
|
204
|
+
ATTRIBUTE.lastIndex = cursor;
|
|
205
|
+
const attribute = ATTRIBUTE.exec(source);
|
|
206
|
+
if (!attribute)
|
|
207
|
+
break;
|
|
208
|
+
const raw = (attribute[2] ?? attribute[3]);
|
|
209
|
+
written.push([
|
|
210
|
+
attribute[1],
|
|
211
|
+
decodeReferences(raw, cursor).replace(/[\t\n]/g, ' '),
|
|
212
|
+
]);
|
|
213
|
+
cursor = ATTRIBUTE.lastIndex;
|
|
214
|
+
}
|
|
215
|
+
while (isSpace(source[cursor]))
|
|
216
|
+
cursor += 1;
|
|
217
|
+
const selfClosing = source[cursor] === '/';
|
|
218
|
+
if (selfClosing)
|
|
219
|
+
cursor += 1;
|
|
220
|
+
if (source[cursor] !== '>')
|
|
221
|
+
throw malformed(`<${name[0]}> is not a well-formed tag`, at);
|
|
222
|
+
const parentScope = stack[stack.length - 1]?.scope ?? rootScope;
|
|
223
|
+
let scope = parentScope;
|
|
224
|
+
const attributes = {};
|
|
225
|
+
const seen = new Set();
|
|
226
|
+
for (const [key, value] of written) {
|
|
227
|
+
if (seen.has(key))
|
|
228
|
+
throw malformed(`attribute ${key} is written twice on <${name[0]}>`, at);
|
|
229
|
+
seen.add(key);
|
|
230
|
+
if (key === 'xmlns' || key.startsWith('xmlns:')) {
|
|
231
|
+
if (scope === parentScope)
|
|
232
|
+
scope = new Map(parentScope);
|
|
233
|
+
const prefix = key === 'xmlns' ? '' : key.slice(6);
|
|
234
|
+
if (prefix === 'xml' || prefix === 'xmlns') {
|
|
235
|
+
throw malformed(`prefix ${prefix} cannot be declared`, at);
|
|
236
|
+
}
|
|
237
|
+
if (prefix !== '' && value === '')
|
|
238
|
+
throw malformed(`prefix ${prefix} is bound to nothing`, at);
|
|
239
|
+
scope.set(prefix, value);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
attributes[key] = value;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const colon = name[0].indexOf(':');
|
|
246
|
+
const prefix = colon === -1 ? '' : name[0].slice(0, colon);
|
|
247
|
+
const namespace = scope.get(prefix);
|
|
248
|
+
if (namespace === undefined && prefix !== '') {
|
|
249
|
+
throw malformed(`prefix ${prefix} is bound to no namespace`, at);
|
|
250
|
+
}
|
|
251
|
+
const element = {
|
|
252
|
+
name: colon === -1 ? name[0] : name[0].slice(colon + 1),
|
|
253
|
+
namespace: namespace ?? '',
|
|
254
|
+
attributes,
|
|
255
|
+
children: [],
|
|
256
|
+
text: '',
|
|
257
|
+
};
|
|
258
|
+
const parent = stack[stack.length - 1];
|
|
259
|
+
if (parent)
|
|
260
|
+
parent.element.children.push(element);
|
|
261
|
+
else
|
|
262
|
+
root = element;
|
|
263
|
+
if (!selfClosing)
|
|
264
|
+
stack.push({ element, qualifiedName: name[0], scope, text: [] });
|
|
265
|
+
at = cursor + 1;
|
|
266
|
+
}
|
|
267
|
+
const unclosed = stack[stack.length - 1];
|
|
268
|
+
if (unclosed)
|
|
269
|
+
throw malformed(`<${unclosed.qualifiedName}> is never closed`, source.length);
|
|
270
|
+
if (root === undefined)
|
|
271
|
+
throw malformed('no document element', 0);
|
|
272
|
+
return root;
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=xml.js.map
|
package/dist/xml.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml.js","sourceRoot":"","sources":["../src/xml.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ekwo-ai/camt053",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Reads an ISO 20022 bank-to-customer statement (camt.053) into plain objects in TypeScript: account, balances and lines, amounts as decimal strings, and what does not add up. Zero dependencies, its own strict XML reader.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"camt.053",
|
|
7
|
+
"camt053",
|
|
8
|
+
"iso20022",
|
|
9
|
+
"bank-statement",
|
|
10
|
+
"bank-to-customer-statement",
|
|
11
|
+
"reconciliation",
|
|
12
|
+
"sepa",
|
|
13
|
+
"xml",
|
|
14
|
+
"parser"
|
|
15
|
+
],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": "Ekwo AI",
|
|
18
|
+
"homepage": "https://github.com/Ekwo-ai/ekwo-os/tree/main/packages/formats/camt053#readme",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/Ekwo-ai/ekwo-os.git",
|
|
22
|
+
"directory": "packages/formats/camt053"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/Ekwo-ai/ekwo-os/issues"
|
|
26
|
+
},
|
|
27
|
+
"type": "module",
|
|
28
|
+
"sideEffects": false,
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"main": "./dist/index.js",
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./dist/index.d.ts",
|
|
42
|
+
"import": "./dist/index.js"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsc -p tsconfig.build.json",
|
|
47
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
48
|
+
"test": "vitest run"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^24.0.0",
|
|
52
|
+
"typescript": "^5.9.0",
|
|
53
|
+
"vitest": "^3.2.0",
|
|
54
|
+
"xmllint-wasm": "^5.3.0"
|
|
55
|
+
}
|
|
56
|
+
}
|