diff --git a/apps/railway-executor/deno.json b/apps/railway-executor/deno.json new file mode 100644 index 0000000..cc2c39b --- /dev/null +++ b/apps/railway-executor/deno.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "allowJs": true, + "lib": ["deno.window"], + "strict": true + }, + "nodeModulesDir": true, + "unstable": ["byonm"], + "imports": { + "zod-to-json-schema": "https://esm.sh/zod-to-json-schema@3.25.0" + } +} diff --git a/apps/railway-executor/server.ts b/apps/railway-executor/server.ts index 9e9dc75..2231d42 100644 --- a/apps/railway-executor/server.ts +++ b/apps/railway-executor/server.ts @@ -38,11 +38,48 @@ async function loadAndDescribe(req: Request): Promise { console.log(`✅ Cache hit: ${cacheKey}`); toolModule = moduleCache.get(cacheKey); } else { - // Dynamic import from esm.sh (Deno supports this natively!) - const url = importUrl || `https://esm.sh/${packageName}@${version}`; - console.log(`📦 Importing: ${url}`); + // Try multiple import strategies for maximum compatibility + // biome-ignore lint/suspicious/noImplicitAnyLet: Module type is dynamic + let module; + // biome-ignore lint/suspicious/noImplicitAnyLet: Error type is dynamic + let importError; + + // Strategy 1: Use Deno's npm: specifier (Node.js compatibility mode) + try { + const npmUrl = `npm:${packageName}@${version}`; + console.log(`📦 Trying npm: specifier (Node.js compat): ${npmUrl}`); + module = await import(npmUrl); + console.log('✅ Successfully imported via npm: specifier'); + } catch (error) { + console.log('❌ npm: import failed:', error.message); + importError = error; + + // Strategy 2: Fall back to esm.sh with explicit Node target + try { + const url = importUrl || `https://esm.sh/${packageName}@${version}`; + // Force esm.sh to use Node.js target instead of Deno target + const esmUrl = url.includes('?') ? `${url}&target=esnext` : `${url}?target=esnext`; + console.log(`📦 Trying esm.sh with Node target: ${esmUrl}`); + module = await import(esmUrl); + console.log('✅ Successfully imported via esm.sh'); + } catch (esmError) { + console.error('❌ Both import strategies failed'); + console.error(' npm: error:', error.message); + console.error(' esm.sh error:', esmError.message); + return Response.json( + { + success: false, + error: `Failed to import package: ${esmError.message}`, + details: { + npmError: error.message, + esmError: esmError.message, + }, + }, + { status: 500 } + ); + } + } - const module = await import(url); let rawExport = module[exportName]; if (!rawExport) { @@ -292,10 +329,49 @@ async function executeTool(req: Request): Promise { console.log(`✅ Using cached tool: ${cacheKey}`); toolModule = moduleCache.get(cacheKey); } else { - const url = importUrl || `https://esm.sh/${packageName}@${version}`; - console.log(`📦 Importing for execution: ${url}`); + // Try multiple import strategies for maximum compatibility + // biome-ignore lint/suspicious/noImplicitAnyLet: Module type is dynamic + let module; + // biome-ignore lint/suspicious/noImplicitAnyLet: Error type is dynamic + let importError; + + // Strategy 1: Use Deno's npm: specifier (Node.js compatibility mode) + try { + const npmUrl = `npm:${packageName}@${version}`; + console.log(`📦 Trying npm: specifier (Node.js compat): ${npmUrl}`); + module = await import(npmUrl); + console.log('✅ Successfully imported via npm: specifier'); + } catch (error) { + console.log('❌ npm: import failed:', error.message); + importError = error; + + // Strategy 2: Fall back to esm.sh with explicit Node target + try { + const url = importUrl || `https://esm.sh/${packageName}@${version}`; + // Force esm.sh to use Node.js target instead of Deno target + const esmUrl = url.includes('?') ? `${url}&target=esnext` : `${url}?target=esnext`; + console.log(`📦 Trying esm.sh with Node target: ${esmUrl}`); + module = await import(esmUrl); + console.log('✅ Successfully imported via esm.sh'); + } catch (esmError) { + console.error('❌ Both import strategies failed'); + console.error(' npm: error:', error.message); + console.error(' esm.sh error:', esmError.message); + return Response.json( + { + success: false, + error: `Failed to import package: ${esmError.message}`, + details: { + npmError: error.message, + esmError: esmError.message, + }, + executionTimeMs: Date.now() - startTime, + }, + { status: 500 } + ); + } + } - const module = await import(url); let rawExport = module[exportName]; if (!rawExport) {