sec-edgar-api 0.2.1 → 0.2.3

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 (40) hide show
  1. package/build/services/ReportBuilder/FactFiscalCalculator.d.ts +51 -0
  2. package/build/services/ReportBuilder/FactFiscalCalculator.js +232 -0
  3. package/build/services/ReportBuilder/FactPeriodResolver.d.ts +48 -0
  4. package/build/services/ReportBuilder/FactPeriodResolver.js +190 -0
  5. package/build/services/ReportBuilder/FactRecordBuilder.d.ts +10 -0
  6. package/build/services/ReportBuilder/FactRecordBuilder.js +71 -0
  7. package/build/services/ReportBuilder/FactSplitAdjuster.d.ts +46 -0
  8. package/build/services/ReportBuilder/FactSplitAdjuster.js +203 -0
  9. package/build/services/ReportBuilder/ReportBuilder.d.ts +40 -0
  10. package/build/services/ReportBuilder/ReportBuilder.js +186 -0
  11. package/build/services/ReportBuilder/ReportRawResolvable.d.ts +17 -0
  12. package/build/services/ReportBuilder/ReportRawResolvable.js +114 -0
  13. package/build/services/ReportBuilder/index.d.ts +2 -0
  14. package/build/services/ReportBuilder/index.js +4 -0
  15. package/build/services/ReportParser/PropertyResolver.d.ts +1 -0
  16. package/build/services/ReportParser/PropertyResolver.js +1 -0
  17. package/build/services/ReportParser/ReportParser.d.ts +4 -11
  18. package/build/services/ReportParser/ReportParser.js +15 -27
  19. package/build/services/ReportParser/ReportRawParser.d.ts +3 -32
  20. package/build/services/ReportParser/ReportRawParser.js +6 -146
  21. package/build/services/ReportParser/ReportWrapper.js +4 -5
  22. package/build/services/ReportParser/resolvers/index.d.ts +2 -0
  23. package/build/services/ReportParser/resolvers/index.js +2 -0
  24. package/build/services/ReportParser/resolvers/resolve-cash-flow-capex.js +4 -3
  25. package/build/services/ReportParser/resolvers/resolve-cash-flow-operating.js +1 -1
  26. package/build/services/ReportParser/resolvers/resolve-cash-flow-working-capital-non-cash.js +1 -1
  27. package/build/services/ReportParser/resolvers/resolve-expense-depreciation.js +1 -1
  28. package/build/services/ReportParser/resolvers/resolve-fiscal-year-cumulative-properties.js +30 -15
  29. package/build/services/ReportParser/resolvers/resolve-q4-fiscal-year-matching-properties.js +32 -4
  30. package/build/services/ReportParser/resolvers/resolve-split-ratio.d.ts +2 -0
  31. package/build/services/ReportParser/resolvers/resolve-split-ratio.js +37 -0
  32. package/build/services/SecEdgarApi/SecEdgarApi.d.ts +1 -2
  33. package/build/types/report-raw.type.d.ts +5 -6
  34. package/build/types/report-translated.type.d.ts +4 -2
  35. package/build/util/calculation-map-by-ns.d.ts +6 -0
  36. package/build/util/calculation-map-by-ns.js +9 -0
  37. package/build/util/key-translations.js +5 -2
  38. package/package.json +1 -1
  39. package/build/services/ReportParser/FactIterator.d.ts +0 -18
  40. package/build/services/ReportParser/FactIterator.js +0 -35
@@ -0,0 +1,203 @@
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
+ /**
15
+ * Adjust share-based property values for splits. Checks where the split was applied,
16
+ * and adjusts all previously filed share facts accordingly.
17
+ */
18
+ var FactSplitAdjuster = /** @class */ (function () {
19
+ function FactSplitAdjuster() {
20
+ this.splitKey = 'StockholdersEquityNoteStockSplitConversionRatio1';
21
+ this.splitByFiscalYearAmount = new Map();
22
+ this.factsByYearQuarterByPropertyName = new Map();
23
+ this.factsAnnaulByYearByPropertyName = new Map();
24
+ this.resolvedProperties = new Set();
25
+ this.sortedSplits = null;
26
+ }
27
+ FactSplitAdjuster.prototype.getMap = function (map, propertyName) {
28
+ var _a;
29
+ return (_a = map.get(propertyName)) !== null && _a !== void 0 ? _a : map.set(propertyName, new Map()).get(propertyName);
30
+ };
31
+ FactSplitAdjuster.prototype.add = function (fact) {
32
+ var propertyName = fact.name, year = fact.year, fiscalPeriod = fact.fiscalPeriod, unit = fact.unit, filed = fact.filed, value = fact.value, end = fact.end;
33
+ if (this.isSplitProperty(propertyName)) {
34
+ this.addSplitData({ end: end, filed: filed, fiscalYear: year, value: Number(value) });
35
+ return;
36
+ }
37
+ if (!this.isSplitAdjustableUnit(unit))
38
+ return;
39
+ if (this.resolvedProperties.has(propertyName)) {
40
+ throw new Error("Property ".concat(propertyName, " has already been resolved"));
41
+ }
42
+ var isAnnual = fiscalPeriod === 'FY';
43
+ var map = isAnnual
44
+ ? this.getMap(this.factsAnnaulByYearByPropertyName, propertyName)
45
+ : this.getMap(this.factsByYearQuarterByPropertyName, propertyName);
46
+ var key = "".concat(year, "_").concat(fiscalPeriod);
47
+ map.set(key, fact);
48
+ };
49
+ FactSplitAdjuster.prototype.getSplitsAsc = function () {
50
+ if (this.sortedSplits)
51
+ return this.sortedSplits;
52
+ var sortedSplits = Array.from(this.splitByFiscalYearAmount.values()).sort(function (a, b) {
53
+ return a.filed < b.filed ? -1 : 1;
54
+ });
55
+ this.sortedSplits = sortedSplits;
56
+ return sortedSplits;
57
+ };
58
+ FactSplitAdjuster.prototype.isSplitProperty = function (propertyName) {
59
+ return propertyName === this.splitKey;
60
+ };
61
+ FactSplitAdjuster.prototype.addSplitData = function (data) {
62
+ var end = data.end, filed = data.filed, fiscalYear = data.fiscalYear, value = data.value;
63
+ var split = value;
64
+ var key = "".concat(fiscalYear, "-").concat(split);
65
+ var prevSplit = this.splitByFiscalYearAmount.get(key);
66
+ if (!prevSplit) {
67
+ this.splitByFiscalYearAmount.set(key, __assign(__assign({}, data), { firstFiled: filed }));
68
+ this.sortedSplits = null;
69
+ return;
70
+ }
71
+ var curEnd = end;
72
+ var curFiled = filed;
73
+ var prevEnd = prevSplit.end;
74
+ var prevFiled = prevSplit.filed;
75
+ var shouldUpdateFactItem = !prevSplit || prevEnd < curEnd || (prevEnd === curEnd && prevFiled > curFiled);
76
+ var shouldUpdateFirstFiled = prevFiled > curFiled;
77
+ if (shouldUpdateFactItem) {
78
+ var curData = this.splitByFiscalYearAmount.get(key);
79
+ curData.end = end;
80
+ curData.filed = filed;
81
+ curData.value = value;
82
+ curData.fiscalYear = fiscalYear;
83
+ this.sortedSplits = null;
84
+ }
85
+ if (shouldUpdateFirstFiled) {
86
+ var curData = this.splitByFiscalYearAmount.get(key);
87
+ curData.firstFiled = curFiled;
88
+ this.sortedSplits = null;
89
+ }
90
+ };
91
+ /**
92
+ * TODO: Find a more reliable way of checking if the split has already been applied.
93
+ */
94
+ FactSplitAdjuster.prototype.didApplySplit = function (params) {
95
+ var nextValue = params.nextValue, prevValue = params.prevValue, split = params.split, isShareRatio = params.isShareRatio, value = params.value, filed = params.filed;
96
+ if (filed > split.filed) {
97
+ return true;
98
+ }
99
+ var dateFiled = new Date(filed);
100
+ // TODO: adust by adding a year because sometimes the already adjusted facts are filed within the
101
+ // year before the split. this might be because the split is listed under a different property? Look into this...
102
+ if (dateFiled.setFullYear(dateFiled.getFullYear() + 1) < new Date(split.firstFiled).getTime()) {
103
+ return false;
104
+ }
105
+ var valWithSplit = isShareRatio ? value / split.value : value * split.value;
106
+ // if we still don't know, see if applying the split puts us closer or further from the prev/next quarter value.
107
+ if (prevValue !== null) {
108
+ var difference = Math.abs(prevValue - value);
109
+ var differenceSplit = Math.abs(prevValue - valWithSplit);
110
+ return difference < differenceSplit;
111
+ }
112
+ if (nextValue !== null) {
113
+ var difference = Math.abs(nextValue - value);
114
+ var differenceSplit = Math.abs(nextValue - valWithSplit);
115
+ return difference < differenceSplit;
116
+ }
117
+ return true;
118
+ };
119
+ FactSplitAdjuster.prototype.isSplitAdjustableUnit = function (unit) {
120
+ return unit.toLowerCase().includes('share');
121
+ };
122
+ FactSplitAdjuster.prototype.isShareRatioUnit = function (unit) {
123
+ var unitLower = unit.toLowerCase();
124
+ return unitLower !== 'shares' && unitLower.includes('share'); // ex: USD/shares or USD-per-share
125
+ };
126
+ FactSplitAdjuster.prototype.getSortedFacts = function (propertyName, isAnnual) {
127
+ var _a, _b, _c;
128
+ var bucket = isAnnual ? this.factsAnnaulByYearByPropertyName : this.factsByYearQuarterByPropertyName;
129
+ var facts = Array.from((_b = (_a = bucket.get(propertyName)) === null || _a === void 0 ? void 0 : _a.values()) !== null && _b !== void 0 ? _b : []);
130
+ return (_c = facts.sort(function (a, b) { return (a.filed < b.filed ? -1 : 1); })) !== null && _c !== void 0 ? _c : [];
131
+ };
132
+ FactSplitAdjuster.prototype.resolveProperty = function (propertyName) {
133
+ if (this.resolvedProperties.has(propertyName))
134
+ return;
135
+ var factsAscQuarter = this.getSortedFacts(propertyName, false);
136
+ var factsAscAnnual = this.getSortedFacts(propertyName, true);
137
+ this.adjustValuesForSplits({ facts: factsAscQuarter });
138
+ this.adjustValuesForSplits({ facts: factsAscAnnual });
139
+ this.resolvedProperties.add(propertyName);
140
+ };
141
+ FactSplitAdjuster.prototype.get = function (propertyName, year, fiscalPeriod) {
142
+ var _a;
143
+ this.resolveProperty(propertyName);
144
+ var key = "".concat(year, "_").concat(fiscalPeriod);
145
+ var isAnnual = fiscalPeriod === 'FY';
146
+ var bucket = isAnnual ? this.factsAnnaulByYearByPropertyName : this.factsByYearQuarterByPropertyName;
147
+ var fact = (_a = bucket.get(propertyName)) === null || _a === void 0 ? void 0 : _a.get(key);
148
+ return fact === null || fact === void 0 ? void 0 : fact.value;
149
+ };
150
+ FactSplitAdjuster.prototype.forEach = function (callback) {
151
+ var _this = this;
152
+ this.factsByYearQuarterByPropertyName.forEach(function (factsByYearQuarter, propertyName) {
153
+ _this.resolveProperty(propertyName);
154
+ factsByYearQuarter.forEach(function (fact, key) {
155
+ var _a = key.split('_'), year = _a[0], fiscalPeriod = _a[1];
156
+ callback({ propertyName: propertyName, year: Number(year), fiscalPeriod: fiscalPeriod, value: Number(fact.value) });
157
+ });
158
+ });
159
+ this.factsAnnaulByYearByPropertyName.forEach(function (factsByYear, propertyName) {
160
+ _this.resolveProperty(propertyName);
161
+ factsByYear.forEach(function (fact, key) {
162
+ var _a = key.split('_'), year = _a[0], fiscalPeriod = _a[1];
163
+ callback({ propertyName: propertyName, year: Number(year), fiscalPeriod: fiscalPeriod, value: Number(fact.value) });
164
+ });
165
+ });
166
+ };
167
+ FactSplitAdjuster.prototype.adjustValuesForSplits = function (params) {
168
+ var _a, _b, _c, _d;
169
+ var facts = params.facts;
170
+ var splits = this.getSplitsAsc();
171
+ if (facts.length === 0 || splits.length === 0)
172
+ return;
173
+ var isShareRatio = this.isShareRatioUnit(facts[0].unit);
174
+ for (var splitIndex = splits.length - 1; splitIndex >= 0; splitIndex--) {
175
+ var split = splits[splitIndex];
176
+ for (var factIndex = facts.length - 1; factIndex >= 0; factIndex--) {
177
+ var fact = facts[factIndex];
178
+ var value = fact.value, filed = fact.filed;
179
+ var nextValue = (_b = (_a = facts[factIndex + 1]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null;
180
+ var prevValue = (_d = (_c = facts[factIndex - 1]) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : null;
181
+ var didApplySplit = this.didApplySplit({
182
+ filed: filed,
183
+ isShareRatio: isShareRatio,
184
+ nextValue: nextValue,
185
+ prevValue: prevValue,
186
+ split: split,
187
+ value: value,
188
+ });
189
+ if (didApplySplit || !split.value) {
190
+ continue;
191
+ }
192
+ if (isShareRatio) {
193
+ fact.value /= split.value;
194
+ }
195
+ else {
196
+ fact.value *= split.value;
197
+ }
198
+ }
199
+ }
200
+ };
201
+ return FactSplitAdjuster;
202
+ }());
203
+ exports.default = FactSplitAdjuster;
@@ -0,0 +1,40 @@
1
+ import { CompanyFactListData, FiscalPeriod, ReportRaw } from '../../types';
2
+ import { SetReportDatesParams } from './FactFiscalCalculator';
3
+ export interface FactItem {
4
+ cik: number | string;
5
+ end: string;
6
+ filed: string;
7
+ name: string;
8
+ unit: string;
9
+ value: number | string;
10
+ start?: string;
11
+ hasSegments?: boolean;
12
+ accn?: string;
13
+ form?: string;
14
+ fp?: string;
15
+ frame?: string;
16
+ fy?: number;
17
+ /** For XBRL reports only */
18
+ segments?: {
19
+ value: string;
20
+ dimension: string;
21
+ }[];
22
+ uuid?: string;
23
+ }
24
+ export interface FactItemWithFiscals extends FactItem {
25
+ fiscalPeriod: FiscalPeriod;
26
+ year: number;
27
+ }
28
+ /**
29
+ * Builds ReportRaw objects from facts. also applies splits and adjusts for fiscal periods.
30
+ */
31
+ export default class ReportBuilder {
32
+ private readonly factRecordBuilder;
33
+ createFacts(companyFacts: CompanyFactListData): {
34
+ facts: FactItem[];
35
+ };
36
+ buildReports(params: {
37
+ facts: FactItem[];
38
+ reportDates?: SetReportDatesParams[];
39
+ }): ReportRaw[];
40
+ }
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var FactFiscalCalculator_1 = require("./FactFiscalCalculator");
4
+ var FactPeriodResolver_1 = require("./FactPeriodResolver");
5
+ var FactRecordBuilder_1 = require("./FactRecordBuilder");
6
+ var FactSplitAdjuster_1 = require("./FactSplitAdjuster");
7
+ /**
8
+ * Builds ReportRaw objects from facts. also applies splits and adjusts for fiscal periods.
9
+ */
10
+ var ReportBuilder = /** @class */ (function () {
11
+ function ReportBuilder() {
12
+ this.factRecordBuilder = new FactRecordBuilder_1.default();
13
+ }
14
+ ReportBuilder.prototype.createFacts = function (companyFacts) {
15
+ return this.factRecordBuilder.createFacts(companyFacts);
16
+ };
17
+ ReportBuilder.prototype.buildReports = function (params) {
18
+ var _a, _b, _c, _d, _e;
19
+ var facts = params.facts, reportDates = params.reportDates;
20
+ if (facts.length === 0) {
21
+ return [];
22
+ }
23
+ var accessionByYearQuarter = new Map();
24
+ reportDates === null || reportDates === void 0 ? void 0 : reportDates.forEach(function (params) {
25
+ var year = params.year, quarter = params.quarter, accn = params.accn;
26
+ if (accn)
27
+ accessionByYearQuarter.set("".concat(year, "_").concat(quarter), accn);
28
+ });
29
+ var reportsCik = Number(facts[0].cik);
30
+ var factFiscalCalculator = new FactFiscalCalculator_1.default();
31
+ var factPeriodResolver = new FactPeriodResolver_1.default({ cik: reportsCik });
32
+ var factSplitAdjuster = new FactSplitAdjuster_1.default();
33
+ facts.forEach(function (fact) { return factFiscalCalculator.add(fact); });
34
+ reportDates === null || reportDates === void 0 ? void 0 : reportDates.forEach(function (params) { return factFiscalCalculator.setReportDates(params); });
35
+ var unitByPropertyName = new Map();
36
+ var splitDateDataByKey = new Map();
37
+ var minYear = Infinity;
38
+ var maxYear = -Infinity;
39
+ var countByAccnByYearQuarter = new Map();
40
+ var filedByPropertyYearQuarterValue = new Map();
41
+ for (var _i = 0, facts_1 = facts; _i < facts_1.length; _i++) {
42
+ var fact = facts_1[_i];
43
+ var end = fact.end, name_1 = fact.name, unit = fact.unit, segments = fact.segments, start = fact.start, value = fact.value, cik = fact.cik, form = fact.form, filed = fact.filed, accn = fact.accn;
44
+ if (Number(fact.cik) !== Number(reportsCik)) {
45
+ throw new Error("All facts must have the same cik ".concat(reportsCik, " !== ").concat(Number(cik)));
46
+ }
47
+ var segmentValue = segments === null || segments === void 0 ? void 0 : segments.map(function (seg) { return "".concat(seg.dimension, "_").concat(seg.value); }).join('&');
48
+ var propertyName = (_a = name_1.split(':').pop()) !== null && _a !== void 0 ? _a : '';
49
+ var propertyNameWithSegment = propertyName + (segmentValue ? "_".concat(segmentValue) : '');
50
+ var _f = factFiscalCalculator.getFiscalYearQuarter({ dateStr: end }), quarter = _f.quarter, year = _f.year;
51
+ if (year < minYear)
52
+ minYear = year;
53
+ if (year > maxYear)
54
+ maxYear = year;
55
+ var splitKey = "".concat(year, "_").concat(value);
56
+ var factFiledKey = "".concat(year, "_").concat(quarter, "_").concat(propertyNameWithSegment, "_").concat(value);
57
+ var isSplit = factSplitAdjuster.isSplitProperty(propertyName);
58
+ unitByPropertyName.set(propertyNameWithSegment, unit);
59
+ filedByPropertyYearQuarterValue.set(factFiledKey, filed);
60
+ if (isSplit && new Date(end) > new Date((_c = (_b = splitDateDataByKey.get(splitKey)) === null || _b === void 0 ? void 0 : _b.end) !== null && _c !== void 0 ? _c : 0)) {
61
+ splitDateDataByKey.set(splitKey, { end: end, quarter: quarter });
62
+ }
63
+ var accnKey = "".concat(year, "_").concat(quarter);
64
+ var accnGiven = accessionByYearQuarter.get(accnKey);
65
+ var filedDistance = Math.abs(new Date(filed).getTime() - new Date(end !== null && end !== void 0 ? end : 0).getTime()) / 86400000;
66
+ var isFiledRecent = filedDistance < 60;
67
+ if (!accnGiven && isFiledRecent && accn && (!form || form === '10-K' || form === '10-Q')) {
68
+ var countByAccn = (_d = countByAccnByYearQuarter.get(accnKey)) !== null && _d !== void 0 ? _d : new Map();
69
+ countByAccn.set(accn, ((_e = countByAccn.get(accn)) !== null && _e !== void 0 ? _e : 0) + 1);
70
+ countByAccnByYearQuarter.set(accnKey, countByAccn);
71
+ }
72
+ factPeriodResolver.add({
73
+ year: year,
74
+ start: start,
75
+ end: end,
76
+ name: propertyNameWithSegment,
77
+ quarter: quarter,
78
+ value: value,
79
+ filed: filed,
80
+ });
81
+ }
82
+ countByAccnByYearQuarter.forEach(function (countByAccn, yearQuarter) {
83
+ if (accessionByYearQuarter.has(yearQuarter))
84
+ return;
85
+ var maxCount = 0;
86
+ var accessionNumber = '';
87
+ countByAccn.forEach(function (count, accn) {
88
+ if (count > maxCount) {
89
+ maxCount = count;
90
+ accessionNumber = accn;
91
+ }
92
+ });
93
+ accessionByYearQuarter.set(yearQuarter, accessionNumber);
94
+ });
95
+ minYear = Number.isFinite(minYear) ? minYear : new Date().getFullYear();
96
+ maxYear = Number.isFinite(maxYear) ? maxYear : new Date().getFullYear();
97
+ var reportsByKey = new Map();
98
+ // resolves quarterly and annual properties and creates reports
99
+ factPeriodResolver.forEach(function (data) {
100
+ var _a, _b;
101
+ var fiscalPeriod = data.fiscalPeriod, propertyName = data.propertyName, value = data.value, year = data.year;
102
+ var key = "".concat(year, "_").concat(fiscalPeriod);
103
+ var quarter = fiscalPeriod === 'FY' ? 4 : Number(fiscalPeriod[1]);
104
+ var dates = factFiscalCalculator.getDatesByYearQuarter({ quarter: quarter, year: year });
105
+ var _c = dates !== null && dates !== void 0 ? dates : { filed: '', end: '' }, filed = _c.filed, end = _c.end;
106
+ var accessionNumber = accessionByYearQuarter.get("".concat(year, "_").concat(quarter));
107
+ var accessionNoHyphen = accessionNumber === null || accessionNumber === void 0 ? void 0 : accessionNumber.replace(/-/g, '');
108
+ var url = accessionNumber
109
+ ? "https://www.sec.gov/Archives/edgar/data/".concat(reportsCik, "/").concat(accessionNoHyphen, "/").concat(accessionNumber, ".txt")
110
+ : null;
111
+ if (!reportsByKey.has(key)) {
112
+ reportsByKey.set(key, {
113
+ cik: reportsCik,
114
+ url: url,
115
+ dateFiled: filed,
116
+ dateReport: end,
117
+ fiscalPeriod: fiscalPeriod,
118
+ fiscalYear: year,
119
+ splitDate: null,
120
+ splitRatio: null,
121
+ });
122
+ }
123
+ var filedKey = "".concat(year, "_").concat(quarter, "_").concat(propertyName, "_").concat(value);
124
+ // add facts to adjust for splits
125
+ factSplitAdjuster.add({
126
+ end: end,
127
+ // use the original fact filed date instead of the report filed date to know if the fact has been split.
128
+ filed: (_a = filedByPropertyYearQuarterValue.get(filedKey)) !== null && _a !== void 0 ? _a : filed,
129
+ fiscalPeriod: fiscalPeriod,
130
+ name: propertyName,
131
+ unit: (_b = unitByPropertyName.get(propertyName)) !== null && _b !== void 0 ? _b : '',
132
+ year: year,
133
+ value: Number(value),
134
+ accn: accessionNumber !== null && accessionNumber !== void 0 ? accessionNumber : '',
135
+ });
136
+ var report = reportsByKey.get(key);
137
+ report[propertyName] = value;
138
+ });
139
+ // iterate through facts adjustable for splits and assign values to reports
140
+ factSplitAdjuster.forEach(function (data) {
141
+ var year = data.year, fiscalPeriod = data.fiscalPeriod, propertyName = data.propertyName, value = data.value;
142
+ var key = "".concat(year, "_").concat(fiscalPeriod);
143
+ var report = reportsByKey.get(key);
144
+ if (!report)
145
+ return;
146
+ report[propertyName] = Math.round(value * 10000) / 10000;
147
+ });
148
+ // add split dates and values to reports
149
+ factSplitAdjuster.getSplitsAsc().forEach(function (split) {
150
+ var _a, _b, _c, _d;
151
+ var _e = factFiscalCalculator.getFiscalYearQuarter({ dateStr: split.end }), quarter = _e.quarter, year = _e.year;
152
+ var keySplit = "".concat(year, "_").concat(split.value);
153
+ var splitDateData = (_a = splitDateDataByKey.get(keySplit)) !== null && _a !== void 0 ? _a : { end: null, quarter: null };
154
+ var splitDate = (_b = splitDateData.end) !== null && _b !== void 0 ? _b : split.filed;
155
+ var splitQuarter = (_c = splitDateData.quarter) !== null && _c !== void 0 ? _c : quarter;
156
+ var fiscalPeriod = "Q".concat(splitQuarter);
157
+ var keyReport = "".concat(year, "_").concat(fiscalPeriod);
158
+ var report = reportsByKey.get(keyReport);
159
+ var reportAnnual = splitQuarter === 4 ? (_d = reportsByKey.get("".concat(year, "_FY"))) !== null && _d !== void 0 ? _d : null : null;
160
+ if (report) {
161
+ report.splitRatio = split.value;
162
+ report.splitDate = splitDate;
163
+ }
164
+ // also assign to annual for Q4
165
+ if (reportAnnual) {
166
+ reportAnnual.splitRatio = split.value;
167
+ reportAnnual.splitDate = splitDate;
168
+ }
169
+ });
170
+ // sort reports ASC by year and quarter
171
+ var reportsSorted = [];
172
+ for (var year = minYear; year <= maxYear; year++) {
173
+ for (var i = 0; i < 5; i++) {
174
+ var fiscalPeriod = i === 4 ? 'FY' : "Q".concat(i + 1);
175
+ var key = "".concat(year, "_").concat(fiscalPeriod);
176
+ var report = reportsByKey.get(key);
177
+ if (report && report.dateReport) {
178
+ reportsSorted.push(report);
179
+ }
180
+ }
181
+ }
182
+ return reportsSorted;
183
+ };
184
+ return ReportBuilder;
185
+ }());
186
+ exports.default = ReportBuilder;
@@ -0,0 +1,17 @@
1
+ import { ReportRaw } from '../../types';
2
+ export type TemplateCode = 'I' | 'T' | 'B' | 'M' | 'N' | 'U';
3
+ export default class ReportRawResolvable {
4
+ readonly report: ReportRaw;
5
+ private readonly emptyKeys;
6
+ private readonly addedProps;
7
+ private readonly calcMap;
8
+ private readonly templateCode;
9
+ private readonly keyStack;
10
+ constructor(report: ReportRaw, templateCode?: TemplateCode | null, calcMap?: Record<string, Record<string, string[]>>);
11
+ get(key: string): string | number | boolean | undefined;
12
+ getNumber(key: string): number;
13
+ isAdded(key: string): boolean;
14
+ private getChildKeysArr;
15
+ private calculateNumericKey;
16
+ toJSON(): ReportRaw;
17
+ }
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var calculation_map_by_ns_1 = require("../../util/calculation-map-by-ns");
4
+ var ReportRawResolvable = /** @class */ (function () {
5
+ function ReportRawResolvable(report, templateCode, calcMap) {
6
+ if (templateCode === void 0) { templateCode = null; }
7
+ if (calcMap === void 0) { calcMap = calculation_map_by_ns_1.calculationMapByNs; }
8
+ this.emptyKeys = new Set();
9
+ this.addedProps = new Set();
10
+ this.keyStack = new Set();
11
+ this.templateCode = templateCode !== null && templateCode !== void 0 ? templateCode : 'N';
12
+ this.report = report;
13
+ this.calcMap = calcMap;
14
+ }
15
+ ReportRawResolvable.prototype.get = function (key) {
16
+ var _a;
17
+ return (_a = this.report[key]) !== null && _a !== void 0 ? _a : this.calculateNumericKey(key, key);
18
+ };
19
+ ReportRawResolvable.prototype.getNumber = function (key) {
20
+ return Number(this.get(key)) || 0;
21
+ };
22
+ ReportRawResolvable.prototype.isAdded = function (key) {
23
+ return this.addedProps.has(key);
24
+ };
25
+ ReportRawResolvable.prototype.getChildKeysArr = function (key) {
26
+ var calcsByRole = this.calcMap[key];
27
+ if (calcsByRole === undefined) {
28
+ return [];
29
+ }
30
+ if (calcsByRole._) {
31
+ return [calcsByRole._];
32
+ }
33
+ var preferredKeys = [];
34
+ switch (this.templateCode) {
35
+ case 'I':
36
+ preferredKeys = [
37
+ 'StatementOfCashFlowsIndirectInvestmentBasedOperations',
38
+ 'StatementOfFinancialPositionUnclassified-InvestmentBasedOperations',
39
+ 'StatementOfCashFlowsIndirectDepositBasedOperations',
40
+ 'StatementOfFinancialPositionUnclassified-DepositBasedOperationsFirstAlternate',
41
+ 'StatementOfFinancialPositionUnclassified-DepositBasedOperations',
42
+ ];
43
+ break;
44
+ case 'B':
45
+ preferredKeys = [
46
+ 'StatementOfFinancialPositionUnclassified-DepositBasedOperationsFirstAlternate',
47
+ 'StatementOfFinancialPositionUnclassified-DepositBasedOperations',
48
+ ];
49
+ break;
50
+ }
51
+ var k = preferredKeys.find(function (k) { return calcsByRole[k]; });
52
+ if (!k) {
53
+ k = Object.keys(calcsByRole)[0];
54
+ }
55
+ return Object.keys(calcsByRole)
56
+ .sort(function (a, b) {
57
+ var indexA = preferredKeys.indexOf(a);
58
+ var indexB = preferredKeys.indexOf(b);
59
+ if (indexB === -1)
60
+ return -1;
61
+ if (indexA === -1)
62
+ return 1;
63
+ return indexA - indexB;
64
+ })
65
+ .map(function (k) { return calcsByRole[k]; });
66
+ };
67
+ ReportRawResolvable.prototype.calculateNumericKey = function (key, topLevelKey) {
68
+ var _a;
69
+ if (this.keyStack.has(key)) {
70
+ return undefined;
71
+ }
72
+ this.keyStack.add(key);
73
+ if (this.emptyKeys.has(key)) {
74
+ return undefined;
75
+ }
76
+ var childKeysArr = this.getChildKeysArr(key);
77
+ if (childKeysArr.length === 0) {
78
+ return undefined;
79
+ }
80
+ var didAdd = false;
81
+ var finalSum = 0;
82
+ for (var _i = 0, childKeysArr_1 = childKeysArr; _i < childKeysArr_1.length; _i++) {
83
+ var childKeys = childKeysArr_1[_i];
84
+ var sum = 0;
85
+ for (var _b = 0, childKeys_1 = childKeys; _b < childKeys_1.length; _b++) {
86
+ var k = childKeys_1[_b];
87
+ var _c = k.split('|'), childKey = _c[0], weightStr = _c[1];
88
+ var value = (_a = this.report[childKey]) !== null && _a !== void 0 ? _a : this.calculateNumericKey(childKey, topLevelKey);
89
+ if (typeof value !== 'number') {
90
+ continue;
91
+ }
92
+ didAdd = true;
93
+ sum += value * Number(weightStr);
94
+ }
95
+ if (sum === 0) {
96
+ continue;
97
+ }
98
+ finalSum = sum;
99
+ break;
100
+ }
101
+ if (!didAdd) {
102
+ this.emptyKeys.add(key);
103
+ return undefined;
104
+ }
105
+ this.report[key] = finalSum;
106
+ this.addedProps.add(key);
107
+ return finalSum;
108
+ };
109
+ ReportRawResolvable.prototype.toJSON = function () {
110
+ return this.report;
111
+ };
112
+ return ReportRawResolvable;
113
+ }());
114
+ exports.default = ReportRawResolvable;
@@ -0,0 +1,2 @@
1
+ import ReportBuilder from './ReportBuilder';
2
+ export default ReportBuilder;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var ReportBuilder_1 = require("./ReportBuilder");
4
+ exports.default = ReportBuilder_1.default;
@@ -18,6 +18,7 @@ export default class PropertyResolver {
18
18
  resolveLiabilityCurrent: typeof import("./resolvers/resolve-liability-current").resolveLiabilityCurrent;
19
19
  resolveQ4FiscalYearMatchingProperties: typeof import("./resolvers/resolve-q4-fiscal-year-matching-properties").resolveQ4FiscalYearMatchingProperties;
20
20
  resolveCashFlowWorkingCapitalNonCash: typeof import("./resolvers/resolve-cash-flow-working-capital-non-cash").resolveCashFlowWorkingCapitalNonCash;
21
+ resolveSplitRatio: typeof import("./resolvers/resolve-split-ratio").resolveSplitRatio;
21
22
  };
22
23
  });
23
24
  getDefaultResolvers(): typeof resolvers;
@@ -37,6 +37,7 @@ var PropertyResolver = /** @class */ (function () {
37
37
  _this.resolvers.resolveCashFlowOperating(report);
38
38
  _this.resolvers.resolveCashFlowCapex(report);
39
39
  _this.resolvers.resolveCashFlowFree(report);
40
+ _this.resolvers.resolveSplitRatio(report);
40
41
  });
41
42
  };
42
43
  return PropertyResolver;
@@ -1,7 +1,6 @@
1
1
  import { CompanyFactListData, ReportRaw, ReportTranslated } from '../../types';
2
- import { IterateFactsCallbackData } from './FactIterator';
3
2
  import PropertyResolver from './PropertyResolver';
4
- import ReportRawParser, { ParseReportsOptions } from './ReportRawParser';
3
+ import ReportRawParser from './ReportRawParser';
5
4
  import ReportWrapper from './ReportWrapper';
6
5
  interface ReportParserArgs {
7
6
  reportRawParser?: ReportRawParser;
@@ -24,7 +23,7 @@ export default class ReportParser {
24
23
  *
25
24
  * @param companyFactListData This is the json file contents of CIK[number].json file from the SEC website. You can find these using their API or by downloading the companyfacts.zip file: https://www.sec.gov/edgar/sec-api-documentation
26
25
  */
27
- parseReports(companyFactListData: Pick<CompanyFactListData, 'facts'>, usePropertyResolver?: boolean): ReportWrapper[];
26
+ parseReports(companyFactListData: CompanyFactListData, usePropertyResolver?: boolean): ReportWrapper[];
28
27
  /**
29
28
  * Same as parseReports but accepts ReportRaw[] instead of CompanyFactListData
30
29
  */
@@ -34,17 +33,11 @@ export default class ReportParser {
34
33
  *
35
34
  * @see https://www.sec.gov/edgar/sec-api-documentation
36
35
  */
37
- parseReportsRaw(companyFactListData: Pick<CompanyFactListData, 'facts'>, options?: ParseReportsOptions): ReportRaw[];
36
+ parseReportsRaw(companyFactListData: CompanyFactListData): ReportRaw[];
38
37
  /**
39
38
  * parseReportsRaw but removes meta data from the report
40
39
  */
41
- parseReportsRawNoMeta(companyFactListData: Pick<CompanyFactListData, 'facts'>, options?: ParseReportsOptions): Record<string, number>[];
42
- /**
43
- * Avoids deep nesting logic while iteratating through company facts
44
- *
45
- * @param callback called on each company fact.
46
- */
47
- iterateCompanyFacts(companyFactListData: Pick<CompanyFactListData, 'facts'>, callback: (data: IterateFactsCallbackData) => void): void;
40
+ parseReportsRawNoMeta(companyFactListData: CompanyFactListData): Record<string, number>[];
48
41
  /**
49
42
  * Translate ReportRaw to ReportTranslated by default, but can be used to translate to any object using both the callback and keyTranslator
50
43
  *