2023-01-17 08:40:54 +00:00
|
|
|
import type { Context } from '../../context.ts'
|
|
|
|
import type { Next } from '../../types.ts'
|
|
|
|
import { getFilePath } from '../../utils/filepath.ts'
|
|
|
|
import { getMimeType } from '../../utils/mime.ts'
|
2022-07-02 14:20:09 +00:00
|
|
|
|
2023-06-26 08:14:40 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
|
// @ts-ignore
|
2023-07-15 05:28:48 +00:00
|
|
|
const { open } = Deno
|
2023-06-26 08:14:40 +00:00
|
|
|
|
2022-07-02 14:20:09 +00:00
|
|
|
export type ServeStaticOptions = {
|
|
|
|
root?: string
|
|
|
|
path?: string
|
2023-05-03 14:05:21 +00:00
|
|
|
rewriteRequestPath?: (path: string) => string
|
2022-07-02 14:20:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const DEFAULT_DOCUMENT = 'index.html'
|
|
|
|
|
2022-09-27 12:40:37 +00:00
|
|
|
export const serveStatic = (options: ServeStaticOptions = { root: '' }) => {
|
|
|
|
return async (c: Context, next: Next) => {
|
2022-07-02 14:20:09 +00:00
|
|
|
// Do nothing if Response is already set
|
2022-09-02 12:13:47 +00:00
|
|
|
if (c.finalized) {
|
2022-07-02 14:20:09 +00:00
|
|
|
await next()
|
2022-10-09 15:11:36 +00:00
|
|
|
return
|
2022-07-02 14:20:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const url = new URL(c.req.url)
|
2023-05-03 14:05:21 +00:00
|
|
|
const filename = options.path ?? decodeURI(url.pathname)
|
2022-07-02 14:20:09 +00:00
|
|
|
let path = getFilePath({
|
2023-05-03 14:05:21 +00:00
|
|
|
filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
|
2022-07-02 14:20:09 +00:00
|
|
|
root: options.root,
|
|
|
|
defaultDocument: DEFAULT_DOCUMENT,
|
|
|
|
})
|
|
|
|
|
2023-07-26 23:37:20 +00:00
|
|
|
if (!path) return await next()
|
|
|
|
|
2022-07-02 14:20:09 +00:00
|
|
|
path = `./${path}`
|
2022-09-19 03:22:55 +00:00
|
|
|
|
2023-07-15 05:28:48 +00:00
|
|
|
let file
|
2022-09-19 03:22:55 +00:00
|
|
|
|
|
|
|
try {
|
2023-07-15 05:28:48 +00:00
|
|
|
file = await open(path)
|
2022-09-19 03:22:55 +00:00
|
|
|
} catch (e) {
|
|
|
|
console.warn(`${e}`)
|
|
|
|
}
|
|
|
|
|
2023-07-15 05:28:48 +00:00
|
|
|
if (file) {
|
2022-07-02 14:20:09 +00:00
|
|
|
const mimeType = getMimeType(path)
|
|
|
|
if (mimeType) {
|
|
|
|
c.header('Content-Type', mimeType)
|
|
|
|
}
|
2023-07-15 05:28:48 +00:00
|
|
|
// Return Response object with stream
|
|
|
|
return c.body(file.readable)
|
2022-07-02 14:20:09 +00:00
|
|
|
} else {
|
|
|
|
console.warn(`Static file: ${path} is not found`)
|
|
|
|
await next()
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|