diff --git a/app/current/src/main/scala/io/scalajs/nodejs/Global.scala b/app/current/src/main/scala/io/scalajs/nodejs/Global.scala index 37f30530a..8df2f70a3 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/Global.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/Global.scala @@ -1,6 +1,6 @@ package io.scalajs.nodejs -import io.scalajs.nodejs.timers.{SetInterval, SetTimeout, UnRef, _} +import io.scalajs.nodejs.timers._ import scala.scalajs.js @@ -10,47 +10,10 @@ import scala.scalajs.js * var something inside an Node.js module will be local to that module. */ @js.native +@deprecated("Use io.scalajs.nodejs package object", "0.9.0") trait Global extends js.Object { - - ///////////////////////////////////////////////////////////////////////////////// - // Global Classes - ///////////////////////////////////////////////////////////////////////////////// - - def DTRACE_NET_SERVER_CONNECTION: js.Function = js.native - - def DTRACE_NET_STREAM_END: js.Function = js.native - - def DTRACE_HTTP_SERVER_REQUEST: js.Function = js.native - - def DTRACE_HTTP_SERVER_RESPONSE: js.Function = js.native - - def DTRACE_HTTP_CLIENT_REQUEST: js.Function = js.native - - def DTRACE_HTTP_CLIENT_RESPONSE: js.Function = js.native - - ///////////////////////////////////////////////////////////////////////////////// - // Global Constants - ///////////////////////////////////////////////////////////////////////////////// - - /** - * The name of the directory that the currently executing script resides in. - */ - def __dirname: String = js.native - - /** - * The filename of the code being executed. This is the resolved absolute path of this code file. For a main program - * this is not necessarily the same filename used in the command line. The value inside a module is the path to that - * module file. - */ - def __filename: String = js.native - - /** - * A reference to the module.exports that is shorter to type. See module system documentation for details on when - * to use exports and when to use module.exports. - * - * exports isn't actually a global but rather local to each module. - */ - val exports: js.Object = js.native + @deprecated("Use io.scalajs.nodejs.exports", "0.9.0") + def exports: js.UndefOr[js.Object] = js.native /** * A reference to the current module. In particular module.exports is used for defining what a module exports and @@ -58,30 +21,31 @@ trait Global extends js.Object { * * module isn't actually a global but rather local to each module. */ - val module: Module = js.native - - ///////////////////////////////////////////////////////////////////////////////// - // Global Objects - ///////////////////////////////////////////////////////////////////////////////// + @deprecated("Use io.scalajs.nodejs.module", "0.9.0") + def module: Module = js.native + @deprecated("Use io.scalajs.nodejs.clearImmediate", "0.9.0") def clearImmediate: ClearImmediate = js.native + @deprecated("Use io.scalajs.nodejs.clearInterval", "0.9.0") def clearInterval: ClearInterval = js.native + @deprecated("Use io.scalajs.nodejs.clearTimeout", "0.9.0") def clearTimeout: ClearTimeout = js.native + @deprecated("Use io.scalajs.nodejs.console", "0.9.0") def console: console_module.Console = js.native + @deprecated("Use io.scalajs.nodejs.process", "0.9.0") def process: io.scalajs.nodejs.process.Process = js.native - def ref: Ref = js.native - + @deprecated("Use io.scalajs.nodejs.setImmediate", "0.9.0") def setImmediate: SetImmediate = js.native + @deprecated("Use io.scalajs.nodejs.setInterval", "0.9.0") def setInterval: SetInterval = js.native + @deprecated("Use io.scalajs.nodejs.setTimeout", "0.9.0") def setTimeout: SetTimeout = js.native - def unref: UnRef = js.native - } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/Module.scala b/app/current/src/main/scala/io/scalajs/nodejs/Module.scala index 20c21dd41..888d70730 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/Module.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/Module.scala @@ -1,7 +1,9 @@ package io.scalajs.nodejs +import com.thoughtworks.enableIf + import scala.scalajs.js -import scala.scalajs.js.annotation.JSGlobal +import scala.scalajs.js.annotation.JSImport /** * In each module, the module free variable is a reference to the object representing the current module. @@ -51,23 +53,31 @@ trait Module extends js.Object { */ var parent: js.Any = js.native + var paths: js.Array[String] = js.native + /** * The module.require method provides a way to load a module as if require() was called from the original module. *

Note that in order to do this, you must get a reference to the module object. Since require() returns the * module.exports, and the module is typically only available within a specific module's code, it must be * explicitly exported in order to be used. */ - def require[T](id: String): T = js.native + def require[T <: js.Any](id: String): T = js.native } /** * Module Companion */ -object Module { +@js.native +@JSImport("module", JSImport.Namespace) +object Module extends Module { + + @enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs10) + var builtinModules: js.Array[String] = js.native - @js.native - @JSGlobal("module") - implicit object module extends Module + @enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12) + def createRequire(filename: String): Require = js.native + @enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12) + def createRequire(filename: io.scalajs.nodejs.url.URL): Require = js.native } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/Require.scala b/app/current/src/main/scala/io/scalajs/nodejs/Require.scala new file mode 100644 index 000000000..04fbc63e2 --- /dev/null +++ b/app/current/src/main/scala/io/scalajs/nodejs/Require.scala @@ -0,0 +1,28 @@ +package io.scalajs.nodejs + +import scala.scalajs.js +import scala.scalajs.js.annotation.JSGlobal + +@js.native +sealed trait Require extends js.Object { + def apply(id: String): js.Any = js.native + + val cache: js.Dictionary[js.Any] = js.native + val main: js.UndefOr[Module] = js.native + val resolve: RequireResolver = js.native +} + +@js.native +@JSGlobal("require") +object Require extends Require + +@js.native +trait RequireResolver extends js.Object { + def apply(request: String, options: ResolveOptions = js.native): js.Any = js.native + + def paths(requiest: String): js.Array[String] = js.native +} + +class ResolveOptions( + var paths: js.UndefOr[js.Array[String]] = js.undefined +) extends js.Object diff --git a/app/current/src/main/scala/io/scalajs/nodejs/fs/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/fs/package.scala index e17995a82..7d7a1d02f 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/fs/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/fs/package.scala @@ -21,6 +21,10 @@ package object fs { type Output = String | Buffer type FileWriteOptions = FileAppendOptions + type ReaddirArrays = js.Array[String] | js.Array[Buffer] + @enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs10) + type ReaddirArrays2 = ReaddirArrays | js.Array[fs.Dirent] + @enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs10) type Dirent = Fs.Dirent diff --git a/app/current/src/main/scala/io/scalajs/nodejs/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/package.scala index a5cc1c53e..365783f62 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/package.scala @@ -1,7 +1,6 @@ package io.scalajs import com.thoughtworks.enableIf -import io.scalajs.nodejs.buffer.Buffer import io.scalajs.nodejs.timers._ import scala.concurrent.duration.FiniteDuration @@ -54,10 +53,6 @@ package object nodejs { // The handle object can be either a server, a socket (anything with an underlying _handle member), or an object with an fd member that is a valid file descriptor. type Handle = js.Function | HasHandle | HasFileDescriptor - type ReaddirArrays = js.Array[String] | js.Array[Buffer] - @enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs10) - type ReaddirArrays2 = ReaddirArrays | js.Array[fs.Dirent] - ///////////////////////////////////////////////////////////////////////////////// // Built-in Properties ///////////////////////////////////////////////////////////////////////////////// @@ -82,15 +77,18 @@ package object nodejs { */ def __filename: String = js.Dynamic.global.__filename.asInstanceOf[String] - /** - * In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope - * var something will define a global variable. In Node.js this is different. The top-level scope is not the global - * scope; var something inside a Node.js module will be local to that module. - */ @js.native @JSGlobal("global") + @deprecated("Use objects in io.scalajs.nodejs", "0.9.0") object global extends Global + @js.native + @enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12) + @JSGlobal("queueMicrotask") + object queueMicrotask extends js.Function1[js.Function, Unit] { + override def apply(arg1: js.Function): Unit = js.native + } + ///////////////////////////////////////////////////////////////////////////////// // Timers ///////////////////////////////////////////////////////////////////////////////// @@ -107,10 +105,6 @@ package object nodejs { @JSGlobal("clearTimeout") object clearTimeout extends ClearTimeout - @js.native - @JSGlobal("ref") - object ref extends Ref - @js.native @JSGlobal("setImmediate") object setImmediate extends SetImmediate @@ -123,10 +117,6 @@ package object nodejs { @JSGlobal("setTimeout") object setTimeout extends SetTimeout - @js.native - @JSGlobal("unref") - object unref extends UnRef - ///////////////////////////////////////////////////////////////////////////////// // Implicit Conversions ///////////////////////////////////////////////////////////////////////////////// @@ -136,6 +126,7 @@ package object nodejs { * @param duration the given [[FiniteDuration duration]] * @return the time in milliseconds as an integer */ + @deprecated("Use io.scalajs.util.DurationHelper", "0.9.0") implicit def duration2Int(duration: FiniteDuration): Int = duration.toMillis.toInt /** @@ -143,6 +134,7 @@ package object nodejs { * @param duration the given [[FiniteDuration duration]] * @return the time in milliseconds as a double */ + @deprecated("Use io.scalajs.util.DurationHelper", "0.9.0") implicit def duration2Double(duration: FiniteDuration): Double = duration.toMillis.toDouble /** @@ -150,72 +142,7 @@ package object nodejs { * @param error the given [[Error]] * @return the resulting [[Exception]] */ - implicit def error2Exception(error: Error): Exception = js.JavaScriptException(error.message) - - ///////////////////////////////////////////////////////////////////////////////// - // Exit Codes - Node.js will normally exit with a 0 status code when no more - // async operations are pending. The following status codes are - // used in other cases: - ///////////////////////////////////////////////////////////////////////////////// - - type ExitCode = Int - - /** - * There was an uncaught exception, and it was not handled by a domain or an 'uncaughtException' event handler. - */ - val UncaughtFatalException: ExitCode = 1 - - /** - * The JavaScript source code internal in Node.js's bootstrapping process caused a parse error. This is extremely - * rare, and generally can only happen during development of Node.js itself. - */ - val InternalJavaScriptParseError: ExitCode = 3 - - /** - * The JavaScript source code internal in Node.js's bootstrapping process failed to return a function value when - * evaluated. This is extremely rare, and generally can only happen during development of Node.js itself. - */ - val InternalJavaScriptEvaluationFailure: ExitCode = 4 - - /** - * There was a fatal unrecoverable error in V8. Typically a message will be printed to stderr with the prefix FATAL ERROR. - */ - val FatalError: ExitCode = 5 - - /** - * There was an uncaught exception, but the internal fatal exception handler function was somehow set to a non-function, - * and could not be called. - */ - val NonFunctionInternalExceptionHandler: ExitCode = 6 - - /** - * There was an uncaught exception, and the internal fatal exception handler function itself threw an error while - * attempting to handle it. This can happen, for example, if a 'uncaughtException' or domain.on('error') handler - * throws an error. - */ - val InternalExceptionHandlerRunTimeFailure: ExitCode = 7 - - /** - * Either an unknown option was specified, or an option requiring a value was provided without a value. - */ - val InvalidArgument: ExitCode = 8 - - /** - * The JavaScript source code internal in Node.js's bootstrapping process threw an error when the bootstrapping - * function was called. This is extremely rare, and generally can only happen during development of Node.js itself. - */ - val InternalJavaScriptRunTimeFailure: ExitCode = 10 - - /** - * The --debug and/or --debug-brk options were set, but an invalid port number was chosen. - */ - val InvalidDebugArgument: ExitCode = 12 - - /** - * If Node.js receives a fatal signal such as SIGKILL or SIGHUP, then its exit code will be 128 plus the value of - * the signal code. This is a standard Unix practice, since exit codes are defined to be 7-bit integers, and signal - * exits set the high-order bit, and then contain the value of the signal code. - */ - val SignalExits: ExitCode = 128 - + @deprecated("Use toException extension method from io.scalajs.util.NodeJSConverters._", "0.9.0") + implicit def error2Exception(error: Error): Exception = + io.scalajs.util.NodeJSConverters.ErrorExtension(error).toException() } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala index cf7df6ec2..816e5434d 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala @@ -13,8 +13,8 @@ package object process { type Environment = js.Dictionary[String] // TODO: js.Set type EnvironmentFlags = js.Any - - type SendHandle = net.Socket | net.Server + type ExitCode = Int + type SendHandle = net.Socket | net.Server @deprecated("use Process object instead", "0.9.0") def allowedNodeEnvironmentFlags: EnvironmentFlags = Process.allowedNodeEnvironmentFlags diff --git a/app/current/src/main/scala/io/scalajs/util/NodeJSConverters.scala b/app/current/src/main/scala/io/scalajs/util/NodeJSConverters.scala new file mode 100644 index 000000000..51e86211f --- /dev/null +++ b/app/current/src/main/scala/io/scalajs/util/NodeJSConverters.scala @@ -0,0 +1,12 @@ +package io.scalajs.util + +import io.scalajs.nodejs.Error + +import scala.scalajs.js + +object NodeJSConverters { + implicit final class ErrorExtension(val error: Error) extends AnyVal { + @inline + def toException(): Exception = js.JavaScriptException(error.message) + } +} diff --git a/app/current/src/test/scala/io/scalajs/nodejs/TopLevelTest.scala b/app/current/src/test/scala/io/scalajs/nodejs/TopLevelTest.scala new file mode 100644 index 000000000..e6117b030 --- /dev/null +++ b/app/current/src/test/scala/io/scalajs/nodejs/TopLevelTest.scala @@ -0,0 +1,14 @@ +package io.scalajs.nodejs + +import org.scalatest.FunSuite + +import scala.scalajs.js + +class TopLevelTest extends FunSuite { + + test("queueMicrotask") { + assert(queueMicrotask.isInstanceOf[js.Function]) + queueMicrotask(() => println("printed from queueMicrotask")) + } + +} diff --git a/app/nodejs-v8/src/test/scala/io/scalajs/nodejs/child_process/ChildProcessTest.scala b/app/nodejs-v8/src/test/scala/io/scalajs/nodejs/child_process/ChildProcessTest.scala index 3008a3ddc..45fcec238 100644 --- a/app/nodejs-v8/src/test/scala/io/scalajs/nodejs/child_process/ChildProcessTest.scala +++ b/app/nodejs-v8/src/test/scala/io/scalajs/nodejs/child_process/ChildProcessTest.scala @@ -3,6 +3,7 @@ package child_process import io.scalajs.nodejs.buffer.Buffer import io.scalajs.util.ScalaJsHelper._ +import io.scalajs.util.NodeJSConverters._ import org.scalatest.AsyncFunSpec import scala.concurrent.{ExecutionContext, Promise} @@ -33,7 +34,7 @@ class ChildProcessTest extends AsyncFunSpec { "cat ./package.json | wc -l", callback = (error: Error, stdout: Output, stderr: Output) => { if (isDefined(error)) { - promise.failure(error) + promise.failure(error.toException) } else { promise.success((stdout, stderr)) } @@ -53,7 +54,7 @@ class ChildProcessTest extends AsyncFunSpec { js.Array("-l"), callback = (error: Error, stdout: Output, stderr: Output) => { if (isDefined(error)) { - promise.failure(error) + promise.failure(error.toException) } else { promise.success((stdout, stderr)) }