diff --git a/foreign/.eslintrc.json b/foreign/.eslintrc.json deleted file mode 100644 index 1c6afb9d..00000000 --- a/foreign/.eslintrc.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "extends": "eslint:recommended", - "rules": { - "strict": [2, "global"], - "block-scoped-var": 2, - "consistent-return": 2, - "eqeqeq": [2, "smart"], - "guard-for-in": 2, - "no-caller": 2, - "no-extend-native": 2, - "no-loop-func": 2, - "no-new": 2, - "no-param-reassign": 2, - "no-return-assign": 2, - "no-unused-expressions": 2, - "no-use-before-define": 2, - "radix": [2, "always"], - "indent": [2, 2], - "quotes": [2, "double"], - "semi": [2, "always"] - } -} diff --git a/foreign/.github/PULL_REQUEST_TEMPLATE.md b/foreign/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 4435abbe..00000000 --- a/foreign/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,12 +0,0 @@ -**Description of the change** - -Clearly and concisely describe the purpose of the pull request. If this PR relates to an existing issue or change proposal, please link to it. Include any other background context that would help reviewers understand the motivation for this PR. - ---- - -**Checklist:** - -- [ ] Added the change to the changelog's "Unreleased" section with a reference to this PR (e.g. "- Made a change (#0000)") -- [ ] Linked any existing issues or proposals that this pull request should close -- [ ] Updated or added relevant documentation -- [ ] Added a test for the contribution (if applicable) diff --git a/foreign/.github/workflows/ci.yml b/foreign/.github/workflows/ci.yml deleted file mode 100644 index c69237a6..00000000 --- a/foreign/.github/workflows/ci.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: CI - -on: - push: - branches: [master] - pull_request: - branches: [master] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - uses: purescript-contrib/setup-purescript@main - with: - purescript: "unstable" - - - uses: actions/setup-node@v2 - with: - node-version: "14.x" - - - name: Install dependencies - run: | - npm install -g bower - npm install - bower install --production - - - name: Build source - run: npm run-script build - - - name: Run tests - run: | - bower install - npm run-script test --if-present diff --git a/foreign/.gitignore b/foreign/.gitignore deleted file mode 100644 index b846b630..00000000 --- a/foreign/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/.* -!/.gitignore -!/.eslintrc.json -!/.github/ -/bower_components/ -/node_modules/ -/output/ -package-lock.json diff --git a/foreign/CHANGELOG.md b/foreign/CHANGELOG.md deleted file mode 100644 index 40eec6a5..00000000 --- a/foreign/CHANGELOG.md +++ /dev/null @@ -1,197 +0,0 @@ -# Changelog - -Notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -Breaking changes: - -New features: - -Bugfixes: - -Other improvements: - -## [v7.0.0](https://github.com/purescript/purescript-foreign/releases/tag/v7.0.0) - 2022-04-27 - -Breaking changes: -- Migrate FFI to ES modules (#86 by @kl0tl and @JordanMartinez) - -New features: - -Bugfixes: - -Other improvements: -- Replace all usages of `F` and `FT` with `Except`/`ExceptT (NonEmptyList ForeignError)` (#87 by @JordanMartinez) - - Often times, the `F` and `FT` aliases did more to hinder usage of this library than help. These aliases - haven't been deprecated, but usage of them is now discouraged. All code in the library now uses - the full type that is aliased by `F` and `FT`. - -## [v6.0.1](https://github.com/purescript/purescript-foreign/releases/tag/v6.0.1) - 2021-04-20 - -Other improvements: -- Fix warnings revealed by v0.14.1 PureScript release (#85 by @JordanMartinez) - -## [v6.0.0](https://github.com/purescript/purescript-foreign/releases/tag/v6.0.0) - 2021-02-26 - -Breaking changes: -- Added support for PureScript 0.14 and dropped support for all previous versions (#80) - -Other improvements: -- Migrated CI to GitHub Actions and updated installation instructions to use Spago (#81) -- Added a CHANGELOG.md file and pull request template (#82, #83) -- Replaced `unsafeToForeign` and `unsafeFromForeign` with `unsafeCoerce` (#72) - -## [v5.0.0](https://github.com/purescript/purescript-foreign/releases/tag/v5.0.0) - 2018-05-24 - -- Updated for PureScript 0.12 -- `renderForeignError` now renders nested errors correcty (@abhin4v) -- The namespace is now `Foreign` rather than `Data.Foreign` -- The `JSONError` constructor was removed. This library is not for JSON, it was a bad name - use `ForeignError` instead. -- `toForeign` has been renamed as `unsafeToForeign` with a comment explaining its intended usage and potential risks - -## [v4.0.1](https://github.com/purescript/purescript-foreign/releases/tag/v4.0.1) - 2017-06-08 - -Fix `Show` instance for `ForeignError` (@rightfold) - -## [v4.0.0](https://github.com/purescript/purescript-foreign/releases/tag/v4.0.0) - 2017-03-29 - -- Updated for PureScript 0.11 -- The library has been drastically simplified to focus on its core use; validating and extracting data from foreign values. This involves changes such as: - - Removal of `IsForeign` / `AsForeign` classes - - Removal of `parseJSON` as this library is not intended for general JSON parsing -- New functions were added for `readNull`, `readUndefined`, `readNullOrUndefined` rather than using the newtypes to direct `IsForeign` choice as it was before -- The `(!)` index/property reading operator has been enhanced to work with `Foreign` or `F Foreign` on the left hand side, allowing for chained property reads - -## [v3.2.0](https://github.com/purescript/purescript-foreign/releases/tag/v3.2.0) - 2017-01-29 - -Add instances for `Null`, `Undefined` and `NullOrUndefined` (@felixSchl) - -## [v3.0.1](https://github.com/purescript/purescript-foreign/releases/tag/v3.0.1) - 2016-11-14 - -- Fixed shadowed name warning - -## [v3.0.0](https://github.com/purescript/purescript-foreign/releases/tag/v3.0.0) - 2016-10-16 - -- Updated lists dependency - -## [v2.0.0](https://github.com/purescript/purescript-foreign/releases/tag/v2.0.0) - 2016-10-13 - -- Updated dependecies -- `F` now uses `Except` and allows for the accumulation of multiple errors when using `<|>` in parsing - -## [v1.1.0](https://github.com/purescript/purescript-foreign/releases/tag/v1.1.0) - 2016-08-09 - -- Added `AsForeign` class and combinators for writing values as `Foreign` (@puffnfresh) - -## [v1.0.0](https://github.com/purescript/purescript-foreign/releases/tag/v1.0.0) - 2016-06-01 - -This release is intended for the PureScript 0.9.1 compiler and newer. - -**Note**: The v1.0.0 tag is not meant to indicate the library is “finished”, the core libraries are all being bumped to this for the 0.9 compiler release so as to use semver more correctly. - -## [v1.0.0-rc.1](https://github.com/purescript/purescript-foreign/releases/tag/v1.0.0-rc.1) - 2016-03-25 - -- Release candidate for the psc 0.8+ core libraries - -## [v0.7.2](https://github.com/purescript/purescript-foreign/releases/tag/v0.7.2) - 2015-11-20 - -- Fixed shadowed type variable warnings (@tfausak) - -## [v0.7.1](https://github.com/purescript/purescript-foreign/releases/tag/v0.7.1) - 2015-11-09 - -Fix a type error. - -## [v0.7.0](https://github.com/purescript/purescript-foreign/releases/tag/v0.7.0) - 2015-08-13 - -- Updated dependencies - -## [v0.6.0](https://github.com/purescript/purescript-foreign/releases/tag/v0.6.0) - 2015-08-02 - -- Updated dependencies - -## [v0.5.1](https://github.com/purescript/purescript-foreign/releases/tag/v0.5.1) - 2015-07-19 - -- Added `IsForeign` instances for `Int` and `Char` (@anttih) - -## [v0.5.0](https://github.com/purescript/purescript-foreign/releases/tag/v0.5.0) - 2015-06-30 - -This release works with versions 0.7.\* of the PureScript compiler. It will not work with older versions. If you are using an older version, you should require an older, compatible version of this library. - -## [v0.5.0-rc.2](https://github.com/purescript/purescript-foreign/releases/tag/v0.5.0-rc.2) - 2015-06-15 - -Rename `!` operator to `ix`. - -## [v0.5.0-rc.1](https://github.com/purescript/purescript-foreign/releases/tag/v0.5.0-rc.1) - 2015-06-10 - -Initial release candidate of the library intended for the 0.7 compiler. - -## [v0.4.2](https://github.com/purescript/purescript-foreign/releases/tag/v0.4.2) - 2015-03-26 - -- `unsafeReadTagged` is now exposed (@garyb) - -## [v0.4.1](https://github.com/purescript/purescript-foreign/releases/tag/v0.4.1) - 2015-03-20 - -Updated docs - -## [v0.4.0](https://github.com/purescript/purescript-foreign/releases/tag/v0.4.0) - 2015-02-21 - -**This release requires PureScript v0.6.8 or later** -- Updated dependencies - -## [v0.3.0](https://github.com/purescript/purescript-foreign/releases/tag/v0.3.0) - 2015-01-10 - -- Made dependency versions explicit (@garyb) - -## [v0.2.3](https://github.com/purescript/purescript-foreign/releases/tag/v0.2.3) - 2014-12-11 - -- Added ES3 fallbacks for `Array.isArray` and `Object.keys` (@davidchambers) - -## [v0.2.2](https://github.com/purescript/purescript-foreign/releases/tag/v0.2.2) - 2014-11-19 - - - -## [v0.2.1](https://github.com/purescript/purescript-foreign/releases/tag/v0.2.1) - 2014-11-18 - -- `IsForeign` instance for `Foreign`. (@MichaelXavier) - -## [v0.2.0](https://github.com/purescript/purescript-foreign/releases/tag/v0.2.0) - 2014-08-20 - -Quite a few breaking changes to both names and types: -- A type for errors instead of using string concatenation. -- Breaking a few functions out into their own submodules. -- Adding types and instances to handle null-like values. -- Use the `Either` monad instead of the `ForeignParser` monad. - -## [v0.1.6](https://github.com/purescript/purescript-foreign/releases/tag/v0.1.6) - 2014-08-09 - -- Removed unused dependency on `purescript-globals` (@garyb) - -## [v0.1.5](https://github.com/purescript/purescript-foreign/releases/tag/v0.1.5) - 2014-08-08 - -- Removed `ReadForeign Error` instance after `Error` was removed from `Global` (@AitorATuin) - -## [v0.1.4](https://github.com/purescript/purescript-foreign/releases/tag/v0.1.4) - 2014-07-29 - -- Added `index` (@philopon) -- Rewrote some calls to `runFnX` to trigger inlining optimisation (@garyb) - -## [v0.1.3](https://github.com/purescript/purescript-foreign/releases/tag/v0.1.3) - 2014-07-26 - -- Updated FFI code to work for changes in codegen (@garyb) -- Added `keys` to read a list of key names from an object (@andreypopp) -- Fixed bug in `prop` that may have resulted in runtime errors when the object is null (@andreypopp) - -## [v0.1.2](https://github.com/purescript/purescript-foreign/releases/tag/v0.1.2) - 2014-06-02 - -- Added `ReadForeign Error` instance (garyb) - -## [v0.1.1](https://github.com/purescript/purescript-foreign/releases/tag/v0.1.1) - 2014-04-27 - - - -## [v0.1.0](https://github.com/purescript/purescript-foreign/releases/tag/v0.1.0) - 2014-04-26 - - - diff --git a/foreign/LICENSE b/foreign/LICENSE deleted file mode 100644 index 311379c1..00000000 --- a/foreign/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ -Copyright 2018 PureScript - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors -may be used to endorse or promote products derived from this software without -specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/foreign/README.md b/foreign/README.md deleted file mode 100644 index a7676dd0..00000000 --- a/foreign/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# purescript-foreign - -[![Latest release](http://img.shields.io/github/release/purescript/purescript-foreign.svg)](https://github.com/purescript/purescript-foreign/releases) -[![Build status](https://github.com/purescript/purescript-foreign/workflows/CI/badge.svg?branch=master)](https://github.com/purescript/purescript-foreign/actions?query=workflow%3ACI+branch%3Amaster) -[![Pursuit](https://pursuit.purescript.org/packages/purescript-foreign/badge)](https://pursuit.purescript.org/packages/purescript-foreign) - -Library for dealing with foreign data (JavaScript objects). - -## Installation - -``` -spago install foreign -``` - -## Examples - -- [Simple types](examples/SimpleTypes.purs) -- [Arrays](examples/Arrays.purs) -- [Objects](examples/Objects.purs) -- [Complex objects](examples/Complex.purs) -- [Applicative style parser](examples/Applicative.purs) -- [Maybe for nulls](examples/MaybeNullable.purs) -- [Nested objects](examples/Nested.purs) -- [Unions](examples/Union.purs) -- [Parser errors](examples/ParseErrors.purs) - -## Documentation - -Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-foreign). diff --git a/foreign/bower.json b/foreign/bower.json deleted file mode 100644 index c84d014b..00000000 --- a/foreign/bower.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "purescript-foreign", - "homepage": "https://github.com/purescript/purescript-foreign", - "authors": [ - "Gary Burgess ", - "Phil Freeman " - ], - "repository": { - "type": "git", - "url": "https://github.com/purescript/purescript-foreign.git" - }, - "license": "BSD-3-Clause", - "ignore": [ - "**/.*", - "bower_components", - "examples", - "node_modules", - "output", - "bower.json", - "package.json" - ], - "dependencies": { - "purescript-either": "^6.0.0", - "purescript-functions": "^6.0.0", - "purescript-identity": "^6.0.0", - "purescript-integers": "^6.0.0", - "purescript-lists": "^7.0.0", - "purescript-maybe": "^6.0.0", - "purescript-prelude": "^6.0.0", - "purescript-strings": "^6.0.0", - "purescript-transformers": "^6.0.0" - }, - "devDependencies": { - "purescript-console": "^6.0.0" - } -} diff --git a/foreign/examples/Applicative.purs b/foreign/examples/Applicative.purs deleted file mode 100755 index 52961c6c..00000000 --- a/foreign/examples/Applicative.purs +++ /dev/null @@ -1,28 +0,0 @@ -module Example.Applicative where - -import Prelude - -import Control.Monad.Except (Except, runExcept) -import Data.List.NonEmpty (NonEmptyList) -import Effect (Effect) -import Effect.Console (logShow) -import Example.Util.Value (foreignValue) -import Foreign (Foreign, ForeignError, readNumber) -import Foreign.Index ((!)) - -data Point = Point Number Number Number - -instance showPoint :: Show Point where - show (Point x y z) = "(Point " <> show [x, y, z] <> ")" - -readPoint :: Foreign -> Except (NonEmptyList ForeignError) Point -readPoint value = do - Point - <$> (value ! "x" >>= readNumber) - <*> (value ! "y" >>= readNumber) - <*> (value ! "z" >>= readNumber) - -main :: Effect Unit -main = - logShow $ runExcept $ - readPoint =<< foreignValue """{ "x": 1, "y": 2, "z": 3 }""" diff --git a/foreign/examples/Arrays.purs b/foreign/examples/Arrays.purs deleted file mode 100644 index 86efd369..00000000 --- a/foreign/examples/Arrays.purs +++ /dev/null @@ -1,17 +0,0 @@ -module Example.Arrays where - -import Prelude - -import Control.Monad.Except (runExcept) -import Data.Traversable (traverse) -import Effect (Effect) -import Effect.Console (logShow) -import Example.Util.Value (foreignValue) -import Foreign (readArray, readNumber, readString) - -main :: Effect Unit -main = do - logShow $ runExcept $ - traverse readString =<< readArray =<< foreignValue """["hello", "world"]""" - logShow $ runExcept $ - traverse readNumber =<< readArray =<< foreignValue """[1, 2, 3, 4]""" diff --git a/foreign/examples/Complex.purs b/foreign/examples/Complex.purs deleted file mode 100755 index 68b6875d..00000000 --- a/foreign/examples/Complex.purs +++ /dev/null @@ -1,46 +0,0 @@ -module Example.Complex where - -import Prelude - -import Control.Monad.Except (Except, runExcept) -import Data.List.NonEmpty (NonEmptyList) -import Data.Maybe (Maybe) -import Data.Traversable (traverse) -import Effect (Effect) -import Effect.Console (logShow) -import Example.Util.Value (foreignValue) -import Foreign (Foreign, ForeignError, readArray, readBoolean, readNumber, readString, readNullOrUndefined) -import Foreign.Index ((!)) - -type SomeObject = - { foo :: String - , bar :: Boolean - , baz :: Number - , list :: Array ListItem - } - -readSomeObject :: Foreign -> Except (NonEmptyList ForeignError) SomeObject -readSomeObject value = do - foo <- value ! "foo" >>= readString - bar <- value ! "bar" >>= readBoolean - baz <- value ! "baz" >>= readNumber - list <- value ! "list" >>= readArray >>= traverse readListItem - pure { foo, bar, baz, list } - -type ListItem = - { x :: Number - , y :: Number - , z :: Maybe Number - } - -readListItem :: Foreign -> Except (NonEmptyList ForeignError) ListItem -readListItem value = do - x <- value ! "x" >>= readNumber - y <- value ! "y" >>= readNumber - z <- value ! "z" >>= readNullOrUndefined >>= traverse readNumber - pure { x, y, z } - -main :: Effect Unit -main = do - let json = """{"foo":"hello","bar":true,"baz":1,"list":[{"x":1,"y":2},{"x":3,"y":4,"z":999}]}""" - logShow $ runExcept $ readSomeObject =<< foreignValue json diff --git a/foreign/examples/MaybeNullable.purs b/foreign/examples/MaybeNullable.purs deleted file mode 100755 index 18316634..00000000 --- a/foreign/examples/MaybeNullable.purs +++ /dev/null @@ -1,21 +0,0 @@ -module Example.MaybeNullable where - -import Prelude - -import Effect (Effect) -import Effect.Console (logShow) -import Control.Monad.Except (runExcept) - -import Foreign (readBoolean, readNull) -import Data.Traversable (traverse) - -import Example.Util.Value (foreignValue) - --- Parsing values that are allowed to null or undefined is possible by --- using Maybe types. -main :: Effect Unit -main = do - logShow $ runExcept $ - traverse readBoolean =<< readNull =<< foreignValue "null" - logShow $ runExcept $ - traverse readBoolean =<< readNull =<< foreignValue "true" diff --git a/foreign/examples/Nested.purs b/foreign/examples/Nested.purs deleted file mode 100755 index bbcb3e4d..00000000 --- a/foreign/examples/Nested.purs +++ /dev/null @@ -1,36 +0,0 @@ -module Example.Nested where - -import Prelude - -import Control.Monad.Except (runExcept) -import Effect (Effect) -import Effect.Console (logShow) -import Example.Util.Value (foreignValue) -import Foreign (F, Foreign, readNumber, readString) -import Foreign.Index ((!)) - -data Foo = Foo Bar Baz - -data Bar = Bar String - -data Baz = Baz Number - -instance showFoo :: Show Foo where - show (Foo bar baz) = "(Foo " <> show bar <> " " <> show baz <> ")" - -instance showBar :: Show Bar where - show (Bar s) = "(Bar " <> show s <> ")" - -instance showBaz :: Show Baz where - show (Baz n) = "(Baz " <> show n <> ")" - -readFoo :: Foreign -> F Foo -readFoo value = do - s <- value ! "foo" ! "bar" >>= readString - n <- value ! "foo" ! "baz" >>= readNumber - pure $ Foo (Bar s) (Baz n) - -main :: Effect Unit -main = - logShow $ runExcept $ - readFoo =<< foreignValue """{ "foo": { "bar": "bar", "baz": 1 } }""" diff --git a/foreign/examples/Objects.purs b/foreign/examples/Objects.purs deleted file mode 100755 index d2fdca96..00000000 --- a/foreign/examples/Objects.purs +++ /dev/null @@ -1,24 +0,0 @@ -module Example.Objects where - -import Prelude - -import Control.Monad.Except (Except, runExcept) -import Data.List.NonEmpty (NonEmptyList) -import Effect (Effect) -import Effect.Console (logShow) -import Example.Util.Value (foreignValue) -import Foreign (Foreign, ForeignError, readNumber) -import Foreign.Index ((!)) - -type Point = { x :: Number, y :: Number } - -readPoint :: Foreign -> Except (NonEmptyList ForeignError) Point -readPoint value = do - x <- value ! "x" >>= readNumber - y <- value ! "y" >>= readNumber - pure { x, y } - -main :: Effect Unit -main = do - logShow $ runExcept $ - readPoint =<< foreignValue """{ "x": 1, "y": 2 }""" diff --git a/foreign/examples/ParseErrors.purs b/foreign/examples/ParseErrors.purs deleted file mode 100755 index 1a4c60aa..00000000 --- a/foreign/examples/ParseErrors.purs +++ /dev/null @@ -1,45 +0,0 @@ -module Example.ParseErrors where - -import Prelude - -import Control.Monad.Except (Except, runExcept) -import Data.List.NonEmpty (NonEmptyList) -import Data.Traversable (traverse) -import Effect (Effect) -import Effect.Console (logShow) -import Example.Util.Value (foreignValue) -import Foreign (Foreign, ForeignError, readArray, readBoolean, readNumber, readString) -import Foreign.Index ((!)) - -newtype Point = Point { x :: Number, y :: Number } - -instance showPoint :: Show Point where - show (Point o) = "(Point { x: " <> show o.x <> ", y: " <> show o.y <> " })" - -readPoint :: Foreign -> Except (NonEmptyList ForeignError) Point -readPoint value = do - x <- value ! "x" >>= readNumber - y <- value ! "y" >>= readNumber - pure $ Point { x: x, y: y } - -main :: Effect Unit -main = do - - -- When trying to parse invalid JSON we catch an exception from - -- `JSON.parse` and pass it on. - logShow $ runExcept $ - readString =<< foreignValue "not even JSON" - - -- When attempting to coerce one type to another we get an error. - logShow $ runExcept $ - readBoolean =<< foreignValue "26" - - -- When parsing fails in an array, we're told at which index the value that - -- failed to parse was, along with the reason the value didn't parse. - logShow $ runExcept $ - traverse readBoolean =<< readArray =<< foreignValue "[1, true, 3]" - - -- When parsing fails in an object, we're the name of the property which - -- failed to parse was, along with the reason the value didn't parse. - logShow $ runExcept $ - readPoint =<< foreignValue """{ "x": 1, "y": false }""" diff --git a/foreign/examples/SimpleTypes.purs b/foreign/examples/SimpleTypes.purs deleted file mode 100644 index e3ba48c4..00000000 --- a/foreign/examples/SimpleTypes.purs +++ /dev/null @@ -1,20 +0,0 @@ -module Example.SimpleTypes where - -import Prelude - -import Control.Monad.Except (runExcept) -import Effect (Effect) -import Effect.Console (logShow) -import Example.Util.Value (foreignValue) -import Foreign (readString, readNumber, readBoolean) - --- Parsing of the simple JSON String, Number and Boolean types is provided --- out of the box. -main :: Effect Unit -main = do - logShow $ runExcept $ - readString =<< foreignValue "\"a JSON string\"" - logShow $ runExcept $ - readNumber =<< foreignValue "42" - logShow $ runExcept $ - readBoolean =<< foreignValue "true" diff --git a/foreign/examples/Union.purs b/foreign/examples/Union.purs deleted file mode 100755 index feee5d15..00000000 --- a/foreign/examples/Union.purs +++ /dev/null @@ -1,59 +0,0 @@ -module Example.Union where - -import Prelude - -import Control.Monad.Except (Except, runExcept) -import Data.List.NonEmpty (NonEmptyList) -import Effect (Effect) -import Effect.Console (logShow) -import Example.Util.Value (foreignValue) -import Foreign (Foreign, ForeignError, readBoolean, readString) -import Foreign.Index ((!)) - -data StringList = Nil | Cons String StringList - -instance showStringList :: Show StringList where - show Nil = "Nil" - show (Cons s l) = "(Cons " <> show s <> " " <> show l <> ")" - -readStringList :: Foreign -> Except (NonEmptyList ForeignError) StringList -readStringList value = - value ! "nil" >>= - readBoolean >>= - if _ - then pure Nil - else - Cons - <$> (value ! "head" >>= readString) - <*> (value ! "tail" >>= readStringList) - -main :: Effect Unit -main = do - - logShow $ runExcept $ - readStringList =<< foreignValue - """ - { "nil": false - , "head": "Hello" - , "tail": - { "nil": false - , "head": "World" - , "tail": - { "nil": true } - } - } - """ - - logShow $ runExcept $ - readStringList =<< foreignValue - """ - { "nil": false - , "head": "Hello" - , "tail": - { "nil": false - , "head": 0 - , "tail": - { "nil": true } - } - } - """ diff --git a/foreign/examples/Util/Value.js b/foreign/examples/Util/Value.js deleted file mode 100644 index 7edc6edc..00000000 --- a/foreign/examples/Util/Value.js +++ /dev/null @@ -1,7 +0,0 @@ -export const foreignValueImpl = function (left, right, str) { - try { - return right(JSON.parse(str)); - } catch (e) { - return left(e.toString()); - } -}; diff --git a/foreign/examples/Util/Value.purs b/foreign/examples/Util/Value.purs deleted file mode 100644 index f70cc40c..00000000 --- a/foreign/examples/Util/Value.purs +++ /dev/null @@ -1,14 +0,0 @@ -module Example.Util.Value where - -import Prelude - -import Control.Monad.Except (Except) -import Data.Function.Uncurried (Fn3, runFn3) -import Data.List.NonEmpty (NonEmptyList) - -import Foreign (Foreign, ForeignError(..), fail) - -foreign import foreignValueImpl :: forall r. Fn3 (String -> r) (Foreign -> r) String r - -foreignValue :: String -> Except (NonEmptyList ForeignError) Foreign -foreignValue json = runFn3 foreignValueImpl (fail <<< ForeignError) pure json diff --git a/foreign/package.json b/foreign/package.json deleted file mode 100644 index 2353ab54..00000000 --- a/foreign/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "private": true, - "scripts": { - "clean": "rimraf output && rimraf .pulp-cache", - "build": "eslint src && pulp build -- --censor-lib --strict", - "test": "pulp build -I examples -- --censor-lib --strict" - }, - "devDependencies": { - "eslint": "^7.15.0", - "pulp": "16.0.0-0", - "purescript-psa": "^0.8.2", - "rimraf": "^3.0.2" - } -} diff --git a/foreign/src/Foreign.js b/foreign/src/Foreign.js deleted file mode 100644 index fdea3eec..00000000 --- a/foreign/src/Foreign.js +++ /dev/null @@ -1,19 +0,0 @@ -export function typeOf(value) { - return typeof value; -} - -export function tagOf(value) { - return Object.prototype.toString.call(value).slice(8, -1); -} - -export function isNull(value) { - return value === null; -} - -export function isUndefined(value) { - return value === undefined; -} - -export const isArray = Array.isArray || function (value) { - return Object.prototype.toString.call(value) === "[object Array]"; -}; diff --git a/foreign/src/Foreign.purs b/foreign/src/Foreign.purs deleted file mode 100644 index e655e254..00000000 --- a/foreign/src/Foreign.purs +++ /dev/null @@ -1,186 +0,0 @@ --- | This module defines types and functions for working with _foreign_ --- | data. --- | --- | `ExceptT (NonEmptyList ForeignError) m` is used in this library --- | to encode possible failures when dealing with foreign data. --- | --- | The `Alt` instance for `ExceptT` allows us to accumulate errors, --- | unlike `Either`, which preserves only the last error. -module Foreign - ( Foreign - , ForeignError(..) - , MultipleErrors(..) - , F - , FT - , renderForeignError - , unsafeToForeign - , unsafeFromForeign - , unsafeReadTagged - , typeOf - , tagOf - , isNull - , isUndefined - , isArray - , readString - , readChar - , readBoolean - , readNumber - , readInt - , readArray - , readNull - , readUndefined - , readNullOrUndefined - , fail - ) where - -import Prelude - -import Control.Monad.Except (Except, ExceptT, mapExceptT, throwError) -import Data.Either (Either(..), either) -import Data.Int as Int -import Data.List.NonEmpty (NonEmptyList) -import Data.List.NonEmpty as NEL -import Data.Maybe (Maybe(..), maybe) -import Data.String.CodeUnits (toChar) -import Unsafe.Coerce (unsafeCoerce) - --- | A type for _foreign data_. --- | --- | Foreign data is data from any external _unknown_ or _unreliable_ --- | source, for which it cannot be guaranteed that the runtime representation --- | conforms to that of any particular type. --- | --- | Suitable applications of `Foreign` are --- | --- | - To represent responses from web services --- | - To integrate with external JavaScript libraries. -foreign import data Foreign :: Type - --- | A type for foreign type errors -data ForeignError - = ForeignError String - | TypeMismatch String String - | ErrorAtIndex Int ForeignError - | ErrorAtProperty String ForeignError - -derive instance eqForeignError :: Eq ForeignError -derive instance ordForeignError :: Ord ForeignError - -instance showForeignError :: Show ForeignError where - show (ForeignError msg) = "(ForeignError " <> show msg <> ")" - show (ErrorAtIndex i e) = "(ErrorAtIndex " <> show i <> " " <> show e <> ")" - show (ErrorAtProperty prop e) = "(ErrorAtProperty " <> show prop <> " " <> show e <> ")" - show (TypeMismatch exps act) = "(TypeMismatch " <> show exps <> " " <> show act <> ")" - --- | A type for accumulating multiple `ForeignError`s. -type MultipleErrors = NonEmptyList ForeignError - -renderForeignError :: ForeignError -> String -renderForeignError (ForeignError msg) = msg -renderForeignError (ErrorAtIndex i e) = "Error at array index " <> show i <> ": " <> renderForeignError e -renderForeignError (ErrorAtProperty prop e) = "Error at property " <> show prop <> ": " <> renderForeignError e -renderForeignError (TypeMismatch exp act) = "Type mismatch: expected " <> exp <> ", found " <> act - --- | While this alias is not deprecated, it is recommended --- | that one use `Except (NonEmptyList ForeignError)` directly --- | for all future usages rather than this type alias. --- | --- | An error monad, used in this library to encode possible failures when --- | dealing with foreign data. --- | --- | The `Alt` instance for `Except` allows us to accumulate errors, --- | unlike `Either`, which preserves only the last error. -type F = Except MultipleErrors - --- | While this alias is not deprecated, it is recommended --- | that one use `ExceptT (NonEmptyList ForeignError)` directly --- | for all future usages rather than this type alias. -type FT = ExceptT MultipleErrors - --- | Coerce any value to the a `Foreign` value. --- | --- | This is considered unsafe as it's only intended to be used on primitive --- | JavaScript types, rather than PureScript types. Exporting PureScript values --- | via the FFI can be dangerous as they can be mutated by code outside the --- | PureScript program, resulting in difficult to diagnose problems elsewhere. -unsafeToForeign :: forall a. a -> Foreign -unsafeToForeign = unsafeCoerce - --- | Unsafely coerce a `Foreign` value. -unsafeFromForeign :: forall a. Foreign -> a -unsafeFromForeign = unsafeCoerce - --- | Read the Javascript _type_ of a value -foreign import typeOf :: Foreign -> String - --- | Read the Javascript _tag_ of a value. --- | --- | This function wraps the `Object.toString` method. -foreign import tagOf :: Foreign -> String - --- | Unsafely coerce a `Foreign` value when the value has a particular `tagOf` --- | value. -unsafeReadTagged :: forall m a. Monad m => String -> Foreign -> ExceptT (NonEmptyList ForeignError) m a -unsafeReadTagged tag value - | tagOf value == tag = pure (unsafeFromForeign value) - | otherwise = fail $ TypeMismatch tag (tagOf value) - --- | Test whether a foreign value is null -foreign import isNull :: Foreign -> Boolean - --- | Test whether a foreign value is undefined -foreign import isUndefined :: Foreign -> Boolean - --- | Test whether a foreign value is an array -foreign import isArray :: Foreign -> Boolean - --- | Attempt to coerce a foreign value to a `String`. -readString :: forall m. Monad m => Foreign -> ExceptT (NonEmptyList ForeignError) m String -readString = unsafeReadTagged "String" - --- | Attempt to coerce a foreign value to a `Char`. -readChar :: forall m. Monad m => Foreign -> ExceptT (NonEmptyList ForeignError) m Char -readChar value = mapExceptT (map $ either (const error) fromString) (readString value) - where - fromString = maybe error pure <<< toChar - error = Left $ NEL.singleton $ TypeMismatch "Char" (tagOf value) - --- | Attempt to coerce a foreign value to a `Boolean`. -readBoolean :: forall m. Monad m => Foreign -> ExceptT (NonEmptyList ForeignError) m Boolean -readBoolean = unsafeReadTagged "Boolean" - --- | Attempt to coerce a foreign value to a `Number`. -readNumber :: forall m. Monad m => Foreign -> ExceptT (NonEmptyList ForeignError) m Number -readNumber = unsafeReadTagged "Number" - --- | Attempt to coerce a foreign value to an `Int`. -readInt :: forall m. Monad m => Foreign -> ExceptT (NonEmptyList ForeignError) m Int -readInt value = mapExceptT (map $ either (const error) fromNumber) (readNumber value) - where - fromNumber = maybe error pure <<< Int.fromNumber - error = Left $ NEL.singleton $ TypeMismatch "Int" (tagOf value) - --- | Attempt to coerce a foreign value to an array. -readArray :: forall m. Monad m => Foreign -> ExceptT (NonEmptyList ForeignError) m (Array Foreign) -readArray value - | isArray value = pure $ unsafeFromForeign value - | otherwise = fail $ TypeMismatch "array" (tagOf value) - -readNull :: forall m. Monad m => Foreign -> ExceptT (NonEmptyList ForeignError) m (Maybe Foreign) -readNull value - | isNull value = pure Nothing - | otherwise = pure (Just value) - -readUndefined :: forall m. Monad m => Foreign -> ExceptT (NonEmptyList ForeignError) m (Maybe Foreign) -readUndefined value - | isUndefined value = pure Nothing - | otherwise = pure (Just value) - -readNullOrUndefined :: forall m. Monad m => Foreign -> ExceptT (NonEmptyList ForeignError) m (Maybe Foreign) -readNullOrUndefined value - | isNull value || isUndefined value = pure Nothing - | otherwise = pure (Just value) - --- | Throws a failure error in `ExceptT (NonEmptyList ForeignError) m`. -fail :: forall m a. Monad m => ForeignError -> ExceptT (NonEmptyList ForeignError) m a -fail = throwError <<< NEL.singleton diff --git a/foreign/src/Foreign/Index.js b/foreign/src/Foreign/Index.js deleted file mode 100644 index 3b077e56..00000000 --- a/foreign/src/Foreign/Index.js +++ /dev/null @@ -1,11 +0,0 @@ -export function unsafeReadPropImpl(f, s, key, value) { - return value == null ? f : s(value[key]); -} - -export function unsafeHasOwnProperty(prop, value) { - return Object.prototype.hasOwnProperty.call(value, prop); -} - -export function unsafeHasProperty(prop, value) { - return prop in value; -} diff --git a/foreign/src/Foreign/Index.purs b/foreign/src/Foreign/Index.purs deleted file mode 100644 index 994db834..00000000 --- a/foreign/src/Foreign/Index.purs +++ /dev/null @@ -1,84 +0,0 @@ --- | This module defines a type class for types which act like --- | _property indices_. - -module Foreign.Index - ( class Index - , class Indexable - , readProp - , readIndex - , ix, (!) - , index - , hasProperty - , hasOwnProperty - , errorAt - ) where - -import Prelude - -import Control.Monad.Except.Trans (ExceptT) - -import Foreign (Foreign, ForeignError(..), typeOf, isUndefined, isNull, fail) -import Data.Function.Uncurried (Fn2, runFn2, Fn4, runFn4) -import Data.List.NonEmpty (NonEmptyList) - --- | This type class identifies types that act like _property indices_. --- | --- | The canonical instances are for `String`s and `Int`s. -class Index i m | i -> m where - index :: Foreign -> i -> ExceptT (NonEmptyList ForeignError) m Foreign - hasProperty :: i -> Foreign -> Boolean - hasOwnProperty :: i -> Foreign -> Boolean - errorAt :: i -> ForeignError -> ForeignError - -class Indexable a m | a -> m where - ix :: forall i. Index i m => a -> i -> ExceptT (NonEmptyList ForeignError) m Foreign - -infixl 9 ix as ! - -foreign import unsafeReadPropImpl :: forall r k. Fn4 r (Foreign -> r) k Foreign r - -unsafeReadProp :: forall k m. Monad m => k -> Foreign -> ExceptT (NonEmptyList ForeignError) m Foreign -unsafeReadProp k value = - runFn4 unsafeReadPropImpl (fail (TypeMismatch "object" (typeOf value))) pure k value - --- | Attempt to read a value from a foreign value property -readProp :: forall m. Monad m => String -> Foreign -> ExceptT (NonEmptyList ForeignError) m Foreign -readProp = unsafeReadProp - --- | Attempt to read a value from a foreign value at the specified numeric index -readIndex :: forall m. Monad m => Int -> Foreign -> ExceptT (NonEmptyList ForeignError) m Foreign -readIndex = unsafeReadProp - -foreign import unsafeHasOwnProperty :: forall k. Fn2 k Foreign Boolean - -hasOwnPropertyImpl :: forall k. k -> Foreign -> Boolean -hasOwnPropertyImpl _ value | isNull value = false -hasOwnPropertyImpl _ value | isUndefined value = false -hasOwnPropertyImpl p value | typeOf value == "object" || typeOf value == "function" = runFn2 unsafeHasOwnProperty p value -hasOwnPropertyImpl _ _ = false - -foreign import unsafeHasProperty :: forall k. Fn2 k Foreign Boolean - -hasPropertyImpl :: forall k. k -> Foreign -> Boolean -hasPropertyImpl _ value | isNull value = false -hasPropertyImpl _ value | isUndefined value = false -hasPropertyImpl p value | typeOf value == "object" || typeOf value == "function" = runFn2 unsafeHasProperty p value -hasPropertyImpl _ _ = false - -instance indexString :: Monad m => Index String m where - index = flip readProp - hasProperty = hasPropertyImpl - hasOwnProperty = hasOwnPropertyImpl - errorAt = ErrorAtProperty - -instance indexInt :: Monad m => Index Int m where - index = flip readIndex - hasProperty = hasPropertyImpl - hasOwnProperty = hasOwnPropertyImpl - errorAt = ErrorAtIndex - -instance indexableForeign :: Monad m => Indexable Foreign m where - ix = index - -instance indexableExceptT :: Monad m => Indexable (ExceptT (NonEmptyList ForeignError) m Foreign) m where - ix f i = flip index i =<< f diff --git a/foreign/src/Foreign/Keys.js b/foreign/src/Foreign/Keys.js deleted file mode 100644 index f5b8f0c6..00000000 --- a/foreign/src/Foreign/Keys.js +++ /dev/null @@ -1,9 +0,0 @@ -export const unsafeKeys = Object.keys || function (value) { - var keys = []; - for (var prop in value) { - if (Object.prototype.hasOwnProperty.call(value, prop)) { - keys.push(prop); - } - } - return keys; -}; diff --git a/foreign/src/Foreign/Keys.purs b/foreign/src/Foreign/Keys.purs deleted file mode 100644 index bca65952..00000000 --- a/foreign/src/Foreign/Keys.purs +++ /dev/null @@ -1,22 +0,0 @@ --- | This module provides functions for working with object properties --- | of Javascript objects. - -module Foreign.Keys - ( keys - ) where - -import Prelude - -import Foreign (Foreign, ForeignError(..), typeOf, isUndefined, isNull, fail) -import Control.Monad.Except (ExceptT) -import Data.List.NonEmpty (NonEmptyList) - -foreign import unsafeKeys :: Foreign -> Array String - --- | Get an array of the properties defined on a foreign value -keys :: forall m. Monad m => Foreign -> ExceptT (NonEmptyList ForeignError) m (Array String) -keys value - | isNull value = fail $ TypeMismatch "object" "null" - | isUndefined value = fail $ TypeMismatch "object" "undefined" - | typeOf value == "object" = pure $ unsafeKeys value - | otherwise = fail $ TypeMismatch "object" (typeOf value)