@cyvest/cyvest-js 4.4.0 → 5.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,6 +1,148 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ LEVEL_COLORS: () => LEVEL_COLORS,
34
+ LEVEL_ORDER: () => LEVEL_ORDER,
35
+ LEVEL_VALUES: () => LEVEL_VALUES,
36
+ areConnected: () => areConnected,
37
+ compareLevels: () => compareLevels,
38
+ countRelationshipsByType: () => countRelationshipsByType,
39
+ findCheckByName: () => findCheckByName,
40
+ findChecksAtLeast: () => findChecksAtLeast,
41
+ findChecksByLevel: () => findChecksByLevel,
42
+ findChecksForObservable: () => findChecksForObservable,
43
+ findChecksForTag: () => findChecksForTag,
44
+ findExternalObservables: () => findExternalObservables,
45
+ findHighestScoringChecks: () => findHighestScoringChecks,
46
+ findHighestScoringObservables: () => findHighestScoringObservables,
47
+ findInternalObservables: () => findInternalObservables,
48
+ findLeafObservables: () => findLeafObservables,
49
+ findMaliciousChecks: () => findMaliciousChecks,
50
+ findMaliciousObservables: () => findMaliciousObservables,
51
+ findObservablesAtLeast: () => findObservablesAtLeast,
52
+ findObservablesByLevel: () => findObservablesByLevel,
53
+ findObservablesByType: () => findObservablesByType,
54
+ findObservablesByValue: () => findObservablesByValue,
55
+ findObservablesContaining: () => findObservablesContaining,
56
+ findObservablesForCheck: () => findObservablesForCheck,
57
+ findObservablesMatching: () => findObservablesMatching,
58
+ findObservablesWithThreatIntel: () => findObservablesWithThreatIntel,
59
+ findOrphanObservables: () => findOrphanObservables,
60
+ findPath: () => findPath,
61
+ findSourceObservables: () => findSourceObservables,
62
+ findSuspiciousChecks: () => findSuspiciousChecks,
63
+ findSuspiciousObservables: () => findSuspiciousObservables,
64
+ findTagsAtLeast: () => findTagsAtLeast,
65
+ findTagsByLevel: () => findTagsByLevel,
66
+ findTagsByNamePattern: () => findTagsByNamePattern,
67
+ findThreatIntelAtLeast: () => findThreatIntelAtLeast,
68
+ findThreatIntelByLevel: () => findThreatIntelByLevel,
69
+ findThreatIntelBySource: () => findThreatIntelBySource,
70
+ findThreatIntelsForObservable: () => findThreatIntelsForObservable,
71
+ findWhitelistedObservables: () => findWhitelistedObservables,
72
+ generateCheckKey: () => generateCheckKey,
73
+ generateEnrichmentKey: () => generateEnrichmentKey,
74
+ generateObservableKey: () => generateObservableKey,
75
+ generateTagKey: () => generateTagKey,
76
+ generateThreatIntelKey: () => generateThreatIntelKey,
77
+ getAllCheckKeys: () => getAllCheckKeys,
78
+ getAllChecks: () => getAllChecks,
79
+ getAllEnrichments: () => getAllEnrichments,
80
+ getAllObservableTypes: () => getAllObservableTypes,
81
+ getAllObservables: () => getAllObservables,
82
+ getAllRelationshipTypes: () => getAllRelationshipTypes,
83
+ getAllTags: () => getAllTags,
84
+ getAllThreatIntelSources: () => getAllThreatIntelSources,
85
+ getAllThreatIntels: () => getAllThreatIntels,
86
+ getCheck: () => getCheck,
87
+ getCheckByName: () => getCheckByName,
88
+ getColorForLevel: () => getColorForLevel,
89
+ getColorForScore: () => getColorForScore,
90
+ getCounts: () => getCounts,
91
+ getDataExtraction: () => getDataExtraction,
92
+ getEnrichment: () => getEnrichment,
93
+ getEnrichmentByName: () => getEnrichmentByName,
94
+ getEntityLevel: () => getEntityLevel,
95
+ getLevelFromScore: () => getLevelFromScore,
96
+ getObservable: () => getObservable,
97
+ getObservableByTypeValue: () => getObservableByTypeValue,
98
+ getObservableChildren: () => getObservableChildren,
99
+ getObservableGraph: () => getObservableGraph,
100
+ getObservableParents: () => getObservableParents,
101
+ getReachableObservables: () => getReachableObservables,
102
+ getRelatedObservables: () => getRelatedObservables,
103
+ getRelatedObservablesByDirection: () => getRelatedObservablesByDirection,
104
+ getRelatedObservablesByType: () => getRelatedObservablesByType,
105
+ getRelationshipsForObservable: () => getRelationshipsForObservable,
106
+ getRootObservable: () => getRootObservable,
107
+ getStartedAt: () => getStartedAt,
108
+ getStats: () => getStats,
109
+ getTag: () => getTag,
110
+ getTagAggregatedLevel: () => getTagAggregatedLevel,
111
+ getTagAggregatedScore: () => getTagAggregatedScore,
112
+ getTagAncestors: () => getTagAncestors,
113
+ getTagByName: () => getTagByName,
114
+ getTagChildren: () => getTagChildren,
115
+ getTagDescendants: () => getTagDescendants,
116
+ getThreatIntel: () => getThreatIntel,
117
+ getThreatIntelBySourceObservable: () => getThreatIntelBySourceObservable,
118
+ getWhitelists: () => getWhitelists,
119
+ hasLevel: () => hasLevel,
120
+ isCyvest: () => isCyvest,
121
+ isLevelAtLeast: () => isLevelAtLeast,
122
+ isLevelHigherThan: () => isLevelHigherThan,
123
+ isLevelLowerThan: () => isLevelLowerThan,
124
+ isTagChildOf: () => isTagChildOf,
125
+ isTagDescendantOf: () => isTagDescendantOf,
126
+ isValidLevel: () => isValidLevel,
127
+ maxLevel: () => maxLevel,
128
+ minLevel: () => minLevel,
129
+ normalizeLevel: () => normalizeLevel,
130
+ parseCheckKey: () => parseCheckKey,
131
+ parseCyvest: () => parseCyvest,
132
+ parseKeyType: () => parseKeyType,
133
+ parseObservableKey: () => parseObservableKey,
134
+ parseThreatIntelKey: () => parseThreatIntelKey,
135
+ sortChecksByLevel: () => sortChecksByLevel,
136
+ sortChecksByScore: () => sortChecksByScore,
137
+ sortObservablesByLevel: () => sortObservablesByLevel,
138
+ sortObservablesByScore: () => sortObservablesByScore,
139
+ validateKey: () => validateKey
140
+ });
141
+ module.exports = __toCommonJS(index_exports);
142
+
1
143
  // src/helpers.ts
2
- import Ajv2020 from "ajv/dist/2020";
3
- import addFormats from "ajv-formats";
144
+ var import__ = __toESM(require("ajv/dist/2020"), 1);
145
+ var import_ajv_formats = __toESM(require("ajv-formats"), 1);
4
146
 
5
147
  // ../../../schema/cyvest.schema.json
6
148
  var cyvest_schema_default = {
@@ -99,12 +241,8 @@ var cyvest_schema_default = {
99
241
  Check: {
100
242
  description: "Represents a verification step in the investigation.\n\nA check validates a specific aspect of the data under investigation\nand contributes to the overall investigation score.",
101
243
  properties: {
102
- check_id: {
103
- title: "Check Id",
104
- type: "string"
105
- },
106
- scope: {
107
- title: "Scope",
244
+ check_name: {
245
+ title: "Check Name",
108
246
  type: "string"
109
247
  },
110
248
  description: {
@@ -149,8 +287,7 @@ var cyvest_schema_default = {
149
287
  }
150
288
  },
151
289
  required: [
152
- "check_id",
153
- "scope",
290
+ "check_name",
154
291
  "description",
155
292
  "comment",
156
293
  "extra",
@@ -164,59 +301,6 @@ var cyvest_schema_default = {
164
301
  title: "Check",
165
302
  type: "object"
166
303
  },
167
- Container: {
168
- additionalProperties: false,
169
- description: "Groups checks and sub-containers for hierarchical organization.\n\nContainers allow structuring the investigation into logical sections\nwith aggregated scores and levels.",
170
- properties: {
171
- path: {
172
- title: "Path",
173
- type: "string"
174
- },
175
- description: {
176
- default: "",
177
- title: "Description",
178
- type: "string"
179
- },
180
- checks: {
181
- items: {
182
- type: "string"
183
- },
184
- title: "Checks",
185
- type: "array"
186
- },
187
- sub_containers: {
188
- additionalProperties: {
189
- $ref: "#/$defs/Container"
190
- },
191
- title: "Sub Containers",
192
- type: "object"
193
- },
194
- key: {
195
- title: "Key",
196
- type: "string"
197
- },
198
- aggregated_score: {
199
- readOnly: true,
200
- title: "Aggregated Score",
201
- type: "number"
202
- },
203
- aggregated_level: {
204
- $ref: "#/$defs/Level",
205
- description: "Calculate the aggregated level from the aggregated score.\n\nReturns:\n Level based on aggregated score",
206
- readOnly: true
207
- }
208
- },
209
- required: [
210
- "path",
211
- "checks",
212
- "sub_containers",
213
- "key",
214
- "aggregated_score",
215
- "aggregated_level"
216
- ],
217
- title: "Container",
218
- type: "object"
219
- },
220
304
  DataExtractionSchema: {
221
305
  additionalProperties: false,
222
306
  description: "Schema for data extraction metadata.",
@@ -541,16 +625,6 @@ var cyvest_schema_default = {
541
625
  title: "Applied Checks",
542
626
  type: "integer"
543
627
  },
544
- checks_by_scope: {
545
- additionalProperties: {
546
- items: {
547
- type: "string"
548
- },
549
- type: "array"
550
- },
551
- title: "Checks By Scope",
552
- type: "object"
553
- },
554
628
  checks_by_level: {
555
629
  additionalProperties: {
556
630
  items: {
@@ -582,9 +656,9 @@ var cyvest_schema_default = {
582
656
  title: "Threat Intel By Level",
583
657
  type: "object"
584
658
  },
585
- total_containers: {
659
+ total_tags: {
586
660
  minimum: 0,
587
- title: "Total Containers",
661
+ title: "Total Tags",
588
662
  type: "integer"
589
663
  }
590
664
  },
@@ -596,11 +670,57 @@ var cyvest_schema_default = {
596
670
  "total_checks",
597
671
  "applied_checks",
598
672
  "total_threat_intel",
599
- "total_containers"
673
+ "total_tags"
600
674
  ],
601
675
  title: "StatisticsSchema",
602
676
  type: "object"
603
677
  },
678
+ Tag: {
679
+ additionalProperties: false,
680
+ description: 'Groups checks for categorical organization.\n\nTags allow structuring the investigation into logical sections\nwith aggregated scores and levels. Hierarchy is automatic based on\nthe ":" delimiter in tag names (e.g., "header:auth:dkim").',
681
+ properties: {
682
+ name: {
683
+ title: "Name",
684
+ type: "string"
685
+ },
686
+ description: {
687
+ default: "",
688
+ title: "Description",
689
+ type: "string"
690
+ },
691
+ checks: {
692
+ items: {
693
+ type: "string"
694
+ },
695
+ title: "Checks",
696
+ type: "array"
697
+ },
698
+ key: {
699
+ title: "Key",
700
+ type: "string"
701
+ },
702
+ direct_score: {
703
+ description: "Calculate the score from direct checks only (no hierarchy).\n\nFor hierarchical aggregation (including descendant tags), use\nInvestigation.get_tag_aggregated_score() or TagProxy.get_aggregated_score().\n\nReturns:\n Total score from direct checks",
704
+ readOnly: true,
705
+ title: "Direct Score",
706
+ type: "number"
707
+ },
708
+ direct_level: {
709
+ $ref: "#/$defs/Level",
710
+ description: "Calculate the level from direct checks only (no hierarchy).\n\nFor hierarchical aggregation (including descendant tags), use\nInvestigation.get_tag_aggregated_level() or TagProxy.get_aggregated_level().\n\nReturns:\n Level based on direct score",
711
+ readOnly: true
712
+ }
713
+ },
714
+ required: [
715
+ "name",
716
+ "checks",
717
+ "key",
718
+ "direct_score",
719
+ "direct_level"
720
+ ],
721
+ title: "Tag",
722
+ type: "object"
723
+ },
604
724
  Taxonomy: {
605
725
  additionalProperties: false,
606
726
  description: "Represents a structured taxonomy entry for threat intelligence.",
@@ -754,12 +874,9 @@ var cyvest_schema_default = {
754
874
  },
755
875
  checks: {
756
876
  additionalProperties: {
757
- items: {
758
- $ref: "#/$defs/Check"
759
- },
760
- type: "array"
877
+ $ref: "#/$defs/Check"
761
878
  },
762
- description: "Checks organized by scope.",
879
+ description: "Checks keyed by their unique key.",
763
880
  title: "Checks",
764
881
  type: "object"
765
882
  },
@@ -779,12 +896,12 @@ var cyvest_schema_default = {
779
896
  title: "Enrichments",
780
897
  type: "object"
781
898
  },
782
- containers: {
899
+ tags: {
783
900
  additionalProperties: {
784
- $ref: "#/$defs/Container"
901
+ $ref: "#/$defs/Tag"
785
902
  },
786
- description: "Containers keyed by their unique key.",
787
- title: "Containers",
903
+ description: "Tags keyed by their unique key.",
904
+ title: "Tags",
788
905
  type: "object"
789
906
  },
790
907
  stats: {
@@ -812,7 +929,7 @@ var cyvest_schema_default = {
812
929
  "checks",
813
930
  "threat_intels",
814
931
  "enrichments",
815
- "containers",
932
+ "tags",
816
933
  "stats",
817
934
  "data_extraction",
818
935
  "score_display"
@@ -822,8 +939,8 @@ var cyvest_schema_default = {
822
939
  };
823
940
 
824
941
  // src/helpers.ts
825
- var ajv = new Ajv2020({ allErrors: true });
826
- addFormats(ajv);
942
+ var ajv = new import__.default({ allErrors: true });
943
+ (0, import_ajv_formats.default)(ajv);
827
944
  var validateFn = null;
828
945
  function getValidator() {
829
946
  if (!validateFn) {
@@ -862,10 +979,9 @@ function generateObservableKey(obsType, value) {
862
979
  const normalizedValue = normalizeValue(value);
863
980
  return `obs:${normalizedType}:${normalizedValue}`;
864
981
  }
865
- function generateCheckKey(checkId, scope) {
866
- const normalizedId = normalizeValue(checkId);
867
- const normalizedScope = normalizeValue(scope);
868
- return `chk:${normalizedId}:${normalizedScope}`;
982
+ function generateCheckKey(checkName) {
983
+ const normalizedName = normalizeValue(checkName);
984
+ return `chk:${normalizedName}`;
869
985
  }
870
986
  function generateThreatIntelKey(source, observableKey) {
871
987
  const normalizedSource = normalizeValue(source);
@@ -879,15 +995,32 @@ function generateEnrichmentKey(name, context) {
879
995
  }
880
996
  return `enr:${normalizedName}`;
881
997
  }
882
- function generateContainerKey(path) {
883
- let normalizedPath = path.replace(/\\/g, "/").replace(/^\/+|\/+$/g, "");
884
- normalizedPath = normalizeValue(normalizedPath);
885
- return `ctr:${normalizedPath}`;
998
+ function generateTagKey(name) {
999
+ const normalizedName = normalizeValue(name);
1000
+ return `tag:${normalizedName}`;
1001
+ }
1002
+ function getTagAncestors(name) {
1003
+ const parts = name.split(":");
1004
+ const ancestors = [];
1005
+ for (let i = 0; i < parts.length - 1; i++) {
1006
+ ancestors.push(parts.slice(0, i + 1).join(":"));
1007
+ }
1008
+ return ancestors;
1009
+ }
1010
+ function isTagChildOf(childName, parentName) {
1011
+ if (!childName.startsWith(parentName + ":")) {
1012
+ return false;
1013
+ }
1014
+ const remaining = childName.slice(parentName.length + 1);
1015
+ return !remaining.includes(":");
1016
+ }
1017
+ function isTagDescendantOf(descendantName, ancestorName) {
1018
+ return descendantName.startsWith(ancestorName + ":");
886
1019
  }
887
1020
  function parseKeyType(key) {
888
1021
  if (key.includes(":")) {
889
1022
  const prefix = key.split(":", 1)[0];
890
- if (["obs", "chk", "ti", "enr", "ctr"].includes(prefix)) {
1023
+ if (["obs", "chk", "ti", "enr", "tag"].includes(prefix)) {
891
1024
  return prefix;
892
1025
  }
893
1026
  }
@@ -925,10 +1058,9 @@ function parseCheckKey(key) {
925
1058
  return null;
926
1059
  }
927
1060
  const parts = key.split(":");
928
- if (parts.length >= 3) {
1061
+ if (parts.length >= 2) {
929
1062
  return {
930
- checkId: parts[1],
931
- scope: parts.slice(2).join(":")
1063
+ checkName: parts.slice(1).join(":")
932
1064
  };
933
1065
  }
934
1066
  return null;
@@ -1045,10 +1177,10 @@ function hasLevel(obj) {
1045
1177
  return typeof obj === "object" && obj !== null && "level" in obj && typeof obj.level === "string" && isValidLevel(obj.level);
1046
1178
  }
1047
1179
  function getEntityLevel(entity) {
1048
- if ("aggregated_level" in entity) {
1049
- const aggregatedLevel = entity.aggregated_level;
1050
- if (typeof aggregatedLevel === "string" && isValidLevel(aggregatedLevel)) {
1051
- return aggregatedLevel;
1180
+ if ("direct_level" in entity) {
1181
+ const directLevel = entity.direct_level;
1182
+ if (typeof directLevel === "string" && isValidLevel(directLevel)) {
1183
+ return directLevel;
1052
1184
  }
1053
1185
  }
1054
1186
  if ("level" in entity && isValidLevel(entity.level)) {
@@ -1071,40 +1203,24 @@ function getObservableByTypeValue(inv, type, value) {
1071
1203
  }
1072
1204
  return void 0;
1073
1205
  }
1074
- function getCheck(inv, key) {
1075
- for (const checks of Object.values(inv.checks)) {
1076
- for (const check of checks) {
1077
- if (check.key === key) {
1078
- return check;
1079
- }
1080
- }
1206
+ function getRootObservable(inv) {
1207
+ const rootType = inv.data_extraction.root_type;
1208
+ if (!rootType) {
1209
+ return void 0;
1081
1210
  }
1082
- return void 0;
1211
+ const rootKey = generateObservableKey(rootType, "root");
1212
+ return inv.observables[rootKey];
1083
1213
  }
1084
- function getCheckByIdScope(inv, checkId, scope) {
1085
- const normalizedId = checkId.trim().toLowerCase();
1086
- const normalizedScope = scope.trim().toLowerCase();
1087
- const scopeChecks = inv.checks[normalizedScope] || inv.checks[scope];
1088
- if (scopeChecks) {
1089
- return scopeChecks.find(
1090
- (c) => c.check_id.toLowerCase() === normalizedId
1091
- );
1092
- }
1093
- for (const checks of Object.values(inv.checks)) {
1094
- for (const check of checks) {
1095
- if (check.check_id.toLowerCase() === normalizedId && check.scope.toLowerCase() === normalizedScope) {
1096
- return check;
1097
- }
1098
- }
1099
- }
1100
- return void 0;
1214
+ function getCheck(inv, key) {
1215
+ return inv.checks[key];
1216
+ }
1217
+ function getCheckByName(inv, checkName) {
1218
+ const normalizedName = checkName.trim().toLowerCase();
1219
+ const key = `chk:${normalizedName}`;
1220
+ return inv.checks[key];
1101
1221
  }
1102
1222
  function getAllChecks(inv) {
1103
- const result = [];
1104
- for (const checks of Object.values(inv.checks)) {
1105
- result.push(...checks);
1106
- }
1107
- return result;
1223
+ return Object.values(inv.checks);
1108
1224
  }
1109
1225
  function getThreatIntel(inv, key) {
1110
1226
  return inv.threat_intels[key];
@@ -1136,46 +1252,16 @@ function getEnrichmentByName(inv, name) {
1136
1252
  function getAllEnrichments(inv) {
1137
1253
  return Object.values(inv.enrichments);
1138
1254
  }
1139
- function getContainer(inv, key) {
1140
- if (inv.containers[key]) {
1141
- return inv.containers[key];
1142
- }
1143
- function searchSubContainers(containers) {
1144
- for (const container of Object.values(containers)) {
1145
- if (container.key === key) {
1146
- return container;
1147
- }
1148
- const found = searchSubContainers(container.sub_containers);
1149
- if (found) return found;
1150
- }
1151
- return void 0;
1152
- }
1153
- return searchSubContainers(inv.containers);
1154
- }
1155
- function getContainerByPath(inv, path) {
1156
- const normalizedPath = path.replace(/\\/g, "/").replace(/^\/+|\/+$/g, "").toLowerCase();
1157
- function searchContainers(containers) {
1158
- for (const container of Object.values(containers)) {
1159
- if (container.path.toLowerCase() === normalizedPath) {
1160
- return container;
1161
- }
1162
- const found = searchContainers(container.sub_containers);
1163
- if (found) return found;
1164
- }
1165
- return void 0;
1166
- }
1167
- return searchContainers(inv.containers);
1255
+ function getTag(inv, key) {
1256
+ return inv.tags[key];
1168
1257
  }
1169
- function getAllContainers(inv) {
1170
- const result = [];
1171
- function collectContainers(containers) {
1172
- for (const container of Object.values(containers)) {
1173
- result.push(container);
1174
- collectContainers(container.sub_containers);
1175
- }
1176
- }
1177
- collectContainers(inv.containers);
1178
- return result;
1258
+ function getTagByName(inv, name) {
1259
+ const normalizedName = name.trim().toLowerCase();
1260
+ const key = `tag:${normalizedName}`;
1261
+ return inv.tags[key];
1262
+ }
1263
+ function getAllTags(inv) {
1264
+ return Object.values(inv.tags);
1179
1265
  }
1180
1266
  function getAllObservables(inv) {
1181
1267
  return Object.values(inv.observables);
@@ -1195,7 +1281,7 @@ function getCounts(inv) {
1195
1281
  checks: getAllChecks(inv).length,
1196
1282
  threatIntels: Object.keys(inv.threat_intels).length,
1197
1283
  enrichments: Object.keys(inv.enrichments).length,
1198
- containers: getAllContainers(inv).length,
1284
+ tags: getAllTags(inv).length,
1199
1285
  whitelists: inv.whitelists.length
1200
1286
  };
1201
1287
  }
@@ -1205,6 +1291,28 @@ function getStartedAt(inv) {
1205
1291
  );
1206
1292
  return event?.timestamp;
1207
1293
  }
1294
+ function getTagChildren(inv, tagName) {
1295
+ return Object.values(inv.tags).filter((tag) => isTagChildOf(tag.name, tagName));
1296
+ }
1297
+ function getTagDescendants(inv, tagName) {
1298
+ const prefix = tagName + ":";
1299
+ return Object.values(inv.tags).filter((tag) => tag.name.startsWith(prefix));
1300
+ }
1301
+ function getTagAggregatedScore(inv, tagName) {
1302
+ const tag = getTagByName(inv, tagName);
1303
+ if (!tag) {
1304
+ return 0;
1305
+ }
1306
+ let total = tag.direct_score;
1307
+ const children = getTagChildren(inv, tagName);
1308
+ for (const child of children) {
1309
+ total += getTagAggregatedScore(inv, child.name);
1310
+ }
1311
+ return total;
1312
+ }
1313
+ function getTagAggregatedLevel(inv, tagName) {
1314
+ return getLevelFromScore(getTagAggregatedScore(inv, tagName));
1315
+ }
1208
1316
 
1209
1317
  // src/finders.ts
1210
1318
  function findObservablesByType(inv, type) {
@@ -1252,51 +1360,19 @@ function findObservablesWithThreatIntel(inv) {
1252
1360
  (obs) => obs.threat_intels.length > 0
1253
1361
  );
1254
1362
  }
1255
- function findChecksByScope(inv, scope) {
1256
- const normalizedScope = scope.trim().toLowerCase();
1257
- if (inv.checks[scope]) {
1258
- return inv.checks[scope];
1259
- }
1260
- for (const [key, checks] of Object.entries(inv.checks)) {
1261
- if (key.toLowerCase() === normalizedScope) {
1262
- return checks;
1263
- }
1264
- }
1265
- return [];
1266
- }
1267
1363
  function findChecksByLevel(inv, level) {
1268
- const result = [];
1269
- for (const checks of Object.values(inv.checks)) {
1270
- for (const check of checks) {
1271
- if (check.level === level) {
1272
- result.push(check);
1273
- }
1274
- }
1275
- }
1276
- return result;
1364
+ return Object.values(inv.checks).filter((check) => check.level === level);
1277
1365
  }
1278
1366
  function findChecksAtLeast(inv, minLevel2) {
1279
- const result = [];
1280
- for (const checks of Object.values(inv.checks)) {
1281
- for (const check of checks) {
1282
- if (isLevelAtLeast(check.level, minLevel2)) {
1283
- result.push(check);
1284
- }
1285
- }
1286
- }
1287
- return result;
1367
+ return Object.values(inv.checks).filter(
1368
+ (check) => isLevelAtLeast(check.level, minLevel2)
1369
+ );
1288
1370
  }
1289
- function findChecksByCheckId(inv, checkId) {
1290
- const normalizedId = checkId.trim().toLowerCase();
1291
- const result = [];
1292
- for (const checks of Object.values(inv.checks)) {
1293
- for (const check of checks) {
1294
- if (check.check_id.toLowerCase() === normalizedId) {
1295
- result.push(check);
1296
- }
1297
- }
1298
- }
1299
- return result;
1371
+ function findCheckByName(inv, checkName) {
1372
+ const normalizedName = checkName.trim().toLowerCase();
1373
+ return Object.values(inv.checks).find(
1374
+ (check) => check.check_name.toLowerCase() === normalizedName
1375
+ );
1300
1376
  }
1301
1377
  function findThreatIntelBySource(inv, source) {
1302
1378
  const normalizedSource = source.trim().toLowerCase();
@@ -1312,52 +1388,31 @@ function findThreatIntelAtLeast(inv, minLevel2) {
1312
1388
  (ti) => isLevelAtLeast(ti.level, minLevel2)
1313
1389
  );
1314
1390
  }
1315
- function findContainersByLevel(inv, level) {
1316
- const result = [];
1317
- function searchContainers(containers) {
1318
- for (const container of Object.values(containers)) {
1319
- if (container.aggregated_level === level) {
1320
- result.push(container);
1321
- }
1322
- searchContainers(container.sub_containers);
1323
- }
1324
- }
1325
- searchContainers(inv.containers);
1326
- return result;
1391
+ function findTagsByLevel(inv, level) {
1392
+ return Object.values(inv.tags).filter((tag) => tag.direct_level === level);
1327
1393
  }
1328
- function findContainersAtLeast(inv, minLevel2) {
1329
- const result = [];
1330
- function searchContainers(containers) {
1331
- for (const container of Object.values(containers)) {
1332
- if (isLevelAtLeast(container.aggregated_level, minLevel2)) {
1333
- result.push(container);
1334
- }
1335
- searchContainers(container.sub_containers);
1336
- }
1337
- }
1338
- searchContainers(inv.containers);
1339
- return result;
1394
+ function findTagsAtLeast(inv, minLevel2) {
1395
+ return Object.values(inv.tags).filter(
1396
+ (tag) => isLevelAtLeast(tag.direct_level, minLevel2)
1397
+ );
1398
+ }
1399
+ function findTagsByNamePattern(inv, pattern) {
1400
+ return Object.values(inv.tags).filter((tag) => pattern.test(tag.name));
1340
1401
  }
1341
- function getChecksForObservable(inv, observableKey) {
1402
+ function findChecksForObservable(inv, observableKey) {
1342
1403
  const result = [];
1343
1404
  const seen = /* @__PURE__ */ new Set();
1344
- const checkLookup = /* @__PURE__ */ new Map();
1345
- for (const checks of Object.values(inv.checks)) {
1346
- for (const check of checks) {
1347
- checkLookup.set(check.key, check);
1348
- }
1349
- }
1350
1405
  const observable = inv.observables[observableKey];
1351
1406
  if (observable) {
1352
1407
  for (const checkKey of observable.check_links) {
1353
- const check = checkLookup.get(checkKey);
1408
+ const check = inv.checks[checkKey];
1354
1409
  if (check && !seen.has(check.key)) {
1355
1410
  result.push(check);
1356
1411
  seen.add(check.key);
1357
1412
  }
1358
1413
  }
1359
1414
  }
1360
- for (const check of checkLookup.values()) {
1415
+ for (const check of Object.values(inv.checks)) {
1361
1416
  if (seen.has(check.key)) {
1362
1417
  continue;
1363
1418
  }
@@ -1368,7 +1423,7 @@ function getChecksForObservable(inv, observableKey) {
1368
1423
  }
1369
1424
  return result;
1370
1425
  }
1371
- function getThreatIntelsForObservable(inv, observableKey) {
1426
+ function findThreatIntelsForObservable(inv, observableKey) {
1372
1427
  const observable = inv.observables[observableKey];
1373
1428
  if (observable) {
1374
1429
  return observable.threat_intels.map((tiKey) => inv.threat_intels[tiKey]).filter((ti) => ti !== void 0);
@@ -1377,51 +1432,41 @@ function getThreatIntelsForObservable(inv, observableKey) {
1377
1432
  (ti) => ti.observable_key === observableKey
1378
1433
  );
1379
1434
  }
1380
- function getObservablesForCheck(inv, checkKey) {
1381
- for (const checks of Object.values(inv.checks)) {
1382
- for (const check of checks) {
1383
- if (check.key === checkKey) {
1384
- const keys = /* @__PURE__ */ new Set();
1385
- for (const link of check.observable_links) {
1386
- keys.add(link.observable_key);
1387
- }
1388
- return Array.from(keys).map((obsKey) => inv.observables[obsKey]).filter((obs) => obs !== void 0);
1389
- }
1435
+ function findObservablesForCheck(inv, checkKey) {
1436
+ const check = inv.checks[checkKey];
1437
+ if (check) {
1438
+ const keys = /* @__PURE__ */ new Set();
1439
+ for (const link of check.observable_links) {
1440
+ keys.add(link.observable_key);
1390
1441
  }
1442
+ return Array.from(keys).map((obsKey) => inv.observables[obsKey]).filter((obs) => obs !== void 0);
1391
1443
  }
1392
1444
  return [];
1393
1445
  }
1394
- function getChecksForContainer(inv, containerKey, recursive = false) {
1446
+ function findChecksForTag(inv, tagKey, recursive = false) {
1395
1447
  const result = [];
1396
- function findContainer(containers) {
1397
- for (const container2 of Object.values(containers)) {
1398
- if (container2.key === containerKey) {
1399
- return container2;
1400
- }
1401
- const found = findContainer(container2.sub_containers);
1402
- if (found) return found;
1448
+ const tag = inv.tags[tagKey];
1449
+ if (!tag) {
1450
+ return result;
1451
+ }
1452
+ for (const checkKey of tag.checks) {
1453
+ const check = inv.checks[checkKey];
1454
+ if (check) {
1455
+ result.push(check);
1403
1456
  }
1404
- return void 0;
1405
1457
  }
1406
- function collectChecks(container2) {
1407
- for (const checkKey of container2.checks) {
1408
- for (const checks of Object.values(inv.checks)) {
1409
- for (const check of checks) {
1410
- if (check.key === checkKey) {
1458
+ if (recursive) {
1459
+ const prefix = tag.name + ":";
1460
+ for (const otherTag of Object.values(inv.tags)) {
1461
+ if (otherTag.name.startsWith(prefix)) {
1462
+ for (const checkKey of otherTag.checks) {
1463
+ const check = inv.checks[checkKey];
1464
+ if (check) {
1411
1465
  result.push(check);
1412
1466
  }
1413
1467
  }
1414
1468
  }
1415
1469
  }
1416
- if (recursive) {
1417
- for (const subContainer of Object.values(container2.sub_containers)) {
1418
- collectChecks(subContainer);
1419
- }
1420
- }
1421
- }
1422
- const container = findContainer(inv.containers);
1423
- if (container) {
1424
- collectChecks(container);
1425
1470
  }
1426
1471
  return result;
1427
1472
  }
@@ -1441,29 +1486,25 @@ function sortChecksByLevel(checks) {
1441
1486
  (a, b) => LEVEL_VALUES[b.level] - LEVEL_VALUES[a.level]
1442
1487
  );
1443
1488
  }
1444
- function getHighestScoringObservables(inv, n = 10) {
1489
+ function findHighestScoringObservables(inv, n = 10) {
1445
1490
  return sortObservablesByScore(Object.values(inv.observables)).slice(0, n);
1446
1491
  }
1447
- function getHighestScoringChecks(inv, n = 10) {
1448
- const allChecks = [];
1449
- for (const checks of Object.values(inv.checks)) {
1450
- allChecks.push(...checks);
1451
- }
1452
- return sortChecksByScore(allChecks).slice(0, n);
1492
+ function findHighestScoringChecks(inv, n = 10) {
1493
+ return sortChecksByScore(Object.values(inv.checks)).slice(0, n);
1453
1494
  }
1454
- function getMaliciousObservables(inv) {
1495
+ function findMaliciousObservables(inv) {
1455
1496
  return findObservablesByLevel(inv, "MALICIOUS");
1456
1497
  }
1457
- function getSuspiciousObservables(inv) {
1498
+ function findSuspiciousObservables(inv) {
1458
1499
  return findObservablesByLevel(inv, "SUSPICIOUS");
1459
1500
  }
1460
- function getMaliciousChecks(inv) {
1501
+ function findMaliciousChecks(inv) {
1461
1502
  return findChecksByLevel(inv, "MALICIOUS");
1462
1503
  }
1463
- function getSuspiciousChecks(inv) {
1504
+ function findSuspiciousChecks(inv) {
1464
1505
  return findChecksByLevel(inv, "SUSPICIOUS");
1465
1506
  }
1466
- function getAllScopes(inv) {
1507
+ function getAllCheckKeys(inv) {
1467
1508
  return Object.keys(inv.checks);
1468
1509
  }
1469
1510
  function getAllObservableTypes(inv) {
@@ -1600,7 +1641,7 @@ function getObservableGraph(inv) {
1600
1641
  }
1601
1642
  return { nodes, edges };
1602
1643
  }
1603
- function findRootObservables(inv) {
1644
+ function findSourceObservables(inv) {
1604
1645
  const targetKeys = /* @__PURE__ */ new Set();
1605
1646
  for (const obs of Object.values(inv.observables)) {
1606
1647
  for (const rel of obs.relationships) {
@@ -1741,92 +1782,101 @@ function getRelationshipsForObservable(inv, observableKey) {
1741
1782
  ]
1742
1783
  };
1743
1784
  }
1744
- export {
1785
+ // Annotate the CommonJS export names for ESM import in node:
1786
+ 0 && (module.exports = {
1745
1787
  LEVEL_COLORS,
1746
1788
  LEVEL_ORDER,
1747
1789
  LEVEL_VALUES,
1748
1790
  areConnected,
1749
1791
  compareLevels,
1750
1792
  countRelationshipsByType,
1793
+ findCheckByName,
1751
1794
  findChecksAtLeast,
1752
- findChecksByCheckId,
1753
1795
  findChecksByLevel,
1754
- findChecksByScope,
1755
- findContainersAtLeast,
1756
- findContainersByLevel,
1796
+ findChecksForObservable,
1797
+ findChecksForTag,
1757
1798
  findExternalObservables,
1799
+ findHighestScoringChecks,
1800
+ findHighestScoringObservables,
1758
1801
  findInternalObservables,
1759
1802
  findLeafObservables,
1803
+ findMaliciousChecks,
1804
+ findMaliciousObservables,
1760
1805
  findObservablesAtLeast,
1761
1806
  findObservablesByLevel,
1762
1807
  findObservablesByType,
1763
1808
  findObservablesByValue,
1764
1809
  findObservablesContaining,
1810
+ findObservablesForCheck,
1765
1811
  findObservablesMatching,
1766
1812
  findObservablesWithThreatIntel,
1767
1813
  findOrphanObservables,
1768
1814
  findPath,
1769
- findRootObservables,
1815
+ findSourceObservables,
1816
+ findSuspiciousChecks,
1817
+ findSuspiciousObservables,
1818
+ findTagsAtLeast,
1819
+ findTagsByLevel,
1820
+ findTagsByNamePattern,
1770
1821
  findThreatIntelAtLeast,
1771
1822
  findThreatIntelByLevel,
1772
1823
  findThreatIntelBySource,
1824
+ findThreatIntelsForObservable,
1773
1825
  findWhitelistedObservables,
1774
1826
  generateCheckKey,
1775
- generateContainerKey,
1776
1827
  generateEnrichmentKey,
1777
1828
  generateObservableKey,
1829
+ generateTagKey,
1778
1830
  generateThreatIntelKey,
1831
+ getAllCheckKeys,
1779
1832
  getAllChecks,
1780
- getAllContainers,
1781
1833
  getAllEnrichments,
1782
1834
  getAllObservableTypes,
1783
1835
  getAllObservables,
1784
1836
  getAllRelationshipTypes,
1785
- getAllScopes,
1837
+ getAllTags,
1786
1838
  getAllThreatIntelSources,
1787
1839
  getAllThreatIntels,
1788
1840
  getCheck,
1789
- getCheckByIdScope,
1790
- getChecksForContainer,
1791
- getChecksForObservable,
1841
+ getCheckByName,
1792
1842
  getColorForLevel,
1793
1843
  getColorForScore,
1794
- getContainer,
1795
- getContainerByPath,
1796
1844
  getCounts,
1797
1845
  getDataExtraction,
1798
1846
  getEnrichment,
1799
1847
  getEnrichmentByName,
1800
1848
  getEntityLevel,
1801
- getHighestScoringChecks,
1802
- getHighestScoringObservables,
1803
1849
  getLevelFromScore,
1804
- getMaliciousChecks,
1805
- getMaliciousObservables,
1806
1850
  getObservable,
1807
1851
  getObservableByTypeValue,
1808
1852
  getObservableChildren,
1809
1853
  getObservableGraph,
1810
1854
  getObservableParents,
1811
- getObservablesForCheck,
1812
1855
  getReachableObservables,
1813
1856
  getRelatedObservables,
1814
1857
  getRelatedObservablesByDirection,
1815
1858
  getRelatedObservablesByType,
1816
1859
  getRelationshipsForObservable,
1860
+ getRootObservable,
1817
1861
  getStartedAt,
1818
1862
  getStats,
1819
- getSuspiciousChecks,
1820
- getSuspiciousObservables,
1863
+ getTag,
1864
+ getTagAggregatedLevel,
1865
+ getTagAggregatedScore,
1866
+ getTagAncestors,
1867
+ getTagByName,
1868
+ getTagChildren,
1869
+ getTagDescendants,
1821
1870
  getThreatIntel,
1822
1871
  getThreatIntelBySourceObservable,
1823
- getThreatIntelsForObservable,
1824
1872
  getWhitelists,
1825
1873
  hasLevel,
1826
1874
  isCyvest,
1827
1875
  isLevelAtLeast,
1828
1876
  isLevelHigherThan,
1829
1877
  isLevelLowerThan,
1878
+ isTagChildOf,
1879
+ isTagDescendantOf,
1830
1880
  isValidLevel,
1831
1881
  maxLevel,
1832
1882
  minLevel,
@@ -1841,4 +1891,4 @@ export {
1841
1891
  sortObservablesByLevel,
1842
1892
  sortObservablesByScore,
1843
1893
  validateKey
1844
- };
1894
+ });