tsx webapps and directories

This commit is contained in:
Chris Wanstrath 2025-09-15 14:18:53 -07:00
parent c3e10559c7
commit 15301f9126
7 changed files with 50 additions and 10 deletions

4
nose/app/dir/index.ts Normal file
View File

@ -0,0 +1,4 @@
import { text } from "./other"
export default (c: Context) =>
c.text(text)

1
nose/app/dir/other.ts Normal file
View File

@ -0,0 +1 @@
export const text = "w00000t!"

View File

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

2
nose/app/jsx.tsx Normal file
View File

@ -0,0 +1,2 @@
export default (c: Context) =>
<b>Very cool!</b>

View File

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

View File

@ -1,25 +1,57 @@
import type { Context } from "hono" import type { Context } from "hono"
import type { Child } from "hono/jsx"
import { join } from "node:path" import { join } from "node:path"
import { NOSE_APP } from "./config" import { NOSE_APP } from "./config"
import { isFile } from "./utils" import { isFile } from "./utils"
type App = (r: Context) => string | Child | Response
export async function serveApp(c: Context, subdomain: string): Promise<Response> { export async function serveApp(c: Context, subdomain: string): Promise<Response> {
const app = await findApp(subdomain) const app = await findApp(subdomain)
if (app) if (app)
return app(c) return await toResponse(app(c))
return c.text(`App Not Found: ${subdomain}`, 404) return c.text(`App Not Found: ${subdomain}`, 404)
} }
async function findApp(name: string): Promise<((r: Context) => Response) | undefined> { async function findApp(name: string): Promise<App | undefined> {
const path = join(NOSE_APP, `${name}.ts`) let path = join(NOSE_APP, `${name}.ts`)
let app = await loadApp(path)
if (app) return app
if (isFile(path)) { path = join(NOSE_APP, `${name}.tsx`)
const mod = await import(path + `?t=${Date.now()}`) app = await loadApp(path)
if (mod?.default) if (app) return app
return mod.default as (r: Context) => Response
} path = join(NOSE_APP, name, "index.ts")
app = await loadApp(path)
if (app) return app
path = join(NOSE_APP, name, "index.tsx")
app = await loadApp(path)
if (app) return app
console.error("can't find app:", name) console.error("can't find app:", name)
} }
async function loadApp(path: string): Promise<App | undefined> {
if (!isFile(path)) return
const mod = await import(path + `?t=${Date.now()}`)
if (mod?.default)
return mod.default as App
}
async function toResponse(source: string | Child | Response): Promise<Response> {
if (source instanceof Response)
return source
else if (typeof source === "string")
return new Response(source)
else
return new Response(await source?.toString(), {
headers: {
"Content-Type": "text/html; charset=utf-8"
}
})
}

View File

@ -6,6 +6,7 @@
"module": "Preserve", "module": "Preserve",
"moduleDetection": "force", "moduleDetection": "force",
"jsx": "react-jsx", "jsx": "react-jsx",
"jsxImportSource": "hono/jsx",
"allowJs": true, "allowJs": true,
// Bundler mode // Bundler mode