mirror of
https://github.com/rowtype-yoga/purescript-graphql-fundeps.git
synced 2024-11-22 11:22:52 +03:00
Initial commit
This commit is contained in:
commit
92258eb6b2
1315
package-lock.json
generated
Normal file
1315
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
package.json
Normal file
18
package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "purescript-graphql-fundeps",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"postinstall": "spago install && spago build",
|
||||
"test": "spago test"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"purescript": "^0.14.1",
|
||||
"spago": "^0.20.3",
|
||||
"xhr2": "^0.2.1"
|
||||
}
|
||||
}
|
104
packages.dhall
Normal file
104
packages.dhall
Normal file
@ -0,0 +1,104 @@
|
||||
{-
|
||||
Welcome to your new Dhall package-set!
|
||||
|
||||
Below are instructions for how to edit this file for most use
|
||||
cases, so that you don't need to know Dhall to use it.
|
||||
|
||||
## Use Cases
|
||||
|
||||
Most will want to do one or both of these options:
|
||||
1. Override/Patch a package's dependency
|
||||
2. Add a package not already in the default package set
|
||||
|
||||
This file will continue to work whether you use one or both options.
|
||||
Instructions for each option are explained below.
|
||||
|
||||
### Overriding/Patching a package
|
||||
|
||||
Purpose:
|
||||
- Change a package's dependency to a newer/older release than the
|
||||
default package set's release
|
||||
- Use your own modified version of some dependency that may
|
||||
include new API, changed API, removed API by
|
||||
using your custom git repo of the library rather than
|
||||
the package set's repo
|
||||
|
||||
Syntax:
|
||||
where `entityName` is one of the following:
|
||||
- dependencies
|
||||
- repo
|
||||
- version
|
||||
-------------------------------
|
||||
let upstream = --
|
||||
in upstream
|
||||
with packageName.entityName = "new value"
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let upstream = --
|
||||
in upstream
|
||||
with halogen.version = "master"
|
||||
with halogen.repo = "https://example.com/path/to/git/repo.git"
|
||||
|
||||
with halogen-vdom.version = "v4.0.0"
|
||||
with halogen-vdom.dependencies = [ "extra-dependency" ] # halogen-vdom.dependencies
|
||||
-------------------------------
|
||||
|
||||
### Additions
|
||||
|
||||
Purpose:
|
||||
- Add packages that aren't already included in the default package set
|
||||
|
||||
Syntax:
|
||||
where `<version>` is:
|
||||
- a tag (i.e. "v4.0.0")
|
||||
- a branch (i.e. "master")
|
||||
- commit hash (i.e. "701f3e44aafb1a6459281714858fadf2c4c2a977")
|
||||
-------------------------------
|
||||
let upstream = --
|
||||
in upstream
|
||||
with new-package-name =
|
||||
{ dependencies =
|
||||
[ "dependency1"
|
||||
, "dependency2"
|
||||
]
|
||||
, repo =
|
||||
"https://example.com/path/to/git/repo.git"
|
||||
, version =
|
||||
"<version>"
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let upstream = --
|
||||
in upstream
|
||||
with benchotron =
|
||||
{ dependencies =
|
||||
[ "arrays"
|
||||
, "exists"
|
||||
, "profunctor"
|
||||
, "strings"
|
||||
, "quickcheck"
|
||||
, "lcg"
|
||||
, "transformers"
|
||||
, "foldable-traversable"
|
||||
, "exceptions"
|
||||
, "node-fs"
|
||||
, "node-buffer"
|
||||
, "node-readline"
|
||||
, "datetime"
|
||||
, "now"
|
||||
]
|
||||
, repo =
|
||||
"https://github.com/hdgarrood/purescript-benchotron.git"
|
||||
, version =
|
||||
"v7.0.0"
|
||||
}
|
||||
-------------------------------
|
||||
-}
|
||||
let upstream =
|
||||
https://github.com/purescript/package-sets/releases/download/psc-0.14.1-20210516/packages.dhall sha256:f5e978371d4cdc4b916add9011021509c8d869f4c3f6d0d2694c0e03a85046c8
|
||||
|
||||
in upstream
|
30
spago.dhall
Normal file
30
spago.dhall
Normal file
@ -0,0 +1,30 @@
|
||||
{-
|
||||
Welcome to a Spago project!
|
||||
You can edit this file as you like.
|
||||
|
||||
Need help? See the following resources:
|
||||
- Spago documentation: https://github.com/purescript/spago
|
||||
- Dhall language tour: https://docs.dhall-lang.org/tutorials/Language-Tour.html
|
||||
|
||||
When creating a new Spago project, you can use
|
||||
`spago init --no-comments` or `spago init -C`
|
||||
to generate this file without the comments in this block.
|
||||
-}
|
||||
{ name = "my-project"
|
||||
, dependencies =
|
||||
[ "aff"
|
||||
, "affjax"
|
||||
, "console"
|
||||
, "effect"
|
||||
, "either"
|
||||
, "http-methods"
|
||||
, "maybe"
|
||||
, "media-types"
|
||||
, "prelude"
|
||||
, "psci-support"
|
||||
, "simple-json"
|
||||
, "strings"
|
||||
]
|
||||
, packages = ./packages.dhall
|
||||
, sources = [ "src/**/*.purs" ]
|
||||
}
|
62
src/GraphQL.purs
Normal file
62
src/GraphQL.purs
Normal file
@ -0,0 +1,62 @@
|
||||
module GraphQL.FunDeps where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Affjax as AX
|
||||
import Affjax.RequestBody as RequestBody
|
||||
import Affjax.RequestHeader (RequestHeader(..))
|
||||
import Affjax.ResponseFormat as ResponseFormat
|
||||
import Data.Either (Either(..))
|
||||
import Data.HTTP.Method (Method(..))
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.MediaType (MediaType(..))
|
||||
import Data.String as String
|
||||
import Data.Symbol (class IsSymbol, reflectSymbol)
|
||||
import Effect.Aff (Aff, error, throwError)
|
||||
import Effect.Class (liftEffect)
|
||||
import Effect.Class.Console as Log
|
||||
import Simple.JSON as JSON
|
||||
import Type.Proxy (Proxy(..))
|
||||
|
||||
data GraphQL
|
||||
|
||||
data Gql (operation :: GraphQL)
|
||||
= Gql
|
||||
|
||||
class GraphQLReqRes (operation :: GraphQL) (gql :: Symbol) (i :: Row Type) (o :: Row Type) | operation -> gql i o
|
||||
|
||||
type Endpoint = String
|
||||
|
||||
type GraphQLClient' (operation :: GraphQL) (gql :: Symbol) (i :: Row Type) (o :: Row Type) = GraphQLReqRes operation gql i o => IsSymbol gql => JSON.WriteForeign { | i } => JSON.ReadForeign { | o } => Gql operation -> Record i -> Aff { | o }
|
||||
|
||||
type GraphQLClient = forall (operation :: GraphQL) (gql :: Symbol) (i :: Row Type) (o :: Row Type). GraphQLClient' operation gql i o
|
||||
|
||||
graphQL :: Endpoint -> Array RequestHeader -> (forall (operation :: GraphQL) (gql :: Symbol) (i :: Row Type) (o :: Row Type). GraphQLReqRes operation gql i o => IsSymbol gql => JSON.WriteForeign { | i } => JSON.ReadForeign { | o } => Gql operation -> Record i -> Aff { | o })
|
||||
graphQL endpoint headers = go
|
||||
where
|
||||
go :: forall (operation :: GraphQL) (gql :: Symbol) (i :: Row Type) (o :: Row Type). GraphQLReqRes operation gql i o => IsSymbol gql => JSON.WriteForeign { | i } => JSON.ReadForeign { | o } => Gql operation -> Record i -> Aff { | o }
|
||||
go _ variables = do
|
||||
let
|
||||
input =
|
||||
{ variables
|
||||
, query: String.replaceAll (String.Pattern "\n") (String.Replacement " ") (String.replaceAll (String.Pattern "\r\n") (String.Replacement " ") (reflectSymbol (Proxy :: Proxy gql)))
|
||||
}
|
||||
res <-
|
||||
AX.request
|
||||
( AX.defaultRequest
|
||||
{ url = endpoint
|
||||
, method = Left POST
|
||||
, responseFormat = ResponseFormat.string
|
||||
, content =
|
||||
Just
|
||||
(RequestBody.string (JSON.writeJSON input))
|
||||
, headers = headers <> [ContentType $ MediaType "application/json"]
|
||||
}
|
||||
)
|
||||
case res of
|
||||
Left err -> do
|
||||
liftEffect $ Log.info "Request did not go through"
|
||||
throwError (error $ AX.printError err)
|
||||
Right response -> case (JSON.readJSON response.body) of
|
||||
Left err1 -> throwError (error $ ("Got an error " <> show response.body <> " err " <> show err1 <> " using input " <> (JSON.writeJSON input)))
|
||||
Right ({ data: d } :: { data :: { | o } }) -> pure d
|
6
test.dhall
Normal file
6
test.dhall
Normal file
@ -0,0 +1,6 @@
|
||||
let conf = ./spago.dhall
|
||||
|
||||
in conf // {
|
||||
sources = conf.sources # [ "test/**/*.purs" ],
|
||||
dependencies = conf.dependencies # [ "spec", "foldable-traversable" ]
|
||||
}
|
69
test/Main.purs
Normal file
69
test/Main.purs
Normal file
@ -0,0 +1,69 @@
|
||||
module Test.Main where
|
||||
|
||||
import Prelude
|
||||
import Data.Foldable (for_)
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Effect (Effect)
|
||||
import Effect.Aff (Milliseconds(..), launchAff_)
|
||||
import Effect.Class.Console as Log
|
||||
import GraphQL.FunDeps (class GraphQLReqRes, Gql(..), GraphQL, GraphQLClient, graphQL)
|
||||
import Test.Spec (describe, it)
|
||||
import Test.Spec.Reporter.Console (consoleReporter)
|
||||
import Test.Spec.Runner (defaultConfig, runSpec')
|
||||
|
||||
endpoint = "https://api.react-finland.fi/graphql" :: String
|
||||
|
||||
foreign import data ReactFinlandConferences :: GraphQL
|
||||
|
||||
instance graphqlReactFinlandConferences ::
|
||||
GraphQLReqRes ReactFinlandConferences """query {
|
||||
conferences {
|
||||
name
|
||||
id
|
||||
}
|
||||
}
|
||||
""" () ( conferences :: Array { name :: String, id :: String } )
|
||||
|
||||
foreign import data ReactFinlandConference :: GraphQL
|
||||
|
||||
instance graphqlReactFinlandConference ::
|
||||
GraphQLReqRes ReactFinlandConference """query($id:ID!) {
|
||||
conference(id:$id) {
|
||||
year
|
||||
websiteUrl
|
||||
speakers {
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
}
|
||||
}
|
||||
""" ( id :: String ) ( conference ::
|
||||
{ year :: String
|
||||
, websiteUrl :: String
|
||||
, speakers ::
|
||||
Array
|
||||
{ firstName :: String
|
||||
, lastName :: String
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
client :: GraphQLClient
|
||||
client = graphQL "https://api.react-finland.fi/graphql" []
|
||||
|
||||
main ∷ Effect Unit
|
||||
main =
|
||||
launchAff_
|
||||
$ runSpec'
|
||||
( defaultConfig
|
||||
{ timeout = Just (Milliseconds 10000.0)
|
||||
}
|
||||
)
|
||||
[ consoleReporter ] do
|
||||
describe "GraphQL Fundeps" do
|
||||
it "Works" do
|
||||
{ conferences } <- client (Gql :: Gql ReactFinlandConferences) {}
|
||||
for_ conferences \{ id } -> do
|
||||
{ conference: { websiteUrl, speakers } } <- client (Gql :: Gql ReactFinlandConference) { id }
|
||||
Log.info websiteUrl
|
||||
Log.info $ show speakers
|
Loading…
Reference in New Issue
Block a user