@@ -0,0 +1,167 @@
1+module Yoga.Om.Node
2+ ( readFile
3+ , readTextFile
4+ , writeFile
5+ , writeTextFile
6+ , appendFile
7+ , appendTextFile
8+ , exists
9+ , mkdir
10+ , rmdir
11+ , unlink
12+ , getEnv
13+ , lookupEnv
14+ , setEnv
15+ , cwd
16+ , FileError
17+ , EnvError
18+ ) where
19+
20+import Prelude
21+
22+import Data.Either (Either(..))
23+import Data.Maybe (Maybe, maybe)
24+import Effect.Aff (Aff)
25+import Effect.Class (liftEffect)
26+import Node.Buffer (Buffer)
27+import Node.Encoding (Encoding(..))
28+import Node.FS.Aff as FS
29+import Node.Path (FilePath)
30+import Node.Process as Process
31+import Yoga.Om (Om)
32+import Yoga.Om as Om
33+
34+-- | Error types for file operations
35+type FileError r =
36+ ( fileNotFound :: { path :: FilePath }
37+ , fileReadError :: { path :: FilePath, message :: String }
38+ , fileWriteError :: { path :: FilePath, message :: String }
39+ , fileSystemError :: { message :: String }
40+ | r
41+ )
42+
43+-- | Error types for environment variable operations
44+type EnvError r =
45+ ( envNotFound :: { variable :: String }
46+ | r
47+ )
48+
49+-- | Read a file as a Buffer
50+readFile
51+ :: forall ctx err
52+ . FilePath
53+ -> Om ctx (FileError err) Buffer
54+readFile path = do
55+ result <- Om.fromAff $ FS.readFile path
56+ pure result
57+
58+-- | Read a file as text with UTF-8 encoding
59+readTextFile
60+ :: forall ctx err
61+ . FilePath
62+ -> Om ctx (FileError err) String
63+readTextFile path = do
64+ result <- Om.fromAff $ FS.readTextFile UTF8 path
65+ pure result
66+
67+-- | Write a Buffer to a file
68+writeFile
69+ :: forall ctx err
70+ . FilePath
71+ -> Buffer
72+ -> Om ctx (FileError err) Unit
73+writeFile path buffer = do
74+ Om.fromAff $ FS.writeFile path buffer
75+
76+-- | Write text to a file with UTF-8 encoding
77+writeTextFile
78+ :: forall ctx err
79+ . FilePath
80+ -> String
81+ -> Om ctx (FileError err) Unit
82+writeTextFile path content = do
83+ Om.fromAff $ FS.writeTextFile UTF8 path content
84+
85+-- | Append a Buffer to a file
86+appendFile
87+ :: forall ctx err
88+ . FilePath
89+ -> Buffer
90+ -> Om ctx (FileError err) Unit
91+appendFile path buffer = do
92+ Om.fromAff $ FS.appendFile path buffer
93+
94+-- | Append text to a file with UTF-8 encoding
95+appendTextFile
96+ :: forall ctx err
97+ . FilePath
98+ -> String
99+ -> Om ctx (FileError err) Unit
100+appendTextFile path content = do
101+ Om.fromAff $ FS.appendTextFile UTF8 path content
102+
103+-- | Check if a file or directory exists
104+exists
105+ :: forall ctx err
106+ . FilePath
107+ -> Om ctx err Boolean
108+exists path = do
109+ (Om.fromAff $ FS.stat path $> true)
110+ # Om.handleErrors { exception: \_ -> pure false }
111+
112+-- | Create a directory
113+mkdir
114+ :: forall ctx err
115+ . FilePath
116+ -> Om ctx (FileError err) Unit
117+mkdir path = do
118+ Om.fromAff $ FS.mkdir path
119+
120+-- | Remove a directory
121+rmdir
122+ :: forall ctx err
123+ . FilePath
124+ -> Om ctx (FileError err) Unit
125+rmdir path = do
126+ Om.fromAff $ FS.rmdir path
127+
128+-- | Delete a file
129+unlink
130+ :: forall ctx err
131+ . FilePath
132+ -> Om ctx (FileError err) Unit
133+unlink path = do
134+ Om.fromAff $ FS.unlink path
135+
136+-- | Get an environment variable, throwing an error if not found
137+getEnv
138+ :: forall ctx err
139+ . String
140+ -> Om ctx (EnvError err) String
141+getEnv variable = do
142+ value <- lookupEnv variable
143+ value # Om.note { envNotFound: { variable } }
144+
145+-- | Look up an environment variable, returning Maybe
146+lookupEnv
147+ :: forall ctx err
148+ . String
149+ -> Om ctx err (Maybe String)
150+lookupEnv variable = do
151+ Om.fromAff $ liftEffect $ Process.lookupEnv variable
152+
153+-- | Set an environment variable
154+setEnv
155+ :: forall ctx err
156+ . String
157+ -> String
158+ -> Om ctx err Unit
159+setEnv variable value = do
160+ Om.fromAff $ liftEffect $ Process.setEnv variable value
161+
162+-- | Get the current working directory
163+cwd
164+ :: forall ctx err
165+ . Om ctx err FilePath
166+cwd = do
167+ Om.fromAff $ liftEffect $ Process.cwd