diff --git a/__tests__/router.test.js b/__tests__/router.test.js
index e208671..547a6ce 100644
--- a/__tests__/router.test.js
+++ b/__tests__/router.test.js
@@ -88,6 +88,33 @@ describe('Router without interceptors', () => {
expect(wrapper.prop('history').location.search).toEqual('?the=query')
expect(Router.getCurrentQuery()).toEqual(query)
})
+
+ test('Redirect from some path to Details page', () => {
+ const historyLength = wrapper.prop('history').index
+
+ Router.push(null, {path: '/path_to_redirect_from'})
+
+ expect(Router.getCurrentRoute()).toEqual(Router.routes.details.path)
+ expect(wrapper.prop('history').index).toEqual(historyLength + 1)
+ })
+
+ test('Default redirect to About page', () => {
+ const historyLength = wrapper.prop('history').index
+
+ Router.push(null, {path: 'some_unrealistic_path'})
+
+ expect(Router.getCurrentRoute()).toEqual(Router.routes.about.path)
+ expect(wrapper.prop('history').index).toEqual(historyLength + 1)
+ })
+
+ test('Redirect to any external url', () => {
+ const externalUrl = 'http://example.com'
+
+ window.location.replace = jest.fn()
+ Router.redirect(externalUrl)
+ expect(window.location.replace).toHaveBeenCalledWith(externalUrl)
+ window.location.replace.mockRestore()
+ })
})
diff --git a/__tests__/setup/routes.js b/__tests__/setup/routes.js
index 01c06a5..71e3a06 100644
--- a/__tests__/setup/routes.js
+++ b/__tests__/setup/routes.js
@@ -56,4 +56,11 @@ export default {
component: DummyComponent('WhiteListParams'),
whiteListParams: ['a', 'c'],
},
+ redirectFromRule: {
+ redirectFrom: '/path_to_redirect_from',
+ redirectTo: '/details'
+ },
+ redirectToAbout: {
+ redirectTo: '/about',
+ },
}
diff --git a/index.js b/index.js
index c781f52..57034ca 100644
--- a/index.js
+++ b/index.js
@@ -10,6 +10,7 @@ const navigationMethodFields = [
'pop',
'popToTop',
'replace',
+ 'redirect',
'showModal',
'dismissModal',
]
diff --git a/package-lock.json b/package-lock.json
index feb7fe3..8a36d3f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "tipsi-router",
- "version": "1.7.0",
+ "version": "1.8.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -7935,9 +7935,8 @@
"dev": true
},
"tipsi-travis-scripts": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/tipsi-travis-scripts/-/tipsi-travis-scripts-1.0.0.tgz",
- "integrity": "sha512-n6A5ZJNnc4H2yKTt+4wYWmhou1WNwkf770I6/DtAqjVvAaqMPeoq4JgEX/SpLVvr5mdMxHV+GxdN0NLD1LLiHw==",
+ "version": "github:tipsi/tipsi-travis-scripts#7c15c289619228ad0e03926c30fe391e934ed672",
+ "from": "github:tipsi/tipsi-travis-scripts#7c15c289619228ad0e03926c30fe391e934ed672",
"dev": true,
"requires": {
"chalk": "2.4.1",
diff --git a/package.json b/package.json
index 2737fcd..261e142 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "tipsi-router",
- "version": "1.7.0",
+ "version": "1.8.0",
"description": "React and RN router solution",
"main": "index.js",
"scripts": {
diff --git a/src/Router.js b/src/Router.js
index c70e9e8..fad2503 100644
--- a/src/Router.js
+++ b/src/Router.js
@@ -1,5 +1,5 @@
import React from 'react'
-import { Router, Switch, Route } from 'react-router-dom'
+import { Router, Switch, Route, Redirect } from 'react-router-dom'
import { ModalRoute } from 'react-router-modal'
import createBrowserHistory from 'history/createBrowserHistory'
import createMemoryHistory from 'history/createMemoryHistory'
@@ -34,7 +34,10 @@ export default class TipsiRouter extends RouterBase {
const initialEntries = Object.values(routes).map(route => route.path)
const initialIndex = initialEntries.indexOf(initialRoute)
- return createMemoryHistory({ initialEntries, initialIndex })
+ // filter out all Redirects (items with 'path' prop equal to undefined)
+ const entriesWithoutRedirects = initialEntries.filter(entry => !!entry)
+
+ return createMemoryHistory({ initialEntries: entriesWithoutRedirects, initialIndex })
}
filterSyncedState(state, filterFields) {
@@ -53,6 +56,21 @@ export default class TipsiRouter extends RouterBase {
createRouter(initialRoute, routes) {
const shouldScrollToTop = this.defaultRouteConfig.shouldScrollToTop || true
const elements = Object.entries(routes).reduce((memo, [key, route]) => {
+ // "to" is only required property for Redirect
+ if (route.redirectTo) {
+ const { redirectFrom, redirectTo, exact } = route
+
+ // only allow "to", "from", or "exact" props to be passed to
+ const redirectParams = {
+ to: redirectTo,
+ }
+
+ if (redirectFrom) redirectParams.from = redirectFrom
+ if (exact) redirectParams.exact = exact
+
+ return memo.concat()
+ }
+
const RouteContainer = route.modal ? ModalRoute : Route
const RouteComponent = route.component
@@ -217,6 +235,10 @@ export default class TipsiRouter extends RouterBase {
this.callHistoryMethodWithArguments('push', e, route, paramsOrOptions)
}
+ redirect(url) {
+ window.location.replace(url)
+ }
+
async dismissModal(e) {
if (e) {
e.preventDefault()
diff --git a/src/Router.native.js b/src/Router.native.js
index 88e1bb2..30d2340 100644
--- a/src/Router.native.js
+++ b/src/Router.native.js
@@ -154,5 +154,8 @@ export default class TipsiRouter extends RouterBase {
)
}
+ /* eslint-disable-next-line */
+ redirect() {}
+
routeName = route => findKey(this.routes, { path: route.path })
}
diff --git a/src/Router.wix.js b/src/Router.wix.js
index 2ba97cd..753e47b 100644
--- a/src/Router.wix.js
+++ b/src/Router.wix.js
@@ -101,5 +101,10 @@ export default class TipsiRouter extends RouterBase {
Navigation.dismissModal()
}
+ /* eslint-disable-next-line */
+ redirect(url) {
+ window.location.replace(url)
+ }
+
routeName = route => findKey(this.routes, { path: route.path })
}