UNPKG

next

Version:

The React Framework

106 lines (104 loc) 5.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "resolveHref", { enumerable: true, get: function() { return resolveHref; } }); const _querystring = require("../shared/lib/router/utils/querystring"); const _formaturl = require("../shared/lib/router/utils/format-url"); const _omit = require("../shared/lib/router/utils/omit"); const _utils = require("../shared/lib/utils"); const _normalizetrailingslash = require("./normalize-trailing-slash"); const _islocalurl = require("../shared/lib/router/utils/is-local-url"); const _utils1 = require("../shared/lib/router/utils"); const _interpolateas = require("../shared/lib/router/utils/interpolate-as"); const _routeregex = require("../shared/lib/router/utils/route-regex"); const _routematcher = require("../shared/lib/router/utils/route-matcher"); function resolveHref(router, href, resolveAs) { // we use a dummy base url for relative urls let base; let urlAsString = typeof href === 'string' ? href : (0, _formaturl.formatWithValidation)(href); // repeated slashes and backslashes in the URL are considered // invalid and will never match a Next.js page/file // https://www.rfc-editor.org/rfc/rfc3986.html#section-3.1 const urlProtoMatch = urlAsString.match(/^[a-z][a-z0-9+.-]*:\/\//i); const urlAsStringNoProto = urlProtoMatch ? urlAsString.slice(urlProtoMatch[0].length) : urlAsString; const urlParts = urlAsStringNoProto.split('?', 1); if ((urlParts[0] || '').match(/(\/\/|\\)/)) { console.error("Invalid href '" + urlAsString + "' passed to next/router in page: '" + router.pathname + "'. Repeated forward-slashes (//) or backslashes \\ are not valid in the href."); const normalizedUrl = (0, _utils.normalizeRepeatedSlashes)(urlAsStringNoProto); urlAsString = (urlProtoMatch ? urlProtoMatch[0] : '') + normalizedUrl; } // Return because it cannot be routed by the Next.js router if (!(0, _islocalurl.isLocalURL)(urlAsString)) { return resolveAs ? [ urlAsString ] : urlAsString; } try { let baseBase = urlAsString.startsWith('#') ? router.asPath : router.pathname; // If the provided href is only a query string, it is safer to use the asPath // considering rewrites. if (urlAsString.startsWith('?')) { baseBase = router.asPath; // However, if is a dynamic route, we need to use the pathname to preserve the // query interpolation and rewrites (router.pathname will look like "/[slug]"). if ((0, _utils1.isDynamicRoute)(router.pathname)) { baseBase = router.pathname; const routeRegex = (0, _routeregex.getRouteRegex)(router.pathname); const match = (0, _routematcher.getRouteMatcher)(routeRegex)(router.asPath); // For dynamic routes, if asPath doesn't match the pathname regex, it is a rewritten path. // In this case, should use asPath to preserve the current URL. if (!match) { baseBase = router.asPath; } // Note: There is an edge case where the pathname is dynamic, and also a rewrite path to the same segment. // E.g. in "/[slug]" path, rewrite "/foo" -> "/bar" // In this case, it will be treated as a non-rewritten path and possibly interpolate the query string. // E.g., "/any?slug=foo" will become the content of "/foo", not rewritten as "/bar" // This is currently a trade-off of not resolving rewrite paths on every Router/Link call, // but using a lighter route regex pattern check. } } base = new URL(baseBase, 'http://n'); } catch (_) { // fallback to / for invalid asPath values e.g. // base = new URL('/', 'http://n'); } try { const finalUrl = new URL(urlAsString, base); finalUrl.pathname = (0, _normalizetrailingslash.normalizePathTrailingSlash)(finalUrl.pathname); let interpolatedAs = ''; if ((0, _utils1.isDynamicRoute)(finalUrl.pathname) && finalUrl.searchParams && resolveAs) { const query = (0, _querystring.searchParamsToUrlQuery)(finalUrl.searchParams); const { result, params } = (0, _interpolateas.interpolateAs)(finalUrl.pathname, finalUrl.pathname, query); if (result) { interpolatedAs = (0, _formaturl.formatWithValidation)({ pathname: result, hash: finalUrl.hash, query: (0, _omit.omit)(query, params) }); } } // if the origin didn't change, it means we received a relative href const resolvedHref = finalUrl.origin === base.origin ? finalUrl.href.slice(finalUrl.origin.length) : finalUrl.href; return resolveAs ? [ resolvedHref, interpolatedAs || resolvedHref ] : resolvedHref; } catch (_) { return resolveAs ? [ urlAsString ] : urlAsString; } } if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') { Object.defineProperty(exports.default, '__esModule', { value: true }); Object.assign(exports.default, exports); module.exports = exports.default; } //# sourceMappingURL=resolve-href.js.map