Recipe-app main

This commit is contained in:
2026-04-09 09:14:39 +02:00
commit 962f4e4be5
10015 changed files with 2445177 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
import type { AppRouterInstance } from '../app-router-context.shared-runtime';
import type { Params } from '../../../server/request/params';
import type { NextRouter } from './router';
import React from 'react';
/** It adapts a Pages Router (`NextRouter`) to the App Router Instance. */
export declare function adaptForAppRouterInstance(pagesRouter: NextRouter): AppRouterInstance;
/**
* adaptForSearchParams transforms the ParsedURLQuery into URLSearchParams.
*
* @param router the router that contains the query.
* @returns the search params in the URLSearchParams format
*/
export declare function adaptForSearchParams(router: Pick<NextRouter, 'isReady' | 'query' | 'asPath'>): URLSearchParams;
export declare function adaptForPathParams(router: Pick<NextRouter, 'isReady' | 'pathname' | 'query' | 'asPath'>): Params | null;
export declare function PathnameContextProviderAdapter({ children, router, ...props }: React.PropsWithChildren<{
router: Pick<NextRouter, 'pathname' | 'asPath' | 'isReady' | 'isFallback'>;
isAutoExport: boolean;
}>): import("react/jsx-runtime").JSX.Element;
+136
View File
@@ -0,0 +1,136 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
PathnameContextProviderAdapter: null,
adaptForAppRouterInstance: null,
adaptForPathParams: null,
adaptForSearchParams: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
PathnameContextProviderAdapter: function() {
return PathnameContextProviderAdapter;
},
adaptForAppRouterInstance: function() {
return adaptForAppRouterInstance;
},
adaptForPathParams: function() {
return adaptForPathParams;
},
adaptForSearchParams: function() {
return adaptForSearchParams;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _hooksclientcontextsharedruntime = require("../hooks-client-context.shared-runtime");
const _utils = require("./utils");
const _aspathtosearchparams = require("./utils/as-path-to-search-params");
const _routeregex = require("./utils/route-regex");
function adaptForAppRouterInstance(pagesRouter) {
return {
back () {
pagesRouter.back();
},
forward () {
pagesRouter.forward();
},
refresh () {
pagesRouter.reload();
},
hmrRefresh () {},
push (href, { scroll } = {}) {
void pagesRouter.push(href, undefined, {
scroll
});
},
replace (href, { scroll } = {}) {
void pagesRouter.replace(href, undefined, {
scroll
});
},
prefetch (href) {
void pagesRouter.prefetch(href);
}
};
}
function adaptForSearchParams(router) {
if (!router.isReady || !router.query) {
return new URLSearchParams();
}
return (0, _aspathtosearchparams.asPathToSearchParams)(router.asPath);
}
function adaptForPathParams(router) {
if (!router.isReady || !router.query) {
return null;
}
const pathParams = {};
const routeRegex = (0, _routeregex.getRouteRegex)(router.pathname);
const keys = Object.keys(routeRegex.groups);
for (const key of keys){
pathParams[key] = router.query[key];
}
return pathParams;
}
function PathnameContextProviderAdapter({ children, router, ...props }) {
const ref = (0, _react.useRef)(props.isAutoExport);
const value = (0, _react.useMemo)(()=>{
// isAutoExport is only ever `true` on the first render from the server,
// so reset it to `false` after we read it for the first time as `true`. If
// we don't use the value, then we don't need it.
const isAutoExport = ref.current;
if (isAutoExport) {
ref.current = false;
}
// When the route is a dynamic route, we need to do more processing to
// determine if we need to stop showing the pathname.
if ((0, _utils.isDynamicRoute)(router.pathname)) {
// When the router is rendering the fallback page, it can't possibly know
// the path, so return `null` here. Read more about fallback pages over
// at:
// https://nextjs.org/docs/api-reference/data-fetching/get-static-paths#fallback-pages
if (router.isFallback) {
return null;
}
// When `isAutoExport` is true, meaning this is a page page has been
// automatically statically optimized, and the router is not ready, then
// we can't know the pathname yet. Read more about automatic static
// optimization at:
// https://nextjs.org/docs/advanced-features/automatic-static-optimization
if (isAutoExport && !router.isReady) {
return null;
}
}
// The `router.asPath` contains the pathname seen by the browser (including
// any query strings), so it should have that stripped. Read more about the
// `asPath` option over at:
// https://nextjs.org/docs/api-reference/next/router#router-object
let url;
try {
url = new URL(router.asPath, 'http://f');
} catch (_) {
// fallback to / for invalid asPath values e.g. //
return '/';
}
return url.pathname;
}, [
router.asPath,
router.isFallback,
router.isReady,
router.pathname
]);
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_hooksclientcontextsharedruntime.PathnameContext.Provider, {
value: value,
children: children
});
}
//# sourceMappingURL=adapters.js.map
File diff suppressed because one or more lines are too long
+229
View File
@@ -0,0 +1,229 @@
import type { ComponentType } from 'react';
import type { DomainLocale } from '../../../server/config';
import type { MittEmitter } from '../mitt';
import type { ParsedUrlQuery } from 'querystring';
import type { RouterEvent } from '../../../client/router';
import type { StyleSheetTuple } from '../../../client/page-loader';
import type { UrlObject } from 'url';
import type PageLoader from '../../../client/page-loader';
import type { NextPageContext, NEXT_DATA } from '../utils';
declare global {
interface Window {
__NEXT_DATA__: NEXT_DATA;
}
}
interface RouteProperties {
shallow: boolean;
}
interface TransitionOptions {
shallow?: boolean;
locale?: string | false;
scroll?: boolean;
unstable_skipClientCache?: boolean;
}
interface NextHistoryState {
url: string;
as: string;
options: TransitionOptions;
}
export type HistoryState = null | {
__NA: true;
__N?: false;
} | {
__N: false;
__NA?: false;
} | ({
__NA?: false;
__N: true;
key: string;
} & NextHistoryState);
interface MiddlewareEffectParams<T extends FetchDataOutput> {
fetchData?: () => Promise<T>;
locale?: string;
asPath: string;
router: Router;
}
export declare function matchesMiddleware<T extends FetchDataOutput>(options: MiddlewareEffectParams<T>): Promise<boolean>;
export type Url = UrlObject | string;
export type BaseRouter = {
route: string;
pathname: string;
query: ParsedUrlQuery;
asPath: string;
basePath: string;
locale?: string | undefined;
locales?: readonly string[] | undefined;
defaultLocale?: string | undefined;
domainLocales?: readonly DomainLocale[] | undefined;
isLocaleDomain: boolean;
};
export type NextRouter = BaseRouter & Pick<Router, 'push' | 'replace' | 'reload' | 'back' | 'forward' | 'prefetch' | 'beforePopState' | 'events' | 'isFallback' | 'isReady' | 'isPreview'>;
export type PrefetchOptions = {
priority?: boolean;
locale?: string | false;
unstable_skipClientCache?: boolean;
};
export type PrivateRouteInfo = (Omit<CompletePrivateRouteInfo, 'styleSheets'> & {
initial: true;
}) | CompletePrivateRouteInfo;
export type CompletePrivateRouteInfo = {
Component: ComponentType;
styleSheets: StyleSheetTuple[];
__N_SSG?: boolean;
__N_SSP?: boolean;
props?: Record<string, any>;
err?: Error;
error?: any;
route?: string;
resolvedAs?: string;
query?: ParsedUrlQuery;
};
export type AppProps = Pick<CompletePrivateRouteInfo, 'Component' | 'err'> & {
router: Router;
} & Record<string, any>;
export type AppComponent = ComponentType<AppProps>;
type Subscription = (data: PrivateRouteInfo, App: AppComponent, resetScroll: {
x: number;
y: number;
} | null) => Promise<void>;
type BeforePopStateCallback = (state: NextHistoryState) => boolean;
type ComponentLoadCancel = (() => void) | null;
type HistoryMethod = 'replaceState' | 'pushState';
interface FetchDataOutput {
dataHref: string;
json: Record<string, any> | null;
response: Response;
text: string;
cacheKey: string;
}
interface NextDataCache {
[asPath: string]: Promise<FetchDataOutput>;
}
export declare function createKey(): string;
export default class Router implements BaseRouter {
basePath: string;
/**
* Map of all components loaded in `Router`
*/
components: {
[pathname: string]: PrivateRouteInfo;
};
sdc: NextDataCache;
sbc: NextDataCache;
sub: Subscription;
clc: ComponentLoadCancel;
pageLoader: PageLoader;
_bps: BeforePopStateCallback | undefined;
events: MittEmitter<RouterEvent>;
_wrapApp: (App: AppComponent) => any;
isSsr: boolean;
_inFlightRoute?: string | undefined;
_shallow?: boolean | undefined;
locales?: readonly string[] | undefined;
defaultLocale?: string | undefined;
domainLocales?: readonly DomainLocale[] | undefined;
isReady: boolean;
isLocaleDomain: boolean;
isFirstPopStateEvent: boolean;
_initialMatchesMiddlewarePromise: Promise<boolean>;
_bfl_s?: import('../../lib/bloom-filter').BloomFilter;
_bfl_d?: import('../../lib/bloom-filter').BloomFilter;
private state;
private _key;
static events: MittEmitter<RouterEvent>;
constructor(pathname: string, query: ParsedUrlQuery, as: string, { initialProps, pageLoader, App, wrapApp, Component, err, subscription, isFallback, locale, locales, defaultLocale, domainLocales, isPreview, }: {
subscription: Subscription;
initialProps: any;
pageLoader: any;
Component: ComponentType;
App: AppComponent;
wrapApp: (WrapAppComponent: AppComponent) => any;
err?: Error;
isFallback: boolean;
locale?: string;
locales?: readonly string[];
defaultLocale?: string;
domainLocales?: readonly DomainLocale[];
isPreview?: boolean;
});
onPopState: (e: PopStateEvent) => void;
reload(): void;
/**
* Go back in history
*/
back(): void;
/**
* Go forward in history
*/
forward(): void;
/**
* Performs a `pushState` with arguments
* @param url of the route
* @param as masks `url` for the browser
* @param options object you can define `shallow` and other options
*/
push(url: Url, as?: Url, options?: TransitionOptions): Promise<boolean>;
/**
* Performs a `replaceState` with arguments
* @param url of the route
* @param as masks `url` for the browser
* @param options object you can define `shallow` and other options
*/
replace(url: Url, as?: Url, options?: TransitionOptions): Promise<boolean>;
_bfl(as: string, resolvedAs?: string, locale?: string | false, skipNavigate?: boolean): Promise<unknown>;
private change;
changeState(method: HistoryMethod, url: string, as: string, options?: TransitionOptions): void;
handleRouteInfoError(err: Error & {
code?: any;
cancelled?: boolean;
}, pathname: string, query: ParsedUrlQuery, as: string, routeProps: RouteProperties, loadErrorFail?: boolean): Promise<CompletePrivateRouteInfo>;
getRouteInfo({ route: requestedRoute, pathname, query, as, resolvedAs, routeProps, locale, hasMiddleware, isPreview, unstable_skipClientCache, isQueryUpdating, isMiddlewareRewrite, isNotFound, }: {
route: string;
pathname: string;
query: ParsedUrlQuery;
as: string;
resolvedAs: string;
hasMiddleware?: boolean;
routeProps: RouteProperties;
locale: string | undefined;
isPreview: boolean;
unstable_skipClientCache?: boolean;
isQueryUpdating?: boolean;
isMiddlewareRewrite?: boolean;
isNotFound?: boolean;
}): Promise<{
type: "redirect-external";
destination: string;
} | {
type: "redirect-internal";
newAs: string;
newUrl: string;
} | PrivateRouteInfo>;
private set;
/**
* Callback to execute before replacing router state
* @param cb callback to be executed
*/
beforePopState(cb: BeforePopStateCallback): void;
onlyAHashChange(as: string): boolean;
scrollToHash(as: string): void;
urlIsNew(asPath: string): boolean;
/**
* Prefetch page code, you may wait for the data during page rendering.
* This feature only works in production!
* @param url the href of prefetched page
* @param asPath the as path of the prefetched page
*/
prefetch(url: string, asPath?: string, options?: PrefetchOptions): Promise<void>;
fetchComponent(route: string): Promise<import("../../../client/page-loader").GoodPageCache>;
_getData<T>(fn: () => Promise<T>): Promise<T>;
getInitialProps(Component: ComponentType, ctx: NextPageContext): Promise<Record<string, any>>;
get route(): string;
get pathname(): string;
get query(): ParsedUrlQuery;
get asPath(): string;
get locale(): string | undefined;
get isFallback(): boolean;
get isPreview(): boolean;
}
export {};
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+71
View File
@@ -0,0 +1,71 @@
import { type SegmentParam } from '../utils/get-segment-param';
import { type InterceptionMarker } from '../utils/interception-routes';
export type RouteGroupAppRouteSegment = {
type: 'route-group';
name: string;
/**
* If present, this segment has an interception marker prefixing it.
*/
interceptionMarker?: InterceptionMarker;
};
export type ParallelRouteAppRouteSegment = {
type: 'parallel-route';
name: string;
/**
* If present, this segment has an interception marker prefixing it.
*/
interceptionMarker?: InterceptionMarker;
};
export type StaticAppRouteSegment = {
type: 'static';
name: string;
/**
* If present, this segment has an interception marker prefixing it.
*/
interceptionMarker?: InterceptionMarker;
};
export type DynamicAppRouteSegment = {
type: 'dynamic';
name: string;
param: SegmentParam;
/**
* If present, this segment has an interception marker prefixing it.
*/
interceptionMarker?: InterceptionMarker;
};
/**
* Represents a single segment in a route path.
* Can be either static (e.g., "blog") or dynamic (e.g., "[slug]").
*/
export type AppRouteSegment = StaticAppRouteSegment | DynamicAppRouteSegment | RouteGroupAppRouteSegment | ParallelRouteAppRouteSegment;
export type NormalizedAppRouteSegment = StaticAppRouteSegment | DynamicAppRouteSegment;
export declare function parseAppRouteSegment(segment: string): AppRouteSegment | null;
export type AppRoute = {
normalized: boolean;
pathname: string;
segments: AppRouteSegment[];
dynamicSegments: DynamicAppRouteSegment[];
interceptionMarker: InterceptionMarker | undefined;
interceptingRoute: AppRoute | undefined;
interceptedRoute: AppRoute | undefined;
};
export type NormalizedAppRoute = Omit<AppRoute, 'normalized' | 'segments'> & {
normalized: true;
segments: NormalizedAppRouteSegment[];
};
export declare function isNormalizedAppRoute(route: InterceptionAppRoute): route is NormalizedInterceptionAppRoute;
export type InterceptionAppRoute = Omit<AppRoute, 'interceptionMarker' | 'interceptingRoute' | 'interceptedRoute'> & {
interceptionMarker: InterceptionMarker;
interceptingRoute: AppRoute;
interceptedRoute: AppRoute;
};
export type NormalizedInterceptionAppRoute = Omit<InterceptionAppRoute, 'normalized' | 'segments' | 'interceptionMarker' | 'interceptingRoute' | 'interceptedRoute'> & {
normalized: true;
segments: NormalizedAppRouteSegment[];
interceptionMarker: InterceptionMarker;
interceptingRoute: NormalizedAppRoute;
interceptedRoute: NormalizedAppRoute;
};
export declare function isInterceptionAppRoute(route: NormalizedAppRoute): route is NormalizedInterceptionAppRoute;
export declare function parseAppRoute(pathname: string, normalized: true): NormalizedAppRoute;
export declare function parseAppRoute(pathname: string, normalized: false): AppRoute;
+122
View File
@@ -0,0 +1,122 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
isInterceptionAppRoute: null,
isNormalizedAppRoute: null,
parseAppRoute: null,
parseAppRouteSegment: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
isInterceptionAppRoute: function() {
return isInterceptionAppRoute;
},
isNormalizedAppRoute: function() {
return isNormalizedAppRoute;
},
parseAppRoute: function() {
return parseAppRoute;
},
parseAppRouteSegment: function() {
return parseAppRouteSegment;
}
});
const _invarianterror = require("../../invariant-error");
const _getsegmentparam = require("../utils/get-segment-param");
const _interceptionroutes = require("../utils/interception-routes");
function parseAppRouteSegment(segment) {
if (segment === '') {
return null;
}
// Check if the segment starts with an interception marker
const interceptionMarker = _interceptionroutes.INTERCEPTION_ROUTE_MARKERS.find((m)=>segment.startsWith(m));
const param = (0, _getsegmentparam.getSegmentParam)(segment);
if (param) {
return {
type: 'dynamic',
name: segment,
param,
interceptionMarker
};
} else if (segment.startsWith('(') && segment.endsWith(')')) {
return {
type: 'route-group',
name: segment,
interceptionMarker
};
} else if (segment.startsWith('@')) {
return {
type: 'parallel-route',
name: segment,
interceptionMarker
};
} else {
return {
type: 'static',
name: segment,
interceptionMarker
};
}
}
function isNormalizedAppRoute(route) {
return route.normalized;
}
function isInterceptionAppRoute(route) {
return route.interceptionMarker !== undefined && route.interceptingRoute !== undefined && route.interceptedRoute !== undefined;
}
function parseAppRoute(pathname, normalized) {
const pathnameSegments = pathname.split('/').filter(Boolean);
// Build segments array with static and dynamic segments
const segments = [];
// Parse if this is an interception route.
let interceptionMarker;
let interceptingRoute;
let interceptedRoute;
for (const segment of pathnameSegments){
// Parse the segment into an AppSegment.
const appSegment = parseAppRouteSegment(segment);
if (!appSegment) {
continue;
}
if (normalized && (appSegment.type === 'route-group' || appSegment.type === 'parallel-route')) {
throw Object.defineProperty(new _invarianterror.InvariantError(`${pathname} is being parsed as a normalized route, but it has a route group or parallel route segment.`), "__NEXT_ERROR_CODE", {
value: "E923",
enumerable: false,
configurable: true
});
}
segments.push(appSegment);
if (appSegment.interceptionMarker) {
const parts = pathname.split(appSegment.interceptionMarker);
if (parts.length !== 2) {
throw Object.defineProperty(new Error(`Invalid interception route: ${pathname}`), "__NEXT_ERROR_CODE", {
value: "E924",
enumerable: false,
configurable: true
});
}
interceptingRoute = normalized ? parseAppRoute(parts[0], true) : parseAppRoute(parts[0], false);
interceptedRoute = normalized ? parseAppRoute(parts[1], true) : parseAppRoute(parts[1], false);
interceptionMarker = appSegment.interceptionMarker;
}
}
const dynamicSegments = segments.filter((segment)=>segment.type === 'dynamic');
return {
normalized,
pathname,
segments,
dynamicSegments,
interceptionMarker,
interceptingRoute,
interceptedRoute
};
}
//# sourceMappingURL=app.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
/**
* For a given path and a locale, if the locale is given, it will prefix the
* locale. The path shouldn't be an API path. If a default locale is given the
* prefix will be omitted if the locale is already the default locale.
*/
export declare function addLocale(path: string, locale?: string | false, defaultLocale?: string, ignorePrefix?: boolean): string;
+28
View File
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "addLocale", {
enumerable: true,
get: function() {
return addLocale;
}
});
const _addpathprefix = require("./add-path-prefix");
const _pathhasprefix = require("./path-has-prefix");
function addLocale(path, locale, defaultLocale, ignorePrefix) {
// If no locale was given or the locale is the default locale, we don't need
// to prefix the path.
if (!locale || locale === defaultLocale) return path;
const lower = path.toLowerCase();
// If the path is an API path or the path already has the locale prefix, we
// don't need to prefix the path.
if (!ignorePrefix) {
if ((0, _pathhasprefix.pathHasPrefix)(lower, '/api')) return path;
if ((0, _pathhasprefix.pathHasPrefix)(lower, `/${locale.toLowerCase()}`)) return path;
}
// Add the locale prefix to the path.
return (0, _addpathprefix.addPathPrefix)(path, `/${locale}`);
}
//# sourceMappingURL=add-locale.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/add-locale.ts"],"sourcesContent":["import { addPathPrefix } from './add-path-prefix'\nimport { pathHasPrefix } from './path-has-prefix'\n\n/**\n * For a given path and a locale, if the locale is given, it will prefix the\n * locale. The path shouldn't be an API path. If a default locale is given the\n * prefix will be omitted if the locale is already the default locale.\n */\nexport function addLocale(\n path: string,\n locale?: string | false,\n defaultLocale?: string,\n ignorePrefix?: boolean\n) {\n // If no locale was given or the locale is the default locale, we don't need\n // to prefix the path.\n if (!locale || locale === defaultLocale) return path\n\n const lower = path.toLowerCase()\n\n // If the path is an API path or the path already has the locale prefix, we\n // don't need to prefix the path.\n if (!ignorePrefix) {\n if (pathHasPrefix(lower, '/api')) return path\n if (pathHasPrefix(lower, `/${locale.toLowerCase()}`)) return path\n }\n\n // Add the locale prefix to the path.\n return addPathPrefix(path, `/${locale}`)\n}\n"],"names":["addLocale","path","locale","defaultLocale","ignorePrefix","lower","toLowerCase","pathHasPrefix","addPathPrefix"],"mappings":";;;;+BAQgBA;;;eAAAA;;;+BARc;+BACA;AAOvB,SAASA,UACdC,IAAY,EACZC,MAAuB,EACvBC,aAAsB,EACtBC,YAAsB;IAEtB,4EAA4E;IAC5E,sBAAsB;IACtB,IAAI,CAACF,UAAUA,WAAWC,eAAe,OAAOF;IAEhD,MAAMI,QAAQJ,KAAKK,WAAW;IAE9B,2EAA2E;IAC3E,iCAAiC;IACjC,IAAI,CAACF,cAAc;QACjB,IAAIG,IAAAA,4BAAa,EAACF,OAAO,SAAS,OAAOJ;QACzC,IAAIM,IAAAA,4BAAa,EAACF,OAAO,CAAC,CAAC,EAAEH,OAAOI,WAAW,IAAI,GAAG,OAAOL;IAC/D;IAEA,qCAAqC;IACrC,OAAOO,IAAAA,4BAAa,EAACP,MAAM,CAAC,CAAC,EAAEC,QAAQ;AACzC","ignoreList":[0]}
@@ -0,0 +1,5 @@
/**
* Adds the provided prefix to the given path. It first ensures that the path
* is indeed starting with a slash.
*/
export declare function addPathPrefix(path: string, prefix?: string): string;
@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "addPathPrefix", {
enumerable: true,
get: function() {
return addPathPrefix;
}
});
const _parsepath = require("./parse-path");
function addPathPrefix(path, prefix) {
if (!path.startsWith('/') || !prefix) {
return path;
}
const { pathname, query, hash } = (0, _parsepath.parsePath)(path);
return `${prefix}${pathname}${query}${hash}`;
}
//# sourceMappingURL=add-path-prefix.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/add-path-prefix.ts"],"sourcesContent":["import { parsePath } from './parse-path'\n\n/**\n * Adds the provided prefix to the given path. It first ensures that the path\n * is indeed starting with a slash.\n */\nexport function addPathPrefix(path: string, prefix?: string) {\n if (!path.startsWith('/') || !prefix) {\n return path\n }\n\n const { pathname, query, hash } = parsePath(path)\n return `${prefix}${pathname}${query}${hash}`\n}\n"],"names":["addPathPrefix","path","prefix","startsWith","pathname","query","hash","parsePath"],"mappings":";;;;+BAMgBA;;;eAAAA;;;2BANU;AAMnB,SAASA,cAAcC,IAAY,EAAEC,MAAe;IACzD,IAAI,CAACD,KAAKE,UAAU,CAAC,QAAQ,CAACD,QAAQ;QACpC,OAAOD;IACT;IAEA,MAAM,EAAEG,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAE,GAAGC,IAAAA,oBAAS,EAACN;IAC5C,OAAO,GAAGC,SAASE,WAAWC,QAAQC,MAAM;AAC9C","ignoreList":[0]}
@@ -0,0 +1,6 @@
/**
* Similarly to `addPathPrefix`, this function adds a suffix at the end on the
* provided path. It also works only for paths ensuring the argument starts
* with a slash.
*/
export declare function addPathSuffix(path: string, suffix?: string): string;
@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "addPathSuffix", {
enumerable: true,
get: function() {
return addPathSuffix;
}
});
const _parsepath = require("./parse-path");
function addPathSuffix(path, suffix) {
if (!path.startsWith('/') || !suffix) {
return path;
}
const { pathname, query, hash } = (0, _parsepath.parsePath)(path);
return `${pathname}${suffix}${query}${hash}`;
}
//# sourceMappingURL=add-path-suffix.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/add-path-suffix.ts"],"sourcesContent":["import { parsePath } from './parse-path'\n\n/**\n * Similarly to `addPathPrefix`, this function adds a suffix at the end on the\n * provided path. It also works only for paths ensuring the argument starts\n * with a slash.\n */\nexport function addPathSuffix(path: string, suffix?: string) {\n if (!path.startsWith('/') || !suffix) {\n return path\n }\n\n const { pathname, query, hash } = parsePath(path)\n return `${pathname}${suffix}${query}${hash}`\n}\n"],"names":["addPathSuffix","path","suffix","startsWith","pathname","query","hash","parsePath"],"mappings":";;;;+BAOgBA;;;eAAAA;;;2BAPU;AAOnB,SAASA,cAAcC,IAAY,EAAEC,MAAe;IACzD,IAAI,CAACD,KAAKE,UAAU,CAAC,QAAQ,CAACD,QAAQ;QACpC,OAAOD;IACT;IAEA,MAAM,EAAEG,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAE,GAAGC,IAAAA,oBAAS,EAACN;IAC5C,OAAO,GAAGG,WAAWF,SAASG,QAAQC,MAAM;AAC9C","ignoreList":[0]}
+36
View File
@@ -0,0 +1,36 @@
/**
* Normalizes an app route so it represents the actual request path. Essentially
* performing the following transformations:
*
* - `/(dashboard)/user/[id]/page` to `/user/[id]`
* - `/(dashboard)/account/page` to `/account`
* - `/user/[id]/page` to `/user/[id]`
* - `/account/page` to `/account`
* - `/page` to `/`
* - `/(dashboard)/user/[id]/route` to `/user/[id]`
* - `/(dashboard)/account/route` to `/account`
* - `/user/[id]/route` to `/user/[id]`
* - `/account/route` to `/account`
* - `/route` to `/`
* - `/` to `/`
*
* @param route the app route to normalize
* @returns the normalized pathname
*/
export declare function normalizeAppPath(route: string): string;
/**
* Comparator for sorting app paths so that parallel slot paths (containing
* `/@`) come before the children/root page path. This ensures the last item
* is always the children page, which is what `renderPageComponent` reads via
* `appPaths[appPaths.length - 1]`.
*
* Without this, route group prefixes like `(group)` (char code 0x28) sort
* before `@` (0x40), causing the children page to sort first instead of last
* and leading to a manifest mismatch / 404 in webpack dev mode.
*/
export declare function compareAppPaths(a: string, b: string): number;
/**
* Strips the `.rsc` extension if it's in the pathname.
* Since this function is used on full urls it checks `?` for searchParams handling.
*/
export declare function normalizeRscURL(url: string): string;
+62
View File
@@ -0,0 +1,62 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
compareAppPaths: null,
normalizeAppPath: null,
normalizeRscURL: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
compareAppPaths: function() {
return compareAppPaths;
},
normalizeAppPath: function() {
return normalizeAppPath;
},
normalizeRscURL: function() {
return normalizeRscURL;
}
});
const _ensureleadingslash = require("../../page-path/ensure-leading-slash");
const _segment = require("../../segment");
function normalizeAppPath(route) {
return (0, _ensureleadingslash.ensureLeadingSlash)(route.split('/').reduce((pathname, segment, index, segments)=>{
// Empty segments are ignored.
if (!segment) {
return pathname;
}
// Groups are ignored.
if ((0, _segment.isGroupSegment)(segment)) {
return pathname;
}
// Parallel segments are ignored.
if (segment[0] === '@') {
return pathname;
}
// The last segment (if it's a leaf) should be ignored.
if ((segment === 'page' || segment === 'route') && index === segments.length - 1) {
return pathname;
}
return `${pathname}/${segment}`;
}, ''));
}
function compareAppPaths(a, b) {
const aHasSlot = a.includes('/@');
const bHasSlot = b.includes('/@');
if (aHasSlot && !bHasSlot) return -1;
if (!aHasSlot && bHasSlot) return 1;
return a.localeCompare(b);
}
function normalizeRscURL(url) {
return url.replace(/\.rsc($|\?)/, // $1 ensures `?` is preserved
'$1');
}
//# sourceMappingURL=app-paths.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/app-paths.ts"],"sourcesContent":["import { ensureLeadingSlash } from '../../page-path/ensure-leading-slash'\nimport { isGroupSegment } from '../../segment'\n\n/**\n * Normalizes an app route so it represents the actual request path. Essentially\n * performing the following transformations:\n *\n * - `/(dashboard)/user/[id]/page` to `/user/[id]`\n * - `/(dashboard)/account/page` to `/account`\n * - `/user/[id]/page` to `/user/[id]`\n * - `/account/page` to `/account`\n * - `/page` to `/`\n * - `/(dashboard)/user/[id]/route` to `/user/[id]`\n * - `/(dashboard)/account/route` to `/account`\n * - `/user/[id]/route` to `/user/[id]`\n * - `/account/route` to `/account`\n * - `/route` to `/`\n * - `/` to `/`\n *\n * @param route the app route to normalize\n * @returns the normalized pathname\n */\nexport function normalizeAppPath(route: string) {\n return ensureLeadingSlash(\n route.split('/').reduce((pathname, segment, index, segments) => {\n // Empty segments are ignored.\n if (!segment) {\n return pathname\n }\n\n // Groups are ignored.\n if (isGroupSegment(segment)) {\n return pathname\n }\n\n // Parallel segments are ignored.\n if (segment[0] === '@') {\n return pathname\n }\n\n // The last segment (if it's a leaf) should be ignored.\n if (\n (segment === 'page' || segment === 'route') &&\n index === segments.length - 1\n ) {\n return pathname\n }\n\n return `${pathname}/${segment}`\n }, '')\n )\n}\n\n/**\n * Comparator for sorting app paths so that parallel slot paths (containing\n * `/@`) come before the children/root page path. This ensures the last item\n * is always the children page, which is what `renderPageComponent` reads via\n * `appPaths[appPaths.length - 1]`.\n *\n * Without this, route group prefixes like `(group)` (char code 0x28) sort\n * before `@` (0x40), causing the children page to sort first instead of last\n * and leading to a manifest mismatch / 404 in webpack dev mode.\n */\nexport function compareAppPaths(a: string, b: string): number {\n const aHasSlot = a.includes('/@')\n const bHasSlot = b.includes('/@')\n if (aHasSlot && !bHasSlot) return -1\n if (!aHasSlot && bHasSlot) return 1\n return a.localeCompare(b)\n}\n\n/**\n * Strips the `.rsc` extension if it's in the pathname.\n * Since this function is used on full urls it checks `?` for searchParams handling.\n */\nexport function normalizeRscURL(url: string) {\n return url.replace(\n /\\.rsc($|\\?)/,\n // $1 ensures `?` is preserved\n '$1'\n )\n}\n"],"names":["compareAppPaths","normalizeAppPath","normalizeRscURL","route","ensureLeadingSlash","split","reduce","pathname","segment","index","segments","isGroupSegment","length","a","b","aHasSlot","includes","bHasSlot","localeCompare","url","replace"],"mappings":";;;;;;;;;;;;;;;;IA+DgBA,eAAe;eAAfA;;IAzCAC,gBAAgB;eAAhBA;;IAqDAC,eAAe;eAAfA;;;oCA3EmB;yBACJ;AAqBxB,SAASD,iBAAiBE,KAAa;IAC5C,OAAOC,IAAAA,sCAAkB,EACvBD,MAAME,KAAK,CAAC,KAAKC,MAAM,CAAC,CAACC,UAAUC,SAASC,OAAOC;QACjD,8BAA8B;QAC9B,IAAI,CAACF,SAAS;YACZ,OAAOD;QACT;QAEA,sBAAsB;QACtB,IAAII,IAAAA,uBAAc,EAACH,UAAU;YAC3B,OAAOD;QACT;QAEA,iCAAiC;QACjC,IAAIC,OAAO,CAAC,EAAE,KAAK,KAAK;YACtB,OAAOD;QACT;QAEA,uDAAuD;QACvD,IACE,AAACC,CAAAA,YAAY,UAAUA,YAAY,OAAM,KACzCC,UAAUC,SAASE,MAAM,GAAG,GAC5B;YACA,OAAOL;QACT;QAEA,OAAO,GAAGA,SAAS,CAAC,EAAEC,SAAS;IACjC,GAAG;AAEP;AAYO,SAASR,gBAAgBa,CAAS,EAAEC,CAAS;IAClD,MAAMC,WAAWF,EAAEG,QAAQ,CAAC;IAC5B,MAAMC,WAAWH,EAAEE,QAAQ,CAAC;IAC5B,IAAID,YAAY,CAACE,UAAU,OAAO,CAAC;IACnC,IAAI,CAACF,YAAYE,UAAU,OAAO;IAClC,OAAOJ,EAAEK,aAAa,CAACJ;AACzB;AAMO,SAASZ,gBAAgBiB,GAAW;IACzC,OAAOA,IAAIC,OAAO,CAChB,eACA,8BAA8B;IAC9B;AAEJ","ignoreList":[0]}
@@ -0,0 +1 @@
export declare function asPathToSearchParams(asPath: string): URLSearchParams;
@@ -0,0 +1,17 @@
// Convert router.asPath to a URLSearchParams object
// example: /dynamic/[slug]?foo=bar -> { foo: 'bar' }
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "asPathToSearchParams", {
enumerable: true,
get: function() {
return asPathToSearchParams;
}
});
function asPathToSearchParams(asPath) {
return new URL(asPath, 'http://n').searchParams;
}
//# sourceMappingURL=as-path-to-search-params.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/as-path-to-search-params.ts"],"sourcesContent":["// Convert router.asPath to a URLSearchParams object\n// example: /dynamic/[slug]?foo=bar -> { foo: 'bar' }\nexport function asPathToSearchParams(asPath: string): URLSearchParams {\n return new URL(asPath, 'http://n').searchParams\n}\n"],"names":["asPathToSearchParams","asPath","URL","searchParams"],"mappings":"AAAA,oDAAoD;AACpD,qDAAqD;;;;;+BACrCA;;;eAAAA;;;AAAT,SAASA,qBAAqBC,MAAc;IACjD,OAAO,IAAIC,IAAID,QAAQ,YAAYE,YAAY;AACjD","ignoreList":[0]}
@@ -0,0 +1 @@
export declare function computeCacheBustingSearchParam(prefetchHeader: '1' | '2' | '0' | undefined, segmentPrefetchHeader: string | string[] | undefined, stateTreeHeader: string | string[] | undefined, nextUrlHeader: string | string[] | undefined): string;
@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "computeCacheBustingSearchParam", {
enumerable: true,
get: function() {
return computeCacheBustingSearchParam;
}
});
const _hash = require("../../hash");
function computeCacheBustingSearchParam(prefetchHeader, segmentPrefetchHeader, stateTreeHeader, nextUrlHeader) {
if ((prefetchHeader === undefined || prefetchHeader === '0') && segmentPrefetchHeader === undefined && stateTreeHeader === undefined && nextUrlHeader === undefined) {
return '';
}
return (0, _hash.hexHash)([
prefetchHeader || '0',
segmentPrefetchHeader || '0',
stateTreeHeader || '0',
nextUrlHeader || '0'
].join(','));
}
//# sourceMappingURL=cache-busting-search-param.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/cache-busting-search-param.ts"],"sourcesContent":["import { hexHash } from '../../hash'\n\nexport function computeCacheBustingSearchParam(\n prefetchHeader: '1' | '2' | '0' | undefined,\n segmentPrefetchHeader: string | string[] | undefined,\n stateTreeHeader: string | string[] | undefined,\n nextUrlHeader: string | string[] | undefined\n): string {\n if (\n (prefetchHeader === undefined || prefetchHeader === '0') &&\n segmentPrefetchHeader === undefined &&\n stateTreeHeader === undefined &&\n nextUrlHeader === undefined\n ) {\n return ''\n }\n return hexHash(\n [\n prefetchHeader || '0',\n segmentPrefetchHeader || '0',\n stateTreeHeader || '0',\n nextUrlHeader || '0',\n ].join(',')\n )\n}\n"],"names":["computeCacheBustingSearchParam","prefetchHeader","segmentPrefetchHeader","stateTreeHeader","nextUrlHeader","undefined","hexHash","join"],"mappings":";;;;+BAEgBA;;;eAAAA;;;sBAFQ;AAEjB,SAASA,+BACdC,cAA2C,EAC3CC,qBAAoD,EACpDC,eAA8C,EAC9CC,aAA4C;IAE5C,IACE,AAACH,CAAAA,mBAAmBI,aAAaJ,mBAAmB,GAAE,KACtDC,0BAA0BG,aAC1BF,oBAAoBE,aACpBD,kBAAkBC,WAClB;QACA,OAAO;IACT;IACA,OAAOC,IAAAA,aAAO,EACZ;QACEL,kBAAkB;QAClBC,yBAAyB;QACzBC,mBAAmB;QACnBC,iBAAiB;KAClB,CAACG,IAAI,CAAC;AAEX","ignoreList":[0]}
@@ -0,0 +1,2 @@
import type { default as Router } from '../router';
export declare function compareRouterStates(a: Router['state'], b: Router['state']): boolean;
@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "compareRouterStates", {
enumerable: true,
get: function() {
return compareRouterStates;
}
});
function compareRouterStates(a, b) {
const stateKeys = Object.keys(a);
if (stateKeys.length !== Object.keys(b).length) return false;
for(let i = stateKeys.length; i--;){
const key = stateKeys[i];
if (key === 'query') {
const queryKeys = Object.keys(a.query);
if (queryKeys.length !== Object.keys(b.query).length) {
return false;
}
for(let j = queryKeys.length; j--;){
const queryKey = queryKeys[j];
if (!b.query.hasOwnProperty(queryKey) || a.query[queryKey] !== b.query[queryKey]) {
return false;
}
}
} else if (!b.hasOwnProperty(key) || a[key] !== b[key]) {
return false;
}
}
return true;
}
//# sourceMappingURL=compare-states.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/compare-states.ts"],"sourcesContent":["import type { default as Router } from '../router'\n\nexport function compareRouterStates(a: Router['state'], b: Router['state']) {\n const stateKeys = Object.keys(a)\n if (stateKeys.length !== Object.keys(b).length) return false\n\n for (let i = stateKeys.length; i--; ) {\n const key = stateKeys[i]\n if (key === 'query') {\n const queryKeys = Object.keys(a.query)\n if (queryKeys.length !== Object.keys(b.query).length) {\n return false\n }\n for (let j = queryKeys.length; j--; ) {\n const queryKey = queryKeys[j]\n if (\n !b.query.hasOwnProperty(queryKey) ||\n a.query[queryKey] !== b.query[queryKey]\n ) {\n return false\n }\n }\n } else if (\n !b.hasOwnProperty(key) ||\n a[key as keyof Router['state']] !== b[key as keyof Router['state']]\n ) {\n return false\n }\n }\n\n return true\n}\n"],"names":["compareRouterStates","a","b","stateKeys","Object","keys","length","i","key","queryKeys","query","j","queryKey","hasOwnProperty"],"mappings":";;;;+BAEgBA;;;eAAAA;;;AAAT,SAASA,oBAAoBC,CAAkB,EAAEC,CAAkB;IACxE,MAAMC,YAAYC,OAAOC,IAAI,CAACJ;IAC9B,IAAIE,UAAUG,MAAM,KAAKF,OAAOC,IAAI,CAACH,GAAGI,MAAM,EAAE,OAAO;IAEvD,IAAK,IAAIC,IAAIJ,UAAUG,MAAM,EAAEC,KAAO;QACpC,MAAMC,MAAML,SAAS,CAACI,EAAE;QACxB,IAAIC,QAAQ,SAAS;YACnB,MAAMC,YAAYL,OAAOC,IAAI,CAACJ,EAAES,KAAK;YACrC,IAAID,UAAUH,MAAM,KAAKF,OAAOC,IAAI,CAACH,EAAEQ,KAAK,EAAEJ,MAAM,EAAE;gBACpD,OAAO;YACT;YACA,IAAK,IAAIK,IAAIF,UAAUH,MAAM,EAAEK,KAAO;gBACpC,MAAMC,WAAWH,SAAS,CAACE,EAAE;gBAC7B,IACE,CAACT,EAAEQ,KAAK,CAACG,cAAc,CAACD,aACxBX,EAAES,KAAK,CAACE,SAAS,KAAKV,EAAEQ,KAAK,CAACE,SAAS,EACvC;oBACA,OAAO;gBACT;YACF;QACF,OAAO,IACL,CAACV,EAAEW,cAAc,CAACL,QAClBP,CAAC,CAACO,IAA6B,KAAKN,CAAC,CAACM,IAA6B,EACnE;YACA,OAAO;QACT;IACF;IAEA,OAAO;AACT","ignoreList":[0]}
@@ -0,0 +1,8 @@
/**
* Run function with `scroll-behavior: auto` applied to `<html/>`.
* This css change will be reverted after the function finishes.
*/
export declare function disableSmoothScrollDuringRouteTransition(fn: () => void, options?: {
dontForceLayout?: boolean;
onlyHashChange?: boolean;
}): void;
@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "disableSmoothScrollDuringRouteTransition", {
enumerable: true,
get: function() {
return disableSmoothScrollDuringRouteTransition;
}
});
const _warnonce = require("../../utils/warn-once");
function disableSmoothScrollDuringRouteTransition(fn, options = {}) {
// if only the hash is changed, we don't need to disable smooth scrolling
// we only care to prevent smooth scrolling when navigating to a new page to avoid jarring UX
if (options.onlyHashChange) {
fn();
return;
}
const htmlElement = document.documentElement;
const hasDataAttribute = htmlElement.dataset.scrollBehavior === 'smooth';
if (!hasDataAttribute) {
// Warn if smooth scrolling is detected but no data attribute is present
if (process.env.NODE_ENV === 'development' && getComputedStyle(htmlElement).scrollBehavior === 'smooth') {
(0, _warnonce.warnOnce)('Detected `scroll-behavior: smooth` on the `<html>` element. To disable smooth scrolling during route transitions, ' + 'add `data-scroll-behavior="smooth"` to your <html> element. ' + 'Learn more: https://nextjs.org/docs/messages/missing-data-scroll-behavior');
}
// No smooth scrolling configured, run directly without style manipulation
fn();
return;
}
// Proceed with temporarily disabling smooth scrolling
const existing = htmlElement.style.scrollBehavior;
htmlElement.style.scrollBehavior = 'auto';
if (!options.dontForceLayout) {
// In Chrome-based browsers we need to force reflow before calling `scrollTo`.
// Otherwise it will not pickup the change in scrollBehavior
// More info here: https://github.com/vercel/next.js/issues/40719#issuecomment-1336248042
htmlElement.getClientRects();
}
fn();
htmlElement.style.scrollBehavior = existing;
}
//# sourceMappingURL=disable-smooth-scroll.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/disable-smooth-scroll.ts"],"sourcesContent":["import { warnOnce } from '../../utils/warn-once'\n\n/**\n * Run function with `scroll-behavior: auto` applied to `<html/>`.\n * This css change will be reverted after the function finishes.\n */\nexport function disableSmoothScrollDuringRouteTransition(\n fn: () => void,\n options: { dontForceLayout?: boolean; onlyHashChange?: boolean } = {}\n) {\n // if only the hash is changed, we don't need to disable smooth scrolling\n // we only care to prevent smooth scrolling when navigating to a new page to avoid jarring UX\n if (options.onlyHashChange) {\n fn()\n return\n }\n\n const htmlElement = document.documentElement\n const hasDataAttribute = htmlElement.dataset.scrollBehavior === 'smooth'\n\n if (!hasDataAttribute) {\n // Warn if smooth scrolling is detected but no data attribute is present\n if (\n process.env.NODE_ENV === 'development' &&\n getComputedStyle(htmlElement).scrollBehavior === 'smooth'\n ) {\n warnOnce(\n 'Detected `scroll-behavior: smooth` on the `<html>` element. To disable smooth scrolling during route transitions, ' +\n 'add `data-scroll-behavior=\"smooth\"` to your <html> element. ' +\n 'Learn more: https://nextjs.org/docs/messages/missing-data-scroll-behavior'\n )\n }\n // No smooth scrolling configured, run directly without style manipulation\n fn()\n return\n }\n\n // Proceed with temporarily disabling smooth scrolling\n const existing = htmlElement.style.scrollBehavior\n htmlElement.style.scrollBehavior = 'auto'\n if (!options.dontForceLayout) {\n // In Chrome-based browsers we need to force reflow before calling `scrollTo`.\n // Otherwise it will not pickup the change in scrollBehavior\n // More info here: https://github.com/vercel/next.js/issues/40719#issuecomment-1336248042\n htmlElement.getClientRects()\n }\n fn()\n htmlElement.style.scrollBehavior = existing\n}\n"],"names":["disableSmoothScrollDuringRouteTransition","fn","options","onlyHashChange","htmlElement","document","documentElement","hasDataAttribute","dataset","scrollBehavior","process","env","NODE_ENV","getComputedStyle","warnOnce","existing","style","dontForceLayout","getClientRects"],"mappings":";;;;+BAMgBA;;;eAAAA;;;0BANS;AAMlB,SAASA,yCACdC,EAAc,EACdC,UAAmE,CAAC,CAAC;IAErE,yEAAyE;IACzE,6FAA6F;IAC7F,IAAIA,QAAQC,cAAc,EAAE;QAC1BF;QACA;IACF;IAEA,MAAMG,cAAcC,SAASC,eAAe;IAC5C,MAAMC,mBAAmBH,YAAYI,OAAO,CAACC,cAAc,KAAK;IAEhE,IAAI,CAACF,kBAAkB;QACrB,wEAAwE;QACxE,IACEG,QAAQC,GAAG,CAACC,QAAQ,KAAK,iBACzBC,iBAAiBT,aAAaK,cAAc,KAAK,UACjD;YACAK,IAAAA,kBAAQ,EACN,uHACE,iEACA;QAEN;QACA,0EAA0E;QAC1Eb;QACA;IACF;IAEA,sDAAsD;IACtD,MAAMc,WAAWX,YAAYY,KAAK,CAACP,cAAc;IACjDL,YAAYY,KAAK,CAACP,cAAc,GAAG;IACnC,IAAI,CAACP,QAAQe,eAAe,EAAE;QAC5B,8EAA8E;QAC9E,4DAA4D;QAC5D,yFAAyF;QACzFb,YAAYc,cAAc;IAC5B;IACAjB;IACAG,YAAYY,KAAK,CAACP,cAAc,GAAGM;AACrC","ignoreList":[0]}
@@ -0,0 +1 @@
export default function escapePathDelimiters(segment: string, escapeEncoded?: boolean): string;
@@ -0,0 +1,16 @@
// escape delimiters used by path-to-regexp
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return escapePathDelimiters;
}
});
function escapePathDelimiters(segment, escapeEncoded) {
return segment.replace(new RegExp(`([/#?]${escapeEncoded ? '|%(2f|23|3f|5c)' : ''})`, 'gi'), (char)=>encodeURIComponent(char));
}
//# sourceMappingURL=escape-path-delimiters.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/escape-path-delimiters.ts"],"sourcesContent":["// escape delimiters used by path-to-regexp\nexport default function escapePathDelimiters(\n segment: string,\n escapeEncoded?: boolean\n): string {\n return segment.replace(\n new RegExp(`([/#?]${escapeEncoded ? '|%(2f|23|3f|5c)' : ''})`, 'gi'),\n (char: string) => encodeURIComponent(char)\n )\n}\n"],"names":["escapePathDelimiters","segment","escapeEncoded","replace","RegExp","char","encodeURIComponent"],"mappings":"AAAA,2CAA2C;;;;;+BAC3C;;;eAAwBA;;;AAAT,SAASA,qBACtBC,OAAe,EACfC,aAAuB;IAEvB,OAAOD,QAAQE,OAAO,CACpB,IAAIC,OAAO,CAAC,MAAM,EAAEF,gBAAgB,oBAAoB,GAAG,CAAC,CAAC,EAAE,OAC/D,CAACG,OAAiBC,mBAAmBD;AAEzC","ignoreList":[0]}
@@ -0,0 +1,7 @@
import type { NextPathnameInfo } from './get-next-pathname-info';
interface ExtendedInfo extends NextPathnameInfo {
defaultLocale?: string;
ignorePrefix?: boolean;
}
export declare function formatNextPathnameInfo(info: ExtendedInfo): string;
export {};
@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "formatNextPathnameInfo", {
enumerable: true,
get: function() {
return formatNextPathnameInfo;
}
});
const _removetrailingslash = require("./remove-trailing-slash");
const _addpathprefix = require("./add-path-prefix");
const _addpathsuffix = require("./add-path-suffix");
const _addlocale = require("./add-locale");
function formatNextPathnameInfo(info) {
let pathname = (0, _addlocale.addLocale)(info.pathname, info.locale, info.buildId ? undefined : info.defaultLocale, info.ignorePrefix);
if (info.buildId || !info.trailingSlash) {
pathname = (0, _removetrailingslash.removeTrailingSlash)(pathname);
}
if (info.buildId) {
pathname = (0, _addpathsuffix.addPathSuffix)((0, _addpathprefix.addPathPrefix)(pathname, `/_next/data/${info.buildId}`), info.pathname === '/' ? 'index.json' : '.json');
}
pathname = (0, _addpathprefix.addPathPrefix)(pathname, info.basePath);
return !info.buildId && info.trailingSlash ? !pathname.endsWith('/') ? (0, _addpathsuffix.addPathSuffix)(pathname, '/') : pathname : (0, _removetrailingslash.removeTrailingSlash)(pathname);
}
//# sourceMappingURL=format-next-pathname-info.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/format-next-pathname-info.ts"],"sourcesContent":["import type { NextPathnameInfo } from './get-next-pathname-info'\nimport { removeTrailingSlash } from './remove-trailing-slash'\nimport { addPathPrefix } from './add-path-prefix'\nimport { addPathSuffix } from './add-path-suffix'\nimport { addLocale } from './add-locale'\n\ninterface ExtendedInfo extends NextPathnameInfo {\n defaultLocale?: string\n ignorePrefix?: boolean\n}\n\nexport function formatNextPathnameInfo(info: ExtendedInfo) {\n let pathname = addLocale(\n info.pathname,\n info.locale,\n info.buildId ? undefined : info.defaultLocale,\n info.ignorePrefix\n )\n\n if (info.buildId || !info.trailingSlash) {\n pathname = removeTrailingSlash(pathname)\n }\n\n if (info.buildId) {\n pathname = addPathSuffix(\n addPathPrefix(pathname, `/_next/data/${info.buildId}`),\n info.pathname === '/' ? 'index.json' : '.json'\n )\n }\n\n pathname = addPathPrefix(pathname, info.basePath)\n return !info.buildId && info.trailingSlash\n ? !pathname.endsWith('/')\n ? addPathSuffix(pathname, '/')\n : pathname\n : removeTrailingSlash(pathname)\n}\n"],"names":["formatNextPathnameInfo","info","pathname","addLocale","locale","buildId","undefined","defaultLocale","ignorePrefix","trailingSlash","removeTrailingSlash","addPathSuffix","addPathPrefix","basePath","endsWith"],"mappings":";;;;+BAWgBA;;;eAAAA;;;qCAVoB;+BACN;+BACA;2BACJ;AAOnB,SAASA,uBAAuBC,IAAkB;IACvD,IAAIC,WAAWC,IAAAA,oBAAS,EACtBF,KAAKC,QAAQ,EACbD,KAAKG,MAAM,EACXH,KAAKI,OAAO,GAAGC,YAAYL,KAAKM,aAAa,EAC7CN,KAAKO,YAAY;IAGnB,IAAIP,KAAKI,OAAO,IAAI,CAACJ,KAAKQ,aAAa,EAAE;QACvCP,WAAWQ,IAAAA,wCAAmB,EAACR;IACjC;IAEA,IAAID,KAAKI,OAAO,EAAE;QAChBH,WAAWS,IAAAA,4BAAa,EACtBC,IAAAA,4BAAa,EAACV,UAAU,CAAC,YAAY,EAAED,KAAKI,OAAO,EAAE,GACrDJ,KAAKC,QAAQ,KAAK,MAAM,eAAe;IAE3C;IAEAA,WAAWU,IAAAA,4BAAa,EAACV,UAAUD,KAAKY,QAAQ;IAChD,OAAO,CAACZ,KAAKI,OAAO,IAAIJ,KAAKQ,aAAa,GACtC,CAACP,SAASY,QAAQ,CAAC,OACjBH,IAAAA,4BAAa,EAACT,UAAU,OACxBA,WACFQ,IAAAA,wCAAmB,EAACR;AAC1B","ignoreList":[0]}
@@ -0,0 +1,4 @@
import type { UrlObject } from 'url';
export declare function formatUrl(urlObj: UrlObject): string;
export declare const urlObjectKeys: string[];
export declare function formatWithValidation(url: UrlObject): string;
+111
View File
@@ -0,0 +1,111 @@
// Format function modified from nodejs
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
formatUrl: null,
formatWithValidation: null,
urlObjectKeys: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
formatUrl: function() {
return formatUrl;
},
formatWithValidation: function() {
return formatWithValidation;
},
urlObjectKeys: function() {
return urlObjectKeys;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _querystring = /*#__PURE__*/ _interop_require_wildcard._(require("./querystring"));
const slashedProtocols = /https?|ftp|gopher|file/;
function formatUrl(urlObj) {
let { auth, hostname } = urlObj;
let protocol = urlObj.protocol || '';
let pathname = urlObj.pathname || '';
let hash = urlObj.hash || '';
let query = urlObj.query || '';
let host = false;
auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ':') + '@' : '';
if (urlObj.host) {
host = auth + urlObj.host;
} else if (hostname) {
host = auth + (~hostname.indexOf(':') ? `[${hostname}]` : hostname);
if (urlObj.port) {
host += ':' + urlObj.port;
}
}
if (query && typeof query === 'object') {
query = String(_querystring.urlQueryToSearchParams(query));
}
let search = urlObj.search || query && `?${query}` || '';
if (protocol && !protocol.endsWith(':')) protocol += ':';
if (urlObj.slashes || (!protocol || slashedProtocols.test(protocol)) && host !== false) {
host = '//' + (host || '');
if (pathname && pathname[0] !== '/') pathname = '/' + pathname;
} else if (!host) {
host = '';
}
if (hash && hash[0] !== '#') hash = '#' + hash;
if (search && search[0] !== '?') search = '?' + search;
pathname = pathname.replace(/[?#]/g, encodeURIComponent);
search = search.replace('#', '%23');
return `${protocol}${host}${pathname}${search}${hash}`;
}
const urlObjectKeys = [
'auth',
'hash',
'host',
'hostname',
'href',
'path',
'pathname',
'port',
'protocol',
'query',
'search',
'slashes'
];
function formatWithValidation(url) {
if (process.env.NODE_ENV === 'development') {
if (url !== null && typeof url === 'object') {
Object.keys(url).forEach((key)=>{
if (!urlObjectKeys.includes(key)) {
console.warn(`Unknown key passed via urlObject into url.format: ${key}`);
}
});
}
}
return formatUrl(url);
}
//# sourceMappingURL=format-url.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
export default function getAssetPathFromRoute(route: string, ext?: string): string;
@@ -0,0 +1,18 @@
// Translates a logical route into its pages asset path (relative from a common prefix)
// "asset path" being its javascript file, data file, prerendered html,...
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return getAssetPathFromRoute;
}
});
function getAssetPathFromRoute(route, ext = '') {
const path = route === '/' ? '/index' : /^\/index(\/|$)/.test(route) ? `/index${route}` : route;
return path + ext;
}
//# sourceMappingURL=get-asset-path-from-route.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/get-asset-path-from-route.ts"],"sourcesContent":["// Translates a logical route into its pages asset path (relative from a common prefix)\n// \"asset path\" being its javascript file, data file, prerendered html,...\nexport default function getAssetPathFromRoute(\n route: string,\n ext: string = ''\n): string {\n const path =\n route === '/'\n ? '/index'\n : /^\\/index(\\/|$)/.test(route)\n ? `/index${route}`\n : route\n return path + ext\n}\n"],"names":["getAssetPathFromRoute","route","ext","path","test"],"mappings":"AAAA,uFAAuF;AACvF,0EAA0E;;;;;+BAC1E;;;eAAwBA;;;AAAT,SAASA,sBACtBC,KAAa,EACbC,MAAc,EAAE;IAEhB,MAAMC,OACJF,UAAU,MACN,WACA,iBAAiBG,IAAI,CAACH,SACpB,CAAC,MAAM,EAAEA,OAAO,GAChBA;IACR,OAAOE,OAAOD;AAChB","ignoreList":[0]}
@@ -0,0 +1,61 @@
import type { DynamicParam } from '../../../../server/app-render/app-render';
import type { LoaderTree } from '../../../../server/lib/app-dir-module';
import type { OpaqueFallbackRouteParams } from '../../../../server/request/fallback-params';
import type { Params } from '../../../../server/request/params';
import type { DynamicParamTypesShort } from '../../app-router-types';
export declare function interpolateParallelRouteParams(loaderTree: LoaderTree, params: Params, pagePath: string, fallbackRouteParams: OpaqueFallbackRouteParams | null): Params;
/**
*
* Shared logic on client and server for creating a dynamic param value.
*
* This code needs to be shared with the client so it can extract dynamic route
* params from the URL without a server request.
*
* Because everything in this module is sent to the client, we should aim to
* keep this code as simple as possible. The special case handling for catchall
* and optional is, alas, unfortunate.
*/
export declare function getDynamicParam(interpolatedParams: Params, segmentKey: string, dynamicParamType: DynamicParamTypesShort, fallbackRouteParams: OpaqueFallbackRouteParams | null, staticSiblings: readonly string[] | null): DynamicParam;
/**
* Regular expression pattern used to match route parameters.
* Matches both single parameters and parameter groups.
* Examples:
* - `[[...slug]]` matches parameter group with key 'slug', repeat: true, optional: true
* - `[...slug]` matches parameter group with key 'slug', repeat: true, optional: false
* - `[[foo]]` matches parameter with key 'foo', repeat: false, optional: true
* - `[bar]` matches parameter with key 'bar', repeat: false, optional: false
*/
export declare const PARAMETER_PATTERN: RegExp;
/**
* Parses a given parameter from a route to a data structure that can be used
* to generate the parametrized route.
* Examples:
* - `[[...slug]]` -> `{ key: 'slug', repeat: true, optional: true }`
* - `[...slug]` -> `{ key: 'slug', repeat: true, optional: false }`
* - `[[foo]]` -> `{ key: 'foo', repeat: false, optional: true }`
* - `[bar]` -> `{ key: 'bar', repeat: false, optional: false }`
* - `fizz` -> `{ key: 'fizz', repeat: false, optional: false }`
* @param param - The parameter to parse.
* @returns The parsed parameter as a data structure.
*/
export declare function parseParameter(param: string): {
key: string;
repeat: boolean;
optional: boolean;
};
/**
* Parses a matched parameter from the PARAMETER_PATTERN regex to a data structure that can be used
* to generate the parametrized route.
* Examples:
* - `[...slug]` -> `{ key: 'slug', repeat: true, optional: true }`
* - `...slug` -> `{ key: 'slug', repeat: true, optional: false }`
* - `[foo]` -> `{ key: 'foo', repeat: false, optional: true }`
* - `bar` -> `{ key: 'bar', repeat: false, optional: false }`
* @param param - The matched parameter to parse.
* @returns The parsed parameter as a data structure.
*/
export declare function parseMatchedParameter(param: string): {
key: string;
repeat: boolean;
optional: boolean;
};
@@ -0,0 +1,174 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
PARAMETER_PATTERN: null,
getDynamicParam: null,
interpolateParallelRouteParams: null,
parseMatchedParameter: null,
parseParameter: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
PARAMETER_PATTERN: function() {
return PARAMETER_PATTERN;
},
getDynamicParam: function() {
return getDynamicParam;
},
interpolateParallelRouteParams: function() {
return interpolateParallelRouteParams;
},
parseMatchedParameter: function() {
return parseMatchedParameter;
},
parseParameter: function() {
return parseParameter;
}
});
const _invarianterror = require("../../invariant-error");
const _parseloadertree = require("./parse-loader-tree");
const _app = require("../routes/app");
const _resolveparamvalue = require("./resolve-param-value");
/**
* Gets the value of a param from the params object. This correctly handles the
* case where the param is a fallback route param and encodes the resulting
* value.
*
* @param interpolatedParams - The params object.
* @param segmentKey - The key of the segment.
* @param fallbackRouteParams - The fallback route params.
* @returns The value of the param.
*/ function getParamValue(interpolatedParams, segmentKey, fallbackRouteParams) {
let value = interpolatedParams[segmentKey];
if (fallbackRouteParams?.has(segmentKey)) {
// We know that the fallback route params has the segment key because we
// checked that above.
const [searchValue] = fallbackRouteParams.get(segmentKey);
value = searchValue;
} else if (Array.isArray(value)) {
value = value.map((i)=>encodeURIComponent(i));
} else if (typeof value === 'string') {
value = encodeURIComponent(value);
}
return value;
}
function interpolateParallelRouteParams(loaderTree, params, pagePath, fallbackRouteParams) {
const interpolated = structuredClone(params);
// Stack-based traversal with depth tracking
const stack = [
{
tree: loaderTree,
depth: 0
}
];
// Parse the route from the provided page path.
const route = (0, _app.parseAppRoute)(pagePath, true);
while(stack.length > 0){
const { tree, depth } = stack.pop();
const { segment, parallelRoutes } = (0, _parseloadertree.parseLoaderTree)(tree);
const appSegment = (0, _app.parseAppRouteSegment)(segment);
if (appSegment?.type === 'dynamic' && !interpolated.hasOwnProperty(appSegment.param.paramName) && // If the param is in the fallback route params, we don't need to
// interpolate it because it's already marked as being unknown.
!fallbackRouteParams?.has(appSegment.param.paramName)) {
const { paramName, paramType } = appSegment.param;
const paramValue = (0, _resolveparamvalue.resolveParamValue)(paramName, paramType, depth, route, interpolated);
if (paramValue !== undefined) {
interpolated[paramName] = paramValue;
} else if (paramType !== 'optional-catchall') {
throw Object.defineProperty(new _invarianterror.InvariantError(`Could not resolve param value for segment: ${paramName}`), "__NEXT_ERROR_CODE", {
value: "E932",
enumerable: false,
configurable: true
});
}
}
// Calculate next depth - increment if this is not a route group and not empty
let nextDepth = depth;
if (appSegment && appSegment.type !== 'route-group' && appSegment.type !== 'parallel-route') {
nextDepth++;
}
// Add all parallel routes to the stack for processing
for (const parallelRoute of Object.values(parallelRoutes)){
stack.push({
tree: parallelRoute,
depth: nextDepth
});
}
}
return interpolated;
}
function getDynamicParam(interpolatedParams, segmentKey, dynamicParamType, fallbackRouteParams, staticSiblings) {
let value = getParamValue(interpolatedParams, segmentKey, fallbackRouteParams);
// handle the case where an optional catchall does not have a value,
// e.g. `/dashboard/[[...slug]]` when requesting `/dashboard`
if (!value || value.length === 0) {
if (dynamicParamType === 'oc') {
return {
param: segmentKey,
value: null,
type: dynamicParamType,
treeSegment: [
segmentKey,
'',
dynamicParamType,
staticSiblings
]
};
}
throw Object.defineProperty(new _invarianterror.InvariantError(`Missing value for segment key: "${segmentKey}" with dynamic param type: ${dynamicParamType}`), "__NEXT_ERROR_CODE", {
value: "E864",
enumerable: false,
configurable: true
});
}
const paramCacheKey = Array.isArray(value) ? value.join('/') : value;
return {
param: segmentKey,
// The value that is passed to user code.
value,
// The value that is rendered in the router tree.
// TODO: If the number of static siblings exceeds some threshold (e.g.,
// dozens or hundreds), consider sending a Bloom filter instead of the full
// array to reduce payload size. The client would then use the Bloom filter
// to check membership with a small false positive rate.
treeSegment: [
segmentKey,
paramCacheKey,
dynamicParamType,
staticSiblings
],
type: dynamicParamType
};
}
const PARAMETER_PATTERN = /^([^[]*)\[((?:\[[^\]]*\])|[^\]]+)\](.*)$/;
function parseParameter(param) {
const match = param.match(PARAMETER_PATTERN);
if (!match) {
return parseMatchedParameter(param);
}
return parseMatchedParameter(match[2]);
}
function parseMatchedParameter(param) {
const optional = param.startsWith('[') && param.endsWith(']');
if (optional) {
param = param.slice(1, -1);
}
const repeat = param.startsWith('...');
if (repeat) {
param = param.slice(3);
}
return {
key: param,
repeat,
optional
};
}
//# sourceMappingURL=get-dynamic-param.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,49 @@
import type { I18NProvider } from '../../../../server/lib/i18n-provider';
export interface NextPathnameInfo {
/**
* The base path in case the pathname included it.
*/
basePath?: string;
/**
* The buildId for when the parsed URL is a data URL. Parsing it can be
* disabled with the `parseData` option.
*/
buildId?: string;
/**
* If there was a locale in the pathname, this will hold its value.
*/
locale?: string;
/**
* The processed pathname without a base path, locale, or data URL elements
* when parsing it is enabled.
*/
pathname: string;
/**
* A boolean telling if the pathname had a trailingSlash. This can be only
* true if trailingSlash is enabled.
*/
trailingSlash?: boolean;
}
interface Options {
/**
* When passed to true, this function will also parse Nextjs data URLs.
*/
parseData?: boolean;
/**
* A partial of the Next.js configuration to parse the URL.
*/
nextConfig?: {
basePath?: string;
i18n?: {
locales?: readonly string[];
} | null;
trailingSlash?: boolean;
};
/**
* If provided, this normalizer will be used to detect the locale instead of
* the default locale detection.
*/
i18nProvider?: I18NProvider;
}
export declare function getNextPathnameInfo(pathname: string, options: Options): NextPathnameInfo;
export {};
@@ -0,0 +1,52 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "getNextPathnameInfo", {
enumerable: true,
get: function() {
return getNextPathnameInfo;
}
});
const _normalizelocalepath = require("../../i18n/normalize-locale-path");
const _removepathprefix = require("./remove-path-prefix");
const _pathhasprefix = require("./path-has-prefix");
function getNextPathnameInfo(pathname, options) {
const { basePath, i18n, trailingSlash } = options.nextConfig ?? {};
const info = {
pathname,
trailingSlash: pathname !== '/' ? pathname.endsWith('/') : trailingSlash
};
if (basePath && (0, _pathhasprefix.pathHasPrefix)(info.pathname, basePath)) {
info.pathname = (0, _removepathprefix.removePathPrefix)(info.pathname, basePath);
info.basePath = basePath;
}
let pathnameNoDataPrefix = info.pathname;
if (info.pathname.startsWith('/_next/data/') && info.pathname.endsWith('.json')) {
const paths = info.pathname.replace(/^\/_next\/data\//, '').replace(/\.json$/, '').split('/');
const buildId = paths[0];
info.buildId = buildId;
pathnameNoDataPrefix = paths[1] !== 'index' ? `/${paths.slice(1).join('/')}` : '/';
// update pathname with normalized if enabled although
// we use normalized to populate locale info still
if (options.parseData === true) {
info.pathname = pathnameNoDataPrefix;
}
}
// If provided, use the locale route normalizer to detect the locale instead
// of the function below.
if (i18n) {
let result = options.i18nProvider ? options.i18nProvider.analyze(info.pathname) : (0, _normalizelocalepath.normalizeLocalePath)(info.pathname, i18n.locales);
info.locale = result.detectedLocale;
info.pathname = result.pathname ?? info.pathname;
if (!result.detectedLocale && info.buildId) {
result = options.i18nProvider ? options.i18nProvider.analyze(pathnameNoDataPrefix) : (0, _normalizelocalepath.normalizeLocalePath)(pathnameNoDataPrefix, i18n.locales);
if (result.detectedLocale) {
info.locale = result.detectedLocale;
}
}
}
return info;
}
//# sourceMappingURL=get-next-pathname-info.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
export default function getRouteFromAssetPath(assetPath: string, ext?: string): string;
@@ -0,0 +1,25 @@
// Translate a pages asset path (relative from a common prefix) back into its logical route
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, // "asset path" being its javascript file, data file, prerendered html,...
"default", {
enumerable: true,
get: function() {
return getRouteFromAssetPath;
}
});
const _isdynamic = require("./is-dynamic");
function getRouteFromAssetPath(assetPath, ext = '') {
assetPath = assetPath.replace(/\\/g, '/');
assetPath = ext && assetPath.endsWith(ext) ? assetPath.slice(0, -ext.length) : assetPath;
if (assetPath.startsWith('/index/') && !(0, _isdynamic.isDynamicRoute)(assetPath)) {
assetPath = assetPath.slice(6);
} else if (assetPath === '/index') {
assetPath = '/';
}
return assetPath;
}
//# sourceMappingURL=get-route-from-asset-path.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/get-route-from-asset-path.ts"],"sourcesContent":["// Translate a pages asset path (relative from a common prefix) back into its logical route\n\nimport { isDynamicRoute } from './is-dynamic'\n\n// \"asset path\" being its javascript file, data file, prerendered html,...\nexport default function getRouteFromAssetPath(\n assetPath: string,\n ext: string = ''\n): string {\n assetPath = assetPath.replace(/\\\\/g, '/')\n assetPath =\n ext && assetPath.endsWith(ext) ? assetPath.slice(0, -ext.length) : assetPath\n if (assetPath.startsWith('/index/') && !isDynamicRoute(assetPath)) {\n assetPath = assetPath.slice(6)\n } else if (assetPath === '/index') {\n assetPath = '/'\n }\n return assetPath\n}\n"],"names":["getRouteFromAssetPath","assetPath","ext","replace","endsWith","slice","length","startsWith","isDynamicRoute"],"mappings":"AAAA,2FAA2F;;;;;+BAI3F,0EAA0E;AAC1E;;;eAAwBA;;;2BAHO;AAGhB,SAASA,sBACtBC,SAAiB,EACjBC,MAAc,EAAE;IAEhBD,YAAYA,UAAUE,OAAO,CAAC,OAAO;IACrCF,YACEC,OAAOD,UAAUG,QAAQ,CAACF,OAAOD,UAAUI,KAAK,CAAC,GAAG,CAACH,IAAII,MAAM,IAAIL;IACrE,IAAIA,UAAUM,UAAU,CAAC,cAAc,CAACC,IAAAA,yBAAc,EAACP,YAAY;QACjEA,YAAYA,UAAUI,KAAK,CAAC;IAC9B,OAAO,IAAIJ,cAAc,UAAU;QACjCA,YAAY;IACd;IACA,OAAOA;AACT","ignoreList":[0]}
@@ -0,0 +1,14 @@
import type { DynamicParamTypes } from '../../app-router-types';
export type SegmentParam = {
paramName: string;
paramType: DynamicParamTypes;
};
/**
* Parse dynamic route segment to type of parameter
*/
export declare function getSegmentParam(segment: string): SegmentParam | null;
export declare function isCatchAll(type: DynamicParamTypes): type is 'catchall' | 'catchall-intercepted-(..)(..)' | 'catchall-intercepted-(.)' | 'catchall-intercepted-(..)' | 'catchall-intercepted-(...)' | 'optional-catchall';
export declare function getParamProperties(paramType: DynamicParamTypes): {
repeat: boolean;
optional: boolean;
};
@@ -0,0 +1,90 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
getParamProperties: null,
getSegmentParam: null,
isCatchAll: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
getParamProperties: function() {
return getParamProperties;
},
getSegmentParam: function() {
return getSegmentParam;
},
isCatchAll: function() {
return isCatchAll;
}
});
const _interceptionroutes = require("./interception-routes");
function getSegmentParam(segment) {
const interceptionMarker = _interceptionroutes.INTERCEPTION_ROUTE_MARKERS.find((marker)=>segment.startsWith(marker));
// if an interception marker is part of the path segment, we need to jump ahead
// to the relevant portion for param parsing
if (interceptionMarker) {
segment = segment.slice(interceptionMarker.length);
}
if (segment.startsWith('[[...') && segment.endsWith(']]')) {
return {
// TODO-APP: Optional catchall does not currently work with parallel routes,
// so for now aren't handling a potential interception marker.
paramType: 'optional-catchall',
paramName: segment.slice(5, -2)
};
}
if (segment.startsWith('[...') && segment.endsWith(']')) {
return {
paramType: interceptionMarker ? `catchall-intercepted-${interceptionMarker}` : 'catchall',
paramName: segment.slice(4, -1)
};
}
if (segment.startsWith('[') && segment.endsWith(']')) {
return {
paramType: interceptionMarker ? `dynamic-intercepted-${interceptionMarker}` : 'dynamic',
paramName: segment.slice(1, -1)
};
}
return null;
}
function isCatchAll(type) {
return type === 'catchall' || type === 'catchall-intercepted-(..)(..)' || type === 'catchall-intercepted-(.)' || type === 'catchall-intercepted-(..)' || type === 'catchall-intercepted-(...)' || type === 'optional-catchall';
}
function getParamProperties(paramType) {
let repeat = false;
let optional = false;
switch(paramType){
case 'catchall':
case 'catchall-intercepted-(..)(..)':
case 'catchall-intercepted-(.)':
case 'catchall-intercepted-(..)':
case 'catchall-intercepted-(...)':
repeat = true;
break;
case 'optional-catchall':
repeat = true;
optional = true;
break;
case 'dynamic':
case 'dynamic-intercepted-(..)(..)':
case 'dynamic-intercepted-(.)':
case 'dynamic-intercepted-(..)':
case 'dynamic-intercepted-(...)':
break;
default:
paramType;
}
return {
repeat,
optional
};
}
//# sourceMappingURL=get-segment-param.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/get-segment-param.tsx"],"sourcesContent":["import { INTERCEPTION_ROUTE_MARKERS } from './interception-routes'\nimport type { DynamicParamTypes } from '../../app-router-types'\n\nexport type SegmentParam = {\n paramName: string\n paramType: DynamicParamTypes\n}\n\n/**\n * Parse dynamic route segment to type of parameter\n */\nexport function getSegmentParam(segment: string): SegmentParam | null {\n const interceptionMarker = INTERCEPTION_ROUTE_MARKERS.find((marker) =>\n segment.startsWith(marker)\n )\n\n // if an interception marker is part of the path segment, we need to jump ahead\n // to the relevant portion for param parsing\n if (interceptionMarker) {\n segment = segment.slice(interceptionMarker.length)\n }\n\n if (segment.startsWith('[[...') && segment.endsWith(']]')) {\n return {\n // TODO-APP: Optional catchall does not currently work with parallel routes,\n // so for now aren't handling a potential interception marker.\n paramType: 'optional-catchall',\n paramName: segment.slice(5, -2),\n }\n }\n\n if (segment.startsWith('[...') && segment.endsWith(']')) {\n return {\n paramType: interceptionMarker\n ? `catchall-intercepted-${interceptionMarker}`\n : 'catchall',\n paramName: segment.slice(4, -1),\n }\n }\n\n if (segment.startsWith('[') && segment.endsWith(']')) {\n return {\n paramType: interceptionMarker\n ? `dynamic-intercepted-${interceptionMarker}`\n : 'dynamic',\n paramName: segment.slice(1, -1),\n }\n }\n\n return null\n}\n\nexport function isCatchAll(\n type: DynamicParamTypes\n): type is\n | 'catchall'\n | 'catchall-intercepted-(..)(..)'\n | 'catchall-intercepted-(.)'\n | 'catchall-intercepted-(..)'\n | 'catchall-intercepted-(...)'\n | 'optional-catchall' {\n return (\n type === 'catchall' ||\n type === 'catchall-intercepted-(..)(..)' ||\n type === 'catchall-intercepted-(.)' ||\n type === 'catchall-intercepted-(..)' ||\n type === 'catchall-intercepted-(...)' ||\n type === 'optional-catchall'\n )\n}\n\nexport function getParamProperties(paramType: DynamicParamTypes): {\n repeat: boolean\n optional: boolean\n} {\n let repeat = false\n let optional = false\n\n switch (paramType) {\n case 'catchall':\n case 'catchall-intercepted-(..)(..)':\n case 'catchall-intercepted-(.)':\n case 'catchall-intercepted-(..)':\n case 'catchall-intercepted-(...)':\n repeat = true\n break\n case 'optional-catchall':\n repeat = true\n optional = true\n break\n case 'dynamic':\n case 'dynamic-intercepted-(..)(..)':\n case 'dynamic-intercepted-(.)':\n case 'dynamic-intercepted-(..)':\n case 'dynamic-intercepted-(...)':\n break\n default:\n paramType satisfies never\n }\n\n return { repeat, optional }\n}\n"],"names":["getParamProperties","getSegmentParam","isCatchAll","segment","interceptionMarker","INTERCEPTION_ROUTE_MARKERS","find","marker","startsWith","slice","length","endsWith","paramType","paramName","type","repeat","optional"],"mappings":";;;;;;;;;;;;;;;;IAuEgBA,kBAAkB;eAAlBA;;IA5DAC,eAAe;eAAfA;;IAyCAC,UAAU;eAAVA;;;oCApD2B;AAWpC,SAASD,gBAAgBE,OAAe;IAC7C,MAAMC,qBAAqBC,8CAA0B,CAACC,IAAI,CAAC,CAACC,SAC1DJ,QAAQK,UAAU,CAACD;IAGrB,+EAA+E;IAC/E,4CAA4C;IAC5C,IAAIH,oBAAoB;QACtBD,UAAUA,QAAQM,KAAK,CAACL,mBAAmBM,MAAM;IACnD;IAEA,IAAIP,QAAQK,UAAU,CAAC,YAAYL,QAAQQ,QAAQ,CAAC,OAAO;QACzD,OAAO;YACL,4EAA4E;YAC5E,8DAA8D;YAC9DC,WAAW;YACXC,WAAWV,QAAQM,KAAK,CAAC,GAAG,CAAC;QAC/B;IACF;IAEA,IAAIN,QAAQK,UAAU,CAAC,WAAWL,QAAQQ,QAAQ,CAAC,MAAM;QACvD,OAAO;YACLC,WAAWR,qBACP,CAAC,qBAAqB,EAAEA,oBAAoB,GAC5C;YACJS,WAAWV,QAAQM,KAAK,CAAC,GAAG,CAAC;QAC/B;IACF;IAEA,IAAIN,QAAQK,UAAU,CAAC,QAAQL,QAAQQ,QAAQ,CAAC,MAAM;QACpD,OAAO;YACLC,WAAWR,qBACP,CAAC,oBAAoB,EAAEA,oBAAoB,GAC3C;YACJS,WAAWV,QAAQM,KAAK,CAAC,GAAG,CAAC;QAC/B;IACF;IAEA,OAAO;AACT;AAEO,SAASP,WACdY,IAAuB;IAQvB,OACEA,SAAS,cACTA,SAAS,mCACTA,SAAS,8BACTA,SAAS,+BACTA,SAAS,gCACTA,SAAS;AAEb;AAEO,SAASd,mBAAmBY,SAA4B;IAI7D,IAAIG,SAAS;IACb,IAAIC,WAAW;IAEf,OAAQJ;QACN,KAAK;QACL,KAAK;QACL,KAAK;QACL,KAAK;QACL,KAAK;YACHG,SAAS;YACT;QACF,KAAK;YACHA,SAAS;YACTC,WAAW;YACX;QACF,KAAK;QACL,KAAK;QACL,KAAK;QACL,KAAK;QACL,KAAK;YACH;QACF;YACEJ;IACJ;IAEA,OAAO;QAAEG;QAAQC;IAAS;AAC5B","ignoreList":[0]}
@@ -0,0 +1 @@
export declare const HTML_LIMITED_BOT_UA_RE: RegExp;
+17
View File
@@ -0,0 +1,17 @@
// This regex contains the bots that we need to do a blocking render for and can't safely stream the response
// due to how they parse the DOM. For example, they might explicitly check for metadata in the `head` tag, so we can't stream metadata tags after the `head` was sent.
// Note: The pattern [\w-]+-Google captures all Google crawlers with "-Google" suffix (e.g., Mediapartners-Google, AdsBot-Google, Storebot-Google)
// as well as crawlers starting with "Google-" (e.g., Google-PageRenderer, Google-InspectionTool)
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "HTML_LIMITED_BOT_UA_RE", {
enumerable: true,
get: function() {
return HTML_LIMITED_BOT_UA_RE;
}
});
const HTML_LIMITED_BOT_UA_RE = /[\w-]+-Google|Google-[\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight/i;
//# sourceMappingURL=html-bots.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/html-bots.ts"],"sourcesContent":["// This regex contains the bots that we need to do a blocking render for and can't safely stream the response\n// due to how they parse the DOM. For example, they might explicitly check for metadata in the `head` tag, so we can't stream metadata tags after the `head` was sent.\n// Note: The pattern [\\w-]+-Google captures all Google crawlers with \"-Google\" suffix (e.g., Mediapartners-Google, AdsBot-Google, Storebot-Google)\n// as well as crawlers starting with \"Google-\" (e.g., Google-PageRenderer, Google-InspectionTool)\nexport const HTML_LIMITED_BOT_UA_RE =\n /[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight/i\n"],"names":["HTML_LIMITED_BOT_UA_RE"],"mappings":"AAAA,6GAA6G;AAC7G,sKAAsK;AACtK,kJAAkJ;AAClJ,iGAAiG;;;;;+BACpFA;;;eAAAA;;;AAAN,MAAMA,yBACX","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export { getSortedRoutes, getSortedRouteObjects } from './sorted-routes';
export { isDynamicRoute } from './is-dynamic';
+30
View File
@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
getSortedRouteObjects: null,
getSortedRoutes: null,
isDynamicRoute: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
getSortedRouteObjects: function() {
return _sortedroutes.getSortedRouteObjects;
},
getSortedRoutes: function() {
return _sortedroutes.getSortedRoutes;
},
isDynamicRoute: function() {
return _isdynamic.isDynamicRoute;
}
});
const _sortedroutes = require("./sorted-routes");
const _isdynamic = require("./is-dynamic");
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/index.ts"],"sourcesContent":["export { getSortedRoutes, getSortedRouteObjects } from './sorted-routes'\nexport { isDynamicRoute } from './is-dynamic'\n"],"names":["getSortedRouteObjects","getSortedRoutes","isDynamicRoute"],"mappings":";;;;;;;;;;;;;;;;IAA0BA,qBAAqB;eAArBA,mCAAqB;;IAAtCC,eAAe;eAAfA,6BAAe;;IACfC,cAAc;eAAdA,yBAAc;;;8BADgC;2BACxB","ignoreList":[0]}
@@ -0,0 +1,2 @@
import type { DynamicParamTypes } from '../../app-router-types';
export declare function interceptionPrefixFromParamType(paramType: DynamicParamTypes): string | null;
@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "interceptionPrefixFromParamType", {
enumerable: true,
get: function() {
return interceptionPrefixFromParamType;
}
});
function interceptionPrefixFromParamType(paramType) {
switch(paramType){
case 'catchall-intercepted-(..)(..)':
case 'dynamic-intercepted-(..)(..)':
return '(..)(..)';
case 'catchall-intercepted-(.)':
case 'dynamic-intercepted-(.)':
return '(.)';
case 'catchall-intercepted-(..)':
case 'dynamic-intercepted-(..)':
return '(..)';
case 'catchall-intercepted-(...)':
case 'dynamic-intercepted-(...)':
return '(...)';
case 'catchall':
case 'dynamic':
case 'optional-catchall':
default:
return null;
}
}
//# sourceMappingURL=interception-prefix-from-param-type.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/interception-prefix-from-param-type.ts"],"sourcesContent":["import type { DynamicParamTypes } from '../../app-router-types'\n\nexport function interceptionPrefixFromParamType(\n paramType: DynamicParamTypes\n): string | null {\n switch (paramType) {\n case 'catchall-intercepted-(..)(..)':\n case 'dynamic-intercepted-(..)(..)':\n return '(..)(..)'\n case 'catchall-intercepted-(.)':\n case 'dynamic-intercepted-(.)':\n return '(.)'\n case 'catchall-intercepted-(..)':\n case 'dynamic-intercepted-(..)':\n return '(..)'\n case 'catchall-intercepted-(...)':\n case 'dynamic-intercepted-(...)':\n return '(...)'\n case 'catchall':\n case 'dynamic':\n case 'optional-catchall':\n default:\n return null\n }\n}\n"],"names":["interceptionPrefixFromParamType","paramType"],"mappings":";;;;+BAEgBA;;;eAAAA;;;AAAT,SAASA,gCACdC,SAA4B;IAE5B,OAAQA;QACN,KAAK;QACL,KAAK;YACH,OAAO;QACT,KAAK;QACL,KAAK;YACH,OAAO;QACT,KAAK;QACL,KAAK;YACH,OAAO;QACT,KAAK;QACL,KAAK;YACH,OAAO;QACT,KAAK;QACL,KAAK;QACL,KAAK;QACL;YACE,OAAO;IACX;AACF","ignoreList":[0]}
@@ -0,0 +1,18 @@
export declare const INTERCEPTION_ROUTE_MARKERS: readonly ["(..)(..)", "(.)", "(..)", "(...)"];
export type InterceptionMarker = (typeof INTERCEPTION_ROUTE_MARKERS)[number];
export declare function isInterceptionRouteAppPath(path: string): boolean;
type InterceptionRouteInformation = {
/**
* The intercepting route. This is the route that is being intercepted or the
* route that the user was coming from. This is matched by the Next-Url
* header.
*/
interceptingRoute: string;
/**
* The intercepted route. This is the route that is being intercepted or the
* route that the user is going to. This is matched by the request pathname.
*/
interceptedRoute: string;
};
export declare function extractInterceptionRouteInformation(path: string): InterceptionRouteInformation;
export {};
@@ -0,0 +1,108 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
INTERCEPTION_ROUTE_MARKERS: null,
extractInterceptionRouteInformation: null,
isInterceptionRouteAppPath: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
INTERCEPTION_ROUTE_MARKERS: function() {
return INTERCEPTION_ROUTE_MARKERS;
},
extractInterceptionRouteInformation: function() {
return extractInterceptionRouteInformation;
},
isInterceptionRouteAppPath: function() {
return isInterceptionRouteAppPath;
}
});
const _apppaths = require("./app-paths");
const INTERCEPTION_ROUTE_MARKERS = [
'(..)(..)',
'(.)',
'(..)',
'(...)'
];
function isInterceptionRouteAppPath(path) {
// TODO-APP: add more serious validation
return path.split('/').find((segment)=>INTERCEPTION_ROUTE_MARKERS.find((m)=>segment.startsWith(m))) !== undefined;
}
function extractInterceptionRouteInformation(path) {
let interceptingRoute;
let marker;
let interceptedRoute;
for (const segment of path.split('/')){
marker = INTERCEPTION_ROUTE_MARKERS.find((m)=>segment.startsWith(m));
if (marker) {
;
[interceptingRoute, interceptedRoute] = path.split(marker, 2);
break;
}
}
if (!interceptingRoute || !marker || !interceptedRoute) {
throw Object.defineProperty(new Error(`Invalid interception route: ${path}. Must be in the format /<intercepting route>/(..|...|..)(..)/<intercepted route>`), "__NEXT_ERROR_CODE", {
value: "E269",
enumerable: false,
configurable: true
});
}
interceptingRoute = (0, _apppaths.normalizeAppPath)(interceptingRoute) // normalize the path, e.g. /(blog)/feed -> /feed
;
switch(marker){
case '(.)':
// (.) indicates that we should match with sibling routes, so we just need to append the intercepted route to the intercepting route
if (interceptingRoute === '/') {
interceptedRoute = `/${interceptedRoute}`;
} else {
interceptedRoute = interceptingRoute + '/' + interceptedRoute;
}
break;
case '(..)':
// (..) indicates that we should match at one level up, so we need to remove the last segment of the intercepting route
if (interceptingRoute === '/') {
throw Object.defineProperty(new Error(`Invalid interception route: ${path}. Cannot use (..) marker at the root level, use (.) instead.`), "__NEXT_ERROR_CODE", {
value: "E207",
enumerable: false,
configurable: true
});
}
interceptedRoute = interceptingRoute.split('/').slice(0, -1).concat(interceptedRoute).join('/');
break;
case '(...)':
// (...) will match the route segment in the root directory, so we need to use the root directory to prepend the intercepted route
interceptedRoute = '/' + interceptedRoute;
break;
case '(..)(..)':
// (..)(..) indicates that we should match at two levels up, so we need to remove the last two segments of the intercepting route
const splitInterceptingRoute = interceptingRoute.split('/');
if (splitInterceptingRoute.length <= 2) {
throw Object.defineProperty(new Error(`Invalid interception route: ${path}. Cannot use (..)(..) marker at the root level or one level up.`), "__NEXT_ERROR_CODE", {
value: "E486",
enumerable: false,
configurable: true
});
}
interceptedRoute = splitInterceptingRoute.slice(0, -2).concat(interceptedRoute).join('/');
break;
default:
throw Object.defineProperty(new Error('Invariant: unexpected marker'), "__NEXT_ERROR_CODE", {
value: "E112",
enumerable: false,
configurable: true
});
}
return {
interceptingRoute,
interceptedRoute
};
}
//# sourceMappingURL=interception-routes.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
import type { ParsedUrlQuery } from 'querystring';
export declare function interpolateAs(route: string, asPathname: string, query: ParsedUrlQuery): {
params: string[];
result: string;
};
@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "interpolateAs", {
enumerable: true,
get: function() {
return interpolateAs;
}
});
const _routematcher = require("./route-matcher");
const _routeregex = require("./route-regex");
function interpolateAs(route, asPathname, query) {
let interpolatedRoute = '';
const dynamicRegex = (0, _routeregex.getRouteRegex)(route);
const dynamicGroups = dynamicRegex.groups;
const dynamicMatches = // Try to match the dynamic route against the asPath
(asPathname !== route ? (0, _routematcher.getRouteMatcher)(dynamicRegex)(asPathname) : '') || // Fall back to reading the values from the href
// TODO: should this take priority; also need to change in the router.
query;
interpolatedRoute = route;
const params = Object.keys(dynamicGroups);
if (!params.every((param)=>{
let value = dynamicMatches[param] || '';
const { repeat, optional } = dynamicGroups[param];
// support single-level catch-all
// TODO: more robust handling for user-error (passing `/`)
let replaced = `[${repeat ? '...' : ''}${param}]`;
if (optional) {
replaced = `${!value ? '/' : ''}[${replaced}]`;
}
if (repeat && !Array.isArray(value)) value = [
value
];
return (optional || param in dynamicMatches) && // Interpolate group into data URL if present
(interpolatedRoute = interpolatedRoute.replace(replaced, repeat ? value.map(// these values should be fully encoded instead of just
// path delimiter escaped since they are being inserted
// into the URL and we expect URL encoded segments
// when parsing dynamic route params
(segment)=>encodeURIComponent(segment)).join('/') : encodeURIComponent(value)) || '/');
})) {
interpolatedRoute = '' // did not satisfy all requirements
;
// n.b. We ignore this error because we handle warning for this case in
// development in the `<Link>` component directly.
}
return {
params,
result: interpolatedRoute
};
}
//# sourceMappingURL=interpolate-as.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/interpolate-as.ts"],"sourcesContent":["import type { ParsedUrlQuery } from 'querystring'\n\nimport { getRouteMatcher } from './route-matcher'\nimport { getRouteRegex } from './route-regex'\n\nexport function interpolateAs(\n route: string,\n asPathname: string,\n query: ParsedUrlQuery\n) {\n let interpolatedRoute = ''\n\n const dynamicRegex = getRouteRegex(route)\n const dynamicGroups = dynamicRegex.groups\n const dynamicMatches =\n // Try to match the dynamic route against the asPath\n (asPathname !== route ? getRouteMatcher(dynamicRegex)(asPathname) : '') ||\n // Fall back to reading the values from the href\n // TODO: should this take priority; also need to change in the router.\n query\n\n interpolatedRoute = route\n const params = Object.keys(dynamicGroups)\n\n if (\n !params.every((param) => {\n let value = dynamicMatches[param] || ''\n const { repeat, optional } = dynamicGroups[param]\n\n // support single-level catch-all\n // TODO: more robust handling for user-error (passing `/`)\n let replaced = `[${repeat ? '...' : ''}${param}]`\n if (optional) {\n replaced = `${!value ? '/' : ''}[${replaced}]`\n }\n if (repeat && !Array.isArray(value)) value = [value]\n\n return (\n (optional || param in dynamicMatches) &&\n // Interpolate group into data URL if present\n (interpolatedRoute =\n interpolatedRoute!.replace(\n replaced,\n repeat\n ? (value as string[])\n .map(\n // these values should be fully encoded instead of just\n // path delimiter escaped since they are being inserted\n // into the URL and we expect URL encoded segments\n // when parsing dynamic route params\n (segment) => encodeURIComponent(segment)\n )\n .join('/')\n : encodeURIComponent(value as string)\n ) || '/')\n )\n })\n ) {\n interpolatedRoute = '' // did not satisfy all requirements\n\n // n.b. We ignore this error because we handle warning for this case in\n // development in the `<Link>` component directly.\n }\n return {\n params,\n result: interpolatedRoute,\n }\n}\n"],"names":["interpolateAs","route","asPathname","query","interpolatedRoute","dynamicRegex","getRouteRegex","dynamicGroups","groups","dynamicMatches","getRouteMatcher","params","Object","keys","every","param","value","repeat","optional","replaced","Array","isArray","replace","map","segment","encodeURIComponent","join","result"],"mappings":";;;;+BAKgBA;;;eAAAA;;;8BAHgB;4BACF;AAEvB,SAASA,cACdC,KAAa,EACbC,UAAkB,EAClBC,KAAqB;IAErB,IAAIC,oBAAoB;IAExB,MAAMC,eAAeC,IAAAA,yBAAa,EAACL;IACnC,MAAMM,gBAAgBF,aAAaG,MAAM;IACzC,MAAMC,iBAEJ,AADA,oDAAoD;IACnDP,CAAAA,eAAeD,QAAQS,IAAAA,6BAAe,EAACL,cAAcH,cAAc,EAAC,KACrE,gDAAgD;IAChD,sEAAsE;IACtEC;IAEFC,oBAAoBH;IACpB,MAAMU,SAASC,OAAOC,IAAI,CAACN;IAE3B,IACE,CAACI,OAAOG,KAAK,CAAC,CAACC;QACb,IAAIC,QAAQP,cAAc,CAACM,MAAM,IAAI;QACrC,MAAM,EAAEE,MAAM,EAAEC,QAAQ,EAAE,GAAGX,aAAa,CAACQ,MAAM;QAEjD,iCAAiC;QACjC,0DAA0D;QAC1D,IAAII,WAAW,CAAC,CAAC,EAAEF,SAAS,QAAQ,KAAKF,MAAM,CAAC,CAAC;QACjD,IAAIG,UAAU;YACZC,WAAW,GAAG,CAACH,QAAQ,MAAM,GAAG,CAAC,EAAEG,SAAS,CAAC,CAAC;QAChD;QACA,IAAIF,UAAU,CAACG,MAAMC,OAAO,CAACL,QAAQA,QAAQ;YAACA;SAAM;QAEpD,OACE,AAACE,CAAAA,YAAYH,SAASN,cAAa,KACnC,6CAA6C;QAC5CL,CAAAA,oBACCA,kBAAmBkB,OAAO,CACxBH,UACAF,SACI,AAACD,MACEO,GAAG,CACF,uDAAuD;QACvD,uDAAuD;QACvD,kDAAkD;QAClD,oCAAoC;QACpC,CAACC,UAAYC,mBAAmBD,UAEjCE,IAAI,CAAC,OACRD,mBAAmBT,WACpB,GAAE;IAEb,IACA;QACAZ,oBAAoB,GAAG,mCAAmC;;IAE1D,uEAAuE;IACvE,kDAAkD;IACpD;IACA,OAAO;QACLO;QACAgB,QAAQvB;IACV;AACF","ignoreList":[0]}
+5
View File
@@ -0,0 +1,5 @@
import { HTML_LIMITED_BOT_UA_RE } from './html-bots';
export declare const HTML_LIMITED_BOT_UA_RE_STRING: string;
export { HTML_LIMITED_BOT_UA_RE };
export declare function isBot(userAgent: string): boolean;
export declare function getBotType(userAgent: string): 'dom' | 'html' | undefined;
+57
View File
@@ -0,0 +1,57 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
HTML_LIMITED_BOT_UA_RE: null,
HTML_LIMITED_BOT_UA_RE_STRING: null,
getBotType: null,
isBot: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
HTML_LIMITED_BOT_UA_RE: function() {
return _htmlbots.HTML_LIMITED_BOT_UA_RE;
},
HTML_LIMITED_BOT_UA_RE_STRING: function() {
return HTML_LIMITED_BOT_UA_RE_STRING;
},
getBotType: function() {
return getBotType;
},
isBot: function() {
return isBot;
}
});
const _htmlbots = require("./html-bots");
// Bot crawler that will spin up a headless browser and execute JS.
// Only the main Googlebot search crawler executes JavaScript, not other Google crawlers.
// x-ref: https://developers.google.com/search/docs/crawling-indexing/google-common-crawlers
// This regex specifically matches "Googlebot" but NOT "Mediapartners-Google", "AdsBot-Google", etc.
const HEADLESS_BROWSER_BOT_UA_RE = /Googlebot(?!-)|Googlebot$/i;
const HTML_LIMITED_BOT_UA_RE_STRING = _htmlbots.HTML_LIMITED_BOT_UA_RE.source;
function isDomBotUA(userAgent) {
return HEADLESS_BROWSER_BOT_UA_RE.test(userAgent);
}
function isHtmlLimitedBotUA(userAgent) {
return _htmlbots.HTML_LIMITED_BOT_UA_RE.test(userAgent);
}
function isBot(userAgent) {
return isDomBotUA(userAgent) || isHtmlLimitedBotUA(userAgent);
}
function getBotType(userAgent) {
if (isDomBotUA(userAgent)) {
return 'dom';
}
if (isHtmlLimitedBotUA(userAgent)) {
return 'html';
}
return undefined;
}
//# sourceMappingURL=is-bot.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/is-bot.ts"],"sourcesContent":["import { HTML_LIMITED_BOT_UA_RE } from './html-bots'\n\n// Bot crawler that will spin up a headless browser and execute JS.\n// Only the main Googlebot search crawler executes JavaScript, not other Google crawlers.\n// x-ref: https://developers.google.com/search/docs/crawling-indexing/google-common-crawlers\n// This regex specifically matches \"Googlebot\" but NOT \"Mediapartners-Google\", \"AdsBot-Google\", etc.\nconst HEADLESS_BROWSER_BOT_UA_RE = /Googlebot(?!-)|Googlebot$/i\n\nexport const HTML_LIMITED_BOT_UA_RE_STRING = HTML_LIMITED_BOT_UA_RE.source\n\nexport { HTML_LIMITED_BOT_UA_RE }\n\nfunction isDomBotUA(userAgent: string) {\n return HEADLESS_BROWSER_BOT_UA_RE.test(userAgent)\n}\n\nfunction isHtmlLimitedBotUA(userAgent: string) {\n return HTML_LIMITED_BOT_UA_RE.test(userAgent)\n}\n\nexport function isBot(userAgent: string): boolean {\n return isDomBotUA(userAgent) || isHtmlLimitedBotUA(userAgent)\n}\n\nexport function getBotType(userAgent: string): 'dom' | 'html' | undefined {\n if (isDomBotUA(userAgent)) {\n return 'dom'\n }\n if (isHtmlLimitedBotUA(userAgent)) {\n return 'html'\n }\n return undefined\n}\n"],"names":["HTML_LIMITED_BOT_UA_RE","HTML_LIMITED_BOT_UA_RE_STRING","getBotType","isBot","HEADLESS_BROWSER_BOT_UA_RE","source","isDomBotUA","userAgent","test","isHtmlLimitedBotUA","undefined"],"mappings":";;;;;;;;;;;;;;;;;IAUSA,sBAAsB;eAAtBA,gCAAsB;;IAFlBC,6BAA6B;eAA7BA;;IAgBGC,UAAU;eAAVA;;IAJAC,KAAK;eAALA;;;0BApBuB;AAEvC,mEAAmE;AACnE,yFAAyF;AACzF,4FAA4F;AAC5F,oGAAoG;AACpG,MAAMC,6BAA6B;AAE5B,MAAMH,gCAAgCD,gCAAsB,CAACK,MAAM;AAI1E,SAASC,WAAWC,SAAiB;IACnC,OAAOH,2BAA2BI,IAAI,CAACD;AACzC;AAEA,SAASE,mBAAmBF,SAAiB;IAC3C,OAAOP,gCAAsB,CAACQ,IAAI,CAACD;AACrC;AAEO,SAASJ,MAAMI,SAAiB;IACrC,OAAOD,WAAWC,cAAcE,mBAAmBF;AACrD;AAEO,SAASL,WAAWK,SAAiB;IAC1C,IAAID,WAAWC,YAAY;QACzB,OAAO;IACT;IACA,IAAIE,mBAAmBF,YAAY;QACjC,OAAO;IACT;IACA,OAAOG;AACT","ignoreList":[0]}
@@ -0,0 +1,8 @@
/**
* Check if a route is dynamic.
*
* @param route - The route to check.
* @param strict - Whether to use strict mode which prohibits segments with prefixes/suffixes (default: true).
* @returns Whether the route is dynamic.
*/
export declare function isDynamicRoute(route: string, strict?: boolean): boolean;
+26
View File
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "isDynamicRoute", {
enumerable: true,
get: function() {
return isDynamicRoute;
}
});
const _interceptionroutes = require("./interception-routes");
// Identify /.*[param].*/ in route string
const TEST_ROUTE = /\/[^/]*\[[^/]+\][^/]*(?=\/|$)/;
// Identify /[param]/ in route string
const TEST_STRICT_ROUTE = /\/\[[^/]+\](?=\/|$)/;
function isDynamicRoute(route, strict = true) {
if ((0, _interceptionroutes.isInterceptionRouteAppPath)(route)) {
route = (0, _interceptionroutes.extractInterceptionRouteInformation)(route).interceptedRoute;
}
if (strict) {
return TEST_STRICT_ROUTE.test(route);
}
return TEST_ROUTE.test(route);
}
//# sourceMappingURL=is-dynamic.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/is-dynamic.ts"],"sourcesContent":["import {\n extractInterceptionRouteInformation,\n isInterceptionRouteAppPath,\n} from './interception-routes'\n\n// Identify /.*[param].*/ in route string\nconst TEST_ROUTE = /\\/[^/]*\\[[^/]+\\][^/]*(?=\\/|$)/\n\n// Identify /[param]/ in route string\nconst TEST_STRICT_ROUTE = /\\/\\[[^/]+\\](?=\\/|$)/\n\n/**\n * Check if a route is dynamic.\n *\n * @param route - The route to check.\n * @param strict - Whether to use strict mode which prohibits segments with prefixes/suffixes (default: true).\n * @returns Whether the route is dynamic.\n */\nexport function isDynamicRoute(route: string, strict: boolean = true): boolean {\n if (isInterceptionRouteAppPath(route)) {\n route = extractInterceptionRouteInformation(route).interceptedRoute\n }\n\n if (strict) {\n return TEST_STRICT_ROUTE.test(route)\n }\n\n return TEST_ROUTE.test(route)\n}\n"],"names":["isDynamicRoute","TEST_ROUTE","TEST_STRICT_ROUTE","route","strict","isInterceptionRouteAppPath","extractInterceptionRouteInformation","interceptedRoute","test"],"mappings":";;;;+BAkBgBA;;;eAAAA;;;oCAfT;AAEP,yCAAyC;AACzC,MAAMC,aAAa;AAEnB,qCAAqC;AACrC,MAAMC,oBAAoB;AASnB,SAASF,eAAeG,KAAa,EAAEC,SAAkB,IAAI;IAClE,IAAIC,IAAAA,8CAA0B,EAACF,QAAQ;QACrCA,QAAQG,IAAAA,uDAAmC,EAACH,OAAOI,gBAAgB;IACrE;IAEA,IAAIH,QAAQ;QACV,OAAOF,kBAAkBM,IAAI,CAACL;IAChC;IAEA,OAAOF,WAAWO,IAAI,CAACL;AACzB","ignoreList":[0]}
@@ -0,0 +1,4 @@
/**
* Detects whether a given url is routable by the Next.js router (browser only).
*/
export declare function isLocalURL(url: string): boolean;
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "isLocalURL", {
enumerable: true,
get: function() {
return isLocalURL;
}
});
const _utils = require("../../utils");
const _hasbasepath = require("../../../../client/has-base-path");
function isLocalURL(url) {
// prevent a hydration mismatch on href for url with anchor refs
if (!(0, _utils.isAbsoluteUrl)(url)) return true;
try {
// absolute urls can be local if they are on the same origin
const locationOrigin = (0, _utils.getLocationOrigin)();
const resolved = new URL(url, locationOrigin);
return resolved.origin === locationOrigin && (0, _hasbasepath.hasBasePath)(resolved.pathname);
} catch (_) {
return false;
}
}
//# sourceMappingURL=is-local-url.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/is-local-url.ts"],"sourcesContent":["import { isAbsoluteUrl, getLocationOrigin } from '../../utils'\nimport { hasBasePath } from '../../../../client/has-base-path'\n\n/**\n * Detects whether a given url is routable by the Next.js router (browser only).\n */\nexport function isLocalURL(url: string): boolean {\n // prevent a hydration mismatch on href for url with anchor refs\n if (!isAbsoluteUrl(url)) return true\n try {\n // absolute urls can be local if they are on the same origin\n const locationOrigin = getLocationOrigin()\n const resolved = new URL(url, locationOrigin)\n return resolved.origin === locationOrigin && hasBasePath(resolved.pathname)\n } catch (_) {\n return false\n }\n}\n"],"names":["isLocalURL","url","isAbsoluteUrl","locationOrigin","getLocationOrigin","resolved","URL","origin","hasBasePath","pathname","_"],"mappings":";;;;+BAMgBA;;;eAAAA;;;uBANiC;6BACrB;AAKrB,SAASA,WAAWC,GAAW;IACpC,gEAAgE;IAChE,IAAI,CAACC,IAAAA,oBAAa,EAACD,MAAM,OAAO;IAChC,IAAI;QACF,4DAA4D;QAC5D,MAAME,iBAAiBC,IAAAA,wBAAiB;QACxC,MAAMC,WAAW,IAAIC,IAAIL,KAAKE;QAC9B,OAAOE,SAASE,MAAM,KAAKJ,kBAAkBK,IAAAA,wBAAW,EAACH,SAASI,QAAQ;IAC5E,EAAE,OAAOC,GAAG;QACV,OAAO;IACT;AACF","ignoreList":[0]}
@@ -0,0 +1,7 @@
import type { BaseNextRequest } from '../../../../server/base-http';
import type { ProxyMatcher } from '../../../../build/analysis/get-page-static-info';
import type { Params } from '../../../../server/request/params';
export interface MiddlewareRouteMatch {
(pathname: string | null | undefined, request: BaseNextRequest, query: Params): boolean;
}
export declare function getMiddlewareRouteMatcher(matchers: ProxyMatcher[]): MiddlewareRouteMatch;
@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "getMiddlewareRouteMatcher", {
enumerable: true,
get: function() {
return getMiddlewareRouteMatcher;
}
});
const _preparedestination = require("./prepare-destination");
function getMiddlewareRouteMatcher(matchers) {
return (pathname, req, query)=>{
for (const matcher of matchers){
const routeMatch = new RegExp(matcher.regexp).exec(pathname);
if (!routeMatch) {
continue;
}
if (matcher.has || matcher.missing) {
const hasParams = (0, _preparedestination.matchHas)(req, query, matcher.has, matcher.missing);
if (!hasParams) {
continue;
}
}
return true;
}
return false;
};
}
//# sourceMappingURL=middleware-route-matcher.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/middleware-route-matcher.ts"],"sourcesContent":["import type { BaseNextRequest } from '../../../../server/base-http'\nimport type { ProxyMatcher } from '../../../../build/analysis/get-page-static-info'\nimport type { Params } from '../../../../server/request/params'\nimport { matchHas } from './prepare-destination'\n\nexport interface MiddlewareRouteMatch {\n (\n pathname: string | null | undefined,\n request: BaseNextRequest,\n query: Params\n ): boolean\n}\n\nexport function getMiddlewareRouteMatcher(\n matchers: ProxyMatcher[]\n): MiddlewareRouteMatch {\n return (\n pathname: string | null | undefined,\n req: BaseNextRequest,\n query: Params\n ) => {\n for (const matcher of matchers) {\n const routeMatch = new RegExp(matcher.regexp).exec(pathname!)\n if (!routeMatch) {\n continue\n }\n\n if (matcher.has || matcher.missing) {\n const hasParams = matchHas(req, query, matcher.has, matcher.missing)\n if (!hasParams) {\n continue\n }\n }\n\n return true\n }\n\n return false\n }\n}\n"],"names":["getMiddlewareRouteMatcher","matchers","pathname","req","query","matcher","routeMatch","RegExp","regexp","exec","has","missing","hasParams","matchHas"],"mappings":";;;;+BAagBA;;;eAAAA;;;oCAVS;AAUlB,SAASA,0BACdC,QAAwB;IAExB,OAAO,CACLC,UACAC,KACAC;QAEA,KAAK,MAAMC,WAAWJ,SAAU;YAC9B,MAAMK,aAAa,IAAIC,OAAOF,QAAQG,MAAM,EAAEC,IAAI,CAACP;YACnD,IAAI,CAACI,YAAY;gBACf;YACF;YAEA,IAAID,QAAQK,GAAG,IAAIL,QAAQM,OAAO,EAAE;gBAClC,MAAMC,YAAYC,IAAAA,4BAAQ,EAACV,KAAKC,OAAOC,QAAQK,GAAG,EAAEL,QAAQM,OAAO;gBACnE,IAAI,CAACC,WAAW;oBACd;gBACF;YACF;YAEA,OAAO;QACT;QAEA,OAAO;IACT;AACF","ignoreList":[0]}
+3
View File
@@ -0,0 +1,3 @@
export declare function omit<T extends {
[key: string]: unknown;
}, K extends keyof T>(object: T, keys: K[]): Omit<T, K>;
+21
View File
@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "omit", {
enumerable: true,
get: function() {
return omit;
}
});
function omit(object, keys) {
const omitted = {};
Object.keys(object).forEach((key)=>{
if (!keys.includes(key)) {
omitted[key] = object[key];
}
});
return omitted;
}
//# sourceMappingURL=omit.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/omit.ts"],"sourcesContent":["export function omit<T extends { [key: string]: unknown }, K extends keyof T>(\n object: T,\n keys: K[]\n): Omit<T, K> {\n const omitted: { [key: string]: unknown } = {}\n Object.keys(object).forEach((key) => {\n if (!keys.includes(key as K)) {\n omitted[key] = object[key]\n }\n })\n return omitted as Omit<T, K>\n}\n"],"names":["omit","object","keys","omitted","Object","forEach","key","includes"],"mappings":";;;;+BAAgBA;;;eAAAA;;;AAAT,SAASA,KACdC,MAAS,EACTC,IAAS;IAET,MAAMC,UAAsC,CAAC;IAC7CC,OAAOF,IAAI,CAACD,QAAQI,OAAO,CAAC,CAACC;QAC3B,IAAI,CAACJ,KAAKK,QAAQ,CAACD,MAAW;YAC5BH,OAAO,CAACG,IAAI,GAAGL,MAAM,CAACK,IAAI;QAC5B;IACF;IACA,OAAOH;AACT","ignoreList":[0]}
@@ -0,0 +1,11 @@
import type { LoaderTree } from '../../../../server/lib/app-dir-module';
export declare function parseLoaderTree(tree: LoaderTree): {
page: import("../../../../build/webpack/loaders/metadata/types").ModuleTuple | undefined;
segment: string;
modules: import("../../../../build/webpack/loaders/next-app-loader").AppDirModules;
conventionPath: string | undefined;
parallelRoutes: {
[parallelRouterKey: string]: LoaderTree;
};
staticSiblings: readonly string[] | null;
};
@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "parseLoaderTree", {
enumerable: true,
get: function() {
return parseLoaderTree;
}
});
const _segment = require("../../segment");
function parseLoaderTree(tree) {
const [segment, parallelRoutes, modules, staticSiblings] = tree;
const { layout, template } = modules;
let { page } = modules;
// a __DEFAULT__ segment means that this route didn't match any of the
// segments in the route, so we should use the default page
page = segment === _segment.DEFAULT_SEGMENT_KEY ? modules.defaultPage : page;
const conventionPath = layout?.[1] || template?.[1] || page?.[1];
return {
page,
segment,
modules,
/* it can be either layout / template / page */ conventionPath,
parallelRoutes,
staticSiblings
};
}
//# sourceMappingURL=parse-loader-tree.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/parse-loader-tree.ts"],"sourcesContent":["import { DEFAULT_SEGMENT_KEY } from '../../segment'\nimport type { LoaderTree } from '../../../../server/lib/app-dir-module'\n\nexport function parseLoaderTree(tree: LoaderTree) {\n const [segment, parallelRoutes, modules, staticSiblings] = tree\n const { layout, template } = modules\n let { page } = modules\n // a __DEFAULT__ segment means that this route didn't match any of the\n // segments in the route, so we should use the default page\n page = segment === DEFAULT_SEGMENT_KEY ? modules.defaultPage : page\n\n const conventionPath = layout?.[1] || template?.[1] || page?.[1]\n\n return {\n page,\n segment,\n modules,\n /* it can be either layout / template / page */\n conventionPath,\n parallelRoutes,\n staticSiblings,\n }\n}\n"],"names":["parseLoaderTree","tree","segment","parallelRoutes","modules","staticSiblings","layout","template","page","DEFAULT_SEGMENT_KEY","defaultPage","conventionPath"],"mappings":";;;;+BAGgBA;;;eAAAA;;;yBAHoB;AAG7B,SAASA,gBAAgBC,IAAgB;IAC9C,MAAM,CAACC,SAASC,gBAAgBC,SAASC,eAAe,GAAGJ;IAC3D,MAAM,EAAEK,MAAM,EAAEC,QAAQ,EAAE,GAAGH;IAC7B,IAAI,EAAEI,IAAI,EAAE,GAAGJ;IACf,sEAAsE;IACtE,2DAA2D;IAC3DI,OAAON,YAAYO,4BAAmB,GAAGL,QAAQM,WAAW,GAAGF;IAE/D,MAAMG,iBAAiBL,QAAQ,CAAC,EAAE,IAAIC,UAAU,CAAC,EAAE,IAAIC,MAAM,CAAC,EAAE;IAEhE,OAAO;QACLA;QACAN;QACAE;QACA,6CAA6C,GAC7CO;QACAR;QACAE;IACF;AACF","ignoreList":[0]}
@@ -0,0 +1,10 @@
/**
* Given a path this function will find the pathname, query and hash and return
* them. This is useful to parse full paths on the client side.
* @param path A path to parse e.g. /foo/bar?id=1#hash
*/
export declare function parsePath(path: string): {
pathname: string;
query: string;
hash: string;
};
+33
View File
@@ -0,0 +1,33 @@
/**
* Given a path this function will find the pathname, query and hash and return
* them. This is useful to parse full paths on the client side.
* @param path A path to parse e.g. /foo/bar?id=1#hash
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "parsePath", {
enumerable: true,
get: function() {
return parsePath;
}
});
function parsePath(path) {
const hashIndex = path.indexOf('#');
const queryIndex = path.indexOf('?');
const hasQuery = queryIndex > -1 && (hashIndex < 0 || queryIndex < hashIndex);
if (hasQuery || hashIndex > -1) {
return {
pathname: path.substring(0, hasQuery ? queryIndex : hashIndex),
query: hasQuery ? path.substring(queryIndex, hashIndex > -1 ? hashIndex : undefined) : '',
hash: hashIndex > -1 ? path.slice(hashIndex) : ''
};
}
return {
pathname: path,
query: '',
hash: ''
};
}
//# sourceMappingURL=parse-path.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/parse-path.ts"],"sourcesContent":["/**\n * Given a path this function will find the pathname, query and hash and return\n * them. This is useful to parse full paths on the client side.\n * @param path A path to parse e.g. /foo/bar?id=1#hash\n */\nexport function parsePath(path: string) {\n const hashIndex = path.indexOf('#')\n const queryIndex = path.indexOf('?')\n const hasQuery = queryIndex > -1 && (hashIndex < 0 || queryIndex < hashIndex)\n\n if (hasQuery || hashIndex > -1) {\n return {\n pathname: path.substring(0, hasQuery ? queryIndex : hashIndex),\n query: hasQuery\n ? path.substring(queryIndex, hashIndex > -1 ? hashIndex : undefined)\n : '',\n hash: hashIndex > -1 ? path.slice(hashIndex) : '',\n }\n }\n\n return { pathname: path, query: '', hash: '' }\n}\n"],"names":["parsePath","path","hashIndex","indexOf","queryIndex","hasQuery","pathname","substring","query","undefined","hash","slice"],"mappings":"AAAA;;;;CAIC;;;;+BACeA;;;eAAAA;;;AAAT,SAASA,UAAUC,IAAY;IACpC,MAAMC,YAAYD,KAAKE,OAAO,CAAC;IAC/B,MAAMC,aAAaH,KAAKE,OAAO,CAAC;IAChC,MAAME,WAAWD,aAAa,CAAC,KAAMF,CAAAA,YAAY,KAAKE,aAAaF,SAAQ;IAE3E,IAAIG,YAAYH,YAAY,CAAC,GAAG;QAC9B,OAAO;YACLI,UAAUL,KAAKM,SAAS,CAAC,GAAGF,WAAWD,aAAaF;YACpDM,OAAOH,WACHJ,KAAKM,SAAS,CAACH,YAAYF,YAAY,CAAC,IAAIA,YAAYO,aACxD;YACJC,MAAMR,YAAY,CAAC,IAAID,KAAKU,KAAK,CAACT,aAAa;QACjD;IACF;IAEA,OAAO;QAAEI,UAAUL;QAAMO,OAAO;QAAIE,MAAM;IAAG;AAC/C","ignoreList":[0]}
@@ -0,0 +1,22 @@
import type { ParsedUrlQuery } from 'querystring';
export interface ParsedRelativeUrl {
auth: string | null;
hash: string;
host: string | null;
hostname: string | null;
href: string;
pathname: string;
port: string | null;
protocol: string | null;
query: ParsedUrlQuery;
search: string;
slashes: null;
}
/**
* Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
* (e.g. `./hello`) then at least base must be.
* Absolute urls are rejected with one exception, in the browser, absolute urls that are on
* the current origin will be parsed as relative
*/
export declare function parseRelativeUrl(url: string, base?: string, parseQuery?: true): ParsedRelativeUrl;
export declare function parseRelativeUrl(url: string, base: string | undefined, parseQuery: false): Omit<ParsedRelativeUrl, 'query'>;
@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "parseRelativeUrl", {
enumerable: true,
get: function() {
return parseRelativeUrl;
}
});
const _utils = require("../../utils");
const _querystring = require("./querystring");
function parseRelativeUrl(url, base, parseQuery = true) {
const globalBase = new URL(typeof window === 'undefined' ? 'http://n' : (0, _utils.getLocationOrigin)());
const resolvedBase = base ? new URL(base, globalBase) : url.startsWith('.') ? new URL(typeof window === 'undefined' ? 'http://n' : window.location.href) : globalBase;
const { pathname, searchParams, search, hash, href, origin } = url.startsWith('/') ? // See https://nodejs.org/api/http.html#messageurl
// Not using `origin` to support other protocols
new URL(`${resolvedBase.protocol}//${resolvedBase.host}${url}`) : new URL(url, resolvedBase);
if (origin !== globalBase.origin) {
throw Object.defineProperty(new Error(`invariant: invalid relative URL, router received ${url}`), "__NEXT_ERROR_CODE", {
value: "E159",
enumerable: false,
configurable: true
});
}
return {
auth: null,
host: null,
hostname: null,
pathname,
port: null,
protocol: null,
query: parseQuery ? (0, _querystring.searchParamsToUrlQuery)(searchParams) : undefined,
search,
hash,
href: href.slice(origin.length),
// We don't know for relative URLs at this point since we set a custom, internal
// base that isn't surfaced to users.
slashes: null
};
}
//# sourceMappingURL=parse-relative-url.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/parse-relative-url.ts"],"sourcesContent":["import type { ParsedUrlQuery } from 'querystring'\nimport { getLocationOrigin } from '../../utils'\nimport { searchParamsToUrlQuery } from './querystring'\n\nexport interface ParsedRelativeUrl {\n auth: string | null\n hash: string\n host: string | null\n hostname: string | null\n href: string\n pathname: string\n port: string | null\n protocol: string | null\n query: ParsedUrlQuery\n search: string\n slashes: null\n}\n\n/**\n * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative\n * (e.g. `./hello`) then at least base must be.\n * Absolute urls are rejected with one exception, in the browser, absolute urls that are on\n * the current origin will be parsed as relative\n */\nexport function parseRelativeUrl(\n url: string,\n base?: string,\n parseQuery?: true\n): ParsedRelativeUrl\nexport function parseRelativeUrl(\n url: string,\n base: string | undefined,\n parseQuery: false\n): Omit<ParsedRelativeUrl, 'query'>\nexport function parseRelativeUrl(\n url: string,\n base?: string,\n parseQuery = true\n): ParsedRelativeUrl | Omit<ParsedRelativeUrl, 'query'> {\n const globalBase = new URL(\n typeof window === 'undefined' ? 'http://n' : getLocationOrigin()\n )\n\n const resolvedBase = base\n ? new URL(base, globalBase)\n : url.startsWith('.')\n ? new URL(\n typeof window === 'undefined' ? 'http://n' : window.location.href\n )\n : globalBase\n\n const { pathname, searchParams, search, hash, href, origin } = url.startsWith(\n '/'\n )\n ? // 'http://localhost:3000///' would be received as '///' in Node.js' IncomingMessage\n // See https://nodejs.org/api/http.html#messageurl\n // Not using `origin` to support other protocols\n new URL(`${resolvedBase.protocol}//${resolvedBase.host}${url}`)\n : new URL(url, resolvedBase)\n\n if (origin !== globalBase.origin) {\n throw new Error(`invariant: invalid relative URL, router received ${url}`)\n }\n\n return {\n auth: null,\n host: null,\n hostname: null,\n pathname,\n port: null,\n protocol: null,\n query: parseQuery ? searchParamsToUrlQuery(searchParams) : undefined,\n search,\n hash,\n href: href.slice(origin.length),\n // We don't know for relative URLs at this point since we set a custom, internal\n // base that isn't surfaced to users.\n slashes: null,\n }\n}\n"],"names":["parseRelativeUrl","url","base","parseQuery","globalBase","URL","window","getLocationOrigin","resolvedBase","startsWith","location","href","pathname","searchParams","search","hash","origin","protocol","host","Error","auth","hostname","port","query","searchParamsToUrlQuery","undefined","slice","length","slashes"],"mappings":";;;;+BAkCgBA;;;eAAAA;;;uBAjCkB;6BACK;AAgChC,SAASA,iBACdC,GAAW,EACXC,IAAa,EACbC,aAAa,IAAI;IAEjB,MAAMC,aAAa,IAAIC,IACrB,OAAOC,WAAW,cAAc,aAAaC,IAAAA,wBAAiB;IAGhE,MAAMC,eAAeN,OACjB,IAAIG,IAAIH,MAAME,cACdH,IAAIQ,UAAU,CAAC,OACb,IAAIJ,IACF,OAAOC,WAAW,cAAc,aAAaA,OAAOI,QAAQ,CAACC,IAAI,IAEnEP;IAEN,MAAM,EAAEQ,QAAQ,EAAEC,YAAY,EAAEC,MAAM,EAAEC,IAAI,EAAEJ,IAAI,EAAEK,MAAM,EAAE,GAAGf,IAAIQ,UAAU,CAC3E,OAGE,kDAAkD;IAClD,gDAAgD;IAChD,IAAIJ,IAAI,GAAGG,aAAaS,QAAQ,CAAC,EAAE,EAAET,aAAaU,IAAI,GAAGjB,KAAK,IAC9D,IAAII,IAAIJ,KAAKO;IAEjB,IAAIQ,WAAWZ,WAAWY,MAAM,EAAE;QAChC,MAAM,qBAAoE,CAApE,IAAIG,MAAM,CAAC,iDAAiD,EAAElB,KAAK,GAAnE,qBAAA;mBAAA;wBAAA;0BAAA;QAAmE;IAC3E;IAEA,OAAO;QACLmB,MAAM;QACNF,MAAM;QACNG,UAAU;QACVT;QACAU,MAAM;QACNL,UAAU;QACVM,OAAOpB,aAAaqB,IAAAA,mCAAsB,EAACX,gBAAgBY;QAC3DX;QACAC;QACAJ,MAAMA,KAAKe,KAAK,CAACV,OAAOW,MAAM;QAC9B,gFAAgF;QAChF,qCAAqC;QACrCC,SAAS;IACX;AACF","ignoreList":[0]}
+15
View File
@@ -0,0 +1,15 @@
import type { ParsedUrlQuery } from 'querystring';
export interface ParsedUrl {
auth: string | null;
hash: string;
hostname: string | null;
href: string;
origin?: string | null;
pathname: string;
port: string | null;
protocol: string | null;
query: ParsedUrlQuery;
search: string;
slashes: boolean | null;
}
export declare function parseUrl(url: string): ParsedUrl;
+38
View File
@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "parseUrl", {
enumerable: true,
get: function() {
return parseUrl;
}
});
const _querystring = require("./querystring");
const _parserelativeurl = require("./parse-relative-url");
function parseUrl(url) {
if (url.startsWith('/')) {
return (0, _parserelativeurl.parseRelativeUrl)(url);
}
const parsedURL = new URL(url);
const username = parsedURL.username;
const password = parsedURL.password;
const auth = username ? password ? `${username}:${password}` : username : null;
const pathname = parsedURL.pathname;
const search = parsedURL.search;
return {
auth,
hash: parsedURL.hash,
hostname: parsedURL.hostname,
href: parsedURL.href,
pathname,
port: parsedURL.port,
protocol: parsedURL.protocol,
query: (0, _querystring.searchParamsToUrlQuery)(parsedURL.searchParams),
search,
origin: parsedURL.origin,
slashes: parsedURL.href.slice(parsedURL.protocol.length, parsedURL.protocol.length + 2) === '//'
};
}
//# sourceMappingURL=parse-url.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/parse-url.ts"],"sourcesContent":["import type { ParsedUrlQuery } from 'querystring'\n\nimport { searchParamsToUrlQuery } from './querystring'\nimport { parseRelativeUrl } from './parse-relative-url'\n\nexport interface ParsedUrl {\n auth: string | null\n hash: string\n hostname: string | null\n href: string\n origin?: string | null\n pathname: string\n port: string | null\n protocol: string | null\n query: ParsedUrlQuery\n search: string\n slashes: boolean | null\n}\n\nexport function parseUrl(url: string): ParsedUrl {\n if (url.startsWith('/')) {\n return parseRelativeUrl(url)\n }\n\n const parsedURL = new URL(url)\n const username = parsedURL.username\n const password = parsedURL.password\n const auth = username\n ? password\n ? `${username}:${password}`\n : username\n : null\n const pathname = parsedURL.pathname\n const search = parsedURL.search\n return {\n auth,\n hash: parsedURL.hash,\n hostname: parsedURL.hostname,\n href: parsedURL.href,\n pathname,\n port: parsedURL.port,\n protocol: parsedURL.protocol,\n query: searchParamsToUrlQuery(parsedURL.searchParams),\n search,\n origin: parsedURL.origin,\n slashes:\n parsedURL.href.slice(\n parsedURL.protocol.length,\n parsedURL.protocol.length + 2\n ) === '//',\n }\n}\n"],"names":["parseUrl","url","startsWith","parseRelativeUrl","parsedURL","URL","username","password","auth","pathname","search","hash","hostname","href","port","protocol","query","searchParamsToUrlQuery","searchParams","origin","slashes","slice","length"],"mappings":";;;;+BAmBgBA;;;eAAAA;;;6BAjBuB;kCACN;AAgB1B,SAASA,SAASC,GAAW;IAClC,IAAIA,IAAIC,UAAU,CAAC,MAAM;QACvB,OAAOC,IAAAA,kCAAgB,EAACF;IAC1B;IAEA,MAAMG,YAAY,IAAIC,IAAIJ;IAC1B,MAAMK,WAAWF,UAAUE,QAAQ;IACnC,MAAMC,WAAWH,UAAUG,QAAQ;IACnC,MAAMC,OAAOF,WACTC,WACE,GAAGD,SAAS,CAAC,EAAEC,UAAU,GACzBD,WACF;IACJ,MAAMG,WAAWL,UAAUK,QAAQ;IACnC,MAAMC,SAASN,UAAUM,MAAM;IAC/B,OAAO;QACLF;QACAG,MAAMP,UAAUO,IAAI;QACpBC,UAAUR,UAAUQ,QAAQ;QAC5BC,MAAMT,UAAUS,IAAI;QACpBJ;QACAK,MAAMV,UAAUU,IAAI;QACpBC,UAAUX,UAAUW,QAAQ;QAC5BC,OAAOC,IAAAA,mCAAsB,EAACb,UAAUc,YAAY;QACpDR;QACAS,QAAQf,UAAUe,MAAM;QACxBC,SACEhB,UAAUS,IAAI,CAACQ,KAAK,CAClBjB,UAAUW,QAAQ,CAACO,MAAM,EACzBlB,UAAUW,QAAQ,CAACO,MAAM,GAAG,OACxB;IACV;AACF","ignoreList":[0]}
@@ -0,0 +1,8 @@
/**
* Checks if a given path starts with a given prefix. It ensures it matches
* exactly without containing extra chars. e.g. prefix /docs should replace
* for /docs, /docs/, /docs/a but not /docsss
* @param path The path to check.
* @param prefix The prefix to check against.
*/
export declare function pathHasPrefix(path: string, prefix: string): boolean;

Some files were not shown because too many files have changed in this diff Show More