diff --git a/src/commands/diff-scan/cmd-diff-scan-get.ts b/src/commands/diff-scan/cmd-diff-scan-get.ts index 75fe1138..c3ad6d44 100644 --- a/src/commands/diff-scan/cmd-diff-scan-get.ts +++ b/src/commands/diff-scan/cmd-diff-scan-get.ts @@ -2,7 +2,7 @@ import colors from 'yoctocolors-cjs' import { logger } from '@socketsecurity/registry/lib/logger' -import { getDiffScan } from './get-diff-scan' +import { handleDiffScan } from './handle-diff-scan' import constants from '../../constants' import { commonFlags } from '../../flags' import { meowOrExit } from '../../utils/meow-with-subcommands' @@ -85,8 +85,8 @@ async function run( parentName }) - const before = String(cli.flags['before'] || '') - const after = String(cli.flags['after'] || '') + const { after, before, depth, file, json, markdown } = cli.flags + const [orgSlug = ''] = cli.input if (!before || !after || cli.input.length < 1) { @@ -107,12 +107,12 @@ async function run( return } - await getDiffScan({ - outputJson: Boolean(cli.flags['json']), - before, - after, - depth: Number(cli.flags['depth']), + await handleDiffScan({ + before: String(before || ''), + after: String(after || ''), + depth: Number(depth), orgSlug, - file: String(cli.flags['file'] || '') + outputKind: json ? 'json' : markdown ? 'markdown' : 'text', + file: String(file || '') }) } diff --git a/src/commands/diff-scan/fetch-diff-scan.ts b/src/commands/diff-scan/fetch-diff-scan.ts new file mode 100644 index 00000000..fd725222 --- /dev/null +++ b/src/commands/diff-scan/fetch-diff-scan.ts @@ -0,0 +1,73 @@ +import colors from 'yoctocolors-cjs' + +import constants from '../../constants' +import { handleAPIError, handleApiCall, queryAPI } from '../../utils/api' +import { AuthError } from '../../utils/errors' +import { getDefaultToken } from '../../utils/sdk' + +import type { SocketSdkReturnType } from '@socketsecurity/sdk' + +export async function fetchDiffScan({ + after, + before, + orgSlug +}: { + after: string + before: string + orgSlug: string +}): Promise['data'] | undefined> { + const apiToken = getDefaultToken() + if (!apiToken) { + throw new AuthError( + 'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.' + ) + } + + return await fetchDiffScanWithToken(apiToken, { + after, + before, + orgSlug + }) +} + +export async function fetchDiffScanWithToken( + apiToken: string, + { + after, + before, + orgSlug + }: { + after: string + before: string + orgSlug: string + } +): Promise['data'] | undefined> { + // Lazily access constants.spinner. + const { spinner } = constants + + spinner.start('Fetching diff-scan...') + + const response = await queryAPI( + `orgs/${orgSlug}/full-scans/diff?before=${encodeURIComponent(before)}&after=${encodeURIComponent(after)}`, + apiToken + ) + + spinner?.successAndStop('Received diff-scan response') + + if (!response.ok) { + const err = await handleAPIError(response.status) + spinner.errorAndStop( + `${colors.bgRed(colors.white(response.statusText))}: ${err}` + ) + return + } + + const result = await handleApiCall( + (await response.json()) as Promise< + SocketSdkReturnType<'GetOrgDiffScan'>['data'] + >, + 'Deserializing json' + ) + + return result +} diff --git a/src/commands/diff-scan/handle-diff-scan.ts b/src/commands/diff-scan/handle-diff-scan.ts new file mode 100644 index 00000000..d017985f --- /dev/null +++ b/src/commands/diff-scan/handle-diff-scan.ts @@ -0,0 +1,31 @@ +import { fetchDiffScan } from './fetch-diff-scan' +import { outputDiffScan } from './output-diff-scan' + +export async function handleDiffScan({ + after, + before, + depth, + file, + orgSlug, + outputKind +}: { + after: string + before: string + depth: number + file: string + orgSlug: string + outputKind: 'json' | 'markdown' | 'text' +}): Promise { + const data = await fetchDiffScan({ + after, + before, + orgSlug + }) + if (!data) return + + await outputDiffScan(data, { + depth, + file, + outputKind + }) +} diff --git a/src/commands/diff-scan/get-diff-scan.ts b/src/commands/diff-scan/output-diff-scan.ts similarity index 53% rename from src/commands/diff-scan/get-diff-scan.ts rename to src/commands/diff-scan/output-diff-scan.ts index b64ba83c..08dd2cf5 100644 --- a/src/commands/diff-scan/get-diff-scan.ts +++ b/src/commands/diff-scan/output-diff-scan.ts @@ -5,90 +5,21 @@ import colors from 'yoctocolors-cjs' import { logger } from '@socketsecurity/registry/lib/logger' -import constants from '../../constants' -import { handleAPIError, handleApiCall, queryAPI } from '../../utils/api' -import { AuthError } from '../../utils/errors' -import { getDefaultToken } from '../../utils/sdk' - import type { SocketSdkReturnType } from '@socketsecurity/sdk' -export async function getDiffScan({ - after, - before, - depth, - file, - orgSlug, - outputJson -}: { - after: string - before: string - depth: number - file: string - orgSlug: string - outputJson: boolean -}): Promise { - const apiToken = getDefaultToken() - if (!apiToken) { - throw new AuthError( - 'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.' - ) - } - - await getDiffScanWithToken({ - after, - before, +export async function outputDiffScan( + result: SocketSdkReturnType<'GetOrgDiffScan'>['data'], + { depth, file, - orgSlug, - outputJson, - apiToken - }) -} -export async function getDiffScanWithToken({ - after, - apiToken, - before, - depth, - file, - orgSlug, - outputJson -}: { - after: string - apiToken: string - depth: number - before: string - file: string - orgSlug: string - outputJson: boolean -}): Promise { - // Lazily access constants.spinner. - const { spinner } = constants - - spinner.start('Getting diff scan...') - - const response = await queryAPI( - `orgs/${orgSlug}/full-scans/diff?before=${encodeURIComponent(before)}&after=${encodeURIComponent(after)}`, - apiToken - ) - - if (!response.ok) { - const err = await handleAPIError(response.status) - spinner.errorAndStop( - `${colors.bgRed(colors.white(response.statusText))}: ${err}` - ) - return + outputKind + }: { + depth: number + file: string + outputKind: 'json' | 'markdown' | 'text' } - - const result = await handleApiCall( - (await response.json()) as Promise< - SocketSdkReturnType<'GetOrgDiffScan'>['data'] - >, - 'Deserializing json' - ) - - spinner.stop() - - const dashboardUrl = (result as any)?.['diff_report_url'] +): Promise { + const dashboardUrl = result.diff_report_url const dashboardMessage = dashboardUrl ? `\n View this diff scan in the Socket dashboard: ${colors.cyan(dashboardUrl)}` : '' @@ -96,7 +27,7 @@ export async function getDiffScanWithToken({ // When forcing json, or dumping to file, serialize to string such that it // won't get truncated. The only way to dump the full raw JSON to stdout is // to use `--json --file -` (the dash is a standard notation for stdout) - if (outputJson || file) { + if (outputKind === 'json' || file) { let json try { json = JSON.stringify(result, null, 2)