]> Dogcows Code - chaz/graphql-client/blobdiff - bin/graphql
Version 0.605
[chaz/graphql-client] / bin / graphql
index 31c48aeb1109a58205ce70161b41f8ed00dd222a..4b523aaead5c7a87dfca5614f6af9fe9d2d0c588 100755 (executable)
 #! perl
-# PODNAME: graphql
 # ABSTRACT: Command-line GraphQL client
+# PODNAME: graphql
+
 
 # FATPACK - Do not remove this line.
 
 use warnings;
 use strict;
 
-use Getopt::Long;
-use GraphQL::Client;
-use JSON::MaybeXS;
-
-our $VERSION = '0.600'; # VERSION
-
-my $version;
-my $help;
-my $manual;
-my $url;
-my $transport       = {};
-my $query           = '-';
-my $variables       = {};
-my $operation_name;
-my $format          = 'json:pretty';
-my $unpack          = 0;
-my $outfile;
-GetOptions(
-    'version'               => \$version,
-    'help|h|?'              => \$help,
-    'manual|man'            => \$manual,
-    'url|u=s'               => \$url,
-    'query|mutation=s'      => \$query,
-    'variables|vars|V=s'    => \$variables,
-    'variable|var|d=s%'     => \$variables,
-    'operation-name|n=s'    => \$operation_name,
-    'transport|t=s%'        => \$transport,
-    'format|f=s'            => \$format,
-    'unpack!'               => \$unpack,
-    'output|o=s'            => \$outfile,
-) or pod2usage(2);
-
-if ($version) {
-    print "graphql $VERSION\n";
-    exit 0;
-}
-if ($help) {
-    pod2usage(-exitval => 0, -verbose => 99, -sections => [qw(NAME SYNOPSIS OPTIONS)]);
-}
-if ($manual) {
-    pod2usage(-exitval => 0, -verbose => 2);
-}
-
-$url    = shift if !$url;
-$query  = shift if !$query || $query eq '-';
-
-if (!$url) {
-    print STDERR "The <URL> or --url option argument is required.\n";
-    pod2usage(2);
-}
-
-$transport = expand_vars($transport);
-
-if (ref $variables) {
-    $variables = expand_vars($variables);
-}
-else {
-    $variables = JSON::MaybeXS->new->decode($variables);
-}
-
-my $client = GraphQL::Client->new(url => $url);
-
-eval { $client->transport };
-if (my $err = $@) {
-    warn $err if $ENV{GRAPHQL_CLIENT_DEBUG};
-    print STDERR "Could not construct a transport for URL: $url\n";
-    print STDERR "Is this URL correct?\n";
-    pod2usage(2);
-}
-
-if (!$query || $query eq '-') {
-    print STDERR "Interactive mode engaged! Waiting for a query on <STDIN>...\n"
-        if -t STDIN; ## no critic (InputOutput::ProhibitInteractiveTest)
-    $query = do { local $/; <> };
-}
-
-my $resp = $client->execute($query, $variables, $operation_name, $transport);
-my $err  = $resp->{errors};
-$unpack = 0 if $err;
-my $data = $unpack ? $resp->{data} : $resp;
-
-if ($outfile) {
-    open(my $out, '>', $outfile) or die "Open $outfile failed: $!";
-    *STDOUT = $out;
-}
-
-print_data($data, $format);
-
-exit($unpack && $err ? 1 : 0);
-
-sub print_data {
-    my ($data, $format) = @_;
-    $format = lc($format || 'json:pretty');
-    if ($format eq 'json' || $format eq 'json:pretty') {
-        my %opts = (canonical => 1, utf8 => 1);
-        $opts{pretty} = 1 if $format eq 'json:pretty';
-        print JSON::MaybeXS->new(%opts)->encode($data);
-    }
-    elsif ($format eq 'yaml') {
-        eval { require YAML } or die "Missing dependency: YAML\n";
-        print YAML::Dump($data);
-    }
-    elsif ($format eq 'csv' || $format eq 'tsv' || $format eq 'table') {
-        my $sep = $format eq 'tsv' ? "\t" : ',';
-
-        my $unpacked = $data;
-        $unpacked = $data->{data} if !$unpack && !$err;
-
-        # check the response to see if it can be formatted
-        my @columns;
-        my $rows = [];
-        if (keys %$unpacked == 1) {
-            my ($val) = values %$unpacked;
-            if (ref $val eq 'ARRAY') {
-                my $first = $val->[0];
-                if ($first && ref $first eq 'HASH') {
-                    @columns = sort keys %$first;
-                    $rows = [
-                        map { [@{$_}{@columns}] } @$val
-                    ];
-                }
-                elsif ($first) {
-                    @columns = keys %$unpacked;
-                    $rows = [map { [$_] } @$val];
-                }
-            }
-        }
+use GraphQL::Client::CLI;
 
-        if (@columns) {
-            if ($format eq 'table') {
-                eval { require Text::Table::Any } or die "Missing dependency: Text::Table::Any\n";
-                my $table = Text::Table::Any::table(
-                    header_row  => 1,
-                    rows        => [[@columns], @$rows],
-                    backend     => $ENV{PERL_TEXT_TABLE},
-                );
-                print $table;
-            }
-            else {
-                eval { require Text::CSV } or die "Missing dependency: Text::CSV\n";
-                my $csv = Text::CSV->new({binary => 1, sep => $sep, eol => $/});
-                $csv->print(*STDOUT, [@columns]);
-                for my $row (@$rows) {
-                    $csv->print(*STDOUT, $row);
-                }
-            }
-        }
-        else {
-            print_data($data);
-            print STDERR sprintf("Error: Response could not be formatted as %s.\n", uc($format));
-            exit 3;
-        }
-    }
-    elsif ($format eq 'perl') {
-        eval { require Data::Dumper } or die "Missing dependency: Data::Dumper\n";
-        print Data::Dumper::Dumper($data);
-    }
-    else {
-        print STDERR "Error: Format not supported: $format\n";
-        print_data($data);
-        exit 3;
-    }
-}
-
-sub expand_vars {
-    my $vars = shift;
-
-    my %out;
-    while (my ($key, $value) = each %$vars) {
-        my $var = $value;
-        my @segments = split(/\./, $key);
-        for my $segment (reverse @segments) {
-            my $saved = $var;
-            if ($segment =~ /^(\d+)$/) {
-                $var = [];
-                $var->[$segment] = $saved;
-            }
-            else {
-                $var = {};
-                $var->{$segment} = $saved;
-            }
-        }
-        %out = (%out, %$var);
-    }
-
-    return \%out;
-}
-
-sub pod2usage {
-    eval { require Pod::Usage };
-    if ($@) {
-        my $ref  = $VERSION eq '999.999' ? 'master' : "v$VERSION";
-        my $exit = (@_ == 1 && $_[0] =~ /^\d+$/ && $_[0]) //
-                   (@_ % 2 == 0 && {@_}->{'-exitval'})    // 2;
-        print STDERR <<END;
-Online documentation is available at:
+our $VERSION = '0.605'; # VERSION
 
-  https://github.com/chazmcgarvey/graphql-client/blob/$ref/README.md
-
-Tip: To enable inline documentation, install the Pod::Usage module.
-
-END
-        exit $exit;
-    }
-    else {
-        goto &Pod::Usage::pod2usage;
-    }
-}
+GraphQL::Client::CLI->main(@ARGV);
 
 __END__
 
@@ -228,14 +26,14 @@ graphql - Command-line GraphQL client
 
 =head1 VERSION
 
-version 0.600
+version 0.605
 
 =head1 SYNOPSIS
 
     graphql <URL> <QUERY> [ [--variables JSON] | [--variable KEY=VALUE]... ]
             [--operation-name NAME] [--transport KEY=VALUE]...
-            [--[no-]unpack] [--format json|json:pretty|yaml|perl|csv|tsv|table]
-            [--output FILE]
+            [--[no-]unpack] [--filter JSONPATH]
+            [--format json|json:pretty|yaml|perl|csv|tsv|table] [--output FILE]
 
     graphql --version|--help|--manual
 
@@ -299,7 +97,8 @@ Aliases: C<--vars>, C<-V>
 
 =head2 C<--variable KEY=VALUE>
 
-An alternative way to provide variables. Repeat this option to provide multiple variables.
+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.
 
@@ -339,9 +138,18 @@ By default, the response structure is printed as-is from the server, and the pro
 
 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.
+structure is printed as-is and the program exits 1. See L</EXAMPLES> to see what this looks like in
+practice.
 
-See L</EXAMPLES>.
+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
 
@@ -485,6 +293,10 @@ 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
@@ -513,6 +325,16 @@ 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
@@ -524,7 +346,13 @@ feature.
 
 =head1 AUTHOR
 
-Charles McGarvey <chazmcgarvey@brokenzipper.com>
+Charles McGarvey <ccm@cpan.org>
+
+=head1 CONTRIBUTOR
+
+=for stopwords jwright
+
+jwright <jwright@ecstuning.com>
 
 =head1 COPYRIGHT AND LICENSE
 
This page took 0.03083 seconds and 4 git commands to generate.