2025-06-19 15:43:01 -07:00
# SERVERUS
A flexible HTTP server for mixed content. Throw static files, markdown, Typescript
and (hopefully, eventually) more into a directory and serverus can serve it up a
bit more like old-school CGI.
## Usage
Compiled:
```
2025-06-30 15:21:07 -07:00
[user@machine ] ~/ serverus --root ./public
2025-06-19 15:43:01 -07:00
```
Container:
```
2025-07-14 20:28:37 -07:00
podman run -d -p 8000:8000 -v /var/public:/www --name web andyburke/serverus:latest
2025-06-19 15:43:01 -07:00
```
Deno:
```
2025-06-30 15:21:07 -07:00
deno --allow-env --allow-read --allow-write --allow-net jsr:@andyburke/serverus --root ./public
2025-06-19 15:43:01 -07:00
```
## Overview
SERVERUS is a Deno-based webserver that allows for various handlers to serve up
different types of content with a great deal of control.
The default handlers are:
2025-06-30 15:21:07 -07:00
- HTML with SSI support
2025-07-14 19:22:59 -07:00
eg:
```
< html >
< body >
<!-- #include file="./header.html" -->
<!-- can include markdown, which will be converted to html -->
<!-- #include file="./essay.md" -->
< div id = "footer" >
<!-- you can include text files as well -->
<!-- #include file="./somedir/footer.txt" >
< / div >
< / body >
< / html >
```
2025-06-19 15:43:01 -07:00
- markdown
will serve markdown as HTML (or raw with an Accept header of text/markdown)
- Typescript
you can put .ts files in your root folder (including in 'parameter' directories,
eg: ./book/:book_id/index.ts) and if they export methods like `GET` and `POST` ,
they will be called for those requests. there's some additional stuff you can
export to ease typical use cases, covered below.
2025-06-30 15:21:07 -07:00
- static files
will serve up static files within the root folder
2025-06-19 15:43:01 -07:00
You just start serverus in a directory (or specify a root) and it tells you where it's
listening.
2025-06-25 17:06:05 -07:00
## Environment Variables
- `SERVERUS_ROOT` : set the root, aka --root on the command line
- `SERVERUS_HANDLERS` : a list of ;-separated directories to look for handlers in
2025-08-01 20:11:17 -07:00
- `SERVERUS_PUT_PATHS_ALLOWED` : a list of ;-separated directories for which file uploads via PUT are allowed
- `SERVERUS_DELETE_PATHS_ALLOWED` : a list of ;-separated directories for which file deletions via DELETE are allowed
2025-06-25 17:06:05 -07:00
2025-11-20 16:44:49 -08:00
### Singe-Page Applications (SPA)
If you place a `.spa` file under the root, that directory will try to return an `index.html` or `index.htm` file that lives in it for any requests that are relative to it. For example:
```
www/
app/
.spa
index.html
```
If you have this file structure (assuming `www` is the root), a `GET` to `/app/foo/bar` will return the `index.html` file in the `app/` directory. (Which would then presumably handle the url in `window.location` appropriately.)
2025-06-19 15:43:01 -07:00
### Typescript Handling
These types and interface define the default serverus Typescript handler's expected
structure:
```typescript
export type PRECHECK = (
request: Request,
meta: Record< string , any >
) => undefined | Response | Promise< undefined | Response > ;
2025-06-25 15:30:55 -07:00
export type PRECHECKS_TABLE = Record< 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH', PRECHECK[]>;
2025-06-19 15:43:01 -07:00
export type ROUTE_HANDLER_METHOD = (request: Request, meta: Record< string , any > ) => Promise< Response > | Response;
export interface ROUTE_HANDLER {
PRECHECKS?: PRECHECKS_TABLE;
GET?: ROUTE_HANDLER_METHOD;
POST?: ROUTE_HANDLER_METHOD;
PUT?: ROUTE_HANDLER_METHOD;
DELETE?: ROUTE_HANDLER_METHOD;
PATCH?: ROUTE_HANDLER_METHOD;
default?: ROUTE_HANDLER_METHOD;
}
```
A default exported method will be called for any unspecified methods and can
decide what to do with the request itself.
2025-06-25 15:30:55 -07:00
`PRECHECKS` can defined a precheck per-method, eg: `PRECHECKS.GET = [( request, meta ) => ...]`
2025-06-19 15:43:01 -07:00
A precheck method should return a `Response` if there's an error that should stop
the request from proceeding. For example, if you require a session for a given route,
you could add a `PRECHECK` that checks for headers/cookies and tries to retrieve a
session, perhaps adding it to the `meta` data that will be passed to the `GET`
handler itself. If there is no session, however, it should return an HTTP `Response`
object indicating permission is denied or similar.
2025-08-11 17:12:55 -07:00
#### _pre.ts files
Any `_pre.ts` files found under the root that export `.load()` and/or `.unload()` methods
will be loaded and those functions will be called at server startup/shutdown, respectively.
2025-06-19 15:43:01 -07:00
#### NOTE ON WINDOWS
Because Windows has more restrictions on filenames, you can use `___` in place of `:` in
parameter directories.
2025-09-11 11:32:58 -07:00
### Examples
TODO: write me
## TODO
- [ ] write examples above
- [ ] reload typescript if it is modified on disk
- [X] wrap markdown converted to html in a div with a class for styling
## CHANGELOG
- 0.13.0
- wrap converted markdown in an `html-from-markdown` class