mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 06:30:17 +00:00
refactor(js): NPM modules resolution (#722)
Refactored NPM modules resolution
This commit is contained in:
parent
19c4e509a8
commit
df19ec6734
@ -2,7 +2,7 @@ package aqua
|
||||
|
||||
import cats.effect.kernel.Async
|
||||
import fs2.io.file.{Files, Path}
|
||||
import aqua.js.{Meta, Module}
|
||||
import aqua.js.Npm
|
||||
import scribe.Logging
|
||||
import cats.syntax.applicative.*
|
||||
import cats.syntax.apply.*
|
||||
@ -14,51 +14,50 @@ import scala.util.Try
|
||||
|
||||
object PlatformPackagePath extends Logging {
|
||||
|
||||
// it could be global installed aqua and local installed, different paths for this
|
||||
def getPackagePath[F[_]: Async](path: String): F[Path] = {
|
||||
val meta = Meta.metaUrl
|
||||
val req = Module.createRequire(meta)
|
||||
Try {
|
||||
// this can throw an error, global or local project path
|
||||
val builtinPath = Path(req.resolve("@fluencelabs/aqua-lib/builtin.aqua").toString)
|
||||
val rootProjectPath = builtinPath.resolve("../../../..")
|
||||
// hack, check if it is a local dependency or global
|
||||
val filePath = rootProjectPath.resolve(path)
|
||||
Files[F].exists(filePath).map {
|
||||
// if not exists, it should be local dependency, check in node_modules
|
||||
case false => rootProjectPath.resolve("node_modules/@fluencelabs/aqua").resolve(path)
|
||||
case true => filePath
|
||||
// get path of nth parent strictly
|
||||
private def parentStrict(n: Int)(path: Path): Option[Path] =
|
||||
if (n <= 0) Some(path)
|
||||
else (0 until n).foldLeft(Option(path))((p, _) => p.flatMap(_.parent))
|
||||
|
||||
}
|
||||
}.getOrElse {
|
||||
// we don't care about path if there is no builtins, but must write an error
|
||||
logger.error("Unexpected. Cannot find project path")
|
||||
Path(path).pure[F]
|
||||
// get path of nth parent relatively
|
||||
private def parentRelative(n: Int)(path: Path): Path =
|
||||
if (n <= 0) path
|
||||
else path.resolve((0 until n).map(_ => "../").mkString)
|
||||
|
||||
// could throw an error
|
||||
private def builtinPath = Path(Npm.resolveModule("@fluencelabs/aqua-lib/builtin.aqua"))
|
||||
|
||||
// it could be global installed aqua and local installed, different paths for this
|
||||
def getPackagePath[F[_]: Async](path: String): F[Path] = Try {
|
||||
val rootProjectPath = parentRelative(4)(builtinPath)
|
||||
// hack, check if it is a local dependency or global
|
||||
val filePath = rootProjectPath.resolve(path)
|
||||
Files[F].exists(filePath).map {
|
||||
// if not exists, it should be local dependency, check in node_modules
|
||||
case false => rootProjectPath.resolve("node_modules/@fluencelabs/aqua").resolve(path)
|
||||
case true => filePath
|
||||
}
|
||||
}.getOrElse {
|
||||
// we don't care about path if there is no builtins, but must write an error
|
||||
logger.error("Unexpected. Cannot find project path")
|
||||
Path(path).pure[F]
|
||||
}
|
||||
|
||||
// get path to node modules if there is `aqua-lib` module with `builtin.aqua` in it
|
||||
def getGlobalNodeModulePath: List[Path] = {
|
||||
val meta = Meta.metaUrl
|
||||
val req = Module.createRequire(meta)
|
||||
Try {
|
||||
// this can throw an error
|
||||
val pathStr = req.resolve("@fluencelabs/aqua-lib/builtin.aqua").toString
|
||||
// hack
|
||||
val globalAquaPath = Path(pathStr).parent.flatMap(_.parent.flatMap(_.parent))
|
||||
def getGlobalNodeModulePath: List[Path] = Try {
|
||||
// hack
|
||||
val globalAquaPath = parentStrict(3)(builtinPath)
|
||||
|
||||
// Also hack. If we found installed `aqua-lib`, it should be in `node_modules` global path.
|
||||
// In global `node_modules` could be installed aqua libs and we must use them,
|
||||
// if they were imported in aqua files
|
||||
val globalNodeModulesPath =
|
||||
globalAquaPath.flatMap(_.parent.flatMap(_.parent.flatMap(_.parent)))
|
||||
|
||||
globalAquaPath.toList ++ globalNodeModulesPath.toList
|
||||
}.getOrElse {
|
||||
// we don't care about path if there is no builtins, but must write an error
|
||||
logger.error("Unexpected. Cannot find 'aqua-lib' dependency with `builtin.aqua` in it")
|
||||
Nil
|
||||
}
|
||||
// Also hack. If we found installed `aqua-lib`, it should be in `node_modules` global path.
|
||||
// In global `node_modules` could be installed aqua libs and we must use them,
|
||||
// if they were imported in aqua files
|
||||
val globalNodeModulesPath = globalAquaPath.flatMap(parentStrict(3))
|
||||
|
||||
globalAquaPath.toList ++ globalNodeModulesPath.toList
|
||||
}.getOrElse {
|
||||
// we don't care about path if there is no builtins, but must write an error
|
||||
logger.error("Unexpected. Cannot find 'aqua-lib' dependency with `builtin.aqua` in it")
|
||||
Nil
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,14 +12,24 @@ object Meta {
|
||||
val metaUrl: String = js.native
|
||||
}
|
||||
|
||||
// Require function from javascript
|
||||
trait Require extends js.Object {
|
||||
|
||||
// resolve path to module
|
||||
def resolve(request: String): String
|
||||
}
|
||||
|
||||
@js.native
|
||||
@JSImport("module", JSImport.Namespace)
|
||||
object Module extends js.Object {
|
||||
|
||||
// make it possible to use `require` in ES module type
|
||||
def createRequire(str: String): Require = js.native
|
||||
def createRequire(filename: String): Require = js.native
|
||||
}
|
||||
|
||||
trait Require extends js.Object {
|
||||
def resolve(str: String): Any
|
||||
object Npm {
|
||||
private def require = Module.createRequire(Meta.metaUrl)
|
||||
|
||||
// Resolve path to module
|
||||
def resolveModule(path: String): String = require.resolve(path)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user