diff --git a/CHANGELOG.md b/CHANGELOG.md index ecc03af..129621e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Haskell Package Versioning Policy](https://pvp.haskell.org/). ## [Unreleased] +## Changed +- `Test.Hspec.GraphQL.*`: replace `IO` in the resolver with any `MonadCatch`. ## [0.9.0.0] - 2020-07-24 ## Fixed diff --git a/README.md b/README.md index 917da40..065645a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ -# Haskell GraphQL +# GraphQL implementation in Haskell. [![Hackage Version](https://img.shields.io/hackage/v/graphql.svg)](https://hackage.haskell.org/package/graphql) [![Build Status](https://github.com/caraus-ecms/graphql/workflows/Haskell%20CI/badge.svg)](https://github.com/caraus-ecms/graphql/actions?query=workflow%3A%22Haskell+CI%22) [![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](https://raw.githubusercontent.com/caraus-ecms/graphql/master/LICENSE) - -GraphQL implementation in Haskell. +[![Simple Haskell](https://www.simplehaskell.org/badges/badge.svg)](https://www.simplehaskell.org) This implementation is relatively low-level by design, it doesn't provide any mappings between the GraphQL types and Haskell's type system and avoids @@ -13,12 +12,19 @@ be built on top of it. ## State of the work -For now this only provides a parser and a printer for the GraphQL query language -and allows to execute queries and mutations using the given schema, but without -the validation step. But the idea is to be a Haskell port of +For now this library provides: + +- Parser for the query and schema languages, as well as a printer for the query + language (minimizer and pretty-printer). +- Data structures to define a type system. +- Executor (queries, mutations and subscriptions are supported). +- Validation is work in progress. +- Introspection isn't available yet. + +But the idea is to be a Haskell port of [`graphql-js`](https://github.com/graphql/graphql-js). -For the list of currently missing features see issues marked as +For a more precise list of currently missing features see issues marked as "[not implemented](https://github.com/caraus-ecms/graphql/labels/not%20implemented)". ## Documentation diff --git a/graphql.cabal b/graphql.cabal index 6ac951a..73e71e7 100644 --- a/graphql.cabal +++ b/graphql.cabal @@ -4,7 +4,7 @@ cabal-version: 1.12 -- -- see: https://github.com/sol/hpack -- --- hash: 5fa34f11ab1242b72c75c3c19b31ba310c24716a0eb2d134d2b17dd558280732 +-- hash: 1d8c32c00a882ccd1fefc4c083d5fe4e83a1825fbf8e0dcfd551ff2c8cd2dda0 name: graphql version: 0.9.0.0 @@ -24,12 +24,10 @@ license-file: LICENSE build-type: Simple extra-source-files: CHANGELOG.md - README.md + CONTRIBUTING.md LICENSE + README.md docs/tutorial/tutorial.lhs -data-files: - tests/data/kitchen-sink.graphql - tests/data/kitchen-sink.min.graphql source-repository head type: git @@ -91,7 +89,6 @@ test-suite tasty Language.GraphQL.ValidateSpec Test.DirectiveSpec Test.FragmentSpec - Test.KitchenSinkSpec Test.RootOperationSpec Test.StarWars.Data Test.StarWars.QuerySpec diff --git a/package.yaml b/package.yaml index dcdc6c8..b7098ee 100644 --- a/package.yaml +++ b/package.yaml @@ -17,14 +17,11 @@ author: extra-source-files: - CHANGELOG.md -- README.md +- CONTRIBUTING.md - LICENSE +- README.md - docs/tutorial/tutorial.lhs -data-files: -- tests/data/*.graphql -- tests/data/*.min.graphql - dependencies: - aeson - base >= 4.7 && < 5 diff --git a/src/Language/GraphQL/AST.hs b/src/Language/GraphQL/AST.hs index 3d368d4..c7ceee8 100644 --- a/src/Language/GraphQL/AST.hs +++ b/src/Language/GraphQL/AST.hs @@ -1,3 +1,7 @@ +{- This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. -} + -- | Target AST for parser. module Language.GraphQL.AST ( module Language.GraphQL.AST.Document diff --git a/src/Language/GraphQL/AST/DirectiveLocation.hs b/src/Language/GraphQL/AST/DirectiveLocation.hs index 5b7a36f..c38c9ff 100644 --- a/src/Language/GraphQL/AST/DirectiveLocation.hs +++ b/src/Language/GraphQL/AST/DirectiveLocation.hs @@ -1,5 +1,9 @@ +{- This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. -} + -- | Various parts of a GraphQL document can be annotated with directives. --- This module describes locations in a document where directives can appear. +-- This module describes locations in a document where directives can appear. module Language.GraphQL.AST.DirectiveLocation ( DirectiveLocation(..) , ExecutableDirectiveLocation(..) @@ -7,8 +11,8 @@ module Language.GraphQL.AST.DirectiveLocation ) where -- | All directives can be splitted in two groups: directives used to annotate --- various parts of executable definitions and the ones used in the schema --- definition. +-- various parts of executable definitions and the ones used in the schema +-- definition. data DirectiveLocation = ExecutableDirectiveLocation ExecutableDirectiveLocation | TypeSystemDirectiveLocation TypeSystemDirectiveLocation diff --git a/src/Language/GraphQL/Execute/Coerce.hs b/src/Language/GraphQL/Execute/Coerce.hs index 60fb71d..08a2fc0 100644 --- a/src/Language/GraphQL/Execute/Coerce.hs +++ b/src/Language/GraphQL/Execute/Coerce.hs @@ -1,3 +1,7 @@ +{- This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. -} + {-# LANGUAGE ExplicitForAll #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} diff --git a/src/Language/GraphQL/Type/In.hs b/src/Language/GraphQL/Type/In.hs index 36e0e2c..8b08041 100644 --- a/src/Language/GraphQL/Type/In.hs +++ b/src/Language/GraphQL/Type/In.hs @@ -1,3 +1,7 @@ +{- This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. -} + {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE ViewPatterns #-} diff --git a/src/Language/GraphQL/Type/Schema.hs b/src/Language/GraphQL/Type/Schema.hs index c5cc6fd..581d9b2 100644 --- a/src/Language/GraphQL/Type/Schema.hs +++ b/src/Language/GraphQL/Type/Schema.hs @@ -1,3 +1,7 @@ +{- This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. -} + -- | This module provides a representation of a @GraphQL@ Schema in addition to -- functions for defining and manipulating schemas. module Language.GraphQL.Type.Schema diff --git a/src/Language/GraphQL/Validate/Rules.hs b/src/Language/GraphQL/Validate/Rules.hs index a3314e7..9faaedd 100644 --- a/src/Language/GraphQL/Validate/Rules.hs +++ b/src/Language/GraphQL/Validate/Rules.hs @@ -17,7 +17,7 @@ import Language.GraphQL.AST.Document newtype Rule = DefinitionRule (Definition -> Maybe String) --- | Default reules given in the specification. +-- | Default rules given in the specification. specifiedRules :: [Rule] specifiedRules = [ executableDefinitionsRule diff --git a/tests/Language/GraphQL/ErrorSpec.hs b/tests/Language/GraphQL/ErrorSpec.hs index 482dc3a..1497c48 100644 --- a/tests/Language/GraphQL/ErrorSpec.hs +++ b/tests/Language/GraphQL/ErrorSpec.hs @@ -1,3 +1,7 @@ +{- This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. -} + {-# LANGUAGE OverloadedStrings #-} module Language.GraphQL.ErrorSpec ( spec diff --git a/tests/Language/GraphQL/Execute/CoerceSpec.hs b/tests/Language/GraphQL/Execute/CoerceSpec.hs index 339c2e3..2b00895 100644 --- a/tests/Language/GraphQL/Execute/CoerceSpec.hs +++ b/tests/Language/GraphQL/Execute/CoerceSpec.hs @@ -1,3 +1,7 @@ +{- This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. -} + {-# LANGUAGE OverloadedStrings #-} module Language.GraphQL.Execute.CoerceSpec ( spec diff --git a/tests/Language/GraphQL/Type/OutSpec.hs b/tests/Language/GraphQL/Type/OutSpec.hs index eecc374..733763d 100644 --- a/tests/Language/GraphQL/Type/OutSpec.hs +++ b/tests/Language/GraphQL/Type/OutSpec.hs @@ -1,3 +1,7 @@ +{- This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. -} + {-# LANGUAGE OverloadedStrings #-} module Language.GraphQL.Type.OutSpec ( spec diff --git a/tests/Test/KitchenSinkSpec.hs b/tests/Test/KitchenSinkSpec.hs deleted file mode 100644 index 9f5a947..0000000 --- a/tests/Test/KitchenSinkSpec.hs +++ /dev/null @@ -1,69 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE QuasiQuotes #-} -module Test.KitchenSinkSpec - ( spec - ) where - -import qualified Data.Text.IO as Text.IO -import qualified Data.Text.Lazy.IO as Text.Lazy.IO -import qualified Data.Text.Lazy as Lazy (Text) -import qualified Language.GraphQL.AST.Encoder as Encoder -import qualified Language.GraphQL.AST.Parser as Parser -import Paths_graphql (getDataFileName) -import Test.Hspec (Spec, describe, it) -import Test.Hspec.Megaparsec (parseSatisfies) -import Text.Megaparsec (parse) -import Text.RawString.QQ (r) - -spec :: Spec -spec = describe "Kitchen Sink" $ do - it "minifies the query" $ do - dataFileName <- getDataFileName "tests/data/kitchen-sink.graphql" - minFileName <- getDataFileName "tests/data/kitchen-sink.min.graphql" - expected <- Text.Lazy.IO.readFile minFileName - - shouldNormalize Encoder.minified dataFileName expected - - it "pretty prints the query" $ do - dataFileName <- getDataFileName "tests/data/kitchen-sink.graphql" - let expected = [r|query queryName($foo: ComplexType, $site: Site = MOBILE) { - whoever123is: node(id: [123, 456]) { - id - ... on User @defer { - field2 { - id - alias: field1(first: 10, after: $foo) @include(if: $foo) { - id - ...frag - } - } - } - } -} - -mutation likeStory { - like(story: 123) @defer { - story { - id - } - } -} - -fragment frag on Friend { - foo(size: $size, bar: $b, obj: {key: "value"}) -} - -{ - unnamed(truthy: true, falsey: false) - query -} -|] - - shouldNormalize Encoder.pretty dataFileName expected - -shouldNormalize :: Encoder.Formatter -> FilePath -> Lazy.Text -> IO () -shouldNormalize formatter dataFileName expected = do - actual <- Text.IO.readFile dataFileName - parse Parser.document dataFileName actual `parseSatisfies` condition - where - condition = (expected ==) . Encoder.document formatter diff --git a/tests/data/kitchen-sink.graphql b/tests/data/kitchen-sink.graphql deleted file mode 100644 index 89903b7..0000000 --- a/tests/data/kitchen-sink.graphql +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2015, Facebook, Inc. -# All rights reserved. -# -# This source code is licensed under the BSD-style license found in the -# LICENSE file in the root directory of this source tree. An additional grant -# of patent rights can be found in the PATENTS file in the same directory. - -query queryName($foo: ComplexType, $site: Site = MOBILE) { - whoever123is: node(id: [123, 456]) { - id, # Inline test comment - ... on User @defer { - field2 { - id, - alias: field1(first: 10, after: $foo) @include(if: $foo) { - id, - ...frag - } - } - } - } -} - -mutation likeStory { - like(story: 123) @defer { - story { - id - } - } -} - -fragment frag on Friend { - foo(size: $size, bar: $b, obj: {key: "value"}) -} - -{ - unnamed(truthy: true, falsey: false), - query -} diff --git a/tests/data/kitchen-sink.min.graphql b/tests/data/kitchen-sink.min.graphql deleted file mode 100644 index 24f5c26..0000000 --- a/tests/data/kitchen-sink.min.graphql +++ /dev/null @@ -1 +0,0 @@ -query queryName($foo:ComplexType,$site:Site=MOBILE){whoever123is:node(id:[123,456]){id,... on User@defer{field2{id,alias:field1(first:10,after:$foo)@include(if:$foo){id,...frag}}}}}mutation likeStory{like(story:123)@defer{story{id}}}fragment frag on Friend{foo(size:$size,bar:$b,obj:{key:"value"})}{unnamed(truthy:true,falsey:false),query}