UNPKG

one

Version:

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

280 lines 9.19 kB
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 getServerManifest_exports = {}; __export(getServerManifest_exports, { getServerManifest: () => getServerManifest, parseParam: () => parseParam }); module.exports = __toCommonJS(getServerManifest_exports); var import_matchers = require("../router/matchers.cjs"); function isNotFoundRoute(route) { return Boolean(route.dynamic && route.dynamic[route.dynamic.length - 1].notFound); } function sortByPathSpecificity([keyA, nodeA], [keyB, nodeB]) { const partsA = keyA.split("/").filter(Boolean); const partsB = keyB.split("/").filter(Boolean); const minLen = Math.min(partsA.length, partsB.length); for (let i = 0; i < minLen; i++) { const aIsDynamic = partsA[i].startsWith("[") || partsA[i] === "+not-found"; const bIsDynamic = partsB[i].startsWith("[") || partsB[i] === "+not-found"; if (!aIsDynamic && bIsDynamic) return -1; if (aIsDynamic && !bIsDynamic) return 1; if (aIsDynamic && bIsDynamic) { const aIsCatchAll = partsA[i].startsWith("[...") || partsA[i] === "+not-found"; const bIsCatchAll = partsB[i].startsWith("[...") || partsB[i] === "+not-found"; if (!aIsCatchAll && bIsCatchAll) return -1; if (aIsCatchAll && !bIsCatchAll) return 1; if (aIsCatchAll && bIsCatchAll) { const aNotFound2 = partsA[i] === "+not-found"; const bNotFound2 = partsB[i] === "+not-found"; if (aNotFound2 && !bNotFound2) return 1; if (!aNotFound2 && bNotFound2) return -1; } } } const aNotFound = isNotFoundRoute(nodeA); const bNotFound = isNotFoundRoute(nodeB); if (aNotFound && !bNotFound) return 1; if (!aNotFound && bNotFound) return -1; if (partsA.length !== partsB.length) { return partsB.length - partsA.length; } return 0; } function getServerManifest(route) { function getFlatNodes(route2, layouts) { if (route2.children.length) { return route2.children.flatMap(child => { return getFlatNodes(child, [...(layouts || []), route2]); }); } let key; if (route2.type === "api") { key = (0, import_matchers.getContextKey)(route2.contextKey).replace(/\/index$/, "") || "/"; } else { const parentSegments = layouts?.flatMap(route3 => { const key2 = (0, import_matchers.getContextKey)(route3.route).replace(/\/index$/, "") || "/"; if (key2 === "/" || key2.startsWith("/(")) { return []; } return [key2]; }); key = (parentSegments ? parentSegments.join("") : "") + (0, import_matchers.getContextKey)(route2.route).replace(/\/index$/, "") || "/"; } return [[key, { ...route2, layouts }]]; } const flat = getFlatNodes(route).sort(sortByPathSpecificity); const pathToRoute = {}; for (const [path, route2] of flat) { if (pathToRoute[path]) { console.warn(` [one] \u274C Duplicate routes error`); console.warn(` Multiple routes at the same path! One route will always win over the other.`); console.warn(` path: ${path}`); console.warn(` first route: ${pathToRoute[path].contextKey}`); console.warn(` second route: ${route2.contextKey} `); } pathToRoute[path] = route2; } const apiRoutes = []; const middlewareRoutes = []; const pageRoutes = []; const allRoutes = []; const addedMiddlewares = {}; for (const [path, node] of flat) { if (node.type === "api") { const route3 = getGeneratedNamedRouteRegex(path, node); apiRoutes.push(route3); allRoutes.push(route3); continue; } if (node.middlewares?.length) { for (const middleware of node.middlewares) { if (!addedMiddlewares[middleware.contextKey]) { addedMiddlewares[middleware.contextKey] = true; middlewareRoutes.push(getGeneratedNamedRouteRegex(path, middleware)); } } } const route2 = getGeneratedNamedRouteRegex(path, node); pageRoutes.push(route2); allRoutes.push(route2); } return { apiRoutes, middlewareRoutes, pageRoutes, allRoutes }; } function getGeneratedNamedRouteRegex(normalizedRoute, node) { return { ...getRouteEntry(normalizedRoute, node), generated: true, isNotFound: isNotFoundRoute(node) }; } function getRouteEntry(normalizedRoute, node) { const result = getPathMeta(normalizedRoute); return { file: node.contextKey, page: (0, import_matchers.getContextKey)(node.route), type: node.type, namedRegex: result.namedRegex, urlPath: result.urlPath, urlCleanPath: result.urlCleanPath, routeKeys: result.routeKeys, layouts: node.layouts, middlewares: node.middlewares }; } function buildGetSafeRouteKey() { let currentCharCode = 96; let currentLength = 1; return () => { let result = ""; let incrementNext = true; for (let i = 0; i < currentLength; i++) { if (incrementNext) { currentCharCode++; if (currentCharCode > 122) { currentCharCode = 97; incrementNext = true; } else { incrementNext = false; } } result = String.fromCharCode(currentCharCode) + result; } if (incrementNext) { currentLength++; currentCharCode = 96; } return result; }; } function removeTrailingSlash(route) { return route.replace(/\/$/, "") || "/"; } function getPathMeta(route) { const segments = removeTrailingSlash(route).slice(1).split("/"); const getSafeRouteKey = buildGetSafeRouteKey(); const routeKeys = {}; const urlPathParts = []; const routeSegments = segments.map((segment, index) => { if (segment === "+not-found" && index === segments.length - 1) { segment = "[...not-found]"; } if (/^\[.*\]$/.test(segment)) { const { name, optional, repeat } = parseParam(segment); let cleanedKey = name.replace(/\W/g, ""); let invalidKey = false; if (cleanedKey.length === 0 || cleanedKey.length > 30) { invalidKey = true; } if (!Number.isNaN(Number.parseInt(cleanedKey.slice(0, 1), 10))) { invalidKey = true; } if (cleanedKey in routeKeys) { invalidKey = true; } if (invalidKey) { cleanedKey = getSafeRouteKey(); } urlPathParts.push({ content: repeat ? "/*" : `/:${name}${optional ? "?" : ""}` }); routeKeys[cleanedKey] = name; return repeat ? optional ? `(?:/(?<${cleanedKey}>.+?))?` : `/(?<${cleanedKey}>.+?)` : `/(?<${cleanedKey}>(?!\\+not-found$)[^/]+?)`; } if (insideParensRegex.test(segment)) { const groupName = (0, import_matchers.matchGroupName)(segment).split(",").map(group => group.trim()).filter(Boolean); urlPathParts.push({ content: `/:${groupName}?`, type: "group" }); if (groupName.length > 1) { const optionalSegment = `\\((?:${groupName.map(escapeStringRegexp).join("|")})\\)`; return `(?:/${optionalSegment})?`; } return `(?:/${escapeStringRegexp(segment)})?`; } urlPathParts.push({ content: `/${segment}` }); return `/${escapeStringRegexp(segment)}`; }).join(""); let urlPath = urlPathParts.map(p => p.content).join(""); let urlCleanPath = urlPathParts.filter(p => p.type !== "group").map(p => p.content).join(""); if (urlPath.endsWith("/*")) { urlPath = urlPath.replace(/\?(?=\/|\/\*)/g, ""); } if (urlCleanPath.endsWith("/*")) { urlCleanPath = urlCleanPath.replace(/\?(?=\/|\/\*)/g, ""); } return { namedRegex: `^${routeSegments}(?:/)?$`, urlPath: urlPath === "" ? "/" : urlPath, urlCleanPath: urlCleanPath === "" ? "/" : urlCleanPath, routeKeys }; } const insideBracketsRegex = /^\[.*\]$/; const insideParensRegex = /^\(.*\)$/; const tripleDotRegex = /^\.\.\./; const replaceRegex = /[|\\{}()[\]^$+*?.-]/g; const hasRegExpRegex = /[|\\{}()[\]^$+*?.-]/; function escapeStringRegexp(str) { if (hasRegExpRegex.test(str)) { return str.replace(replaceRegex, "\\$&"); } return str; } function parseParam(param) { let repeat = false; let optional = false; let name = param; if (/^\[\[.*\]\]$/.test(name)) { optional = true; name = name.slice(2, -2); } else if (insideBracketsRegex.test(name)) { name = name.slice(1, -1); } if (tripleDotRegex.test(name)) { repeat = true; name = name.slice(3); } return { name, repeat, optional }; }