@remix-run/router 1.0.1 → 1.0.2
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/CHANGELOG.md +8 -0
- package/dist/index.d.ts +1 -1
- package/dist/router.cjs.js +81 -26
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.js +81 -26
- package/dist/router.js.map +1 -1
- package/dist/utils.d.ts +29 -9
- package/index.ts +4 -0
- package/package.json +1 -1
- package/router.ts +31 -9
- package/utils.ts +113 -27
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# `@remix-run/router`
|
|
2
2
|
|
|
3
|
+
## 1.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Reset `actionData` after a successful action redirect ([#9334](https://github.com/remix-run/react-router/pull/9334))
|
|
8
|
+
- Update `matchPath` to avoid false positives on dash-separated segments ([#9300](https://github.com/remix-run/react-router/pull/9300))
|
|
9
|
+
- If an index route has children, it will result in a runtime error. We have strengthened our `RouteObject`/`RouteProps` types to surface the error in TypeScript. ([#9366](https://github.com/remix-run/react-router/pull/9366))
|
|
10
|
+
|
|
3
11
|
## 1.0.1
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { convertRoutesToDataRoutes } from "./utils";
|
|
2
|
-
export type { ActionFunction, ActionFunctionArgs, AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticRouteMatch, AgnosticRouteObject, TrackedPromise, FormEncType, FormMethod, JsonFunction, LoaderFunction, LoaderFunctionArgs, ParamParseKey, Params, PathMatch, PathPattern, RedirectFunction, ShouldRevalidateFunction, Submission, } from "./utils";
|
|
2
|
+
export type { ActionFunction, ActionFunctionArgs, AgnosticDataIndexRouteObject, AgnosticDataNonIndexRouteObject, AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticIndexRouteObject, AgnosticNonIndexRouteObject, AgnosticRouteMatch, AgnosticRouteObject, TrackedPromise, FormEncType, FormMethod, JsonFunction, LoaderFunction, LoaderFunctionArgs, ParamParseKey, Params, PathMatch, PathPattern, RedirectFunction, ShouldRevalidateFunction, Submission, } from "./utils";
|
|
3
3
|
export { AbortedDeferredError, ErrorResponse, defer, generatePath, getToPathname, invariant, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, redirect, resolvePath, resolveTo, stripBasename, warning, } from "./utils";
|
|
4
4
|
export type { BrowserHistory, BrowserHistoryOptions, HashHistory, HashHistoryOptions, History, InitialEntry, Location, MemoryHistory, MemoryHistoryOptions, Path, To, } from "./history";
|
|
5
5
|
export { Action, createBrowserHistory, createPath, createHashHistory, createMemoryHistory, parsePath, } from "./history";
|
package/dist/router.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.0.
|
|
2
|
+
* @remix-run/router v1.0.2
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -487,8 +487,12 @@ let ResultType;
|
|
|
487
487
|
ResultType["error"] = "error";
|
|
488
488
|
})(ResultType || (ResultType = {}));
|
|
489
489
|
|
|
490
|
-
|
|
490
|
+
function isIndexRoute(route) {
|
|
491
|
+
return route.index === true;
|
|
492
|
+
} // Walk the route tree generating unique IDs where necessary so we are working
|
|
491
493
|
// solely with AgnosticDataRouteObject's within the Router
|
|
494
|
+
|
|
495
|
+
|
|
492
496
|
function convertRoutesToDataRoutes(routes, parentPath, allIds) {
|
|
493
497
|
if (parentPath === void 0) {
|
|
494
498
|
parentPath = [];
|
|
@@ -501,15 +505,24 @@ function convertRoutesToDataRoutes(routes, parentPath, allIds) {
|
|
|
501
505
|
return routes.map((route, index) => {
|
|
502
506
|
let treePath = [...parentPath, index];
|
|
503
507
|
let id = typeof route.id === "string" ? route.id : treePath.join("-");
|
|
508
|
+
invariant(route.index !== true || !route.children, "Cannot specify children on an index route");
|
|
504
509
|
invariant(!allIds.has(id), "Found a route id collision on id \"" + id + "\". Route " + "id's must be globally unique within Data Router usages");
|
|
505
510
|
allIds.add(id);
|
|
506
511
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
512
|
+
if (isIndexRoute(route)) {
|
|
513
|
+
let indexRoute = _extends({}, route, {
|
|
514
|
+
id
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
return indexRoute;
|
|
518
|
+
} else {
|
|
519
|
+
let pathOrLayoutRoute = _extends({}, route, {
|
|
520
|
+
id,
|
|
521
|
+
children: route.children ? convertRoutesToDataRoutes(route.children, treePath, allIds) : undefined
|
|
522
|
+
});
|
|
511
523
|
|
|
512
|
-
|
|
524
|
+
return pathOrLayoutRoute;
|
|
525
|
+
}
|
|
513
526
|
});
|
|
514
527
|
}
|
|
515
528
|
/**
|
|
@@ -573,7 +586,9 @@ function flattenRoutes(routes, branches, parentsMeta, parentPath) {
|
|
|
573
586
|
// the "flattened" version.
|
|
574
587
|
|
|
575
588
|
if (route.children && route.children.length > 0) {
|
|
576
|
-
invariant(
|
|
589
|
+
invariant( // Our types know better, but runtime JS may not!
|
|
590
|
+
// @ts-expect-error
|
|
591
|
+
route.index !== true, "Index routes must not have child routes. Please remove " + ("all child routes from route path \"" + path + "\"."));
|
|
577
592
|
flattenRoutes(route.children, branches, routesMeta, path);
|
|
578
593
|
} // Routes without a path shouldn't ever match by themselves unless they are
|
|
579
594
|
// index routes, so don't add them to the list of possible branches.
|
|
@@ -762,16 +777,19 @@ function compilePath(path, caseSensitive, end) {
|
|
|
762
777
|
paramNames.push("*");
|
|
763
778
|
regexpSource += path === "*" || path === "/*" ? "(.*)$" // Already matched the initial /, just match the rest
|
|
764
779
|
: "(?:\\/(.+)|\\/*)$"; // Don't include the / in params["*"]
|
|
765
|
-
} else {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
//
|
|
770
|
-
//
|
|
771
|
-
//
|
|
772
|
-
//
|
|
773
|
-
|
|
774
|
-
|
|
780
|
+
} else if (end) {
|
|
781
|
+
// When matching to the end, ignore trailing slashes
|
|
782
|
+
regexpSource += "\\/*$";
|
|
783
|
+
} else if (path !== "" && path !== "/") {
|
|
784
|
+
// If our path is non-empty and contains anything beyond an initial slash,
|
|
785
|
+
// then we have _some_ form of path in our regex so we should expect to
|
|
786
|
+
// match only if we find the end of this path segment. Look for an optional
|
|
787
|
+
// non-captured trailing slash (to match a portion of the URL) or the end
|
|
788
|
+
// of the path (if we've matched to the end). We used to do this with a
|
|
789
|
+
// word boundary but that gives false positives on routes like
|
|
790
|
+
// /user-preferences since `-` counts as a word boundary.
|
|
791
|
+
regexpSource += "(?:(?=\\/|$))";
|
|
792
|
+
} else ;
|
|
775
793
|
|
|
776
794
|
let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i");
|
|
777
795
|
return [matcher, paramNames];
|
|
@@ -874,6 +892,10 @@ function resolvePathname(relativePath, fromPathname) {
|
|
|
874
892
|
});
|
|
875
893
|
return segments.length > 1 ? segments.join("/") : "/";
|
|
876
894
|
}
|
|
895
|
+
|
|
896
|
+
function getInvalidPathError(char, field, dest, path) {
|
|
897
|
+
return "Cannot include a '" + char + "' character in a manually specified " + ("`to." + field + "` field [" + JSON.stringify(path) + "]. Please separate it out to the ") + ("`to." + dest + "` field. Alternatively you may provide the full path as ") + "a string in <Link to=\"...\"> and the router will parse it for you.";
|
|
898
|
+
}
|
|
877
899
|
/**
|
|
878
900
|
* @private
|
|
879
901
|
*/
|
|
@@ -884,7 +906,17 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
|
|
|
884
906
|
isPathRelative = false;
|
|
885
907
|
}
|
|
886
908
|
|
|
887
|
-
let to
|
|
909
|
+
let to;
|
|
910
|
+
|
|
911
|
+
if (typeof toArg === "string") {
|
|
912
|
+
to = parsePath(toArg);
|
|
913
|
+
} else {
|
|
914
|
+
to = _extends({}, toArg);
|
|
915
|
+
invariant(!to.pathname || !to.pathname.includes("?"), getInvalidPathError("?", "pathname", "search", to));
|
|
916
|
+
invariant(!to.pathname || !to.pathname.includes("#"), getInvalidPathError("#", "pathname", "hash", to));
|
|
917
|
+
invariant(!to.search || !to.search.includes("#"), getInvalidPathError("#", "search", "hash", to));
|
|
918
|
+
}
|
|
919
|
+
|
|
888
920
|
let isEmptyPath = toArg === "" || to.pathname === "";
|
|
889
921
|
let toPathname = isEmptyPath ? "/" : to.pathname;
|
|
890
922
|
let from; // Routing is relative to the current pathname if explicitly requested.
|
|
@@ -1347,15 +1379,17 @@ function createRouter(init) {
|
|
|
1347
1379
|
|
|
1348
1380
|
|
|
1349
1381
|
function completeNavigation(location, newState) {
|
|
1382
|
+
var _state$navigation$for;
|
|
1383
|
+
|
|
1350
1384
|
// Deduce if we're in a loading/actionReload state:
|
|
1351
1385
|
// - We have committed actionData in the store
|
|
1352
1386
|
// - The current navigation was a submission
|
|
1353
1387
|
// - We're past the submitting state and into the loading state
|
|
1354
|
-
// -
|
|
1355
|
-
//
|
|
1356
|
-
//
|
|
1357
|
-
//
|
|
1358
|
-
let isActionReload = state.actionData != null && state.navigation.formMethod != null && state.navigation.state === "loading"; // Always preserve any existing loaderData from re-used routes
|
|
1388
|
+
// - The location we've finished loading is different from the submission
|
|
1389
|
+
// location, indicating we redirected from the action (avoids false
|
|
1390
|
+
// positives for loading/submissionRedirect when actionData returned
|
|
1391
|
+
// on a prior submission)
|
|
1392
|
+
let isActionReload = state.actionData != null && state.navigation.formMethod != null && state.navigation.state === "loading" && ((_state$navigation$for = state.navigation.formAction) == null ? void 0 : _state$navigation$for.split("?")[0]) === location.pathname; // Always preserve any existing loaderData from re-used routes
|
|
1359
1393
|
|
|
1360
1394
|
let newLoaderData = newState.loaderData ? {
|
|
1361
1395
|
loaderData: mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [])
|
|
@@ -2314,10 +2348,31 @@ function unstable_createStaticHandler(routes) {
|
|
|
2314
2348
|
|
|
2315
2349
|
if (result instanceof Response) {
|
|
2316
2350
|
return result;
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
let error = result.errors ? Object.values(result.errors)[0] : undefined;
|
|
2354
|
+
|
|
2355
|
+
if (error !== undefined) {
|
|
2356
|
+
// While we always re-throw Responses returned from loaders/actions
|
|
2357
|
+
// directly for route requests and prevent the unwrapping into an
|
|
2358
|
+
// ErrorResponse, we still need this for error cases _prior_ the
|
|
2359
|
+
// execution of the loader/action, such as a 404/405 error.
|
|
2360
|
+
if (isRouteErrorResponse(error)) {
|
|
2361
|
+
return new Response(error.data, {
|
|
2362
|
+
status: error.status,
|
|
2363
|
+
statusText: error.statusText
|
|
2364
|
+
});
|
|
2365
|
+
} // If we got back result.errors, that means the loader/action threw
|
|
2366
|
+
// _something_ that wasn't a Response, but it's not guaranteed/required
|
|
2367
|
+
// to be an `instanceof Error` either, so we have to use throw here to
|
|
2368
|
+
// preserve the "error" state outside of queryImpl.
|
|
2369
|
+
|
|
2370
|
+
|
|
2371
|
+
throw error;
|
|
2317
2372
|
} // Pick off the right state value to return
|
|
2318
2373
|
|
|
2319
2374
|
|
|
2320
|
-
let routeData = [result.
|
|
2375
|
+
let routeData = [result.actionData, result.loaderData].find(v => v);
|
|
2321
2376
|
let value = Object.values(routeData || {})[0];
|
|
2322
2377
|
|
|
2323
2378
|
if (isRouteErrorResponse(value)) {
|
|
@@ -2923,7 +2978,7 @@ function processRouteLoaderData(matches, matchesToLoad, results, pendingError, a
|
|
|
2923
2978
|
loaderData[id] = result.data; // Error status codes always override success status codes, but if all
|
|
2924
2979
|
// loaders are successful we take the deepest status code.
|
|
2925
2980
|
|
|
2926
|
-
if (result.statusCode !== 200 && !foundError) {
|
|
2981
|
+
if (result.statusCode != null && result.statusCode !== 200 && !foundError) {
|
|
2927
2982
|
statusCode = result.statusCode;
|
|
2928
2983
|
}
|
|
2929
2984
|
|