git.iko.soy/rowtype-yoga/purescript-yoga-json
on main help sign in
21 files changed+2319−191
since splitsnapshots
unifiedsplit
.github/workflows/ci.yml+5−3 .gitignore+4−1 CHANGELOG.md+34 README.md+129−37 bower.json−47 docs/simple-json-migration.md+47 package-lock.json+17−12 package.json+4−7 packages.dhall−5 spago.dhall−37 spago.lock+1747 spago.yaml+52 src/Yoga/JSON.js+1 src/Yoga/JSON.purs+115−16 src/Yoga/JSON/Derive.purs+13 src/Yoga/JSON/Error.purs+7 test.dhall−15 test/BasicsSpec.purs+98−8 test/GenericsSpec.purs+1−1 test/Main.purs+3−2 test/WriteViaSpec.purs+42
.github/workflows/ci.yml+5−3
@@ -13,13 +13,15 @@ jobs:
1313 - uses: actions/checkout@v2
1414
1515 - uses: purescript-contrib/setup-purescript@main
16+ with:
17+ spago: "unstable"
1618
1719 - uses: actions/setup-node@v2
1820 with:
19− node-version: "14"
21+ node-version: "20"
2022
2123 - name: Cache PureScript dependencies
22− uses: actions/cache@v2
24+ uses: actions/cache@v4
2325 # This cache uses the .dhall files to know when it should reinstall
2426 # and rebuild packages. It caches both the installed packages from
2527 # the `.spago` directory and compilation artifacts from the `output`
@@ -27,7 +29,7 @@ jobs:
2729 # have changed. If you do not want to cache compiled output, remove
2830 # the `output` path.
2931 with:
30− key: ${{ runner.os }}-spago-${{ hashFiles('**/*.dhall') }}
32+ key: ${{ runner.os }}-spago-${{ hashFiles('**/*.yaml') }}
3133 path: |
3234 .spago
3335 output
.gitignore+4−1
@@ -7,4 +7,7 @@
77/.psa*
88/.spago/
99/.nyc_output/
10−/coverage/
10+/coverage/
11+/.idea/
12+.spec-results
13+.DS_Store
CHANGELOG.mdnew file+34
@@ -0,0 +1,34 @@
1+# Changelog
2+
3+## v5.2.2
4+
5+- Fix variant decoding selecting absent branches whose payload decoders accept missing values, such as empty records and `Maybe`. Branches now require an own property matching their label.
6+
7+## v4.0.1
8+
9+- Allow the type of `read*` functions to be visibly applied (#24 by @postsolar)
10+
11+## v4.0.0
12+- Replace `bigints` dependency with `js-bigints` so that no more external npm dependency is needed (#11 by @sigma-andex)
13+
14+## v3.0.2
15+- Minor internal updates
16+- Improve error handling
17+- Add codecs and `JSDate` (@i-am-the-slime)
18+
19+## v3.0.1
20+- Readme update
21+
22+## v3.0.0
23+- Add codecs for enums and more instances (#9 by @i-am-the-slime)
24+- Add codecs for `Map` and `Map` with newtype (#4 by @i-am-the-slime)
25+
26+## v2.0.0
27+- Add support for `BigInt` (#5 by @sigma-andex)
28+- Improve Generics (#3 by @i-am-the-slime)
29+
30+## v1.0.1
31+- Add Generics (#2 by @i-am-the-slime)
32+
33+## v1.0.0
34+- Initial commit
README.md+129−37
@@ -1,70 +1,162 @@
11# purescript-yoga-json
22
3−**Note**: This is a fork of [simple-json](https://github.com/justinwoo/purescript-simple-json) ([MIT Licence](./LICENSE/simple-json.LICENSE)).
3+`yoga-json` is a light-weight and simple json library for purescript.
44
5+**Note**: This library was initially forked from the amazing [simple-json](https://github.com/justinwoo/purescript-simple-json) ([MIT Licence](./LICENSE/simple-json.LICENSE)).
6+Replace your imports from `Simple.JSON` to `Yoga.JSON` to migrate.
57## Table of Contents
8+* [features](#features)
9+* [installation](#installation)
610* [usage](#usage)
7−* [migrate from `simple-json`](#migrate-from-purescript-simple-json)
11+
12+## Features
13+
14+* 😌 simple and easy to use json codecs
15+* 🪶 light-weight
16+* 🤖 built-in support for many common types (`Sum` types, Tuples, BigInts, Maps, JSDate, DateTime, Eithers, NonEmptyStrings )
17+* 🖍 human-friendly error reporting
18+
19+## Installation
20+
21+```
22+spago install yoga-json
23+```
824
925## Usage
1026
27+`purescript-yoga-json` basically provides two functions `writeJSON` and `readJSON`.
28+
29+Use `writeJSON` to serialise a type to a JSON string:
30+
1131```purescript
1232import Yoga.JSON as JSON
1333
1434serialised :: String
1535serialised =
1636 JSON.writeJSON { first_name: "Lola", last_name: "Flores" }
37+ -- {"last_name":"Flores","first_name":"Lola"}
38+```
39+
40+Use `readJSON` to deserialise a JSON string:
41+```purescript
42+import Yoga.JSON as JSON
43+
44+deserialised :: Either MultipleErrors { first_name :: String, last_name :: String }
45+deserialised = JSON.readJSON """{ "first_name": "Lola", "last_name": "Flores" }"""
46+-- Right { first_name: "Lola", last_name: "Flores" }
47+```
48+
49+As the parsing can fail, `readJSON` returns an `Either`, potentially containing a `Left` data constructor with `MultipleErrors`. If you don't care about the specific errors, you can use `readJSON_`, which returns a `Maybe`:
50+
51+```purescript
52+deserialised :: Maybe { first_name :: String, last_name :: String }
53+deserialised = JSON.readJSON_ """{ "first_name": "Lola", "last_name": "Flores" }"""
54+-- Just { first_name: "Lola", last_name: "Flores" }
55+```
56+
57+
58+## Sum types
59+
60+`purescript-yoga-json` provides utility functions to easily generate serialisers and deserialisers for your sum types.
61+
62+Let's start with a simple example of a sum type where our data constructors do not contain any further values:
63+
1764```
65+import Data.Either (Either)
66+import Data.Generic.Rep (class Generic)
67+import Yoga.JSON as JSON
68+import Yoga.JSON.Generics (genericReadForeignEnum, genericWriteForeignEnum)
69+import Yoga.JSON.Generics.EnumSumRep as Enum
1870
19−Check out the tests for how to encode/decode increasingly complex types.
71+data MyEnum = Enum1 | Enum2 | Enum3
72+```
2073
21−## Migrate from `purescript-simple-json`
74+Now, we need to derive a `Generic` instance for it:
2275
23−`purescript-yoga-json` is almost (read below if you use variants) a drop-in replacement for `purescript-simple-json`. Just change the imports from `Simple.JSON` to `Yoga.JSON`.
76+```
77+derive instance Generic MyEnum _
78+-- and optionally a Show instance
79+instance Show MyEnum where
80+ show = genericShow
81+```
2482
25−## Additions over `simple-json`
83+Next, we define a `WriteForeign` instance and implement the `writeImpl` function using `genericWriteForeignEnum Enum.defaultOptions`.
2684
27−### Errors
28−yoga-json will actually report multiple errors at once in the case of records, objects, and arrays.
29−There's also a way to make errors more readable with `renderHumanError`:
30−(e.g. `Must provide a value of type 'Int' instead of 'Object' at $.a.b.c.d[1]`)
85+```purescript
86+instance WriteForeign MyEnum
87+ where
88+ writeImpl = genericWriteForeignEnum Enum.defaultOptions
89+```
3190
91+Similarly, we implement the `ReadForeign` instance using `genericReadForeignEnum Enum.defaultOptions`
92+```purescript
93+instance ReadForeign MyEnum
94+ where
95+ readImpl = genericReadForeignEnum Enum.defaultOptions
96+```
3297
33−### Tuples
34−There is an inbuilt codec for `Tuple`s thanks to @ursi
35−`yoga-json` represents tuples as arrays in JSON.
98+That's all, we can now serialise our data type:
99+```purescript
100+serialised = writeJSON { "myEnum": Enum3 }
101+-- {"myEnum":"Enum3"}
102+```
103+and deserialise it:
104+```purescript
105+deserialised :: E { "myEnum" :: MyEnum }
106+deserialised = readJSON serialised
107+-- Right { myEnum: Enum3 }
108+```
36109
37−### Eithers
38−There is an inbuilt codec for `Either`s.
39−`yoga-json` represents eithers as objects with a `type` and a `value` tag in JSON.
110+### Writing custom codecs
40111
41−### JSDate and DateTime
42−Both are encoded as ISO8601 strings as spat out by `JSDate.toISOString`.
112+In order to write your own, custom codecs you will need to provide instances for `WriteForeign` and `ReadForeign`.
43113
44−### Generics
45−It includes @justinwoo's codecs for en- and decoding generics inspired by
46−[simple-json-generics](https://github.com/justinwoo/purescript-simple-json-generics)
114+Let's see an example. We define a simple data type `TrafficLight` that has three data constructors `Red`, `Yellow` and `Green`:
115+```purescript
116+data TrafficLight = Red | Yellow | Green
117+```
118+We would like to serialise these constructors as lower case strings `"red"`, `"yellow"` and `"green"`.
47119
48−It is possible to customise the representation of enums, tagged sum types, and untagged sum types via options.
120+First we need to provide an implementation for the `WriteForeign` type class, that tells `yoga-json` how to serialise the type. We pattern match on the three different data constructors and write them as the three `String`s red, yellow and green, using the same `writeImpl` function:
121+```purescript
122+instance WriteForeign TrafficLight where
123+ writeImpl Red = writeImpl "red"
124+ writeImpl Yellow = writeImpl "yellow"
125+ writeImpl Green = writeImpl "green"
126+```
127+This works, because `yoga-json` already knows how to serialise a `String`.
49128
50−### BigInts
51−It can *read* bigints (if you install `big-integer` as a JS dependency).
129+Similarly, we need to provide an implementation for the `ReadForeign` type class, that tells `yoga-json` how to deserialise the type. We start by deserialising into a primitive type, typically a String or an Object, and then convert it to our desired Purescript type.
52130
53−### 💣 Cannot write bigints as bigints but only strings
54−It seems that there is no way to write bigints in JavaScript except for writing your own `JSON.stringify`.
131+Since we don't know the input `String`, it might contain invalid data and therefore deserialisation might fail. `yoga-json` uses the `ExceptT` monad to reflect this. We can return valid values using `pure` and `fail` on invalid values:
55132
56−## Differences to `simple-json`
133+```purescript
134+instance ReadForeign TrafficLight where
135+ readImpl json = do
136+ -- deserialise into a string
137+ str :: String <- readImpl json
138+ -- now we pattern match on our valid types
139+ case str of
140+ "red" -> pure Red
141+ "yellow" -> pure Yellow
142+ "green" -> pure Green
143+ -- and fail if we get an invalid type
144+ other -> fail $ ForeignError $ "Failed to parse " <> other <> " as TrafficLight"
145+```
57146
58−### 💣 Variant codec
59−If you want to emulate `simple-json`'s format you may use the newtype `TaggedVariant`
147+Now we can serialise our data type:
148+```purescript
149+serialised = writeJSON { "trafficLight": Red }
150+-- {"trafficLight":"red"}
151+```
60152
153+and deserialise it:
61154```purescript
62−type YourVariantRow = ( a :: Int, b :: String )
63−type YourVariant = Variant YourVariantRow
64−x :: YourVariant
65−x = inj (Proxy :: Proxy "a") 5
66−-- encoded = writeJSON x
67−-- ^ Let's say you had this before
68−-- You can now do:
69−encoded = writeJSON (TaggedVariant "type" "value" x)
155+deserialised :: E { "trafficLight" :: TrafficLight }
156+deserialised = readJSON """{ "trafficLight": "green" }"""
157+-- Right { trafficLight: Green }
158+
159+deserialisedUnknown :: E { "trafficLight" :: TrafficLight }
160+deserialisedUnknown = readJSON """{ "trafficLight": "purple" }"""
161+-- Left (NonEmptyList (NonEmpty (ErrorAtProperty "trafficLight" (ForeignError "Failed to parse purple as TrafficLight")) Nil))
70162```
bower.jsondeleted−47
@@ -1,47 +0,0 @@
1−{
2− "name": "purescript-yoga-json",
3− "license": [
4− "MIT"
5− ],
6− "repository": {
7− "type": "git",
8− "url": "https://github.com/rowtype-yoga/purescript-yoga-json.git"
9− },
10− "ignore": [
11− "**/.*",
12− "node_modules",
13− "bower_components",
14− "output"
15− ],
16− "dependencies": {
17− "purescript-arrays": "^v7.0.0",
18− "purescript-bifunctors": "^v6.0.0",
19− "purescript-bigints": "^v7.0.1",
20− "purescript-console": "^v6.0.0",
21− "purescript-control": "^v6.0.0",
22− "purescript-datetime": "^v6.0.0",
23− "purescript-effect": "^v4.0.0",
24− "purescript-either": "^v6.1.0",
25− "purescript-exceptions": "^v6.0.0",
26− "purescript-foldable-traversable": "^v6.0.0",
27− "purescript-foreign": "^v7.0.0",
28− "purescript-foreign-object": "^v4.0.0",
29− "purescript-identity": "^v6.0.0",
30− "purescript-integers": "^v6.0.0",
31− "purescript-js-date": "^v8.0.0",
32− "purescript-lists": "^v7.0.0",
33− "purescript-maybe": "^v6.0.0",
34− "purescript-newtype": "^v5.0.0",
35− "purescript-nullable": "^v6.0.0",
36− "purescript-numbers": "^v9.0.0",
37− "purescript-ordered-collections": "^v3.0.0",
38− "purescript-partial": "^v4.0.0",
39− "purescript-prelude": "^v6.0.0",
40− "purescript-record": "^v4.0.0",
41− "purescript-transformers": "^v6.0.0",
42− "purescript-tuples": "^v7.0.0",
43− "purescript-typelevel-prelude": "^v7.0.0",
44− "purescript-unsafe-coerce": "^v6.0.0",
45− "purescript-variant": "^v8.0.0"
46− }
47−}
docs/simple-json-migration.mdnew file+47
@@ -0,0 +1,47 @@
1+# Migrate from `purescript-simple-json`
2+
3+`purescript-yoga-json` is a fork of [simple-json](https://github.com/justinwoo/purescript-simple-json) ([MIT Licence](./LICENSE/simple-json.LICENSE)) and almost (read below if you use variants) a drop-in replacement for `purescript-simple-json`. Just change the imports from `Simple.JSON` to `Yoga.JSON`.
4+
5+## Additions over `simple-json`
6+
7+### Errors
8+yoga-json will actually report multiple errors at once in the case of records, objects, and arrays.
9+There's also a way to make errors more readable with `renderHumanError`:
10+(e.g. `Must provide a value of type 'Int' instead of 'Object' at $.a.b.c.d[1]`)
11+
12+
13+### Tuples
14+There is an inbuilt codec for `Tuple`s thanks to @ursi
15+`yoga-json` represents tuples as arrays in JSON.
16+
17+### Eithers
18+There is an inbuilt codec for `Either`s.
19+`yoga-json` represents eithers as objects with a `type` and a `value` tag in JSON.
20+
21+### JSDate and DateTime
22+Both are encoded as ISO8601 strings as spat out by `JSDate.toISOString`.
23+
24+### Generics
25+It includes @justinwoo's codecs for en- and decoding generics inspired by
26+[simple-json-generics](https://github.com/justinwoo/purescript-simple-json-generics)
27+
28+It is possible to customise the representation of enums, tagged sum types, and untagged sum types via options.
29+
30+### BigInts
31+There is an inbuilt codec for `BigInt`. Writing a `BigInt` however will result in a String. This is a current limitation of JavaScript and the only way around it - it seems - is writing your own JSON.stringify method (which is out of scope of this project).
32+
33+## Differences to `simple-json`
34+
35+### 💣 Variant codec
36+If you want to emulate `simple-json`'s format you may use the newtype `TaggedVariant`
37+
38+```purescript
39+type YourVariantRow = ( a :: Int, b :: String )
40+type YourVariant = Variant YourVariantRow
41+x :: YourVariant
42+x = inj (Proxy :: Proxy "a") 5
43+-- encoded = writeJSON x
44+-- ^ Let's say you had this before
45+-- You can now do:
46+encoded = writeJSON (TaggedVariant "type" "value" x)
47+```
package-lock.json+17−12
@@ -4,6 +4,7 @@
44 "requires": true,
55 "packages": {
66 "": {
7+ "name": "purescript-yoga-json",
78 "devDependencies": {
89 "c8": "^7.12.0",
910 "rimraf": "^3.0.2"
@@ -163,10 +164,11 @@
163164 "dev": true
164165 },
165166 "node_modules/cross-spawn": {
166− "version": "7.0.3",
167− "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
168− "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
167+ "version": "7.0.6",
168+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
169+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
169170 "dev": true,
171+ "license": "MIT",
170172 "dependencies": {
171173 "path-key": "^3.1.0",
172174 "shebang-command": "^2.0.0",
@@ -458,7 +460,9 @@
458460 "version": "3.0.2",
459461 "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
460462 "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
463+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
461464 "dev": true,
465+ "license": "ISC",
462466 "dependencies": {
463467 "glob": "^7.1.3"
464468 },
@@ -470,10 +474,11 @@
470474 }
471475 },
472476 "node_modules/semver": {
473− "version": "6.3.0",
474− "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
475− "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
477+ "version": "6.3.1",
478+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
479+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
476480 "dev": true,
481+ "license": "ISC",
477482 "bin": {
478483 "semver": "bin/semver.js"
479484 }
@@ -789,9 +794,9 @@
789794 "dev": true
790795 },
791796 "cross-spawn": {
792− "version": "7.0.3",
793− "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
794− "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
797+ "version": "7.0.6",
798+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
799+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
795800 "dev": true,
796801 "requires": {
797802 "path-key": "^3.1.0",
@@ -1012,9 +1017,9 @@
10121017 }
10131018 },
10141019 "semver": {
1015− "version": "6.3.0",
1016− "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
1017− "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
1020+ "version": "6.3.1",
1021+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
1022+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
10181023 "dev": true
10191024 },
10201025 "shebang-command": {
package.json+4−7
@@ -1,14 +1,11 @@
11{
22 "scripts": {
3− "test": "spago -x test.dhall test --purs-args '-g sourcemaps'",
4− "precoverage": "rimraf output && npm run test",
5− "coverage": "c8 --100 npm run test"
6− },
7− "dependencies": {
3+ "test": "spago test",
4+ "precoverage": "npm run test",
5+ "coverage": "c8 --lines=99 --branches=75 --statements=99 npm run test"
86 },
97 "type": "module",
108 "devDependencies": {
11− "c8": "^7.12.0",
12− "rimraf": "^3.0.2"
9+ "c8": "^7.12.0"
1310 }
1411}
packages.dhalldeleted−5
@@ -1,5 +0,0 @@
1−let upstream =
2− https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20221017/packages.dhall
3− sha256:88a9c22385f181da79caa7922502558b37a5fb759d45b45e904b105b8f88f6eb
4−
5−in upstream
spago.dhalldeleted−37
@@ -1,37 +0,0 @@
1−{ name = "yoga-json"
2−, license = "MIT"
3−, repository = "https://github.com/rowtype-yoga/purescript-yoga-json.git"
4−, dependencies =
5− [ "arrays"
6− , "bifunctors"
7− , "js-bigints"
8− , "console"
9− , "control"
10− , "datetime"
11− , "effect"
12− , "either"
13− , "exceptions"
14− , "foldable-traversable"
15− , "foreign"
16− , "foreign-object"
17− , "identity"
18− , "integers"
19− , "js-date"
20− , "lists"
21− , "maybe"
22− , "newtype"
23− , "nullable"
24− , "numbers"
25− , "ordered-collections"
26− , "partial"
27− , "prelude"
28− , "record"
29− , "transformers"
30− , "tuples"
31− , "typelevel-prelude"
32− , "unsafe-coerce"
33− , "variant"
34− ]
35−, packages = ./packages.dhall
36−, sources = [ "src/**/*.purs" ]
37−}
spago.locknew file+1747
@@ -0,0 +1,1747 @@
1+{
2+ "workspace": {
3+ "packages": {
4+ "yoga-json": {
5+ "path": "./",
6+ "core": {
7+ "dependencies": [
8+ {
9+ "arrays": ">=7.3.0 <8.0.0"
10+ },
11+ {
12+ "bifunctors": ">=6.0.0 <7.0.0"
13+ },
14+ {
15+ "control": ">=6.0.0 <7.0.0"
16+ },
17+ {
18+ "datetime": ">=6.1.0 <7.0.0"
19+ },
20+ {
21+ "effect": ">=4.0.0 <5.0.0"
22+ },
23+ {
24+ "either": ">=6.1.0 <7.0.0"
25+ },
26+ {
27+ "exceptions": ">=6.1.0 <7.0.0"
28+ },
29+ {
30+ "foldable-traversable": ">=6.0.0 <7.0.0"
31+ },
32+ {
33+ "foreign": ">=7.0.0 <8.0.0"
34+ },
35+ {
36+ "foreign-object": ">=4.1.0 <5.0.0"
37+ },
38+ {
39+ "free": ">=7.1.0 <8.0.0"
40+ },
41+ {
42+ "identity": ">=6.0.0 <7.0.0"
43+ },
44+ {
45+ "integers": ">=6.0.0 <7.0.0"
46+ },
47+ {
48+ "js-bigints": ">=2.2.1 <3.0.0"
49+ },
50+ {
51+ "js-date": ">=8.0.0 <9.0.0"
52+ },
53+ {
54+ "lists": ">=7.0.0 <8.0.0"
55+ },
56+ {
57+ "maybe": ">=6.0.0 <7.0.0"
58+ },
59+ {
60+ "newtype": ">=5.0.0 <6.0.0"
61+ },
62+ {
63+ "nullable": ">=6.0.0 <7.0.0"
64+ },
65+ {
66+ "numbers": ">=9.0.1 <10.0.0"
67+ },
68+ {
69+ "ordered-collections": ">=3.2.0 <4.0.0"
70+ },
71+ {
72+ "partial": ">=4.0.0 <5.0.0"
73+ },
74+ {
75+ "prelude": ">=6.0.2 <7.0.0"
76+ },
77+ {
78+ "record": ">=4.0.0 <5.0.0"
79+ },
80+ {
81+ "safe-coerce": ">=2.0.0 <3.0.0"
82+ },
83+ {
84+ "strings": ">=6.0.1 <7.0.0"
85+ },
86+ {
87+ "transformers": ">=6.1.0 <7.0.0"
88+ },
89+ {
90+ "tuples": ">=7.0.0 <8.0.0"
91+ },
92+ {
93+ "typelevel-prelude": ">=7.0.0 <8.0.0"
94+ },
95+ {
96+ "unsafe-coerce": ">=6.0.0 <7.0.0"
97+ },
98+ {
99+ "variant": ">=8.0.0 <9.0.0"
100+ },
101+ {
102+ "yoga-tree": ">=1.0.0 <2.0.0"
103+ }
104+ ]
105+ },
106+ "test": {
107+ "dependencies": [
108+ "spec",
109+ "spec-discovery",
110+ "spec-node",
111+ "strings-extra"
112+ ]
113+ }
114+ }
115+ },
116+ "package_set": {
117+ "address": {
118+ "registry": "63.2.1"
119+ },
120+ "compiler": ">=0.15.15 <0.16.0",
121+ "content": {
122+ "abc-parser": "2.0.1",
123+ "ace": "9.1.0",
124+ "address-rfc2821": "0.1.1",
125+ "aff": "8.0.0",
126+ "aff-bus": "6.0.0",
127+ "aff-coroutines": "9.0.0",
128+ "aff-promise": "4.0.0",
129+ "aff-retry": "2.0.0",
130+ "affjax": "13.0.0",
131+ "affjax-node": "1.0.0",
132+ "affjax-web": "1.0.0",
133+ "ansi": "7.0.0",
134+ "apexcharts": "0.5.0",
135+ "applicative-phases": "1.0.0",
136+ "argonaut": "9.0.0",
137+ "argonaut-aeson-generic": "0.4.1",
138+ "argonaut-codecs": "9.1.0",
139+ "argonaut-core": "7.0.0",
140+ "argonaut-generic": "8.0.0",
141+ "argonaut-traversals": "10.0.0",
142+ "argparse-basic": "2.0.0",
143+ "array-builder": "0.1.2",
144+ "array-search": "0.6.0",
145+ "arraybuffer": "13.2.0",
146+ "arraybuffer-builder": "3.1.0",
147+ "arraybuffer-types": "3.0.2",
148+ "arrays": "7.3.0",
149+ "arrays-extra": "0.6.1",
150+ "arrays-zipper": "2.0.1",
151+ "ask": "1.0.0",
152+ "assert": "6.0.0",
153+ "assert-multiple": "0.4.0",
154+ "avar": "5.0.1",
155+ "b64": "0.0.8",
156+ "barbies": "1.0.1",
157+ "barlow-lens": "0.9.0",
158+ "bifunctors": "6.0.0",
159+ "bigints": "7.0.1",
160+ "bolson": "0.3.9",
161+ "bookhound": "0.1.7",
162+ "bower-json": "3.0.0",
163+ "call-by-name": "4.0.1",
164+ "canvas": "6.0.0",
165+ "canvas-action": "9.0.0",
166+ "cartesian": "1.0.6",
167+ "catenable-lists": "7.0.0",
168+ "cbor-stream": "1.3.0",
169+ "chameleon": "1.0.0",
170+ "chameleon-halogen": "1.0.3",
171+ "chameleon-react-basic": "1.1.0",
172+ "chameleon-styled": "2.5.0",
173+ "chameleon-transformers": "1.0.0",
174+ "channel": "1.0.0",
175+ "checked-exceptions": "3.1.1",
176+ "choku": "1.0.2",
177+ "classless": "0.1.1",
178+ "classless-arbitrary": "0.1.1",
179+ "classless-decode-json": "0.1.1",
180+ "classless-encode-json": "0.1.3",
181+ "classnames": "2.0.0",
182+ "codec": "6.1.0",
183+ "codec-argonaut": "10.0.0",
184+ "codec-json": "2.0.0",
185+ "colors": "7.0.1",
186+ "concur-core": "0.5.0",
187+ "concur-react": "0.5.0",
188+ "concurrent-queues": "3.0.0",
189+ "console": "6.1.0",
190+ "const": "6.0.0",
191+ "contravariant": "6.0.0",
192+ "control": "6.0.0",
193+ "convertable-options": "1.0.0",
194+ "coroutines": "7.0.0",
195+ "css": "6.0.0",
196+ "css-class-name-extractor": "0.0.4",
197+ "css-frameworks": "1.0.1",
198+ "csv-stream": "2.3.0",
199+ "data-mvc": "0.0.2",
200+ "datetime": "6.1.0",
201+ "datetime-parsing": "0.2.0",
202+ "debounce": "0.1.0",
203+ "debug": "6.0.2",
204+ "decimals": "7.1.0",
205+ "default-values": "1.0.1",
206+ "deku": "0.9.23",
207+ "deno": "0.0.5",
208+ "dissect": "1.0.0",
209+ "distributive": "6.0.0",
210+ "dodo-printer": "2.2.3",
211+ "dom-filereader": "7.0.0",
212+ "dom-indexed": "12.0.0",
213+ "dom-simple": "0.4.0",
214+ "dotenv": "4.0.3",
215+ "droplet": "0.6.0",
216+ "dts": "1.0.0",
217+ "dual-numbers": "1.0.3",
218+ "dynamic-buffer": "3.0.1",
219+ "echarts-simple": "0.0.1",
220+ "effect": "4.0.0",
221+ "either": "6.1.0",
222+ "elmish": "0.13.0",
223+ "elmish-enzyme": "0.1.1",
224+ "elmish-hooks": "0.10.3",
225+ "elmish-html": "0.9.0",
226+ "elmish-testing-library": "0.3.2",
227+ "email-validate": "7.0.0",
228+ "encoding": "0.0.9",
229+ "enums": "6.0.1",
230+ "env-names": "0.4.0",
231+ "error": "2.0.0",
232+ "eta-conversion": "0.3.2",
233+ "exceptions": "6.1.0",
234+ "exists": "6.0.0",
235+ "exitcodes": "4.0.0",
236+ "expect-inferred": "3.0.0",
237+ "ezfetch": "1.1.0",
238+ "fahrtwind": "2.0.0",
239+ "fallback": "0.1.0",
240+ "fast-vect": "1.2.0",
241+ "fetch": "4.1.0",
242+ "fetch-argonaut": "1.0.1",
243+ "fetch-core": "5.1.0",
244+ "fetch-yoga-json": "1.1.0",
245+ "ffi-simple": "0.5.1",
246+ "fft-js": "0.1.0",
247+ "filterable": "5.0.0",
248+ "fix-functor": "0.1.0",
249+ "fixed-points": "7.0.0",
250+ "fixed-precision": "5.0.0",
251+ "flame": "1.3.0",
252+ "float32": "2.0.0",
253+ "fmt": "0.2.1",
254+ "foldable-traversable": "6.0.0",
255+ "foldable-traversable-extra": "0.0.6",
256+ "foreign": "7.0.0",
257+ "foreign-object": "4.1.0",
258+ "foreign-readwrite": "3.4.0",
259+ "forgetmenot": "0.1.0",
260+ "fork": "6.0.0",
261+ "form-urlencoded": "7.0.0",
262+ "formatters": "7.0.0",
263+ "framer-motion": "1.0.1",
264+ "free": "7.1.0",
265+ "freeap": "7.0.0",
266+ "freer-free": "0.0.1",
267+ "freet": "7.0.0",
268+ "functions": "6.0.0",
269+ "functor1": "3.0.0",
270+ "functors": "5.0.0",
271+ "fuzzy": "0.4.0",
272+ "gen": "4.0.0",
273+ "generate-values": "1.0.1",
274+ "generic-router": "0.0.1",
275+ "geojson": "0.0.5",
276+ "geometria": "2.2.0",
277+ "gojs": "0.1.1",
278+ "grain": "3.0.0",
279+ "grain-router": "3.0.0",
280+ "grain-virtualized": "3.0.0",
281+ "graphs": "8.1.0",
282+ "group": "4.1.1",
283+ "halogen": "7.0.0",
284+ "halogen-bootstrap5": "5.3.2",
285+ "halogen-canvas": "1.0.0",
286+ "halogen-css": "10.0.0",
287+ "halogen-echarts-simple": "0.0.4",
288+ "halogen-formless": "4.0.3",
289+ "halogen-helix": "1.0.1",
290+ "halogen-hooks": "0.6.3",
291+ "halogen-hooks-extra": "0.9.0",
292+ "halogen-infinite-scroll": "1.1.0",
293+ "halogen-store": "0.5.4",
294+ "halogen-storybook": "2.0.0",
295+ "halogen-subscriptions": "2.0.0",
296+ "halogen-svg-elems": "8.0.0",
297+ "halogen-typewriter": "1.0.4",
298+ "halogen-vdom": "8.0.0",
299+ "halogen-vdom-string-renderer": "0.5.0",
300+ "halogen-xterm": "2.0.0",
301+ "heckin": "2.0.1",
302+ "heterogeneous": "0.6.0",
303+ "homogeneous": "0.4.0",
304+ "http-methods": "6.0.0",
305+ "httpurple": "4.0.0",
306+ "huffman": "0.4.0",
307+ "humdrum": "0.0.1",
308+ "hyrule": "2.3.8",
309+ "identity": "6.0.0",
310+ "identy": "4.0.1",
311+ "indexed-db": "1.0.0",
312+ "indexed-monad": "3.0.0",
313+ "int64": "3.0.0",
314+ "integers": "6.0.0",
315+ "interpolate": "5.0.2",
316+ "intersection-observer": "1.0.1",
317+ "invariant": "6.0.0",
318+ "jarilo": "1.0.1",
319+ "jelly": "0.10.0",
320+ "jelly-router": "0.3.0",
321+ "jelly-signal": "0.4.0",
322+ "jest": "1.0.0",
323+ "js-abort-controller": "1.0.0",
324+ "js-bigints": "2.2.1",
325+ "js-date": "8.0.0",
326+ "js-fetch": "0.2.1",
327+ "js-fileio": "3.0.0",
328+ "js-intl": "1.1.4",
329+ "js-iterators": "0.1.1",
330+ "js-maps": "0.1.2",
331+ "js-promise": "1.0.0",
332+ "js-promise-aff": "1.0.0",
333+ "js-timers": "6.1.0",
334+ "js-uri": "3.1.0",
335+ "jsdom": "1.0.0",
336+ "json": "1.1.0",
337+ "json-codecs": "5.0.0",
338+ "justifill": "0.5.0",
339+ "jwt": "0.0.9",
340+ "labeled-data": "0.2.0",
341+ "language-cst-parser": "0.14.1",
342+ "lazy": "6.0.0",
343+ "lazy-joe": "1.0.0",
344+ "lcg": "4.0.0",
345+ "leibniz": "5.0.0",
346+ "leveldb": "1.0.1",
347+ "liminal": "1.0.1",
348+ "linalg": "6.0.0",
349+ "lists": "7.0.0",
350+ "literals": "1.0.2",
351+ "logging": "3.0.0",
352+ "logging-journald": "0.4.0",
353+ "lumi-components": "18.0.0",
354+ "machines": "7.0.0",
355+ "maps-eager": "0.5.0",
356+ "marionette": "1.0.0",
357+ "marionette-react-basic-hooks": "0.1.1",
358+ "marked": "0.1.0",
359+ "matrices": "5.0.1",
360+ "matryoshka": "1.0.0",
361+ "maybe": "6.0.0",
362+ "media-types": "6.0.0",
363+ "meowclient": "1.0.0",
364+ "midi": "4.0.0",
365+ "milkis": "9.0.0",
366+ "minibench": "4.0.1",
367+ "mmorph": "7.0.0",
368+ "monad-control": "5.0.0",
369+ "monad-logger": "1.3.1",
370+ "monad-loops": "0.5.0",
371+ "monad-unlift": "1.0.1",
372+ "monoid-extras": "0.0.1",
373+ "monoidal": "0.16.0",
374+ "morello": "0.4.0",
375+ "mote": "3.0.0",
376+ "motsunabe": "2.0.0",
377+ "mvc": "0.0.1",
378+ "mysql": "6.0.1",
379+ "n3": "0.1.0",
380+ "nano-id": "1.1.0",
381+ "nanoid": "0.1.0",
382+ "naturals": "3.0.0",
383+ "nested-functor": "0.2.1",
384+ "newtype": "5.0.0",
385+ "nextjs": "0.1.1",
386+ "nextui": "0.2.0",
387+ "node-buffer": "9.0.0",
388+ "node-child-process": "11.1.0",
389+ "node-event-emitter": "3.0.0",
390+ "node-execa": "5.0.0",
391+ "node-fs": "9.2.0",
392+ "node-glob-basic": "2.0.0",
393+ "node-http": "9.1.0",
394+ "node-http2": "1.1.1",
395+ "node-human-signals": "1.0.0",
396+ "node-net": "5.1.0",
397+ "node-os": "5.1.0",
398+ "node-path": "5.0.1",
399+ "node-process": "11.2.0",
400+ "node-readline": "8.1.1",
401+ "node-sqlite3": "8.0.0",
402+ "node-stream-pipes": "2.1.6",
403+ "node-streams": "9.0.1",
404+ "node-tls": "0.3.1",
405+ "node-url": "7.0.1",
406+ "node-workerbees": "0.3.1",
407+ "node-zlib": "0.4.0",
408+ "nonempty": "7.0.0",
409+ "now": "6.0.0",
410+ "npm-package-json": "2.0.0",
411+ "nullable": "6.0.0",
412+ "numberfield": "0.2.2",
413+ "numbers": "9.0.1",
414+ "oak": "3.1.1",
415+ "oak-debug": "1.2.2",
416+ "object-maps": "0.3.0",
417+ "ocarina": "1.5.4",
418+ "oooooooooorrrrrrrmm-lib": "0.0.1",
419+ "open-colors-scales-and-schemes": "1.0.0",
420+ "open-folds": "6.4.0",
421+ "open-foreign-generic": "11.0.3",
422+ "open-memoize": "6.2.0",
423+ "open-mkdirp-aff": "1.2.0",
424+ "open-pairing": "6.2.0",
425+ "open-smolder": "12.0.2",
426+ "options": "7.0.0",
427+ "optparse": "5.0.1",
428+ "ordered-collections": "3.2.0",
429+ "ordered-set": "0.4.0",
430+ "orders": "6.0.0",
431+ "owoify": "1.2.0",
432+ "pairs": "9.0.1",
433+ "parallel": "7.0.0",
434+ "parsing": "10.2.0",
435+ "parsing-dataview": "3.2.4",
436+ "partial": "4.0.0",
437+ "pathy": "9.0.0",
438+ "pha": "0.13.0",
439+ "phaser": "0.7.0",
440+ "phylio": "1.1.2",
441+ "pipes": "8.0.0",
442+ "pirates-charm": "0.0.1",
443+ "pmock": "0.9.0",
444+ "point-free": "1.0.0",
445+ "pointed-list": "0.5.1",
446+ "polymorphic-vectors": "4.0.0",
447+ "posix-types": "6.0.0",
448+ "postgresql": "2.0.20",
449+ "precise": "6.0.0",
450+ "precise-datetime": "7.0.0",
451+ "prelude": "6.0.2",
452+ "prettier-printer": "3.0.0",
453+ "printf": "0.1.0",
454+ "priority-queue": "0.1.2",
455+ "profunctor": "6.0.1",
456+ "profunctor-lenses": "8.0.0",
457+ "protobuf": "4.4.0",
458+ "psa-utils": "8.0.0",
459+ "psci-support": "6.0.0",
460+ "punycode": "1.0.0",
461+ "qualified-do": "2.2.0",
462+ "quantities": "12.2.0",
463+ "quickcheck": "8.0.1",
464+ "quickcheck-combinators": "0.1.3",
465+ "quickcheck-laws": "7.0.0",
466+ "quickcheck-utf8": "0.0.0",
467+ "random": "6.0.0",
468+ "rationals": "6.0.0",
469+ "rdf": "0.1.0",
470+ "react": "11.0.0",
471+ "react-aria": "0.2.0",
472+ "react-basic": "17.0.0",
473+ "react-basic-classic": "3.0.0",
474+ "react-basic-dnd": "10.1.0",
475+ "react-basic-dom": "7.0.0",
476+ "react-basic-dom-beta": "0.1.1",
477+ "react-basic-emotion": "7.1.0",
478+ "react-basic-hooks": "8.2.0",
479+ "react-basic-storybook": "2.0.0",
480+ "react-dom": "8.0.0",
481+ "react-halo": "3.0.0",
482+ "react-icons": "1.1.5",
483+ "react-markdown": "0.1.0",
484+ "react-testing-library": "4.0.1",
485+ "react-virtuoso": "1.0.0",
486+ "reactix": "0.6.1",
487+ "read": "1.0.1",
488+ "recharts": "1.1.0",
489+ "record": "4.0.0",
490+ "record-extra": "5.0.1",
491+ "record-ptional-fields": "0.1.2",
492+ "record-studio": "1.0.4",
493+ "refs": "6.0.0",
494+ "remotedata": "5.0.1",
495+ "repr": "0.5.0",
496+ "resize-observer": "1.0.0",
497+ "resource": "2.0.1",
498+ "resourcet": "1.0.0",
499+ "result": "1.0.3",
500+ "return": "0.2.0",
501+ "ring-modules": "5.0.1",
502+ "rito": "0.3.4",
503+ "roman": "0.4.0",
504+ "rough-notation": "1.0.2",
505+ "routing": "11.0.0",
506+ "routing-duplex": "0.7.0",
507+ "run": "5.0.0",
508+ "safe-coerce": "2.0.0",
509+ "safely": "4.0.1",
510+ "school-of-music": "1.3.0",
511+ "selection-foldable": "0.2.0",
512+ "selective-functors": "1.0.1",
513+ "semirings": "7.0.0",
514+ "shuffle": "1.1.0",
515+ "signal": "13.0.0",
516+ "simple-emitter": "3.0.1",
517+ "simple-i18n": "2.0.1",
518+ "simple-json": "9.0.0",
519+ "simple-json-generics": "0.2.1",
520+ "simple-ulid": "3.0.0",
521+ "sized-matrices": "1.0.0",
522+ "sized-vectors": "5.0.2",
523+ "slug": "3.1.0",
524+ "small-ffi": "4.0.1",
525+ "soundfonts": "4.1.0",
526+ "sparse-matrices": "2.0.1",
527+ "sparse-polynomials": "3.0.1",
528+ "spec": "8.1.1",
529+ "spec-discovery": "8.4.0",
530+ "spec-mocha": "5.1.1",
531+ "spec-node": "0.0.3",
532+ "spec-quickcheck": "5.0.2",
533+ "spec-reporter-xunit": "0.7.1",
534+ "splitmix": "2.1.0",
535+ "ssrs": "1.0.0",
536+ "st": "6.2.0",
537+ "statistics": "0.3.2",
538+ "strictlypositiveint": "1.0.1",
539+ "string-parsers": "8.0.0",
540+ "strings": "6.0.1",
541+ "strings-extra": "4.0.0",
542+ "stringutils": "0.0.12",
543+ "substitute": "0.2.3",
544+ "supply": "0.2.0",
545+ "svg-parser": "3.0.0",
546+ "systemd-journald": "0.3.0",
547+ "tagged": "4.0.2",
548+ "tailrec": "6.1.0",
549+ "tanstack-query": "2.0.0",
550+ "tecton": "0.2.1",
551+ "tecton-halogen": "0.2.0",
552+ "test-unit": "17.0.0",
553+ "thermite": "6.3.1",
554+ "thermite-dom": "0.3.1",
555+ "these": "6.0.0",
556+ "threading": "0.0.3",
557+ "tidy": "0.11.1",
558+ "tidy-codegen": "4.0.1",
559+ "tldr": "0.0.0",
560+ "toestand": "0.9.0",
561+ "transformation-matrix": "1.0.1",
562+ "transformers": "6.1.0",
563+ "tree-rose": "4.0.2",
564+ "ts-bridge": "4.0.0",
565+ "tuples": "7.0.0",
566+ "two-or-more": "1.0.0",
567+ "type-equality": "4.0.1",
568+ "typedenv": "2.0.1",
569+ "typelevel": "6.0.0",
570+ "typelevel-lists": "2.1.0",
571+ "typelevel-peano": "1.0.1",
572+ "typelevel-prelude": "7.0.0",
573+ "typelevel-regex": "0.0.3",
574+ "typelevel-rows": "0.1.0",
575+ "typisch": "0.4.0",
576+ "uint": "7.0.0",
577+ "ulid": "3.0.1",
578+ "uncurried-transformers": "1.1.0",
579+ "undefined": "2.0.0",
580+ "undefined-is-not-a-problem": "1.1.0",
581+ "unfoldable": "6.0.0",
582+ "unicode": "6.0.0",
583+ "unique": "0.6.1",
584+ "unlift": "1.0.1",
585+ "unordered-collections": "3.1.0",
586+ "unsafe-coerce": "6.0.0",
587+ "unsafe-reference": "5.0.0",
588+ "untagged-to-tagged": "0.1.4",
589+ "untagged-union": "1.0.0",
590+ "uri": "9.0.0",
591+ "url-immutable": "1.0.0",
592+ "uuid": "9.0.0",
593+ "uuidv4": "1.0.0",
594+ "validation": "6.0.0",
595+ "variant": "8.0.0",
596+ "variant-encodings": "2.0.0",
597+ "vectorfield": "1.0.1",
598+ "vectors": "2.1.0",
599+ "versions": "7.0.0",
600+ "visx": "0.0.2",
601+ "vitest": "1.0.0",
602+ "web-clipboard": "6.0.0",
603+ "web-cssom": "2.0.0",
604+ "web-cssom-view": "0.1.0",
605+ "web-dom": "6.0.0",
606+ "web-dom-parser": "8.0.0",
607+ "web-dom-xpath": "3.0.0",
608+ "web-encoding": "3.0.0",
609+ "web-events": "4.0.0",
610+ "web-fetch": "4.0.1",
611+ "web-file": "4.0.0",
612+ "web-geometry": "0.1.0",
613+ "web-html": "4.1.0",
614+ "web-pointerevents": "2.0.0",
615+ "web-proletarian": "1.0.0",
616+ "web-promise": "3.2.0",
617+ "web-resize-observer": "2.1.0",
618+ "web-router": "1.0.0",
619+ "web-socket": "4.0.0",
620+ "web-storage": "5.0.0",
621+ "web-streams": "4.0.0",
622+ "web-touchevents": "4.0.0",
623+ "web-uievents": "5.0.0",
624+ "web-url": "2.0.0",
625+ "web-workers": "1.1.0",
626+ "web-xhr": "5.0.1",
627+ "webextension-polyfill": "0.1.0",
628+ "webgpu": "0.0.1",
629+ "which": "2.0.0",
630+ "whine-core": "0.0.28",
631+ "xterm": "1.0.0",
632+ "yoga-fetch": "1.0.1",
633+ "yoga-json": "5.1.0",
634+ "yoga-om": "0.1.0",
635+ "yoga-postgres": "6.0.0",
636+ "yoga-react-dom": "1.0.1",
637+ "yoga-subtlecrypto": "0.1.0",
638+ "yoga-tree": "1.0.0",
639+ "z3": "0.0.2",
640+ "zipperarray": "2.0.0"
641+ }
642+ },
643+ "extra_packages": {}
644+ },
645+ "packages": {
646+ "aff": {
647+ "type": "registry",
648+ "version": "8.0.0",
649+ "integrity": "sha256-9BRIrSdRoYybfiUmBqgKJ66cPqxYHb277bVWQMn/9sg=",
650+ "dependencies": [
651+ "control",
652+ "datetime",
653+ "effect",
654+ "either",
655+ "exceptions",
656+ "functions",
657+ "newtype",
658+ "parallel",
659+ "partial",
660+ "prelude",
661+ "st",
662+ "tailrec",
663+ "transformers",
664+ "unsafe-coerce"
665+ ]
666+ },
667+ "ansi": {
668+ "type": "registry",
669+ "version": "7.0.0",
670+ "integrity": "sha256-tOUaXJFzPSfBVAqLI8hc+Tz2M1rg16cXqyHaK/3SmFg=",
671+ "dependencies": [
672+ "foldable-traversable",
673+ "lists",
674+ "prelude"
675+ ]
676+ },
677+ "argonaut-codecs": {
678+ "type": "registry",
679+ "version": "9.1.0",
680+ "integrity": "sha256-K910SBrmYallESsm8pxJYThs7lig6hxX3M4PW33Cgew=",
681+ "dependencies": [
682+ "argonaut-core",
683+ "arrays",
684+ "bifunctors",
685+ "either",
686+ "foldable-traversable",
687+ "foreign-object",
688+ "identity",
689+ "integers",
690+ "lists",
691+ "maybe",
692+ "nonempty",
693+ "ordered-collections",
694+ "prelude",
695+ "record",
696+ "strings",
697+ "tuples"
698+ ]
699+ },
700+ "argonaut-core": {
701+ "type": "registry",
702+ "version": "7.0.0",
703+ "integrity": "sha256-gYZihtBIKthVuXXoiPphMookSf8M5aHyFYkcIWqlxTM=",
704+ "dependencies": [
705+ "arrays",
706+ "control",
707+ "either",
708+ "foreign-object",
709+ "functions",
710+ "gen",
711+ "maybe",
712+ "nonempty",
713+ "prelude",
714+ "strings",
715+ "tailrec"
716+ ]
717+ },
718+ "arraybuffer-types": {
719+ "type": "registry",
720+ "version": "3.0.2",
721+ "integrity": "sha256-p05cJnSkyeoB7VHzMyc2Eb1RwUaB7Nl0sQSqEGNEUD8=",
722+ "dependencies": []
723+ },
724+ "arrays": {
725+ "type": "registry",
726+ "version": "7.3.0",
727+ "integrity": "sha256-GD4z7LCi9wzi7FCQqbWhvs8paoUK9NO+HwgXZ+KP8Rk=",
728+ "dependencies": [
729+ "bifunctors",
730+ "control",
731+ "foldable-traversable",
732+ "functions",
733+ "maybe",
734+ "nonempty",
735+ "partial",
736+ "prelude",
737+ "safe-coerce",
738+ "st",
739+ "tailrec",
740+ "tuples",
741+ "unfoldable",
742+ "unsafe-coerce"
743+ ]
744+ },
745+ "avar": {
746+ "type": "registry",
747+ "version": "5.0.1",
748+ "integrity": "sha256-8V4SxF4TIWZ9Ik1P4lPzIRUAZeFBe8w5WA2VcCEKsIk=",
749+ "dependencies": [
750+ "aff",
751+ "effect",
752+ "either",
753+ "exceptions",
754+ "functions",
755+ "maybe",
756+ "prelude"
757+ ]
758+ },
759+ "bifunctors": {
760+ "type": "registry",
761+ "version": "6.0.0",
762+ "integrity": "sha256-tXhmlMiyVy6mbUreVZQt/2EGEsPr0T1PjJi+YCG5J7E=",
763+ "dependencies": [
764+ "const",
765+ "either",
766+ "newtype",
767+ "prelude",
768+ "tuples"
769+ ]
770+ },
771+ "catenable-lists": {
772+ "type": "registry",
773+ "version": "7.0.0",
774+ "integrity": "sha256-7+i/MHBLIRh604iCNT4ENWRWE/wuHIotER4kpdX9Ve0=",
775+ "dependencies": [
776+ "control",
777+ "foldable-traversable",
778+ "lists",
779+ "maybe",
780+ "prelude",
781+ "tuples",
782+ "unfoldable"
783+ ]
784+ },
785+ "const": {
786+ "type": "registry",
787+ "version": "6.0.0",
788+ "integrity": "sha256-S+m0lQsxnji0z1XRUmkn+3RFuWJ5CXWuIr1u3i8Bfoc=",
789+ "dependencies": [
790+ "invariant",
791+ "newtype",
792+ "prelude"
793+ ]
794+ },
795+ "contravariant": {
796+ "type": "registry",
797+ "version": "6.0.0",
798+ "integrity": "sha256-nuckEWqL80NaPmR/l9AUyrfycNh18XcvlZV9PAamwqc=",
799+ "dependencies": [
800+ "const",
801+ "either",
802+ "newtype",
803+ "prelude",
804+ "tuples"
805+ ]
806+ },
807+ "control": {
808+ "type": "registry",
809+ "version": "6.0.0",
810+ "integrity": "sha256-0vxyYh5FL+ilxgLo954w1LqCUC0RSIivNNlb9CaNUQg=",
811+ "dependencies": [
812+ "newtype",
813+ "prelude"
814+ ]
815+ },
816+ "datetime": {
817+ "type": "registry",
818+ "version": "6.1.0",
819+ "integrity": "sha256-tbv6eDXy6QOD7YSknxYSbsDF32OC2JrNbSBpzMs7Doc=",
820+ "dependencies": [
821+ "bifunctors",
822+ "control",
823+ "either",
824+ "enums",
825+ "foldable-traversable",
826+ "functions",
827+ "gen",
828+ "integers",
829+ "lists",
830+ "maybe",
831+ "newtype",
832+ "numbers",
833+ "ordered-collections",
834+ "partial",
835+ "prelude",
836+ "tuples"
837+ ]
838+ },
839+ "distributive": {
840+ "type": "registry",
841+ "version": "6.0.0",
842+ "integrity": "sha256-netyJK4B32PDYHD0tF2AenKgo3urzbI770ycM0pArAo=",
843+ "dependencies": [
844+ "identity",
845+ "newtype",
846+ "prelude",
847+ "tuples",
848+ "type-equality"
849+ ]
850+ },
851+ "effect": {
852+ "type": "registry",
853+ "version": "4.0.0",
854+ "integrity": "sha256-DdqU3bncRTjgMVPPRlAuGHVeajSPEcRaRhNuio7if6s=",
855+ "dependencies": [
856+ "prelude"
857+ ]
858+ },
859+ "either": {
860+ "type": "registry",
861+ "version": "6.1.0",
862+ "integrity": "sha256-tBHx3PgtH4GZOApZCDkcM7szRTYJinrUrVGWazQCUUg=",
863+ "dependencies": [
864+ "control",
865+ "invariant",
866+ "maybe",
867+ "prelude"
868+ ]
869+ },
870+ "enums": {
871+ "type": "registry",
872+ "version": "6.0.1",
873+ "integrity": "sha256-sdZOmLX5+5pASGpvVyT0vSD5BBYQjZiayjV5XiPutso=",
874+ "dependencies": [
875+ "control",
876+ "either",
877+ "gen",
878+ "maybe",
879+ "newtype",
880+ "nonempty",
881+ "partial",
882+ "prelude",
883+ "tuples",
884+ "unfoldable"
885+ ]
886+ },
887+ "exceptions": {
888+ "type": "registry",
889+ "version": "6.1.0",
890+ "integrity": "sha256-nRrr+N0wk0TUFOWLR7e1n1oxcXo/X345bQUtoY9lW6A=",
891+ "dependencies": [
892+ "effect",
893+ "either",
894+ "maybe",
895+ "prelude"
896+ ]
897+ },
898+ "exists": {
899+ "type": "registry",
900+ "version": "6.0.0",
901+ "integrity": "sha256-vtLbrWNaI+pzx/2fw2AQnCovoLtcosClIhjO26QKkh8=",
902+ "dependencies": [
903+ "unsafe-coerce"
904+ ]
905+ },
906+ "exitcodes": {
907+ "type": "registry",
908+ "version": "4.0.0",
909+ "integrity": "sha256-xBl4aFSEQ05Owp1ZvO6OxxvLK3LVzU35RSbj79SsePQ=",
910+ "dependencies": [
911+ "enums",
912+ "maybe",
913+ "prelude"
914+ ]
915+ },
916+ "foldable-traversable": {
917+ "type": "registry",
918+ "version": "6.0.0",
919+ "integrity": "sha256-NGGWyCio/xjce6fPP7y3wwg7CheqllID6aJudDxbWhA=",
920+ "dependencies": [
921+ "bifunctors",
922+ "const",
923+ "control",
924+ "either",
925+ "functors",
926+ "identity",
927+ "maybe",
928+ "newtype",
929+ "orders",
930+ "prelude",
931+ "tuples"
932+ ]
933+ },
934+ "foreign": {
935+ "type": "registry",
936+ "version": "7.0.0",
937+ "integrity": "sha256-jiDRMVQfovGsbbA/FzbzYf6iWk9i2b5gNrIjz+gFfsI=",
938+ "dependencies": [
939+ "either",
940+ "functions",
941+ "integers",
942+ "lists",
943+ "maybe",
944+ "prelude",
945+ "strings",
946+ "transformers",
947+ "unsafe-coerce"
948+ ]
949+ },
950+ "foreign-object": {
951+ "type": "registry",
952+ "version": "4.1.0",
953+ "integrity": "sha256-x/Q7r80z/vmHRKvPwhYmHP/DnJciPtsyGfRTMzayKIU=",
954+ "dependencies": [
955+ "arrays",
956+ "foldable-traversable",
957+ "functions",
958+ "gen",
959+ "lists",
960+ "maybe",
961+ "prelude",
962+ "st",
963+ "tailrec",
964+ "tuples",
965+ "typelevel-prelude",
966+ "unfoldable",
967+ "unsafe-coerce"
968+ ]
969+ },
970+ "fork": {
971+ "type": "registry",
972+ "version": "6.0.0",
973+ "integrity": "sha256-0keBVeZZg1eCZEy/En1CohVW829gQUqKtqBNIRa93/A=",
974+ "dependencies": [
975+ "aff",
976+ "prelude",
977+ "transformers"
978+ ]
979+ },
980+ "free": {
981+ "type": "registry",
982+ "version": "7.1.0",
983+ "integrity": "sha256-tUBInfUpRQEw4u94GWcYW7EYdmSdDHSRn88a+C0eltU=",
984+ "dependencies": [
985+ "catenable-lists",
986+ "control",
987+ "distributive",
988+ "either",
989+ "exists",
990+ "foldable-traversable",
991+ "invariant",
992+ "lazy",
993+ "maybe",
994+ "prelude",
995+ "tailrec",
996+ "transformers",
997+ "tuples",
998+ "unsafe-coerce"
999+ ]
1000+ },
1001+ "functions": {
1002+ "type": "registry",
1003+ "version": "6.0.0",
1004+ "integrity": "sha256-0jgtOr+SFO4UScKc40oA/9Vdcf2rLn3h3vZlY0KfqVo=",
1005+ "dependencies": [
1006+ "prelude"
1007+ ]
1008+ },
1009+ "functors": {
1010+ "type": "registry",
1011+ "version": "5.0.0",
1012+ "integrity": "sha256-W1o/4wcp6S3chodYL8uixlXK2mfr1L+SzM1R+whqUco=",
1013+ "dependencies": [
1014+ "bifunctors",
1015+ "const",
1016+ "contravariant",
1017+ "control",
1018+ "distributive",
1019+ "either",
1020+ "invariant",
1021+ "maybe",
1022+ "newtype",
1023+ "prelude",
1024+ "profunctor",
1025+ "tuples",
1026+ "unsafe-coerce"
1027+ ]
1028+ },
1029+ "gen": {
1030+ "type": "registry",
1031+ "version": "4.0.0",
1032+ "integrity": "sha256-kyOateeOtQa07vfTMYeSuCKdelgKE1R65fwKkZ10wsY=",
1033+ "dependencies": [
1034+ "either",
1035+ "foldable-traversable",
1036+ "identity",
1037+ "maybe",
1038+ "newtype",
1039+ "nonempty",
1040+ "prelude",
1041+ "tailrec",
1042+ "tuples",
1043+ "unfoldable"
1044+ ]
1045+ },
1046+ "identity": {
1047+ "type": "registry",
1048+ "version": "6.0.0",
1049+ "integrity": "sha256-RY/iXPpxpqvKHYfJeFVNI1J06kohB9rbtWYuha8t0LE=",
1050+ "dependencies": [
1051+ "control",
1052+ "invariant",
1053+ "newtype",
1054+ "prelude"
1055+ ]
1056+ },
1057+ "integers": {
1058+ "type": "registry",
1059+ "version": "6.0.0",
1060+ "integrity": "sha256-Y8yozC1uHRLcruobEyv5/bMKzE1BoKJ/olHv6o+bgm8=",
1061+ "dependencies": [
1062+ "maybe",
1063+ "numbers",
1064+ "prelude"
1065+ ]
1066+ },
1067+ "invariant": {
1068+ "type": "registry",
1069+ "version": "6.0.0",
1070+ "integrity": "sha256-HyoT1I5qIHRq8RSZji6zZDvqnpVjLw748utrKwZtqsw=",
1071+ "dependencies": [
1072+ "control",
1073+ "prelude"
1074+ ]
1075+ },
1076+ "js-bigints": {
1077+ "type": "registry",
1078+ "version": "2.2.1",
1079+ "integrity": "sha256-r1rE6Olv5b3JrP32lY2uKJ+eBRTsrVnC983K8VWwqe4=",
1080+ "dependencies": [
1081+ "integers",
1082+ "maybe",
1083+ "prelude"
1084+ ]
1085+ },
1086+ "js-date": {
1087+ "type": "registry",
1088+ "version": "8.0.0",
1089+ "integrity": "sha256-DNQrp4xYc8o80jtxo0aOkUeXGi6h0Xidkk2ZQ8Y4l5Y=",
1090+ "dependencies": [
1091+ "datetime",
1092+ "effect",
1093+ "enums",
1094+ "foreign",
1095+ "functions",
1096+ "integers",
1097+ "maybe",
1098+ "prelude"
1099+ ]
1100+ },
1101+ "lazy": {
1102+ "type": "registry",
1103+ "version": "6.0.0",
1104+ "integrity": "sha256-MHRC+1Pc+AjortBp4b/e1e6KpEpsDwaJBNBB7TOL+1I=",
1105+ "dependencies": [
1106+ "control",
1107+ "foldable-traversable",
1108+ "invariant",
1109+ "prelude"
1110+ ]
1111+ },
1112+ "lists": {
1113+ "type": "registry",
1114+ "version": "7.0.0",
1115+ "integrity": "sha256-/mGd7wLoU+wsTcqii7SSUByxsvwvjnu2PjwAD47yYb4=",
1116+ "dependencies": [
1117+ "bifunctors",
1118+ "control",
1119+ "foldable-traversable",
1120+ "lazy",
1121+ "maybe",
1122+ "newtype",
1123+ "nonempty",
1124+ "partial",
1125+ "prelude",
1126+ "tailrec",
1127+ "tuples",
1128+ "unfoldable"
1129+ ]
1130+ },
1131+ "maybe": {
1132+ "type": "registry",
1133+ "version": "6.0.0",
1134+ "integrity": "sha256-8X6XEgtZ5lqfkEuc1hWOofnL6mwhk8gSJTxwvbR/SbY=",
1135+ "dependencies": [
1136+ "control",
1137+ "invariant",
1138+ "newtype",
1139+ "prelude"
1140+ ]
1141+ },
1142+ "mmorph": {
1143+ "type": "registry",
1144+ "version": "7.0.0",
1145+ "integrity": "sha256-Cfltaq+tfYjuSoSBN/b8cSQZbvZTqIRs6ebQewbIkGs=",
1146+ "dependencies": [
1147+ "bifunctors",
1148+ "either",
1149+ "free",
1150+ "functors",
1151+ "identity",
1152+ "maybe",
1153+ "newtype",
1154+ "prelude",
1155+ "transformers",
1156+ "tuples"
1157+ ]
1158+ },
1159+ "newtype": {
1160+ "type": "registry",
1161+ "version": "5.0.0",
1162+ "integrity": "sha256-dt6w0cty4OS+Pjt9fsh3iU6ottqSU83mdAZkaEEvo6c=",
1163+ "dependencies": [
1164+ "prelude",
1165+ "safe-coerce"
1166+ ]
1167+ },
1168+ "node-buffer": {
1169+ "type": "registry",
1170+ "version": "9.0.0",
1171+ "integrity": "sha256-RdQjilmEHqsT4fwpCr8Mavw8KTafYrS3ZM6zeAAVAl8=",
1172+ "dependencies": [
1173+ "arraybuffer-types",
1174+ "effect",
1175+ "functions",
1176+ "maybe",
1177+ "nullable",
1178+ "partial",
1179+ "prelude",
1180+ "st",
1181+ "unsafe-coerce"
1182+ ]
1183+ },
1184+ "node-event-emitter": {
1185+ "type": "registry",
1186+ "version": "3.0.0",
1187+ "integrity": "sha256-wodx71NxJBPXOaawFn01V1ByYB2vT+I3RuV2giOVKMg=",
1188+ "dependencies": [
1189+ "effect",
1190+ "either",
1191+ "functions",
1192+ "maybe",
1193+ "nullable",
1194+ "prelude",
1195+ "unsafe-coerce"
1196+ ]
1197+ },
1198+ "node-fs": {
1199+ "type": "registry",
1200+ "version": "9.2.0",
1201+ "integrity": "sha256-fxioTSm9y47WuYs9F/7nxCh/RVDCl3Kr3Hg779J4SJA=",
1202+ "dependencies": [
1203+ "aff",
1204+ "datetime",
1205+ "effect",
1206+ "either",
1207+ "enums",
1208+ "exceptions",
1209+ "functions",
1210+ "integers",
1211+ "js-date",
1212+ "maybe",
1213+ "node-buffer",
1214+ "node-path",
1215+ "node-streams",
1216+ "nullable",
1217+ "partial",
1218+ "prelude",
1219+ "strings"
1220+ ]
1221+ },
1222+ "node-path": {
1223+ "type": "registry",
1224+ "version": "5.0.1",
1225+ "integrity": "sha256-j7n/SmpVz0FOMJl4XZop3ofJ+MeIPkMNqUEUKHEL6Us=",
1226+ "dependencies": [
1227+ "effect"
1228+ ]
1229+ },
1230+ "node-process": {
1231+ "type": "registry",
1232+ "version": "11.2.0",
1233+ "integrity": "sha256-onzKeNmaeYfN3HSDPqSFTrrP2Yl9tnVsfKKhnf2plxM=",
1234+ "dependencies": [
1235+ "effect",
1236+ "exceptions",
1237+ "foreign",
1238+ "foreign-object",
1239+ "maybe",
1240+ "node-event-emitter",
1241+ "node-streams",
1242+ "nullable",
1243+ "posix-types",
1244+ "prelude",
1245+ "strings"
1246+ ]
1247+ },
1248+ "node-streams": {
1249+ "type": "registry",
1250+ "version": "9.0.1",
1251+ "integrity": "sha256-yuVGm/R/tBr4Nphi+a1a984Z0fkmN9Q5wWtSmbmJTpA=",
1252+ "dependencies": [
1253+ "aff",
1254+ "arrays",
1255+ "effect",
1256+ "either",
1257+ "exceptions",
1258+ "maybe",
1259+ "node-buffer",
1260+ "node-event-emitter",
1261+ "nullable",
1262+ "prelude",
1263+ "refs",
1264+ "st",
1265+ "tailrec",
1266+ "unsafe-coerce"
1267+ ]
1268+ },
1269+ "nonempty": {
1270+ "type": "registry",
1271+ "version": "7.0.0",
1272+ "integrity": "sha256-Ctkq8/+KiGqCE53Y/LvibA/coy7ev9HtRZU+GYS7yfQ=",
1273+ "dependencies": [
1274+ "control",
1275+ "foldable-traversable",
1276+ "maybe",
1277+ "prelude",
1278+ "tuples",
1279+ "unfoldable"
1280+ ]
1281+ },
1282+ "now": {
1283+ "type": "registry",
1284+ "version": "6.0.0",
1285+ "integrity": "sha256-mTyG4s8tps3XIf0jjV/lME2/QlwMzrQly2wqfSSUM3o=",
1286+ "dependencies": [
1287+ "datetime",
1288+ "effect",
1289+ "prelude"
1290+ ]
1291+ },
1292+ "nullable": {
1293+ "type": "registry",
1294+ "version": "6.0.0",
1295+ "integrity": "sha256-CDAZk+L9Sc0GCFTkE8n+qdp4Ys8avvnkU+m2hVALt7M=",
1296+ "dependencies": [
1297+ "functions",
1298+ "maybe",
1299+ "prelude"
1300+ ]
1301+ },
1302+ "numbers": {
1303+ "type": "registry",
1304+ "version": "9.0.1",
1305+ "integrity": "sha256-ZydYckgwRAnRaFC7pu6fADhzdwX+UqHZrfJyet64zls=",
1306+ "dependencies": [
1307+ "functions",
1308+ "maybe",
1309+ "prelude"
1310+ ]
1311+ },
1312+ "open-memoize": {
1313+ "type": "registry",
1314+ "version": "6.2.0",
1315+ "integrity": "sha256-yJLuVYX8FocHIJ+6q7efH/Pj4S+e1Y57DZ5Dn7qf4ww=",
1316+ "dependencies": [
1317+ "either",
1318+ "integers",
1319+ "lazy",
1320+ "lists",
1321+ "maybe",
1322+ "partial",
1323+ "prelude",
1324+ "strings",
1325+ "tuples"
1326+ ]
1327+ },
1328+ "optparse": {
1329+ "type": "registry",
1330+ "version": "5.0.1",
1331+ "integrity": "sha256-2btDjHPRR0uujUQJuZAN9AzvVoXe7yG6IwnY5evERhQ=",
1332+ "dependencies": [
1333+ "arrays",
1334+ "bifunctors",
1335+ "control",
1336+ "effect",
1337+ "either",
1338+ "enums",
1339+ "exists",
1340+ "exitcodes",
1341+ "foldable-traversable",
1342+ "free",
1343+ "integers",
1344+ "lazy",
1345+ "lists",
1346+ "maybe",
1347+ "newtype",
1348+ "node-buffer",
1349+ "node-process",
1350+ "node-streams",
1351+ "nonempty",
1352+ "numbers",
1353+ "open-memoize",
1354+ "partial",
1355+ "prelude",
1356+ "strings",
1357+ "tailrec",
1358+ "transformers",
1359+ "tuples"
1360+ ]
1361+ },
1362+ "ordered-collections": {
1363+ "type": "registry",
1364+ "version": "3.2.0",
1365+ "integrity": "sha256-NaEXc2cz/7lJfxPWEja4XlZbGxuRqJwFKQJjsJf51kQ=",
1366+ "dependencies": [
1367+ "arrays",
1368+ "control",
1369+ "foldable-traversable",
1370+ "functions",
1371+ "gen",
1372+ "lists",
1373+ "maybe",
1374+ "newtype",
1375+ "partial",
1376+ "prelude",
1377+ "safe-coerce",
1378+ "tailrec",
1379+ "tuples",
1380+ "unfoldable"
1381+ ]
1382+ },
1383+ "orders": {
1384+ "type": "registry",
1385+ "version": "6.0.0",
1386+ "integrity": "sha256-nSMxZK7wxyDULkjZqvMyB71mVo6b0AyLLHosDVbv1XM=",
1387+ "dependencies": [
1388+ "newtype",
1389+ "prelude"
1390+ ]
1391+ },
1392+ "parallel": {
1393+ "type": "registry",
1394+ "version": "7.0.0",
1395+ "integrity": "sha256-bAGpVhrFz2IyHkA4MR7+tE/19FZ7dzYBdYPgK5svkqw=",
1396+ "dependencies": [
1397+ "control",
1398+ "effect",
1399+ "either",
1400+ "foldable-traversable",
1401+ "functors",
1402+ "maybe",
1403+ "newtype",
1404+ "prelude",
1405+ "profunctor",
1406+ "refs",
1407+ "transformers"
1408+ ]
1409+ },
1410+ "partial": {
1411+ "type": "registry",
1412+ "version": "4.0.0",
1413+ "integrity": "sha256-mdrlJBAgFMh79hNRW39uv7c+BwnnaOrAMmdh7+VhEhs=",
1414+ "dependencies": []
1415+ },
1416+ "pipes": {
1417+ "type": "registry",
1418+ "version": "8.0.0",
1419+ "integrity": "sha256-dtUNpG8BGVr7pu6mQZyAnUAftUHgNS7f0QH3Kw5UTpQ=",
1420+ "dependencies": [
1421+ "aff",
1422+ "control",
1423+ "effect",
1424+ "either",
1425+ "foldable-traversable",
1426+ "identity",
1427+ "lists",
1428+ "maybe",
1429+ "mmorph",
1430+ "newtype",
1431+ "prelude",
1432+ "tailrec",
1433+ "transformers",
1434+ "tuples"
1435+ ]
1436+ },
1437+ "posix-types": {
1438+ "type": "registry",
1439+ "version": "6.0.0",
1440+ "integrity": "sha256-Je5jG439F/SFO/IvVevZnWVxDIonrehlKuJkefP2lHE=",
1441+ "dependencies": [
1442+ "maybe",
1443+ "newtype",
1444+ "prelude"
1445+ ]
1446+ },
1447+ "prelude": {
1448+ "type": "registry",
1449+ "version": "6.0.2",
1450+ "integrity": "sha256-IqykrDRquGUD/LRSad7y75hZv3bUsGQ4knc8tdez8Qw=",
1451+ "dependencies": []
1452+ },
1453+ "profunctor": {
1454+ "type": "registry",
1455+ "version": "6.0.1",
1456+ "integrity": "sha256-Ow0mJC+PIIRq/a3mzCWY5vxuTgR/e+Ee68+mWeSRnWY=",
1457+ "dependencies": [
1458+ "control",
1459+ "distributive",
1460+ "either",
1461+ "exists",
1462+ "invariant",
1463+ "newtype",
1464+ "prelude",
1465+ "tuples"
1466+ ]
1467+ },
1468+ "record": {
1469+ "type": "registry",
1470+ "version": "4.0.0",
1471+ "integrity": "sha256-WQ8fqp4X1wTA70J4qUcPW4Z7DCwx6e5KJnT/EuTdWSc=",
1472+ "dependencies": [
1473+ "functions",
1474+ "prelude",
1475+ "unsafe-coerce"
1476+ ]
1477+ },
1478+ "refs": {
1479+ "type": "registry",
1480+ "version": "6.0.0",
1481+ "integrity": "sha256-KKD5G9dR2SauuDGULUJsxjqDOEi1Jqm+2Sq5U2mY8YU=",
1482+ "dependencies": [
1483+ "effect",
1484+ "prelude"
1485+ ]
1486+ },
1487+ "safe-coerce": {
1488+ "type": "registry",
1489+ "version": "2.0.0",
1490+ "integrity": "sha256-EJrxtKt5xC7TYjBZrSBO/J7Aw3DmtilYjt4olpAXWVc=",
1491+ "dependencies": [
1492+ "unsafe-coerce"
1493+ ]
1494+ },
1495+ "spec": {
1496+ "type": "registry",
1497+ "version": "8.1.1",
1498+ "integrity": "sha256-b6qjDb7lUJGLV+WEoywLu6BCXC4zGpfbN43mTL+vBeI=",
1499+ "dependencies": [
1500+ "aff",
1501+ "ansi",
1502+ "arrays",
1503+ "avar",
1504+ "bifunctors",
1505+ "control",
1506+ "datetime",
1507+ "effect",
1508+ "either",
1509+ "exceptions",
1510+ "foldable-traversable",
1511+ "fork",
1512+ "identity",
1513+ "integers",
1514+ "lists",
1515+ "maybe",
1516+ "newtype",
1517+ "now",
1518+ "ordered-collections",
1519+ "parallel",
1520+ "pipes",
1521+ "prelude",
1522+ "refs",
1523+ "strings",
1524+ "tailrec",
1525+ "transformers",
1526+ "tuples"
1527+ ]
1528+ },
1529+ "spec-discovery": {
1530+ "type": "registry",
1531+ "version": "8.4.0",
1532+ "integrity": "sha256-aFp8bllT/wrxQu8hMlDchQQY08dQAz+Xdq2hZi5z3yY=",
1533+ "dependencies": [
1534+ "aff",
1535+ "effect",
1536+ "foldable-traversable",
1537+ "prelude",
1538+ "spec",
1539+ "spec-node"
1540+ ]
1541+ },
1542+ "spec-node": {
1543+ "type": "registry",
1544+ "version": "0.0.3",
1545+ "integrity": "sha256-8/9+g0obbamV0YtqzmttbWs8HaWF7CEeW+eDtqzuAAo=",
1546+ "dependencies": [
1547+ "aff",
1548+ "argonaut-codecs",
1549+ "argonaut-core",
1550+ "arrays",
1551+ "control",
1552+ "datetime",
1553+ "effect",
1554+ "either",
1555+ "foldable-traversable",
1556+ "identity",
1557+ "integers",
1558+ "maybe",
1559+ "newtype",
1560+ "node-buffer",
1561+ "node-fs",
1562+ "node-process",
1563+ "now",
1564+ "numbers",
1565+ "optparse",
1566+ "ordered-collections",
1567+ "partial",
1568+ "prelude",
1569+ "spec",
1570+ "strings",
1571+ "tuples"
1572+ ]
1573+ },
1574+ "st": {
1575+ "type": "registry",
1576+ "version": "6.2.0",
1577+ "integrity": "sha256-WI4MEkkwUd4pnwZQ3G8VKWgX5t1RSNJludm5e9boaRo=",
1578+ "dependencies": [
1579+ "effect",
1580+ "partial",
1581+ "prelude",
1582+ "tailrec",
1583+ "unsafe-coerce"
1584+ ]
1585+ },
1586+ "strings": {
1587+ "type": "registry",
1588+ "version": "6.0.1",
1589+ "integrity": "sha256-FNto2hoNW5Da6W6crIk77YXMagBvOGHZE1kO7eZ1vLM=",
1590+ "dependencies": [
1591+ "arrays",
1592+ "control",
1593+ "either",
1594+ "enums",
1595+ "foldable-traversable",
1596+ "gen",
1597+ "integers",
1598+ "maybe",
1599+ "newtype",
1600+ "nonempty",
1601+ "partial",
1602+ "prelude",
1603+ "tailrec",
1604+ "tuples",
1605+ "unfoldable",
1606+ "unsafe-coerce"
1607+ ]
1608+ },
1609+ "strings-extra": {
1610+ "type": "registry",
1611+ "version": "4.0.0",
1612+ "integrity": "sha256-Wlsa9A4hg4PnZYa9WsE0e820xilquVwm33nn067qNIA=",
1613+ "dependencies": [
1614+ "arrays",
1615+ "foldable-traversable",
1616+ "prelude",
1617+ "strings",
1618+ "unicode"
1619+ ]
1620+ },
1621+ "tailrec": {
1622+ "type": "registry",
1623+ "version": "6.1.0",
1624+ "integrity": "sha256-xrorCfP0xV1wubs27idQCHQqdvSUuqmmL/am7Ji1wVU=",
1625+ "dependencies": [
1626+ "bifunctors",
1627+ "effect",
1628+ "either",
1629+ "identity",
1630+ "maybe",
1631+ "partial",
1632+ "prelude",
1633+ "refs"
1634+ ]
1635+ },
1636+ "transformers": {
1637+ "type": "registry",
1638+ "version": "6.1.0",
1639+ "integrity": "sha256-QJmgNT/y7ljPHSsXaW4zxF/982BFiQ90KNL1g/NtEOQ=",
1640+ "dependencies": [
1641+ "control",
1642+ "distributive",
1643+ "effect",
1644+ "either",
1645+ "exceptions",
1646+ "foldable-traversable",
1647+ "identity",
1648+ "lazy",
1649+ "maybe",
1650+ "newtype",
1651+ "prelude",
1652+ "st",
1653+ "tailrec",
1654+ "tuples",
1655+ "unfoldable"
1656+ ]
1657+ },
1658+ "tuples": {
1659+ "type": "registry",
1660+ "version": "7.0.0",
1661+ "integrity": "sha256-BKy7EfK8S1KeTCwyWqyW1wwcpSAQuh3IsczSVgS6fzY=",
1662+ "dependencies": [
1663+ "control",
1664+ "invariant",
1665+ "prelude"
1666+ ]
1667+ },
1668+ "type-equality": {
1669+ "type": "registry",
1670+ "version": "4.0.1",
1671+ "integrity": "sha256-BBqYOSnAKmayRvR5mtZoCf4SlYs2ipatD/+5nQx73aw=",
1672+ "dependencies": []
1673+ },
1674+ "typelevel-prelude": {
1675+ "type": "registry",
1676+ "version": "7.0.0",
1677+ "integrity": "sha256-+pHi14/40mTj/+lmCWqL0T7iXIXD1+NSg/KItyyoB0A=",
1678+ "dependencies": [
1679+ "prelude",
1680+ "type-equality"
1681+ ]
1682+ },
1683+ "unfoldable": {
1684+ "type": "registry",
1685+ "version": "6.0.0",
1686+ "integrity": "sha256-BK/6By1sKp/ztk+9CF3q43SV0QDTLVdsGqFerKHSmbg=",
1687+ "dependencies": [
1688+ "foldable-traversable",
1689+ "maybe",
1690+ "partial",
1691+ "prelude",
1692+ "tuples"
1693+ ]
1694+ },
1695+ "unicode": {
1696+ "type": "registry",
1697+ "version": "6.0.0",
1698+ "integrity": "sha256-5KugCNyYxscmZpnMbssOQA96XimuBN/bjHpdrtd5qaY=",
1699+ "dependencies": [
1700+ "arrays",
1701+ "enums",
1702+ "integers",
1703+ "maybe",
1704+ "partial",
1705+ "prelude",
1706+ "strings",
1707+ "unsafe-coerce"
1708+ ]
1709+ },
1710+ "unsafe-coerce": {
1711+ "type": "registry",
1712+ "version": "6.0.0",
1713+ "integrity": "sha256-0L1QsaY20OILjfU5TV72d3U/tSjhmL9hJ32WMp857Lk=",
1714+ "dependencies": []
1715+ },
1716+ "variant": {
1717+ "type": "registry",
1718+ "version": "8.0.0",
1719+ "integrity": "sha256-Ydrgl8liWEwYQOWW76PdZtg3vxKpoKgsnmFyTLgZkoU=",
1720+ "dependencies": [
1721+ "control",
1722+ "enums",
1723+ "foldable-traversable",
1724+ "lists",
1725+ "maybe",
1726+ "partial",
1727+ "prelude",
1728+ "type-equality",
1729+ "unsafe-coerce"
1730+ ]
1731+ },
1732+ "yoga-tree": {
1733+ "type": "registry",
1734+ "version": "1.0.0",
1735+ "integrity": "sha256-s8rIVEQkRi1VrMc92T9ceXcY0X6r5A4QqT6f7GgmDQI=",
1736+ "dependencies": [
1737+ "arrays",
1738+ "control",
1739+ "foldable-traversable",
1740+ "free",
1741+ "maybe",
1742+ "prelude",
1743+ "tailrec"
1744+ ]
1745+ }
1746+ }
1747+}
spago.yamlnew file+52
@@ -0,0 +1,52 @@
1+package:
2+ name: yoga-json
3+ dependencies:
4+ - arrays: ">=7.3.0 <8.0.0"
5+ - bifunctors: ">=6.0.0 <7.0.0"
6+ - control: ">=6.0.0 <7.0.0"
7+ - datetime: ">=6.1.0 <7.0.0"
8+ - effect: ">=4.0.0 <5.0.0"
9+ - either: ">=6.1.0 <7.0.0"
10+ - exceptions: ">=6.1.0 <7.0.0"
11+ - foldable-traversable: ">=6.0.0 <7.0.0"
12+ - foreign: ">=7.0.0 <8.0.0"
13+ - foreign-object: ">=4.1.0 <5.0.0"
14+ - free: ">=7.1.0 <8.0.0"
15+ - identity: ">=6.0.0 <7.0.0"
16+ - integers: ">=6.0.0 <7.0.0"
17+ - js-bigints: ">=2.2.1 <3.0.0"
18+ - js-date: ">=8.0.0 <9.0.0"
19+ - lists: ">=7.0.0 <8.0.0"
20+ - maybe: ">=6.0.0 <7.0.0"
21+ - newtype: ">=5.0.0 <6.0.0"
22+ - nullable: ">=6.0.0 <7.0.0"
23+ - numbers: ">=9.0.1 <10.0.0"
24+ - ordered-collections: ">=3.2.0 <4.0.0"
25+ - partial: ">=4.0.0 <5.0.0"
26+ - prelude: ">=6.0.2 <7.0.0"
27+ - record: ">=4.0.0 <5.0.0"
28+ - safe-coerce: ">=2.0.0 <3.0.0"
29+ - strings: ">=6.0.1 <7.0.0"
30+ - transformers: ">=6.1.0 <7.0.0"
31+ - tuples: ">=7.0.0 <8.0.0"
32+ - typelevel-prelude: ">=7.0.0 <8.0.0"
33+ - unsafe-coerce: ">=6.0.0 <7.0.0"
34+ - variant: ">=8.0.0 <9.0.0"
35+ - yoga-tree: ">=1.0.0 <2.0.0"
36+ test:
37+ main: Test.Main
38+ dependencies:
39+ - spec
40+ - spec-node
41+ - spec-discovery
42+ - strings-extra
43+
44+ publish:
45+ version: 5.2.2
46+ license: MIT
47+ location:
48+ githubOwner: rowtype-yoga
49+ githubRepo: purescript-yoga-json
50+workspace:
51+ packageSet:
52+ registry: 63.2.1
src/Yoga/JSON.js+1
@@ -16,3 +16,4 @@ function replacer(key, value) {
1616}
1717
1818export const _unsafeStringify = (data) => JSON.stringify(data, replacer);
19+export const _unsafePrettyStringify = spaces => data => JSON.stringify(data, replacer, spaces);
src/Yoga/JSON.purs+115−16
@@ -4,6 +4,7 @@ module Yoga.JSON
44 , readJSON'
55 , readJSON_
66 , writeJSON
7+ , writePrettyJSON
78 , write
89 , read
910 , read'
@@ -11,7 +12,6 @@ module Yoga.JSON
1112 , parseJSON
1213 , undefined
1314 , unsafeStringify
14−
1515 , class ReadForeign
1616 , readImpl
1717 , class ReadForeignFields
@@ -21,25 +21,25 @@ module Yoga.JSON
2121 , class ReadTuple
2222 , readTupleImpl
2323 , tupleSize
24−
2524 , class WriteForeign
2625 , writeImpl
2726 , class WriteForeignFields
2827 , writeImplFields
2928 , class WriteForeignVariant
3029 , writeVariantImpl
31−
3230 ) where
3331
3432import Prelude
3533
3634import Control.Alt ((<|>))
3735import Control.Apply (lift2)
36+import Control.Comonad.Cofree as Cofree
3837import Control.Monad.Except (ExceptT(..), except, runExcept, throwError, withExcept)
3938import Data.Array as Array
4039import Data.Array.NonEmpty (NonEmptyArray, fromArray, toArray)
4140import Data.Bifunctor (lmap)
4241import Data.DateTime (DateTime)
42+import Data.DateTime.Instant (Instant, instant, unInstant)
4343import Data.Either (Either(..), hush, note)
4444import Data.Foldable (class Foldable, foldl)
4545import Data.FoldableWithIndex (foldrWithIndex)
@@ -52,10 +52,15 @@ import Data.List.NonEmpty (NonEmptyList, singleton)
5252import Data.Map (Map)
5353import Data.Map as Map
5454import Data.Maybe (Maybe(..), fromMaybe, fromMaybe', maybe)
55−import Data.Newtype (class Newtype)
55+import Data.Newtype (class Newtype, unwrap, wrap)
5656import Data.Nullable (Nullable, toMaybe, toNullable)
5757import Data.Number as Number
58+import Data.Set (Set)
59+import Data.Set as Set
60+import Data.String.NonEmpty.Internal (NonEmptyString)
61+import Data.String.NonEmpty.Internal as NonEmptyString
5862import Data.Symbol (class IsSymbol, reflectSymbol)
63+import Data.Time.Duration (Days, Hours, Milliseconds, Minutes, Seconds)
5964import Data.Traversable (traverse)
6065import Data.Tuple (Tuple(..))
6166import Data.Variant (Variant, inj, on)
@@ -63,11 +68,11 @@ import Effect.Exception (message, try)
6368import Effect.Uncurried as EU
6469import Effect.Unsafe (unsafePerformEffect)
6570import Foreign (F, Foreign, ForeignError(..), MultipleErrors, fail, isNull, isUndefined, readArray, readBoolean, readChar, readInt, readNull, readNumber, readString, tagOf, unsafeFromForeign, unsafeReadTagged, unsafeToForeign)
66−import Foreign.Index (readProp)
71+import Foreign.Index (hasOwnProperty, readProp)
6772import Foreign.Object (Object)
6873import Foreign.Object as Object
69−import Js.BigInt.BigInt (BigInt)
70−import Js.BigInt.BigInt (fromInt, fromNumber, fromString) as BigInt
74+import JS.BigInt (BigInt)
75+import JS.BigInt (fromInt, fromNumber, fromString, toString) as BigInt
7176import Partial.Unsafe (unsafeCrashWith)
7277import Prim.Row as Row
7378import Prim.RowList (class RowToList, Cons, Nil, RowList)
@@ -76,6 +81,8 @@ import Record.Builder (Builder)
7681import Record.Builder as Builder
7782import Type.Prelude (Proxy(..))
7883import Unsafe.Coerce (unsafeCoerce)
84+import Yoga.Tree (Tree)
85+import Yoga.Tree as Tree
7986
8087-- | An alias for the Either result of decoding
8188type E a = Either MultipleErrors a
@@ -83,7 +90,7 @@ type E a = Either MultipleErrors a
8390-- | Read a JSON string to a type `a` while returning a `MultipleErrors` if the
8491-- | parsing failed.
8592readJSON ∷
86− ∀ a.
93+ ∀ @a.
8794 ReadForeign a ⇒
8895 String →
8996 E a
@@ -91,7 +98,7 @@ readJSON = runExcept <<< (readImpl <=< parseJSON)
9198
9299-- | Read a JSON string to a type `a` using `F a`. Useful with record types.
93100readJSON' ∷
94− ∀ a.
101+ ∀ @a.
95102 ReadForeign a ⇒
96103 String →
97104 F a
@@ -100,7 +107,7 @@ readJSON' = readImpl <=< parseJSON
100107-- | Read a JSON string to a type `a` while returning `Nothing` if the parsing
101108-- | failed.
102109readJSON_ ∷
103− ∀ a.
110+ ∀ @a.
104111 ReadForeign a ⇒
105112 String →
106113 Maybe a
@@ -109,6 +116,9 @@ readJSON_ = hush <<< readJSON
109116-- | JSON.stringify
110117foreign import _unsafeStringify ∷ ∀ a. a → String
111118
119+-- | JSON.stringify with a number of spaces
120+foreign import _unsafePrettyStringify ∷ ∀ a. Int → a → String
121+
112122unsafeStringify ∷ ∀ a. a → String
113123unsafeStringify = _unsafeStringify
114124
@@ -120,6 +130,14 @@ writeJSON ∷
120130 String
121131writeJSON = _unsafeStringify <<< writeImpl
122132
133+writePrettyJSON ∷
134+ ∀ a.
135+ WriteForeign a ⇒
136+ Int →
137+ a →
138+ String
139+writePrettyJSON spaces = _unsafePrettyStringify spaces <<< writeImpl
140+
123141write ∷
124142 ∀ a.
125143 WriteForeign a ⇒
@@ -129,14 +147,14 @@ write = writeImpl
129147
130148-- | Read a Foreign value to a type
131149read ∷
132− ∀ a.
150+ ∀ @a.
133151 ReadForeign a ⇒
134152 Foreign →
135153 E a
136154read = runExcept <<< readImpl
137155
138156read' ∷
139− ∀ a.
157+ ∀ @a.
140158 ReadForeign a ⇒
141159 Foreign →
142160 F a
@@ -144,7 +162,7 @@ read' = readImpl
144162
145163-- | Read a Foreign value to a type, as a Maybe of type
146164read_ ∷
147− ∀ a.
165+ ∀ @a.
148166 ReadForeign a ⇒
149167 Foreign →
150168 Maybe a
@@ -212,6 +230,12 @@ instance ReadForeign BigInt where
212230instance ReadForeign String where
213231 readImpl = readString
214232
233+instance ReadForeign NonEmptyString where
234+ readImpl = readString >=>
235+ NonEmptyString.fromString
236+ >>> note (pure $ ForeignError "String must not be empty")
237+ >>> except
238+
215239instance ReadForeign Boolean where
216240 readImpl = readBoolean
217241
@@ -379,10 +403,13 @@ instance
379403 , ReadForeignVariant tail row
380404 ) ⇒
381405 ReadForeignVariant (Cons name ty tail) row where
382− readVariantImpl _ o = readVariantImpl (Proxy ∷ Proxy tail) o <|> ado
383− value ∷ ty ← readProp name o >>= readImpl
384− in inj namep value
406+ readVariantImpl _ o =
407+ if hasOwnProperty @String @Identity name o then rest <|> ado
408+ value ∷ ty ← readProp name o >>= readImpl
409+ in inj namep value
410+ else rest
385411 where
412+ rest = readVariantImpl (Proxy ∷ Proxy tail) o
386413 namep = Proxy ∷ Proxy name
387414 name = reflectSymbol namep
388415
@@ -402,6 +429,9 @@ instance WriteForeign Foreign where
402429instance WriteForeign String where
403430 writeImpl = unsafeToForeign
404431
432+instance WriteForeign NonEmptyString where
433+ writeImpl = unsafeToForeign
434+
405435instance WriteForeign Int where
406436 writeImpl = unsafeToForeign
407437
@@ -536,6 +566,8 @@ instance (WriteForeign a) ⇒ WriteForeign (Map String a) where
536566 writeImpl = foldrWithIndex Object.insert Object.empty >>> writeImpl
537567else instance (WriteForeign a) ⇒ WriteForeign (Map Int a) where
538568 writeImpl = foldrWithIndex (show >>> Object.insert) Object.empty >>> writeImpl
569+else instance (WriteForeign a) ⇒ WriteForeign (Map BigInt a) where
570+ writeImpl = foldrWithIndex (BigInt.toString >>> Object.insert) Object.empty >>> writeImpl
539571else instance (Newtype nt key, WriteForeign (Map key value)) ⇒ WriteForeign (Map nt value) where
540572 writeImpl = (unsafeCoerce ∷ (_ → Map key value)) >>> writeImpl
541573
@@ -543,9 +575,18 @@ instance (ReadForeign a) ⇒ ReadForeign (Map String a) where
543575 readImpl = (readImpl ∷ (_ → _ (Object a))) >>> map (foldrWithIndex Map.insert Map.empty)
544576else instance (ReadForeign a) ⇒ ReadForeign (Map Int a) where
545577 readImpl = (readImpl ∷ (_ → _ (Object a))) >>> map (foldrWithIndex (unsafeStringToInt >>> Map.insert) Map.empty)
578+else instance (ReadForeign a) ⇒ ReadForeign (Map BigInt a) where
579+ readImpl = (readImpl ∷ (_ → _ (Object a))) >>> map (foldrWithIndex (unsafeStringToBigInt >>> Map.insert) Map.empty)
546580else instance (Newtype nt key, ReadForeign (Map key value)) ⇒ ReadForeign (Map nt value) where
547581 readImpl = (readImpl ∷ (_ → _ (Map key value))) >>> map (unsafeCoerce ∷ (Map key value → Map nt value))
548582
583+-- Set instances
584+instance (WriteForeign a) ⇒ WriteForeign (Set a) where
585+ writeImpl set = writeImpl (Set.toUnfoldable set ∷ Array a)
586+
587+instance (Ord a, ReadForeign a) ⇒ ReadForeign (Set a) where
588+ readImpl f = Set.fromFoldable <$> (readImpl f ∷ F (Array a))
589+
549590-- Date instances
550591instance WriteForeign JSDate where
551592 writeImpl = JSDate.toISOString >>> unsafePerformEffect >>> writeImpl
@@ -562,10 +603,54 @@ instance ReadForeign DateTime where
562603 >>> note (pure $ ForeignError "Invalid date time")
563604 >>> except
564605
606+instance WriteForeign Instant where
607+ writeImpl = unInstant >>> writeImpl
608+
609+instance ReadForeign Instant where
610+ readImpl f = do
611+ millis ← readImpl f
612+ case instant millis of
613+ Nothing → except $ Left (pure $ ForeignError "Invalid instant")
614+ Just ins → pure ins
615+
616+instance WriteForeign Milliseconds where
617+ writeImpl = unwrap >>> writeImpl
618+
619+instance ReadForeign Milliseconds where
620+ readImpl = readImpl >>> map wrap
621+
622+instance WriteForeign Seconds where
623+ writeImpl = unwrap >>> writeImpl
624+
625+instance ReadForeign Seconds where
626+ readImpl = readImpl >>> map wrap
627+
628+instance WriteForeign Minutes where
629+ writeImpl = unwrap >>> writeImpl
630+
631+instance ReadForeign Minutes where
632+ readImpl = readImpl >>> map wrap
633+
634+instance WriteForeign Hours where
635+ writeImpl = unwrap >>> writeImpl
636+
637+instance ReadForeign Hours where
638+ readImpl = readImpl >>> map wrap
639+
640+instance WriteForeign Days where
641+ writeImpl = unwrap >>> writeImpl
642+
643+instance ReadForeign Days where
644+ readImpl = readImpl >>> map wrap
645+
565646unsafeStringToInt ∷ String → Int
566647unsafeStringToInt = Int.fromString >>>
567648 (fromMaybe' \_ → unsafeCrashWith "impossible")
568649
650+unsafeStringToBigInt ∷ String → BigInt
651+unsafeStringToBigInt = BigInt.fromString >>>
652+ (fromMaybe' \_ → unsafeCrashWith "impossible")
653+
569654sequenceCombining ∷
570655 ∀ f a.
571656 Monoid (f a) ⇒
@@ -582,3 +667,17 @@ sequenceCombining = foldl fn (Right mempty) >>> except
582667 Left errs, Right _ → Left errs
583668 Right values, Right value → Right (values <> pure value)
584669 Right _, Left errs → Left errs
670+
671+instance WriteForeign a ⇒ WriteForeign (Tree a) where
672+ writeImpl ∷ Tree a → Foreign
673+ writeImpl t = write { value: Cofree.head t, children }
674+ where
675+ tail = Cofree.tail t
676+ children = if Array.null tail then Nothing else Just (writeImpl <$> tail)
677+
678+instance ReadForeign a ⇒ ReadForeign (Tree a) where
679+ readImpl f = do
680+ { value, children } ∷ { value ∷ a, children ∷ Maybe (Array Foreign) } ← readImpl f
681+ case children of
682+ Nothing → pure (Tree.leaf value)
683+ Just cs → traverse readImpl cs <#> Tree.mkTree value
src/Yoga/JSON/Derive.pursnew file+13
@@ -0,0 +1,13 @@
1+module Yoga.JSON.Derive where
2+
3+import Prelude
4+
5+import Foreign (Foreign, F)
6+import Safe.Coerce (class Coercible, coerce)
7+import Yoga.JSON (class ReadForeign, class WriteForeign, readImpl, writeImpl)
8+
9+writeVia ∷ ∀ @via a. (Coercible a via) ⇒ WriteForeign via ⇒ a → Foreign
10+writeVia = writeImpl <<< (coerce ∷ _ → via)
11+
12+readVia ∷ ∀ @via a. (Coercible a via) ⇒ ReadForeign via ⇒ Foreign → F a
13+readVia fgn = readImpl fgn # map (coerce ∷ via → _)
src/Yoga/JSON/Error.purs+7
@@ -3,6 +3,10 @@ module Yoga.JSON.Error where
33import Prelude
44
55import Foreign (ForeignError(..))
6+import Data.Semigroup.Foldable (intercalateMap)
7+import Data.Bifunctor (lmap)
8+import Yoga.JSON (E)
9+import Data.Either (Either)
610
711toJSONPath ∷ ForeignError → String
812toJSONPath fe = "$" <> path
@@ -20,6 +24,9 @@ renderHumanError = errorToJSON >>> toHuman
2024 where
2125 toHuman { message, path } = message <> " at " <> path
2226
27+withStringErrors :: forall a. E a -> Either String a
28+withStringErrors = lmap (intercalateMap "\n" renderHumanError)
29+
2330errorToJSON ∷
2431 ForeignError →
2532 { message ∷ String
test.dhalldeleted−15
@@ -1,15 +0,0 @@
1−let conf = ./spago.dhall
2−
3−in conf
4− // { sources = conf.sources # [ "test/**/*.purs" ]
5− , dependencies =
6− conf.dependencies
7− # [ "spec"
8− , "spec-discovery"
9− , "aff"
10− , "strings-extra"
11− , "newtype"
12− , "debug"
13− , "now"
14− ]
15− }
test/BasicsSpec.purs+98−8
@@ -3,7 +3,7 @@ module Test.BasicsSpec where
33import Prelude
44
55import Data.Array.NonEmpty as NEA
6−import Data.Either (Either(..))
6+import Data.Either (Either(..), isLeft)
77import Data.Foldable (traverse_)
88import Data.JSDate as JSDate
99import Data.List as List
@@ -12,14 +12,18 @@ import Data.Map as Map
1212import Data.Maybe (Maybe(..), fromJust, fromMaybe')
1313import Data.Newtype (class Newtype, un)
1414import Data.Nullable as Nullable
15+import Data.Set as Set
16+import Data.String.NonEmpty (NonEmptyString, nes)
17+import Data.Time.Duration (Days(..), Hours(..), Milliseconds(..), Minutes(..), Seconds(..))
1518import Data.Tuple (Tuple(..))
1619import Data.Tuple.Nested ((/\))
1720import Data.Variant (Variant, inj)
1821import Effect.Class (liftEffect)
1922import Effect.Now (nowDateTime)
23+import Foreign (ForeignError(..))
2024import Foreign.Object as Object
21−import Js.BigInt.BigInt (BigInt)
22−import Js.BigInt.BigInt as BigInt
25+import JS.BigInt (BigInt)
26+import JS.BigInt as BigInt
2327import Partial.Unsafe (unsafeCrashWith, unsafePartial)
2428import Test.Spec (Spec, describe, it)
2529import Test.Spec.Assertions (shouldEqual)
@@ -27,9 +31,10 @@ import Test.Util (roundtrips)
2731import Type.Proxy (Proxy(..))
2832import Yoga.JSON (class ReadForeign, class WriteForeign, readJSON, writeJSON)
2933import Yoga.JSON.Variant (TaggedVariant(..), UntaggedVariant(..))
34+import Yoga.Tree (Tree, mkLeaf, mkTree, showTree)
3035
3136spec ∷ Spec Unit
32−spec = describe "En- and decoding" $ do
37+spec = describe "En- and decoding" do
3338
3439 describe "works on primitive types" do
3540 it "roundtrips Number" $ roundtrips 3.1414
@@ -48,7 +53,8 @@ spec = describe "En- and decoding" $ do
4853 roundtrips ((Right 3) ∷ Either String Int)
4954 writeJSON (Right 3 ∷ Either Int Int) `shouldEqual` """{"value":3,"type":"right"}"""
5055 writeJSON (Left true ∷ Either Boolean Int) `shouldEqual` """{"value":true,"type":"left"}"""
51− it "roundtrips Tuple" $ do
56+
57+ it "roundtrips Tuple" do
5258 roundtrips (Tuple 3 4)
5359 roundtrips ("4" /\ 8 /\ Just 4)
5460 it "roundtrips Array" $ traverse_ roundtrips [ [ "A", "B" ], [] ]
@@ -62,6 +68,9 @@ spec = describe "En- and decoding" $ do
6268 $ roundtrips (Map.fromFoldable [ (Stringy "A" /\ "B"), (Stringy "C" /\ "D") ])
6369 it "roundtrips Map with Int newtype keys"
6470 $ roundtrips (Map.fromFoldable [ (Inty 4 /\ "B"), (Inty 8 /\ "D") ])
71+ it "roundtrips Map with BigInt newtype keys"
72+ $ roundtrips (Map.fromFoldable [ (BigInty (BigInt.fromInt 5) /\ "B"), (BigInty big /\ "D") ])
73+ it "roundtrips Set String" $ roundtrips (Set.fromFoldable [ "A", "B", "C" ])
6574 it "roundtrips BigInt" do
6675 let
6776 inputStr = """{ "number":1, "big": 18014398509481982, "mediumBig": 1652955871799, "smallBig": 10 }"""
@@ -75,7 +84,6 @@ spec = describe "En- and decoding" $ do
7584 it "roundtrips BigInt (2)" do
7685 let
7786 smallBig = BigInt.fromInt 10
78− big = unsafePartial $ fromJust $ BigInt.fromString "18014398509481982"
7987
8088 expected = { big, smallBig }
8189 json = writeJSON expected
@@ -102,10 +110,33 @@ spec = describe "En- and decoding" $ do
102110 let expected = show "2022-01-01T00:00:00.000Z"
103111 result `shouldEqual` expected
104112
113+ describe "works with Durations" do
114+ it "roundtrips" do
115+ let millis = Milliseconds 16.67
116+ roundtrips millis
117+ writeJSON millis `shouldEqual` "16.67"
118+
119+ let seconds = Seconds 60.0
120+ roundtrips seconds
121+ writeJSON seconds `shouldEqual` "60"
122+
123+ let minutes = Minutes 10.0
124+ roundtrips minutes
125+ writeJSON minutes `shouldEqual` "10"
126+
127+ let hours = Hours 24.0
128+ roundtrips hours
129+ writeJSON hours `shouldEqual` "24"
130+
131+ let days = Days 365.0
132+ roundtrips days
133+ writeJSON days `shouldEqual` "365"
134+
105135 describe "works on record types" do
106136 it "roundtrips" do
107137 roundtrips { a: 12, b: "54" }
108138 roundtrips { a: 12, b: { c: "54" } }
139+ roundtrips {}
109140
110141 describe "works on newtypes" do
111142 it "roundtrips" do
@@ -113,9 +144,30 @@ spec = describe "En- and decoding" $ do
113144
114145 describe "works on variant types" do
115146 it "roundtrips" do
116− roundtrips (inj (Proxy ∷ _ "erwin") "e" ∷ Variant ("erwin" ∷ String))
147+ let input = inj (Proxy ∷ _ "a") {} ∷ Variant (a ∷ {}, b ∷ {})
148+ let asJSON = writeJSON input
149+ readJSON asJSON `shouldEqual` Right input
150+
151+ let input2 = inj (Proxy ∷ _ "b") {} ∷ Variant (a ∷ {}, b ∷ {})
152+ let asJSON2 = writeJSON input2
153+ readJSON asJSON2 `shouldEqual` Right input2
154+
155+ roundtrips (inj (Proxy ∷ _ "erwin") "e" ∷ Variant (erwin ∷ String))
117156 roundtrips (inj (Proxy ∷ _ "jackie") 7 ∷ Variant ExampleVariant)
118157
158+ it "does not select an absent optional branch" do
159+ let expected = inj (Proxy ∷ _ "a") 42 ∷ Variant (a ∷ Int, b ∷ Maybe Int)
160+ readJSON """{"a":42}""" `shouldEqual` Right expected
161+
162+ it "accepts an explicitly null optional branch" do
163+ let expected = inj (Proxy ∷ _ "b") Nothing ∷ Variant (a ∷ Int, b ∷ Maybe Int)
164+ readJSON """{"b":null}""" `shouldEqual` Right expected
165+
166+ it "rejects objects without a matching variant key" do
167+ traverse_
168+ (\json → isLeft (readJSON json ∷ _ (Variant (a ∷ {}, b ∷ {}))) `shouldEqual` true)
169+ [ "{}", """{"unknown":{}}""" ]
170+
119171 describe "works on tagged variant types" do
120172 it "roundtrips" do
121173 roundtrips (TaggedVariant (erwin "e") ∷ TaggedVariant "super" "hans" (Erwin ()))
@@ -133,13 +185,39 @@ spec = describe "En- and decoding" $ do
133185 roundtrips (UntaggedVariant (erwin "e") ∷ UntaggedVariant (Erwin ()))
134186 let bareVariant = erwin "e"
135187 let res = writeJSON (UntaggedVariant bareVariant ∷ UntaggedVariant ExampleVariant)
136− let expected = """"e""""
188+ let expected = "\"e\""
137189 res `shouldEqual` expected
138190 let
139191 parsed ∷ _ (UntaggedVariant ExampleVariant)
140192 parsed = readJSON expected
141193 (un UntaggedVariant <$> parsed) `shouldEqual` Right bareVariant
142194
195+ describe "works on non empty strings" do
196+ it "roundtrips NonEmptyString" do
197+ roundtrips (nes (Proxy ∷ Proxy "Non-Empty"))
198+ it "fails to decode empty strings" do
199+ let (result ∷ (Either _ NonEmptyString)) = readJSON (show "")
200+ result `shouldEqual` Left (pure $ ForeignError "String must not be empty")
201+
202+ describe "works on trees" do
203+ it "roundtrips" do
204+ let t = mkTree "a" [ mkTree "b" [ mkLeaf "c", mkLeaf "d" ] ]
205+ roundtrips (ShowTree t)
206+
207+ it "encodes as expected" do
208+ let t = mkTree "a" [ mkTree "b" [ mkLeaf "c", mkLeaf "d" ] ]
209+ writeJSON (ShowTree t) `shouldEqual`
210+ """{"value":"a","children":[{"value":"b","children":[{"value":"c"},{"value":"d"}]}]}"""
211+
212+newtype ShowTree = ShowTree (Tree String)
213+
214+instance Show ShowTree where
215+ show (ShowTree t) = showTree t
216+
217+derive newtype instance WriteForeign ShowTree
218+derive newtype instance ReadForeign ShowTree
219+derive newtype instance Eq ShowTree
220+
143221type ExampleVariant = ("erwin" ∷ String, "jackie" ∷ Int)
144222type ExampleTaggedVariant t v = TaggedVariant t v ExampleVariant
145223
@@ -165,3 +243,15 @@ derive newtype instance Eq Inty
165243derive newtype instance Ord Inty
166244derive newtype instance WriteForeign Inty
167245derive newtype instance ReadForeign Inty
246+
247+newtype BigInty = BigInty BigInt
248+
249+derive instance Newtype BigInty _
250+derive newtype instance Show BigInty
251+derive newtype instance Eq BigInty
252+derive newtype instance Ord BigInty
253+derive newtype instance WriteForeign BigInty
254+derive newtype instance ReadForeign BigInty
255+
256+big ∷ BigInt
257+big = unsafePartial $ fromJust $ BigInt.fromString "18014398509481982"
test/GenericsSpec.purs+1−1
@@ -14,7 +14,7 @@ import Yoga.JSON.Generics as GenericTaggedSum
1414import Yoga.JSON.Generics.EnumSumRep as Enum
1515
1616spec ∷ Spec Unit
17−spec = describe "Generics" $ do
17+spec = describe "Generics" do
1818
1919 describe "Enum" do
2020 describe "MyEnum = Enum1 | Enum2 | Enum3" do
test/Main.purs+3−2
@@ -4,11 +4,12 @@ import Prelude
44
55import Effect (Effect)
66import Effect.Aff (launchAff_)
7+import Effect.Class (liftEffect)
78import Test.Spec.Discovery (discover)
89import Test.Spec.Reporter (consoleReporter)
9−import Test.Spec.Runner (runSpec)
10+import Test.Spec.Runner.Node (runSpecAndExitProcess)
1011
1112main ∷ Effect Unit
1213main = launchAff_ $
1314 discover """\..*Spec"""
14− >>= runSpec [ consoleReporter ]
15+ >>= runSpecAndExitProcess [ consoleReporter ] >>> liftEffect
test/WriteViaSpec.pursnew file+42
@@ -0,0 +1,42 @@
1+module Test.WriteViaSpec where
2+
3+import Prelude
4+
5+import Data.Either (Either(..))
6+import Test.Spec (Spec, describe, it)
7+import Test.Spec.Assertions (shouldEqual)
8+import Yoga.JSON (class ReadForeign, class WriteForeign)
9+import Yoga.JSON as JSON
10+import Yoga.JSON.Derive (readVia, writeVia)
11+
12+spec ∷ Spec Unit
13+spec = describe "En- and decoding with Coercibles" do
14+ let referenceJSON = """{"myString":"A","myInt":3}"""
15+ it "writing works" do
16+ let myRecord = MyRecord { myInt: MyInt 3, myString: MyString "A" }
17+ JSON.writeJSON myRecord `shouldEqual` referenceJSON
18+ it "reading works" do
19+ JSON.readJSON referenceJSON `shouldEqual` Right (MyRecord { myInt: MyInt 3, myString: MyString "A" })
20+
21+newtype MyInt = MyInt Int
22+newtype MyString = MyString String
23+
24+newtype MyRecord = MyRecord
25+ { myInt ∷ MyInt
26+ , myString ∷ MyString
27+ }
28+
29+instance WriteForeign MyRecord where
30+ writeImpl = writeVia @{ myInt ∷ Int, myString ∷ String }
31+
32+instance ReadForeign MyRecord where
33+ readImpl = readVia @{ myInt ∷ Int, myString ∷ String }
34+
35+-- Below instances are just necessary for the tests to compile
36+
37+instance Show MyRecord where
38+ show = JSON.writeJSON
39+
40+derive instance Eq MyRecord
41+derive instance Eq MyInt
42+derive instance Eq MyString