22import { Command } from 'commander'
33import { execSync } from 'child_process'
44import { existsSync , mkdirSync , readdirSync , readFileSync , statSync } from 'fs'
5- import { basename , dirname , extname , join , relative , resolve } from 'path'
5+ import { basename , dirname , extname , isAbsolute , join , normalize , relative , resolve } from 'path'
66import { checkLeapInstallation } from './chain/install'
77
88/**
@@ -19,7 +19,10 @@ export async function compileContract(file: string | undefined, outputDir: strin
1919 return
2020 }
2121
22- const absoluteOutputDir = resolve ( outputDir )
22+ // Resolve output directory to absolute path, handling both relative and absolute paths
23+ const absoluteOutputDir = isAbsolute ( outputDir )
24+ ? normalize ( outputDir )
25+ : normalize ( resolve ( outputDir ) )
2326 ensureOutputDirectory ( absoluteOutputDir )
2427
2528 // Ensure cdt-cpp is installed
@@ -92,11 +95,11 @@ export async function getFilesToCompile(
9295}
9396
9497/**
95- * Ensure output directory exists
98+ * Ensure output directory exists, create it if it doesn't
9699 */
97100function ensureOutputDirectory ( dir : string ) : void {
98101 if ( ! existsSync ( dir ) ) {
99- throw new Error ( `Output directory does not exist: ${ dir } ` )
102+ mkdirSync ( dir , { recursive : true } )
100103 }
101104}
102105
@@ -314,7 +317,15 @@ async function compileSingleFile(
314317 }
315318 } else {
316319 // Use path relative to current directory (preserve structure)
317- relativePath = relative ( currentDir , filePath )
320+ // But if the relative path goes outside currentDir (starts with ..),
321+ // just use the filename to avoid path issues
322+ const relPath = relative ( currentDir , filePath )
323+ if ( relPath . startsWith ( '..' ) ) {
324+ // If path goes outside current directory, just use filename
325+ relativePath = basename ( filePath , '.cpp' )
326+ } else {
327+ relativePath = relPath
328+ }
318329 }
319330
320331 const relativeDir = dirname ( relativePath )
@@ -326,7 +337,8 @@ async function compileSingleFile(
326337 wasmOutput = join ( outputDir , `${ fileName } .wasm` )
327338 } else {
328339 // File is in a subdirectory, preserve the structure (but without src/ prefix if stripped)
329- const outputSubDir = join ( outputDir , relativeDir )
340+ // Normalize the path to prevent issues with relative paths containing '..'
341+ const outputSubDir = normalize ( join ( outputDir , relativeDir ) )
330342 // Ensure the output subdirectory exists
331343 if ( ! existsSync ( outputSubDir ) ) {
332344 mkdirSync ( outputSubDir , { recursive : true } )
0 commit comments