UNPKG

@modern-js/server-core

Version:

A Progressive React Framework for modern web development.

246 lines (245 loc) • 7.58 kB
import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator"; import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array"; import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array"; import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator"; import path from "path"; import { fileReader } from "@modern-js/runtime-utils/fileReader"; import { fs } from "@modern-js/utils"; import { getMimeType } from "hono/utils/mime"; import { sortRoutes } from "../../../utils"; var serverStaticPlugin = function() { return { name: "@modern-js/plugin-server-static", setup: function setup(api) { return { prepare: function prepare() { var _api_useAppContext = api.useAppContext(), middlewares = _api_useAppContext.middlewares, pwd = _api_useAppContext.distDirectory, routes = _api_useAppContext.routes; var config = api.useConfigContext(); var serverStaticMiddleware = createStaticMiddleware({ pwd, routes, output: config.output || {}, html: config.html || {} }); middlewares.push({ name: "server-static", handler: serverStaticMiddleware }); } }; } }; }; function createPublicMiddleware(param) { var pwd = param.pwd, routes = param.routes; return function() { var _ref = _async_to_generator(function(c, next) { var route, entryPath, filename, data, mimeType; return _ts_generator(this, function(_state) { switch (_state.label) { case 0: route = matchPublicRoute(c.req, routes); if (!route) return [ 3, 2 ]; entryPath = route.entryPath; filename = path.join(pwd, entryPath); return [ 4, fileReader.readFile(filename, "buffer") ]; case 1: data = _state.sent(); mimeType = getMimeType(filename); if (data !== null) { if (mimeType) { c.header("Content-Type", mimeType); } Object.entries(route.responseHeaders || {}).forEach(function(param2) { var _param = _sliced_to_array(param2, 2), k = _param[0], v = _param[1]; c.header(k, v); }); return [ 2, c.body(data, 200) ]; } _state.label = 2; case 2: return [ 4, next() ]; case 3: return [ 2, _state.sent() ]; } }); }); return function(c, next) { return _ref.apply(this, arguments); }; }(); } function matchPublicRoute(req, routes) { var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0; try { for (var _iterator = routes.sort(sortRoutes)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var route = _step.value; if (!route.isSSR && route.entryPath.startsWith("public") && req.path.startsWith(route.urlPath)) { return route; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return void 0; } var extractPathname = function(url) { try { if (url.includes("://")) { return new URL(url).pathname || "/"; } if (url.startsWith("//")) { return new URL("http:".concat(url)).pathname || "/"; } return url; } catch (e) { return url; } }; function createStaticMiddleware(options) { var pwd = options.pwd, routes = options.routes; var prefix = options.output.assetPrefix || "/"; var pathPrefix = extractPathname(prefix); var _options_output = options.output, tmp = _options_output.distPath, _ref = tmp === void 0 ? {} : tmp, cssPath = _ref.css, jsPath = _ref.js, mediaPath = _ref.media; var _options_html = options.html, favicon = _options_html.favicon, faviconByEntries = _options_html.faviconByEntries; var favicons = prepareFavicons(favicon, faviconByEntries); var staticFiles = [ cssPath, jsPath, mediaPath ].filter(function(v) { return Boolean(v); }); var staticReg = [ "static/", "upload/" ].concat(_to_consumable_array(staticFiles)); var iconReg = [ "favicon.ico", "icon.png" ].concat(_to_consumable_array(favicons)); var regPrefix = pathPrefix.endsWith("/") ? pathPrefix : "".concat(pathPrefix, "/"); var staticPathRegExp = new RegExp("^".concat(regPrefix, "(").concat(_to_consumable_array(staticReg).concat(_to_consumable_array(iconReg)).join("|"), ")")); return function() { var _ref2 = _async_to_generator(function(c, next) { var pageRoute, pathname, hit, filepath, mimeType, stat, size, chunk; return _ts_generator(this, function(_state) { switch (_state.label) { case 0: pageRoute = c.get("route"); pathname = c.req.path; if (pageRoute && path.extname(pathname) === "") { return [ 2, next() ]; } hit = staticPathRegExp.test(pathname); if (!hit) return [ 3, 4 ]; filepath = path.join(pwd, pathname.replace(pathPrefix, function() { return ""; })); return [ 4, fs.pathExists(filepath) ]; case 1: if (!_state.sent()) { return [ 2, next() ]; } mimeType = getMimeType(filepath); if (mimeType) { c.header("Content-Type", mimeType); } return [ 4, fs.lstat(filepath) ]; case 2: stat = _state.sent(); size = stat.size; return [ 4, fileReader.readFileFromSystem(filepath, "buffer") ]; case 3: chunk = _state.sent(); c.header("Content-Length", String(size)); return [ 2, c.body(chunk, 200) ]; case 4: return [ 2, createPublicMiddleware({ pwd, routes: routes || [] })(c, next) ]; case 5: return [ 2 ]; } }); }); return function(c, next) { return _ref2.apply(this, arguments); }; }(); } var prepareFavicons = function(favicon, faviconByEntries) { var faviconNames = []; if (favicon && typeof favicon === "string") { faviconNames.push(favicon.substring(favicon.lastIndexOf("/") + 1)); } if (faviconByEntries) { Object.keys(faviconByEntries).forEach(function(f) { var curFavicon = faviconByEntries[f]; if (curFavicon) { faviconNames.push(curFavicon.substring(curFavicon.lastIndexOf("/") + 1)); } }); } return faviconNames; }; export { createPublicMiddleware, createStaticMiddleware, serverStaticPlugin };