[d565449] | 1 | 'use strict';
|
---|
| 2 |
|
---|
| 3 | Object.defineProperty(exports, '__esModule', { value: true });
|
---|
| 4 |
|
---|
| 5 | var React = require('react');
|
---|
| 6 | var router = require('@remix-run/router');
|
---|
| 7 | var reactRouter = require('react-router');
|
---|
| 8 | var reactRouterDom = require('react-router-dom');
|
---|
| 9 |
|
---|
| 10 | function _interopNamespace(e) {
|
---|
| 11 | if (e && e.__esModule) return e;
|
---|
| 12 | var n = Object.create(null);
|
---|
| 13 | if (e) {
|
---|
| 14 | Object.keys(e).forEach(function (k) {
|
---|
| 15 | if (k !== 'default') {
|
---|
| 16 | var d = Object.getOwnPropertyDescriptor(e, k);
|
---|
| 17 | Object.defineProperty(n, k, d.get ? d : {
|
---|
| 18 | enumerable: true,
|
---|
| 19 | get: function () { return e[k]; }
|
---|
| 20 | });
|
---|
| 21 | }
|
---|
| 22 | });
|
---|
| 23 | }
|
---|
| 24 | n["default"] = e;
|
---|
| 25 | return Object.freeze(n);
|
---|
| 26 | }
|
---|
| 27 |
|
---|
| 28 | var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
---|
| 29 |
|
---|
| 30 | /**
|
---|
| 31 | * A `<Router>` that may not navigate to any other location. This is useful
|
---|
| 32 | * on the server where there is no stateful UI.
|
---|
| 33 | */
|
---|
| 34 | function StaticRouter({
|
---|
| 35 | basename,
|
---|
| 36 | children,
|
---|
| 37 | location: locationProp = "/",
|
---|
| 38 | future
|
---|
| 39 | }) {
|
---|
| 40 | if (typeof locationProp === "string") {
|
---|
| 41 | locationProp = reactRouterDom.parsePath(locationProp);
|
---|
| 42 | }
|
---|
| 43 | let action = router.Action.Pop;
|
---|
| 44 | let location = {
|
---|
| 45 | pathname: locationProp.pathname || "/",
|
---|
| 46 | search: locationProp.search || "",
|
---|
| 47 | hash: locationProp.hash || "",
|
---|
| 48 | state: locationProp.state != null ? locationProp.state : null,
|
---|
| 49 | key: locationProp.key || "default"
|
---|
| 50 | };
|
---|
| 51 | let staticNavigator = getStatelessNavigator();
|
---|
| 52 | return /*#__PURE__*/React__namespace.createElement(reactRouterDom.Router, {
|
---|
| 53 | basename: basename,
|
---|
| 54 | children: children,
|
---|
| 55 | location: location,
|
---|
| 56 | navigationType: action,
|
---|
| 57 | navigator: staticNavigator,
|
---|
| 58 | future: future,
|
---|
| 59 | static: true
|
---|
| 60 | });
|
---|
| 61 | }
|
---|
| 62 | /**
|
---|
| 63 | * A Data Router that may not navigate to any other location. This is useful
|
---|
| 64 | * on the server where there is no stateful UI.
|
---|
| 65 | */
|
---|
| 66 | function StaticRouterProvider({
|
---|
| 67 | context,
|
---|
| 68 | router: router$1,
|
---|
| 69 | hydrate = true,
|
---|
| 70 | nonce
|
---|
| 71 | }) {
|
---|
| 72 | !(router$1 && context) ? process.env.NODE_ENV !== "production" ? router.UNSAFE_invariant(false, "You must provide `router` and `context` to <StaticRouterProvider>") : router.UNSAFE_invariant(false) : void 0;
|
---|
| 73 | let dataRouterContext = {
|
---|
| 74 | router: router$1,
|
---|
| 75 | navigator: getStatelessNavigator(),
|
---|
| 76 | static: true,
|
---|
| 77 | staticContext: context,
|
---|
| 78 | basename: context.basename || "/"
|
---|
| 79 | };
|
---|
| 80 | let fetchersContext = new Map();
|
---|
| 81 | let hydrateScript = "";
|
---|
| 82 | if (hydrate !== false) {
|
---|
| 83 | let data = {
|
---|
| 84 | loaderData: context.loaderData,
|
---|
| 85 | actionData: context.actionData,
|
---|
| 86 | errors: serializeErrors(context.errors)
|
---|
| 87 | };
|
---|
| 88 | // Use JSON.parse here instead of embedding a raw JS object here to speed
|
---|
| 89 | // up parsing on the client. Dual-stringify is needed to ensure all quotes
|
---|
| 90 | // are properly escaped in the resulting string. See:
|
---|
| 91 | // https://v8.dev/blog/cost-of-javascript-2019#json
|
---|
| 92 | let json = htmlEscape(JSON.stringify(JSON.stringify(data)));
|
---|
| 93 | hydrateScript = `window.__staticRouterHydrationData = JSON.parse(${json});`;
|
---|
| 94 | }
|
---|
| 95 | let {
|
---|
| 96 | state
|
---|
| 97 | } = dataRouterContext.router;
|
---|
| 98 | return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(reactRouterDom.UNSAFE_DataRouterContext.Provider, {
|
---|
| 99 | value: dataRouterContext
|
---|
| 100 | }, /*#__PURE__*/React__namespace.createElement(reactRouterDom.UNSAFE_DataRouterStateContext.Provider, {
|
---|
| 101 | value: state
|
---|
| 102 | }, /*#__PURE__*/React__namespace.createElement(reactRouterDom.UNSAFE_FetchersContext.Provider, {
|
---|
| 103 | value: fetchersContext
|
---|
| 104 | }, /*#__PURE__*/React__namespace.createElement(reactRouterDom.UNSAFE_ViewTransitionContext.Provider, {
|
---|
| 105 | value: {
|
---|
| 106 | isTransitioning: false
|
---|
| 107 | }
|
---|
| 108 | }, /*#__PURE__*/React__namespace.createElement(reactRouterDom.Router, {
|
---|
| 109 | basename: dataRouterContext.basename,
|
---|
| 110 | location: state.location,
|
---|
| 111 | navigationType: state.historyAction,
|
---|
| 112 | navigator: dataRouterContext.navigator,
|
---|
| 113 | static: dataRouterContext.static,
|
---|
| 114 | future: {
|
---|
| 115 | v7_relativeSplatPath: router$1.future.v7_relativeSplatPath
|
---|
| 116 | }
|
---|
| 117 | }, /*#__PURE__*/React__namespace.createElement(DataRoutes, {
|
---|
| 118 | routes: router$1.routes,
|
---|
| 119 | future: router$1.future,
|
---|
| 120 | state: state
|
---|
| 121 | })))))), hydrateScript ? /*#__PURE__*/React__namespace.createElement("script", {
|
---|
| 122 | suppressHydrationWarning: true,
|
---|
| 123 | nonce: nonce,
|
---|
| 124 | dangerouslySetInnerHTML: {
|
---|
| 125 | __html: hydrateScript
|
---|
| 126 | }
|
---|
| 127 | }) : null);
|
---|
| 128 | }
|
---|
| 129 | function DataRoutes({
|
---|
| 130 | routes,
|
---|
| 131 | future,
|
---|
| 132 | state
|
---|
| 133 | }) {
|
---|
| 134 | return reactRouter.UNSAFE_useRoutesImpl(routes, undefined, state, future);
|
---|
| 135 | }
|
---|
| 136 | function serializeErrors(errors) {
|
---|
| 137 | if (!errors) return null;
|
---|
| 138 | let entries = Object.entries(errors);
|
---|
| 139 | let serialized = {};
|
---|
| 140 | for (let [key, val] of entries) {
|
---|
| 141 | // Hey you! If you change this, please change the corresponding logic in
|
---|
| 142 | // deserializeErrors in react-router-dom/index.tsx :)
|
---|
| 143 | if (router.isRouteErrorResponse(val)) {
|
---|
| 144 | serialized[key] = {
|
---|
| 145 | ...val,
|
---|
| 146 | __type: "RouteErrorResponse"
|
---|
| 147 | };
|
---|
| 148 | } else if (val instanceof Error) {
|
---|
| 149 | // Do not serialize stack traces from SSR for security reasons
|
---|
| 150 | serialized[key] = {
|
---|
| 151 | message: val.message,
|
---|
| 152 | __type: "Error",
|
---|
| 153 | // If this is a subclass (i.e., ReferenceError), send up the type so we
|
---|
| 154 | // can re-create the same type during hydration.
|
---|
| 155 | ...(val.name !== "Error" ? {
|
---|
| 156 | __subType: val.name
|
---|
| 157 | } : {})
|
---|
| 158 | };
|
---|
| 159 | } else {
|
---|
| 160 | serialized[key] = val;
|
---|
| 161 | }
|
---|
| 162 | }
|
---|
| 163 | return serialized;
|
---|
| 164 | }
|
---|
| 165 | function getStatelessNavigator() {
|
---|
| 166 | return {
|
---|
| 167 | createHref,
|
---|
| 168 | encodeLocation,
|
---|
| 169 | push(to) {
|
---|
| 170 | throw new Error(`You cannot use navigator.push() on the server because it is a stateless ` + `environment. This error was probably triggered when you did a ` + `\`navigate(${JSON.stringify(to)})\` somewhere in your app.`);
|
---|
| 171 | },
|
---|
| 172 | replace(to) {
|
---|
| 173 | throw new Error(`You cannot use navigator.replace() on the server because it is a stateless ` + `environment. This error was probably triggered when you did a ` + `\`navigate(${JSON.stringify(to)}, { replace: true })\` somewhere ` + `in your app.`);
|
---|
| 174 | },
|
---|
| 175 | go(delta) {
|
---|
| 176 | throw new Error(`You cannot use navigator.go() on the server because it is a stateless ` + `environment. This error was probably triggered when you did a ` + `\`navigate(${delta})\` somewhere in your app.`);
|
---|
| 177 | },
|
---|
| 178 | back() {
|
---|
| 179 | throw new Error(`You cannot use navigator.back() on the server because it is a stateless ` + `environment.`);
|
---|
| 180 | },
|
---|
| 181 | forward() {
|
---|
| 182 | throw new Error(`You cannot use navigator.forward() on the server because it is a stateless ` + `environment.`);
|
---|
| 183 | }
|
---|
| 184 | };
|
---|
| 185 | }
|
---|
| 186 | function createStaticHandler(routes, opts) {
|
---|
| 187 | return router.createStaticHandler(routes, {
|
---|
| 188 | ...opts,
|
---|
| 189 | mapRouteProperties: reactRouter.UNSAFE_mapRouteProperties
|
---|
| 190 | });
|
---|
| 191 | }
|
---|
| 192 | function createStaticRouter(routes, context, opts = {}) {
|
---|
| 193 | let manifest = {};
|
---|
| 194 | let dataRoutes = router.UNSAFE_convertRoutesToDataRoutes(routes, reactRouter.UNSAFE_mapRouteProperties, undefined, manifest);
|
---|
| 195 | // Because our context matches may be from a framework-agnostic set of
|
---|
| 196 | // routes passed to createStaticHandler(), we update them here with our
|
---|
| 197 | // newly created/enhanced data routes
|
---|
| 198 | let matches = context.matches.map(match => {
|
---|
| 199 | let route = manifest[match.route.id] || match.route;
|
---|
| 200 | return {
|
---|
| 201 | ...match,
|
---|
| 202 | route
|
---|
| 203 | };
|
---|
| 204 | });
|
---|
| 205 | let msg = method => `You cannot use router.${method}() on the server because it is a stateless environment`;
|
---|
| 206 | return {
|
---|
| 207 | get basename() {
|
---|
| 208 | return context.basename;
|
---|
| 209 | },
|
---|
| 210 | get future() {
|
---|
| 211 | return {
|
---|
| 212 | v7_fetcherPersist: false,
|
---|
| 213 | v7_normalizeFormMethod: false,
|
---|
| 214 | v7_partialHydration: opts.future?.v7_partialHydration === true,
|
---|
| 215 | v7_prependBasename: false,
|
---|
| 216 | v7_relativeSplatPath: opts.future?.v7_relativeSplatPath === true,
|
---|
| 217 | v7_skipActionErrorRevalidation: false
|
---|
| 218 | };
|
---|
| 219 | },
|
---|
| 220 | get state() {
|
---|
| 221 | return {
|
---|
| 222 | historyAction: router.Action.Pop,
|
---|
| 223 | location: context.location,
|
---|
| 224 | matches,
|
---|
| 225 | loaderData: context.loaderData,
|
---|
| 226 | actionData: context.actionData,
|
---|
| 227 | errors: context.errors,
|
---|
| 228 | initialized: true,
|
---|
| 229 | navigation: router.IDLE_NAVIGATION,
|
---|
| 230 | restoreScrollPosition: null,
|
---|
| 231 | preventScrollReset: false,
|
---|
| 232 | revalidation: "idle",
|
---|
| 233 | fetchers: new Map(),
|
---|
| 234 | blockers: new Map()
|
---|
| 235 | };
|
---|
| 236 | },
|
---|
| 237 | get routes() {
|
---|
| 238 | return dataRoutes;
|
---|
| 239 | },
|
---|
| 240 | get window() {
|
---|
| 241 | return undefined;
|
---|
| 242 | },
|
---|
| 243 | initialize() {
|
---|
| 244 | throw msg("initialize");
|
---|
| 245 | },
|
---|
| 246 | subscribe() {
|
---|
| 247 | throw msg("subscribe");
|
---|
| 248 | },
|
---|
| 249 | enableScrollRestoration() {
|
---|
| 250 | throw msg("enableScrollRestoration");
|
---|
| 251 | },
|
---|
| 252 | navigate() {
|
---|
| 253 | throw msg("navigate");
|
---|
| 254 | },
|
---|
| 255 | fetch() {
|
---|
| 256 | throw msg("fetch");
|
---|
| 257 | },
|
---|
| 258 | revalidate() {
|
---|
| 259 | throw msg("revalidate");
|
---|
| 260 | },
|
---|
| 261 | createHref,
|
---|
| 262 | encodeLocation,
|
---|
| 263 | getFetcher() {
|
---|
| 264 | return router.IDLE_FETCHER;
|
---|
| 265 | },
|
---|
| 266 | deleteFetcher() {
|
---|
| 267 | throw msg("deleteFetcher");
|
---|
| 268 | },
|
---|
| 269 | dispose() {
|
---|
| 270 | throw msg("dispose");
|
---|
| 271 | },
|
---|
| 272 | getBlocker() {
|
---|
| 273 | return router.IDLE_BLOCKER;
|
---|
| 274 | },
|
---|
| 275 | deleteBlocker() {
|
---|
| 276 | throw msg("deleteBlocker");
|
---|
| 277 | },
|
---|
| 278 | patchRoutes() {
|
---|
| 279 | throw msg("patchRoutes");
|
---|
| 280 | },
|
---|
| 281 | _internalFetchControllers: new Map(),
|
---|
| 282 | _internalActiveDeferreds: new Map(),
|
---|
| 283 | _internalSetRoutes() {
|
---|
| 284 | throw msg("_internalSetRoutes");
|
---|
| 285 | }
|
---|
| 286 | };
|
---|
| 287 | }
|
---|
| 288 | function createHref(to) {
|
---|
| 289 | return typeof to === "string" ? to : reactRouterDom.createPath(to);
|
---|
| 290 | }
|
---|
| 291 | function encodeLocation(to) {
|
---|
| 292 | let href = typeof to === "string" ? to : reactRouterDom.createPath(to);
|
---|
| 293 | // Treating this as a full URL will strip any trailing spaces so we need to
|
---|
| 294 | // pre-encode them since they might be part of a matching splat param from
|
---|
| 295 | // an ancestor route
|
---|
| 296 | href = href.replace(/ $/, "%20");
|
---|
| 297 | let encoded = ABSOLUTE_URL_REGEX.test(href) ? new URL(href) : new URL(href, "http://localhost");
|
---|
| 298 | return {
|
---|
| 299 | pathname: encoded.pathname,
|
---|
| 300 | search: encoded.search,
|
---|
| 301 | hash: encoded.hash
|
---|
| 302 | };
|
---|
| 303 | }
|
---|
| 304 | const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
|
---|
| 305 | // This utility is based on https://github.com/zertosh/htmlescape
|
---|
| 306 | // License: https://github.com/zertosh/htmlescape/blob/0527ca7156a524d256101bb310a9f970f63078ad/LICENSE
|
---|
| 307 | const ESCAPE_LOOKUP = {
|
---|
| 308 | "&": "\\u0026",
|
---|
| 309 | ">": "\\u003e",
|
---|
| 310 | "<": "\\u003c",
|
---|
| 311 | "\u2028": "\\u2028",
|
---|
| 312 | "\u2029": "\\u2029"
|
---|
| 313 | };
|
---|
| 314 | const ESCAPE_REGEX = /[&><\u2028\u2029]/g;
|
---|
| 315 | function htmlEscape(str) {
|
---|
| 316 | return str.replace(ESCAPE_REGEX, match => ESCAPE_LOOKUP[match]);
|
---|
| 317 | }
|
---|
| 318 |
|
---|
| 319 | exports.StaticRouter = StaticRouter;
|
---|
| 320 | exports.StaticRouterProvider = StaticRouterProvider;
|
---|
| 321 | exports.createStaticHandler = createStaticHandler;
|
---|
| 322 | exports.createStaticRouter = createStaticRouter;
|
---|