package OX::Meta::Middleware;
BEGIN {
$OX::Meta::Middleware::AUTHORITY = 'cpan:STEVAN';
}
$OX::Meta::Middleware::VERSION = '0.14';
use Moose;
use namespace::autoclean;
has middleware => (
is => 'ro',
isa => 'OX::Types::Middleware',
required => 1,
);
has dependencies => (
is => 'ro',
isa => 'HashRef',
default => sub { +{} },
);
has lifecycle => (
is => 'ro',
isa => 'Str',
);
has condition => (
is => 'ro',
isa => 'CodeRef',
);
has service => (
is => 'ro',
isa => 'Bread::Board::Service',
lazy => 1,
default => sub {
my $self = shift;
my $mw = $self->middleware;
my $deps = $self->dependencies;
my %common = (
name => '__ANON__',
(defined $self->lifecycle
? (lifecycle => $self->lifecycle)
: ()),
);
my $mw_service;
if (!ref($mw)) {
$mw_service = Bread::Board::BlockInjection->new(
%common,
block => sub {
my $s = shift;
my $mw_obj = $mw->new(
map { $_ => $s->param($_) } $s->get_param_keys
);
# this should just be sub { $mw_obj->wrap($_[0]) }
# (actually, this whole thing should just be a constructor
# injection) but wrap calls to_app, which calls prepare_app
# every time, which we'd like to avoid for singleton
# middleware. it is kind of gross though, would be nice to
# maybe push this back into plack
$mw_obj->prepare_app;
return sub {
my $app = shift;
$mw_obj->{app} = $app;
sub { $mw_obj->call(@_) };
};
},
dependencies => $deps,
);
}
elsif (blessed($mw)) {
$mw_service = Bread::Board::Literal->new(
%common,
value => $mw,
);
}
else {
$mw_service = Bread::Board::BlockInjection->new(
%common,
block => sub {
my $s = shift;
return sub {
my $app = shift;
return $mw->($app, $s);
};
},
dependencies => $deps,
);
}
return $mw_service;
},
);
sub resolve {
my $self = shift;
my ($container) = @_;
my $mw_service = $self->service;
$mw_service->parent($container);
my $resolved_mw = $mw_service->get;
$mw_service->detach_from_parent;
if (my $condition = $self->condition) {
require Plack::Middleware::Conditional;
my $builder = $resolved_mw;
$resolved_mw = sub {
Plack::Middleware::Conditional->new(
condition => $condition,
builder => sub {
OX::Util::apply_middleware($_[0], $builder)
},
)->wrap($_[0]);
};
}
return $resolved_mw;
}
__PACKAGE__->meta->make_immutable;
=for Pod::Coverage
resolve
=cut
1;