package JSON::Validator;
use Mojo::Base -base;
use Carp qw(confess);
use JSON::Validator::Store;
use JSON::Validator::Util qw(E data_checksum is_type);
use Mojo::Util qw(sha1_sum);
use Sca
our %SCHEMAS = (
'http://json-schema.org/draft-04/schema#' => '+Draft4',
'http://json-schema.org/draft-06/schema#' => '+Draft6',
'http://json-schema.org/draft-07/schema#
' => '+Draft7',
'https://json-schema.org/draft/2019-09/schema' => '+Draft201909',
'http://swagger.io/v2/schema.json' => '+OpenAPIv2',
'https://spec.openapis
JSON::Validator::Schema::Draft201909;
use Mojo::Base 'JSON::Validator::Schema';
use JSON::Validator::Schema::Draft4;
use JSON::Validator::Schema::Draft6;
use JSON::Validator::Schema::Draft7;
use JSON
::Validator::URI qw(uri);
use JSON::Validator::Util qw(E is_bool is_type);
has moniker => 'draft2019';
has specification => 'https://json-schema.org/draft/2019-09/schema';
has _ref_keys =>
my $formats = shift->JSON::Validator::Schema::Draft7::_build_formats;
$formats->{duration} = JSON::Validator::Formats->can('check_duration');
$formats->{uuid} = JSON::Validator::Formats->ca
e JSON::Validator::Store;
use Mojo::Base -base;
use Mojo::Exception;
use Mojo::File qw(path);
use Mojo::JSON;
use Mojo::JSON::Pointer;
use Mojo::UserAgent;
use Mojo::Util qw(url_unescape);
use JSON::
Validator::Schema;
use JSON::Validator::URI qw(uri);
use JSON::Validator::Util qw(data_section str2data);
use Scalar::Util qw(blessed);
use constant DEBUG => $ENV{JSON_VALIDATOR_DEBUG} && 1;
ase_tolerant;
die $@ unless eval q(package JSON::Validator::Exception; use Mojo::Base 'Mojo::Exception'; 1);
has cache_paths => sub { [split(/:/, $ENV{JSON_VALIDATOR_CACHE_PATH} || ''), BUNDLED_PATH
package JSON::Validator::OpenAPI::Mojolicious;
use Mojo::Base 'JSON::Validator::OpenAPI';
sub _get_request_data {
my ($self, $c, $in) = @_;
return $c->req->url->query->to_hash if $in eq 'query'
f $in eq 'formData';
return $c->req->headers->to_hash if $in eq 'header';
return $c->req->json if $in eq 'body';
$self->_invalid_in($in);
}
sub _get_request_uploads {
my (
$in);
}
}
1;
=encoding utf8
=head1 NAME
JSON::Validator::OpenAPI::Mojolicious - Request/response adapter for Mojolicious
=head1 SYNOPSIS
See L<JSON::Validator::OpenAPI/SYNOPSIS>.
=head1 DESCR
package JSON::Validator::URI;
use Mojo::Base 'Mojo::URL';
use Exporter qw(import);
use Digest::SHA ();
use Mojo::JSON;
use Scalar::Util qw(blessed);
use constant UUID_NAMESPACE => do {
my $uuid =
>nid('uuid');
state $d = Digest::SHA->new(1);
$d->reset->add(UUID_NAMESPACE)->add(Mojo::JSON::encode_json(shift));
my $uuid = substr $d->digest, 0, 16;
substr $uuid, 6, 1, chr(ord(substr $uuid
clone;
}
1;
=encoding utf8
=head1 NAME
JSON::Validator::URI - Uniform Resource Identifier
=head1 SYNOPSIS
use JSON::Validator::URI;
my $urn = JSON::Validator::URI->new('urn:uuid:ee564b8a-7a
package JSON::Validator::OpenAPI::Dancer2;
use Hash::MultiValue;
use Mojo::Base 'JSON::Validator::OpenAPI';
sub _get_request_data {
my ($self, $dsl, $in) = @_;
if ($in eq 'query') {
return $
_in($in);
}
}
1;
=encoding utf8
=head1 NAME
JSON::Validator::OpenAPI::Dancer2 - Request/response adapter for Dancer2
=head1 SYNOPSIS
See L<JSON::Validator::OpenAPI/SYNOPSIS>.
=head1 DESCRIPTI
ON
This module contains private methods to get/set request/response data for
L<Dancer2>.
=head1 SEE ALSO
L<Dancer2::Plugin::OpenAPI>.
L<JSON::Validator>.
=cut
JSON::Validator::Schema;
use Mojo::Base 'JSON::Validator'; # TODO: Change this to "use Mojo::Base -base"
use Carp qw(carp);
use JSON::Validator::Formats;
use JSON::Validator::URI qw(uri);
use JSON
type prefix_errors schema_type str2data);
use List::Util qw(first uniq);
use Mojo::JSON qw(false true);
use Mojo::JSON::Pointer;
use Mojo::Util qw(deprecated);
use Scalar::Util qw(blessed);
has error
s => sub {
my $self = shift;
my $specification = $self->specification || 'http://json-schema.org/draft-04/schema#';
my $validator = $self->new(store => $self->store, _refs => {})->coerc
package JSON::Validator::OpenAPI;
use Carp ();
use Mojo::Base 'JSON::Validator';
use Mojo::Util qw(deprecated monkey_patch);
use Scalar::Util ();
use constant DEBUG => $ENV{JSON_VALIDATOR_DEBUG} || 0
=> 'http://swagger.io/v2/schema.json';
my %COLLECTION_RE = (pipes => qr{\|}, csv => qr{,}, ssv => qr{\s}, tsv => qr{\t});
has _json_validator => sub { state $v = JSON::Validator->new; };
sub load_a
nd_validate_spec {
my ($self, $spec, $args) = @_;
my $openapi = JSON::Validator->new->schema($args->{schema} || SPECIFICATION_URL);
my ($api_spec, @errors);
# 1. first check if $ref is in the
package JSON::Validator::Joi;
use Mojo::Base -base;
use Exporter 'import';
use List::Util qw(uniq);
use Mojo::JSON qw(false true);
use Mojo::Util;
use Scalar::Util qw(blessed);
use Storable qw(dclone
"Subroutine redefined" warnings
require JSON::Validator::Schema::Draft7;
has enum => sub { +[] };
has type => 'object';
has validator => sub { JSON::Validator::Schema::Draft7->new->coerce(
f = shift;
my $json = {type => $self->type};
$json->{additionalItems} = false if $self->{strict};
$json->{maxItems} = $self->{max} if defined $self->{max};
$json->{minItems}
package JSON::Validator::Formats;
use Mojo::Base -strict;
use Scalar::Util 'looks_like_number';
require Time::Local;
use constant DATA_VALIDATE_DOMAIN => eval 'require Data::Validate::Domain;1';
us
_IDN_ENCODE => eval 'require Net::IDN::Encode;1';
use constant WARN_MISSING_MODULE => $ENV{JSON_VALIDATOR_WARN} // 1;
our $IRI_TEST_NAME = 'iri-reference';
sub check_byte {
$_[0] =~ /^[A-Za
t not start with //.';
}
return undef;
}
sub check_json_pointer {
return !length $_[0] || $_[0] =~ m!^/! ? undef : 'Does not match json-pointer format.';
}
sub check_ipv4 {
return undef if
package JSON::Validator::Schema::Draft7;
use Mojo::Base 'JSON::Validator::Schema';
use JSON::Validator::Schema::Draft4;
use JSON::Validator::Schema::Draft6;
use JSON::Validator::Util qw(E is_type);
=> 'http://json-schema.org/draft-07/schema#';
sub _build_formats {
return {
'date' => JSON::Validator::Formats->can('check_date'),
'date-time' => JSON::Validato
=> JSON::Validator::Formats->can('check_email'),
'hostname' => JSON::Validator::Formats->can('check_hostname'),
'idn-email' => JSON::Validator::Format
package JSON::Validator::Schema::OpenAPIv3;
use Mojo::Base 'JSON::Validator::Schema::Draft201909';
use JSON::Validator::Util qw(E data_type negotiate_content_type schema_type);
use Mojo::JSON
19-04-02';
require JSON::Validator::Schema::OpenAPIv2;
*coerce = \&JSON::Validator::Schema::OpenAPIv2::coerce;
*errors = \&JSON::Validator::Schema:
= \&JSON::Validator::Schema::OpenAPIv2::routes;
*validate_request = \&JSON::Validator::Schema::OpenAPIv2::validate_request;
*validate_response = \&JSON::Validator
package JSON::Validator::Schema::Draft6;
use Mojo::Base 'JSON::Validator::Schema';
use JSON::Validator::Schema::Draft4;
use JSON::Validator::URI qw(uri);
use JSON::Validator::Util qw(E data_type is_t
'http://json-schema.org/draft-06/schema#';
sub _build_formats {
return {
'date-time' => JSON::Validator::Formats->can('check_date_time'),
'email' => JSON::Valida
me' => JSON::Validator::Formats->can('check_hostname'),
'ipv4' => JSON::Validator::Formats->can('check_ipv4'),
'ipv6' => JSON::Validator::Formats
package JSON::Validator::Schema::OpenAPIv2;
use Mojo::Base 'JSON::Validator::Schema::Draft4';
use JSON::Validator::Util qw(E data_type negotiate_content_type schema_type);
use Mojo::Collection;
my $
->data)];
};
has moniker => 'openapiv2';
has specification => 'http://swagger.io/v2/schema.json';
sub add_default_response {
my ($self, $params) = ($_[0], shift->_params_for_add_default_resp
> sub {undef},
'byte' => JSON::Validator::Formats->can('check_byte'),
'date' => JSON::Validator::Formats->can('check_date'),
'date-time' => JSON::Validator::Formats->can('check_d
package JSON::Validator::Util;
use Mojo::Base -strict;
use B;
use Carp ();
use Exporter 'import';
use JSON::Validator::Error;
use List::Util;
use Mojo::Collection;
use Mojo::JSON;
use Mojo::Loader;
u
se Mojo::Util;
use Scalar::Util 'blessed';
use constant SEREAL_SUPPORT => !$ENV{JSON_VALIDATOR_NO_SEREAL} && eval 'use Sereal::Encoder 4.00;1';
use constant CORE_BOOL => defined &builtin::is_boo
ool is_num is_type),
qw(negotiate_content_type prefix_errors schema_type str2data),
);
sub E { JSON::Validator::Error->new(@_) }
my $serializer = SEREAL_SUPPORT ? \&_sereal_encode : \&_yaml_dump;
package JSON::Validator::Schema::Draft4;
use Mojo::Base 'JSON::Validator::Schema';
use JSON::Validator::Util qw(E data_checksum data_type is_type);
use List::Util 'uniq';
has id => sub {
my $data
fication => 'http://json-schema.org/draft-04/schema#';
sub _build_formats {
return {
'date-time' => JSON::Validator::Formats->can('check_date_time'),
'email' => JSON::Validator::Formats
JSON::Validator::Formats->can('check_hostname'),
'ipv4' => JSON::Validator::Formats->can('check_ipv4'),
'ipv6' => JSON::Validator::Formats->can('check_ipv6'),
'regex' => JSON
package JSON::Validator::Error;
use Mojo::Base -base;
use overload q("") => \&to_string, bool => sub {1}, fallback => 1;
our $MESSAGES = {
allOf => {type => '/allOf Expected %3 - got %4.'},
anyO
ge }
sub TO_JSON { {message => $_[0]->message, path => $_[0]->path} }
1;
=encoding utf8
=head1 NAME
JSON::Validator::Error - JSON::Validator error object
=head1 SYNOPSIS
use JSON::Validator:
:Error;
my $err = JSON::Validator::Error->new($path, $message);
=head1 DESCRIPTION
L<JSON::Validator::Error> is a class representing validation errors from
L<JSON::Validator>.
=head1 ATTRIBUTES