UNPKG

sec-edgar-api

Version:

Fetch and parse SEC earnings reports and other filings. Useful for financial analysis.

210 lines (209 loc) 13 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildReportTrees = void 0; function hrefToKey(href) { var fragment = href.split('#').pop() || ''; return fragment.replace('_', ':'); } function getLabelTypeByHref(linkbase) { var _a, _b, _c, _d; var labelLink = (_a = linkbase === null || linkbase === void 0 ? void 0 : linkbase.labelLink) === null || _a === void 0 ? void 0 : _a[0]; 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]; })); 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]; })); var labelByTypeByLabelId = new Map(); (_d = labelLink === null || labelLink === void 0 ? void 0 : labelLink.label) === null || _d === void 0 ? void 0 : _d.forEach(function (l) { var _a; var bucket = (_a = labelByTypeByLabelId.get(l.label)) !== null && _a !== void 0 ? _a : labelByTypeByLabelId.set(l.label, {}).get(l.label); bucket[l.type.substring(l.type.lastIndexOf('/') + 1)] = l.text; }); var labelByTypeByHref = new Map(); labelLocByHref.forEach(function (locator, href) { var _a, _b, _c; 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 : {}); }); return labelByTypeByHref; } function getBestLabel(params) { var _a; var href = params.href, labelByHref = params.labelByHref, preferredLabel = params.preferredLabel; var bucket = labelByHref.get(href); if (!bucket) return null; // try getting preferred label var preferredLabelType = preferredLabel === null || preferredLabel === void 0 ? void 0 : preferredLabel.substring((preferredLabel === null || preferredLabel === void 0 ? void 0 : preferredLabel.lastIndexOf('/')) + 1); if (preferredLabelType && bucket[preferredLabelType]) return bucket[preferredLabelType]; // if not provided, choose first of these. for (var _i = 0, _b = ['verboseLabel', 'terseLabel', 'label', 'periodEndLabel']; _i < _b.length; _i++) { var type = _b[_i]; if (bucket[type]) return bucket[type]; } // return whatever is left return (_a = Object.values(bucket)[0]) !== null && _a !== void 0 ? _a : null; } function getPeriodFacts(params) { var _a; var factsByConcept = params.factsByConcept, conceptKey = params.conceptKey, isPeriodStart = params.isPeriodStart; var facts = (_a = factsByConcept.get(conceptKey)) !== null && _a !== void 0 ? _a : []; var primaryFacts = facts.filter(function (f) { return f.isCurrentPeriod; }); if (!isPeriodStart || primaryFacts.length === 0) return primaryFacts; var primaryFact = primaryFacts[0]; var maxEnd = facts.reduce(function (max, f) { return (f.end > max && f.end < primaryFact.end ? f.end : max); }, '0000-00-00'); return facts.filter(function (f) { return !f.isCurrentPeriod && f.end === maxEnd; }); } function extractMemberFacts(facts, memberInclusionRule, allowedMembers) { if (memberInclusionRule === 'never') return []; var allMembers = facts .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; }) .map(function (f) { return ({ value: f.value, segments: f.segments }); }); if (memberInclusionRule === 'always') return allMembers; return allMembers.filter(function (m) { 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)); }); }); } function extractPrimaryFact(facts) { var _a; 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; } function buildTemplateHierarchyFlat(params) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; 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; var itemsById = new Map(); for (var _i = 0, arcs_1 = arcs; _i < arcs_1.length; _i++) { var arc = arcs_1[_i]; var hrefFrom = (_b = (_a = locByLabel.get(arc.from)) === null || _a === void 0 ? void 0 : _a.href) !== null && _b !== void 0 ? _b : ''; var hrefTo = (_d = (_c = locByLabel.get(arc.to)) === null || _c === void 0 ? void 0 : _c.href) !== null && _d !== void 0 ? _d : ''; var keyFrom = hrefToKey(hrefFrom); var keyTo = hrefToKey(hrefTo); var isPeriodStart = (_f = (_e = arc.preferredLabel) === null || _e === void 0 ? void 0 : _e.endsWith('periodStartLabel')) !== null && _f !== void 0 ? _f : false; if (!itemsById.has(arc.from)) { var periodFactsFrom = getPeriodFacts({ conceptKey: keyFrom, factsByConcept: factsByConcept, isPeriodStart: isPeriodStart }); var membersFrom = extractMemberFacts(periodFactsFrom, memberInclusionRule, allowedMembers); var primaryFactFrom = extractPrimaryFact(periodFactsFrom); itemsById.set(arc.from, { id: arc.from, parentId: null, key: keyFrom, parentKey: null, weight: 1, order: 0, label: (_g = getBestLabel({ href: hrefFrom, labelByHref: labelByHref, preferredLabel: arc.preferredLabel })) !== null && _g !== void 0 ? _g : keyFrom, isPeriodStart: isPeriodStart, period: (primaryFactFrom === null || primaryFactFrom === void 0 ? void 0 : primaryFactFrom.period) || 0, value: (_h = primaryFactFrom === null || primaryFactFrom === void 0 ? void 0 : primaryFactFrom.value) !== null && _h !== void 0 ? _h : null, unit: (_j = primaryFactFrom === null || primaryFactFrom === void 0 ? void 0 : primaryFactFrom.unit) !== null && _j !== void 0 ? _j : '', members: membersFrom, children: [], }); } var periodFactsTo = getPeriodFacts({ conceptKey: keyTo, factsByConcept: factsByConcept, isPeriodStart: isPeriodStart }); var membersTo = extractMemberFacts(periodFactsTo, memberInclusionRule, allowedMembers); var primaryFactTo = extractPrimaryFact(periodFactsTo); var hierarchyTo = { id: arc.to, parentId: arc.from, key: keyTo, parentKey: arc.from ? hrefToKey(hrefFrom) : null, weight: arc.weight || 1, order: arc.order || 0, label: (_k = getBestLabel({ href: hrefTo, labelByHref: labelByHref, preferredLabel: arc.preferredLabel })) !== null && _k !== void 0 ? _k : keyTo, isPeriodStart: isPeriodStart, period: (primaryFactTo === null || primaryFactTo === void 0 ? void 0 : primaryFactTo.period) || 0, value: (_l = primaryFactTo === null || primaryFactTo === void 0 ? void 0 : primaryFactTo.value) !== null && _l !== void 0 ? _l : null, unit: (_m = primaryFactTo === null || primaryFactTo === void 0 ? void 0 : primaryFactTo.unit) !== null && _m !== void 0 ? _m : '', members: membersTo, children: [], }; if (!itemsById.has(arc.to)) { itemsById.set(arc.to, hierarchyTo); } else { Object.assign(itemsById.get(arc.to), hierarchyTo); } itemsById.get(arc.from).children.push(itemsById.get(arc.to)); } return itemsById; } function hierarchyToTree(itemsById) { itemsById.forEach(function (item) { var _a, _b; if (item.parentId) { itemsById.delete(item.id); } // eslint-disable-next-line @typescript-eslint/no-explicit-any var itemUntyped = item; delete itemUntyped.id; delete itemUntyped.parentId; delete itemUntyped.parentKey; delete itemUntyped.order; if (((_a = itemUntyped.children) === null || _a === void 0 ? void 0 : _a.length) === 0) delete itemUntyped.children; if (((_b = itemUntyped.members) === null || _b === void 0 ? void 0 : _b.length) === 0) delete itemUntyped.members; }); return Array.from(itemsById.values()); } function buildReportTrees(params) { var _a, _b, _c, _d, _e, _f, _g; var xbrlJson = params.xbrlJson, _h = params.memberInclusionRule, memberInclusionRule = _h === void 0 ? 'inReportsWherePresent' : _h; var filingSummary = xbrlJson.filingSummary; if (!filingSummary) return []; var labelByHref = getLabelTypeByHref((_a = xbrlJson.linkbaseLabel) === null || _a === void 0 ? void 0 : _a.xbrl); var factsByConcept = new Map(); xbrlJson.facts.forEach(function (fact) { var _a; var bucket = (_a = factsByConcept.get(fact.name)) !== null && _a !== void 0 ? _a : factsByConcept.set(fact.name, []).get(fact.name); bucket.push(fact); }); 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 : []; 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 : []; // Iterate through the xbrl reports and build tree structures var reports = filingSummary.reports.map(function (report) { var _a, _b, _c, _d, _e; var calculationLink = calculationLinks.find(function (link) { return link.role === report.role; }); var presentationLink = presentationLinks.find(function (link) { return link.role === report.role; }); 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 : []); 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 : []); var allowedMembers = new Set(); (_e = presentationLink === null || presentationLink === void 0 ? void 0 : presentationLink.presentationArc) === null || _e === void 0 ? void 0 : _e.forEach(function (arc) { var _a, _b, _c, _d; allowedMembers.add(hrefToKey((_b = (_a = locatorByLabelPres.get(arc.to)) === null || _a === void 0 ? void 0 : _a.href) !== null && _b !== void 0 ? _b : '')); allowedMembers.add(hrefToKey((_d = (_c = locatorByLabelPres.get(arc.from)) === null || _c === void 0 ? void 0 : _c.href) !== null && _d !== void 0 ? _d : '')); }); var hierarchyCalc = buildTemplateHierarchyFlat({ arcs: (calculationLink === null || calculationLink === void 0 ? void 0 : calculationLink.calculationArc) || [], labelByHref: labelByHref, locByLabel: locatorByLabelCalc, factsByConcept: factsByConcept, allowedMembers: allowedMembers, memberInclusionRule: memberInclusionRule, }); var hierarchyPres = buildTemplateHierarchyFlat({ arcs: (presentationLink === null || presentationLink === void 0 ? void 0 : presentationLink.presentationArc) || [], labelByHref: labelByHref, locByLabel: locatorByLabelPres, factsByConcept: factsByConcept, allowedMembers: allowedMembers, memberInclusionRule: memberInclusionRule, }); return __assign(__assign({}, report), { calculationTree: hierarchyToTree(hierarchyCalc), presentationTree: hierarchyToTree(hierarchyPres) }); }); return reports; } exports.buildReportTrees = buildReportTrees;