From a1e36bd8f8073f24106f51deed42521f0fcc4de7 Mon Sep 17 00:00:00 2001 From: Mal Miller <59854849+mmiller-max@users.noreply.github.com> Date: Sat, 4 Dec 2021 13:02:14 +0000 Subject: [PATCH] Add docs --- README.md | 63 +++++++++++++++++++++++++++++++++++++++-- docs/make.jl | 4 +++ docs/src/index.md | 68 +++++++++++++++++++++++++++++++++++++-------- docs/src/private.md | 19 +++++++++++++ docs/src/public.md | 9 ++++++ src/parser.jl | 5 ++++ src/strings.jl | 3 +- 7 files changed, 155 insertions(+), 16 deletions(-) create mode 100644 docs/src/private.md create mode 100644 docs/src/public.md diff --git a/README.md b/README.md index a1b4926..25d3f1e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,69 @@ # GraphQLParser +*A Julia package to parse and validate GraphQL executable documents* + [![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://mmiller-max.github.io/GraphQLParser.jl/dev) [![Build Status](https://github.com/mmiller-max/GraphQLParser.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/mmiller-max/GraphQLParser.jl/actions/workflows/CI.yml?query=branch%3Amain) [![Coverage](https://codecov.io/gh/mmiller-max/GraphQLParser.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/mmiller-max/GraphQLParser.jl) -Parses a GraphQL query string into a nested struture of types. Follows the [2021 specification](https://spec.graphql.org/October2021). +Parses a GraphQL executable document (that is, a query string) and partially validates it. Follows the [2021 specification](https://spec.graphql.org/October2021). + +Why only partial validation? Full validation (as per the GraphQL specification) requies knowledge of the schema, and GraphQLParser assumes no knowledge of the server and will therefore only perform some validation. + +For example, the validation provided by this package will fail if parsing fields, or if two variable definitions use the same name, but will not fail if a field is incorrectly named for a particularly query. +For more information about what is covered, see the documentation. + +## Installation + +The package can be installed with Julia's package manager, +either by using the Pkg REPL mode (press `]` to enter): +``` +pkg> add GraphQLParser +``` +or by using Pkg functions +```julia-repl +julia> using Pkg; Pkg.add("GraphQLParser") +``` + +## Use + +This package can be used to check whether a document is valid + +```julia +using GraphQLParser + +document = """ +query myQuery{ + findDog +} +""" + +is_valid_executable_document(document) +# true +``` + +Or return a list of validation errors + +```julia +using GraphQLParser -Does not perform any interaction with the server, so no input coercion or any checking, other than checking that the query string is valid. +document = """ +query myQuery{ + findDog +} -Mostly just an attempt to see how easy this would be, but potentially has some uses in other GraphQL packages. +query myQuery{ + findCat +} +""" +errors = validate_executable_document(document) +errors[1] +# GQLError +# message: There can only be one Operation named "myQuery". +# location: Line 1 Column 1 +errors[2] +# GQLError +# message: There can only be one Operation named "myQuery". +# location: Line 5 Column 1 +``` \ No newline at end of file diff --git a/docs/make.jl b/docs/make.jl index 7a85211..a5a7dc9 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,6 +15,10 @@ makedocs(; ), pages=[ "Home" => "index.md", + "Library" => [ + "Public" => "public.md", + "Private" => "private.md", + ] ], ) diff --git a/docs/src/index.md b/docs/src/index.md index 31a7168..66ac6b4 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -4,25 +4,71 @@ CurrentModule = GraphQLParser # GraphQLParser +*A Julia package to parse and validate GraphQL executable documents* + Documentation for [GraphQLParser](https://github.com/mmiller-max/GraphQLParser.jl). +## Installation -```@index +The package can be installed with Julia's package manager, +either by using the Pkg REPL mode (press `]` to enter): +``` +pkg> add GraphQLParser +``` +or by using Pkg functions +```julia-repl +julia> using Pkg; Pkg.add("GraphQLParser") ``` -```@autodocs -Modules = [GraphQLParser] +## Use + +This package can be used to check whether a document is valid + +```julia +using GraphQLParser + +document = """ +query myQuery{ + findDog +} +""" + +is_valid_executable_document(document) +# true ``` -## Validation +Or return a list of validation errors + +```julia +using GraphQLParser -`validate_executable_document` performs validation that does not require the schema and therefore does not fully validate the document as per the GraphQL specification. -The validation includes: +document = """ +query myQuery{ + findDog +} -- [5.2.1.1 Named Operation Uniqueness](https://spec.graphql.org/October2021/#sec-Named-Operation-Definitions) -- [5.2.2.1 Lone Anonymous Operation](https://spec.graphql.org/October2021/#sec-Anonymous-Operation-Definitions) -- [5.5.1.1 Fragment Name Uniqueness](https://spec.graphql.org/October2021/#sec-Fragment-Name-Uniqueness) -- [5.5.1.4 Fragments Must Be Used](https://spec.graphql.org/October2021/#sec-Fragments-Must-Be-Used) -= [5.5.2.1 Fragment spread target defined](https://spec.graphql.org/October2021/#sec-Fragment-spread-target-defined) +query myQuery{ + findCat +} +""" +errors = validate_executable_document(document) +errors[1] +# GQLError +# message: There can only be one Operation named "myQuery". +# location: Line 1 Column 1 +errors[2] +# GQLError +# message: There can only be one Operation named "myQuery". +# location: Line 5 Column 1 +``` + +## Validation +[`validate_executable_document`](@ref) performs validation that does not require the schema and therefore does not fully validate the document as per the GraphQL specification. +The validation performed includes: +- [5.2.1.1 Named operation uniqueness](https://spec.graphql.org/October2021/#sec-Named-Operation-Definitions) +- [5.2.2.1 Lone anonymous pperation](https://spec.graphql.org/October2021/#sec-Anonymous-Operation-Definitions) +- [5.5.1.1 Fragment name uniqueness](https://spec.graphql.org/October2021/#sec-Fragment-Name-Uniqueness) +- [5.5.1.4 Fragments must be used](https://spec.graphql.org/October2021/#sec-Fragments-Must-Be-Used) +- [5.5.2.1 Fragment spread target defined](https://spec.graphql.org/October2021/#sec-Fragment-spread-target-defined) diff --git a/docs/src/private.md b/docs/src/private.md new file mode 100644 index 0000000..d3287da --- /dev/null +++ b/docs/src/private.md @@ -0,0 +1,19 @@ +# Private + +Package internals documentation. + +## Parsing + +Parsing is currently part of the private API as the output types are liable to change. Once this has stabilised, this will move to the public API. + +```@docs +GraphQLParser.parse +``` + +## Miscellaneous + +```@autodocs +Modules = [GraphQLParser] +Filter = t -> !in(t, (GraphQLParser.parse,)) +Public = false +``` \ No newline at end of file diff --git a/docs/src/public.md b/docs/src/public.md new file mode 100644 index 0000000..d8e3975 --- /dev/null +++ b/docs/src/public.md @@ -0,0 +1,9 @@ +# Public + +Documentation for GraphQLParser's public interface. + +```@autodocs +Modules = [GraphQLParser] +Public = true +Private = false +``` \ No newline at end of file diff --git a/src/parser.jl b/src/parser.jl index ca5ec25..440de92 100644 --- a/src/parser.jl +++ b/src/parser.jl @@ -5,6 +5,11 @@ # - assumes that pos is the first character of what it is trying to parse (i.e. not an ignored charactaer) # - returns pos at the position just after it has finished reading +""" + parse(str::AbstractString) + +Parses a GraphQL executable document string. +""" function parse(str::AbstractString) buf = codeunits(str) len = length(buf) diff --git a/src/strings.jl b/src/strings.jl index f7257af..f25dfe2 100644 --- a/src/strings.jl +++ b/src/strings.jl @@ -153,8 +153,7 @@ end """ format_block_string(str) -Perform the formatting defined here: -https://spec.graphql.org/October2021/#sec-String-Value.Semantics +Perform the formatting defined [in the specification](https://spec.graphql.org/October2021/#sec-String-Value.Semantics). """ function format_block_string(str) lines = split(str, r"\r|\n") # split by line terminators