simple-fs-server/routes/dir/[...path].tsx
2023-01-05 18:18:07 +09:00

84 lines
2.3 KiB
TypeScript

import { PageProps, Handlers, HandlerContext } from "$fresh/server.ts";
import { Head, asset } from "$fresh/runtime.ts";
import {removePrefixFromPathname} from "../../util/util.ts";
import { join } from "path/posix.ts";
import DirList, { EntryInfo } from "../../islands/DirList.tsx";
import FileViewer from "../../islands/FileViewer.tsx";
type DirProps = {
type: "dir";
path: string;
stat: Deno.FileInfo;
files: EntryInfo[];
}
type FileProps = {
type: "file";
path: string;
stat: Deno.FileInfo;
}
type DirOrFileProps = DirProps | FileProps;
async function GET(req: Request, ctx: HandlerContext): Promise<Response>{
const authRequired = Deno.env.get("AUTH_REQUIRED") === "true";
if (authRequired) {
const login = ctx.state["login"];
if (!login) {
return new Response(null, {
status: 401,
headers: {
"content-type": "text/plain",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"Access-Control-Allow-Headers": "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
}
});
}
}
const url = new URL(req.url);
const path = removePrefixFromPathname(url.pathname, "/dir");
const stat = await Deno.stat(path);
if (stat.isDirectory){
const filesIter = await Deno.readDir(path);
const files: EntryInfo[] = []
for await (const file of filesIter){
const fileStat = await Deno.stat(join(path, file.name));
files.push({
...file,
lastModified: fileStat.mtime ? new Date(fileStat.mtime) : undefined,
size: fileStat.size
});
}
return await ctx.render({
type: "dir",
stat,
files
, path
})
}
else{
return await ctx.render({
type: "file",
stat, path
});
}
}
export const handler: Handlers = {
GET
}
export default function DirLists(props: PageProps<DirOrFileProps>) {
const data = props.data;
return (<>
<Head>
<title>Simple file server : {data.path}</title>
</Head>
<div class="p-4 mx-auto max-w-screen-md">
{data.type === "dir" ? (<DirList path={data.path} files={data.files}></DirList>) :
(<FileViewer path={data.path}></FileViewer>)}
</div>
</>
);
}