Skip to content

Commit ffd99e5

Browse files
committed
abstractions
1 parent a237483 commit ffd99e5

File tree

3 files changed

+120
-87
lines changed

3 files changed

+120
-87
lines changed

src/commands/analytics/display-analytics.ts

Lines changed: 47 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import contrib from 'blessed-contrib'
66

77
import { logger } from '@socketsecurity/registry/lib/logger'
88

9+
import { fetchOrgAnalyticsData } from './fetch-org-analytics.ts'
10+
import { fetchRepoAnalyticsData } from './fetch-repo-analytics.ts' // Note: Widgets does not seem to actually work as code :'(
911
import constants from '../../constants'
10-
import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api'
1112
import { AuthError } from '../../utils/errors.ts'
1213
import { mdTableStringNumber } from '../../utils/markdown.ts'
13-
import { getDefaultToken, setupSdk } from '../../utils/sdk'
14+
import { getDefaultToken } from '../../utils/sdk'
1415

15-
import type { Spinner } from '@socketsecurity/registry/lib/spinner'
1616
import type { SocketSdkReturnType } from '@socketsecurity/sdk'
17-
import type { Widgets } from 'blessed' // Note: Widgets does not seem to actually work as code :'(
17+
import type { Widgets } from 'blessed'
1818

1919
interface FormattedData {
2020
top_five_alert_types: Record<string, number>
@@ -32,22 +32,6 @@ interface FormattedData {
3232
total_low_prevented: Record<string, number>
3333
}
3434

35-
// Note: This maps `new Date(date).getMonth()` to English three letters
36-
export const Months = [
37-
'Jan',
38-
'Feb',
39-
'Mar',
40-
'Apr',
41-
'May',
42-
'Jun',
43-
'Jul',
44-
'Aug',
45-
'Sep',
46-
'Oct',
47-
'Nov',
48-
'Dec'
49-
] as const
50-
5135
const METRICS = [
5236
'total_critical_alerts',
5337
'total_high_alerts',
@@ -63,6 +47,22 @@ const METRICS = [
6347
'total_low_prevented'
6448
] as const
6549

50+
// Note: This maps `new Date(date).getMonth()` to English three letters
51+
const Months = [
52+
'Jan',
53+
'Feb',
54+
'Mar',
55+
'Apr',
56+
'May',
57+
'Jun',
58+
'Jul',
59+
'Aug',
60+
'Sep',
61+
'Oct',
62+
'Nov',
63+
'Dec'
64+
] as const
65+
6666
export async function displayAnalytics({
6767
filePath,
6868
outputKind,
@@ -127,17 +127,9 @@ async function outputAnalyticsWithToken({
127127
if (!data) return
128128

129129
if (outputKind === 'json') {
130-
let serialized
131-
try {
132-
serialized = JSON.stringify(data, null, 2)
133-
} catch (e) {
134-
// This could be caused by circular references, which is an "us" problem
135-
logger.error(
136-
'There was a problem converting the data set to JSON. Please try without --json or with --markdown'
137-
)
138-
process.exitCode = 1
139-
return
140-
}
130+
let serialized = renderJson(data)
131+
if (!serialized) return
132+
141133
if (filePath && filePath !== '-') {
142134
try {
143135
await fs.writeFile(filePath, serialized, 'utf8')
@@ -154,7 +146,7 @@ async function outputAnalyticsWithToken({
154146
const fdata = scope === 'org' ? formatDataOrg(data) : formatDataRepo(data)
155147

156148
if (outputKind === 'markdown') {
157-
const serialized = renderMarkdown(fdata)
149+
const serialized = renderMarkdown(fdata, time, repo)
158150

159151
if (filePath) {
160152
try {
@@ -172,9 +164,30 @@ async function outputAnalyticsWithToken({
172164
}
173165
}
174166

175-
function renderMarkdown(data: FormattedData): string {
167+
function renderJson(data: unknown): string | undefined {
168+
try {
169+
return JSON.stringify(data, null, 2)
170+
} catch (e) {
171+
// This could be caused by circular references, which is an "us" problem
172+
logger.error(
173+
'There was a problem converting the data set to JSON. Please try without --json or with --markdown'
174+
)
175+
process.exitCode = 1
176+
return
177+
}
178+
}
179+
180+
function renderMarkdown(
181+
data: FormattedData,
182+
days: number,
183+
repoSlug: string
184+
): string {
176185
return (
177-
'# Socket Alert Analytics\n\nThese are the Socket.dev stats are analytics for the org / [name] repo of the past 7/30/90 days\n\n' +
186+
`# Socket Alert Analytics
187+
188+
These are the Socket.dev stats are analytics for the ${repoSlug ? `${repoSlug} repo` : 'org'} of the past ${days} days
189+
190+
` +
178191
[
179192
[
180193
'Total critical alerts',
@@ -302,59 +315,6 @@ function displayAnalyticsScreen(data: FormattedData): void {
302315
screen.key(['escape', 'q', 'C-c'], () => process.exit(0))
303316
}
304317

305-
async function fetchOrgAnalyticsData(
306-
time: number,
307-
spinner: Spinner,
308-
apiToken: string
309-
): Promise<SocketSdkReturnType<'getOrgAnalytics'>['data'] | undefined> {
310-
const socketSdk = await setupSdk(apiToken)
311-
const result = await handleApiCall(
312-
socketSdk.getOrgAnalytics(time.toString()),
313-
'fetching analytics data'
314-
)
315-
316-
if (result.success === false) {
317-
handleUnsuccessfulApiResponse('getOrgAnalytics', result, spinner)
318-
return undefined
319-
}
320-
321-
spinner.stop()
322-
323-
if (!result.data.length) {
324-
logger.log('No analytics data is available for this organization yet.')
325-
return undefined
326-
}
327-
328-
return result.data
329-
}
330-
331-
async function fetchRepoAnalyticsData(
332-
repo: string,
333-
time: number,
334-
spinner: Spinner,
335-
apiToken: string
336-
): Promise<SocketSdkReturnType<'getRepoAnalytics'>['data'] | undefined> {
337-
const socketSdk = await setupSdk(apiToken)
338-
const result = await handleApiCall(
339-
socketSdk.getRepoAnalytics(repo, time.toString()),
340-
'fetching analytics data'
341-
)
342-
343-
if (result.success === false) {
344-
handleUnsuccessfulApiResponse('getRepoAnalytics', result, spinner)
345-
return undefined
346-
}
347-
348-
spinner.stop()
349-
350-
if (!result.data.length) {
351-
logger.log('No analytics data is available for this organization yet.')
352-
return undefined
353-
}
354-
355-
return result.data
356-
}
357-
358318
function formatDataRepo(
359319
data: SocketSdkReturnType<'getRepoAnalytics'>['data']
360320
): FormattedData {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { logger } from '@socketsecurity/registry/lib/logger'
2+
3+
import {
4+
handleApiCall,
5+
handleUnsuccessfulApiResponse
6+
} from '../../utils/api.ts'
7+
import { setupSdk } from '../../utils/sdk.ts'
8+
9+
import type { Spinner } from '@socketsecurity/registry/lib/spinner'
10+
import type { SocketSdkReturnType } from '@socketsecurity/sdk'
11+
12+
export async function fetchOrgAnalyticsData(
13+
time: number,
14+
spinner: Spinner,
15+
apiToken: string
16+
): Promise<SocketSdkReturnType<'getOrgAnalytics'>['data'] | undefined> {
17+
const socketSdk = await setupSdk(apiToken)
18+
const result = await handleApiCall(
19+
socketSdk.getOrgAnalytics(time.toString()),
20+
'fetching analytics data'
21+
)
22+
23+
if (result.success === false) {
24+
handleUnsuccessfulApiResponse('getOrgAnalytics', result, spinner)
25+
return undefined
26+
}
27+
28+
spinner.stop()
29+
30+
if (!result.data.length) {
31+
logger.log('No analytics data is available for this organization yet.')
32+
return undefined
33+
}
34+
35+
return result.data
36+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { logger } from '@socketsecurity/registry/lib/logger'
2+
3+
import {
4+
handleApiCall,
5+
handleUnsuccessfulApiResponse
6+
} from '../../utils/api.ts'
7+
import { setupSdk } from '../../utils/sdk.ts'
8+
9+
import type { Spinner } from '@socketsecurity/registry/lib/spinner'
10+
import type { SocketSdkReturnType } from '@socketsecurity/sdk'
11+
12+
export async function fetchRepoAnalyticsData(
13+
repo: string,
14+
time: number,
15+
spinner: Spinner,
16+
apiToken: string
17+
): Promise<SocketSdkReturnType<'getRepoAnalytics'>['data'] | undefined> {
18+
const socketSdk = await setupSdk(apiToken)
19+
const result = await handleApiCall(
20+
socketSdk.getRepoAnalytics(repo, time.toString()),
21+
'fetching analytics data'
22+
)
23+
24+
if (result.success === false) {
25+
handleUnsuccessfulApiResponse('getRepoAnalytics', result, spinner)
26+
return undefined
27+
}
28+
29+
spinner.stop()
30+
31+
if (!result.data.length) {
32+
logger.log('No analytics data is available for this organization yet.')
33+
return undefined
34+
}
35+
36+
return result.data
37+
}

0 commit comments

Comments
 (0)