Skip to content

Commit 5f842e9

Browse files
committed
Merge branch 'main' of github.com:SocketDev/socket-cli into directory-target-fix
2 parents 5f78dfd + 062dafa commit 5f842e9

File tree

1,001 files changed

+128463
-12955
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,001 files changed

+128463
-12955
lines changed

.config/babel.config.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
'use strict'
2-
31
const path = require('node:path')
42

53
const rootPath = path.join(__dirname, '..')
64
const scriptsPath = path.join(rootPath, 'scripts')
75
const babelPluginsPath = path.join(scriptsPath, 'babel')
86

97
module.exports = {
10-
presets: ['@babel/preset-typescript'],
8+
presets: [
9+
'@babel/preset-typescript',
10+
[
11+
'@babel/preset-react',
12+
{
13+
runtime: 'automatic',
14+
},
15+
],
16+
],
1117
plugins: [
1218
'@babel/plugin-proposal-export-default-from',
1319
'@babel/plugin-transform-export-namespace-from',
@@ -21,7 +27,12 @@ module.exports = {
2127
version: '^7.27.1',
2228
},
2329
],
24-
path.join(babelPluginsPath, 'transform-set-proto-plugin.js'),
25-
path.join(babelPluginsPath, 'transform-url-parse-plugin.js'),
30+
// Run strict-mode transformations first to fix loose-mode code.
31+
path.join(babelPluginsPath, 'babel-plugin-strict-mode.mjs'),
32+
path.join(babelPluginsPath, 'babel-plugin-inline-require-calls.js'),
33+
path.join(babelPluginsPath, 'transform-set-proto-plugin.mjs'),
34+
path.join(babelPluginsPath, 'transform-url-parse-plugin.mjs'),
35+
// Run --with-intl=none transforms last to handle Intl/locale APIs.
36+
path.join(babelPluginsPath, 'babel-plugin-with-intl-none.mjs'),
2637
],
2738
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Polyfill for import.meta.url in CommonJS bundles.
3+
* This file is injected by esbuild's inject option.
4+
*/
5+
6+
// Convert __filename to file:// URL format.
7+
export const __importMetaUrl =
8+
typeof __filename !== 'undefined'
9+
? `file://${__filename.replace(/\\/g, '/')}`
10+
: 'file:///unknown'

.config/esbuild.cli.build.mjs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* esbuild build script for Socket CLI.
3+
*/
4+
5+
import { build } from 'esbuild'
6+
7+
import config from './esbuild.cli.config.mjs'
8+
9+
console.log('Building Socket CLI with esbuild...\n')
10+
11+
try {
12+
const result = await build(config)
13+
14+
console.log('✓ Build completed successfully')
15+
console.log(`✓ Output: ${config.outfile}`)
16+
17+
if (result.metafile) {
18+
const outputSize = Object.values(result.metafile.outputs)[0]?.bytes
19+
if (outputSize) {
20+
console.log(`✓ Bundle size: ${(outputSize / 1024 / 1024).toFixed(2)} MB`)
21+
}
22+
}
23+
} catch (error) {
24+
console.error('Build failed:', error)
25+
// eslint-disable-next-line n/no-process-exit
26+
process.exit(1)
27+
}

.config/esbuild.cli.config.mjs

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
/**
2+
* esbuild configuration for building Socket CLI as a SINGLE unified file.
3+
*
4+
* esbuild is much faster than Rollup and doesn't have template literal corruption issues.
5+
*/
6+
7+
import { execSync } from 'node:child_process'
8+
import { randomUUID } from 'node:crypto'
9+
import { existsSync, readFileSync } from 'node:fs'
10+
import { builtinModules } from 'node:module'
11+
import path from 'node:path'
12+
import { fileURLToPath } from 'node:url'
13+
14+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
15+
const rootPath = path.join(__dirname, '..')
16+
17+
// Read package.json for version and metadata.
18+
const packageJson = JSON.parse(
19+
readFileSync(path.join(rootPath, 'package.json'), 'utf-8'),
20+
)
21+
22+
// Get current git commit hash.
23+
let gitHash = ''
24+
try {
25+
gitHash = execSync('git rev-parse --short HEAD', {
26+
cwd: rootPath,
27+
encoding: 'utf-8',
28+
}).trim()
29+
} catch {}
30+
31+
// Get dependency versions from package.json devDependencies.
32+
const coanaVersion = packageJson.devDependencies?.['@coana-tech/cli'] || ''
33+
const cdxgenVersion = packageJson.devDependencies?.['@cyclonedx/cdxgen'] || ''
34+
const synpVersion = packageJson.devDependencies?.['synp'] || ''
35+
36+
// Build-time constants that can be overridden by environment variables.
37+
const publishedBuild = process.env['INLINED_SOCKET_CLI_PUBLISHED_BUILD'] === '1'
38+
const legacyBuild = process.env['INLINED_SOCKET_CLI_LEGACY_BUILD'] === '1'
39+
const sentryBuild = process.env['INLINED_SOCKET_CLI_SENTRY_BUILD'] === '1'
40+
41+
// Compute version hash (matches Rollup implementation).
42+
const randUuidSegment = randomUUID().split('-')[0]
43+
const versionHash = `${packageJson.version}:${gitHash}:${randUuidSegment}${
44+
publishedBuild ? '' : ':dev'
45+
}`
46+
47+
// Get local Socket package paths.
48+
const socketPackages = {
49+
'@socketsecurity/registry': path.join(
50+
rootPath,
51+
'..',
52+
'socket-registry',
53+
'registry',
54+
),
55+
'@socketsecurity/sdk': path.join(rootPath, '..', 'socket-sdk-js'),
56+
'@socketregistry/packageurl-js': path.join(
57+
rootPath,
58+
'..',
59+
'socket-packageurl-js',
60+
),
61+
}
62+
63+
// Resolve subpath from package.json exports.
64+
function resolvePackageSubpath(packagePath, subpath) {
65+
try {
66+
const pkgJsonPath = path.join(packagePath, 'package.json')
67+
const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'))
68+
const exports = pkgJson.exports || {}
69+
70+
// Try exact export match.
71+
const exportKey = subpath === '.' ? '.' : `./${subpath}`
72+
if (exports[exportKey]) {
73+
const exportValue = exports[exportKey]
74+
// Handle conditional exports.
75+
if (typeof exportValue === 'object' && exportValue.default) {
76+
return path.join(packagePath, exportValue.default)
77+
}
78+
// Handle simple string exports.
79+
if (typeof exportValue === 'string') {
80+
return path.join(packagePath, exportValue)
81+
}
82+
}
83+
84+
// Fallback: try conventional paths.
85+
const distPath = path.join(packagePath, 'dist', subpath)
86+
if (existsSync(`${distPath}.js`)) {
87+
return `${distPath}.js`
88+
}
89+
if (existsSync(`${distPath}.mjs`)) {
90+
return `${distPath}.mjs`
91+
}
92+
if (existsSync(path.join(distPath, 'index.js'))) {
93+
return path.join(distPath, 'index.js')
94+
}
95+
if (existsSync(path.join(distPath, 'index.mjs'))) {
96+
return path.join(distPath, 'index.mjs')
97+
}
98+
} catch {}
99+
100+
return null
101+
}
102+
103+
export default {
104+
entryPoints: [path.join(rootPath, 'src/cli-dispatch.mts')],
105+
bundle: true,
106+
outfile: path.join(rootPath, 'dist/cli.js'),
107+
platform: 'node',
108+
target: 'node20',
109+
format: 'cjs',
110+
111+
// Externalize Node.js built-ins.
112+
external: [...builtinModules, ...builtinModules.map(m => `node:${m}`)],
113+
114+
// Add shebang.
115+
banner: {
116+
js: '#!/usr/bin/env node\n"use strict";',
117+
},
118+
119+
// Source maps off for production.
120+
sourcemap: false,
121+
122+
// Don't minify (keep readable for debugging).
123+
minify: false,
124+
125+
// Keep names for better stack traces.
126+
keepNames: true,
127+
128+
// Define environment variables and import.meta.
129+
define: {
130+
'process.env.NODE_ENV': '"production"',
131+
'import.meta.url': '__importMetaUrl',
132+
// Inject build metadata (replaces Rollup replace plugin).
133+
'process.env.INLINED_SOCKET_CLI_VERSION': JSON.stringify(
134+
packageJson.version,
135+
),
136+
'process.env.INLINED_SOCKET_CLI_VERSION_HASH': JSON.stringify(versionHash),
137+
'process.env.INLINED_SOCKET_CLI_NAME': JSON.stringify(packageJson.name),
138+
'process.env.INLINED_SOCKET_CLI_HOMEPAGE': JSON.stringify(
139+
packageJson.homepage,
140+
),
141+
'process.env.INLINED_SOCKET_CLI_COANA_TECH_CLI_VERSION':
142+
JSON.stringify(coanaVersion),
143+
'process.env.INLINED_SOCKET_CLI_CYCLONEDX_CDXGEN_VERSION':
144+
JSON.stringify(cdxgenVersion),
145+
'process.env.INLINED_SOCKET_CLI_SYNP_VERSION': JSON.stringify(synpVersion),
146+
'process.env.INLINED_SOCKET_CLI_PUBLISHED_BUILD': JSON.stringify(
147+
publishedBuild ? '1' : '',
148+
),
149+
'process.env.INLINED_SOCKET_CLI_LEGACY_BUILD': JSON.stringify(
150+
legacyBuild ? '1' : '',
151+
),
152+
'process.env.INLINED_SOCKET_CLI_SENTRY_BUILD': JSON.stringify(
153+
sentryBuild ? '1' : '',
154+
),
155+
// Python version/tag are optional and typically empty for standard builds.
156+
'process.env.INLINED_SOCKET_CLI_PYTHON_VERSION': JSON.stringify(''),
157+
'process.env.INLINED_SOCKET_CLI_PYTHON_BUILD_TAG': JSON.stringify(''),
158+
},
159+
160+
// Inject import.meta.url polyfill for CJS.
161+
inject: [path.join(__dirname, 'esbuild-inject-import-meta.mjs')],
162+
163+
// Handle special cases with plugins.
164+
plugins: [
165+
{
166+
name: 'resolve-socket-packages',
167+
setup(build) {
168+
// Resolve local Socket packages with subpath exports.
169+
for (const [packageName, packagePath] of Object.entries(
170+
socketPackages,
171+
)) {
172+
// Handle package root imports.
173+
build.onResolve(
174+
{ filter: new RegExp(`^${packageName.replace('/', '\\/')}$`) },
175+
() => {
176+
if (!existsSync(packagePath)) {
177+
return null
178+
}
179+
const resolved = resolvePackageSubpath(packagePath, '.')
180+
if (resolved) {
181+
return { path: resolved }
182+
}
183+
return null
184+
},
185+
)
186+
187+
// Handle subpath imports.
188+
build.onResolve(
189+
{ filter: new RegExp(`^${packageName.replace('/', '\\/')}\\/`) },
190+
args => {
191+
if (!existsSync(packagePath)) {
192+
return null
193+
}
194+
const subpath = args.path.slice(packageName.length + 1)
195+
const resolved = resolvePackageSubpath(packagePath, subpath)
196+
if (resolved) {
197+
return { path: resolved }
198+
}
199+
return null
200+
},
201+
)
202+
}
203+
},
204+
},
205+
206+
{
207+
name: 'yoga-wasm-alias',
208+
setup(build) {
209+
// Redirect yoga-layout to our custom synchronous implementation.
210+
build.onResolve({ filter: /^yoga-layout$/ }, () => {
211+
return {
212+
path: path.join(rootPath, 'external/yoga-sync.mjs'),
213+
}
214+
})
215+
},
216+
},
217+
218+
{
219+
name: 'stub-problematic-packages',
220+
setup(build) {
221+
// Stub iconv-lite and encoding to avoid bundling issues.
222+
build.onResolve({ filter: /^(iconv-lite|encoding)(\/|$)/ }, args => {
223+
return {
224+
path: args.path,
225+
namespace: 'stub',
226+
}
227+
})
228+
229+
build.onLoad({ filter: /.*/, namespace: 'stub' }, () => {
230+
return {
231+
contents: 'module.exports = {}',
232+
loader: 'js',
233+
}
234+
})
235+
},
236+
},
237+
238+
{
239+
name: 'ignore-unsupported-files',
240+
setup(build) {
241+
// Ignore .cs files and other non-JS files.
242+
build.onResolve({ filter: /\.(cs|node-gyp)$/ }, () => {
243+
return { path: '/dev/null', external: true }
244+
})
245+
},
246+
},
247+
],
248+
}

0 commit comments

Comments
 (0)