sec-edgar-api 0.0.3 → 0.0.6
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 +15 -43
- package/build/downloader.d.ts +6 -0
- package/build/downloader.js +9 -0
- package/build/index.d.ts +2 -7
- package/build/index.js +12 -8
- package/build/services/Client/Client.d.ts +43 -0
- package/build/services/Client/Client.js +104 -0
- package/build/services/Client/index.d.ts +3 -0
- package/build/services/Client/index.js +15 -0
- package/build/services/DocumentParser/DocumentParser.d.ts +15 -0
- package/build/services/DocumentParser/DocumentParser.js +19 -0
- package/build/services/DocumentParser/XMLParser.d.ts +25 -0
- package/build/services/DocumentParser/XMLParser.js +178 -0
- package/build/services/DocumentParser/index.d.ts +2 -0
- package/build/services/DocumentParser/index.js +4 -0
- package/build/services/DocumentParser/parsers/index.d.ts +7 -0
- package/build/services/DocumentParser/parsers/index.js +9 -0
- package/build/services/DocumentParser/parsers/parse-form-13g.d.ts +8 -0
- package/build/services/DocumentParser/parsers/parse-form-13g.js +88 -0
- package/build/services/DocumentParser/parsers/parse-form-4.d.ts +8 -0
- package/build/services/DocumentParser/parsers/parse-form-4.js +220 -0
- package/build/services/FactsDownloader/Downloader.d.ts +26 -0
- package/build/services/FactsDownloader/Downloader.js +102 -0
- package/build/services/FactsDownloader/FactsDownloader.d.ts +37 -0
- package/build/services/FactsDownloader/FactsDownloader.js +131 -0
- package/build/services/FactsDownloader/Unzipper.d.ts +40 -0
- package/build/services/FactsDownloader/Unzipper.js +40 -0
- package/build/services/FactsDownloader/index.d.ts +2 -0
- package/build/services/FactsDownloader/index.js +4 -0
- package/build/services/ReportParser/ReportParser.d.ts +1 -1
- package/build/services/ReportParser/ReportTranslatedProxy.d.ts +1 -1
- package/build/services/ReportParser/ReportWrapper.js +1 -2
- package/build/services/ReportParser/resolvers/helpers.d.ts +1 -1
- package/build/services/SecEdgarApi/RequestWrapper.d.ts +30 -0
- package/build/services/SecEdgarApi/RequestWrapper.js +133 -0
- package/build/services/SecEdgarApi/SecConnector.d.ts +1 -1
- package/build/services/SecEdgarApi/SecConnector.js +1 -1
- package/build/services/SecEdgarApi/SecEdgarApi.d.ts +140 -30
- package/build/services/SecEdgarApi/SecEdgarApi.js +284 -42
- package/build/services/SecEdgarApi/Throttler.d.ts +1 -2
- package/build/services/SecEdgarApi/Throttler.js +13 -13
- package/build/services/SecEdgarApi/index.js +1 -5
- package/build/types/common.type.d.ts +12 -0
- package/build/types/common.type.js +2 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.js +3 -5
- package/build/types/parsed-filings.type.d.ts +58 -0
- package/build/types/parsed-filings.type.js +2 -0
- package/build/types/report-raw.type.d.ts +3 -3
- package/build/types/submission.type.d.ts +19 -1
- package/package.json +1 -5
package/README.md
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
|
-
#
|
|
1
|
+
# SEC Edgar API
|
|
2
2
|
|
|
3
3
|
Fetch and parse earnings reports and other documents filed with the SEC using the EDGAR API.
|
|
4
4
|
This package is focused on the earnings reports for stock analysis.
|
|
5
5
|
|
|
6
|
+
Some main data points available include:
|
|
7
|
+
|
|
8
|
+
- Earnings Reports
|
|
9
|
+
- Insider Transactions
|
|
10
|
+
- Institutional Holders
|
|
11
|
+
- Filing History
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```SH
|
|
16
|
+
npm install sec-edgar-api
|
|
17
|
+
```
|
|
18
|
+
|
|
6
19
|
## Report Interface
|
|
7
20
|
|
|
8
21
|
Reports are all returned as a uniform interface:
|
|
@@ -87,7 +100,7 @@ interface ReportTranslated {
|
|
|
87
100
|
import package contents
|
|
88
101
|
|
|
89
102
|
```TS
|
|
90
|
-
import {
|
|
103
|
+
import { secEdgarApi } from 'sec-edgar-api'
|
|
91
104
|
```
|
|
92
105
|
|
|
93
106
|
You can fetch reports individually directly from the SEC website, (throttled to 10 requests per second)
|
|
@@ -97,36 +110,6 @@ You can fetch reports individually directly from the SEC website, (throttled to
|
|
|
97
110
|
const reports = await secEdgarApi.getReports({ symbol: 'AAPL' })
|
|
98
111
|
```
|
|
99
112
|
|
|
100
|
-
or download all data from the SEC website and read directly from the files so you don't have to worry about rate limiting.
|
|
101
|
-
|
|
102
|
-
```TS
|
|
103
|
-
const downloadDirectory = './downloads/companyfacts'
|
|
104
|
-
|
|
105
|
-
// Download companyfacts directory from sec.gov (over 15GB)
|
|
106
|
-
await secEdgarApi.downloadCompanyFactsDirectory({
|
|
107
|
-
outputDirname: downloadDirectory,
|
|
108
|
-
onDownloadComplete: () => process.stdout.write('\n'),
|
|
109
|
-
onChunk: ({ percentComplete, stage }) => {
|
|
110
|
-
// Write progress bar to console
|
|
111
|
-
const countBarsComplete = Math.ceil(percentComplete * 30)
|
|
112
|
-
const barStr = `${'='.repeat(countBarsComplete)}${' '.repeat(30 - countBarsComplete)}`
|
|
113
|
-
const percentStr = `${(Math.round(percentComplete * 10000) / 100).toFixed(2)}%`
|
|
114
|
-
const statusStr = stage === 'download' ? 'Downloading...' : 'Unzipping...'
|
|
115
|
-
|
|
116
|
-
process.stdout.write(`\r<${barStr}> ${percentStr} ${statusStr}`)
|
|
117
|
-
},
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
// read companyfacts directory
|
|
121
|
-
const companyFacts = factFileReader.readFactFile({
|
|
122
|
-
companyFactsDirname: downloadDirectory,
|
|
123
|
-
symbol: 'AAPL',
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
// parse reports (same return value as secEdgarApi.getReports())
|
|
127
|
-
const reports = reportParser.parseReports(companyFacts)
|
|
128
|
-
```
|
|
129
|
-
|
|
130
113
|
## Resolvers
|
|
131
114
|
|
|
132
115
|
**WARNING** Still in testing. Values may not be accurate for all companies since the properties provided in the reports differ.
|
|
@@ -162,17 +145,6 @@ Files for mapping & resolving properties:
|
|
|
162
145
|
- Mapping properties: `src/util/key-translations.ts`
|
|
163
146
|
- Resolving properties: `src/services/ReportParser.ts` (add resolvers to the `resolvers/` directory, import to `/resolver/index.ts`, and add to ReportParser.resolveAll)
|
|
164
147
|
|
|
165
|
-
These are the scripts I used to get keys commonly used across reports, which you can use to add to `key-translations.ts`
|
|
166
|
-
|
|
167
|
-
```TS
|
|
168
|
-
import { readAllCompanyFactFiles, getPropertyUsageCounts } from './scripts/script-helpers'
|
|
169
|
-
|
|
170
|
-
const companyFactsList = readAllCompanyFactFiles(path.resolve('./downloads/companyfacts'), 10)
|
|
171
|
-
const propertyUsageCounts = getPropertyUsageCounts(companyFactsList)
|
|
172
|
-
|
|
173
|
-
fs.writeFileSync('./downloads/property-usage-counts.json', JSON.stringify(propertyUsageCounts, null, 2))
|
|
174
|
-
```
|
|
175
|
-
|
|
176
148
|
### Resources
|
|
177
149
|
|
|
178
150
|
- Validate resolved values: https://finance.yahoo.com/
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.factsDownloader = void 0;
|
|
4
|
+
var FactsDownloader_1 = require("./services/FactsDownloader");
|
|
5
|
+
/**
|
|
6
|
+
* Downloads companyfacts.zip from sec.gov and extracts the directory
|
|
7
|
+
*/
|
|
8
|
+
var factsDownloader = new FactsDownloader_1.default();
|
|
9
|
+
exports.factsDownloader = factsDownloader;
|
package/build/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import FactFileReader from './services/FactFileReader';
|
|
2
1
|
import ReportParser from './services/ReportParser';
|
|
3
2
|
import SecEdgarApi from './services/SecEdgarApi';
|
|
4
3
|
/**
|
|
@@ -6,11 +5,6 @@ import SecEdgarApi from './services/SecEdgarApi';
|
|
|
6
5
|
* reports as json objects.
|
|
7
6
|
*/
|
|
8
7
|
declare const reportParser: ReportParser;
|
|
9
|
-
/**
|
|
10
|
-
* Reads files from the companyfacts directory (which can be downloaded
|
|
11
|
-
* using secEdgarApi.downloadCompanyFacts()).
|
|
12
|
-
*/
|
|
13
|
-
declare const factFileReader: FactFileReader;
|
|
14
8
|
/**
|
|
15
9
|
* Gets company reports and filings from the SEC EDGAR API. Requests are
|
|
16
10
|
* throttled with 120ms delay between requests to avoid rate limiting.
|
|
@@ -18,4 +12,5 @@ declare const factFileReader: FactFileReader;
|
|
|
18
12
|
* @see https://www.sec.gov/edgar/sec-api-documentation
|
|
19
13
|
*/
|
|
20
14
|
declare const secEdgarApi: SecEdgarApi;
|
|
21
|
-
export { reportParser,
|
|
15
|
+
export { reportParser, secEdgarApi };
|
|
16
|
+
export * from './types';
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
2
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.secEdgarApi = exports.
|
|
4
|
-
var FactFileReader_1 = require("./services/FactFileReader");
|
|
13
|
+
exports.secEdgarApi = exports.reportParser = void 0;
|
|
5
14
|
var ReportParser_1 = require("./services/ReportParser");
|
|
6
15
|
var SecEdgarApi_1 = require("./services/SecEdgarApi");
|
|
7
16
|
/**
|
|
@@ -10,12 +19,6 @@ var SecEdgarApi_1 = require("./services/SecEdgarApi");
|
|
|
10
19
|
*/
|
|
11
20
|
var reportParser = new ReportParser_1.default();
|
|
12
21
|
exports.reportParser = reportParser;
|
|
13
|
-
/**
|
|
14
|
-
* Reads files from the companyfacts directory (which can be downloaded
|
|
15
|
-
* using secEdgarApi.downloadCompanyFacts()).
|
|
16
|
-
*/
|
|
17
|
-
var factFileReader = new FactFileReader_1.default();
|
|
18
|
-
exports.factFileReader = factFileReader;
|
|
19
22
|
/**
|
|
20
23
|
* Gets company reports and filings from the SEC EDGAR API. Requests are
|
|
21
24
|
* throttled with 120ms delay between requests to avoid rate limiting.
|
|
@@ -24,3 +27,4 @@ exports.factFileReader = factFileReader;
|
|
|
24
27
|
*/
|
|
25
28
|
var secEdgarApi = new SecEdgarApi_1.default();
|
|
26
29
|
exports.secEdgarApi = secEdgarApi;
|
|
30
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { ClientRequest, IncomingMessage, RequestOptions } from 'http';
|
|
3
|
+
declare type Primitive = string | number | boolean | null | undefined;
|
|
4
|
+
interface HttpClient {
|
|
5
|
+
request: (options: string | URL | RequestOptions, callback?: (res: IncomingMessage) => void) => ClientRequest;
|
|
6
|
+
}
|
|
7
|
+
export interface OnChunkData {
|
|
8
|
+
percentComplete: number;
|
|
9
|
+
chunk: Buffer;
|
|
10
|
+
}
|
|
11
|
+
export interface ClientResponse {
|
|
12
|
+
statusCode: number;
|
|
13
|
+
message: string;
|
|
14
|
+
data: Buffer | null;
|
|
15
|
+
}
|
|
16
|
+
export interface RequestParams {
|
|
17
|
+
url: string;
|
|
18
|
+
headers?: Record<string, string>;
|
|
19
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
20
|
+
data?: string | Record<string, Primitive | object>;
|
|
21
|
+
timeout?: number;
|
|
22
|
+
onError?: (err: Error) => void;
|
|
23
|
+
onChunk?: (data: OnChunkData) => void;
|
|
24
|
+
onResponse?: (response: IncomingMessage) => void;
|
|
25
|
+
onSuccess?: (response: ClientResponse) => void;
|
|
26
|
+
resolveData?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface ClientArgs {
|
|
29
|
+
httpClient?: HttpClient;
|
|
30
|
+
defaultHeaders?: Record<string, string>;
|
|
31
|
+
}
|
|
32
|
+
export interface IClient {
|
|
33
|
+
request(params: RequestParams): Promise<ClientResponse>;
|
|
34
|
+
setDefaultHeaders?(headers: Record<string, string>): void;
|
|
35
|
+
}
|
|
36
|
+
export default class Client implements IClient {
|
|
37
|
+
private readonly httpClient;
|
|
38
|
+
private defaultHeaders;
|
|
39
|
+
constructor(args?: ClientArgs);
|
|
40
|
+
setDefaultHeaders(headers: Record<string, string>): void;
|
|
41
|
+
request(params: RequestParams): Promise<ClientResponse>;
|
|
42
|
+
}
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
var https = require("https");
|
|
15
|
+
var Client = /** @class */ (function () {
|
|
16
|
+
function Client(args) {
|
|
17
|
+
if (args === void 0) { args = {
|
|
18
|
+
httpClient: https,
|
|
19
|
+
defaultHeaders: {
|
|
20
|
+
// this can be any user agent, just not empty
|
|
21
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 RuxitSynthetic/1.0 v1060014908909962014 t8797611264074608560 ath259cea6f altpriv cvcv=2 smf=0',
|
|
22
|
+
},
|
|
23
|
+
}; }
|
|
24
|
+
var httpClient = args.httpClient, defaultHeaders = args.defaultHeaders;
|
|
25
|
+
this.httpClient = httpClient !== null && httpClient !== void 0 ? httpClient : https;
|
|
26
|
+
this.defaultHeaders = defaultHeaders !== null && defaultHeaders !== void 0 ? defaultHeaders : {};
|
|
27
|
+
}
|
|
28
|
+
Client.prototype.setDefaultHeaders = function (headers) {
|
|
29
|
+
this.defaultHeaders = headers;
|
|
30
|
+
};
|
|
31
|
+
Client.prototype.request = function (params) {
|
|
32
|
+
var _this = this;
|
|
33
|
+
var url = params.url, data = params.data, headers = params.headers, onChunk = params.onChunk, onResponse = params.onResponse, onError = params.onError, onSuccess = params.onSuccess, _a = params.resolveData, resolveData = _a === void 0 ? true : _a, _b = params.method, method = _b === void 0 ? 'GET' : _b, _c = params.timeout, timeout = _c === void 0 ? 86400000 : _c;
|
|
34
|
+
var allHeaders = __assign(__assign({}, this.defaultHeaders), headers);
|
|
35
|
+
return new Promise(function (resolve, reject) {
|
|
36
|
+
var responseData = '';
|
|
37
|
+
var request = _this.httpClient.request(url, function (res) {
|
|
38
|
+
var _a, _b, _c;
|
|
39
|
+
var lengthTotal = parseInt((_a = res.headers['content-length']) !== null && _a !== void 0 ? _a : '0');
|
|
40
|
+
var lengthCurrent = 0;
|
|
41
|
+
onResponse === null || onResponse === void 0 ? void 0 : onResponse(res);
|
|
42
|
+
if (res.statusCode !== 200) {
|
|
43
|
+
reject({
|
|
44
|
+
statusCode: (_b = res.statusCode) !== null && _b !== void 0 ? _b : 400,
|
|
45
|
+
message: (_c = res.statusMessage) !== null && _c !== void 0 ? _c : 'Bad Request',
|
|
46
|
+
data: null,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
res.on('data', function (chunk) {
|
|
50
|
+
lengthCurrent += chunk.length;
|
|
51
|
+
if (resolveData) {
|
|
52
|
+
responseData += chunk;
|
|
53
|
+
}
|
|
54
|
+
onChunk === null || onChunk === void 0 ? void 0 : onChunk({
|
|
55
|
+
percentComplete: lengthCurrent / lengthTotal,
|
|
56
|
+
chunk: Buffer.from(chunk),
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
res.on('error', function (err) {
|
|
60
|
+
var _a, _b;
|
|
61
|
+
onError === null || onError === void 0 ? void 0 : onError(err);
|
|
62
|
+
reject({
|
|
63
|
+
statusCode: (_a = res.statusCode) !== null && _a !== void 0 ? _a : 400,
|
|
64
|
+
message: (_b = res.statusMessage) !== null && _b !== void 0 ? _b : 'Bad Request',
|
|
65
|
+
data: null,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
res.on('end', function () {
|
|
69
|
+
var _a, _b;
|
|
70
|
+
var buffer = Buffer.from(responseData);
|
|
71
|
+
var clientResponse = {
|
|
72
|
+
statusCode: (_a = res.statusCode) !== null && _a !== void 0 ? _a : 200,
|
|
73
|
+
message: (_b = res.statusMessage) !== null && _b !== void 0 ? _b : 'OK',
|
|
74
|
+
data: buffer,
|
|
75
|
+
};
|
|
76
|
+
onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(clientResponse);
|
|
77
|
+
resolve(clientResponse);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
request.on('timeout', function () {
|
|
81
|
+
request.destroy();
|
|
82
|
+
reject({
|
|
83
|
+
statusCode: null,
|
|
84
|
+
message: 'Connection Timeout',
|
|
85
|
+
data: null,
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
request.setTimeout(timeout, function () { return reject("timeout after ".concat(timeout, "ms")); });
|
|
89
|
+
for (var key in allHeaders) {
|
|
90
|
+
request.setHeader(key, allHeaders[key]);
|
|
91
|
+
}
|
|
92
|
+
if (data) {
|
|
93
|
+
if (typeof data === 'string')
|
|
94
|
+
request.write(data);
|
|
95
|
+
else
|
|
96
|
+
request.write(JSON.stringify(data));
|
|
97
|
+
}
|
|
98
|
+
request.method = method;
|
|
99
|
+
request.end();
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
return Client;
|
|
103
|
+
}());
|
|
104
|
+
exports.default = Client;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
var Client_1 = require("./Client");
|
|
14
|
+
exports.default = Client_1.default;
|
|
15
|
+
__exportStar(require("./Client"), exports);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { InsiderTransaction, XMLParams } from '../../types';
|
|
2
|
+
import XMLParser from './XMLParser';
|
|
3
|
+
import parsers from './parsers';
|
|
4
|
+
interface DocumentParserArgs {
|
|
5
|
+
parser?: XMLParser;
|
|
6
|
+
parsersByName?: typeof parsers;
|
|
7
|
+
}
|
|
8
|
+
export default class DocumentParser {
|
|
9
|
+
private readonly parser;
|
|
10
|
+
private readonly parsersByName;
|
|
11
|
+
constructor(args?: DocumentParserArgs);
|
|
12
|
+
parseInsiderTransactions(params: XMLParams): InsiderTransaction[];
|
|
13
|
+
parseHolders(params: XMLParams): import("../../types").Holder[];
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var XMLParser_1 = require("./XMLParser");
|
|
4
|
+
var parsers_1 = require("./parsers");
|
|
5
|
+
var DocumentParser = /** @class */ (function () {
|
|
6
|
+
function DocumentParser(args) {
|
|
7
|
+
var _a = args !== null && args !== void 0 ? args : {}, _b = _a.parser, parser = _b === void 0 ? new XMLParser_1.default() : _b, _c = _a.parsersByName, parsersByName = _c === void 0 ? parsers_1.default : _c;
|
|
8
|
+
this.parser = parser;
|
|
9
|
+
this.parsersByName = parsersByName;
|
|
10
|
+
}
|
|
11
|
+
DocumentParser.prototype.parseInsiderTransactions = function (params) {
|
|
12
|
+
return this.parsersByName.parseForm4(params, this.parser);
|
|
13
|
+
};
|
|
14
|
+
DocumentParser.prototype.parseHolders = function (params) {
|
|
15
|
+
return this.parsersByName.parseForm13g(params, this.parser);
|
|
16
|
+
};
|
|
17
|
+
return DocumentParser;
|
|
18
|
+
}());
|
|
19
|
+
exports.default = DocumentParser;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface OnCharacterData {
|
|
2
|
+
char: string;
|
|
3
|
+
index: number;
|
|
4
|
+
path: string;
|
|
5
|
+
pathOccurrenceCount: number;
|
|
6
|
+
}
|
|
7
|
+
interface Parse2Params {
|
|
8
|
+
xml: string;
|
|
9
|
+
onCharacter?: (data: OnCharacterData) => void;
|
|
10
|
+
onOpenTag?: (data: OnCharacterData) => void;
|
|
11
|
+
onCloseTag?: (data: OnCharacterData) => void;
|
|
12
|
+
}
|
|
13
|
+
interface IterateTablesParams {
|
|
14
|
+
xml: string;
|
|
15
|
+
parentPath?: string;
|
|
16
|
+
trimSpaces?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export default class XMLParser {
|
|
19
|
+
iterateXML(params: Parse2Params): string[];
|
|
20
|
+
/**
|
|
21
|
+
* Returns text in each table cell mapped by `${table}.${row}.${col}`
|
|
22
|
+
*/
|
|
23
|
+
getTableTextMap(params: IterateTablesParams): Map<string, string>;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var XMLParser = /** @class */ (function () {
|
|
4
|
+
function XMLParser() {
|
|
5
|
+
}
|
|
6
|
+
XMLParser.prototype.iterateXML = function (params) {
|
|
7
|
+
var _a, _b, _c, _d;
|
|
8
|
+
var xml = params.xml, onCharacter = params.onCharacter, onCloseTag = params.onCloseTag, onOpenTag = params.onOpenTag;
|
|
9
|
+
var selfEnclosingTags = new Set([
|
|
10
|
+
'filename',
|
|
11
|
+
'description',
|
|
12
|
+
'br',
|
|
13
|
+
'meta',
|
|
14
|
+
'link',
|
|
15
|
+
'img',
|
|
16
|
+
'input',
|
|
17
|
+
'hr',
|
|
18
|
+
'area',
|
|
19
|
+
'base',
|
|
20
|
+
'col',
|
|
21
|
+
'command',
|
|
22
|
+
'embed',
|
|
23
|
+
'keygen',
|
|
24
|
+
'param',
|
|
25
|
+
'source',
|
|
26
|
+
'track',
|
|
27
|
+
'wbr',
|
|
28
|
+
]);
|
|
29
|
+
var pathOccurrenceCountMap = new Map();
|
|
30
|
+
var curPath = '';
|
|
31
|
+
var curTag = '';
|
|
32
|
+
var didStart = false;
|
|
33
|
+
var pathsArr = [];
|
|
34
|
+
for (var i = 0; i < xml.length; i++) {
|
|
35
|
+
var char = xml[i];
|
|
36
|
+
if (char === '<' && xml[i + 1] !== '/' && xml[i + 1] !== '?' && xml[i + 1] !== '!') {
|
|
37
|
+
var iOpen = i;
|
|
38
|
+
didStart = true;
|
|
39
|
+
i++;
|
|
40
|
+
var j = 0;
|
|
41
|
+
var didEndTagName = false;
|
|
42
|
+
while (xml[i] !== '>') {
|
|
43
|
+
didEndTagName =
|
|
44
|
+
didEndTagName ||
|
|
45
|
+
xml[i] === ' ' ||
|
|
46
|
+
xml[i] === '\n' ||
|
|
47
|
+
xml[i] === '\r' ||
|
|
48
|
+
xml[i] === '\t' ||
|
|
49
|
+
xml[i] === '/';
|
|
50
|
+
if (!didEndTagName) {
|
|
51
|
+
curTag += xml[i].toLowerCase();
|
|
52
|
+
}
|
|
53
|
+
i++;
|
|
54
|
+
j++;
|
|
55
|
+
if (j > 1000) {
|
|
56
|
+
throw new Error('too many iterations');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// map path for non-self-enclosing tags
|
|
60
|
+
if (!selfEnclosingTags.has(curTag)) {
|
|
61
|
+
curPath = "".concat(curPath).concat(curPath.length > 0 ? '.' : '').concat(curTag).toLowerCase();
|
|
62
|
+
var pathOccurrenceCount = (_a = pathOccurrenceCountMap.get(curPath)) !== null && _a !== void 0 ? _a : 0;
|
|
63
|
+
pathOccurrenceCountMap.set(curPath, pathOccurrenceCount + 1);
|
|
64
|
+
pathsArr.push(curPath);
|
|
65
|
+
onOpenTag === null || onOpenTag === void 0 ? void 0 : onOpenTag({
|
|
66
|
+
char: char,
|
|
67
|
+
index: iOpen,
|
|
68
|
+
path: curPath,
|
|
69
|
+
pathOccurrenceCount: (_b = pathOccurrenceCountMap.get(curPath)) !== null && _b !== void 0 ? _b : 0,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
curTag = '';
|
|
73
|
+
}
|
|
74
|
+
else if (char === '<' && xml[i + 1] === '/') {
|
|
75
|
+
while (xml[i] !== '>') {
|
|
76
|
+
i++;
|
|
77
|
+
}
|
|
78
|
+
onCloseTag === null || onCloseTag === void 0 ? void 0 : onCloseTag({
|
|
79
|
+
char: char,
|
|
80
|
+
index: i,
|
|
81
|
+
path: curPath,
|
|
82
|
+
pathOccurrenceCount: (_c = pathOccurrenceCountMap.get(curPath)) !== null && _c !== void 0 ? _c : 0,
|
|
83
|
+
});
|
|
84
|
+
curPath = curPath.slice(0, curPath.lastIndexOf('.'));
|
|
85
|
+
}
|
|
86
|
+
else if (didStart) {
|
|
87
|
+
onCharacter === null || onCharacter === void 0 ? void 0 : onCharacter({
|
|
88
|
+
char: char,
|
|
89
|
+
index: i,
|
|
90
|
+
path: curPath,
|
|
91
|
+
pathOccurrenceCount: (_d = pathOccurrenceCountMap.get(curPath)) !== null && _d !== void 0 ? _d : 0,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return pathsArr;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Returns text in each table cell mapped by `${table}.${row}.${col}`
|
|
99
|
+
*/
|
|
100
|
+
XMLParser.prototype.getTableTextMap = function (params) {
|
|
101
|
+
var xml = params.xml, parentPath = params.parentPath, _a = params.trimSpaces, trimSpaces = _a === void 0 ? true : _a;
|
|
102
|
+
var rowPaths = new Set([
|
|
103
|
+
"".concat(parentPath, ".table.tbody.tr"),
|
|
104
|
+
"".concat(parentPath, ".table.thead.tr"),
|
|
105
|
+
"".concat(parentPath, ".table.tfoot.tr"),
|
|
106
|
+
"".concat(parentPath, ".table.tr"),
|
|
107
|
+
]);
|
|
108
|
+
var colPaths = new Set([
|
|
109
|
+
"".concat(parentPath, ".table.tbody.tr.td"),
|
|
110
|
+
"".concat(parentPath, ".table.thead.tr.td"),
|
|
111
|
+
"".concat(parentPath, ".table.tfoot.tr.td"),
|
|
112
|
+
"".concat(parentPath, ".table.tr.td"),
|
|
113
|
+
"".concat(parentPath, ".table.tbody.tr.th"),
|
|
114
|
+
"".concat(parentPath, ".table.thead.tr.th"),
|
|
115
|
+
"".concat(parentPath, ".table.tfoot.tr.th"),
|
|
116
|
+
"".concat(parentPath, ".table.tr.th"),
|
|
117
|
+
]);
|
|
118
|
+
var table = 0;
|
|
119
|
+
var row = 0;
|
|
120
|
+
var col = 0;
|
|
121
|
+
var textByColKey = new Map();
|
|
122
|
+
var spaceChars = new Set(['\n', '\r', '\t']);
|
|
123
|
+
this.iterateXML({
|
|
124
|
+
xml: xml,
|
|
125
|
+
onOpenTag: function (_a) {
|
|
126
|
+
var _b;
|
|
127
|
+
var path = _a.path;
|
|
128
|
+
var colKey = "".concat(table, ".").concat(row, ".").concat(col);
|
|
129
|
+
var textCur = (_b = textByColKey.get(colKey)) !== null && _b !== void 0 ? _b : '';
|
|
130
|
+
var pathLower = path.toLowerCase();
|
|
131
|
+
if (textCur.trim().length === 0 && col === 0) {
|
|
132
|
+
textByColKey.delete(colKey);
|
|
133
|
+
}
|
|
134
|
+
var isTable = parentPath ? pathLower === "".concat(parentPath, ".table") : pathLower.endsWith('table');
|
|
135
|
+
var isRow = parentPath ? rowPaths.has(pathLower) : pathLower.endsWith('tr');
|
|
136
|
+
var isCol = parentPath
|
|
137
|
+
? colPaths.has(pathLower)
|
|
138
|
+
: pathLower.endsWith('td') || pathLower.endsWith('th');
|
|
139
|
+
if (isTable) {
|
|
140
|
+
table++;
|
|
141
|
+
col = 0;
|
|
142
|
+
row = 0;
|
|
143
|
+
}
|
|
144
|
+
else if (isRow) {
|
|
145
|
+
row++;
|
|
146
|
+
col = 0;
|
|
147
|
+
}
|
|
148
|
+
else if (isCol) {
|
|
149
|
+
col++;
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
onCharacter: function (_a) {
|
|
153
|
+
var _b;
|
|
154
|
+
var char = _a.char;
|
|
155
|
+
char = spaceChars.has(char) ? ' ' : char;
|
|
156
|
+
var colKey = "".concat(table, ".").concat(row, ".").concat(col);
|
|
157
|
+
var textCur = (_b = textByColKey.get(colKey)) !== null && _b !== void 0 ? _b : '';
|
|
158
|
+
if (trimSpaces && char === ' ' && textCur.endsWith(' '))
|
|
159
|
+
return;
|
|
160
|
+
textByColKey.set(colKey, "".concat(textCur).concat(char));
|
|
161
|
+
},
|
|
162
|
+
onCloseTag: function () {
|
|
163
|
+
var _a;
|
|
164
|
+
var colKey = "".concat(table, ".").concat(row, ".").concat(col);
|
|
165
|
+
var textCur = (_a = textByColKey.get(colKey)) !== null && _a !== void 0 ? _a : '';
|
|
166
|
+
if (textCur.trim().length === 0 && col === 0) {
|
|
167
|
+
textByColKey.delete(colKey);
|
|
168
|
+
}
|
|
169
|
+
else if (!textCur.endsWith(' ')) {
|
|
170
|
+
textByColKey.set(colKey, "".concat(textCur, " "));
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
return textByColKey;
|
|
175
|
+
};
|
|
176
|
+
return XMLParser;
|
|
177
|
+
}());
|
|
178
|
+
exports.default = XMLParser;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var parse_form_4_1 = require("./parse-form-4");
|
|
4
|
+
var parse_form_13g_1 = require("./parse-form-13g");
|
|
5
|
+
var parsers = {
|
|
6
|
+
parseForm4: parse_form_4_1.parseForm4,
|
|
7
|
+
parseForm13g: parse_form_13g_1.parseForm13g,
|
|
8
|
+
};
|
|
9
|
+
exports.default = parsers;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Holder, XMLParams } from '../../../types';
|
|
2
|
+
import XMLParser from '../XMLParser';
|
|
3
|
+
/**
|
|
4
|
+
* Form SC 13G - Holders
|
|
5
|
+
*
|
|
6
|
+
* example at https://www.sec.gov/Archives/edgar/data/320193/000119312523038262/d382361dsc13ga.htm
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseForm13g(params: XMLParams, xmlParser?: XMLParser): Holder[];
|