avantgate 1.0.0 → 1.1.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/README.md +384 -287
- package/dist/chunk-CO26LNFD.mjs +521 -0
- package/dist/finance/index.d.mts +76 -0
- package/dist/finance/index.d.ts +76 -0
- package/dist/finance/index.js +536 -0
- package/dist/finance/index.mjs +20 -0
- package/dist/index.d.mts +127 -3
- package/dist/index.d.ts +127 -3
- package/dist/index.js +929 -13
- package/dist/index.mjs +460 -48
- package/dist/strategy.interface-CB4_ZAuk.d.mts +16 -0
- package/dist/strategy.interface-CB4_ZAuk.d.ts +16 -0
- package/package.json +67 -55
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/finance/index.ts
|
|
21
|
+
var finance_exports = {};
|
|
22
|
+
__export(finance_exports, {
|
|
23
|
+
AccountingFactory: () => AccountingFactory,
|
|
24
|
+
FrenchPCGStrategy: () => FrenchPCGStrategy,
|
|
25
|
+
InternationalAccountingStrategy: () => InternationalAccountingStrategy,
|
|
26
|
+
SwissCOStrategy: () => SwissCOStrategy,
|
|
27
|
+
UkIFRSStrategy: () => UkIFRSStrategy,
|
|
28
|
+
UsGAAPStrategy: () => UsGAAPStrategy,
|
|
29
|
+
cleanFinancialJSON: () => cleanFinancialJSON,
|
|
30
|
+
withFinancialNormalizer: () => withFinancialNormalizer
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(finance_exports);
|
|
33
|
+
|
|
34
|
+
// src/finance/strategies/french-pcg.strategy.ts
|
|
35
|
+
var FrenchPCGStrategy = class {
|
|
36
|
+
jurisdictionCode = "FR";
|
|
37
|
+
standard = "PCG";
|
|
38
|
+
defaultCurrency = "EUR";
|
|
39
|
+
cleanNumber(value) {
|
|
40
|
+
if (typeof value === "number") {
|
|
41
|
+
return Number.isFinite(value) ? value : 0;
|
|
42
|
+
}
|
|
43
|
+
if (!value || typeof value !== "string") {
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
let str = value.trim();
|
|
47
|
+
let isNegative = false;
|
|
48
|
+
const parenMatch = str.match(/^\(\s*(.+?)\s*\)$/);
|
|
49
|
+
if (parenMatch) {
|
|
50
|
+
isNegative = true;
|
|
51
|
+
str = parenMatch[1];
|
|
52
|
+
} else if (str.startsWith("-")) {
|
|
53
|
+
isNegative = true;
|
|
54
|
+
str = str.substring(1).trim();
|
|
55
|
+
}
|
|
56
|
+
let multiplier = 1;
|
|
57
|
+
if (/[kK](?:€|eur)?\b/i.test(str)) {
|
|
58
|
+
multiplier = 1e3;
|
|
59
|
+
str = str.replace(/[kK](?:€|eur)?\b/gi, "").trim();
|
|
60
|
+
} else if (/[mM](?:€|eur)?\b/i.test(str)) {
|
|
61
|
+
multiplier = 1e6;
|
|
62
|
+
str = str.replace(/[mM](?:€|eur)?\b/gi, "").trim();
|
|
63
|
+
}
|
|
64
|
+
str = str.replace(/[€$£]/g, "").replace(/\s+/g, "").replace(/\u00A0/g, "").trim();
|
|
65
|
+
str = str.replace(",", ".");
|
|
66
|
+
const parsed = parseFloat(str);
|
|
67
|
+
if (isNaN(parsed)) {
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
const finalValue = parsed * multiplier;
|
|
71
|
+
return isNegative ? -Math.abs(finalValue) : finalValue;
|
|
72
|
+
}
|
|
73
|
+
cleanJSON(rawText) {
|
|
74
|
+
let result = rawText;
|
|
75
|
+
result = result.replace(
|
|
76
|
+
/(:\s*)\(\s*([0-9][0-9\s.,]*(?:k€|k|keur|m€|m|meur|€)?)\s*\)/gi,
|
|
77
|
+
(_, prefix, amountStr) => {
|
|
78
|
+
const num = this.cleanNumber(`(${amountStr})`);
|
|
79
|
+
return `${prefix}${num}`;
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
result = result.replace(
|
|
83
|
+
/(:\s*)"\s*\(\s*([0-9][0-9\s.,]*(?:k€|k|keur|m€|m|meur|€)?)\s*\)\s*"/gi,
|
|
84
|
+
(_, prefix, amountStr) => {
|
|
85
|
+
const num = this.cleanNumber(`(${amountStr})`);
|
|
86
|
+
return `${prefix}${num}`;
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
result = result.replace(
|
|
90
|
+
/(:\s*)"\s*([+-]?[0-9][0-9\s.,]*(?:k€|k|keur|m€|m|meur|€))\s*"/gi,
|
|
91
|
+
(_, prefix, amountStr) => {
|
|
92
|
+
const num = this.cleanNumber(amountStr);
|
|
93
|
+
return `${prefix}${num}`;
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
result = result.replace(
|
|
97
|
+
/(:\s*)"\s*([+-]?(?:[0-9]{1,3}(?:\s+[0-9]{3})+(?:,[0-9]+)?|[0-9]+,[0-9]+))\s*"/g,
|
|
98
|
+
(_, prefix, amountStr) => {
|
|
99
|
+
const num = this.cleanNumber(amountStr);
|
|
100
|
+
return `${prefix}${num}`;
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
detect(text) {
|
|
106
|
+
const lower = text.toLowerCase();
|
|
107
|
+
const frPatterns = [
|
|
108
|
+
/\bcerfa\b/i,
|
|
109
|
+
/\bliasse\s+fiscale\b/i,
|
|
110
|
+
/\bbilan\s+(actif|passif)\b/i,
|
|
111
|
+
/\bcompte\s+de\s+r[ée]sultat\b/i,
|
|
112
|
+
/\bplan\s+comptable\s+g[ée]n[ée]ral\b/i,
|
|
113
|
+
/\bpcg\b/i,
|
|
114
|
+
/\bsiren\b/i,
|
|
115
|
+
/\bsiret\b/i,
|
|
116
|
+
/\b[0-9\s.,]+(?:k€|m€)\b/i,
|
|
117
|
+
/\beur\b/i,
|
|
118
|
+
/€/
|
|
119
|
+
];
|
|
120
|
+
return frPatterns.some((pattern) => pattern.test(lower));
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// src/finance/strategies/us-gaap.strategy.ts
|
|
125
|
+
var UsGAAPStrategy = class {
|
|
126
|
+
jurisdictionCode = "US";
|
|
127
|
+
standard = "US_GAAP";
|
|
128
|
+
defaultCurrency = "USD";
|
|
129
|
+
cleanNumber(value) {
|
|
130
|
+
if (typeof value === "number") {
|
|
131
|
+
return Number.isFinite(value) ? value : 0;
|
|
132
|
+
}
|
|
133
|
+
if (!value || typeof value !== "string") {
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
let str = value.trim();
|
|
137
|
+
let isNegative = false;
|
|
138
|
+
const parenMatch = str.match(/^[(\[]\s*(.+?)\s*[)\]]$/);
|
|
139
|
+
if (parenMatch) {
|
|
140
|
+
isNegative = true;
|
|
141
|
+
str = parenMatch[1];
|
|
142
|
+
} else if (str.startsWith("-")) {
|
|
143
|
+
isNegative = true;
|
|
144
|
+
str = str.substring(1).trim();
|
|
145
|
+
}
|
|
146
|
+
let multiplier = 1;
|
|
147
|
+
if (/[kK]\b/.test(str)) {
|
|
148
|
+
multiplier = 1e3;
|
|
149
|
+
str = str.replace(/[kK]\b/g, "").trim();
|
|
150
|
+
} else if (/[mM]\b/.test(str)) {
|
|
151
|
+
multiplier = 1e6;
|
|
152
|
+
str = str.replace(/[mM]\b/g, "").trim();
|
|
153
|
+
} else if (/[bB]\b/.test(str)) {
|
|
154
|
+
multiplier = 1e9;
|
|
155
|
+
str = str.replace(/[bB]\b/g, "").trim();
|
|
156
|
+
}
|
|
157
|
+
str = str.replace(/[$]/g, "").replace(/\busd\b/gi, "").replace(/,/g, "").replace(/\s+/g, "").trim();
|
|
158
|
+
const parsed = parseFloat(str);
|
|
159
|
+
if (isNaN(parsed)) {
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
162
|
+
const finalVal = parsed * multiplier;
|
|
163
|
+
return isNegative ? -Math.abs(finalVal) : finalVal;
|
|
164
|
+
}
|
|
165
|
+
cleanJSON(rawText) {
|
|
166
|
+
let result = rawText;
|
|
167
|
+
result = result.replace(
|
|
168
|
+
/(:\s*)[(\[]\s*([0-9][0-9,.]*(?:k|m|b|\$)?)\s*[)\]]/gi,
|
|
169
|
+
(_, prefix, amountStr) => {
|
|
170
|
+
const num = this.cleanNumber(`(${amountStr})`);
|
|
171
|
+
return `${prefix}${num}`;
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
result = result.replace(
|
|
175
|
+
/(:\s*)"\s*[(\[]\s*([0-9][0-9,.]*(?:k|m|b|\$)?)\s*[)\]]\s*"/gi,
|
|
176
|
+
(_, prefix, amountStr) => {
|
|
177
|
+
const num = this.cleanNumber(`(${amountStr})`);
|
|
178
|
+
return `${prefix}${num}`;
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
result = result.replace(
|
|
182
|
+
/(:\s*)"\s*([+-]?\$?\s*[0-9][0-9,.]*\s*(?:k|m|b|\$)?)\s*"/gi,
|
|
183
|
+
(_, prefix, amountStr) => {
|
|
184
|
+
if (!amountStr.includes("$") && !/[kmb]/i.test(amountStr)) {
|
|
185
|
+
return `${prefix}"${amountStr}"`;
|
|
186
|
+
}
|
|
187
|
+
const num = this.cleanNumber(amountStr);
|
|
188
|
+
return `${prefix}${num}`;
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
detect(text) {
|
|
194
|
+
const lower = text.toLowerCase();
|
|
195
|
+
const usPatterns = [
|
|
196
|
+
/\b10-[kq]\b/i,
|
|
197
|
+
/\bsec\s+filing\b/i,
|
|
198
|
+
/\bus[\s_-]?gaap\b/i,
|
|
199
|
+
/\bbalance\s+sheet\b/i,
|
|
200
|
+
/\bincome\s+statement\b/i,
|
|
201
|
+
/\bstatement\s+of\s+cash\s+flows\b/i,
|
|
202
|
+
/\$|usd/i
|
|
203
|
+
];
|
|
204
|
+
return usPatterns.some((pattern) => pattern.test(lower));
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// src/finance/strategies/uk-ifrs.strategy.ts
|
|
209
|
+
var UkIFRSStrategy = class {
|
|
210
|
+
jurisdictionCode = "UK";
|
|
211
|
+
standard = "IFRS";
|
|
212
|
+
defaultCurrency = "GBP";
|
|
213
|
+
cleanNumber(value) {
|
|
214
|
+
if (typeof value === "number") {
|
|
215
|
+
return Number.isFinite(value) ? value : 0;
|
|
216
|
+
}
|
|
217
|
+
if (!value || typeof value !== "string") {
|
|
218
|
+
return 0;
|
|
219
|
+
}
|
|
220
|
+
let str = value.trim();
|
|
221
|
+
let isNegative = false;
|
|
222
|
+
const parenMatch = str.match(/^\(\s*(.+?)\s*\)$/);
|
|
223
|
+
if (parenMatch) {
|
|
224
|
+
isNegative = true;
|
|
225
|
+
str = parenMatch[1];
|
|
226
|
+
} else if (str.startsWith("-")) {
|
|
227
|
+
isNegative = true;
|
|
228
|
+
str = str.substring(1).trim();
|
|
229
|
+
}
|
|
230
|
+
let multiplier = 1;
|
|
231
|
+
if (/[kK]\b/.test(str)) {
|
|
232
|
+
multiplier = 1e3;
|
|
233
|
+
str = str.replace(/[kK]\b/g, "").trim();
|
|
234
|
+
} else if (/[mM]\b/.test(str)) {
|
|
235
|
+
multiplier = 1e6;
|
|
236
|
+
str = str.replace(/[mM]\b/g, "").trim();
|
|
237
|
+
}
|
|
238
|
+
str = str.replace(/[£]/g, "").replace(/\bgbp\b/gi, "").replace(/,/g, "").replace(/\s+/g, "").trim();
|
|
239
|
+
const parsed = parseFloat(str);
|
|
240
|
+
if (isNaN(parsed)) {
|
|
241
|
+
return 0;
|
|
242
|
+
}
|
|
243
|
+
const finalVal = parsed * multiplier;
|
|
244
|
+
return isNegative ? -Math.abs(finalVal) : finalVal;
|
|
245
|
+
}
|
|
246
|
+
cleanJSON(rawText) {
|
|
247
|
+
let result = rawText;
|
|
248
|
+
result = result.replace(
|
|
249
|
+
/(:\s*)\(\s*([0-9][0-9,.]*(?:k|m|£)?)\s*\)/gi,
|
|
250
|
+
(_, prefix, amountStr) => {
|
|
251
|
+
const num = this.cleanNumber(`(${amountStr})`);
|
|
252
|
+
return `${prefix}${num}`;
|
|
253
|
+
}
|
|
254
|
+
);
|
|
255
|
+
result = result.replace(
|
|
256
|
+
/(:\s*)"\s*\(\s*([0-9][0-9,.]*(?:k|m|£)?)\s*\)\s*"/gi,
|
|
257
|
+
(_, prefix, amountStr) => {
|
|
258
|
+
const num = this.cleanNumber(`(${amountStr})`);
|
|
259
|
+
return `${prefix}${num}`;
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
result = result.replace(
|
|
263
|
+
/(:\s*)"\s*([+-]?£\s*[0-9][0-9,.]*\s*(?:k|m)?)\s*"/gi,
|
|
264
|
+
(_, prefix, amountStr) => {
|
|
265
|
+
const num = this.cleanNumber(amountStr);
|
|
266
|
+
return `${prefix}${num}`;
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
271
|
+
detect(text) {
|
|
272
|
+
const lower = text.toLowerCase();
|
|
273
|
+
const ukPatterns = [
|
|
274
|
+
/\bcompanies\s+house\b/i,
|
|
275
|
+
/\bfrs\s*102\b/i,
|
|
276
|
+
/\bhmrc\b/i,
|
|
277
|
+
/\bprofit\s+and\s+loss\b/i,
|
|
278
|
+
/£|\bgbp\b/i
|
|
279
|
+
];
|
|
280
|
+
return ukPatterns.some((pattern) => pattern.test(lower));
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
// src/finance/strategies/swiss-co.strategy.ts
|
|
285
|
+
var SwissCOStrategy = class {
|
|
286
|
+
jurisdictionCode = "CH";
|
|
287
|
+
standard = "SWISS_CO";
|
|
288
|
+
defaultCurrency = "CHF";
|
|
289
|
+
cleanNumber(value) {
|
|
290
|
+
if (typeof value === "number") {
|
|
291
|
+
return Number.isFinite(value) ? value : 0;
|
|
292
|
+
}
|
|
293
|
+
if (!value || typeof value !== "string") {
|
|
294
|
+
return 0;
|
|
295
|
+
}
|
|
296
|
+
let str = value.trim();
|
|
297
|
+
let isNegative = false;
|
|
298
|
+
const parenMatch = str.match(/^\(\s*(.+?)\s*\)$/);
|
|
299
|
+
if (parenMatch) {
|
|
300
|
+
isNegative = true;
|
|
301
|
+
str = parenMatch[1];
|
|
302
|
+
} else if (str.startsWith("-")) {
|
|
303
|
+
isNegative = true;
|
|
304
|
+
str = str.substring(1).trim();
|
|
305
|
+
}
|
|
306
|
+
let multiplier = 1;
|
|
307
|
+
if (/[kK]\b/.test(str)) {
|
|
308
|
+
multiplier = 1e3;
|
|
309
|
+
str = str.replace(/[kK]\b/g, "").trim();
|
|
310
|
+
} else if (/[mM]\b/.test(str)) {
|
|
311
|
+
multiplier = 1e6;
|
|
312
|
+
str = str.replace(/[mM]\b/g, "").trim();
|
|
313
|
+
}
|
|
314
|
+
str = str.replace(/\bchf\b/gi, "").replace(/['’]/g, "").replace(/\s+/g, "").trim();
|
|
315
|
+
str = str.replace(",", ".");
|
|
316
|
+
const parsed = parseFloat(str);
|
|
317
|
+
if (isNaN(parsed)) {
|
|
318
|
+
return 0;
|
|
319
|
+
}
|
|
320
|
+
const finalVal = parsed * multiplier;
|
|
321
|
+
return isNegative ? -Math.abs(finalVal) : finalVal;
|
|
322
|
+
}
|
|
323
|
+
cleanJSON(rawText) {
|
|
324
|
+
let result = rawText;
|
|
325
|
+
result = result.replace(
|
|
326
|
+
/(:\s*)\(\s*([0-9][0-9'’.,\s]*(?:k|m|chf)?)\s*\)/gi,
|
|
327
|
+
(_, prefix, amountStr) => {
|
|
328
|
+
const num = this.cleanNumber(`(${amountStr})`);
|
|
329
|
+
return `${prefix}${num}`;
|
|
330
|
+
}
|
|
331
|
+
);
|
|
332
|
+
result = result.replace(
|
|
333
|
+
/(:\s*)"\s*\(\s*([0-9][0-9'’.,\s]*(?:k|m|chf)?)\s*\)\s*"/gi,
|
|
334
|
+
(_, prefix, amountStr) => {
|
|
335
|
+
const num = this.cleanNumber(`(${amountStr})`);
|
|
336
|
+
return `${prefix}${num}`;
|
|
337
|
+
}
|
|
338
|
+
);
|
|
339
|
+
result = result.replace(
|
|
340
|
+
/(:\s*)"\s*([+-]?[0-9][0-9'’.,\s]*(?:k|m|chf))\s*"/gi,
|
|
341
|
+
(_, prefix, amountStr) => {
|
|
342
|
+
const num = this.cleanNumber(amountStr);
|
|
343
|
+
return `${prefix}${num}`;
|
|
344
|
+
}
|
|
345
|
+
);
|
|
346
|
+
return result;
|
|
347
|
+
}
|
|
348
|
+
detect(text) {
|
|
349
|
+
const lower = text.toLowerCase();
|
|
350
|
+
const chPatterns = [
|
|
351
|
+
/\bcode\s+des\s+obligations\b/i,
|
|
352
|
+
/\bart\.?\s*725\b/i,
|
|
353
|
+
/\bche-[0-9]{3}\.[0-9]{3}\.[0-9]{3}\b/i,
|
|
354
|
+
/\bchf\b/i,
|
|
355
|
+
/\b[0-9]{1,3}(?:'[0-9]{3})+\b/
|
|
356
|
+
];
|
|
357
|
+
return chPatterns.some((pattern) => pattern.test(lower));
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// src/finance/strategies/international.strategy.ts
|
|
362
|
+
var InternationalAccountingStrategy = class {
|
|
363
|
+
jurisdictionCode = "INTERNATIONAL";
|
|
364
|
+
standard = "OTHER";
|
|
365
|
+
defaultCurrency = "EUR";
|
|
366
|
+
cleanNumber(value) {
|
|
367
|
+
if (typeof value === "number") {
|
|
368
|
+
return Number.isFinite(value) ? value : 0;
|
|
369
|
+
}
|
|
370
|
+
if (!value || typeof value !== "string") {
|
|
371
|
+
return 0;
|
|
372
|
+
}
|
|
373
|
+
let str = value.trim();
|
|
374
|
+
let isNegative = false;
|
|
375
|
+
const parenMatch = str.match(/^[(\[]\s*(.+?)\s*[)\]]$/);
|
|
376
|
+
if (parenMatch) {
|
|
377
|
+
isNegative = true;
|
|
378
|
+
str = parenMatch[1];
|
|
379
|
+
} else if (str.startsWith("-")) {
|
|
380
|
+
isNegative = true;
|
|
381
|
+
str = str.substring(1).trim();
|
|
382
|
+
}
|
|
383
|
+
let multiplier = 1;
|
|
384
|
+
if (/[kK]\b/.test(str)) {
|
|
385
|
+
multiplier = 1e3;
|
|
386
|
+
str = str.replace(/[kK]\b/g, "").trim();
|
|
387
|
+
} else if (/[mM]\b/.test(str)) {
|
|
388
|
+
multiplier = 1e6;
|
|
389
|
+
str = str.replace(/[mM]\b/g, "").trim();
|
|
390
|
+
}
|
|
391
|
+
str = str.replace(/[€$£]/g, "").replace(/\b(?:eur|usd|gbp|chf)\b/gi, "").trim();
|
|
392
|
+
if (str.includes(",") && str.includes(".")) {
|
|
393
|
+
if (str.lastIndexOf(",") > str.lastIndexOf(".")) {
|
|
394
|
+
str = str.replace(/\./g, "").replace(",", ".");
|
|
395
|
+
} else {
|
|
396
|
+
str = str.replace(/,/g, "");
|
|
397
|
+
}
|
|
398
|
+
} else if (str.includes(",")) {
|
|
399
|
+
if (/,\d{1,2}$/.test(str)) {
|
|
400
|
+
str = str.replace(",", ".");
|
|
401
|
+
} else {
|
|
402
|
+
str = str.replace(",", "");
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
str = str.replace(/\s+/g, "");
|
|
406
|
+
const parsed = parseFloat(str);
|
|
407
|
+
if (isNaN(parsed)) {
|
|
408
|
+
return 0;
|
|
409
|
+
}
|
|
410
|
+
const finalVal = parsed * multiplier;
|
|
411
|
+
return isNegative ? -Math.abs(finalVal) : finalVal;
|
|
412
|
+
}
|
|
413
|
+
cleanJSON(rawText) {
|
|
414
|
+
let result = rawText;
|
|
415
|
+
result = result.replace(
|
|
416
|
+
/(:\s*)[(\[]\s*([0-9][0-9,.\s]*(?:k|m|€|\$|£)?)\s*[)\]]/gi,
|
|
417
|
+
(_, prefix, amountStr) => {
|
|
418
|
+
const num = this.cleanNumber(`(${amountStr})`);
|
|
419
|
+
return `${prefix}${num}`;
|
|
420
|
+
}
|
|
421
|
+
);
|
|
422
|
+
result = result.replace(
|
|
423
|
+
/(:\s*)"\s*[(\[]\s*([0-9][0-9,.\s]*(?:k|m|€|\$|£)?)\s*[)\]]\s*"/gi,
|
|
424
|
+
(_, prefix, amountStr) => {
|
|
425
|
+
const num = this.cleanNumber(`(${amountStr})`);
|
|
426
|
+
return `${prefix}${num}`;
|
|
427
|
+
}
|
|
428
|
+
);
|
|
429
|
+
return result;
|
|
430
|
+
}
|
|
431
|
+
detect(_text) {
|
|
432
|
+
return true;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
// src/finance/factory.ts
|
|
437
|
+
var AccountingFactory = class {
|
|
438
|
+
static strategies = /* @__PURE__ */ new Map();
|
|
439
|
+
static detectionOrder = [];
|
|
440
|
+
static {
|
|
441
|
+
this.initDefaults();
|
|
442
|
+
}
|
|
443
|
+
static initDefaults() {
|
|
444
|
+
const fr = new FrenchPCGStrategy();
|
|
445
|
+
const us = new UsGAAPStrategy();
|
|
446
|
+
const uk = new UkIFRSStrategy();
|
|
447
|
+
const ch = new SwissCOStrategy();
|
|
448
|
+
const intl = new InternationalAccountingStrategy();
|
|
449
|
+
this.registerStrategy(ch);
|
|
450
|
+
this.registerStrategy(uk);
|
|
451
|
+
this.registerStrategy(us);
|
|
452
|
+
this.registerStrategy(fr);
|
|
453
|
+
this.registerStrategy(intl);
|
|
454
|
+
}
|
|
455
|
+
static registerStrategy(strategy) {
|
|
456
|
+
this.strategies.set(strategy.jurisdictionCode, strategy);
|
|
457
|
+
this.detectionOrder = [
|
|
458
|
+
strategy,
|
|
459
|
+
...this.detectionOrder.filter((s) => s.jurisdictionCode !== strategy.jurisdictionCode)
|
|
460
|
+
];
|
|
461
|
+
}
|
|
462
|
+
static getStrategy(code) {
|
|
463
|
+
if (!code) {
|
|
464
|
+
return this.strategies.get("FR") || new FrenchPCGStrategy();
|
|
465
|
+
}
|
|
466
|
+
const strategy = this.strategies.get(code);
|
|
467
|
+
if (!strategy) {
|
|
468
|
+
return this.strategies.get("FR") || new FrenchPCGStrategy();
|
|
469
|
+
}
|
|
470
|
+
return strategy;
|
|
471
|
+
}
|
|
472
|
+
static detectStrategy(documentText) {
|
|
473
|
+
for (const strategy of this.detectionOrder) {
|
|
474
|
+
if (strategy.jurisdictionCode !== "INTERNATIONAL" && strategy.detect(documentText)) {
|
|
475
|
+
return strategy;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return this.getStrategy("FR");
|
|
479
|
+
}
|
|
480
|
+
static resetDefaults() {
|
|
481
|
+
this.strategies.clear();
|
|
482
|
+
this.detectionOrder = [];
|
|
483
|
+
this.initDefaults();
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
// src/response-validator.ts
|
|
488
|
+
function extractAndCleanJSON(rawText) {
|
|
489
|
+
let cleaned = rawText.trim();
|
|
490
|
+
cleaned = cleaned.replace(/<think>[\s\S]*?<\/think>/gi, "").trim();
|
|
491
|
+
const codeBlockMatch = cleaned.match(/```(?:json)?\s*([\s\S]*?)\s*```/i);
|
|
492
|
+
if (codeBlockMatch && codeBlockMatch[1]) {
|
|
493
|
+
cleaned = codeBlockMatch[1].trim();
|
|
494
|
+
}
|
|
495
|
+
const firstBrace = cleaned.indexOf("{");
|
|
496
|
+
const firstBracket = cleaned.indexOf("[");
|
|
497
|
+
let startIndex = -1;
|
|
498
|
+
if (firstBrace !== -1 && firstBracket !== -1) {
|
|
499
|
+
startIndex = Math.min(firstBrace, firstBracket);
|
|
500
|
+
} else if (firstBrace !== -1) {
|
|
501
|
+
startIndex = firstBrace;
|
|
502
|
+
} else if (firstBracket !== -1) {
|
|
503
|
+
startIndex = firstBracket;
|
|
504
|
+
}
|
|
505
|
+
const lastBrace = cleaned.lastIndexOf("}");
|
|
506
|
+
const lastBracket = cleaned.lastIndexOf("]");
|
|
507
|
+
const endIndex = Math.max(lastBrace, lastBracket);
|
|
508
|
+
if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
|
|
509
|
+
cleaned = cleaned.slice(startIndex, endIndex + 1);
|
|
510
|
+
}
|
|
511
|
+
return cleaned;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// src/finance/normalizer.ts
|
|
515
|
+
function cleanFinancialJSON(rawText, options) {
|
|
516
|
+
if (!rawText) {
|
|
517
|
+
return "";
|
|
518
|
+
}
|
|
519
|
+
const jsonBlock = extractAndCleanJSON(rawText);
|
|
520
|
+
const strategy = options?.jurisdiction ? AccountingFactory.getStrategy(options.jurisdiction) : options?.autoDetect !== false ? AccountingFactory.detectStrategy(rawText) : AccountingFactory.getStrategy("FR");
|
|
521
|
+
return strategy.cleanJSON(jsonBlock);
|
|
522
|
+
}
|
|
523
|
+
function withFinancialNormalizer(options) {
|
|
524
|
+
return (rawText) => cleanFinancialJSON(rawText, options);
|
|
525
|
+
}
|
|
526
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
527
|
+
0 && (module.exports = {
|
|
528
|
+
AccountingFactory,
|
|
529
|
+
FrenchPCGStrategy,
|
|
530
|
+
InternationalAccountingStrategy,
|
|
531
|
+
SwissCOStrategy,
|
|
532
|
+
UkIFRSStrategy,
|
|
533
|
+
UsGAAPStrategy,
|
|
534
|
+
cleanFinancialJSON,
|
|
535
|
+
withFinancialNormalizer
|
|
536
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccountingFactory,
|
|
3
|
+
FrenchPCGStrategy,
|
|
4
|
+
InternationalAccountingStrategy,
|
|
5
|
+
SwissCOStrategy,
|
|
6
|
+
UkIFRSStrategy,
|
|
7
|
+
UsGAAPStrategy,
|
|
8
|
+
cleanFinancialJSON,
|
|
9
|
+
withFinancialNormalizer
|
|
10
|
+
} from "../chunk-CO26LNFD.mjs";
|
|
11
|
+
export {
|
|
12
|
+
AccountingFactory,
|
|
13
|
+
FrenchPCGStrategy,
|
|
14
|
+
InternationalAccountingStrategy,
|
|
15
|
+
SwissCOStrategy,
|
|
16
|
+
UkIFRSStrategy,
|
|
17
|
+
UsGAAPStrategy,
|
|
18
|
+
cleanFinancialJSON,
|
|
19
|
+
withFinancialNormalizer
|
|
20
|
+
};
|