sec-edgar-api 1.0.7 → 1.0.8

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.
@@ -15,8 +15,8 @@ export interface XbrlFilingSummary {
15
15
  reportFormat: string;
16
16
  reports: XbrlFilingSummaryReport[];
17
17
  }
18
- type XbrlFilingSummaryMenuCategory = 'Cover' | 'Statements' | 'Notes' | 'Policies' | 'Tables' | 'Details';
19
- type XbrlFilingSummaryReportType = 'Sheet' | 'Notes' | 'Book';
18
+ export type XbrlFilingSummaryMenuCategory = 'Cover' | 'Statements' | 'Notes' | 'Policies' | 'Tables' | 'Details';
19
+ export type XbrlFilingSummaryReportType = 'Sheet' | 'Notes' | 'Book';
20
20
  export interface XbrlFilingSummaryReport {
21
21
  longName: string;
22
22
  shortName: string;
@@ -38,4 +38,3 @@ export default class FilingSummaryParser {
38
38
  private toText;
39
39
  parse(xml: string): XbrlFilingSummary | null;
40
40
  }
41
- export {};
@@ -0,0 +1,36 @@
1
+ import { DocumentXbrlResult } from '../services/DocumentParser/parsers/parse-xbrl';
2
+ import { XbrlFilingSummaryReport } from '../services/DocumentParser/XBRLParser/FilingSummaryParser';
3
+ export interface XbrlFilingSummaryReportWithTrees extends XbrlFilingSummaryReport {
4
+ calculationTree: TreeNode[];
5
+ presentationTree: TreeNode[];
6
+ }
7
+ export type MemberInclusionRule = 'always' | 'inReportsWherePresent' | 'never';
8
+ interface TreeNode {
9
+ label: string;
10
+ value: number | string | null;
11
+ unit: string;
12
+ period: number;
13
+ key: string;
14
+ isPeriodStart: boolean;
15
+ weight: number;
16
+ members?: MemberFact[];
17
+ children?: TreeNode[];
18
+ }
19
+ interface MemberFact {
20
+ segments: {
21
+ dimension: string;
22
+ value: string;
23
+ }[];
24
+ value: string | number | null;
25
+ }
26
+ export interface BuildReportTreesParams {
27
+ xbrlJson: DocumentXbrlResult;
28
+ /**
29
+ * Where members should be included in the tree nodes.
30
+ *
31
+ * @default 'inReportsWherePresent'
32
+ */
33
+ memberInclusionRule?: MemberInclusionRule;
34
+ }
35
+ export declare function buildReportTrees(params: BuildReportTreesParams): XbrlFilingSummaryReportWithTrees[];
36
+ export {};
@@ -0,0 +1,209 @@
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
+ exports.buildReportTrees = void 0;
15
+ function hrefToKey(href) {
16
+ var fragment = href.split('#').pop() || '';
17
+ return fragment.replace('_', ':');
18
+ }
19
+ function getLabelTypeByHref(linkbase) {
20
+ var _a, _b, _c, _d;
21
+ var labelLink = (_a = linkbase === null || linkbase === void 0 ? void 0 : linkbase.labelLink) === null || _a === void 0 ? void 0 : _a[0];
22
+ var labelLocByHref = new Map((_b = labelLink === null || labelLink === void 0 ? void 0 : labelLink.loc) === null || _b === void 0 ? void 0 : _b.map(function (l) { return [l.href, l]; }));
23
+ var labelArcByFrom = new Map((_c = labelLink === null || labelLink === void 0 ? void 0 : labelLink.labelArc) === null || _c === void 0 ? void 0 : _c.map(function (l) { return [l.from, l]; }));
24
+ var labelByTypeByLabelId = new Map();
25
+ (_d = labelLink === null || labelLink === void 0 ? void 0 : labelLink.label) === null || _d === void 0 ? void 0 : _d.forEach(function (l) {
26
+ var _a;
27
+ var bucket = (_a = labelByTypeByLabelId.get(l.label)) !== null && _a !== void 0 ? _a : labelByTypeByLabelId.set(l.label, {}).get(l.label);
28
+ bucket[l.type.substring(l.type.lastIndexOf('/') + 1)] = l.text;
29
+ });
30
+ var labelByTypeByHref = new Map();
31
+ labelLocByHref.forEach(function (locator, href) {
32
+ var _a, _b, _c;
33
+ labelByTypeByHref.set(href, (_c = labelByTypeByLabelId.get((_b = (_a = labelArcByFrom.get(locator.label)) === null || _a === void 0 ? void 0 : _a.to) !== null && _b !== void 0 ? _b : '')) !== null && _c !== void 0 ? _c : {});
34
+ });
35
+ return labelByTypeByHref;
36
+ }
37
+ function getBestLabel(params) {
38
+ var _a;
39
+ var href = params.href, labelByHref = params.labelByHref, preferredLabel = params.preferredLabel;
40
+ var bucket = labelByHref.get(href);
41
+ if (!bucket)
42
+ return null;
43
+ // try getting preferred label
44
+ var preferredLabelType = preferredLabel === null || preferredLabel === void 0 ? void 0 : preferredLabel.substring((preferredLabel === null || preferredLabel === void 0 ? void 0 : preferredLabel.lastIndexOf('/')) + 1);
45
+ if (preferredLabelType && bucket[preferredLabelType])
46
+ return bucket[preferredLabelType];
47
+ // if not provided, choose first of these.
48
+ for (var _i = 0, _b = ['verboseLabel', 'terseLabel', 'label', 'periodEndLabel']; _i < _b.length; _i++) {
49
+ var type = _b[_i];
50
+ if (bucket[type])
51
+ return bucket[type];
52
+ }
53
+ // return whatever is left
54
+ return (_a = Object.values(bucket)[0]) !== null && _a !== void 0 ? _a : null;
55
+ }
56
+ function getPeriodFacts(params) {
57
+ var _a;
58
+ var factsByConcept = params.factsByConcept, conceptKey = params.conceptKey, isPeriodStart = params.isPeriodStart;
59
+ var facts = (_a = factsByConcept.get(conceptKey)) !== null && _a !== void 0 ? _a : [];
60
+ var primaryFacts = facts.filter(function (f) { return f.isCurrentPeriod; });
61
+ if (!isPeriodStart || primaryFacts.length === 0)
62
+ return primaryFacts;
63
+ var primaryFact = primaryFacts[0];
64
+ var maxEnd = facts.reduce(function (max, f) { return (f.end > max && f.end < primaryFact.end ? f.end : max); }, '0000-00-00');
65
+ return facts.filter(function (f) { return !f.isCurrentPeriod && f.end === maxEnd; });
66
+ }
67
+ function extractMemberFacts(facts, memberInclusionRule, allowedMembers) {
68
+ if (memberInclusionRule === 'never')
69
+ return [];
70
+ var allMembers = facts
71
+ .filter(function (f) { var _a, _b; return ((_b = (_a = f.segments) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0; })
72
+ .map(function (f) { return ({ value: f.value, segments: f.segments }); });
73
+ if (memberInclusionRule === 'always')
74
+ return allMembers;
75
+ return allMembers.filter(function (m) {
76
+ return m.segments.every(function (s) { return (allowedMembers === null || allowedMembers === void 0 ? void 0 : allowedMembers.has(s.value)) && (allowedMembers === null || allowedMembers === void 0 ? void 0 : allowedMembers.has(s.dimension)); });
77
+ });
78
+ }
79
+ function extractPrimaryFact(facts) {
80
+ var _a;
81
+ return (_a = facts.find(function (f) { var _a, _b; return !((_b = (_a = f.segments) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0); })) !== null && _a !== void 0 ? _a : null;
82
+ }
83
+ function buildTemplateHierarchyFlat(params) {
84
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
85
+ var arcs = params.arcs, labelByHref = params.labelByHref, locByLabel = params.locByLabel, factsByConcept = params.factsByConcept, allowedMembers = params.allowedMembers, _o = params.memberInclusionRule, memberInclusionRule = _o === void 0 ? 'inReportsWherePresent' : _o;
86
+ var itemsById = new Map();
87
+ for (var _i = 0, arcs_1 = arcs; _i < arcs_1.length; _i++) {
88
+ var arc = arcs_1[_i];
89
+ var hrefFrom = (_b = (_a = locByLabel.get(arc.from)) === null || _a === void 0 ? void 0 : _a.href) !== null && _b !== void 0 ? _b : '';
90
+ var hrefTo = (_d = (_c = locByLabel.get(arc.to)) === null || _c === void 0 ? void 0 : _c.href) !== null && _d !== void 0 ? _d : '';
91
+ var keyFrom = hrefToKey(hrefFrom);
92
+ var keyTo = hrefToKey(hrefTo);
93
+ var isPeriodStart = (_f = (_e = arc.preferredLabel) === null || _e === void 0 ? void 0 : _e.endsWith('periodStartLabel')) !== null && _f !== void 0 ? _f : false;
94
+ if (!itemsById.has(arc.from)) {
95
+ var periodFactsFrom = getPeriodFacts({ conceptKey: keyFrom, factsByConcept: factsByConcept, isPeriodStart: isPeriodStart });
96
+ var membersFrom = extractMemberFacts(periodFactsFrom, memberInclusionRule, allowedMembers);
97
+ var primaryFactFrom = extractPrimaryFact(periodFactsFrom);
98
+ itemsById.set(arc.from, {
99
+ id: arc.from,
100
+ parentId: null,
101
+ key: keyFrom,
102
+ parentKey: null,
103
+ weight: 1,
104
+ order: 0,
105
+ label: (_g = getBestLabel({ href: hrefFrom, labelByHref: labelByHref, preferredLabel: arc.preferredLabel })) !== null && _g !== void 0 ? _g : keyFrom,
106
+ isPeriodStart: isPeriodStart,
107
+ period: (primaryFactFrom === null || primaryFactFrom === void 0 ? void 0 : primaryFactFrom.period) || 0,
108
+ value: (_h = primaryFactFrom === null || primaryFactFrom === void 0 ? void 0 : primaryFactFrom.value) !== null && _h !== void 0 ? _h : null,
109
+ unit: (_j = primaryFactFrom === null || primaryFactFrom === void 0 ? void 0 : primaryFactFrom.unit) !== null && _j !== void 0 ? _j : '',
110
+ members: membersFrom,
111
+ children: [],
112
+ });
113
+ }
114
+ var periodFactsTo = getPeriodFacts({ conceptKey: keyTo, factsByConcept: factsByConcept, isPeriodStart: isPeriodStart });
115
+ var membersTo = extractMemberFacts(periodFactsTo, memberInclusionRule, allowedMembers);
116
+ var primaryFactTo = extractPrimaryFact(periodFactsTo);
117
+ var hierarchyTo = {
118
+ id: arc.to,
119
+ parentId: arc.from,
120
+ key: keyTo,
121
+ parentKey: arc.from ? hrefToKey(hrefFrom) : null,
122
+ weight: arc.weight || 1,
123
+ order: arc.order || 0,
124
+ label: (_k = getBestLabel({ href: hrefTo, labelByHref: labelByHref, preferredLabel: arc.preferredLabel })) !== null && _k !== void 0 ? _k : keyTo,
125
+ isPeriodStart: isPeriodStart,
126
+ period: (primaryFactTo === null || primaryFactTo === void 0 ? void 0 : primaryFactTo.period) || 0,
127
+ value: (_l = primaryFactTo === null || primaryFactTo === void 0 ? void 0 : primaryFactTo.value) !== null && _l !== void 0 ? _l : null,
128
+ unit: (_m = primaryFactTo === null || primaryFactTo === void 0 ? void 0 : primaryFactTo.unit) !== null && _m !== void 0 ? _m : '',
129
+ members: membersTo,
130
+ children: [],
131
+ };
132
+ if (!itemsById.has(arc.to)) {
133
+ itemsById.set(arc.to, hierarchyTo);
134
+ }
135
+ else {
136
+ Object.assign(itemsById.get(arc.to), hierarchyTo);
137
+ }
138
+ itemsById.get(arc.from).children.push(itemsById.get(arc.to));
139
+ }
140
+ return itemsById;
141
+ }
142
+ function hierarchyToTree(itemsById) {
143
+ itemsById.forEach(function (item) {
144
+ var _a, _b;
145
+ if (item.parentId) {
146
+ itemsById.delete(item.id);
147
+ }
148
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
149
+ var itemUntyped = item;
150
+ delete itemUntyped.id;
151
+ delete itemUntyped.parentId;
152
+ delete itemUntyped.parentKey;
153
+ delete itemUntyped.order;
154
+ if (((_a = itemUntyped.children) === null || _a === void 0 ? void 0 : _a.length) === 0)
155
+ delete itemUntyped.children;
156
+ if (((_b = itemUntyped.members) === null || _b === void 0 ? void 0 : _b.length) === 0)
157
+ delete itemUntyped.members;
158
+ });
159
+ return Array.from(itemsById.values());
160
+ }
161
+ function buildReportTrees(params) {
162
+ var _a, _b, _c, _d, _e, _f, _g;
163
+ var xbrlJson = params.xbrlJson, _h = params.memberInclusionRule, memberInclusionRule = _h === void 0 ? 'inReportsWherePresent' : _h;
164
+ var filingSummary = xbrlJson.filingSummary;
165
+ if (!filingSummary)
166
+ return [];
167
+ var labelByHref = getLabelTypeByHref((_a = xbrlJson.linkbaseLabel) === null || _a === void 0 ? void 0 : _a.xbrl);
168
+ var factsByConcept = new Map();
169
+ xbrlJson.facts.forEach(function (fact) {
170
+ var _a;
171
+ var bucket = (_a = factsByConcept.get(fact.name)) !== null && _a !== void 0 ? _a : factsByConcept.set(fact.name, []).get(fact.name);
172
+ bucket.push(fact);
173
+ });
174
+ var calculationLinks = (_d = (_c = (_b = xbrlJson.linkbaseCalculation) === null || _b === void 0 ? void 0 : _b.xbrl) === null || _c === void 0 ? void 0 : _c.calculationLink) !== null && _d !== void 0 ? _d : [];
175
+ var presentationLinks = (_g = (_f = (_e = xbrlJson.linkbasePresentation) === null || _e === void 0 ? void 0 : _e.xbrl) === null || _f === void 0 ? void 0 : _f.presentationLink) !== null && _g !== void 0 ? _g : [];
176
+ // Iterate through the xbrl reports and build tree structures
177
+ var reports = filingSummary.reports.map(function (report) {
178
+ var _a, _b, _c, _d, _e;
179
+ var calculationLink = calculationLinks.find(function (link) { return link.role === report.role; });
180
+ var presentationLink = presentationLinks.find(function (link) { return link.role === report.role; });
181
+ var locatorByLabelCalc = new Map((_b = (_a = calculationLink === null || calculationLink === void 0 ? void 0 : calculationLink.loc) === null || _a === void 0 ? void 0 : _a.map(function (l) { return [l.label, l]; })) !== null && _b !== void 0 ? _b : []);
182
+ var locatorByLabelPres = new Map((_d = (_c = presentationLink === null || presentationLink === void 0 ? void 0 : presentationLink.loc) === null || _c === void 0 ? void 0 : _c.map(function (l) { return [l.label, l]; })) !== null && _d !== void 0 ? _d : []);
183
+ var allowedMembers = new Set();
184
+ (_e = presentationLink === null || presentationLink === void 0 ? void 0 : presentationLink.presentationArc) === null || _e === void 0 ? void 0 : _e.forEach(function (arc) {
185
+ var _a, _b, _c, _d;
186
+ allowedMembers.add(hrefToKey((_b = (_a = locatorByLabelPres.get(arc.to)) === null || _a === void 0 ? void 0 : _a.href) !== null && _b !== void 0 ? _b : ''));
187
+ allowedMembers.add(hrefToKey((_d = (_c = locatorByLabelPres.get(arc.from)) === null || _c === void 0 ? void 0 : _c.href) !== null && _d !== void 0 ? _d : ''));
188
+ });
189
+ var hierarchyCalc = buildTemplateHierarchyFlat({
190
+ arcs: (calculationLink === null || calculationLink === void 0 ? void 0 : calculationLink.calculationArc) || [],
191
+ labelByHref: labelByHref,
192
+ locByLabel: locatorByLabelCalc,
193
+ factsByConcept: factsByConcept,
194
+ allowedMembers: allowedMembers,
195
+ memberInclusionRule: memberInclusionRule,
196
+ });
197
+ var hierarchyPres = buildTemplateHierarchyFlat({
198
+ arcs: (presentationLink === null || presentationLink === void 0 ? void 0 : presentationLink.presentationArc) || [],
199
+ labelByHref: labelByHref,
200
+ locByLabel: locatorByLabelPres,
201
+ factsByConcept: factsByConcept,
202
+ allowedMembers: allowedMembers,
203
+ memberInclusionRule: memberInclusionRule,
204
+ });
205
+ return __assign(__assign({}, report), { calculationTree: hierarchyToTree(hierarchyCalc), presentationTree: hierarchyToTree(hierarchyPres) });
206
+ });
207
+ return reports;
208
+ }
209
+ exports.buildReportTrees = buildReportTrees;
@@ -59,41 +59,6 @@ function getLabelByTaxonomy(labelLinkbase) {
59
59
  return labelByTaxonomy;
60
60
  }
61
61
  exports.getLabelByTaxonomy = getLabelByTaxonomy;
62
- // /**
63
- // * Gets labels by taxonomy from the label linkbase. priority level: verboseLabel > terseLabel > label.
64
- // */
65
- // export function getDefinitionByTaxonomy(definitionLinkbase: XbrlLinkbase) {
66
- // const labelByTaxonomy: Record<string, string> = {}
67
- // const taxonomyWithVerboseLabels = new Set<string>()
68
- // definitionLinkbase.definitionLink?.forEach((link) => {
69
- // link.definitionArc?.forEach(({ }) => {
70
- // const taxonomy = getTaxonomyFromId(definition)
71
- // // skip if verbose label already exists for this taxonomy
72
- // if (taxonomyWithVerboseLabels.has(taxonomy)) {
73
- // return
74
- // }
75
- // // label, terseLabel, or verboseLabel
76
- // const labelType = role.substring(role.lastIndexOf('/') + 1) as
77
- // | 'label'
78
- // | 'terseLabel'
79
- // | 'verboseLabel'
80
- // | 'periodStartLabel'
81
- // | 'periodEndLabel'
82
- // // skip periodStartLabel. Used for beginning cash position, but overwrites end cash position.
83
- // if (labelType === 'periodStartLabel') {
84
- // return
85
- // }
86
- // if (labelType === 'verboseLabel') {
87
- // taxonomyWithVerboseLabels.add(taxonomy)
88
- // }
89
- // // prefer terseLabel over regular label
90
- // if (!labelByTaxonomy[taxonomy] || labelType === 'terseLabel' || labelType === 'verboseLabel') {
91
- // labelByTaxonomy[taxonomy] = text
92
- // }
93
- // })
94
- // })
95
- // return labelByTaxonomy
96
- // }
97
62
  function isPascaleCase(str) {
98
63
  var startsWithUpperCase = str && str[0].toLowerCase() !== str[0];
99
64
  return startsWithUpperCase && str.split('').some(function (c) { return c.toLowerCase() === c; });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sec-edgar-api",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
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)",