wai-middleware-preprocessor- WAI middleware for preprocessing static files

Safe HaskellNone




Serve files subject to a preprocessing function. This library makes it easy to integrate Javascript or CSS preprocessors into a WAI application that will compile the relevant files at runtime



ppMiddleware :: Preprocessor -> Middleware Source

Run a preprocessor on incoming requests

For example, if your preprocessor has input extension ".fay" and output extension ".js" (and just does the identity function)

ppMiddleware (preprocessor ".fay" ".js" (Just))

and a request to "index.js" goes through the generated middleware

GET "/index.js"

If "index.js" exists, it does nothing

If "index.js" does not exist, it does the following:

If "index.fay" exists, it will read it in, run the function on its content, and it will write the output to "index.js"

Otherwise, it will do nothing

Finally, in all cases, it will pass the request along

ppFileMiddleware :: Policy -> Preprocessor -> Middleware Source

Preprocessor composed with static file server

This function is just the composition of staticPolicy from wai-middleware-static and ppMiddleware. The policy creation functions from that library are also exported from this library for ease of use.


data Preprocessor Source

Preprocessors are comprised of an input file extension (String), an output file extension (String), and a transforming function (Text -> Maybe Text)

preprocessor Source


:: String

input extension

-> String

output extension

-> (Text -> Maybe Text)

transforming function

-> Preprocessor


Constructor for a preprocessor.

runPreprocessor :: Preprocessor -> FilePath -> IO () Source

Run the preprocessor on a given file

preprocess :: FilePath -> FilePath -> (Text -> Maybe Text) -> IO () Source

Read in the input file, run through the preprocessor, and write it out


data Policy :: *

Take an incoming URI and optionally modify or filter it. The result will be treated as a filepath.


Monoid Policy

Note: mempty == policy Just (the always accepting policy) mappend == >-> (policy sequencing)

(<|>) :: Policy -> Policy -> Policy infixr 4

Choose between two policies. If the first fails, run the second.

(>->) :: Policy -> Policy -> Policy infixr 5

Sequence two policies. They are run from left to right. (Note: this is mappend)

policy :: (String -> Maybe String) -> Policy

Lift a function into a Policy

predicate :: (String -> Bool) -> Policy

Lift a predicate into a Policy

addBase :: String -> Policy

Add a base path to the URI

staticPolicy (addBase "/home/user/files")

GET "foo/bar" looks for "/home/user/files/foo/bar"

addSlash :: Policy

Add an initial slash to to the URI, if not already present.

staticPolicy addSlash

GET "foo/bar" looks for "/foo/bar"

contains :: String -> Policy

Accept only URIs containing given string

hasPrefix :: String -> Policy

Accept only URIs with given prefix

hasSuffix :: String -> Policy

Accept only URIs with given suffix

noDots :: Policy

Reject URIs containing ".."

isNotAbsolute :: Policy

Reject URIs that are absolute paths

only :: [(String, String)] -> Policy

Use URI as the key to an association list, rejecting those not found. The policy result is the matching value.

staticPolicy (only [("foo/bar", "/home/user/files/bar")])

GET "foo/bar" looks for "/home/user/files/bar" GET "baz/bar" doesn't match anything


tryPolicy :: Policy -> String -> Maybe String

Run a policy