@fin.cx/opendata 4.8.0 → 4.9.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/gleif/classes.gleifclient.d.ts +26 -0
- package/dist_ts/gleif/classes.gleifclient.js +214 -0
- package/dist_ts/gleif/classes.gleiferror.d.ts +6 -0
- package/dist_ts/gleif/classes.gleiferror.js +11 -0
- package/dist_ts/gleif/crosswalk.d.ts +7 -0
- package/dist_ts/gleif/crosswalk.js +25 -0
- package/dist_ts/gleif/csv.d.ts +2 -0
- package/dist_ts/gleif/csv.js +75 -0
- package/dist_ts/gleif/data.crosswalk.d.ts +12 -0
- package/dist_ts/gleif/data.crosswalk.js +1265 -0
- package/dist_ts/gleif/index.d.ts +6 -0
- package/dist_ts/gleif/index.js +7 -0
- package/dist_ts/gleif/interfaces.d.ts +101 -0
- package/dist_ts/gleif/interfaces.js +2 -0
- package/dist_ts/gleif/plugins.d.ts +1 -0
- package/dist_ts/gleif/plugins.js +3 -0
- package/dist_ts/gleif/records.d.ts +6 -0
- package/dist_ts/gleif/records.js +107 -0
- package/dist_ts/gleif/stream.zip.d.ts +2 -0
- package/dist_ts/gleif/stream.zip.js +54 -0
- package/dist_ts/handelsregister/data.codelists.d.ts +2 -0
- package/dist_ts/handelsregister/data.codelists.js +10 -10
- package/dist_ts/handelsregister/interfaces.d.ts +5 -1
- package/dist_ts/handelsregister/parse.structuredcontent.js +6 -4
- package/dist_ts/plugins.d.ts +2 -0
- package/dist_ts/plugins.js +4 -1
- package/package.json +7 -2
- package/readme.md +79 -4
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/gleif/classes.gleifclient.ts +170 -0
- package/ts/gleif/classes.gleiferror.ts +8 -0
- package/ts/gleif/crosswalk.ts +29 -0
- package/ts/gleif/csv.ts +60 -0
- package/ts/gleif/data.crosswalk.ts +1271 -0
- package/ts/gleif/index.ts +6 -0
- package/ts/gleif/interfaces.ts +107 -0
- package/ts/gleif/plugins.ts +2 -0
- package/ts/gleif/records.ts +104 -0
- package/ts/gleif/stream.zip.ts +43 -0
- package/ts/handelsregister/data.codelists.ts +11 -9
- package/ts/handelsregister/interfaces.ts +5 -1
- package/ts/handelsregister/parse.structuredcontent.ts +5 -3
- package/ts/plugins.ts +4 -0
|
@@ -83,7 +83,7 @@ const readLegalForm = (organisationsArg) => {
|
|
|
83
83
|
const code = codeAt(organisation, 'angabenZurRechtsform', 'rechtsform');
|
|
84
84
|
if (code) {
|
|
85
85
|
const label = legalFormLabels[code];
|
|
86
|
-
return label ? { code, ...label } : { code };
|
|
86
|
+
return label ? { code, ...(label.short ? { short: label.short } : {}), long: label.long } : { code };
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
return undefined;
|
|
@@ -274,8 +274,11 @@ export const parseStructuredContent = (xmlArg) => {
|
|
|
274
274
|
representatives.push(representative);
|
|
275
275
|
}
|
|
276
276
|
const holders = entityRole.participant.kind === 'person' ? [...organisations, entityRole.participant.element] : organisations;
|
|
277
|
+
const legalForm = readLegalForm(organisations);
|
|
277
278
|
const content = {
|
|
278
|
-
|
|
279
|
+
// XJustiz also represents natural-person businesses as organisations. Unknown/missing forms
|
|
280
|
+
// retain the structural rule: an organisation holder means organisation, otherwise person.
|
|
281
|
+
entityKind: legalForm && legalFormLabels[legalForm.code]?.naturalPerson ? 'person' : organisations.length > 0 ? 'organisation' : 'person',
|
|
279
282
|
name,
|
|
280
283
|
register: readRegister(root, organisations),
|
|
281
284
|
representationStated: entitled.length > 0,
|
|
@@ -283,7 +286,6 @@ export const parseStructuredContent = (xmlArg) => {
|
|
|
283
286
|
binding: false,
|
|
284
287
|
notice: structuredContentNotice,
|
|
285
288
|
};
|
|
286
|
-
const legalForm = readLegalForm(organisations);
|
|
287
289
|
const seat = readSeat(organisations);
|
|
288
290
|
const address = readAddress(holders);
|
|
289
291
|
const status = readStatus(baseData);
|
|
@@ -303,4 +305,4 @@ export const parseStructuredContent = (xmlArg) => {
|
|
|
303
305
|
content.producedAt = producedAt;
|
|
304
306
|
return content;
|
|
305
307
|
};
|
|
306
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2Uuc3RydWN0dXJlZGNvbnRlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9oYW5kZWxzcmVnaXN0ZXIvcGFyc2Uuc3RydWN0dXJlZGNvbnRlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDekUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFXckcsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG1CQUFtQixFQUFFLDBCQUEwQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFJeEcsTUFBTSxnQkFBZ0IsR0FBRyx1QkFBdUIsQ0FBQztBQUNqRCxNQUFNLGVBQWUsR0FBRyx1QkFBdUIsQ0FBQztBQUNoRCwyRkFBMkY7QUFDM0YsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztBQUU1QyxNQUFNLE9BQU8sR0FBRyxDQUFDLFVBQWtCLEVBQUUsUUFBa0IsRUFBd0IsRUFBRSxDQUMvRSxJQUFJLG9CQUFvQixDQUFDLDRCQUE0QixFQUFFLFVBQVUsRUFBRTtJQUNqRSxJQUFJLEVBQUUsb0JBQW9CO0lBQzFCLEdBQUcsQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDO0NBQ3ZELENBQUMsQ0FBQztBQUVMLE1BQU0sYUFBYSxHQUFHLENBQUMsVUFBdUIsRUFBRSxPQUFlLEVBQWlCLEVBQUUsQ0FDaEYsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxD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
|
|
308
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2Uuc3RydWN0dXJlZGNvbnRlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9oYW5kZWxzcmVnaXN0ZXIvcGFyc2Uuc3RydWN0dXJlZGNvbnRlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDekUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFXckcsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG1CQUFtQixFQUFFLDBCQUEwQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFJeEcsTUFBTSxnQkFBZ0IsR0FBRyx1QkFBdUIsQ0FBQztBQUNqRCxNQUFNLGVBQWUsR0FBRyx1QkFBdUIsQ0FBQztBQUNoRCwyRkFBMkY7QUFDM0YsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztBQUU1QyxNQUFNLE9BQU8sR0FBRyxDQUFDLFVBQWtCLEVBQUUsUUFBa0IsRUFBd0IsRUFBRSxDQUMvRSxJQUFJLG9CQUFvQixDQUFDLDRCQUE0QixFQUFFLFVBQVUsRUFBRTtJQUNqRSxJQUFJLEVBQUUsb0JBQW9CO0lBQzFCLEdBQUcsQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDO0NBQ3ZELENBQUMsQ0FBQztBQUVMLE1BQU0sYUFBYSxHQUFHLENBQUMsVUFBdUIsRUFBRSxPQUFlLEVBQWlCLEVBQUUsQ0FDaEYsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxD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
|
package/dist_ts/plugins.d.ts
CHANGED
|
@@ -5,3 +5,5 @@ import * as smartpromise from '@push.rocks/smartpromise';
|
|
|
5
5
|
import * as smartrequest from '@push.rocks/smartrequest';
|
|
6
6
|
declare const getErrorMessage: (error: unknown) => string;
|
|
7
7
|
export { getErrorMessage, smartpath, smartpromise, smartrequest, };
|
|
8
|
+
import * as fflate from 'fflate';
|
|
9
|
+
export { fflate };
|
package/dist_ts/plugins.js
CHANGED
|
@@ -12,4 +12,7 @@ const getErrorMessage = (error) => {
|
|
|
12
12
|
return String(error);
|
|
13
13
|
};
|
|
14
14
|
export { getErrorMessage, smartpath, smartpromise, smartrequest, };
|
|
15
|
-
|
|
15
|
+
// third-party scope
|
|
16
|
+
import * as fflate from 'fflate';
|
|
17
|
+
export { fflate };
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBRWxDLE9BQU8sRUFDTCxJQUFJLEdBQ0wsQ0FBQTtBQUVELG9CQUFvQjtBQUNwQixPQUFPLEtBQUssU0FBUyxNQUFNLHVCQUF1QixDQUFDO0FBQ25ELE9BQU8sS0FBSyxZQUFZLE1BQU0sMEJBQTBCLENBQUM7QUFDekQsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUV6RCxNQUFNLGVBQWUsR0FBRyxDQUFDLEtBQWMsRUFBRSxFQUFFO0lBQ3pDLElBQUksS0FBSyxZQUFZLEtBQUssRUFBRSxDQUFDO1FBQzNCLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUN2QixDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDdkIsQ0FBQyxDQUFDO0FBRUYsT0FBTyxFQUNMLGVBQWUsRUFDZixTQUFTLEVBQ1QsWUFBWSxFQUNaLFlBQVksR0FDYixDQUFBO0FBRUQsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQyJ9
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fin.cx/opendata",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.9.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Open business and financial data for TypeScript: register lookups on the German register portal (handelsregister.de) without storage, the statutory public holidays of the German federal states, the base rate of § 247 BGB, the German consumer price index with the arithmetic of index clauses, published financial statements read from their HTML, PDF or ESEF documents, and stock and crypto prices and fundamentals from several providers.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
"types": "./dist_ts/financialstatements/index.d.ts",
|
|
35
35
|
"import": "./dist_ts/financialstatements/index.js"
|
|
36
36
|
},
|
|
37
|
+
"./gleif": {
|
|
38
|
+
"types": "./dist_ts/gleif/index.d.ts",
|
|
39
|
+
"import": "./dist_ts/gleif/index.js"
|
|
40
|
+
},
|
|
37
41
|
"./package.json": "./package.json"
|
|
38
42
|
},
|
|
39
43
|
"type": "module",
|
|
@@ -42,7 +46,7 @@
|
|
|
42
46
|
"devDependencies": {
|
|
43
47
|
"@git.zone/tsbuild": "^6.0.2",
|
|
44
48
|
"@git.zone/tsrun": "^3.0.3",
|
|
45
|
-
"@git.zone/tstest": "^7.2.
|
|
49
|
+
"@git.zone/tstest": "^7.2.1",
|
|
46
50
|
"@push.rocks/qenv": "^6.1.3",
|
|
47
51
|
"@types/node": "26.6.4"
|
|
48
52
|
},
|
|
@@ -52,6 +56,7 @@
|
|
|
52
56
|
"@push.rocks/smartpromise": "^4.3.0",
|
|
53
57
|
"@push.rocks/smartrequest": "^5.0.1",
|
|
54
58
|
"@push.rocks/smartxml": "^2.1.0",
|
|
59
|
+
"fflate": "0.8.3",
|
|
55
60
|
"parse5": "^8.0.1",
|
|
56
61
|
"pdfjs-dist": "^6.3.289"
|
|
57
62
|
},
|
package/readme.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`@fin.cx/opendata` is a TypeScript toolbox for open business and market data: stock and crypto prices, SEC fundamentals, lookups in the German registers through the register portal of the federal states, the statutory public holidays of the German federal states, the base rate of § 247 BGB, the German consumer price index for index clauses, and the figures of published financial statements. It is built for programmers who want scriptable APIs and real workflows instead of a thin wrapper around one remote endpoint.
|
|
4
4
|
|
|
5
|
-
It gives you
|
|
5
|
+
It gives you nine practical lanes in one package:
|
|
6
6
|
|
|
7
7
|
- `StockPriceService` for stock and crypto prices with caching, retries, failover, historical ranges, and intraday support
|
|
8
8
|
- `FundamentalsService` and `StockDataService` for SEC fundamentals and combined price + fundamentals payloads
|
|
@@ -12,6 +12,7 @@ It gives you eight practical lanes in one package:
|
|
|
12
12
|
- VAT ID confirmation, from `@fin.cx/opendata/vatid`, over the BZSt's eVatR REST API (the confirmation of § 18e UStG, simple or qualified) and the European Commission's VIES REST API, without any storage
|
|
13
13
|
- the consumer price index, from `@fin.cx/opendata/cpi`, for the Verbraucherpreisindex für Deutschland of the Statistisches Bundesamt as the Deutsche Bundesbank republishes it, with the arithmetic of index clauses (Wertsicherungsklauseln, § 557b BGB), without any storage
|
|
14
14
|
- published financial statements, from `@fin.cx/opendata/financialstatements`, for the balance sheet and the income statement under the HGB from the HTML or the PDF the Unternehmensregister shows, and the facts of an ESEF report, read from a document the caller obtained, without any request or storage
|
|
15
|
+
- GLEIF Level 1 data, from `@fin.cx/opendata/gleif`, for streamed Golden Copy full/delta imports, single-LEI lookup, and German registration-authority codes mapped to XJustiz register courts
|
|
15
16
|
|
|
16
17
|
## Issue Reporting and Security
|
|
17
18
|
|
|
@@ -387,6 +388,78 @@ console.log({
|
|
|
387
388
|
});
|
|
388
389
|
```
|
|
389
390
|
|
|
391
|
+
### GLEIF Level 1 data (`@fin.cx/opendata/gleif`)
|
|
392
|
+
|
|
393
|
+
`GleifClient` discovers the current GLEIF Golden Copy publication, streams its LEI-CDF 3.1 ZIP/CSV records, or looks up one LEI through GLEIF's public JSON:API. It keeps no files or data. `fetch` is injectable; every request has a signal and a time limit, with no retries. Breaking a `for await` loop cancels the download. Only publication metadata and single-record JSON responses are collected (at most 2 MiB); the ZIP and CSV are read incrementally with backpressure and a default 1,048,576-character limit per CSV row. A completed stream checks the compressed byte and unfiltered record counts against the publication descriptor.
|
|
394
|
+
|
|
395
|
+
```ts
|
|
396
|
+
import {
|
|
397
|
+
GleifClient,
|
|
398
|
+
courtFromRegistrationAuthority,
|
|
399
|
+
registrationAuthorityFromCourt,
|
|
400
|
+
parseRegistrationAuthorityEntityId,
|
|
401
|
+
registerReferenceFromRegistrationAuthority,
|
|
402
|
+
} from '@fin.cx/opendata/gleif';
|
|
403
|
+
|
|
404
|
+
const gleif = new GleifClient({ userAgent: 'Example Books (+https://example.com/contact)' });
|
|
405
|
+
const publish = await gleif.getLatestPublish();
|
|
406
|
+
// Save this descriptor in your own store to identify the import's publication.
|
|
407
|
+
for await (const record of gleif.readGoldenCopy(publish.fullFile, { country: 'DE' })) {
|
|
408
|
+
console.log(record.lei, record.legalName.name, record.registrationAuthority);
|
|
409
|
+
}
|
|
410
|
+
// Or discover and stream in one call. Other kinds: GoldenCopy, LastDay, LastWeek, LastMonth.
|
|
411
|
+
for await (const record of gleif.streamRecords({ kind: 'IntraDay', jurisdiction: 'DE' })) {
|
|
412
|
+
console.log(record.lei, record.lastUpdateDate);
|
|
413
|
+
}
|
|
414
|
+
const record = await gleif.lookup('529900W18LQJJN6SJ336');
|
|
415
|
+
const court = courtFromRegistrationAuthority('RA000222'); // { code: 'H1101', name: 'Bremen' }
|
|
416
|
+
const raCode = registrationAuthorityFromCourt('H1101'); // RA000222
|
|
417
|
+
const number = parseRegistrationAuthorityEntityId('HRB 35230HB'); // { type: 'HRB', number: '35230 HB' }
|
|
418
|
+
const reference = registerReferenceFromRegistrationAuthority('RA000222', 'HRB 35230HB');
|
|
419
|
+
// IRegisterReference: { court, type: 'HRB', number: '35230 HB' }
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
The exact yielded/lookup contract is `IGleifRecord`:
|
|
423
|
+
|
|
424
|
+
```ts
|
|
425
|
+
interface IGleifRecord {
|
|
426
|
+
lei: string;
|
|
427
|
+
legalName: IGleifName;
|
|
428
|
+
otherNames: IGleifName[];
|
|
429
|
+
transliteratedOtherNames: IGleifName[];
|
|
430
|
+
legalForm?: { elfCode?: string; other?: string };
|
|
431
|
+
legalAddress: IGleifAddress;
|
|
432
|
+
headquartersAddress: IGleifAddress;
|
|
433
|
+
jurisdiction?: string;
|
|
434
|
+
entityStatus: string;
|
|
435
|
+
entityCategory?: string;
|
|
436
|
+
registrationAuthority?: { id?: string; otherId?: string; entityId?: string };
|
|
437
|
+
registrationStatus: string;
|
|
438
|
+
initialRegistrationDate: string;
|
|
439
|
+
lastUpdateDate: string;
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
`IGleifName` carries `name`, optional `language`, and optional published other-name `type`. `IGleifAddress` carries `addressLines`, `city`, `country`, and optional `language`, `region`, `postalCode`, `addressNumber`, `addressNumberWithinBuilding` and `mailRouting`. Empty optional source fields are absent, other-name lists are arrays, and dates remain the published ISO 8601 strings, including fractional seconds. ELF codes remain codes; no legal-form designation is invented. Status and category strings remain as published. `country` compares the legal address's ISO country, `jurisdiction` compares the exact legal jurisdiction; when both are supplied, both must match. Filtering happens after parsing each record, before yielding it.
|
|
444
|
+
|
|
445
|
+
The full file and delta descriptors are `IGleifGoldenCopyFile` (`url`, `format: 'csv'`, `cdfVersion: 'LEI_3.1'`, `kind`, `recordCount`, `size`). `getLatestPublish()` returns `IGleifPublish` (`publishDate`, `fullFile`, `deltaFiles`). Options include `fetch`, `goldenCopyBaseUrl`, `restBaseUrl`, `userAgent` and `timeoutMs` (default 30 minutes per request, including consumer time). Read calls accept `country`, `jurisdiction`, `signal` and `maxRowChars`. `lookup()` and discovery accept `signal`. `parseGleifRestRecord(json)` maps an already obtained JSON:API response without fetching. `GleifError` exposes `code` and, for HTTP errors, `httpStatus`.
|
|
446
|
+
|
|
447
|
+
GLEIF publishes full files three times daily and deltas for the preceding 8 hours (`IntraDay`), 24 hours (`LastDay`), 7 days (`LastWeek`) and 31 days (`LastMonth`). Level 1 deltas contain the current version of new or changed LEI records. They contain no per-record change kind: this module does not infer insert/update/delete events. The deletion flag described in the manual concerns Level 2 relationships, which this module does not read. A delta overlaps earlier windows; callers own their import checkpoint and idempotent persistence. Discovery selects the CSV format from GLEIF's descriptors rather than constructing file download URLs. Unsupported CDF versions or missing columns fail explicitly.
|
|
448
|
+
|
|
449
|
+
The generated German RA ↔ XJustiz crosswalk uses the official **GLEIF Registration Authorities List v1.9, 2026-09-30**. Its 177 German authorities contain 147 mapped courts and 30 non-court authorities with unmapped reasons. Of opendata's 150 court codes, 147 are mapped; `Y1303` (Arnstadt Zweigstelle Ilmenau), `Y1208` (Pößneck Zweigstelle Bad Lobenstein) and `R1105` (Langenfeld) have no distinct RA in that version. No parent/successor mapping is inferred. `germanRegistrationAuthorities`, `gleifUnmappedCourts` and `gleifRegistrationAuthoritiesSource` expose the list and its provenance. Unknown/unmapped codes and unparseable register identifiers return `undefined`. Register identifiers must state their type (HRA, HRB, GnR, PR, VR or GsR); leading zeros and location suffixes are preserved.
|
|
450
|
+
|
|
451
|
+
Reproduce the code list offline with `tsx scripts/generate.gleif-crosswalk.ts`, or verify it with `--check`. `--refresh` fetches only the small official RA CSV and updates the committed German subset and generated list. For a new RA-list version, update the version/date constants in the generator, review new names and mapping ambiguity, then refresh and run the exhaustive tests. The generator never contacts a register portal.
|
|
452
|
+
|
|
453
|
+
Official sources, read on 2026-10-13:
|
|
454
|
+
|
|
455
|
+
- [Golden Copy and Delta Files overview](https://www.gleif.org/en/lei-data/gleif-golden-copy) and [specification/user manual v2.2](https://www.gleif.org/lei-data/gleif-golden-copy/2022-02-23_gleif-golden-copy-and-delta-files_v2.2-final.pdf), especially §§1.5–1.6 and 2.2: ZIP compression, formats, delta windows and API discovery at `https://goldencopy.gleif.org/api/v2/golden-copies/publishes/latest`. `leidata-preview.gleif.org` is the documented legacy domain for the same API.
|
|
456
|
+
- [LEI-CDF 3.1 format](https://www.gleif.org/en/lei-data/access-and-use-lei-data/level-1-data-lei-cdf-3-1-format) and [official XSD](https://www.gleif.org/lei-data/access-and-use-lei-data/level-1-data-lei-cdf-3-1-format/2021-03-04_lei-cdf-v3-1.xsd). CSV uses the published dotted columns, including `Entity.LegalName`, numbered other/transliterated names, `Entity.RegistrationAuthority.RegistrationAuthorityID` / `RegistrationAuthorityEntityID`, `Entity.LegalForm.EntityLegalFormCode`, addresses and registration dates. The parser reads the header rather than assuming column positions; fixtures preserve all 338 published columns.
|
|
457
|
+
- [GLEIF REST API documentation](https://api.gleif.org/docs): `GET https://api.gleif.org/api/v1/lei-records/{lei}`, JSON:API `data.attributes.entity` and `data.attributes.registration`, including `registeredAt.id` and `registeredAs`.
|
|
458
|
+
- [RA-list publication page](https://www.gleif.org/en/about-lei/code-lists/gleif-registration-authorities-list) and [v1.9 CSV](https://www.gleif.org/lei-data/code-lists/gleif-registration-authorities-list/2026-09-30_ra-list-v1.9.csv).
|
|
459
|
+
- [GLEIF LEI Data Terms of Use](https://www.gleif.org/en/meta/lei-data-terms-of-use): data available through its access service are provided under [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/).
|
|
460
|
+
|
|
461
|
+
Fixtures are 100 records each from the 2026-10-13 00:00 full and intra-day CSVs, publication descriptors, and the REST documentation's single-record response. Tests make no GLEIF requests; ZIPs are created from these small CSV samples in memory. Provenance is in `test/fixtures/gleif/readme.md`. Full-population imports and GLEIF request-rate limits have not been verified; only bounded live samples, documented shapes and offline fixtures were checked.
|
|
462
|
+
|
|
390
463
|
### Register Lookups (Handelsregister)
|
|
391
464
|
|
|
392
465
|
`HandelsregisterClient` speaks to the register portal of the federal states over plain HTTP, the way a browser would: it opens the search form, sends the search, reads the result list and, for one entry, downloads the structured register content (SI, an XJustiz XML file) and parses it.
|
|
@@ -471,7 +544,9 @@ A refusal of `SlidingWindowGate` is a `HandelsregisterError` with the code `rate
|
|
|
471
544
|
#### What a result holds
|
|
472
545
|
|
|
473
546
|
- `IRegisterMatch`, one row of the result list: `reference` (court with code and name, register type, number with suffix), `formerCourt`, `federalState`, `name`, `seat`, `sheetStatus` (`current`, `closed` or `other`, with the portal's word in `sheetStatusText`), `formerNames` and the `documents` the portal offers.
|
|
474
|
-
- `IRegisterStructuredContent`, the parsed SI: `name`, `legalForm` (XUnternehmen code with short and long designation), `seat`, the business `address`, `register`, `status` (XJustiz status of the legal entity), `lastEntryOn`, `representatives` and `representationStated`, `producedAt`, `binding: false` and the portal's `notice`.
|
|
547
|
+
- `IRegisterStructuredContent`, the parsed SI: `entityKind`, `name`, `legalForm` (XUnternehmen code with short and long designation), `seat`, the business `address`, `register`, `status` (XJustiz status of the legal entity), `lastEntryOn`, `representatives` and `representationStated`, `producedAt`, `binding: false` and the portal's `notice`.
|
|
548
|
+
- `entityKind` classifies the registered entity, not its representatives or the XML element's name. Natural-person business forms return `'person'` even when XJustiz uses an `<organisation>` element: commercial sole traders (`410000`), registered sole traders (`411000`, `411100` in Germany, `411200` abroad), farmers/foresters (`422000`), other economic activity of a natural person (`428100`), foreign economic activity of a natural person (`490000`) and foreign sole traders under EU (`491000`) or non-EU law (`492000`). These entries belong to XUnternehmen's category "Wirtschaftliche Tätigkeit einer natürlichen Person" (`400000`); the internal `naturalPerson` marker stays in the code table and never appears in the returned `legalForm`. Partnerships such as OHG and KG remain `'organisation'`, including those with natural-person partners.
|
|
549
|
+
- Otherwise, including unknown, empty or missing legal forms, `entityKind` retains the structural rule: a `basisdatenRegister/rechtstraeger` holder or an entity participant described as `<organisation>` means `'organisation'`; without either it is `'person'`. This fallback does not confirm that an unknown form is an organisation, so consumers must account for it when applying privacy rules. Search results and the GLEIF RA ↔ court crosswalk do not provide `entityKind`; read SI for this classification.
|
|
475
550
|
- A closed sheet ("Geschlossenes Registerblatt") means the entry was deleted, or its sheet was closed when the entity moved to another court, changed its legal form or merged. The result list does not say which, and the portal offers no structured content for it.
|
|
476
551
|
- The structured content states no date for the status itself; `lastEntryOn` is the date of the latest entry on the sheet.
|
|
477
552
|
- Of people the parser reads the name and the function only. Birth dates, places of residence and private addresses never leave it.
|
|
@@ -690,7 +765,7 @@ Four holidays apply only in part of a state:
|
|
|
690
765
|
|
|
691
766
|
The package ships no market or register data. Prices and fundamentals come at run time from the providers you register (Marketstack, CoinGecko, SEC EDGAR), and register entries come at run time from the register portal of the federal states (handelsregister.de), one lookup at a time. Financial statements come from the caller: `@fin.cx/opendata/financialstatements` reads the documents it is given and fetches none.
|
|
692
767
|
|
|
693
|
-
The package carries two kinds of data: the holiday rules of `@fin.cx/opendata/holidays` (`ts/holidays/data.holidays.ts`), described at the end of this section, and the code tables that `@fin.cx/opendata/handelsregister` uses to decode the structured register content (`ts/handelsregister/data.codelists.ts`). The code tables are official code lists, published on XRepository (https://www.xrepository.de), and were taken on 2026-09-23:
|
|
768
|
+
The GLEIF module also carries the generated RA ↔ court crosswalk described above. The package carries two other kinds of data: the holiday rules of `@fin.cx/opendata/holidays` (`ts/holidays/data.holidays.ts`), described at the end of this section, and the code tables that `@fin.cx/opendata/handelsregister` uses to decode the structured register content (`ts/handelsregister/data.codelists.ts`). The code tables are official code lists, published on XRepository (https://www.xrepository.de), and were taken on 2026-09-23:
|
|
694
769
|
|
|
695
770
|
| Table | Code list | Issued by |
|
|
696
771
|
| --- | --- | --- |
|
|
@@ -767,7 +842,7 @@ The reader of `@fin.cx/opendata/financialstatements` follows the outlines of the
|
|
|
767
842
|
pnpm test
|
|
768
843
|
```
|
|
769
844
|
|
|
770
|
-
Some market data tests hit live remote services, so they may depend on network access or optional API credentials. The register lookup is tested against minimal hand-written pages and structured content with synthetic values only; the tests never contact the register portal. The VAT ID clients are tested against the answers the two services gave on 2026-09-27 to their documented test values (`test/fixtures/vatid/`); the tests never contact them. The consumer price index client is tested against the answers the Bundesbank's API gave on 2026-10-05 and two answers written by hand from them (`test/fixtures/cpi/`); the tests never contact it. The financial statement reader is tested against HTML statements written by hand in the shape of the register's (`test/fixtures/financialstatements/`), PDFs the tests write themselves, and ESEF reports and packages the tests write, all with synthetic values; the tests contact no register.
|
|
845
|
+
GLEIF tests use only small real published fixtures (`test/fixtures/gleif/`) and injected fetches, including cancellation, malformed input, optional names and exhaustive crosswalk coverage. Some market data tests hit live remote services, so they may depend on network access or optional API credentials. The register lookup is tested against minimal hand-written pages and structured content with synthetic values only; the tests never contact the register portal. The VAT ID clients are tested against the answers the two services gave on 2026-09-27 to their documented test values (`test/fixtures/vatid/`); the tests never contact them. The consumer price index client is tested against the answers the Bundesbank's API gave on 2026-10-05 and two answers written by hand from them (`test/fixtures/cpi/`); the tests never contact it. The financial statement reader is tested against HTML statements written by hand in the shape of the register's (`test/fixtures/financialstatements/`), PDFs the tests write themselves, and ESEF reports and packages the tests write, all with synthetic values; the tests contact no register.
|
|
771
846
|
|
|
772
847
|
## License and Legal Information
|
|
773
848
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@fin.cx/opendata',
|
|
6
|
-
version: '4.
|
|
6
|
+
version: '4.9.1',
|
|
7
7
|
description: 'Open business and financial data for TypeScript: register lookups on the German register portal (handelsregister.de) without storage, the statutory public holidays of the German federal states, the base rate of § 247 BGB, the German consumer price index with the arithmetic of index clauses, published financial statements read from their HTML, PDF or ESEF documents, and stock and crypto prices and fundamentals from several providers.'
|
|
8
8
|
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { GleifError } from './classes.gleiferror.js';
|
|
2
|
+
import { parseCsvRows } from './csv.js';
|
|
3
|
+
import { csvRecordMapper, parseGleifRestRecord } from './records.js';
|
|
4
|
+
import { unzipCsv } from './stream.zip.js';
|
|
5
|
+
import type { IGleifClientOptions, IGleifGoldenCopyFile, IGleifPublish, IGleifReadOptions, IGleifRecord, IGleifStreamOptions, TGleifDelta, TGleifFileKind } from './interfaces.js';
|
|
6
|
+
|
|
7
|
+
export const gleifGoldenCopyBaseUrl = 'https://goldencopy.gleif.org/api/v2';
|
|
8
|
+
export const gleifRestBaseUrl = 'https://api.gleif.org/api/v1';
|
|
9
|
+
export const gleifDeltaKinds: readonly TGleifDelta[] = ['IntraDay', 'LastDay', 'LastWeek', 'LastMonth'];
|
|
10
|
+
|
|
11
|
+
const bad = (labelArg: string): never => { throw new GleifError('unexpected_answer', `Invalid GLEIF publication ${labelArg}.`); };
|
|
12
|
+
const object = (valueArg: unknown): Record<string, unknown> =>
|
|
13
|
+
valueArg && typeof valueArg === 'object' && !Array.isArray(valueArg) ? valueArg as Record<string, unknown> : bad('object');
|
|
14
|
+
const url = (valueArg: unknown): string => {
|
|
15
|
+
if (typeof valueArg !== 'string') throw new GleifError('invalid_input', 'Expected an HTTP(S) URL.');
|
|
16
|
+
let parsed: URL;
|
|
17
|
+
try { parsed = new URL(valueArg); } catch { throw new GleifError('invalid_input', 'Expected an HTTP(S) URL.'); }
|
|
18
|
+
if (!['http:', 'https:'].includes(parsed.protocol) || parsed.username || parsed.password) throw new GleifError('invalid_input', 'Expected an HTTP(S) URL without credentials.');
|
|
19
|
+
return valueArg;
|
|
20
|
+
};
|
|
21
|
+
const descriptor = (valueArg: unknown, kindArg: TGleifFileKind): IGleifGoldenCopyFile => {
|
|
22
|
+
const value = object(valueArg);
|
|
23
|
+
if (value.type !== 'lei2' || value.format !== 'csv' || value.cdf_version !== 'LEI_3.1' || value.delta_type !== kindArg) bad('file type, format, CDF version or delta type');
|
|
24
|
+
if (!Number.isSafeInteger(value.record_count) || Number(value.record_count) < 0 || !Number.isSafeInteger(value.size) || Number(value.size) < 1) bad('record count or size');
|
|
25
|
+
return { url: url(value.url), kind: kindArg, format: 'csv', cdfVersion: 'LEI_3.1', recordCount: value.record_count as number, size: value.size as number };
|
|
26
|
+
};
|
|
27
|
+
const checkFilters = (optionsArg: IGleifReadOptions): void => {
|
|
28
|
+
if (optionsArg.country !== undefined && !/^[A-Z]{2}$/.test(optionsArg.country)) throw new GleifError('invalid_input', 'country must be an ISO alpha-2 code, e.g. DE.');
|
|
29
|
+
if (optionsArg.jurisdiction !== undefined && !/^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/.test(optionsArg.jurisdiction)) throw new GleifError('invalid_input', 'jurisdiction must be a country or subdivision code.');
|
|
30
|
+
if (optionsArg.maxRowChars !== undefined && (!Number.isSafeInteger(optionsArg.maxRowChars) || optionsArg.maxRowChars < 1)) throw new GleifError('invalid_input', 'maxRowChars must be a positive safe integer.');
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const abortable = async <TArg>(promiseArg: Promise<TArg>, signalArg: AbortSignal): Promise<TArg> => {
|
|
34
|
+
signalArg.throwIfAborted();
|
|
35
|
+
let abort: (() => void) | undefined;
|
|
36
|
+
const aborted = new Promise<never>((_, rejectArg) => {
|
|
37
|
+
abort = () => rejectArg(signalArg.reason);
|
|
38
|
+
signalArg.addEventListener('abort', abort, { once: true });
|
|
39
|
+
});
|
|
40
|
+
try { return await Promise.race([promiseArg, aborted]); }
|
|
41
|
+
finally { if (abort) signalArg.removeEventListener('abort', abort); }
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/** Official Golden Copy ZIP/CSV streams and JSON:API lookup; no files, cache or retries. */
|
|
45
|
+
export class GleifClient {
|
|
46
|
+
private readonly goldenCopyBaseUrl: string;
|
|
47
|
+
private readonly restBaseUrl: string;
|
|
48
|
+
private readonly timeoutMs: number;
|
|
49
|
+
|
|
50
|
+
constructor(private readonly options: IGleifClientOptions = {}) {
|
|
51
|
+
this.goldenCopyBaseUrl = url(options.goldenCopyBaseUrl ?? gleifGoldenCopyBaseUrl).replace(/\/$/, '');
|
|
52
|
+
this.restBaseUrl = url(options.restBaseUrl ?? gleifRestBaseUrl).replace(/\/$/, '');
|
|
53
|
+
this.timeoutMs = options.timeoutMs ?? 30 * 60 * 1000;
|
|
54
|
+
if (!Number.isSafeInteger(this.timeoutMs) || this.timeoutMs < 1 || this.timeoutMs > 2147483647) throw new GleifError('invalid_input', 'timeoutMs must be a positive integer within the timer range.');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Discovers the current full file and all four delta windows from the official v2 API. */
|
|
58
|
+
public async getLatestPublish(optionsArg: { signal?: AbortSignal } = {}): Promise<IGleifPublish> {
|
|
59
|
+
const response = object(await this.getJson(`${this.goldenCopyBaseUrl}/golden-copies/publishes/latest`, optionsArg.signal));
|
|
60
|
+
const publish = object(response.data);
|
|
61
|
+
if (typeof publish.publish_date !== 'string' || !/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(publish.publish_date)) bad('date');
|
|
62
|
+
const level1 = object(publish.lei2);
|
|
63
|
+
const deltas = object(level1.delta_files);
|
|
64
|
+
const deltaFiles = Object.fromEntries(gleifDeltaKinds.map((kindArg) => [kindArg, descriptor(object(deltas[kindArg]).csv, kindArg)])) as Record<TGleifDelta, IGleifGoldenCopyFile>;
|
|
65
|
+
return { publishDate: publish.publish_date as string, fullFile: descriptor(object(level1.full_file).csv, 'GoldenCopy'), deltaFiles };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Discovers once, then streams the selected full file or delta. */
|
|
69
|
+
public async *streamRecords(optionsArg: IGleifStreamOptions = {}): AsyncGenerator<IGleifRecord> {
|
|
70
|
+
checkFilters(optionsArg);
|
|
71
|
+
const kind = optionsArg.kind ?? 'GoldenCopy';
|
|
72
|
+
if (kind !== 'GoldenCopy' && !gleifDeltaKinds.includes(kind)) throw new GleifError('invalid_input', 'Unknown Golden Copy file kind.');
|
|
73
|
+
const publish = await this.getLatestPublish(optionsArg);
|
|
74
|
+
yield* this.readGoldenCopy(kind === 'GoldenCopy' ? publish.fullFile : publish.deltaFiles[kind], optionsArg);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Streams a discovered descriptor. Breaking iteration cancels the response immediately. */
|
|
78
|
+
public async *readGoldenCopy(fileArg: IGleifGoldenCopyFile, optionsArg: IGleifReadOptions = {}): AsyncGenerator<IGleifRecord> {
|
|
79
|
+
checkFilters(optionsArg);
|
|
80
|
+
if (fileArg.format !== 'csv' || fileArg.cdfVersion !== 'LEI_3.1' || !['GoldenCopy', ...gleifDeltaKinds].includes(fileArg.kind) || !Number.isSafeInteger(fileArg.size) || fileArg.size < 1 || !Number.isSafeInteger(fileArg.recordCount) || fileArg.recordCount < 0) {
|
|
81
|
+
throw new GleifError('invalid_input', 'Expected a discovered LEI-CDF 3.1 ZIP/CSV descriptor.');
|
|
82
|
+
}
|
|
83
|
+
const uri = url(fileArg.url);
|
|
84
|
+
let compressedBytes = 0;
|
|
85
|
+
const response = this.requestBytes(uri, optionsArg.signal, 'application/zip');
|
|
86
|
+
async function* counted(): AsyncGenerator<Uint8Array> {
|
|
87
|
+
for await (const chunk of response) { compressedBytes += chunk.length; yield chunk; }
|
|
88
|
+
}
|
|
89
|
+
let mapper: ((rowArg: string[]) => IGleifRecord) | undefined;
|
|
90
|
+
let records = 0;
|
|
91
|
+
for await (const row of parseCsvRows(unzipCsv(counted()), optionsArg.maxRowChars)) {
|
|
92
|
+
if (optionsArg.signal?.aborted) throw new GleifError('aborted', 'GLEIF iteration was aborted.');
|
|
93
|
+
if (!mapper) { mapper = csvRecordMapper(row); continue; }
|
|
94
|
+
const record = mapper(row);
|
|
95
|
+
records++;
|
|
96
|
+
if ((!optionsArg.country || record.legalAddress.country === optionsArg.country) && (!optionsArg.jurisdiction || record.jurisdiction === optionsArg.jurisdiction)) yield record;
|
|
97
|
+
}
|
|
98
|
+
if (!mapper) throw new GleifError('invalid_csv', 'Golden Copy CSV has no header.');
|
|
99
|
+
if (compressedBytes !== fileArg.size || records !== fileArg.recordCount) throw new GleifError('unexpected_answer', `Golden Copy totals differ from its descriptor: ${compressedBytes} bytes, ${records} records.`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** One LEI using the documented public JSON:API resource, mapped to the same record type. */
|
|
103
|
+
public async lookup(leiArg: string, optionsArg: { signal?: AbortSignal } = {}): Promise<IGleifRecord> {
|
|
104
|
+
if (!/^[A-Z0-9]{18}\d{2}$/.test(leiArg)) throw new GleifError('invalid_input', 'Expected a 20-character LEI.');
|
|
105
|
+
const record = parseGleifRestRecord(await this.getJson(`${this.restBaseUrl}/lei-records/${leiArg}`, optionsArg.signal));
|
|
106
|
+
if (record.lei !== leiArg) throw new GleifError('unexpected_answer', 'GLEIF answered with a different LEI.');
|
|
107
|
+
return record;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private async getJson(uriArg: string, signalArg?: AbortSignal): Promise<unknown> {
|
|
111
|
+
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
112
|
+
let text = '';
|
|
113
|
+
let bytes = 0;
|
|
114
|
+
try {
|
|
115
|
+
for await (const chunk of this.requestBytes(uriArg, signalArg, 'application/vnd.api+json, application/json')) {
|
|
116
|
+
bytes += chunk.length;
|
|
117
|
+
if (bytes > 2 * 1024 * 1024) throw new GleifError('record_limit', 'GLEIF metadata/lookup exceeds 2 MiB.');
|
|
118
|
+
text += decoder.decode(chunk, { stream: true });
|
|
119
|
+
}
|
|
120
|
+
return JSON.parse(text + decoder.decode());
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (error instanceof GleifError) throw error;
|
|
123
|
+
throw new GleifError('unexpected_answer', 'GLEIF did not answer with valid JSON.', undefined, { cause: error });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private async *requestBytes(uriArg: string, signalArg: AbortSignal | undefined, acceptArg: string): AsyncGenerator<Uint8Array> {
|
|
128
|
+
const controller = new AbortController();
|
|
129
|
+
const signal = signalArg ? AbortSignal.any([signalArg, controller.signal]) : controller.signal;
|
|
130
|
+
const timer = setTimeout(() => controller.abort(new Error('GLEIF request timed out.')), this.timeoutMs);
|
|
131
|
+
let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;
|
|
132
|
+
let ended = false;
|
|
133
|
+
let failed = false;
|
|
134
|
+
try {
|
|
135
|
+
signal.throwIfAborted();
|
|
136
|
+
const headers: Record<string, string> = { Accept: acceptArg };
|
|
137
|
+
if (this.options.userAgent) headers['User-Agent'] = this.options.userAgent;
|
|
138
|
+
const response = await abortable((this.options.fetch ?? globalThis.fetch)(uriArg, { headers, signal }), signal);
|
|
139
|
+
if (response.status !== 200) {
|
|
140
|
+
await response.body?.cancel();
|
|
141
|
+
throw new GleifError(response.status === 404 ? 'not_found' : 'http_error', `GLEIF answered HTTP ${response.status}.`, response.status);
|
|
142
|
+
}
|
|
143
|
+
if (!response.body) throw new GleifError('unexpected_answer', 'GLEIF response has no body.');
|
|
144
|
+
reader = response.body.getReader();
|
|
145
|
+
while (true) {
|
|
146
|
+
const chunk = await abortable(reader.read(), signal);
|
|
147
|
+
if (chunk.done) { ended = true; break; }
|
|
148
|
+
signal.throwIfAborted();
|
|
149
|
+
yield chunk.value;
|
|
150
|
+
}
|
|
151
|
+
} catch (error) {
|
|
152
|
+
failed = true;
|
|
153
|
+
if (signal.aborted) throw new GleifError(signalArg?.aborted ? 'aborted' : 'timeout', 'GLEIF request ended before completion.', undefined, { cause: error });
|
|
154
|
+
if (error instanceof GleifError) throw error;
|
|
155
|
+
throw new GleifError('unreachable', 'Could not read the GLEIF response.', undefined, { cause: error });
|
|
156
|
+
} finally {
|
|
157
|
+
clearTimeout(timer);
|
|
158
|
+
try {
|
|
159
|
+
if (reader) {
|
|
160
|
+
try { if (!ended) await reader.cancel(); }
|
|
161
|
+
catch (error) {
|
|
162
|
+
// An already failed/aborted reader rejects cancellation with its existing error.
|
|
163
|
+
// Preserve the primary error; normal loop exit must still report cleanup failures.
|
|
164
|
+
if (!failed && !signal.aborted) throw new GleifError('unreachable', 'Could not cancel the GLEIF response.', undefined, { cause: error });
|
|
165
|
+
} finally { reader.releaseLock(); }
|
|
166
|
+
}
|
|
167
|
+
} finally { controller.abort(); }
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type TGleifErrorCode = 'invalid_input' | 'http_error' | 'not_found' | 'unreachable' | 'timeout' | 'aborted' | 'unexpected_answer' | 'invalid_archive' | 'invalid_csv' | 'record_limit';
|
|
2
|
+
|
|
3
|
+
export class GleifError extends Error {
|
|
4
|
+
constructor(public readonly code: TGleifErrorCode, messageArg: string, public readonly httpStatus?: number, optionsArg?: ErrorOptions) {
|
|
5
|
+
super(messageArg, optionsArg);
|
|
6
|
+
this.name = 'GleifError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { registerCourts } from '../handelsregister/data.codelists.js';
|
|
2
|
+
import { formatRegisterNumber, parseRegisterNumber, toRegisterType } from '../handelsregister/references.js';
|
|
3
|
+
import type { IRegisterCourt, IRegisterReference } from '../handelsregister/interfaces.js';
|
|
4
|
+
import { germanRegistrationAuthorities } from './data.crosswalk.js';
|
|
5
|
+
import type { IGleifRegisterNumber } from './interfaces.js';
|
|
6
|
+
|
|
7
|
+
export const courtFromRegistrationAuthority = (raCodeArg: string): IRegisterCourt | undefined => {
|
|
8
|
+
const courtCode = germanRegistrationAuthorities.find((authorityArg) => authorityArg.raCode === raCodeArg)?.courtCode;
|
|
9
|
+
return courtCode ? registerCourts.find((courtArg) => courtArg.code === courtCode) : undefined;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const registrationAuthorityFromCourt = (courtCodeArg: string): string | undefined =>
|
|
13
|
+
germanRegistrationAuthorities.find((authorityArg) => authorityArg.courtCode === courtCodeArg)?.raCode;
|
|
14
|
+
|
|
15
|
+
/** Anchored identifier only, with canonical type and location suffix; never guesses a register type. */
|
|
16
|
+
export const parseRegistrationAuthorityEntityId = (entityIdArg: string): IGleifRegisterNumber | undefined => {
|
|
17
|
+
if (typeof entityIdArg !== 'string') return undefined;
|
|
18
|
+
const match = /^(HRA|HRB|GnR|PR|VR|GsR)\s*\.?\s*(?:Nr\.?\s*)?(\d{1,9}(?:\s*[A-Za-zÄÖÜäöü]{1,5})?)$/i.exec(entityIdArg.trim());
|
|
19
|
+
if (!match) return undefined;
|
|
20
|
+
const type = toRegisterType(match[1]);
|
|
21
|
+
const number = parseRegisterNumber(match[2]);
|
|
22
|
+
return type && number ? { type, number: formatRegisterNumber(number) } : undefined;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const registerReferenceFromRegistrationAuthority = (raCodeArg: string, entityIdArg: string): IRegisterReference | undefined => {
|
|
26
|
+
const court = courtFromRegistrationAuthority(raCodeArg);
|
|
27
|
+
const number = parseRegistrationAuthorityEntityId(entityIdArg);
|
|
28
|
+
return court && number ? { court, ...number } : undefined;
|
|
29
|
+
};
|
package/ts/gleif/csv.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { GleifError } from './classes.gleiferror.js';
|
|
2
|
+
|
|
3
|
+
/** Strict incremental CSV: quoted commas, doubled quotes, embedded CR/LF and split UTF-8. */
|
|
4
|
+
export async function* parseCsvRows(sourceArg: AsyncIterable<Uint8Array>, maxRowCharsArg = 1024 * 1024): AsyncGenerator<string[]> {
|
|
5
|
+
if (!Number.isSafeInteger(maxRowCharsArg) || maxRowCharsArg < 1) {
|
|
6
|
+
throw new GleifError('invalid_input', 'maxRowChars must be a positive safe integer.');
|
|
7
|
+
}
|
|
8
|
+
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
9
|
+
const parser: { state: 'start' | 'unquoted' | 'quoted' | 'closed' } = { state: 'start' };
|
|
10
|
+
let field = '';
|
|
11
|
+
let row: string[] = [];
|
|
12
|
+
let rowChars = 0;
|
|
13
|
+
let skipLf = false;
|
|
14
|
+
function* read(textArg: string): Generator<string[]> {
|
|
15
|
+
for (const character of textArg) {
|
|
16
|
+
if (skipLf) {
|
|
17
|
+
skipLf = false;
|
|
18
|
+
if (character === '\n') continue;
|
|
19
|
+
}
|
|
20
|
+
if (++rowChars > maxRowCharsArg) throw new GleifError('record_limit', 'CSV row exceeds maxRowChars.');
|
|
21
|
+
if (parser.state === 'quoted') {
|
|
22
|
+
if (character === '"') parser.state = 'closed';
|
|
23
|
+
else field += character;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (parser.state === 'closed' && character === '"') {
|
|
27
|
+
field += '"';
|
|
28
|
+
parser.state = 'quoted';
|
|
29
|
+
} else if (character === ',') {
|
|
30
|
+
row.push(field);
|
|
31
|
+
field = '';
|
|
32
|
+
parser.state = 'start';
|
|
33
|
+
} else if (character === '\n' || character === '\r') {
|
|
34
|
+
row.push(field);
|
|
35
|
+
// Empty physical lines are not records.
|
|
36
|
+
if (row.length !== 1 || row[0] !== '') yield row;
|
|
37
|
+
row = [];
|
|
38
|
+
field = '';
|
|
39
|
+
parser.state = 'start';
|
|
40
|
+
rowChars = 0;
|
|
41
|
+
skipLf = character === '\r';
|
|
42
|
+
} else if (parser.state === 'start' && character === '"') {
|
|
43
|
+
parser.state = 'quoted';
|
|
44
|
+
} else {
|
|
45
|
+
if (parser.state === 'closed' || character === '"') throw new GleifError('invalid_csv', 'Unexpected character outside a quoted CSV field.');
|
|
46
|
+
field += character;
|
|
47
|
+
parser.state = 'unquoted';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
for await (const chunk of sourceArg) yield* read(decoder.decode(chunk, { stream: true }));
|
|
53
|
+
yield* read(decoder.decode());
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (error instanceof TypeError) throw new GleifError('invalid_csv', 'CSV is not valid UTF-8.', undefined, { cause: error });
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
if (parser.state === 'quoted') throw new GleifError('invalid_csv', 'Unterminated quoted CSV field.');
|
|
59
|
+
if (field !== '' || row.length || parser.state !== 'start') yield [...row, field];
|
|
60
|
+
}
|