Skip to content
This repository was archived by the owner on Jul 30, 2024. It is now read-only.

Overhaul fs module #58

Merged
merged 1 commit into from
Sep 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
551 changes: 341 additions & 210 deletions app/current/src/main/scala/io/scalajs/nodejs/fs/Fs.scala

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
package io.scalajs.nodejs
package fs

import com.thoughtworks.enableIf
import io.scalajs.nodejs.buffer.Buffer
import io.scalajs.nodejs.stream.Readable
import io.scalajs.util.PromiseHelper.promiseCallback1

import scala.concurrent.Future
import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport
import scala.scalajs.js.|

/**
* fs.ReadStream - ReadStream is a Readable Stream.
* @see https://nodejs.org/api/stream.html#stream_class_stream_readable
*/
@js.native
trait ReadStream extends Readable {
@JSImport("fs", "ReadStream")
class ReadStream(path: Path) extends Readable {

/////////////////////////////////////////////////////////////////////////////////
// Properties
Expand Down Expand Up @@ -42,6 +45,8 @@ trait ReadStream extends Readable {
*/
def close(callback: js.Function1[Unit, Any]): Unit = js.native

@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12)
val pending: Boolean = js.native
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import scala.scalajs.js
* }}}
* @since 0.1.21
*/
// TODO: BigIntStats if Scala.js added BigInt support
@js.native
trait Stats extends js.Object {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import io.scalajs.util.PromiseHelper._

import scala.concurrent.Future
import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport
import scala.scalajs.js.|

/**
* fs.WriteStream - WriteStream is a Writable Stream.
* @see https://nodejs.org/api/fs.html#fs_class_fs_writestream
*/
@js.native
trait WriteStream extends Writable {
@JSImport("fs", "ReadStream")
class WriteStream(path: Path) extends Writable {

/////////////////////////////////////////////////////////////////////////////////
// Properties
Expand Down
97 changes: 78 additions & 19 deletions app/current/src/main/scala/io/scalajs/nodejs/fs/package.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
package io.scalajs.nodejs

import io.scalajs.RawOptions
import com.thoughtworks.enableIf
import io.scalajs.nodejs.buffer.Buffer
import io.scalajs.nodejs.url.URL
import io.scalajs.util.PromiseHelper._

import scala.concurrent.Future
import scala.scalajs.js
import scala.scalajs.js.typedarray.Uint8Array
import scala.scalajs.js.typedarray.{DataView, TypedArray, Uint8Array}
import scala.scalajs.js.|

/**
* fs package object
*/
package object fs {

type Path = Uint8Array | String | URL
type Time = Int | String | js.Date
type BufferLike = TypedArray[_, _] | DataView
type Output = String | Buffer

@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs10)
type Dirent = Fs.Dirent

/////////////////////////////////////////////////////////////////////////////////
// Implicit conversions and classes
/////////////////////////////////////////////////////////////////////////////////
Expand All @@ -22,10 +31,14 @@ package object fs {
* File System Extensions
* @param fs the given [[Fs file system]] instance
*/
final implicit class FsExtensions(val fs: Fs) extends AnyVal {
final implicit class FsExtensions(private val fs: Fs) extends AnyVal {
@inline
def accessFuture(path: Buffer | String): Future[Unit] = {
promiseWithError0[FileIOError](fs.access(path, _))
}

@inline
def accessFuture(path: Buffer | String, mode: FileMode = null): Future[Unit] = {
def accessFuture(path: Buffer | String, mode: FileMode): Future[Unit] = {
promiseWithError0[FileIOError](fs.access(path, mode, _))
}

Expand All @@ -51,7 +64,7 @@ package object fs {
def fdatasyncFuture(fd: FileDescriptor): Future[Unit] = promiseWithError0[FileIOError](fs.fdatasync(fd, _))

@inline
def futimesFuture(fd: FileDescriptor, atime: Integer, mtime: Integer): Future[Unit] = {
def futimesFuture(fd: FileDescriptor, atime: Time, mtime: Time): Future[Unit] = {
promiseWithError0[FileIOError](fs.futimes(fd, atime, mtime, _))
}

Expand All @@ -71,14 +84,23 @@ package object fs {
}

@inline
def mkdirFuture(path: Buffer | String, mode: FileMode = null): Future[Unit] = {
def mkdirFuture(path: Buffer | String, mode: FileMode): Future[Unit] = {
promiseWithError0[FileIOError](fs.mkdir(path, mode, _))
}

@inline
def openFuture(path: Buffer | String, flags: Flags, mode: FileMode = null): Future[FileDescriptor] = {
def mkdirFuture(path: Buffer | String): Future[Unit] = {
promiseWithError0[FileIOError](fs.mkdir(path, _))
}

@inline
def openFuture(path: Buffer | String, flags: Flags, mode: FileMode): Future[FileDescriptor] = {
promiseWithError1[FileIOError, FileDescriptor](fs.open(path, flags, mode, _))
}
@inline
def openFuture(path: Buffer | String, flags: Flags): Future[FileDescriptor] = {
promiseWithError1[FileIOError, FileDescriptor](fs.open(path, flags, _))
}

@inline
def readFuture(fd: FileDescriptor,
Expand All @@ -90,14 +112,37 @@ package object fs {
}

@inline
def readdirFuture(path: Buffer | String,
options: String | FileEncodingOptions | RawOptions = null): Future[js.Array[String]] = {
promiseWithError1[FileIOError, js.Array[String]](fs.readdir(path, options, _))
def readdirFuture(path: Buffer | String, options: String = "utf8"): Future[js.Array[String]] = {
val callback: FsCallback1[js.Array[String]] => Unit = { callback =>
fs.readdir(path, options, callback.asInstanceOf[FsCallback1[ReaddirArrays]])
}
promiseWithError1[FileIOError, js.Array[String]](callback)
}

@inline
def readdirBufferFuture(path: Buffer | String): Future[js.Array[Buffer]] = {
val callback: FsCallback1[js.Array[Buffer]] => Unit = { callback =>
fs.readdir(
path,
new FileEncodingOptions(encoding = "buffer"),
callback.asInstanceOf[FsCallback1[ReaddirArrays]]
)
}
promiseWithError1[FileIOError, js.Array[Buffer]](callback)
}

@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs10)
@inline
def readFileFuture(file: String, options: FileInputOptions = null): Future[js.Any] = {
promiseWithError1[FileIOError, js.Any](fs.readFile(file, options, _))
def readdirDirentFuture(path: Buffer | String): Future[js.Array[Dirent]] = {
val callback: FsCallback1[js.Array[Dirent]] => Unit = { callback =>
fs.readdir(path, new ReaddirOptions(withFileTypes = true), callback.asInstanceOf[FsCallback1[ReaddirArrays]])
}
promiseWithError1[FileIOError, js.Array[Dirent]](callback)
}

@inline
def readFileFuture(file: String, options: ReadFileOptions = null): Future[Output] = {
promiseWithError1[FileIOError, Output](fs.readFile(file, options, _))
}

@inline
Expand All @@ -106,8 +151,13 @@ package object fs {
}

@inline
def realpathFuture(path: String, options: FileEncodingOptions = null): Future[String] = {
promiseWithError1[FileIOError, String](fs.realpath(path, options, _))
def realpathFuture(path: String): Future[String] = {
promiseWithError1[FileIOError, String](fs.realpath(path, _))
}

@inline
def realpathFuture(path: String, options: FileEncodingOptions): Future[Output] = {
promiseWithError1[FileIOError, Output](fs.realpath(path, options, _))
}

@inline
Expand Down Expand Up @@ -139,10 +189,10 @@ package object fs {

@inline
def writeFuture(fd: FileDescriptor,
buffer: Buffer | Uint8Array,
offset: Integer = null,
length: Integer = null,
position: Integer = null): Future[(FileType, Buffer)] = {
buffer: Uint8Array,
offset: Int | Null = null,
length: Int | Null = null,
position: Int | Null = null): Future[(FileType, Buffer)] = {
promiseWithError2[FileIOError, Int, Buffer](fs.write(fd, buffer, offset, length, position, _))
}

Expand All @@ -162,10 +212,19 @@ package object fs {
}

@inline
def writeFileFuture(file: String, data: Buffer | String, options: FileOutputOptions = null): Future[Unit] = {
def writeFileFuture(file: String, data: Buffer, options: FileOutputOptions = null): Future[Unit] = {
promiseWithError0[FileIOError](fs.writeFile(file, data, options, _))
}

@inline
def writeFileFuture(file: String, data: String, options: FileOutputOptions): Future[Unit] = {
promiseWithError0[FileIOError](fs.writeFile(file, data, options, _))
}

@inline
def writeFileFuture(file: String, data: String): Future[Unit] = {
promiseWithError0[FileIOError](fs.writeFile(file, data, _))
}
}

}
8 changes: 7 additions & 1 deletion app/current/src/main/scala/io/scalajs/nodejs/package.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.scalajs

import com.thoughtworks.enableIf
import io.scalajs.nodejs.buffer.Buffer
import io.scalajs.nodejs.timers._

import scala.concurrent.duration.FiniteDuration
Expand Down Expand Up @@ -27,7 +29,7 @@ package object nodejs {

type FileIOError = SystemError

type FileMode = Integer
type FileMode = Int

type FileType = Int

Expand All @@ -48,6 +50,10 @@ 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
/////////////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.scalajs.nodejs.fs

import org.scalatest.FunSpec

import scala.scalajs.js
import scala.scalajs.js.typedarray.Uint8Array

/**
* File System (Fs) Tests
*
*/
class FsClassesTest extends FunSpec {
describe("ReadStream") {
it("supports pending added in v11.2.0") {
assert(new ReadStream("package.json").pending)
}
}

}
6 changes: 6 additions & 0 deletions app/nodejs-v8/src/test/scala/nodejs/fs/FsTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ class FsTest extends FunSpec {
}
}

it("support access") {
Fs.access("./package.json", err => {
assert(err == null)
})
}

}

}
29 changes: 29 additions & 0 deletions app/nodejs-v8/src/test/scala/nodejs/fs/ReadStreamTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.scalajs.nodejs
package fs

import io.scalajs.nodejs.buffer.Buffer
import io.scalajs.nodejs.url.URL
import org.scalatest.FunSpec

import scala.scalajs.js

class FsClassesTest extends FunSpec {
val dirname = process.cwd()

describe("ReadStream") {
it("supports constructor(") {
assert(new ReadStream("package.json") != null)
assert(new ReadStream(Buffer.from("package.json")) != null)
assert(new ReadStream(new URL(s"file:///${dirname}/package.json")) != null)
}
}

describe("WriteStream") {
it("supports constructor") {
assert(new WriteStream("package.json") != null)
assert(new WriteStream(Buffer.from("package.json")) != null)
assert(new WriteStream(new URL(s"file:///${dirname}/package.json")) != null)
}
}

}