diff --git a/.envrc b/.envrc index 3550a30f..22e250e0 100644 --- a/.envrc +++ b/.envrc @@ -1 +1,3 @@ +watch_file flake.lock +watch_file flake.nix use flake diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index 4e341f00..646325e0 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -1,6 +1,10 @@ # modified from https://github.com/jgm/pandoc/blob/master/.github/workflows/ci.yml name: Haskell library and example +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + on: push: branches: @@ -17,16 +21,12 @@ jobs: fail-fast: false matrix: versions: - - ghc: '8.6.5' - cabal: '3.6' - - ghc: '8.8.4' - cabal: '3.6' - - ghc: '8.10.4' - cabal: '3.6' - - ghc: '9.0.2' - cabal: '3.6' - ghc: '9.2.4' cabal: '3.6' + - ghc: '9.4.6' + cabal: '3.6' + # - ghc: '9.6.3' + # cabal: '3.6' steps: - uses: actions/checkout@v2 @@ -58,13 +58,49 @@ jobs: dist-newstyle key: ${{ runner.os }}-${{ matrix.versions.ghc }}-${{ matrix.versions.cabal }}-cabal-local + # - name: Set up a PureScript toolchain + # uses: purescript-contrib/setup-purescript@main + # with: # https://github.com/purescript-contrib/setup-purescript#specify-versions + # spago: "latest" + # purescript: "0.15.13" + + - name: Set up new Spago + run: npm install -g spago@next purescript + + - name: Cache PureScript dependencies + uses: actions/cache@v2 + with: + key: ${{ runner.os }}-spago-${{ hashFiles('**/*.dhall') }} + path: | + .spago + output + test/RoundTripArgonautAesonGeneric/app/output + test/RoundTripJsonHelpers/app/output + - name: Install dependencies run: | - cabal update - cabal build all --dependencies-only --enable-tests --disable-optimization - - name: Build + cabal update + cabal build all --dependencies-only --enable-tests --disable-optimization + - name: Build Haskell + run: | + cabal build all --enable-tests --disable-optimization 2>&1 | tee build.log + - name: Build PureScript Argonaut test project + run: | + cd test/RoundTripArgonautAesonGeneric/app + spago build + - name: Build PureScript JsonHelpers test project run: | - cabal build all --enable-tests --disable-optimization 2>&1 | tee build.log + cd test/RoundTripJsonHelpers/app + spago build - name: Test run: | - cabal test all --disable-optimization + # There are two PureScript projects which the Haskell tests build and run. + # The first build produces warnings which cause the Haskell tests to fail; + # pre-building these two projects clears these warnings. + cd test/RoundTripArgonautAesonGeneric/app + spago build + cd ../../../ + cd test/RoundTripJsonHelpers/app + spago build + cd ../../../ + cabal test all --disable-optimization diff --git a/.github/workflows/nix-flake.yml b/.github/workflows/nix-flake.yml index d09c9898..95277b2d 100644 --- a/.github/workflows/nix-flake.yml +++ b/.github/workflows/nix-flake.yml @@ -6,7 +6,10 @@ jobs: tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v20 - - run: nix build - # - run: nix flake check + - uses: actions/checkout@v3 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - name: "Check `nix develop` shell" + run: nix develop --check + - run: nix build + - run: nix flake check diff --git a/.github/workflows/purescript.yml b/.github/workflows/purescript.yml index 551e38bb..d1078215 100644 --- a/.github/workflows/purescript.yml +++ b/.github/workflows/purescript.yml @@ -19,10 +19,14 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up a PureScript toolchain - uses: purescript-contrib/setup-purescript@main - with: # https://github.com/purescript-contrib/setup-purescript#specify-versions - purescript: "0.15.4" + # - name: Set up a PureScript toolchain + # uses: purescript-contrib/setup-purescript@main + # with: # https://github.com/purescript-contrib/setup-purescript#specify-versions + # spago: "latest" + # purescript: "0.15.13" + + - name: Set up new Spago + run: npm install -g spago@next purescript - name: Cache PureScript dependencies uses: actions/cache@v2 @@ -38,10 +42,10 @@ jobs: spago install - name: Build source - run: spago build --no-install + run: spago build - name: Bundle app - run: spago bundle-app --to static/index.js + run: spago bundle --bundle-type app --outfile static/index.js - name: Run tests - run: spago test --no-install + run: spago test diff --git a/.gitignore b/.gitignore index 9e7215ab..d5b93e03 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ cabal.sandbox.config dist dist-* shell.nix -stack.yaml .dir-locals.el .psc-ide-port diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..8c7a8bb7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,15 @@ +# Changelog for purescript-bridge + +## 0.16.0.0 (unreleased) +* merge https://github.com/input-output-hk/purescript-bridge +* support https://github.com/input-output-hk/purescript-bridge-json-helpers +* `CodeGenSwitches` no longer used +* `Proxy` no longer used +* `Printer` uses `Leijen.Text` instead of `Text` +* `genericShow` PureScript instance from IOHK + * I think the same as https://github.com/eskimor/purescript-bridge/pull/85 + * PR 85 has been replaced with IOHK's implementation +* some unit tests replaced with IOHK's tests +* all printer imports are combined into one function `instanceToImportLines` instead of being divided between two modules +* excellent `RoundTrip` tests implemented by IOHK + * greatly improves test coverage for both Argonaut and `json-helpers` and exposes issues diff --git a/README.md b/README.md index 2ceb6eb5..d0f6bf28 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,99 @@ # purescript-bridge - - -[![Haskell library and example](https://github.com/eskimor/purescript-bridge/actions/workflows/haskell.yml/badge.svg)](https://github.com/eskimor/purescript-bridge/actions/workflows/haskell.yml) [![Purescript example](https://github.com/eskimor/purescript-bridge/actions/workflows/purescript.yml/badge.svg)](https://github.com/eskimor/purescript-bridge/actions/workflows/purescript.yml) [![Nix Flake](https://github.com/eskimor/purescript-bridge/actions/workflows/nix-flake.yml/badge.svg)](https://github.com/eskimor/purescript-bridge/actions/workflows/nix-flake.yml) - - +[![Haskell library and example](https://github.com/eskimor/purescript-bridge/actions/workflows/haskell.yml/badge.svg)](https://github.com/eskimor/purescript-bridge/actions/workflows/haskell.yml) [![PureScript example](https://github.com/eskimor/purescript-bridge/actions/workflows/purescript.yml/badge.svg)](https://github.com/eskimor/purescript-bridge/actions/workflows/purescript.yml) [![Nix Flake](https://github.com/eskimor/purescript-bridge/actions/workflows/nix-flake.yml/badge.svg)](https://github.com/eskimor/purescript-bridge/actions/workflows/nix-flake.yml) Translate your Haskell types to PureScript types. It should in theory work for almost all Haskell types, including type constructors! You just have to instantiate it with dummy parameters from e.g. "Language.PureScript.Bridge.TypeParameters". Data type translation is fully and easily customizable by providing your own `BridgePart` instances! -The latest version of this project requires **Purescript 0.15**. +The latest version of this project requires **PureScript 0.15**. ## JSON encoding / decoding +### Haskell +Use [`aeson`](http://hackage.haskell.org/package/aeson)'s generic encoding/decoding with default options + +### PureScript +There are three PureScript libraries which can interface with Aeson through PureScript bridge. The second, `purescript-argonaut-aeson-generic`, has issues. -For compatible JSON representations: +#### [`input-output-hk/purescript-bridge-json-helpers`](https://github.com/input-output-hk/purescript-bridge-json-helpers.git) + +Enable this on the Haskell side with `Language.PureScript.Bridge.SumType.jsonHelpers`. + + +* this library is demonstrated by the `example`; see `./example/readme.md`. +* see `./test/RoundTripJsonHelpers` for an additional example +* sample Dhall config (for [spago-legacy](https://github.com/purescript/spago-legacy)): +``` +, json-helpers = + { dependencies = + [ "aff" + , "argonaut-codecs" + , "argonaut-core" + , "arrays" + , "bifunctors" + , "contravariant" + , "control" + , "effect" + , "either" + , "enums" + , "foldable-traversable" + , "foreign-object" + , "maybe" + , "newtype" + , "ordered-collections" + , "prelude" + , "profunctor" + , "psci-support" + , "quickcheck" + , "record" + , "spec" + , "spec-quickcheck" + , "transformers" + , "tuples" + , "typelevel-prelude" + ] + , repo = + "https://github.com/input-output-hk/purescript-bridge-json-helpers.git" + , version = "486db9ee62882baa42cca24f556848c5f6bec565" + } +``` +#### [`purescript-argonaut-aeson-generic >=0.4.1`](https://pursuit.purescript.org/packages/purescript-argonaut-aeson-generic/0.4.1) ([GitHub](https://github.com/coot/purescript-argonaut-aeson-generic)) -* On Haskell side: - * Use [`aeson`](http://hackage.haskell.org/package/aeson)'s generic encoding/decoding with default options -* On Purescript side: - * Use [`purescript-argonaut-aeson-generic >=0.4.1`](https://pursuit.purescript.org/packages/purescript-argonaut-aeson-generic/0.4.1) ([GitHub](https://github.com/coot/purescript-argonaut-aeson-generic)) - * Or use [`purescript-foreign-generic`](https://pursuit.purescript.org/packages/purescript-foreign-generic). - * [This branch](https://github.com/paf31/purescript-foreign-generic/pull/76) is updated for Purescript 0.15. +Enable this on the Haskell side with `Language.PureScript.Bridge.SumType.argonautAesonGeneric`. + +**TODO**: [resolve incompatibility between Argonaut and Aeson](https://github.com/purescript-contrib/purescript-argonaut-codecs/issues/115) + +**Additional requirement**: [`peterbecich/purescript-argonaut-codecs`](https://github.com/peterbecich/purescript-argonaut-codecs.git) +* commit `04abb3eb24a4deafe125be0eb23e2786c642e66b` +* this library is demonstrated by the `example`; see `./example/readme.md`. +* see `./test/RoundTripArgonautAesonGeneric` for additional example + * note that some types have been disabled from the `RoundTripArgonautAesonGeneric` test + * `RoundTripJsonHelpers` tests more types + * the types tested can be expanded when the incompatibility issue is resolved +* sample Dhall config: +``` + , argonaut-codecs = + { dependencies = [ "console" ] + , repo = "https://github.com/peterbecich/purescript-argonaut-codecs.git" + , version = "04abb3eb24a4deafe125be0eb23e2786c642e66b" + } +``` +* forked from [`purescript-contrib/purescript-argonaut-codecs`](https://github.com/purescript-contrib/purescript-argonaut-codecs) + +#### [`paf31/purescript-foreign-generic`](https://github.com/paf31/purescript-foreign-generic) + +See `ForeignObject` in `Language.PureScript.Bridge.SumType`. + +This may need to be fixed. + +The test coverage is less than the other two libraries. ## Documentation Usage of this library is documented in `Language.Purescript.Bridge`, with `writePSTypes` you should have everything to get started. Documentation can be found [here](https://www.stackage.org/nightly/package/purescript-bridge). +There is an example; see `./example/readme.md`. + ## Status It works for my use case and is used in production. PRs for more `PSType`s definitions and bridges are very welcome! diff --git a/cabal.project b/cabal.project index 13f1d515..be700cd3 100644 --- a/cabal.project +++ b/cabal.project @@ -1,3 +1,5 @@ packages: . example/. + +tests: true diff --git a/development.md b/development.md new file mode 100644 index 00000000..1c19ae8c --- /dev/null +++ b/development.md @@ -0,0 +1,14 @@ +# Regenerate everything +reset && stack run generate-purescript && mv src/Argonaut/* example/src/Argonaut && mv src/JsonHelpers/* example/src/JsonHelpers; cd example && spago bundle --bundle-type app --outfile static/index.js; cd .. + +# Regenerate purescript files +reset && cd example && spago bundle --bundle-type app --outfile static/index.js; cd .. + +# Roundtrip server example + +## Tab 1 +stack run example + +## Tab 2 +cd example/static +parcel serve index.html diff --git a/example/app/GeneratePurescript.hs b/example/app/GeneratePurescript.hs index c86d2b22..a4e7e5a3 100644 --- a/example/app/GeneratePurescript.hs +++ b/example/app/GeneratePurescript.hs @@ -3,21 +3,22 @@ module Main where import Control.Lens import Data.Text (pack) import Language.PureScript.Bridge -import Language.PureScript.Bridge.CodeGenSwitches (ForeignOptions (ForeignOptions), - genForeign, - useGenRep) +import ArgonautTypes +import JsonHelpersTypes import qualified MyLib -import Types - -frontEndRoot :: String -frontEndRoot = "src" +import Types (myBridge) -- https://discourse.purescript.org/t/latest-and-greatest-haskell-purescript-serialization/1640/6 main :: IO () main = do - writePSTypesWith - (useGenRep <> genForeign (ForeignOptions False False)) - frontEndRoot + writePSTypesWithNamespace + (Just . PackageName $ pack "Argonaut") + "src" + (buildBridge myBridge) + myArgonautTypes + writePSTypesWithNamespace + (Just . PackageName $ pack "JsonHelpers") + "src" (buildBridge myBridge) - myTypes + myJsonHelpersTypes diff --git a/example/app/Main.hs b/example/app/Main.hs index 76b06e88..c538f02f 100644 --- a/example/app/Main.hs +++ b/example/app/Main.hs @@ -1,8 +1,25 @@ module Main where +import ArgonautTypes +import Control.Lens +import Data.Text (pack) +import JsonHelpersTypes +import Language.PureScript.Bridge import qualified MyLib (main) +import Types main :: IO () main = do - putStrLn "Hello, Haskell!" + -- generate PureScript before server starts + writePSTypesWithNamespace + (Just . PackageName $ pack "Argonaut") + "src" + (buildBridge myBridge) + myArgonautTypes + writePSTypesWithNamespace + (Just . PackageName $ pack "JsonHelpers") + "src" + (buildBridge myBridge) + myJsonHelpersTypes + MyLib.main diff --git a/example/example.cabal b/example/example.cabal index 61cd2406..7654fa47 100644 --- a/example/example.cabal +++ b/example/example.cabal @@ -9,7 +9,7 @@ build-type: Simple extra-source-files: CHANGELOG.md library - exposed-modules: MyLib, Types + exposed-modules: MyLib, Types, ArgonautTypes, JsonHelpersTypes hs-source-dirs: src build-depends: base >=4.8 && <5 , aeson >= 1.5.5.0 @@ -23,12 +23,17 @@ library , text , warp , purescript-bridge + , QuickCheck default-language: Haskell2010 executable example main-is: Main.hs hs-source-dirs: app - build-depends: base >=4.8 && <5, example + build-depends: base >=4.8 && <5 + , example + , purescript-bridge + , text + , lens default-language: Haskell2010 executable generate-purescript diff --git a/example/packages.dhall b/example/packages.dhall deleted file mode 100644 index 90bb1736..00000000 --- a/example/packages.dhall +++ /dev/null @@ -1,35 +0,0 @@ -let upstream = - https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20220901/packages.dhall - sha256:f1531b29c21ac437ffe5666c1b6cc76f0a9c29d3c9d107ff047aa2567744994f - -let additions = - { argonaut-aeson-generic = - { dependencies = - [ "argonaut" - , "argonaut-codecs" - , "argonaut-generic" - , "console" - , "effect" - , "foreign-object" - , "test-unit" - ] - , repo = - "https://github.com/coot/purescript-argonaut-aeson-generic.git" - , version = "v0.4.1" - } - , foreign-generic = - { dependencies = - [ "effect" - , "foreign" - , "foreign-object" - , "ordered-collections" - , "exceptions" - , "record" - , "identity" - ] - , repo = "https://github.com/jsparkes/purescript-foreign-generic.git" - , version = "844f2ababa2c7a0482bf871e1e6bf970b7e51313" - } - } - -in upstream // additions diff --git a/example/readme.md b/example/readme.md index c4eb963a..a9d787f6 100644 --- a/example/readme.md +++ b/example/readme.md @@ -1,23 +1,41 @@ -# Purescript Bridge example +# PureScript Bridge example -This project demonstrates the libraries Purescript Bridge and [`purescript-argonaut-aeson-generic`](https://pursuit.purescript.org/packages/purescript-argonaut-aeson-generic) ([GitHub](https://github.com/coot/purescript-argonaut-aeson-generic)). +This project demonstrates: +- PureScript Bridge +- [`purescript-argonaut-aeson-generic`](https://pursuit.purescript.org/packages/purescript-argonaut-aeson-generic) ([GitHub](https://github.com/coot/purescript-argonaut-aeson-generic)) +- [`input-output-hk/purescript-bridge-json-helpers`](https://github.com/input-output-hk/purescript-bridge-json-helpers.git) -It needs Purescript 0.15. +The Haskell type `Foo`, in `src/Types.hs`, is generated for PureScript by PureScript Bridge. Some of values in `Foo` are randomly generated every time the page is loaded. -The Haskell type `Foo`, in `src/Types.hs`, is generated for Purescript by Purescript Bridge. Purescript Argonaut Aeson Generic is used to decode and encode this type, client-side. +On page load, the client: +- requests a `Foo` from the server +- decodes this value using `purescript-argonaut-aeson-generic` +- modifies some of the values +- encodes this with `purescript-argonaut-aeson-generic`, and sends it back to the server +- repeats these steps, encoding and decoding instead with `json-helpers` -In this directory: +# Dependencies +## Nix +The `nix develop` shell will provide PureScript 0.15 and Spago. +## Without Nix +You must install PureScript 0.15 and [spago-legacy](https://github.com/purescript/spago-legacy). -- Generate the Javascript bundle: +# Running the example +- Enter the `example` directory -```spago bundle-app --to static/index.js``` +- With Nix: +``` +nix run +``` -- `cabal run example` +- Or without Nix: +``` +cabal run example +``` - Open [http://localhost:8080/index.html](http://localhost:8080/index.html) - Open the browser's developer console and look for the message received: - ``` Foo message: Hello Foo number: 123 Foo list length: 11 ``` @@ -28,10 +46,24 @@ Foo message: Hello Foo number: 123 Foo list length: 11 Foo message: Hola Foo number: 124 Foo list length: 22 ``` ----------------- +# Updating the PureScript Bridge +- Enter the `example` directory + +- Regenerate the PureScript Bridge types: +``` +cabal run generate-purescript +``` + +- Generate the Javascript bundle: +``` +spago bundle-app --to static/index.js +``` +- or: +``` +spago bundle-app --watch --to static/index.js +``` -Regenerate the Purescript for the bridge type `Foo` with `cabal run generate-purescript`. +- Restart the server ----------------- -This Purescript Discourse thread assisted me: https://discourse.purescript.org/t/latest-and-greatest-haskell-purescript-serialization/1640 +More discussion: https://discourse.purescript.org/t/latest-and-greatest-haskell-purescript-serialization/1640 diff --git a/example/spago.dhall b/example/spago.dhall deleted file mode 100644 index 0a650982..00000000 --- a/example/spago.dhall +++ /dev/null @@ -1,23 +0,0 @@ -{ name = "purescript-bridge-example" -, dependencies = - [ "console" - , "effect" - , "foreign-generic" - , "profunctor-lenses" - , "aff" - , "affjax" - , "affjax-web" - , "argonaut-aeson-generic" - , "ordered-collections" - , "argonaut-codecs" - , "argonaut-generic" - , "either" - , "foldable-traversable" - , "foreign-object" - , "maybe" - , "newtype" - , "prelude" - ] -, packages = ./packages.dhall -, sources = [ "src/**/*.purs", "test/**/*.purs" ] -} diff --git a/example/spago.lock b/example/spago.lock new file mode 100644 index 00000000..78d376f4 --- /dev/null +++ b/example/spago.lock @@ -0,0 +1,1627 @@ +workspace: + packages: + bridge-example: + path: ./ + dependencies: + - aff + - affjax + - affjax-web + - argonaut + - argonaut-aeson-generic + - argonaut-codecs + - argonaut-generic + - console + - control + - effect + - either + - foldable-traversable + - foreign-generic + - foreign-object + - json-helpers + - maybe + - newtype + - ordered-collections + - prelude + - profunctor-lenses + - tuples + test_dependencies: [] + build_plan: + - aff + - affjax + - affjax-web + - ansi + - argonaut + - argonaut-aeson-generic + - argonaut-codecs + - argonaut-core + - argonaut-generic + - argonaut-traversals + - arraybuffer-types + - arrays + - avar + - bifunctors + - catenable-lists + - console + - const + - contravariant + - control + - datetime + - distributive + - effect + - either + - enums + - exceptions + - exists + - foldable-traversable + - foreign + - foreign-generic + - foreign-object + - fork + - form-urlencoded + - free + - functions + - functors + - gen + - http-methods + - identity + - integers + - invariant + - js-date + - js-timers + - js-uri + - json-helpers + - lazy + - lcg + - lists + - maybe + - media-types + - mmorph + - newtype + - nonempty + - now + - nullable + - numbers + - ordered-collections + - orders + - parallel + - partial + - pipes + - prelude + - profunctor + - profunctor-lenses + - psci-support + - quickcheck + - random + - record + - refs + - safe-coerce + - spec + - spec-quickcheck + - st + - strings + - tailrec + - test-unit + - transformers + - tuples + - type-equality + - typelevel-prelude + - unfoldable + - unsafe-coerce + - web-dom + - web-events + - web-file + - web-html + - web-storage + - web-xhr + package_set: + address: + registry: 50.1.0 + compiler: ">=0.15.14 <0.16.0" + content: + abc-parser: 2.0.1 + ace: 9.1.0 + aff: 7.1.0 + aff-bus: 6.0.0 + aff-coroutines: 9.0.0 + aff-promise: 4.0.0 + aff-retry: 2.0.0 + affjax: 13.0.0 + affjax-node: 1.0.0 + affjax-web: 1.0.0 + ansi: 7.0.0 + applicative-phases: 1.0.0 + argonaut: 9.0.0 + argonaut-aeson-generic: 0.4.1 + argonaut-codecs: 9.1.0 + argonaut-core: 7.0.0 + argonaut-generic: 8.0.0 + argonaut-traversals: 10.0.0 + argparse-basic: 2.0.0 + array-builder: 0.1.2 + array-search: 0.5.6 + arraybuffer: 13.2.0 + arraybuffer-builder: 3.1.0 + arraybuffer-types: 3.0.2 + arrays: 7.3.0 + arrays-extra: 0.6.1 + arrays-zipper: 2.0.1 + ask: 1.0.0 + assert: 6.0.0 + assert-multiple: 0.3.4 + avar: 5.0.0 + b64: 0.0.8 + barbies: 1.0.1 + barlow-lens: 0.9.0 + bifunctors: 6.0.0 + bigints: 7.0.1 + bolson: 0.3.9 + bookhound: 0.1.7 + bower-json: 3.0.0 + call-by-name: 4.0.1 + canvas: 6.0.0 + canvas-action: 9.0.0 + cartesian: 1.0.6 + catenable-lists: 7.0.0 + chameleon: 1.0.0 + chameleon-halogen: 1.0.3 + chameleon-react-basic: 1.1.0 + chameleon-styled: 2.5.0 + chameleon-transformers: 1.0.0 + channel: 1.0.0 + checked-exceptions: 3.1.1 + choku: 1.0.1 + classless: 0.1.1 + classless-arbitrary: 0.1.1 + classless-decode-json: 0.1.1 + classless-encode-json: 0.1.3 + classnames: 2.0.0 + codec: 6.1.0 + codec-argonaut: 10.0.0 + codec-json: 1.1.0 + colors: 7.0.1 + concur-core: 0.5.0 + concur-react: 0.5.0 + concurrent-queues: 3.0.0 + console: 6.1.0 + const: 6.0.0 + contravariant: 6.0.0 + control: 6.0.0 + convertable-options: 1.0.0 + coroutines: 7.0.0 + css: 6.0.0 + css-frameworks: 1.0.1 + data-mvc: 0.0.2 + datetime: 6.1.0 + datetime-parsing: 0.2.0 + debug: 6.0.2 + decimals: 7.1.0 + default-values: 1.0.1 + deku: 0.9.23 + deno: 0.0.5 + dissect: 1.0.0 + distributive: 6.0.0 + dom-filereader: 7.0.0 + dom-indexed: 12.0.0 + dotenv: 4.0.3 + droplet: 0.6.0 + dts: 1.0.0 + dual-numbers: 1.0.2 + dynamic-buffer: 3.0.1 + echarts-simple: 0.0.1 + effect: 4.0.0 + either: 6.1.0 + elmish: 0.11.3 + elmish-enzyme: 0.1.1 + elmish-hooks: 0.10.0 + elmish-html: 0.8.2 + elmish-testing-library: 0.3.2 + email-validate: 7.0.0 + encoding: 0.0.9 + enums: 6.0.1 + env-names: 0.3.4 + error: 2.0.0 + eta-conversion: 0.3.2 + exceptions: 6.0.0 + exists: 6.0.0 + exitcodes: 4.0.0 + expect-inferred: 3.0.0 + fahrtwind: 2.0.0 + fallback: 0.1.0 + fast-vect: 1.2.0 + fetch: 4.1.0 + fetch-argonaut: 1.0.1 + fetch-core: 5.1.0 + fetch-yoga-json: 1.1.0 + fft-js: 0.1.0 + filterable: 5.0.0 + fix-functor: 0.1.0 + fixed-points: 7.0.0 + fixed-precision: 5.0.0 + flame: 1.3.0 + float32: 2.0.0 + fmt: 0.2.1 + foldable-traversable: 6.0.0 + foldable-traversable-extra: 0.0.6 + foreign: 7.0.0 + foreign-object: 4.1.0 + foreign-readwrite: 3.4.0 + forgetmenot: 0.1.0 + fork: 6.0.0 + form-urlencoded: 7.0.0 + formatters: 7.0.0 + framer-motion: 1.0.1 + free: 7.1.0 + freeap: 7.0.0 + freer-free: 0.0.1 + freet: 7.0.0 + functions: 6.0.0 + functor1: 3.0.0 + functors: 5.0.0 + fuzzy: 0.4.0 + gen: 4.0.0 + generate-values: 1.0.1 + generic-router: 0.0.1 + geojson: 0.0.5 + geometry-plane: 1.0.3 + gojs: 0.1.1 + grain: 3.0.0 + grain-router: 3.0.0 + grain-virtualized: 3.0.0 + graphs: 8.1.0 + group: 4.1.1 + halogen: 7.0.0 + halogen-bootstrap5: 5.3.2 + halogen-canvas: 1.0.0 + halogen-css: 10.0.0 + halogen-echarts-simple: 0.0.4 + halogen-formless: 4.0.3 + halogen-helix: 1.0.0 + halogen-hooks: 0.6.3 + halogen-hooks-extra: 0.9.0 + halogen-infinite-scroll: 1.1.0 + halogen-store: 0.5.4 + halogen-storybook: 2.0.0 + halogen-subscriptions: 2.0.0 + halogen-svg-elems: 8.0.0 + halogen-typewriter: 1.0.4 + halogen-vdom: 8.0.0 + halogen-vdom-string-renderer: 0.5.0 + halogen-xterm: 2.0.0 + heckin: 2.0.1 + heterogeneous: 0.6.0 + homogeneous: 0.4.0 + http-methods: 6.0.0 + httpurple: 4.0.0 + humdrum: 0.0.1 + hyrule: 2.3.8 + identity: 6.0.0 + identy: 4.0.1 + indexed-db: 1.0.0 + indexed-monad: 3.0.0 + int64: 3.0.0 + integers: 6.0.0 + interpolate: 5.0.2 + intersection-observer: 1.0.1 + invariant: 6.0.0 + jarilo: 1.0.1 + jelly: 0.10.0 + jelly-router: 0.3.0 + jelly-signal: 0.4.0 + jest: 1.0.0 + js-abort-controller: 1.0.0 + js-bigints: 2.2.1 + js-date: 8.0.0 + js-fetch: 0.2.1 + js-fileio: 3.0.0 + js-intl: 1.0.4 + js-iterators: 0.1.1 + js-maps: 0.1.2 + js-promise: 1.0.0 + js-promise-aff: 1.0.0 + js-timers: 6.1.0 + js-uri: 3.1.0 + json: 1.0.0 + json-codecs: 5.0.0 + justifill: 0.5.0 + jwt: 0.0.9 + labeled-data: 0.2.0 + lazy: 6.0.0 + lazy-joe: 1.0.0 + lcg: 4.0.0 + leibniz: 5.0.0 + leveldb: 1.0.1 + liminal: 1.0.1 + linalg: 6.0.0 + lists: 7.0.0 + literals: 1.0.2 + logging: 3.0.0 + logging-journald: 0.4.0 + lumi-components: 18.0.0 + machines: 7.0.0 + maps-eager: 0.4.1 + marionette: 1.0.0 + marionette-react-basic-hooks: 0.1.1 + marked: 0.1.0 + matrices: 5.0.1 + matryoshka: 1.0.0 + maybe: 6.0.0 + media-types: 6.0.0 + meowclient: 1.0.0 + midi: 4.0.0 + milkis: 9.0.0 + minibench: 4.0.1 + mmorph: 7.0.0 + monad-control: 5.0.0 + monad-logger: 1.3.1 + monad-loops: 0.5.0 + monad-unlift: 1.0.1 + monoid-extras: 0.0.1 + monoidal: 0.16.0 + morello: 0.4.0 + mote: 3.0.0 + motsunabe: 2.0.0 + mvc: 0.0.1 + mysql: 6.0.1 + n3: 0.1.0 + nano-id: 1.1.0 + nanoid: 0.1.0 + naturals: 3.0.0 + nested-functor: 0.2.1 + newtype: 5.0.0 + nextjs: 0.1.1 + nextui: 0.2.0 + node-buffer: 9.0.0 + node-child-process: 11.1.0 + node-event-emitter: 3.0.0 + node-execa: 5.0.0 + node-fs: 9.1.0 + node-glob-basic: 1.3.0 + node-http: 9.1.0 + node-http2: 1.1.1 + node-human-signals: 1.0.0 + node-net: 5.1.0 + node-os: 5.1.0 + node-path: 5.0.0 + node-process: 11.2.0 + node-readline: 8.1.0 + node-sqlite3: 8.0.0 + node-streams: 9.0.0 + node-tls: 0.3.1 + node-url: 7.0.1 + node-zlib: 0.4.0 + nonempty: 7.0.0 + now: 6.0.0 + npm-package-json: 2.0.0 + nullable: 6.0.0 + numberfield: 0.1.0 + numbers: 9.0.1 + oak: 3.1.1 + oak-debug: 1.2.2 + object-maps: 0.3.0 + ocarina: 1.5.4 + open-folds: 6.3.0 + open-memoize: 6.1.0 + open-pairing: 6.1.0 + options: 7.0.0 + optparse: 5.0.1 + ordered-collections: 3.1.1 + ordered-set: 0.4.0 + orders: 6.0.0 + owoify: 1.2.0 + pairs: 9.0.1 + parallel: 7.0.0 + parsing: 10.2.0 + parsing-dataview: 3.2.4 + partial: 4.0.0 + pathy: 9.0.0 + pha: 0.13.0 + phaser: 0.7.0 + phylio: 1.1.2 + pipes: 8.0.0 + pirates-charm: 0.0.1 + pmock: 0.9.0 + point-free: 1.0.0 + pointed-list: 0.5.1 + polymorphic-vectors: 4.0.0 + posix-types: 6.0.0 + precise: 6.0.0 + precise-datetime: 7.0.0 + prelude: 6.0.1 + prettier-printer: 3.0.0 + profunctor: 6.0.0 + profunctor-lenses: 8.0.0 + protobuf: 4.3.0 + psa-utils: 8.0.0 + psci-support: 6.0.0 + punycode: 1.0.0 + qualified-do: 2.2.0 + quantities: 12.2.0 + quickcheck: 8.0.1 + quickcheck-combinators: 0.1.3 + quickcheck-laws: 7.0.0 + quickcheck-utf8: 0.0.0 + random: 6.0.0 + rationals: 6.0.0 + rdf: 0.1.0 + react: 11.0.0 + react-aria: 0.2.0 + react-basic: 17.0.0 + react-basic-classic: 3.0.0 + react-basic-dnd: 10.1.0 + react-basic-dom: 6.1.0 + react-basic-emotion: 7.1.0 + react-basic-hooks: 8.2.0 + react-basic-storybook: 2.0.0 + react-dom: 8.0.0 + react-halo: 3.0.0 + react-icons: 1.1.4 + react-markdown: 0.1.0 + react-testing-library: 4.0.1 + react-virtuoso: 1.0.0 + read: 1.0.1 + recharts: 1.1.0 + record: 4.0.0 + record-extra: 5.0.1 + record-ptional-fields: 0.1.2 + record-studio: 1.0.4 + refs: 6.0.0 + remotedata: 5.0.0 + resize-observer: 1.0.0 + resource: 2.0.1 + resourcet: 1.0.0 + result: 1.0.3 + return: 0.2.0 + ring-modules: 5.0.1 + rito: 0.3.4 + rough-notation: 1.0.0 + routing: 11.0.0 + routing-duplex: 0.7.0 + run: 5.0.0 + safe-coerce: 2.0.0 + safely: 4.0.1 + school-of-music: 1.3.0 + selection-foldable: 0.2.0 + selective-functors: 1.0.1 + semirings: 7.0.0 + signal: 13.0.0 + simple-emitter: 3.0.1 + simple-i18n: 2.0.1 + simple-json: 9.0.0 + simple-ulid: 3.0.0 + sized-matrices: 1.0.0 + sized-vectors: 5.0.2 + slug: 3.0.8 + small-ffi: 4.0.1 + soundfonts: 4.1.0 + sparse-matrices: 1.3.0 + sparse-polynomials: 2.0.5 + spec: 7.6.0 + spec-mocha: 5.1.0 + spec-quickcheck: 5.0.0 + splitmix: 2.1.0 + ssrs: 1.0.0 + st: 6.2.0 + statistics: 0.3.2 + strictlypositiveint: 1.0.1 + string-parsers: 8.0.0 + strings: 6.0.1 + strings-extra: 4.0.0 + stringutils: 0.0.12 + substitute: 0.2.3 + supply: 0.2.0 + svg-parser: 3.0.0 + systemd-journald: 0.3.0 + tagged: 4.0.2 + tailrec: 6.1.0 + tecton: 0.2.1 + tecton-halogen: 0.2.0 + test-unit: 17.0.0 + thermite: 6.3.1 + thermite-dom: 0.3.1 + these: 6.0.0 + transformation-matrix: 1.0.1 + transformers: 6.0.0 + tree-rose: 4.0.2 + ts-bridge: 4.0.0 + tuples: 7.0.0 + two-or-more: 1.0.0 + type-equality: 4.0.1 + typedenv: 2.0.1 + typelevel: 6.0.0 + typelevel-lists: 2.1.0 + typelevel-peano: 1.0.1 + typelevel-prelude: 7.0.0 + typelevel-regex: 0.0.3 + typelevel-rows: 0.1.0 + uint: 7.0.0 + ulid: 3.0.1 + uncurried-transformers: 1.1.0 + undefined: 2.0.0 + undefined-is-not-a-problem: 1.1.0 + unfoldable: 6.0.0 + unicode: 6.0.0 + unique: 0.6.1 + unlift: 1.0.1 + unordered-collections: 3.0.1 + unsafe-coerce: 6.0.0 + unsafe-reference: 5.0.0 + untagged-to-tagged: 0.1.4 + untagged-union: 1.0.0 + uri: 9.0.0 + uuid: 9.0.0 + uuidv4: 1.0.0 + validation: 6.0.0 + variant: 8.0.0 + variant-encodings: 2.0.0 + vectorfield: 1.0.1 + vectors: 2.1.0 + versions: 7.0.0 + visx: 0.0.2 + web-clipboard: 5.0.0 + web-cssom: 2.0.0 + web-cssom-view: 0.1.0 + web-dom: 6.0.0 + web-dom-parser: 8.0.0 + web-dom-xpath: 3.0.0 + web-encoding: 3.0.0 + web-events: 4.0.0 + web-fetch: 4.0.1 + web-file: 4.0.0 + web-geometry: 0.1.0 + web-html: 4.1.0 + web-pointerevents: 2.0.0 + web-proletarian: 1.0.0 + web-promise: 3.2.0 + web-resize-observer: 2.1.0 + web-router: 1.0.0 + web-socket: 4.0.0 + web-storage: 5.0.0 + web-streams: 4.0.0 + web-touchevents: 4.0.0 + web-uievents: 5.0.0 + web-url: 2.0.0 + web-workers: 1.1.0 + web-xhr: 5.0.1 + webextension-polyfill: 0.1.0 + webgpu: 0.0.1 + which: 2.0.0 + xterm: 1.0.0 + yoga-fetch: 1.0.1 + yoga-json: 5.1.0 + yoga-om: 0.1.0 + yoga-postgres: 6.0.0 + yoga-tree: 1.0.0 + z3: 0.0.2 + zipperarray: 2.0.0 + extra_packages: + argonaut-aeson-generic: + git: https://github.com/coot/purescript-argonaut-aeson-generic.git + ref: v0.4.1 + dependencies: + - argonaut + - argonaut-codecs + - argonaut-generic + - console + - effect + - foreign-object + - test-unit + argonaut-codecs: + git: https://github.com/peterbecich/purescript-argonaut-codecs.git + ref: 04abb3eb24a4deafe125be0eb23e2786c642e66b + dependencies: + - console + foreign-generic: + git: https://github.com/jsparkes/purescript-foreign-generic.git + ref: 844f2ababa2c7a0482bf871e1e6bf970b7e51313 + dependencies: + - effect + - exceptions + - foreign + - foreign-object + - identity + - ordered-collections + - record + json-helpers: + git: https://github.com/input-output-hk/purescript-bridge-json-helpers.git + ref: 486db9ee62882baa42cca24f556848c5f6bec565 + dependencies: + - aff + - argonaut-codecs + - argonaut-core + - arrays + - bifunctors + - contravariant + - control + - effect + - either + - enums + - foldable-traversable + - foreign-object + - maybe + - newtype + - ordered-collections + - prelude + - profunctor + - psci-support + - quickcheck + - record + - spec + - spec-quickcheck + - transformers + - tuples + - typelevel-prelude +packages: + aff: + type: registry + version: 7.1.0 + integrity: sha256-7hOC6uQO9XBAI5FD8F33ChLjFAiZVfd4BJMqlMh7TNU= + dependencies: + - arrays + - bifunctors + - control + - datetime + - effect + - either + - exceptions + - foldable-traversable + - functions + - maybe + - newtype + - parallel + - prelude + - refs + - tailrec + - transformers + - unsafe-coerce + affjax: + type: registry + version: 13.0.0 + integrity: sha256-blYfaoW4FYIrIdvmT4sB7nN7BathFaEfZuiVLPmHJOo= + dependencies: + - aff + - argonaut-core + - arraybuffer-types + - foreign + - form-urlencoded + - http-methods + - integers + - media-types + - nullable + - refs + - unsafe-coerce + - web-xhr + affjax-web: + type: registry + version: 1.0.0 + integrity: sha256-n/yJUk1wMxMN7fJ2TJ+fELgieomy29N617yOshAnrc0= + dependencies: + - aff + - affjax + - either + - maybe + - prelude + ansi: + type: registry + version: 7.0.0 + integrity: sha256-ZMB6HD+q9CXvn9fRCmJ8dvuDrOVHcjombL3oNOerVnE= + dependencies: + - foldable-traversable + - lists + - strings + argonaut: + type: registry + version: 9.0.0 + integrity: sha256-9sHzkzcFkaMUa9+3FjIybJDYnHtY4Jp4zHOJ84qPTXo= + dependencies: + - argonaut-codecs + - argonaut-core + - argonaut-traversals + argonaut-aeson-generic: + type: git + url: https://github.com/coot/purescript-argonaut-aeson-generic.git + rev: 4cee717e3e0003b76e699550f5fc35976901078c + dependencies: + - argonaut + - argonaut-codecs + - argonaut-generic + - console + - effect + - foreign-object + - test-unit + argonaut-codecs: + type: git + url: https://github.com/peterbecich/purescript-argonaut-codecs.git + rev: 04abb3eb24a4deafe125be0eb23e2786c642e66b + dependencies: + - console + argonaut-core: + type: registry + version: 7.0.0 + integrity: sha256-RC82GfAjItydxrO24cdX373KHVZiLqybu19b5X8u7B4= + dependencies: + - arrays + - control + - either + - foreign-object + - functions + - gen + - maybe + - nonempty + - prelude + - strings + - tailrec + argonaut-generic: + type: registry + version: 8.0.0 + integrity: sha256-WCqRWoomRKg5BFZnGBS4k4SqBX84fy/X1aJzMyaIeP0= + dependencies: + - argonaut-codecs + - argonaut-core + - prelude + - record + argonaut-traversals: + type: registry + version: 10.0.0 + integrity: sha256-9nSfqR70rjiNWVVsCoK+jrm9dmyZTx89IKNYO6uNUIk= + dependencies: + - argonaut-codecs + - argonaut-core + - profunctor-lenses + arraybuffer-types: + type: registry + version: 3.0.2 + integrity: sha256-mQKokysYVkooS4uXbO+yovmV/s8b138Ws3zQvOwIHRA= + dependencies: [] + arrays: + type: registry + version: 7.3.0 + integrity: sha256-tmcklBlc/muUtUfr9RapdCPwnlQeB3aSrC4dK85gQlc= + dependencies: + - bifunctors + - control + - foldable-traversable + - functions + - maybe + - nonempty + - partial + - prelude + - safe-coerce + - st + - tailrec + - tuples + - unfoldable + - unsafe-coerce + avar: + type: registry + version: 5.0.0 + integrity: sha256-e7hf0x4hEpcygXP0LtvfvAQ49Bbj2aWtZT3gqM///0A= + dependencies: + - aff + - effect + - either + - exceptions + - functions + - maybe + bifunctors: + type: registry + version: 6.0.0 + integrity: sha256-/gZwC9YhNxZNQpnHa5BIYerCGM2jeX9ukZiEvYxm5Nw= + dependencies: + - const + - either + - newtype + - prelude + - tuples + catenable-lists: + type: registry + version: 7.0.0 + integrity: sha256-76vYENhwF4BWTBsjeLuErCH2jqVT4M3R1HX+4RwSftA= + dependencies: + - control + - foldable-traversable + - lists + - maybe + - prelude + - tuples + - unfoldable + console: + type: registry + version: 6.1.0 + integrity: sha256-CxmAzjgyuGDmt9FZW51VhV6rBPwR6o0YeKUzA9rSzcM= + dependencies: + - effect + - prelude + const: + type: registry + version: 6.0.0 + integrity: sha256-tNrxDW8D8H4jdHE2HiPzpLy08zkzJMmGHdRqt5BQuTc= + dependencies: + - invariant + - newtype + - prelude + contravariant: + type: registry + version: 6.0.0 + integrity: sha256-TP+ooAp3vvmdjfQsQJSichF5B4BPDHp3wAJoWchip6c= + dependencies: + - const + - either + - newtype + - prelude + - tuples + control: + type: registry + version: 6.0.0 + integrity: sha256-sH7Pg9E96JCPF9PIA6oQ8+BjTyO/BH1ZuE/bOcyj4Jk= + dependencies: + - newtype + - prelude + datetime: + type: registry + version: 6.1.0 + integrity: sha256-g/5X5BBegQWLpI9IWD+sY6mcaYpzzlW5lz5NBzaMtyI= + dependencies: + - bifunctors + - control + - either + - enums + - foldable-traversable + - functions + - gen + - integers + - lists + - maybe + - newtype + - numbers + - ordered-collections + - partial + - prelude + - tuples + distributive: + type: registry + version: 6.0.0 + integrity: sha256-HTDdmEnzigMl+02SJB88j+gAXDx9VKsbvR4MJGDPbOQ= + dependencies: + - identity + - newtype + - prelude + - tuples + - type-equality + effect: + type: registry + version: 4.0.0 + integrity: sha256-eBtZu+HZcMa5HilvI6kaDyVX3ji8p0W9MGKy2K4T6+M= + dependencies: + - prelude + either: + type: registry + version: 6.1.0 + integrity: sha256-6hgTPisnMWVwQivOu2PKYcH8uqjEOOqDyaDQVUchTpY= + dependencies: + - control + - invariant + - maybe + - prelude + enums: + type: registry + version: 6.0.1 + integrity: sha256-HWaD73JFLorc4A6trKIRUeDMdzE+GpkJaEOM1nTNkC8= + dependencies: + - control + - either + - gen + - maybe + - newtype + - nonempty + - partial + - prelude + - tuples + - unfoldable + exceptions: + type: registry + version: 6.0.0 + integrity: sha256-y/xTAEIZIARCE+50/u1di0ncebJ+CIwNOLswyOWzMTw= + dependencies: + - effect + - either + - maybe + - prelude + exists: + type: registry + version: 6.0.0 + integrity: sha256-A0JQHpTfo1dNOj9U5/Fd3xndlRSE0g2IQWOGor2yXn8= + dependencies: + - unsafe-coerce + foldable-traversable: + type: registry + version: 6.0.0 + integrity: sha256-fLeqRYM4jUrZD5H4WqcwUgzU7XfYkzO4zhgtNc3jcWM= + dependencies: + - bifunctors + - const + - control + - either + - functors + - identity + - maybe + - newtype + - orders + - prelude + - tuples + foreign: + type: registry + version: 7.0.0 + integrity: sha256-1ORiqoS3HW+qfwSZAppHPWy4/6AQysxZ2t29jcdUMNA= + dependencies: + - either + - functions + - identity + - integers + - lists + - maybe + - prelude + - strings + - transformers + foreign-generic: + type: git + url: https://github.com/jsparkes/purescript-foreign-generic.git + rev: 844f2ababa2c7a0482bf871e1e6bf970b7e51313 + dependencies: + - effect + - exceptions + - foreign + - foreign-object + - identity + - ordered-collections + - record + foreign-object: + type: registry + version: 4.1.0 + integrity: sha256-q24okj6mT+yGHYQ+ei/pYPj5ih6sTbu7eDv/WU56JVo= + dependencies: + - arrays + - foldable-traversable + - functions + - gen + - lists + - maybe + - prelude + - st + - tailrec + - tuples + - typelevel-prelude + - unfoldable + fork: + type: registry + version: 6.0.0 + integrity: sha256-X7u0SuCvFbLbzuNEKLBNuWjmcroqMqit4xEzpQwAP7E= + dependencies: + - aff + form-urlencoded: + type: registry + version: 7.0.0 + integrity: sha256-WUzk8DTjrbPVHKZ5w7XpPBO6ci6xFhvYguHp6RvX+18= + dependencies: + - foldable-traversable + - js-uri + - maybe + - newtype + - prelude + - strings + - tuples + free: + type: registry + version: 7.1.0 + integrity: sha256-JAumgEsGSzJCNLD8AaFvuX7CpqS5yruCngi6yI7+V5k= + dependencies: + - catenable-lists + - control + - distributive + - either + - exists + - foldable-traversable + - invariant + - lazy + - maybe + - prelude + - tailrec + - transformers + - tuples + - unsafe-coerce + functions: + type: registry + version: 6.0.0 + integrity: sha256-adMyJNEnhGde2unHHAP79gPtlNjNqzgLB8arEOn9hLI= + dependencies: + - prelude + functors: + type: registry + version: 5.0.0 + integrity: sha256-zfPWWYisbD84MqwpJSZFlvM6v86McM68ob8p9s27ywU= + dependencies: + - bifunctors + - const + - contravariant + - control + - distributive + - either + - invariant + - maybe + - newtype + - prelude + - profunctor + - tuples + - unsafe-coerce + gen: + type: registry + version: 4.0.0 + integrity: sha256-f7yzAXWwr+xnaqEOcvyO3ezKdoes8+WXWdXIHDBCAPI= + dependencies: + - either + - foldable-traversable + - identity + - maybe + - newtype + - nonempty + - prelude + - tailrec + - tuples + - unfoldable + http-methods: + type: registry + version: 6.0.0 + integrity: sha256-Orr7rbDGcp7qoqmUMXPRMjBx+C4jqOQcFe9+gE3nMgU= + dependencies: + - either + - prelude + - strings + identity: + type: registry + version: 6.0.0 + integrity: sha256-4wY0XZbAksjY6UAg99WkuKyJlQlWAfTi2ssadH0wVMY= + dependencies: + - control + - invariant + - newtype + - prelude + integers: + type: registry + version: 6.0.0 + integrity: sha256-sf+sK26R1hzwl3NhXR7WAu9zCDjQnfoXwcyGoseX158= + dependencies: + - maybe + - numbers + - prelude + invariant: + type: registry + version: 6.0.0 + integrity: sha256-RGWWyYrz0Hs1KjPDA+87Kia67ZFBhfJ5lMGOMCEFoLo= + dependencies: + - control + - prelude + js-date: + type: registry + version: 8.0.0 + integrity: sha256-6TVF4DWg5JL+jRAsoMssYw8rgOVALMUHT1CuNZt8NRo= + dependencies: + - datetime + - effect + - exceptions + - foreign + - integers + - now + js-timers: + type: registry + version: 6.1.0 + integrity: sha256-znHWLSSOYw15P5DTcsAdal2lf7nGA2yayLdOZ2t5r7o= + dependencies: + - effect + js-uri: + type: registry + version: 3.1.0 + integrity: sha256-3p0ynHveCJmC2CXze+eMBdW/2l5e953Q8XMAKz+jxUo= + dependencies: + - functions + - maybe + json-helpers: + type: git + url: https://github.com/input-output-hk/purescript-bridge-json-helpers.git + rev: 486db9ee62882baa42cca24f556848c5f6bec565 + dependencies: + - aff + - argonaut-codecs + - argonaut-core + - arrays + - bifunctors + - contravariant + - control + - effect + - either + - enums + - foldable-traversable + - foreign-object + - maybe + - newtype + - ordered-collections + - prelude + - profunctor + - psci-support + - quickcheck + - record + - spec + - spec-quickcheck + - transformers + - tuples + - typelevel-prelude + lazy: + type: registry + version: 6.0.0 + integrity: sha256-lMsfFOnlqfe4KzRRiW8ot5ge6HtcU3Eyh2XkXcP5IgU= + dependencies: + - control + - foldable-traversable + - invariant + - prelude + lcg: + type: registry + version: 4.0.0 + integrity: sha256-h7ME5cthLfbgJOJdsZcSfFpwXsx4rf8YmhebU+3iSYg= + dependencies: + - effect + - integers + - maybe + - partial + - prelude + - random + lists: + type: registry + version: 7.0.0 + integrity: sha256-EKF15qYqucuXP2lT/xPxhqy58f0FFT6KHdIB/yBOayI= + dependencies: + - bifunctors + - control + - foldable-traversable + - lazy + - maybe + - newtype + - nonempty + - partial + - prelude + - tailrec + - tuples + - unfoldable + maybe: + type: registry + version: 6.0.0 + integrity: sha256-5cCIb0wPwbat2PRkQhUeZO0jcAmf8jCt2qE0wbC3v2Q= + dependencies: + - control + - invariant + - newtype + - prelude + media-types: + type: registry + version: 6.0.0 + integrity: sha256-n/4FoGBasbVSYscGVRSyBunQ6CZbL3jsYL+Lp01mc9k= + dependencies: + - newtype + - prelude + mmorph: + type: registry + version: 7.0.0 + integrity: sha256-urZlZNNqGeQFe5D/ClHlR8QgGBNHTMFPtJ5S5IpflTQ= + dependencies: + - free + - functors + - transformers + newtype: + type: registry + version: 5.0.0 + integrity: sha256-gdrQu8oGe9eZE6L3wOI8ql/igOg+zEGB5ITh2g+uttw= + dependencies: + - prelude + - safe-coerce + nonempty: + type: registry + version: 7.0.0 + integrity: sha256-54ablJZUHGvvlTJzi3oXyPCuvY6zsrWJuH/dMJ/MFLs= + dependencies: + - control + - foldable-traversable + - maybe + - prelude + - tuples + - unfoldable + now: + type: registry + version: 6.0.0 + integrity: sha256-xZ7x37ZMREfs6GCDw/h+FaKHV/3sPWmtqBZRGTxybQY= + dependencies: + - datetime + - effect + nullable: + type: registry + version: 6.0.0 + integrity: sha256-yiGBVl3AD+Guy4kNWWeN+zl1gCiJK+oeIFtZtPCw4+o= + dependencies: + - effect + - functions + - maybe + numbers: + type: registry + version: 9.0.1 + integrity: sha256-/9M6aeMDBdB4cwYDeJvLFprAHZ49EbtKQLIJsneXLIk= + dependencies: + - functions + - maybe + ordered-collections: + type: registry + version: 3.1.1 + integrity: sha256-boSYHmlz4aSbwsNN4VxiwCStc0t+y1F7BXmBS+1JNtI= + dependencies: + - arrays + - foldable-traversable + - gen + - lists + - maybe + - partial + - prelude + - st + - tailrec + - tuples + - unfoldable + orders: + type: registry + version: 6.0.0 + integrity: sha256-nBA0g3/ai0euH8q9pSbGqk53W2q6agm/dECZTHcoink= + dependencies: + - newtype + - prelude + parallel: + type: registry + version: 7.0.0 + integrity: sha256-gUC9i4Txnx9K9RcMLsjujbwZz6BB1bnE2MLvw4GIw5o= + dependencies: + - control + - effect + - either + - foldable-traversable + - functors + - maybe + - newtype + - prelude + - profunctor + - refs + - transformers + partial: + type: registry + version: 4.0.0 + integrity: sha256-fwXerld6Xw1VkReh8yeQsdtLVrjfGiVuC5bA1Wyo/J4= + dependencies: [] + pipes: + type: registry + version: 8.0.0 + integrity: sha256-kvfqGM4cPA/wCcBHbp5psouFw5dZGvku2462x7ZBwSY= + dependencies: + - aff + - lists + - mmorph + - prelude + - tailrec + - transformers + - tuples + prelude: + type: registry + version: 6.0.1 + integrity: sha256-o8p6SLYmVPqzXZhQFd2hGAWEwBoXl1swxLG/scpJ0V0= + dependencies: [] + profunctor: + type: registry + version: 6.0.0 + integrity: sha256-99NzxFgTr4CGlCSRYG1kShL+JhYbihhHtbOk1/0R5zI= + dependencies: + - control + - distributive + - either + - exists + - invariant + - newtype + - prelude + - tuples + profunctor-lenses: + type: registry + version: 8.0.0 + integrity: sha256-K7f29rHRHgVSb2Y/PaSKtfYPriP6n87BJNO7EhsZHas= + dependencies: + - arrays + - bifunctors + - const + - control + - distributive + - either + - foldable-traversable + - foreign-object + - functors + - identity + - lists + - maybe + - newtype + - ordered-collections + - partial + - prelude + - profunctor + - record + - transformers + - tuples + psci-support: + type: registry + version: 6.0.0 + integrity: sha256-C6ql4P9TEP06hft/1Z5QumPA4yARR4VIxDdhmL1EO+Y= + dependencies: + - console + - effect + - prelude + quickcheck: + type: registry + version: 8.0.1 + integrity: sha256-ZvpccKQCvgslTXZCNmpYW4bUsFzhZd/kQUr2WmxFTGY= + dependencies: + - arrays + - console + - control + - effect + - either + - enums + - exceptions + - foldable-traversable + - gen + - identity + - integers + - lazy + - lcg + - lists + - maybe + - newtype + - nonempty + - numbers + - partial + - prelude + - record + - st + - strings + - tailrec + - transformers + - tuples + - unfoldable + random: + type: registry + version: 6.0.0 + integrity: sha256-CJ611a35MPCE7XQMp0rdC6MCn76znlhisiCRgboAG+Q= + dependencies: + - effect + - integers + record: + type: registry + version: 4.0.0 + integrity: sha256-Za5U85bTRJEfGK5Sk4hM41oXy84YQI0I8TL3WUn1Qzg= + dependencies: + - functions + - prelude + - unsafe-coerce + refs: + type: registry + version: 6.0.0 + integrity: sha256-Vgwne7jIbD3ZMoLNNETLT8Litw6lIYo3MfYNdtYWj9s= + dependencies: + - effect + - prelude + safe-coerce: + type: registry + version: 2.0.0 + integrity: sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU= + dependencies: + - unsafe-coerce + spec: + type: registry + version: 7.6.0 + integrity: sha256-+merGdQbL9zWONbnt8S8J9afGJ59MQqGtS0qSd3yu4I= + dependencies: + - aff + - ansi + - arrays + - avar + - bifunctors + - control + - datetime + - effect + - either + - exceptions + - foldable-traversable + - fork + - identity + - integers + - lists + - maybe + - newtype + - now + - ordered-collections + - parallel + - pipes + - prelude + - refs + - strings + - tailrec + - transformers + - tuples + spec-quickcheck: + type: registry + version: 5.0.0 + integrity: sha256-iE0iThqZCuDGe3pwg5RvqcL8E5cRQ4txDuloCclOsCs= + dependencies: + - aff + - prelude + - quickcheck + - random + - spec + st: + type: registry + version: 6.2.0 + integrity: sha256-z9X0WsOUlPwNx9GlCC+YccCyz8MejC8Wb0C4+9fiBRY= + dependencies: + - partial + - prelude + - tailrec + - unsafe-coerce + strings: + type: registry + version: 6.0.1 + integrity: sha256-WssD3DbX4OPzxSdjvRMX0yvc9+pS7n5gyPv5I2Trb7k= + dependencies: + - arrays + - control + - either + - enums + - foldable-traversable + - gen + - integers + - maybe + - newtype + - nonempty + - partial + - prelude + - tailrec + - tuples + - unfoldable + - unsafe-coerce + tailrec: + type: registry + version: 6.1.0 + integrity: sha256-Xx19ECVDRrDWpz9D2GxQHHV89vd61dnXxQm0IcYQHGk= + dependencies: + - bifunctors + - effect + - either + - identity + - maybe + - partial + - prelude + - refs + test-unit: + type: registry + version: 17.0.0 + integrity: sha256-aITJ2KngFFjASmG0JjnjybaKWl9dn7Hf2B3Wk4engNs= + dependencies: + - aff + - avar + - effect + - either + - free + - js-timers + - lists + - prelude + - quickcheck + - strings + transformers: + type: registry + version: 6.0.0 + integrity: sha256-Pzw40HjthX77tdPAYzjx43LK3X5Bb7ZspYAp27wksFA= + dependencies: + - control + - distributive + - effect + - either + - exceptions + - foldable-traversable + - identity + - lazy + - maybe + - newtype + - prelude + - tailrec + - tuples + - unfoldable + tuples: + type: registry + version: 7.0.0 + integrity: sha256-1rXgTomes9105BjgXqIw0FL6Fz1lqqUTLWOumhWec1M= + dependencies: + - control + - invariant + - prelude + type-equality: + type: registry + version: 4.0.1 + integrity: sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw= + dependencies: [] + typelevel-prelude: + type: registry + version: 7.0.0 + integrity: sha256-uFF2ph+vHcQpfPuPf2a3ukJDFmLhApmkpTMviHIWgJM= + dependencies: + - prelude + - type-equality + unfoldable: + type: registry + version: 6.0.0 + integrity: sha256-JtikvJdktRap7vr/K4ITlxUX1QexpnqBq0G/InLr6eg= + dependencies: + - foldable-traversable + - maybe + - partial + - prelude + - tuples + unsafe-coerce: + type: registry + version: 6.0.0 + integrity: sha256-IqIYW4Vkevn8sI+6aUwRGvd87tVL36BBeOr0cGAE7t0= + dependencies: [] + web-dom: + type: registry + version: 6.0.0 + integrity: sha256-1kSKWFDI4LupdmpjK01b1MMxDFW7jvatEgPgVmCmSBQ= + dependencies: + - web-events + web-events: + type: registry + version: 4.0.0 + integrity: sha256-YDt8b6u1tzGtnWyNRodne57iO8FNSGPaTCVzBUyUn4k= + dependencies: + - datetime + - enums + - foreign + - nullable + web-file: + type: registry + version: 4.0.0 + integrity: sha256-1h5jPBkvjY71jLEdwVadXCx86/2inNoMBO//Rd3eCSU= + dependencies: + - foreign + - media-types + - web-dom + web-html: + type: registry + version: 4.1.0 + integrity: sha256-ByqS/h1/yG+hjCOnOQp7L1QpIWzQENNKB1kaHtpEhlE= + dependencies: + - js-date + - web-dom + - web-file + - web-storage + web-storage: + type: registry + version: 5.0.0 + integrity: sha256-q+6lxcnfWxus0/nDeFVtF1V+tLehZvvXQ0cduYPLksY= + dependencies: + - nullable + - web-events + web-xhr: + type: registry + version: 5.0.1 + integrity: sha256-3dbIPVG66S+hPrgEVnpD78hrGjE7qlBbsReWOz89Ios= + dependencies: + - arraybuffer-types + - datetime + - http-methods + - web-dom + - web-file + - web-html diff --git a/example/spago.yaml b/example/spago.yaml new file mode 100644 index 00000000..80e706e9 --- /dev/null +++ b/example/spago.yaml @@ -0,0 +1,24 @@ +package: + name: example + dependencies: + - aff + - affjax + - affjax-web + - argonaut + - argonaut-aeson-generic + - argonaut-codecs + - argonaut-generic + - console + - control + - effect + - either + - foldable-traversable + - foreign-generic + - foreign-object + - json-helpers + - maybe + - newtype + - ordered-collections + - prelude + - profunctor-lenses + - tuples diff --git a/example/src/Argonaut/Types.purs b/example/src/Argonaut/Types.purs new file mode 100644 index 00000000..54a7ba9f --- /dev/null +++ b/example/src/Argonaut/Types.purs @@ -0,0 +1,262 @@ +-- File auto generated by purescript-bridge! -- +module Argonaut.Types where + +import Prelude + +import Control.Lazy (defer) +import Data.Argonaut.Aeson.Decode.Generic (genericDecodeAeson) +import Data.Argonaut.Aeson.Encode.Generic (genericEncodeAeson) +import Data.Argonaut.Aeson.Options (defaultOptions) as Argonaut +import Data.Argonaut.Decode (class DecodeJson) +import Data.Argonaut.Decode.Class (class DecodeJson, class DecodeJsonField, decodeJson) +import Data.Argonaut.Decode.Class as Argonaut +import Data.Argonaut.Encode (class EncodeJson) +import Data.Argonaut.Encode.Class (class EncodeJson, encodeJson) +import Data.Argonaut.Encode.Class as Argonaut +import Data.Bounded.Generic (genericBottom, genericTop) +import Data.Either (Either) +import Data.Enum (class Enum) +import Data.Enum.Generic (genericPred, genericSucc) +import Data.Generic.Rep (class Generic) +import Data.Lens (Iso', Lens', Prism', iso, lens, prism') +import Data.Lens.Iso.Newtype (_Newtype) +import Data.Lens.Record (prop) +import Data.Maybe (Maybe(..)) +import Data.Newtype (class Newtype) +import Data.Show.Generic (genericShow) +import Foreign.Object (Object) +import Type.Proxy (Proxy(Proxy)) + +newtype Baz = Baz { _bazMessage :: String } + +instance EncodeJson Baz where + encodeJson = defer \_ -> genericEncodeAeson Argonaut.defaultOptions + +instance DecodeJson Baz where + decodeJson = defer \_ -> genericDecodeAeson Argonaut.defaultOptions + + + +instance Show Baz where + show a = genericShow a + +derive instance Generic Baz _ + +derive instance Newtype Baz _ + +-------------------------------------------------------------------------------- + +_Baz :: Iso' Baz {_bazMessage :: String} +_Baz = _Newtype + +bazMessage :: Lens' Baz String +bazMessage = _Newtype <<< prop (Proxy :: _"_bazMessage") + +-------------------------------------------------------------------------------- + +data ID a = ID + +instance (EncodeJson a) => EncodeJson (ID a) where + encodeJson = defer \_ -> genericEncodeAeson Argonaut.defaultOptions + +instance (DecodeJson a, DecodeJsonField a) => DecodeJson (ID a) where + decodeJson = defer \_ -> genericDecodeAeson Argonaut.defaultOptions + + + +instance Show (ID a) where + show a = genericShow a + +derive instance Generic (ID a) _ + +-- instance Enum (ID a) where +-- succ = genericSucc +-- pred = genericPred + +-- instance Bounded (ID a) where +-- bottom = genericBottom +-- top = genericTop + +-------------------------------------------------------------------------------- + +_ID :: forall a. Iso' (ID a) Unit +_ID = iso (const unit) (const ID) + +-------------------------------------------------------------------------------- + +newtype ID2 a = ID2 { getID :: Int } + +instance (EncodeJson a) => EncodeJson (ID2 a) where + encodeJson = defer \_ -> genericEncodeAeson Argonaut.defaultOptions + +instance (DecodeJson a, DecodeJsonField a) => DecodeJson (ID2 a) where + decodeJson = defer \_ -> genericDecodeAeson Argonaut.defaultOptions + + + +instance Show (ID2 a) where + show a = genericShow a + +derive instance Generic (ID2 a) _ + +derive instance Newtype (ID2 a) _ + +-------------------------------------------------------------------------------- + +_ID2 :: forall a. Iso' (ID2 a) {getID :: Int} +_ID2 = _Newtype + +-------------------------------------------------------------------------------- + +newtype Foo = Foo + { _fooMessage :: String + , _fooE :: Either String Int + , _fooNumber :: Int + , _fooList :: Array Int + , _fooMap :: Object Int + , _fooBaz :: Baz + , _fooTestSum :: TestSum + , _fooTestData :: TestData + } + +instance EncodeJson Foo where + encodeJson = defer \_ -> genericEncodeAeson Argonaut.defaultOptions + +instance DecodeJson Foo where + decodeJson = defer \_ -> genericDecodeAeson Argonaut.defaultOptions + + + +instance Show Foo where + show a = genericShow a + +derive instance Generic Foo _ + +derive instance Newtype Foo _ + +-------------------------------------------------------------------------------- + +_Foo :: Iso' Foo {_fooMessage :: String, _fooE :: Either String Int, _fooNumber :: Int, _fooList :: Array Int, _fooMap :: Object Int, _fooBaz :: Baz, _fooTestSum :: TestSum, _fooTestData :: TestData} +_Foo = _Newtype + +fooMessage :: Lens' Foo String +fooMessage = _Newtype <<< prop (Proxy :: _"_fooMessage") + +fooE :: Lens' Foo (Either String Int) +fooE = _Newtype <<< prop (Proxy :: _"_fooE") + +fooNumber :: Lens' Foo Int +fooNumber = _Newtype <<< prop (Proxy :: _"_fooNumber") + +fooList :: Lens' Foo (Array Int) +fooList = _Newtype <<< prop (Proxy :: _"_fooList") + +fooMap :: Lens' Foo (Object Int) +fooMap = _Newtype <<< prop (Proxy :: _"_fooMap") + +fooBaz :: Lens' Foo Baz +fooBaz = _Newtype <<< prop (Proxy :: _"_fooBaz") + +fooTestSum :: Lens' Foo TestSum +fooTestSum = _Newtype <<< prop (Proxy :: _"_fooTestSum") + +fooTestData :: Lens' Foo TestData +fooTestData = _Newtype <<< prop (Proxy :: _"_fooTestData") + +-------------------------------------------------------------------------------- + +newtype Bar a = Bar a + +instance (EncodeJson a) => EncodeJson (Bar a) where + encodeJson = defer \_ -> genericEncodeAeson Argonaut.defaultOptions + +instance (DecodeJson a, DecodeJsonField a) => DecodeJson (Bar a) where + decodeJson = defer \_ -> genericDecodeAeson Argonaut.defaultOptions + + + +instance (Show a) => Show (Bar a) where + show a = genericShow a + +derive instance Generic (Bar a) _ + +derive instance Newtype (Bar a) _ + +-------------------------------------------------------------------------------- + +_Bar :: forall a. Iso' (Bar a) a +_Bar = _Newtype + +-------------------------------------------------------------------------------- + +data TestSum + = Nullary + | Bool Boolean + | Int Int + | Number Number + +instance EncodeJson TestSum where + encodeJson = defer \_ -> genericEncodeAeson Argonaut.defaultOptions + +instance DecodeJson TestSum where + decodeJson = defer \_ -> genericDecodeAeson Argonaut.defaultOptions + + + +instance Show TestSum where + show a = genericShow a + +derive instance Generic TestSum _ + +-------------------------------------------------------------------------------- + +_Nullary :: Prism' TestSum Unit +_Nullary = prism' (const Nullary) case _ of + Nullary -> Just unit + _ -> Nothing + +_Bool :: Prism' TestSum Boolean +_Bool = prism' Bool case _ of + (Bool a) -> Just a + _ -> Nothing + +_Int :: Prism' TestSum Int +_Int = prism' Int case _ of + (Int a) -> Just a + _ -> Nothing + +_Number :: Prism' TestSum Number +_Number = prism' Number case _ of + (Number a) -> Just a + _ -> Nothing + +-------------------------------------------------------------------------------- + +data TestData + = TMaybe (Maybe TestSum) + | TEither String + +instance EncodeJson TestData where + encodeJson = defer \_ -> genericEncodeAeson Argonaut.defaultOptions + +instance DecodeJson TestData where + decodeJson = defer \_ -> genericDecodeAeson Argonaut.defaultOptions + + + +instance Show TestData where + show a = genericShow a + +derive instance Generic TestData _ + +-------------------------------------------------------------------------------- + +_TMaybe :: Prism' TestData (Maybe TestSum) +_TMaybe = prism' TMaybe case _ of + (TMaybe a) -> Just a + _ -> Nothing + +_TEither :: Prism' TestData String +_TEither = prism' TEither case _ of + (TEither a) -> Just a + _ -> Nothing diff --git a/example/src/ArgonautTypes.hs b/example/src/ArgonautTypes.hs new file mode 100644 index 00000000..1a72ed58 --- /dev/null +++ b/example/src/ArgonautTypes.hs @@ -0,0 +1,23 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE TypeApplications #-} + +module ArgonautTypes where + +import Language.PureScript.Bridge (Language (Haskell), + argonautAesonGeneric, mkSumType) +import Language.PureScript.Bridge.SumType (SumType) +import Language.PureScript.Bridge.TypeParameters (A) +import Types + +myArgonautTypes :: [SumType 'Haskell] +myArgonautTypes = + [ argonautAesonGeneric . additionalInstances $ mkSumType @Baz + , argonautAesonGeneric . additionalInstances $ mkSumType @(ID A) + , argonautAesonGeneric . additionalInstances $ mkSumType @(ID2 A) + , argonautAesonGeneric . additionalInstances $ mkSumType @Foo + , argonautAesonGeneric . additionalInstances $ mkSumType @(Bar A) + , argonautAesonGeneric . additionalInstances $ mkSumType @TestSum + , argonautAesonGeneric . additionalInstances $ mkSumType @TestData + ] diff --git a/example/src/JsonHelpers/Types.purs b/example/src/JsonHelpers/Types.purs new file mode 100644 index 00000000..e9eed87d --- /dev/null +++ b/example/src/JsonHelpers/Types.purs @@ -0,0 +1,304 @@ +-- File auto generated by purescript-bridge! -- +module JsonHelpers.Types where + +import Prelude + +import Control.Lazy (defer) +import Data.Argonaut (encodeJson, jsonNull) +import Data.Argonaut.Aeson.Decode.Generic (genericDecodeAeson) +import Data.Argonaut.Aeson.Encode.Generic (genericEncodeAeson) +import Data.Argonaut.Aeson.Options (defaultOptions) as Argonaut +import Data.Argonaut.Decode.Aeson (($\>), (*\>), (\>)) +import Data.Argonaut.Decode.Aeson as D +import Data.Argonaut.Decode.Class (class DecodeJson, class DecodeJsonField, decodeJson) +import Data.Argonaut.Decode.Class as Argonaut +import Data.Argonaut.Encode.Aeson ((>$<), (>/\<)) +import Data.Argonaut.Encode.Aeson as E +import Data.Argonaut.Encode.Class (class EncodeJson, encodeJson) +import Data.Argonaut.Encode.Class as Argonaut +import Data.Bounded.Generic (genericBottom, genericTop) +import Data.Either (Either) +import Data.Enum (class Enum) +import Data.Enum.Generic (genericPred, genericSucc) +import Data.Generic.Rep (class Generic) +import Data.Lens (Iso', Lens', Prism', iso, lens, prism') +import Data.Lens.Iso.Newtype (_Newtype) +import Data.Lens.Record (prop) +import Data.Map +import Data.Map as Map +import Data.Maybe (Maybe(..)) +import Data.Newtype (class Newtype, unwrap) +import Data.Show.Generic (genericShow) +import Data.Tuple.Nested ((/\)) +import Foreign.Object (Object) +import Type.Proxy (Proxy(Proxy)) + +newtype Baz = Baz { _bazMessage :: String } + +instance EncodeJson Baz where + encodeJson = defer \_ -> E.encode $ unwrap >$< (E.record + { _bazMessage: E.value :: _ String }) + +instance DecodeJson Baz where + decodeJson = defer \_ -> D.decode $ (Baz <$> D.record "Baz" { _bazMessage: D.value :: _ String }) + + + +instance Show Baz where + show a = genericShow a + +derive instance Generic Baz _ + +derive instance Newtype Baz _ + +-------------------------------------------------------------------------------- + +_Baz :: Iso' Baz {_bazMessage :: String} +_Baz = _Newtype + +bazMessage :: Lens' Baz String +bazMessage = _Newtype <<< prop (Proxy :: _"_bazMessage") + +-------------------------------------------------------------------------------- + +data ID a = ID + +-- instance (EncodeJson a) => EncodeJson (ID a) where +-- encodeJson = defer \_ -> E.encode E.enum + +-- instance (DecodeJson a, DecodeJsonField a) => DecodeJson (ID a) where +-- decodeJson = defer \_ -> D.decode D.enum + + + +instance Show (ID a) where + show a = genericShow a + +derive instance Generic (ID a) _ + +-- instance Enum (ID a) where +-- succ = genericSucc +-- pred = genericPred + +-- instance Bounded (ID a) where +-- bottom = genericBottom +-- top = genericTop + +-------------------------------------------------------------------------------- + +_ID :: forall a. Iso' (ID a) Unit +_ID = iso (const unit) (const ID) + +-------------------------------------------------------------------------------- + +newtype ID2 a = ID2 { getID :: Int } + +instance (EncodeJson a) => EncodeJson (ID2 a) where + encodeJson = defer \_ -> E.encode $ unwrap >$< (E.record + { getID: E.value :: _ Int }) + +instance (DecodeJson a, DecodeJsonField a) => DecodeJson (ID2 a) where + decodeJson = defer \_ -> D.decode $ (ID2 <$> D.record "ID2" { getID: D.value :: _ Int }) + + + +instance Show (ID2 a) where + show a = genericShow a + +derive instance Generic (ID2 a) _ + +derive instance Newtype (ID2 a) _ + +-------------------------------------------------------------------------------- + +_ID2 :: forall a. Iso' (ID2 a) {getID :: Int} +_ID2 = _Newtype + +-------------------------------------------------------------------------------- + +newtype Foo = Foo + { _fooMessage :: String + , _fooE :: Either String Int + , _fooNumber :: Int + , _fooList :: Array Int + , _fooMap :: Object Int + , _fooBaz :: Baz + , _fooTestSum :: TestSum + , _fooTestData :: TestData + } + +instance EncodeJson Foo where + encodeJson = defer \_ -> E.encode $ unwrap >$< (E.record + { _fooMessage: E.value :: _ String + , _fooE: (E.either E.value E.value) :: _ (Either String Int) + , _fooNumber: E.value :: _ Int + , _fooList: E.value :: _ (Array Int) + , _fooMap: E.value :: _ (Object Int) + , _fooBaz: E.value :: _ Baz + , _fooTestSum: E.value :: _ TestSum + , _fooTestData: E.value :: _ TestData + }) + +instance DecodeJson Foo where + decodeJson = defer \_ -> D.decode $ (Foo <$> D.record "Foo" + { _fooMessage: D.value :: _ String + , _fooE: (D.either D.value D.value) :: _ (Either String Int) + , _fooNumber: D.value :: _ Int + , _fooList: D.value :: _ (Array Int) + , _fooMap: D.value :: _ (Object Int) + , _fooBaz: D.value :: _ Baz + , _fooTestSum: D.value :: _ TestSum + , _fooTestData: D.value :: _ TestData + }) + + + +instance Show Foo where + show a = genericShow a + +derive instance Generic Foo _ + +derive instance Newtype Foo _ + +-------------------------------------------------------------------------------- + +_Foo :: Iso' Foo {_fooMessage :: String, _fooE :: Either String Int, _fooNumber :: Int, _fooList :: Array Int, _fooMap :: Object Int, _fooBaz :: Baz, _fooTestSum :: TestSum, _fooTestData :: TestData} +_Foo = _Newtype + +fooMessage :: Lens' Foo String +fooMessage = _Newtype <<< prop (Proxy :: _"_fooMessage") + +fooE :: Lens' Foo (Either String Int) +fooE = _Newtype <<< prop (Proxy :: _"_fooE") + +fooNumber :: Lens' Foo Int +fooNumber = _Newtype <<< prop (Proxy :: _"_fooNumber") + +fooList :: Lens' Foo (Array Int) +fooList = _Newtype <<< prop (Proxy :: _"_fooList") + +fooMap :: Lens' Foo (Object Int) +fooMap = _Newtype <<< prop (Proxy :: _"_fooMap") + +fooBaz :: Lens' Foo Baz +fooBaz = _Newtype <<< prop (Proxy :: _"_fooBaz") + +fooTestSum :: Lens' Foo TestSum +fooTestSum = _Newtype <<< prop (Proxy :: _"_fooTestSum") + +fooTestData :: Lens' Foo TestData +fooTestData = _Newtype <<< prop (Proxy :: _"_fooTestData") + +-------------------------------------------------------------------------------- + +newtype Bar a = Bar a + +instance (EncodeJson a) => EncodeJson (Bar a) where + encodeJson = defer \_ -> E.encode $ unwrap >$< E.value + +instance (DecodeJson a, DecodeJsonField a) => DecodeJson (Bar a) where + decodeJson = defer \_ -> D.decode $ (Bar <$> D.value) + + + +instance (Show a) => Show (Bar a) where + show a = genericShow a + +derive instance Generic (Bar a) _ + +derive instance Newtype (Bar a) _ + +-------------------------------------------------------------------------------- + +_Bar :: forall a. Iso' (Bar a) a +_Bar = _Newtype + +-------------------------------------------------------------------------------- + +data TestSum + = Nullary + | Bool Boolean + | Int Int + | Number Number + +instance EncodeJson TestSum where + encodeJson = defer \_ -> case _ of + Nullary -> encodeJson { tag: "Nullary", contents: jsonNull } + Bool a -> E.encodeTagged "Bool" a E.value + Int a -> E.encodeTagged "Int" a E.value + Number a -> E.encodeTagged "Number" a E.value + +instance DecodeJson TestSum where + decodeJson = defer \_ -> D.decode + $ D.sumType "TestSum" $ Map.fromFoldable + [ "Nullary" /\ pure Nullary + , "Bool" /\ D.content (Bool <$> D.value) + , "Int" /\ D.content (Int <$> D.value) + , "Number" /\ D.content (Number <$> D.value) + ] + + + +instance Show TestSum where + show a = genericShow a + +derive instance Generic TestSum _ + +-------------------------------------------------------------------------------- + +_Nullary :: Prism' TestSum Unit +_Nullary = prism' (const Nullary) case _ of + Nullary -> Just unit + _ -> Nothing + +_Bool :: Prism' TestSum Boolean +_Bool = prism' Bool case _ of + (Bool a) -> Just a + _ -> Nothing + +_Int :: Prism' TestSum Int +_Int = prism' Int case _ of + (Int a) -> Just a + _ -> Nothing + +_Number :: Prism' TestSum Number +_Number = prism' Number case _ of + (Number a) -> Just a + _ -> Nothing + +-------------------------------------------------------------------------------- + +data TestData + = TMaybe (Maybe TestSum) + | TEither String + +instance EncodeJson TestData where + encodeJson = defer \_ -> case _ of + TMaybe a -> E.encodeTagged "TMaybe" a (E.maybe E.value) + TEither a -> E.encodeTagged "TEither" a E.value + +instance DecodeJson TestData where + decodeJson = defer \_ -> D.decode + $ D.sumType "TestData" $ Map.fromFoldable + [ "TMaybe" /\ D.content (TMaybe <$> (D.maybe D.value)) + , "TEither" /\ D.content (TEither <$> D.value) + ] + + + +instance Show TestData where + show a = genericShow a + +derive instance Generic TestData _ + +-------------------------------------------------------------------------------- + +_TMaybe :: Prism' TestData (Maybe TestSum) +_TMaybe = prism' TMaybe case _ of + (TMaybe a) -> Just a + _ -> Nothing + +_TEither :: Prism' TestData String +_TEither = prism' TEither case _ of + (TEither a) -> Just a + _ -> Nothing diff --git a/example/src/JsonHelpersTypes.hs b/example/src/JsonHelpersTypes.hs new file mode 100644 index 00000000..3b440fda --- /dev/null +++ b/example/src/JsonHelpersTypes.hs @@ -0,0 +1,23 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE TypeApplications #-} + +module JsonHelpersTypes where + +import Language.PureScript.Bridge (Language (Haskell), jsonHelpers, + mkSumType) +import Language.PureScript.Bridge.SumType (SumType) +import Language.PureScript.Bridge.TypeParameters (A) +import Types + +myJsonHelpersTypes :: [SumType 'Haskell] +myJsonHelpersTypes = + [ jsonHelpers . additionalInstances $ mkSumType @Baz + , jsonHelpers . additionalInstances $ mkSumType @(ID A) + , jsonHelpers . additionalInstances $ mkSumType @(ID2 A) + , jsonHelpers . additionalInstances $ mkSumType @Foo + , jsonHelpers . additionalInstances $ mkSumType @(Bar A) + , jsonHelpers . additionalInstances $ mkSumType @TestSum + , jsonHelpers . additionalInstances $ mkSumType @TestData + ] diff --git a/example/src/Main.purs b/example/src/Main.purs index 1f1d71f0..532ab6c9 100644 --- a/example/src/Main.purs +++ b/example/src/Main.purs @@ -1,60 +1,94 @@ -module Main where +module ExampleMain where import Prelude -import Data.Argonaut.Decode.Error (JsonDecodeError, printJsonDecodeError) +import Affjax.RequestBody as RequestBody +import Affjax.ResponseFormat (json) +import Affjax.Web (get, post_) import Data.Argonaut.Aeson.Decode.Generic (genericDecodeAeson) import Data.Argonaut.Aeson.Encode.Generic (genericEncodeAeson) +import Data.Argonaut.Decode (JsonDecodeError, decodeJson, parseJson, printJsonDecodeError) +import Data.Argonaut.Encode (encodeJson) import Data.Argonaut.Aeson.Options (defaultOptions) +import Data.Argonaut.Decode.Error (JsonDecodeError, printJsonDecodeError) import Data.Either (Either(Left, Right)) -import Data.Maybe (Maybe(Just)) -import Data.Lens (over, view, set) import Data.Foldable (length) +import Data.Lens (over, view, set) +import Data.Maybe (Maybe(Just)) import Data.Traversable (for_) import Effect (Effect) -import Effect.Console (log) -import Effect.Class (liftEffect) import Effect.Aff (launchAff_) -import Affjax.Web (get, post_) -import Affjax.ResponseFormat (json) -import Affjax.RequestBody as RequestBody -import Types (Foo, fooMessage, fooNumber, fooList) -import Data.Argonaut.Decode.Error (JsonDecodeError) -import Data.Argonaut.Decode.Generic (genericDecodeJson) -import Data.Argonaut.Encode.Generic (genericEncodeJson) -import Types (Foo, fooMessage, fooNumber, fooList, fooMap) -import Data.Map as Map - +import Effect.Class (liftEffect) +import Effect.Console (log) +import Foreign.Object (empty) import Foreign.Object as Object +import Argonaut.Types (Baz(Baz), Foo(Foo), TestData(..), TestSum(..), fooMessage, fooNumber, fooList, fooMap, fooTestSum, fooTestData) + +testFoo = Foo + { _fooMessage: "foo" + , _fooE: Left "foo" + , _fooNumber: 1 + , _fooList: [1,2,3] + , _fooMap: empty + , _fooBaz: Baz { _bazMessage: "baz" } + , _fooTestSum: Nullary + , _fooTestData: TEither "foo" + } main :: Effect Unit -main = log "Hello, Purescript!" *> launchAff_ do - -- "Foo" tests untagged JSON, i.e.: - -- { "_fooMessage": "Hello", "_fooNumber": 123 } +main = log "Hello, PureScript!" *> launchAff_ do + -- request a Foo; decode with ArgonautAesonGeneric + fooResponse <- get json "/foo" + for_ fooResponse \fooPayload -> do + liftEffect $ log $ "Decode and Encode with ArgonautAesoGeneric" + let + eArgonautDecodedFoo :: Either JsonDecodeError Foo + eArgonautDecodedFoo = genericDecodeAeson defaultOptions fooPayload.body + case eArgonautDecodedFoo of + Left e -> liftEffect $ log $ "Error decoding Foo: " <> printJsonDecodeError e + Right _ -> pure unit + for_ eArgonautDecodedFoo \argonautDecodedFoo -> do + liftEffect do + log $ "Foo message: " <> (view fooMessage argonautDecodedFoo) + log $ "Foo number: " <> (show $ view fooNumber argonautDecodedFoo) + log $ "Foo list length: " <> (show (length $ view fooList argonautDecodedFoo :: Int)) + log $ "Foo map size: " <> (show (Object.size $ view fooMap argonautDecodedFoo :: Int)) + log $ "Foo test sum: " <> show (view fooTestSum argonautDecodedFoo) + log $ "Foo test data: " <> show (view fooTestData argonautDecodedFoo) + let + -- modify the Foo received and send it back + modifiedFoo = set fooMessage "Hello from ArgonautAesonGeneric" + $ over fooNumber (_+1) + $ over fooList (\l -> l <> l) + $ over fooMap (\o -> Object.insert "abc" 123 o) + $ argonautDecodedFoo + response = Just $ RequestBody.json $ genericEncodeAeson defaultOptions modifiedFoo + post_ "/foo" response - -- request a Foo + -- request a Foo; decode with JsonHelpers fooResponse <- get json "/foo" for_ fooResponse \fooPayload -> do + liftEffect $ log $ "Decode and Encode with JsonHelpers" let - efoo :: Either JsonDecodeError Foo - efoo = genericDecodeAeson defaultOptions fooPayload.body - case efoo of + eJsonHelpersDecodedFoo :: Either JsonDecodeError Foo + eJsonHelpersDecodedFoo = decodeJson fooPayload.body + case eJsonHelpersDecodedFoo of Left e -> liftEffect $ log $ "Error decoding Foo: " <> printJsonDecodeError e Right _ -> pure unit - for_ efoo \foo -> do + for_ eJsonHelpersDecodedFoo \jsonHelpersFoo -> do liftEffect do - log $ "Foo message: " <> (view fooMessage foo) - <> "\t Foo number: " <> (show $ view fooNumber foo) - <> "\t Foo list length: " - <> (show (length $ view fooList foo :: Int)) - <> "\t Foo map size: " - <> (show (Object.size $ view fooMap foo :: Int)) + log $ "Foo message: " <> (view fooMessage jsonHelpersFoo) + log $ "Foo number: " <> (show $ view fooNumber jsonHelpersFoo) + log $ "Foo list length: " <> (show (length $ view fooList jsonHelpersFoo :: Int)) + log $ "Foo map size: " <> (show (Object.size $ view fooMap jsonHelpersFoo :: Int)) + log $ "Foo test sum: " <> show (view fooTestSum jsonHelpersFoo) + log $ "Foo test data: " <> show (view fooTestData jsonHelpersFoo) let -- modify the Foo received and send it back - foo' = set fooMessage "Hola" + modifiedFoo = set fooMessage "Hello from JsonHelpers" $ over fooNumber (_+1) $ over fooList (\l -> l <> l) $ over fooMap (\o -> Object.insert "abc" 123 o) - $ foo - response = Just $ RequestBody.json $ genericEncodeAeson defaultOptions foo' + $ jsonHelpersFoo + response = Just $ RequestBody.json $ encodeJson modifiedFoo post_ "/foo" response diff --git a/example/src/MyLib.hs b/example/src/MyLib.hs index 7efc91db..3e0220c8 100644 --- a/example/src/MyLib.hs +++ b/example/src/MyLib.hs @@ -1,5 +1,6 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeOperators #-} module MyLib (main) where @@ -8,43 +9,65 @@ import Prelude import Control.Lens (view) import Control.Monad.IO.Class (liftIO) -import Data.Aeson +import Data.Aeson () import qualified Data.Aeson.Encode.Pretty as AP import qualified Data.ByteString.Lazy.Char8 as Char8 import qualified Data.Map.Lazy as Map import Data.Text (pack, unpack) -import GHC.Generics -import GHC.TypeLits -import Network.Wai.Handler.Warp -import Servant +import qualified Data.Text as T +import GHC.Generics () +import GHC.TypeLits () +import Network.Wai.Handler.Warp (run) +import Servant (Get, JSON, NoContent (..), Post, Proxy (..), Raw, + ReqBody, Server, serve, serveDirectoryWebApp, + type (:<|>) (..), type (:>)) import System.Environment (lookupEnv) +import Test.QuickCheck (Arbitrary (..), chooseEnum, generate, oneof, + resize, sized) -import Types (Baz (Baz), Foo (Foo), fooList, fooMap, fooMessage, - fooNumber) +import qualified Types +import Types (Baz (Baz), Foo (Foo), TestData (..), TestSum (..), + fooList, fooMap, fooMessage, fooNumber) type FooServer = "foo" :> (Get '[JSON] Foo :<|> ReqBody '[JSON] Foo :> Post '[JSON] NoContent ) -foo :: Foo -foo = Foo - (pack "Hello") - 123 - [10..20] - (Map.fromList [(pack "foo", 2), (pack "bar", 3), (pack "baz", 3)]) - (Baz $ pack "hello") +foo :: IO Foo +foo = do + testEither :: Either T.Text Int <- generate arbitrary + testData :: TestData <- generate arbitrary + testSum :: TestSum <- generate arbitrary + return $ Foo + (pack "Hello") + testEither + 123 + [10..13] + (Map.fromList [(pack "foo", 2), (pack "bar", 3), (pack "baz", 3)]) + (Baz $ pack "hello") + testSum + testData fooServer :: Server FooServer fooServer = getFoo :<|> postFoo where - getFoo = return foo + getFoo = do + fooValue <- liftIO foo + liftIO $ putStrLn "-----------------" + liftIO $ putStrLn "Foo:" + liftIO $ putStrLn $ show fooValue + liftIO $ putStrLn "Serving JSON:" + liftIO $ Char8.putStrLn $ AP.encodePretty fooValue + return fooValue + postFoo foo = do let logMsg = "Foo message: " <> (unpack $ view fooMessage foo) <> "\t Foo number: " <> (show (view fooNumber foo)) <> "\t Foo list length: " <> (show . length $ view fooList foo) <> "\t Foo Map length: " <> (show . length $ view fooMap foo) + liftIO . putStrLn $ "Received from client:" liftIO . putStrLn $ logMsg return NoContent @@ -58,7 +81,4 @@ api = Proxy main :: IO () main = do - putStrLn "Serving Foo:" - Char8.putStrLn $ AP.encodePretty foo - run 8080 . serve api $ fooServer :<|> staticServer diff --git a/example/src/Types.hs b/example/src/Types.hs index 75994a49..6461d251 100644 --- a/example/src/Types.hs +++ b/example/src/Types.hs @@ -1,62 +1,128 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeOperators #-} module Types where import Control.Lens.TH (makeLenses) -import Data.Aeson +import Data.Aeson (FromJSON, SumEncoding (..), ToJSON (toEncoding), + defaultOptions, defaultTaggedObject, + genericToEncoding, sumEncoding, + tagSingleConstructors, unwrapUnaryRecords) import qualified Data.Map.Lazy as Map -import Data.Proxy -import Data.Text -import Data.Typeable -import GHC.Generics -import Language.PureScript.Bridge -import Language.PureScript.Bridge.PSTypes +import Data.Proxy () +import Data.Text (Text, pack) +import Data.Typeable (Typeable) +import GHC.Generics (Generic) +import Language.PureScript.Bridge (BridgePart, Language (Haskell), + argonautAesonGeneric, + defaultBridge, genericShow, + jsonHelpers, lenses, mkSumType) +import Language.PureScript.Bridge.PSTypes () +import Language.PureScript.Bridge.SumType (SumType) import Language.PureScript.Bridge.TypeParameters (A) +import Test.QuickCheck (Arbitrary (..), chooseEnum, oneof, resize, + sized) data Baz = Baz { _bazMessage :: Text } - deriving (FromJSON, Generic, ToJSON) + deriving (FromJSON, Generic, Show) + +instance ToJSON Baz where + toEncoding = genericToEncoding + ( + defaultOptions + { tagSingleConstructors = True + , unwrapUnaryRecords = True + } + ) makeLenses ''Baz -bazProxy :: Proxy Baz -bazProxy = Proxy +-- https://github.com/eskimor/purescript-bridge/pull/89#issuecomment-1890994859 +data ID a = ID + deriving (Generic, Show) + +newtype ID2 a + = ID2 { getID :: Int } + deriving (Generic, Show) + + + +data TestSum + = Nullary + | Bool Bool + | Int Int + | Number Double + deriving (Eq, FromJSON, Generic, Ord, Show, ToJSON) + +instance Arbitrary Text where + arbitrary = pure $ pack "foooo" + +instance Arbitrary TestSum where + arbitrary = + oneof + [ pure Nullary + , Bool <$> arbitrary + , Int <$> arbitrary + , Number <$> arbitrary + ] + +data TestData + = TMaybe (Maybe TestSum) + | TEither Text -- (Either Int Text) -- (Either (Maybe Int) (Maybe Bool)) + deriving (Eq, FromJSON, Generic, Ord, Show, ToJSON) + +instance Arbitrary TestData where + arbitrary = + oneof + [ -- Maybe <$> arbitrary + -- , + TEither <$> arbitrary + ] + data Foo = Foo - { _fooMessage :: Text - , _fooNumber :: Int - , _fooList :: [Int] - , _fooMap :: Map.Map Text Int - , _fooBaz :: Baz + { _fooMessage :: Text + , _fooE :: Either Text Int + , _fooNumber :: Int + , _fooList :: [Int] + , _fooMap :: Map.Map Text Int + , _fooBaz :: Baz + , _fooTestSum :: TestSum + , _fooTestData :: TestData } - deriving (FromJSON, Generic, ToJSON) + deriving (FromJSON, Generic, Show, ToJSON) + -makeLenses ''Foo -fooProxy :: Proxy Foo -fooProxy = Proxy +instance {-# OVERLAPPING #-} ToJSON (Either Text Int) where + toEncoding = genericToEncoding + ( + defaultOptions + { tagSingleConstructors = True + , unwrapUnaryRecords = True + -- , sumEncoding = TaggedObject "foo" "bar" -- defaultTaggedObject { contentsFieldName = "value" } + } + ) + +instance {-# OVERLAPPING #-} FromJSON (Either Text Int) + +makeLenses ''Foo -- TODO newtype data Bar a = Bar a - deriving (Generic, Show, Typeable, FromJSON, ToJSON) + deriving (FromJSON, Generic, Show, ToJSON, Typeable) makeLenses ''Bar -barProxy :: Proxy Bar -barProxy = Proxy +additionalInstances = lenses . genericShow myBridge :: BridgePart myBridge = defaultBridge - -myTypes :: [SumType 'Haskell] -myTypes = - [ mkSumType (Proxy :: Proxy Baz) - , mkSumType (Proxy :: Proxy Foo) - , mkSumType (Proxy :: Proxy (Bar A)) - ] diff --git a/example/src/Types.purs b/example/src/Types.purs deleted file mode 100644 index 37731274..00000000 --- a/example/src/Types.purs +++ /dev/null @@ -1,98 +0,0 @@ --- File auto generated by purescript-bridge! -- -module Types where - -import Data.Argonaut.Aeson.Decode.Generic (genericDecodeAeson) -import Data.Argonaut.Aeson.Encode.Generic (genericEncodeAeson) -import Data.Argonaut.Aeson.Options as Argonaut -import Data.Argonaut.Decode.Class (class DecodeJson, class DecodeJsonField, decodeJson) -import Data.Argonaut.Encode.Class (class EncodeJson, encodeJson) -import Data.Generic.Rep (class Generic) -import Data.Lens (Iso', Lens', Prism', lens, prism') -import Data.Lens.Iso.Newtype (_Newtype) -import Data.Lens.Record (prop) -import Data.Maybe (Maybe(..)) -import Data.Newtype (class Newtype) -import Foreign.Class (class Decode, class Encode) -import Foreign.Generic (defaultOptions, genericDecode, genericEncode) -import Foreign.Object (Object) -import Prim (Array, Int, String) -import Type.Proxy (Proxy(Proxy)) - -import Prelude - -newtype Baz = - Baz { - _bazMessage :: String - } - - - -instance encodeJsonBaz :: EncodeJson Baz where - encodeJson = genericEncodeAeson Argonaut.defaultOptions -instance decodeJsonBaz :: DecodeJson Baz where - decodeJson = genericDecodeAeson Argonaut.defaultOptions -derive instance genericBaz :: Generic Baz _ -derive instance newtypeBaz :: Newtype Baz _ - --------------------------------------------------------------------------------- -_Baz :: Iso' Baz { _bazMessage :: String} -_Baz = _Newtype - -bazMessage :: Lens' Baz String -bazMessage = _Newtype <<< prop (Proxy :: Proxy "_bazMessage") - --------------------------------------------------------------------------------- -newtype Foo = - Foo { - _fooMessage :: String - , _fooNumber :: Int - , _fooList :: Array Int - , _fooMap :: Object Int - , _fooBaz :: Baz - } - - - -instance encodeJsonFoo :: EncodeJson Foo where - encodeJson = genericEncodeAeson Argonaut.defaultOptions -instance decodeJsonFoo :: DecodeJson Foo where - decodeJson = genericDecodeAeson Argonaut.defaultOptions -derive instance genericFoo :: Generic Foo _ -derive instance newtypeFoo :: Newtype Foo _ - --------------------------------------------------------------------------------- -_Foo :: Iso' Foo { _fooMessage :: String, _fooNumber :: Int, _fooList :: Array Int, _fooMap :: Object Int, _fooBaz :: Baz} -_Foo = _Newtype - -fooMessage :: Lens' Foo String -fooMessage = _Newtype <<< prop (Proxy :: Proxy "_fooMessage") - -fooNumber :: Lens' Foo Int -fooNumber = _Newtype <<< prop (Proxy :: Proxy "_fooNumber") - -fooList :: Lens' Foo (Array Int) -fooList = _Newtype <<< prop (Proxy :: Proxy "_fooList") - -fooMap :: Lens' Foo (Object Int) -fooMap = _Newtype <<< prop (Proxy :: Proxy "_fooMap") - -fooBaz :: Lens' Foo Baz -fooBaz = _Newtype <<< prop (Proxy :: Proxy "_fooBaz") - --------------------------------------------------------------------------------- -newtype Bar a = - Bar a - - - -instance encodeJsonBar :: (Generic a ra, EncodeJson a) => EncodeJson (Bar a) where - encodeJson = genericEncodeAeson Argonaut.defaultOptions -instance decodeJsonBar :: (Generic a ra, DecodeJson a, DecodeJsonField a) => DecodeJson (Bar a) where - decodeJson = genericDecodeAeson Argonaut.defaultOptions -derive instance genericBar :: Generic a ra => Generic (Bar a) _ -derive instance newtypeBar :: Newtype (Bar a) _ - --------------------------------------------------------------------------------- -_Bar :: forall a. Iso' (Bar a) a -_Bar = _Newtype --------------------------------------------------------------------------------- diff --git a/example/static/index.html b/example/static/index.html index 7601961f..68fe7ba7 100644 --- a/example/static/index.html +++ b/example/static/index.html @@ -1,16 +1,17 @@
-