@remix-run/router 1.0.4 → 1.0.5-pre.1

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # `@remix-run/router`
2
2
 
3
+ ## 1.0.5-pre.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Remove `instanceof Response` checks in favor of `isResponse` ([#9690](https://github.com/remix-run/react-router/pull/9690))
8
+ - Fix URL creation in Remix integration tests ([#9689](https://github.com/remix-run/react-router/pull/9689))
9
+
10
+ ## 1.0.5-pre.0
11
+
12
+ ### Patch Changes
13
+
14
+ - Fix URL creation in Cloudflare Pages or other non-browser-environment ([#9682](https://github.com/remix-run/react-router/pull/9682))
15
+ - Fix requests sent to revalidating loaders so they reflect a GET request ([#9680](https://github.com/remix-run/react-router/pull/9680))
16
+
3
17
  ## 1.0.4
4
18
 
5
19
  ### Patch Changes
@@ -46,7 +60,7 @@ For an overview of the features provided by `react-router`, we recommend you go
46
60
 
47
61
  For an overview of the features provided by `@remix-run/router`, please check out the [`README`][remix-router-readme].
48
62
 
49
- [rr-docs]: https://reactrouter.com/
50
- [rr-feature-overview]: https://reactrouter.com/en/6.4.0/start/overview
51
- [rr-tutorial]: https://reactrouter.com/en/6.4.0/start/tutorial
63
+ [rr-docs]: https://reactrouter.com
64
+ [rr-feature-overview]: https://reactrouter.com/start/overview
65
+ [rr-tutorial]: https://reactrouter.com/start/tutorial
52
66
  [remix-router-readme]: https://github.com/remix-run/react-router/blob/main/packages/router/README.md
package/dist/history.d.ts CHANGED
@@ -214,6 +214,11 @@ export declare type HashHistoryOptions = UrlHistoryOptions;
214
214
  * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory
215
215
  */
216
216
  export declare function createHashHistory(options?: HashHistoryOptions): HashHistory;
217
+ /**
218
+ * @private
219
+ */
220
+ export declare function invariant(value: boolean, message?: string): asserts value;
221
+ export declare function invariant<T>(value: T | null | undefined, message?: string): asserts value is T;
217
222
  /**
218
223
  * Creates a Location object with a unique key from the given Path
219
224
  */
@@ -226,7 +231,7 @@ export declare function createPath({ pathname, search, hash, }: Partial<Path>):
226
231
  * Parses a string URL path into its separate pathname, search, and hash components.
227
232
  */
228
233
  export declare function parsePath(path: string): Partial<Path>;
229
- export declare function createURL(location: Location | string): URL;
234
+ export declare function createClientSideURL(location: Location | string): URL;
230
235
  export interface UrlHistory extends History {
231
236
  }
232
237
  export declare type UrlHistoryOptions = {
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { convertRoutesToDataRoutes, getPathContributingMatches } from "./utils";
2
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
- export { AbortedDeferredError, ErrorResponse, defer, generatePath, getToPathname, invariant, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, redirect, resolvePath, resolveTo, stripBasename, warning, } from "./utils";
3
+ export { AbortedDeferredError, ErrorResponse, defer, generatePath, getToPathname, 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
- export { Action, createBrowserHistory, createPath, createHashHistory, createMemoryHistory, parsePath, } from "./history";
5
+ export { Action, createBrowserHistory, createPath, createHashHistory, createMemoryHistory, invariant, parsePath, } from "./history";
6
6
  export * from "./router";
7
7
  /** @internal */
8
8
  export { convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getPathContributingMatches as UNSAFE_getPathContributingMatches, };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @remix-run/router v1.0.4
2
+ * @remix-run/router v1.0.5-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -281,6 +281,16 @@ function createHashHistory(options) {
281
281
  //#region UTILS
282
282
  ////////////////////////////////////////////////////////////////////////////////
283
283
 
284
+ /**
285
+ * @private
286
+ */
287
+
288
+ function invariant(value, message) {
289
+ if (value === false || value === null || typeof value === "undefined") {
290
+ throw new Error(message);
291
+ }
292
+ }
293
+
284
294
  function warning$1(cond, message) {
285
295
  if (!cond) {
286
296
  // eslint-disable-next-line no-console
@@ -379,12 +389,13 @@ function parsePath(path) {
379
389
 
380
390
  return parsedPath;
381
391
  }
382
- function createURL(location) {
392
+ function createClientSideURL(location) {
383
393
  // window.location.origin is "null" (the literal string value) in Firefox
384
394
  // under certain conditions, notably when serving from a local HTML file
385
395
  // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297
386
- let base = typeof window !== "undefined" && typeof window.location !== "undefined" && window.location.origin !== "null" ? window.location.origin : "unknown://unknown";
396
+ let base = typeof window !== "undefined" && typeof window.location !== "undefined" && window.location.origin !== "null" ? window.location.origin : window.location.href;
387
397
  let href = typeof location === "string" ? location : createPath(location);
398
+ invariant(base, "No window.location.(origin|href) available to create URL for href: " + href);
388
399
  return new URL(href, base);
389
400
  }
390
401
 
@@ -479,7 +490,7 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
479
490
 
480
491
  encodeLocation(to) {
481
492
  // Encode a Location the same way window.location would
482
- let url = createURL(typeof to === "string" ? to : createPath(to));
493
+ let url = createClientSideURL(typeof to === "string" ? to : createPath(to));
483
494
  return {
484
495
  pathname: url.pathname,
485
496
  search: url.search,
@@ -555,7 +566,7 @@ function convertRoutesToDataRoutes(routes, parentPath, allIds) {
555
566
  /**
556
567
  * Matches the given routes to a location and returns the match data.
557
568
  *
558
- * @see https://reactrouter.com/docs/en/v6/utils/match-routes
569
+ * @see https://reactrouter.com/utils/match-routes
559
570
  */
560
571
 
561
572
  function matchRoutes(routes, locationArg, basename) {
@@ -718,7 +729,7 @@ function matchRouteBranch(branch, pathname) {
718
729
  /**
719
730
  * Returns a path with params interpolated.
720
731
  *
721
- * @see https://reactrouter.com/docs/en/v6/utils/generate-path
732
+ * @see https://reactrouter.com/utils/generate-path
722
733
  */
723
734
 
724
735
 
@@ -751,7 +762,7 @@ function generatePath(path, params) {
751
762
  * Performs pattern matching on a URL pathname and returns information about
752
763
  * the match.
753
764
  *
754
- * @see https://reactrouter.com/docs/en/v6/utils/match-path
765
+ * @see https://reactrouter.com/utils/match-path
755
766
  */
756
767
  function matchPath(pattern, pathname) {
757
768
  if (typeof pattern === "string") {
@@ -873,15 +884,6 @@ function stripBasename(pathname, basename) {
873
884
  * @private
874
885
  */
875
886
 
876
- function invariant(value, message) {
877
- if (value === false || value === null || typeof value === "undefined") {
878
- throw new Error(message);
879
- }
880
- }
881
- /**
882
- * @private
883
- */
884
-
885
887
  function warning(cond, message) {
886
888
  if (!cond) {
887
889
  // eslint-disable-next-line no-console
@@ -900,7 +902,7 @@ function warning(cond, message) {
900
902
  /**
901
903
  * Returns a resolved path object relative to the given pathname.
902
904
  *
903
- * @see https://reactrouter.com/docs/en/v6/utils/resolve-path
905
+ * @see https://reactrouter.com/utils/resolve-path
904
906
  */
905
907
 
906
908
  function resolvePath(to, fromPathname) {
@@ -1624,7 +1626,7 @@ function createRouter(init) {
1624
1626
 
1625
1627
 
1626
1628
  pendingNavigationController = new AbortController();
1627
- let request = createRequest(location, pendingNavigationController.signal, opts && opts.submission);
1629
+ let request = createClientSideRequest(location, pendingNavigationController.signal, opts && opts.submission);
1628
1630
  let pendingActionData;
1629
1631
  let pendingError;
1630
1632
 
@@ -1654,7 +1656,11 @@ function createRouter(init) {
1654
1656
  location
1655
1657
  }, opts.submission);
1656
1658
 
1657
- loadingNavigation = navigation;
1659
+ loadingNavigation = navigation; // Create a GET request for the loaders
1660
+
1661
+ request = new Request(request.url, {
1662
+ signal: request.signal
1663
+ });
1658
1664
  } // Call loaders
1659
1665
 
1660
1666
 
@@ -1943,7 +1949,7 @@ function createRouter(init) {
1943
1949
  }); // Call the action for the fetcher
1944
1950
 
1945
1951
  let abortController = new AbortController();
1946
- let fetchRequest = createRequest(path, abortController.signal, submission);
1952
+ let fetchRequest = createClientSideRequest(path, abortController.signal, submission);
1947
1953
  fetchControllers.set(key, abortController);
1948
1954
  let actionResult = await callLoaderOrAction("action", fetchRequest, match, requestMatches, router.basename);
1949
1955
 
@@ -1987,7 +1993,7 @@ function createRouter(init) {
1987
1993
 
1988
1994
 
1989
1995
  let nextLocation = state.navigation.location || state.location;
1990
- let revalidationRequest = createRequest(nextLocation, abortController.signal);
1996
+ let revalidationRequest = createClientSideRequest(nextLocation, abortController.signal);
1991
1997
  let matches = state.navigation.state !== "idle" ? matchRoutes(dataRoutes, state.navigation.location, init.basename) : state.matches;
1992
1998
  invariant(matches, "Didn't find any matches after fetcher action");
1993
1999
  let loadId = ++incrementingLoadId;
@@ -2107,7 +2113,7 @@ function createRouter(init) {
2107
2113
  }); // Call the loader for this fetcher route match
2108
2114
 
2109
2115
  let abortController = new AbortController();
2110
- let fetchRequest = createRequest(path, abortController.signal);
2116
+ let fetchRequest = createClientSideRequest(path, abortController.signal);
2111
2117
  fetchControllers.set(key, abortController);
2112
2118
  let result = await callLoaderOrAction("loader", fetchRequest, match, matches, router.basename); // Deferred isn't supported or fetcher loads, await everything and treat it
2113
2119
  // as a normal load. resolveDeferredData will return undefined if this
@@ -2187,21 +2193,27 @@ function createRouter(init) {
2187
2193
 
2188
2194
 
2189
2195
  async function startRedirectNavigation(state, redirect, replace) {
2196
+ var _window;
2197
+
2190
2198
  if (redirect.revalidate) {
2191
2199
  isRevalidationRequired = true;
2192
2200
  }
2193
2201
 
2194
2202
  let redirectLocation = createLocation(state.location, redirect.location);
2195
- invariant(redirectLocation, "Expected a location on the redirect navigation");
2203
+ invariant(redirectLocation, "Expected a location on the redirect navigation"); // Check if this an external redirect that goes to a new origin
2196
2204
 
2197
- if (redirect.external && typeof window !== "undefined" && typeof window.location !== "undefined") {
2198
- if (replace) {
2199
- window.location.replace(redirect.location);
2200
- } else {
2201
- window.location.assign(redirect.location);
2202
- }
2205
+ if (typeof ((_window = window) == null ? void 0 : _window.location) !== "undefined") {
2206
+ let newOrigin = createClientSideURL(redirect.location).origin;
2203
2207
 
2204
- return;
2208
+ if (window.location.origin !== newOrigin) {
2209
+ if (replace) {
2210
+ window.location.replace(redirect.location);
2211
+ } else {
2212
+ window.location.assign(redirect.location);
2213
+ }
2214
+
2215
+ return;
2216
+ }
2205
2217
  } // There's no need to abort on redirects, since we don't detect the
2206
2218
  // redirect until the action/loaders have settled
2207
2219
 
@@ -2248,7 +2260,7 @@ function createRouter(init) {
2248
2260
  // accordingly
2249
2261
  let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(_ref8 => {
2250
2262
  let [, href, match, fetchMatches] = _ref8;
2251
- return callLoaderOrAction("loader", createRequest(href, request.signal), match, fetchMatches, router.basename);
2263
+ return callLoaderOrAction("loader", createClientSideRequest(href, request.signal), match, fetchMatches, router.basename);
2252
2264
  })]);
2253
2265
  let loaderResults = results.slice(0, matchesToLoad.length);
2254
2266
  let fetcherResults = results.slice(matchesToLoad.length);
@@ -2532,7 +2544,7 @@ function unstable_createStaticHandler(routes, opts) {
2532
2544
 
2533
2545
  let result = await queryImpl(request, location, matches);
2534
2546
 
2535
- if (result instanceof Response) {
2547
+ if (isResponse(result)) {
2536
2548
  return result;
2537
2549
  } // When returning StaticHandlerContext, we patch back in the location here
2538
2550
  // since we need it for React Context. But this helps keep our submit and
@@ -2598,7 +2610,7 @@ function unstable_createStaticHandler(routes, opts) {
2598
2610
 
2599
2611
  let result = await queryImpl(request, location, matches, match);
2600
2612
 
2601
- if (result instanceof Response) {
2613
+ if (isResponse(result)) {
2602
2614
  return result;
2603
2615
  }
2604
2616
 
@@ -2627,7 +2639,7 @@ function unstable_createStaticHandler(routes, opts) {
2627
2639
  }
2628
2640
 
2629
2641
  let result = await loadRouteData(request, matches, routeMatch);
2630
- return result instanceof Response ? result : _extends({}, result, {
2642
+ return isResponse(result) ? result : _extends({}, result, {
2631
2643
  actionData: null,
2632
2644
  actionHeaders: {}
2633
2645
  });
@@ -2659,7 +2671,7 @@ function unstable_createStaticHandler(routes, opts) {
2659
2671
  if (!actionMatch.route.action) {
2660
2672
  let error = getInternalRouterError(405, {
2661
2673
  method: request.method,
2662
- pathname: createURL(request.url).pathname,
2674
+ pathname: new URL(request.url).pathname,
2663
2675
  routeId: actionMatch.route.id
2664
2676
  });
2665
2677
 
@@ -2734,9 +2746,13 @@ function unstable_createStaticHandler(routes, opts) {
2734
2746
  [actionMatch.route.id]: result.headers
2735
2747
  } : {})
2736
2748
  });
2737
- }
2749
+ } // Create a GET request for the loaders
2750
+
2738
2751
 
2739
- let context = await loadRouteData(request, matches);
2752
+ let loaderRequest = new Request(request.url, {
2753
+ signal: request.signal
2754
+ });
2755
+ let context = await loadRouteData(loaderRequest, matches);
2740
2756
  return _extends({}, context, result.statusCode ? {
2741
2757
  statusCode: result.statusCode
2742
2758
  } : {}, {
@@ -2755,7 +2771,7 @@ function unstable_createStaticHandler(routes, opts) {
2755
2771
  if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader)) {
2756
2772
  throw getInternalRouterError(400, {
2757
2773
  method: request.method,
2758
- pathname: createURL(request.url).pathname,
2774
+ pathname: new URL(request.url).pathname,
2759
2775
  routeId: routeMatch == null ? void 0 : routeMatch.route.id
2760
2776
  });
2761
2777
  }
@@ -2949,9 +2965,9 @@ function isNewRouteInstance(currentMatch, match) {
2949
2965
  }
2950
2966
 
2951
2967
  function shouldRevalidateLoader(currentLocation, currentMatch, submission, location, match, isRevalidationRequired, actionResult) {
2952
- let currentUrl = createURL(currentLocation);
2968
+ let currentUrl = createClientSideURL(currentLocation);
2953
2969
  let currentParams = currentMatch.params;
2954
- let nextUrl = createURL(location);
2970
+ let nextUrl = createClientSideURL(location);
2955
2971
  let nextParams = match.params; // This is the default implementation as to when we revalidate. If the route
2956
2972
  // provides it's own implementation, then we give them full control but
2957
2973
  // provide this value so they can leverage it if needed after they check
@@ -3021,20 +3037,18 @@ async function callLoaderOrAction(type, request, match, matches, basename, isSta
3021
3037
  request.signal.removeEventListener("abort", onReject);
3022
3038
  }
3023
3039
 
3024
- if (result instanceof Response) {
3040
+ if (isResponse(result)) {
3025
3041
  let status = result.status; // Process redirects
3026
3042
 
3027
3043
  if (redirectStatusCodes.has(status)) {
3028
3044
  let location = result.headers.get("Location");
3029
- invariant(location, "Redirects returned/thrown from loaders/actions must have a Location header"); // Check if this an external redirect that goes to a new origin
3030
-
3031
- let external = createURL(location).origin !== createURL("/").origin; // Support relative routing in internal redirects
3045
+ invariant(location, "Redirects returned/thrown from loaders/actions must have a Location header");
3046
+ let isAbsolute = /^[a-z+]+:\/\//i.test(location) || location.startsWith("//"); // Support relative routing in internal redirects
3032
3047
 
3033
- if (!external) {
3048
+ if (!isAbsolute) {
3034
3049
  let activeMatches = matches.slice(0, matches.indexOf(match) + 1);
3035
3050
  let routePathnames = getPathContributingMatches(activeMatches).map(match => match.pathnameBase);
3036
- let requestPath = createURL(request.url).pathname;
3037
- let resolvedLocation = resolveTo(location, routePathnames, requestPath);
3051
+ let resolvedLocation = resolveTo(location, routePathnames, new URL(request.url).pathname);
3038
3052
  invariant(createPath(resolvedLocation), "Unable to resolve redirect location: " + location); // Prepend the basename to the redirect location if we have one
3039
3053
 
3040
3054
  if (basename) {
@@ -3058,8 +3072,7 @@ async function callLoaderOrAction(type, request, match, matches, basename, isSta
3058
3072
  type: ResultType.redirect,
3059
3073
  status,
3060
3074
  location,
3061
- revalidate: result.headers.get("X-Remix-Revalidate") !== null,
3062
- external
3075
+ revalidate: result.headers.get("X-Remix-Revalidate") !== null
3063
3076
  };
3064
3077
  } // For SSR single-route requests, we want to hand Responses back directly
3065
3078
  // without unwrapping. We do this with the QueryRouteResponse wrapper
@@ -3117,10 +3130,13 @@ async function callLoaderOrAction(type, request, match, matches, basename, isSta
3117
3130
  type: ResultType.data,
3118
3131
  data: result
3119
3132
  };
3120
- }
3133
+ } // Utility method for creating the Request instances for loaders/actions during
3134
+ // client-side navigations and fetches. During SSR we will always have a
3135
+ // Request instance from the static handler (query/queryRoute)
3136
+
3121
3137
 
3122
- function createRequest(location, signal, submission) {
3123
- let url = createURL(stripHashFromPath(location)).toString();
3138
+ function createClientSideRequest(location, signal, submission) {
3139
+ let url = createClientSideURL(stripHashFromPath(location)).toString();
3124
3140
  let init = {
3125
3141
  signal
3126
3142
  };
@@ -3374,8 +3390,12 @@ function isRedirectResult(result) {
3374
3390
  return (result && result.type) === ResultType.redirect;
3375
3391
  }
3376
3392
 
3393
+ function isResponse(value) {
3394
+ return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
3395
+ }
3396
+
3377
3397
  function isRedirectResponse(result) {
3378
- if (!(result instanceof Response)) {
3398
+ if (!isResponse(result)) {
3379
3399
  return false;
3380
3400
  }
3381
3401
 
@@ -3385,7 +3405,7 @@ function isRedirectResponse(result) {
3385
3405
  }
3386
3406
 
3387
3407
  function isQueryRouteResponse(obj) {
3388
- return obj && obj.response instanceof Response && (obj.type === ResultType.data || ResultType.error);
3408
+ return obj && isResponse(obj.response) && (obj.type === ResultType.data || ResultType.error);
3389
3409
  }
3390
3410
 
3391
3411
  function isValidMethod(method) {