Skip to content

Commit 8f694ba

Browse files
integrate node fs aff (#75)
* Copy over node-fs-aff as-is * Integrate tests * Add changelog entry
1 parent 3607325 commit 8f694ba

File tree

4 files changed

+346
-1
lines changed

4 files changed

+346
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Notable changes to this project are documented in this file. The format is based
77
Breaking changes:
88

99
New features:
10+
- Integrate `node-fs-aff` into library (#75 by @JordanMartinez)
1011

1112
Bugfixes:
1213

src/Node/FS/Aff.purs

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
module Node.FS.Aff
2+
( access
3+
, access'
4+
, copyFile
5+
, copyFile'
6+
, mkdtemp
7+
, mkdtemp'
8+
, rename
9+
, truncate
10+
, chown
11+
, chmod
12+
, stat
13+
, link
14+
, symlink
15+
, readlink
16+
, realpath
17+
, realpath'
18+
, unlink
19+
, rmdir
20+
, rmdir'
21+
, rm
22+
, rm'
23+
, mkdir
24+
, mkdir'
25+
, readdir
26+
, utimes
27+
, readFile
28+
, readTextFile
29+
, writeFile
30+
, writeTextFile
31+
, appendFile
32+
, appendTextFile
33+
, fdOpen
34+
, fdRead
35+
, fdNext
36+
, fdWrite
37+
, fdAppend
38+
, fdClose
39+
) where
40+
41+
import Prelude
42+
43+
import Data.DateTime (DateTime)
44+
import Data.Either (Either(..))
45+
import Data.Maybe (Maybe)
46+
import Effect (Effect)
47+
import Effect.Aff (Aff, Error, makeAff, nonCanceler)
48+
import Node.Buffer (Buffer)
49+
import Node.Encoding (Encoding)
50+
import Node.FS as F
51+
import Node.FS.Async as A
52+
import Node.FS.Constants (AccessMode, CopyMode)
53+
import Node.FS.Perms (Perms)
54+
import Node.FS.Stats (Stats)
55+
import Node.Path (FilePath)
56+
57+
toAff
58+
:: forall a
59+
. (A.Callback a -> Effect Unit)
60+
-> Aff a
61+
toAff p = makeAff \k -> p k $> nonCanceler
62+
63+
toAff1
64+
:: forall a x
65+
. (x -> A.Callback a -> Effect Unit)
66+
-> x
67+
-> Aff a
68+
toAff1 f a = toAff (f a)
69+
70+
toAff2
71+
:: forall a x y
72+
. (x -> y -> A.Callback a -> Effect Unit)
73+
-> x
74+
-> y
75+
-> Aff a
76+
toAff2 f a b = toAff (f a b)
77+
78+
toAff3
79+
:: forall a x y z
80+
. (x -> y -> z -> A.Callback a -> Effect Unit)
81+
-> x
82+
-> y
83+
-> z
84+
-> Aff a
85+
toAff3 f a b c = toAff (f a b c)
86+
87+
toAff5
88+
:: forall a w v x y z
89+
. (w -> v -> x -> y -> z -> A.Callback a -> Effect Unit)
90+
-> w
91+
-> v
92+
-> x
93+
-> y
94+
-> z
95+
-> Aff a
96+
toAff5 f a b c d e = toAff (f a b c d e)
97+
98+
access :: String -> Aff (Maybe Error)
99+
access path = makeAff \k -> do
100+
A.access path (k <<< Right)
101+
pure nonCanceler
102+
103+
access' :: String -> AccessMode -> Aff (Maybe Error)
104+
access' path mode = makeAff \k -> do
105+
A.access' path mode (k <<< Right)
106+
pure nonCanceler
107+
108+
copyFile :: String -> String -> Aff Unit
109+
copyFile = toAff2 A.copyFile
110+
111+
copyFile' :: String -> String -> CopyMode -> Aff Unit
112+
copyFile' = toAff3 A.copyFile'
113+
114+
mkdtemp :: String -> Aff String
115+
mkdtemp = toAff1 A.mkdtemp
116+
117+
mkdtemp' :: String -> Encoding -> Aff String
118+
mkdtemp' = toAff2 A.mkdtemp'
119+
120+
-- |
121+
-- | Rename a file.
122+
-- |
123+
rename :: FilePath -> FilePath -> Aff Unit
124+
rename = toAff2 A.rename
125+
126+
-- |
127+
-- | Truncates a file to the specified length.
128+
-- |
129+
truncate :: FilePath -> Int -> Aff Unit
130+
truncate = toAff2 A.truncate
131+
132+
-- |
133+
-- | Changes the ownership of a file.
134+
-- |
135+
chown :: FilePath -> Int -> Int -> Aff Unit
136+
chown = toAff3 A.chown
137+
138+
-- |
139+
-- | Changes the permissions of a file.
140+
-- |
141+
chmod :: FilePath -> Perms -> Aff Unit
142+
chmod = toAff2 A.chmod
143+
144+
-- |
145+
-- | Gets file statistics.
146+
-- |
147+
stat :: FilePath -> Aff Stats
148+
stat = toAff1 A.stat
149+
150+
-- |
151+
-- | Creates a link to an existing file.
152+
-- |
153+
link :: FilePath -> FilePath -> Aff Unit
154+
link = toAff2 A.link
155+
156+
-- |
157+
-- | Creates a symlink.
158+
-- |
159+
symlink
160+
:: FilePath
161+
-> FilePath
162+
-> F.SymlinkType
163+
-> Aff Unit
164+
symlink = toAff3 A.symlink
165+
166+
-- |
167+
-- | Reads the value of a symlink.
168+
-- |
169+
readlink :: FilePath -> Aff FilePath
170+
readlink = toAff1 A.readlink
171+
172+
-- |
173+
-- | Find the canonicalized absolute location for a path.
174+
-- |
175+
realpath :: FilePath -> Aff FilePath
176+
realpath = toAff1 A.realpath
177+
178+
-- |
179+
-- | Find the canonicalized absolute location for a path using a cache object
180+
-- | for already resolved paths.
181+
-- |
182+
realpath' :: forall cache. FilePath -> { | cache } -> Aff FilePath
183+
realpath' = toAff2 A.realpath'
184+
185+
-- |
186+
-- | Deletes a file.
187+
-- |
188+
unlink :: FilePath -> Aff Unit
189+
unlink = toAff1 A.unlink
190+
191+
-- |
192+
-- | Deletes a directory.
193+
-- |
194+
rmdir :: FilePath -> Aff Unit
195+
rmdir = toAff1 A.rmdir
196+
197+
-- |
198+
-- | Deletes a directory with options.
199+
-- |
200+
rmdir' :: FilePath -> { maxRetries :: Int, retryDelay :: Int } -> Aff Unit
201+
rmdir' = toAff2 A.rmdir'
202+
203+
-- |
204+
-- | Deletes a file or directory.
205+
-- |
206+
rm :: FilePath -> Aff Unit
207+
rm = toAff1 A.rmdir
208+
209+
-- |
210+
-- | Deletes a file or directory with options.
211+
-- |
212+
rm' :: FilePath -> { force :: Boolean, maxRetries :: Int, recursive :: Boolean, retryDelay :: Int } -> Aff Unit
213+
rm' = toAff2 A.rm'
214+
215+
-- |
216+
-- | Makes a new directory.
217+
-- |
218+
mkdir :: FilePath -> Aff Unit
219+
mkdir = toAff1 A.mkdir
220+
221+
-- |
222+
-- | Makes a new directory with all of its options.
223+
-- |
224+
mkdir' :: FilePath -> { recursive :: Boolean, mode :: Perms } -> Aff Unit
225+
mkdir' = toAff2 A.mkdir'
226+
227+
-- |
228+
-- | Reads the contents of a directory.
229+
-- |
230+
readdir :: FilePath -> Aff (Array FilePath)
231+
readdir = toAff1 A.readdir
232+
233+
-- |
234+
-- | Sets the accessed and modified times for the specified file.
235+
-- |
236+
utimes :: FilePath -> DateTime -> DateTime -> Aff Unit
237+
utimes = toAff3 A.utimes
238+
239+
-- |
240+
-- | Reads the entire contents of a file returning the result as a raw buffer.
241+
-- |
242+
readFile :: FilePath -> Aff Buffer
243+
readFile = toAff1 A.readFile
244+
245+
-- |
246+
-- | Reads the entire contents of a text file with the specified encoding.
247+
-- |
248+
readTextFile :: Encoding -> FilePath -> Aff String
249+
readTextFile = toAff2 A.readTextFile
250+
251+
-- |
252+
-- | Writes a buffer to a file.
253+
-- |
254+
writeFile :: FilePath -> Buffer -> Aff Unit
255+
writeFile = toAff2 A.writeFile
256+
257+
-- |
258+
-- | Writes text to a file using the specified encoding.
259+
-- |
260+
writeTextFile :: Encoding -> FilePath -> String -> Aff Unit
261+
writeTextFile = toAff3 A.writeTextFile
262+
263+
-- |
264+
-- | Appends the contents of a buffer to a file.
265+
-- |
266+
appendFile :: FilePath -> Buffer -> Aff Unit
267+
appendFile = toAff2 A.appendFile
268+
269+
-- |
270+
-- | Appends text to a file using the specified encoding.
271+
-- |
272+
appendTextFile :: Encoding -> FilePath -> String -> Aff Unit
273+
appendTextFile = toAff3 A.appendTextFile
274+
275+
-- | Open a file asynchronously. See the [Node Documentation](https://nodejs.org/api/fs.html#fs_fs_open_path_flags_mode_callback)
276+
-- | for details.
277+
fdOpen
278+
:: FilePath
279+
-> F.FileFlags
280+
-> Maybe F.FileMode
281+
-> Aff F.FileDescriptor
282+
fdOpen = toAff3 A.fdOpen
283+
284+
-- | Read from a file asynchronously. See the [Node Documentation](https://nodejs.org/api/fs.html#fs_fs_read_fd_buffer_offset_length_position_callback)
285+
-- | for details.
286+
fdRead
287+
:: F.FileDescriptor
288+
-> Buffer
289+
-> F.BufferOffset
290+
-> F.BufferLength
291+
-> Maybe F.FilePosition
292+
-> Aff F.ByteCount
293+
fdRead = toAff5 A.fdRead
294+
295+
-- | Convenience function to fill the whole buffer from the current
296+
-- | file position.
297+
fdNext :: F.FileDescriptor -> Buffer -> Aff F.ByteCount
298+
fdNext = toAff2 A.fdNext
299+
300+
-- | Write to a file asynchronously. See the [Node Documentation](https://nodejs.org/api/fs.html#fs_fs_write_fd_buffer_offset_length_position_callback)
301+
-- | for details.
302+
fdWrite
303+
:: F.FileDescriptor
304+
-> Buffer
305+
-> F.BufferOffset
306+
-> F.BufferLength
307+
-> Maybe F.FilePosition
308+
-> Aff F.ByteCount
309+
fdWrite = toAff5 A.fdWrite
310+
311+
-- | Convenience function to append the whole buffer to the current
312+
-- | file position.
313+
fdAppend :: F.FileDescriptor -> Buffer -> Aff F.ByteCount
314+
fdAppend = toAff2 A.fdAppend
315+
316+
-- | Close a file asynchronously. See the [Node Documentation](https://nodejs.org/api/fs.html#fs_fs_close_fd_callback)
317+
-- | for details.
318+
fdClose :: F.FileDescriptor -> Aff Unit
319+
fdClose = toAff1 A.fdClose

test/Main.purs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
module Test.Main where
22

33
import Prelude
4+
45
import Effect (Effect)
56
import Test as Test
6-
import TestAsync as TestAsync
77
import Test.Streams as Streams
8+
import TestAff as TestAff
9+
import TestAsync as TestAsync
810

911
main :: Effect Unit
1012
main = do
1113
Test.main
1214
TestAsync.main
1315
Streams.main
16+
TestAff.main

test/TestAff.purs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module TestAff where
2+
3+
import Prelude
4+
5+
import Data.Array (filterA)
6+
import Data.Maybe (maybe)
7+
import Data.String.CodeUnits (charAt, singleton)
8+
import Effect (Effect)
9+
import Effect.Aff (launchAff_)
10+
import Effect.Class (liftEffect)
11+
import Effect.Console (log)
12+
import Node.FS.Aff (stat, readdir)
13+
import Node.FS.Stats (isDirectory)
14+
15+
main :: Effect Unit
16+
main = launchAff_ do
17+
files <- readdir "."
18+
files' <- flip filterA files \file -> do
19+
stat <- stat file
20+
pure $ isDirectory stat
21+
&& (maybe false (singleton >>> (_ /= ".")) $ charAt 0 file)
22+
liftEffect $ log $ show files'

0 commit comments

Comments
 (0)