@nx/next-router
Advanced tools
Comparing version 1.0.5 to 1.1.0
@@ -1,4 +0,19 @@ | ||
export { default as Link } from './Link'; | ||
export { default as Route } from './Route'; | ||
export { default as Router } from './Router'; | ||
import NextLink from 'next/link'; | ||
import Router from './Router'; | ||
import Link from './Link'; | ||
import withNextRouterFactory from './hocs/withNextRouter'; | ||
import { CurrentRoute, RouterMatch, Routes } from './types'; | ||
declare let router: Router; | ||
declare let link: any; | ||
declare let withNextRouter: any; | ||
interface Constructable<T> { | ||
new (routes: Routes): T; | ||
} | ||
export declare const init: (routes: Routes, routerClass?: Constructable<Router> | undefined, LinkFactory?: ((router: Router) => (props: any) => NextLink) | undefined, getRouterMatchFunction?: ((appCtx: import("next/dist/next-server/lib/utils").AppContextType<import("next/router").Router>, router: Router) => RouterMatch) | undefined) => void; | ||
declare const useRouter: () => CurrentRoute; | ||
export { Router as RouterClass, Link as LinkFactory, withNextRouterFactory }; | ||
export { router as Router }; | ||
export { link as Link }; | ||
export { withNextRouter, useRouter }; | ||
export { default as RouteClass } from './Route'; | ||
export { Routes, RouteMatch, RouteAssemble, LinkProps } from './types'; |
@@ -5,5 +5,5 @@ 'use strict'; | ||
var NextRouter = _interopDefault(require('next/router')); | ||
var React = require('react'); | ||
var NextLink = _interopDefault(require('next/link')); | ||
var NextRouter = _interopDefault(require('next/router')); | ||
@@ -28,2 +28,8 @@ function _extends() { | ||
function _inheritsLoose(subClass, superClass) { | ||
subClass.prototype = Object.create(superClass.prototype); | ||
subClass.prototype.constructor = subClass; | ||
subClass.__proto__ = superClass; | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
@@ -44,30 +50,21 @@ if (source == null) return {}; | ||
var Link = function Link(router) { | ||
return function (_ref) { | ||
var route = _ref.route, | ||
_ref$params = _ref.params, | ||
params = _ref$params === void 0 ? {} : _ref$params, | ||
_ref$hash = _ref.hash, | ||
hash = _ref$hash === void 0 ? '' : _ref$hash, | ||
href = _ref.href, | ||
children = _ref.children, | ||
props = _objectWithoutPropertiesLoose(_ref, ["route", "params", "hash", "href", "children"]); | ||
var getUrlParams = function getUrlParams(queryString) { | ||
if (!queryString) { | ||
return {}; | ||
} | ||
if (!route && !href) { | ||
throw new Error('next-router: You have to provide a route or a href to the Link'); | ||
} | ||
var hashes = queryString.split('&'); | ||
var params = {}; | ||
hashes.map(function (hash) { | ||
var _hash$split = hash.split('='), | ||
key = _hash$split[0], | ||
val = _hash$split[1]; | ||
var mergedProps; | ||
if (route) { | ||
mergedProps = _extends({}, router.getLinkProps(route, params, hash), {}, props); | ||
} else { | ||
mergedProps = _extends({}, router.getLinkPropsFromHref(href || ''), {}, props); | ||
if (key) { | ||
params[key] = val ? decodeURIComponent(val) : null; | ||
} | ||
return React.createElement(NextLink, Object.assign({}, mergedProps), children); | ||
}; | ||
}); | ||
return params; | ||
}; | ||
// import * as pathToRegexp from 'path-to-regexp'; | ||
var pathToRegexp = | ||
@@ -102,4 +99,14 @@ /*#__PURE__*/ | ||
var asPathNoHash = asPathSplitted[0]; | ||
var asPathNoHashSplitted = asPathNoHash.split('?'); | ||
var asPathNoHashNoQuery = asPathNoHashSplitted[0]; // get query params | ||
var queryParams = {}; | ||
if (asPathNoHashSplitted.length > 1) { | ||
queryParams = getUrlParams(asPathNoHashSplitted[1]); | ||
} // get hash | ||
var hash = asPathSplitted.length > 1 ? asPathSplitted[1] : ''; | ||
var match = this.regex.exec(asPathNoHash); | ||
var match = this.regex.exec(asPathNoHashNoQuery); | ||
@@ -110,2 +117,3 @@ if (match !== null) { | ||
params: params, | ||
query: queryParams, | ||
hash: hash, | ||
@@ -119,5 +127,6 @@ path: asPath, | ||
return { | ||
params: null, | ||
hash: '', | ||
path: '', | ||
params: {}, | ||
query: queryParams, | ||
hash: hash, | ||
path: asPath, | ||
page: '', | ||
@@ -146,3 +155,2 @@ matched: false | ||
this.currentRoute = null; | ||
this.isCurrentRouteSet = false; | ||
this.addRoutes(routes); | ||
@@ -184,4 +192,5 @@ } | ||
route: '', | ||
params: null, | ||
path: '', | ||
params: {}, | ||
query: {}, | ||
path: asPath, | ||
page: '', | ||
@@ -224,5 +233,5 @@ hash: '', | ||
_proto.getLinkPropsFromHref = function getLinkPropsFromHref(href, cleanFunction) { | ||
if (cleanFunction === void 0) { | ||
cleanFunction = function cleanFunction(href) { | ||
_proto.getLinkPropsFromHref = function getLinkPropsFromHref(href, transformFn) { | ||
if (transformFn === void 0) { | ||
transformFn = function transformFn(href) { | ||
return href; | ||
@@ -233,3 +242,3 @@ }; | ||
var hrefSlash = href.substr(0, 1) !== '/' ? "/" + href : href; | ||
var match = this.match(cleanFunction(hrefSlash)); | ||
var match = this.match(transformFn(hrefSlash)); | ||
@@ -264,26 +273,39 @@ if (match.matched) { | ||
_proto.getRequestHandler = function getRequestHandler(app) { | ||
_proto.getRequestHandler = function getRequestHandler(renderFunction) { | ||
var _this = this; | ||
var nextHandler = app.getRequestHandler(); | ||
return function (req, res) { | ||
return function (req, res, next) { | ||
// don't render next url's | ||
var isNextUrl = req.url.match(/^\/_next|^\/static/); | ||
if (isNextUrl) { | ||
return next(); | ||
} // try to match request url | ||
var _this$match = _this.match(req.url), | ||
matched = _this$match.matched, | ||
route = _this$match.route, | ||
page = _this$match.page, | ||
params = _this$match.params, | ||
matched = _this$match.matched; | ||
query = _this$match.query, | ||
hash = _this$match.hash; | ||
if (matched) { | ||
if (!_this.isCurrentRouteSet) { | ||
_this.setCurrentRoute({ | ||
page: page, | ||
params: params | ||
}); | ||
// set current route for later access | ||
_this.setCurrentRoute({ | ||
route: route, | ||
page: page, | ||
params: params, | ||
query: query, | ||
hash: hash | ||
}); // call render function | ||
_this.isCurrentRouteSet = true; | ||
if (renderFunction) { | ||
return renderFunction(req, res, page, params, query, route); | ||
} | ||
} | ||
app.render(req, res, page, params); | ||
} else { | ||
nextHandler(req, res); | ||
} | ||
next(); | ||
}; | ||
@@ -300,17 +322,149 @@ }; | ||
_proto.getProps = function getProps() { | ||
return { | ||
route: NextRouter.route, | ||
query: NextRouter.query, | ||
pathname: NextRouter.pathname, | ||
asPath: NextRouter.asPath | ||
}; | ||
}; | ||
return Router; | ||
}(); | ||
exports.Link = Link; | ||
exports.Route = Route; | ||
exports.Router = Router; | ||
var Link = function Link(router) { | ||
return function (_ref) { | ||
var route = _ref.route, | ||
_ref$params = _ref.params, | ||
params = _ref$params === void 0 ? {} : _ref$params, | ||
_ref$hash = _ref.hash, | ||
hash = _ref$hash === void 0 ? '' : _ref$hash, | ||
href = _ref.href, | ||
children = _ref.children, | ||
props = _objectWithoutPropertiesLoose(_ref, ["route", "params", "hash", "href", "children"]); | ||
if (!route && !href) { | ||
throw new Error('next-router: You have to provide a route or a href to the Link'); | ||
} | ||
var mergedProps; | ||
if (route) { | ||
mergedProps = _extends({}, router.getLinkProps(route, params, hash), {}, props); | ||
} else { | ||
mergedProps = _extends({}, router.getLinkPropsFromHref(href || ''), {}, props); | ||
} | ||
return React.createElement(NextLink, Object.assign({}, mergedProps), children); | ||
}; | ||
}; | ||
var getRouterMatch = function getRouterMatch(appCtx, router) { | ||
var asPath = appCtx.ctx.asPath || ''; | ||
return router.match(asPath); | ||
}; | ||
var withNextRouterFactory = (function (router, getRouterMatchFunction) { | ||
if (!getRouterMatchFunction) { | ||
getRouterMatchFunction = getRouterMatch; | ||
} | ||
return function (App) { | ||
var _a; | ||
return _a = | ||
/*#__PURE__*/ | ||
function (_React$Component) { | ||
_inheritsLoose(WrappedApp, _React$Component); | ||
function WrappedApp() { | ||
return _React$Component.apply(this, arguments) || this; | ||
} | ||
var _proto = WrappedApp.prototype; | ||
_proto.render = function render() { | ||
var _this$props = this.props, | ||
initialProps = _this$props.initialProps, | ||
nextRouter_currentRoute = _this$props.nextRouter_currentRoute, | ||
props = _objectWithoutPropertiesLoose(_this$props, ["initialProps", "nextRouter_currentRoute"]); // set current route on hydration | ||
if (!router.getCurrentRoute()) { | ||
router.setCurrentRoute(nextRouter_currentRoute); | ||
} | ||
return React.createElement(App, Object.assign({}, props, initialProps)); | ||
}; | ||
return WrappedApp; | ||
}(React.Component), _a.getInitialProps = function (appCtx) { | ||
try { | ||
var _temp3 = function _temp3() { | ||
return { | ||
nextRouter_currentRoute: nextRouter_currentRoute, | ||
initialProps: initialProps | ||
}; | ||
}; | ||
var initialProps = {}; | ||
var routerMatch = { | ||
route: '', | ||
params: {}, | ||
query: {}, | ||
path: '', | ||
page: '', | ||
hash: '', | ||
matched: false | ||
}; | ||
if (getRouterMatchFunction) { | ||
routerMatch = getRouterMatchFunction(appCtx, router); | ||
} | ||
if (!routerMatch.matched) { | ||
if (appCtx.ctx.res) { | ||
appCtx.ctx.res.statusCode = 404; | ||
} | ||
} | ||
var _routerMatch = routerMatch, | ||
route = _routerMatch.route, | ||
page = _routerMatch.page, | ||
params = _routerMatch.params, | ||
query = _routerMatch.query, | ||
hash = _routerMatch.hash; | ||
var nextRouter_currentRoute = { | ||
route: route, | ||
page: page, | ||
params: params, | ||
query: query, | ||
hash: hash | ||
}; | ||
router.setCurrentRoute(nextRouter_currentRoute); | ||
appCtx.ctx.query = _extends({}, query, {}, params); | ||
var _temp4 = function () { | ||
if ('getInitialProps' in App) { | ||
return Promise.resolve(App.getInitialProps.call(App, appCtx)).then(function (_App$getInitialProps$) { | ||
initialProps = _App$getInitialProps$; | ||
}); | ||
} | ||
}(); | ||
return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4)); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
}, _a; | ||
}; | ||
}); | ||
var init = function init(routes, routerClass, LinkFactory, getRouterMatchFunction) { | ||
exports.Router = routerClass ? new routerClass(routes) : new Router(routes); | ||
exports.Link = LinkFactory ? LinkFactory(exports.Router) : Link(exports.Router); | ||
exports.withNextRouter = withNextRouterFactory(exports.Router, getRouterMatchFunction); | ||
}; | ||
var useRouter = function useRouter() { | ||
return exports.Router.getCurrentRoute(); | ||
}; | ||
exports.LinkFactory = Link; | ||
exports.RouteClass = Route; | ||
exports.RouterClass = Router; | ||
exports.init = init; | ||
exports.useRouter = useRouter; | ||
exports.withNextRouterFactory = withNextRouterFactory; | ||
//# sourceMappingURL=next-router.cjs.development.js.map |
@@ -1,2 +0,2 @@ | ||
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var t=require("react"),r=e(require("next/link")),n=e(require("next/router"));function a(){return(a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}var u=require("path-to-regexp"),o=function(){function e(e,t){this.page=t,this.compiled=u.compile(e),this.keys=[],this.regex=u(e,this.keys)}var t=e.prototype;return t.valuesToParams=function(e,t){return e.reduce(function(e,r,n){var a;return void 0===r?e:Object.assign(e,((a={})[t[n].name]=decodeURIComponent(r),a))},{})},t.match=function(e){var t=e.split("#"),r=t.length>1?t[1]:"",n=this.regex.exec(t[0]);return null!==n?{params:this.valuesToParams(n.slice(1),this.keys),hash:r,path:e,page:this.page,matched:!0}:{params:null,hash:"",path:"",page:"",matched:!1}},t.assemble=function(e){var t=this.compiled(e);return""===t?"/":t.replace(/%23/g,"#")},t.getPage=function(){return this.page},e}(),s=function(){function e(e){this.routes={},this.currentRoute=null,this.isCurrentRouteSet=!1,this.addRoutes(e)}var t=e.prototype;return t.addRoutes=function(e,t){for(var r in t&&(this.routes={}),e)e.hasOwnProperty(r)&&(this.routes[r]=new o(e[r].pattern,e[r].page))},t.match=function(e){for(var t in this.routes)if(this.routes.hasOwnProperty(t)){var r=this.routes[t].match(e);if(r.matched)return a({},r,{route:t})}return{route:"",params:null,path:"",page:"",hash:"",matched:!1}},t.assemble=function(e,t){if(this.routes[e])return{path:this.routes[e].assemble(t),page:this.routes[e].getPage()};throw new Error("next-router: No route matched")},t.getLinkProps=function(e,t,r){void 0===t&&(t={}),void 0===r&&(r="");var n=this.assemble(e,t);return{href:{pathname:n.page,query:t},as:n.path+(""!==r?"#"+r:"")}},t.getLinkPropsFromHref=function(e,t){void 0===t&&(t=function(e){return e});var r="/"!==e.substr(0,1)?"/"+e:e,n=this.match(t(r));return n.matched?this.getLinkProps(n.route,n.params,n.hash):{href:e,as:e}},t.push=function(e,t){void 0===t&&(t={});var r=this.getLinkProps(e,t);return n.push(r.href,r.as)},t.replace=function(e,t){void 0===t&&(t={});var r=this.getLinkProps(e,t);return n.replace(r.href,r.as)},t.getRequestHandler=function(e){var t=this,r=e.getRequestHandler();return function(n,a){var u=t.match(n.url),o=u.page,s=u.params;u.matched?(t.isCurrentRouteSet||(t.setCurrentRoute({page:o,params:s}),t.isCurrentRouteSet=!0),e.render(n,a,o,s)):r(n,a)}},t.setCurrentRoute=function(e){this.currentRoute=e},t.getCurrentRoute=function(){return this.currentRoute},t.getProps=function(){return{route:n.route,query:n.query,pathname:n.pathname,asPath:n.asPath}},e}();exports.Link=function(e){return function(n){var u,o=n.route,s=n.params,i=void 0===s?{}:s,h=n.hash,c=void 0===h?"":h,p=n.href,f=n.children,l=function(e,t){if(null==e)return{};var r,n,a={},u=Object.keys(e);for(n=0;n<u.length;n++)t.indexOf(r=u[n])>=0||(a[r]=e[r]);return a}(n,["route","params","hash","href","children"]);if(!o&&!p)throw new Error("next-router: You have to provide a route or a href to the Link");return u=a({},o?e.getLinkProps(o,i,c):e.getLinkPropsFromHref(p||""),{},l),t.createElement(r,Object.assign({},u),f)}},exports.Route=o,exports.Router=s; | ||
"use strict";function t(t){return t&&"object"==typeof t&&"default"in t?t.default:t}var e=t(require("next/router")),r=require("react"),n=t(require("next/link"));function o(){return(o=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t}).apply(this,arguments)}function u(t,e){if(null==t)return{};var r,n,o={},u=Object.keys(t);for(n=0;n<u.length;n++)e.indexOf(r=u[n])>=0||(o[r]=t[r]);return o}var a=require("path-to-regexp"),s=function(){function t(t,e){this.page=e,this.compiled=a.compile(t),this.keys=[],this.regex=a(t,this.keys)}var e=t.prototype;return e.valuesToParams=function(t,e){return t.reduce(function(t,r,n){var o;return void 0===r?t:Object.assign(t,((o={})[e[n].name]=decodeURIComponent(r),o))},{})},e.match=function(t){var e=t.split("#"),r=e[0].split("?"),n=r[0],o={};r.length>1&&(o=function(t){if(!t)return{};var e=t.split("&"),r={};return e.map(function(t){var e=t.split("="),n=e[0],o=e[1];n&&(r[n]=o?decodeURIComponent(o):null)}),r}(r[1]));var u=e.length>1?e[1]:"",a=this.regex.exec(n);return null!==a?{params:this.valuesToParams(a.slice(1),this.keys),query:o,hash:u,path:t,page:this.page,matched:!0}:{params:{},query:o,hash:u,path:t,page:"",matched:!1}},e.assemble=function(t){var e=this.compiled(t);return""===e?"/":e.replace(/%23/g,"#")},e.getPage=function(){return this.page},t}(),i=function(){function t(t){this.routes={},this.currentRoute=null,this.addRoutes(t)}var r=t.prototype;return r.addRoutes=function(t,e){for(var r in e&&(this.routes={}),t)t.hasOwnProperty(r)&&(this.routes[r]=new s(t[r].pattern,t[r].page))},r.match=function(t){for(var e in this.routes)if(this.routes.hasOwnProperty(e)){var r=this.routes[e].match(t);if(r.matched)return o({},r,{route:e})}return{route:"",params:{},query:{},path:t,page:"",hash:"",matched:!1}},r.assemble=function(t,e){if(this.routes[t])return{path:this.routes[t].assemble(e),page:this.routes[t].getPage()};throw new Error("next-router: No route matched")},r.getLinkProps=function(t,e,r){void 0===e&&(e={}),void 0===r&&(r="");var n=this.assemble(t,e);return{href:{pathname:n.page,query:e},as:n.path+(""!==r?"#"+r:"")}},r.getLinkPropsFromHref=function(t,e){void 0===e&&(e=function(t){return t});var r="/"!==t.substr(0,1)?"/"+t:t,n=this.match(e(r));return n.matched?this.getLinkProps(n.route,n.params,n.hash):{href:t,as:t}},r.push=function(t,r){void 0===r&&(r={});var n=this.getLinkProps(t,r);return e.push(n.href,n.as)},r.replace=function(t,r){void 0===r&&(r={});var n=this.getLinkProps(t,r);return e.replace(n.href,n.as)},r.getRequestHandler=function(t){var e=this;return function(r,n,o){if(r.url.match(/^\/_next|^\/static/))return o();var u=e.match(r.url),a=u.route,s=u.page,i=u.params,h=u.query;if(u.matched&&(e.setCurrentRoute({route:a,page:s,params:i,query:h,hash:u.hash}),t))return t(r,n,s,i,h,a);o()}},r.setCurrentRoute=function(t){this.currentRoute=t},r.getCurrentRoute=function(){return this.currentRoute},t}(),h=function(t){return function(e){var a,s=e.route,i=e.params,h=void 0===i?{}:i,c=e.hash,p=void 0===c?"":c,f=e.href,l=e.children,m=u(e,["route","params","hash","href","children"]);if(!s&&!f)throw new Error("next-router: You have to provide a route or a href to the Link");return a=o({},s?t.getLinkProps(s,h,p):t.getLinkPropsFromHref(f||""),{},m),r.createElement(n,Object.assign({},a),l)}},c=function(t,e){return e.match(t.ctx.asPath||"")},p=function(t,e){return e||(e=c),function(n){var a;return(a=function(e){var o,a;function s(){return e.apply(this,arguments)||this}return a=e,(o=s).prototype=Object.create(a.prototype),o.prototype.constructor=o,o.__proto__=a,s.prototype.render=function(){var e=this.props,o=e.initialProps,a=e.nextRouter_currentRoute,s=u(e,["initialProps","nextRouter_currentRoute"]);return t.getCurrentRoute()||t.setCurrentRoute(a),r.createElement(n,Object.assign({},s,o))},s}(r.Component)).getInitialProps=function(r){try{var u=function(){return{nextRouter_currentRoute:c,initialProps:a}},a={},s={route:"",params:{},query:{},path:"",page:"",hash:"",matched:!1};e&&(s=e(r,t)),s.matched||r.ctx.res&&(r.ctx.res.statusCode=404);var i=s.params,h=s.query,c={route:s.route,page:s.page,params:i,query:h,hash:s.hash};t.setCurrentRoute(c),r.ctx.query=o({},h,{},i);var p=function(){if("getInitialProps"in n)return Promise.resolve(n.getInitialProps.call(n,r)).then(function(t){a=t})}();return Promise.resolve(p&&p.then?p.then(u):u())}catch(t){return Promise.reject(t)}},a}};exports.LinkFactory=h,exports.RouteClass=s,exports.RouterClass=i,exports.init=function(t,e,r,n){exports.Router=e?new e(t):new i(t),exports.Link=r?r(exports.Router):h(exports.Router),exports.withNextRouter=p(exports.Router,n)},exports.useRouter=function(){return exports.Router.getCurrentRoute()},exports.withNextRouterFactory=p; | ||
//# sourceMappingURL=next-router.cjs.production.min.js.map |
@@ -1,4 +0,4 @@ | ||
import { createElement } from 'react'; | ||
import NextRouter from 'next/router'; | ||
import { createElement, Component } from 'react'; | ||
import NextLink from 'next/link'; | ||
import NextRouter from 'next/router'; | ||
@@ -23,2 +23,8 @@ function _extends() { | ||
function _inheritsLoose(subClass, superClass) { | ||
subClass.prototype = Object.create(superClass.prototype); | ||
subClass.prototype.constructor = subClass; | ||
subClass.__proto__ = superClass; | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
@@ -39,30 +45,21 @@ if (source == null) return {}; | ||
var Link = function Link(router) { | ||
return function (_ref) { | ||
var route = _ref.route, | ||
_ref$params = _ref.params, | ||
params = _ref$params === void 0 ? {} : _ref$params, | ||
_ref$hash = _ref.hash, | ||
hash = _ref$hash === void 0 ? '' : _ref$hash, | ||
href = _ref.href, | ||
children = _ref.children, | ||
props = _objectWithoutPropertiesLoose(_ref, ["route", "params", "hash", "href", "children"]); | ||
var getUrlParams = function getUrlParams(queryString) { | ||
if (!queryString) { | ||
return {}; | ||
} | ||
if (!route && !href) { | ||
throw new Error('next-router: You have to provide a route or a href to the Link'); | ||
} | ||
var hashes = queryString.split('&'); | ||
var params = {}; | ||
hashes.map(function (hash) { | ||
var _hash$split = hash.split('='), | ||
key = _hash$split[0], | ||
val = _hash$split[1]; | ||
var mergedProps; | ||
if (route) { | ||
mergedProps = _extends({}, router.getLinkProps(route, params, hash), {}, props); | ||
} else { | ||
mergedProps = _extends({}, router.getLinkPropsFromHref(href || ''), {}, props); | ||
if (key) { | ||
params[key] = val ? decodeURIComponent(val) : null; | ||
} | ||
return createElement(NextLink, Object.assign({}, mergedProps), children); | ||
}; | ||
}); | ||
return params; | ||
}; | ||
// import * as pathToRegexp from 'path-to-regexp'; | ||
var pathToRegexp = | ||
@@ -97,4 +94,14 @@ /*#__PURE__*/ | ||
var asPathNoHash = asPathSplitted[0]; | ||
var asPathNoHashSplitted = asPathNoHash.split('?'); | ||
var asPathNoHashNoQuery = asPathNoHashSplitted[0]; // get query params | ||
var queryParams = {}; | ||
if (asPathNoHashSplitted.length > 1) { | ||
queryParams = getUrlParams(asPathNoHashSplitted[1]); | ||
} // get hash | ||
var hash = asPathSplitted.length > 1 ? asPathSplitted[1] : ''; | ||
var match = this.regex.exec(asPathNoHash); | ||
var match = this.regex.exec(asPathNoHashNoQuery); | ||
@@ -105,2 +112,3 @@ if (match !== null) { | ||
params: params, | ||
query: queryParams, | ||
hash: hash, | ||
@@ -114,5 +122,6 @@ path: asPath, | ||
return { | ||
params: null, | ||
hash: '', | ||
path: '', | ||
params: {}, | ||
query: queryParams, | ||
hash: hash, | ||
path: asPath, | ||
page: '', | ||
@@ -141,3 +150,2 @@ matched: false | ||
this.currentRoute = null; | ||
this.isCurrentRouteSet = false; | ||
this.addRoutes(routes); | ||
@@ -179,4 +187,5 @@ } | ||
route: '', | ||
params: null, | ||
path: '', | ||
params: {}, | ||
query: {}, | ||
path: asPath, | ||
page: '', | ||
@@ -219,5 +228,5 @@ hash: '', | ||
_proto.getLinkPropsFromHref = function getLinkPropsFromHref(href, cleanFunction) { | ||
if (cleanFunction === void 0) { | ||
cleanFunction = function cleanFunction(href) { | ||
_proto.getLinkPropsFromHref = function getLinkPropsFromHref(href, transformFn) { | ||
if (transformFn === void 0) { | ||
transformFn = function transformFn(href) { | ||
return href; | ||
@@ -228,3 +237,3 @@ }; | ||
var hrefSlash = href.substr(0, 1) !== '/' ? "/" + href : href; | ||
var match = this.match(cleanFunction(hrefSlash)); | ||
var match = this.match(transformFn(hrefSlash)); | ||
@@ -259,26 +268,39 @@ if (match.matched) { | ||
_proto.getRequestHandler = function getRequestHandler(app) { | ||
_proto.getRequestHandler = function getRequestHandler(renderFunction) { | ||
var _this = this; | ||
var nextHandler = app.getRequestHandler(); | ||
return function (req, res) { | ||
return function (req, res, next) { | ||
// don't render next url's | ||
var isNextUrl = req.url.match(/^\/_next|^\/static/); | ||
if (isNextUrl) { | ||
return next(); | ||
} // try to match request url | ||
var _this$match = _this.match(req.url), | ||
matched = _this$match.matched, | ||
route = _this$match.route, | ||
page = _this$match.page, | ||
params = _this$match.params, | ||
matched = _this$match.matched; | ||
query = _this$match.query, | ||
hash = _this$match.hash; | ||
if (matched) { | ||
if (!_this.isCurrentRouteSet) { | ||
_this.setCurrentRoute({ | ||
page: page, | ||
params: params | ||
}); | ||
// set current route for later access | ||
_this.setCurrentRoute({ | ||
route: route, | ||
page: page, | ||
params: params, | ||
query: query, | ||
hash: hash | ||
}); // call render function | ||
_this.isCurrentRouteSet = true; | ||
if (renderFunction) { | ||
return renderFunction(req, res, page, params, query, route); | ||
} | ||
} | ||
app.render(req, res, page, params); | ||
} else { | ||
nextHandler(req, res); | ||
} | ||
next(); | ||
}; | ||
@@ -295,15 +317,147 @@ }; | ||
_proto.getProps = function getProps() { | ||
return { | ||
route: NextRouter.route, | ||
query: NextRouter.query, | ||
pathname: NextRouter.pathname, | ||
asPath: NextRouter.asPath | ||
}; | ||
}; | ||
return Router; | ||
}(); | ||
export { Link, Route, Router }; | ||
var Link = function Link(router) { | ||
return function (_ref) { | ||
var route = _ref.route, | ||
_ref$params = _ref.params, | ||
params = _ref$params === void 0 ? {} : _ref$params, | ||
_ref$hash = _ref.hash, | ||
hash = _ref$hash === void 0 ? '' : _ref$hash, | ||
href = _ref.href, | ||
children = _ref.children, | ||
props = _objectWithoutPropertiesLoose(_ref, ["route", "params", "hash", "href", "children"]); | ||
if (!route && !href) { | ||
throw new Error('next-router: You have to provide a route or a href to the Link'); | ||
} | ||
var mergedProps; | ||
if (route) { | ||
mergedProps = _extends({}, router.getLinkProps(route, params, hash), {}, props); | ||
} else { | ||
mergedProps = _extends({}, router.getLinkPropsFromHref(href || ''), {}, props); | ||
} | ||
return createElement(NextLink, Object.assign({}, mergedProps), children); | ||
}; | ||
}; | ||
var getRouterMatch = function getRouterMatch(appCtx, router) { | ||
var asPath = appCtx.ctx.asPath || ''; | ||
return router.match(asPath); | ||
}; | ||
var withNextRouterFactory = (function (router, getRouterMatchFunction) { | ||
if (!getRouterMatchFunction) { | ||
getRouterMatchFunction = getRouterMatch; | ||
} | ||
return function (App) { | ||
var _a; | ||
return _a = | ||
/*#__PURE__*/ | ||
function (_React$Component) { | ||
_inheritsLoose(WrappedApp, _React$Component); | ||
function WrappedApp() { | ||
return _React$Component.apply(this, arguments) || this; | ||
} | ||
var _proto = WrappedApp.prototype; | ||
_proto.render = function render() { | ||
var _this$props = this.props, | ||
initialProps = _this$props.initialProps, | ||
nextRouter_currentRoute = _this$props.nextRouter_currentRoute, | ||
props = _objectWithoutPropertiesLoose(_this$props, ["initialProps", "nextRouter_currentRoute"]); // set current route on hydration | ||
if (!router.getCurrentRoute()) { | ||
router.setCurrentRoute(nextRouter_currentRoute); | ||
} | ||
return createElement(App, Object.assign({}, props, initialProps)); | ||
}; | ||
return WrappedApp; | ||
}(Component), _a.getInitialProps = function (appCtx) { | ||
try { | ||
var _temp3 = function _temp3() { | ||
return { | ||
nextRouter_currentRoute: nextRouter_currentRoute, | ||
initialProps: initialProps | ||
}; | ||
}; | ||
var initialProps = {}; | ||
var routerMatch = { | ||
route: '', | ||
params: {}, | ||
query: {}, | ||
path: '', | ||
page: '', | ||
hash: '', | ||
matched: false | ||
}; | ||
if (getRouterMatchFunction) { | ||
routerMatch = getRouterMatchFunction(appCtx, router); | ||
} | ||
if (!routerMatch.matched) { | ||
if (appCtx.ctx.res) { | ||
appCtx.ctx.res.statusCode = 404; | ||
} | ||
} | ||
var _routerMatch = routerMatch, | ||
route = _routerMatch.route, | ||
page = _routerMatch.page, | ||
params = _routerMatch.params, | ||
query = _routerMatch.query, | ||
hash = _routerMatch.hash; | ||
var nextRouter_currentRoute = { | ||
route: route, | ||
page: page, | ||
params: params, | ||
query: query, | ||
hash: hash | ||
}; | ||
router.setCurrentRoute(nextRouter_currentRoute); | ||
appCtx.ctx.query = _extends({}, query, {}, params); | ||
var _temp4 = function () { | ||
if ('getInitialProps' in App) { | ||
return Promise.resolve(App.getInitialProps.call(App, appCtx)).then(function (_App$getInitialProps$) { | ||
initialProps = _App$getInitialProps$; | ||
}); | ||
} | ||
}(); | ||
return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4)); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
}, _a; | ||
}; | ||
}); | ||
var router; | ||
var link; | ||
var withNextRouter; | ||
var init = function init(routes, routerClass, LinkFactory, getRouterMatchFunction) { | ||
router = routerClass ? new routerClass(routes) : new Router(routes); | ||
link = LinkFactory ? LinkFactory(router) : Link(router); | ||
withNextRouter = withNextRouterFactory(router, getRouterMatchFunction); | ||
}; | ||
var useRouter = function useRouter() { | ||
return router.getCurrentRoute(); | ||
}; | ||
export { link as Link, Link as LinkFactory, Route as RouteClass, router as Router, Router as RouterClass, init, useRouter, withNextRouter, withNextRouterFactory }; | ||
//# sourceMappingURL=next-router.esm.js.map |
@@ -1,27 +0,17 @@ | ||
/// <reference types="node" /> | ||
import { RouteMatch, CurrentRoute, Routes, RouteAssemble, LinkProps } from '../types'; | ||
import { RouterMatch, CurrentRoute, Routes, RouteAssemble, LinkProps } from '../types'; | ||
declare class Router { | ||
private routes; | ||
private currentRoute; | ||
private isCurrentRouteSet; | ||
constructor(routes: Routes); | ||
addRoutes(routes: Routes, overwrite?: boolean): void; | ||
match(asPath: string): RouteMatch & { | ||
route: string; | ||
}; | ||
match(asPath: string): RouterMatch; | ||
assemble(route: string, params: any): RouteAssemble; | ||
getLinkProps(route: string, params?: any, hash?: string): LinkProps; | ||
getLinkPropsFromHref(href: string, cleanFunction?: (href: string) => string): LinkProps; | ||
getLinkPropsFromHref(href: string, transformFn?: (href: string) => string): LinkProps; | ||
push(route: string, params?: any): Promise<boolean>; | ||
replace(route: string, params?: any): Promise<boolean>; | ||
getRequestHandler(app: any): (req: any, res: any) => void; | ||
getRequestHandler(renderFunction: Function): (req: any, res: any, next: any) => any; | ||
setCurrentRoute(currentRoute: CurrentRoute): void; | ||
getCurrentRoute(): CurrentRoute; | ||
getProps(): { | ||
route: string; | ||
query: import("querystring").ParsedUrlQuery; | ||
pathname: string; | ||
asPath: string; | ||
}; | ||
} | ||
export default Router; |
export declare type Route = { | ||
pattern: string; | ||
page: string; | ||
[key: string]: any; | ||
}; | ||
@@ -11,2 +12,3 @@ export declare type Routes = { | ||
params: any; | ||
query: any; | ||
matched: boolean; | ||
@@ -16,5 +18,11 @@ path: string; | ||
}; | ||
export declare type RouterMatch = RouteMatch & { | ||
route: string; | ||
}; | ||
export declare type CurrentRoute = { | ||
route: string; | ||
page: string; | ||
params: any; | ||
query: any; | ||
hash: string; | ||
} | null; | ||
@@ -21,0 +29,0 @@ export declare type RouteAssemble = { |
{ | ||
"name": "@nx/next-router", | ||
"version": "1.0.5", | ||
"version": "1.1.0", | ||
"description": "A routing library for Next.js", | ||
@@ -42,2 +42,3 @@ "repository": "nexumAG/next-router", | ||
"next": "^9.0.6", | ||
"prettier": "^1.18.2", | ||
"react": "^16.9.0", | ||
@@ -44,0 +45,0 @@ "react-dom": "^16.9.0", |
136
README.md
@@ -21,3 +21,12 @@ # next-router | ||
- Url Hashes support | ||
- withNextRouter HOC for custom app component (make current route available) | ||
- useRouter hook | ||
- Link and Router available as Singleton thru `import { Link, Router } from '@nx/next-router';` | ||
###### TODO: | ||
- Router events with route information | ||
- Unnamed parameters (does it make sense? -> [unnamed-parameters](https://github.com/pillarjs/path-to-regexp#unnamed-parameters) | ||
- Nested routes | ||
## How to | ||
@@ -30,3 +39,3 @@ | ||
```javascript | ||
import { Router, Routes, Link } from '@nx/next-router'; | ||
import { Routes, init } from '@nx/next-router'; | ||
@@ -44,7 +53,3 @@ const routes: Routes = { | ||
const router = new Router(routes); | ||
const link = Link(router); | ||
export { router as Router }; | ||
export { link as Link }; | ||
init(routes); | ||
``` | ||
@@ -59,3 +64,2 @@ | ||
}, | ||
``` | ||
@@ -69,5 +73,9 @@ | ||
You can use the exported Link component instead of the next/link. | ||
Import the routes config file once in your application. (e.g. Custom App component) | ||
You can use next-router Link component instead of the next/link. | ||
```jsx | ||
import 'routes.config'; // import this only once and before using Link | ||
import { Link } from '@nx/next-router'; | ||
@@ -83,4 +91,116 @@ // /user pattern | ||
</Link> | ||
``` | ||
#### withNextRouter HOC | ||
If you use this HOC the query params and route information will be available in `getInitialProps` and `useRouter` hook. | ||
```jsx | ||
// _app.tsx | ||
import React from 'react'; | ||
import App from 'next/app'; | ||
import '../routes.config'; | ||
import { withNextRouter } from '@nx/next-router'; | ||
class MyApp extends App { | ||
render() { | ||
const { Component, pageProps } = this.props; | ||
return <Component {...pageProps} />; | ||
} | ||
} | ||
export default withNextRouter(MyApp); | ||
``` | ||
```jsx | ||
// next page example | ||
Page.getInitialProps = async ({ query }) => { | ||
// query contains the matched route params + get params | ||
return { query }; | ||
} | ||
``` | ||
```jsx | ||
// userRouter hook example | ||
import React from 'react'; | ||
import { useRouter } from '@nx/next-router'; | ||
const Component = props => { | ||
const { route, params, query } = useRouter(); | ||
return ( | ||
<> | ||
<h1>Route: {route}</h1> | ||
<p>params:</p> | ||
{JSON.stringify(params)} | ||
<p>query:</p> | ||
{JSON.stringify(query)} | ||
</> | ||
); | ||
} | ||
``` | ||
#### Custom Router/Link | ||
You can pass a custom Router class, Link component or getRouterMatchFunction to the init function if you need to. | ||
They will be used instead of the built ins with `import { Link, Router } from '@nx/next-router';`. | ||
```javascript | ||
import { Routes, init } from '@nx/next-router'; | ||
const routes: Routes = { | ||
... | ||
}; | ||
init(routes, YourRouterClass, YourLinkFactory, yourGetRouterMatchFunction); | ||
``` | ||
#### Custom Server | ||
If you use a custom server you can create more complex routes and are not limited by what you can do with Next.js default routing. | ||
Disable file-system routing | ||
```javascript | ||
// next.config.js | ||
module.exports = { | ||
useFileSystemPublicRoutes: false, | ||
} | ||
``` | ||
```javascript | ||
// server.js | ||
const express = require('express'); | ||
const next = require('next'); | ||
require('./routes.config'); | ||
const Router = require('@nx/next-router').Router; | ||
const port = parseInt(process.env.PORT, 10) || 3000; | ||
const dev = process.env.NODE_ENV !== 'production'; | ||
const app = next({ dev }); | ||
const handle = app.getRequestHandler(); | ||
const render = (req, res, page, params, query, route) => app.render(req, res, page, params); | ||
app.prepare().then(() => { | ||
const server = express(); | ||
server.use(Router.getRequestHandler(render)); | ||
server.all('*', (req, res) => { | ||
return handle(req, res); | ||
}) | ||
server.listen(port, err => { | ||
if (err) throw err | ||
console.log(`> Ready on http://localhost:${port}`); | ||
}) | ||
}); | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
95212
20
938
201
12