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.
Files changed (51) hide show
  1. package/README.md +15 -43
  2. package/build/downloader.d.ts +6 -0
  3. package/build/downloader.js +9 -0
  4. package/build/index.d.ts +2 -7
  5. package/build/index.js +12 -8
  6. package/build/services/Client/Client.d.ts +43 -0
  7. package/build/services/Client/Client.js +104 -0
  8. package/build/services/Client/index.d.ts +3 -0
  9. package/build/services/Client/index.js +15 -0
  10. package/build/services/DocumentParser/DocumentParser.d.ts +15 -0
  11. package/build/services/DocumentParser/DocumentParser.js +19 -0
  12. package/build/services/DocumentParser/XMLParser.d.ts +25 -0
  13. package/build/services/DocumentParser/XMLParser.js +178 -0
  14. package/build/services/DocumentParser/index.d.ts +2 -0
  15. package/build/services/DocumentParser/index.js +4 -0
  16. package/build/services/DocumentParser/parsers/index.d.ts +7 -0
  17. package/build/services/DocumentParser/parsers/index.js +9 -0
  18. package/build/services/DocumentParser/parsers/parse-form-13g.d.ts +8 -0
  19. package/build/services/DocumentParser/parsers/parse-form-13g.js +88 -0
  20. package/build/services/DocumentParser/parsers/parse-form-4.d.ts +8 -0
  21. package/build/services/DocumentParser/parsers/parse-form-4.js +220 -0
  22. package/build/services/FactsDownloader/Downloader.d.ts +26 -0
  23. package/build/services/FactsDownloader/Downloader.js +102 -0
  24. package/build/services/FactsDownloader/FactsDownloader.d.ts +37 -0
  25. package/build/services/FactsDownloader/FactsDownloader.js +131 -0
  26. package/build/services/FactsDownloader/Unzipper.d.ts +40 -0
  27. package/build/services/FactsDownloader/Unzipper.js +40 -0
  28. package/build/services/FactsDownloader/index.d.ts +2 -0
  29. package/build/services/FactsDownloader/index.js +4 -0
  30. package/build/services/ReportParser/ReportParser.d.ts +1 -1
  31. package/build/services/ReportParser/ReportTranslatedProxy.d.ts +1 -1
  32. package/build/services/ReportParser/ReportWrapper.js +1 -2
  33. package/build/services/ReportParser/resolvers/helpers.d.ts +1 -1
  34. package/build/services/SecEdgarApi/RequestWrapper.d.ts +30 -0
  35. package/build/services/SecEdgarApi/RequestWrapper.js +133 -0
  36. package/build/services/SecEdgarApi/SecConnector.d.ts +1 -1
  37. package/build/services/SecEdgarApi/SecConnector.js +1 -1
  38. package/build/services/SecEdgarApi/SecEdgarApi.d.ts +140 -30
  39. package/build/services/SecEdgarApi/SecEdgarApi.js +284 -42
  40. package/build/services/SecEdgarApi/Throttler.d.ts +1 -2
  41. package/build/services/SecEdgarApi/Throttler.js +13 -13
  42. package/build/services/SecEdgarApi/index.js +1 -5
  43. package/build/types/common.type.d.ts +12 -0
  44. package/build/types/common.type.js +2 -0
  45. package/build/types/index.d.ts +2 -0
  46. package/build/types/index.js +3 -5
  47. package/build/types/parsed-filings.type.d.ts +58 -0
  48. package/build/types/parsed-filings.type.js +2 -0
  49. package/build/types/report-raw.type.d.ts +3 -3
  50. package/build/types/submission.type.d.ts +19 -1
  51. package/package.json +1 -5
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseForm13g = void 0;
4
+ var XMLParser_1 = require("../XMLParser");
5
+ /**
6
+ * Form SC 13G - Holders
7
+ *
8
+ * example at https://www.sec.gov/Archives/edgar/data/320193/000119312523038262/d382361dsc13ga.htm
9
+ */
10
+ function parseForm13g(params, xmlParser) {
11
+ var _a, _b, _c, _d;
12
+ if (xmlParser === void 0) { xmlParser = new XMLParser_1.default(); }
13
+ var xml = params.xml;
14
+ var textMap = xmlParser.getTableTextMap({ xml: xml });
15
+ var holders = [];
16
+ var getKey = function (text) {
17
+ var keyMap = {
18
+ 'name of reporting': 'name',
19
+ 'names of reporting': 'name',
20
+ 'citizenship or place': 'origin',
21
+ 'sole voting power': 'votingPowerSole',
22
+ 'shared voting power': 'votingPowerShared',
23
+ 'sole dispositive power': 'dispositivePowerSole',
24
+ 'shared dispositive power': 'dispositivePowerShared',
25
+ 'aggregate amount beneficially owned': 'shares',
26
+ 'percent of class': 'percentOfClass',
27
+ 'type of reporting person': 'typeOfReportingPerson',
28
+ };
29
+ var textLower = text.toLowerCase();
30
+ for (var key in keyMap) {
31
+ if (textLower.includes(key))
32
+ return keyMap[key];
33
+ }
34
+ return null;
35
+ };
36
+ var _loop_1 = function (text) {
37
+ var colName = getKey(text);
38
+ var isNewHolder = colName === 'name';
39
+ if (isNewHolder) {
40
+ if (((_a = holders[holders.length - 1]) === null || _a === void 0 ? void 0 : _a.name) === '') {
41
+ holders.pop();
42
+ }
43
+ holders.push({
44
+ name: '',
45
+ origin: '',
46
+ shares: 0,
47
+ percentOfClass: '',
48
+ votingPowerSole: null,
49
+ votingPowerShared: null,
50
+ dispositivePowerSole: null,
51
+ dispositivePowerShared: null,
52
+ typeOfReportingPerson: null,
53
+ });
54
+ }
55
+ var holder = holders[holders.length - 1];
56
+ // continue if no colName or if the value is already set
57
+ if (colName === null || ![0, '', null].includes(holder[colName]))
58
+ return "continue";
59
+ var textParts = text.split(' ').filter(function (t) { return t.trim() !== ''; });
60
+ var colNameIndex = textParts.findIndex(function (t) { return getKey(t) === colName; });
61
+ var value = (_c = (_b = textParts[colNameIndex + 1]) === null || _b === void 0 ? void 0 : _b.trim()) !== null && _c !== void 0 ? _c : '';
62
+ switch (colName) {
63
+ case 'shares':
64
+ holder.shares = Number(value.replace(/[^0-9]/g, '')) || 0;
65
+ break;
66
+ case 'typeOfReportingPerson':
67
+ holder[colName] = value === '' ? null : value;
68
+ break;
69
+ case 'votingPowerSole':
70
+ case 'votingPowerShared':
71
+ case 'dispositivePowerSole':
72
+ case 'dispositivePowerShared':
73
+ holder[colName] = value.toLowerCase() === 'none' ? null : value;
74
+ break;
75
+ default:
76
+ holder[colName] = value;
77
+ }
78
+ };
79
+ for (var _i = 0, _e = Array.from(textMap.values()); _i < _e.length; _i++) {
80
+ var text = _e[_i];
81
+ _loop_1(text);
82
+ }
83
+ if (((_d = holders[holders.length - 1]) === null || _d === void 0 ? void 0 : _d.name) === '') {
84
+ holders.pop();
85
+ }
86
+ return holders;
87
+ }
88
+ exports.parseForm13g = parseForm13g;
@@ -0,0 +1,8 @@
1
+ import { InsiderTransaction, XMLParams } from '../../../types';
2
+ import XMLParser from '../XMLParser';
3
+ /**
4
+ * Form 4 - Insider Transactions
5
+ *
6
+ * example at https://www.sec.gov/Archives/edgar/data/320193/000032019323000079/xslF345X05/wk-form4_1691533817.xml
7
+ */
8
+ export declare function parseForm4(params: XMLParams, xmlParser?: XMLParser): InsiderTransaction[];
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseForm4 = void 0;
4
+ var XMLParser_1 = require("../XMLParser");
5
+ /**
6
+ * Form 4 - Insider Transactions
7
+ *
8
+ * example at https://www.sec.gov/Archives/edgar/data/320193/000032019323000079/xslF345X05/wk-form4_1691533817.xml
9
+ */
10
+ function parseForm4(params, xmlParser) {
11
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
12
+ if (xmlParser === void 0) { xmlParser = new XMLParser_1.default(); }
13
+ var xml = params.xml;
14
+ var textMap = xmlParser.getTableTextMap({ xml: xml, parentPath: 'html.body' });
15
+ var getTextBetween = function (text, before, after) {
16
+ var indexBefore = text.indexOf(before);
17
+ var indexAfter = after ? text.indexOf(after, indexBefore) : text.length;
18
+ return text.substring(indexBefore + before.length, indexAfter).trim();
19
+ };
20
+ var relationText = (_a = textMap.get('2.1.3')) !== null && _a !== void 0 ? _a : '';
21
+ var filerNameText = (_b = textMap.get('2.1.1')) !== null && _b !== void 0 ? _b : '';
22
+ var filterNameText = getTextBetween(filerNameText, '1. Name and Address of Reporting Person*', '(Last)');
23
+ var isDirector = relationText.substring(0, relationText.indexOf('Director')).includes('X');
24
+ var isOwner10 = getTextBetween(relationText, 'Director', '10% Owner').includes('X');
25
+ var isOfficer = getTextBetween(relationText, '10% Owner', 'Officer (give title below)').includes('X');
26
+ var isOther = getTextBetween(relationText, 'Officer (give title below)', 'Other (specify below)').includes('X');
27
+ var position = getTextBetween(relationText, 'Other (specify below)');
28
+ var filerPositionTypes = [];
29
+ if (isDirector)
30
+ filerPositionTypes.push('Director');
31
+ if (isOwner10)
32
+ filerPositionTypes.push('10% Owner');
33
+ if (isOfficer)
34
+ filerPositionTypes.push('Officer');
35
+ if (isOther)
36
+ filerPositionTypes.push('Other');
37
+ var codeTranslations = {
38
+ P: 'Purchase',
39
+ S: 'Sale',
40
+ V: 'Voluntary Reporting',
41
+ A: 'Grant',
42
+ D: 'Sale to Issuer',
43
+ F: 'Payment of Exercise Price',
44
+ I: 'Discretionary Transaction',
45
+ M: 'Conversion of Derivative Exempt',
46
+ C: 'Conversion of Derivative',
47
+ E: 'Expiration of Short Derivative Position',
48
+ H: 'Expiration of Long Derivative Position',
49
+ O: 'Exercise of out-of-the-money Derivative',
50
+ X: 'Exercise of in-the-money Derivative',
51
+ G: 'Gift',
52
+ L: 'Small Acquisition',
53
+ W: 'Acquisition or Disposition By Will or Laws',
54
+ Z: 'Voting Trust Deposit or Withdrawal',
55
+ J: 'Other Acquisition or Disposition',
56
+ K: 'Equity Swap',
57
+ U: 'Disposition Change in Control',
58
+ };
59
+ var toDate = function (str) {
60
+ if (str === '')
61
+ return '';
62
+ var _a = str.split('/'), month = _a[0], day = _a[1], year = _a[2];
63
+ return [month, day, year].some(function (x) { return x === undefined; }) ? '' : "".concat(year, "-").concat(month, "-").concat(day);
64
+ };
65
+ var createTransaction = function () { return ({
66
+ filerName: filterNameText,
67
+ filerPosition: position,
68
+ filerPositionTypes: filerPositionTypes,
69
+ category: 'Non-Derivative',
70
+ securityType: '',
71
+ securityTypeUnderlying: null,
72
+ date: '',
73
+ dateExecuted: null,
74
+ dateExpiration: null,
75
+ dateExercisable: null,
76
+ transactionType: null,
77
+ transactionCode: null,
78
+ transactionDescription: null,
79
+ price: null,
80
+ priceExcercised: null,
81
+ shares: null,
82
+ sharesUnderlying: null,
83
+ sharesEnding: null,
84
+ ownership: '',
85
+ explainationByKey: {},
86
+ }); };
87
+ var getColText = function (colKey) {
88
+ var _a, _b;
89
+ var text = (_a = textMap.get(colKey)) === null || _a === void 0 ? void 0 : _a.replace(/\(\d+\)|\$/g, '');
90
+ return (_b = text === null || text === void 0 ? void 0 : text.trim()) !== null && _b !== void 0 ? _b : '';
91
+ };
92
+ var headingNonDerivative = [
93
+ 'securityType',
94
+ 'date',
95
+ 'dateExecuted',
96
+ 'transactionCode',
97
+ '',
98
+ 'shares',
99
+ 'transactionType',
100
+ 'price',
101
+ 'sharesEnding',
102
+ 'ownership',
103
+ ];
104
+ var headingDerivative = [
105
+ 'securityType',
106
+ 'priceExcercised',
107
+ 'date',
108
+ 'dateExecuted',
109
+ 'transactionCode',
110
+ '',
111
+ 'shares',
112
+ 'shares',
113
+ 'dateExercisable',
114
+ 'dateExpiration',
115
+ 'securityTypeUnderlying',
116
+ 'sharesUnderlying',
117
+ 'price',
118
+ 'sharesEnding',
119
+ 'ownership',
120
+ ];
121
+ var maxIterations = 10000;
122
+ var transactions = [];
123
+ transactionsNonDerivative: for (var row = 4; row < maxIterations; row++) {
124
+ var transaction = createTransaction();
125
+ transaction.category = 'Non-Derivative';
126
+ // get all non-derivative transactions
127
+ for (var col = 1; col < 11; col++) {
128
+ var colName = ((_c = headingNonDerivative[col - 1]) !== null && _c !== void 0 ? _c : '');
129
+ var colKey = "3.".concat(row, ".").concat(col);
130
+ var text = getColText(colKey);
131
+ var explanationNum = (_f = (_e = ((_d = textMap.get(colKey)) !== null && _d !== void 0 ? _d : '').match(/(?<=\()\d+(?=\))/g)) === null || _e === void 0 ? void 0 : _e[0]) !== null && _f !== void 0 ? _f : null;
132
+ var explanationText = explanationNum ? (_g = textMap.get("5.".concat(Number(explanationNum) + 1, ".1"))) !== null && _g !== void 0 ? _g : '' : null;
133
+ if (colName === '')
134
+ continue;
135
+ if (explanationText !== null)
136
+ transaction.explainationByKey[colName] = explanationText.trim();
137
+ if (!textMap.has(colKey))
138
+ break transactionsNonDerivative;
139
+ switch (colName) {
140
+ case 'transactionType':
141
+ transaction.transactionType = text === 'A' ? 'Acquire' : 'Dispose';
142
+ continue;
143
+ case 'transactionCode':
144
+ transaction.transactionDescription = (_h = codeTranslations[text]) !== null && _h !== void 0 ? _h : '';
145
+ transaction.transactionCode = text;
146
+ continue;
147
+ case 'date':
148
+ transaction.date = toDate(text);
149
+ continue;
150
+ case 'dateExecuted':
151
+ case 'dateExercisable':
152
+ case 'dateExpiration':
153
+ transaction[colName] = toDate(text) || null;
154
+ continue;
155
+ case 'price':
156
+ case 'shares':
157
+ case 'sharesEnding':
158
+ var valueNum = Number(text.replace(/,/g, ''));
159
+ transaction[colName] = text === '' || isNaN(valueNum) ? null : valueNum;
160
+ continue;
161
+ default:
162
+ transaction[colName] = text;
163
+ }
164
+ }
165
+ transactions.push(transaction);
166
+ }
167
+ transactionsDerivative: for (var row = 4; row < maxIterations; row++) {
168
+ var transaction = createTransaction();
169
+ transaction.category = 'Derivative';
170
+ var textSharesAcquired = getColText("4.".concat(row, ".6"));
171
+ var textSharesDisposed = getColText("4.".concat(row, ".7"));
172
+ var sharesAcquired = Number(textSharesAcquired);
173
+ var sharesDisposed = Number(textSharesDisposed);
174
+ if (textSharesAcquired !== '' || textSharesDisposed !== '') {
175
+ transaction.transactionType = sharesAcquired - sharesDisposed > 0 ? 'Acquire' : 'Dispose';
176
+ }
177
+ for (var col = 1; col < 16; col++) {
178
+ var colName = ((_j = headingDerivative[col - 1]) !== null && _j !== void 0 ? _j : '');
179
+ var colKey = "4.".concat(row, ".").concat(col);
180
+ var text = ((_k = textMap.get(colKey)) !== null && _k !== void 0 ? _k : '').replace(/\(\d+\)|\$/g, '').trim();
181
+ var explanationNum = (_o = (_m = ((_l = textMap.get(colKey)) !== null && _l !== void 0 ? _l : '').match(/(?<=\()\d+(?=\))/g)) === null || _m === void 0 ? void 0 : _m[0]) !== null && _o !== void 0 ? _o : null;
182
+ var explanationText = explanationNum ? (_p = textMap.get("5.".concat(Number(explanationNum) + 1, ".1"))) !== null && _p !== void 0 ? _p : '' : null;
183
+ if (colName === '')
184
+ continue;
185
+ if (explanationText !== null)
186
+ transaction.explainationByKey[colName] = explanationText.trim();
187
+ if (!textMap.has(colKey))
188
+ break transactionsDerivative;
189
+ switch (colName) {
190
+ case 'transactionType':
191
+ transaction.transactionType = text === 'A' ? 'Acquire' : 'Dispose';
192
+ continue;
193
+ case 'transactionCode':
194
+ transaction.transactionDescription = (_q = codeTranslations[text]) !== null && _q !== void 0 ? _q : '';
195
+ transaction.transactionCode = text;
196
+ continue;
197
+ case 'dateExecuted':
198
+ case 'dateExercisable':
199
+ case 'dateExpiration':
200
+ transaction[colName] = toDate(text) || null;
201
+ continue;
202
+ case 'price':
203
+ case 'shares':
204
+ case 'sharesUnderlying':
205
+ case 'priceExcercised':
206
+ case 'sharesEnding':
207
+ if (colName === 'shares' && transaction.shares !== null)
208
+ continue;
209
+ var valueNum = Number(text.replace(/,/g, ''));
210
+ transaction[colName] = text === '' || isNaN(valueNum) ? null : valueNum;
211
+ continue;
212
+ default:
213
+ transaction[colName] = text;
214
+ }
215
+ }
216
+ transactions.push(transaction);
217
+ }
218
+ return transactions;
219
+ }
220
+ exports.parseForm4 = parseForm4;
@@ -0,0 +1,26 @@
1
+ /// <reference types="node" />
2
+ import { WriteStream } from 'fs';
3
+ import { IClient, RequestParams } from '../Client';
4
+ export interface DownloadParams extends RequestParams {
5
+ filename: string;
6
+ createDirIfNotExists?: boolean;
7
+ }
8
+ export interface IDownloader {
9
+ download(params: DownloadParams): Promise<boolean>;
10
+ }
11
+ interface FileManager {
12
+ createWriteStream(path: string): WriteStream;
13
+ existsSync(path: string): boolean;
14
+ mkdirSync(path: string): void;
15
+ }
16
+ interface DownloaderArgs {
17
+ client: IClient;
18
+ fileManager: FileManager;
19
+ }
20
+ export default class Downlaoder implements IDownloader {
21
+ private readonly client;
22
+ private readonly fileManager;
23
+ constructor(args?: DownloaderArgs);
24
+ download(params: DownloadParams): Promise<boolean>;
25
+ }
26
+ export {};
@@ -0,0 +1,102 @@
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
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __rest = (this && this.__rest) || function (s, e) {
50
+ var t = {};
51
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
52
+ t[p] = s[p];
53
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
54
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
55
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
56
+ t[p[i]] = s[p[i]];
57
+ }
58
+ return t;
59
+ };
60
+ Object.defineProperty(exports, "__esModule", { value: true });
61
+ var fs = require("fs");
62
+ var Client_1 = require("../Client");
63
+ var Downlaoder = /** @class */ (function () {
64
+ function Downlaoder(args) {
65
+ if (args === void 0) { args = { client: new Client_1.default(), fileManager: fs }; }
66
+ var client = args.client, fileManager = args.fileManager;
67
+ this.client = client;
68
+ this.fileManager = fileManager;
69
+ }
70
+ Downlaoder.prototype.download = function (params) {
71
+ var _this = this;
72
+ var filename = params.filename, onSuccess = params.onSuccess, onError = params.onError, _a = params.createDirIfNotExists, createDirIfNotExists = _a === void 0 ? false : _a, rest = __rest(params, ["filename", "onSuccess", "onError", "createDirIfNotExists"]);
73
+ return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
74
+ var dir, file;
75
+ return __generator(this, function (_a) {
76
+ dir = filename.substring(0, filename.lastIndexOf('/'));
77
+ if (dir.length > 0 && createDirIfNotExists && !this.fileManager.existsSync(dir)) {
78
+ this.fileManager.mkdirSync(dir);
79
+ }
80
+ file = this.fileManager.createWriteStream(filename);
81
+ file.on('close', function () { return resolve(true); });
82
+ file.on('finish', function () { return file.close(); });
83
+ file.on('error', function (err) {
84
+ file.destroy();
85
+ onError === null || onError === void 0 ? void 0 : onError(err);
86
+ reject(false);
87
+ });
88
+ this.client
89
+ .request(__assign(__assign({ onError: onError }, rest), { onResponse: function (res) {
90
+ var _a;
91
+ res.pipe(file);
92
+ (_a = rest.onResponse) === null || _a === void 0 ? void 0 : _a.call(rest, res);
93
+ } }))
94
+ .then(function (res) { return onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(res); })
95
+ .catch(function () { return reject(false); });
96
+ return [2 /*return*/];
97
+ });
98
+ }); });
99
+ };
100
+ return Downlaoder;
101
+ }());
102
+ exports.default = Downlaoder;
@@ -0,0 +1,37 @@
1
+ /// <reference types="node" />
2
+ import { IDownloader } from './Downloader';
3
+ import Unzipper from './Unzipper';
4
+ interface FactsDownloaderArgs {
5
+ downloader: IDownloader;
6
+ unzipper: Unzipper;
7
+ }
8
+ interface OnChunkData {
9
+ percentComplete: number;
10
+ chunk: Buffer;
11
+ stage: 'download' | 'unzip';
12
+ }
13
+ export interface DownloadCompanyFactsDirectoryParams {
14
+ outputDirname: string;
15
+ unzip?: boolean;
16
+ onChunk?: (data: OnChunkData) => void;
17
+ onDownloadComplete?: () => void;
18
+ onComplete?: () => void;
19
+ onError?: (err: Error) => void;
20
+ }
21
+ export interface IFactsDownloader {
22
+ downloadCompanyFactsDirectory(params: DownloadCompanyFactsDirectoryParams): Promise<boolean>;
23
+ }
24
+ export default class FactsDownloader implements IFactsDownloader {
25
+ private readonly unzipper;
26
+ private readonly downloader;
27
+ constructor(args?: FactsDownloaderArgs);
28
+ /**
29
+ * Downloads the companyfacts.zip file and extracts the directory containing all company
30
+ * reports available from sec.gov. After downloading, you can use factFileReader and reportParser
31
+ * to get and read reports.
32
+ *
33
+ * Note: Over 15GB of data is downloaded and extracted.
34
+ */
35
+ downloadCompanyFactsDirectory(params: DownloadCompanyFactsDirectoryParams): Promise<boolean>;
36
+ }
37
+ export {};
@@ -0,0 +1,131 @@
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
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ var Downloader_1 = require("./Downloader");
51
+ var Unzipper_1 = require("./Unzipper");
52
+ var FactsDownloader = /** @class */ (function () {
53
+ function FactsDownloader(args) {
54
+ if (args === void 0) { args = {
55
+ downloader: new Downloader_1.default(),
56
+ unzipper: new Unzipper_1.default(),
57
+ }; }
58
+ var unzipper = args.unzipper, downloader = args.downloader;
59
+ this.unzipper = unzipper;
60
+ this.downloader = downloader;
61
+ }
62
+ /**
63
+ * Downloads the companyfacts.zip file and extracts the directory containing all company
64
+ * reports available from sec.gov. After downloading, you can use factFileReader and reportParser
65
+ * to get and read reports.
66
+ *
67
+ * Note: Over 15GB of data is downloaded and extracted.
68
+ */
69
+ FactsDownloader.prototype.downloadCompanyFactsDirectory = function (params) {
70
+ return __awaiter(this, void 0, void 0, function () {
71
+ var outputDirname, onChunk, onDownloadComplete, onError, onComplete, _a, unzip;
72
+ var _this = this;
73
+ return __generator(this, function (_b) {
74
+ outputDirname = params.outputDirname, onChunk = params.onChunk, onDownloadComplete = params.onDownloadComplete, onError = params.onError, onComplete = params.onComplete, _a = params.unzip, unzip = _a === void 0 ? true : _a;
75
+ return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
76
+ var filename, e_1;
77
+ return __generator(this, function (_a) {
78
+ switch (_a.label) {
79
+ case 0:
80
+ filename = "".concat(outputDirname, ".zip");
81
+ _a.label = 1;
82
+ case 1:
83
+ _a.trys.push([1, 5, , 6]);
84
+ // download from sec
85
+ return [4 /*yield*/, this.downloader.download({
86
+ url: 'https://www.sec.gov/Archives/edgar/daily-index/xbrl/companyfacts.zip',
87
+ filename: filename,
88
+ createDirIfNotExists: true,
89
+ resolveData: false,
90
+ headers: {
91
+ 'Accept-Encoding': 'gzip, deflate',
92
+ },
93
+ onError: function (err) { return reject(err); },
94
+ onChunk: onChunk ? function (data) { return onChunk === null || onChunk === void 0 ? void 0 : onChunk(__assign(__assign({}, data), { stage: 'download' })); } : undefined,
95
+ })];
96
+ case 2:
97
+ // download from sec
98
+ _a.sent();
99
+ onDownloadComplete === null || onDownloadComplete === void 0 ? void 0 : onDownloadComplete();
100
+ if (!unzip) return [3 /*break*/, 4];
101
+ // unzip companyfacts.zip
102
+ return [4 /*yield*/, this.unzipper.unzip({
103
+ inputFilename: filename,
104
+ outputDirname: outputDirname,
105
+ deleteOriginal: true,
106
+ onError: function (err) { return reject(err); },
107
+ onChunk: onChunk ? function (data) { return onChunk === null || onChunk === void 0 ? void 0 : onChunk(__assign(__assign({}, data), { stage: 'unzip' })); } : undefined,
108
+ })];
109
+ case 3:
110
+ // unzip companyfacts.zip
111
+ _a.sent();
112
+ _a.label = 4;
113
+ case 4:
114
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete();
115
+ resolve(true);
116
+ return [3 /*break*/, 6];
117
+ case 5:
118
+ e_1 = _a.sent();
119
+ onError === null || onError === void 0 ? void 0 : onError(e_1);
120
+ reject(e_1);
121
+ return [3 /*break*/, 6];
122
+ case 6: return [2 /*return*/];
123
+ }
124
+ });
125
+ }); })];
126
+ });
127
+ });
128
+ };
129
+ return FactsDownloader;
130
+ }());
131
+ exports.default = FactsDownloader;
@@ -0,0 +1,40 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import * as fs from 'fs';
4
+ import { ReadStream } from 'fs';
5
+ import { ParseStream } from 'unzipper';
6
+ interface IFileManager {
7
+ createReadStream(path: string): ReadStream;
8
+ unlinkSync(path: string): void;
9
+ statSync(path: string): fs.Stats;
10
+ }
11
+ interface IFileUnzipper {
12
+ Extract(options: {
13
+ path: string;
14
+ }): ParseStream;
15
+ }
16
+ interface UnzipperArgs {
17
+ unzipper: IFileUnzipper;
18
+ fileManager: IFileManager;
19
+ }
20
+ interface OnChunkData {
21
+ percentComplete: number;
22
+ chunk: Buffer;
23
+ }
24
+ interface UnzipParams {
25
+ inputFilename: string;
26
+ outputDirname: string;
27
+ onChunk?: (data: OnChunkData) => void;
28
+ onError?: (err: Error) => void;
29
+ deleteOriginal?: boolean;
30
+ }
31
+ export interface IUnzipper {
32
+ unzip(params: UnzipParams): Promise<any>;
33
+ }
34
+ export default class Unzipper implements IUnzipper {
35
+ private readonly fileManager;
36
+ private readonly unzipper;
37
+ constructor(args?: UnzipperArgs);
38
+ unzip(params: UnzipParams): Promise<unknown>;
39
+ }
40
+ export {};