@chainpatrol/cli 0.11.0 → 0.13.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/{breakdown-MM5GSZKV.js → breakdown-B6QUGYI6.js} +21 -6
  3. package/dist/{check-GDKUHVQI.js → check-P5JJJNEX.js} +1 -1
  4. package/dist/{chunk-EPKNZRX6.js → chunk-BQDMAEQU.js} +51 -6
  5. package/dist/{chunk-37KYJWB3.js → chunk-DJVB73FL.js} +1 -1
  6. package/dist/{chunk-YXRFUYA6.js → chunk-NQT77IB7.js} +50 -8
  7. package/dist/{chunk-SX3L6NKR.js → chunk-OSRFCVBT.js} +129 -2
  8. package/dist/chunk-S37VFIZY.js +66 -0
  9. package/dist/cli.js +411 -86
  10. package/dist/{completions-62OW3B3Y.js → completions-6C6KG5DH.js} +1 -1
  11. package/dist/{configs-update-7X7657PB.js → configs-update-3ZVXGADV.js} +1 -1
  12. package/dist/{create-FL4QQTPN.js → create-DFH2G7RH.js} +1 -1
  13. package/dist/{drift-JKBHWWFU.js → drift-T74V2C3J.js} +1 -1
  14. package/dist/found-NXAWEIEK.js +59 -0
  15. package/dist/{healthcheck-EVQVPGWW.js → healthcheck-HZYEIIOR.js} +1 -1
  16. package/dist/{list-BLNIE4GL.js → list-23QQYAV5.js} +1 -1
  17. package/dist/list-EIVPGMWJ.js +82 -0
  18. package/dist/list-I7SBGA52.js +50 -0
  19. package/dist/{list-5DN6X3DP.js → list-IYJBKE2F.js} +1 -1
  20. package/dist/list-PBAXQSL5.js +85 -0
  21. package/dist/list-QUFY4IP7.js +146 -0
  22. package/dist/{list-JPG2ZSR4.js → list-WJQT2XLE.js} +7 -1
  23. package/dist/{list-ULHPOUJV.js → list-WX5G3IOF.js} +2 -2
  24. package/dist/list-YCT6DYDI.js +89 -0
  25. package/dist/{list-XDGU6SJQ.js → list-YRJPN4PI.js} +1 -1
  26. package/dist/{list-E5XNR2YG.js → list-ZFPML3ZR.js} +47 -3
  27. package/dist/{list-json-R2MIXADX.js → list-json-T2Z7NV7G.js} +1 -1
  28. package/dist/{organization-MJRKWC4Z.js → organization-GS5LFIWO.js} +19 -6
  29. package/dist/{run-EUVRC72M.js → run-BHEXWBAS.js} +2 -2
  30. package/dist/{run-2YZZGZYN.js → run-CJGN6TX4.js} +1 -1
  31. package/dist/{run-5E5EC3MP.js → run-MSO6IXEV.js} +1 -1
  32. package/dist/search-WPSKQGUS.js +71 -0
  33. package/dist/{setup-skill-HAENFIFQ.js → setup-skill-TPMTULHJ.js} +2 -2
  34. package/dist/{snapshot-3FUJICJJ.js → snapshot-ZWAHEG64.js} +1 -1
  35. package/dist/{summary-RVYQUKWV.js → summary-CV657J5V.js} +19 -6
  36. package/dist/{validate-UOVKEAJM.js → validate-SM5DD7I2.js} +1 -1
  37. package/dist/whoami-DH5HVLFN.js +69 -0
  38. package/package.json +1 -1
  39. package/dist/found-3WI4XQG4.js +0 -95
@@ -3,7 +3,7 @@ import {
3
3
  installCompletions,
4
4
  printCompletions,
5
5
  uninstallCompletions
6
- } from "./chunk-YXRFUYA6.js";
6
+ } from "./chunk-NQT77IB7.js";
7
7
  export {
8
8
  getCompletionScript,
9
9
  installCompletions,
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VFT3TD3E.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-SX3L6NKR.js";
10
+ } from "./chunk-OSRFCVBT.js";
11
11
  import "./chunk-EGWK6SRQ.js";
12
12
  import "./chunk-TFCNKBRC.js";
13
13
  import "./chunk-U73SABXK.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-SX3L6NKR.js";
11
+ } from "./chunk-OSRFCVBT.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-SX3L6NKR.js";
11
+ } from "./chunk-OSRFCVBT.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -0,0 +1,59 @@
1
+ import {
2
+ resolveDateRange
3
+ } from "./chunk-S37VFIZY.js";
4
+ import {
5
+ printOutput,
6
+ toCsvRows
7
+ } from "./chunk-VFT3TD3E.js";
8
+ import {
9
+ createApiClient
10
+ } from "./chunk-OSRFCVBT.js";
11
+ import "./chunk-EGWK6SRQ.js";
12
+ import "./chunk-TFCNKBRC.js";
13
+ import "./chunk-U73SABXK.js";
14
+
15
+ // src/commands/metrics/found.ts
16
+ async function runMetricsFound(options) {
17
+ const range = resolveDateRange({
18
+ from: options.from,
19
+ to: options.to,
20
+ thisWeek: options.thisWeek
21
+ });
22
+ const client = options.apiClient ?? createApiClient();
23
+ const result = await client.getMetricsFound({
24
+ slug: options.org,
25
+ startDate: range.startDate,
26
+ endDate: range.endDate,
27
+ brandIds: options.brandIds
28
+ });
29
+ const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
30
+ printOutput({
31
+ outputFormat,
32
+ json: { ...result, range },
33
+ markdown: [
34
+ `# Found Threats (${options.org}) \u2014 ${range.label}`,
35
+ "",
36
+ `- Metric: ${result.metric}`,
37
+ `- Found: ${result.found}`,
38
+ `- Range: ${range.startDate} \u2192 ${range.endDate}`
39
+ ].join("\n"),
40
+ csv: toCsvRows([
41
+ {
42
+ rangeLabel: range.label,
43
+ metric: result.metric,
44
+ found: result.found,
45
+ startDate: range.startDate,
46
+ endDate: range.endDate
47
+ }
48
+ ]),
49
+ human: () => {
50
+ console.log(
51
+ `Found threats (${result.metric}) for ${options.org} \u2014 ${range.label}: ${result.found}`
52
+ );
53
+ console.log(`Range: ${range.startDate} \u2192 ${range.endDate}`);
54
+ }
55
+ });
56
+ }
57
+ export {
58
+ runMetricsFound
59
+ };
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-SX3L6NKR.js";
11
+ } from "./chunk-OSRFCVBT.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-VFT3TD3E.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-SX3L6NKR.js";
7
+ } from "./chunk-OSRFCVBT.js";
8
8
  import "./chunk-EGWK6SRQ.js";
9
9
  import "./chunk-TFCNKBRC.js";
10
10
  import "./chunk-U73SABXK.js";
@@ -0,0 +1,82 @@
1
+ import {
2
+ CliExitError,
3
+ ExitCode
4
+ } from "./chunk-E2LAMILJ.js";
5
+ import {
6
+ printOutput,
7
+ toCsvRows
8
+ } from "./chunk-VFT3TD3E.js";
9
+ import {
10
+ createApiClient
11
+ } from "./chunk-OSRFCVBT.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
+ import "./chunk-TFCNKBRC.js";
14
+ import "./chunk-U73SABXK.js";
15
+
16
+ // src/commands/orgs/assets/list.ts
17
+ function toRow(asset) {
18
+ return {
19
+ id: asset.id,
20
+ content: asset.content,
21
+ type: asset.type,
22
+ status: asset.status,
23
+ name: asset.name ?? "",
24
+ group: asset.group?.name ?? "",
25
+ groupId: asset.group?.id ?? "",
26
+ createdAt: asset.createdAt,
27
+ updatedAt: asset.updatedAt
28
+ };
29
+ }
30
+ async function runOrgsAssetsList(options) {
31
+ const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
32
+ const perPage = options.perPage;
33
+ if (perPage !== void 0 && (perPage < 1 || perPage > 1e3)) {
34
+ throw new CliExitError(
35
+ "orgs assets list requires --per-page between 1 and 1000.",
36
+ ExitCode.USAGE
37
+ );
38
+ }
39
+ const client = options.apiClient ?? createApiClient();
40
+ const input = {
41
+ type: options.type ? options.type.toUpperCase() : void 0,
42
+ groupId: options.groupId,
43
+ query: options.query,
44
+ perPage,
45
+ nextPage: options.nextPage
46
+ };
47
+ const result = await client.listOrganizationAssets(input);
48
+ const rows = result.assets.map(toRow);
49
+ printOutput({
50
+ outputFormat,
51
+ json: result,
52
+ markdown: [
53
+ "# Organization assets",
54
+ "",
55
+ `- Returned: ${result.assets.length}`,
56
+ `- Next page cursor: ${result.next_page ?? "none"}`,
57
+ "",
58
+ ...rows.map(
59
+ (row) => `- #${row.id} [${row.status}] ${row.content} (${row.type}) group=${row.group || "-"} updated=${row.updatedAt}`
60
+ )
61
+ ].join("\n"),
62
+ csv: toCsvRows(rows),
63
+ human: () => {
64
+ if (result.assets.length === 0) {
65
+ console.log("No organization assets found.");
66
+ return;
67
+ }
68
+ console.log(`Organization assets \u2014 returned ${result.assets.length}`);
69
+ for (const row of rows) {
70
+ console.log(
71
+ `#${row.id} [${row.status}] ${row.content} (${row.type}) group=${row.group || "-"} name=${row.name || "-"} updated=${row.updatedAt}`
72
+ );
73
+ }
74
+ if (result.next_page) {
75
+ console.log(`Next page cursor: ${result.next_page}`);
76
+ }
77
+ }
78
+ });
79
+ }
80
+ export {
81
+ runOrgsAssetsList
82
+ };
@@ -0,0 +1,50 @@
1
+ import {
2
+ printOutput,
3
+ toCsvRows
4
+ } from "./chunk-VFT3TD3E.js";
5
+ import {
6
+ createApiClient
7
+ } from "./chunk-OSRFCVBT.js";
8
+ import "./chunk-EGWK6SRQ.js";
9
+ import "./chunk-TFCNKBRC.js";
10
+ import "./chunk-U73SABXK.js";
11
+
12
+ // src/commands/orgs/asset-groups/list.ts
13
+ function toRow(group) {
14
+ return {
15
+ id: group.id,
16
+ name: group.name,
17
+ assetCount: group.assetCount
18
+ };
19
+ }
20
+ async function runOrgsAssetGroupsList(options) {
21
+ const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
22
+ const client = options.apiClient ?? createApiClient();
23
+ const result = await client.listOrganizationAssetGroups();
24
+ const rows = result.groups.map(toRow);
25
+ printOutput({
26
+ outputFormat,
27
+ json: result,
28
+ markdown: [
29
+ "# Organization asset groups",
30
+ "",
31
+ `- Returned: ${result.groups.length}`,
32
+ "",
33
+ ...rows.map((row) => `- #${row.id} ${row.name} (assets=${row.assetCount})`)
34
+ ].join("\n"),
35
+ csv: toCsvRows(rows),
36
+ human: () => {
37
+ if (result.groups.length === 0) {
38
+ console.log("No asset groups found.");
39
+ return;
40
+ }
41
+ console.log(`Organization asset groups \u2014 returned ${result.groups.length}`);
42
+ for (const row of rows) {
43
+ console.log(`#${row.id} ${row.name} (assets=${row.assetCount})`);
44
+ }
45
+ }
46
+ });
47
+ }
48
+ export {
49
+ runOrgsAssetGroupsList
50
+ };
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-JCMWDZYY.js";
5
5
  import {
6
6
  createApiClient
7
- } from "./chunk-SX3L6NKR.js";
7
+ } from "./chunk-OSRFCVBT.js";
8
8
  import {
9
9
  AuthCorruptedError,
10
10
  AuthExpiredError,
@@ -0,0 +1,85 @@
1
+ import {
2
+ CliExitError,
3
+ ExitCode
4
+ } from "./chunk-E2LAMILJ.js";
5
+ import {
6
+ printOutput,
7
+ toCsvRows
8
+ } from "./chunk-VFT3TD3E.js";
9
+ import {
10
+ createApiClient
11
+ } from "./chunk-OSRFCVBT.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
+ import "./chunk-TFCNKBRC.js";
14
+ import "./chunk-U73SABXK.js";
15
+
16
+ // src/commands/asset/list.ts
17
+ function toRow(asset) {
18
+ return {
19
+ content: asset.content,
20
+ type: asset.type,
21
+ status: asset.status,
22
+ watchStatus: asset.watchStatus,
23
+ updatedAt: asset.updatedAt
24
+ };
25
+ }
26
+ async function runAssetList(options) {
27
+ const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
28
+ if (!options.type) {
29
+ throw new CliExitError(
30
+ "asset list requires --asset-type <URL|ADDRESS|TWITTER|...>. Pass a single value.",
31
+ ExitCode.USAGE
32
+ );
33
+ }
34
+ const perPage = options.perPage;
35
+ if (perPage !== void 0 && (perPage < 1 || perPage > 1e4)) {
36
+ throw new CliExitError(
37
+ "asset list requires --per-page between 1 and 10000.",
38
+ ExitCode.USAGE
39
+ );
40
+ }
41
+ const client = options.apiClient ?? createApiClient();
42
+ const input = {
43
+ type: options.type.toUpperCase(),
44
+ status: options.status ? options.status.toUpperCase() : void 0,
45
+ startDate: options.from,
46
+ endDate: options.to,
47
+ perPage,
48
+ nextPage: options.nextPage
49
+ };
50
+ const result = await client.listAssets(input);
51
+ const rows = result.assets.map(toRow);
52
+ printOutput({
53
+ outputFormat,
54
+ json: result,
55
+ markdown: [
56
+ `# Assets (${input.type})`,
57
+ "",
58
+ `- Returned: ${result.assets.length}`,
59
+ `- Next page cursor: ${result.next_page ?? "none"}`,
60
+ "",
61
+ ...rows.map(
62
+ (row) => `- [${row.status}] ${row.content} (${row.type}) watch=${row.watchStatus} updated=${row.updatedAt}`
63
+ )
64
+ ].join("\n"),
65
+ csv: toCsvRows(rows),
66
+ human: () => {
67
+ if (result.assets.length === 0) {
68
+ console.log("No assets found.");
69
+ return;
70
+ }
71
+ console.log(`Assets (${input.type}) \u2014 returned ${result.assets.length}`);
72
+ for (const row of rows) {
73
+ console.log(
74
+ `[${row.status}] ${row.content} (${row.type}) watch=${row.watchStatus} updated=${row.updatedAt}`
75
+ );
76
+ }
77
+ if (result.next_page) {
78
+ console.log(`Next page cursor: ${result.next_page}`);
79
+ }
80
+ }
81
+ });
82
+ }
83
+ export {
84
+ runAssetList
85
+ };
@@ -0,0 +1,146 @@
1
+ import {
2
+ CliExitError,
3
+ ExitCode
4
+ } from "./chunk-E2LAMILJ.js";
5
+ import {
6
+ printOutput,
7
+ toCsvRows
8
+ } from "./chunk-VFT3TD3E.js";
9
+ import {
10
+ DETECTION_CONFIDENCE_LEVELS,
11
+ DETECTION_REPORTED_FILTERS,
12
+ LIVENESS_FILTER_VALUES,
13
+ WATCHLIST_FILTER_VALUES,
14
+ createApiClient
15
+ } from "./chunk-OSRFCVBT.js";
16
+ import "./chunk-EGWK6SRQ.js";
17
+ import "./chunk-TFCNKBRC.js";
18
+ import "./chunk-U73SABXK.js";
19
+
20
+ // src/commands/detections/list.ts
21
+ var CONFIDENCE_SET = new Set(DETECTION_CONFIDENCE_LEVELS);
22
+ var REPORTED_SET = new Set(DETECTION_REPORTED_FILTERS);
23
+ var LIVENESS_SET = new Set(LIVENESS_FILTER_VALUES);
24
+ var WATCHLIST_SET = new Set(WATCHLIST_FILTER_VALUES);
25
+ function validateEnumList(values, validSet, flagName, transform = (v) => v) {
26
+ if (!values || values.length === 0) return void 0;
27
+ const normalized = values.map(transform);
28
+ const invalid = normalized.filter((value) => !validSet.has(value));
29
+ if (invalid.length > 0) {
30
+ throw new CliExitError(
31
+ `Invalid --${flagName} value(s): ${invalid.join(", ")}. Valid: ${Array.from(
32
+ validSet
33
+ ).join(", ")}`,
34
+ ExitCode.USAGE
35
+ );
36
+ }
37
+ return normalized;
38
+ }
39
+ function toRow(detection) {
40
+ return {
41
+ id: detection.id,
42
+ source: detection.source,
43
+ confidence: detection.confidence,
44
+ reportStatus: detection.reportStatus,
45
+ threatContent: detection.threatContent,
46
+ assetContent: detection.asset.content,
47
+ assetType: detection.asset.type,
48
+ assetStatus: detection.asset.status,
49
+ createdAt: detection.createdAt
50
+ };
51
+ }
52
+ async function runDetectionsList(options) {
53
+ const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
54
+ const limit = options.limit;
55
+ if (limit !== void 0 && (limit < 1 || limit > 100)) {
56
+ throw new CliExitError(
57
+ "detections list requires --limit between 1 and 100.",
58
+ ExitCode.USAGE
59
+ );
60
+ }
61
+ const confidence = validateEnumList(
62
+ options.confidence,
63
+ CONFIDENCE_SET,
64
+ "confidence",
65
+ (v) => v.toLowerCase()
66
+ );
67
+ const reported = validateEnumList(
68
+ options.reported,
69
+ REPORTED_SET,
70
+ "reported",
71
+ (v) => v.toLowerCase()
72
+ );
73
+ const liveness = validateEnumList(
74
+ options.liveness,
75
+ LIVENESS_SET,
76
+ "liveness",
77
+ (v) => v.toUpperCase()
78
+ );
79
+ const watchlist = validateEnumList(
80
+ options.watchlist,
81
+ WATCHLIST_SET,
82
+ "watchlist",
83
+ (v) => v.toUpperCase()
84
+ );
85
+ const countryCodes = options.countryCodes?.length ? options.countryCodes.map((code) => code.toUpperCase()) : void 0;
86
+ if (countryCodes?.some((code) => code.length !== 2)) {
87
+ throw new CliExitError(
88
+ "--country-code values must be 2-letter ISO country codes (e.g. US, GB).",
89
+ ExitCode.USAGE
90
+ );
91
+ }
92
+ const client = options.apiClient ?? createApiClient();
93
+ const input = {
94
+ slug: options.org,
95
+ cursor: options.cursor,
96
+ limit,
97
+ query: options.query,
98
+ startDate: options.from,
99
+ endDate: options.to,
100
+ sources: options.sources?.length ? options.sources : void 0,
101
+ confidence,
102
+ assetStatus: options.assetStatus?.length ? options.assetStatus.map((s) => s.toUpperCase()) : void 0,
103
+ assetType: options.assetType?.length ? options.assetType.map((t) => t.toUpperCase()) : void 0,
104
+ brandIds: options.brandIds?.length ? options.brandIds : void 0,
105
+ liveness,
106
+ watchlist,
107
+ reported,
108
+ countryCodes,
109
+ onlyDeleted: options.onlyDeleted
110
+ };
111
+ const result = await client.listDetections(input);
112
+ const rows = result.detections.map(toRow);
113
+ printOutput({
114
+ outputFormat,
115
+ json: result,
116
+ markdown: [
117
+ `# Detections (${options.org})`,
118
+ "",
119
+ `- Returned: ${result.detections.length}`,
120
+ `- Next cursor: ${result.nextCursor ?? "none"}`,
121
+ "",
122
+ ...rows.map(
123
+ (row) => `- #${row.id} [${row.confidence}] ${row.source} \u2192 ${row.assetContent} (${row.assetType}) ${row.assetStatus} reported=${row.reportStatus} created=${row.createdAt}`
124
+ )
125
+ ].join("\n"),
126
+ csv: toCsvRows(rows),
127
+ human: () => {
128
+ if (result.detections.length === 0) {
129
+ console.log("No detections found.");
130
+ return;
131
+ }
132
+ console.log(`Detections for ${options.org} \u2014 returned ${result.detections.length}`);
133
+ for (const row of rows) {
134
+ console.log(
135
+ `#${row.id} [${row.confidence}] ${row.source} \u2192 ${row.assetContent} (${row.assetType}/${row.assetStatus}) ${row.reportStatus} ${row.createdAt}`
136
+ );
137
+ }
138
+ if (result.nextCursor !== void 0) {
139
+ console.log(`Next cursor: ${result.nextCursor}`);
140
+ }
141
+ }
142
+ });
143
+ }
144
+ export {
145
+ runDetectionsList
146
+ };
@@ -11,7 +11,7 @@ import {
11
11
  TAKEDOWN_SORT_KEYS,
12
12
  TAKEDOWN_STATUSES,
13
13
  createApiClient
14
- } from "./chunk-SX3L6NKR.js";
14
+ } from "./chunk-OSRFCVBT.js";
15
15
  import "./chunk-EGWK6SRQ.js";
16
16
  import "./chunk-TFCNKBRC.js";
17
17
  import "./chunk-U73SABXK.js";
@@ -88,6 +88,12 @@ async function runTakedownsList(options) {
88
88
  assetType,
89
89
  takedownStatus,
90
90
  livenessStatus,
91
+ brandIds: options.brandIds?.length ? options.brandIds : void 0,
92
+ assigneeIds: options.assigneeIds?.length ? options.assigneeIds : void 0,
93
+ startedAtStartDate: options.startedFrom,
94
+ startedAtEndDate: options.startedTo,
95
+ hideAutomatedTakedowns: options.hideAutomatedTakedowns,
96
+ hideAutomatedLivenessChecks: options.hideAutomatedLivenessChecks,
91
97
  perPage,
92
98
  nextPage: options.nextPage,
93
99
  sorting: options.sortBy ? [
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  PRESETS
3
- } from "./chunk-37KYJWB3.js";
3
+ } from "./chunk-DJVB73FL.js";
4
4
  import "./chunk-E2LAMILJ.js";
5
5
  import {
6
6
  printOutput,
7
7
  toCsvRows
8
8
  } from "./chunk-VFT3TD3E.js";
9
- import "./chunk-SX3L6NKR.js";
9
+ import "./chunk-OSRFCVBT.js";
10
10
  import "./chunk-EGWK6SRQ.js";
11
11
  import "./chunk-TFCNKBRC.js";
12
12
  import "./chunk-U73SABXK.js";
@@ -0,0 +1,89 @@
1
+ import {
2
+ CliExitError,
3
+ ExitCode
4
+ } from "./chunk-E2LAMILJ.js";
5
+ import {
6
+ printOutput,
7
+ toCsvRows
8
+ } from "./chunk-VFT3TD3E.js";
9
+ import {
10
+ createApiClient
11
+ } from "./chunk-OSRFCVBT.js";
12
+ import "./chunk-EGWK6SRQ.js";
13
+ import "./chunk-TFCNKBRC.js";
14
+ import "./chunk-U73SABXK.js";
15
+
16
+ // src/commands/threats/list.ts
17
+ function toRow(threat) {
18
+ return {
19
+ id: threat.id,
20
+ content: threat.content,
21
+ type: threat.type,
22
+ blockedAt: threat.blockedAt
23
+ };
24
+ }
25
+ async function runThreatsList(options) {
26
+ const outputFormat = options.outputFormat ?? (options.json ? "json" : "human");
27
+ const perPage = options.perPage;
28
+ if (perPage !== void 0 && (perPage < 1 || perPage > 100)) {
29
+ throw new CliExitError(
30
+ "threats list requires --per-page between 1 and 100.",
31
+ ExitCode.USAGE
32
+ );
33
+ }
34
+ const sortDirection = options.sortDirection;
35
+ if (sortDirection && sortDirection !== "asc" && sortDirection !== "desc") {
36
+ throw new CliExitError(
37
+ `Invalid --sort-direction '${sortDirection}'. Use 'asc' or 'desc'.`,
38
+ ExitCode.USAGE
39
+ );
40
+ }
41
+ const client = options.apiClient ?? createApiClient();
42
+ const input = {
43
+ query: options.query,
44
+ startDate: options.from,
45
+ endDate: options.to,
46
+ assetType: options.assetType?.length ? options.assetType.map((t) => t.toUpperCase()) : void 0,
47
+ sorting: options.sortBy ? [
48
+ {
49
+ key: options.sortBy,
50
+ direction: sortDirection ?? "desc"
51
+ }
52
+ ] : void 0,
53
+ perPage,
54
+ nextPage: options.nextPage
55
+ };
56
+ const result = await client.listThreats(input);
57
+ const rows = result.threats.map(toRow);
58
+ printOutput({
59
+ outputFormat,
60
+ json: result,
61
+ markdown: [
62
+ "# Threats",
63
+ "",
64
+ `- Returned: ${result.threats.length}`,
65
+ `- Next page cursor: ${result.next_page ?? "none"}`,
66
+ "",
67
+ ...rows.map(
68
+ (row) => `- #${row.id} (${row.type}) ${row.content} \u2014 blocked=${row.blockedAt}`
69
+ )
70
+ ].join("\n"),
71
+ csv: toCsvRows(rows),
72
+ human: () => {
73
+ if (result.threats.length === 0) {
74
+ console.log("No threats found.");
75
+ return;
76
+ }
77
+ console.log(`Threats \u2014 returned ${result.threats.length}`);
78
+ for (const row of rows) {
79
+ console.log(`#${row.id} (${row.type}) ${row.content} \u2014 blocked=${row.blockedAt}`);
80
+ }
81
+ if (result.next_page) {
82
+ console.log(`Next page cursor: ${result.next_page}`);
83
+ }
84
+ }
85
+ });
86
+ }
87
+ export {
88
+ runThreatsList
89
+ };
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VFT3TD3E.js";
9
9
  import {
10
10
  createApiClient
11
- } from "./chunk-SX3L6NKR.js";
11
+ } from "./chunk-OSRFCVBT.js";
12
12
  import "./chunk-EGWK6SRQ.js";
13
13
  import "./chunk-TFCNKBRC.js";
14
14
  import "./chunk-U73SABXK.js";