UNPKG

vike

Version:

The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.

133 lines (132 loc) 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPageContextUrlComputed = getPageContextUrlComputed; // ===================== // File determining the URL logic. // URLs need to be computed, because the user can modify the URL e.g. with onBeforeRoute() for i18n. // ===================== const objectDefineProperty_js_1 = require("../utils/objectDefineProperty.js"); const preparePageContextForPublicUsage_js_1 = require("./preparePageContextForPublicUsage.js"); const utils_js_1 = require("./utils.js"); function getPageContextUrlComputed(pageContext) { (0, utils_js_1.assert)(typeof pageContext.urlOriginal === 'string'); (0, preparePageContextForPublicUsage_js_1.assertPropertyGetters)(pageContext); const pageContextUrlComputed = {}; (0, objectDefineProperty_js_1.objectDefineProperty)(pageContextUrlComputed, 'urlPathname', { get: urlPathnameGetter, enumerable: true, configurable: true, }); (0, objectDefineProperty_js_1.objectDefineProperty)(pageContextUrlComputed, 'url', { get: urlGetter, enumerable: false, configurable: true, }); (0, objectDefineProperty_js_1.objectDefineProperty)(pageContextUrlComputed, 'urlParsed', { get: urlParsedGetter, enumerable: true, configurable: true, }); return pageContextUrlComputed; } function getUrlParsed(pageContext) { // Example of i18n app using `throw render()`: // 1. User goes to '/fr-FR/admin'. // 2. The first onBeforeRoute() call accesses pageContext.urlPathname (its value is '/fr-FR/admin': the pathname of pageContext.urlOriginal, since both pageContext.urlLogical and pageContext._urlRewrite are undefined) and sets pageContext.urlLogical to '/admin'. // 3. A guard() hooks accesses pageContext.urlPathname (its value is '/admin': the pathname of pageContext.urlLogical) and calls `throw render('/fr-FR/login')` // 4. Vike create a new pageContext object (pageContext.urlLogical is erased) and sets pageContext._urlRewrite to '/fr-FR/login'. (While pageContext.urlOriginal is still '/fr-FR/admin'.) // 5. The second onBeforeRoute() call accesses pageContext.urlPathname (its value is '/fr-FR/login': the pathname of pageContext._urlRewrite, since pageContext.urlLogical is undefined) and sets pageContext.urlLogical to '/login'. // 6. The value of pageContext.urlPathname is now '/login': the pathname of `pageContext.urlLogical`. (While pageContext.urlOriginal is still '/fr-FR/admin'.) // Reproduction: https://github.com/vikejs/vike/discussions/1436#discussioncomment-8142023 // Determine logical URL const assertUrlResolved = (src) => (0, utils_js_1.assert)(typeof urlResolved === 'string', // TODO/eventually: remove debug logs, see: // - https://github.com/vikejs/vike/issues/2138#issuecomment-2631713411 // - https://github.com/vikejs/vike/commit/5c7810f3080ab62536950f26e019bb2a3a517082 { src, urlResolved }); let urlResolved; let isBaseToBeRemoved; if (pageContext.urlLogical) { // Set by onBeforeRoute() urlResolved = pageContext.urlLogical; isBaseToBeRemoved = false; assertUrlResolved(1); } else if (pageContext._urlRewrite) { // Set by `throw render()` urlResolved = pageContext._urlRewrite; isBaseToBeRemoved = false; assertUrlResolved(2); } else { // Set by renderPage() urlResolved = pageContext.urlOriginal; isBaseToBeRemoved = true; assertUrlResolved(3); } assertUrlResolved(4); // Remove .pageContext.json let urlHandler = pageContext._urlHandler; if (!urlHandler) urlHandler = (url) => url; urlResolved = urlHandler(urlResolved); // Remove Base URL. // - We assume there isn't any Base URL to the URLs set by the user at `throw render()` and onBeforeRoute() // - This makes sense because the Base URL is merely a setting: ideally the user should write code that doesn't know anything about it (so that the user can remove/add/change Base URL without having to modify any code). // - pageContext.urlOriginal is the URL of the HTTP request and thus contains the Base URL. const baseServer = !isBaseToBeRemoved ? '/' : pageContext._baseServer; // Parse URL return (0, utils_js_1.parseUrl)(urlResolved, baseServer); } function urlPathnameGetter() { const { pathname } = getUrlParsed(this); const urlPathname = pathname; (0, utils_js_1.assert)(urlPathname.startsWith('/')); return urlPathname; } function urlGetter() { // TODO/v1-release: remove (0, utils_js_1.assertWarning)(false, '`pageContext.url` is outdated. Use `pageContext.urlPathname`, `pageContext.urlParsed`, or `pageContext.urlOriginal` instead. (See https://vike.dev/migration/0.4.23 for more information.)', { onlyOnce: true, showStackTrace: true }); return urlPathnameGetter.call(this); } function urlParsedGetter() { const { // remove isBaseMissing as it isn't part of UrlPublic isBaseMissing: _, ...urlParsed } = getUrlParsed(this); const hashIsAvailable = (0, utils_js_1.isBrowser)(); const warnHashNotAvailable = (prop) => { (0, utils_js_1.assertWarning)(hashIsAvailable, `pageContext.urlParsed.${prop} isn't available on the server-side (HTTP requests don't include the URL hash)`, { onlyOnce: true, showStackTrace: true }); }; const urlParsedEnhanced = { ...urlParsed, get hash() { warnHashNotAvailable('hash'); return urlParsed.hash; }, get hashOriginal() { warnHashNotAvailable('hashOriginal'); return urlParsed.hashOriginal; }, // TODO/next-major-release: remove get hashString() { (0, utils_js_1.assertWarning)(false, 'pageContext.urlParsed.hashString has been renamed to pageContext.urlParsed.hashOriginal', { onlyOnce: true, showStackTrace: true, }); warnHashNotAvailable('hashString'); return urlParsed.hashOriginal; }, // TODO/next-major-release: remove get searchString() { (0, utils_js_1.assertWarning)(false, 'pageContext.urlParsed.searchString has been renamed to pageContext.urlParsed.searchOriginal', { onlyOnce: true, showStackTrace: true }); return urlParsed.searchOriginal; }, }; (0, utils_js_1.changeEnumerable)(urlParsedEnhanced, 'hashString', false); (0, utils_js_1.changeEnumerable)(urlParsedEnhanced, 'searchString', false); if (!hashIsAvailable) { (0, utils_js_1.changeEnumerable)(urlParsedEnhanced, 'hash', false); (0, utils_js_1.changeEnumerable)(urlParsedEnhanced, 'hashOriginal', false); } return urlParsedEnhanced; }