simple-fs-server/routes/dir/[...path].tsx
2023-01-06 18:24:27 +09:00

88 lines
2.3 KiB
TypeScript

import { HandlerContext, Handlers, PageProps } from "$fresh/server.ts";
import { asset, Head } 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: 302,
headers: {
"Location": "/login",
"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(decodeURI(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>
</>
);
}