Skip to content

Commit d7e6e81

Browse files
committed
refactor(bootstrap): replace console logging with logger and use semver
Improvements to bootstrap package: Logging changes: - Replaced process.stderr.write() with logger.log() and logger.error() - Consistent use of @socketsecurity/lib/logger throughout - Better formatted error messages Version detection: - Replaced manual version parsing with semver.gte() - Created .config/node-version.mjs with NODE_VERSION constants - Added esbuild define to inject MIN_NODE_VERSION at build time - hasModernNode() now uses semver for proper version comparison Build configuration: - Added semver to devDependencies (catalog:) - Enhanced esbuild configs with version constant injection - Tree shaking already enabled, working correctly Benefits: - More reliable version comparisons using semver library - Centralized version configuration - Better error output formatting - Consistent logging patterns
1 parent c69cbd6 commit d7e6e81

File tree

8 files changed

+156
-143
lines changed

8 files changed

+156
-143
lines changed

packages/bootstrap/.config/esbuild.npm.config.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { build } from 'esbuild'
77
import path from 'node:path'
88
import { fileURLToPath } from 'node:url'
99

10+
import { NODE_VERSION_SEMVER } from './node-version.mjs'
11+
1012
const __dirname = path.dirname(fileURLToPath(import.meta.url))
1113
const rootPath = path.resolve(__dirname, '..')
1214

@@ -15,6 +17,9 @@ const config = {
1517
js: '#!/usr/bin/env node',
1618
},
1719
bundle: true,
20+
define: {
21+
__MIN_NODE_VERSION__: JSON.stringify(NODE_VERSION_SEMVER),
22+
},
1823
entryPoints: [path.join(rootPath, 'src', 'bootstrap-npm.mts')],
1924
external: [],
2025
format: 'cjs',

packages/bootstrap/.config/esbuild.smol.config.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { build } from 'esbuild'
77
import path from 'node:path'
88
import { fileURLToPath } from 'node:url'
99

10+
import { NODE_VERSION_SEMVER } from './node-version.mjs'
1011
import { smolTransformPlugin } from './esbuild-plugin-smol-transform.mjs'
1112

1213
const __dirname = path.dirname(fileURLToPath(import.meta.url))
@@ -17,6 +18,9 @@ const config = {
1718
js: '#!/usr/bin/env node',
1819
},
1920
bundle: true,
21+
define: {
22+
__MIN_NODE_VERSION__: JSON.stringify(NODE_VERSION_SEMVER),
23+
},
2024
entryPoints: [path.join(rootPath, 'src', 'bootstrap-smol.mts')],
2125
external: [],
2226
format: 'cjs',
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Node.js version configuration for Socket CLI.
3+
* This version is used by bootstrap, smol builder, and SEA builder.
4+
*/
5+
6+
/**
7+
* Target Node.js version (with 'v' prefix).
8+
* Must have SEA (Single Executable Application) support.
9+
*/
10+
export const NODE_VERSION = 'v24.10.0'
11+
12+
/**
13+
* Semantic version (without 'v' prefix) for semver comparisons.
14+
*/
15+
export const NODE_VERSION_SEMVER = '24.10.0'

packages/bootstrap/dist/bootstrap-npm.js

Lines changed: 51 additions & 62 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/bootstrap/dist/bootstrap-smol.js

Lines changed: 51 additions & 62 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/bootstrap/src/bootstrap-npm.mts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* It downloads @socketsecurity/cli from npm and executes it.
66
*/
77

8+
import { logger } from '@socketsecurity/lib/logger'
9+
810
import { findAndExecuteCli, getArgs } from './shared/bootstrap-shared.mjs'
911

1012
async function main() {
@@ -14,6 +16,6 @@ async function main() {
1416

1517
// Run the bootstrap.
1618
main().catch((e) => {
17-
process.stderr.write(`❌ Bootstrap error: ${e instanceof Error ? e.message : String(e)}\n`)
19+
logger.error(`Bootstrap error: ${e instanceof Error ? e.message : String(e)}`)
1820
process.exit(1)
1921
})

packages/bootstrap/src/bootstrap-smol.mts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* The smol binary loads this at startup via lib/internal/process/pre_execution.js.
88
*/
99

10+
import { logger } from '@socketsecurity/lib/logger'
11+
1012
import { findAndExecuteCli, getArgs } from './shared/bootstrap-shared.mjs'
1113

1214
async function main() {
@@ -16,6 +18,6 @@ async function main() {
1618

1719
// Run the bootstrap.
1820
main().catch((e) => {
19-
process.stderr.write(`❌ Bootstrap error: ${e instanceof Error ? e.message : String(e)}\n`)
21+
logger.error(`Bootstrap error: ${e instanceof Error ? e.message : String(e)}`)
2022
process.exit(1)
2123
})

packages/bootstrap/src/shared/bootstrap-shared.mjs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,19 @@ import path from 'node:path'
1010
import { brotliDecompressSync } from 'node:zlib'
1111

1212
import { dlxPackage } from '@socketsecurity/lib/dlx-package'
13+
import { logger } from '@socketsecurity/lib/logger'
14+
import { gte } from 'semver'
1315

1416
export const SOCKET_DLX_DIR = path.join(homedir(), '.socket', '_dlx')
1517

18+
/**
19+
* Minimum Node.js version with SEA support.
20+
* This constant is injected at build time by esbuild from .config/node-version.mjs.
21+
* @type {string}
22+
*/
23+
// @ts-expect-error - Injected by esbuild define.
24+
const MIN_NODE_VERSION = __MIN_NODE_VERSION__
25+
1626
/**
1727
* Get CLI package paths.
1828
*/
@@ -34,17 +44,14 @@ export function getArgs() {
3444
}
3545

3646
/**
37-
* Check if system has modern Node.js (>=24.10.0).
47+
* Check if system has modern Node.js (>=24.10.0) with SEA support.
3848
*/
3949
export function hasModernNode() {
40-
const version = process.version // e.g., 'v24.10.0'.
41-
const match = version.match(/^v(\d+)\.(\d+)\.(\d+)/)
42-
if (!match) {
50+
try {
51+
return gte(process.version, MIN_NODE_VERSION)
52+
} catch {
4353
return false
4454
}
45-
46-
const [, major, minor] = match.map(Number)
47-
return major > 24 || (major === 24 && minor >= 10)
4855
}
4956

5057
/**
@@ -92,8 +99,8 @@ export function executeCompressedCli(bzPath, args) {
9299
* Download and install CLI using dlxPackage.
93100
*/
94101
export async function downloadCli() {
95-
process.stderr.write('📦 Socket CLI not found, downloading...\n')
96-
process.stderr.write('\n')
102+
logger.log('📦 Socket CLI not found, downloading...')
103+
logger.log('')
97104

98105
// Create directories.
99106
mkdirSync(SOCKET_DLX_DIR, { recursive: true })
@@ -111,7 +118,7 @@ export async function downloadCli() {
111118
},
112119
)
113120

114-
process.stderr.write(` Installed to: ${result.packageDir}\n`)
121+
logger.log(` Installed to: ${result.packageDir}`)
115122

116123
// Wait for installation to complete (but the spawn will fail since we don't have a command).
117124
// That's okay - we just need the package installed.
@@ -121,13 +128,13 @@ export async function downloadCli() {
121128
// Ignore execution errors - we only care that the package was installed.
122129
}
123130

124-
process.stderr.write('✅ Socket CLI installed successfully\n')
125-
process.stderr.write('\n')
131+
logger.log('✅ Socket CLI installed successfully')
132+
logger.log('')
126133

127134
return result
128135
} catch (e) {
129-
process.stderr.write('❌ Failed to download Socket CLI\n')
130-
process.stderr.write(` Error: ${e instanceof Error ? e.message : String(e)}\n`)
136+
logger.error('Failed to download Socket CLI')
137+
logger.error(` Error: ${e instanceof Error ? e.message : String(e)}`)
131138
process.exit(1)
132139
}
133140
}
@@ -154,8 +161,8 @@ export async function findAndExecuteCli(args) {
154161
}
155162

156163
// If we still can't find the CLI, exit with error.
157-
process.stderr.write('❌ Socket CLI installation failed\n')
158-
process.stderr.write(' CLI entry point not found after installation\n')
159-
process.stderr.write(` Looked in: ${cliEntry}\n`)
164+
logger.error('Socket CLI installation failed')
165+
logger.error(' CLI entry point not found after installation')
166+
logger.error(` Looked in: ${cliEntry}`)
160167
process.exit(1)
161168
}

0 commit comments

Comments
 (0)