Skip to content

Commit 3a31573

Browse files
committed
Revert "fix(lint): resolve lint errors and remove dead getInternals code"
This reverts commit 7cfefac.
1 parent 7cfefac commit 3a31573

File tree

8 files changed

+112
-24
lines changed

8 files changed

+112
-24
lines changed

packages/cli/.config/eslint.config.mjs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -365,23 +365,16 @@ export default [
365365
},
366366
},
367367
{
368-
// Relax rules for script and config files
369-
files: [
370-
'scripts/**/*.{mjs,js}',
371-
'bin/**/*.{mjs,js}',
372-
'.config/**/*.{mjs,js}',
373-
],
368+
// Relax rules for script files
369+
files: ['scripts/**/*.{mjs,js}', 'bin/**/*.{mjs,js}'],
374370
rules: {
375-
'n/no-extraneous-import': 'off',
376-
'n/no-extraneous-require': 'off',
377371
'n/no-process-exit': 'off',
378372
'n/no-unsupported-features/node-builtins': 'off',
379373
'n/no-missing-import': 'off',
380374
'import-x/no-unresolved': 'off',
381375
'no-await-in-loop': 'off',
382376
'no-unused-vars': 'off',
383377
'no-undef': 'off',
384-
'unicorn/consistent-function-scoping': 'off',
385378
},
386379
},
387380
{
@@ -406,10 +399,6 @@ export default [
406399
'no-undef': 'off',
407400
// Allow console in tests
408401
'no-console': 'off',
409-
// Allow process.exit in tests
410-
'n/no-process-exit': 'off',
411-
// Allow scoped functions in tests
412-
'unicorn/consistent-function-scoping': 'off',
413402
},
414403
},
415404
]

packages/cli/src/constants.mts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ import {
248248
REPORT_LEVEL_WARN,
249249
} from './constants/reporting.mts'
250250
import {
251+
getInternals,
251252
getShadowNpmBinPath as SHADOW_getShadowNpmBinPath,
252253
getShadowNpxBinPath as SHADOW_getShadowNpxBinPath,
253254
getShadowPnpmBinPath as SHADOW_getShadowPnpmBinPath,
@@ -368,6 +369,7 @@ export {
368369
getExecPath,
369370
getGithubCachePath,
370371
getInstrumentWithSentryPath,
372+
getInternals,
371373
getMinimumVersionByAgent,
372374
getNmBunPath,
373375
getNmNodeGypPath,
@@ -619,6 +621,7 @@ export default {
619621
getExecPath,
620622
getGithubCachePath,
621623
getInstrumentWithSentryPath,
624+
getInternals,
622625
getMinimumVersionByAgent,
623626
getNmBunPath,
624627
getNmNodeGypPath,

packages/cli/src/constants/shadow.mts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ export const SOCKET_CLI_SHADOW_SILENT = 'SOCKET_CLI_SHADOW_SILENT'
3030
export const SOCKET_CLI_ACCEPT_RISKS = 'SOCKET_CLI_ACCEPT_RISKS'
3131
export const SOCKET_CLI_VIEW_ALL_RISKS = 'SOCKET_CLI_VIEW_ALL_RISKS'
3232

33+
/**
34+
* Get registry internals for accessing IPC and Sentry instances.
35+
*/
36+
export function getInternals(): RegistryInternals {
37+
const registry = require('@socketsecurity/registry')
38+
return registry.internals ?? {}
39+
}
40+
3341
/**
3442
* Get the path to the shadow npm binary.
3543
*/

packages/cli/src/shadow/npm/arborist/lib/arborist/index.mts

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ import { NPX } from '../../../../../constants/agents.mts'
1010
import ENV from '../../../../../constants/env.mts'
1111
import { NODE_MODULES } from '../../../../../constants/packages.mts'
1212
import {
13+
getInternals,
1314
SOCKET_CLI_ACCEPT_RISKS,
1415
SOCKET_CLI_SHADOW_ACCEPT_RISKS,
1516
SOCKET_CLI_SHADOW_API_TOKEN,
17+
SOCKET_CLI_SHADOW_BIN,
1618
SOCKET_CLI_SHADOW_PROGRESS,
1719
SOCKET_CLI_SHADOW_SILENT,
1820
SOCKET_CLI_VIEW_ALL_RISKS,
@@ -30,6 +32,9 @@ import type {
3032
NodeClass,
3133
} from '../../types.mts'
3234

35+
const internals = getInternals()
36+
const getIpc = internals.getIpc
37+
3338
export const SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES = {
3439
__proto__: null,
3540
audit: false,
@@ -96,7 +101,97 @@ export class SafeArborist extends Arborist {
96101
this: SafeArborist,
97102
...args: Parameters<InstanceType<ArboristClass>['reify']>
98103
): Promise<NodeClass> {
99-
// Note: Registry no longer provides IPC, always use risky reify.
104+
const options = {
105+
__proto__: null,
106+
...(args.length ? args[0] : undefined),
107+
} as ArboristReifyOptions
108+
109+
const ipc = getIpc ? await getIpc() : undefined
110+
111+
const binName = ipc?.[SOCKET_CLI_SHADOW_BIN]
112+
if (!binName) {
113+
return await this[kRiskyReify](...args)
114+
}
115+
116+
await super.reify(
117+
{
118+
...options,
119+
...SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES,
120+
progress: false,
121+
},
122+
// @ts-expect-error: TypeScript gets grumpy about rest parameters.
123+
...args.slice(1),
124+
)
125+
126+
const shadowAcceptRisks = !!ipc?.[SOCKET_CLI_SHADOW_ACCEPT_RISKS]
127+
const shadowProgress = !!ipc?.[SOCKET_CLI_SHADOW_PROGRESS]
128+
const shadowSilent = !!ipc?.[SOCKET_CLI_SHADOW_SILENT]
129+
130+
const acceptRisks = shadowAcceptRisks || ENV.SOCKET_CLI_ACCEPT_RISKS
131+
const reportOnlyBlocking =
132+
acceptRisks || options['dryRun'] || options['yes']
133+
const silent = !!options['silent']
134+
const spinnerInstance =
135+
silent || !shadowProgress ? undefined : (getSpinner() ?? undefined)
136+
137+
const isShadowNpx = binName === NPX
138+
const hasExisting = await findUp(NODE_MODULES, {
139+
cwd: process.cwd(),
140+
onlyDirectories: true,
141+
})
142+
const shouldCheckExisting = reportOnlyBlocking ? true : isShadowNpx
143+
144+
const needInfoOn = getDetailsFromDiff(this.diff, {
145+
filter: {
146+
existing: shouldCheckExisting,
147+
},
148+
})
149+
150+
const alertsMap = await getAlertsMapFromArborist(this, needInfoOn, {
151+
apiToken: ipc?.[SOCKET_CLI_SHADOW_API_TOKEN],
152+
spinner: spinnerInstance,
153+
filter: reportOnlyBlocking
154+
? {
155+
actions: ['error'],
156+
blocked: true,
157+
existing: shouldCheckExisting,
158+
}
159+
: {
160+
actions: ['error', 'monitor', 'warn'],
161+
existing: shouldCheckExisting,
162+
},
163+
})
164+
165+
if (alertsMap.size) {
166+
process.exitCode = 1
167+
const viewAllRisks = ENV.SOCKET_CLI_VIEW_ALL_RISKS
168+
logAlertsMap(alertsMap, {
169+
hideAt: viewAllRisks ? 'none' : 'middle',
170+
output: process.stderr,
171+
})
172+
throw new Error(
173+
`
174+
Socket ${binName} exiting due to risks.${
175+
viewAllRisks
176+
? ''
177+
: `\nView all risks - Rerun with environment variable ${SOCKET_CLI_VIEW_ALL_RISKS}=1.`
178+
}${
179+
acceptRisks
180+
? ''
181+
: `\nAccept risks - Rerun with environment variable ${SOCKET_CLI_ACCEPT_RISKS}=1.`
182+
}
183+
`.trim(),
184+
)
185+
}
186+
if (!silent && !shadowSilent) {
187+
logger.success(
188+
`Socket ${binName} ${acceptRisks ? 'accepted' : 'found no'}${hasExisting ? ' new' : ''} risks`,
189+
)
190+
if (isShadowNpx) {
191+
logger.log(`Running ${options.add?.[0]}`)
192+
}
193+
}
194+
100195
return await this[kRiskyReify](...args)
101196
}
102197
}

packages/cli/src/types.test.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ describe('types', () => {
3333

3434
it('can be used as a union type', () => {
3535
// Intentionally defined inline to test type inference in specific context.
36+
// eslint-disable-next-line unicorn/consistent-function-scoping
3637
const processResult = (value: number): CResult<string> => {
3738
if (value > 0) {
3839
return { ok: true, data: `Positive: ${value}` }

packages/cli/src/utils/promise/queue.test.mts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,10 @@ describe('PromiseQueue', () => {
9898
const queue = new PromiseQueue(1)
9999

100100
// Intentionally defined inline for test simplicity.
101+
// eslint-disable-next-line unicorn/consistent-function-scoping
101102
const goodTask = () => Promise.resolve('success')
102103
// Intentionally defined inline for test simplicity.
104+
// eslint-disable-next-line unicorn/consistent-function-scoping
103105
const badTask = () => Promise.reject(new Error('failure'))
104106

105107
const result1 = await queue.add(goodTask)

packages/cli/src/utils/registry/npm-registry.mts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,8 @@ export async function retryWithBackoff<T>(
169169
let lastError: Error | unknown
170170
let delay = baseDelayMs
171171

172-
// Retry logic requires sequential attempts.
173172
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
174173
try {
175-
// eslint-disable-next-line no-await-in-loop
176174
return await fn()
177175
} catch (error) {
178176
lastError = error
@@ -182,7 +180,6 @@ export async function retryWithBackoff<T>(
182180
attempt < maxRetries &&
183181
(code === 'EBUSY' || code === 'EMFILE' || code === 'ENFILE')
184182
) {
185-
// eslint-disable-next-line no-await-in-loop
186183
await new Promise(resolve => setTimeout(resolve, delay))
187184
delay *= backoffFactor
188185
continue
@@ -272,14 +269,12 @@ export async function extractTarball(
272269
}
273270

274271
// Extract files to target directory.
275-
// Files must be extracted sequentially.
276272
for (const file of files) {
277273
// Sanitize file path to prevent directory traversal attacks.
278274
const sanitizedPath = sanitizeTarballPath(file.name)
279275
const targetPath = path.join(targetDir, sanitizedPath)
280276

281277
if (file.type === 'directory') {
282-
// eslint-disable-next-line no-await-in-loop
283278
await retryWithBackoff(() =>
284279
fs.mkdir(targetPath, { recursive: true }),
285280
).catch(error => {
@@ -290,7 +285,6 @@ export async function extractTarball(
290285
} else if (file.type === 'file' && file.data) {
291286
// Ensure parent directory exists.
292287
const parentDir = path.dirname(targetPath)
293-
// eslint-disable-next-line no-await-in-loop
294288
await retryWithBackoff(() =>
295289
fs.mkdir(parentDir, { recursive: true }),
296290
).catch(error => {
@@ -306,7 +300,6 @@ export async function extractTarball(
306300
})
307301

308302
// Write file.
309-
// eslint-disable-next-line no-await-in-loop
310303
await retryWithBackoff(() =>
311304
fs.writeFile(targetPath, file.data as Uint8Array<ArrayBufferLike>),
312305
).catch(error => {
@@ -326,7 +319,6 @@ export async function extractTarball(
326319
const mode = Number.parseInt(file.attrs.mode, 8)
327320
// Validate mode is a valid number before attempting chmod.
328321
if (!Number.isNaN(mode) && mode > 0) {
329-
// eslint-disable-next-line no-await-in-loop
330322
await retryWithBackoff(() => fs.chmod(targetPath, mode)).catch(
331323
error => {
332324
// Chmod failures are non-fatal - log but continue.

packages/cli/src/utils/terminal/lazy-ink.mts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ export async function loadInkTable() {
3636
export function isInkAvailable(): boolean {
3737
try {
3838
// Check if modules exist without loading them
39-
// eslint-disable-next-line n/no-extraneous-require
4039
require.resolve('ink')
41-
// eslint-disable-next-line n/no-extraneous-require
4240
require.resolve('react')
4341
return true
4442
} catch {

0 commit comments

Comments
 (0)