77-- | import Node.ChildProcess (ChildProcess(), CHILD_PROCESS())
88-- | import Node.ChildProcess as ChildProcess
99-- | ```
10+ -- |
11+ -- | The [Node.js documentation](https://nodejs.org/api/child_process.html)
12+ -- | will probably also be useful to read if you want to use this module.
1013module Node.ChildProcess
1114 ( Handle ()
1215 , ChildProcess ()
@@ -28,9 +31,13 @@ module Node.ChildProcess
2831 , onMessage
2932 , onError
3033 , spawn
31- , fork
3234 , SpawnOptions ()
3335 , defaultSpawnOptions
36+ , exec
37+ , ExecOptions ()
38+ , ExecResult ()
39+ , defaultExecOptions
40+ , fork
3441 , StdIOBehaviour (..)
3542 , pipe
3643 , inherit
@@ -48,13 +55,15 @@ import Control.Monad.Eff.Exception.Unsafe (unsafeThrow)
4855import Data.StrMap (StrMap ())
4956import Data.Function (Fn2 (), runFn2 )
5057import Data.Nullable (Nullable (), toNullable , toMaybe )
51- import Data.Maybe (Maybe (..), fromMaybe )
58+ import Data.Maybe (Maybe (..), fromMaybe , maybe )
5259import Data.Foreign (Foreign ())
53- import Data.Posix (Pid ())
60+ import Data.Posix (Pid (), Gid (), Uid () )
5461import Data.Posix.Signal (Signal ())
5562import Data.Posix.Signal as Signal
5663import Unsafe.Coerce (unsafeCoerce )
5764
65+ import Node.Buffer (Buffer ())
66+ import Node.Encoding (Encoding ())
5867import Node.FS as FS
5968import Node.Stream (Readable (), Writable (), Stream ())
6069
@@ -138,14 +147,6 @@ instance showExit :: Show Exit where
138147 show (Normally x) = " Normally " <> show x
139148 show (BySignal sig) = " BySignal " <> show sig
140149
141- type SpawnOptions =
142- { cwd :: Maybe String
143- , stdio :: Array (Maybe StdIOBehaviour )
144- , env :: Maybe (StrMap String )
145- , detached :: Boolean
146- , uid :: Maybe Int
147- , gid :: Maybe Int
148- }
149150
150151mkExit :: Nullable Int -> Nullable String -> Exit
151152mkExit code signal =
@@ -201,10 +202,14 @@ foreign import spawnImpl :: forall opts eff. String -> Array String -> { | opts
201202-- There's gotta be a better way.
202203foreign import undefined :: forall a . a
203204
204- -- | A special case of `spawn` for creating Node.js child processes. The first
205- -- | argument is the module to be run, and the second is the argv (command line
206- -- | arguments).
207- foreign import fork :: forall eff . String -> Array String -> Eff (cp :: CHILD_PROCESS | eff ) ChildProcess
205+ type SpawnOptions =
206+ { cwd :: Maybe String
207+ , stdio :: Array (Maybe StdIOBehaviour )
208+ , env :: Maybe (StrMap String )
209+ , detached :: Boolean
210+ , uid :: Maybe Uid
211+ , gid :: Maybe Gid
212+ }
208213
209214defaultSpawnOptions :: SpawnOptions
210215defaultSpawnOptions =
@@ -216,6 +221,71 @@ defaultSpawnOptions =
216221 , gid: Nothing
217222 }
218223
224+ -- | Similar to `spawn`, except that this variant will buffer output, and wait
225+ -- | until the process has exited before calling the callback.
226+ -- |
227+ -- | Note that the child process will be killed if the amount of output exceeds
228+ -- | a certain threshold (the default is defined by Node.js).
229+ exec :: forall eff .
230+ String ->
231+ ExecOptions ->
232+ (ExecResult -> Eff (cp :: CHILD_PROCESS | eff ) Unit ) ->
233+ Eff (cp :: CHILD_PROCESS | eff ) Unit
234+ exec cmd opts callback =
235+ execImpl cmd (convert opts) \err stdout' stderr' ->
236+ callback { error: (toMaybe err)
237+ , stdout: stdout'
238+ , stderr: stderr'
239+ }
240+ where
241+ convert opts =
242+ { cwd: fromMaybe undefined opts.cwd
243+ , env: fromMaybe undefined opts.env
244+ , timeout: fromMaybe undefined opts.timeout
245+ , maxBuffer: fromMaybe undefined opts.maxBuffer
246+ , killSignal: fromMaybe undefined opts.killSignal
247+ , uid: fromMaybe undefined opts.uid
248+ , gid: fromMaybe undefined opts.gid
249+ }
250+
251+ foreign import execImpl :: forall eff opts .
252+ String ->
253+ { | opts } ->
254+ (Nullable Exception.Error -> Buffer -> Buffer -> Eff (cp :: CHILD_PROCESS | eff ) Unit ) ->
255+ Eff (cp :: CHILD_PROCESS | eff ) Unit
256+
257+ type ExecOptions =
258+ { cwd :: Maybe String
259+ , env :: Maybe (StrMap String )
260+ , timeout :: Maybe Number
261+ , maxBuffer :: Maybe Int
262+ , killSignal :: Maybe Signal
263+ , uid :: Maybe Uid
264+ , gid :: Maybe Gid
265+ }
266+
267+ defaultExecOptions :: ExecOptions
268+ defaultExecOptions =
269+ { cwd: Nothing
270+ , env: Nothing
271+ , timeout: Nothing
272+ , maxBuffer: Nothing
273+ , killSignal: Nothing
274+ , uid: Nothing
275+ , gid: Nothing
276+ }
277+
278+ type ExecResult =
279+ { stderr :: Buffer
280+ , stdout :: Buffer
281+ , error :: Maybe Exception.Error
282+ }
283+
284+ -- | A special case of `spawn` for creating Node.js child processes. The first
285+ -- | argument is the module to be run, and the second is the argv (command line
286+ -- | arguments).
287+ foreign import fork :: forall eff . String -> Array String -> Eff (cp :: CHILD_PROCESS | eff ) ChildProcess
288+
219289-- | An error which occurred inside a child process.
220290type Error =
221291 { code :: String
0 commit comments