@uniweb/core 0.38.0 → 0.38.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/package.json +1 -1
- package/src/index.js +1 -0
- package/src/resolve-route.js +44 -0
package/package.json
CHANGED
package/src/index.js
CHANGED
package/src/resolve-route.js
CHANGED
|
@@ -330,6 +330,10 @@ export function landingRoute(site, page, seen = new Set()) {
|
|
|
330
330
|
*
|
|
331
331
|
* `status` is what a host that sends one sends. A static host has its own ways to say each kind.
|
|
332
332
|
*
|
|
333
|
+
* ⭐ **A redirect's `location` names nothing of the request's query or fragment** — a path in, a
|
|
334
|
+
* location out. `carryQuery` adds them, as the runtime does before it navigates and as a host that
|
|
335
|
+
* answers with an HTTP redirect should, so a link's parameters reach the page the visitor lands on.
|
|
336
|
+
*
|
|
333
337
|
* @param {Object} site - one locale's site content (`{ pages, config, notFound? }`), or its `routeIndex`
|
|
334
338
|
* @param {string} path - the request path, with any deployment base removed
|
|
335
339
|
* @param {{ activeLocale?: string, defaultLocale?: string }} [context] - defaults to the content's
|
|
@@ -415,6 +419,46 @@ function redirect(location, status, reason) {
|
|
|
415
419
|
return { kind: 'redirect', status, location, reason }
|
|
416
420
|
}
|
|
417
421
|
|
|
422
|
+
/**
|
|
423
|
+
* ⭐ **WHAT THE VISITOR ASKED WITH RIDES ALONG.** A redirect's `location` with the query and the
|
|
424
|
+
* fragment of the URL the visitor arrived at, as an HTTP redirect keeps them: the request's query
|
|
425
|
+
* unless the location names its own, and its fragment unless the location names one. So a link's
|
|
426
|
+
* parameters reach the page the visitor lands on — a campaign's tags, or a token a site's backend
|
|
427
|
+
* mails to the site's root (`/?verify=…`).
|
|
428
|
+
*
|
|
429
|
+
* ⛔ **Never onto another origin.** A query can carry a token minted for this site, so a location
|
|
430
|
+
* on another origin — another site, a locale's own domain — goes as written. Without an `origin`,
|
|
431
|
+
* every location with a scheme, or protocol-relative, is taken to be elsewhere.
|
|
432
|
+
*
|
|
433
|
+
* ⛔ Until 2026-10-11 the runtime navigated to the location alone, so on a root that redirects — an
|
|
434
|
+
* authored `redirect:`, a page with no content of its own — a mailed link lost its token before any
|
|
435
|
+
* code could read it.
|
|
436
|
+
*
|
|
437
|
+
* @param {string} location - a redirect's `location`
|
|
438
|
+
* @param {{ search?: string, hash?: string }} [request] - the request's query (`?…`) and fragment
|
|
439
|
+
* (`#…`) — a `Location` will do
|
|
440
|
+
* @param {string|null} [origin] - the site's origin (`https://example.com`)
|
|
441
|
+
* @returns {string}
|
|
442
|
+
*/
|
|
443
|
+
export function carryQuery(location, { search = '', hash = '' } = {}, origin = null) {
|
|
444
|
+
const query = search && search !== '?' ? (search.startsWith('?') ? search : `?${search}`) : ''
|
|
445
|
+
const fragment = hash && hash !== '#' ? (hash.startsWith('#') ? hash : `#${hash}`) : ''
|
|
446
|
+
if (typeof location !== 'string' || !location || (!query && !fragment)) return location
|
|
447
|
+
if (location.startsWith('//') || HAS_SCHEME.test(location)) {
|
|
448
|
+
let target = null
|
|
449
|
+
try {
|
|
450
|
+
target = origin ? new URL(location, origin) : null
|
|
451
|
+
} catch {
|
|
452
|
+
target = null
|
|
453
|
+
}
|
|
454
|
+
if (!target || target.origin !== origin) return location
|
|
455
|
+
}
|
|
456
|
+
const cut = location.indexOf('#')
|
|
457
|
+
const path = cut < 0 ? location : location.slice(0, cut)
|
|
458
|
+
const own = cut < 0 ? '' : location.slice(cut)
|
|
459
|
+
return path + (path.includes('?') ? '' : query) + (own || fragment)
|
|
460
|
+
}
|
|
461
|
+
|
|
418
462
|
const HAS_SCHEME = /^[a-z][a-z0-9+.-]*:/i
|
|
419
463
|
|
|
420
464
|
/**
|