#! perl
# ABSTRACT: Command-line GraphQL client
# PODNAME: graphql


# FATPACK - Do not remove this line.

use warnings;
use strict;

use GraphQL::Client::CLI;

our $VERSION = '0.605'; # VERSION

GraphQL::Client::CLI->main(@ARGV);

__END__

=pod

=encoding UTF-8

=head1 NAME

graphql - Command-line GraphQL client

=head1 VERSION

version 0.605

=head1 SYNOPSIS

    graphql <URL> <QUERY> [ [--variables JSON] | [--variable KEY=VALUE]... ]
            [--operation-name NAME] [--transport KEY=VALUE]...
            [--[no-]unpack] [--filter JSONPATH]
            [--format json|json:pretty|yaml|perl|csv|tsv|table] [--output FILE]

    graphql --version|--help|--manual

=head1 DESCRIPTION

C<graphql> is a command-line program for executing queries and mutations on
a L<GraphQL|https://graphql.org/> server.

=head1 INSTALL

There are several ways to install F<graphql> to your system.

=head2 from CPAN

You can install F<graphql> using L<cpanm>:

    cpanm GraphQL::Client

=head2 from GitHub

You can also choose to download F<graphql> as a self-contained executable:

    curl -OL https://raw.githubusercontent.com/chazmcgarvey/graphql-client/solo/graphql
    chmod +x graphql

To hack on the code, clone the repo instead:

    git clone https://github.com/chazmcgarvey/graphql-client.git
    cd graphql-client
    make bootstrap      # installs dependencies; requires cpanm

=head1 OPTIONS

=head2 C<--url URL>

The URL of the GraphQL server endpoint.

If no C<--url> option is given, the first argument is assumed to be the URL.

This option is required.

Alias: C<-u>

=head2 C<--query STR>

The query or mutation to execute.

If no C<--query> option is given, the next argument (after URL) is assumed to be the query.

If the value is "-" (which is the default), the query will be read from C<STDIN>.

See: L<https://graphql.org/learn/queries/>

Alias: C<--mutation>

=head2 C<--variables JSON>

Provide the variables as a JSON object.

Aliases: C<--vars>, C<-V>

=head2 C<--variable KEY=VALUE>

An alternative way to provide variables one at a time. This option can be repeated to provide
multiple variables.

If used in combination with L</"--variables JSON">, this option is silently ignored.

See: L<https://graphql.org/learn/queries/#variables>

Aliases: C<--var>, C<-d>

=head2 C<--operation-name NAME>

Inform the server which query/mutation to execute.

Alias: C<-n>

=head2 C<--output FILE>

Write the response to a file instead of STDOUT.

Alias: C<-o>

=head2 C<--transport KEY=VALUE>

Key-value pairs for configuring the transport (usually HTTP).

Alias: C<-t>

=head2 C<--format STR>

Specify the output format to use. See L</FORMAT>.

Alias: C<-f>

=head2 C<--unpack>

Enables unpack mode.

By default, the response structure is printed as-is from the server, and the program exits 0.

When unpack mode is enabled, if the response completes with no errors, only the data section of
the response is printed and the program exits 0. If the response has errors, the whole response
structure is printed as-is and the program exits 1. See L</EXAMPLES> to see what this looks like in
practice.

Use C<--no-unpack> to disable if unpack mode was enabled via C<GRAPHQL_CLIENT_OPTIONS>.

=head2 C<--filter JSONPATH>

Filter the response based on a L<JSONPath|JSON::Path/SYNOPSIS> expression.

Requires L<JSON::Path>.

Alias: C<-p>

=head1 FORMAT

The argument for L</"--format STR"> can be one of:

=over 4

=item *

C<csv> - Comma-separated values (requires L<Text::CSV>)

=item *

C<json:pretty> - Human-readable JSON (default)

=item *

C<json> - JSON

=item *

C<perl> - Perl code (requires L<Data::Dumper>)

=item *

C<table> - Table (requires L<Text::Table::Any>)

=item *

C<tsv> - Tab-separated values (requires L<Text::CSV>)

=item *

C<yaml> - YAML (requires L<YAML>)

=back

The C<csv>, C<tsv>, and C<table> formats will only work if the response has a particular shape:

    {
        "data" : {
            "onefield" : [
                {
                    "key" : "value",
                    ...
                },
                ...
            ]
        }
    }

or

    {
        "data" : {
            "onefield" : [
                "value",
                ...
            ]
        }
    }

If the response cannot be formatted, the default format will be used instead, an error message will
be printed to STDERR, and the program will exit 3.

Table formatting can be done by one of several different modules, each with its own features and
bugs. The default module is L<Text::Table::Tiny>, but this can be overridden using the
C<PERL_TEXT_TABLE> environment variable if desired, like this:

    PERL_TEXT_TABLE=Text::Table::HTML graphql ... -f table

The list of supported modules is at L<Text::Table::Any/@BACKENDS>.

=head1 EXAMPLES

Different ways to provide the query/mutation to execute:

    graphql http://myserver/graphql {hello}

    echo {hello} | graphql http://myserver/graphql

    graphql http://myserver/graphql <<END
    > {hello}
    > END

    graphql http://myserver/graphql
    Interactive mode engaged! Waiting for a query on <STDIN>...
    {hello}
    ^D

Execute a query with variables:

    graphql http://myserver/graphql <<END --var episode=JEDI
    > query HeroNameAndFriends($episode: Episode) {
    >   hero(episode: $episode) {
    >     name
    >     friends {
    >       name
    >     }
    >   }
    > }
    > END

    graphql http://myserver/graphql --vars '{"episode":"JEDI"}'

Configure the transport:

    graphql http://myserver/graphql {hello} -t headers.authorization='Basic s3cr3t'

This example shows the effect of L</--unpack>:

    graphql http://myserver/graphql {hello}

    # Output:
    {
        "data" : {
            "hello" : "Hello world!"
        }
    }

    graphql http://myserver/graphql {hello} --unpack

    # Output:
    {
        "hello" : "Hello world!"
    }

=head1 ENVIRONMENT

Some environment variables affect the way C<graphql> behaves:

=over 4

=item *

C<GRAPHQL_CLIENT_DEBUG> - Set to 1 to print diagnostic messages to STDERR.

=item *

C<GRAPHQL_CLIENT_HTTP_USER_AGENT> - Set the HTTP user agent string.

=item *

C<GRAPHQL_CLIENT_OPTIONS> - Set the default set of options.

=item *

C<PERL_TEXT_TABLE> - Set table format backend; see L</FORMAT>.

=back

=head1 EXIT STATUS

Here is a consolidated summary of what exit statuses mean:

=over 4

=item *

C<0> - Success

=item *

C<1> - Client or server errors

=item *

C<2> - Option usage is wrong

=item *

C<3> - Could not format the response as requested

=back

=head1 SEE ALSO

=over 4

=item *

L<GraphQL::Client> - Programmatic interface

=back

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website
L<https://github.com/chazmcgarvey/graphql-client/issues>

When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.

=head1 AUTHOR

Charles McGarvey <ccm@cpan.org>

=head1 CONTRIBUTOR

=for stopwords jwright

jwright <jwright@ecstuning.com>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2020 by Charles McGarvey.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
