3
3
import chalk from 'chalk'
4
4
import meow from 'meow'
5
5
import ora from 'ora'
6
- import { ErrorWithCause } from 'pony-cause'
7
6
7
+ import { handleApiCall , handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js'
8
8
import { ChalkOrMarkdown } from '../../utils/chalk-markdown.js'
9
- import { AuthError , InputError } from '../../utils/errors.js'
9
+ import { InputError } from '../../utils/errors.js'
10
10
import { getSeveritySummary } from '../../utils/format-issues.js'
11
11
import { printFlagList } from '../../utils/formatting.js'
12
12
import { setupSdk } from '../../utils/sdk.js'
13
13
14
- const description = 'Look up info regarding a package'
14
+ /** @type {import('../../utils/meow-with-subcommands').CliSubcommand } */
15
+ export const info = {
16
+ description : 'Look up info regarding a package' ,
17
+ async run ( argv , importMeta , { parentName } ) {
18
+ const name = parentName + ' info'
15
19
16
- /** @type {import('../../utils/meow-with-subcommands').CliSubcommandRun } */
17
- const run = async ( argv , importMeta , { parentName } ) => {
18
- const name = parentName + ' info'
20
+ const input = setupCommand ( name , info . description , argv , importMeta )
21
+ const result = input && await fetchPackageData ( input . pkgName , input . pkgVersion )
19
22
23
+ if ( result ) {
24
+ formatPackageDataOutput ( result . data , { name, ...input } )
25
+ }
26
+ }
27
+ }
28
+
29
+ // Internal functions
30
+
31
+ /**
32
+ * @param {string } name
33
+ * @param {string } description
34
+ * @param {readonly string[] } argv
35
+ * @param {ImportMeta } importMeta
36
+ * @returns {void|{ outputJson: boolean, outputMarkdown: boolean, pkgName: string, pkgVersion: string } }
37
+ */
38
+ function setupCommand ( name , description , argv , importMeta ) {
20
39
const cli = meow ( `
21
40
Usage
22
41
$ ${ name } <name>
23
42
24
43
Options
25
44
${ printFlagList ( {
26
- '--debug' : 'Output debug information' ,
27
45
'--json' : 'Output result as json' ,
28
46
'--markdown' : 'Output result as markdown' ,
29
47
} , 6 ) }
@@ -36,11 +54,6 @@ const run = async (argv, importMeta, { parentName }) => {
36
54
description,
37
55
importMeta,
38
56
flags : {
39
- debug : {
40
- type : 'boolean' ,
41
- alias : 'd' ,
42
- default : false ,
43
- } ,
44
57
json : {
45
58
type : 'boolean' ,
46
59
alias : 'j' ,
@@ -83,47 +96,56 @@ const run = async (argv, importMeta, { parentName }) => {
83
96
throw new InputError ( 'Need to specify a version, like eg: [email protected] ' )
84
97
}
85
98
86
- const socketSdk = await setupSdk ( )
99
+ return {
100
+ outputJson,
101
+ outputMarkdown,
102
+ pkgName,
103
+ pkgVersion
104
+ }
105
+ }
87
106
107
+ /**
108
+ * @param {string } pkgName
109
+ * @param {string } pkgVersion
110
+ * @returns {Promise<void|import('@socketsecurity/sdk').SocketSdkReturnType<'getIssuesByNPMPackage'>> }
111
+ */
112
+ async function fetchPackageData ( pkgName , pkgVersion ) {
113
+ const socketSdk = await setupSdk ( )
88
114
const spinner = ora ( `Looking up data for version ${ pkgVersion } of ${ pkgName } ` ) . start ( )
89
-
90
- /** @type {Awaited<ReturnType<typeof socketSdk.getIssuesByNPMPackage>> } */
91
- let result
92
-
93
- try {
94
- result = await socketSdk . getIssuesByNPMPackage ( pkgName , pkgVersion )
95
- } catch ( cause ) {
96
- spinner . fail ( )
97
- throw new ErrorWithCause ( 'Failed to look up package' , { cause } )
98
- }
115
+ const result = await handleApiCall ( socketSdk . getIssuesByNPMPackage ( pkgName , pkgVersion ) , spinner , 'looking up package' )
99
116
100
117
if ( result . success === false ) {
101
- if ( result . status === 401 || result . status === 403 ) {
102
- spinner . stop ( )
103
- throw new AuthError ( result . error . message )
104
- }
105
- spinner . fail ( chalk . white . bgRed ( 'API returned an error:' ) + ' ' + result . error . message )
106
- process . exit ( 1 )
118
+ return handleUnsuccessfulApiResponse ( result , spinner )
107
119
}
108
120
109
- const issueSummary = getSeveritySummary ( result . data )
121
+ // Conclude the status of the API call
110
122
123
+ const issueSummary = getSeveritySummary ( result . data )
111
124
spinner . succeed ( `Found ${ issueSummary || 'no' } issues for version ${ pkgVersion } of ${ pkgName } ` )
112
125
126
+ return result
127
+ }
128
+
129
+ /**
130
+ * @param {import('@socketsecurity/sdk').SocketSdkReturnType<'getIssuesByNPMPackage'>["data"] } data
131
+ * @param {{ name: string, outputJson: boolean, outputMarkdown: boolean, pkgName: string, pkgVersion: string } } context
132
+ * @returns {void }
133
+ */
134
+ function formatPackageDataOutput ( data , { name, outputJson, outputMarkdown, pkgName, pkgVersion } ) {
135
+ // If JSON, output and return...
136
+
113
137
if ( outputJson ) {
114
- console . log ( JSON . stringify ( result . data , undefined , 2 ) )
138
+ console . log ( JSON . stringify ( data , undefined , 2 ) )
115
139
return
116
140
}
117
141
142
+ // ...else do the CLI / Markdown output dance
143
+
118
144
const format = new ChalkOrMarkdown ( ! ! outputMarkdown )
119
145
const url = `https://socket.dev/npm/package/${ pkgName } /overview/${ pkgVersion } `
120
146
121
147
console . log ( '\nDetailed info on socket.dev: ' + format . hyperlink ( `${ pkgName } v${ pkgVersion } ` , url , { fallbackToUrl : true } ) )
122
-
123
148
if ( ! outputMarkdown ) {
124
149
console . log ( chalk . dim ( '\nOr rerun' , chalk . italic ( name ) , 'using the' , chalk . italic ( '--json' ) , 'flag to get full JSON output' ) )
125
150
}
126
151
}
127
-
128
- /** @type {import('../../utils/meow-with-subcommands').CliSubcommand } */
129
- export const info = { description, run }
0 commit comments