sec-edgar-api 1.0.0 → 1.0.1

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.
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Practical examples of working with XBRL relationships using your existing types
3
+ */
4
+ import type { XbrlInstance, XbrlLinkbase } from '../types';
5
+ /**
6
+ * Example 1: Extract presentation hierarchy from your XBRL data
7
+ */
8
+ export declare function extractPresentationHierarchy(presentationLinkbase: XbrlLinkbase): Record<string, ConceptNode>;
9
+ /**
10
+ * Example 2: Extract calculation relationships
11
+ */
12
+ export declare function extractCalculationRelationships(calculationLinkbase: XbrlLinkbase): Record<string, CalculationRule>;
13
+ /**
14
+ * Example 3: Extract dimensional relationships (axis/member mappings)
15
+ */
16
+ export declare function extractDimensionalRelationships(definitionLinkbase: XbrlLinkbase): Record<string, DimensionStructure>;
17
+ /**
18
+ * Example 4: Find facts with specific dimensional context
19
+ */
20
+ export declare function findFactsWithDimensions(instance: XbrlInstance, conceptName: string, dimensionFilters?: {
21
+ dimension: string;
22
+ member?: string;
23
+ }[]): {
24
+ fact: import("../types").XbrlElement;
25
+ context: import("../types").XbrlContext;
26
+ dimensions: {
27
+ dimension: string;
28
+ member: string;
29
+ }[];
30
+ }[];
31
+ /**
32
+ * Example 5: Build a complete concept map with all relationships
33
+ */
34
+ export declare function buildCompleteConceptMap(linkbases: {
35
+ presentation: XbrlLinkbase;
36
+ calculation: XbrlLinkbase;
37
+ definition: XbrlLinkbase;
38
+ label: XbrlLinkbase;
39
+ }): Map<string, CompleteConcept>;
40
+ interface ConceptNode {
41
+ concept: string;
42
+ children: ConceptChild[];
43
+ role: string;
44
+ order: number;
45
+ }
46
+ interface ConceptChild {
47
+ concept: string;
48
+ order: number;
49
+ preferredLabel?: string;
50
+ }
51
+ interface CalculationRule {
52
+ summationItem: string;
53
+ contributingItems: CalculationItem[];
54
+ }
55
+ interface CalculationItem {
56
+ concept: string;
57
+ weight: number;
58
+ order: number;
59
+ }
60
+ interface DimensionStructure {
61
+ concept: string;
62
+ type: string;
63
+ dimensions?: string[];
64
+ domains?: string[];
65
+ members?: string[];
66
+ }
67
+ interface ConceptLabel {
68
+ text: string;
69
+ role: string;
70
+ lang: string;
71
+ }
72
+ interface CompleteConcept {
73
+ name: string;
74
+ labels: ConceptLabel[];
75
+ presentation: ConceptNode | null;
76
+ calculation: CalculationRule | null;
77
+ dimensions: DimensionStructure | null;
78
+ }
79
+ export declare function usageExamples(): {
80
+ segmentRevenue: {
81
+ fact: import("../types").XbrlElement;
82
+ context: import("../types").XbrlContext;
83
+ dimensions: {
84
+ dimension: string;
85
+ member: string;
86
+ }[];
87
+ }[];
88
+ northAmericaRevenue: {
89
+ fact: import("../types").XbrlElement;
90
+ context: import("../types").XbrlContext;
91
+ dimensions: {
92
+ dimension: string;
93
+ member: string;
94
+ }[];
95
+ }[];
96
+ };
97
+ export {};
@@ -0,0 +1,277 @@
1
+ "use strict";
2
+ /**
3
+ * Practical examples of working with XBRL relationships using your existing types
4
+ */
5
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
6
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
7
+ if (ar || !(i in from)) {
8
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
9
+ ar[i] = from[i];
10
+ }
11
+ }
12
+ return to.concat(ar || Array.prototype.slice.call(from));
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.usageExamples = exports.buildCompleteConceptMap = exports.findFactsWithDimensions = exports.extractDimensionalRelationships = exports.extractCalculationRelationships = exports.extractPresentationHierarchy = void 0;
16
+ /**
17
+ * Example 1: Extract presentation hierarchy from your XBRL data
18
+ */
19
+ function extractPresentationHierarchy(presentationLinkbase) {
20
+ var _a;
21
+ var hierarchy = {};
22
+ // Process each presentation link (usually one per role/statement)
23
+ (_a = presentationLinkbase.presentationLink) === null || _a === void 0 ? void 0 : _a.forEach(function (link) {
24
+ var roleUri = link.role || 'default';
25
+ // Get all concept locators and relationship arcs
26
+ var locators = (link.loc || []);
27
+ var arcs = (link.presentationArc || []);
28
+ // Build concept reference map
29
+ var conceptMap = new Map();
30
+ locators.forEach(function (loc) {
31
+ var concept = extractConceptFromHref(loc.href);
32
+ conceptMap.set(loc.label, concept);
33
+ });
34
+ // Build parent-child relationships
35
+ arcs.forEach(function (arc) {
36
+ var parent = conceptMap.get(arc.from);
37
+ var child = conceptMap.get(arc.to);
38
+ if (parent && child) {
39
+ // Initialize parent node if it doesn't exist
40
+ if (!hierarchy[parent]) {
41
+ hierarchy[parent] = {
42
+ concept: parent,
43
+ children: [],
44
+ role: roleUri,
45
+ order: 0,
46
+ };
47
+ }
48
+ // Add child with ordering information
49
+ hierarchy[parent].children.push({
50
+ concept: child,
51
+ order: arc.order || 0,
52
+ preferredLabel: arc.preferredLabel,
53
+ });
54
+ // Sort children by order
55
+ hierarchy[parent].children.sort(function (a, b) { return a.order - b.order; });
56
+ }
57
+ });
58
+ });
59
+ return hierarchy;
60
+ }
61
+ exports.extractPresentationHierarchy = extractPresentationHierarchy;
62
+ /**
63
+ * Example 2: Extract calculation relationships
64
+ */
65
+ function extractCalculationRelationships(calculationLinkbase) {
66
+ var _a;
67
+ var calculations = {};
68
+ (_a = calculationLinkbase.calculationLink) === null || _a === void 0 ? void 0 : _a.forEach(function (link) {
69
+ var locators = (link.loc || []);
70
+ var arcs = (link.calculationArc || []);
71
+ // Build concept reference map
72
+ var conceptMap = new Map();
73
+ locators.forEach(function (loc) {
74
+ var concept = extractConceptFromHref(loc.href);
75
+ conceptMap.set(loc.label, concept);
76
+ });
77
+ // Group arcs by summation item (the 'to' end of the arc)
78
+ var summationGroups = new Map();
79
+ arcs.forEach(function (arc) {
80
+ var summationConcept = conceptMap.get(arc.to);
81
+ if (summationConcept) {
82
+ if (!summationGroups.has(summationConcept)) {
83
+ summationGroups.set(summationConcept, []);
84
+ }
85
+ summationGroups.get(summationConcept).push(arc);
86
+ }
87
+ });
88
+ // Build calculation rules
89
+ summationGroups.forEach(function (contributingArcs, summationConcept) {
90
+ calculations[summationConcept] = {
91
+ summationItem: summationConcept,
92
+ contributingItems: contributingArcs.map(function (arc) { return ({
93
+ concept: conceptMap.get(arc.from) || '',
94
+ weight: arc.weight || 1,
95
+ order: arc.order || 0,
96
+ }); }),
97
+ };
98
+ });
99
+ });
100
+ return calculations;
101
+ }
102
+ exports.extractCalculationRelationships = extractCalculationRelationships;
103
+ /**
104
+ * Example 3: Extract dimensional relationships (axis/member mappings)
105
+ */
106
+ function extractDimensionalRelationships(definitionLinkbase) {
107
+ var _a;
108
+ var dimensions = {};
109
+ (_a = definitionLinkbase.definitionLink) === null || _a === void 0 ? void 0 : _a.forEach(function (link) {
110
+ var locators = (link.loc || []);
111
+ var arcs = (link.definitionArc || []);
112
+ // Build concept reference map
113
+ var conceptMap = new Map();
114
+ locators.forEach(function (loc) {
115
+ var concept = extractConceptFromHref(loc.href);
116
+ conceptMap.set(loc.label, concept);
117
+ });
118
+ // Process dimensional arcs based on their arcrole
119
+ arcs.forEach(function (arc) {
120
+ var fromConcept = conceptMap.get(arc.from);
121
+ var toConcept = conceptMap.get(arc.to);
122
+ var arcrole = arc.arcrole || '';
123
+ if (fromConcept && toConcept) {
124
+ switch (arcrole) {
125
+ case 'http://xbrl.org/int/dim/arcrole/hypercube-dimension':
126
+ // Hypercube contains dimension
127
+ initializeDimension(dimensions, fromConcept, 'hypercube');
128
+ dimensions[fromConcept].dimensions = dimensions[fromConcept].dimensions || [];
129
+ dimensions[fromConcept].dimensions.push(toConcept);
130
+ break;
131
+ case 'http://xbrl.org/int/dim/arcrole/dimension-domain':
132
+ // Dimension has domain
133
+ initializeDimension(dimensions, fromConcept, 'dimension');
134
+ dimensions[fromConcept].domains = dimensions[fromConcept].domains || [];
135
+ dimensions[fromConcept].domains.push(toConcept);
136
+ break;
137
+ case 'http://xbrl.org/int/dim/arcrole/domain-member':
138
+ // Domain has member
139
+ initializeDimension(dimensions, fromConcept, 'domain');
140
+ dimensions[fromConcept].members = dimensions[fromConcept].members || [];
141
+ dimensions[fromConcept].members.push(toConcept);
142
+ break;
143
+ }
144
+ }
145
+ });
146
+ });
147
+ return dimensions;
148
+ }
149
+ exports.extractDimensionalRelationships = extractDimensionalRelationships;
150
+ /**
151
+ * Example 4: Find facts with specific dimensional context
152
+ */
153
+ function findFactsWithDimensions(instance, conceptName, dimensionFilters) {
154
+ var matchingFacts = [];
155
+ // Filter facts by concept name
156
+ var conceptFacts = instance.factElements.filter(function (fact) { return fact.name === conceptName; });
157
+ var _loop_1 = function (fact) {
158
+ // Get the context for this fact
159
+ var context = instance.contexts.find(function (ctx) { return ctx.id === fact.contextRef; });
160
+ if (!context)
161
+ return "continue";
162
+ // Check if this fact matches our dimensional filters
163
+ if (dimensionFilters) {
164
+ var matchesFilters = dimensionFilters.every(function (filter) {
165
+ var matchingSegment = context.entity.segment.find(function (seg) { return seg.dimension === filter.dimension; });
166
+ if (!matchingSegment)
167
+ return false;
168
+ // If specific member is required, check for it
169
+ if (filter.member && matchingSegment.value !== filter.member) {
170
+ return false;
171
+ }
172
+ return true;
173
+ });
174
+ if (!matchesFilters)
175
+ return "continue";
176
+ }
177
+ matchingFacts.push({
178
+ fact: fact,
179
+ context: context,
180
+ dimensions: context.entity.segment.map(function (seg) { return ({
181
+ dimension: seg.dimension,
182
+ member: seg.value,
183
+ }); }),
184
+ });
185
+ };
186
+ for (var _i = 0, conceptFacts_1 = conceptFacts; _i < conceptFacts_1.length; _i++) {
187
+ var fact = conceptFacts_1[_i];
188
+ _loop_1(fact);
189
+ }
190
+ return matchingFacts;
191
+ }
192
+ exports.findFactsWithDimensions = findFactsWithDimensions;
193
+ /**
194
+ * Example 5: Build a complete concept map with all relationships
195
+ */
196
+ function buildCompleteConceptMap(linkbases) {
197
+ var conceptMap = new Map();
198
+ // Extract all relationships
199
+ var presentationHierarchy = extractPresentationHierarchy(linkbases.presentation);
200
+ var calculationRelationships = extractCalculationRelationships(linkbases.calculation);
201
+ var dimensionalRelationships = extractDimensionalRelationships(linkbases.definition);
202
+ var labels = extractLabels(linkbases.label);
203
+ // Combine all concepts
204
+ var allConcepts = new Set(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], Object.keys(presentationHierarchy), true), Object.keys(calculationRelationships), true), Object.keys(dimensionalRelationships), true), Object.keys(labels), true));
205
+ // Build complete concept entries
206
+ allConcepts.forEach(function (concept) {
207
+ conceptMap.set(concept, {
208
+ name: concept,
209
+ labels: labels[concept] || [],
210
+ presentation: presentationHierarchy[concept] || null,
211
+ calculation: calculationRelationships[concept] || null,
212
+ dimensions: dimensionalRelationships[concept] || null,
213
+ });
214
+ });
215
+ return conceptMap;
216
+ }
217
+ exports.buildCompleteConceptMap = buildCompleteConceptMap;
218
+ // Helper functions and types
219
+ function extractConceptFromHref(href) {
220
+ var match = href.match(/#(.+)$/);
221
+ return match ? match[1] : '';
222
+ }
223
+ function initializeDimension(dimensions, concept, type) {
224
+ if (!dimensions[concept]) {
225
+ dimensions[concept] = {
226
+ concept: concept,
227
+ type: type,
228
+ dimensions: [],
229
+ domains: [],
230
+ members: [],
231
+ };
232
+ }
233
+ }
234
+ function extractLabels(labelLinkbase) {
235
+ var _a;
236
+ var labels = {};
237
+ (_a = labelLinkbase.labelLink) === null || _a === void 0 ? void 0 : _a.forEach(function (link) {
238
+ var locators = (link.loc || []);
239
+ var arcs = (link.labelArc || []);
240
+ var labelResources = link.label || [];
241
+ // Build concept reference map
242
+ var conceptMap = new Map();
243
+ locators.forEach(function (loc) {
244
+ var concept = extractConceptFromHref(loc.href);
245
+ conceptMap.set(loc.label, concept);
246
+ });
247
+ // Connect labels to concepts
248
+ arcs.forEach(function (arc) {
249
+ var concept = conceptMap.get(arc.from);
250
+ var labelResource = labelResources.find(function (r) { return r.label === arc.to; });
251
+ if (concept && labelResource) {
252
+ labels[concept] = labels[concept] || [];
253
+ labels[concept].push({
254
+ text: labelResource.text || '',
255
+ role: labelResource.role || '',
256
+ lang: labelResource.lang || 'en',
257
+ });
258
+ }
259
+ });
260
+ });
261
+ return labels;
262
+ }
263
+ // Usage examples:
264
+ function usageExamples() {
265
+ // Example: Get all revenue facts broken down by segment
266
+ var segmentRevenue = findFactsWithDimensions({}, // Your XBRL instance
267
+ 'us-gaap:Revenues', [{ dimension: 'us-gaap:SegmentDomain' }]);
268
+ // Example: Get specific segment revenue
269
+ var northAmericaRevenue = findFactsWithDimensions({}, 'us-gaap:Revenues', [
270
+ {
271
+ dimension: 'us-gaap:SegmentDomain',
272
+ member: 'us-gaap:NorthAmericaSegmentMember',
273
+ },
274
+ ]);
275
+ return { segmentRevenue: segmentRevenue, northAmericaRevenue: northAmericaRevenue };
276
+ }
277
+ exports.usageExamples = usageExamples;
@@ -0,0 +1,145 @@
1
+ import type { XbrlInstance, XbrlLinkbase, XbrlSchema } from '../types';
2
+ export declare class XbrlRelationshipBuilder {
3
+ private instance;
4
+ private schema;
5
+ private presentationLinkbase;
6
+ private calculationLinkbase;
7
+ private definitionLinkbase;
8
+ private labelLinkbase;
9
+ constructor(data: {
10
+ instance: XbrlInstance;
11
+ schema: XbrlSchema;
12
+ presentationLinkbase: XbrlLinkbase;
13
+ calculationLinkbase: XbrlLinkbase;
14
+ definitionLinkbase: XbrlLinkbase;
15
+ labelLinkbase: XbrlLinkbase;
16
+ });
17
+ /**
18
+ * 1. PRESENTATION LINKBASE - Defines hierarchical structure
19
+ * Shows how concepts are organized in financial statements
20
+ */
21
+ buildPresentationHierarchy(): Record<string, ConceptHierarchy>;
22
+ /**
23
+ * 2. CALCULATION LINKBASE - Defines mathematical relationships
24
+ * Shows how concepts add up to totals
25
+ */
26
+ buildCalculationRelationships(): Record<string, CalculationRelationship>;
27
+ /**
28
+ * 3. DEFINITION LINKBASE - Defines dimensional relationships
29
+ * Shows axis, members, domains, and hypercubes
30
+ */
31
+ buildDimensionalRelationships(): Record<string, DimensionalRelationship>;
32
+ /**
33
+ * 4. LABEL LINKBASE - Provides human-readable labels
34
+ * Maps concepts to their display labels
35
+ */
36
+ buildLabelMappings(): Record<string, ConceptLabel[]>;
37
+ /**
38
+ * 5. RELATING FACTS TO DIMENSIONS
39
+ * Shows how actual data values relate to dimensional context
40
+ */
41
+ buildFactDimensionalMappings(): FactDimensionalMapping[];
42
+ /**
43
+ * 6. COMPREHENSIVE TAXONOMY MAPPING
44
+ * Combines all relationships into a unified structure
45
+ */
46
+ buildComprehensiveTaxonomyMap(): {
47
+ presentation: Record<string, ConceptHierarchy>;
48
+ calculations: Record<string, CalculationRelationship>;
49
+ dimensions: Record<string, DimensionalRelationship>;
50
+ labels: Record<string, ConceptLabel[]>;
51
+ factMappings: FactDimensionalMapping[];
52
+ getConceptChildren: (concept: string) => ConceptChild[];
53
+ getConceptCalculation: (concept: string) => CalculationRelationship;
54
+ getConceptLabels: (concept: string) => ConceptLabel[];
55
+ getFactsForConcept: (concept: string) => FactDimensionalMapping[];
56
+ getDimensionsForConcept: (concept: string) => DimensionalRelationship;
57
+ };
58
+ private getLocators;
59
+ private getPresentationArcs;
60
+ private getCalculationArcs;
61
+ private getDefinitionArcs;
62
+ private getLabelArcs;
63
+ private getLabelResources;
64
+ private getConceptFromLocator;
65
+ private addHypercubeDimension;
66
+ private addDimensionDomain;
67
+ private addDomainMember;
68
+ private addAllRelationship;
69
+ }
70
+ interface ConceptHierarchy {
71
+ concept: string;
72
+ children: ConceptChild[];
73
+ order: number;
74
+ role: string;
75
+ }
76
+ interface ConceptChild {
77
+ concept: string;
78
+ order: number;
79
+ preferredLabel?: string;
80
+ }
81
+ interface CalculationRelationship {
82
+ summationItem: string;
83
+ contributingItems: CalculationItem[];
84
+ }
85
+ interface CalculationItem {
86
+ concept: string;
87
+ weight: number;
88
+ order: number;
89
+ }
90
+ interface DimensionalRelationship {
91
+ type: 'hypercube' | 'dimension' | 'domain' | 'member';
92
+ concept: string;
93
+ dimensions?: DimensionalItem[];
94
+ domains?: DimensionalItem[];
95
+ members?: DimensionalItem[];
96
+ all?: DimensionalItem[];
97
+ }
98
+ interface DimensionalItem {
99
+ concept: string;
100
+ type: string;
101
+ }
102
+ interface ConceptLabel {
103
+ text: string;
104
+ role: string;
105
+ lang: string;
106
+ }
107
+ interface FactDimensionalMapping {
108
+ factName: string;
109
+ value: string;
110
+ unit: string;
111
+ context: DimensionalContext;
112
+ contextRef: string;
113
+ }
114
+ interface DimensionalContext {
115
+ entity: string;
116
+ period: {
117
+ startDate?: string;
118
+ endDate?: string;
119
+ instant?: string;
120
+ };
121
+ dimensions: {
122
+ dimension: string;
123
+ member: string;
124
+ }[];
125
+ }
126
+ export declare function exampleUsage(xbrlData: {
127
+ instance: XbrlInstance;
128
+ schema: XbrlSchema;
129
+ presentationLinkbase: XbrlLinkbase;
130
+ calculationLinkbase: XbrlLinkbase;
131
+ definitionLinkbase: XbrlLinkbase;
132
+ labelLinkbase: XbrlLinkbase;
133
+ }): {
134
+ presentation: Record<string, ConceptHierarchy>;
135
+ calculations: Record<string, CalculationRelationship>;
136
+ dimensions: Record<string, DimensionalRelationship>;
137
+ labels: Record<string, ConceptLabel[]>;
138
+ factMappings: FactDimensionalMapping[];
139
+ getConceptChildren: (concept: string) => ConceptChild[];
140
+ getConceptCalculation: (concept: string) => CalculationRelationship;
141
+ getConceptLabels: (concept: string) => ConceptLabel[];
142
+ getFactsForConcept: (concept: string) => FactDimensionalMapping[];
143
+ getDimensionsForConcept: (concept: string) => DimensionalRelationship;
144
+ };
145
+ export {};
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.exampleUsage = exports.XbrlRelationshipBuilder = void 0;
40
+ /**
41
+ * Example of how to use XBRL types to relate taxonomies, axis, members, and facts
42
+ * using linkbases (calculation, presentation, definition, etc.)
43
+ */
44
+ var fs = require("fs");
45
+ var __1 = require("..");
46
+ // Example: Building a comprehensive XBRL relationship map
47
+ var XbrlRelationshipBuilder = /** @class */ (function () {
48
+ function XbrlRelationshipBuilder(data) {
49
+ this.instance = data.instance;
50
+ this.schema = data.schema;
51
+ this.presentationLinkbase = data.presentationLinkbase;
52
+ this.calculationLinkbase = data.calculationLinkbase;
53
+ this.definitionLinkbase = data.definitionLinkbase;
54
+ this.labelLinkbase = data.labelLinkbase;
55
+ }
56
+ /**
57
+ * 1. PRESENTATION LINKBASE - Defines hierarchical structure
58
+ * Shows how concepts are organized in financial statements
59
+ */
60
+ XbrlRelationshipBuilder.prototype.buildPresentationHierarchy = function () {
61
+ var _this = this;
62
+ var _a;
63
+ var hierarchy = {};
64
+ // Process presentation links
65
+ (_a = this.presentationLinkbase.presentationLink) === null || _a === void 0 ? void 0 : _a.forEach(function (link) {
66
+ var roleUri = link.role || '';
67
+ // Get locators (concept references)
68
+ var locators = _this.getLocators(link);
69
+ var arcs = _this.getPresentationArcs(link);
70
+ // Build parent-child relationships
71
+ arcs.forEach(function (arc) {
72
+ var parentConcept = _this.getConceptFromLocator(locators, arc.from);
73
+ var childConcept = _this.getConceptFromLocator(locators, arc.to);
74
+ if (parentConcept && childConcept) {
75
+ hierarchy[parentConcept] = hierarchy[parentConcept] || {
76
+ concept: parentConcept,
77
+ children: [],
78
+ order: arc.order || 0,
79
+ role: roleUri,
80
+ };
81
+ hierarchy[parentConcept].children.push({
82
+ concept: childConcept,
83
+ order: arc.order || 0,
84
+ preferredLabel: arc.preferredLabel,
85
+ });
86
+ }
87
+ });
88
+ });
89
+ return hierarchy;
90
+ };
91
+ /**
92
+ * 2. CALCULATION LINKBASE - Defines mathematical relationships
93
+ * Shows how concepts add up to totals
94
+ */
95
+ XbrlRelationshipBuilder.prototype.buildCalculationRelationships = function () {
96
+ var _this = this;
97
+ var _a;
98
+ var calculations = {};
99
+ (_a = this.calculationLinkbase.calculationLink) === null || _a === void 0 ? void 0 : _a.forEach(function (link) {
100
+ var locators = _this.getLocators(link);
101
+ var arcs = _this.getCalculationArcs(link);
102
+ arcs.forEach(function (arc) {
103
+ var summationConcept = _this.getConceptFromLocator(locators, arc.to);
104
+ var itemConcept = _this.getConceptFromLocator(locators, arc.from);
105
+ if (summationConcept && itemConcept) {
106
+ calculations[summationConcept] = calculations[summationConcept] || {
107
+ summationItem: summationConcept,
108
+ contributingItems: [],
109
+ };
110
+ calculations[summationConcept].contributingItems.push({
111
+ concept: itemConcept,
112
+ weight: arc.weight || 1,
113
+ order: arc.order || 0,
114
+ });
115
+ }
116
+ });
117
+ });
118
+ return calculations;
119
+ };
120
+ /**
121
+ * 3. DEFINITION LINKBASE - Defines dimensional relationships
122
+ * Shows axis, members, domains, and hypercubes
123
+ */
124
+ XbrlRelationshipBuilder.prototype.buildDimensionalRelationships = function () {
125
+ var _this = this;
126
+ var _a;
127
+ var dimensions = {};
128
+ (_a = this.definitionLinkbase.definitionLink) === null || _a === void 0 ? void 0 : _a.forEach(function (link) {
129
+ var locators = _this.getLocators(link);
130
+ var arcs = _this.getDefinitionArcs(link);
131
+ arcs.forEach(function (arc) {
132
+ var arcrole = arc.arcrole || '';
133
+ var fromConcept = _this.getConceptFromLocator(locators, arc.from);
134
+ var toConcept = _this.getConceptFromLocator(locators, arc.to);
135
+ if (fromConcept && toConcept) {
136
+ // Different arcroles define different relationship types
137
+ switch (arcrole) {
138
+ case 'http://xbrl.org/int/dim/arcrole/hypercube-dimension':
139
+ // Hypercube to dimension relationship
140
+ _this.addHypercubeDimension(dimensions, fromConcept, toConcept);
141
+ break;
142
+ case 'http://xbrl.org/int/dim/arcrole/dimension-domain':
143
+ // Dimension to domain relationship
144
+ _this.addDimensionDomain(dimensions, fromConcept, toConcept);
145
+ break;
146
+ case 'http://xbrl.org/int/dim/arcrole/domain-member':
147
+ // Domain to member relationship
148
+ _this.addDomainMember(dimensions, fromConcept, toConcept);
149
+ break;
150
+ case 'http://xbrl.org/int/dim/arcrole/all':
151
+ // All relationship (for hypercubes)
152
+ _this.addAllRelationship(dimensions, fromConcept, toConcept);
153
+ break;
154
+ }
155
+ }
156
+ });
157
+ });
158
+ return dimensions;
159
+ };
160
+ /**
161
+ * 4. LABEL LINKBASE - Provides human-readable labels
162
+ * Maps concepts to their display labels
163
+ */
164
+ XbrlRelationshipBuilder.prototype.buildLabelMappings = function () {
165
+ var _this = this;
166
+ var _a;
167
+ var labels = {};
168
+ (_a = this.labelLinkbase.labelLink) === null || _a === void 0 ? void 0 : _a.forEach(function (link) {
169
+ var locators = _this.getLocators(link);
170
+ var arcs = _this.getLabelArcs(link);
171
+ var labelResources = _this.getLabelResources(link);
172
+ arcs.forEach(function (arc) {
173
+ var concept = _this.getConceptFromLocator(locators, arc.from);
174
+ var labelResource = labelResources.find(function (r) { return r.label === arc.to; });
175
+ if (concept && labelResource) {
176
+ labels[concept] = labels[concept] || [];
177
+ labels[concept].push({
178
+ text: labelResource.text || '',
179
+ role: labelResource.role || '',
180
+ lang: labelResource.lang || 'en',
181
+ });
182
+ }
183
+ });
184
+ });
185
+ return labels;
186
+ };
187
+ /**
188
+ * 5. RELATING FACTS TO DIMENSIONS
189
+ * Shows how actual data values relate to dimensional context
190
+ */
191
+ XbrlRelationshipBuilder.prototype.buildFactDimensionalMappings = function () {
192
+ var _this = this;
193
+ var factMappings = [];
194
+ this.instance.factElements.forEach(function (fact) {
195
+ var context = _this.instance.contexts.find(function (c) { return c.id === fact.contextRef; });
196
+ if (context) {
197
+ var dimensionalContext = {
198
+ entity: context.entity.identifier.value,
199
+ period: context.period,
200
+ dimensions: context.entity.segment.map(function (seg) { return ({
201
+ dimension: seg.dimension,
202
+ member: seg.value,
203
+ }); }),
204
+ };
205
+ factMappings.push({
206
+ factName: fact.name,
207
+ value: fact.text || '',
208
+ unit: fact.unitRef || '',
209
+ context: dimensionalContext,
210
+ contextRef: fact.contextRef,
211
+ });
212
+ }
213
+ });
214
+ return factMappings;
215
+ };
216
+ /**
217
+ * 6. COMPREHENSIVE TAXONOMY MAPPING
218
+ * Combines all relationships into a unified structure
219
+ */
220
+ XbrlRelationshipBuilder.prototype.buildComprehensiveTaxonomyMap = function () {
221
+ var presentation = this.buildPresentationHierarchy();
222
+ var calculations = this.buildCalculationRelationships();
223
+ var dimensions = this.buildDimensionalRelationships();
224
+ var labels = this.buildLabelMappings();
225
+ var factMappings = this.buildFactDimensionalMappings();
226
+ return {
227
+ presentation: presentation,
228
+ calculations: calculations,
229
+ dimensions: dimensions,
230
+ labels: labels,
231
+ factMappings: factMappings,
232
+ // Helper methods to navigate relationships
233
+ getConceptChildren: function (concept) { var _a; return ((_a = presentation[concept]) === null || _a === void 0 ? void 0 : _a.children) || []; },
234
+ getConceptCalculation: function (concept) { return calculations[concept]; },
235
+ getConceptLabels: function (concept) { return labels[concept] || []; },
236
+ getFactsForConcept: function (concept) { return factMappings.filter(function (f) { return f.factName === concept; }); },
237
+ getDimensionsForConcept: function (concept) { return dimensions[concept]; },
238
+ };
239
+ };
240
+ // Helper methods
241
+ XbrlRelationshipBuilder.prototype.getLocators = function (link) {
242
+ return (link.loc || []).filter(function (item) { return item.type === 'locator'; });
243
+ };
244
+ XbrlRelationshipBuilder.prototype.getPresentationArcs = function (link) {
245
+ return (link.presentationArc || []).filter(function (item) { return item.type === 'arc'; });
246
+ };
247
+ XbrlRelationshipBuilder.prototype.getCalculationArcs = function (link) {
248
+ return (link.calculationArc || []).filter(function (item) { return item.type === 'arc'; });
249
+ };
250
+ XbrlRelationshipBuilder.prototype.getDefinitionArcs = function (link) {
251
+ return (link.definitionArc || []).filter(function (item) { return item.type === 'arc'; });
252
+ };
253
+ XbrlRelationshipBuilder.prototype.getLabelArcs = function (link) {
254
+ return (link.labelArc || []).filter(function (item) { return item.type === 'arc'; });
255
+ };
256
+ XbrlRelationshipBuilder.prototype.getLabelResources = function (link) {
257
+ return (link.label || []).filter(function (item) { return item.type === 'resource'; });
258
+ };
259
+ XbrlRelationshipBuilder.prototype.getConceptFromLocator = function (locators, label) {
260
+ var locator = locators.find(function (loc) { return loc.label === label; });
261
+ if (!locator)
262
+ return null;
263
+ // Extract concept name from href (e.g., "concept.xsd#us-gaap_Assets")
264
+ var match = locator.href.match(/#(.+)$/);
265
+ return match ? match[1] : null;
266
+ };
267
+ XbrlRelationshipBuilder.prototype.addHypercubeDimension = function (dimensions, hypercube, dimension) {
268
+ dimensions[hypercube] = dimensions[hypercube] || { type: 'hypercube', concept: hypercube, dimensions: [] };
269
+ dimensions[hypercube].dimensions = dimensions[hypercube].dimensions || [];
270
+ dimensions[hypercube].dimensions.push({ concept: dimension, type: 'dimension' });
271
+ };
272
+ XbrlRelationshipBuilder.prototype.addDimensionDomain = function (dimensions, dimension, domain) {
273
+ dimensions[dimension] = dimensions[dimension] || { type: 'dimension', concept: dimension, domains: [] };
274
+ dimensions[dimension].domains = dimensions[dimension].domains || [];
275
+ dimensions[dimension].domains.push({ concept: domain, type: 'domain' });
276
+ };
277
+ XbrlRelationshipBuilder.prototype.addDomainMember = function (dimensions, domain, member) {
278
+ dimensions[domain] = dimensions[domain] || { type: 'domain', concept: domain, members: [] };
279
+ dimensions[domain].members = dimensions[domain].members || [];
280
+ dimensions[domain].members.push({ concept: member, type: 'member' });
281
+ };
282
+ XbrlRelationshipBuilder.prototype.addAllRelationship = function (dimensions, from, to) {
283
+ // Handle 'all' relationships for hypercubes
284
+ dimensions[from] = dimensions[from] || { type: 'hypercube', concept: from, all: [] };
285
+ dimensions[from].all = dimensions[from].all || [];
286
+ dimensions[from].all.push({ concept: to, type: 'all' });
287
+ };
288
+ return XbrlRelationshipBuilder;
289
+ }());
290
+ exports.XbrlRelationshipBuilder = XbrlRelationshipBuilder;
291
+ // Example usage:
292
+ function exampleUsage(xbrlData) {
293
+ var builder = new XbrlRelationshipBuilder(xbrlData);
294
+ var taxonomyMap = builder.buildComprehensiveTaxonomyMap();
295
+ // Example: Find all children of "Assets" concept
296
+ var assetChildren = taxonomyMap.getConceptChildren('us-gaap:Assets');
297
+ console.log('Asset children:', assetChildren);
298
+ // Example: Get calculation for "Assets" (what adds up to total assets)
299
+ var assetCalculation = taxonomyMap.getConceptCalculation('us-gaap:Assets');
300
+ console.log('Asset calculation:', assetCalculation);
301
+ // Example: Get all labels for "Assets" concept
302
+ var assetLabels = taxonomyMap.getConceptLabels('us-gaap:Assets');
303
+ console.log('Asset labels:', assetLabels);
304
+ // Example: Get all facts for "Assets" concept
305
+ var assetFacts = taxonomyMap.getFactsForConcept('us-gaap:Assets');
306
+ console.log('Asset facts:', assetFacts);
307
+ // Example: Get dimensional information for a concept
308
+ var assetDimensions = taxonomyMap.getDimensionsForConcept('us-gaap:Assets');
309
+ console.log('Asset dimensions:', assetDimensions);
310
+ return taxonomyMap;
311
+ }
312
+ exports.exampleUsage = exampleUsage;
313
+ function runExample() {
314
+ return __awaiter(this, void 0, void 0, function () {
315
+ var res, builder;
316
+ return __generator(this, function (_a) {
317
+ switch (_a.label) {
318
+ case 0: return [4 /*yield*/, __1.secEdgarApi.getDocumentXbrl({
319
+ url: 'https://www.sec.gov/Archives/edgar/data/320193/000032019324000123/0000320193-24-000123.txt',
320
+ })];
321
+ case 1:
322
+ res = _a.sent();
323
+ builder = new XbrlRelationshipBuilder({
324
+ calculationLinkbase: res.linkbaseCalculation.xbrl,
325
+ definitionLinkbase: res.linkbaseDefinition.xbrl,
326
+ instance: res.instance.xbrl,
327
+ labelLinkbase: res.linkbaseLabel.xbrl,
328
+ presentationLinkbase: res.linkbasePresentation.xbrl,
329
+ schema: res.schema.xbrl,
330
+ });
331
+ fs.writeFileSync('fact-dimensional-mappings.json', JSON.stringify(builder.buildFactDimensionalMappings(), null, 2));
332
+ return [2 /*return*/];
333
+ }
334
+ });
335
+ });
336
+ }
337
+ runExample();
@@ -62,22 +62,22 @@ var InstanceParser = /** @class */ (function () {
62
62
  };
63
63
  InstanceParser.prototype.parse = function (xml) {
64
64
  var _this = this;
65
- var _a, _b, _c;
65
+ var _a, _b, _c, _d;
66
66
  var xbrl = util_xbrl_1.default.extractXbrlObject(this.xmlParser.parse(xml));
67
67
  var contexts = util_xbrl_1.default
68
- .toArray((_b = (_a = xbrl === null || xbrl === void 0 ? void 0 : xbrl.context) !== null && _a !== void 0 ? _a : xbrl === null || xbrl === void 0 ? void 0 : xbrl['xbrli:context']) !== null && _b !== void 0 ? _b : [])
68
+ .toArray((_c = (_b = (_a = xbrl === null || xbrl === void 0 ? void 0 : xbrl.context) !== null && _a !== void 0 ? _a : xbrl === null || xbrl === void 0 ? void 0 : xbrl['xbrli:context']) !== null && _b !== void 0 ? _b : xbrl === null || xbrl === void 0 ? void 0 : xbrl['xbrl:context']) !== null && _c !== void 0 ? _c : [])
69
69
  .map(function (context) { return _this.parseContext(context); });
70
- var units = util_xbrl_1.default.toArray((_c = xbrl === null || xbrl === void 0 ? void 0 : xbrl.unit) !== null && _c !== void 0 ? _c : []).map(function (unit) {
71
- var _a, _b, _c, _d, _e;
70
+ var units = util_xbrl_1.default.toArray((_d = xbrl === null || xbrl === void 0 ? void 0 : xbrl.unit) !== null && _d !== void 0 ? _d : []).map(function (unit) {
71
+ var _a, _b, _c, _d, _e, _f, _g;
72
72
  return ({
73
73
  id: (_a = unit['@_id']) !== null && _a !== void 0 ? _a : '',
74
- measure: (_e = (_c = (_b = unit['xbrli:measure']) === null || _b === void 0 ? void 0 : _b['#text']) !== null && _c !== void 0 ? _c : (_d = unit['measure']) === null || _d === void 0 ? void 0 : _d['#text']) !== null && _e !== void 0 ? _e : '',
74
+ measure: (_g = (_e = (_c = (_b = unit['xbrli:measure']) === null || _b === void 0 ? void 0 : _b['#text']) !== null && _c !== void 0 ? _c : (_d = unit['measure']) === null || _d === void 0 ? void 0 : _d['#text']) !== null && _e !== void 0 ? _e : (_f = unit['xbrl:measure']) === null || _f === void 0 ? void 0 : _f['#text']) !== null && _g !== void 0 ? _g : '',
75
75
  });
76
76
  });
77
77
  var factElements = [];
78
78
  for (var name_1 in xbrl) {
79
- for (var _i = 0, _d = util_xbrl_1.default.toArray(xbrl[name_1]); _i < _d.length; _i++) {
80
- var element = _d[_i];
79
+ for (var _i = 0, _e = util_xbrl_1.default.toArray(xbrl[name_1]); _i < _e.length; _i++) {
80
+ var element = _e[_i];
81
81
  if (!element['@_contextRef'])
82
82
  continue;
83
83
  var factElement = { name: name_1, id: '', contextRef: '' };
@@ -24,6 +24,7 @@ var __rest = (this && this.__rest) || function (s, e) {
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.parseXbrl = void 0;
26
26
  var constants_1 = require("../../../util/constants");
27
+ var util_xbrl_1 = require("../../../util/util-xbrl");
27
28
  var FactFiscalCalculator_1 = require("../../ReportRawBuilder/FactFiscalCalculator");
28
29
  var FactPeriodResolver_1 = require("../../ReportRawBuilder/FactPeriodResolver");
29
30
  var XBRLParser_1 = require("../XBRLParser/XBRLParser");
@@ -36,8 +37,8 @@ function isWithinDays(params) {
36
37
  return daysDiff < days;
37
38
  }
38
39
  function buildReportsFromFacts(params) {
39
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
40
- var filing = params.filing, facts = params.facts, fiscalPeriod = params.fiscalPeriod, fiscalYear = params.fiscalYear, pathSeparator = params.pathSeparator, cikProp = params.cik, fiscalYearEnd = params.fiscalYearEnd;
40
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
41
+ var filing = params.filing, facts = params.facts, fiscalPeriod = params.fiscalPeriod, fiscalYear = params.fiscalYear, pathSeparator = params.pathSeparator, cikProp = params.cik;
41
42
  var urlParts = (_a = filing === null || filing === void 0 ? void 0 : filing.url.split('/')) !== null && _a !== void 0 ? _a : [];
42
43
  var cik = cikProp !== null && cikProp !== void 0 ? cikProp : urlParts[(_b = urlParts.indexOf('data')) !== null && _b !== void 0 ? _b : -1];
43
44
  var reportFactValues = {
@@ -63,37 +64,38 @@ function buildReportsFromFacts(params) {
63
64
  var roundPlacesByName = new Map();
64
65
  var scaleByName = new Map();
65
66
  var isFocusFactByDateKey = new Map();
66
- var fiscalYearEndMonth = Number(fiscalYearEnd.substring(0, 2));
67
- var fiscalYearEndDay = Number(fiscalYearEnd.substring(2));
68
- var fiscalCalculator = new FactFiscalCalculator_1.default({
69
- filings: filing ? [filing] : undefined,
70
- facts: facts,
71
- fiscalYearEnd: { day: fiscalYearEndDay, month: fiscalYearEndMonth },
72
- });
73
67
  var fiscalsByDateKey = new Map();
68
+ var focusPeriodByQuarter = {
69
+ 1: 3,
70
+ 2: 6,
71
+ 3: 9,
72
+ 4: 12,
73
+ };
74
74
  for (var _i = 0, facts_1 = facts; _i < facts_1.length; _i++) {
75
75
  var fact = facts_1[_i];
76
- var dateKey = fact.start ? "".concat(fact.start, "_").concat(fact.end) : fact.end;
76
+ var period = FactPeriodResolver_1.default.getPeriod({ start: fact.start, end: fact.end });
77
+ var dateKey = fact.start ? "".concat(fact.start, "_").concat(fact.end, "_").concat(period) : "".concat(fact.end, "_").concat(period);
77
78
  if (!fiscalsByDateKey.has(dateKey)) {
78
- var _w = fiscalCalculator.getFiscalYearQuarter({ dateStr: fact.end }), quarter = _w.quarter, year = _w.year;
79
- var period = FactPeriodResolver_1.default.getPeriod({ end: fact.end, start: fact.start });
80
- var fiscalPeriod_1 = (period === 12 && quarter === 4 ? 'FY' : "Q".concat(quarter));
81
- fiscalsByDateKey.set(dateKey, { fiscalYear: year, fiscalPeriod: fiscalPeriod_1 });
79
+ var fiscalPeriod_1 = (period === 12 && fact.quarter === 4 ? 'FY' : "Q".concat(fact.quarter));
80
+ fiscalsByDateKey.set(dateKey, { fiscalYear: fact.fiscalYear, fiscalPeriod: fiscalPeriod_1 });
82
81
  }
83
82
  var isSplitFact = fact === splitFact;
84
- var isFocusFact = (_h = isFocusFactByDateKey.get(dateKey)) !== null && _h !== void 0 ? _h : (isWithinDays({ dateA: fact.end, dateB: reportFocus.dateReport, days: 45 }) || isSplitFact);
85
- (_j = reportByDateRange[dateKey]) !== null && _j !== void 0 ? _j : (reportByDateRange[dateKey] = {
83
+ var focusPeriod = (_h = focusPeriodByQuarter[fact.quarter]) !== null && _h !== void 0 ? _h : 0;
84
+ var isFocusPeriod = period === focusPeriod || period === 0;
85
+ var isFocusFact = (_j = isFocusFactByDateKey.get(dateKey)) !== null && _j !== void 0 ? _j : (isFocusPeriod &&
86
+ (isWithinDays({ dateA: fact.end, dateB: reportFocus.dateReport, days: 45 }) || isSplitFact));
87
+ (_k = reportByDateRange[dateKey]) !== null && _k !== void 0 ? _k : (reportByDateRange[dateKey] = {
86
88
  cik: reportFocus.cik,
87
- url: '',
88
- splitDate: (_k = splitFact === null || splitFact === void 0 ? void 0 : splitFact.end) !== null && _k !== void 0 ? _k : null,
89
+ url: (_l = filing === null || filing === void 0 ? void 0 : filing.url) !== null && _l !== void 0 ? _l : '',
90
+ splitDate: (_m = splitFact === null || splitFact === void 0 ? void 0 : splitFact.end) !== null && _m !== void 0 ? _m : null,
89
91
  splitRatio: (splitFact === null || splitFact === void 0 ? void 0 : splitFact.value) ? Number(splitFact.value) : null,
90
92
  dateFiled: reportFocus.dateFiled,
91
93
  dateReport: fact.end,
92
- fiscalPeriod: (_l = fiscalsByDateKey.get(dateKey)) === null || _l === void 0 ? void 0 : _l.fiscalPeriod,
93
- startDate: (_m = fact.start) !== null && _m !== void 0 ? _m : '',
94
+ fiscalPeriod: (_o = fiscalsByDateKey.get(dateKey)) === null || _o === void 0 ? void 0 : _o.fiscalPeriod,
95
+ startDate: (_p = fact.start) !== null && _p !== void 0 ? _p : '',
94
96
  endDate: fact.end,
95
- fiscalYear: (_o = fiscalsByDateKey.get(dateKey)) === null || _o === void 0 ? void 0 : _o.fiscalYear,
96
- period: FactPeriodResolver_1.default.getPeriod({ start: fact.start, end: fact.end }),
97
+ fiscalYear: (_q = fiscalsByDateKey.get(dateKey)) === null || _q === void 0 ? void 0 : _q.fiscalYear,
98
+ period: period,
97
99
  isCurrentPeriod: isFocusFact,
98
100
  });
99
101
  if (isFocusFact) {
@@ -103,11 +105,11 @@ function buildReportsFromFacts(params) {
103
105
  isFocusFactByDateKey.set(dateKey, isFocusFact);
104
106
  }
105
107
  var el = fact;
106
- var scale = Number((_p = el.scale) !== null && _p !== void 0 ? _p : 0) || 0;
107
- var decimals = Number((_q = el.decimals) !== null && _q !== void 0 ? _q : 0) || 0;
108
+ var scale = Number((_r = el.scale) !== null && _r !== void 0 ? _r : 0) || 0;
109
+ var decimals = Number((_s = el.decimals) !== null && _s !== void 0 ? _s : 0) || 0;
108
110
  var suffix = fact.name.includes(pathSeparator)
109
111
  ? null
110
- : (_r = fact === null || fact === void 0 ? void 0 : fact.segments) === null || _r === void 0 ? void 0 : _r.map(function (_a) {
112
+ : (_t = fact === null || fact === void 0 ? void 0 : fact.segments) === null || _t === void 0 ? void 0 : _t.map(function (_a) {
111
113
  var dimension = _a.dimension, value = _a.value;
112
114
  return "".concat(dimension).concat(pathSeparator).concat(value);
113
115
  }).join(pathSeparator);
@@ -121,8 +123,8 @@ function buildReportsFromFacts(params) {
121
123
  var prevRounding = roundPlacesByName.get(prevFactKey);
122
124
  var prevScale = scaleByName.get(prevFactKey);
123
125
  var prevFact_1 = factByName.get(prevFactKey);
124
- var prevUnit = (_t = (_s = prevFact_1 === null || prevFact_1 === void 0 ? void 0 : prevFact_1.unit) === null || _s === void 0 ? void 0 : _s.split('_').pop()) === null || _t === void 0 ? void 0 : _t.toLowerCase();
125
- var unit = (_v = (_u = fact.unit) === null || _u === void 0 ? void 0 : _u.split('_').pop()) === null || _v === void 0 ? void 0 : _v.toLowerCase();
126
+ var prevUnit = (_v = (_u = prevFact_1 === null || prevFact_1 === void 0 ? void 0 : prevFact_1.unit) === null || _u === void 0 ? void 0 : _u.split('_').pop()) === null || _v === void 0 ? void 0 : _v.toLowerCase();
127
+ var unit = (_x = (_w = fact.unit) === null || _w === void 0 ? void 0 : _w.split('_').pop()) === null || _x === void 0 ? void 0 : _x.toLowerCase();
126
128
  var shouldSkip = [
127
129
  (prevUnit === null || prevUnit === void 0 ? void 0 : prevUnit.length) === 3 && (unit === null || unit === void 0 ? void 0 : unit.length) === 3 && prevUnit !== unit && prevUnit === 'usd',
128
130
  (prevRounding !== null && prevRounding !== void 0 ? prevRounding : 0) < roundPlaces,
@@ -149,33 +151,46 @@ function buildReportsFromFacts(params) {
149
151
  return { reportFocus: reportFocus, reportByDateRange: reportByDateRange, factsFiltered: Array.from(factByName.values()) };
150
152
  }
151
153
  function parseXbrl(params) {
152
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
154
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
153
155
  var parser = new XBRLParser_1.default();
154
- var xml = params.xml, _o = params.includeReport, includeReport = _o === void 0 ? true : _o, options = __rest(params, ["xml", "includeReport"]);
156
+ var xml = params.xml, _r = params.includeReport, includeReport = _r === void 0 ? true : _r, options = __rest(params, ["xml", "includeReport"]);
155
157
  var response = parser.parse(xml, options);
156
- var _p = (_b = (_a = response.instance) === null || _a === void 0 ? void 0 : _a.xbrl) !== null && _b !== void 0 ? _b : {}, _q = _p.contexts, contexts = _q === void 0 ? [] : _q, _r = _p.factElements, factElements = _r === void 0 ? [] : _r;
158
+ var _s = (_b = (_a = response.instance) === null || _a === void 0 ? void 0 : _a.xbrl) !== null && _b !== void 0 ? _b : {}, _t = _s.contexts, contexts = _t === void 0 ? [] : _t, _u = _s.factElements, factElements = _u === void 0 ? [] : _u;
159
+ var labelByTaxonomy = (0, util_xbrl_1.getLabelByTaxonomy)((_d = (_c = response.linkbaseLabel) === null || _c === void 0 ? void 0 : _c.xbrl) !== null && _d !== void 0 ? _d : {});
157
160
  var contextById = new Map();
158
161
  contexts.forEach(function (context) { return contextById.set(context.id, context); });
159
162
  var cik = response.header.cik;
160
163
  var accessionNumber = response.header.accessionNumber;
161
164
  var accessionNumberNoHyphens = accessionNumber.replace(/-/g, '');
165
+ var fiscalCalculator = new FactFiscalCalculator_1.default({
166
+ fiscalYearEnd: {
167
+ day: Number(response.header.fiscalYearEnd.substring(2)),
168
+ month: Number(response.header.fiscalYearEnd.substring(0, 2)),
169
+ },
170
+ });
162
171
  var facts = [];
163
172
  for (var _i = 0, factElements_1 = factElements; _i < factElements_1.length; _i++) {
164
173
  var fact = factElements_1[_i];
165
174
  var context = contextById.get(fact.contextRef);
166
- var end = (_d = (_c = context === null || context === void 0 ? void 0 : context.period.endDate) !== null && _c !== void 0 ? _c : context === null || context === void 0 ? void 0 : context.period.instant) !== null && _d !== void 0 ? _d : '';
175
+ var end = (_f = (_e = context === null || context === void 0 ? void 0 : context.period.endDate) !== null && _e !== void 0 ? _e : context === null || context === void 0 ? void 0 : context.period.instant) !== null && _f !== void 0 ? _f : '';
167
176
  var start = context === null || context === void 0 ? void 0 : context.period.startDate;
177
+ var _v = fiscalCalculator.getFiscalYearQuarter({ dateStr: end }), quarter = _v.quarter, year = _v.year;
168
178
  var factParsed = {
169
179
  cik: cik,
170
180
  end: end,
171
181
  filed: response.header.filingDate,
172
182
  name: fact.name,
173
- unit: (_e = fact.unitRef) !== null && _e !== void 0 ? _e : 'pure',
183
+ unit: (_g = fact.unitRef) !== null && _g !== void 0 ? _g : 'pure',
174
184
  value: isNaN(Number(fact.text)) ? String(fact.text) : Number(fact.text),
175
185
  accn: accessionNumber,
176
186
  form: response.header.form,
177
- segments: (_f = context === null || context === void 0 ? void 0 : context.entity.segment) !== null && _f !== void 0 ? _f : [],
187
+ segments: (_h = context === null || context === void 0 ? void 0 : context.entity.segment) !== null && _h !== void 0 ? _h : [],
178
188
  start: start,
189
+ contextRef: fact.contextRef,
190
+ label: (_j = labelByTaxonomy[fact.name]) !== null && _j !== void 0 ? _j : fact.name,
191
+ period: FactPeriodResolver_1.default.getPeriod({ start: start, end: end }),
192
+ quarter: quarter,
193
+ fiscalYear: year,
179
194
  };
180
195
  if (factParsed.decimals) {
181
196
  factParsed.decimals = Number(fact.decimals);
@@ -190,28 +205,21 @@ function parseXbrl(params) {
190
205
  var fiscalYear = fiscalYearFact ? Number(fiscalYearFact.value) : 0;
191
206
  var fiscalPeriod = fiscalPeriodFact ? fiscalPeriodFact.value : 'FY';
192
207
  if (!fiscalPeriodFact || !fiscalYearFact) {
193
- var fiscalCalculator = new FactFiscalCalculator_1.default({
194
- fiscalYearEnd: {
195
- day: Number(response.header.fiscalYearEnd.substring(2)),
196
- month: Number(response.header.fiscalYearEnd.substring(0, 2)),
197
- },
198
- });
199
- var reportDate = (_g = response.header.reportDate) !== null && _g !== void 0 ? _g : (_j = (_h = response.instance) === null || _h === void 0 ? void 0 : _h.xbrl.factElements.find(function (f) { return f.name === 'dei:DocumentPeriodEndDate'; })) === null || _j === void 0 ? void 0 : _j.text;
208
+ var reportDate = (_k = response.header.reportDate) !== null && _k !== void 0 ? _k : (_m = (_l = response.instance) === null || _l === void 0 ? void 0 : _l.xbrl.factElements.find(function (f) { return f.name === 'dei:DocumentPeriodEndDate'; })) === null || _m === void 0 ? void 0 : _m.text;
200
209
  if (!reportDate) {
201
210
  throw new Error("Report date not found. Unable to determine fiscal year and period. accn: ".concat(accessionNumber));
202
211
  }
203
- var _s = fiscalCalculator.getFiscalYearQuarter({ dateStr: reportDate !== null && reportDate !== void 0 ? reportDate : '' }), quarter = _s.quarter, year = _s.year;
212
+ var _w = fiscalCalculator.getFiscalYearQuarter({ dateStr: reportDate !== null && reportDate !== void 0 ? reportDate : '' }), quarter = _w.quarter, year = _w.year;
204
213
  fiscalYear = year;
205
214
  fiscalPeriod = (quarter === 4 ? 'FY' : "Q".concat(quarter));
206
215
  }
207
216
  var factsForBuilder = includeReport ? facts : [];
208
- var _t = buildReportsFromFacts({
217
+ var _x = buildReportsFromFacts({
209
218
  facts: factsForBuilder,
210
219
  pathSeparator: '>',
211
- fiscalPeriod: (_k = factsForBuilder.find(function (f) { return f.name === 'dei:DocumentFiscalPeriodFocus'; })) === null || _k === void 0 ? void 0 : _k.value,
212
- fiscalYear: Number((_m = (_l = factsForBuilder.find(function (f) { return f.name === 'dei:DocumentFiscalYearFocus'; })) === null || _l === void 0 ? void 0 : _l.value) !== null && _m !== void 0 ? _m : 0),
220
+ fiscalPeriod: (_o = factsForBuilder.find(function (f) { return f.name === 'dei:DocumentFiscalPeriodFocus'; })) === null || _o === void 0 ? void 0 : _o.value,
221
+ fiscalYear: Number((_q = (_p = factsForBuilder.find(function (f) { return f.name === 'dei:DocumentFiscalYearFocus'; })) === null || _p === void 0 ? void 0 : _p.value) !== null && _q !== void 0 ? _q : 0),
213
222
  cik: response.header.cik,
214
- fiscalYearEnd: response.header.fiscalYearEnd,
215
223
  filing: {
216
224
  acceptanceDateTime: response.header.acceptanceDatetime,
217
225
  accessionNumber: accessionNumber,
@@ -230,7 +238,7 @@ function parseXbrl(params) {
230
238
  url: "https://www.sec.gov/Archives/edgar/data/".concat(cik, "/").concat(accessionNumberNoHyphens, "/").concat(accessionNumber, ".txt"),
231
239
  urlPrimaryDocument: '',
232
240
  },
233
- }), factsFiltered = _t.factsFiltered, reportFocus = _t.reportFocus, reportByDateRange = _t.reportByDateRange;
241
+ }), factsFiltered = _x.factsFiltered, reportFocus = _x.reportFocus, reportByDateRange = _x.reportByDateRange;
234
242
  // Some concepts have members, but do not have a sum. add the sum to the report.
235
243
  var periodReports = Object.values(reportByDateRange);
236
244
  return __assign(__assign({}, response), { fiscalYear: fiscalYear, fiscalPeriod: fiscalPeriod, facts: factsFiltered, report: factsFiltered.length > 0 ? reportFocus : null, xml: xml, periodReports: periodReports });
@@ -300,6 +300,7 @@ export default class SecEdgarApi {
300
300
  formType?: DailyFilingFormType;
301
301
  /** max 5 */
302
302
  lookbackDays?: number;
303
+ startsWith?: string;
303
304
  }): Promise<{
304
305
  date: string;
305
306
  matchCount: number;
@@ -595,11 +595,11 @@ var SecEdgarApi = /** @class */ (function () {
595
595
  SecEdgarApi.prototype.getCurrentFilingsDaily = function (params) {
596
596
  var _a;
597
597
  return __awaiter(this, void 0, void 0, function () {
598
- var _b, _c, formType, _d, lookbackDays, indexByFormType, indexFormType, url, xml;
599
- return __generator(this, function (_e) {
600
- switch (_e.label) {
598
+ var _b, _c, formType, _d, lookbackDays, _e, startsWith, indexByFormType, indexFormType, url, xml;
599
+ return __generator(this, function (_f) {
600
+ switch (_f.label) {
601
601
  case 0:
602
- _b = params !== null && params !== void 0 ? params : {}, _c = _b.formType, formType = _c === void 0 ? 'ALL' : _c, _d = _b.lookbackDays, lookbackDays = _d === void 0 ? 0 : _d;
602
+ _b = params !== null && params !== void 0 ? params : {}, _c = _b.formType, formType = _c === void 0 ? 'ALL' : _c, _d = _b.lookbackDays, lookbackDays = _d === void 0 ? 0 : _d, _e = _b.startsWith, startsWith = _e === void 0 ? '' : _e;
603
603
  if (lookbackDays > 5) {
604
604
  throw new Error("lookbackDays must be <= 5. Received ".concat(lookbackDays));
605
605
  }
@@ -613,10 +613,10 @@ var SecEdgarApi = /** @class */ (function () {
613
613
  ALL: 6,
614
614
  };
615
615
  indexFormType = (_a = indexByFormType[formType]) !== null && _a !== void 0 ? _a : 0;
616
- url = "".concat(this.baseUrlSec, "/cgi-bin/current?q1=").concat(lookbackDays, "&q2=").concat(indexFormType);
616
+ url = "".concat(this.baseUrlSec, "/cgi-bin/current?q1=").concat(lookbackDays, "&q2=").concat(indexFormType, "&q3=").concat(startsWith);
617
617
  return [4 /*yield*/, this.request(url, true)];
618
618
  case 1:
619
- xml = (_e.sent());
619
+ xml = (_f.sent());
620
620
  return [2 /*return*/, this.documentParser.parseCurrentFilingsDaily({ xml: xml })];
621
621
  }
622
622
  });
@@ -79,6 +79,11 @@ export interface FactItemExtended extends FactItem {
79
79
  isCurrentPeriod?: boolean;
80
80
  decimals?: number;
81
81
  scale?: number;
82
+ contextRef: string;
83
+ label: string;
84
+ period: number;
85
+ quarter: number;
86
+ fiscalYear: number;
82
87
  }
83
88
  export interface FactItemWithFiscals extends FactItem {
84
89
  fiscalPeriod: FiscalPeriod;
@@ -0,0 +1,3 @@
1
+ import { XbrlLinkbase } from '../types/xbrl.type';
2
+ export declare function getLabelByTaxonomy(labelLinkbase: XbrlLinkbase): Record<string, string>;
3
+ export declare function getTaxonomyFromId(id: string): string;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTaxonomyFromId = exports.getLabelByTaxonomy = void 0;
4
+ function getLabelByTaxonomy(labelLinkbase) {
5
+ var _a;
6
+ var labelByTaxonomy = {};
7
+ (_a = labelLinkbase.labelLink) === null || _a === void 0 ? void 0 : _a.forEach(function (link) {
8
+ var _a;
9
+ (_a = link.label) === null || _a === void 0 ? void 0 : _a.forEach(function (_a) {
10
+ var _b = _a.label, label = _b === void 0 ? '' : _b, _c = _a.text, text = _c === void 0 ? '' : _c, _d = _a.role, role = _d === void 0 ? '' : _d;
11
+ var taxonomy = getTaxonomyFromId(label);
12
+ // prefer terseLabel over regular label
13
+ if (role.endsWith('terseLabel') || !labelByTaxonomy[taxonomy]) {
14
+ labelByTaxonomy[taxonomy] = text;
15
+ }
16
+ });
17
+ });
18
+ return labelByTaxonomy;
19
+ }
20
+ exports.getLabelByTaxonomy = getLabelByTaxonomy;
21
+ function getTaxonomyFromId(id) {
22
+ return id.split('_').slice(1, 3).join(':');
23
+ }
24
+ exports.getTaxonomyFromId = getTaxonomyFromId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sec-edgar-api",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
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)",