33 */
44
55import { promises as fs } from 'node:fs'
6+ import Module from 'node:module'
67import path from 'node:path'
78import { fileURLToPath } from 'node:url'
89
910import { parse } from '@babel/parser'
1011import MagicString from 'magic-string'
1112
12- import { getLocalPackageAliases } from '../scripts/utils/get-local-package-aliases.mjs'
13+ import { NODE_MODULES } from '@socketsecurity/lib/paths/dirnames'
14+ import { envAsBoolean } from '@socketsecurity/lib/env/helpers'
15+ import { getDefaultLogger } from '@socketsecurity/lib/logger'
1316
1417const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) )
18+
1519const rootPath = path . join ( __dirname , '..' )
1620const srcPath = path . join ( rootPath , 'src' )
1721const distPath = path . join ( rootPath , 'dist' )
1822
23+ const logger = getDefaultLogger ( )
24+
1925/**
2026 * Plugin to shorten module paths in bundled output with conflict detection.
2127 * Uses @babel/parser and magic-string for precise AST-based modifications.
@@ -31,14 +37,16 @@ function createPathShorteningPlugin() {
3137 )
3238
3339 for ( const outputPath of outputs ) {
40+ // eslint-disable-next-line no-await-in-loop
3441 const content = await fs . readFile ( outputPath , 'utf8' )
3542 const magicString = new MagicString ( content )
3643
3744 // Track module paths and their shortened versions
3845 const pathMap = new Map ( )
3946 const conflictDetector = new Map ( )
4047
41- function shortenPath ( longPath ) {
48+ // eslint-disable-next-line unicorn/consistent-function-scoping
49+ const shortenPath = longPath => {
4250 if ( pathMap . has ( longPath ) ) {
4351 return pathMap . get ( longPath )
4452 }
@@ -67,8 +75,8 @@ function createPathShorteningPlugin() {
6775 if ( conflictDetector . has ( shortPath ) ) {
6876 const existingPath = conflictDetector . get ( shortPath )
6977 if ( existingPath !== longPath ) {
70- console . warn (
71- `⚠ Path conflict detected:\n "${ shortPath } "\n Maps to: "${ existingPath } "\n Also from: "${ longPath } "\n Keeping original paths to avoid conflict.` ,
78+ logger . warn (
79+ `Path conflict detected:\n "${ shortPath } "\n Maps to: "${ existingPath } "\n Also from: "${ longPath } "\n Keeping original paths to avoid conflict.` ,
7280 )
7381 shortPath = longPath
7482 }
@@ -91,7 +99,7 @@ function createPathShorteningPlugin() {
9199 for ( const comment of ast . comments || [ ] ) {
92100 if (
93101 comment . type === 'CommentLine' &&
94- comment . value . includes ( 'node_modules' )
102+ comment . value . includes ( NODE_MODULES )
95103 ) {
96104 const originalPath = comment . value . trim ( )
97105 const shortPath = shortenPath ( originalPath )
@@ -115,7 +123,7 @@ function createPathShorteningPlugin() {
115123 if (
116124 node . type === 'StringLiteral' &&
117125 node . value &&
118- node . value . includes ( 'node_modules' )
126+ node . value . includes ( NODE_MODULES )
119127 ) {
120128 const originalPath = node . value
121129 const shortPath = shortenPath ( originalPath )
@@ -145,11 +153,11 @@ function createPathShorteningPlugin() {
145153 }
146154
147155 walk ( ast . program )
156+ // eslint-disable-next-line no-await-in-loop
148157 await fs . writeFile ( outputPath , magicString . toString ( ) , 'utf8' )
149158 } catch ( error ) {
150- console . error (
151- `Failed to shorten paths in ${ outputPath } :` ,
152- error . message ,
159+ logger . error (
160+ `Failed to shorten paths in ${ outputPath } : ${ error . message } ` ,
153161 )
154162 }
155163 }
@@ -160,57 +168,38 @@ function createPathShorteningPlugin() {
160168}
161169
162170/**
163- * Plugin to handle local package aliases .
164- * Provides consistent alias resolution across all Socket repos .
171+ * Plugin to ensure all Node.js builtins use the node: protocol .
172+ * Intercepts imports of Node.js built-in modules and rewrites them to use the node: prefix .
165173 */
166- function createAliasPlugin ( ) {
167- const aliases = getLocalPackageAliases ( rootPath )
168-
169- // Only create plugin if we have local aliases
170- if ( Object . keys ( aliases ) . length === 0 ) {
171- return null
172- }
173-
174- // Packages that should always be bundled (even when using local aliases)
175- const ALWAYS_BUNDLED = new Set ( [ '@socketsecurity/lib' ] )
176-
174+ function createNodeProtocolPlugin ( ) {
175+ // Get list of Node.js built-in modules dynamically
177176 return {
178- name : 'local-package-aliases ' ,
177+ name : 'node-protocol ' ,
179178 setup ( build ) {
180- // Intercept imports for aliased packages and mark as external.
181- for ( const [ packageName , _aliasPath ] of Object . entries ( aliases ) ) {
182- // Skip packages that should always be bundled - let esbuild bundle them naturally
183- if ( ALWAYS_BUNDLED . has ( packageName ) ) {
179+ for ( const builtin of Module . builtinModules ) {
180+ // Skip builtins that already have node: prefix
181+ if ( builtin . startsWith ( 'node:' ) ) {
184182 continue
185183 }
186184
187- // Match both exact package name and subpath imports.
185+ // Match imports that don't already have the node: prefix
186+ // Escape special regex characters in module name
187+ const escapedBuiltin = builtin . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' )
188188 build . onResolve (
189- { filter : new RegExp ( `^${ packageName } (/|$)` ) } ,
190- args => {
191- // Mark as external using the original package name to avoid absolute paths in output.
192- // This ensures require('@socketsecurity/lib') instead of require('/absolute/path/to/socket-lib/dist').
193- return { path : args . path , external : true }
189+ { filter : new RegExp ( `^${ escapedBuiltin } $` ) } ,
190+ _args => {
191+ // Return with node: prefix and mark as external
192+ return {
193+ path : `node:${ builtin } ` ,
194+ external : true ,
195+ }
194196 } ,
195197 )
196198 }
197199 } ,
198200 }
199201}
200202
201- // Get local package aliases for bundled packages
202- function getBundledPackageAliases ( ) {
203- const aliases = getLocalPackageAliases ( rootPath )
204- const bundledAliases = { }
205-
206- // @socketsecurity /lib should always be bundled (not external)
207- if ( aliases [ '@socketsecurity/lib' ] ) {
208- bundledAliases [ '@socketsecurity/lib' ] = aliases [ '@socketsecurity/lib' ]
209- }
210-
211- return bundledAliases
212- }
213-
214203// Build configuration for ESM output
215204export const buildConfig = {
216205 entryPoints : [ `${ srcPath } /index.ts` , `${ srcPath } /testing.ts` ] ,
@@ -222,28 +211,22 @@ export const buildConfig = {
222211 platform : 'node' ,
223212 // Target Node.js 18+ features.
224213 target : 'node18' ,
225- sourcemap : false ,
214+ // Enable source maps for coverage (set COVERAGE=true env var)
215+ sourcemap : envAsBoolean ( process . env . COVERAGE ) ,
226216 minify : false ,
227217 treeShaking : true ,
228218 // For bundle analysis
229219 metafile : true ,
230220 logLevel : 'info' ,
231221
232- // Alias local packages that should be bundled (not external)
233- alias : getBundledPackageAliases ( ) ,
234-
235- // Use plugin for local package aliases (consistent across all Socket repos).
236- plugins : [ createPathShorteningPlugin ( ) , createAliasPlugin ( ) ] . filter ( Boolean ) ,
222+ // Use plugins for module resolution and path handling.
223+ plugins : [ createNodeProtocolPlugin ( ) , createPathShorteningPlugin ( ) ] . filter (
224+ Boolean ,
225+ ) ,
237226
238227 // External dependencies.
239- // Note: @socketsecurity /lib is bundled (not external) to reduce consumer dependencies.
240- // With format: 'cjs', bundling CJS code works fine (no __require wrapper issues).
241- external : [ ] ,
242-
243- // Banner for generated code
244- banner : {
245- js : '/* Socket SDK CJS - Built with esbuild */' ,
246- } ,
228+ // @socketsecurity /lib is external (not bundled) - consumers must install it.
229+ external : [ '@socketsecurity/lib' ] ,
247230
248231 // TypeScript configuration
249232 tsconfig : path . join ( rootPath , 'tsconfig.json' ) ,
@@ -265,12 +248,12 @@ export const watchConfig = {
265248 watch : {
266249 onRebuild ( error , result ) {
267250 if ( error ) {
268- console . error ( ' Watch build failed:' , error )
251+ logger . error ( ` Watch build failed: ${ error } ` )
269252 } else {
270- console . log ( 'Watch build succeeded' )
253+ logger . log ( 'Watch build succeeded' )
271254 if ( result . metafile ) {
272255 const analysis = analyzeMetafile ( result . metafile )
273- console . log ( analysis )
256+ logger . log ( analysis )
274257 }
275258 }
276259 } ,
0 commit comments