kequapp
Version:
A minimal, zero-magic Node web framework built on native APIs
43 lines (42 loc) • 1.86 kB
JavaScript
import fs from 'node:fs';
import path from 'node:path';
import { createAction } from "../../router/modules.js";
import guessContentType from "../../util/guess-content-type.js";
import { validateArray, validateExists, validateObject, validatePathname, } from "../../util/validate.js";
import Ex from "../tools/ex.js";
import sendFile from "./send-file.js";
export default function staticDirectory(options) {
validateOptions(options);
return createAction(async ({ req, res, params }) => {
const location = await getLocation(options.location, params.wild, options.index);
const contentType = guessContentType(location, options.contentTypes);
await sendFile(req, res, location, contentType);
});
}
function validateOptions(options) {
validateExists(options, 'Static directory options');
validateObject(options, 'Static directory options');
validateExists(options.location, 'Static directory options.location');
validatePathname(options.location, 'Static directory options.location');
validateArray(options.index, 'Static directory options.index', 'string');
validateObject(options.contentTypes, 'Static directory options.contentTypes', 'string');
}
async function getLocation(location, wild = '', index = []) {
const absolute = path.join(process.cwd(), location, wild);
try {
const stats = await fs.promises.stat(absolute);
if (stats.isDirectory() && index.length > 0) {
const files = await fs.promises.readdir(absolute);
for (const file of index) {
if (files.includes(file))
return path.join(location, wild, file);
}
}
if (stats.isFile())
return path.join(location, wild);
}
catch (_error) {
// fail
}
throw Ex.NotFound(undefined, { absolute, index });
}