- 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
327 lines
11 KiB
TypeScript
327 lines
11 KiB
TypeScript
import { RenderingMode } from '../rendering-mode';
|
|
import type { RouteHas } from '../../lib/load-custom-routes';
|
|
import type { Revalidate } from '../../server/lib/cache-control';
|
|
import type { NextConfigComplete } from '../../server/config-shared';
|
|
import { AdapterOutputType, type PHASE_TYPE } from '../../shared/lib/constants';
|
|
import type { MiddlewareManifest } from '../webpack/plugins/middleware-plugin';
|
|
import type { RoutesManifest, PrerenderManifest, FunctionsConfigManifest, DynamicPrerenderManifestRoute } from '..';
|
|
interface SharedRouteFields {
|
|
/**
|
|
* id is the unique identifier of the output
|
|
*/
|
|
id: string;
|
|
/**
|
|
* filePath is the location on disk of the built entrypoint asset
|
|
*/
|
|
filePath: string;
|
|
/**
|
|
* pathname is the URL pathname the asset should be served at
|
|
*/
|
|
pathname: string;
|
|
/**
|
|
* sourcePage is the original source in the app or pages folder
|
|
*/
|
|
sourcePage: string;
|
|
/**
|
|
* runtime is which runtime the entrypoint is built for
|
|
*/
|
|
runtime: 'nodejs' | 'edge';
|
|
/**
|
|
* assets are all necessary traced assets that could be
|
|
* loaded by the output to handle a request e.g. traced
|
|
* node_modules or necessary manifests for Next.js.
|
|
* The key is the relative path from the repo root and the value
|
|
* is the absolute path to the file
|
|
*/
|
|
assets: Record<string, string>;
|
|
/**
|
|
* wasmAssets are bundled wasm files with mapping of name
|
|
* to filePath on disk
|
|
*/
|
|
wasmAssets?: Record<string, string>;
|
|
/**
|
|
* config related to the route
|
|
*/
|
|
config: {
|
|
/**
|
|
* maxDuration is a segment config to signal the max
|
|
* execution duration a route should be allowed before
|
|
* it's timed out
|
|
*/
|
|
maxDuration?: number;
|
|
/**
|
|
* preferredRegion is a segment config to signal deployment
|
|
* region preferences to the provider being used
|
|
*/
|
|
preferredRegion?: string | string[];
|
|
/**
|
|
* env is the environment variables to expose, this is only
|
|
* populated for edge runtime currently
|
|
*/
|
|
env?: Record<string, string>;
|
|
};
|
|
}
|
|
export interface AdapterOutput {
|
|
/**
|
|
* `PAGES` represents all the React pages that are under `pages/`.
|
|
*/
|
|
PAGES: SharedRouteFields & {
|
|
type: AdapterOutputType.PAGES;
|
|
};
|
|
/**
|
|
* `PAGES_API` represents all the API routes under `pages/api/`.
|
|
*/
|
|
PAGES_API: SharedRouteFields & {
|
|
type: AdapterOutputType.PAGES_API;
|
|
};
|
|
/**
|
|
* `APP_PAGE` represents all the React pages that are under `app/` with the
|
|
* filename of `page.{j,t}s{,x}`.
|
|
*/
|
|
APP_PAGE: SharedRouteFields & {
|
|
type: AdapterOutputType.APP_PAGE;
|
|
};
|
|
/**
|
|
* `APP_ROUTE` represents all the API routes and metadata routes that are under `app/` with the
|
|
* filename of `route.{j,t}s{,x}`.
|
|
*/
|
|
APP_ROUTE: SharedRouteFields & {
|
|
type: AdapterOutputType.APP_ROUTE;
|
|
};
|
|
/**
|
|
* `PRERENDER` represents an ISR enabled route that might
|
|
* have a seeded cache entry or fallback generated during build
|
|
*/
|
|
PRERENDER: {
|
|
id: string;
|
|
pathname: string;
|
|
type: AdapterOutputType.PRERENDER;
|
|
/**
|
|
* For prerenders the parent output is the originating
|
|
* page that the prerender is created from
|
|
*/
|
|
parentOutputId: string;
|
|
/**
|
|
* groupId is the identifier for a group of prerenders that should be
|
|
* revalidated together
|
|
*/
|
|
groupId: number;
|
|
pprChain?: {
|
|
headers: Record<string, string>;
|
|
};
|
|
/**
|
|
* parentFallbackMode signals whether additional routes can be generated
|
|
* e.g. fallback: false or 'blocking' in getStaticPaths in pages router
|
|
*/
|
|
parentFallbackMode?: DynamicPrerenderManifestRoute['fallback'];
|
|
/**
|
|
* fallback is initial cache data generated during build for a prerender
|
|
*/
|
|
fallback?: {
|
|
/**
|
|
* path to the fallback file can be HTML/JSON/RSC
|
|
*/
|
|
filePath: string;
|
|
/**
|
|
* initialStatus is the status code that should be applied
|
|
* when serving the fallback
|
|
*/
|
|
initialStatus?: number;
|
|
/**
|
|
* initialHeaders are the headers that should be sent when
|
|
* serving the fallback
|
|
*/
|
|
initialHeaders?: Record<string, string | string[]>;
|
|
/**
|
|
* initial expiration is how long until the fallback entry
|
|
* is considered expired and no longer valid to serve
|
|
*/
|
|
initialExpiration?: number;
|
|
/**
|
|
* initial revalidate is how long until the fallback is
|
|
* considered stale and should be revalidated
|
|
*/
|
|
initialRevalidate?: Revalidate;
|
|
/**
|
|
* postponedState is the PPR state when it postponed and is used for resuming
|
|
*/
|
|
postponedState?: string;
|
|
};
|
|
/**
|
|
* config related to the route
|
|
*/
|
|
config: {
|
|
/**
|
|
* allowQuery is the allowed query values to be passed
|
|
* to an ISR function and what should be considered for the cacheKey
|
|
* e.g. for /blog/[slug], "slug" is the only allowQuery
|
|
*/
|
|
allowQuery?: string[];
|
|
/**
|
|
* allowHeader is the allowed headers to be passed to an
|
|
* ISR function to prevent accidentally poisoning the cache
|
|
* from leaking additional information that can impact the render
|
|
*/
|
|
allowHeader?: string[];
|
|
/**
|
|
* bypass for is a list of has conditions the cache
|
|
* should be bypassed and invoked directly e.g. action header
|
|
*/
|
|
bypassFor?: RouteHas[];
|
|
/**
|
|
* renderingMode signals PPR or not for a prerender
|
|
*/
|
|
renderingMode?: RenderingMode;
|
|
/**
|
|
* bypassToken is the generated token that signals a prerender cache
|
|
* should be bypassed
|
|
*/
|
|
bypassToken?: string;
|
|
};
|
|
};
|
|
/**
|
|
* `STATIC_FILE` represents a static file (ie /_next/static) or a purely
|
|
* static HTML asset e.g. an automatically statically optimized page
|
|
* that does not use ISR
|
|
*/
|
|
STATIC_FILE: {
|
|
id: string;
|
|
filePath: string;
|
|
pathname: string;
|
|
type: AdapterOutputType.STATIC_FILE;
|
|
};
|
|
/**
|
|
* `MIDDLEWARE` represents the middleware output if present
|
|
*/
|
|
MIDDLEWARE: SharedRouteFields & {
|
|
type: AdapterOutputType.MIDDLEWARE;
|
|
/**
|
|
* config related to the route
|
|
*/
|
|
config: SharedRouteFields['config'] & {
|
|
/**
|
|
* matchers are the configured matchers for middleware
|
|
*/
|
|
matchers?: Array<{
|
|
source: string;
|
|
sourceRegex: string;
|
|
has: RouteHas[] | undefined;
|
|
missing: RouteHas[] | undefined;
|
|
}>;
|
|
};
|
|
};
|
|
}
|
|
export interface AdapterOutputs {
|
|
pages: Array<AdapterOutput['PAGES']>;
|
|
middleware?: AdapterOutput['MIDDLEWARE'];
|
|
appPages: Array<AdapterOutput['APP_PAGE']>;
|
|
pagesApi: Array<AdapterOutput['PAGES_API']>;
|
|
appRoutes: Array<AdapterOutput['APP_ROUTE']>;
|
|
prerenders: Array<AdapterOutput['PRERENDER']>;
|
|
staticFiles: Array<AdapterOutput['STATIC_FILE']>;
|
|
}
|
|
type RewriteItem = {
|
|
source: string;
|
|
sourceRegex: string;
|
|
destination: string;
|
|
has: RouteHas[] | undefined;
|
|
missing: RouteHas[] | undefined;
|
|
};
|
|
type DynamicRouteItem = {
|
|
source: string;
|
|
sourceRegex: string;
|
|
destination: string;
|
|
has: RouteHas[] | undefined;
|
|
missing: RouteHas[] | undefined;
|
|
};
|
|
export interface NextAdapter {
|
|
name: string;
|
|
/**
|
|
* modifyConfig is called for any CLI command that loads the next.config
|
|
* to only apply for specific commands the "phase" should be used
|
|
* @param config
|
|
* @param ctx
|
|
* @returns
|
|
*/
|
|
modifyConfig?: (config: NextConfigComplete, ctx: {
|
|
phase: PHASE_TYPE;
|
|
}) => Promise<NextConfigComplete> | NextConfigComplete;
|
|
onBuildComplete?: (ctx: {
|
|
routes: {
|
|
headers: Array<{
|
|
source: string;
|
|
sourceRegex: string;
|
|
headers: Record<string, string>;
|
|
has: RouteHas[] | undefined;
|
|
missing: RouteHas[] | undefined;
|
|
priority?: boolean;
|
|
}>;
|
|
redirects: Array<{
|
|
source: string;
|
|
sourceRegex: string;
|
|
destination: string;
|
|
statusCode: number;
|
|
has: RouteHas[] | undefined;
|
|
missing: RouteHas[] | undefined;
|
|
priority?: boolean;
|
|
}>;
|
|
rewrites: {
|
|
beforeFiles: RewriteItem[];
|
|
afterFiles: RewriteItem[];
|
|
fallback: RewriteItem[];
|
|
};
|
|
dynamicRoutes: Array<DynamicRouteItem>;
|
|
};
|
|
outputs: AdapterOutputs;
|
|
/**
|
|
* projectDir is the absolute directory the Next.js application is in
|
|
*/
|
|
projectDir: string;
|
|
/**
|
|
* repoRoot is the absolute path of the detected root of the repo
|
|
*/
|
|
repoRoot: string;
|
|
/**
|
|
* distDir is the absolute path to the dist directory
|
|
*/
|
|
distDir: string;
|
|
/**
|
|
* config is the loaded next.config (has modifyConfig applied)
|
|
*/
|
|
config: NextConfigComplete;
|
|
/**
|
|
* nextVersion is the current version of Next.js being used
|
|
*/
|
|
nextVersion: string;
|
|
/**
|
|
* buildId is the current unique ID for the build, this can be
|
|
* influenced by NextConfig.generateBuildId
|
|
*/
|
|
buildId: string;
|
|
}) => Promise<void> | void;
|
|
}
|
|
export declare function handleBuildComplete({ dir, config, buildId, configOutDir, distDir, pageKeys, tracingRoot, adapterPath, appPageKeys, staticPages, nextVersion, hasStatic404, hasStatic500, routesManifest, serverPropsPages, hasNodeMiddleware, prerenderManifest, middlewareManifest, requiredServerFiles, hasInstrumentationHook, functionsConfigManifest, }: {
|
|
dir: string;
|
|
distDir: string;
|
|
buildId: string;
|
|
configOutDir: string;
|
|
adapterPath: string;
|
|
tracingRoot: string;
|
|
nextVersion: string;
|
|
hasStatic404: boolean;
|
|
hasStatic500: boolean;
|
|
staticPages: Set<string>;
|
|
hasNodeMiddleware: boolean;
|
|
config: NextConfigComplete;
|
|
pageKeys: readonly string[];
|
|
serverPropsPages: Set<string>;
|
|
requiredServerFiles: string[];
|
|
routesManifest: RoutesManifest;
|
|
hasInstrumentationHook: boolean;
|
|
prerenderManifest: PrerenderManifest;
|
|
middlewareManifest: MiddlewareManifest;
|
|
appPageKeys?: readonly string[] | undefined;
|
|
functionsConfigManifest: FunctionsConfigManifest;
|
|
}): Promise<void>;
|
|
export {};
|