git.iko.soy/rowtype-yoga/purescript-yoga-json
on main help sign in
.github/workflows/ci.yml+6−4
since splitsnapshots
unifiedsplit
@@ -13,13 +13,15 @@ jobs:
13 - uses: actions/checkout@v2
13 - uses: actions/checkout@v2
14
14
15 - uses: purescript-contrib/setup-purescript@main
15 - uses: purescript-contrib/setup-purescript@main
16+ with:
17+ spago: "unstable"
16
18
17 - uses: actions/setup-node@v2
19 - uses: actions/setup-node@v2
18 with:
20 with:
19− node-version: "14"
21+ node-version: "20"
20
22
21 - name: Cache PureScript dependencies
23 - name: Cache PureScript dependencies
22− uses: actions/cache@v2
24+ uses: actions/cache@v4
23 # This cache uses the .dhall files to know when it should reinstall
25 # This cache uses the .dhall files to know when it should reinstall
24 # and rebuild packages. It caches both the installed packages from
26 # and rebuild packages. It caches both the installed packages from
25 # the `.spago` directory and compilation artifacts from the `output`
27 # the `.spago` directory and compilation artifacts from the `output`
@@ -27,11 +29,11 @@ jobs:
27 # have changed. If you do not want to cache compiled output, remove
29 # have changed. If you do not want to cache compiled output, remove
28 # the `output` path.
30 # the `output` path.
29 with:
31 with:
30− key: ${{ runner.os }}-spago-${{ hashFiles('**/*.dhall') }}
32+ key: ${{ runner.os }}-spago-${{ hashFiles('**/*.yaml') }}
31 path: |
33 path: |
32 .spago
34 .spago
33 output
35 output
34 - run: npm install
36 - run: npm install
35 - run: spago build
37 - run: spago build
36
38
37− - run: spago -x test.dhall test
39+ - run: npm run coverage
.gitignore+5
@@ -6,3 +6,8 @@
6/.purs*
6/.purs*
7/.psa*
7/.psa*
8/.spago/
8/.spago/
9+/.nyc_output/
10+/coverage/
11+/.idea/
12+.spec-results
13+.DS_Store
.nycrc.jsonnew file+8
@@ -0,0 +1,8 @@
1+{
2+ "all": true,
3+ "extension": [".purs"],
4+ "include": [ "src/**/*.purs"],
5+ "exclude": [ "src/Yoga/JSON/Generics.purs"],
6+ "excludeAfterRemap": true,
7+ "sourceMap": true
8+}
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+136−26
@@ -1,52 +1,162 @@
1−# 🐏👑 purescript-yoga-json
1+# purescript-yoga-json
2
2
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.
4
4
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.
5## Table of Contents
7## Table of Contents
8+* [features](#features)
9+* [installation](#installation)
6* [usage](#usage)
10* [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+```
8
24
9## Usage
25## Usage
10
26
27+`purescript-yoga-json` basically provides two functions `writeJSON` and `readJSON`.
28+
29+Use `writeJSON` to serialise a type to a JSON string:
30+
11```purescript
31```purescript
12import Yoga.JSON as JSON
32import Yoga.JSON as JSON
13
33
14serialised :: String
34serialised :: String
15serialised =
35serialised =
16 JSON.writeJSON { first_name: "Lola", last_name: "Flores" }
36 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+
64+```
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
70+
71+data MyEnum = Enum1 | Enum2 | Enum3
17```
72```
18
73
19−Check out the tests for how to encode/decode increasingly complex types.
74+Now, we need to derive a `Generic` instance for it:
20
75
21−## Migrate from `purescript-simple-json`
76+```
77+derive instance Generic MyEnum _
78+-- and optionally a Show instance
79+instance Show MyEnum where
80+ show = genericShow
81+```
22
82
23−`purescript-yoga-json` is a drop-in replacement for `purescript-simple-json`. Just change the imports from `Simple.JSON` to `Yoga.JSON`.
83+Next, we define a `WriteForeign` instance and implement the `writeImpl` function using `genericWriteForeignEnum Enum.defaultOptions`.
24
84
25−## Differences to `simple-json`
85+```purescript
86+instance WriteForeign MyEnum
87+ where
88+ writeImpl = genericWriteForeignEnum Enum.defaultOptions
89+```
26
90
27−### Tuples
91+Similarly, we implement the `ReadForeign` instance using `genericReadForeignEnum Enum.defaultOptions`
28−There is an inbuilt codec for `Tuple`s thanks to @ursi
92+```purescript
93+instance ReadForeign MyEnum
94+ where
95+ readImpl = genericReadForeignEnum Enum.defaultOptions
96+```
29
97
30−### Generics
98+That's all, we can now serialise our data type:
31−It includes @justinwoo's codecs for en- and decoding generics inspired by
99+```purescript
32−[simple-json-generics](https://github.com/justinwoo/purescript-simple-json-generics)
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+```
33
109
34−### BigInts
110+### Writing custom codecs
35−It can *read* bigints (if you install `big-integer` as a JS dependency).
36
111
37−### 💣 Cannot write bigints as bigints but only strings
112+In order to write your own, custom codecs you will need to provide instances for `WriteForeign` and `ReadForeign`.
38−It seems that there is no way to write bigints in JavaScript except for writing your own `JSON.stringify`.
39
113
40−### 💣 The Variant Codec is different
114+Let's see an example. We define a simple data type `TrafficLight` that has three data constructors `Red`, `Yellow` and `Green`:
41−If you want to emulate `simple-json`'s format you may use the newtype `TaggedVariant`
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"`.
42
119
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:
43```purescript
121```purescript
44−type YourVariantRow = ( a :: Int, b :: String )
122+instance WriteForeign TrafficLight where
45−type YourVariant = Variant YourVariantRow
123+ writeImpl Red = writeImpl "red"
46−x :: YourVariant
124+ writeImpl Yellow = writeImpl "yellow"
47−x = inj (Proxy :: Proxy "a") 5
125+ writeImpl Green = writeImpl "green"
48−-- encoded = writeJSON x
126+```
49−-- ^ Let's say you had this before
127+This works, because `yoga-json` already knows how to serialise a `String`.
50−-- You can now do:
128+
51−encoded = writeJSON (TaggedVariant "type" "value" x)
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.
130+
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:
132+
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+```
146+
147+Now we can serialise our data type:
148+```purescript
149+serialised = writeJSON { "trafficLight": Red }
150+-- {"trafficLight":"red"}
151+```
152+
153+and deserialise it:
154+```purescript
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))
52```
162```
bower.jsondeleted−39
@@ -1,39 +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-control": "^v6.0.0",
20− "purescript-effect": "^v4.0.0",
21− "purescript-either": "^v6.1.0",
22− "purescript-exceptions": "^v6.0.0",
23− "purescript-foldable-traversable": "^v6.0.0",
24− "purescript-foreign": "^v7.0.0",
25− "purescript-foreign-object": "^v4.0.0",
26− "purescript-identity": "^v6.0.0",
27− "purescript-lists": "^v7.0.0",
28− "purescript-maybe": "^v6.0.0",
29− "purescript-newtype": "^v5.0.0",
30− "purescript-nullable": "^v6.0.0",
31− "purescript-partial": "^v4.0.0",
32− "purescript-prelude": "^v6.0.0",
33− "purescript-record": "^v4.0.0",
34− "purescript-transformers": "^v6.0.0",
35− "purescript-tuples": "^v7.0.0",
36− "purescript-typelevel-prelude": "^v7.0.0",
37− "purescript-variant": "^v8.0.0"
38− }
39−}
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+1140−10
@@ -4,24 +4,1154 @@
4 "requires": true,
4 "requires": true,
5 "packages": {
5 "packages": {
6 "": {
6 "": {
7+ "name": "purescript-yoga-json",
8+ "devDependencies": {
9+ "c8": "^7.12.0",
10+ "rimraf": "^3.0.2"
11+ }
12+ },
13+ "node_modules/@bcoe/v8-coverage": {
14+ "version": "0.2.3",
15+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
16+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
17+ "dev": true
18+ },
19+ "node_modules/@istanbuljs/schema": {
20+ "version": "0.1.3",
21+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
22+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
23+ "dev": true,
24+ "engines": {
25+ "node": ">=8"
26+ }
27+ },
28+ "node_modules/@jridgewell/resolve-uri": {
29+ "version": "3.1.0",
30+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
31+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
32+ "dev": true,
33+ "engines": {
34+ "node": ">=6.0.0"
35+ }
36+ },
37+ "node_modules/@jridgewell/sourcemap-codec": {
38+ "version": "1.4.14",
39+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
40+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
41+ "dev": true
42+ },
43+ "node_modules/@jridgewell/trace-mapping": {
44+ "version": "0.3.17",
45+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
46+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
47+ "dev": true,
48+ "dependencies": {
49+ "@jridgewell/resolve-uri": "3.1.0",
50+ "@jridgewell/sourcemap-codec": "1.4.14"
51+ }
52+ },
53+ "node_modules/@types/istanbul-lib-coverage": {
54+ "version": "2.0.4",
55+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
56+ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
57+ "dev": true
58+ },
59+ "node_modules/ansi-regex": {
60+ "version": "5.0.1",
61+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
62+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
63+ "dev": true,
64+ "engines": {
65+ "node": ">=8"
66+ }
67+ },
68+ "node_modules/ansi-styles": {
69+ "version": "4.3.0",
70+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
71+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
72+ "dev": true,
73+ "dependencies": {
74+ "color-convert": "^2.0.1"
75+ },
76+ "engines": {
77+ "node": ">=8"
78+ },
79+ "funding": {
80+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
81+ }
82+ },
83+ "node_modules/balanced-match": {
84+ "version": "1.0.2",
85+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
86+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
87+ "dev": true
88+ },
89+ "node_modules/brace-expansion": {
90+ "version": "1.1.11",
91+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
92+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
93+ "dev": true,
94+ "dependencies": {
95+ "balanced-match": "^1.0.0",
96+ "concat-map": "0.0.1"
97+ }
98+ },
99+ "node_modules/c8": {
100+ "version": "7.12.0",
101+ "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz",
102+ "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==",
103+ "dev": true,
104+ "dependencies": {
105+ "@bcoe/v8-coverage": "^0.2.3",
106+ "@istanbuljs/schema": "^0.1.3",
107+ "find-up": "^5.0.0",
108+ "foreground-child": "^2.0.0",
109+ "istanbul-lib-coverage": "^3.2.0",
110+ "istanbul-lib-report": "^3.0.0",
111+ "istanbul-reports": "^3.1.4",
112+ "rimraf": "^3.0.2",
113+ "test-exclude": "^6.0.0",
114+ "v8-to-istanbul": "^9.0.0",
115+ "yargs": "^16.2.0",
116+ "yargs-parser": "^20.2.9"
117+ },
118+ "bin": {
119+ "c8": "bin/c8.js"
120+ },
121+ "engines": {
122+ "node": ">=10.12.0"
123+ }
124+ },
125+ "node_modules/cliui": {
126+ "version": "7.0.4",
127+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
128+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
129+ "dev": true,
130+ "dependencies": {
131+ "string-width": "^4.2.0",
132+ "strip-ansi": "^6.0.0",
133+ "wrap-ansi": "^7.0.0"
134+ }
135+ },
136+ "node_modules/color-convert": {
137+ "version": "2.0.1",
138+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
139+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
140+ "dev": true,
141+ "dependencies": {
142+ "color-name": "~1.1.4"
143+ },
144+ "engines": {
145+ "node": ">=7.0.0"
146+ }
147+ },
148+ "node_modules/color-name": {
149+ "version": "1.1.4",
150+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
151+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
152+ "dev": true
153+ },
154+ "node_modules/concat-map": {
155+ "version": "0.0.1",
156+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
157+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
158+ "dev": true
159+ },
160+ "node_modules/convert-source-map": {
161+ "version": "1.9.0",
162+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
163+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
164+ "dev": true
165+ },
166+ "node_modules/cross-spawn": {
167+ "version": "7.0.6",
168+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
169+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
170+ "dev": true,
171+ "license": "MIT",
172+ "dependencies": {
173+ "path-key": "^3.1.0",
174+ "shebang-command": "^2.0.0",
175+ "which": "^2.0.1"
176+ },
177+ "engines": {
178+ "node": ">= 8"
179+ }
180+ },
181+ "node_modules/emoji-regex": {
182+ "version": "8.0.0",
183+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
184+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
185+ "dev": true
186+ },
187+ "node_modules/escalade": {
188+ "version": "3.1.1",
189+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
190+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
191+ "dev": true,
192+ "engines": {
193+ "node": ">=6"
194+ }
195+ },
196+ "node_modules/find-up": {
197+ "version": "5.0.0",
198+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
199+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
200+ "dev": true,
201+ "dependencies": {
202+ "locate-path": "^6.0.0",
203+ "path-exists": "^4.0.0"
204+ },
205+ "engines": {
206+ "node": ">=10"
207+ },
208+ "funding": {
209+ "url": "https://github.com/sponsors/sindresorhus"
210+ }
211+ },
212+ "node_modules/foreground-child": {
213+ "version": "2.0.0",
214+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
215+ "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
216+ "dev": true,
217+ "dependencies": {
218+ "cross-spawn": "^7.0.0",
219+ "signal-exit": "^3.0.2"
220+ },
221+ "engines": {
222+ "node": ">=8.0.0"
223+ }
224+ },
225+ "node_modules/fs.realpath": {
226+ "version": "1.0.0",
227+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
228+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
229+ "dev": true
230+ },
231+ "node_modules/get-caller-file": {
232+ "version": "2.0.5",
233+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
234+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
235+ "dev": true,
236+ "engines": {
237+ "node": "6.* || 8.* || >= 10.*"
238+ }
239+ },
240+ "node_modules/glob": {
241+ "version": "7.2.3",
242+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
243+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
244+ "dev": true,
245+ "dependencies": {
246+ "fs.realpath": "^1.0.0",
247+ "inflight": "^1.0.4",
248+ "inherits": "2",
249+ "minimatch": "^3.1.1",
250+ "once": "^1.3.0",
251+ "path-is-absolute": "^1.0.0"
252+ },
253+ "engines": {
254+ "node": "*"
255+ },
256+ "funding": {
257+ "url": "https://github.com/sponsors/isaacs"
258+ }
259+ },
260+ "node_modules/has-flag": {
261+ "version": "4.0.0",
262+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
263+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
264+ "dev": true,
265+ "engines": {
266+ "node": ">=8"
267+ }
268+ },
269+ "node_modules/html-escaper": {
270+ "version": "2.0.2",
271+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
272+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
273+ "dev": true
274+ },
275+ "node_modules/inflight": {
276+ "version": "1.0.6",
277+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
278+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
279+ "dev": true,
280+ "dependencies": {
281+ "once": "^1.3.0",
282+ "wrappy": "1"
283+ }
284+ },
285+ "node_modules/inherits": {
286+ "version": "2.0.4",
287+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
288+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
289+ "dev": true
290+ },
291+ "node_modules/is-fullwidth-code-point": {
292+ "version": "3.0.0",
293+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
294+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
295+ "dev": true,
296+ "engines": {
297+ "node": ">=8"
298+ }
299+ },
300+ "node_modules/isexe": {
301+ "version": "2.0.0",
302+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
303+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
304+ "dev": true
305+ },
306+ "node_modules/istanbul-lib-coverage": {
307+ "version": "3.2.0",
308+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
309+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
310+ "dev": true,
311+ "engines": {
312+ "node": ">=8"
313+ }
314+ },
315+ "node_modules/istanbul-lib-report": {
316+ "version": "3.0.0",
317+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
318+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
319+ "dev": true,
320+ "dependencies": {
321+ "istanbul-lib-coverage": "^3.0.0",
322+ "make-dir": "^3.0.0",
323+ "supports-color": "^7.1.0"
324+ },
325+ "engines": {
326+ "node": ">=8"
327+ }
328+ },
329+ "node_modules/istanbul-reports": {
330+ "version": "3.1.5",
331+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
332+ "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
333+ "dev": true,
334+ "dependencies": {
335+ "html-escaper": "^2.0.0",
336+ "istanbul-lib-report": "^3.0.0"
337+ },
338+ "engines": {
339+ "node": ">=8"
340+ }
341+ },
342+ "node_modules/locate-path": {
343+ "version": "6.0.0",
344+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
345+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
346+ "dev": true,
347+ "dependencies": {
348+ "p-locate": "^5.0.0"
349+ },
350+ "engines": {
351+ "node": ">=10"
352+ },
353+ "funding": {
354+ "url": "https://github.com/sponsors/sindresorhus"
355+ }
356+ },
357+ "node_modules/make-dir": {
358+ "version": "3.1.0",
359+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
360+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
361+ "dev": true,
362+ "dependencies": {
363+ "semver": "^6.0.0"
364+ },
365+ "engines": {
366+ "node": ">=8"
367+ },
368+ "funding": {
369+ "url": "https://github.com/sponsors/sindresorhus"
370+ }
371+ },
372+ "node_modules/minimatch": {
373+ "version": "3.1.2",
374+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
375+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
376+ "dev": true,
377+ "dependencies": {
378+ "brace-expansion": "^1.1.7"
379+ },
380+ "engines": {
381+ "node": "*"
382+ }
383+ },
384+ "node_modules/once": {
385+ "version": "1.4.0",
386+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
387+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
388+ "dev": true,
389+ "dependencies": {
390+ "wrappy": "1"
391+ }
392+ },
393+ "node_modules/p-limit": {
394+ "version": "3.1.0",
395+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
396+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
397+ "dev": true,
398+ "dependencies": {
399+ "yocto-queue": "^0.1.0"
400+ },
401+ "engines": {
402+ "node": ">=10"
403+ },
404+ "funding": {
405+ "url": "https://github.com/sponsors/sindresorhus"
406+ }
407+ },
408+ "node_modules/p-locate": {
409+ "version": "5.0.0",
410+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
411+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
412+ "dev": true,
413+ "dependencies": {
414+ "p-limit": "^3.0.2"
415+ },
416+ "engines": {
417+ "node": ">=10"
418+ },
419+ "funding": {
420+ "url": "https://github.com/sponsors/sindresorhus"
421+ }
422+ },
423+ "node_modules/path-exists": {
424+ "version": "4.0.0",
425+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
426+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
427+ "dev": true,
428+ "engines": {
429+ "node": ">=8"
430+ }
431+ },
432+ "node_modules/path-is-absolute": {
433+ "version": "1.0.1",
434+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
435+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
436+ "dev": true,
437+ "engines": {
438+ "node": ">=0.10.0"
439+ }
440+ },
441+ "node_modules/path-key": {
442+ "version": "3.1.1",
443+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
444+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
445+ "dev": true,
446+ "engines": {
447+ "node": ">=8"
448+ }
449+ },
450+ "node_modules/require-directory": {
451+ "version": "2.1.1",
452+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
453+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
454+ "dev": true,
455+ "engines": {
456+ "node": ">=0.10.0"
457+ }
458+ },
459+ "node_modules/rimraf": {
460+ "version": "3.0.2",
461+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
462+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
463+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
464+ "dev": true,
465+ "license": "ISC",
466+ "dependencies": {
467+ "glob": "^7.1.3"
468+ },
469+ "bin": {
470+ "rimraf": "bin.js"
471+ },
472+ "funding": {
473+ "url": "https://github.com/sponsors/isaacs"
474+ }
475+ },
476+ "node_modules/semver": {
477+ "version": "6.3.1",
478+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
479+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
480+ "dev": true,
481+ "license": "ISC",
482+ "bin": {
483+ "semver": "bin/semver.js"
484+ }
485+ },
486+ "node_modules/shebang-command": {
487+ "version": "2.0.0",
488+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
489+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
490+ "dev": true,
491+ "dependencies": {
492+ "shebang-regex": "^3.0.0"
493+ },
494+ "engines": {
495+ "node": ">=8"
496+ }
497+ },
498+ "node_modules/shebang-regex": {
499+ "version": "3.0.0",
500+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
501+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
502+ "dev": true,
503+ "engines": {
504+ "node": ">=8"
505+ }
506+ },
507+ "node_modules/signal-exit": {
508+ "version": "3.0.7",
509+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
510+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
511+ "dev": true
512+ },
513+ "node_modules/string-width": {
514+ "version": "4.2.3",
515+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
516+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
517+ "dev": true,
7 "dependencies": {
518 "dependencies": {
8− "big-integer": "^1.6.51"
519+ "emoji-regex": "^8.0.0",
520+ "is-fullwidth-code-point": "^3.0.0",
521+ "strip-ansi": "^6.0.1"
522+ },
523+ "engines": {
524+ "node": ">=8"
9 }
525 }
10 },
526 },
11− "node_modules/big-integer": {
527+ "node_modules/strip-ansi": {
12− "version": "1.6.51",
528+ "version": "6.0.1",
13− "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
529+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
14− "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
530+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
531+ "dev": true,
532+ "dependencies": {
533+ "ansi-regex": "^5.0.1"
534+ },
15 "engines": {
535 "engines": {
16− "node": ">=0.6"
536+ "node": ">=8"
537+ }
538+ },
539+ "node_modules/supports-color": {
540+ "version": "7.2.0",
541+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
542+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
543+ "dev": true,
544+ "dependencies": {
545+ "has-flag": "^4.0.0"
546+ },
547+ "engines": {
548+ "node": ">=8"
549+ }
550+ },
551+ "node_modules/test-exclude": {
552+ "version": "6.0.0",
553+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
554+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
555+ "dev": true,
556+ "dependencies": {
557+ "@istanbuljs/schema": "^0.1.2",
558+ "glob": "^7.1.4",
559+ "minimatch": "^3.0.4"
560+ },
561+ "engines": {
562+ "node": ">=8"
563+ }
564+ },
565+ "node_modules/v8-to-istanbul": {
566+ "version": "9.0.1",
567+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
568+ "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
569+ "dev": true,
570+ "dependencies": {
571+ "@jridgewell/trace-mapping": "^0.3.12",
572+ "@types/istanbul-lib-coverage": "^2.0.1",
573+ "convert-source-map": "^1.6.0"
574+ },
575+ "engines": {
576+ "node": ">=10.12.0"
577+ }
578+ },
579+ "node_modules/which": {
580+ "version": "2.0.2",
581+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
582+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
583+ "dev": true,
584+ "dependencies": {
585+ "isexe": "^2.0.0"
586+ },
587+ "bin": {
588+ "node-which": "bin/node-which"
589+ },
590+ "engines": {
591+ "node": ">= 8"
592+ }
593+ },
594+ "node_modules/wrap-ansi": {
595+ "version": "7.0.0",
596+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
597+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
598+ "dev": true,
599+ "dependencies": {
600+ "ansi-styles": "^4.0.0",
601+ "string-width": "^4.1.0",
602+ "strip-ansi": "^6.0.0"
603+ },
604+ "engines": {
605+ "node": ">=10"
606+ },
607+ "funding": {
608+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
609+ }
610+ },
611+ "node_modules/wrappy": {
612+ "version": "1.0.2",
613+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
614+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
615+ "dev": true
616+ },
617+ "node_modules/y18n": {
618+ "version": "5.0.8",
619+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
620+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
621+ "dev": true,
622+ "engines": {
623+ "node": ">=10"
624+ }
625+ },
626+ "node_modules/yargs": {
627+ "version": "16.2.0",
628+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
629+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
630+ "dev": true,
631+ "dependencies": {
632+ "cliui": "^7.0.2",
633+ "escalade": "^3.1.1",
634+ "get-caller-file": "^2.0.5",
635+ "require-directory": "^2.1.1",
636+ "string-width": "^4.2.0",
637+ "y18n": "^5.0.5",
638+ "yargs-parser": "^20.2.2"
639+ },
640+ "engines": {
641+ "node": ">=10"
642+ }
643+ },
644+ "node_modules/yargs-parser": {
645+ "version": "20.2.9",
646+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
647+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
648+ "dev": true,
649+ "engines": {
650+ "node": ">=10"
651+ }
652+ },
653+ "node_modules/yocto-queue": {
654+ "version": "0.1.0",
655+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
656+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
657+ "dev": true,
658+ "engines": {
659+ "node": ">=10"
660+ },
661+ "funding": {
662+ "url": "https://github.com/sponsors/sindresorhus"
17 }
663 }
18 }
664 }
19 },
665 },
20 "dependencies": {
666 "dependencies": {
21− "big-integer": {
667+ "@bcoe/v8-coverage": {
22− "version": "1.6.51",
668+ "version": "0.2.3",
23− "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
669+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
24− "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg=="
670+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
671+ "dev": true
672+ },
673+ "@istanbuljs/schema": {
674+ "version": "0.1.3",
675+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
676+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
677+ "dev": true
678+ },
679+ "@jridgewell/resolve-uri": {
680+ "version": "3.1.0",
681+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
682+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
683+ "dev": true
684+ },
685+ "@jridgewell/sourcemap-codec": {
686+ "version": "1.4.14",
687+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
688+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
689+ "dev": true
690+ },
691+ "@jridgewell/trace-mapping": {
692+ "version": "0.3.17",
693+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
694+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
695+ "dev": true,
696+ "requires": {
697+ "@jridgewell/resolve-uri": "3.1.0",
698+ "@jridgewell/sourcemap-codec": "1.4.14"
699+ }
700+ },
701+ "@types/istanbul-lib-coverage": {
702+ "version": "2.0.4",
703+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
704+ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
705+ "dev": true
706+ },
707+ "ansi-regex": {
708+ "version": "5.0.1",
709+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
710+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
711+ "dev": true
712+ },
713+ "ansi-styles": {
714+ "version": "4.3.0",
715+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
716+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
717+ "dev": true,
718+ "requires": {
719+ "color-convert": "^2.0.1"
720+ }
721+ },
722+ "balanced-match": {
723+ "version": "1.0.2",
724+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
725+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
726+ "dev": true
727+ },
728+ "brace-expansion": {
729+ "version": "1.1.11",
730+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
731+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
732+ "dev": true,
733+ "requires": {
734+ "balanced-match": "^1.0.0",
735+ "concat-map": "0.0.1"
736+ }
737+ },
738+ "c8": {
739+ "version": "7.12.0",
740+ "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz",
741+ "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==",
742+ "dev": true,
743+ "requires": {
744+ "@bcoe/v8-coverage": "^0.2.3",
745+ "@istanbuljs/schema": "^0.1.3",
746+ "find-up": "^5.0.0",
747+ "foreground-child": "^2.0.0",
748+ "istanbul-lib-coverage": "^3.2.0",
749+ "istanbul-lib-report": "^3.0.0",
750+ "istanbul-reports": "^3.1.4",
751+ "rimraf": "^3.0.2",
752+ "test-exclude": "^6.0.0",
753+ "v8-to-istanbul": "^9.0.0",
754+ "yargs": "^16.2.0",
755+ "yargs-parser": "^20.2.9"
756+ }
757+ },
758+ "cliui": {
759+ "version": "7.0.4",
760+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
761+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
762+ "dev": true,
763+ "requires": {
764+ "string-width": "^4.2.0",
765+ "strip-ansi": "^6.0.0",
766+ "wrap-ansi": "^7.0.0"
767+ }
768+ },
769+ "color-convert": {
770+ "version": "2.0.1",
771+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
772+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
773+ "dev": true,
774+ "requires": {
775+ "color-name": "~1.1.4"
776+ }
777+ },
778+ "color-name": {
779+ "version": "1.1.4",
780+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
781+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
782+ "dev": true
783+ },
784+ "concat-map": {
785+ "version": "0.0.1",
786+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
787+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
788+ "dev": true
789+ },
790+ "convert-source-map": {
791+ "version": "1.9.0",
792+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
793+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
794+ "dev": true
795+ },
796+ "cross-spawn": {
797+ "version": "7.0.6",
798+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
799+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
800+ "dev": true,
801+ "requires": {
802+ "path-key": "^3.1.0",
803+ "shebang-command": "^2.0.0",
804+ "which": "^2.0.1"
805+ }
806+ },
807+ "emoji-regex": {
808+ "version": "8.0.0",
809+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
810+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
811+ "dev": true
812+ },
813+ "escalade": {
814+ "version": "3.1.1",
815+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
816+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
817+ "dev": true
818+ },
819+ "find-up": {
820+ "version": "5.0.0",
821+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
822+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
823+ "dev": true,
824+ "requires": {
825+ "locate-path": "^6.0.0",
826+ "path-exists": "^4.0.0"
827+ }
828+ },
829+ "foreground-child": {
830+ "version": "2.0.0",
831+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
832+ "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
833+ "dev": true,
834+ "requires": {
835+ "cross-spawn": "^7.0.0",
836+ "signal-exit": "^3.0.2"
837+ }
838+ },
839+ "fs.realpath": {
840+ "version": "1.0.0",
841+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
842+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
843+ "dev": true
844+ },
845+ "get-caller-file": {
846+ "version": "2.0.5",
847+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
848+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
849+ "dev": true
850+ },
851+ "glob": {
852+ "version": "7.2.3",
853+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
854+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
855+ "dev": true,
856+ "requires": {
857+ "fs.realpath": "^1.0.0",
858+ "inflight": "^1.0.4",
859+ "inherits": "2",
860+ "minimatch": "^3.1.1",
861+ "once": "^1.3.0",
862+ "path-is-absolute": "^1.0.0"
863+ }
864+ },
865+ "has-flag": {
866+ "version": "4.0.0",
867+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
868+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
869+ "dev": true
870+ },
871+ "html-escaper": {
872+ "version": "2.0.2",
873+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
874+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
875+ "dev": true
876+ },
877+ "inflight": {
878+ "version": "1.0.6",
879+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
880+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
881+ "dev": true,
882+ "requires": {
883+ "once": "^1.3.0",
884+ "wrappy": "1"
885+ }
886+ },
887+ "inherits": {
888+ "version": "2.0.4",
889+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
890+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
891+ "dev": true
892+ },
893+ "is-fullwidth-code-point": {
894+ "version": "3.0.0",
895+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
896+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
897+ "dev": true
898+ },
899+ "isexe": {
900+ "version": "2.0.0",
901+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
902+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
903+ "dev": true
904+ },
905+ "istanbul-lib-coverage": {
906+ "version": "3.2.0",
907+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
908+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
909+ "dev": true
910+ },
911+ "istanbul-lib-report": {
912+ "version": "3.0.0",
913+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
914+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
915+ "dev": true,
916+ "requires": {
917+ "istanbul-lib-coverage": "^3.0.0",
918+ "make-dir": "^3.0.0",
919+ "supports-color": "^7.1.0"
920+ }
921+ },
922+ "istanbul-reports": {
923+ "version": "3.1.5",
924+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
925+ "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
926+ "dev": true,
927+ "requires": {
928+ "html-escaper": "^2.0.0",
929+ "istanbul-lib-report": "^3.0.0"
930+ }
931+ },
932+ "locate-path": {
933+ "version": "6.0.0",
934+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
935+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
936+ "dev": true,
937+ "requires": {
938+ "p-locate": "^5.0.0"
939+ }
940+ },
941+ "make-dir": {
942+ "version": "3.1.0",
943+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
944+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
945+ "dev": true,
946+ "requires": {
947+ "semver": "^6.0.0"
948+ }
949+ },
950+ "minimatch": {
951+ "version": "3.1.2",
952+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
953+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
954+ "dev": true,
955+ "requires": {
956+ "brace-expansion": "^1.1.7"
957+ }
958+ },
959+ "once": {
960+ "version": "1.4.0",
961+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
962+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
963+ "dev": true,
964+ "requires": {
965+ "wrappy": "1"
966+ }
967+ },
968+ "p-limit": {
969+ "version": "3.1.0",
970+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
971+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
972+ "dev": true,
973+ "requires": {
974+ "yocto-queue": "^0.1.0"
975+ }
976+ },
977+ "p-locate": {
978+ "version": "5.0.0",
979+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
980+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
981+ "dev": true,
982+ "requires": {
983+ "p-limit": "^3.0.2"
984+ }
985+ },
986+ "path-exists": {
987+ "version": "4.0.0",
988+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
989+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
990+ "dev": true
991+ },
992+ "path-is-absolute": {
993+ "version": "1.0.1",
994+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
995+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
996+ "dev": true
997+ },
998+ "path-key": {
999+ "version": "3.1.1",
1000+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1001+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1002+ "dev": true
1003+ },
1004+ "require-directory": {
1005+ "version": "2.1.1",
1006+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
1007+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
1008+ "dev": true
1009+ },
1010+ "rimraf": {
1011+ "version": "3.0.2",
1012+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
1013+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
1014+ "dev": true,
1015+ "requires": {
1016+ "glob": "^7.1.3"
1017+ }
1018+ },
1019+ "semver": {
1020+ "version": "6.3.1",
1021+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
1022+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
1023+ "dev": true
1024+ },
1025+ "shebang-command": {
1026+ "version": "2.0.0",
1027+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1028+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1029+ "dev": true,
1030+ "requires": {
1031+ "shebang-regex": "^3.0.0"
1032+ }
1033+ },
1034+ "shebang-regex": {
1035+ "version": "3.0.0",
1036+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1037+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1038+ "dev": true
1039+ },
1040+ "signal-exit": {
1041+ "version": "3.0.7",
1042+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
1043+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
1044+ "dev": true
1045+ },
1046+ "string-width": {
1047+ "version": "4.2.3",
1048+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1049+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1050+ "dev": true,
1051+ "requires": {
1052+ "emoji-regex": "^8.0.0",
1053+ "is-fullwidth-code-point": "^3.0.0",
1054+ "strip-ansi": "^6.0.1"
1055+ }
1056+ },
1057+ "strip-ansi": {
1058+ "version": "6.0.1",
1059+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1060+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1061+ "dev": true,
1062+ "requires": {
1063+ "ansi-regex": "^5.0.1"
1064+ }
1065+ },
1066+ "supports-color": {
1067+ "version": "7.2.0",
1068+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
1069+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
1070+ "dev": true,
1071+ "requires": {
1072+ "has-flag": "^4.0.0"
1073+ }
1074+ },
1075+ "test-exclude": {
1076+ "version": "6.0.0",
1077+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
1078+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
1079+ "dev": true,
1080+ "requires": {
1081+ "@istanbuljs/schema": "^0.1.2",
1082+ "glob": "^7.1.4",
1083+ "minimatch": "^3.0.4"
1084+ }
1085+ },
1086+ "v8-to-istanbul": {
1087+ "version": "9.0.1",
1088+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
1089+ "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
1090+ "dev": true,
1091+ "requires": {
1092+ "@jridgewell/trace-mapping": "^0.3.12",
1093+ "@types/istanbul-lib-coverage": "^2.0.1",
1094+ "convert-source-map": "^1.6.0"
1095+ }
1096+ },
1097+ "which": {
1098+ "version": "2.0.2",
1099+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1100+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1101+ "dev": true,
1102+ "requires": {
1103+ "isexe": "^2.0.0"
1104+ }
1105+ },
1106+ "wrap-ansi": {
1107+ "version": "7.0.0",
1108+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1109+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1110+ "dev": true,
1111+ "requires": {
1112+ "ansi-styles": "^4.0.0",
1113+ "string-width": "^4.1.0",
1114+ "strip-ansi": "^6.0.0"
1115+ }
1116+ },
1117+ "wrappy": {
1118+ "version": "1.0.2",
1119+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1120+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
1121+ "dev": true
1122+ },
1123+ "y18n": {
1124+ "version": "5.0.8",
1125+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
1126+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
1127+ "dev": true
1128+ },
1129+ "yargs": {
1130+ "version": "16.2.0",
1131+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
1132+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
1133+ "dev": true,
1134+ "requires": {
1135+ "cliui": "^7.0.2",
1136+ "escalade": "^3.1.1",
1137+ "get-caller-file": "^2.0.5",
1138+ "require-directory": "^2.1.1",
1139+ "string-width": "^4.2.0",
1140+ "y18n": "^5.0.5",
1141+ "yargs-parser": "^20.2.2"
1142+ }
1143+ },
1144+ "yargs-parser": {
1145+ "version": "20.2.9",
1146+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
1147+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
1148+ "dev": true
1149+ },
1150+ "yocto-queue": {
1151+ "version": "0.1.0",
1152+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
1153+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
1154+ "dev": true
25 }
1155 }
26 }
1156 }
27}
1157}
package.json+8−3
@@ -1,6 +1,11 @@
1{
1{
2− "dependencies": {
2+ "scripts": {
3− "big-integer": "^1.6.51"
3+ "test": "spago test",
4+ "precoverage": "npm run test",
5+ "coverage": "c8 --lines=99 --branches=75 --statements=99 npm run test"
4 },
6 },
5− "type": "module"
7+ "type": "module",
8+ "devDependencies": {
9+ "c8": "^7.12.0"
10+ }
6}
11}
packages.dhalldeleted−5
@@ -1,5 +0,0 @@
1−let upstream =
2− https://github.com/purescript/package-sets/releases/download/psc-0.15.2-20220610/packages.dhall
3− sha256:348212b7c79da7d343bed71b48ed164d426f1977f92196babac49bd560b32e75
4−
5−in upstream
spago.dhalldeleted−34
@@ -1,34 +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− , "bigints"
8− , "console"
9− , "control"
10− , "effect"
11− , "either"
12− , "exceptions"
13− , "foldable-traversable"
14− , "foreign"
15− , "foreign-object"
16− , "identity"
17− , "integers"
18− , "lists"
19− , "maybe"
20− , "newtype"
21− , "nullable"
22− , "ordered-collections"
23− , "partial"
24− , "prelude"
25− , "record"
26− , "transformers"
27− , "tuples"
28− , "typelevel-prelude"
29− , "unsafe-coerce"
30− , "variant"
31− ]
32−, packages = ./packages.dhall
33−, sources = [ "src/**/*.purs" ]
34−}
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+10−9
@@ -1,18 +1,19 @@
1function reviver(key, value) {
1function reviver(key, value) {
2− if (key === 'big') {
2+ if (key === "big") {
3− return BigInt(value);
3+ return BigInt(value);
4− }
4+ }
5− return value;
5+ return value;
6}
6}
7export const _parseJSON = (payload) => JSON.parse(payload, reviver);
7export const _parseJSON = (payload) => JSON.parse(payload, reviver);
8
8
9export const _undefined = undefined;
9export const _undefined = undefined;
10
10
11function replacer(key, value) {
11function replacer(key, value) {
12− if (key === 'big') {
12+ if (typeof value === "bigint") {
13− return value.toString();
13+ return value.toString();
14− }
15− return value;
16 }
14 }
17−
15+ return value;
16+}
17+
18export const _unsafeStringify = (data) => JSON.stringify(data, replacer);
18export const _unsafeStringify = (data) => JSON.stringify(data, replacer);
19+export const _unsafePrettyStringify = spaces => data => JSON.stringify(data, replacer, spaces);
src/Yoga/JSON.purs+222−49
@@ -4,6 +4,7 @@ module Yoga.JSON
4 , readJSON'
4 , readJSON'
5 , readJSON_
5 , readJSON_
6 , writeJSON
6 , writeJSON
7+ , writePrettyJSON
7 , write
8 , write
8 , read
9 , read
9 , read'
10 , read'
@@ -11,7 +12,6 @@ module Yoga.JSON
11 , parseJSON
12 , parseJSON
12 , undefined
13 , undefined
13 , unsafeStringify
14 , unsafeStringify
14−
15 , class ReadForeign
15 , class ReadForeign
16 , readImpl
16 , readImpl
17 , class ReadForeignFields
17 , class ReadForeignFields
@@ -21,48 +21,58 @@ module Yoga.JSON
21 , class ReadTuple
21 , class ReadTuple
22 , readTupleImpl
22 , readTupleImpl
23 , tupleSize
23 , tupleSize
24−
25 , class WriteForeign
24 , class WriteForeign
26 , writeImpl
25 , writeImpl
27 , class WriteForeignFields
26 , class WriteForeignFields
28 , writeImplFields
27 , writeImplFields
29 , class WriteForeignVariant
28 , class WriteForeignVariant
30 , writeVariantImpl
29 , writeVariantImpl
31−
32 ) where
30 ) where
33
31
34import Prelude
32import Prelude
35
33
36import Control.Alt ((<|>))
34import Control.Alt ((<|>))
37import Control.Apply (lift2)
35import Control.Apply (lift2)
36+import Control.Comonad.Cofree as Cofree
38import Control.Monad.Except (ExceptT(..), except, runExcept, throwError, withExcept)
37import Control.Monad.Except (ExceptT(..), except, runExcept, throwError, withExcept)
39import Data.Array as Array
38import Data.Array as Array
40import Data.Array.NonEmpty (NonEmptyArray, fromArray, toArray)
39import Data.Array.NonEmpty (NonEmptyArray, fromArray, toArray)
41import Data.Bifunctor (lmap)
40import Data.Bifunctor (lmap)
42−import Data.BigInt (BigInt)
41+import Data.DateTime (DateTime)
43−import Data.BigInt as BigInt
42+import Data.DateTime.Instant (Instant, instant, unInstant)
44−import Data.Either (Either, hush, note)
43+import Data.Either (Either(..), hush, note)
44+import Data.Foldable (class Foldable, foldl)
45import Data.FoldableWithIndex (foldrWithIndex)
45import Data.FoldableWithIndex (foldrWithIndex)
46+import Data.FunctorWithIndex (mapWithIndex)
46import Data.Identity (Identity(..))
47import Data.Identity (Identity(..))
47import Data.Int as Int
48import Data.Int as Int
49+import Data.JSDate (JSDate)
50+import Data.JSDate as JSDate
48import Data.List.NonEmpty (NonEmptyList, singleton)
51import Data.List.NonEmpty (NonEmptyList, singleton)
49import Data.Map (Map)
52import Data.Map (Map)
50import Data.Map as Map
53import Data.Map as Map
51import Data.Maybe (Maybe(..), fromMaybe, fromMaybe', maybe)
54import Data.Maybe (Maybe(..), fromMaybe, fromMaybe', maybe)
52−import Data.Newtype (class Newtype)
55+import Data.Newtype (class Newtype, unwrap, wrap)
53import Data.Nullable (Nullable, toMaybe, toNullable)
56import Data.Nullable (Nullable, toMaybe, toNullable)
57+import 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
54import Data.Symbol (class IsSymbol, reflectSymbol)
62import Data.Symbol (class IsSymbol, reflectSymbol)
63+import Data.Time.Duration (Days, Hours, Milliseconds, Minutes, Seconds)
55−import Data.Traversable (sequence, traverse)
64+import Data.Traversable (traverse)
56−import Data.TraversableWithIndex (traverseWithIndex)
57import Data.Tuple (Tuple(..))
65import Data.Tuple (Tuple(..))
58import Data.Variant (Variant, inj, on)
66import Data.Variant (Variant, inj, on)
59import Effect.Exception (message, try)
67import Effect.Exception (message, try)
60import Effect.Uncurried as EU
68import Effect.Uncurried as EU
61import Effect.Unsafe (unsafePerformEffect)
69import Effect.Unsafe (unsafePerformEffect)
62import Foreign (F, Foreign, ForeignError(..), MultipleErrors, fail, isNull, isUndefined, readArray, readBoolean, readChar, readInt, readNull, readNumber, readString, tagOf, unsafeFromForeign, unsafeReadTagged, unsafeToForeign)
70import Foreign (F, Foreign, ForeignError(..), MultipleErrors, fail, isNull, isUndefined, readArray, readBoolean, readChar, readInt, readNull, readNumber, readString, tagOf, unsafeFromForeign, unsafeReadTagged, unsafeToForeign)
63−import Foreign.Index (readProp)
71+import Foreign.Index (hasOwnProperty, readProp)
64import Foreign.Object (Object)
72import Foreign.Object (Object)
65import Foreign.Object as Object
73import Foreign.Object as Object
74+import JS.BigInt (BigInt)
75+import JS.BigInt (fromInt, fromNumber, fromString, toString) as BigInt
66import Partial.Unsafe (unsafeCrashWith)
76import Partial.Unsafe (unsafeCrashWith)
67import Prim.Row as Row
77import Prim.Row as Row
68import Prim.RowList (class RowToList, Cons, Nil, RowList)
78import Prim.RowList (class RowToList, Cons, Nil, RowList)
@@ -71,6 +81,8 @@ import Record.Builder (Builder)
71import Record.Builder as Builder
81import Record.Builder as Builder
72import Type.Prelude (Proxy(..))
82import Type.Prelude (Proxy(..))
73import Unsafe.Coerce (unsafeCoerce)
83import Unsafe.Coerce (unsafeCoerce)
84+import Yoga.Tree (Tree)
85+import Yoga.Tree as Tree
74
86
75-- | An alias for the Either result of decoding
87-- | An alias for the Either result of decoding
76type E a = Either MultipleErrors a
88type E a = Either MultipleErrors a
@@ -78,7 +90,7 @@ type E a = Either MultipleErrors a
78-- | Read a JSON string to a type `a` while returning a `MultipleErrors` if the
90-- | Read a JSON string to a type `a` while returning a `MultipleErrors` if the
79-- | parsing failed.
91-- | parsing failed.
80readJSON ∷
92readJSON ∷
81− ∀ a.
93+ ∀ @a.
82 ReadForeign a ⇒
94 ReadForeign a ⇒
83 String →
95 String →
84 E a
96 E a
@@ -86,7 +98,7 @@ readJSON = runExcept <<< (readImpl <=< parseJSON)
86
98
87-- | Read a JSON string to a type `a` using `F a`. Useful with record types.
99-- | Read a JSON string to a type `a` using `F a`. Useful with record types.
88readJSON' ∷
100readJSON' ∷
89− ∀ a.
101+ ∀ @a.
90 ReadForeign a ⇒
102 ReadForeign a ⇒
91 String →
103 String →
92 F a
104 F a
@@ -95,7 +107,7 @@ readJSON' = readImpl <=< parseJSON
95-- | Read a JSON string to a type `a` while returning `Nothing` if the parsing
107-- | Read a JSON string to a type `a` while returning `Nothing` if the parsing
96-- | failed.
108-- | failed.
97readJSON_ ∷
109readJSON_ ∷
98− ∀ a.
110+ ∀ @a.
99 ReadForeign a ⇒
111 ReadForeign a ⇒
100 String →
112 String →
101 Maybe a
113 Maybe a
@@ -104,6 +116,9 @@ readJSON_ = hush <<< readJSON
104-- | JSON.stringify
116-- | JSON.stringify
105foreign import _unsafeStringify ∷ ∀ a. a → String
117foreign import _unsafeStringify ∷ ∀ a. a → String
106
118
119+-- | JSON.stringify with a number of spaces
120+foreign import _unsafePrettyStringify ∷ ∀ a. Int → a → String
121+
107unsafeStringify ∷ ∀ a. a → String
122unsafeStringify ∷ ∀ a. a → String
108unsafeStringify = _unsafeStringify
123unsafeStringify = _unsafeStringify
109
124
@@ -115,6 +130,14 @@ writeJSON ∷
115 String
130 String
116writeJSON = _unsafeStringify <<< writeImpl
131writeJSON = _unsafeStringify <<< writeImpl
117
132
133+writePrettyJSON ∷
134+ ∀ a.
135+ WriteForeign a ⇒
136+ Int →
137+ a →
138+ String
139+writePrettyJSON spaces = _unsafePrettyStringify spaces <<< writeImpl
140+
118write ∷
141write ∷
119 ∀ a.
142 ∀ a.
120 WriteForeign a ⇒
143 WriteForeign a ⇒
@@ -124,14 +147,14 @@ write = writeImpl
124
147
125-- | Read a Foreign value to a type
148-- | Read a Foreign value to a type
126read ∷
149read ∷
127− ∀ a.
150+ ∀ @a.
128 ReadForeign a ⇒
151 ReadForeign a ⇒
129 Foreign →
152 Foreign →
130 E a
153 E a
131read = runExcept <<< readImpl
154read = runExcept <<< readImpl
132
155
133read' ∷
156read' ∷
134− ∀ a.
157+ ∀ @a.
135 ReadForeign a ⇒
158 ReadForeign a ⇒
136 Foreign →
159 Foreign →
137 F a
160 F a
@@ -139,7 +162,7 @@ read' = readImpl
139
162
140-- | Read a Foreign value to a type, as a Maybe of type
163-- | Read a Foreign value to a type, as a Maybe of type
141read_ ∷
164read_ ∷
142− ∀ a.
165+ ∀ @a.
143 ReadForeign a ⇒
166 ReadForeign a ⇒
144 Foreign →
167 Foreign →
145 Maybe a
168 Maybe a
@@ -185,26 +208,39 @@ readBigInt ∷
185readBigInt = unsafeReadTagged "BigInt"
208readBigInt = unsafeReadTagged "BigInt"
186
209
187instance ReadForeign BigInt where
210instance ReadForeign BigInt where
188− readImpl fValue = tryInt fValue <|> readBigInt fValue <|> tryString fValue
211+ readImpl fValue = tryInt fValue <|> tryNumber fValue <|> readBigInt fValue <|> tryString fValue
189 where
212 where
190 tryInt f = readInt f <#> BigInt.fromInt
213 tryInt f = readInt f <#> BigInt.fromInt
214+ tryNumber f = do
215+ num ← readNumber f
216+ if Number.round num == num then
217+ BigInt.fromNumber num
218+ # note (err $ "Cannot convert Number " <> show num <> " to BigInt")
219+ # except
220+ else
221+ (Left $ err $ "Cannot convert decimal Number " <> show num <> " to BigInt")
222+ # except
191 tryString f = do
223 tryString f = do
192 bi ← readString f
224 bi ← readString f
193 BigInt.fromString bi
225 BigInt.fromString bi
194− # note
226+ # note (err $ "Cannot convert String " <> bi <> " to BigInt")
195− ( singleton $ ForeignError $ "String " <> bi <>
196− " could not be converted to BigInt"
197− )
198 # except
227 # except
199−
228+ err = pure <<< ForeignError
229+
200instance ReadForeign String where
230instance ReadForeign String where
201 readImpl = readString
231 readImpl = readString
202
232
233+instance ReadForeign NonEmptyString where
234+ readImpl = readString >=>
235+ NonEmptyString.fromString
236+ >>> note (pure $ ForeignError "String must not be empty")
237+ >>> except
238+
203instance ReadForeign Boolean where
239instance ReadForeign Boolean where
204 readImpl = readBoolean
240 readImpl = readBoolean
205
241
206instance ReadForeign a ⇒ ReadForeign (Array a) where
242instance ReadForeign a ⇒ ReadForeign (Array a) where
207− readImpl = traverseWithIndex readAtIdx <=< readArray
243+ readImpl = sequenceCombining <<< mapWithIndex readAtIdx <=< readArray
208
244
209instance ReadForeign a ⇒ ReadForeign (Maybe a) where
245instance ReadForeign a ⇒ ReadForeign (Maybe a) where
210 readImpl = readNullOrUndefined readImpl
246 readImpl = readNullOrUndefined readImpl
@@ -221,9 +257,33 @@ instance ReadForeign a ⇒ ReadForeign (Nullable a) where
221 TypeMismatch inner other → TypeMismatch ("Nullable " <> inner) other
257 TypeMismatch inner other → TypeMismatch ("Nullable " <> inner) other
222 _ → error
258 _ → error
223
259
260+instance (ReadForeign a, ReadForeign b) ⇒ ReadForeign (Either a b) where
261+ readImpl f = do
262+ { type: tpe, value } ∷ { type ∷ String, value ∷ Foreign } ← readImpl f
263+ case tpe of
264+ "left" → Left <$> readImpl value
265+ "right" → Right <$> readImpl value
266+ _ → except $ Left (pure $ ForeignError $ "Invalid Either tag " <> tpe)
267+
224instance ReadForeign a ⇒ ReadForeign (Object.Object a) where
268instance ReadForeign a ⇒ ReadForeign (Object.Object a) where
225− readImpl = sequence <<< Object.mapWithKey (const readImpl) <=< readObject'
269+ readImpl = gatherErrors <<< Object.mapWithKey readProp <=< readObject'
226 where
270 where
271+ gatherErrors ∷ Object (F a) → F (Object a)
272+ gatherErrors = Object.toUnfoldable
273+ >>> Array.foldl fn (Right (Object.empty))
274+ >>> except
275+ where
276+ fn ∷ _ → _ → (Either MultipleErrors (Object a))
277+ fn acc (Tuple k v) = do
278+ case acc, runExcept v of
279+ Left errs, Left errsNew → Left (errs <> errsNew)
280+ Left errs, Right _ → Left errs
281+ Right obj, Right value → Right (Object.insert k value obj)
282+ Right _, Left errs → Left errs
283+
284+ readProp key value = except $ lmap (map (ErrorAtProperty key))
285+ (readImpl value # runExcept)
286+
227 readObject' ∷ Foreign → F (Object Foreign)
287 readObject' ∷ Foreign → F (Object Foreign)
228 readObject' value
288 readObject' value
229 | tagOf value == "Object" = pure $ unsafeFromForeign value
289 | tagOf value == "Object" = pure $ unsafeFromForeign value
@@ -298,16 +358,20 @@ instance
298 , Row.Cons name ty from' to
358 , Row.Cons name ty from' to
299 ) ⇒
359 ) ⇒
300 ReadForeignFields (Cons name ty tail) from to where
360 ReadForeignFields (Cons name ty tail) from to where
301− getFields _ obj = do
361+ getFields _ obj = except
302− compose <$> first <*> rest
362+ case runExcept first, runExcept rest of
363+ Right f, Right r → Right (f <<< r)
364+ Left e1, Left e2 → Left (e1 <> e2)
365+ Right _, Left es → Left es
366+ Left es, Right _ → Left es
303 where
367 where
304− value = withExcept' (readImpl =<< readProp name obj)
368+ value = enrichErrorWithPropName (readImpl =<< readProp name obj)
305 first = Builder.insert nameP <$> value
369 first = Builder.insert nameP <$> value
306 rest = getFields tailP obj
370 rest = getFields tailP obj
307 nameP = Proxy ∷ Proxy name
371 nameP = Proxy ∷ Proxy name
308 tailP = Proxy ∷ Proxy tail
372 tailP = Proxy ∷ Proxy tail
309 name = reflectSymbol nameP
373 name = reflectSymbol nameP
310− withExcept' = (withExcept <<< map) (ErrorAtProperty name)
374+ enrichErrorWithPropName = (withExcept <<< map) (ErrorAtProperty name)
311
375
312readAtIdx ∷ ∀ a. ReadForeign a ⇒ Int → Foreign → F a
376readAtIdx ∷ ∀ a. ReadForeign a ⇒ Int → Foreign → F a
313readAtIdx i f = withExcept (map (ErrorAtIndex i)) (readImpl f)
377readAtIdx i f = withExcept (map (ErrorAtIndex i)) (readImpl f)
@@ -339,10 +403,13 @@ instance
339 , ReadForeignVariant tail row
403 , ReadForeignVariant tail row
340 ) ⇒
404 ) ⇒
341 ReadForeignVariant (Cons name ty tail) row where
405 ReadForeignVariant (Cons name ty tail) row where
342− readVariantImpl _ o = readVariantImpl (Proxy :: Proxy tail) o <|> ado
406+ readVariantImpl _ o =
407+ if hasOwnProperty @String @Identity name o then rest <|> ado
343− value :: ty <- readProp name o >>= readImpl
408+ value ∷ ty ← readProp name o >>= readImpl
344− in inj namep value
409+ in inj namep value
410+ else rest
345 where
411 where
412+ rest = readVariantImpl (Proxy ∷ Proxy tail) o
346 namep = Proxy ∷ Proxy name
413 namep = Proxy ∷ Proxy name
347 name = reflectSymbol namep
414 name = reflectSymbol namep
348
415
@@ -362,6 +429,9 @@ instance WriteForeign Foreign where
362instance WriteForeign String where
429instance WriteForeign String where
363 writeImpl = unsafeToForeign
430 writeImpl = unsafeToForeign
364
431
432+instance WriteForeign NonEmptyString where
433+ writeImpl = unsafeToForeign
434+
365instance WriteForeign Int where
435instance WriteForeign Int where
366 writeImpl = unsafeToForeign
436 writeImpl = unsafeToForeign
367
437
@@ -386,6 +456,11 @@ instance WriteForeign a ⇒ WriteForeign (Maybe a) where
386instance WriteForeign a ⇒ WriteForeign (Nullable a) where
456instance WriteForeign a ⇒ WriteForeign (Nullable a) where
387 writeImpl = maybe (unsafeToForeign $ toNullable Nothing) writeImpl <<< toMaybe
457 writeImpl = maybe (unsafeToForeign $ toNullable Nothing) writeImpl <<< toMaybe
388
458
459+instance (WriteForeign a, WriteForeign b) ⇒ WriteForeign (Either a b) where
460+ writeImpl value = case value of
461+ Left l → writeImpl { type: "left", value: writeImpl l }
462+ Right r → writeImpl { type: "right", value: writeImpl r }
463+
389instance WriteForeign a ⇒ WriteForeign (Object.Object a) where
464instance WriteForeign a ⇒ WriteForeign (Object.Object a) where
390 writeImpl = unsafeToForeign <<< Object.mapWithKey (const writeImpl)
465 writeImpl = unsafeToForeign <<< Object.mapWithKey (const writeImpl)
391
466
@@ -487,24 +562,122 @@ instance writeForeignNEArray ∷ WriteForeign a ⇒ WriteForeign (NonEmptyArray
487 writeImpl a = writeImpl <<< toArray $ a
562 writeImpl a = writeImpl <<< toArray $ a
488
563
489-- Map instances
564-- Map instances
490−instance (WriteForeign a) => WriteForeign (Map String a) where
565+instance (WriteForeign a) ⇒ WriteForeign (Map String a) where
491 writeImpl = foldrWithIndex Object.insert Object.empty >>> writeImpl
566 writeImpl = foldrWithIndex Object.insert Object.empty >>> writeImpl
492−else
493−instance (WriteForeign a) => WriteForeign (Map Int a) where
567+else instance (WriteForeign a) ⇒ WriteForeign (Map Int a) where
494 writeImpl = foldrWithIndex (show >>> Object.insert) Object.empty >>> writeImpl
568 writeImpl = foldrWithIndex (show >>> Object.insert) Object.empty >>> writeImpl
495−else
569+else instance (WriteForeign a) ⇒ WriteForeign (Map BigInt a) where
570+ writeImpl = foldrWithIndex (BigInt.toString >>> Object.insert) Object.empty >>> writeImpl
496−instance (Newtype nt key, WriteForeign (Map key value)) => WriteForeign (Map nt value) where
571+else instance (Newtype nt key, WriteForeign (Map key value)) ⇒ WriteForeign (Map nt value) where
497− writeImpl = (unsafeCoerce :: (_ -> Map key value )) >>> writeImpl
572+ writeImpl = (unsafeCoerce ∷ (_ → Map key value)) >>> writeImpl
498−
573+
499−instance (ReadForeign a) => ReadForeign (Map String a) where
574+instance (ReadForeign a) ⇒ ReadForeign (Map String a) where
500− readImpl = (readImpl :: (_ -> _ (Object a))) >>> map (foldrWithIndex Map.insert Map.empty)
575+ readImpl = (readImpl ∷ (_ → _ (Object a))) >>> map (foldrWithIndex Map.insert Map.empty)
501−else
502−instance (ReadForeign a) => ReadForeign (Map Int a) where
576+else instance (ReadForeign a) ⇒ ReadForeign (Map Int a) where
503− readImpl = (readImpl :: (_ -> _ (Object a))) >>> map (foldrWithIndex (unsafeStringToInt >>> Map.insert) Map.empty)
577+ readImpl = (readImpl ∷ (_ → _ (Object a))) >>> map (foldrWithIndex (unsafeStringToInt >>> Map.insert) Map.empty)
504−else
578+else instance (ReadForeign a) ⇒ ReadForeign (Map BigInt a) where
579+ readImpl = (readImpl ∷ (_ → _ (Object a))) >>> map (foldrWithIndex (unsafeStringToBigInt >>> Map.insert) Map.empty)
505−instance (Newtype nt key, ReadForeign (Map key value)) => ReadForeign (Map nt value) where
580+else instance (Newtype nt key, ReadForeign (Map key value)) ⇒ ReadForeign (Map nt value) where
506− readImpl = (readImpl :: (_ -> _ (Map key value))) >>> map (unsafeCoerce :: (Map key value -> Map nt value))
581+ readImpl = (readImpl ∷ (_ → _ (Map key value))) >>> map (unsafeCoerce ∷ (Map key value → Map nt value))
507−
582+
508−unsafeStringToInt :: String → Int
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+
590+-- Date instances
591+instance WriteForeign JSDate where
592+ writeImpl = JSDate.toISOString >>> unsafePerformEffect >>> writeImpl
593+
594+instance ReadForeign JSDate where
595+ readImpl = readImpl >>> map (JSDate.parse >>> unsafePerformEffect)
596+
597+instance WriteForeign DateTime where
598+ writeImpl = JSDate.fromDateTime >>> writeImpl
599+
600+instance ReadForeign DateTime where
601+ readImpl = readImpl >=>
602+ JSDate.toDateTime
603+ >>> note (pure $ ForeignError "Invalid date time")
604+ >>> except
605+
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+
646+unsafeStringToInt ∷ String → Int
509unsafeStringToInt = Int.fromString >>>
647unsafeStringToInt = Int.fromString >>>
648+ (fromMaybe' \_ → unsafeCrashWith "impossible")
649+
650+unsafeStringToBigInt ∷ String → BigInt
651+unsafeStringToBigInt = BigInt.fromString >>>
510− (fromMaybe' \_ -> unsafeCrashWith "impossible")
652+ (fromMaybe' \_ → unsafeCrashWith "impossible")
653+
654+sequenceCombining ∷
655+ ∀ f a.
656+ Monoid (f a) ⇒
657+ Foldable f ⇒
658+ Applicative f ⇒
659+ f (F a) →
660+ F (f a)
661+sequenceCombining = foldl fn (Right mempty) >>> except
662+ where
663+ fn ∷ _ → _ → (Either MultipleErrors (f a))
664+ fn acc elem = do
665+ case acc, runExcept elem of
666+ Left errs, Left errsNew → Left (errs <> errsNew)
667+ Left errs, Right _ → Left errs
668+ Right values, Right value → Right (values <> pure value)
669+ 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+46−6
@@ -3,14 +3,54 @@ module Yoga.JSON.Error where
3import Prelude
3import Prelude
4
4
5import Foreign (ForeignError(..))
5import Foreign (ForeignError(..))
6+import Data.Semigroup.Foldable (intercalateMap)
7+import Data.Bifunctor (lmap)
8+import Yoga.JSON (E)
9+import Data.Either (Either)
6
10
7−toJSONPath :: ForeignError -> String
11+toJSONPath ∷ ForeignError → String
8toJSONPath fe = "$" <> path
12toJSONPath fe = "$" <> path
9 where
13 where
10 path = go fe
14 path = go fe
11 go = case _ of
15 go = case _ of
12− ForeignError _ -> ""
16+ ForeignError _ → ""
13− TypeMismatch _ _ -> ""
17+ TypeMismatch _ _ → ""
14− ErrorAtIndex i e -> "[" <> show i <> "]" <> go e
18+ ErrorAtIndex i e → "[" <> show i <> "]" <> go e
15− ErrorAtProperty _ (TypeMismatch _ "undefined") -> ""
19+ ErrorAtProperty _ (TypeMismatch _ "undefined") → ""
16− ErrorAtProperty prop e -> "." <> prop <> go e
20+ ErrorAtProperty prop e → "." <> prop <> go e
21+
22+renderHumanError ∷ ForeignError → String
23+renderHumanError = errorToJSON >>> toHuman
24+ where
25+ toHuman { message, path } = message <> " at " <> path
26+
27+withStringErrors :: forall a. E a -> Either String a
28+withStringErrors = lmap (intercalateMap "\n" renderHumanError)
29+
30+errorToJSON ∷
31+ ForeignError →
32+ { message ∷ String
33+ , path ∷ String
34+ }
35+errorToJSON err = go err
36+ where
37+ path = toJSONPath err
38+ go = case _ of
39+ ForeignError s →
40+ { path
41+ , message: s
42+ }
43+ TypeMismatch exp "Undefined" →
44+ { path
45+ , message: "Must provide a value of type '" <> exp <> "'"
46+ }
47+ TypeMismatch exp "undefined" →
48+ { path
49+ , message: "Must provide a value of type '" <> exp <> "'"
50+ }
51+ TypeMismatch exp act →
52+ { path
53+ , message: "Must provide a value of type '" <> exp <> "' instead of '" <> act <> "'"
54+ }
55+ ErrorAtIndex _ e → go e
56+ ErrorAtProperty _ e → go e
src/Yoga/JSON/Generics.purs+1−1
@@ -5,4 +5,4 @@ module Yoga.JSON.Generics
5import Yoga.JSON.Generics.TaggedSumRep (class ReadGenericTaggedSumRep, class WriteGenericTaggedSumRep, Options, defaultOptions, genericReadForeignTaggedSum, genericReadForeignTaggedSumRep, genericWriteForeignTaggedSum, genericWriteForeignTaggedSumRep) as Exported
5import Yoga.JSON.Generics.TaggedSumRep (class ReadGenericTaggedSumRep, class WriteGenericTaggedSumRep, Options, defaultOptions, genericReadForeignTaggedSum, genericReadForeignTaggedSumRep, genericWriteForeignTaggedSum, genericWriteForeignTaggedSumRep) as Exported
6import Yoga.JSON.Generics.UntaggedSumRep (class ReadGenericUntaggedSumRep, class WriteGenericUntaggedSumRep, genericReadForeignUntaggedSum, genericReadForeignUntaggedSumRep, genericWriteForeignUntaggedSum, genericWriteForeignUntaggedSumRep) as Exported
6import Yoga.JSON.Generics.UntaggedSumRep (class ReadGenericUntaggedSumRep, class WriteGenericUntaggedSumRep, genericReadForeignUntaggedSum, genericReadForeignUntaggedSumRep, genericWriteForeignUntaggedSum, genericWriteForeignUntaggedSumRep) as Exported
7import Yoga.JSON.Generics.EnumSumRep (class GenericEnumSumRep, genericEnumReadForeign, genericEnumWriteForeign, genericReadForeignEnum, genericWriteForeignEnum) as Exported
7import Yoga.JSON.Generics.EnumSumRep (class GenericEnumSumRep, genericEnumReadForeign, genericEnumWriteForeign, genericReadForeignEnum, genericWriteForeignEnum) as Exported
8−import Yoga.JSON.Generics.UntaggedProductRep (class ReadGenericUntaggedProduct, class WriteGenericUntaggedProduct, Offset, genericReadForeignUntaggedProduct, genericReadForeignUntaggedProductRep, genericWriteForeignUntaggedProduct, genericWriteForeignUntaggedProductRep) as Exported
8+import Yoga.JSON.Generics.UntaggedProductRep (class ReadGenericUntaggedProduct, class WriteGenericUntaggedProduct, Offset, genericReadForeignUntaggedProduct, genericReadForeignUntaggedProductRep, genericWriteForeignUntaggedProduct, genericWriteForeignUntaggedProductRep) as Exported
src/Yoga/JSON/Generics/EnumSumRep.purs+45−32
@@ -9,44 +9,57 @@ import Foreign as Foreign
9import Yoga.JSON as JSON
9import Yoga.JSON as JSON
10import Type.Prelude (class IsSymbol, Proxy(..), reflectSymbol)
10import Type.Prelude (class IsSymbol, Proxy(..), reflectSymbol)
11
11
12+type Options =
13+ { toConstructorName ∷ String → String }
14+
15+defaultOptions ∷ Options
16+defaultOptions = { toConstructorName: identity }
17+
12−genericReadForeignEnum
18+genericReadForeignEnum ∷
13− :: forall a rep
19+ ∀ a rep.
14− . GR.Generic a rep
20+ GR.Generic a rep ⇒
15− => GenericEnumSumRep rep
21+ GenericEnumSumRep rep ⇒
22+ Options →
16− => Foreign
23+ Foreign →
17− -> Foreign.F a
24+ Foreign.F a
18−genericReadForeignEnum f =
25+genericReadForeignEnum options f =
19− GR.to <$> genericEnumReadForeign f
26+ GR.to <$> genericEnumReadForeign options f
20−
27+
21−genericWriteForeignEnum
28+genericWriteForeignEnum ∷
22− :: forall a rep
29+ ∀ a rep.
23− . GR.Generic a rep
30+ GR.Generic a rep ⇒
24− => GenericEnumSumRep rep
31+ GenericEnumSumRep rep ⇒
25− => a
32+ Options →
33+ a →
26− -> Foreign
34+ Foreign
27−genericWriteForeignEnum a = genericEnumWriteForeign (GR.from a)
35+genericWriteForeignEnum options a = genericEnumWriteForeign options (GR.from a)
28
36
29-- | Generic Enum Sum Representations, with constructor names as strings
37-- | Generic Enum Sum Representations, with constructor names as strings
30class GenericEnumSumRep rep where
38class GenericEnumSumRep rep where
31− genericEnumReadForeign :: Foreign -> Foreign.F rep
39+ genericEnumReadForeign ∷ Options → Foreign → Foreign.F rep
32− genericEnumWriteForeign :: rep -> Foreign
40+ genericEnumWriteForeign ∷ Options → rep → Foreign
33
41
42+instance
34−instance ( GenericEnumSumRep a , GenericEnumSumRep b) =>
43+ ( GenericEnumSumRep a
44+ , GenericEnumSumRep b
45+ ) ⇒
35 GenericEnumSumRep (GR.Sum a b) where
46 GenericEnumSumRep (GR.Sum a b) where
36− genericEnumReadForeign f = GR.Inl <$> genericEnumReadForeign f
47+ genericEnumReadForeign options f = GR.Inl <$> genericEnumReadForeign options f
37− <|> GR.Inr <$> genericEnumReadForeign f
48+ <|> GR.Inr <$> genericEnumReadForeign options f
38− genericEnumWriteForeign = case _ of
49+ genericEnumWriteForeign options = case _ of
39− (GR.Inl a) -> genericEnumWriteForeign a
50+ (GR.Inl a) → genericEnumWriteForeign options a
40− (GR.Inr a) -> genericEnumWriteForeign a
51+ (GR.Inr a) → genericEnumWriteForeign options a
41
52
53+instance
42−instance (IsSymbol name) =>
54+ ( IsSymbol name
55+ ) ⇒
43 GenericEnumSumRep (GR.Constructor name GR.NoArguments) where
56 GenericEnumSumRep (GR.Constructor name GR.NoArguments) where
44− genericEnumReadForeign f = do
57+ genericEnumReadForeign options f = do
45− s <- JSON.readImpl f
58+ s ← JSON.readImpl f
46− if s == name then pure $ GR.Constructor GR.NoArguments
59+ if s == options.toConstructorName name then pure $ GR.Constructor GR.NoArguments
47 else fail <<< Foreign.ForeignError $
60 else fail <<< Foreign.ForeignError $
48− "Enum string " <> s <> " did not match expected string " <> name
61+ "Enum string " <> s <> " did not match expected string " <> options.toConstructorName name
49 where
62 where
50− name = reflectSymbol (Proxy :: Proxy name)
63+ name = reflectSymbol (Proxy ∷ Proxy name)
51− genericEnumWriteForeign (GR.Constructor GR.NoArguments) =
64+ genericEnumWriteForeign options (GR.Constructor GR.NoArguments) =
52− JSON.writeImpl $ reflectSymbol (Proxy :: Proxy name)
65+ JSON.writeImpl $ options.toConstructorName (reflectSymbol (Proxy ∷ Proxy name))
src/Yoga/JSON/Generics/UntaggedProductRep.purs+6−3
@@ -58,18 +58,21 @@ genericWriteForeignUntaggedProduct ∷
58genericWriteForeignUntaggedProduct a =
58genericWriteForeignUntaggedProduct a =
59 JSON.write (genericWriteForeignUntaggedProductRep [] (GR.from a))
59 JSON.write (genericWriteForeignUntaggedProductRep [] (GR.from a))
60
60
61−
62-- | Generic Untagged Product Representations, as a heterogeneous fixed-length array
61-- | Generic Untagged Product Representations, as a heterogeneous fixed-length array
63-- | You should consider using records instead in almost any usage.
62-- | You should consider using records instead in almost any usage.
64class WriteGenericUntaggedProduct rep where
63class WriteGenericUntaggedProduct rep where
65 genericWriteForeignUntaggedProductRep ∷ Array Foreign → rep → Array Foreign
64 genericWriteForeignUntaggedProductRep ∷ Array Foreign → rep → Array Foreign
66
65
66+instance
67−instance (WriteGenericUntaggedProduct a) ⇒
67+ ( WriteGenericUntaggedProduct a
68+ ) ⇒
68 WriteGenericUntaggedProduct (GR.Constructor name a) where
69 WriteGenericUntaggedProduct (GR.Constructor name a) where
69 genericWriteForeignUntaggedProductRep arr (GR.Constructor a) =
70 genericWriteForeignUntaggedProductRep arr (GR.Constructor a) =
70 genericWriteForeignUntaggedProductRep arr a
71 genericWriteForeignUntaggedProductRep arr a
71
72
73+instance
72−instance (JSON.WriteForeign a) ⇒
74+ ( JSON.WriteForeign a
75+ ) ⇒
73 WriteGenericUntaggedProduct (GR.Argument a) where
76 WriteGenericUntaggedProduct (GR.Argument a) where
74 genericWriteForeignUntaggedProductRep arr (GR.Argument a) =
77 genericWriteForeignUntaggedProductRep arr (GR.Argument a) =
75 Array.snoc arr (JSON.write a)
78 Array.snoc arr (JSON.write a)
src/Yoga/JSON/Generics/UntaggedSumRep.purs+22−22
@@ -8,69 +8,69 @@ import Foreign (Foreign)
8import Foreign as Foreign
8import Foreign as Foreign
9import Yoga.JSON as JSON
9import Yoga.JSON as JSON
10
10
11−genericReadForeignUntaggedSum
11+genericReadForeignUntaggedSum ∷
12− :: forall a rep
12+ ∀ a rep.
13− . GR.Generic a rep
13+ GR.Generic a rep ⇒
14− => ReadGenericUntaggedSumRep rep
14+ ReadGenericUntaggedSumRep rep ⇒
15− => Foreign
15+ Foreign →
16− -> Foreign.F a
16+ Foreign.F a
17genericReadForeignUntaggedSum f = GR.to <$> genericReadForeignUntaggedSumRep f
17genericReadForeignUntaggedSum f = GR.to <$> genericReadForeignUntaggedSumRep f
18
18
19-- | Generic Untagged Sum Representations
19-- | Generic Untagged Sum Representations
20-- | Note that because the members are untagged, you should verify your members are not the same type
20-- | Note that because the members are untagged, you should verify your members are not the same type
21class ReadGenericUntaggedSumRep rep where
21class ReadGenericUntaggedSumRep rep where
22− genericReadForeignUntaggedSumRep :: Foreign -> Foreign.F rep
22+ genericReadForeignUntaggedSumRep ∷ Foreign → Foreign.F rep
23
23
24instance
24instance
25 ( ReadGenericUntaggedSumRep a
25 ( ReadGenericUntaggedSumRep a
26 , ReadGenericUntaggedSumRep b
26 , ReadGenericUntaggedSumRep b
27− ) =>
27+ ) ⇒
28 ReadGenericUntaggedSumRep (GR.Sum a b) where
28 ReadGenericUntaggedSumRep (GR.Sum a b) where
29 genericReadForeignUntaggedSumRep f = GR.Inl <$> genericReadForeignUntaggedSumRep f
29 genericReadForeignUntaggedSumRep f = GR.Inl <$> genericReadForeignUntaggedSumRep f
30 <|> GR.Inr <$> genericReadForeignUntaggedSumRep f
30 <|> GR.Inr <$> genericReadForeignUntaggedSumRep f
31
31
32instance
32instance
33 ( ReadGenericUntaggedSumRep a
33 ( ReadGenericUntaggedSumRep a
34− ) =>
34+ ) ⇒
35 ReadGenericUntaggedSumRep (GR.Constructor name a) where
35 ReadGenericUntaggedSumRep (GR.Constructor name a) where
36 genericReadForeignUntaggedSumRep f = GR.Constructor <$> genericReadForeignUntaggedSumRep f
36 genericReadForeignUntaggedSumRep f = GR.Constructor <$> genericReadForeignUntaggedSumRep f
37
37
38instance
38instance
39 ( JSON.ReadForeign a
39 ( JSON.ReadForeign a
40− ) =>
40+ ) ⇒
41 ReadGenericUntaggedSumRep (GR.Argument a) where
41 ReadGenericUntaggedSumRep (GR.Argument a) where
42 genericReadForeignUntaggedSumRep f = GR.Argument <$> JSON.readImpl f
42 genericReadForeignUntaggedSumRep f = GR.Argument <$> JSON.readImpl f
43
43
44−genericWriteForeignUntaggedSum
44+genericWriteForeignUntaggedSum ∷
45− :: forall a rep
45+ ∀ a rep.
46− . GR.Generic a rep
46+ GR.Generic a rep ⇒
47− => WriteGenericUntaggedSumRep rep
47+ WriteGenericUntaggedSumRep rep ⇒
48− => a
48+ a →
49− -> Foreign
49+ Foreign
50genericWriteForeignUntaggedSum a = GR.from a # genericWriteForeignUntaggedSumRep
50genericWriteForeignUntaggedSum a = GR.from a # genericWriteForeignUntaggedSumRep
51
51
52-- | Generic Untagged Sum Representations
52-- | Generic Untagged Sum Representations
53-- | Note that because the members are untagged, you should verify your members are not the same type
53-- | Note that because the members are untagged, you should verify your members are not the same type
54class WriteGenericUntaggedSumRep rep where
54class WriteGenericUntaggedSumRep rep where
55− genericWriteForeignUntaggedSumRep :: rep -> Foreign
55+ genericWriteForeignUntaggedSumRep ∷ rep → Foreign
56
56
57instance
57instance
58 ( WriteGenericUntaggedSumRep a
58 ( WriteGenericUntaggedSumRep a
59 , WriteGenericUntaggedSumRep b
59 , WriteGenericUntaggedSumRep b
60− ) =>
60+ ) ⇒
61 WriteGenericUntaggedSumRep (GR.Sum a b) where
61 WriteGenericUntaggedSumRep (GR.Sum a b) where
62 genericWriteForeignUntaggedSumRep = case _ of
62 genericWriteForeignUntaggedSumRep = case _ of
63− GR.Inl a -> genericWriteForeignUntaggedSumRep a
63+ GR.Inl a → genericWriteForeignUntaggedSumRep a
64− GR.Inr a -> genericWriteForeignUntaggedSumRep a
64+ GR.Inr a → genericWriteForeignUntaggedSumRep a
65
65
66instance
66instance
67 ( WriteGenericUntaggedSumRep a
67 ( WriteGenericUntaggedSumRep a
68− ) =>
68+ ) ⇒
69 WriteGenericUntaggedSumRep (GR.Constructor name a) where
69 WriteGenericUntaggedSumRep (GR.Constructor name a) where
70 genericWriteForeignUntaggedSumRep (GR.Constructor a) = genericWriteForeignUntaggedSumRep a
70 genericWriteForeignUntaggedSumRep (GR.Constructor a) = genericWriteForeignUntaggedSumRep a
71
71
72instance
72instance
73 ( JSON.WriteForeign a
73 ( JSON.WriteForeign a
74− ) =>
74+ ) ⇒
75 WriteGenericUntaggedSumRep (GR.Argument a) where
75 WriteGenericUntaggedSumRep (GR.Argument a) where
76 genericWriteForeignUntaggedSumRep (GR.Argument a) = JSON.write a
76 genericWriteForeignUntaggedSumRep (GR.Argument a) = JSON.write a
src/Yoga/JSON/Variant.purs+6−6
@@ -20,8 +20,8 @@ newtype TaggedVariant ∷ Symbol → Symbol → Row Type → Type
20newtype TaggedVariant tt vt v = TaggedVariant (Variant v)
20newtype TaggedVariant tt vt v = TaggedVariant (Variant v)
21
21
22instance Newtype (TaggedVariant tt vt v) (Variant v)
22instance Newtype (TaggedVariant tt vt v) (Variant v)
23−derive newtype instance (Show (Variant v)) => Show (TaggedVariant tt vt v)
23+derive newtype instance (Show (Variant v)) ⇒ Show (TaggedVariant tt vt v)
24−derive newtype instance (Eq (Variant v)) => Eq (TaggedVariant tt vt v)
24+derive newtype instance (Eq (Variant v)) ⇒ Eq (TaggedVariant tt vt v)
25
25
26instance
26instance
27 ( RowToList row rl
27 ( RowToList row rl
@@ -104,7 +104,7 @@ instance
104 readVariantImpl _ o = readVariantImpl (Proxy ∷ Proxy tail) o <|> do
104 readVariantImpl _ o = readVariantImpl (Proxy ∷ Proxy tail) o <|> do
105 type_ ← readProp typeTag o >>= readImpl
105 type_ ← readProp typeTag o >>= readImpl
106 if type_ == name then do
106 if type_ == name then do
107− value :: ty <- readProp valueTag o >>= readImpl
107+ value ∷ ty ← readProp valueTag o >>= readImpl
108 pure $ TaggedVariant (inj namep value)
108 pure $ TaggedVariant (inj namep value)
109 else
109 else
110 (fail <<< ForeignError $ "Did not match variant tag " <> name)
110 (fail <<< ForeignError $ "Did not match variant tag " <> name)
@@ -121,8 +121,8 @@ newtype UntaggedVariant ∷ Row Type → Type
121newtype UntaggedVariant v = UntaggedVariant (Variant v)
121newtype UntaggedVariant v = UntaggedVariant (Variant v)
122
122
123instance Newtype (UntaggedVariant v) (Variant v)
123instance Newtype (UntaggedVariant v) (Variant v)
124−derive newtype instance (Show (Variant v)) => Show (UntaggedVariant v)
124+derive newtype instance (Show (Variant v)) ⇒ Show (UntaggedVariant v)
125−derive newtype instance (Eq (Variant v)) => Eq (UntaggedVariant v)
125+derive newtype instance (Eq (Variant v)) ⇒ Eq (UntaggedVariant v)
126
126
127instance
127instance
128 ( RowToList row rl
128 ( RowToList row rl
@@ -190,7 +190,7 @@ instance
190 ReadForeignUntaggedVariant (Cons name ty tail) row where
190 ReadForeignUntaggedVariant (Cons name ty tail) row where
191 readUntaggedVariantImpl _ o =
191 readUntaggedVariantImpl _ o =
192 readUntaggedVariantImpl (Proxy ∷ Proxy tail) o <|> ado
192 readUntaggedVariantImpl (Proxy ∷ Proxy tail) o <|> ado
193− v <- readImpl o
193+ v ← readImpl o
194 in UntaggedVariant (inj namep v)
194 in UntaggedVariant (inj namep v)
195
195
196 where
196 where
test.dhalldeleted−14
@@ -1,14 +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− ]
14− }
test/BasicsSpec.purs+167−44
@@ -3,28 +3,38 @@ module Test.BasicsSpec where
3import Prelude
3import Prelude
4
4
5import Data.Array.NonEmpty as NEA
5import Data.Array.NonEmpty as NEA
6−import Data.BigInt (BigInt)
7−import Data.Either (Either(..))
6+import Data.Either (Either(..), isLeft)
8import Data.Foldable (traverse_)
7import Data.Foldable (traverse_)
8+import Data.JSDate as JSDate
9import Data.List as List
9import Data.List as List
10import Data.List.Lazy as LazyList
10import Data.List.Lazy as LazyList
11import Data.Map as Map
11import Data.Map as Map
12−import Data.Maybe (Maybe(..))
12+import Data.Maybe (Maybe(..), fromJust, fromMaybe')
13import Data.Newtype (class Newtype, un)
13import Data.Newtype (class Newtype, un)
14import Data.Nullable as Nullable
14import 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(..))
15import Data.Tuple (Tuple(..))
18import Data.Tuple (Tuple(..))
16import Data.Tuple.Nested ((/\))
19import Data.Tuple.Nested ((/\))
17import Data.Variant (Variant, inj)
20import Data.Variant (Variant, inj)
21+import Effect.Class (liftEffect)
22+import Effect.Now (nowDateTime)
23+import Foreign (ForeignError(..))
18import Foreign.Object as Object
24import Foreign.Object as Object
25+import JS.BigInt (BigInt)
26+import JS.BigInt as BigInt
27+import Partial.Unsafe (unsafeCrashWith, unsafePartial)
19import Test.Spec (Spec, describe, it)
28import Test.Spec (Spec, describe, it)
20import Test.Spec.Assertions (shouldEqual)
29import Test.Spec.Assertions (shouldEqual)
21import Test.Util (roundtrips)
30import Test.Util (roundtrips)
22import Type.Proxy (Proxy(..))
31import Type.Proxy (Proxy(..))
23import Yoga.JSON (class ReadForeign, class WriteForeign, readJSON, writeJSON)
32import Yoga.JSON (class ReadForeign, class WriteForeign, readJSON, writeJSON)
24import Yoga.JSON.Variant (TaggedVariant(..), UntaggedVariant(..))
33import Yoga.JSON.Variant (TaggedVariant(..), UntaggedVariant(..))
34+import Yoga.Tree (Tree, mkLeaf, mkTree, showTree)
25
35
26−spec :: Spec Unit
36+spec ∷ Spec Unit
27−spec = describe "En- and decoding" $ do
37+spec = describe "En- and decoding" do
28
38
29 describe "works on primitive types" do
39 describe "works on primitive types" do
30 it "roundtrips Number" $ roundtrips 3.1414
40 it "roundtrips Number" $ roundtrips 3.1414
@@ -36,46 +46,97 @@ spec = describe "En- and decoding" $ do
36 it "roundtrips Maybe" do
46 it "roundtrips Maybe" do
37 roundtrips (Just 3)
47 roundtrips (Just 3)
38 -- just roundtrips Nothing doesn't work when rendering the JSON
48 -- just roundtrips Nothing doesn't work when rendering the JSON
39− roundtrips { empty: Nothing :: Maybe Int }
49+ roundtrips { empty: Nothing ∷ Maybe Int }
40− it "roundtrips Nullable" $ traverse_ roundtrips [Nullable.notNull 3, Nullable.null]
50+ it "roundtrips Nullable" $ traverse_ roundtrips [ Nullable.notNull 3, Nullable.null ]
41− it "roundtrips Tuple" $ do
51+ it "roundtrips Either" do
52+ roundtrips ((Left 3) ∷ Either Int Int)
53+ roundtrips ((Right 3) ∷ Either String Int)
54+ writeJSON (Right 3 ∷ Either Int Int) `shouldEqual` """{"value":3,"type":"right"}"""
55+ writeJSON (Left true ∷ Either Boolean Int) `shouldEqual` """{"value":true,"type":"left"}"""
56+
57+ it "roundtrips Tuple" do
42 roundtrips (Tuple 3 4)
58 roundtrips (Tuple 3 4)
43 roundtrips ("4" /\ 8 /\ Just 4)
59 roundtrips ("4" /\ 8 /\ Just 4)
44− it "roundtrips Array" $ traverse_ roundtrips [["A", "B"],[]]
60+ it "roundtrips Array" $ traverse_ roundtrips [ [ "A", "B" ], [] ]
45− it "roundtrips LazyList" $ traverse_ roundtrips (LazyList.fromFoldable [["A", "B"],[]])
61+ it "roundtrips LazyList" $ traverse_ roundtrips (LazyList.fromFoldable [ [ "A", "B" ], [] ])
46− it "roundtrips List" $ traverse_ roundtrips (List.fromFoldable [["A", "B"],[]])
62+ it "roundtrips List" $ traverse_ roundtrips (List.fromFoldable [ [ "A", "B" ], [] ])
47− it "roundtrips NonEmptyArray" $ roundtrips (NEA.cons' "A" ["B"])
63+ it "roundtrips NonEmptyArray" $ roundtrips (NEA.cons' "A" [ "B" ])
48 it "roundtrips Object" $ roundtrips (Object.fromHomogeneous { a: 12, b: 54 })
64 it "roundtrips Object" $ roundtrips (Object.fromHomogeneous { a: 12, b: 54 })
49− it "roundtrips String Map" $ roundtrips (Map.fromFoldable [("A" /\ 8),("C" /\ 7)])
65+ it "roundtrips String Map" $ roundtrips (Map.fromFoldable [ ("A" /\ 8), ("C" /\ 7) ])
50− it "roundtrips Int Map" $ roundtrips (Map.fromFoldable [(4 /\ "B"),(8 /\ "D")])
66+ it "roundtrips Int Map" $ roundtrips (Map.fromFoldable [ (4 /\ "B"), (8 /\ "D") ])
51 it "roundtrips Map with String newtype keys"
67 it "roundtrips Map with String newtype keys"
52− $ roundtrips (Map.fromFoldable [(Stringy "A" /\ "B"),(Stringy "C" /\ "D")])
68+ $ roundtrips (Map.fromFoldable [ (Stringy "A" /\ "B"), (Stringy "C" /\ "D") ])
53 it "roundtrips Map with Int newtype keys"
69 it "roundtrips Map with Int newtype keys"
54− $ roundtrips (Map.fromFoldable [(Inty 4 /\ "B"),(Inty 8 /\ "D")])
70+ $ 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" ])
55 it "roundtrips BigInt" do
74 it "roundtrips BigInt" do
56 let
75 let
57− inputStr = """{ "number":1, "big": 18014398509481982, "smallBig": 10 }"""
76+ inputStr = """{ "number":1, "big": 18014398509481982, "mediumBig": 1652955871799, "smallBig": 10 }"""
58− expected = """{"smallBig":"10","number":1,"big":"18014398509481982"}"""
77+ expected = """{"smallBig":"10","number":1,"mediumBig":"1652955871799","big":"18014398509481982"}"""
78+
59− parsed ∷ _ ({ number ∷ Int, big ∷ BigInt, smallBig ∷ BigInt })
79+ parsed ∷ _ ({ number ∷ Int, mediumBig ∷ BigInt, big ∷ BigInt, smallBig ∷ BigInt })
60 parsed = readJSON inputStr
80 parsed = readJSON inputStr
61 stringified = parsed <#> writeJSON
81 stringified = parsed <#> writeJSON
62 stringified `shouldEqual` (Right expected)
82 stringified `shouldEqual` (Right expected)
63− -- [TODO] Comment in as soon as bug in big-integers is fixed
83+
64− -- it "roundtrips BigInt (2)" do
84+ it "roundtrips BigInt (2)" do
65− -- let
85+ let
66− -- smallBig = BigInt.fromInt 10
86+ smallBig = BigInt.fromInt 10
67− -- big = unsafePartial $ fromJust $ BigInt.fromString "18014398509481982"
87+
68−
69− -- expected = { big, smallBig }
88+ expected = { big, smallBig }
70− -- json = spy "json" $ writeJSON expected
89+ json = writeJSON expected
71−
90+
72− -- parsed ∷ _ ({ big ∷ BigInt, smallBig ∷ BigInt })
91+ parsed ∷ _ ({ big ∷ BigInt, smallBig ∷ BigInt })
73− -- parsed = readJSON json
92+ parsed = readJSON json
74− -- (spy "parsed" parsed) `shouldEqual` (Right expected)
93+ parsed `shouldEqual` (Right expected)
94+
95+ describe "works with JSDate" do
96+ it "roundtrips" do
97+ now ← JSDate.now # liftEffect
98+ roundtrips now
99+ someDate ← JSDate.parse "2022-01-01:00:00:00Z" # liftEffect
100+ let result = writeJSON someDate
101+ let expected = show "2022-01-01T00:00:00.000Z"
102+ result `shouldEqual` expected
103+
104+ describe "works with DateTime" do
105+ it "roundtrips" do
106+ now ← nowDateTime # liftEffect
107+ roundtrips now
108+ someDate ← JSDate.parse "2022-01-01:00:00:00Z" <#> (JSDate.toDateTime >>> fromMaybe' \_ → unsafeCrashWith "nope") # liftEffect
109+ let result = writeJSON someDate
110+ let expected = show "2022-01-01T00:00:00.000Z"
111+ result `shouldEqual` expected
112+
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+
75 describe "works on record types" do
135 describe "works on record types" do
76 it "roundtrips" do
136 it "roundtrips" do
77 roundtrips { a: 12, b: "54" }
137 roundtrips { a: 12, b: "54" }
78 roundtrips { a: 12, b: { c: "54" } }
138 roundtrips { a: 12, b: { c: "54" } }
139+ roundtrips {}
79
140
80 describe "works on newtypes" do
141 describe "works on newtypes" do
81 it "roundtrips" do
142 it "roundtrips" do
@@ -83,41 +144,90 @@ spec = describe "En- and decoding" $ do
83
144
84 describe "works on variant types" do
145 describe "works on variant types" do
85 it "roundtrips" do
146 it "roundtrips" do
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+
86− roundtrips (inj (Proxy :: _ "erwin") "e" :: Variant ("erwin" :: String))
155+ roundtrips (inj (Proxy ∷ _ "erwin") "e" ∷ Variant (erwin ∷ String))
87− roundtrips (inj (Proxy :: _ "jackie") 7 :: Variant ExampleVariant)
156+ roundtrips (inj (Proxy ∷ _ "jackie") 7 ∷ Variant ExampleVariant)
157+
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":{}}""" ]
88
170
89 describe "works on tagged variant types" do
171 describe "works on tagged variant types" do
90 it "roundtrips" do
172 it "roundtrips" do
91− roundtrips (TaggedVariant (erwin "e") :: TaggedVariant "super" "hans" (Erwin ()))
173+ roundtrips (TaggedVariant (erwin "e") ∷ TaggedVariant "super" "hans" (Erwin ()))
92 let bareVariant = erwin "e"
174 let bareVariant = erwin "e"
93− let res = writeJSON (TaggedVariant bareVariant :: TaggedVariant "type" "value" ExampleVariant)
175+ let res = writeJSON (TaggedVariant bareVariant ∷ TaggedVariant "type" "value" ExampleVariant)
94 let expected = """{"value":"e","type":"erwin"}"""
176 let expected = """{"value":"e","type":"erwin"}"""
95 res `shouldEqual` expected
177 res `shouldEqual` expected
96 let
178 let
97− parsed :: _ (TaggedVariant "type" "value" ExampleVariant)
179+ parsed ∷ _ (TaggedVariant "type" "value" ExampleVariant)
98 parsed = readJSON expected
180 parsed = readJSON expected
99 (un TaggedVariant <$> parsed) `shouldEqual` Right bareVariant
181 (un TaggedVariant <$> parsed) `shouldEqual` Right bareVariant
100
182
101 describe "works on untagged variant types" do
183 describe "works on untagged variant types" do
102 it "roundtrips" do
184 it "roundtrips" do
103− roundtrips (UntaggedVariant (erwin "e") :: UntaggedVariant (Erwin ()))
185+ roundtrips (UntaggedVariant (erwin "e") ∷ UntaggedVariant (Erwin ()))
104 let bareVariant = erwin "e"
186 let bareVariant = erwin "e"
105− let res = writeJSON (UntaggedVariant bareVariant :: UntaggedVariant ExampleVariant)
187+ let res = writeJSON (UntaggedVariant bareVariant ∷ UntaggedVariant ExampleVariant)
106− let expected = """"e""""
188+ let expected = "\"e\""
107 res `shouldEqual` expected
189 res `shouldEqual` expected
108 let
190 let
109− parsed :: _ (UntaggedVariant ExampleVariant)
191+ parsed ∷ _ (UntaggedVariant ExampleVariant)
110 parsed = readJSON expected
192 parsed = readJSON expected
111 (un UntaggedVariant <$> parsed) `shouldEqual` Right bareVariant
193 (un UntaggedVariant <$> parsed) `shouldEqual` Right bareVariant
112
194
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+
113−type ExampleVariant = ("erwin" :: String, "jackie" :: Int)
221+type ExampleVariant = ("erwin" ∷ String, "jackie" ∷ Int)
114type ExampleTaggedVariant t v = TaggedVariant t v ExampleVariant
222type ExampleTaggedVariant t v = TaggedVariant t v ExampleVariant
115
223
116−erwin ∷ ∀ a r. a → Variant ( erwin ∷ a | r )
224+erwin ∷ ∀ a r. a → Variant (erwin ∷ a | r)
117−erwin = inj (Proxy :: Proxy "erwin")
225+erwin = inj (Proxy ∷ Proxy "erwin")
226+
118−type Erwin r = (erwin :: String | r)
227+type Erwin r = (erwin ∷ String | r)
119
228
120newtype Stringy = Stringy String
229newtype Stringy = Stringy String
230+
121derive instance Newtype Stringy _
231derive instance Newtype Stringy _
122derive newtype instance Show Stringy
232derive newtype instance Show Stringy
123derive newtype instance Eq Stringy
233derive newtype instance Eq Stringy
@@ -126,9 +236,22 @@ derive newtype instance WriteForeign Stringy
126derive newtype instance ReadForeign Stringy
236derive newtype instance ReadForeign Stringy
127
237
128newtype Inty = Inty Int
238newtype Inty = Inty Int
239+
129derive instance Newtype Inty _
240derive instance Newtype Inty _
130derive newtype instance Show Inty
241derive newtype instance Show Inty
131derive newtype instance Eq Inty
242derive newtype instance Eq Inty
132derive newtype instance Ord Inty
243derive newtype instance Ord Inty
133derive newtype instance WriteForeign Inty
244derive newtype instance WriteForeign Inty
134derive newtype instance ReadForeign Inty
245derive 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/ErrorsSpec.purs+53−5
@@ -3,22 +3,70 @@ module Test.ErrorsSpec where
3import Prelude
3import Prelude
4
4
5import Data.Array as Array
5import Data.Array as Array
6−import Data.Either (blush)
6+import Data.Bifunctor (lmap)
7+import Data.Either (Either(..), blush)
7import Data.Maybe (Maybe(..))
8import Data.Maybe (Maybe(..))
9+import Foreign (ForeignError(..))
10+import Foreign.Object (Object)
8import Test.Spec (Spec, describe, it)
11import Test.Spec (Spec, describe, it)
9import Test.Spec.Assertions (shouldEqual)
12import Test.Spec.Assertions (shouldEqual)
10import Type.Proxy (Proxy(..))
13import Type.Proxy (Proxy(..))
11−import Yoga.JSON (class ReadForeign, readJSON)
14+import Yoga.JSON (class ReadForeign, E, readJSON)
12−import Yoga.JSON.Error (toJSONPath)
15+import Yoga.JSON as JSON
16+import Yoga.JSON.Error (renderHumanError, toJSONPath)
13
17
14spec ∷ Spec Unit
18spec ∷ Spec Unit
15spec = describe "Errors" do
19spec = describe "Errors" do
20+ describe "are returned at once" do
21+ it "returns multiple errors for object" do
22+ let
23+ res ∷ E (Object Int)
24+ res = JSON.readJSON """{ "something": "no", "else": true }"""
25+ e1 = ErrorAtProperty "something" (TypeMismatch "Int" "String")
26+ e2 = ErrorAtProperty "else" (TypeMismatch "Int" "Boolean")
27+ res `shouldEqual` (Left (pure e1 <> pure e2))
28+
29+ it "returns multiple errors for record" do
30+ let
31+ res ∷ E { a ∷ Int, b ∷ String }
32+ res = JSON.readJSON """{ "b": true }"""
33+ e1 = ErrorAtProperty "a" (TypeMismatch "Int" "Undefined")
34+ e2 = ErrorAtProperty "b" (TypeMismatch "String" "Boolean")
35+ res `shouldEqual` (Left (pure e1 <> pure e2))
36+
37+ it "returns multiple errors for array" do
38+ let
39+ res ∷ E (Array Int)
40+ res = JSON.readJSON """[1,"a",2,true]"""
41+ e1 = ErrorAtIndex 1 (TypeMismatch "Int" "String")
42+ e2 = ErrorAtIndex 3 (TypeMismatch "Int" "Boolean")
43+ res `shouldEqual` (Left (pure e1 <> pure e2))
44+
45+ describe "produces human-friendly errors" do
46+ it "For some object" do
47+ let
48+ res ∷ E (Object Int)
49+ res = JSON.readJSON """{ "something": "no", "else": true }"""
50+ e1 = "Must provide a value of type 'Int' instead of 'String' at $.something"
51+ e2 = "Must provide a value of type 'Int' instead of 'Boolean' at $.else"
52+ (res # lmap (map renderHumanError >>> Array.fromFoldable))
53+ `shouldEqual` (Left [ e1, e2 ])
54+
55+ it "For deeply nested keys" do
56+ let
57+ res ∷ E { a ∷ { b ∷ { c ∷ { d ∷ String } } } }
58+ res = JSON.readJSON """{ "a": { "b": { "c": { }}}}"""
59+ e = "Must provide a value of type 'String' at $.a.b.c.d"
60+ (res # lmap (map renderHumanError >>> Array.fromFoldable))
61+ `shouldEqual` (Left [ e ])
62+
16 describe "have the correct JSON path" do
63 describe "have the correct JSON path" do
17 it "empty json" do
64 it "empty json" do
18 (getErrorPath (Proxy ∷ _ {}) "") `shouldEqual` Just [ "$" ]
65 (getErrorPath (Proxy ∷ _ {}) "") `shouldEqual` Just [ "$" ]
19 it "nested json json" do
66 it "nested json json" do
20 let
67 let
21− xo ="""
68+ xo =
69+ """
22 { "deeply": { "nested": { "array":
70 { "deeply": { "nested": { "array":
23 [ { "of": { "values": "hello" } }
71 [ { "of": { "values": "hello" } }
24 , 8
72 , 8
@@ -33,4 +81,4 @@ spec = describe "Errors" do
33getErrorPath ∷ ∀ a. ReadForeign a ⇒ Proxy a → String → Maybe (Array String)
81getErrorPath ∷ ∀ a. ReadForeign a ⇒ Proxy a → String → Maybe (Array String)
34getErrorPath _ x = do
82getErrorPath _ x = do
35 let e = (readJSON x ∷ _ a) # blush
83 let e = (readJSON x ∷ _ a) # blush
36− (e <#> map toJSONPath <#> Array.fromFoldable)
84+ (e <#> map toJSONPath <#> Array.fromFoldable)
test/GenericsSpec.purs+71−20
@@ -9,15 +9,23 @@ import Test.Spec (Spec, describe, it)
9import Test.Spec.Assertions (shouldEqual)
9import Test.Spec.Assertions (shouldEqual)
10import Test.Util (roundtrips)
10import Test.Util (roundtrips)
11import Yoga.JSON (class ReadForeign, class WriteForeign, writeJSON)
11import Yoga.JSON (class ReadForeign, class WriteForeign, writeJSON)
12−import Yoga.JSON.Generics (genericReadForeignTaggedSum, genericWriteForeignTaggedSum)
12+import Yoga.JSON.Generics (defaultOptions, genericReadForeignEnum, genericReadForeignTaggedSum, genericReadForeignUntaggedProduct, genericReadForeignUntaggedSum, genericWriteForeignEnum, genericWriteForeignTaggedSum, genericWriteForeignUntaggedProduct, genericWriteForeignUntaggedSum)
13import Yoga.JSON.Generics as GenericTaggedSum
13import Yoga.JSON.Generics as GenericTaggedSum
14−import Yoga.JSON.Generics.EnumSumRep (genericReadForeignEnum, genericWriteForeignEnum)
14+import Yoga.JSON.Generics.EnumSumRep as Enum
15−import Yoga.JSON.Generics.TaggedSumRep (defaultOptions)
16−import Yoga.JSON.Generics.UntaggedProductRep (genericReadForeignUntaggedProduct, genericWriteForeignUntaggedProduct)
17−import Yoga.JSON.Generics.UntaggedSumRep (genericReadForeignUntaggedSum, genericWriteForeignUntaggedSum)
18
15
19spec ∷ Spec Unit
16spec ∷ Spec Unit
20−spec = describe "Generics" $ do
17+spec = describe "Generics" do
18+
19+ describe "Enum" do
20+ describe "MyEnum = Enum1 | Enum2 | Enum3" do
21+ it "roundtrips" do
22+ roundtrips (Enum1)
23+ roundtrips (Enum3)
24+
25+ describe "works with custom constructor names" do
26+ it "roundtrips" do
27+ roundtrips (SomeOtherEnum2)
28+ writeJSON (SomeThirdEnum3) `shouldEqual` "\"some_third_enum_3\""
21
29
22 describe "Untagged" do
30 describe "Untagged" do
23
31
@@ -56,43 +64,86 @@ spec = describe "Generics" $ do
56 writeJSON (IsEnum) `shouldEqual` """{"kind":"is_enum"}"""
64 writeJSON (IsEnum) `shouldEqual` """{"kind":"is_enum"}"""
57
65
58data HalfEnum = NotEnum Int | IsEnum
66data HalfEnum = NotEnum Int | IsEnum
67+
59derive instance Generic HalfEnum _
68derive instance Generic HalfEnum _
60derive instance Eq HalfEnum
69derive instance Eq HalfEnum
61−instance Show HalfEnum where show = genericShow
70+instance Show HalfEnum where
71+ show = genericShow
72+
62−halfEnumOptions :: GenericTaggedSum.Options
73+halfEnumOptions ∷ GenericTaggedSum.Options
63halfEnumOptions = { typeTag: "kind", valueTag: "data", toConstructorName: snakeCase }
74halfEnumOptions = { typeTag: "kind", valueTag: "data", toConstructorName: snakeCase }
75+
76+instance ReadForeign HalfEnum where
64−instance ReadForeign HalfEnum where readImpl = genericReadForeignTaggedSum halfEnumOptions
77+ readImpl = genericReadForeignTaggedSum halfEnumOptions
78+
79+instance WriteForeign HalfEnum where
65−instance WriteForeign HalfEnum where writeImpl = genericWriteForeignTaggedSum halfEnumOptions
80+ writeImpl = genericWriteForeignTaggedSum halfEnumOptions
66
81
67data MyEnum = Enum1 | Enum2 | Enum3
82data MyEnum = Enum1 | Enum2 | Enum3
68
83
69derive instance Generic MyEnum _
84derive instance Generic MyEnum _
70derive instance Eq MyEnum
85derive instance Eq MyEnum
71−instance Show MyEnum where show = genericShow
86+instance Show MyEnum where
87+ show = genericShow
88+
72−instance ReadForeign MyEnum where readImpl = genericReadForeignEnum
89+instance ReadForeign MyEnum
90+ where
91+ readImpl = genericReadForeignEnum Enum.defaultOptions
92+
73−instance WriteForeign MyEnum where writeImpl = genericWriteForeignEnum
93+instance WriteForeign MyEnum
94+ where
95+ writeImpl = genericWriteForeignEnum Enum.defaultOptions
96+
97+data MyEnum2 = SomeEnum2 | SomeOtherEnum2 | SomeThirdEnum3
98+
99+derive instance Generic MyEnum2 _
100+derive instance Eq MyEnum2
101+instance Show MyEnum2 where
102+ show = genericShow
103+
104+instance ReadForeign MyEnum2
105+ where
106+ readImpl = genericReadForeignEnum { toConstructorName: snakeCase }
107+
108+instance WriteForeign MyEnum2
109+ where
110+ writeImpl = genericWriteForeignEnum { toConstructorName: snakeCase }
74
111
75data IntOrString = AnInt Int | AString String
112data IntOrString = AnInt Int | AString String
113+
76derive instance Generic IntOrString _
114derive instance Generic IntOrString _
77derive instance Eq IntOrString
115derive instance Eq IntOrString
78−instance Show IntOrString where show = genericShow
116+instance Show IntOrString where
117+ show = genericShow
118+
119+instance ReadForeign IntOrString where
79−instance ReadForeign IntOrString where readImpl = genericReadForeignUntaggedSum
120+ readImpl = genericReadForeignUntaggedSum
121+
122+instance WriteForeign IntOrString where
80−instance WriteForeign IntOrString where writeImpl = genericWriteForeignUntaggedSum
123+ writeImpl = genericWriteForeignUntaggedSum
81
124
82data DoubleTrouble = IntAndString Int String
125data DoubleTrouble = IntAndString Int String
83
126
84derive instance Generic DoubleTrouble _
127derive instance Generic DoubleTrouble _
85derive instance Eq DoubleTrouble
128derive instance Eq DoubleTrouble
86−instance Show DoubleTrouble where show = genericShow
129+instance Show DoubleTrouble where
130+ show = genericShow
131+
132+instance ReadForeign DoubleTrouble where
87−instance ReadForeign DoubleTrouble where readImpl = genericReadForeignUntaggedProduct
133+ readImpl = genericReadForeignUntaggedProduct
134+
135+instance WriteForeign DoubleTrouble where
88−instance WriteForeign DoubleTrouble where writeImpl = genericWriteForeignUntaggedProduct
136+ writeImpl = genericWriteForeignUntaggedProduct
89
137
90data IntOrStringTagged = ATaggedInt Int | ATaggedString String
138data IntOrStringTagged = ATaggedInt Int | ATaggedString String
91
139
92derive instance Generic IntOrStringTagged _
140derive instance Generic IntOrStringTagged _
93derive instance Eq IntOrStringTagged
141derive instance Eq IntOrStringTagged
94−instance Show IntOrStringTagged where show = genericShow
142+instance Show IntOrStringTagged where
143+ show = genericShow
144+
95instance ReadForeign IntOrStringTagged where
145instance ReadForeign IntOrStringTagged where
96 readImpl = genericReadForeignTaggedSum defaultOptions
146 readImpl = genericReadForeignTaggedSum defaultOptions
147+
97instance WriteForeign IntOrStringTagged where
148instance WriteForeign IntOrStringTagged where
98 writeImpl = genericWriteForeignTaggedSum defaultOptions
149 writeImpl = genericWriteForeignTaggedSum defaultOptions
test/Main.purs+4−3
@@ -4,11 +4,12 @@ import Prelude
4
4
5import Effect (Effect)
5import Effect (Effect)
6import Effect.Aff (launchAff_)
6import Effect.Aff (launchAff_)
7+import Effect.Class (liftEffect)
7import Test.Spec.Discovery (discover)
8import Test.Spec.Discovery (discover)
8import Test.Spec.Reporter (consoleReporter)
9import Test.Spec.Reporter (consoleReporter)
9−import Test.Spec.Runner (runSpec)
10+import Test.Spec.Runner.Node (runSpecAndExitProcess)
10
11
11−main :: Effect Unit
12+main ∷ Effect Unit
12main = launchAff_ $
13main = launchAff_ $
13 discover """\..*Spec"""
14 discover """\..*Spec"""
14− >>= runSpec [consoleReporter]
15+ >>= runSpecAndExitProcess [ consoleReporter ] >>> liftEffect
test/Util.purs+5−5
@@ -5,11 +5,11 @@ import Prelude
5import Data.Either (Either(..))
5import Data.Either (Either(..))
6import Data.Semigroup.Foldable (intercalateMap)
6import Data.Semigroup.Foldable (intercalateMap)
7import Effect.Aff (Aff)
7import Effect.Aff (Aff)
8−import Foreign (Foreign, renderForeignError)
8+import Foreign (Foreign)
9import Test.Spec.Assertions (fail)
9import Test.Spec.Assertions (fail)
10import Type.Proxy (Proxy(..))
10import Type.Proxy (Proxy(..))
11import Yoga.JSON (class ReadForeign, class WriteForeign, read, readJSON, write, writeJSON)
11import Yoga.JSON (class ReadForeign, class WriteForeign, read, readJSON, write, writeJSON)
12−import Yoga.JSON.Error (toJSONPath)
12+import Yoga.JSON.Error (renderHumanError, toJSONPath)
13
13
14roundtrips ∷ ∀ a. Show a ⇒ Eq a ⇒ ReadForeign a ⇒ WriteForeign a ⇒ a → Aff Unit
14roundtrips ∷ ∀ a. Show a ⇒ Eq a ⇒ ReadForeign a ⇒ WriteForeign a ⇒ a → Aff Unit
15roundtrips x = do
15roundtrips x = do
@@ -18,10 +18,10 @@ roundtrips x = do
18
18
19shouldRead ∷ ∀ a. ReadForeign a ⇒ Proxy a → Foreign → Aff Unit
19shouldRead ∷ ∀ a. ReadForeign a ⇒ Proxy a → Foreign → Aff Unit
20shouldRead _ = read >>> case _ of
20shouldRead _ = read >>> case _ of
21− Left e → fail (intercalateMap "\n" renderForeignError e <> "\n" <> intercalateMap "\n" toJSONPath e)
21+ Left e → fail (intercalateMap "\n" renderHumanError e <> "\n" <> intercalateMap "\n" toJSONPath e)
22 Right (_ ∷ a) → pure unit
22 Right (_ ∷ a) → pure unit
23
23
24shouldReadJSON ∷ ∀ a. ReadForeign a ⇒ Proxy a → String → Aff Unit
24shouldReadJSON ∷ ∀ a. ReadForeign a ⇒ Proxy a → String → Aff Unit
25shouldReadJSON _ = readJSON >>> case _ of
25shouldReadJSON _ = readJSON >>> case _ of
26− Left e → fail (intercalateMap "\n" renderForeignError e <> "\n" <> intercalateMap "\n" toJSONPath e)
26+ Left e → fail (intercalateMap "\n" renderHumanError e <> "\n" <> intercalateMap "\n" toJSONPath e)
27− Right (_ ∷ a) → pure unit
27+ Right (_ ∷ a) → pure unit
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