@cyanheads/secedgar-mcp-server 0.15.8 → 0.15.9
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.
- package/AGENTS.md +10 -7
- package/CLAUDE.md +10 -7
- package/README.md +11 -6
- package/changelog/0.15.x/0.15.9.md +32 -0
- package/dist/mcp-server/prompts/definitions/company-analysis.prompt.js +2 -2
- package/dist/mcp-server/prompts/definitions/company-analysis.prompt.js.map +1 -1
- package/dist/mcp-server/resources/definitions/concepts.resource.d.ts +2 -1
- package/dist/mcp-server/resources/definitions/concepts.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/concepts.resource.js +5 -4
- package/dist/mcp-server/resources/definitions/concepts.resource.js.map +1 -1
- package/dist/mcp-server/tools/definitions/compare-companies.tool.d.ts +10 -0
- package/dist/mcp-server/tools/definitions/compare-companies.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/compare-companies.tool.js +143 -14
- package/dist/mcp-server/tools/definitions/compare-companies.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.d.ts +6 -1
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.js +93 -32
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-financials.tool.d.ts +6 -0
- package/dist/mcp-server/tools/definitions/get-financials.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-financials.tool.js +130 -60
- package/dist/mcp-server/tools/definitions/get-financials.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-snapshot.tool.d.ts +3 -0
- package/dist/mcp-server/tools/definitions/get-snapshot.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-snapshot.tool.js +16 -7
- package/dist/mcp-server/tools/definitions/get-snapshot.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/index.d.ts +81 -57
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-concepts.tool.d.ts +2 -1
- package/dist/mcp-server/tools/definitions/search-concepts.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-concepts.tool.js +5 -4
- package/dist/mcp-server/tools/definitions/search-concepts.tool.js.map +1 -1
- package/dist/services/edgar/concept-map.d.ts +38 -4
- package/dist/services/edgar/concept-map.d.ts.map +1 -1
- package/dist/services/edgar/concept-map.js +196 -9
- package/dist/services/edgar/concept-map.js.map +1 -1
- package/dist/services/edgar/concept-series.d.ts +79 -18
- package/dist/services/edgar/concept-series.d.ts.map +1 -1
- package/dist/services/edgar/concept-series.js +175 -25
- package/dist/services/edgar/concept-series.js.map +1 -1
- package/dist/services/edgar/edgar-api-service.d.ts +4 -6
- package/dist/services/edgar/edgar-api-service.d.ts.map +1 -1
- package/dist/services/edgar/edgar-api-service.js +34 -38
- package/dist/services/edgar/edgar-api-service.js.map +1 -1
- package/dist/services/edgar/mirror/edgar-mirror.d.ts +10 -1
- package/dist/services/edgar/mirror/edgar-mirror.d.ts.map +1 -1
- package/dist/services/edgar/mirror/edgar-mirror.js +52 -13
- package/dist/services/edgar/mirror/edgar-mirror.js.map +1 -1
- package/dist/services/edgar/trigram-similarity.d.ts +13 -0
- package/dist/services/edgar/trigram-similarity.d.ts.map +1 -0
- package/dist/services/edgar/trigram-similarity.js +40 -0
- package/dist/services/edgar/trigram-similarity.js.map +1 -0
- package/dist/services/edgar/types.d.ts +12 -2
- package/dist/services/edgar/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/server.json +3 -3
|
@@ -1,14 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Frame-aligned XBRL series resolution, shared by every tool that
|
|
3
3
|
* reads company facts. One value per standard calendar period: entries without a
|
|
4
|
-
* `frame` are dropped,
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* `frame` are dropped, a frame held by a proxy statement is answered with the
|
|
5
|
+
* filer's reporting-form fact for the same period, same-frame collisions resolve
|
|
6
|
+
* by tag priority (index 0 = the preferred total), and ties within one tag
|
|
7
|
+
* resolve to the latest `filed` date so a restatement replaces the original.
|
|
8
|
+
* Every resolved value names the tag and unit key it was read under. Extracted
|
|
9
|
+
* from `get_financials` so the snapshot and comparison tools produce numbers
|
|
10
|
+
* identical to it rather than re-implementing the rules.
|
|
9
11
|
* @module services/edgar/concept-series
|
|
10
12
|
*/
|
|
11
13
|
import { listConcepts, resolveConceptTarget } from './concept-map.js';
|
|
14
|
+
/**
|
|
15
|
+
* Schedule 14A and 14C forms — proxy and information statements in every
|
|
16
|
+
* variant EDGAR names (`DEF 14A`, `PRE 14A`, `DEFA14A`, `DEFM14A`, `PRER14A`,
|
|
17
|
+
* `DEF 14C`, …).
|
|
18
|
+
*/
|
|
19
|
+
const PROXY_FORM = /^[A-Z]{3,4} ?14[AC]$/;
|
|
20
|
+
/**
|
|
21
|
+
* Whether a fact comes from a proxy or information statement. Since the
|
|
22
|
+
* pay-versus-performance rule a DEF 14A re-tags five fiscal years of
|
|
23
|
+
* `NetIncomeLoss`, and SEC frames the latest-filed fact for a period, so the
|
|
24
|
+
* proxy's figure — often rounded, sometimes mis-scaled or sign-flipped — holds
|
|
25
|
+
* the annual frame over the 10-K's (#123).
|
|
26
|
+
*/
|
|
27
|
+
export function isProxyForm(form) {
|
|
28
|
+
return PROXY_FORM.test(form);
|
|
29
|
+
}
|
|
30
|
+
/** Quarterly reports — `10-Q` and the transition-period `10-QT`, with amendments. */
|
|
31
|
+
const QUARTERLY_FORM = /^10-QT?(\/A)?$/;
|
|
32
|
+
/**
|
|
33
|
+
* Whether a fact comes from a quarterly report. SEC frames any roughly
|
|
34
|
+
* year-long duration as `CY####`, including the trailing-twelve-month figure a
|
|
35
|
+
* 10-Q discloses, so a 10-Q fact filed after the 10-K can hold an annual frame
|
|
36
|
+
* for a year the filer has not closed (#142).
|
|
37
|
+
*/
|
|
38
|
+
export function isQuarterlyForm(form) {
|
|
39
|
+
return QUARTERLY_FORM.test(form);
|
|
40
|
+
}
|
|
12
41
|
/**
|
|
13
42
|
* SEC stamps a retired element's retirement date into the taxonomy label it
|
|
14
43
|
* serves with every companyconcept and companyfacts payload — e.g.
|
|
@@ -20,6 +49,89 @@ const DEPRECATED_LABEL = /\(Deprecated\s+(\d{4}-\d{2}-\d{2})\)/i;
|
|
|
20
49
|
const ANNUAL_FRAME = /^CY\d{4}$/;
|
|
21
50
|
/** Quarterly frame — `CY2023Q3` (duration) or `CY2023Q3I` (instant). */
|
|
22
51
|
const QUARTERLY_FRAME = /^CY\d{4}Q\d/;
|
|
52
|
+
/**
|
|
53
|
+
* The latest-filed fact reporting the same period (`start` and `end`) as a
|
|
54
|
+
* frame holder, from a form that is neither a proxy statement nor — when the
|
|
55
|
+
* holder is a quarterly report — another quarterly report. `sameSeries` must
|
|
56
|
+
* already be scoped to the holder's tag and unit key — a
|
|
57
|
+
* multi-currency filer frames one period under two units.
|
|
58
|
+
*/
|
|
59
|
+
function reportingFormTwin(holder, sameSeries) {
|
|
60
|
+
const quarterlyHolder = isQuarterlyForm(holder.form);
|
|
61
|
+
let twin;
|
|
62
|
+
for (const candidate of sameSeries) {
|
|
63
|
+
if (isProxyForm(candidate.form))
|
|
64
|
+
continue;
|
|
65
|
+
if (quarterlyHolder && isQuarterlyForm(candidate.form))
|
|
66
|
+
continue;
|
|
67
|
+
if (candidate.end !== holder.end || candidate.start !== holder.start)
|
|
68
|
+
continue;
|
|
69
|
+
if (!twin || candidate.filed > twin.filed)
|
|
70
|
+
twin = candidate;
|
|
71
|
+
}
|
|
72
|
+
return twin;
|
|
73
|
+
}
|
|
74
|
+
/** A 52/53-week filer's year end drifts by up to a week around its nominal date. */
|
|
75
|
+
const FISCAL_YEAR_END_TOLERANCE_DAYS = 7;
|
|
76
|
+
/** Day of year (1–366) of a YYYY-MM-DD date, compared circularly below. */
|
|
77
|
+
function dayOfYear(date) {
|
|
78
|
+
const at = Date.parse(date);
|
|
79
|
+
return Math.floor((at - Date.parse(`${date.slice(0, 4)}-01-01`)) / 86_400_000) + 1;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Whether a quarterly report's year-long fact covers a closed fiscal year, read
|
|
83
|
+
* from the same series: it must have ended before the report was filed, and its
|
|
84
|
+
* end must fall on a fiscal-year end the series shows — the end of a year-long
|
|
85
|
+
* fact from any other form, within a week. A trailing-twelve-month figure ends
|
|
86
|
+
* on a fiscal quarter end instead. When the series holds no year-long fact from
|
|
87
|
+
* another form there is nothing to test against, and the fact is kept.
|
|
88
|
+
*/
|
|
89
|
+
function closesFiscalYear(holder, sameSeries) {
|
|
90
|
+
if (holder.end >= holder.filed)
|
|
91
|
+
return false;
|
|
92
|
+
const holderDay = dayOfYear(holder.end);
|
|
93
|
+
let sawFiscalYear = false;
|
|
94
|
+
for (const candidate of sameSeries) {
|
|
95
|
+
if (!candidate.start || isQuarterlyForm(candidate.form) || isProxyForm(candidate.form)) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const days = (Date.parse(candidate.end) - Date.parse(candidate.start)) / 86_400_000;
|
|
99
|
+
if (days < 350 || days > 380)
|
|
100
|
+
continue;
|
|
101
|
+
sawFiscalYear = true;
|
|
102
|
+
const apart = Math.abs(dayOfYear(candidate.end) - holderDay);
|
|
103
|
+
if (Math.min(apart, 366 - apart) <= FISCAL_YEAR_END_TOLERANCE_DAYS)
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return !sawFiscalYear;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The fact a frame should resolve to, or `undefined` when the frame holds no
|
|
110
|
+
* value for that period. Two holder forms are corrected; every other form keeps
|
|
111
|
+
* its frame — an 8-K recast carries a restatement no later periodic report
|
|
112
|
+
* repeats (Bank of America's CY2013 is 10,539M from its 2016 8-K against
|
|
113
|
+
* 11,431M in the 10-K before it).
|
|
114
|
+
*
|
|
115
|
+
* - A proxy statement (#123): the latest reporting-form fact for the same
|
|
116
|
+
* period, else the proxy value, which is still the filer's reported figure.
|
|
117
|
+
* - A quarterly report holding an annual `CY####` frame (#142): the latest
|
|
118
|
+
* same-period fact from a form that is neither a quarterly report nor a proxy
|
|
119
|
+
* statement (the 10-K, in practice), else the holder when it covers a
|
|
120
|
+
* closed fiscal year a later 10-Q happens to disclose ({@link closesFiscalYear}),
|
|
121
|
+
* else nothing — a trailing-twelve-month or unfinished-year figure is not an
|
|
122
|
+
* annual value. Quarterly and instant frames from 10-Qs are untouched.
|
|
123
|
+
*
|
|
124
|
+
* `sameSeries` is the holder's tag under its unit key.
|
|
125
|
+
*/
|
|
126
|
+
export function frameHolderFact(holder, sameSeries) {
|
|
127
|
+
if (isProxyForm(holder.form))
|
|
128
|
+
return reportingFormTwin(holder, sameSeries) ?? holder;
|
|
129
|
+
if (isQuarterlyForm(holder.form) && holder.frame && ANNUAL_FRAME.test(holder.frame)) {
|
|
130
|
+
return (reportingFormTwin(holder, sameSeries) ??
|
|
131
|
+
(closesFiscalYear(holder, sameSeries) ? holder : undefined));
|
|
132
|
+
}
|
|
133
|
+
return holder;
|
|
134
|
+
}
|
|
23
135
|
/**
|
|
24
136
|
* Tag positions ordered by how many standard calendar periods each covers for
|
|
25
137
|
* this filer, widest first, with the declared order breaking a tie. A tag that
|
|
@@ -71,8 +183,16 @@ export function preferredTagIndex(units, selection = 'priority') {
|
|
|
71
183
|
* {@link seriesStalenessCaveats} exists to report (#101, #102).
|
|
72
184
|
*
|
|
73
185
|
* Within one tag, the later `filed` date wins so an amended filing replaces the
|
|
74
|
-
* original.
|
|
75
|
-
*
|
|
186
|
+
* original. A frame held by a proxy statement, or an annual frame held by a
|
|
187
|
+
* quarterly report, is first corrected within its own tag and unit key
|
|
188
|
+
* ({@link frameHolderFact}), keeping the frame. That runs before the cross-tag
|
|
189
|
+
* collision, so a proxy-held frame in the leading tag takes its twin from that
|
|
190
|
+
* tag and is never handed to a lower one (#123); a trailing-twelve-month frame
|
|
191
|
+
* the leader holds drops out, and a lower tag may then fill it with a real
|
|
192
|
+
* annual value (#142).
|
|
193
|
+
*
|
|
194
|
+
* Returns an empty map when nothing carried a frame — the caller distinguishes
|
|
195
|
+
* that from "the concept is not reported at all".
|
|
76
196
|
*/
|
|
77
197
|
export function resolveFrameSeries(units, selection = 'priority') {
|
|
78
198
|
const winner = selection === 'coverage' ? preferredTagIndex(units, selection) : undefined;
|
|
@@ -82,11 +202,17 @@ export function resolveFrameSeries(units, selection = 'priority') {
|
|
|
82
202
|
const { frame } = unit;
|
|
83
203
|
if (!frame)
|
|
84
204
|
continue;
|
|
205
|
+
// Only the two corrected holder shapes pay for scoping the series.
|
|
206
|
+
const reported = isProxyForm(unit.form) || (ANNUAL_FRAME.test(frame) && isQuarterlyForm(unit.form))
|
|
207
|
+
? frameHolderFact(unit, considered.filter((u) => u.tagIndex === unit.tagIndex && u.unit === unit.unit))
|
|
208
|
+
: unit;
|
|
209
|
+
if (!reported)
|
|
210
|
+
continue;
|
|
85
211
|
const existing = byFrame.get(frame);
|
|
86
212
|
if (!existing ||
|
|
87
|
-
|
|
88
|
-
(
|
|
89
|
-
byFrame.set(frame, { ...
|
|
213
|
+
reported.tagIndex < existing.tagIndex ||
|
|
214
|
+
(reported.tagIndex === existing.tagIndex && reported.filed > existing.filed)) {
|
|
215
|
+
byFrame.set(frame, { ...reported, frame });
|
|
90
216
|
}
|
|
91
217
|
}
|
|
92
218
|
const resolved = new Map();
|
|
@@ -210,16 +336,29 @@ export function matchesPeriodType(frame, periodType) {
|
|
|
210
336
|
return QUARTERLY_FRAME.test(frame);
|
|
211
337
|
return true;
|
|
212
338
|
}
|
|
339
|
+
/**
|
|
340
|
+
* The tag a resolved series is described by: the one behind its newest value.
|
|
341
|
+
* A successor appended behind an older leader (#125) answers the recent frames
|
|
342
|
+
* while the leader answers the old ones, so the leader — or whichever tag
|
|
343
|
+
* `preferredTagIndex` picks — would describe the series by a tag that produced
|
|
344
|
+
* none of its current values. Under `coverage` only the winner contributes, so
|
|
345
|
+
* the two agree. Falls back to `preferredTagIndex` when nothing carried a frame.
|
|
346
|
+
*/
|
|
347
|
+
export function describingTag(series, units, selection) {
|
|
348
|
+
const newest = series.reduce((latest, unit) => (!latest || unit.end > latest.end ? unit : latest), undefined);
|
|
349
|
+
if (newest)
|
|
350
|
+
return newest.tag;
|
|
351
|
+
const winner = preferredTagIndex(units, selection);
|
|
352
|
+
return units.find((unit) => unit.tagIndex === winner)?.tag;
|
|
353
|
+
}
|
|
213
354
|
/**
|
|
214
355
|
* Resolve one concept from a companyfacts payload, applying the same tag
|
|
215
356
|
* selection and frame dedup as {@link resolveFrameSeries}. Returns `undefined`
|
|
216
357
|
* when the filer reports none of the candidate tags under this taxonomy, which
|
|
217
358
|
* the caller surfaces as a gap alongside the tags it tried.
|
|
218
359
|
*
|
|
219
|
-
* The reported `tag`, `label`, `description`, and `unit`
|
|
220
|
-
*
|
|
221
|
-
* differ, and describing the series by a tag that lost every frame would misname
|
|
222
|
-
* the values.
|
|
360
|
+
* The reported `tag`, `label`, `description`, and `unit` describe the tag behind
|
|
361
|
+
* the newest value ({@link describingTag}), not the first one present.
|
|
223
362
|
*/
|
|
224
363
|
export function seriesFromCompanyFacts(facts, taxonomy, tags, selection = 'priority') {
|
|
225
364
|
const namespace = facts.facts[taxonomy];
|
|
@@ -227,7 +366,12 @@ export function seriesFromCompanyFacts(facts, taxonomy, tags, selection = 'prior
|
|
|
227
366
|
return;
|
|
228
367
|
const units = [];
|
|
229
368
|
const tagsTried = [];
|
|
230
|
-
/**
|
|
369
|
+
/**
|
|
370
|
+
* Taxonomy metadata of every tag the filer reports, plus its first unit key.
|
|
371
|
+
* SEC serves some tags with no label (`InterestExpenseNonoperating`); the label
|
|
372
|
+
* is then empty so a caller falls back to the concept's own label rather than
|
|
373
|
+
* printing the raw tag as one.
|
|
374
|
+
*/
|
|
231
375
|
const reported = new Map();
|
|
232
376
|
for (const [tagIndex, tag] of tags.entries()) {
|
|
233
377
|
tagsTried.push(tag);
|
|
@@ -235,24 +379,30 @@ export function seriesFromCompanyFacts(facts, taxonomy, tags, selection = 'prior
|
|
|
235
379
|
if (!concept?.units)
|
|
236
380
|
continue;
|
|
237
381
|
for (const [unitKey, values] of Object.entries(concept.units)) {
|
|
238
|
-
if (!reported.has(
|
|
239
|
-
reported.set(
|
|
240
|
-
|
|
241
|
-
label: concept.label ?? tag,
|
|
382
|
+
if (!reported.has(tag)) {
|
|
383
|
+
reported.set(tag, {
|
|
384
|
+
label: concept.label ?? '',
|
|
242
385
|
unit: unitKey,
|
|
243
386
|
...(concept.description !== undefined ? { description: concept.description } : {}),
|
|
244
387
|
});
|
|
245
388
|
}
|
|
246
389
|
for (const value of values)
|
|
247
|
-
units.push({ ...value, tagIndex });
|
|
390
|
+
units.push({ ...value, tag, tagIndex, unit: unitKey });
|
|
248
391
|
}
|
|
249
392
|
}
|
|
250
|
-
const
|
|
393
|
+
const series = [...resolveFrameSeries(units, selection).values()].sort((a, b) => b.end.localeCompare(a.end));
|
|
251
394
|
/** Falls back to the first reporting tag when nothing carried a value to rank. */
|
|
252
|
-
const
|
|
253
|
-
|
|
395
|
+
const tag = describingTag(series, units, selection) ?? [...reported.keys()][0];
|
|
396
|
+
const described = tag !== undefined ? reported.get(tag) : undefined;
|
|
397
|
+
if (tag === undefined || !described)
|
|
254
398
|
return;
|
|
255
|
-
|
|
256
|
-
|
|
399
|
+
return {
|
|
400
|
+
...described,
|
|
401
|
+
unit: series[0]?.unit ?? described.unit,
|
|
402
|
+
tag,
|
|
403
|
+
series,
|
|
404
|
+
tagsTried,
|
|
405
|
+
taxonomy,
|
|
406
|
+
};
|
|
257
407
|
}
|
|
258
408
|
//# sourceMappingURL=concept-series.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"concept-series.js","sourceRoot":"","sources":["../../../src/services/edgar/concept-series.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"concept-series.js","sourceRoot":"","sources":["../../../src/services/edgar/concept-series.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,11 +48,6 @@ export interface SeriesFilingFeed {
|
|
|
48
48
|
* back unchanged, so the result is safe to compare against a raw lowercased name.
|
|
49
49
|
*/
|
|
50
50
|
export declare function normalizeCompanySuffix(name: string): string;
|
|
51
|
-
/**
|
|
52
|
-
* Dice-coefficient trigram similarity between two strings.
|
|
53
|
-
* Returns a value in [0, 1]; 1 means identical.
|
|
54
|
-
*/
|
|
55
|
-
export declare function trigramSimilarity(a: string, b: string): number;
|
|
56
51
|
/**
|
|
57
52
|
* Run a trigram similarity scan over the in-memory entry set. Each entry is scored
|
|
58
53
|
* on its name and on its ticker, and keeps the higher of the two — one ranked,
|
|
@@ -242,13 +237,16 @@ declare class EdgarApiService {
|
|
|
242
237
|
* no-data error path, which surfaces the namespaces and tags a filer uses.
|
|
243
238
|
* Served from the local mirror when enabled and synced — the mirror stores one
|
|
244
239
|
* row per (cik, taxonomy, tag) and reassembles the API shape off a `cik` point
|
|
245
|
-
* lookup; the live API is the fallback.
|
|
240
|
+
* lookup; the live API is the fallback. A concept unit that arrives as
|
|
241
|
+
* anything but an array is dropped (#141).
|
|
246
242
|
*/
|
|
247
243
|
tryGetCompanyFacts(cik: string): Promise<CompanyFactsResponse | null>;
|
|
248
244
|
/**
|
|
249
245
|
* Fetch XBRL data for a concept. Returns `null` if the company does not report this tag.
|
|
250
246
|
* Served from the local mirror when enabled and synced; the live API is the
|
|
251
247
|
* fallback (and covers filings newer than the last refresh when `mirrorFallbackLive`).
|
|
248
|
+
* A payload whose every unit arrives malformed comes back with no units — the
|
|
249
|
+
* tag is named but carries nothing (#141).
|
|
252
250
|
*/
|
|
253
251
|
tryGetCompanyConcept(cik: string, taxonomy: string, tag: string): Promise<CompanyConceptResponse | null>;
|
|
254
252
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edgar-api-service.d.ts","sourceRoot":"","sources":["../../../src/services/edgar/edgar-api-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,OAAO,EACL,KAAK,aAAa,EAGlB,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"edgar-api-service.d.ts","sourceRoot":"","sources":["../../../src/services/edgar/edgar-api-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ import { getServerConfig } from '../../config/server-config.js';
|
|
|
11
11
|
import { getEdgarMirror } from './mirror/index.js';
|
|
12
12
|
import formerNamesData from './data/former-names.json' with { type: 'json' };
|
|
13
13
|
import { parseFilingHeaders, parseSubmissionHeader, } from './filing-headers.js';
|
|
14
|
+
import { trigramSimilarity } from './trigram-similarity.js';
|
|
14
15
|
import { childText, findTag, findTags } from './xml-nodes.js';
|
|
15
16
|
const MAX_RETRIES = 3;
|
|
16
17
|
const BASE_BACKOFF_MS = 1000;
|
|
@@ -94,40 +95,8 @@ export function normalizeCompanySuffix(name) {
|
|
|
94
95
|
return canonical ? `${name.slice(0, cut)} ${canonical}` : name;
|
|
95
96
|
}
|
|
96
97
|
// ---------------------------------------------------------------------------
|
|
97
|
-
//
|
|
98
|
+
// Near-match company suggestions
|
|
98
99
|
// ---------------------------------------------------------------------------
|
|
99
|
-
/**
|
|
100
|
-
* Build the set of trigrams for a string.
|
|
101
|
-
* Pads with two spaces on each side so edge characters are covered.
|
|
102
|
-
*/
|
|
103
|
-
function trigramSet(s) {
|
|
104
|
-
const padded = ` ${s} `;
|
|
105
|
-
const grams = new Set();
|
|
106
|
-
for (let i = 0; i < padded.length - 2; i++) {
|
|
107
|
-
grams.add(padded.slice(i, i + 3));
|
|
108
|
-
}
|
|
109
|
-
return grams;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Dice-coefficient trigram similarity between two strings.
|
|
113
|
-
* Returns a value in [0, 1]; 1 means identical.
|
|
114
|
-
*/
|
|
115
|
-
export function trigramSimilarity(a, b) {
|
|
116
|
-
if (a === b)
|
|
117
|
-
return 1;
|
|
118
|
-
const ga = trigramSet(a);
|
|
119
|
-
const gb = trigramSet(b);
|
|
120
|
-
if (ga.size === 0 && gb.size === 0)
|
|
121
|
-
return 1;
|
|
122
|
-
if (ga.size === 0 || gb.size === 0)
|
|
123
|
-
return 0;
|
|
124
|
-
let intersection = 0;
|
|
125
|
-
for (const g of ga) {
|
|
126
|
-
if (gb.has(g))
|
|
127
|
-
intersection++;
|
|
128
|
-
}
|
|
129
|
-
return (2 * intersection) / (ga.size + gb.size);
|
|
130
|
-
}
|
|
131
100
|
/**
|
|
132
101
|
* Run a trigram similarity scan over the in-memory entry set. Each entry is scored
|
|
133
102
|
* on its name and on its ticker, and keeps the higher of the two — one ranked,
|
|
@@ -612,20 +581,31 @@ class EdgarApiService {
|
|
|
612
581
|
* no-data error path, which surfaces the namespaces and tags a filer uses.
|
|
613
582
|
* Served from the local mirror when enabled and synced — the mirror stores one
|
|
614
583
|
* row per (cik, taxonomy, tag) and reassembles the API shape off a `cik` point
|
|
615
|
-
* lookup; the live API is the fallback.
|
|
584
|
+
* lookup; the live API is the fallback. A concept unit that arrives as
|
|
585
|
+
* anything but an array is dropped (#141).
|
|
616
586
|
*/
|
|
617
|
-
tryGetCompanyFacts(cik) {
|
|
587
|
+
async tryGetCompanyFacts(cik) {
|
|
618
588
|
const padded = cik.padStart(10, '0');
|
|
619
|
-
|
|
589
|
+
const facts = await this.mirrorOrLive((m) => m.companyFactsReady(), (m) => m.getCompanyFacts(cik), () => this.tryFetchJson(`https://data.sec.gov/api/xbrl/companyfacts/CIK${padded}.json`));
|
|
590
|
+
for (const namespace of Object.values(facts?.facts ?? {})) {
|
|
591
|
+
for (const concept of Object.values(namespace))
|
|
592
|
+
concept.units = arrayUnits(concept.units);
|
|
593
|
+
}
|
|
594
|
+
return facts;
|
|
620
595
|
}
|
|
621
596
|
/**
|
|
622
597
|
* Fetch XBRL data for a concept. Returns `null` if the company does not report this tag.
|
|
623
598
|
* Served from the local mirror when enabled and synced; the live API is the
|
|
624
599
|
* fallback (and covers filings newer than the last refresh when `mirrorFallbackLive`).
|
|
600
|
+
* A payload whose every unit arrives malformed comes back with no units — the
|
|
601
|
+
* tag is named but carries nothing (#141).
|
|
625
602
|
*/
|
|
626
|
-
tryGetCompanyConcept(cik, taxonomy, tag) {
|
|
603
|
+
async tryGetCompanyConcept(cik, taxonomy, tag) {
|
|
627
604
|
const padded = cik.padStart(10, '0');
|
|
628
|
-
|
|
605
|
+
const concept = await this.mirrorOrLive((m) => m.companyFactsReady(), (m) => m.getCompanyConcept(cik, taxonomy, tag), () => this.tryFetchJson(`https://data.sec.gov/api/xbrl/companyconcept/CIK${padded}/${taxonomy}/${tag}.json`));
|
|
606
|
+
if (concept)
|
|
607
|
+
concept.units = arrayUnits(concept.units);
|
|
608
|
+
return concept;
|
|
629
609
|
}
|
|
630
610
|
/**
|
|
631
611
|
* Fetch cross-company frame data. Returns `null` if no companies report this combination.
|
|
@@ -957,6 +937,22 @@ class EdgarApiService {
|
|
|
957
937
|
return this.tickerCache;
|
|
958
938
|
}
|
|
959
939
|
}
|
|
940
|
+
/**
|
|
941
|
+
* The units of an XBRL concept, keeping only those whose value is an array.
|
|
942
|
+
* SEC's companyconcept endpoint serves some filers' units as an empty object —
|
|
943
|
+
* `"units":{"USD":{}}` for Visa's and Coca-Cola's NetIncomeLoss — and the mirror
|
|
944
|
+
* stores payloads as served, while every reader iterates a unit as a list of
|
|
945
|
+
* facts. Dropped here, at the edge, a malformed unit reads as one the filer
|
|
946
|
+
* reported nothing under (#141).
|
|
947
|
+
*/
|
|
948
|
+
function arrayUnits(units) {
|
|
949
|
+
const kept = {};
|
|
950
|
+
for (const [unit, values] of Object.entries(units ?? {})) {
|
|
951
|
+
if (Array.isArray(values))
|
|
952
|
+
kept[unit] = values;
|
|
953
|
+
}
|
|
954
|
+
return kept;
|
|
955
|
+
}
|
|
960
956
|
/**
|
|
961
957
|
* Classify a mirror ticker row. The mirror schema has no series or class column:
|
|
962
958
|
* tickers-sync stores a fund symbol from company_tickers_mf.json with an empty
|