HTTPurple
- Package
- purescript-httpurple
- Repository
- sigma-andex/purescript-httpurple
Re-exports from Data.Generic.Rep
#Generic Source
class Generic a rep | a -> rep
The Generic
class asserts the existence of a type function from types
to their representations using the type constructors defined in this module.
Re-exports from HTTPurple.Body
#toString Source
toString :: forall m. MonadAff m => RequestBody -> m String
Turn RequestBody
into a String
This drains the Readable
stream in RequestBody
for the first time
and returns cached result from then on.
#toStream Source
toStream :: RequestBody -> Readable ()
Return the Readable
stream directly from RequestBody
#toBuffer Source
toBuffer :: forall m. MonadAff m => RequestBody -> m Buffer
Turn RequestBody
into a Buffer
This drains the Readable
stream in RequestBody
for the first time
and returns cached result from then on.
Re-exports from HTTPurple.Cont
#usingCont Source
usingCont :: forall output m. Applicative m => ContT output m output -> m output
Run the continuation
Re-exports from HTTPurple.Headers
#ResponseHeaders Source
newtype ResponseHeaders
The ResponseHeaders
type is a wrapper for a map
that represents the set of headers in an HTTP response.
A response header can contain multiple values per key,
e.g. in the case of multiple Set-Cookie directives.
Instances
Semigroup ResponseHeaders
Show ResponseHeaders
Allow a
ResponseHeaders
to be represented as a string. This string is formatted in HTTP headers format.Eq ResponseHeaders
Compare two
ResponseHeaders
objects by comparing the underlyingObjects
.
#RequestHeaders Source
newtype RequestHeaders
The RequestHeaders
type is a wrapper for a map
that represents the set of headers in an HTTP request.
A request header contains maximum one value per key.
Instances
Newtype RequestHeaders _
Lookup RequestHeaders String String
Given a string, return a
Maybe
containing the value of the matching header, if there is any.Show RequestHeaders
Allow a
RequestHeaders
to be represented as a string. This string is formatted in HTTP headers format.Eq RequestHeaders
Compare two
RequestHeaders
objects by comparing the underlyingObjects
.Semigroup RequestHeaders
Allow one
RequestHeaders
objects to be appended to another.
#headers Source
headers :: forall r. ToHeaders r => r -> ResponseHeaders
Create ResponseHeaders
from a record, an Array (Tuple String String)
or an Array (Tuple String (Array String))
#header Source
header :: String -> String -> ResponseHeaders
Create a singleton header from a key-value pair.
#empty Source
empty :: ResponseHeaders
Return a ResponseHeaders
containing no headers.
Re-exports from HTTPurple.Json
#JsonEncoder Source
newtype JsonEncoder json
Constructors
JsonEncoder (json -> String)
Instances
Newtype (JsonEncoder json) (json -> String)
#JsonDecoder Source
newtype JsonDecoder err json
Constructors
JsonDecoder (String -> Either err json)
Instances
Newtype (JsonDecoder err json) (String -> Either err json)
#toJson Source
toJson :: forall (json :: Type). JsonEncoder json -> json -> String
Serialise a type to json using the given driver.
#fromJson Source
fromJson :: forall (err :: Type) (json :: Type) (m :: Type -> Type). MonadAff m => JsonDecoder err json -> RequestBody -> ContT Response m json
Parse the RequestBody
as json using the provided JsonDecoder
.
If it fails, an empty bad request is returned
Returns a continuation
Re-exports from HTTPurple.Lookup
#(!@) Source
Operator alias for HTTPurple.Lookup.at (left-associative / precedence 8)
Expose at
as the infix operator !@
#(!?) Source
Operator alias for HTTPurple.Lookup.has (left-associative / precedence 8)
Expose has
as the infix operator !?
#(!!) Source
Operator alias for HTTPurple.Lookup.lookup (left-associative / precedence 8)
!!
is inspired by !!
in Data.Array
, but note that it differs from
!!
in Data.Array
in that you can use !!
for any other instance of
Lookup
.
Re-exports from HTTPurple.Method
Re-exports from HTTPurple.Middleware
#MiddlewareM Source
type MiddlewareM :: (Type -> Type) -> Type -> Row Type -> Row Type -> Type
type MiddlewareM m route extIn extOut = (ExtRequest route extOut -> m Response) -> ExtRequest route extIn -> m Response
#Middleware Source
type Middleware :: Type -> Row Type -> Row Type -> Type
type Middleware route extIn extOut = MiddlewareM Aff route extIn extOut
Re-exports from HTTPurple.NodeMiddleware
#NodeMiddlewareStack Source
newtype NodeMiddlewareStack :: Row Type -> Row Type -> Type
newtype NodeMiddlewareStack input output
Constructors
NodeMiddlewareStack (MiddlewareResult input -> ContT (MiddlewareResult output) Effect (MiddlewareResult input))
Instances
Newtype (NodeMiddlewareStack input output) (MiddlewareResult input -> ContT (MiddlewareResult output) Effect (MiddlewareResult input))
#NodeMiddleware Source
newtype NodeMiddleware :: forall k. k -> Type
newtype NodeMiddleware extended
Constructors
NodeMiddleware (EffectFn3 (IncomingMessage IMServer) ServerResponse (EffectFn1 (UndefinedOr Error) Unit) (Effect Unit))
Instances
Newtype (NodeMiddleware extended) _
#NextInvocation Source
#MiddlewareResultR Source
type MiddlewareResultR :: Row Type
type MiddlewareResultR = (middlewareResult :: NextInvocation, request :: IncomingMessage IMServer, response :: ServerResponse)
#MiddlewareResult Source
newtype MiddlewareResult :: forall k. k -> Type
newtype MiddlewareResult input
Constructors
Instances
Newtype (NodeMiddlewareStack input output) (MiddlewareResult input -> ContT (MiddlewareResult output) Effect (MiddlewareResult input))
#UsingMiddleware Source
class UsingMiddleware :: Row Type -> Row Type -> Row Type -> Constraint
class UsingMiddleware input thru output | input thru -> output where
Members
usingMiddleware :: NodeMiddleware thru -> MiddlewareResult input -> ContT (MiddlewareResult output) Effect (MiddlewareResult input)
Instances
(Union input thru tmp, Union tmp tmp2 output) => UsingMiddleware input thru output
#dontCallNext Source
dontCallNext :: forall (m :: Type -> Type). Applicative m => m Unit
#callNextWithError Source
callNextWithError :: EffectFn1 NextHandlerArg Unit -> Error -> Effect Unit
Re-exports from HTTPurple.Path
#Path Source
type Path = Array String
The Path
type is just sugar for an Array
of String
segments that are
sent in a request and indicates the path of the resource being requested.
Note that this type has an implementation of Lookup
for Int
keys
defined by lookupArray
in Lookup.purs because
lookupArray
is defined for any Array
of Monoids
. So you can do
something like path !! 2
to get the path segment at index 2.
Re-exports from HTTPurple.Query
#Query Source
type Query = Object String
The Query
type is a Object
of Strings
, with one entry per query
parameter in the request. For any query parameters that don't have values
(/some/path?query
or /some/path?query=
), the value in the Object
for
that parameter will be the an empty string. Note that this type has an
implementation of Lookup
for String
keys defined by lookupObject
in
Lookup.purs because lookupObject
is defined for any
Object
of Monoids
. So you can do something like query !! "foo"
to get
the value of the query parameter "foo".
Re-exports from HTTPurple.Request
#ExtRequest Source
type ExtRequest :: Type -> Row Type -> Type
type ExtRequest route ext = Record (RequestR route ext)
Like Request
, but can contain additional fields
Re-exports from HTTPurple.Response
#Response Source
type Response = { headers :: ResponseHeaders, status :: Status, writeBody :: ServerResponse -> Aff Unit }
A Response
is a status code, headers, and a body.
#variantAlsoNegotiates' Source
variantAlsoNegotiates' :: forall m. MonadAff m => ResponseHeaders -> m Response
506 with headers
#variantAlsoNegotiates Source
variantAlsoNegotiates :: forall m. MonadAff m => m Response
506
#useProxy' Source
useProxy' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
305 with headers
#upgradeRequired' Source
upgradeRequired' :: forall m. MonadAff m => ResponseHeaders -> m Response
426 with headers
#upgradeRequired Source
upgradeRequired :: forall m. MonadAff m => m Response
426
#unsupportedMediaType' Source
unsupportedMediaType' :: forall m. MonadAff m => ResponseHeaders -> m Response
415 with headers
#unsupportedMediaType Source
unsupportedMediaType :: forall m. MonadAff m => m Response
415
#unprocessableEntity' Source
unprocessableEntity' :: forall m. MonadAff m => ResponseHeaders -> m Response
422 with headers
#unprocessableEntity Source
unprocessableEntity :: forall m. MonadAff m => m Response
422
#unauthorized' Source
unauthorized' :: forall m. MonadAff m => ResponseHeaders -> m Response
401 with headers
#unauthorized Source
unauthorized :: forall m. MonadAff m => m Response
401
#uRITooLong' Source
uRITooLong' :: forall m. MonadAff m => ResponseHeaders -> m Response
414 with headers
#uRITooLong Source
uRITooLong :: forall m. MonadAff m => m Response
414
#tooManyRequests' Source
tooManyRequests' :: forall m. MonadAff m => ResponseHeaders -> m Response
429 with headers
#tooManyRequests Source
tooManyRequests :: forall m. MonadAff m => m Response
429
#temporaryRedirect' Source
temporaryRedirect' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
307 with headers
#temporaryRedirect Source
temporaryRedirect :: forall m b. MonadAff m => Body b => b -> m Response
307
#switchingProtocols' Source
switchingProtocols' :: forall m. MonadAff m => ResponseHeaders -> m Response
101 with headers
#switchingProtocols Source
switchingProtocols :: forall m. MonadAff m => m Response
101
#seeOther' Source
seeOther' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
303 with headers
#resetContent' Source
resetContent' :: forall m. MonadAff m => ResponseHeaders -> m Response
205 with headers
#resetContent Source
resetContent :: forall m. MonadAff m => m Response
205
#requestTimeout' Source
requestTimeout' :: forall m. MonadAff m => ResponseHeaders -> m Response
408 with headers
#requestTimeout Source
requestTimeout :: forall m. MonadAff m => m Response
408
#requestHeaderFieldsTooLarge' Source
requestHeaderFieldsTooLarge' :: forall m. MonadAff m => ResponseHeaders -> m Response
431 with headers
#requestHeaderFieldsTooLarge Source
requestHeaderFieldsTooLarge :: forall m. MonadAff m => m Response
431
#rangeNotSatisfiable' Source
rangeNotSatisfiable' :: forall m. MonadAff m => ResponseHeaders -> m Response
416 with headers
#rangeNotSatisfiable Source
rangeNotSatisfiable :: forall m. MonadAff m => m Response
416
#proxyAuthenticationRequired' Source
proxyAuthenticationRequired' :: forall m. MonadAff m => ResponseHeaders -> m Response
407 with headers
#proxyAuthenticationRequired Source
proxyAuthenticationRequired :: forall m. MonadAff m => m Response
407
#processing' Source
processing' :: forall m. MonadAff m => ResponseHeaders -> m Response
102 with headers
#processing Source
processing :: forall m. MonadAff m => m Response
102
#preconditionRequired' Source
preconditionRequired' :: forall m. MonadAff m => ResponseHeaders -> m Response
428 with headers
#preconditionRequired Source
preconditionRequired :: forall m. MonadAff m => m Response
428
#preconditionFailed' Source
preconditionFailed' :: forall m. MonadAff m => ResponseHeaders -> m Response
412 with headers
#preconditionFailed Source
preconditionFailed :: forall m. MonadAff m => m Response
412
#permanentRedirect' Source
permanentRedirect' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
308 with headers
#permanentRedirect Source
permanentRedirect :: forall m b. MonadAff m => Body b => b -> m Response
308
#paymentRequired' Source
paymentRequired' :: forall m. MonadAff m => ResponseHeaders -> m Response
402 with headers
#paymentRequired Source
paymentRequired :: forall m. MonadAff m => m Response
402
#payloadTooLarge' Source
payloadTooLarge' :: forall m. MonadAff m => ResponseHeaders -> m Response
413 with headers
#payloadTooLarge Source
payloadTooLarge :: forall m. MonadAff m => m Response
413
#partialContent' Source
partialContent' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
206 with headers
#ok' Source
ok' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
200 with headers
#notModified' Source
notModified' :: forall m. MonadAff m => ResponseHeaders -> m Response
304 with headers
#notModified Source
notModified :: forall m. MonadAff m => m Response
304
#notImplemented' Source
notImplemented' :: forall m. MonadAff m => ResponseHeaders -> m Response
501 with headers
#notImplemented Source
notImplemented :: forall m. MonadAff m => m Response
501
#notExtended' Source
notExtended' :: forall m. MonadAff m => ResponseHeaders -> m Response
510 with headers
#notExtended Source
notExtended :: forall m. MonadAff m => m Response
510
#notAcceptable' Source
notAcceptable' :: forall m. MonadAff m => ResponseHeaders -> m Response
406 with headers
#notAcceptable Source
notAcceptable :: forall m. MonadAff m => m Response
406
#nonAuthoritativeInformation' Source
nonAuthoritativeInformation' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
203 with headers
#nonAuthoritativeInformation Source
nonAuthoritativeInformation :: forall m b. MonadAff m => Body b => b -> m Response
203
#noContent' Source
noContent' :: forall m. MonadAff m => ResponseHeaders -> m Response
204 with headers
#networkAuthenticationRequired' Source
networkAuthenticationRequired' :: forall m. MonadAff m => ResponseHeaders -> m Response
511 with headers
#networkAuthenticationRequired Source
networkAuthenticationRequired :: forall m. MonadAff m => m Response
511
#multipleChoices' Source
multipleChoices' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
300 with headers
#multiStatus' Source
multiStatus' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
207 with headers
#movedPermanently' Source
movedPermanently' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
301 with headers
#misdirectedRequest' Source
misdirectedRequest' :: forall m. MonadAff m => ResponseHeaders -> m Response
421 with headers
#misdirectedRequest Source
misdirectedRequest :: forall m. MonadAff m => m Response
421
#methodNotAllowed' Source
methodNotAllowed' :: forall m. MonadAff m => ResponseHeaders -> m Response
405 with headers
#methodNotAllowed Source
methodNotAllowed :: forall m. MonadAff m => m Response
405
#loopDetected' Source
loopDetected' :: forall m. MonadAff m => ResponseHeaders -> m Response
508 with headers
#loopDetected Source
loopDetected :: forall m. MonadAff m => m Response
508
#lengthRequired' Source
lengthRequired' :: forall m. MonadAff m => ResponseHeaders -> m Response
411 with headers
#lengthRequired Source
lengthRequired :: forall m. MonadAff m => m Response
411
#internalServerError' Source
internalServerError' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
500 with headers
#internalServerError Source
internalServerError :: forall m b. MonadAff m => Body b => b -> m Response
500
#insufficientStorage' Source
insufficientStorage' :: forall m. MonadAff m => ResponseHeaders -> m Response
507 with headers
#insufficientStorage Source
insufficientStorage :: forall m. MonadAff m => m Response
507
#imATeapot' Source
imATeapot' :: forall m. MonadAff m => ResponseHeaders -> m Response
418 with headers
#iMUsed' Source
iMUsed' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
226 with headers
#hTTPVersionNotSupported' Source
hTTPVersionNotSupported' :: forall m. MonadAff m => ResponseHeaders -> m Response
505 with headers
#hTTPVersionNotSupported Source
hTTPVersionNotSupported :: forall m. MonadAff m => m Response
505
#gatewayTimeout' Source
gatewayTimeout' :: forall m. MonadAff m => ResponseHeaders -> m Response
504 with headers
#gatewayTimeout Source
gatewayTimeout :: forall m. MonadAff m => m Response
504
#found' Source
found' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
302 with headers
#forbidden' Source
forbidden' :: forall m. MonadAff m => ResponseHeaders -> m Response
403 with headers
#failedDependency' Source
failedDependency' :: forall m. MonadAff m => ResponseHeaders -> m Response
424 with headers
#failedDependency Source
failedDependency :: forall m. MonadAff m => m Response
424
#expectationFailed' Source
expectationFailed' :: forall m. MonadAff m => ResponseHeaders -> m Response
417 with headers
#expectationFailed Source
expectationFailed :: forall m. MonadAff m => m Response
417
#emptyResponse' Source
emptyResponse' :: forall m. MonadAff m => Status -> ResponseHeaders -> m Response
The same as emptyResponse
but with headers.
#emptyResponse Source
emptyResponse :: forall m. MonadAff m => Status -> m Response
The same as response
but without a body.
#conflict' Source
conflict' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
409 with headers
#badRequest' Source
badRequest' :: forall m b. MonadAff m => Body b => ResponseHeaders -> b -> m Response
400 with headers
#badGateway' Source
badGateway' :: forall m. MonadAff m => ResponseHeaders -> m Response
502 with headers
#badGateway Source
badGateway :: forall m. MonadAff m => m Response
502
#alreadyReported' Source
alreadyReported' :: forall m. MonadAff m => ResponseHeaders -> m Response
208 with headers
#alreadyReported Source
alreadyReported :: forall m. MonadAff m => m Response
208
Re-exports from HTTPurple.Routes
#mkRoute Source
mkRoute :: forall i iGen r. Generic i iGen => GRouteDuplex iGen r => Record r -> RouteDuplex i i
Make a route from a RoudeDuplex
definition.
#combineRoutes Source
combineRoutes :: forall left right. RouteDuplex' left -> RouteDuplex' right -> RouteDuplex' (Either left right)
Combine two routes
#(<+>) Source
Operator alias for HTTPurple.Routes.combineRoutes (right-associative / precedence 3)
Infix operator for orElse
#type (<+>) Source
Operator alias for Data.Either.Either (right-associative / precedence 0)
Type-level operator two combine two route definitions.
Re-exports from HTTPurple.Server
#RoutingSettingsR Source
type RoutingSettingsR :: Type -> Row Type -> Row Type -> Row Type
type RoutingSettingsR route output r = (route :: RouteDuplex' route, router :: ExtRequest route output -> ResponseM | r)
#MiddlewareSettingsR Source
type MiddlewareSettingsR :: Row Type -> Row Type -> Row Type
type MiddlewareSettingsR input output = (nodeMiddleware :: NodeMiddlewareStack input output)
#ListenOptions Source
type ListenOptions = Record ListenOptionsR
#ExtRoutingSettings Source
type ExtRoutingSettings :: Type -> Row Type -> Row Type -> Type
type ExtRoutingSettings route input output = Record (RoutingSettingsR route output) + (MiddlewareSettingsR input output)
#BasicRoutingSettings Source
type BasicRoutingSettings route = Record (RoutingSettingsR route () ())
#serveNodeMiddleware Source
serveNodeMiddleware :: forall route from fromRL via missing missingList input output outputRL thru. RowToList missing missingList => FillableFields missingList () missing => Union via missing (ListenOptionsR) => RowToList from fromRL => JustifiableFields fromRL from () via => Union output thru output => RowToList output outputRL => KeysRL outputRL => Nub (RequestR route output) (RequestR route output) => Record from -> ExtRoutingSettings route input output -> ServerM
#serve Source
serve :: forall route from fromRL via missing missingList. RowToList missing missingList => FillableFields missingList () missing => Union via missing (ListenOptionsR) => RowToList from fromRL => JustifiableFields fromRL from () via => Record from -> BasicRoutingSettings route -> ServerM
Re-exports from HTTPurple.Status
Re-exports from HTTPurple.Validation
#fromValidated Source
fromValidated :: forall input err validated m. MonadAff m => (input -> Either err validated) -> input -> ContT Response m validated
Validate an input using a validate function. If validation fails, a bad request is resturned. Returns a continuation
Re-exports from Routing.Duplex
#RouteDuplex' Source
type RouteDuplex' a = RouteDuplex a a
A type restricted variant of RouteDuplex
where input and output are
the same type. This type will typically be your custom Route
data type
representing valid routes within your application.
#RouteDuplex Source
data RouteDuplex i o
The core abstraction of this library. The values of this type can be used both for parsing
values of type o
from String
as well as printing values of type i
into String
.
For most purposes, you'll likely want RouteDuplex'
which uses the same
type for both parameters.
Constructors
RouteDuplex (i -> RoutePrinter) (RouteParser o)
Instances
Functor (RouteDuplex i)
Apply (RouteDuplex i)
Applicative (RouteDuplex i)
Profunctor RouteDuplex
(IsSymbol sym, Cons sym (RouteDuplex String String -> RouteDuplex a b) rx1 r1, Cons sym a rx2 r2, Cons sym b r3 rx3, Lacks sym r3, RouteDuplexBuildParams rest r1 r2 rx3 r4) => RouteDuplexBuildParams (Cons sym (RouteDuplex String String -> RouteDuplex a b) rest) r1 r2 r3 r4
#RouteDuplexBuildParams Source
class RouteDuplexBuildParams :: RowList Type -> Row Type -> Row Type -> Row Type -> Row Type -> Constraint
class RouteDuplexBuildParams (rl :: RowList Type) (r1 :: Row Type) (r2 :: Row Type) (r3 :: Row Type) (r4 :: Row Type) | rl -> r1 r2 r3 r4 where
Members
buildParams :: Proxy rl -> Record r1 -> RouteDuplex (Record r2) (Record r3) -> RouteDuplex (Record r2) (Record r4)
Instances
(IsSymbol sym, Cons sym (RouteDuplex String String -> RouteDuplex a b) rx1 r1, Cons sym a rx2 r2, Cons sym b r3 rx3, Lacks sym r3, RouteDuplexBuildParams rest r1 r2 rx3 r4) => RouteDuplexBuildParams (Cons sym (RouteDuplex String String -> RouteDuplex a b) rest) r1 r2 r3 r4
RouteDuplexBuildParams Nil r1 r2 r3 r3
#RouteDuplexParams Source
class RouteDuplexParams :: Row Type -> Row Type -> Constraint
class RouteDuplexParams (r1 :: Row Type) (r2 :: Row Type) | r1 -> r2 where
Members
params :: Record r1 -> RouteDuplex' (Record r2)
Builds a
RouteDuplex
from a record of query parameter parsers/printers, where each property corresponds to a query parameter with the same name.search = params { page: int , filter: optional <<< string } parse search "?page=3&filter=Galaxy%20Quest" == Right { page: 3, filter: Just "Galaxy Quest" }
Instances
(RowToList r1 rl, RouteDuplexBuildParams rl r1 r2 () r2) => RouteDuplexParams r1 r2
#suffix Source
suffix :: forall a b. RouteDuplex a b -> String -> RouteDuplex a b
Similar to prefix
. Strips (when parsing) or adds (when printing) a given
string segment from the end of the path. The same precautions for prefix
apply here.
#string Source
string :: RouteDuplex' String -> RouteDuplex' String
This does nothing (internally it's defined as identity).
It can be used to restrict a type parameter of a polymorphic RouteDuplex' a
to String
.
#segment Source
segment :: RouteDuplex' String
Consumes or prints a single path segment. Note: URI encoding and decoding is done automatically.
parse segment "abc" == Right "abc"
parse segment "abc%20def" == Right "abc def" -- automatic decoding of uri components
parse segment "abc/def" == Right "abc"
parse segment "/abc" == Right "" -- the empty string before the first '/'
parse (root segment) "/abc" == Right "abc"
print segment "hello there" == "hello%20there"
print segment "" == "/"
#root Source
root :: forall a b. RouteDuplex a b -> RouteDuplex a b
Modifies a given codec to require a prefix of '/'. You can think of it as stripping and adding the '/' at the beginning of path, failing if it's not there.
parse (root segment) "/abc" == Right "abc"
parse (root segment) "abc" == Left (Expected "" "abc")
print (root segment) "abc" == "/abc"
#rest Source
rest :: RouteDuplex' (Array String)
Consumes or prints all the remaining segments.
parse rest "" == Right []
parse (path "a/b" rest) "a/b/c/d" == Right ["c", "d"]
print rest ["a", "b"] == "a/b"
#record Source
record :: forall r. RouteDuplex r (Record ())
Combined with prop
or :=
, builds a Record where the order of
parsing and printing matters.
date =
record
# prop (Proxy :: _ "year") (int segment)
# prop (Proxy :: _ "month") (int segment)
# prop (Proxy :: _ "day") (int segment)
parse (path "blog" date) "blog/2019/1/2" ==
Right { year: 2019, month: 1, day: 2 }
#prop Source
prop :: forall sym a b r1 r2 r3 rx. IsSymbol sym => Cons sym a rx r1 => Cons sym b r2 r3 => Lacks sym r2 => Proxy sym -> RouteDuplex a b -> RouteDuplex (Record r1) (Record r2) -> RouteDuplex (Record r1) (Record r3)
See record
.
#print Source
print :: forall i o. RouteDuplex i o -> i -> String
Renders a value of type i
into a String representation of URI path,
query and fragment (hash).
#prefix Source
prefix :: forall a b. String -> RouteDuplex a b -> RouteDuplex a b
Strips (when parsing) or adds (when printing) a given string segment of the
path. Note: this combinator only deals with a single segment.
If you pass it a string containing '/' it will percent encode it and treat it as single segment.
E.g. prefix "/api/v1"
will attempt to match single segment "%2Fapi%2Fv1"
which is probably not what you want.
See path
if you want to deal with prefixes consisting of multiple segments.
parse (prefix "api" segment) "api/a" == Right "a"
parse (prefix "/api/v1" segment)) "/api/v1/a" == Left (Expected "/api/v1" "")
-- contrast with `path`
parse (path "/api/v1" segment)) "/api/v1/a" == Right "a"
#path Source
path :: forall a b. String -> RouteDuplex a b -> RouteDuplex a b
Strips (when parsing) or adds (when printing) a given String prefix,
potentially consisting of multiple path segments. Constrast this with prefix
,
which only deals with single segment.
parse (path "/api/v1" segment) "/api/v1/a" == Right "a"
parse (path "/api/v1" segment) "/api/v2/a" == Left (Expected "v1" "v2")
#parse Source
parse :: forall i o. RouteDuplex i o -> String -> Either RouteError o
Uses a given codec to parse a value of type o
out of String representing
the path, query and fragment (hash) of a URI (see
URI - generic syntax)
or produce a RouteError
if parsing fails.
#param Source
param :: String -> RouteDuplex' String
param name
consumes or prints a query parameter with the given name
.
Parsing will fail if the parameter is not there.
parse (param "search") "?search=keyword" == Right "keyword"
parse (param "search") "/" == Left (MissingParam "search")
parse (optional (param "search")) "/" == Right Nothing
#optional Source
optional :: forall a b. RouteDuplex a b -> RouteDuplex (Maybe a) (Maybe b)
Augments the behavior of a given codec by making it return Nothing
if parsing
fails, or Just value
if it succeeds.
parse (optional segment) "a" == Right (Just "a")
parse (optional segment) "" == Right Nothing
print (optional segment) (Just "a") == "a"
print (optional segment) Nothing == ""
#many1 Source
many1 :: forall f a b. Foldable f => Alt f => Applicative f => RouteDuplex a b -> RouteDuplex (f a) (f b)
Repeatedly applies a given codec to parse one or more values from path segments. Parsing will fail if no segment can be parsed.
parse (many1 (int segment)) "1/2/3/x" == Right [1,2,3]
parse (many1 (int segment)) "x", == Left (Expected "Int" "x") :: Either RouteError (Array Int)
#many Source
many :: forall f a b. Foldable f => Alternative f => RouteDuplex a b -> RouteDuplex (f a) (f b)
Similar to many1
, except also succeeds when no values can be parsed.
parse (many (int segment)) "1/2/3/x" == Right [1,2,3]
parse (many (int segment)) "x", == Right []
#int Source
int :: RouteDuplex' String -> RouteDuplex' Int
Refines a codec of Strings to Ints.
parse (int segment) "1" == Right 1
parse (int segment) "x" == Left (Expected "Int" "x")
print (int segment) 1 == "1"
#flag Source
flag :: RouteDuplex' String -> RouteDuplex' Boolean
Consumes or prints a query flag (i.e. parameter without value).
Note: that this combinator ignores the value of the parameter. It only cares about its presence/absence.
Presence is interpreted as true
, absence as false
.
parse (flag (param "x")) "?x" == Right true
parse (flag (param "x")) "?x=true", == Right true
parse (flag (param "x")) "?x=false", == Right true -- value is ignored, what matters is presence of the parameter x
parse (flag (param "x")) "?y", == Right false
#end Source
end :: forall a b. RouteDuplex a b -> RouteDuplex a b
end codec
will only suceed if codec
succeeds and there are no
additional path segments remaining to be processed.
parse (end segment) "abc" == Right "abc"
parse (end segment) "abc/def" == Left (ExpectedEndOfPath "def")
#default Source
default :: forall a b. b -> RouteDuplex a b -> RouteDuplex a b
Sets a default value which will be returned when parsing fails. Does not influence printing in any way.
parse (default 0 $ int segment) "1" == Right 1
parse (default 0 $ int segment) "x" == Right 0
#boolean Source
boolean :: RouteDuplex' String -> RouteDuplex' Boolean
Refines a codec of Strings to Booleans, where true
and false
are the
strings "true"
and "false"
, and other strings are rejected.
parse (boolean segment) "true" == Right true
parse (boolean segment) "x" == Left (Expected "Boolean" "x")
print (boolean segment) true == "true"
#as Source
as :: forall s a b. (a -> s) -> (String -> Either String b) -> RouteDuplex s String -> RouteDuplex a b
Builds a codec for a custom type out of printer and parser functions.
data Sort = Asc | Desc
sortToString :: Sort -> String
sortToString = case _ of
Asc -> "asc"
Desc -> "desc"
sortFromString :: String -> Either String Sort
sortFromString = case _ of
"asc" -> Right Asc
"desc" -> Right Desc
val -> Left $ "Not a sort: " <> val
sort :: RouteDuplex' String -> RouteDuplex' Sort
sort = as sortToString sortFromString
Re-exports from Routing.Duplex.Generic
#GRouteDuplex Source
class GRouteDuplex :: Type -> Row Type -> Constraint
class GRouteDuplex rep (r :: Row Type) | rep -> r
Instances
(GRouteDuplex a r, GRouteDuplex b r) => GRouteDuplex (Sum a b) r
(IsSymbol sym, Cons sym (RouteDuplex a a) rx r, GRouteDuplexCtr a b) => GRouteDuplex (Constructor sym b) r
#GRouteDuplexCtr Source
class GRouteDuplexCtr a b | a -> b
Instances
GRouteDuplexCtr (Product a b) (Product a b)
GRouteDuplexCtr NoArguments NoArguments
GRouteDuplexCtr (Argument a) (Argument a)
GRouteDuplexCtr a (Argument a)
#sum Source
sum :: forall a rep r. Generic a rep => GRouteDuplex rep r => Record r -> RouteDuplex' a
Builds a parser/printer from a record, where each record field corresponds to a constructor name for your data type.
Note: this implicitly inserts calls to end
for each constructor, making
the parser only valid for parsing URI suffixes. To parse URI prefixes, or
to just have more explicit control, use sumPrefix
.
#product Source
product :: forall a b c. GRouteDuplexCtr b c => RouteDuplex' a -> RouteDuplex' b -> RouteDuplex' (Product (Argument a) c)
Re-exports from Routing.Duplex.Generic.Syntax
#gparams Source
gparams :: forall a b c. GParams a b c => a -> b -> RouteDuplex' c
#gsep Source
gsep :: forall a b c. GSep a b c => a -> b -> RouteDuplex' c
- Modules
- HTTPurple
- HTTPurple.
Body - HTTPurple.
Cont - HTTPurple.
Headers - HTTPurple.
Json - HTTPurple.
Lookup - HTTPurple.
Method - HTTPurple.
Middleware - HTTPurple.
NodeMiddleware - HTTPurple.
Path - HTTPurple.
Query - HTTPurple.
Request - HTTPurple.
Response - HTTPurple.
Routes - HTTPurple.
Server - HTTPurple.
Status - HTTPurple.
Utils - HTTPurple.
Validation - HTTPurple.
Version
Allow one
ResponseHeaders
objects to be appended to another.