Skip to content

Instantly share code, notes, and snippets.

@goodwin64
Last active October 29, 2021 18:27
Show Gist options
  • Save goodwin64/1ad592b4c1807f2489b9b5daa67bc8ab to your computer and use it in GitHub Desktop.
Save goodwin64/1ad592b4c1807f2489b9b5daa67bc8ab to your computer and use it in GitHub Desktop.
Implementation of a tiny react-router helper utility
import mapValues from 'lodash/mapValues';
export type WindvanePaths<PNms, PIds, Pths> = {
[key in keyof Pths]: Array<keyof PNms | keyof PIds>;
}
export interface WindvaneOptions<PNms, PIds, Pths> {
pathNames: PNms;
pathIds: PIds;
pathsConcatScheme: WindvanePaths<PNms, PIds, Pths>;
}
export type ParamsToReplace<PIds> = Partial<Record<keyof PIds, string>>
export interface WindvaneApi<PNms, PIds, Pths> extends WindvaneOptions<PNms, PIds, Pths> {
createUrl: (path: keyof WindvanePaths<PNms, PIds, Pths>, paramsToReplace?: ParamsToReplace<PIds>) => string;
paths: {
[key in keyof WindvaneOptions<PNms, PIds, Pths>['pathsConcatScheme']]: string;
},
}
export function windvane<PNms, PIds, Pths>(
options: WindvaneOptions<PNms, PIds, Pths>,
): WindvaneApi<PNms, PIds, Pths> {
const paths: WindvaneApi<PNms, PIds, Pths>['paths'] = mapValues(
options.pathsConcatScheme,
(urlSlices) => urlSlices
.map(slice => {
// @ts-ignore
return slice in options.pathNames ? options.pathNames[slice] : `:${options.pathIds[slice]}`;
})
.join('/'),
);
const createUrl: WindvaneApi<PNms, PIds, Pths>['createUrl'] = (pathKey, paramsToReplace) => {
const prefix = paths[pathKey].startsWith('/') ? '' : '/';
if (!paramsToReplace) {
return prefix + paths[pathKey];
}
return prefix + Object
.entries(paramsToReplace)
.reduce((acc, [key, val]) => {
if (!val) {
return acc;
}
// @ts-ignore
return acc.replace(`:${key}`, val);
}, paths[pathKey]);
};
return {
...options,
createUrl,
paths,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment