Skip to content

Commit 1df3ebd

Browse files
committed
fix: TypeError [ERR_INVALID_ARG_TYPE]: The "options.filter" property must be of type function. Received null
1 parent 43d512b commit 1df3ebd

File tree

5 files changed

+78
-8
lines changed

5 files changed

+78
-8
lines changed

spago.lock

+4-3
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
},
144144
"package_set": {
145145
"address": {
146-
"registry": "60.3.0"
146+
"registry": "60.5.0"
147147
},
148148
"compiler": ">=0.15.15 <0.16.0",
149149
"content": {
@@ -358,6 +358,7 @@
358358
"js-promise-aff": "1.0.0",
359359
"js-timers": "6.1.0",
360360
"js-uri": "3.1.0",
361+
"jsdom": "1.0.0",
361362
"json": "1.1.0",
362363
"json-codecs": "5.0.0",
363364
"justifill": "0.5.0",
@@ -547,8 +548,8 @@
547548
"soundfonts": "4.1.0",
548549
"sparse-matrices": "2.0.1",
549550
"sparse-polynomials": "3.0.1",
550-
"spec": "8.0.0",
551-
"spec-discovery": "8.3.0",
551+
"spec": "8.1.0",
552+
"spec-discovery": "8.4.0",
552553
"spec-mocha": "5.1.1",
553554
"spec-node": "0.0.2",
554555
"spec-quickcheck": "5.0.2",

spago.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,5 @@ package:
4040
- node-event-emitter
4141
workspace:
4242
packageSet:
43-
registry: 60.3.0
43+
registry: 60.5.0
4444
extraPackages: {}

src/Node/FS/Internal/Undefinable.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* eslint-disable no-eq-null, eqeqeq */
2+
3+
const undefinedImpl = undefined;
4+
export { undefinedImpl as undefined };
5+
6+
export function undefinable(a, r, f) {
7+
return a === undefined ? r : f(a);
8+
}
9+
10+
export function notUndefined(x) {
11+
return x;
12+
}

src/Node/FS/Internal/Undefinable.purs

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
-- | This module defines types and functions for working with undefinable types
2+
-- | using the FFI.
3+
4+
module Node.FS.Internal.Undefinable
5+
( Undefinable
6+
, undefined
7+
, notUndefined
8+
, toMaybe
9+
, toUndefinable
10+
) where
11+
12+
import Prelude
13+
14+
import Data.Eq (class Eq1)
15+
import Data.Function (on)
16+
import Data.Function.Uncurried (Fn3, runFn3)
17+
import Data.Maybe (Maybe(..), maybe)
18+
import Data.Ord (class Ord1)
19+
20+
foreign import data Undefinable :: Type -> Type
21+
22+
type role Undefinable representational
23+
24+
-- | The undefined value.
25+
foreign import undefined :: forall a. Undefinable a
26+
27+
foreign import undefinable :: forall a r. Fn3 (Undefinable a) r (a -> r) r
28+
29+
-- | Wrap a non-undefined value.
30+
foreign import notUndefined :: forall a. a -> Undefinable a
31+
32+
-- | Takes `Nothing` to `undefined`, and `Just a` to `a`.
33+
toUndefinable :: forall a. Maybe a -> Undefinable a
34+
toUndefinable = maybe undefined notUndefined
35+
36+
-- | Represent `undefined` using `Maybe a` as `Nothing`. Note that this function
37+
-- | can violate parametricity, as it inspects the runtime representation of
38+
-- | its argument (see the warning about the pitfall of `Undefinable` above).
39+
toMaybe :: forall a. Undefinable a -> Maybe a
40+
toMaybe n = runFn3 undefinable n Nothing Just
41+
42+
instance showUndefinable :: Show a => Show (Undefinable a) where
43+
show = maybe "undefined" show <<< toMaybe
44+
45+
instance eqUndefinable :: Eq a => Eq (Undefinable a) where
46+
eq = eq `on` toMaybe
47+
48+
instance eq1Undefinable :: Eq1 Undefinable where
49+
eq1 = eq
50+
51+
instance ordUndefinable :: Ord a => Ord (Undefinable a) where
52+
compare = compare `on` toMaybe
53+
54+
instance ord1Undefinable :: Ord1 Undefinable where
55+
compare1 = compare

src/Node/FS/Options.purs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
module Node.FS.Options where
22

3-
import Node.FS.Types (BufferLength, BufferOffset, EncodingString, FileMode, FilePosition)
43
import Prelude
54

65
import Data.Function.Uncurried (Fn2, mkFn2)
@@ -13,7 +12,10 @@ import Node.Buffer (Buffer)
1312
import Node.Encoding (Encoding(..), encodingToNode)
1413
import Node.FS.Constants (FileFlags(..), fileFlagsToNode)
1514
import Node.FS.Dirent (Dirent, DirentNameTypeString)
15+
import Node.FS.Internal.Undefinable (Undefinable)
16+
import Node.FS.Internal.Undefinable as Undefinable
1617
import Node.FS.Perms (Perms, all, mkPerms, permsToString, read, write)
18+
import Node.FS.Types (BufferLength, BufferOffset, EncodingString, FileMode, FilePosition)
1719
import Node.Path (FilePath)
1820

1921
type RmdirOptions = { maxRetries :: Int, retryDelay :: Int }
@@ -249,7 +251,8 @@ fdWriteOptionsToInternal { offset, length, position } = { offset, length: Nullab
249251
type CpOptionsInternal =
250252
{ dereference :: Boolean
251253
, errorOnExist :: Boolean
252-
, filter :: Nullable (Fn2 FilePath FilePath Boolean)
254+
-- if null - will throw "TypeError [ERR_INVALID_ARG_TYPE]: The "options.filter" property must be of type function. Received null"
255+
, filter :: Undefinable (Fn2 FilePath FilePath Boolean)
253256
, force :: Boolean
254257
, mode :: FileMode
255258
, preserveTimestamps :: Boolean
@@ -286,7 +289,7 @@ cpOptionsToCpOptionsInternal opts =
286289
, errorOnExist: case opts.force of
287290
CpForce_TrueWithErrorOnExit -> true
288291
_ -> false
289-
, filter: toNullable $ map mkFn2 (opts.filter)
292+
, filter: Undefinable.toUndefinable $ map mkFn2 (opts.filter)
290293
, force: case opts.force of
291294
CpForce_False -> false
292295
_ -> true
@@ -326,4 +329,3 @@ opendirOptionsDefault = { bufferSize: 32, recursive: false, encoding: UTF8 }
326329

327330
opendirOptionsToInternal :: OpendirOptions -> OpendirOptionsInternal
328331
opendirOptionsToInternal { encoding, bufferSize, recursive } = { encoding: encodingToNode encoding, bufferSize, recursive }
329-

0 commit comments

Comments
 (0)