use v6.d.PREVIEW; use Cro::HTTP::Router; use Cro::HTTP::Request; use Cro::HTTP::Response; use Cro::Transform; use Cro; class Ultramarine::Controller { has $.license is required; has $.authorisation is required; has $.collection is required; sub respond(*@body) { response.status = 200; response.set-body(@body); } my class URLRewrite does Cro::Transform { method consumes() { Cro::HTTP::Request } method produces() { Cro::HTTP::Request } my token prefix { '/rest' } my token api-method { '/' \w+ } my token suffix { '.view' } my token query { '?' .* } my token api-url { ^ ? $ } method transformer(Supply $requests --> Supply) { supply whenever $requests -> $request { with $request { if (.target ~~ //) { emit .clone( original-target => .original-target // .target, target => ($).join, ); } else { emit $_; } } } } } method inner-routes() { return route { # this needs to be here, not in the Server because its # short-circuited "unauthorised" response will be emited # in an 'after' middleware, but the # ResponseSerializerExtension is applied just before those # middlewares, so our serialised won't be seen by the # "unauthorised" response before $!authorisation; post my $ping = -> 'ping' { respond [] } get $ping; post my $getLicense = -> 'getLicense' { my $expires = $.license.expires-at.DateTime.truncated-to('second'); respond [ :status, license => [ :valid($.license.is-valid.Str.lc), :email($.license.email), :licenseExpires($expires.yyyy-mm-dd ~ ':' ~ $expires.hh-mm-ss), ], ], } get $getLicense; post my $getMusicFolders = -> 'getMusicFolders' { respond [ :status, musicFolders => [ musicFolder => [ :id<0>, :name ], ] ], } get $getMusicFolders; # this is clearly not a Subsonic method get -> 'dakkarList' { await $.collection.is-ready; respond [ :status, songs => $.collection.all-songs, ]; } } } method routes() { return Cro.compose( URLRewrite, route { include 'rest' => self.inner-routes() }, ); } }