@tinkoff/router 0.1.75 → 0.1.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.browser.js +23 -8
- package/lib/index.es.js +23 -8
- package/lib/index.js +23 -8
- package/lib/router/abstract.d.ts +2 -1
- package/lib/types.d.ts +2 -0
- package/lib/utils.d.ts +1 -1
- package/package.json +1 -1
package/lib/index.browser.js
CHANGED
|
@@ -221,17 +221,20 @@ class AbstractRouter {
|
|
|
221
221
|
await this.runHooks('afterUpdateCurrent', navigation);
|
|
222
222
|
}
|
|
223
223
|
async navigate(navigateOptions) {
|
|
224
|
-
return this.internalNavigate(
|
|
224
|
+
return this.internalNavigate(makeNavigateOptions(navigateOptions), {});
|
|
225
225
|
}
|
|
226
|
-
async internalNavigate(navigateOptions, { history }) {
|
|
226
|
+
async internalNavigate(navigateOptions, { history, redirect }) {
|
|
227
227
|
var _a;
|
|
228
228
|
const { url, replace, params, navigateState, code } = navigateOptions;
|
|
229
|
-
const prevNavigation =
|
|
229
|
+
const prevNavigation = redirect
|
|
230
|
+
? this.lastNavigation
|
|
231
|
+
: (_a = this.currentNavigation) !== null && _a !== void 0 ? _a : this.lastNavigation;
|
|
230
232
|
if (!url && !prevNavigation) {
|
|
231
233
|
throw new Error('Navigate url should be specified and cannot be omitted for first navigation');
|
|
232
234
|
}
|
|
233
235
|
const resolvedUrl = this.resolveUrl(navigateOptions);
|
|
234
236
|
const { to: from, url: fromUrl } = prevNavigation !== null && prevNavigation !== void 0 ? prevNavigation : {};
|
|
237
|
+
const redirectFrom = redirect ? this.currentNavigation.to : undefined;
|
|
235
238
|
let navigation = {
|
|
236
239
|
type: 'navigate',
|
|
237
240
|
from,
|
|
@@ -241,6 +244,8 @@ class AbstractRouter {
|
|
|
241
244
|
history,
|
|
242
245
|
navigateState,
|
|
243
246
|
code,
|
|
247
|
+
redirect,
|
|
248
|
+
redirectFrom,
|
|
244
249
|
};
|
|
245
250
|
await this.runHooks('beforeResolve', navigation);
|
|
246
251
|
const to = this.resolveRoute({ url: resolvedUrl, params, navigateState }, { wildcard: true });
|
|
@@ -366,7 +371,9 @@ class AbstractRouter {
|
|
|
366
371
|
pathname = makePath(currentRoute.path, { ...currentRoute.params, ...params });
|
|
367
372
|
}
|
|
368
373
|
}
|
|
369
|
-
|
|
374
|
+
if (isSameHost(resultUrl)) {
|
|
375
|
+
pathname = this.normalizePathname(pathname);
|
|
376
|
+
}
|
|
370
377
|
return convertRawUrl(rawAssignUrl(resultUrl, {
|
|
371
378
|
pathname,
|
|
372
379
|
search: url ? resultUrl.search : '',
|
|
@@ -556,7 +563,7 @@ const wrapHistory = ({ onNavigate }) => {
|
|
|
556
563
|
const history = (delta) => {
|
|
557
564
|
go(delta);
|
|
558
565
|
};
|
|
559
|
-
const browserNavigate = (replace) => {
|
|
566
|
+
const browserNavigate = (replace = false) => {
|
|
560
567
|
return (navigateState, title, url) => {
|
|
561
568
|
onNavigate({ url, replace, navigateState });
|
|
562
569
|
};
|
|
@@ -770,8 +777,11 @@ class ClientRouter extends AbstractRouter {
|
|
|
770
777
|
// in case we didn't find any matched route just force hard page navigation
|
|
771
778
|
const prevUrl = (_b = (_a = navigation.fromUrl) === null || _a === void 0 ? void 0 : _a.href) !== null && _b !== void 0 ? _b : window.location.href;
|
|
772
779
|
const nextUrl = navigation.url.href;
|
|
773
|
-
|
|
774
|
-
|
|
780
|
+
const isNoSpaNavigation = navigation.from && !navigation.to;
|
|
781
|
+
// prevent redirect cycle on the same page,
|
|
782
|
+
// except cases when we run no-spa navigations,
|
|
783
|
+
// because we need hard reload in this cases
|
|
784
|
+
if (isNoSpaNavigation ? true : prevUrl !== nextUrl) {
|
|
775
785
|
if (navigation.replace) {
|
|
776
786
|
window.location.replace(nextUrl);
|
|
777
787
|
}
|
|
@@ -787,7 +797,12 @@ class ClientRouter extends AbstractRouter {
|
|
|
787
797
|
}
|
|
788
798
|
async redirect(navigation, target) {
|
|
789
799
|
await super.redirect(navigation, target);
|
|
790
|
-
return this.
|
|
800
|
+
return this.internalNavigate({
|
|
801
|
+
...target,
|
|
802
|
+
replace: target.replace || navigation.replace,
|
|
803
|
+
}, {
|
|
804
|
+
redirect: true,
|
|
805
|
+
});
|
|
791
806
|
}
|
|
792
807
|
}
|
|
793
808
|
|
package/lib/index.es.js
CHANGED
|
@@ -221,17 +221,20 @@ class AbstractRouter {
|
|
|
221
221
|
await this.runHooks('afterUpdateCurrent', navigation);
|
|
222
222
|
}
|
|
223
223
|
async navigate(navigateOptions) {
|
|
224
|
-
return this.internalNavigate(
|
|
224
|
+
return this.internalNavigate(makeNavigateOptions(navigateOptions), {});
|
|
225
225
|
}
|
|
226
|
-
async internalNavigate(navigateOptions, { history }) {
|
|
226
|
+
async internalNavigate(navigateOptions, { history, redirect }) {
|
|
227
227
|
var _a;
|
|
228
228
|
const { url, replace, params, navigateState, code } = navigateOptions;
|
|
229
|
-
const prevNavigation =
|
|
229
|
+
const prevNavigation = redirect
|
|
230
|
+
? this.lastNavigation
|
|
231
|
+
: (_a = this.currentNavigation) !== null && _a !== void 0 ? _a : this.lastNavigation;
|
|
230
232
|
if (!url && !prevNavigation) {
|
|
231
233
|
throw new Error('Navigate url should be specified and cannot be omitted for first navigation');
|
|
232
234
|
}
|
|
233
235
|
const resolvedUrl = this.resolveUrl(navigateOptions);
|
|
234
236
|
const { to: from, url: fromUrl } = prevNavigation !== null && prevNavigation !== void 0 ? prevNavigation : {};
|
|
237
|
+
const redirectFrom = redirect ? this.currentNavigation.to : undefined;
|
|
235
238
|
let navigation = {
|
|
236
239
|
type: 'navigate',
|
|
237
240
|
from,
|
|
@@ -241,6 +244,8 @@ class AbstractRouter {
|
|
|
241
244
|
history,
|
|
242
245
|
navigateState,
|
|
243
246
|
code,
|
|
247
|
+
redirect,
|
|
248
|
+
redirectFrom,
|
|
244
249
|
};
|
|
245
250
|
await this.runHooks('beforeResolve', navigation);
|
|
246
251
|
const to = this.resolveRoute({ url: resolvedUrl, params, navigateState }, { wildcard: true });
|
|
@@ -366,7 +371,9 @@ class AbstractRouter {
|
|
|
366
371
|
pathname = makePath(currentRoute.path, { ...currentRoute.params, ...params });
|
|
367
372
|
}
|
|
368
373
|
}
|
|
369
|
-
|
|
374
|
+
if (isSameHost(resultUrl)) {
|
|
375
|
+
pathname = this.normalizePathname(pathname);
|
|
376
|
+
}
|
|
370
377
|
return convertRawUrl(rawAssignUrl(resultUrl, {
|
|
371
378
|
pathname,
|
|
372
379
|
search: url ? resultUrl.search : '',
|
|
@@ -786,7 +793,7 @@ const wrapHistory = ({ onNavigate }) => {
|
|
|
786
793
|
const history = (delta) => {
|
|
787
794
|
go(delta);
|
|
788
795
|
};
|
|
789
|
-
const browserNavigate = (replace) => {
|
|
796
|
+
const browserNavigate = (replace = false) => {
|
|
790
797
|
return (navigateState, title, url) => {
|
|
791
798
|
onNavigate({ url, replace, navigateState });
|
|
792
799
|
};
|
|
@@ -1000,8 +1007,11 @@ class ClientRouter extends AbstractRouter {
|
|
|
1000
1007
|
// in case we didn't find any matched route just force hard page navigation
|
|
1001
1008
|
const prevUrl = (_b = (_a = navigation.fromUrl) === null || _a === void 0 ? void 0 : _a.href) !== null && _b !== void 0 ? _b : window.location.href;
|
|
1002
1009
|
const nextUrl = navigation.url.href;
|
|
1003
|
-
|
|
1004
|
-
|
|
1010
|
+
const isNoSpaNavigation = navigation.from && !navigation.to;
|
|
1011
|
+
// prevent redirect cycle on the same page,
|
|
1012
|
+
// except cases when we run no-spa navigations,
|
|
1013
|
+
// because we need hard reload in this cases
|
|
1014
|
+
if (isNoSpaNavigation ? true : prevUrl !== nextUrl) {
|
|
1005
1015
|
if (navigation.replace) {
|
|
1006
1016
|
window.location.replace(nextUrl);
|
|
1007
1017
|
}
|
|
@@ -1017,7 +1027,12 @@ class ClientRouter extends AbstractRouter {
|
|
|
1017
1027
|
}
|
|
1018
1028
|
async redirect(navigation, target) {
|
|
1019
1029
|
await super.redirect(navigation, target);
|
|
1020
|
-
return this.
|
|
1030
|
+
return this.internalNavigate({
|
|
1031
|
+
...target,
|
|
1032
|
+
replace: target.replace || navigation.replace,
|
|
1033
|
+
}, {
|
|
1034
|
+
redirect: true,
|
|
1035
|
+
});
|
|
1021
1036
|
}
|
|
1022
1037
|
}
|
|
1023
1038
|
|
package/lib/index.js
CHANGED
|
@@ -236,17 +236,20 @@ class AbstractRouter {
|
|
|
236
236
|
await this.runHooks('afterUpdateCurrent', navigation);
|
|
237
237
|
}
|
|
238
238
|
async navigate(navigateOptions) {
|
|
239
|
-
return this.internalNavigate(
|
|
239
|
+
return this.internalNavigate(makeNavigateOptions(navigateOptions), {});
|
|
240
240
|
}
|
|
241
|
-
async internalNavigate(navigateOptions, { history }) {
|
|
241
|
+
async internalNavigate(navigateOptions, { history, redirect }) {
|
|
242
242
|
var _a;
|
|
243
243
|
const { url, replace, params, navigateState, code } = navigateOptions;
|
|
244
|
-
const prevNavigation =
|
|
244
|
+
const prevNavigation = redirect
|
|
245
|
+
? this.lastNavigation
|
|
246
|
+
: (_a = this.currentNavigation) !== null && _a !== void 0 ? _a : this.lastNavigation;
|
|
245
247
|
if (!url && !prevNavigation) {
|
|
246
248
|
throw new Error('Navigate url should be specified and cannot be omitted for first navigation');
|
|
247
249
|
}
|
|
248
250
|
const resolvedUrl = this.resolveUrl(navigateOptions);
|
|
249
251
|
const { to: from, url: fromUrl } = prevNavigation !== null && prevNavigation !== void 0 ? prevNavigation : {};
|
|
252
|
+
const redirectFrom = redirect ? this.currentNavigation.to : undefined;
|
|
250
253
|
let navigation = {
|
|
251
254
|
type: 'navigate',
|
|
252
255
|
from,
|
|
@@ -256,6 +259,8 @@ class AbstractRouter {
|
|
|
256
259
|
history,
|
|
257
260
|
navigateState,
|
|
258
261
|
code,
|
|
262
|
+
redirect,
|
|
263
|
+
redirectFrom,
|
|
259
264
|
};
|
|
260
265
|
await this.runHooks('beforeResolve', navigation);
|
|
261
266
|
const to = this.resolveRoute({ url: resolvedUrl, params, navigateState }, { wildcard: true });
|
|
@@ -381,7 +386,9 @@ class AbstractRouter {
|
|
|
381
386
|
pathname = makePath(currentRoute.path, { ...currentRoute.params, ...params });
|
|
382
387
|
}
|
|
383
388
|
}
|
|
384
|
-
|
|
389
|
+
if (isSameHost(resultUrl)) {
|
|
390
|
+
pathname = this.normalizePathname(pathname);
|
|
391
|
+
}
|
|
385
392
|
return url.convertRawUrl(url.rawAssignUrl(resultUrl, {
|
|
386
393
|
pathname,
|
|
387
394
|
search: url$1 ? resultUrl.search : '',
|
|
@@ -801,7 +808,7 @@ const wrapHistory = ({ onNavigate }) => {
|
|
|
801
808
|
const history = (delta) => {
|
|
802
809
|
go(delta);
|
|
803
810
|
};
|
|
804
|
-
const browserNavigate = (replace) => {
|
|
811
|
+
const browserNavigate = (replace = false) => {
|
|
805
812
|
return (navigateState, title, url) => {
|
|
806
813
|
onNavigate({ url, replace, navigateState });
|
|
807
814
|
};
|
|
@@ -1015,8 +1022,11 @@ class ClientRouter extends AbstractRouter {
|
|
|
1015
1022
|
// in case we didn't find any matched route just force hard page navigation
|
|
1016
1023
|
const prevUrl = (_b = (_a = navigation.fromUrl) === null || _a === void 0 ? void 0 : _a.href) !== null && _b !== void 0 ? _b : window.location.href;
|
|
1017
1024
|
const nextUrl = navigation.url.href;
|
|
1018
|
-
|
|
1019
|
-
|
|
1025
|
+
const isNoSpaNavigation = navigation.from && !navigation.to;
|
|
1026
|
+
// prevent redirect cycle on the same page,
|
|
1027
|
+
// except cases when we run no-spa navigations,
|
|
1028
|
+
// because we need hard reload in this cases
|
|
1029
|
+
if (isNoSpaNavigation ? true : prevUrl !== nextUrl) {
|
|
1020
1030
|
if (navigation.replace) {
|
|
1021
1031
|
window.location.replace(nextUrl);
|
|
1022
1032
|
}
|
|
@@ -1032,7 +1042,12 @@ class ClientRouter extends AbstractRouter {
|
|
|
1032
1042
|
}
|
|
1033
1043
|
async redirect(navigation, target) {
|
|
1034
1044
|
await super.redirect(navigation, target);
|
|
1035
|
-
return this.
|
|
1045
|
+
return this.internalNavigate({
|
|
1046
|
+
...target,
|
|
1047
|
+
replace: target.replace || navigation.replace,
|
|
1048
|
+
}, {
|
|
1049
|
+
redirect: true,
|
|
1050
|
+
});
|
|
1036
1051
|
}
|
|
1037
1052
|
}
|
|
1038
1053
|
|
package/lib/router/abstract.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export interface Options {
|
|
|
20
20
|
}
|
|
21
21
|
interface InternalOptions {
|
|
22
22
|
history?: boolean;
|
|
23
|
+
redirect?: boolean;
|
|
23
24
|
}
|
|
24
25
|
export declare abstract class AbstractRouter {
|
|
25
26
|
protected started: boolean;
|
|
@@ -45,7 +46,7 @@ export declare abstract class AbstractRouter {
|
|
|
45
46
|
protected internalUpdateCurrentRoute(updateRouteOptions: UpdateCurrentRouteOptions, { history }: InternalOptions): Promise<void>;
|
|
46
47
|
protected runUpdateCurrentRoute(navigation: Navigation): Promise<void>;
|
|
47
48
|
navigate(navigateOptions: NavigateOptions | string): Promise<void>;
|
|
48
|
-
protected internalNavigate(navigateOptions: NavigateOptions, { history }: InternalOptions): Promise<void>;
|
|
49
|
+
protected internalNavigate(navigateOptions: NavigateOptions, { history, redirect }: InternalOptions): Promise<void>;
|
|
49
50
|
protected runNavigate(navigation: Navigation): Promise<void>;
|
|
50
51
|
protected run(navigation: Navigation): Promise<void>;
|
|
51
52
|
resolve(resolveOptions: NavigateOptions | string, options?: Parameters<AbstractRouter['resolveRoute']>[1]): import("../types").NavigationRoute;
|
package/lib/types.d.ts
CHANGED
|
@@ -40,6 +40,8 @@ export interface Navigation {
|
|
|
40
40
|
history?: boolean;
|
|
41
41
|
cancelled?: boolean;
|
|
42
42
|
code?: number;
|
|
43
|
+
redirect?: boolean;
|
|
44
|
+
redirectFrom?: NavigationRoute;
|
|
43
45
|
}
|
|
44
46
|
export declare type NavigationGuard = (navigation: Navigation) => Promise<void | NavigateOptions | string | boolean>;
|
|
45
47
|
export declare type NavigationHook = (navigation: Navigation) => Promise<void>;
|
package/lib/utils.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ import type { NavigateOptions, NavigationHook, NavigationSyncHook, NavigationGua
|
|
|
3
3
|
export declare const isFilePath: (pathname: string) => boolean;
|
|
4
4
|
export declare const normalizeTrailingSlash: (pathname: string, trailingSlash?: boolean) => string;
|
|
5
5
|
export declare const normalizeManySlashes: (hrefOrPath: string) => string;
|
|
6
|
-
export declare const isSameHost: import("@tinkoff/utils/typings/types").Func<true> | ((url: Url) => boolean);
|
|
6
|
+
export declare const isSameHost: import("@tinkoff/utils/typings/types").Func<true> | ((url: Url | URL) => boolean);
|
|
7
7
|
export declare const makeNavigateOptions: (options: string | NavigateOptions) => NavigateOptions;
|
|
8
8
|
export declare const registerHook: <T extends NavigationHook | NavigationSyncHook | NavigationGuard>(hooksSet: Set<T>, hook: T) => () => void;
|