From 56e81400681b829ef1b6929f1992b5045ab5dc5a Mon Sep 17 00:00:00 2001 From: Peter van der Zee Date: Thu, 20 Mar 2025 16:00:17 +0100 Subject: [PATCH] Apply handle pattern to dependencies --- src/commands/dependencies/cmd-dependencies.ts | 13 ++-- .../dependencies/fetch-dependencies.ts | 58 +++++++++++++++ .../dependencies/find-dependencies.ts | 73 ------------------- .../dependencies/handle-dependencies.ts | 17 +++++ .../dependencies/output-dependencies.ts | 59 +++++++++++++++ 5 files changed, 141 insertions(+), 79 deletions(-) create mode 100644 src/commands/dependencies/fetch-dependencies.ts delete mode 100644 src/commands/dependencies/find-dependencies.ts create mode 100644 src/commands/dependencies/handle-dependencies.ts create mode 100644 src/commands/dependencies/output-dependencies.ts diff --git a/src/commands/dependencies/cmd-dependencies.ts b/src/commands/dependencies/cmd-dependencies.ts index b1ff22ccc..88e664880 100644 --- a/src/commands/dependencies/cmd-dependencies.ts +++ b/src/commands/dependencies/cmd-dependencies.ts @@ -1,6 +1,6 @@ import { logger } from '@socketsecurity/registry/lib/logger' -import { findDependencies } from './find-dependencies' +import { handleDependencies } from './handle-dependencies' import constants from '../../constants' import { commonFlags, outputFlags } from '../../flags' import { meowOrExit } from '../../utils/meow-with-subcommands' @@ -61,15 +61,16 @@ async function run( parentName }) + const { json, limit, markdown, offset } = cli.flags + if (cli.flags['dryRun']) { logger.log(DRY_RUN_BAIL_TEXT) return } - // TODO: markdown flag is ignored - await findDependencies({ - limit: Number(cli.flags['limit'] || 0) || 0, - offset: Number(cli.flags['offset'] || 0) || 0, - outputJson: Boolean(cli.flags['json']) + await handleDependencies({ + limit: Number(limit || 0) || 0, + offset: Number(offset || 0) || 0, + outputKind: json ? 'json' : markdown ? 'markdown' : 'text' }) } diff --git a/src/commands/dependencies/fetch-dependencies.ts b/src/commands/dependencies/fetch-dependencies.ts new file mode 100644 index 000000000..d5f3d3475 --- /dev/null +++ b/src/commands/dependencies/fetch-dependencies.ts @@ -0,0 +1,58 @@ +import constants from '../../constants' +import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api' +import { AuthError } from '../../utils/errors' +import { getDefaultToken, setupSdk } from '../../utils/sdk' + +import type { SocketSdkReturnType } from '@socketsecurity/sdk' + +export async function fetchDependencies({ + limit, + offset +}: { + limit: number + offset: number +}): 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 fetchDependenciesWithToken(apiToken, { + limit, + offset + }) +} + +async function fetchDependenciesWithToken( + apiToken: string, + { + limit, + offset + }: { + limit: number + offset: number + } +): Promise['data'] | undefined> { + // Lazily access constants.spinner. + const { spinner } = constants + + spinner.start('Fetching organization dependencies...') + + const socketSdk = await setupSdk(apiToken) + + const result = await handleApiCall( + socketSdk.searchDependencies({ limit, offset }), + 'Searching dependencies' + ) + + spinner?.successAndStop('Received organization dependencies response.') + + if (!result.success) { + handleUnsuccessfulApiResponse('searchDependencies', result) + return + } + + return result.data +} diff --git a/src/commands/dependencies/find-dependencies.ts b/src/commands/dependencies/find-dependencies.ts deleted file mode 100644 index 1896ccff3..000000000 --- a/src/commands/dependencies/find-dependencies.ts +++ /dev/null @@ -1,73 +0,0 @@ -// @ts-ignore -import chalkTable from 'chalk-table' -import colors from 'yoctocolors-cjs' - -import { logger } from '@socketsecurity/registry/lib/logger' - -import constants from '../../constants' -import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api' -import { AuthError } from '../../utils/errors' -import { getDefaultToken, setupSdk } from '../../utils/sdk' - -export async function findDependencies({ - limit, - offset, - outputJson -}: { - outputJson: boolean - limit: number - offset: number -}): 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.' - ) - } - // Lazily access constants.spinner. - const { spinner } = constants - - spinner.start('Searching dependencies...') - - const socketSdk = await setupSdk(apiToken) - - const result = await handleApiCall( - socketSdk.searchDependencies({ limit, offset }), - 'Searching dependencies' - ) - - if (!result.success) { - handleUnsuccessfulApiResponse('searchDependencies', result) - return - } - - spinner.stop('Organization dependencies:') - - if (outputJson) { - logger.log(result.data) - return - } - - logger.log( - 'Request details: Offset:', - offset, - ', limit:', - limit, - ', is there more data after this?', - result.data.end ? 'no' : 'yes' - ) - - const options = { - columns: [ - { field: 'namespace', name: colors.cyan('Namespace') }, - { field: 'name', name: colors.cyan('Name') }, - { field: 'version', name: colors.cyan('Version') }, - { field: 'repository', name: colors.cyan('Repository') }, - { field: 'branch', name: colors.cyan('Branch') }, - { field: 'type', name: colors.cyan('Type') }, - { field: 'direct', name: colors.cyan('Direct') } - ] - } - - logger.log(chalkTable(options, result.data.rows)) -} diff --git a/src/commands/dependencies/handle-dependencies.ts b/src/commands/dependencies/handle-dependencies.ts new file mode 100644 index 000000000..4071b7d53 --- /dev/null +++ b/src/commands/dependencies/handle-dependencies.ts @@ -0,0 +1,17 @@ +import { fetchDependencies } from './fetch-dependencies' +import { outputDependencies } from './output-dependencies' + +export async function handleDependencies({ + limit, + offset, + outputKind +}: { + limit: number + offset: number + outputKind: 'json' | 'markdown' | 'text' +}): Promise { + const data = await fetchDependencies({ limit, offset }) + if (!data) return + + await outputDependencies(data, { limit, offset, outputKind }) +} diff --git a/src/commands/dependencies/output-dependencies.ts b/src/commands/dependencies/output-dependencies.ts new file mode 100644 index 000000000..e754a45d1 --- /dev/null +++ b/src/commands/dependencies/output-dependencies.ts @@ -0,0 +1,59 @@ +// @ts-ignore +import chalkTable from 'chalk-table' +import colors from 'yoctocolors-cjs' + +import { logger } from '@socketsecurity/registry/lib/logger' + +import type { SocketSdkReturnType } from '@socketsecurity/sdk' + +export async function outputDependencies( + data: SocketSdkReturnType<'searchDependencies'>['data'], + { + limit, + offset, + outputKind + }: { + limit: number + offset: number + outputKind: 'json' | 'markdown' | 'text' + } +): Promise { + if (outputKind === 'json') { + let json + try { + json = JSON.stringify(data, null, 2) + } catch (e) { + process.exitCode = 1 + logger.fail( + 'There was a problem converting the data to JSON, please try without the `--json` flag' + ) + return + } + + logger.log(json) + return + } + + logger.log( + 'Request details: Offset:', + offset, + ', limit:', + limit, + ', is there more data after this?', + data.end ? 'no' : 'yes' + ) + + const options = { + columns: [ + { field: 'namespace', name: colors.cyan('Namespace') }, + { field: 'name', name: colors.cyan('Name') }, + { field: 'version', name: colors.cyan('Version') }, + { field: 'repository', name: colors.cyan('Repository') }, + { field: 'branch', name: colors.cyan('Branch') }, + { field: 'type', name: colors.cyan('Type') }, + { field: 'direct', name: colors.cyan('Direct') } + ] + } + + logger.log(chalkTable(options, data.rows)) +}