From d156e2ff5490ec8b2d54981f42b435fe3472eef3 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 18:12:11 +0100 Subject: [PATCH 01/83] Add temporary type to example. --- examples/src/GithubPagination.elm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 4e706a855..a6dad6f46 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -33,6 +33,25 @@ type alias Paginator dataType cursorType = } + +-- first query -> No Cursor, just count (first or last) +-- Result comes back -> Get a cursor, maintain the count +-- second query, Cursor, no count (use from previous) + + +type PaginationContinuation cursor + = Forward { first : Int } { after : cursor } + | Backward { last : Int } { before : cursor } + + +paginationArguments : Maybe String -> Query.SearchOptionalArguments -> Query.SearchOptionalArguments +paginationArguments maybeCursor optionals = + { optionals + | first = Present 1 + , after = OptionalArgument.fromMaybe maybeCursor + } + + query : Maybe String -> SelectionSet Response RootQuery query cursor = Query.search From ad8895b13b000873a918fe6eccba36fa4e65b572 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 18:29:52 +0100 Subject: [PATCH 02/83] Use paginationArguments helper. --- examples/src/GithubPagination.elm | 36 ++++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index a6dad6f46..e7395ac52 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -37,30 +37,36 @@ type alias Paginator dataType cursorType = -- first query -> No Cursor, just count (first or last) -- Result comes back -> Get a cursor, maintain the count -- second query, Cursor, no count (use from previous) +-- type PaginationContinuation cursor +-- = Forward { first : Int } { after : cursor } +-- | Backward { last : Int } { before : cursor } -type PaginationContinuation cursor - = Forward { first : Int } { after : cursor } - | Backward { last : Int } { before : cursor } +type PaginationSetup + = Forward { first : Int } + | Backward { last : Int } -paginationArguments : Maybe String -> Query.SearchOptionalArguments -> Query.SearchOptionalArguments -paginationArguments maybeCursor optionals = - { optionals - | first = Present 1 - , after = OptionalArgument.fromMaybe maybeCursor - } +paginationArguments : Maybe String -> PaginationSetup -> Query.SearchOptionalArguments -> Query.SearchOptionalArguments +paginationArguments maybeCursor paginationSetup optionals = + case paginationSetup of + Forward { first } -> + { optionals + | first = Present first + , after = OptionalArgument.fromMaybe maybeCursor + } + + Backward { last } -> + { optionals + | last = Present last + , before = OptionalArgument.fromMaybe maybeCursor + } query : Maybe String -> SelectionSet Response RootQuery query cursor = Query.search - (\optionals -> - { optionals - | first = Present 1 - , after = OptionalArgument.fromMaybe cursor - } - ) + (paginationArguments cursor (Forward { first = 1 })) { query = "language:Elm" , type_ = Github.Enum.SearchType.Repository } From 2f8a5bab07f9ee61736a241f25b297794f0bff06 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 19:14:57 +0100 Subject: [PATCH 03/83] Add example paginator to generated code as prototype. --- examples/src/Github/Object/PageInfo.elm | 14 ++++++++- examples/src/GithubPagination.elm | 40 +++++++++++-------------- src/Graphql/PaginatorSetup.elm | 17 +++++++++++ 3 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 src/Graphql/PaginatorSetup.elm diff --git a/examples/src/Github/Object/PageInfo.elm b/examples/src/Github/Object/PageInfo.elm index 412fa10f1..506824aac 100644 --- a/examples/src/Github/Object/PageInfo.elm +++ b/examples/src/Github/Object/PageInfo.elm @@ -2,7 +2,7 @@ -- https://github.com/dillonkearns/elm-graphql -module Github.Object.PageInfo exposing (endCursor, hasNextPage, hasPreviousPage, startCursor) +module Github.Object.PageInfo exposing (endCursor, fromSetup, hasNextPage, hasPreviousPage, startCursor) import Github.InputObject import Github.Interface @@ -15,10 +15,22 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.PaginatorSetup exposing (CurrentPage, PaginatorSetup(..)) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode +fromSetup : PaginatorSetup -> SelectionSet (CurrentPage String) Github.Object.PageInfo +fromSetup paginatorSetup = + Graphql.SelectionSet.map2 CurrentPage + endCursor + hasNextPage + + + +-- SelectionSet.empty + + {-| When paginating forwards, the cursor to continue. -} endCursor : SelectionSet (Maybe String) Github.Object.PageInfo diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index e7395ac52..a51cafb47 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -16,6 +16,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) +import Graphql.PaginatorSetup exposing (CurrentPage, PaginatorSetup(..)) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, p, pre, text) import Html.Events exposing (onClick) @@ -29,7 +30,7 @@ type alias Response = type alias Paginator dataType cursorType = { data : dataType - , paginationData : PaginationData cursorType + , paginationData : CurrentPage cursorType } @@ -42,12 +43,7 @@ type alias Paginator dataType cursorType = -- | Backward { last : Int } { before : cursor } -type PaginationSetup - = Forward { first : Int } - | Backward { last : Int } - - -paginationArguments : Maybe String -> PaginationSetup -> Query.SearchOptionalArguments -> Query.SearchOptionalArguments +paginationArguments : Maybe String -> PaginatorSetup -> Query.SearchOptionalArguments -> Query.SearchOptionalArguments paginationArguments maybeCursor paginationSetup optionals = case paginationSetup of Forward { first } -> @@ -70,27 +66,27 @@ query cursor = { query = "language:Elm" , type_ = Github.Enum.SearchType.Repository } - searchSelection + (SelectionSet.map2 Paginator + searchResultFieldEdges + (Github.Object.SearchResultItemConnection.pageInfo + (Github.Object.PageInfo.fromSetup (Forward { first = 1 })) + ) + ) searchSelection : SelectionSet Response Github.Object.SearchResultItemConnection searchSelection = - SelectionSet.succeed Paginator - |> with searchResultFieldEdges - |> with (Github.Object.SearchResultItemConnection.pageInfo searchPageInfoSelection) - - -type alias PaginationData cursorType = - { cursor : Maybe cursorType - , hasNextPage : Bool - } + SelectionSet.map2 Paginator + searchResultFieldEdges + (Github.Object.SearchResultItemConnection.pageInfo searchPageInfoSelection) -searchPageInfoSelection : SelectionSet (PaginationData String) Github.Object.PageInfo +searchPageInfoSelection : SelectionSet (CurrentPage String) Github.Object.PageInfo searchPageInfoSelection = - SelectionSet.succeed PaginationData - |> with Github.Object.PageInfo.endCursor - |> with Github.Object.PageInfo.hasNextPage + -- SelectionSet.succeed PaginationData + -- |> with Github.Object.PageInfo.endCursor + -- |> with Github.Object.PageInfo.hasNextPage + Github.Object.PageInfo.fromSetup (Forward { first = 1 }) searchResultFieldNodes : SelectionSet (List Repo) Github.Object.SearchResultItemConnection @@ -188,7 +184,7 @@ update msg model = GetNextPage -> case model of (RemoteData.Success successResponse) :: rest -> - if successResponse.paginationData.hasNextPage then + if successResponse.paginationData.done then ( RemoteData.Loading :: model, makeRequest successResponse.paginationData.cursor ) else diff --git a/src/Graphql/PaginatorSetup.elm b/src/Graphql/PaginatorSetup.elm new file mode 100644 index 000000000..34056e6e6 --- /dev/null +++ b/src/Graphql/PaginatorSetup.elm @@ -0,0 +1,17 @@ +module Graphql.PaginatorSetup exposing (CurrentPage, PaginatorSetup(..)) + +{-| TODO +-} + + +{-| Uses [the relay protocol](https://facebook.github.io/relay/graphql/connections.htm). +-} +type PaginatorSetup + = Forward { first : Int } + | Backward { last : Int } + + +type alias CurrentPage cursorType = + { cursor : Maybe cursorType + , done : Bool + } From 000411cf185bfba6b44ba4c572e07d546adef559 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 19:23:17 +0100 Subject: [PATCH 04/83] Clean up example. --- examples/src/GithubPagination.elm | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index a51cafb47..f91290fce 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -61,42 +61,23 @@ paginationArguments maybeCursor paginationSetup optionals = query : Maybe String -> SelectionSet Response RootQuery query cursor = + let + setup = + Forward { first = 1 } + in Query.search - (paginationArguments cursor (Forward { first = 1 })) + (paginationArguments cursor setup) { query = "language:Elm" , type_ = Github.Enum.SearchType.Repository } (SelectionSet.map2 Paginator searchResultFieldEdges (Github.Object.SearchResultItemConnection.pageInfo - (Github.Object.PageInfo.fromSetup (Forward { first = 1 })) + (Github.Object.PageInfo.fromSetup setup) ) ) -searchSelection : SelectionSet Response Github.Object.SearchResultItemConnection -searchSelection = - SelectionSet.map2 Paginator - searchResultFieldEdges - (Github.Object.SearchResultItemConnection.pageInfo searchPageInfoSelection) - - -searchPageInfoSelection : SelectionSet (CurrentPage String) Github.Object.PageInfo -searchPageInfoSelection = - -- SelectionSet.succeed PaginationData - -- |> with Github.Object.PageInfo.endCursor - -- |> with Github.Object.PageInfo.hasNextPage - Github.Object.PageInfo.fromSetup (Forward { first = 1 }) - - -searchResultFieldNodes : SelectionSet (List Repo) Github.Object.SearchResultItemConnection -searchResultFieldNodes = - Github.Object.SearchResultItemConnection.nodes searchResultSelection - |> SelectionSet.nonNullOrFail - |> SelectionSet.nonNullElementsOrFail - |> SelectionSet.nonNullElementsOrFail - - searchResultFieldEdges : SelectionSet (List Repo) Github.Object.SearchResultItemConnection searchResultFieldEdges = Github.Object.SearchResultItemConnection.edges From 28d166a8533642c3898a534e1119a52e07f175cb Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 19:42:23 +0100 Subject: [PATCH 05/83] Add helper function for paginated searches. --- examples/src/Github/Query.elm | 14 +++++++++++++- examples/src/GithubPagination.elm | 19 +++++++++++++++++++ src/Graphql/PaginatorSetup.elm | 28 +++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index 4cbcc41e7..ff5eeb73a 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -2,7 +2,7 @@ -- https://github.com/dillonkearns/elm-graphql -module Github.Query exposing (CodeOfConductRequiredArguments, LicenseRequiredArguments, MarketplaceCategoriesOptionalArguments, MarketplaceCategoryRequiredArguments, MarketplaceListingRequiredArguments, MarketplaceListingsOptionalArguments, NodeRequiredArguments, NodesRequiredArguments, OrganizationRequiredArguments, RateLimitOptionalArguments, RepositoryOwnerRequiredArguments, RepositoryRequiredArguments, ResourceRequiredArguments, SearchOptionalArguments, SearchRequiredArguments, TopicRequiredArguments, UserRequiredArguments, codeOfConduct, codesOfConduct, license, licenses, marketplaceCategories, marketplaceCategory, marketplaceListing, marketplaceListings, meta, node, nodes, organization, rateLimit, relay, repository, repositoryOwner, resource, search, topic, user, viewer) +module Github.Query exposing (CodeOfConductRequiredArguments, LicenseRequiredArguments, MarketplaceCategoriesOptionalArguments, MarketplaceCategoryRequiredArguments, MarketplaceListingRequiredArguments, MarketplaceListingsOptionalArguments, NodeRequiredArguments, NodesRequiredArguments, OrganizationRequiredArguments, RateLimitOptionalArguments, RepositoryOwnerRequiredArguments, RepositoryRequiredArguments, ResourceRequiredArguments, SearchOptionalArguments, SearchRequiredArguments, TopicRequiredArguments, UserRequiredArguments, codeOfConduct, codesOfConduct, license, licenses, marketplaceCategories, marketplaceCategory, marketplaceListing, marketplaceListings, meta, node, nodes, organization, rateLimit, relay, repository, repositoryOwner, resource, search, searchPaginated, topic, user, viewer) import Github.Enum.SearchType import Github.InputObject @@ -16,6 +16,7 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, PaginatorSetup(..)) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode exposing (Decoder) @@ -330,6 +331,17 @@ search fillInOptionals requiredArgs object_ = Object.selectionForCompositeField "search" (optionalArgs ++ [ Argument.required "query" requiredArgs.query Encode.string, Argument.required "type" requiredArgs.type_ (Encode.enum Github.Enum.SearchType.toString) ]) object_ identity +searchPaginated : + Maybe String + -> PaginatorSetup + -> (SearchOptionalArguments -> SearchOptionalArguments) + -> SearchRequiredArguments + -> SelectionSet decodesTo Github.Object.SearchResultItemConnection + -> SelectionSet decodesTo RootQuery +searchPaginated cursor paginatorSetup fillInOptionals = + search (fillInOptionals >> PaginatorSetup.addPageInfo cursor paginatorSetup) + + type alias TopicRequiredArguments = { name : String } diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index f91290fce..a109bd11d 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -78,6 +78,25 @@ query cursor = ) +newThing cursor = + let + setup = + Forward { first = 1 } + in + Query.searchPaginated cursor + setup + identity + { query = "language:Elm" + , type_ = Github.Enum.SearchType.Repository + } + (SelectionSet.map2 Paginator + searchResultFieldEdges + (Github.Object.SearchResultItemConnection.pageInfo + (Github.Object.PageInfo.fromSetup setup) + ) + ) + + searchResultFieldEdges : SelectionSet (List Repo) Github.Object.SearchResultItemConnection searchResultFieldEdges = Github.Object.SearchResultItemConnection.edges diff --git a/src/Graphql/PaginatorSetup.elm b/src/Graphql/PaginatorSetup.elm index 34056e6e6..df79d96dc 100644 --- a/src/Graphql/PaginatorSetup.elm +++ b/src/Graphql/PaginatorSetup.elm @@ -1,7 +1,33 @@ -module Graphql.PaginatorSetup exposing (CurrentPage, PaginatorSetup(..)) +module Graphql.PaginatorSetup exposing (CurrentPage, PageInfo, PaginatorSetup(..), addPageInfo) + +import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) + + +type alias PageInfo pageInfo cursor = + { pageInfo + | first : OptionalArgument Int + , last : OptionalArgument Int + , before : OptionalArgument cursor + , after : OptionalArgument cursor + } + {-| TODO -} +addPageInfo : Maybe cursor -> PaginatorSetup -> PageInfo pageInfo cursor -> PageInfo pageInfo cursor +addPageInfo maybeCursor paginationSetup optionals = + case paginationSetup of + Forward { first } -> + { optionals + | first = Present first + , after = OptionalArgument.fromMaybe maybeCursor + } + + Backward { last } -> + { optionals + | last = Present last + , before = OptionalArgument.fromMaybe maybeCursor + } {-| Uses [the relay protocol](https://facebook.github.io/relay/graphql/connections.htm). From 767f0b93a1d5275860cc18e726c1f2ee567a37b5 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 19:45:47 +0100 Subject: [PATCH 06/83] Move type into library. --- examples/src/Github/Query.elm | 12 ++++++++++-- examples/src/GithubPagination.elm | 18 ++++++------------ src/Graphql/PaginatorSetup.elm | 8 +++++++- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index ff5eeb73a..e379804ed 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -338,8 +338,16 @@ searchPaginated : -> SearchRequiredArguments -> SelectionSet decodesTo Github.Object.SearchResultItemConnection -> SelectionSet decodesTo RootQuery -searchPaginated cursor paginatorSetup fillInOptionals = - search (fillInOptionals >> PaginatorSetup.addPageInfo cursor paginatorSetup) +searchPaginated cursor paginatorSetup fillInOptionals requiredArgs object_ = + -- let + -- foo = + -- Graphql.SelectionSet.map2 Paginator + -- searchResultFieldEdges + -- (Github.Object.SearchResultItemConnection.pageInfo + -- (Github.Object.PageInfo.fromSetup setup) + -- ) + -- in + search (fillInOptionals >> PaginatorSetup.addPageInfo cursor paginatorSetup) requiredArgs object_ type alias TopicRequiredArguments = diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index a109bd11d..4294682b3 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -16,7 +16,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup exposing (CurrentPage, PaginatorSetup(..)) +import Graphql.PaginatorSetup exposing (CurrentPage, PaginatedData, PaginatorSetup(..)) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, p, pre, text) import Html.Events exposing (onClick) @@ -25,13 +25,7 @@ import RemoteData exposing (RemoteData) type alias Response = - Paginator (List Repo) String - - -type alias Paginator dataType cursorType = - { data : dataType - , paginationData : CurrentPage cursorType - } + PaginatedData (List Repo) String @@ -70,7 +64,7 @@ query cursor = { query = "language:Elm" , type_ = Github.Enum.SearchType.Repository } - (SelectionSet.map2 Paginator + (SelectionSet.map2 PaginatedData searchResultFieldEdges (Github.Object.SearchResultItemConnection.pageInfo (Github.Object.PageInfo.fromSetup setup) @@ -89,7 +83,7 @@ newThing cursor = { query = "language:Elm" , type_ = Github.Enum.SearchType.Repository } - (SelectionSet.map2 Paginator + (SelectionSet.map2 PaginatedData searchResultFieldEdges (Github.Object.SearchResultItemConnection.pageInfo (Github.Object.PageInfo.fromSetup setup) @@ -184,8 +178,8 @@ update msg model = GetNextPage -> case model of (RemoteData.Success successResponse) :: rest -> - if successResponse.paginationData.done then - ( RemoteData.Loading :: model, makeRequest successResponse.paginationData.cursor ) + if successResponse.currentPage.done then + ( RemoteData.Loading :: model, makeRequest successResponse.currentPage.cursor ) else ( model, Cmd.none ) diff --git a/src/Graphql/PaginatorSetup.elm b/src/Graphql/PaginatorSetup.elm index df79d96dc..5161a43ea 100644 --- a/src/Graphql/PaginatorSetup.elm +++ b/src/Graphql/PaginatorSetup.elm @@ -1,8 +1,14 @@ -module Graphql.PaginatorSetup exposing (CurrentPage, PageInfo, PaginatorSetup(..), addPageInfo) +module Graphql.PaginatorSetup exposing (CurrentPage, PageInfo, PaginatedData, PaginatorSetup(..), addPageInfo) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) +type alias PaginatedData data cursor = + { data : data + , currentPage : CurrentPage cursor + } + + type alias PageInfo pageInfo cursor = { pageInfo | first : OptionalArgument Int From a70f45a404fc7f616205efea11c365ea2d4b7673 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 19:50:52 +0100 Subject: [PATCH 07/83] Reverse list in example. --- examples/src/GithubPagination.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 4294682b3..e7b26c760 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -167,7 +167,7 @@ view model = , div [] [ button [ onClick GetNextPage ] [ text "Load next page..." ] ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view model + , PrintAny.view (model |> List.reverse) ] ] From 17e15455fc832acaff0bd204ccf2334a6ea22efe Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 20:02:27 +0100 Subject: [PATCH 08/83] Include page info in helper function. --- examples/src/Github/Query.elm | 13 +++++++-- examples/src/GithubPagination.elm | 25 +---------------- src/Graphql/Internal/Paginator.elm | 45 ++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 src/Graphql/Internal/Paginator.elm diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index e379804ed..be9a72b0d 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -14,9 +14,10 @@ import Github.Union import Graphql.Internal.Builder.Argument as Argument exposing (Argument) import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) +import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, PaginatorSetup(..)) +import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, PaginatedData, PaginatorSetup(..)) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode exposing (Decoder) @@ -337,7 +338,7 @@ searchPaginated : -> (SearchOptionalArguments -> SearchOptionalArguments) -> SearchRequiredArguments -> SelectionSet decodesTo Github.Object.SearchResultItemConnection - -> SelectionSet decodesTo RootQuery + -> SelectionSet (PaginatedData decodesTo String) RootQuery searchPaginated cursor paginatorSetup fillInOptionals requiredArgs object_ = -- let -- foo = @@ -347,7 +348,13 @@ searchPaginated cursor paginatorSetup fillInOptionals requiredArgs object_ = -- (Github.Object.PageInfo.fromSetup setup) -- ) -- in - search (fillInOptionals >> PaginatorSetup.addPageInfo cursor paginatorSetup) requiredArgs object_ + search (fillInOptionals >> PaginatorSetup.addPageInfo cursor paginatorSetup) + requiredArgs + (Graphql.SelectionSet.map2 PaginatedData + object_ + -- (Github.Object.SearchResultItemConnection.pageInfo (Github.Object.PageInfo.fromSetup setup)) + (Graphql.Internal.Paginator.fromSetup paginatorSetup) + ) type alias TopicRequiredArguments = diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index e7b26c760..f0b8b7d69 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -55,24 +55,6 @@ paginationArguments maybeCursor paginationSetup optionals = query : Maybe String -> SelectionSet Response RootQuery query cursor = - let - setup = - Forward { first = 1 } - in - Query.search - (paginationArguments cursor setup) - { query = "language:Elm" - , type_ = Github.Enum.SearchType.Repository - } - (SelectionSet.map2 PaginatedData - searchResultFieldEdges - (Github.Object.SearchResultItemConnection.pageInfo - (Github.Object.PageInfo.fromSetup setup) - ) - ) - - -newThing cursor = let setup = Forward { first = 1 } @@ -83,12 +65,7 @@ newThing cursor = { query = "language:Elm" , type_ = Github.Enum.SearchType.Repository } - (SelectionSet.map2 PaginatedData - searchResultFieldEdges - (Github.Object.SearchResultItemConnection.pageInfo - (Github.Object.PageInfo.fromSetup setup) - ) - ) + searchResultFieldEdges searchResultFieldEdges : SelectionSet (List Repo) Github.Object.SearchResultItemConnection diff --git a/src/Graphql/Internal/Paginator.elm b/src/Graphql/Internal/Paginator.elm new file mode 100644 index 000000000..0e5decb41 --- /dev/null +++ b/src/Graphql/Internal/Paginator.elm @@ -0,0 +1,45 @@ +module Graphql.Internal.Paginator exposing (fromSetup) + +import Graphql.Internal.Builder.Argument as Argument exposing (Argument) +import Graphql.Internal.Builder.Object as Object +import Graphql.Internal.Encode as Encode exposing (Value) +import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) +import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.PaginatorSetup exposing (CurrentPage, PaginatorSetup(..)) +import Graphql.SelectionSet exposing (SelectionSet) +import Json.Decode as Decode + + +fromSetup : PaginatorSetup -> SelectionSet (CurrentPage String) pageInfo +fromSetup paginatorSetup = + Graphql.SelectionSet.map2 CurrentPage + endCursor + hasNextPage + + +{-| When paginating forwards, the cursor to continue. +-} +endCursor : SelectionSet (Maybe String) pageInfo +endCursor = + Object.selectionForField "(Maybe String)" "endCursor" [] (Decode.string |> Decode.nullable) + + +{-| When paginating forwards, are there more items? +-} +hasNextPage : SelectionSet Bool pageInfo +hasNextPage = + Object.selectionForField "Bool" "hasNextPage" [] Decode.bool + + +{-| When paginating backwards, are there more items? +-} +hasPreviousPage : SelectionSet Bool pageInfo +hasPreviousPage = + Object.selectionForField "Bool" "hasPreviousPage" [] Decode.bool + + +{-| When paginating backwards, the cursor to continue. +-} +startCursor : SelectionSet (Maybe String) pageInfo +startCursor = + Object.selectionForField "(Maybe String)" "startCursor" [] (Decode.string |> Decode.nullable) From 1db867f1f62b5bf3f881f53435d1f5e4bb359263 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 20:03:19 +0100 Subject: [PATCH 09/83] Change formatting. --- examples/src/GithubPagination.elm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index f0b8b7d69..5f94370e7 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -62,9 +62,7 @@ query cursor = Query.searchPaginated cursor setup identity - { query = "language:Elm" - , type_ = Github.Enum.SearchType.Repository - } + { query = "language:Elm", type_ = Github.Enum.SearchType.Repository } searchResultFieldEdges From 6a3b6cd7d71495af3e7c00ec619d54ee285cb841 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 20:04:56 +0100 Subject: [PATCH 10/83] Remove unused code. --- examples/src/GithubPagination.elm | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 5f94370e7..0b655690e 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -32,25 +32,6 @@ type alias Response = -- first query -> No Cursor, just count (first or last) -- Result comes back -> Get a cursor, maintain the count -- second query, Cursor, no count (use from previous) --- type PaginationContinuation cursor --- = Forward { first : Int } { after : cursor } --- | Backward { last : Int } { before : cursor } - - -paginationArguments : Maybe String -> PaginatorSetup -> Query.SearchOptionalArguments -> Query.SearchOptionalArguments -paginationArguments maybeCursor paginationSetup optionals = - case paginationSetup of - Forward { first } -> - { optionals - | first = Present first - , after = OptionalArgument.fromMaybe maybeCursor - } - - Backward { last } -> - { optionals - | last = Present last - , before = OptionalArgument.fromMaybe maybeCursor - } query : Maybe String -> SelectionSet Response RootQuery From 4f36802d393b88423e96c889a8166de521992e1a Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 20:21:06 +0100 Subject: [PATCH 11/83] Assume list for PaginatedData type. --- examples/src/Github/Query.elm | 11 +---------- examples/src/GithubPagination.elm | 2 +- src/Graphql/PaginatorSetup.elm | 2 +- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index be9a72b0d..3f0131f6e 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -337,22 +337,13 @@ searchPaginated : -> PaginatorSetup -> (SearchOptionalArguments -> SearchOptionalArguments) -> SearchRequiredArguments - -> SelectionSet decodesTo Github.Object.SearchResultItemConnection + -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection -> SelectionSet (PaginatedData decodesTo String) RootQuery searchPaginated cursor paginatorSetup fillInOptionals requiredArgs object_ = - -- let - -- foo = - -- Graphql.SelectionSet.map2 Paginator - -- searchResultFieldEdges - -- (Github.Object.SearchResultItemConnection.pageInfo - -- (Github.Object.PageInfo.fromSetup setup) - -- ) - -- in search (fillInOptionals >> PaginatorSetup.addPageInfo cursor paginatorSetup) requiredArgs (Graphql.SelectionSet.map2 PaginatedData object_ - -- (Github.Object.SearchResultItemConnection.pageInfo (Github.Object.PageInfo.fromSetup setup)) (Graphql.Internal.Paginator.fromSetup paginatorSetup) ) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 0b655690e..b4d376177 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -25,7 +25,7 @@ import RemoteData exposing (RemoteData) type alias Response = - PaginatedData (List Repo) String + PaginatedData Repo String diff --git a/src/Graphql/PaginatorSetup.elm b/src/Graphql/PaginatorSetup.elm index 5161a43ea..79d1d2dcd 100644 --- a/src/Graphql/PaginatorSetup.elm +++ b/src/Graphql/PaginatorSetup.elm @@ -4,7 +4,7 @@ import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(. type alias PaginatedData data cursor = - { data : data + { data : List data , currentPage : CurrentPage cursor } From 2321f1dede449cc030ad8e2c7ff2667202deaa55 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 20:25:47 +0100 Subject: [PATCH 12/83] Include pagination setup in data type. --- examples/src/Github/Query.elm | 3 ++- src/Graphql/PaginatorSetup.elm | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index 3f0131f6e..db52b3dc9 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -342,9 +342,10 @@ searchPaginated : searchPaginated cursor paginatorSetup fillInOptionals requiredArgs object_ = search (fillInOptionals >> PaginatorSetup.addPageInfo cursor paginatorSetup) requiredArgs - (Graphql.SelectionSet.map2 PaginatedData + (Graphql.SelectionSet.map3 PaginatedData object_ (Graphql.Internal.Paginator.fromSetup paginatorSetup) + (Graphql.SelectionSet.succeed paginatorSetup) ) diff --git a/src/Graphql/PaginatorSetup.elm b/src/Graphql/PaginatorSetup.elm index 79d1d2dcd..78f4d987c 100644 --- a/src/Graphql/PaginatorSetup.elm +++ b/src/Graphql/PaginatorSetup.elm @@ -6,6 +6,7 @@ import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(. type alias PaginatedData data cursor = { data : List data , currentPage : CurrentPage cursor + , setup : PaginatorSetup } From 6d7c7aa4d2b511a81002f2adaaeb17cdc510498c Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 22:01:48 +0100 Subject: [PATCH 13/83] Store pagination data in model. --- examples/src/GithubPagination.elm | 17 +++++++++-------- src/Graphql/PaginatorSetup.elm | 10 +++++++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index b4d376177..e7a5f7835 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -16,7 +16,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup exposing (CurrentPage, PaginatedData, PaginatorSetup(..)) +import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, PaginatedData, PaginatorSetup(..)) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, p, pre, text) import Html.Events exposing (onClick) @@ -101,7 +101,8 @@ type Msg type alias Model = - List RemoteDataResponse + -- List RemoteDataResponse + PaginatedData RemoteDataResponse String type alias RemoteDataResponse = @@ -110,7 +111,7 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = - ( [ RemoteData.Loading ], makeRequest Nothing ) + ( PaginatorSetup.init (Forward { first = 1 }) [ RemoteData.Loading ], makeRequest Nothing ) view : Model -> Html.Html Msg @@ -123,7 +124,7 @@ view model = , div [] [ button [ onClick GetNextPage ] [ text "Load next page..." ] ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view (model |> List.reverse) + , PrintAny.view (model.data |> List.reverse) ] ] @@ -132,10 +133,10 @@ update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of GetNextPage -> - case model of + case model.data of (RemoteData.Success successResponse) :: rest -> if successResponse.currentPage.done then - ( RemoteData.Loading :: model, makeRequest successResponse.currentPage.cursor ) + ( { model | data = RemoteData.Loading :: model.data }, makeRequest successResponse.currentPage.cursor ) else ( model, Cmd.none ) @@ -144,9 +145,9 @@ update msg model = ( model, Cmd.none ) GotResponse response -> - case model of + case model.data of head :: rest -> - ( response :: rest, Cmd.none ) + ( { model | data = response :: rest }, Cmd.none ) _ -> ( model, Cmd.none ) diff --git a/src/Graphql/PaginatorSetup.elm b/src/Graphql/PaginatorSetup.elm index 78f4d987c..59b8b9258 100644 --- a/src/Graphql/PaginatorSetup.elm +++ b/src/Graphql/PaginatorSetup.elm @@ -1,8 +1,16 @@ -module Graphql.PaginatorSetup exposing (CurrentPage, PageInfo, PaginatedData, PaginatorSetup(..), addPageInfo) +module Graphql.PaginatorSetup exposing (CurrentPage, PageInfo, PaginatedData, PaginatorSetup(..), addPageInfo, init) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) +init : PaginatorSetup -> List data -> PaginatedData data cursor +init paginatorSetup initialData = + { data = initialData + , currentPage = { cursor = Nothing, done = False } + , setup = paginatorSetup + } + + type alias PaginatedData data cursor = { data : List data , currentPage : CurrentPage cursor From 5f337b73218a774135ef26dee4604fa962b8914e Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 22:03:43 +0100 Subject: [PATCH 14/83] Rename type. --- examples/src/Github/Object/PageInfo.elm | 4 ++-- examples/src/Github/Query.elm | 4 ++-- examples/src/GithubPagination.elm | 2 +- src/Graphql/Internal/Paginator.elm | 4 ++-- src/Graphql/PaginatorSetup.elm | 10 +++++----- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/src/Github/Object/PageInfo.elm b/examples/src/Github/Object/PageInfo.elm index 506824aac..b0ce1368d 100644 --- a/examples/src/Github/Object/PageInfo.elm +++ b/examples/src/Github/Object/PageInfo.elm @@ -15,12 +15,12 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup exposing (CurrentPage, PaginatorSetup(..)) +import Graphql.PaginatorSetup exposing (CurrentPage, Direction(..)) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode -fromSetup : PaginatorSetup -> SelectionSet (CurrentPage String) Github.Object.PageInfo +fromSetup : Direction -> SelectionSet (CurrentPage String) Github.Object.PageInfo fromSetup paginatorSetup = Graphql.SelectionSet.map2 CurrentPage endCursor diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index db52b3dc9..6e1e635eb 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -17,7 +17,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, PaginatedData, PaginatorSetup(..)) +import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode exposing (Decoder) @@ -334,7 +334,7 @@ search fillInOptionals requiredArgs object_ = searchPaginated : Maybe String - -> PaginatorSetup + -> Direction -> (SearchOptionalArguments -> SearchOptionalArguments) -> SearchRequiredArguments -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index e7a5f7835..c15ca7256 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -16,7 +16,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, PaginatedData, PaginatorSetup(..)) +import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, p, pre, text) import Html.Events exposing (onClick) diff --git a/src/Graphql/Internal/Paginator.elm b/src/Graphql/Internal/Paginator.elm index 0e5decb41..58b27ce73 100644 --- a/src/Graphql/Internal/Paginator.elm +++ b/src/Graphql/Internal/Paginator.elm @@ -5,12 +5,12 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup exposing (CurrentPage, PaginatorSetup(..)) +import Graphql.PaginatorSetup exposing (CurrentPage, Direction(..)) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode -fromSetup : PaginatorSetup -> SelectionSet (CurrentPage String) pageInfo +fromSetup : Direction -> SelectionSet (CurrentPage String) pageInfo fromSetup paginatorSetup = Graphql.SelectionSet.map2 CurrentPage endCursor diff --git a/src/Graphql/PaginatorSetup.elm b/src/Graphql/PaginatorSetup.elm index 59b8b9258..f4e682eaa 100644 --- a/src/Graphql/PaginatorSetup.elm +++ b/src/Graphql/PaginatorSetup.elm @@ -1,9 +1,9 @@ -module Graphql.PaginatorSetup exposing (CurrentPage, PageInfo, PaginatedData, PaginatorSetup(..), addPageInfo, init) +module Graphql.PaginatorSetup exposing (CurrentPage, Direction(..), PageInfo, PaginatedData, addPageInfo, init) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -init : PaginatorSetup -> List data -> PaginatedData data cursor +init : Direction -> List data -> PaginatedData data cursor init paginatorSetup initialData = { data = initialData , currentPage = { cursor = Nothing, done = False } @@ -14,7 +14,7 @@ init paginatorSetup initialData = type alias PaginatedData data cursor = { data : List data , currentPage : CurrentPage cursor - , setup : PaginatorSetup + , setup : Direction } @@ -29,7 +29,7 @@ type alias PageInfo pageInfo cursor = {-| TODO -} -addPageInfo : Maybe cursor -> PaginatorSetup -> PageInfo pageInfo cursor -> PageInfo pageInfo cursor +addPageInfo : Maybe cursor -> Direction -> PageInfo pageInfo cursor -> PageInfo pageInfo cursor addPageInfo maybeCursor paginationSetup optionals = case paginationSetup of Forward { first } -> @@ -47,7 +47,7 @@ addPageInfo maybeCursor paginationSetup optionals = {-| Uses [the relay protocol](https://facebook.github.io/relay/graphql/connections.htm). -} -type PaginatorSetup +type Direction = Forward { first : Int } | Backward { last : Int } From e69887807d6096e6868b99987bb386dd84f904f5 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 22:40:03 +0100 Subject: [PATCH 15/83] Fix issue in paginator. --- src/Graphql/Internal/Paginator.elm | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Graphql/Internal/Paginator.elm b/src/Graphql/Internal/Paginator.elm index 58b27ce73..f1773ac6c 100644 --- a/src/Graphql/Internal/Paginator.elm +++ b/src/Graphql/Internal/Paginator.elm @@ -10,11 +10,15 @@ import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode -fromSetup : Direction -> SelectionSet (CurrentPage String) pageInfo +fromSetup : Direction -> SelectionSet (CurrentPage String) connection fromSetup paginatorSetup = - Graphql.SelectionSet.map2 CurrentPage - endCursor - hasNextPage + let + object_ = + Graphql.SelectionSet.map2 CurrentPage + endCursor + hasNextPage + in + Object.selectionForCompositeField "pageInfo" [] object_ identity {-| When paginating forwards, the cursor to continue. From 6dabfd0653738dccc52f0023bbad327d8354eee7 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 22:40:17 +0100 Subject: [PATCH 16/83] Update pagination code. --- examples/src/Github/Query.elm | 7 ++++--- examples/src/GithubPagination.elm | 32 ++++++++++++++++++++----------- src/Graphql/PaginatorSetup.elm | 20 +++++++++---------- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index 6e1e635eb..f1a4c68f7 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -333,14 +333,15 @@ search fillInOptionals requiredArgs object_ = searchPaginated : - Maybe String + Int + -> Maybe String -> Direction -> (SearchOptionalArguments -> SearchOptionalArguments) -> SearchRequiredArguments -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection -> SelectionSet (PaginatedData decodesTo String) RootQuery -searchPaginated cursor paginatorSetup fillInOptionals requiredArgs object_ = - search (fillInOptionals >> PaginatorSetup.addPageInfo cursor paginatorSetup) +searchPaginated pageSize cursor paginatorSetup fillInOptionals requiredArgs object_ = + search (fillInOptionals >> PaginatorSetup.addPageInfo pageSize cursor paginatorSetup) requiredArgs (Graphql.SelectionSet.map3 PaginatedData object_ diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index c15ca7256..86db6979d 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -34,14 +34,15 @@ type alias Response = -- second query, Cursor, no count (use from previous) -query : Maybe String -> SelectionSet Response RootQuery -query cursor = +query : PaginatedData any String -> SelectionSet Response RootQuery +query paginator = let setup = - Forward { first = 1 } + Forward in - Query.searchPaginated cursor - setup + Query.searchPaginated 1 + paginator.currentPage.cursor + paginator.direction identity { query = "language:Elm", type_ = Github.Enum.SearchType.Repository } searchResultFieldEdges @@ -87,9 +88,9 @@ repositorySelection = |> with (Repository.stargazers identity Github.Object.StargazerConnection.totalCount) -makeRequest : Maybe String -> Cmd Msg -makeRequest cursor = - query cursor +makeRequest : PaginatedData any String -> Cmd Msg +makeRequest paginator = + query paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" |> Graphql.Http.withHeader "authorization" "Bearer dbd4c239b0bbaa40ab0ea291fa811775da8f5b59" |> Graphql.Http.send (\result -> result |> RemoteData.fromResult |> GotResponse) @@ -105,13 +106,22 @@ type alias Model = PaginatedData RemoteDataResponse String + +-- type PaginatedRemoteData data +-- = NotLoading +-- | Loading data +-- | MoreToLoad data +-- | AllLoaded + + type alias RemoteDataResponse = RemoteData (Graphql.Http.Error Response) Response init : Flags -> ( Model, Cmd Msg ) init flags = - ( PaginatorSetup.init (Forward { first = 1 }) [ RemoteData.Loading ], makeRequest Nothing ) + PaginatorSetup.init Forward [ RemoteData.Loading ] + |> (\paginator -> ( paginator, makeRequest paginator )) view : Model -> Html.Html Msg @@ -119,7 +129,7 @@ view model = div [] [ div [] [ h1 [] [ text "Generated Query" ] - , pre [] [ text (Document.serializeQuery (query Nothing)) ] + , pre [] [ text (Document.serializeQuery (query model)) ] ] , div [] [ button [ onClick GetNextPage ] [ text "Load next page..." ] ] , div [] @@ -136,7 +146,7 @@ update msg model = case model.data of (RemoteData.Success successResponse) :: rest -> if successResponse.currentPage.done then - ( { model | data = RemoteData.Loading :: model.data }, makeRequest successResponse.currentPage.cursor ) + ( { model | data = RemoteData.Loading :: model.data }, makeRequest successResponse ) else ( model, Cmd.none ) diff --git a/src/Graphql/PaginatorSetup.elm b/src/Graphql/PaginatorSetup.elm index f4e682eaa..8adc27330 100644 --- a/src/Graphql/PaginatorSetup.elm +++ b/src/Graphql/PaginatorSetup.elm @@ -7,14 +7,14 @@ init : Direction -> List data -> PaginatedData data cursor init paginatorSetup initialData = { data = initialData , currentPage = { cursor = Nothing, done = False } - , setup = paginatorSetup + , direction = paginatorSetup } type alias PaginatedData data cursor = { data : List data , currentPage : CurrentPage cursor - , setup : Direction + , direction : Direction } @@ -29,18 +29,18 @@ type alias PageInfo pageInfo cursor = {-| TODO -} -addPageInfo : Maybe cursor -> Direction -> PageInfo pageInfo cursor -> PageInfo pageInfo cursor -addPageInfo maybeCursor paginationSetup optionals = +addPageInfo : Int -> Maybe cursor -> Direction -> PageInfo pageInfo cursor -> PageInfo pageInfo cursor +addPageInfo pageSize maybeCursor paginationSetup optionals = case paginationSetup of - Forward { first } -> + Forward -> { optionals - | first = Present first + | first = Present pageSize , after = OptionalArgument.fromMaybe maybeCursor } - Backward { last } -> + Backward -> { optionals - | last = Present last + | last = Present pageSize , before = OptionalArgument.fromMaybe maybeCursor } @@ -48,8 +48,8 @@ addPageInfo maybeCursor paginationSetup optionals = {-| Uses [the relay protocol](https://facebook.github.io/relay/graphql/connections.htm). -} type Direction - = Forward { first : Int } - | Backward { last : Int } + = Forward + | Backward type alias CurrentPage cursorType = From 008be9e5c8b0794490ccb95d4d1f9d34f139018c Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 22:42:45 +0100 Subject: [PATCH 17/83] Pass in paginator to helper function. --- examples/src/Github/Query.elm | 11 +++++------ examples/src/GithubPagination.elm | 3 +-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index f1a4c68f7..9503e2158 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -334,19 +334,18 @@ search fillInOptionals requiredArgs object_ = searchPaginated : Int - -> Maybe String - -> Direction + -> PaginatedData any String -> (SearchOptionalArguments -> SearchOptionalArguments) -> SearchRequiredArguments -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection -> SelectionSet (PaginatedData decodesTo String) RootQuery -searchPaginated pageSize cursor paginatorSetup fillInOptionals requiredArgs object_ = - search (fillInOptionals >> PaginatorSetup.addPageInfo pageSize cursor paginatorSetup) +searchPaginated pageSize paginator fillInOptionals requiredArgs object_ = + search (fillInOptionals >> PaginatorSetup.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) requiredArgs (Graphql.SelectionSet.map3 PaginatedData object_ - (Graphql.Internal.Paginator.fromSetup paginatorSetup) - (Graphql.SelectionSet.succeed paginatorSetup) + (Graphql.Internal.Paginator.fromSetup paginator.direction) + (Graphql.SelectionSet.succeed paginator.direction) ) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 86db6979d..8ebdaa00d 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -41,8 +41,7 @@ query paginator = Forward in Query.searchPaginated 1 - paginator.currentPage.cursor - paginator.direction + paginator identity { query = "language:Elm", type_ = Github.Enum.SearchType.Repository } searchResultFieldEdges From 28725431d30094efd6bcf16dfe29e114eeb254f3 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 23:02:42 +0100 Subject: [PATCH 18/83] Allow pagination size to be set. --- examples/src/GithubPagination.elm | 60 ++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 8ebdaa00d..211a0e4be 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -18,7 +18,7 @@ import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) -import Html exposing (button, div, h1, p, pre, text) +import Html exposing (button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) import PrintAny import RemoteData exposing (RemoteData) @@ -34,13 +34,13 @@ type alias Response = -- second query, Cursor, no count (use from previous) -query : PaginatedData any String -> SelectionSet Response RootQuery -query paginator = +query : Int -> PaginatedData any String -> SelectionSet Response RootQuery +query pageSize paginator = let setup = Forward in - Query.searchPaginated 1 + Query.searchPaginated pageSize paginator identity { query = "language:Elm", type_ = Github.Enum.SearchType.Repository } @@ -87,9 +87,9 @@ repositorySelection = |> with (Repository.stargazers identity Github.Object.StargazerConnection.totalCount) -makeRequest : PaginatedData any String -> Cmd Msg -makeRequest paginator = - query paginator +makeRequest : Int -> PaginatedData any String -> Cmd Msg +makeRequest pageSize paginator = + query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" |> Graphql.Http.withHeader "authorization" "Bearer dbd4c239b0bbaa40ab0ea291fa811775da8f5b59" |> Graphql.Http.send (\result -> result |> RemoteData.fromResult |> GotResponse) @@ -98,11 +98,14 @@ makeRequest paginator = type Msg = GotResponse RemoteDataResponse | GetNextPage + | CountChanged String type alias Model = -- List RemoteDataResponse - PaginatedData RemoteDataResponse String + { pageSize : Int + , data : PaginatedData RemoteDataResponse String + } @@ -120,7 +123,13 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = PaginatorSetup.init Forward [ RemoteData.Loading ] - |> (\paginator -> ( paginator, makeRequest paginator )) + |> (\paginator -> + ( { pageSize = 1 + , data = paginator + } + , makeRequest 1 paginator + ) + ) view : Model -> Html.Html Msg @@ -128,12 +137,15 @@ view model = div [] [ div [] [ h1 [] [ text "Generated Query" ] - , pre [] [ text (Document.serializeQuery (query model)) ] + , pre [] [ text (Document.serializeQuery (query model.pageSize model.data)) ] + ] + , div [] + [ button [ onClick GetNextPage ] [ text <| "Load next " ++ String.fromInt model.pageSize ++ " item(s)..." ] + , input [ Html.Events.onInput CountChanged ] [] ] - , div [] [ button [ onClick GetNextPage ] [ text "Load next page..." ] ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view (model.data |> List.reverse) + , PrintAny.view (model.data.data |> List.reverse) ] ] @@ -142,10 +154,14 @@ update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of GetNextPage -> - case model.data of + case model.data.data of (RemoteData.Success successResponse) :: rest -> if successResponse.currentPage.done then - ( { model | data = RemoteData.Loading :: model.data }, makeRequest successResponse ) + let + modelData = + model.data + in + ( { model | data = { modelData | data = RemoteData.Loading :: model.data.data } }, makeRequest model.pageSize successResponse ) else ( model, Cmd.none ) @@ -154,13 +170,25 @@ update msg model = ( model, Cmd.none ) GotResponse response -> - case model.data of + case model.data.data of head :: rest -> - ( { model | data = response :: rest }, Cmd.none ) + let + modelData = + model.data + in + ( { model | data = { modelData | data = response :: rest } }, Cmd.none ) _ -> ( model, Cmd.none ) + CountChanged newPageSizeString -> + case newPageSizeString |> String.toInt of + Just newPageSize -> + ( { model | pageSize = newPageSize }, Cmd.none ) + + Nothing -> + ( model, Cmd.none ) + type alias Flags = () From d2ccee775cdd28a480d06c6a77edd77089868222 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 23:06:52 +0100 Subject: [PATCH 19/83] Rename module. --- examples/src/Github/Object/PageInfo.elm | 2 +- examples/src/Github/Query.elm | 4 ++-- examples/src/GithubPagination.elm | 4 ++-- src/Graphql/Internal/Paginator.elm | 2 +- src/Graphql/{PaginatorSetup.elm => Pagination.elm} | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) rename src/Graphql/{PaginatorSetup.elm => Pagination.elm} (92%) diff --git a/examples/src/Github/Object/PageInfo.elm b/examples/src/Github/Object/PageInfo.elm index b0ce1368d..9f0db854c 100644 --- a/examples/src/Github/Object/PageInfo.elm +++ b/examples/src/Github/Object/PageInfo.elm @@ -15,7 +15,7 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup exposing (CurrentPage, Direction(..)) +import Graphql.Pagination exposing (CurrentPage, Direction(..)) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index 9503e2158..f5e30c526 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -17,7 +17,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode exposing (Decoder) @@ -340,7 +340,7 @@ searchPaginated : -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection -> SelectionSet (PaginatedData decodesTo String) RootQuery searchPaginated pageSize paginator fillInOptionals requiredArgs object_ = - search (fillInOptionals >> PaginatorSetup.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) + search (fillInOptionals >> Pagination.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) requiredArgs (Graphql.SelectionSet.map3 PaginatedData object_ diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 211a0e4be..607758658 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -16,7 +16,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup as PaginatorSetup exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) @@ -122,7 +122,7 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = - PaginatorSetup.init Forward [ RemoteData.Loading ] + Pagination.init Forward [ RemoteData.Loading ] |> (\paginator -> ( { pageSize = 1 , data = paginator diff --git a/src/Graphql/Internal/Paginator.elm b/src/Graphql/Internal/Paginator.elm index f1773ac6c..12c4aa91a 100644 --- a/src/Graphql/Internal/Paginator.elm +++ b/src/Graphql/Internal/Paginator.elm @@ -5,7 +5,7 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatorSetup exposing (CurrentPage, Direction(..)) +import Graphql.Pagination exposing (CurrentPage, Direction(..)) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode diff --git a/src/Graphql/PaginatorSetup.elm b/src/Graphql/Pagination.elm similarity index 92% rename from src/Graphql/PaginatorSetup.elm rename to src/Graphql/Pagination.elm index 8adc27330..8c200136d 100644 --- a/src/Graphql/PaginatorSetup.elm +++ b/src/Graphql/Pagination.elm @@ -1,4 +1,4 @@ -module Graphql.PaginatorSetup exposing (CurrentPage, Direction(..), PageInfo, PaginatedData, addPageInfo, init) +module Graphql.Pagination exposing (CurrentPage, Direction(..), PageInfo, PaginatedData, addPageInfo, init) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) From dbd539baa8ff47c9c1ae510519c45cf9cb1ce7d4 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 23:20:42 +0100 Subject: [PATCH 20/83] Append to list paging within helper. --- examples/src/Github/Query.elm | 4 +-- examples/src/GithubPagination.elm | 41 +++++++++---------------------- src/Graphql/Pagination.elm | 4 +-- 3 files changed, 16 insertions(+), 33 deletions(-) diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index f5e30c526..7c660279d 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -334,7 +334,7 @@ search fillInOptionals requiredArgs object_ = searchPaginated : Int - -> PaginatedData any String + -> PaginatedData decodesTo String -> (SearchOptionalArguments -> SearchOptionalArguments) -> SearchRequiredArguments -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection @@ -343,7 +343,7 @@ searchPaginated pageSize paginator fillInOptionals requiredArgs object_ = search (fillInOptionals >> Pagination.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) requiredArgs (Graphql.SelectionSet.map3 PaginatedData - object_ + (object_ |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) (Graphql.Internal.Paginator.fromSetup paginator.direction) (Graphql.SelectionSet.succeed paginator.direction) ) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 607758658..5d7146d9a 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -21,7 +21,6 @@ import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) import PrintAny -import RemoteData exposing (RemoteData) type alias Response = @@ -34,7 +33,7 @@ type alias Response = -- second query, Cursor, no count (use from previous) -query : Int -> PaginatedData any String -> SelectionSet Response RootQuery +query : Int -> PaginatedData Repo String -> SelectionSet Response RootQuery query pageSize paginator = let setup = @@ -87,12 +86,12 @@ repositorySelection = |> with (Repository.stargazers identity Github.Object.StargazerConnection.totalCount) -makeRequest : Int -> PaginatedData any String -> Cmd Msg +makeRequest : Int -> PaginatedData Repo String -> Cmd Msg makeRequest pageSize paginator = query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" |> Graphql.Http.withHeader "authorization" "Bearer dbd4c239b0bbaa40ab0ea291fa811775da8f5b59" - |> Graphql.Http.send (\result -> result |> RemoteData.fromResult |> GotResponse) + |> Graphql.Http.send GotResponse type Msg @@ -104,7 +103,7 @@ type Msg type alias Model = -- List RemoteDataResponse { pageSize : Int - , data : PaginatedData RemoteDataResponse String + , data : PaginatedData Repo String } @@ -117,12 +116,12 @@ type alias Model = type alias RemoteDataResponse = - RemoteData (Graphql.Http.Error Response) Response + Result (Graphql.Http.Error Response) Response init : Flags -> ( Model, Cmd Msg ) init flags = - Pagination.init Forward [ RemoteData.Loading ] + Pagination.init Forward [] |> (\paginator -> ( { pageSize = 1 , data = paginator @@ -137,7 +136,8 @@ view model = div [] [ div [] [ h1 [] [ text "Generated Query" ] - , pre [] [ text (Document.serializeQuery (query model.pageSize model.data)) ] + + -- , pre [] [ text (Document.serializeQuery (query model.pageSize model.data)) ] ] , div [] [ button [ onClick GetNextPage ] [ text <| "Load next " ++ String.fromInt model.pageSize ++ " item(s)..." ] @@ -154,29 +154,12 @@ update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of GetNextPage -> - case model.data.data of - (RemoteData.Success successResponse) :: rest -> - if successResponse.currentPage.done then - let - modelData = - model.data - in - ( { model | data = { modelData | data = RemoteData.Loading :: model.data.data } }, makeRequest model.pageSize successResponse ) - - else - ( model, Cmd.none ) - - _ -> - ( model, Cmd.none ) + ( model, makeRequest model.pageSize model.data ) GotResponse response -> - case model.data.data of - head :: rest -> - let - modelData = - model.data - in - ( { model | data = { modelData | data = response :: rest } }, Cmd.none ) + case response of + Ok successData -> + ( { model | data = successData }, Cmd.none ) _ -> ( model, Cmd.none ) diff --git a/src/Graphql/Pagination.elm b/src/Graphql/Pagination.elm index 8c200136d..3e518688e 100644 --- a/src/Graphql/Pagination.elm +++ b/src/Graphql/Pagination.elm @@ -4,10 +4,10 @@ import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(. init : Direction -> List data -> PaginatedData data cursor -init paginatorSetup initialData = +init direction initialData = { data = initialData , currentPage = { cursor = Nothing, done = False } - , direction = paginatorSetup + , direction = direction } From 4c354fdcf42ce854359216c024248b9da82f89d0 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 23:21:59 +0100 Subject: [PATCH 21/83] Remove comment. --- examples/src/GithubPagination.elm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 5d7146d9a..fdce57796 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -27,12 +27,6 @@ type alias Response = PaginatedData Repo String - --- first query -> No Cursor, just count (first or last) --- Result comes back -> Get a cursor, maintain the count --- second query, Cursor, no count (use from previous) - - query : Int -> PaginatedData Repo String -> SelectionSet Response RootQuery query pageSize paginator = let From e3cc9dd8a14afeb627a90872192996e930e65f82 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 23:43:42 +0100 Subject: [PATCH 22/83] Add another pagination example. --- examples/src/Github/Object/Repository.elm | 19 ++- examples/src/GithubPagination2.elm | 149 ++++++++++++++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 examples/src/GithubPagination2.elm diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index e18a81041..2ef54442b 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -2,7 +2,7 @@ -- https://github.com/dillonkearns/elm-graphql -module Github.Object.Repository exposing (AssignableUsersOptionalArguments, CollaboratorsOptionalArguments, CommitCommentsOptionalArguments, DeployKeysOptionalArguments, DeploymentsOptionalArguments, ForksOptionalArguments, IssueOrPullRequestRequiredArguments, IssueRequiredArguments, IssuesOptionalArguments, LabelRequiredArguments, LabelsOptionalArguments, LanguagesOptionalArguments, MentionableUsersOptionalArguments, MilestoneRequiredArguments, MilestonesOptionalArguments, ObjectOptionalArguments, ProjectRequiredArguments, ProjectsOptionalArguments, ProtectedBranchesOptionalArguments, PullRequestRequiredArguments, PullRequestsOptionalArguments, RefRequiredArguments, RefsOptionalArguments, RefsRequiredArguments, ReleaseRequiredArguments, ReleasesOptionalArguments, RepositoryTopicsOptionalArguments, ShortDescriptionHTMLOptionalArguments, StargazersOptionalArguments, WatchersOptionalArguments, assignableUsers, codeOfConduct, collaborators, commitComments, createdAt, databaseId, defaultBranchRef, deployKeys, deployments, description, descriptionHTML, diskUsage, forkCount, forks, hasIssuesEnabled, hasWikiEnabled, homepageUrl, id, isArchived, isFork, isLocked, isMirror, isPrivate, issue, issueOrPullRequest, issues, label, labels, languages, license, licenseInfo, lockReason, mentionableUsers, milestone, milestones, mirrorUrl, name, nameWithOwner, object, owner, parent, primaryLanguage, project, projects, projectsResourcePath, projectsUrl, protectedBranches, pullRequest, pullRequests, pushedAt, ref, refs, release, releases, repositoryTopics, resourcePath, shortDescriptionHTML, sshUrl, stargazers, updatedAt, url, viewerCanAdminister, viewerCanCreateProjects, viewerCanSubscribe, viewerCanUpdateTopics, viewerHasStarred, viewerPermission, viewerSubscription, watchers) +module Github.Object.Repository exposing (AssignableUsersOptionalArguments, CollaboratorsOptionalArguments, CommitCommentsOptionalArguments, DeployKeysOptionalArguments, DeploymentsOptionalArguments, ForksOptionalArguments, IssueOrPullRequestRequiredArguments, IssueRequiredArguments, IssuesOptionalArguments, LabelRequiredArguments, LabelsOptionalArguments, LanguagesOptionalArguments, MentionableUsersOptionalArguments, MilestoneRequiredArguments, MilestonesOptionalArguments, ObjectOptionalArguments, ProjectRequiredArguments, ProjectsOptionalArguments, ProtectedBranchesOptionalArguments, PullRequestRequiredArguments, PullRequestsOptionalArguments, RefRequiredArguments, RefsOptionalArguments, RefsRequiredArguments, ReleaseRequiredArguments, ReleasesOptionalArguments, RepositoryTopicsOptionalArguments, ShortDescriptionHTMLOptionalArguments, StargazersOptionalArguments, WatchersOptionalArguments, assignableUsers, codeOfConduct, collaborators, commitComments, createdAt, databaseId, defaultBranchRef, deployKeys, deployments, description, descriptionHTML, diskUsage, forkCount, forks, hasIssuesEnabled, hasWikiEnabled, homepageUrl, id, isArchived, isFork, isLocked, isMirror, isPrivate, issue, issueOrPullRequest, issues, label, labels, languages, license, licenseInfo, lockReason, mentionableUsers, milestone, milestones, mirrorUrl, name, nameWithOwner, object, owner, parent, primaryLanguage, project, projects, projectsResourcePath, projectsUrl, protectedBranches, pullRequest, pullRequests, pushedAt, ref, refs, release, releases, repositoryTopics, resourcePath, shortDescriptionHTML, sshUrl, stargazers, stargazersPaginated, updatedAt, url, viewerCanAdminister, viewerCanCreateProjects, viewerCanSubscribe, viewerCanUpdateTopics, viewerHasStarred, viewerPermission, viewerSubscription, watchers) import Github.Enum.CollaboratorAffiliation import Github.Enum.IssueState @@ -24,8 +24,10 @@ import Github.Union import Graphql.Internal.Builder.Argument as Argument exposing (Argument) import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) +import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode @@ -981,6 +983,21 @@ stargazers fillInOptionals object_ = Object.selectionForCompositeField "stargazers" optionalArgs object_ identity +stargazersPaginated : + Int + -> PaginatedData decodesTo String + -> (StargazersOptionalArguments -> StargazersOptionalArguments) + -> SelectionSet (List decodesTo) Github.Object.StargazerConnection + -> SelectionSet (PaginatedData decodesTo String) Github.Object.Repository +stargazersPaginated pageSize paginator fillInOptionals object_ = + stargazers (fillInOptionals >> Pagination.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) + (Graphql.SelectionSet.map3 PaginatedData + (object_ |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) + (Graphql.Internal.Paginator.fromSetup paginator.direction) + (Graphql.SelectionSet.succeed paginator.direction) + ) + + {-| Identifies the date and time when the object was last updated. -} updatedAt : SelectionSet Github.ScalarCodecs.DateTime Github.Object.Repository diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm new file mode 100644 index 000000000..6be4ce681 --- /dev/null +++ b/examples/src/GithubPagination2.elm @@ -0,0 +1,149 @@ +module GithubPagination2 exposing (main) + +import Browser +import Github.Enum.SearchType +import Github.Object +import Github.Object.PageInfo +import Github.Object.Repository as Repository +import Github.Object.SearchResultItemConnection +import Github.Object.SearchResultItemEdge +import Github.Object.StargazerConnection +import Github.Object.StargazerEdge +import Github.Object.User +import Github.Query as Query +import Github.Scalar +import Github.Union +import Github.Union.SearchResultItem +import Graphql.Document as Document +import Graphql.Http +import Graphql.Operation exposing (RootQuery) +import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) +import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) +import Html exposing (button, div, h1, input, p, pre, text) +import Html.Events exposing (onClick) +import PrintAny + + +type alias Response = + PaginatedData StarGazer String + + +query : Int -> PaginatedData StarGazer String -> SelectionSet Response RootQuery +query pageSize paginator = + let + setup = + Forward + in + Query.repository { owner = "dillonkearns", name = "elm-graphql" } + (Repository.stargazersPaginated + pageSize + paginator + identity + stargazerSelection + ) + |> SelectionSet.nonNullOrFail + + +stargazerSelection : SelectionSet (List String) Github.Object.StargazerConnection +stargazerSelection = + Github.Object.StargazerConnection.edges (Github.Object.StargazerEdge.node (Github.Object.User.name |> SelectionSet.withDefault "???")) + |> SelectionSet.nonNullOrFail + |> SelectionSet.nonNullElementsOrFail + + +type alias StarGazer = + String + + +makeRequest : Int -> PaginatedData StarGazer String -> Cmd Msg +makeRequest pageSize paginator = + query pageSize paginator + |> Graphql.Http.queryRequest "https://api.github.com/graphql" + |> Graphql.Http.withHeader "authorization" "Bearer dbd4c239b0bbaa40ab0ea291fa811775da8f5b59" + |> Graphql.Http.send GotResponse + + +type Msg + = GotResponse RemoteDataResponse + | GetNextPage + | CountChanged String + + +type alias Model = + -- List RemoteDataResponse + { pageSize : Int + , data : PaginatedData StarGazer String + } + + +type alias RemoteDataResponse = + Result (Graphql.Http.Error Response) Response + + +init : Flags -> ( Model, Cmd Msg ) +init flags = + Pagination.init Forward [] + |> (\paginator -> + ( { pageSize = 1 + , data = paginator + } + , makeRequest 1 paginator + ) + ) + + +view : Model -> Html.Html Msg +view model = + div [] + [ div [] + [ h1 [] [ text "Generated Query" ] + + -- , pre [] [ text (Document.serializeQuery (query model.pageSize model.data)) ] + ] + , div [] + [ button [ onClick GetNextPage ] [ text <| "Load next " ++ String.fromInt model.pageSize ++ " item(s)..." ] + , input [ Html.Events.onInput CountChanged ] [] + ] + , div [] + [ h1 [] [ text "Response" ] + , PrintAny.view (model.data.data |> List.reverse) + ] + ] + + +update : Msg -> Model -> ( Model, Cmd Msg ) +update msg model = + case msg of + GetNextPage -> + ( model, makeRequest model.pageSize model.data ) + + GotResponse response -> + case response of + Ok successData -> + ( { model | data = successData }, Cmd.none ) + + _ -> + ( model, Cmd.none ) + + CountChanged newPageSizeString -> + case newPageSizeString |> String.toInt of + Just newPageSize -> + ( { model | pageSize = newPageSize }, Cmd.none ) + + Nothing -> + ( model, Cmd.none ) + + +type alias Flags = + () + + +main : Program Flags Model Msg +main = + Browser.element + { init = init + , update = update + , subscriptions = \_ -> Sub.none + , view = view + } From 7aae1d417200d1207c7f0a60613215f8896e135d Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 21 Feb 2019 23:50:16 +0100 Subject: [PATCH 23/83] Extract internal function. --- examples/src/Github/Object/Repository.elm | 6 +----- examples/src/Github/Query.elm | 6 +----- src/Graphql/Internal/Paginator.elm | 16 ++++++++++++++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index 2ef54442b..d03a034bf 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -991,11 +991,7 @@ stargazersPaginated : -> SelectionSet (PaginatedData decodesTo String) Github.Object.Repository stargazersPaginated pageSize paginator fillInOptionals object_ = stargazers (fillInOptionals >> Pagination.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) - (Graphql.SelectionSet.map3 PaginatedData - (object_ |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) - (Graphql.Internal.Paginator.fromSetup paginator.direction) - (Graphql.SelectionSet.succeed paginator.direction) - ) + (Graphql.Internal.Paginator.selectionSet pageSize paginator object_) {-| Identifies the date and time when the object was last updated. diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index 7c660279d..193ea34a2 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -342,11 +342,7 @@ searchPaginated : searchPaginated pageSize paginator fillInOptionals requiredArgs object_ = search (fillInOptionals >> Pagination.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) requiredArgs - (Graphql.SelectionSet.map3 PaginatedData - (object_ |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) - (Graphql.Internal.Paginator.fromSetup paginator.direction) - (Graphql.SelectionSet.succeed paginator.direction) - ) + (Graphql.Internal.Paginator.selectionSet pageSize paginator object_) type alias TopicRequiredArguments = diff --git a/src/Graphql/Internal/Paginator.elm b/src/Graphql/Internal/Paginator.elm index 12c4aa91a..6eaf1df14 100644 --- a/src/Graphql/Internal/Paginator.elm +++ b/src/Graphql/Internal/Paginator.elm @@ -1,15 +1,27 @@ -module Graphql.Internal.Paginator exposing (fromSetup) +module Graphql.Internal.Paginator exposing (fromSetup, selectionSet) import Graphql.Internal.Builder.Argument as Argument exposing (Argument) import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Pagination exposing (CurrentPage, Direction(..)) +import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode +selectionSet : + Int + -> PaginatedData decodesTo String + -> SelectionSet (List decodesTo) typeLock + -> SelectionSet (PaginatedData decodesTo String) typeLock +selectionSet pageSize paginator selection = + Graphql.SelectionSet.map3 PaginatedData + (selection |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) + (fromSetup paginator.direction) + (Graphql.SelectionSet.succeed paginator.direction) + + fromSetup : Direction -> SelectionSet (CurrentPage String) connection fromSetup paginatorSetup = let From 0fed02d754c0b99ff2370ef47972f7031957a602 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Fri, 22 Feb 2019 10:57:34 +0100 Subject: [PATCH 24/83] Include stargazer metadata in example. --- examples/src/GithubPagination2.elm | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 6be4ce681..6289f06f0 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -26,10 +26,10 @@ import PrintAny type alias Response = - PaginatedData StarGazer String + PaginatedData Stargazer String -query : Int -> PaginatedData StarGazer String -> SelectionSet Response RootQuery +query : Int -> PaginatedData Stargazer String -> SelectionSet Response RootQuery query pageSize paginator = let setup = @@ -45,18 +45,24 @@ query pageSize paginator = |> SelectionSet.nonNullOrFail -stargazerSelection : SelectionSet (List String) Github.Object.StargazerConnection +type alias Stargazer = + { name : String + , starredAt : Github.Scalar.DateTime + } + + +stargazerSelection : SelectionSet (List Stargazer) Github.Object.StargazerConnection stargazerSelection = - Github.Object.StargazerConnection.edges (Github.Object.StargazerEdge.node (Github.Object.User.name |> SelectionSet.withDefault "???")) + Github.Object.StargazerConnection.edges + (SelectionSet.map2 Stargazer + (Github.Object.StargazerEdge.node (Github.Object.User.name |> SelectionSet.withDefault "???")) + Github.Object.StargazerEdge.starredAt + ) |> SelectionSet.nonNullOrFail |> SelectionSet.nonNullElementsOrFail -type alias StarGazer = - String - - -makeRequest : Int -> PaginatedData StarGazer String -> Cmd Msg +makeRequest : Int -> PaginatedData Stargazer String -> Cmd Msg makeRequest pageSize paginator = query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" @@ -73,7 +79,7 @@ type Msg type alias Model = -- List RemoteDataResponse { pageSize : Int - , data : PaginatedData StarGazer String + , data : PaginatedData Stargazer String } From 5f495bf551b37128b5b8c60825be1d4ef68dd3fc Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Fri, 22 Feb 2019 11:08:36 +0100 Subject: [PATCH 25/83] Show whether done loading or not in example. --- examples/src/GithubPagination2.elm | 20 ++++++++++++++++++-- src/Graphql/Pagination.elm | 4 ++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 6289f06f0..73e2c945e 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -20,7 +20,7 @@ import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) -import Html exposing (button, div, h1, input, p, pre, text) +import Html exposing (Html, button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) import PrintAny @@ -99,7 +99,7 @@ init flags = ) -view : Model -> Html.Html Msg +view : Model -> Html Msg view model = div [] [ div [] @@ -110,6 +110,7 @@ view model = , div [] [ button [ onClick GetNextPage ] [ text <| "Load next " ++ String.fromInt model.pageSize ++ " item(s)..." ] , input [ Html.Events.onInput CountChanged ] [] + , paginationDetailsView model ] , div [] [ h1 [] [ text "Response" ] @@ -118,6 +119,21 @@ view model = ] +paginationDetailsView : Model -> Html msg +paginationDetailsView model = + doneView model + + +doneView model = + Html.text + (if model.data.currentPage.hasNextPage then + "Loading..." + + else + "✅" + ) + + update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of diff --git a/src/Graphql/Pagination.elm b/src/Graphql/Pagination.elm index 3e518688e..438d37609 100644 --- a/src/Graphql/Pagination.elm +++ b/src/Graphql/Pagination.elm @@ -6,7 +6,7 @@ import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(. init : Direction -> List data -> PaginatedData data cursor init direction initialData = { data = initialData - , currentPage = { cursor = Nothing, done = False } + , currentPage = { cursor = Nothing, hasNextPage = True } , direction = direction } @@ -54,5 +54,5 @@ type Direction type alias CurrentPage cursorType = { cursor : Maybe cursorType - , done : Bool + , hasNextPage : Bool } From c87d718ce1b17fbfe90030b0f78ddf8b0d98af5c Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Fri, 22 Feb 2019 11:11:21 +0100 Subject: [PATCH 26/83] Show number loaded so far. --- examples/src/GithubPagination2.elm | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 73e2c945e..0495edfba 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -121,16 +121,25 @@ view model = paginationDetailsView : Model -> Html msg paginationDetailsView model = - doneView model + div [] + [ "Loaded " + ++ (model.data.data + |> List.length + |> String.fromInt + ) + ++ " so far" + |> text + , doneView model + ] doneView model = Html.text (if model.data.currentPage.hasNextPage then - "Loading..." + "..." else - "✅" + " ✅" ) From 3fc6f70a9436ac7b5520412be7790c8b4e77ad4c Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Fri, 22 Feb 2019 11:36:55 +0100 Subject: [PATCH 27/83] Rename record field in example. --- examples/src/GithubPagination2.elm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 0495edfba..e9277347d 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -79,7 +79,7 @@ type Msg type alias Model = -- List RemoteDataResponse { pageSize : Int - , data : PaginatedData Stargazer String + , paginator : PaginatedData Stargazer String } @@ -92,7 +92,7 @@ init flags = Pagination.init Forward [] |> (\paginator -> ( { pageSize = 1 - , data = paginator + , paginator = paginator } , makeRequest 1 paginator ) @@ -114,7 +114,7 @@ view model = ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view (model.data.data |> List.reverse) + , PrintAny.view (model.paginator.data |> List.reverse) ] ] @@ -123,7 +123,7 @@ paginationDetailsView : Model -> Html msg paginationDetailsView model = div [] [ "Loaded " - ++ (model.data.data + ++ (model.paginator.data |> List.length |> String.fromInt ) @@ -135,7 +135,7 @@ paginationDetailsView model = doneView model = Html.text - (if model.data.currentPage.hasNextPage then + (if model.paginator.currentPage.hasNextPage then "..." else @@ -147,12 +147,12 @@ update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of GetNextPage -> - ( model, makeRequest model.pageSize model.data ) + ( model, makeRequest model.pageSize model.paginator ) GotResponse response -> case response of Ok successData -> - ( { model | data = successData }, Cmd.none ) + ( { model | paginator = successData }, Cmd.none ) _ -> ( model, Cmd.none ) From 4c3fad86b7dfe3744e6d07be24127c957875bc41 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Fri, 22 Feb 2019 11:53:40 +0100 Subject: [PATCH 28/83] Rename field in pagination module to be direction-agnostic. --- examples/src/GithubPagination2.elm | 2 +- src/Graphql/Pagination.elm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index e9277347d..8a8e72ff9 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -135,7 +135,7 @@ paginationDetailsView model = doneView model = Html.text - (if model.paginator.currentPage.hasNextPage then + (if model.paginator.currentPage.isLoading then "..." else diff --git a/src/Graphql/Pagination.elm b/src/Graphql/Pagination.elm index 438d37609..fcd0152dd 100644 --- a/src/Graphql/Pagination.elm +++ b/src/Graphql/Pagination.elm @@ -6,7 +6,7 @@ import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(. init : Direction -> List data -> PaginatedData data cursor init direction initialData = { data = initialData - , currentPage = { cursor = Nothing, hasNextPage = True } + , currentPage = { cursor = Nothing, isLoading = True } , direction = direction } @@ -54,5 +54,5 @@ type Direction type alias CurrentPage cursorType = { cursor : Maybe cursorType - , hasNextPage : Bool + , isLoading : Bool } From 990d87fbf6467566ddf40c1186990f2f13ca546e Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Fri, 22 Feb 2019 11:54:18 +0100 Subject: [PATCH 29/83] Remove unused variable in example. --- examples/src/GithubPagination2.elm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 8a8e72ff9..d42edb000 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -31,10 +31,6 @@ type alias Response = query : Int -> PaginatedData Stargazer String -> SelectionSet Response RootQuery query pageSize paginator = - let - setup = - Forward - in Query.repository { owner = "dillonkearns", name = "elm-graphql" } (Repository.stargazersPaginated pageSize From 1502ead0bd06f9dfbfe36e1053a86f9d27b320ab Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Fri, 22 Feb 2019 12:00:31 +0100 Subject: [PATCH 30/83] Fix pagination to check hasPreviousPage for Backward pagination. --- examples/src/GithubPagination2.elm | 6 +++--- src/Graphql/Internal/Paginator.elm | 13 ++++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index d42edb000..281fe16ba 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -42,7 +42,7 @@ query pageSize paginator = type alias Stargazer = - { name : String + { login : String , starredAt : Github.Scalar.DateTime } @@ -51,7 +51,7 @@ stargazerSelection : SelectionSet (List Stargazer) Github.Object.StargazerConnec stargazerSelection = Github.Object.StargazerConnection.edges (SelectionSet.map2 Stargazer - (Github.Object.StargazerEdge.node (Github.Object.User.name |> SelectionSet.withDefault "???")) + (Github.Object.StargazerEdge.node Github.Object.User.login) Github.Object.StargazerEdge.starredAt ) |> SelectionSet.nonNullOrFail @@ -85,7 +85,7 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = - Pagination.init Forward [] + Pagination.init Backward [] |> (\paginator -> ( { pageSize = 1 , paginator = paginator diff --git a/src/Graphql/Internal/Paginator.elm b/src/Graphql/Internal/Paginator.elm index 6eaf1df14..0016d6b68 100644 --- a/src/Graphql/Internal/Paginator.elm +++ b/src/Graphql/Internal/Paginator.elm @@ -26,9 +26,16 @@ fromSetup : Direction -> SelectionSet (CurrentPage String) connection fromSetup paginatorSetup = let object_ = - Graphql.SelectionSet.map2 CurrentPage - endCursor - hasNextPage + case paginatorSetup of + Forward -> + Graphql.SelectionSet.map2 CurrentPage + endCursor + hasNextPage + + Backward -> + Graphql.SelectionSet.map2 CurrentPage + startCursor + hasPreviousPage in Object.selectionForCompositeField "pageInfo" [] object_ identity From 2cce475cce5446bd013fab92d7d02b201be6ed31 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Fri, 22 Feb 2019 20:52:45 +0100 Subject: [PATCH 31/83] Make paginated stargazer connection take a SelectionSet on the Edge. --- examples/src/Github/Object/Repository.elm | 9 +++++++-- examples/src/GithubPagination2.elm | 14 ++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index d03a034bf..0e78369c8 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -987,11 +987,16 @@ stargazersPaginated : Int -> PaginatedData decodesTo String -> (StargazersOptionalArguments -> StargazersOptionalArguments) - -> SelectionSet (List decodesTo) Github.Object.StargazerConnection + -> SelectionSet decodesTo Github.Object.StargazerEdge -> SelectionSet (PaginatedData decodesTo String) Github.Object.Repository stargazersPaginated pageSize paginator fillInOptionals object_ = stargazers (fillInOptionals >> Pagination.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) - (Graphql.Internal.Paginator.selectionSet pageSize paginator object_) + (Graphql.Internal.Paginator.selectionSet pageSize paginator (stargazerEdges object_)) + + +stargazerEdges : SelectionSet decodesTo Github.Object.StargazerEdge -> SelectionSet (List decodesTo) Github.Object.StargazerConnection +stargazerEdges object_ = + Object.selectionForCompositeField "edges" [] object_ (identity >> Decode.list) {-| Identifies the date and time when the object was last updated. diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 281fe16ba..e783d61d5 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -47,15 +47,13 @@ type alias Stargazer = } -stargazerSelection : SelectionSet (List Stargazer) Github.Object.StargazerConnection +stargazerSelection : SelectionSet Stargazer Github.Object.StargazerEdge stargazerSelection = - Github.Object.StargazerConnection.edges - (SelectionSet.map2 Stargazer - (Github.Object.StargazerEdge.node Github.Object.User.login) - Github.Object.StargazerEdge.starredAt - ) - |> SelectionSet.nonNullOrFail - |> SelectionSet.nonNullElementsOrFail + SelectionSet.map2 Stargazer + -- you can grab core data from the Node like this + (Github.Object.StargazerEdge.node Github.Object.User.login) + -- plus you can grab meta-data from the "Edge" (represents the relationship) + Github.Object.StargazerEdge.starredAt makeRequest : Int -> PaginatedData Stargazer String -> Cmd Msg From d650cabd5946d9cdea84ebb9ebdf52f1e9ba5a31 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 23 Feb 2019 19:36:34 +0100 Subject: [PATCH 32/83] Add some test case boilerplate for Connection definition detection. --- .../tests/Parser/ConnectionDetectorTests.elm | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 generator/tests/Parser/ConnectionDetectorTests.elm diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm new file mode 100644 index 000000000..e57f63fc6 --- /dev/null +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -0,0 +1,40 @@ +module Parser.ConnectionDetectorTests exposing (all) + +import Expect +import Graphql.Parser.CamelCaseName as CamelCaseName +import Graphql.Parser.ClassCaseName as ClassCaseName +import Graphql.Parser.Type as Type exposing (IsNullable(..), TypeDefinition(..), TypeReference(..)) +import Test exposing (Test, describe, test) + + + +-- TypeReference ReferrableType IsNullable + + +isConnection : TypeDefinition -> Bool +isConnection typeReference = + False + + +field : String -> String -> Type.Field +field inputObjectName fieldName = + { name = CamelCaseName.build fieldName + , description = Nothing + , typeRef = TypeReference (Type.InputObjectRef (ClassCaseName.build inputObjectName)) NonNullable + , args = [] + } + + +all : Test +all = + describe "detect connections" + [ describe "non-objects" + [ test "scalar is not a Connection" <| + \() -> + TypeDefinition (ClassCaseName.build "SomeInputObject") + (Type.InputObjectType [ field "String" "hello" ]) + Nothing + |> isConnection + |> Expect.false "Should not detect Scalars as Connections." + ] + ] From feff533e5ec7bb73e27a154b9da42f4627d322e8 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 23 Feb 2019 19:43:18 +0100 Subject: [PATCH 33/83] Add test case, change expected type of connection detection function. --- .../tests/Parser/ConnectionDetectorTests.elm | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index e57f63fc6..39a755dd1 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -7,13 +7,15 @@ import Graphql.Parser.Type as Type exposing (IsNullable(..), TypeDefinition(..), import Test exposing (Test, describe, test) +type DetectionResult + = Miss + | SpecViolation + | Match --- TypeReference ReferrableType IsNullable - -isConnection : TypeDefinition -> Bool -isConnection typeReference = - False +isConnection : TypeDefinition -> DetectionResult +isConnection (TypeDefinition typeName definableType description) = + Miss field : String -> String -> Type.Field @@ -35,6 +37,15 @@ all = (Type.InputObjectType [ field "String" "hello" ]) Nothing |> isConnection - |> Expect.false "Should not detect Scalars as Connections." + |> Expect.equal Miss + ] + , describe "objects" + [ test "Object with correct name violates convention, should warn" <| + \() -> + TypeDefinition (ClassCaseName.build "StargazerConnection") + (Type.InputObjectType [ field "String" "hello" ]) + Nothing + |> isConnection + |> Expect.equal SpecViolation ] ] From db72e38013e4ee6ba35cf0a715207e137c8d0044 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 23 Feb 2019 19:47:08 +0100 Subject: [PATCH 34/83] Check for spec violations. --- generator/tests/Parser/ConnectionDetectorTests.elm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index 39a755dd1..583e8863e 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -15,7 +15,11 @@ type DetectionResult isConnection : TypeDefinition -> DetectionResult isConnection (TypeDefinition typeName definableType description) = - Miss + if typeName |> ClassCaseName.raw |> String.endsWith "Connection" then + SpecViolation + + else + Miss field : String -> String -> Type.Field From decbbfcb5b9821bb6de0cf9579e3fa609f1c13a0 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 23 Feb 2019 20:03:13 +0100 Subject: [PATCH 35/83] Add helper to define type definitions. --- .../tests/Parser/ConnectionDetectorTests.elm | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index 583e8863e..e76276c58 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -37,19 +37,47 @@ all = [ describe "non-objects" [ test "scalar is not a Connection" <| \() -> - TypeDefinition (ClassCaseName.build "SomeInputObject") + typeDefinition "SomeInputObject" (Type.InputObjectType [ field "String" "hello" ]) - Nothing |> isConnection |> Expect.equal Miss ] , describe "objects" [ test "Object with correct name violates convention, should warn" <| \() -> - TypeDefinition (ClassCaseName.build "StargazerConnection") + typeDefinition "StargazerConnection" (Type.InputObjectType [ field "String" "hello" ]) - Nothing + |> isConnection + |> Expect.equal SpecViolation + + {- + { + repository(owner: "dillonkearns", name: "elm-graphql") { + stargazers(first: 10, after: null) { + totalCount + pageInfo { + hasNextPage + endCursor + } + edges { + node { + login + } + starredAt + } + } + } + } + + -} + , test "strict spec match" <| + \() -> + typeDefinition "StargazerConnection" (Type.InputObjectType [ field "String" "hello" ]) |> isConnection |> Expect.equal SpecViolation ] ] + + +typeDefinition classCaseName definableType = + TypeDefinition (ClassCaseName.build classCaseName) definableType Nothing From 407055298d2cca56109ba623e068d4b04f8815e1 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 23 Feb 2019 20:04:34 +0100 Subject: [PATCH 36/83] Add type annotation. --- generator/tests/Parser/ConnectionDetectorTests.elm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index e76276c58..46ba1b1f2 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -3,7 +3,7 @@ module Parser.ConnectionDetectorTests exposing (all) import Expect import Graphql.Parser.CamelCaseName as CamelCaseName import Graphql.Parser.ClassCaseName as ClassCaseName -import Graphql.Parser.Type as Type exposing (IsNullable(..), TypeDefinition(..), TypeReference(..)) +import Graphql.Parser.Type as Type exposing (DefinableType, IsNullable(..), TypeDefinition(..), TypeReference(..)) import Test exposing (Test, describe, test) @@ -79,5 +79,6 @@ all = ] +typeDefinition : String -> DefinableType -> TypeDefinition typeDefinition classCaseName definableType = TypeDefinition (ClassCaseName.build classCaseName) definableType Nothing From f5fd970fba182b79a37c21a164a002b69730b568 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 23 Feb 2019 20:09:54 +0100 Subject: [PATCH 37/83] Pass in all type definitions to check. --- .../tests/Parser/ConnectionDetectorTests.elm | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index 46ba1b1f2..3a4b9ba43 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -13,8 +13,8 @@ type DetectionResult | Match -isConnection : TypeDefinition -> DetectionResult -isConnection (TypeDefinition typeName definableType description) = +isConnection : TypeDefinition -> List TypeDefinition -> DetectionResult +isConnection (TypeDefinition typeName definableType description) allDefinitions = if typeName |> ClassCaseName.raw |> String.endsWith "Connection" then SpecViolation @@ -37,17 +37,17 @@ all = [ describe "non-objects" [ test "scalar is not a Connection" <| \() -> - typeDefinition "SomeInputObject" - (Type.InputObjectType [ field "String" "hello" ]) - |> isConnection + isConnection + (typeDefinition "SomeInputObject" (Type.InputObjectType [ field "String" "hello" ])) + [] |> Expect.equal Miss ] , describe "objects" [ test "Object with correct name violates convention, should warn" <| \() -> - typeDefinition "StargazerConnection" - (Type.InputObjectType [ field "String" "hello" ]) - |> isConnection + isConnection + (typeDefinition "StargazerConnection" (Type.InputObjectType [ field "String" "hello" ])) + [] |> Expect.equal SpecViolation {- @@ -72,8 +72,10 @@ all = -} , test "strict spec match" <| \() -> - typeDefinition "StargazerConnection" (Type.InputObjectType [ field "String" "hello" ]) - |> isConnection + isConnection + (typeDefinition "StargazerConnection" (Type.ObjectType [ field "PageInfo" "pageInfo" ])) + [ typeDefinition "StargazerEdge" (Type.InputObjectType [ field "String" "hello" ]) + ] |> Expect.equal SpecViolation ] ] From 5dea1c03d18949ba23d7d155d1d2d1d2fb9a823e Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 23 Feb 2019 20:31:50 +0100 Subject: [PATCH 38/83] Extract page info definition example in test. --- .../tests/Parser/ConnectionDetectorTests.elm | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index 3a4b9ba43..87622f74f 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -3,6 +3,7 @@ module Parser.ConnectionDetectorTests exposing (all) import Expect import Graphql.Parser.CamelCaseName as CamelCaseName import Graphql.Parser.ClassCaseName as ClassCaseName +import Graphql.Parser.Scalar as Scalar import Graphql.Parser.Type as Type exposing (DefinableType, IsNullable(..), TypeDefinition(..), TypeReference(..)) import Test exposing (Test, describe, test) @@ -22,15 +23,6 @@ isConnection (TypeDefinition typeName definableType description) allDefinitions Miss -field : String -> String -> Type.Field -field inputObjectName fieldName = - { name = CamelCaseName.build fieldName - , description = Nothing - , typeRef = TypeReference (Type.InputObjectRef (ClassCaseName.build inputObjectName)) NonNullable - , args = [] - } - - all : Test all = describe "detect connections" @@ -74,7 +66,8 @@ all = \() -> isConnection (typeDefinition "StargazerConnection" (Type.ObjectType [ field "PageInfo" "pageInfo" ])) - [ typeDefinition "StargazerEdge" (Type.InputObjectType [ field "String" "hello" ]) + [ strictPageInfoDefinition + , typeDefinition "StargazerEdge" (Type.InputObjectType [ field "String" "hello" ]) ] |> Expect.equal SpecViolation ] @@ -84,3 +77,33 @@ all = typeDefinition : String -> DefinableType -> TypeDefinition typeDefinition classCaseName definableType = TypeDefinition (ClassCaseName.build classCaseName) definableType Nothing + + +strictPageInfoDefinition : TypeDefinition +strictPageInfoDefinition = + typeDefinition "PageInfo" + (Type.ObjectType + [ fieldNew "hasPreviousPage" (Type.Scalar Scalar.Boolean) NonNullable + , fieldNew "hasNextPage" (Type.Scalar Scalar.Boolean) NonNullable + , fieldNew "startCursor" (Type.Scalar Scalar.String) Nullable + , fieldNew "endCursor" (Type.Scalar Scalar.String) Nullable + ] + ) + + +fieldNew : String -> Type.ReferrableType -> IsNullable -> Type.Field +fieldNew fieldName reference isNullable = + { name = CamelCaseName.build fieldName + , description = Nothing + , typeRef = TypeReference reference isNullable + , args = [] + } + + +field : String -> String -> Type.Field +field inputObjectName fieldName = + { name = CamelCaseName.build fieldName + , description = Nothing + , typeRef = TypeReference (Type.InputObjectRef (ClassCaseName.build inputObjectName)) NonNullable + , args = [] + } From 069c182da3e4302b52d07dbec210a17b0508bd83 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 23 Feb 2019 20:46:14 +0100 Subject: [PATCH 39/83] Fix up some fields in test. --- generator/tests/Parser/ConnectionDetectorTests.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index 87622f74f..2bf77d5ca 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -38,7 +38,7 @@ all = [ test "Object with correct name violates convention, should warn" <| \() -> isConnection - (typeDefinition "StargazerConnection" (Type.InputObjectType [ field "String" "hello" ])) + (typeDefinition "StargazerConnection" (Type.ObjectType [ fieldNew "totalCount" (Type.Scalar Scalar.Int) NonNullable ])) [] |> Expect.equal SpecViolation From e9724684c555924217ae778ce314cc3c2a3e2f18 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 12:52:07 +0100 Subject: [PATCH 40/83] Remove type variable for cursor in PaginatedData. --- examples/src/Github/Object/PageInfo.elm | 2 +- examples/src/Github/Object/Repository.elm | 4 ++-- examples/src/Github/Query.elm | 4 ++-- examples/src/GithubPagination.elm | 8 ++++---- examples/src/GithubPagination2.elm | 8 ++++---- src/Graphql/Internal/Paginator.elm | 6 +++--- src/Graphql/Pagination.elm | 10 +++++----- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/examples/src/Github/Object/PageInfo.elm b/examples/src/Github/Object/PageInfo.elm index 9f0db854c..bfbcdd357 100644 --- a/examples/src/Github/Object/PageInfo.elm +++ b/examples/src/Github/Object/PageInfo.elm @@ -20,7 +20,7 @@ import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode -fromSetup : Direction -> SelectionSet (CurrentPage String) Github.Object.PageInfo +fromSetup : Direction -> SelectionSet CurrentPage Github.Object.PageInfo fromSetup paginatorSetup = Graphql.SelectionSet.map2 CurrentPage endCursor diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index 0e78369c8..acf037acb 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -985,10 +985,10 @@ stargazers fillInOptionals object_ = stargazersPaginated : Int - -> PaginatedData decodesTo String + -> PaginatedData decodesTo -> (StargazersOptionalArguments -> StargazersOptionalArguments) -> SelectionSet decodesTo Github.Object.StargazerEdge - -> SelectionSet (PaginatedData decodesTo String) Github.Object.Repository + -> SelectionSet (PaginatedData decodesTo) Github.Object.Repository stargazersPaginated pageSize paginator fillInOptionals object_ = stargazers (fillInOptionals >> Pagination.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) (Graphql.Internal.Paginator.selectionSet pageSize paginator (stargazerEdges object_)) diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index 193ea34a2..236c60d9f 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -334,11 +334,11 @@ search fillInOptionals requiredArgs object_ = searchPaginated : Int - -> PaginatedData decodesTo String + -> PaginatedData decodesTo -> (SearchOptionalArguments -> SearchOptionalArguments) -> SearchRequiredArguments -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection - -> SelectionSet (PaginatedData decodesTo String) RootQuery + -> SelectionSet (PaginatedData decodesTo) RootQuery searchPaginated pageSize paginator fillInOptionals requiredArgs object_ = search (fillInOptionals >> Pagination.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) requiredArgs diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index fdce57796..0ab18d783 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -24,10 +24,10 @@ import PrintAny type alias Response = - PaginatedData Repo String + PaginatedData Repo -query : Int -> PaginatedData Repo String -> SelectionSet Response RootQuery +query : Int -> PaginatedData Repo -> SelectionSet Response RootQuery query pageSize paginator = let setup = @@ -80,7 +80,7 @@ repositorySelection = |> with (Repository.stargazers identity Github.Object.StargazerConnection.totalCount) -makeRequest : Int -> PaginatedData Repo String -> Cmd Msg +makeRequest : Int -> PaginatedData Repo -> Cmd Msg makeRequest pageSize paginator = query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" @@ -97,7 +97,7 @@ type Msg type alias Model = -- List RemoteDataResponse { pageSize : Int - , data : PaginatedData Repo String + , data : PaginatedData Repo } diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index e783d61d5..2c4c7e2e7 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -26,10 +26,10 @@ import PrintAny type alias Response = - PaginatedData Stargazer String + PaginatedData Stargazer -query : Int -> PaginatedData Stargazer String -> SelectionSet Response RootQuery +query : Int -> PaginatedData Stargazer -> SelectionSet Response RootQuery query pageSize paginator = Query.repository { owner = "dillonkearns", name = "elm-graphql" } (Repository.stargazersPaginated @@ -56,7 +56,7 @@ stargazerSelection = Github.Object.StargazerEdge.starredAt -makeRequest : Int -> PaginatedData Stargazer String -> Cmd Msg +makeRequest : Int -> PaginatedData Stargazer -> Cmd Msg makeRequest pageSize paginator = query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" @@ -73,7 +73,7 @@ type Msg type alias Model = -- List RemoteDataResponse { pageSize : Int - , paginator : PaginatedData Stargazer String + , paginator : PaginatedData Stargazer } diff --git a/src/Graphql/Internal/Paginator.elm b/src/Graphql/Internal/Paginator.elm index 0016d6b68..eeb7c7930 100644 --- a/src/Graphql/Internal/Paginator.elm +++ b/src/Graphql/Internal/Paginator.elm @@ -12,9 +12,9 @@ import Json.Decode as Decode selectionSet : Int - -> PaginatedData decodesTo String + -> PaginatedData decodesTo -> SelectionSet (List decodesTo) typeLock - -> SelectionSet (PaginatedData decodesTo String) typeLock + -> SelectionSet (PaginatedData decodesTo) typeLock selectionSet pageSize paginator selection = Graphql.SelectionSet.map3 PaginatedData (selection |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) @@ -22,7 +22,7 @@ selectionSet pageSize paginator selection = (Graphql.SelectionSet.succeed paginator.direction) -fromSetup : Direction -> SelectionSet (CurrentPage String) connection +fromSetup : Direction -> SelectionSet CurrentPage connection fromSetup paginatorSetup = let object_ = diff --git a/src/Graphql/Pagination.elm b/src/Graphql/Pagination.elm index fcd0152dd..fcab89db0 100644 --- a/src/Graphql/Pagination.elm +++ b/src/Graphql/Pagination.elm @@ -3,7 +3,7 @@ module Graphql.Pagination exposing (CurrentPage, Direction(..), PageInfo, Pagina import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -init : Direction -> List data -> PaginatedData data cursor +init : Direction -> List data -> PaginatedData data init direction initialData = { data = initialData , currentPage = { cursor = Nothing, isLoading = True } @@ -11,9 +11,9 @@ init direction initialData = } -type alias PaginatedData data cursor = +type alias PaginatedData data = { data : List data - , currentPage : CurrentPage cursor + , currentPage : CurrentPage , direction : Direction } @@ -52,7 +52,7 @@ type Direction | Backward -type alias CurrentPage cursorType = - { cursor : Maybe cursorType +type alias CurrentPage = + { cursor : Maybe String , isLoading : Bool } From 837a91d5f049c169530b132983d5bd58b57dd3bd Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 12:56:59 +0100 Subject: [PATCH 41/83] Rename module. --- examples/src/Github/Object/PageInfo.elm | 2 +- examples/src/Github/Object/Repository.elm | 4 ++-- examples/src/Github/Query.elm | 4 ++-- examples/src/GithubPagination.elm | 2 +- examples/src/GithubPagination2.elm | 4 ++-- src/Graphql/Internal/Paginator.elm | 2 +- src/Graphql/{Pagination.elm => PaginatedData.elm} | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) rename src/Graphql/{Pagination.elm => PaginatedData.elm} (92%) diff --git a/examples/src/Github/Object/PageInfo.elm b/examples/src/Github/Object/PageInfo.elm index bfbcdd357..c2e5a9acf 100644 --- a/examples/src/Github/Object/PageInfo.elm +++ b/examples/src/Github/Object/PageInfo.elm @@ -15,7 +15,7 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Pagination exposing (CurrentPage, Direction(..)) +import Graphql.PaginatedData exposing (CurrentPage, Direction(..)) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index acf037acb..ee5930ff6 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -27,7 +27,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.PaginatedData as PaginatedData exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode @@ -990,7 +990,7 @@ stargazersPaginated : -> SelectionSet decodesTo Github.Object.StargazerEdge -> SelectionSet (PaginatedData decodesTo) Github.Object.Repository stargazersPaginated pageSize paginator fillInOptionals object_ = - stargazers (fillInOptionals >> Pagination.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) + stargazers (fillInOptionals >> PaginatedData.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) (Graphql.Internal.Paginator.selectionSet pageSize paginator (stargazerEdges object_)) diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index 236c60d9f..aa4f3ed9a 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -17,7 +17,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.PaginatedData as PaginatedData exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode exposing (Decoder) @@ -340,7 +340,7 @@ searchPaginated : -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection -> SelectionSet (PaginatedData decodesTo) RootQuery searchPaginated pageSize paginator fillInOptionals requiredArgs object_ = - search (fillInOptionals >> Pagination.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) + search (fillInOptionals >> PaginatedData.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) requiredArgs (Graphql.Internal.Paginator.selectionSet pageSize paginator object_) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 0ab18d783..f756af57d 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -16,7 +16,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.PaginatedData as Pagination exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 2c4c7e2e7..1a5df0582 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -18,7 +18,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.PaginatedData as PaginatedData exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (Html, button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) @@ -83,7 +83,7 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = - Pagination.init Backward [] + PaginatedData.init Backward [] |> (\paginator -> ( { pageSize = 1 , paginator = paginator diff --git a/src/Graphql/Internal/Paginator.elm b/src/Graphql/Internal/Paginator.elm index eeb7c7930..224be5199 100644 --- a/src/Graphql/Internal/Paginator.elm +++ b/src/Graphql/Internal/Paginator.elm @@ -5,7 +5,7 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Pagination as Pagination exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.PaginatedData as PaginatedData exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode diff --git a/src/Graphql/Pagination.elm b/src/Graphql/PaginatedData.elm similarity index 92% rename from src/Graphql/Pagination.elm rename to src/Graphql/PaginatedData.elm index fcab89db0..f66cae2c8 100644 --- a/src/Graphql/Pagination.elm +++ b/src/Graphql/PaginatedData.elm @@ -1,4 +1,4 @@ -module Graphql.Pagination exposing (CurrentPage, Direction(..), PageInfo, PaginatedData, addPageInfo, init) +module Graphql.PaginatedData exposing (CurrentPage, Direction(..), PageInfo, PaginatedData, addPageInfo, init) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) From 77c538cef5a509196fd129eb7972223009ccd36b Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 12:59:40 +0100 Subject: [PATCH 42/83] Rename custom type variants. --- examples/src/GithubPagination2.elm | 2 +- src/Graphql/Internal/Paginator.elm | 4 ++-- src/Graphql/PaginatedData.elm | 16 ++++++++++++---- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 1a5df0582..97b31c19e 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -83,7 +83,7 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = - PaginatedData.init Backward [] + PaginatedData.init PaginateBackward [] |> (\paginator -> ( { pageSize = 1 , paginator = paginator diff --git a/src/Graphql/Internal/Paginator.elm b/src/Graphql/Internal/Paginator.elm index 224be5199..2bf37e86e 100644 --- a/src/Graphql/Internal/Paginator.elm +++ b/src/Graphql/Internal/Paginator.elm @@ -27,12 +27,12 @@ fromSetup paginatorSetup = let object_ = case paginatorSetup of - Forward -> + PaginateForward -> Graphql.SelectionSet.map2 CurrentPage endCursor hasNextPage - Backward -> + PaginateBackward -> Graphql.SelectionSet.map2 CurrentPage startCursor hasPreviousPage diff --git a/src/Graphql/PaginatedData.elm b/src/Graphql/PaginatedData.elm index f66cae2c8..3726d9b6f 100644 --- a/src/Graphql/PaginatedData.elm +++ b/src/Graphql/PaginatedData.elm @@ -32,24 +32,32 @@ type alias PageInfo pageInfo cursor = addPageInfo : Int -> Maybe cursor -> Direction -> PageInfo pageInfo cursor -> PageInfo pageInfo cursor addPageInfo pageSize maybeCursor paginationSetup optionals = case paginationSetup of - Forward -> + PaginateForward -> { optionals | first = Present pageSize , after = OptionalArgument.fromMaybe maybeCursor } - Backward -> + PaginateBackward -> { optionals | last = Present pageSize , before = OptionalArgument.fromMaybe maybeCursor } +type Forward + = Forward + + +type Backward + = Backward + + {-| Uses [the relay protocol](https://facebook.github.io/relay/graphql/connections.htm). -} type Direction - = Forward - | Backward + = PaginateForward + | PaginateBackward type alias CurrentPage = From 2e3108a5d11b801cf78ce5e3fb788e545c3dc848 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 13:01:36 +0100 Subject: [PATCH 43/83] Create forward constructor for PagiantedData. --- examples/src/GithubPagination.elm | 8 ++------ examples/src/GithubPagination2.elm | 2 +- src/Graphql/PaginatedData.elm | 10 +++++----- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index f756af57d..5ac2145da 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -16,7 +16,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatedData as Pagination exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.PaginatedData as PaginatedData exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) @@ -29,10 +29,6 @@ type alias Response = query : Int -> PaginatedData Repo -> SelectionSet Response RootQuery query pageSize paginator = - let - setup = - Forward - in Query.searchPaginated pageSize paginator identity @@ -115,7 +111,7 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = - Pagination.init Forward [] + PaginatedData.forward |> (\paginator -> ( { pageSize = 1 , data = paginator diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 97b31c19e..d56f34432 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -83,7 +83,7 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = - PaginatedData.init PaginateBackward [] + PaginatedData.forward |> (\paginator -> ( { pageSize = 1 , paginator = paginator diff --git a/src/Graphql/PaginatedData.elm b/src/Graphql/PaginatedData.elm index 3726d9b6f..d2d6e605d 100644 --- a/src/Graphql/PaginatedData.elm +++ b/src/Graphql/PaginatedData.elm @@ -1,13 +1,13 @@ -module Graphql.PaginatedData exposing (CurrentPage, Direction(..), PageInfo, PaginatedData, addPageInfo, init) +module Graphql.PaginatedData exposing (CurrentPage, Direction(..), PageInfo, PaginatedData, addPageInfo, forward) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -init : Direction -> List data -> PaginatedData data -init direction initialData = - { data = initialData +forward : PaginatedData data +forward = + { data = [] , currentPage = { cursor = Nothing, isLoading = True } - , direction = direction + , direction = PaginateForward } From e6e5a7fadaaa237c3d0a89d5db58288c616efa1a Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 13:02:18 +0100 Subject: [PATCH 44/83] Create backward paginator constructor. --- src/Graphql/PaginatedData.elm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Graphql/PaginatedData.elm b/src/Graphql/PaginatedData.elm index d2d6e605d..984e9e8d4 100644 --- a/src/Graphql/PaginatedData.elm +++ b/src/Graphql/PaginatedData.elm @@ -1,4 +1,4 @@ -module Graphql.PaginatedData exposing (CurrentPage, Direction(..), PageInfo, PaginatedData, addPageInfo, forward) +module Graphql.PaginatedData exposing (CurrentPage, Direction(..), PageInfo, PaginatedData, addPageInfo, backward, forward) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) @@ -11,6 +11,14 @@ forward = } +backward : PaginatedData data +backward = + { data = [] + , currentPage = { cursor = Nothing, isLoading = True } + , direction = PaginateBackward + } + + type alias PaginatedData data = { data : List data , currentPage : CurrentPage From a9382d042183bfa4f27f0abf692dec6147b247a4 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 04:33:03 -0800 Subject: [PATCH 45/83] Use Custom Type to represent PaginatedData. --- examples/src/Github/Object/PageInfo.elm | 59 ------------------ examples/src/Github/Object/Repository.elm | 6 +- examples/src/Github/Query.elm | 6 +- examples/src/GithubPagination2.elm | 10 ++-- src/Graphql/Internal/Paginator.elm | 43 +++++++------ src/Graphql/PaginatedData.elm | 73 +++++++++++++++-------- 6 files changed, 80 insertions(+), 117 deletions(-) delete mode 100644 examples/src/Github/Object/PageInfo.elm diff --git a/examples/src/Github/Object/PageInfo.elm b/examples/src/Github/Object/PageInfo.elm deleted file mode 100644 index c2e5a9acf..000000000 --- a/examples/src/Github/Object/PageInfo.elm +++ /dev/null @@ -1,59 +0,0 @@ --- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql --- https://github.com/dillonkearns/elm-graphql - - -module Github.Object.PageInfo exposing (endCursor, fromSetup, hasNextPage, hasPreviousPage, startCursor) - -import Github.InputObject -import Github.Interface -import Github.Object -import Github.Scalar -import Github.ScalarCodecs -import Github.Union -import Graphql.Internal.Builder.Argument as Argument exposing (Argument) -import Graphql.Internal.Builder.Object as Object -import Graphql.Internal.Encode as Encode exposing (Value) -import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) -import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatedData exposing (CurrentPage, Direction(..)) -import Graphql.SelectionSet exposing (SelectionSet) -import Json.Decode as Decode - - -fromSetup : Direction -> SelectionSet CurrentPage Github.Object.PageInfo -fromSetup paginatorSetup = - Graphql.SelectionSet.map2 CurrentPage - endCursor - hasNextPage - - - --- SelectionSet.empty - - -{-| When paginating forwards, the cursor to continue. --} -endCursor : SelectionSet (Maybe String) Github.Object.PageInfo -endCursor = - Object.selectionForField "(Maybe String)" "endCursor" [] (Decode.string |> Decode.nullable) - - -{-| When paginating forwards, are there more items? --} -hasNextPage : SelectionSet Bool Github.Object.PageInfo -hasNextPage = - Object.selectionForField "Bool" "hasNextPage" [] Decode.bool - - -{-| When paginating backwards, are there more items? --} -hasPreviousPage : SelectionSet Bool Github.Object.PageInfo -hasPreviousPage = - Object.selectionForField "Bool" "hasPreviousPage" [] Decode.bool - - -{-| When paginating backwards, the cursor to continue. --} -startCursor : SelectionSet (Maybe String) Github.Object.PageInfo -startCursor = - Object.selectionForField "(Maybe String)" "startCursor" [] (Decode.string |> Decode.nullable) diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index ee5930ff6..69eed5513 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -27,7 +27,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatedData as PaginatedData exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.PaginatedData as PaginatedData exposing (Direction(..), PaginatedData) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode @@ -990,8 +990,8 @@ stargazersPaginated : -> SelectionSet decodesTo Github.Object.StargazerEdge -> SelectionSet (PaginatedData decodesTo) Github.Object.Repository stargazersPaginated pageSize paginator fillInOptionals object_ = - stargazers (fillInOptionals >> PaginatedData.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) - (Graphql.Internal.Paginator.selectionSet pageSize paginator (stargazerEdges object_)) + stargazers (fillInOptionals >> PaginatedData.addPageInfo pageSize paginator) + (PaginatedData.selectionSet pageSize paginator (stargazerEdges object_)) stargazerEdges : SelectionSet decodesTo Github.Object.StargazerEdge -> SelectionSet (List decodesTo) Github.Object.StargazerConnection diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index aa4f3ed9a..e38e95093 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -17,7 +17,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatedData as PaginatedData exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.PaginatedData as PaginatedData exposing (Direction(..), PaginatedData) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode exposing (Decoder) @@ -340,9 +340,9 @@ searchPaginated : -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection -> SelectionSet (PaginatedData decodesTo) RootQuery searchPaginated pageSize paginator fillInOptionals requiredArgs object_ = - search (fillInOptionals >> PaginatedData.addPageInfo pageSize paginator.currentPage.cursor paginator.direction) + search (fillInOptionals >> PaginatedData.addPageInfo pageSize paginator) requiredArgs - (Graphql.Internal.Paginator.selectionSet pageSize paginator object_) + (PaginatedData.selectionSet pageSize paginator object_) type alias TopicRequiredArguments = diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index d56f34432..f720b7729 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -3,7 +3,6 @@ module GithubPagination2 exposing (main) import Browser import Github.Enum.SearchType import Github.Object -import Github.Object.PageInfo import Github.Object.Repository as Repository import Github.Object.SearchResultItemConnection import Github.Object.SearchResultItemEdge @@ -18,7 +17,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatedData as PaginatedData exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.PaginatedData as PaginatedData exposing (Direction(..), PaginatedData) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (Html, button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) @@ -108,7 +107,7 @@ view model = ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view (model.paginator.data |> List.reverse) + , PrintAny.view (model.paginator |> PaginatedData.data |> List.reverse) ] ] @@ -117,7 +116,8 @@ paginationDetailsView : Model -> Html msg paginationDetailsView model = div [] [ "Loaded " - ++ (model.paginator.data + ++ (model.paginator + |> PaginatedData.data |> List.length |> String.fromInt ) @@ -129,7 +129,7 @@ paginationDetailsView model = doneView model = Html.text - (if model.paginator.currentPage.isLoading then + (if model.paginator |> PaginatedData.moreToLoad then "..." else diff --git a/src/Graphql/Internal/Paginator.elm b/src/Graphql/Internal/Paginator.elm index 2bf37e86e..e5233eb47 100644 --- a/src/Graphql/Internal/Paginator.elm +++ b/src/Graphql/Internal/Paginator.elm @@ -1,41 +1,38 @@ -module Graphql.Internal.Paginator exposing (fromSetup, selectionSet) +module Graphql.Internal.Paginator exposing (CurrentPage, backwardSelection, forwardSelection) import Graphql.Internal.Builder.Argument as Argument exposing (Argument) import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatedData as PaginatedData exposing (CurrentPage, Direction(..), PaginatedData) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode -selectionSet : - Int - -> PaginatedData decodesTo - -> SelectionSet (List decodesTo) typeLock - -> SelectionSet (PaginatedData decodesTo) typeLock -selectionSet pageSize paginator selection = - Graphql.SelectionSet.map3 PaginatedData - (selection |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) - (fromSetup paginator.direction) - (Graphql.SelectionSet.succeed paginator.direction) +type alias CurrentPage = + { cursor : Maybe String + , isLoading : Bool + } -fromSetup : Direction -> SelectionSet CurrentPage connection -fromSetup paginatorSetup = +forwardSelection : SelectionSet CurrentPage connection +forwardSelection = let object_ = - case paginatorSetup of - PaginateForward -> - Graphql.SelectionSet.map2 CurrentPage - endCursor - hasNextPage + Graphql.SelectionSet.map2 CurrentPage + endCursor + hasNextPage + in + Object.selectionForCompositeField "pageInfo" [] object_ identity + - PaginateBackward -> - Graphql.SelectionSet.map2 CurrentPage - startCursor - hasPreviousPage +backwardSelection : SelectionSet CurrentPage connection +backwardSelection = + let + object_ = + Graphql.SelectionSet.map2 CurrentPage + startCursor + hasPreviousPage in Object.selectionForCompositeField "pageInfo" [] object_ identity diff --git a/src/Graphql/PaginatedData.elm b/src/Graphql/PaginatedData.elm index 984e9e8d4..f280e9b0f 100644 --- a/src/Graphql/PaginatedData.elm +++ b/src/Graphql/PaginatedData.elm @@ -1,55 +1,86 @@ -module Graphql.PaginatedData exposing (CurrentPage, Direction(..), PageInfo, PaginatedData, addPageInfo, backward, forward) +module Graphql.PaginatedData exposing (Direction(..), PageInfo, PaginatedData, addPageInfo, backward, data, forward, moreToLoad, selectionSet) +import Graphql.Internal.Paginator exposing (CurrentPage) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) +import Graphql.SelectionSet exposing (SelectionSet) + + +moreToLoad : PaginatedData data -> Bool +moreToLoad (PaginatedData paginator) = + paginator.currentPage.isLoading + + +data : PaginatedData data -> List data +data (PaginatedData paginator) = + paginator.data forward : PaginatedData data forward = - { data = [] - , currentPage = { cursor = Nothing, isLoading = True } - , direction = PaginateForward - } + PaginatedData + { data = [] + , currentPage = { cursor = Nothing, isLoading = True } + , direction = PaginateForward + } backward : PaginatedData data backward = - { data = [] - , currentPage = { cursor = Nothing, isLoading = True } - , direction = PaginateBackward - } + PaginatedData + { data = [] + , currentPage = { cursor = Nothing, isLoading = True } + , direction = PaginateBackward + } + +selectionSet : + Int + -> PaginatedData decodesTo + -> SelectionSet (List decodesTo) typeLock + -> SelectionSet (PaginatedData decodesTo) typeLock +selectionSet pageSize (PaginatedData paginator) selection = + Graphql.SelectionSet.map3 PaginatedDataRecord + (selection |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) + Graphql.Internal.Paginator.forwardSelection + (Graphql.SelectionSet.succeed paginator.direction) + |> Graphql.SelectionSet.map PaginatedData -type alias PaginatedData data = + +type PaginatedData data + = PaginatedData (PaginatedDataRecord data) + + +type alias PaginatedDataRecord data = { data : List data , currentPage : CurrentPage , direction : Direction } -type alias PageInfo pageInfo cursor = +type alias PageInfo pageInfo = { pageInfo | first : OptionalArgument Int , last : OptionalArgument Int - , before : OptionalArgument cursor - , after : OptionalArgument cursor + , before : OptionalArgument String + , after : OptionalArgument String } {-| TODO -} -addPageInfo : Int -> Maybe cursor -> Direction -> PageInfo pageInfo cursor -> PageInfo pageInfo cursor -addPageInfo pageSize maybeCursor paginationSetup optionals = - case paginationSetup of +addPageInfo : Int -> PaginatedData data -> PageInfo pageInfo -> PageInfo pageInfo +addPageInfo pageSize (PaginatedData paginator) optionals = + case paginator.direction of PaginateForward -> { optionals | first = Present pageSize - , after = OptionalArgument.fromMaybe maybeCursor + , after = OptionalArgument.fromMaybe paginator.currentPage.cursor } PaginateBackward -> { optionals | last = Present pageSize - , before = OptionalArgument.fromMaybe maybeCursor + , before = OptionalArgument.fromMaybe paginator.currentPage.cursor } @@ -66,9 +97,3 @@ type Backward type Direction = PaginateForward | PaginateBackward - - -type alias CurrentPage = - { cursor : Maybe String - , isLoading : Bool - } From d89c8eeb38678946d9d7dc753f11178e62c48835 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 04:34:39 -0800 Subject: [PATCH 46/83] Rename PaginatedData to Paginator. --- examples/src/Github/Object/Repository.elm | 10 ++--- examples/src/Github/Query.elm | 10 ++--- examples/src/GithubPagination.elm | 12 +++--- examples/src/GithubPagination2.elm | 18 ++++----- .../{PaginatedData.elm => Paginator.elm} | 38 +++++++++---------- 5 files changed, 44 insertions(+), 44 deletions(-) rename src/Graphql/{PaginatedData.elm => Paginator.elm} (66%) diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index 69eed5513..a282ad00d 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -27,7 +27,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatedData as PaginatedData exposing (Direction(..), PaginatedData) +import Graphql.Paginator as Paginator exposing (Direction(..), Paginator) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode @@ -985,13 +985,13 @@ stargazers fillInOptionals object_ = stargazersPaginated : Int - -> PaginatedData decodesTo + -> Paginator decodesTo -> (StargazersOptionalArguments -> StargazersOptionalArguments) -> SelectionSet decodesTo Github.Object.StargazerEdge - -> SelectionSet (PaginatedData decodesTo) Github.Object.Repository + -> SelectionSet (Paginator decodesTo) Github.Object.Repository stargazersPaginated pageSize paginator fillInOptionals object_ = - stargazers (fillInOptionals >> PaginatedData.addPageInfo pageSize paginator) - (PaginatedData.selectionSet pageSize paginator (stargazerEdges object_)) + stargazers (fillInOptionals >> Paginator.addPageInfo pageSize paginator) + (Paginator.selectionSet pageSize paginator (stargazerEdges object_)) stargazerEdges : SelectionSet decodesTo Github.Object.StargazerEdge -> SelectionSet (List decodesTo) Github.Object.StargazerConnection diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index e38e95093..c2f78ae53 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -17,7 +17,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatedData as PaginatedData exposing (Direction(..), PaginatedData) +import Graphql.Paginator as Paginator exposing (Direction(..), Paginator) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode exposing (Decoder) @@ -334,15 +334,15 @@ search fillInOptionals requiredArgs object_ = searchPaginated : Int - -> PaginatedData decodesTo + -> Paginator decodesTo -> (SearchOptionalArguments -> SearchOptionalArguments) -> SearchRequiredArguments -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection - -> SelectionSet (PaginatedData decodesTo) RootQuery + -> SelectionSet (Paginator decodesTo) RootQuery searchPaginated pageSize paginator fillInOptionals requiredArgs object_ = - search (fillInOptionals >> PaginatedData.addPageInfo pageSize paginator) + search (fillInOptionals >> Paginator.addPageInfo pageSize paginator) requiredArgs - (PaginatedData.selectionSet pageSize paginator object_) + (Paginator.selectionSet pageSize paginator object_) type alias TopicRequiredArguments = diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 5ac2145da..28f94a389 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -16,7 +16,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatedData as PaginatedData exposing (CurrentPage, Direction(..), PaginatedData) +import Graphql.Paginator as Paginator exposing (CurrentPage, Direction(..), Paginator) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) @@ -24,10 +24,10 @@ import PrintAny type alias Response = - PaginatedData Repo + Paginator Repo -query : Int -> PaginatedData Repo -> SelectionSet Response RootQuery +query : Int -> Paginator Repo -> SelectionSet Response RootQuery query pageSize paginator = Query.searchPaginated pageSize paginator @@ -76,7 +76,7 @@ repositorySelection = |> with (Repository.stargazers identity Github.Object.StargazerConnection.totalCount) -makeRequest : Int -> PaginatedData Repo -> Cmd Msg +makeRequest : Int -> Paginator Repo -> Cmd Msg makeRequest pageSize paginator = query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" @@ -93,7 +93,7 @@ type Msg type alias Model = -- List RemoteDataResponse { pageSize : Int - , data : PaginatedData Repo + , data : Paginator Repo } @@ -111,7 +111,7 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = - PaginatedData.forward + Paginator.forward |> (\paginator -> ( { pageSize = 1 , data = paginator diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index f720b7729..7fd0bcb27 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -17,7 +17,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.PaginatedData as PaginatedData exposing (Direction(..), PaginatedData) +import Graphql.Paginator as Paginator exposing (Direction(..), Paginator) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (Html, button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) @@ -25,10 +25,10 @@ import PrintAny type alias Response = - PaginatedData Stargazer + Paginator Stargazer -query : Int -> PaginatedData Stargazer -> SelectionSet Response RootQuery +query : Int -> Paginator Stargazer -> SelectionSet Response RootQuery query pageSize paginator = Query.repository { owner = "dillonkearns", name = "elm-graphql" } (Repository.stargazersPaginated @@ -55,7 +55,7 @@ stargazerSelection = Github.Object.StargazerEdge.starredAt -makeRequest : Int -> PaginatedData Stargazer -> Cmd Msg +makeRequest : Int -> Paginator Stargazer -> Cmd Msg makeRequest pageSize paginator = query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" @@ -72,7 +72,7 @@ type Msg type alias Model = -- List RemoteDataResponse { pageSize : Int - , paginator : PaginatedData Stargazer + , paginator : Paginator Stargazer } @@ -82,7 +82,7 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = - PaginatedData.forward + Paginator.forward |> (\paginator -> ( { pageSize = 1 , paginator = paginator @@ -107,7 +107,7 @@ view model = ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view (model.paginator |> PaginatedData.data |> List.reverse) + , PrintAny.view (model.paginator |> Paginator.data |> List.reverse) ] ] @@ -117,7 +117,7 @@ paginationDetailsView model = div [] [ "Loaded " ++ (model.paginator - |> PaginatedData.data + |> Paginator.data |> List.length |> String.fromInt ) @@ -129,7 +129,7 @@ paginationDetailsView model = doneView model = Html.text - (if model.paginator |> PaginatedData.moreToLoad then + (if model.paginator |> Paginator.moreToLoad then "..." else diff --git a/src/Graphql/PaginatedData.elm b/src/Graphql/Paginator.elm similarity index 66% rename from src/Graphql/PaginatedData.elm rename to src/Graphql/Paginator.elm index f280e9b0f..9dbe17ed9 100644 --- a/src/Graphql/PaginatedData.elm +++ b/src/Graphql/Paginator.elm @@ -1,32 +1,32 @@ -module Graphql.PaginatedData exposing (Direction(..), PageInfo, PaginatedData, addPageInfo, backward, data, forward, moreToLoad, selectionSet) +module Graphql.Paginator exposing (Direction(..), PageInfo, Paginator, addPageInfo, backward, data, forward, moreToLoad, selectionSet) import Graphql.Internal.Paginator exposing (CurrentPage) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) import Graphql.SelectionSet exposing (SelectionSet) -moreToLoad : PaginatedData data -> Bool -moreToLoad (PaginatedData paginator) = +moreToLoad : Paginator data -> Bool +moreToLoad (Paginator paginator) = paginator.currentPage.isLoading -data : PaginatedData data -> List data -data (PaginatedData paginator) = +data : Paginator data -> List data +data (Paginator paginator) = paginator.data -forward : PaginatedData data +forward : Paginator data forward = - PaginatedData + Paginator { data = [] , currentPage = { cursor = Nothing, isLoading = True } , direction = PaginateForward } -backward : PaginatedData data +backward : Paginator data backward = - PaginatedData + Paginator { data = [] , currentPage = { cursor = Nothing, isLoading = True } , direction = PaginateBackward @@ -35,22 +35,22 @@ backward = selectionSet : Int - -> PaginatedData decodesTo + -> Paginator decodesTo -> SelectionSet (List decodesTo) typeLock - -> SelectionSet (PaginatedData decodesTo) typeLock -selectionSet pageSize (PaginatedData paginator) selection = - Graphql.SelectionSet.map3 PaginatedDataRecord + -> SelectionSet (Paginator decodesTo) typeLock +selectionSet pageSize (Paginator paginator) selection = + Graphql.SelectionSet.map3 PaginatorRecord (selection |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) Graphql.Internal.Paginator.forwardSelection (Graphql.SelectionSet.succeed paginator.direction) - |> Graphql.SelectionSet.map PaginatedData + |> Graphql.SelectionSet.map Paginator -type PaginatedData data - = PaginatedData (PaginatedDataRecord data) +type Paginator data + = Paginator (PaginatorRecord data) -type alias PaginatedDataRecord data = +type alias PaginatorRecord data = { data : List data , currentPage : CurrentPage , direction : Direction @@ -68,8 +68,8 @@ type alias PageInfo pageInfo = {-| TODO -} -addPageInfo : Int -> PaginatedData data -> PageInfo pageInfo -> PageInfo pageInfo -addPageInfo pageSize (PaginatedData paginator) optionals = +addPageInfo : Int -> Paginator data -> PageInfo pageInfo -> PageInfo pageInfo +addPageInfo pageSize (Paginator paginator) optionals = case paginator.direction of PaginateForward -> { optionals From 2719e3fbee07e84cbfcadb09370352cdc0ea3ee7 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 04:41:23 -0800 Subject: [PATCH 47/83] Add phantom type to allow limiting arguments to only one direction in generated code. --- examples/src/Github/Object/Repository.elm | 4 ++-- examples/src/Github/Query.elm | 6 +++--- examples/src/GithubPagination2.elm | 8 ++++---- src/Graphql/Paginator.elm | 18 +++++++++--------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index a282ad00d..48b01cf07 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -985,10 +985,10 @@ stargazers fillInOptionals object_ = stargazersPaginated : Int - -> Paginator decodesTo + -> Paginator direction decodesTo -> (StargazersOptionalArguments -> StargazersOptionalArguments) -> SelectionSet decodesTo Github.Object.StargazerEdge - -> SelectionSet (Paginator decodesTo) Github.Object.Repository + -> SelectionSet (Paginator direction decodesTo) Github.Object.Repository stargazersPaginated pageSize paginator fillInOptionals object_ = stargazers (fillInOptionals >> Paginator.addPageInfo pageSize paginator) (Paginator.selectionSet pageSize paginator (stargazerEdges object_)) diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index c2f78ae53..27dff73b7 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -17,7 +17,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Paginator as Paginator exposing (Direction(..), Paginator) +import Graphql.Paginator as Paginator exposing (Backward, Direction(..), Forward, Paginator) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode exposing (Decoder) @@ -334,11 +334,11 @@ search fillInOptionals requiredArgs object_ = searchPaginated : Int - -> Paginator decodesTo + -> Paginator direction decodesTo -> (SearchOptionalArguments -> SearchOptionalArguments) -> SearchRequiredArguments -> SelectionSet (List decodesTo) Github.Object.SearchResultItemConnection - -> SelectionSet (Paginator decodesTo) RootQuery + -> SelectionSet (Paginator direction decodesTo) RootQuery searchPaginated pageSize paginator fillInOptionals requiredArgs object_ = search (fillInOptionals >> Paginator.addPageInfo pageSize paginator) requiredArgs diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 7fd0bcb27..69532db1b 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -25,10 +25,10 @@ import PrintAny type alias Response = - Paginator Stargazer + Paginator Paginator.Forward Stargazer -query : Int -> Paginator Stargazer -> SelectionSet Response RootQuery +query : Int -> Paginator Paginator.Forward Stargazer -> SelectionSet Response RootQuery query pageSize paginator = Query.repository { owner = "dillonkearns", name = "elm-graphql" } (Repository.stargazersPaginated @@ -55,7 +55,7 @@ stargazerSelection = Github.Object.StargazerEdge.starredAt -makeRequest : Int -> Paginator Stargazer -> Cmd Msg +makeRequest : Int -> Paginator Paginator.Forward Stargazer -> Cmd Msg makeRequest pageSize paginator = query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" @@ -72,7 +72,7 @@ type Msg type alias Model = -- List RemoteDataResponse { pageSize : Int - , paginator : Paginator Stargazer + , paginator : Paginator Paginator.Forward Stargazer } diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index 9dbe17ed9..de48a93ac 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -1,21 +1,21 @@ -module Graphql.Paginator exposing (Direction(..), PageInfo, Paginator, addPageInfo, backward, data, forward, moreToLoad, selectionSet) +module Graphql.Paginator exposing (Backward, Direction(..), Forward, PageInfo, Paginator, addPageInfo, backward, data, forward, moreToLoad, selectionSet) import Graphql.Internal.Paginator exposing (CurrentPage) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) import Graphql.SelectionSet exposing (SelectionSet) -moreToLoad : Paginator data -> Bool +moreToLoad : Paginator direction data -> Bool moreToLoad (Paginator paginator) = paginator.currentPage.isLoading -data : Paginator data -> List data +data : Paginator direction data -> List data data (Paginator paginator) = paginator.data -forward : Paginator data +forward : Paginator Forward data forward = Paginator { data = [] @@ -24,7 +24,7 @@ forward = } -backward : Paginator data +backward : Paginator Backward data backward = Paginator { data = [] @@ -35,9 +35,9 @@ backward = selectionSet : Int - -> Paginator decodesTo + -> Paginator direction decodesTo -> SelectionSet (List decodesTo) typeLock - -> SelectionSet (Paginator decodesTo) typeLock + -> SelectionSet (Paginator direction decodesTo) typeLock selectionSet pageSize (Paginator paginator) selection = Graphql.SelectionSet.map3 PaginatorRecord (selection |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) @@ -46,7 +46,7 @@ selectionSet pageSize (Paginator paginator) selection = |> Graphql.SelectionSet.map Paginator -type Paginator data +type Paginator direction data = Paginator (PaginatorRecord data) @@ -68,7 +68,7 @@ type alias PageInfo pageInfo = {-| TODO -} -addPageInfo : Int -> Paginator data -> PageInfo pageInfo -> PageInfo pageInfo +addPageInfo : Int -> Paginator direction data -> PageInfo pageInfo -> PageInfo pageInfo addPageInfo pageSize (Paginator paginator) optionals = case paginator.direction of PaginateForward -> From 9ecdef10c3b0dcdc2626ab30d452e19b776b1368 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 04:50:09 -0800 Subject: [PATCH 48/83] Reorder file. --- src/Graphql/Paginator.elm | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index de48a93ac..d1d685681 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -5,14 +5,15 @@ import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(. import Graphql.SelectionSet exposing (SelectionSet) -moreToLoad : Paginator direction data -> Bool -moreToLoad (Paginator paginator) = - paginator.currentPage.isLoading +type Paginator direction data + = Paginator (PaginatorRecord data) -data : Paginator direction data -> List data -data (Paginator paginator) = - paginator.data +type alias PaginatorRecord data = + { data : List data + , currentPage : CurrentPage + , direction : Direction + } forward : Paginator Forward data @@ -33,6 +34,16 @@ backward = } +moreToLoad : Paginator direction data -> Bool +moreToLoad (Paginator paginator) = + paginator.currentPage.isLoading + + +data : Paginator direction data -> List data +data (Paginator paginator) = + paginator.data + + selectionSet : Int -> Paginator direction decodesTo @@ -46,17 +57,6 @@ selectionSet pageSize (Paginator paginator) selection = |> Graphql.SelectionSet.map Paginator -type Paginator direction data - = Paginator (PaginatorRecord data) - - -type alias PaginatorRecord data = - { data : List data - , currentPage : CurrentPage - , direction : Direction - } - - type alias PageInfo pageInfo = { pageInfo | first : OptionalArgument Int From 40a33b826ca485fb0f38b66b58695d8878a163d6 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 05:04:54 -0800 Subject: [PATCH 49/83] Use direction in new paginator selection set. --- src/Graphql/Paginator.elm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index d1d685681..f8c343739 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -52,7 +52,13 @@ selectionSet : selectionSet pageSize (Paginator paginator) selection = Graphql.SelectionSet.map3 PaginatorRecord (selection |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) - Graphql.Internal.Paginator.forwardSelection + (case paginator.direction of + PaginateForward -> + Graphql.Internal.Paginator.forwardSelection + + PaginateBackward -> + Graphql.Internal.Paginator.backwardSelection + ) (Graphql.SelectionSet.succeed paginator.direction) |> Graphql.SelectionSet.map Paginator From e9d81f5f636c1a19d1762fd03cc3fcc89f9f2dcb Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 24 Feb 2019 05:05:10 -0800 Subject: [PATCH 50/83] Remove comment. --- examples/src/GithubPagination2.elm | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 69532db1b..56d0e046a 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -70,7 +70,6 @@ type Msg type alias Model = - -- List RemoteDataResponse { pageSize : Int , paginator : Paginator Paginator.Forward Stargazer } From a776f836e4bc053035de24fc289d8bb2c0df17e3 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 03:42:18 -0800 Subject: [PATCH 51/83] Fix error in example. --- examples/src/GithubPagination.elm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 28f94a389..59f2b45fd 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -3,7 +3,6 @@ module GithubPagination exposing (main) import Browser import Github.Enum.SearchType import Github.Object -import Github.Object.PageInfo import Github.Object.Repository as Repository import Github.Object.SearchResultItemConnection import Github.Object.SearchResultItemEdge @@ -16,7 +15,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Paginator as Paginator exposing (CurrentPage, Direction(..), Paginator) +import Graphql.Paginator as Paginator exposing (Direction(..), Paginator) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) @@ -24,10 +23,10 @@ import PrintAny type alias Response = - Paginator Repo + Paginator Paginator.Forward Repo -query : Int -> Paginator Repo -> SelectionSet Response RootQuery +query : Int -> Paginator Paginator.Forward Repo -> SelectionSet Response RootQuery query pageSize paginator = Query.searchPaginated pageSize paginator @@ -76,7 +75,7 @@ repositorySelection = |> with (Repository.stargazers identity Github.Object.StargazerConnection.totalCount) -makeRequest : Int -> Paginator Repo -> Cmd Msg +makeRequest : Int -> Paginator Paginator.Forward Repo -> Cmd Msg makeRequest pageSize paginator = query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" @@ -93,7 +92,7 @@ type Msg type alias Model = -- List RemoteDataResponse { pageSize : Int - , data : Paginator Repo + , data : Paginator Paginator.Forward Repo } @@ -135,7 +134,7 @@ view model = ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view (model.data.data |> List.reverse) + , PrintAny.view (model.data |> Paginator.data |> List.reverse) ] ] From ce1e5a73f8192435b029b993f319b4c0b0230104 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 03:43:45 -0800 Subject: [PATCH 52/83] Remove exposed low-level type. --- examples/src/Github/Object/Repository.elm | 2 +- examples/src/Github/Query.elm | 2 +- examples/src/GithubPagination.elm | 2 +- examples/src/GithubPagination2.elm | 2 +- src/Graphql/Paginator.elm | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index 48b01cf07..307de395d 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -27,7 +27,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Paginator as Paginator exposing (Direction(..), Paginator) +import Graphql.Paginator as Paginator exposing (Paginator) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode diff --git a/examples/src/Github/Query.elm b/examples/src/Github/Query.elm index 27dff73b7..e1b448d5a 100644 --- a/examples/src/Github/Query.elm +++ b/examples/src/Github/Query.elm @@ -17,7 +17,7 @@ import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Internal.Paginator import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Paginator as Paginator exposing (Backward, Direction(..), Forward, Paginator) +import Graphql.Paginator as Paginator exposing (Backward, Forward, Paginator) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode exposing (Decoder) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 59f2b45fd..f1b728d5b 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -15,7 +15,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Paginator as Paginator exposing (Direction(..), Paginator) +import Graphql.Paginator as Paginator exposing (Paginator) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 56d0e046a..1a2f03b16 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -17,7 +17,7 @@ import Graphql.Document as Document import Graphql.Http import Graphql.Operation exposing (RootQuery) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) -import Graphql.Paginator as Paginator exposing (Direction(..), Paginator) +import Graphql.Paginator as Paginator exposing (Paginator) import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, with) import Html exposing (Html, button, div, h1, input, p, pre, text) import Html.Events exposing (onClick) diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index f8c343739..62fc92d4a 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -1,4 +1,4 @@ -module Graphql.Paginator exposing (Backward, Direction(..), Forward, PageInfo, Paginator, addPageInfo, backward, data, forward, moreToLoad, selectionSet) +module Graphql.Paginator exposing (Backward, Forward, PageInfo, Paginator, addPageInfo, backward, data, forward, moreToLoad, selectionSet) import Graphql.Internal.Paginator exposing (CurrentPage) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) From e7548d34e741f2c2ef33e905eeed7c2a857a195c Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 03:44:48 -0800 Subject: [PATCH 53/83] Rename internal types. --- src/Graphql/Paginator.elm | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index 62fc92d4a..f1cf65800 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -21,7 +21,7 @@ forward = Paginator { data = [] , currentPage = { cursor = Nothing, isLoading = True } - , direction = PaginateForward + , direction = Forward } @@ -30,7 +30,7 @@ backward = Paginator { data = [] , currentPage = { cursor = Nothing, isLoading = True } - , direction = PaginateBackward + , direction = Backward } @@ -53,10 +53,10 @@ selectionSet pageSize (Paginator paginator) selection = Graphql.SelectionSet.map3 PaginatorRecord (selection |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) (case paginator.direction of - PaginateForward -> + Forward -> Graphql.Internal.Paginator.forwardSelection - PaginateBackward -> + Backward -> Graphql.Internal.Paginator.backwardSelection ) (Graphql.SelectionSet.succeed paginator.direction) @@ -77,13 +77,13 @@ type alias PageInfo pageInfo = addPageInfo : Int -> Paginator direction data -> PageInfo pageInfo -> PageInfo pageInfo addPageInfo pageSize (Paginator paginator) optionals = case paginator.direction of - PaginateForward -> + Forward -> { optionals | first = Present pageSize , after = OptionalArgument.fromMaybe paginator.currentPage.cursor } - PaginateBackward -> + Backward -> { optionals | last = Present pageSize , before = OptionalArgument.fromMaybe paginator.currentPage.cursor @@ -91,15 +91,15 @@ addPageInfo pageSize (Paginator paginator) optionals = type Forward - = Forward + = ForwardValue type Backward - = Backward + = BackwardValue {-| Uses [the relay protocol](https://facebook.github.io/relay/graphql/connections.htm). -} type Direction - = PaginateForward - | PaginateBackward + = Forward + | Backward From a5f220db7fec5b6a77459033101cc335543f1c64 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 04:06:21 -0800 Subject: [PATCH 54/83] Rename pagination "data" to more domain-appropriate "nodes". --- examples/src/GithubPagination.elm | 2 +- examples/src/GithubPagination2.elm | 14 +++++++------- src/Graphql/Paginator.elm | 25 +++++++++++++++---------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index f1b728d5b..0af8ee88e 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -134,7 +134,7 @@ view model = ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view (model.data |> Paginator.data |> List.reverse) + , PrintAny.view (model.data |> Paginator.nodes |> List.reverse) ] ] diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 1a2f03b16..dde348449 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -25,10 +25,10 @@ import PrintAny type alias Response = - Paginator Paginator.Forward Stargazer + Paginator Paginator.Backward Stargazer -query : Int -> Paginator Paginator.Forward Stargazer -> SelectionSet Response RootQuery +query : Int -> Paginator Paginator.Backward Stargazer -> SelectionSet Response RootQuery query pageSize paginator = Query.repository { owner = "dillonkearns", name = "elm-graphql" } (Repository.stargazersPaginated @@ -55,7 +55,7 @@ stargazerSelection = Github.Object.StargazerEdge.starredAt -makeRequest : Int -> Paginator Paginator.Forward Stargazer -> Cmd Msg +makeRequest : Int -> Paginator Paginator.Backward Stargazer -> Cmd Msg makeRequest pageSize paginator = query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" @@ -71,7 +71,7 @@ type Msg type alias Model = { pageSize : Int - , paginator : Paginator Paginator.Forward Stargazer + , paginator : Paginator Paginator.Backward Stargazer } @@ -81,7 +81,7 @@ type alias RemoteDataResponse = init : Flags -> ( Model, Cmd Msg ) init flags = - Paginator.forward + Paginator.backward |> (\paginator -> ( { pageSize = 1 , paginator = paginator @@ -106,7 +106,7 @@ view model = ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view (model.paginator |> Paginator.data |> List.reverse) + , PrintAny.view (model.paginator |> Paginator.nodes |> List.reverse) ] ] @@ -116,7 +116,7 @@ paginationDetailsView model = div [] [ "Loaded " ++ (model.paginator - |> Paginator.data + |> Paginator.nodes |> List.length |> String.fromInt ) diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index f1cf65800..606987e4c 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -1,4 +1,4 @@ -module Graphql.Paginator exposing (Backward, Forward, PageInfo, Paginator, addPageInfo, backward, data, forward, moreToLoad, selectionSet) +module Graphql.Paginator exposing (Backward, Forward, PageInfo, Paginator, addPageInfo, backward, forward, moreToLoad, nodes, selectionSet) import Graphql.Internal.Paginator exposing (CurrentPage) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) @@ -10,25 +10,25 @@ type Paginator direction data type alias PaginatorRecord data = - { data : List data + { nodes : List data , currentPage : CurrentPage , direction : Direction } -forward : Paginator Forward data +forward : Paginator Forward node forward = Paginator - { data = [] + { nodes = [] , currentPage = { cursor = Nothing, isLoading = True } , direction = Forward } -backward : Paginator Backward data +backward : Paginator Backward node backward = Paginator - { data = [] + { nodes = [] , currentPage = { cursor = Nothing, isLoading = True } , direction = Backward } @@ -39,9 +39,9 @@ moreToLoad (Paginator paginator) = paginator.currentPage.isLoading -data : Paginator direction data -> List data -data (Paginator paginator) = - paginator.data +nodes : Paginator direction node -> List node +nodes (Paginator paginator) = + paginator.nodes selectionSet : @@ -51,7 +51,12 @@ selectionSet : -> SelectionSet (Paginator direction decodesTo) typeLock selectionSet pageSize (Paginator paginator) selection = Graphql.SelectionSet.map3 PaginatorRecord - (selection |> Graphql.SelectionSet.map (\newList -> paginator.data ++ newList)) + (selection + |> Graphql.SelectionSet.map + (\newNodes -> + paginator.nodes ++ newNodes + ) + ) (case paginator.direction of Forward -> Graphql.Internal.Paginator.forwardSelection From a8e6606fb8d607c46db945018b4c6c97021e5621 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 07:51:01 -0800 Subject: [PATCH 55/83] Add test setup for pagination. --- tests/PaginationTests.elm | 66 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 tests/PaginationTests.elm diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm new file mode 100644 index 000000000..729b093cc --- /dev/null +++ b/tests/PaginationTests.elm @@ -0,0 +1,66 @@ +module PaginationTests exposing (all) + +import Dict +import Expect +import Graphql.Document +import Graphql.Http.GraphqlError as GraphqlError +import Graphql.Internal.Builder.Object as Object +import Graphql.Paginator as Paginator exposing (Paginator) +import Graphql.SelectionSet as SelectionSet +import Json.Decode as Decode +import Test exposing (Test, describe, test) + + +all : Test +all = + describe "pagination" + [ test "reverse pagination items are added in correct order" <| + \() -> + """ + { + "data": { + "edges": [ + { + "node": { + "login3832528868": "nickbytes" + }, + "starredAt987198633": "2019-02-24T21:49:48Z" + }, + { + "node": { + "login3832528868": "achou11" + }, + "starredAt987198633": "2019-02-24T23:30:53Z" + }, + { + "node": { + "login3832528868": "boxtim" + }, + "starredAt987198633": "2019-02-25T00:26:03Z" + } + ], + "pageInfo": { + "startCursor12867311": "Y3Vyc29yOnYyOpIAzglq1vk=", + "hasPreviousPage3880003826": true + } + } +} + """ + |> Decode.decodeString + (Paginator.selectionSet 2 + Paginator.backward + (Object.selectionForCompositeField "edges" [] SelectionSet.empty (identity >> Decode.list)) + |> Graphql.Document.decoder + ) + |> expectNodes [] + ] + + +expectNodes : List node -> Result error (Paginator direction node) -> Expect.Expectation +expectNodes expectedNodes result = + case result of + Ok paginator -> + paginator |> Paginator.nodes |> Expect.equal expectedNodes + + Err error -> + Expect.fail (Debug.toString error) From b5315bd475afc49020eb2779ffc56c5978673969 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 07:57:23 -0800 Subject: [PATCH 56/83] Update elm-test version. --- package-lock.json | 53 ++++++++++++++--------------------------------- package.json | 2 +- 2 files changed, 16 insertions(+), 39 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4d5ea8a07..4710aa79c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1483,27 +1483,28 @@ } }, "elm-test": { - "version": "0.19.0-rev3", - "resolved": "https://registry.npmjs.org/elm-test/-/elm-test-0.19.0-rev3.tgz", - "integrity": "sha512-+zcutibM0LOG6uT48bMsSGzyPnptgenxBUjNMJFRYuddTrOFVH1dFCKUu512lsvihBUJixaxjIG+DjQbWlpO/Q==", + "version": "0.19.0-rev5", + "resolved": "https://registry.npmjs.org/elm-test/-/elm-test-0.19.0-rev5.tgz", + "integrity": "sha512-D/LS6Db9VIuaM3UffbBkrHmR6oLpm68EYVSru9CeHkVqUQwedVuLmZX6d0jvnU0C8I/dLSEdXlGueaPgTGhNnA==", "dev": true, "requires": { "chalk": "2.1.0", "chokidar": "1.7.0", "cross-spawn": "4.0.0", - "elmi-to-json": "0.19.0", + "elmi-to-json": "0.19.1", "find-parent-dir": "^0.3.0", "firstline": "1.2.1", "fs-extra": "0.30.0", "fsevents": "1.2.4", "glob": "7.1.1", - "lodash": "4.17.10", + "lodash": "4.17.11", "minimist": "^1.2.0", "murmur-hash-js": "1.0.0", "node-elm-compiler": "5.0.1", "split": "1.0.1", "supports-color": "4.2.0", "temp": "0.8.3", + "which": "1.3.1", "xmlbuilder": "^8.2.2" }, "dependencies": { @@ -1554,27 +1555,9 @@ "which": "^1.2.9" } }, - "find-elm-dependencies": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-elm-dependencies/-/find-elm-dependencies-2.0.0.tgz", - "integrity": "sha512-lnLilxwdS3U/CSPoMnfUL1u21MBNolv6NF54y4Yds7WxdRMrTBXrmugrcvIGvakWQ2anYuinmBSUR+jUQy+vpA==", - "dev": true, - "requires": { - "firstline": "1.2.0", - "lodash": "4.17.10" - }, - "dependencies": { - "firstline": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/firstline/-/firstline-1.2.0.tgz", - "integrity": "sha1-yfSIbn9/vwr8EtcZQdzgaxkq6gU=", - "dev": true - } - } - }, "fs-extra": { "version": "0.30.0", - "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", "dev": true, "requires": { @@ -1599,17 +1582,11 @@ "path-is-absolute": "^1.0.0" } }, - "node-elm-compiler": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/node-elm-compiler/-/node-elm-compiler-5.0.1.tgz", - "integrity": "sha512-Li9NfZTL83/URoUEWly+iHJeOcZRBYUaeIL4MImnB4r21oe/xpkR6JRHjdNjLf1rMtO0tgPyOvuGW4Beytaaow==", - "dev": true, - "requires": { - "cross-spawn": "4.0.0", - "find-elm-dependencies": "2.0.0", - "lodash": "4.17.10", - "temp": "^0.8.3" - } + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true }, "supports-color": { "version": "4.2.0", @@ -1658,9 +1635,9 @@ } }, "elmi-to-json": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/elmi-to-json/-/elmi-to-json-0.19.0.tgz", - "integrity": "sha512-qNrxc1m2KAYbxT22rHyWBjzhYjJkENYgl6Ya7XVL1uxcZPiaINwFEJ7OdpGnLsM79xsWPT0z9yesQtYXKrWE7w==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/elmi-to-json/-/elmi-to-json-0.19.1.tgz", + "integrity": "sha512-O0Z3YsYU9OTb1hTDGORWxi69QjQFEIPfZVq/oc1D5lhL3swduHKY8vdKGuo+WlKVdTas99oNIsgL7yojWdYcsQ==", "dev": true, "requires": { "binwrap": "^0.2.0-rc2" diff --git a/package.json b/package.json index 7d1cdfe58..7b3b06f11 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "elm-analyse": "^0.13.3", "elm-hot-loader": "0.5.4", "elm-live": "3.0.5", - "elm-test": "^0.19.0-rev3", + "elm-test": "^0.19.0-rev5", "elm-webpack-loader": "5.0.0", "fs-extra": "^5.0.0", "ts-loader": "^3.2.0", From 33a5255d149190b1adff103ee3435c27b7b9b5ee Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 07:58:21 -0800 Subject: [PATCH 57/83] Make test green. --- tests/PaginationTests.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm index 729b093cc..a539756c8 100644 --- a/tests/PaginationTests.elm +++ b/tests/PaginationTests.elm @@ -52,7 +52,7 @@ all = (Object.selectionForCompositeField "edges" [] SelectionSet.empty (identity >> Decode.list)) |> Graphql.Document.decoder ) - |> expectNodes [] + |> expectNodes [ (), (), () ] ] From 89799300e8facd575d871107b6b5dcae70e36117 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 08:05:02 -0800 Subject: [PATCH 58/83] Decode field within nodes. --- tests/PaginationTests.elm | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm index a539756c8..58e5ef825 100644 --- a/tests/PaginationTests.elm +++ b/tests/PaginationTests.elm @@ -22,19 +22,19 @@ all = "edges": [ { "node": { - "login3832528868": "nickbytes" + "login3832528868": "3rd" }, "starredAt987198633": "2019-02-24T21:49:48Z" }, { "node": { - "login3832528868": "achou11" + "login3832528868": "2nd" }, "starredAt987198633": "2019-02-24T23:30:53Z" }, { "node": { - "login3832528868": "boxtim" + "login3832528868": "1st" }, "starredAt987198633": "2019-02-25T00:26:03Z" } @@ -49,13 +49,21 @@ all = |> Decode.decodeString (Paginator.selectionSet 2 Paginator.backward - (Object.selectionForCompositeField "edges" [] SelectionSet.empty (identity >> Decode.list)) + (Object.selectionForCompositeField "edges" [] loginFieldTotal (identity >> Decode.list)) |> Graphql.Document.decoder ) - |> expectNodes [ (), (), () ] + |> expectNodes [ "3rd", "2nd", "1st" ] ] +loginFieldTotal = + Object.selectionForCompositeField "node" [] loginField identity + + +loginField = + Object.selectionForField "String" "login" [] Decode.string + + expectNodes : List node -> Result error (Paginator direction node) -> Expect.Expectation expectNodes expectedNodes result = case result of From 3e5d5e5c0d9552249fa4874550c6c576de54a151 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 08:06:07 -0800 Subject: [PATCH 59/83] Extract selection. --- tests/PaginationTests.elm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm index 58e5ef825..3ef27b9ed 100644 --- a/tests/PaginationTests.elm +++ b/tests/PaginationTests.elm @@ -47,15 +47,15 @@ all = } """ |> Decode.decodeString - (Paginator.selectionSet 2 - Paginator.backward - (Object.selectionForCompositeField "edges" [] loginFieldTotal (identity >> Decode.list)) - |> Graphql.Document.decoder - ) + (Paginator.selectionSet 2 Paginator.backward edgesSelection |> Graphql.Document.decoder) |> expectNodes [ "3rd", "2nd", "1st" ] ] +edgesSelection = + Object.selectionForCompositeField "edges" [] loginFieldTotal (identity >> Decode.list) + + loginFieldTotal = Object.selectionForCompositeField "node" [] loginField identity From d7558941c915972a2479514e6508a997f8de3519 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 08:15:06 -0800 Subject: [PATCH 60/83] Add test helper for pagination tests. --- tests/PaginationTests.elm | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm index 3ef27b9ed..619c63dc0 100644 --- a/tests/PaginationTests.elm +++ b/tests/PaginationTests.elm @@ -47,8 +47,8 @@ all = } """ |> Decode.decodeString - (Paginator.selectionSet 2 Paginator.backward edgesSelection |> Graphql.Document.decoder) - |> expectNodes [ "3rd", "2nd", "1st" ] + (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) + |> expectPaginator (ExpectStillLoading [ "3rd", "2nd", "1st" ]) ] @@ -64,11 +64,27 @@ loginField = Object.selectionForField "String" "login" [] Decode.string -expectNodes : List node -> Result error (Paginator direction node) -> Expect.Expectation -expectNodes expectedNodes result = - case result of - Ok paginator -> - paginator |> Paginator.nodes |> Expect.equal expectedNodes +type PaginationExpection node + = ExpectStillLoading (List node) - Err error -> - Expect.fail (Debug.toString error) + + +-- | ExpectDoneLoading (List node) + + +expectPaginator : PaginationExpection node -> Result error (Paginator direction node) -> Expect.Expectation +expectPaginator expectation result = + case expectation of + ExpectStillLoading expectedNodes -> + case result of + Ok paginator -> + { moreToLoad = paginator |> Paginator.moreToLoad + , nodes = paginator |> Paginator.nodes + } + |> Expect.equal + { moreToLoad = True + , nodes = expectedNodes + } + + Err error -> + Expect.fail (Debug.toString error) From fd8bcf842a71549b5ebe89e79d74cd957383124a Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 08:27:46 -0800 Subject: [PATCH 61/83] Extract helper function to create json. --- tests/PaginationTests.elm | 68 ++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm index 619c63dc0..d7c0d1317 100644 --- a/tests/PaginationTests.elm +++ b/tests/PaginationTests.elm @@ -8,6 +8,7 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Paginator as Paginator exposing (Paginator) import Graphql.SelectionSet as SelectionSet import Json.Decode as Decode +import String.Interpolate exposing (interpolate) import Test exposing (Test, describe, test) @@ -16,42 +17,49 @@ all = describe "pagination" [ test "reverse pagination items are added in correct order" <| \() -> - """ - { - "data": { - "edges": [ - { - "node": { - "login3832528868": "3rd" - }, - "starredAt987198633": "2019-02-24T21:49:48Z" - }, - { - "node": { - "login3832528868": "2nd" - }, - "starredAt987198633": "2019-02-24T23:30:53Z" - }, - { - "node": { - "login3832528868": "1st" - }, - "starredAt987198633": "2019-02-25T00:26:03Z" - } - ], - "pageInfo": { - "startCursor12867311": "Y3Vyc29yOnYyOpIAzglq1vk=", - "hasPreviousPage3880003826": true - } - } -} - """ + pageOfRequests "3rd" "2nd" "1st" |> Decode.decodeString (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) |> expectPaginator (ExpectStillLoading [ "3rd", "2nd", "1st" ]) ] +pageOfRequests : String -> String -> String -> String +pageOfRequests item1 item2 item3 = + interpolate + """ + { + "data": { + "edges": [ + { + "node": { + "login3832528868": "{0}" + }, + "starredAt987198633": "2019-02-24T21:49:48Z" + }, + { + "node": { + "login3832528868": "{1}" + }, + "starredAt987198633": "2019-02-24T23:30:53Z" + }, + { + "node": { + "login3832528868": "{2}" + }, + "starredAt987198633": "2019-02-25T00:26:03Z" + } + ], + "pageInfo": { + "startCursor12867311": "Y3Vyc29yOnYyOpIAzglq1vk=", + "hasPreviousPage3880003826": true + } + } + } + """ + [ item1, item2, item3 ] + + edgesSelection = Object.selectionForCompositeField "edges" [] loginFieldTotal (identity >> Decode.list) From c1abed1d27f4c6f4f97d0f17c2a4d8da2ea99a52 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 08:33:35 -0800 Subject: [PATCH 62/83] Capture failing test case. --- tests/PaginationTests.elm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm index d7c0d1317..2615e1724 100644 --- a/tests/PaginationTests.elm +++ b/tests/PaginationTests.elm @@ -21,6 +21,16 @@ all = |> Decode.decodeString (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) |> expectPaginator (ExpectStillLoading [ "3rd", "2nd", "1st" ]) + , test "reverse pagination items are added in correct order after second request" <| + \() -> + pageOfRequests "3rd" "2nd" "1st" + |> Decode.decodeString (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) + |> Result.andThen + (\paginator -> + pageOfRequests "6" "5" "4" + |> Decode.decodeString (Paginator.selectionSet 3 paginator edgesSelection |> Graphql.Document.decoder) + ) + |> expectPaginator (ExpectStillLoading [ "6", "5", "4", "3rd", "2nd", "1st" ]) ] From 94addaeccd33632e8a243aabe11bab372d4eb350 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 08:42:04 -0800 Subject: [PATCH 63/83] Ordering for backwards matches ordering from server now. --- src/Graphql/Paginator.elm | 3 ++- tests/PaginationTests.elm | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index 606987e4c..63e4320c1 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -42,6 +42,7 @@ moreToLoad (Paginator paginator) = nodes : Paginator direction node -> List node nodes (Paginator paginator) = paginator.nodes + |> List.reverse selectionSet : @@ -54,7 +55,7 @@ selectionSet pageSize (Paginator paginator) selection = (selection |> Graphql.SelectionSet.map (\newNodes -> - paginator.nodes ++ newNodes + newNodes ++ paginator.nodes ) ) (case paginator.direction of diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm index 2615e1724..b0d8492e1 100644 --- a/tests/PaginationTests.elm +++ b/tests/PaginationTests.elm @@ -20,7 +20,7 @@ all = pageOfRequests "3rd" "2nd" "1st" |> Decode.decodeString (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) - |> expectPaginator (ExpectStillLoading [ "3rd", "2nd", "1st" ]) + |> expectPaginator (ExpectStillLoading [ "1st", "2nd", "3rd" ]) , test "reverse pagination items are added in correct order after second request" <| \() -> pageOfRequests "3rd" "2nd" "1st" @@ -30,7 +30,7 @@ all = pageOfRequests "6" "5" "4" |> Decode.decodeString (Paginator.selectionSet 3 paginator edgesSelection |> Graphql.Document.decoder) ) - |> expectPaginator (ExpectStillLoading [ "6", "5", "4", "3rd", "2nd", "1st" ]) + |> expectPaginator (ExpectStillLoading [ "1st", "2nd", "3rd", "4", "5", "6" ]) ] From bc600f9d3167f472ae31f7bbaeabe40ccd659f52 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 25 Feb 2019 18:26:22 -0800 Subject: [PATCH 64/83] Add test case for forward pagination. --- tests/PaginationTests.elm | 104 ++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 22 deletions(-) diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm index b0d8492e1..00d1c5e1d 100644 --- a/tests/PaginationTests.elm +++ b/tests/PaginationTests.elm @@ -15,27 +15,37 @@ import Test exposing (Test, describe, test) all : Test all = describe "pagination" - [ test "reverse pagination items are added in correct order" <| - \() -> - pageOfRequests "3rd" "2nd" "1st" - |> Decode.decodeString - (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) - |> expectPaginator (ExpectStillLoading [ "1st", "2nd", "3rd" ]) - , test "reverse pagination items are added in correct order after second request" <| - \() -> - pageOfRequests "3rd" "2nd" "1st" - |> Decode.decodeString (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) - |> Result.andThen - (\paginator -> - pageOfRequests "6" "5" "4" - |> Decode.decodeString (Paginator.selectionSet 3 paginator edgesSelection |> Graphql.Document.decoder) - ) - |> expectPaginator (ExpectStillLoading [ "1st", "2nd", "3rd", "4", "5", "6" ]) + [ describe "backward" + [ test "reverse pagination items are added in correct order" <| + \() -> + backwardPageOfRequests "3rd" "2nd" "1st" + |> Decode.decodeString + (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) + |> expectPaginator (ExpectStillLoading [ "1st", "2nd", "3rd" ]) + , test "reverse pagination items are added in correct order after second request" <| + \() -> + backwardPageOfRequests "3rd" "2nd" "1st" + |> Decode.decodeString (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) + |> Result.andThen + (\paginator -> + backwardPageOfRequests "6" "5" "4" + |> Decode.decodeString (Paginator.selectionSet 3 paginator edgesSelection |> Graphql.Document.decoder) + ) + |> expectPaginator (ExpectStillLoading [ "1st", "2nd", "3rd", "4", "5", "6" ]) + ] + , describe "forward" + [ test "paginated items are added in correct order" <| + \() -> + forwardPageOfRequests "3rd" "2nd" "1st" + |> Decode.decodeString + (Paginator.selectionSet 3 Paginator.forward edgesSelection |> Graphql.Document.decoder) + |> expectPaginator (ExpectDoneLoading [ "1st", "2nd", "3rd" ]) + ] ] -pageOfRequests : String -> String -> String -> String -pageOfRequests item1 item2 item3 = +backwardPageOfRequests : String -> String -> String -> String +backwardPageOfRequests item1 item2 item3 = interpolate """ { @@ -70,6 +80,45 @@ pageOfRequests item1 item2 item3 = [ item1, item2, item3 ] +forwardPageOfRequests : String -> String -> String -> String +forwardPageOfRequests item1 item2 item3 = + interpolate + """ + { + "data": { + "edges": [ + { + "cursor": "Y3Vyc29yOnYyOpIAzglq1vk=", + "node": { + "login3832528868": "{0}" + }, + "starredAt987198633": "2019-02-24T21:49:48Z" + }, + { + "cursor": "Y3Vyc29yOnYyOpIAzglq7e0=", + "node": { + "login3832528868": "{1}" + }, + "starredAt987198633": "2019-02-24T23:30:53Z" + }, + { + "cursor": "Y3Vyc29yOnYyOpIAzglq-Mo=", + "node": { + "login3832528868": "{2}" + }, + "starredAt987198633": "2019-02-25T00:26:03Z" + } + ], + "pageInfo": { + "endCursor12867311": "Y3Vyc29yOnYyOpIAzglq-Mo=", + "hasNextPage3880003826": false + } + } +} + """ + [ item1, item2, item3 ] + + edgesSelection = Object.selectionForCompositeField "edges" [] loginFieldTotal (identity >> Decode.list) @@ -84,10 +133,7 @@ loginField = type PaginationExpection node = ExpectStillLoading (List node) - - - --- | ExpectDoneLoading (List node) + | ExpectDoneLoading (List node) expectPaginator : PaginationExpection node -> Result error (Paginator direction node) -> Expect.Expectation @@ -106,3 +152,17 @@ expectPaginator expectation result = Err error -> Expect.fail (Debug.toString error) + + ExpectDoneLoading expectedNodes -> + case result of + Ok paginator -> + { moreToLoad = paginator |> Paginator.moreToLoad + , nodes = paginator |> Paginator.nodes + } + |> Expect.equal + { moreToLoad = False + , nodes = expectedNodes + } + + Err error -> + Expect.fail (Debug.toString error) From e84621f2efb2ecd1dd3aca6e6deef522ac6cf449 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Tue, 26 Feb 2019 06:26:48 -0800 Subject: [PATCH 65/83] Fix test cases. --- examples/src/GithubPagination.elm | 2 +- examples/src/GithubPagination2.elm | 20 ++++++++++++-------- src/Graphql/Paginator.elm | 8 ++++++-- tests/PaginationTests.elm | 10 +++++----- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/examples/src/GithubPagination.elm b/examples/src/GithubPagination.elm index 0af8ee88e..e406e3a5a 100644 --- a/examples/src/GithubPagination.elm +++ b/examples/src/GithubPagination.elm @@ -134,7 +134,7 @@ view model = ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view (model.data |> Paginator.nodes |> List.reverse) + , PrintAny.view (model.data |> Paginator.nodes) ] ] diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index dde348449..0afc9aad2 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -25,10 +25,10 @@ import PrintAny type alias Response = - Paginator Paginator.Backward Stargazer + Paginator Paginator.Forward Stargazer -query : Int -> Paginator Paginator.Backward Stargazer -> SelectionSet Response RootQuery +query : Int -> Paginator Paginator.Forward Stargazer -> SelectionSet Response RootQuery query pageSize paginator = Query.repository { owner = "dillonkearns", name = "elm-graphql" } (Repository.stargazersPaginated @@ -55,7 +55,7 @@ stargazerSelection = Github.Object.StargazerEdge.starredAt -makeRequest : Int -> Paginator Paginator.Backward Stargazer -> Cmd Msg +makeRequest : Int -> Paginator Paginator.Forward Stargazer -> Cmd Msg makeRequest pageSize paginator = query pageSize paginator |> Graphql.Http.queryRequest "https://api.github.com/graphql" @@ -71,7 +71,7 @@ type Msg type alias Model = { pageSize : Int - , paginator : Paginator Paginator.Backward Stargazer + , paginator : Paginator Paginator.Forward Stargazer } @@ -79,14 +79,18 @@ type alias RemoteDataResponse = Result (Graphql.Http.Error Response) Response +initialPageSize = + 100 + + init : Flags -> ( Model, Cmd Msg ) init flags = - Paginator.backward + Paginator.forward |> (\paginator -> - ( { pageSize = 1 + ( { pageSize = initialPageSize , paginator = paginator } - , makeRequest 1 paginator + , makeRequest initialPageSize paginator ) ) @@ -106,7 +110,7 @@ view model = ] , div [] [ h1 [] [ text "Response" ] - , PrintAny.view (model.paginator |> Paginator.nodes |> List.reverse) + , PrintAny.view (model.paginator |> Paginator.nodes) ] ] diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index 63e4320c1..e4261d5a8 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -42,7 +42,6 @@ moreToLoad (Paginator paginator) = nodes : Paginator direction node -> List node nodes (Paginator paginator) = paginator.nodes - |> List.reverse selectionSet : @@ -55,7 +54,12 @@ selectionSet pageSize (Paginator paginator) selection = (selection |> Graphql.SelectionSet.map (\newNodes -> - newNodes ++ paginator.nodes + case paginator.direction of + Forward -> + newNodes ++ paginator.nodes + + Backward -> + newNodes ++ paginator.nodes ) ) (case paginator.direction of diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm index 00d1c5e1d..53f142cec 100644 --- a/tests/PaginationTests.elm +++ b/tests/PaginationTests.elm @@ -18,17 +18,17 @@ all = [ describe "backward" [ test "reverse pagination items are added in correct order" <| \() -> - backwardPageOfRequests "3rd" "2nd" "1st" + backwardPageOfRequests "4" "5" "6" |> Decode.decodeString (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) - |> expectPaginator (ExpectStillLoading [ "1st", "2nd", "3rd" ]) + |> expectPaginator (ExpectStillLoading [ "4", "5", "6" ]) , test "reverse pagination items are added in correct order after second request" <| \() -> - backwardPageOfRequests "3rd" "2nd" "1st" + backwardPageOfRequests "4" "5" "6" |> Decode.decodeString (Paginator.selectionSet 3 Paginator.backward edgesSelection |> Graphql.Document.decoder) |> Result.andThen (\paginator -> - backwardPageOfRequests "6" "5" "4" + backwardPageOfRequests "1st" "2nd" "3rd" |> Decode.decodeString (Paginator.selectionSet 3 paginator edgesSelection |> Graphql.Document.decoder) ) |> expectPaginator (ExpectStillLoading [ "1st", "2nd", "3rd", "4", "5", "6" ]) @@ -36,7 +36,7 @@ all = , describe "forward" [ test "paginated items are added in correct order" <| \() -> - forwardPageOfRequests "3rd" "2nd" "1st" + forwardPageOfRequests "1st" "2nd" "3rd" |> Decode.decodeString (Paginator.selectionSet 3 Paginator.forward edgesSelection |> Graphql.Document.decoder) |> expectPaginator (ExpectDoneLoading [ "1st", "2nd", "3rd" ]) From 2f114e15b12f389534235421141cbb6d944c882d Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Tue, 26 Feb 2019 06:34:18 -0800 Subject: [PATCH 66/83] Fix forward pagination list appending order. --- examples/src/GithubPagination2.elm | 2 +- src/Graphql/Paginator.elm | 2 +- tests/PaginationTests.elm | 10 ++++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index 0afc9aad2..b84ecbfe7 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -80,7 +80,7 @@ type alias RemoteDataResponse = initialPageSize = - 100 + 1 init : Flags -> ( Model, Cmd Msg ) diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index e4261d5a8..18ac09104 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -56,7 +56,7 @@ selectionSet pageSize (Paginator paginator) selection = (\newNodes -> case paginator.direction of Forward -> - newNodes ++ paginator.nodes + paginator.nodes ++ newNodes Backward -> newNodes ++ paginator.nodes diff --git a/tests/PaginationTests.elm b/tests/PaginationTests.elm index 53f142cec..9d820d2df 100644 --- a/tests/PaginationTests.elm +++ b/tests/PaginationTests.elm @@ -40,6 +40,16 @@ all = |> Decode.decodeString (Paginator.selectionSet 3 Paginator.forward edgesSelection |> Graphql.Document.decoder) |> expectPaginator (ExpectDoneLoading [ "1st", "2nd", "3rd" ]) + , test "second page is added in correct order" <| + \() -> + forwardPageOfRequests "1st" "2nd" "3rd" + |> Decode.decodeString (Paginator.selectionSet 3 Paginator.forward edgesSelection |> Graphql.Document.decoder) + |> Result.andThen + (\paginator -> + forwardPageOfRequests "4" "5" "6" + |> Decode.decodeString (Paginator.selectionSet 3 paginator edgesSelection |> Graphql.Document.decoder) + ) + |> expectPaginator (ExpectDoneLoading [ "1st", "2nd", "3rd", "4", "5", "6" ]) ] ] From df660f9f5063cd2fd73a1c24ec916f687ad164aa Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 13 Apr 2019 11:11:26 -0700 Subject: [PATCH 67/83] Add correct example of connection in test. --- .../tests/Parser/ConnectionDetectorTests.elm | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index 2bf77d5ca..69fbbfdb1 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -4,7 +4,7 @@ import Expect import Graphql.Parser.CamelCaseName as CamelCaseName import Graphql.Parser.ClassCaseName as ClassCaseName import Graphql.Parser.Scalar as Scalar -import Graphql.Parser.Type as Type exposing (DefinableType, IsNullable(..), TypeDefinition(..), TypeReference(..)) +import Graphql.Parser.Type as Type exposing (DefinableType(..), IsNullable(..), ReferrableType(..), TypeDefinition(..), TypeReference(..)) import Test exposing (Test, describe, test) @@ -107,3 +107,38 @@ field inputObjectName fieldName = , typeRef = TypeReference (Type.InputObjectRef (ClassCaseName.build inputObjectName)) NonNullable , args = [] } + + +properConnectionExample = + [ TypeDefinition (ClassCaseName.build "PageInfo") + (ObjectType + [ { args = [], description = Just "", name = CamelCaseName.build "endCursor", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } + , { args = [], description = Just "", name = CamelCaseName.build "hasNextPage", typeRef = TypeReference (Type.Scalar Scalar.Boolean) NonNullable } + , { args = [] + , description = Just "" + , name = CamelCaseName.build "hasPreviousPage" + , typeRef = TypeReference (Type.Scalar Scalar.Boolean) NonNullable + } + , { args = [], description = Just "", name = CamelCaseName.build "starCursor", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } + ] + ) + Nothing + , TypeDefinition (ClassCaseName.build "Query") + (ObjectType + [ { args = + [ { description = Nothing, name = CamelCaseName.build "after", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } + , { description = Nothing, name = CamelCaseName.build "before", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } + , { description = Nothing, name = CamelCaseName.build "first", typeRef = TypeReference (Type.Scalar Scalar.Int) Nullable } + , { description = Nothing, name = CamelCaseName.build "last", typeRef = TypeReference (Type.Scalar Scalar.Int) Nullable } + ] + , description = Just "" + , name = CamelCaseName.build "stargazers" + , typeRef = TypeReference (ObjectRef "StargazerConnection") NonNullable + } + ] + ) + Nothing + , TypeDefinition (ClassCaseName.build "StargazerConnection") (ObjectType [ { args = [], description = Just "", name = CamelCaseName.build "edges", typeRef = TypeReference (List (TypeReference (ObjectRef "StargazerEdge") Nullable)) Nullable }, { args = [], description = Just "", name = CamelCaseName.build "pageInfo", typeRef = TypeReference (ObjectRef "PageInfo") NonNullable }, { args = [], description = Just "", name = CamelCaseName.build "totalCount", typeRef = TypeReference (Type.Scalar Scalar.Int) NonNullable } ]) Nothing + , TypeDefinition (ClassCaseName.build "StargazerEdge") (ObjectType [ { args = [], description = Just "", name = CamelCaseName.build "cursor", typeRef = TypeReference (Type.Scalar Scalar.String) NonNullable }, { args = [], description = Just "", name = CamelCaseName.build "node", typeRef = TypeReference (ObjectRef "User") NonNullable } ]) Nothing + , TypeDefinition (ClassCaseName.build "User") (ObjectType [ { args = [], description = Just "", name = CamelCaseName.build "name", typeRef = TypeReference (Type.Scalar Scalar.String) NonNullable } ]) Nothing + ] From 34ba9d94f3156597e208c89da4961dc33593a742 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 13 Apr 2019 11:43:01 -0700 Subject: [PATCH 68/83] Change isConnection to test fields. --- .../tests/Parser/ConnectionDetectorTests.elm | 87 ++++++++++--------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index 69fbbfdb1..8ae7608b6 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -14,10 +14,10 @@ type DetectionResult | Match -isConnection : TypeDefinition -> List TypeDefinition -> DetectionResult -isConnection (TypeDefinition typeName definableType description) allDefinitions = - if typeName |> ClassCaseName.raw |> String.endsWith "Connection" then - SpecViolation +isConnection : Type.Field -> List TypeDefinition -> DetectionResult +isConnection candidateField allDefinitions = + if CamelCaseName.raw candidateField.name == "stargazers" then + Match else Miss @@ -30,46 +30,43 @@ all = [ test "scalar is not a Connection" <| \() -> isConnection - (typeDefinition "SomeInputObject" (Type.InputObjectType [ field "String" "hello" ])) + (field "String" "hello") [] |> Expect.equal Miss ] , describe "objects" - [ test "Object with correct name violates convention, should warn" <| - \() -> - isConnection - (typeDefinition "StargazerConnection" (Type.ObjectType [ fieldNew "totalCount" (Type.Scalar Scalar.Int) NonNullable ])) - [] - |> Expect.equal SpecViolation - - {- - { - repository(owner: "dillonkearns", name: "elm-graphql") { - stargazers(first: 10, after: null) { - totalCount - pageInfo { - hasNextPage - endCursor - } - edges { - node { - login + [ -- test "Object with correct name violates convention, should warn" <| + -- \() -> + -- isConnection + -- (fieldNew "totalCount" (Type.Scalar Scalar.Int) NonNullable) + -- [] + -- |> Expect.equal SpecViolation + {- + { + repository(owner: "dillonkearns", name: "elm-graphql") { + stargazers(first: 10, after: null) { + totalCount + pageInfo { + hasNextPage + endCursor + } + edges { + node { + login + } + starredAt } - starredAt } } } - } - -} - , test "strict spec match" <| + -} + test "strict spec match" <| \() -> isConnection - (typeDefinition "StargazerConnection" (Type.ObjectType [ field "PageInfo" "pageInfo" ])) - [ strictPageInfoDefinition - , typeDefinition "StargazerEdge" (Type.InputObjectType [ field "String" "hello" ]) - ] - |> Expect.equal SpecViolation + properField + properConnectionExample + |> Expect.equal Match ] ] @@ -125,16 +122,7 @@ properConnectionExample = Nothing , TypeDefinition (ClassCaseName.build "Query") (ObjectType - [ { args = - [ { description = Nothing, name = CamelCaseName.build "after", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } - , { description = Nothing, name = CamelCaseName.build "before", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } - , { description = Nothing, name = CamelCaseName.build "first", typeRef = TypeReference (Type.Scalar Scalar.Int) Nullable } - , { description = Nothing, name = CamelCaseName.build "last", typeRef = TypeReference (Type.Scalar Scalar.Int) Nullable } - ] - , description = Just "" - , name = CamelCaseName.build "stargazers" - , typeRef = TypeReference (ObjectRef "StargazerConnection") NonNullable - } + [ properField ] ) Nothing @@ -142,3 +130,16 @@ properConnectionExample = , TypeDefinition (ClassCaseName.build "StargazerEdge") (ObjectType [ { args = [], description = Just "", name = CamelCaseName.build "cursor", typeRef = TypeReference (Type.Scalar Scalar.String) NonNullable }, { args = [], description = Just "", name = CamelCaseName.build "node", typeRef = TypeReference (ObjectRef "User") NonNullable } ]) Nothing , TypeDefinition (ClassCaseName.build "User") (ObjectType [ { args = [], description = Just "", name = CamelCaseName.build "name", typeRef = TypeReference (Type.Scalar Scalar.String) NonNullable } ]) Nothing ] + + +properField = + { args = + [ { description = Nothing, name = CamelCaseName.build "after", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } + , { description = Nothing, name = CamelCaseName.build "before", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } + , { description = Nothing, name = CamelCaseName.build "first", typeRef = TypeReference (Type.Scalar Scalar.Int) Nullable } + , { description = Nothing, name = CamelCaseName.build "last", typeRef = TypeReference (Type.Scalar Scalar.Int) Nullable } + ] + , description = Just "" + , name = CamelCaseName.build "stargazers" + , typeRef = TypeReference (ObjectRef "StargazerConnection") NonNullable + } From e67a9dd2fbeaf93a43d07d13746194e58512ba9d Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 13 Apr 2019 11:54:22 -0700 Subject: [PATCH 69/83] Extract functions. --- generator/tests/Parser/ConnectionDetectorTests.elm | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index 8ae7608b6..616632dbd 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -16,13 +16,21 @@ type DetectionResult isConnection : Type.Field -> List TypeDefinition -> DetectionResult isConnection candidateField allDefinitions = - if CamelCaseName.raw candidateField.name == "stargazers" then + if hasArgs candidateField then Match else Miss +hasArgs candidateField = + hasArg "first" candidateField.args + + +hasArg argName args = + List.filter (\arg -> CamelCaseName.raw arg.name == argName) args /= [] + + all : Test all = describe "detect connections" @@ -139,7 +147,7 @@ properField = , { description = Nothing, name = CamelCaseName.build "first", typeRef = TypeReference (Type.Scalar Scalar.Int) Nullable } , { description = Nothing, name = CamelCaseName.build "last", typeRef = TypeReference (Type.Scalar Scalar.Int) Nullable } ] - , description = Just "" + , description = Nothing , name = CamelCaseName.build "stargazers" , typeRef = TypeReference (ObjectRef "StargazerConnection") NonNullable } From 562d24071952deac38ba02cd2b22143b2253812a Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 13 Apr 2019 15:59:29 -0700 Subject: [PATCH 70/83] Test isPageInfo. --- .../tests/Parser/ConnectionDetectorTests.elm | 69 +++++++++++++++---- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index 616632dbd..c5f8188db 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -23,8 +23,30 @@ isConnection candidateField allDefinitions = Miss +hasPageInfo : List TypeDefinition -> Bool +hasPageInfo allDefinitions = + List.any (\def -> defIsPageInfo def) + allDefinitions + + +defIsPageInfo : TypeDefinition -> Bool +defIsPageInfo (TypeDefinition name typeDef description) = + ClassCaseName.raw name + == "PageInfo" + && (case typeDef of + Type.ObjectType fields -> + List.any (\currentField -> CamelCaseName.raw currentField.name == "endCursor") fields + + _ -> + False + ) + + hasArgs candidateField = hasArg "first" candidateField.args + && hasArg "last" candidateField.args + && hasArg "after" candidateField.args + && hasArg "before" candidateField.args hasArg argName args = @@ -76,6 +98,23 @@ all = properConnectionExample |> Expect.equal Match ] + , describe "has page info" + [ test "same name but doesn't match" <| + \() -> + hasPageInfo + [ TypeDefinition (ClassCaseName.build "PageInfo") + (ObjectType + [ { args = [], description = Nothing, name = CamelCaseName.build "notRealPageInfo", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } + ] + ) + Nothing + ] + |> Expect.equal False + , test "present" <| + \() -> + hasPageInfo [ properPageInfo ] + |> Expect.equal True + ] ] @@ -115,19 +154,7 @@ field inputObjectName fieldName = properConnectionExample = - [ TypeDefinition (ClassCaseName.build "PageInfo") - (ObjectType - [ { args = [], description = Just "", name = CamelCaseName.build "endCursor", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } - , { args = [], description = Just "", name = CamelCaseName.build "hasNextPage", typeRef = TypeReference (Type.Scalar Scalar.Boolean) NonNullable } - , { args = [] - , description = Just "" - , name = CamelCaseName.build "hasPreviousPage" - , typeRef = TypeReference (Type.Scalar Scalar.Boolean) NonNullable - } - , { args = [], description = Just "", name = CamelCaseName.build "starCursor", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } - ] - ) - Nothing + [ properPageInfo , TypeDefinition (ClassCaseName.build "Query") (ObjectType [ properField @@ -151,3 +178,19 @@ properField = , name = CamelCaseName.build "stargazers" , typeRef = TypeReference (ObjectRef "StargazerConnection") NonNullable } + + +properPageInfo = + TypeDefinition (ClassCaseName.build "PageInfo") + (ObjectType + [ { args = [], description = Just "", name = CamelCaseName.build "endCursor", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } + , { args = [], description = Just "", name = CamelCaseName.build "hasNextPage", typeRef = TypeReference (Type.Scalar Scalar.Boolean) NonNullable } + , { args = [] + , description = Just "" + , name = CamelCaseName.build "hasPreviousPage" + , typeRef = TypeReference (Type.Scalar Scalar.Boolean) NonNullable + } + , { args = [], description = Just "", name = CamelCaseName.build "starCursor", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } + ] + ) + Nothing From 0d4414297db551e562e31f864130db27de50eea7 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 13 Apr 2019 16:03:35 -0700 Subject: [PATCH 71/83] Test isPageInfo for single items in the test. --- generator/tests/Parser/ConnectionDetectorTests.elm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index c5f8188db..fe49c7ab1 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -25,12 +25,12 @@ isConnection candidateField allDefinitions = hasPageInfo : List TypeDefinition -> Bool hasPageInfo allDefinitions = - List.any (\def -> defIsPageInfo def) + List.any (\def -> isPageInfo def) allDefinitions -defIsPageInfo : TypeDefinition -> Bool -defIsPageInfo (TypeDefinition name typeDef description) = +isPageInfo : TypeDefinition -> Bool +isPageInfo (TypeDefinition name typeDef description) = ClassCaseName.raw name == "PageInfo" && (case typeDef of @@ -101,18 +101,18 @@ all = , describe "has page info" [ test "same name but doesn't match" <| \() -> - hasPageInfo - [ TypeDefinition (ClassCaseName.build "PageInfo") + isPageInfo + (TypeDefinition (ClassCaseName.build "PageInfo") (ObjectType [ { args = [], description = Nothing, name = CamelCaseName.build "notRealPageInfo", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } ] ) Nothing - ] + ) |> Expect.equal False , test "present" <| \() -> - hasPageInfo [ properPageInfo ] + isPageInfo properPageInfo |> Expect.equal True ] ] From f0cff4ff22f1f04d92a3c80ba69e22c15ed984ff Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 13 Apr 2019 16:12:17 -0700 Subject: [PATCH 72/83] Remove duplicate. --- .../tests/Parser/ConnectionDetectorTests.elm | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index fe49c7ab1..7e3601658 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -123,8 +123,8 @@ typeDefinition classCaseName definableType = TypeDefinition (ClassCaseName.build classCaseName) definableType Nothing -strictPageInfoDefinition : TypeDefinition -strictPageInfoDefinition = +properPageInfo : TypeDefinition +properPageInfo = typeDefinition "PageInfo" (Type.ObjectType [ fieldNew "hasPreviousPage" (Type.Scalar Scalar.Boolean) NonNullable @@ -178,19 +178,3 @@ properField = , name = CamelCaseName.build "stargazers" , typeRef = TypeReference (ObjectRef "StargazerConnection") NonNullable } - - -properPageInfo = - TypeDefinition (ClassCaseName.build "PageInfo") - (ObjectType - [ { args = [], description = Just "", name = CamelCaseName.build "endCursor", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } - , { args = [], description = Just "", name = CamelCaseName.build "hasNextPage", typeRef = TypeReference (Type.Scalar Scalar.Boolean) NonNullable } - , { args = [] - , description = Just "" - , name = CamelCaseName.build "hasPreviousPage" - , typeRef = TypeReference (Type.Scalar Scalar.Boolean) NonNullable - } - , { args = [], description = Just "", name = CamelCaseName.build "starCursor", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } - ] - ) - Nothing From 27d96d7ac706f2ad7b8216e5cae60567865f4ba4 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 13 Apr 2019 16:21:42 -0700 Subject: [PATCH 73/83] Extract function. --- .../tests/Parser/ConnectionDetectorTests.elm | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index 7e3601658..c60eb3ab5 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -169,12 +169,19 @@ properConnectionExample = properField = { args = - [ { description = Nothing, name = CamelCaseName.build "after", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } - , { description = Nothing, name = CamelCaseName.build "before", typeRef = TypeReference (Type.Scalar Scalar.String) Nullable } - , { description = Nothing, name = CamelCaseName.build "first", typeRef = TypeReference (Type.Scalar Scalar.Int) Nullable } - , { description = Nothing, name = CamelCaseName.build "last", typeRef = TypeReference (Type.Scalar Scalar.Int) Nullable } + [ buildArg "after" (Type.Scalar Scalar.String) Nullable + , buildArg "before" (Type.Scalar Scalar.String) Nullable + , buildArg "first" (Type.Scalar Scalar.Int) Nullable + , buildArg "last" (Type.Scalar Scalar.Int) Nullable ] , description = Nothing , name = CamelCaseName.build "stargazers" , typeRef = TypeReference (ObjectRef "StargazerConnection") NonNullable } + + +buildArg name topLevelType isNullable = + { description = Nothing + , name = CamelCaseName.build name + , typeRef = TypeReference topLevelType isNullable + } From 9467ec414349b1be76f9e01e57e1dac269a868b1 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sat, 13 Apr 2019 16:42:28 -0700 Subject: [PATCH 74/83] Add todo list comment. --- generator/tests/Parser/ConnectionDetectorTests.elm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/generator/tests/Parser/ConnectionDetectorTests.elm b/generator/tests/Parser/ConnectionDetectorTests.elm index c60eb3ab5..282131fe5 100644 --- a/generator/tests/Parser/ConnectionDetectorTests.elm +++ b/generator/tests/Parser/ConnectionDetectorTests.elm @@ -185,3 +185,14 @@ buildArg name topLevelType isNullable = , name = CamelCaseName.build name , typeRef = TypeReference topLevelType isNullable } + + + +{- + https://github.com/facebook/relay/blob/master/website/spec/Connections.md + + - Object type + - Ends in "Connection" + - Has "edges" field, List of edge type + - Has "pageInfo" field, non-null, of type PageInfo +-} From 0aa80ea19fb6c2ec9fff3d92e0022f629b94b580 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 14 Apr 2019 09:59:26 -0700 Subject: [PATCH 75/83] Hand-generate full stargazers paginated form. --- examples/src/Github/Object/Repository.elm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index 307de395d..12552c4ea 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -983,6 +983,25 @@ stargazers fillInOptionals object_ = Object.selectionForCompositeField "stargazers" optionalArgs object_ identity +stargazers2 : + Int + -> Paginator direction decodesTo + -> (StargazersOptionalArguments -> StargazersOptionalArguments) + -> SelectionSet decodesTo Github.Object.StargazerEdge + -> SelectionSet (Paginator direction decodesTo) Github.Object.Repository +stargazers2 pageSize paginator fillInOptionals object_ = + let + filledInOptionals = + fillInOptionals { first = Absent, after = Absent, last = Absent, before = Absent, orderBy = Absent } + |> Paginator.addPageInfo pageSize paginator + + optionalArgs = + [ Argument.optional "first" filledInOptionals.first Encode.int, Argument.optional "after" filledInOptionals.after Encode.string, Argument.optional "last" filledInOptionals.last Encode.int, Argument.optional "before" filledInOptionals.before Encode.string, Argument.optional "orderBy" filledInOptionals.orderBy Github.InputObject.encodeStarOrder ] + |> List.filterMap identity + in + Object.selectionForCompositeField "stargazers" optionalArgs (Paginator.selectionSet pageSize paginator (stargazerEdges object_)) identity + + stargazersPaginated : Int -> Paginator direction decodesTo From 3b55e98da34c7b2d3564973edfce5501ee70ad64 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 14 Apr 2019 10:31:41 -0700 Subject: [PATCH 76/83] Remove unused arg and type. --- generator/src/Graphql/Generator/Field.elm | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/generator/src/Graphql/Generator/Field.elm b/generator/src/Graphql/Generator/Field.elm index 17c6acb3a..f0f66dd2b 100644 --- a/generator/src/Graphql/Generator/Field.elm +++ b/generator/src/Graphql/Generator/Field.elm @@ -177,13 +177,8 @@ addOptionalArgs field context args fieldGenerator = fieldGenerator -type ObjectOrInterface - = Object - | Interface - - -objectThing : Context -> TypeReference -> String -> ObjectOrInterface -> FieldGenerator -objectThing context typeRef refName objectOrInterface = +objectThing : Context -> TypeReference -> String -> FieldGenerator +objectThing context typeRef refName = let typeLock = case ReferenceLeaf.get typeRef of @@ -270,13 +265,13 @@ init : Context -> CamelCaseName -> TypeReference -> FieldGenerator init ({ apiSubmodule } as context) fieldName ((Type.TypeReference referrableType isNullable) as typeRef) = case leafType typeRef of ObjectLeaf refName -> - objectThing context typeRef refName Object + objectThing context typeRef refName InterfaceLeaf refName -> - objectThing context typeRef refName Interface + objectThing context typeRef refName UnionLeaf refName -> - objectThing context typeRef refName Interface + objectThing context typeRef refName EnumLeaf -> initScalarField context typeRef From 17800aee93f00ae5b4b22f2e72b97268c653992d Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 14 Apr 2019 11:51:57 -0700 Subject: [PATCH 77/83] Add generated code for pagination example. --- examples/elm.json | 3 +- examples/gen/Pages/Enum/CacheControlScope.elm | 52 +++++++++++++++ examples/gen/Pages/InputObject.elm | 10 +++ examples/gen/Pages/Interface.elm | 10 +++ examples/gen/Pages/Object.elm | 21 +++++++ examples/gen/Pages/Object/PageInfo.elm | 43 +++++++++++++ .../gen/Pages/Object/StargazerConnection.elm | 37 +++++++++++ examples/gen/Pages/Object/StargazerEdge.elm | 31 +++++++++ examples/gen/Pages/Object/User.elm | 25 ++++++++ examples/gen/Pages/Query.elm | 48 ++++++++++++++ examples/gen/Pages/Scalar.elm | 50 +++++++++++++++ examples/gen/Pages/ScalarCodecs.elm | 19 ++++++ examples/gen/Pages/Union.elm | 10 +++ examples/gen/Pages/VerifyScalarCodecs.elm | 10 +++ generator/src/Graphql/Generator/Field.elm | 63 ++++++++++++++++++- package.json | 1 + 16 files changed, 431 insertions(+), 2 deletions(-) create mode 100644 examples/gen/Pages/Enum/CacheControlScope.elm create mode 100644 examples/gen/Pages/InputObject.elm create mode 100644 examples/gen/Pages/Interface.elm create mode 100644 examples/gen/Pages/Object.elm create mode 100644 examples/gen/Pages/Object/PageInfo.elm create mode 100644 examples/gen/Pages/Object/StargazerConnection.elm create mode 100644 examples/gen/Pages/Object/StargazerEdge.elm create mode 100644 examples/gen/Pages/Object/User.elm create mode 100644 examples/gen/Pages/Query.elm create mode 100644 examples/gen/Pages/Scalar.elm create mode 100644 examples/gen/Pages/ScalarCodecs.elm create mode 100644 examples/gen/Pages/Union.elm create mode 100644 examples/gen/Pages/VerifyScalarCodecs.elm diff --git a/examples/elm.json b/examples/elm.json index 110e0dab5..fbd0fe60c 100644 --- a/examples/elm.json +++ b/examples/elm.json @@ -3,6 +3,7 @@ "source-directories": [ "../src", "src", + "gen", "src/complex" ], "elm-version": "0.19.0", @@ -35,4 +36,4 @@ "direct": {}, "indirect": {} } -} \ No newline at end of file +} diff --git a/examples/gen/Pages/Enum/CacheControlScope.elm b/examples/gen/Pages/Enum/CacheControlScope.elm new file mode 100644 index 000000000..a3c78032a --- /dev/null +++ b/examples/gen/Pages/Enum/CacheControlScope.elm @@ -0,0 +1,52 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.Enum.CacheControlScope exposing (CacheControlScope(..), decoder, list, toString) + +import Json.Decode as Decode exposing (Decoder) + + +{-| + + - Public - + - Private - + +-} +type CacheControlScope + = Public + | Private + + +list : List CacheControlScope +list = + [ Public, Private ] + + +decoder : Decoder CacheControlScope +decoder = + Decode.string + |> Decode.andThen + (\string -> + case string of + "PUBLIC" -> + Decode.succeed Public + + "PRIVATE" -> + Decode.succeed Private + + _ -> + Decode.fail ("Invalid CacheControlScope type, " ++ string ++ " try re-running the @dillonkearns/elm-graphql CLI ") + ) + + +{-| Convert from the union type representating the Enum to a string that the GraphQL server will recognize. +-} +toString : CacheControlScope -> String +toString enum = + case enum of + Public -> + "PUBLIC" + + Private -> + "PRIVATE" diff --git a/examples/gen/Pages/InputObject.elm b/examples/gen/Pages/InputObject.elm new file mode 100644 index 000000000..5c121cbf8 --- /dev/null +++ b/examples/gen/Pages/InputObject.elm @@ -0,0 +1,10 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.InputObject exposing (placeholder) + + +placeholder : String +placeholder = + "" diff --git a/examples/gen/Pages/Interface.elm b/examples/gen/Pages/Interface.elm new file mode 100644 index 000000000..d9fc72dc8 --- /dev/null +++ b/examples/gen/Pages/Interface.elm @@ -0,0 +1,10 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.Interface exposing (placeholder) + + +placeholder : String +placeholder = + "" diff --git a/examples/gen/Pages/Object.elm b/examples/gen/Pages/Object.elm new file mode 100644 index 000000000..a834740c0 --- /dev/null +++ b/examples/gen/Pages/Object.elm @@ -0,0 +1,21 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.Object exposing (PageInfo(..), StargazerConnection(..), StargazerEdge(..), User(..)) + + +type PageInfo + = PageInfo + + +type StargazerConnection + = StargazerConnection + + +type StargazerEdge + = StargazerEdge + + +type User + = User diff --git a/examples/gen/Pages/Object/PageInfo.elm b/examples/gen/Pages/Object/PageInfo.elm new file mode 100644 index 000000000..759584ca8 --- /dev/null +++ b/examples/gen/Pages/Object/PageInfo.elm @@ -0,0 +1,43 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.Object.PageInfo exposing (endCursor, hasNextPage, hasPreviousPage, starCursor) + +import Graphql.Internal.Builder.Argument as Argument exposing (Argument) +import Graphql.Internal.Builder.Object as Object +import Graphql.Internal.Encode as Encode exposing (Value) +import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) +import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.SelectionSet exposing (SelectionSet) +import Json.Decode as Decode +import Pages.InputObject +import Pages.Interface +import Pages.Object +import Pages.Scalar +import Pages.ScalarCodecs +import Pages.Union + + +{-| -} +endCursor : SelectionSet (Maybe String) Pages.Object.PageInfo +endCursor = + Object.selectionForField "(Maybe String)" "endCursor" [] (Decode.string |> Decode.nullable) + + +{-| -} +hasNextPage : SelectionSet Bool Pages.Object.PageInfo +hasNextPage = + Object.selectionForField "Bool" "hasNextPage" [] Decode.bool + + +{-| -} +hasPreviousPage : SelectionSet Bool Pages.Object.PageInfo +hasPreviousPage = + Object.selectionForField "Bool" "hasPreviousPage" [] Decode.bool + + +{-| -} +starCursor : SelectionSet (Maybe String) Pages.Object.PageInfo +starCursor = + Object.selectionForField "(Maybe String)" "starCursor" [] (Decode.string |> Decode.nullable) diff --git a/examples/gen/Pages/Object/StargazerConnection.elm b/examples/gen/Pages/Object/StargazerConnection.elm new file mode 100644 index 000000000..9268c62cc --- /dev/null +++ b/examples/gen/Pages/Object/StargazerConnection.elm @@ -0,0 +1,37 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.Object.StargazerConnection exposing (edges, pageInfo, totalCount) + +import Graphql.Internal.Builder.Argument as Argument exposing (Argument) +import Graphql.Internal.Builder.Object as Object +import Graphql.Internal.Encode as Encode exposing (Value) +import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) +import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.SelectionSet exposing (SelectionSet) +import Json.Decode as Decode +import Pages.InputObject +import Pages.Interface +import Pages.Object +import Pages.Scalar +import Pages.ScalarCodecs +import Pages.Union + + +{-| -} +edges : SelectionSet decodesTo Pages.Object.StargazerEdge -> SelectionSet (Maybe (List (Maybe decodesTo))) Pages.Object.StargazerConnection +edges object_ = + Object.selectionForCompositeField "edges" [] object_ (identity >> Decode.nullable >> Decode.list >> Decode.nullable) + + +{-| -} +pageInfo : SelectionSet decodesTo Pages.Object.PageInfo -> SelectionSet decodesTo Pages.Object.StargazerConnection +pageInfo object_ = + Object.selectionForCompositeField "pageInfo" [] object_ identity + + +{-| -} +totalCount : SelectionSet Int Pages.Object.StargazerConnection +totalCount = + Object.selectionForField "Int" "totalCount" [] Decode.int diff --git a/examples/gen/Pages/Object/StargazerEdge.elm b/examples/gen/Pages/Object/StargazerEdge.elm new file mode 100644 index 000000000..c8325e53f --- /dev/null +++ b/examples/gen/Pages/Object/StargazerEdge.elm @@ -0,0 +1,31 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.Object.StargazerEdge exposing (cursor, node) + +import Graphql.Internal.Builder.Argument as Argument exposing (Argument) +import Graphql.Internal.Builder.Object as Object +import Graphql.Internal.Encode as Encode exposing (Value) +import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) +import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.SelectionSet exposing (SelectionSet) +import Json.Decode as Decode +import Pages.InputObject +import Pages.Interface +import Pages.Object +import Pages.Scalar +import Pages.ScalarCodecs +import Pages.Union + + +{-| -} +cursor : SelectionSet String Pages.Object.StargazerEdge +cursor = + Object.selectionForField "String" "cursor" [] Decode.string + + +{-| -} +node : SelectionSet decodesTo Pages.Object.User -> SelectionSet decodesTo Pages.Object.StargazerEdge +node object_ = + Object.selectionForCompositeField "node" [] object_ identity diff --git a/examples/gen/Pages/Object/User.elm b/examples/gen/Pages/Object/User.elm new file mode 100644 index 000000000..6c1fb1a25 --- /dev/null +++ b/examples/gen/Pages/Object/User.elm @@ -0,0 +1,25 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.Object.User exposing (name) + +import Graphql.Internal.Builder.Argument as Argument exposing (Argument) +import Graphql.Internal.Builder.Object as Object +import Graphql.Internal.Encode as Encode exposing (Value) +import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) +import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.SelectionSet exposing (SelectionSet) +import Json.Decode as Decode +import Pages.InputObject +import Pages.Interface +import Pages.Object +import Pages.Scalar +import Pages.ScalarCodecs +import Pages.Union + + +{-| -} +name : SelectionSet String Pages.Object.User +name = + Object.selectionForField "String" "name" [] Decode.string diff --git a/examples/gen/Pages/Query.elm b/examples/gen/Pages/Query.elm new file mode 100644 index 000000000..49f8b08bc --- /dev/null +++ b/examples/gen/Pages/Query.elm @@ -0,0 +1,48 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.Query exposing (StargazersOptionalArguments, stargazers) + +import Graphql.Internal.Builder.Argument as Argument exposing (Argument) +import Graphql.Internal.Builder.Object as Object +import Graphql.Internal.Encode as Encode exposing (Value) +import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) +import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.SelectionSet exposing (SelectionSet) +import Json.Decode as Decode exposing (Decoder) +import Pages.InputObject +import Pages.Interface +import Pages.Object +import Pages.Scalar +import Pages.ScalarCodecs +import Pages.Union + + +type alias StargazersOptionalArguments = + { after : OptionalArgument String + , before : OptionalArgument String + , first : OptionalArgument Int + , last : OptionalArgument Int + } + + +{-| + + - after - + - before - + - first - + - last - + +-} +stargazers : (StargazersOptionalArguments -> StargazersOptionalArguments) -> SelectionSet decodesTo Pages.Object.StargazerConnection -> SelectionSet decodesTo RootQuery +stargazers fillInOptionals object_ = + let + filledInOptionals = + fillInOptionals { after = Absent, before = Absent, first = Absent, last = Absent } + + optionalArgs = + [ Argument.optional "after" filledInOptionals.after Encode.string, Argument.optional "before" filledInOptionals.before Encode.string, Argument.optional "first" filledInOptionals.first Encode.int, Argument.optional "last" filledInOptionals.last Encode.int ] + |> List.filterMap identity + in + Object.selectionForCompositeField "stargazers" optionalArgs object_ identity diff --git a/examples/gen/Pages/Scalar.elm b/examples/gen/Pages/Scalar.elm new file mode 100644 index 000000000..bd6062149 --- /dev/null +++ b/examples/gen/Pages/Scalar.elm @@ -0,0 +1,50 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.Scalar exposing (Codecs, Upload(..), defaultCodecs, defineCodecs, unwrapCodecs, unwrapEncoder) + +import Graphql.Codec exposing (Codec) +import Graphql.Internal.Builder.Object as Object +import Graphql.Internal.Encode +import Json.Decode as Decode exposing (Decoder) +import Json.Encode as Encode + + +type Upload + = Upload String + + +defineCodecs : + { codecUpload : Codec valueUpload } + -> Codecs valueUpload +defineCodecs definitions = + Codecs definitions + + +unwrapCodecs : + Codecs valueUpload + -> { codecUpload : Codec valueUpload } +unwrapCodecs (Codecs unwrappedCodecs) = + unwrappedCodecs + + +unwrapEncoder getter (Codecs unwrappedCodecs) = + (unwrappedCodecs |> getter |> .encoder) >> Graphql.Internal.Encode.fromJson + + +type Codecs valueUpload + = Codecs (RawCodecs valueUpload) + + +type alias RawCodecs valueUpload = + { codecUpload : Codec valueUpload } + + +defaultCodecs : RawCodecs Upload +defaultCodecs = + { codecUpload = + { encoder = \(Upload raw) -> Encode.string raw + , decoder = Object.scalarDecoder |> Decode.map Upload + } + } diff --git a/examples/gen/Pages/ScalarCodecs.elm b/examples/gen/Pages/ScalarCodecs.elm new file mode 100644 index 000000000..16eb8525f --- /dev/null +++ b/examples/gen/Pages/ScalarCodecs.elm @@ -0,0 +1,19 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.ScalarCodecs exposing (Upload, codecs) + +import Json.Decode as Decode exposing (Decoder) +import Pages.Scalar exposing (defaultCodecs) + + +type alias Upload = + Pages.Scalar.Upload + + +codecs : Pages.Scalar.Codecs Upload +codecs = + Pages.Scalar.defineCodecs + { codecUpload = defaultCodecs.codecUpload + } diff --git a/examples/gen/Pages/Union.elm b/examples/gen/Pages/Union.elm new file mode 100644 index 000000000..03abbdeac --- /dev/null +++ b/examples/gen/Pages/Union.elm @@ -0,0 +1,10 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.Union exposing (placeholder) + + +placeholder : String +placeholder = + "" diff --git a/examples/gen/Pages/VerifyScalarCodecs.elm b/examples/gen/Pages/VerifyScalarCodecs.elm new file mode 100644 index 000000000..3a4e87d48 --- /dev/null +++ b/examples/gen/Pages/VerifyScalarCodecs.elm @@ -0,0 +1,10 @@ +-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql +-- https://github.com/dillonkearns/elm-graphql + + +module Pages.VerifyScalarCodecs exposing (placeholder) + + +placeholder : String +placeholder = + "" diff --git a/generator/src/Graphql/Generator/Field.elm b/generator/src/Graphql/Generator/Field.elm index f0f66dd2b..485bc17fa 100644 --- a/generator/src/Graphql/Generator/Field.elm +++ b/generator/src/Graphql/Generator/Field.elm @@ -127,6 +127,59 @@ fieldArgsString { fieldArgs } = "(" ++ String.join " ++ " fieldArgs ++ ")" +toPaginatorFieldGenerator : Context -> Type.Field -> FieldGenerator +toPaginatorFieldGenerator ({ apiSubmodule } as context) field = + init context field.name field.typeRef + |> addRequiredArgs field context field.args + |> addOptionalArgs field context field.args + + +paginatorGenerator : Context -> TypeReference -> String -> FieldGenerator +paginatorGenerator context typeRef refName = + let + typeLock = + case ReferenceLeaf.get typeRef of + ReferenceLeaf.Object -> + ModuleName.object context (ClassCaseName.build refName) |> String.join "." + + ReferenceLeaf.Interface -> + ModuleName.interface context (ClassCaseName.build refName) |> String.join "." + + ReferenceLeaf.Enum -> + MyDebug.crash "TODO" + + ReferenceLeaf.Union -> + ModuleName.union context (ClassCaseName.build refName) |> String.join "." + + ReferenceLeaf.Scalar -> + MyDebug.crash "TODO" + + objectArgAnnotation = + interpolate + "SelectionSet decodesTo {0}" + [ typeLock ] + in + { annotatedArgs = [] + , fieldArgs = [] + , decoderAnnotation = Graphql.Generator.Decoder.generateType context typeRef + , decoder = "object_" + , otherThing = ".selectionForCompositeField" + , letBindings = [] + , objectDecoderChain = + " (" + ++ (Graphql.Generator.Decoder.generateDecoder context typeRef + |> String.join " >> " + ) + ++ ")" + |> Just + , typeAliases = [] + } + |> prependArg + { annotation = objectArgAnnotation + , arg = "object_" + } + + toFieldGenerator : Context -> Type.Field -> FieldGenerator toFieldGenerator ({ apiSubmodule } as context) field = init context field.name field.typeRef @@ -234,13 +287,18 @@ type LeafRef | UnionLeaf String | EnumLeaf | ScalarLeaf + | PaginatorLeaf String leafType : TypeReference -> LeafRef leafType (Type.TypeReference referrableType isNullable) = case referrableType of Type.ObjectRef refName -> - ObjectLeaf refName + if refName |> String.endsWith "Connection" then + PaginatorLeaf refName + + else + ObjectLeaf refName Type.InterfaceRef refName -> InterfaceLeaf refName @@ -279,6 +337,9 @@ init ({ apiSubmodule } as context) fieldName ((Type.TypeReference referrableType ScalarLeaf -> initScalarField context typeRef + PaginatorLeaf connectionName -> + paginatorGenerator context typeRef connectionName + initScalarField : Context -> TypeReference -> FieldGenerator initScalarField context typeRef = diff --git a/package.json b/package.json index 7b3b06f11..611653ac1 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "test": "elm-test && cd generator && elm-test", "test:watch": "elm-test --watch", "gen:starwars": "npm run build && cd examples && ../bin/elm-graphql --scalar-codecs CustomScalarCodecs https://elm-graphql.herokuapp.com --base Swapi --output src", + "gen:pages": "npm run build && cd examples && ../bin/elm-graphql http://localhost:4000 --base Pages --output gen", "gen:normalize_test": "npm run build && cd ete_tests && ../bin/elm-graphql http://localhost:4000 --base Normalize && cd -", "gen:github": "npm run build && && cd examples && ../bin/elm-graphql --introspection-file examples/github-schema.json --base Github --output src", "approve-compilation": "cd ete_tests && elm make src/NormalizeDemo.elm --output /dev/null && cd - && cd examples && elm make --output /dev/null src/Github.elm src/Starwars.elm src/complex/Main.elm src/SimpleMutation.elm", From d41c38090836f37b878cca612eb9ecc9935d7b70 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 14 Apr 2019 12:27:38 -0700 Subject: [PATCH 78/83] Change hand-generated code. --- .../gen/Pages/Object/StargazerConnection.elm | 4 ++-- examples/gen/Pages/Query.elm | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/examples/gen/Pages/Object/StargazerConnection.elm b/examples/gen/Pages/Object/StargazerConnection.elm index 9268c62cc..935c9621d 100644 --- a/examples/gen/Pages/Object/StargazerConnection.elm +++ b/examples/gen/Pages/Object/StargazerConnection.elm @@ -20,9 +20,9 @@ import Pages.Union {-| -} -edges : SelectionSet decodesTo Pages.Object.StargazerEdge -> SelectionSet (Maybe (List (Maybe decodesTo))) Pages.Object.StargazerConnection +edges : SelectionSet decodesTo Pages.Object.StargazerEdge -> SelectionSet (List decodesTo) Pages.Object.StargazerConnection edges object_ = - Object.selectionForCompositeField "edges" [] object_ (identity >> Decode.nullable >> Decode.list >> Decode.nullable) + Object.selectionForCompositeField "edges" [] object_ (identity >> Decode.list) {-| -} diff --git a/examples/gen/Pages/Query.elm b/examples/gen/Pages/Query.elm index 49f8b08bc..bef76e048 100644 --- a/examples/gen/Pages/Query.elm +++ b/examples/gen/Pages/Query.elm @@ -9,11 +9,13 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.Paginator as Paginator exposing (Paginator) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode exposing (Decoder) import Pages.InputObject import Pages.Interface import Pages.Object +import Pages.Object.StargazerConnection import Pages.Scalar import Pages.ScalarCodecs import Pages.Union @@ -35,14 +37,20 @@ type alias StargazersOptionalArguments = - last - -} -stargazers : (StargazersOptionalArguments -> StargazersOptionalArguments) -> SelectionSet decodesTo Pages.Object.StargazerConnection -> SelectionSet decodesTo RootQuery -stargazers fillInOptionals object_ = +stargazers : + Int + -> Paginator direction decodesTo + -> (StargazersOptionalArguments -> StargazersOptionalArguments) + -> SelectionSet decodesTo Pages.Object.StargazerEdge + -> SelectionSet (Paginator direction decodesTo) Pages.Object.User +stargazers pageSize paginator fillInOptionals object_ = let filledInOptionals = - fillInOptionals { after = Absent, before = Absent, first = Absent, last = Absent } + fillInOptionals { first = Absent, after = Absent, last = Absent, before = Absent } + |> Paginator.addPageInfo pageSize paginator optionalArgs = - [ Argument.optional "after" filledInOptionals.after Encode.string, Argument.optional "before" filledInOptionals.before Encode.string, Argument.optional "first" filledInOptionals.first Encode.int, Argument.optional "last" filledInOptionals.last Encode.int ] + [ Argument.optional "first" filledInOptionals.first Encode.int, Argument.optional "after" filledInOptionals.after Encode.string, Argument.optional "last" filledInOptionals.last Encode.int, Argument.optional "before" filledInOptionals.before Encode.string ] |> List.filterMap identity in - Object.selectionForCompositeField "stargazers" optionalArgs object_ identity + Object.selectionForCompositeField "stargazers" optionalArgs (Paginator.selectionSet pageSize paginator (Pages.Object.StargazerConnection.edges object_)) identity From ccc55dca0e6786a78654f6b942b0a1fc6258d0bb Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 14 Apr 2019 12:27:50 -0700 Subject: [PATCH 79/83] Remove unecessary cases. --- generator/src/Graphql/Generator/Field.elm | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/generator/src/Graphql/Generator/Field.elm b/generator/src/Graphql/Generator/Field.elm index 485bc17fa..5d5da78d8 100644 --- a/generator/src/Graphql/Generator/Field.elm +++ b/generator/src/Graphql/Generator/Field.elm @@ -142,16 +142,7 @@ paginatorGenerator context typeRef refName = ReferenceLeaf.Object -> ModuleName.object context (ClassCaseName.build refName) |> String.join "." - ReferenceLeaf.Interface -> - ModuleName.interface context (ClassCaseName.build refName) |> String.join "." - - ReferenceLeaf.Enum -> - MyDebug.crash "TODO" - - ReferenceLeaf.Union -> - ModuleName.union context (ClassCaseName.build refName) |> String.join "." - - ReferenceLeaf.Scalar -> + _ -> MyDebug.crash "TODO" objectArgAnnotation = From 6b7a1a41c27aa3e616de38b67369fb0137a39a37 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 14 Apr 2019 12:53:00 -0700 Subject: [PATCH 80/83] Fill out more details for generator for paginator. --- generator/src/Graphql/Generator/Field.elm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/generator/src/Graphql/Generator/Field.elm b/generator/src/Graphql/Generator/Field.elm index 5d5da78d8..772e0691e 100644 --- a/generator/src/Graphql/Generator/Field.elm +++ b/generator/src/Graphql/Generator/Field.elm @@ -153,7 +153,7 @@ paginatorGenerator context typeRef refName = { annotatedArgs = [] , fieldArgs = [] , decoderAnnotation = Graphql.Generator.Decoder.generateType context typeRef - , decoder = "object_" + , decoder = "(Paginator.selectionSet pageSize paginator (Pages.Object.StargazerConnection.edges object_))" , otherThing = ".selectionForCompositeField" , letBindings = [] , objectDecoderChain = @@ -169,6 +169,14 @@ paginatorGenerator context typeRef refName = { annotation = objectArgAnnotation , arg = "object_" } + |> prependArg + { annotation = "Paginator direction decodesTo" + , arg = "paginator" + } + |> prependArg + { annotation = "Int" + , arg = "pageSize" + } toFieldGenerator : Context -> Type.Field -> FieldGenerator From 3c01c457ba503841be15d80652f73b8f2b4660ad Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 14 Apr 2019 15:04:05 -0700 Subject: [PATCH 81/83] Add helper function for adding pageInfo optional args. --- examples/src/Github/Object/Repository.elm | 3 ++- src/Graphql/Paginator.elm | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index 12552c4ea..1d2ea8d5e 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -996,8 +996,9 @@ stargazers2 pageSize paginator fillInOptionals object_ = |> Paginator.addPageInfo pageSize paginator optionalArgs = - [ Argument.optional "first" filledInOptionals.first Encode.int, Argument.optional "after" filledInOptionals.after Encode.string, Argument.optional "last" filledInOptionals.last Encode.int, Argument.optional "before" filledInOptionals.before Encode.string, Argument.optional "orderBy" filledInOptionals.orderBy Github.InputObject.encodeStarOrder ] + [ Argument.optional "orderBy" filledInOptionals.orderBy Github.InputObject.encodeStarOrder ] |> List.filterMap identity + |> List.append (Paginator.pageInfoOptionalArgs pageSize paginator) in Object.selectionForCompositeField "stargazers" optionalArgs (Paginator.selectionSet pageSize paginator (stargazerEdges object_)) identity diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index 18ac09104..956410679 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -1,5 +1,7 @@ -module Graphql.Paginator exposing (Backward, Forward, PageInfo, Paginator, addPageInfo, backward, forward, moreToLoad, nodes, selectionSet) +module Graphql.Paginator exposing (Backward, Forward, PageInfo, Paginator, addPageInfo, backward, forward, moreToLoad, nodes, pageInfoOptionalArgs, selectionSet) +import Graphql.Internal.Builder.Argument exposing (Argument) +import Graphql.Internal.Encode import Graphql.Internal.Paginator exposing (CurrentPage) import Graphql.OptionalArgument as OptionalArgument exposing (OptionalArgument(..)) import Graphql.SelectionSet exposing (SelectionSet) @@ -100,6 +102,22 @@ addPageInfo pageSize (Paginator paginator) optionals = } +pageInfoOptionalArgs : Int -> Paginator direction data -> List Argument +pageInfoOptionalArgs pageSize (Paginator paginator) = + case paginator.direction of + Forward -> + [ Graphql.Internal.Builder.Argument.Argument "first" (Graphql.Internal.Encode.int pageSize) |> Just + , Maybe.map (\cursor -> Graphql.Internal.Builder.Argument.Argument "after" (Graphql.Internal.Encode.string cursor)) paginator.currentPage.cursor + ] + |> List.filterMap identity + + Backward -> + [ Graphql.Internal.Builder.Argument.Argument "last" (Graphql.Internal.Encode.int pageSize) |> Just + , Maybe.map (\cursor -> Graphql.Internal.Builder.Argument.Argument "before" (Graphql.Internal.Encode.string cursor)) paginator.currentPage.cursor + ] + |> List.filterMap identity + + type Forward = ForwardValue From 4fdf0596d39a920d1228b7beaf555fc3d000b9ba Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 14 Apr 2019 16:23:49 -0700 Subject: [PATCH 82/83] Update code example to use new paginator syntax. --- examples/src/Github/Object/Repository.elm | 26 ++++++++++++++--- .../src/Github/Object/StargazerConnection.elm | 13 ++++++++- examples/src/GithubPagination2.elm | 28 ++++++++++++++++++- src/Graphql/Paginator.elm | 5 ++-- 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/examples/src/Github/Object/Repository.elm b/examples/src/Github/Object/Repository.elm index 1d2ea8d5e..a95fd9d37 100644 --- a/examples/src/Github/Object/Repository.elm +++ b/examples/src/Github/Object/Repository.elm @@ -2,7 +2,7 @@ -- https://github.com/dillonkearns/elm-graphql -module Github.Object.Repository exposing (AssignableUsersOptionalArguments, CollaboratorsOptionalArguments, CommitCommentsOptionalArguments, DeployKeysOptionalArguments, DeploymentsOptionalArguments, ForksOptionalArguments, IssueOrPullRequestRequiredArguments, IssueRequiredArguments, IssuesOptionalArguments, LabelRequiredArguments, LabelsOptionalArguments, LanguagesOptionalArguments, MentionableUsersOptionalArguments, MilestoneRequiredArguments, MilestonesOptionalArguments, ObjectOptionalArguments, ProjectRequiredArguments, ProjectsOptionalArguments, ProtectedBranchesOptionalArguments, PullRequestRequiredArguments, PullRequestsOptionalArguments, RefRequiredArguments, RefsOptionalArguments, RefsRequiredArguments, ReleaseRequiredArguments, ReleasesOptionalArguments, RepositoryTopicsOptionalArguments, ShortDescriptionHTMLOptionalArguments, StargazersOptionalArguments, WatchersOptionalArguments, assignableUsers, codeOfConduct, collaborators, commitComments, createdAt, databaseId, defaultBranchRef, deployKeys, deployments, description, descriptionHTML, diskUsage, forkCount, forks, hasIssuesEnabled, hasWikiEnabled, homepageUrl, id, isArchived, isFork, isLocked, isMirror, isPrivate, issue, issueOrPullRequest, issues, label, labels, languages, license, licenseInfo, lockReason, mentionableUsers, milestone, milestones, mirrorUrl, name, nameWithOwner, object, owner, parent, primaryLanguage, project, projects, projectsResourcePath, projectsUrl, protectedBranches, pullRequest, pullRequests, pushedAt, ref, refs, release, releases, repositoryTopics, resourcePath, shortDescriptionHTML, sshUrl, stargazers, stargazersPaginated, updatedAt, url, viewerCanAdminister, viewerCanCreateProjects, viewerCanSubscribe, viewerCanUpdateTopics, viewerHasStarred, viewerPermission, viewerSubscription, watchers) +module Github.Object.Repository exposing (AssignableUsersOptionalArguments, CollaboratorsOptionalArguments, CommitCommentsOptionalArguments, DeployKeysOptionalArguments, DeploymentsOptionalArguments, ForksOptionalArguments, IssueOrPullRequestRequiredArguments, IssueRequiredArguments, IssuesOptionalArguments, LabelRequiredArguments, LabelsOptionalArguments, LanguagesOptionalArguments, MentionableUsersOptionalArguments, MilestoneRequiredArguments, MilestonesOptionalArguments, ObjectOptionalArguments, ProjectRequiredArguments, ProjectsOptionalArguments, ProtectedBranchesOptionalArguments, PullRequestRequiredArguments, PullRequestsOptionalArguments, RefRequiredArguments, RefsOptionalArguments, RefsRequiredArguments, ReleaseRequiredArguments, ReleasesOptionalArguments, RepositoryTopicsOptionalArguments, ShortDescriptionHTMLOptionalArguments, StargazersOptionalArguments, WatchersOptionalArguments, assignableUsers, codeOfConduct, collaborators, commitComments, createdAt, databaseId, defaultBranchRef, deployKeys, deployments, description, descriptionHTML, diskUsage, forkCount, forks, hasIssuesEnabled, hasWikiEnabled, homepageUrl, id, isArchived, isFork, isLocked, isMirror, isPrivate, issue, issueOrPullRequest, issues, label, labels, languages, license, licenseInfo, lockReason, mentionableUsers, milestone, milestones, mirrorUrl, name, nameWithOwner, object, owner, parent, primaryLanguage, project, projects, projectsResourcePath, projectsUrl, protectedBranches, pullRequest, pullRequests, pushedAt, ref, refs, release, releases, repositoryTopics, resourcePath, shortDescriptionHTML, sshUrl, stargazers, stargazers3, stargazersPaginated, updatedAt, url, viewerCanAdminister, viewerCanCreateProjects, viewerCanSubscribe, viewerCanUpdateTopics, viewerHasStarred, viewerPermission, viewerSubscription, watchers) import Github.Enum.CollaboratorAffiliation import Github.Enum.IssueState @@ -993,14 +993,32 @@ stargazers2 pageSize paginator fillInOptionals object_ = let filledInOptionals = fillInOptionals { first = Absent, after = Absent, last = Absent, before = Absent, orderBy = Absent } - |> Paginator.addPageInfo pageSize paginator optionalArgs = [ Argument.optional "orderBy" filledInOptionals.orderBy Github.InputObject.encodeStarOrder ] |> List.filterMap identity |> List.append (Paginator.pageInfoOptionalArgs pageSize paginator) in - Object.selectionForCompositeField "stargazers" optionalArgs (Paginator.selectionSet pageSize paginator (stargazerEdges object_)) identity + Object.selectionForCompositeField "stargazers" optionalArgs (Paginator.selectionSet paginator (stargazerEdges object_)) identity + + +stargazers3 : + Int + -> Paginator direction decodesTo + -> (StargazersOptionalArguments -> StargazersOptionalArguments) + -> SelectionSet finalDecodesTo Github.Object.StargazerConnection + -> SelectionSet finalDecodesTo Github.Object.Repository +stargazers3 pageSize paginator fillInOptionals object_ = + let + filledInOptionals = + fillInOptionals { first = Absent, after = Absent, last = Absent, before = Absent, orderBy = Absent } + + optionalArgs = + [ Argument.optional "orderBy" filledInOptionals.orderBy Github.InputObject.encodeStarOrder ] + |> List.filterMap identity + |> List.append (Paginator.pageInfoOptionalArgs pageSize paginator) + in + Object.selectionForCompositeField "stargazers" optionalArgs object_ identity stargazersPaginated : @@ -1011,7 +1029,7 @@ stargazersPaginated : -> SelectionSet (Paginator direction decodesTo) Github.Object.Repository stargazersPaginated pageSize paginator fillInOptionals object_ = stargazers (fillInOptionals >> Paginator.addPageInfo pageSize paginator) - (Paginator.selectionSet pageSize paginator (stargazerEdges object_)) + (Paginator.selectionSet paginator (stargazerEdges object_)) stargazerEdges : SelectionSet decodesTo Github.Object.StargazerEdge -> SelectionSet (List decodesTo) Github.Object.StargazerConnection diff --git a/examples/src/Github/Object/StargazerConnection.elm b/examples/src/Github/Object/StargazerConnection.elm index 11232eed8..6b25d393e 100644 --- a/examples/src/Github/Object/StargazerConnection.elm +++ b/examples/src/Github/Object/StargazerConnection.elm @@ -2,7 +2,7 @@ -- https://github.com/dillonkearns/elm-graphql -module Github.Object.StargazerConnection exposing (edges, nodes, pageInfo, totalCount) +module Github.Object.StargazerConnection exposing (edges, edgesPaginator, nodes, pageInfo, totalCount) import Github.InputObject import Github.Interface @@ -15,6 +15,7 @@ import Graphql.Internal.Builder.Object as Object import Graphql.Internal.Encode as Encode exposing (Value) import Graphql.Operation exposing (RootMutation, RootQuery, RootSubscription) import Graphql.OptionalArgument exposing (OptionalArgument(..)) +import Graphql.Paginator as Paginator exposing (Paginator) import Graphql.SelectionSet exposing (SelectionSet) import Json.Decode as Decode @@ -45,3 +46,13 @@ pageInfo object_ = totalCount : SelectionSet Int Github.Object.StargazerConnection totalCount = Object.selectionForField "Int" "totalCount" [] Decode.int + + +edgesPaginator : + Paginator direction decodesTo + -> SelectionSet decodesTo Github.Object.StargazerEdge + -> SelectionSet (Paginator direction decodesTo) Github.Object.StargazerConnection +edgesPaginator paginator object_ = + Paginator.selectionSet + paginator + (Object.selectionForCompositeField "edges" [] object_ (identity >> Decode.list)) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index b84ecbfe7..a930af0ed 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -28,8 +28,27 @@ type alias Response = Paginator Paginator.Forward Stargazer -query : Int -> Paginator Paginator.Forward Stargazer -> SelectionSet Response RootQuery + +-- queryNew : Int -> Paginator Paginator.Forward Stargazer -> SelectionSet Response RootQuery + + +query : + Int + -> Paginator Paginator.Forward Stargazer + -> SelectionSet (Paginator Paginator.Forward Stargazer) RootQuery query pageSize paginator = + Query.repository { owner = "dillonkearns", name = "elm-graphql" } + (Repository.stargazers3 + pageSize + paginator + identity + (connectionSelection paginator) + ) + |> SelectionSet.nonNullOrFail + + +queryOld : Int -> Paginator Paginator.Forward Stargazer -> SelectionSet Response RootQuery +queryOld pageSize paginator = Query.repository { owner = "dillonkearns", name = "elm-graphql" } (Repository.stargazersPaginated pageSize @@ -46,6 +65,13 @@ type alias Stargazer = } +connectionSelection : + Paginator Paginator.Forward Stargazer + -> SelectionSet (Paginator Paginator.Forward Stargazer) Github.Object.StargazerConnection +connectionSelection paginator = + Github.Object.StargazerConnection.edgesPaginator paginator stargazerSelection + + stargazerSelection : SelectionSet Stargazer Github.Object.StargazerEdge stargazerSelection = SelectionSet.map2 Stargazer diff --git a/src/Graphql/Paginator.elm b/src/Graphql/Paginator.elm index 956410679..19c4efbad 100644 --- a/src/Graphql/Paginator.elm +++ b/src/Graphql/Paginator.elm @@ -47,11 +47,10 @@ nodes (Paginator paginator) = selectionSet : - Int - -> Paginator direction decodesTo + Paginator direction decodesTo -> SelectionSet (List decodesTo) typeLock -> SelectionSet (Paginator direction decodesTo) typeLock -selectionSet pageSize (Paginator paginator) selection = +selectionSet (Paginator paginator) selection = Graphql.SelectionSet.map3 PaginatorRecord (selection |> Graphql.SelectionSet.map From 3823b87f63fd334dfe2d3bc7231e5c9765bb8c78 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Sun, 14 Apr 2019 16:32:24 -0700 Subject: [PATCH 83/83] Add total count selection to illustrate selecting other fields from connection. --- examples/src/GithubPagination2.elm | 39 ++++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/examples/src/GithubPagination2.elm b/examples/src/GithubPagination2.elm index a930af0ed..fd5995725 100644 --- a/examples/src/GithubPagination2.elm +++ b/examples/src/GithubPagination2.elm @@ -25,7 +25,7 @@ import PrintAny type alias Response = - Paginator Paginator.Forward Stargazer + ( Int, Paginator Paginator.Forward Stargazer ) @@ -35,28 +35,32 @@ type alias Response = query : Int -> Paginator Paginator.Forward Stargazer - -> SelectionSet (Paginator Paginator.Forward Stargazer) RootQuery + -> SelectionSet ( Int, Paginator Paginator.Forward Stargazer ) RootQuery query pageSize paginator = Query.repository { owner = "dillonkearns", name = "elm-graphql" } (Repository.stargazers3 pageSize paginator identity - (connectionSelection paginator) + (SelectionSet.map2 Tuple.pair + Github.Object.StargazerConnection.totalCount + (connectionSelection paginator) + ) ) |> SelectionSet.nonNullOrFail -queryOld : Int -> Paginator Paginator.Forward Stargazer -> SelectionSet Response RootQuery -queryOld pageSize paginator = - Query.repository { owner = "dillonkearns", name = "elm-graphql" } - (Repository.stargazersPaginated - pageSize - paginator - identity - stargazerSelection - ) - |> SelectionSet.nonNullOrFail + +-- queryOld : Int -> Paginator Paginator.Forward Stargazer -> SelectionSet Response RootQuery +-- queryOld pageSize paginator = +-- Query.repository { owner = "dillonkearns", name = "elm-graphql" } +-- (Repository.stargazersPaginated +-- pageSize +-- paginator +-- identity +-- stargazerSelection +-- ) +-- |> SelectionSet.nonNullOrFail type alias Stargazer = @@ -98,6 +102,7 @@ type Msg type alias Model = { pageSize : Int , paginator : Paginator Paginator.Forward Stargazer + , totalCount : Int } @@ -115,6 +120,7 @@ init flags = |> (\paginator -> ( { pageSize = initialPageSize , paginator = paginator + , totalCount = -1 } , makeRequest initialPageSize paginator ) @@ -130,7 +136,8 @@ view model = -- , pre [] [ text (Document.serializeQuery (query model.pageSize model.data)) ] ] , div [] - [ button [ onClick GetNextPage ] [ text <| "Load next " ++ String.fromInt model.pageSize ++ " item(s)..." ] + [ p [] [ text <| String.fromInt model.totalCount ] + , button [ onClick GetNextPage ] [ text <| "Load next " ++ String.fromInt model.pageSize ++ " item(s)..." ] , input [ Html.Events.onInput CountChanged ] [] , paginationDetailsView model ] @@ -174,8 +181,8 @@ update msg model = GotResponse response -> case response of - Ok successData -> - ( { model | paginator = successData }, Cmd.none ) + Ok ( totalCount, successData ) -> + ( { model | totalCount = totalCount, paginator = successData }, Cmd.none ) _ -> ( model, Cmd.none )