sec-edgar-api 0.5.1 → 0.5.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.
package/build/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import ReportParser from './services/ReportParser';
2
2
  import SecEdgarApi from './services/SecEdgarApi';
3
3
  import ReportResolvable from './services/ReportParser/ReportResolvable';
4
4
  import { utilMap } from './util/util-map';
5
+ import FactFiscalCalculator from './services/ReportRawBuilder/FactFiscalCalculator';
5
6
  /**
6
7
  * Takes company facts data from the SEC and translates them to
7
8
  * reports as json objects.
@@ -14,5 +15,5 @@ declare const reportParser: ReportParser;
14
15
  * @see https://www.sec.gov/edgar/sec-api-documentation
15
16
  */
16
17
  declare const secEdgarApi: SecEdgarApi;
17
- export { reportParser, secEdgarApi, ReportResolvable, utilMap };
18
+ export { reportParser, secEdgarApi, ReportResolvable, utilMap, FactFiscalCalculator };
18
19
  export type * from './types';
package/build/index.js CHANGED
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.utilMap = exports.ReportResolvable = exports.secEdgarApi = exports.reportParser = void 0;
3
+ exports.FactFiscalCalculator = exports.utilMap = exports.ReportResolvable = exports.secEdgarApi = exports.reportParser = void 0;
4
4
  var ReportParser_1 = require("./services/ReportParser");
5
5
  var SecEdgarApi_1 = require("./services/SecEdgarApi");
6
6
  var ReportResolvable_1 = require("./services/ReportParser/ReportResolvable");
7
7
  exports.ReportResolvable = ReportResolvable_1.default;
8
8
  var util_map_1 = require("./util/util-map");
9
9
  Object.defineProperty(exports, "utilMap", { enumerable: true, get: function () { return util_map_1.utilMap; } });
10
+ var FactFiscalCalculator_1 = require("./services/ReportRawBuilder/FactFiscalCalculator");
11
+ exports.FactFiscalCalculator = FactFiscalCalculator_1.default;
10
12
  /**
11
13
  * Takes company facts data from the SEC and translates them to
12
14
  * reports as json objects.
@@ -2,6 +2,7 @@ import { XMLParams } from '../../types';
2
2
  import { GetDocumentXbrlParams } from '../SecEdgarApi';
3
3
  import XMLParser from './XMLParserLegacy';
4
4
  import parsers from './parsers';
5
+ import { DocumentXbrlResult } from './parsers/parse-xbrl';
5
6
  interface DocumentParserArgs {
6
7
  parser?: XMLParser;
7
8
  parsersByName?: typeof parsers;
@@ -36,10 +37,6 @@ export default class DocumentParser {
36
37
  };
37
38
  parseCurrentFilings(params: XMLParams): import("../../types").CurrentFilingsList;
38
39
  parseCurrentFilingsXbrl(params: XMLParams): import("../../types").CurrentFilingsXBRL;
39
- parseXbrl(params: XMLParams & GetDocumentXbrlParams): import("./XBRLParser/XBRLParser").XbrlParseResult & {
40
- report: import("../../types").ReportRaw | null;
41
- facts: import("../../types").FactItemExtended[];
42
- xml: string;
43
- };
40
+ parseXbrl(params: XMLParams & GetDocumentXbrlParams): DocumentXbrlResult;
44
41
  }
45
42
  export {};
@@ -1,8 +1,17 @@
1
1
  import type { FactItemExtended, ReportRaw, XMLParams } from '../../../types';
2
2
  import { GetDocumentXbrlParams } from '../../SecEdgarApi';
3
3
  import { XbrlParseResult } from '../XBRLParser/XBRLParser';
4
- export declare function parseXbrl(params: XMLParams & GetDocumentXbrlParams): XbrlParseResult & {
4
+ interface ReportWithPeriod extends ReportRaw {
5
+ period: number;
6
+ startDate: string;
7
+ endDate: string;
8
+ }
9
+ export interface DocumentXbrlResult extends XbrlParseResult {
5
10
  report: ReportRaw | null;
6
11
  facts: FactItemExtended[];
7
12
  xml: string;
8
- };
13
+ /** Facts grouped into reports by their start and end dates */
14
+ periodReports: ReportWithPeriod[];
15
+ }
16
+ export declare function parseXbrl(params: XMLParams & GetDocumentXbrlParams): DocumentXbrlResult;
17
+ export {};
@@ -24,15 +24,19 @@ var __rest = (this && this.__rest) || function (s, e) {
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.parseXbrl = void 0;
26
26
  var constants_1 = require("../../../util/constants");
27
+ var FactFiscalCalculator_1 = require("../../ReportRawBuilder/FactFiscalCalculator");
28
+ var FactPeriodResolver_1 = require("../../ReportRawBuilder/FactPeriodResolver");
27
29
  var XBRLParser_1 = require("../XBRLParser/XBRLParser");
28
30
  function isWithinDays(params) {
29
31
  var dateA = params.dateA, dateB = params.dateB, days = params.days;
32
+ if (dateA === dateB)
33
+ return true;
30
34
  var timeDiff = Math.abs(new Date(dateA).getTime() - new Date(dateB).getTime());
31
35
  var daysDiff = timeDiff / (1000 * 3600 * 24);
32
36
  return daysDiff < days;
33
37
  }
34
38
  function buildReportsFromFacts(params) {
35
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
39
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
36
40
  var filing = params.filing, facts = params.facts, fiscalPeriod = params.fiscalPeriod, fiscalYear = params.fiscalYear, pathSeparator = params.pathSeparator, cikProp = params.cik;
37
41
  var urlParts = (_a = filing === null || filing === void 0 ? void 0 : filing.url.split('/')) !== null && _a !== void 0 ? _a : [];
38
42
  var cik = cikProp !== null && cikProp !== void 0 ? cikProp : urlParts[(_b = urlParts.indexOf('data')) !== null && _b !== void 0 ? _b : -1];
@@ -59,22 +63,49 @@ function buildReportsFromFacts(params) {
59
63
  var roundPlacesByName = new Map();
60
64
  var scaleByName = new Map();
61
65
  var isFocusFactByDateKey = new Map();
66
+ var dateYearEnd = new Date(reportFocus.dateReport);
67
+ var offsetByFiscalPeriod = { Q1: 9, Q2: 6, Q3: 3, Q4: 0, FY: 0 };
68
+ dateYearEnd.setMonth(dateYearEnd.getMonth() + ((_h = offsetByFiscalPeriod[reportFocus.fiscalPeriod]) !== null && _h !== void 0 ? _h : 0));
69
+ var fiscalCalculator = new FactFiscalCalculator_1.default({
70
+ filings: filing ? [filing] : undefined,
71
+ facts: facts,
72
+ fiscalYearEnd: { day: dateYearEnd.getDate(), month: dateYearEnd.getMonth() + 1 },
73
+ });
74
+ var fiscalsByDateKey = new Map();
62
75
  for (var _i = 0, facts_1 = facts; _i < facts_1.length; _i++) {
63
76
  var fact = facts_1[_i];
64
77
  var dateKey = fact.start ? "".concat(fact.start, "_").concat(fact.end) : fact.end;
65
- (_h = reportByDateRange[dateKey]) !== null && _h !== void 0 ? _h : (reportByDateRange[dateKey] = {
66
- startDate: (_j = fact.start) !== null && _j !== void 0 ? _j : '',
78
+ if (!fiscalsByDateKey.has(dateKey)) {
79
+ var _x = fiscalCalculator.getFiscalYearQuarter({ dateStr: fact.end }), quarter = _x.quarter, year = _x.year;
80
+ var period = FactPeriodResolver_1.default.getPeriod({ end: fact.end, start: fact.start });
81
+ var fiscalPeriod_1 = (period === 12 && quarter === 4 ? 'FY' : "Q".concat(quarter));
82
+ fiscalsByDateKey.set(dateKey, { fiscalYear: year, fiscalPeriod: fiscalPeriod_1 });
83
+ }
84
+ (_j = reportByDateRange[dateKey]) !== null && _j !== void 0 ? _j : (reportByDateRange[dateKey] = {
85
+ cik: reportFocus.cik,
86
+ url: '',
87
+ splitDate: (_k = splitFact === null || splitFact === void 0 ? void 0 : splitFact.end) !== null && _k !== void 0 ? _k : null,
88
+ splitRatio: (splitFact === null || splitFact === void 0 ? void 0 : splitFact.value) ? Number(splitFact.value) : null,
89
+ dateFiled: reportFocus.dateFiled,
90
+ dateReport: fact.end,
91
+ fiscalPeriod: (_l = fiscalsByDateKey.get(dateKey)) === null || _l === void 0 ? void 0 : _l.fiscalPeriod,
92
+ startDate: (_m = fact.start) !== null && _m !== void 0 ? _m : '',
67
93
  endDate: fact.end,
94
+ fiscalYear: (_o = fiscalsByDateKey.get(dateKey)) === null || _o === void 0 ? void 0 : _o.fiscalYear,
95
+ period: FactPeriodResolver_1.default.getPeriod({ start: fact.start, end: fact.end }),
68
96
  });
69
97
  var isSplitFact = fact === splitFact;
70
- var isFocusFact = (_k = isFocusFactByDateKey.get(dateKey)) !== null && _k !== void 0 ? _k : (isWithinDays({ dateA: fact.end, dateB: reportFocus.dateReport, days: 45 }) || isSplitFact);
98
+ var isFocusFact = (_p = isFocusFactByDateKey.get(dateKey)) !== null && _p !== void 0 ? _p : (isWithinDays({ dateA: fact.end, dateB: reportFocus.dateReport, days: 45 }) || isSplitFact);
99
+ if (isFocusFact) {
100
+ fact.isCurrentPeriod = true;
101
+ }
71
102
  if (!isSplitFact) {
72
103
  isFocusFactByDateKey.set(dateKey, isFocusFact);
73
104
  }
74
105
  var el = fact;
75
- var scale = Number((_l = el.scale) !== null && _l !== void 0 ? _l : 0) || 0;
76
- var decimals = Number((_m = el.decimals) !== null && _m !== void 0 ? _m : 0) || 0;
77
- var suffix = (_o = fact === null || fact === void 0 ? void 0 : fact.segments) === null || _o === void 0 ? void 0 : _o.map(function (_a) {
106
+ var scale = Number((_q = el.scale) !== null && _q !== void 0 ? _q : 0) || 0;
107
+ var decimals = Number((_r = el.decimals) !== null && _r !== void 0 ? _r : 0) || 0;
108
+ var suffix = (_s = fact === null || fact === void 0 ? void 0 : fact.segments) === null || _s === void 0 ? void 0 : _s.map(function (_a) {
78
109
  var dimension = _a.dimension, value = _a.value;
79
110
  return "".concat(dimension).concat(pathSeparator).concat(value);
80
111
  }).join(pathSeparator);
@@ -88,8 +119,8 @@ function buildReportsFromFacts(params) {
88
119
  var prevRounding = roundPlacesByName.get(prevFactKey);
89
120
  var prevScale = scaleByName.get(prevFactKey);
90
121
  var prevFact_1 = factByName.get(prevFactKey);
91
- var prevUnit = (_q = (_p = prevFact_1 === null || prevFact_1 === void 0 ? void 0 : prevFact_1.unit) === null || _p === void 0 ? void 0 : _p.split('_').pop()) === null || _q === void 0 ? void 0 : _q.toLowerCase();
92
- var unit = (_s = (_r = fact.unit) === null || _r === void 0 ? void 0 : _r.split('_').pop()) === null || _s === void 0 ? void 0 : _s.toLowerCase();
122
+ var prevUnit = (_u = (_t = prevFact_1 === null || prevFact_1 === void 0 ? void 0 : prevFact_1.unit) === null || _t === void 0 ? void 0 : _t.split('_').pop()) === null || _u === void 0 ? void 0 : _u.toLowerCase();
123
+ var unit = (_w = (_v = fact.unit) === null || _v === void 0 ? void 0 : _v.split('_').pop()) === null || _w === void 0 ? void 0 : _w.toLowerCase();
93
124
  var shouldSkip = [
94
125
  (prevUnit === null || prevUnit === void 0 ? void 0 : prevUnit.length) === 3 && (unit === null || unit === void 0 ? void 0 : unit.length) === 3 && prevUnit !== unit && prevUnit === 'usd',
95
126
  (prevRounding !== null && prevRounding !== void 0 ? prevRounding : 0) < roundPlaces,
@@ -177,7 +208,7 @@ function parseXbrl(params) {
177
208
  url: "https://www.sec.gov/Archives/edgar/data/".concat(cik, "/").concat(accessionNumberNoHyphens, "/").concat(accessionNumber, ".txt"),
178
209
  urlPrimaryDocument: '',
179
210
  },
180
- }), factsFiltered = _p.factsFiltered, reportFocus = _p.reportFocus;
181
- return __assign(__assign({}, response), { facts: factsFiltered, report: factsFiltered.length > 0 ? reportFocus : null, xml: xml });
211
+ }), factsFiltered = _p.factsFiltered, reportFocus = _p.reportFocus, reportByDateRange = _p.reportByDateRange;
212
+ return __assign(__assign({}, response), { facts: factsFiltered, report: factsFiltered.length > 0 ? reportFocus : null, xml: xml, periodReports: Object.values(reportByDateRange) });
182
213
  }
183
214
  exports.parseXbrl = parseXbrl;
@@ -31,16 +31,16 @@ export default class ReportParser {
31
31
  /**
32
32
  * Same as parseReports but accepts ReportRaw[] instead of CompanyFactListData
33
33
  */
34
- parseReportsFromRaw<T = ReportTranslated>(params: {
35
- reportsRaw: ReportRaw[];
34
+ translateReport<T = ReportTranslated>(params: {
35
+ report: ReportRaw;
36
36
  calculationMap?: CalculationMap<T>;
37
- }): (ReportRaw & T)[];
37
+ }): ReportRaw & T;
38
38
  /**
39
39
  * Parse raw reports
40
40
  *
41
41
  * @see https://www.sec.gov/edgar/sec-api-documentation
42
42
  */
43
- parseReportsRaw(companyFactListData: CompanyFactListData, options: Omit<BuildReportsParams, 'facts'> & {
43
+ parseReportsRaw(companyFactListData: CompanyFactListData, options?: Omit<BuildReportsParams, 'facts'> & {
44
44
  includeNamePrefix?: boolean;
45
45
  }): ReportRaw[];
46
46
  /**
@@ -48,6 +48,8 @@ export default class ReportParser {
48
48
  */
49
49
  buildReports(params: BuildReportsParams): ReportRaw[];
50
50
  /**
51
+ * @deprecated use translateReport
52
+ *
51
53
  * Translate ReportRaw to ReportTranslated by default, but can be used to translate to any object using both the callback and keyTranslator
52
54
  *
53
55
  * @param reportsRaw this is the output of parseReportsRaw
@@ -53,31 +53,32 @@ var ReportParser = /** @class */ (function () {
53
53
  /**
54
54
  * Same as parseReports but accepts ReportRaw[] instead of CompanyFactListData
55
55
  */
56
- ReportParser.prototype.parseReportsFromRaw = function (params) {
57
- var reportsRaw = params.reportsRaw, calculationMap = params.calculationMap;
56
+ ReportParser.prototype.translateReport = function (params) {
57
+ var _a;
58
+ var report = params.report, calculationMap = params.calculationMap;
58
59
  var calcMap = calculationMap !== null && calculationMap !== void 0 ? calculationMap : this.defaultCalculationMap;
59
- return reportsRaw.map(function (report) {
60
- var _a;
61
- var reportNew = {
62
- cik: report.cik,
63
- dateFiled: report.dateFiled,
64
- dateReport: report.dateReport,
65
- fiscalPeriod: report.fiscalPeriod,
66
- url: report.url,
67
- fiscalYear: report.fiscalYear,
68
- splitDate: report.splitDate,
69
- splitRatio: report.splitRatio,
70
- };
71
- var reportResolvable = new ReportResolvable_1.default({
72
- report: report,
73
- calculationMap: calcMap,
74
- });
75
- for (var key in calcMap) {
76
- var value = (_a = reportResolvable.get(key)) !== null && _a !== void 0 ? _a : null;
60
+ var reportNew = {
61
+ cik: report.cik,
62
+ dateFiled: report.dateFiled,
63
+ dateReport: report.dateReport,
64
+ fiscalPeriod: report.fiscalPeriod,
65
+ url: report.url,
66
+ fiscalYear: report.fiscalYear,
67
+ splitDate: report.splitDate,
68
+ splitRatio: report.splitRatio,
69
+ };
70
+ var reportResolvable = new ReportResolvable_1.default({
71
+ report: report,
72
+ calculationMap: calcMap,
73
+ });
74
+ for (var key in calcMap) {
75
+ var value = (_a = reportResolvable.get(key)) !== null && _a !== void 0 ? _a : null;
76
+ // use first truthy value
77
+ if (!reportNew[key]) {
77
78
  reportNew[key] = value;
78
79
  }
79
- return reportNew;
80
- });
80
+ }
81
+ return reportNew;
81
82
  };
82
83
  /**
83
84
  * Parse raw reports
@@ -85,7 +86,7 @@ var ReportParser = /** @class */ (function () {
85
86
  * @see https://www.sec.gov/edgar/sec-api-documentation
86
87
  */
87
88
  ReportParser.prototype.parseReportsRaw = function (companyFactListData, options) {
88
- var includeNamePrefix = options.includeNamePrefix;
89
+ var includeNamePrefix = (options !== null && options !== void 0 ? options : {}).includeNamePrefix;
89
90
  var facts = this.reportBuilder.createFacts(companyFactListData, includeNamePrefix).facts;
90
91
  return this.reportBuilder.buildReports(__assign({ facts: facts }, options));
91
92
  };
@@ -96,6 +97,8 @@ var ReportParser = /** @class */ (function () {
96
97
  return this.reportBuilder.buildReports(params);
97
98
  };
98
99
  /**
100
+ * @deprecated use translateReport
101
+ *
99
102
  * Translate ReportRaw to ReportTranslated by default, but can be used to translate to any object using both the callback and keyTranslator
100
103
  *
101
104
  * @param reportsRaw this is the output of parseReportsRaw
@@ -18,13 +18,16 @@ export default class FactFiscalCalculator {
18
18
  private readonly endDateCountMap;
19
19
  private readonly filedDateCountByEndDate;
20
20
  private didResolve;
21
+ private readonly fiscalYearEnd;
21
22
  constructor(params?: {
22
23
  facts?: Pick<FactItem, 'end' | 'filed'>[];
23
24
  filings?: Pick<FilingListItemTranslated, 'form' | 'reportDate' | 'filingDate' | 'accessionNumber'>[];
25
+ fiscalYearEnd?: {
26
+ month: number;
27
+ day: number;
28
+ } | null;
24
29
  });
25
- useFilingsForDates(params: {
26
- filings: Pick<FilingListItemTranslated, 'form' | 'reportDate' | 'filingDate' | 'accessionNumber'>[];
27
- }): void;
30
+ private useFilingsForDates;
28
31
  add(fact: {
29
32
  end: string;
30
33
  filed: string;
@@ -44,13 +47,21 @@ export default class FactFiscalCalculator {
44
47
  getFiscalYearQuarter(params: {
45
48
  dateStr: string;
46
49
  endDateByYear?: Map<number, Date>;
50
+ fiscalYearEnd?: {
51
+ month: number;
52
+ day: number;
53
+ } | null;
47
54
  }): {
48
55
  year: number;
49
56
  quarter: number;
50
57
  };
51
58
  static getFiscalYearQuarter(params: {
52
59
  dateStr: string;
53
- endDateByYear: Map<number, Date>;
60
+ endDateByYear?: Map<number, Date>;
61
+ fiscalYearEnd?: {
62
+ month: number;
63
+ day: number;
64
+ } | null;
54
65
  }): {
55
66
  quarter: number;
56
67
  year: number;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ var constants_1 = require("../../util/constants");
3
4
  /**
4
5
  * Gets the fiscal period for a given date. does this by checking when the FY end periods are,
5
6
  * Then measures the offset from the end date to the next/previous fiscal year end.
@@ -14,10 +15,10 @@ var FactFiscalCalculator = /** @class */ (function () {
14
15
  this.endDateCountMap = new Map();
15
16
  this.filedDateCountByEndDate = new Map();
16
17
  this.didResolve = false;
17
- var _a = params !== null && params !== void 0 ? params : {}, _b = _a.facts, facts = _b === void 0 ? [] : _b, _c = _a.filings, filings = _c === void 0 ? [] : _c;
18
- if (filings.length > 0) {
19
- this.useFilingsForDates({ filings: filings });
20
- }
18
+ this.fiscalYearEnd = null;
19
+ var _a = params !== null && params !== void 0 ? params : {}, _b = _a.facts, facts = _b === void 0 ? [] : _b, _c = _a.filings, filings = _c === void 0 ? [] : _c, fiscalYearEnd = _a.fiscalYearEnd;
20
+ this.fiscalYearEnd = fiscalYearEnd !== null && fiscalYearEnd !== void 0 ? fiscalYearEnd : null;
21
+ this.useFilingsForDates({ filings: filings });
21
22
  facts.forEach(function (fact) { return _this.add(fact); });
22
23
  }
23
24
  FactFiscalCalculator.prototype.useFilingsForDates = function (params) {
@@ -26,12 +27,12 @@ var FactFiscalCalculator = /** @class */ (function () {
26
27
  var endDateByYear = new Map();
27
28
  filings.forEach(function (_a) {
28
29
  var reportDate = _a.reportDate, form = _a.form;
29
- if (form === '10-K' || form === '20-F') {
30
+ if (constants_1.FORMS_EARNINGS_ANNUAL.includes(form)) {
30
31
  endDateByYear.set(Number(reportDate.substring(0, 4)), new Date(reportDate));
31
32
  }
32
33
  });
33
34
  filings.forEach(function (filing) {
34
- if (filing.form === '10-K' || filing.form === '10-Q' || filing.form === '20-F' || filing.form === '40-F') {
35
+ if (constants_1.FORMS_EARNINGS.includes(filing.form)) {
35
36
  var _a = _this.getFiscalYearQuarter({
36
37
  dateStr: filing.reportDate,
37
38
  endDateByYear: endDateByYear,
@@ -203,17 +204,25 @@ var FactFiscalCalculator = /** @class */ (function () {
203
204
  return (_a = this.datesByFiscals.get("".concat(params.year, "_").concat(params.quarter))) !== null && _a !== void 0 ? _a : null;
204
205
  };
205
206
  FactFiscalCalculator.prototype.getFiscalYearQuarter = function (params) {
206
- var dateStr = params.dateStr, _a = params.endDateByYear, endDateByYear = _a === void 0 ? this.endDateByYear : _a;
207
+ var dateStr = params.dateStr, _a = params.endDateByYear, endDateByYear = _a === void 0 ? this.endDateByYear : _a, _b = params.fiscalYearEnd, fiscalYearEnd = _b === void 0 ? this.fiscalYearEnd : _b;
207
208
  if (this.fiscalsByEndDate.has(dateStr)) {
208
209
  return this.fiscalsByEndDate.get(dateStr);
209
210
  }
210
- var fiscals = FactFiscalCalculator.getFiscalYearQuarter({ dateStr: dateStr, endDateByYear: endDateByYear });
211
+ var fiscals = FactFiscalCalculator.getFiscalYearQuarter({ dateStr: dateStr, endDateByYear: endDateByYear, fiscalYearEnd: fiscalYearEnd });
211
212
  this.fiscalsByEndDate.set(dateStr, fiscals);
212
213
  return fiscals;
213
214
  };
214
215
  FactFiscalCalculator.getFiscalYearQuarter = function (params) {
215
- var dateStr = params.dateStr, endDateByYear = params.endDateByYear;
216
- if (endDateByYear.size === 0) {
216
+ var _a;
217
+ var dateStr = params.dateStr, endDateByYearProp = params.endDateByYear, fiscalYearEnd = params.fiscalYearEnd;
218
+ var endDateByYear = endDateByYearProp !== null && endDateByYearProp !== void 0 ? endDateByYearProp : new Map();
219
+ if (fiscalYearEnd) {
220
+ var month = fiscalYearEnd.month, day = fiscalYearEnd.day;
221
+ var year = new Date().getFullYear();
222
+ var yearEndDate_1 = new Date("".concat(year, "-").concat(month, "-").concat(day));
223
+ endDateByYear.set(year, (_a = endDateByYear.get(year)) !== null && _a !== void 0 ? _a : yearEndDate_1);
224
+ }
225
+ if (!(endDateByYear === null || endDateByYear === void 0 ? void 0 : endDateByYear.size)) {
217
226
  throw new Error('No annual report dates provided');
218
227
  }
219
228
  var getYearEndDate = function (year) {
@@ -197,20 +197,9 @@ var FactPeriodResolver = /** @class */ (function () {
197
197
  var _this = this;
198
198
  this.propertiesByYear.forEach(function (properties, year) {
199
199
  properties.forEach(function (propertyName) {
200
- var _a, _b;
200
+ var _a;
201
201
  for (var i = 0; i < 4; i++) {
202
202
  var bucketSum = (_a = _this.sumByQuarterByPropertyByYear.get(year)) === null || _a === void 0 ? void 0 : _a.get(propertyName);
203
- var bucketQuarter = _this.getOrSetBucketArr(_this.valueByQuarterByPropertyByYear, year, propertyName);
204
- if (bucketSum && !bucketSum.has(i)) {
205
- var prevSum = 0;
206
- var quarterSum = 0;
207
- for (var j = 0; j < i; j++) {
208
- prevSum = quarterSum;
209
- quarterSum = (_b = bucketSum.get(j)) !== null && _b !== void 0 ? _b : quarterSum;
210
- }
211
- bucketSum.set(i, quarterSum);
212
- bucketQuarter.set(i, quarterSum - prevSum);
213
- }
214
203
  var value = bucketSum === null || bucketSum === void 0 ? void 0 : bucketSum.get(i);
215
204
  if (value === undefined)
216
205
  continue;
@@ -1,18 +1,26 @@
1
- import type { CompanyFactListData, FactGroup, FactItem, ReportRaw, SplitData } from '../../types';
2
- import FactFiscalCalculator, { SetReportDatesParams } from './FactFiscalCalculator';
1
+ import type { CompanyFactListData, FactGroup, FactItem, FilingListItemTranslated, ReportRaw, SplitData } from '../../types';
2
+ import FactFiscalCalculator from './FactFiscalCalculator';
3
3
  export interface BuildReportsParams {
4
4
  facts: FactItem[];
5
5
  /**
6
6
  * for more accurate dates, add this. Otherwise, dates will be inferred
7
7
  * using the fact periods. The filing and report dates can be found in the SubmissionList (segEdgarApi.getSubmissions)
8
8
  */
9
- reportDates?: SetReportDatesParams[];
9
+ filings?: Pick<FilingListItemTranslated, 'form' | 'reportDate' | 'filingDate' | 'accessionNumber'>[];
10
10
  /**
11
11
  * Splits will be extracted from facts if not provided.
12
12
  */
13
13
  splits?: SplitData[];
14
14
  resolvePeriodValues?: boolean;
15
15
  adjustForSplits?: boolean;
16
+ /**
17
+ * For member facts (facts with segments), the separator between the fact name and the segments.
18
+ */
19
+ pathSeparatorForMemberFacts?: string;
20
+ fiscalYearEnd?: {
21
+ month: number;
22
+ day: number;
23
+ } | null;
16
24
  }
17
25
  /**
18
26
  * Builds ReportRaw objects from company facts. Adjusts for splits and resolves period values.
@@ -22,7 +30,7 @@ export default class ReportRawBuilder {
22
30
  createFacts(companyFacts: CompanyFactListData, includeNamePrefix?: boolean): {
23
31
  facts: FactItem[];
24
32
  };
25
- private createFiscalCalculator;
33
+ private getFactKey;
26
34
  buildReports(params: BuildReportsParams): ReportRaw[];
27
35
  private createReportKey;
28
36
  private createReport;
@@ -1,5 +1,17 @@
1
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
+ };
2
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
+ var constants_1 = require("../../util/constants");
3
15
  var FactFiscalCalculator_1 = require("./FactFiscalCalculator");
4
16
  var FactGrouper_1 = require("./FactGrouper");
5
17
  var FactRecordBuilder_1 = require("./FactRecordBuilder");
@@ -15,43 +27,50 @@ var ReportRawBuilder = /** @class */ (function () {
15
27
  if (includeNamePrefix === void 0) { includeNamePrefix = false; }
16
28
  return this.factRecordBuilder.createFacts(companyFacts, includeNamePrefix);
17
29
  };
18
- ReportRawBuilder.prototype.createFiscalCalculator = function (params) {
19
- var facts = params.facts;
20
- var fiscalCalculator = new FactFiscalCalculator_1.default();
21
- for (var _i = 0, facts_1 = facts; _i < facts_1.length; _i++) {
22
- var fact = facts_1[_i];
23
- fiscalCalculator.add(fact);
24
- }
25
- return fiscalCalculator;
30
+ ReportRawBuilder.prototype.getFactKey = function (fact, pathSeparator) {
31
+ var _a;
32
+ var suffix = (_a = fact.segments) === null || _a === void 0 ? void 0 : _a.map(function (_a) {
33
+ var dimension = _a.dimension, value = _a.value;
34
+ return "".concat(dimension).concat(pathSeparator).concat(value);
35
+ }).join(pathSeparator);
36
+ return suffix ? "".concat(fact.name).concat(pathSeparator).concat(suffix) : fact.name;
26
37
  };
27
38
  ReportRawBuilder.prototype.buildReports = function (params) {
28
- var facts = params.facts, reportDates = params.reportDates, splitsProp = params.splits, _a = params.resolvePeriodValues, resolvePeriodValues = _a === void 0 ? true : _a, _b = params.adjustForSplits, adjustForSplits = _b === void 0 ? true : _b;
39
+ var _this = this;
40
+ var factsProp = params.facts, filings = params.filings, splitsProp = params.splits, _a = params.resolvePeriodValues, resolvePeriodValues = _a === void 0 ? true : _a, _b = params.adjustForSplits, adjustForSplits = _b === void 0 ? true : _b, _c = params.pathSeparatorForMemberFacts, pathSeparatorForMemberFacts = _c === void 0 ? '>' : _c, fiscalYearEnd = params.fiscalYearEnd;
41
+ // Rename member facts to prevent overwriting parent facts.
42
+ var facts = factsProp.map(function (fact) {
43
+ var factKey = _this.getFactKey(fact, pathSeparatorForMemberFacts);
44
+ return __assign(__assign({}, fact), { name: factKey });
45
+ });
29
46
  if (facts.length === 0) {
30
47
  return [];
31
48
  }
49
+ var reportsCik = Number(facts[0].cik);
50
+ var fiscalCalculator = new FactFiscalCalculator_1.default({
51
+ filings: filings === null || filings === void 0 ? void 0 : filings.filter(function (f) { return constants_1.FORMS_EARNINGS.includes(f.form); }),
52
+ facts: facts,
53
+ fiscalYearEnd: fiscalYearEnd,
54
+ });
32
55
  var accessionByYearQuarter = new Map();
33
- reportDates === null || reportDates === void 0 ? void 0 : reportDates.forEach(function (params) {
34
- var year = params.year, quarter = params.quarter, accn = params.accn;
35
- if (accn)
36
- accessionByYearQuarter.set("".concat(year, "_").concat(quarter), accn);
56
+ filings === null || filings === void 0 ? void 0 : filings.forEach(function (f) {
57
+ var _a = fiscalCalculator.getFiscalYearQuarter({ dateStr: f.reportDate }), year = _a.year, quarter = _a.quarter;
58
+ accessionByYearQuarter.set(f.accessionNumber, "".concat(year, "_").concat(quarter));
37
59
  });
38
- var reportsCik = Number(facts[0].cik);
39
- var fiscalCalculator = reportDates ? new FactFiscalCalculator_1.default() : this.createFiscalCalculator({ facts: facts });
40
- reportDates === null || reportDates === void 0 ? void 0 : reportDates.forEach(function (params) { return fiscalCalculator.setReportDates(params); });
41
60
  var factGrouper = new FactGrouper_1.default();
42
61
  var factSplitAdjuster = new FactSplitAdjuster_1.default();
43
62
  // if splits not included in params and need to adjust, extract from facts
44
63
  var splits = adjustForSplits
45
64
  ? splitsProp !== null && splitsProp !== void 0 ? splitsProp : factSplitAdjuster.getSplits({ splitFacts: factSplitAdjuster.filterSplitFacts({ facts: facts }) })
46
65
  : splitsProp;
47
- var _c = factGrouper.buildFactGroupsByReportKey({
66
+ var _d = factGrouper.buildFactGroupsByReportKey({
48
67
  facts: facts,
49
68
  cik: reportsCik,
50
69
  fiscalCalculator: fiscalCalculator,
51
70
  resolvePeriodValues: resolvePeriodValues,
52
71
  generateMissingGroups: false,
53
72
  splits: splits,
54
- }), factGroupsByReportKey = _c.factGroupsByReportKey, maxYear = _c.maxYear, minYear = _c.minYear;
73
+ }), factGroupsByReportKey = _d.factGroupsByReportKey, maxYear = _d.maxYear, minYear = _d.minYear;
55
74
  return this.buildReportsFromGroups({
56
75
  factGroupsByReportKey: factGroupsByReportKey,
57
76
  fiscalCalculator: fiscalCalculator,
@@ -231,11 +231,7 @@ export default class SecEdgarApi {
231
231
  *
232
232
  * Use "include" params to specify what to parse. If not provided, all data is parsed.
233
233
  */
234
- getDocumentXbrl(params: GetDocumentXbrlParams): Promise<import("../DocumentParser/XBRLParser/XBRLParser").XbrlParseResult & {
235
- report: ReportRaw | null;
236
- facts: import("../../types").FactItemExtended[];
237
- xml: string;
238
- }>;
234
+ getDocumentXbrl(params: GetDocumentXbrlParams): Promise<import("../DocumentParser/parsers/parse-xbrl").DocumentXbrlResult>;
239
235
  /**
240
236
  * Builds a url for a document. If fileName is not provided, it defaults to `${accessionNumber}.txt`
241
237
  *
@@ -302,17 +302,17 @@ var SecEdgarApi = /** @class */ (function () {
302
302
  */
303
303
  SecEdgarApi.prototype.getReports = function (params) {
304
304
  return __awaiter(this, void 0, void 0, function () {
305
- var calculationMap, reportsRaw;
305
+ var calculationMap, reports;
306
+ var _this = this;
306
307
  return __generator(this, function (_a) {
307
308
  switch (_a.label) {
308
309
  case 0:
309
310
  calculationMap = params.calculationMap;
310
311
  return [4 /*yield*/, this.getReportsRaw(__assign(__assign({}, params), { includeNamePrefix: true }))];
311
312
  case 1:
312
- reportsRaw = _a.sent();
313
- return [2 /*return*/, this.reportParser.parseReportsFromRaw({
314
- reportsRaw: reportsRaw,
315
- calculationMap: calculationMap,
313
+ reports = _a.sent();
314
+ return [2 /*return*/, reports.map(function (report) {
315
+ return _this.reportParser.translateReport({ report: report, calculationMap: calculationMap });
316
316
  })];
317
317
  }
318
318
  });
@@ -76,6 +76,7 @@ export interface FactItem {
76
76
  }
77
77
  export interface FactItemExtended extends FactItem {
78
78
  isUsedInReport?: boolean;
79
+ isCurrentPeriod?: boolean;
79
80
  decimals?: number;
80
81
  scale?: number;
81
82
  }
@@ -1,2 +1,4 @@
1
1
  declare const KEY_SPLIT = "StockholdersEquityNoteStockSplitConversionRatio1";
2
- export { KEY_SPLIT };
2
+ declare const FORMS_EARNINGS: string[];
3
+ declare const FORMS_EARNINGS_ANNUAL: string[];
4
+ export { KEY_SPLIT, FORMS_EARNINGS, FORMS_EARNINGS_ANNUAL };
@@ -1,5 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.KEY_SPLIT = void 0;
3
+ exports.FORMS_EARNINGS_ANNUAL = exports.FORMS_EARNINGS = exports.KEY_SPLIT = void 0;
4
4
  var KEY_SPLIT = 'StockholdersEquityNoteStockSplitConversionRatio1';
5
5
  exports.KEY_SPLIT = KEY_SPLIT;
6
+ var FORMS_EARNINGS = ['10-Q', '10-K', '20-F', '40-F'];
7
+ exports.FORMS_EARNINGS = FORMS_EARNINGS;
8
+ var FORMS_EARNINGS_ANNUAL = ['10-K', '20-F', '40-F'];
9
+ exports.FORMS_EARNINGS_ANNUAL = FORMS_EARNINGS_ANNUAL;
@@ -1,5 +1,7 @@
1
1
  import type { ReportTranslated } from '../types/report-translated.type';
2
2
  /**
3
+ * @deprecated use calculationMap for ReportResolvable
4
+ *
3
5
  * Checks if any of the array keys exist in the object to assign to the translated key
4
6
  * These were checked against Yahoo Finance values, adding the ones that most often matched the yahoo values
5
7
  */
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  /**
4
+ * @deprecated use calculationMap for ReportResolvable
5
+ *
4
6
  * Checks if any of the array keys exist in the object to assign to the translated key
5
7
  * These were checked against Yahoo Finance values, adding the ones that most often matched the yahoo values
6
8
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sec-edgar-api",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Fetch and parse SEC earnings reports and other filings. Useful for financial analysis.",
5
5
  "main": "build/index.js",
6
6
  "author": "Andrew Evers (https://github.com/andyevers)",