123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- "use strict";
- const path = require("path");
- const {
- parse
- } = require("url");
- const querystring = require("querystring");
- const getPaths = require("./getPaths");
- /** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
- /** @typedef {import("../index.js").ServerResponse} ServerResponse */
- const cacheStore = new WeakMap();
- /**
- * @param {Function} fn
- * @param {{ cache?: Map<any, any> }} [cache]
- * @returns {any}
- */
- // @ts-ignore
- const mem = (fn, {
- cache = new Map()
- } = {}) => {
- /**
- * @param {any} arguments_
- * @return {any}
- */
- const memoized = (...arguments_) => {
- const [key] = arguments_;
- const cacheItem = cache.get(key);
- if (cacheItem) {
- return cacheItem.data;
- }
- const result = fn.apply(void 0, arguments_);
- cache.set(key, {
- data: result
- });
- return result;
- };
- cacheStore.set(memoized, cache);
- return memoized;
- };
- const memoizedParse = mem(parse);
- /**
- * @template {IncomingMessage} Request
- * @template {ServerResponse} Response
- * @param {import("../index.js").Context<Request, Response>} context
- * @param {string} url
- * @returns {string | undefined}
- */
- function getFilenameFromUrl(context, url) {
- const {
- options
- } = context;
- const paths = getPaths(context);
- let foundFilename;
- let urlObject;
- try {
- // The `url` property of the `request` is contains only `pathname`, `search` and `hash`
- urlObject = memoizedParse(url, false, true);
- } catch (_ignoreError) {
- return;
- }
- for (const {
- publicPath,
- outputPath
- } of paths) {
- let filename;
- let publicPathObject;
- try {
- publicPathObject = memoizedParse(publicPath !== "auto" && publicPath ? publicPath : "/", false, true);
- } catch (_ignoreError) {
- // eslint-disable-next-line no-continue
- continue;
- }
- if (urlObject.pathname && urlObject.pathname.startsWith(publicPathObject.pathname)) {
- filename = outputPath;
- // Strip the `pathname` property from the `publicPath` option from the start of requested url
- // `/complex/foo.js` => `foo.js`
- const pathname = urlObject.pathname.slice(publicPathObject.pathname.length);
- if (pathname) {
- filename = path.join(outputPath, querystring.unescape(pathname));
- }
- let fsStats;
- try {
- fsStats = /** @type {import("fs").statSync} */
- context.outputFileSystem.statSync(filename);
- } catch (_ignoreError) {
- // eslint-disable-next-line no-continue
- continue;
- }
- if (fsStats.isFile()) {
- foundFilename = filename;
- break;
- } else if (fsStats.isDirectory() && (typeof options.index === "undefined" || options.index)) {
- const indexValue = typeof options.index === "undefined" || typeof options.index === "boolean" ? "index.html" : options.index;
- filename = path.join(filename, indexValue);
- try {
- fsStats = /** @type {import("fs").statSync} */
- context.outputFileSystem.statSync(filename);
- } catch (__ignoreError) {
- // eslint-disable-next-line no-continue
- continue;
- }
- if (fsStats.isFile()) {
- foundFilename = filename;
- break;
- }
- }
- }
- }
- // eslint-disable-next-line consistent-return
- return foundFilename;
- }
- module.exports = getFilenameFromUrl;
|