82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
function flattenProperties(
|
|
obj: Record<PropertyKey, unknown>,
|
|
parent: string | null = null,
|
|
res: Record<PropertyKey, unknown> = {}
|
|
): Record<PropertyKey, unknown> {
|
|
for (const key of Object.keys(obj)) {
|
|
const propName = parent ? parent + "." + key : key;
|
|
if (obj[key] instanceof Object) {
|
|
flattenProperties(
|
|
obj[key] as Record<PropertyKey, unknown>,
|
|
propName,
|
|
res
|
|
);
|
|
} else {
|
|
res[propName] = obj[key];
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
const route = function route(
|
|
routeName: string,
|
|
parameters: Record<
|
|
string,
|
|
string | number | null | undefined | Array<string | number>
|
|
> = {},
|
|
keepActualQueries = false,
|
|
keepActualHashes = false
|
|
): string {
|
|
const routes = flattenProperties(globalThis.__SYSTEM._routes);
|
|
const routeUrl =
|
|
Object.prototype.hasOwnProperty.call(routes, routeName) // NOSONAR - Safari 15 does not support Object.hasOwn()
|
|
? (routes[routeName] as string)
|
|
: null;
|
|
|
|
// * Return null if route url could not be found
|
|
if (!routeUrl) {
|
|
throw new Error(`route '${routeName}' not found`);
|
|
}
|
|
|
|
const queryParameters: Record<string, number | string> = {},
|
|
url = new URL(globalThis.location.origin),
|
|
searchParams = new URL(String(globalThis.location)).searchParams,
|
|
hash = globalThis.location.hash;
|
|
let pathname = routeUrl.replace(origin, "");
|
|
|
|
// * Replace parameters in path name.
|
|
for (const paramName in parameters) {
|
|
const paramValue = String(parameters[paramName]);
|
|
if (pathname.includes(paramName)) {
|
|
// * Replace pathname part with parameter
|
|
pathname = pathname.replace(paramName, paramValue);
|
|
} else {
|
|
// * push parameter to be in queries
|
|
queryParameters[paramName] = paramValue;
|
|
}
|
|
}
|
|
url.pathname = pathname;
|
|
|
|
// * Build query
|
|
if (keepActualQueries) {
|
|
// * Push actual queries
|
|
for (const param of searchParams) {
|
|
url.searchParams.set(param[0], param[1]);
|
|
}
|
|
}
|
|
// * Push request queries
|
|
for (const paramName in queryParameters) {
|
|
url.searchParams.set(
|
|
paramName,
|
|
String(queryParameters[paramName])
|
|
);
|
|
}
|
|
|
|
if (keepActualHashes) {
|
|
url.hash = hash;
|
|
}
|
|
|
|
return String(url);
|
|
};
|
|
|
|
export default route;
|