UNPKG

@ladjs/koa-better-static

Version:

Static file serving middleware for koa

80 lines (65 loc) 1.71 kB
const { normalize, resolve, parse, sep } = require('node:path'); const resolvePath = require('resolve-path'); const debug = require('debug')('@ladjs/koa-better-static'); const send = require('./send'); module.exports = serve; /** * Serve static files from `root`. * * @param {String} root * @param {Object} [opts] * @return {Function} * @api public */ function serve(root, opts = {}) { if (typeof root !== 'string') throw new Error('`root` argument missing'); if (opts.maxAge) { opts.maxage = opts.maxAge; delete opts.maxAge; } const options = { index: false, maxage: 0, hidden: false, ifModifiedSinceSupport: true, ...opts }; const normalizedRoot = normalize(resolve(root)); // Options debug('static "%s" %j', root, opts); return async function (ctx, next) { if (ctx.method === 'HEAD' || ctx.method === 'GET') { let path = ctx.path.slice(parse(ctx.path).root.length); try { path = decodeURIComponent(path); } catch { ctx.throw('Could not decode path', 400); return; } if (options.index && ctx.path.at(-1) === '/') { path += options.index; } path = resolvePath(normalizedRoot, path); if (!options.hidden && isHidden(root, path)) { return; } if (await send(ctx, path, options)) { return; } } return next(); }; } function isHidden(root, path) { path = path.slice(root.length).split(sep); // optimized with `findIndex` /* for (let i = 0; i < path.length; i++) { if (path[i][0] === '.') { return true; } } return false; */ return path.findIndex((segment) => segment[0] === '.') !== -1; }