UNPKG

sec-edgar-api

Version:

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

96 lines (95 loc) 4.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTaxonomyFromId = exports.getLabelByTaxonomy = exports.getPrimaryDocumentation = exports.getPrimaryLabel = exports.getLabelsByTypeByTaxonomy = void 0; function getLabelsByTypeByTaxonomy(labelLinkbase) { var _a; var labelsByTypeByTaxonomy = {}; (_a = labelLinkbase === null || labelLinkbase === void 0 ? void 0 : labelLinkbase.labelLink) === null || _a === void 0 ? void 0 : _a.forEach(function (link) { var _a; (_a = link.label) === null || _a === void 0 ? void 0 : _a.forEach(function (_a) { var _b; var _c = _a.label, label = _c === void 0 ? '' : _c, _d = _a.text, text = _d === void 0 ? '' : _d, _e = _a.role, role = _e === void 0 ? '' : _e; var taxonomy = getTaxonomyFromId(label); var labelType = role.substring(role.lastIndexOf('/') + 1); (_b = labelsByTypeByTaxonomy[taxonomy]) !== null && _b !== void 0 ? _b : (labelsByTypeByTaxonomy[taxonomy] = {}); labelsByTypeByTaxonomy[taxonomy][labelType] = text; }); }); return labelsByTypeByTaxonomy; } exports.getLabelsByTypeByTaxonomy = getLabelsByTypeByTaxonomy; /** * The primary label based on priority: verboseLabel > terseLabel > label > periodEndLabel > first available label (excluding periodStartLabel) * * @param labelsByType The result of getLabelsByTypeByTaxonomy[key] */ function getPrimaryLabel(labelsByType) { var _a, _b; var preferredLabel = labelsByType.verboseLabel || labelsByType.terseLabel || labelsByType.label || labelsByType.periodEndLabel; if (preferredLabel) return preferredLabel; // return the first available label that is not periodStartLabel return (_b = (_a = Object.entries(labelsByType).find(function (_a) { var k = _a[0], v = _a[1]; return k !== 'periodStartLabel' && v.length > 0; })) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : ''; } exports.getPrimaryLabel = getPrimaryLabel; /** * The primary documentation based on priority: documentation > longest available label * * @param labelsByType The result of getLabelsByTypeByTaxonomy[key] */ function getPrimaryDocumentation(labelsByType) { if (labelsByType.documentation) return labelsByType.documentation; var validKeys = Object.keys(labelsByType).filter(function (key) { return key !== 'periodStartLabel'; }); return validKeys.reduce(function (acc, curr) { return (acc.length > curr.length ? acc : curr); }, ''); } exports.getPrimaryDocumentation = getPrimaryDocumentation; /** * Gets labels by taxonomy from the label linkbase. priority level: verboseLabel > terseLabel > label. */ function getLabelByTaxonomy(labelLinkbase) { var labelByTaxonomy = {}; var labelsByTypeByTaxonomy = getLabelsByTypeByTaxonomy(labelLinkbase); for (var taxonomy in labelsByTypeByTaxonomy) { labelByTaxonomy[taxonomy] = getPrimaryLabel(labelsByTypeByTaxonomy[taxonomy]); } return labelByTaxonomy; } exports.getLabelByTaxonomy = getLabelByTaxonomy; function isPascaleCase(str) { var startsWithUpperCase = str && str[0].toLowerCase() !== str[0]; return startsWithUpperCase && str.split('').some(function (c) { return c.toLowerCase() === c; }); } var knownPrefixes = { 'us-gaap': true, 'ifrs-full': true, dei: true, srt: true, country: true, }; function getTaxonomyFromId(id) { var parts = id.split('_'); var isLabelIndicatorPosition3 = parts[2] === 'lbl'; var isKnownPrefixPosition1 = knownPrefixes[parts[0]] === true; var isNameInPosition2 = parts.length <= 2 || isLabelIndicatorPosition3 || isKnownPrefixPosition1 || isPascaleCase(parts[1]); var result = isNameInPosition2 ? parts.slice(0, 2).join(':') : parts.slice(1, 3).join(':'); // this happens when the prefix is touching the concept name like "loc_us-gaapAssetsCurrent_lab". // The symbol "GAN" has this issue. if (result.startsWith('loc:')) { var idWithoutLoc_1 = id.substring(4); var knownPrefix = Object.keys(knownPrefixes).find(function (prefix) { return idWithoutLoc_1.startsWith(prefix); }); if (knownPrefix) { return "".concat(knownPrefix, ":").concat(idWithoutLoc_1.substring(knownPrefix.length).split('_')[0]); } // custom taxonomy, assume the first capital letter followed by a lowercase is the concept name. ex: GANAssetsCurrentCustomConcept.match(/([A-Z][a-z]+)/) var indexUpperFollowedByLower = idWithoutLoc_1.search(/[a-z]/) - 1; var customPrefix = idWithoutLoc_1.substring(0, indexUpperFollowedByLower); var conceptName = idWithoutLoc_1.substring(indexUpperFollowedByLower).split('_')[0]; return "".concat(customPrefix, ":").concat(conceptName.replace(/'|"/g, '')); } return result.replace(/'|"/g, ''); } exports.getTaxonomyFromId = getTaxonomyFromId;