diff --git a/.eslintrc.json b/.eslintrc.json index 7b219e5..e533320 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,6 @@ { "parserOptions": { - "ecmaVersion": 6, + "ecmaVersion": 9, "sourceType": "module" }, "extends": "eslint:recommended", diff --git a/CHANGELOG.md b/CHANGELOG.md index 19be5fe..99483bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,24 @@ New features: getGid :: Stats -> Number getGid s = Stats.gid s ``` +- Update `[fd]createReadStream`/`[fd]createWriteStream` to allow more options (#77 by @JordanMartinez) + + | Removes... | ...in favor of | + | - | - | + | `createReadStreamWith` | `createReadStream'` | + | `fdCreateReadStreamWith` | `fdCreateReadStream'` | + | `createWriteStreamWith` | `createWriteStream'` | + | `fdCreateWriteStreamWith` | `fdCreateWriteStream'` | + + In the new APIs, all options are exposed and may require converting + PureScript values to JavaScript ones. + ```purs + filePath # createWriteStream' + { flags: fileFlagsToNode R + , encoding: encodingToNode UTF8 + , mode: permsToInt Perms.all + } + ``` Bugfixes: diff --git a/src/Node/FS/Stream.js b/src/Node/FS/Stream.js index bfc7126..9fdb6d8 100644 --- a/src/Node/FS/Stream.js +++ b/src/Node/FS/Stream.js @@ -1,4 +1,11 @@ -export { - createReadStream as createReadStreamImpl, - createWriteStream as createWriteStreamImpl -} from "fs"; +import fs from "node:fs"; + +export const createReadStreamImpl = (path) => fs.createReadStream(path); +export const createReadStreamOptsImpl = (path, opts) => fs.createReadStream(path, opts); +export const fdCreateReadStreamImpl = (fd) => fs.createReadStream(null, { fd }); +export const fdCreateReadStreamOptsImpl = (fd, opts) => fs.createReadStream(null, { ...opts, fd}); + +export const createWriteStreamImpl = (path) => fs.createWriteStream(path); +export const createWriteStreamOptsImpl = (path, opts) => fs.createWriteStream(path, opts); +export const fdCreateWriteStreamImpl = (fd) => fs.createWriteStream(null, { fd }); +export const fdCreateWriteStreamOptsImpl = (fd, opts) => fs.createWriteStream(null, { ...opts, fd}); diff --git a/src/Node/FS/Stream.purs b/src/Node/FS/Stream.purs index 0c4468a..f1c054e 100644 --- a/src/Node/FS/Stream.purs +++ b/src/Node/FS/Stream.purs @@ -1,138 +1,152 @@ module Node.FS.Stream ( createWriteStream - , fdCreateWriteStream , WriteStreamOptions - , defaultWriteStreamOptions - , createWriteStreamWith - , fdCreateWriteStreamWith + , createWriteStream' + , fdCreateWriteStream + , fdCreateWriteStream' , createReadStream - , fdCreateReadStream , ReadStreamOptions - , defaultReadStreamOptions - , createReadStreamWith - , fdCreateReadStreamWith + , createReadStream' + , fdCreateReadStream + , fdCreateReadStream' ) where -import Prelude - -import Data.Nullable (Nullable, notNull, null) import Effect (Effect) -import Effect.Uncurried (EffectFn2, runEffectFn2) +import Effect.Uncurried (EffectFn1, EffectFn2, runEffectFn1, runEffectFn2) import Node.FS (FileDescriptor) -import Node.FS.Constants (FileFlags(..), fileFlagsToNode) -import Node.FS.Perms (Perms) -import Node.FS.Perms as Perms import Node.Path (FilePath) import Node.Stream (Readable, Writable) - -foreign import createReadStreamImpl :: forall opts. EffectFn2 (Nullable FilePath) { | opts } (Readable ()) -foreign import createWriteStreamImpl :: forall opts. EffectFn2 (Nullable FilePath) { | opts } (Writable ()) - -readWrite :: Perms -readWrite = Perms.mkPerms rw rw rw - where - rw = Perms.read + Perms.write +import Prim.Row as Row -- | Create a Writable stream which writes data to the specified file, using -- | the default options. -createWriteStream - :: FilePath +createWriteStream :: FilePath -> Effect (Writable ()) +createWriteStream f = runEffectFn1 createWriteStreamImpl f + +foreign import createWriteStreamImpl :: EffectFn1 (FilePath) (Writable ()) + +type WriteStreamOptions = + ( flags :: String + , encoding :: String + , mode :: Int + , autoClose :: Boolean + , emitClose :: Boolean + , start :: Int + ) + +-- | Create a Writable stream which writes data to the specified file. +-- | Unused options should not be specified. Some options +-- | (e.g. `flags`, `encoding`, and `mode`) should convert their +-- | PureScript values to the corresponding JavaScript ones: +-- | ``` +-- | filePath # createWriteStream' +-- | { flags: fileFlagsToNode R +-- | , encoding: encodingToNode UTF8 +-- | , mode: permsToInt Perms.all +-- | } +-- | ``` +createWriteStream' + :: forall r trash + . Row.Union r trash WriteStreamOptions + => FilePath + -> { | r } -> Effect (Writable ()) -createWriteStream = createWriteStreamWith defaultWriteStreamOptions +createWriteStream' f opts = runEffectFn2 createWriteStreamOptsImpl f opts + +foreign import createWriteStreamOptsImpl :: forall r. EffectFn2 (FilePath) ({ | r }) ((Writable ())) -- | Create a Writable stream which writes data to the specified file -- | descriptor, using the default options. -fdCreateWriteStream - :: FileDescriptor +fdCreateWriteStream :: FileDescriptor -> Effect (Writable ()) +fdCreateWriteStream f = runEffectFn1 fdCreateWriteStreamImpl f + +foreign import fdCreateWriteStreamImpl :: EffectFn1 (FileDescriptor) (Writable ()) + +-- | Create a Writable stream which writes data to the specified file descriptor. +-- | Unused options should not be specified. Some options +-- | (e.g. `flags`, `encoding`, and `mode`) should convert their +-- | PureScript values to the corresponding JavaScript ones: +-- | ``` +-- | filePath # fdCreateWriteStream' +-- | { flags: fileFlagsToNode R +-- | , encoding: encodingToNode UTF8 +-- | , mode: permsToInt Perms.all +-- | } +-- | ``` +fdCreateWriteStream' + :: forall r trash + . Row.Union r trash WriteStreamOptions + => FileDescriptor + -> { | r } -> Effect (Writable ()) -fdCreateWriteStream = fdCreateWriteStreamWith defaultWriteStreamOptions +fdCreateWriteStream' f opts = runEffectFn2 fdCreateWriteStreamOptsImpl f opts -type WriteStreamOptions = - { flags :: FileFlags - , perms :: Perms - } - -defaultWriteStreamOptions :: WriteStreamOptions -defaultWriteStreamOptions = - { flags: W - , perms: readWrite - } - --- | Like `createWriteStream`, but allows you to pass options. -createWriteStreamWith - :: WriteStreamOptions - -> FilePath - -> Effect (Writable ()) -createWriteStreamWith opts file = runEffectFn2 - createWriteStreamImpl - (notNull file) - { mode: Perms.permsToInt opts.perms - , flags: fileFlagsToNode opts.flags - } - --- | Like `fdCreateWriteStream`, but allows you to pass options. -fdCreateWriteStreamWith - :: WriteStreamOptions - -> FileDescriptor - -> Effect (Writable ()) -fdCreateWriteStreamWith opts fd = runEffectFn2 - createWriteStreamImpl - null - { fd - , mode: Perms.permsToInt opts.perms - , flags: fileFlagsToNode opts.flags - } +foreign import fdCreateWriteStreamOptsImpl :: forall r. EffectFn2 (FileDescriptor) ({ | r }) (Writable ()) -- | Create a Readable stream which reads data to the specified file, using -- | the default options. -createReadStream - :: FilePath - -> Effect (Readable ()) -createReadStream = createReadStreamWith defaultReadStreamOptions +createReadStream :: FilePath -> Effect (Readable ()) +createReadStream p = runEffectFn1 createReadStreamImpl p --- | Create a Readable stream which reads data to the specified file --- | descriptor, using the default options. -fdCreateReadStream - :: FileDescriptor - -> Effect (Readable ()) -fdCreateReadStream = fdCreateReadStreamWith defaultReadStreamOptions +foreign import createReadStreamImpl :: EffectFn1 (FilePath) (Readable ()) type ReadStreamOptions = - { flags :: FileFlags - , perms :: Perms + ( flags :: String + , encoding :: String + , mode :: Int , autoClose :: Boolean - } - -defaultReadStreamOptions :: ReadStreamOptions -defaultReadStreamOptions = - { flags: R - , perms: readWrite - , autoClose: true - } + , emitClose :: Boolean + , start :: Int + , end :: Int + , highWaterMark :: Int + ) -- | Create a Readable stream which reads data from the specified file. -createReadStreamWith - :: ReadStreamOptions - -> FilePath +-- | Unused options should not be specified. Some options +-- | (e.g. `flags`, `encoding`, and `mode`) should convert their +-- | PureScript values to the corresponding JavaScript ones: +-- | ``` +-- | filePath # createReadStream' +-- | { flags: fileFlagsToNode R +-- | , encoding: encodingToNode UTF8 +-- | , mode: permsToInt Perms.all +-- | } +-- | ``` +createReadStream' + :: forall r trash + . Row.Union r trash ReadStreamOptions + => FilePath + -> { | r } -> Effect (Readable ()) -createReadStreamWith opts file = runEffectFn2 - createReadStreamImpl - (notNull file) - { mode: Perms.permsToInt opts.perms - , flags: fileFlagsToNode opts.flags - , autoClose: opts.autoClose - } - --- | Create a Readable stream which reads data from the specified file descriptor. -fdCreateReadStreamWith - :: ReadStreamOptions - -> FileDescriptor +createReadStream' path opts = runEffectFn2 createReadStreamOptsImpl path opts + +foreign import createReadStreamOptsImpl :: forall r. EffectFn2 (FilePath) ({ | r }) ((Readable ())) + +-- | Create a Readable stream which reads data to the specified file +-- | descriptor, using the default options. +fdCreateReadStream :: FileDescriptor -> Effect (Readable ()) +fdCreateReadStream f = runEffectFn1 fdCreateReadStreamImpl f + +foreign import fdCreateReadStreamImpl :: EffectFn1 (FileDescriptor) (Readable ()) + +-- | Create a Readable stream which reads data to the specified file descriptor. +-- | Unused options should not be specified. Some options +-- | (e.g. `flags`, `encoding`, and `mode`) should convert their +-- | PureScript values to the corresponding JavaScript ones: +-- | ``` +-- | filePath # fdCreateReadStream' +-- | { flags: fileFlagsToNode R +-- | , encoding: encodingToNode UTF8 +-- | , mode: permsToInt Perms.all +-- | } +-- | ``` +fdCreateReadStream' + :: forall r trash + . Row.Union r trash ReadStreamOptions + => FileDescriptor + -> { | r } -> Effect (Readable ()) -fdCreateReadStreamWith opts fd = runEffectFn2 - createReadStreamImpl - null - { fd - , mode: Perms.permsToInt opts.perms - , flags: fileFlagsToNode opts.flags - , autoClose: opts.autoClose - } +fdCreateReadStream' f opts = runEffectFn2 fdCreateReadStreamOptsImpl f opts + +foreign import fdCreateReadStreamOptsImpl :: forall r. EffectFn2 (FileDescriptor) ({ | r }) ((Readable ())) +