2024-01-05 14:11:43 +00:00
|
|
|
import { generatePath, type PathParam } from "react-router-dom";
|
2023-10-17 07:36:26 +00:00
|
|
|
|
2024-01-05 14:11:43 +00:00
|
|
|
/**
|
|
|
|
* Represents an object that contains the parameters to be included in a path.
|
|
|
|
*
|
|
|
|
* @example
|
|
|
|
* const params: PathParams<"/user/:id"> = { id: "123" };
|
|
|
|
*/
|
|
|
|
export type PathParams<Path extends string> = {
|
|
|
|
[key in PathParam<Path>]: string;
|
|
|
|
};
|
2023-10-17 07:36:26 +00:00
|
|
|
|
2024-01-05 14:11:43 +00:00
|
|
|
/**
|
|
|
|
* Generates a path that represents the given path template with parameters interpolated and encoded in it, so that it can safely used in a URL.
|
|
|
|
*
|
|
|
|
* @param originalPath - The path template to use to generate the path.
|
|
|
|
* @param params - An object that contains the parameters to be included in the path.
|
|
|
|
*
|
|
|
|
* @example
|
|
|
|
* const path = "/user/:id";
|
|
|
|
* const params = { id: "123" };
|
|
|
|
* const encodedPath = generateEncodedPath(path, params);
|
|
|
|
* // encodedPath will be "/user/123"
|
|
|
|
*/
|
2023-10-17 07:36:26 +00:00
|
|
|
export function generateEncodedPath<Path extends string>(
|
|
|
|
originalPath: Path,
|
2024-01-05 14:11:43 +00:00
|
|
|
params: PathParams<Path>,
|
2023-10-17 07:36:26 +00:00
|
|
|
): string {
|
2024-01-05 14:11:43 +00:00
|
|
|
// Clone the params object so we don't mutate the original.
|
|
|
|
const encodedParams = structuredClone(params);
|
2023-10-17 07:36:26 +00:00
|
|
|
|
2024-01-05 14:11:43 +00:00
|
|
|
// Encode each param in the path so that it can be used in a URL.
|
|
|
|
for (const key in encodedParams) {
|
|
|
|
const pathKey = key as PathParam<Path>;
|
|
|
|
encodedParams[pathKey] = encodeURIComponent(encodedParams[pathKey]);
|
|
|
|
}
|
2023-10-17 07:36:26 +00:00
|
|
|
|
2024-01-05 14:11:43 +00:00
|
|
|
return generatePath(originalPath, encodedParams);
|
2023-10-17 07:36:26 +00:00
|
|
|
}
|