UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

484 lines (479 loc) 17.3 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var createHandleRequest_exports = {}; __export(createHandleRequest_exports, { compileManifest: () => compileManifest, createHandleRequest: () => createHandleRequest, getLoaderParams: () => getLoaderParams, getSubdomain: () => getSubdomain, getURLfromRequestURL: () => getURLfromRequestURL, resolveAPIRoute: () => resolveAPIRoute, resolveLoaderRoute: () => resolveLoaderRoute, resolvePageRoute: () => resolvePageRoute, runMiddlewares: () => runMiddlewares }); module.exports = __toCommonJS(createHandleRequest_exports); var import_constants = require("./constants.native.js"); var import_cleanUrl = require("./utils/cleanUrl.native.js"); var import_isResponse = require("./utils/isResponse.native.js"); var import_getManifest = require("./vite/getManifest.native.js"); var import_resolveResponse = require("./vite/resolveResponse.native.js"); function _type_of(obj) { "@swc/helpers - typeof"; return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } var debugRouter = process.env.ONE_DEBUG_ROUTER; function ensureResponse(value) { if ((0, import_isResponse.isResponse)(value)) return value; if (typeof value === "string") { return new Response(value, { headers: { "Content-Type": "text/html" } }); } if (value && (typeof value === "undefined" ? "undefined" : _type_of(value)) === "object") { return Response.json(value); } return new Response(value); } async function runMiddlewares(handlers, request, route, getResponse) { var middlewares = route.middlewares; if (!(middlewares === null || middlewares === void 0 ? void 0 : middlewares.length)) { return await getResponse(); } if (!handlers.loadMiddleware) { throw new Error(`No middleware handler configured`); } if (debugRouter) { console.info(`[one] \u{1F517} middleware chain (${middlewares.length}) for ${route.page}`); } var context = {}; async function dispatch(index) { var _this; var middlewareModule = middlewares[index]; if (!middlewareModule) { if (debugRouter) { console.info(`[one] \u2713 middleware chain complete`); } return ensureResponse(await getResponse()); } if (debugRouter) { console.info(`[one] \u2192 middleware[${index}]: ${middlewareModule.contextKey}`); } var exported = (_this = await handlers.loadMiddleware(middlewareModule)) === null || _this === void 0 ? void 0 : _this.default; if (!exported) { throw new Error(`No valid export found in middleware: ${middlewareModule.contextKey}`); } var next = async function () { return dispatch(index + 1); }; var response = await exported({ request, next, context }); if (response) { if (debugRouter) { console.info(`[one] \u2190 middleware[${index}] returned early (status: ${response.status})`); } return response; } return dispatch(index + 1); } return dispatch(0); } async function resolveAPIRoute(handlers, request, url, route) { var { pathname } = url; var params = getRouteParams(pathname, route); if (debugRouter) { console.info(`[one] \u{1F4E1} API ${request.method} ${pathname} \u2192 ${route.file}`, params); } return await runMiddlewares(handlers, request, route, async function () { try { return (0, import_resolveResponse.resolveAPIEndpoint)(function () { return handlers.handleAPI({ request, route, url, loaderProps: { path: pathname, search: url.search, subdomain: getSubdomain(url), params } }); }, request, params || {}); } catch (err) { if ((0, import_isResponse.isResponse)(err)) { return err; } if (process.env.NODE_ENV === "development") { console.error(` [one] Error importing API route at ${pathname}: ${err} If this is an import error, you can likely fix this by adding this dependency to the "optimizeDeps.include" array in your vite.config.ts. `); } throw err; } }); } async function resolveLoaderRoute(handlers, request, url, route) { if (debugRouter) { console.info(`[one] \u{1F4E6} loader ${url.pathname} \u2192 ${route.file}`); } var isNativeRequest = url.searchParams.get("platform") === "ios" || url.searchParams.get("platform") === "android"; var response = await runMiddlewares(handlers, request, route, async function () { return await (0, import_resolveResponse.resolveResponse)(async function () { var headers = new Headers(); headers.set("Content-Type", "text/javascript"); try { var loaderResponse = await handlers.handleLoader({ request, route, url, loaderProps: { path: url.pathname, search: url.search, subdomain: getSubdomain(url), request: route.type === "ssr" ? request : void 0, params: getLoaderParams(url, route) } }); var body2 = isNativeRequest && loaderResponse ? toCjsLoader(loaderResponse) : loaderResponse; return new Response(body2, { headers }); } catch (err) { if ((0, import_isResponse.isResponse)(err)) { return err; } if ((err === null || err === void 0 ? void 0 : err.code) !== "ERR_MODULE_NOT_FOUND") { console.error(`Error running loader: ${err}`); } throw err; } }); }); if (response.status >= 300 && response.status < 400) { var location = response.headers.get("location"); if (location) { var redirectUrl = new URL(location, url.origin); var redirectPath = redirectUrl.pathname + redirectUrl.search + redirectUrl.hash; var data = `{__oneRedirect:${JSON.stringify(redirectPath)},__oneRedirectStatus:${response.status}}`; var body = isNativeRequest ? `exports.loader=function(){return ${data}}` : `export function loader(){return${data}}`; return new Response(body, { headers: { "Content-Type": "text/javascript" } }); } } if (response.status === 401 || response.status === 403) { var data1 = `{__oneError:${response.status},__oneErrorMessage:${JSON.stringify(response.statusText || "Unauthorized")}}`; var body1 = isNativeRequest ? `exports.loader=function(){return ${data1}}` : `export function loader(){return${data1}}`; return new Response(body1, { headers: { "Content-Type": "text/javascript" } }); } return response; } function toCjsLoader(esmCode) { if (esmCode.startsWith("exports.")) { return esmCode; } var match = esmCode.match(/export\s+function\s+loader\s*\(\)\s*\{\s*return\s+([\s\S]+)\s*\}/); if (match) { return `exports.loader=function(){return ${match[1]}}`; } return `exports.loader=function(){return {}}`; } async function resolvePageRoute(handlers, request, url, route) { var _route_middlewares; var { pathname, search } = url; if (debugRouter) { console.info(`[one] \u{1F4C4} page ${pathname} \u2192 ${route.file} (${route.type})`); } var loaderProps = { path: pathname, search, subdomain: getSubdomain(url), request: route.type === "ssr" ? request : void 0, params: getLoaderParams(url, route) }; if (!((_route_middlewares = route.middlewares) === null || _route_middlewares === void 0 ? void 0 : _route_middlewares.length)) { return (0, import_resolveResponse.resolveResponse)(function () { return handlers.handlePage({ request, route, url, loaderProps }); }); } return (0, import_resolveResponse.resolveResponse)(async function () { return await runMiddlewares(handlers, request, route, async function () { return await handlers.handlePage({ request, route, url, loaderProps }); }); }); } var _urlCache = /* @__PURE__ */new WeakMap(); function getURLfromRequestURL(request) { var url = _urlCache.get(request); if (url) return url; var urlString = request.url || ""; url = new URL(urlString || "", request.headers.get("host") ? `http://${request.headers.get("host")}` : ""); _urlCache.set(request, url); return url; } function getSubdomain(url) { var host = url.hostname; if (!host || host === "localhost" || /^\d+\.\d+\.\d+\.\d+$/.test(host)) { return void 0; } var parts = host.split("."); if (parts.length < 3) { return void 0; } return parts.slice(0, -2).join("."); } function compileRouteRegex(route) { return { ...route, compiledRegex: new RegExp(route.namedRegex) }; } function compileManifest(manifest) { return { pageRoutes: manifest.pageRoutes.map(compileRouteRegex), apiRoutes: manifest.apiRoutes.map(compileRouteRegex) }; } function createHandleRequest(handlers, param) { var { routerRoot, ignoredRouteFiles } = param; var manifest = (0, import_getManifest.getManifest)({ routerRoot, ignoredRouteFiles }); if (!manifest) { throw new Error(`No routes manifest`); } var compiledManifest = compileManifest(manifest); return { manifest, handler: async function handleRequest(request) { var url = getURLfromRequestURL(request); var { pathname, search } = url; if (pathname === "/__vxrnhmr" || pathname.startsWith("/@vite/") || pathname.startsWith("/@fs/") || pathname.startsWith("/@id/") || pathname.startsWith("/node_modules/") || pathname.startsWith("/debugger-frontend") || pathname.startsWith("/inspector")) { return null; } var looksLikeStaticFile = !pathname.endsWith(import_constants.LOADER_JS_POSTFIX_UNCACHED) && /\.[a-zA-Z0-9]{2,4}$/.test(pathname); if (handlers.handleAPI) { var apiRoute = compiledManifest.apiRoutes.find(function (route2) { return route2.compiledRegex.test(pathname); }); if (apiRoute) { if (debugRouter) { console.info(`[one] \u26A1 ${pathname} \u2192 matched API route: ${apiRoute.page}`); } return await resolveAPIRoute(handlers, request, url, apiRoute); } } if (request.method !== "GET") { return null; } if (handlers.handleLoader) { var isClientRequestingNewRoute = pathname.endsWith(import_constants.LOADER_JS_POSTFIX_UNCACHED); if (isClientRequestingNewRoute) { var platformParam = url.searchParams.get("platform"); var isNativePlatform = platformParam === "ios" || platformParam === "android" || platformParam === "native"; if (isNativePlatform && handlers.handleStaticFile) { var nativeLoaderPath = pathname.replace(/\.js$/, ".native.js"); var staticResponse = await handlers.handleStaticFile(nativeLoaderPath); if (staticResponse) { return staticResponse; } } var originalUrl = (0, import_cleanUrl.getPathFromLoaderPath)(pathname); var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0; try { for (var _iterator = compiledManifest.pageRoutes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var route = _step.value; if (route.file === "") { continue; } var finalUrl = new URL(originalUrl, url.origin); finalUrl.search = url.search; if (!route.compiledRegex.test(finalUrl.pathname)) { continue; } if (route.hasLoader === false) { var emptyBody = isNativePlatform ? "exports.loader=function(){return undefined}" : "export function loader() { return undefined }"; return new Response(emptyBody, { headers: { "Content-Type": "text/javascript" } }); } var cleanedRequest = new Request(finalUrl, request); return resolveLoaderRoute(handlers, cleanedRequest, finalUrl, route); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var emptyBody1 = isNativePlatform ? "exports.loader=function(){return{}}" : "export {}"; return new Response(emptyBody1, { headers: { "Content-Type": "text/javascript" } }); } } if (handlers.handlePage) { var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = void 0; try { for (var _iterator1 = compiledManifest.pageRoutes[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) { var route1 = _step1.value; if (!route1.compiledRegex.test(pathname)) { continue; } var isDynamicRoute = Object.keys(route1.routeKeys).length > 0; var isNotFoundRoute = route1.page.endsWith("/+not-found"); if (looksLikeStaticFile && isDynamicRoute && !isNotFoundRoute) { if (debugRouter) { console.info(`[one] \u26A1 ${pathname} \u2192 skipping dynamic route ${route1.page} for static-looking path`); } continue; } if (looksLikeStaticFile && route1.file === "") { if (debugRouter) { console.info(`[one] \u26A1 ${pathname} \u2192 404 for probe path (no +not-found defined)`); } return new Response(null, { status: 404, headers: { "Content-Type": "text/plain" } }); } if (debugRouter) { console.info(`[one] \u26A1 ${pathname} \u2192 matched page route: ${route1.page} (${route1.type})`); } return resolvePageRoute(handlers, request, url, route1); } } catch (err) { _didIteratorError1 = true; _iteratorError1 = err; } finally { try { if (!_iteratorNormalCompletion1 && _iterator1.return != null) { _iterator1.return(); } } finally { if (_didIteratorError1) { throw _iteratorError1; } } } } return null; } }; } function getLoaderParams(url, config) { var params = {}; var match = config.compiledRegex.exec(url.pathname); if (match === null || match === void 0 ? void 0 : match.groups) { var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0; try { for (var _iterator = Object.entries(match.groups)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var [key, value] = _step.value; var namedKey = config.routeKeys[key]; params[namedKey] = value; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } return params; } function getRouteParams(pathname, route) { var regex = new RegExp(route.namedRegex); var match = regex.exec(pathname); if (!match) return {}; return Object.fromEntries(Object.entries(route.routeKeys).map(function (param) { var [key, value] = param; var _match_groups; return [value, ((_match_groups = match.groups) === null || _match_groups === void 0 ? void 0 : _match_groups[key]) || ""]; })); } //# sourceMappingURL=createHandleRequest.native.js.map