@socketsecurity/cli 0.8.2 → 0.9.3

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.
package/README.md CHANGED
@@ -18,6 +18,7 @@ socket --help
18
18
  socket info webtorrent@1.9.1
19
19
  socket report create package.json --view
20
20
  socket report view QXU8PmK7LfH608RAwfIKdbcHgwEd_ZeWJ9QEGv05FJUQ
21
+ socket wrapper --enable
21
22
  ```
22
23
 
23
24
  ## Commands
@@ -35,6 +36,10 @@ socket report view QXU8PmK7LfH608RAwfIKdbcHgwEd_ZeWJ9QEGv05FJUQ
35
36
 
36
37
  * `socket report view <report-id>` - looks up issues and scores from a report
37
38
 
39
+ * `socket wrapper --enable` and `socket wrapper --disable` - Enables and disables the Socket 'safe-npm' wrapper.
40
+
41
+ * `socket raw-npm` and `socket raw-npx` - Temporarily disables the Socket 'safe-npm' wrapper.
42
+
38
43
  ## Aliases
39
44
 
40
45
  All aliases supports flags and arguments of the commands they alias.
package/cli.js CHANGED
@@ -15,8 +15,17 @@ import { initUpdateNotifier } from './lib/utils/update-notifier.js'
15
15
  initUpdateNotifier()
16
16
 
17
17
  try {
18
+ const formattedCliCommands = Object.fromEntries(Object.entries(cliCommands).map((entry) => {
19
+ if (entry[0] === 'rawNpm') {
20
+ entry[0] = 'raw-npm'
21
+ } else if (entry[0] === 'rawNpx') {
22
+ entry[0] = 'raw-npx'
23
+ }
24
+ return entry
25
+ }))
26
+
18
27
  await meowWithSubcommands(
19
- cliCommands,
28
+ formattedCliCommands,
20
29
  {
21
30
  aliases: {
22
31
  ci: {
@@ -4,3 +4,6 @@ export * from './npm/index.js'
4
4
  export * from './npx/index.js'
5
5
  export * from './login/index.js'
6
6
  export * from './logout/index.js'
7
+ export * from './wrapper/index.js'
8
+ export * from './raw-npm/index.js'
9
+ export * from './raw-npx/index.js'
@@ -20,10 +20,13 @@ export const info = {
20
20
  const name = parentName + ' info'
21
21
 
22
22
  const input = setupCommand(name, info.description, argv, importMeta)
23
- const packageData = input && await fetchPackageData(input.pkgName, input.pkgVersion, input)
24
-
25
- if (packageData) {
26
- formatPackageDataOutput(packageData, { name, ...input })
23
+ if (input) {
24
+ const spinnerText = input.pkgVersion === 'latest' ? `Looking up data for the latest version of ${input.pkgName}\n` : `Looking up data for version ${input.pkgVersion} of ${input.pkgName}\n`
25
+ const spinner = ora(spinnerText).start()
26
+ const packageData = await fetchPackageData(input.pkgName, input.pkgVersion, input, spinner)
27
+ if (packageData) {
28
+ formatPackageDataOutput(packageData, { name, ...input }, spinner)
29
+ }
27
30
  }
28
31
  }
29
32
  }
@@ -90,16 +93,8 @@ function setupCommand (name, description, argv, importMeta) {
90
93
 
91
94
  const versionSeparator = rawPkgName.lastIndexOf('@')
92
95
 
93
- if (versionSeparator < 1) {
94
- throw new InputError('Need to specify a full package identifier, like eg: webtorrent@1.0.0')
95
- }
96
-
97
- const pkgName = rawPkgName.slice(0, versionSeparator)
98
- const pkgVersion = rawPkgName.slice(versionSeparator + 1)
99
-
100
- if (!pkgVersion) {
101
- throw new InputError('Need to specify a version, like eg: webtorrent@1.0.0')
102
- }
96
+ const pkgName = versionSeparator < 1 ? rawPkgName : rawPkgName.slice(0, versionSeparator)
97
+ const pkgVersion = versionSeparator < 1 ? 'latest' : rawPkgName.slice(versionSeparator + 1)
103
98
 
104
99
  return {
105
100
  includeAllIssues,
@@ -115,53 +110,78 @@ function setupCommand (name, description, argv, importMeta) {
115
110
  * @typedef PackageData
116
111
  * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'getIssuesByNPMPackage'>["data"]} data
117
112
  * @property {Record<import('../../utils/format-issues').SocketIssue['severity'], number>} severityCount
113
+ * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'getScoreByNPMPackage'>["data"]} score
118
114
  */
119
115
 
120
116
  /**
121
117
  * @param {string} pkgName
122
118
  * @param {string} pkgVersion
123
- * @param {Pick<CommandContext, 'includeAllIssues' | 'strict'>} context
119
+ * @param {Pick<CommandContext, 'includeAllIssues'>} context
120
+ * @param {import('ora').Ora} spinner
124
121
  * @returns {Promise<void|PackageData>}
125
122
  */
126
- async function fetchPackageData (pkgName, pkgVersion, { includeAllIssues, strict }) {
123
+ async function fetchPackageData (pkgName, pkgVersion, { includeAllIssues }, spinner) {
127
124
  const socketSdk = await setupSdk(getDefaultKey() || FREE_API_KEY)
128
- const spinner = ora(`Looking up data for version ${pkgVersion} of ${pkgName}`).start()
129
125
  const result = await handleApiCall(socketSdk.getIssuesByNPMPackage(pkgName, pkgVersion), 'looking up package')
126
+ const scoreResult = await handleApiCall(socketSdk.getScoreByNPMPackage(pkgName, pkgVersion), 'looking up package score')
130
127
 
131
128
  if (result.success === false) {
132
129
  return handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result, spinner)
133
130
  }
134
131
 
135
- // Conclude the status of the API call
132
+ if (scoreResult.success === false) {
133
+ return handleUnsuccessfulApiResponse('getScoreByNPMPackage', scoreResult, spinner)
134
+ }
136
135
 
136
+ // Conclude the status of the API call
137
137
  const severityCount = getSeverityCount(result.data, includeAllIssues ? undefined : 'high')
138
138
 
139
- if (objectSome(severityCount)) {
140
- const issueSummary = formatSeverityCount(severityCount)
141
- spinner[strict ? 'fail' : 'succeed'](`Package has these issues: ${issueSummary}`)
142
- } else {
143
- spinner.succeed('Package has no issues')
144
- }
145
-
146
139
  return {
147
140
  data: result.data,
148
141
  severityCount,
142
+ score: scoreResult.data
149
143
  }
150
144
  }
151
145
 
152
146
  /**
153
147
  * @param {PackageData} packageData
154
148
  * @param {{ name: string } & CommandContext} context
149
+ * @param {import('ora').Ora} spinner
155
150
  * @returns {void}
156
151
  */
157
- function formatPackageDataOutput ({ data, severityCount }, { name, outputJson, outputMarkdown, pkgName, pkgVersion, strict }) {
152
+ function formatPackageDataOutput ({ data, severityCount, score }, { name, outputJson, outputMarkdown, pkgName, pkgVersion, strict }, spinner) {
158
153
  if (outputJson) {
159
154
  console.log(JSON.stringify(data, undefined, 2))
160
155
  } else {
156
+ console.log('\nPackage report card:')
157
+ const scoreResult = {
158
+ 'Supply Chain Risk': Math.floor(score.supplyChainRisk.score * 100),
159
+ 'Maintenance': Math.floor(score.maintenance.score * 100),
160
+ 'Quality': Math.floor(score.quality.score * 100),
161
+ 'Vulnerabilities': Math.floor(score.vulnerability.score * 100),
162
+ 'License': Math.floor(score.license.score * 100)
163
+ }
164
+ Object.entries(scoreResult).map(score => console.log(`- ${score[0]}: ${formatScore(score[1])}`))
165
+
166
+ // Package issues list
167
+ if (objectSome(severityCount)) {
168
+ const issueSummary = formatSeverityCount(severityCount)
169
+ console.log('\n')
170
+ spinner[strict ? 'fail' : 'succeed'](`Package has these issues: ${issueSummary}`)
171
+ formatPackageIssuesDetails(data, outputMarkdown)
172
+ } else {
173
+ console.log('\n')
174
+ spinner.succeed('Package has no issues')
175
+ }
176
+
177
+ // Link to issues list
161
178
  const format = new ChalkOrMarkdown(!!outputMarkdown)
162
179
  const url = `https://socket.dev/npm/package/${pkgName}/overview/${pkgVersion}`
163
-
164
- console.log('\nDetailed info on socket.dev: ' + format.hyperlink(`${pkgName} v${pkgVersion}`, url, { fallbackToUrl: true }))
180
+ if (pkgVersion === 'latest') {
181
+ console.log('\nDetailed info on socket.dev: ' + format.hyperlink(`${pkgName}`, url, { fallbackToUrl: true }))
182
+ } else {
183
+ console.log('\nDetailed info on socket.dev: ' + format.hyperlink(`${pkgName} v${pkgVersion}`, url, { fallbackToUrl: true }))
184
+ }
165
185
  if (!outputMarkdown) {
166
186
  console.log(chalk.dim('\nOr rerun', chalk.italic(name), 'using the', chalk.italic('--json'), 'flag to get full JSON output'))
167
187
  }
@@ -171,3 +191,55 @@ async function fetchPackageData (pkgName, pkgVersion, { includeAllIssues, strict
171
191
  process.exit(1)
172
192
  }
173
193
  }
194
+
195
+ /**
196
+ * @param {import('@socketsecurity/sdk').SocketSdkReturnType<'getIssuesByNPMPackage'>["data"]} packageData
197
+ * @param {boolean} outputMarkdown
198
+ * @returns {void[]}
199
+ */
200
+ function formatPackageIssuesDetails (packageData, outputMarkdown) {
201
+ const issueDetails = packageData.filter(d => d.value?.severity === 'high' || d.value?.severity === 'critical')
202
+
203
+ const uniqueIssues = issueDetails.reduce((/** @type {{ [key: string]: {count: Number, label: string | undefined} }} */ acc, issue) => {
204
+ const { type } = issue
205
+ if (type) {
206
+ if (!acc[type]) {
207
+ acc[type] = {
208
+ label: issue.value?.label,
209
+ count: 1
210
+ }
211
+ } else {
212
+ // @ts-ignore
213
+ acc[type].count += 1
214
+ }
215
+ }
216
+ return acc
217
+ }, {})
218
+
219
+ const format = new ChalkOrMarkdown(!!outputMarkdown)
220
+ return Object.keys(uniqueIssues).map(issue => {
221
+ const issueWithLink = format.hyperlink(`${uniqueIssues[issue]?.label}`, `https://socket.dev/npm/issue/${issue}`, { fallbackToUrl: true })
222
+ if (uniqueIssues[issue]?.count === 1) {
223
+ return console.log(`- ${issueWithLink}`)
224
+ }
225
+ return console.log(`- ${issueWithLink}: ${uniqueIssues[issue]?.count}`)
226
+ })
227
+ }
228
+
229
+ /**
230
+ * @param {number} score
231
+ * @returns {string}
232
+ */
233
+ function formatScore (score) {
234
+ const error = chalk.hex('#de7c7b')
235
+ const warning = chalk.hex('#e59361')
236
+ const success = chalk.hex('#a4cb9d')
237
+
238
+ if (score > 80) {
239
+ return `${success(score)}`
240
+ } else if (score < 80 && score > 60) {
241
+ return `${warning(score)}`
242
+ } else {
243
+ return `${error(score)}`
244
+ }
245
+ }
@@ -0,0 +1,59 @@
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
+ }
@@ -0,0 +1,59 @@
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
+ }
@@ -0,0 +1,199 @@
1
+ /* eslint-disable no-console */
2
+ import fs from 'fs'
3
+ import homedir from 'os'
4
+ import readline from 'readline'
5
+
6
+ import meow from 'meow'
7
+
8
+ import { commandFlags } from '../../flags/index.js'
9
+ import { printFlagList } from '../../utils/formatting.js'
10
+
11
+ const BASH_FILE = `${homedir.homedir()}/.bashrc`
12
+ const ZSH_BASH_FILE = `${homedir.homedir()}/.zshrc`
13
+
14
+ /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */
15
+ export const wrapper = {
16
+ description: 'Enable or disable the Socket npm/npx wrapper',
17
+ async run (argv, importMeta, { parentName }) {
18
+ const name = parentName + ' wrapper'
19
+
20
+ setupCommand(name, wrapper.description, argv, importMeta)
21
+ }
22
+ }
23
+
24
+ /**
25
+ * @param {string} name
26
+ * @param {string} description
27
+ * @param {readonly string[]} argv
28
+ * @param {ImportMeta} importMeta
29
+ * @returns {void}
30
+ */
31
+ function setupCommand (name, description, argv, importMeta) {
32
+ const flags = commandFlags
33
+
34
+ const cli = meow(`
35
+ Usage
36
+ $ ${name} <flag>
37
+
38
+ Options
39
+ ${printFlagList(flags, 6)}
40
+
41
+ Examples
42
+ $ ${name} --enable
43
+ $ ${name} --disable
44
+ `, {
45
+ argv,
46
+ description,
47
+ importMeta,
48
+ flags
49
+ })
50
+
51
+ const { enable, disable } = cli.flags
52
+
53
+ if (argv[0] === '--postinstall') {
54
+ // Check if the wrapper is already enabled before showing the postinstall prompt
55
+ const socketWrapperEnabled = (fs.existsSync(BASH_FILE) && checkSocketWrapperAlreadySetup(BASH_FILE)) || (fs.existsSync(ZSH_BASH_FILE) && checkSocketWrapperAlreadySetup(ZSH_BASH_FILE))
56
+
57
+ if (!socketWrapperEnabled) {
58
+ installSafeNpm(`The Socket CLI is now successfully installed! 🎉
59
+
60
+ To better protect yourself against supply-chain attacks, our "safe npm" wrapper can warn you about malicious packages whenever you run 'npm install'.
61
+
62
+ Do you want to install "safe npm" (this will create an alias to the socket-npm command)? (y/n)`)
63
+ }
64
+
65
+ return
66
+ }
67
+
68
+ if (!enable && !disable) {
69
+ cli.showHelp()
70
+ return
71
+ }
72
+
73
+ if (enable) {
74
+ if (fs.existsSync(BASH_FILE)) {
75
+ const socketWrapperEnabled = checkSocketWrapperAlreadySetup(BASH_FILE)
76
+ !socketWrapperEnabled && addAlias(BASH_FILE)
77
+ }
78
+ if (fs.existsSync(ZSH_BASH_FILE)) {
79
+ const socketWrapperEnabled = checkSocketWrapperAlreadySetup(ZSH_BASH_FILE)
80
+ !socketWrapperEnabled && addAlias(ZSH_BASH_FILE)
81
+ }
82
+ } else if (disable) {
83
+ if (fs.existsSync(BASH_FILE)) {
84
+ removeAlias(BASH_FILE)
85
+ }
86
+ if (fs.existsSync(ZSH_BASH_FILE)) {
87
+ removeAlias(ZSH_BASH_FILE)
88
+ }
89
+ }
90
+ if (!fs.existsSync(BASH_FILE) && !fs.existsSync(ZSH_BASH_FILE)) {
91
+ console.error('There was an issue setting up the alias in your bash profile')
92
+ }
93
+ return
94
+ }
95
+
96
+ /**
97
+ * @param {string} query
98
+ * @returns {void}
99
+ */
100
+ const installSafeNpm = (query) => {
101
+ console.log(`
102
+ _____ _ _
103
+ | __|___ ___| |_ ___| |_
104
+ |__ | . | _| '_| -_| _|
105
+ |_____|___|___|_,_|___|_|
106
+
107
+ `)
108
+
109
+ const rl = readline.createInterface({
110
+ input: process.stdin,
111
+ output: process.stdout,
112
+ })
113
+ return askQuestion(rl, query)
114
+ }
115
+
116
+ /**
117
+ * @param {any} rl
118
+ * @param {string} query
119
+ * @returns {void}
120
+ */
121
+ const askQuestion = (rl, query) => {
122
+ rl.question(query, (/** @type {string} */ ans) => {
123
+ if (ans.toLowerCase() === 'y') {
124
+ try {
125
+ if (fs.existsSync(BASH_FILE)) {
126
+ addAlias(BASH_FILE)
127
+ }
128
+ if (fs.existsSync(ZSH_BASH_FILE)) {
129
+ addAlias(ZSH_BASH_FILE)
130
+ }
131
+ } catch (e) {
132
+ throw new Error(`There was an issue setting up the alias: ${e}`)
133
+ }
134
+ rl.close()
135
+ } else if (ans.toLowerCase() !== 'n') {
136
+ askQuestion(rl, 'Incorrect input: please enter either y (yes) or n (no): ')
137
+ } else {
138
+ rl.close()
139
+ }
140
+ })
141
+ }
142
+
143
+ /**
144
+ * @param {string} file
145
+ * @returns {void}
146
+ */
147
+ const addAlias = (file) => {
148
+ return fs.appendFile(file, 'alias npm="socket npm"\nalias npx="socket npx"\n', (err) => {
149
+ if (err) {
150
+ return new Error(`There was an error setting up the alias: ${err}`)
151
+ }
152
+ console.log(`
153
+ The alias was added to ${file}. Running 'npm install' will now be wrapped in Socket's "safe npm" 🎉
154
+ If you want to disable it at any time, run \`socket wrapper --disable\`
155
+ `)
156
+ })
157
+ }
158
+
159
+ /**
160
+ * @param {string} file
161
+ * @returns {void}
162
+ */
163
+ const removeAlias = (file) => {
164
+ return fs.readFile(file, 'utf8', function (err, data) {
165
+ if (err) {
166
+ console.error(`There was an error removing the alias: ${err}`)
167
+ return
168
+ }
169
+ const linesWithoutSocketAlias = data.split('\n').filter(l => l !== 'alias npm="socket npm"' && l !== 'alias npx="socket npx"')
170
+
171
+ const updatedFileContent = linesWithoutSocketAlias.join('\n')
172
+
173
+ fs.writeFile(file, updatedFileContent, function (err) {
174
+ if (err) {
175
+ console.log(err)
176
+ return
177
+ } else {
178
+ console.log(`
179
+ The alias was removed from ${file}. Running 'npm install' will now run the standard npm command.
180
+ `)
181
+ }
182
+ })
183
+ })
184
+ }
185
+
186
+ /**
187
+ * @param {string} file
188
+ * @returns {boolean}
189
+ */
190
+ const checkSocketWrapperAlreadySetup = (file) => {
191
+ const fileContent = fs.readFileSync(file, 'utf-8')
192
+ const linesWithSocketAlias = fileContent.split('\n').filter(l => l === 'alias npm="socket npm"' || l === 'alias npx="socket npx"')
193
+
194
+ if (linesWithSocketAlias.length) {
195
+ console.log(`The Socket npm/npx wrapper is set up in your bash profile (${file}).`)
196
+ return true
197
+ }
198
+ return false
199
+ }
@@ -0,0 +1,14 @@
1
+ import { prepareFlags } from '../utils/flags.js'
2
+
3
+ export const commandFlags = prepareFlags({
4
+ enable: {
5
+ type: 'boolean',
6
+ default: false,
7
+ description: 'Enables the Socket npm/npx wrapper',
8
+ },
9
+ disable: {
10
+ type: 'boolean',
11
+ default: false,
12
+ description: 'Disables the Socket npm/npx wrapper',
13
+ }
14
+ })
@@ -1,2 +1,3 @@
1
1
  export { outputFlags } from './output.js'
2
2
  export { validationFlags } from './validation.js'
3
+ export { commandFlags } from './command.js'
@@ -101,7 +101,7 @@ export async function mapGlobEntryToFiles (entry, supportedFiles) {
101
101
  const pyFilePatterns = Object.values(supportedFiles['pypi'] || {})
102
102
  .map(p => `**/${/** @type {{ pattern: string }} */ (p).pattern}`)
103
103
 
104
- const goSupported = supportedFiles['go'] || {}
104
+ const goSupported = supportedFiles['golang'] || {}
105
105
  const goSupplementalPatterns = Object.values(goSupported)
106
106
  // .filter(key => key !== 'gomod')
107
107
  .map(p => `**/${/** @type {{ pattern: string }} */ (p).pattern}`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@socketsecurity/cli",
3
- "version": "0.8.2",
3
+ "version": "0.9.3",
4
4
  "description": "CLI tool for Socket.dev",
5
5
  "homepage": "http://github.com/SocketDev/socket-cli-js",
6
6
  "repository": {
@@ -40,7 +40,8 @@
40
40
  "prepare": "husky install",
41
41
  "test:unit": "c8 --reporter=lcov --reporter text node --test",
42
42
  "test-ci": "run-s test:*",
43
- "test": "run-s check test:*"
43
+ "test": "run-s check test:*",
44
+ "//postinstall": "node ./cli.js wrapper --postinstall"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@socketsecurity/eslint-config": "^3.0.1",
@@ -82,7 +83,7 @@
82
83
  "dependencies": {
83
84
  "@apideck/better-ajv-errors": "^0.3.6",
84
85
  "@socketsecurity/config": "^2.0.0",
85
- "@socketsecurity/sdk": "^0.7.2",
86
+ "@socketsecurity/sdk": "^0.7.3",
86
87
  "chalk": "^5.1.2",
87
88
  "globby": "^13.1.3",
88
89
  "hpagent": "^1.2.0",