@ktjs/router 0.13.0 → 0.14.0
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/dist/index.d.ts +9 -4
- package/dist/index.iife.js +63 -16
- package/dist/index.legacy.js +118 -51
- package/dist/index.mjs +63 -16
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -31,8 +31,10 @@ interface RawRouteConfig {
|
|
|
31
31
|
name?: string;
|
|
32
32
|
/** Optional metadata attached to the route */
|
|
33
33
|
meta?: Record<string, any>;
|
|
34
|
-
/** Route-level guard executed before entering this route */
|
|
35
|
-
beforeEnter?: (
|
|
34
|
+
/** Route-level guard executed before entering this route. Return false to block, string/object to redirect */
|
|
35
|
+
beforeEnter?: (
|
|
36
|
+
context: RouteContext
|
|
37
|
+
) => string | NavBaseOptions | boolean | void | Promise<string | NavBaseOptions | boolean | void>;
|
|
36
38
|
/** Route-level hook executed after navigation */
|
|
37
39
|
after?: (context: RouteContext) => void | Promise<void>;
|
|
38
40
|
/** Nested child routes */
|
|
@@ -96,8 +98,11 @@ interface RouterConfig {
|
|
|
96
98
|
/** Array of route definitions */
|
|
97
99
|
routes: RawRouteConfig[];
|
|
98
100
|
|
|
99
|
-
/** Global guard executed before each navigation (except silentPush) */
|
|
100
|
-
beforeEach?: (
|
|
101
|
+
/** Global guard executed before each navigation (except silentPush). Return false to block, string/object to redirect */
|
|
102
|
+
beforeEach?: (
|
|
103
|
+
to: RouteContext,
|
|
104
|
+
from: RouteContext | null
|
|
105
|
+
) => string | NavBaseOptions | boolean | void | Promise<string | NavBaseOptions | boolean | void>;
|
|
101
106
|
|
|
102
107
|
/** Global hook executed after each navigation */
|
|
103
108
|
afterEach?: (to: RouteContext, from: RouteContext | null) => void | Promise<void>;
|
package/dist/index.iife.js
CHANGED
|
@@ -189,49 +189,75 @@ var __ktjs_router__ = (function (exports) {
|
|
|
189
189
|
const executeGuardsSync = (to, from, guardLevel) => {
|
|
190
190
|
try {
|
|
191
191
|
if (guardLevel === 0 /* GuardLevel.None */) {
|
|
192
|
-
return true;
|
|
192
|
+
return { continue: true };
|
|
193
193
|
}
|
|
194
194
|
if (guardLevel & 1 /* GuardLevel.Global */) {
|
|
195
195
|
const result = beforeEach(to, from);
|
|
196
196
|
if (result === false) {
|
|
197
|
-
return false;
|
|
197
|
+
return { continue: false };
|
|
198
|
+
}
|
|
199
|
+
if (typeof result === 'string') {
|
|
200
|
+
return { continue: false, redirectTo: { path: result } };
|
|
201
|
+
}
|
|
202
|
+
if (result && typeof result === 'object' && !('then' in result)) {
|
|
203
|
+
return { continue: false, redirectTo: result };
|
|
198
204
|
}
|
|
199
205
|
}
|
|
200
206
|
if (guardLevel & 2 /* GuardLevel.Route */) {
|
|
201
207
|
const targetRoute = to.matched[to.matched.length - 1];
|
|
202
208
|
const result = targetRoute.beforeEnter(to);
|
|
203
209
|
if (result === false) {
|
|
204
|
-
return false;
|
|
210
|
+
return { continue: false };
|
|
211
|
+
}
|
|
212
|
+
if (typeof result === 'string') {
|
|
213
|
+
return { continue: false, redirectTo: { path: result } };
|
|
214
|
+
}
|
|
215
|
+
if (result && typeof result === 'object' && !('then' in result)) {
|
|
216
|
+
return { continue: false, redirectTo: result };
|
|
205
217
|
}
|
|
206
218
|
}
|
|
207
|
-
return true;
|
|
219
|
+
return { continue: true };
|
|
208
220
|
}
|
|
209
221
|
catch (error) {
|
|
210
222
|
onError(error);
|
|
211
|
-
return false;
|
|
223
|
+
return { continue: false };
|
|
212
224
|
}
|
|
213
225
|
};
|
|
214
226
|
const executeGuards = async (to, from, guardLevel) => {
|
|
215
227
|
try {
|
|
216
228
|
if (guardLevel === 0 /* GuardLevel.None */) {
|
|
217
|
-
return true;
|
|
229
|
+
return { continue: true };
|
|
218
230
|
}
|
|
219
231
|
if (guardLevel & 1 /* GuardLevel.Global */) {
|
|
220
232
|
const result = await beforeEach(to, from);
|
|
221
233
|
if (result === false) {
|
|
222
|
-
return false;
|
|
234
|
+
return { continue: false };
|
|
235
|
+
}
|
|
236
|
+
if (typeof result === 'string') {
|
|
237
|
+
return { continue: false, redirectTo: { path: result } };
|
|
238
|
+
}
|
|
239
|
+
if (result && typeof result === 'object') {
|
|
240
|
+
return { continue: false, redirectTo: result };
|
|
223
241
|
}
|
|
224
242
|
}
|
|
225
243
|
if (guardLevel & 2 /* GuardLevel.Route */) {
|
|
226
244
|
const targetRoute = to.matched[to.matched.length - 1];
|
|
227
|
-
const result = targetRoute.beforeEnter(to);
|
|
228
|
-
|
|
245
|
+
const result = await targetRoute.beforeEnter(to);
|
|
246
|
+
if (result === false) {
|
|
247
|
+
return { continue: false };
|
|
248
|
+
}
|
|
249
|
+
if (typeof result === 'string') {
|
|
250
|
+
return { continue: false, redirectTo: { path: result } };
|
|
251
|
+
}
|
|
252
|
+
if (result && typeof result === 'object') {
|
|
253
|
+
return { continue: false, redirectTo: result };
|
|
254
|
+
}
|
|
229
255
|
}
|
|
230
|
-
return true;
|
|
256
|
+
return { continue: true };
|
|
231
257
|
}
|
|
232
258
|
catch (error) {
|
|
233
259
|
onError(error);
|
|
234
|
-
return false;
|
|
260
|
+
return { continue: false };
|
|
235
261
|
}
|
|
236
262
|
};
|
|
237
263
|
const navigatePrepare = (options) => {
|
|
@@ -280,15 +306,25 @@ var __ktjs_router__ = (function (exports) {
|
|
|
280
306
|
fullPath,
|
|
281
307
|
};
|
|
282
308
|
};
|
|
283
|
-
const navigateSync = (options) => {
|
|
309
|
+
const navigateSync = (options, redirectCount = 0) => {
|
|
284
310
|
try {
|
|
311
|
+
// Prevent infinite redirect loop
|
|
312
|
+
if (redirectCount > 10) {
|
|
313
|
+
onError(new Error('Maximum redirect count exceeded'));
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
285
316
|
const prep = navigatePrepare(options);
|
|
286
317
|
if (!prep) {
|
|
287
318
|
return false;
|
|
288
319
|
}
|
|
289
320
|
const { guardLevel, replace, to, fullPath } = prep;
|
|
290
321
|
// Execute guards
|
|
291
|
-
|
|
322
|
+
const guardResult = executeGuardsSync(to, current, guardLevel);
|
|
323
|
+
if (!guardResult.continue) {
|
|
324
|
+
// Check if there's a redirect
|
|
325
|
+
if (guardResult.redirectTo) {
|
|
326
|
+
return navigateSync(guardResult.redirectTo, redirectCount + 1);
|
|
327
|
+
}
|
|
292
328
|
return false;
|
|
293
329
|
}
|
|
294
330
|
// Update browser history
|
|
@@ -311,15 +347,24 @@ var __ktjs_router__ = (function (exports) {
|
|
|
311
347
|
return false;
|
|
312
348
|
}
|
|
313
349
|
};
|
|
314
|
-
const navigateAsync = async (options) => {
|
|
350
|
+
const navigateAsync = async (options, redirectCount = 0) => {
|
|
315
351
|
try {
|
|
352
|
+
// Prevent infinite redirect loop
|
|
353
|
+
if (redirectCount > 10) {
|
|
354
|
+
onError(new Error('Maximum redirect count exceeded'));
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
316
357
|
const prep = navigatePrepare(options);
|
|
317
358
|
if (!prep) {
|
|
318
359
|
return false;
|
|
319
360
|
}
|
|
320
361
|
const { guardLevel, replace, to, fullPath } = prep;
|
|
321
|
-
const
|
|
322
|
-
if (!
|
|
362
|
+
const guardResult = await executeGuards(to, current, guardLevel);
|
|
363
|
+
if (!guardResult.continue) {
|
|
364
|
+
// Check if there's a redirect
|
|
365
|
+
if (guardResult.redirectTo) {
|
|
366
|
+
return navigateAsync(guardResult.redirectTo, redirectCount + 1);
|
|
367
|
+
}
|
|
323
368
|
return false;
|
|
324
369
|
}
|
|
325
370
|
// ---- Guards passed ----
|
|
@@ -330,6 +375,8 @@ var __ktjs_router__ = (function (exports) {
|
|
|
330
375
|
else {
|
|
331
376
|
window.history.pushState({ path: to.path }, '', url);
|
|
332
377
|
}
|
|
378
|
+
current = to;
|
|
379
|
+
history.push(to);
|
|
333
380
|
executeAfterHooks(to, history[history.length - 2] ?? null);
|
|
334
381
|
return true;
|
|
335
382
|
}
|
package/dist/index.legacy.js
CHANGED
|
@@ -67,6 +67,16 @@ var __ktjs_router__ = (function (exports) {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
function __spreadArray(to, from, pack) {
|
|
71
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
72
|
+
if (ar || !(i in from)) {
|
|
73
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
74
|
+
ar[i] = from[i];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
71
81
|
var e = new Error(message);
|
|
72
82
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
@@ -272,26 +282,38 @@ var __ktjs_router__ = (function (exports) {
|
|
|
272
282
|
var executeGuardsSync = function (to, from, guardLevel) {
|
|
273
283
|
try {
|
|
274
284
|
if (guardLevel === 0 /* GuardLevel.None */) {
|
|
275
|
-
return true;
|
|
285
|
+
return { continue: true };
|
|
276
286
|
}
|
|
277
287
|
if (guardLevel & 1 /* GuardLevel.Global */) {
|
|
278
288
|
var result = beforeEach(to, from);
|
|
279
289
|
if (result === false) {
|
|
280
|
-
return false;
|
|
290
|
+
return { continue: false };
|
|
291
|
+
}
|
|
292
|
+
if (typeof result === 'string') {
|
|
293
|
+
return { continue: false, redirectTo: { path: result } };
|
|
294
|
+
}
|
|
295
|
+
if (result && typeof result === 'object' && !('then' in result)) {
|
|
296
|
+
return { continue: false, redirectTo: result };
|
|
281
297
|
}
|
|
282
298
|
}
|
|
283
299
|
if (guardLevel & 2 /* GuardLevel.Route */) {
|
|
284
300
|
var targetRoute = to.matched[to.matched.length - 1];
|
|
285
301
|
var result = targetRoute.beforeEnter(to);
|
|
286
302
|
if (result === false) {
|
|
287
|
-
return false;
|
|
303
|
+
return { continue: false };
|
|
304
|
+
}
|
|
305
|
+
if (typeof result === 'string') {
|
|
306
|
+
return { continue: false, redirectTo: { path: result } };
|
|
307
|
+
}
|
|
308
|
+
if (result && typeof result === 'object' && !('then' in result)) {
|
|
309
|
+
return { continue: false, redirectTo: result };
|
|
288
310
|
}
|
|
289
311
|
}
|
|
290
|
-
return true;
|
|
312
|
+
return { continue: true };
|
|
291
313
|
}
|
|
292
314
|
catch (error) {
|
|
293
315
|
onError(error);
|
|
294
|
-
return false;
|
|
316
|
+
return { continue: false };
|
|
295
317
|
}
|
|
296
318
|
};
|
|
297
319
|
var executeGuards = function (to, from, guardLevel) { return __awaiter(void 0, void 0, void 0, function () {
|
|
@@ -299,30 +321,46 @@ var __ktjs_router__ = (function (exports) {
|
|
|
299
321
|
return __generator(this, function (_a) {
|
|
300
322
|
switch (_a.label) {
|
|
301
323
|
case 0:
|
|
302
|
-
_a.trys.push([0,
|
|
324
|
+
_a.trys.push([0, 5, , 6]);
|
|
303
325
|
if (guardLevel === 0 /* GuardLevel.None */) {
|
|
304
|
-
return [2 /*return*/, true];
|
|
326
|
+
return [2 /*return*/, { continue: true }];
|
|
305
327
|
}
|
|
306
328
|
if (!(guardLevel & 1 /* GuardLevel.Global */)) return [3 /*break*/, 2];
|
|
307
329
|
return [4 /*yield*/, beforeEach(to, from)];
|
|
308
330
|
case 1:
|
|
309
331
|
result = _a.sent();
|
|
310
332
|
if (result === false) {
|
|
311
|
-
return [2 /*return*/, false];
|
|
333
|
+
return [2 /*return*/, { continue: false }];
|
|
334
|
+
}
|
|
335
|
+
if (typeof result === 'string') {
|
|
336
|
+
return [2 /*return*/, { continue: false, redirectTo: { path: result } }];
|
|
337
|
+
}
|
|
338
|
+
if (result && typeof result === 'object') {
|
|
339
|
+
return [2 /*return*/, { continue: false, redirectTo: result }];
|
|
312
340
|
}
|
|
313
341
|
_a.label = 2;
|
|
314
342
|
case 2:
|
|
315
|
-
if (guardLevel & 2 /* GuardLevel.Route */)
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
return [2 /*return*/, result !== false];
|
|
319
|
-
}
|
|
320
|
-
return [2 /*return*/, true];
|
|
343
|
+
if (!(guardLevel & 2 /* GuardLevel.Route */)) return [3 /*break*/, 4];
|
|
344
|
+
targetRoute = to.matched[to.matched.length - 1];
|
|
345
|
+
return [4 /*yield*/, targetRoute.beforeEnter(to)];
|
|
321
346
|
case 3:
|
|
347
|
+
result = _a.sent();
|
|
348
|
+
if (result === false) {
|
|
349
|
+
return [2 /*return*/, { continue: false }];
|
|
350
|
+
}
|
|
351
|
+
if (typeof result === 'string') {
|
|
352
|
+
return [2 /*return*/, { continue: false, redirectTo: { path: result } }];
|
|
353
|
+
}
|
|
354
|
+
if (result && typeof result === 'object') {
|
|
355
|
+
return [2 /*return*/, { continue: false, redirectTo: result }];
|
|
356
|
+
}
|
|
357
|
+
_a.label = 4;
|
|
358
|
+
case 4: return [2 /*return*/, { continue: true }];
|
|
359
|
+
case 5:
|
|
322
360
|
error_1 = _a.sent();
|
|
323
361
|
onError(error_1);
|
|
324
|
-
return [2 /*return*/, false];
|
|
325
|
-
case
|
|
362
|
+
return [2 /*return*/, { continue: false }];
|
|
363
|
+
case 6: return [2 /*return*/];
|
|
326
364
|
}
|
|
327
365
|
});
|
|
328
366
|
}); };
|
|
@@ -373,16 +411,27 @@ var __ktjs_router__ = (function (exports) {
|
|
|
373
411
|
fullPath: fullPath,
|
|
374
412
|
};
|
|
375
413
|
};
|
|
376
|
-
var navigateSync = function (options) {
|
|
414
|
+
var navigateSync = function (options, redirectCount) {
|
|
377
415
|
var _a;
|
|
416
|
+
if (redirectCount === void 0) { redirectCount = 0; }
|
|
378
417
|
try {
|
|
418
|
+
// Prevent infinite redirect loop
|
|
419
|
+
if (redirectCount > 10) {
|
|
420
|
+
onError(new Error('Maximum redirect count exceeded'));
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
379
423
|
var prep = navigatePrepare(options);
|
|
380
424
|
if (!prep) {
|
|
381
425
|
return false;
|
|
382
426
|
}
|
|
383
427
|
var guardLevel = prep.guardLevel, replace = prep.replace, to = prep.to, fullPath = prep.fullPath;
|
|
384
428
|
// Execute guards
|
|
385
|
-
|
|
429
|
+
var guardResult = executeGuardsSync(to, current, guardLevel);
|
|
430
|
+
if (!guardResult.continue) {
|
|
431
|
+
// Check if there's a redirect
|
|
432
|
+
if (guardResult.redirectTo) {
|
|
433
|
+
return navigateSync(guardResult.redirectTo, redirectCount + 1);
|
|
434
|
+
}
|
|
386
435
|
return false;
|
|
387
436
|
}
|
|
388
437
|
// Update browser history
|
|
@@ -405,41 +454,59 @@ var __ktjs_router__ = (function (exports) {
|
|
|
405
454
|
return false;
|
|
406
455
|
}
|
|
407
456
|
};
|
|
408
|
-
var navigateAsync = function (
|
|
409
|
-
var
|
|
410
|
-
var
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
457
|
+
var navigateAsync = function (options_1) {
|
|
458
|
+
var args_1 = [];
|
|
459
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
460
|
+
args_1[_i - 1] = arguments[_i];
|
|
461
|
+
}
|
|
462
|
+
return __awaiter(void 0, __spreadArray([options_1], args_1, true), void 0, function (options, redirectCount) {
|
|
463
|
+
var prep, guardLevel, replace, to, fullPath, guardResult, url, error_2;
|
|
464
|
+
var _a;
|
|
465
|
+
if (redirectCount === void 0) { redirectCount = 0; }
|
|
466
|
+
return __generator(this, function (_b) {
|
|
467
|
+
switch (_b.label) {
|
|
468
|
+
case 0:
|
|
469
|
+
_b.trys.push([0, 2, , 3]);
|
|
470
|
+
// Prevent infinite redirect loop
|
|
471
|
+
if (redirectCount > 10) {
|
|
472
|
+
onError(new Error('Maximum redirect count exceeded'));
|
|
473
|
+
return [2 /*return*/, false];
|
|
474
|
+
}
|
|
475
|
+
prep = navigatePrepare(options);
|
|
476
|
+
if (!prep) {
|
|
477
|
+
return [2 /*return*/, false];
|
|
478
|
+
}
|
|
479
|
+
guardLevel = prep.guardLevel, replace = prep.replace, to = prep.to, fullPath = prep.fullPath;
|
|
480
|
+
return [4 /*yield*/, executeGuards(to, current, guardLevel)];
|
|
481
|
+
case 1:
|
|
482
|
+
guardResult = _b.sent();
|
|
483
|
+
if (!guardResult.continue) {
|
|
484
|
+
// Check if there's a redirect
|
|
485
|
+
if (guardResult.redirectTo) {
|
|
486
|
+
return [2 /*return*/, navigateAsync(guardResult.redirectTo, redirectCount + 1)];
|
|
487
|
+
}
|
|
488
|
+
return [2 /*return*/, false];
|
|
489
|
+
}
|
|
490
|
+
url = fullPath;
|
|
491
|
+
if (replace) {
|
|
492
|
+
window.history.replaceState({ path: to.path }, '', url);
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
window.history.pushState({ path: to.path }, '', url);
|
|
496
|
+
}
|
|
497
|
+
current = to;
|
|
498
|
+
history.push(to);
|
|
499
|
+
executeAfterHooks(to, (_a = history[history.length - 2]) !== null && _a !== void 0 ? _a : null);
|
|
500
|
+
return [2 /*return*/, true];
|
|
501
|
+
case 2:
|
|
502
|
+
error_2 = _b.sent();
|
|
503
|
+
onError(error_2);
|
|
424
504
|
return [2 /*return*/, false];
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
window.history.replaceState({ path: to.path }, '', url);
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
window.history.pushState({ path: to.path }, '', url);
|
|
432
|
-
}
|
|
433
|
-
executeAfterHooks(to, (_a = history[history.length - 2]) !== null && _a !== void 0 ? _a : null);
|
|
434
|
-
return [2 /*return*/, true];
|
|
435
|
-
case 2:
|
|
436
|
-
error_2 = _b.sent();
|
|
437
|
-
onError(error_2);
|
|
438
|
-
return [2 /*return*/, false];
|
|
439
|
-
case 3: return [2 /*return*/];
|
|
440
|
-
}
|
|
505
|
+
case 3: return [2 /*return*/];
|
|
506
|
+
}
|
|
507
|
+
});
|
|
441
508
|
});
|
|
442
|
-
}
|
|
509
|
+
};
|
|
443
510
|
var navigate = asyncGuards ? navigateSync : navigateAsync;
|
|
444
511
|
var executeAfterHooksSync = function (to, from) {
|
|
445
512
|
var targetRoute = to.matched[to.matched.length - 1];
|
package/dist/index.mjs
CHANGED
|
@@ -186,49 +186,75 @@ const createRouter = (config) => {
|
|
|
186
186
|
const executeGuardsSync = (to, from, guardLevel) => {
|
|
187
187
|
try {
|
|
188
188
|
if (guardLevel === 0 /* GuardLevel.None */) {
|
|
189
|
-
return true;
|
|
189
|
+
return { continue: true };
|
|
190
190
|
}
|
|
191
191
|
if (guardLevel & 1 /* GuardLevel.Global */) {
|
|
192
192
|
const result = beforeEach(to, from);
|
|
193
193
|
if (result === false) {
|
|
194
|
-
return false;
|
|
194
|
+
return { continue: false };
|
|
195
|
+
}
|
|
196
|
+
if (typeof result === 'string') {
|
|
197
|
+
return { continue: false, redirectTo: { path: result } };
|
|
198
|
+
}
|
|
199
|
+
if (result && typeof result === 'object' && !('then' in result)) {
|
|
200
|
+
return { continue: false, redirectTo: result };
|
|
195
201
|
}
|
|
196
202
|
}
|
|
197
203
|
if (guardLevel & 2 /* GuardLevel.Route */) {
|
|
198
204
|
const targetRoute = to.matched[to.matched.length - 1];
|
|
199
205
|
const result = targetRoute.beforeEnter(to);
|
|
200
206
|
if (result === false) {
|
|
201
|
-
return false;
|
|
207
|
+
return { continue: false };
|
|
208
|
+
}
|
|
209
|
+
if (typeof result === 'string') {
|
|
210
|
+
return { continue: false, redirectTo: { path: result } };
|
|
211
|
+
}
|
|
212
|
+
if (result && typeof result === 'object' && !('then' in result)) {
|
|
213
|
+
return { continue: false, redirectTo: result };
|
|
202
214
|
}
|
|
203
215
|
}
|
|
204
|
-
return true;
|
|
216
|
+
return { continue: true };
|
|
205
217
|
}
|
|
206
218
|
catch (error) {
|
|
207
219
|
onError(error);
|
|
208
|
-
return false;
|
|
220
|
+
return { continue: false };
|
|
209
221
|
}
|
|
210
222
|
};
|
|
211
223
|
const executeGuards = async (to, from, guardLevel) => {
|
|
212
224
|
try {
|
|
213
225
|
if (guardLevel === 0 /* GuardLevel.None */) {
|
|
214
|
-
return true;
|
|
226
|
+
return { continue: true };
|
|
215
227
|
}
|
|
216
228
|
if (guardLevel & 1 /* GuardLevel.Global */) {
|
|
217
229
|
const result = await beforeEach(to, from);
|
|
218
230
|
if (result === false) {
|
|
219
|
-
return false;
|
|
231
|
+
return { continue: false };
|
|
232
|
+
}
|
|
233
|
+
if (typeof result === 'string') {
|
|
234
|
+
return { continue: false, redirectTo: { path: result } };
|
|
235
|
+
}
|
|
236
|
+
if (result && typeof result === 'object') {
|
|
237
|
+
return { continue: false, redirectTo: result };
|
|
220
238
|
}
|
|
221
239
|
}
|
|
222
240
|
if (guardLevel & 2 /* GuardLevel.Route */) {
|
|
223
241
|
const targetRoute = to.matched[to.matched.length - 1];
|
|
224
|
-
const result = targetRoute.beforeEnter(to);
|
|
225
|
-
|
|
242
|
+
const result = await targetRoute.beforeEnter(to);
|
|
243
|
+
if (result === false) {
|
|
244
|
+
return { continue: false };
|
|
245
|
+
}
|
|
246
|
+
if (typeof result === 'string') {
|
|
247
|
+
return { continue: false, redirectTo: { path: result } };
|
|
248
|
+
}
|
|
249
|
+
if (result && typeof result === 'object') {
|
|
250
|
+
return { continue: false, redirectTo: result };
|
|
251
|
+
}
|
|
226
252
|
}
|
|
227
|
-
return true;
|
|
253
|
+
return { continue: true };
|
|
228
254
|
}
|
|
229
255
|
catch (error) {
|
|
230
256
|
onError(error);
|
|
231
|
-
return false;
|
|
257
|
+
return { continue: false };
|
|
232
258
|
}
|
|
233
259
|
};
|
|
234
260
|
const navigatePrepare = (options) => {
|
|
@@ -277,15 +303,25 @@ const createRouter = (config) => {
|
|
|
277
303
|
fullPath,
|
|
278
304
|
};
|
|
279
305
|
};
|
|
280
|
-
const navigateSync = (options) => {
|
|
306
|
+
const navigateSync = (options, redirectCount = 0) => {
|
|
281
307
|
try {
|
|
308
|
+
// Prevent infinite redirect loop
|
|
309
|
+
if (redirectCount > 10) {
|
|
310
|
+
onError(new Error('Maximum redirect count exceeded'));
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
282
313
|
const prep = navigatePrepare(options);
|
|
283
314
|
if (!prep) {
|
|
284
315
|
return false;
|
|
285
316
|
}
|
|
286
317
|
const { guardLevel, replace, to, fullPath } = prep;
|
|
287
318
|
// Execute guards
|
|
288
|
-
|
|
319
|
+
const guardResult = executeGuardsSync(to, current, guardLevel);
|
|
320
|
+
if (!guardResult.continue) {
|
|
321
|
+
// Check if there's a redirect
|
|
322
|
+
if (guardResult.redirectTo) {
|
|
323
|
+
return navigateSync(guardResult.redirectTo, redirectCount + 1);
|
|
324
|
+
}
|
|
289
325
|
return false;
|
|
290
326
|
}
|
|
291
327
|
// Update browser history
|
|
@@ -308,15 +344,24 @@ const createRouter = (config) => {
|
|
|
308
344
|
return false;
|
|
309
345
|
}
|
|
310
346
|
};
|
|
311
|
-
const navigateAsync = async (options) => {
|
|
347
|
+
const navigateAsync = async (options, redirectCount = 0) => {
|
|
312
348
|
try {
|
|
349
|
+
// Prevent infinite redirect loop
|
|
350
|
+
if (redirectCount > 10) {
|
|
351
|
+
onError(new Error('Maximum redirect count exceeded'));
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
313
354
|
const prep = navigatePrepare(options);
|
|
314
355
|
if (!prep) {
|
|
315
356
|
return false;
|
|
316
357
|
}
|
|
317
358
|
const { guardLevel, replace, to, fullPath } = prep;
|
|
318
|
-
const
|
|
319
|
-
if (!
|
|
359
|
+
const guardResult = await executeGuards(to, current, guardLevel);
|
|
360
|
+
if (!guardResult.continue) {
|
|
361
|
+
// Check if there's a redirect
|
|
362
|
+
if (guardResult.redirectTo) {
|
|
363
|
+
return navigateAsync(guardResult.redirectTo, redirectCount + 1);
|
|
364
|
+
}
|
|
320
365
|
return false;
|
|
321
366
|
}
|
|
322
367
|
// ---- Guards passed ----
|
|
@@ -327,6 +372,8 @@ const createRouter = (config) => {
|
|
|
327
372
|
else {
|
|
328
373
|
window.history.pushState({ path: to.path }, '', url);
|
|
329
374
|
}
|
|
375
|
+
current = to;
|
|
376
|
+
history.push(to);
|
|
330
377
|
executeAfterHooks(to, history[history.length - 2] ?? null);
|
|
331
378
|
return true;
|
|
332
379
|
}
|