#370 #377 #378 Builtin as default import and minor changes (#384)

This commit is contained in:
Dima 2021-12-03 20:30:00 +03:00 committed by GitHub
parent e22867caa4
commit 3e762d6654
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 240 additions and 106 deletions

View File

@ -22,12 +22,6 @@ jobs:
### Setup ### Setup
- uses: olafurpg/setup-scala@v10 - uses: olafurpg/setup-scala@v10
### Update & build
- name: Assembly
run: sbt cli/assembly
env:
BUILD_NUMBER: ${{ github.run_number }}
- name: JS build - name: JS build
run: sbt cliJS/fullLinkJS run: sbt cliJS/fullLinkJS
env: env:
@ -55,12 +49,6 @@ jobs:
env: env:
BUILD_NUMBER: ${{ github.run_number }} BUILD_NUMBER: ${{ github.run_number }}
- name: Check .jar exists
run: |
JAR="cli/.jvm/target/scala-3.0.2/aqua-${{ env.VERSION }}.jar"
stat "$JAR"
echo "JAR=$JAR" >> $GITHUB_ENV
- name: Check .js exists - name: Check .js exists
run: | run: |
JS="cli/.js/target/scala-3.0.2/cli-opt/aqua-${{ env.VERSION }}.js" JS="cli/.js/target/scala-3.0.2/cli-opt/aqua-${{ env.VERSION }}.js"
@ -74,7 +62,6 @@ jobs:
node-version: "15" node-version: "15"
registry-url: "https://registry.npmjs.org" registry-url: "https://registry.npmjs.org"
- run: cp ${{ env.JAR }} ./npm/aqua.jar
- run: cp ${{ env.JS }} ./npm/aqua.js - run: cp ${{ env.JS }} ./npm/aqua.js
- run: npm version ${{ env.VERSION }} - run: npm version ${{ env.VERSION }}
@ -118,7 +105,6 @@ jobs:
draft: false draft: false
prerelease: false prerelease: false
files: | files: |
${{ env.JAR }}
${{ env.JS }} ${{ env.JS }}
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,8 +1,13 @@
package aqua package aqua
import aqua.js.{AvmLogLevel, FluenceJSLogLevel, Meta, Module}
import fs2.io.file.Path
import scribe.Level import scribe.Level
object Utils { import scala.util.Try
object LogLevelTransformer {
def logLevelToAvm(logLevel: Level): AvmLogLevel = { def logLevelToAvm(logLevel: Level): AvmLogLevel = {
logLevel match { logLevel match {
case Level.Trace => "trace" case Level.Trace => "trace"

View File

@ -1,18 +1,39 @@
package aqua package aqua
import aqua.js.{Meta, Module}
import cats.effect.ExitCode import cats.effect.ExitCode
import cats.effect.kernel.Async import cats.effect.kernel.Async
import com.monovore.decline.Opts import com.monovore.decline.Opts
import fs2.io.file.Files import fs2.io.file.{Files, Path}
import scala.concurrent.ExecutionContext
import scala.concurrent.ExecutionContext
import aqua.run.RunOpts import aqua.run.RunOpts
import aqua.keypair.KeyPairOpts import aqua.keypair.KeyPairOpts
import scribe.Logging
import scala.util.Try
// JS-specific options and subcommands // JS-specific options and subcommands
object PlatformOpts { object PlatformOpts extends Logging {
def opts[F[_]: Files: AquaIO: Async](implicit ec: ExecutionContext): Opts[F[ExitCode]] =
Opts.subcommand(RunOpts.runCommand[F]) orElse
Opts.subcommand(KeyPairOpts.createKeypair[F])
}
def opts[F[_]: Files: AquaIO: Async](implicit ec: ExecutionContext): Opts[F[ExitCode]] =
Opts.subcommand(RunOpts.runCommand[F]) orElse
Opts.subcommand(KeyPairOpts.createKeypair[F])
// get path to node modules if there is `aqua-lib` module with `builtin.aqua` in it
def getGlobalNodeModulePath: Option[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
Path(pathStr).parent.map(_.resolve("../.."))
}.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")
None
}
}
}

View File

@ -1,4 +1,4 @@
package aqua package aqua.js
import aqua.backend.{ArgDefinition, FunctionDef, NamesConfig, TypeDefinition} import aqua.backend.{ArgDefinition, FunctionDef, NamesConfig, TypeDefinition}
import aqua.model.transform.TransformConfig import aqua.model.transform.TransformConfig

View File

@ -1,5 +1,6 @@
package aqua package aqua.js
import aqua.*
import aqua.backend.{ArgDefinition, FunctionDef, NamesConfig, TypeDefinition} import aqua.backend.{ArgDefinition, FunctionDef, NamesConfig, TypeDefinition}
import scala.concurrent.Promise import scala.concurrent.Promise

View File

@ -0,0 +1,25 @@
package aqua.js
import scala.scalajs.js
import scala.scalajs.js.annotation.{JSExportAll, JSImport}
object Meta {
// get `import`.meta.url info from javascript
// it is needed for `createRequire` function
@js.native
@JSImport("./utils.js", "metaUrl")
val metaUrl: String = js.native
}
@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
}
trait Require extends js.Object {
def resolve(str: String): Any
}

View File

@ -1,18 +1,18 @@
package aqua.keypair package aqua.keypair
import cats.effect.ExitCode import aqua.io.OutputPrinter
import cats.effect.kernel.{Async} import aqua.js.KeyPair
import cats.Monad import aqua.keypair.KeyPairShow.show
import cats.implicits.catsSyntaxApplicativeId
import cats.Applicative
import cats.Applicative.ops.toAllApplicativeOps import cats.Applicative.ops.toAllApplicativeOps
import cats.syntax.show._ import cats.effect.ExitCode
import cats.effect.kernel.Async
import cats.implicits.catsSyntaxApplicativeId
import cats.syntax.show.*
import cats.{Applicative, Monad}
import com.monovore.decline.{Command, Opts} import com.monovore.decline.{Command, Opts}
import scribe.Logging import scribe.Logging
import scala.concurrent.{ExecutionContext, Future}
import aqua.KeyPair import scala.concurrent.{ExecutionContext, Future}
import KeyPairShow.show
// Options and commands to work with KeyPairs // Options and commands to work with KeyPairs
object KeyPairOpts extends Logging { object KeyPairOpts extends Logging {
@ -33,7 +33,7 @@ object KeyPairOpts extends Logging {
KeyPair.randomEd25519().toFuture.pure[F] KeyPair.randomEd25519().toFuture.pure[F]
) )
.map(keypair => .map(keypair =>
println(s"${keypair.show}") OutputPrinter.print(s"${keypair.show}")
ExitCode.Success ExitCode.Success
) )
) )

View File

@ -1,19 +1,19 @@
package aqua.keypair package aqua.keypair
import scala.scalajs.js.JSON import aqua.js.KeyPair
import scala.scalajs.js
import java.util.Base64
import aqua.KeyPair
import cats.Show import cats.Show
import java.util.Base64
import scala.scalajs.js
import scala.scalajs.js.JSON
object KeyPairShow { object KeyPairShow {
def stringify(keypair: KeyPair): String = { def stringify(keypair: KeyPair): String = {
val encoder = Base64.getEncoder() val encoder = Base64.getEncoder()
val kp = js.Dynamic.literal( val kp = js.Dynamic.literal(
peerId = keypair.Libp2pPeerId.toB58String(), peerId = keypair.Libp2pPeerId.toB58String(),
secretKey = encoder.encodeToString(keypair.toEd25519PrivateKey().toArray.map(s => s.toByte)), secretKey = encoder.encodeToString(keypair.toEd25519PrivateKey().toArray.map(s => s.toByte)),
publicKey = encoder.encodeToString(keypair.Libp2pPeerId.pubKey.bytes.toArray.map(s => s.toByte)), publicKey = encoder.encodeToString(keypair.Libp2pPeerId.pubKey.bytes.toArray.map(s => s.toByte)),
) )
JSON.stringify(kp, space = 4) JSON.stringify(kp, space = 4)

View File

@ -7,7 +7,8 @@ import aqua.backend.ts.TypeScriptBackend
import aqua.backend.{FunctionDef, Generated} import aqua.backend.{FunctionDef, Generated}
import aqua.compiler.{AquaCompiled, AquaCompiler} import aqua.compiler.{AquaCompiled, AquaCompiler}
import aqua.files.{AquaFileSources, AquaFilesIO, FileModuleId} import aqua.files.{AquaFileSources, AquaFilesIO, FileModuleId}
import aqua.io.AquaFileError import aqua.io.{AquaFileError, OutputPrinter}
import aqua.js.*
import aqua.model.func.raw.{CallArrowTag, CallServiceTag, FuncOp, FuncOps} import aqua.model.func.raw.{CallArrowTag, CallServiceTag, FuncOp, FuncOps}
import aqua.model.func.{Call, FuncCallable} import aqua.model.func.{Call, FuncCallable}
import aqua.model.transform.res.{AquaRes, FuncRes} import aqua.model.transform.res.{AquaRes, FuncRes}
@ -34,6 +35,7 @@ import scribe.Logging
import scala.concurrent.{ExecutionContext, Future, Promise} import scala.concurrent.{ExecutionContext, Future, Promise}
import scala.scalajs.js import scala.scalajs.js
import scala.scalajs.js.Dynamic.global as g
import scala.scalajs.js.JSConverters.* import scala.scalajs.js.JSConverters.*
import scala.scalajs.js.JSON import scala.scalajs.js.JSON
import scala.scalajs.js.annotation.* import scala.scalajs.js.annotation.*
@ -61,7 +63,7 @@ object RunCommand extends Logging {
)(implicit )(implicit
ec: ExecutionContext ec: ExecutionContext
): F[Unit] = { ): F[Unit] = {
FluenceUtils.setLogLevel(Utils.logLevelToFluenceJS(config.logLevel)) FluenceUtils.setLogLevel(LogLevelTransformer.logLevelToFluenceJS(config.logLevel))
// stops peer in any way at the end of execution // stops peer in any way at the end of execution
val resource = Resource.make(Fluence.getPeer().pure[F]) { peer => val resource = Resource.make(Fluence.getPeer().pure[F]) { peer =>
@ -74,10 +76,10 @@ object RunCommand extends Logging {
secretKey <- keyPairOrNull(config.secretKey) secretKey <- keyPairOrNull(config.secretKey)
_ <- Fluence _ <- Fluence
.start( .start(
PeerConfig(multiaddr, config.timeout, Utils.logLevelToAvm(config.logLevel), secretKey) PeerConfig(multiaddr, config.timeout, LogLevelTransformer.logLevelToAvm(config.logLevel), secretKey)
) )
.toFuture .toFuture
_ = println("Your peerId: " + peer.getStatus().peerId) _ = OutputPrinter.print("Your peerId: " + peer.getStatus().peerId)
promise = Promise.apply[Unit]() promise = Promise.apply[Unit]()
_ = CallJsFunction.registerUnitService( _ = CallJsFunction.registerUnitService(
peer, peer,
@ -88,7 +90,7 @@ object RunCommand extends Logging {
// if an input function returns a result, our success will be after it is printed // if an input function returns a result, our success will be after it is printed
// otherwise finish after JS SDK will finish sending a request // otherwise finish after JS SDK will finish sending a request
// TODO use custom function for output // TODO use custom function for output
println(str) OutputPrinter.print(str)
promise.success(()) promise.success(())
} }
) )
@ -112,7 +114,6 @@ object RunCommand extends Logging {
// func wrapFunc(): // func wrapFunc():
// res <- funcCallable(args:_*) // res <- funcCallable(args:_*)
// Console.print(res) // Console.print(res)
// TODO: now it supports only one result. If funcCallable will return multiple results, only first will be printed
private def wrapCall( private def wrapCall(
funcName: String, funcName: String,
funcCallable: FuncCallable, funcCallable: FuncCallable,
@ -157,7 +158,7 @@ object RunCommand extends Logging {
"Function execution failed by timeout. You can increase timeout with '--timeout' option in milliseconds or check if your code can hang while executing." "Function execution failed by timeout. You can increase timeout with '--timeout' option in milliseconds or check if your code can hang while executing."
} else t.getMessage } else t.getMessage
// TODO use custom function for error output // TODO use custom function for error output
println(message) OutputPrinter.error(message)
} }
/** /**
@ -178,9 +179,9 @@ object RunCommand extends Logging {
)(implicit ec: ExecutionContext): F[Unit] = { )(implicit ec: ExecutionContext): F[Unit] = {
implicit val aio: AquaIO[IO] = new AquaFilesIO[IO] implicit val aio: AquaIO[IO] = new AquaFilesIO[IO]
val sources = new AquaFileSources[F](input, imports)
for { for {
prelude <- Prelude.init()
sources = new AquaFileSources[F](input, prelude.importPaths)
// compile only context to wrap and call function later // compile only context to wrap and call function later
compileResult <- Clock[F].timed( compileResult <- Clock[F].timed(
AquaCompiler AquaCompiler
@ -204,7 +205,7 @@ object RunCommand extends Logging {
val air = FuncAirGen(funcRes).generate.show val air = FuncAirGen(funcRes).generate.show
if (runConfig.printAir) { if (runConfig.printAir) {
println(air) OutputPrinter.print(air)
} }
funcCall[F](multiaddr, air, definitions, runConfig).map { _ => funcCall[F](multiaddr, air, definitions, runConfig).map { _ =>
@ -223,7 +224,7 @@ object RunCommand extends Logging {
logger.debug(s"Call time: ${callTime.toMillis}ms") logger.debug(s"Call time: ${callTime.toMillis}ms")
result.fold( result.fold(
{ (errs: NonEmptyChain[String]) => { (errs: NonEmptyChain[String]) =>
errs.toChain.toList.foreach(err => println(err + "\n")) errs.toChain.toList.foreach(err => OutputPrinter.error(err + "\n"))
}, },
identity identity
) )

View File

@ -13,7 +13,7 @@ import cats.syntax.applicative.*
import cats.syntax.apply.* import cats.syntax.apply.*
import cats.syntax.flatMap.* import cats.syntax.flatMap.*
import cats.syntax.functor.* import cats.syntax.functor.*
import cats.{Id, Monad, ~>} import cats.{~>, Id, Monad}
import com.monovore.decline.{Command, Opts} import com.monovore.decline.{Command, Opts}
import fs2.io.file.Files import fs2.io.file.Files
import scribe.Logging import scribe.Logging
@ -24,9 +24,10 @@ import scala.concurrent.ExecutionContext
object RunOpts extends Logging { object RunOpts extends Logging {
val timeoutOpt: Opts[Int] = val timeoutOpt: Opts[Int] =
Opts.option[Int]("timeout", "Request timeout in milliseconds", "t") Opts
.option[Int]("timeout", "Request timeout in milliseconds", "t")
.withDefault(7000) .withDefault(7000)
val multiaddrOpt: Opts[String] = val multiaddrOpt: Opts[String] =
Opts Opts
.option[String]("addr", "Relay multiaddress", "a") .option[String]("addr", "Relay multiaddress", "a")
@ -57,7 +58,6 @@ object RunOpts extends Logging {
.map(_ => true) .map(_ => true)
.withDefault(false) .withDefault(false)
val funcOpt: Opts[(String, List[LiteralModel])] = val funcOpt: Opts[(String, List[LiteralModel])] =
Opts Opts
.option[String]("func", "Function to call with args", "f") .option[String]("func", "Function to call with args", "f")
@ -70,7 +70,9 @@ object RunOpts extends Logging {
case _ => false case _ => false
} }
if (hasVars) { if (hasVars) {
Validated.invalidNel("Function can have only literal arguments, no variables or constants allowed at the moment") Validated.invalidNel(
"Function can have only literal arguments, no variables or constants allowed at the moment"
)
} else { } else {
val args = expr.args.collect { case l @ Literal(_, _) => val args = expr.args.collect { case l @ Literal(_, _) =>
LiteralModel(l.value, l.ts) LiteralModel(l.value, l.ts)
@ -85,9 +87,26 @@ object RunOpts extends Logging {
def runOptions[F[_]: Files: AquaIO: Async](implicit def runOptions[F[_]: Files: AquaIO: Async](implicit
ec: ExecutionContext ec: ExecutionContext
): Opts[F[cats.effect.ExitCode]] = ): Opts[F[cats.effect.ExitCode]] =
(AppOpts.inputOpts[F], AppOpts.importOpts[F], multiaddrOpt, funcOpt, timeoutOpt, AppOpts.logLevelOpt, printAir, AppOpts.wrapWithOption(secretKeyOpt)).mapN { (
case (inputF, importF, multiaddr, (func, args), timeout, logLevel, printAir, secretKey) => AppOpts.inputOpts[F],
AppOpts.importOpts[F],
multiaddrOpt,
funcOpt,
timeoutOpt,
AppOpts.logLevelOpt,
printAir,
AppOpts.wrapWithOption(secretKeyOpt)
).mapN {
case (
inputF,
importF,
multiaddr,
(func, args),
timeout,
logLevel,
printAir,
secretKey
) =>
scribe.Logger.root scribe.Logger.root
.clearHandlers() .clearHandlers()
.clearModifiers() .clearModifiers()
@ -114,7 +133,14 @@ object RunOpts extends Logging {
}, },
{ imps => { imps =>
RunCommand RunCommand
.run(multiaddr, func, args, input, imps, RunConfig(timeout, logLevel, printAir, secretKey)) .run(
multiaddr,
func,
args,
input,
imps,
RunConfig(timeout, logLevel, printAir, secretKey)
)
.map(_ => cats.effect.ExitCode.Success) .map(_ => cats.effect.ExitCode.Success)
} }
) )

View File

@ -2,8 +2,10 @@ package aqua
import cats.effect.ExitCode import cats.effect.ExitCode
import com.monovore.decline.Opts import com.monovore.decline.Opts
import fs2.io.file.Path
// Scala-specific options and subcommands // Scala-specific options and subcommands
object PlatformOpts { object PlatformOpts {
def opts[F[_]]: Opts[F[ExitCode]] = Opts.never def opts[F[_]]: Opts[F[ExitCode]] = Opts.never
def getGlobalNodeModulePath: Option[Path] = None
} }

View File

@ -14,7 +14,7 @@ import cats.syntax.applicative.*
import cats.syntax.flatMap.* import cats.syntax.flatMap.*
import cats.syntax.functor.* import cats.syntax.functor.*
import cats.syntax.traverse.* import cats.syntax.traverse.*
import cats.{Comonad, Functor, Monad, ~>} import cats.{~>, Comonad, Functor, Monad}
import com.monovore.decline.Opts.help import com.monovore.decline.Opts.help
import com.monovore.decline.{Opts, Visibility} import com.monovore.decline.{Opts, Visibility}
import fs2.io.file.{Files, Path} import fs2.io.file.{Files, Path}
@ -92,14 +92,19 @@ object AppOpts {
.map(s => checkPath[F](s)) .map(s => checkPath[F](s))
def outputOpts[F[_]: Monad: Files]: Opts[F[ValidatedNec[String, Option[Path]]]] = def outputOpts[F[_]: Monad: Files]: Opts[F[ValidatedNec[String, Option[Path]]]] =
Opts.option[String]("output", "Path to the output directory. Will be created if not exists", "o") Opts
.option[String]("output", "Path to the output directory. Will be created if not exists", "o")
.map(s => Option(s)) .map(s => Option(s))
.withDefault(None) .withDefault(None)
.map(_.map(checkOutput[F]).getOrElse(Validated.validNec[String, Option[Path]](None).pure[F])) .map(_.map(checkOutput[F]).getOrElse(Validated.validNec[String, Option[Path]](None).pure[F]))
def importOpts[F[_]: Monad: Files]: Opts[F[ValidatedNec[String, List[Path]]]] = def importOpts[F[_]: Monad: Files]: Opts[F[ValidatedNec[String, List[Path]]]] =
Opts Opts
.options[String]("import", "Path to the directory to import from. May be used several times", "m") .options[String](
"import",
"Path to the directory to import from. May be used several times",
"m"
)
.orEmpty .orEmpty
.map { ps => .map { ps =>
val checked: List[F[ValidatedNec[String, Path]]] = ps.map { pStr => val checked: List[F[ValidatedNec[String, Path]]] = ps.map { pStr =>
@ -116,21 +121,7 @@ object AppOpts {
} }
} }
// check if node_modules directory exists and add it in imports list checked.sequence.map(_.sequence)
val nodeModules = Path("node_modules")
val nodeImportF: F[Option[Path]] = Files[F].exists(nodeModules).flatMap {
case true =>
Files[F].isDirectory(nodeModules).map(isDir => if (isDir) Some(nodeModules) else None )
case false => None.pure[F]
}
for {
result <- checked.sequence.map(_.sequence)
nodeImport <- nodeImportF
} yield {
result.map(_ ++ nodeImport)
}
} }
def constantOpts[F[_]: LiftParser: Comonad]: Opts[List[TransformConfig.Const]] = def constantOpts[F[_]: LiftParser: Comonad]: Opts[List[TransformConfig.Const]] =
@ -193,7 +184,10 @@ object AppOpts {
val scriptOpt: Opts[Boolean] = val scriptOpt: Opts[Boolean] =
Opts Opts
.flag("scheduled", "Generate air code for script storage. Without error handling wrappers and hops on relay. Will ignore other options") .flag(
"scheduled",
"Generate air code for script storage. Without error handling wrappers and hops on relay. Will ignore other options"
)
.map(_ => true) .map(_ => true)
.withDefault(false) .withDefault(false)

View File

@ -66,7 +66,7 @@ object AquaCli extends IOApp with Logging {
constantOpts[Id], constantOpts[Id],
dryOpt, dryOpt,
scriptOpt scriptOpt
).mapN { ).mapN {
case (inputF, importsF, outputF, toAirOp, toJs, noRelayOp, noXorOp, h, v, logLevel, constants, isDryRun, isScheduled) => case (inputF, importsF, outputF, toAirOp, toJs, noRelayOp, noXorOp, h, v, logLevel, constants, isDryRun, isScheduled) =>
scribe.Logger.root scribe.Logger.root
.clearHandlers() .clearHandlers()

View File

@ -13,8 +13,9 @@ import cats.data.*
import cats.parse.LocationMap import cats.parse.LocationMap
import cats.syntax.applicative.* import cats.syntax.applicative.*
import cats.syntax.functor.* import cats.syntax.functor.*
import cats.syntax.flatMap.*
import cats.syntax.show.* import cats.syntax.show.*
import cats.{Applicative, Eval, Monad, Show, ~>} import cats.{~>, Applicative, Eval, Monad, Show}
import fs2.io.file.{Files, Path} import fs2.io.file.{Files, Path}
import scribe.Logging import scribe.Logging
@ -36,17 +37,22 @@ object AquaPathCompiler extends Logging {
transformConfig: TransformConfig transformConfig: TransformConfig
): F[ValidatedNec[String, Chain[String]]] = { ): F[ValidatedNec[String, Chain[String]]] = {
import ErrorRendering.showError import ErrorRendering.showError
val sources = new AquaFileSources[F](srcPath, imports) (for {
AquaCompiler prelude <- Prelude.init(withPrelude = false)
.compileTo[F, AquaFileError, FileModuleId, FileSpan.F, String]( sources = new AquaFileSources[F](srcPath, imports ++ prelude.importPaths)
sources, compiler <- AquaCompiler
SpanParser.parser, .compileTo[F, AquaFileError, FileModuleId, FileSpan.F, String](
backend, sources,
transformConfig, SpanParser.parser,
targetPath.map(sources.write).getOrElse(dry[F]) backend,
) transformConfig,
targetPath.map(sources.write).getOrElse(dry[F])
)
} yield {
compiler
// 'distinct' to delete all duplicated errors // 'distinct' to delete all duplicated errors
.map(_.leftMap(_.map(_.show).distinct)) }).map(_.leftMap(_.map(_.show).distinct))
} }
def dry[F[_]: Applicative]( def dry[F[_]: Applicative](

View File

@ -0,0 +1,39 @@
package aqua
import cats.Monad
import cats.syntax.applicative.*
import cats.syntax.flatMap.*
import cats.syntax.functor.*
import fs2.io.file.{Files, Path}
import scribe.Logging
import scala.util.Try
/**
* @param importPaths list of paths where imports will be searched
*/
case class Prelude(importPaths: List[Path])
// JS-specific functions
object Prelude extends Logging {
def init[F[_]: Files: Monad](withPrelude: Boolean = true): F[Prelude] = {
// check if node_modules directory exists and add it in imports list
val nodeModules = Path("node_modules")
val nodeImportF: F[Option[Path]] = Files[F].exists(nodeModules).flatMap {
case true =>
Files[F].isDirectory(nodeModules).map(isDir => if (isDir) Some(nodeModules) else None)
case false => None.pure[F]
}
nodeImportF.map { nodeImport =>
val imports =
if (withPrelude)
nodeImport.toList ++ PlatformOpts.getGlobalNodeModulePath.toList
else nodeImport.toList
new Prelude(imports)
}
}
}

View File

@ -0,0 +1,14 @@
package aqua.io
// Uses to print outputs in CLI
// TODO: add F[_], cause it is effect
object OutputPrinter {
def print(str: String): Unit = {
println(str)
}
def error(str: String): Unit = {
println(str)
}
}

25
npm/package-lock.json generated
View File

@ -9,7 +9,8 @@
"version": "0.0.0", "version": "0.0.0",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@fluencelabs/fluence": "0.15.1" "@fluencelabs/aqua-lib": "0.2.1",
"@fluencelabs/fluence": "0.15.2"
}, },
"bin": { "bin": {
"aqua": "index.js", "aqua": "index.js",
@ -75,6 +76,11 @@
"resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz",
"integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="
}, },
"node_modules/@fluencelabs/aqua-lib": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua-lib/-/aqua-lib-0.2.1.tgz",
"integrity": "sha512-uLP9mbgFHR1Q1FYhehasNxNBlTclBsjNI9MvIPF8oXtVJtnvPi+R4rGGTOHtRJukunxhpAV/svWQU9a2BRyDmQ=="
},
"node_modules/@fluencelabs/avm": { "node_modules/@fluencelabs/avm": {
"version": "0.16.0-restriction-operator.9", "version": "0.16.0-restriction-operator.9",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.16.0-restriction-operator.9.tgz", "resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.16.0-restriction-operator.9.tgz",
@ -84,9 +90,9 @@
} }
}, },
"node_modules/@fluencelabs/fluence": { "node_modules/@fluencelabs/fluence": {
"version": "0.15.1", "version": "0.15.2",
"resolved": "https://registry.npmjs.org/@fluencelabs/fluence/-/fluence-0.15.1.tgz", "resolved": "https://registry.npmjs.org/@fluencelabs/fluence/-/fluence-0.15.2.tgz",
"integrity": "sha512-ZHLw85XgVMglCVJjGkdGRFzL7kO2x31BCYDt4BVlMCE/S2nFSsVHU8DO35Jlh40QZhQdN3F5dbJpkgdcwdC8bw==", "integrity": "sha512-RWGh70XkqcJusaqB4TR0tVBSVkzlMU9krwALQmgilLTxaSBMPtB6xMt13ceEJ/G6BwsLZWdgY2Wy6GvdSheKaw==",
"dependencies": { "dependencies": {
"@chainsafe/libp2p-noise": "4.0.0", "@chainsafe/libp2p-noise": "4.0.0",
"@fluencelabs/avm": "0.16.0-restriction-operator.9", "@fluencelabs/avm": "0.16.0-restriction-operator.9",
@ -2818,6 +2824,11 @@
} }
} }
}, },
"@fluencelabs/aqua-lib": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua-lib/-/aqua-lib-0.2.1.tgz",
"integrity": "sha512-uLP9mbgFHR1Q1FYhehasNxNBlTclBsjNI9MvIPF8oXtVJtnvPi+R4rGGTOHtRJukunxhpAV/svWQU9a2BRyDmQ=="
},
"@fluencelabs/avm": { "@fluencelabs/avm": {
"version": "0.16.0-restriction-operator.9", "version": "0.16.0-restriction-operator.9",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.16.0-restriction-operator.9.tgz", "resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.16.0-restriction-operator.9.tgz",
@ -2827,9 +2838,9 @@
} }
}, },
"@fluencelabs/fluence": { "@fluencelabs/fluence": {
"version": "0.15.1", "version": "0.15.2",
"resolved": "https://registry.npmjs.org/@fluencelabs/fluence/-/fluence-0.15.1.tgz", "resolved": "https://registry.npmjs.org/@fluencelabs/fluence/-/fluence-0.15.2.tgz",
"integrity": "sha512-ZHLw85XgVMglCVJjGkdGRFzL7kO2x31BCYDt4BVlMCE/S2nFSsVHU8DO35Jlh40QZhQdN3F5dbJpkgdcwdC8bw==", "integrity": "sha512-RWGh70XkqcJusaqB4TR0tVBSVkzlMU9krwALQmgilLTxaSBMPtB6xMt13ceEJ/G6BwsLZWdgY2Wy6GvdSheKaw==",
"requires": { "requires": {
"@chainsafe/libp2p-noise": "4.0.0", "@chainsafe/libp2p-noise": "4.0.0",
"@fluencelabs/avm": "0.16.0-restriction-operator.9", "@fluencelabs/avm": "0.16.0-restriction-operator.9",

View File

@ -6,8 +6,8 @@
"files": [ "files": [
"aqua.js", "aqua.js",
"index.js", "index.js",
"index-java.js", "error.js",
"error.js" "utils.js"
], ],
"bin": { "bin": {
"aqua": "index.js", "aqua": "index.js",
@ -18,7 +18,8 @@
"from:scalajs": "cp ../cli/.js/target/scala-3.0.2/cli-opt/main.js ./aqua.js && npm run run -- $@" "from:scalajs": "cp ../cli/.js/target/scala-3.0.2/cli-opt/main.js ./aqua.js && npm run run -- $@"
}, },
"dependencies": { "dependencies": {
"@fluencelabs/fluence": "0.15.1" "@fluencelabs/fluence": "0.15.2",
"@fluencelabs/aqua-lib": "0.2.1"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

2
npm/utils.js Normal file
View File

@ -0,0 +1,2 @@
// It should work in scala as js.`import`.meta.url, but it doesn't compile for some reasons
export const metaUrl = import.meta.url

View File

@ -1,4 +1,4 @@
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.7.0") addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.7.1")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0") addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0")