diff --git a/packages/cli/src/commands/scan/create-scan-from-github.mts b/packages/cli/src/commands/scan/create-scan-from-github.mts index 7429f980d..9da610346 100644 --- a/packages/cli/src/commands/scan/create-scan-from-github.mts +++ b/packages/cli/src/commands/scan/create-scan-from-github.mts @@ -350,7 +350,7 @@ async function testAndDownloadManifestFile({ orgGithub: string repoSlug: string supportedFiles: - | SocketSdkSuccessResult<'getReportSupportedFiles'>['data'] + | SocketSdkSuccessResult<'getSupportedFiles'>['data'] | undefined tmpDir: string }): Promise> { diff --git a/packages/cli/src/commands/scan/fetch-supported-scan-file-names.mts b/packages/cli/src/commands/scan/fetch-supported-scan-file-names.mts index 5dfb6e58a..87199c18b 100644 --- a/packages/cli/src/commands/scan/fetch-supported-scan-file-names.mts +++ b/packages/cli/src/commands/scan/fetch-supported-scan-file-names.mts @@ -1,3 +1,4 @@ +import { getDefaultOrgSlug } from '../ci/fetch-default-org-slug.mjs' import { handleApiCall } from '../../utils/socket/api.mjs' import { setupSdk } from '../../utils/socket/sdk.mjs' @@ -7,14 +8,15 @@ import type { Spinner } from '@socketsecurity/lib/spinner' import type { SocketSdkSuccessResult } from '@socketsecurity/sdk' export type FetchSupportedScanFileNamesOptions = { + orgSlug?: string | undefined sdkOpts?: SetupSdkOptions | undefined spinner?: Spinner | undefined } export async function fetchSupportedScanFileNames( options?: FetchSupportedScanFileNamesOptions | undefined, -): Promise['data']>> { - const { sdkOpts, spinner } = { +): Promise['data']>> { + const { orgSlug, sdkOpts, spinner } = { __proto__: null, ...options, } as FetchSupportedScanFileNamesOptions @@ -25,8 +27,18 @@ export async function fetchSupportedScanFileNames( } const sockSdk = sockSdkCResult.data - return await handleApiCall<'getReportSupportedFiles'>( - sockSdk.getSupportedScanFiles(), + // Use provided orgSlug or discover it. + let resolvedOrgSlug = orgSlug + if (!resolvedOrgSlug) { + const orgSlugCResult = await getDefaultOrgSlug() + if (!orgSlugCResult.ok) { + return orgSlugCResult + } + resolvedOrgSlug = orgSlugCResult.data + } + + return await handleApiCall<'getSupportedFiles'>( + sockSdk.getSupportedFiles(resolvedOrgSlug), { description: 'supported scan file types', spinner, diff --git a/packages/cli/src/commands/scan/handle-create-new-scan.mts b/packages/cli/src/commands/scan/handle-create-new-scan.mts index e7295fc6a..da7d812d2 100644 --- a/packages/cli/src/commands/scan/handle-create-new-scan.mts +++ b/packages/cli/src/commands/scan/handle-create-new-scan.mts @@ -131,7 +131,7 @@ export async function handleCreateNewScan({ const spinner = getDefaultSpinner() - const supportedFilesCResult = await fetchSupportedScanFileNames({ spinner }) + const supportedFilesCResult = await fetchSupportedScanFileNames({ orgSlug, spinner }) if (!supportedFilesCResult.ok) { debug('warn', 'Failed to fetch supported scan file names') debugDir('inspect', { supportedFilesCResult }) diff --git a/packages/cli/src/utils/fs/glob.mts b/packages/cli/src/utils/fs/glob.mts index cc619e3bc..7b475e2d8 100644 --- a/packages/cli/src/utils/fs/glob.mts +++ b/packages/cli/src/utils/fs/glob.mts @@ -159,14 +159,14 @@ function workspacePatternToGlobPattern(workspace: string): string { export function filterBySupportedScanFiles( filepaths: string[] | readonly string[], - supportedFiles: SocketSdkSuccessResult<'getReportSupportedFiles'>['data'], + supportedFiles: SocketSdkSuccessResult<'getSupportedFiles'>['data'], ): string[] { const patterns = getSupportedFilePatterns(supportedFiles) return filepaths.filter(p => micromatch.some(p, patterns, { dot: true })) } export function createSupportedFilesFilter( - supportedFiles: SocketSdkSuccessResult<'getReportSupportedFiles'>['data'], + supportedFiles: SocketSdkSuccessResult<'getSupportedFiles'>['data'], ): (filepath: string) => boolean { const patterns = getSupportedFilePatterns(supportedFiles) return (filepath: string) => @@ -174,7 +174,7 @@ export function createSupportedFilesFilter( } export function getSupportedFilePatterns( - supportedFiles: SocketSdkSuccessResult<'getReportSupportedFiles'>['data'], + supportedFiles: SocketSdkSuccessResult<'getSupportedFiles'>['data'], ): string[] { const patterns: string[] = [] for (const key of Object.keys(supportedFiles)) { @@ -309,7 +309,7 @@ export async function globWorkspace( export function isReportSupportedFile( filepath: string, - supportedFiles: SocketSdkSuccessResult<'getReportSupportedFiles'>['data'], + supportedFiles: SocketSdkSuccessResult<'getSupportedFiles'>['data'], ) { const patterns = getSupportedFilePatterns(supportedFiles) return micromatch.some(filepath, patterns, { dot: true }) diff --git a/packages/cli/src/utils/fs/path-resolve.mts b/packages/cli/src/utils/fs/path-resolve.mts index 25392ed9d..6e5b47683 100644 --- a/packages/cli/src/utils/fs/path-resolve.mts +++ b/packages/cli/src/utils/fs/path-resolve.mts @@ -111,7 +111,7 @@ export type PackageFilesForScanOptions = { export async function getPackageFilesForScan( inputPaths: string[], - supportedFiles: SocketSdkSuccessResult<'getReportSupportedFiles'>['data'], + supportedFiles: SocketSdkSuccessResult<'getSupportedFiles'>['data'], options?: PackageFilesForScanOptions | undefined, ): Promise { const { config: socketConfig, cwd = process.cwd() } = { diff --git a/packages/cli/test/unit/commands/scan/fetch-supported-scan-file-names.test.mts b/packages/cli/test/unit/commands/scan/fetch-supported-scan-file-names.test.mts index c6e2a2427..aa958c8dd 100644 --- a/packages/cli/test/unit/commands/scan/fetch-supported-scan-file-names.test.mts +++ b/packages/cli/test/unit/commands/scan/fetch-supported-scan-file-names.test.mts @@ -1,24 +1,8 @@ /** * Unit tests for fetchSupportedScanFileNames. * - * Purpose: - * Tests fetching supported manifest file names for scanning. Validates which files Socket can analyze. - * - * Test Coverage: - * - Successful API operation - * - SDK setup failure handling - * - API call error scenarios - * - Custom SDK options (API tokens, base URLs) - * - Supported file types - * - Ecosystem detection - * - Null prototype usage for security - * - * Testing Approach: - * Uses SDK test helpers to mock Socket API interactions. Validates comprehensive - * error handling and API integration. - * - * Related Files: - * - src/commands/SupportedScanFileNames.mts (implementation) + * Tests fetching supported manifest file names for scanning. + * Validates which files Socket can analyze via the SDK v4 getSupportedFiles API. */ import { describe, expect, it, vi } from 'vitest' @@ -51,13 +35,13 @@ describe('fetchSupportedScanFileNames', () => { } const { mockHandleApi, mockSdk } = await setupSdkMockSuccess( - 'getSupportedScanFiles', + 'getSupportedFiles', mockData, ) - const result = await fetchSupportedScanFileNames() + const result = await fetchSupportedScanFileNames({ orgSlug: 'test-org' }) - expect(mockSdk.getSupportedScanFiles).toHaveBeenCalledWith() + expect(mockSdk.getSupportedFiles).toHaveBeenCalledWith('test-org') expect(mockHandleApi).toHaveBeenCalledWith(expect.any(Promise), { description: 'supported scan file types', }) @@ -74,7 +58,7 @@ describe('fetchSupportedScanFileNames', () => { cause: 'Invalid configuration', }) - const result = await fetchSupportedScanFileNames() + const result = await fetchSupportedScanFileNames({ orgSlug: 'test-org' }) expect(result.ok).toBe(false) expect(result.message).toBe('Failed to setup SDK') @@ -85,9 +69,9 @@ describe('fetchSupportedScanFileNames', () => { const { fetchSupportedScanFileNames } = await import('../../../../../src/commands/scan/fetch-supported-scan-file-names.mts') - await setupSdkMockError('getSupportedScanFiles', 'API error', 500) + await setupSdkMockError('getSupportedFiles', 'API error', 500) - const result = await fetchSupportedScanFileNames() + const result = await fetchSupportedScanFileNames({ orgSlug: 'test-org' }) expect(result.ok).toBe(false) expect(result.code).toBe(500) @@ -98,21 +82,23 @@ describe('fetchSupportedScanFileNames', () => { await import('../../../../../src/commands/scan/fetch-supported-scan-file-names.mts') const { mockSdk, mockSetupSdk } = await setupSdkMockSuccess( - 'getSupportedScanFiles', + 'getSupportedFiles', {}, ) - const options = { + await fetchSupportedScanFileNames({ + orgSlug: 'my-org', sdkOpts: { apiToken: 'custom-token', baseUrl: 'https://api.example.com', }, - } - - await fetchSupportedScanFileNames(options) + }) - expect(mockSetupSdk).toHaveBeenCalledWith(options.sdkOpts) - expect(mockSdk.getSupportedScanFiles).toHaveBeenCalledWith() + expect(mockSetupSdk).toHaveBeenCalledWith({ + apiToken: 'custom-token', + baseUrl: 'https://api.example.com', + }) + expect(mockSdk.getSupportedFiles).toHaveBeenCalledWith('my-org') }) it('passes custom spinner', async () => { @@ -120,7 +106,7 @@ describe('fetchSupportedScanFileNames', () => { await import('../../../../../src/commands/scan/fetch-supported-scan-file-names.mts') const { mockHandleApi } = await setupSdkMockSuccess( - 'getSupportedScanFiles', + 'getSupportedFiles', {}, ) @@ -131,11 +117,7 @@ describe('fetchSupportedScanFileNames', () => { fail: vi.fn(), } - const options = { - spinner: mockSpinner, - } - - await fetchSupportedScanFileNames(options) + await fetchSupportedScanFileNames({ orgSlug: 'test-org', spinner: mockSpinner }) expect(mockHandleApi).toHaveBeenCalledWith(expect.any(Promise), { description: 'supported scan file types', @@ -147,76 +129,28 @@ describe('fetchSupportedScanFileNames', () => { const { fetchSupportedScanFileNames } = await import('../../../../../src/commands/scan/fetch-supported-scan-file-names.mts') - await setupSdkMockSuccess('getSupportedScanFiles', { + await setupSdkMockSuccess('getSupportedFiles', { supportedFiles: [], ecosystems: [], }) - const result = await fetchSupportedScanFileNames() + const result = await fetchSupportedScanFileNames({ orgSlug: 'test-org' }) expect(result.ok).toBe(true) expect(result.data?.supportedFiles).toEqual([]) expect(result.data?.ecosystems).toEqual([]) }) - it('handles comprehensive file types', async () => { - const { fetchSupportedScanFileNames } = - await import('../../../../../src/commands/scan/fetch-supported-scan-file-names.mts') - - const comprehensiveFiles = [ - // JavaScript/Node.js - 'package.json', - 'package-lock.json', - 'yarn.lock', - 'pnpm-lock.yaml', - // PHP - 'composer.json', - 'composer.lock', - // Ruby - 'Gemfile', - 'Gemfile.lock', - // Python - 'requirements.txt', - 'Pipfile', - 'Pipfile.lock', - 'poetry.lock', - 'pyproject.toml', - // Go - 'go.mod', - 'go.sum', - // Java - 'pom.xml', - 'build.gradle', - // .NET - 'packages.config', - '*.csproj', - // Rust - 'Cargo.toml', - 'Cargo.lock', - ] - - await setupSdkMockSuccess('getSupportedScanFiles', { - supportedFiles: comprehensiveFiles, - }) - - const result = await fetchSupportedScanFileNames() - - expect(result.ok).toBe(true) - expect(result.data?.supportedFiles).toContain('package.json') - expect(result.data?.supportedFiles).toContain('Cargo.toml') - expect(result.data?.supportedFiles).toContain('pom.xml') - }) - - it('works without options parameter', async () => { + it('works with orgSlug provided', async () => { const { fetchSupportedScanFileNames } = await import('../../../../../src/commands/scan/fetch-supported-scan-file-names.mts') const { mockHandleApi, mockSetupSdk } = await setupSdkMockSuccess( - 'getSupportedScanFiles', + 'getSupportedFiles', { supportedFiles: ['package.json'] }, ) - const result = await fetchSupportedScanFileNames() + const result = await fetchSupportedScanFileNames({ orgSlug: 'test-org' }) expect(mockSetupSdk).toHaveBeenCalledWith(undefined) expect(mockHandleApi).toHaveBeenCalledWith(expect.any(Promise), { @@ -230,12 +164,10 @@ describe('fetchSupportedScanFileNames', () => { const { fetchSupportedScanFileNames } = await import('../../../../../src/commands/scan/fetch-supported-scan-file-names.mts') - const { mockSdk } = await setupSdkMockSuccess('getSupportedScanFiles', {}) + const { mockSdk } = await setupSdkMockSuccess('getSupportedFiles', {}) - // This tests that the function properly uses __proto__: null. - await fetchSupportedScanFileNames() + await fetchSupportedScanFileNames({ orgSlug: 'test-org' }) - // The function should work without prototype pollution issues. - expect(mockSdk.getSupportedScanFiles).toHaveBeenCalled() + expect(mockSdk.getSupportedFiles).toHaveBeenCalled() }) }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index df3f6b4bf..c857e39ec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,8 +7,8 @@ settings: catalogs: default: '@anthropic-ai/claude-code': - specifier: 2.1.92 - version: 2.1.92 + specifier: 2.1.98 + version: 2.1.98 '@babel/core': specifier: 7.28.4 version: 7.28.4 @@ -97,8 +97,8 @@ catalogs: specifier: 2.0.2 version: 2.0.2 '@socketsecurity/sdk': - specifier: 3.4.1 - version: 3.4.1 + specifier: 4.0.0 + version: 4.0.0 '@types/adm-zip': specifier: 0.5.7 version: 0.5.7 @@ -335,7 +335,7 @@ importers: devDependencies: '@anthropic-ai/claude-code': specifier: 'catalog:' - version: 2.1.92 + version: 2.1.98 '@babel/core': specifier: 'catalog:' version: 7.28.4 @@ -425,7 +425,7 @@ importers: version: 2.0.2(typescript@5.9.3) '@socketsecurity/sdk': specifier: 'catalog:' - version: 3.4.1(typescript@5.9.3) + version: 4.0.0(typescript@5.9.3) '@types/cmd-shim': specifier: 'catalog:' version: 5.0.2 @@ -665,7 +665,7 @@ importers: version: 2.0.2(typescript@5.9.3) '@socketsecurity/sdk': specifier: 'catalog:' - version: 3.4.1(typescript@5.9.3) + version: 4.0.0(typescript@5.9.3) '@types/adm-zip': specifier: 'catalog:' version: 0.5.7 @@ -794,8 +794,8 @@ packages: engines: {node: '>=20'} hasBin: true - '@anthropic-ai/claude-code@2.1.92': - resolution: {integrity: sha512-mNGw/IK3+1yHsQBeKaNtdTPCrQDkUEuNTJtm3OBTXs4bBkUVdIgRme/34ZnbZkl2VMMYPoNaTvqX2qJZ9EdSxQ==} + '@anthropic-ai/claude-code@2.1.98': + resolution: {integrity: sha512-qecREauMWXHplkpjqsuDuUv4ww+NprMl71k9sMuLkZU7qwjLMkTPxRBjuKvZWWMrAPvZWdGZE9LljUTfCQ1lWQ==} engines: {node: '>=18.0.0'} hasBin: true @@ -2242,10 +2242,6 @@ packages: resolution: {integrity: sha512-DM81ydAjO2GJKkNf2Vn17InJ37sEYLK1YyhxpDX16OdbOpYlsDIw8QyeFEUZtc7GqsQXbcPKJmz3j/2qS+BhKQ==} engines: {node: '>=18'} - '@socketregistry/packageurl-js@1.3.5': - resolution: {integrity: sha512-Fl4GNUJ/z3IBJBGj4IsJfuRGUBCRMgX0df0mb5x5buaCPDKC+NhMhAFuxpc3viLSHV12CO2rGaNCf4fBYWI0FA==} - engines: {node: '>=18', pnpm: '>=10.16.0'} - '@socketregistry/packageurl-js@1.4.1': resolution: {integrity: sha512-t/UrOd1DMYXcGuKo2v07WMbuHCMlKBKOriTHu4cn9OIxfj1qWKoF/kpOswGHOWkG5zwj2Ke/2+qLiDugmx5z+A==} engines: {node: '>=18.20.4', pnpm: '>=10.25.0'} @@ -2292,9 +2288,9 @@ packages: typescript: optional: true - '@socketsecurity/sdk@3.4.1': - resolution: {integrity: sha512-Znpqi0GPBNk1j6QzKzcnP069Umpdn4mOuYtalux1qnz8/9X7CEcOFk8z8gUwaeQfsfwSP4NEgRcQvZZDkcg8wQ==} - engines: {node: '>=18', pnpm: '>=10.25.0'} + '@socketsecurity/sdk@4.0.0': + resolution: {integrity: sha512-e7MAVhjkeCMVoqYC8lmFk8GdwlNp8ZYTq9izkOrFf2ZZJMPaREC83lbk0xKTYIJKc09lxVhFLYLtDT/n4LgA4A==} + engines: {node: '>=18.20.8', pnpm: '>=10.33.0'} '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -4634,7 +4630,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 - '@anthropic-ai/claude-code@2.1.92': + '@anthropic-ai/claude-code@2.1.98': optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 @@ -5978,8 +5974,6 @@ snapshots: '@socketregistry/isarray@1.0.8': {} - '@socketregistry/packageurl-js@1.3.5': {} - '@socketregistry/packageurl-js@1.4.1': dependencies: picomatch: 4.0.3 @@ -6011,9 +6005,8 @@ snapshots: optionalDependencies: typescript: 5.9.3 - '@socketsecurity/sdk@3.4.1(typescript@5.9.3)': + '@socketsecurity/sdk@4.0.0(typescript@5.9.3)': dependencies: - '@socketregistry/packageurl-js': 1.3.5 '@socketsecurity/lib': 5.15.0(typescript@5.9.3) form-data: 4.0.5 transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3a26a4c69..6b6423870 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,7 +1,7 @@ # Wait 7 days (10080 minutes) before installing newly published packages. minimumReleaseAge: 10080 minimumReleaseAgeExclude: - - '@anthropic-ai/claude-code@2.1.92' + - '@anthropic-ai/claude-code@2.1.98' - '@socketaddon/*' - '@socketbin/*' - '@socketregistry/*' @@ -12,7 +12,7 @@ packages: - '!packages/package-builder/build' catalog: - '@anthropic-ai/claude-code': 2.1.92 + '@anthropic-ai/claude-code': 2.1.98 '@babel/core': 7.28.4 '@babel/generator': 7.28.5 '@babel/parser': 7.28.4 @@ -47,7 +47,7 @@ catalog: '@socketsecurity/config': 3.0.1 '@socketsecurity/lib': 5.15.0 '@socketsecurity/registry': 2.0.2 - '@socketsecurity/sdk': 3.4.1 + '@socketsecurity/sdk': 4.0.0 '@types/adm-zip': 0.5.7 '@types/cmd-shim': 5.0.2 '@types/js-yaml': 4.0.9