sec-edgar-api 0.0.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.
Files changed (84) hide show
  1. package/README.md +27 -0
  2. package/build/index.d.ts +21 -0
  3. package/build/index.js +26 -0
  4. package/build/services/FactFileReader/FactFileReader.d.ts +30 -0
  5. package/build/services/FactFileReader/FactFileReader.js +36 -0
  6. package/build/services/FactFileReader/index.d.ts +2 -0
  7. package/build/services/FactFileReader/index.js +4 -0
  8. package/build/services/ReportParser/FactIterator.d.ts +18 -0
  9. package/build/services/ReportParser/FactIterator.js +35 -0
  10. package/build/services/ReportParser/PropertyResolver.d.ts +25 -0
  11. package/build/services/ReportParser/PropertyResolver.js +44 -0
  12. package/build/services/ReportParser/ReportParser.d.ts +53 -0
  13. package/build/services/ReportParser/ReportParser.js +97 -0
  14. package/build/services/ReportParser/ReportRawParser.d.ts +34 -0
  15. package/build/services/ReportParser/ReportRawParser.js +154 -0
  16. package/build/services/ReportParser/ReportTranslatedProxy.d.ts +9 -0
  17. package/build/services/ReportParser/ReportTranslatedProxy.js +40 -0
  18. package/build/services/ReportParser/ReportWrapper.d.ts +27 -0
  19. package/build/services/ReportParser/ReportWrapper.js +89 -0
  20. package/build/services/ReportParser/index.d.ts +2 -0
  21. package/build/services/ReportParser/index.js +4 -0
  22. package/build/services/ReportParser/resolvers/helpers.d.ts +21 -0
  23. package/build/services/ReportParser/resolvers/helpers.js +49 -0
  24. package/build/services/ReportParser/resolvers/index.d.ts +31 -0
  25. package/build/services/ReportParser/resolvers/index.js +33 -0
  26. package/build/services/ReportParser/resolvers/resolve-asset-current.d.ts +2 -0
  27. package/build/services/ReportParser/resolvers/resolve-asset-current.js +20 -0
  28. package/build/services/ReportParser/resolvers/resolve-asset-non-current-ppe-gross.d.ts +2 -0
  29. package/build/services/ReportParser/resolvers/resolve-asset-non-current-ppe-gross.js +20 -0
  30. package/build/services/ReportParser/resolvers/resolve-cash-flow-capex.d.ts +5 -0
  31. package/build/services/ReportParser/resolvers/resolve-cash-flow-capex.js +37 -0
  32. package/build/services/ReportParser/resolvers/resolve-cash-flow-free.d.ts +2 -0
  33. package/build/services/ReportParser/resolvers/resolve-cash-flow-free.js +23 -0
  34. package/build/services/ReportParser/resolvers/resolve-cash-flow-operating.d.ts +2 -0
  35. package/build/services/ReportParser/resolvers/resolve-cash-flow-operating.js +39 -0
  36. package/build/services/ReportParser/resolvers/resolve-cash-flow-working-capital-non-cash.d.ts +2 -0
  37. package/build/services/ReportParser/resolvers/resolve-cash-flow-working-capital-non-cash.js +22 -0
  38. package/build/services/ReportParser/resolvers/resolve-ebit.d.ts +2 -0
  39. package/build/services/ReportParser/resolvers/resolve-ebit.js +25 -0
  40. package/build/services/ReportParser/resolvers/resolve-expense-depreciation.d.ts +2 -0
  41. package/build/services/ReportParser/resolvers/resolve-expense-depreciation.js +96 -0
  42. package/build/services/ReportParser/resolvers/resolve-expense-operating.d.ts +2 -0
  43. package/build/services/ReportParser/resolvers/resolve-expense-operating.js +22 -0
  44. package/build/services/ReportParser/resolvers/resolve-expense-total.d.ts +2 -0
  45. package/build/services/ReportParser/resolvers/resolve-expense-total.js +20 -0
  46. package/build/services/ReportParser/resolvers/resolve-fiscal-year-cumulative-properties.d.ts +5 -0
  47. package/build/services/ReportParser/resolvers/resolve-fiscal-year-cumulative-properties.js +70 -0
  48. package/build/services/ReportParser/resolvers/resolve-liability-current.d.ts +2 -0
  49. package/build/services/ReportParser/resolvers/resolve-liability-current.js +20 -0
  50. package/build/services/ReportParser/resolvers/resolve-q4-fiscal-year-matching-properties.d.ts +5 -0
  51. package/build/services/ReportParser/resolvers/resolve-q4-fiscal-year-matching-properties.js +24 -0
  52. package/build/services/ReportParser/resolvers/resolve-revenue-total.d.ts +2 -0
  53. package/build/services/ReportParser/resolvers/resolve-revenue-total.js +20 -0
  54. package/build/services/SecEdgarApi/Client.d.ts +44 -0
  55. package/build/services/SecEdgarApi/Client.js +104 -0
  56. package/build/services/SecEdgarApi/Downloader.d.ts +26 -0
  57. package/build/services/SecEdgarApi/Downloader.js +102 -0
  58. package/build/services/SecEdgarApi/FactsDownloader.d.ts +30 -0
  59. package/build/services/SecEdgarApi/FactsDownloader.js +125 -0
  60. package/build/services/SecEdgarApi/SecConnector.d.ts +47 -0
  61. package/build/services/SecEdgarApi/SecConnector.js +143 -0
  62. package/build/services/SecEdgarApi/SecEdgarApi.d.ts +92 -0
  63. package/build/services/SecEdgarApi/SecEdgarApi.js +184 -0
  64. package/build/services/SecEdgarApi/Throttler.d.ts +34 -0
  65. package/build/services/SecEdgarApi/Throttler.js +111 -0
  66. package/build/services/SecEdgarApi/Unzipper.d.ts +40 -0
  67. package/build/services/SecEdgarApi/Unzipper.js +40 -0
  68. package/build/services/SecEdgarApi/index.d.ts +3 -0
  69. package/build/services/SecEdgarApi/index.js +19 -0
  70. package/build/types/company-facts.type.d.ts +53 -0
  71. package/build/types/company-facts.type.js +2 -0
  72. package/build/types/index.d.ts +4 -0
  73. package/build/types/index.js +20 -0
  74. package/build/types/report-raw.type.d.ts +23 -0
  75. package/build/types/report-raw.type.js +2 -0
  76. package/build/types/report-translated.type.d.ts +58 -0
  77. package/build/types/report-translated.type.js +2 -0
  78. package/build/types/submission.type.d.ts +70 -0
  79. package/build/types/submission.type.js +2 -0
  80. package/build/util/cik-by-symbol.d.ts +5 -0
  81. package/build/util/cik-by-symbol.js +9632 -0
  82. package/build/util/key-translations.d.ts +7 -0
  83. package/build/util/key-translations.js +174 -0
  84. package/package.json +41 -0
@@ -0,0 +1,47 @@
1
+ import { CompanyFactFrame, CompanyFactListData, MultiCompanyFactFrame } from '../../types';
2
+ import { SubmissionList } from '../../types/submission.type';
3
+ import { IClient } from './Client';
4
+ import { IThrottler } from './Throttler';
5
+ interface SecApiArgs {
6
+ throttler: IThrottler;
7
+ client: IClient;
8
+ cikBySymbol: Record<string, number>;
9
+ }
10
+ export interface GetSymbolParams {
11
+ symbol: string;
12
+ }
13
+ export interface GetFactParams {
14
+ symbol: string;
15
+ fact: string;
16
+ taxonomy?: 'us-gaap' | 'dei' | 'invest' | string;
17
+ }
18
+ export interface GetFactFrameParams {
19
+ fact: string;
20
+ frame: string;
21
+ unit?: 'pure' | 'USD' | 'shares' | string;
22
+ taxonomy?: 'us-gaap' | 'dei' | 'invest' | string;
23
+ }
24
+ export interface ISecConnector {
25
+ getSubmissions(params: GetSymbolParams): Promise<SubmissionList>;
26
+ getFact(params: GetFactParams): Promise<CompanyFactFrame>;
27
+ getFacts(params: GetSymbolParams): Promise<CompanyFactListData>;
28
+ getFactFrame(params: GetFactFrameParams): Promise<MultiCompanyFactFrame>;
29
+ }
30
+ /**
31
+ * Gets reports from companies filed with the SEC
32
+ *
33
+ * @see https://www.sec.gov/edgar/sec-api-documentation
34
+ */
35
+ export default class SecConnector implements ISecConnector {
36
+ private readonly throttler;
37
+ private readonly client;
38
+ private readonly cikBySymbol;
39
+ constructor(args?: SecApiArgs);
40
+ private getCikString;
41
+ private request;
42
+ getSubmissions(params: GetSymbolParams): Promise<SubmissionList>;
43
+ getFact(params: GetFactParams): Promise<CompanyFactFrame>;
44
+ getFacts(params: GetSymbolParams): Promise<CompanyFactListData>;
45
+ getFactFrame(params: GetFactFrameParams): Promise<MultiCompanyFactFrame>;
46
+ }
47
+ export {};
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ 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;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var cik_by_symbol_1 = require("../../util/cik-by-symbol");
40
+ var Client_1 = require("./Client");
41
+ var Throttler_1 = require("./Throttler");
42
+ /**
43
+ * Gets reports from companies filed with the SEC
44
+ *
45
+ * @see https://www.sec.gov/edgar/sec-api-documentation
46
+ */
47
+ var SecConnector = /** @class */ (function () {
48
+ function SecConnector(args) {
49
+ if (args === void 0) { args = { client: new Client_1.default(), throttler: new Throttler_1.default(), cikBySymbol: cik_by_symbol_1.default }; }
50
+ var client = args.client, throttler = args.throttler, cikBySymbol = args.cikBySymbol;
51
+ this.client = client;
52
+ this.throttler = throttler;
53
+ this.cikBySymbol = cikBySymbol;
54
+ }
55
+ SecConnector.prototype.getCikString = function (symbol) {
56
+ var _a;
57
+ var cik = (_a = this.cikBySymbol[symbol]) !== null && _a !== void 0 ? _a : '';
58
+ return cik.toString().padStart(10, '0');
59
+ };
60
+ SecConnector.prototype.request = function (path) {
61
+ return __awaiter(this, void 0, void 0, function () {
62
+ var baseUrl;
63
+ var _this = this;
64
+ return __generator(this, function (_a) {
65
+ baseUrl = 'https://data.sec.gov';
66
+ return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
67
+ var _this = this;
68
+ return __generator(this, function (_a) {
69
+ this.throttler.add(function () { return __awaiter(_this, void 0, void 0, function () {
70
+ var response, responseData, e_1;
71
+ var _a, _b;
72
+ return __generator(this, function (_c) {
73
+ switch (_c.label) {
74
+ case 0:
75
+ _c.trys.push([0, 2, , 3]);
76
+ return [4 /*yield*/, this.client.request({
77
+ url: "".concat(baseUrl).concat(path),
78
+ onError: function (err) { return reject(err); },
79
+ })];
80
+ case 1:
81
+ response = _c.sent();
82
+ responseData = (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.toString('utf-8')) !== null && _b !== void 0 ? _b : null;
83
+ if (response.statusCode >= 400 || typeof responseData !== 'string') {
84
+ reject("Request failed with status ".concat(response.statusCode, " ").concat(response.message));
85
+ }
86
+ resolve(JSON.parse(responseData));
87
+ return [3 /*break*/, 3];
88
+ case 2:
89
+ e_1 = _c.sent();
90
+ reject(e_1);
91
+ return [3 /*break*/, 3];
92
+ case 3: return [2 /*return*/];
93
+ }
94
+ });
95
+ }); });
96
+ return [2 /*return*/];
97
+ });
98
+ }); })];
99
+ });
100
+ });
101
+ };
102
+ SecConnector.prototype.getSubmissions = function (params) {
103
+ return __awaiter(this, void 0, void 0, function () {
104
+ var symbol, cik;
105
+ return __generator(this, function (_a) {
106
+ symbol = params.symbol;
107
+ cik = this.getCikString(symbol);
108
+ return [2 /*return*/, this.request("/submissions/CIK".concat(cik, ".json"))];
109
+ });
110
+ });
111
+ };
112
+ SecConnector.prototype.getFact = function (params) {
113
+ return __awaiter(this, void 0, void 0, function () {
114
+ var symbol, fact, _a, taxonomy, cik;
115
+ return __generator(this, function (_b) {
116
+ symbol = params.symbol, fact = params.fact, _a = params.taxonomy, taxonomy = _a === void 0 ? 'us-gaap' : _a;
117
+ cik = this.getCikString(symbol);
118
+ return [2 /*return*/, this.request("/api/xbrl/companyconcept/CIK".concat(cik, "/").concat(taxonomy, "/").concat(fact, ".json"))];
119
+ });
120
+ });
121
+ };
122
+ SecConnector.prototype.getFacts = function (params) {
123
+ return __awaiter(this, void 0, void 0, function () {
124
+ var symbol, cik;
125
+ return __generator(this, function (_a) {
126
+ symbol = params.symbol;
127
+ cik = this.getCikString(symbol);
128
+ return [2 /*return*/, this.request("/api/xbrl/companyfacts/CIK".concat(cik, ".json"))];
129
+ });
130
+ });
131
+ };
132
+ SecConnector.prototype.getFactFrame = function (params) {
133
+ return __awaiter(this, void 0, void 0, function () {
134
+ var fact, frame, _a, taxonomy, _b, unit;
135
+ return __generator(this, function (_c) {
136
+ fact = params.fact, frame = params.frame, _a = params.taxonomy, taxonomy = _a === void 0 ? 'us-gaap' : _a, _b = params.unit, unit = _b === void 0 ? 'pure' : _b;
137
+ return [2 /*return*/, this.request("/api/xbrl/frames/".concat(taxonomy, "/").concat(fact, "/").concat(unit, "/").concat(frame, ".json"))];
138
+ });
139
+ });
140
+ };
141
+ return SecConnector;
142
+ }());
143
+ exports.default = SecConnector;
@@ -0,0 +1,92 @@
1
+ import { CompanyFactFrame, CompanyFactListData, MultiCompanyFactFrame, ReportRaw, SubmissionList } from '../../types';
2
+ import ReportParser from '../ReportParser';
3
+ import { ParseReportsOptions } from '../ReportParser/ReportRawParser';
4
+ import ReportWrapper from '../ReportParser/ReportWrapper';
5
+ import { DownloadCompanyFactsDirectoryParams, IFactsDownloader } from './FactsDownloader';
6
+ import { GetFactFrameParams, GetFactParams, GetSymbolParams, ISecConnector } from './SecConnector';
7
+ interface SecEdgarApiArgs {
8
+ secConnector: ISecConnector;
9
+ reportParser: ReportParser;
10
+ factsDownloader: IFactsDownloader;
11
+ }
12
+ /**
13
+ * Gets company reports and filings from the SEC EDGAR API
14
+ *
15
+ * Requests are throttled with 120ms delay between requests to avoid rate limiting
16
+ *
17
+ * @see https://www.sec.gov/edgar/sec-api-documentation
18
+ */
19
+ export default class SecEdgarApi {
20
+ private readonly reportParser;
21
+ private readonly secConnector;
22
+ private readonly factsDownloader;
23
+ constructor(args?: SecEdgarApiArgs);
24
+ /**
25
+ * endpoint: /submissions/CIK${cik}.json
26
+ *
27
+ * This JSON data structure contains metadata such as current name, former name,
28
+ * and stock exchanges and ticker symbols of publicly-traded companies. The object’s
29
+ * property path contains at least one year’s of filing or to 1,000 (whichever is more)
30
+ * of the most recent filings in a compact columnar data array. If the entity has
31
+ * additional filings, files will contain an array of additional JSON files and the
32
+ * date range for the filings each one contains.
33
+ */
34
+ getSubmissions(params: GetSymbolParams): Promise<SubmissionList>;
35
+ /**
36
+ * endpoint /api/xbrl/companyconcept/CIK${cik}/${taxonomy}/${fact}.json
37
+ *
38
+ * This API returns all the company concepts data for a company into a single API call:
39
+ */
40
+ getFacts(params: GetSymbolParams): Promise<CompanyFactListData>;
41
+ /**
42
+ * endpoint /api/xbrl/companyconcept/CIK${cik}/${taxonomy}/${fact}.json
43
+ *
44
+ * The company-concept API returns all the XBRL disclosures from a single company (CIK)
45
+ * and concept (a taxonomy and tag) into a single JSON file, with a separate array
46
+ * of facts for each units on measure that the company has chosen to disclose
47
+ * (e.g. net profits reported in U.S. dollars and in Canadian dollars).
48
+ */
49
+ getFact(params: GetFactParams): Promise<CompanyFactFrame>;
50
+ /**
51
+ * endpoint /api/xbrl/frames/${taxonomy}/${fact}/${unit}/${frame}.json
52
+ *
53
+ * The xbrl/frames API aggregates one fact for each reporting entity that is last filed
54
+ * that most closely fits the calendrical period requested. This API supports for annual,
55
+ * quarterly and instantaneous data:
56
+ *
57
+ * data.sec.gov/api/xbrl/frames/us-gaap/AccountsPayableCurrent/USD/CY2019Q1I.json
58
+ *
59
+ * Where the units of measure specified in the XBRL contains a numerator and a denominator,
60
+ * these are separated by “-per-” such as “USD-per-shares”. Note that the default unit
61
+ * in XBRL is “pure”.
62
+ *
63
+ * The period format is CY#### for annual data (duration 365 days +/- 30 days), CY####Q#
64
+ * for quarterly data (duration 91 days +/- 30 days), and CY####Q#I for instantaneous data.
65
+ * Because company financial calendars can start and end on any month or day and even
66
+ * change in length from quarter to quarter to according to the day of the week, the frame
67
+ * data is assembled by the dates that best align with a calendar quarter or year. Data
68
+ * users should be mindful different reporting start and end dates for facts contained
69
+ * in a frame.
70
+ */
71
+ getFactFrame(params: GetFactFrameParams): Promise<MultiCompanyFactFrame>;
72
+ /**
73
+ * Parses reports from company facts. Calculates missing properties and uses a single interface
74
+ * for all reports. This includes only 10-K and 10-Q annual and quarterly reports. To include
75
+ * all reports, use getReportsRaw
76
+ *
77
+ * Note that calculated properties are estimated if they are not available in the company facts.
78
+ */
79
+ getReports(params: GetSymbolParams): Promise<ReportWrapper[]>;
80
+ /**
81
+ * Parses reports from company facts. Calculates missing properties and uses a single interface
82
+ * for all reports.
83
+ */
84
+ getReportsRaw(params: GetSymbolParams & ParseReportsOptions): Promise<ReportRaw[]>;
85
+ /**
86
+ * Downloads the companyfacts.zip file and extracts the directory containing all company
87
+ * reports available from sec.gov. After downloading, you can use factFileReader and reportParser
88
+ * to get and read reports.
89
+ */
90
+ downloadCompanyFactsDirectory(params: DownloadCompanyFactsDirectoryParams): Promise<boolean>;
91
+ }
92
+ export {};
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ 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;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var ReportParser_1 = require("../ReportParser");
40
+ var FactsDownloader_1 = require("./FactsDownloader");
41
+ var SecConnector_1 = require("./SecConnector");
42
+ /**
43
+ * Gets company reports and filings from the SEC EDGAR API
44
+ *
45
+ * Requests are throttled with 120ms delay between requests to avoid rate limiting
46
+ *
47
+ * @see https://www.sec.gov/edgar/sec-api-documentation
48
+ */
49
+ var SecEdgarApi = /** @class */ (function () {
50
+ function SecEdgarApi(args) {
51
+ if (args === void 0) { args = {
52
+ secConnector: new SecConnector_1.default(),
53
+ reportParser: new ReportParser_1.default(),
54
+ factsDownloader: new FactsDownloader_1.default(),
55
+ }; }
56
+ var secConnector = args.secConnector, reportParser = args.reportParser, factsDownloader = args.factsDownloader;
57
+ this.secConnector = secConnector;
58
+ this.reportParser = reportParser;
59
+ this.factsDownloader = factsDownloader;
60
+ }
61
+ /**
62
+ * endpoint: /submissions/CIK${cik}.json
63
+ *
64
+ * This JSON data structure contains metadata such as current name, former name,
65
+ * and stock exchanges and ticker symbols of publicly-traded companies. The object’s
66
+ * property path contains at least one year’s of filing or to 1,000 (whichever is more)
67
+ * of the most recent filings in a compact columnar data array. If the entity has
68
+ * additional filings, files will contain an array of additional JSON files and the
69
+ * date range for the filings each one contains.
70
+ */
71
+ SecEdgarApi.prototype.getSubmissions = function (params) {
72
+ return __awaiter(this, void 0, void 0, function () {
73
+ return __generator(this, function (_a) {
74
+ return [2 /*return*/, this.secConnector.getSubmissions(params)];
75
+ });
76
+ });
77
+ };
78
+ /**
79
+ * endpoint /api/xbrl/companyconcept/CIK${cik}/${taxonomy}/${fact}.json
80
+ *
81
+ * This API returns all the company concepts data for a company into a single API call:
82
+ */
83
+ SecEdgarApi.prototype.getFacts = function (params) {
84
+ return __awaiter(this, void 0, void 0, function () {
85
+ return __generator(this, function (_a) {
86
+ return [2 /*return*/, this.secConnector.getFacts(params)];
87
+ });
88
+ });
89
+ };
90
+ /**
91
+ * endpoint /api/xbrl/companyconcept/CIK${cik}/${taxonomy}/${fact}.json
92
+ *
93
+ * The company-concept API returns all the XBRL disclosures from a single company (CIK)
94
+ * and concept (a taxonomy and tag) into a single JSON file, with a separate array
95
+ * of facts for each units on measure that the company has chosen to disclose
96
+ * (e.g. net profits reported in U.S. dollars and in Canadian dollars).
97
+ */
98
+ SecEdgarApi.prototype.getFact = function (params) {
99
+ return __awaiter(this, void 0, void 0, function () {
100
+ return __generator(this, function (_a) {
101
+ return [2 /*return*/, this.secConnector.getFact(params)];
102
+ });
103
+ });
104
+ };
105
+ /**
106
+ * endpoint /api/xbrl/frames/${taxonomy}/${fact}/${unit}/${frame}.json
107
+ *
108
+ * The xbrl/frames API aggregates one fact for each reporting entity that is last filed
109
+ * that most closely fits the calendrical period requested. This API supports for annual,
110
+ * quarterly and instantaneous data:
111
+ *
112
+ * data.sec.gov/api/xbrl/frames/us-gaap/AccountsPayableCurrent/USD/CY2019Q1I.json
113
+ *
114
+ * Where the units of measure specified in the XBRL contains a numerator and a denominator,
115
+ * these are separated by “-per-” such as “USD-per-shares”. Note that the default unit
116
+ * in XBRL is “pure”.
117
+ *
118
+ * The period format is CY#### for annual data (duration 365 days +/- 30 days), CY####Q#
119
+ * for quarterly data (duration 91 days +/- 30 days), and CY####Q#I for instantaneous data.
120
+ * Because company financial calendars can start and end on any month or day and even
121
+ * change in length from quarter to quarter to according to the day of the week, the frame
122
+ * data is assembled by the dates that best align with a calendar quarter or year. Data
123
+ * users should be mindful different reporting start and end dates for facts contained
124
+ * in a frame.
125
+ */
126
+ SecEdgarApi.prototype.getFactFrame = function (params) {
127
+ return __awaiter(this, void 0, void 0, function () {
128
+ return __generator(this, function (_a) {
129
+ return [2 /*return*/, this.secConnector.getFactFrame(params)];
130
+ });
131
+ });
132
+ };
133
+ /**
134
+ * Parses reports from company facts. Calculates missing properties and uses a single interface
135
+ * for all reports. This includes only 10-K and 10-Q annual and quarterly reports. To include
136
+ * all reports, use getReportsRaw
137
+ *
138
+ * Note that calculated properties are estimated if they are not available in the company facts.
139
+ */
140
+ SecEdgarApi.prototype.getReports = function (params) {
141
+ return __awaiter(this, void 0, void 0, function () {
142
+ var facts;
143
+ return __generator(this, function (_a) {
144
+ switch (_a.label) {
145
+ case 0: return [4 /*yield*/, this.getFacts(params)];
146
+ case 1:
147
+ facts = _a.sent();
148
+ return [2 /*return*/, this.reportParser.parseReports(facts)];
149
+ }
150
+ });
151
+ });
152
+ };
153
+ /**
154
+ * Parses reports from company facts. Calculates missing properties and uses a single interface
155
+ * for all reports.
156
+ */
157
+ SecEdgarApi.prototype.getReportsRaw = function (params) {
158
+ return __awaiter(this, void 0, void 0, function () {
159
+ var facts;
160
+ return __generator(this, function (_a) {
161
+ switch (_a.label) {
162
+ case 0: return [4 /*yield*/, this.getFacts(params)];
163
+ case 1:
164
+ facts = _a.sent();
165
+ return [2 /*return*/, this.reportParser.parseReportsRaw(facts)];
166
+ }
167
+ });
168
+ });
169
+ };
170
+ /**
171
+ * Downloads the companyfacts.zip file and extracts the directory containing all company
172
+ * reports available from sec.gov. After downloading, you can use factFileReader and reportParser
173
+ * to get and read reports.
174
+ */
175
+ SecEdgarApi.prototype.downloadCompanyFactsDirectory = function (params) {
176
+ return __awaiter(this, void 0, void 0, function () {
177
+ return __generator(this, function (_a) {
178
+ return [2 /*return*/, this.factsDownloader.downloadCompanyFactsDirectory(params)];
179
+ });
180
+ });
181
+ };
182
+ return SecEdgarApi;
183
+ }());
184
+ exports.default = SecEdgarApi;
@@ -0,0 +1,34 @@
1
+ interface OnProgressData {
2
+ queueLength: number;
3
+ countRunning: number;
4
+ }
5
+ interface ThrottlerArgs {
6
+ maxConcurrent?: number;
7
+ delayMs?: number;
8
+ onProgress?: (data: OnProgressData) => void;
9
+ onResult?: (result: any) => void;
10
+ onError?: (err: any) => void;
11
+ onEnd?: (results: any[], errors: any[]) => void;
12
+ }
13
+ export interface IThrottler {
14
+ setDelayMs(delayMs: number): void;
15
+ add: (fn: () => Promise<any>) => void;
16
+ }
17
+ export default class Throttler implements IThrottler {
18
+ private readonly queue;
19
+ private readonly results;
20
+ private readonly errors;
21
+ private countRunning;
22
+ private maxConcurrent;
23
+ private delayMs;
24
+ onProgress?: (data: OnProgressData) => void;
25
+ onResult?: (result: any) => void;
26
+ onError?: (err: any) => void;
27
+ onEnd?: (results: any[], errors: any[]) => void;
28
+ constructor(args?: ThrottlerArgs);
29
+ setMaxConcurrent(maxConcurrent: number): void;
30
+ setDelayMs(delayMs: number): void;
31
+ add(fn: () => Promise<any>): void;
32
+ private run;
33
+ }
34
+ export {};
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ 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;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var Throttler = /** @class */ (function () {
40
+ function Throttler(args) {
41
+ if (args === void 0) { args = {}; }
42
+ var _a = args.maxConcurrent, maxConcurrent = _a === void 0 ? 1 : _a, _b = args.delayMs, delayMs = _b === void 0 ? 120 : _b, onProgress = args.onProgress, onResult = args.onResult, onError = args.onError, onEnd = args.onEnd;
43
+ this.maxConcurrent = maxConcurrent;
44
+ this.delayMs = delayMs;
45
+ this.countRunning = 0;
46
+ this.queue = [];
47
+ this.results = [];
48
+ this.errors = [];
49
+ this.onProgress = onProgress;
50
+ this.onResult = onResult;
51
+ this.onError = onError;
52
+ this.onEnd = onEnd;
53
+ }
54
+ Throttler.prototype.setMaxConcurrent = function (maxConcurrent) {
55
+ this.maxConcurrent = maxConcurrent;
56
+ };
57
+ Throttler.prototype.setDelayMs = function (delayMs) {
58
+ this.delayMs = delayMs;
59
+ };
60
+ Throttler.prototype.add = function (fn) {
61
+ this.queue.push(fn);
62
+ this.run();
63
+ };
64
+ Throttler.prototype.run = function () {
65
+ var _a, _b, _c, _d;
66
+ return __awaiter(this, void 0, void 0, function () {
67
+ var fn, result, err_1;
68
+ var _this = this;
69
+ return __generator(this, function (_e) {
70
+ switch (_e.label) {
71
+ case 0:
72
+ if (this.countRunning >= this.maxConcurrent) {
73
+ return [2 /*return*/];
74
+ }
75
+ if (this.queue.length === 0) {
76
+ if (this.countRunning === 0) {
77
+ (_a = this.onEnd) === null || _a === void 0 ? void 0 : _a.call(this, this.results, this.errors);
78
+ }
79
+ return [2 /*return*/];
80
+ }
81
+ this.countRunning++;
82
+ fn = this.queue.shift();
83
+ _e.label = 1;
84
+ case 1:
85
+ _e.trys.push([1, 3, , 4]);
86
+ return [4 /*yield*/, fn()];
87
+ case 2:
88
+ result = _e.sent();
89
+ this.results.push(result);
90
+ (_b = this.onResult) === null || _b === void 0 ? void 0 : _b.call(this, result);
91
+ return [3 /*break*/, 4];
92
+ case 3:
93
+ err_1 = _e.sent();
94
+ this.errors.push(err_1);
95
+ (_c = this.onError) === null || _c === void 0 ? void 0 : _c.call(this, err_1);
96
+ return [3 /*break*/, 4];
97
+ case 4:
98
+ this.countRunning--;
99
+ (_d = this.onProgress) === null || _d === void 0 ? void 0 : _d.call(this, {
100
+ queueLength: this.queue.length,
101
+ countRunning: this.countRunning,
102
+ });
103
+ setTimeout(function () { return _this.run(); }, this.delayMs);
104
+ return [2 /*return*/];
105
+ }
106
+ });
107
+ });
108
+ };
109
+ return Throttler;
110
+ }());
111
+ exports.default = Throttler;
@@ -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 {};