webapp basics

This commit is contained in:
Chris Wanstrath 2025-09-15 14:03:07 -07:00
parent 931bb597f4
commit c3e10559c7
8 changed files with 56 additions and 2 deletions

2
nose/app/hello.ts Normal file
View File

@ -0,0 +1,2 @@
export default (c: Context) =>
c.text("Hello, world!")

2
nose/app/ping.ts Normal file
View File

@ -0,0 +1,2 @@
export default (c: Context) =>
c.text("pong")

3
nose/bin/hello.ts Normal file
View File

@ -0,0 +1,3 @@
export default function (): string {
return "Hello, world!"
}

6
nose/global.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
// src/global.d.ts
import type { Context as HonoContext } from "hono"
declare global {
type Context = HonoContext
}

6
src/config.ts Normal file
View File

@ -0,0 +1,6 @@
import { resolve, join } from "node:path"
export const NOSE_ICON = ` ͡° ͜ʖ ͡°`
export const NOSE_DIR = resolve("./nose")
export const NOSE_BIN = resolve(join(NOSE_DIR, "bin"))
export const NOSE_APP = resolve(join(NOSE_DIR, "app"))

0
src/js/.gitignore vendored Normal file
View File

View File

@ -3,9 +3,9 @@ import { serveStatic } from "hono/bun"
import { prettyJSON } from "hono/pretty-json" import { prettyJSON } from "hono/pretty-json"
import color from "kleur" import color from "kleur"
import { NOSE_ICON, NOSE_DIR, NOSE_BIN, NOSE_APP } from "./config"
import { transpile, isFile } from "./utils" import { transpile, isFile } from "./utils"
import { serveApp } from "./webapp"
export const NOSE_ICON = ` ͡° ͜ʖ ͡°`
// //
// Hono setup // Hono setup
@ -43,7 +43,13 @@ app.get("/js/:path{.+}", async c => {
// app routes // app routes
// //
app.get("*", async c => {
const url = new URL(c.req.url)
const domains = url.hostname.split(".")
const subdomain = domains.length > 1 ? domains[0]! : "none"
return await serveApp(c, subdomain)
})
// //
// server shutdown // server shutdown
@ -70,9 +76,13 @@ for (const sig of ["SIGINT", "SIGTERM"] as const) {
// //
console.log(color.cyan(NOSE_ICON)) console.log(color.cyan(NOSE_ICON))
console.log(color.blue("NOSE_DIR:"), color.yellow(NOSE_DIR))
console.log(color.blue("NOSE_BIN:"), color.yellow(NOSE_BIN))
console.log(color.blue("NOSE_APP:"), color.yellow(NOSE_APP))
export default { export default {
port: process.env.PORT || 3000, port: process.env.PORT || 3000,
hostname: "0.0.0.0",
fetch: app.fetch, fetch: app.fetch,
idleTimeout: 0, idleTimeout: 0,
} }

25
src/webapp.ts Normal file
View File

@ -0,0 +1,25 @@
import type { Context } from "hono"
import { join } from "node:path"
import { NOSE_APP } from "./config"
import { isFile } from "./utils"
export async function serveApp(c: Context, subdomain: string): Promise<Response> {
const app = await findApp(subdomain)
if (app)
return app(c)
return c.text(`App Not Found: ${subdomain}`, 404)
}
async function findApp(name: string): Promise<((r: Context) => Response) | undefined> {
const path = join(NOSE_APP, `${name}.ts`)
if (isFile(path)) {
const mod = await import(path + `?t=${Date.now()}`)
if (mod?.default)
return mod.default as (r: Context) => Response
}
console.error("can't find app:", name)
}