From ed001c212744541313a952fcad30a63b8361eb96 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 10 Feb 2025 16:57:08 +0100 Subject: [PATCH] fix_resolving_pkg --- libs/remix-url-resolver/src/resolve.ts | 89 +++++++++++++++----------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/libs/remix-url-resolver/src/resolve.ts b/libs/remix-url-resolver/src/resolve.ts index a859643325..23d66d8c71 100644 --- a/libs/remix-url-resolver/src/resolve.ts +++ b/libs/remix-url-resolver/src/resolve.ts @@ -136,7 +136,6 @@ export class RemixURLResolver { * Handle an import statement based on NPM * @param url The url of the NPM import statement */ - async handleNpmImport(url: string): Promise { if (!url) throw new Error('url is empty') let fetchUrl = url @@ -144,45 +143,16 @@ export class RemixURLResolver { if (this.getDependencies && !isVersioned) { try { const { deps, yarnLock, packageLock } = await this.getDependencies() - let matchLength = 0 - let pkg if (deps) { - Object.keys(deps).map((dep) => { - const reg = new RegExp(dep + '/', 'g') - const match = url.match(reg) - if (match && match.length > 0 && matchLength < match[0].length) { - matchLength = match[0].length - pkg = dep - } - }) - if (pkg) { - let version - if (yarnLock) { - // yarn.lock - const regex = new RegExp(`"${pkg}@(.*)"`, 'g') - const yarnVersion = regex.exec(yarnLock) - if (yarnVersion && yarnVersion.length > 1) { - version = yarnVersion[1] - } - } - if (!version && packageLock && packageLock['dependencies'] && packageLock['dependencies'][pkg] && packageLock['dependencies'][pkg]['version']) { - // package-lock.json - version = packageLock['dependencies'][pkg]['version'] - } - if (!version) { - // package.json - version = deps[pkg] - } - if (version) { - // If the entry is pointing to a github repo, redirect to correct handler instead of continuing - if (version.startsWith("github:")) { - const [, repo, tag] = version.match(/github:([^#]+)#(.+)/); - const filePath = url.replace(/^[^/]+\//, ''); - return this.handleGithubCall(repo, `blob/${tag}/${filePath}`); - } - const versionSemver = semver.minVersion(version) - fetchUrl = url.replace(pkg, `${pkg}@${versionSemver.version}`) - } + // Packages have usually a slash in the name which make it difficult to distinguish them from a path. + // we first try to resolve the path with a slash. packages like @openzepplin/contracts will be resolved in that case. + let transformedUrl = getPkg(fetchUrl.split('/')[0] + '/' + fetchUrl.split('/')[1], yarnLock, packageLock, deps, url, fetchUrl) + if (!transformedUrl) { + // then we fallback to the case where the package doesn't have a slash in its name. + transformedUrl = getPkg(fetchUrl.split('/')[0], yarnLock, packageLock, deps, url, fetchUrl) + } + if (transformedUrl) { + fetchUrl = transformedUrl } } } catch (e) { @@ -269,3 +239,44 @@ export class RemixURLResolver { function semverRegex() { return /(?<=^v?|\sv?)(?:(?:0|[1-9]\d{0,9}?)\.){2}(?:0|[1-9]\d{0,9})(?:-(?:--+)?(?:0|[1-9]\d*|\d*[a-z]+\d*)){0,100}(?=$| |\+|\.)(?:(?<=-\S+)(?:\.(?:--?|[\da-z-]*[a-z-]\d*|0|[1-9]\d*)){1,100}?)?(?!\.)(?:\+(?:[\da-z]\.?-?){1,100}?(?!\w))?(?!\+)/gi; } + +function getPkg(pkg, yarnLock, packageLock, deps, url, fetchUrl) { + let version + if (yarnLock) { + // yarn.lock + const regex = new RegExp(`"${pkg}@(.*)"`, 'g') + const yarnVersion = regex.exec(yarnLock) + if (yarnVersion && yarnVersion.length > 1) { + version = yarnVersion[1] + } + } + if (!version && packageLock && packageLock['packages'] && packageLock['packages']['node_modules/' + pkg] && packageLock['packages']['node_modules/' + pkg]['version']) { + // package-lock.json version 3 + version = packageLock['packages']['node_modules/' + pkg]['version'] + } + if (!version && packageLock && packageLock['dependencies'] && packageLock['dependencies'][pkg] && packageLock['dependencies'][pkg]['version']) { + // package-lock.json version 2 + version = packageLock['dependencies'][pkg]['version'] + } + // package.json + if (deps[pkg]) { + version = deps[pkg] + } + if (version) { + // If the entry is pointing to a github repo, redirect to correct handler instead of continuing + if (version.startsWith("github:")) { + const [, repo, tag] = version.match(/github:([^#]+)#(.+)/); + const filePath = url.replace(/^[^/]+\//, ''); + return this.handleGithubCall(repo, `blob/${tag}/${filePath}`); + } + if (version.startsWith('npm:')) { + fetchUrl = url.replace(pkg, version.replace('npm:', '')) + return fetchUrl + } else { + // const versionSemver = semver.minVersion(version) + fetchUrl = url.replace(pkg, `${pkg}@${version}`) + return fetchUrl + } + } + return null +}