@@ -8,9 +8,13 @@ import path from 'node:path'
88import process from 'node:process'
99import { fileURLToPath } from 'node:url'
1010
11+ import type { Comment } from '@babel/types'
12+
1113import { parse } from '@babel/parser'
1214import MagicString from 'magic-string'
1315
16+ import type { BuildResult , Metafile , OnResolveArgs , PluginBuild } from 'esbuild'
17+
1418import { NODE_MODULES } from '@socketsecurity/lib/paths/dirnames'
1519import { envAsBoolean } from '@socketsecurity/lib/env/helpers'
1620import { getDefaultLogger } from '@socketsecurity/lib/logger'
@@ -35,8 +39,8 @@ const externalDependencies = Object.keys(packageJson.dependencies || {})
3539function createPathShorteningPlugin ( ) {
3640 return {
3741 name : 'shorten-module-paths' ,
38- setup ( build ) {
39- build . onEnd ( async result => {
42+ setup ( build : PluginBuild ) {
43+ build . onEnd ( async ( result : BuildResult ) => {
4044 if ( ! result . outputFiles && result . metafile ) {
4145 const outputs = Object . keys ( result . metafile . outputs ) . filter (
4246 f => f . endsWith ( '.js' ) || f . endsWith ( '.mjs' ) ,
@@ -52,7 +56,7 @@ function createPathShorteningPlugin() {
5256 const conflictDetector = new Map ( )
5357
5458 // eslint-disable-next-line unicorn/consistent-function-scoping
55- const shortenPath = longPath => {
59+ const shortenPath = ( longPath : string ) : string => {
5660 if ( pathMap . has ( longPath ) ) {
5761 return pathMap . get ( longPath )
5862 }
@@ -102,15 +106,19 @@ function createPathShorteningPlugin() {
102106 } )
103107
104108 // Walk through all comments
105- for ( const comment of ast . comments || [ ] ) {
109+ for ( const comment of ( ast . comments || [ ] ) as Comment [ ] ) {
106110 if (
107111 comment . type === 'CommentLine' &&
108112 comment . value . includes ( NODE_MODULES )
109113 ) {
110114 const originalPath = comment . value . trim ( )
111115 const shortPath = shortenPath ( originalPath )
112116
113- if ( shortPath !== originalPath ) {
117+ if (
118+ shortPath !== originalPath &&
119+ comment . start != null &&
120+ comment . end != null
121+ ) {
114122 magicString . overwrite (
115123 comment . start ,
116124 comment . end ,
@@ -121,33 +129,36 @@ function createPathShorteningPlugin() {
121129 }
122130
123131 // Walk through all string literals
124- function walk ( node ) {
132+ function walk ( node : unknown ) {
125133 if ( ! node || typeof node !== 'object' ) {
126134 return
127135 }
136+ const n = node as Record < string , unknown >
128137
129138 if (
130- node . type === 'StringLiteral' &&
131- node . value &&
132- node . value . includes ( NODE_MODULES )
139+ n [ ' type' ] === 'StringLiteral' &&
140+ typeof n [ ' value' ] === 'string' &&
141+ n [ ' value' ] . includes ( NODE_MODULES )
133142 ) {
134- const originalPath = node . value
143+ const originalPath = n [ ' value' ]
135144 const shortPath = shortenPath ( originalPath )
136-
137- if ( shortPath !== originalPath ) {
138- magicString . overwrite (
139- node . start + 1 ,
140- node . end - 1 ,
141- shortPath ,
142- )
145+ const start = n [ 'start' ]
146+ const end = n [ 'end' ]
147+
148+ if (
149+ shortPath !== originalPath &&
150+ typeof start === 'number' &&
151+ typeof end === 'number'
152+ ) {
153+ magicString . overwrite ( start + 1 , end - 1 , shortPath )
143154 }
144155 }
145156
146- for ( const key of Object . keys ( node ) ) {
157+ for ( const key of Object . keys ( n ) ) {
147158 if ( key === 'start' || key === 'end' || key === 'loc' ) {
148159 continue
149160 }
150- const value = node [ key ]
161+ const value = n [ key ]
151162 if ( Array . isArray ( value ) ) {
152163 for ( const item of value ) {
153164 walk ( item )
@@ -158,12 +169,12 @@ function createPathShorteningPlugin() {
158169 }
159170 }
160171
161- walk ( ast . program )
172+ walk ( ast . program as unknown )
162173 // eslint-disable-next-line no-await-in-loop
163174 await fs . writeFile ( outputPath , magicString . toString ( ) , 'utf8' )
164- } catch ( error ) {
175+ } catch ( e ) {
165176 logger . error (
166- `Failed to shorten paths in ${ outputPath } : ${ error . message } ` ,
177+ `Failed to shorten paths in ${ outputPath } : ${ e instanceof Error ? e . message : String ( e ) } ` ,
167178 )
168179 }
169180 }
@@ -181,7 +192,7 @@ function createNodeProtocolPlugin() {
181192 // Get list of Node.js built-in modules dynamically
182193 return {
183194 name : 'node-protocol' ,
184- setup ( build ) {
195+ setup ( build : PluginBuild ) {
185196 for ( const builtin of Module . builtinModules ) {
186197 // Skip builtins that already have node: prefix
187198 if ( builtin . startsWith ( 'node:' ) ) {
@@ -193,7 +204,7 @@ function createNodeProtocolPlugin() {
193204 const escapedBuiltin = builtin . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' )
194205 build . onResolve (
195206 { filter : new RegExp ( `^${ escapedBuiltin } $` ) } ,
196- _args => {
207+ ( _args : OnResolveArgs ) => {
197208 // Return with node: prefix and mark as external
198209 return {
199210 path : `node:${ builtin } ` ,
@@ -237,7 +248,7 @@ function createLibStubPlugin() {
237248
238249 return {
239250 name : 'stub-unused-internals' ,
240- setup ( build ) {
251+ setup ( build : PluginBuild ) {
241252 // Stub heavy lib modules with empty exports.
242253 build . onLoad ( { filter : libStubPattern } , ( ) => ( {
243254 contents : 'module.exports = {}' ,
@@ -262,13 +273,13 @@ export const buildConfig = {
262273 outdir : distPath ,
263274 outbase : srcPath ,
264275 bundle : true ,
265- format : 'cjs' ,
276+ format : 'cjs' as const ,
266277 // Target Node.js environment (not browser).
267- platform : 'node' ,
278+ platform : 'node' as const ,
268279 // Target Node.js 18+ features.
269280 target : 'node18' ,
270281 // Enable source maps for coverage (set COVERAGE=true env var)
271- sourcemap : envAsBoolean ( process . env . COVERAGE ) ,
282+ sourcemap : envAsBoolean ( process . env [ ' COVERAGE' ] ) ,
272283 minify : false ,
273284 treeShaking : true ,
274285 // For bundle analysis
@@ -292,7 +303,7 @@ export const buildConfig = {
292303 // Define constants for optimization
293304 define : {
294305 'process.env.NODE_ENV' : JSON . stringify (
295- process . env . NODE_ENV || 'production' ,
306+ process . env [ ' NODE_ENV' ] || 'production' ,
296307 ) ,
297308 } ,
298309}
@@ -301,15 +312,15 @@ export const buildConfig = {
301312export const watchConfig = {
302313 ...buildConfig ,
303314 minify : false ,
304- sourcemap : 'inline' ,
315+ sourcemap : 'inline' as const ,
305316 logLevel : 'debug' ,
306317 watch : {
307- onRebuild ( error , result ) {
318+ onRebuild ( error : Error | null , result : BuildResult | null ) {
308319 if ( error ) {
309320 logger . error ( `Watch build failed: ${ error } ` )
310321 } else {
311322 logger . log ( 'Watch build succeeded' )
312- if ( result . metafile ) {
323+ if ( result ? .metafile ) {
313324 const analysis = analyzeMetafile ( result . metafile )
314325 logger . log ( analysis )
315326 }
@@ -321,12 +332,12 @@ export const watchConfig = {
321332/**
322333 * Analyze build output for size information
323334 */
324- function analyzeMetafile ( metafile ) {
335+ function analyzeMetafile ( metafile : Metafile ) {
325336 const outputs = Object . keys ( metafile . outputs )
326337 let totalSize = 0
327338
328339 const files = outputs . map ( file => {
329- const output = metafile . outputs [ file ]
340+ const output = metafile . outputs [ file ] !
330341 totalSize += output . bytes
331342 return {
332343 name : path . relative ( rootPath , file ) ,
0 commit comments