one
Version:
One is a new React Framework that makes Vite serve both native and web.
323 lines (322 loc) • 10.4 kB
JavaScript
import { getContextKey, matchGroupName } from "../router/matchers.native.js";
function isNotFoundRoute(route) {
return Boolean(route.dynamic && route.dynamic[route.dynamic.length - 1].notFound);
}
function sortByPathSpecificity(param, param1) {
var [keyA, nodeA] = param,
[keyB, nodeB] = param1;
var partsA = keyA.split("/").filter(Boolean);
var partsB = keyB.split("/").filter(Boolean);
var minLen = Math.min(partsA.length, partsB.length);
for (var i = 0; i < minLen; i++) {
var aIsDynamic = partsA[i].startsWith("[") || partsA[i] === "+not-found";
var bIsDynamic = partsB[i].startsWith("[") || partsB[i] === "+not-found";
if (!aIsDynamic && bIsDynamic) return -1;
if (aIsDynamic && !bIsDynamic) return 1;
if (aIsDynamic && bIsDynamic) {
var aIsCatchAll = partsA[i].startsWith("[...") || partsA[i] === "+not-found";
var bIsCatchAll = partsB[i].startsWith("[...") || partsB[i] === "+not-found";
if (!aIsCatchAll && bIsCatchAll) return -1;
if (aIsCatchAll && !bIsCatchAll) return 1;
if (aIsCatchAll && bIsCatchAll) {
var aNotFound = partsA[i] === "+not-found";
var bNotFound = partsB[i] === "+not-found";
if (aNotFound && !bNotFound) return 1;
if (!aNotFound && bNotFound) return -1;
}
}
}
var aNotFound1 = isNotFoundRoute(nodeA);
var bNotFound1 = isNotFoundRoute(nodeB);
if (aNotFound1 && !bNotFound1) return 1;
if (!aNotFound1 && bNotFound1) 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(function (child) {
return getFlatNodes(child, [...(layouts || []), route2]);
});
}
var key;
if (route2.type === "api") {
key = getContextKey(route2.contextKey).replace(/\/index$/, "") || "/";
} else {
var parentSegments = layouts === null || layouts === void 0 ? void 0 : layouts.flatMap(function (route3) {
var key2 = getContextKey(route3.route).replace(/\/index$/, "") || "/";
if (key2 === "/" || key2.startsWith("/(")) {
return [];
}
return [key2];
});
key = (parentSegments ? parentSegments.join("") : "") + getContextKey(route2.route).replace(/\/index$/, "") || "/";
}
return [[key, {
...route2,
layouts
}]];
}
var flat = getFlatNodes(route).sort(sortByPathSpecificity);
var pathToRoute = {};
var _iteratorNormalCompletion = true,
_didIteratorError = false,
_iteratorError = void 0;
try {
for (var _iterator = flat[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var [path, _$route] = _step.value;
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: ${_$route.contextKey}
`);
}
pathToRoute[path] = _$route;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
var apiRoutes = [];
var middlewareRoutes = [];
var pageRoutes = [];
var allRoutes = [];
var addedMiddlewares = {};
var _iteratorNormalCompletion1 = true,
_didIteratorError1 = false,
_iteratorError1 = void 0;
try {
for (var _iterator1 = flat[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
var [path1, node] = _step1.value;
var _node_middlewares;
if (node.type === "api") {
var _$route1 = getGeneratedNamedRouteRegex(path1, node);
apiRoutes.push(_$route1);
allRoutes.push(_$route1);
continue;
}
if ((_node_middlewares = node.middlewares) === null || _node_middlewares === void 0 ? void 0 : _node_middlewares.length) {
var _iteratorNormalCompletion2 = true,
_didIteratorError2 = false,
_iteratorError2 = void 0;
try {
for (var _iterator2 = node.middlewares[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var middleware = _step2.value;
if (!addedMiddlewares[middleware.contextKey]) {
addedMiddlewares[middleware.contextKey] = true;
middlewareRoutes.push(getGeneratedNamedRouteRegex(path1, middleware));
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
var _$route2 = getGeneratedNamedRouteRegex(path1, node);
pageRoutes.push(_$route2);
allRoutes.push(_$route2);
}
} catch (err) {
_didIteratorError1 = true;
_iteratorError1 = err;
} finally {
try {
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
_iterator1.return();
}
} finally {
if (_didIteratorError1) {
throw _iteratorError1;
}
}
}
return {
apiRoutes,
middlewareRoutes,
pageRoutes,
allRoutes
};
}
function getGeneratedNamedRouteRegex(normalizedRoute, node) {
return {
...getRouteEntry(normalizedRoute, node),
generated: true,
isNotFound: isNotFoundRoute(node)
};
}
function getRouteEntry(normalizedRoute, node) {
var result = getPathMeta(normalizedRoute);
return {
file: node.contextKey,
page: 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() {
var currentCharCode = 96;
var currentLength = 1;
return function () {
var result = "";
var incrementNext = true;
for (var 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) {
var segments = removeTrailingSlash(route).slice(1).split("/");
var getSafeRouteKey = buildGetSafeRouteKey();
var routeKeys = {};
var urlPathParts = [];
var routeSegments = segments.map(function (segment, index) {
if (segment === "+not-found" && index === segments.length - 1) {
segment = "[...not-found]";
}
if (/^\[.*\]$/.test(segment)) {
var {
name,
optional,
repeat
} = parseParam(segment);
var cleanedKey = name.replace(/\W/g, "");
var 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)) {
var groupName = matchGroupName(segment).split(",").map(function (group) {
return group.trim();
}).filter(Boolean);
urlPathParts.push({
content: `/:${groupName}?`,
type: "group"
});
if (groupName.length > 1) {
var optionalSegment = `\\((?:${groupName.map(escapeStringRegexp).join("|")})\\)`;
return `(?:/${optionalSegment})?`;
}
return `(?:/${escapeStringRegexp(segment)})?`;
}
urlPathParts.push({
content: `/${segment}`
});
return `/${escapeStringRegexp(segment)}`;
}).join("");
var urlPath = urlPathParts.map(function (p) {
return p.content;
}).join("");
var urlCleanPath = urlPathParts.filter(function (p) {
return p.type !== "group";
}).map(function (p) {
return 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
};
}
var insideBracketsRegex = /^\[.*\]$/;
var insideParensRegex = /^\(.*\)$/;
var tripleDotRegex = /^\.\.\./;
var replaceRegex = /[|\\{}()[\]^$+*?.-]/g;
var hasRegExpRegex = /[|\\{}()[\]^$+*?.-]/;
function escapeStringRegexp(str) {
if (hasRegExpRegex.test(str)) {
return str.replace(replaceRegex, "\\$&");
}
return str;
}
function parseParam(param) {
var repeat = false;
var optional = false;
var 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
};
}
export { getServerManifest, parseParam };
//# sourceMappingURL=getServerManifest.native.js.map