feat: initial commit
This commit is contained in:
commit
8c578b42bd
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
bower_components/
|
||||||
|
node_modules/
|
||||||
|
.pulp-cache/
|
||||||
|
output/
|
||||||
|
output-es/
|
||||||
|
generated-docs/
|
||||||
|
.psc-package/
|
||||||
|
.psc*
|
||||||
|
.purs*
|
||||||
|
.psa*
|
||||||
|
.spago
|
1
.tool-versions
Normal file
1
.tool-versions
Normal file
@ -0,0 +1 @@
|
|||||||
|
purescript 0.15.16-1
|
16
jsconfig.json
Normal file
16
jsconfig.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"types": ["bun-types"],
|
||||||
|
"lib": ["esnext"],
|
||||||
|
"target": "esnext",
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"jsx": "react",
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"strict": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.js", "bun/**/*.js"]
|
||||||
|
}
|
10
package.json
Normal file
10
package.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "purescript-csv-stream",
|
||||||
|
"dependencies": {
|
||||||
|
"csv-parse": "^5.5.5",
|
||||||
|
"csv-stringify": "^6.4.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.4.5"
|
||||||
|
}
|
||||||
|
}
|
760
spago.lock
Normal file
760
spago.lock
Normal file
@ -0,0 +1,760 @@
|
|||||||
|
workspace:
|
||||||
|
packages:
|
||||||
|
csv-stream:
|
||||||
|
path: ./
|
||||||
|
dependencies:
|
||||||
|
- aff
|
||||||
|
- arrays
|
||||||
|
- bifunctors
|
||||||
|
- datetime
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- exceptions
|
||||||
|
- foldable-traversable
|
||||||
|
- foreign
|
||||||
|
- foreign-object
|
||||||
|
- integers
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- node-event-emitter
|
||||||
|
- node-streams
|
||||||
|
- nullable
|
||||||
|
- numbers
|
||||||
|
- precise-datetime
|
||||||
|
- prelude
|
||||||
|
- record
|
||||||
|
- st
|
||||||
|
- strings
|
||||||
|
- tailrec
|
||||||
|
- transformers
|
||||||
|
- typelevel-prelude
|
||||||
|
- unsafe-coerce
|
||||||
|
test_dependencies:
|
||||||
|
- console
|
||||||
|
build_plan:
|
||||||
|
- aff
|
||||||
|
- arraybuffer-types
|
||||||
|
- arrays
|
||||||
|
- bifunctors
|
||||||
|
- console
|
||||||
|
- const
|
||||||
|
- contravariant
|
||||||
|
- control
|
||||||
|
- datetime
|
||||||
|
- decimals
|
||||||
|
- distributive
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- enums
|
||||||
|
- exceptions
|
||||||
|
- exists
|
||||||
|
- fixed-points
|
||||||
|
- foldable-traversable
|
||||||
|
- foreign
|
||||||
|
- foreign-object
|
||||||
|
- formatters
|
||||||
|
- functions
|
||||||
|
- functors
|
||||||
|
- gen
|
||||||
|
- identity
|
||||||
|
- integers
|
||||||
|
- invariant
|
||||||
|
- js-date
|
||||||
|
- lazy
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- node-buffer
|
||||||
|
- node-event-emitter
|
||||||
|
- node-streams
|
||||||
|
- nonempty
|
||||||
|
- now
|
||||||
|
- nullable
|
||||||
|
- numbers
|
||||||
|
- ordered-collections
|
||||||
|
- orders
|
||||||
|
- parallel
|
||||||
|
- parsing
|
||||||
|
- partial
|
||||||
|
- precise-datetime
|
||||||
|
- prelude
|
||||||
|
- profunctor
|
||||||
|
- record
|
||||||
|
- refs
|
||||||
|
- safe-coerce
|
||||||
|
- st
|
||||||
|
- strings
|
||||||
|
- tailrec
|
||||||
|
- transformers
|
||||||
|
- tuples
|
||||||
|
- type-equality
|
||||||
|
- typelevel-prelude
|
||||||
|
- unfoldable
|
||||||
|
- unicode
|
||||||
|
- unsafe-coerce
|
||||||
|
extra_packages: {}
|
||||||
|
packages:
|
||||||
|
aff:
|
||||||
|
type: registry
|
||||||
|
version: 7.1.0
|
||||||
|
integrity: sha256-7hOC6uQO9XBAI5FD8F33ChLjFAiZVfd4BJMqlMh7TNU=
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- bifunctors
|
||||||
|
- control
|
||||||
|
- datetime
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- exceptions
|
||||||
|
- foldable-traversable
|
||||||
|
- functions
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- parallel
|
||||||
|
- prelude
|
||||||
|
- refs
|
||||||
|
- tailrec
|
||||||
|
- transformers
|
||||||
|
- unsafe-coerce
|
||||||
|
arraybuffer-types:
|
||||||
|
type: registry
|
||||||
|
version: 3.0.2
|
||||||
|
integrity: sha256-mQKokysYVkooS4uXbO+yovmV/s8b138Ws3zQvOwIHRA=
|
||||||
|
dependencies: []
|
||||||
|
arrays:
|
||||||
|
type: registry
|
||||||
|
version: 7.3.0
|
||||||
|
integrity: sha256-tmcklBlc/muUtUfr9RapdCPwnlQeB3aSrC4dK85gQlc=
|
||||||
|
dependencies:
|
||||||
|
- bifunctors
|
||||||
|
- control
|
||||||
|
- foldable-traversable
|
||||||
|
- functions
|
||||||
|
- maybe
|
||||||
|
- nonempty
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- safe-coerce
|
||||||
|
- st
|
||||||
|
- tailrec
|
||||||
|
- tuples
|
||||||
|
- unfoldable
|
||||||
|
- unsafe-coerce
|
||||||
|
bifunctors:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-/gZwC9YhNxZNQpnHa5BIYerCGM2jeX9ukZiEvYxm5Nw=
|
||||||
|
dependencies:
|
||||||
|
- const
|
||||||
|
- either
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
- tuples
|
||||||
|
console:
|
||||||
|
type: registry
|
||||||
|
version: 6.1.0
|
||||||
|
integrity: sha256-CxmAzjgyuGDmt9FZW51VhV6rBPwR6o0YeKUzA9rSzcM=
|
||||||
|
dependencies:
|
||||||
|
- effect
|
||||||
|
- prelude
|
||||||
|
const:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-tNrxDW8D8H4jdHE2HiPzpLy08zkzJMmGHdRqt5BQuTc=
|
||||||
|
dependencies:
|
||||||
|
- invariant
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
contravariant:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-TP+ooAp3vvmdjfQsQJSichF5B4BPDHp3wAJoWchip6c=
|
||||||
|
dependencies:
|
||||||
|
- const
|
||||||
|
- either
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
- tuples
|
||||||
|
control:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-sH7Pg9E96JCPF9PIA6oQ8+BjTyO/BH1ZuE/bOcyj4Jk=
|
||||||
|
dependencies:
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
datetime:
|
||||||
|
type: registry
|
||||||
|
version: 6.1.0
|
||||||
|
integrity: sha256-g/5X5BBegQWLpI9IWD+sY6mcaYpzzlW5lz5NBzaMtyI=
|
||||||
|
dependencies:
|
||||||
|
- bifunctors
|
||||||
|
- control
|
||||||
|
- either
|
||||||
|
- enums
|
||||||
|
- foldable-traversable
|
||||||
|
- functions
|
||||||
|
- gen
|
||||||
|
- integers
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- numbers
|
||||||
|
- ordered-collections
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- tuples
|
||||||
|
decimals:
|
||||||
|
type: registry
|
||||||
|
version: 7.1.0
|
||||||
|
integrity: sha256-DriR6lPEfFpjVv7e4JAQkr3ZLf0h17Qg2cAIrhxWV7w=
|
||||||
|
dependencies:
|
||||||
|
- maybe
|
||||||
|
distributive:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-HTDdmEnzigMl+02SJB88j+gAXDx9VKsbvR4MJGDPbOQ=
|
||||||
|
dependencies:
|
||||||
|
- identity
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
- tuples
|
||||||
|
- type-equality
|
||||||
|
effect:
|
||||||
|
type: registry
|
||||||
|
version: 4.0.0
|
||||||
|
integrity: sha256-eBtZu+HZcMa5HilvI6kaDyVX3ji8p0W9MGKy2K4T6+M=
|
||||||
|
dependencies:
|
||||||
|
- prelude
|
||||||
|
either:
|
||||||
|
type: registry
|
||||||
|
version: 6.1.0
|
||||||
|
integrity: sha256-6hgTPisnMWVwQivOu2PKYcH8uqjEOOqDyaDQVUchTpY=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- invariant
|
||||||
|
- maybe
|
||||||
|
- prelude
|
||||||
|
enums:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.1
|
||||||
|
integrity: sha256-HWaD73JFLorc4A6trKIRUeDMdzE+GpkJaEOM1nTNkC8=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- either
|
||||||
|
- gen
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- nonempty
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- tuples
|
||||||
|
- unfoldable
|
||||||
|
exceptions:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-y/xTAEIZIARCE+50/u1di0ncebJ+CIwNOLswyOWzMTw=
|
||||||
|
dependencies:
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- maybe
|
||||||
|
- prelude
|
||||||
|
exists:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-A0JQHpTfo1dNOj9U5/Fd3xndlRSE0g2IQWOGor2yXn8=
|
||||||
|
dependencies:
|
||||||
|
- unsafe-coerce
|
||||||
|
fixed-points:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-hTl5fzeG4mzAOFzEzAeNH7kJvJgYCH7x3v2NdX9pOE4=
|
||||||
|
dependencies:
|
||||||
|
- exists
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
- transformers
|
||||||
|
foldable-traversable:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-fLeqRYM4jUrZD5H4WqcwUgzU7XfYkzO4zhgtNc3jcWM=
|
||||||
|
dependencies:
|
||||||
|
- bifunctors
|
||||||
|
- const
|
||||||
|
- control
|
||||||
|
- either
|
||||||
|
- functors
|
||||||
|
- identity
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- orders
|
||||||
|
- prelude
|
||||||
|
- tuples
|
||||||
|
foreign:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-1ORiqoS3HW+qfwSZAppHPWy4/6AQysxZ2t29jcdUMNA=
|
||||||
|
dependencies:
|
||||||
|
- either
|
||||||
|
- functions
|
||||||
|
- identity
|
||||||
|
- integers
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- prelude
|
||||||
|
- strings
|
||||||
|
- transformers
|
||||||
|
foreign-object:
|
||||||
|
type: registry
|
||||||
|
version: 4.1.0
|
||||||
|
integrity: sha256-q24okj6mT+yGHYQ+ei/pYPj5ih6sTbu7eDv/WU56JVo=
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- foldable-traversable
|
||||||
|
- functions
|
||||||
|
- gen
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- prelude
|
||||||
|
- st
|
||||||
|
- tailrec
|
||||||
|
- tuples
|
||||||
|
- typelevel-prelude
|
||||||
|
- unfoldable
|
||||||
|
formatters:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-5JaC9d2p0xoqJWjWxlHH19R4iJwFTBr4j7SlYcLgicE=
|
||||||
|
dependencies:
|
||||||
|
- datetime
|
||||||
|
- fixed-points
|
||||||
|
- lists
|
||||||
|
- numbers
|
||||||
|
- parsing
|
||||||
|
- prelude
|
||||||
|
- transformers
|
||||||
|
functions:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-adMyJNEnhGde2unHHAP79gPtlNjNqzgLB8arEOn9hLI=
|
||||||
|
dependencies:
|
||||||
|
- prelude
|
||||||
|
functors:
|
||||||
|
type: registry
|
||||||
|
version: 5.0.0
|
||||||
|
integrity: sha256-zfPWWYisbD84MqwpJSZFlvM6v86McM68ob8p9s27ywU=
|
||||||
|
dependencies:
|
||||||
|
- bifunctors
|
||||||
|
- const
|
||||||
|
- contravariant
|
||||||
|
- control
|
||||||
|
- distributive
|
||||||
|
- either
|
||||||
|
- invariant
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
- profunctor
|
||||||
|
- tuples
|
||||||
|
- unsafe-coerce
|
||||||
|
gen:
|
||||||
|
type: registry
|
||||||
|
version: 4.0.0
|
||||||
|
integrity: sha256-f7yzAXWwr+xnaqEOcvyO3ezKdoes8+WXWdXIHDBCAPI=
|
||||||
|
dependencies:
|
||||||
|
- either
|
||||||
|
- foldable-traversable
|
||||||
|
- identity
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- nonempty
|
||||||
|
- prelude
|
||||||
|
- tailrec
|
||||||
|
- tuples
|
||||||
|
- unfoldable
|
||||||
|
identity:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-4wY0XZbAksjY6UAg99WkuKyJlQlWAfTi2ssadH0wVMY=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- invariant
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
integers:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-sf+sK26R1hzwl3NhXR7WAu9zCDjQnfoXwcyGoseX158=
|
||||||
|
dependencies:
|
||||||
|
- maybe
|
||||||
|
- numbers
|
||||||
|
- prelude
|
||||||
|
invariant:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-RGWWyYrz0Hs1KjPDA+87Kia67ZFBhfJ5lMGOMCEFoLo=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- prelude
|
||||||
|
js-date:
|
||||||
|
type: registry
|
||||||
|
version: 8.0.0
|
||||||
|
integrity: sha256-6TVF4DWg5JL+jRAsoMssYw8rgOVALMUHT1CuNZt8NRo=
|
||||||
|
dependencies:
|
||||||
|
- datetime
|
||||||
|
- effect
|
||||||
|
- exceptions
|
||||||
|
- foreign
|
||||||
|
- integers
|
||||||
|
- now
|
||||||
|
lazy:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-lMsfFOnlqfe4KzRRiW8ot5ge6HtcU3Eyh2XkXcP5IgU=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- foldable-traversable
|
||||||
|
- invariant
|
||||||
|
- prelude
|
||||||
|
lists:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-EKF15qYqucuXP2lT/xPxhqy58f0FFT6KHdIB/yBOayI=
|
||||||
|
dependencies:
|
||||||
|
- bifunctors
|
||||||
|
- control
|
||||||
|
- foldable-traversable
|
||||||
|
- lazy
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- nonempty
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- tailrec
|
||||||
|
- tuples
|
||||||
|
- unfoldable
|
||||||
|
maybe:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-5cCIb0wPwbat2PRkQhUeZO0jcAmf8jCt2qE0wbC3v2Q=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- invariant
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
newtype:
|
||||||
|
type: registry
|
||||||
|
version: 5.0.0
|
||||||
|
integrity: sha256-gdrQu8oGe9eZE6L3wOI8ql/igOg+zEGB5ITh2g+uttw=
|
||||||
|
dependencies:
|
||||||
|
- prelude
|
||||||
|
- safe-coerce
|
||||||
|
node-buffer:
|
||||||
|
type: registry
|
||||||
|
version: 9.0.0
|
||||||
|
integrity: sha256-PWE2DJ5ruBLCmeA/fUiuySEFmUJ/VuRfyrnCuVZBlu4=
|
||||||
|
dependencies:
|
||||||
|
- arraybuffer-types
|
||||||
|
- effect
|
||||||
|
- maybe
|
||||||
|
- nullable
|
||||||
|
- st
|
||||||
|
- unsafe-coerce
|
||||||
|
node-event-emitter:
|
||||||
|
type: registry
|
||||||
|
version: 3.0.0
|
||||||
|
integrity: sha256-Qw0MjsT4xRH2j2i4K8JmRjcMKnH5z1Cw39t00q4LE4w=
|
||||||
|
dependencies:
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- functions
|
||||||
|
- maybe
|
||||||
|
- nullable
|
||||||
|
- prelude
|
||||||
|
- unsafe-coerce
|
||||||
|
node-streams:
|
||||||
|
type: registry
|
||||||
|
version: 9.0.0
|
||||||
|
integrity: sha256-2n6dq7YWleTDmD1Kur/ul7Cn08IvWrScgPf+0PgX2TQ=
|
||||||
|
dependencies:
|
||||||
|
- aff
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- exceptions
|
||||||
|
- node-buffer
|
||||||
|
- node-event-emitter
|
||||||
|
- nullable
|
||||||
|
- prelude
|
||||||
|
nonempty:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-54ablJZUHGvvlTJzi3oXyPCuvY6zsrWJuH/dMJ/MFLs=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- foldable-traversable
|
||||||
|
- maybe
|
||||||
|
- prelude
|
||||||
|
- tuples
|
||||||
|
- unfoldable
|
||||||
|
now:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-xZ7x37ZMREfs6GCDw/h+FaKHV/3sPWmtqBZRGTxybQY=
|
||||||
|
dependencies:
|
||||||
|
- datetime
|
||||||
|
- effect
|
||||||
|
nullable:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-yiGBVl3AD+Guy4kNWWeN+zl1gCiJK+oeIFtZtPCw4+o=
|
||||||
|
dependencies:
|
||||||
|
- effect
|
||||||
|
- functions
|
||||||
|
- maybe
|
||||||
|
numbers:
|
||||||
|
type: registry
|
||||||
|
version: 9.0.1
|
||||||
|
integrity: sha256-/9M6aeMDBdB4cwYDeJvLFprAHZ49EbtKQLIJsneXLIk=
|
||||||
|
dependencies:
|
||||||
|
- functions
|
||||||
|
- maybe
|
||||||
|
ordered-collections:
|
||||||
|
type: registry
|
||||||
|
version: 3.2.0
|
||||||
|
integrity: sha256-o9jqsj5rpJmMdoe/zyufWHFjYYFTTsJpgcuCnqCO6PM=
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- foldable-traversable
|
||||||
|
- gen
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- st
|
||||||
|
- tailrec
|
||||||
|
- tuples
|
||||||
|
- unfoldable
|
||||||
|
orders:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-nBA0g3/ai0euH8q9pSbGqk53W2q6agm/dECZTHcoink=
|
||||||
|
dependencies:
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
parallel:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-VJbkGD0rAKX+NUEeBJbYJ78bEKaZbgow+QwQEfPB6ko=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- foldable-traversable
|
||||||
|
- functors
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
- profunctor
|
||||||
|
- refs
|
||||||
|
- transformers
|
||||||
|
parsing:
|
||||||
|
type: registry
|
||||||
|
version: 10.2.0
|
||||||
|
integrity: sha256-ZDIdMFAKkst57x6BVa1aUWJnS8smoZnXsZ339Aq1mPA=
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- control
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- enums
|
||||||
|
- foldable-traversable
|
||||||
|
- functions
|
||||||
|
- identity
|
||||||
|
- integers
|
||||||
|
- lazy
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- nullable
|
||||||
|
- numbers
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- st
|
||||||
|
- strings
|
||||||
|
- tailrec
|
||||||
|
- transformers
|
||||||
|
- tuples
|
||||||
|
- unfoldable
|
||||||
|
- unicode
|
||||||
|
- unsafe-coerce
|
||||||
|
partial:
|
||||||
|
type: registry
|
||||||
|
version: 4.0.0
|
||||||
|
integrity: sha256-fwXerld6Xw1VkReh8yeQsdtLVrjfGiVuC5bA1Wyo/J4=
|
||||||
|
dependencies: []
|
||||||
|
precise-datetime:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-F7tzZ7++Ihtg3xjumzwaHQvGQg61UtEAe5MWeOlTzRY=
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- datetime
|
||||||
|
- decimals
|
||||||
|
- either
|
||||||
|
- enums
|
||||||
|
- foldable-traversable
|
||||||
|
- formatters
|
||||||
|
- integers
|
||||||
|
- js-date
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- numbers
|
||||||
|
- prelude
|
||||||
|
- strings
|
||||||
|
- tuples
|
||||||
|
- unicode
|
||||||
|
prelude:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.1
|
||||||
|
integrity: sha256-o8p6SLYmVPqzXZhQFd2hGAWEwBoXl1swxLG/scpJ0V0=
|
||||||
|
dependencies: []
|
||||||
|
profunctor:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.1
|
||||||
|
integrity: sha256-E58hSYdJvF2Qjf9dnWLPlJKh2Z2fLfFLkQoYi16vsFk=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- distributive
|
||||||
|
- either
|
||||||
|
- exists
|
||||||
|
- invariant
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
- tuples
|
||||||
|
record:
|
||||||
|
type: registry
|
||||||
|
version: 4.0.0
|
||||||
|
integrity: sha256-Za5U85bTRJEfGK5Sk4hM41oXy84YQI0I8TL3WUn1Qzg=
|
||||||
|
dependencies:
|
||||||
|
- functions
|
||||||
|
- prelude
|
||||||
|
- unsafe-coerce
|
||||||
|
refs:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-Vgwne7jIbD3ZMoLNNETLT8Litw6lIYo3MfYNdtYWj9s=
|
||||||
|
dependencies:
|
||||||
|
- effect
|
||||||
|
- prelude
|
||||||
|
safe-coerce:
|
||||||
|
type: registry
|
||||||
|
version: 2.0.0
|
||||||
|
integrity: sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU=
|
||||||
|
dependencies:
|
||||||
|
- unsafe-coerce
|
||||||
|
st:
|
||||||
|
type: registry
|
||||||
|
version: 6.2.0
|
||||||
|
integrity: sha256-z9X0WsOUlPwNx9GlCC+YccCyz8MejC8Wb0C4+9fiBRY=
|
||||||
|
dependencies:
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- tailrec
|
||||||
|
- unsafe-coerce
|
||||||
|
strings:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.1
|
||||||
|
integrity: sha256-WssD3DbX4OPzxSdjvRMX0yvc9+pS7n5gyPv5I2Trb7k=
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- control
|
||||||
|
- either
|
||||||
|
- enums
|
||||||
|
- foldable-traversable
|
||||||
|
- gen
|
||||||
|
- integers
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- nonempty
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- tailrec
|
||||||
|
- tuples
|
||||||
|
- unfoldable
|
||||||
|
- unsafe-coerce
|
||||||
|
tailrec:
|
||||||
|
type: registry
|
||||||
|
version: 6.1.0
|
||||||
|
integrity: sha256-Xx19ECVDRrDWpz9D2GxQHHV89vd61dnXxQm0IcYQHGk=
|
||||||
|
dependencies:
|
||||||
|
- bifunctors
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- identity
|
||||||
|
- maybe
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- refs
|
||||||
|
transformers:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-Pzw40HjthX77tdPAYzjx43LK3X5Bb7ZspYAp27wksFA=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- distributive
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- exceptions
|
||||||
|
- foldable-traversable
|
||||||
|
- identity
|
||||||
|
- lazy
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
- tailrec
|
||||||
|
- tuples
|
||||||
|
- unfoldable
|
||||||
|
tuples:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-1rXgTomes9105BjgXqIw0FL6Fz1lqqUTLWOumhWec1M=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- invariant
|
||||||
|
- prelude
|
||||||
|
type-equality:
|
||||||
|
type: registry
|
||||||
|
version: 4.0.1
|
||||||
|
integrity: sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw=
|
||||||
|
dependencies: []
|
||||||
|
typelevel-prelude:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-uFF2ph+vHcQpfPuPf2a3ukJDFmLhApmkpTMviHIWgJM=
|
||||||
|
dependencies:
|
||||||
|
- prelude
|
||||||
|
- type-equality
|
||||||
|
unfoldable:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-JtikvJdktRap7vr/K4ITlxUX1QexpnqBq0G/InLr6eg=
|
||||||
|
dependencies:
|
||||||
|
- foldable-traversable
|
||||||
|
- maybe
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- tuples
|
||||||
|
unicode:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-QJnTVZpmihEAUiMeYrfkusVoziJWp2hJsgi9bMQLue8=
|
||||||
|
dependencies:
|
||||||
|
- foldable-traversable
|
||||||
|
- maybe
|
||||||
|
- strings
|
||||||
|
unsafe-coerce:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-IqIYW4Vkevn8sI+6aUwRGvd87tVL36BBeOr0cGAE7t0=
|
||||||
|
dependencies: []
|
45
spago.yaml
Normal file
45
spago.yaml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package:
|
||||||
|
name: csv-stream
|
||||||
|
publish:
|
||||||
|
version: '1.0.0'
|
||||||
|
license: 'GPL-3.0-or-later'
|
||||||
|
location:
|
||||||
|
githubOwner: 'cakekindel'
|
||||||
|
githubRepo: 'purescript-csv-stream'
|
||||||
|
build:
|
||||||
|
strict: true
|
||||||
|
pedanticPackages: true
|
||||||
|
dependencies:
|
||||||
|
- aff: ">=7.1.0 <8.0.0"
|
||||||
|
- arrays: ">=7.3.0 <8.0.0"
|
||||||
|
- bifunctors: ">=6.0.0 <7.0.0"
|
||||||
|
- datetime: ">=6.1.0 <7.0.0"
|
||||||
|
- effect: ">=4.0.0 <5.0.0"
|
||||||
|
- either: ">=6.1.0 <7.0.0"
|
||||||
|
- exceptions: ">=6.0.0 <7.0.0"
|
||||||
|
- foldable-traversable: ">=6.0.0 <7.0.0"
|
||||||
|
- foreign: ">=7.0.0 <8.0.0"
|
||||||
|
- foreign-object: ">=4.1.0 <5.0.0"
|
||||||
|
- integers: ">=6.0.0 <7.0.0"
|
||||||
|
- lists: ">=7.0.0 <8.0.0"
|
||||||
|
- maybe: ">=6.0.0 <7.0.0"
|
||||||
|
- newtype: ">=5.0.0 <6.0.0"
|
||||||
|
- node-event-emitter: ">=3.0.0 <4.0.0"
|
||||||
|
- node-streams: ">=9.0.0 <10.0.0"
|
||||||
|
- nullable: ">=6.0.0 <7.0.0"
|
||||||
|
- numbers: ">=9.0.1 <10.0.0"
|
||||||
|
- precise-datetime: ">=7.0.0 <8.0.0"
|
||||||
|
- prelude: ">=6.0.1 <7.0.0"
|
||||||
|
- record: ">=4.0.0 <5.0.0"
|
||||||
|
- st: ">=6.2.0 <7.0.0"
|
||||||
|
- strings: ">=6.0.1 <7.0.0"
|
||||||
|
- tailrec: ">=6.1.0 <7.0.0"
|
||||||
|
- transformers: ">=6.0.0 <7.0.0"
|
||||||
|
- typelevel-prelude: ">=7.0.0 <8.0.0"
|
||||||
|
- unsafe-coerce: ">=6.0.0 <7.0.0"
|
||||||
|
test:
|
||||||
|
main: Test.Main
|
||||||
|
dependencies:
|
||||||
|
- console
|
||||||
|
workspace:
|
||||||
|
extraPackages: {}
|
44
src/Data.CSV.Record.purs
Normal file
44
src/Data.CSV.Record.purs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
module Data.CSV.Record where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Control.Monad.Error.Class (liftMaybe)
|
||||||
|
import Control.Monad.Except (Except)
|
||||||
|
import Data.Array as Array
|
||||||
|
import Data.CSV (class ReadCSV, class WriteCSV, readCSV, writeCSV)
|
||||||
|
import Data.List.NonEmpty (NonEmptyList)
|
||||||
|
import Data.Maybe (fromMaybe)
|
||||||
|
import Data.Symbol (class IsSymbol)
|
||||||
|
import Foreign (ForeignError(..))
|
||||||
|
import Prim.Row (class Cons, class Lacks)
|
||||||
|
import Prim.RowList (class RowToList, Cons, Nil, RowList)
|
||||||
|
import Record as Record
|
||||||
|
import Type.Prelude (Proxy(..))
|
||||||
|
|
||||||
|
class WriteCSVRecord :: Row Type -> RowList Type -> Constraint
|
||||||
|
class RowToList r rl <= WriteCSVRecord r rl | rl -> r where
|
||||||
|
writeCSVRecord :: { | r } -> Array String
|
||||||
|
|
||||||
|
instance (RowToList r (Cons k v tailrl), IsSymbol k, WriteCSV v, Lacks k tail, Cons k v tail r, WriteCSVRecord tail tailrl) => WriteCSVRecord r (Cons k v tailrl) where
|
||||||
|
writeCSVRecord r = let
|
||||||
|
val = writeCSV $ Record.get (Proxy @k) r
|
||||||
|
tail = writeCSVRecord @tail @tailrl $ Record.delete (Proxy @k) r
|
||||||
|
in
|
||||||
|
[val] <> tail
|
||||||
|
|
||||||
|
instance WriteCSVRecord () Nil where
|
||||||
|
writeCSVRecord _ = []
|
||||||
|
|
||||||
|
class ReadCSVRecord :: Row Type -> RowList Type -> Constraint
|
||||||
|
class RowToList r rl <= ReadCSVRecord r rl | rl -> r where
|
||||||
|
readCSVRecord :: Array String -> Except (NonEmptyList ForeignError) { | r }
|
||||||
|
|
||||||
|
instance (RowToList r (Cons k v tailrl), IsSymbol k, ReadCSV v, Lacks k tail, Cons k v tail r, ReadCSVRecord tail tailrl) => ReadCSVRecord r (Cons k v tailrl) where
|
||||||
|
readCSVRecord vals = do
|
||||||
|
valraw <- liftMaybe (pure $ ForeignError "unexpected end of record") $ Array.head vals
|
||||||
|
val <- readCSV @v valraw
|
||||||
|
tail <- readCSVRecord @tail @tailrl (fromMaybe [] $ Array.tail vals)
|
||||||
|
pure $ Record.insert (Proxy @k) val tail
|
||||||
|
|
||||||
|
instance ReadCSVRecord () Nil where
|
||||||
|
readCSVRecord _ = pure {}
|
73
src/Data.CSV.purs
Normal file
73
src/Data.CSV.purs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
module Data.CSV where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Control.Monad.Error.Class (liftMaybe, throwError)
|
||||||
|
import Control.Monad.Except (Except)
|
||||||
|
import Data.DateTime (DateTime)
|
||||||
|
import Data.Int as Int
|
||||||
|
import Data.List.NonEmpty (NonEmptyList)
|
||||||
|
import Data.Maybe (Maybe(..), maybe)
|
||||||
|
import Data.Newtype (unwrap)
|
||||||
|
import Data.Number.Format (toString) as Number
|
||||||
|
import Data.PreciseDateTime (fromDateTime, fromRFC3339String, toDateTimeLossy, toRFC3339String)
|
||||||
|
import Data.RFC3339String (RFC3339String(..))
|
||||||
|
import Data.String as String
|
||||||
|
import Foreign (ForeignError(..), readInt, readNumber, unsafeToForeign)
|
||||||
|
|
||||||
|
class ReadCSV a where
|
||||||
|
readCSV :: String -> Except (NonEmptyList ForeignError) a
|
||||||
|
|
||||||
|
class WriteCSV a where
|
||||||
|
writeCSV :: a -> String
|
||||||
|
|
||||||
|
instance ReadCSV Int where
|
||||||
|
readCSV = readInt <<< unsafeToForeign
|
||||||
|
|
||||||
|
instance ReadCSV Number where
|
||||||
|
readCSV = readNumber <<< unsafeToForeign
|
||||||
|
|
||||||
|
instance ReadCSV String where
|
||||||
|
readCSV = pure
|
||||||
|
|
||||||
|
instance ReadCSV DateTime where
|
||||||
|
readCSV s = map toDateTimeLossy $ liftMaybe (pure $ ForeignError $ "invalid ISO date string: " <> s) $ fromRFC3339String $ RFC3339String s
|
||||||
|
|
||||||
|
instance ReadCSV Boolean where
|
||||||
|
readCSV s =
|
||||||
|
let
|
||||||
|
inner "t" = pure true
|
||||||
|
inner "true" = pure true
|
||||||
|
inner "yes" = pure true
|
||||||
|
inner "y" = pure true
|
||||||
|
inner "1" = pure true
|
||||||
|
inner "f" = pure false
|
||||||
|
inner "false" = pure false
|
||||||
|
inner "no" = pure false
|
||||||
|
inner "n" = pure false
|
||||||
|
inner "0" = pure false
|
||||||
|
inner _ = throwError $ pure $ ForeignError $ "invalid boolean value: " <> s
|
||||||
|
in
|
||||||
|
inner $ String.toLower s
|
||||||
|
|
||||||
|
instance ReadCSV a => ReadCSV (Maybe a) where
|
||||||
|
readCSV "" = pure Nothing
|
||||||
|
readCSV s = Just <$> readCSV s
|
||||||
|
|
||||||
|
instance WriteCSV Int where
|
||||||
|
writeCSV = Int.toStringAs Int.decimal
|
||||||
|
|
||||||
|
instance WriteCSV Number where
|
||||||
|
writeCSV = Number.toString
|
||||||
|
|
||||||
|
instance WriteCSV String where
|
||||||
|
writeCSV = identity
|
||||||
|
|
||||||
|
instance WriteCSV DateTime where
|
||||||
|
writeCSV = unwrap <<< toRFC3339String <<< fromDateTime
|
||||||
|
|
||||||
|
instance WriteCSV Boolean where
|
||||||
|
writeCSV = show
|
||||||
|
|
||||||
|
instance WriteCSV a => WriteCSV (Maybe a) where
|
||||||
|
writeCSV = maybe "" writeCSV
|
7
src/Node.Stream.CSV.Readable.js
Normal file
7
src/Node.Stream.CSV.Readable.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import {parse} from 'csv-parse'
|
||||||
|
|
||||||
|
/** @type {(s: import('csv-parse').Options) => () => import('csv-parse').Parser} */
|
||||||
|
export const makeImpl = c => () => parse(c)
|
||||||
|
|
||||||
|
/** @type {(s: import('stream').Duplex) => () => string[] | null} */
|
||||||
|
export const readImpl = s => () => s.read();
|
121
src/Node.Stream.CSV.Readable.purs
Normal file
121
src/Node.Stream.CSV.Readable.purs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
module Node.Stream.CSV.Readable where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Control.Monad.Error.Class (liftEither)
|
||||||
|
import Control.Monad.Except (runExcept)
|
||||||
|
import Control.Monad.Maybe.Trans (MaybeT(..), runMaybeT)
|
||||||
|
import Control.Monad.Rec.Class (whileJust)
|
||||||
|
import Control.Monad.ST.Global as ST
|
||||||
|
import Data.Array.ST as Array.ST
|
||||||
|
import Data.Bifunctor (lmap)
|
||||||
|
import Data.CSV.Record (class ReadCSVRecord, readCSVRecord)
|
||||||
|
import Data.Either (Either(..))
|
||||||
|
import Data.Maybe (Maybe(..))
|
||||||
|
import Data.Nullable (Nullable)
|
||||||
|
import Data.Nullable as Nullable
|
||||||
|
import Data.Traversable (for_)
|
||||||
|
import Effect (Effect)
|
||||||
|
import Effect.Aff (Aff, makeAff)
|
||||||
|
import Effect.Class (liftEffect)
|
||||||
|
import Effect.Exception (error)
|
||||||
|
import Effect.Uncurried (mkEffectFn1)
|
||||||
|
import Foreign (Foreign, unsafeToForeign)
|
||||||
|
import Foreign.Object (Object)
|
||||||
|
import Foreign.Object as Object
|
||||||
|
import Node.EventEmitter (EventHandle(..))
|
||||||
|
import Node.EventEmitter as Event
|
||||||
|
import Node.EventEmitter.UtilTypes (EventHandle1)
|
||||||
|
import Node.Stream (Read, Stream, Write)
|
||||||
|
import Node.Stream as Stream
|
||||||
|
import Prim.Row (class Union)
|
||||||
|
import Prim.RowList (class RowToList)
|
||||||
|
import Unsafe.Coerce (unsafeCoerce)
|
||||||
|
|
||||||
|
data CSVRead
|
||||||
|
|
||||||
|
-- | Stream transforming chunks of a CSV file
|
||||||
|
-- | into parsed purescript objects.
|
||||||
|
-- |
|
||||||
|
-- | The CSV contents may be piped into this stream
|
||||||
|
-- | as Buffer or String encoded chunks.
|
||||||
|
-- |
|
||||||
|
-- | Records can be read with `read` when `Node.Stream.readable`
|
||||||
|
-- | is true.
|
||||||
|
type CSVParser :: Row Type -> Row Type -> Type
|
||||||
|
type CSVParser a r = Stream (read :: Read, write :: Write, csv :: CSVRead | r)
|
||||||
|
|
||||||
|
-- | https://csv.js.org/parse/options/
|
||||||
|
type Config r =
|
||||||
|
( bom :: Boolean
|
||||||
|
, group_columns_by_name :: Boolean
|
||||||
|
, comment :: String
|
||||||
|
, comment_no_infix :: Boolean
|
||||||
|
, delimiter :: String
|
||||||
|
, encoding :: String
|
||||||
|
, escape :: String
|
||||||
|
, from :: Int
|
||||||
|
, from_line :: Int
|
||||||
|
, ignore_last_delimiters :: Boolean
|
||||||
|
, info :: Boolean
|
||||||
|
, max_record_size :: Int
|
||||||
|
, quote :: String
|
||||||
|
, raw :: Boolean
|
||||||
|
, record_delimiter :: String
|
||||||
|
, relax_column_count :: Boolean
|
||||||
|
, skip_empty_lines :: Boolean
|
||||||
|
, skip_records_with_empty_values :: Boolean
|
||||||
|
, skip_records_with_error :: Boolean
|
||||||
|
, to :: Int
|
||||||
|
, to_line :: Int
|
||||||
|
, trim :: Boolean
|
||||||
|
, ltrim :: Boolean
|
||||||
|
, rtrim :: Boolean
|
||||||
|
| r
|
||||||
|
)
|
||||||
|
|
||||||
|
make :: forall @r rl config missing extra. ReadCSVRecord r rl => Union config missing (Config extra) => { | config } -> Effect (CSVParser r ())
|
||||||
|
make = makeImpl <<< unsafeToForeign <<< Object.union (recordToForeign {columns: true, cast: false, cast_date: false}) <<< recordToForeign
|
||||||
|
|
||||||
|
-- | Reads a parsed record from the stream.
|
||||||
|
-- |
|
||||||
|
-- | Returns `Nothing` when either:
|
||||||
|
-- | - The internal buffer of parsed records has been exhausted, but there will be more (`Node.Stream.readable` and `Node.Stream.closed` are both `false`)
|
||||||
|
-- | - All records have been processed (`Node.Stream.closed` is `true`)
|
||||||
|
read :: forall @r rl a. RowToList r rl => ReadCSVRecord r rl => CSVParser r a -> Effect (Maybe { | r })
|
||||||
|
read stream = runMaybeT do
|
||||||
|
raw :: Array String <- MaybeT $ Nullable.toMaybe <$> readImpl stream
|
||||||
|
liftEither $ lmap (error <<< show) $ runExcept $ readCSVRecord @r @rl raw
|
||||||
|
|
||||||
|
-- | Collect all parsed records into an array
|
||||||
|
readAll :: forall @r rl a. RowToList r rl => ReadCSVRecord r rl => CSVParser r a -> Aff (Array { | r })
|
||||||
|
readAll stream = do
|
||||||
|
records <- liftEffect $ ST.toEffect $ Array.ST.new
|
||||||
|
|
||||||
|
whileJust do
|
||||||
|
isReadable <- liftEffect $ Stream.readable stream
|
||||||
|
when (not isReadable) $ makeAff \res -> mempty <* flip (Event.once Stream.readableH) stream $ res $ Right unit
|
||||||
|
liftEffect $ whileJust do
|
||||||
|
r <- read @r stream
|
||||||
|
for_ r \r' -> ST.toEffect $ Array.ST.push r' records
|
||||||
|
pure $ void r
|
||||||
|
|
||||||
|
isClosed <- liftEffect $ Stream.closed stream
|
||||||
|
pure $ if isClosed then Nothing else Just unit
|
||||||
|
|
||||||
|
liftEffect $ ST.toEffect $ Array.ST.unsafeFreeze records
|
||||||
|
|
||||||
|
-- | `data` event. Emitted when a CSV record has been parsed.
|
||||||
|
dataH :: forall r a. EventHandle1 (CSVParser r a) { | r }
|
||||||
|
dataH = EventHandle "data" mkEffectFn1
|
||||||
|
|
||||||
|
-- | FFI
|
||||||
|
foreign import makeImpl :: forall r. Foreign -> Effect (Stream r)
|
||||||
|
|
||||||
|
-- | FFI
|
||||||
|
foreign import readImpl :: forall r. Stream r -> Effect (Nullable (Array String))
|
||||||
|
|
||||||
|
-- | FFI
|
||||||
|
recordToForeign :: forall r. Record r -> Object Foreign
|
||||||
|
recordToForeign = unsafeCoerce
|
||||||
|
|
7
src/Node.Stream.CSV.Writable.js
Normal file
7
src/Node.Stream.CSV.Writable.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import {stringify} from 'csv-stringify'
|
||||||
|
|
||||||
|
/** @type {(c: import('csv-stringify').Options) => () => import('csv-stringify').Stringifier} */
|
||||||
|
export const makeImpl = c => () => stringify(c)
|
||||||
|
|
||||||
|
/** @type {(s: import('csv-stringify').Stringifier) => (vals: Array<string>) => () => void} */
|
||||||
|
export const writeImpl = s => vals => () => s.write(vals)
|
60
src/Node.Stream.CSV.Writable.purs
Normal file
60
src/Node.Stream.CSV.Writable.purs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
module Node.Stream.CSV.Writable where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Data.CSV.Record (class WriteCSVRecord, writeCSVRecord)
|
||||||
|
import Data.String.Regex (Regex)
|
||||||
|
import Effect (Effect)
|
||||||
|
import Foreign (Foreign, unsafeToForeign)
|
||||||
|
import Foreign.Object (Object)
|
||||||
|
import Foreign.Object as Object
|
||||||
|
import Node.Stream (Read, Stream, Write)
|
||||||
|
import Prim.Row (class Union)
|
||||||
|
import Unsafe.Coerce (unsafeCoerce)
|
||||||
|
|
||||||
|
data CSVWrite
|
||||||
|
|
||||||
|
-- | Stream transforming rows of stringified CSV values
|
||||||
|
-- | to CSV-formatted rows.
|
||||||
|
-- |
|
||||||
|
-- | Write rows to the stream using `write`.
|
||||||
|
-- |
|
||||||
|
-- | Stringified rows are emitted on the `Readable` end as string
|
||||||
|
-- | chunks, meaning it can be treated as a `Node.Stream.Readable`
|
||||||
|
-- | that has had `setEncoding UTF8` invoked on it.
|
||||||
|
type CSVStringifier :: Row Type -> Row Type -> Type
|
||||||
|
type CSVStringifier a r = Stream (read :: Read, write :: Write, csv :: CSVWrite | r)
|
||||||
|
|
||||||
|
-- | https://csv.js.org/stringify/options/
|
||||||
|
type Config r =
|
||||||
|
( bom :: Boolean
|
||||||
|
, group_columns_by_name :: Boolean
|
||||||
|
, delimiter :: String
|
||||||
|
, record_delimiter :: String
|
||||||
|
, escape :: String
|
||||||
|
, escape_formulas :: Boolean
|
||||||
|
, header :: Boolean
|
||||||
|
, quote :: String
|
||||||
|
, quoted :: Boolean
|
||||||
|
, quoted_empty :: Boolean
|
||||||
|
, quoted_match :: Regex
|
||||||
|
, quoted_string :: Boolean
|
||||||
|
| r
|
||||||
|
)
|
||||||
|
|
||||||
|
foreign import makeImpl :: forall r. Foreign -> Effect (Stream r)
|
||||||
|
foreign import writeImpl :: forall r. Stream r -> Array String -> Effect Unit
|
||||||
|
|
||||||
|
recordToForeign :: forall r. Record r -> Object Foreign
|
||||||
|
recordToForeign = unsafeCoerce
|
||||||
|
|
||||||
|
-- | Create a CSVStringifier
|
||||||
|
make :: forall @r rl config missing extra. WriteCSVRecord r rl => Union config missing (Config extra) => { | config } -> Effect (CSVStringifier r ())
|
||||||
|
make = makeImpl <<< unsafeToForeign <<< Object.union (recordToForeign {columns: true, cast: false, cast_date: false}) <<< recordToForeign
|
||||||
|
|
||||||
|
-- | Write a record to a CSVStringifier.
|
||||||
|
-- |
|
||||||
|
-- | The record will be emitted on the `Readable` end
|
||||||
|
-- | of the stream as a string chunk.
|
||||||
|
write :: forall @r rl a. WriteCSVRecord r rl => CSVStringifier r a -> { | r } -> Effect Unit
|
||||||
|
write s = writeImpl s <<< writeCSVRecord @r @rl
|
2
src/Node.Stream.CSV.purs
Normal file
2
src/Node.Stream.CSV.purs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
module Node.Stream.CSV where
|
||||||
|
|
12
test/Test/Main.purs
Normal file
12
test/Test/Main.purs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module Test.Main where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Effect (Effect)
|
||||||
|
import Effect.Class.Console (log)
|
||||||
|
|
||||||
|
main :: Effect Unit
|
||||||
|
main = do
|
||||||
|
log "🍕"
|
||||||
|
log "You should add some tests."
|
||||||
|
|
Loading…
Reference in New Issue
Block a user