Skip to content

Commit

Permalink
Added basename support
Browse files Browse the repository at this point in the history
  • Loading branch information
salvoravida committed Sep 10, 2022
1 parent 9ad00d6 commit b9e2426
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 8 deletions.
70 changes: 70 additions & 0 deletions __tests__/middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,4 +249,74 @@ describe('RouterMiddleware history v5', () => {
expect(fakeHistory.forward).toHaveBeenCalledTimes(0);
});
});

describe('with basename', () => {
let routerMiddleware;
let nextDispatch;
let fakeHistory;

beforeEach(() => {
fakeHistory = {
push: jest.fn(() => {}),
replace: jest.fn(() => {}),
go: jest.fn(() => {}),
back: jest.fn(() => {}),
forward: jest.fn(() => {}),
} as unknown as History;
routerMiddleware = createRouterMiddleware({
history: fakeHistory,
showHistoryAction: false,
basename: '/page',
});
nextDispatch = jest.fn(() => {});
});

it('should handle push action partial path', () => {
routerMiddleware()(nextDispatch)(push('/path'));
expect(nextDispatch).toHaveBeenCalledTimes(0);
expect(fakeHistory.push).toHaveBeenCalledTimes(1);
expect(fakeHistory.push).toHaveBeenCalledWith('/page/path');

routerMiddleware()(nextDispatch)(push({ pathname: '/path' }));
expect(nextDispatch).toHaveBeenCalledTimes(0);
expect(fakeHistory.push).toHaveBeenCalledTimes(2);
expect(fakeHistory.push).toHaveBeenCalledWith({ pathname: '/page/path' });
});

it('should handle replace action partial path', () => {
routerMiddleware()(nextDispatch)(replace('/path'));
expect(nextDispatch).toHaveBeenCalledTimes(0);
expect(fakeHistory.replace).toHaveBeenCalledTimes(1);
expect(fakeHistory.replace).toHaveBeenCalledWith('/page/path');

routerMiddleware()(nextDispatch)(replace({ pathname: '/path' }));
expect(nextDispatch).toHaveBeenCalledTimes(0);
expect(fakeHistory.replace).toHaveBeenCalledTimes(2);
expect(fakeHistory.replace).toHaveBeenCalledWith({ pathname: '/page/path' });
});

it('should handle push action full path', () => {
routerMiddleware()(nextDispatch)(push('/page/path'));
expect(nextDispatch).toHaveBeenCalledTimes(0);
expect(fakeHistory.push).toHaveBeenCalledTimes(1);
expect(fakeHistory.push).toHaveBeenCalledWith('/page/path');

routerMiddleware()(nextDispatch)(push({ pathname: '/page/path' }));
expect(nextDispatch).toHaveBeenCalledTimes(0);
expect(fakeHistory.push).toHaveBeenCalledTimes(2);
expect(fakeHistory.push).toHaveBeenCalledWith({ pathname: '/page/path' });
});

it('should handle replace action full path', () => {
routerMiddleware()(nextDispatch)(replace('/page/path'));
expect(nextDispatch).toHaveBeenCalledTimes(0);
expect(fakeHistory.replace).toHaveBeenCalledTimes(1);
expect(fakeHistory.replace).toHaveBeenCalledWith('/page/path');

routerMiddleware()(nextDispatch)(replace({ pathname: '/page/path' }));
expect(nextDispatch).toHaveBeenCalledTimes(0);
expect(fakeHistory.replace).toHaveBeenCalledTimes(2);
expect(fakeHistory.replace).toHaveBeenCalledWith({ pathname: '/page/path' });
});
});
});
6 changes: 4 additions & 2 deletions src/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface IHistoryContextOptions {
savePreviousLocations?: number;
batch?: (callback: () => void) => void;
reachGlobalHistory?: ReachHistory;
basename?: string;
}

export interface IHistoryContext {
Expand All @@ -40,6 +41,7 @@ export const createReduxHistoryContext = ({
savePreviousLocations = 0,
batch,
reachGlobalHistory,
basename,
}: IHistoryContextOptions): IHistoryContext => {
let listenObject = false;

Expand All @@ -59,8 +61,8 @@ export const createReduxHistoryContext = ({
selectRouterState = state => state[routerReducerKey];
}

const routerReducer = createRouterReducer({ savePreviousLocations });
const routerMiddleware = createRouterMiddleware({ history, showHistoryAction });
const routerReducer = createRouterReducer({ savePreviousLocations, basename });
const routerMiddleware = createRouterMiddleware({ history, showHistoryAction, basename });

/** ****************************************** REDUX TRAVELLING ************************************************** */

Expand Down
41 changes: 36 additions & 5 deletions src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,25 @@ import { CALL_HISTORY_METHOD, HistoryMethods } from './actions';
type CreateRouterMiddlewareArgs = {
history: History;
showHistoryAction: boolean;
basename?: string;
};

function appendBasename(location: string | Location, basename: string): string | Location {
if (typeof location === 'string' && !location.startsWith(basename)) {
return basename + location;
}
if (
typeof location === 'object' &&
!!location.pathname &&
!location.pathname.startsWith(basename)
) {
return { ...location, pathname: basename + location.pathname };
}
return location;
}

export const createRouterMiddleware =
({ history, showHistoryAction }: CreateRouterMiddlewareArgs): Middleware =>
({ history, showHistoryAction, basename }: CreateRouterMiddlewareArgs): Middleware =>
() =>
(next: Dispatch) =>
(action: ReduxAction) => {
Expand All @@ -22,12 +37,28 @@ export const createRouterMiddleware =

// eslint-disable-next-line default-case
switch (method) {
case 'push':
history.push(...(args as Parameters<History['push']>));
case 'push': {
let callArgs = args;
if (basename && args.length > 0) {
callArgs = [
appendBasename(args[0] as string | Location, basename),
...args.slice(1),
];
}
history.push(...(callArgs as Parameters<History['push']>));
break;
case 'replace':
history.replace(...(args as Parameters<History['replace']>));
}
case 'replace': {
let callArgs = args;
if (basename && args.length > 0) {
callArgs = [
appendBasename(args[0] as string | Location, basename),
...args.slice(1),
];
}
history.replace(...(callArgs as Parameters<History['replace']>));
break;
}
case 'go':
history.go(...(args as Parameters<History['go']>));
break;
Expand Down
10 changes: 9 additions & 1 deletion src/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,20 @@ export type RouterState = {
location?: Location | null;
action?: Action | null;
previousLocations?: { location?: Location | null; action?: Action | null }[];
basename?: string;
};

export const createRouterReducer = ({ savePreviousLocations = 0 }): Reducer<RouterState> => {
export const createRouterReducer = ({
savePreviousLocations = 0,
basename,
}: {
savePreviousLocations?: number;
basename?: string;
}): Reducer<RouterState> => {
const initialState: RouterState = {
location: null,
action: null,
basename,
};

// eslint-disable-next-line no-restricted-globals
Expand Down

0 comments on commit b9e2426

Please sign in to comment.