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

Commit 5a54e80

Browse files
author
exoego
committed
Overhaul fs module
1 parent 5c7bf7e commit 5a54e80

File tree

9 files changed

+490
-232
lines changed

9 files changed

+490
-232
lines changed

app/current/src/main/scala/io/scalajs/nodejs/fs/Fs.scala

Lines changed: 341 additions & 210 deletions
Large diffs are not rendered by default.

app/current/src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
package io.scalajs.nodejs
22
package fs
33

4+
import com.thoughtworks.enableIf
45
import io.scalajs.nodejs.buffer.Buffer
56
import io.scalajs.nodejs.stream.Readable
67
import io.scalajs.util.PromiseHelper.promiseCallback1
78

89
import scala.concurrent.Future
910
import scala.scalajs.js
11+
import scala.scalajs.js.annotation.JSImport
1012
import scala.scalajs.js.|
1113

1214
/**
1315
* fs.ReadStream - ReadStream is a Readable Stream.
1416
* @see https://nodejs.org/api/stream.html#stream_class_stream_readable
1517
*/
1618
@js.native
17-
trait ReadStream extends Readable {
19+
@JSImport("fs", "ReadStream")
20+
class ReadStream(path: Path) extends Readable {
1821

1922
/////////////////////////////////////////////////////////////////////////////////
2023
// Properties
@@ -42,6 +45,8 @@ trait ReadStream extends Readable {
4245
*/
4346
def close(callback: js.Function1[Unit, Any]): Unit = js.native
4447

48+
@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12)
49+
val pending: Boolean = js.native
4550
}
4651

4752
/**

app/current/src/main/scala/io/scalajs/nodejs/fs/Stats.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import scala.scalajs.js
3131
* }}}
3232
* @since 0.1.21
3333
*/
34+
// TODO: BigIntStats if Scala.js added BigInt support
3435
@js.native
3536
trait Stats extends js.Object {
3637

app/current/src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@ import io.scalajs.util.PromiseHelper._
77

88
import scala.concurrent.Future
99
import scala.scalajs.js
10+
import scala.scalajs.js.annotation.JSImport
1011
import scala.scalajs.js.|
1112

1213
/**
1314
* fs.WriteStream - WriteStream is a Writable Stream.
1415
* @see https://nodejs.org/api/fs.html#fs_class_fs_writestream
1516
*/
1617
@js.native
17-
trait WriteStream extends Writable {
18+
@JSImport("fs", "ReadStream")
19+
class WriteStream(path: Path) extends Writable {
1820

1921
/////////////////////////////////////////////////////////////////////////////////
2022
// Properties

app/current/src/main/scala/io/scalajs/nodejs/fs/package.scala

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
package io.scalajs.nodejs
22

3-
import io.scalajs.RawOptions
3+
import com.thoughtworks.enableIf
44
import io.scalajs.nodejs.buffer.Buffer
5+
import io.scalajs.nodejs.url.URL
56
import io.scalajs.util.PromiseHelper._
67

78
import scala.concurrent.Future
89
import scala.scalajs.js
9-
import scala.scalajs.js.typedarray.Uint8Array
10+
import scala.scalajs.js.typedarray.{DataView, TypedArray, Uint8Array}
1011
import scala.scalajs.js.|
1112

1213
/**
1314
* fs package object
1415
*/
1516
package object fs {
1617

18+
type Path = Uint8Array | String | URL
19+
type Time = Int | String | js.Date
20+
type BufferLike = TypedArray[_, _] | DataView
21+
type Output = String | Buffer
22+
23+
@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs10)
24+
type Dirent = Fs.Dirent
25+
1726
/////////////////////////////////////////////////////////////////////////////////
1827
// Implicit conversions and classes
1928
/////////////////////////////////////////////////////////////////////////////////
@@ -22,10 +31,14 @@ package object fs {
2231
* File System Extensions
2332
* @param fs the given [[Fs file system]] instance
2433
*/
25-
final implicit class FsExtensions(val fs: Fs) extends AnyVal {
34+
final implicit class FsExtensions(private val fs: Fs) extends AnyVal {
35+
@inline
36+
def accessFuture(path: Buffer | String): Future[Unit] = {
37+
promiseWithError0[FileIOError](fs.access(path, _))
38+
}
2639

2740
@inline
28-
def accessFuture(path: Buffer | String, mode: FileMode = null): Future[Unit] = {
41+
def accessFuture(path: Buffer | String, mode: FileMode): Future[Unit] = {
2942
promiseWithError0[FileIOError](fs.access(path, mode, _))
3043
}
3144

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

5366
@inline
54-
def futimesFuture(fd: FileDescriptor, atime: Integer, mtime: Integer): Future[Unit] = {
67+
def futimesFuture(fd: FileDescriptor, atime: Time, mtime: Time): Future[Unit] = {
5568
promiseWithError0[FileIOError](fs.futimes(fd, atime, mtime, _))
5669
}
5770

@@ -71,14 +84,23 @@ package object fs {
7184
}
7285

7386
@inline
74-
def mkdirFuture(path: Buffer | String, mode: FileMode = null): Future[Unit] = {
87+
def mkdirFuture(path: Buffer | String, mode: FileMode): Future[Unit] = {
7588
promiseWithError0[FileIOError](fs.mkdir(path, mode, _))
7689
}
7790

7891
@inline
79-
def openFuture(path: Buffer | String, flags: Flags, mode: FileMode = null): Future[FileDescriptor] = {
92+
def mkdirFuture(path: Buffer | String): Future[Unit] = {
93+
promiseWithError0[FileIOError](fs.mkdir(path, _))
94+
}
95+
96+
@inline
97+
def openFuture(path: Buffer | String, flags: Flags, mode: FileMode): Future[FileDescriptor] = {
8098
promiseWithError1[FileIOError, FileDescriptor](fs.open(path, flags, mode, _))
8199
}
100+
@inline
101+
def openFuture(path: Buffer | String, flags: Flags): Future[FileDescriptor] = {
102+
promiseWithError1[FileIOError, FileDescriptor](fs.open(path, flags, _))
103+
}
82104

83105
@inline
84106
def readFuture(fd: FileDescriptor,
@@ -90,14 +112,37 @@ package object fs {
90112
}
91113

92114
@inline
93-
def readdirFuture(path: Buffer | String,
94-
options: String | FileEncodingOptions | RawOptions = null): Future[js.Array[String]] = {
95-
promiseWithError1[FileIOError, js.Array[String]](fs.readdir(path, options, _))
115+
def readdirFuture(path: Buffer | String, options: String = "utf8"): Future[js.Array[String]] = {
116+
val callback: FsCallback1[js.Array[String]] => Unit = { callback =>
117+
fs.readdir(path, options, callback.asInstanceOf[FsCallback1[ReaddirArrays]])
118+
}
119+
promiseWithError1[FileIOError, js.Array[String]](callback)
120+
}
121+
122+
@inline
123+
def readdirBufferFuture(path: Buffer | String): Future[js.Array[Buffer]] = {
124+
val callback: FsCallback1[js.Array[Buffer]] => Unit = { callback =>
125+
fs.readdir(
126+
path,
127+
new FileEncodingOptions(encoding = "buffer"),
128+
callback.asInstanceOf[FsCallback1[ReaddirArrays]]
129+
)
130+
}
131+
promiseWithError1[FileIOError, js.Array[Buffer]](callback)
96132
}
97133

134+
@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs10)
98135
@inline
99-
def readFileFuture(file: String, options: FileInputOptions = null): Future[js.Any] = {
100-
promiseWithError1[FileIOError, js.Any](fs.readFile(file, options, _))
136+
def readdirDirentFuture(path: Buffer | String): Future[js.Array[Dirent]] = {
137+
val callback: FsCallback1[js.Array[Dirent]] => Unit = { callback =>
138+
fs.readdir(path, new ReaddirOptions(withFileTypes = true), callback.asInstanceOf[FsCallback1[ReaddirArrays]])
139+
}
140+
promiseWithError1[FileIOError, js.Array[Dirent]](callback)
141+
}
142+
143+
@inline
144+
def readFileFuture(file: String, options: ReadFileOptions = null): Future[Output] = {
145+
promiseWithError1[FileIOError, Output](fs.readFile(file, options, _))
101146
}
102147

103148
@inline
@@ -106,8 +151,13 @@ package object fs {
106151
}
107152

108153
@inline
109-
def realpathFuture(path: String, options: FileEncodingOptions = null): Future[String] = {
110-
promiseWithError1[FileIOError, String](fs.realpath(path, options, _))
154+
def realpathFuture(path: String): Future[String] = {
155+
promiseWithError1[FileIOError, String](fs.realpath(path, _))
156+
}
157+
158+
@inline
159+
def realpathFuture(path: String, options: FileEncodingOptions): Future[Output] = {
160+
promiseWithError1[FileIOError, Output](fs.realpath(path, options, _))
111161
}
112162

113163
@inline
@@ -139,10 +189,10 @@ package object fs {
139189

140190
@inline
141191
def writeFuture(fd: FileDescriptor,
142-
buffer: Buffer | Uint8Array,
143-
offset: Integer = null,
144-
length: Integer = null,
145-
position: Integer = null): Future[(FileType, Buffer)] = {
192+
buffer: Uint8Array,
193+
offset: Int | Null = null,
194+
length: Int | Null = null,
195+
position: Int | Null = null): Future[(FileType, Buffer)] = {
146196
promiseWithError2[FileIOError, Int, Buffer](fs.write(fd, buffer, offset, length, position, _))
147197
}
148198

@@ -162,10 +212,19 @@ package object fs {
162212
}
163213

164214
@inline
165-
def writeFileFuture(file: String, data: Buffer | String, options: FileOutputOptions = null): Future[Unit] = {
215+
def writeFileFuture(file: String, data: Buffer, options: FileOutputOptions = null): Future[Unit] = {
166216
promiseWithError0[FileIOError](fs.writeFile(file, data, options, _))
167217
}
168218

219+
@inline
220+
def writeFileFuture(file: String, data: String, options: FileOutputOptions): Future[Unit] = {
221+
promiseWithError0[FileIOError](fs.writeFile(file, data, options, _))
222+
}
223+
224+
@inline
225+
def writeFileFuture(file: String, data: String): Future[Unit] = {
226+
promiseWithError0[FileIOError](fs.writeFile(file, data, _))
227+
}
169228
}
170229

171230
}

app/current/src/main/scala/io/scalajs/nodejs/package.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.scalajs
22

3+
import com.thoughtworks.enableIf
4+
import io.scalajs.nodejs.buffer.Buffer
35
import io.scalajs.nodejs.timers._
46

57
import scala.concurrent.duration.FiniteDuration
@@ -27,7 +29,7 @@ package object nodejs {
2729

2830
type FileIOError = SystemError
2931

30-
type FileMode = Integer
32+
type FileMode = Int
3133

3234
type FileType = Int
3335

@@ -48,6 +50,10 @@ package object nodejs {
4850
// 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.
4951
type Handle = js.Function | HasHandle | HasFileDescriptor
5052

53+
type ReaddirArrays = js.Array[String] | js.Array[Buffer]
54+
@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs10)
55+
type ReaddirArrays2 = ReaddirArrays | js.Array[fs.Dirent]
56+
5157
/////////////////////////////////////////////////////////////////////////////////
5258
// Built-in Properties
5359
/////////////////////////////////////////////////////////////////////////////////
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.scalajs.nodejs.fs
2+
3+
import org.scalatest.FunSpec
4+
5+
import scala.scalajs.js
6+
import scala.scalajs.js.typedarray.Uint8Array
7+
8+
/**
9+
* File System (Fs) Tests
10+
*
11+
*/
12+
class FsClassesTest extends FunSpec {
13+
describe("ReadStream") {
14+
it("supports pending added in v11.2.0") {
15+
assert(new ReadStream("package.json").pending)
16+
}
17+
}
18+
19+
}

app/nodejs-v8/src/test/scala/nodejs/fs/FsTest.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ class FsTest extends FunSpec {
7474
}
7575
}
7676

77+
it("support access") {
78+
Fs.access("./package.json", err => {
79+
assert(err == null)
80+
})
81+
}
82+
7783
}
7884

7985
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.scalajs.nodejs
2+
package fs
3+
4+
import io.scalajs.nodejs.buffer.Buffer
5+
import io.scalajs.nodejs.url.URL
6+
import org.scalatest.FunSpec
7+
8+
import scala.scalajs.js
9+
10+
class FsClassesTest extends FunSpec {
11+
val dirname = process.cwd()
12+
13+
describe("ReadStream") {
14+
it("supports constructor(") {
15+
assert(new ReadStream("package.json") != null)
16+
assert(new ReadStream(Buffer.from("package.json")) != null)
17+
assert(new ReadStream(new URL(s"file:///${dirname}/package.json")) != null)
18+
}
19+
}
20+
21+
describe("WriteStream") {
22+
it("supports constructor") {
23+
assert(new WriteStream("package.json") != null)
24+
assert(new WriteStream(Buffer.from("package.json")) != null)
25+
assert(new WriteStream(new URL(s"file:///${dirname}/package.json")) != null)
26+
}
27+
}
28+
29+
}

0 commit comments

Comments
 (0)