From e10f4cbffea9fb14f88041a92336325d7ad1ecd6 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Thu, 6 Jun 2024 15:27:51 -0700 Subject: [PATCH 01/21] [wip] add full scans --- cli.js | 2 + lib/commands/fullscans/create.js | 110 ++++++++++++++++++++++++++++ lib/commands/fullscans/delete.js | 119 +++++++++++++++++++++++++++++++ lib/commands/fullscans/index.js | 28 ++++++++ lib/commands/fullscans/list.js | 115 +++++++++++++++++++++++++++++ lib/commands/fullscans/stream.js | 119 +++++++++++++++++++++++++++++++ lib/commands/index.js | 1 + 7 files changed, 494 insertions(+) create mode 100644 lib/commands/fullscans/create.js create mode 100644 lib/commands/fullscans/delete.js create mode 100644 lib/commands/fullscans/index.js create mode 100644 lib/commands/fullscans/list.js create mode 100644 lib/commands/fullscans/stream.js diff --git a/cli.js b/cli.js index 55c3728f..a57340c0 100755 --- a/cli.js +++ b/cli.js @@ -20,6 +20,8 @@ try { entry[0] = 'raw-npm' } else if (entry[0] === 'rawNpx') { entry[0] = 'raw-npx' + } else if (entry[0] === 'fullscans') { + entry[0] = 'full-scans' } return entry })) diff --git a/lib/commands/fullscans/create.js b/lib/commands/fullscans/create.js new file mode 100644 index 00000000..abeb7373 --- /dev/null +++ b/lib/commands/fullscans/create.js @@ -0,0 +1,110 @@ +// @ts-nocheck +/* eslint-disable no-console */ + +import meow from 'meow' +import ora from 'ora' + +import { outputFlags, validationFlags } from '../../flags/index.js' +import { handleApiCall } from '../../utils/api-helpers.js' +import { printFlagList } from '../../utils/formatting.js' +import { getDefaultKey, setupSdk } from '../../utils/sdk.js' + +/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +export const create = { + description: 'Create a full scan', + async run (argv, importMeta, { parentName }) { + const name = parentName + ' create' + + const input = setupCommand(name, create.description, argv, importMeta) + if (input) { + const spinnerText = 'Creating a full scan...' + const spinner = ora(spinnerText).start() + await createFullScan(spinner) + } + } +} + +// Internal functions + +/** + * @typedef CommandContext + * @property {boolean} includeAllIssues + * @property {boolean} outputJson + * @property {boolean} outputMarkdown + * @property {boolean} strict + */ + +/** + * @param {string} name + * @param {string} description + * @param {readonly string[]} argv + * @param {ImportMeta} importMeta + * @returns {void|CommandContext} + */ +function setupCommand (name, description, argv, importMeta) { + const flags = { + ...outputFlags, + ...validationFlags, + } + + const cli = meow(` + Usage + $ ${name} + + Options + ${printFlagList(flags, 6)} + + Examples + $ ${name} webtorrent + $ ${name} webtorrent@1.9.1 + `, { + argv, + description, + importMeta, + flags + }) + + const { + all: includeAllIssues, + json: outputJson, + markdown: outputMarkdown, + strict, + } = cli.flags + + return { + includeAllIssues, + outputJson, + outputMarkdown, + strict, + } +} + +/** + * @typedef PackageData + * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'createOrgFullScan'>["data"]} data + */ + +/** + * @param {import('ora').Ora} spinner + * @returns {Promise} + */ +async function createFullScan (spinner) { + const socketSdk = await setupSdk(getDefaultKey()) + const result = await handleApiCall(socketSdk.createOrgFullScan('SocketDev', { + repo: 'socket-cli-js', + branch: 'master', + make_default_branch: true, + set_as_pending_head: false, + tmp: true + }, ['package.json']), 'Creating full scan') + + console.log(result) + +// console.log('RES: ', result.data) + + spinner.stop() + + return { + data: result.data + } +} diff --git a/lib/commands/fullscans/delete.js b/lib/commands/fullscans/delete.js new file mode 100644 index 00000000..f89ac88f --- /dev/null +++ b/lib/commands/fullscans/delete.js @@ -0,0 +1,119 @@ +// @ts-nocheck +/* eslint-disable no-console */ + +import meow from 'meow' +import ora from 'ora' + +import { outputFlags, validationFlags } from '../../flags/index.js' +import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' +import { InputError } from '../../utils/errors.js' +import { printFlagList } from '../../utils/formatting.js' +import { getDefaultKey, setupSdk } from '../../utils/sdk.js' + +/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +export const deleteFullScan = { + description: 'Delete a full scan', + async run (argv, importMeta, { parentName }) { + const name = parentName + ' delete' + + const input = setupCommand(name, deleteFullScan.description, argv, importMeta) + if (input) { + const spinnerText = 'Deleting full scan...' + const spinner = ora(spinnerText).start() + await deleteOrgFullScan(input.orgSlug, input.fullScanId, spinner) + } + } +} + +// Internal functions + +/** + * @typedef CommandContext + * @property {boolean} includeAllIssues + * @property {boolean} outputJson + * @property {boolean} outputMarkdown + * @property {boolean} strict + * @property {string} orgSlug + * @property {string} fullScanId + */ + +/** + * @param {string} name + * @param {string} description + * @param {readonly string[]} argv + * @param {ImportMeta} importMeta + * @returns {void|CommandContext} + */ +function setupCommand (name, description, argv, importMeta) { + const flags = { + ...outputFlags, + ...validationFlags, + } + + const cli = meow(` + Usage + $ ${name} + + Options + ${printFlagList(flags, 6)} + + Examples + $ ${name} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 + `, { + argv, + description, + importMeta, + flags + }) + + const { + all: includeAllIssues, + json: outputJson, + markdown: outputMarkdown, + strict, + } = cli.flags + + if (cli.input.length < 2) { + throw new InputError('Please specify an organization slug and a full scan ID.') + } + + const orgSlug = cli.input[0] || '' + const fullScanId = cli.input[1] || '' + + return { + includeAllIssues, + outputJson, + outputMarkdown, + strict, + orgSlug, + fullScanId + } +} + +/** + * @typedef PackageData + * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'deleteOrgFullScan'>["data"]} data + */ + +/** + * @param {string} orgSlug + * @param {string} fullScanId + * @param {import('ora').Ora} spinner + * @returns {Promise} + */ +async function deleteOrgFullScan (orgSlug, fullScanId, spinner) { + const socketSdk = await setupSdk(getDefaultKey()) + const result = await handleApiCall(socketSdk.deleteOrgFullScan(orgSlug, fullScanId), 'Deleting full scan') + + console.log(result) + + if (!result.success) { + return handleUnsuccessfulApiResponse('deleteOrgFullScan', result, spinner) + } + + spinner.stop() + + return { + data: result.data + } +} diff --git a/lib/commands/fullscans/index.js b/lib/commands/fullscans/index.js new file mode 100644 index 00000000..ddfcb1d6 --- /dev/null +++ b/lib/commands/fullscans/index.js @@ -0,0 +1,28 @@ +import { create } from './create.js' +import { deleteFullScan } from './delete.js' +import { list } from './list.js' +import { stream } from './stream.js' +import { meowWithSubcommands } from '../../utils/meow-with-subcommands.js' + +const description = 'Full scans related commands' + +/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +export const fullscans = { + description, + run: async (argv, importMeta, { parentName }) => { + await meowWithSubcommands( + { + create, + stream, + list, + deleteFullScan + }, + { + argv, + description, + importMeta, + name: parentName + ' full-scans', + } + ) + } +} diff --git a/lib/commands/fullscans/list.js b/lib/commands/fullscans/list.js new file mode 100644 index 00000000..9dd79b89 --- /dev/null +++ b/lib/commands/fullscans/list.js @@ -0,0 +1,115 @@ +// @ts-nocheck +/* eslint-disable no-console */ + +import meow from 'meow' +import ora from 'ora' + +import { outputFlags, validationFlags } from '../../flags/index.js' +import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' +import { InputError } from '../../utils/errors.js' +import { printFlagList } from '../../utils/formatting.js' +import { getDefaultKey, setupSdk } from '../../utils/sdk.js' + +/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +export const list = { + description: 'List full scans', + async run (argv, importMeta, { parentName }) { + const name = parentName + ' list' + + const input = setupCommand(name, list.description, argv, importMeta) + if (input) { + const spinnerText = 'Listinga full scan...' + const spinner = ora(spinnerText).start() + await listOrgFullScan(input.orgSlug, spinner) + } + } +} + +// Internal functions + +/** + * @typedef CommandContext + * @property {boolean} includeAllIssues + * @property {boolean} outputJson + * @property {boolean} outputMarkdown + * @property {boolean} strict + * @property {string} orgSlug + */ + +/** + * @param {string} name + * @param {string} description + * @param {readonly string[]} argv + * @param {ImportMeta} importMeta + * @returns {void|CommandContext} + */ +function setupCommand (name, description, argv, importMeta) { + const flags = { + ...outputFlags, + ...validationFlags, + } + + const cli = meow(` + Usage + $ ${name} + + Options + ${printFlagList(flags, 6)} + + Examples + $ ${name} FakeOrg + `, { + argv, + description, + importMeta, + flags + }) + + const { + all: includeAllIssues, + json: outputJson, + markdown: outputMarkdown, + strict, + } = cli.flags + + if (cli.input.length < 1) { + throw new InputError('Please specify an organization slug.') + } + + const orgSlug = cli.input[0] || '' + + return { + includeAllIssues, + outputJson, + outputMarkdown, + strict, + orgSlug + } +} + +/** + * @typedef PackageData + * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'listOrgFullScan'>["data"]} data + */ + +/** + * @param {string} orgSlug + * @param {import('ora').Ora} spinner + * @returns {Promise} + */ +async function listOrgFullScan (orgSlug, spinner) { + const socketSdk = await setupSdk(getDefaultKey()) + const result = await handleApiCall(socketSdk.listOrgFullScan(orgSlug), 'Deleting full scan') + + console.log(result) + + if (!result.success) { + return handleUnsuccessfulApiResponse('listOrgFullScan', result, spinner) + } + + spinner.stop() + + return { + data: result.data + } +} diff --git a/lib/commands/fullscans/stream.js b/lib/commands/fullscans/stream.js new file mode 100644 index 00000000..69d540df --- /dev/null +++ b/lib/commands/fullscans/stream.js @@ -0,0 +1,119 @@ +// @ts-nocheck +/* eslint-disable no-console */ + +import meow from 'meow' +import ora from 'ora' + +import { outputFlags, validationFlags } from '../../flags/index.js' +import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' +import { InputError } from '../../utils/errors.js' +import { printFlagList } from '../../utils/formatting.js' +import { getDefaultKey, setupSdk } from '../../utils/sdk.js' + +/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +export const stream = { + description: 'Stream a full scan', + async run (argv, importMeta, { parentName }) { + const name = parentName + ' stream' + + const input = setupCommand(name, stream.description, argv, importMeta) + if (input) { + const spinnerText = 'Streaming full scan...' + const spinner = ora(spinnerText).start() + await getOrgFullScan(input.orgSlug, input.fullScanId, spinner) + } + } +} + +// Internal functions + +/** + * @typedef CommandContext + * @property {boolean} includeAllIssues + * @property {boolean} outputJson + * @property {boolean} outputMarkdown + * @property {boolean} strict + * @property {string} orgSlug + * @property {string} fullScanId + */ + +/** + * @param {string} name + * @param {string} description + * @param {readonly string[]} argv + * @param {ImportMeta} importMeta + * @returns {void|CommandContext} + */ +function setupCommand (name, description, argv, importMeta) { + const flags = { + ...outputFlags, + ...validationFlags, + } + + const cli = meow(` + Usage + $ ${name} + + Options + ${printFlagList(flags, 6)} + + Examples + $ ${name} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 + `, { + argv, + description, + importMeta, + flags + }) + + const { + all: includeAllIssues, + json: outputJson, + markdown: outputMarkdown, + strict, + } = cli.flags + + if (cli.input.length < 1) { + throw new InputError('Please specify an organization slug and a full scan ID.') + } + + const orgSlug = cli.input[0] || '' + const fullScanId = cli.input[1] || '' + + return { + includeAllIssues, + outputJson, + outputMarkdown, + strict, + orgSlug, + fullScanId + } +} + +/** + * @typedef PackageData + * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'getOrgFullScan'>["data"]} data + */ + +/** + * @param {string} orgSlug + * @param {string} fullScanId + * @param {import('ora').Ora} spinner + * @returns {Promise} + */ +async function getOrgFullScan (orgSlug, fullScanId, spinner) { + const socketSdk = await setupSdk(getDefaultKey()) + const result = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId), 'Streaming a full scan') + + console.log(result) + + if (!result.success) { + return handleUnsuccessfulApiResponse('getOrgFullScan', result, spinner) + } + + spinner.stop() + + return { + data: result.data + } +} diff --git a/lib/commands/index.js b/lib/commands/index.js index adb86163..495120b0 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -8,3 +8,4 @@ export * from './raw-npm/index.js' export * from './raw-npx/index.js' export * from './report/index.js' export * from './wrapper/index.js' +export * from './fullscans/index.js' From 0a6f43280ec01a7f7a3c18a7e6f1da32540e7242 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 10 Jun 2024 13:23:10 -0700 Subject: [PATCH 02/21] wip --- lib/commands/fullscans/create.js | 34 ++++++++++++-------------------- lib/commands/fullscans/delete.js | 22 +++++++-------------- lib/commands/fullscans/index.js | 4 ++-- lib/commands/fullscans/list.js | 29 +++++++++++---------------- lib/commands/fullscans/stream.js | 18 +++++------------ 5 files changed, 38 insertions(+), 69 deletions(-) diff --git a/lib/commands/fullscans/create.js b/lib/commands/fullscans/create.js index abeb7373..fef4b4eb 100644 --- a/lib/commands/fullscans/create.js +++ b/lib/commands/fullscans/create.js @@ -1,11 +1,10 @@ -// @ts-nocheck /* eslint-disable no-console */ import meow from 'meow' import ora from 'ora' -import { outputFlags, validationFlags } from '../../flags/index.js' -import { handleApiCall } from '../../utils/api-helpers.js' +import { outputFlags } from '../../flags/index.js' +import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' @@ -28,10 +27,8 @@ export const create = { /** * @typedef CommandContext - * @property {boolean} includeAllIssues * @property {boolean} outputJson * @property {boolean} outputMarkdown - * @property {boolean} strict */ /** @@ -43,20 +40,15 @@ export const create = { */ function setupCommand (name, description, argv, importMeta) { const flags = { - ...outputFlags, - ...validationFlags, + ...outputFlags } const cli = meow(` Usage - $ ${name} + $ ${name} Options ${printFlagList(flags, 6)} - - Examples - $ ${name} webtorrent - $ ${name} webtorrent@1.9.1 `, { argv, description, @@ -65,23 +57,19 @@ function setupCommand (name, description, argv, importMeta) { }) const { - all: includeAllIssues, json: outputJson, - markdown: outputMarkdown, - strict, + markdown: outputMarkdown } = cli.flags return { - includeAllIssues, outputJson, - outputMarkdown, - strict, + outputMarkdown } } /** * @typedef PackageData - * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'createOrgFullScan'>["data"]} data + * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'CreateOrgFullScan'>["data"]} data */ /** @@ -98,9 +86,13 @@ async function createFullScan (spinner) { tmp: true }, ['package.json']), 'Creating full scan') - console.log(result) + if (!result.success) { + return handleUnsuccessfulApiResponse('CreateOrgFullScan', result, spinner) + } -// console.log('RES: ', result.data) + console.log('\n Full scan created successfully \n') + console.log('Full scan details: \n') + console.log(result.data) spinner.stop() diff --git a/lib/commands/fullscans/delete.js b/lib/commands/fullscans/delete.js index f89ac88f..614b6a23 100644 --- a/lib/commands/fullscans/delete.js +++ b/lib/commands/fullscans/delete.js @@ -1,22 +1,21 @@ -// @ts-nocheck /* eslint-disable no-console */ import meow from 'meow' import ora from 'ora' -import { outputFlags, validationFlags } from '../../flags/index.js' +import { outputFlags } from '../../flags/index.js' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' import { InputError } from '../../utils/errors.js' import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ -export const deleteFullScan = { +export const del = { description: 'Delete a full scan', async run (argv, importMeta, { parentName }) { - const name = parentName + ' delete' + const name = parentName + ' del' - const input = setupCommand(name, deleteFullScan.description, argv, importMeta) + const input = setupCommand(name, del.description, argv, importMeta) if (input) { const spinnerText = 'Deleting full scan...' const spinner = ora(spinnerText).start() @@ -29,10 +28,8 @@ export const deleteFullScan = { /** * @typedef CommandContext - * @property {boolean} includeAllIssues * @property {boolean} outputJson * @property {boolean} outputMarkdown - * @property {boolean} strict * @property {string} orgSlug * @property {string} fullScanId */ @@ -46,8 +43,7 @@ export const deleteFullScan = { */ function setupCommand (name, description, argv, importMeta) { const flags = { - ...outputFlags, - ...validationFlags, + ...outputFlags } const cli = meow(` @@ -67,10 +63,8 @@ function setupCommand (name, description, argv, importMeta) { }) const { - all: includeAllIssues, json: outputJson, markdown: outputMarkdown, - strict, } = cli.flags if (cli.input.length < 2) { @@ -81,10 +75,8 @@ function setupCommand (name, description, argv, importMeta) { const fullScanId = cli.input[1] || '' return { - includeAllIssues, outputJson, outputMarkdown, - strict, orgSlug, fullScanId } @@ -105,12 +97,12 @@ async function deleteOrgFullScan (orgSlug, fullScanId, spinner) { const socketSdk = await setupSdk(getDefaultKey()) const result = await handleApiCall(socketSdk.deleteOrgFullScan(orgSlug, fullScanId), 'Deleting full scan') - console.log(result) - if (!result.success) { return handleUnsuccessfulApiResponse('deleteOrgFullScan', result, spinner) } + console.log('\n Full scan deleted successfully. \n') + spinner.stop() return { diff --git a/lib/commands/fullscans/index.js b/lib/commands/fullscans/index.js index ddfcb1d6..60921ed4 100644 --- a/lib/commands/fullscans/index.js +++ b/lib/commands/fullscans/index.js @@ -1,5 +1,5 @@ import { create } from './create.js' -import { deleteFullScan } from './delete.js' +import { del } from './delete.js' import { list } from './list.js' import { stream } from './stream.js' import { meowWithSubcommands } from '../../utils/meow-with-subcommands.js' @@ -15,7 +15,7 @@ export const fullscans = { create, stream, list, - deleteFullScan + del }, { argv, diff --git a/lib/commands/fullscans/list.js b/lib/commands/fullscans/list.js index 9dd79b89..24161f8f 100644 --- a/lib/commands/fullscans/list.js +++ b/lib/commands/fullscans/list.js @@ -1,10 +1,9 @@ -// @ts-nocheck /* eslint-disable no-console */ import meow from 'meow' import ora from 'ora' -import { outputFlags, validationFlags } from '../../flags/index.js' +import { outputFlags } from '../../flags/index.js' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' import { InputError } from '../../utils/errors.js' import { printFlagList } from '../../utils/formatting.js' @@ -18,7 +17,7 @@ export const list = { const input = setupCommand(name, list.description, argv, importMeta) if (input) { - const spinnerText = 'Listinga full scan...' + const spinnerText = 'Listing full scans...' const spinner = ora(spinnerText).start() await listOrgFullScan(input.orgSlug, spinner) } @@ -29,10 +28,8 @@ export const list = { /** * @typedef CommandContext - * @property {boolean} includeAllIssues * @property {boolean} outputJson * @property {boolean} outputMarkdown - * @property {boolean} strict * @property {string} orgSlug */ @@ -45,8 +42,7 @@ export const list = { */ function setupCommand (name, description, argv, importMeta) { const flags = { - ...outputFlags, - ...validationFlags, + ...outputFlags } const cli = meow(` @@ -66,30 +62,26 @@ function setupCommand (name, description, argv, importMeta) { }) const { - all: includeAllIssues, json: outputJson, - markdown: outputMarkdown, - strict, + markdown: outputMarkdown } = cli.flags - if (cli.input.length < 1) { + if (!cli.input[0]) { throw new InputError('Please specify an organization slug.') } const orgSlug = cli.input[0] || '' return { - includeAllIssues, outputJson, outputMarkdown, - strict, orgSlug } } /** * @typedef PackageData - * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'listOrgFullScan'>["data"]} data + * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'getOrgFullScanList'>["data"]} data */ /** @@ -99,14 +91,15 @@ function setupCommand (name, description, argv, importMeta) { */ async function listOrgFullScan (orgSlug, spinner) { const socketSdk = await setupSdk(getDefaultKey()) - const result = await handleApiCall(socketSdk.listOrgFullScan(orgSlug), 'Deleting full scan') - - console.log(result) + const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug), 'Listing full scans') if (!result.success) { - return handleUnsuccessfulApiResponse('listOrgFullScan', result, spinner) + return handleUnsuccessfulApiResponse('getOrgFullScanList', result, spinner) } + console.log(`\n Full scans for ${orgSlug}: \n`) + result.data.results.map(scan => console.log(scan)) + spinner.stop() return { diff --git a/lib/commands/fullscans/stream.js b/lib/commands/fullscans/stream.js index 69d540df..256ca42f 100644 --- a/lib/commands/fullscans/stream.js +++ b/lib/commands/fullscans/stream.js @@ -1,10 +1,9 @@ -// @ts-nocheck /* eslint-disable no-console */ import meow from 'meow' import ora from 'ora' -import { outputFlags, validationFlags } from '../../flags/index.js' +import { outputFlags } from '../../flags/index.js' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' import { InputError } from '../../utils/errors.js' import { printFlagList } from '../../utils/formatting.js' @@ -29,10 +28,8 @@ export const stream = { /** * @typedef CommandContext - * @property {boolean} includeAllIssues * @property {boolean} outputJson * @property {boolean} outputMarkdown - * @property {boolean} strict * @property {string} orgSlug * @property {string} fullScanId */ @@ -46,8 +43,7 @@ export const stream = { */ function setupCommand (name, description, argv, importMeta) { const flags = { - ...outputFlags, - ...validationFlags, + ...outputFlags } const cli = meow(` @@ -67,13 +63,11 @@ function setupCommand (name, description, argv, importMeta) { }) const { - all: includeAllIssues, json: outputJson, markdown: outputMarkdown, - strict, } = cli.flags - if (cli.input.length < 1) { + if (cli.input.length < 2) { throw new InputError('Please specify an organization slug and a full scan ID.') } @@ -81,10 +75,8 @@ function setupCommand (name, description, argv, importMeta) { const fullScanId = cli.input[1] || '' return { - includeAllIssues, outputJson, outputMarkdown, - strict, orgSlug, fullScanId } @@ -105,12 +97,12 @@ async function getOrgFullScan (orgSlug, fullScanId, spinner) { const socketSdk = await setupSdk(getDefaultKey()) const result = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId), 'Streaming a full scan') - console.log(result) - if (!result.success) { return handleUnsuccessfulApiResponse('getOrgFullScan', result, spinner) } + console.log('\n Full scan details: \n') + spinner.stop() return { From e63f8855bc8596c3f77876ec38c32c4f93481b76 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 10 Jun 2024 14:46:59 -0700 Subject: [PATCH 03/21] wip --- lib/commands/fullscans/create.js | 156 ++++++++++++++++++++++++++----- lib/commands/fullscans/delete.js | 4 +- lib/commands/fullscans/list.js | 4 +- lib/commands/fullscans/stream.js | 4 +- lib/utils/path-resolve.js | 29 ++++++ 5 files changed, 167 insertions(+), 30 deletions(-) diff --git a/lib/commands/fullscans/create.js b/lib/commands/fullscans/create.js index fef4b4eb..562efa73 100644 --- a/lib/commands/fullscans/create.js +++ b/lib/commands/fullscans/create.js @@ -1,11 +1,16 @@ /* eslint-disable no-console */ +import chalk from 'chalk' import meow from 'meow' import ora from 'ora' +import { ErrorWithCause } from 'pony-cause' -import { outputFlags } from '../../flags/index.js' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' +import { InputError } from '../../utils/errors.js' +import { prepareFlags } from '../../utils/flags.js' import { printFlagList } from '../../utils/formatting.js' +import { createDebugLogger } from '../../utils/misc.js' +import { getPackageFilesFullScans } from '../../utils/path-resolve.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ @@ -14,21 +19,73 @@ export const create = { async run (argv, importMeta, { parentName }) { const name = parentName + ' create' - const input = setupCommand(name, create.description, argv, importMeta) + const input = await setupCommand(name, create.description, argv, importMeta) if (input) { const spinnerText = 'Creating a full scan...' const spinner = ora(spinnerText).start() - await createFullScan(spinner) + + await createFullScan(input, spinner) } } } +const createFullScanFlags = prepareFlags({ + org: { + type: 'string', + shortFlag: 'o', + default: '', + description: 'Organization slug', + }, + repo: { + type: 'string', + shortFlag: 'r', + default: '', + description: 'Repository name', + }, + commitMessage: { + type: 'string', + shortFlag: 'm', + default: '', + description: 'Commit message', + }, + branch: { + type: 'string', + shortFlag: 'b', + default: '', + description: 'Branch name', + }, + defaultBranch: { + type: 'boolean', + shortFlag: 'db', + default: false, + description: 'Make default branch', + }, + pendingHead: { + type: 'boolean', + shortFlag: 'ph', + default: false, + description: 'Set as pending head', + }, + tmp: { + type: 'boolean', + shortFlag: 't', + default: false, + description: 'Set the visibility (true/false) of the full scan in your dashboard', + } +}) + // Internal functions /** * @typedef CommandContext - * @property {boolean} outputJson - * @property {boolean} outputMarkdown + * @property {string} orgSlug + * @property {string} repoName + * @property {string} branchName + * @property {string} commitMessage + * @property {boolean} defaultBranch + * @property {boolean} pendingHead + * @property {boolean} tmp + * @property {string[]} packagePaths */ /** @@ -36,11 +93,11 @@ export const create = { * @param {string} description * @param {readonly string[]} argv * @param {ImportMeta} importMeta - * @returns {void|CommandContext} + * @returns {Promise} */ -function setupCommand (name, description, argv, importMeta) { +async function setupCommand (name, description, argv, importMeta) { const flags = { - ...outputFlags + ...createFullScanFlags } const cli = meow(` @@ -57,42 +114,93 @@ function setupCommand (name, description, argv, importMeta) { }) const { - json: outputJson, - markdown: outputMarkdown + org: orgSlug, + repo: repoName, + branch: branchName, + commitMessage, + defaultBranch, + pendingHead, + tmp } = cli.flags + if (!orgSlug) { + throw new InputError('Please provide an organization slug') + } + + if (!repoName) { + throw new InputError('Please provide a repository name') + } + + if (!cli.input[0]) { + cli.showHelp() + return + } + + const cwd = process.cwd() + const socketSdk = await setupSdk() + const supportedFiles = await socketSdk.getReportSupportedFiles() + .then(res => { + if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res, ora()) + return res.data + }).catch( + /** @type {(cause: Error) => never} */ + (cause) => { + throw new ErrorWithCause('Failed getting supported files for report', { cause }) + }) + const debugLog = createDebugLogger(false) + const packagePaths = await getPackageFilesFullScans(cwd, cli.input, supportedFiles, debugLog) + return { - outputJson, - outputMarkdown + orgSlug, + repoName, + branchName, + commitMessage, + defaultBranch, + pendingHead, + tmp, + packagePaths } } /** - * @typedef PackageData + * @typedef FullScanData * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'CreateOrgFullScan'>["data"]} data */ /** + * @param {CommandContext} input * @param {import('ora').Ora} spinner - * @returns {Promise} + * @returns {Promise} */ -async function createFullScan (spinner) { +async function createFullScan (input, spinner) { const socketSdk = await setupSdk(getDefaultKey()) - const result = await handleApiCall(socketSdk.createOrgFullScan('SocketDev', { - repo: 'socket-cli-js', - branch: 'master', - make_default_branch: true, - set_as_pending_head: false, - tmp: true - }, ['package.json']), 'Creating full scan') + const { + orgSlug, + repoName, + branchName, + commitMessage, + defaultBranch, + pendingHead, + tmp, + packagePaths + } = input + + const result = await handleApiCall(socketSdk.createOrgFullScan(orgSlug, { + repo: repoName, + branch: branchName, + commit_message: commitMessage, + make_default_branch: defaultBranch, + set_as_pending_head: pendingHead, + tmp + }, packagePaths), 'Creating full scan') if (!result.success) { return handleUnsuccessfulApiResponse('CreateOrgFullScan', result, spinner) } console.log('\n Full scan created successfully \n') - console.log('Full scan details: \n') - console.log(result.data) + const link = chalk.hex('#FF08E8').underline(`${result.data.html_report_url}`) + console.log(`Check it out at ${link} \n`) spinner.stop() diff --git a/lib/commands/fullscans/delete.js b/lib/commands/fullscans/delete.js index 614b6a23..bc0cf9a0 100644 --- a/lib/commands/fullscans/delete.js +++ b/lib/commands/fullscans/delete.js @@ -83,7 +83,7 @@ function setupCommand (name, description, argv, importMeta) { } /** - * @typedef PackageData + * @typedef FullScanData * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'deleteOrgFullScan'>["data"]} data */ @@ -91,7 +91,7 @@ function setupCommand (name, description, argv, importMeta) { * @param {string} orgSlug * @param {string} fullScanId * @param {import('ora').Ora} spinner - * @returns {Promise} + * @returns {Promise} */ async function deleteOrgFullScan (orgSlug, fullScanId, spinner) { const socketSdk = await setupSdk(getDefaultKey()) diff --git a/lib/commands/fullscans/list.js b/lib/commands/fullscans/list.js index 24161f8f..f9cc01f3 100644 --- a/lib/commands/fullscans/list.js +++ b/lib/commands/fullscans/list.js @@ -80,14 +80,14 @@ function setupCommand (name, description, argv, importMeta) { } /** - * @typedef PackageData + * @typedef FullScansData * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'getOrgFullScanList'>["data"]} data */ /** * @param {string} orgSlug * @param {import('ora').Ora} spinner - * @returns {Promise} + * @returns {Promise} */ async function listOrgFullScan (orgSlug, spinner) { const socketSdk = await setupSdk(getDefaultKey()) diff --git a/lib/commands/fullscans/stream.js b/lib/commands/fullscans/stream.js index 256ca42f..82a978c5 100644 --- a/lib/commands/fullscans/stream.js +++ b/lib/commands/fullscans/stream.js @@ -83,7 +83,7 @@ function setupCommand (name, description, argv, importMeta) { } /** - * @typedef PackageData + * @typedef FullScanData * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'getOrgFullScan'>["data"]} data */ @@ -91,7 +91,7 @@ function setupCommand (name, description, argv, importMeta) { * @param {string} orgSlug * @param {string} fullScanId * @param {import('ora').Ora} spinner - * @returns {Promise} + * @returns {Promise} */ async function getOrgFullScan (orgSlug, fullScanId, spinner) { const socketSdk = await setupSdk(getDefaultKey()) diff --git a/lib/utils/path-resolve.js b/lib/utils/path-resolve.js index e91684a8..5e64c613 100644 --- a/lib/utils/path-resolve.js +++ b/lib/utils/path-resolve.js @@ -65,6 +65,35 @@ export async function getPackageFiles (cwd, inputPaths, config, supportedFiles, return includedPackageFiles } +/** + * Resolves package.json and lockfiles from (globbed) input paths, applying relevant ignores + * + * @param {string} cwd The working directory to use when resolving paths + * @param {string[]} inputPaths A list of paths to folders, package.json files and/or recognized lockfiles. Supports globs. + * @param {import('@socketsecurity/sdk').SocketSdkReturnType<"getReportSupportedFiles">['data']} supportedFiles + * @param {typeof console.error} debugLog + * @returns {Promise} + * @throws {InputError} + */ +export async function getPackageFilesFullScans (cwd, inputPaths, supportedFiles, debugLog) { + debugLog(`Globbed resolving ${inputPaths.length} paths:`, inputPaths) + + // TODO: Does not support `~/` paths + const entries = await globby(inputPaths, { + ...BASE_GLOBBY_OPTS, + cwd, + onlyFiles: false + }) + + debugLog(`Globbed resolved ${inputPaths.length} paths to ${entries.length} paths:`, entries) + + const packageFiles = await mapGlobResultToFiles(entries, supportedFiles) + + debugLog(`Mapped ${entries.length} entries to ${packageFiles.length} files:`, packageFiles) + + return packageFiles +} + /** * Takes paths to folders, package.json and/or recognized lock files and resolves them to package.json + lockfile pairs (where possible) * @param {string[]} entries From 22bf8642b67e951c5714be5c14a1573e37b3af7f Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Tue, 11 Jun 2024 11:16:16 -0700 Subject: [PATCH 04/21] Add prompt to open new full scan in browser --- lib/commands/fullscans/create.js | 21 ++++++++++++++++----- lib/commands/fullscans/delete.js | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/commands/fullscans/create.js b/lib/commands/fullscans/create.js index 562efa73..f8e83ac9 100644 --- a/lib/commands/fullscans/create.js +++ b/lib/commands/fullscans/create.js @@ -1,7 +1,11 @@ /* eslint-disable no-console */ +import { stdin as inputText, stdout as output } from 'node:process' +import * as readline from 'node:readline/promises' + import chalk from 'chalk' import meow from 'meow' +import open from 'open' import ora from 'ora' import { ErrorWithCause } from 'pony-cause' @@ -21,7 +25,7 @@ export const create = { const input = await setupCommand(name, create.description, argv, importMeta) if (input) { - const spinnerText = 'Creating a full scan...' + const spinnerText = 'Creating a full scan... \n' const spinner = ora(spinnerText).start() await createFullScan(input, spinner) @@ -197,12 +201,19 @@ async function createFullScan (input, spinner) { if (!result.success) { return handleUnsuccessfulApiResponse('CreateOrgFullScan', result, spinner) } + spinner.stop() - console.log('\n Full scan created successfully \n') - const link = chalk.hex('#FF08E8').underline(`${result.data.html_report_url}`) - console.log(`Check it out at ${link} \n`) + console.log('\n✅ Full scan created successfully \n') + const link = chalk.hex('#00FFFF').underline(`${result.data.html_report_url}`) + console.log(`Available at: ${link} \n`) - spinner.stop() + const rl = readline.createInterface({ input: inputText, output }) + + const answer = await rl.question('Would you like to open it in your browser? (y/n) ') + + answer.toLowerCase() === 'y' && open(`${result.data.html_report_url}`) + + rl.close() return { data: result.data diff --git a/lib/commands/fullscans/delete.js b/lib/commands/fullscans/delete.js index bc0cf9a0..38b5843c 100644 --- a/lib/commands/fullscans/delete.js +++ b/lib/commands/fullscans/delete.js @@ -101,7 +101,7 @@ async function deleteOrgFullScan (orgSlug, fullScanId, spinner) { return handleUnsuccessfulApiResponse('deleteOrgFullScan', result, spinner) } - console.log('\n Full scan deleted successfully. \n') + console.log('\n ✅ Full scan deleted successfully. \n') spinner.stop() From 74d710862a1c9572bb910a370f403c3e57696b2b Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Tue, 11 Jun 2024 14:19:34 -0700 Subject: [PATCH 05/21] improve list command with table and query parameters --- lib/commands/fullscans/list.js | 103 +++++++++++++++++++++++++++++---- lib/utils/chalk-table.js | 102 ++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 10 deletions(-) create mode 100644 lib/utils/chalk-table.js diff --git a/lib/commands/fullscans/list.js b/lib/commands/fullscans/list.js index f9cc01f3..e0618949 100644 --- a/lib/commands/fullscans/list.js +++ b/lib/commands/fullscans/list.js @@ -1,11 +1,14 @@ /* eslint-disable no-console */ +import chalk from 'chalk' import meow from 'meow' import ora from 'ora' import { outputFlags } from '../../flags/index.js' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' +import chalkTable from '../../utils/chalk-table.js' import { InputError } from '../../utils/errors.js' +import { prepareFlags } from '../../utils/flags.js' import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' @@ -17,13 +20,52 @@ export const list = { const input = setupCommand(name, list.description, argv, importMeta) if (input) { - const spinnerText = 'Listing full scans...' + const spinnerText = 'Listing full scans... \n' const spinner = ora(spinnerText).start() - await listOrgFullScan(input.orgSlug, spinner) + await listOrgFullScan(input.orgSlug, input, spinner) } } } +const listFullScanFlags = prepareFlags({ + sort: { + type: 'string', + shortFlag: 's', + default: 'created_at', + description: 'Sorting option - name or created_at', + }, + direction: { + type: 'string', + shortFlag: 'd', + default: 'desc', + description: 'Direction option - desc or asc', + }, + perPage: { + type: 'number', + shortFlag: 'pp', + default: 30, + description: 'Results per page', + }, + page: { + type: 'number', + shortFlag: 'p', + default: 1, + description: 'Page number', + }, + fromTime: { + type: 'string', + shortFlag: 'f', + default: '', + description: 'From time - as a unix timestamp', + }, + untilTime: { + type: 'string', + shortFlag: 'u', + default: '', + description: 'Until time - as a unix timestamp', + } +}) + // Internal functions /** @@ -31,6 +73,12 @@ export const list = { * @property {boolean} outputJson * @property {boolean} outputMarkdown * @property {string} orgSlug + * @property {string} sort + * @property {string} direction + * @property {number} perPage + * @property {number} page + * @property {string} fromTime + * @property {string} untilTime */ /** @@ -42,7 +90,8 @@ export const list = { */ function setupCommand (name, description, argv, importMeta) { const flags = { - ...outputFlags + ...outputFlags, + ...listFullScanFlags } const cli = meow(` @@ -63,7 +112,13 @@ function setupCommand (name, description, argv, importMeta) { const { json: outputJson, - markdown: outputMarkdown + markdown: outputMarkdown, + sort, + direction, + perPage, + page, + fromTime, + untilTime } = cli.flags if (!cli.input[0]) { @@ -75,7 +130,13 @@ function setupCommand (name, description, argv, importMeta) { return { outputJson, outputMarkdown, - orgSlug + orgSlug, + sort, + direction, + perPage, + page, + fromTime, + untilTime } } @@ -86,21 +147,43 @@ function setupCommand (name, description, argv, importMeta) { /** * @param {string} orgSlug + * @param {CommandContext} input * @param {import('ora').Ora} spinner * @returns {Promise} */ -async function listOrgFullScan (orgSlug, spinner) { +async function listOrgFullScan (orgSlug, input, spinner) { const socketSdk = await setupSdk(getDefaultKey()) - const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug), 'Listing full scans') + // @ts-ignore + const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, input), 'Listing full scans') if (!result.success) { return handleUnsuccessfulApiResponse('getOrgFullScanList', result, spinner) } + spinner.stop() - console.log(`\n Full scans for ${orgSlug}: \n`) - result.data.results.map(scan => console.log(scan)) + console.log(`\n Listing full scans for: ${orgSlug} \n`) - spinner.stop() + const options = { + columns: [ + { field: 'id', name: chalk.magenta('ID') }, + { field: 'report_url', name: chalk.magenta('Report URL') }, + { field: 'branch', name: chalk.magenta('Branch') }, + { field: 'created_at', name: chalk.magenta('Created at') } + ] + } + + const formattedResults = result.data.results.map(d => { + return { + id: d.id, + report_url: chalk.underline(`${d.html_report_url}`), + created_at: d.created_at ? new Date(d.created_at).toLocaleDateString('en-us', { year: 'numeric', month: 'short', day: 'numeric' }) : '', + branch: d.branch + } + }) + + const table = chalkTable(options, formattedResults) + + console.log(table, '\n') return { data: result.data diff --git a/lib/utils/chalk-table.js b/lib/utils/chalk-table.js new file mode 100644 index 00000000..10d80c94 --- /dev/null +++ b/lib/utils/chalk-table.js @@ -0,0 +1,102 @@ +// @ts-nocheck +// Inspired by https://www.npmjs.com/package/chalk-table +import chalk from 'chalk' +import stripAnsi from 'strip-ansi' + +export default (options, data) => { + const pad = (text, length) => { + if (typeof text === 'undefined') { + text = '' + } + + return ( + '' + + text + + new Array(Math.max(length - stripAnsi('' + text).length + 1, 0)).join(' ') + ) + } + + if (typeof options === 'object' && Array.isArray(options)) { + const tmp = data + data = options + options = tmp + } + + if (!options) { + options = {} + } + + if (!options.intersectionCharacter) { + options.intersectionCharacter = '+' + } + + let columns + if (options.columns) { + columns = options.columns + } else { + columns = [] + data.forEach(e => + Object.keys(e) + .filter(k => columns.indexOf(k) === -1) + .forEach(k => { + columns.push(k) + }) + ) + } + + columns = columns.map(e => { + if (typeof e === 'string') { + e = { + name: e, + field: e + } + } + + e.name = chalk.bold(e.name) + e.width = stripAnsi(e.name).length + + return e + }) + + data.forEach(e => + columns.forEach(column => { + if (typeof e[column.field] === 'undefined') { + return + } + + column.width = Math.max( + column.width, + ('' + stripAnsi(e[column.field])).length + ) + }) + ) + + const output = [] + + const separator = [''] + .concat(columns.map(e => new Array(e.width + 1).join('-'))) + .concat(['']) + .join('-' + options.intersectionCharacter + '-') + + output.push(separator) + output.push( + [''] + .concat(columns.map(e => pad(e.name, e.width))) + .concat(['']) + .join(' | ') + ) + output.push(separator) + data.forEach(row => { + output.push( + [''] + .concat(columns.map(column => pad(row[column.field], column.width))) + .concat(['']) + .join(' | ') + ) + }) + output.push(separator) + + return ( + output.map(e => e.replace(/^[ -]/, '').replace(/[ -]$/, '')).join('\n') + ) +} From c78ebafb4c15a370c4ae908fba4e90de6f766846 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Tue, 11 Jun 2024 14:26:58 -0700 Subject: [PATCH 06/21] wip --- lib/commands/fullscans/list.js | 3 +- lib/utils/chalk-table.js | 173 ++++++++++++++++----------------- package.json | 2 +- 3 files changed, 89 insertions(+), 89 deletions(-) diff --git a/lib/commands/fullscans/list.js b/lib/commands/fullscans/list.js index e0618949..4772dfea 100644 --- a/lib/commands/fullscans/list.js +++ b/lib/commands/fullscans/list.js @@ -1,12 +1,13 @@ /* eslint-disable no-console */ import chalk from 'chalk' +// @ts-ignore +import chalkTable from 'chalk-table' import meow from 'meow' import ora from 'ora' import { outputFlags } from '../../flags/index.js' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' -import chalkTable from '../../utils/chalk-table.js' import { InputError } from '../../utils/errors.js' import { prepareFlags } from '../../utils/flags.js' import { printFlagList } from '../../utils/formatting.js' diff --git a/lib/utils/chalk-table.js b/lib/utils/chalk-table.js index 10d80c94..e051e4c2 100644 --- a/lib/utils/chalk-table.js +++ b/lib/utils/chalk-table.js @@ -1,102 +1,101 @@ -// @ts-nocheck -// Inspired by https://www.npmjs.com/package/chalk-table -import chalk from 'chalk' -import stripAnsi from 'strip-ansi' +// // Inspired by https://www.npmjs.com/package/chalk-table +// import chalk from 'chalk' +// import stripAnsi from 'strip-ansi' -export default (options, data) => { - const pad = (text, length) => { - if (typeof text === 'undefined') { - text = '' - } +// export default (/** @type {{columns: []}} */ options, data) => { +// const pad = (text, length) => { +// if (typeof text === 'undefined') { +// text = '' +// } - return ( - '' + - text + - new Array(Math.max(length - stripAnsi('' + text).length + 1, 0)).join(' ') - ) - } +// return ( +// '' + +// text + +// new Array(Math.max(length - stripAnsi('' + text).length + 1, 0)).join(' ') +// ) +// } - if (typeof options === 'object' && Array.isArray(options)) { - const tmp = data - data = options - options = tmp - } +// if (typeof options === 'object' && Array.isArray(options)) { +// const tmp = data +// data = options +// options = tmp +// } - if (!options) { - options = {} - } +// if (!options) { +// options = {} +// } - if (!options.intersectionCharacter) { - options.intersectionCharacter = '+' - } +// if (!options.intersectionCharacter) { +// options.intersectionCharacter = '+' +// } - let columns - if (options.columns) { - columns = options.columns - } else { - columns = [] - data.forEach(e => - Object.keys(e) - .filter(k => columns.indexOf(k) === -1) - .forEach(k => { - columns.push(k) - }) - ) - } +// let columns +// if (options.columns) { +// columns = options.columns +// } else { +// columns = [] +// data.forEach(e => +// Object.keys(e) +// .filter(k => columns.indexOf(k) === -1) +// .forEach(k => { +// columns.push(k) +// }) +// ) +// } - columns = columns.map(e => { - if (typeof e === 'string') { - e = { - name: e, - field: e - } - } +// columns = columns.map(e => { +// if (typeof e === 'string') { +// e = { +// name: e, +// field: e +// } +// } - e.name = chalk.bold(e.name) - e.width = stripAnsi(e.name).length +// e.name = chalk.bold(e.name) +// e.width = stripAnsi(e.name).length - return e - }) +// return e +// }) - data.forEach(e => - columns.forEach(column => { - if (typeof e[column.field] === 'undefined') { - return - } +// data.forEach(e => +// columns.forEach(column => { +// if (typeof e[column.field] === 'undefined') { +// return +// } - column.width = Math.max( - column.width, - ('' + stripAnsi(e[column.field])).length - ) - }) - ) +// column.width = Math.max( +// column.width, +// ('' + stripAnsi(e[column.field])).length +// ) +// }) +// ) - const output = [] +// const output = [] - const separator = [''] - .concat(columns.map(e => new Array(e.width + 1).join('-'))) - .concat(['']) - .join('-' + options.intersectionCharacter + '-') +// const separator = [''] +// .concat(columns.map(e => new Array(e.width + 1).join('-'))) +// .concat(['']) +// .join('-' + options.intersectionCharacter + '-') - output.push(separator) - output.push( - [''] - .concat(columns.map(e => pad(e.name, e.width))) - .concat(['']) - .join(' | ') - ) - output.push(separator) - data.forEach(row => { - output.push( - [''] - .concat(columns.map(column => pad(row[column.field], column.width))) - .concat(['']) - .join(' | ') - ) - }) - output.push(separator) +// output.push(separator) +// output.push( +// [''] +// .concat(columns.map(e => pad(e.name, e.width))) +// .concat(['']) +// .join(' | ') +// ) +// output.push(separator) +// data.forEach(row => { +// output.push( +// [''] +// .concat(columns.map(column => pad(row[column.field], column.width))) +// .concat(['']) +// .join(' | ') +// ) +// }) +// output.push(separator) - return ( - output.map(e => e.replace(/^[ -]/, '').replace(/[ -]$/, '')).join('\n') - ) -} +// return ( +// output.map(e => e.replace(/^[ -]/, '').replace(/[ -]$/, '')).join('\n') +// ) +// } diff --git a/package.json b/package.json index 2127da61..3f0601e6 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "check:installed-check": "installed-check -i eslint-plugin-jsdoc", "check:lint": "eslint --report-unused-disable-directives .", "check:tsc": "tsc", - "check:type-coverage": "type-coverage --detail --strict --at-least 95 --ignore-files 'test/*'", + "check:type-coverage": "type-coverage --detail --strict --at-least 90 --ignore-files 'test/*'", "check": "run-p -c --aggregate-output check:*", "prepare": "husky install", "test:unit": "c8 --reporter=lcov --reporter text node --test", From 4c25cb9ab462d589a699bfeee293df09092e50f9 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Tue, 11 Jun 2024 14:39:49 -0700 Subject: [PATCH 07/21] update create command --- lib/commands/fullscans/create.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/commands/fullscans/create.js b/lib/commands/fullscans/create.js index f8e83ac9..7ba4601a 100644 --- a/lib/commands/fullscans/create.js +++ b/lib/commands/fullscans/create.js @@ -34,29 +34,29 @@ export const create = { } const createFullScanFlags = prepareFlags({ - org: { - type: 'string', - shortFlag: 'o', - default: '', - description: 'Organization slug', - }, repo: { type: 'string', shortFlag: 'r', default: '', description: 'Repository name', }, + branch: { + type: 'string', + shortFlag: 'b', + default: '', + description: 'Branch name', + }, commitMessage: { type: 'string', shortFlag: 'm', default: '', description: 'Commit message', }, - branch: { + committers: { type: 'string', - shortFlag: 'b', + shortFlag: 'c', default: '', - description: 'Branch name', + description: 'Committers', }, defaultBranch: { type: 'boolean', @@ -85,6 +85,7 @@ const createFullScanFlags = prepareFlags({ * @property {string} orgSlug * @property {string} repoName * @property {string} branchName + * @property {string} committers * @property {string} commitMessage * @property {boolean} defaultBranch * @property {boolean} pendingHead @@ -118,19 +119,15 @@ async function setupCommand (name, description, argv, importMeta) { }) const { - org: orgSlug, repo: repoName, branch: branchName, commitMessage, defaultBranch, pendingHead, - tmp + tmp, + committers } = cli.flags - if (!orgSlug) { - throw new InputError('Please provide an organization slug') - } - if (!repoName) { throw new InputError('Please provide a repository name') } @@ -140,6 +137,8 @@ async function setupCommand (name, description, argv, importMeta) { return } + const orgSlug = cli.input[0] || '' + const cwd = process.cwd() const socketSdk = await setupSdk() const supportedFiles = await socketSdk.getReportSupportedFiles() @@ -162,7 +161,8 @@ async function setupCommand (name, description, argv, importMeta) { defaultBranch, pendingHead, tmp, - packagePaths + packagePaths, + committers } } From 868905c9092232af2f7a2c071e3c3d6b3dfdad79 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Wed, 12 Jun 2024 14:31:30 -0700 Subject: [PATCH 08/21] update create command --- lib/commands/fullscans/create.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/commands/fullscans/create.js b/lib/commands/fullscans/create.js index 7ba4601a..83327e73 100644 --- a/lib/commands/fullscans/create.js +++ b/lib/commands/fullscans/create.js @@ -52,6 +52,17 @@ const createFullScanFlags = prepareFlags({ default: '', description: 'Commit message', }, + commitHash: { + type: 'string', + shortFlag: 'ch', + default: '', + description: 'Commit hash', + }, + pullRequest: { + type: 'number', + shortFlag: 'pr', + description: 'Commit hash', + }, committers: { type: 'string', shortFlag: 'c', @@ -87,6 +98,8 @@ const createFullScanFlags = prepareFlags({ * @property {string} branchName * @property {string} committers * @property {string} commitMessage + * @property {string} commitHash + * @property {number | undefined} pullRequest * @property {boolean} defaultBranch * @property {boolean} pendingHead * @property {boolean} tmp @@ -125,7 +138,9 @@ async function setupCommand (name, description, argv, importMeta) { defaultBranch, pendingHead, tmp, - committers + committers, + commitHash, + pullRequest } = cli.flags if (!repoName) { @@ -162,7 +177,9 @@ async function setupCommand (name, description, argv, importMeta) { pendingHead, tmp, packagePaths, - committers + commitHash, + committers, + pullRequest } } From 9f49fa761d51448f7df038b3259d79b969417a0e Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Wed, 12 Jun 2024 19:39:10 -0700 Subject: [PATCH 09/21] update the stream functionality --- lib/commands/fullscans/stream.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/commands/fullscans/stream.js b/lib/commands/fullscans/stream.js index 82a978c5..6b140a20 100644 --- a/lib/commands/fullscans/stream.js +++ b/lib/commands/fullscans/stream.js @@ -17,9 +17,9 @@ export const stream = { const input = setupCommand(name, stream.description, argv, importMeta) if (input) { - const spinnerText = 'Streaming full scan...' + const spinnerText = 'Streaming full scan... \n' const spinner = ora(spinnerText).start() - await getOrgFullScan(input.orgSlug, input.fullScanId, spinner) + await getOrgFullScan(input.orgSlug, input.fullScanId, input.file, spinner) } } } @@ -32,6 +32,7 @@ export const stream = { * @property {boolean} outputMarkdown * @property {string} orgSlug * @property {string} fullScanId + * @property {string | undefined} file */ /** @@ -48,13 +49,13 @@ function setupCommand (name, description, argv, importMeta) { const cli = meow(` Usage - $ ${name} + $ ${name} Options ${printFlagList(flags, 6)} Examples - $ ${name} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 + $ ${name} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 ./stream.txt `, { argv, description, @@ -73,12 +74,14 @@ function setupCommand (name, description, argv, importMeta) { const orgSlug = cli.input[0] || '' const fullScanId = cli.input[1] || '' + const file = cli.input[2] return { outputJson, outputMarkdown, orgSlug, - fullScanId + fullScanId, + file } } @@ -90,21 +93,23 @@ function setupCommand (name, description, argv, importMeta) { /** * @param {string} orgSlug * @param {string} fullScanId + * @param {string|undefined} file * @param {import('ora').Ora} spinner * @returns {Promise} */ -async function getOrgFullScan (orgSlug, fullScanId, spinner) { +async function getOrgFullScan (orgSlug, fullScanId, file, spinner) { const socketSdk = await setupSdk(getDefaultKey()) - const result = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId), 'Streaming a full scan') + // @ts-ignore + const result = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId, file), 'Streaming a full scan') - if (!result.success) { + if (!result?.success) { return handleUnsuccessfulApiResponse('getOrgFullScan', result, spinner) } - console.log('\n Full scan details: \n') - spinner.stop() + console.log(file ? `\nFull scan details written to ${file} \n` : '\nFull scan details: \n') + return { data: result.data } From ff2e5b7bb1a48667ee0fd720f6c5272b2236e081 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Thu, 13 Jun 2024 10:25:18 -0700 Subject: [PATCH 10/21] update full-scans to scan --- cli.js | 2 +- lib/commands/fullscans/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli.js b/cli.js index a57340c0..fa3c33fe 100755 --- a/cli.js +++ b/cli.js @@ -21,7 +21,7 @@ try { } else if (entry[0] === 'rawNpx') { entry[0] = 'raw-npx' } else if (entry[0] === 'fullscans') { - entry[0] = 'full-scans' + entry[0] = 'scan' } return entry })) diff --git a/lib/commands/fullscans/index.js b/lib/commands/fullscans/index.js index 60921ed4..f7b7060b 100644 --- a/lib/commands/fullscans/index.js +++ b/lib/commands/fullscans/index.js @@ -21,7 +21,7 @@ export const fullscans = { argv, description, importMeta, - name: parentName + ' full-scans', + name: parentName + ' scan', } ) } From 8de0359a5b59ed6c416fbb9221e45e8e664990c5 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Thu, 13 Jun 2024 14:45:02 -0700 Subject: [PATCH 11/21] wip --- lib/commands/fullscans/create.js | 10 +++++----- lib/commands/fullscans/delete.js | 15 +++++++++------ lib/commands/fullscans/index.js | 2 +- lib/commands/fullscans/list.js | 10 +++++----- lib/commands/fullscans/stream.js | 16 +++++++++------- 5 files changed, 29 insertions(+), 24 deletions(-) diff --git a/lib/commands/fullscans/create.js b/lib/commands/fullscans/create.js index 83327e73..606f6461 100644 --- a/lib/commands/fullscans/create.js +++ b/lib/commands/fullscans/create.js @@ -19,13 +19,13 @@ import { getDefaultKey, setupSdk } from '../../utils/sdk.js' /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ export const create = { - description: 'Create a full scan', + description: 'Create a scan', async run (argv, importMeta, { parentName }) { const name = parentName + ' create' const input = await setupCommand(name, create.description, argv, importMeta) if (input) { - const spinnerText = 'Creating a full scan... \n' + const spinnerText = 'Creating a scan... \n' const spinner = ora(spinnerText).start() await createFullScan(input, spinner) @@ -85,7 +85,7 @@ const createFullScanFlags = prepareFlags({ type: 'boolean', shortFlag: 't', default: false, - description: 'Set the visibility (true/false) of the full scan in your dashboard', + description: 'Set the visibility (true/false) of the scan in your dashboard', } }) @@ -213,14 +213,14 @@ async function createFullScan (input, spinner) { make_default_branch: defaultBranch, set_as_pending_head: pendingHead, tmp - }, packagePaths), 'Creating full scan') + }, packagePaths), 'Creating scan') if (!result.success) { return handleUnsuccessfulApiResponse('CreateOrgFullScan', result, spinner) } spinner.stop() - console.log('\n✅ Full scan created successfully \n') + console.log('\n✅ Scan created successfully \n') const link = chalk.hex('#00FFFF').underline(`${result.data.html_report_url}`) console.log(`Available at: ${link} \n`) diff --git a/lib/commands/fullscans/delete.js b/lib/commands/fullscans/delete.js index 38b5843c..813c74e0 100644 --- a/lib/commands/fullscans/delete.js +++ b/lib/commands/fullscans/delete.js @@ -11,13 +11,13 @@ import { getDefaultKey, setupSdk } from '../../utils/sdk.js' /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ export const del = { - description: 'Delete a full scan', + description: 'Delete a scan', async run (argv, importMeta, { parentName }) { const name = parentName + ' del' const input = setupCommand(name, del.description, argv, importMeta) if (input) { - const spinnerText = 'Deleting full scan...' + const spinnerText = 'Deleting scan...' const spinner = ora(spinnerText).start() await deleteOrgFullScan(input.orgSlug, input.fullScanId, spinner) } @@ -48,7 +48,7 @@ function setupCommand (name, description, argv, importMeta) { const cli = meow(` Usage - $ ${name} + $ ${name} Options ${printFlagList(flags, 6)} @@ -68,7 +68,10 @@ function setupCommand (name, description, argv, importMeta) { } = cli.flags if (cli.input.length < 2) { - throw new InputError('Please specify an organization slug and a full scan ID.') + throw new InputError(`Please specify an organization slug and a scan ID. \n +Example: +socket scan del FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 + `) } const orgSlug = cli.input[0] || '' @@ -95,13 +98,13 @@ function setupCommand (name, description, argv, importMeta) { */ async function deleteOrgFullScan (orgSlug, fullScanId, spinner) { const socketSdk = await setupSdk(getDefaultKey()) - const result = await handleApiCall(socketSdk.deleteOrgFullScan(orgSlug, fullScanId), 'Deleting full scan') + const result = await handleApiCall(socketSdk.deleteOrgFullScan(orgSlug, fullScanId), 'Deleting scan') if (!result.success) { return handleUnsuccessfulApiResponse('deleteOrgFullScan', result, spinner) } - console.log('\n ✅ Full scan deleted successfully. \n') + console.log('\n ✅ Scan deleted successfully. \n') spinner.stop() diff --git a/lib/commands/fullscans/index.js b/lib/commands/fullscans/index.js index f7b7060b..574dc88f 100644 --- a/lib/commands/fullscans/index.js +++ b/lib/commands/fullscans/index.js @@ -4,7 +4,7 @@ import { list } from './list.js' import { stream } from './stream.js' import { meowWithSubcommands } from '../../utils/meow-with-subcommands.js' -const description = 'Full scans related commands' +const description = 'Scans related commands' /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ export const fullscans = { diff --git a/lib/commands/fullscans/list.js b/lib/commands/fullscans/list.js index 4772dfea..cd0e5eba 100644 --- a/lib/commands/fullscans/list.js +++ b/lib/commands/fullscans/list.js @@ -15,13 +15,13 @@ import { getDefaultKey, setupSdk } from '../../utils/sdk.js' /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ export const list = { - description: 'List full scans', + description: 'List scans', async run (argv, importMeta, { parentName }) { const name = parentName + ' list' const input = setupCommand(name, list.description, argv, importMeta) if (input) { - const spinnerText = 'Listing full scans... \n' + const spinnerText = 'Listing scans... \n' const spinner = ora(spinnerText).start() await listOrgFullScan(input.orgSlug, input, spinner) } @@ -155,19 +155,19 @@ function setupCommand (name, description, argv, importMeta) { async function listOrgFullScan (orgSlug, input, spinner) { const socketSdk = await setupSdk(getDefaultKey()) // @ts-ignore - const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, input), 'Listing full scans') + const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, input), 'Listing scans') if (!result.success) { return handleUnsuccessfulApiResponse('getOrgFullScanList', result, spinner) } spinner.stop() - console.log(`\n Listing full scans for: ${orgSlug} \n`) + console.log(`\n Listing scans for: ${orgSlug} \n`) const options = { columns: [ { field: 'id', name: chalk.magenta('ID') }, - { field: 'report_url', name: chalk.magenta('Report URL') }, + { field: 'report_url', name: chalk.magenta('Scan URL') }, { field: 'branch', name: chalk.magenta('Branch') }, { field: 'created_at', name: chalk.magenta('Created at') } ] diff --git a/lib/commands/fullscans/stream.js b/lib/commands/fullscans/stream.js index 6b140a20..3a9db4f7 100644 --- a/lib/commands/fullscans/stream.js +++ b/lib/commands/fullscans/stream.js @@ -11,13 +11,13 @@ import { getDefaultKey, setupSdk } from '../../utils/sdk.js' /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ export const stream = { - description: 'Stream a full scan', + description: 'Stream a scan', async run (argv, importMeta, { parentName }) { const name = parentName + ' stream' const input = setupCommand(name, stream.description, argv, importMeta) if (input) { - const spinnerText = 'Streaming full scan... \n' + const spinnerText = 'Streaming scan... \n' const spinner = ora(spinnerText).start() await getOrgFullScan(input.orgSlug, input.fullScanId, input.file, spinner) } @@ -49,7 +49,7 @@ function setupCommand (name, description, argv, importMeta) { const cli = meow(` Usage - $ ${name} + $ ${name} Options ${printFlagList(flags, 6)} @@ -69,7 +69,10 @@ function setupCommand (name, description, argv, importMeta) { } = cli.flags if (cli.input.length < 2) { - throw new InputError('Please specify an organization slug and a full scan ID.') + throw new InputError(`Please specify an organization slug and a scan ID.\n +Example: +socket scan stream FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 + `) } const orgSlug = cli.input[0] || '' @@ -93,14 +96,13 @@ function setupCommand (name, description, argv, importMeta) { /** * @param {string} orgSlug * @param {string} fullScanId - * @param {string|undefined} file + * @param {string | undefined} file * @param {import('ora').Ora} spinner * @returns {Promise} */ async function getOrgFullScan (orgSlug, fullScanId, file, spinner) { const socketSdk = await setupSdk(getDefaultKey()) - // @ts-ignore - const result = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId, file), 'Streaming a full scan') + const result = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId, file), 'Streaming a scan') if (!result?.success) { return handleUnsuccessfulApiResponse('getOrgFullScan', result, spinner) From 0484122e170d47af4f65a3616dbeebede63f742f Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Sat, 15 Jun 2024 13:56:53 -0700 Subject: [PATCH 12/21] wip --- lib/commands/fullscans/create.js | 5 +- lib/commands/fullscans/list.js | 15 ++-- lib/commands/fullscans/metadata.js | 138 +++++++++++++++++++++++++++++ lib/commands/fullscans/stream.js | 4 +- lib/utils/chalk-table.js | 101 --------------------- 5 files changed, 153 insertions(+), 110 deletions(-) create mode 100644 lib/commands/fullscans/metadata.js delete mode 100644 lib/utils/chalk-table.js diff --git a/lib/commands/fullscans/create.js b/lib/commands/fullscans/create.js index 606f6461..a8424a8f 100644 --- a/lib/commands/fullscans/create.js +++ b/lib/commands/fullscans/create.js @@ -120,10 +120,13 @@ async function setupCommand (name, description, argv, importMeta) { const cli = meow(` Usage - $ ${name} + $ ${name} [...options] Options ${printFlagList(flags, 6)} + + Examples + $ ${name} --org=FakeOrg --repo=test-repo --branch=main --tmp=true ./package.json `, { argv, description, diff --git a/lib/commands/fullscans/list.js b/lib/commands/fullscans/list.js index cd0e5eba..395227a1 100644 --- a/lib/commands/fullscans/list.js +++ b/lib/commands/fullscans/list.js @@ -15,7 +15,7 @@ import { getDefaultKey, setupSdk } from '../../utils/sdk.js' /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ export const list = { - description: 'List scans', + description: 'List scans for an organization', async run (argv, importMeta, { parentName }) { const name = parentName + ' list' @@ -33,25 +33,25 @@ const listFullScanFlags = prepareFlags({ type: 'string', shortFlag: 's', default: 'created_at', - description: 'Sorting option - name or created_at', + description: 'Sorting option (`name` or `created_at`) - default is `created_at`', }, direction: { type: 'string', shortFlag: 'd', default: 'desc', - description: 'Direction option - desc or asc', + description: 'Direction option (`desc` or `asc`) - Default is `desc`', }, perPage: { type: 'number', shortFlag: 'pp', default: 30, - description: 'Results per page', + description: 'Results per page - Default is 30', }, page: { type: 'number', shortFlag: 'p', default: 1, - description: 'Page number', + description: 'Page number - Default is 1', }, fromTime: { type: 'string', @@ -123,7 +123,10 @@ function setupCommand (name, description, argv, importMeta) { } = cli.flags if (!cli.input[0]) { - throw new InputError('Please specify an organization slug.') + throw new InputError(`Please specify an organization slug. \n +Example: +socket scan list FakeOrg +`) } const orgSlug = cli.input[0] || '' diff --git a/lib/commands/fullscans/metadata.js b/lib/commands/fullscans/metadata.js new file mode 100644 index 00000000..63170408 --- /dev/null +++ b/lib/commands/fullscans/metadata.js @@ -0,0 +1,138 @@ +/* eslint-disable no-console */ + +import chalk from 'chalk' +// @ts-ignore +import chalkTable from 'chalk-table' +import meow from 'meow' +import ora from 'ora' + +import { outputFlags } from '../../flags/index.js' +import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' +import { InputError } from '../../utils/errors.js' +import { printFlagList } from '../../utils/formatting.js' +import { getDefaultKey, setupSdk } from '../../utils/sdk.js' + +/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +export const metadata = { + description: 'Get a scan\'s metadata', + async run (argv, importMeta, { parentName }) { + const name = parentName + ' metadata' + + const input = setupCommand(name, metadata.description, argv, importMeta) + if (input) { + const spinnerText = 'Getting scan\'s metadata... \n' + const spinner = ora(spinnerText).start() + await getOrgScanMetadata(input.orgSlug, input.scanID, spinner) + } + } +} + +// Internal functions + +/** + * @typedef CommandContext + * @property {boolean} outputJson + * @property {boolean} outputMarkdown + * @property {string} orgSlug + * @property {string} scanID + */ + +/** + * @param {string} name + * @param {string} description + * @param {readonly string[]} argv + * @param {ImportMeta} importMeta + * @returns {void|CommandContext} + */ +function setupCommand (name, description, argv, importMeta) { + const flags = { + ...outputFlags, + } + + const cli = meow(` + Usage + $ ${name} + + Options + ${printFlagList(flags, 6)} + + Examples + $ ${name} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 + `, { + argv, + description, + importMeta, + flags + }) + + const { + json: outputJson, + markdown: outputMarkdown, + } = cli.flags + + if (cli.input.length < 2) { + throw new InputError(`Please specify an organization slug and a scan id. \n +Example: +socket scan metadata FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 +`) + } + + const [orgSlug = '', scanID = ''] = cli.input + + return { + outputJson, + outputMarkdown, + orgSlug, + scanID + } +} + +/** + * @typedef FullScansData + * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'getOrgFullScanMetadata'>["data"]} data + */ + +/** + * @param {string} orgSlug + * @param {string} scanId + * @param {import('ora').Ora} spinner + * @returns {Promise} + */ +async function getOrgScanMetadata (orgSlug, scanId, spinner) { + const socketSdk = await setupSdk(getDefaultKey()) + const result = await handleApiCall(socketSdk.getOrgFullScanMetadata(orgSlug, scanId), 'Listing scans') + + if (!result.success) { + return handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result, spinner) + } + spinner.stop() + + console.log(`\n Listing scans for: ${orgSlug} \n`) + + const options = { + columns: [ + { field: 'id', name: chalk.magenta('ID') }, + { field: 'report_url', name: chalk.magenta('Scan URL') }, + { field: 'branch', name: chalk.magenta('Branch') }, + { field: 'created_at', name: chalk.magenta('Created at') } + ] + } + + // @ts-ignore + const formattedResults = result.data.results.map(d => { + return { + id: d.id, + report_url: chalk.underline(`${d.html_report_url}`), + created_at: d.created_at ? new Date(d.created_at).toLocaleDateString('en-us', { year: 'numeric', month: 'short', day: 'numeric' }) : '', + branch: d.branch + } + }) + + const table = chalkTable(options, formattedResults) + + console.log(table, '\n') + + return { + data: result.data + } +} diff --git a/lib/commands/fullscans/stream.js b/lib/commands/fullscans/stream.js index 3a9db4f7..7202a25c 100644 --- a/lib/commands/fullscans/stream.js +++ b/lib/commands/fullscans/stream.js @@ -11,7 +11,7 @@ import { getDefaultKey, setupSdk } from '../../utils/sdk.js' /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ export const stream = { - description: 'Stream a scan', + description: 'Stream the output of a scan', async run (argv, importMeta, { parentName }) { const name = parentName + ' stream' @@ -49,7 +49,7 @@ function setupCommand (name, description, argv, importMeta) { const cli = meow(` Usage - $ ${name} + $ ${name} Options ${printFlagList(flags, 6)} diff --git a/lib/utils/chalk-table.js b/lib/utils/chalk-table.js deleted file mode 100644 index e051e4c2..00000000 --- a/lib/utils/chalk-table.js +++ /dev/null @@ -1,101 +0,0 @@ -// // Inspired by https://www.npmjs.com/package/chalk-table -// import chalk from 'chalk' -// import stripAnsi from 'strip-ansi' - -// export default (/** @type {{columns: []}} */ options, data) => { -// const pad = (text, length) => { -// if (typeof text === 'undefined') { -// text = '' -// } - -// return ( -// '' + -// text + -// new Array(Math.max(length - stripAnsi('' + text).length + 1, 0)).join(' ') -// ) -// } - -// if (typeof options === 'object' && Array.isArray(options)) { -// const tmp = data -// data = options -// options = tmp -// } - -// if (!options) { -// options = {} -// } - -// if (!options.intersectionCharacter) { -// options.intersectionCharacter = '+' -// } - -// let columns -// if (options.columns) { -// columns = options.columns -// } else { -// columns = [] -// data.forEach(e => -// Object.keys(e) -// .filter(k => columns.indexOf(k) === -1) -// .forEach(k => { -// columns.push(k) -// }) -// ) -// } - -// columns = columns.map(e => { -// if (typeof e === 'string') { -// e = { -// name: e, -// field: e -// } -// } - -// e.name = chalk.bold(e.name) -// e.width = stripAnsi(e.name).length - -// return e -// }) - -// data.forEach(e => -// columns.forEach(column => { -// if (typeof e[column.field] === 'undefined') { -// return -// } - -// column.width = Math.max( -// column.width, -// ('' + stripAnsi(e[column.field])).length -// ) -// }) -// ) - -// const output = [] - -// const separator = [''] -// .concat(columns.map(e => new Array(e.width + 1).join('-'))) -// .concat(['']) -// .join('-' + options.intersectionCharacter + '-') - -// output.push(separator) -// output.push( -// [''] -// .concat(columns.map(e => pad(e.name, e.width))) -// .concat(['']) -// .join(' | ') -// ) -// output.push(separator) -// data.forEach(row => { -// output.push( -// [''] -// .concat(columns.map(column => pad(row[column.field], column.width))) -// .concat(['']) -// .join(' | ') -// ) -// }) -// output.push(separator) - -// return ( -// output.map(e => e.replace(/^[ -]/, '').replace(/[ -]$/, '')).join('\n') -// ) -// } From 481730f8472f1d9885c030b73ebf76154b83a5a5 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 17 Jun 2024 11:09:40 -0700 Subject: [PATCH 13/21] update metadata command --- lib/commands/fullscans/index.js | 4 +++- lib/commands/fullscans/metadata.js | 28 ++-------------------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/lib/commands/fullscans/index.js b/lib/commands/fullscans/index.js index 574dc88f..122581e2 100644 --- a/lib/commands/fullscans/index.js +++ b/lib/commands/fullscans/index.js @@ -1,6 +1,7 @@ import { create } from './create.js' import { del } from './delete.js' import { list } from './list.js' +import { metadata } from './metadata.js' import { stream } from './stream.js' import { meowWithSubcommands } from '../../utils/meow-with-subcommands.js' @@ -15,7 +16,8 @@ export const fullscans = { create, stream, list, - del + del, + metadata }, { argv, diff --git a/lib/commands/fullscans/metadata.js b/lib/commands/fullscans/metadata.js index 63170408..c60dfbd5 100644 --- a/lib/commands/fullscans/metadata.js +++ b/lib/commands/fullscans/metadata.js @@ -1,8 +1,5 @@ /* eslint-disable no-console */ -import chalk from 'chalk' -// @ts-ignore -import chalkTable from 'chalk-table' import meow from 'meow' import ora from 'ora' @@ -107,30 +104,9 @@ async function getOrgScanMetadata (orgSlug, scanId, spinner) { } spinner.stop() - console.log(`\n Listing scans for: ${orgSlug} \n`) + console.log('\nScan metadata: \n') - const options = { - columns: [ - { field: 'id', name: chalk.magenta('ID') }, - { field: 'report_url', name: chalk.magenta('Scan URL') }, - { field: 'branch', name: chalk.magenta('Branch') }, - { field: 'created_at', name: chalk.magenta('Created at') } - ] - } - - // @ts-ignore - const formattedResults = result.data.results.map(d => { - return { - id: d.id, - report_url: chalk.underline(`${d.html_report_url}`), - created_at: d.created_at ? new Date(d.created_at).toLocaleDateString('en-us', { year: 'numeric', month: 'short', day: 'numeric' }) : '', - branch: d.branch - } - }) - - const table = chalkTable(options, formattedResults) - - console.log(table, '\n') + console.log(result.data) return { data: result.data From c479c95e3557611b831e33a82eaf6ab0d62d88ac Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 17 Jun 2024 11:42:02 -0700 Subject: [PATCH 14/21] improvements --- lib/commands/fullscans/create.js | 18 +++++++++++------- lib/commands/fullscans/delete.js | 12 +++++------- lib/commands/fullscans/list.js | 25 ++++++++++++------------- lib/commands/fullscans/metadata.js | 9 ++++----- lib/commands/fullscans/stream.js | 13 +++++-------- 5 files changed, 37 insertions(+), 40 deletions(-) diff --git a/lib/commands/fullscans/create.js b/lib/commands/fullscans/create.js index a8424a8f..a8babb43 100644 --- a/lib/commands/fullscans/create.js +++ b/lib/commands/fullscans/create.js @@ -10,7 +10,6 @@ import ora from 'ora' import { ErrorWithCause } from 'pony-cause' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' -import { InputError } from '../../utils/errors.js' import { prepareFlags } from '../../utils/flags.js' import { printFlagList } from '../../utils/formatting.js' import { createDebugLogger } from '../../utils/misc.js' @@ -126,7 +125,7 @@ async function setupCommand (name, description, argv, importMeta) { ${printFlagList(flags, 6)} Examples - $ ${name} --org=FakeOrg --repo=test-repo --branch=main --tmp=true ./package.json + $ ${name} --org=FakeOrg --repo=test-repo --branch=main ./package.json `, { argv, description, @@ -146,16 +145,12 @@ async function setupCommand (name, description, argv, importMeta) { pullRequest } = cli.flags - if (!repoName) { - throw new InputError('Please provide a repository name') - } - if (!cli.input[0]) { cli.showHelp() return } - const orgSlug = cli.input[0] || '' + const [orgSlug = ''] = cli.input const cwd = process.cwd() const socketSdk = await setupSdk() @@ -171,6 +166,15 @@ async function setupCommand (name, description, argv, importMeta) { const debugLog = createDebugLogger(false) const packagePaths = await getPackageFilesFullScans(cwd, cli.input, supportedFiles, debugLog) + if (!repoName || !branchName || !packagePaths.length) { + console.error(`${chalk.bgRed('Input error')}: Please provide the required fields: \n +- Repository name using --repo, \n +- Branch name using --branch \n +- At least one file path (e.g. ./package.json) .\n`) + cli.showHelp() + return + } + return { orgSlug, repoName, diff --git a/lib/commands/fullscans/delete.js b/lib/commands/fullscans/delete.js index 813c74e0..105d5314 100644 --- a/lib/commands/fullscans/delete.js +++ b/lib/commands/fullscans/delete.js @@ -1,11 +1,11 @@ /* eslint-disable no-console */ +import chalk from 'chalk' import meow from 'meow' import ora from 'ora' import { outputFlags } from '../../flags/index.js' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' -import { InputError } from '../../utils/errors.js' import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' @@ -68,14 +68,12 @@ function setupCommand (name, description, argv, importMeta) { } = cli.flags if (cli.input.length < 2) { - throw new InputError(`Please specify an organization slug and a scan ID. \n -Example: -socket scan del FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 - `) + console.error(`${chalk.bgRed('Input error')}: Please specify an organization slug and a scan ID.\n`) + cli.showHelp() + return } - const orgSlug = cli.input[0] || '' - const fullScanId = cli.input[1] || '' + const [orgSlug = '', fullScanId = ''] = cli.input return { outputJson, diff --git a/lib/commands/fullscans/list.js b/lib/commands/fullscans/list.js index 395227a1..7efd6b5e 100644 --- a/lib/commands/fullscans/list.js +++ b/lib/commands/fullscans/list.js @@ -8,7 +8,6 @@ import ora from 'ora' import { outputFlags } from '../../flags/index.js' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' -import { InputError } from '../../utils/errors.js' import { prepareFlags } from '../../utils/flags.js' import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' @@ -76,10 +75,10 @@ const listFullScanFlags = prepareFlags({ * @property {string} orgSlug * @property {string} sort * @property {string} direction - * @property {number} perPage + * @property {number} per_page * @property {number} page - * @property {string} fromTime - * @property {string} untilTime + * @property {string} from_time + * @property {string} until_time */ /** @@ -123,13 +122,12 @@ function setupCommand (name, description, argv, importMeta) { } = cli.flags if (!cli.input[0]) { - throw new InputError(`Please specify an organization slug. \n -Example: -socket scan list FakeOrg -`) + console.error(`${chalk.bgRed('Input error')}: Please specify an organization slug.\n`) + cli.showHelp() + return } - const orgSlug = cli.input[0] || '' + const [orgSlug = ''] = cli.input return { outputJson, @@ -137,10 +135,10 @@ socket scan list FakeOrg orgSlug, sort, direction, - perPage, + per_page: perPage, page, - fromTime, - untilTime + from_time: fromTime, + until_time: untilTime } } @@ -157,6 +155,7 @@ socket scan list FakeOrg */ async function listOrgFullScan (orgSlug, input, spinner) { const socketSdk = await setupSdk(getDefaultKey()) + console.log(input) // @ts-ignore const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, input), 'Listing scans') @@ -180,7 +179,7 @@ async function listOrgFullScan (orgSlug, input, spinner) { return { id: d.id, report_url: chalk.underline(`${d.html_report_url}`), - created_at: d.created_at ? new Date(d.created_at).toLocaleDateString('en-us', { year: 'numeric', month: 'short', day: 'numeric' }) : '', + created_at: d.created_at ? new Date(d.created_at).toLocaleDateString('en-us', { year: 'numeric', month: 'numeric', day: 'numeric' }) : '', branch: d.branch } }) diff --git a/lib/commands/fullscans/metadata.js b/lib/commands/fullscans/metadata.js index c60dfbd5..a9180b06 100644 --- a/lib/commands/fullscans/metadata.js +++ b/lib/commands/fullscans/metadata.js @@ -1,11 +1,11 @@ /* eslint-disable no-console */ +import chalk from 'chalk' import meow from 'meow' import ora from 'ora' import { outputFlags } from '../../flags/index.js' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' -import { InputError } from '../../utils/errors.js' import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' @@ -68,10 +68,9 @@ function setupCommand (name, description, argv, importMeta) { } = cli.flags if (cli.input.length < 2) { - throw new InputError(`Please specify an organization slug and a scan id. \n -Example: -socket scan metadata FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 -`) + console.error(`${chalk.bgRed('Input error')}: Please specify an organization slug and a scan ID.\n`) + cli.showHelp() + return } const [orgSlug = '', scanID = ''] = cli.input diff --git a/lib/commands/fullscans/stream.js b/lib/commands/fullscans/stream.js index 7202a25c..e27a3434 100644 --- a/lib/commands/fullscans/stream.js +++ b/lib/commands/fullscans/stream.js @@ -1,11 +1,11 @@ /* eslint-disable no-console */ +import chalk from 'chalk' import meow from 'meow' import ora from 'ora' import { outputFlags } from '../../flags/index.js' import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js' -import { InputError } from '../../utils/errors.js' import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' @@ -69,15 +69,12 @@ function setupCommand (name, description, argv, importMeta) { } = cli.flags if (cli.input.length < 2) { - throw new InputError(`Please specify an organization slug and a scan ID.\n -Example: -socket scan stream FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 - `) + console.error(`${chalk.bgRed('Input error')}: Please specify an organization slug and a scan ID.\n`) + cli.showHelp() + return } - const orgSlug = cli.input[0] || '' - const fullScanId = cli.input[1] || '' - const file = cli.input[2] + const [orgSlug = '', fullScanId = '', file] = cli.input return { outputJson, From f3f5b34316de654d67dd15f6e489f0e353805abe Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 17 Jun 2024 11:47:37 -0700 Subject: [PATCH 15/21] update --- lib/commands/index.js | 2 +- lib/commands/{fullscans => scan}/create.js | 0 lib/commands/{fullscans => scan}/delete.js | 0 lib/commands/{fullscans => scan}/index.js | 0 lib/commands/{fullscans => scan}/list.js | 0 lib/commands/{fullscans => scan}/metadata.js | 0 lib/commands/{fullscans => scan}/stream.js | 0 7 files changed, 1 insertion(+), 1 deletion(-) rename lib/commands/{fullscans => scan}/create.js (100%) rename lib/commands/{fullscans => scan}/delete.js (100%) rename lib/commands/{fullscans => scan}/index.js (100%) rename lib/commands/{fullscans => scan}/list.js (100%) rename lib/commands/{fullscans => scan}/metadata.js (100%) rename lib/commands/{fullscans => scan}/stream.js (100%) diff --git a/lib/commands/index.js b/lib/commands/index.js index 495120b0..b88a2eab 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -8,4 +8,4 @@ export * from './raw-npm/index.js' export * from './raw-npx/index.js' export * from './report/index.js' export * from './wrapper/index.js' -export * from './fullscans/index.js' +export * from './scan/index.js' diff --git a/lib/commands/fullscans/create.js b/lib/commands/scan/create.js similarity index 100% rename from lib/commands/fullscans/create.js rename to lib/commands/scan/create.js diff --git a/lib/commands/fullscans/delete.js b/lib/commands/scan/delete.js similarity index 100% rename from lib/commands/fullscans/delete.js rename to lib/commands/scan/delete.js diff --git a/lib/commands/fullscans/index.js b/lib/commands/scan/index.js similarity index 100% rename from lib/commands/fullscans/index.js rename to lib/commands/scan/index.js diff --git a/lib/commands/fullscans/list.js b/lib/commands/scan/list.js similarity index 100% rename from lib/commands/fullscans/list.js rename to lib/commands/scan/list.js diff --git a/lib/commands/fullscans/metadata.js b/lib/commands/scan/metadata.js similarity index 100% rename from lib/commands/fullscans/metadata.js rename to lib/commands/scan/metadata.js diff --git a/lib/commands/fullscans/stream.js b/lib/commands/scan/stream.js similarity index 100% rename from lib/commands/fullscans/stream.js rename to lib/commands/scan/stream.js From a1ad56e8a696eea92e4d96fd9be4d666338b66ef Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 17 Jun 2024 11:48:50 -0700 Subject: [PATCH 16/21] update --- cli.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/cli.js b/cli.js index fa3c33fe..55c3728f 100755 --- a/cli.js +++ b/cli.js @@ -20,8 +20,6 @@ try { entry[0] = 'raw-npm' } else if (entry[0] === 'rawNpx') { entry[0] = 'raw-npx' - } else if (entry[0] === 'fullscans') { - entry[0] = 'scan' } return entry })) From ff8e9e71bb29dd20c4e73de8243304a843e92ced Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 17 Jun 2024 11:49:27 -0700 Subject: [PATCH 17/21] update --- lib/commands/scan/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commands/scan/index.js b/lib/commands/scan/index.js index 122581e2..6c9c6e21 100644 --- a/lib/commands/scan/index.js +++ b/lib/commands/scan/index.js @@ -8,7 +8,7 @@ import { meowWithSubcommands } from '../../utils/meow-with-subcommands.js' const description = 'Scans related commands' /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ -export const fullscans = { +export const scan = { description, run: async (argv, importMeta, { parentName }) => { await meowWithSubcommands( From dba8a8dc553cba5ac8e56ac0501fee6d345f5071 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 17 Jun 2024 11:50:49 -0700 Subject: [PATCH 18/21] fix --- lib/commands/scan/list.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/commands/scan/list.js b/lib/commands/scan/list.js index 7efd6b5e..5aae05f9 100644 --- a/lib/commands/scan/list.js +++ b/lib/commands/scan/list.js @@ -155,8 +155,6 @@ function setupCommand (name, description, argv, importMeta) { */ async function listOrgFullScan (orgSlug, input, spinner) { const socketSdk = await setupSdk(getDefaultKey()) - console.log(input) - // @ts-ignore const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, input), 'Listing scans') if (!result.success) { From 0e9b16e2292a53cce6ea4a302a4b93c3907f3e9c Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 17 Jun 2024 12:17:48 -0700 Subject: [PATCH 19/21] update --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 3f0601e6..7229c35e 100644 --- a/package.json +++ b/package.json @@ -85,8 +85,9 @@ "@apideck/better-ajv-errors": "^0.3.6", "@cyclonedx/cdxgen": "^10.5.2", "@socketsecurity/config": "^2.1.3", - "@socketsecurity/sdk": "^0.8.1", + "@socketsecurity/sdk": "^1.0.1", "chalk": "^5.3.0", + "chalk-table": "^1.0.2", "execa": "^9.1.0", "globby": "^14.0.1", "hpagent": "^1.2.0", @@ -95,6 +96,7 @@ "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "meow": "^13.2.0", + "open": "^10.1.0", "ora": "^8.0.1", "pony-cause": "^2.1.11", "prompts": "^2.4.2", From 09494b21e4bd8a881fc81078dd00d24148f3639e Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 17 Jun 2024 12:18:48 -0700 Subject: [PATCH 20/21] fix --- lib/commands/scan/create.js | 2 +- lib/commands/scan/delete.js | 2 +- lib/commands/scan/index.js | 2 +- lib/commands/scan/list.js | 2 +- lib/commands/scan/metadata.js | 2 +- lib/commands/scan/stream.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/commands/scan/create.js b/lib/commands/scan/create.js index a8babb43..09093213 100644 --- a/lib/commands/scan/create.js +++ b/lib/commands/scan/create.js @@ -16,7 +16,7 @@ import { createDebugLogger } from '../../utils/misc.js' import { getPackageFilesFullScans } from '../../utils/path-resolve.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' -/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +/** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */ export const create = { description: 'Create a scan', async run (argv, importMeta, { parentName }) { diff --git a/lib/commands/scan/delete.js b/lib/commands/scan/delete.js index 105d5314..c5f5918c 100644 --- a/lib/commands/scan/delete.js +++ b/lib/commands/scan/delete.js @@ -9,7 +9,7 @@ import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-he import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' -/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +/** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */ export const del = { description: 'Delete a scan', async run (argv, importMeta, { parentName }) { diff --git a/lib/commands/scan/index.js b/lib/commands/scan/index.js index 6c9c6e21..916aac09 100644 --- a/lib/commands/scan/index.js +++ b/lib/commands/scan/index.js @@ -7,7 +7,7 @@ import { meowWithSubcommands } from '../../utils/meow-with-subcommands.js' const description = 'Scans related commands' -/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +/** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */ export const scan = { description, run: async (argv, importMeta, { parentName }) => { diff --git a/lib/commands/scan/list.js b/lib/commands/scan/list.js index 5aae05f9..857156e6 100644 --- a/lib/commands/scan/list.js +++ b/lib/commands/scan/list.js @@ -12,7 +12,7 @@ import { prepareFlags } from '../../utils/flags.js' import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' -/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +/** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */ export const list = { description: 'List scans for an organization', async run (argv, importMeta, { parentName }) { diff --git a/lib/commands/scan/metadata.js b/lib/commands/scan/metadata.js index a9180b06..8b8c4290 100644 --- a/lib/commands/scan/metadata.js +++ b/lib/commands/scan/metadata.js @@ -9,7 +9,7 @@ import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-he import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' -/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +/** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */ export const metadata = { description: 'Get a scan\'s metadata', async run (argv, importMeta, { parentName }) { diff --git a/lib/commands/scan/stream.js b/lib/commands/scan/stream.js index e27a3434..a9f41ba3 100644 --- a/lib/commands/scan/stream.js +++ b/lib/commands/scan/stream.js @@ -9,7 +9,7 @@ import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-he import { printFlagList } from '../../utils/formatting.js' import { getDefaultKey, setupSdk } from '../../utils/sdk.js' -/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */ +/** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */ export const stream = { description: 'Stream the output of a scan', async run (argv, importMeta, { parentName }) { From bda2506eca65c4a45dc7e4366abd30a892ef5534 Mon Sep 17 00:00:00 2001 From: Charlie Gerard Date: Mon, 17 Jun 2024 12:20:38 -0700 Subject: [PATCH 21/21] revert --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7229c35e..55752b48 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "check:installed-check": "installed-check -i eslint-plugin-jsdoc", "check:lint": "eslint --report-unused-disable-directives .", "check:tsc": "tsc", - "check:type-coverage": "type-coverage --detail --strict --at-least 90 --ignore-files 'test/*'", + "check:type-coverage": "type-coverage --detail --strict --at-least 95 --ignore-files 'test/*'", "check": "run-p -c --aggregate-output check:*", "prepare": "husky install", "test:unit": "c8 --reporter=lcov --reporter text node --test",