 (s/def ::out string?)
 (s/def ::err string?)
 
-(s/fdef sh-internal
-  :args ::sh-async-args
-  :ret (s/keys :req-un [::exit ::out ::err]))
-
 (s/fdef sh
   :args ::sh-args
   :ret (s/keys :req-un [::exit ::out ::err]))
+
+(s/fdef sh-async
+  :args ::sh-async-args
+  :ret nil?)


(def ^:private nil-func (fn [_] nil))
(defn- sh-internal
  "Launches a sub-process with the supplied arguments.
  Parameters: cmd, <options>, cb (may be nil-func for synchronous)
  cmd      the command(s) (Strings) to execute. will be concatenated together.
  options  optional keyword arguments-- see below.
  cb       the callback to call upon completion (for async). specify nil-func for sync.
  Options are:
  :in      may be given followed by a string of one of the following formats:
           String conforming to URL Syntax: 'file:///tmp/test.txt'
           String pointing at an *existing* 'file: '/tmp/test.txt'
           String with string input: 'Printing input from stdin with funny chars like $@ &'
           to be fed to the sub-process's stdin.
  :in-enc  option may be given followed by a String, used as a character
           encoding name (for example \"UTF-8\" or \"ISO-8859-1\") to
           convert the input string specified by the :in option to the
           sub-process's stdin.  Defaults to UTF-8.
  :out-enc option may be given followed by a String. If a
           String is given, it will be used as a character encoding
           name (for example \"UTF-8\" or \"ISO-8859-1\") to convert
           the sub-process's stdout to a String which is returned.
  :env     override the process env with a map of String: String.
  :dir     override the process dir with a String or planck.io/File.
  if the command can be launched and cb is nil-func, sh returns a map of
    :exit => sub-process's exit code
    :out  => sub-process's stdout (as String)
    :err  => sub-process's stderr (String via platform default encoding),
  otherwise if cb is not nil-func, executes async and returns nil immediately.
  otherwise it throws an exception"
  [& args]
  (let [{:keys [cmd opts cb]} (s/conform ::sh-async-args args)]
    (when (nil? cmd)

        (throw (js/Error. err))
        (if async? nil translated)))))

(defn sh
  "Launches a sub-process with the supplied arguments.
  Parameters: cmd, <options>
  cmd      the command(s) (Strings) to execute. will be concatenated together.
  options  optional keyword arguments-- see below.
  Options are:
  :in      may be given followed by a string of one of the following formats:
           String conforming to URL Syntax: 'file:///tmp/test.txt'
           String pointing at an *existing* 'file: '/tmp/test.txt'
           String with string input: 'Printing input from stdin with funny chars like $@ &'
           to be fed to the sub-process's stdin.
  :in-enc  option may be given followed by a String, used as a character
           encoding name (for example \"UTF-8\" or \"ISO-8859-1\") to
           convert the input string specified by the :in option to the
           sub-process's stdin.  Defaults to UTF-8.
  :out-enc option may be given followed by a String. If a
           String is given, it will be used as a character encoding
           name (for example \"UTF-8\" or \"ISO-8859-1\") to convert
           the sub-process's stdout to a String which is returned.
  :env     override the process env with a map of String: String.
  :dir     override the process dir with a String or planck.io/File.
  if the command can be launched, sh returns a map of
    :exit => sub-process's exit code
    :out  => sub-process's stdout (as String)
    :err  => sub-process's stderr (String via platform default encoding),
  otherwise it throws an exception"
  [& args]
  (apply sh-internal (concat args [nil-func])))

(when-not (clojure.string/starts-with? js/PLANCK_VERSION "1.")
  (defn sh-async 
    "Launches a sub-process with the supplied arguments.
    Parameters: cmd, <options>, cb
    cmd      the command(s) (Strings) to execute. will be concatenated together.
    options  optional keyword arguments-- see below.
    cb       the callback to call upon completion
    Options are:
    :in      may be given followed by a string of one of the following formats:
             String conforming to URL Syntax: 'file:///tmp/test.txt'
             String pointing at an *existing* 'file: '/tmp/test.txt'
             String with string input: 'Printing input from stdin with funny chars like $@ &'
             to be fed to the sub-process's stdin.
    :in-enc  option may be given followed by a String, used as a character
             encoding name (for example \"UTF-8\" or \"ISO-8859-1\") to
             convert the input string specified by the :in option to the
             sub-process's stdin.  Defaults to UTF-8.
    :out-enc option may be given followed by a String. If a
             String is given, it will be used as a character encoding
             name (for example \"UTF-8\" or \"ISO-8859-1\") to convert
             the sub-process's stdout to a String which is returned.
    :env     override the process env with a map of String: String.
    :dir     override the process dir with a String or planck.io/File.
    if the command can be launched, sh-async calls back with a map of
      :exit => sub-process's exit code
      :out  => sub-process's stdout (as String)
      :err  => sub-process's stderr (String via platform default encoding),
    Returns nil immediately"
    [& args]
    (apply sh-internal args)))

(s/def ::string-string-map? (s/and map? (fn [m]
