Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/commands/fix/cmd-fix.mts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ Available styles:
default: '',
description: 'Path to store upgrades as a JSON file at this path.',
},
minimumReleaseAge: {
type: 'string',
default: '',
description:
'Set a minimum age requirement for suggested upgrade versions (e.g., 1h, 2d, 3w). A higher age requirement reduces the risk of upgrading to malicious versions. For example, setting the value to 1 week (1w) gives ecosystem maintainers one week to remove potentially malicious versions.',
},
}

const hiddenFlags: MeowFlags = {
Expand Down Expand Up @@ -224,6 +230,7 @@ async function run(
limit,
markdown,
maxSatisfying,
minimumReleaseAge,
outputFile,
prCheck,
rangeStyle,
Expand All @@ -243,6 +250,7 @@ async function run(
rangeStyle: RangeStyle
unknownFlags?: string[]
outputFile: string
minimumReleaseAge: string
}

const dryRun = !!cli.flags['dryRun']
Expand Down Expand Up @@ -306,6 +314,7 @@ async function run(
ghsas,
glob,
limit,
minimumReleaseAge,
minSatisfying,
prCheck,
orgSlug,
Expand Down
1 change: 1 addition & 0 deletions src/commands/fix/cmd-fix.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ describe('socket fix', async () => {
--json Output as JSON
--limit The number of fixes to attempt at a time (default 10)
--markdown Output as Markdown
--minimum-release-age Set a minimum age requirement for suggested upgrade versions (e.g., 1h, 2d, 3w). A higher age requirement reduces the risk of upgrading to malicious versions. For example, setting the value to 1 week (1w) gives ecosystem maintainers one week to remove potentially malicious versions.
--no-apply-fixes Compute fixes only, do not apply them. Logs what upgrades would be applied. If combined with --output-file, the output file will contain the upgrades that would be applied.
--output-file Path to store upgrades as a JSON file at this path.
--range-style Define how dependency version ranges are updated in package.json (default 'preserve').
Expand Down
10 changes: 10 additions & 0 deletions src/commands/fix/coana-fix.mts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export async function coanaFix(
ghsas,
glob,
limit,
minimumReleaseAge,
orgSlug,
outputFile,
spinner,
Expand Down Expand Up @@ -142,6 +143,9 @@ export async function coanaFix(
...(fixConfig.rangeStyle
? ['--range-style', fixConfig.rangeStyle]
: []),
...(minimumReleaseAge
? ['--minimum-release-age', minimumReleaseAge]
: []),
...(glob ? ['--glob', glob] : []),
...(!applyFixes ? [FLAG_DRY_RUN] : []),
...(outputFile ? ['--output-file', outputFile] : []),
Expand Down Expand Up @@ -194,6 +198,9 @@ export async function coanaFix(
...(fixConfig.rangeStyle
? ['--range-style', fixConfig.rangeStyle]
: []),
...(minimumReleaseAge
? ['--minimum-release-age', minimumReleaseAge]
: []),
...(glob ? ['--glob', glob] : []),
...fixConfig.unknownFlags,
],
Expand Down Expand Up @@ -251,6 +258,9 @@ export async function coanaFix(
...(fixConfig.rangeStyle
? ['--range-style', fixConfig.rangeStyle]
: []),
...(minimumReleaseAge
? ['--minimum-release-age', minimumReleaseAge]
: []),
...(glob ? ['--glob', glob] : []),
...fixConfig.unknownFlags,
],
Expand Down
3 changes: 3 additions & 0 deletions src/commands/fix/handle-fix.mts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type HandleFixConfig = Remap<
outputKind: OutputKind
unknownFlags: string[]
outputFile: string
minimumReleaseAge: string
}
>

Expand Down Expand Up @@ -105,6 +106,7 @@ export async function handleFix({
glob,
limit,
minSatisfying,
minimumReleaseAge,
orgSlug,
outputFile,
outputKind,
Expand Down Expand Up @@ -138,6 +140,7 @@ export async function handleFix({
ghsas: await convertIdsToGhsas(ghsas),
glob,
limit,
minimumReleaseAge,
minSatisfying,
orgSlug,
prCheck,
Expand Down
1 change: 1 addition & 0 deletions src/commands/fix/types.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type FixConfig = {
ghsas: string[]
glob: string
limit: number
minimumReleaseAge: string
minSatisfying: boolean
orgSlug: string
prCheck: boolean
Expand Down
23 changes: 23 additions & 0 deletions src/utils/dlx.mts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import { createRequire } from 'node:module'

import { getOwn } from '@socketsecurity/registry/lib/objects'
import { spawn } from '@socketsecurity/registry/lib/spawn'

import { getDefaultOrgSlug } from '../commands/ci/fetch-default-org-slug.mts'
import constants, {
Expand Down Expand Up @@ -168,6 +169,9 @@ export async function spawnDlx(
* Helper to spawn coana with dlx.
* Automatically uses force and silent when version is not pinned exactly.
* Returns a CResult with stdout extraction for backward compatibility.
*
* If SOCKET_CLI_COANA_LOCAL_PATH environment variable is set, uses the local
* Coana CLI at that path instead of downloading from npm.
*/
export async function spawnCoanaDlx(
args: string[] | readonly string[],
Expand Down Expand Up @@ -207,6 +211,25 @@ export async function spawnCoanaDlx(
}

try {
const localCoanaPath = process.env['SOCKET_CLI_COANA_LOCAL_PATH']
// Use local Coana CLI if path is provided.
if (localCoanaPath) {
const finalEnv = {
...process.env,
...constants.processEnv,
...mixinsEnv,
...spawnEnv,
}
const spawnResult = await spawn('node', [localCoanaPath, ...args], {
cwd: dlxOptions.cwd,
env: finalEnv,
stdio: spawnExtra?.['stdio'] || 'inherit',
})

return { ok: true, data: spawnResult.stdout }
}

// Use npm/dlx version.
const result = await spawnDlx(
{
name: '@coana-tech/cli',
Expand Down
Loading