@socketsecurity/cli 0.10.1 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +22 -22
  2. package/bin/npm +2 -0
  3. package/bin/npx +2 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +3419 -0
  7. package/dist/errors.d.ts +7 -0
  8. package/dist/link.d.ts +2 -0
  9. package/dist/link.js +45 -0
  10. package/dist/npm-cli.d.ts +2 -0
  11. package/dist/npm-cli.js +84 -0
  12. package/dist/npm-injection.d.ts +1 -0
  13. package/dist/npm-injection.js +913 -0
  14. package/dist/npm-injection2.d.ts +25 -0
  15. package/dist/npm-injection2.js +899 -0
  16. package/dist/npx-cli.d.ts +2 -0
  17. package/dist/npx-cli.js +60 -0
  18. package/dist/path-resolve.d.ts +12 -0
  19. package/dist/path-resolve.js +139 -0
  20. package/dist/sdk.d.ts +27 -0
  21. package/dist/sdk.js +224 -0
  22. package/dist/settings.d.ts +9 -0
  23. package/dist/type-helpers.d.ts +3 -0
  24. package/dist/vendor.js +25421 -0
  25. package/package.json +105 -52
  26. package/{lib/shadow/translations.json → translations.json} +20 -20
  27. package/cli.js +0 -72
  28. package/lib/commands/audit-log/index.js +0 -162
  29. package/lib/commands/cdxgen/index.js +0 -211
  30. package/lib/commands/dependencies/index.js +0 -150
  31. package/lib/commands/index.js +0 -14
  32. package/lib/commands/info/index.js +0 -287
  33. package/lib/commands/login/index.js +0 -170
  34. package/lib/commands/logout/index.js +0 -35
  35. package/lib/commands/npm/index.js +0 -27
  36. package/lib/commands/npx/index.js +0 -22
  37. package/lib/commands/raw-npm/index.js +0 -59
  38. package/lib/commands/raw-npx/index.js +0 -59
  39. package/lib/commands/report/create.js +0 -251
  40. package/lib/commands/report/index.js +0 -24
  41. package/lib/commands/report/view.js +0 -176
  42. package/lib/commands/repos/create.js +0 -166
  43. package/lib/commands/repos/delete.js +0 -93
  44. package/lib/commands/repos/index.js +0 -30
  45. package/lib/commands/repos/list.js +0 -170
  46. package/lib/commands/repos/update.js +0 -166
  47. package/lib/commands/repos/view.js +0 -128
  48. package/lib/commands/scan/create.js +0 -245
  49. package/lib/commands/scan/delete.js +0 -112
  50. package/lib/commands/scan/index.js +0 -30
  51. package/lib/commands/scan/list.js +0 -192
  52. package/lib/commands/scan/metadata.js +0 -113
  53. package/lib/commands/scan/stream.js +0 -115
  54. package/lib/commands/wrapper/index.js +0 -199
  55. package/lib/flags/command.js +0 -14
  56. package/lib/flags/index.js +0 -3
  57. package/lib/flags/output.js +0 -16
  58. package/lib/flags/validation.js +0 -14
  59. package/lib/shadow/bin/npm +0 -2
  60. package/lib/shadow/bin/npx +0 -2
  61. package/lib/shadow/link.cjs +0 -50
  62. package/lib/shadow/npm-cli.cjs +0 -27
  63. package/lib/shadow/npm-injection.cjs +0 -649
  64. package/lib/shadow/npx-cli.cjs +0 -27
  65. package/lib/shadow/package.json +0 -3
  66. package/lib/shadow/tty-server.cjs +0 -222
  67. package/lib/shadow/update-notifier.mjs +0 -3
  68. package/lib/utils/api-helpers.js +0 -42
  69. package/lib/utils/chalk-markdown.js +0 -125
  70. package/lib/utils/errors.js +0 -14
  71. package/lib/utils/flags.js +0 -27
  72. package/lib/utils/format-issues.js +0 -99
  73. package/lib/utils/formatting.js +0 -47
  74. package/lib/utils/issue-rules.cjs +0 -180
  75. package/lib/utils/meow-with-subcommands.js +0 -87
  76. package/lib/utils/misc.js +0 -61
  77. package/lib/utils/path-resolve.js +0 -204
  78. package/lib/utils/sdk.js +0 -99
  79. package/lib/utils/settings.js +0 -69
  80. package/lib/utils/type-helpers.cjs +0 -13
  81. package/lib/utils/update-notifier.js +0 -18
@@ -1,170 +0,0 @@
1
- import isInteractive from 'is-interactive'
2
- import meow from 'meow'
3
- import ora from 'ora'
4
- import prompts from 'prompts'
5
- import terminalLink from 'terminal-link'
6
-
7
- import { AuthError, InputError } from '../../utils/errors.js'
8
- import { prepareFlags } from '../../utils/flags.js'
9
- import { printFlagList } from '../../utils/formatting.js'
10
- import { FREE_API_KEY, setupSdk } from '../../utils/sdk.js'
11
- import { getSetting, updateSetting } from '../../utils/settings.js'
12
-
13
- const description = 'Socket API login'
14
-
15
- /** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
16
- export const login = {
17
- description,
18
- run: async (argv, importMeta, { parentName }) => {
19
- const flags = prepareFlags({
20
- apiBaseUrl: {
21
- type: 'string',
22
- description: 'API server to connect to for login',
23
- },
24
- apiProxy: {
25
- type: 'string',
26
- description: 'Proxy to use when making connection to API server'
27
- }
28
- })
29
- const name = parentName + ' login'
30
- const cli = meow(`
31
- Usage
32
- $ ${name}
33
-
34
- Logs into the Socket API by prompting for an API key
35
-
36
- Options
37
- ${printFlagList({
38
- 'api-base-url': flags.apiBaseUrl.description,
39
- 'api-proxy': flags.apiProxy.description
40
- }, 8)}
41
-
42
- Examples
43
- $ ${name}
44
- `, {
45
- argv,
46
- description,
47
- importMeta,
48
- flags
49
- })
50
-
51
- /**
52
- * @param {{aborted: boolean}} state
53
- */
54
- const promptAbortHandler = (state) => {
55
- if (state.aborted) {
56
- process.nextTick(() => process.exit(1))
57
- }
58
- }
59
-
60
- if (cli.input.length) cli.showHelp()
61
-
62
- if (!isInteractive()) {
63
- throw new InputError('cannot prompt for credentials in a non-interactive shell')
64
- }
65
- /**
66
- * @type {{ apiKey: string }}
67
- */
68
- const result = await prompts({
69
- type: 'password',
70
- name: 'apiKey',
71
- message: `Enter your ${terminalLink(
72
- 'Socket.dev API key',
73
- 'https://docs.socket.dev/docs/api-keys'
74
- )} (leave blank for a public key)`,
75
- onState: promptAbortHandler
76
- })
77
-
78
- const apiKey = result.apiKey || FREE_API_KEY
79
-
80
- /**
81
- * @type {string | null | undefined}
82
- */
83
- let apiBaseUrl = cli.flags.apiBaseUrl
84
- apiBaseUrl ??= getSetting('apiBaseUrl') ??
85
- undefined
86
-
87
- /**
88
- * @type {string | null | undefined}
89
- */
90
- let apiProxy = cli.flags.apiProxy
91
- apiProxy ??= getSetting('apiProxy') ??
92
- undefined
93
-
94
- const spinner = ora('Verifying API key...').start()
95
-
96
- /** @type {import('@socketsecurity/sdk').SocketSdkReturnType<'getOrganizations'>['data']} */
97
- let orgs
98
-
99
- try {
100
- const sdk = await setupSdk(apiKey, apiBaseUrl, apiProxy)
101
- const result = await sdk.getOrganizations()
102
- if (!result.success) throw new AuthError()
103
- orgs = result.data
104
- spinner.succeed('API key verified\n')
105
- } catch (e) {
106
- spinner.fail('Invalid API key')
107
- return
108
- }
109
-
110
- /**
111
- * @template T
112
- * @param {T | null | undefined} value
113
- * @returns {value is T}
114
- */
115
- const nonNullish = value => value != null
116
-
117
- /** @type {prompts.Choice[]} */
118
- const enforcedChoices = Object.values(orgs.organizations)
119
- .filter(nonNullish)
120
- .filter(org => org.plan === 'enterprise')
121
- .map(org => ({
122
- title: org.name,
123
- value: org.id
124
- }))
125
-
126
- /** @type {string[]} */
127
- let enforcedOrgs = []
128
-
129
- if (enforcedChoices.length > 1) {
130
- /**
131
- * @type { {id: string} }
132
- */
133
- const { id } = await prompts({
134
- type: 'select',
135
- name: 'id',
136
- hint: '\n Pick "None" if this is a personal device',
137
- message: 'Which organization\'s policies should Socket enforce system-wide?',
138
- choices: enforcedChoices.concat({
139
- title: 'None',
140
- value: null
141
- }),
142
- onState: promptAbortHandler
143
- })
144
- if (id) enforcedOrgs = [id]
145
- } else if (enforcedChoices.length) {
146
- /**
147
- * @type { {confirmOrg: boolean} }
148
- */
149
- const { confirmOrg } = await prompts({
150
- type: 'confirm',
151
- name: 'confirmOrg',
152
- message: `Should Socket enforce ${enforcedChoices[0]?.title}'s security policies system-wide?`,
153
- initial: true,
154
- onState: promptAbortHandler
155
- })
156
- if (confirmOrg) {
157
- const existing = /** @type {undefined | {value: string}} */(enforcedChoices[0])
158
- if (existing) {
159
- enforcedOrgs = [existing.value]
160
- }
161
- }
162
- }
163
- // MUST DO all updateSetting ON SAME TICK TO AVOID PARTIAL WRITE
164
- updateSetting('enforcedOrgs', enforcedOrgs)
165
- const oldKey = getSetting('apiKey')
166
- updateSetting('apiKey', apiKey)
167
- updateSetting('apiBaseUrl', apiBaseUrl)
168
- spinner.succeed(`API credentials ${oldKey ? 'updated' : 'set'}`)
169
- }
170
- }
@@ -1,35 +0,0 @@
1
- import meow from 'meow'
2
- import ora from 'ora'
3
-
4
- import { updateSetting } from '../../utils/settings.js'
5
-
6
- const description = 'Socket API logout'
7
-
8
- /** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
9
- export const logout = {
10
- description,
11
- run: async (argv, importMeta, { parentName }) => {
12
- const name = parentName + ' logout'
13
- const cli = meow(`
14
- Usage
15
- $ ${name}
16
-
17
- Logs out of the Socket API and clears all Socket credentials from disk
18
-
19
- Examples
20
- $ ${name}
21
- `, {
22
- argv,
23
- description,
24
- importMeta,
25
- })
26
-
27
- if (cli.input.length) cli.showHelp()
28
-
29
- updateSetting('apiKey', null)
30
- updateSetting('apiBaseUrl', null)
31
- updateSetting('apiProxy', null)
32
- updateSetting('enforcedOrgs', null)
33
- ora('Successfully logged out').succeed()
34
- }
35
- }
@@ -1,27 +0,0 @@
1
- import { spawn, execSync } from 'child_process'
2
- import { fileURLToPath } from 'url'
3
-
4
- const description = 'npm wrapper functionality'
5
-
6
- /** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
7
- export const npm = {
8
- description,
9
- run: async (argv, _importMeta, _ctx) => {
10
- const npmVersion = execSync('npm -v').toString()
11
- const wrapperPath = fileURLToPath(new URL('../../shadow/npm-cli.cjs', import.meta.url))
12
- process.exitCode = 1
13
- spawn(process.execPath, [wrapperPath, ...argv], {
14
- stdio: 'inherit',
15
- env: {
16
- ...process.env,
17
- NPM_VERSION: npmVersion
18
- }
19
- }).on('exit', (code, signal) => {
20
- if (signal) {
21
- process.kill(process.pid, signal)
22
- } else if (code !== null) {
23
- process.exit(code)
24
- }
25
- })
26
- }
27
- }
@@ -1,22 +0,0 @@
1
- import { spawn } from 'child_process'
2
- import { fileURLToPath } from 'url'
3
-
4
- const description = 'npx wrapper functionality'
5
-
6
- /** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
7
- export const npx = {
8
- description,
9
- run: async (argv, _importMeta, _ctx) => {
10
- const wrapperPath = fileURLToPath(new URL('../../shadow/npx-cli.cjs', import.meta.url))
11
- process.exitCode = 1
12
- spawn(process.execPath, [wrapperPath, ...argv], {
13
- stdio: 'inherit'
14
- }).on('exit', (code, signal) => {
15
- if (signal) {
16
- process.kill(process.pid, signal)
17
- } else if (code !== null) {
18
- process.exit(code)
19
- }
20
- })
21
- }
22
- }
@@ -1,59 +0,0 @@
1
- import { spawn } from 'child_process'
2
-
3
- import meow from 'meow'
4
-
5
- import { validationFlags } from '../../flags/index.js'
6
- import { printFlagList } from '../../utils/formatting.js'
7
-
8
- /** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
9
- export const rawNpm = {
10
- description: 'Temporarily disable the Socket npm wrapper',
11
- async run (argv, importMeta, { parentName }) {
12
- const name = parentName + ' raw-npm'
13
-
14
- setupCommand(name, rawNpm.description, argv, importMeta)
15
- }
16
- }
17
-
18
- /**
19
- * @param {string} name
20
- * @param {string} description
21
- * @param {readonly string[]} argv
22
- * @param {ImportMeta} importMeta
23
- * @returns {void}
24
- */
25
- function setupCommand (name, description, argv, importMeta) {
26
- const flags = validationFlags
27
-
28
- const cli = meow(`
29
- Usage
30
- $ ${name} <npm command>
31
-
32
- Options
33
- ${printFlagList(flags, 6)}
34
-
35
- Examples
36
- $ ${name} install
37
- `, {
38
- argv,
39
- description,
40
- importMeta,
41
- flags
42
- })
43
-
44
- if (!argv[0]) {
45
- cli.showHelp()
46
- return
47
- }
48
-
49
- spawn('npm', [argv.join(' ')], {
50
- stdio: 'inherit',
51
- shell: true
52
- }).on('exit', (code, signal) => {
53
- if (signal) {
54
- process.kill(process.pid, signal)
55
- } else if (code !== null) {
56
- process.exit(code)
57
- }
58
- })
59
- }
@@ -1,59 +0,0 @@
1
- import { spawn } from 'child_process'
2
-
3
- import meow from 'meow'
4
-
5
- import { validationFlags } from '../../flags/index.js'
6
- import { printFlagList } from '../../utils/formatting.js'
7
-
8
- /** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
9
- export const rawNpx = {
10
- description: 'Temporarily disable the Socket npm/npx wrapper',
11
- async run (argv, importMeta, { parentName }) {
12
- const name = parentName + ' raw-npx'
13
-
14
- setupCommand(name, rawNpx.description, argv, importMeta)
15
- }
16
- }
17
-
18
- /**
19
- * @param {string} name
20
- * @param {string} description
21
- * @param {readonly string[]} argv
22
- * @param {ImportMeta} importMeta
23
- * @returns {void}
24
- */
25
- function setupCommand (name, description, argv, importMeta) {
26
- const flags = validationFlags
27
-
28
- const cli = meow(`
29
- Usage
30
- $ ${name} <npx command>
31
-
32
- Options
33
- ${printFlagList(flags, 6)}
34
-
35
- Examples
36
- $ ${name} install
37
- `, {
38
- argv,
39
- description,
40
- importMeta,
41
- flags
42
- })
43
-
44
- if (!argv[0]) {
45
- cli.showHelp()
46
- return
47
- }
48
-
49
- spawn('npx', [argv.join(' ')], {
50
- stdio: 'inherit',
51
- shell: true
52
- }).on('exit', (code, signal) => {
53
- if (signal) {
54
- process.kill(process.pid, signal)
55
- } else if (code !== null) {
56
- process.exit(code)
57
- }
58
- })
59
- }
@@ -1,251 +0,0 @@
1
- /* eslint-disable no-console */
2
-
3
- import path from 'node:path'
4
-
5
- import { betterAjvErrors } from '@apideck/better-ajv-errors'
6
- import { readSocketConfig, SocketValidationError } from '@socketsecurity/config'
7
- import meow from 'meow'
8
- import ora from 'ora'
9
- import { ErrorWithCause } from 'pony-cause'
10
-
11
- import { fetchReportData, formatReportDataOutput } from './view.js'
12
- import { outputFlags, validationFlags } from '../../flags/index.js'
13
- import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js'
14
- import { ChalkOrMarkdown, logSymbols } from '../../utils/chalk-markdown.js'
15
- import { InputError } from '../../utils/errors.js'
16
- import { prepareFlags } from '../../utils/flags.js'
17
- import { printFlagList } from '../../utils/formatting.js'
18
- import { createDebugLogger } from '../../utils/misc.js'
19
- import { getPackageFiles } from '../../utils/path-resolve.js'
20
- import { setupSdk } from '../../utils/sdk.js'
21
-
22
- /** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
23
- export const create = {
24
- description: 'Create a project report',
25
- async run (argv, importMeta, { parentName }) {
26
- const name = parentName + ' create'
27
-
28
- const input = await setupCommand(name, create.description, argv, importMeta)
29
-
30
- if (input) {
31
- const {
32
- config,
33
- cwd,
34
- debugLog,
35
- dryRun,
36
- includeAllIssues,
37
- outputJson,
38
- outputMarkdown,
39
- packagePaths,
40
- strict,
41
- view,
42
- } = input
43
-
44
- const result = input && await createReport(packagePaths, { config, cwd, debugLog, dryRun })
45
-
46
- if (result && view) {
47
- const reportId = result.data.id
48
- const reportData = input && await fetchReportData(reportId, { includeAllIssues, strict })
49
-
50
- if (reportData) {
51
- formatReportDataOutput(reportData, { includeAllIssues, name, outputJson, outputMarkdown, reportId, strict })
52
- }
53
- } else if (result) {
54
- formatReportCreationOutput(result.data, { outputJson, outputMarkdown })
55
- }
56
- }
57
- }
58
- }
59
-
60
- // Internal functions
61
-
62
- /**
63
- * @typedef CommandContext
64
- * @property {import('@socketsecurity/config').SocketYml|undefined} config
65
- * @property {string} cwd
66
- * @property {typeof console.error} debugLog
67
- * @property {boolean} dryRun
68
- * @property {boolean} includeAllIssues
69
- * @property {boolean} outputJson
70
- * @property {boolean} outputMarkdown
71
- * @property {string[]} packagePaths
72
- * @property {boolean} strict
73
- * @property {boolean} view
74
- */
75
-
76
- /**
77
- * @param {string} name
78
- * @param {string} description
79
- * @param {readonly string[]} argv
80
- * @param {ImportMeta} importMeta
81
- * @returns {Promise<void|CommandContext>}
82
- */
83
- async function setupCommand (name, description, argv, importMeta) {
84
- const flags = prepareFlags({
85
- ...outputFlags,
86
- ...validationFlags,
87
- debug: {
88
- type: 'boolean',
89
- shortFlag: 'd',
90
- default: false,
91
- description: 'Output debug information',
92
- },
93
- dryRun: {
94
- type: 'boolean',
95
- default: false,
96
- description: 'Only output what will be done without actually doing it',
97
- },
98
- view: {
99
- type: 'boolean',
100
- shortFlag: 'v',
101
- default: false,
102
- description: 'Will wait for and return the created report'
103
- },
104
- })
105
-
106
- const cli = meow(`
107
- Usage
108
- $ ${name} <paths-to-package-folders-and-files>
109
-
110
- Uploads the specified "package.json" and lock files for JavaScript, Python, and Go dependency manifests.
111
- If any folder is specified, the ones found in there recursively are uploaded.
112
-
113
- Supports globbing such as "**/package.json", "**/requirements.txt", "**/pyproject.toml", and "**/go.mod".
114
-
115
- Ignores any file specified in your project's ".gitignore", your project's
116
- "socket.yml" file's "projectIgnorePaths" and also has a sensible set of
117
- default ignores from the "ignore-by-default" module.
118
-
119
- Options
120
- ${printFlagList({
121
- 'all': 'Include all issues',
122
- 'debug': 'Output debug information',
123
- 'dry-run': 'Only output what will be done without actually doing it',
124
- 'json': 'Output result as json',
125
- 'markdown': 'Output result as markdown',
126
- 'strict': 'Exits with an error code if any matching issues are found',
127
- 'view': 'Will wait for and return the created report'
128
- }, 6)}
129
-
130
- Examples
131
- $ ${name} .
132
- $ ${name} '**/package.json'
133
- $ ${name} /path/to/a/package.json /path/to/another/package.json
134
- $ ${name} . --view --json
135
- `, {
136
- argv,
137
- description,
138
- importMeta,
139
- flags,
140
- })
141
-
142
- const {
143
- all: includeAllIssues,
144
- dryRun,
145
- json: outputJson,
146
- markdown: outputMarkdown,
147
- strict,
148
- view,
149
- } = cli.flags
150
-
151
- if (!cli.input[0]) {
152
- cli.showHelp()
153
- return
154
- }
155
-
156
- const debugLog = createDebugLogger(dryRun || cli.flags.debug)
157
-
158
- // TODO: Allow setting a custom cwd and/or configFile path?
159
- const cwd = process.cwd()
160
- const absoluteConfigPath = path.join(cwd, 'socket.yml')
161
-
162
- const config = await readSocketConfig(absoluteConfigPath)
163
- .catch(/** @param {unknown} cause */ cause => {
164
- if (cause && typeof cause === 'object' && cause instanceof SocketValidationError) {
165
- // Inspired by workbox-build: https://github.com/GoogleChrome/workbox/blob/95f97a207fd51efb3f8a653f6e3e58224183a778/packages/workbox-build/src/lib/validate-options.ts#L68-L71
166
- const betterErrors = betterAjvErrors({
167
- basePath: 'config',
168
- data: cause.data,
169
- errors: cause.validationErrors,
170
- // @ts-ignore
171
- schema: cause.schema,
172
- })
173
- throw new InputError(
174
- 'The socket.yml config is not valid',
175
- betterErrors.map((err) => `[${err.path}] ${err.message}.${err.suggestion ? err.suggestion : ''}`).join('\n')
176
- )
177
- } else {
178
- throw new ErrorWithCause('Failed to read socket.yml config', { cause })
179
- }
180
- })
181
-
182
- const socketSdk = await setupSdk()
183
- const supportedFiles = await socketSdk.getReportSupportedFiles()
184
- .then(res => {
185
- if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res, ora())
186
- return res.data
187
- }).catch(
188
- /** @type {(cause: Error) => never} */
189
- (cause) => {
190
- throw new ErrorWithCause('Failed getting supported files for report', { cause })
191
- })
192
-
193
- const packagePaths = await getPackageFiles(cwd, cli.input, config, supportedFiles, debugLog)
194
-
195
- return {
196
- config,
197
- cwd,
198
- debugLog,
199
- dryRun,
200
- includeAllIssues,
201
- outputJson,
202
- outputMarkdown,
203
- packagePaths,
204
- strict,
205
- view,
206
- }
207
- }
208
-
209
- /**
210
- * @param {string[]} packagePaths
211
- * @param {Pick<CommandContext, 'config' | 'cwd' | 'debugLog' | 'dryRun'>} context
212
- * @returns {Promise<void|import('@socketsecurity/sdk').SocketSdkReturnType<'createReport'>>}
213
- */
214
- async function createReport (packagePaths, { config, cwd, debugLog, dryRun }) {
215
- debugLog('Uploading:', packagePaths.join(`\n${logSymbols.info} Uploading: `))
216
-
217
- if (dryRun) {
218
- return
219
- }
220
-
221
- const socketSdk = await setupSdk()
222
- const spinner = ora(`Creating report with ${packagePaths.length} package files`).start()
223
- const apiCall = socketSdk.createReportFromFilePaths(packagePaths, cwd, config?.issueRules)
224
- const result = await handleApiCall(apiCall, 'creating report')
225
-
226
- if (result.success === false) {
227
- return handleUnsuccessfulApiResponse('createReport', result, spinner)
228
- }
229
-
230
- // Conclude the status of the API call
231
-
232
- spinner.succeed()
233
-
234
- return result
235
- }
236
-
237
- /**
238
- * @param {import('@socketsecurity/sdk').SocketSdkReturnType<'createReport'>["data"]} data
239
- * @param {Pick<CommandContext, 'outputJson' | 'outputMarkdown'>} context
240
- * @returns {void}
241
- */
242
- function formatReportCreationOutput (data, { outputJson, outputMarkdown }) {
243
- if (outputJson) {
244
- console.log(JSON.stringify(data, undefined, 2))
245
- return
246
- }
247
-
248
- const format = new ChalkOrMarkdown(!!outputMarkdown)
249
-
250
- console.log('\nNew report: ' + format.hyperlink(data.id, data.url, { fallbackToUrl: true }))
251
- }
@@ -1,24 +0,0 @@
1
- import { create } from './create.js'
2
- import { view } from './view.js'
3
- import { meowWithSubcommands } from '../../utils/meow-with-subcommands.js'
4
-
5
- const description = 'Project report related commands'
6
-
7
- /** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
8
- export const report = {
9
- description,
10
- run: async (argv, importMeta, { parentName }) => {
11
- await meowWithSubcommands(
12
- {
13
- create,
14
- view,
15
- },
16
- {
17
- argv,
18
- description,
19
- importMeta,
20
- name: parentName + ' report',
21
- }
22
- )
23
- }
24
- }