APISchema

 view release on metacpan or  search on metacpan

LICENSE  view on Meta::CPAN


    b) cause the whole of any work that you distribute or publish, that
    in whole or in part contains the Program or any part thereof, either
    with or without modifications, to be licensed at no charge to all
    third parties under the terms of this General Public License (except
    that you may choose to grant warranty protection to some or all
    third parties, at your option).

    c) If the modified program normally reads commands interactively when
    run, you must cause it, when started running for such interactive use
    in the simplest and most usual way, to print or display an
    announcement including an appropriate copyright notice and a notice
    that there is no warranty (or else, saying that you provide a
    warranty) and that users may redistribute the program under these
    conditions, and telling the user how to view a copy of this General
    Public License.

    d) You may charge a fee for the physical act of transferring a
    copy, and you may at your option offer warranty protection in
    exchange for a fee.

README.md  view on Meta::CPAN

    };

    # Inject routes to an existing router object
    my $router = Router::Simple->new;
    $router->connect(...);
    my $generator = APISchema::Generator::Router::Simple->new;
    $generator->inject_routes($schema => $router);

    # Documentation
    use APISchema::Generator::Markdown;
    print do {
        my $generator = APISchema::Generator::Markdown->new;
        $generator->format_schema($schema);
    };

    # Middleware (in app.psgi)

    enable "APISchema::ResponseValidator", schema => $schema;
    enable "APISchema::RequestValidator", schema => $schema;

# DESCRIPTION

lib/APISchema.pm  view on Meta::CPAN

    };

    # Inject routes to an existing router object
    my $router = Router::Simple->new;
    $router->connect(...);
    my $generator = APISchema::Generator::Router::Simple->new;
    $generator->inject_routes($schema => $router);

    # Documentation
    use APISchema::Generator::Markdown;
    print do {
        my $generator = APISchema::Generator::Markdown->new;
        $generator->format_schema($schema);
    };

    # Middleware (in app.psgi)

    enable "APISchema::ResponseValidator", schema => $schema;
    enable "APISchema::RequestValidator", schema => $schema;

=head1 DESCRIPTION

lib/APISchema/DSL.pm  view on Meta::CPAN


my $_directive = {};

sub process (&) {
    my $dsl = shift;

    my $schema = APISchema::Schema->new;

    local $_directive->{include} = sub {
        my ($file) = @_;
        -r $_[0] or Carp::croak(sprintf 'No such file: %s', $file);
        my $content = file($file)->slurp;
        my $with_utf8 = "use utf8;\n" . $content;
        eval $with_utf8;
        Carp::croak($@) if $@;
    };
    local $_directive->{title} = sub {
        $schema->title(@_);
    };
    local $_directive->{description} = sub {
        $schema->description(@_);

lib/APISchema/DSL.pm  view on Meta::CPAN

sub description ($) { $_directive->{description}->(@_) }
sub filter (&) { $_directive->{filter}->(@_) }
sub resource ($@) { $_directive->{resource}->(@_) }
for my $method (keys %METHODS) {
    no strict 'refs';
    *$method = sub ($@) { goto \&{ $_directive->{$method} } };
}

# disable the global definitions
@$_directive{@DIRECTIVES} = (sub {
    Carp::croak(sprintf(
        q(%s should be called inside 'process {}' block),
        join '/', @DIRECTIVES
    ));
}) x scalar @DIRECTIVES;

1;
__END__

lib/APISchema/Generator/Markdown/ExampleFormatter.pm  view on Meta::CPAN

    my ($self) = @_;
    my $header = $self->spec->{header} or return '';
    my $resource = $header->definition or return '';
    my $example = $self->example($resource);

    return '' unless defined $example;
    return '' unless (ref $example) eq 'HASH';
    return '' unless scalar keys %$example;

    return join "\n", map {
        sprintf '%s: %s', $_ =~ s/[_]/-/gr, $example->{$_};
    } sort keys %$example;
}

sub parameter {
    my ($self) = @_;
    my $parameter = $self->spec->{parameter} or return '';
    my $resource = $parameter->definition or return '';
    my $example = $self->example($resource);

    return '' unless defined $example;
    return '' unless (ref $example) eq 'HASH';
    return '' unless scalar keys %$example;

    return '?' . join '&', map {
        # TODO multiple values?
        sprintf '%s=%s', map { uri_escape_utf8 $_ } $_, $example->{$_};
    } sort keys %$example;
}

sub body {
    my ($self) = @_;
    my $body = $self->spec->{body} or return '';
    my $resource = $body->definition or return '';
    my $example = $self->example($resource);

    return '' unless defined $example;

lib/APISchema/Generator/Markdown/Formatter.pm  view on Meta::CPAN

                return join($bar, map { type($_) } @$union);
            }
        }
    }

    my $ref = ref $def ? $def->{'$ref'} : $def;
    if ($ref) {
        $ref = $ref =~ s!^#/resource/!!r;
        my $ref_text = "`$ref`";
        my $name = $ref =~ s!/.*$!!r;
        $ref_text = sprintf('[%s](#%s)', $ref_text, anchor(resource => $name)) if $name;
        return $ref_text;
    }

    return join $bar, map { code($_) } @{$def->{enum}} if $def->{enum};

    my $type = $def->{type};
    if ($type) {
        return sprintf '`%s`', $type unless ref $type;
        return join $bar, map { code($_) } @{$type} if ref $type eq 'ARRAY';
    }

    return 'undefined';
}

sub json ($) {
    my $x = shift;
    if (ref $x eq 'SCALAR') {
        if ($$x eq 1) {

lib/APISchema/Generator/Markdown/Formatter.pm  view on Meta::CPAN

        $x =~ s/^\[\s*(.*)\s*\]\n$/$1/;
    }
    return $x;
}

sub _code ($) {
    my $text = shift;
    return '' unless defined $text;
    if ($text =~ /[`|]/) {
        $text =~ s/[|]/|/g;
        return sprintf '<code>%s</code>', $text;
    }
    return sprintf '`%s`', $text;
}

sub code ($;$) {
    my ($text, $exists) = @_;
    return $exists ? '`null`' : '' unless defined $text;
    return _code json $text;
}

sub anchor ($$) {
    my ($label, $obj) = @_;
    my $name = ref $obj ? $obj->title : $obj;
    return sprintf '%s-%s', $label, uri_escape_utf8($name);
}

sub restriction ($) {
    my $def = shift;
    return '' unless (ref $def) eq 'HASH';

    my @result = ();
    for my $r (sort @{+RESTRICTIONS}) {
        next unless defined $def->{$r};

        if (ref $def->{$r}) {
            push @result, _code sprintf "$r%s", json $def->{$r};
        } else {
            push @result, _code sprintf "$r(%s)", json $def->{$r};
        }
    }
    return join ' ', @result;
}

sub desc ($) {
    my $text = shift || '';
    $text = $text =~ s/[\r\n].*\z//sr;
    $text = substr($text, 0, SHORT_DESCRIPTION_LENGTH) . '...'
        if length($text) > SHORT_DESCRIPTION_LENGTH;

lib/APISchema/Route.pm  view on Meta::CPAN

    $filter = [qw(header parameter body)] unless scalar @$filter;
    my %filter = map { $_ => 1 } grep { $resource->{$_} } @$filter;
    return +{
        %$resource,
        map {
            my $name = $resource->{$_};
            $_ => APISchema::Resource->new(
                title => $name,
                definition => ,+{
                    %$resource_root,
                    '$ref' => sprintf '#/resource/%s', $name,
                },
            );
        } grep { $filter{$_} } qw(header parameter body),
    };
}

sub canonical_request_resource {
    my ($self, $resource_root, $extra_args, $filter) = @_;
    return $self->_canonical_resource(
        request => $resource_root,

script/generate_markdown_document.pl  view on Meta::CPAN

    use Path::Class qw(file);
    my $Root = file(__FILE__)->dir->parent->resolve->absolute;
    unshift @INC, $Root->subdir('lib').q();
}

# lib
use APISchema::DSL;
use APISchema::Generator::Markdown;

unless ($ARGV[0]) {
    print <<EOM;
Usage: $0 <file>
Options:
  <file>    API definition file.
EOM
    exit;
}

my $schema = APISchema::DSL::process {
    include $ARGV[0];
};

my $generator = APISchema::Generator::Markdown->new;
print encode_utf8 $generator->format_schema($schema);



( run in 0.765 second using v1.01-cache-2.11-cpan-de7293f3b23 )