Middleware library for creating apps for Gemini protocol on top of Deno runtime using TypeScript
Repository
Current version released
3 years ago
Versions
Kaksik
Middleware library for creating applications for Gemini protocol on top of Deno runtime, written in TypeScript.
Heavily inspired by oak and denoscuri.
Feature roadmap
- Serve gemtext (out of the box, see
TODO: Gemtext docs
) - Serve static files at configured URLs (via middleware, see serveStatic)
- Serve programmable resources at configured URLs (via middleware, see handleRoutes)
- Serve redirect responses at configured URLs (via middleware, see handleRedirects)
- Serve gone responses at configured URLs (via middleware)
- Improve
Response
class - Document
Gemtext
usage - – ‘Good enough’ point –
- Propose yours by filing an issue
Usage
Prerequisites
- Install Deno executable
- Obtain SSL certificates. You can generate self-signed ones using
openssl
command:openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
Your first app
Create minimal application in app.ts
:
import { Application } from 'https://deno.land/x/kaksik/mod.ts'
const app = new Application({
keyFile: '/path/to/key.pem',
certFile: '/path/to/cert.pem',
})
app.use(ctx => {
ctx.response.body = '# Hello World!'
})
await app.start()
Then run it:
deno run --allow-net --allow-read app.ts
Other examples
See examples
folder.
Available middleware
serveStatic
Serves static files from a directory to specified URL
import { Application, serveStatic } from 'https://deno.land/x/kaksik/mod.ts'
const app = new Application({
keyFile: '/path/to/key.pem',
certFile: '/path/to/cert.pem',
})
app.use(serveStatic('./log/', '/gemlog/'))
app.use(serveStatic('./public/'))
await app.start()
Beware of ordering of serveStatic
middleware usages: more generic URLs should occur
later that more specific, e.g., /path/subpath/
must be before /path/
.
handleRoutes
Runs specified async function when request path matches configured route.
import {
Application,
handleRoutes,
Route,
} from 'https://deno.land/x/kaksik/mod.ts'
const app = new Application({
keyFile: '/path/to/key.pem',
certFile: '/path/to/cert.pem',
})
app.use(handleRoutes(
new Route('/test', async (ctx) => {
ctx.response.body = '# Test page'
}),
new Route<{id?: string}>('/param/:id', async (ctx) => {
ctx.response.body = '# Parametrized page\r\n' +
'id = ' + ctx.pathParams.id
}),
new Route('/', async (ctx) => {
ctx.response.body = '# HOME page\r\n' +
'=> /test Test page served by other route\r\n' +
'=> /param/7 Parametrized page, where id=7\r\n' +
'=> /404 No routes matched'
}),
))
app.use(async (ctx) => {
ctx.response.body = '# No routes matched\r\n' +
'Running fallback middleware'
})
await app.start()
handleRedirects
Sends either temporary or permanent redirect response when path matches configuration.
import {
Application,
handleRedirects,
handleRoutes,
Redirect,
Route,
} from 'https://deno.land/x/kaksik/mod.ts'
const app = new Application({
keyFile: '/path/to/key.pem',
certFile: '/path/to/cert.pem',
})
app.use(handleRedirects(
new Redirect('/short', '/long-very-long-url', true),
new Redirect('/home', 'https://tymo.name'),
))
app.use(handleRoutes(
new Route('/long-very-long-url', async (ctx) => {
ctx.response.body = '# Redirect target page'
}),
))
await app.start()
Trivia
“Kaksik” means “twin” in Estonian.