sec-edgar-api 0.5.12 → 1.0.0

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.
@@ -1,4 +1,4 @@
1
- import type { InsiderTransaction, Issuer, Owner, XMLParams } from '../../../types';
1
+ import { Owner, InsiderTransaction, Issuer, XMLParams } from '../../../types';
2
2
  export declare function parseInsiderTransactions(params: XMLParams): {
3
3
  transactions: InsiderTransaction[];
4
4
  owners: Owner[];
@@ -1,50 +1,49 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseInsiderTransactions = void 0;
4
- var HtmlTableExtractor_1 = require("../../HtmlTableExtractor");
4
+ function parseTable(html) {
5
+ var rows = html.split('<tr');
6
+ return rows
7
+ .map(function (rowHtml) {
8
+ return rowHtml
9
+ .split('<td')
10
+ .map(function (cellHtml) { return cellHtml.substring(cellHtml.indexOf('>') + 1, cellHtml.lastIndexOf('</td>')); })
11
+ .slice(1);
12
+ })
13
+ .filter(function (row) { return row.length > 0; });
14
+ }
15
+ function stripHtml(html) {
16
+ return html
17
+ .replace(/<.*?>/g, '')
18
+ .replace(/&nbsp;/g, ' ')
19
+ .replace(/\n/g, ' ')
20
+ .replace(/\s+/, ' ')
21
+ .trim();
22
+ }
23
+ function toNumber(value) {
24
+ return Number(value.replace(/,/g, '').trim()) || 0;
25
+ }
5
26
  function parseInsiderTransactions(params) {
6
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
27
+ var _a, _b, _c, _d;
7
28
  var xml = params.xml;
8
- var parser = new HtmlTableExtractor_1.default();
9
- var tables = parser.extractTables(xml, {
10
- stripHtml: true,
11
- tagsToExclude: ['sup'],
12
- stripParenthesis: true,
13
- removeEmptyColumns: false,
14
- getHeaderRowIndex: function (data) {
15
- return data.rows.findIndex(function (row) {
16
- var isNotEmptyRow = row.some(function (cell) { return cell.html.replace(/<.*?>/g, '').replace(/&.*?;/g, '').replace(/\s/g, '').length > 0; });
17
- return isNotEmptyRow;
18
- });
19
- },
20
- });
21
- var getTableHeadHtml = function (table) {
22
- var _a;
23
- var match = table.html.replace(/\n/g, '').match(/<b>.*?<\/b>/g);
24
- var matches = Array.isArray(match) ? match : [];
25
- return (_a = matches.find(function (match) { return match.includes('<a'); })) !== null && _a !== void 0 ? _a : null;
26
- };
27
- var tableCompany = tables.find(function (table) { return table.html.includes('cgi-bin/browse-edgar?action=getcompany') && getTableHeadHtml(table) !== null; });
28
- var tableCompanyHead = tableCompany ? getTableHeadHtml(tableCompany) || '' : '';
29
- var issuerCik = Number((_b = (_a = tableCompanyHead.split('</a>')[0]) === null || _a === void 0 ? void 0 : _a.split('>').pop()) === null || _b === void 0 ? void 0 : _b.trim()) || 0;
30
- var issuerName = ((_d = (_c = tableCompanyHead.split('(')[0]) === null || _c === void 0 ? void 0 : _c.split('>').pop()) === null || _d === void 0 ? void 0 : _d.trim()) || '';
31
- var cells = (_e = tableCompany === null || tableCompany === void 0 ? void 0 : tableCompany.rows.flat()) !== null && _e !== void 0 ? _e : [];
32
- cells.find(function (cell) { return cell.html.toLowerCase().includes('<b'); });
33
- var getHeaderRow = function (table) { return table.rows.find(function (row) { return row.some(function (cell) { return cell.isHeaderRowCell; }); }); };
34
- var findTableWithCol = function (colTextLower) {
35
- return tables.find(function (table) { var _a; return (_a = getHeaderRow(table)) === null || _a === void 0 ? void 0 : _a.some(function (cell) { return String(cell.valueParsed).toLowerCase().includes(colTextLower); }); });
36
- };
37
- var tableOwners = findTableWithCol('type of owner');
38
- var tableTransactions = findTableWithCol('security name');
39
- var stripHtml = function (html) {
40
- return html
41
- .replace(/<.*?>/g, '')
42
- .replace(/&nbsp;/g, ' ')
43
- .replace(/\n/g, ' ')
44
- .replace(/\s+/, ' ')
45
- .trim();
46
- };
47
- var ownerByCik = new Map();
29
+ var ownerTableHeadingIndex = xml.indexOf('sortid=');
30
+ var transactionTableIdIndex = xml.indexOf('id="transaction-report"');
31
+ if (ownerTableHeadingIndex === -1) {
32
+ throw new Error('Owner table heading not found in XML data');
33
+ }
34
+ var ownerTableStartIndex = xml.lastIndexOf('<table', ownerTableHeadingIndex);
35
+ var ownerTableEndIndex = xml.indexOf('</table>', ownerTableHeadingIndex) + 8;
36
+ var ownerTableHtml = xml.substring(ownerTableStartIndex, ownerTableEndIndex);
37
+ var transactionTableStartIndex = xml.lastIndexOf('<table', transactionTableIdIndex);
38
+ var transactionTableEndIndex = xml.indexOf('</table>', transactionTableIdIndex) + 8;
39
+ var transactionTableHtml = xml.substring(transactionTableStartIndex, transactionTableEndIndex);
40
+ var issuerUrlIndex = xml.indexOf('cgi-bin/browse-edgar?action=getcompany');
41
+ var issuerUrlStartIndex = xml.lastIndexOf('<b>', issuerUrlIndex) + 3;
42
+ var issuerUrlEndIndex = xml.indexOf('</b>', issuerUrlIndex);
43
+ var issuerHtml = xml.substring(issuerUrlStartIndex, issuerUrlEndIndex).trim();
44
+ var issuerHtmlCikStart = issuerHtml.lastIndexOf('(') + 1;
45
+ var issuerCik = toNumber(stripHtml(issuerHtml.substring(issuerHtmlCikStart, issuerHtml.lastIndexOf(')'))));
46
+ var issuerName = issuerHtml.substring(0, issuerHtmlCikStart - 1).trim();
48
47
  var headerOwner = ['owner_name', 'filings', 'transaction_date', 'type_of_owner'];
49
48
  var headerTransaction = [
50
49
  'acquisition_or_disposition',
@@ -60,33 +59,37 @@ function parseInsiderTransactions(params) {
60
59
  'owner_cik',
61
60
  'security_title',
62
61
  ];
63
- for (var _i = 0, _r = (_f = tableOwners === null || tableOwners === void 0 ? void 0 : tableOwners.rows) !== null && _f !== void 0 ? _f : []; _i < _r.length; _i++) {
64
- var row = _r[_i];
65
- if ((_g = row[0]) === null || _g === void 0 ? void 0 : _g.isHeaderRowCell)
66
- continue;
62
+ var ownerByCik = new Map();
63
+ var ownerRows = parseTable(ownerTableHtml);
64
+ var transactionRows = parseTable(transactionTableHtml);
65
+ var isSwitchedOwnerIssuer = stripHtml((_b = (_a = ownerRows[0]) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.toLowerCase()).includes('issuer') || false;
66
+ for (var i = 1; i < ownerRows.length; i++) {
67
+ var row = ownerRows[i];
68
+ // if (row.length === 0 || row[0].includes('Owner Name') || row[0].includes('Issuer')) continue // Skip header row
67
69
  var owner = {
68
70
  ownerName: '',
69
71
  ownerCik: 0,
70
72
  ownerPosition: null,
71
73
  isDirector: false,
72
74
  isOfficer: false,
75
+ isTenPercentOwner: false,
73
76
  };
74
- for (var _s = 0, row_1 = row; _s < row_1.length; _s++) {
75
- var cell = row_1[_s];
76
- var colName = headerOwner[cell.colIndex];
77
- var htmlStripped = stripHtml(cell.html);
77
+ for (var i_1 = 0; i_1 < row.length; i_1++) {
78
+ var colName = headerOwner[i_1];
79
+ var htmlStripped = stripHtml(row[i_1]);
78
80
  switch (colName) {
79
81
  case 'owner_name':
80
82
  owner.ownerName = htmlStripped.split('Current Name')[0];
81
83
  break;
82
84
  case 'filings':
83
- owner.ownerCik = Number(cell.valueParsed || 0) || 0;
85
+ owner.ownerCik = toNumber(htmlStripped);
84
86
  break;
85
87
  case 'type_of_owner': {
86
- var parts = htmlStripped.split(':');
87
- owner.isDirector = (_h = parts[0]) === null || _h === void 0 ? void 0 : _h.toLowerCase().includes('director');
88
- owner.isOfficer = (_j = parts[0]) === null || _j === void 0 ? void 0 : _j.toLowerCase().includes('officer');
89
- owner.ownerPosition = ((_k = parts[1]) === null || _k === void 0 ? void 0 : _k.trim()) || null;
88
+ var _e = htmlStripped.split(':').map(function (s) { return s.toLowerCase().trim(); }), ownerType = _e[0], _f = _e[1], position = _f === void 0 ? null : _f;
89
+ owner.isDirector = ownerType.includes('director');
90
+ owner.isOfficer = ownerType.includes('officer');
91
+ owner.isTenPercentOwner = ownerType.includes('10 percent') || ownerType.includes('10%');
92
+ owner.ownerPosition = position;
90
93
  break;
91
94
  }
92
95
  }
@@ -94,10 +97,10 @@ function parseInsiderTransactions(params) {
94
97
  ownerByCik.set(owner.ownerCik, owner);
95
98
  }
96
99
  var transactions = [];
97
- for (var _t = 0, _u = (_l = tableTransactions === null || tableTransactions === void 0 ? void 0 : tableTransactions.rows) !== null && _l !== void 0 ? _l : []; _t < _u.length; _t++) {
98
- var row = _u[_t];
99
- if ((_m = row[0]) === null || _m === void 0 ? void 0 : _m.isHeaderRowCell)
100
- continue;
100
+ for (var _i = 0, transactionRows_1 = transactionRows; _i < transactionRows_1.length; _i++) {
101
+ var row = transactionRows_1[_i];
102
+ if (row.length === 0 || row[0].includes('Acquisition or Dis'))
103
+ continue; // Skip header row
101
104
  var transaction = {
102
105
  ownerName: '',
103
106
  ownerCik: 0,
@@ -106,6 +109,9 @@ function parseInsiderTransactions(params) {
106
109
  issuerName: issuerName,
107
110
  isDirector: false,
108
111
  isOfficer: false,
112
+ accessionNumber: '',
113
+ deemedExecutionDate: '',
114
+ form: '',
109
115
  /** true = buy, false = sell */
110
116
  isAcquisition: false,
111
117
  isDirectOwnership: false,
@@ -115,17 +121,15 @@ function parseInsiderTransactions(params) {
115
121
  transactionShares: 0,
116
122
  sharesOwnedFollowingTransaction: 0,
117
123
  lineNumber: 0,
118
- deemedExecutionDate: '',
119
- form: '',
120
- accessionNumber: '',
124
+ isTenPercentOwner: false,
121
125
  };
122
- for (var _v = 0, row_2 = row; _v < row_2.length; _v++) {
123
- var cell = row_2[_v];
124
- var colName = headerTransaction[cell.colIndex];
125
- var htmlStripped = stripHtml(cell.html);
126
+ for (var i = 0; i < row.length; i++) {
127
+ var colName = headerTransaction[i];
128
+ var html = row[i];
129
+ var htmlStripped = stripHtml(html);
126
130
  switch (colName) {
127
131
  case 'acquisition_or_disposition':
128
- transaction.isAcquisition = String(cell.valueParsed).toLowerCase() === 'a';
132
+ transaction.isAcquisition = String(htmlStripped).toLowerCase() === 'a';
129
133
  break;
130
134
  case 'transaction_date':
131
135
  transaction.transactionDate = htmlStripped;
@@ -136,7 +140,7 @@ function parseInsiderTransactions(params) {
136
140
  case 'reporting_owner':
137
141
  break;
138
142
  case 'form': {
139
- var url = (_p = (_o = cell.html.match(/href="([^"]+)"/)) === null || _o === void 0 ? void 0 : _o[1]) !== null && _p !== void 0 ? _p : '';
143
+ var url = (_d = (_c = html.match(/href="([^"]+)"/)) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : '';
140
144
  transaction.accessionNumber = url.substring(url.lastIndexOf('/') + 1, url.lastIndexOf('-'));
141
145
  transaction.form = htmlStripped;
142
146
  break;
@@ -148,22 +152,23 @@ function parseInsiderTransactions(params) {
148
152
  transaction.isDirectOwnership = htmlStripped.toLowerCase().includes('d');
149
153
  break;
150
154
  case 'num_securities_transacted':
151
- transaction.transactionShares = Number(cell.valueParsed) || 0;
155
+ transaction.transactionShares = toNumber(htmlStripped) || 0;
152
156
  break;
153
157
  case 'num_securities_following':
154
- transaction.sharesOwnedFollowingTransaction = Number(cell.valueParsed) || 0;
158
+ transaction.sharesOwnedFollowingTransaction = toNumber(htmlStripped);
155
159
  break;
156
160
  case 'line_number':
157
- transaction.lineNumber = Number(cell.valueParsed) || 0;
161
+ transaction.lineNumber = toNumber(htmlStripped);
158
162
  break;
159
163
  case 'owner_cik': {
160
- var owner = ownerByCik.get(Number(cell.valueParsed) || 0);
164
+ var owner = ownerByCik.get(toNumber(htmlStripped) || 0);
161
165
  if (owner) {
162
166
  transaction.ownerName = owner.ownerName;
163
167
  transaction.ownerCik = owner.ownerCik;
164
168
  transaction.ownerPosition = owner.ownerPosition;
165
169
  transaction.isDirector = owner.isDirector;
166
170
  transaction.isOfficer = owner.isOfficer;
171
+ transaction.isTenPercentOwner = owner.isTenPercentOwner;
167
172
  }
168
173
  break;
169
174
  }
@@ -174,9 +179,6 @@ function parseInsiderTransactions(params) {
174
179
  }
175
180
  transactions.push(transaction);
176
181
  }
177
- var isSwitchedOwnerIssuer = (_q = tableTransactions === null || tableTransactions === void 0 ? void 0 : tableTransactions.rows) === null || _q === void 0 ? void 0 : _q.some(function (r) {
178
- return r.some(function (c) { return String(c.valueParsed).toLowerCase() === 'issuer'; });
179
- });
180
182
  var owners = Array.from(ownerByCik.values());
181
183
  var issuers = [{ issuerName: issuerName, issuerCik: issuerCik }];
182
184
  // if searching by person, owner and issuer data will be switched
@@ -194,6 +196,10 @@ function parseInsiderTransactions(params) {
194
196
  transaction.ownerName = issuerName;
195
197
  });
196
198
  }
197
- return { transactions: transactions, owners: owners, issuers: issuers };
199
+ return {
200
+ transactions: transactions,
201
+ owners: Array.from(ownerByCik.values()),
202
+ issuers: issuers,
203
+ };
198
204
  }
199
205
  exports.parseInsiderTransactions = parseInsiderTransactions;
@@ -5,6 +5,7 @@ export interface Owner {
5
5
  ownerPosition: string | null;
6
6
  isDirector: boolean;
7
7
  isOfficer: boolean;
8
+ isTenPercentOwner: boolean;
8
9
  }
9
10
  export interface Issuer {
10
11
  issuerName: string;
@@ -14,6 +15,7 @@ export interface InsiderTransaction {
14
15
  ownerName: string;
15
16
  ownerCik: number;
16
17
  ownerPosition: string | null;
18
+ isTenPercentOwner: boolean;
17
19
  issuerCik: number;
18
20
  issuerName: string;
19
21
  isDirector: boolean;
@@ -25,6 +27,7 @@ export interface InsiderTransaction {
25
27
  transactionDate: string;
26
28
  /**
27
29
  * ### Transaction Codes
30
+ * - P: Purchase
28
31
  * - S: Sale
29
32
  * - V: Voluntary Reporting
30
33
  * - A: Grant
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sec-edgar-api",
3
- "version": "0.5.12",
3
+ "version": "1.0.0",
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)",