import { AppRoute, AppRoutePaths, AppRoutesParams } from "../../routes.defs";
interface BuildLinkOptions {
encodeURIComponent?: boolean;
}
export default function buildRouteLink<P extends AppRoute>(
route: P,
routeParams: "params" extends keyof AppRoutesParams[P]
? AppRoutesParams[P]["params"]
: {} | null,
options?: BuildLinkOptions
): typeof AppRoutePaths[P] {
const path = AppRoutePaths[route];
return buildPathLink(path, routeParams, options);
}
export function buildPathLink<P extends AppRoute>(
path: string,
routeParams: "params" extends keyof AppRoutesParams[P]
? AppRoutesParams[P]["params"]
: {} | null,
options?: BuildLinkOptions
): string {
if (
routeParams == null ||
(routeParams != null &&
typeof routeParams === "object" &&
Object.keys(routeParams as any).length <= 0)
) {
return path;
}
const paramsEntries = Object.entries(routeParams as never);
let pathParts = path.split("/");
let linkBuilder = [] as string[];
pathParts.forEach((part) => {
if (part.trim() === "") {
linkBuilder.push("");
} else if (
"*" in routeParams &&
(routeParams as any)["*"] != null &&
part === "*"
) {
linkBuilder.push((routeParams as any)["*"]);
} else if (part.includes(":")) {
paramsEntries.forEach(([k, v]) => {
if (k == null || k.trim() === "" || k === "*") return;
const keyRegExp = new RegExp(`:${k}`, "g");
if (Array.isArray(part.match(keyRegExp))) {
linkBuilder.push(part.replace(keyRegExp, `${String(v)}`));
}
});
} else {
linkBuilder.push(part);
}
});
const shouldEncodeURIComponents = !!(
options == null ||
options.encodeURIComponent == null ||
options.encodeURIComponent !== false
);
return linkBuilder
.map((param) =>
shouldEncodeURIComponents ? encodeURIComponent(param) : param
)
.join("/");
}