@cyvest/cyvest-js 4.4.1 → 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.
package/dist/index.js CHANGED
@@ -99,12 +99,8 @@ var cyvest_schema_default = {
99
99
  Check: {
100
100
  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
101
  properties: {
102
- check_id: {
103
- title: "Check Id",
104
- type: "string"
105
- },
106
- scope: {
107
- title: "Scope",
102
+ check_name: {
103
+ title: "Check Name",
108
104
  type: "string"
109
105
  },
110
106
  description: {
@@ -149,8 +145,7 @@ var cyvest_schema_default = {
149
145
  }
150
146
  },
151
147
  required: [
152
- "check_id",
153
- "scope",
148
+ "check_name",
154
149
  "description",
155
150
  "comment",
156
151
  "extra",
@@ -164,59 +159,6 @@ var cyvest_schema_default = {
164
159
  title: "Check",
165
160
  type: "object"
166
161
  },
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
162
  DataExtractionSchema: {
221
163
  additionalProperties: false,
222
164
  description: "Schema for data extraction metadata.",
@@ -541,16 +483,6 @@ var cyvest_schema_default = {
541
483
  title: "Applied Checks",
542
484
  type: "integer"
543
485
  },
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
486
  checks_by_level: {
555
487
  additionalProperties: {
556
488
  items: {
@@ -582,9 +514,9 @@ var cyvest_schema_default = {
582
514
  title: "Threat Intel By Level",
583
515
  type: "object"
584
516
  },
585
- total_containers: {
517
+ total_tags: {
586
518
  minimum: 0,
587
- title: "Total Containers",
519
+ title: "Total Tags",
588
520
  type: "integer"
589
521
  }
590
522
  },
@@ -596,11 +528,57 @@ var cyvest_schema_default = {
596
528
  "total_checks",
597
529
  "applied_checks",
598
530
  "total_threat_intel",
599
- "total_containers"
531
+ "total_tags"
600
532
  ],
601
533
  title: "StatisticsSchema",
602
534
  type: "object"
603
535
  },
536
+ Tag: {
537
+ additionalProperties: false,
538
+ 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").',
539
+ properties: {
540
+ name: {
541
+ title: "Name",
542
+ type: "string"
543
+ },
544
+ description: {
545
+ default: "",
546
+ title: "Description",
547
+ type: "string"
548
+ },
549
+ checks: {
550
+ items: {
551
+ type: "string"
552
+ },
553
+ title: "Checks",
554
+ type: "array"
555
+ },
556
+ key: {
557
+ title: "Key",
558
+ type: "string"
559
+ },
560
+ direct_score: {
561
+ 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",
562
+ readOnly: true,
563
+ title: "Direct Score",
564
+ type: "number"
565
+ },
566
+ direct_level: {
567
+ $ref: "#/$defs/Level",
568
+ 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",
569
+ readOnly: true
570
+ }
571
+ },
572
+ required: [
573
+ "name",
574
+ "checks",
575
+ "key",
576
+ "direct_score",
577
+ "direct_level"
578
+ ],
579
+ title: "Tag",
580
+ type: "object"
581
+ },
604
582
  Taxonomy: {
605
583
  additionalProperties: false,
606
584
  description: "Represents a structured taxonomy entry for threat intelligence.",
@@ -754,12 +732,9 @@ var cyvest_schema_default = {
754
732
  },
755
733
  checks: {
756
734
  additionalProperties: {
757
- items: {
758
- $ref: "#/$defs/Check"
759
- },
760
- type: "array"
735
+ $ref: "#/$defs/Check"
761
736
  },
762
- description: "Checks organized by scope.",
737
+ description: "Checks keyed by their unique key.",
763
738
  title: "Checks",
764
739
  type: "object"
765
740
  },
@@ -779,12 +754,12 @@ var cyvest_schema_default = {
779
754
  title: "Enrichments",
780
755
  type: "object"
781
756
  },
782
- containers: {
757
+ tags: {
783
758
  additionalProperties: {
784
- $ref: "#/$defs/Container"
759
+ $ref: "#/$defs/Tag"
785
760
  },
786
- description: "Containers keyed by their unique key.",
787
- title: "Containers",
761
+ description: "Tags keyed by their unique key.",
762
+ title: "Tags",
788
763
  type: "object"
789
764
  },
790
765
  stats: {
@@ -812,7 +787,7 @@ var cyvest_schema_default = {
812
787
  "checks",
813
788
  "threat_intels",
814
789
  "enrichments",
815
- "containers",
790
+ "tags",
816
791
  "stats",
817
792
  "data_extraction",
818
793
  "score_display"
@@ -862,10 +837,9 @@ function generateObservableKey(obsType, value) {
862
837
  const normalizedValue = normalizeValue(value);
863
838
  return `obs:${normalizedType}:${normalizedValue}`;
864
839
  }
865
- function generateCheckKey(checkId, scope) {
866
- const normalizedId = normalizeValue(checkId);
867
- const normalizedScope = normalizeValue(scope);
868
- return `chk:${normalizedId}:${normalizedScope}`;
840
+ function generateCheckKey(checkName) {
841
+ const normalizedName = normalizeValue(checkName);
842
+ return `chk:${normalizedName}`;
869
843
  }
870
844
  function generateThreatIntelKey(source, observableKey) {
871
845
  const normalizedSource = normalizeValue(source);
@@ -879,15 +853,32 @@ function generateEnrichmentKey(name, context) {
879
853
  }
880
854
  return `enr:${normalizedName}`;
881
855
  }
882
- function generateContainerKey(path) {
883
- let normalizedPath = path.replace(/\\/g, "/").replace(/^\/+|\/+$/g, "");
884
- normalizedPath = normalizeValue(normalizedPath);
885
- return `ctr:${normalizedPath}`;
856
+ function generateTagKey(name) {
857
+ const normalizedName = normalizeValue(name);
858
+ return `tag:${normalizedName}`;
859
+ }
860
+ function getTagAncestors(name) {
861
+ const parts = name.split(":");
862
+ const ancestors = [];
863
+ for (let i = 0; i < parts.length - 1; i++) {
864
+ ancestors.push(parts.slice(0, i + 1).join(":"));
865
+ }
866
+ return ancestors;
867
+ }
868
+ function isTagChildOf(childName, parentName) {
869
+ if (!childName.startsWith(parentName + ":")) {
870
+ return false;
871
+ }
872
+ const remaining = childName.slice(parentName.length + 1);
873
+ return !remaining.includes(":");
874
+ }
875
+ function isTagDescendantOf(descendantName, ancestorName) {
876
+ return descendantName.startsWith(ancestorName + ":");
886
877
  }
887
878
  function parseKeyType(key) {
888
879
  if (key.includes(":")) {
889
880
  const prefix = key.split(":", 1)[0];
890
- if (["obs", "chk", "ti", "enr", "ctr"].includes(prefix)) {
881
+ if (["obs", "chk", "ti", "enr", "tag"].includes(prefix)) {
891
882
  return prefix;
892
883
  }
893
884
  }
@@ -925,10 +916,9 @@ function parseCheckKey(key) {
925
916
  return null;
926
917
  }
927
918
  const parts = key.split(":");
928
- if (parts.length >= 3) {
919
+ if (parts.length >= 2) {
929
920
  return {
930
- checkId: parts[1],
931
- scope: parts.slice(2).join(":")
921
+ checkName: parts.slice(1).join(":")
932
922
  };
933
923
  }
934
924
  return null;
@@ -1045,10 +1035,10 @@ function hasLevel(obj) {
1045
1035
  return typeof obj === "object" && obj !== null && "level" in obj && typeof obj.level === "string" && isValidLevel(obj.level);
1046
1036
  }
1047
1037
  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;
1038
+ if ("direct_level" in entity) {
1039
+ const directLevel = entity.direct_level;
1040
+ if (typeof directLevel === "string" && isValidLevel(directLevel)) {
1041
+ return directLevel;
1052
1042
  }
1053
1043
  }
1054
1044
  if ("level" in entity && isValidLevel(entity.level)) {
@@ -1071,40 +1061,24 @@ function getObservableByTypeValue(inv, type, value) {
1071
1061
  }
1072
1062
  return void 0;
1073
1063
  }
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
- }
1064
+ function getRootObservable(inv) {
1065
+ const rootType = inv.data_extraction.root_type;
1066
+ if (!rootType) {
1067
+ return void 0;
1081
1068
  }
1082
- return void 0;
1069
+ const rootKey = generateObservableKey(rootType, "root");
1070
+ return inv.observables[rootKey];
1083
1071
  }
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;
1072
+ function getCheck(inv, key) {
1073
+ return inv.checks[key];
1074
+ }
1075
+ function getCheckByName(inv, checkName) {
1076
+ const normalizedName = checkName.trim().toLowerCase();
1077
+ const key = `chk:${normalizedName}`;
1078
+ return inv.checks[key];
1101
1079
  }
1102
1080
  function getAllChecks(inv) {
1103
- const result = [];
1104
- for (const checks of Object.values(inv.checks)) {
1105
- result.push(...checks);
1106
- }
1107
- return result;
1081
+ return Object.values(inv.checks);
1108
1082
  }
1109
1083
  function getThreatIntel(inv, key) {
1110
1084
  return inv.threat_intels[key];
@@ -1136,46 +1110,16 @@ function getEnrichmentByName(inv, name) {
1136
1110
  function getAllEnrichments(inv) {
1137
1111
  return Object.values(inv.enrichments);
1138
1112
  }
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);
1113
+ function getTag(inv, key) {
1114
+ return inv.tags[key];
1168
1115
  }
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;
1116
+ function getTagByName(inv, name) {
1117
+ const normalizedName = name.trim().toLowerCase();
1118
+ const key = `tag:${normalizedName}`;
1119
+ return inv.tags[key];
1120
+ }
1121
+ function getAllTags(inv) {
1122
+ return Object.values(inv.tags);
1179
1123
  }
1180
1124
  function getAllObservables(inv) {
1181
1125
  return Object.values(inv.observables);
@@ -1195,7 +1139,7 @@ function getCounts(inv) {
1195
1139
  checks: getAllChecks(inv).length,
1196
1140
  threatIntels: Object.keys(inv.threat_intels).length,
1197
1141
  enrichments: Object.keys(inv.enrichments).length,
1198
- containers: getAllContainers(inv).length,
1142
+ tags: getAllTags(inv).length,
1199
1143
  whitelists: inv.whitelists.length
1200
1144
  };
1201
1145
  }
@@ -1205,6 +1149,28 @@ function getStartedAt(inv) {
1205
1149
  );
1206
1150
  return event?.timestamp;
1207
1151
  }
1152
+ function getTagChildren(inv, tagName) {
1153
+ return Object.values(inv.tags).filter((tag) => isTagChildOf(tag.name, tagName));
1154
+ }
1155
+ function getTagDescendants(inv, tagName) {
1156
+ const prefix = tagName + ":";
1157
+ return Object.values(inv.tags).filter((tag) => tag.name.startsWith(prefix));
1158
+ }
1159
+ function getTagAggregatedScore(inv, tagName) {
1160
+ const tag = getTagByName(inv, tagName);
1161
+ if (!tag) {
1162
+ return 0;
1163
+ }
1164
+ let total = tag.direct_score;
1165
+ const children = getTagChildren(inv, tagName);
1166
+ for (const child of children) {
1167
+ total += getTagAggregatedScore(inv, child.name);
1168
+ }
1169
+ return total;
1170
+ }
1171
+ function getTagAggregatedLevel(inv, tagName) {
1172
+ return getLevelFromScore(getTagAggregatedScore(inv, tagName));
1173
+ }
1208
1174
 
1209
1175
  // src/finders.ts
1210
1176
  function findObservablesByType(inv, type) {
@@ -1252,51 +1218,19 @@ function findObservablesWithThreatIntel(inv) {
1252
1218
  (obs) => obs.threat_intels.length > 0
1253
1219
  );
1254
1220
  }
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
1221
  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;
1222
+ return Object.values(inv.checks).filter((check) => check.level === level);
1277
1223
  }
1278
1224
  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;
1225
+ return Object.values(inv.checks).filter(
1226
+ (check) => isLevelAtLeast(check.level, minLevel2)
1227
+ );
1288
1228
  }
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;
1229
+ function findCheckByName(inv, checkName) {
1230
+ const normalizedName = checkName.trim().toLowerCase();
1231
+ return Object.values(inv.checks).find(
1232
+ (check) => check.check_name.toLowerCase() === normalizedName
1233
+ );
1300
1234
  }
1301
1235
  function findThreatIntelBySource(inv, source) {
1302
1236
  const normalizedSource = source.trim().toLowerCase();
@@ -1312,52 +1246,31 @@ function findThreatIntelAtLeast(inv, minLevel2) {
1312
1246
  (ti) => isLevelAtLeast(ti.level, minLevel2)
1313
1247
  );
1314
1248
  }
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;
1249
+ function findTagsByLevel(inv, level) {
1250
+ return Object.values(inv.tags).filter((tag) => tag.direct_level === level);
1327
1251
  }
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;
1252
+ function findTagsAtLeast(inv, minLevel2) {
1253
+ return Object.values(inv.tags).filter(
1254
+ (tag) => isLevelAtLeast(tag.direct_level, minLevel2)
1255
+ );
1340
1256
  }
1341
- function getChecksForObservable(inv, observableKey) {
1257
+ function findTagsByNamePattern(inv, pattern) {
1258
+ return Object.values(inv.tags).filter((tag) => pattern.test(tag.name));
1259
+ }
1260
+ function findChecksForObservable(inv, observableKey) {
1342
1261
  const result = [];
1343
1262
  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
1263
  const observable = inv.observables[observableKey];
1351
1264
  if (observable) {
1352
1265
  for (const checkKey of observable.check_links) {
1353
- const check = checkLookup.get(checkKey);
1266
+ const check = inv.checks[checkKey];
1354
1267
  if (check && !seen.has(check.key)) {
1355
1268
  result.push(check);
1356
1269
  seen.add(check.key);
1357
1270
  }
1358
1271
  }
1359
1272
  }
1360
- for (const check of checkLookup.values()) {
1273
+ for (const check of Object.values(inv.checks)) {
1361
1274
  if (seen.has(check.key)) {
1362
1275
  continue;
1363
1276
  }
@@ -1368,7 +1281,7 @@ function getChecksForObservable(inv, observableKey) {
1368
1281
  }
1369
1282
  return result;
1370
1283
  }
1371
- function getThreatIntelsForObservable(inv, observableKey) {
1284
+ function findThreatIntelsForObservable(inv, observableKey) {
1372
1285
  const observable = inv.observables[observableKey];
1373
1286
  if (observable) {
1374
1287
  return observable.threat_intels.map((tiKey) => inv.threat_intels[tiKey]).filter((ti) => ti !== void 0);
@@ -1377,51 +1290,41 @@ function getThreatIntelsForObservable(inv, observableKey) {
1377
1290
  (ti) => ti.observable_key === observableKey
1378
1291
  );
1379
1292
  }
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
- }
1293
+ function findObservablesForCheck(inv, checkKey) {
1294
+ const check = inv.checks[checkKey];
1295
+ if (check) {
1296
+ const keys = /* @__PURE__ */ new Set();
1297
+ for (const link of check.observable_links) {
1298
+ keys.add(link.observable_key);
1390
1299
  }
1300
+ return Array.from(keys).map((obsKey) => inv.observables[obsKey]).filter((obs) => obs !== void 0);
1391
1301
  }
1392
1302
  return [];
1393
1303
  }
1394
- function getChecksForContainer(inv, containerKey, recursive = false) {
1304
+ function findChecksForTag(inv, tagKey, recursive = false) {
1395
1305
  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;
1306
+ const tag = inv.tags[tagKey];
1307
+ if (!tag) {
1308
+ return result;
1309
+ }
1310
+ for (const checkKey of tag.checks) {
1311
+ const check = inv.checks[checkKey];
1312
+ if (check) {
1313
+ result.push(check);
1403
1314
  }
1404
- return void 0;
1405
1315
  }
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) {
1316
+ if (recursive) {
1317
+ const prefix = tag.name + ":";
1318
+ for (const otherTag of Object.values(inv.tags)) {
1319
+ if (otherTag.name.startsWith(prefix)) {
1320
+ for (const checkKey of otherTag.checks) {
1321
+ const check = inv.checks[checkKey];
1322
+ if (check) {
1411
1323
  result.push(check);
1412
1324
  }
1413
1325
  }
1414
1326
  }
1415
1327
  }
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
1328
  }
1426
1329
  return result;
1427
1330
  }
@@ -1441,29 +1344,25 @@ function sortChecksByLevel(checks) {
1441
1344
  (a, b) => LEVEL_VALUES[b.level] - LEVEL_VALUES[a.level]
1442
1345
  );
1443
1346
  }
1444
- function getHighestScoringObservables(inv, n = 10) {
1347
+ function findHighestScoringObservables(inv, n = 10) {
1445
1348
  return sortObservablesByScore(Object.values(inv.observables)).slice(0, n);
1446
1349
  }
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);
1350
+ function findHighestScoringChecks(inv, n = 10) {
1351
+ return sortChecksByScore(Object.values(inv.checks)).slice(0, n);
1453
1352
  }
1454
- function getMaliciousObservables(inv) {
1353
+ function findMaliciousObservables(inv) {
1455
1354
  return findObservablesByLevel(inv, "MALICIOUS");
1456
1355
  }
1457
- function getSuspiciousObservables(inv) {
1356
+ function findSuspiciousObservables(inv) {
1458
1357
  return findObservablesByLevel(inv, "SUSPICIOUS");
1459
1358
  }
1460
- function getMaliciousChecks(inv) {
1359
+ function findMaliciousChecks(inv) {
1461
1360
  return findChecksByLevel(inv, "MALICIOUS");
1462
1361
  }
1463
- function getSuspiciousChecks(inv) {
1362
+ function findSuspiciousChecks(inv) {
1464
1363
  return findChecksByLevel(inv, "SUSPICIOUS");
1465
1364
  }
1466
- function getAllScopes(inv) {
1365
+ function getAllCheckKeys(inv) {
1467
1366
  return Object.keys(inv.checks);
1468
1367
  }
1469
1368
  function getAllObservableTypes(inv) {
@@ -1600,7 +1499,7 @@ function getObservableGraph(inv) {
1600
1499
  }
1601
1500
  return { nodes, edges };
1602
1501
  }
1603
- function findRootObservables(inv) {
1502
+ function findSourceObservables(inv) {
1604
1503
  const targetKeys = /* @__PURE__ */ new Set();
1605
1504
  for (const obs of Object.values(inv.observables)) {
1606
1505
  for (const rel of obs.relationships) {
@@ -1748,85 +1647,93 @@ export {
1748
1647
  areConnected,
1749
1648
  compareLevels,
1750
1649
  countRelationshipsByType,
1650
+ findCheckByName,
1751
1651
  findChecksAtLeast,
1752
- findChecksByCheckId,
1753
1652
  findChecksByLevel,
1754
- findChecksByScope,
1755
- findContainersAtLeast,
1756
- findContainersByLevel,
1653
+ findChecksForObservable,
1654
+ findChecksForTag,
1757
1655
  findExternalObservables,
1656
+ findHighestScoringChecks,
1657
+ findHighestScoringObservables,
1758
1658
  findInternalObservables,
1759
1659
  findLeafObservables,
1660
+ findMaliciousChecks,
1661
+ findMaliciousObservables,
1760
1662
  findObservablesAtLeast,
1761
1663
  findObservablesByLevel,
1762
1664
  findObservablesByType,
1763
1665
  findObservablesByValue,
1764
1666
  findObservablesContaining,
1667
+ findObservablesForCheck,
1765
1668
  findObservablesMatching,
1766
1669
  findObservablesWithThreatIntel,
1767
1670
  findOrphanObservables,
1768
1671
  findPath,
1769
- findRootObservables,
1672
+ findSourceObservables,
1673
+ findSuspiciousChecks,
1674
+ findSuspiciousObservables,
1675
+ findTagsAtLeast,
1676
+ findTagsByLevel,
1677
+ findTagsByNamePattern,
1770
1678
  findThreatIntelAtLeast,
1771
1679
  findThreatIntelByLevel,
1772
1680
  findThreatIntelBySource,
1681
+ findThreatIntelsForObservable,
1773
1682
  findWhitelistedObservables,
1774
1683
  generateCheckKey,
1775
- generateContainerKey,
1776
1684
  generateEnrichmentKey,
1777
1685
  generateObservableKey,
1686
+ generateTagKey,
1778
1687
  generateThreatIntelKey,
1688
+ getAllCheckKeys,
1779
1689
  getAllChecks,
1780
- getAllContainers,
1781
1690
  getAllEnrichments,
1782
1691
  getAllObservableTypes,
1783
1692
  getAllObservables,
1784
1693
  getAllRelationshipTypes,
1785
- getAllScopes,
1694
+ getAllTags,
1786
1695
  getAllThreatIntelSources,
1787
1696
  getAllThreatIntels,
1788
1697
  getCheck,
1789
- getCheckByIdScope,
1790
- getChecksForContainer,
1791
- getChecksForObservable,
1698
+ getCheckByName,
1792
1699
  getColorForLevel,
1793
1700
  getColorForScore,
1794
- getContainer,
1795
- getContainerByPath,
1796
1701
  getCounts,
1797
1702
  getDataExtraction,
1798
1703
  getEnrichment,
1799
1704
  getEnrichmentByName,
1800
1705
  getEntityLevel,
1801
- getHighestScoringChecks,
1802
- getHighestScoringObservables,
1803
1706
  getLevelFromScore,
1804
- getMaliciousChecks,
1805
- getMaliciousObservables,
1806
1707
  getObservable,
1807
1708
  getObservableByTypeValue,
1808
1709
  getObservableChildren,
1809
1710
  getObservableGraph,
1810
1711
  getObservableParents,
1811
- getObservablesForCheck,
1812
1712
  getReachableObservables,
1813
1713
  getRelatedObservables,
1814
1714
  getRelatedObservablesByDirection,
1815
1715
  getRelatedObservablesByType,
1816
1716
  getRelationshipsForObservable,
1717
+ getRootObservable,
1817
1718
  getStartedAt,
1818
1719
  getStats,
1819
- getSuspiciousChecks,
1820
- getSuspiciousObservables,
1720
+ getTag,
1721
+ getTagAggregatedLevel,
1722
+ getTagAggregatedScore,
1723
+ getTagAncestors,
1724
+ getTagByName,
1725
+ getTagChildren,
1726
+ getTagDescendants,
1821
1727
  getThreatIntel,
1822
1728
  getThreatIntelBySourceObservable,
1823
- getThreatIntelsForObservable,
1824
1729
  getWhitelists,
1825
1730
  hasLevel,
1826
1731
  isCyvest,
1827
1732
  isLevelAtLeast,
1828
1733
  isLevelHigherThan,
1829
1734
  isLevelLowerThan,
1735
+ isTagChildOf,
1736
+ isTagDescendantOf,
1830
1737
  isValidLevel,
1831
1738
  maxLevel,
1832
1739
  minLevel,