mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 22:50:18 +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 cats.effect.kernel.Async
|
||||||
import fs2.io.file.{Files, Path}
|
import fs2.io.file.{Files, Path}
|
||||||
import aqua.js.{Meta, Module}
|
import aqua.js.Npm
|
||||||
import scribe.Logging
|
import scribe.Logging
|
||||||
import cats.syntax.applicative.*
|
import cats.syntax.applicative.*
|
||||||
import cats.syntax.apply.*
|
import cats.syntax.apply.*
|
||||||
@ -14,44 +14,44 @@ import scala.util.Try
|
|||||||
|
|
||||||
object PlatformPackagePath extends Logging {
|
object PlatformPackagePath extends Logging {
|
||||||
|
|
||||||
|
// 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))
|
||||||
|
|
||||||
|
// 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
|
// it could be global installed aqua and local installed, different paths for this
|
||||||
def getPackagePath[F[_]: Async](path: String): F[Path] = {
|
def getPackagePath[F[_]: Async](path: String): F[Path] = Try {
|
||||||
val meta = Meta.metaUrl
|
val rootProjectPath = parentRelative(4)(builtinPath)
|
||||||
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
|
// hack, check if it is a local dependency or global
|
||||||
val filePath = rootProjectPath.resolve(path)
|
val filePath = rootProjectPath.resolve(path)
|
||||||
Files[F].exists(filePath).map {
|
Files[F].exists(filePath).map {
|
||||||
// if not exists, it should be local dependency, check in node_modules
|
// if not exists, it should be local dependency, check in node_modules
|
||||||
case false => rootProjectPath.resolve("node_modules/@fluencelabs/aqua").resolve(path)
|
case false => rootProjectPath.resolve("node_modules/@fluencelabs/aqua").resolve(path)
|
||||||
case true => filePath
|
case true => filePath
|
||||||
|
|
||||||
}
|
}
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
// we don't care about path if there is no builtins, but must write an error
|
// we don't care about path if there is no builtins, but must write an error
|
||||||
logger.error("Unexpected. Cannot find project path")
|
logger.error("Unexpected. Cannot find project path")
|
||||||
Path(path).pure[F]
|
Path(path).pure[F]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// get path to node modules if there is `aqua-lib` module with `builtin.aqua` in it
|
// get path to node modules if there is `aqua-lib` module with `builtin.aqua` in it
|
||||||
def getGlobalNodeModulePath: List[Path] = {
|
def getGlobalNodeModulePath: List[Path] = Try {
|
||||||
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
|
// hack
|
||||||
val globalAquaPath = Path(pathStr).parent.flatMap(_.parent.flatMap(_.parent))
|
val globalAquaPath = parentStrict(3)(builtinPath)
|
||||||
|
|
||||||
// Also hack. If we found installed `aqua-lib`, it should be in `node_modules` global path.
|
// 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,
|
// In global `node_modules` could be installed aqua libs and we must use them,
|
||||||
// if they were imported in aqua files
|
// if they were imported in aqua files
|
||||||
val globalNodeModulesPath =
|
val globalNodeModulesPath = globalAquaPath.flatMap(parentStrict(3))
|
||||||
globalAquaPath.flatMap(_.parent.flatMap(_.parent.flatMap(_.parent)))
|
|
||||||
|
|
||||||
globalAquaPath.toList ++ globalNodeModulesPath.toList
|
globalAquaPath.toList ++ globalNodeModulesPath.toList
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
@ -60,5 +60,4 @@ object PlatformPackagePath extends Logging {
|
|||||||
Nil
|
Nil
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,24 @@ object Meta {
|
|||||||
val metaUrl: String = js.native
|
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
|
@js.native
|
||||||
@JSImport("module", JSImport.Namespace)
|
@JSImport("module", JSImport.Namespace)
|
||||||
object Module extends js.Object {
|
object Module extends js.Object {
|
||||||
|
|
||||||
// make it possible to use `require` in ES module type
|
// 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 {
|
object Npm {
|
||||||
def resolve(str: String): Any
|
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