Skip to content
Closed
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
"yargs-parser": "catalog:"
},
"patchedDependencies": {
"@socketsecurity/[email protected]": "patches/@[email protected]",
"@npmcli/[email protected]": "patches/@[email protected]",
"@npmcli/[email protected]": "patches/@[email protected]",
"@sigstore/[email protected]": "patches/@[email protected]",
Expand Down
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"logo-light.png"
],
"scripts": {
"prebuild": "node scripts/generate-packages.mjs",
"build": "node --max-old-space-size=8192 --import=./scripts/load.mjs scripts/build.mjs",
"build:force": "node --max-old-space-size=8192 --import=./scripts/load.mjs scripts/build.mjs --force",
"build:watch": "node --max-old-space-size=8192 --import=./scripts/load.mjs scripts/build.mjs --watch",
Expand Down
24 changes: 10 additions & 14 deletions packages/cli/scripts/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ async function main() {
const verbose = isVerbose()
const watch = process.argv.includes('--watch')
const force = process.argv.includes('--force')
const prod = process.argv.includes('--prod')
const _prod = process.argv.includes('--prod')

// Pass --force flag via environment variable.
if (force) {
Expand Down Expand Up @@ -202,19 +202,15 @@ async function main() {
command: 'node',
args: [...NODE_MEMORY_FLAGS, '.config/esbuild.inject.config.mjs'],
},
// Copy CLI to dist for production builds.
...(prod
? [
{
name: 'Copy CLI to dist',
command: 'node',
args: [
'-e',
'require("fs").copyFileSync("build/cli.js", "dist/cli.js")',
],
},
]
: []),
// Copy CLI to dist (required for dist/index.js to work).
{
name: 'Copy CLI to dist',
command: 'node',
args: [
'-e',
'require("fs").copyFileSync("build/cli.js", "dist/cli.js")',
],
},
]

// Run build steps sequentially.
Expand Down
5 changes: 3 additions & 2 deletions packages/cli/scripts/extract-models.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
*/

import { existsSync } from 'node:fs'
import { mkdir, readFile, writeFile } from 'node:fs/promises'
import { readFile, writeFile } from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'

import { safeMkdir } from '@socketsecurity/lib/fs'
import { getDefaultLogger } from '@socketsecurity/lib/logger'
import { downloadSocketBtmRelease } from '@socketsecurity/lib/releases/socket-btm'
import { spawn } from '@socketsecurity/lib/spawn'
Expand All @@ -27,7 +28,7 @@ const outputDir = path.join(rootPath, 'build/models')
* Extract tar.gz to output directory if needed.
*/
async function extractModels(tarGzPath, releaseTag) {
await mkdir(outputDir, { recursive: true })
await safeMkdir(outputDir)

const versionPath = path.join(outputDir, '.version')

Expand Down
6 changes: 3 additions & 3 deletions packages/cli/scripts/extract-onnx-runtime.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import path from 'node:path'
import { fileURLToPath } from 'node:url'

import {
ensureOutputDir,
generateHashComment,
shouldExtract,
} from 'build-infra/lib/extraction-cache'

import { safeMkdirSync } from '@socketsecurity/lib/fs'
import { getDefaultLogger } from '@socketsecurity/lib/logger'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
Expand Down Expand Up @@ -78,7 +78,7 @@ export const Tensor = ort.Tensor
export default ort
`

ensureOutputDir(outputPath)
safeMkdirSync(path.dirname(outputPath))
writeFileSync(outputPath, placeholderContent, 'utf-8')
logger.log(`✓ Generated placeholder ${outputPath}`)
process.exit(0)
Expand Down Expand Up @@ -138,7 +138,7 @@ export const Tensor = ort.Tensor
export default ort
`

ensureOutputDir(outputPath)
safeMkdirSync(path.dirname(outputPath))
writeFileSync(outputPath, onnxSyncContent, 'utf-8')

logger.log(`✓ Generated ${outputPath}`)
Expand Down
110 changes: 94 additions & 16 deletions packages/cli/scripts/extract-yoga-wasm.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,46 @@
* Idempotent: Skips regeneration if cached file hasn't changed.
*/

import { createHash } from 'node:crypto'
import { existsSync } from 'node:fs'
import { readFile, writeFile } from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'

import { safeMkdir } from '@socketsecurity/lib/fs'
import { getDefaultLogger } from '@socketsecurity/lib/logger'
import { downloadSocketBtmRelease } from '@socketsecurity/lib/releases/socket-btm'

import {
computeFileHash,
generateHeader,
} from './utils/socket-btm-releases.mjs'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const rootPath = path.join(__dirname, '..')
const logger = getDefaultLogger()

const outputPath = path.join(rootPath, 'build/yoga-sync.mjs')
const versionPath = path.join(rootPath, 'build/yoga.version')

/**
* Compute SHA256 hash of file content.
*/
async function computeFileHash(filePath) {
const content = await readFile(filePath)
return createHash('sha256').update(content).digest('hex')
}

/**
* Generate file header with metadata.
*/
function generateHeader({ assetName, scriptName, sourceHash, tag }) {
const hashLine = sourceHash ? `\n * Source hash: ${sourceHash}` : ''

return `/**
* AUTO-GENERATED by ${scriptName}
* DO NOT EDIT MANUALLY - changes will be overwritten on next build.
*
* Source: socket-btm GitHub releases (${tag})
* Asset: ${assetName}${hashLine}
*/`
}

/**
* Generate placeholder stub when yoga WASM is not available.
*/
Expand Down Expand Up @@ -59,6 +79,7 @@ const yoga = {
export default yoga
`

await safeMkdir(path.dirname(outputPath))
await writeFile(outputPath, placeholderContent, 'utf-8')
logger.warn('Using placeholder yoga (affects table rendering)')
process.exit(0)
Expand All @@ -73,17 +94,73 @@ async function main() {

let assetPath
try {
// Download yoga-sync.mjs asset using @socketsecurity/lib helper.
// Asset name pattern: yoga-sync-{DATE}-{COMMIT}.mjs
// The pattern is resolved automatically to find the latest matching asset.
// This handles version caching automatically.
assetPath = await downloadSocketBtmRelease({
asset: 'yoga-sync-*.mjs',
cwd: rootPath,
downloadDir: '../../packages/build-infra/build/downloaded',
quiet: false,
tool: 'yoga-layout',
})
// Since lib 5.3.0 doesn't support glob patterns, we need to find the exact
// asset name from the GitHub release before downloading.
const downloadDir = path.join(
rootPath,
'../../packages/build-infra/build/downloaded',
)
const assetsDir = path.join(downloadDir, 'yoga-layout', 'assets')

// Check if we already have cached assets first.
const { readdirSync } = await import('node:fs')
if (existsSync(assetsDir)) {
const yogaFiles = readdirSync(assetsDir).filter(f =>
f.match(/^yoga-sync-.*\.mjs$/),
)
if (yogaFiles.length) {
assetPath = path.join(assetsDir, yogaFiles[0])
logger.info('Using cached yoga-layout (assets)')
}
}

// If not cached, fetch release info from GitHub API to get exact asset name.
if (!assetPath) {
// Use GitHub token if available (required in CI to avoid rate limiting).
const token = process.env.GH_TOKEN || process.env.GITHUB_TOKEN
const headers = {
Accept: 'application/vnd.github.v3+json',
'User-Agent': 'socket-cli',
}
if (token) {
headers.Authorization = `Bearer ${token}`
}

const response = await fetch(
'https://api.github.com/repos/SocketDev/socket-btm/releases',
{ headers },
)
if (!response.ok) {
throw new Error(`GitHub API error: ${response.status}`)
}

const releases = await response.json()
const yogaRelease = releases.find(r =>
r.tag_name.startsWith('yoga-layout-'),
)

if (!yogaRelease) {
throw new Error('No yoga-layout release found on GitHub')
}

// Find the yoga-sync-*.mjs asset.
const yogaAsset = yogaRelease.assets.find(
a => a.name.startsWith('yoga-sync-') && a.name.endsWith('.mjs'),
)

if (!yogaAsset) {
throw new Error('No yoga-sync-*.mjs asset found in release')
}

// Now download using the exact asset name.
assetPath = await downloadSocketBtmRelease({
asset: yogaAsset.name,
cwd: rootPath,
downloadDir,
quiet: false,
tool: 'yoga-layout',
})
}
} catch (e) {
logger.groupEnd()
logger.warn(`yoga-layout not available: ${e.message}`)
Expand Down Expand Up @@ -137,6 +214,7 @@ async function main() {
${syncContent}
`

await safeMkdir(path.dirname(outputPath))
await writeFile(outputPath, jsContent, 'utf-8')

// Write version file.
Expand Down
19 changes: 19 additions & 0 deletions packages/cli/scripts/generate-packages.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Generate template-based packages required for CLI build.
* Runs the package generation scripts from package-builder.
*/

import { spawn } from '@socketsecurity/lib/spawn'

const scripts = [
'../package-builder/scripts/generate-cli-sentry-package.mjs',
'../package-builder/scripts/generate-socket-package.mjs',
'../package-builder/scripts/generate-socketbin-packages.mjs',
]

for (const script of scripts) {
const result = await spawn('node', [script], { stdio: 'inherit' })
if (result.code !== 0) {
process.exit(result.code)
}
}
40 changes: 0 additions & 40 deletions packages/cli/scripts/utils/socket-btm-releases.mjs

This file was deleted.

21 changes: 20 additions & 1 deletion packages/cli/src/utils/cli/with-subcommands.mts
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,26 @@ export async function meowWithSubcommands(

// If first arg is a flag (starts with --), try Python CLI forwarding.
// This enables: socket --repo owner/repo --target-path .
if (commandOrAliasName?.startsWith('--')) {
// Exception: Don't forward Node.js CLI built-in flags (help, version, etc).
const nodeCliFlags = new Set([
'--help',
'--version',
'--config',
'--compact-header',
'--dry-run',
'--json',
'--markdown',
'--org',
'--spinner',
'--no-spinner',
'--nobanner',
'--no-banner',
'--help-full',
])
if (
commandOrAliasName?.startsWith('--') &&
!nodeCliFlags.has(commandOrAliasName)
) {
const pythonResult = await spawnSocketPython(argv, {
stdio: 'inherit',
})
Expand Down
13 changes: 13 additions & 0 deletions patches/@[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/dist/external/debug.js b/dist/external/debug.js
index 2633cad5c0e9105b567fc84bdd9fc354473937e1..7d735a9da9eecc8b7a31285486cf867abfd38a0c 100644
--- a/dist/external/debug.js
+++ b/dist/external/debug.js
@@ -24,6 +24,8 @@ var require_debug = __commonJS({
debug.names = [];
debug.skips = [];
debug.formatters = {};
+ debug.enable = function() {};
+ debug.disable = function() { return ''; };
module2.exports = debug;
}
});
Loading