diff --git a/packages/imports/package.json b/packages/imports/package.json index 1ba834d..9b28a46 100644 --- a/packages/imports/package.json +++ b/packages/imports/package.json @@ -18,6 +18,7 @@ "debug": "^3.1.0", "hosted-git-info": "^2.6.0", "path-browserify": "^1.0.0", - "url": "^0.11.0" + "url": "^0.11.0", + "is-url": "^1.2.4" } } diff --git a/packages/imports/src/utils.ts b/packages/imports/src/utils.ts index c1d810d..8dbb679 100644 --- a/packages/imports/src/utils.ts +++ b/packages/imports/src/utils.ts @@ -1,4 +1,5 @@ import { ResolverEngine } from "@resolver-engine/core"; +import isUrl from "is-url"; import pathSys from "path"; import urlSys from "url"; import { ImportFile } from "./parsers/importparser"; @@ -25,6 +26,25 @@ export function findImports(data: ImportFile): string[] { return result; } +function resolvePath(workingDir: string, relativePath: string): string { + // If the working dir is an URL (a file imported from an URL location) + // or the relative path is an URL (an URL imported from a local file) + // use url.resolve, which will work in both cases. + // > url.resolve('/local/folder/', 'http://example.com/myfile.sol') + // 'http://example.com/myfile.sol' + // > url.resolve('http://example.com/', 'myfile.sol') + // 'http://example.com/myfile.sol' + // + // If not, use path.resolve, since using url.resolve will escape certain + // charaters (e.g. a space as an %20), breaking the path + // > url.resolve('/local/path/with spaces/', 'myfile.sol') + // '/local/path/with%20spaces/myfile.sol' + + return isUrl(workingDir) || isUrl(relativePath) + ? urlSys.resolve(workingDir, relativePath) + : pathSys.resolve(pathSys.dirname(workingDir), relativePath); +} + interface ImportTreeNode extends ImportFile { uri: string; // uri and url the same as in rest of resolver-engine @@ -105,7 +125,7 @@ export async function gatherSources( if (workingDir !== "") { workingDir += "/"; } - const absoluteRoots = roots.map(what => urlSys.resolve(workingDir, what)); + const absoluteRoots = roots.map(what => resolvePath(workingDir, what)); for (const absWhat of absoluteRoots) { queue.push({ cwd: workingDir, file: absWhat, relativeTo: workingDir }); alreadyImported.add(absWhat); @@ -120,7 +140,7 @@ export async function gatherSources( // if not - return the same name it was imported with let relativePath: string; if (fileData.file[0] === ".") { - relativePath = urlSys.resolve(fileData.relativeTo, fileData.file); + relativePath = resolvePath(fileData.relativeTo, fileData.file); result.push({ url: relativePath, source: resolvedFile.source, provider: resolvedFile.provider }); } else { relativePath = fileData.file; @@ -131,7 +151,7 @@ export async function gatherSources( for (const foundImport of foundImports) { let importName: string; if (foundImport[0] === ".") { - importName = urlSys.resolve(relativePath, foundImport); + importName = resolvePath(relativePath, foundImport); } else { importName = foundImport; }