feat(blog): add file-based blog with dynamic slugs, MDX content and layout shell
- Introduced blog routing using Next.js App Router - Implemented dynamic [slug] pages for blog posts - Added MDX-based content loading via lib/posts - Integrated shared TopBar layout with navigation - Established clear content, lib and component separation
This commit is contained in:
323
apps/public-web/node_modules/next/dist/server/server-utils.js
generated
vendored
Normal file
323
apps/public-web/node_modules/next/dist/server/server-utils.js
generated
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
0 && (module.exports = {
|
||||
getPreviouslyRevalidatedTags: null,
|
||||
getServerUtils: null,
|
||||
interpolateDynamicPath: null,
|
||||
normalizeCdnUrl: null,
|
||||
normalizeDynamicRouteParams: null
|
||||
});
|
||||
function _export(target, all) {
|
||||
for(var name in all)Object.defineProperty(target, name, {
|
||||
enumerable: true,
|
||||
get: all[name]
|
||||
});
|
||||
}
|
||||
_export(exports, {
|
||||
getPreviouslyRevalidatedTags: function() {
|
||||
return getPreviouslyRevalidatedTags;
|
||||
},
|
||||
getServerUtils: function() {
|
||||
return getServerUtils;
|
||||
},
|
||||
interpolateDynamicPath: function() {
|
||||
return interpolateDynamicPath;
|
||||
},
|
||||
normalizeCdnUrl: function() {
|
||||
return normalizeCdnUrl;
|
||||
},
|
||||
normalizeDynamicRouteParams: function() {
|
||||
return normalizeDynamicRouteParams;
|
||||
}
|
||||
});
|
||||
const _normalizelocalepath = require("../shared/lib/i18n/normalize-locale-path");
|
||||
const _pathmatch = require("../shared/lib/router/utils/path-match");
|
||||
const _routeregex = require("../shared/lib/router/utils/route-regex");
|
||||
const _routematcher = require("../shared/lib/router/utils/route-matcher");
|
||||
const _preparedestination = require("../shared/lib/router/utils/prepare-destination");
|
||||
const _removetrailingslash = require("../shared/lib/router/utils/remove-trailing-slash");
|
||||
const _apppaths = require("../shared/lib/router/utils/app-paths");
|
||||
const _constants = require("../lib/constants");
|
||||
const _utils = require("./web/utils");
|
||||
const _decodequerypathparameter = require("./lib/decode-query-path-parameter");
|
||||
const _url = require("../lib/url");
|
||||
const _formaturl = require("../shared/lib/router/utils/format-url");
|
||||
function filterInternalQuery(query, paramKeys) {
|
||||
// this is used to pass query information in rewrites
|
||||
// but should not be exposed in final query
|
||||
delete query['nextInternalLocale'];
|
||||
for(const key in query){
|
||||
const isNextQueryPrefix = key !== _constants.NEXT_QUERY_PARAM_PREFIX && key.startsWith(_constants.NEXT_QUERY_PARAM_PREFIX);
|
||||
const isNextInterceptionMarkerPrefix = key !== _constants.NEXT_INTERCEPTION_MARKER_PREFIX && key.startsWith(_constants.NEXT_INTERCEPTION_MARKER_PREFIX);
|
||||
if (isNextQueryPrefix || isNextInterceptionMarkerPrefix || paramKeys.includes(key)) {
|
||||
delete query[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
function normalizeCdnUrl(req, paramKeys) {
|
||||
// make sure to normalize req.url from CDNs to strip dynamic and rewrite
|
||||
// params from the query which are added during routing
|
||||
const _parsedUrl = (0, _url.parseReqUrl)(req.url);
|
||||
// we can't normalize if we can't parse
|
||||
if (!_parsedUrl) {
|
||||
return req.url;
|
||||
}
|
||||
delete _parsedUrl.search;
|
||||
filterInternalQuery(_parsedUrl.query, paramKeys);
|
||||
req.url = (0, _formaturl.formatUrl)(_parsedUrl);
|
||||
}
|
||||
function interpolateDynamicPath(pathname, params, defaultRouteRegex) {
|
||||
if (!defaultRouteRegex) return pathname;
|
||||
for (const param of Object.keys(defaultRouteRegex.groups)){
|
||||
const { optional, repeat } = defaultRouteRegex.groups[param];
|
||||
let builtParam = `[${repeat ? '...' : ''}${param}]`;
|
||||
if (optional) {
|
||||
builtParam = `[${builtParam}]`;
|
||||
}
|
||||
let paramValue;
|
||||
const value = params[param];
|
||||
if (Array.isArray(value)) {
|
||||
paramValue = value.map((v)=>v && encodeURIComponent(v)).join('/');
|
||||
} else if (value) {
|
||||
paramValue = encodeURIComponent(value);
|
||||
} else {
|
||||
paramValue = '';
|
||||
}
|
||||
if (paramValue || optional) {
|
||||
pathname = pathname.replaceAll(builtParam, paramValue);
|
||||
}
|
||||
}
|
||||
return pathname;
|
||||
}
|
||||
function normalizeDynamicRouteParams(query, defaultRouteRegex, defaultRouteMatches, ignoreMissingOptional) {
|
||||
let hasValidParams = true;
|
||||
let params = {};
|
||||
for (const key of Object.keys(defaultRouteRegex.groups)){
|
||||
let value = query[key];
|
||||
if (typeof value === 'string') {
|
||||
value = (0, _apppaths.normalizeRscURL)(value);
|
||||
} else if (Array.isArray(value)) {
|
||||
value = value.map(_apppaths.normalizeRscURL);
|
||||
}
|
||||
// if the value matches the default value we can't rely
|
||||
// on the parsed params, this is used to signal if we need
|
||||
// to parse x-now-route-matches or not
|
||||
const defaultValue = defaultRouteMatches[key];
|
||||
const isOptional = defaultRouteRegex.groups[key].optional;
|
||||
const isDefaultValue = Array.isArray(defaultValue) ? defaultValue.some((defaultVal)=>{
|
||||
return Array.isArray(value) ? value.some((val)=>val.includes(defaultVal)) : value == null ? void 0 : value.includes(defaultVal);
|
||||
}) : value == null ? void 0 : value.includes(defaultValue);
|
||||
if (isDefaultValue || typeof value === 'undefined' && !(isOptional && ignoreMissingOptional)) {
|
||||
return {
|
||||
params: {},
|
||||
hasValidParams: false
|
||||
};
|
||||
}
|
||||
// non-provided optional values should be undefined so normalize
|
||||
// them to undefined
|
||||
if (isOptional && (!value || Array.isArray(value) && value.length === 1 && // fallback optional catch-all SSG pages have
|
||||
// [[...paramName]] for the root path on Vercel
|
||||
(value[0] === 'index' || value[0] === `[[...${key}]]`) || value === 'index' || value === `[[...${key}]]`)) {
|
||||
value = undefined;
|
||||
delete query[key];
|
||||
}
|
||||
// query values from the proxy aren't already split into arrays
|
||||
// so make sure to normalize catch-all values
|
||||
if (value && typeof value === 'string' && defaultRouteRegex.groups[key].repeat) {
|
||||
value = value.split('/');
|
||||
}
|
||||
if (value) {
|
||||
params[key] = value;
|
||||
}
|
||||
}
|
||||
return {
|
||||
params,
|
||||
hasValidParams
|
||||
};
|
||||
}
|
||||
function getServerUtils({ page, i18n, basePath, rewrites, pageIsDynamic, trailingSlash, caseSensitive }) {
|
||||
let defaultRouteRegex;
|
||||
let dynamicRouteMatcher;
|
||||
let defaultRouteMatches;
|
||||
if (pageIsDynamic) {
|
||||
defaultRouteRegex = (0, _routeregex.getNamedRouteRegex)(page, {
|
||||
prefixRouteKeys: false
|
||||
});
|
||||
dynamicRouteMatcher = (0, _routematcher.getRouteMatcher)(defaultRouteRegex);
|
||||
defaultRouteMatches = dynamicRouteMatcher(page);
|
||||
}
|
||||
function handleRewrites(req, parsedUrl) {
|
||||
// Here we deep clone the parsedUrl to avoid mutating the original. We also
|
||||
// cast this to a mutable type so we can mutate it within this scope.
|
||||
const rewrittenParsedUrl = structuredClone(parsedUrl);
|
||||
const rewriteParams = {};
|
||||
let fsPathname = rewrittenParsedUrl.pathname;
|
||||
const matchesPage = ()=>{
|
||||
const fsPathnameNoSlash = (0, _removetrailingslash.removeTrailingSlash)(fsPathname || '');
|
||||
return fsPathnameNoSlash === (0, _removetrailingslash.removeTrailingSlash)(page) || (dynamicRouteMatcher == null ? void 0 : dynamicRouteMatcher(fsPathnameNoSlash));
|
||||
};
|
||||
const checkRewrite = (rewrite)=>{
|
||||
const matcher = (0, _pathmatch.getPathMatch)(rewrite.source + (trailingSlash ? '(/)?' : ''), {
|
||||
removeUnnamedParams: true,
|
||||
strict: true,
|
||||
sensitive: !!caseSensitive
|
||||
});
|
||||
if (!rewrittenParsedUrl.pathname) return false;
|
||||
let params = matcher(rewrittenParsedUrl.pathname);
|
||||
if ((rewrite.has || rewrite.missing) && params) {
|
||||
const hasParams = (0, _preparedestination.matchHas)(req, rewrittenParsedUrl.query, rewrite.has, rewrite.missing);
|
||||
if (hasParams) {
|
||||
Object.assign(params, hasParams);
|
||||
} else {
|
||||
params = false;
|
||||
}
|
||||
}
|
||||
if (params) {
|
||||
const { parsedDestination, destQuery } = (0, _preparedestination.prepareDestination)({
|
||||
appendParamsToQuery: true,
|
||||
destination: rewrite.destination,
|
||||
params: params,
|
||||
query: rewrittenParsedUrl.query
|
||||
});
|
||||
// if the rewrite destination is external break rewrite chain
|
||||
if (parsedDestination.protocol) {
|
||||
return true;
|
||||
}
|
||||
Object.assign(rewriteParams, destQuery, params);
|
||||
Object.assign(rewrittenParsedUrl.query, parsedDestination.query);
|
||||
delete parsedDestination.query;
|
||||
Object.assign(rewrittenParsedUrl, parsedDestination);
|
||||
fsPathname = rewrittenParsedUrl.pathname;
|
||||
if (!fsPathname) return false;
|
||||
if (basePath) {
|
||||
fsPathname = fsPathname.replace(new RegExp(`^${basePath}`), '') || '/';
|
||||
}
|
||||
if (i18n) {
|
||||
const result = (0, _normalizelocalepath.normalizeLocalePath)(fsPathname, i18n.locales);
|
||||
fsPathname = result.pathname;
|
||||
rewrittenParsedUrl.query.nextInternalLocale = result.detectedLocale || params.nextInternalLocale;
|
||||
}
|
||||
if (fsPathname === page) {
|
||||
return true;
|
||||
}
|
||||
if (pageIsDynamic && dynamicRouteMatcher) {
|
||||
const dynamicParams = dynamicRouteMatcher(fsPathname);
|
||||
if (dynamicParams) {
|
||||
rewrittenParsedUrl.query = {
|
||||
...rewrittenParsedUrl.query,
|
||||
...dynamicParams
|
||||
};
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
for (const rewrite of rewrites.beforeFiles || []){
|
||||
checkRewrite(rewrite);
|
||||
}
|
||||
if (fsPathname !== page) {
|
||||
let finished = false;
|
||||
for (const rewrite of rewrites.afterFiles || []){
|
||||
finished = checkRewrite(rewrite);
|
||||
if (finished) break;
|
||||
}
|
||||
if (!finished && !matchesPage()) {
|
||||
for (const rewrite of rewrites.fallback || []){
|
||||
finished = checkRewrite(rewrite);
|
||||
if (finished) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
rewriteParams,
|
||||
rewrittenParsedUrl
|
||||
};
|
||||
}
|
||||
function getParamsFromRouteMatches(routeMatchesHeader) {
|
||||
// If we don't have a default route regex, we can't get params from route
|
||||
// matches
|
||||
if (!defaultRouteRegex) return null;
|
||||
const { groups, routeKeys } = defaultRouteRegex;
|
||||
const matcher = (0, _routematcher.getRouteMatcher)({
|
||||
re: {
|
||||
// Simulate a RegExp match from the \`req.url\` input
|
||||
exec: (str)=>{
|
||||
// Normalize all the prefixed query params.
|
||||
const obj = Object.fromEntries(new URLSearchParams(str));
|
||||
for (const [key, value] of Object.entries(obj)){
|
||||
const normalizedKey = (0, _utils.normalizeNextQueryParam)(key);
|
||||
if (!normalizedKey) continue;
|
||||
obj[normalizedKey] = value;
|
||||
delete obj[key];
|
||||
}
|
||||
// Use all the named route keys.
|
||||
const result = {};
|
||||
for (const keyName of Object.keys(routeKeys)){
|
||||
const paramName = routeKeys[keyName];
|
||||
// If this param name is not a valid parameter name, then skip it.
|
||||
if (!paramName) continue;
|
||||
const group = groups[paramName];
|
||||
const value = obj[keyName];
|
||||
// When we're missing a required param, we can't match the route.
|
||||
if (!group.optional && !value) return null;
|
||||
result[group.pos] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
groups
|
||||
});
|
||||
const routeMatches = matcher(routeMatchesHeader);
|
||||
if (!routeMatches) return null;
|
||||
return routeMatches;
|
||||
}
|
||||
function normalizeQueryParams(query, routeParamKeys) {
|
||||
// this is used to pass query information in rewrites
|
||||
// but should not be exposed in final query
|
||||
delete query['nextInternalLocale'];
|
||||
for (const [key, value] of Object.entries(query)){
|
||||
const normalizedKey = (0, _utils.normalizeNextQueryParam)(key);
|
||||
if (!normalizedKey) continue;
|
||||
// Remove the prefixed key from the query params because we want
|
||||
// to consume it for the dynamic route matcher.
|
||||
delete query[key];
|
||||
routeParamKeys.add(normalizedKey);
|
||||
if (typeof value === 'undefined') continue;
|
||||
query[normalizedKey] = Array.isArray(value) ? value.map((v)=>(0, _decodequerypathparameter.decodeQueryPathParameter)(v)) : (0, _decodequerypathparameter.decodeQueryPathParameter)(value);
|
||||
}
|
||||
}
|
||||
return {
|
||||
handleRewrites,
|
||||
defaultRouteRegex,
|
||||
dynamicRouteMatcher,
|
||||
defaultRouteMatches,
|
||||
normalizeQueryParams,
|
||||
getParamsFromRouteMatches,
|
||||
/**
|
||||
* Normalize dynamic route params.
|
||||
*
|
||||
* @param query - The query params to normalize.
|
||||
* @param ignoreMissingOptional - Whether to ignore missing optional params.
|
||||
* @returns The normalized params and whether they are valid.
|
||||
*/ normalizeDynamicRouteParams: (query, ignoreMissingOptional)=>{
|
||||
if (!defaultRouteRegex || !defaultRouteMatches) {
|
||||
return {
|
||||
params: {},
|
||||
hasValidParams: false
|
||||
};
|
||||
}
|
||||
return normalizeDynamicRouteParams(query, defaultRouteRegex, defaultRouteMatches, ignoreMissingOptional);
|
||||
},
|
||||
normalizeCdnUrl: (req, paramKeys)=>normalizeCdnUrl(req, paramKeys),
|
||||
interpolateDynamicPath: (pathname, params)=>interpolateDynamicPath(pathname, params, defaultRouteRegex),
|
||||
filterInternalQuery: (query, paramKeys)=>filterInternalQuery(query, paramKeys)
|
||||
};
|
||||
}
|
||||
function getPreviouslyRevalidatedTags(headers, previewModeId) {
|
||||
return typeof headers[_constants.NEXT_CACHE_REVALIDATED_TAGS_HEADER] === 'string' && headers[_constants.NEXT_CACHE_REVALIDATE_TAG_TOKEN_HEADER] === previewModeId ? headers[_constants.NEXT_CACHE_REVALIDATED_TAGS_HEADER].split(',') : [];
|
||||
}
|
||||
|
||||
//# sourceMappingURL=server-utils.js.map
|
||||
Reference in New Issue
Block a user