UNPKG

sec-edgar-api

Version:

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

188 lines (187 loc) 9.44 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.RowNode = void 0; var ColNode_1 = require("./ColNode"); var XMLNode_1 = require("./XMLNode"); var RowNode = /** @class */ (function (_super) { __extends(RowNode, _super); function RowNode() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.isHeader = false; _this.isEmpty = null; return _this; } RowNode.prototype.getIsEmpty = function () { if (this.isEmpty !== null) return this.isEmpty; this.isEmpty = this.toArray().filter(Boolean).length === 0; return Boolean(this.isEmpty); }; RowNode.prototype.clone = function () { var clone = new RowNode({ attributesStr: this.getAttributesStr(), path: this.getPath() }); clone.setText(this.getText()); this.getChildren().forEach(function (child) { var childNew = new ColNode_1.ColNode({ attributesStr: child.getAttributesStr(), path: child.getPath() }); var prevChild = clone.getChildren()[clone.getChildren().length - 1]; childNew.setText(child.getText()); childNew.setIndex(child.getIndex()); prevChild === null || prevChild === void 0 ? void 0 : prevChild.setNextSibling(childNew); clone.addChild(childNew); }); return clone; }; RowNode.prototype.setIsHeader = function (isHeader) { this.isHeader = isHeader; }; RowNode.prototype.getIsHeader = function () { return this.isHeader; }; RowNode.prototype.getChildren = function () { return _super.prototype.getChildren.call(this); }; RowNode.prototype.getParent = function () { return _super.prototype.getParent.call(this); }; RowNode.prototype.getNextSibling = function () { return _super.prototype.getNextSibling.call(this); }; RowNode.prototype.getPreviousSibling = function () { return _super.prototype.getPreviousSibling.call(this); }; /** * Uses the columns in this row to build a table. Each column is also an array since cols can touch * multiple other cells on the top and bottom due to colspan. * * ```ts * const returnExample = [ * [ [ColNode, ColNode], [ColNode], [ColNode, ColNode, ColNode] ] * [ [ColNode], [ColNode], [ColNode] ], // this row * [ [ColNode], [ColNode], [ColNode, ColNode] ], * ] * ``` */ RowNode.prototype.getTableFromCols = function () { var _a, _b, _c; var colIndexRanges = this.getChildren().map(function (col) { return [col.getIndex(), col.getIndex() + col.getColSpan()]; }); var rows = this.getParent().getChildren(); var tableRowCols = rows.map(function () { return colIndexRanges.map(function () { return []; }); }); for (var rowIndex = 0; rowIndex < rows.length; rowIndex++) { var row = rows[rowIndex]; var colsShift = 0; var _loop_1 = function (col) { var _e = [col.getIndex(), col.getIndex() + col.getColSpan()], indexStart = _e[0], indexEnd = _e[1]; // // TODO: Instead of shifting cols here, just shift them in XMLParser when they are created while ((_a = tableRowCols[rowIndex][colsShift]) === null || _a === void 0 ? void 0 : _a.some(function (c) { return c.getParent() !== col.getParent(); })) { colsShift++; } // tableRowCols for (var i = 0; i < colIndexRanges.length; i++) { var _f = colIndexRanges[i], boundaryStart = _f[0], boundaryEnd = _f[1]; if (indexEnd <= boundaryStart || indexStart >= boundaryEnd) continue; for (var j = rowIndex; j < rowIndex + col.getRowSpan(); j++) { (_c = (_b = tableRowCols[j]) === null || _b === void 0 ? void 0 : _b[i + colsShift]) === null || _c === void 0 ? void 0 : _c.push(col); } } }; for (var _i = 0, _d = row.getChildren(); _i < _d.length; _i++) { var col = _d[_i]; _loop_1(col); } } return tableRowCols; }; RowNode.prototype.toTable = function (parseValues) { var _a, _b, _c; if (parseValues === void 0) { parseValues = true; } var table = this.getTableFromCols(); var tableTextArr = []; var headerRowIndex = (_a = this.getParent().getHeaderRowIndex()) !== null && _a !== void 0 ? _a : -1; for (var rowIndex = 0; rowIndex < table.length; rowIndex++) { var row = table[rowIndex]; var colTextArr = []; for (var _i = 0, row_1 = row; _i < row_1.length; _i++) { var colArr = row_1[_i]; var colText = colArr.reduce(function (acc, col) { return "".concat(acc, " ").concat(col.getText()); }, ''); // skip rows that are titles within the table body var isTitleRow = colArr.length === 1 && colArr[0].getColSpan() >= this.getChildren().length && rowIndex > headerRowIndex; if (isTitleRow) continue; if (!parseValues) { colTextArr.push(colText.trim()); continue; } // sometimes there is a rogue percent sign that is not in a column, so we need to check the next column var nextCol = (_b = colArr[colArr.length - 1]) === null || _b === void 0 ? void 0 : _b.getNextSibling(); var isMissingPercentSign = (nextCol === null || nextCol === void 0 ? void 0 : nextCol.getText().includes('%')) && nextCol.parseValue() === null; var isMissingParenthesis = (nextCol === null || nextCol === void 0 ? void 0 : nextCol.getText().includes(')')) && colText.includes('(') && !colText.includes(')'); var colValue = isMissingParenthesis ? "".concat(colText.trim(), ")") : colText.trim(); colValue = isMissingPercentSign ? "".concat(colText.trim(), "%") : colText.trim(); colValue = this.parseValue(colValue); colValue = typeof colValue === 'string' ? colValue.replace(/\s+/g, ' ') : colValue; colTextArr.push(colValue); } tableTextArr.push(colTextArr); } if (!parseValues) return tableTextArr; var emptyColIndexes = new Set(); cols: for (var colIndex = 0; colIndex < tableTextArr[0].length; colIndex++) { for (var rowIndex = 1; rowIndex < tableTextArr.length; rowIndex++) { if (Boolean(tableTextArr[rowIndex][colIndex]) && tableTextArr[rowIndex][colIndex] !== '%') { continue cols; } } emptyColIndexes.add(colIndex); } tableTextArr.forEach(function (row, i) { tableTextArr[i] = row.filter(function (_, i) { return !emptyColIndexes.has(i); }); }); var tableTextArrFiltered = []; for (var rowIndex = 0; rowIndex < tableTextArr.length; rowIndex++) { var row = tableTextArr[rowIndex]; var isEmpty = !row.some(Boolean); // if is empty before the header or empty next to another empty row, continue if (isEmpty && (rowIndex < headerRowIndex || !((_c = tableTextArr[rowIndex - 1]) === null || _c === void 0 ? void 0 : _c.some(Boolean)))) { continue; } tableTextArrFiltered.push(row); } return tableTextArr.filter(function (row, i) { var rowPrev = tableTextArr[i - 1]; var isEmpty = !row.some(Boolean); var isLast = i === tableTextArr.length - 1; // empty rows cannot be before header, last in array, or next to another empty row return !(isEmpty && (i < headerRowIndex || !(rowPrev === null || rowPrev === void 0 ? void 0 : rowPrev.some(Boolean)) || isLast)); }); }; RowNode.prototype.toArray = function (parseValues) { var _this = this; if (parseValues === void 0) { parseValues = true; } var cols = []; this.getChildren().forEach(function (col) { cols.push(parseValues ? _this.parseValue(col.getText()) : col.getText()); Array.from({ length: col.getColSpan() - 1 }).forEach(function () { return cols.push(null); }); }); return cols; }; return RowNode; }(XMLNode_1.XMLNode)); exports.RowNode = RowNode;